Check out the REST API reference.' ),
+ 'https://developer.wordpress.org/rest-api/reference/'
+ );
+ ?>
+
+
+
+
-
+
-
-
Resource hints help browsers decide which resources to fetch and preprocess. WordPress 4.6 adds them automatically for your styles and scripts making your site even faster.' ),
- 'https://make.wordpress.org/core/2016/07/06/resource-hints-in-4-6/'
- );
- ?>
-
-
-
-
+
+
-
WP_Term_Query', 'WP_Post_Type' );
- ?>
+
WP_Term_Query',
- 'WP_Post_Type'
+ /* translators: %s: https://make.wordpress.org/core/2016/09/09/new-functions-hooks-and-behaviour-for-theme-developers-in-wordpress-4-7/ */
+ __( 'WordPress 4.7 includes new functions, hooks, and behavior for theme developers.' ),
+ 'https://make.wordpress.org/core/2016/09/09/new-functions-hooks-and-behaviour-for-theme-developers-in-wordpress-4-7/'
);
?>
has been expanded to support types, descriptions, and REST API visibility.' ),
- 'https://make.wordpress.org/core/2016/07/08/enhancing-register_meta-in-4-6/'
+ /* translators: %s: https://make.wordpress.org/core/2016/09/08/wp_hook-next-generation-actions-and-filters/ */
+ __( 'The code that lies beneath actions and filters has been overhauled and modernized, fixing bugs along the way.' ),
+ 'https://make.wordpress.org/core/2016/09/08/wp_hook-next-generation-actions-and-filters/'
);
?>
-
-
WordPress.org’s community of translators.' ); ?>
-
-
-
-
-
-
-
-
-
-
-
API for enforcing validation constraints. Likewise, customizer controls now support notifications, which are used to display validation errors instead of failing silently.' ); ?>
-
-
-
+
WP_Site_Query',
- 'WP_Network_Query'
+ /* translators: 1: register_setting(), 2: https://make.wordpress.org/core/2016/10/26/registering-your-settings-in-wordpress-4-7/ */
+ __( '%1$s has been enhanced to include type, description, and REST API visibility.' ),
+ 'register_setting()',
+ 'https://make.wordpress.org/core/2016/10/26/registering-your-settings-in-wordpress-4-7/'
);
?>
@@ -278,4 +278,4 @@ function wp_widget_control( $sidebar_args ) {
*/
function wp_widgets_access_body_class($classes) {
return "$classes widgets_access ";
-}
\ No newline at end of file
+}
diff --git a/code/wp-admin/index.php b/code/wp-admin/index.php
index 86bed0ad..d2d7ec88 100644
--- a/code/wp-admin/index.php
+++ b/code/wp-admin/index.php
@@ -33,7 +33,6 @@
$help = '
' . __( 'Welcome to your WordPress Dashboard! This is the screen you will see when you log in to your site, and gives you access to all the site management features of WordPress. You can get help for any screen by clicking the Help tab above the screen title.' ) . '
';
-// Not using chaining here, so as to be parseable by PHP4.
$screen = get_current_screen();
$screen->add_help_tab( array(
@@ -95,8 +94,8 @@
$screen->set_help_sidebar(
'
diff --git a/code/wp-admin/theme-install.php b/code/wp-admin/theme-install.php
index 6b384655..dadef0dd 100644
--- a/code/wp-admin/theme-install.php
+++ b/code/wp-admin/theme-install.php
@@ -37,22 +37,28 @@
wp_localize_script( 'theme', '_wpThemeSettings', array(
'themes' => false,
'settings' => array(
- 'isInstall' => true,
- 'canInstall' => current_user_can( 'install_themes' ),
- 'installURI' => current_user_can( 'install_themes' ) ? self_admin_url( 'theme-install.php' ) : null,
- 'adminUrl' => parse_url( self_admin_url(), PHP_URL_PATH )
+ 'isInstall' => true,
+ 'canInstall' => current_user_can( 'install_themes' ),
+ 'installURI' => current_user_can( 'install_themes' ) ? self_admin_url( 'theme-install.php' ) : null,
+ 'adminUrl' => parse_url( self_admin_url(), PHP_URL_PATH )
),
'l10n' => array(
- 'addNew' => __( 'Add New Theme' ),
- 'search' => __( 'Search Themes' ),
- 'searchPlaceholder' => __( 'Search themes...' ), // placeholder (no ellipsis)
- 'upload' => __( 'Upload Theme' ),
- 'back' => __( 'Back' ),
- 'error' => __( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server’s configuration. If you continue to have problems, please try the support forums.' ),
- 'themesFound' => __( 'Number of Themes found: %d' ),
- 'noThemesFound' => __( 'No themes found. Try a different search.' ),
- 'collapseSidebar' => __( 'Collapse Sidebar' ),
- 'expandSidebar' => __( 'Expand Sidebar' ),
+ 'addNew' => __( 'Add New Theme' ),
+ 'search' => __( 'Search Themes' ),
+ 'searchPlaceholder' => __( 'Search themes...' ), // placeholder (no ellipsis)
+ 'upload' => __( 'Upload Theme' ),
+ 'back' => __( 'Back' ),
+ 'error' => sprintf(
+ /* translators: %s: support forums URL */
+ __( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server’s configuration. If you continue to have problems, please try the support forums.' ),
+ __( 'https://wordpress.org/support/' )
+ ),
+ 'themesFound' => __( 'Number of Themes found: %d' ),
+ 'noThemesFound' => __( 'No themes found. Try a different search.' ),
+ 'collapseSidebar' => __( 'Collapse Sidebar' ),
+ 'expandSidebar' => __( 'Expand Sidebar' ),
+ /* translators: hidden accessibility text */
+ 'selectFeatureFilter' => __( 'Select one or more Theme features to filter by' ),
),
'installedThemes' => array_keys( $installed_themes ),
) );
@@ -76,7 +82,7 @@
$help_overview =
'
' . sprintf(
/* translators: %s: Theme Directory URL */
- __( 'You can find additional themes for your site by using the Theme Browser/Installer on this screen, which will display themes from the WordPress Theme Directory. These themes are designed and developed by third parties, are available free of charge, and are compatible with the license WordPress uses.' ),
+ __( 'You can find additional themes for your site by using the Theme Browser/Installer on this screen, which will display themes from the WordPress Theme Directory. These themes are designed and developed by third parties, are available free of charge, and are compatible with the license WordPress uses.' ),
__( 'https://wordpress.org/themes/' )
) . '
' .
'
' . __( 'You can Search for themes by keyword, author, or tag, or can get more specific and search by criteria listed in the feature filter.' ) . ' ' . __( 'The search results will be updated as you type.' ) . '
' . $args->link_after . '', $item_output );
- }
-
- return $item_output;
-}
-add_filter( 'walker_nav_menu_start_el', 'twentyfifteen_nav_description', 10, 4 );
-
-/**
- * Add a `screen-reader-text` class to the search form's submit button.
- *
- * @since Twenty Fifteen 1.0
- *
- * @param string $html Search form HTML.
- * @return string Modified search form HTML.
- */
-function twentyfifteen_search_form_modify( $html ) {
- return str_replace( 'class="search-submit"', 'class="search-submit screen-reader-text"', $html );
-}
-add_filter( 'get_search_form', 'twentyfifteen_search_form_modify' );
-
-/**
- * Implement the Custom Header feature.
- *
- * @since Twenty Fifteen 1.0
- */
-require get_template_directory() . '/inc/custom-header.php';
-
-/**
- * Custom template tags for this theme.
- *
- * @since Twenty Fifteen 1.0
- */
-require get_template_directory() . '/inc/template-tags.php';
-
-/**
- * Customizer additions.
- *
- * @since Twenty Fifteen 1.0
- */
-require get_template_directory() . '/inc/customizer.php';
diff --git a/code/wp-content/themes/twentyfifteen/genericons/COPYING.txt b/code/wp-content/themes/twentyfifteen/genericons/COPYING.txt
deleted file mode 100644
index aece214b..00000000
--- a/code/wp-content/themes/twentyfifteen/genericons/COPYING.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-Genericons is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
-
-The fonts are distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-
-As a special exception, if you create a document which uses this font, and embed this font or unaltered portions of this font into the document, this font does not by itself cause the resulting document to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the document might be covered by the GNU General Public License. If you modify this font, you may extend this exception to your version of the font, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version.
-
-This license does not convey any intellectual property rights to third party trademarks that may be included in the icon font; such marks remain subject to all rights and guidelines of use of their owner.
\ No newline at end of file
diff --git a/code/wp-content/themes/twentyfifteen/genericons/Genericons.eot b/code/wp-content/themes/twentyfifteen/genericons/Genericons.eot
deleted file mode 100644
index b5f8647f..00000000
Binary files a/code/wp-content/themes/twentyfifteen/genericons/Genericons.eot and /dev/null differ
diff --git a/code/wp-content/themes/twentyfifteen/genericons/Genericons.svg b/code/wp-content/themes/twentyfifteen/genericons/Genericons.svg
deleted file mode 100644
index f8131107..00000000
--- a/code/wp-content/themes/twentyfifteen/genericons/Genericons.svg
+++ /dev/null
@@ -1,543 +0,0 @@
-
-
-
-
diff --git a/code/wp-content/themes/twentyfifteen/genericons/Genericons.ttf b/code/wp-content/themes/twentyfifteen/genericons/Genericons.ttf
deleted file mode 100644
index 1f160ddb..00000000
Binary files a/code/wp-content/themes/twentyfifteen/genericons/Genericons.ttf and /dev/null differ
diff --git a/code/wp-content/themes/twentyfifteen/genericons/Genericons.woff b/code/wp-content/themes/twentyfifteen/genericons/Genericons.woff
deleted file mode 100644
index 973e0339..00000000
Binary files a/code/wp-content/themes/twentyfifteen/genericons/Genericons.woff and /dev/null differ
diff --git a/code/wp-content/themes/twentyfifteen/genericons/LICENSE.txt b/code/wp-content/themes/twentyfifteen/genericons/LICENSE.txt
deleted file mode 100644
index d159169d..00000000
--- a/code/wp-content/themes/twentyfifteen/genericons/LICENSE.txt
+++ /dev/null
@@ -1,339 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Lesser General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-
- Copyright (C)
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) year name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- , 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.
diff --git a/code/wp-content/themes/twentyfifteen/genericons/README.md b/code/wp-content/themes/twentyfifteen/genericons/README.md
deleted file mode 100644
index faf8f609..00000000
--- a/code/wp-content/themes/twentyfifteen/genericons/README.md
+++ /dev/null
@@ -1,152 +0,0 @@
-## Genericons
-
-Genericons are vector icons embedded in a webfont designed to be clean and simple keeping with a generic aesthetic.
-
-Use genericons for instant HiDPI, to change icon colors on the fly, or even with CSS effects such as drop-shadows or gradients!
-
-
-### Usage
-
-To use it, place the `font` folder in your stylesheet directory and enqueue the genericons.css file. Now you can create an icon like this:
-
-```
-.my-icon:before {
- content: '\f101';
- font: normal 16px/1 'Genericons';
- display: inline-block;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
-}
-```
-
-This will output a comment icon before every element with the class "my-icon". The `content: '\f101';` part of this CSS is easily copied from the helper tool at http://genericons.com/, or `example.html` in the `font` directory.
-
-You can also use the bundled example.css if you'd rather insert the icons using HTML tags.
-
-
-### Notes
-
-**Photoshop mockups**
-
-The `Genericons.ttf` file found in the `font` directory can be placed in your system fonts folder and used Photoshop or other graphics apps if you like.
-
-If you're using Genericons in your Photoshop mockups, please remember to delete the old version of the font from Font Book, and grab the new one from the zip file. This also affects using it in your webdesigns: if you have an old version of the font installed locally, that's the font that'll be used in your website as well, so if you're missing icons, check for old versions of the font on your system.
-
-**Pixel grid**
-
-Genericons has been designed for a 16x16px grid. That means it'll look sharp at font-size: 16px exactly. It'll also be crisp at multiples thereof, such as 32px or 64px. It'll look reasonably crisp at in-between font sizes such as 24px or 48px, but not quite as crisp as 16 or 32. Please don't set the font-size to 17px, though, that'll just look terrible blurry.
-
-**Antialiasing**
-
-If you keep intact the `-webkit-font-smoothing: antialiased;` and `-moz-osx-font-smoothing: grayscale;` CSS properties. That'll make the icons look their best possible, in Firefox and WebKit based browsers.
-
-**optimizeLegibility**
-
-Note: On Android browsers with version 4.2, 4.3, and probably later, Genericons will simply not show up if you're using the CSS property "text-rendering" set to "optimizeLegibility.
-
-**Updates**
-
-We don't often update icons, but do very carefully when we get good feedback suggesting improvements. Please be mindful if you upgrade, and check that the updated icons behave as you intended.
-
-
-### Changelog
-
-**3.2**
-
-A number of new icons and a couple of quick updates.
-
-* New: Activity
-* New: HTML anchor
-* New: Bug
-* New: Download
-* New: Handset
-* New: Microphone
-* New: Minus
-* New: Plus
-* New: Move
-* New: Rating stars, empty, half, full
-* New: Shuffle
-* New: video camera
-* New: Spotify
-* New: Twitch
-* Update: Fixed geometry in Edit icon
-* Update: Updated Foursquare icon
-
-Twitch and Spotify mark the last social icons that will be added to Genericons.
-Future social icons will have to happen in a separate font.
-
-**3.1**
-
-Genericons is now generated using a commandline tool called FontCustom. This makes it far easier to add new icons to the font, but the switch means the download zip now has a different layout, fonts have different filenames, there's now no .otf font included (but the .ttf should suffice), and the font now has slightly different metrics. I've taken great care to ensure this new version should work as a drop-in replacement, but please be mindful and test carefully if you choose to upgrade.
-
-* Per feedback, the baked-in 16px width and height has been removed from the helper CSS. It wasn't really necessary (the glyph itself has these dimensions naturally), and it caused some headaches.
-* Base64 encoding is now included by default in the helper CSS. This makes it drop-in easy to get Genericons working in Firefox even when using a CDN.
-* Title attribute on website tool.
-* New: Website.
-* New: Ellipsis.
-* New: Foursquare.
-* New: X-post.
-* New: Sitemap.
-* New: Hierarchy.
-* New: Paintbrush.
-* Updated: Show and Hide icons were updated for clarity.
-
-**3.0.3**
-
-Bunch of updates mostly.
-
-* Two new icons, Dropbox and Fullscreen.
-* Updates to all icons containing an exclamation mark.
-* Updates to Image and Quote.
-* Nicer "Share" icon.
-* Bigger default Linkedin icon.
-
-**3.0.2**
-
-A slew of new stuff and updates.
-
-* Social icons: Skype, Digg, Reddit, Stumbleupon, Pocket.
-* New generic icons: heart, lock and print.
-* New editing icons: code, bold, italic, image
-* New interaction icons: subscribe, unsubscribe, subscribed, reply all, reply, flag.
-* The hyperlink icon has been updated to be clearer, chunkier.
-* The "home" icon has been updated for style, size and clarity.
-* The email icon has been updated for style and clarity, and to fit with the new subscribe icons.
-* The document icon has been updated for style.
-* The "pin" icon has been updated for style and clarity.
-* The Twitter icon has been scaled down to fit with the other social icons.
-
-**3.0.1**
-
-Mostly maintenance.
-
-* Fixed an issue with the example page that showed an old "top" icon instead of the actual NEW "refresh" icon.
-* Added inverse Google+ and Path.
-* Replaced tabs with spaces in the helper CSS.
-* Changed the Genericons.com copy/paste tool to serve span's instead of div's for casual icon insertion. It's being converted to "inline-block" anyway.
-
-**3.0**
-
-Mainly maintenance and a few new icons.
-
-* Fast forward, rewind, PollDaddy, Notice, Info, Help, Portfolio
-* Updated the feed icon. It's a bit smaller now for consistency, the previous one was rather big.
-* So, the previous version numbering, 2.09, wasn't very PHP version compare friendly. So from now on it'll be 3.0, 3.1 etc. Props Ipstenu.
-* Genericons.com now has a mini release blog.
-* The CSS has prettier formatting, props Konstantin Obenland.
-
-**2.09**
-
-Updated Facebook icon to new version. Updated Instagram logo to use new one-color version. Updated Google+ icon to use same radius as Instagram and Facebook. Added a bunch of new icons, cog, unapprove, cart, media player buttons, tablet, send to tablet.
-
-**2.06**
-
-Included Base64 encoded version. This is necessary for Genericons to work with CDNs in Firefox. Firefox blocks fonts linked from a different domain. A CDN (typically s.example.com) usually puts the font on a subdomain, and is hence blocked in Firefox.
-
-**2.05**
-
-Added a bunch of new icons, including upload to cloud, download to cloud, many more.
-
-**2.0**
-
-Initial public release
diff --git a/code/wp-content/themes/twentyfifteen/genericons/genericons.css b/code/wp-content/themes/twentyfifteen/genericons/genericons.css
deleted file mode 100644
index 36f02a34..00000000
--- a/code/wp-content/themes/twentyfifteen/genericons/genericons.css
+++ /dev/null
@@ -1,209 +0,0 @@
-/**
-
- Genericons
-
-*/
-
-
-/* IE8 and below use EOT and allow cross-site embedding.
- IE9 uses WOFF which is base64 encoded to allow cross-site embedding.
- So unfortunately, IE9 will throw a console error, but it'll still work.
- When the font is base64 encoded, cross-site embedding works in Firefox */
-
-@font-face {
- font-family: 'Genericons';
- src: url('Genericons.eot');
-}
-
-@font-face {
- font-family: 'Genericons';
- src: url(data:application/font-woff;charset=utf-8;base64,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) format('woff'),
- url('Genericons.ttf') format('truetype'),
- url('Genericons.svg#genericonsregular') format('svg');
- font-weight: normal;
- font-style: normal;
-}
-
-@media screen and (-webkit-min-device-pixel-ratio:0) {
- @font-face {
- font-family: "Genericons";
- src: url("./Genericons.svg#Genericons") format("svg");
- }
-}
-
-
-/**
- * All Genericons
- */
-
-.genericon {
- font-size: 16px;
- vertical-align: top;
- text-align: center;
- -moz-transition: color .1s ease-in 0;
- -webkit-transition: color .1s ease-in 0;
- display: inline-block;
- font-family: "Genericons";
- font-style: normal;
- font-weight: normal;
- font-variant: normal;
- line-height: 1;
- text-decoration: inherit;
- text-transform: none;
- -moz-osx-font-smoothing: grayscale;
- -webkit-font-smoothing: antialiased;
- speak: none;
-}
-
-
-/**
- * Individual icons
- */
-
-.genericon-404:before { content: "\f423"; }
-.genericon-activity:before { content: "\f508"; }
-.genericon-anchor:before { content: "\f509"; }
-.genericon-aside:before { content: "\f101"; }
-.genericon-attachment:before { content: "\f416"; }
-.genericon-audio:before { content: "\f109"; }
-.genericon-bold:before { content: "\f471"; }
-.genericon-book:before { content: "\f444"; }
-.genericon-bug:before { content: "\f50a"; }
-.genericon-cart:before { content: "\f447"; }
-.genericon-category:before { content: "\f301"; }
-.genericon-chat:before { content: "\f108"; }
-.genericon-checkmark:before { content: "\f418"; }
-.genericon-close:before { content: "\f405"; }
-.genericon-close-alt:before { content: "\f406"; }
-.genericon-cloud:before { content: "\f426"; }
-.genericon-cloud-download:before { content: "\f440"; }
-.genericon-cloud-upload:before { content: "\f441"; }
-.genericon-code:before { content: "\f462"; }
-.genericon-codepen:before { content: "\f216"; }
-.genericon-cog:before { content: "\f445"; }
-.genericon-collapse:before { content: "\f432"; }
-.genericon-comment:before { content: "\f300"; }
-.genericon-day:before { content: "\f305"; }
-.genericon-digg:before { content: "\f221"; }
-.genericon-document:before { content: "\f443"; }
-.genericon-dot:before { content: "\f428"; }
-.genericon-downarrow:before { content: "\f502"; }
-.genericon-download:before { content: "\f50b"; }
-.genericon-draggable:before { content: "\f436"; }
-.genericon-dribbble:before { content: "\f201"; }
-.genericon-dropbox:before { content: "\f225"; }
-.genericon-dropdown:before { content: "\f433"; }
-.genericon-dropdown-left:before { content: "\f434"; }
-.genericon-edit:before { content: "\f411"; }
-.genericon-ellipsis:before { content: "\f476"; }
-.genericon-expand:before { content: "\f431"; }
-.genericon-external:before { content: "\f442"; }
-.genericon-facebook:before { content: "\f203"; }
-.genericon-facebook-alt:before { content: "\f204"; }
-.genericon-fastforward:before { content: "\f458"; }
-.genericon-feed:before { content: "\f413"; }
-.genericon-flag:before { content: "\f468"; }
-.genericon-flickr:before { content: "\f211"; }
-.genericon-foursquare:before { content: "\f226"; }
-.genericon-fullscreen:before { content: "\f474"; }
-.genericon-gallery:before { content: "\f103"; }
-.genericon-github:before { content: "\f200"; }
-.genericon-googleplus:before { content: "\f206"; }
-.genericon-googleplus-alt:before { content: "\f218"; }
-.genericon-handset:before { content: "\f50c"; }
-.genericon-heart:before { content: "\f461"; }
-.genericon-help:before { content: "\f457"; }
-.genericon-hide:before { content: "\f404"; }
-.genericon-hierarchy:before { content: "\f505"; }
-.genericon-home:before { content: "\f409"; }
-.genericon-image:before { content: "\f102"; }
-.genericon-info:before { content: "\f455"; }
-.genericon-instagram:before { content: "\f215"; }
-.genericon-italic:before { content: "\f472"; }
-.genericon-key:before { content: "\f427"; }
-.genericon-leftarrow:before { content: "\f503"; }
-.genericon-link:before { content: "\f107"; }
-.genericon-linkedin:before { content: "\f207"; }
-.genericon-linkedin-alt:before { content: "\f208"; }
-.genericon-location:before { content: "\f417"; }
-.genericon-lock:before { content: "\f470"; }
-.genericon-mail:before { content: "\f410"; }
-.genericon-maximize:before { content: "\f422"; }
-.genericon-menu:before { content: "\f419"; }
-.genericon-microphone:before { content: "\f50d"; }
-.genericon-minimize:before { content: "\f421"; }
-.genericon-minus:before { content: "\f50e"; }
-.genericon-month:before { content: "\f307"; }
-.genericon-move:before { content: "\f50f"; }
-.genericon-next:before { content: "\f429"; }
-.genericon-notice:before { content: "\f456"; }
-.genericon-paintbrush:before { content: "\f506"; }
-.genericon-path:before { content: "\f219"; }
-.genericon-pause:before { content: "\f448"; }
-.genericon-phone:before { content: "\f437"; }
-.genericon-picture:before { content: "\f473"; }
-.genericon-pinned:before { content: "\f308"; }
-.genericon-pinterest:before { content: "\f209"; }
-.genericon-pinterest-alt:before { content: "\f210"; }
-.genericon-play:before { content: "\f452"; }
-.genericon-plugin:before { content: "\f439"; }
-.genericon-plus:before { content: "\f510"; }
-.genericon-pocket:before { content: "\f224"; }
-.genericon-polldaddy:before { content: "\f217"; }
-.genericon-portfolio:before { content: "\f460"; }
-.genericon-previous:before { content: "\f430"; }
-.genericon-print:before { content: "\f469"; }
-.genericon-quote:before { content: "\f106"; }
-.genericon-rating-empty:before { content: "\f511"; }
-.genericon-rating-full:before { content: "\f512"; }
-.genericon-rating-half:before { content: "\f513"; }
-.genericon-reddit:before { content: "\f222"; }
-.genericon-refresh:before { content: "\f420"; }
-.genericon-reply:before { content: "\f412"; }
-.genericon-reply-alt:before { content: "\f466"; }
-.genericon-reply-single:before { content: "\f467"; }
-.genericon-rewind:before { content: "\f459"; }
-.genericon-rightarrow:before { content: "\f501"; }
-.genericon-search:before { content: "\f400"; }
-.genericon-send-to-phone:before { content: "\f438"; }
-.genericon-send-to-tablet:before { content: "\f454"; }
-.genericon-share:before { content: "\f415"; }
-.genericon-show:before { content: "\f403"; }
-.genericon-shuffle:before { content: "\f514"; }
-.genericon-sitemap:before { content: "\f507"; }
-.genericon-skip-ahead:before { content: "\f451"; }
-.genericon-skip-back:before { content: "\f450"; }
-.genericon-skype:before { content: "\f220"; }
-.genericon-spam:before { content: "\f424"; }
-.genericon-spotify:before { content: "\f515"; }
-.genericon-standard:before { content: "\f100"; }
-.genericon-star:before { content: "\f408"; }
-.genericon-status:before { content: "\f105"; }
-.genericon-stop:before { content: "\f449"; }
-.genericon-stumbleupon:before { content: "\f223"; }
-.genericon-subscribe:before { content: "\f463"; }
-.genericon-subscribed:before { content: "\f465"; }
-.genericon-summary:before { content: "\f425"; }
-.genericon-tablet:before { content: "\f453"; }
-.genericon-tag:before { content: "\f302"; }
-.genericon-time:before { content: "\f303"; }
-.genericon-top:before { content: "\f435"; }
-.genericon-trash:before { content: "\f407"; }
-.genericon-tumblr:before { content: "\f214"; }
-.genericon-twitch:before { content: "\f516"; }
-.genericon-twitter:before { content: "\f202"; }
-.genericon-unapprove:before { content: "\f446"; }
-.genericon-unsubscribe:before { content: "\f464"; }
-.genericon-unzoom:before { content: "\f401"; }
-.genericon-uparrow:before { content: "\f500"; }
-.genericon-user:before { content: "\f304"; }
-.genericon-video:before { content: "\f104"; }
-.genericon-videocamera:before { content: "\f517"; }
-.genericon-vimeo:before { content: "\f212"; }
-.genericon-warning:before { content: "\f414"; }
-.genericon-website:before { content: "\f475"; }
-.genericon-week:before { content: "\f306"; }
-.genericon-wordpress:before { content: "\f205"; }
-.genericon-xpost:before { content: "\f504"; }
-.genericon-youtube:before { content: "\f213"; }
-.genericon-zoom:before { content: "\f402"; }
diff --git a/code/wp-content/themes/twentyfifteen/header.php b/code/wp-content/themes/twentyfifteen/header.php
deleted file mode 100644
index 28de34ed..00000000
--- a/code/wp-content/themes/twentyfifteen/header.php
+++ /dev/null
@@ -1,52 +0,0 @@
-
- class="no-js">
-
-
-
-
-
-
-
-
-
->
-
-
- = 2 || $page >= 2 ) && ! is_404() ) {
- $title = "$title $sep " . sprintf( __( 'Page %s', 'twentyfourteen' ), max( $paged, $page ) );
- }
-
- return $title;
-}
-add_filter( 'wp_title', 'twentyfourteen_wp_title', 10, 2 );
-
-// Implement Custom Header features.
-require get_template_directory() . '/inc/custom-header.php';
-
-// Custom template tags for this theme.
-require get_template_directory() . '/inc/template-tags.php';
-
-// Add Customizer functionality.
-require get_template_directory() . '/inc/customizer.php';
-
-/*
- * Add Featured Content functionality.
- *
- * To overwrite in a plugin, define your own Featured_Content class on or
- * before the 'setup_theme' hook.
- */
-if ( ! class_exists( 'Featured_Content' ) && 'plugins.php' !== $GLOBALS['pagenow'] ) {
- require get_template_directory() . '/inc/featured-content.php';
-}
diff --git a/code/wp-content/themes/twentyfourteen/genericons/COPYING.txt b/code/wp-content/themes/twentyfourteen/genericons/COPYING.txt
deleted file mode 100644
index aece214b..00000000
--- a/code/wp-content/themes/twentyfourteen/genericons/COPYING.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-Genericons is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
-
-The fonts are distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-
-As a special exception, if you create a document which uses this font, and embed this font or unaltered portions of this font into the document, this font does not by itself cause the resulting document to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the document might be covered by the GNU General Public License. If you modify this font, you may extend this exception to your version of the font, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version.
-
-This license does not convey any intellectual property rights to third party trademarks that may be included in the icon font; such marks remain subject to all rights and guidelines of use of their owner.
\ No newline at end of file
diff --git a/code/wp-content/themes/twentyfourteen/genericons/Genericons-Regular.otf b/code/wp-content/themes/twentyfourteen/genericons/Genericons-Regular.otf
deleted file mode 100644
index 5cd41e8b..00000000
Binary files a/code/wp-content/themes/twentyfourteen/genericons/Genericons-Regular.otf and /dev/null differ
diff --git a/code/wp-content/themes/twentyfourteen/genericons/LICENSE.txt b/code/wp-content/themes/twentyfourteen/genericons/LICENSE.txt
deleted file mode 100644
index d159169d..00000000
--- a/code/wp-content/themes/twentyfourteen/genericons/LICENSE.txt
+++ /dev/null
@@ -1,339 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Lesser General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-
- Copyright (C)
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) year name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- , 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.
diff --git a/code/wp-content/themes/twentyfourteen/genericons/README.txt b/code/wp-content/themes/twentyfourteen/genericons/README.txt
deleted file mode 100644
index 7a0a92e5..00000000
--- a/code/wp-content/themes/twentyfourteen/genericons/README.txt
+++ /dev/null
@@ -1,123 +0,0 @@
- ___ ____ __ _ ____ ____ __ ___ __ __ _ ____
- / __)( __)( ( \( __)( _ \( )/ __)/ \ ( ( \/ ___)
-( (_ \ ) _) / / ) _) ) / )(( (__( O )/ /\___ \
- \___/(____)\_)__)(____)(__\_)(__)\___)\__/ \_)__)(____/
-
-
-Genericons are vector icons embedded in a webfont designed to be clean and simple keeping with a generic aesthetic.
-
-Use genericons for instant HiDPI, to change icon colors on the fly, or even with CSS effects such as drop-shadows or gradients!
-
-
-_ _ ____ ____ ____ ____
-| | [__ |__| | __ |___
-|__| ___] | | |__] |___
-
-
-To use it, place the font folder in your stylesheet directory and paste this in your CSS file:
-
-/* =Genericons, thanks to FontSquirrel.com for conversion!
--------------------------------------------------------------- */
-@font-face {
- font-family: 'Genericons';
- src: url('font/genericons-regular-webfont.eot');
- src: url('font/genericons-regular-webfont.eot?#iefix') format('embedded-opentype'),
- url('font/genericons-regular-webfont.woff') format('woff'),
- url('font/genericons-regular-webfont.ttf') format('truetype'),
- url('font/genericons-regular-webfont.svg#genericonsregular') format('svg');
- font-weight: normal;
- font-style: normal;
-
-}
-
-Note: the above only works if you don't use a CDN. If you do, or don't know what that is, you should use the syntax that's embedded in genericons.css.
-
-From then on, you can create an icon like this:
-
-.my-icon:before {
- content: '\f101';
- display: inline-block;
- -webkit-font-smoothing: antialiased;
- font: normal 16px/1 'Genericons';
- vertical-align: top;
-}
-
-This will output a comment icon before every element with the class "my-icon". The "content: '\f101';" part of this CSS is easily copied from the helper tool at http://genericons.com/
-
-You can also use the bundled example.css if you'd rather insert the icons using HTML tags.
-
-
-_ _ ____ ___ ____ ____
-|\ | | | | |___ [__
-| \| |__| | |___ ___]
-
-
-Photoshop mockups:
-
-Genericons-Regular.otf found in the root directory of this zip has not been web-font-ified. So you can drop it in your system fonts folder and use the font in Photoshop if you like.
-
-For those of you using Genericons in your Photoshop mockup, remember to delete the old version of the font from Font Book, and grab the new one from the zip file. This also affects using it in your webdesigns: if you have an old version of the font installed locally, that's the font that'll be used in your website as well, so if you're missing icons, check for old versions of the font on your system.
-
-Pixel grid:
-
-Note that Genericons has been designed for a 16x16 pixel grid. That means it'll look sharp at font-size: 16px exactly. It'll also be crisp at multiples thereof, such as 32px or 64px. It'll also look reasonably crisp at in-between font sizes such as 24px or 48px, but not quite as crisp as 16 or 32. Please don't set the font-size to 17px, though, that'll just look terrible.
-
-Also note the CSS property "-webkit-font-smoothing: antialiased". That makes the icons look great in WebKit browsers. Please see http://noscope.com/2012/font-smoothing for more info.
-
-Updates:
-
-We don't often update icons, but do very carefully when we get good feedback suggesting improvements. Please be mindful if you upgrade, and check that the updated icons behave as you intended.
-
-
-
-____ _ _ ____ _ _ ____ ____ _ ____ ____
-| |__| |__| |\ | | __ |___ | | | | __
-|___ | | | | | \| |__] |___ |___ |__| |__]
-
-V3.0.3:
-Bunch of updates mostly.
-- Two new icons, Dropbox and Fullscreen.
-- Updates to all icons containing an exclamation mark.
-- Updates to Image and Quote.
-- Nicer "Share" icon.
-- Bigger default Linkedin icon.
-
-V3.0.2:
-A slew of new stuff and updates.
-- Social icons: Skype, Digg, Reddit, Stumbleupon, Pocket.
-- New generic icons: heart, lock and print.
-- New editing icons: code, bold, italic, image
-- New interaction icons: subscribe, unsubscribe, subscribed, reply all, reply, flag.
-- The hyperlink icon has been updated to be clearer, chunkier.
-- The "home" icon has been updated for style, size and clarity.
-- The email icon has been updated for style and clarity, and to fit with the new subscribe icons.
-- The document icon has been updated for style.
-- The "pin" icon has been updated for style and clarity.
-- The Twitter icon has been scaled down to fit with the other social icons.
-
-V3.0.1:
-Mostly maintenance.
-- Fixed an issue with the example page that showed an old "top" icon instead of the actual NEW "refresh" icon.
-- Added inverse Google+ and Path.
-- Replaced tabs with spaces in the helper CSS.
-- Changed the Genericons.com copy/paste tool to serve span's instead of div's for casual icon insertion. It's being converted to "inline-block" anyway.
-
-V3.0:
-Mainly maintenance and a few new icons.
-- Fast forward, rewind, PollDaddy, Notice, Info, Help, Portfolio
-- Updated the feed icon. It's a bit smaller now for consistency, the previous one was rather big.
-- So, the previous version numbering, 2.09, wasn't very PHP version compare friendly. So from now on it'll be 3.0, 3.1 etc. Props Ipstenu.
-- Genericons.com now has a mini release blog.
-- The CSS has prettier formatting, props Konstantin Obenland.
-
-V2.09:
-Updated Facebook icon to new version. Updated Instagram logo to use new one-color version. Updated Google+ icon to use same radius as Instagram and Facebook. Added a bunch of new icons, cog, unapprove, cart, media player buttons, tablet, send to tablet.
-
-V2.06:
-Included Base64 encoded version. This is necessary for Genericons to work with CDNs in Firefox. Firefox blocks fonts linked from a different domain. A CDN (typically s.example.com) usually puts the font on a subdomain, and is hence blocked in Firefox.
-
-V2.05:
-Added a bunch of new icons, including upload to cloud, download to cloud, many more.
-
-V2:
-Initial public release
\ No newline at end of file
diff --git a/code/wp-content/themes/twentyfourteen/genericons/font/genericons-regular-webfont.eot b/code/wp-content/themes/twentyfourteen/genericons/font/genericons-regular-webfont.eot
deleted file mode 100644
index 46574695..00000000
Binary files a/code/wp-content/themes/twentyfourteen/genericons/font/genericons-regular-webfont.eot and /dev/null differ
diff --git a/code/wp-content/themes/twentyfourteen/genericons/font/genericons-regular-webfont.svg b/code/wp-content/themes/twentyfourteen/genericons/font/genericons-regular-webfont.svg
deleted file mode 100644
index ef236c10..00000000
--- a/code/wp-content/themes/twentyfourteen/genericons/font/genericons-regular-webfont.svg
+++ /dev/null
@@ -1,135 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/code/wp-content/themes/twentyfourteen/genericons/font/genericons-regular-webfont.ttf b/code/wp-content/themes/twentyfourteen/genericons/font/genericons-regular-webfont.ttf
deleted file mode 100644
index b6f125e7..00000000
Binary files a/code/wp-content/themes/twentyfourteen/genericons/font/genericons-regular-webfont.ttf and /dev/null differ
diff --git a/code/wp-content/themes/twentyfourteen/genericons/font/genericons-regular-webfont.woff b/code/wp-content/themes/twentyfourteen/genericons/font/genericons-regular-webfont.woff
deleted file mode 100644
index da8be383..00000000
Binary files a/code/wp-content/themes/twentyfourteen/genericons/font/genericons-regular-webfont.woff and /dev/null differ
diff --git a/code/wp-content/themes/twentyfourteen/genericons/genericons.css b/code/wp-content/themes/twentyfourteen/genericons/genericons.css
deleted file mode 100644
index b10b86fc..00000000
--- a/code/wp-content/themes/twentyfourteen/genericons/genericons.css
+++ /dev/null
@@ -1,197 +0,0 @@
-/**
-
- Genericons Helper CSS
-
-*/
-
-
-/**
- * The font was graciously generated by Font Squirrel (http://www.fontsquirrel.com). We love those guys.
- */
-
-@font-face {
- font-family: 'Genericons';
- src: url('font/genericons-regular-webfont.eot');
-}
-
-@font-face {
- font-family: 'Genericons';
- src: url(data:application/font-woff;charset=utf-8;base64,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) format('woff'),
- url('font/genericons-regular-webfont.ttf') format('truetype'),
- url('font/genericons-regular-webfont.svg#genericonsregular') format('svg');
- font-weight: normal;
- font-style: normal;
-}
-
-
-/**
- * All Genericons
- */
-
-.genericon {
- display: inline-block;
- width: 16px;
- height: 16px;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
- font-size: 16px;
- line-height: 1;
- font-family: 'Genericons';
- text-decoration: inherit;
- font-weight: normal;
- font-style: normal;
- vertical-align: top;
-}
-
-/**
- * IE7 and IE6 hacks
- */
-
-.genericon {
- *overflow: auto;
- *zoom: 1;
- *display: inline;
-}
-
-/**
- * Individual icons
- */
-
-/* Post formats */
-.genericon-standard:before { content: '\f100'; }
-.genericon-aside:before { content: '\f101'; }
-.genericon-image:before { content: '\f102'; }
-.genericon-gallery:before { content: '\f103'; }
-.genericon-video:before { content: '\f104'; }
-.genericon-status:before { content: '\f105'; }
-.genericon-quote:before { content: '\f106'; }
-.genericon-link:before { content: '\f107'; }
-.genericon-chat:before { content: '\f108'; }
-.genericon-audio:before { content: '\f109'; }
-
-/* Social icons */
-.genericon-github:before { content: '\f200'; }
-.genericon-dribbble:before { content: '\f201'; }
-.genericon-twitter:before { content: '\f202'; }
-.genericon-facebook:before { content: '\f203'; }
-.genericon-facebook-alt:before { content: '\f204'; }
-.genericon-wordpress:before { content: '\f205'; }
-.genericon-googleplus:before { content: '\f206'; }
-.genericon-linkedin:before { content: '\f207'; }
-.genericon-linkedin-alt:before { content: '\f208'; }
-.genericon-pinterest:before { content: '\f209'; }
-.genericon-pinterest-alt:before { content: '\f210'; }
-.genericon-flickr:before { content: '\f211'; }
-.genericon-vimeo:before { content: '\f212'; }
-.genericon-youtube:before { content: '\f213'; }
-.genericon-tumblr:before { content: '\f214'; }
-.genericon-instagram:before { content: '\f215'; }
-.genericon-codepen:before { content: '\f216'; }
-.genericon-polldaddy:before { content: '\f217'; }
-.genericon-googleplus-alt:before { content: '\f218'; }
-.genericon-path:before { content: '\f219'; }
-.genericon-skype:before { content: '\f220'; }
-.genericon-digg:before { content: '\f221'; }
-.genericon-reddit:before { content: '\f222'; }
-.genericon-stumbleupon:before { content: '\f223'; }
-.genericon-pocket:before { content: '\f224'; }
-.genericon-dropbox:before { content: '\f225'; }
-
-/* Meta icons */
-.genericon-comment:before { content: '\f300'; }
-.genericon-category:before { content: '\f301'; }
-.genericon-tag:before { content: '\f302'; }
-.genericon-time:before { content: '\f303'; }
-.genericon-user:before { content: '\f304'; }
-.genericon-day:before { content: '\f305'; }
-.genericon-week:before { content: '\f306'; }
-.genericon-month:before { content: '\f307'; }
-.genericon-pinned:before { content: '\f308'; }
-
-/* Other icons */
-.genericon-search:before { content: '\f400'; }
-.genericon-unzoom:before { content: '\f401'; }
-.genericon-zoom:before { content: '\f402'; }
-.genericon-show:before { content: '\f403'; }
-.genericon-hide:before { content: '\f404'; }
-.genericon-close:before { content: '\f405'; }
-.genericon-close-alt:before { content: '\f406'; }
-.genericon-trash:before { content: '\f407'; }
-.genericon-star:before { content: '\f408'; }
-.genericon-home:before { content: '\f409'; }
-.genericon-mail:before { content: '\f410'; }
-.genericon-edit:before { content: '\f411'; }
-.genericon-reply:before { content: '\f412'; }
-.genericon-feed:before { content: '\f413'; }
-.genericon-warning:before { content: '\f414'; }
-.genericon-share:before { content: '\f415'; }
-.genericon-attachment:before { content: '\f416'; }
-.genericon-location:before { content: '\f417'; }
-.genericon-checkmark:before { content: '\f418'; }
-.genericon-menu:before { content: '\f419'; }
-.genericon-refresh:before { content: '\f420'; }
-.genericon-minimize:before { content: '\f421'; }
-.genericon-maximize:before { content: '\f422'; }
-.genericon-404:before { content: '\f423'; }
-.genericon-spam:before { content: '\f424'; }
-.genericon-summary:before { content: '\f425'; }
-.genericon-cloud:before { content: '\f426'; }
-.genericon-key:before { content: '\f427'; }
-.genericon-dot:before { content: '\f428'; }
-.genericon-next:before { content: '\f429'; }
-.genericon-previous:before { content: '\f430'; }
-.genericon-expand:before { content: '\f431'; }
-.genericon-collapse:before { content: '\f432'; }
-.genericon-dropdown:before { content: '\f433'; }
-.genericon-dropdown-left:before { content: '\f434'; }
-.genericon-top:before { content: '\f435'; }
-.genericon-draggable:before { content: '\f436'; }
-.genericon-phone:before { content: '\f437'; }
-.genericon-send-to-phone:before { content: '\f438'; }
-.genericon-plugin:before { content: '\f439'; }
-.genericon-cloud-download:before { content: '\f440'; }
-.genericon-cloud-upload:before { content: '\f441'; }
-.genericon-external:before { content: '\f442'; }
-.genericon-document:before { content: '\f443'; }
-.genericon-book:before { content: '\f444'; }
-.genericon-cog:before { content: '\f445'; }
-.genericon-unapprove:before { content: '\f446'; }
-.genericon-cart:before { content: '\f447'; }
-.genericon-pause:before { content: '\f448'; }
-.genericon-stop:before { content: '\f449'; }
-.genericon-skip-back:before { content: '\f450'; }
-.genericon-skip-ahead:before { content: '\f451'; }
-.genericon-play:before { content: '\f452'; }
-.genericon-tablet:before { content: '\f453'; }
-.genericon-send-to-tablet:before { content: '\f454'; }
-.genericon-info:before { content: '\f455'; }
-.genericon-notice:before { content: '\f456'; }
-.genericon-help:before { content: '\f457'; }
-.genericon-fastforward:before { content: '\f458'; }
-.genericon-rewind:before { content: '\f459'; }
-.genericon-portfolio:before { content: '\f460'; }
-.genericon-heart:before { content: '\f461'; }
-.genericon-code:before { content: '\f462'; }
-.genericon-subscribe:before { content: '\f463'; }
-.genericon-unsubscribe:before { content: '\f464'; }
-.genericon-subscribed:before { content: '\f465'; }
-.genericon-reply-alt:before { content: '\f466'; }
-.genericon-reply-single:before { content: '\f467'; }
-.genericon-flag:before { content: '\f468'; }
-.genericon-print:before { content: '\f469'; }
-.genericon-lock:before { content: '\f470'; }
-.genericon-bold:before { content: '\f471'; }
-.genericon-italic:before { content: '\f472'; }
-.genericon-picture:before { content: '\f473'; }
-.genericon-fullscreen:before { content: '\f474'; }
-
-/* Generic shapes */
-.genericon-uparrow:before { content: '\f500'; }
-.genericon-rightarrow:before { content: '\f501'; }
-.genericon-downarrow:before { content: '\f502'; }
-.genericon-leftarrow:before { content: '\f503'; }
-
-
-
-
-
diff --git a/code/wp-content/themes/twentyfourteen/header.php b/code/wp-content/themes/twentyfourteen/header.php
deleted file mode 100644
index 7286d889..00000000
--- a/code/wp-content/themes/twentyfourteen/header.php
+++ /dev/null
@@ -1,65 +0,0 @@
- section and everything up till
', $message );
-}
-
-/**
- * Prevent the Customizer from being loaded on WordPress versions prior to 3.6.
- *
- * @since Twenty Fourteen 1.0
- */
-function twentyfourteen_customize() {
- wp_die( sprintf( __( 'Twenty Fourteen requires at least WordPress version 3.6. You are running version %s. Please upgrade and try again.', 'twentyfourteen' ), $GLOBALS['wp_version'] ), '', array(
- 'back_link' => true,
- ) );
-}
-add_action( 'load-customize.php', 'twentyfourteen_customize' );
-
-/**
- * Prevent the Theme Preview from being loaded on WordPress versions prior to 3.4.
- *
- * @since Twenty Fourteen 1.0
- */
-function twentyfourteen_preview() {
- if ( isset( $_GET['preview'] ) ) {
- wp_die( sprintf( __( 'Twenty Fourteen requires at least WordPress version 3.6. You are running version %s. Please upgrade and try again.', 'twentyfourteen' ), $GLOBALS['wp_version'] ) );
- }
-}
-add_action( 'template_redirect', 'twentyfourteen_preview' );
diff --git a/code/wp-content/themes/twentyfourteen/inc/custom-header.php b/code/wp-content/themes/twentyfourteen/inc/custom-header.php
deleted file mode 100644
index 287b1068..00000000
--- a/code/wp-content/themes/twentyfourteen/inc/custom-header.php
+++ /dev/null
@@ -1,147 +0,0 @@
- Header screen.
- * @type string $admin_preview_callback Callback function used to create the custom header markup in
- * the Appearance > Header screen.
- * }
- */
- add_theme_support( 'custom-header', apply_filters( 'twentyfourteen_custom_header_args', array(
- 'default-text-color' => 'fff',
- 'width' => 1260,
- 'height' => 240,
- 'flex-height' => true,
- 'wp-head-callback' => 'twentyfourteen_header_style',
- 'admin-head-callback' => 'twentyfourteen_admin_header_style',
- 'admin-preview-callback' => 'twentyfourteen_admin_header_image',
- ) ) );
-}
-add_action( 'after_setup_theme', 'twentyfourteen_custom_header_setup' );
-
-if ( ! function_exists( 'twentyfourteen_header_style' ) ) :
-/**
- * Styles the header image and text displayed on the blog
- *
- * @see twentyfourteen_custom_header_setup().
- *
- */
-function twentyfourteen_header_style() {
- $text_color = get_header_textcolor();
-
- // If no custom color for text is set, let's bail.
- if ( display_header_text() && $text_color === get_theme_support( 'custom-header', 'default-text-color' ) )
- return;
-
- // If we get this far, we have custom styles.
- ?>
-
- Header screen.
- *
- * @see twentyfourteen_custom_header_setup()
- *
- * @since Twenty Fourteen 1.0
- */
-function twentyfourteen_admin_header_style() {
-?>
-
- Header screen.
- *
- * @see twentyfourteen_custom_header_setup()
- *
- * @since Twenty Fourteen 1.0
- */
-function twentyfourteen_admin_header_image() {
-?>
-
-
-
-
-
-
-get_setting( 'blogname' )->transport = 'postMessage';
- $wp_customize->get_setting( 'blogdescription' )->transport = 'postMessage';
- $wp_customize->get_setting( 'header_textcolor' )->transport = 'postMessage';
-
- if ( isset( $wp_customize->selective_refresh ) ) {
- $wp_customize->selective_refresh->add_partial( 'blogname', array(
- 'selector' => '.site-title a',
- 'container_inclusive' => false,
- 'render_callback' => 'twentyfourteen_customize_partial_blogname',
- ) );
- $wp_customize->selective_refresh->add_partial( 'blogdescription', array(
- 'selector' => '.site-description',
- 'container_inclusive' => false,
- 'render_callback' => 'twentyfourteen_customize_partial_blogdescription',
- ) );
- }
-
- // Rename the label to "Site Title Color" because this only affects the site title in this theme.
- $wp_customize->get_control( 'header_textcolor' )->label = __( 'Site Title Color', 'twentyfourteen' );
-
- // Rename the label to "Display Site Title & Tagline" in order to make this option extra clear.
- $wp_customize->get_control( 'display_header_text' )->label = __( 'Display Site Title & Tagline', 'twentyfourteen' );
-
- // Add custom description to Colors and Background controls or sections.
- if ( property_exists( $wp_customize->get_control( 'background_color' ), 'description' ) ) {
- $wp_customize->get_control( 'background_color' )->description = __( 'May only be visible on wide screens.', 'twentyfourteen' );
- $wp_customize->get_control( 'background_image' )->description = __( 'May only be visible on wide screens.', 'twentyfourteen' );
- } else {
- $wp_customize->get_section( 'colors' )->description = __( 'Background may only be visible on wide screens.', 'twentyfourteen' );
- $wp_customize->get_section( 'background_image' )->description = __( 'Background may only be visible on wide screens.', 'twentyfourteen' );
- }
-
- // Add the featured content section in case it's not already there.
- $wp_customize->add_section( 'featured_content', array(
- 'title' => __( 'Featured Content', 'twentyfourteen' ),
- 'description' => sprintf( __( 'Use a tag to feature your posts. If no posts match the tag, sticky posts will be displayed instead.', 'twentyfourteen' ),
- esc_url( add_query_arg( 'tag', _x( 'featured', 'featured content default tag slug', 'twentyfourteen' ), admin_url( 'edit.php' ) ) ),
- admin_url( 'edit.php?show_sticky=1' )
- ),
- 'priority' => 130,
- 'active_callback' => 'is_front_page',
- ) );
-
- // Add the featured content layout setting and control.
- $wp_customize->add_setting( 'featured_content_layout', array(
- 'default' => 'grid',
- 'sanitize_callback' => 'twentyfourteen_sanitize_layout',
- ) );
-
- $wp_customize->add_control( 'featured_content_layout', array(
- 'label' => __( 'Layout', 'twentyfourteen' ),
- 'section' => 'featured_content',
- 'type' => 'select',
- 'choices' => array(
- 'grid' => __( 'Grid', 'twentyfourteen' ),
- 'slider' => __( 'Slider', 'twentyfourteen' ),
- ),
- ) );
-}
-add_action( 'customize_register', 'twentyfourteen_customize_register' );
-
-/**
- * Render the site title for the selective refresh partial.
- *
- * @since Twenty Fourteen 1.7
- * @see twentyfourteen_customize_register()
- *
- * @return void
- */
-function twentyfourteen_customize_partial_blogname() {
- bloginfo( 'name' );
-}
-
-/**
- * Render the site tagline for the selective refresh partial.
- *
- * @since Twenty Fourteen 1.7
- * @see twentyfourteen_customize_register()
- *
- * @return void
- */
-function twentyfourteen_customize_partial_blogdescription() {
- bloginfo( 'description' );
-}
-
-/**
- * Sanitize the Featured Content layout value.
- *
- * @since Twenty Fourteen 1.0
- *
- * @param string $layout Layout type.
- * @return string Filtered layout type (grid|slider).
- */
-function twentyfourteen_sanitize_layout( $layout ) {
- if ( ! in_array( $layout, array( 'grid', 'slider' ) ) ) {
- $layout = 'grid';
- }
-
- return $layout;
-}
-
-/**
- * Bind JS handlers to make Customizer preview reload changes asynchronously.
- *
- * @since Twenty Fourteen 1.0
- */
-function twentyfourteen_customize_preview_js() {
- wp_enqueue_script( 'twentyfourteen_customizer', get_template_directory_uri() . '/js/customizer.js', array( 'customize-preview' ), '20131205', true );
-}
-add_action( 'customize_preview_init', 'twentyfourteen_customize_preview_js' );
-
-/**
- * Add contextual help to the Themes and Post edit screens.
- *
- * @since Twenty Fourteen 1.0
- */
-function twentyfourteen_contextual_help() {
- if ( 'admin_head-edit.php' === current_filter() && 'post' !== $GLOBALS['typenow'] ) {
- return;
- }
-
- get_current_screen()->add_help_tab( array(
- 'id' => 'twentyfourteen',
- 'title' => __( 'Twenty Fourteen', 'twentyfourteen' ),
- 'content' =>
- '
' .
- '
' . sprintf( __( 'The home page features your choice of up to 6 posts prominently displayed in a grid or slider, controlled by a tag; you can change the tag and layout in Appearance → Customize. If no posts match the tag, sticky posts will be displayed instead.', 'twentyfourteen' ), esc_url( add_query_arg( 'tag', _x( 'featured', 'featured content default tag slug', 'twentyfourteen' ), admin_url( 'edit.php' ) ) ), admin_url( 'customize.php' ), admin_url( 'edit.php?show_sticky=1' ) ) . '
' .
- '
' . sprintf( __( 'Enhance your site design by using Featured Images for posts you’d like to stand out (also known as post thumbnails). This allows you to associate an image with your post without inserting it. Twenty Fourteen uses featured images for posts and pages—above the title—and in the Featured Content area on the home page.', 'twentyfourteen' ), 'https://codex.wordpress.org/Post_Thumbnails#Setting_a_Post_Thumbnail' ) . '
' .
- '
' . sprintf( __( 'For an in-depth tutorial, and more tips and tricks, visit the Twenty Fourteen documentation.', 'twentyfourteen' ), 'https://codex.wordpress.org/Twenty_Fourteen' ) . '
' .
- '
',
- ) );
-}
-add_action( 'admin_head-themes.php', 'twentyfourteen_contextual_help' );
-add_action( 'admin_head-edit.php', 'twentyfourteen_contextual_help' );
diff --git a/code/wp-content/themes/twentyfourteen/inc/featured-content.php b/code/wp-content/themes/twentyfourteen/inc/featured-content.php
deleted file mode 100644
index ffeb993d..00000000
--- a/code/wp-content/themes/twentyfourteen/inc/featured-content.php
+++ /dev/null
@@ -1,531 +0,0 @@
- $post_ids,
- 'posts_per_page' => count( $post_ids ),
- ) );
-
- return $featured_posts;
- }
-
- /**
- * Get featured post IDs
- *
- * This function will return the an array containing the
- * post IDs of all featured posts.
- *
- * Sets the "featured_content_ids" transient.
- *
- * @static
- * @access public
- * @since Twenty Fourteen 1.0
- *
- * @return array Array of post IDs.
- */
- public static function get_featured_post_ids() {
- // Get array of cached results if they exist.
- $featured_ids = get_transient( 'featured_content_ids' );
-
- if ( false === $featured_ids ) {
- $settings = self::get_setting();
- $term = get_term_by( 'name', $settings['tag-name'], 'post_tag' );
-
- if ( $term ) {
- // Query for featured posts.
- $featured_ids = get_posts( array(
- 'fields' => 'ids',
- 'numberposts' => self::$max_posts,
- 'suppress_filters' => false,
- 'tax_query' => array(
- array(
- 'field' => 'term_id',
- 'taxonomy' => 'post_tag',
- 'terms' => $term->term_id,
- ),
- ),
- ) );
- }
-
- // Get sticky posts if no Featured Content exists.
- if ( ! $featured_ids ) {
- $featured_ids = self::get_sticky_posts();
- }
-
- set_transient( 'featured_content_ids', $featured_ids );
- }
-
- // Ensure correct format before return.
- return array_map( 'absint', $featured_ids );
- }
-
- /**
- * Return an array with IDs of posts maked as sticky.
- *
- * @static
- * @access public
- * @since Twenty Fourteen 1.0
- *
- * @return array Array of sticky posts.
- */
- public static function get_sticky_posts() {
- return array_slice( get_option( 'sticky_posts', array() ), 0, self::$max_posts );
- }
-
- /**
- * Delete featured content ids transient.
- *
- * Hooks in the "save_post" action.
- *
- * @see Featured_Content::validate_settings().
- *
- * @static
- * @access public
- * @since Twenty Fourteen 1.0
- */
- public static function delete_transient() {
- delete_transient( 'featured_content_ids' );
- }
-
- /**
- * Exclude featured posts from the home page blog query.
- *
- * Filter the home page posts, and remove any featured post ID's from it.
- * Hooked onto the 'pre_get_posts' action, this changes the parameters of
- * the query before it gets any posts.
- *
- * @static
- * @access public
- * @since Twenty Fourteen 1.0
- *
- * @param WP_Query $query WP_Query object.
- * @return WP_Query Possibly-modified WP_Query.
- */
- public static function pre_get_posts( $query ) {
-
- // Bail if not home or not main query.
- if ( ! $query->is_home() || ! $query->is_main_query() ) {
- return;
- }
-
- // Bail if the blog page is not the front page.
- if ( 'posts' !== get_option( 'show_on_front' ) ) {
- return;
- }
-
- $featured = self::get_featured_post_ids();
-
- // Bail if no featured posts.
- if ( ! $featured ) {
- return;
- }
-
- // We need to respect post ids already in the blacklist.
- $post__not_in = $query->get( 'post__not_in' );
-
- if ( ! empty( $post__not_in ) ) {
- $featured = array_merge( (array) $post__not_in, $featured );
- $featured = array_unique( $featured );
- }
-
- $query->set( 'post__not_in', $featured );
- }
-
- /**
- * Reset tag option when the saved tag is deleted.
- *
- * It's important to mention that the transient needs to be deleted,
- * too. While it may not be obvious by looking at the function alone,
- * the transient is deleted by Featured_Content::validate_settings().
- *
- * Hooks in the "delete_post_tag" action.
- *
- * @see Featured_Content::validate_settings().
- *
- * @static
- * @access public
- * @since Twenty Fourteen 1.0
- *
- * @param int $tag_id The term_id of the tag that has been deleted.
- */
- public static function delete_post_tag( $tag_id ) {
- $settings = self::get_setting();
-
- if ( empty( $settings['tag-id'] ) || $tag_id != $settings['tag-id'] ) {
- return;
- }
-
- $settings['tag-id'] = 0;
- $settings = self::validate_settings( $settings );
- update_option( 'featured-content', $settings );
- }
-
- /**
- * Hide featured tag from displaying when global terms are queried from the front end.
- *
- * Hooks into the "get_terms" filter.
- *
- * @static
- * @access public
- * @since Twenty Fourteen 1.0
- *
- * @param array $terms List of term objects. This is the return value of get_terms().
- * @param array $taxonomies An array of taxonomy slugs.
- * @return array A filtered array of terms.
- *
- * @uses Featured_Content::get_setting()
- */
- public static function hide_featured_term( $terms, $taxonomies, $args ) {
-
- // This filter is only appropriate on the front end.
- if ( is_admin() ) {
- return $terms;
- }
-
- // We only want to hide the featured tag.
- if ( ! in_array( 'post_tag', $taxonomies ) ) {
- return $terms;
- }
-
- // Bail if no terms were returned.
- if ( empty( $terms ) ) {
- return $terms;
- }
-
- // Bail if term objects are unavailable.
- if ( 'all' != $args['fields'] ) {
- return $terms;
- }
-
- $settings = self::get_setting();
- foreach ( $terms as $order => $term ) {
- if ( ( $settings['tag-id'] === $term->term_id || $settings['tag-name'] === $term->name ) && 'post_tag' === $term->taxonomy ) {
- unset( $terms[ $order ] );
- }
- }
-
- return $terms;
- }
-
- /**
- * Hide featured tag from display when terms associated with a post object
- * are queried from the front end.
- *
- * Hooks into the "get_the_terms" filter.
- *
- * @static
- * @access public
- * @since Twenty Fourteen 1.0
- *
- * @param array $terms A list of term objects. This is the return value of get_the_terms().
- * @param int $id The ID field for the post object that terms are associated with.
- * @param array $taxonomy An array of taxonomy slugs.
- * @return array Filtered array of terms.
- *
- * @uses Featured_Content::get_setting()
- */
- public static function hide_the_featured_term( $terms, $id, $taxonomy ) {
-
- // This filter is only appropriate on the front end.
- if ( is_admin() ) {
- return $terms;
- }
-
- // Make sure we are in the correct taxonomy.
- if ( 'post_tag' != $taxonomy ) {
- return $terms;
- }
-
- // No terms? Return early!
- if ( empty( $terms ) ) {
- return $terms;
- }
-
- $settings = self::get_setting();
- foreach ( $terms as $order => $term ) {
- if ( ( $settings['tag-id'] === $term->term_id || $settings['tag-name'] === $term->name ) && 'post_tag' === $term->taxonomy ) {
- unset( $terms[ $term->term_id ] );
- }
- }
-
- return $terms;
- }
-
- /**
- * Register custom setting on the Settings -> Reading screen.
- *
- * @static
- * @access public
- * @since Twenty Fourteen 1.0
- */
- public static function register_setting() {
- register_setting( 'featured-content', 'featured-content', array( __CLASS__, 'validate_settings' ) );
- }
-
- /**
- * Add settings to the Customizer.
- *
- * @static
- * @access public
- * @since Twenty Fourteen 1.0
- *
- * @param WP_Customize_Manager $wp_customize Customizer object.
- */
- public static function customize_register( $wp_customize ) {
- $wp_customize->add_section( 'featured_content', array(
- 'title' => __( 'Featured Content', 'twentyfourteen' ),
- 'description' => sprintf( __( 'Use a tag to feature your posts. If no posts match the tag, sticky posts will be displayed instead.', 'twentyfourteen' ),
- esc_url( add_query_arg( 'tag', _x( 'featured', 'featured content default tag slug', 'twentyfourteen' ), admin_url( 'edit.php' ) ) ),
- admin_url( 'edit.php?show_sticky=1' )
- ),
- 'priority' => 130,
- 'theme_supports' => 'featured-content',
- ) );
-
- // Add Featured Content settings.
- $wp_customize->add_setting( 'featured-content[tag-name]', array(
- 'default' => _x( 'featured', 'featured content default tag slug', 'twentyfourteen' ),
- 'type' => 'option',
- 'sanitize_js_callback' => array( __CLASS__, 'delete_transient' ),
- ) );
- $wp_customize->add_setting( 'featured-content[hide-tag]', array(
- 'default' => true,
- 'type' => 'option',
- 'sanitize_js_callback' => array( __CLASS__, 'delete_transient' ),
- ) );
-
- // Add Featured Content controls.
- $wp_customize->add_control( 'featured-content[tag-name]', array(
- 'label' => __( 'Tag Name', 'twentyfourteen' ),
- 'section' => 'featured_content',
- 'priority' => 20,
- ) );
- $wp_customize->add_control( 'featured-content[hide-tag]', array(
- 'label' => __( 'Don’t display tag on front end.', 'twentyfourteen' ),
- 'section' => 'featured_content',
- 'type' => 'checkbox',
- 'priority' => 30,
- ) );
- }
-
- /**
- * Enqueue the tag suggestion script.
- *
- * @static
- * @access public
- * @since Twenty Fourteen 1.0
- */
- public static function enqueue_scripts() {
- wp_enqueue_script( 'featured-content-suggest', get_template_directory_uri() . '/js/featured-content-admin.js', array( 'jquery', 'suggest' ), '20131022', true );
- }
-
- /**
- * Get featured content settings.
- *
- * Get all settings recognized by this module. This function
- * will return all settings whether or not they have been stored
- * in the database yet. This ensures that all keys are available
- * at all times.
- *
- * In the event that you only require one setting, you may pass
- * its name as the first parameter to the function and only that
- * value will be returned.
- *
- * @static
- * @access public
- * @since Twenty Fourteen 1.0
- *
- * @param string $key The key of a recognized setting.
- * @return mixed Array of all settings by default. A single value if passed as first parameter.
- */
- public static function get_setting( $key = 'all' ) {
- $saved = (array) get_option( 'featured-content' );
-
- $defaults = array(
- 'hide-tag' => 1,
- 'tag-id' => 0,
- 'tag-name' => _x( 'featured', 'featured content default tag slug', 'twentyfourteen' ),
- );
-
- $options = wp_parse_args( $saved, $defaults );
- $options = array_intersect_key( $options, $defaults );
-
- if ( 'all' != $key ) {
- return isset( $options[ $key ] ) ? $options[ $key ] : false;
- }
-
- return $options;
- }
-
- /**
- * Validate featured content settings.
- *
- * Make sure that all user supplied content is in an expected
- * format before saving to the database. This function will also
- * delete the transient set in Featured_Content::get_featured_content().
- *
- * @static
- * @access public
- * @since Twenty Fourteen 1.0
- *
- * @param array $input Array of settings input.
- * @return array Validated settings output.
- */
- public static function validate_settings( $input ) {
- $output = array();
-
- if ( empty( $input['tag-name'] ) ) {
- $output['tag-id'] = 0;
- } else {
- $term = get_term_by( 'name', $input['tag-name'], 'post_tag' );
-
- if ( $term ) {
- $output['tag-id'] = $term->term_id;
- } else {
- $new_tag = wp_create_tag( $input['tag-name'] );
-
- if ( ! is_wp_error( $new_tag ) && isset( $new_tag['term_id'] ) ) {
- $output['tag-id'] = $new_tag['term_id'];
- }
- }
-
- $output['tag-name'] = $input['tag-name'];
- }
-
- $output['hide-tag'] = isset( $input['hide-tag'] ) && $input['hide-tag'] ? 1 : 0;
-
- // Delete the featured post ids transient.
- self::delete_transient();
-
- return $output;
- }
-} // Featured_Content
-
-Featured_Content::setup();
diff --git a/code/wp-content/themes/twentyfourteen/inc/template-tags.php b/code/wp-content/themes/twentyfourteen/inc/template-tags.php
deleted file mode 100644
index f63ee828..00000000
--- a/code/wp-content/themes/twentyfourteen/inc/template-tags.php
+++ /dev/null
@@ -1,227 +0,0 @@
-max_num_pages < 2 ) {
- return;
- }
-
- $paged = get_query_var( 'paged' ) ? intval( get_query_var( 'paged' ) ) : 1;
- $pagenum_link = html_entity_decode( get_pagenum_link() );
- $query_args = array();
- $url_parts = explode( '?', $pagenum_link );
-
- if ( isset( $url_parts[1] ) ) {
- wp_parse_str( $url_parts[1], $query_args );
- }
-
- $pagenum_link = remove_query_arg( array_keys( $query_args ), $pagenum_link );
- $pagenum_link = trailingslashit( $pagenum_link ) . '%_%';
-
- $format = $wp_rewrite->using_index_permalinks() && ! strpos( $pagenum_link, 'index.php' ) ? 'index.php/' : '';
- $format .= $wp_rewrite->using_permalinks() ? user_trailingslashit( $wp_rewrite->pagination_base . '/%#%', 'paged' ) : '?paged=%#%';
-
- // Set up paginated links.
- $links = paginate_links( array(
- 'base' => $pagenum_link,
- 'format' => $format,
- 'total' => $wp_query->max_num_pages,
- 'current' => $paged,
- 'mid_size' => 1,
- 'add_args' => array_map( 'urlencode', $query_args ),
- 'prev_text' => __( '← Previous', 'twentyfourteen' ),
- 'next_text' => __( 'Next →', 'twentyfourteen' ),
- ) );
-
- if ( $links ) :
-
- ?>
-
- post_parent ) : get_adjacent_post( false, '', true );
- $next = get_adjacent_post( false, '', false );
-
- if ( ! $next && ! $previous ) {
- return;
- }
-
- ?>
-
- ' . __( 'Sticky', 'twentyfourteen' ) . '';
- }
-
- // Set up and print post meta information.
- printf( '%5$s',
- esc_url( get_permalink() ),
- esc_attr( get_the_date( 'c' ) ),
- esc_html( get_the_date() ),
- esc_url( get_author_posts_url( get_the_author_meta( 'ID' ) ) ),
- get_the_author()
- );
-}
-endif;
-
-/**
- * Find out if blog has more than one category.
- *
- * @since Twenty Fourteen 1.0
- *
- * @return boolean true if blog has more than 1 category
- */
-function twentyfourteen_categorized_blog() {
- if ( false === ( $all_the_cool_cats = get_transient( 'twentyfourteen_category_count' ) ) ) {
- // Create an array of all the categories that are attached to posts
- $all_the_cool_cats = get_categories( array(
- 'hide_empty' => 1,
- ) );
-
- // Count the number of categories that are attached to the posts
- $all_the_cool_cats = count( $all_the_cool_cats );
-
- set_transient( 'twentyfourteen_category_count', $all_the_cool_cats );
- }
-
- if ( 1 !== (int) $all_the_cool_cats ) {
- // This blog has more than 1 category so twentyfourteen_categorized_blog should return true
- return true;
- } else {
- // This blog has only 1 category so twentyfourteen_categorized_blog should return false
- return false;
- }
-}
-
-/**
- * Flush out the transients used in twentyfourteen_categorized_blog.
- *
- * @since Twenty Fourteen 1.0
- */
-function twentyfourteen_category_transient_flusher() {
- // Like, beat it. Dig?
- delete_transient( 'twentyfourteen_category_count' );
-}
-add_action( 'edit_category', 'twentyfourteen_category_transient_flusher' );
-add_action( 'save_post', 'twentyfourteen_category_transient_flusher' );
-
-if ( ! function_exists( 'twentyfourteen_post_thumbnail' ) ) :
-/**
- * Display an optional post thumbnail.
- *
- * Wraps the post thumbnail in an anchor element on index
- * views, or a div element when on single views.
- *
- * @since Twenty Fourteen 1.0
- * @since Twenty Fourteen 1.4 Was made 'pluggable', or overridable.
- */
-function twentyfourteen_post_thumbnail() {
- if ( post_password_required() || is_attachment() || ! has_post_thumbnail() ) {
- return;
- }
-
- if ( is_singular() ) :
- ?>
-
-
',
- ) );
-}
-add_action( 'widgets_init', 'twentythirteen_widgets_init' );
-
-if ( ! function_exists( 'twentythirteen_paging_nav' ) ) :
-/**
- * Display navigation to next/previous set of posts when applicable.
- *
- * @since Twenty Thirteen 1.0
- */
-function twentythirteen_paging_nav() {
- global $wp_query;
-
- // Don't print empty markup if there's only one page.
- if ( $wp_query->max_num_pages < 2 )
- return;
- ?>
-
- post_parent ) : get_adjacent_post( false, '', true );
- $next = get_adjacent_post( false, '', false );
-
- if ( ! $next && ! $previous )
- return;
- ?>
-
- ' . esc_html__( 'Sticky', 'twentythirteen' ) . '';
-
- if ( ! has_post_format( 'link' ) && 'post' == get_post_type() )
- twentythirteen_entry_date();
-
- // Translators: used between list items, there is a space after the comma.
- $categories_list = get_the_category_list( __( ', ', 'twentythirteen' ) );
- if ( $categories_list ) {
- echo '' . $categories_list . '';
- }
-
- // Translators: used between list items, there is a space after the comma.
- $tag_list = get_the_tag_list( '', __( ', ', 'twentythirteen' ) );
- if ( $tag_list ) {
- echo '' . $tag_list . '';
- }
-
- // Post author
- if ( 'post' == get_post_type() ) {
- printf( '%3$s',
- esc_url( get_author_posts_url( get_the_author_meta( 'ID' ) ) ),
- esc_attr( sprintf( __( 'View all posts by %s', 'twentythirteen' ), get_the_author() ) ),
- get_the_author()
- );
- }
-}
-endif;
-
-if ( ! function_exists( 'twentythirteen_entry_date' ) ) :
-/**
- * Print HTML with date information for current post.
- *
- * Create your own twentythirteen_entry_date() to override in a child theme.
- *
- * @since Twenty Thirteen 1.0
- *
- * @param boolean $echo (optional) Whether to echo the date. Default true.
- * @return string The HTML-formatted post date.
- */
-function twentythirteen_entry_date( $echo = true ) {
- if ( has_post_format( array( 'chat', 'status' ) ) )
- $format_prefix = _x( '%1$s on %2$s', '1: post format name. 2: date', 'twentythirteen' );
- else
- $format_prefix = '%2$s';
-
- $date = sprintf( '',
- esc_url( get_permalink() ),
- esc_attr( sprintf( __( 'Permalink to %s', 'twentythirteen' ), the_title_attribute( 'echo=0' ) ) ),
- esc_attr( get_the_date( 'c' ) ),
- esc_html( sprintf( $format_prefix, get_post_format_string( get_post_format() ), get_the_date() ) )
- );
-
- if ( $echo )
- echo $date;
-
- return $date;
-}
-endif;
-
-if ( ! function_exists( 'twentythirteen_the_attached_image' ) ) :
-/**
- * Print the attached image with a link to the next attached image.
- *
- * @since Twenty Thirteen 1.0
- */
-function twentythirteen_the_attached_image() {
- /**
- * Filter the image attachment size to use.
- *
- * @since Twenty thirteen 1.0
- *
- * @param array $size {
- * @type int The attachment height in pixels.
- * @type int The attachment width in pixels.
- * }
- */
- $attachment_size = apply_filters( 'twentythirteen_attachment_size', array( 724, 724 ) );
- $next_attachment_url = wp_get_attachment_url();
- $post = get_post();
-
- /*
- * Grab the IDs of all the image attachments in a gallery so we can get the URL
- * of the next adjacent image in a gallery, or the first image (if we're
- * looking at the last image in a gallery), or, in a gallery of one, just the
- * link to that image file.
- */
- $attachment_ids = get_posts( array(
- 'post_parent' => $post->post_parent,
- 'fields' => 'ids',
- 'numberposts' => -1,
- 'post_status' => 'inherit',
- 'post_type' => 'attachment',
- 'post_mime_type' => 'image',
- 'order' => 'ASC',
- 'orderby' => 'menu_order ID',
- ) );
-
- // If there is more than 1 attachment in a gallery...
- if ( count( $attachment_ids ) > 1 ) {
- foreach ( $attachment_ids as $attachment_id ) {
- if ( $attachment_id == $post->ID ) {
- $next_id = current( $attachment_ids );
- break;
- }
- }
-
- // get the URL of the next image attachment...
- if ( $next_id )
- $next_attachment_url = get_attachment_link( $next_id );
-
- // or get the URL of the first image attachment.
- else
- $next_attachment_url = get_attachment_link( reset( $attachment_ids ) );
- }
-
- printf( '%3$s',
- esc_url( $next_attachment_url ),
- the_title_attribute( array( 'echo' => false ) ),
- wp_get_attachment_image( $post->ID, $attachment_size )
- );
-}
-endif;
-
-/**
- * Return the post URL.
- *
- * @uses get_url_in_content() to get the URL in the post meta (if it exists) or
- * the first link found in the post content.
- *
- * Falls back to the post permalink if no URL is found in the post.
- *
- * @since Twenty Thirteen 1.0
- *
- * @return string The Link format URL.
- */
-function twentythirteen_get_link_url() {
- $content = get_the_content();
- $has_url = get_url_in_content( $content );
-
- return ( $has_url ) ? $has_url : apply_filters( 'the_permalink', get_permalink() );
-}
-
-if ( ! function_exists( 'twentythirteen_excerpt_more' ) && ! is_admin() ) :
-/**
- * Replaces "[...]" (appended to automatically generated excerpts) with ...
- * and a Continue reading link.
- *
- * @since Twenty Thirteen 1.4
- *
- * @param string $more Default Read More excerpt link.
- * @return string Filtered Read More excerpt link.
- */
-function twentythirteen_excerpt_more( $more ) {
- $link = sprintf( '%2$s',
- esc_url( get_permalink( get_the_ID() ) ),
- /* translators: %s: Name of current post */
- sprintf( __( 'Continue reading %s →', 'twentythirteen' ), '' . get_the_title( get_the_ID() ) . '' )
- );
- return ' … ' . $link;
-}
-add_filter( 'excerpt_more', 'twentythirteen_excerpt_more' );
-endif;
-
-/**
- * Extend the default WordPress body classes.
- *
- * Adds body classes to denote:
- * 1. Single or multiple authors.
- * 2. Active widgets in the sidebar to change the layout and spacing.
- * 3. When avatars are disabled in discussion settings.
- *
- * @since Twenty Thirteen 1.0
- *
- * @param array $classes A list of existing body class values.
- * @return array The filtered body class list.
- */
-function twentythirteen_body_class( $classes ) {
- if ( ! is_multi_author() )
- $classes[] = 'single-author';
-
- if ( is_active_sidebar( 'sidebar-2' ) && ! is_attachment() && ! is_404() )
- $classes[] = 'sidebar';
-
- if ( ! get_option( 'show_avatars' ) )
- $classes[] = 'no-avatars';
-
- return $classes;
-}
-add_filter( 'body_class', 'twentythirteen_body_class' );
-
-/**
- * Adjust content_width value for video post formats and attachment templates.
- *
- * @since Twenty Thirteen 1.0
- */
-function twentythirteen_content_width() {
- global $content_width;
-
- if ( is_attachment() )
- $content_width = 724;
- elseif ( has_post_format( 'audio' ) )
- $content_width = 484;
-}
-add_action( 'template_redirect', 'twentythirteen_content_width' );
-
-/**
- * Add postMessage support for site title and description for the Customizer.
- *
- * @since Twenty Thirteen 1.0
- *
- * @param WP_Customize_Manager $wp_customize Customizer object.
- */
-function twentythirteen_customize_register( $wp_customize ) {
- $wp_customize->get_setting( 'blogname' )->transport = 'postMessage';
- $wp_customize->get_setting( 'blogdescription' )->transport = 'postMessage';
- $wp_customize->get_setting( 'header_textcolor' )->transport = 'postMessage';
-}
-add_action( 'customize_register', 'twentythirteen_customize_register' );
-
-/**
- * Enqueue Javascript postMessage handlers for the Customizer.
- *
- * Binds JavaScript handlers to make the Customizer preview
- * reload changes asynchronously.
- *
- * @since Twenty Thirteen 1.0
- */
-function twentythirteen_customize_preview_js() {
- wp_enqueue_script( 'twentythirteen-customizer', get_template_directory_uri() . '/js/theme-customizer.js', array( 'customize-preview' ), '20141120', true );
-}
-add_action( 'customize_preview_init', 'twentythirteen_customize_preview_js' );
diff --git a/code/wp-content/themes/twentythirteen/genericons/COPYING.txt b/code/wp-content/themes/twentythirteen/genericons/COPYING.txt
deleted file mode 100644
index aece214b..00000000
--- a/code/wp-content/themes/twentythirteen/genericons/COPYING.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-Genericons is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
-
-The fonts are distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-
-As a special exception, if you create a document which uses this font, and embed this font or unaltered portions of this font into the document, this font does not by itself cause the resulting document to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the document might be covered by the GNU General Public License. If you modify this font, you may extend this exception to your version of the font, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version.
-
-This license does not convey any intellectual property rights to third party trademarks that may be included in the icon font; such marks remain subject to all rights and guidelines of use of their owner.
\ No newline at end of file
diff --git a/code/wp-content/themes/twentythirteen/genericons/Genericons-Regular.otf b/code/wp-content/themes/twentythirteen/genericons/Genericons-Regular.otf
deleted file mode 100644
index 5cd41e8b..00000000
Binary files a/code/wp-content/themes/twentythirteen/genericons/Genericons-Regular.otf and /dev/null differ
diff --git a/code/wp-content/themes/twentythirteen/genericons/LICENSE.txt b/code/wp-content/themes/twentythirteen/genericons/LICENSE.txt
deleted file mode 100644
index d159169d..00000000
--- a/code/wp-content/themes/twentythirteen/genericons/LICENSE.txt
+++ /dev/null
@@ -1,339 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Lesser General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-
- Copyright (C)
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) year name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- , 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.
diff --git a/code/wp-content/themes/twentythirteen/genericons/README.txt b/code/wp-content/themes/twentythirteen/genericons/README.txt
deleted file mode 100644
index 7a0a92e5..00000000
--- a/code/wp-content/themes/twentythirteen/genericons/README.txt
+++ /dev/null
@@ -1,123 +0,0 @@
- ___ ____ __ _ ____ ____ __ ___ __ __ _ ____
- / __)( __)( ( \( __)( _ \( )/ __)/ \ ( ( \/ ___)
-( (_ \ ) _) / / ) _) ) / )(( (__( O )/ /\___ \
- \___/(____)\_)__)(____)(__\_)(__)\___)\__/ \_)__)(____/
-
-
-Genericons are vector icons embedded in a webfont designed to be clean and simple keeping with a generic aesthetic.
-
-Use genericons for instant HiDPI, to change icon colors on the fly, or even with CSS effects such as drop-shadows or gradients!
-
-
-_ _ ____ ____ ____ ____
-| | [__ |__| | __ |___
-|__| ___] | | |__] |___
-
-
-To use it, place the font folder in your stylesheet directory and paste this in your CSS file:
-
-/* =Genericons, thanks to FontSquirrel.com for conversion!
--------------------------------------------------------------- */
-@font-face {
- font-family: 'Genericons';
- src: url('font/genericons-regular-webfont.eot');
- src: url('font/genericons-regular-webfont.eot?#iefix') format('embedded-opentype'),
- url('font/genericons-regular-webfont.woff') format('woff'),
- url('font/genericons-regular-webfont.ttf') format('truetype'),
- url('font/genericons-regular-webfont.svg#genericonsregular') format('svg');
- font-weight: normal;
- font-style: normal;
-
-}
-
-Note: the above only works if you don't use a CDN. If you do, or don't know what that is, you should use the syntax that's embedded in genericons.css.
-
-From then on, you can create an icon like this:
-
-.my-icon:before {
- content: '\f101';
- display: inline-block;
- -webkit-font-smoothing: antialiased;
- font: normal 16px/1 'Genericons';
- vertical-align: top;
-}
-
-This will output a comment icon before every element with the class "my-icon". The "content: '\f101';" part of this CSS is easily copied from the helper tool at http://genericons.com/
-
-You can also use the bundled example.css if you'd rather insert the icons using HTML tags.
-
-
-_ _ ____ ___ ____ ____
-|\ | | | | |___ [__
-| \| |__| | |___ ___]
-
-
-Photoshop mockups:
-
-Genericons-Regular.otf found in the root directory of this zip has not been web-font-ified. So you can drop it in your system fonts folder and use the font in Photoshop if you like.
-
-For those of you using Genericons in your Photoshop mockup, remember to delete the old version of the font from Font Book, and grab the new one from the zip file. This also affects using it in your webdesigns: if you have an old version of the font installed locally, that's the font that'll be used in your website as well, so if you're missing icons, check for old versions of the font on your system.
-
-Pixel grid:
-
-Note that Genericons has been designed for a 16x16 pixel grid. That means it'll look sharp at font-size: 16px exactly. It'll also be crisp at multiples thereof, such as 32px or 64px. It'll also look reasonably crisp at in-between font sizes such as 24px or 48px, but not quite as crisp as 16 or 32. Please don't set the font-size to 17px, though, that'll just look terrible.
-
-Also note the CSS property "-webkit-font-smoothing: antialiased". That makes the icons look great in WebKit browsers. Please see http://noscope.com/2012/font-smoothing for more info.
-
-Updates:
-
-We don't often update icons, but do very carefully when we get good feedback suggesting improvements. Please be mindful if you upgrade, and check that the updated icons behave as you intended.
-
-
-
-____ _ _ ____ _ _ ____ ____ _ ____ ____
-| |__| |__| |\ | | __ |___ | | | | __
-|___ | | | | | \| |__] |___ |___ |__| |__]
-
-V3.0.3:
-Bunch of updates mostly.
-- Two new icons, Dropbox and Fullscreen.
-- Updates to all icons containing an exclamation mark.
-- Updates to Image and Quote.
-- Nicer "Share" icon.
-- Bigger default Linkedin icon.
-
-V3.0.2:
-A slew of new stuff and updates.
-- Social icons: Skype, Digg, Reddit, Stumbleupon, Pocket.
-- New generic icons: heart, lock and print.
-- New editing icons: code, bold, italic, image
-- New interaction icons: subscribe, unsubscribe, subscribed, reply all, reply, flag.
-- The hyperlink icon has been updated to be clearer, chunkier.
-- The "home" icon has been updated for style, size and clarity.
-- The email icon has been updated for style and clarity, and to fit with the new subscribe icons.
-- The document icon has been updated for style.
-- The "pin" icon has been updated for style and clarity.
-- The Twitter icon has been scaled down to fit with the other social icons.
-
-V3.0.1:
-Mostly maintenance.
-- Fixed an issue with the example page that showed an old "top" icon instead of the actual NEW "refresh" icon.
-- Added inverse Google+ and Path.
-- Replaced tabs with spaces in the helper CSS.
-- Changed the Genericons.com copy/paste tool to serve span's instead of div's for casual icon insertion. It's being converted to "inline-block" anyway.
-
-V3.0:
-Mainly maintenance and a few new icons.
-- Fast forward, rewind, PollDaddy, Notice, Info, Help, Portfolio
-- Updated the feed icon. It's a bit smaller now for consistency, the previous one was rather big.
-- So, the previous version numbering, 2.09, wasn't very PHP version compare friendly. So from now on it'll be 3.0, 3.1 etc. Props Ipstenu.
-- Genericons.com now has a mini release blog.
-- The CSS has prettier formatting, props Konstantin Obenland.
-
-V2.09:
-Updated Facebook icon to new version. Updated Instagram logo to use new one-color version. Updated Google+ icon to use same radius as Instagram and Facebook. Added a bunch of new icons, cog, unapprove, cart, media player buttons, tablet, send to tablet.
-
-V2.06:
-Included Base64 encoded version. This is necessary for Genericons to work with CDNs in Firefox. Firefox blocks fonts linked from a different domain. A CDN (typically s.example.com) usually puts the font on a subdomain, and is hence blocked in Firefox.
-
-V2.05:
-Added a bunch of new icons, including upload to cloud, download to cloud, many more.
-
-V2:
-Initial public release
\ No newline at end of file
diff --git a/code/wp-content/themes/twentythirteen/genericons/font/genericons-regular-webfont.eot b/code/wp-content/themes/twentythirteen/genericons/font/genericons-regular-webfont.eot
deleted file mode 100644
index 46574695..00000000
Binary files a/code/wp-content/themes/twentythirteen/genericons/font/genericons-regular-webfont.eot and /dev/null differ
diff --git a/code/wp-content/themes/twentythirteen/genericons/font/genericons-regular-webfont.svg b/code/wp-content/themes/twentythirteen/genericons/font/genericons-regular-webfont.svg
deleted file mode 100644
index ef236c10..00000000
--- a/code/wp-content/themes/twentythirteen/genericons/font/genericons-regular-webfont.svg
+++ /dev/null
@@ -1,135 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/code/wp-content/themes/twentythirteen/genericons/font/genericons-regular-webfont.ttf b/code/wp-content/themes/twentythirteen/genericons/font/genericons-regular-webfont.ttf
deleted file mode 100644
index b6f125e7..00000000
Binary files a/code/wp-content/themes/twentythirteen/genericons/font/genericons-regular-webfont.ttf and /dev/null differ
diff --git a/code/wp-content/themes/twentythirteen/genericons/font/genericons-regular-webfont.woff b/code/wp-content/themes/twentythirteen/genericons/font/genericons-regular-webfont.woff
deleted file mode 100644
index da8be383..00000000
Binary files a/code/wp-content/themes/twentythirteen/genericons/font/genericons-regular-webfont.woff and /dev/null differ
diff --git a/code/wp-content/themes/twentythirteen/genericons/genericons.css b/code/wp-content/themes/twentythirteen/genericons/genericons.css
deleted file mode 100644
index b10b86fc..00000000
--- a/code/wp-content/themes/twentythirteen/genericons/genericons.css
+++ /dev/null
@@ -1,197 +0,0 @@
-/**
-
- Genericons Helper CSS
-
-*/
-
-
-/**
- * The font was graciously generated by Font Squirrel (http://www.fontsquirrel.com). We love those guys.
- */
-
-@font-face {
- font-family: 'Genericons';
- src: url('font/genericons-regular-webfont.eot');
-}
-
-@font-face {
- font-family: 'Genericons';
- src: url(data:application/font-woff;charset=utf-8;base64,d09GRgABAAAAAENIABEAAAAAatQAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAABgAAAABwAAAAcaii0EkdERUYAAAGcAAAAHQAAACAArQAET1MvMgAAAbwAAABCAAAAYJdbaIVjbWFwAAACAAAAAJgAAAGyqWnWY2N2dCAAAAKYAAAADgAAAA4BYgHJZnBnbQAAAqgAAAGxAAACZVO0L6dnYXNwAAAEXAAAAAgAAAAIAAAAEGdseWYAAARkAAA5fgAAWkD4H3YjaGVhZAAAPeQAAAArAAAANgUfUT9oaGVhAAA+EAAAABwAAAAkEAMH3WhtdHgAAD4sAAAAiAAAAQpVkUB7bG9jYQAAPrQAAAECAAABAoDMauhtYXhwAAA/uAAAACAAAAAgAagCQm5hbWUAAD/YAAABYgAAAthC114IcG9zdAAAQTwAAAHUAAAFCuMEJONwcmVwAABDEAAAAC4AAAAusPIrFHdlYmYAAENAAAAABgAAAAbRQFLPAAAAAQAAAADMPaLPAAAAAM71j4QAAAAAzvWBvnjaY2BkYGDgA2IJBhBgYmAEwnogZgHzGAAJvwCyAAAAeNpjYGb/zDiBgZWBhdWY5QwDA8NMCM10hsEIzAdKYQeh3uF+DA6qf74ys6X9S2Ng4GBg0AAKMyIpUWBgBACOigvWAAB42mNgYGBmgGAZBkYGEFgD5DGC+SwME4C0AhCyMDCo/vnI+Ynzk+Qn1c8cXzi/SH7R/GL5xfNL5JfMLyVfmf//B6tg+MTwSeCTwmeGLwxfBL4ofDH44vAl4EvCl4KvDP//32LnZ+Hj4+PgY+LV4DHk0eZR5ZHnkeQR5uHlYeeugdqOFzCyMcCVMTIBCSZ0BQzDHgAA5FwqMwAAAQkARQBBAGYAfwC3AAB42l1Ru05bQRDdDQ8DgcTYIDnaFLOZkMZ7oQUJxNWNYmQ7heUIaTdykYtxAR9AgUQN2q8ZoKGkSJsGIRdIfEI+IRIza4iiNDs7s3POmTNLypGqd+lrz1PnJJDC3QbNNv1OSLWzAPek6+uNjLSDB1psZvTKdfv+Cwab0ZQ7agDlPW8pDxlNO4FatKf+0fwKhvv8H/M7GLQ00/TUOgnpIQTmm3FLg+8ZzbrLD/qC1eFiMDCkmKbiLj+mUv63NOdqy7C1kdG8gzMR+ck0QFNrbQSa/tQh1fNxFEuQy6axNpiYsv4kE8GFyXRVU7XM+NrBXbKz6GCDKs2BB9jDVnkMHg4PJhTStyTKLA0R9mKrxAgRkxwKOeXcyf6kQPlIEsa8SUo744a1BsaR18CgNk+z/zybTW1vHcL4WRzBd78ZSzr4yIbaGBFiO2IpgAlEQkZV+YYaz70sBuRS+89AlIDl8Y9/nQi07thEPJe1dQ4xVgh6ftvc8suKu1a5zotCd2+qaqjSKc37Xs6+xwOeHgvDQWPBm8/7/kqB+jwsrjRoDgRDejd6/6K16oirvBc+sifTv7FaAAAAAAEAAf//AA942q18C3xU1bnvWnvveSaZmT3PZJKZzHtCJpkJ88hkIIQhCAECCAQCCCooggTkjS9q3Vqpioo9tqJVK2hbsdpj90xA2mJrjtVaW0fLFbmt1h6xp1ptPcfe9rSKmc39vrVnQhBsz/39bmBm7732npm1vvU9/t9jLaIh8Ef/yj1DeKIlBlJLzIRMFP1i2Mbb/DXUZeNdIv2r0vPEE166+An4u/MJ7pnyBZeS0+R0+XVymi6HE+X4aaoQSsb9TSREyxEOvlQjwXfrSA18s424yJVEJgmZlmQhIVtSsqYki0lZn5DtKdlQkh1JuTYh15WoXJ+QhRNFoq9NJpOyrlTUCcbYcF7HG/C9xhCTdZaCncZkV6lgsiaTRbsL79sthlihgcZIx0Sa8TvO9+KgO2Xo7GnCSWVJIGWJk07DNUckiY57KZUj4Sjc1cE/GION9BLZmJDNJdkGHYR+2mEwJ6DHcp2lIEJ/dKWCg8YKYp1oHRYMRj7kypGCzQxXVKsjcNUxkVisIZ9gtXCCL0TszmRnOhKg5BW6mj5KV7/yirJfuUTZT5P7ju/bd5xPjG985RXuIWzdhyQWiEQlnaSVGHVdxE+uZ7SFvvkSciMQMyHzpWEj79DH5JqSrIfeBlhva0tyraVQD731lGSPpWCFM22pEIR+11LRWtAbczm5XpS5nOyBUfAOM/RbtoqyBsbS6IOxaKm1FtscYoHT5GBMNuAYv00jIoVtdpJKkkyaBAPEle70OR12rS8iAYHZ/0+ArHmq+8EPqVY59cMfKJ9IR6nx6FHlb0epxCPNTxNpVBJ8B1aV34a7Y0/uPnp09y3PPIPj5oh+PF9Nx3EX9LWpFDKWIYm8BYxVl6SyJSGTE7KQBErIvKWgp4wU2qRcY4GxxoBYOGsEB+AXaeWVghfQVoHuKHCEA0fwUn1XiHprVALRwSYtzgEHFyJcCvABDTAV3sNTCfimjqQJlU2sK9AvTWnYoCEwKcYS8pKhVDAD5Y1EtALFCxoDHPkccnCFdjpRI8bh207SnpN3bz1Ntt6tkfafPLn/C8+3lP8gcfe3PM94FH5JS4iROMhKImsTspgCZpStSeSJGkaZWiCIk/WCUUP9/aKRR8kxakGmgEI1QBRTSTZZZAdyUNFhwrsOEeTKpcoVEMdOgmKyM+M/cwryIynHjw/t46onQDSQr+PKcUr2DY07JRzSjNGlgaTIPoKiDnMSS8he4NA065++VNQT/GG9AN3SWwpu6Fa8VIy7sTE+ERrjlkIdNDpKxToHNtZBF2WHpRCFRn+pGPVjYzQE/c4Add164GtjfS5XqIsD/9a4PDHg30LUAc3e1hzwdawGJVYMTWQySsV0Z9ahdYgonxkxHc14KVwAH+MdmBY412XwTiSAT7kcMENkaDC/5cCW/OAQ42aCfD3WxI1QafX+8H25JYq0YMuWBVRakrsvvH+1IgFjcxqKh91K5RHKHlHUR0DWgbvIiA5pZiVB0kZkf0K2pXCKgMFrU0wThRJy/QmQ6EIY5qkgWICNGmAkDcBGKX+S9Tjop2IwEKFZPw5KbYsB2x5YJZBVBw6sUvJKXlp1gEfN8vivsEVS8sjR7Ca8K3k6ckBZJf3qcSqdaSGEp1U50EAPfWRmRctT7Kj+BOoks6XghKlpKhUCMB9mmI9ho9VWj1rEKRYafDgHFGTgsNZgdjibKrMAHabhznQ06+VRElw9NB2BC+qwm6gOf5TJZaa/f4V7gscyOXNR34UX9q1Ydnl8YBJPkNE+hVd///H+FY1TZsyNzr+z86K+o7882rdi+Qc3L33srslo/uCV1oNGIevIBiJfkZAvKcmtqEGofCXjxs6S3GkpNFKU2MJ66H0n9LPYP29BDvRko/i0xuLovmDJZUzVX3IFcJTlMrjRKuZrjDYPaWlL52cPXooD1VgPBULhjiQbnJi2klAqKRCrw0I02kgm3ZlJR3sEfOMi0Tg1cbpIVKuL82aqdWkddi/v0upMNE6jcSHaSk3U6fIKLq+uM2tHNRENkUepje765TG6i1ofVa5TfhEK0BnzrpMGs+u1Rr3ZJtSlui/PXr1nz9XZy3oSRuOkjvXZQem6uZnapqnLlvo4gyfQ6RFqGwyimzd43IE6ytdZm0OdUxbFaSCk/EK5TiC/pF+AL39U+U9l9zGlUP7jOl1zg/D8wpsnG5pnDT217ZGt5pZZl06knGCdGPZznD88UdRy3D03bN+/7amhWT594qI6E+3KCnXBxnpOV+O2wtiau/y83t3Q3OAEXZS8Vqj3addxTrRxOnxjc2MmjYzzJ5E+soDsIMU6QmJypITao7kkd6nztZDZNwuIhaVwIcxXbxLV6yKYsgtBHvJ1mto6wdnUHGppz0yexearPgLtRgOxtfZMzfcumIvT1Cwe0tMmz2Q877IW/YkLcmjj6ilMmA/mywJqHkw3b7e6Okk2Eq2l0awzlOWiWkKd/mSW47XE5rT1CNlIKBjQUi/n6hRcXNTE2bwUPmPNhr6FM0UfgpftW99SPlR2K2vg9WFox8Yb6Hffs+SVd5Wtf/c9R/+6567h55Q/U/FXdNbho/7v/Va57W9rf649MO+O9RO+qBz5gU+iC5yeqPYJOvd695f7nv77YtOkFZ6HXq5X/sQnz/3+b8HvcrMPKq9eW6Kd8zqkwWT9V5yz4tT9tyXK0U8fGFlA2+gtc5RjmvWPKY9xk3w9vaEv3mMpb/GkFtf6tY3UM5y7dEh5tPF+5ef3baSLR+JMfiTaBjjkN6DNYdgpXxY41JlKwmEKsGicZtJZp+BC/k4lXZ1ZrQ5fyLImXgj6pI4WSn52zTOhqDeRvPHxBUvnLkvuoXveMf7q/gMbpfWt11y1dvYm2rPz6XeUX39LeZUe03yDu3uzrs7981s0MT756CVXLH7iFzXR9vv/9w731Fv66to3L9D59Nd//MEv7l+KfSOAkXQSiZILCKpIUJYBMG9JWUzIvpTsLMlulXVaAHeeQDAKMNRgAVwpuwBLpQoTgHlcgOZkd47BhPHaVPTb/FNQv7qykWDAxHloEMFDICLtG9KQoX37hpR3qalWeTfW+5h2/vpL7lnWpijltqF9iBHw9qfwzr1IhZHa7iz9P8bsJTsv+JMyWs4hwAOLTyTNe9D3BjKf6VMHs+K2ZJFQNG7EBRYPUIVetexupv+5JHZdTBZd9fiMy2GIFesZNq4nYAsbKzY8JaZ7uFTS2Ux54FAP5+fRmHPSb9Nrn7wqO+R26/5tborONikvKCP8SzRBufl7NuW1PK+8m59helU5NnqEn01A21fpawbcsRiQx1qyl8h1CXlpSW5OFMJpwGSNpcKEOKD4RSqh142T0W6Q0QuT8ppSsXsN9rG7H4a0xlJYBe0guFcC7btRcA0ouDbnkuUXM6FtXorCTPUGYrcFsn0rL161BmW1UTzkjM3qR0UsL7IWWjpQaq0WaydIrROkVgtSG0GppVpbKtk5lXY6tTqtjtp40LadLqfa5qVqYw+XSaOuNSDjulCSBYpsHYnytNMKWho4WCft/YjOpRvp3I/27v1IOaR8TTn0UfpUSblx5u50eGMw4LCZ7G0TaUS+YYndbLfvvjCyIRi02KjZEptIgwvrATnU2zmbxqKt1eh5fv4k4ybl/QdfVR6iF27ZsedmgfuY3nrkjcs1U/g5n/kVOOO4Pym71gieh6hJw/G0OcBruNH7OJEu03EBHzVio63ByUHrw7T2wtxKf3x5JiB4jY019SanaDfmBukVm58/9XV/XKvhDpb3DtHtb7463NJ66wOqfzE2tzPIcnIFeYjISxNyS0qeXUK+AxA5HRyNlGwvFafbcfqme2H6GoAX16pzjJ4bOmpg8WV3Ug6Btk4WAyF8NNAF3LgO5lcHHscwb5q5AmctIOaNmhrvhFhv/+LB1WyuZ8NcF0lsJqjgAm+Cc128C+3udPEItfiDockrL2Pm1Cbi5KCZpK6ANhjgM6qkeqhfDIp+hwrrUWrBzIJ51cP9LDtNZf0BLd9DXWBPNS6cVZBgW6TTBd/k1AJrSDeUvB6fu9lrnW07cp8q2uCknGaqDyCtotFcfDcfNIdsHlHUx+ceumjgwK3lR278/YzcG9LiObbBULfHo9PR8qElt01z3L3ruh85HdKuG16i79Lf38hPyfm7wx4qaKehRlD9H/zqUfiVJufdT23g3LVNYqO93mFMz5x815GtRzr2Xnbqm0vWU9pQN7lhYmBigyds0V8hdD7ya0H4/TcPjAjCL4mKycCAap8Br94CunkWQ9owB3wCcEwVaasT5IEJ8pYYUtYBtinUmYDCHrEghhCWhepF6yGLua09rqIyu3MyBQAZp6A6bKA3gMLpbA9NJREjw3mcA2Wo0WX8XmrhAKVdsZBbvJauGRhYZ6NzlKcBls2usQ9OnTTXT2fn1t2+KNSbSvh9jhrlCIU/rTj7sstm969aferb/L+P+rkJnY3JmZNWzyj/J9e15bsbsjW2xsZgk3iX+23lPeU/Lz6LT5sAe2bJDUwDARL2x0DtdDBn0Oc7IcqdKdkG/pdFdsP4u9j4wQO2MCfYy/wG2a9yawwcEkuhTVVDOSCL18NMgOwXC/UuIE7AKmdyckwsdHQiiXxwu9CSUV3h8SYC0PbnkosRixkOoNWYyUCbQMnCaXT6ALegd/oiC9WBF/x1qtdbZqR2U/3B25MLuwIW5ePxRmSfcO2kCy+c1D1v/qdH+IbR9+jRdltL17CyjL74vafr2yINW4AZngRAtQCw1DTyXVJ0In4yJ+QJJaSQFgjSywiSKckZS6EJRg52MmAptDOXuTAdDp3uH/bUfDSHOGJGk9wAVBwp2OkncmRk2GqP2GJFePft8e0JakFMc+SQ1d7gjsTxj447l/NuWmjKgCC7clNQkANiUevswLN2a8E8AanZMQF9NNLco0o2mCoEyk6rw84J4L9EOVDQ0UjWpmIKJ3MGtKi+rSzqYOIcdhBeHaLlaIR7su/eYzT2lEwTL+94QvnZi5d/LzDbErj4Xp3n0Za71g4sC08xua67YucPLlc++PiOD7+xbMCq01kMuqDzxi8Jf7rqN688fOl1Lymf3vk35eqTF+eV3+Z2fbXz4C5OXnjNHUc3LErd81zu8q98n058+gQ1XX7wzWu/usbhrp/SUm8xpKgaXhvDsINkNymakO4AO2Yn5C60kcwmLmWkD5fksKWQAkrPLclzLYWZcDa5JE9W3V/wPZYBI85NAW1iiYHFqC9nikdMGltz1zTLArycbC04pyIBnSb0QhYDTWeDF2IwEps7PCE1eeqCz3geiGSDgWhnFoCpSj4mu+BrOV3OTmDSbGckClRmWAHJDNTPomEErgVVC/ABpsJ1tuOh+gZfvXuOZ1bT3gWPlvdc8tjf9971f75zfW5ondUjcBZeozFd0CeNbH3p5IJ9lyy63FYz0ds3fdF2i96w1VavBbT61Fl+hnIJvP7z0dYd66g703+ETv3ZtuPfvGzeTY8NL9/zWqveZDPkDTanOP/61cVbF7751Nf+fu/OBfGHr27tXXr/1thCm00JD6zecy0dZX70AW6VbpXmAChGM2khTBeyOIlJDRZRNUJjKRiA4nXV4JDV4vR1WiI+oXI88Fe67K9/VR7n7qycCN9VHv9r5ZwdK7iY6G4EF8ZPMgRjnPUl2ZqQTSwOh9E28D7ADZa1GFsrEo0FZcBkHa5r8vhUxncBdzdSaypJic0aDvFwCUyNxi3CowxopcXX2Vcu/MrGb5TpJrq61qL8Sbnjlhn52yz6LVu7Znfb0xOPLZdv1Fy+cbFysvwX5ST93/QnlKcr9LXKgOf+lbJMzRfSWTRh09+/lTD6VGOKZvDjrYRimJMgWsNgKzlXuYUNVDq5XyAYjxqFd45FfdD1xhYF35vRSUd60F8RSdsCejoAnpxsSMC3UjmYkJtOYLTSmSyEkCQWjH/VoZlJiXZmgsGsd2ZFGHUUeVFEoBpEiAYg7Vc/dbtvufTiGzatWHbtl2+f290mivQJZfC02N4xe84G4dHyHdf1Ttvma3bau6h7WaihPf4AfZk20BfuWH7xlHzwLNsRJDEymdzMbAdYCW9CjpbkhoQcSMkJFp4SSrJgAaGlcneFKAhhfcAoquCCp4ADabRgpExOMddzCkhs2AcjCuTkCeKw19PGvMpGjM2QQkMUZLnRF27BtoRYCE04nwEB9z7FAjZ+EEEwcOBP+UMVTgyrxgWckEiMgkieZUWk/oyGZPqVjyzKcWWZctyifERZFPGk8hzX3J+RMv3s7SxDMoSNPOntwXhd2/Ge3mbluZP4oerT/RlQZ4AtKGALhdiJCzzzZqBeFOgXB9+cyglGHowfWjAYL3sZ9GuB9zFz0gF0aXDA6J31Tcjsckg8pNUgnnOhHRgOhFvbEP6xSFyWdiZdFOmho8gGNDKVRm1UDPOusMi7snAe1YiarIG6MpR4uB+LLSL3Y4+n3CvarbZyr+eWb387w2mUd957j3oPvv/BB72c5j3lHep9r/wpvffbvJO+1lxPX6upUdrrm5V2n1Npq6mhx50PbdqkPK48TtPP0q4HnqWp8rMPPfRQOUCXPfgs1/TsA3RZ+dlNvzmLhzJkKXmGPMZ4yF6SexLy90rynETV9fnRONcHsYUaWLoHzq4pydeoxAKm+TGGmNqAaZbm5HvEQ88sX9d7AOlyjbVYJ1yNWqJBzNtqNXZvoCPZ3TNn3qVbbv/6Y/9aHGaAuccOtjUyaTIC5jnguD5N9RZv97zvY7xTswjudSRTuc/xjIRUMoSgOM5FUfJAxwjRSCgasWY7Q1lA1wLHJFLIwjSgYz+V70RD4oqwpwSdltPg/U40G3E0wFoA1U5mR1B44RJvZ+PgUEbQvOCVDo033AS74vJyzGTjBWWP4ldgMIFMwbhXJMSU3nl8rp436bVv/Ynetnby0n0vbd8hRztnb9usPH3wceWDvjl1S5fR9iLn/6Vy8Gf3iY994Vrq2zV31r3lr93Dm+hl1PrQN6n3slDgSuU3+7+hvH7VVWuoqH/gqk3/PnmKs3/mmxcusTtSyZUrF0TSejGVXjwwOVerjTW3JOKz6jiTweGcMbfPFo9Y+2KxFf45Wm5wd+8FV3jqw+9s3taVjQQ/uOlL3+e1Swfv2HbtwIqfUIdxw+K1yl+v2jHlc1y6t5Tb3vz7y7fdvPPYQ0P2jueuu0956tpdWzyNv93/EL3q6w/+L6/W8rZy74dfOz27z5xzfE2598R+GMU26c5duegX79Xqdm7eoPz6+mue9/oHLl7xzpx59u6eSy9bvLjeNdHVN2FZ3yyNtjs7EJ5qcWhoV4z3zvF4/UIsMHdRNKs3NDRfcMW0DQmr5ao752xYF4tt33nddXe6bG/cvnf79tZgU4A6fsJteLZnnn1yz/oNpOoj6gnw/nxyJbmR3EFvIrImIa8tyVJCvjUl31SSdyeL0k3o8kl7DLHiTRKe3vQlcBRvssjXIyoHxBlNyJtSciuIyJ0JOXFCXl8avnB9Qh+TSQkDHxeW5PWWQp6l+2SXRc6W5GwCTgo7oMlXGr7ct0PNcfkshT3QdHNSvr0k35Is3r4Hf+32W+GH99yOp3skcDvvUrGsYevIsIplZ1nkmSOFQe4TednID4UdIy1qc59FnjFSWMp/Ii8fKcyaqYeG4Zl9M2yxQt8MPXxouG/WTFtMHrQMLx1cBq2Dy/TyUsvwsqXLbTFyZMbMvlmDS5ctj1f+6DktDArn14NIZjSbUKxdYnHl2utRcH07QDeK7ihahsKeGtAFE0C0pbXQSgDRoTa4SSw6XUzKo9dDszuxfoeKGuxeQGs94P/GhQSNc2mQPowqxwX0dH0gYBhKBqNqN6G3zLlMvM7EZ9M9fLYHmsEHdoDdAQ+44tMBGNSZABXGeZphTrQDHWopf90LX9j5i39Zl6zzeTpD/iU2m6ve5gq3dfvqLc3eeL39nvuURuXjb8ye55u+8ouzbV16quUESo2NJtuUOXfuSiVnt1hfDcSmheqDA7Paa4O2VM+0UHPt0986+rurU00r4l2XX5B0TbampzRNWjO9w8EfZYAKnGP6y95rLu1KDm6VprfMmNKebfb0mm2xjoTT6Yn09ixPxuZPhQvLkpvyBxd3bbikr1XDiYJZZ6ox69xtcVuDoHPGfJ7++X2WxMKOVrOhRtTxfCiebU2mvFvvOiAc2pQPtuZWbt+R3jrZ5rHmLtq6qXzqjF+uYvovg87vAr6/CP3qvgTLrq5A9V5IA3cBgzYni+ksslw6AbyetSAUAJtQWAnKPU1hzi9cMohznhULgb4cWjorThTv5ZupVwMk16CWFE1qyB/OvBygIL/YAfoT9GtcGw12MBBkovgRXZy/qaZv+syDBwuP3L9rpbuhtuWqi6/ItsQ2br5285VLp4lWytWIvpap4fSmxTNsVv8F07sstGvaK7vWu7jg1EUrVg7k7bbeX+/NtTQ28GJjvcFwUueaNEH45iM/XTl/22QfZ2pqMBo0tllLvvLo725YfvtA1qapq9NplT/ytYFAe7SlzsY1eGvraH0gZgq188Xyu3W+lfO/PffmFXPa/WY95Sw3JKe1r1owb1JbTe1LBt/6TYg37wI6bgc6+sm14JUi3mopFRtakHANDiDchoR8eUlekmApwSXVlCCVr0vI3hPyCnBRS8WAl0WU1oGUewN46iXwyRWWQpyB+GK8jmUNe0D0rwfqB7wgTr5cIb4CjKPgaGjRz9uJAlUnymYQspYGuA1Sd/kGkCpzPMDuLRGH67ykE0/1iNiZV0oxnl1xTHVOHXOPoiA6oQh4SFlw/NH4MfSKmZ3I+H9wH6PhzuoTldvBAE6pw67ewH/wzRXkW71/15dO7r7rmhn9T9Kud3bbUvRLJ2/ZtfHCuU8qP3tntzid3tmZXnrNkX1bN3dPDgSnTFoyb9PyxqDfLwKoXLm6LebzOhoSmUCgoX5SbtHg5js2bsjlsumVl37x4ik5v79n2vr57QlXo9PR5IulgyHNfbtPfqm/dvc7ys+eXLVkaDNcTTJ9+R3a9eTgwI7yX/rnz01MjccXL1m3bEpPJNrYUG/XG6xml90TD4R8vp4OmzMUXJlMtLc3uFuic2avXnvBtJYWN4CyZm8yP6HN6fQF0hNdbr+f+QcgY1rMcSbJCiK3If4uRttYGrcOpzyVkHUnZLFUFHXYKLZiLYjYwN697D0IHKATWaEIBrvTWIihg9l0wLRGEVARllQE7QgThMoOE4laM0Wwbdfqxt5iNOlk2Bu8YSqNTNy0Ok91tW6rf/lMi15PD2T6OyJO+N+fySMeVvLTdvRd1ErB97nkkY9v14jt/qbFDyxaciAc6c9M6K3zR9kbPDrU39LRwsIBJbpXl9JtJxPJJDKbLCJryEayg9xAryaYe5xaki9LyMtLxeWXwWjI8kHg55Usgr4hJc8rFdPrrsG6mK6E/IUUxmEBYTsS8paSvEP1qr6YkNtPyN2l4WR3+5gVTZbkbkuhH2RiQUleYCmshbOhkjxkYcGdSEnehtbYVhq+LjJdj8Gwwo2VoM9P/rJLtYg6i6wfKbiFT+SGkR/++eC/PYLNBXeDHsNB9SOFWrhTN0Ke1ulr6+ob3FXL95lrZve620VrIZEGDdgvDvOaLiZbC6zF1oGlqBbXisNT+5azUP6QdXjCiktYAnW6mDdYHE3eq7Zs3/kFbIhYC6FrMOKxaDlMb3dOnicejrQnQpOnq8m7w+A4kZ3X4QUvFjVNffjdDmtB2wh2c8cW6ILNynyuSnLKBrLq0qBkO5kRjIZ5p0uNMamsgUAZhDdOs3Z4HMMgTrsTYTOGkjFH4GQhKbs2YE+D18KEGy6ZEIfSnexOtegHv5qFUkpXD6zpPvL7lRqr1UFz9QMdc9avn9O3VqOcmvfb73WvG9jZFTe9oDylbFP+9QVLW2ZtS2KJp23CpIVP0OB3n6TBJ55Q3nryu8pb26bFE9N6V3pbzV13/0uXudVrHvzB0UH6L9MugVba0Z5vb8/TgY5YbkK78JWBqwdWG+hLzppazawJE9d/bf3qvm7li7WrBq8eyK5oTE689d3du39/a7KzcXkm0dTfE8q9cuLpoaHDGzbC+ycre3tX9t4f85q7uszemHlw8H3Wwl+PP9Fe/vGUec0dLZMI1qVwGIOWiAd8wzuI3JiQ21KytlTUNqKYaikwdgtj3tpS1XE8U6pTX5Lr1cismKyk7QJqhUer6kLqeZj1RlasVJNjir1Q247soG0EC9sQCrPpFp82mC31zT4/skGtVTbm1PIwtbajh/qcLocummGlHDyLcYUzriy7PYX6WfUS+Lu6xAUJzYvU+aLmG+vhlNKX7tr7Er9w/TfwQveS8h8/4xcee8WfSPjpe7f96NnbNrR3rAzE4wGlec9zP73tf3XEj+O9Xx2746c/qdbr6DCvHSJTmL/oLMkeFm1ATzHMKCGWZFEtPACvMALjbRQxOF+LI/Q4mRVTS1Uq4QKsKOOI3UWzzmTWRTuRt3QGGgnoME0hgHtfLSSjJEKHhPDesIYOhed0ZsLKG8qb4Y0hLPZgeUvpGJab0dX01qGIsk/I5wU6FBmaA8/RSDiMGAhzf8+C39vL6rDU6j5iM2htGZeBZh2UN2glehVnU+4u/5kz063lD4WH6Ta67eHyR5Sz043lPyt3062cWfka/ygNKt9XXuYP0OXKy8qRcnb7OppSSuu2Kz/hfkxnKW8pB/kXaFo5qPwG7QTWwmCtk5U4yLgCGFuiEqSi4rklL5Xxw8iwxgXLk6oDHdqHNSz70P5wwKlarPMLsnyroYR1VMCOHHx7bQLrjUjBgHVaOrU4xQVYmAdQjaZLgi8pS5KU50dOA9ODZwRoUSpX6ge12F+B1JJ6ghWOWBkDU25EZi+YWKcN1C/SM+WAGEIrY+3KEFgNHi4VuBQyeNU/Vm/D+KeZhMnFjIMcjIOQfSIs0KCyDwaogiU5OBZeAPkp+ICRhusEuwf9i4agaD1c69A0hcIsguBxwDVmV/3hasHiWYECK3gNYELTcS5gophLxlKczT+iGvDnNT/avPlHyqfKO8qnPxJXPPj6B68/uEI90G9LtPUivvCZh+CMM5x5Cg7KQ/QNZYVyYgVRa8W0qD+A7MTLZkUoYe4ea0StCbkGa4sKts9MO6koWo6c3E/J/pNlwoopEWBgWPI04fepZZRn6FhDGkkbuapaQRnDqpJirBmVVCwKSqo+AVxQ0BiSrJRQl6RyOxNRtZaSA8qqcWMMAoZKxQmY5CQTPPDJkKWgZYSXDRbsKYa/4tVSukzKwV4irQb5QGb9oIeEdOdkqrJwIJIBFkYuAoABQ/iU9Gd4FogbZcG7iFtyRyLpCFhVCYQS/j6FZ/E+x566KB2JuBUCz7jH1WpVxtxJ7quOOZOQ0ykspjl3rNnzjvWcYXVV8ELDR19CYCCn4yY5NVJo03wit4+QYlt7CtHAMBzTYzhAqwFma4pEWya0MubLmEG+Erl/Sp2UfzLnpS4Pb9eBzo6CQbb9YyKBKaK8089zkrbd7W7SbXzq8+nF+VwcRzmNEcjWpIPnaYHUnkW3asQzQVIkSyaTqWQ6OVKlZFOiEOpIpVgx3kSgoi9RbEl3p6DFD6yRmYLYrS1R6MpDS3upkJsG1+cS/YJxRG8CmeV8cK+5VBACeLRguLzQ0gbn0VKhFQssohZmFNNdcJ4qFTon4ZEVWRS0eTifWiroe/E4NmEz/ikf2qCVh1f1+Hnnn0d56Tx/5yc7Kk+qas1zirDHtzP/mw7SQd31uusBVxDaw2WxAis5lWKlINVFAmaqtbt0UQrqabDW3tVB7/jd4fCGyOFI5DDXfDg8FDkcDh/+nbLzghV0sD29UL0fPhwZCh8un8Sn8JF34H6SjKv/tsGvzWcWx4VzzDStl2laNdbtVvVrM9abYmxbI5gsCDkMiE5IwYUlmaac3CQOU1JjUFVruodLejnw8iiLbcep1YLV0xaCzFxRiZvpf0mK+PXv73z9wfCZwmmhv6I1d37/64oo0f/avOJBjlf2Ysk02FlWOsef1Xc/WVvtvZdVzVXGEDh3DMHKGA7jGLy+84zCKw4TR00Dq5ezygYcVpG67Syy/I9GxWMd/j8e2a2c9M8Gp6iMcPb4JpDhceMLM10WTBa9TIt7W8A5bGaRgmY/qOXK2FvHjb0Fo4koTnIgWYyyGEQ0DJ9qieJpCxa3RMcoFEPpAwrJQk6OikVXE0vfua0FDdZO/P8j1ljE7Z8RrRoe+x+Q7qxYlgAS1KYn2uOkjtVYxpBLahKytYTJuWjFFrIFGUAvcMs9J8YlvMBLbMcclwd4pUbk670sgzNBPGQUrM0BptGjCC90JkeTH9c/YM2Ex4cDFymiCgCLCCqiPOCCZGcW0Cr4VDrO0ulzWrQ+axUQnbqC1tA2WrOGfqpor1D+Wzmu/PeaP9Jt81741fNz6U7lroff3vhCv1DJbu1nsEkg9NS67dvXKhpFs24bYMpTyl3zBwbm0R10+yOL5pc/VB8+yVVhFWDaKi0QzzYCLVIkzzxyoIBBpUA6gXUypNDcCi6GpUnMsenOG4nO7HJ7wpF2LO+VBWtRa7XlquME51LHBkZdZuqiUcr8TRqxZbFsAdUXkiEYsFEni76y8e77t2/fvW4LDEu586PbwhdpyEWj7Sf3t3UqbSY33sCB//k2ei0jyL5/u5QeN8FtddSX3h1fNB8/9yZ+rjyw/6RJaessH7k7juP/863KbUgTehk93tm2/yRR6w05ieHUGkIMHGbTDBS8B06ieWUE3mheUkbYmzLCk7Ov2TNErbdktQ416AvQsS+R+PzoCLzxeWl0hL2NjgDIPeuaPYMyLVUwXw1orHZyC8EqCUR5rmSyaGbCbDaBWIqOBjSkrNC8YAwzm8pkOg4uQbXm3AI8aivJtupqIcwa1LNEbSEBfGsBtFHkAkEMo7vsWMMzQV37YgDGbcPFMJwhx9zFcAVcahyIeMf/U7O0RDWczGwi0OzPUAQeZJRUrB5aOGxAJIJY7DRxoxlkWVWpTLiRcn78C9oFcxpxHbN3hHrB57kXcDAxgGtFeaqpwdbfHKFv0jeP0N+UDx8+JNyoPF1+n85VDnEuOodyrvL7aL9Uv0aCqTWSVpaf0QGVQMQ11fovdLaFEq6IKegxYEYxHm3gdLggBiuWJOQNaRTr7UF1CPCFoEUUcFHU8v8xPx+1iQFXwhgoWwpE0ZHhySm4AyOEMeJ6mnKeB3IoqL8FNtcj2hH4nJ7VqeFnhSzNoozgSwJHbWQUGQ01VvsqbmCVMg/f4ZMjvKTkR+EbMCmg3ivX4XvFR4Rvhm/1MVTGw4gNTNeDx2VE+eWJqEZyKVv0gz0m6kBxSRgu1ygzl64ssSGOszU6tsahF6tHCqbGFKsf0TN30YZpX7bogZ4o6G3AkipSNldX1bDCqka2BgIoPBYIEtkyAH+aC8EpAE03dfgtHAlRsuXAFvivVtacJuC+HztG99KFtOmnm06TXyjfUSKchT2CU6OW3hyjq18Bv4ls+qnyH8r3lG3HqEDfoEt/gWMgYHt1f9Q9xWhdX/FG7Uy7m6HjDQk0b5iLiGRpD3W6qBM9aFvKVu3q/G3LuI9zDz44ifv7sm0HP/kjd0NqOK38helbSl7eK7x+8fTpF38a2/uyhi2tGz1c1a38WG2JlURInFxKEHg0lIoNGLMnDU4wryDoTSU5jnHI1lJloaAZhbpo1uBD5loMBCcScssJuU0NAbW1YJi+IaBhtqapGUQ22qaWUfhR7zpd6AlGWcESVwnJsaVLWlZKlq36ihLt7KdTnrv5/WXhOUORHQ/sP3nl3KHw1of2nwQu/3m/8pPnbv7Dcko5NiGgY8l3j69ZHh6aG9l2cr+yZmhOeDs6lthI6TY2I6SyPoytdYpiVWIEC+2wUNtaKlrZUiYr5jhgCnxqBfpY9KuJrU1DBXZGbemZI88K0s1NoLY07gjaHrtYqG3G5CFYnAYW8NKLhRq2nqbWigqM5tSot2h3+s6sWGKxr1TFvawsaQKu5ghbjgfdB80jwQGvlE8QPvB5VPK4TIlTlyepLuXzSjdecQTvlCW2ZI/VEgFH3qNFeTERJ8w3Lj1D7ewaVwRhV7EUKOSC3YJDEmpzLBdWAUV2LYavquVXVKogoOULlPXK+gUHKwsHxxDPB68tUIbovgW0pPztKN5U7doqtGuat1E9oWJx0SC3SnqbjqB7IfikEY6sKiN/wqTqsb/qukLvuJWqmoqAj4WBcF3VmQWDevIxUV+0srL0zPs4/0EkIfAfqsE9ISkbS0UjW+ZmBHsma6BBNU6+khxKFut9rGy/CW5Zkyz8x9YI8rmCrx6OQXWNoDUb9YtRTOpaXWIkxFGxGSQ3k+aiolPAikmdi5JrN/yOk/4wa8GvDx5SfvM4L9le71sI5zT0ONwRyIPUteF3ZekPfT+4UlY+jCmnvCfojPJRDp/74TqZ2mJU1/y68sOjDyrvb/idmqvhgaYCrsF0VOmEQS0hUdCMLROkkoDqG4lAqnYIJwHp21KN5ejUaJhepQmWWOE3oJY2jH1RmNkgAQwQLrvE4NooOptobQa4vJ5o/h2+0cbQ680Ew0IupjyaWG6kOYlrHUHu/EkMP9eqS+W04wv9zpQqqTIXUIFtuFqkVCtaMeVeCCBaaPI2I48WeBfc0Zsd9erSg2GDyd6gJuCBwxCwd6Z7aNJL7SYaiFRxrKFyb4Du3KL8N/2qNDL41ae+OohvrVsf3rr1Yfpo9Q6f5/b3KM1gMcn6yiODgzSHD21VpLF7Z9klXKGcJEhTdYWykfEtx9Yp47pkdSlyQUMA7uiNcCZUlAPFhXb+RnpG0aMx5NlS1zL5yxkdz401KtLZGt6g4rbKOmnVk6hGRu5ns13L1mm5U3IOy/2wii6Qkqew7FU+Ibem5GklOcJW5iRY700p6Dqu5+1UNcf4gAgMZpgTm0IhVxJtiA8DIXBmwRhUoRujHZNLwwZzTy8+MFldK6oGPAqTu2DgWAOlclcF1zEuCzr8maC1Gj38zNE6DuHZxq8qPwvtAbbBSEaEQbdx/y8ah/suomxhMb4wFoIQ8FNQRYAGRx9jj9PIWYc32GF0XDBErS8FzIXx6kaSIGhVeLY4iGeGhTdgRpQ3ob1sYhoXjUgJK/3RvGN0sbIiiyW7wPtMVXKe0r4hne7o7i9fkji6bf9Jl6tSGcjtO77PE9x9dNUVu07u7+lVF6Gjjsc8hqBG/4GHopH0VLVcz26mJhoFRwKj4y/SOXPe7z8+h3rhOOdYv5KjByg5cBoRpQ/vHu9/f84c5Z3+1/rfn83NUnL8L0+TA8xBpYggNeia6VAn69g4eVVlVMp1q7qiast5Nd5bjfKqueXXNB9q/hVUtHtsbaohoSJBXHYqa9SkELosUabelO8spR8qtqV0Ka5KXzqo2BTbIF0K9sRGX9NK7LuA6bPUD5+KQuOHS5XvoH6iS5fyI+xZ/BjLK+S12H/0LtEjghbAlGB/yiMCAOE8O2PPoZ3K43OAvQ3sgxz4V3klzxMuXwYva0TJj9WU89BJsNciKcIFTDOgUYGRATxOXl2gTkFDQzc/5zmQeVTQ6lL2qp+gkdi2DVZWG43+ri6ByAP9ARa6YQj5U+gjR9RSX2RGC15oJC05a6+H80VJv4/UL1p8HSm2Wr8o+iei4AqJoj2UxjbAeo5wBtv0iWJ9Sxe2GQAkTshhW22i2NTGIql1paKnHSOpFJUHOVEU1L0i+FJRazSxM+b9Fe31TXhlKxWdbi87YzmRYkhVGcFSMYLR0yRmSABQFtNd3UkWQC12TuqBs8K0yn4SZ4Kenw2C/k+uOSL94z9OOnsDijL5f7tmLMGxXBPLC6EOnsryQiD5jVgXUN2zomlc+bJYjeGDFkX470Gbh1Ere+6cTFoggstXqgaCw3X9akoNa43VXTVUG0HUVBuuYNpHh3gyOj5vpfZPC7IcIV8i2JlACZExgqEIA0N6QDwqpGCl2MU6G1vgb0ZdFlXXkyN2kuuSiJSM6qYFLFeMdcahBAbyCj4jrivTaDm1ulgWwGQTIxN0meKlXIdYSo1+G2gGADLYAL8jmDl7yKExe6hu/wC+Jg5VGj/4SpoOvQK4f5qwPSKYaIyRYX/VDWLxDbXOBXNaDVg/ZgSPIIUOokNdx2ms5u60NZhrKWq0SAANNcSKWg3Lm2OBE4AXK9xvKFVXdfrtBD32CMFpwxH4K0c0Mspbb50mbylvsTlib4L0nvJIu/IXWtdOL6XrKAtFoE1Sj5X1AES1Mc0wW4tJMYKrV7zgtqWq1sb7WWsDM+Q/ARPBZiHkB1tbE0G85I0AePL5Q+ih8GKxkQVd/qEpwlL/gIYdKNBbq/2MVcK9OBRpiA5RhrsBFIG29/nG2yi1YBDe1PGcsZkBXA/sYwPxgngki16Gtr1sIF6E4z6LOkRco6AuTfD6YDAuwvpfoM5/2ntM6TJ7em7PWXcRvimqZf1sr1VOw/xnJXZjAI18NbNcGuaR4HYemAUt1rLitloLkt42tsXI+OScheHaosWMD1rAg0a3i+XdipzRipEvtuYC49UCNurVRtwKRhZVAdHhJGRFA9o6DEVjtyT0cDAIFFEugpPyG5yKfShj/ze5MJ4/Vn6D8dFYHlcgRtJVHYdRtcM1n+l2JRKFPZQ56JVRI46JKmXOgOhHg0PBcPEqHZHB4Uri1LUm3JiMiaAFZxIMIjhwmTRKlzY1TguCX6BlmsRWGjZqcVeWehYNMTKoVDCCp1VwNuTOKEMxGNDiogsH6IZORISRdBYjflhfwKrB8qPq0gsebMfoKxlVGX6KGkJCLZC9J8vWIZEDulW6VeAXd+K8Rlh5VqcahckCxDkhd5TkDgurJnWzzGqhg8e0vEZfO6EddVpaHLaE6tjSEbf1sOiob2oOshhIEgTtsIf4Qy24x4ncKQ5TTT1uqCGbrYe1xjqLzaX6KVmsZIpmNZ1ZPusCzJZ18U5X2IV1TjqXLqzV2XRYzhjVRW2RqKaq9w/8Qa//wyQ6MdHtuOOl6ZbpL93p7ErRiZNYs/Jq21QnNBv001+6w9GVUl7lIgyFcX+sNnYnzvcwfony6qTKd0M7Z6yAN/6s/ZfYbKo7MLnHrNnYnkYudQcmnDkXOG2HcQcm0c6o4jYj9bQ6YnWcswsT27EoS7U22skWEJ6zG1OSth2/9QvlGbPK3NFZyvHjt52zL1PyuHJ8Fnf0izRVnrHrtuO07Zx+byIon+D9mJn3Y8QobKW+pIJHm5jmr2Wrprlk0cjKHI2o6o0WNAg65vagodYn2Rh16MKZbKCQRLFgBqll7ipu08SwLC41dWDyyFLBxdUCNNQvAsjvKGK/is0+zA5azLOi/yKQU79gJqu/arjOyDBivCZS9dnVgJWgUv6Mz872E2ABY9XJQcj4qRqPIWNxAO/ZsYPq15XGBRFQflSPX40zs32OJLZfGa5P01U+VMGo+AmbGsmFIai/qwLWcZ/lznyWRw0w9lnKdoFSd9ZSt3Eqs2+o7PNExu/zRKr7PPGUbVSir2KuaZW9Sf7/oS46DnWdKWQaZeuEkTAV+IHICm+cUmGXhpzKjIu9Vvqo4q4bSLEJ+/j/iLx045DX58CuELDkIU6jFZqZ1J0XcdmqiMtf+Xd+xFXdb0tSR3n6rJFzn4VcZdx4ipkBtbDr1HjUdbYsukgH0yF2dY+PsRmqT7C949REkA7tvFkEg5T7nD3b+JQYPHfftiLrV2xk5LMqgn+PdWYU+nlWf8xj/bGx/piYZR/fH5Or2p/a8/VnfHj+3P58+0zs5rM9EpLj4zfj+4R5zytZnxIlrLv2sB2R1OwnatumUrGJ7UHSZMNUugWjkyj+uIFAE+CGw7yxtq6NmamI+LRBMLfGO1JqbVmqOpbW847Fxcriseod/3loCivlqxX0wYD1c8fJrfzymkiju74+c0Gj+2XROmMgHF685KuHas87dP74oT6L2Bhsagy0trdNywU8dkd7ZtKkhZunTTuTsmBreNWcBagrm8jyWgA5VKEDXvPRt1mC6O1znsWkEjwrsN0GcZdB+rbiUz/B8l7VfBnm5KzECTKJ1HawiJcJdD83tilbTRJj5hgXRtWQsvltNGhLRYM2dp6iPJzDbw/SxYMgBo4TMWmkcgmC8Ue41LCYdBmVAOKlsYtKXlHViaCy3Jir7bRGQmYajQgfW7Zwt3G3bbH8XHltyyOPbFFe09yhPD9UfpC7Yoh2/0kc+vrXh0Tmz5C19KTuAW0zKHgD7h9po1nepmbvMPlrW0s7Xj927HW66WNKPqb3vE4TyrHXfykQJbeX5mhu7+iyHoH0jD6+l75IX9yrvFipSQBtVcknNpAw2U5QNtwsWNhUwhC6L1XZqC6IMUJW82hEzizogkkgYBMjoAYVGior/GiTutGFP6lmhDGn35zAckhAB00YDMWwaDAMZzyXY1un0TBLYxrO4wenRBUL+3m2V4dWrdYcq2XK9Et0rNBCzXxKSiXxiVJXfaqfZir7iJw+z7g96B2q4/aoK8e9bJRw7VYLg21qvVGjG/dt1KGf5XZVh2LyIMQ38Ll/NpjM5w+CZUP/Yfel8/S7mZB/8HsYYYt+3i9upBb6/EXKvsP/8FdnKB/RF/AptjdeRe40oNu9LP6vHxfx1luBCryWVGoxUIR5MD1J4hCjcRrEXY9YGQOmawC37ZvzzJrTiDlYXQP+Q/yg4KaGyvF9c+YqUiWeWJUbN8uhYozdlMBELylwtZWlJoazfoee5yfO/tpxuSIeaJgmiIlslV1SixqhGgVgOsFXRT5+/E2NwPYnqSAgMclWt/ApdEDjPG7pwAr0grlUz8a+mZv7+zfPRI5Tz/o29qRyiB5OEQzvY5AaX+Wxs7G9ZHCvUZE4SD/zqNT6aFoqaulYUIIf22NSrSwQ1FwOAPOCoAPDoDfWmK02dT2GbMqNA4tZrMhvpv5ohDn80J3TmObhydYtZbJlK88qCFiUCcgGfw9vhT/+YUrO8vccIDPziGrRCzXOJMv56FXBEU7IzlJRcGJnBeysU/UYakrFGrZFVg0AHSZOLmdVnCpoDNwCH/HQ8ZhMXS+AzEvb6OO0jVU8Eqw15TD8TBm/SjDdMMWV4o9+PsOwCcbpOMLipXWsx0sYDjaxPVvVdQCc2mWgo4m5CyZ1m1bAXm7MjmtUsddYWTE6KThMIq5rkJ0iXMqeSjhbZAubdGyVUzCcQssZo5nKEbswtC83sPbobmVkBFO4I2oxCoLbfUNLZ0UfumT3UUwBS8waYn2Q2ucapHANm38OQ7cFXp9Sly2o2VGsAZ7i/NP7rAaYi8v6uMxZCgbtJ7iTJ6/9hB/meL2hUgGMFM6mbMGsXxfkUzpOapE+klroCDtwhEXRykSq1gVJDPtj5Kx3XDU4VavBAZnUlHBr10oG0QYkqqFqjZ5GLBhMqB9FARFIbS43lluMUp6r4grE+5iJUfIjFVTNPACJy4+UV1EfPYMNNGx/D+Q5DUNxDsD+VlLdv7gpUUm12ERXVufCGIorymQzG3VlRcqyttID7z7wAALWBx54l66FkcIRrh94AFrQMuMlrsiAw+i7WHOjEPUTgsSeY/VWGN8fOW98P4V1VyP4bzSv5gzgUs80JuBvbGW3Vewi5FndFsfqtli7nozm4S4V8pWaLg7zHaIAjfj6WCL/F8P1u2sAAHjaY2BkYGBgZjjy6Mpmh3h+m68M8hwMIHDua+N+ZJqDgQNCMYEoAHf+C1gAeNpjYGRg4GD4fwNEMjD8/w8kgSIogBUAY/wD9XjaNU+7FcJADJNNCvq87MMOvEdNxRyq0mWH1GEWegZhACz54nvnj+yTzvGDLQ8gKr8iEQDBRDKqgmqZMMq7/y5kd/UdCLFiC+ITZiivaz6fR0er6d054SksUgzmU3qFEXdFzV2Ez8Ywlc/m5Pilsr2VWitP/bGJ4wvDWi96P3Not+n2B3lgIYIAAAAmACYAJgAuAJIA3gFaAaABrgHkAjoC1AMkA4IEUAUiBXAFzgYgBw4H7ghiCPYJsgp4Cq4LCAs2C4AMHAyiDiAPnBBAEUYRvBMwE7wUHhRaFIYUshTcFVAVgBX6FpYXXBeSF/AYYBkCGYgaBhooGkoa1BryGyQbQBtsG5Yb+Bw2HLAdLh1yHYYdsh4cHjYeYB7iHyYf3iAgIFIgdCCaILIgxiDcIPAhBiEkIegiOCK6IxAjeCPQJDQkbCS8JVIlriYWJjomWCZ2JpQmoib0J3QnvCgGKJAopii8KQApIilMKcgqJCpiKpwqyCsUK2QrvCwWLFYsnizgLPYtBC0SLSAAAAABAAAAgAC9ABAAAAAAAAIAAQACABYAAAEAAYEAAAAAeNqNkr1OAkEUhc8CmmBhRSysNtFCTfiXqFBZiIkaQzRqZ7KaBYz8CStg4/PpC1j6EJZWfjMMwSCFmczOuWfOPffOzEpa0avi8hJJSZ/MCfaUIprgmFb15XBcZW+qSWjTKzu8pLF36/Ay/IfDSa173w6/aS2WcvhdudiOjlXTmXwNFaqvgR7UVYe4wOzC+AqIX1hboMiq/qpHoEhNUN0yESjUWPd8e0RT3RaaiNFTWVnGyI6MGuw+s5qKDfgWGSa3Q42QmYXtwabxD/SE0vi0YTZUdRWP/tTb5nTGw/Rq/LrW74K4QTVznr6KeOUYRVV0pVPd6By0KC89l7lI489prufu6Xe1mi5hJtGMbaKMnN+Q/bzdy2iPb4UTB3rE02jqsOae7nirjEp27uNR0MG/+j+BD21Xh+y24Qf2tjvcQYjr7CUnPVStm09eYLPycKb/Em9Zoq755u2fk2Pd/QGe+3ARAAB42m3S1XIUURRG4VmDBHd3d5k+Z5/uBIdAcHd3CRI0OBRPyCshmRWu6Kqp/6brm9qrutVujTy/frZS63/Pjz8/Wm3ajGEs4xhPDxOYyCQmM4WpTGM6M5jJLGYzh7nMYz4LWMgiFrOEpSxjOStYySpWs4a1rGM9G9jIJjazha1sYzsdKhKZoFDT0EsfO9jJLnazh73sYz8H6OcghxjgMEc4yjGOc4KTnOI0ZzjLOc5zgYtc4jJXuMo1rnODm9ziNne4yz3u84CHPOIxTxjkKc94zguGeMkrXvOGt7xjmPd84COf+MwXvvKN7z3DQ4OpDPT/3YGq03ErN7nZDbe4tdu4vW7fyCa9pJf0kl7SS3pJL+klvTTqVXqVXqVX6VV6lV6lV+lVepVe0kt6SS/pJb3U9bL3ZO/J3pO9J3tP7oy+X7uN2/3/0Amd0Amd0Amd0Amd+Od07wi7hF3CLmGXsEvYJewSdgm7hF3CLmGXsEvYJewSdomkl/SSXtLLelkv62W9rJf1sl7Wy3pZL/RCL/RCL/RCL/RCL/RCr+gVvaJX9Ipe0St6Ra/oFb1ar9ar9Wq9Wq/Wq/VqvVqv1mv0Gr1Gr9Frul7xuyp+V8XvqnTyb1UoNRm4Af+FsAGNAEuwCFBYsQEBjlmxRgYrWCGwEFlLsBRSWCGwgFkdsAYrXFhZsBQrAAAAAVLP0T8AAA==) format('woff'),
- url('font/genericons-regular-webfont.ttf') format('truetype'),
- url('font/genericons-regular-webfont.svg#genericonsregular') format('svg');
- font-weight: normal;
- font-style: normal;
-}
-
-
-/**
- * All Genericons
- */
-
-.genericon {
- display: inline-block;
- width: 16px;
- height: 16px;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
- font-size: 16px;
- line-height: 1;
- font-family: 'Genericons';
- text-decoration: inherit;
- font-weight: normal;
- font-style: normal;
- vertical-align: top;
-}
-
-/**
- * IE7 and IE6 hacks
- */
-
-.genericon {
- *overflow: auto;
- *zoom: 1;
- *display: inline;
-}
-
-/**
- * Individual icons
- */
-
-/* Post formats */
-.genericon-standard:before { content: '\f100'; }
-.genericon-aside:before { content: '\f101'; }
-.genericon-image:before { content: '\f102'; }
-.genericon-gallery:before { content: '\f103'; }
-.genericon-video:before { content: '\f104'; }
-.genericon-status:before { content: '\f105'; }
-.genericon-quote:before { content: '\f106'; }
-.genericon-link:before { content: '\f107'; }
-.genericon-chat:before { content: '\f108'; }
-.genericon-audio:before { content: '\f109'; }
-
-/* Social icons */
-.genericon-github:before { content: '\f200'; }
-.genericon-dribbble:before { content: '\f201'; }
-.genericon-twitter:before { content: '\f202'; }
-.genericon-facebook:before { content: '\f203'; }
-.genericon-facebook-alt:before { content: '\f204'; }
-.genericon-wordpress:before { content: '\f205'; }
-.genericon-googleplus:before { content: '\f206'; }
-.genericon-linkedin:before { content: '\f207'; }
-.genericon-linkedin-alt:before { content: '\f208'; }
-.genericon-pinterest:before { content: '\f209'; }
-.genericon-pinterest-alt:before { content: '\f210'; }
-.genericon-flickr:before { content: '\f211'; }
-.genericon-vimeo:before { content: '\f212'; }
-.genericon-youtube:before { content: '\f213'; }
-.genericon-tumblr:before { content: '\f214'; }
-.genericon-instagram:before { content: '\f215'; }
-.genericon-codepen:before { content: '\f216'; }
-.genericon-polldaddy:before { content: '\f217'; }
-.genericon-googleplus-alt:before { content: '\f218'; }
-.genericon-path:before { content: '\f219'; }
-.genericon-skype:before { content: '\f220'; }
-.genericon-digg:before { content: '\f221'; }
-.genericon-reddit:before { content: '\f222'; }
-.genericon-stumbleupon:before { content: '\f223'; }
-.genericon-pocket:before { content: '\f224'; }
-.genericon-dropbox:before { content: '\f225'; }
-
-/* Meta icons */
-.genericon-comment:before { content: '\f300'; }
-.genericon-category:before { content: '\f301'; }
-.genericon-tag:before { content: '\f302'; }
-.genericon-time:before { content: '\f303'; }
-.genericon-user:before { content: '\f304'; }
-.genericon-day:before { content: '\f305'; }
-.genericon-week:before { content: '\f306'; }
-.genericon-month:before { content: '\f307'; }
-.genericon-pinned:before { content: '\f308'; }
-
-/* Other icons */
-.genericon-search:before { content: '\f400'; }
-.genericon-unzoom:before { content: '\f401'; }
-.genericon-zoom:before { content: '\f402'; }
-.genericon-show:before { content: '\f403'; }
-.genericon-hide:before { content: '\f404'; }
-.genericon-close:before { content: '\f405'; }
-.genericon-close-alt:before { content: '\f406'; }
-.genericon-trash:before { content: '\f407'; }
-.genericon-star:before { content: '\f408'; }
-.genericon-home:before { content: '\f409'; }
-.genericon-mail:before { content: '\f410'; }
-.genericon-edit:before { content: '\f411'; }
-.genericon-reply:before { content: '\f412'; }
-.genericon-feed:before { content: '\f413'; }
-.genericon-warning:before { content: '\f414'; }
-.genericon-share:before { content: '\f415'; }
-.genericon-attachment:before { content: '\f416'; }
-.genericon-location:before { content: '\f417'; }
-.genericon-checkmark:before { content: '\f418'; }
-.genericon-menu:before { content: '\f419'; }
-.genericon-refresh:before { content: '\f420'; }
-.genericon-minimize:before { content: '\f421'; }
-.genericon-maximize:before { content: '\f422'; }
-.genericon-404:before { content: '\f423'; }
-.genericon-spam:before { content: '\f424'; }
-.genericon-summary:before { content: '\f425'; }
-.genericon-cloud:before { content: '\f426'; }
-.genericon-key:before { content: '\f427'; }
-.genericon-dot:before { content: '\f428'; }
-.genericon-next:before { content: '\f429'; }
-.genericon-previous:before { content: '\f430'; }
-.genericon-expand:before { content: '\f431'; }
-.genericon-collapse:before { content: '\f432'; }
-.genericon-dropdown:before { content: '\f433'; }
-.genericon-dropdown-left:before { content: '\f434'; }
-.genericon-top:before { content: '\f435'; }
-.genericon-draggable:before { content: '\f436'; }
-.genericon-phone:before { content: '\f437'; }
-.genericon-send-to-phone:before { content: '\f438'; }
-.genericon-plugin:before { content: '\f439'; }
-.genericon-cloud-download:before { content: '\f440'; }
-.genericon-cloud-upload:before { content: '\f441'; }
-.genericon-external:before { content: '\f442'; }
-.genericon-document:before { content: '\f443'; }
-.genericon-book:before { content: '\f444'; }
-.genericon-cog:before { content: '\f445'; }
-.genericon-unapprove:before { content: '\f446'; }
-.genericon-cart:before { content: '\f447'; }
-.genericon-pause:before { content: '\f448'; }
-.genericon-stop:before { content: '\f449'; }
-.genericon-skip-back:before { content: '\f450'; }
-.genericon-skip-ahead:before { content: '\f451'; }
-.genericon-play:before { content: '\f452'; }
-.genericon-tablet:before { content: '\f453'; }
-.genericon-send-to-tablet:before { content: '\f454'; }
-.genericon-info:before { content: '\f455'; }
-.genericon-notice:before { content: '\f456'; }
-.genericon-help:before { content: '\f457'; }
-.genericon-fastforward:before { content: '\f458'; }
-.genericon-rewind:before { content: '\f459'; }
-.genericon-portfolio:before { content: '\f460'; }
-.genericon-heart:before { content: '\f461'; }
-.genericon-code:before { content: '\f462'; }
-.genericon-subscribe:before { content: '\f463'; }
-.genericon-unsubscribe:before { content: '\f464'; }
-.genericon-subscribed:before { content: '\f465'; }
-.genericon-reply-alt:before { content: '\f466'; }
-.genericon-reply-single:before { content: '\f467'; }
-.genericon-flag:before { content: '\f468'; }
-.genericon-print:before { content: '\f469'; }
-.genericon-lock:before { content: '\f470'; }
-.genericon-bold:before { content: '\f471'; }
-.genericon-italic:before { content: '\f472'; }
-.genericon-picture:before { content: '\f473'; }
-.genericon-fullscreen:before { content: '\f474'; }
-
-/* Generic shapes */
-.genericon-uparrow:before { content: '\f500'; }
-.genericon-rightarrow:before { content: '\f501'; }
-.genericon-downarrow:before { content: '\f502'; }
-.genericon-leftarrow:before { content: '\f503'; }
-
-
-
-
-
diff --git a/code/wp-content/themes/twentythirteen/header.php b/code/wp-content/themes/twentythirteen/header.php
deleted file mode 100644
index 094f74cc..00000000
--- a/code/wp-content/themes/twentythirteen/header.php
+++ /dev/null
@@ -1,51 +0,0 @@
- section and everything up till
- <# if ( data.description ) { #>
+
+ <# if ( data.description && ! data.description_hidden ) { #>
{{{ data.description }}}
diff --git a/code/wp-includes/class-wp-customize-setting.php b/code/wp-includes/class-wp-customize-setting.php
index a0d04d38..7f1f98ac 100644
--- a/code/wp-includes/class-wp-customize-setting.php
+++ b/code/wp-includes/class-wp-customize-setting.php
@@ -498,6 +498,8 @@ final public function save() {
/**
* Fetch and sanitize the $_POST value for the setting.
*
+ * During a save request prior to save, post_value() provides the new value while value() does not.
+ *
* @since 3.4.0
*
* @param mixed $default A default value which is used as a fallback. Default is null.
@@ -694,6 +696,15 @@ public function value() {
$is_core_type = ( 'option' === $this->type || 'theme_mod' === $this->type );
if ( ! $is_core_type && ! $this->is_multidimensional_aggregated ) {
+
+ // Use post value if previewed and a post value is present.
+ if ( $this->is_previewed ) {
+ $value = $this->post_value( null );
+ if ( null !== $value ) {
+ return $value;
+ }
+ }
+
$value = $this->get_root_value( $this->default );
/**
diff --git a/code/wp-includes/class-wp-customize-widgets.php b/code/wp-includes/class-wp-customize-widgets.php
index 16549ff6..74031194 100644
--- a/code/wp-includes/class-wp-customize-widgets.php
+++ b/code/wp-includes/class-wp-customize-widgets.php
@@ -93,16 +93,18 @@ final class WP_Customize_Widgets {
public function __construct( $manager ) {
$this->manager = $manager;
- // Skip useless hooks when the user can't manage widgets anyway.
+ // See https://github.com/xwp/wp-customize-snapshots/blob/962586659688a5b1fd9ae93618b7ce2d4e7a421c/php/class-customize-snapshot-manager.php#L420-L449
+ add_filter( 'customize_dynamic_setting_args', array( $this, 'filter_customize_dynamic_setting_args' ), 10, 2 );
+ add_action( 'widgets_init', array( $this, 'register_settings' ), 95 );
+ add_action( 'customize_register', array( $this, 'schedule_customize_register' ), 1 );
+
+ // Skip remaining hooks when the user can't manage widgets anyway.
if ( ! current_user_can( 'edit_theme_options' ) ) {
return;
}
- add_filter( 'customize_dynamic_setting_args', array( $this, 'filter_customize_dynamic_setting_args' ), 10, 2 );
- add_action( 'widgets_init', array( $this, 'register_settings' ), 95 );
add_action( 'wp_loaded', array( $this, 'override_sidebars_widgets_for_theme_switch' ) );
add_action( 'customize_controls_init', array( $this, 'customize_controls_init' ) );
- add_action( 'customize_register', array( $this, 'schedule_customize_register' ), 1 );
add_action( 'customize_controls_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
add_action( 'customize_controls_print_styles', array( $this, 'print_styles' ) );
add_action( 'customize_controls_print_scripts', array( $this, 'print_scripts' ) );
@@ -276,6 +278,7 @@ public function override_sidebars_widgets_for_theme_switch() {
$this->old_sidebars_widgets = wp_get_sidebars_widgets();
add_filter( 'customize_value_old_sidebars_widgets_data', array( $this, 'filter_customize_value_old_sidebars_widgets_data' ) );
+ $this->manager->set_post_value( 'old_sidebars_widgets_data', $this->old_sidebars_widgets ); // Override any value cached in changeset.
// retrieve_widgets() looks at the global $sidebars_widgets
$sidebars_widgets = $this->old_sidebars_widgets;
@@ -712,7 +715,7 @@ public function enqueue_scripts() {
<% }); %>
- {btn}
+ {btn}
'
);
@@ -729,11 +732,12 @@ public function enqueue_scripts() {
'error' => __( 'An error has occurred. Please reload the page and try again.' ),
'widgetMovedUp' => __( 'Widget moved up' ),
'widgetMovedDown' => __( 'Widget moved down' ),
- 'noAreasRendered' => __( 'There are no widget areas currently rendered in the preview. Navigate in the preview to a template that makes use of a widget area in order to access its widgets here.' ),
+ 'noAreasRendered' => __( 'There are no widget areas on the page shown, however other pages in this theme do have them.' ),
'reorderModeOn' => __( 'Reorder mode enabled' ),
'reorderModeOff' => __( 'Reorder mode closed' ),
'reorderLabelOn' => esc_attr__( 'Reorder widgets' ),
- 'reorderLabelOff' => esc_attr__( 'Close reorder mode' ),
+ 'widgetsFound' => __( 'Number of widgets found: %d' ),
+ 'noWidgetsFound' => __( 'No widgets found.' ),
),
'tpl' => array(
'widgetReorderNav' => $widget_reorder_nav_tpl,
@@ -777,7 +781,10 @@ public function output_widget_control_templates() {
-
+
+
+
+
get_available_widgets() as $available_widget ): ?>
@@ -785,6 +792,7 @@ public function output_widget_control_templates() {
+
diff --git a/code/wp-includes/class-wp-dependency.php b/code/wp-includes/class-wp-dependency.php
new file mode 100644
index 00000000..92c54561
--- /dev/null
+++ b/code/wp-includes/class-wp-dependency.php
@@ -0,0 +1,104 @@
+handle, $this->src, $this->deps, $this->ver, $this->args ) = func_get_args();
+ if ( ! is_array($this->deps) )
+ $this->deps = array();
+ }
+
+ /**
+ * Add handle data.
+ *
+ * @access public
+ * @since 2.6.0
+ *
+ * @param string $name The data key to add.
+ * @param mixed $data The data value to add.
+ * @return bool False if not scalar, true otherwise.
+ */
+ public function add_data( $name, $data ) {
+ if ( !is_scalar($name) )
+ return false;
+ $this->extra[$name] = $data;
+ return true;
+ }
+
+}
diff --git a/code/wp-includes/class-wp-editor.php b/code/wp-includes/class-wp-editor.php
index f7137f83..916be4d9 100644
--- a/code/wp-includes/class-wp-editor.php
+++ b/code/wp-includes/class-wp-editor.php
@@ -26,6 +26,7 @@ final class _WP_Editors {
private static $editor_buttons_css = true;
private static $drag_drop_upload = false;
private static $old_dfw_compat = false;
+ private static $translation;
private function __construct() {}
@@ -296,14 +297,13 @@ public static function editor( $content, $editor_id, $settings = array() ) {
/**
* @static
*
- * @global string $wp_version
* @global string $tinymce_version
*
* @param string $editor_id
* @param array $set
*/
public static function editor_settings($editor_id, $set) {
- global $wp_version, $tinymce_version;
+ global $tinymce_version;
if ( empty(self::$first_init) ) {
if ( is_admin() ) {
@@ -352,12 +352,19 @@ public static function editor_settings($editor_id, $set) {
if ( empty( self::$first_init ) ) {
self::$baseurl = includes_url( 'js/tinymce' );
- $mce_locale = get_locale();
+ $mce_locale = get_user_locale();
self::$mce_locale = $mce_locale = empty( $mce_locale ) ? 'en' : strtolower( substr( $mce_locale, 0, 2 ) ); // ISO 639-1
/** This filter is documented in wp-admin/includes/media.php */
$no_captions = (bool) apply_filters( 'disable_captions', '' );
$ext_plugins = '';
+ $shortcut_labels = array();
+
+ foreach ( self::get_translation() as $name => $value ) {
+ if ( is_array( $value ) ) {
+ $shortcut_labels[$name] = $value[1];
+ }
+ }
if ( $set['teeny'] ) {
@@ -551,7 +558,8 @@ public static function editor_settings($editor_id, $set) {
'wpeditimage_disable_captions' => $no_captions,
'wpeditimage_html5_captions' => current_theme_supports( 'html5', 'caption' ),
'plugins' => implode( ',', $plugins ),
- 'wp_lang_attr' => get_bloginfo( 'language' )
+ 'wp_lang_attr' => get_bloginfo( 'language' ),
+ 'wp_shortcut_labels' => wp_json_encode( $shortcut_labels ),
);
if ( ! empty( $mce_external_plugins ) ) {
@@ -559,7 +567,7 @@ public static function editor_settings($editor_id, $set) {
}
$suffix = SCRIPT_DEBUG ? '' : '.min';
- $version = 'ver=' . $wp_version;
+ $version = 'ver=' . get_bloginfo( 'version' );
$dashicons = includes_url( "css/dashicons$suffix.css?$version" );
// WordPress default stylesheet and dashicons
@@ -601,7 +609,7 @@ public static function editor_settings($editor_id, $set) {
$mce_buttons = apply_filters( 'teeny_mce_buttons', array('bold', 'italic', 'underline', 'blockquote', 'strikethrough', 'bullist', 'numlist', 'alignleft', 'aligncenter', 'alignright', 'undo', 'redo', 'link', 'unlink', 'fullscreen'), $editor_id );
$mce_buttons_2 = $mce_buttons_3 = $mce_buttons_4 = array();
} else {
- $mce_buttons = array( 'bold', 'italic', 'strikethrough', 'bullist', 'numlist', 'blockquote', 'hr', 'alignleft', 'aligncenter', 'alignright', 'link', 'unlink', 'wp_more', 'spellchecker' );
+ $mce_buttons = array( 'formatselect', 'bold', 'italic', 'bullist', 'numlist', 'blockquote', 'alignleft', 'aligncenter', 'alignright', 'link', 'unlink', 'wp_more', 'spellchecker' );
if ( ! wp_is_mobile() ) {
if ( $set['_content_editor_dfw'] ) {
@@ -623,7 +631,7 @@ public static function editor_settings($editor_id, $set) {
*/
$mce_buttons = apply_filters( 'mce_buttons', $mce_buttons, $editor_id );
- $mce_buttons_2 = array( 'formatselect', 'underline', 'alignjustify', 'forecolor', 'pastetext', 'removeformat', 'charmap', 'outdent', 'indent', 'undo', 'redo' );
+ $mce_buttons_2 = array( 'strikethrough', 'hr', 'forecolor', 'pastetext', 'removeformat', 'charmap', 'outdent', 'indent', 'undo', 'redo' );
if ( ! wp_is_mobile() ) {
$mce_buttons_2[] = 'wp_help';
@@ -664,6 +672,7 @@ public static function editor_settings($editor_id, $set) {
if ( $post = get_post() ) {
$body_class .= ' post-type-' . sanitize_html_class( $post->post_type ) . ' post-status-' . sanitize_html_class( $post->post_status );
+
if ( post_type_supports( $post->post_type, 'post-formats' ) ) {
$post_format = get_post_format( $post );
if ( $post_format && ! is_wp_error( $post_format ) )
@@ -671,9 +680,14 @@ public static function editor_settings($editor_id, $set) {
else
$body_class .= ' post-format-standard';
}
+
+ if ( $page_template = get_page_template_slug( $post ) ) {
+ $page_template = str_replace( '.', '-', basename( $page_template, '.php' ) );
+ $body_class .= ' page-template-' . sanitize_html_class( $page_template );
+ }
}
- $body_class .= ' locale-' . sanitize_html_class( strtolower( str_replace( '_', '-', get_locale() ) ) );
+ $body_class .= ' locale-' . sanitize_html_class( strtolower( str_replace( '_', '-', get_user_locale() ) ) );
if ( !empty($set['tinymce']['body_class']) ) {
$body_class .= ' ' . $set['tinymce']['body_class'];
@@ -807,73 +821,64 @@ public static function enqueue_scripts() {
) );
}
- /**
- * Translates the default TinyMCE strings and returns them as JSON encoded object ready to be loaded with tinymce.addI18n().
- * Can be used directly (_WP_Editors::wp_mce_translation()) by passing the same locale as set in the TinyMCE init object.
- *
- * @static
- * @param string $mce_locale The locale used for the editor.
- * @param bool $json_only optional Whether to include the JavaScript calls to tinymce.addI18n() and tinymce.ScriptLoader.markDone().
- * @return string Translation object, JSON encoded.
- */
- public static function wp_mce_translation( $mce_locale = '', $json_only = false ) {
-
- $mce_translation = array(
+ private static function get_translation() {
+ if ( empty( self::$translation ) ) {
+ self::$translation = array(
// Default TinyMCE strings
'New document' => __( 'New document' ),
'Formats' => _x( 'Formats', 'TinyMCE' ),
'Headings' => _x( 'Headings', 'TinyMCE' ),
- 'Heading 1' => __( 'Heading 1' ),
- 'Heading 2' => __( 'Heading 2' ),
- 'Heading 3' => __( 'Heading 3' ),
- 'Heading 4' => __( 'Heading 4' ),
- 'Heading 5' => __( 'Heading 5' ),
- 'Heading 6' => __( 'Heading 6' ),
+ 'Heading 1' => array( __( 'Heading 1' ), 'access1' ),
+ 'Heading 2' => array( __( 'Heading 2' ), 'access2' ),
+ 'Heading 3' => array( __( 'Heading 3' ), 'access3' ),
+ 'Heading 4' => array( __( 'Heading 4' ), 'access4' ),
+ 'Heading 5' => array( __( 'Heading 5' ), 'access5' ),
+ 'Heading 6' => array( __( 'Heading 6' ), 'access6' ),
/* translators: block tags */
'Blocks' => _x( 'Blocks', 'TinyMCE' ),
- 'Paragraph' => __( 'Paragraph' ),
- 'Blockquote' => __( 'Blockquote' ),
+ 'Paragraph' => array( __( 'Paragraph' ), 'access7' ),
+ 'Blockquote' => array( __( 'Blockquote' ), 'accessQ' ),
'Div' => _x( 'Div', 'HTML tag' ),
'Pre' => _x( 'Pre', 'HTML tag' ),
'Preformatted' => _x( 'Preformatted', 'HTML tag' ),
'Address' => _x( 'Address', 'HTML tag' ),
'Inline' => _x( 'Inline', 'HTML elements' ),
- 'Underline' => __( 'Underline' ),
- 'Strikethrough' => __( 'Strikethrough' ),
+ 'Underline' => array( __( 'Underline' ), 'metaU' ),
+ 'Strikethrough' => array( __( 'Strikethrough' ), 'accessD' ),
'Subscript' => __( 'Subscript' ),
'Superscript' => __( 'Superscript' ),
'Clear formatting' => __( 'Clear formatting' ),
- 'Bold' => __( 'Bold' ),
- 'Italic' => __( 'Italic' ),
- 'Code' => __( 'Code' ),
+ 'Bold' => array( __( 'Bold' ), 'metaB' ),
+ 'Italic' => array( __( 'Italic' ), 'metaI' ),
+ 'Code' => array( __( 'Code' ), 'accessX' ),
'Source code' => __( 'Source code' ),
'Font Family' => __( 'Font Family' ),
'Font Sizes' => __( 'Font Sizes' ),
- 'Align center' => __( 'Align center' ),
- 'Align right' => __( 'Align right' ),
- 'Align left' => __( 'Align left' ),
- 'Justify' => __( 'Justify' ),
+ 'Align center' => array( __( 'Align center' ), 'accessC' ),
+ 'Align right' => array( __( 'Align right' ), 'accessR' ),
+ 'Align left' => array( __( 'Align left' ), 'accessL' ),
+ 'Justify' => array( __( 'Justify' ), 'accessJ' ),
'Increase indent' => __( 'Increase indent' ),
'Decrease indent' => __( 'Decrease indent' ),
- 'Cut' => __( 'Cut' ),
- 'Copy' => __( 'Copy' ),
- 'Paste' => __( 'Paste' ),
- 'Select all' => __( 'Select all' ),
- 'Undo' => __( 'Undo' ),
- 'Redo' => __( 'Redo' ),
+ 'Cut' => array( __( 'Cut' ), 'metaX' ),
+ 'Copy' => array( __( 'Copy' ), 'metaC' ),
+ 'Paste' => array( __( 'Paste' ), 'metaV' ),
+ 'Select all' => array( __( 'Select all' ), 'metaA' ),
+ 'Undo' => array( __( 'Undo' ), 'metaZ' ),
+ 'Redo' => array( __( 'Redo' ), 'metaY' ),
'Ok' => __( 'OK' ),
'Cancel' => __( 'Cancel' ),
'Close' => __( 'Close' ),
'Visual aids' => __( 'Visual aids' ),
- 'Bullet list' => __( 'Bulleted list' ),
- 'Numbered list' => __( 'Numbered list' ),
+ 'Bullet list' => array( __( 'Bulleted list' ), 'accessU' ),
+ 'Numbered list' => array( __( 'Numbered list' ), 'accessO' ),
'Square' => _x( 'Square', 'list style' ),
'Default' => _x( 'Default', 'list style' ),
'Circle' => _x( 'Circle', 'list style' ),
@@ -899,7 +904,7 @@ public static function wp_mce_translation( $mce_locale = '', $json_only = false
'Author' => __( 'Author' ),
// Media, image plugins
- 'Insert/edit image' => __( 'Insert/edit image' ),
+ 'Insert/edit image' => array( __( 'Insert/edit image' ), 'accessM' ),
'General' => __( 'General' ),
'Advanced' => __( 'Advanced' ),
'Source' => __( 'Source' ),
@@ -933,8 +938,8 @@ public static function wp_mce_translation( $mce_locale = '', $json_only = false
'Horizontal line' => __( 'Horizontal line' ),
'Horizontal space' => __( 'Horizontal space' ),
'Restore last draft' => __( 'Restore last draft' ),
- 'Insert/edit link' => __( 'Insert/edit link' ),
- 'Remove link' => __( 'Remove link' ),
+ 'Insert/edit link' => array( __( 'Insert/edit link' ), 'metaK' ),
+ 'Remove link' => array( __( 'Remove link' ), 'accessS' ),
'Color' => __( 'Color' ),
'Custom color' => __( 'Custom color' ),
@@ -1038,11 +1043,11 @@ public static function wp_mce_translation( $mce_locale = '', $json_only = false
'Format' => _x( 'Format', 'TinyMCE menu' ),
// WordPress strings
- 'Toolbar Toggle' => __( 'Toolbar Toggle' ),
- 'Insert Read More tag' => __( 'Insert Read More tag' ),
- 'Insert Page Break tag' => __( 'Insert Page Break tag' ),
+ 'Toolbar Toggle' => array( __( 'Toolbar Toggle' ), 'accessZ' ),
+ 'Insert Read More tag' => array( __( 'Insert Read More tag' ), 'accessT' ),
+ 'Insert Page Break tag' => array( __( 'Insert Page Break tag' ), 'accessP' ),
'Read more...' => __( 'Read more...' ), // Title on the placeholder inside the editor (no ellipsis)
- 'Distraction-free writing mode' => __( 'Distraction-free writing mode' ),
+ 'Distraction-free writing mode' => array( __( 'Distraction-free writing mode' ), 'accessW' ),
'No alignment' => __( 'No alignment' ), // Tooltip for the 'alignnone' button in the image toolbar
'Remove' => __( 'Remove' ), // Tooltip for the 'remove' button in the image toolbar
'Edit ' => __( 'Edit' ), // Tooltip for the 'edit' button in the image toolbar
@@ -1051,7 +1056,7 @@ public static function wp_mce_translation( $mce_locale = '', $json_only = false
'Link options' => __( 'Link options' ), // Tooltip for the 'link options' button in the inline link dialog
// Shortcuts help modal
- 'Keyboard Shortcuts' => __( 'Keyboard Shortcuts' ),
+ 'Keyboard Shortcuts' => array( __( 'Keyboard Shortcuts' ), 'accessH' ),
'Default shortcuts,' => __( 'Default shortcuts,' ),
'Additional shortcuts,' => __( 'Additional shortcuts,' ),
'Focus shortcuts:' => __( 'Focus shortcuts:' ),
@@ -1074,7 +1079,8 @@ public static function wp_mce_translation( $mce_locale = '', $json_only = false
__( 'The following formatting shortcuts are replaced when pressing Enter. Press Escape or the Undo button to undo.' ),
'The next group of formatting shortcuts are applied as you type or when you insert them around plain text in the same paragraph. Press Escape or the Undo button to undo.' =>
__( 'The next group of formatting shortcuts are applied as you type or when you insert them around plain text in the same paragraph. Press Escape or the Undo button to undo.' ),
- );
+ );
+ }
/**
* Link plugin (not included):
@@ -1087,10 +1093,31 @@ public static function wp_mce_translation( $mce_locale = '', $json_only = false
* Url
*/
+ return self::$translation;
+ }
+
+ /**
+ * Translates the default TinyMCE strings and returns them as JSON encoded object ready to be loaded with tinymce.addI18n().
+ * Can be used directly (_WP_Editors::wp_mce_translation()) by passing the same locale as set in the TinyMCE init object.
+ *
+ * @static
+ * @param string $mce_locale The locale used for the editor.
+ * @param bool $json_only optional Whether to include the JavaScript calls to tinymce.addI18n() and tinymce.ScriptLoader.markDone().
+ * @return string Translation object, JSON encoded.
+ */
+ public static function wp_mce_translation( $mce_locale = '', $json_only = false ) {
if ( ! $mce_locale ) {
$mce_locale = self::$mce_locale;
}
+ $mce_translation = self::get_translation();
+
+ foreach ( $mce_translation as $name => $value ) {
+ if ( is_array( $value ) ) {
+ $mce_translation[$name] = $value[0];
+ }
+ }
+
/**
* Filters translated strings prepared for TinyMCE.
*
@@ -1131,13 +1158,12 @@ public static function wp_mce_translation( $mce_locale = '', $json_only = false
/**
*
* @static
- * @global string $wp_version
* @global string $tinymce_version
* @global bool $concatenate_scripts
* @global bool $compress_scripts
*/
public static function editor_js() {
- global $wp_version, $tinymce_version, $concatenate_scripts, $compress_scripts;
+ global $tinymce_version, $concatenate_scripts, $compress_scripts;
/**
* Filters "tiny_mce_version" is deprecated
@@ -1215,7 +1241,7 @@ public static function editor_js() {
$baseurl = self::$baseurl;
// Load tinymce.js when running from /src, else load wp-tinymce.js.gz (production) or tinymce.min.js (SCRIPT_DEBUG)
- $mce_suffix = false !== strpos( $wp_version, '-src' ) ? '' : '.min';
+ $mce_suffix = false !== strpos( get_bloginfo( 'version' ), '-src' ) ? '' : '.min';
if ( $tmce_on ) {
if ( $compressed ) {
@@ -1259,14 +1285,6 @@ public static function editor_js() {
var init, id, $wrap;
if ( typeof tinymce !== 'undefined' ) {
- // Fix RTL
- tinymce.on( 'addeditor', function( event ) {
- event.editor.rtl = event.editor.settings.rtl_ui ||
- ( event.editor.editorManager &&
- event.editor.editorManager.i18n &&
- event.editor.editorManager.i18n.rtl );
- }, true );
-
for ( id in tinyMCEPreInit.mceInit ) {
init = tinyMCEPreInit.mceInit[id];
$wrap = tinymce.$( '#wp-' + id + '-wrap' );
diff --git a/code/wp-includes/class-wp-embed.php b/code/wp-includes/class-wp-embed.php
index 17a976f2..a8ce4d6c 100644
--- a/code/wp-includes/class-wp-embed.php
+++ b/code/wp-includes/class-wp-embed.php
@@ -384,4 +384,3 @@ public function maybe_make_link( $url ) {
return apply_filters( 'embed_maybe_make_link', $output, $url );
}
}
-$GLOBALS['wp_embed'] = new WP_Embed();
diff --git a/code/wp-includes/class-wp-error.php b/code/wp-includes/class-wp-error.php
index 1010adb0..22273f89 100644
--- a/code/wp-includes/class-wp-error.php
+++ b/code/wp-includes/class-wp-error.php
@@ -202,17 +202,3 @@ public function remove( $code ) {
unset( $this->error_data[ $code ] );
}
}
-
-/**
- * Check whether variable is a WordPress Error.
- *
- * Returns true if $thing is an object of the WP_Error class.
- *
- * @since 2.1.0
- *
- * @param mixed $thing Check if unknown variable is a WP_Error object.
- * @return bool True, if WP_Error. False, if not WP_Error.
- */
-function is_wp_error( $thing ) {
- return ( $thing instanceof WP_Error );
-}
diff --git a/code/wp-includes/class-wp-feed-cache-transient.php b/code/wp-includes/class-wp-feed-cache-transient.php
new file mode 100644
index 00000000..1b5be477
--- /dev/null
+++ b/code/wp-includes/class-wp-feed-cache-transient.php
@@ -0,0 +1,141 @@
+name = 'feed_' . $filename;
+ $this->mod_name = 'feed_mod_' . $filename;
+
+ $lifetime = $this->lifetime;
+ /**
+ * Filters the transient lifetime of the feed cache.
+ *
+ * @since 2.8.0
+ *
+ * @param int $lifetime Cache duration in seconds. Default is 43200 seconds (12 hours).
+ * @param string $filename Unique identifier for the cache object.
+ */
+ $this->lifetime = apply_filters( 'wp_feed_cache_transient_lifetime', $lifetime, $filename);
+ }
+
+ /**
+ * Sets the transient.
+ *
+ * @since 2.8.0
+ * @access public
+ *
+ * @param SimplePie $data Data to save.
+ * @return true Always true.
+ */
+ public function save($data) {
+ if ( $data instanceof SimplePie ) {
+ $data = $data->data;
+ }
+
+ set_transient($this->name, $data, $this->lifetime);
+ set_transient($this->mod_name, time(), $this->lifetime);
+ return true;
+ }
+
+ /**
+ * Gets the transient.
+ *
+ * @since 2.8.0
+ * @access public
+ *
+ * @return mixed Transient value.
+ */
+ public function load() {
+ return get_transient($this->name);
+ }
+
+ /**
+ * Gets mod transient.
+ *
+ * @since 2.8.0
+ * @access public
+ *
+ * @return mixed Transient value.
+ */
+ public function mtime() {
+ return get_transient($this->mod_name);
+ }
+
+ /**
+ * Sets mod transient.
+ *
+ * @since 2.8.0
+ * @access public
+ *
+ * @return bool False if value was not set and true if value was set.
+ */
+ public function touch() {
+ return set_transient($this->mod_name, time(), $this->lifetime);
+ }
+
+ /**
+ * Deletes transients.
+ *
+ * @since 2.8.0
+ * @access public
+ *
+ * @return true Always true.
+ */
+ public function unlink() {
+ delete_transient($this->name);
+ delete_transient($this->mod_name);
+ return true;
+ }
+}
diff --git a/code/wp-includes/class-wp-feed-cache.php b/code/wp-includes/class-wp-feed-cache.php
new file mode 100644
index 00000000..337d3f3e
--- /dev/null
+++ b/code/wp-includes/class-wp-feed-cache.php
@@ -0,0 +1,33 @@
+callbacks[ $priority ] );
+
+ $this->callbacks[ $priority ][ $idx ] = array(
+ 'function' => $function_to_add,
+ 'accepted_args' => $accepted_args
+ );
+
+ // if we're adding a new priority to the list, put them back in sorted order
+ if ( ! $priority_existed && count( $this->callbacks ) > 1 ) {
+ ksort( $this->callbacks, SORT_NUMERIC );
+ }
+
+ if ( $this->nesting_level > 0 ) {
+ $this->resort_active_iterations( $priority, $priority_existed );
+ }
+ }
+
+ /**
+ * Handles reseting callback priority keys mid-iteration.
+ *
+ * @since 4.7.0
+ * @access private
+ *
+ * @param bool|int $new_priority Optional. The priority of the new filter being added. Default false,
+ * for no priority being added.
+ * @param bool $priority_existed Optional. Flag for whether the priority already existed before the new
+ * filter was added. Default false.
+ */
+ private function resort_active_iterations( $new_priority = false, $priority_existed = false ) {
+ $new_priorities = array_keys( $this->callbacks );
+
+ // If there are no remaining hooks, clear out all running iterations.
+ if ( ! $new_priorities ) {
+ foreach ( $this->iterations as $index => $iteration ) {
+ $this->iterations[ $index ] = $new_priorities;
+ }
+ return;
+ }
+
+ $min = min( $new_priorities );
+ foreach ( $this->iterations as $index => &$iteration ) {
+ $current = current( $iteration );
+ // If we're already at the end of this iteration, just leave the array pointer where it is.
+ if ( false === $current ) {
+ continue;
+ }
+
+ $iteration = $new_priorities;
+
+ if ( $current < $min ) {
+ array_unshift( $iteration, $current );
+ continue;
+ }
+
+ while ( current( $iteration ) < $current ) {
+ if ( false === next( $iteration ) ) {
+ break;
+ }
+ }
+
+ // If we have a new priority that didn't exist, but ::apply_filters() or ::do_action() thinks it's the current priority...
+ if ( $new_priority === $this->current_priority[ $index ] && ! $priority_existed ) {
+ /*
+ * ... and the new priority is the same as what $this->iterations thinks is the previous
+ * priority, we need to move back to it.
+ */
+
+ if ( false === current( $iteration ) ) {
+ // If we've already moved off the end of the array, go back to the last element.
+ $prev = end( $iteration );
+ } else {
+ // Otherwise, just go back to the previous element.
+ $prev = prev( $iteration );
+ }
+ if ( false === $prev ) {
+ // Start of the array. Reset, and go about our day.
+ reset( $iteration );
+ } elseif ( $new_priority !== $prev ) {
+ // Previous wasn't the same. Move forward again.
+ next( $iteration );
+ }
+ }
+ }
+ unset( $iteration );
+ }
+
+ /**
+ * Unhooks a function or method from a specific filter action.
+ *
+ * @since 4.7.0
+ * @access public
+ *
+ * @param string $tag The filter hook to which the function to be removed is hooked. Used
+ * for building the callback ID when SPL is not available.
+ * @param callable $function_to_remove The callback to be removed from running when the filter is applied.
+ * @param int $priority The exact priority used when adding the original filter callback.
+ * @return bool Whether the callback existed before it was removed.
+ */
+ public function remove_filter( $tag, $function_to_remove, $priority ) {
+ $function_key = _wp_filter_build_unique_id( $tag, $function_to_remove, $priority );
+
+ $exists = isset( $this->callbacks[ $priority ][ $function_key ] );
+ if ( $exists ) {
+ unset( $this->callbacks[ $priority ][ $function_key ] );
+ if ( ! $this->callbacks[ $priority ] ) {
+ unset( $this->callbacks[ $priority ] );
+ if ( $this->nesting_level > 0 ) {
+ $this->resort_active_iterations();
+ }
+ }
+ }
+ return $exists;
+ }
+
+ /**
+ * Checks if a specific action has been registered for this hook.
+ *
+ * @since 4.7.0
+ * @access public
+ *
+ * @param callable|bool $function_to_check Optional. The callback to check for. Default false.
+ * @param string $tag Optional. The name of the filter hook. Used for building
+ * the callback ID when SPL is not available. Default empty.
+ * @return bool|int The priority of that hook is returned, or false if the function is not attached.
+ */
+ public function has_filter( $tag = '', $function_to_check = false ) {
+ if ( false === $function_to_check ) {
+ return $this->has_filters();
+ }
+
+ $function_key = _wp_filter_build_unique_id( $tag, $function_to_check, false );
+ if ( ! $function_key ) {
+ return false;
+ }
+
+ foreach ( $this->callbacks as $priority => $callbacks ) {
+ if ( isset( $callbacks[ $function_key ] ) ) {
+ return $priority;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Checks if any callbacks have been registered for this hook.
+ *
+ * @since 4.7.0
+ * @access public
+ *
+ * @return bool True if callbacks have been registered for the current hook, otherwise false.
+ */
+ public function has_filters() {
+ foreach ( $this->callbacks as $callbacks ) {
+ if ( $callbacks ) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Removes all callbacks from the current filter.
+ *
+ * @since 4.7.0
+ * @access public
+ *
+ * @param int|bool $priority Optional. The priority number to remove. Default false.
+ */
+ public function remove_all_filters( $priority = false ) {
+ if ( ! $this->callbacks ) {
+ return;
+ }
+
+ if ( false === $priority ) {
+ $this->callbacks = array();
+ } else if ( isset( $this->callbacks[ $priority ] ) ) {
+ unset( $this->callbacks[ $priority ] );
+ }
+
+ if ( $this->nesting_level > 0 ) {
+ $this->resort_active_iterations();
+ }
+ }
+
+ /**
+ * Calls the callback functions added to a filter hook.
+ *
+ * @since 4.7.0
+ * @access public
+ *
+ * @param mixed $value The value to filter.
+ * @param array $args Arguments to pass to callbacks.
+ * @return mixed The filtered value after all hooked functions are applied to it.
+ */
+ public function apply_filters( $value, $args ) {
+ if ( ! $this->callbacks ) {
+ return $value;
+ }
+
+ $nesting_level = $this->nesting_level++;
+
+ $this->iterations[ $nesting_level ] = array_keys( $this->callbacks );
+ $num_args = count( $args );
+
+ do {
+ $this->current_priority[ $nesting_level ] = $priority = current( $this->iterations[ $nesting_level ] );
+
+ foreach ( $this->callbacks[ $priority ] as $the_ ) {
+ if( ! $this->doing_action ) {
+ $args[ 0 ] = $value;
+ }
+
+ // Avoid the array_slice if possible.
+ if ( $the_['accepted_args'] == 0 ) {
+ $value = call_user_func_array( $the_['function'], array() );
+ } elseif ( $the_['accepted_args'] >= $num_args ) {
+ $value = call_user_func_array( $the_['function'], $args );
+ } else {
+ $value = call_user_func_array( $the_['function'], array_slice( $args, 0, (int)$the_['accepted_args'] ) );
+ }
+ }
+ } while ( false !== next( $this->iterations[ $nesting_level ] ) );
+
+ unset( $this->iterations[ $nesting_level ] );
+ unset( $this->current_priority[ $nesting_level ] );
+
+ $this->nesting_level--;
+
+ return $value;
+ }
+
+ /**
+ * Executes the callback functions hooked on a specific action hook.
+ *
+ * @since 4.7.0
+ * @access public
+ *
+ * @param mixed $args Arguments to pass to the hook callbacks.
+ */
+ public function do_action( $args ) {
+ $this->doing_action = true;
+ $this->apply_filters( '', $args );
+
+ // If there are recursive calls to the current action, we haven't finished it until we get to the last one.
+ if ( ! $this->nesting_level ) {
+ $this->doing_action = false;
+ }
+ }
+
+ /**
+ * Processes the functions hooked into the 'all' hook.
+ *
+ * @since 4.7.0
+ * @access public
+ *
+ * @param array $args Arguments to pass to the hook callbacks. Passed by reference.
+ */
+ public function do_all_hook( &$args ) {
+ $nesting_level = $this->nesting_level++;
+ $this->iterations[ $nesting_level ] = array_keys( $this->callbacks );
+
+ do {
+ $priority = current( $this->iterations[ $nesting_level ] );
+ foreach ( $this->callbacks[ $priority ] as $the_ ) {
+ call_user_func_array( $the_['function'], $args );
+ }
+ } while ( false !== next( $this->iterations[ $nesting_level ] ) );
+
+ unset( $this->iterations[ $nesting_level ] );
+ $this->nesting_level--;
+ }
+
+ /**
+ * Return the current priority level of the currently running iteration of the hook.
+ *
+ * @since 4.7.0
+ * @access public
+ *
+ * @return int|false If the hook is running, return the current priority level. If it isn't running, return false.
+ */
+ public function current_priority() {
+ if ( false === current( $this->iterations ) ) {
+ return false;
+ }
+
+ return current( current( $this->iterations ) );
+ }
+
+ /**
+ * Normalizes filters set up before WordPress has initialized to WP_Hook objects.
+ *
+ * @since 4.7.0
+ * @access public
+ * @static
+ *
+ * @param array $filters Filters to normalize.
+ * @return WP_Hook[] Array of normalized filters.
+ */
+ public static function build_preinitialized_hooks( $filters ) {
+ /** @var WP_Hook[] $normalized */
+ $normalized = array();
+
+ foreach ( $filters as $tag => $callback_groups ) {
+ if ( is_object( $callback_groups ) && $callback_groups instanceof WP_Hook ) {
+ $normalized[ $tag ] = $callback_groups;
+ continue;
+ }
+ $hook = new WP_Hook();
+
+ // Loop through callback groups.
+ foreach ( $callback_groups as $priority => $callbacks ) {
+
+ // Loop through callbacks.
+ foreach ( $callbacks as $cb ) {
+ $hook->add_filter( $tag, $cb['function'], $priority, $cb['accepted_args'] );
+ }
+ }
+ $normalized[ $tag ] = $hook;
+ }
+ return $normalized;
+ }
+
+ /**
+ * Determines whether an offset value exists.
+ *
+ * @since 4.7.0
+ * @access public
+ *
+ * @link http://php.net/manual/en/arrayaccess.offsetexists.php
+ *
+ * @param mixed $offset An offset to check for.
+ * @return bool True if the offset exists, false otherwise.
+ */
+ public function offsetExists( $offset ) {
+ return isset( $this->callbacks[ $offset ] );
+ }
+
+ /**
+ * Retrieves a value at a specified offset.
+ *
+ * @since 4.7.0
+ * @access public
+ *
+ * @link http://php.net/manual/en/arrayaccess.offsetget.php
+ *
+ * @param mixed $offset The offset to retrieve.
+ * @return mixed If set, the value at the specified offset, null otherwise.
+ */
+ public function offsetGet( $offset ) {
+ return isset( $this->callbacks[ $offset ] ) ? $this->callbacks[ $offset ] : null;
+ }
+
+ /**
+ * Sets a value at a specified offset.
+ *
+ * @since 4.7.0
+ * @access public
+ *
+ * @link http://php.net/manual/en/arrayaccess.offsetset.php
+ *
+ * @param mixed $offset The offset to assign the value to.
+ * @param mixed $value The value to set.
+ */
+ public function offsetSet( $offset, $value ) {
+ if ( is_null( $offset ) ) {
+ $this->callbacks[] = $value;
+ } else {
+ $this->callbacks[ $offset ] = $value;
+ }
+ }
+
+ /**
+ * Unsets a specified offset.
+ *
+ * @since 4.7.0
+ * @access public
+ *
+ * @link http://php.net/manual/en/arrayaccess.offsetunset.php
+ *
+ * @param mixed $offset The offset to unset.
+ */
+ public function offsetUnset( $offset ) {
+ unset( $this->callbacks[ $offset ] );
+ }
+
+ /**
+ * Returns the current element.
+ *
+ * @since 4.7.0
+ * @access public
+ *
+ * @link http://php.net/manual/en/iterator.current.php
+ *
+ * @return array Of callbacks at current priority.
+ */
+ public function current() {
+ return current( $this->callbacks );
+ }
+
+ /**
+ * Moves forward to the next element.
+ *
+ * @since 4.7.0
+ * @access public
+ *
+ * @link http://php.net/manual/en/iterator.next.php
+ *
+ * @return array Of callbacks at next priority.
+ */
+ public function next() {
+ return next( $this->callbacks );
+ }
+
+ /**
+ * Returns the key of the current element.
+ *
+ * @since 4.7.0
+ * @access public
+ *
+ * @link http://php.net/manual/en/iterator.key.php
+ *
+ * @return mixed Returns current priority on success, or NULL on failure
+ */
+ public function key() {
+ return key( $this->callbacks );
+ }
+
+ /**
+ * Checks if current position is valid.
+ *
+ * @since 4.7.0
+ * @access public
+ *
+ * @link http://php.net/manual/en/iterator.valid.php
+ *
+ * @return boolean
+ */
+ public function valid() {
+ return key( $this->callbacks ) !== null;
+ }
+
+ /**
+ * Rewinds the Iterator to the first element.
+ *
+ * @since 4.7.0
+ * @access public
+ *
+ * @link http://php.net/manual/en/iterator.rewind.php
+ */
+ public function rewind() {
+ reset( $this->callbacks );
+ }
+
+}
diff --git a/code/wp-includes/class-wp-http-requests-hooks.php b/code/wp-includes/class-wp-http-requests-hooks.php
new file mode 100644
index 00000000..108fae8c
--- /dev/null
+++ b/code/wp-includes/class-wp-http-requests-hooks.php
@@ -0,0 +1,76 @@
+url = $url;
+ $this->request = $request;
+ }
+
+ /**
+ * Dispatch a Requests hook to a native WordPress action.
+ *
+ * @param string $hook Hook name.
+ * @param array $parameters Parameters to pass to callbacks.
+ * @return boolean True if hooks were run, false if nothing was hooked.
+ */
+ public function dispatch( $hook, $parameters = array() ) {
+ $result = parent::dispatch( $hook, $parameters );
+
+ // Handle back-compat actions
+ switch ( $hook ) {
+ case 'curl.before_send':
+ /** This action is documented in wp-includes/class-wp-http-curl.php */
+ do_action_ref_array( 'http_api_curl', array( $parameters[0], $this->request, $this->url ) );
+ break;
+ }
+
+ /**
+ * Transforms a native Request hook to a WordPress actions.
+ *
+ * This action maps Requests internal hook to a native WordPress action.
+ *
+ * @see https://github.com/rmccue/Requests/blob/master/docs/hooks.md
+ *
+ * @param array $parameters Parameters from Requests internal hook.
+ * @param array $request Request data in WP_Http format.
+ * @param string $url URL to request.
+ */
+ do_action_ref_array( "requests-{$hook}", $parameters, $this->request, $this->url );
+
+ return $result;
+ }
+}
diff --git a/code/wp-includes/class-wp-http-requests-response.php b/code/wp-includes/class-wp-http-requests-response.php
index ab0a5cc0..66083191 100644
--- a/code/wp-includes/class-wp-http-requests-response.php
+++ b/code/wp-includes/class-wp-http-requests-response.php
@@ -65,17 +65,18 @@ public function get_response_object() {
* @since 4.6.0
* @access public
*
- * @return array Map of header name to header value.
+ * @see \Requests_Utility_CaseInsensitiveDictionary
+ *
+ * @return \Requests_Utility_CaseInsensitiveDictionary Map of header name to header value.
*/
public function get_headers() {
- // Ensure headers remain case-insensitive
+ // Ensure headers remain case-insensitive.
$converted = new Requests_Utility_CaseInsensitiveDictionary();
foreach ( $this->response->headers->getAll() as $key => $value ) {
if ( count( $value ) === 1 ) {
$converted[ $key ] = $value[0];
- }
- else {
+ } else {
$converted[ $key ] = $value;
}
}
diff --git a/code/wp-includes/class-wp-http-response.php b/code/wp-includes/class-wp-http-response.php
index e46b01e0..da83de1d 100644
--- a/code/wp-includes/class-wp-http-response.php
+++ b/code/wp-includes/class-wp-http-response.php
@@ -28,7 +28,7 @@ class WP_HTTP_Response {
*
* @since 4.4.0
* @access public
- * @var int
+ * @var array
*/
public $headers;
@@ -37,7 +37,7 @@ class WP_HTTP_Response {
*
* @since 4.4.0
* @access public
- * @var array
+ * @var int
*/
public $status;
diff --git a/code/wp-includes/class-wp-image-editor-imagick.php b/code/wp-includes/class-wp-image-editor-imagick.php
index 82b872d7..fc6fc933 100644
--- a/code/wp-includes/class-wp-image-editor-imagick.php
+++ b/code/wp-includes/class-wp-image-editor-imagick.php
@@ -73,6 +73,7 @@ public static function test( $args = array() ) {
'rotateimage',
'flipimage',
'flopimage',
+ 'readimage',
);
// Now, test for deep requirements within Imagick.
@@ -144,7 +145,17 @@ public function load() {
wp_raise_memory_limit( 'image' );
try {
- $this->image = new Imagick( $this->file );
+ $this->image = new Imagick();
+ $file_parts = pathinfo( $this->file );
+ $filename = $this->file;
+
+ if ( 'pdf' == strtolower( $file_parts['extension'] ) ) {
+ $filename = $this->pdf_setup();
+ }
+
+ // Reading image after Imagick instantiation because `setResolution`
+ // only applies correctly before the image is read.
+ $this->image->readImage( $filename );
if ( ! $this->image->valid() )
return new WP_Error( 'invalid_image', __('File is not an image.'), $this->file);
@@ -727,4 +738,27 @@ protected function strip_meta() {
return true;
}
+ /**
+ * Sets up Imagick for PDF processing.
+ * Increases rendering DPI and only loads first page.
+ *
+ * @since 4.7.0
+ * @access protected
+ *
+ * @return string|WP_Error File to load or WP_Error on failure.
+ */
+ protected function pdf_setup() {
+ try {
+ // By default, PDFs are rendered in a very low resolution.
+ // We want the thumbnail to be readable, so increase the rendering DPI.
+ $this->image->setResolution( 128, 128 );
+
+ // Only load the first page.
+ return $this->file . '[0]';
+ }
+ catch ( Exception $e ) {
+ return new WP_Error( 'pdf_setup_failed', $e->getMessage(), $this->file );
+ }
+ }
+
}
diff --git a/code/wp-includes/class-wp-image-editor.php b/code/wp-includes/class-wp-image-editor.php
index c046823e..cc991eb8 100644
--- a/code/wp-includes/class-wp-image-editor.php
+++ b/code/wp-includes/class-wp-image-editor.php
@@ -346,12 +346,8 @@ protected function get_output_format( $filename = null, $mime_type = null ) {
}
if ( $filename ) {
- $ext = '';
- $info = pathinfo( $filename );
- $dir = $info['dirname'];
-
- if ( isset( $info['extension'] ) )
- $ext = $info['extension'];
+ $dir = pathinfo( $filename, PATHINFO_DIRNAME );
+ $ext = pathinfo( $filename, PATHINFO_EXTENSION );
$filename = trailingslashit( $dir ) . wp_basename( $filename, ".$ext" ) . ".{$new_ext}";
}
@@ -375,9 +371,8 @@ public function generate_filename( $suffix = null, $dest_path = null, $extension
if ( ! $suffix )
$suffix = $this->get_suffix();
- $info = pathinfo( $this->file );
- $dir = $info['dirname'];
- $ext = $info['extension'];
+ $dir = pathinfo( $this->file, PATHINFO_DIRNAME );
+ $ext = pathinfo( $this->file, PATHINFO_EXTENSION );
$name = wp_basename( $this->file, ".$ext" );
$new_ext = strtolower( $extension ? $extension : $ext );
diff --git a/code/wp-includes/class-wp-list-util.php b/code/wp-includes/class-wp-list-util.php
new file mode 100644
index 00000000..4af814d5
--- /dev/null
+++ b/code/wp-includes/class-wp-list-util.php
@@ -0,0 +1,267 @@
+output = $this->input = $input;
+ }
+
+ /**
+ * Returns the original input array.
+ *
+ * @since 4.7.0
+ * @access public
+ *
+ * @return array The input array.
+ */
+ public function get_input() {
+ return $this->input;
+ }
+
+ /**
+ * Returns the output array.
+ *
+ * @since 4.7.0
+ * @access public
+ *
+ * @return array The output array.
+ */
+ public function get_output() {
+ return $this->output;
+ }
+
+ /**
+ * Filters the list, based on a set of key => value arguments.
+ *
+ * @since 4.7.0
+ *
+ * @param array $args Optional. An array of key => value arguments to match
+ * against each object. Default empty array.
+ * @param string $operator Optional. The logical operation to perform. 'AND' means
+ * all elements from the array must match. 'OR' means only
+ * one element needs to match. 'NOT' means no elements may
+ * match. Default 'AND'.
+ * @return array Array of found values.
+ */
+ public function filter( $args = array(), $operator = 'AND' ) {
+ if ( empty( $args ) ) {
+ return $this->output;
+ }
+
+ $operator = strtoupper( $operator );
+
+ if ( ! in_array( $operator, array( 'AND', 'OR', 'NOT' ), true ) ) {
+ return array();
+ }
+
+ $count = count( $args );
+ $filtered = array();
+
+ foreach ( $this->output as $key => $obj ) {
+ $to_match = (array) $obj;
+
+ $matched = 0;
+ foreach ( $args as $m_key => $m_value ) {
+ if ( array_key_exists( $m_key, $to_match ) && $m_value == $to_match[ $m_key ] ) {
+ $matched++;
+ }
+ }
+
+ if (
+ ( 'AND' == $operator && $matched == $count ) ||
+ ( 'OR' == $operator && $matched > 0 ) ||
+ ( 'NOT' == $operator && 0 == $matched )
+ ) {
+ $filtered[$key] = $obj;
+ }
+ }
+
+ $this->output = $filtered;
+
+ return $this->output;
+ }
+
+ /**
+ * Plucks a certain field out of each object in the list.
+ *
+ * This has the same functionality and prototype of
+ * array_column() (PHP 5.5) but also supports objects.
+ *
+ * @since 4.7.0
+ *
+ * @param int|string $field Field from the object to place instead of the entire object
+ * @param int|string $index_key Optional. Field from the object to use as keys for the new array.
+ * Default null.
+ * @return array Array of found values. If `$index_key` is set, an array of found values with keys
+ * corresponding to `$index_key`. If `$index_key` is null, array keys from the original
+ * `$list` will be preserved in the results.
+ */
+ public function pluck( $field, $index_key = null ) {
+ if ( ! $index_key ) {
+ /*
+ * This is simple. Could at some point wrap array_column()
+ * if we knew we had an array of arrays.
+ */
+ foreach ( $this->output as $key => $value ) {
+ if ( is_object( $value ) ) {
+ $this->output[ $key ] = $value->$field;
+ } else {
+ $this->output[ $key ] = $value[ $field ];
+ }
+ }
+ return $this->output;
+ }
+
+ /*
+ * When index_key is not set for a particular item, push the value
+ * to the end of the stack. This is how array_column() behaves.
+ */
+ $newlist = array();
+ foreach ( $this->output as $value ) {
+ if ( is_object( $value ) ) {
+ if ( isset( $value->$index_key ) ) {
+ $newlist[ $value->$index_key ] = $value->$field;
+ } else {
+ $newlist[] = $value->$field;
+ }
+ } else {
+ if ( isset( $value[ $index_key ] ) ) {
+ $newlist[ $value[ $index_key ] ] = $value[ $field ];
+ } else {
+ $newlist[] = $value[ $field ];
+ }
+ }
+ }
+
+ $this->output = $newlist;
+
+ return $this->output;
+ }
+
+ /**
+ * Sorts the list, based on one or more orderby arguments.
+ *
+ * @since 4.7.0
+ *
+ * @param string|array $orderby Optional. Either the field name to order by or an array
+ * of multiple orderby fields as $orderby => $order.
+ * @param string $order Optional. Either 'ASC' or 'DESC'. Only used if $orderby
+ * is a string.
+ * @param bool $preserve_keys Optional. Whether to preserve keys. Default false.
+ * @return array The sorted array.
+ */
+ public function sort( $orderby = array(), $order = 'ASC', $preserve_keys = false ) {
+ if ( empty( $orderby ) ) {
+ return $this->output;
+ }
+
+ if ( is_string( $orderby ) ) {
+ $orderby = array( $orderby => $order );
+ }
+
+ foreach ( $orderby as $field => $direction ) {
+ $orderby[ $field ] = 'DESC' === strtoupper( $direction ) ? 'DESC' : 'ASC';
+ }
+
+ $this->orderby = $orderby;
+
+ if ( $preserve_keys ) {
+ uasort( $this->output, array( $this, 'sort_callback' ) );
+ } else {
+ usort( $this->output, array( $this, 'sort_callback' ) );
+ }
+
+ $this->orderby = array();
+
+ return $this->output;
+ }
+
+ /**
+ * Callback to sort the list by specific fields.
+ *
+ * @since 4.7.0
+ * @access private
+ *
+ * @see WP_List_Util::sort()
+ *
+ * @param object|array $a One object to compare.
+ * @param object|array $b The other object to compare.
+ * @return int 0 if both objects equal. -1 if second object should come first, 1 otherwise.
+ */
+ private function sort_callback( $a, $b ) {
+ if ( empty( $this->orderby ) ) {
+ return 0;
+ }
+
+ $a = (array) $a;
+ $b = (array) $b;
+
+ foreach ( $this->orderby as $field => $direction ) {
+ if ( ! isset( $a[ $field ] ) || ! isset( $b[ $field ] ) ) {
+ continue;
+ }
+
+ if ( $a[ $field ] == $b[ $field ] ) {
+ continue;
+ }
+
+ $results = 'DESC' === $direction ? array( 1, -1 ) : array( -1, 1 );
+
+ if ( is_numeric( $a[ $field ] ) && is_numeric( $b[ $field ] ) ) {
+ return ( $a[ $field ] < $b[ $field ] ) ? $results[0] : $results[1];
+ }
+
+ return 0 > strcmp( $a[ $field ], $b[ $field ] ) ? $results[0] : $results[1];
+ }
+
+ return 0;
+ }
+}
diff --git a/code/wp-includes/class-wp-locale-switcher.php b/code/wp-includes/class-wp-locale-switcher.php
new file mode 100644
index 00000000..2b0638d2
--- /dev/null
+++ b/code/wp-includes/class-wp-locale-switcher.php
@@ -0,0 +1,240 @@
+original_locale = is_admin() ? get_user_locale() : get_locale();
+ $this->available_languages = array_merge( array( 'en_US' ), get_available_languages() );
+ }
+
+ /**
+ * Initializes the locale switcher.
+ *
+ * Hooks into the {@see 'locale'} filter to change the locale on the fly.
+ */
+ public function init() {
+ add_filter( 'locale', array( $this, 'filter_locale' ) );
+ }
+
+ /**
+ * Switches the translations according to the given locale.
+ *
+ * @since 4.7.0
+ *
+ * @param string $locale The locale to switch to.
+ * @return bool True on success, false on failure.
+ */
+ public function switch_to_locale( $locale ) {
+ $current_locale = is_admin() ? get_user_locale() : get_locale();
+ if ( $current_locale === $locale ) {
+ return false;
+ }
+
+ if ( ! in_array( $locale, $this->available_languages, true ) ) {
+ return false;
+ }
+
+ $this->locales[] = $locale;
+
+ $this->change_locale( $locale );
+
+ /**
+ * Fires when the locale is switched.
+ *
+ * @since 4.7.0
+ *
+ * @param string $locale The new locale.
+ */
+ do_action( 'switch_locale', $locale );
+
+ return true;
+ }
+
+ /**
+ * Restores the translations according to the previous locale.
+ *
+ * @since 4.7.0
+ *
+ * @return string|false Locale on success, false on failure.
+ */
+ public function restore_previous_locale() {
+ $previous_locale = array_pop( $this->locales );
+
+ if ( null === $previous_locale ) {
+ // The stack is empty, bail.
+ return false;
+ }
+
+ $locale = end( $this->locales );
+
+ if ( ! $locale ) {
+ // There's nothing left in the stack: go back to the original locale.
+ $locale = $this->original_locale;
+ }
+
+ $this->change_locale( $locale );
+
+ /**
+ * Fires when the locale is restored to the previous one.
+ *
+ * @since 4.7.0
+ *
+ * @param string $locale The new locale.
+ * @param string $previous_locale The previous locale.
+ */
+ do_action( 'restore_previous_locale', $locale, $previous_locale );
+
+ return $locale;
+ }
+
+ /**
+ * Restores the translations according to the original locale.
+ *
+ * @since 4.7.0
+ *
+ * @return string|false Locale on success, false on failure.
+ */
+ public function restore_current_locale() {
+ if ( empty( $this->locales ) ) {
+ return false;
+ }
+
+ $this->locales = array( $this->original_locale );
+
+ return $this->restore_previous_locale();
+ }
+
+ /**
+ * Whether switch_to_locale() is in effect.
+ *
+ * @since 4.7.0
+ *
+ * @return bool True if the locale has been switched, false otherwise.
+ */
+ public function is_switched() {
+ return ! empty( $this->locales );
+ }
+
+ /**
+ * Filters the WordPress install's locale.
+ *
+ * @since 4.7.0
+ *
+ * @param string $locale The WordPress install's locale.
+ * @return string The locale currently being switched to.
+ */
+ public function filter_locale( $locale ) {
+ $switched_locale = end( $this->locales );
+
+ if ( $switched_locale ) {
+ return $switched_locale;
+ }
+
+ return $locale;
+ }
+
+ /**
+ * Load translations for a given locale.
+ *
+ * When switching to a locale, translations for this locale must be loaded from scratch.
+ *
+ * @since 4.7.0
+ * @access private
+ *
+ * @global Mo[] $l10n An array of all currently loaded text domains.
+ *
+ * @param string $locale The locale to load translations for.
+ */
+ private function load_translations( $locale ) {
+ global $l10n;
+
+ $domains = $l10n ? array_keys( $l10n ) : array();
+
+ load_default_textdomain( $locale );
+
+ foreach ( $domains as $domain ) {
+ if ( 'default' === $domain ) {
+ continue;
+ }
+
+ unload_textdomain( $domain );
+ get_translations_for_domain( $domain );
+ }
+ }
+
+ /**
+ * Changes the site's locale to the given one.
+ *
+ * Loads the translations, changes the global `$wp_locale` object and updates
+ * all post type labels.
+ *
+ * @since 4.7.0
+ * @access private
+ *
+ * @global WP_Locale $wp_locale The WordPress date and time locale object.
+ *
+ * @param string $locale The locale to change to.
+ */
+ private function change_locale( $locale ) {
+ // Reset translation availability information.
+ _get_path_to_translation( null, true );
+
+ $this->load_translations( $locale );
+
+ $GLOBALS['wp_locale'] = new WP_Locale();
+
+ /**
+ * Fires when the locale is switched to or restored.
+ *
+ * @since 4.7.0
+ *
+ * @param string $locale The new locale.
+ */
+ do_action( 'change_locale', $locale );
+ }
+}
diff --git a/code/wp-includes/class-wp-locale.php b/code/wp-includes/class-wp-locale.php
index e8dcfc64..2cc6afaa 100644
--- a/code/wp-includes/class-wp-locale.php
+++ b/code/wp-includes/class-wp-locale.php
@@ -59,6 +59,14 @@ class WP_Locale {
*/
public $month;
+ /**
+ * Stores the translated strings for the month names in genitive case, if the locale specifies.
+ *
+ * @since 4.4.0
+ * @var array
+ */
+ public $month_genitive;
+
/**
* Stores the translated strings for the abbreviated month names.
*
@@ -117,7 +125,6 @@ public function __construct() {
* @access private
*
* @global string $text_direction
- * @global string $wp_version
*/
public function init() {
// The Weekdays
@@ -223,7 +230,7 @@ public function init() {
elseif ( 'rtl' == _x( 'ltr', 'text direction' ) )
$this->text_direction = 'rtl';
- if ( 'rtl' === $this->text_direction && strpos( $GLOBALS['wp_version'], '-src' ) ) {
+ if ( 'rtl' === $this->text_direction && strpos( get_bloginfo( 'version' ), '-src' ) ) {
$this->text_direction = 'ltr';
add_action( 'all_admin_notices', array( $this, 'rtl_src_admin_notice' ) );
}
diff --git a/code/wp-includes/class-wp-matchesmapregex.php b/code/wp-includes/class-wp-matchesmapregex.php
new file mode 100644
index 00000000..86ebb252
--- /dev/null
+++ b/code/wp-includes/class-wp-matchesmapregex.php
@@ -0,0 +1,97 @@
+_subject = $subject;
+ $this->_matches = $matches;
+ $this->output = $this->_map();
+ }
+
+ /**
+ * Substitute substring matches in subject.
+ *
+ * static helper function to ease use
+ *
+ * @static
+ * @access public
+ *
+ * @param string $subject subject
+ * @param array $matches data used for substitution
+ * @return string
+ */
+ public static function apply($subject, $matches) {
+ $oSelf = new WP_MatchesMapRegex($subject, $matches);
+ return $oSelf->output;
+ }
+
+ /**
+ * do the actual mapping
+ *
+ * @access private
+ * @return string
+ */
+ private function _map() {
+ $callback = array($this, 'callback');
+ return preg_replace_callback($this->_pattern, $callback, $this->_subject);
+ }
+
+ /**
+ * preg_replace_callback hook
+ *
+ * @access public
+ * @param array $matches preg_replace regexp matches
+ * @return string
+ */
+ public function callback($matches) {
+ $index = intval(substr($matches[0], 9, -1));
+ return ( isset( $this->_matches[$index] ) ? urlencode($this->_matches[$index]) : '' );
+ }
+}
diff --git a/code/wp-includes/class-wp-network-query.php b/code/wp-includes/class-wp-network-query.php
index 7f8954ca..1bf38ad7 100644
--- a/code/wp-includes/class-wp-network-query.php
+++ b/code/wp-includes/class-wp-network-query.php
@@ -103,7 +103,7 @@ class WP_Network_Query {
* Default false.
* @type string $fields Network fields to return. Accepts 'ids' (returns an array of network IDs)
* or empty (returns an array of complete network objects). Default empty.
- * @type int $number Maximum number of networks to retrieve. Default null (no limit).
+ * @type int $number Maximum number of networks to retrieve. Default empty (no limit).
* @type int $offset Number of networks to offset the query. Used to build LIMIT clause.
* Default 0.
* @type bool $no_found_rows Whether to disable the `SQL_CALC_FOUND_ROWS` query. Default true.
@@ -111,12 +111,10 @@ class WP_Network_Query {
* 'domain_length', 'path_length' and 'network__in'. Also accepts false,
* an empty array, or 'none' to disable `ORDER BY` clause. Default 'id'.
* @type string $order How to order retrieved networks. Accepts 'ASC', 'DESC'. Default 'ASC'.
- * @type string $domain Limit results to those affiliated with a given network ID.
- * Default current network ID.
+ * @type string $domain Limit results to those affiliated with a given domain. Default empty.
* @type array $domain__in Array of domains to include affiliated networks for. Default empty.
* @type array $domain__not_in Array of domains to exclude affiliated networks for. Default empty.
- * @type string $path Limit results to those affiliated with a given network ID.
- * Default current network ID.
+ * @type string $path Limit results to those affiliated with a given path. Default empty.
* @type array $path__in Array of paths to include affiliated networks for. Default empty.
* @type array $path__not_in Array of paths to exclude affiliated networks for. Default empty.
* @type string $search Search term(s) to retrieve matching networks for. Default empty.
@@ -211,11 +209,7 @@ public function get_networks() {
// $args can include anything. Only use the args defined in the query_var_defaults to compute the key.
$key = md5( serialize( wp_array_slice_assoc( $this->query_vars, array_keys( $this->query_var_defaults ) ) ) );
- $last_changed = wp_cache_get( 'last_changed', 'networks' );
- if ( ! $last_changed ) {
- $last_changed = microtime();
- wp_cache_set( 'last_changed', $last_changed, 'networks' );
- }
+ $last_changed = wp_cache_get_last_changed( 'networks' );
$cache_key = "get_network_ids:$key:$last_changed";
$cache_value = wp_cache_get( $cache_key, 'networks' );
diff --git a/code/wp-includes/class-wp-post-type.php b/code/wp-includes/class-wp-post-type.php
index c08ca5e5..0b1d3c00 100644
--- a/code/wp-includes/class-wp-post-type.php
+++ b/code/wp-includes/class-wp-post-type.php
@@ -366,7 +366,7 @@ public function set_props( $args ) {
$args = wp_parse_args( $args );
/**
- * Filter the arguments for registering a post type.
+ * Filters the arguments for registering a post type.
*
* @since 4.4.0
*
diff --git a/code/wp-includes/class-wp-post.php b/code/wp-includes/class-wp-post.php
index 5904e588..c9669348 100644
--- a/code/wp-includes/class-wp-post.php
+++ b/code/wp-includes/class-wp-post.php
@@ -210,9 +210,11 @@ final class WP_Post {
public static function get_instance( $post_id ) {
global $wpdb;
- $post_id = (int) $post_id;
- if ( ! $post_id )
+ if ( ! is_numeric( $post_id ) || $post_id != floor( $post_id ) || ! $post_id ) {
return false;
+ }
+
+ $post_id = (int) $post_id;
$_post = wp_cache_get( $post_id, 'posts' );
@@ -252,7 +254,7 @@ public function __isset( $key ) {
return true;
if ( 'page_template' == $key )
- return ( 'page' == $this->post_type );
+ return true;
if ( 'post_category' == $key )
return true;
diff --git a/code/wp-includes/class-wp-query.php b/code/wp-includes/class-wp-query.php
new file mode 100644
index 00000000..7f3c22a7
--- /dev/null
+++ b/code/wp-includes/class-wp-query.php
@@ -0,0 +1,4107 @@
+query_vars state like md5(serialize( $this->query_vars ) ) so we know
+ * whether we have to re-parse because something has changed
+ *
+ * @since 3.1.0
+ * @access private
+ * @var bool|string
+ */
+ private $query_vars_hash = false;
+
+ /**
+ * Whether query vars have changed since the initial parse_query() call. Used to catch modifications to query vars made
+ * via pre_get_posts hooks.
+ *
+ * @since 3.1.1
+ * @access private
+ */
+ private $query_vars_changed = true;
+
+ /**
+ * Set if post thumbnails are cached
+ *
+ * @since 3.2.0
+ * @access public
+ * @var bool
+ */
+ public $thumbnails_cached = false;
+
+ /**
+ * Cached list of search stopwords.
+ *
+ * @since 3.7.0
+ * @var array
+ */
+ private $stopwords;
+
+ private $compat_fields = array( 'query_vars_hash', 'query_vars_changed' );
+
+ private $compat_methods = array( 'init_query_flags', 'parse_tax_query' );
+
+ /**
+ * Resets query flags to false.
+ *
+ * The query flags are what page info WordPress was able to figure out.
+ *
+ * @since 2.0.0
+ * @access private
+ */
+ private function init_query_flags() {
+ $this->is_single = false;
+ $this->is_preview = false;
+ $this->is_page = false;
+ $this->is_archive = false;
+ $this->is_date = false;
+ $this->is_year = false;
+ $this->is_month = false;
+ $this->is_day = false;
+ $this->is_time = false;
+ $this->is_author = false;
+ $this->is_category = false;
+ $this->is_tag = false;
+ $this->is_tax = false;
+ $this->is_search = false;
+ $this->is_feed = false;
+ $this->is_comment_feed = false;
+ $this->is_trackback = false;
+ $this->is_home = false;
+ $this->is_404 = false;
+ $this->is_paged = false;
+ $this->is_admin = false;
+ $this->is_attachment = false;
+ $this->is_singular = false;
+ $this->is_robots = false;
+ $this->is_posts_page = false;
+ $this->is_post_type_archive = false;
+ }
+
+ /**
+ * Initiates object properties and sets default values.
+ *
+ * @since 1.5.0
+ * @access public
+ */
+ public function init() {
+ unset($this->posts);
+ unset($this->query);
+ $this->query_vars = array();
+ unset($this->queried_object);
+ unset($this->queried_object_id);
+ $this->post_count = 0;
+ $this->current_post = -1;
+ $this->in_the_loop = false;
+ unset( $this->request );
+ unset( $this->post );
+ unset( $this->comments );
+ unset( $this->comment );
+ $this->comment_count = 0;
+ $this->current_comment = -1;
+ $this->found_posts = 0;
+ $this->max_num_pages = 0;
+ $this->max_num_comment_pages = 0;
+
+ $this->init_query_flags();
+ }
+
+ /**
+ * Reparse the query vars.
+ *
+ * @since 1.5.0
+ * @access public
+ */
+ public function parse_query_vars() {
+ $this->parse_query();
+ }
+
+ /**
+ * Fills in the query variables, which do not exist within the parameter.
+ *
+ * @since 2.1.0
+ * @since 4.4.0 Removed the `comments_popup` public query variable.
+ * @access public
+ *
+ * @param array $array Defined query variables.
+ * @return array Complete query variables with undefined ones filled in empty.
+ */
+ public function fill_query_vars($array) {
+ $keys = array(
+ 'error'
+ , 'm'
+ , 'p'
+ , 'post_parent'
+ , 'subpost'
+ , 'subpost_id'
+ , 'attachment'
+ , 'attachment_id'
+ , 'name'
+ , 'static'
+ , 'pagename'
+ , 'page_id'
+ , 'second'
+ , 'minute'
+ , 'hour'
+ , 'day'
+ , 'monthnum'
+ , 'year'
+ , 'w'
+ , 'category_name'
+ , 'tag'
+ , 'cat'
+ , 'tag_id'
+ , 'author'
+ , 'author_name'
+ , 'feed'
+ , 'tb'
+ , 'paged'
+ , 'meta_key'
+ , 'meta_value'
+ , 'preview'
+ , 's'
+ , 'sentence'
+ , 'title'
+ , 'fields'
+ , 'menu_order'
+ , 'embed'
+ );
+
+ foreach ( $keys as $key ) {
+ if ( !isset($array[$key]) )
+ $array[$key] = '';
+ }
+
+ $array_keys = array( 'category__in', 'category__not_in', 'category__and', 'post__in', 'post__not_in', 'post_name__in',
+ 'tag__in', 'tag__not_in', 'tag__and', 'tag_slug__in', 'tag_slug__and', 'post_parent__in', 'post_parent__not_in',
+ 'author__in', 'author__not_in' );
+
+ foreach ( $array_keys as $key ) {
+ if ( !isset($array[$key]) )
+ $array[$key] = array();
+ }
+ return $array;
+ }
+
+ /**
+ * Parse a query string and set query type booleans.
+ *
+ * @since 1.5.0
+ * @since 4.2.0 Introduced the ability to order by specific clauses of a `$meta_query`, by passing the clause's
+ * array key to `$orderby`.
+ * @since 4.4.0 Introduced `$post_name__in` and `$title` parameters. `$s` was updated to support excluded
+ * search terms, by prepending a hyphen.
+ * @since 4.5.0 Removed the `$comments_popup` parameter.
+ * Introduced the `$comment_status` and `$ping_status` parameters.
+ * Introduced `RAND(x)` syntax for `$orderby`, which allows an integer seed value to random sorts.
+ * @since 4.6.0 Added 'post_name__in' support for `$orderby`. Introduced the `$lazy_load_term_meta` argument.
+ * @access public
+ *
+ * @param string|array $query {
+ * Optional. Array or string of Query parameters.
+ *
+ * @type int $attachment_id Attachment post ID. Used for 'attachment' post_type.
+ * @type int|string $author Author ID, or comma-separated list of IDs.
+ * @type string $author_name User 'user_nicename'.
+ * @type array $author__in An array of author IDs to query from.
+ * @type array $author__not_in An array of author IDs not to query from.
+ * @type bool $cache_results Whether to cache post information. Default true.
+ * @type int|string $cat Category ID or comma-separated list of IDs (this or any children).
+ * @type array $category__and An array of category IDs (AND in).
+ * @type array $category__in An array of category IDs (OR in, no children).
+ * @type array $category__not_in An array of category IDs (NOT in).
+ * @type string $category_name Use category slug (not name, this or any children).
+ * @type string $comment_status Comment status.
+ * @type int $comments_per_page The number of comments to return per page.
+ * Default 'comments_per_page' option.
+ * @type array $date_query An associative array of WP_Date_Query arguments.
+ * See WP_Date_Query::__construct().
+ * @type int $day Day of the month. Default empty. Accepts numbers 1-31.
+ * @type bool $exact Whether to search by exact keyword. Default false.
+ * @type string|array $fields Which fields to return. Single field or all fields (string),
+ * or array of fields. 'id=>parent' uses 'id' and 'post_parent'.
+ * Default all fields. Accepts 'ids', 'id=>parent'.
+ * @type int $hour Hour of the day. Default empty. Accepts numbers 0-23.
+ * @type int|bool $ignore_sticky_posts Whether to ignore sticky posts or not. Setting this to false
+ * excludes stickies from 'post__in'. Accepts 1|true, 0|false.
+ * Default 0|false.
+ * @type int $m Combination YearMonth. Accepts any four-digit year and month
+ * numbers 1-12. Default empty.
+ * @type string $meta_compare Comparison operator to test the 'meta_value'.
+ * @type string $meta_key Custom field key.
+ * @type array $meta_query An associative array of WP_Meta_Query arguments. See WP_Meta_Query.
+ * @type string $meta_value Custom field value.
+ * @type int $meta_value_num Custom field value number.
+ * @type int $menu_order The menu order of the posts.
+ * @type int $monthnum The two-digit month. Default empty. Accepts numbers 1-12.
+ * @type string $name Post slug.
+ * @type bool $nopaging Show all posts (true) or paginate (false). Default false.
+ * @type bool $no_found_rows Whether to skip counting the total rows found. Enabling can improve
+ * performance. Default false.
+ * @type int $offset The number of posts to offset before retrieval.
+ * @type string $order Designates ascending or descending order of posts. Default 'DESC'.
+ * Accepts 'ASC', 'DESC'.
+ * @type string|array $orderby Sort retrieved posts by parameter. One or more options may be
+ * passed. To use 'meta_value', or 'meta_value_num',
+ * 'meta_key=keyname' must be also be defined. To sort by a
+ * specific `$meta_query` clause, use that clause's array key.
+ * Default 'date'. Accepts 'none', 'name', 'author', 'date',
+ * 'title', 'modified', 'menu_order', 'parent', 'ID', 'rand',
+ * 'RAND(x)' (where 'x' is an integer seed value),
+ * 'comment_count', 'meta_value', 'meta_value_num', 'post__in',
+ * 'post_name__in', 'post_parent__in', and the array keys
+ * of `$meta_query`.
+ * @type int $p Post ID.
+ * @type int $page Show the number of posts that would show up on page X of a
+ * static front page.
+ * @type int $paged The number of the current page.
+ * @type int $page_id Page ID.
+ * @type string $pagename Page slug.
+ * @type string $perm Show posts if user has the appropriate capability.
+ * @type string $ping_status Ping status.
+ * @type array $post__in An array of post IDs to retrieve, sticky posts will be included
+ * @type string $post_mime_type The mime type of the post. Used for 'attachment' post_type.
+ * @type array $post__not_in An array of post IDs not to retrieve. Note: a string of comma-
+ * separated IDs will NOT work.
+ * @type int $post_parent Page ID to retrieve child pages for. Use 0 to only retrieve
+ * top-level pages.
+ * @type array $post_parent__in An array containing parent page IDs to query child pages from.
+ * @type array $post_parent__not_in An array containing parent page IDs not to query child pages from.
+ * @type string|array $post_type A post type slug (string) or array of post type slugs.
+ * Default 'any' if using 'tax_query'.
+ * @type string|array $post_status A post status (string) or array of post statuses.
+ * @type int $posts_per_page The number of posts to query for. Use -1 to request all posts.
+ * @type int $posts_per_archive_page The number of posts to query for by archive page. Overrides
+ * 'posts_per_page' when is_archive(), or is_search() are true.
+ * @type array $post_name__in An array of post slugs that results must match.
+ * @type string $s Search keyword(s). Prepending a term with a hyphen will
+ * exclude posts matching that term. Eg, 'pillow -sofa' will
+ * return posts containing 'pillow' but not 'sofa'. The
+ * character used for exclusion can be modified using the
+ * the 'wp_query_search_exclusion_prefix' filter.
+ * @type int $second Second of the minute. Default empty. Accepts numbers 0-60.
+ * @type bool $sentence Whether to search by phrase. Default false.
+ * @type bool $suppress_filters Whether to suppress filters. Default false.
+ * @type string $tag Tag slug. Comma-separated (either), Plus-separated (all).
+ * @type array $tag__and An array of tag ids (AND in).
+ * @type array $tag__in An array of tag ids (OR in).
+ * @type array $tag__not_in An array of tag ids (NOT in).
+ * @type int $tag_id Tag id or comma-separated list of IDs.
+ * @type array $tag_slug__and An array of tag slugs (AND in).
+ * @type array $tag_slug__in An array of tag slugs (OR in). unless 'ignore_sticky_posts' is
+ * true. Note: a string of comma-separated IDs will NOT work.
+ * @type array $tax_query An associative array of WP_Tax_Query arguments.
+ * See WP_Tax_Query->queries.
+ * @type string $title Post title.
+ * @type bool $update_post_meta_cache Whether to update the post meta cache. Default true.
+ * @type bool $update_post_term_cache Whether to update the post term cache. Default true.
+ * @type bool $lazy_load_term_meta Whether to lazy-load term meta. Setting to false will
+ * disable cache priming for term meta, so that each
+ * get_term_meta() call will hit the database.
+ * Defaults to the value of `$update_post_term_cache`.
+ * @type int $w The week number of the year. Default empty. Accepts numbers 0-53.
+ * @type int $year The four-digit year. Default empty. Accepts any four-digit year.
+ * }
+ */
+ public function parse_query( $query = '' ) {
+ if ( ! empty( $query ) ) {
+ $this->init();
+ $this->query = $this->query_vars = wp_parse_args( $query );
+ } elseif ( ! isset( $this->query ) ) {
+ $this->query = $this->query_vars;
+ }
+
+ $this->query_vars = $this->fill_query_vars($this->query_vars);
+ $qv = &$this->query_vars;
+ $this->query_vars_changed = true;
+
+ if ( ! empty($qv['robots']) )
+ $this->is_robots = true;
+
+ if ( ! is_scalar( $qv['p'] ) || $qv['p'] < 0 ) {
+ $qv['p'] = 0;
+ $qv['error'] = '404';
+ } else {
+ $qv['p'] = intval( $qv['p'] );
+ }
+
+ $qv['page_id'] = absint($qv['page_id']);
+ $qv['year'] = absint($qv['year']);
+ $qv['monthnum'] = absint($qv['monthnum']);
+ $qv['day'] = absint($qv['day']);
+ $qv['w'] = absint($qv['w']);
+ $qv['m'] = is_scalar( $qv['m'] ) ? preg_replace( '|[^0-9]|', '', $qv['m'] ) : '';
+ $qv['paged'] = absint($qv['paged']);
+ $qv['cat'] = preg_replace( '|[^0-9,-]|', '', $qv['cat'] ); // comma separated list of positive or negative integers
+ $qv['author'] = preg_replace( '|[^0-9,-]|', '', $qv['author'] ); // comma separated list of positive or negative integers
+ $qv['pagename'] = trim( $qv['pagename'] );
+ $qv['name'] = trim( $qv['name'] );
+ $qv['title'] = trim( $qv['title'] );
+ if ( '' !== $qv['hour'] ) $qv['hour'] = absint($qv['hour']);
+ if ( '' !== $qv['minute'] ) $qv['minute'] = absint($qv['minute']);
+ if ( '' !== $qv['second'] ) $qv['second'] = absint($qv['second']);
+ if ( '' !== $qv['menu_order'] ) $qv['menu_order'] = absint($qv['menu_order']);
+
+ // Fairly insane upper bound for search string lengths.
+ if ( ! is_scalar( $qv['s'] ) || ( ! empty( $qv['s'] ) && strlen( $qv['s'] ) > 1600 ) ) {
+ $qv['s'] = '';
+ }
+
+ // Compat. Map subpost to attachment.
+ if ( '' != $qv['subpost'] )
+ $qv['attachment'] = $qv['subpost'];
+ if ( '' != $qv['subpost_id'] )
+ $qv['attachment_id'] = $qv['subpost_id'];
+
+ $qv['attachment_id'] = absint($qv['attachment_id']);
+
+ if ( ('' != $qv['attachment']) || !empty($qv['attachment_id']) ) {
+ $this->is_single = true;
+ $this->is_attachment = true;
+ } elseif ( '' != $qv['name'] ) {
+ $this->is_single = true;
+ } elseif ( $qv['p'] ) {
+ $this->is_single = true;
+ } elseif ( ('' !== $qv['hour']) && ('' !== $qv['minute']) &&('' !== $qv['second']) && ('' != $qv['year']) && ('' != $qv['monthnum']) && ('' != $qv['day']) ) {
+ // If year, month, day, hour, minute, and second are set, a single
+ // post is being queried.
+ $this->is_single = true;
+ } elseif ( '' != $qv['static'] || '' != $qv['pagename'] || !empty($qv['page_id']) ) {
+ $this->is_page = true;
+ $this->is_single = false;
+ } else {
+ // Look for archive queries. Dates, categories, authors, search, post type archives.
+
+ if ( isset( $this->query['s'] ) ) {
+ $this->is_search = true;
+ }
+
+ if ( '' !== $qv['second'] ) {
+ $this->is_time = true;
+ $this->is_date = true;
+ }
+
+ if ( '' !== $qv['minute'] ) {
+ $this->is_time = true;
+ $this->is_date = true;
+ }
+
+ if ( '' !== $qv['hour'] ) {
+ $this->is_time = true;
+ $this->is_date = true;
+ }
+
+ if ( $qv['day'] ) {
+ if ( ! $this->is_date ) {
+ $date = sprintf( '%04d-%02d-%02d', $qv['year'], $qv['monthnum'], $qv['day'] );
+ if ( $qv['monthnum'] && $qv['year'] && ! wp_checkdate( $qv['monthnum'], $qv['day'], $qv['year'], $date ) ) {
+ $qv['error'] = '404';
+ } else {
+ $this->is_day = true;
+ $this->is_date = true;
+ }
+ }
+ }
+
+ if ( $qv['monthnum'] ) {
+ if ( ! $this->is_date ) {
+ if ( 12 < $qv['monthnum'] ) {
+ $qv['error'] = '404';
+ } else {
+ $this->is_month = true;
+ $this->is_date = true;
+ }
+ }
+ }
+
+ if ( $qv['year'] ) {
+ if ( ! $this->is_date ) {
+ $this->is_year = true;
+ $this->is_date = true;
+ }
+ }
+
+ if ( $qv['m'] ) {
+ $this->is_date = true;
+ if ( strlen($qv['m']) > 9 ) {
+ $this->is_time = true;
+ } elseif ( strlen( $qv['m'] ) > 7 ) {
+ $this->is_day = true;
+ } elseif ( strlen( $qv['m'] ) > 5 ) {
+ $this->is_month = true;
+ } else {
+ $this->is_year = true;
+ }
+ }
+
+ if ( '' != $qv['w'] ) {
+ $this->is_date = true;
+ }
+
+ $this->query_vars_hash = false;
+ $this->parse_tax_query( $qv );
+
+ foreach ( $this->tax_query->queries as $tax_query ) {
+ if ( ! is_array( $tax_query ) ) {
+ continue;
+ }
+
+ if ( isset( $tax_query['operator'] ) && 'NOT IN' != $tax_query['operator'] ) {
+ switch ( $tax_query['taxonomy'] ) {
+ case 'category':
+ $this->is_category = true;
+ break;
+ case 'post_tag':
+ $this->is_tag = true;
+ break;
+ default:
+ $this->is_tax = true;
+ }
+ }
+ }
+ unset( $tax_query );
+
+ if ( empty($qv['author']) || ($qv['author'] == '0') ) {
+ $this->is_author = false;
+ } else {
+ $this->is_author = true;
+ }
+
+ if ( '' != $qv['author_name'] )
+ $this->is_author = true;
+
+ if ( !empty( $qv['post_type'] ) && ! is_array( $qv['post_type'] ) ) {
+ $post_type_obj = get_post_type_object( $qv['post_type'] );
+ if ( ! empty( $post_type_obj->has_archive ) )
+ $this->is_post_type_archive = true;
+ }
+
+ if ( $this->is_post_type_archive || $this->is_date || $this->is_author || $this->is_category || $this->is_tag || $this->is_tax )
+ $this->is_archive = true;
+ }
+
+ if ( '' != $qv['feed'] )
+ $this->is_feed = true;
+
+ if ( '' != $qv['embed'] ) {
+ $this->is_embed = true;
+ }
+
+ if ( '' != $qv['tb'] )
+ $this->is_trackback = true;
+
+ if ( '' != $qv['paged'] && ( intval($qv['paged']) > 1 ) )
+ $this->is_paged = true;
+
+ // if we're previewing inside the write screen
+ if ( '' != $qv['preview'] )
+ $this->is_preview = true;
+
+ if ( is_admin() )
+ $this->is_admin = true;
+
+ if ( false !== strpos($qv['feed'], 'comments-') ) {
+ $qv['feed'] = str_replace('comments-', '', $qv['feed']);
+ $qv['withcomments'] = 1;
+ }
+
+ $this->is_singular = $this->is_single || $this->is_page || $this->is_attachment;
+
+ if ( $this->is_feed && ( !empty($qv['withcomments']) || ( empty($qv['withoutcomments']) && $this->is_singular ) ) )
+ $this->is_comment_feed = true;
+
+ if ( !( $this->is_singular || $this->is_archive || $this->is_search || $this->is_feed || ( defined( 'REST_REQUEST' ) && REST_REQUEST ) || $this->is_trackback || $this->is_404 || $this->is_admin || $this->is_robots ) )
+ $this->is_home = true;
+
+ // Correct is_* for page_on_front and page_for_posts
+ if ( $this->is_home && 'page' == get_option('show_on_front') && get_option('page_on_front') ) {
+ $_query = wp_parse_args($this->query);
+ // pagename can be set and empty depending on matched rewrite rules. Ignore an empty pagename.
+ if ( isset($_query['pagename']) && '' == $_query['pagename'] )
+ unset($_query['pagename']);
+
+ unset( $_query['embed'] );
+
+ if ( empty($_query) || !array_diff( array_keys($_query), array('preview', 'page', 'paged', 'cpage') ) ) {
+ $this->is_page = true;
+ $this->is_home = false;
+ $qv['page_id'] = get_option('page_on_front');
+ // Correct for page_on_front
+ if ( !empty($qv['paged']) ) {
+ $qv['page'] = $qv['paged'];
+ unset($qv['paged']);
+ }
+ }
+ }
+
+ if ( '' != $qv['pagename'] ) {
+ $this->queried_object = get_page_by_path( $qv['pagename'] );
+
+ if ( $this->queried_object && 'attachment' == $this->queried_object->post_type ) {
+ if ( preg_match( "/^[^%]*%(?:postname)%/", get_option( 'permalink_structure' ) ) ) {
+ // See if we also have a post with the same slug
+ $post = get_page_by_path( $qv['pagename'], OBJECT, 'post' );
+ if ( $post ) {
+ $this->queried_object = $post;
+ $this->is_page = false;
+ $this->is_single = true;
+ }
+ }
+ }
+
+ if ( ! empty( $this->queried_object ) ) {
+ $this->queried_object_id = (int) $this->queried_object->ID;
+ } else {
+ unset( $this->queried_object );
+ }
+
+ if ( 'page' == get_option('show_on_front') && isset($this->queried_object_id) && $this->queried_object_id == get_option('page_for_posts') ) {
+ $this->is_page = false;
+ $this->is_home = true;
+ $this->is_posts_page = true;
+ }
+ }
+
+ if ( $qv['page_id'] ) {
+ if ( 'page' == get_option('show_on_front') && $qv['page_id'] == get_option('page_for_posts') ) {
+ $this->is_page = false;
+ $this->is_home = true;
+ $this->is_posts_page = true;
+ }
+ }
+
+ if ( !empty($qv['post_type']) ) {
+ if ( is_array($qv['post_type']) )
+ $qv['post_type'] = array_map('sanitize_key', $qv['post_type']);
+ else
+ $qv['post_type'] = sanitize_key($qv['post_type']);
+ }
+
+ if ( ! empty( $qv['post_status'] ) ) {
+ if ( is_array( $qv['post_status'] ) )
+ $qv['post_status'] = array_map('sanitize_key', $qv['post_status']);
+ else
+ $qv['post_status'] = preg_replace('|[^a-z0-9_,-]|', '', $qv['post_status']);
+ }
+
+ if ( $this->is_posts_page && ( ! isset($qv['withcomments']) || ! $qv['withcomments'] ) )
+ $this->is_comment_feed = false;
+
+ $this->is_singular = $this->is_single || $this->is_page || $this->is_attachment;
+ // Done correcting is_* for page_on_front and page_for_posts
+
+ if ( '404' == $qv['error'] )
+ $this->set_404();
+
+ $this->is_embed = $this->is_embed && ( $this->is_singular || $this->is_404 );
+
+ $this->query_vars_hash = md5( serialize( $this->query_vars ) );
+ $this->query_vars_changed = false;
+
+ /**
+ * Fires after the main query vars have been parsed.
+ *
+ * @since 1.5.0
+ *
+ * @param WP_Query &$this The WP_Query instance (passed by reference).
+ */
+ do_action_ref_array( 'parse_query', array( &$this ) );
+ }
+
+ /**
+ * Parses various taxonomy related query vars.
+ *
+ * For BC, this method is not marked as protected. See [28987].
+ *
+ * @access protected
+ * @since 3.1.0
+ *
+ * @param array $q The query variables. Passed by reference.
+ */
+ public function parse_tax_query( &$q ) {
+ if ( ! empty( $q['tax_query'] ) && is_array( $q['tax_query'] ) ) {
+ $tax_query = $q['tax_query'];
+ } else {
+ $tax_query = array();
+ }
+
+ if ( !empty($q['taxonomy']) && !empty($q['term']) ) {
+ $tax_query[] = array(
+ 'taxonomy' => $q['taxonomy'],
+ 'terms' => array( $q['term'] ),
+ 'field' => 'slug',
+ );
+ }
+
+ foreach ( get_taxonomies( array() , 'objects' ) as $taxonomy => $t ) {
+ if ( 'post_tag' == $taxonomy )
+ continue; // Handled further down in the $q['tag'] block
+
+ if ( $t->query_var && !empty( $q[$t->query_var] ) ) {
+ $tax_query_defaults = array(
+ 'taxonomy' => $taxonomy,
+ 'field' => 'slug',
+ );
+
+ if ( isset( $t->rewrite['hierarchical'] ) && $t->rewrite['hierarchical'] ) {
+ $q[$t->query_var] = wp_basename( $q[$t->query_var] );
+ }
+
+ $term = $q[$t->query_var];
+
+ if ( is_array( $term ) ) {
+ $term = implode( ',', $term );
+ }
+
+ if ( strpos($term, '+') !== false ) {
+ $terms = preg_split( '/[+]+/', $term );
+ foreach ( $terms as $term ) {
+ $tax_query[] = array_merge( $tax_query_defaults, array(
+ 'terms' => array( $term )
+ ) );
+ }
+ } else {
+ $tax_query[] = array_merge( $tax_query_defaults, array(
+ 'terms' => preg_split( '/[,]+/', $term )
+ ) );
+ }
+ }
+ }
+
+ // If querystring 'cat' is an array, implode it.
+ if ( is_array( $q['cat'] ) ) {
+ $q['cat'] = implode( ',', $q['cat'] );
+ }
+
+ // Category stuff
+ if ( ! empty( $q['cat'] ) && ! $this->is_singular ) {
+ $cat_in = $cat_not_in = array();
+
+ $cat_array = preg_split( '/[,\s]+/', urldecode( $q['cat'] ) );
+ $cat_array = array_map( 'intval', $cat_array );
+ $q['cat'] = implode( ',', $cat_array );
+
+ foreach ( $cat_array as $cat ) {
+ if ( $cat > 0 )
+ $cat_in[] = $cat;
+ elseif ( $cat < 0 )
+ $cat_not_in[] = abs( $cat );
+ }
+
+ if ( ! empty( $cat_in ) ) {
+ $tax_query[] = array(
+ 'taxonomy' => 'category',
+ 'terms' => $cat_in,
+ 'field' => 'term_id',
+ 'include_children' => true
+ );
+ }
+
+ if ( ! empty( $cat_not_in ) ) {
+ $tax_query[] = array(
+ 'taxonomy' => 'category',
+ 'terms' => $cat_not_in,
+ 'field' => 'term_id',
+ 'operator' => 'NOT IN',
+ 'include_children' => true
+ );
+ }
+ unset( $cat_array, $cat_in, $cat_not_in );
+ }
+
+ if ( ! empty( $q['category__and'] ) && 1 === count( (array) $q['category__and'] ) ) {
+ $q['category__and'] = (array) $q['category__and'];
+ if ( ! isset( $q['category__in'] ) )
+ $q['category__in'] = array();
+ $q['category__in'][] = absint( reset( $q['category__and'] ) );
+ unset( $q['category__and'] );
+ }
+
+ if ( ! empty( $q['category__in'] ) ) {
+ $q['category__in'] = array_map( 'absint', array_unique( (array) $q['category__in'] ) );
+ $tax_query[] = array(
+ 'taxonomy' => 'category',
+ 'terms' => $q['category__in'],
+ 'field' => 'term_id',
+ 'include_children' => false
+ );
+ }
+
+ if ( ! empty($q['category__not_in']) ) {
+ $q['category__not_in'] = array_map( 'absint', array_unique( (array) $q['category__not_in'] ) );
+ $tax_query[] = array(
+ 'taxonomy' => 'category',
+ 'terms' => $q['category__not_in'],
+ 'operator' => 'NOT IN',
+ 'include_children' => false
+ );
+ }
+
+ if ( ! empty($q['category__and']) ) {
+ $q['category__and'] = array_map( 'absint', array_unique( (array) $q['category__and'] ) );
+ $tax_query[] = array(
+ 'taxonomy' => 'category',
+ 'terms' => $q['category__and'],
+ 'field' => 'term_id',
+ 'operator' => 'AND',
+ 'include_children' => false
+ );
+ }
+
+ // If querystring 'tag' is array, implode it.
+ if ( is_array( $q['tag'] ) ) {
+ $q['tag'] = implode( ',', $q['tag'] );
+ }
+
+ // Tag stuff
+ if ( '' != $q['tag'] && !$this->is_singular && $this->query_vars_changed ) {
+ if ( strpos($q['tag'], ',') !== false ) {
+ $tags = preg_split('/[,\r\n\t ]+/', $q['tag']);
+ foreach ( (array) $tags as $tag ) {
+ $tag = sanitize_term_field('slug', $tag, 0, 'post_tag', 'db');
+ $q['tag_slug__in'][] = $tag;
+ }
+ } elseif ( preg_match('/[+\r\n\t ]+/', $q['tag'] ) || ! empty( $q['cat'] ) ) {
+ $tags = preg_split('/[+\r\n\t ]+/', $q['tag']);
+ foreach ( (array) $tags as $tag ) {
+ $tag = sanitize_term_field('slug', $tag, 0, 'post_tag', 'db');
+ $q['tag_slug__and'][] = $tag;
+ }
+ } else {
+ $q['tag'] = sanitize_term_field('slug', $q['tag'], 0, 'post_tag', 'db');
+ $q['tag_slug__in'][] = $q['tag'];
+ }
+ }
+
+ if ( !empty($q['tag_id']) ) {
+ $q['tag_id'] = absint( $q['tag_id'] );
+ $tax_query[] = array(
+ 'taxonomy' => 'post_tag',
+ 'terms' => $q['tag_id']
+ );
+ }
+
+ if ( !empty($q['tag__in']) ) {
+ $q['tag__in'] = array_map('absint', array_unique( (array) $q['tag__in'] ) );
+ $tax_query[] = array(
+ 'taxonomy' => 'post_tag',
+ 'terms' => $q['tag__in']
+ );
+ }
+
+ if ( !empty($q['tag__not_in']) ) {
+ $q['tag__not_in'] = array_map('absint', array_unique( (array) $q['tag__not_in'] ) );
+ $tax_query[] = array(
+ 'taxonomy' => 'post_tag',
+ 'terms' => $q['tag__not_in'],
+ 'operator' => 'NOT IN'
+ );
+ }
+
+ if ( !empty($q['tag__and']) ) {
+ $q['tag__and'] = array_map('absint', array_unique( (array) $q['tag__and'] ) );
+ $tax_query[] = array(
+ 'taxonomy' => 'post_tag',
+ 'terms' => $q['tag__and'],
+ 'operator' => 'AND'
+ );
+ }
+
+ if ( !empty($q['tag_slug__in']) ) {
+ $q['tag_slug__in'] = array_map('sanitize_title_for_query', array_unique( (array) $q['tag_slug__in'] ) );
+ $tax_query[] = array(
+ 'taxonomy' => 'post_tag',
+ 'terms' => $q['tag_slug__in'],
+ 'field' => 'slug'
+ );
+ }
+
+ if ( !empty($q['tag_slug__and']) ) {
+ $q['tag_slug__and'] = array_map('sanitize_title_for_query', array_unique( (array) $q['tag_slug__and'] ) );
+ $tax_query[] = array(
+ 'taxonomy' => 'post_tag',
+ 'terms' => $q['tag_slug__and'],
+ 'field' => 'slug',
+ 'operator' => 'AND'
+ );
+ }
+
+ $this->tax_query = new WP_Tax_Query( $tax_query );
+
+ /**
+ * Fires after taxonomy-related query vars have been parsed.
+ *
+ * @since 3.7.0
+ *
+ * @param WP_Query $this The WP_Query instance.
+ */
+ do_action( 'parse_tax_query', $this );
+ }
+
+ /**
+ * Generate SQL for the WHERE clause based on passed search terms.
+ *
+ * @since 3.7.0
+ *
+ * @param array $q Query variables.
+ * @return string WHERE clause.
+ */
+ protected function parse_search( &$q ) {
+ global $wpdb;
+
+ $search = '';
+
+ // added slashes screw with quote grouping when done early, so done later
+ $q['s'] = stripslashes( $q['s'] );
+ if ( empty( $_GET['s'] ) && $this->is_main_query() )
+ $q['s'] = urldecode( $q['s'] );
+ // there are no line breaks in fields
+ $q['s'] = str_replace( array( "\r", "\n" ), '', $q['s'] );
+ $q['search_terms_count'] = 1;
+ if ( ! empty( $q['sentence'] ) ) {
+ $q['search_terms'] = array( $q['s'] );
+ } else {
+ if ( preg_match_all( '/".*?("|$)|((?<=[\t ",+])|^)[^\t ",+]+/', $q['s'], $matches ) ) {
+ $q['search_terms_count'] = count( $matches[0] );
+ $q['search_terms'] = $this->parse_search_terms( $matches[0] );
+ // if the search string has only short terms or stopwords, or is 10+ terms long, match it as sentence
+ if ( empty( $q['search_terms'] ) || count( $q['search_terms'] ) > 9 )
+ $q['search_terms'] = array( $q['s'] );
+ } else {
+ $q['search_terms'] = array( $q['s'] );
+ }
+ }
+
+ $n = ! empty( $q['exact'] ) ? '' : '%';
+ $searchand = '';
+ $q['search_orderby_title'] = array();
+
+ /**
+ * Filters the prefix that indicates that a search term should be excluded from results.
+ *
+ * @since 4.7.0
+ *
+ * @param string $exclusion_prefix The prefix. Default '-'. Returning
+ * an empty value disables exclusions.
+ */
+ $exclusion_prefix = apply_filters( 'wp_query_search_exclusion_prefix', '-' );
+
+ foreach ( $q['search_terms'] as $term ) {
+ // If there is an $exclusion_prefix, terms prefixed with it should be excluded.
+ $exclude = $exclusion_prefix && ( $exclusion_prefix === substr( $term, 0, 1 ) );
+ if ( $exclude ) {
+ $like_op = 'NOT LIKE';
+ $andor_op = 'AND';
+ $term = substr( $term, 1 );
+ } else {
+ $like_op = 'LIKE';
+ $andor_op = 'OR';
+ }
+
+ if ( $n && ! $exclude ) {
+ $like = '%' . $wpdb->esc_like( $term ) . '%';
+ $q['search_orderby_title'][] = $wpdb->prepare( "{$wpdb->posts}.post_title LIKE %s", $like );
+ }
+
+ $like = $n . $wpdb->esc_like( $term ) . $n;
+ $search .= $wpdb->prepare( "{$searchand}(({$wpdb->posts}.post_title $like_op %s) $andor_op ({$wpdb->posts}.post_excerpt $like_op %s) $andor_op ({$wpdb->posts}.post_content $like_op %s))", $like, $like, $like );
+ $searchand = ' AND ';
+ }
+
+ if ( ! empty( $search ) ) {
+ $search = " AND ({$search}) ";
+ if ( ! is_user_logged_in() ) {
+ $search .= " AND ({$wpdb->posts}.post_password = '') ";
+ }
+ }
+
+ return $search;
+ }
+
+ /**
+ * Check if the terms are suitable for searching.
+ *
+ * Uses an array of stopwords (terms) that are excluded from the separate
+ * term matching when searching for posts. The list of English stopwords is
+ * the approximate search engines list, and is translatable.
+ *
+ * @since 3.7.0
+ *
+ * @param array $terms Terms to check.
+ * @return array Terms that are not stopwords.
+ */
+ protected function parse_search_terms( $terms ) {
+ $strtolower = function_exists( 'mb_strtolower' ) ? 'mb_strtolower' : 'strtolower';
+ $checked = array();
+
+ $stopwords = $this->get_search_stopwords();
+
+ foreach ( $terms as $term ) {
+ // keep before/after spaces when term is for exact match
+ if ( preg_match( '/^".+"$/', $term ) )
+ $term = trim( $term, "\"'" );
+ else
+ $term = trim( $term, "\"' " );
+
+ // Avoid single A-Z and single dashes.
+ if ( ! $term || ( 1 === strlen( $term ) && preg_match( '/^[a-z\-]$/i', $term ) ) )
+ continue;
+
+ if ( in_array( call_user_func( $strtolower, $term ), $stopwords, true ) )
+ continue;
+
+ $checked[] = $term;
+ }
+
+ return $checked;
+ }
+
+ /**
+ * Retrieve stopwords used when parsing search terms.
+ *
+ * @since 3.7.0
+ *
+ * @return array Stopwords.
+ */
+ protected function get_search_stopwords() {
+ if ( isset( $this->stopwords ) )
+ return $this->stopwords;
+
+ /* translators: This is a comma-separated list of very common words that should be excluded from a search,
+ * like a, an, and the. These are usually called "stopwords". You should not simply translate these individual
+ * words into your language. Instead, look for and provide commonly accepted stopwords in your language.
+ */
+ $words = explode( ',', _x( 'about,an,are,as,at,be,by,com,for,from,how,in,is,it,of,on,or,that,the,this,to,was,what,when,where,who,will,with,www',
+ 'Comma-separated list of search stopwords in your language' ) );
+
+ $stopwords = array();
+ foreach ( $words as $word ) {
+ $word = trim( $word, "\r\n\t " );
+ if ( $word )
+ $stopwords[] = $word;
+ }
+
+ /**
+ * Filters stopwords used when parsing search terms.
+ *
+ * @since 3.7.0
+ *
+ * @param array $stopwords Stopwords.
+ */
+ $this->stopwords = apply_filters( 'wp_search_stopwords', $stopwords );
+ return $this->stopwords;
+ }
+
+ /**
+ * Generate SQL for the ORDER BY condition based on passed search terms.
+ *
+ * @param array $q Query variables.
+ * @return string ORDER BY clause.
+ */
+ protected function parse_search_order( &$q ) {
+ global $wpdb;
+
+ if ( $q['search_terms_count'] > 1 ) {
+ $num_terms = count( $q['search_orderby_title'] );
+
+ // If the search terms contain negative queries, don't bother ordering by sentence matches.
+ $like = '';
+ if ( ! preg_match( '/(?:\s|^)\-/', $q['s'] ) ) {
+ $like = '%' . $wpdb->esc_like( $q['s'] ) . '%';
+ }
+
+ $search_orderby = '';
+
+ // sentence match in 'post_title'
+ if ( $like ) {
+ $search_orderby .= $wpdb->prepare( "WHEN {$wpdb->posts}.post_title LIKE %s THEN 1 ", $like );
+ }
+
+ // sanity limit, sort as sentence when more than 6 terms
+ // (few searches are longer than 6 terms and most titles are not)
+ if ( $num_terms < 7 ) {
+ // all words in title
+ $search_orderby .= 'WHEN ' . implode( ' AND ', $q['search_orderby_title'] ) . ' THEN 2 ';
+ // any word in title, not needed when $num_terms == 1
+ if ( $num_terms > 1 )
+ $search_orderby .= 'WHEN ' . implode( ' OR ', $q['search_orderby_title'] ) . ' THEN 3 ';
+ }
+
+ // Sentence match in 'post_content' and 'post_excerpt'.
+ if ( $like ) {
+ $search_orderby .= $wpdb->prepare( "WHEN {$wpdb->posts}.post_excerpt LIKE %s THEN 4 ", $like );
+ $search_orderby .= $wpdb->prepare( "WHEN {$wpdb->posts}.post_content LIKE %s THEN 5 ", $like );
+ }
+
+ if ( $search_orderby ) {
+ $search_orderby = '(CASE ' . $search_orderby . 'ELSE 6 END)';
+ }
+ } else {
+ // single word or sentence search
+ $search_orderby = reset( $q['search_orderby_title'] ) . ' DESC';
+ }
+
+ return $search_orderby;
+ }
+
+ /**
+ * If the passed orderby value is allowed, convert the alias to a
+ * properly-prefixed orderby value.
+ *
+ * @since 4.0.0
+ * @access protected
+ *
+ * @param string $orderby Alias for the field to order by.
+ * @return string|false Table-prefixed value to used in the ORDER clause. False otherwise.
+ */
+ protected function parse_orderby( $orderby ) {
+ global $wpdb;
+
+ // Used to filter values.
+ $allowed_keys = array(
+ 'post_name', 'post_author', 'post_date', 'post_title', 'post_modified',
+ 'post_parent', 'post_type', 'name', 'author', 'date', 'title', 'modified',
+ 'parent', 'type', 'ID', 'menu_order', 'comment_count', 'rand',
+ );
+
+ $primary_meta_key = '';
+ $primary_meta_query = false;
+ $meta_clauses = $this->meta_query->get_clauses();
+ if ( ! empty( $meta_clauses ) ) {
+ $primary_meta_query = reset( $meta_clauses );
+
+ if ( ! empty( $primary_meta_query['key'] ) ) {
+ $primary_meta_key = $primary_meta_query['key'];
+ $allowed_keys[] = $primary_meta_key;
+ }
+
+ $allowed_keys[] = 'meta_value';
+ $allowed_keys[] = 'meta_value_num';
+ $allowed_keys = array_merge( $allowed_keys, array_keys( $meta_clauses ) );
+ }
+
+ // If RAND() contains a seed value, sanitize and add to allowed keys.
+ $rand_with_seed = false;
+ if ( preg_match( '/RAND\(([0-9]+)\)/i', $orderby, $matches ) ) {
+ $orderby = sprintf( 'RAND(%s)', intval( $matches[1] ) );
+ $allowed_keys[] = $orderby;
+ $rand_with_seed = true;
+ }
+
+ if ( ! in_array( $orderby, $allowed_keys, true ) ) {
+ return false;
+ }
+
+ switch ( $orderby ) {
+ case 'post_name':
+ case 'post_author':
+ case 'post_date':
+ case 'post_title':
+ case 'post_modified':
+ case 'post_parent':
+ case 'post_type':
+ case 'ID':
+ case 'menu_order':
+ case 'comment_count':
+ $orderby_clause = "{$wpdb->posts}.{$orderby}";
+ break;
+ case 'rand':
+ $orderby_clause = 'RAND()';
+ break;
+ case $primary_meta_key:
+ case 'meta_value':
+ if ( ! empty( $primary_meta_query['type'] ) ) {
+ $orderby_clause = "CAST({$primary_meta_query['alias']}.meta_value AS {$primary_meta_query['cast']})";
+ } else {
+ $orderby_clause = "{$primary_meta_query['alias']}.meta_value";
+ }
+ break;
+ case 'meta_value_num':
+ $orderby_clause = "{$primary_meta_query['alias']}.meta_value+0";
+ break;
+ default:
+ if ( array_key_exists( $orderby, $meta_clauses ) ) {
+ // $orderby corresponds to a meta_query clause.
+ $meta_clause = $meta_clauses[ $orderby ];
+ $orderby_clause = "CAST({$meta_clause['alias']}.meta_value AS {$meta_clause['cast']})";
+ } elseif ( $rand_with_seed ) {
+ $orderby_clause = $orderby;
+ } else {
+ // Default: order by post field.
+ $orderby_clause = "{$wpdb->posts}.post_" . sanitize_key( $orderby );
+ }
+
+ break;
+ }
+
+ return $orderby_clause;
+ }
+
+ /**
+ * Parse an 'order' query variable and cast it to ASC or DESC as necessary.
+ *
+ * @since 4.0.0
+ * @access protected
+ *
+ * @param string $order The 'order' query variable.
+ * @return string The sanitized 'order' query variable.
+ */
+ protected function parse_order( $order ) {
+ if ( ! is_string( $order ) || empty( $order ) ) {
+ return 'DESC';
+ }
+
+ if ( 'ASC' === strtoupper( $order ) ) {
+ return 'ASC';
+ } else {
+ return 'DESC';
+ }
+ }
+
+ /**
+ * Sets the 404 property and saves whether query is feed.
+ *
+ * @since 2.0.0
+ * @access public
+ */
+ public function set_404() {
+ $is_feed = $this->is_feed;
+
+ $this->init_query_flags();
+ $this->is_404 = true;
+
+ $this->is_feed = $is_feed;
+ }
+
+ /**
+ * Retrieve query variable.
+ *
+ * @since 1.5.0
+ * @since 3.9.0 The `$default` argument was introduced.
+ *
+ * @access public
+ *
+ * @param string $query_var Query variable key.
+ * @param mixed $default Optional. Value to return if the query variable is not set. Default empty.
+ * @return mixed Contents of the query variable.
+ */
+ public function get( $query_var, $default = '' ) {
+ if ( isset( $this->query_vars[ $query_var ] ) ) {
+ return $this->query_vars[ $query_var ];
+ }
+
+ return $default;
+ }
+
+ /**
+ * Set query variable.
+ *
+ * @since 1.5.0
+ * @access public
+ *
+ * @param string $query_var Query variable key.
+ * @param mixed $value Query variable value.
+ */
+ public function set($query_var, $value) {
+ $this->query_vars[$query_var] = $value;
+ }
+
+ /**
+ * Retrieve the posts based on query variables.
+ *
+ * There are a few filters and actions that can be used to modify the post
+ * database query.
+ *
+ * @since 1.5.0
+ * @access public
+ *
+ * @return array List of posts.
+ */
+ public function get_posts() {
+ global $wpdb;
+
+ $this->parse_query();
+
+ /**
+ * Fires after the query variable object is created, but before the actual query is run.
+ *
+ * Note: If using conditional tags, use the method versions within the passed instance
+ * (e.g. $this->is_main_query() instead of is_main_query()). This is because the functions
+ * like is_main_query() test against the global $wp_query instance, not the passed one.
+ *
+ * @since 2.0.0
+ *
+ * @param WP_Query &$this The WP_Query instance (passed by reference).
+ */
+ do_action_ref_array( 'pre_get_posts', array( &$this ) );
+
+ // Shorthand.
+ $q = &$this->query_vars;
+
+ // Fill again in case pre_get_posts unset some vars.
+ $q = $this->fill_query_vars($q);
+
+ // Parse meta query
+ $this->meta_query = new WP_Meta_Query();
+ $this->meta_query->parse_query_vars( $q );
+
+ // Set a flag if a pre_get_posts hook changed the query vars.
+ $hash = md5( serialize( $this->query_vars ) );
+ if ( $hash != $this->query_vars_hash ) {
+ $this->query_vars_changed = true;
+ $this->query_vars_hash = $hash;
+ }
+ unset($hash);
+
+ // First let's clear some variables
+ $distinct = '';
+ $whichauthor = '';
+ $whichmimetype = '';
+ $where = '';
+ $limits = '';
+ $join = '';
+ $search = '';
+ $groupby = '';
+ $post_status_join = false;
+ $page = 1;
+
+ if ( isset( $q['caller_get_posts'] ) ) {
+ _deprecated_argument( 'WP_Query', '3.1.0', __( '"caller_get_posts" is deprecated. Use "ignore_sticky_posts" instead.' ) );
+ if ( !isset( $q['ignore_sticky_posts'] ) )
+ $q['ignore_sticky_posts'] = $q['caller_get_posts'];
+ }
+
+ if ( !isset( $q['ignore_sticky_posts'] ) )
+ $q['ignore_sticky_posts'] = false;
+
+ if ( !isset($q['suppress_filters']) )
+ $q['suppress_filters'] = false;
+
+ if ( !isset($q['cache_results']) ) {
+ if ( wp_using_ext_object_cache() )
+ $q['cache_results'] = false;
+ else
+ $q['cache_results'] = true;
+ }
+
+ if ( !isset($q['update_post_term_cache']) )
+ $q['update_post_term_cache'] = true;
+
+ if ( ! isset( $q['lazy_load_term_meta'] ) ) {
+ $q['lazy_load_term_meta'] = $q['update_post_term_cache'];
+ }
+
+ if ( !isset($q['update_post_meta_cache']) )
+ $q['update_post_meta_cache'] = true;
+
+ if ( !isset($q['post_type']) ) {
+ if ( $this->is_search )
+ $q['post_type'] = 'any';
+ else
+ $q['post_type'] = '';
+ }
+ $post_type = $q['post_type'];
+ if ( empty( $q['posts_per_page'] ) ) {
+ $q['posts_per_page'] = get_option( 'posts_per_page' );
+ }
+ if ( isset($q['showposts']) && $q['showposts'] ) {
+ $q['showposts'] = (int) $q['showposts'];
+ $q['posts_per_page'] = $q['showposts'];
+ }
+ if ( (isset($q['posts_per_archive_page']) && $q['posts_per_archive_page'] != 0) && ($this->is_archive || $this->is_search) )
+ $q['posts_per_page'] = $q['posts_per_archive_page'];
+ if ( !isset($q['nopaging']) ) {
+ if ( $q['posts_per_page'] == -1 ) {
+ $q['nopaging'] = true;
+ } else {
+ $q['nopaging'] = false;
+ }
+ }
+
+ if ( $this->is_feed ) {
+ // This overrides posts_per_page.
+ if ( ! empty( $q['posts_per_rss'] ) ) {
+ $q['posts_per_page'] = $q['posts_per_rss'];
+ } else {
+ $q['posts_per_page'] = get_option( 'posts_per_rss' );
+ }
+ $q['nopaging'] = false;
+ }
+ $q['posts_per_page'] = (int) $q['posts_per_page'];
+ if ( $q['posts_per_page'] < -1 )
+ $q['posts_per_page'] = abs($q['posts_per_page']);
+ elseif ( $q['posts_per_page'] == 0 )
+ $q['posts_per_page'] = 1;
+
+ if ( !isset($q['comments_per_page']) || $q['comments_per_page'] == 0 )
+ $q['comments_per_page'] = get_option('comments_per_page');
+
+ if ( $this->is_home && (empty($this->query) || $q['preview'] == 'true') && ( 'page' == get_option('show_on_front') ) && get_option('page_on_front') ) {
+ $this->is_page = true;
+ $this->is_home = false;
+ $q['page_id'] = get_option('page_on_front');
+ }
+
+ if ( isset($q['page']) ) {
+ $q['page'] = trim($q['page'], '/');
+ $q['page'] = absint($q['page']);
+ }
+
+ // If true, forcibly turns off SQL_CALC_FOUND_ROWS even when limits are present.
+ if ( isset($q['no_found_rows']) )
+ $q['no_found_rows'] = (bool) $q['no_found_rows'];
+ else
+ $q['no_found_rows'] = false;
+
+ switch ( $q['fields'] ) {
+ case 'ids':
+ $fields = "{$wpdb->posts}.ID";
+ break;
+ case 'id=>parent':
+ $fields = "{$wpdb->posts}.ID, {$wpdb->posts}.post_parent";
+ break;
+ default:
+ $fields = "{$wpdb->posts}.*";
+ }
+
+ if ( '' !== $q['menu_order'] ) {
+ $where .= " AND {$wpdb->posts}.menu_order = " . $q['menu_order'];
+ }
+ // The "m" parameter is meant for months but accepts datetimes of varying specificity
+ if ( $q['m'] ) {
+ $where .= " AND YEAR({$wpdb->posts}.post_date)=" . substr($q['m'], 0, 4);
+ if ( strlen($q['m']) > 5 ) {
+ $where .= " AND MONTH({$wpdb->posts}.post_date)=" . substr($q['m'], 4, 2);
+ }
+ if ( strlen($q['m']) > 7 ) {
+ $where .= " AND DAYOFMONTH({$wpdb->posts}.post_date)=" . substr($q['m'], 6, 2);
+ }
+ if ( strlen($q['m']) > 9 ) {
+ $where .= " AND HOUR({$wpdb->posts}.post_date)=" . substr($q['m'], 8, 2);
+ }
+ if ( strlen($q['m']) > 11 ) {
+ $where .= " AND MINUTE({$wpdb->posts}.post_date)=" . substr($q['m'], 10, 2);
+ }
+ if ( strlen($q['m']) > 13 ) {
+ $where .= " AND SECOND({$wpdb->posts}.post_date)=" . substr($q['m'], 12, 2);
+ }
+ }
+
+ // Handle the other individual date parameters
+ $date_parameters = array();
+
+ if ( '' !== $q['hour'] )
+ $date_parameters['hour'] = $q['hour'];
+
+ if ( '' !== $q['minute'] )
+ $date_parameters['minute'] = $q['minute'];
+
+ if ( '' !== $q['second'] )
+ $date_parameters['second'] = $q['second'];
+
+ if ( $q['year'] )
+ $date_parameters['year'] = $q['year'];
+
+ if ( $q['monthnum'] )
+ $date_parameters['monthnum'] = $q['monthnum'];
+
+ if ( $q['w'] )
+ $date_parameters['week'] = $q['w'];
+
+ if ( $q['day'] )
+ $date_parameters['day'] = $q['day'];
+
+ if ( $date_parameters ) {
+ $date_query = new WP_Date_Query( array( $date_parameters ) );
+ $where .= $date_query->get_sql();
+ }
+ unset( $date_parameters, $date_query );
+
+ // Handle complex date queries
+ if ( ! empty( $q['date_query'] ) ) {
+ $this->date_query = new WP_Date_Query( $q['date_query'] );
+ $where .= $this->date_query->get_sql();
+ }
+
+
+ // If we've got a post_type AND it's not "any" post_type.
+ if ( !empty($q['post_type']) && 'any' != $q['post_type'] ) {
+ foreach ( (array)$q['post_type'] as $_post_type ) {
+ $ptype_obj = get_post_type_object($_post_type);
+ if ( !$ptype_obj || !$ptype_obj->query_var || empty($q[ $ptype_obj->query_var ]) )
+ continue;
+
+ if ( ! $ptype_obj->hierarchical ) {
+ // Non-hierarchical post types can directly use 'name'.
+ $q['name'] = $q[ $ptype_obj->query_var ];
+ } else {
+ // Hierarchical post types will operate through 'pagename'.
+ $q['pagename'] = $q[ $ptype_obj->query_var ];
+ $q['name'] = '';
+ }
+
+ // Only one request for a slug is possible, this is why name & pagename are overwritten above.
+ break;
+ } //end foreach
+ unset($ptype_obj);
+ }
+
+ if ( '' !== $q['title'] ) {
+ $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_title = %s", stripslashes( $q['title'] ) );
+ }
+
+ // Parameters related to 'post_name'.
+ if ( '' != $q['name'] ) {
+ $q['name'] = sanitize_title_for_query( $q['name'] );
+ $where .= " AND {$wpdb->posts}.post_name = '" . $q['name'] . "'";
+ } elseif ( '' != $q['pagename'] ) {
+ if ( isset($this->queried_object_id) ) {
+ $reqpage = $this->queried_object_id;
+ } else {
+ if ( 'page' != $q['post_type'] ) {
+ foreach ( (array)$q['post_type'] as $_post_type ) {
+ $ptype_obj = get_post_type_object($_post_type);
+ if ( !$ptype_obj || !$ptype_obj->hierarchical )
+ continue;
+
+ $reqpage = get_page_by_path($q['pagename'], OBJECT, $_post_type);
+ if ( $reqpage )
+ break;
+ }
+ unset($ptype_obj);
+ } else {
+ $reqpage = get_page_by_path($q['pagename']);
+ }
+ if ( !empty($reqpage) )
+ $reqpage = $reqpage->ID;
+ else
+ $reqpage = 0;
+ }
+
+ $page_for_posts = get_option('page_for_posts');
+ if ( ('page' != get_option('show_on_front') ) || empty($page_for_posts) || ( $reqpage != $page_for_posts ) ) {
+ $q['pagename'] = sanitize_title_for_query( wp_basename( $q['pagename'] ) );
+ $q['name'] = $q['pagename'];
+ $where .= " AND ({$wpdb->posts}.ID = '$reqpage')";
+ $reqpage_obj = get_post( $reqpage );
+ if ( is_object($reqpage_obj) && 'attachment' == $reqpage_obj->post_type ) {
+ $this->is_attachment = true;
+ $post_type = $q['post_type'] = 'attachment';
+ $this->is_page = true;
+ $q['attachment_id'] = $reqpage;
+ }
+ }
+ } elseif ( '' != $q['attachment'] ) {
+ $q['attachment'] = sanitize_title_for_query( wp_basename( $q['attachment'] ) );
+ $q['name'] = $q['attachment'];
+ $where .= " AND {$wpdb->posts}.post_name = '" . $q['attachment'] . "'";
+ } elseif ( is_array( $q['post_name__in'] ) && ! empty( $q['post_name__in'] ) ) {
+ $q['post_name__in'] = array_map( 'sanitize_title_for_query', $q['post_name__in'] );
+ $post_name__in = "'" . implode( "','", $q['post_name__in'] ) . "'";
+ $where .= " AND {$wpdb->posts}.post_name IN ($post_name__in)";
+ }
+
+ // If an attachment is requested by number, let it supersede any post number.
+ if ( $q['attachment_id'] )
+ $q['p'] = absint($q['attachment_id']);
+
+ // If a post number is specified, load that post
+ if ( $q['p'] ) {
+ $where .= " AND {$wpdb->posts}.ID = " . $q['p'];
+ } elseif ( $q['post__in'] ) {
+ $post__in = implode(',', array_map( 'absint', $q['post__in'] ));
+ $where .= " AND {$wpdb->posts}.ID IN ($post__in)";
+ } elseif ( $q['post__not_in'] ) {
+ $post__not_in = implode(',', array_map( 'absint', $q['post__not_in'] ));
+ $where .= " AND {$wpdb->posts}.ID NOT IN ($post__not_in)";
+ }
+
+ if ( is_numeric( $q['post_parent'] ) ) {
+ $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_parent = %d ", $q['post_parent'] );
+ } elseif ( $q['post_parent__in'] ) {
+ $post_parent__in = implode( ',', array_map( 'absint', $q['post_parent__in'] ) );
+ $where .= " AND {$wpdb->posts}.post_parent IN ($post_parent__in)";
+ } elseif ( $q['post_parent__not_in'] ) {
+ $post_parent__not_in = implode( ',', array_map( 'absint', $q['post_parent__not_in'] ) );
+ $where .= " AND {$wpdb->posts}.post_parent NOT IN ($post_parent__not_in)";
+ }
+
+ if ( $q['page_id'] ) {
+ if ( ('page' != get_option('show_on_front') ) || ( $q['page_id'] != get_option('page_for_posts') ) ) {
+ $q['p'] = $q['page_id'];
+ $where = " AND {$wpdb->posts}.ID = " . $q['page_id'];
+ }
+ }
+
+ // If a search pattern is specified, load the posts that match.
+ if ( strlen( $q['s'] ) ) {
+ $search = $this->parse_search( $q );
+ }
+
+ if ( ! $q['suppress_filters'] ) {
+ /**
+ * Filters the search SQL that is used in the WHERE clause of WP_Query.
+ *
+ * @since 3.0.0
+ *
+ * @param string $search Search SQL for WHERE clause.
+ * @param WP_Query $this The current WP_Query object.
+ */
+ $search = apply_filters_ref_array( 'posts_search', array( $search, &$this ) );
+ }
+
+ // Taxonomies
+ if ( !$this->is_singular ) {
+ $this->parse_tax_query( $q );
+
+ $clauses = $this->tax_query->get_sql( $wpdb->posts, 'ID' );
+
+ $join .= $clauses['join'];
+ $where .= $clauses['where'];
+ }
+
+ if ( $this->is_tax ) {
+ if ( empty($post_type) ) {
+ // Do a fully inclusive search for currently registered post types of queried taxonomies
+ $post_type = array();
+ $taxonomies = array_keys( $this->tax_query->queried_terms );
+ foreach ( get_post_types( array( 'exclude_from_search' => false ) ) as $pt ) {
+ $object_taxonomies = $pt === 'attachment' ? get_taxonomies_for_attachments() : get_object_taxonomies( $pt );
+ if ( array_intersect( $taxonomies, $object_taxonomies ) )
+ $post_type[] = $pt;
+ }
+ if ( ! $post_type )
+ $post_type = 'any';
+ elseif ( count( $post_type ) == 1 )
+ $post_type = $post_type[0];
+
+ $post_status_join = true;
+ } elseif ( in_array('attachment', (array) $post_type) ) {
+ $post_status_join = true;
+ }
+ }
+
+ /*
+ * Ensure that 'taxonomy', 'term', 'term_id', 'cat', and
+ * 'category_name' vars are set for backward compatibility.
+ */
+ if ( ! empty( $this->tax_query->queried_terms ) ) {
+
+ /*
+ * Set 'taxonomy', 'term', and 'term_id' to the
+ * first taxonomy other than 'post_tag' or 'category'.
+ */
+ if ( ! isset( $q['taxonomy'] ) ) {
+ foreach ( $this->tax_query->queried_terms as $queried_taxonomy => $queried_items ) {
+ if ( empty( $queried_items['terms'][0] ) ) {
+ continue;
+ }
+
+ if ( ! in_array( $queried_taxonomy, array( 'category', 'post_tag' ) ) ) {
+ $q['taxonomy'] = $queried_taxonomy;
+
+ if ( 'slug' === $queried_items['field'] ) {
+ $q['term'] = $queried_items['terms'][0];
+ } else {
+ $q['term_id'] = $queried_items['terms'][0];
+ }
+
+ // Take the first one we find.
+ break;
+ }
+ }
+ }
+
+ // 'cat', 'category_name', 'tag_id'
+ foreach ( $this->tax_query->queried_terms as $queried_taxonomy => $queried_items ) {
+ if ( empty( $queried_items['terms'][0] ) ) {
+ continue;
+ }
+
+ if ( 'category' === $queried_taxonomy ) {
+ $the_cat = get_term_by( $queried_items['field'], $queried_items['terms'][0], 'category' );
+ if ( $the_cat ) {
+ $this->set( 'cat', $the_cat->term_id );
+ $this->set( 'category_name', $the_cat->slug );
+ }
+ unset( $the_cat );
+ }
+
+ if ( 'post_tag' === $queried_taxonomy ) {
+ $the_tag = get_term_by( $queried_items['field'], $queried_items['terms'][0], 'post_tag' );
+ if ( $the_tag ) {
+ $this->set( 'tag_id', $the_tag->term_id );
+ }
+ unset( $the_tag );
+ }
+ }
+ }
+
+ if ( !empty( $this->tax_query->queries ) || !empty( $this->meta_query->queries ) ) {
+ $groupby = "{$wpdb->posts}.ID";
+ }
+
+ // Author/user stuff
+
+ if ( ! empty( $q['author'] ) && $q['author'] != '0' ) {
+ $q['author'] = addslashes_gpc( '' . urldecode( $q['author'] ) );
+ $authors = array_unique( array_map( 'intval', preg_split( '/[,\s]+/', $q['author'] ) ) );
+ foreach ( $authors as $author ) {
+ $key = $author > 0 ? 'author__in' : 'author__not_in';
+ $q[$key][] = abs( $author );
+ }
+ $q['author'] = implode( ',', $authors );
+ }
+
+ if ( ! empty( $q['author__not_in'] ) ) {
+ $author__not_in = implode( ',', array_map( 'absint', array_unique( (array) $q['author__not_in'] ) ) );
+ $where .= " AND {$wpdb->posts}.post_author NOT IN ($author__not_in) ";
+ } elseif ( ! empty( $q['author__in'] ) ) {
+ $author__in = implode( ',', array_map( 'absint', array_unique( (array) $q['author__in'] ) ) );
+ $where .= " AND {$wpdb->posts}.post_author IN ($author__in) ";
+ }
+
+ // Author stuff for nice URLs
+
+ if ( '' != $q['author_name'] ) {
+ if ( strpos($q['author_name'], '/') !== false ) {
+ $q['author_name'] = explode('/', $q['author_name']);
+ if ( $q['author_name'][ count($q['author_name'])-1 ] ) {
+ $q['author_name'] = $q['author_name'][count($q['author_name'])-1]; // no trailing slash
+ } else {
+ $q['author_name'] = $q['author_name'][count($q['author_name'])-2]; // there was a trailing slash
+ }
+ }
+ $q['author_name'] = sanitize_title_for_query( $q['author_name'] );
+ $q['author'] = get_user_by('slug', $q['author_name']);
+ if ( $q['author'] )
+ $q['author'] = $q['author']->ID;
+ $whichauthor .= " AND ({$wpdb->posts}.post_author = " . absint($q['author']) . ')';
+ }
+
+ // MIME-Type stuff for attachment browsing
+
+ if ( isset( $q['post_mime_type'] ) && '' != $q['post_mime_type'] ) {
+ $whichmimetype = wp_post_mime_type_where( $q['post_mime_type'], $wpdb->posts );
+ }
+ $where .= $search . $whichauthor . $whichmimetype;
+
+ if ( ! empty( $this->meta_query->queries ) ) {
+ $clauses = $this->meta_query->get_sql( 'post', $wpdb->posts, 'ID', $this );
+ $join .= $clauses['join'];
+ $where .= $clauses['where'];
+ }
+
+ $rand = ( isset( $q['orderby'] ) && 'rand' === $q['orderby'] );
+ if ( ! isset( $q['order'] ) ) {
+ $q['order'] = $rand ? '' : 'DESC';
+ } else {
+ $q['order'] = $rand ? '' : $this->parse_order( $q['order'] );
+ }
+
+ // Order by.
+ if ( empty( $q['orderby'] ) ) {
+ /*
+ * Boolean false or empty array blanks out ORDER BY,
+ * while leaving the value unset or otherwise empty sets the default.
+ */
+ if ( isset( $q['orderby'] ) && ( is_array( $q['orderby'] ) || false === $q['orderby'] ) ) {
+ $orderby = '';
+ } else {
+ $orderby = "{$wpdb->posts}.post_date " . $q['order'];
+ }
+ } elseif ( 'none' == $q['orderby'] ) {
+ $orderby = '';
+ } elseif ( $q['orderby'] == 'post__in' && ! empty( $post__in ) ) {
+ $orderby = "FIELD( {$wpdb->posts}.ID, $post__in )";
+ } elseif ( $q['orderby'] == 'post_parent__in' && ! empty( $post_parent__in ) ) {
+ $orderby = "FIELD( {$wpdb->posts}.post_parent, $post_parent__in )";
+ } elseif ( $q['orderby'] == 'post_name__in' && ! empty( $post_name__in ) ) {
+ $orderby = "FIELD( {$wpdb->posts}.post_name, $post_name__in )";
+ } else {
+ $orderby_array = array();
+ if ( is_array( $q['orderby'] ) ) {
+ foreach ( $q['orderby'] as $_orderby => $order ) {
+ $orderby = addslashes_gpc( urldecode( $_orderby ) );
+ $parsed = $this->parse_orderby( $orderby );
+
+ if ( ! $parsed ) {
+ continue;
+ }
+
+ $orderby_array[] = $parsed . ' ' . $this->parse_order( $order );
+ }
+ $orderby = implode( ', ', $orderby_array );
+
+ } else {
+ $q['orderby'] = urldecode( $q['orderby'] );
+ $q['orderby'] = addslashes_gpc( $q['orderby'] );
+
+ foreach ( explode( ' ', $q['orderby'] ) as $i => $orderby ) {
+ $parsed = $this->parse_orderby( $orderby );
+ // Only allow certain values for safety.
+ if ( ! $parsed ) {
+ continue;
+ }
+
+ $orderby_array[] = $parsed;
+ }
+ $orderby = implode( ' ' . $q['order'] . ', ', $orderby_array );
+
+ if ( empty( $orderby ) ) {
+ $orderby = "{$wpdb->posts}.post_date " . $q['order'];
+ } elseif ( ! empty( $q['order'] ) ) {
+ $orderby .= " {$q['order']}";
+ }
+ }
+ }
+
+ // Order search results by relevance only when another "orderby" is not specified in the query.
+ if ( ! empty( $q['s'] ) ) {
+ $search_orderby = '';
+ if ( ! empty( $q['search_orderby_title'] ) && ( empty( $q['orderby'] ) && ! $this->is_feed ) || ( isset( $q['orderby'] ) && 'relevance' === $q['orderby'] ) )
+ $search_orderby = $this->parse_search_order( $q );
+
+ if ( ! $q['suppress_filters'] ) {
+ /**
+ * Filters the ORDER BY used when ordering search results.
+ *
+ * @since 3.7.0
+ *
+ * @param string $search_orderby The ORDER BY clause.
+ * @param WP_Query $this The current WP_Query instance.
+ */
+ $search_orderby = apply_filters( 'posts_search_orderby', $search_orderby, $this );
+ }
+
+ if ( $search_orderby )
+ $orderby = $orderby ? $search_orderby . ', ' . $orderby : $search_orderby;
+ }
+
+ if ( is_array( $post_type ) && count( $post_type ) > 1 ) {
+ $post_type_cap = 'multiple_post_type';
+ } else {
+ if ( is_array( $post_type ) )
+ $post_type = reset( $post_type );
+ $post_type_object = get_post_type_object( $post_type );
+ if ( empty( $post_type_object ) )
+ $post_type_cap = $post_type;
+ }
+
+ if ( isset( $q['post_password'] ) ) {
+ $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_password = %s", $q['post_password'] );
+ if ( empty( $q['perm'] ) ) {
+ $q['perm'] = 'readable';
+ }
+ } elseif ( isset( $q['has_password'] ) ) {
+ $where .= sprintf( " AND {$wpdb->posts}.post_password %s ''", $q['has_password'] ? '!=' : '=' );
+ }
+
+ if ( ! empty( $q['comment_status'] ) ) {
+ $where .= $wpdb->prepare( " AND {$wpdb->posts}.comment_status = %s ", $q['comment_status'] );
+ }
+
+ if ( ! empty( $q['ping_status'] ) ) {
+ $where .= $wpdb->prepare( " AND {$wpdb->posts}.ping_status = %s ", $q['ping_status'] );
+ }
+
+ if ( 'any' == $post_type ) {
+ $in_search_post_types = get_post_types( array('exclude_from_search' => false) );
+ if ( empty( $in_search_post_types ) ) {
+ $where .= ' AND 1=0 ';
+ } else {
+ $where .= " AND {$wpdb->posts}.post_type IN ('" . join("', '", $in_search_post_types ) . "')";
+ }
+ } elseif ( !empty( $post_type ) && is_array( $post_type ) ) {
+ $where .= " AND {$wpdb->posts}.post_type IN ('" . join("', '", $post_type) . "')";
+ } elseif ( ! empty( $post_type ) ) {
+ $where .= " AND {$wpdb->posts}.post_type = '$post_type'";
+ $post_type_object = get_post_type_object ( $post_type );
+ } elseif ( $this->is_attachment ) {
+ $where .= " AND {$wpdb->posts}.post_type = 'attachment'";
+ $post_type_object = get_post_type_object ( 'attachment' );
+ } elseif ( $this->is_page ) {
+ $where .= " AND {$wpdb->posts}.post_type = 'page'";
+ $post_type_object = get_post_type_object ( 'page' );
+ } else {
+ $where .= " AND {$wpdb->posts}.post_type = 'post'";
+ $post_type_object = get_post_type_object ( 'post' );
+ }
+
+ $edit_cap = 'edit_post';
+ $read_cap = 'read_post';
+
+ if ( ! empty( $post_type_object ) ) {
+ $edit_others_cap = $post_type_object->cap->edit_others_posts;
+ $read_private_cap = $post_type_object->cap->read_private_posts;
+ } else {
+ $edit_others_cap = 'edit_others_' . $post_type_cap . 's';
+ $read_private_cap = 'read_private_' . $post_type_cap . 's';
+ }
+
+ $user_id = get_current_user_id();
+
+ $q_status = array();
+ if ( ! empty( $q['post_status'] ) ) {
+ $statuswheres = array();
+ $q_status = $q['post_status'];
+ if ( ! is_array( $q_status ) )
+ $q_status = explode(',', $q_status);
+ $r_status = array();
+ $p_status = array();
+ $e_status = array();
+ if ( in_array( 'any', $q_status ) ) {
+ foreach ( get_post_stati( array( 'exclude_from_search' => true ) ) as $status ) {
+ if ( ! in_array( $status, $q_status ) ) {
+ $e_status[] = "{$wpdb->posts}.post_status <> '$status'";
+ }
+ }
+ } else {
+ foreach ( get_post_stati() as $status ) {
+ if ( in_array( $status, $q_status ) ) {
+ if ( 'private' == $status ) {
+ $p_status[] = "{$wpdb->posts}.post_status = '$status'";
+ } else {
+ $r_status[] = "{$wpdb->posts}.post_status = '$status'";
+ }
+ }
+ }
+ }
+
+ if ( empty($q['perm'] ) || 'readable' != $q['perm'] ) {
+ $r_status = array_merge($r_status, $p_status);
+ unset($p_status);
+ }
+
+ if ( !empty($e_status) ) {
+ $statuswheres[] = "(" . join( ' AND ', $e_status ) . ")";
+ }
+ if ( !empty($r_status) ) {
+ if ( !empty($q['perm'] ) && 'editable' == $q['perm'] && !current_user_can($edit_others_cap) ) {
+ $statuswheres[] = "({$wpdb->posts}.post_author = $user_id " . "AND (" . join( ' OR ', $r_status ) . "))";
+ } else {
+ $statuswheres[] = "(" . join( ' OR ', $r_status ) . ")";
+ }
+ }
+ if ( !empty($p_status) ) {
+ if ( !empty($q['perm'] ) && 'readable' == $q['perm'] && !current_user_can($read_private_cap) ) {
+ $statuswheres[] = "({$wpdb->posts}.post_author = $user_id " . "AND (" . join( ' OR ', $p_status ) . "))";
+ } else {
+ $statuswheres[] = "(" . join( ' OR ', $p_status ) . ")";
+ }
+ }
+ if ( $post_status_join ) {
+ $join .= " LEFT JOIN {$wpdb->posts} AS p2 ON ({$wpdb->posts}.post_parent = p2.ID) ";
+ foreach ( $statuswheres as $index => $statuswhere ) {
+ $statuswheres[$index] = "($statuswhere OR ({$wpdb->posts}.post_status = 'inherit' AND " . str_replace( $wpdb->posts, 'p2', $statuswhere ) . "))";
+ }
+ }
+ $where_status = implode( ' OR ', $statuswheres );
+ if ( ! empty( $where_status ) ) {
+ $where .= " AND ($where_status)";
+ }
+ } elseif ( !$this->is_singular ) {
+ $where .= " AND ({$wpdb->posts}.post_status = 'publish'";
+
+ // Add public states.
+ $public_states = get_post_stati( array('public' => true) );
+ foreach ( (array) $public_states as $state ) {
+ if ( 'publish' == $state ) // Publish is hard-coded above.
+ continue;
+ $where .= " OR {$wpdb->posts}.post_status = '$state'";
+ }
+
+ if ( $this->is_admin ) {
+ // Add protected states that should show in the admin all list.
+ $admin_all_states = get_post_stati( array('protected' => true, 'show_in_admin_all_list' => true) );
+ foreach ( (array) $admin_all_states as $state ) {
+ $where .= " OR {$wpdb->posts}.post_status = '$state'";
+ }
+ }
+
+ if ( is_user_logged_in() ) {
+ // Add private states that are limited to viewing by the author of a post or someone who has caps to read private states.
+ $private_states = get_post_stati( array('private' => true) );
+ foreach ( (array) $private_states as $state ) {
+ $where .= current_user_can( $read_private_cap ) ? " OR {$wpdb->posts}.post_status = '$state'" : " OR {$wpdb->posts}.post_author = $user_id AND {$wpdb->posts}.post_status = '$state'";
+ }
+ }
+
+ $where .= ')';
+ }
+
+ /*
+ * Apply filters on where and join prior to paging so that any
+ * manipulations to them are reflected in the paging by day queries.
+ */
+ if ( !$q['suppress_filters'] ) {
+ /**
+ * Filters the WHERE clause of the query.
+ *
+ * @since 1.5.0
+ *
+ * @param string $where The WHERE clause of the query.
+ * @param WP_Query &$this The WP_Query instance (passed by reference).
+ */
+ $where = apply_filters_ref_array( 'posts_where', array( $where, &$this ) );
+
+ /**
+ * Filters the JOIN clause of the query.
+ *
+ * @since 1.5.0
+ *
+ * @param string $where The JOIN clause of the query.
+ * @param WP_Query &$this The WP_Query instance (passed by reference).
+ */
+ $join = apply_filters_ref_array( 'posts_join', array( $join, &$this ) );
+ }
+
+ // Paging
+ if ( empty($q['nopaging']) && !$this->is_singular ) {
+ $page = absint($q['paged']);
+ if ( !$page )
+ $page = 1;
+
+ // If 'offset' is provided, it takes precedence over 'paged'.
+ if ( isset( $q['offset'] ) && is_numeric( $q['offset'] ) ) {
+ $q['offset'] = absint( $q['offset'] );
+ $pgstrt = $q['offset'] . ', ';
+ } else {
+ $pgstrt = absint( ( $page - 1 ) * $q['posts_per_page'] ) . ', ';
+ }
+ $limits = 'LIMIT ' . $pgstrt . $q['posts_per_page'];
+ }
+
+ // Comments feeds
+ if ( $this->is_comment_feed && ! $this->is_singular ) {
+ if ( $this->is_archive || $this->is_search ) {
+ $cjoin = "JOIN {$wpdb->posts} ON ({$wpdb->comments}.comment_post_ID = {$wpdb->posts}.ID) $join ";
+ $cwhere = "WHERE comment_approved = '1' $where";
+ $cgroupby = "{$wpdb->comments}.comment_id";
+ } else { // Other non singular e.g. front
+ $cjoin = "JOIN {$wpdb->posts} ON ( {$wpdb->comments}.comment_post_ID = {$wpdb->posts}.ID )";
+ $cwhere = "WHERE ( post_status = 'publish' OR ( post_status = 'inherit' AND post_type = 'attachment' ) ) AND comment_approved = '1'";
+ $cgroupby = '';
+ }
+
+ if ( !$q['suppress_filters'] ) {
+ /**
+ * Filters the JOIN clause of the comments feed query before sending.
+ *
+ * @since 2.2.0
+ *
+ * @param string $cjoin The JOIN clause of the query.
+ * @param WP_Query &$this The WP_Query instance (passed by reference).
+ */
+ $cjoin = apply_filters_ref_array( 'comment_feed_join', array( $cjoin, &$this ) );
+
+ /**
+ * Filters the WHERE clause of the comments feed query before sending.
+ *
+ * @since 2.2.0
+ *
+ * @param string $cwhere The WHERE clause of the query.
+ * @param WP_Query &$this The WP_Query instance (passed by reference).
+ */
+ $cwhere = apply_filters_ref_array( 'comment_feed_where', array( $cwhere, &$this ) );
+
+ /**
+ * Filters the GROUP BY clause of the comments feed query before sending.
+ *
+ * @since 2.2.0
+ *
+ * @param string $cgroupby The GROUP BY clause of the query.
+ * @param WP_Query &$this The WP_Query instance (passed by reference).
+ */
+ $cgroupby = apply_filters_ref_array( 'comment_feed_groupby', array( $cgroupby, &$this ) );
+
+ /**
+ * Filters the ORDER BY clause of the comments feed query before sending.
+ *
+ * @since 2.8.0
+ *
+ * @param string $corderby The ORDER BY clause of the query.
+ * @param WP_Query &$this The WP_Query instance (passed by reference).
+ */
+ $corderby = apply_filters_ref_array( 'comment_feed_orderby', array( 'comment_date_gmt DESC', &$this ) );
+
+ /**
+ * Filters the LIMIT clause of the comments feed query before sending.
+ *
+ * @since 2.8.0
+ *
+ * @param string $climits The JOIN clause of the query.
+ * @param WP_Query &$this The WP_Query instance (passed by reference).
+ */
+ $climits = apply_filters_ref_array( 'comment_feed_limits', array( 'LIMIT ' . get_option('posts_per_rss'), &$this ) );
+ }
+ $cgroupby = ( ! empty( $cgroupby ) ) ? 'GROUP BY ' . $cgroupby : '';
+ $corderby = ( ! empty( $corderby ) ) ? 'ORDER BY ' . $corderby : '';
+
+ $comments = (array) $wpdb->get_results("SELECT $distinct {$wpdb->comments}.* FROM {$wpdb->comments} $cjoin $cwhere $cgroupby $corderby $climits");
+ // Convert to WP_Comment
+ $this->comments = array_map( 'get_comment', $comments );
+ $this->comment_count = count($this->comments);
+
+ $post_ids = array();
+
+ foreach ( $this->comments as $comment )
+ $post_ids[] = (int) $comment->comment_post_ID;
+
+ $post_ids = join(',', $post_ids);
+ $join = '';
+ if ( $post_ids ) {
+ $where = "AND {$wpdb->posts}.ID IN ($post_ids) ";
+ } else {
+ $where = "AND 0";
+ }
+ }
+
+ $pieces = array( 'where', 'groupby', 'join', 'orderby', 'distinct', 'fields', 'limits' );
+
+ /*
+ * Apply post-paging filters on where and join. Only plugins that
+ * manipulate paging queries should use these hooks.
+ */
+ if ( !$q['suppress_filters'] ) {
+ /**
+ * Filters the WHERE clause of the query.
+ *
+ * Specifically for manipulating paging queries.
+ *
+ * @since 1.5.0
+ *
+ * @param string $where The WHERE clause of the query.
+ * @param WP_Query &$this The WP_Query instance (passed by reference).
+ */
+ $where = apply_filters_ref_array( 'posts_where_paged', array( $where, &$this ) );
+
+ /**
+ * Filters the GROUP BY clause of the query.
+ *
+ * @since 2.0.0
+ *
+ * @param string $groupby The GROUP BY clause of the query.
+ * @param WP_Query &$this The WP_Query instance (passed by reference).
+ */
+ $groupby = apply_filters_ref_array( 'posts_groupby', array( $groupby, &$this ) );
+
+ /**
+ * Filters the JOIN clause of the query.
+ *
+ * Specifically for manipulating paging queries.
+ *
+ * @since 1.5.0
+ *
+ * @param string $join The JOIN clause of the query.
+ * @param WP_Query &$this The WP_Query instance (passed by reference).
+ */
+ $join = apply_filters_ref_array( 'posts_join_paged', array( $join, &$this ) );
+
+ /**
+ * Filters the ORDER BY clause of the query.
+ *
+ * @since 1.5.1
+ *
+ * @param string $orderby The ORDER BY clause of the query.
+ * @param WP_Query &$this The WP_Query instance (passed by reference).
+ */
+ $orderby = apply_filters_ref_array( 'posts_orderby', array( $orderby, &$this ) );
+
+ /**
+ * Filters the DISTINCT clause of the query.
+ *
+ * @since 2.1.0
+ *
+ * @param string $distinct The DISTINCT clause of the query.
+ * @param WP_Query &$this The WP_Query instance (passed by reference).
+ */
+ $distinct = apply_filters_ref_array( 'posts_distinct', array( $distinct, &$this ) );
+
+ /**
+ * Filters the LIMIT clause of the query.
+ *
+ * @since 2.1.0
+ *
+ * @param string $limits The LIMIT clause of the query.
+ * @param WP_Query &$this The WP_Query instance (passed by reference).
+ */
+ $limits = apply_filters_ref_array( 'post_limits', array( $limits, &$this ) );
+
+ /**
+ * Filters the SELECT clause of the query.
+ *
+ * @since 2.1.0
+ *
+ * @param string $fields The SELECT clause of the query.
+ * @param WP_Query &$this The WP_Query instance (passed by reference).
+ */
+ $fields = apply_filters_ref_array( 'posts_fields', array( $fields, &$this ) );
+
+ /**
+ * Filters all query clauses at once, for convenience.
+ *
+ * Covers the WHERE, GROUP BY, JOIN, ORDER BY, DISTINCT,
+ * fields (SELECT), and LIMITS clauses.
+ *
+ * @since 3.1.0
+ *
+ * @param array $clauses The list of clauses for the query.
+ * @param WP_Query &$this The WP_Query instance (passed by reference).
+ */
+ $clauses = (array) apply_filters_ref_array( 'posts_clauses', array( compact( $pieces ), &$this ) );
+
+ $where = isset( $clauses[ 'where' ] ) ? $clauses[ 'where' ] : '';
+ $groupby = isset( $clauses[ 'groupby' ] ) ? $clauses[ 'groupby' ] : '';
+ $join = isset( $clauses[ 'join' ] ) ? $clauses[ 'join' ] : '';
+ $orderby = isset( $clauses[ 'orderby' ] ) ? $clauses[ 'orderby' ] : '';
+ $distinct = isset( $clauses[ 'distinct' ] ) ? $clauses[ 'distinct' ] : '';
+ $fields = isset( $clauses[ 'fields' ] ) ? $clauses[ 'fields' ] : '';
+ $limits = isset( $clauses[ 'limits' ] ) ? $clauses[ 'limits' ] : '';
+ }
+
+ /**
+ * Fires to announce the query's current selection parameters.
+ *
+ * For use by caching plugins.
+ *
+ * @since 2.3.0
+ *
+ * @param string $selection The assembled selection query.
+ */
+ do_action( 'posts_selection', $where . $groupby . $orderby . $limits . $join );
+
+ /*
+ * Filters again for the benefit of caching plugins.
+ * Regular plugins should use the hooks above.
+ */
+ if ( !$q['suppress_filters'] ) {
+ /**
+ * Filters the WHERE clause of the query.
+ *
+ * For use by caching plugins.
+ *
+ * @since 2.5.0
+ *
+ * @param string $where The WHERE clause of the query.
+ * @param WP_Query &$this The WP_Query instance (passed by reference).
+ */
+ $where = apply_filters_ref_array( 'posts_where_request', array( $where, &$this ) );
+
+ /**
+ * Filters the GROUP BY clause of the query.
+ *
+ * For use by caching plugins.
+ *
+ * @since 2.5.0
+ *
+ * @param string $groupby The GROUP BY clause of the query.
+ * @param WP_Query &$this The WP_Query instance (passed by reference).
+ */
+ $groupby = apply_filters_ref_array( 'posts_groupby_request', array( $groupby, &$this ) );
+
+ /**
+ * Filters the JOIN clause of the query.
+ *
+ * For use by caching plugins.
+ *
+ * @since 2.5.0
+ *
+ * @param string $join The JOIN clause of the query.
+ * @param WP_Query &$this The WP_Query instance (passed by reference).
+ */
+ $join = apply_filters_ref_array( 'posts_join_request', array( $join, &$this ) );
+
+ /**
+ * Filters the ORDER BY clause of the query.
+ *
+ * For use by caching plugins.
+ *
+ * @since 2.5.0
+ *
+ * @param string $orderby The ORDER BY clause of the query.
+ * @param WP_Query &$this The WP_Query instance (passed by reference).
+ */
+ $orderby = apply_filters_ref_array( 'posts_orderby_request', array( $orderby, &$this ) );
+
+ /**
+ * Filters the DISTINCT clause of the query.
+ *
+ * For use by caching plugins.
+ *
+ * @since 2.5.0
+ *
+ * @param string $distinct The DISTINCT clause of the query.
+ * @param WP_Query &$this The WP_Query instance (passed by reference).
+ */
+ $distinct = apply_filters_ref_array( 'posts_distinct_request', array( $distinct, &$this ) );
+
+ /**
+ * Filters the SELECT clause of the query.
+ *
+ * For use by caching plugins.
+ *
+ * @since 2.5.0
+ *
+ * @param string $fields The SELECT clause of the query.
+ * @param WP_Query &$this The WP_Query instance (passed by reference).
+ */
+ $fields = apply_filters_ref_array( 'posts_fields_request', array( $fields, &$this ) );
+
+ /**
+ * Filters the LIMIT clause of the query.
+ *
+ * For use by caching plugins.
+ *
+ * @since 2.5.0
+ *
+ * @param string $limits The LIMIT clause of the query.
+ * @param WP_Query &$this The WP_Query instance (passed by reference).
+ */
+ $limits = apply_filters_ref_array( 'post_limits_request', array( $limits, &$this ) );
+
+ /**
+ * Filters all query clauses at once, for convenience.
+ *
+ * For use by caching plugins.
+ *
+ * Covers the WHERE, GROUP BY, JOIN, ORDER BY, DISTINCT,
+ * fields (SELECT), and LIMITS clauses.
+ *
+ * @since 3.1.0
+ *
+ * @param array $pieces The pieces of the query.
+ * @param WP_Query &$this The WP_Query instance (passed by reference).
+ */
+ $clauses = (array) apply_filters_ref_array( 'posts_clauses_request', array( compact( $pieces ), &$this ) );
+
+ $where = isset( $clauses[ 'where' ] ) ? $clauses[ 'where' ] : '';
+ $groupby = isset( $clauses[ 'groupby' ] ) ? $clauses[ 'groupby' ] : '';
+ $join = isset( $clauses[ 'join' ] ) ? $clauses[ 'join' ] : '';
+ $orderby = isset( $clauses[ 'orderby' ] ) ? $clauses[ 'orderby' ] : '';
+ $distinct = isset( $clauses[ 'distinct' ] ) ? $clauses[ 'distinct' ] : '';
+ $fields = isset( $clauses[ 'fields' ] ) ? $clauses[ 'fields' ] : '';
+ $limits = isset( $clauses[ 'limits' ] ) ? $clauses[ 'limits' ] : '';
+ }
+
+ if ( ! empty($groupby) )
+ $groupby = 'GROUP BY ' . $groupby;
+ if ( !empty( $orderby ) )
+ $orderby = 'ORDER BY ' . $orderby;
+
+ $found_rows = '';
+ if ( !$q['no_found_rows'] && !empty($limits) )
+ $found_rows = 'SQL_CALC_FOUND_ROWS';
+
+ $this->request = $old_request = "SELECT $found_rows $distinct $fields FROM {$wpdb->posts} $join WHERE 1=1 $where $groupby $orderby $limits";
+
+ if ( !$q['suppress_filters'] ) {
+ /**
+ * Filters the completed SQL query before sending.
+ *
+ * @since 2.0.0
+ *
+ * @param string $request The complete SQL query.
+ * @param WP_Query &$this The WP_Query instance (passed by reference).
+ */
+ $this->request = apply_filters_ref_array( 'posts_request', array( $this->request, &$this ) );
+ }
+
+ /**
+ * Filters the posts array before the query takes place.
+ *
+ * Return a non-null value to bypass WordPress's default post queries.
+ *
+ * Filtering functions that require pagination information are encouraged to set
+ * the `found_posts` and `max_num_pages` properties of the WP_Query object,
+ * passed to the filter by reference. If WP_Query does not perform a database
+ * query, it will not have enough information to generate these values itself.
+ *
+ * @since 4.6.0
+ *
+ * @param array|null $posts Return an array of post data to short-circuit WP's query,
+ * or null to allow WP to run its normal queries.
+ * @param WP_Query $this The WP_Query instance, passed by reference.
+ */
+ $this->posts = apply_filters_ref_array( 'posts_pre_query', array( null, &$this ) );
+
+ if ( 'ids' == $q['fields'] ) {
+ if ( null === $this->posts ) {
+ $this->posts = $wpdb->get_col( $this->request );
+ }
+
+ $this->posts = array_map( 'intval', $this->posts );
+ $this->post_count = count( $this->posts );
+ $this->set_found_posts( $q, $limits );
+
+ return $this->posts;
+ }
+
+ if ( 'id=>parent' == $q['fields'] ) {
+ if ( null === $this->posts ) {
+ $this->posts = $wpdb->get_results( $this->request );
+ }
+
+ $this->post_count = count( $this->posts );
+ $this->set_found_posts( $q, $limits );
+
+ $r = array();
+ foreach ( $this->posts as $key => $post ) {
+ $this->posts[ $key ]->ID = (int) $post->ID;
+ $this->posts[ $key ]->post_parent = (int) $post->post_parent;
+
+ $r[ (int) $post->ID ] = (int) $post->post_parent;
+ }
+
+ return $r;
+ }
+
+ if ( null === $this->posts ) {
+ $split_the_query = ( $old_request == $this->request && "{$wpdb->posts}.*" == $fields && !empty( $limits ) && $q['posts_per_page'] < 500 );
+
+ /**
+ * Filters whether to split the query.
+ *
+ * Splitting the query will cause it to fetch just the IDs of the found posts
+ * (and then individually fetch each post by ID), rather than fetching every
+ * complete row at once. One massive result vs. many small results.
+ *
+ * @since 3.4.0
+ *
+ * @param bool $split_the_query Whether or not to split the query.
+ * @param WP_Query $this The WP_Query instance.
+ */
+ $split_the_query = apply_filters( 'split_the_query', $split_the_query, $this );
+
+ if ( $split_the_query ) {
+ // First get the IDs and then fill in the objects
+
+ $this->request = "SELECT $found_rows $distinct {$wpdb->posts}.ID FROM {$wpdb->posts} $join WHERE 1=1 $where $groupby $orderby $limits";
+
+ /**
+ * Filters the Post IDs SQL request before sending.
+ *
+ * @since 3.4.0
+ *
+ * @param string $request The post ID request.
+ * @param WP_Query $this The WP_Query instance.
+ */
+ $this->request = apply_filters( 'posts_request_ids', $this->request, $this );
+
+ $ids = $wpdb->get_col( $this->request );
+
+ if ( $ids ) {
+ $this->posts = $ids;
+ $this->set_found_posts( $q, $limits );
+ _prime_post_caches( $ids, $q['update_post_term_cache'], $q['update_post_meta_cache'] );
+ } else {
+ $this->posts = array();
+ }
+ } else {
+ $this->posts = $wpdb->get_results( $this->request );
+ $this->set_found_posts( $q, $limits );
+ }
+ }
+
+ // Convert to WP_Post objects.
+ if ( $this->posts ) {
+ $this->posts = array_map( 'get_post', $this->posts );
+ }
+
+ if ( ! $q['suppress_filters'] ) {
+ /**
+ * Filters the raw post results array, prior to status checks.
+ *
+ * @since 2.3.0
+ *
+ * @param array $posts The post results array.
+ * @param WP_Query &$this The WP_Query instance (passed by reference).
+ */
+ $this->posts = apply_filters_ref_array( 'posts_results', array( $this->posts, &$this ) );
+ }
+
+ if ( !empty($this->posts) && $this->is_comment_feed && $this->is_singular ) {
+ /** This filter is documented in wp-includes/query.php */
+ $cjoin = apply_filters_ref_array( 'comment_feed_join', array( '', &$this ) );
+
+ /** This filter is documented in wp-includes/query.php */
+ $cwhere = apply_filters_ref_array( 'comment_feed_where', array( "WHERE comment_post_ID = '{$this->posts[0]->ID}' AND comment_approved = '1'", &$this ) );
+
+ /** This filter is documented in wp-includes/query.php */
+ $cgroupby = apply_filters_ref_array( 'comment_feed_groupby', array( '', &$this ) );
+ $cgroupby = ( ! empty( $cgroupby ) ) ? 'GROUP BY ' . $cgroupby : '';
+
+ /** This filter is documented in wp-includes/query.php */
+ $corderby = apply_filters_ref_array( 'comment_feed_orderby', array( 'comment_date_gmt DESC', &$this ) );
+ $corderby = ( ! empty( $corderby ) ) ? 'ORDER BY ' . $corderby : '';
+
+ /** This filter is documented in wp-includes/query.php */
+ $climits = apply_filters_ref_array( 'comment_feed_limits', array( 'LIMIT ' . get_option('posts_per_rss'), &$this ) );
+
+ $comments_request = "SELECT {$wpdb->comments}.* FROM {$wpdb->comments} $cjoin $cwhere $cgroupby $corderby $climits";
+ $comments = $wpdb->get_results($comments_request);
+ // Convert to WP_Comment
+ $this->comments = array_map( 'get_comment', $comments );
+ $this->comment_count = count($this->comments);
+ }
+
+ // Check post status to determine if post should be displayed.
+ if ( !empty($this->posts) && ($this->is_single || $this->is_page) ) {
+ $status = get_post_status($this->posts[0]);
+ if ( 'attachment' === $this->posts[0]->post_type && 0 === (int) $this->posts[0]->post_parent ) {
+ $this->is_page = false;
+ $this->is_single = true;
+ $this->is_attachment = true;
+ }
+ $post_status_obj = get_post_status_object($status);
+
+ // If the post_status was specifically requested, let it pass through.
+ if ( !$post_status_obj->public && ! in_array( $status, $q_status ) ) {
+
+ if ( ! is_user_logged_in() ) {
+ // User must be logged in to view unpublished posts.
+ $this->posts = array();
+ } else {
+ if ( $post_status_obj->protected ) {
+ // User must have edit permissions on the draft to preview.
+ if ( ! current_user_can($edit_cap, $this->posts[0]->ID) ) {
+ $this->posts = array();
+ } else {
+ $this->is_preview = true;
+ if ( 'future' != $status )
+ $this->posts[0]->post_date = current_time('mysql');
+ }
+ } elseif ( $post_status_obj->private ) {
+ if ( ! current_user_can($read_cap, $this->posts[0]->ID) )
+ $this->posts = array();
+ } else {
+ $this->posts = array();
+ }
+ }
+ }
+
+ if ( $this->is_preview && $this->posts && current_user_can( $edit_cap, $this->posts[0]->ID ) ) {
+ /**
+ * Filters the single post for preview mode.
+ *
+ * @since 2.7.0
+ *
+ * @param WP_Post $post_preview The Post object.
+ * @param WP_Query &$this The WP_Query instance (passed by reference).
+ */
+ $this->posts[0] = get_post( apply_filters_ref_array( 'the_preview', array( $this->posts[0], &$this ) ) );
+ }
+ }
+
+ // Put sticky posts at the top of the posts array
+ $sticky_posts = get_option('sticky_posts');
+ if ( $this->is_home && $page <= 1 && is_array($sticky_posts) && !empty($sticky_posts) && !$q['ignore_sticky_posts'] ) {
+ $num_posts = count($this->posts);
+ $sticky_offset = 0;
+ // Loop over posts and relocate stickies to the front.
+ for ( $i = 0; $i < $num_posts; $i++ ) {
+ if ( in_array($this->posts[$i]->ID, $sticky_posts) ) {
+ $sticky_post = $this->posts[$i];
+ // Remove sticky from current position
+ array_splice($this->posts, $i, 1);
+ // Move to front, after other stickies
+ array_splice($this->posts, $sticky_offset, 0, array($sticky_post));
+ // Increment the sticky offset. The next sticky will be placed at this offset.
+ $sticky_offset++;
+ // Remove post from sticky posts array
+ $offset = array_search($sticky_post->ID, $sticky_posts);
+ unset( $sticky_posts[$offset] );
+ }
+ }
+
+ // If any posts have been excluded specifically, Ignore those that are sticky.
+ if ( !empty($sticky_posts) && !empty($q['post__not_in']) )
+ $sticky_posts = array_diff($sticky_posts, $q['post__not_in']);
+
+ // Fetch sticky posts that weren't in the query results
+ if ( !empty($sticky_posts) ) {
+ $stickies = get_posts( array(
+ 'post__in' => $sticky_posts,
+ 'post_type' => $post_type,
+ 'post_status' => 'publish',
+ 'nopaging' => true
+ ) );
+
+ foreach ( $stickies as $sticky_post ) {
+ array_splice( $this->posts, $sticky_offset, 0, array( $sticky_post ) );
+ $sticky_offset++;
+ }
+ }
+ }
+
+ // If comments have been fetched as part of the query, make sure comment meta lazy-loading is set up.
+ if ( ! empty( $this->comments ) ) {
+ wp_queue_comments_for_comment_meta_lazyload( $this->comments );
+ }
+
+ if ( ! $q['suppress_filters'] ) {
+ /**
+ * Filters the array of retrieved posts after they've been fetched and
+ * internally processed.
+ *
+ * @since 1.5.0
+ *
+ * @param array $posts The array of retrieved posts.
+ * @param WP_Query &$this The WP_Query instance (passed by reference).
+ */
+ $this->posts = apply_filters_ref_array( 'the_posts', array( $this->posts, &$this ) );
+ }
+
+ // Ensure that any posts added/modified via one of the filters above are
+ // of the type WP_Post and are filtered.
+ if ( $this->posts ) {
+ $this->post_count = count( $this->posts );
+
+ $this->posts = array_map( 'get_post', $this->posts );
+
+ if ( $q['cache_results'] )
+ update_post_caches($this->posts, $post_type, $q['update_post_term_cache'], $q['update_post_meta_cache']);
+
+ $this->post = reset( $this->posts );
+ } else {
+ $this->post_count = 0;
+ $this->posts = array();
+ }
+
+ if ( $q['lazy_load_term_meta'] ) {
+ wp_queue_posts_for_term_meta_lazyload( $this->posts );
+ }
+
+ return $this->posts;
+ }
+
+ /**
+ * Set up the amount of found posts and the number of pages (if limit clause was used)
+ * for the current query.
+ *
+ * @since 3.5.0
+ * @access private
+ *
+ * @param array $q Query variables.
+ * @param string $limits LIMIT clauses of the query.
+ */
+ private function set_found_posts( $q, $limits ) {
+ global $wpdb;
+ // Bail if posts is an empty array. Continue if posts is an empty string,
+ // null, or false to accommodate caching plugins that fill posts later.
+ if ( $q['no_found_rows'] || ( is_array( $this->posts ) && ! $this->posts ) )
+ return;
+
+ if ( ! empty( $limits ) ) {
+ /**
+ * Filters the query to run for retrieving the found posts.
+ *
+ * @since 2.1.0
+ *
+ * @param string $found_posts The query to run to find the found posts.
+ * @param WP_Query &$this The WP_Query instance (passed by reference).
+ */
+ $this->found_posts = $wpdb->get_var( apply_filters_ref_array( 'found_posts_query', array( 'SELECT FOUND_ROWS()', &$this ) ) );
+ } else {
+ $this->found_posts = count( $this->posts );
+ }
+
+ /**
+ * Filters the number of found posts for the query.
+ *
+ * @since 2.1.0
+ *
+ * @param int $found_posts The number of posts found.
+ * @param WP_Query &$this The WP_Query instance (passed by reference).
+ */
+ $this->found_posts = apply_filters_ref_array( 'found_posts', array( $this->found_posts, &$this ) );
+
+ if ( ! empty( $limits ) )
+ $this->max_num_pages = ceil( $this->found_posts / $q['posts_per_page'] );
+ }
+
+ /**
+ * Set up the next post and iterate current post index.
+ *
+ * @since 1.5.0
+ * @access public
+ *
+ * @return WP_Post Next post.
+ */
+ public function next_post() {
+
+ $this->current_post++;
+
+ $this->post = $this->posts[$this->current_post];
+ return $this->post;
+ }
+
+ /**
+ * Sets up the current post.
+ *
+ * Retrieves the next post, sets up the post, sets the 'in the loop'
+ * property to true.
+ *
+ * @since 1.5.0
+ * @access public
+ *
+ * @global WP_Post $post
+ */
+ public function the_post() {
+ global $post;
+ $this->in_the_loop = true;
+
+ if ( $this->current_post == -1 ) // loop has just started
+ /**
+ * Fires once the loop is started.
+ *
+ * @since 2.0.0
+ *
+ * @param WP_Query &$this The WP_Query instance (passed by reference).
+ */
+ do_action_ref_array( 'loop_start', array( &$this ) );
+
+ $post = $this->next_post();
+ $this->setup_postdata( $post );
+ }
+
+ /**
+ * Determines whether there are more posts available in the loop.
+ *
+ * Calls the {@see 'loop_end'} action when the loop is complete.
+ *
+ * @since 1.5.0
+ * @access public
+ *
+ * @return bool True if posts are available, false if end of loop.
+ */
+ public function have_posts() {
+ if ( $this->current_post + 1 < $this->post_count ) {
+ return true;
+ } elseif ( $this->current_post + 1 == $this->post_count && $this->post_count > 0 ) {
+ /**
+ * Fires once the loop has ended.
+ *
+ * @since 2.0.0
+ *
+ * @param WP_Query &$this The WP_Query instance (passed by reference).
+ */
+ do_action_ref_array( 'loop_end', array( &$this ) );
+ // Do some cleaning up after the loop
+ $this->rewind_posts();
+ }
+
+ $this->in_the_loop = false;
+ return false;
+ }
+
+ /**
+ * Rewind the posts and reset post index.
+ *
+ * @since 1.5.0
+ * @access public
+ */
+ public function rewind_posts() {
+ $this->current_post = -1;
+ if ( $this->post_count > 0 ) {
+ $this->post = $this->posts[0];
+ }
+ }
+
+ /**
+ * Iterate current comment index and return WP_Comment object.
+ *
+ * @since 2.2.0
+ * @access public
+ *
+ * @return WP_Comment Comment object.
+ */
+ public function next_comment() {
+ $this->current_comment++;
+
+ $this->comment = $this->comments[$this->current_comment];
+ return $this->comment;
+ }
+
+ /**
+ * Sets up the current comment.
+ *
+ * @since 2.2.0
+ * @access public
+ * @global WP_Comment $comment Current comment.
+ */
+ public function the_comment() {
+ global $comment;
+
+ $comment = $this->next_comment();
+
+ if ( $this->current_comment == 0 ) {
+ /**
+ * Fires once the comment loop is started.
+ *
+ * @since 2.2.0
+ */
+ do_action( 'comment_loop_start' );
+ }
+ }
+
+ /**
+ * Whether there are more comments available.
+ *
+ * Automatically rewinds comments when finished.
+ *
+ * @since 2.2.0
+ * @access public
+ *
+ * @return bool True, if more comments. False, if no more posts.
+ */
+ public function have_comments() {
+ if ( $this->current_comment + 1 < $this->comment_count ) {
+ return true;
+ } elseif ( $this->current_comment + 1 == $this->comment_count ) {
+ $this->rewind_comments();
+ }
+
+ return false;
+ }
+
+ /**
+ * Rewind the comments, resets the comment index and comment to first.
+ *
+ * @since 2.2.0
+ * @access public
+ */
+ public function rewind_comments() {
+ $this->current_comment = -1;
+ if ( $this->comment_count > 0 ) {
+ $this->comment = $this->comments[0];
+ }
+ }
+
+ /**
+ * Sets up the WordPress query by parsing query string.
+ *
+ * @since 1.5.0
+ * @access public
+ *
+ * @param string $query URL query string.
+ * @return array List of posts.
+ */
+ public function query( $query ) {
+ $this->init();
+ $this->query = $this->query_vars = wp_parse_args( $query );
+ return $this->get_posts();
+ }
+
+ /**
+ * Retrieve queried object.
+ *
+ * If queried object is not set, then the queried object will be set from
+ * the category, tag, taxonomy, posts page, single post, page, or author
+ * query variable. After it is set up, it will be returned.
+ *
+ * @since 1.5.0
+ * @access public
+ *
+ * @return object
+ */
+ public function get_queried_object() {
+ if ( isset($this->queried_object) )
+ return $this->queried_object;
+
+ $this->queried_object = null;
+ $this->queried_object_id = null;
+
+ if ( $this->is_category || $this->is_tag || $this->is_tax ) {
+ if ( $this->is_category ) {
+ if ( $this->get( 'cat' ) ) {
+ $term = get_term( $this->get( 'cat' ), 'category' );
+ } elseif ( $this->get( 'category_name' ) ) {
+ $term = get_term_by( 'slug', $this->get( 'category_name' ), 'category' );
+ }
+ } elseif ( $this->is_tag ) {
+ if ( $this->get( 'tag_id' ) ) {
+ $term = get_term( $this->get( 'tag_id' ), 'post_tag' );
+ } elseif ( $this->get( 'tag' ) ) {
+ $term = get_term_by( 'slug', $this->get( 'tag' ), 'post_tag' );
+ }
+ } else {
+ // For other tax queries, grab the first term from the first clause.
+ if ( ! empty( $this->tax_query->queried_terms ) ) {
+ $queried_taxonomies = array_keys( $this->tax_query->queried_terms );
+ $matched_taxonomy = reset( $queried_taxonomies );
+ $query = $this->tax_query->queried_terms[ $matched_taxonomy ];
+
+ if ( ! empty( $query['terms'] ) ) {
+ if ( 'term_id' == $query['field'] ) {
+ $term = get_term( reset( $query['terms'] ), $matched_taxonomy );
+ } else {
+ $term = get_term_by( $query['field'], reset( $query['terms'] ), $matched_taxonomy );
+ }
+ }
+ }
+ }
+
+ if ( ! empty( $term ) && ! is_wp_error( $term ) ) {
+ $this->queried_object = $term;
+ $this->queried_object_id = (int) $term->term_id;
+
+ if ( $this->is_category && 'category' === $this->queried_object->taxonomy )
+ _make_cat_compat( $this->queried_object );
+ }
+ } elseif ( $this->is_post_type_archive ) {
+ $post_type = $this->get( 'post_type' );
+ if ( is_array( $post_type ) )
+ $post_type = reset( $post_type );
+ $this->queried_object = get_post_type_object( $post_type );
+ } elseif ( $this->is_posts_page ) {
+ $page_for_posts = get_option('page_for_posts');
+ $this->queried_object = get_post( $page_for_posts );
+ $this->queried_object_id = (int) $this->queried_object->ID;
+ } elseif ( $this->is_singular && ! empty( $this->post ) ) {
+ $this->queried_object = $this->post;
+ $this->queried_object_id = (int) $this->post->ID;
+ } elseif ( $this->is_author ) {
+ $this->queried_object_id = (int) $this->get('author');
+ $this->queried_object = get_userdata( $this->queried_object_id );
+ }
+
+ return $this->queried_object;
+ }
+
+ /**
+ * Retrieve ID of the current queried object.
+ *
+ * @since 1.5.0
+ * @access public
+ *
+ * @return int
+ */
+ public function get_queried_object_id() {
+ $this->get_queried_object();
+
+ if ( isset($this->queried_object_id) ) {
+ return $this->queried_object_id;
+ }
+
+ return 0;
+ }
+
+ /**
+ * Constructor.
+ *
+ * Sets up the WordPress query, if parameter is not empty.
+ *
+ * @since 1.5.0
+ * @access public
+ *
+ * @param string|array $query URL query string or array of vars.
+ */
+ public function __construct( $query = '' ) {
+ if ( ! empty( $query ) ) {
+ $this->query( $query );
+ }
+ }
+
+ /**
+ * Make private properties readable for backward compatibility.
+ *
+ * @since 4.0.0
+ * @access public
+ *
+ * @param string $name Property to get.
+ * @return mixed Property.
+ */
+ public function __get( $name ) {
+ if ( in_array( $name, $this->compat_fields ) ) {
+ return $this->$name;
+ }
+ }
+
+ /**
+ * Make private properties checkable for backward compatibility.
+ *
+ * @since 4.0.0
+ * @access public
+ *
+ * @param string $name Property to check if set.
+ * @return bool Whether the property is set.
+ */
+ public function __isset( $name ) {
+ if ( in_array( $name, $this->compat_fields ) ) {
+ return isset( $this->$name );
+ }
+ }
+
+ /**
+ * Make private/protected methods readable for backward compatibility.
+ *
+ * @since 4.0.0
+ * @access public
+ *
+ * @param callable $name Method to call.
+ * @param array $arguments Arguments to pass when calling.
+ * @return mixed|false Return value of the callback, false otherwise.
+ */
+ public function __call( $name, $arguments ) {
+ if ( in_array( $name, $this->compat_methods ) ) {
+ return call_user_func_array( array( $this, $name ), $arguments );
+ }
+ return false;
+ }
+
+ /**
+ * Is the query for an existing archive page?
+ *
+ * Month, Year, Category, Author, Post Type archive...
+ *
+ * @since 3.1.0
+ *
+ * @return bool
+ */
+ public function is_archive() {
+ return (bool) $this->is_archive;
+ }
+
+ /**
+ * Is the query for an existing post type archive page?
+ *
+ * @since 3.1.0
+ *
+ * @param mixed $post_types Optional. Post type or array of posts types to check against.
+ * @return bool
+ */
+ public function is_post_type_archive( $post_types = '' ) {
+ if ( empty( $post_types ) || ! $this->is_post_type_archive )
+ return (bool) $this->is_post_type_archive;
+
+ $post_type = $this->get( 'post_type' );
+ if ( is_array( $post_type ) )
+ $post_type = reset( $post_type );
+ $post_type_object = get_post_type_object( $post_type );
+
+ return in_array( $post_type_object->name, (array) $post_types );
+ }
+
+ /**
+ * Is the query for an existing attachment page?
+ *
+ * @since 3.1.0
+ *
+ * @param mixed $attachment Attachment ID, title, slug, or array of such.
+ * @return bool
+ */
+ public function is_attachment( $attachment = '' ) {
+ if ( ! $this->is_attachment ) {
+ return false;
+ }
+
+ if ( empty( $attachment ) ) {
+ return true;
+ }
+
+ $attachment = array_map( 'strval', (array) $attachment );
+
+ $post_obj = $this->get_queried_object();
+
+ if ( in_array( (string) $post_obj->ID, $attachment ) ) {
+ return true;
+ } elseif ( in_array( $post_obj->post_title, $attachment ) ) {
+ return true;
+ } elseif ( in_array( $post_obj->post_name, $attachment ) ) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Is the query for an existing author archive page?
+ *
+ * If the $author parameter is specified, this function will additionally
+ * check if the query is for one of the authors specified.
+ *
+ * @since 3.1.0
+ *
+ * @param mixed $author Optional. User ID, nickname, nicename, or array of User IDs, nicknames, and nicenames
+ * @return bool
+ */
+ public function is_author( $author = '' ) {
+ if ( !$this->is_author )
+ return false;
+
+ if ( empty($author) )
+ return true;
+
+ $author_obj = $this->get_queried_object();
+
+ $author = array_map( 'strval', (array) $author );
+
+ if ( in_array( (string) $author_obj->ID, $author ) )
+ return true;
+ elseif ( in_array( $author_obj->nickname, $author ) )
+ return true;
+ elseif ( in_array( $author_obj->user_nicename, $author ) )
+ return true;
+
+ return false;
+ }
+
+ /**
+ * Is the query for an existing category archive page?
+ *
+ * If the $category parameter is specified, this function will additionally
+ * check if the query is for one of the categories specified.
+ *
+ * @since 3.1.0
+ *
+ * @param mixed $category Optional. Category ID, name, slug, or array of Category IDs, names, and slugs.
+ * @return bool
+ */
+ public function is_category( $category = '' ) {
+ if ( !$this->is_category )
+ return false;
+
+ if ( empty($category) )
+ return true;
+
+ $cat_obj = $this->get_queried_object();
+
+ $category = array_map( 'strval', (array) $category );
+
+ if ( in_array( (string) $cat_obj->term_id, $category ) )
+ return true;
+ elseif ( in_array( $cat_obj->name, $category ) )
+ return true;
+ elseif ( in_array( $cat_obj->slug, $category ) )
+ return true;
+
+ return false;
+ }
+
+ /**
+ * Is the query for an existing tag archive page?
+ *
+ * If the $tag parameter is specified, this function will additionally
+ * check if the query is for one of the tags specified.
+ *
+ * @since 3.1.0
+ *
+ * @param mixed $tag Optional. Tag ID, name, slug, or array of Tag IDs, names, and slugs.
+ * @return bool
+ */
+ public function is_tag( $tag = '' ) {
+ if ( ! $this->is_tag )
+ return false;
+
+ if ( empty( $tag ) )
+ return true;
+
+ $tag_obj = $this->get_queried_object();
+
+ $tag = array_map( 'strval', (array) $tag );
+
+ if ( in_array( (string) $tag_obj->term_id, $tag ) )
+ return true;
+ elseif ( in_array( $tag_obj->name, $tag ) )
+ return true;
+ elseif ( in_array( $tag_obj->slug, $tag ) )
+ return true;
+
+ return false;
+ }
+
+ /**
+ * Is the query for an existing custom taxonomy archive page?
+ *
+ * If the $taxonomy parameter is specified, this function will additionally
+ * check if the query is for that specific $taxonomy.
+ *
+ * If the $term parameter is specified in addition to the $taxonomy parameter,
+ * this function will additionally check if the query is for one of the terms
+ * specified.
+ *
+ * @since 3.1.0
+ *
+ * @global array $wp_taxonomies
+ *
+ * @param mixed $taxonomy Optional. Taxonomy slug or slugs.
+ * @param mixed $term Optional. Term ID, name, slug or array of Term IDs, names, and slugs.
+ * @return bool True for custom taxonomy archive pages, false for built-in taxonomies (category and tag archives).
+ */
+ public function is_tax( $taxonomy = '', $term = '' ) {
+ global $wp_taxonomies;
+
+ if ( !$this->is_tax )
+ return false;
+
+ if ( empty( $taxonomy ) )
+ return true;
+
+ $queried_object = $this->get_queried_object();
+ $tax_array = array_intersect( array_keys( $wp_taxonomies ), (array) $taxonomy );
+ $term_array = (array) $term;
+
+ // Check that the taxonomy matches.
+ if ( ! ( isset( $queried_object->taxonomy ) && count( $tax_array ) && in_array( $queried_object->taxonomy, $tax_array ) ) )
+ return false;
+
+ // Only a Taxonomy provided.
+ if ( empty( $term ) )
+ return true;
+
+ return isset( $queried_object->term_id ) &&
+ count( array_intersect(
+ array( $queried_object->term_id, $queried_object->name, $queried_object->slug ),
+ $term_array
+ ) );
+ }
+
+ /**
+ * Whether the current URL is within the comments popup window.
+ *
+ * @since 3.1.0
+ * @deprecated 4.5.0
+ *
+ * @return bool
+ */
+ public function is_comments_popup() {
+ _deprecated_function( __FUNCTION__, '4.5.0' );
+
+ return false;
+ }
+
+ /**
+ * Is the query for an existing date archive?
+ *
+ * @since 3.1.0
+ *
+ * @return bool
+ */
+ public function is_date() {
+ return (bool) $this->is_date;
+ }
+
+ /**
+ * Is the query for an existing day archive?
+ *
+ * @since 3.1.0
+ *
+ * @return bool
+ */
+ public function is_day() {
+ return (bool) $this->is_day;
+ }
+
+ /**
+ * Is the query for a feed?
+ *
+ * @since 3.1.0
+ *
+ * @param string|array $feeds Optional feed types to check.
+ * @return bool
+ */
+ public function is_feed( $feeds = '' ) {
+ if ( empty( $feeds ) || ! $this->is_feed )
+ return (bool) $this->is_feed;
+ $qv = $this->get( 'feed' );
+ if ( 'feed' == $qv )
+ $qv = get_default_feed();
+ return in_array( $qv, (array) $feeds );
+ }
+
+ /**
+ * Is the query for a comments feed?
+ *
+ * @since 3.1.0
+ *
+ * @return bool
+ */
+ public function is_comment_feed() {
+ return (bool) $this->is_comment_feed;
+ }
+
+ /**
+ * Is the query for the front page of the site?
+ *
+ * This is for what is displayed at your site's main URL.
+ *
+ * Depends on the site's "Front page displays" Reading Settings 'show_on_front' and 'page_on_front'.
+ *
+ * If you set a static page for the front page of your site, this function will return
+ * true when viewing that page.
+ *
+ * Otherwise the same as @see WP_Query::is_home()
+ *
+ * @since 3.1.0
+ *
+ * @return bool True, if front of site.
+ */
+ public function is_front_page() {
+ // most likely case
+ if ( 'posts' == get_option( 'show_on_front') && $this->is_home() )
+ return true;
+ elseif ( 'page' == get_option( 'show_on_front') && get_option( 'page_on_front' ) && $this->is_page( get_option( 'page_on_front' ) ) )
+ return true;
+ else
+ return false;
+ }
+
+ /**
+ * Is the query for the blog homepage?
+ *
+ * This is the page which shows the time based blog content of your site.
+ *
+ * Depends on the site's "Front page displays" Reading Settings 'show_on_front' and 'page_for_posts'.
+ *
+ * If you set a static page for the front page of your site, this function will return
+ * true only on the page you set as the "Posts page".
+ *
+ * @see WP_Query::is_front_page()
+ *
+ * @since 3.1.0
+ *
+ * @return bool True if blog view homepage.
+ */
+ public function is_home() {
+ return (bool) $this->is_home;
+ }
+
+ /**
+ * Is the query for an existing month archive?
+ *
+ * @since 3.1.0
+ *
+ * @return bool
+ */
+ public function is_month() {
+ return (bool) $this->is_month;
+ }
+
+ /**
+ * Is the query for an existing single page?
+ *
+ * If the $page parameter is specified, this function will additionally
+ * check if the query is for one of the pages specified.
+ *
+ * @see WP_Query::is_single()
+ * @see WP_Query::is_singular()
+ *
+ * @since 3.1.0
+ *
+ * @param int|string|array $page Optional. Page ID, title, slug, path, or array of such. Default empty.
+ * @return bool Whether the query is for an existing single page.
+ */
+ public function is_page( $page = '' ) {
+ if ( !$this->is_page )
+ return false;
+
+ if ( empty( $page ) )
+ return true;
+
+ $page_obj = $this->get_queried_object();
+
+ $page = array_map( 'strval', (array) $page );
+
+ if ( in_array( (string) $page_obj->ID, $page ) ) {
+ return true;
+ } elseif ( in_array( $page_obj->post_title, $page ) ) {
+ return true;
+ } elseif ( in_array( $page_obj->post_name, $page ) ) {
+ return true;
+ } else {
+ foreach ( $page as $pagepath ) {
+ if ( ! strpos( $pagepath, '/' ) ) {
+ continue;
+ }
+ $pagepath_obj = get_page_by_path( $pagepath );
+
+ if ( $pagepath_obj && ( $pagepath_obj->ID == $page_obj->ID ) ) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Is the query for paged result and not for the first page?
+ *
+ * @since 3.1.0
+ *
+ * @return bool
+ */
+ public function is_paged() {
+ return (bool) $this->is_paged;
+ }
+
+ /**
+ * Is the query for a post or page preview?
+ *
+ * @since 3.1.0
+ *
+ * @return bool
+ */
+ public function is_preview() {
+ return (bool) $this->is_preview;
+ }
+
+ /**
+ * Is the query for the robots file?
+ *
+ * @since 3.1.0
+ *
+ * @return bool
+ */
+ public function is_robots() {
+ return (bool) $this->is_robots;
+ }
+
+ /**
+ * Is the query for a search?
+ *
+ * @since 3.1.0
+ *
+ * @return bool
+ */
+ public function is_search() {
+ return (bool) $this->is_search;
+ }
+
+ /**
+ * Is the query for an existing single post?
+ *
+ * Works for any post type excluding pages.
+ *
+ * If the $post parameter is specified, this function will additionally
+ * check if the query is for one of the Posts specified.
+ *
+ * @see WP_Query::is_page()
+ * @see WP_Query::is_singular()
+ *
+ * @since 3.1.0
+ *
+ * @param int|string|array $post Optional. Post ID, title, slug, path, or array of such. Default empty.
+ * @return bool Whether the query is for an existing single post.
+ */
+ public function is_single( $post = '' ) {
+ if ( !$this->is_single )
+ return false;
+
+ if ( empty($post) )
+ return true;
+
+ $post_obj = $this->get_queried_object();
+
+ $post = array_map( 'strval', (array) $post );
+
+ if ( in_array( (string) $post_obj->ID, $post ) ) {
+ return true;
+ } elseif ( in_array( $post_obj->post_title, $post ) ) {
+ return true;
+ } elseif ( in_array( $post_obj->post_name, $post ) ) {
+ return true;
+ } else {
+ foreach ( $post as $postpath ) {
+ if ( ! strpos( $postpath, '/' ) ) {
+ continue;
+ }
+ $postpath_obj = get_page_by_path( $postpath, OBJECT, $post_obj->post_type );
+
+ if ( $postpath_obj && ( $postpath_obj->ID == $post_obj->ID ) ) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Is the query for an existing single post of any post type (post, attachment, page, ... )?
+ *
+ * If the $post_types parameter is specified, this function will additionally
+ * check if the query is for one of the Posts Types specified.
+ *
+ * @see WP_Query::is_page()
+ * @see WP_Query::is_single()
+ *
+ * @since 3.1.0
+ *
+ * @param string|array $post_types Optional. Post type or array of post types. Default empty.
+ * @return bool Whether the query is for an existing single post of any of the given post types.
+ */
+ public function is_singular( $post_types = '' ) {
+ if ( empty( $post_types ) || !$this->is_singular )
+ return (bool) $this->is_singular;
+
+ $post_obj = $this->get_queried_object();
+
+ return in_array( $post_obj->post_type, (array) $post_types );
+ }
+
+ /**
+ * Is the query for a specific time?
+ *
+ * @since 3.1.0
+ *
+ * @return bool
+ */
+ public function is_time() {
+ return (bool) $this->is_time;
+ }
+
+ /**
+ * Is the query for a trackback endpoint call?
+ *
+ * @since 3.1.0
+ *
+ * @return bool
+ */
+ public function is_trackback() {
+ return (bool) $this->is_trackback;
+ }
+
+ /**
+ * Is the query for an existing year archive?
+ *
+ * @since 3.1.0
+ *
+ * @return bool
+ */
+ public function is_year() {
+ return (bool) $this->is_year;
+ }
+
+ /**
+ * Is the query a 404 (returns no results)?
+ *
+ * @since 3.1.0
+ *
+ * @return bool
+ */
+ public function is_404() {
+ return (bool) $this->is_404;
+ }
+
+ /**
+ * Is the query for an embedded post?
+ *
+ * @since 4.4.0
+ *
+ * @return bool
+ */
+ public function is_embed() {
+ return (bool) $this->is_embed;
+ }
+
+ /**
+ * Is the query the main query?
+ *
+ * @since 3.3.0
+ *
+ * @global WP_Query $wp_query Global WP_Query instance.
+ *
+ * @return bool
+ */
+ public function is_main_query() {
+ global $wp_the_query;
+ return $wp_the_query === $this;
+ }
+
+ /**
+ * Set up global post data.
+ *
+ * @since 4.1.0
+ * @since 4.4.0 Added the ability to pass a post ID to `$post`.
+ *
+ * @global int $id
+ * @global WP_User $authordata
+ * @global string|int|bool $currentday
+ * @global string|int|bool $currentmonth
+ * @global int $page
+ * @global array $pages
+ * @global int $multipage
+ * @global int $more
+ * @global int $numpages
+ *
+ * @param WP_Post|object|int $post WP_Post instance or Post ID/object.
+ * @return true True when finished.
+ */
+ public function setup_postdata( $post ) {
+ global $id, $authordata, $currentday, $currentmonth, $page, $pages, $multipage, $more, $numpages;
+
+ if ( ! ( $post instanceof WP_Post ) ) {
+ $post = get_post( $post );
+ }
+
+ if ( ! $post ) {
+ return;
+ }
+
+ $id = (int) $post->ID;
+
+ $authordata = get_userdata($post->post_author);
+
+ $currentday = mysql2date('d.m.y', $post->post_date, false);
+ $currentmonth = mysql2date('m', $post->post_date, false);
+ $numpages = 1;
+ $multipage = 0;
+ $page = $this->get( 'page' );
+ if ( ! $page )
+ $page = 1;
+
+ /*
+ * Force full post content when viewing the permalink for the $post,
+ * or when on an RSS feed. Otherwise respect the 'more' tag.
+ */
+ if ( $post->ID === get_queried_object_id() && ( $this->is_page() || $this->is_single() ) ) {
+ $more = 1;
+ } elseif ( $this->is_feed() ) {
+ $more = 1;
+ } else {
+ $more = 0;
+ }
+
+ $content = $post->post_content;
+ if ( false !== strpos( $content, '' ) ) {
+ $content = str_replace( "\n\n", '', $content );
+ $content = str_replace( "\n", '', $content );
+ $content = str_replace( "\n", '', $content );
+
+ // Ignore nextpage at the beginning of the content.
+ if ( 0 === strpos( $content, '' ) )
+ $content = substr( $content, 15 );
+
+ $pages = explode('', $content);
+ } else {
+ $pages = array( $post->post_content );
+ }
+
+ /**
+ * Filters the "pages" derived from splitting the post content.
+ *
+ * "Pages" are determined by splitting the post content based on the presence
+ * of `` tags.
+ *
+ * @since 4.4.0
+ *
+ * @param array $pages Array of "pages" derived from the post content.
+ * of `` tags..
+ * @param WP_Post $post Current post object.
+ */
+ $pages = apply_filters( 'content_pagination', $pages, $post );
+
+ $numpages = count( $pages );
+
+ if ( $numpages > 1 ) {
+ if ( $page > 1 ) {
+ $more = 1;
+ }
+ $multipage = 1;
+ } else {
+ $multipage = 0;
+ }
+
+ /**
+ * Fires once the post data has been setup.
+ *
+ * @since 2.8.0
+ * @since 4.1.0 Introduced `$this` parameter.
+ *
+ * @param WP_Post &$post The Post object (passed by reference).
+ * @param WP_Query &$this The current Query object (passed by reference).
+ */
+ do_action_ref_array( 'the_post', array( &$post, &$this ) );
+
+ return true;
+ }
+ /**
+ * After looping through a nested query, this function
+ * restores the $post global to the current post in this query.
+ *
+ * @since 3.7.0
+ *
+ * @global WP_Post $post
+ */
+ public function reset_postdata() {
+ if ( ! empty( $this->post ) ) {
+ $GLOBALS['post'] = $this->post;
+ $this->setup_postdata( $this->post );
+ }
+ }
+
+ /**
+ * Lazyload term meta for posts in the loop.
+ *
+ * @since 4.4.0
+ * @deprecated 4.5.0 See wp_queue_posts_for_term_meta_lazyload().
+ *
+ * @param mixed $check
+ * @param int $term_id
+ * @return mixed
+ */
+ public function lazyload_term_meta( $check, $term_id ) {
+ _deprecated_function( __METHOD__, '4.5.0' );
+ return $check;
+ }
+
+ /**
+ * Lazyload comment meta for comments in the loop.
+ *
+ * @since 4.4.0
+ * @deprecated 4.5.0 See wp_queue_comments_for_comment_meta_lazyload().
+ *
+ * @param mixed $check
+ * @param int $comment_id
+ * @return mixed
+ */
+ public function lazyload_comment_meta( $check, $comment_id ) {
+ _deprecated_function( __METHOD__, '4.5.0' );
+ return $check;
+ }
+}
diff --git a/code/wp-includes/class-wp-rewrite.php b/code/wp-includes/class-wp-rewrite.php
index 2c576156..17c58b90 100644
--- a/code/wp-includes/class-wp-rewrite.php
+++ b/code/wp-includes/class-wp-rewrite.php
@@ -1413,7 +1413,7 @@ public function rewrite_rules() {
*
* @param array $rules The rewrite rules generated for the current permastruct.
*/
- $rules = apply_filters( $permastructname . '_rewrite_rules', $rules );
+ $rules = apply_filters( "{$permastructname}_rewrite_rules", $rules );
if ( 'post_tag' == $permastructname ) {
/**
@@ -1475,6 +1475,10 @@ public function wp_rewrite_rules() {
if ( empty($this->rules) ) {
$this->matches = 'matches';
$this->rewrite_rules();
+ if ( ! did_action( 'wp_loaded' ) ) {
+ add_action( 'wp_loaded', array( $this, 'flush_rules' ) );
+ return $this->rules;
+ }
update_option('rewrite_rules', $this->rules);
}
diff --git a/code/wp-includes/class-wp-roles.php b/code/wp-includes/class-wp-roles.php
index ff733e22..23e05d7b 100644
--- a/code/wp-includes/class-wp-roles.php
+++ b/code/wp-includes/class-wp-roles.php
@@ -105,11 +105,11 @@ public function __call( $name, $arguments ) {
* @since 2.1.0
* @access protected
*
- * @global wpdb $wpdb WordPress database abstraction object.
* @global array $wp_user_roles Used to set the 'roles' property value.
*/
protected function _init() {
- global $wpdb, $wp_user_roles;
+ global $wp_user_roles, $wpdb;
+
$this->role_key = $wpdb->get_blog_prefix() . 'user_roles';
if ( ! empty( $wp_user_roles ) ) {
$this->roles = $wp_user_roles;
@@ -127,6 +127,15 @@ protected function _init() {
$this->role_objects[$role] = new WP_Role( $role, $this->roles[$role]['capabilities'] );
$this->role_names[$role] = $this->roles[$role]['name'];
}
+
+ /**
+ * After the roles have been initialized, allow plugins to add their own roles.
+ *
+ * @since 4.7.0
+ *
+ * @param WP_Roles $this A reference to the WP_Roles object.
+ */
+ do_action( 'wp_roles_init', $this );
}
/**
@@ -136,29 +145,12 @@ protected function _init() {
* after switching wpdb to a new site ID.
*
* @since 3.5.0
+ * @deprecated 4.7.0 Use new WP_Roles()
* @access public
- *
- * @global wpdb $wpdb WordPress database abstraction object.
*/
public function reinit() {
- // There is no need to reinit if using the wp_user_roles global.
- if ( ! $this->use_db )
- return;
-
- global $wpdb;
-
- // Duplicated from _init() to avoid an extra function call.
- $this->role_key = $wpdb->get_blog_prefix() . 'user_roles';
- $this->roles = get_option( $this->role_key );
- if ( empty( $this->roles ) )
- return;
-
- $this->role_objects = array();
- $this->role_names = array();
- foreach ( array_keys( $this->roles ) as $role ) {
- $this->role_objects[$role] = new WP_Role( $role, $this->roles[$role]['capabilities'] );
- $this->role_names[$role] = $this->roles[$role]['name'];
- }
+ _deprecated_function( __METHOD__, '4.7.0', 'new WP_Roles()' );
+ $this->_init();
}
/**
diff --git a/code/wp-includes/class-wp-session-tokens.php b/code/wp-includes/class-wp-session-tokens.php
new file mode 100644
index 00000000..2f498b84
--- /dev/null
+++ b/code/wp-includes/class-wp-session-tokens.php
@@ -0,0 +1,317 @@
+user_id = $user_id;
+ }
+
+ /**
+ * Get a session token manager instance for a user.
+ *
+ * This method contains a filter that allows a plugin to swap out
+ * the session manager for a subclass of WP_Session_Tokens.
+ *
+ * @since 4.0.0
+ * @access public
+ * @static
+ *
+ * @param int $user_id User whose session to manage.
+ */
+ final public static function get_instance( $user_id ) {
+ /**
+ * Filters the session token manager used.
+ *
+ * @since 4.0.0
+ *
+ * @param string $session Name of class to use as the manager.
+ * Default 'WP_User_Meta_Session_Tokens'.
+ */
+ $manager = apply_filters( 'session_token_manager', 'WP_User_Meta_Session_Tokens' );
+ return new $manager( $user_id );
+ }
+
+ /**
+ * Hashes a session token for storage.
+ *
+ * @since 4.0.0
+ * @access private
+ *
+ * @param string $token Session token to hash.
+ * @return string A hash of the session token (a verifier).
+ */
+ final private function hash_token( $token ) {
+ // If ext/hash is not present, use sha1() instead.
+ if ( function_exists( 'hash' ) ) {
+ return hash( 'sha256', $token );
+ } else {
+ return sha1( $token );
+ }
+ }
+
+ /**
+ * Get a user's session.
+ *
+ * @since 4.0.0
+ * @access public
+ *
+ * @param string $token Session token
+ * @return array User session
+ */
+ final public function get( $token ) {
+ $verifier = $this->hash_token( $token );
+ return $this->get_session( $verifier );
+ }
+
+ /**
+ * Validate a user's session token as authentic.
+ *
+ * Checks that the given token is present and hasn't expired.
+ *
+ * @since 4.0.0
+ * @access public
+ *
+ * @param string $token Token to verify.
+ * @return bool Whether the token is valid for the user.
+ */
+ final public function verify( $token ) {
+ $verifier = $this->hash_token( $token );
+ return (bool) $this->get_session( $verifier );
+ }
+
+ /**
+ * Generate a session token and attach session information to it.
+ *
+ * A session token is a long, random string. It is used in a cookie
+ * link that cookie to an expiration time and to ensure the cookie
+ * becomes invalidated upon logout.
+ *
+ * This function generates a token and stores it with the associated
+ * expiration time (and potentially other session information via the
+ * {@see 'attach_session_information'} filter).
+ *
+ * @since 4.0.0
+ * @access public
+ *
+ * @param int $expiration Session expiration timestamp.
+ * @return string Session token.
+ */
+ final public function create( $expiration ) {
+ /**
+ * Filters the information attached to the newly created session.
+ *
+ * Could be used in the future to attach information such as
+ * IP address or user agent to a session.
+ *
+ * @since 4.0.0
+ *
+ * @param array $session Array of extra data.
+ * @param int $user_id User ID.
+ */
+ $session = apply_filters( 'attach_session_information', array(), $this->user_id );
+ $session['expiration'] = $expiration;
+
+ // IP address.
+ if ( !empty( $_SERVER['REMOTE_ADDR'] ) ) {
+ $session['ip'] = $_SERVER['REMOTE_ADDR'];
+ }
+
+ // User-agent.
+ if ( ! empty( $_SERVER['HTTP_USER_AGENT'] ) ) {
+ $session['ua'] = wp_unslash( $_SERVER['HTTP_USER_AGENT'] );
+ }
+
+ // Timestamp
+ $session['login'] = time();
+
+ $token = wp_generate_password( 43, false, false );
+
+ $this->update( $token, $session );
+
+ return $token;
+ }
+
+ /**
+ * Update a session token.
+ *
+ * @since 4.0.0
+ * @access public
+ *
+ * @param string $token Session token to update.
+ * @param array $session Session information.
+ */
+ final public function update( $token, $session ) {
+ $verifier = $this->hash_token( $token );
+ $this->update_session( $verifier, $session );
+ }
+
+ /**
+ * Destroy a session token.
+ *
+ * @since 4.0.0
+ * @access public
+ *
+ * @param string $token Session token to destroy.
+ */
+ final public function destroy( $token ) {
+ $verifier = $this->hash_token( $token );
+ $this->update_session( $verifier, null );
+ }
+
+ /**
+ * Destroy all session tokens for this user,
+ * except a single token, presumably the one in use.
+ *
+ * @since 4.0.0
+ * @access public
+ *
+ * @param string $token_to_keep Session token to keep.
+ */
+ final public function destroy_others( $token_to_keep ) {
+ $verifier = $this->hash_token( $token_to_keep );
+ $session = $this->get_session( $verifier );
+ if ( $session ) {
+ $this->destroy_other_sessions( $verifier );
+ } else {
+ $this->destroy_all_sessions();
+ }
+ }
+
+ /**
+ * Determine whether a session token is still valid,
+ * based on expiration.
+ *
+ * @since 4.0.0
+ * @access protected
+ *
+ * @param array $session Session to check.
+ * @return bool Whether session is valid.
+ */
+ final protected function is_still_valid( $session ) {
+ return $session['expiration'] >= time();
+ }
+
+ /**
+ * Destroy all session tokens for a user.
+ *
+ * @since 4.0.0
+ * @access public
+ */
+ final public function destroy_all() {
+ $this->destroy_all_sessions();
+ }
+
+ /**
+ * Destroy all session tokens for all users.
+ *
+ * @since 4.0.0
+ * @access public
+ * @static
+ */
+ final public static function destroy_all_for_all_users() {
+ $manager = apply_filters( 'session_token_manager', 'WP_User_Meta_Session_Tokens' );
+ call_user_func( array( $manager, 'drop_sessions' ) );
+ }
+
+ /**
+ * Retrieve all sessions of a user.
+ *
+ * @since 4.0.0
+ * @access public
+ *
+ * @return array Sessions of a user.
+ */
+ final public function get_all() {
+ return array_values( $this->get_sessions() );
+ }
+
+ /**
+ * This method should retrieve all sessions of a user, keyed by verifier.
+ *
+ * @since 4.0.0
+ * @access protected
+ *
+ * @return array Sessions of a user, keyed by verifier.
+ */
+ abstract protected function get_sessions();
+
+ /**
+ * This method should look up a session by its verifier (token hash).
+ *
+ * @since 4.0.0
+ * @access protected
+ *
+ * @param string $verifier Verifier of the session to retrieve.
+ * @return array|null The session, or null if it does not exist.
+ */
+ abstract protected function get_session( $verifier );
+
+ /**
+ * This method should update a session by its verifier.
+ *
+ * Omitting the second argument should destroy the session.
+ *
+ * @since 4.0.0
+ * @access protected
+ *
+ * @param string $verifier Verifier of the session to update.
+ * @param array $session Optional. Session. Omitting this argument destroys the session.
+ */
+ abstract protected function update_session( $verifier, $session = null );
+
+ /**
+ * This method should destroy all session tokens for this user,
+ * except a single session passed.
+ *
+ * @since 4.0.0
+ * @access protected
+ *
+ * @param string $verifier Verifier of the session to keep.
+ */
+ abstract protected function destroy_other_sessions( $verifier );
+
+ /**
+ * This method should destroy all sessions for a user.
+ *
+ * @since 4.0.0
+ * @access protected
+ */
+ abstract protected function destroy_all_sessions();
+
+ /**
+ * This static method should destroy all session tokens for all users.
+ *
+ * @since 4.0.0
+ * @access public
+ * @static
+ */
+ public static function drop_sessions() {}
+}
diff --git a/code/wp-includes/class-wp-simplepie-file.php b/code/wp-includes/class-wp-simplepie-file.php
new file mode 100644
index 00000000..b87df7d9
--- /dev/null
+++ b/code/wp-includes/class-wp-simplepie-file.php
@@ -0,0 +1,72 @@
+url = $url;
+ $this->timeout = $timeout;
+ $this->redirects = $redirects;
+ $this->headers = $headers;
+ $this->useragent = $useragent;
+
+ $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE;
+
+ if ( preg_match('/^http(s)?:\/\//i', $url) ) {
+ $args = array(
+ 'timeout' => $this->timeout,
+ 'redirection' => $this->redirects,
+ );
+
+ if ( !empty($this->headers) )
+ $args['headers'] = $this->headers;
+
+ if ( SIMPLEPIE_USERAGENT != $this->useragent ) //Use default WP user agent unless custom has been specified
+ $args['user-agent'] = $this->useragent;
+
+ $res = wp_safe_remote_request($url, $args);
+
+ if ( is_wp_error($res) ) {
+ $this->error = 'WP HTTP Error: ' . $res->get_error_message();
+ $this->success = false;
+ } else {
+ $this->headers = wp_remote_retrieve_headers( $res );
+ $this->body = wp_remote_retrieve_body( $res );
+ $this->status_code = wp_remote_retrieve_response_code( $res );
+ }
+ } else {
+ $this->error = '';
+ $this->success = false;
+ }
+ }
+}
diff --git a/code/wp-includes/class-wp-simplepie-sanitize-kses.php b/code/wp-includes/class-wp-simplepie-sanitize-kses.php
new file mode 100644
index 00000000..dce5edce
--- /dev/null
+++ b/code/wp-includes/class-wp-simplepie-sanitize-kses.php
@@ -0,0 +1,59 @@
+)/', $data)) {
+ $type |= SIMPLEPIE_CONSTRUCT_HTML;
+ }
+ else {
+ $type |= SIMPLEPIE_CONSTRUCT_TEXT;
+ }
+ }
+ if ( $type & SIMPLEPIE_CONSTRUCT_BASE64 ) {
+ $data = base64_decode( $data );
+ }
+ if ( $type & ( SIMPLEPIE_CONSTRUCT_HTML | SIMPLEPIE_CONSTRUCT_XHTML ) ) {
+ $data = wp_kses_post( $data );
+ if ( $this->output_encoding !== 'UTF-8' ) {
+ $data = $this->registry->call( 'Misc', 'change_encoding', array( $data, 'UTF-8', $this->output_encoding ) );
+ }
+ return $data;
+ } else {
+ return parent::sanitize( $data, $type, $base );
+ }
+ }
+}
diff --git a/code/wp-includes/class-wp-site-query.php b/code/wp-includes/class-wp-site-query.php
index cbffd664..8f52372d 100644
--- a/code/wp-includes/class-wp-site-query.php
+++ b/code/wp-includes/class-wp-site-query.php
@@ -113,7 +113,7 @@ class WP_Site_Query {
* @type string $fields Site fields to return. Accepts 'ids' (returns an array of site IDs)
* or empty (returns an array of complete site objects). Default empty.
* @type int $ID A site ID to only return that site. Default empty.
- * @type int $number Maximum number of sites to retrieve. Default null (no limit).
+ * @type int $number Maximum number of sites to retrieve. Default 100.
* @type int $offset Number of sites to offset the query. Used to build LIMIT clause.
* Default 0.
* @type bool $no_found_rows Whether to disable the `SQL_CALC_FOUND_ROWS` query. Default true.
@@ -127,12 +127,10 @@ class WP_Site_Query {
* include all networks. Default 0.
* @type array $network__in Array of network IDs to include affiliated sites for. Default empty.
* @type array $network__not_in Array of network IDs to exclude affiliated sites for. Default empty.
- * @type string $domain Limit results to those affiliated with a given domain.
- * Default empty.
+ * @type string $domain Limit results to those affiliated with a given domain. Default empty.
* @type array $domain__in Array of domains to include affiliated sites for. Default empty.
* @type array $domain__not_in Array of domains to exclude affiliated sites for. Default empty.
- * @type string $path Limit results to those affiliated with a given path.
- * Default empty.
+ * @type string $path Limit results to those affiliated with a given path. Default empty.
* @type array $path__in Array of paths to include affiliated sites for. Default empty.
* @type array $path__not_in Array of paths to exclude affiliated sites for. Default empty.
* @type int $public Limit results to public sites. Accepts '1' or '0'. Default empty.
@@ -247,11 +245,7 @@ public function get_sites() {
// $args can include anything. Only use the args defined in the query_var_defaults to compute the key.
$key = md5( serialize( wp_array_slice_assoc( $this->query_vars, array_keys( $this->query_var_defaults ) ) ) );
- $last_changed = wp_cache_get( 'last_changed', 'sites' );
- if ( ! $last_changed ) {
- $last_changed = microtime();
- wp_cache_set( 'last_changed', $last_changed, 'sites' );
- }
+ $last_changed = wp_cache_get_last_changed( 'sites' );
$cache_key = "get_sites:$key:$last_changed";
$cache_value = wp_cache_get( $cache_key, 'sites' );
@@ -511,6 +505,8 @@ protected function get_site_ids() {
$this->sql_clauses['where']['date_query'] = preg_replace( '/^\s*AND\s*/', '', $this->date_query->get_sql() );
}
+ $join = '';
+
$where = implode( ' AND ', $this->sql_clauses['where'] );
$pieces = array( 'fields', 'join', 'where', 'orderby', 'limits', 'groupby' );
diff --git a/code/wp-includes/class-wp-site.php b/code/wp-includes/class-wp-site.php
index a250c8d0..53529fe9 100644
--- a/code/wp-includes/class-wp-site.php
+++ b/code/wp-includes/class-wp-site.php
@@ -15,8 +15,12 @@
*
* @since 4.5.0
*
- * @property int $id
- * @property int $network_id
+ * @property int $id
+ * @property int $network_id
+ * @property string $blogname
+ * @property string $siteurl
+ * @property int $post_count
+ * @property string $home
*/
final class WP_Site {
@@ -310,7 +314,7 @@ public function __set( $key, $value ) {
*
* @see WP_Site::__get()
*
- * @return object A raw site object with all details included.
+ * @return stdClass A raw site object with all details included.
*/
private function get_details() {
$details = wp_cache_get( $this->blog_id, 'site-details' );
@@ -342,12 +346,15 @@ private function get_details() {
}
}
+ /** This filter is documented in wp-includes/ms-blogs.php */
+ $details = apply_filters_deprecated( 'blog_details', array( $details ), '4.7.0', 'site_details' );
+
/**
* Filters a site's extended properties.
*
* @since 4.6.0
*
- * @param object $details The site details.
+ * @param stdClass $details The site details.
*/
$details = apply_filters( 'site_details', $details );
diff --git a/code/wp-includes/class-wp-taxonomy.php b/code/wp-includes/class-wp-taxonomy.php
new file mode 100644
index 00000000..4611ce97
--- /dev/null
+++ b/code/wp-includes/class-wp-taxonomy.php
@@ -0,0 +1,416 @@
+name = $taxonomy;
+
+ $this->set_props( $object_type, $args );
+ }
+
+ /**
+ * Sets taxonomy properties.
+ *
+ * @since 4.7.0
+ * @access public
+ *
+ * @param array|string $object_type Name of the object type for the taxonomy object.
+ * @param array|string $args Array or query string of arguments for registering a taxonomy.
+ */
+ public function set_props( $object_type, $args ) {
+ $args = wp_parse_args( $args );
+
+ /**
+ * Filters the arguments for registering a taxonomy.
+ *
+ * @since 4.4.0
+ *
+ * @param array $args Array of arguments for registering a taxonomy.
+ * @param string $taxonomy Taxonomy key.
+ * @param array $object_type Array of names of object types for the taxonomy.
+ */
+ $args = apply_filters( 'register_taxonomy_args', $args, $this->name, (array) $object_type );
+
+ $defaults = array(
+ 'labels' => array(),
+ 'description' => '',
+ 'public' => true,
+ 'publicly_queryable' => null,
+ 'hierarchical' => false,
+ 'show_ui' => null,
+ 'show_in_menu' => null,
+ 'show_in_nav_menus' => null,
+ 'show_tagcloud' => null,
+ 'show_in_quick_edit' => null,
+ 'show_admin_column' => false,
+ 'meta_box_cb' => null,
+ 'capabilities' => array(),
+ 'rewrite' => true,
+ 'query_var' => $this->name,
+ 'update_count_callback' => '',
+ '_builtin' => false,
+ );
+
+ $args = array_merge( $defaults, $args );
+
+ // If not set, default to the setting for public.
+ if ( null === $args['publicly_queryable'] ) {
+ $args['publicly_queryable'] = $args['public'];
+ }
+
+ if ( false !== $args['query_var'] && ( is_admin() || false !== $args['publicly_queryable'] ) ) {
+ if ( true === $args['query_var'] ) {
+ $args['query_var'] = $this->name;
+ } else {
+ $args['query_var'] = sanitize_title_with_dashes( $args['query_var'] );
+ }
+ } else {
+ // Force query_var to false for non-public taxonomies.
+ $args['query_var'] = false;
+ }
+
+ if ( false !== $args['rewrite'] && ( is_admin() || '' != get_option( 'permalink_structure' ) ) ) {
+ $args['rewrite'] = wp_parse_args( $args['rewrite'], array(
+ 'with_front' => true,
+ 'hierarchical' => false,
+ 'ep_mask' => EP_NONE,
+ ) );
+
+ if ( empty( $args['rewrite']['slug'] ) ) {
+ $args['rewrite']['slug'] = sanitize_title_with_dashes( $this->name );
+ }
+ }
+
+ // If not set, default to the setting for public.
+ if ( null === $args['show_ui'] ) {
+ $args['show_ui'] = $args['public'];
+ }
+
+ // If not set, default to the setting for show_ui.
+ if ( null === $args['show_in_menu'] || ! $args['show_ui'] ) {
+ $args['show_in_menu'] = $args['show_ui'];
+ }
+
+ // If not set, default to the setting for public.
+ if ( null === $args['show_in_nav_menus'] ) {
+ $args['show_in_nav_menus'] = $args['public'];
+ }
+
+ // If not set, default to the setting for show_ui.
+ if ( null === $args['show_tagcloud'] ) {
+ $args['show_tagcloud'] = $args['show_ui'];
+ }
+
+ // If not set, default to the setting for show_ui.
+ if ( null === $args['show_in_quick_edit'] ) {
+ $args['show_in_quick_edit'] = $args['show_ui'];
+ }
+
+ $default_caps = array(
+ 'manage_terms' => 'manage_categories',
+ 'edit_terms' => 'manage_categories',
+ 'delete_terms' => 'manage_categories',
+ 'assign_terms' => 'edit_posts',
+ );
+
+ $args['cap'] = (object) array_merge( $default_caps, $args['capabilities'] );
+ unset( $args['capabilities'] );
+
+ $args['object_type'] = array_unique( (array) $object_type );
+
+ // If not set, use the default meta box
+ if ( null === $args['meta_box_cb'] ) {
+ if ( $args['hierarchical'] ) {
+ $args['meta_box_cb'] = 'post_categories_meta_box';
+ } else {
+ $args['meta_box_cb'] = 'post_tags_meta_box';
+ }
+ }
+
+ foreach ( $args as $property_name => $property_value ) {
+ $this->$property_name = $property_value;
+ }
+
+ $this->labels = get_taxonomy_labels( $this );
+ $this->label = $this->labels->name;
+ }
+
+ /**
+ * Adds the necessary rewrite rules for the taxonomy.
+ *
+ * @since 4.7.0
+ * @access public
+ *
+ * @global WP $wp Current WordPress environment instance.
+ */
+ public function add_rewrite_rules() {
+ /* @var WP $wp */
+ global $wp;
+
+ // Non-publicly queryable taxonomies should not register query vars, except in the admin.
+ if ( false !== $this->query_var && $wp ) {
+ $wp->add_query_var( $this->query_var );
+ }
+
+ if ( false !== $this->rewrite && ( is_admin() || '' != get_option( 'permalink_structure' ) ) ) {
+ if ( $this->hierarchical && $this->rewrite['hierarchical'] ) {
+ $tag = '(.+?)';
+ } else {
+ $tag = '([^/]+)';
+ }
+
+ add_rewrite_tag( "%$this->name%", $tag, $this->query_var ? "{$this->query_var}=" : "taxonomy=$this->name&term=" );
+ add_permastruct( $this->name, "{$this->rewrite['slug']}/%$this->name%", $this->rewrite );
+ }
+ }
+
+ /**
+ * Removes any rewrite rules, permastructs, and rules for the taxonomy.
+ *
+ * @since 4.7.0
+ * @access public
+ *
+ * @global WP $wp Current WordPress environment instance.
+ */
+ public function remove_rewrite_rules() {
+ /* @var WP $wp */
+ global $wp;
+
+ // Remove query var.
+ if ( false !== $this->query_var ) {
+ $wp->remove_query_var( $this->query_var );
+ }
+
+ // Remove rewrite tags and permastructs.
+ if ( false !== $this->rewrite ) {
+ remove_rewrite_tag( "%$this->name%" );
+ remove_permastruct( $this->name );
+ }
+ }
+
+ /**
+ * Registers the ajax callback for the meta box.
+ *
+ * @since 4.7.0
+ * @access public
+ */
+ public function add_hooks() {
+ add_filter( 'wp_ajax_add-' . $this->name, '_wp_ajax_add_hierarchical_term' );
+ }
+
+ /**
+ * Removes the ajax callback for the meta box.
+ *
+ * @since 4.7.0
+ * @access public
+ */
+ public function remove_hooks() {
+ remove_filter( 'wp_ajax_add-' . $this->name, '_wp_ajax_add_hierarchical_term' );
+ }
+}
diff --git a/code/wp-includes/class-wp-term-query.php b/code/wp-includes/class-wp-term-query.php
index 38977f45..434d810d 100644
--- a/code/wp-includes/class-wp-term-query.php
+++ b/code/wp-includes/class-wp-term-query.php
@@ -93,6 +93,7 @@ class WP_Term_Query {
*
* @since 4.6.0
* @since 4.6.0 Introduced 'term_taxonomy_id' parameter.
+ * @since 4.7.0 Introduced 'object_ids' parameter.
* @access public
*
* @param string|array $query {
@@ -100,6 +101,8 @@ class WP_Term_Query {
*
* @type string|array $taxonomy Taxonomy name, or array of taxonomies, to which results should
* be limited.
+ * @type int|array $object_ids Optional. Object ID, or array of object IDs. Results will be
+ * limited to terms associated with these objects.
* @type string $orderby Field(s) to order terms by. Accepts term fields ('name',
* 'slug', 'term_group', 'term_id', 'id', 'description'),
* 'count' for term taxonomy count, 'include' to match the
@@ -123,13 +126,17 @@ class WP_Term_Query {
* positive number. Default ''|0 (all).
* @type int $offset The number by which to offset the terms query. Default empty.
* @type string $fields Term fields to query for. Accepts 'all' (returns an array of
- * complete term objects), 'ids' (returns an array of ids),
- * 'id=>parent' (returns an associative array with ids as keys,
- * parent term IDs as values), 'names' (returns an array of term
- * names), 'count' (returns the number of matching terms),
- * 'id=>name' (returns an associative array with ids as keys,
- * term names as values), or 'id=>slug' (returns an associative
- * array with ids as keys, term slugs as values). Default 'all'.
+ * complete term objects), 'all_with_object_id' (returns an
+ * array of term objects with the 'object_id' param; only works
+ * when the `$fields` parameter is 'object_ids' ), 'ids'
+ * (returns an array of ids), 'tt_ids' (returns an array of
+ * term taxonomy ids), 'id=>parent' (returns an associative
+ * array with ids as keys, parent term IDs as values), 'names'
+ * (returns an array of term names), 'count' (returns the number
+ * of matching terms), 'id=>name' (returns an associative array
+ * with ids as keys, term names as values), or 'id=>slug'
+ * (returns an associative array with ids as keys, term slugs
+ * as values). Default 'all'.
* @type bool $count Whether to return a term count (true) or array of term objects
* (false). Will take precedence over `$fields` if true.
* Default false.
@@ -174,6 +181,7 @@ class WP_Term_Query {
public function __construct( $query = '' ) {
$this->query_var_defaults = array(
'taxonomy' => null,
+ 'object_ids' => null,
'orderby' => 'name',
'order' => 'ASC',
'hide_empty' => true,
@@ -199,6 +207,10 @@ public function __construct( $query = '' ) {
'cache_domain' => 'core',
'update_term_meta_cache' => true,
'meta_query' => '',
+ 'meta_key' => '',
+ 'meta_value' => '',
+ 'meta_type' => '',
+ 'meta_compare' => '',
);
if ( ! empty( $query ) ) {
@@ -253,15 +265,7 @@ public function parse_query( $query = '' ) {
$query['taxonomy'] = $taxonomies;
- /**
- * Filters the terms query arguments.
- *
- * @since 3.1.0
- *
- * @param array $args An array of get_terms() arguments.
- * @param array $taxonomies An array of taxonomies.
- */
- $this->query_vars = apply_filters( 'get_terms_args', $query, $taxonomies );
+ $this->query_vars = $query;
/**
* Fires after term query vars have been parsed.
@@ -383,7 +387,13 @@ public function get_terms() {
}
}
- $orderby = $this->parse_orderby( $this->query_vars['orderby'] );
+ // 'term_order' is a legal sort order only when joining the relationship table.
+ $_orderby = $this->query_vars['orderby'];
+ if ( 'term_order' === $_orderby && empty( $this->query_vars['object_ids'] ) ) {
+ $_orderby = 'term_id';
+ }
+ $orderby = $this->parse_orderby( $_orderby );
+
if ( $orderby ) {
$orderby = "ORDER BY $orderby";
}
@@ -498,6 +508,24 @@ public function get_terms() {
$this->sql_clauses['where']['description__like'] = $wpdb->prepare( "tt.description LIKE %s", '%' . $wpdb->esc_like( $args['description__like'] ) . '%' );
}
+ if ( ! empty( $args['object_ids'] ) ) {
+ $object_ids = $args['object_ids'];
+ if ( ! is_array( $object_ids ) ) {
+ $object_ids = array( $object_ids );
+ }
+
+ $object_ids = implode( ', ', array_map( 'intval', $object_ids ) );
+ $this->sql_clauses['where']['object_ids'] = "tr.object_id IN ($object_ids)";
+ }
+
+ /*
+ * When querying for object relationships, the 'count > 0' check
+ * added by 'hide_empty' is superfluous.
+ */
+ if ( ! empty( $args['object_ids'] ) ) {
+ $args['hide_empty'] = false;
+ }
+
if ( '' !== $parent ) {
$parent = (int) $parent;
$this->sql_clauses['where']['parent'] = "tt.parent = '$parent'";
@@ -549,7 +577,13 @@ public function get_terms() {
$selects = array();
switch ( $args['fields'] ) {
case 'all':
+ case 'all_with_object_id' :
+ case 'tt_ids' :
+ case 'slugs' :
$selects = array( 't.*', 'tt.*' );
+ if ( 'all_with_object_id' === $args['fields'] && ! empty( $args['object_ids'] ) ) {
+ $selects[] = 'tr.object_id';
+ }
break;
case 'ids':
case 'id=>parent':
@@ -593,9 +627,11 @@ public function get_terms() {
$join .= " INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id";
- $where = implode( ' AND ', $this->sql_clauses['where'] );
+ if ( ! empty( $this->query_vars['object_ids'] ) ) {
+ $join .= " INNER JOIN {$wpdb->term_relationships} AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id";
+ }
- $pieces = array( 'fields', 'join', 'where', 'distinct', 'orderby', 'order', 'limits' );
+ $where = implode( ' AND ', $this->sql_clauses['where'] );
/**
* Filters the terms query SQL clauses.
@@ -606,7 +642,7 @@ public function get_terms() {
* @param array $taxonomies An array of taxonomies.
* @param array $args An array of terms query arguments.
*/
- $clauses = apply_filters( 'terms_clauses', compact( $pieces ), $taxonomies, $args );
+ $clauses = apply_filters( 'terms_clauses', compact( 'fields', 'join', 'where', 'distinct', 'orderby', 'order', 'limits' ), $taxonomies, $args );
$fields = isset( $clauses[ 'fields' ] ) ? $clauses[ 'fields' ] : '';
$join = isset( $clauses[ 'join' ] ) ? $clauses[ 'join' ] : '';
@@ -629,11 +665,7 @@ public function get_terms() {
// $args can be anything. Only use the args defined in defaults to compute the key.
$key = md5( serialize( wp_array_slice_assoc( $args, array_keys( $this->query_var_defaults ) ) ) . serialize( $taxonomies ) . $this->request );
- $last_changed = wp_cache_get( 'last_changed', 'terms' );
- if ( ! $last_changed ) {
- $last_changed = microtime();
- wp_cache_set( 'last_changed', $last_changed, 'terms' );
- }
+ $last_changed = wp_cache_get_last_changed( 'terms' );
$cache_key = "get_terms:$key:$last_changed";
$cache = wp_cache_get( $cache_key, 'terms' );
if ( false !== $cache ) {
@@ -646,11 +678,13 @@ public function get_terms() {
}
if ( 'count' == $_fields ) {
- return $wpdb->get_var( $this->request );
+ $count = $wpdb->get_var( $this->request );
+ wp_cache_set( $cache_key, $count, 'terms' );
+ return $count;
}
$terms = $wpdb->get_results( $this->request );
- if ( 'all' == $_fields ) {
+ if ( 'all' == $_fields || 'all_with_object_id' === $_fields ) {
update_term_cache( $terms );
}
@@ -701,6 +735,26 @@ public function get_terms() {
}
}
+ /*
+ * When querying for terms connected to objects, we may get
+ * duplicate results. The duplicates should be preserved if
+ * `$fields` is 'all_with_object_id', but should otherwise be
+ * removed.
+ */
+ if ( ! empty( $args['object_ids'] ) && 'all_with_object_id' != $_fields ) {
+ $_tt_ids = $_terms = array();
+ foreach ( $terms as $term ) {
+ if ( isset( $_tt_ids[ $term->term_id ] ) ) {
+ continue;
+ }
+
+ $_tt_ids[ $term->term_id ] = 1;
+ $_terms[] = $term;
+ }
+
+ $terms = $_terms;
+ }
+
$_terms = array();
if ( 'id=>parent' == $_fields ) {
foreach ( $terms as $term ) {
@@ -708,12 +762,20 @@ public function get_terms() {
}
} elseif ( 'ids' == $_fields ) {
foreach ( $terms as $term ) {
- $_terms[] = $term->term_id;
+ $_terms[] = (int) $term->term_id;
+ }
+ } elseif ( 'tt_ids' == $_fields ) {
+ foreach ( $terms as $term ) {
+ $_terms[] = (int) $term->term_taxonomy_id;
}
} elseif ( 'names' == $_fields ) {
foreach ( $terms as $term ) {
$_terms[] = $term->name;
}
+ } elseif ( 'slugs' == $_fields ) {
+ foreach ( $terms as $term ) {
+ $_terms[] = $term->slug;
+ }
} elseif ( 'id=>name' == $_fields ) {
foreach ( $terms as $term ) {
$_terms[ $term->term_id ] = $term->name;
@@ -739,7 +801,7 @@ public function get_terms() {
wp_cache_add( $cache_key, $terms, 'terms', DAY_IN_SECONDS );
- if ( 'all' === $_fields ) {
+ if ( 'all' === $_fields || 'all_with_object_id' === $_fields ) {
$terms = array_map( 'get_term', $terms );
}
@@ -761,19 +823,16 @@ public function get_terms() {
protected function parse_orderby( $orderby_raw ) {
$_orderby = strtolower( $orderby_raw );
$maybe_orderby_meta = false;
- if ( 'count' == $_orderby ) {
- $orderby = 'tt.count';
- } elseif ( 'name' == $_orderby ) {
- $orderby = 't.name';
- } elseif ( 'slug' == $_orderby ) {
- $orderby = 't.slug';
+
+ if ( in_array( $_orderby, array( 'term_id', 'name', 'slug', 'term_group' ), true ) ) {
+ $orderby = "t.$_orderby";
+ } elseif ( in_array( $_orderby, array( 'count', 'parent', 'taxonomy', 'term_taxonomy_id', 'description' ), true ) ) {
+ $orderby = "tt.$_orderby";
+ } elseif ( 'term_order' === $_orderby ) {
+ $orderby = 'tr.term_order';
} elseif ( 'include' == $_orderby && ! empty( $this->query_vars['include'] ) ) {
- $include = implode( ',', array_map( 'absint', $this->query_vars['include'] ) );
+ $include = implode( ',', wp_parse_id_list( $this->query_vars['include'] ) );
$orderby = "FIELD( t.term_id, $include )";
- } elseif ( 'term_group' == $_orderby ) {
- $orderby = 't.term_group';
- } elseif ( 'description' == $_orderby ) {
- $orderby = 'tt.description';
} elseif ( 'none' == $_orderby ) {
$orderby = '';
} elseif ( empty( $_orderby ) || 'id' == $_orderby || 'term_id' === $_orderby ) {
diff --git a/code/wp-includes/class-wp-term.php b/code/wp-includes/class-wp-term.php
index 3b4931a0..6cb4a15b 100644
--- a/code/wp-includes/class-wp-term.php
+++ b/code/wp-includes/class-wp-term.php
@@ -125,11 +125,12 @@ final class WP_Term {
public static function get_instance( $term_id, $taxonomy = null ) {
global $wpdb;
- $term_id = (int) $term_id;
- if ( ! $term_id ) {
+ if ( ! is_numeric( $term_id ) || $term_id != floor( $term_id ) || ! $term_id ) {
return false;
}
+ $term_id = (int) $term_id;
+
$_term = wp_cache_get( $term_id, 'terms' );
// If there isn't a cached version, hit the database.
@@ -250,7 +251,6 @@ public function __get( $key ) {
}
return sanitize_term( $data, $data->taxonomy, 'raw' );
- break;
}
}
}
diff --git a/code/wp-includes/class-wp-text-diff-renderer-inline.php b/code/wp-includes/class-wp-text-diff-renderer-inline.php
new file mode 100644
index 00000000..236e388b
--- /dev/null
+++ b/code/wp-includes/class-wp-text-diff-renderer-inline.php
@@ -0,0 +1,33 @@
+_show_split_view = $params[ 'show_split_view' ];
+ }
+
+ /**
+ * @ignore
+ *
+ * @param string $header
+ * @return string
+ */
+ public function _startBlock( $header ) {
+ return '';
+ }
+
+ /**
+ * @ignore
+ *
+ * @param array $lines
+ * @param string $prefix
+ */
+ public function _lines( $lines, $prefix=' ' ) {
+ }
+
+ /**
+ * @ignore
+ *
+ * @param string $line HTML-escape the value.
+ * @return string
+ */
+ public function addedLine( $line ) {
+ return "
\n";
+ }
+ }
+ return $r;
+ }
+
+ /**
+ * Process changed lines to do word-by-word diffs for extra highlighting.
+ *
+ * (TRAC style) sometimes these lines can actually be deleted or added rows.
+ * We do additional processing to figure that out
+ *
+ * @access public
+ * @since 2.6.0
+ *
+ * @param array $orig
+ * @param array $final
+ * @return string
+ */
+ public function _changed( $orig, $final ) {
+ $r = '';
+
+ // Does the aforementioned additional processing
+ // *_matches tell what rows are "the same" in orig and final. Those pairs will be diffed to get word changes
+ // match is numeric: an index in other column
+ // match is 'X': no match. It is a new row
+ // *_rows are column vectors for the orig column and the final column.
+ // row >= 0: an indix of the $orig or $final array
+ // row < 0: a blank row for that column
+ list($orig_matches, $final_matches, $orig_rows, $final_rows) = $this->interleave_changed_lines( $orig, $final );
+
+ // These will hold the word changes as determined by an inline diff
+ $orig_diffs = array();
+ $final_diffs = array();
+
+ // Compute word diffs for each matched pair using the inline diff
+ foreach ( $orig_matches as $o => $f ) {
+ if ( is_numeric($o) && is_numeric($f) ) {
+ $text_diff = new Text_Diff( 'auto', array( array($orig[$o]), array($final[$f]) ) );
+ $renderer = new $this->inline_diff_renderer;
+ $diff = $renderer->render( $text_diff );
+
+ // If they're too different, don't include any or
+ if ( preg_match_all( '!(.*?|.*?)!', $diff, $diff_matches ) ) {
+ // length of all text between or
+ $stripped_matches = strlen(strip_tags( join(' ', $diff_matches[0]) ));
+ // since we count lengith of text between or (instead of picking just one),
+ // we double the length of chars not in those tags.
+ $stripped_diff = strlen(strip_tags( $diff )) * 2 - $stripped_matches;
+ $diff_ratio = $stripped_matches / $stripped_diff;
+ if ( $diff_ratio > $this->_diff_threshold )
+ continue; // Too different. Don't save diffs.
+ }
+
+ // Un-inline the diffs by removing del or ins
+ $orig_diffs[$o] = preg_replace( '|.*?|', '', $diff );
+ $final_diffs[$f] = preg_replace( '|.*?|', '', $diff );
+ }
+ }
+
+ foreach ( array_keys($orig_rows) as $row ) {
+ // Both columns have blanks. Ignore them.
+ if ( $orig_rows[$row] < 0 && $final_rows[$row] < 0 )
+ continue;
+
+ // If we have a word based diff, use it. Otherwise, use the normal line.
+ if ( isset( $orig_diffs[$orig_rows[$row]] ) )
+ $orig_line = $orig_diffs[$orig_rows[$row]];
+ elseif ( isset( $orig[$orig_rows[$row]] ) )
+ $orig_line = htmlspecialchars($orig[$orig_rows[$row]]);
+ else
+ $orig_line = '';
+
+ if ( isset( $final_diffs[$final_rows[$row]] ) )
+ $final_line = $final_diffs[$final_rows[$row]];
+ elseif ( isset( $final[$final_rows[$row]] ) )
+ $final_line = htmlspecialchars($final[$final_rows[$row]]);
+ else
+ $final_line = '';
+
+ if ( $orig_rows[$row] < 0 ) { // Orig is blank. This is really an added row.
+ $r .= $this->_added( array($final_line), false );
+ } elseif ( $final_rows[$row] < 0 ) { // Final is blank. This is really a deleted row.
+ $r .= $this->_deleted( array($orig_line), false );
+ } else { // A true changed row.
+ if ( $this->_show_split_view ) {
+ $r .= '
';
+ $html .= sprintf( '%s',
+ esc_url( remove_query_arg( 'updated', wp_get_referer() ) ),
+ __( 'Please try again.' )
+ );
+ }
}
wp_die( $html, __( 'WordPress Failure Notice' ), 403 );
@@ -2542,7 +2576,8 @@ function wp_nonce_ays( $action ) {
* an integer to be used as the response code.
*
* @param string|WP_Error $message Optional. Error message. If this is a WP_Error object,
- * the error's messages are used. Default empty.
+ * and not an Ajax or XML-RPC request, the error's messages are used.
+ * Default empty.
* @param string|int $title Optional. Error title. If `$message` is a `WP_Error` object,
* error data with the key 'title' may be used to specify the title.
* If `$title` is an integer, then it is treated as the response
@@ -2551,7 +2586,7 @@ function wp_nonce_ays( $action ) {
* Optional. Arguments to control behavior. If `$args` is an integer, then it is treated
* as the response code. Default empty array.
*
- * @type int $response The HTTP response code. Default 500.
+ * @type int $response The HTTP response code. Default 200 for Ajax requests, 500 otherwise.
* @type bool $back_link Whether to include a link to go back. Default false.
* @type string $text_direction The text direction. This is only useful internally, when WordPress
* is still loading and the site's locale is not set up yet. Accepts 'rtl'.
@@ -2567,7 +2602,7 @@ function wp_die( $message = '', $title = '', $args = array() ) {
$title = '';
}
- if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
+ if ( wp_doing_ajax() ) {
/**
* Filters the callback for killing WordPress execution for Ajax requests.
*
@@ -2608,9 +2643,9 @@ function wp_die( $message = '', $title = '', $args = array() ) {
* @since 3.0.0
* @access private
*
- * @param string $message Error message.
- * @param string $title Optional. Error title. Default empty.
- * @param string|array $args Optional. Arguments to control behavior. Default empty array.
+ * @param string|WP_Error $message Error message or WP_Error object.
+ * @param string $title Optional. Error title. Default empty.
+ * @param string|array $args Optional. Arguments to control behavior. Default empty array.
*/
function _default_wp_die_handler( $message, $title = '', $args = array() ) {
$defaults = array( 'response' => 500 );
@@ -2835,9 +2870,20 @@ function _xmlrpc_wp_die_handler( $message, $title = '', $args = array() ) {
* @since 3.4.0
* @access private
*
- * @param string $message Optional. Response to print. Default empty.
+ * @param string $message Error message.
+ * @param string $title Optional. Error title (unused). Default empty.
+ * @param string|array $args Optional. Arguments to control behavior. Default empty array.
*/
-function _ajax_wp_die_handler( $message = '' ) {
+function _ajax_wp_die_handler( $message, $title = '', $args = array() ) {
+ $defaults = array(
+ 'response' => 200,
+ );
+ $r = wp_parse_args( $args, $defaults );
+
+ if ( ! headers_sent() && null !== $r['response'] ) {
+ status_header( $r['response'] );
+ }
+
if ( is_scalar( $message ) )
die( (string) $message );
die( '0' );
@@ -3054,33 +3100,44 @@ function _wp_json_prepare_data( $data ) {
* Send a JSON response back to an Ajax request.
*
* @since 3.5.0
+ * @since 4.7.0 The `$status_code` parameter was added.
*
- * @param mixed $response Variable (usually an array or object) to encode as JSON,
- * then print and die.
+ * @param mixed $response Variable (usually an array or object) to encode as JSON,
+ * then print and die.
+ * @param int $status_code The HTTP status code to output.
*/
-function wp_send_json( $response ) {
+function wp_send_json( $response, $status_code = null ) {
@header( 'Content-Type: application/json; charset=' . get_option( 'blog_charset' ) );
+ if ( null !== $status_code ) {
+ status_header( $status_code );
+ }
echo wp_json_encode( $response );
- if ( defined( 'DOING_AJAX' ) && DOING_AJAX )
- wp_die();
- else
+
+ if ( wp_doing_ajax() ) {
+ wp_die( '', '', array(
+ 'response' => null,
+ ) );
+ } else {
die;
+ }
}
/**
* Send a JSON response back to an Ajax request, indicating success.
*
* @since 3.5.0
+ * @since 4.7.0 The `$status_code` parameter was added.
*
- * @param mixed $data Data to encode as JSON, then print and die.
+ * @param mixed $data Data to encode as JSON, then print and die.
+ * @param int $status_code The HTTP status code to output.
*/
-function wp_send_json_success( $data = null ) {
+function wp_send_json_success( $data = null, $status_code = null ) {
$response = array( 'success' => true );
if ( isset( $data ) )
$response['data'] = $data;
- wp_send_json( $response );
+ wp_send_json( $response, $status_code );
}
/**
@@ -3093,10 +3150,12 @@ function wp_send_json_success( $data = null ) {
*
* @since 3.5.0
* @since 4.1.0 The `$data` parameter is now processed if a WP_Error object is passed in.
+ * @since 4.7.0 The `$status_code` parameter was added.
*
- * @param mixed $data Data to encode as JSON, then print and die.
+ * @param mixed $data Data to encode as JSON, then print and die.
+ * @param int $status_code The HTTP status code to output.
*/
-function wp_send_json_error( $data = null ) {
+function wp_send_json_error( $data = null, $status_code = null ) {
$response = array( 'success' => false );
if ( isset( $data ) ) {
@@ -3114,7 +3173,7 @@ function wp_send_json_error( $data = null ) {
}
}
- wp_send_json( $response );
+ wp_send_json( $response, $status_code );
}
/**
@@ -3134,7 +3193,7 @@ function wp_check_jsonp_callback( $callback ) {
return false;
}
- $jsonp_callback = preg_replace( '/[^\w\.]/', '', $callback, -1, $illegal_char_count );
+ preg_replace( '/[^\w\.]/', '', $callback, -1, $illegal_char_count );
return 0 === $illegal_char_count;
}
@@ -3181,6 +3240,16 @@ function _config_wp_siteurl( $url = '' ) {
return $url;
}
+/**
+ * Delete the fresh site option.
+ *
+ * @since 4.7.0
+ * @access private
+ */
+function _delete_option_fresh_site() {
+ update_option( 'fresh_site', 0 );
+}
+
/**
* Set the localized direction for MCE plugin.
*
@@ -3295,6 +3364,18 @@ function smilies_init() {
);
}
+ /**
+ * Filters all the smilies.
+ *
+ * This filter must be added before `smilies_init` is run, as
+ * it is normally only run once to setup the smilies regex.
+ *
+ * @since 4.7.0
+ *
+ * @param array $wpsmiliestrans List of the smilies.
+ */
+ $wpsmiliestrans = apply_filters('smilies', $wpsmiliestrans);
+
if (count($wpsmiliestrans) == 0) {
return;
}
@@ -3341,9 +3422,10 @@ function smilies_init() {
* to be merged into another array.
*
* @since 2.2.0
+ * @since 2.3.0 `$args` can now also be an object.
*
- * @param string|array $args Value to merge with $defaults
- * @param array $defaults Optional. Array that serves as the defaults. Default empty.
+ * @param string|array|object $args Value to merge with $defaults.
+ * @param array $defaults Optional. Array that serves as the defaults. Default empty.
* @return array Merged user defined values with defaults.
*/
function wp_parse_args( $args, $defaults = '' ) {
@@ -3374,6 +3456,26 @@ function wp_parse_id_list( $list ) {
return array_unique(array_map('absint', $list));
}
+/**
+ * Clean up an array, comma- or space-separated list of slugs.
+ *
+ * @since 4.7.0
+ *
+ * @param array|string $list List of slugs.
+ * @return array Sanitized array of slugs.
+ */
+function wp_parse_slug_list( $list ) {
+ if ( ! is_array( $list ) ) {
+ $list = preg_split( '/[\s,]+/', $list );
+ }
+
+ foreach ( $list as $key => $value ) {
+ $list[ $key ] = sanitize_title( $value );
+ }
+
+ return array_unique( $list );
+}
+
/**
* Extract a slice of an array, given a list of keys.
*
@@ -3414,6 +3516,7 @@ function wp_is_numeric_array( $data ) {
* Filters a list of objects, based on a set of key => value arguments.
*
* @since 3.0.0
+ * @since 4.7.0 Uses WP_List_Util class.
*
* @param array $list An array of objects to filter
* @param array $args Optional. An array of key => value arguments to match
@@ -3427,21 +3530,26 @@ function wp_is_numeric_array( $data ) {
* @return array A list of objects or object fields.
*/
function wp_filter_object_list( $list, $args = array(), $operator = 'and', $field = false ) {
- if ( ! is_array( $list ) )
+ if ( ! is_array( $list ) ) {
return array();
+ }
- $list = wp_list_filter( $list, $args, $operator );
+ $util = new WP_List_Util( $list );
- if ( $field )
- $list = wp_list_pluck( $list, $field );
+ $util->filter( $args, $operator );
+
+ if ( $field ) {
+ $util->pluck( $field );
+ }
- return $list;
+ return $util->get_output();
}
/**
* Filters a list of objects, based on a set of key => value arguments.
*
* @since 3.1.0
+ * @since 4.7.0 Uses WP_List_Util class.
*
* @param array $list An array of objects to filter.
* @param array $args Optional. An array of key => value arguments to match
@@ -3453,33 +3561,12 @@ function wp_filter_object_list( $list, $args = array(), $operator = 'and', $fiel
* @return array Array of found values.
*/
function wp_list_filter( $list, $args = array(), $operator = 'AND' ) {
- if ( ! is_array( $list ) )
+ if ( ! is_array( $list ) ) {
return array();
-
- if ( empty( $args ) )
- return $list;
-
- $operator = strtoupper( $operator );
- $count = count( $args );
- $filtered = array();
-
- foreach ( $list as $key => $obj ) {
- $to_match = (array) $obj;
-
- $matched = 0;
- foreach ( $args as $m_key => $m_value ) {
- if ( array_key_exists( $m_key, $to_match ) && $m_value == $to_match[ $m_key ] )
- $matched++;
- }
-
- if ( ( 'AND' == $operator && $matched == $count )
- || ( 'OR' == $operator && $matched > 0 )
- || ( 'NOT' == $operator && 0 == $matched ) ) {
- $filtered[$key] = $obj;
- }
}
- return $filtered;
+ $util = new WP_List_Util( $list );
+ return $util->filter( $args, $operator );
}
/**
@@ -3490,6 +3577,7 @@ function wp_list_filter( $list, $args = array(), $operator = 'AND' ) {
*
* @since 3.1.0
* @since 4.0.0 $index_key parameter added.
+ * @since 4.7.0 Uses WP_List_Util class.
*
* @param array $list List of objects or arrays
* @param int|string $field Field from the object to place instead of the entire object
@@ -3500,43 +3588,30 @@ function wp_list_filter( $list, $args = array(), $operator = 'AND' ) {
* `$list` will be preserved in the results.
*/
function wp_list_pluck( $list, $field, $index_key = null ) {
- if ( ! $index_key ) {
- /*
- * This is simple. Could at some point wrap array_column()
- * if we knew we had an array of arrays.
- */
- foreach ( $list as $key => $value ) {
- if ( is_object( $value ) ) {
- $list[ $key ] = $value->$field;
- } else {
- $list[ $key ] = $value[ $field ];
- }
- }
- return $list;
- }
+ $util = new WP_List_Util( $list );
+ return $util->pluck( $field, $index_key );
+}
- /*
- * When index_key is not set for a particular item, push the value
- * to the end of the stack. This is how array_column() behaves.
- */
- $newlist = array();
- foreach ( $list as $value ) {
- if ( is_object( $value ) ) {
- if ( isset( $value->$index_key ) ) {
- $newlist[ $value->$index_key ] = $value->$field;
- } else {
- $newlist[] = $value->$field;
- }
- } else {
- if ( isset( $value[ $index_key ] ) ) {
- $newlist[ $value[ $index_key ] ] = $value[ $field ];
- } else {
- $newlist[] = $value[ $field ];
- }
- }
+/**
+ * Sorts a list of objects, based on one or more orderby arguments.
+ *
+ * @since 4.7.0
+ *
+ * @param array $list An array of objects to filter.
+ * @param string|array $orderby Optional. Either the field name to order by or an array
+ * of multiple orderby fields as $orderby => $order.
+ * @param string $order Optional. Either 'ASC' or 'DESC'. Only used if $orderby
+ * is a string.
+ * @param bool $preserve_keys Optional. Whether to preserve keys. Default false.
+ * @return array The sorted array.
+ */
+function wp_list_sort( $list, $orderby = array(), $order = 'ASC', $preserve_keys = false ) {
+ if ( ! is_array( $list ) ) {
+ return array();
}
- return $newlist;
+ $util = new WP_List_Util( $list );
+ return $util->sort( $orderby, $order, $preserve_keys );
}
/**
@@ -3703,15 +3778,19 @@ function _deprecated_function( $function, $version, $replacement = null ) {
*/
if ( WP_DEBUG && apply_filters( 'deprecated_function_trigger_error', true ) ) {
if ( function_exists( '__' ) ) {
- if ( ! is_null( $replacement ) )
+ if ( ! is_null( $replacement ) ) {
+ /* translators: 1: PHP function name, 2: version number, 3: alternative function name */
trigger_error( sprintf( __('%1$s is deprecated since version %2$s! Use %3$s instead.'), $function, $version, $replacement ) );
- else
+ } else {
+ /* translators: 1: PHP function name, 2: version number */
trigger_error( sprintf( __('%1$s is deprecated since version %2$s with no alternative available.'), $function, $version ) );
+ }
} else {
- if ( ! is_null( $replacement ) )
+ if ( ! is_null( $replacement ) ) {
trigger_error( sprintf( '%1$s is deprecated since version %2$s! Use %3$s instead.', $function, $version, $replacement ) );
- else
+ } else {
trigger_error( sprintf( '%1$s is deprecated since version %2$s with no alternative available.', $function, $version ) );
+ }
}
}
}
@@ -3827,15 +3906,19 @@ function _deprecated_file( $file, $version, $replacement = null, $message = '' )
if ( WP_DEBUG && apply_filters( 'deprecated_file_trigger_error', true ) ) {
$message = empty( $message ) ? '' : ' ' . $message;
if ( function_exists( '__' ) ) {
- if ( ! is_null( $replacement ) )
+ if ( ! is_null( $replacement ) ) {
+ /* translators: 1: PHP file name, 2: version number, 3: alternative file name */
trigger_error( sprintf( __('%1$s is deprecated since version %2$s! Use %3$s instead.'), $file, $version, $replacement ) . $message );
- else
+ } else {
+ /* translators: 1: PHP file name, 2: version number */
trigger_error( sprintf( __('%1$s is deprecated since version %2$s with no alternative available.'), $file, $version ) . $message );
+ }
} else {
- if ( ! is_null( $replacement ) )
+ if ( ! is_null( $replacement ) ) {
trigger_error( sprintf( '%1$s is deprecated since version %2$s! Use %3$s instead.', $file, $version, $replacement ) . $message );
- else
+ } else {
trigger_error( sprintf( '%1$s is deprecated since version %2$s with no alternative available.', $file, $version ) . $message );
+ }
}
}
}
@@ -3887,15 +3970,19 @@ function _deprecated_argument( $function, $version, $message = null ) {
*/
if ( WP_DEBUG && apply_filters( 'deprecated_argument_trigger_error', true ) ) {
if ( function_exists( '__' ) ) {
- if ( ! is_null( $message ) )
+ if ( ! is_null( $message ) ) {
+ /* translators: 1: PHP function name, 2: version number, 3: optional message regarding the change */
trigger_error( sprintf( __('%1$s was called with an argument that is deprecated since version %2$s! %3$s'), $function, $version, $message ) );
- else
+ } else {
+ /* translators: 1: PHP function name, 2: version number */
trigger_error( sprintf( __('%1$s was called with an argument that is deprecated since version %2$s with no alternative available.'), $function, $version ) );
+ }
} else {
- if ( ! is_null( $message ) )
+ if ( ! is_null( $message ) ) {
trigger_error( sprintf( '%1$s was called with an argument that is deprecated since version %2$s! %3$s', $function, $version, $message ) );
- else
+ } else {
trigger_error( sprintf( '%1$s was called with an argument that is deprecated since version %2$s with no alternative available.', $function, $version ) );
+ }
}
}
}
@@ -3943,8 +4030,10 @@ function _deprecated_hook( $hook, $version, $replacement = null, $message = null
if ( WP_DEBUG && apply_filters( 'deprecated_hook_trigger_error', true ) ) {
$message = empty( $message ) ? '' : ' ' . $message;
if ( ! is_null( $replacement ) ) {
+ /* translators: 1: WordPress hook name, 2: version number, 3: alternative hook name */
trigger_error( sprintf( __( '%1$s is deprecated since version %2$s! Use %3$s instead.' ), $hook, $version, $replacement ) . $message );
} else {
+ /* translators: 1: WordPress hook name, 2: version number */
trigger_error( sprintf( __( '%1$s is deprecated since version %2$s with no alternative available.' ), $hook, $version ) . $message );
}
}
@@ -3988,14 +4077,24 @@ function _doing_it_wrong( $function, $message, $version ) {
*/
if ( WP_DEBUG && apply_filters( 'doing_it_wrong_trigger_error', true ) ) {
if ( function_exists( '__' ) ) {
- $version = is_null( $version ) ? '' : sprintf( __( '(This message was added in version %s.)' ), $version );
+ if ( is_null( $version ) ) {
+ $version = '';
+ } else {
+ /* translators: %s: version number */
+ $version = sprintf( __( '(This message was added in version %s.)' ), $version );
+ }
/* translators: %s: Codex URL */
$message .= ' ' . sprintf( __( 'Please see Debugging in WordPress for more information.' ),
__( 'https://codex.wordpress.org/Debugging_in_WordPress' )
);
+ /* translators: Developer debugging message. 1: PHP function name, 2: Explanatory message, 3: Version information message */
trigger_error( sprintf( __( '%1$s was called incorrectly. %2$s %3$s' ), $function, $message, $version ) );
} else {
- $version = is_null( $version ) ? '' : sprintf( '(This message was added in version %s.)', $version );
+ if ( is_null( $version ) ) {
+ $version = '';
+ } else {
+ $version = sprintf( '(This message was added in version %s.)', $version );
+ }
$message .= sprintf( ' Please see Debugging in WordPress for more information.',
'https://codex.wordpress.org/Debugging_in_WordPress'
);
@@ -4238,23 +4337,18 @@ function wp_suspend_cache_invalidation( $suspend = true ) {
*
* @since 3.0.0
*
- * @global object $current_site
- *
* @param int $site_id Optional. Site ID to test. Defaults to current site.
* @return bool True if $site_id is the main site of the network, or if not
* running Multisite.
*/
function is_main_site( $site_id = null ) {
- // This is the current network's information; 'site' is old terminology.
- global $current_site;
-
if ( ! is_multisite() )
return true;
if ( ! $site_id )
$site_id = get_current_blog_id();
- return (int) $site_id === (int) $current_site->blog_id;
+ return (int) $site_id === (int) get_network()->site_id;
}
/**
@@ -4270,10 +4364,8 @@ function is_main_network( $network_id = null ) {
return true;
}
- $current_network_id = (int) get_current_site()->id;
-
if ( null === $network_id ) {
- $network_id = $current_network_id;
+ $network_id = get_current_network_id();
}
$network_id = (int) $network_id;
@@ -4286,31 +4378,23 @@ function is_main_network( $network_id = null ) {
*
* @since 4.3.0
*
- * @global wpdb $wpdb WordPress database abstraction object.
- *
* @return int The ID of the main network.
*/
function get_main_network_id() {
- global $wpdb;
-
if ( ! is_multisite() ) {
return 1;
}
- $current_site = get_current_site();
+ $current_network = get_network();
if ( defined( 'PRIMARY_NETWORK_ID' ) ) {
$main_network_id = PRIMARY_NETWORK_ID;
- } elseif ( isset( $current_site->id ) && 1 === (int) $current_site->id ) {
+ } elseif ( isset( $current_network->id ) && 1 === (int) $current_network->id ) {
// If the current network has an ID of 1, assume it is the main network.
$main_network_id = 1;
} else {
- $main_network_id = wp_cache_get( 'primary_network_id', 'site-options' );
-
- if ( false === $main_network_id ) {
- $main_network_id = (int) $wpdb->get_var( "SELECT id FROM {$wpdb->site} ORDER BY id LIMIT 1" );
- wp_cache_add( 'primary_network_id', $main_network_id, 'site-options' );
- }
+ $_networks = get_networks( array( 'fields' => 'ids', 'number' => 1 ) );
+ $main_network_id = array_shift( $_networks );
}
/**
@@ -4432,21 +4516,25 @@ function _wp_timezone_choice_usort_callback( $a, $b ) {
* Gives a nicely-formatted list of timezone strings.
*
* @since 2.9.0
+ * @since 4.7.0 Added the `$locale` parameter.
*
* @staticvar bool $mo_loaded
+ * @staticvar string $locale_loaded
*
* @param string $selected_zone Selected timezone.
+ * @param string $locale Optional. Locale to load the timezones in. Default current site locale.
* @return string
*/
-function wp_timezone_choice( $selected_zone ) {
- static $mo_loaded = false;
+function wp_timezone_choice( $selected_zone, $locale = null ) {
+ static $mo_loaded = false, $locale_loaded = null;
$continents = array( 'Africa', 'America', 'Antarctica', 'Arctic', 'Asia', 'Atlantic', 'Australia', 'Europe', 'Indian', 'Pacific');
- // Load translations for continents and cities
- if ( !$mo_loaded ) {
- $locale = get_locale();
- $mofile = WP_LANG_DIR . '/continents-cities-' . $locale . '.mo';
+ // Load translations for continents and cities.
+ if ( ! $mo_loaded || $locale !== $locale_loaded ) {
+ $locale_loaded = $locale ? $locale : get_locale();
+ $mofile = WP_LANG_DIR . '/continents-cities-' . $locale_loaded . '.mo';
+ unload_textdomain( 'continents-cities' );
load_textdomain( 'continents-cities', $mofile );
$mo_loaded = true;
}
@@ -4890,6 +4978,7 @@ function send_frame_options_header() {
*
* @since 3.3.0
* @since 4.3.0 Added 'webcal' to the protocols array.
+ * @since 4.7.0 Added 'urn' to the protocols array.
*
* @see wp_kses()
* @see esc_url()
@@ -4898,13 +4987,13 @@ function send_frame_options_header() {
*
* @return array Array of allowed protocols. Defaults to an array containing 'http', 'https',
* 'ftp', 'ftps', 'mailto', 'news', 'irc', 'gopher', 'nntp', 'feed', 'telnet',
- * 'mms', 'rtsp', 'svn', 'tel', 'fax', 'xmpp', and 'webcal'.
+ * 'mms', 'rtsp', 'svn', 'tel', 'fax', 'xmpp', 'webcal', and 'urn'.
*/
function wp_allowed_protocols() {
static $protocols = array();
if ( empty( $protocols ) ) {
- $protocols = array( 'http', 'https', 'ftp', 'ftps', 'mailto', 'news', 'irc', 'gopher', 'nntp', 'feed', 'telnet', 'mms', 'rtsp', 'svn', 'tel', 'fax', 'xmpp', 'webcal' );
+ $protocols = array( 'http', 'https', 'ftp', 'ftps', 'mailto', 'news', 'irc', 'gopher', 'nntp', 'feed', 'telnet', 'mms', 'rtsp', 'svn', 'tel', 'fax', 'xmpp', 'webcal', 'urn' );
/**
* Filters the list of protocols allowed in HTML attributes.
@@ -5193,13 +5282,15 @@ function get_tag_regex( $tag ) {
* @return string The canonical form of the charset.
*/
function _canonical_charset( $charset ) {
- if ( 'UTF-8' === $charset || 'utf-8' === $charset || 'utf8' === $charset ||
- 'UTF8' === $charset )
+ if ( 'utf-8' === strtolower( $charset ) || 'utf8' === strtolower( $charset) ) {
+
return 'UTF-8';
+ }
+
+ if ( 'iso-8859-1' === strtolower( $charset ) || 'iso8859-1' === strtolower( $charset ) ) {
- if ( 'ISO-8859-1' === $charset || 'iso-8859-1' === $charset ||
- 'iso8859-1' === $charset || 'ISO8859-1' === $charset )
return 'ISO-8859-1';
+ }
return $charset;
}
@@ -5464,3 +5555,40 @@ function wp_raise_memory_limit( $context = 'admin' ) {
return false;
}
+
+/**
+ * Generate a random UUID (version 4).
+ *
+ * @since 4.7.0
+ *
+ * @return string UUID.
+ */
+function wp_generate_uuid4() {
+ return sprintf( '%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
+ mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ),
+ mt_rand( 0, 0xffff ),
+ mt_rand( 0, 0x0fff ) | 0x4000,
+ mt_rand( 0, 0x3fff ) | 0x8000,
+ mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff )
+ );
+}
+
+/**
+ * Get last changed date for the specified cache group.
+ *
+ * @since 4.7.0
+ *
+ * @param $group Where the cache contents are grouped.
+ *
+ * @return string $last_changed UNIX timestamp with microseconds representing when the group was last changed.
+ */
+function wp_cache_get_last_changed( $group ) {
+ $last_changed = wp_cache_get( 'last_changed', $group );
+
+ if ( ! $last_changed ) {
+ $last_changed = microtime();
+ wp_cache_set( 'last_changed', $last_changed, $group );
+ }
+
+ return $last_changed;
+}
diff --git a/code/wp-includes/functions.wp-scripts.php b/code/wp-includes/functions.wp-scripts.php
index 767d995d..dccaaf26 100644
--- a/code/wp-includes/functions.wp-scripts.php
+++ b/code/wp-includes/functions.wp-scripts.php
@@ -34,11 +34,12 @@ function wp_scripts() {
* @param string $function Function name.
*/
function _wp_scripts_maybe_doing_it_wrong( $function ) {
- if ( did_action( 'init' ) ) {
+ if ( did_action( 'init' ) || did_action( 'admin_enqueue_scripts' ) || did_action( 'wp_enqueue_scripts' ) || did_action( 'login_enqueue_scripts' ) ) {
return;
}
_doing_it_wrong( $function, sprintf(
+ /* translators: 1: wp_enqueue_scripts, 2: admin_enqueue_scripts, 3: login_enqueue_scripts */
__( 'Scripts and styles should not be registered or enqueued until the %1$s, %2$s, or %3$s hooks.' ),
'wp_enqueue_scripts',
'admin_enqueue_scripts',
@@ -224,8 +225,12 @@ function wp_deregister_script( $handle ) {
);
if ( in_array( $handle, $no ) ) {
- $message = sprintf( __( 'Do not deregister the %1$s script in the administration area. To target the front-end theme, use the %2$s hook.' ),
- "$handle", 'wp_enqueue_scripts' );
+ $message = sprintf(
+ /* translators: 1: script name, 2: wp_enqueue_scripts */
+ __( 'Do not deregister the %1$s script in the administration area. To target the front-end theme, use the %2$s hook.' ),
+ "$handle",
+ 'wp_enqueue_scripts'
+ );
_doing_it_wrong( __FUNCTION__, $message, '3.6.0' );
return;
}
@@ -247,6 +252,7 @@ function wp_deregister_script( $handle ) {
*
* @param string $handle Name of the script. Should be unique.
* @param string $src Full URL of the script, or path of the script relative to the WordPress root directory.
+ * Default empty.
* @param array $deps Optional. An array of registered script handles this script depends on. Default empty array.
* @param string|bool|null $ver Optional. String specifying script version number, if it has one, which is added to the URL
* as a query string for cache busting purposes. If version is set to false, a version
@@ -255,7 +261,7 @@ function wp_deregister_script( $handle ) {
* @param bool $in_footer Optional. Whether to enqueue the script before instead of in the
.
* Default 'false'.
*/
-function wp_enqueue_script( $handle, $src = false, $deps = array(), $ver = false, $in_footer = false ) {
+function wp_enqueue_script( $handle, $src = '', $deps = array(), $ver = false, $in_footer = false ) {
$wp_scripts = wp_scripts();
_wp_scripts_maybe_doing_it_wrong( __FUNCTION__ );
diff --git a/code/wp-includes/functions.wp-styles.php b/code/wp-includes/functions.wp-styles.php
index 5312f823..db2603a9 100644
--- a/code/wp-includes/functions.wp-styles.php
+++ b/code/wp-includes/functions.wp-styles.php
@@ -151,6 +151,7 @@ function wp_deregister_style( $handle ) {
*
* @param string $handle Name of the stylesheet. Should be unique.
* @param string $src Full URL of the stylesheet, or path of the stylesheet relative to the WordPress root directory.
+ * Default empty.
* @param array $deps Optional. An array of registered stylesheet handles this stylesheet depends on. Default empty array.
* @param string|bool|null $ver Optional. String specifying stylesheet version number, if it has one, which is added to the URL
* as a query string for cache busting purposes. If version is set to false, a version
@@ -160,7 +161,7 @@ function wp_deregister_style( $handle ) {
* Default 'all'. Accepts media types like 'all', 'print' and 'screen', or media queries like
* '(orientation: portrait)' and '(max-width: 640px)'.
*/
-function wp_enqueue_style( $handle, $src = false, $deps = array(), $ver = false, $media = 'all' ) {
+function wp_enqueue_style( $handle, $src = '', $deps = array(), $ver = false, $media = 'all' ) {
_wp_scripts_maybe_doing_it_wrong( __FUNCTION__ );
$wp_styles = wp_styles();
diff --git a/code/wp-includes/general-template.php b/code/wp-includes/general-template.php
index a5d5ea7d..ed91e5bd 100644
--- a/code/wp-includes/general-template.php
+++ b/code/wp-includes/general-template.php
@@ -30,7 +30,7 @@ function get_header( $name = null ) {
* @since 2.1.0
* @since 2.8.0 $name parameter added.
*
- * @param string $name Name of the specific header file to use.
+ * @param string|null $name Name of the specific header file to use. null for the default header.
*/
do_action( 'get_header', $name );
@@ -69,7 +69,7 @@ function get_footer( $name = null ) {
* @since 2.1.0
* @since 2.8.0 $name parameter added.
*
- * @param string $name Name of the specific footer file to use.
+ * @param string|null $name Name of the specific footer file to use. null for the default footer.
*/
do_action( 'get_footer', $name );
@@ -108,7 +108,7 @@ function get_sidebar( $name = null ) {
* @since 2.2.0
* @since 2.8.0 $name parameter added.
*
- * @param string $name Name of the specific sidebar file to use.
+ * @param string|null $name Name of the specific sidebar file to use. null for the default sidebar.
*/
do_action( 'get_sidebar', $name );
@@ -152,8 +152,8 @@ function get_template_part( $slug, $name = null ) {
*
* @since 3.0.0
*
- * @param string $slug The slug name for the generic template.
- * @param string $name The name of the specialized template.
+ * @param string $slug The slug name for the generic template.
+ * @param string|null $name The name of the specialized template.
*/
do_action( "get_template_part_{$slug}", $slug, $name );
@@ -383,7 +383,7 @@ function wp_registration_url() {
* @type string $redirect URL to redirect to. Must be absolute, as in "https://example.com/mypage/".
* Default is to redirect back to the request URI.
* @type string $form_id ID attribute value for the form. Default 'loginform'.
- * @type string $label_username Label for the username or email address field. Default 'Username or Email'.
+ * @type string $label_username Label for the username or email address field. Default 'Username or Email Address'.
* @type string $label_password Label for the password field. Default 'Password'.
* @type string $label_remember Label for the remember field. Default 'Remember Me'.
* @type string $label_log_in Label for the submit button. Default 'Log In'.
@@ -405,7 +405,7 @@ function wp_login_form( $args = array() ) {
// Default 'redirect' value takes the user back to the request URI.
'redirect' => ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'],
'form_id' => 'loginform',
- 'label_username' => __( 'Username or Email' ),
+ 'label_username' => __( 'Username or Email Address' ),
'label_password' => __( 'Password' ),
'label_remember' => __( 'Remember Me' ),
'label_log_in' => __( 'Log In' ),
@@ -481,7 +481,7 @@ function wp_login_form( $args = array() ) {
' . $login_form_middle . '
' . ( $args['remember'] ? '' : '' ) . '
-
+
' . $login_form_bottom . '
@@ -783,8 +783,11 @@ function get_bloginfo( $show = '', $filter = 'raw' ) {
* @return string Site Icon URL.
*/
function get_site_icon_url( $size = 512, $url = '', $blog_id = 0 ) {
- if ( is_multisite() && (int) $blog_id !== get_current_blog_id() ) {
+ $switched_blog = false;
+
+ if ( is_multisite() && ! empty( $blog_id ) && (int) $blog_id !== get_current_blog_id() ) {
switch_to_blog( $blog_id );
+ $switched_blog = true;
}
$site_icon_id = get_option( 'site_icon' );
@@ -798,7 +801,7 @@ function get_site_icon_url( $size = 512, $url = '', $blog_id = 0 ) {
$url = wp_get_attachment_image_url( $site_icon_id, $size_data );
}
- if ( is_multisite() && ms_is_switched() ) {
+ if ( $switched_blog ) {
restore_current_blog();
}
@@ -848,13 +851,16 @@ function has_site_icon( $blog_id = 0 ) {
* @return bool Whether the site has a custom logo or not.
*/
function has_custom_logo( $blog_id = 0 ) {
- if ( is_multisite() && (int) $blog_id !== get_current_blog_id() ) {
+ $switched_blog = false;
+
+ if ( is_multisite() && ! empty( $blog_id ) && (int) $blog_id !== get_current_blog_id() ) {
switch_to_blog( $blog_id );
+ $switched_blog = true;
}
$custom_logo_id = get_theme_mod( 'custom_logo' );
- if ( is_multisite() && ms_is_switched() ) {
+ if ( $switched_blog ) {
restore_current_blog();
}
@@ -871,9 +877,11 @@ function has_custom_logo( $blog_id = 0 ) {
*/
function get_custom_logo( $blog_id = 0 ) {
$html = '';
+ $switched_blog = false;
- if ( is_multisite() && (int) $blog_id !== get_current_blog_id() ) {
+ if ( is_multisite() && ! empty( $blog_id ) && (int) $blog_id !== get_current_blog_id() ) {
switch_to_blog( $blog_id );
+ $switched_blog = true;
}
$custom_logo_id = get_theme_mod( 'custom_logo' );
@@ -896,7 +904,7 @@ function get_custom_logo( $blog_id = 0 ) {
);
}
- if ( is_multisite() && ms_is_switched() ) {
+ if ( $switched_blog ) {
restore_current_blog();
}
@@ -1453,16 +1461,22 @@ function the_archive_title( $before = '', $after = '' ) {
*/
function get_the_archive_title() {
if ( is_category() ) {
+ /* translators: Category archive title. 1: Category name */
$title = sprintf( __( 'Category: %s' ), single_cat_title( '', false ) );
} elseif ( is_tag() ) {
+ /* translators: Tag archive title. 1: Tag name */
$title = sprintf( __( 'Tag: %s' ), single_tag_title( '', false ) );
} elseif ( is_author() ) {
+ /* translators: Author archive title. 1: Author name */
$title = sprintf( __( 'Author: %s' ), '' . get_the_author() . '' );
} elseif ( is_year() ) {
+ /* translators: Yearly archive title. 1: Year */
$title = sprintf( __( 'Year: %s' ), get_the_date( _x( 'Y', 'yearly archives date format' ) ) );
} elseif ( is_month() ) {
+ /* translators: Monthly archive title. 1: Month name and year */
$title = sprintf( __( 'Month: %s' ), get_the_date( _x( 'F Y', 'monthly archives date format' ) ) );
} elseif ( is_day() ) {
+ /* translators: Daily archive title. 1: Date */
$title = sprintf( __( 'Day: %s' ), get_the_date( _x( 'F j, Y', 'daily archives date format' ) ) );
} elseif ( is_tax( 'post_format' ) ) {
if ( is_tax( 'post_format', 'post-format-aside' ) ) {
@@ -1485,10 +1499,11 @@ function get_the_archive_title() {
$title = _x( 'Chats', 'post format archive title' );
}
} elseif ( is_post_type_archive() ) {
+ /* translators: Post type archive title. 1: Post type name */
$title = sprintf( __( 'Archives: %s' ), post_type_archive_title( '', false ) );
} elseif ( is_tax() ) {
$tax = get_taxonomy( get_queried_object()->taxonomy );
- /* translators: 1: Taxonomy singular name, 2: Current taxonomy term */
+ /* translators: Taxonomy term archive title. 1: Taxonomy singular name, 2: Current taxonomy term */
$title = sprintf( __( '%1$s: %2$s' ), $tax->labels->singular_name, single_term_title( '', false ) );
} else {
$title = __( 'Archives' );
@@ -1505,7 +1520,7 @@ function get_the_archive_title() {
}
/**
- * Display category, tag, or term description.
+ * Display category, tag, term, or author description.
*
* @since 4.1.0
*
@@ -1522,23 +1537,30 @@ function the_archive_description( $before = '', $after = '' ) {
}
/**
- * Retrieve category, tag, or term description.
+ * Retrieve category, tag, term, or author description.
*
* @since 4.1.0
+ * @since 4.7.0 Added support for author archives.
+ *
+ * @see term_description()
*
* @return string Archive description.
*/
function get_the_archive_description() {
+ if ( is_author() ) {
+ $description = get_the_author_meta( 'description' );
+ } else {
+ $description = term_description();
+ }
+
/**
* Filters the archive description.
*
* @since 4.1.0
*
- * @see term_description()
- *
* @param string $description Archive description to be displayed.
*/
- return apply_filters( 'get_the_archive_description', term_description() );
+ return apply_filters( 'get_the_archive_description', $description );
}
/**
@@ -1698,11 +1720,7 @@ function wp_get_archives( $args = '' ) {
$output = '';
- $last_changed = wp_cache_get( 'last_changed', 'posts' );
- if ( ! $last_changed ) {
- $last_changed = microtime();
- wp_cache_set( 'last_changed', $last_changed, 'posts' );
- }
+ $last_changed = wp_cache_get_last_changed( 'posts' );
$limit = $r['limit'];
@@ -2040,6 +2058,7 @@ function get_calendar( $initial = true, $echo = true ) {
if ( in_array( $day, $daywithpost ) ) {
// any posts today?
$date_format = date( _x( 'F j, Y', 'daily archives date format' ), strtotime( "{$thisyear}-{$thismonth}-{$day}" ) );
+ /* translators: Post calendar label. 1: Date */
$label = sprintf( __( 'Posts published on %s' ), $date_format );
$calendar_output .= sprintf(
'%s',
@@ -2765,12 +2784,26 @@ function wp_site_icon() {
return;
}
- $meta_tags = array(
- sprintf( '', esc_url( get_site_icon_url( 32 ) ) ),
- sprintf( '', esc_url( get_site_icon_url( 192 ) ) ),
- sprintf( '', esc_url( get_site_icon_url( 180 ) ) ),
- sprintf( '', esc_url( get_site_icon_url( 270 ) ) ),
- );
+ $meta_tags = array();
+ $icon_32 = get_site_icon_url( 32 );
+ if ( empty( $icon_32 ) && is_customize_preview() ) {
+ $icon_32 = '/favicon.ico'; // Serve default favicon URL in customizer so element can be updated for preview.
+ }
+ if ( $icon_32 ) {
+ $meta_tags[] = sprintf( '', esc_url( $icon_32 ) );
+ }
+ $icon_192 = get_site_icon_url( 192 );
+ if ( $icon_192 ) {
+ $meta_tags[] = sprintf( '', esc_url( $icon_192 ) );
+ }
+ $icon_180 = get_site_icon_url( 180 );
+ if ( $icon_180 ) {
+ $meta_tags[] = sprintf( '', esc_url( $icon_180 ) );
+ }
+ $icon_270 = get_site_icon_url( 270 );
+ if ( $icon_270 ) {
+ $meta_tags[] = sprintf( '', esc_url( $icon_270 ) );
+ }
/**
* Filters the site icon meta tags, so Plugins can add their own.
@@ -2812,9 +2845,11 @@ function wp_resource_hints() {
* The path is removed in the foreach loop below.
*/
/** This filter is documented in wp-includes/formatting.php */
- $hints['dns-prefetch'][] = apply_filters( 'emoji_svg_url', 'https://s.w.org/images/core/emoji/2/svg/' );
+ $hints['dns-prefetch'][] = apply_filters( 'emoji_svg_url', 'https://s.w.org/images/core/emoji/2.2.1/svg/' );
foreach ( $hints as $relation_type => $urls ) {
+ $unique_urls = array();
+
/**
* Filters domains and URLs for resource hints of relation type.
*
@@ -2826,16 +2861,31 @@ function wp_resource_hints() {
$urls = apply_filters( 'wp_resource_hints', $urls, $relation_type );
foreach ( $urls as $key => $url ) {
+ $atts = array();
+
+ if ( is_array( $url ) ) {
+ if ( isset( $url['href'] ) ) {
+ $atts = $url;
+ $url = $url['href'];
+ } else {
+ continue;
+ }
+ }
+
$url = esc_url( $url, array( 'http', 'https' ) );
+
if ( ! $url ) {
- unset( $urls[ $key ] );
+ continue;
+ }
+
+ if ( isset( $unique_urls[ $url ] ) ) {
continue;
}
if ( in_array( $relation_type, array( 'preconnect', 'dns-prefetch' ) ) ) {
$parsed = wp_parse_url( $url );
+
if ( empty( $parsed['host'] ) ) {
- unset( $urls[ $key ] );
continue;
}
@@ -2847,13 +2897,34 @@ function wp_resource_hints() {
}
}
- $urls[ $key ] = $url;
+ $atts['rel'] = $relation_type;
+ $atts['href'] = $url;
+
+ $unique_urls[ $url ] = $atts;
}
- $urls = array_unique( $urls );
+ foreach ( $unique_urls as $atts ) {
+ $html = '';
+
+ foreach ( $atts as $attr => $value ) {
+ if ( ! is_scalar( $value ) ||
+ ( ! in_array( $attr, array( 'as', 'crossorigin', 'href', 'pr', 'rel', 'type' ), true ) && ! is_numeric( $attr ))
+ ) {
+ continue;
+ }
+
+ $value = ( 'href' === $attr ) ? esc_url( $value ) : esc_attr( $value );
+
+ if ( ! is_string( $attr ) ) {
+ $html .= " $value";
+ } else {
+ $html .= " $attr='$value'";
+ }
+ }
+
+ $html = trim( $html );
- foreach ( $urls as $url ) {
- printf( "\n", $relation_type, $url );
+ echo "\n";
}
}
}
@@ -2892,21 +2963,21 @@ function wp_dependencies_unique_hosts() {
}
/**
- * Whether the user should have a WYSIWIG editor.
+ * Whether the user can access the visual editor.
*
- * Checks that the user requires a WYSIWIG editor and that the editor is
- * supported in the users browser.
+ * Checks if the user can access the visual editor and that it's supported by the user's browser.
*
* @since 2.0.0
*
- * @global bool $wp_rich_edit
- * @global bool $is_gecko
- * @global bool $is_opera
- * @global bool $is_safari
- * @global bool $is_chrome
- * @global bool $is_IE
+ * @global bool $wp_rich_edit Whether the user can access the visual editor.
+ * @global bool $is_gecko Whether the browser is Gecko-based.
+ * @global bool $is_opera Whether the browser is Opera.
+ * @global bool $is_safari Whether the browser is Safari.
+ * @global bool $is_chrome Whether the browser is Chrome.
+ * @global bool $is_IE Whether the browser is Internet Explorer.
+ * @global bool $is_edge Whether the browser is Microsoft Edge.
*
- * @return bool
+ * @return bool True if the user can access the visual editor, false otherwise.
*/
function user_can_richedit() {
global $wp_rich_edit, $is_gecko, $is_opera, $is_safari, $is_chrome, $is_IE, $is_edge;
@@ -2924,11 +2995,11 @@ function user_can_richedit() {
}
/**
- * Filters whether the user can access the rich (Visual) editor.
+ * Filters whether the user can access the visual editor.
*
* @since 2.1.0
*
- * @param bool $wp_rich_edit Whether the user can access to the rich (Visual) editor.
+ * @param bool $wp_rich_edit Whether the user can access the visual editor.
*/
return apply_filters( 'user_can_richedit', $wp_rich_edit );
}
@@ -2955,7 +3026,7 @@ function wp_default_editor() {
*
* @since 2.5.0
*
- * @param array $r An array of editors. Accepts 'tinymce', 'html', 'test'.
+ * @param string $r Which editor should be displayed by default. Either 'tinymce', 'html', or 'test'.
*/
return apply_filters( 'wp_default_editor', $r );
}
@@ -2982,7 +3053,6 @@ function wp_default_editor() {
function wp_editor( $content, $editor_id, $settings = array() ) {
if ( ! class_exists( '_WP_Editors', false ) )
require( ABSPATH . WPINC . '/class-wp-editor.php' );
-
_WP_Editors::editor($content, $editor_id, $settings);
}
@@ -3149,8 +3219,8 @@ function language_attributes( $doctype = 'html' ) {
* Default 1.
* @type int $mid_size How many numbers to either side of the current pages. Default 2.
* @type bool $prev_next Whether to include the previous and next links in the list. Default true.
- * @type bool $prev_text The previous page text. Default '« Previous'.
- * @type bool $next_text The next page text. Default '« Previous'.
+ * @type bool $prev_text The previous page text. Default '« Previous'.
+ * @type bool $next_text The next page text. Default 'Next »'.
* @type string $type Controls format of the returned value. Possible values are 'plain',
* 'array' and 'list'. Default is 'plain'.
* @type array $add_args An array of query args to add. Default false.
@@ -3276,7 +3346,7 @@ function paginate_links( $args = '' ) {
endif;
endif;
endfor;
- if ( $args['prev_next'] && $current && ( $current < $total || -1 == $total ) ) :
+ if ( $args['prev_next'] && $current && $current < $total ) :
$link = str_replace( '%_%', $args['format'], $args['base'] );
$link = str_replace( '%#%', $current + 1, $link );
if ( $add_args )
@@ -3347,8 +3417,6 @@ function wp_admin_css_color( $key, $name, $url, $colors = array(), $icons = arra
* Registers the default Admin color schemes
*
* @since 3.0.0
- *
- * @global string $wp_version
*/
function register_admin_color_schemes() {
$suffix = is_rtl() ? '-rtl' : '';
@@ -3361,8 +3429,9 @@ function register_admin_color_schemes() {
);
// Other color schemes are not available when running out of src
- if ( false !== strpos( $GLOBALS['wp_version'], '-src' ) )
+ if ( false !== strpos( get_bloginfo( 'version' ), '-src' ) ) {
return;
+ }
wp_admin_css_color( 'light', _x( 'Light', 'admin color scheme' ),
admin_url( "css/colors/light/colors$suffix.css" ),
diff --git a/code/wp-includes/http.php b/code/wp-includes/http.php
index 130eae3c..862e456a 100644
--- a/code/wp-includes/http.php
+++ b/code/wp-includes/http.php
@@ -208,9 +208,12 @@ function wp_remote_head($url, $args = array()) {
* Retrieve only the headers from the raw response.
*
* @since 2.7.0
+ * @since 4.6.0 Return value changed from an array to an Requests_Utility_CaseInsensitiveDictionary instance.
+ *
+ * @see \Requests_Utility_CaseInsensitiveDictionary
*
* @param array $response HTTP response.
- * @return array The headers of the response. Empty array if incorrect parameter given.
+ * @return array|\Requests_Utility_CaseInsensitiveDictionary The headers of the response. Empty array if incorrect parameter given.
*/
function wp_remote_retrieve_headers( $response ) {
if ( is_wp_error( $response ) || ! isset( $response['headers'] ) ) {
@@ -614,7 +617,7 @@ function ms_allowed_http_request_hosts( $is_external, $host ) {
static $queried = array();
if ( $is_external )
return $is_external;
- if ( $host === get_current_site()->domain )
+ if ( $host === get_network()->domain )
return true;
if ( isset( $queried[ $host ] ) )
return $queried[ $host ];
@@ -623,47 +626,118 @@ function ms_allowed_http_request_hosts( $is_external, $host ) {
}
/**
- * A wrapper for PHP's parse_url() function that handles edgecases in < PHP 5.4.7
+ * A wrapper for PHP's parse_url() function that handles consistency in the return
+ * values across PHP versions.
*
* PHP 5.4.7 expanded parse_url()'s ability to handle non-absolute url's, including
- * schemeless and relative url's with :// in the path, this works around those
- * limitations providing a standard output on PHP 5.2~5.4+.
+ * schemeless and relative url's with :// in the path. This function works around
+ * those limitations providing a standard output on PHP 5.2~5.4+.
+ *
+ * Secondly, across various PHP versions, schemeless URLs starting containing a ":"
+ * in the query are being handled inconsistently. This function works around those
+ * differences as well.
*
* Error suppression is used as prior to PHP 5.3.3, an E_WARNING would be generated
* when URL parsing failed.
*
* @since 4.4.0
- *
- * @param string $url The URL to parse.
- * @return bool|array False on failure; Array of URL components on success;
- * See parse_url()'s return values.
+ * @since 4.7.0 The $component parameter was added for parity with PHP's parse_url().
+ *
+ * @param string $url The URL to parse.
+ * @param int $component The specific component to retrieve. Use one of the PHP
+ * predefined constants to specify which one.
+ * Defaults to -1 (= return all parts as an array).
+ * @see http://php.net/manual/en/function.parse-url.php
+ * @return mixed False on parse failure; Array of URL components on success;
+ * When a specific component has been requested: null if the component
+ * doesn't exist in the given URL; a sting or - in the case of
+ * PHP_URL_PORT - integer when it does. See parse_url()'s return values.
*/
-function wp_parse_url( $url ) {
+function wp_parse_url( $url, $component = -1 ) {
+ $to_unset = array();
+ $url = strval( $url );
+
+ if ( '//' === substr( $url, 0, 2 ) ) {
+ $to_unset[] = 'scheme';
+ $url = 'placeholder:' . $url;
+ } elseif ( '/' === substr( $url, 0, 1 ) ) {
+ $to_unset[] = 'scheme';
+ $to_unset[] = 'host';
+ $url = 'placeholder://placeholder' . $url;
+ }
+
$parts = @parse_url( $url );
- if ( ! $parts ) {
- // < PHP 5.4.7 compat, trouble with relative paths including a scheme break in the path
- if ( '/' == $url[0] && false !== strpos( $url, '://' ) ) {
- // Since we know it's a relative path, prefix with a scheme/host placeholder and try again
- if ( ! $parts = @parse_url( 'placeholder://placeholder' . $url ) ) {
- return $parts;
- }
- // Remove the placeholder values
- unset( $parts['scheme'], $parts['host'] );
- } else {
- return $parts;
- }
+
+ if ( false === $parts ) {
+ // Parsing failure.
+ return $parts;
}
- // < PHP 5.4.7 compat, doesn't detect schemeless URL's host field
- if ( '//' == substr( $url, 0, 2 ) && ! isset( $parts['host'] ) ) {
- $path_parts = explode( '/', substr( $parts['path'], 2 ), 2 );
- $parts['host'] = $path_parts[0];
- if ( isset( $path_parts[1] ) ) {
- $parts['path'] = '/' . $path_parts[1];
- } else {
- unset( $parts['path'] );
- }
+ // Remove the placeholder values.
+ foreach ( $to_unset as $key ) {
+ unset( $parts[ $key ] );
}
- return $parts;
+ return _get_component_from_parsed_url_array( $parts, $component );
+}
+
+/**
+ * Retrieve a specific component from a parsed URL array.
+ *
+ * @internal
+ *
+ * @since 4.7.0
+ *
+ * @param array|false $url_parts The parsed URL. Can be false if the URL failed to parse.
+ * @param int $component The specific component to retrieve. Use one of the PHP
+ * predefined constants to specify which one.
+ * Defaults to -1 (= return all parts as an array).
+ * @see http://php.net/manual/en/function.parse-url.php
+ * @return mixed False on parse failure; Array of URL components on success;
+ * When a specific component has been requested: null if the component
+ * doesn't exist in the given URL; a sting or - in the case of
+ * PHP_URL_PORT - integer when it does. See parse_url()'s return values.
+ */
+function _get_component_from_parsed_url_array( $url_parts, $component = -1 ) {
+ if ( -1 === $component ) {
+ return $url_parts;
+ }
+
+ $key = _wp_translate_php_url_constant_to_key( $component );
+ if ( false !== $key && is_array( $url_parts ) && isset( $url_parts[ $key ] ) ) {
+ return $url_parts[ $key ];
+ } else {
+ return null;
+ }
+}
+
+/**
+ * Translate a PHP_URL_* constant to the named array keys PHP uses.
+ *
+ * @internal
+ *
+ * @since 4.7.0
+ *
+ * @see http://php.net/manual/en/url.constants.php
+ *
+ * @param int $constant PHP_URL_* constant.
+ * @return string|bool The named key or false.
+ */
+function _wp_translate_php_url_constant_to_key( $constant ) {
+ $translation = array(
+ PHP_URL_SCHEME => 'scheme',
+ PHP_URL_HOST => 'host',
+ PHP_URL_PORT => 'port',
+ PHP_URL_USER => 'user',
+ PHP_URL_PASS => 'pass',
+ PHP_URL_PATH => 'path',
+ PHP_URL_QUERY => 'query',
+ PHP_URL_FRAGMENT => 'fragment',
+ );
+
+ if ( isset( $translation[ $constant ] ) ) {
+ return $translation[ $constant ];
+ } else {
+ return false;
+ }
}
diff --git a/code/wp-includes/js/autosave.js b/code/wp-includes/js/autosave.js
index b5a8c6c0..e88943d6 100644
--- a/code/wp-includes/js/autosave.js
+++ b/code/wp-includes/js/autosave.js
@@ -315,7 +315,8 @@ window.autosave = function() {
var content, post_title, excerpt, $notice,
postData = getSavedPostData(),
cookie = wpCookies.get( 'wp-saving-post' ),
- $newerAutosaveNotice = $( '#has-newer-autosave' ).parent( '.notice' );
+ $newerAutosaveNotice = $( '#has-newer-autosave' ).parent( '.notice' ),
+ $headerEnd = $( '.wp-header-end' );
if ( cookie === post_id + '-saved' ) {
wpCookies.remove( 'wp-saving-post' );
@@ -338,8 +339,16 @@ window.autosave = function() {
return;
}
+ /*
+ * If '.wp-header-end' is found, append the notices after it otherwise
+ * after the first h1 or h2 heading found within the main content.
+ */
+ if ( ! $headerEnd.length ) {
+ $headerEnd = $( '.wrap h1, .wrap h2' ).first();
+ }
+
$notice = $( '#local-storage-notice' )
- .insertAfter( $( '.wrap h1, .wrap h2' ).first() )
+ .insertAfter( $headerEnd )
.addClass( 'notice-warning' );
if ( $newerAutosaveNotice.length ) {
diff --git a/code/wp-includes/js/autosave.min.js b/code/wp-includes/js/autosave.min.js
index f4a01657..f88edf4b 100644
--- a/code/wp-includes/js/autosave.min.js
+++ b/code/wp-includes/js/autosave.min.js
@@ -1 +1 @@
-window.autosave=function(){return!0},function(a,b){function c(){function c(b){var c,d,e,f=(new Date).getTime(),h=[],i=g();return i&&i.isDirty()&&!i.isHidden()&&f-3e3>k&&(i.save(),k=f),e={post_id:a("#post_ID").val()||0,post_type:a("#post_type").val()||"",post_author:a("#post_author").val()||"",post_title:a("#title").val()||"",content:a("#content").val()||"",excerpt:a("#excerpt").val()||""},"local"===b?e:(a('input[id^="in-category-"]:checked').each(function(){h.push(this.value)}),e.catslist=h.join(","),(c=a("#post_name").val())&&(e.post_name=c),(d=a("#parent_id").val())&&(e.parent_id=d),a("#comment_status").prop("checked")&&(e.comment_status="open"),a("#ping_status").prop("checked")&&(e.ping_status="open"),"1"===a("#auto_draft").val()&&(e.auto_draft="1"),e)}function d(b){return"object"==typeof b?(b.post_title||"")+"::"+(b.content||"")+"::"+(b.excerpt||""):(a("#title").val()||"")+"::"+(a("#content").val()||"")+"::"+(a("#excerpt").val()||"")}function e(){l.trigger("autosave-disable-buttons"),setTimeout(f,5e3)}function f(){l.trigger("autosave-enable-buttons")}function g(){return"undefined"!=typeof tinymce&&tinymce.get("content")}function h(){function e(){var a=Math.random().toString(),c=!1;try{b.sessionStorage.setItem("wp-test",a),c=b.sessionStorage.getItem("wp-test")===a,b.sessionStorage.removeItem("wp-test")}catch(d){}return v=c,c}function f(){var a=!1;return v&&t&&(a=sessionStorage.getItem("wp-autosave-"+t),a=a?JSON.parse(a):{}),a}function h(a){var b;return!(!v||!t)&&(b="wp-autosave-"+t,sessionStorage.setItem(b,JSON.stringify(a)),null!==sessionStorage.getItem(b))}function i(){var a=f();return!(!a||!u)&&(a["post_"+u]||!1)}function k(a){var b=f();if(!b||!u)return!1;if(a)b["post_"+u]=a;else{if(!b.hasOwnProperty("post_"+u))return!1;delete b["post_"+u]}return h(b)}function m(){y=!0}function n(){y=!1}function o(b){var e,f,g=!1;return!(y||!v)&&(b?(e=i()||{},a.extend(e,b)):e=c("local"),f=d(e),"undefined"==typeof x&&(x=j),f!==x&&(e.save_time=(new Date).getTime(),e.status=a("#post_status").val()||"",g=k(e),g&&(x=f),g))}function p(){u=a("#post_ID").val()||0,a("#wp-content-wrap").hasClass("tmce-active")?l.on("tinymce-editor-init.autosave",function(){b.setTimeout(function(){r()},1500)}):r(),w=b.setInterval(o,15e3),a("form#post").on("submit.autosave-local",function(){var c=g(),d=a("#post_ID").val()||0;c&&!c.isHidden()?c.on("submit",function(){o({post_title:a("#title").val()||"",content:a("#content").val()||"",excerpt:a("#excerpt").val()||""})}):o({post_title:a("#title").val()||"",content:a("#content").val()||"",excerpt:a("#excerpt").val()||""});var e="https:"===b.location.protocol;wpCookies.set("wp-saving-post",d+"-check",86400,!1,!1,e)})}function q(a,b){function c(a){return a.toString().replace(/[\x20\t\r\n\f]+/g,"")}return c(a||"")===c(b||"")}function r(){var b,c,d,e,f=i(),g=wpCookies.get("wp-saving-post"),h=a("#has-newer-autosave").parent(".notice");return g===u+"-saved"?(wpCookies.remove("wp-saving-post"),void k(!1)):void(f&&(b=a("#content").val()||"",c=a("#title").val()||"",d=a("#excerpt").val()||"",q(b,f.content)&&q(c,f.post_title)&&q(d,f.excerpt)||(e=a("#local-storage-notice").insertAfter(a(".wrap h1, .wrap h2").first()).addClass("notice-warning"),h.length?h.slideUp(150,function(){e.slideDown(150)}):e.slideDown(200),e.find(".restore-backup").on("click.autosave-local",function(){s(f),e.fadeTo(250,0,function(){e.slideUp(150)})}))))}function s(b){var c;return!!b&&(x=d(b),a("#title").val()!==b.post_title&&a("#title").focus().val(b.post_title||""),a("#excerpt").val(b.excerpt||""),c=g(),c&&!c.isHidden()&&"undefined"!=typeof switchEditors?(c.settings.wpautop&&b.content&&(b.content=switchEditors.wpautop(b.content)),c.undoManager.transact(function(){c.setContent(b.content||""),c.nodeChanged()})):(a("#content-html").click(),a("#content").focus(),document.execCommand("selectAll"),document.execCommand("insertText",!1,b.content||"")),!0)}var t,u,v,w,x,y=!1;return t="undefined"!=typeof b.autosaveL10n&&b.autosaveL10n.blog_id,e()&&t&&(a("#content").length||a("#excerpt").length)&&l.ready(p),{hasStorage:v,getSavedPostData:i,save:o,suspend:m,resume:n}}function i(){function g(){q=!0,b.clearTimeout(r),r=b.setTimeout(function(){q=!1},1e4)}function h(){v=!0}function i(){v=!1}function k(b){p(),q=!1,t=s,s="",l.trigger("after-autosave",[b]),f(),b.success&&a("#auto_draft").val("")}function m(){u=0,wp.heartbeat.connectNow()}function n(){return d()!==j}function o(){var f,h;return!(v||q||!b.autosave())&&(!((new Date).getTime()k&&(i.save(),k=f),e={post_id:a("#post_ID").val()||0,post_type:a("#post_type").val()||"",post_author:a("#post_author").val()||"",post_title:a("#title").val()||"",content:a("#content").val()||"",excerpt:a("#excerpt").val()||""},"local"===b?e:(a('input[id^="in-category-"]:checked').each(function(){h.push(this.value)}),e.catslist=h.join(","),(c=a("#post_name").val())&&(e.post_name=c),(d=a("#parent_id").val())&&(e.parent_id=d),a("#comment_status").prop("checked")&&(e.comment_status="open"),a("#ping_status").prop("checked")&&(e.ping_status="open"),"1"===a("#auto_draft").val()&&(e.auto_draft="1"),e)}function d(b){return"object"==typeof b?(b.post_title||"")+"::"+(b.content||"")+"::"+(b.excerpt||""):(a("#title").val()||"")+"::"+(a("#content").val()||"")+"::"+(a("#excerpt").val()||"")}function e(){l.trigger("autosave-disable-buttons"),setTimeout(f,5e3)}function f(){l.trigger("autosave-enable-buttons")}function g(){return"undefined"!=typeof tinymce&&tinymce.get("content")}function h(){function e(){var a=Math.random().toString(),c=!1;try{b.sessionStorage.setItem("wp-test",a),c=b.sessionStorage.getItem("wp-test")===a,b.sessionStorage.removeItem("wp-test")}catch(d){}return v=c,c}function f(){var a=!1;return v&&t&&(a=sessionStorage.getItem("wp-autosave-"+t),a=a?JSON.parse(a):{}),a}function h(a){var b;return!(!v||!t)&&(b="wp-autosave-"+t,sessionStorage.setItem(b,JSON.stringify(a)),null!==sessionStorage.getItem(b))}function i(){var a=f();return!(!a||!u)&&(a["post_"+u]||!1)}function k(a){var b=f();if(!b||!u)return!1;if(a)b["post_"+u]=a;else{if(!b.hasOwnProperty("post_"+u))return!1;delete b["post_"+u]}return h(b)}function m(){y=!0}function n(){y=!1}function o(b){var e,f,g=!1;return!(y||!v)&&(b?(e=i()||{},a.extend(e,b)):e=c("local"),f=d(e),"undefined"==typeof x&&(x=j),f!==x&&(e.save_time=(new Date).getTime(),e.status=a("#post_status").val()||"",g=k(e),g&&(x=f),g))}function p(){u=a("#post_ID").val()||0,a("#wp-content-wrap").hasClass("tmce-active")?l.on("tinymce-editor-init.autosave",function(){b.setTimeout(function(){r()},1500)}):r(),w=b.setInterval(o,15e3),a("form#post").on("submit.autosave-local",function(){var c=g(),d=a("#post_ID").val()||0;c&&!c.isHidden()?c.on("submit",function(){o({post_title:a("#title").val()||"",content:a("#content").val()||"",excerpt:a("#excerpt").val()||""})}):o({post_title:a("#title").val()||"",content:a("#content").val()||"",excerpt:a("#excerpt").val()||""});var e="https:"===b.location.protocol;wpCookies.set("wp-saving-post",d+"-check",86400,!1,!1,e)})}function q(a,b){function c(a){return a.toString().replace(/[\x20\t\r\n\f]+/g,"")}return c(a||"")===c(b||"")}function r(){var b,c,d,e,f=i(),g=wpCookies.get("wp-saving-post"),h=a("#has-newer-autosave").parent(".notice"),j=a(".wp-header-end");return g===u+"-saved"?(wpCookies.remove("wp-saving-post"),void k(!1)):void(f&&(b=a("#content").val()||"",c=a("#title").val()||"",d=a("#excerpt").val()||"",q(b,f.content)&&q(c,f.post_title)&&q(d,f.excerpt)||(j.length||(j=a(".wrap h1, .wrap h2").first()),e=a("#local-storage-notice").insertAfter(j).addClass("notice-warning"),h.length?h.slideUp(150,function(){e.slideDown(150)}):e.slideDown(200),e.find(".restore-backup").on("click.autosave-local",function(){s(f),e.fadeTo(250,0,function(){e.slideUp(150)})}))))}function s(b){var c;return!!b&&(x=d(b),a("#title").val()!==b.post_title&&a("#title").focus().val(b.post_title||""),a("#excerpt").val(b.excerpt||""),c=g(),c&&!c.isHidden()&&"undefined"!=typeof switchEditors?(c.settings.wpautop&&b.content&&(b.content=switchEditors.wpautop(b.content)),c.undoManager.transact(function(){c.setContent(b.content||""),c.nodeChanged()})):(a("#content-html").click(),a("#content").focus(),document.execCommand("selectAll"),document.execCommand("insertText",!1,b.content||"")),!0)}var t,u,v,w,x,y=!1;return t="undefined"!=typeof b.autosaveL10n&&b.autosaveL10n.blog_id,e()&&t&&(a("#content").length||a("#excerpt").length)&&l.ready(p),{hasStorage:v,getSavedPostData:i,save:o,suspend:m,resume:n}}function i(){function g(){q=!0,b.clearTimeout(r),r=b.setTimeout(function(){q=!1},1e4)}function h(){v=!0}function i(){v=!1}function k(b){p(),q=!1,t=s,s="",l.trigger("after-autosave",[b]),f(),b.success&&a("#auto_draft").val("")}function m(){u=0,wp.heartbeat.connectNow()}function n(){return d()!==j}function o(){var f,h;return!(v||q||!b.autosave())&&(!((new Date).getTime()7)}),c=b.extend({},d.Events,{initialize:function(){this.body=b(document.body),c.settings&&b.support.postMessage&&(b.support.cors||!c.settings.isCrossDomain)&&(this.window=b(window),this.element=b('').appendTo(this.body),this.bind("open",this.overlay.show),this.bind("close",this.overlay.hide),b("#wpbody").on("click",".load-customize",function(a){a.preventDefault(),c.link=b(this),c.open(c.link.attr("href"))}),b.support.history&&this.window.on("popstate",c.popstate),b.support.hashchange&&(this.window.on("hashchange",c.hashchange),this.window.triggerHandler("hashchange")))},popstate:function(a){var b=a.originalEvent.state;b&&b.customize?c.open(b.customize):c.active&&c.close()},hashchange:function(){var a=window.location.toString().split("#")[1];a&&0===a.indexOf("wp_customize=on")&&c.open(c.settings.url+"?"+a),a||b.support.history||c.close()},beforeunload:function(){if(!c.saved())return c.settings.l10n.saveAlert},open:function(a){if(!this.active){if(c.settings.browser.mobile)return window.location=a;this.originalDocumentTitle=document.title,this.active=!0,this.body.addClass("customize-loading"),this.saved=new d.Value((!0)),this.iframe=b("",{src:a,title:c.settings.l10n.mainIframeTitle}).appendTo(this.element),this.iframe.one("load",this.loaded),this.messenger=new d.Messenger({url:a,channel:"loader",targetWindow:this.iframe[0].contentWindow}),this.messenger.bind("ready",function(){c.messenger.send("back")}),this.messenger.bind("close",function(){b.support.history?history.back():b.support.hashchange?window.location.hash="":c.close()}),b(window).on("beforeunload",this.beforeunload),this.messenger.bind("saved",function(){c.saved(!0)}),this.messenger.bind("change",function(){c.saved(!1)}),this.messenger.bind("title",function(a){window.document.title=a}),this.pushState(a),this.trigger("open")}},pushState:function(a){var c=a.split("?")[1];b.support.history&&window.location.href!==a?history.pushState({customize:a},"",a):!b.support.history&&b.support.hashchange&&c&&(window.location.hash="wp_customize=on&"+c),this.trigger("open")},opened:function(){c.body.addClass("customize-active full-overlay-active")},close:function(){if(this.active){if(!this.saved()&&!confirm(c.settings.l10n.saveAlert))return void history.forward();this.active=!1,this.trigger("close"),this.originalDocumentTitle&&(document.title=this.originalDocumentTitle),this.link&&this.link.focus()}},closed:function(){c.iframe.remove(),c.messenger.destroy(),c.iframe=null,c.messenger=null,c.saved=null,c.body.removeClass("customize-active full-overlay-active").removeClass("customize-loading"),b(window).off("beforeunload",c.beforeunload)},loaded:function(){c.body.removeClass("customize-loading")},overlay:{show:function(){this.element.fadeIn(200,c.opened)},hide:function(){this.element.fadeOut(200,c.closed)}}}),b(function(){c.settings=_wpCustomizeLoaderSettings,c.initialize()}),d.Loader=c}(wp,jQuery);
\ No newline at end of file
+window.wp=window.wp||{},function(a,b){var c,d=wp.customize;b.extend(b.support,{history:!(!window.history||!history.pushState),hashchange:"onhashchange"in window&&(void 0===document.documentMode||document.documentMode>7)}),c=b.extend({},d.Events,{initialize:function(){this.body=b(document.body),c.settings&&b.support.postMessage&&(b.support.cors||!c.settings.isCrossDomain)&&(this.window=b(window),this.element=b('').appendTo(this.body),this.bind("open",this.overlay.show),this.bind("close",this.overlay.hide),b("#wpbody").on("click",".load-customize",function(a){a.preventDefault(),c.link=b(this),c.open(c.link.attr("href"))}),b.support.history&&this.window.on("popstate",c.popstate),b.support.hashchange&&(this.window.on("hashchange",c.hashchange),this.window.triggerHandler("hashchange")))},popstate:function(a){var b=a.originalEvent.state;b&&b.customize?c.open(b.customize):c.active&&c.close()},hashchange:function(){var a=window.location.toString().split("#")[1];a&&0===a.indexOf("wp_customize=on")&&c.open(c.settings.url+"?"+a),a||b.support.history||c.close()},beforeunload:function(){if(!c.saved())return c.settings.l10n.saveAlert},open:function(a){if(!this.active){if(c.settings.browser.mobile)return window.location=a;this.originalDocumentTitle=document.title,this.active=!0,this.body.addClass("customize-loading"),this.saved=new d.Value(!0),this.iframe=b("",{src:a,title:c.settings.l10n.mainIframeTitle}).appendTo(this.element),this.iframe.one("load",this.loaded),this.messenger=new d.Messenger({url:a,channel:"loader",targetWindow:this.iframe[0].contentWindow}),history.replaceState&&this.messenger.bind("changeset-uuid",function(a){var c=document.createElement("a");c.href=location.href,c.search=b.param(_.extend(d.utils.parseQueryString(c.search.substr(1)),{changeset_uuid:a})),history.replaceState({customize:c.href},"",c.href)}),this.messenger.bind("ready",function(){c.messenger.send("back")}),this.messenger.bind("close",function(){b.support.history?history.back():b.support.hashchange?window.location.hash="":c.close()}),b(window).on("beforeunload",this.beforeunload),this.messenger.bind("saved",function(){c.saved(!0)}),this.messenger.bind("change",function(){c.saved(!1)}),this.messenger.bind("title",function(a){window.document.title=a}),this.pushState(a),this.trigger("open")}},pushState:function(a){var c=a.split("?")[1];b.support.history&&window.location.href!==a?history.pushState({customize:a},"",a):!b.support.history&&b.support.hashchange&&c&&(window.location.hash="wp_customize=on&"+c),this.trigger("open")},opened:function(){c.body.addClass("customize-active full-overlay-active").attr("aria-busy","true")},close:function(){if(this.active){if(!this.saved()&&!confirm(c.settings.l10n.saveAlert))return void history.forward();this.active=!1,this.trigger("close"),this.originalDocumentTitle&&(document.title=this.originalDocumentTitle)}},closed:function(){c.iframe.remove(),c.messenger.destroy(),c.iframe=null,c.messenger=null,c.saved=null,c.body.removeClass("customize-active full-overlay-active").removeClass("customize-loading"),b(window).off("beforeunload",c.beforeunload),c.link&&c.link.focus()},loaded:function(){c.body.removeClass("customize-loading").attr("aria-busy","false")},overlay:{show:function(){this.element.fadeIn(200,c.opened)},hide:function(){this.element.fadeOut(200,c.closed)}}}),b(function(){c.settings=_wpCustomizeLoaderSettings,c.initialize()}),d.Loader=c}(wp,jQuery);
\ No newline at end of file
diff --git a/code/wp-includes/js/customize-preview-nav-menus.js b/code/wp-includes/js/customize-preview-nav-menus.js
index bd42f5e0..27c52510 100644
--- a/code/wp-includes/js/customize-preview-nav-menus.js
+++ b/code/wp-includes/js/customize-preview-nav-menus.js
@@ -15,7 +15,19 @@ wp.customize.navMenusPreview = wp.customize.MenusCustomizerPreview = ( function(
* Initialize nav menus preview.
*/
self.init = function() {
- var self = this;
+ var self = this, synced = false;
+
+ /*
+ * Keep track of whether we synced to determine whether or not bindSettingListener
+ * should also initially fire the listener. This initial firing needs to wait until
+ * after all of the settings have been synced from the pane in order to prevent
+ * an infinite selective fallback-refresh. Note that this sync handler will be
+ * added after the sync handler in customize-preview.js, so it will be triggered
+ * after all of the settings are added.
+ */
+ api.preview.bind( 'sync', function() {
+ synced = true;
+ } );
if ( api.selectiveRefresh ) {
// Listen for changes to settings related to nav menus.
@@ -23,7 +35,17 @@ wp.customize.navMenusPreview = wp.customize.MenusCustomizerPreview = ( function(
self.bindSettingListener( setting );
} );
api.bind( 'add', function( setting ) {
- self.bindSettingListener( setting, { fire: true } );
+
+ /*
+ * Handle case where an invalid nav menu item (one for which its associated object has been deleted)
+ * is synced from the controls into the preview. Since invalid nav menu items are filtered out from
+ * being exported to the frontend by the _is_valid_nav_menu_item filter in wp_get_nav_menu_items(),
+ * the customizer controls will have a nav_menu_item setting where the preview will have none, and
+ * this can trigger an infinite fallback refresh when the nav menu item lacks any valid items.
+ */
+ if ( setting.get() && ! setting.get()._invalid ) {
+ self.bindSettingListener( setting, { fire: synced } );
+ }
} );
api.bind( 'remove', function( setting ) {
self.unbindSettingListener( setting );
@@ -106,7 +128,7 @@ wp.customize.navMenusPreview = wp.customize.MenusCustomizerPreview = ( function(
* @returns {boolean}
*/
isRelatedSetting: function( setting, newValue, oldValue ) {
- var partial = this, navMenuLocationSetting, navMenuId, isNavMenuItemSetting;
+ var partial = this, navMenuLocationSetting, navMenuId, isNavMenuItemSetting, _newValue, _oldValue, urlParser;
if ( _.isString( setting ) ) {
setting = api( setting );
}
@@ -123,9 +145,29 @@ wp.customize.navMenusPreview = wp.customize.MenusCustomizerPreview = ( function(
*/
isNavMenuItemSetting = /^nav_menu_item\[/.test( setting.id );
if ( isNavMenuItemSetting && _.isObject( newValue ) && _.isObject( oldValue ) ) {
- delete newValue.type_label;
- delete oldValue.type_label;
- if ( _.isEqual( oldValue, newValue ) ) {
+ _newValue = _.clone( newValue );
+ _oldValue = _.clone( oldValue );
+ delete _newValue.type_label;
+ delete _oldValue.type_label;
+
+ // Normalize URL scheme when parent frame is HTTPS to prevent selective refresh upon initial page load.
+ if ( 'https' === api.preview.scheme.get() ) {
+ urlParser = document.createElement( 'a' );
+ urlParser.href = _newValue.url;
+ urlParser.protocol = 'https:';
+ _newValue.url = urlParser.href;
+ urlParser.href = _oldValue.url;
+ urlParser.protocol = 'https:';
+ _oldValue.url = urlParser.href;
+ }
+
+ // Prevent original_title differences from causing refreshes if title is present.
+ if ( newValue.title ) {
+ delete _oldValue.original_title;
+ delete _newValue.original_title;
+ }
+
+ if ( _.isEqual( _oldValue, _newValue ) ) {
return false;
}
}
@@ -365,6 +407,11 @@ wp.customize.navMenusPreview = wp.customize.MenusCustomizerPreview = ( function(
self.highlightControls = function() {
var selector = '.menu-item';
+ // Skip adding highlights if not in the customizer preview iframe.
+ if ( ! api.settings.channel ) {
+ return;
+ }
+
// Focus on the menu item control when shift+clicking the menu item.
$( document ).on( 'click', selector, function( e ) {
var navMenuItemParts;
diff --git a/code/wp-includes/js/customize-preview-nav-menus.min.js b/code/wp-includes/js/customize-preview-nav-menus.min.js
index e321da16..6cbdd0ea 100644
--- a/code/wp-includes/js/customize-preview-nav-menus.min.js
+++ b/code/wp-includes/js/customize-preview-nav-menus.min.js
@@ -1 +1 @@
-wp.customize.navMenusPreview=wp.customize.MenusCustomizerPreview=function(a,b,c,d){"use strict";var e={data:{navMenuInstanceArgs:{}}};return"undefined"!=typeof _wpCustomizePreviewNavMenusExports&&b.extend(e.data,_wpCustomizePreviewNavMenusExports),e.init=function(){var a=this;d.selectiveRefresh&&(d.each(function(b){a.bindSettingListener(b)}),d.bind("add",function(b){a.bindSettingListener(b,{fire:!0})}),d.bind("remove",function(b){a.unbindSettingListener(b)}),d.selectiveRefresh.bind("render-partials-response",function(c){c.nav_menu_instance_args&&b.extend(a.data.navMenuInstanceArgs,c.nav_menu_instance_args)})),d.preview.bind("active",function(){a.highlightControls()})},d.selectiveRefresh&&(e.NavMenuInstancePartial=d.selectiveRefresh.Partial.extend({initialize:function(a,c){var e,f,g=this;if(e=a.match(/^nav_menu_instance\[([0-9a-f]{32})]$/),!e)throw new Error("Illegal id for nav_menu_instance partial. The key corresponds with the args HMAC.");if(f=e[1],c=c||{},c.params=b.extend({selector:'[data-customize-partial-id="'+a+'"]',navMenuArgs:c.constructingContainerContext||{},containerInclusive:!0},c.params||{}),d.selectiveRefresh.Partial.prototype.initialize.call(g,a,c),!b.isObject(g.params.navMenuArgs))throw new Error("Missing navMenuArgs");if(g.params.navMenuArgs.args_hmac!==f)throw new Error("args_hmac mismatch with id")},isRelatedSetting:function(a,c,e){var f,g,h,i=this;if(b.isString(a)&&(a=d(a)),h=/^nav_menu_item\[/.test(a.id),h&&b.isObject(c)&&b.isObject(e)&&(delete c.type_label,delete e.type_label,b.isEqual(e,c)))return!1;if(i.params.navMenuArgs.theme_location){if("nav_menu_locations["+i.params.navMenuArgs.theme_location+"]"===a.id)return!0;f=d("nav_menu_locations["+i.params.navMenuArgs.theme_location+"]")}return g=i.params.navMenuArgs.menu,!g&&f&&(g=f()),!!g&&("nav_menu["+g+"]"===a.id||h&&(c&&c.nav_menu_term_id===g||e&&e.nav_menu_term_id===g))},refresh:function(){var c,e=this,f=a.Deferred();return b.isNumber(e.params.navMenuArgs.menu)?c=e.params.navMenuArgs.menu:e.params.navMenuArgs.theme_location&&d.has("nav_menu_locations["+e.params.navMenuArgs.theme_location+"]")&&(c=d("nav_menu_locations["+e.params.navMenuArgs.theme_location+"]").get()),c?d.selectiveRefresh.Partial.prototype.refresh.call(e):(e.fallback(),f.reject(),f.promise())},renderContent:function(b){var c=this,e=b.container;""===b.addedContent&&b.partial.fallback(),d.selectiveRefresh.Partial.prototype.renderContent.call(c,b)&&a(document).trigger("customize-preview-menu-refreshed",[{instanceNumber:null,wpNavArgs:b.context,wpNavMenuArgs:b.context,oldContainer:e,newContainer:b.container}])}}),d.selectiveRefresh.partialConstructor.nav_menu_instance=e.NavMenuInstancePartial,e.handleUnplacedNavMenuInstances=function(a){var c;return c=b.filter(b.values(e.data.navMenuInstanceArgs),function(a){return!d.selectiveRefresh.partial.has("nav_menu_instance["+a.args_hmac+"]")}),!!b.findWhere(c,a)&&(d.selectiveRefresh.requestFullRefresh(),!0)},e.bindSettingListener=function(a,b){var c;return b=b||{},(c=a.id.match(/^nav_menu\[(-?\d+)]$/))?(a._navMenuId=parseInt(c[1],10),a.bind(this.onChangeNavMenuSetting),b.fire&&this.onChangeNavMenuSetting.call(a,a(),!1),!0):(c=a.id.match(/^nav_menu_item\[(-?\d+)]$/))?(a._navMenuItemId=parseInt(c[1],10),a.bind(this.onChangeNavMenuItemSetting),b.fire&&this.onChangeNavMenuItemSetting.call(a,a(),!1),!0):(c=a.id.match(/^nav_menu_locations\[(.+?)]/),!!c&&(a._navMenuThemeLocation=c[1],a.bind(this.onChangeNavMenuLocationsSetting),b.fire&&this.onChangeNavMenuLocationsSetting.call(a,a(),!1),!0))},e.unbindSettingListener=function(a){a.unbind(this.onChangeNavMenuSetting),a.unbind(this.onChangeNavMenuItemSetting),a.unbind(this.onChangeNavMenuLocationsSetting)},e.onChangeNavMenuSetting=function(){var a=this;e.handleUnplacedNavMenuInstances({menu:a._navMenuId}),d.each(function(b){b._navMenuThemeLocation&&a._navMenuId===b()&&e.handleUnplacedNavMenuInstances({theme_location:b._navMenuThemeLocation})})},e.onChangeNavMenuItemSetting=function(a,b){var c,f=a||b;c=d("nav_menu["+String(f.nav_menu_term_id)+"]"),c&&e.onChangeNavMenuSetting.call(c)},e.onChangeNavMenuLocationsSetting=function(){var a,c=this;e.handleUnplacedNavMenuInstances({theme_location:c._navMenuThemeLocation}),a=!!b.findWhere(b.values(e.data.navMenuInstanceArgs),{theme_location:c._navMenuThemeLocation}),a||d.selectiveRefresh.requestFullRefresh()}),e.highlightControls=function(){var b=".menu-item";a(document).on("click",b,function(b){var c;b.shiftKey&&(c=a(this).attr("class").match(/(?:^|\s)menu-item-(\d+)(?:\s|$)/),c&&(b.preventDefault(),b.stopPropagation(),d.preview.send("focus-nav-menu-item-control",parseInt(c[1],10))))})},d.bind("preview-ready",function(){e.init()}),e}(jQuery,_,wp,wp.customize);
\ No newline at end of file
+wp.customize.navMenusPreview=wp.customize.MenusCustomizerPreview=function(a,b,c,d){"use strict";var e={data:{navMenuInstanceArgs:{}}};return"undefined"!=typeof _wpCustomizePreviewNavMenusExports&&b.extend(e.data,_wpCustomizePreviewNavMenusExports),e.init=function(){var a=this,c=!1;d.preview.bind("sync",function(){c=!0}),d.selectiveRefresh&&(d.each(function(b){a.bindSettingListener(b)}),d.bind("add",function(b){b.get()&&!b.get()._invalid&&a.bindSettingListener(b,{fire:c})}),d.bind("remove",function(b){a.unbindSettingListener(b)}),d.selectiveRefresh.bind("render-partials-response",function(c){c.nav_menu_instance_args&&b.extend(a.data.navMenuInstanceArgs,c.nav_menu_instance_args)})),d.preview.bind("active",function(){a.highlightControls()})},d.selectiveRefresh&&(e.NavMenuInstancePartial=d.selectiveRefresh.Partial.extend({initialize:function(a,c){var e,f,g=this;if(e=a.match(/^nav_menu_instance\[([0-9a-f]{32})]$/),!e)throw new Error("Illegal id for nav_menu_instance partial. The key corresponds with the args HMAC.");if(f=e[1],c=c||{},c.params=b.extend({selector:'[data-customize-partial-id="'+a+'"]',navMenuArgs:c.constructingContainerContext||{},containerInclusive:!0},c.params||{}),d.selectiveRefresh.Partial.prototype.initialize.call(g,a,c),!b.isObject(g.params.navMenuArgs))throw new Error("Missing navMenuArgs");if(g.params.navMenuArgs.args_hmac!==f)throw new Error("args_hmac mismatch with id")},isRelatedSetting:function(a,c,e){var f,g,h,i,j,k,l=this;if(b.isString(a)&&(a=d(a)),h=/^nav_menu_item\[/.test(a.id),h&&b.isObject(c)&&b.isObject(e)&&(i=b.clone(c),j=b.clone(e),delete i.type_label,delete j.type_label,"https"===d.preview.scheme.get()&&(k=document.createElement("a"),k.href=i.url,k.protocol="https:",i.url=k.href,k.href=j.url,k.protocol="https:",j.url=k.href),c.title&&(delete j.original_title,delete i.original_title),b.isEqual(j,i)))return!1;if(l.params.navMenuArgs.theme_location){if("nav_menu_locations["+l.params.navMenuArgs.theme_location+"]"===a.id)return!0;f=d("nav_menu_locations["+l.params.navMenuArgs.theme_location+"]")}return g=l.params.navMenuArgs.menu,!g&&f&&(g=f()),!!g&&("nav_menu["+g+"]"===a.id||h&&(c&&c.nav_menu_term_id===g||e&&e.nav_menu_term_id===g))},refresh:function(){var c,e=this,f=a.Deferred();return b.isNumber(e.params.navMenuArgs.menu)?c=e.params.navMenuArgs.menu:e.params.navMenuArgs.theme_location&&d.has("nav_menu_locations["+e.params.navMenuArgs.theme_location+"]")&&(c=d("nav_menu_locations["+e.params.navMenuArgs.theme_location+"]").get()),c?d.selectiveRefresh.Partial.prototype.refresh.call(e):(e.fallback(),f.reject(),f.promise())},renderContent:function(b){var c=this,e=b.container;""===b.addedContent&&b.partial.fallback(),d.selectiveRefresh.Partial.prototype.renderContent.call(c,b)&&a(document).trigger("customize-preview-menu-refreshed",[{instanceNumber:null,wpNavArgs:b.context,wpNavMenuArgs:b.context,oldContainer:e,newContainer:b.container}])}}),d.selectiveRefresh.partialConstructor.nav_menu_instance=e.NavMenuInstancePartial,e.handleUnplacedNavMenuInstances=function(a){var c;return c=b.filter(b.values(e.data.navMenuInstanceArgs),function(a){return!d.selectiveRefresh.partial.has("nav_menu_instance["+a.args_hmac+"]")}),!!b.findWhere(c,a)&&(d.selectiveRefresh.requestFullRefresh(),!0)},e.bindSettingListener=function(a,b){var c;return b=b||{},(c=a.id.match(/^nav_menu\[(-?\d+)]$/))?(a._navMenuId=parseInt(c[1],10),a.bind(this.onChangeNavMenuSetting),b.fire&&this.onChangeNavMenuSetting.call(a,a(),!1),!0):(c=a.id.match(/^nav_menu_item\[(-?\d+)]$/))?(a._navMenuItemId=parseInt(c[1],10),a.bind(this.onChangeNavMenuItemSetting),b.fire&&this.onChangeNavMenuItemSetting.call(a,a(),!1),!0):(c=a.id.match(/^nav_menu_locations\[(.+?)]/),!!c&&(a._navMenuThemeLocation=c[1],a.bind(this.onChangeNavMenuLocationsSetting),b.fire&&this.onChangeNavMenuLocationsSetting.call(a,a(),!1),!0))},e.unbindSettingListener=function(a){a.unbind(this.onChangeNavMenuSetting),a.unbind(this.onChangeNavMenuItemSetting),a.unbind(this.onChangeNavMenuLocationsSetting)},e.onChangeNavMenuSetting=function(){var a=this;e.handleUnplacedNavMenuInstances({menu:a._navMenuId}),d.each(function(b){b._navMenuThemeLocation&&a._navMenuId===b()&&e.handleUnplacedNavMenuInstances({theme_location:b._navMenuThemeLocation})})},e.onChangeNavMenuItemSetting=function(a,b){var c,f=a||b;c=d("nav_menu["+String(f.nav_menu_term_id)+"]"),c&&e.onChangeNavMenuSetting.call(c)},e.onChangeNavMenuLocationsSetting=function(){var a,c=this;e.handleUnplacedNavMenuInstances({theme_location:c._navMenuThemeLocation}),a=!!b.findWhere(b.values(e.data.navMenuInstanceArgs),{theme_location:c._navMenuThemeLocation}),a||d.selectiveRefresh.requestFullRefresh()}),e.highlightControls=function(){var b=".menu-item";d.settings.channel&&a(document).on("click",b,function(b){var c;b.shiftKey&&(c=a(this).attr("class").match(/(?:^|\s)menu-item-(\d+)(?:\s|$)/),c&&(b.preventDefault(),b.stopPropagation(),d.preview.send("focus-nav-menu-item-control",parseInt(c[1],10))))})},d.bind("preview-ready",function(){e.init()}),e}(jQuery,_,wp,wp.customize);
\ No newline at end of file
diff --git a/code/wp-includes/js/customize-preview-widgets.js b/code/wp-includes/js/customize-preview-widgets.js
index 47972784..6c05e894 100644
--- a/code/wp-includes/js/customize-preview-widgets.js
+++ b/code/wp-includes/js/customize-preview-widgets.js
@@ -357,7 +357,6 @@ wp.customize.widgetsPreview = wp.customize.WidgetCustomizerPreview = (function(
widgetPartial = new self.WidgetPartial( partialId, {
params: {}
} );
- api.selectiveRefresh.partial.add( widgetPartial.id, widgetPartial );
}
// Make sure that there is a container element for the widget in the sidebar, if at least a placeholder.
@@ -400,6 +399,8 @@ wp.customize.widgetsPreview = wp.customize.WidgetCustomizerPreview = (function(
wasInserted = true;
} );
+ api.selectiveRefresh.partial.add( widgetPartial.id, widgetPartial );
+
if ( wasInserted ) {
sidebarPartial.reflowWidgets();
}
@@ -537,7 +538,9 @@ wp.customize.widgetsPreview = wp.customize.WidgetCustomizerPreview = (function(
// Remove class names that incorporate the string formatting placeholders %1$s and %2$s.
widgetClasses = widgetClasses.replace( /\S*%[12]\$s\S*/g, '' );
widgetClasses = widgetClasses.replace( /^\s+|\s+$/g, '' );
- widgetSelector += '.' + widgetClasses.split( /\s+/ ).join( '.' );
+ if ( widgetClasses ) {
+ widgetSelector += '.' + widgetClasses.split( /\s+/ ).join( '.' );
+ }
self.widgetSelectors.push( widgetSelector );
});
};
@@ -570,6 +573,11 @@ wp.customize.widgetsPreview = wp.customize.WidgetCustomizerPreview = (function(
var self = this,
selector = this.widgetSelectors.join( ',' );
+ // Skip adding highlights if not in the customizer preview iframe.
+ if ( ! api.settings.channel ) {
+ return;
+ }
+
$( selector ).attr( 'title', this.l10n.widgetTooltip );
$( document ).on( 'mouseenter', selector, function() {
diff --git a/code/wp-includes/js/customize-preview-widgets.min.js b/code/wp-includes/js/customize-preview-widgets.min.js
index 8a8e2bb7..567dafc7 100644
--- a/code/wp-includes/js/customize-preview-widgets.min.js
+++ b/code/wp-includes/js/customize-preview-widgets.min.js
@@ -1 +1 @@
-wp.customize.widgetsPreview=wp.customize.WidgetCustomizerPreview=function(a,b,c,d){var e;return e={renderedSidebars:{},renderedWidgets:{},registeredSidebars:[],registeredWidgets:{},widgetSelectors:[],preview:null,l10n:{widgetTooltip:""},selectiveRefreshableWidgets:{}},e.init=function(){var a=this;a.preview=d.preview,b.isEmpty(a.selectiveRefreshableWidgets)||a.addPartials(),a.buildWidgetSelectors(),a.highlightControls(),a.preview.bind("highlight-widget",a.highlightWidget),d.preview.bind("active",function(){a.highlightControls()})},e.WidgetPartial=d.selectiveRefresh.Partial.extend({initialize:function(a,c){var f,g=this;if(f=a.match(/^widget\[(.+)]$/),!f)throw new Error("Illegal id for widget partial.");g.widgetId=f[1],g.widgetIdParts=e.parseWidgetId(g.widgetId),c=c||{},c.params=b.extend({settings:[e.getWidgetSettingId(g.widgetId)],containerInclusive:!0},c.params||{}),d.selectiveRefresh.Partial.prototype.initialize.call(g,a,c)},refresh:function(){var b,c=this;return e.selectiveRefreshableWidgets[c.widgetIdParts.idBase]?d.selectiveRefresh.Partial.prototype.refresh.call(c):(b=a.Deferred(),b.reject(),c.fallback(),b.promise())},renderContent:function(a){var b=this;d.selectiveRefresh.Partial.prototype.renderContent.call(b,a)&&(d.preview.send("widget-updated",b.widgetId),d.selectiveRefresh.trigger("widget-updated",b))}}),e.SidebarPartial=d.selectiveRefresh.Partial.extend({initialize:function(a,c){var e,f=this;if(e=a.match(/^sidebar\[(.+)]$/),!e)throw new Error("Illegal id for sidebar partial.");if(f.sidebarId=e[1],c=c||{},c.params=b.extend({settings:["sidebars_widgets["+f.sidebarId+"]"]},c.params||{}),d.selectiveRefresh.Partial.prototype.initialize.call(f,a,c),!f.params.sidebarArgs)throw new Error("The sidebarArgs param was not provided.");if(f.params.settings.length>1)throw new Error("Expected SidebarPartial to only have one associated setting")},ready:function(){var a=this;b.each(a.settings(),function(c){d(c).bind(b.bind(a.handleSettingChange,a))}),d.selectiveRefresh.bind("partial-content-rendered",function(c){var f=c.partial.extended(e.WidgetPartial)&&-1!==b.indexOf(a.getWidgetIds(),c.partial.widgetId);f&&d.selectiveRefresh.trigger("sidebar-updated",a)}),d.bind("change",function(c){var d,f;f=e.parseWidgetSettingId(c.id),f&&(d=f.idBase,f.number&&(d+="-"+String(f.number)),-1!==b.indexOf(a.getWidgetIds(),d)&&a.ensureWidgetPlacementContainers(d))})},findDynamicSidebarBoundaryNodes:function(){var a,c,d=this,e={};return a=/^(dynamic_sidebar_before|dynamic_sidebar_after):(.+):(\d+)$/,c=function(f){b.each(f,function(f){var g;if(8===f.nodeType){if(g=f.nodeValue.match(a),!g||g[2]!==d.sidebarId)return;b.isUndefined(e[g[3]])&&(e[g[3]]={before:null,after:null,instanceNumber:parseInt(g[3],10)}),"dynamic_sidebar_before"===g[1]?e[g[3]].before=f:e[g[3]].after=f}else 1===f.nodeType&&c(f.childNodes)})},c(document.body.childNodes),b.values(e)},placements:function(){var a=this;return b.map(a.findDynamicSidebarBoundaryNodes(),function(b){return new d.selectiveRefresh.Placement({partial:a,container:null,startNode:b.before,endNode:b.after,context:{instanceNumber:b.instanceNumber}})})},getWidgetIds:function(){var a,c,e=this;if(a=e.settings()[0],!a)throw new Error("Missing associated setting.");if(!d.has(a))throw new Error("Setting does not exist.");if(c=d(a).get(),!b.isArray(c))throw new Error("Expected setting to be array of widget IDs");return c.slice(0)},reflowWidgets:function(){var a,c,e,f=this,g=[];return c=f.getWidgetIds(),a=f.placements(),e={},b.each(c,function(a){var b=d.selectiveRefresh.partial("widget["+a+"]");b&&(e[a]=b)}),b.each(a,function(a){var c,f=[],h=!1,i=-1;b.each(e,function(d){b.each(d.placements(),function(b){a.context.instanceNumber===b.context.sidebar_instance_number&&(c=b.container.index(),f.push({partial:d,placement:b,position:c}),c0&&d.selectiveRefresh.trigger("sidebar-updated",f),g},ensureWidgetPlacementContainers:function(c){var f,g=this,h=!1,i="widget["+c+"]";return f=d.selectiveRefresh.partial(i),f||(f=new e.WidgetPartial(i,{params:{}}),d.selectiveRefresh.partial.add(f.id,f)),b.each(g.placements(),function(d){var e,i;e=b.find(f.placements(),function(a){return a.context.sidebar_instance_number===d.context.instanceNumber}),e||(i=a(g.params.sidebarArgs.before_widget.replace(/%1\$s/g,c).replace(/%2\$s/g,"widget")+g.params.sidebarArgs.after_widget),i[0]&&(i.attr("data-customize-partial-id",f.id),i.attr("data-customize-partial-type","widget"),i.attr("data-customize-widget-id",c),i.data("customize-partial-placement-context",{sidebar_id:g.sidebarId,sidebar_instance_number:d.context.instanceNumber}),d.endNode.parentNode.insertBefore(i[0],d.endNode),h=!0))}),h&&g.reflowWidgets(),f},handleSettingChange:function(a,c){var e,f,g,h=this,i=[];return(e=c.length>0&&0===a.length||a.length>0&&0===c.length)?void h.fallback():(f=b.difference(c,a),b.each(f,function(a){var c=d.selectiveRefresh.partial("widget["+a+"]");c&&b.each(c.placements(),function(a){var b=a.context.sidebar_id===h.sidebarId||a.context.sidebar_args&&a.context.sidebar_args.id===h.sidebarId;b&&a.container.remove()})}),g=b.difference(a,c),b.each(g,function(a){var b=h.ensureWidgetPlacementContainers(a);i.push(b)}),b.each(i,function(a){a.refresh()}),void d.selectiveRefresh.trigger("sidebar-updated",h))},refresh:function(){var c=this,e=a.Deferred();return e.fail(function(){c.fallback()}),0===c.placements().length?e.reject():(b.each(c.reflowWidgets(),function(a){d.selectiveRefresh.trigger("partial-content-rendered",a)}),e.resolve()),e.promise()}}),d.selectiveRefresh.partialConstructor.sidebar=e.SidebarPartial,d.selectiveRefresh.partialConstructor.widget=e.WidgetPartial,e.addPartials=function(){b.each(e.registeredSidebars,function(a){var b,c="sidebar["+a.id+"]";b=d.selectiveRefresh.partial(c),b||(b=new e.SidebarPartial(c,{params:{sidebarArgs:a}}),d.selectiveRefresh.partial.add(b.id,b))})},e.buildWidgetSelectors=function(){var b=this;a.each(b.registeredSidebars,function(c,d){var e,f,g,h=[d.before_widget,d.before_title,d.after_title,d.after_widget].join("");e=a(h),f=e.prop("tagName")||"",g=e.prop("className")||"",g&&(g=g.replace(/\S*%[12]\$s\S*/g,""),g=g.replace(/^\s+|\s+$/g,""),f+="."+g.split(/\s+/).join("."),b.widgetSelectors.push(f))})},e.highlightWidget=function(b){var c=a(document.body),d=a("#"+b);c.find(".widget-customizer-highlighted-widget").removeClass("widget-customizer-highlighted-widget"),d.addClass("widget-customizer-highlighted-widget"),setTimeout(function(){d.removeClass("widget-customizer-highlighted-widget")},500)},e.highlightControls=function(){var b=this,c=this.widgetSelectors.join(",");a(c).attr("title",this.l10n.widgetTooltip),a(document).on("mouseenter",c,function(){b.preview.send("highlight-widget-control",a(this).prop("id"))}),a(document).on("click",c,function(c){c.shiftKey&&(c.preventDefault(),b.preview.send("focus-widget-control",a(this).prop("id")))})},e.parseWidgetId=function(a){var b,c={idBase:"",number:null};return b=a.match(/^(.+)-(\d+)$/),b?(c.idBase=b[1],c.number=parseInt(b[2],10)):c.idBase=a,c},e.parseWidgetSettingId=function(a){var b,c={idBase:"",number:null};return(b=a.match(/^widget_([^\[]+?)(?:\[(\d+)])?$/))?(c.idBase=b[1],b[2]&&(c.number=parseInt(b[2],10)),c):null},e.getWidgetSettingId=function(a){var b,c=this.parseWidgetId(a);return b="widget_"+c.idBase,c.number&&(b+="["+String(c.number)+"]"),b},d.bind("preview-ready",function(){a.extend(e,_wpWidgetCustomizerPreviewSettings),e.init()}),e}(jQuery,_,wp,wp.customize);
\ No newline at end of file
+wp.customize.widgetsPreview=wp.customize.WidgetCustomizerPreview=function(a,b,c,d){var e;return e={renderedSidebars:{},renderedWidgets:{},registeredSidebars:[],registeredWidgets:{},widgetSelectors:[],preview:null,l10n:{widgetTooltip:""},selectiveRefreshableWidgets:{}},e.init=function(){var a=this;a.preview=d.preview,b.isEmpty(a.selectiveRefreshableWidgets)||a.addPartials(),a.buildWidgetSelectors(),a.highlightControls(),a.preview.bind("highlight-widget",a.highlightWidget),d.preview.bind("active",function(){a.highlightControls()})},e.WidgetPartial=d.selectiveRefresh.Partial.extend({initialize:function(a,c){var f,g=this;if(f=a.match(/^widget\[(.+)]$/),!f)throw new Error("Illegal id for widget partial.");g.widgetId=f[1],g.widgetIdParts=e.parseWidgetId(g.widgetId),c=c||{},c.params=b.extend({settings:[e.getWidgetSettingId(g.widgetId)],containerInclusive:!0},c.params||{}),d.selectiveRefresh.Partial.prototype.initialize.call(g,a,c)},refresh:function(){var b,c=this;return e.selectiveRefreshableWidgets[c.widgetIdParts.idBase]?d.selectiveRefresh.Partial.prototype.refresh.call(c):(b=a.Deferred(),b.reject(),c.fallback(),b.promise())},renderContent:function(a){var b=this;d.selectiveRefresh.Partial.prototype.renderContent.call(b,a)&&(d.preview.send("widget-updated",b.widgetId),d.selectiveRefresh.trigger("widget-updated",b))}}),e.SidebarPartial=d.selectiveRefresh.Partial.extend({initialize:function(a,c){var e,f=this;if(e=a.match(/^sidebar\[(.+)]$/),!e)throw new Error("Illegal id for sidebar partial.");if(f.sidebarId=e[1],c=c||{},c.params=b.extend({settings:["sidebars_widgets["+f.sidebarId+"]"]},c.params||{}),d.selectiveRefresh.Partial.prototype.initialize.call(f,a,c),!f.params.sidebarArgs)throw new Error("The sidebarArgs param was not provided.");if(f.params.settings.length>1)throw new Error("Expected SidebarPartial to only have one associated setting")},ready:function(){var a=this;b.each(a.settings(),function(c){d(c).bind(b.bind(a.handleSettingChange,a))}),d.selectiveRefresh.bind("partial-content-rendered",function(c){var f=c.partial.extended(e.WidgetPartial)&&-1!==b.indexOf(a.getWidgetIds(),c.partial.widgetId);f&&d.selectiveRefresh.trigger("sidebar-updated",a)}),d.bind("change",function(c){var d,f;f=e.parseWidgetSettingId(c.id),f&&(d=f.idBase,f.number&&(d+="-"+String(f.number)),-1!==b.indexOf(a.getWidgetIds(),d)&&a.ensureWidgetPlacementContainers(d))})},findDynamicSidebarBoundaryNodes:function(){var a,c,d=this,e={};return a=/^(dynamic_sidebar_before|dynamic_sidebar_after):(.+):(\d+)$/,c=function(f){b.each(f,function(f){var g;if(8===f.nodeType){if(g=f.nodeValue.match(a),!g||g[2]!==d.sidebarId)return;b.isUndefined(e[g[3]])&&(e[g[3]]={before:null,after:null,instanceNumber:parseInt(g[3],10)}),"dynamic_sidebar_before"===g[1]?e[g[3]].before=f:e[g[3]].after=f}else 1===f.nodeType&&c(f.childNodes)})},c(document.body.childNodes),b.values(e)},placements:function(){var a=this;return b.map(a.findDynamicSidebarBoundaryNodes(),function(b){return new d.selectiveRefresh.Placement({partial:a,container:null,startNode:b.before,endNode:b.after,context:{instanceNumber:b.instanceNumber}})})},getWidgetIds:function(){var a,c,e=this;if(a=e.settings()[0],!a)throw new Error("Missing associated setting.");if(!d.has(a))throw new Error("Setting does not exist.");if(c=d(a).get(),!b.isArray(c))throw new Error("Expected setting to be array of widget IDs");return c.slice(0)},reflowWidgets:function(){var a,c,e,f=this,g=[];return c=f.getWidgetIds(),a=f.placements(),e={},b.each(c,function(a){var b=d.selectiveRefresh.partial("widget["+a+"]");b&&(e[a]=b)}),b.each(a,function(a){var c,f=[],h=!1,i=-1;b.each(e,function(d){b.each(d.placements(),function(b){a.context.instanceNumber===b.context.sidebar_instance_number&&(c=b.container.index(),f.push({partial:d,placement:b,position:c}),c0&&d.selectiveRefresh.trigger("sidebar-updated",f),g},ensureWidgetPlacementContainers:function(c){var f,g=this,h=!1,i="widget["+c+"]";return f=d.selectiveRefresh.partial(i),f||(f=new e.WidgetPartial(i,{params:{}})),b.each(g.placements(),function(d){var e,i;e=b.find(f.placements(),function(a){return a.context.sidebar_instance_number===d.context.instanceNumber}),e||(i=a(g.params.sidebarArgs.before_widget.replace(/%1\$s/g,c).replace(/%2\$s/g,"widget")+g.params.sidebarArgs.after_widget),i[0]&&(i.attr("data-customize-partial-id",f.id),i.attr("data-customize-partial-type","widget"),i.attr("data-customize-widget-id",c),i.data("customize-partial-placement-context",{sidebar_id:g.sidebarId,sidebar_instance_number:d.context.instanceNumber}),d.endNode.parentNode.insertBefore(i[0],d.endNode),h=!0))}),d.selectiveRefresh.partial.add(f.id,f),h&&g.reflowWidgets(),f},handleSettingChange:function(a,c){var e,f,g,h=this,i=[];return(e=c.length>0&&0===a.length||a.length>0&&0===c.length)?void h.fallback():(f=b.difference(c,a),b.each(f,function(a){var c=d.selectiveRefresh.partial("widget["+a+"]");c&&b.each(c.placements(),function(a){var b=a.context.sidebar_id===h.sidebarId||a.context.sidebar_args&&a.context.sidebar_args.id===h.sidebarId;b&&a.container.remove()})}),g=b.difference(a,c),b.each(g,function(a){var b=h.ensureWidgetPlacementContainers(a);i.push(b)}),b.each(i,function(a){a.refresh()}),void d.selectiveRefresh.trigger("sidebar-updated",h))},refresh:function(){var c=this,e=a.Deferred();return e.fail(function(){c.fallback()}),0===c.placements().length?e.reject():(b.each(c.reflowWidgets(),function(a){d.selectiveRefresh.trigger("partial-content-rendered",a)}),e.resolve()),e.promise()}}),d.selectiveRefresh.partialConstructor.sidebar=e.SidebarPartial,d.selectiveRefresh.partialConstructor.widget=e.WidgetPartial,e.addPartials=function(){b.each(e.registeredSidebars,function(a){var b,c="sidebar["+a.id+"]";b=d.selectiveRefresh.partial(c),b||(b=new e.SidebarPartial(c,{params:{sidebarArgs:a}}),d.selectiveRefresh.partial.add(b.id,b))})},e.buildWidgetSelectors=function(){var b=this;a.each(b.registeredSidebars,function(c,d){var e,f,g,h=[d.before_widget,d.before_title,d.after_title,d.after_widget].join("");e=a(h),f=e.prop("tagName")||"",g=e.prop("className")||"",g&&(g=g.replace(/\S*%[12]\$s\S*/g,""),g=g.replace(/^\s+|\s+$/g,""),g&&(f+="."+g.split(/\s+/).join(".")),b.widgetSelectors.push(f))})},e.highlightWidget=function(b){var c=a(document.body),d=a("#"+b);c.find(".widget-customizer-highlighted-widget").removeClass("widget-customizer-highlighted-widget"),d.addClass("widget-customizer-highlighted-widget"),setTimeout(function(){d.removeClass("widget-customizer-highlighted-widget")},500)},e.highlightControls=function(){var b=this,c=this.widgetSelectors.join(",");d.settings.channel&&(a(c).attr("title",this.l10n.widgetTooltip),a(document).on("mouseenter",c,function(){b.preview.send("highlight-widget-control",a(this).prop("id"))}),a(document).on("click",c,function(c){c.shiftKey&&(c.preventDefault(),b.preview.send("focus-widget-control",a(this).prop("id")))}))},e.parseWidgetId=function(a){var b,c={idBase:"",number:null};return b=a.match(/^(.+)-(\d+)$/),b?(c.idBase=b[1],c.number=parseInt(b[2],10)):c.idBase=a,c},e.parseWidgetSettingId=function(a){var b,c={idBase:"",number:null};return(b=a.match(/^widget_([^\[]+?)(?:\[(\d+)])?$/))?(c.idBase=b[1],b[2]&&(c.number=parseInt(b[2],10)),c):null},e.getWidgetSettingId=function(a){var b,c=this.parseWidgetId(a);return b="widget_"+c.idBase,c.number&&(b+="["+String(c.number)+"]"),b},d.bind("preview-ready",function(){a.extend(e,_wpWidgetCustomizerPreviewSettings),e.init()}),e}(jQuery,_,wp,wp.customize);
\ No newline at end of file
diff --git a/code/wp-includes/js/customize-preview.js b/code/wp-includes/js/customize-preview.js
index f5569ed1..a4cb196d 100644
--- a/code/wp-includes/js/customize-preview.js
+++ b/code/wp-includes/js/customize-preview.js
@@ -3,7 +3,68 @@
*/
(function( exports, $ ){
var api = wp.customize,
- debounce;
+ debounce,
+ currentHistoryState = {};
+
+ /*
+ * Capture the state that is passed into history.replaceState() and history.pushState()
+ * and also which is returned in the popstate event so that when the changeset_uuid
+ * gets updated when transitioning to a new changeset there the current state will
+ * be supplied in the call to history.replaceState().
+ */
+ ( function( history ) {
+ var injectUrlWithState;
+
+ if ( ! history.replaceState ) {
+ return;
+ }
+
+ /**
+ * Amend the supplied URL with the customized state.
+ *
+ * @since 4.7.0
+ * @access private
+ *
+ * @param {string} url URL.
+ * @returns {string} URL with customized state.
+ */
+ injectUrlWithState = function( url ) {
+ var urlParser, oldQueryParams, newQueryParams;
+ urlParser = document.createElement( 'a' );
+ urlParser.href = url;
+ oldQueryParams = api.utils.parseQueryString( location.search.substr( 1 ) );
+ newQueryParams = api.utils.parseQueryString( urlParser.search.substr( 1 ) );
+
+ newQueryParams.customize_changeset_uuid = oldQueryParams.customize_changeset_uuid;
+ if ( oldQueryParams.customize_theme ) {
+ newQueryParams.customize_theme = oldQueryParams.customize_theme;
+ }
+ if ( oldQueryParams.customize_messenger_channel ) {
+ newQueryParams.customize_messenger_channel = oldQueryParams.customize_messenger_channel;
+ }
+ urlParser.search = $.param( newQueryParams );
+ return urlParser.href;
+ };
+
+ history.replaceState = ( function( nativeReplaceState ) {
+ return function historyReplaceState( data, title, url ) {
+ currentHistoryState = data;
+ return nativeReplaceState.call( history, data, title, injectUrlWithState( url ) );
+ };
+ } )( history.replaceState );
+
+ history.pushState = ( function( nativePushState ) {
+ return function historyPushState( data, title, url ) {
+ currentHistoryState = data;
+ return nativePushState.call( history, data, title, injectUrlWithState( url ) );
+ };
+ } )( history.pushState );
+
+ window.addEventListener( 'popstate', function( event ) {
+ currentHistoryState = event.state;
+ } );
+
+ }( history ) );
/**
* Returns a debounced version of the function.
@@ -37,51 +98,558 @@
* @param {object} options - Extend any instance parameter or method with this object.
*/
initialize: function( params, options ) {
- var self = this;
+ var preview = this, urlParser = document.createElement( 'a' );
+
+ api.Messenger.prototype.initialize.call( preview, params, options );
+
+ urlParser.href = preview.origin();
+ preview.add( 'scheme', urlParser.protocol.replace( /:$/, '' ) );
+
+ preview.body = $( document.body );
+ preview.window = $( window );
+
+ if ( api.settings.channel ) {
+
+ // If in an iframe, then intercept the link clicks and form submissions.
+ preview.body.on( 'click.preview', 'a', function( event ) {
+ preview.handleLinkClick( event );
+ } );
+ preview.body.on( 'submit.preview', 'form', function( event ) {
+ preview.handleFormSubmit( event );
+ } );
+
+ preview.window.on( 'scroll.preview', debounce( function() {
+ preview.send( 'scroll', preview.window.scrollTop() );
+ }, 200 ) );
+
+ preview.bind( 'scroll', function( distance ) {
+ preview.window.scrollTop( distance );
+ });
+ }
+ },
+
+ /**
+ * Handle link clicks in preview.
+ *
+ * @since 4.7.0
+ * @access public
+ *
+ * @param {jQuery.Event} event Event.
+ */
+ handleLinkClick: function( event ) {
+ var preview = this, link, isInternalJumpLink;
+ link = $( event.target );
+
+ // No-op if the anchor is not a link.
+ if ( _.isUndefined( link.attr( 'href' ) ) ) {
+ return;
+ }
+
+ isInternalJumpLink = ( '#' === link.attr( 'href' ).substr( 0, 1 ) );
- api.Messenger.prototype.initialize.call( this, params, options );
+ // Allow internal jump links to behave normally without preventing default.
+ if ( isInternalJumpLink ) {
+ return;
+ }
- this.body = $( document.body );
- this.body.on( 'click.preview', 'a', function( event ) {
- var link, isInternalJumpLink;
- link = $( this );
- isInternalJumpLink = ( '#' === link.attr( 'href' ).substr( 0, 1 ) );
+ // If the link is not previewable, prevent the browser from navigating to it.
+ if ( ! api.isLinkPreviewable( link[0] ) ) {
+ wp.a11y.speak( api.settings.l10n.linkUnpreviewable );
event.preventDefault();
+ return;
+ }
+
+ // Prevent initiating navigating from click and instead rely on sending url message to pane.
+ event.preventDefault();
+
+ /*
+ * Note the shift key is checked so shift+click on widgets or
+ * nav menu items can just result on focusing on the corresponding
+ * control instead of also navigating to the URL linked to.
+ */
+ if ( event.shiftKey ) {
+ return;
+ }
+
+ // Note: It's not relevant to send scroll because sending url message will have the same effect.
+ preview.send( 'url', link.prop( 'href' ) );
+ },
+
+ /**
+ * Handle form submit.
+ *
+ * @since 4.7.0
+ * @access public
+ *
+ * @param {jQuery.Event} event Event.
+ */
+ handleFormSubmit: function( event ) {
+ var preview = this, urlParser, form;
+ urlParser = document.createElement( 'a' );
+ form = $( event.target );
+ urlParser.href = form.prop( 'action' );
+
+ // If the link is not previewable, prevent the browser from navigating to it.
+ if ( 'GET' !== form.prop( 'method' ).toUpperCase() || ! api.isLinkPreviewable( urlParser ) ) {
+ wp.a11y.speak( api.settings.l10n.formUnpreviewable );
+ event.preventDefault();
+ return;
+ }
+
+ /*
+ * If the default wasn't prevented already (in which case the form
+ * submission is already being handled by JS), and if it has a GET
+ * request method, then take the serialized form data and add it as
+ * a query string to the action URL and send this in a url message
+ * to the customizer pane so that it will be loaded. If the form's
+ * action points to a non-previewable URL, the customizer pane's
+ * previewUrl setter will reject it so that the form submission is
+ * a no-op, which is the same behavior as when clicking a link to an
+ * external site in the preview.
+ */
+ if ( ! event.isDefaultPrevented() ) {
+ if ( urlParser.search.length > 1 ) {
+ urlParser.search += '&';
+ }
+ urlParser.search += form.serialize();
+ preview.send( 'url', urlParser.href );
+ }
+
+ // Prevent default since navigation should be done via sending url message or via JS submit handler.
+ event.preventDefault();
+ }
+ });
+
+ /**
+ * Inject the changeset UUID into links in the document.
+ *
+ * @since 4.7.0
+ * @access protected
+ *
+ * @access private
+ * @returns {void}
+ */
+ api.addLinkPreviewing = function addLinkPreviewing() {
+ var linkSelectors = 'a[href], area';
+
+ // Inject links into initial document.
+ $( document.body ).find( linkSelectors ).each( function() {
+ api.prepareLinkPreview( this );
+ } );
- if ( isInternalJumpLink && '#' !== link.attr( 'href' ) ) {
- $( link.attr( 'href' ) ).each( function() {
- this.scrollIntoView();
+ // Inject links for new elements added to the page.
+ if ( 'undefined' !== typeof MutationObserver ) {
+ api.mutationObserver = new MutationObserver( function( mutations ) {
+ _.each( mutations, function( mutation ) {
+ $( mutation.target ).find( linkSelectors ).each( function() {
+ api.prepareLinkPreview( this );
} );
+ } );
+ } );
+ api.mutationObserver.observe( document.documentElement, {
+ childList: true,
+ subtree: true
+ } );
+ } else {
+
+ // If mutation observers aren't available, fallback to just-in-time injection.
+ $( document.documentElement ).on( 'click focus mouseover', linkSelectors, function() {
+ api.prepareLinkPreview( this );
+ } );
+ }
+ };
+
+ /**
+ * Should the supplied link is previewable.
+ *
+ * @since 4.7.0
+ * @access public
+ *
+ * @param {HTMLAnchorElement|HTMLAreaElement} element Link element.
+ * @param {string} element.search Query string.
+ * @param {string} element.pathname Path.
+ * @param {string} element.host Host.
+ * @param {object} [options]
+ * @param {object} [options.allowAdminAjax=false] Allow admin-ajax.php requests.
+ * @returns {boolean} Is appropriate for changeset link.
+ */
+ api.isLinkPreviewable = function isLinkPreviewable( element, options ) {
+ var matchesAllowedUrl, parsedAllowedUrl, args;
+
+ args = _.extend( {}, { allowAdminAjax: false }, options || {} );
+
+ if ( 'javascript:' === element.protocol ) { // jshint ignore:line
+ return true;
+ }
+
+ // Only web URLs can be previewed.
+ if ( 'https:' !== element.protocol && 'http:' !== element.protocol ) {
+ return false;
+ }
+
+ parsedAllowedUrl = document.createElement( 'a' );
+ matchesAllowedUrl = ! _.isUndefined( _.find( api.settings.url.allowed, function( allowedUrl ) {
+ parsedAllowedUrl.href = allowedUrl;
+ return parsedAllowedUrl.protocol === element.protocol && parsedAllowedUrl.host === element.host && 0 === element.pathname.indexOf( parsedAllowedUrl.pathname.replace( /\/$/, '' ) );
+ } ) );
+ if ( ! matchesAllowedUrl ) {
+ return false;
+ }
+
+ // Skip wp login and signup pages.
+ if ( /\/wp-(login|signup)\.php$/.test( element.pathname ) ) {
+ return false;
+ }
+
+ // Allow links to admin ajax as faux frontend URLs.
+ if ( /\/wp-admin\/admin-ajax\.php$/.test( element.pathname ) ) {
+ return args.allowAdminAjax;
+ }
+
+ // Disallow links to admin, includes, and content.
+ if ( /\/wp-(admin|includes|content)(\/|$)/.test( element.pathname ) ) {
+ return false;
+ }
+
+ return true;
+ };
+
+ /**
+ * Inject the customize_changeset_uuid query param into links on the frontend.
+ *
+ * @since 4.7.0
+ * @access protected
+ *
+ * @param {HTMLAnchorElement|HTMLAreaElement} element Link element.
+ * @param {string} element.search Query string.
+ * @param {string} element.host Host.
+ * @param {string} element.protocol Protocol.
+ * @returns {void}
+ */
+ api.prepareLinkPreview = function prepareLinkPreview( element ) {
+ var queryParams;
+
+ // Skip links in admin bar.
+ if ( $( element ).closest( '#wpadminbar' ).length ) {
+ return;
+ }
+
+ // Ignore links with href="#" or href="#id".
+ if ( '#' === $( element ).attr( 'href' ).substr( 0, 1 ) ) {
+ return;
+ }
+
+ // Make sure links in preview use HTTPS if parent frame uses HTTPS.
+ if ( api.settings.channel && 'https' === api.preview.scheme.get() && 'http:' === element.protocol && -1 !== api.settings.url.allowedHosts.indexOf( element.host ) ) {
+ element.protocol = 'https:';
+ }
+
+ if ( ! api.isLinkPreviewable( element ) ) {
+
+ // Style link as unpreviewable only if previewing in iframe; if previewing on frontend, links will be allowed to work normally.
+ if ( api.settings.channel ) {
+ $( element ).addClass( 'customize-unpreviewable' );
+ }
+ return;
+ }
+ $( element ).removeClass( 'customize-unpreviewable' );
+
+ queryParams = api.utils.parseQueryString( element.search.substring( 1 ) );
+ queryParams.customize_changeset_uuid = api.settings.changeset.uuid;
+ if ( ! api.settings.theme.active ) {
+ queryParams.customize_theme = api.settings.theme.stylesheet;
+ }
+ if ( api.settings.channel ) {
+ queryParams.customize_messenger_channel = api.settings.channel;
+ }
+ element.search = $.param( queryParams );
+
+ // Prevent links from breaking out of preview iframe.
+ if ( api.settings.channel ) {
+ element.target = '_self';
+ }
+ };
+
+ /**
+ * Inject the changeset UUID into Ajax requests.
+ *
+ * @since 4.7.0
+ * @access protected
+ *
+ * @return {void}
+ */
+ api.addRequestPreviewing = function addRequestPreviewing() {
+
+ /**
+ * Rewrite Ajax requests to inject customizer state.
+ *
+ * @param {object} options Options.
+ * @param {string} options.type Type.
+ * @param {string} options.url URL.
+ * @param {object} originalOptions Original options.
+ * @param {XMLHttpRequest} xhr XHR.
+ * @returns {void}
+ */
+ var prefilterAjax = function( options, originalOptions, xhr ) {
+ var urlParser, queryParams, requestMethod, dirtyValues = {};
+ urlParser = document.createElement( 'a' );
+ urlParser.href = options.url;
+
+ // Abort if the request is not for this site.
+ if ( ! api.isLinkPreviewable( urlParser, { allowAdminAjax: true } ) ) {
+ return;
+ }
+ queryParams = api.utils.parseQueryString( urlParser.search.substring( 1 ) );
+
+ // Note that _dirty flag will be cleared with changeset updates.
+ api.each( function( setting ) {
+ if ( setting._dirty ) {
+ dirtyValues[ setting.id ] = setting.get();
}
+ } );
- /*
- * Note the shift key is checked so shift+click on widgets or
- * nav menu items can just result on focusing on the corresponding
- * control instead of also navigating to the URL linked to.
- */
- if ( event.shiftKey || isInternalJumpLink ) {
- return;
+ if ( ! _.isEmpty( dirtyValues ) ) {
+ requestMethod = options.type.toUpperCase();
+
+ // Override underlying request method to ensure unsaved changes to changeset can be included (force Backbone.emulateHTTP).
+ if ( 'POST' !== requestMethod ) {
+ xhr.setRequestHeader( 'X-HTTP-Method-Override', requestMethod );
+ queryParams._method = requestMethod;
+ options.type = 'POST';
}
- self.send( 'scroll', 0 );
- self.send( 'url', link.prop( 'href' ) );
- });
- // You cannot submit forms.
- // @todo: Allow form submissions by mixing $_POST data with the customize setting $_POST data.
- this.body.on( 'submit.preview', 'form', function( event ) {
- event.preventDefault();
- });
+ // Amend the post data with the customized values.
+ if ( options.data ) {
+ options.data += '&';
+ } else {
+ options.data = '';
+ }
+ options.data += $.param( {
+ customized: JSON.stringify( dirtyValues )
+ } );
+ }
- this.window = $( window );
- this.window.on( 'scroll.preview', debounce( function() {
- self.send( 'scroll', self.window.scrollTop() );
- }, 200 ));
+ // Include customized state query params in URL.
+ queryParams.customize_changeset_uuid = api.settings.changeset.uuid;
+ if ( ! api.settings.theme.active ) {
+ queryParams.customize_theme = api.settings.theme.stylesheet;
+ }
+ urlParser.search = $.param( queryParams );
+ options.url = urlParser.href;
+ };
- this.bind( 'scroll', function( distance ) {
- self.window.scrollTop( distance );
- });
+ $.ajaxPrefilter( prefilterAjax );
+ };
+
+ /**
+ * Inject changeset UUID into forms, allowing preview to persist through submissions.
+ *
+ * @since 4.7.0
+ * @access protected
+ *
+ * @returns {void}
+ */
+ api.addFormPreviewing = function addFormPreviewing() {
+
+ // Inject inputs for forms in initial document.
+ $( document.body ).find( 'form' ).each( function() {
+ api.prepareFormPreview( this );
+ } );
+
+ // Inject inputs for new forms added to the page.
+ if ( 'undefined' !== typeof MutationObserver ) {
+ api.mutationObserver = new MutationObserver( function( mutations ) {
+ _.each( mutations, function( mutation ) {
+ $( mutation.target ).find( 'form' ).each( function() {
+ api.prepareFormPreview( this );
+ } );
+ } );
+ } );
+ api.mutationObserver.observe( document.documentElement, {
+ childList: true,
+ subtree: true
+ } );
}
- });
+ };
+
+ /**
+ * Inject changeset into form inputs.
+ *
+ * @since 4.7.0
+ * @access protected
+ *
+ * @param {HTMLFormElement} form Form.
+ * @returns {void}
+ */
+ api.prepareFormPreview = function prepareFormPreview( form ) {
+ var urlParser, stateParams = {};
+
+ if ( ! form.action ) {
+ form.action = location.href;
+ }
+
+ urlParser = document.createElement( 'a' );
+ urlParser.href = form.action;
+
+ // Make sure forms in preview use HTTPS if parent frame uses HTTPS.
+ if ( api.settings.channel && 'https' === api.preview.scheme.get() && 'http:' === urlParser.protocol && -1 !== api.settings.url.allowedHosts.indexOf( urlParser.host ) ) {
+ urlParser.protocol = 'https:';
+ form.action = urlParser.href;
+ }
+
+ if ( 'GET' !== form.method.toUpperCase() || ! api.isLinkPreviewable( urlParser ) ) {
+
+ // Style form as unpreviewable only if previewing in iframe; if previewing on frontend, all forms will be allowed to work normally.
+ if ( api.settings.channel ) {
+ $( form ).addClass( 'customize-unpreviewable' );
+ }
+ return;
+ }
+ $( form ).removeClass( 'customize-unpreviewable' );
+
+ stateParams.customize_changeset_uuid = api.settings.changeset.uuid;
+ if ( ! api.settings.theme.active ) {
+ stateParams.customize_theme = api.settings.theme.stylesheet;
+ }
+ if ( api.settings.channel ) {
+ stateParams.customize_messenger_channel = api.settings.channel;
+ }
+
+ _.each( stateParams, function( value, name ) {
+ var input = $( form ).find( 'input[name="' + name + '"]' );
+ if ( input.length ) {
+ input.val( value );
+ } else {
+ $( form ).prepend( $( '', {
+ type: 'hidden',
+ name: name,
+ value: value
+ } ) );
+ }
+ } );
+
+ // Prevent links from breaking out of preview iframe.
+ if ( api.settings.channel ) {
+ form.target = '_self';
+ }
+ };
+
+ /**
+ * Watch current URL and send keep-alive (heartbeat) messages to the parent.
+ *
+ * Keep the customizer pane notified that the preview is still alive
+ * and that the user hasn't navigated to a non-customized URL.
+ *
+ * @since 4.7.0
+ * @access protected
+ */
+ api.keepAliveCurrentUrl = ( function() {
+ var previousPathName = location.pathname,
+ previousQueryString = location.search.substr( 1 ),
+ previousQueryParams = null,
+ stateQueryParams = [ 'customize_theme', 'customize_changeset_uuid', 'customize_messenger_channel' ];
+
+ return function keepAliveCurrentUrl() {
+ var urlParser, currentQueryParams;
+
+ // Short-circuit with keep-alive if previous URL is identical (as is normal case).
+ if ( previousQueryString === location.search.substr( 1 ) && previousPathName === location.pathname ) {
+ api.preview.send( 'keep-alive' );
+ return;
+ }
+
+ urlParser = document.createElement( 'a' );
+ if ( null === previousQueryParams ) {
+ urlParser.search = previousQueryString;
+ previousQueryParams = api.utils.parseQueryString( previousQueryString );
+ _.each( stateQueryParams, function( name ) {
+ delete previousQueryParams[ name ];
+ } );
+ }
+
+ // Determine if current URL minus customized state params and URL hash.
+ urlParser.href = location.href;
+ currentQueryParams = api.utils.parseQueryString( urlParser.search.substr( 1 ) );
+ _.each( stateQueryParams, function( name ) {
+ delete currentQueryParams[ name ];
+ } );
+
+ if ( previousPathName !== location.pathname || ! _.isEqual( previousQueryParams, currentQueryParams ) ) {
+ urlParser.search = $.param( currentQueryParams );
+ urlParser.hash = '';
+ api.settings.url.self = urlParser.href;
+ api.preview.send( 'ready', {
+ currentUrl: api.settings.url.self,
+ activePanels: api.settings.activePanels,
+ activeSections: api.settings.activeSections,
+ activeControls: api.settings.activeControls,
+ settingValidities: api.settings.settingValidities
+ } );
+ } else {
+ api.preview.send( 'keep-alive' );
+ }
+ previousQueryParams = currentQueryParams;
+ previousQueryString = location.search.substr( 1 );
+ previousPathName = location.pathname;
+ };
+ } )();
+
+ api.settingPreviewHandlers = {
+
+ /**
+ * Preview changes to custom logo.
+ *
+ * @param {number} attachmentId Attachment ID for custom logo.
+ * @returns {void}
+ */
+ custom_logo: function( attachmentId ) {
+ $( 'body' ).toggleClass( 'wp-custom-logo', !! attachmentId );
+ },
+
+ /**
+ * Preview changes to custom css.
+ *
+ * @param {string} value Custom CSS..
+ * @returns {void}
+ */
+ custom_css: function( value ) {
+ $( '#wp-custom-css' ).text( value );
+ },
+
+ /**
+ * Preview changes to any of the background settings.
+ *
+ * @returns {void}
+ */
+ background: function() {
+ var css = '', settings = {};
+
+ _.each( ['color', 'image', 'preset', 'position_x', 'position_y', 'size', 'repeat', 'attachment'], function( prop ) {
+ settings[ prop ] = api( 'background_' + prop );
+ } );
+
+ /*
+ * The body will support custom backgrounds if either the color or image are set.
+ *
+ * See get_body_class() in /wp-includes/post-template.php
+ */
+ $( document.body ).toggleClass( 'custom-background', !! ( settings.color() || settings.image() ) );
+
+ if ( settings.color() ) {
+ css += 'background-color: ' + settings.color() + ';';
+ }
+
+ if ( settings.image() ) {
+ css += 'background-image: url("' + settings.image() + '");';
+ css += 'background-size: ' + settings.size() + ';';
+ css += 'background-position: ' + settings.position_x() + ' ' + settings.position_y() + ';';
+ css += 'background-repeat: ' + settings.repeat() + ';';
+ css += 'background-attachment: ' + settings.attachment() + ';';
+ }
+
+ $( '#custom-background-css' ).text( 'body.custom-background { ' + css + ' }' );
+ }
+ };
$( function() {
var bg, setValue;
@@ -96,6 +664,10 @@
channel: api.settings.channel
});
+ api.addLinkPreviewing();
+ api.addRequestPreviewing();
+ api.addFormPreviewing();
+
/**
* Create/update a setting value.
*
@@ -139,6 +711,25 @@
});
api.preview.bind( 'sync', function( events ) {
+
+ /*
+ * Delete any settings that already exist locally which haven't been
+ * modified in the controls while the preview was loading. This prevents
+ * situations where the JS value being synced from the pane may differ
+ * from the PHP-sanitized JS value in the preview which causes the
+ * non-sanitized JS value to clobber the PHP-sanitized value. This
+ * is particularly important for selective refresh partials that
+ * have a fallback refresh behavior since infinite refreshing would
+ * result.
+ */
+ if ( events.settings && events['settings-modified-while-loading'] ) {
+ _.each( _.keys( events.settings ), function( syncedSettingId ) {
+ if ( api.has( syncedSettingId ) && ! events['settings-modified-while-loading'][ syncedSettingId ] ) {
+ delete events.settings[ syncedSettingId ];
+ }
+ } );
+ }
+
$.each( events, function( event, args ) {
api.preview.trigger( event, args );
});
@@ -149,15 +740,47 @@
api.preview.send( 'nonce', api.settings.nonce );
api.preview.send( 'documentTitle', document.title );
+
+ // Send scroll in case of loading via non-refresh.
+ api.preview.send( 'scroll', $( window ).scrollTop() );
});
api.preview.bind( 'saved', function( response ) {
+
+ if ( response.next_changeset_uuid ) {
+ api.settings.changeset.uuid = response.next_changeset_uuid;
+
+ // Update UUIDs in links and forms.
+ $( document.body ).find( 'a[href], area' ).each( function() {
+ api.prepareLinkPreview( this );
+ } );
+ $( document.body ).find( 'form' ).each( function() {
+ api.prepareFormPreview( this );
+ } );
+
+ /*
+ * Replace the UUID in the URL. Note that the wrapped history.replaceState()
+ * will handle injecting the current api.settings.changeset.uuid into the URL,
+ * so this is merely to trigger that logic.
+ */
+ if ( history.replaceState ) {
+ history.replaceState( currentHistoryState, '', location.href );
+ }
+ }
+
api.trigger( 'saved', response );
} );
- api.bind( 'saved', function() {
- api.each( function( setting ) {
- setting._dirty = false;
+ /*
+ * Clear dirty flag for settings when saved to changeset so that they
+ * won't be needlessly included in selective refresh or ajax requests.
+ */
+ api.preview.bind( 'changeset-saved', function( data ) {
+ _.each( data.saved_changeset_values, function( value, settingId ) {
+ var setting = api( settingId );
+ if ( setting && _.isEqual( setting.get(), value ) ) {
+ setting._dirty = false;
+ }
} );
} );
@@ -170,12 +793,16 @@
* containers and controls are active.
*/
api.preview.send( 'ready', {
+ currentUrl: api.settings.url.self,
activePanels: api.settings.activePanels,
activeSections: api.settings.activeSections,
activeControls: api.settings.activeControls,
settingValidities: api.settings.settingValidities
} );
+ // Send ready when URL changes via JS.
+ setInterval( api.keepAliveCurrentUrl, api.settings.timeouts.keepAliveSend );
+
// Display a loading indicator when preview is reloading, and remove on failure.
api.preview.bind( 'loading-initiated', function () {
$( 'body' ).addClass( 'wp-customizer-unloading' );
@@ -185,42 +812,13 @@
});
/* Custom Backgrounds */
- bg = $.map(['color', 'image', 'position_x', 'repeat', 'attachment'], function( prop ) {
+ bg = $.map( ['color', 'image', 'preset', 'position_x', 'position_y', 'size', 'repeat', 'attachment'], function( prop ) {
return 'background_' + prop;
- });
-
- api.when.apply( api, bg ).done( function( color, image, position_x, repeat, attachment ) {
- var body = $(document.body),
- head = $('head'),
- style = $('#custom-background-css'),
- update;
-
- update = function() {
- var css = '';
-
- // The body will support custom backgrounds if either
- // the color or image are set.
- //
- // See get_body_class() in /wp-includes/post-template.php
- body.toggleClass( 'custom-background', !! ( color() || image() ) );
-
- if ( color() )
- css += 'background-color: ' + color() + ';';
-
- if ( image() ) {
- css += 'background-image: url("' + image() + '");';
- css += 'background-position: top ' + position_x() + ';';
- css += 'background-repeat: ' + repeat() + ';';
- css += 'background-attachment: ' + attachment() + ';';
- }
-
- // Refresh the stylesheet by removing and recreating it.
- style.remove();
- style = $('').appendTo( head );
- };
+ } );
+ api.when.apply( api, bg ).done( function() {
$.each( arguments, function() {
- this.bind( update );
+ this.bind( api.settingPreviewHandlers.background );
});
});
@@ -231,11 +829,13 @@
*
* @since 4.5.0
*/
- api( 'custom_logo', function( setting ) {
- $( 'body' ).toggleClass( 'wp-custom-logo', !! setting.get() );
- setting.bind( function( attachmentId ) {
- $( 'body' ).toggleClass( 'wp-custom-logo', !! attachmentId );
- } );
+ api( 'custom_logo', function ( setting ) {
+ api.settingPreviewHandlers.custom_logo.call( setting, setting.get() );
+ setting.bind( api.settingPreviewHandlers.custom_logo );
+ } );
+
+ api( 'custom_css[' + api.settings.theme.stylesheet + ']', function( setting ) {
+ setting.bind( api.settingPreviewHandlers.custom_css );
} );
api.trigger( 'preview-ready' );
diff --git a/code/wp-includes/js/customize-preview.min.js b/code/wp-includes/js/customize-preview.min.js
index e8413394..964a7a80 100644
--- a/code/wp-includes/js/customize-preview.min.js
+++ b/code/wp-includes/js/customize-preview.min.js
@@ -1 +1 @@
-!function(a,b){var c,d=wp.customize;c=function(a,b,c){var d;return function(){var e=arguments;c=c||this,clearTimeout(d),d=setTimeout(function(){d=null,a.apply(c,e)},b)}},d.Preview=d.Messenger.extend({initialize:function(a,e){var f=this;d.Messenger.prototype.initialize.call(this,a,e),this.body=b(document.body),this.body.on("click.preview","a",function(a){var c,d;c=b(this),d="#"===c.attr("href").substr(0,1),a.preventDefault(),d&&"#"!==c.attr("href")&&b(c.attr("href")).each(function(){this.scrollIntoView()}),a.shiftKey||d||(f.send("scroll",0),f.send("url",c.prop("href")))}),this.body.on("submit.preview","form",function(a){a.preventDefault()}),this.window=b(window),this.window.on("scroll.preview",c(function(){f.send("scroll",f.window.scrollTop())},200)),this.bind("scroll",function(a){f.window.scrollTop(a)})}}),b(function(){var a,c;d.settings=window._wpCustomizeSettings,d.settings&&(d.preview=new d.Preview({url:window.location.href,channel:d.settings.channel}),c=function(a,b,c){var e=d(a);e?e.set(b):(c=c||!1,e=d.create(a,b,{id:a}),c&&(e._dirty=!0))},d.preview.bind("settings",function(a){b.each(a,c)}),d.preview.trigger("settings",d.settings.values),b.each(d.settings._dirty,function(a,b){var c=d(b);c&&(c._dirty=!0)}),d.preview.bind("setting",function(a){var b=!0;c.apply(null,a.concat(b))}),d.preview.bind("sync",function(a){b.each(a,function(a,b){d.preview.trigger(a,b)}),d.preview.send("synced")}),d.preview.bind("active",function(){d.preview.send("nonce",d.settings.nonce),d.preview.send("documentTitle",document.title)}),d.preview.bind("saved",function(a){d.trigger("saved",a)}),d.bind("saved",function(){d.each(function(a){a._dirty=!1})}),d.preview.bind("nonce-refresh",function(a){b.extend(d.settings.nonce,a)}),d.preview.send("ready",{activePanels:d.settings.activePanels,activeSections:d.settings.activeSections,activeControls:d.settings.activeControls,settingValidities:d.settings.settingValidities}),d.preview.bind("loading-initiated",function(){b("body").addClass("wp-customizer-unloading")}),d.preview.bind("loading-failed",function(){b("body").removeClass("wp-customizer-unloading")}),a=b.map(["color","image","position_x","repeat","attachment"],function(a){return"background_"+a}),d.when.apply(d,a).done(function(a,c,d,e,f){var g,h=b(document.body),i=b("head"),j=b("#custom-background-css");g=function(){var g="";h.toggleClass("custom-background",!(!a()&&!c())),a()&&(g+="background-color: "+a()+";"),c()&&(g+='background-image: url("'+c()+'");',g+="background-position: top "+d()+";",g+="background-repeat: "+e()+";",g+="background-attachment: "+f()+";"),j.remove(),j=b('").appendTo(i)},b.each(arguments,function(){this.bind(g)})}),d("custom_logo",function(a){b("body").toggleClass("wp-custom-logo",!!a.get()),a.bind(function(a){b("body").toggleClass("wp-custom-logo",!!a)})}),d.trigger("preview-ready"))})}(wp,jQuery);
\ No newline at end of file
+!function(a,b){var c,d=wp.customize,e={};!function(a){var c;a.replaceState&&(c=function(a){var c,e,f;return c=document.createElement("a"),c.href=a,e=d.utils.parseQueryString(location.search.substr(1)),f=d.utils.parseQueryString(c.search.substr(1)),f.customize_changeset_uuid=e.customize_changeset_uuid,e.customize_theme&&(f.customize_theme=e.customize_theme),e.customize_messenger_channel&&(f.customize_messenger_channel=e.customize_messenger_channel),c.search=b.param(f),c.href},a.replaceState=function(b){return function(d,f,g){return e=d,b.call(a,d,f,c(g))}}(a.replaceState),a.pushState=function(b){return function(d,f,g){return e=d,b.call(a,d,f,c(g))}}(a.pushState),window.addEventListener("popstate",function(a){e=a.state}))}(history),c=function(a,b,c){var d;return function(){var e=arguments;c=c||this,clearTimeout(d),d=setTimeout(function(){d=null,a.apply(c,e)},b)}},d.Preview=d.Messenger.extend({initialize:function(a,e){var f=this,g=document.createElement("a");d.Messenger.prototype.initialize.call(f,a,e),g.href=f.origin(),f.add("scheme",g.protocol.replace(/:$/,"")),f.body=b(document.body),f.window=b(window),d.settings.channel&&(f.body.on("click.preview","a",function(a){f.handleLinkClick(a)}),f.body.on("submit.preview","form",function(a){f.handleFormSubmit(a)}),f.window.on("scroll.preview",c(function(){f.send("scroll",f.window.scrollTop())},200)),f.bind("scroll",function(a){f.window.scrollTop(a)}))},handleLinkClick:function(a){var c,e,f=this;if(c=b(a.target),!_.isUndefined(c.attr("href"))&&(e="#"===c.attr("href").substr(0,1),!e)){if(!d.isLinkPreviewable(c[0]))return wp.a11y.speak(d.settings.l10n.linkUnpreviewable),void a.preventDefault();a.preventDefault(),a.shiftKey||f.send("url",c.prop("href"))}},handleFormSubmit:function(a){var c,e,f=this;return c=document.createElement("a"),e=b(a.target),c.href=e.prop("action"),"GET"===e.prop("method").toUpperCase()&&d.isLinkPreviewable(c)?(a.isDefaultPrevented()||(c.search.length>1&&(c.search+="&"),c.search+=e.serialize(),f.send("url",c.href)),void a.preventDefault()):(wp.a11y.speak(d.settings.l10n.formUnpreviewable),void a.preventDefault())}}),d.addLinkPreviewing=function(){var a="a[href], area";b(document.body).find(a).each(function(){d.prepareLinkPreview(this)}),"undefined"!=typeof MutationObserver?(d.mutationObserver=new MutationObserver(function(c){_.each(c,function(c){b(c.target).find(a).each(function(){d.prepareLinkPreview(this)})})}),d.mutationObserver.observe(document.documentElement,{childList:!0,subtree:!0})):b(document.documentElement).on("click focus mouseover",a,function(){d.prepareLinkPreview(this)})},d.isLinkPreviewable=function(a,b){var c,e,f;return f=_.extend({},{allowAdminAjax:!1},b||{}),"javascript:"===a.protocol||("https:"===a.protocol||"http:"===a.protocol)&&(e=document.createElement("a"),c=!_.isUndefined(_.find(d.settings.url.allowed,function(b){return e.href=b,e.protocol===a.protocol&&e.host===a.host&&0===a.pathname.indexOf(e.pathname.replace(/\/$/,""))})),!!c&&(!/\/wp-(login|signup)\.php$/.test(a.pathname)&&(/\/wp-admin\/admin-ajax\.php$/.test(a.pathname)?f.allowAdminAjax:!/\/wp-(admin|includes|content)(\/|$)/.test(a.pathname))))},d.prepareLinkPreview=function(a){var c;if(!b(a).closest("#wpadminbar").length&&"#"!==b(a).attr("href").substr(0,1)){if(d.settings.channel&&"https"===d.preview.scheme.get()&&"http:"===a.protocol&&-1!==d.settings.url.allowedHosts.indexOf(a.host)&&(a.protocol="https:"),!d.isLinkPreviewable(a))return void(d.settings.channel&&b(a).addClass("customize-unpreviewable"));b(a).removeClass("customize-unpreviewable"),c=d.utils.parseQueryString(a.search.substring(1)),c.customize_changeset_uuid=d.settings.changeset.uuid,d.settings.theme.active||(c.customize_theme=d.settings.theme.stylesheet),d.settings.channel&&(c.customize_messenger_channel=d.settings.channel),a.search=b.param(c),d.settings.channel&&(a.target="_self")}},d.addRequestPreviewing=function(){var a=function(a,c,e){var f,g,h,i={};f=document.createElement("a"),f.href=a.url,d.isLinkPreviewable(f,{allowAdminAjax:!0})&&(g=d.utils.parseQueryString(f.search.substring(1)),d.each(function(a){a._dirty&&(i[a.id]=a.get())}),_.isEmpty(i)||(h=a.type.toUpperCase(),"POST"!==h&&(e.setRequestHeader("X-HTTP-Method-Override",h),g._method=h,a.type="POST"),a.data?a.data+="&":a.data="",a.data+=b.param({customized:JSON.stringify(i)})),g.customize_changeset_uuid=d.settings.changeset.uuid,d.settings.theme.active||(g.customize_theme=d.settings.theme.stylesheet),f.search=b.param(g),a.url=f.href)};b.ajaxPrefilter(a)},d.addFormPreviewing=function(){b(document.body).find("form").each(function(){d.prepareFormPreview(this)}),"undefined"!=typeof MutationObserver&&(d.mutationObserver=new MutationObserver(function(a){_.each(a,function(a){b(a.target).find("form").each(function(){d.prepareFormPreview(this)})})}),d.mutationObserver.observe(document.documentElement,{childList:!0,subtree:!0}))},d.prepareFormPreview=function(a){var c,e={};return a.action||(a.action=location.href),c=document.createElement("a"),c.href=a.action,d.settings.channel&&"https"===d.preview.scheme.get()&&"http:"===c.protocol&&-1!==d.settings.url.allowedHosts.indexOf(c.host)&&(c.protocol="https:",a.action=c.href),"GET"===a.method.toUpperCase()&&d.isLinkPreviewable(c)?(b(a).removeClass("customize-unpreviewable"),e.customize_changeset_uuid=d.settings.changeset.uuid,d.settings.theme.active||(e.customize_theme=d.settings.theme.stylesheet),d.settings.channel&&(e.customize_messenger_channel=d.settings.channel),_.each(e,function(c,d){var e=b(a).find('input[name="'+d+'"]');e.length?e.val(c):b(a).prepend(b("",{type:"hidden",name:d,value:c}))}),void(d.settings.channel&&(a.target="_self"))):void(d.settings.channel&&b(a).addClass("customize-unpreviewable"))},d.keepAliveCurrentUrl=function(){var a=location.pathname,c=location.search.substr(1),e=null,f=["customize_theme","customize_changeset_uuid","customize_messenger_channel"];return function(){var g,h;return c===location.search.substr(1)&&a===location.pathname?void d.preview.send("keep-alive"):(g=document.createElement("a"),null===e&&(g.search=c,e=d.utils.parseQueryString(c),_.each(f,function(a){delete e[a]})),g.href=location.href,h=d.utils.parseQueryString(g.search.substr(1)),_.each(f,function(a){delete h[a]}),a===location.pathname&&_.isEqual(e,h)?d.preview.send("keep-alive"):(g.search=b.param(h),g.hash="",d.settings.url.self=g.href,d.preview.send("ready",{currentUrl:d.settings.url.self,activePanels:d.settings.activePanels,activeSections:d.settings.activeSections,activeControls:d.settings.activeControls,settingValidities:d.settings.settingValidities})),e=h,c=location.search.substr(1),void(a=location.pathname))}}(),d.settingPreviewHandlers={custom_logo:function(a){b("body").toggleClass("wp-custom-logo",!!a)},custom_css:function(a){b("#wp-custom-css").text(a)},background:function(){var a="",c={};_.each(["color","image","preset","position_x","position_y","size","repeat","attachment"],function(a){c[a]=d("background_"+a)}),b(document.body).toggleClass("custom-background",!(!c.color()&&!c.image())),c.color()&&(a+="background-color: "+c.color()+";"),c.image()&&(a+='background-image: url("'+c.image()+'");',a+="background-size: "+c.size()+";",a+="background-position: "+c.position_x()+" "+c.position_y()+";",a+="background-repeat: "+c.repeat()+";",a+="background-attachment: "+c.attachment()+";"),b("#custom-background-css").text("body.custom-background { "+a+" }")}},b(function(){var a,c;d.settings=window._wpCustomizeSettings,d.settings&&(d.preview=new d.Preview({url:window.location.href,channel:d.settings.channel}),d.addLinkPreviewing(),d.addRequestPreviewing(),d.addFormPreviewing(),c=function(a,b,c){var e=d(a);e?e.set(b):(c=c||!1,e=d.create(a,b,{id:a}),c&&(e._dirty=!0))},d.preview.bind("settings",function(a){b.each(a,c)}),d.preview.trigger("settings",d.settings.values),b.each(d.settings._dirty,function(a,b){var c=d(b);c&&(c._dirty=!0)}),d.preview.bind("setting",function(a){var b=!0;c.apply(null,a.concat(b))}),d.preview.bind("sync",function(a){a.settings&&a["settings-modified-while-loading"]&&_.each(_.keys(a.settings),function(b){d.has(b)&&!a["settings-modified-while-loading"][b]&&delete a.settings[b]}),b.each(a,function(a,b){d.preview.trigger(a,b)}),d.preview.send("synced")}),d.preview.bind("active",function(){d.preview.send("nonce",d.settings.nonce),d.preview.send("documentTitle",document.title),d.preview.send("scroll",b(window).scrollTop())}),d.preview.bind("saved",function(a){a.next_changeset_uuid&&(d.settings.changeset.uuid=a.next_changeset_uuid,b(document.body).find("a[href], area").each(function(){d.prepareLinkPreview(this)}),b(document.body).find("form").each(function(){d.prepareFormPreview(this)}),history.replaceState&&history.replaceState(e,"",location.href)),d.trigger("saved",a)}),d.preview.bind("changeset-saved",function(a){_.each(a.saved_changeset_values,function(a,b){var c=d(b);c&&_.isEqual(c.get(),a)&&(c._dirty=!1)})}),d.preview.bind("nonce-refresh",function(a){b.extend(d.settings.nonce,a)}),d.preview.send("ready",{currentUrl:d.settings.url.self,activePanels:d.settings.activePanels,activeSections:d.settings.activeSections,activeControls:d.settings.activeControls,settingValidities:d.settings.settingValidities}),setInterval(d.keepAliveCurrentUrl,d.settings.timeouts.keepAliveSend),d.preview.bind("loading-initiated",function(){b("body").addClass("wp-customizer-unloading")}),d.preview.bind("loading-failed",function(){b("body").removeClass("wp-customizer-unloading")}),a=b.map(["color","image","preset","position_x","position_y","size","repeat","attachment"],function(a){return"background_"+a}),d.when.apply(d,a).done(function(){b.each(arguments,function(){this.bind(d.settingPreviewHandlers.background)})}),d("custom_logo",function(a){d.settingPreviewHandlers.custom_logo.call(a,a.get()),a.bind(d.settingPreviewHandlers.custom_logo)}),d("custom_css["+d.settings.theme.stylesheet+"]",function(a){a.bind(d.settingPreviewHandlers.custom_css)}),d.trigger("preview-ready"))})}(wp,jQuery);
\ No newline at end of file
diff --git a/code/wp-includes/js/customize-selective-refresh.js b/code/wp-includes/js/customize-selective-refresh.js
index ec51058e..f6dfa0b9 100644
--- a/code/wp-includes/js/customize-selective-refresh.js
+++ b/code/wp-includes/js/customize-selective-refresh.js
@@ -6,13 +6,13 @@ wp.customize.selectiveRefresh = ( function( $, api ) {
self = {
ready: $.Deferred(),
+ editShortcutVisibility: new api.Value(),
data: {
partials: {},
renderQueryVar: '',
l10n: {
shiftClickToEdit: ''
- },
- refreshBuffer: 250
+ }
},
currentRequest: null
};
@@ -43,7 +43,7 @@ wp.customize.selectiveRefresh = ( function( $, api ) {
id: null,
- /**
+ /**
* Constructor.
*
* @since 4.5.0
@@ -83,8 +83,9 @@ wp.customize.selectiveRefresh = ( function( $, api ) {
*/
ready: function() {
var partial = this;
- _.each( _.pluck( partial.placements(), 'container' ), function( container ) {
- $( container ).attr( 'title', self.data.l10n.shiftClickToEdit );
+ _.each( partial.placements(), function( placement ) {
+ $( placement.container ).attr( 'title', self.data.l10n.shiftClickToEdit );
+ partial.createEditShortcutForPlacement( placement );
} );
$( document ).on( 'click', partial.params.selector, function( e ) {
if ( ! e.shiftKey ) {
@@ -99,6 +100,141 @@ wp.customize.selectiveRefresh = ( function( $, api ) {
} );
},
+ /**
+ * Create and show the edit shortcut for a given partial placement container.
+ *
+ * @since 4.7.0
+ * @access public
+ *
+ * @param {Placement} placement The placement container element.
+ * @returns {void}
+ */
+ createEditShortcutForPlacement: function( placement ) {
+ var partial = this, $shortcut, $placementContainer, illegalAncestorSelector, illegalContainerSelector;
+ if ( ! placement.container ) {
+ return;
+ }
+ $placementContainer = $( placement.container );
+ illegalAncestorSelector = 'head';
+ illegalContainerSelector = 'area, audio, base, bdi, bdo, br, button, canvas, col, colgroup, command, datalist, embed, head, hr, html, iframe, img, input, keygen, label, link, map, math, menu, meta, noscript, object, optgroup, option, param, progress, rp, rt, ruby, script, select, source, style, svg, table, tbody, textarea, tfoot, thead, title, tr, track, video, wbr';
+ if ( ! $placementContainer.length || $placementContainer.is( illegalContainerSelector ) || $placementContainer.closest( illegalAncestorSelector ).length ) {
+ return;
+ }
+ $shortcut = partial.createEditShortcut();
+ partial.addEditShortcutToPlacement( placement, $shortcut );
+ $shortcut.on( 'click', function( event ) {
+ event.preventDefault();
+ event.stopPropagation();
+ partial.showControl();
+ } );
+ },
+
+ /**
+ * Add an edit shortcut to the placement container.
+ *
+ * @since 4.7.0
+ * @access public
+ *
+ * @param {Placement} placement The placement for the partial.
+ * @param {jQuery} $editShortcut The shortcut element as a jQuery object.
+ * @returns {void}
+ */
+ addEditShortcutToPlacement: function( placement, $editShortcut ) {
+ var $placementContainer = $( placement.container );
+ $placementContainer.prepend( $editShortcut );
+ if ( ! $placementContainer.is( ':visible' ) || 'none' === $placementContainer.css( 'display' ) ) {
+ $editShortcut.addClass( 'customize-partial-edit-shortcut-hidden' );
+ }
+ },
+
+ /**
+ * Return the unique class name for the edit shortcut button for this partial.
+ *
+ * @since 4.7.0
+ * @access public
+ *
+ * @return {string} Partial ID converted into a class name for use in shortcut.
+ */
+ getEditShortcutClassName: function() {
+ var partial = this, cleanId;
+ cleanId = partial.id.replace( /]/g, '' ).replace( /\[/g, '-' );
+ return 'customize-partial-edit-shortcut-' + cleanId;
+ },
+
+ /**
+ * Return the appropriate translated string for the edit shortcut button.
+ *
+ * @since 4.7.0
+ * @access public
+ *
+ * @return {string} Tooltip for edit shortcut.
+ */
+ getEditShortcutTitle: function() {
+ var partial = this, l10n = self.data.l10n;
+ switch ( partial.getType() ) {
+ case 'widget':
+ return l10n.clickEditWidget;
+ case 'blogname':
+ return l10n.clickEditTitle;
+ case 'blogdescription':
+ return l10n.clickEditTitle;
+ case 'nav_menu':
+ return l10n.clickEditMenu;
+ default:
+ return l10n.clickEditMisc;
+ }
+ },
+
+ /**
+ * Return the type of this partial
+ *
+ * Will use `params.type` if set, but otherwise will try to infer type from settingId.
+ *
+ * @since 4.7.0
+ * @access public
+ *
+ * @return {string} Type of partial derived from type param or the related setting ID.
+ */
+ getType: function() {
+ var partial = this, settingId;
+ settingId = partial.params.primarySetting || _.first( partial.settings() ) || 'unknown';
+ if ( partial.params.type ) {
+ return partial.params.type;
+ }
+ if ( settingId.match( /^nav_menu_instance\[/ ) ) {
+ return 'nav_menu';
+ }
+ if ( settingId.match( /^widget_.+\[\d+]$/ ) ) {
+ return 'widget';
+ }
+ return settingId;
+ },
+
+ /**
+ * Create an edit shortcut button for this partial.
+ *
+ * @since 4.7.0
+ * @access public
+ *
+ * @return {jQuery} The edit shortcut button element.
+ */
+ createEditShortcut: function() {
+ var partial = this, shortcutTitle, $buttonContainer, $button, $image;
+ shortcutTitle = partial.getEditShortcutTitle();
+ $buttonContainer = $( '', {
+ 'class': 'customize-partial-edit-shortcut ' + partial.getEditShortcutClassName()
+ } );
+ $button = $( '', {
+ 'aria-label': shortcutTitle,
+ 'title': shortcutTitle,
+ 'class': 'customize-partial-edit-shortcut-button'
+ } );
+ $image = $( '' );
+ $button.append( $image );
+ $buttonContainer.append( $button );
+ return $buttonContainer;
+ },
+
/**
* Find all placements for this partial int he document.
*
@@ -176,10 +312,16 @@ wp.customize.selectiveRefresh = ( function( $, api ) {
* @since 4.5.0
*/
showControl: function() {
- var partial = this, settingId = partial.params.primarySetting;
+ var partial = this, settingId = partial.params.primarySetting, menuSlug;
if ( ! settingId ) {
settingId = _.first( partial.settings() );
}
+ if ( partial.getType() === 'nav_menu' ) {
+ menuSlug = partial.params.navMenuArgs.theme_location;
+ if ( menuSlug ) {
+ settingId = 'nav_menu_locations[' + menuSlug + ']';
+ }
+ }
api.preview.send( 'focus-control-for-setting', settingId );
},
@@ -320,6 +462,7 @@ wp.customize.selectiveRefresh = ( function( $, api ) {
self.orginalDocumentWrite = null;
/* jshint ignore:end */
+ partial.createEditShortcutForPlacement( placement );
placement.container.removeClass( 'customize-partial-refreshing' );
// Prevent placement container from being being re-triggered as being rendered among nested partials.
@@ -485,8 +628,9 @@ wp.customize.selectiveRefresh = ( function( $, api ) {
return {
wp_customize: 'on',
nonce: api.settings.nonce.preview,
- theme: api.settings.theme.stylesheet,
- customized: JSON.stringify( dirtyCustomized )
+ customize_theme: api.settings.theme.stylesheet,
+ customized: JSON.stringify( dirtyCustomized ),
+ customize_changeset_uuid: api.settings.changeset.uuid
};
};
@@ -668,7 +812,7 @@ wp.customize.selectiveRefresh = ( function( $, api ) {
self._pendingPartialRequests = {};
} );
},
- self.data.refreshBuffer
+ api.settings.timeouts.selectiveRefresh
);
return partialRequest.deferred.promise();
@@ -745,11 +889,6 @@ wp.customize.selectiveRefresh = ( function( $, api ) {
api.bind( 'preview-ready', function() {
var handleSettingChange, watchSettingChange, unwatchSettingChange;
- // Polyfill for IE8 to support the document.head attribute.
- if ( ! document.head ) {
- document.head = $( 'head:first' )[0];
- }
-
_.extend( self.data, _customizePartialRefreshExports );
// Create the partial JS models.
@@ -859,6 +998,17 @@ wp.customize.selectiveRefresh = ( function( $, api ) {
}
} );
+ api.preview.bind( 'edit-shortcut-visibility', function( visibility ) {
+ api.selectiveRefresh.editShortcutVisibility.set( visibility );
+ } );
+ api.selectiveRefresh.editShortcutVisibility.bind( function( visibility ) {
+ var body = $( document.body ), shouldAnimateHide;
+
+ shouldAnimateHide = ( 'hidden' === visibility && body.hasClass( 'customize-partial-edit-shortcuts-shown' ) && ! body.hasClass( 'customize-partial-edit-shortcuts-hidden' ) );
+ body.toggleClass( 'customize-partial-edit-shortcuts-hidden', shouldAnimateHide );
+ body.toggleClass( 'customize-partial-edit-shortcuts-shown', 'visible' === visibility );
+ } );
+
api.preview.bind( 'active', function() {
// Make all partials ready.
diff --git a/code/wp-includes/js/customize-selective-refresh.min.js b/code/wp-includes/js/customize-selective-refresh.min.js
index d84e66fb..599120ce 100644
--- a/code/wp-includes/js/customize-selective-refresh.min.js
+++ b/code/wp-includes/js/customize-selective-refresh.min.js
@@ -1 +1 @@
-wp.customize.selectiveRefresh=function(a,b){"use strict";var c,d,e;return c={ready:a.Deferred(),data:{partials:{},renderQueryVar:"",l10n:{shiftClickToEdit:""},refreshBuffer:250},currentRequest:null},_.extend(c,b.Events),d=c.Partial=b.Class.extend({id:null,initialize:function(b,c){var d=this;c=c||{},d.id=b,d.params=_.extend({selector:null,settings:[],primarySetting:null,containerInclusive:!1,fallbackRefresh:!0},c.params||{}),d.deferred={},d.deferred.ready=a.Deferred(),d.deferred.ready.done(function(){d.ready()})},ready:function(){var b=this;_.each(_.pluck(b.placements(),"container"),function(b){a(b).attr("title",c.data.l10n.shiftClickToEdit)}),a(document).on("click",b.params.selector,function(c){c.shiftKey&&(c.preventDefault(),_.each(b.placements(),function(d){a(d.container).is(c.currentTarget)&&b.showControl()}))})},placements:function(){var b,c=this;return b=c.params.selector||"",b&&(b+=", "),b+='[data-customize-partial-id="'+c.id+'"]',a(b).map(function(){var b,d=a(this);if(b=d.data("customize-partial-placement-context"),_.isString(b)&&"{"===b.substr(0,1))throw new Error("context JSON parse error");return new e({partial:c,container:d,context:b})}).get()},settings:function(){var a=this;return a.params.settings&&0!==a.params.settings.length?a.params.settings:a.params.primarySetting?[a.params.primarySetting]:[a.id]},isRelatedSetting:function(a){var c=this;return _.isString(a)&&(a=b(a)),!!a&&-1!==_.indexOf(c.settings(),a.id)},showControl:function(){var a=this,c=a.params.primarySetting;c||(c=_.first(a.settings())),b.preview.send("focus-control-for-setting",c)},preparePlacement:function(b){a(b.container).addClass("customize-partial-refreshing")},_pendingRefreshPromise:null,refresh:function(){var a,b=this;return a=c.requestPartial(b),b._pendingRefreshPromise||(_.each(b.placements(),function(a){b.preparePlacement(a)}),a.done(function(a){_.each(a,function(a){b.renderContent(a)})}),a.fail(function(a,c){b.fallback(a,c)}),b._pendingRefreshPromise=a,a.always(function(){b._pendingRefreshPromise=null})),a},renderContent:function(b){var d,e,f=this;if(!b.container)return f.fallback(new Error("no_container"),[b]),!1;if(b.container=a(b.container),!1===b.addedContent)return f.fallback(new Error("missing_render"),[b]),!1;if(!_.isString(b.addedContent))return f.fallback(new Error("non_string_content"),[b]),!1;c.orginalDocumentWrite=document.write,document.write=function(){throw new Error(c.data.l10n.badDocumentWrite)};try{if(d=b.addedContent,wp.emoji&&wp.emoji.parse&&!a.contains(document.head,b.container[0])&&(d=wp.emoji.parse(d)),f.params.containerInclusive)e=a(d),b.context=_.extend(b.context,e.data("customize-partial-placement-context")||{}),e.data("customize-partial-placement-context",b.context),b.removedNodes=b.container,b.container=e,b.removedNodes.replaceWith(b.container),b.container.attr("title",c.data.l10n.shiftClickToEdit);else{for(b.removedNodes=document.createDocumentFragment();b.container[0].firstChild;)b.removedNodes.appendChild(b.container[0].firstChild);b.container.html(d)}b.container.removeClass("customize-render-content-error")}catch(g){"undefined"!=typeof console&&console.error&&console.error(f.id,g)}return document.write=c.orginalDocumentWrite,c.orginalDocumentWrite=null,b.container.removeClass("customize-partial-refreshing"),b.container.data("customize-partial-content-rendered",!0),c.trigger("partial-content-rendered",b),!0},fallback:function(){var a=this;a.params.fallbackRefresh&&c.requestFullRefresh()}}),c.Placement=e=b.Class.extend({partial:null,container:null,startNode:null,endNode:null,context:null,addedContent:null,removedNodes:null,initialize:function(b){var c=this;if(b=_.extend({},b||{}),!b.partial||!b.partial.extended(d))throw new Error("Missing partial");b.context=b.context||{},b.container&&(b.container=a(b.container)),_.extend(c,b)}}),c.partialConstructor={},c.partial=new b.Values({defaultConstructor:d}),c.getCustomizeQuery=function(){var a={};return b.each(function(b,c){b._dirty&&(a[c]=b())}),{wp_customize:"on",nonce:b.settings.nonce.preview,theme:b.settings.theme.stylesheet,customized:JSON.stringify(a)}},c._pendingPartialRequests={},c._debouncedTimeoutId=null,c._currentRequest=null,c.requestFullRefresh=function(){b.preview.send("refresh")},c.requestPartial=function(d){var f;return c._debouncedTimeoutId&&(clearTimeout(c._debouncedTimeoutId),c._debouncedTimeoutId=null),c._currentRequest&&(c._currentRequest.abort(),c._currentRequest=null),f=c._pendingPartialRequests[d.id],f&&"pending"===f.deferred.state()||(f={deferred:a.Deferred(),partial:d},c._pendingPartialRequests[d.id]=f),d=null,c._debouncedTimeoutId=setTimeout(function(){var a,d,f,g;c._debouncedTimeoutId=null,a=c.getCustomizeQuery(),f={},d={},_.each(c._pendingPartialRequests,function(a,b){f[b]=a.partial.placements(),c.partial.has(b)?d[b]=_.map(f[b],function(a){return a.context||{}}):a.deferred.rejectWith(a.partial,[new Error("partial_removed"),f[b]])}),a.partials=JSON.stringify(d),a[c.data.renderQueryVar]="1",g=c._currentRequest=wp.ajax.send(null,{data:a,url:b.settings.url.self}),g.done(function(a){c.trigger("render-partials-response",a),a.errors&&"undefined"!=typeof console&&console.warn&&_.each(a.errors,function(a){console.warn(a)}),_.each(c._pendingPartialRequests,function(b,c){var d;_.isArray(a.contents[c])?(d=_.map(a.contents[c],function(a,d){var g=f[c][d];return g?g.addedContent=a:g=new e({partial:b.partial,addedContent:a}),g}),b.deferred.resolveWith(b.partial,[d])):b.deferred.rejectWith(b.partial,[new Error("unrecognized_partial"),f[c]])}),c._pendingPartialRequests={}}),g.fail(function(a,b){"abort"!==b&&(_.each(c._pendingPartialRequests,function(b,c){b.deferred.rejectWith(b.partial,[a,f[c]])}),c._pendingPartialRequests={})})},c.data.refreshBuffer),f.deferred.promise()},c.addPartials=function(b,d){var f;b||(b=document.documentElement),b=a(b),d=_.extend({triggerRendered:!0},d||{}),f=b.find("[data-customize-partial-id]"),b.is("[data-customize-partial-id]")&&(f=f.add(b)),f.each(function(){var b,f,g,h,i,j=a(this);f=j.data("customize-partial-id"),f&&(i=j.data("customize-partial-placement-context")||{},b=c.partial(f),b||(h=j.data("customize-partial-options")||{},h.constructingContainerContext=j.data("customize-partial-placement-context")||{},g=c.partialConstructor[j.data("customize-partial-type")]||c.Partial,b=new g(f,h),c.partial.add(b.id,b)),d.triggerRendered&&!j.data("customize-partial-content-rendered")&&c.trigger("partial-content-rendered",new e({partial:b,context:i,container:j})),j.data("customize-partial-content-rendered",!0))})},b.bind("preview-ready",function(){var d,e,f;document.head||(document.head=a("head:first")[0]),_.extend(c.data,_customizePartialRefreshExports),_.each(c.data.partials,function(a,b){var d,e=c.partial(b);e?_.extend(e.params,a):(d=c.partialConstructor[a.type]||c.Partial,e=new d(b,{params:a}),c.partial.add(b,e))}),d=function(a,b){var d=this;c.partial.each(function(c){c.isRelatedSetting(d,a,b)&&c.refresh()})},e=function(a){d.call(a,a(),null),a.bind(d)},f=function(a){d.call(a,null,a()),a.unbind(d)},b.bind("add",e),b.bind("remove",f),b.each(function(a){a.bind(d)}),c.addPartials(document.documentElement,{triggerRendered:!1}),"undefined"!=typeof MutationObserver&&(c.mutationObserver=new MutationObserver(function(b){_.each(b,function(b){c.addPartials(a(b.target))})}),c.mutationObserver.observe(document.documentElement,{childList:!0,subtree:!0})),b.selectiveRefresh.bind("partial-content-rendered",function(a){a.container&&c.addPartials(a.container)}),b.selectiveRefresh.bind("render-partials-response",function(a){a.setting_validities&&b.preview.send("selective-refresh-setting-validities",a.setting_validities)}),b.preview.bind("active",function(){c.partial.each(function(a){a.deferred.ready.resolve()}),c.partial.bind("add",function(a){a.deferred.ready.resolve()})})}),c}(jQuery,wp.customize);
\ No newline at end of file
+wp.customize.selectiveRefresh=function(a,b){"use strict";var c,d,e;return c={ready:a.Deferred(),editShortcutVisibility:new b.Value,data:{partials:{},renderQueryVar:"",l10n:{shiftClickToEdit:""}},currentRequest:null},_.extend(c,b.Events),d=c.Partial=b.Class.extend({id:null,initialize:function(b,c){var d=this;c=c||{},d.id=b,d.params=_.extend({selector:null,settings:[],primarySetting:null,containerInclusive:!1,fallbackRefresh:!0},c.params||{}),d.deferred={},d.deferred.ready=a.Deferred(),d.deferred.ready.done(function(){d.ready()})},ready:function(){var b=this;_.each(b.placements(),function(d){a(d.container).attr("title",c.data.l10n.shiftClickToEdit),b.createEditShortcutForPlacement(d)}),a(document).on("click",b.params.selector,function(c){c.shiftKey&&(c.preventDefault(),_.each(b.placements(),function(d){a(d.container).is(c.currentTarget)&&b.showControl()}))})},createEditShortcutForPlacement:function(b){var c,d,e,f,g=this;b.container&&(d=a(b.container),e="head",f="area, audio, base, bdi, bdo, br, button, canvas, col, colgroup, command, datalist, embed, head, hr, html, iframe, img, input, keygen, label, link, map, math, menu, meta, noscript, object, optgroup, option, param, progress, rp, rt, ruby, script, select, source, style, svg, table, tbody, textarea, tfoot, thead, title, tr, track, video, wbr",!d.length||d.is(f)||d.closest(e).length||(c=g.createEditShortcut(),g.addEditShortcutToPlacement(b,c),c.on("click",function(a){a.preventDefault(),a.stopPropagation(),g.showControl()})))},addEditShortcutToPlacement:function(b,c){var d=a(b.container);d.prepend(c),d.is(":visible")&&"none"!==d.css("display")||c.addClass("customize-partial-edit-shortcut-hidden")},getEditShortcutClassName:function(){var a,b=this;return a=b.id.replace(/]/g,"").replace(/\[/g,"-"),"customize-partial-edit-shortcut-"+a},getEditShortcutTitle:function(){var a=this,b=c.data.l10n;switch(a.getType()){case"widget":return b.clickEditWidget;case"blogname":return b.clickEditTitle;case"blogdescription":return b.clickEditTitle;case"nav_menu":return b.clickEditMenu;default:return b.clickEditMisc}},getType:function(){var a,b=this;return a=b.params.primarySetting||_.first(b.settings())||"unknown",b.params.type?b.params.type:a.match(/^nav_menu_instance\[/)?"nav_menu":a.match(/^widget_.+\[\d+]$/)?"widget":a},createEditShortcut:function(){var b,c,d,e,f=this;return b=f.getEditShortcutTitle(),c=a("",{"class":"customize-partial-edit-shortcut "+f.getEditShortcutClassName()}),d=a("",{"aria-label":b,title:b,"class":"customize-partial-edit-shortcut-button"}),e=a(''),d.append(e),c.append(d),c},placements:function(){var b,c=this;return b=c.params.selector||"",b&&(b+=", "),b+='[data-customize-partial-id="'+c.id+'"]',a(b).map(function(){var b,d=a(this);if(b=d.data("customize-partial-placement-context"),_.isString(b)&&"{"===b.substr(0,1))throw new Error("context JSON parse error");return new e({partial:c,container:d,context:b})}).get()},settings:function(){var a=this;return a.params.settings&&0!==a.params.settings.length?a.params.settings:a.params.primarySetting?[a.params.primarySetting]:[a.id]},isRelatedSetting:function(a){var c=this;return _.isString(a)&&(a=b(a)),!!a&&-1!==_.indexOf(c.settings(),a.id)},showControl:function(){var a,c=this,d=c.params.primarySetting;d||(d=_.first(c.settings())),"nav_menu"===c.getType()&&(a=c.params.navMenuArgs.theme_location,a&&(d="nav_menu_locations["+a+"]")),b.preview.send("focus-control-for-setting",d)},preparePlacement:function(b){a(b.container).addClass("customize-partial-refreshing")},_pendingRefreshPromise:null,refresh:function(){var a,b=this;return a=c.requestPartial(b),b._pendingRefreshPromise||(_.each(b.placements(),function(a){b.preparePlacement(a)}),a.done(function(a){_.each(a,function(a){b.renderContent(a)})}),a.fail(function(a,c){b.fallback(a,c)}),b._pendingRefreshPromise=a,a.always(function(){b._pendingRefreshPromise=null})),a},renderContent:function(b){var d,e,f=this;if(!b.container)return f.fallback(new Error("no_container"),[b]),!1;if(b.container=a(b.container),!1===b.addedContent)return f.fallback(new Error("missing_render"),[b]),!1;if(!_.isString(b.addedContent))return f.fallback(new Error("non_string_content"),[b]),!1;c.orginalDocumentWrite=document.write,document.write=function(){throw new Error(c.data.l10n.badDocumentWrite)};try{if(d=b.addedContent,wp.emoji&&wp.emoji.parse&&!a.contains(document.head,b.container[0])&&(d=wp.emoji.parse(d)),f.params.containerInclusive)e=a(d),b.context=_.extend(b.context,e.data("customize-partial-placement-context")||{}),e.data("customize-partial-placement-context",b.context),b.removedNodes=b.container,b.container=e,b.removedNodes.replaceWith(b.container),b.container.attr("title",c.data.l10n.shiftClickToEdit);else{for(b.removedNodes=document.createDocumentFragment();b.container[0].firstChild;)b.removedNodes.appendChild(b.container[0].firstChild);b.container.html(d)}b.container.removeClass("customize-render-content-error")}catch(g){"undefined"!=typeof console&&console.error&&console.error(f.id,g)}return document.write=c.orginalDocumentWrite,c.orginalDocumentWrite=null,f.createEditShortcutForPlacement(b),b.container.removeClass("customize-partial-refreshing"),b.container.data("customize-partial-content-rendered",!0),c.trigger("partial-content-rendered",b),!0},fallback:function(){var a=this;a.params.fallbackRefresh&&c.requestFullRefresh()}}),c.Placement=e=b.Class.extend({partial:null,container:null,startNode:null,endNode:null,context:null,addedContent:null,removedNodes:null,initialize:function(b){var c=this;if(b=_.extend({},b||{}),!b.partial||!b.partial.extended(d))throw new Error("Missing partial");b.context=b.context||{},b.container&&(b.container=a(b.container)),_.extend(c,b)}}),c.partialConstructor={},c.partial=new b.Values({defaultConstructor:d}),c.getCustomizeQuery=function(){var a={};return b.each(function(b,c){b._dirty&&(a[c]=b())}),{wp_customize:"on",nonce:b.settings.nonce.preview,customize_theme:b.settings.theme.stylesheet,customized:JSON.stringify(a),customize_changeset_uuid:b.settings.changeset.uuid}},c._pendingPartialRequests={},c._debouncedTimeoutId=null,c._currentRequest=null,c.requestFullRefresh=function(){b.preview.send("refresh")},c.requestPartial=function(d){var f;return c._debouncedTimeoutId&&(clearTimeout(c._debouncedTimeoutId),c._debouncedTimeoutId=null),c._currentRequest&&(c._currentRequest.abort(),c._currentRequest=null),f=c._pendingPartialRequests[d.id],f&&"pending"===f.deferred.state()||(f={deferred:a.Deferred(),partial:d},c._pendingPartialRequests[d.id]=f),d=null,c._debouncedTimeoutId=setTimeout(function(){var a,d,f,g;c._debouncedTimeoutId=null,a=c.getCustomizeQuery(),f={},d={},_.each(c._pendingPartialRequests,function(a,b){f[b]=a.partial.placements(),c.partial.has(b)?d[b]=_.map(f[b],function(a){return a.context||{}}):a.deferred.rejectWith(a.partial,[new Error("partial_removed"),f[b]])}),a.partials=JSON.stringify(d),a[c.data.renderQueryVar]="1",g=c._currentRequest=wp.ajax.send(null,{data:a,url:b.settings.url.self}),g.done(function(a){c.trigger("render-partials-response",a),a.errors&&"undefined"!=typeof console&&console.warn&&_.each(a.errors,function(a){console.warn(a)}),_.each(c._pendingPartialRequests,function(b,c){var d;_.isArray(a.contents[c])?(d=_.map(a.contents[c],function(a,d){var g=f[c][d];return g?g.addedContent=a:g=new e({partial:b.partial,addedContent:a}),g}),b.deferred.resolveWith(b.partial,[d])):b.deferred.rejectWith(b.partial,[new Error("unrecognized_partial"),f[c]])}),c._pendingPartialRequests={}}),g.fail(function(a,b){"abort"!==b&&(_.each(c._pendingPartialRequests,function(b,c){b.deferred.rejectWith(b.partial,[a,f[c]])}),c._pendingPartialRequests={})})},b.settings.timeouts.selectiveRefresh),f.deferred.promise()},c.addPartials=function(b,d){var f;b||(b=document.documentElement),b=a(b),d=_.extend({triggerRendered:!0},d||{}),f=b.find("[data-customize-partial-id]"),b.is("[data-customize-partial-id]")&&(f=f.add(b)),f.each(function(){var b,f,g,h,i,j=a(this);f=j.data("customize-partial-id"),f&&(i=j.data("customize-partial-placement-context")||{},b=c.partial(f),b||(h=j.data("customize-partial-options")||{},h.constructingContainerContext=j.data("customize-partial-placement-context")||{},g=c.partialConstructor[j.data("customize-partial-type")]||c.Partial,b=new g(f,h),c.partial.add(b.id,b)),d.triggerRendered&&!j.data("customize-partial-content-rendered")&&c.trigger("partial-content-rendered",new e({partial:b,context:i,container:j})),j.data("customize-partial-content-rendered",!0))})},b.bind("preview-ready",function(){var d,e,f;_.extend(c.data,_customizePartialRefreshExports),_.each(c.data.partials,function(a,b){var d,e=c.partial(b);e?_.extend(e.params,a):(d=c.partialConstructor[a.type]||c.Partial,e=new d(b,{params:a}),c.partial.add(b,e))}),d=function(a,b){var d=this;c.partial.each(function(c){c.isRelatedSetting(d,a,b)&&c.refresh()})},e=function(a){d.call(a,a(),null),a.bind(d)},f=function(a){d.call(a,null,a()),a.unbind(d)},b.bind("add",e),b.bind("remove",f),b.each(function(a){a.bind(d)}),c.addPartials(document.documentElement,{triggerRendered:!1}),"undefined"!=typeof MutationObserver&&(c.mutationObserver=new MutationObserver(function(b){_.each(b,function(b){c.addPartials(a(b.target))})}),c.mutationObserver.observe(document.documentElement,{childList:!0,subtree:!0})),b.selectiveRefresh.bind("partial-content-rendered",function(a){a.container&&c.addPartials(a.container)}),b.selectiveRefresh.bind("render-partials-response",function(a){a.setting_validities&&b.preview.send("selective-refresh-setting-validities",a.setting_validities)}),b.preview.bind("edit-shortcut-visibility",function(a){b.selectiveRefresh.editShortcutVisibility.set(a)}),b.selectiveRefresh.editShortcutVisibility.bind(function(b){var c,d=a(document.body);c="hidden"===b&&d.hasClass("customize-partial-edit-shortcuts-shown")&&!d.hasClass("customize-partial-edit-shortcuts-hidden"),d.toggleClass("customize-partial-edit-shortcuts-hidden",c),d.toggleClass("customize-partial-edit-shortcuts-shown","visible"===b)}),b.preview.bind("active",function(){c.partial.each(function(a){a.deferred.ready.resolve()}),c.partial.bind("add",function(a){a.deferred.ready.resolve()})})}),c}(jQuery,wp.customize);
\ No newline at end of file
diff --git a/code/wp-includes/js/heartbeat.js b/code/wp-includes/js/heartbeat.js
index 9867ceb1..6c5e8d15 100644
--- a/code/wp-includes/js/heartbeat.js
+++ b/code/wp-includes/js/heartbeat.js
@@ -131,7 +131,7 @@
// Needed for some hosts that cannot handle frequent requests and the user may exceed the allocated server CPU time, etc.
// The minimal interval can be up to 600 sec. however setting it to longer than 120 sec. will limit or disable
// some of the functionality (like post locks).
- // Once set at initialization, minimalInterval cannot be changed/overriden.
+ // Once set at initialization, minimalInterval cannot be changed/overridden.
if ( options.minimalInterval ) {
options.minimalInterval = parseInt( options.minimalInterval, 10 );
settings.minimalInterval = options.minimalInterval > 0 && options.minimalInterval <= 600 ? options.minimalInterval * 1000 : 0;
diff --git a/code/wp-includes/js/mce-view.js b/code/wp-includes/js/mce-view.js
index 3d2616d7..8c8de56a 100644
--- a/code/wp-includes/js/mce-view.js
+++ b/code/wp-includes/js/mce-view.js
@@ -157,6 +157,14 @@
text = tinymce.DOM.decode( text );
+ if ( text.indexOf( '[' ) !== -1 && text.indexOf( ']' ) !== -1 ) {
+ // Looks like a shortcode? Remove any line breaks from inside of shortcodes
+ // or autop will replace them with
and later and the string won't match.
+ text = text.replace( /\[[^\]]+\]/g, function( match ) {
+ return match.replace( /[\r\n]/g, '' );
+ });
+ }
+
if ( ! force ) {
instance = this.getInstance( text );
@@ -208,7 +216,7 @@
*/
render: function( force ) {
_.each( instances, function( instance ) {
- instance.render( force );
+ instance.render( null, force );
} );
},
@@ -294,7 +302,7 @@
initialize: function() {},
/**
- * Retuns the content to render in the view node.
+ * Returns the content to render in the view node.
*
* @return {*}
*/
@@ -490,7 +498,8 @@
var dom = editor.dom,
styles = '',
bodyClasses = editor.getBody().className || '',
- editorHead = editor.getDoc().getElementsByTagName( 'head' )[0];
+ editorHead = editor.getDoc().getElementsByTagName( 'head' )[0],
+ iframe, iframeWin, iframeDoc, MutationObserver, observer, i, block;
tinymce.each( dom.$( 'link[rel="stylesheet"]', editorHead ), function( link ) {
if ( link.href && link.href.indexOf( 'skins/lightgray/content.min.css' ) === -1 &&
@@ -511,135 +520,137 @@
}, '\u200B' );
}
- // Seems the browsers need a bit of time to insert/set the view nodes,
- // or the iframe will fail especially when switching Text => Visual.
- setTimeout( function() {
- var iframe, iframeWin, iframeDoc, MutationObserver, observer, i, block;
+ editor.undoManager.transact( function() {
+ node.innerHTML = '';
- editor.undoManager.transact( function() {
- node.innerHTML = '';
+ iframe = dom.add( node, 'iframe', {
+ /* jshint scripturl: true */
+ src: tinymce.Env.ie ? 'javascript:""' : '',
+ frameBorder: '0',
+ allowTransparency: 'true',
+ scrolling: 'no',
+ 'class': 'wpview-sandbox',
+ style: {
+ width: '100%',
+ display: 'block'
+ },
+ height: self.iframeHeight
+ } );
- iframe = dom.add( node, 'iframe', {
- /* jshint scripturl: true */
- src: tinymce.Env.ie ? 'javascript:""' : '',
- frameBorder: '0',
- allowTransparency: 'true',
- scrolling: 'no',
- 'class': 'wpview-sandbox',
- style: {
- width: '100%',
- display: 'block'
- },
- height: self.iframeHeight
- } );
+ dom.add( node, 'span', { 'class': 'mce-shim' } );
+ dom.add( node, 'span', { 'class': 'wpview-end' } );
+ } );
- dom.add( node, 'span', { 'class': 'mce-shim' } );
- dom.add( node, 'span', { 'class': 'wpview-end' } );
- } );
+ // Bail if the iframe node is not attached to the DOM.
+ // Happens when the view is dragged in the editor.
+ // There is a browser restriction when iframes are moved in the DOM. They get emptied.
+ // The iframe will be rerendered after dropping the view node at the new location.
+ if ( ! iframe.contentWindow ) {
+ return;
+ }
+
+ iframeWin = iframe.contentWindow;
+ iframeDoc = iframeWin.document;
+ iframeDoc.open();
+
+ iframeDoc.write(
+ '' +
+ '' +
+ '
' +
+ '' +
+ head +
+ styles +
+ '' +
+ '' +
+ '' +
+ body +
+ '' +
+ ''
+ );
+
+ iframeDoc.close();
- // Bail if the iframe node is not attached to the DOM.
- // Happens when the view is dragged in the editor.
- // There is a browser restriction when iframes are moved in the DOM. They get emptied.
- // The iframe will be rerendered after dropping the view node at the new location.
- if ( ! iframe.contentWindow ) {
+ function resize() {
+ var $iframe;
+
+ if ( block ) {
return;
}
- iframeWin = iframe.contentWindow;
- iframeDoc = iframeWin.document;
- iframeDoc.open();
-
- iframeDoc.write(
- '' +
- '' +
- '' +
- '' +
- head +
- styles +
- '' +
- '' +
- '' +
- body +
- '' +
- ''
- );
-
- iframeDoc.close();
-
- function resize() {
- var $iframe;
-
- if ( block ) {
- return;
- }
-
- // Make sure the iframe still exists.
- if ( iframe.contentWindow ) {
- $iframe = $( iframe );
- self.iframeHeight = $( iframeDoc.body ).height();
+ // Make sure the iframe still exists.
+ if ( iframe.contentWindow ) {
+ $iframe = $( iframe );
+ self.iframeHeight = $( iframeDoc.body ).height();
- if ( $iframe.height() !== self.iframeHeight ) {
- $iframe.height( self.iframeHeight );
- editor.nodeChanged();
- }
+ if ( $iframe.height() !== self.iframeHeight ) {
+ $iframe.height( self.iframeHeight );
+ editor.nodeChanged();
}
}
+ }
- if ( self.iframeHeight ) {
- block = true;
+ if ( self.iframeHeight ) {
+ block = true;
- setTimeout( function() {
- block = false;
- resize();
- }, 3000 );
- }
+ setTimeout( function() {
+ block = false;
+ resize();
+ }, 3000 );
+ }
+
+ function reload() {
+ $( node ).data( 'rendered', null );
- $( iframeWin ).on( 'load', resize );
+ setTimeout( function() {
+ wp.mce.views.render();
+ } );
+ }
- MutationObserver = iframeWin.MutationObserver || iframeWin.WebKitMutationObserver || iframeWin.MozMutationObserver;
+ $( iframeWin ).on( 'load', resize ).on( 'unload', reload );
- if ( MutationObserver ) {
- observer = new MutationObserver( _.debounce( resize, 100 ) );
+ MutationObserver = iframeWin.MutationObserver || iframeWin.WebKitMutationObserver || iframeWin.MozMutationObserver;
- observer.observe( iframeDoc.body, {
- attributes: true,
- childList: true,
- subtree: true
- } );
- } else {
- for ( i = 1; i < 6; i++ ) {
- setTimeout( resize, i * 700 );
- }
+ if ( MutationObserver ) {
+ observer = new MutationObserver( _.debounce( resize, 100 ) );
+
+ observer.observe( iframeDoc.body, {
+ attributes: true,
+ childList: true,
+ subtree: true
+ } );
+ } else {
+ for ( i = 1; i < 6; i++ ) {
+ setTimeout( resize, i * 700 );
}
+ }
- callback && callback.call( self, editor, node );
- }, 50 );
+ callback && callback.call( self, editor, node );
}, rendered );
},
/**
* Sets a loader for all view nodes tied to this view instance.
*/
- setLoader: function() {
+ setLoader: function( dashicon ) {
this.setContent(
'
)(https?:\/\/[^\s"]+?)(<\/p>\s*|$)/gi,c=b.exec(a);if(c)return{index:c.index+c[1].length,content:c[2],options:{url:!0}}}}))}(window,window.wp.mce.views,window.wp.media,window.jQuery);
\ No newline at end of file
+!function(a,b,c,d){"use strict";var e={},f={};b.mce=b.mce||{},b.mce.views={register:function(a,c){e[a]=b.mce.View.extend(_.extend(c,{type:a}))},unregister:function(a){delete e[a]},get:function(a){return e[a]},unbind:function(){_.each(f,function(a){a.unbind()})},setMarkers:function(a){var b,c,d=[{content:a}],f=this;return _.each(e,function(a,e){c=d.slice(),d=[],_.each(c,function(c){var g,h,i=c.content;if(c.processed)return void d.push(c);for(;i&&(g=a.prototype.match(i));)g.index&&d.push({content:i.substring(0,g.index)}),b=f.createInstance(e,g.content,g.options),h=b.loader?".":b.text,d.push({content:b.ignore?h:'
/g," "]])}function h(a){if(c.isWordContent(a))return a;var b=e.settings.paste_webkit_styles;if(e.settings.paste_remove_styles_if_webkit===!1||"all"==b)return a;if(b&&(b=b.split(/[, ]/)),b){var d=e.dom,f=e.selection.getNode();a=a.replace(/(<[^>]+) style="([^"]*)"([^>]*>)/gi,function(a,c,e,g){var h=d.parseStyle(e,"span"),i={};if("none"===b)return c+g;for(var j=0;j]+) style="([^"]*)"([^>]*>)/gi,"$1$3");return a=a.replace(/(<[^>]+) data-mce-style="([^"]+)"([^>]*>)/gi,function(a,b,c,d){return b+' style="'+c+'"'+d})}a.webkit&&f(h),a.ie&&f(g)}}),d("tinymce/pasteplugin/Plugin",["tinymce/PluginManager","tinymce/pasteplugin/Clipboard","tinymce/pasteplugin/WordFilter","tinymce/pasteplugin/Quirks"],function(a,b,c,d){var e;a.add("paste",function(f){function g(){return e||f.settings.paste_plaintext_inform===!1}function h(){if("text"==i.pasteFormat)this.active(!1),i.pasteFormat="html",f.fire("PastePlainTextToggle",{state:!1});else if(i.pasteFormat="text",this.active(!0),!g()){var a=f.translate("Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.");f.notificationManager.open({text:a,type:"info"}),e=!0,f.fire("PastePlainTextToggle",{state:!0})}f.focus()}var i,j=this,k=f.settings;return/(^|[ ,])powerpaste([, ]|$)/.test(k.plugins)&&a.get("powerpaste")?void("undefined"!=typeof console&&console.log&&console.log("PowerPaste is incompatible with Paste plugin! Remove 'paste' from the 'plugins' option.")):(j.clipboard=i=new b(f),j.quirks=new d(f),j.wordFilter=new c(f),f.settings.paste_as_text&&(j.clipboard.pasteFormat="text"),k.paste_preprocess&&f.on("PastePreProcess",function(a){k.paste_preprocess.call(j,j,a)}),k.paste_postprocess&&f.on("PastePostProcess",function(a){k.paste_postprocess.call(j,j,a)}),f.addCommand("mceInsertClipboardContent",function(a,b){b.content&&j.clipboard.pasteHtml(b.content),b.text&&j.clipboard.pasteText(b.text)}),f.settings.paste_block_drop&&f.on("dragend dragover draggesture dragdrop drop drag",function(a){a.preventDefault(),a.stopPropagation()}),f.settings.paste_data_images||f.on("drop",function(a){var b=a.dataTransfer;b&&b.files&&b.files.length>0&&a.preventDefault()}),f.addButton("pastetext",{icon:"pastetext",tooltip:"Paste as text",onclick:h,active:"text"==j.clipboard.pasteFormat}),void f.addMenuItem("pastetext",{text:"Paste as text",selectable:!0,active:i.pasteFormat,onclick:h}))})}),f(["tinymce/pasteplugin/Utils"])}(this);
\ No newline at end of file
diff --git a/code/wp-includes/js/tinymce/plugins/wordpress/plugin.js b/code/wp-includes/js/tinymce/plugins/wordpress/plugin.js
index b930e921..a38a26d3 100644
--- a/code/wp-includes/js/tinymce/plugins/wordpress/plugin.js
+++ b/code/wp-includes/js/tinymce/plugins/wordpress/plugin.js
@@ -131,10 +131,9 @@ tinymce.PluginManager.add( 'wordpress', function( editor ) {
}
// Remove spaces from empty paragraphs.
- // Avoid backtracking, can freeze the editor. See #35890.
- // (This is also quite faster than using only one regex.)
+ // Try to avoid a lot of backtracking, can freeze the editor. See #35890 and #38294.
event.content = event.content.replace( /
([^<>]+)<\/p>/gi, function( tag, text ) {
- if ( /^( |\s|\u00a0|\ufeff)+$/i.test( text ) ) {
+ if ( text === ' ' || ! /\S/.test( text ) ) {
return '
\n";
- }
- }
- return $r;
- }
-
- /**
- * Process changed lines to do word-by-word diffs for extra highlighting.
- *
- * (TRAC style) sometimes these lines can actually be deleted or added rows.
- * We do additional processing to figure that out
- *
- * @access public
- * @since 2.6.0
- *
- * @param array $orig
- * @param array $final
- * @return string
- */
- public function _changed( $orig, $final ) {
- $r = '';
-
- // Does the aforementioned additional processing
- // *_matches tell what rows are "the same" in orig and final. Those pairs will be diffed to get word changes
- // match is numeric: an index in other column
- // match is 'X': no match. It is a new row
- // *_rows are column vectors for the orig column and the final column.
- // row >= 0: an indix of the $orig or $final array
- // row < 0: a blank row for that column
- list($orig_matches, $final_matches, $orig_rows, $final_rows) = $this->interleave_changed_lines( $orig, $final );
-
- // These will hold the word changes as determined by an inline diff
- $orig_diffs = array();
- $final_diffs = array();
-
- // Compute word diffs for each matched pair using the inline diff
- foreach ( $orig_matches as $o => $f ) {
- if ( is_numeric($o) && is_numeric($f) ) {
- $text_diff = new Text_Diff( 'auto', array( array($orig[$o]), array($final[$f]) ) );
- $renderer = new $this->inline_diff_renderer;
- $diff = $renderer->render( $text_diff );
-
- // If they're too different, don't include any or
- if ( preg_match_all( '!(.*?|.*?)!', $diff, $diff_matches ) ) {
- // length of all text between or
- $stripped_matches = strlen(strip_tags( join(' ', $diff_matches[0]) ));
- // since we count lengith of text between or (instead of picking just one),
- // we double the length of chars not in those tags.
- $stripped_diff = strlen(strip_tags( $diff )) * 2 - $stripped_matches;
- $diff_ratio = $stripped_matches / $stripped_diff;
- if ( $diff_ratio > $this->_diff_threshold )
- continue; // Too different. Don't save diffs.
- }
-
- // Un-inline the diffs by removing del or ins
- $orig_diffs[$o] = preg_replace( '|.*?|', '', $diff );
- $final_diffs[$f] = preg_replace( '|.*?|', '', $diff );
- }
- }
-
- foreach ( array_keys($orig_rows) as $row ) {
- // Both columns have blanks. Ignore them.
- if ( $orig_rows[$row] < 0 && $final_rows[$row] < 0 )
- continue;
-
- // If we have a word based diff, use it. Otherwise, use the normal line.
- if ( isset( $orig_diffs[$orig_rows[$row]] ) )
- $orig_line = $orig_diffs[$orig_rows[$row]];
- elseif ( isset( $orig[$orig_rows[$row]] ) )
- $orig_line = htmlspecialchars($orig[$orig_rows[$row]]);
- else
- $orig_line = '';
-
- if ( isset( $final_diffs[$final_rows[$row]] ) )
- $final_line = $final_diffs[$final_rows[$row]];
- elseif ( isset( $final[$final_rows[$row]] ) )
- $final_line = htmlspecialchars($final[$final_rows[$row]]);
- else
- $final_line = '';
-
- if ( $orig_rows[$row] < 0 ) { // Orig is blank. This is really an added row.
- $r .= $this->_added( array($final_line), false );
- } elseif ( $final_rows[$row] < 0 ) { // Final is blank. This is really a deleted row.
- $r .= $this->_deleted( array($orig_line), false );
- } else { // A true changed row.
- if ( $this->_show_split_view ) {
- $r .= '
- -
- - 1 && get_option( 'page_comments' ) ) : ?> - - - -- 'ol', - 'short_ping' => true, - 'avatar_size' => 34, - ) ); - ?> -
- - 1 && get_option( 'page_comments' ) ) : ?> - - - - - - - - - - - -