first
339
wp-content/plugins/debloat/LICENSE
Normal file
@@ -0,0 +1,339 @@
|
||||
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.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
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.
|
||||
|
||||
<signature of Ty Coon>, 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.
|
52
wp-content/plugins/debloat/bootstrap.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
/**
|
||||
* Plugin bootstrap
|
||||
*/
|
||||
defined('WPINC') || exit;
|
||||
|
||||
if (version_compare(phpversion(), '7.1', '<')) {
|
||||
/**
|
||||
* Display an admin error notice when PHP is older the version 7.1
|
||||
* Hook it to the 'admin_notices' action.
|
||||
*/
|
||||
function debloat_old_php_admin_error_notice() {
|
||||
|
||||
$message = sprintf(esc_html__(
|
||||
'The %2$sDebloat%3$s plugin requires %2$sPHP 7.1+%3$s to run properly. Please contact your web hosting company and ask them to update the PHP version of your site.%4$s Your current version of PHP has reached end-of-life is %2$shighly insecure: %1$s%3$s', 'debloat'),
|
||||
phpversion(),
|
||||
'<strong>',
|
||||
'</strong>',
|
||||
'<br>'
|
||||
);
|
||||
|
||||
printf('<div class="notice notice-error"><p>%1$s</p></div>', wp_kses_post($message));
|
||||
}
|
||||
|
||||
add_action('admin_notices', 'debloat_old_php_admin_error_notice');
|
||||
|
||||
// bail
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Launch the plugin
|
||||
*/
|
||||
require_once plugin_dir_path(__FILE__) . 'inc/plugin.php';
|
||||
|
||||
$plugin = \Sphere\Debloat\Plugin::get_instance();
|
||||
$plugin->plugin_file = __FILE__;
|
||||
|
||||
// Init on plugins loaded
|
||||
add_action('plugins_loaded', array($plugin, 'init'));
|
||||
|
||||
/**
|
||||
* Register activation and deactivation hooks
|
||||
*/
|
||||
|
||||
register_activation_hook(DEBLOAT_PLUGIN_FILE, function() {
|
||||
// Noop
|
||||
});
|
||||
|
||||
register_deactivation_hook(DEBLOAT_PLUGIN_FILE, function() {
|
||||
// Noop
|
||||
});
|
101
wp-content/plugins/debloat/css/admin/cmb2.css
Normal file
@@ -0,0 +1,101 @@
|
||||
.sphere-cmb2-wrap {
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
.sphere-cmb2-wrap .cmb-type-checkbox .cmb-td {
|
||||
max-width: 750px;
|
||||
padding-top: 5px !important;
|
||||
}
|
||||
|
||||
.sphere-cmb2-wrap .cmb2-metabox-description {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.sphere-cmb2-wrap label > .cmb2-metabox-description {
|
||||
font-size: 13px;
|
||||
font-style: normal;
|
||||
line-height: 1.4;
|
||||
color: #444;
|
||||
max-width: 500px;
|
||||
}
|
||||
|
||||
.sphere-cmb2-wrap .cmb2-metabox > .cmb-row:not(._) {
|
||||
padding: 15px 1em;
|
||||
}
|
||||
|
||||
.cmb2-options-page .sphere-cmb2-wrap .cmb-type-title .cmb2-metabox-title {
|
||||
font-size: 14px;
|
||||
text-transform: initial;
|
||||
font-weight: 700;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.cmb2-options-page .cmb2-metabox > .cmb-row > .cmb-th {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.sphere-cmb2-wrap .cache-info {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifics for Debloat Plugin options page.
|
||||
*/
|
||||
.debloat-options {
|
||||
max-width: 100%;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.debloat-options .nav-tab-wrapper {
|
||||
margin-bottom: 1em !important;
|
||||
}
|
||||
|
||||
.debloat-options .cmb-field-list > :first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.debloat-inner-wrap {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.debloat-inner-wrap form,
|
||||
.debloat-options .wrap {
|
||||
width: 72%;
|
||||
max-width: 1200px;
|
||||
}
|
||||
|
||||
.debloat-sidebar {
|
||||
width: 28%;
|
||||
padding-left: 35px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
@media (max-width: 940px) {
|
||||
.debloat-options .wrap,
|
||||
.debloat-inner-wrap form {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.debloat-sidebar {
|
||||
min-width: 350px;
|
||||
}
|
||||
}
|
||||
|
||||
.debloat-cache-info .cmb-type-title {
|
||||
margin-top: 0 !important;
|
||||
}
|
||||
|
||||
.debloat-intro-info {
|
||||
margin-bottom: 22px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.debloat-intro-info h3 {
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.debloat-intro-info li {
|
||||
font-size: 13px;
|
||||
line-height: 1.5;
|
||||
}
|
22
wp-content/plugins/debloat/debloat.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/**
|
||||
* Debloat Plugin.
|
||||
*
|
||||
* @package Sphere\Debloat
|
||||
*
|
||||
* Plugin Name: Debloat
|
||||
* Description: Remove Unused CSS, Optimize CSS, Optimize JS and speed up your site.
|
||||
* Version: 1.2.3
|
||||
* Author: asadkn
|
||||
* Author URI: https://profiles.wordpress.org/asadkn/
|
||||
* License: GPL-2.0+
|
||||
* License URI: http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
* Text Domain: debloat
|
||||
* Domain Path: /languages
|
||||
* Requires PHP: 7.1
|
||||
*/
|
||||
|
||||
defined('WPINC') || exit;
|
||||
|
||||
define('DEBLOAT_PLUGIN_FILE', __FILE__);
|
||||
require_once plugin_dir_path(__FILE__) . 'bootstrap.php';
|
353
wp-content/plugins/debloat/inc/admin/admin.php
Normal file
@@ -0,0 +1,353 @@
|
||||
<?php
|
||||
|
||||
namespace Sphere\Debloat;
|
||||
|
||||
use Sphere\Debloat\Admin\Cache;
|
||||
use Sphere\Debloat\Admin\OptionsData;
|
||||
|
||||
/**
|
||||
* Admin initialization.
|
||||
*
|
||||
* @author asadkn
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Admin
|
||||
{
|
||||
/**
|
||||
* @var Sphere\Debloat\Admin\Cache
|
||||
*/
|
||||
protected $cache;
|
||||
|
||||
/**
|
||||
* Setup hooks
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
$this->cache = new Cache;
|
||||
$this->cache->init();
|
||||
|
||||
add_action('cmb2_admin_init', [$this, 'setup_options']);
|
||||
|
||||
// Enqueue at a lower priority to be after CMB2.
|
||||
add_action('admin_enqueue_scripts', [$this, 'register_assets'], 99);
|
||||
|
||||
// Page to delete cache.
|
||||
add_action('admin_menu', function() {
|
||||
add_submenu_page(
|
||||
'',
|
||||
'Delete Cache',
|
||||
'Delete Cache',
|
||||
'manage_options',
|
||||
'debloat-delete-cache',
|
||||
[$this, 'delete_cache']
|
||||
);
|
||||
});
|
||||
|
||||
// Empty cache on save.
|
||||
add_action('cmb2_save_options-page_fields', [$this, '_delete_cache']);
|
||||
|
||||
/**
|
||||
* Fix: CMB2 doesn't save unchecked making default => true impossible.
|
||||
*/
|
||||
add_filter('cmb2_sanitize_checkbox', function($override, $value) {
|
||||
return is_null($value) ? '0' : $value;
|
||||
}, 20, 2);
|
||||
|
||||
// Custom CMB2 field for manual callback
|
||||
add_action('cmb2_render_manual', function($field) {
|
||||
|
||||
// Add attributes to an empty span for cmb2-conditional
|
||||
if (!empty($field->args['attributes'])) {
|
||||
printf('<meta name="%s" %s />',
|
||||
$field->args('id'),
|
||||
\CMB2_Utils::concat_attrs($field->args('attributes'))
|
||||
);
|
||||
}
|
||||
|
||||
if (!empty($field->args['render_html']) && is_callable($field->args['render_html'])) {
|
||||
call_user_func($field->args['render_html'], $field);
|
||||
}
|
||||
|
||||
if (!empty($field->args['desc'])) {
|
||||
echo '<p class="cmb2-metabox-description">' . esc_html($field->args['desc']) . '</p>';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Register admin assets
|
||||
*/
|
||||
public function register_assets()
|
||||
{
|
||||
// Specific assets for option pages only
|
||||
if (!empty($_GET['page']) && strpos($_GET['page'], 'debloat_options') !== false) {
|
||||
|
||||
wp_enqueue_script(
|
||||
'debloat-cmb2-conditionals',
|
||||
Plugin::get_instance()->dir_url . 'js/admin/cmb2-conditionals.js',
|
||||
['jquery'],
|
||||
Plugin::VERSION
|
||||
);
|
||||
|
||||
wp_enqueue_script(
|
||||
'debloat-options',
|
||||
Plugin::get_instance()->dir_url . 'js/admin/options.js',
|
||||
['jquery', 'debloat-cmb2-conditionals'],
|
||||
Plugin::VERSION
|
||||
);
|
||||
|
||||
wp_enqueue_style(
|
||||
'debloat-admin-cmb2',
|
||||
Plugin::get_instance()->dir_url . 'css/admin/cmb2.css',
|
||||
['cmb2-styles'],
|
||||
Plugin::VERSION
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete Cache page.
|
||||
*/
|
||||
public function delete_cache()
|
||||
{
|
||||
check_admin_referer('debloat_delete_cache');
|
||||
$this->_delete_cache();
|
||||
|
||||
echo '
|
||||
<h2>Clearing Cache</h2>
|
||||
<p>Caches cleared. You may also have to clear your cache plugins.</p>
|
||||
<a href="' . esc_url(admin_url('admin.php?page=debloat_options')) . '">Back to Options</a>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback: Delete the cache.
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
public function _delete_cache()
|
||||
{
|
||||
$this->cache->empty();
|
||||
|
||||
/**
|
||||
* Hook after deleting cache.
|
||||
*/
|
||||
do_action('debloat/after_delete_cache');
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup admin options with CMB2
|
||||
*/
|
||||
public function setup_options()
|
||||
{
|
||||
// Configure admin options
|
||||
$options = new_cmb2_box([
|
||||
'id' => 'debloat_options',
|
||||
'title' => esc_html__('Debloat Plugin Settings', 'debloat'),
|
||||
'object_types' => ['options-page'],
|
||||
'option_key' => 'debloat_options',
|
||||
'parent_slug' => 'options-general.php',
|
||||
'menu_title' => esc_html__('Debloat: Optimize', 'debloat'),
|
||||
'tab_group' => 'debloat_options',
|
||||
'tab_title' => esc_html__('Optimize CSS', 'debloat'),
|
||||
'classes' => 'sphere-cmb2-wrap',
|
||||
'display_cb' => [$this, 'render_options_page'],
|
||||
]);
|
||||
|
||||
$this->add_options(
|
||||
OptionsData::get_css(),
|
||||
$options
|
||||
);
|
||||
|
||||
// Configure admin options
|
||||
$js_options = new_cmb2_box([
|
||||
'id' => 'debloat_options_js',
|
||||
'title' => esc_html__('Optimize JS', 'debloat'),
|
||||
'object_types' => ['options-page'],
|
||||
'option_key' => 'debloat_options_js',
|
||||
'parent_slug' => 'debloat_options',
|
||||
'menu_title' => esc_html__('Optimize JS', 'debloat'),
|
||||
'tab_group' => 'debloat_options',
|
||||
'tab_title' => esc_html__('Optimize JS', 'debloat'),
|
||||
'classes' => 'sphere-cmb2-wrap',
|
||||
'display_cb' => [$this, 'render_options_page'],
|
||||
]);
|
||||
|
||||
$this->add_options(
|
||||
OptionsData::get_js(),
|
||||
$js_options
|
||||
);
|
||||
|
||||
// Configure admin options
|
||||
$general_options = new_cmb2_box([
|
||||
'id' => 'debloat_options_general',
|
||||
'title' => esc_html__('General Settings', 'debloat'),
|
||||
'object_types' => ['options-page'],
|
||||
'option_key' => 'debloat_options_general',
|
||||
'parent_slug' => 'debloat_options',
|
||||
'menu_title' => esc_html__('General Settings', 'debloat'),
|
||||
'tab_group' => 'debloat_options',
|
||||
'tab_title' => esc_html__('General Settings', 'debloat'),
|
||||
'display_cb' => [$this, 'render_options_page'],
|
||||
'classes' => 'sphere-cmb2-wrap'
|
||||
]);
|
||||
|
||||
$this->add_options(
|
||||
OptionsData::get_general(),
|
||||
$general_options
|
||||
);
|
||||
|
||||
do_action('debloat/admin/after_options', $options);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Add options to CMB2 array.
|
||||
*
|
||||
* @param array $options
|
||||
* @param \CMB2 $object
|
||||
* @return void
|
||||
*/
|
||||
protected function add_options($options, $object)
|
||||
{
|
||||
return array_map(
|
||||
function($option) use ($object) {
|
||||
if (isset($option['attributes']['data-conditional-id'])) {
|
||||
$condition = &$option['attributes']['data-conditional-id'];
|
||||
if (is_array($condition)) {
|
||||
$condition = json_encode($condition);
|
||||
}
|
||||
}
|
||||
|
||||
$field_id = $object->add_field($option);
|
||||
|
||||
if ($option['type'] === 'group') {
|
||||
$this->add_option_group($option, $field_id, $object);
|
||||
}
|
||||
|
||||
},
|
||||
$options
|
||||
);
|
||||
}
|
||||
|
||||
protected function add_option_group($option, $group_id, $object)
|
||||
{
|
||||
if ($option['id'] === 'allow_conditionals_data') {
|
||||
$object->add_group_field($group_id, [
|
||||
'id' => 'type',
|
||||
'name' => esc_html__('Condition Type', 'debloat'),
|
||||
'type' => 'radio',
|
||||
'default' => 'class',
|
||||
'options' => [
|
||||
'class' => esc_html__('Class - If a class (in "condition match") exists in HTML, keep classes matching "selector match".', 'debloat'),
|
||||
'prefix' => esc_html__('Prefix - Condition matches the first class and keeps all the used child classes. Example: .s-dark will keep .s-dark .site-header.', 'debloat'),
|
||||
],
|
||||
]);
|
||||
|
||||
$object->add_group_field($group_id, [
|
||||
'id' => 'match',
|
||||
'name' => esc_html__('Condition Match', 'debloat'),
|
||||
'desc' => esc_html__('Required. Usually a single class, example:', 'debloat') . '<code>.my-class</code>',
|
||||
'type' => 'text',
|
||||
'default' => '',
|
||||
]);
|
||||
|
||||
$object->add_group_field($group_id, [
|
||||
'id' => 'search',
|
||||
'name' => esc_html__('Selectors Match', 'debloat'),
|
||||
'desc' => esc_html__('Enter one per line. See example matchings in "Always Keep Selectors" above.', 'debloat'),
|
||||
'type' => 'textarea_small',
|
||||
'default' => '',
|
||||
'attributes' => [
|
||||
'data-conditional-id' => json_encode([$group_id, 'type']),
|
||||
'data-conditional-value' => 'class'
|
||||
]
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function render_options_page($hookup)
|
||||
{
|
||||
?>
|
||||
<div class="cmb2-options-page debloat-options option-<?php echo esc_attr( sanitize_html_class( $hookup->option_key ) ); ?>">
|
||||
<div class="wrap">
|
||||
<?php if ( $hookup->cmb->prop( 'title' ) ) : ?>
|
||||
<h2><?php echo wp_kses_post( $hookup->cmb->prop( 'title' ) ); ?></h2>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="wrap"><?php $hookup->options_page_tab_nav_output(); ?></div>
|
||||
|
||||
<div class="debloat-inner-wrap">
|
||||
<form class="cmb-form debloat-options-form" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" method="POST" id="<?php echo esc_attr($hookup->cmb->cmb_id); ?>" enctype="multipart/form-data" encoding="multipart/form-data">
|
||||
<input type="hidden" name="action" value="<?php echo esc_attr( $hookup->option_key ); ?>">
|
||||
|
||||
<div class="sphere-cmb2-wrap debloat-intro-info">
|
||||
<div class="cmb2-wrap cmb2-metabox">
|
||||
<div class="cmb-row">
|
||||
<h3>Important: Debloat Plugin</h3>
|
||||
<p>
|
||||
This plugin is for advanced users. The features "Remove Unused CSS" and "Delay JS" are especially for advanced users only.
|
||||
</p>
|
||||
<ol>
|
||||
<li>Use a cache plugin like W3 Total Cache, WP Super Cache, etc. <strong>Required</strong> for Remove Unused CSS feature.</li>
|
||||
<li>Do <strong>NOT</strong> enable minification, CSS, or JS optimization via another plugin.</li>
|
||||
<li>If your theme doesn't have it built-in, use a Lazyload plugin for images.</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php $hookup->options_page_metabox(); ?>
|
||||
<?php submit_button( esc_attr( $hookup->cmb->prop( 'save_button' ) ), 'primary', 'submit-cmb' ); ?>
|
||||
</form>
|
||||
<div class="debloat-sidebar">
|
||||
<?php $this->cache_info(); ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
public function cache_info()
|
||||
{
|
||||
$js_cache = Plugin::file_cache()->get_stats('js');
|
||||
$css_cache = Plugin::file_cache()->get_stats('css');
|
||||
|
||||
// Number of css sheets in cache.
|
||||
$css_sheets = count($this->cache->get_transients());
|
||||
?>
|
||||
|
||||
<div class="sphere-cmb2-wrap debloat-cache-info">
|
||||
<div class="cmb2-wrap cmb2-metabox">
|
||||
<div class="cmb-row cmb-type-title">
|
||||
<div class="cmb-td">
|
||||
<h3 class="cmb2-metabox-title">
|
||||
<?php esc_html_e('Cache Stats', 'debloat'); ?>
|
||||
</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="cmb-row">
|
||||
<?php if (defined('SCRIPT_DEBUG') && SCRIPT_DEBUG): ?>
|
||||
<p><strong>Minification Disabled</strong>: SCRIPT_DEBUG is enabled (likely in wp-config.php).</p>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="cache-stats">
|
||||
<p><?php printf(esc_html__('Minified CSS files: %d', 'debloat'), $css_cache); ?></p>
|
||||
<p><?php printf(esc_html__('Minified JS files: %d', 'debloat'), $js_cache); ?></p>
|
||||
<p><?php printf(esc_html__('Processed CSS Sheets: %d', 'debloat'), $css_sheets); ?></p>
|
||||
</div>
|
||||
|
||||
<a href="<?php echo wp_nonce_url(admin_url('admin.php?page=debloat-delete-cache'), 'debloat_delete_cache'); ?>"
|
||||
class="button button-secondary" style="margin-top: 10px;">
|
||||
<?php echo esc_html('Empty All Cache', 'debloat'); ?>
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
}
|
||||
}
|
183
wp-content/plugins/debloat/inc/admin/cache.php
Normal file
@@ -0,0 +1,183 @@
|
||||
<?php
|
||||
|
||||
namespace Sphere\Debloat\Admin;
|
||||
use Sphere\Debloat\Plugin;
|
||||
|
||||
/**
|
||||
* Cache clear, stats and similar for admin area.
|
||||
*
|
||||
* @author asadkn
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Cache
|
||||
{
|
||||
protected $deleting = false;
|
||||
|
||||
public function init()
|
||||
{
|
||||
$this->register_clear_hooks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register hooks to clear cache.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register_clear_hooks()
|
||||
{
|
||||
/**
|
||||
* Use this hook to clear caches externally.
|
||||
*/
|
||||
add_action('debloat/empty_caches', [$this, 'empty']);
|
||||
|
||||
/**
|
||||
* Other plugin hooks to empty cache on.
|
||||
*/
|
||||
$hooks = [
|
||||
// WP Rocket.
|
||||
'after_rocket_clean_domain',
|
||||
|
||||
// W3 Total Cache.
|
||||
'w3tc_flush_all',
|
||||
|
||||
// SGF plugin font cache delete.
|
||||
'sgf/after_delete_cache',
|
||||
];
|
||||
|
||||
foreach ($hooks as $hook) {
|
||||
add_action($hook, [$this, 'empty']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the debloat cache transients.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_transients()
|
||||
{
|
||||
global $wpdb;
|
||||
|
||||
return (array) $wpdb->get_results(
|
||||
"SELECT `option_name` FROM {$wpdb->options} WHERE `option_name` LIKE '_transient_debloat_sheet_cache_%'",
|
||||
ARRAY_A
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all the debloat cache transients.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function delete_transients()
|
||||
{
|
||||
foreach ($this->get_transients() as $transient) {
|
||||
$transient = str_replace('_transient_', '', $transient['option_name']);
|
||||
\delete_transient($transient);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all types of caches.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function empty()
|
||||
{
|
||||
// Already clearing the caches. Needed as we hook into plugins clear methods,
|
||||
// but also call them ourselves on cache clear.
|
||||
if ($this->deleting) {
|
||||
return;
|
||||
}
|
||||
|
||||
// One of the hooks set via register_clear_hooks() may fire.
|
||||
$this->deleting = true;
|
||||
|
||||
$this->delete_transients();
|
||||
|
||||
// Delete files cache.
|
||||
Plugin::file_cache()->delete_cache('js');
|
||||
Plugin::file_cache()->delete_cache('css');
|
||||
|
||||
// Clear cache plugins.
|
||||
$this->empty_cache_plugins();
|
||||
|
||||
$this->deleting = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty external caches from plugins and hosts.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function empty_cache_plugins()
|
||||
{
|
||||
// WP Super Cache.
|
||||
if (function_exists('wp_cache_clear_cache')) {
|
||||
wp_cache_clear_cache(
|
||||
is_multisite() ? get_current_blog_id() : 0
|
||||
);
|
||||
}
|
||||
|
||||
// W3 Total Cache.
|
||||
if (function_exists('w3tc_pgcache_flush')) {
|
||||
w3tc_pgcache_flush();
|
||||
}
|
||||
|
||||
// WP Rocket.
|
||||
if (function_exists('rocket_clean_domain')) {
|
||||
rocket_clean_domain();
|
||||
}
|
||||
|
||||
// WP Fastest Cache.
|
||||
if (function_exists('wpfc_clear_all_cache')) {
|
||||
wpfc_clear_all_cache();
|
||||
}
|
||||
|
||||
// Swift Performance plugin.
|
||||
if (class_exists('\Swift_Performance_Cache') && is_callable(['\Swift_Performance_Cache', 'clear_all_cache'])) {
|
||||
\Swift_Performance_Cache::clear_all_cache();
|
||||
}
|
||||
|
||||
// LiteSpeed Cache.
|
||||
if (class_exists('\LiteSpeed_Cache_API') && is_callable(['\LiteSpeed_Cache_API', 'purge_all'])) {
|
||||
\LiteSpeed_Cache_API::purge_all();
|
||||
}
|
||||
|
||||
// Cache Enabler.
|
||||
if (class_exists('\Cache_Enabler') && is_callable(['\Cache_Enabler', 'clear_total_cache'])) {
|
||||
\Cache_Enabler::clear_total_cache();
|
||||
}
|
||||
|
||||
// Comet cache.
|
||||
if (class_exists('\comet_cache') && is_callable(['\comet_cache', 'clear'])) {
|
||||
\comet_cache::clear();
|
||||
}
|
||||
|
||||
// RT Nginx Helper plugin.
|
||||
if (defined('NGINX_HELPER_BASENAME')) {
|
||||
do_action('rt_nginx_helper_purge_all');
|
||||
}
|
||||
|
||||
// Hummingbird
|
||||
if (class_exists('\Hummingbird\WP_Hummingbird') && is_callable(['\Hummingbird\WP_Hummingbird', 'flush_cache'])) {
|
||||
\Hummingbird\WP_Hummingbird::flush_cache();
|
||||
}
|
||||
|
||||
// Pagely.
|
||||
if (class_exists('\PagelyCachePurge') && is_callable(['\PagelyCachePurge', 'purgeAll'])) {
|
||||
\PagelyCachePurge::purgeAll();
|
||||
}
|
||||
|
||||
// WPEngine
|
||||
if (class_exists('\WpeCommon')) {
|
||||
is_callable(['\WpeCommon', 'purge_memcached']) && \WpeCommon::purge_memcached();
|
||||
is_callable(['\WpeCommon', 'purge_varnish_cache']) && \WpeCommon::purge_varnish_cache();
|
||||
}
|
||||
|
||||
// SiteGround.
|
||||
if (function_exists('sg_cachepress_purge_cache')) {
|
||||
sg_cachepress_purge_cache();
|
||||
}
|
||||
}
|
||||
}
|
446
wp-content/plugins/debloat/inc/admin/options-data.php
Normal file
@@ -0,0 +1,446 @@
|
||||
<?php
|
||||
|
||||
namespace Sphere\Debloat\Admin;
|
||||
|
||||
/**
|
||||
* Options data.
|
||||
*/
|
||||
class OptionsData
|
||||
{
|
||||
/**
|
||||
* Common shared data and options.
|
||||
*
|
||||
* @param string $key
|
||||
* @return array
|
||||
*/
|
||||
public static function get_common($key = '')
|
||||
{
|
||||
$_common = [];
|
||||
$_common['enable_on'] = [
|
||||
'all' => esc_html__('All Pages', 'debloat'),
|
||||
'single' => esc_html__('Single Post/Article', 'debloat'),
|
||||
'pages' => esc_html__('Pages', 'delobat'),
|
||||
'home' => esc_html__('Homepage', 'delobat'),
|
||||
'archives' => esc_html__('Archives', 'delobat'),
|
||||
'categories' => esc_html__('Categories', 'delobat'),
|
||||
'search' => esc_html__('Search', 'delobat'),
|
||||
];
|
||||
|
||||
return $key ? $_common[$key] : $_common;
|
||||
}
|
||||
|
||||
public static function get_css()
|
||||
{
|
||||
$options = [];
|
||||
$options[] = [
|
||||
'name' => esc_html__('Optimize CSS', 'debloat'),
|
||||
// 'description' => 'foo',
|
||||
'type' => 'title',
|
||||
'id' => '_optimize_css',
|
||||
];
|
||||
|
||||
$options[] = [
|
||||
'id' => 'optimize_css',
|
||||
'name' => esc_html__('Fix Render-Blocking CSS', 'debloat'),
|
||||
'desc' => esc_html__('Enable CSS Optimizations to fix Render-blocking CSS.', 'debloat'),
|
||||
'type' => 'checkbox',
|
||||
'default' => 0,
|
||||
];
|
||||
$options[] = [
|
||||
'id' => 'optimize_css_to_inline',
|
||||
'name' => esc_html__('Inline Optimized CSS', 'debloat'),
|
||||
'desc' => esc_html__('Inline the CSS to prevent flash of unstyled content. Highly recommended.', 'debloat'),
|
||||
'type' => 'checkbox',
|
||||
'default' => 1,
|
||||
'attributes' => ['data-conditional-id' => 'optimize_css'],
|
||||
];
|
||||
$options[] = [
|
||||
'id' => 'optimize_gfonts_inline',
|
||||
'name' => esc_html__('Inline Google Fonts CSS', 'debloat'),
|
||||
'desc' => esc_html__('Inline the Google Fonts CSS for a big boost on FCP and slight on LCP on mobile. Highly recommended.', 'debloat'),
|
||||
'type' => 'checkbox',
|
||||
'default' => 1,
|
||||
'attributes' => ['data-conditional-id' => 'optimize_css'],
|
||||
];
|
||||
$options[] = [
|
||||
'id' => 'optimize_css_minify',
|
||||
'name' => esc_html__('Minify CSS', 'debloat'),
|
||||
'desc' => esc_html__('Minify CSS to reduced the CSS size.', 'debloat'),
|
||||
'type' => 'checkbox',
|
||||
'default' => 1,
|
||||
'attributes' => ['data-conditional-id' => 'optimize_css'],
|
||||
];
|
||||
$options[] = [
|
||||
'id' => 'optimize_css_excludes',
|
||||
'name' => esc_html__('Exclude Styles', 'debloat'),
|
||||
'desc' =>
|
||||
esc_html__('Enter one per line to exclude certain CSS files from this optimizations. Examples:', 'debloat')
|
||||
. ' <code>id:my-css-id</code>
|
||||
<br /><code>wp-content/themes/my-theme/style.css</code>
|
||||
<br /><code>wp-content/themes/my-theme*</code>
|
||||
',
|
||||
'type' => 'textarea_small',
|
||||
'default' => '',
|
||||
'attributes' => ['data-conditional-id' => 'optimize_css'],
|
||||
];
|
||||
$options[] = [
|
||||
'id' => 'integrations_css',
|
||||
'name' => esc_html__('Enable Plugin Integrations', 'debloat'),
|
||||
'desc' => esc_html__('Special pre-made rules for CSS, specific to plugins, are applied if enabled.', 'debloat'),
|
||||
'type' => 'multicheck_inline',
|
||||
'options' => [
|
||||
'elementor' => 'Elementor',
|
||||
'wpbakery' => 'WPBakery Page Builder',
|
||||
],
|
||||
'default' => ['elementor', 'wpbakery'],
|
||||
'select_all_button' => false,
|
||||
];
|
||||
|
||||
$options[] = [
|
||||
'id' => 'optimize_gfonts',
|
||||
'name' => esc_html__('Optimize Google Fonts', 'debloat'),
|
||||
'desc' => esc_html__('Add preconnect hints and add display swap for Google Fonts.', 'debloat'),
|
||||
'type' => 'checkbox',
|
||||
'default' => 1,
|
||||
];
|
||||
|
||||
$options[] = [
|
||||
'name' => esc_html__('Optimize CSS: Remove Unused', 'debloat'),
|
||||
// 'description' => 'foo',
|
||||
'type' => 'title',
|
||||
'id' => '_remove_unused',
|
||||
];
|
||||
|
||||
$options[] = [
|
||||
'id' => 'remove_css',
|
||||
'name' => esc_html__('Remove Unused CSS', 'debloat'),
|
||||
'desc' => esc_html__('This is an expensive process. DO NOT use without a cache plugin.', 'debloat'),
|
||||
'type' => 'checkbox',
|
||||
'default' => 0,
|
||||
];
|
||||
|
||||
$options[] = [
|
||||
'id' => 'remove_css_all',
|
||||
'name' => esc_html__('Remove from All Stylesheets', 'debloat'),
|
||||
'desc' => esc_html__('WARNING: Only use if you are sure your plugins and themes dont add classes using JS. May also be enabled when delay loading all the original CSS.', 'debloat'),
|
||||
'type' => 'checkbox',
|
||||
'default' => 0,
|
||||
'attributes' => ['data-conditional-id' => 'remove_css'],
|
||||
];
|
||||
|
||||
$options[] = [
|
||||
'id' => 'remove_css_plugins',
|
||||
'name' => esc_html__('Enable for Plugins CSS', 'debloat'),
|
||||
'desc' => esc_html__('Removed unused CSS on all plugins CSS files.', 'debloat'),
|
||||
'type' => 'checkbox',
|
||||
'default' => 0,
|
||||
'attributes' => [
|
||||
'data-conditional-id' => [
|
||||
['key' => 'remove_css'],
|
||||
['key' => 'remove_css_all', 'value' => 'off'],
|
||||
]
|
||||
],
|
||||
];
|
||||
|
||||
$options[] = [
|
||||
'id' => 'remove_css_theme',
|
||||
'name' => esc_html__('Enable for Theme CSS', 'debloat'),
|
||||
'desc' => esc_html__('Removed unused CSS from all theme CSS files.', 'debloat'),
|
||||
'type' => 'checkbox',
|
||||
'default' => 0,
|
||||
'attributes' => [
|
||||
'data-conditional-id' => [
|
||||
['key' => 'remove_css'],
|
||||
['key' => 'remove_css_all', 'value' => 'off'],
|
||||
]
|
||||
],
|
||||
];
|
||||
|
||||
$options[] = [
|
||||
'id' => 'remove_css_includes',
|
||||
'name' => esc_html__('Target Stylesheets', 'debloat'),
|
||||
'desc' =>
|
||||
esc_html__('Will remove unused CSS from these targets. You may use an ID or the part of the URL. Examples:', 'debloat')
|
||||
. ' <code>id:my-css-id</code>
|
||||
<br /><code>wp-content/themes/my-theme/style.css</code>
|
||||
<br /><code>wp-content/themes/my-theme*</code>: All theme stylesheets.
|
||||
<br /><code>plugins/plugin-slug/*</code>: All stylesheets for plugin-slug.
|
||||
',
|
||||
'type' => 'textarea_small',
|
||||
'default' => 'id:wp-block-library',
|
||||
'attributes' => [
|
||||
'data-conditional-id' => [
|
||||
['key' => 'remove_css'],
|
||||
['key' => 'remove_css_all', 'value' => 'off'],
|
||||
]
|
||||
],
|
||||
];
|
||||
|
||||
$options[] = [
|
||||
'id' => 'remove_css_excludes',
|
||||
'name' => esc_html__('Exclude Stylesheets', 'debloat'),
|
||||
'desc' =>
|
||||
esc_html__('Enter one per line to exclude certain CSS files from this optimizations. Examples:', 'debloat')
|
||||
. ' <code>id:my-css-id</code>
|
||||
<br /><code>wp-content/themes/my-theme/style.css</code>
|
||||
<br /><code>wp-content/themes/my-theme*</code>
|
||||
',
|
||||
'type' => 'textarea_small',
|
||||
'default' => '',
|
||||
'attributes' => ['data-conditional-id' => 'remove_css'],
|
||||
];
|
||||
|
||||
$options[] = [
|
||||
'id' => 'allow_css_selectors',
|
||||
'name' => esc_html__('Always Keep Selectors', 'debloat'),
|
||||
'desc' =>
|
||||
esc_html__('Enter one per line. Partial or full matches for selectors (if any of these keywords found, the selector will be kept). Examples:', 'debloat')
|
||||
. ' <code>.myclass</code>
|
||||
<br /><code>.myclass*</code>: Will match selectors starting with .myclass, .myclass-xyz, .myclass_xyz etc.
|
||||
<br /><code>.myclass *</code>: Selectors starting with .myclass, .myclass .sub-class and so on.
|
||||
<br /><code>*.myclass *</code>: For matching .xyz .myclass, .myclass, .xyz .myclass .xyz and so on.
|
||||
',
|
||||
'type' => 'textarea_small',
|
||||
'default' => '',
|
||||
'attributes' => ['data-conditional-id' => 'remove_css'],
|
||||
];
|
||||
|
||||
$options[] = [
|
||||
'id' => 'allow_css_conditionals',
|
||||
'name' => esc_html__('Advanced: Conditionally Keep Selectors', 'debloat'),
|
||||
'desc' => 'Add advanced conditions.',
|
||||
'type' => 'checkbox',
|
||||
'default' => 0,
|
||||
'attributes' => ['data-conditional-id' => 'remove_css'],
|
||||
];
|
||||
|
||||
$options[] = [
|
||||
'id' => 'allow_conditionals_data',
|
||||
'name' => '',
|
||||
'desc' => 'Keep selector if a certain condition is true. For example, condition type class with match <code>.mfp-lightbox</code> can be used to search for <code>.mfp-</code> to keep all the CSS selectors that have .mfp- in selector.',
|
||||
'type' => 'group',
|
||||
'default' => [],
|
||||
'attributes' => ['data-conditional-id' => 'remove_css'],
|
||||
'options' => [
|
||||
'group_title' => 'Condition {#}',
|
||||
'add_button' => esc_html__('Add Condition', 'debloat'),
|
||||
'remove_button' => esc_html__('Remove', 'debloat'),
|
||||
'closed' => true,
|
||||
]
|
||||
];
|
||||
|
||||
|
||||
$options[] = [
|
||||
'id' => 'remove_css_on',
|
||||
'name' => esc_html__('Remove CSS On', 'debloat'),
|
||||
'desc' => esc_html__('Pages where unused CSS should be removed.', 'debloat'),
|
||||
'type' => 'multicheck',
|
||||
'options' => self::get_common('enable_on'),
|
||||
'default' => ['all'],
|
||||
'select_all_button' => false,
|
||||
'attributes' => ['data-conditional-id' => 'remove_css'],
|
||||
];
|
||||
|
||||
$options[] = [
|
||||
'id' => 'delay_css_load',
|
||||
'name' => esc_html__('Delay load Original CSS', 'debloat'),
|
||||
'desc' => esc_html__('Delay-loading all of the original CSS might be needed in situations where there are too many JS-based CSS classes that are added later such as sliders, that you cannot track down and add to exclusions right now. Or on pages that may have Auto-load Next Post.', 'debloat'),
|
||||
'type' => 'checkbox',
|
||||
'default' => 0,
|
||||
'attributes' => ['data-conditional-id' => 'remove_css'],
|
||||
];
|
||||
|
||||
$options[] = [
|
||||
'id' => 'delay_css_on',
|
||||
'name' => esc_html__('Delay load Original On', 'debloat'),
|
||||
'desc' => esc_html__('Pages where original CSS should be delayed load.', 'debloat'),
|
||||
'type' => 'multicheck',
|
||||
'options' => self::get_common('enable_on'),
|
||||
'default' => ['all'],
|
||||
'select_all_button' => false,
|
||||
'attributes' => ['data-conditional-id' => 'delay_css_load'],
|
||||
];
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
public static function get_js()
|
||||
{
|
||||
$options = [];
|
||||
|
||||
/**
|
||||
* Optimize JS
|
||||
*/
|
||||
$options[] = [
|
||||
'name' => esc_html__('Optimize JS', 'debloat'),
|
||||
// 'description' => 'foo',
|
||||
'type' => 'title',
|
||||
'id' => '_defer_js',
|
||||
];
|
||||
|
||||
$options[] = [
|
||||
'id' => 'defer_js',
|
||||
'name' => esc_html__('Defer Javascript', 'debloat'),
|
||||
'desc' => esc_html__('Delay JS execution till HTML is loaded to fix Render-Blocking JS issues.', 'debloat'),
|
||||
'type' => 'checkbox',
|
||||
'default' => 0,
|
||||
];
|
||||
|
||||
$options[] = [
|
||||
'id' => 'defer_js_excludes',
|
||||
'name' => esc_html__('Exclude Scripts', 'debloat'),
|
||||
'desc' => esc_html__('Enter one per line to exclude certain JS files from being deferred.', 'debloat'),
|
||||
'type' => 'textarea_small',
|
||||
'default' => '',
|
||||
'attributes' => ['data-conditional-id' => 'defer_js'],
|
||||
];
|
||||
|
||||
$options[] = [
|
||||
'id' => 'defer_js_inline',
|
||||
'name' => esc_html__('Defer Inline JS', 'debloat'),
|
||||
'desc' => sprintf(
|
||||
'%s<p><strong>%s</strong> %s</p>',
|
||||
esc_html__('Defer all inline JS.', 'debloat'),
|
||||
esc_html__('Note:', 'debloat'),
|
||||
esc_html__('Normally not needed. All correct dependent inline scripts are deferred by default. Enable if inline JS not enqueued using WordPress enqueue functions.', 'debloat')
|
||||
),
|
||||
'type' => 'checkbox',
|
||||
'default' => 0,
|
||||
'attributes' => ['data-conditional-id' => 'defer_js'],
|
||||
];
|
||||
|
||||
$options[] = [
|
||||
'id' => 'minify_js',
|
||||
'name' => esc_html__('Minify Javascript', 'debloat'),
|
||||
'desc' => esc_html__('Minify all the deferred or delayed JS files.', 'debloat'),
|
||||
'type' => 'checkbox',
|
||||
'default' => 0,
|
||||
];
|
||||
|
||||
$options[] = [
|
||||
'id' => 'integrations_js',
|
||||
'name' => esc_html__('Enable Plugin Integrations', 'debloat'),
|
||||
'desc' => esc_html__('Special pre-made rules for javascript, specific to plugins, are applied if enabled.', 'debloat'),
|
||||
'type' => 'multicheck_inline',
|
||||
'options' => [
|
||||
'elementor' => 'Elementor',
|
||||
'wpbakery' => 'WPBakery Page Builder',
|
||||
],
|
||||
'default' => ['elementor', 'wpbakery'],
|
||||
'select_all_button' => false,
|
||||
];
|
||||
|
||||
/**
|
||||
* Delay JS
|
||||
*/
|
||||
$options[] = [
|
||||
'name' => esc_html__('Delay Load JS', 'debloat'),
|
||||
// 'description' => 'foo',
|
||||
'type' => 'title',
|
||||
'id' => '_delay_js',
|
||||
];
|
||||
|
||||
$options[] = [
|
||||
'id' => 'delay_js',
|
||||
'name' => esc_html__('Delay Javascript', 'debloat'),
|
||||
'desc' => esc_html__('Delay execution of the targeted JS files until user interaction.', 'debloat'),
|
||||
'type' => 'checkbox',
|
||||
'default' => 0,
|
||||
];
|
||||
|
||||
$options[] = [
|
||||
'id' => 'delay_js_max',
|
||||
'name' => esc_html__('Maximum Delay (in seconds)', 'debloat'),
|
||||
'desc' => esc_html__('Max seconds to wait for interaction until delayed JS is loaded anyways.', 'debloat'),
|
||||
'type' => 'text_small',
|
||||
'default' => '',
|
||||
'attributes' => [
|
||||
'type' => 'number',
|
||||
'min' => 0,
|
||||
'data-conditional-id' => 'delay_js'
|
||||
],
|
||||
];
|
||||
|
||||
$options[] = [
|
||||
'id' => 'delay_js_all',
|
||||
'name' => esc_html__('Delay All Scripts', 'debloat'),
|
||||
'desc' => esc_html__('CAREFUL. Delays all JS files. Its better to target scripts manually below. If there are scripts that setup sliders/carousels, animations, or other similar things, these won\'t be setup until the first user interaction.', 'debloat'),
|
||||
'type' => 'checkbox',
|
||||
'default' => 0,
|
||||
'attributes' => ['data-conditional-id' => 'delay_js'],
|
||||
];
|
||||
|
||||
$options[] = [
|
||||
'id' => 'delay_js_includes',
|
||||
'name' => esc_html__('Target Scripts', 'debloat'),
|
||||
'desc' =>
|
||||
esc_html__('Will delay from these scripts. You may use an ID, part of the URL, or any code for inline scripts. One per line. Examples:', 'debloat')
|
||||
. ' <code>id:my-js-id</code>
|
||||
<br /><code>my-theme/js-file.js</code>
|
||||
<br /><code>wp-content/themes/my-theme/*</code>: All theme JS files.
|
||||
<br /><code>plugins/plugin-slug/*</code>: All JS files for plugin-slug.
|
||||
',
|
||||
'type' => 'textarea_small',
|
||||
'default' => implode("\n", [
|
||||
'twitter.com/widgets.js',
|
||||
'gtm.js',
|
||||
'id:google_gtagjs'
|
||||
]),
|
||||
'attributes' => [
|
||||
'data-conditional-id' => [
|
||||
['key' => 'delay_js'],
|
||||
['key' => 'delay_js_all', 'value' => 'off'],
|
||||
]
|
||||
],
|
||||
];
|
||||
|
||||
$options[] = [
|
||||
'id' => 'delay_js_excludes',
|
||||
'name' => esc_html__('Exclude Scripts', 'debloat'),
|
||||
'desc' =>
|
||||
esc_html__('Enter one per line to exclude certain scripts from this optimizations. Examples:', 'debloat')
|
||||
. '<code>id:my-js-id</code>
|
||||
<br /><code>my-theme/js-file.js</code>
|
||||
<br /><code>wp-content/themes/my-theme/*</code>: All theme JS files.
|
||||
<br /><code>someStringInJs</code>: Exclude by some text in inline JS tag.
|
||||
',
|
||||
'type' => 'textarea_small',
|
||||
'default' => '',
|
||||
'attributes' => ['data-conditional-id' => 'delay_js'],
|
||||
];
|
||||
|
||||
$options[] = [
|
||||
'id' => 'delay_js_adsense',
|
||||
'name' => esc_html__('Delay Google Ads', 'debloat'),
|
||||
'desc' => esc_html__('Delay Google Adsense until first interaction. Note: This may not be ideal if you have ads that are in header.', 'debloat'),
|
||||
'type' => 'checkbox',
|
||||
'default' => 1,
|
||||
'attributes' => ['data-conditional-id' => 'delay_js'],
|
||||
];
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
public static function get_general()
|
||||
{
|
||||
$options = [];
|
||||
|
||||
$options[] = [
|
||||
'name' => esc_html__('Disable for Admins', 'debloat'),
|
||||
'desc' => esc_html__('Disable processing for logged in admin users or any user with capability "manage_options". (Useful if using a pagebuilder that conflicts)', 'debloat'),
|
||||
'id' => 'disable_for_admins',
|
||||
'type' => 'checkbox',
|
||||
'default' => 0,
|
||||
];
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
public static function get_all()
|
||||
{
|
||||
return array_merge(
|
||||
self::get_css(),
|
||||
self::get_js()
|
||||
);
|
||||
}
|
||||
}
|
98
wp-content/plugins/debloat/inc/autoloader.php
Normal file
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
namespace Sphere\Debloat;
|
||||
|
||||
/**
|
||||
* Autoloader for loading classes off defined namespaces or a class map.
|
||||
*
|
||||
* @author asadkn
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Autoloader
|
||||
{
|
||||
public $class_map;
|
||||
public $namespaces = [];
|
||||
|
||||
public function __construct($namespaces = null, $prepend = false)
|
||||
{
|
||||
if (is_array($namespaces)) {
|
||||
$this->namespaces = $namespaces;
|
||||
}
|
||||
|
||||
spl_autoload_register(array($this, 'load'), true, $prepend);
|
||||
}
|
||||
|
||||
/**
|
||||
* Autoloader the class either using a class map or via conversion of
|
||||
* class name to file.
|
||||
*
|
||||
* @param string $class
|
||||
*/
|
||||
public function load($class)
|
||||
{
|
||||
if (isset($this->class_map[$class])) {
|
||||
$file = $this->class_map[$class];
|
||||
}
|
||||
else {
|
||||
foreach ($this->namespaces as $namespace => $dir) {
|
||||
if (strpos($class, $namespace) !== false) {
|
||||
$file = $this->get_file_path($class, $namespace, $dir);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($file)) {
|
||||
require_once $file;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get file path to include.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* Bunyad_Theme_Foo_Bar to inc/foo/bar/bar.php (fallback to inc/foo/bar.php)
|
||||
* Bunyad\Blocks\FooBar to blocks/foo-bar/foo-bar.php (fallback to inc/foo-bar.php)
|
||||
*
|
||||
* @return string Relative path to the file from the theme dir
|
||||
*/
|
||||
public function get_file_path($class, $prefix = '', $path = '')
|
||||
{
|
||||
// Remove namespace and convert underscore as a namespace delim.
|
||||
$class = str_replace($prefix, '', $class);
|
||||
$class = str_replace('_', '\\', $class);
|
||||
|
||||
// Split to convert CamelCase.
|
||||
$parts = explode('\\', $class);
|
||||
foreach ($parts as $key => $part) {
|
||||
|
||||
$test = substr($part, 1);
|
||||
|
||||
// Convert CamelCase to Camel-Case
|
||||
if (strtolower($test) !== $test) {
|
||||
$part = preg_replace('/(.)(?=[A-Z])/u', '$1-', $part);
|
||||
}
|
||||
|
||||
$parts[$key] = $part;
|
||||
}
|
||||
|
||||
$name = strtolower(array_pop($parts));
|
||||
$path = $path . '/' . strtolower(
|
||||
implode('/', $parts)
|
||||
);
|
||||
$path = trailingslashit($path);
|
||||
|
||||
// Preferred and fallback file path.
|
||||
$pref_file = $path . "{$name}/{$name}.php";
|
||||
$alt_file = $path . "{$name}.php";
|
||||
|
||||
// Try with directory path pattern first.
|
||||
if (file_exists($pref_file)) {
|
||||
return $pref_file;
|
||||
}
|
||||
else if (file_exists($alt_file)) {
|
||||
return $alt_file;
|
||||
}
|
||||
}
|
||||
}
|
91
wp-content/plugins/debloat/inc/base/asset.php
Normal file
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
namespace Sphere\Debloat\Base;
|
||||
|
||||
use Sphere\Debloat\Plugin;
|
||||
|
||||
/**
|
||||
* Base class for scripts and stylesheets.
|
||||
*
|
||||
* @uses Plugin::file_system()
|
||||
*
|
||||
* @author asadkn
|
||||
* @since 1.0.0
|
||||
*/
|
||||
abstract class Asset
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $orig_url;
|
||||
public $url;
|
||||
public $minified_url;
|
||||
|
||||
/**
|
||||
* Whether the asset is local or at a remote URL.
|
||||
* Note: Defaults to null for lazy init.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
private $is_remote = null;
|
||||
|
||||
/**
|
||||
* Return URL to get content from. Minified URL if present.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function get_content_url()
|
||||
{
|
||||
return $this->minified_url ?: $this->url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render attributes using key values.
|
||||
*
|
||||
* @param array $orig_attrs Key value pair of attributes.
|
||||
* @param array $safe List of attributes pre-escaped.
|
||||
* @return array Array of attributes.
|
||||
*/
|
||||
public function render_attrs($orig_attrs, $safe = [])
|
||||
{
|
||||
$attrs = [];
|
||||
foreach ($orig_attrs as $key => $value) {
|
||||
|
||||
// For true, no value is needed in HTML.
|
||||
if ($value === true) {
|
||||
$attrs[] = $key;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Adding previously escaped, but escape again just in case it was done using
|
||||
// different quotes originally.
|
||||
$value = !in_array($key, $safe) ? esc_attr($value) : $value;
|
||||
$attrs[] = sprintf('%s="%s"', $key, $value);
|
||||
}
|
||||
|
||||
return $attrs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the asset is on a remote location.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function is_remote()
|
||||
{
|
||||
if ($this->is_remote || $this->minified_url) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->is_remote === null && !Plugin::file_system()->url_to_local($this->url)) {
|
||||
$this->is_remote = true;
|
||||
}
|
||||
|
||||
return $this->is_remote;
|
||||
}
|
||||
}
|
193
wp-content/plugins/debloat/inc/delay-load/delay-load.php
Normal file
@@ -0,0 +1,193 @@
|
||||
<?php
|
||||
|
||||
namespace Sphere\Debloat;
|
||||
|
||||
use Sphere\Debloat\OptimizeCss\Stylesheet;
|
||||
use Sphere\Debloat\OptimizeJs\Script;
|
||||
|
||||
/**
|
||||
* Delay load assets singleton.
|
||||
*
|
||||
* @author asadkn
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class DelayLoad
|
||||
{
|
||||
public $enabled = true;
|
||||
public $use_js = false;
|
||||
public $js_type;
|
||||
|
||||
public $preload = [];
|
||||
|
||||
/**
|
||||
* Note: Should be used a singleton.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->register_hooks();
|
||||
}
|
||||
|
||||
public function register_hooks()
|
||||
{
|
||||
// add_action('wp_enqueue_scripts', [$this, 'register_assets']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable injection of required scripts and preloads, as needed.
|
||||
*
|
||||
* @param null|true $use_js Whether to inject delay/defer JS. null keeps the current.
|
||||
* @return void
|
||||
*/
|
||||
public function enable($use_js = null)
|
||||
{
|
||||
$this->enabled = true;
|
||||
|
||||
if ($use_js === true) {
|
||||
$this->use_js = $use_js;
|
||||
}
|
||||
}
|
||||
|
||||
public function disable()
|
||||
{
|
||||
$this->enabled = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue a preload.
|
||||
*
|
||||
* @param Stylesheet|Script $asset
|
||||
* @return void
|
||||
*/
|
||||
public function add_preload($asset)
|
||||
{
|
||||
$this->preload[] = $asset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add extras to the provided HTML buffer.
|
||||
*
|
||||
* @param string $html
|
||||
* @return string
|
||||
*/
|
||||
public function render($html)
|
||||
{
|
||||
if (!$this->enabled) {
|
||||
return $html;
|
||||
}
|
||||
|
||||
$js = $this->render_js();
|
||||
$preloads = $this->render_preloads();
|
||||
|
||||
$append = $preloads . $js;
|
||||
|
||||
// Add to body or at the end.
|
||||
// Note: Has to be at the end to ensure all <script> tags with defer has been added.
|
||||
if (strpos($html, '</body>') !== false) {
|
||||
$html = str_replace('</body>', $append . "\n</body>", $html);
|
||||
} else {
|
||||
$html .= $append;
|
||||
}
|
||||
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
protected function render_preloads()
|
||||
{
|
||||
$preloads = [];
|
||||
foreach ($this->preload as $preload) {
|
||||
$media = 'all';
|
||||
$type = ($preload instanceof Stylesheet) ? 'style' : 'script';
|
||||
|
||||
if ($type === 'style') {
|
||||
$media = $preload->media ?: $media;
|
||||
}
|
||||
|
||||
$preloads[] = sprintf(
|
||||
'<link rel="prefetch" href="%1$s" as="%2$s" media="%3$s" />',
|
||||
esc_url($preload->get_content_url()),
|
||||
$type,
|
||||
esc_attr($media)
|
||||
);
|
||||
}
|
||||
|
||||
return implode('', $preloads);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get JS enqueues and inline scripts as needed.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function render_js()
|
||||
{
|
||||
if (!$this->use_js) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$js = '';
|
||||
$min = Plugin::get_instance()->env !== 'dev' ? '.min' : '';
|
||||
|
||||
// Defer JS is always inline.
|
||||
$js .= sprintf(
|
||||
'<script data-cfasync="false">%s</script>',
|
||||
Plugin::file_system()->get_contents(
|
||||
Plugin::get_instance()->dir_path . 'inc/delay-load/js/defer-load'. $min .'.js'
|
||||
)
|
||||
);
|
||||
|
||||
// Delay load JS comes after, just in case, to not mess up readyState.
|
||||
if ($this->js_type === 'inline') {
|
||||
$js .= sprintf(
|
||||
'<script data-cfasync="false">%s</script>',
|
||||
Plugin::file_system()->get_contents(
|
||||
Plugin::get_instance()->dir_path . 'inc/delay-load/js/delay-load'. $min .'.js'
|
||||
)
|
||||
);
|
||||
|
||||
} else {
|
||||
|
||||
$js .= sprintf(
|
||||
'<script type="text/javascript" src="%s" data-cfasync="false"></script>',
|
||||
esc_url(Plugin::get_instance()->dir_url . 'inc/delay-load/js/delay-load'. $min .'.js?ver=' . Plugin::VERSION)
|
||||
);
|
||||
}
|
||||
|
||||
if (!$js) {
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Add configs.
|
||||
*/
|
||||
$configs = [
|
||||
'cssDelayType' => Plugin::options()->delay_css_type,
|
||||
'jsDelayType' => Plugin::options()->delay_js_type,
|
||||
'jsDelayMax' => Plugin::options()->delay_js_max
|
||||
];
|
||||
|
||||
$js = sprintf(
|
||||
'<script>var debloatConfig = %1$s;</script>%2$s',
|
||||
json_encode($configs),
|
||||
$js
|
||||
);
|
||||
|
||||
return $js;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for conditionals for delay load.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function should_delay_css()
|
||||
{
|
||||
if (!Plugin::options()->delay_css_load) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$valid = Plugin::process()->check_enabled(Plugin::options()->delay_css_on);
|
||||
|
||||
return apply_filters('debloat/should_delay_css', $valid);
|
||||
}
|
||||
}
|
36
wp-content/plugins/debloat/inc/delay-load/js/defer-load.js
Normal file
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* Debloat plugin's defer load.
|
||||
* @preserve
|
||||
* @copyright asadkn 2021
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
(() => {
|
||||
const n = true;
|
||||
const e = [ ...document.querySelectorAll("script[defer]") ];
|
||||
if (e.length && document.readyState !== "complete") {
|
||||
let t = document.readyState;
|
||||
Object.defineProperty(document, "readyState", {
|
||||
configurable: true,
|
||||
get() {
|
||||
return t;
|
||||
},
|
||||
set(e) {
|
||||
return t = e;
|
||||
}
|
||||
});
|
||||
let e = false;
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
t = "interactive";
|
||||
n && console.log("DCL Ready.");
|
||||
e = true;
|
||||
document.dispatchEvent(new Event("readystatechange"));
|
||||
e = false;
|
||||
});
|
||||
document.addEventListener("readystatechange", () => {
|
||||
if (!e && t === "interactive") {
|
||||
t = "complete";
|
||||
}
|
||||
});
|
||||
}
|
||||
})();
|
1
wp-content/plugins/debloat/inc/delay-load/js/defer-load.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
"use strict";(()=>{if([...document.querySelectorAll("script[defer]")].length&&"complete"!==document.readyState){let t=document.readyState;Object.defineProperty(document,"readyState",{configurable:!0,get(){return t},set(e){return t=e}});let e=!1;document.addEventListener("DOMContentLoaded",()=>{t="interactive",e=!0,document.dispatchEvent(new Event("readystatechange")),e=!1}),document.addEventListener("readystatechange",()=>{e||"interactive"!==t||(t="complete")})}})();
|
254
wp-content/plugins/debloat/inc/delay-load/js/delay-load.js
Normal file
@@ -0,0 +1,254 @@
|
||||
/**
|
||||
* Delay load functionality of debloat plugin.
|
||||
* @preserve
|
||||
* @copyright asadkn 2021
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
(() => {
|
||||
const r = window.debloatConfig || {};
|
||||
const s = true;
|
||||
let c = [];
|
||||
const d = {
|
||||
HTMLDocument: document.addEventListener.bind(document),
|
||||
Window: window.addEventListener.bind(window)
|
||||
};
|
||||
const n = {};
|
||||
let a;
|
||||
let o = false;
|
||||
let i = false;
|
||||
let l = false;
|
||||
let u = false;
|
||||
let e = false;
|
||||
let f = [];
|
||||
let t = [];
|
||||
function m() {
|
||||
h();
|
||||
w();
|
||||
document.addEventListener("debloat-load-css", () => w(true));
|
||||
document.addEventListener("debloat-load-js", () => h(true));
|
||||
}
|
||||
function h(e) {
|
||||
f = [ ...document.querySelectorAll("script[data-debloat-delay]") ];
|
||||
if (f.length) {
|
||||
E();
|
||||
y("js", e);
|
||||
}
|
||||
}
|
||||
function w(e) {
|
||||
t = [ ...document.querySelectorAll("link[data-debloat-delay]") ];
|
||||
if (t.length) {
|
||||
y("css", e);
|
||||
}
|
||||
}
|
||||
function y(t, n) {
|
||||
t = t || "js";
|
||||
const o = n ? "onload" : r[t + "DelayType"] || "onload";
|
||||
const a = t === "js" ? p : g;
|
||||
if (t === "js") {
|
||||
n || o === "onload" ? v() : D(v);
|
||||
}
|
||||
switch (o) {
|
||||
case "onload":
|
||||
D(() => a(n));
|
||||
break;
|
||||
|
||||
case "interact":
|
||||
let e = false;
|
||||
const s = [ "mousemove", "mousedown", "keydown", "touchstart", "wheel" ];
|
||||
const c = () => {
|
||||
if (e) {
|
||||
return;
|
||||
}
|
||||
e = true;
|
||||
t === "js" ? O(() => setTimeout(a, 2)) : a();
|
||||
};
|
||||
s.forEach(e => {
|
||||
document.addEventListener(e, c, {
|
||||
passive: true,
|
||||
once: true
|
||||
});
|
||||
});
|
||||
if (t === "js" && r.jsDelayMax) {
|
||||
O(() => setTimeout(c, r.jsDelayMax * 1e3));
|
||||
}
|
||||
break;
|
||||
|
||||
case "custom-delay":
|
||||
D(() => {
|
||||
const e = parseInt(element.dataset.customDelay) * 1e3;
|
||||
setTimeout(a, e);
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
function g() {
|
||||
t.forEach(e => b(e));
|
||||
}
|
||||
function p(e) {
|
||||
v();
|
||||
if (!e) {
|
||||
l = true;
|
||||
a = document.readyState;
|
||||
let t = "loading";
|
||||
Object.defineProperty(document, "readyState", {
|
||||
configurable: true,
|
||||
get() {
|
||||
return t;
|
||||
},
|
||||
set(e) {
|
||||
return t = e;
|
||||
}
|
||||
});
|
||||
}
|
||||
let t;
|
||||
const n = new Promise(e => t = e);
|
||||
const o = () => {
|
||||
if (!f.length) {
|
||||
t();
|
||||
return;
|
||||
}
|
||||
const e = b(f.shift());
|
||||
e.then(o);
|
||||
};
|
||||
o();
|
||||
n.then(j).catch(e => {
|
||||
console.error(e);
|
||||
j();
|
||||
});
|
||||
setTimeout(() => !c.length || j(), 45e3);
|
||||
}
|
||||
function v(o) {
|
||||
if (e) {
|
||||
return;
|
||||
}
|
||||
e = true;
|
||||
f.forEach(e => {
|
||||
const t = e.src || e.dataset.src;
|
||||
if (!t) {
|
||||
return;
|
||||
}
|
||||
const n = document.createElement("link");
|
||||
Object.assign(n, {
|
||||
rel: o || "preload",
|
||||
as: "script",
|
||||
href: t,
|
||||
...e.crossOrigin && {
|
||||
crossOrigin: e.crossOrigin
|
||||
}
|
||||
});
|
||||
document.head.append(n);
|
||||
});
|
||||
}
|
||||
function b(t) {
|
||||
let e;
|
||||
const n = t.dataset.src;
|
||||
const o = t => {
|
||||
return new Promise(e => {
|
||||
t.addEventListener("load", e);
|
||||
t.addEventListener("error", e);
|
||||
});
|
||||
};
|
||||
if (n) {
|
||||
const s = document.createElement("script");
|
||||
e = o(s);
|
||||
t.getAttributeNames().forEach(e => {
|
||||
e === "src" || (s[e] = t[e]);
|
||||
});
|
||||
s.async = false;
|
||||
s.src = n;
|
||||
t.parentNode.replaceChild(s, t);
|
||||
} else if (t.type && t.type === "text/debloat-script") {
|
||||
t.type = t.dataset.type || "text/javascript";
|
||||
t.text += " ";
|
||||
}
|
||||
const a = t.dataset.href;
|
||||
if (a) {
|
||||
e = o(t);
|
||||
t.href = a;
|
||||
}
|
||||
[ "debloatDelay", "src" ].forEach(e => {
|
||||
t.dataset[e] = "";
|
||||
delete t.dataset[e];
|
||||
});
|
||||
return e || Promise.resolve();
|
||||
}
|
||||
function E() {
|
||||
if (o) {
|
||||
return;
|
||||
}
|
||||
o = true;
|
||||
const e = (t, e) => {
|
||||
e.addEventListener(t, e => n[t] = e);
|
||||
};
|
||||
e("DOMContentLoaded", document);
|
||||
e("load", window);
|
||||
e("readystatechange", document);
|
||||
e("pageshow", window);
|
||||
const t = function(e, t, ...n) {
|
||||
const o = [ "readystatechange", "DOMContentLoaded", "load", "pageshow" ];
|
||||
if (l && !i && o.includes(e)) {
|
||||
s && console.log("Adding: ", e, t, n);
|
||||
const a = {
|
||||
event: e,
|
||||
cb: t,
|
||||
context: this,
|
||||
args: n
|
||||
};
|
||||
c.push(a);
|
||||
return;
|
||||
}
|
||||
if (d[this.constructor.name]) {
|
||||
d[this.constructor.name].call(this, e, t, ...n);
|
||||
}
|
||||
};
|
||||
document.addEventListener = t.bind(document);
|
||||
window.addEventListener = t.bind(window);
|
||||
Object.defineProperty(window, "onload", {
|
||||
set(e) {
|
||||
window.addEventListener("load", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
function L(e) {
|
||||
try {
|
||||
e.cb.call(e.context, n[e.event], ...e.args);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
function j() {
|
||||
if (u) {
|
||||
return;
|
||||
}
|
||||
s && console.log("Firing Load Events", c);
|
||||
u = true;
|
||||
const e = c.filter(e => e.event === "readystatechange");
|
||||
document.readyState = "interactive";
|
||||
e.forEach(e => L(e));
|
||||
for (const t of c) {
|
||||
t.event === "DOMContentLoaded" && L(t);
|
||||
}
|
||||
for (const t of c) {
|
||||
t.event === "load" && L(t);
|
||||
}
|
||||
c = [];
|
||||
u = false;
|
||||
i = true;
|
||||
l = false;
|
||||
D(() => {
|
||||
document.readyState = "complete";
|
||||
setTimeout(() => {
|
||||
e.forEach(e => L(e));
|
||||
}, 2);
|
||||
});
|
||||
}
|
||||
function D(e) {
|
||||
const t = a || document.readyState;
|
||||
t === "complete" ? e() : d.Window("load", () => e());
|
||||
}
|
||||
function O(e) {
|
||||
document.readyState !== "loading" ? e() : d.Window("DOMContentLoaded", () => e());
|
||||
}
|
||||
m();
|
||||
})();
|
1
wp-content/plugins/debloat/inc/delay-load/js/delay-load.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
"use strict";(()=>{const s=window.debloatConfig||{},a=!0;let d=[];const c={HTMLDocument:document.addEventListener.bind(document),Window:window.addEventListener.bind(window)},n={};let r,o=!1,i=!1,l=!1,u=!1,e=!1,m=[],t=[];function f(e){var t;m=[...document.querySelectorAll("script[data-debloat-delay]")],m.length&&(o||(o=!0,(t=(t,e)=>{e.addEventListener(t,e=>n[t]=e)})("DOMContentLoaded",document),t("load",window),t("readystatechange",document),t("pageshow",window),t=function(e,t,...n){var o;l&&!i&&["readystatechange","DOMContentLoaded","load","pageshow"].includes(e)?(a,o={event:e,cb:t,context:this,args:n},d.push(o)):c[this.constructor.name]&&c[this.constructor.name].call(this,e,t,...n)},document.addEventListener=t.bind(document),window.addEventListener=t.bind(window),Object.defineProperty(window,"onload",{set(e){window.addEventListener("load",e)}})),w("js",e))}function h(e){t=[...document.querySelectorAll("link[data-debloat-delay]")],t.length&&w("css",e)}function w(t,n){t=t||"js";var o=!n&&s[t+"DelayType"]||"onload";const a="js"===t?v:y;switch("js"===t&&(n||"onload"===o?p():L(p)),o){case"onload":L(()=>a(n));break;case"interact":let e=!1;const d=["mousemove","mousedown","keydown","touchstart","wheel"],c=()=>{e||(e=!0,"js"===t?j(()=>setTimeout(a,2)):a())};d.forEach(e=>{document.addEventListener(e,c,{passive:!0,once:!0})}),"js"===t&&s.jsDelayMax&&j(()=>setTimeout(c,1e3*s.jsDelayMax));break;case"custom-delay":L(()=>{var e=1e3*parseInt(element.dataset.customDelay);setTimeout(a,e)})}}function y(){t.forEach(e=>g(e))}function v(e){if(p(),!e){l=!0,r=document.readyState;let t="loading";Object.defineProperty(document,"readyState",{configurable:!0,get(){return t},set(e){return t=e}})}let t;const n=new Promise(e=>t=e),o=()=>{if(m.length){const e=g(m.shift());e.then(o)}else t()};o(),n.then(E).catch(e=>{E()}),setTimeout(()=>!d.length||E(),45e3)}function p(o){e||(e=!0,m.forEach(e=>{var t,n=e.src||e.dataset.src;n&&(t=document.createElement("link"),Object.assign(t,{rel:o||"preload",as:"script",href:n,...e.crossOrigin&&{crossOrigin:e.crossOrigin}}),document.head.append(t))}))}function g(t){let e;var n=t.dataset.src,o=t=>new Promise(e=>{t.addEventListener("load",e),t.addEventListener("error",e)});if(n){const a=document.createElement("script");e=o(a),t.getAttributeNames().forEach(e=>{"src"===e||(a[e]=t[e])}),a.async=!1,a.src=n,t.parentNode.replaceChild(a,t)}else t.type&&"text/debloat-script"===t.type&&(t.type=t.dataset.type||"text/javascript",t.text+=" ");n=t.dataset.href;return n&&(e=o(t),t.href=n),["debloatDelay","src"].forEach(e=>{t.dataset[e]="",delete t.dataset[e]}),e||Promise.resolve()}function b(e){try{e.cb.call(e.context,n[e.event],...e.args)}catch(e){}}function E(){if(!u){a,u=!0;const e=d.filter(e=>"readystatechange"===e.event);document.readyState="interactive",e.forEach(e=>b(e));for(const t of d)"DOMContentLoaded"===t.event&&b(t);for(const n of d)"load"===n.event&&b(n);d=[],u=!1,i=!0,l=!1,L(()=>{document.readyState="complete",setTimeout(()=>{e.forEach(e=>b(e))},2)})}}function L(e){"complete"===(r||document.readyState)?e():c.Window("load",()=>e())}function j(e){"loading"!==document.readyState?e():c.Window("DOMContentLoaded",()=>e())}f(),h(),document.addEventListener("debloat-load-css",()=>h(!0)),document.addEventListener("debloat-load-js",()=>f(!0))})();
|
173
wp-content/plugins/debloat/inc/file-cache.php
Normal file
@@ -0,0 +1,173 @@
|
||||
<?php
|
||||
|
||||
namespace Sphere\Debloat;
|
||||
|
||||
/**
|
||||
* Filesystem based cache for assets.
|
||||
*
|
||||
* @author asadkn
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class FileCache
|
||||
{
|
||||
/**
|
||||
* @var Filesystem
|
||||
*/
|
||||
protected $fs;
|
||||
public $cache_path;
|
||||
public $cache_url;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->fs = Plugin::file_system();
|
||||
$this->cache_path = WP_CONTENT_DIR . '/cache/debloat/';
|
||||
$this->cache_url = WP_CONTENT_URL . '/cache/debloat/';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a cached file path.
|
||||
*
|
||||
* @param string $id
|
||||
* @return bool
|
||||
*/
|
||||
public function get($id)
|
||||
{
|
||||
$file = $this->get_file_name($id);
|
||||
if (!$file) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$file = $this->get_cache_path($id) . $file;
|
||||
if ($this->fs->is_file($file)) {
|
||||
return $file;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a cached file URL.
|
||||
*
|
||||
* @param string $id
|
||||
* @return bool|string
|
||||
*/
|
||||
public function get_url($id)
|
||||
{
|
||||
if (!$this->get($id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$file = $this->get_file_name($id);
|
||||
|
||||
if (!$file) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->cache_url . $this->get_cache_type($file) . '/' . $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get file name for cache storage/retrieval provided a URL or path.
|
||||
*
|
||||
* @param string $id URL or path of a file.
|
||||
* @return string
|
||||
*/
|
||||
protected function get_file_name($id)
|
||||
{
|
||||
// Get a local path if a valid URL was provided. Remote URLs also work.
|
||||
$file = $this->fs->url_to_local($id);
|
||||
if (!$file) {
|
||||
// Remote here.
|
||||
}
|
||||
|
||||
// MD5 on the id instead of file, as it's likely to be a URL that can has a changing
|
||||
// query string reuqiring a new cached entry.
|
||||
$hash = md5($id);
|
||||
return $hash . '.' . $this->get_cache_type($file ?: $id);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Save a file in the cache.
|
||||
*
|
||||
* @param string $id Path, a local asset URL, or a unqiue name.
|
||||
* @param string $content
|
||||
* @return bool|string File path on success or false on failure.
|
||||
*/
|
||||
public function set($id, string $content = '')
|
||||
{
|
||||
if (!$content) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ensure path exists.
|
||||
$path = $this->get_cache_path($id);
|
||||
$this->fs->mkdir_p($path);
|
||||
|
||||
$file = $path . $this->get_file_name($id);
|
||||
if ($this->fs->put_contents($file, $content)) {
|
||||
return $file;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cache path based on provided file path or id.
|
||||
*
|
||||
* @param string $asset A local path or a URL.
|
||||
* @return string
|
||||
*/
|
||||
public function get_cache_path($asset = '')
|
||||
{
|
||||
$path = $this->cache_path;
|
||||
$asset = $asset ? $this->fs->url_to_local($asset) : '';
|
||||
|
||||
// Path with asset type directory.
|
||||
return $path . $this->get_cache_type($asset) . '/';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type of cache group based on file extension.
|
||||
*
|
||||
* @param string $id File path or name. URLs fine too.
|
||||
* @return string
|
||||
*/
|
||||
protected function get_cache_type(string $file)
|
||||
{
|
||||
$extension = pathinfo($file, PATHINFO_EXTENSION);
|
||||
$type = $extension === 'js' ? 'js' : 'css';
|
||||
|
||||
return $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all the cached files for specified cache.
|
||||
*
|
||||
* @param string $type
|
||||
* @return void
|
||||
*/
|
||||
public function delete_cache($type = 'js')
|
||||
{
|
||||
$dir = $this->cache_path . $type . '/';
|
||||
$files = (array) $this->fs->dirlist($dir);
|
||||
|
||||
foreach ($files as $file) {
|
||||
$this->fs->delete($dir . $file['name']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get number of files in cache for a specific type.
|
||||
*
|
||||
* @param string $type
|
||||
* @return integer
|
||||
*/
|
||||
public function get_stats($type = 'js')
|
||||
{
|
||||
$dir = $this->cache_path . $type;
|
||||
$files = $this->fs->dirlist($dir);
|
||||
|
||||
return $files ? count($files) : 0;
|
||||
}
|
||||
}
|
231
wp-content/plugins/debloat/inc/file-system.php
Normal file
@@ -0,0 +1,231 @@
|
||||
<?php
|
||||
|
||||
namespace Sphere\Debloat;
|
||||
|
||||
/**
|
||||
* Filesystem that mainly wraps the WP_File_System
|
||||
*
|
||||
* @author asadkn
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @mixin \WP_Filesystem_Base
|
||||
*/
|
||||
class FileSystem
|
||||
{
|
||||
/**
|
||||
* Pattern to remove protocol and www
|
||||
*/
|
||||
const PROTO_REMOVE_PATTERN = '#^(https?)?:?//(|www\.)#i';
|
||||
|
||||
/**
|
||||
* @var WP_Filesystem_Base
|
||||
*/
|
||||
public $filesystem;
|
||||
|
||||
protected $valid_hosts;
|
||||
protected $paths_urls;
|
||||
|
||||
/**
|
||||
* Setup file system
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
global $wp_filesystem;
|
||||
|
||||
if (empty($wp_filesystem)) {
|
||||
|
||||
require_once wp_normalize_path(ABSPATH . '/wp-admin/includes/file.php');
|
||||
|
||||
// At shutdown is usually a ob_start callback which doesn't permit calling ob_*
|
||||
if (did_action('shutdown') && ob_get_level() > 0) {
|
||||
$creds = request_filesystem_credentials('');
|
||||
}
|
||||
else {
|
||||
ob_start();
|
||||
$creds = request_filesystem_credentials('');
|
||||
ob_end_clean();
|
||||
}
|
||||
|
||||
if (!$creds) {
|
||||
$creds = array();
|
||||
}
|
||||
|
||||
$filesystem = WP_Filesystem($creds);
|
||||
|
||||
if (!$filesystem) {
|
||||
|
||||
// Fallback to lax permissions
|
||||
$upload = wp_upload_dir();
|
||||
WP_Filesystem(false, $upload['basedir'], true);
|
||||
}
|
||||
}
|
||||
|
||||
$this->filesystem = $wp_filesystem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively make parent directories for a path.
|
||||
*
|
||||
* Note: Adapted a bit from wp_mkdir_p().
|
||||
*
|
||||
* @param string $path
|
||||
* @return boolean true on success, false or failure.
|
||||
*/
|
||||
public function mkdir_p($path)
|
||||
{
|
||||
if ($this->is_dir($path)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$path = str_replace('//', '/', $path);
|
||||
|
||||
// Safe mode safety.
|
||||
$path = rtrim($path, '/');
|
||||
$path = $path ?: '/';
|
||||
|
||||
$created = $this->mkdir($path, FS_CHMOD_DIR);
|
||||
if ($created) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If it failed above, try again by creating the parent first, recursively.
|
||||
$parent = dirname($path);
|
||||
if ($parent !== '/' && $this->mkdir_p($parent)) {
|
||||
return $this->mkdir($path, FS_CHMOD_DIR);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a local file by the provided URL, if possible.
|
||||
*
|
||||
* @see wp_normalize_path()
|
||||
*
|
||||
* @return bool|string Either the path or false on failure.
|
||||
*/
|
||||
public function url_to_local($url)
|
||||
{
|
||||
$url = trim($url);
|
||||
|
||||
// Not a URL, just return the path.
|
||||
if (substr($url, 0, 4) !== 'http' && substr($url, 0, 2) !== '//') {
|
||||
return $url;
|
||||
}
|
||||
|
||||
$url = explode('?', trim($url));
|
||||
$url = trim($url[0]);
|
||||
|
||||
// We're not working with encoded URLs.
|
||||
if (strpos($url, '%') !== false) {
|
||||
$url = urldecode($url);
|
||||
}
|
||||
|
||||
// Add https:// for parse_url() or it fails.
|
||||
$url_no_proto = preg_replace(self::PROTO_REMOVE_PATTERN, '', $url);
|
||||
$url_host = parse_url('https://' . $url_no_proto, PHP_URL_HOST);
|
||||
|
||||
// Not a known host / URL.
|
||||
if (!in_array($url_host, $this->get_valid_hosts())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Go through each known path url map and stop at first matched.
|
||||
*/
|
||||
$valid_urls = $this->get_paths_urls();
|
||||
$url_dirname = dirname($url_no_proto);
|
||||
$matched = [];
|
||||
|
||||
foreach ($valid_urls as $path_url) {
|
||||
|
||||
if (strpos($url_dirname, untrailingslashit($path_url['url'])) !== false) {
|
||||
$matched = $path_url;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// We have a matched path.
|
||||
if (!empty($matched['path'])) {
|
||||
$path = wp_normalize_path(
|
||||
$matched['path'] . str_replace($matched['url'], '', $url_dirname)
|
||||
);
|
||||
|
||||
$file = trailingslashit($path) . wp_basename($url_no_proto);
|
||||
|
||||
if (file_exists($file) && is_file($file) && is_readable($file)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get recognized hostnames for stylesheet URLs.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_valid_hosts()
|
||||
{
|
||||
if (!$this->valid_hosts) {
|
||||
$this->valid_hosts = wp_list_pluck(
|
||||
$this->get_paths_urls(),
|
||||
'host'
|
||||
);
|
||||
}
|
||||
|
||||
return apply_filters('debloat/file_system/valid_hosts', $this->valid_hosts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a map of known path URLs, associated local path, and host.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_paths_urls()
|
||||
{
|
||||
if (!$this->paths_urls) {
|
||||
|
||||
// We add https:// back for parse_url() to prevent it from failing
|
||||
$site_url = preg_replace(self::PROTO_REMOVE_PATTERN, '', site_url());
|
||||
$site_host = parse_url('https://' . $site_url, PHP_URL_HOST);
|
||||
|
||||
$content_url = preg_replace(self::PROTO_REMOVE_PATTERN, '', content_url());
|
||||
$content_host = parse_url('https://' . $content_url, PHP_URL_HOST);
|
||||
|
||||
/**
|
||||
* This array will be processed in order it's defined to find the matching host and URL.
|
||||
*/
|
||||
$hosts = [
|
||||
|
||||
// First priority to use content_host and content_url()
|
||||
'content' => [
|
||||
'url' => $content_url,
|
||||
'path' => WP_CONTENT_DIR,
|
||||
'host' => $content_host
|
||||
],
|
||||
|
||||
// Fallback to using site URL with ABSPATH
|
||||
'site' => [
|
||||
'url' => $site_url,
|
||||
'path' => ABSPATH,
|
||||
'host' => $site_host
|
||||
],
|
||||
];
|
||||
|
||||
$this->paths_urls = apply_filters('debloat/file_system/paths_urls', $hosts);
|
||||
}
|
||||
|
||||
return $this->paths_urls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Proxies to WP_Filesystem_Base
|
||||
*/
|
||||
public function __call($name, $arguments)
|
||||
{
|
||||
return call_user_func_array([$this->filesystem, $name], $arguments);
|
||||
}
|
||||
|
||||
}
|
156
wp-content/plugins/debloat/inc/integrations/elementor.php
Normal file
@@ -0,0 +1,156 @@
|
||||
<?php
|
||||
|
||||
namespace Sphere\Debloat\Integrations;
|
||||
|
||||
use Sphere\Debloat\Plugin;
|
||||
|
||||
/**
|
||||
* Rules specific to Elementor plugin.
|
||||
*/
|
||||
class Elementor
|
||||
{
|
||||
public $allow_selectors;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->register_hooks();
|
||||
}
|
||||
|
||||
public function register_hooks()
|
||||
{
|
||||
add_action('wp', [$this, 'setup']);
|
||||
}
|
||||
|
||||
public function setup()
|
||||
{
|
||||
if (in_array('elementor', Plugin::options()->integrations_css)) {
|
||||
$this->setup_remove_css();
|
||||
}
|
||||
|
||||
if (in_array('elementor', Plugin::options()->integrations_js)) {
|
||||
$this->setup_delay_js();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Special rules related to remove css when Elementor is active.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setup_remove_css()
|
||||
{
|
||||
// Add all Elementor frontend files for CSS processing.
|
||||
add_filter('debloat/remove_css_includes', function($include) {
|
||||
|
||||
$include[] = 'id:elementor-frontend-css';
|
||||
$include[] = 'id:elementor-pro-css';
|
||||
// $include[] = 'elementor/*font-awesome';
|
||||
return $include;
|
||||
});
|
||||
|
||||
add_filter('debloat/remove_css_excludes', function($exclude, \Sphere\Debloat\RemoveCss $remove_css) {
|
||||
|
||||
// Don't bother with animations CSS file as it won't remove much.
|
||||
if (!empty($remove_css->used_markup['classes']['elementor-invisible'])) {
|
||||
$exclude[] = 'id:elementor-animations';
|
||||
}
|
||||
|
||||
return $exclude;
|
||||
}, 10, 2);
|
||||
|
||||
/**
|
||||
* Elementor selectors extras.
|
||||
*/
|
||||
$this->allow_selectors = [
|
||||
[
|
||||
'type' => 'any',
|
||||
'sheet' => 'id:elementor-',
|
||||
'search' => [
|
||||
'*.e--ua-*',
|
||||
'.elementor-loading',
|
||||
'.elementor-invisible',
|
||||
'.elementor-background-video-embed',
|
||||
]
|
||||
],
|
||||
[
|
||||
'type' => 'class',
|
||||
'class' => 'elementor-invisible',
|
||||
'sheet' => 'id:elementor-',
|
||||
'search' => [
|
||||
'.animated'
|
||||
]
|
||||
],
|
||||
[
|
||||
'type' => 'class',
|
||||
'class' => 'elementor-invisible',
|
||||
'sheet' => 'id:elementor-',
|
||||
'search' => [
|
||||
'.animated'
|
||||
]
|
||||
],
|
||||
];
|
||||
|
||||
if (is_user_logged_in()) {
|
||||
$this->allow_selectors[] = [
|
||||
'type' => 'any',
|
||||
'sheet' => 'id:elementor-',
|
||||
'search' => [
|
||||
'#wp-admin-bar*',
|
||||
'*#wpadminbar*',
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
if (defined('ELEMENTOR_PRO_VERSION')) {
|
||||
$this->allow_selectors = array_merge($this->allow_selectors, [
|
||||
[
|
||||
'type' => 'class',
|
||||
'class' => 'elementor-posts-container',
|
||||
// 'sheet' => 'id:elementor-',
|
||||
'search' => [
|
||||
'.elementor-posts-container',
|
||||
'.elementor-has-item-ratio'
|
||||
]
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
add_filter('debloat/allow_css_selectors', function($allow, \Sphere\Debloat\RemoveCss $remove_css) {
|
||||
|
||||
$html = $remove_css->html;
|
||||
if (strpos($html, 'background_slideshow_gallery') !== false) {
|
||||
array_push($this->allow_selectors, ...[
|
||||
[
|
||||
'type' => 'any',
|
||||
'sheet' => 'id:elementor-',
|
||||
'search' => [
|
||||
'*.swiper-*',
|
||||
'*.elementor-background-slideshow*',
|
||||
'.elementor-ken-burns*',
|
||||
]
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
return array_merge($allow, $this->allow_selectors);
|
||||
}, 10, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Special rules related to Delay JS when Elementor is active.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setup_delay_js()
|
||||
{
|
||||
add_filter('debloat/delay_js_includes', function($include) {
|
||||
$include[] = 'elementor/*';
|
||||
|
||||
// Admin bar should also be delayed as elementor creates admin bar items later
|
||||
// and the events won't register.
|
||||
$include[] = 'wp-includes/js/admin-bar*.js';
|
||||
|
||||
return $include;
|
||||
});
|
||||
}
|
||||
}
|
177
wp-content/plugins/debloat/inc/integrations/wpbakery.php
Normal file
@@ -0,0 +1,177 @@
|
||||
<?php
|
||||
|
||||
namespace Sphere\Debloat\Integrations;
|
||||
use Sphere\Debloat\Plugin;
|
||||
|
||||
/**
|
||||
* Rules specific to WPBakery Page Builder plugin.
|
||||
*/
|
||||
class Wpbakery
|
||||
{
|
||||
public $allow_selectors;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->register_hooks();
|
||||
}
|
||||
|
||||
public function register_hooks()
|
||||
{
|
||||
add_action('wp', [$this, 'setup']);
|
||||
}
|
||||
|
||||
public function setup()
|
||||
{
|
||||
if (in_array('wpbakery', Plugin::options()->integrations_css)) {
|
||||
$this->setup_remove_css();
|
||||
}
|
||||
|
||||
if (in_array('wpbakery', Plugin::options()->integrations_js)) {
|
||||
$this->setup_delay_js();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Special rules related to remove css when WPBakery is active.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setup_remove_css()
|
||||
{
|
||||
// Add all WPBakery frontend files for CSS processing.
|
||||
add_filter('debloat/remove_css_includes', function($include) {
|
||||
|
||||
// Only need to remove unused on this. All other CSS files are modular and included only if needed.
|
||||
$include[] = 'id:js_composer_front';
|
||||
|
||||
// FontAwesome can also go through this.
|
||||
$include[] = 'js_composer/*font-awesome';
|
||||
|
||||
return $include;
|
||||
});
|
||||
|
||||
add_filter('debloat/remove_css_excludes', function($exclude, \Sphere\Debloat\RemoveCss $remove_css) {
|
||||
// // Don't bother with animations CSS file as it won't remove much.
|
||||
// $exclude[] = 'id:vc_animate-css';
|
||||
|
||||
// // Pageable owl carousel.
|
||||
// $exclude[] = 'id:vc_pageable_owl-carousel';
|
||||
|
||||
// // prettyPhoto would need all the CSS.
|
||||
// $exclude[] = 'js_composer/*prettyphoto';
|
||||
|
||||
// // owlcarousel is added only if needed.
|
||||
// $exclude[] = 'js_composer/*owl';
|
||||
|
||||
return $exclude;
|
||||
}, 10, 2);
|
||||
|
||||
/**
|
||||
* WPbakery selectors extras.
|
||||
*/
|
||||
$this->allow_selectors = [
|
||||
[
|
||||
'type' => 'any',
|
||||
'search' => [
|
||||
'.vc_mobile',
|
||||
'.vc_desktop',
|
||||
]
|
||||
],
|
||||
[
|
||||
'type' => 'class',
|
||||
'class' => 'vc_parallax',
|
||||
'sheet' => 'id:js_composer_front',
|
||||
'search' => [
|
||||
'*.vc_parallax*',
|
||||
'.vc_hidden'
|
||||
]
|
||||
],
|
||||
[
|
||||
'type' => 'class',
|
||||
'class' => 'vc_pie_chart',
|
||||
'sheet' => 'id:js_composer_front',
|
||||
'search' => [
|
||||
'.vc_ready'
|
||||
]
|
||||
],
|
||||
|
||||
[
|
||||
'type' => 'class',
|
||||
'class' => 'wpb_gmaps_widget',
|
||||
'sheet' => 'id:js_composer_front',
|
||||
'search' => [
|
||||
'.map_ready',
|
||||
]
|
||||
],
|
||||
|
||||
[
|
||||
'type' => 'class',
|
||||
'class' => 'wpb_animate_when_almost_visible',
|
||||
'sheet' => 'id:js_composer_front',
|
||||
'search' => [
|
||||
'.wpb_start_animation',
|
||||
'.animated'
|
||||
]
|
||||
],
|
||||
|
||||
[
|
||||
'type' => 'class',
|
||||
'class' => 'vc_toggle',
|
||||
'sheet' => 'id:js_composer_front',
|
||||
'search' => [
|
||||
'.vc_toggle_active',
|
||||
]
|
||||
],
|
||||
|
||||
[
|
||||
'type' => 'class',
|
||||
'class' => 'vc_grid',
|
||||
'sheet' => 'id:js_composer_front',
|
||||
'search' => [
|
||||
'.vc_grid-loading',
|
||||
'.vc_visible-item',
|
||||
'.vc_is-hover',
|
||||
|
||||
// -complete and -failed etc. too
|
||||
'*.vc-spinner*',
|
||||
'*.vc-grid*.vc_active*',
|
||||
|
||||
// Other dependencies maybe: prettyPhoto, owlcarousel for pagination of specific type.
|
||||
]
|
||||
],
|
||||
];
|
||||
|
||||
add_filter('debloat/allow_css_selectors', function($allow, \Sphere\Debloat\RemoveCss $remove_css) {
|
||||
|
||||
// $html = $remove_css->html;
|
||||
// if (strpos($html, 'background_slideshow_gallery') !== false) {
|
||||
// array_push($this->allow_selectors, ...[
|
||||
// [
|
||||
// 'type' => 'any',
|
||||
// 'sheet' => 'id:elementor-',
|
||||
// 'search' => [
|
||||
// '*.swiper-*',
|
||||
// '*.elementor-background-slideshow*',
|
||||
// '.elementor-ken-burns*',
|
||||
// ]
|
||||
// ],
|
||||
// ]);
|
||||
// }
|
||||
|
||||
return array_merge($allow, $this->allow_selectors);
|
||||
}, 10, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Special rules related to Delay JS when WPBakery is active.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setup_delay_js()
|
||||
{
|
||||
add_filter('debloat/delay_js_includes', function($include) {
|
||||
$include[] = 'js_composer/*';
|
||||
return $include;
|
||||
});
|
||||
}
|
||||
}
|
201
wp-content/plugins/debloat/inc/minifier.php
Normal file
@@ -0,0 +1,201 @@
|
||||
<?php
|
||||
|
||||
namespace Sphere\Debloat;
|
||||
|
||||
use Sphere\Debloat\Base\Asset;
|
||||
use Sphere\Debloat\OptimizeCss\Stylesheet;
|
||||
use MatthiasMullie\Minify;
|
||||
|
||||
/**
|
||||
* Minifer for assets with cache integration.
|
||||
*
|
||||
* @author asadkn
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Minifier
|
||||
{
|
||||
protected $asset_type = 'js';
|
||||
|
||||
/**
|
||||
* @var Sphere\Debloat\OptimizeCss\Stylesheet|Sphere\Debloat\OptimizeJs\Script
|
||||
*/
|
||||
protected $asset;
|
||||
|
||||
/**
|
||||
* @param \Sphere\Debloat\Base\Asset $asset
|
||||
*/
|
||||
public function __construct(Asset $asset)
|
||||
{
|
||||
if ($asset instanceof Stylesheet) {
|
||||
$this->asset_type = 'css';
|
||||
}
|
||||
|
||||
$this->asset = $asset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Minify the asset, cache it, and replace its URL in the asset object.
|
||||
*
|
||||
* @uses Plugin::file_cache()
|
||||
* @uses Plugin::file_system()
|
||||
*
|
||||
* @return string URL of the minified file.
|
||||
*/
|
||||
public function process()
|
||||
{
|
||||
// Not for inline assets.
|
||||
if (!$this->asset->url) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Debugging scripts. Do not minify.
|
||||
if (defined('SCRIPT_DEBUG') && SCRIPT_DEBUG) {
|
||||
return;
|
||||
}
|
||||
|
||||
$file = Plugin::file_cache()->get_url($this->asset->url);
|
||||
if (!$file) {
|
||||
$minify = $this->minify();
|
||||
if (!$minify) {
|
||||
return;
|
||||
}
|
||||
|
||||
// For CSS assets, convert URLs to fully qualified.
|
||||
$this->maybe_convert_urls();
|
||||
|
||||
if (!Plugin::file_cache()->set($this->asset->url, $this->asset->content)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$file = Plugin::file_cache()->get_url($this->asset->url);
|
||||
}
|
||||
|
||||
$this->asset->minified_url = $file;
|
||||
return $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Minify the file using the URL in the asset object.
|
||||
*
|
||||
* @return string|boolean
|
||||
*/
|
||||
public function minify()
|
||||
{
|
||||
// We support google fonts remote fetch.
|
||||
if (
|
||||
Plugin::options()->optimize_gfonts_inline &&
|
||||
$this->asset instanceof Stylesheet &&
|
||||
$this->asset->is_google_fonts()
|
||||
) {
|
||||
$this->fetch_remote_content();
|
||||
|
||||
} else {
|
||||
// We minify and cache local source only for now.
|
||||
$source_file = Plugin::file_system()->url_to_local($this->asset->url);
|
||||
if (!$source_file) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$source = Plugin::file_system()->get_contents($source_file);
|
||||
$this->asset->content = $source;
|
||||
}
|
||||
|
||||
/**
|
||||
* We want a cached file with source data whether existing is minified or not - as
|
||||
* post-processing is needed for URLs when inlining the CSS.
|
||||
*
|
||||
* For JS, caching the already min files also serves the purpose of not testing them
|
||||
* again, unnecessarily.
|
||||
*/
|
||||
if ($this->is_content_minified()) {
|
||||
return $this->asset->content;
|
||||
}
|
||||
|
||||
Util\debug_log('Minifying: ' . $this->asset->url);
|
||||
|
||||
// JS minifier.
|
||||
if ($this->asset_type === 'js') {
|
||||
|
||||
// Improper handling for older webpack: https://github.com/matthiasmullie/minify/issues/375
|
||||
if (strpos($source, 'var __webpack_require__ = function (moduleId)') !== false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$minifier = new Minify\JS($this->asset->content);
|
||||
$this->asset->content = $minifier->minify();
|
||||
|
||||
} else {
|
||||
|
||||
// CSS minifier. Set content and convert urls.
|
||||
$minifier = new Minify\CSS($this->asset->content);
|
||||
$this->asset->content = $minifier->minify();
|
||||
}
|
||||
|
||||
return $this->asset->content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert URLs for CSS assets.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function maybe_convert_urls()
|
||||
{
|
||||
if ($this->asset_type !== 'css') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if any non-data URLs exist.
|
||||
if (!preg_match('/url\((?![\'"\s]*data:)/', $this->asset->content)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->asset->convert_urls();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get remote asset content and add to asset content.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function fetch_remote_content()
|
||||
{
|
||||
$request = wp_remote_get($this->asset->url, [
|
||||
'timeout' => 5,
|
||||
// For google fonts mainly.
|
||||
'user-agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36',
|
||||
]);
|
||||
|
||||
if (is_wp_error($request) || empty($request['body'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->asset->content = $request['body'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if provided content is already minified.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function is_content_minified($content = '')
|
||||
{
|
||||
$content = $content ?: $this->asset->content;
|
||||
|
||||
// Already minified asset.
|
||||
if (preg_match('/[\-\.]min\.(js|css)/', $this->asset->url)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$content = trim($content);
|
||||
if (!$content) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Hacky, but will do.
|
||||
$new_lines = substr_count($content, "\n", 0, min(strlen($content), 2000));
|
||||
if ($new_lines < 5) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
106
wp-content/plugins/debloat/inc/optimize-css/google-fonts.php
Normal file
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
namespace Sphere\Debloat\OptimizeCss;
|
||||
|
||||
use Sphere\Debloat\Plugin;
|
||||
|
||||
/**
|
||||
* Add a few Google Font optimizations.
|
||||
*
|
||||
* @author asadkn
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class GoogleFonts
|
||||
{
|
||||
public $active = false;
|
||||
protected $renders = [];
|
||||
|
||||
public function enable()
|
||||
{
|
||||
$this->active = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add resource hints for preconnect and so on.
|
||||
*
|
||||
* @param string $html Full DOM HTML.
|
||||
* @return void
|
||||
*/
|
||||
public function add_hints($html)
|
||||
{
|
||||
if (!$this->active || !Plugin::options()->optimize_gfonts) {
|
||||
return $html;
|
||||
}
|
||||
|
||||
// preconnect with dns-prefetch fallback for Firefox. Due to safari bug, can't be in same rel.
|
||||
$hint = '<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />';
|
||||
$hint .= '<link rel="dns-prefetch" href="https://fonts.gstatic.com" />';
|
||||
|
||||
// Only needed if not inlined.
|
||||
if (!Plugin::options()->optimize_css || !Plugin::options()->optimize_gfonts_inline) {
|
||||
$hint .= '<link rel="preconnect" href="https://fonts.googleapis.com" crossorigin />';
|
||||
$hint .= '<link rel="dns-prefetch" href="https://fonts.googleapis.com" />';
|
||||
}
|
||||
|
||||
// Add in to head.
|
||||
$html = str_replace('<head>', '<head>' . $hint, $html);
|
||||
|
||||
// No longer needed as preconnect's better and we always want to use https.
|
||||
$html = str_replace("<link rel='dns-prefetch' href='//fonts.googleapis.com' />", '', $html);
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Late processing and injecting data in HTML DOM.
|
||||
*
|
||||
* @param string $html
|
||||
* @return string
|
||||
*/
|
||||
public function render_in_dom($html)
|
||||
{
|
||||
if ($this->renders) {
|
||||
$html = str_replace('<head>', '<head>' . implode('', $this->renders), $html);
|
||||
}
|
||||
|
||||
$html = $this->add_hints($html);
|
||||
return $html;
|
||||
}
|
||||
|
||||
public function optimize(Stylesheet $sheet)
|
||||
{
|
||||
if (!$sheet->is_google_fonts()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set normal render if optimizations are disabled.
|
||||
if (!Plugin::options()->optimize_gfonts) {
|
||||
$sheet->render_type = 'normal';
|
||||
return;
|
||||
}
|
||||
|
||||
$sheet->delay_type = 'preload';
|
||||
if (strpos($sheet->url, 'display=') === false) {
|
||||
$sheet->url .= '&display=swap';
|
||||
}
|
||||
}
|
||||
|
||||
public function do_render(Stylesheet $sheet)
|
||||
{
|
||||
return $sheet->render();
|
||||
|
||||
// $orig_media = $sheet->media;
|
||||
|
||||
// // If no display= or if display=auto.
|
||||
// if (!preg_match('/display=(?!auto)/', $sheet->url)) {
|
||||
// $sheet->media = 'x';
|
||||
// }
|
||||
|
||||
// // Add the JS to render with display: swap on mobile.
|
||||
// $extra = "<script>const e = document.currentScript.previousElementSibling; window.innerWidth > 1024 || (e.href+='&display=swap'); e.media='" . esc_js($orig_media) ."'</script>";
|
||||
// $this->renders[] = $sheet->render() . $extra;
|
||||
|
||||
// // Return empty space to strip out the tag.
|
||||
// return ' ';
|
||||
}
|
||||
}
|
251
wp-content/plugins/debloat/inc/optimize-css/optimize-css.php
Normal file
@@ -0,0 +1,251 @@
|
||||
<?php
|
||||
|
||||
namespace Sphere\Debloat;
|
||||
use Sphere\Debloat\OptimizeCss\Stylesheet;
|
||||
|
||||
/**
|
||||
* Process stylesheets to debloat and optimize CSS.
|
||||
*
|
||||
* @author asadkn
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class OptimizeCss
|
||||
{
|
||||
/**
|
||||
* @var \DOMDocument
|
||||
*/
|
||||
protected $dom;
|
||||
protected $html;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $stylesheets;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $exclude_sheets;
|
||||
|
||||
public function __construct(\DOMDocument $dom, string $raw_html)
|
||||
{
|
||||
$this->dom = $dom;
|
||||
$this->html = $raw_html;
|
||||
}
|
||||
|
||||
public function process()
|
||||
{
|
||||
$this->find_stylesheets();
|
||||
|
||||
// Setup optimization excludes.
|
||||
$exclude = Util\option_to_array(Plugin::options()->optimize_css_excludes);
|
||||
$this->exclude_sheets = apply_filters('debloat/optimize_css_excludes', $exclude);
|
||||
|
||||
// Remove CSS first, if any.
|
||||
if ($this->should_remove_css()) {
|
||||
$remove_css = new RemoveCss($this->stylesheets, $this->dom, $this->html);
|
||||
$this->html = $remove_css->process();
|
||||
}
|
||||
|
||||
/**
|
||||
* Process and replace stylesheets with CSS cleaned.
|
||||
*/
|
||||
$has_delayed = false;
|
||||
$has_gfonts = false;
|
||||
$replacements = [];
|
||||
|
||||
/** @var Stylesheet $sheet */
|
||||
foreach ($this->stylesheets as $sheet) {
|
||||
$replacement = '';
|
||||
|
||||
// Optimizations such as min and inline.
|
||||
$this->optimize($sheet);
|
||||
|
||||
if (Plugin::options()->optimize_gfonts && $sheet->is_google_fonts()) {
|
||||
$replacement = Plugin::google_fonts()->do_render($sheet);
|
||||
$has_gfonts = true;
|
||||
}
|
||||
|
||||
if (!$replacement) {
|
||||
// Get the rendered stylesheet to replace original with.
|
||||
$replacement = $sheet->render();
|
||||
}
|
||||
|
||||
if ($replacement) {
|
||||
// Util\debug_log('Replacing: ' . print_r($sheet, true));
|
||||
$replacements[$sheet->orig_url] = $replacement;
|
||||
|
||||
if ($sheet->has_delay()) {
|
||||
$has_delayed = true;
|
||||
|
||||
// onload and preload type doesn't need prefetch; both use a non-JS method.
|
||||
if (!in_array($sheet->delay_type, ['onload', 'preload'])) {
|
||||
Plugin::delay_load()->add_preload($sheet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Found Google Fonts.
|
||||
if ($sheet->is_google_fonts()) {
|
||||
$has_gfonts = true;
|
||||
}
|
||||
|
||||
// Free up memory.
|
||||
$sheet->content = null;
|
||||
$sheet->parsed_data = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make stylesheet replacements, if any. Slightly more efficient in one go.
|
||||
*/
|
||||
if ($replacements) {
|
||||
$urls = array_map('preg_quote', array_keys($replacements));
|
||||
|
||||
// Using callback to prevent issues with backreferences such as $1 or \0 in replacement string.
|
||||
$this->html = preg_replace_callback(
|
||||
'#<link[^>]*href=(?:"|\'|)('. implode('|', $urls) .')(?:"|\'|\s)[^>]*>#Usi',
|
||||
function ($match) use ($replacements) {
|
||||
if (!empty($replacements[ $match[1] ])) {
|
||||
return $replacements[ $match[1] ];
|
||||
}
|
||||
|
||||
return $match[0];
|
||||
},
|
||||
$this->html
|
||||
);
|
||||
}
|
||||
|
||||
if ($has_delayed) {
|
||||
Plugin::delay_load()->enable(
|
||||
Plugin::options()->delay_css_type === 'onload' ? true : null
|
||||
);
|
||||
}
|
||||
|
||||
if ($has_gfonts) {
|
||||
Plugin::google_fonts()->enable();
|
||||
$this->html = Plugin::google_fonts()->render_in_dom($this->html);
|
||||
}
|
||||
|
||||
return $this->html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply CSS optimizes such as minify and inline, if enabled.
|
||||
*
|
||||
* @param Stylesheet $sheet
|
||||
* @return void
|
||||
*/
|
||||
public function optimize(Stylesheet $sheet)
|
||||
{
|
||||
if (!$this->should_optimize($sheet)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We're going to use onload delay method (non-JS) fixing render blocking.
|
||||
$sheet->delay_type = 'onload';
|
||||
$sheet->set_render('delay');
|
||||
|
||||
// Should the sheet be minified.
|
||||
$minify = Plugin::options()->optimize_css_minify;
|
||||
|
||||
// For inline CSS, minification is enforced.
|
||||
if (Plugin::options()->optimize_css_to_inline) {
|
||||
$minify = true;
|
||||
}
|
||||
|
||||
// Will optimize if it's a google font. Note: Has to be done before minify.
|
||||
Plugin::google_fonts()->optimize($sheet);
|
||||
|
||||
// Google Fonts inline also relies on minification.
|
||||
if ($sheet->is_google_fonts() && Plugin::options()->optimize_gfonts_inline) {
|
||||
$minify = true;
|
||||
}
|
||||
|
||||
if ($minify) {
|
||||
$minifier = new Minifier($sheet);
|
||||
$minifier->process();
|
||||
}
|
||||
|
||||
if (Plugin::options()->optimize_css_to_inline) {
|
||||
if (!$sheet->content) {
|
||||
$file = Plugin::file_system()->url_to_local($sheet->get_content_url());
|
||||
|
||||
if ($file) {
|
||||
$sheet->content = Plugin::file_system()->get_contents($file);
|
||||
}
|
||||
}
|
||||
|
||||
// If we have content by now.
|
||||
if ($sheet->content) {
|
||||
$sheet->set_render('inline');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if stylesheet should be optimized, based on exclusion and inclusion
|
||||
* rules and settings.
|
||||
*
|
||||
* @param Stylesheet $sheet
|
||||
* @return boolean
|
||||
*/
|
||||
public function should_optimize(Stylesheet $sheet)
|
||||
{
|
||||
// Only go ahead if optimizations are enabled and remove css hasn't happened.
|
||||
if (!Plugin::options()->optimize_css || $sheet->render_type === 'remove_css') {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Debugging scripts. Can't be minified, so can't be inline either.
|
||||
if (defined('SCRIPT_DEBUG') && SCRIPT_DEBUG) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle manual excludes first.
|
||||
if ($this->exclude_sheets) {
|
||||
foreach ($this->exclude_sheets as $exclude) {
|
||||
if (Util\asset_match($exclude, $sheet)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all the stylesheet links.
|
||||
*
|
||||
* @return Stylesheet[]
|
||||
*/
|
||||
public function find_stylesheets()
|
||||
{
|
||||
$stylesheets = [];
|
||||
|
||||
// Note: Can't use DOM parser as html entities in the URLs will be removed and
|
||||
// replacing won't be possible later.
|
||||
preg_match_all('#<link[^>]*stylesheet[^>]*>#Usi', $this->html, $matches);
|
||||
|
||||
foreach ($matches[0] as $sheet) {
|
||||
$sheet = Stylesheet::from_tag($sheet);
|
||||
|
||||
if ($sheet) {
|
||||
$stylesheets[] = $sheet;
|
||||
}
|
||||
}
|
||||
|
||||
$this->stylesheets = $stylesheets;
|
||||
return $this->stylesheets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should unused CSS be removed.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function should_remove_css()
|
||||
{
|
||||
$valid = Plugin::options()->remove_css && Plugin::process()->check_enabled(Plugin::options()->remove_css_on);
|
||||
return apply_filters('debloat/should_remove_css', $valid);
|
||||
}
|
||||
}
|
296
wp-content/plugins/debloat/inc/optimize-css/stylesheet.php
Normal file
@@ -0,0 +1,296 @@
|
||||
<?php
|
||||
|
||||
namespace Sphere\Debloat\OptimizeCss;
|
||||
|
||||
use Sphere\Debloat\Base\Asset;
|
||||
use Sphere\Debloat\Util;
|
||||
|
||||
/**
|
||||
* Value object for stylehseets.
|
||||
*
|
||||
* @author asadkn
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Stylesheet extends Asset
|
||||
{
|
||||
public $has_cache = false;
|
||||
|
||||
/**
|
||||
* Specify a different id to use while rendering the script.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $render_id = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $file;
|
||||
|
||||
/**
|
||||
* CSS content.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $content = '';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $parsed_data;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $render_type = '';
|
||||
public $delay_type = 'onload';
|
||||
|
||||
/**
|
||||
* Whether delay load exists. Some sheets may have a different render_type but
|
||||
* may still need to be delayed in addition.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
public $has_delay = false;
|
||||
|
||||
/**
|
||||
* Media type for this stylesheet.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $media;
|
||||
|
||||
/**
|
||||
* Pre-rendered content
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $render_string;
|
||||
|
||||
public $original_size = 0;
|
||||
public $new_size = 0;
|
||||
|
||||
/**
|
||||
* Whether the stylesheet is a google fonts link.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $is_google_fonts = false;
|
||||
|
||||
public function __construct(string $id, string $url)
|
||||
{
|
||||
$this->id = $id;
|
||||
$this->orig_url = $url;
|
||||
|
||||
// Cleaned URL.
|
||||
$this->url = html_entity_decode($url, ENT_COMPAT | ENT_SUBSTITUTE);
|
||||
|
||||
if (!$this->id) {
|
||||
$this->id = md5($this->url);
|
||||
}
|
||||
|
||||
$this->is_google_fonts = stripos($this->url, 'fonts.googleapis.com/css') !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method: Create an instance provided an HTML tag.
|
||||
*
|
||||
* @param string $tag
|
||||
* @return boolean|self
|
||||
*/
|
||||
public static function from_tag(string $tag)
|
||||
{
|
||||
$attrs = Util\parse_attrs($tag);
|
||||
|
||||
if (!isset($attrs['href'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$sheet = new self($attrs['id'] ?? '', $attrs['href']);
|
||||
$sheet->media = $attrs['media'] ?? '';
|
||||
|
||||
return $sheet;
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
if ($this->render_string) {
|
||||
return $this->render_string;
|
||||
}
|
||||
|
||||
$attrs = [
|
||||
'rel' => 'stylesheet',
|
||||
'id' => $this->render_id ?: $this->id,
|
||||
];
|
||||
|
||||
if ($this->media) {
|
||||
$attrs['media'] = $this->media;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Render type 'delay' at onload or delay via JS for later.
|
||||
*/
|
||||
if ($this->render_type === 'delay') {
|
||||
if ($this->media === 'print') {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ($this->delay_type === 'onload') {
|
||||
$media = $this->media ?? 'all';
|
||||
$attrs = array_replace($attrs, [
|
||||
'media' => 'print',
|
||||
'href' => $this->get_content_url(),
|
||||
'onload' => "this.media='{$media}'"
|
||||
]);
|
||||
|
||||
} else if ($this->delay_type === 'preload') {
|
||||
$attrs = array_replace($attrs, [
|
||||
'rel' => 'preload',
|
||||
'as' => 'style',
|
||||
'href' => $this->get_content_url(),
|
||||
'onload' => "this.rel='stylesheet'"
|
||||
]);
|
||||
|
||||
} else {
|
||||
/**
|
||||
* Other types of delayed loads are handled via JS, so add the relevant data.
|
||||
*/
|
||||
$attrs += [
|
||||
'data-debloat-delay' => true,
|
||||
'data-href' => $this->get_content_url()
|
||||
];
|
||||
}
|
||||
|
||||
return sprintf(
|
||||
'<link %1$s/>',
|
||||
implode(' ', $this->render_attrs($attrs, ['onload']))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 2. Render type 'inline' when the CSS has to be inlined.
|
||||
*/
|
||||
if ($this->render_type === 'inline') {
|
||||
if (!$this->content) {
|
||||
return '';
|
||||
}
|
||||
|
||||
unset($attrs['rel']);
|
||||
|
||||
if ($attrs['media'] === 'all') {
|
||||
unset($attrs['media']);
|
||||
}
|
||||
|
||||
return sprintf(
|
||||
'<style %1$s>%2$s</style>',
|
||||
implode(' ', $this->render_attrs($attrs)),
|
||||
$this->content
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 3. Normal render. Usually for stylesheets that just have to be minified.
|
||||
*/
|
||||
if ($this->render_type === 'normal') {
|
||||
$attrs += [
|
||||
'href' => $this->get_content_url()
|
||||
];
|
||||
|
||||
return sprintf(
|
||||
'<link %1$s/>',
|
||||
implode(' ', $this->render_attrs($attrs))
|
||||
);
|
||||
}
|
||||
|
||||
// Default to nothing.
|
||||
return '';
|
||||
}
|
||||
|
||||
public function set_render($type, $render_string = '')
|
||||
{
|
||||
$this->render_type = $type;
|
||||
|
||||
if ($render_string) {
|
||||
$this->render_string = $render_string;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not stylesheet is delayed or has a delayed factor to it (such as
|
||||
* remove_css + delay combo).
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function has_delay()
|
||||
{
|
||||
return $this->has_delay || $this->render_type === 'delay';
|
||||
}
|
||||
|
||||
public function convert_urls()
|
||||
{
|
||||
// Original base URL.
|
||||
$base_url = preg_replace('#[^/]+\?.*$#', '', $this->url);
|
||||
|
||||
// Borrowed and modified from MatthiasMullie\Minify\CSS.
|
||||
$regex = '/
|
||||
# open url()
|
||||
url\(
|
||||
\s*
|
||||
|
||||
# open path enclosure
|
||||
(?P<quotes>["\'])?
|
||||
|
||||
# fetch path
|
||||
(?P<path>.+?)
|
||||
|
||||
# close path enclosure, conditional
|
||||
(?(quotes)(?P=quotes))
|
||||
|
||||
\s*
|
||||
# close url()
|
||||
\)
|
||||
/ix';
|
||||
|
||||
preg_match_all($regex, $this->content, $matches, PREG_SET_ORDER);
|
||||
if (!$matches) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($matches as $match) {
|
||||
$url = trim($match['path']);
|
||||
|
||||
if (substr($url, 0, 5) === 'data:') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$parsed_url = parse_url($url);
|
||||
|
||||
// Skip known host and protocol-relative paths.
|
||||
if (!empty($parsed_url['host']) || empty($parsed_url['path']) || $parsed_url['path'][0] === '/') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$new_url = $base_url . $url;
|
||||
|
||||
// URLs with quotes, #, brackets or characters above 0x7e should be quoted.
|
||||
// Restore original quotes.
|
||||
// Ref: https://developer.mozilla.org/en-US/docs/Web/CSS/url()#syntax
|
||||
if (preg_match('/[\s\)\'"#\x{7f}-\x{9f}]/u', $new_url)) {
|
||||
$new_url = $match['quotes'] . $new_url . $match['quotes'];
|
||||
}
|
||||
|
||||
$new_url = 'url(' . $new_url. ')';
|
||||
$this->content = str_replace($match[0], $new_url, $this->content);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the style is a google fonts URL.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function is_google_fonts()
|
||||
{
|
||||
return $this->is_google_fonts;
|
||||
}
|
||||
}
|
358
wp-content/plugins/debloat/inc/optimize-js/optimize-js.php
Normal file
@@ -0,0 +1,358 @@
|
||||
<?php
|
||||
|
||||
namespace Sphere\Debloat;
|
||||
use Sphere\Debloat\OptimizeJs\Script;
|
||||
|
||||
/**
|
||||
* JS Optimizations such as defer and delay.
|
||||
*
|
||||
* @author asadkn
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class OptimizeJs
|
||||
{
|
||||
protected $html;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $scripts = [];
|
||||
|
||||
/**
|
||||
* Include and exclude scripts for "delay".
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $include_scripts = [];
|
||||
protected $exclude_scripts = [];
|
||||
|
||||
/**
|
||||
* Exclude scripts from defer.
|
||||
*/
|
||||
protected $exclude_defer = [];
|
||||
|
||||
/**
|
||||
* Scripts already delayed or deffered.
|
||||
*/
|
||||
protected $done_delay = [];
|
||||
protected $done_defer = [];
|
||||
|
||||
/**
|
||||
* Scripts registered data from core.
|
||||
*/
|
||||
protected $enqueues = [];
|
||||
|
||||
public function __construct(string $html)
|
||||
{
|
||||
$this->html = $html;
|
||||
}
|
||||
|
||||
public function process()
|
||||
{
|
||||
$this->find_scripts();
|
||||
|
||||
// Figure out valid scripts.
|
||||
$this->setup_valid_scripts();
|
||||
|
||||
do_action('debloat/optimize_js_begin', $this);
|
||||
|
||||
// Early First pass to setup valid parents for child dependency checks.
|
||||
array_map(function($script) {
|
||||
$this->should_defer_script($script);
|
||||
}, $this->scripts);
|
||||
|
||||
/**
|
||||
* Setup scripts defer and delays and render the replacements.
|
||||
*/
|
||||
$has_delayed = false;
|
||||
foreach ($this->scripts as $script) {
|
||||
|
||||
// Has to be done for all scripts.
|
||||
if (Plugin::options()->minify_js) {
|
||||
$this->minify_js($script);
|
||||
$script->render = true;
|
||||
}
|
||||
|
||||
// Defer script if not already deferred.
|
||||
if ($this->should_defer_script($script)) {
|
||||
$script->defer = true;
|
||||
$script->render = true;
|
||||
|
||||
$has_delayed = true;
|
||||
}
|
||||
|
||||
// Should this script be delayed.
|
||||
if ($this->should_delay_script($script)) {
|
||||
$script->delay = true;
|
||||
$script->render = true;
|
||||
|
||||
$has_delayed = true;
|
||||
}
|
||||
else {
|
||||
Util\debug_log('Skipping: ' . print_r($script, true));
|
||||
}
|
||||
|
||||
if ($script->render) {
|
||||
$this->html = str_replace($script->orig_html, $script->render(), $this->html);
|
||||
}
|
||||
}
|
||||
|
||||
if ($has_delayed) {
|
||||
Plugin::delay_load()->enable(true);
|
||||
}
|
||||
|
||||
return $this->html;
|
||||
}
|
||||
|
||||
public function find_scripts()
|
||||
{
|
||||
/**
|
||||
* Collect all valid enqueues.
|
||||
*/
|
||||
$all_scripts = [];
|
||||
foreach (wp_scripts()->registered as $handle => $script) {
|
||||
|
||||
// Not an enqueued script, ignore.
|
||||
if (!in_array($handle, wp_scripts()->done)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Don't mutate original.
|
||||
$script = clone $script;
|
||||
|
||||
$script->deps = array_map(function($id) {
|
||||
// jQuery JS should be mapped to core. Add -js suffix for others.
|
||||
return $id === 'jquery' ? 'jquery-core-js' : $id . '-js';
|
||||
}, $script->deps);
|
||||
|
||||
// Add -js prefix to match the IDs that will retrieved from attrs.
|
||||
$handle .= '-js';
|
||||
$all_scripts[$handle] = $script;
|
||||
|
||||
// Pseudo entry for extras, adding a dependency.
|
||||
if (isset($script->extra['after'])) {
|
||||
$all_scripts[$handle . '-after'] = (object) [
|
||||
'deps' => [$handle]
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$this->enqueues = $all_scripts;
|
||||
|
||||
/**
|
||||
* Find all scripts.
|
||||
*/
|
||||
if (!preg_match_all('#<script.*?</script>#si', $this->html, $matches)) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($matches[0] as $script) {
|
||||
$script = Script::from_tag($script);
|
||||
if ($script) {
|
||||
$script->deps = $this->enqueues[$script->id]->deps ?? [];
|
||||
|
||||
// Note: There can be multiple scripts with same URL or id. So we don't use $script->id.
|
||||
$this->scripts[] = $script;
|
||||
|
||||
// Inline script has jQuery content? Ensure dependency.
|
||||
if (
|
||||
!$script->url &&
|
||||
!in_array('jquery-core-js', $script->deps) &&
|
||||
strpos($script->content, 'jQuery') !== false
|
||||
) {
|
||||
$script->deps[] = 'jquery-core-js';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the script has a parent dependency that is delayed/deferred.
|
||||
*
|
||||
* @param Script $script
|
||||
* @param array $valid
|
||||
* @return boolean
|
||||
*/
|
||||
public function check_dependency(Script $script, array $valid)
|
||||
{
|
||||
// Check if one of parent dependencies is delayed/deferred.
|
||||
foreach ((array) $script->deps as $dep) {
|
||||
if (isset($valid[$dep])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// For translations, if wp-i18n-js is valid, so should be translations.
|
||||
if (preg_match('/-js-translations/', $script->id, $matches)) {
|
||||
if (isset($valid['wp-i18n-js'])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Special case: Inline script with a parent dep. If parent is true, so is child.
|
||||
// Note: 'before' and 'extra' isn't accounted for and is not usually needed. Since 'extra' is
|
||||
// usually localization and 'before' has to happen before anyways.
|
||||
if (preg_match('/(.+?-js)-(before|after)/', $script->id, $matches)) {
|
||||
$handle = $matches[1];
|
||||
|
||||
// Parent was valid, so is the current child.
|
||||
if (isset($valid[$handle])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should the script be delayed using one of the JS delay methods.
|
||||
*
|
||||
* @param Script $script
|
||||
* @return boolean
|
||||
*/
|
||||
public function should_delay_script(Script $script)
|
||||
{
|
||||
if (!Plugin::options()->delay_js) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Excludes should be handled before includes and parents check.
|
||||
foreach ($this->exclude_scripts as $exclude) {
|
||||
if (Util\asset_match($exclude, $script, 'orig_html')) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Delay all.
|
||||
if (Plugin::options()->delay_js_all) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->check_dependency($script, $this->done_delay)) {
|
||||
$this->done_delay[$script->id] = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach ($this->include_scripts as $include) {
|
||||
if (Util\asset_match($include, $script, 'orig_html')) {
|
||||
$this->done_delay[$script->id] = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should the script be deferred.
|
||||
*
|
||||
* @param Script $script
|
||||
* @return boolean
|
||||
*/
|
||||
public function should_defer_script(Script $script)
|
||||
{
|
||||
// Defer not enabled.
|
||||
if (!Plugin::options()->defer_js) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($this->exclude_defer as $exclude) {
|
||||
if (Util\asset_match($exclude, $script, 'orig_html')) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// For inline scripts: By default not deferred, unless child of a deferred.
|
||||
if (!$script->url) {
|
||||
if (Plugin::options()->defer_js_inline) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->check_dependency($script, $this->done_defer)) {
|
||||
$this->done_defer[$script->id] = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// If defer or async attr already exists on original script.
|
||||
if ($script->defer || $script->async) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->done_defer[$script->id] = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup includes and excludes based on options.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setup_valid_scripts()
|
||||
{
|
||||
// Used by both delay and defer.
|
||||
$shared_excludes = [
|
||||
// Lazyloads should generally be loaded as early as possible and not deferred.
|
||||
'lazysizes.js',
|
||||
'lazyload.js',
|
||||
'lazysizes.min.js',
|
||||
'lazyLoadOptions',
|
||||
'lazyLoadThumb',
|
||||
];
|
||||
|
||||
/**
|
||||
* Defer scripts.
|
||||
*/
|
||||
$defer_excludes = array_merge(
|
||||
Util\option_to_array(Plugin::options()->defer_js_excludes),
|
||||
$shared_excludes
|
||||
);
|
||||
|
||||
$defer_excludes[] = 'id:-js-extra';
|
||||
$this->exclude_defer = apply_filters('debloat/defer_js_excludes', $defer_excludes);
|
||||
|
||||
/**
|
||||
* Delayed load scripts.
|
||||
*/
|
||||
$excludes = Util\option_to_array(Plugin::options()->delay_js_excludes);
|
||||
$excludes = array_merge($excludes, $shared_excludes, [
|
||||
// Jetpack stats.
|
||||
'url://stats.wp.com',
|
||||
'_stq.push',
|
||||
|
||||
// WPML browser redirect.
|
||||
'browser-redirect/app.js',
|
||||
|
||||
// Skip -js-extra as it's global variables and localization that shouldn't be delayed.
|
||||
'id:-js-extra'
|
||||
]);
|
||||
|
||||
$this->exclude_scripts = apply_filters('debloat/delay_js_excludes', $excludes);
|
||||
|
||||
$this->include_scripts = array_merge(
|
||||
$this->include_scripts,
|
||||
Util\option_to_array(Plugin::options()->delay_js_includes)
|
||||
);
|
||||
|
||||
// Enable delay adsense.
|
||||
if (Plugin::options()->delay_js_adsense) {
|
||||
$this->include_scripts[] = 'adsbygoogle.js';
|
||||
}
|
||||
|
||||
$this->include_scripts = apply_filters('debloat/delay_js_includes', $this->include_scripts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Minify the JS file, if possible.
|
||||
*
|
||||
* @param Script $script
|
||||
* @return void
|
||||
*/
|
||||
public function minify_js(Script $script)
|
||||
{
|
||||
$minifier = new Minifier($script);
|
||||
$minifier->process();
|
||||
}
|
||||
}
|
208
wp-content/plugins/debloat/inc/optimize-js/script.php
Normal file
@@ -0,0 +1,208 @@
|
||||
<?php
|
||||
|
||||
namespace Sphere\Debloat\OptimizeJs;
|
||||
|
||||
use Sphere\Debloat\Util;
|
||||
use Sphere\Debloat\Base\Asset;
|
||||
|
||||
/**
|
||||
* Class for handling scripts.
|
||||
*
|
||||
* @author asadkn
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Script extends Asset
|
||||
{
|
||||
public $defer = false;
|
||||
public $async = false;
|
||||
public $delay = false;
|
||||
|
||||
/**
|
||||
* Dependencies to mirror from core script.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $deps = [];
|
||||
|
||||
/**
|
||||
* Inner content for inline scripts
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $content = '';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $attrs = [];
|
||||
|
||||
/**
|
||||
* Original HTML tag.
|
||||
*/
|
||||
public $orig_html = '';
|
||||
|
||||
/**
|
||||
* Whether the script is dirty and needs rendering.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
public $render = false;
|
||||
|
||||
/**
|
||||
* @var callable|null
|
||||
*/
|
||||
protected $minifier;
|
||||
|
||||
public function __construct(string $id, string $url = '', string $orig_html = '')
|
||||
{
|
||||
$this->id = $id;
|
||||
$this->url = $url;
|
||||
$this->orig_url = $url;
|
||||
$this->orig_html = $orig_html;
|
||||
|
||||
if (!$this->id) {
|
||||
$this->id = md5($this->url ?: uniqid('debloat_script', true));
|
||||
}
|
||||
|
||||
// Has to be processed early as it might have to be searched for things like defer.
|
||||
$this->process_content();
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method: Create an instance provided an HTML tag.
|
||||
*
|
||||
* @param string $tag
|
||||
* @return boolean|self
|
||||
*/
|
||||
public static function from_tag(string $tag)
|
||||
{
|
||||
$attrs = Util\parse_attrs($tag);
|
||||
|
||||
// Only process scripts of type javascript or missing type (assumed JS by browser).
|
||||
if (isset($attrs['type']) && strpos($attrs['type'], 'javascript') === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$script = new self($attrs['id'] ?? '', $attrs['src'] ?? '', $tag);
|
||||
|
||||
// Note: We keep 'id' just in case if there was an original id.
|
||||
$script->attrs = \array_diff_key($attrs, array_flip(['src', 'defer', 'async']));
|
||||
|
||||
if (isset($attrs['defer'])) {
|
||||
$script->defer = true;
|
||||
}
|
||||
|
||||
if (isset($attrs['async'])) {
|
||||
$script->async = true;
|
||||
}
|
||||
|
||||
return $script;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the HTML.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
// Add src if available.
|
||||
if ($this->url) {
|
||||
$this->attrs += [
|
||||
'src' => $this->get_content_url(),
|
||||
'id' => $this->id,
|
||||
];
|
||||
}
|
||||
|
||||
$this->process_delay();
|
||||
|
||||
// Setting local to avoid mutating.
|
||||
$content = $this->content;
|
||||
|
||||
if (!$this->url && $content && is_callable($this->minifier)) {
|
||||
$content = call_user_func($this->minifier, $content);
|
||||
}
|
||||
|
||||
// Add defer for external scripts. For inline scripts, use data uri in src.
|
||||
if ($this->defer) {
|
||||
$this->attrs['defer'] = true;
|
||||
|
||||
if (!$this->url) {
|
||||
$this->attrs['src'] = 'data:text/javascript;base64,' . base64_encode($content);
|
||||
$content = '';
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->async) {
|
||||
$this->attrs['async'] = true;
|
||||
}
|
||||
|
||||
$render_atts = implode(' ', $this->render_attrs($this->attrs));
|
||||
$new_tag = sprintf(
|
||||
'<script%1$s>%2$s</script>',
|
||||
$render_atts ? " $render_atts" : '',
|
||||
!$this->url ? $content : ''
|
||||
);
|
||||
|
||||
return $new_tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the inner content, if any.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function process_content()
|
||||
{
|
||||
if (!$this->url) {
|
||||
$this->content = preg_replace('#<script[^>]*>(.+?)</script>\s*$#is', '\\1', $this->orig_html);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a callable minifier function.
|
||||
*
|
||||
* @param callable $minifier
|
||||
* @return void
|
||||
*/
|
||||
public function set_minifier($minifier)
|
||||
{
|
||||
$this->minifier = $minifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process and add delayed script attributes if needed.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function process_delay()
|
||||
{
|
||||
if (!$this->delay) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Defer / async shouldn't be enabled anymore. Delay load logic implies deferred anyways.
|
||||
$this->defer = false;
|
||||
$this->async = false;
|
||||
|
||||
// Add delay.
|
||||
$this->attrs['data-debloat-delay'] = 1;
|
||||
|
||||
// Normal script with a URL.
|
||||
if (!empty($this->attrs['src'])) {
|
||||
$this->attrs['data-src'] = $this->attrs['src'];
|
||||
}
|
||||
// Inline script with content.
|
||||
elseif ($this->content) {
|
||||
|
||||
if (!empty($this->attrs['type'])) {
|
||||
$this->attrs['data-type'] = $this->attrs['type'];
|
||||
}
|
||||
|
||||
$this->attrs['type'] = 'text/debloat-script';
|
||||
}
|
||||
|
||||
unset($this->attrs['src']);
|
||||
}
|
||||
|
||||
}
|
91
wp-content/plugins/debloat/inc/options.php
Normal file
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
namespace Sphere\Debloat;
|
||||
use Sphere\Debloat\Admin\OptionsData;
|
||||
|
||||
/**
|
||||
* A very basic options class.
|
||||
*
|
||||
* @author asadkn
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Options
|
||||
{
|
||||
/**
|
||||
* @var string|array Option key to use for get_options().
|
||||
*/
|
||||
public $option_key;
|
||||
public $_options;
|
||||
public $defaults = [];
|
||||
|
||||
/**
|
||||
* @param string|array $option_key
|
||||
*/
|
||||
public function __construct($option_key)
|
||||
{
|
||||
$this->option_key = $option_key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
$this->load_defaults();
|
||||
|
||||
if (is_array($this->option_key)) {
|
||||
$this->_options = [];
|
||||
|
||||
foreach ($this->option_key as $key) {
|
||||
$this->_options = array_merge($this->_options, (array) get_option($key));
|
||||
}
|
||||
|
||||
} else {
|
||||
$this->_options = (array) get_option($this->option_key);
|
||||
}
|
||||
|
||||
$this->_options = apply_filters('debloat/init_options', $this->_options);
|
||||
}
|
||||
|
||||
public function load_defaults()
|
||||
{
|
||||
if (!class_exists('Sphere\Debloat\Admin\OptionsData')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->defaults = array_reduce(
|
||||
OptionsData::get_all(),
|
||||
function($acc, $option) {
|
||||
$acc[$option['id']] = isset($option['default']) ? $option['default'] : '';
|
||||
return $acc;
|
||||
},
|
||||
[]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an option
|
||||
*/
|
||||
public function get($key, $fallback = '')
|
||||
{
|
||||
if (array_key_exists($key, $this->_options)) {
|
||||
return $this->_options[$key];
|
||||
}
|
||||
|
||||
if (array_key_exists($key, $this->defaults)) {
|
||||
return $this->defaults[$key];
|
||||
}
|
||||
|
||||
return $fallback;
|
||||
}
|
||||
|
||||
public function __get($key)
|
||||
{
|
||||
return $this->get($key);
|
||||
}
|
||||
|
||||
public function __set($key, $value)
|
||||
{
|
||||
$this->_options[$key] = $value;
|
||||
}
|
||||
}
|
219
wp-content/plugins/debloat/inc/plugin.php
Normal file
@@ -0,0 +1,219 @@
|
||||
<?php
|
||||
|
||||
namespace Sphere\Debloat;
|
||||
|
||||
/**
|
||||
* The Plugin Bootstrap and Setup.
|
||||
*
|
||||
* Dual acts as a container and a facade.
|
||||
*
|
||||
* @author asadkn
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @method static FileSystem file_system() Extends \WP_Filesystem_Base
|
||||
* @method static Process process()
|
||||
* @method static Options options()
|
||||
* @method static DelayLoad delay_load()
|
||||
* @method static FileCache file_cache()
|
||||
* @method static OptimizeCss\GoogleFonts google_fonts()
|
||||
*/
|
||||
class Plugin
|
||||
{
|
||||
/**
|
||||
* Plugin version
|
||||
*/
|
||||
const VERSION = '1.2.3';
|
||||
|
||||
public static $instance;
|
||||
|
||||
/**
|
||||
* @var string Can be 'dev' for debgging.
|
||||
*/
|
||||
public $env = 'production';
|
||||
|
||||
/**
|
||||
* Path to plugin folder, trailing slashed.
|
||||
*/
|
||||
public $dir_path;
|
||||
public $dir_url;
|
||||
|
||||
public $plugin_file;
|
||||
|
||||
/**
|
||||
* A pseudo service container
|
||||
*/
|
||||
public $container;
|
||||
|
||||
/**
|
||||
* Set it hooks on init.
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
$this->dir_path = plugin_dir_path($this->plugin_file);
|
||||
$this->dir_url = plugin_dir_url($this->plugin_file);
|
||||
|
||||
// Fire up the main autoloader.
|
||||
require_once $this->dir_path . 'inc/autoloader.php';
|
||||
new Autoloader([
|
||||
'Sphere\Debloat\\' => $this->dir_path . 'inc',
|
||||
]);
|
||||
|
||||
// Composer autoloader.
|
||||
require_once $this->dir_path . 'vendor/autoload.php';
|
||||
|
||||
/**
|
||||
* Setup and init common requires.
|
||||
*/
|
||||
// Options object with bound constructor args.
|
||||
$this->container['options'] = $this->shared(
|
||||
__NAMESPACE__ . '\Options',
|
||||
[
|
||||
['debloat_options', 'debloat_options_js', 'debloat_options_general']
|
||||
]
|
||||
);
|
||||
|
||||
// The process handler.
|
||||
$this->container['process'] = $this->shared(__NAMESPACE__ . '\Process');
|
||||
|
||||
// File system with lazy init singleton.
|
||||
$this->container['file_system'] = $this->shared(__NAMESPACE__ . '\FileSystem');
|
||||
|
||||
// Delay Load assets.
|
||||
$this->container['delay_load'] = $this->shared(__NAMESPACE__ . '\DelayLoad');
|
||||
|
||||
// File cache handler.
|
||||
$this->container['file_cache'] = $this->shared(__NAMESPACE__ . '\FileCache');
|
||||
|
||||
// Google Fonts is a singleton.
|
||||
$this->container['google_fonts'] = $this->shared(__NAMESPACE__ . '\OptimizeCss\GoogleFonts');
|
||||
|
||||
/**
|
||||
* Admin only requires
|
||||
*
|
||||
* We load these only on Admin side to keep things lean and performant.
|
||||
*
|
||||
* Note on CMB2:
|
||||
* It's used ONLY as an admin side dependency and never even
|
||||
* loaded on the frontend. Use native WP options API on front.
|
||||
*/
|
||||
if (is_admin() || defined('WP_CLI')) {
|
||||
|
||||
$admin = new Admin;
|
||||
$admin->init();
|
||||
|
||||
// We don't want CMB2 backend loaded at all in AJAX requests (admin-ajax.php passes is_admin() test)
|
||||
if (!wp_doing_ajax()) {
|
||||
require_once $this->dir_path . 'vendor/cmb2/init.php';
|
||||
}
|
||||
|
||||
// Path bug fix for cmb2 in composer
|
||||
add_filter('cmb2_meta_box_url', function() {
|
||||
return self::get_instance()->dir_url . 'vendor/cmb2';
|
||||
});
|
||||
|
||||
// WP-CLI commands.
|
||||
if (class_exists('\WP_CLI')) {
|
||||
\WP_CLI::add_command('debloat', '\Sphere\Debloat\WpCli\Commands');
|
||||
}
|
||||
}
|
||||
|
||||
// Utility functions.
|
||||
require_once $this->dir_path . 'inc/util.php';
|
||||
|
||||
$this->register_hooks();
|
||||
|
||||
// Load the options.
|
||||
self::options()->init();
|
||||
|
||||
// Init process to setup hooks.
|
||||
self::process()->init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a single instance class for container.
|
||||
*
|
||||
* @param string $class Fully-qualifed class name
|
||||
* @param array|null $args Bound args to pass to constructor
|
||||
*/
|
||||
public function shared($class, $args = null)
|
||||
{
|
||||
return function($fresh = false) use ($class, $args) {
|
||||
static $object;
|
||||
|
||||
if (!$object || $fresh) {
|
||||
|
||||
if (!$args) {
|
||||
$object = new $class;
|
||||
}
|
||||
else {
|
||||
$ref = new \ReflectionClass($class);
|
||||
$object = $ref->newInstanceArgs($args);
|
||||
}
|
||||
}
|
||||
|
||||
return $object;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup hooks actions.
|
||||
*/
|
||||
public function register_hooks()
|
||||
{
|
||||
// Translations
|
||||
add_action('plugins_loaded', array($this, 'load_textdomain'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup translations.
|
||||
*/
|
||||
public function load_textdomain()
|
||||
{
|
||||
load_plugin_textdomain(
|
||||
'debloat',
|
||||
false,
|
||||
basename($this->dir_path) . '/languages'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an object from container.
|
||||
*/
|
||||
public function get($name, $args = array())
|
||||
{
|
||||
if (!isset($this->container[$name])) {
|
||||
throw new \Exception("No container exists with key '{$name}'");
|
||||
}
|
||||
|
||||
$object = $this->container[$name];
|
||||
|
||||
if (is_callable($object)) {
|
||||
return call_user_func_array($object, $args);
|
||||
}
|
||||
else if (is_string($object)) {
|
||||
$object = new $object;
|
||||
}
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* @uses self::get()
|
||||
*/
|
||||
public static function __callStatic($name, $args = array())
|
||||
{
|
||||
return self::get_instance()->get($name, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public static function get_instance()
|
||||
{
|
||||
if (self::$instance == null) {
|
||||
self::$instance = new static();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
}
|
259
wp-content/plugins/debloat/inc/process.php
Normal file
@@ -0,0 +1,259 @@
|
||||
<?php
|
||||
|
||||
namespace Sphere\Debloat;
|
||||
|
||||
/**
|
||||
* Debloat processing setup for JS and CSS optimizations.
|
||||
*
|
||||
* @author asadkn
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Process
|
||||
{
|
||||
/**
|
||||
* Init happens too early around plugins_loaded
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
// Setup a few extra options.
|
||||
Plugin::options()->delay_css_type = 'interact';
|
||||
Plugin::options()->delay_js_type = 'interact';
|
||||
|
||||
// Setup at init but before template_redirect.
|
||||
add_action('init', [$this, 'setup']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup filters for processing
|
||||
*
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public function setup()
|
||||
{
|
||||
if ($this->should_process()) {
|
||||
|
||||
// Load integrations.
|
||||
$integrations = array_unique(array_merge(
|
||||
(array) Plugin::options()->integrations_js,
|
||||
(array) Plugin::options()->integrations_css
|
||||
));
|
||||
|
||||
if ($integrations) {
|
||||
if (in_array('elementor', $integrations) && class_exists('\Elementor\Plugin', false)) {
|
||||
new Integrations\Elementor;
|
||||
}
|
||||
|
||||
if (in_array('wpbakery', $integrations) && class_exists('Vc_Manager')) {
|
||||
new Integrations\Wpbakery;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process HTML for inline and local stylesheets.
|
||||
*
|
||||
* wp_ob_end_flush_all() will take care of flushing it.
|
||||
*
|
||||
* Note: Autoptimize starts at priority 2 so we use 3 to process BEFORE AO.
|
||||
*/
|
||||
add_action('template_redirect', function() {
|
||||
if (!apply_filters('debloat/should_process', true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Can't go in should_process() as that's too early.
|
||||
if (function_exists('\amp_is_request') && \amp_is_request()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Shouldn't process feeds, embeds (iframe), or robots.txt request.
|
||||
if (\is_feed() || \is_embed() || \is_robots()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ob_start([$this, 'process_markup']);
|
||||
}, -999);
|
||||
|
||||
// DEBUG: Devs if your output is disappearing - which you need for debugging,
|
||||
// uncomment below and comment the init action above.
|
||||
// add_action('template_redirect', function() { ob_start(); }, -999);
|
||||
// add_action('shutdown', function() {
|
||||
// $content = ob_get_clean();
|
||||
// echo $this->process_markup($content);
|
||||
// }, -10);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process DOM Markup provided with the html.
|
||||
*
|
||||
* @param string $html
|
||||
* @return string
|
||||
*/
|
||||
public function process_markup($html)
|
||||
{
|
||||
do_action('debloat/process_markup', $this);
|
||||
|
||||
if (!$this->is_valid_markup($html)) {
|
||||
return $html;
|
||||
}
|
||||
|
||||
$dom = null;
|
||||
|
||||
if ($this->should_optimize_css()) {
|
||||
$dom = $this->get_dom($html);
|
||||
$optimize = new OptimizeCss($dom, $html);
|
||||
$html = $optimize->process();
|
||||
}
|
||||
|
||||
if ($this->should_optimize_js()) {
|
||||
$optimize_js = new OptimizeJs($html);
|
||||
$html = $optimize_js->process();
|
||||
}
|
||||
|
||||
// Add delay load JS and extras as needed.
|
||||
$html = Plugin::delay_load()->render($html);
|
||||
|
||||
// Failed at processing DOM, return original.
|
||||
if (!$dom) {
|
||||
return $html;
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
public function is_valid_markup($html)
|
||||
{
|
||||
if (stripos($html, '<html') === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get DOM object for the provided HTML.
|
||||
*
|
||||
* @param string $html
|
||||
* @return boolean|\DOMDocument
|
||||
*/
|
||||
protected function get_dom($html)
|
||||
{
|
||||
if (!$html) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$libxml_previous = libxml_use_internal_errors(true);
|
||||
$dom = new \DOMDocument();
|
||||
$result = $dom->loadHTML($html);
|
||||
|
||||
libxml_clear_errors();
|
||||
libxml_use_internal_errors($libxml_previous);
|
||||
|
||||
// Deprecating xpath querying.
|
||||
// if ($result) {
|
||||
// $dom->xpath = new \DOMXPath($dom);
|
||||
// }
|
||||
|
||||
return $result ? $dom : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should any processing be done at all.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function should_process()
|
||||
{
|
||||
if (is_admin()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (function_exists('is_customize_preview') && is_customize_preview()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isset($_GET['nodebloat'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Util\is_elementor()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// WPBakery Page Builder. vc_is_page_editable() isn't reliable at all hooks.
|
||||
if (!empty($_GET['vc_editable'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Plugin::options()->disable_for_admins && current_user_can('manage_options')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should the JS be optimized.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function should_optimize_js()
|
||||
{
|
||||
$valid = true;
|
||||
return apply_filters('debloat/should_optimize_js', $valid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Should the CSS be optimized.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function should_optimize_css()
|
||||
{
|
||||
$valid = Plugin::options()->remove_css || Plugin::options()->optimize_css;
|
||||
return apply_filters('debloat/should_optimize_css', $valid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Conditions test to see if current page matches in the provided valid conditions.
|
||||
*
|
||||
* @param array $enable_on
|
||||
* @return boolean
|
||||
*/
|
||||
public function check_enabled(array $enable_on)
|
||||
{
|
||||
if (in_array('all', $enable_on)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$conditions = [
|
||||
'pages' => 'is_page',
|
||||
'posts' => 'is_single',
|
||||
'archives' => 'is_archive',
|
||||
'archive' => 'is_archive', // Alias
|
||||
'categories' => 'is_category',
|
||||
'tags' => 'is_tag',
|
||||
'search' => 'is_search',
|
||||
'404' => 'is_404',
|
||||
'home' => function() {
|
||||
return is_home() || is_front_page();
|
||||
},
|
||||
];
|
||||
|
||||
$satisfy = false;
|
||||
foreach ($enable_on as $key) {
|
||||
if (!isset($conditions[$key]) || !is_callable($conditions[$key])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$satisfy = call_user_func($conditions[$key]);
|
||||
|
||||
// Stop going further in loop once satisfied.
|
||||
if ($satisfy) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $satisfy;
|
||||
}
|
||||
}
|
388
wp-content/plugins/debloat/inc/remove-css/remove-css.php
Normal file
@@ -0,0 +1,388 @@
|
||||
<?php
|
||||
|
||||
namespace Sphere\Debloat;
|
||||
use Sphere\Debloat\RemoveCss\Sanitizer;
|
||||
use Sphere\Debloat\OptimizeCss\Stylesheet;
|
||||
|
||||
/**
|
||||
* Process stylesheets to debloat and optimize CSS.
|
||||
*
|
||||
* @author asadkn
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class RemoveCss
|
||||
{
|
||||
/**
|
||||
* @var \DOMDocument
|
||||
*/
|
||||
public $dom;
|
||||
public $html;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $used_markup = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $stylesheets;
|
||||
|
||||
protected $include_sheets = [];
|
||||
protected $exclude_sheets = [];
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @param Stylesheet[] $stylesheets
|
||||
* @param \DOMDocument $dom
|
||||
* @param string $raw_html
|
||||
*/
|
||||
public function __construct($stylesheets, \DOMDocument $dom, string $raw_html)
|
||||
{
|
||||
$this->stylesheets = $stylesheets;
|
||||
$this->dom = $dom;
|
||||
$this->html = $raw_html;
|
||||
}
|
||||
|
||||
public function process()
|
||||
{
|
||||
// Collect all the classes, ids, tags used in DOM.
|
||||
$this->find_used_selectors();
|
||||
|
||||
// Figure out valid sheets.
|
||||
$this->setup_valid_sheets();
|
||||
|
||||
/**
|
||||
* Process and replace stylesheets with CSS cleaned.
|
||||
*/
|
||||
do_action('debloat/remove_css_begin', $this);
|
||||
$allow_selectors = $this->get_allowed_selectors();
|
||||
|
||||
foreach ($this->stylesheets as $sheet) {
|
||||
if (!$this->should_process_stylesheet($sheet)) {
|
||||
// Util\debug_log('Skipping: ' . print_r($sheet, true));
|
||||
continue;
|
||||
}
|
||||
|
||||
// Perhaps not a local file or unreadable.
|
||||
$file_data = $this->process_file_by_url($sheet->url);
|
||||
if (!$file_data) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$sheet->content = $file_data['content'];
|
||||
$sheet->file = $file_data['file'];
|
||||
|
||||
// Parsed sheet will be cached instead of being parsed by Sabberworm again.
|
||||
$this->setup_sheet_cache($sheet);
|
||||
|
||||
/**
|
||||
* Fire up sanitizer to process and remove unused CSS.
|
||||
*/
|
||||
$sanitizer = new Sanitizer($sheet, $this->used_markup, $allow_selectors);
|
||||
$sanitized_css = $sanitizer->sanitize();
|
||||
|
||||
// Store sizes for debug info.
|
||||
$sheet->original_size = strlen($sheet->content);
|
||||
$sheet->new_size = $sanitized_css ? strlen($sanitized_css) : $sheet->original_size;
|
||||
|
||||
if ($sanitized_css) {
|
||||
|
||||
// Pre-render as we'll have to add a delayed css tag as well, if enabled.
|
||||
$sheet->content = $sanitized_css;
|
||||
$sheet->render_id = 'debloat-' . $sheet->id;
|
||||
$sheet->set_render('inline');
|
||||
$replacement = $sheet->render();
|
||||
|
||||
// Add tags for delayed CSS files.
|
||||
if (Plugin::delay_load()->should_delay_css()) {
|
||||
|
||||
$sheet->delay_type = Plugin::options()->delay_css_type;
|
||||
$sheet->set_render('delay');
|
||||
$sheet->has_delay = true;
|
||||
|
||||
// Add the delay load CSS tag in addition to inlined sanitized CSS above.
|
||||
$replacement .= $sheet->render();
|
||||
}
|
||||
|
||||
$sheet->set_render('remove_css', $replacement);
|
||||
|
||||
// Save in parsed css cache if not already saved.
|
||||
$this->save_sheet_cache($sheet);
|
||||
}
|
||||
|
||||
// Free up memory.
|
||||
$sheet->content = '';
|
||||
$sheet->parsed_data = '';
|
||||
}
|
||||
|
||||
// $this->stylesheets = array_map(function($sheet) {
|
||||
// if (isset($sheet->original_size)) {
|
||||
// $sheet->saved = $sheet->original_size - $sheet->new_size;
|
||||
// }
|
||||
// return $sheet;
|
||||
// }, $this->stylesheets);
|
||||
|
||||
$total = array_reduce($this->stylesheets, function($acc, $item) {
|
||||
if (!empty($item->original_size)) {
|
||||
$acc += ($item->original_size - $item->new_size);
|
||||
}
|
||||
return $acc;
|
||||
}, 0);
|
||||
|
||||
$this->html .= "\n<!-- Debloat Remove CSS Saved: {$total} bytes. -->";
|
||||
|
||||
return $this->html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add parsed data cache to stylesheet object. Will be used by save_sheet_cache later.
|
||||
*
|
||||
* @param Stylesheet $sheet
|
||||
* @return void
|
||||
*/
|
||||
public function setup_sheet_cache(Stylesheet $sheet)
|
||||
{
|
||||
if (!isset($sheet->file)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$cache = get_transient($this->get_transient_id($sheet));
|
||||
if ($cache && $cache['mtime'] < Plugin::file_system()->mtime($sheet->file)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($cache && !empty($cache['data'])) {
|
||||
$sheet->parsed_data = $cache['data'];
|
||||
$sheet->has_cache = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
protected function get_transient_id($sheet)
|
||||
{
|
||||
return substr('debloat_sheet_cache_' . $sheet->id, 0, 190);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cache the parsed data.
|
||||
*
|
||||
* Note: This doesn't cache whole CSS as that would vary based on found selectors.
|
||||
*
|
||||
* @param Stylesheet $sheet
|
||||
* @return void
|
||||
*/
|
||||
public function save_sheet_cache(Stylesheet $sheet)
|
||||
{
|
||||
if ($sheet->has_cache) {
|
||||
return;
|
||||
}
|
||||
|
||||
$cache_data = [
|
||||
'data' => $sheet->parsed_data,
|
||||
'mtime' => Plugin::file_system()->mtime($sheet->file)
|
||||
];
|
||||
|
||||
// With expiry; won't be auto-loaded.
|
||||
set_transient($this->get_transient_id($sheet), $cache_data, MONTH_IN_SECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup includes and excludes based on options.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setup_valid_sheets()
|
||||
{
|
||||
$default_excludes = [
|
||||
'wp-includes/css/dashicons.css',
|
||||
'admin-bar.css',
|
||||
'wp-mediaelement'
|
||||
];
|
||||
|
||||
$excludes = array_merge(
|
||||
$default_excludes,
|
||||
Util\option_to_array(Plugin::options()->remove_css_excludes)
|
||||
);
|
||||
|
||||
$this->exclude_sheets = apply_filters('debloat/remove_css_excludes', $excludes, $this);
|
||||
|
||||
if (Plugin::options()->remove_css_all) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Plugin::options()->remove_css_theme) {
|
||||
$this->include_sheets[] = content_url('themes') . '/*';
|
||||
}
|
||||
|
||||
if (Plugin::options()->remove_css_plugins) {
|
||||
$this->include_sheets[] = content_url('plugins') . '/*';
|
||||
}
|
||||
|
||||
$this->include_sheets = array_merge(
|
||||
$this->include_sheets,
|
||||
Util\option_to_array(Plugin::options()->remove_css_includes)
|
||||
);
|
||||
|
||||
$this->include_sheets = apply_filters('debloat/remove_css_includes', $this->include_sheets, $this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if stylesheet should be processed, based on exclusion and inclusion
|
||||
* rules and settings.
|
||||
*
|
||||
* @param Stylesheet $sheet
|
||||
* @return boolean
|
||||
*/
|
||||
public function should_process_stylesheet(Stylesheet $sheet)
|
||||
{
|
||||
// Handle manual excludes first.
|
||||
if ($this->exclude_sheets) {
|
||||
foreach ($this->exclude_sheets as $exclude) {
|
||||
if (Util\asset_match($exclude, $sheet)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// All stylesheets are valid.
|
||||
if (Plugin::options()->remove_css_all) {
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach ($this->include_sheets as $include) {
|
||||
if (Util\asset_match($include, $sheet)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the allowed selectors in correct data format to be used by sanitizer.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_allowed_selectors()
|
||||
{
|
||||
// Allowed selectors of type 'any': simple match in selector string.
|
||||
$allowed_any = array_map(
|
||||
function($value) {
|
||||
if (!$value) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return [
|
||||
'type' => 'any',
|
||||
'search' => [$value]
|
||||
];
|
||||
},
|
||||
Util\option_to_array((string) Plugin::options()->allow_css_selectors)
|
||||
);
|
||||
|
||||
// Conditional selectors.
|
||||
$allowed_conditionals = [];
|
||||
$conditionals = Plugin::options()->allow_css_conditionals
|
||||
? (array) Plugin::options()->allow_conditionals_data
|
||||
: [];
|
||||
|
||||
if ($conditionals) {
|
||||
$allowed_conditionals = array_map(
|
||||
function($value) {
|
||||
if (!isset($value['match'])) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$value['class'] = preg_replace('/^\./', '', trim($value['match']));
|
||||
|
||||
if ($value['type'] !== 'prefix' && isset($value['selectors'])) {
|
||||
$value['search'] = Util\option_to_array($value['selectors']);
|
||||
}
|
||||
|
||||
return $value;
|
||||
},
|
||||
$conditionals
|
||||
);
|
||||
}
|
||||
|
||||
$allowed = apply_filters(
|
||||
'debloat/allow_css_selectors',
|
||||
array_filter(array_merge($allowed_any, $allowed_conditionals)),
|
||||
$this
|
||||
);
|
||||
|
||||
return $allowed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all the classes, ids, and tags used in the document.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function find_used_selectors()
|
||||
{
|
||||
$this->used_markup = [
|
||||
'tags' => [],
|
||||
'classes' => [],
|
||||
'ids' => [],
|
||||
];
|
||||
|
||||
/**
|
||||
* @var DOMElement $node
|
||||
*/
|
||||
$classes = [];
|
||||
foreach ($this->dom->getElementsByTagName('*') as $node) {
|
||||
$this->used_markup['tags'][ $node->tagName ] = 1;
|
||||
|
||||
// Collect tag classes.
|
||||
if ($node->hasAttribute('class')) {
|
||||
$class = $node->getAttribute('class');
|
||||
$ele_classes = preg_split('/\s+/', $class);
|
||||
array_push($classes, ...$ele_classes);
|
||||
}
|
||||
|
||||
if ($node->hasAttribute('id')) {
|
||||
$this->used_markup['ids'][ $node->getAttribute('id') ] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Add the classes.
|
||||
$classes = array_filter(array_unique($classes));
|
||||
if ($classes) {
|
||||
$this->used_markup['classes'] = array_fill_keys($classes, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a stylesheet via URL
|
||||
*
|
||||
* @uses Plugin::file_system()
|
||||
* @uses Plugin::file_system()->url_to_local()
|
||||
* @return boolean|array With 'content' and 'file'.
|
||||
*/
|
||||
public function process_file_by_url($url)
|
||||
{
|
||||
// Try to get local path for this stylesheet
|
||||
$file = Plugin::file_system()->url_to_local($url);
|
||||
if (!$file) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We can only support .css files yet
|
||||
if (substr($file, -4) !== '.css') {
|
||||
return false;
|
||||
}
|
||||
|
||||
$content = Plugin::file_system()->get_contents($file);
|
||||
if (!$content) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return [
|
||||
'content' => $content,
|
||||
'file' => $file
|
||||
];
|
||||
}
|
||||
}
|
529
wp-content/plugins/debloat/inc/remove-css/sanitizer.php
Normal file
@@ -0,0 +1,529 @@
|
||||
<?php
|
||||
|
||||
namespace Sphere\Debloat\RemoveCss;
|
||||
|
||||
use Sabberworm\CSS\CSSList\AtRuleBlockList;
|
||||
use Sabberworm\CSS\CSSList\CSSBlockList;
|
||||
use Sabberworm\CSS\CSSList\Document;
|
||||
use Sabberworm\CSS\OutputFormat;
|
||||
use Sabberworm\CSS\Parser as CSSParser;
|
||||
use Sabberworm\CSS\RuleSet\DeclarationBlock;
|
||||
use Sabberworm\CSS\Settings;
|
||||
use Sabberworm\CSS\Value\URL;
|
||||
|
||||
use Sphere\Debloat\OptimizeCss\Stylesheet;
|
||||
use Sphere\Debloat\Util;
|
||||
|
||||
/**
|
||||
* Sanitizer removes the unnecessary CSS, provided a stylesheet.
|
||||
*
|
||||
* @author asadkn
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Sanitizer
|
||||
{
|
||||
/**
|
||||
* @var Stylesheet
|
||||
*/
|
||||
protected $sheet;
|
||||
|
||||
protected $css;
|
||||
protected $used_markup = [
|
||||
'classes' => [],
|
||||
'tags' => [],
|
||||
'ids' => []
|
||||
];
|
||||
|
||||
protected $allow_selectors = [];
|
||||
|
||||
/**
|
||||
* @param Stylesheet $sheet
|
||||
* @param array $used_markup {
|
||||
* @type array $classes
|
||||
* @type array $tags
|
||||
* @type array $ids
|
||||
* }
|
||||
*/
|
||||
public function __construct(Stylesheet $sheet, array $used_markup, $allow = [])
|
||||
{
|
||||
$this->sheet = $sheet;
|
||||
$this->css = $sheet->content;
|
||||
$this->used_markup = array_replace($this->used_markup, $used_markup);
|
||||
|
||||
$this->allow_selectors = $allow;
|
||||
|
||||
}
|
||||
|
||||
public function set_cache($data)
|
||||
{
|
||||
$this->cache = $data;
|
||||
}
|
||||
|
||||
public function sanitize()
|
||||
{
|
||||
$data = $this->sheet->parsed_data ?: [];
|
||||
if (!$data) {
|
||||
|
||||
// Strip the dreaded UTF-8 byte order mark (BOM, \uFEFF). Ref: https://github.com/sabberworm/PHP-CSS-Parser/issues/150
|
||||
$this->css = preg_replace('/^\xEF\xBB\xBF/', '', $this->css);
|
||||
|
||||
$config = Settings::create()->withMultibyteSupport(false);
|
||||
$parser = new CSSParser($this->css, $config);
|
||||
$parsed = $parser->parse();
|
||||
|
||||
// Fix relative URLs.
|
||||
$this->convert_urls($parsed);
|
||||
$data = $this->transform_data($parsed);
|
||||
|
||||
$this->sheet->parsed_data = $data;
|
||||
}
|
||||
|
||||
$this->process_allowed_selectors();
|
||||
|
||||
return $this->render_css($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert relative URLs to full URLs for inline inclusion or changed paths.
|
||||
*
|
||||
* @param Document $data
|
||||
* @return void
|
||||
*/
|
||||
public function convert_urls(Document $data)
|
||||
{
|
||||
$base_url = preg_replace('#[^/]+\?.*$#', '', $this->sheet->url);
|
||||
|
||||
$values = $data->getAllValues();
|
||||
foreach ($values as $value) {
|
||||
if (!($value instanceof URL)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$url = $value->getURL()->getString();
|
||||
// if (substr($url, 0, 5) === 'data:') {
|
||||
// continue;
|
||||
// }
|
||||
if (preg_match('/^(https?|data):/', $url)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$parsed_url = parse_url($url);
|
||||
|
||||
// Skip known host and protocol-relative paths.
|
||||
if (!empty($parsed_url['host']) || empty($parsed_url['path']) || $parsed_url['path'][0] === '/') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$new_url = $base_url . $url;
|
||||
$value->getUrl()->setString($new_url);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform data structure to store in our format. This data will be used without
|
||||
* loading CSS Parser on further requests.
|
||||
*
|
||||
* @param CSSBlockList $data
|
||||
* @return array
|
||||
*/
|
||||
public function transform_data(CSSBlockList $data)
|
||||
{
|
||||
$items = [];
|
||||
foreach ($data->getContents() as $content) {
|
||||
if ($content instanceof AtRuleBlockList) {
|
||||
$items[] = [
|
||||
'rulesets' => $this->transform_data($content),
|
||||
'at_rule' => "@{$content->atRuleName()} {$content->atRuleArgs()}",
|
||||
];
|
||||
}
|
||||
else {
|
||||
$item = [
|
||||
//'css' => $content->render(OutputFormat::createPretty())
|
||||
'css' => $content->render(OutputFormat::createCompact())
|
||||
];
|
||||
|
||||
if ($content instanceof DeclarationBlock) {
|
||||
$item['selectors'] = $this->parse_selectors($content->getSelectors());
|
||||
}
|
||||
|
||||
$items[] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse selectors to get classes, id, tags and attrs.
|
||||
*
|
||||
* @param array $selectors
|
||||
* @return array
|
||||
*/
|
||||
protected function parse_selectors($selectors)
|
||||
{
|
||||
$selectors = array_map(
|
||||
function($sel) {
|
||||
return $sel->__toString();
|
||||
},
|
||||
$selectors
|
||||
);
|
||||
|
||||
$selectors_data = [];
|
||||
foreach ($selectors as $selector) {
|
||||
$data = [
|
||||
'classes' => [],
|
||||
'ids' => [],
|
||||
'tags' => [],
|
||||
// 'pseudo' => [],
|
||||
'attrs' => [],
|
||||
'selector' => trim($selector),
|
||||
];
|
||||
|
||||
// if (strpos($selector, ':root') !== false) {
|
||||
// $data['pseudo'][':root'] = 1;
|
||||
// }
|
||||
|
||||
// Based on AMP plugin.
|
||||
// Handle :not() and pseudo selectors to eliminate false negatives.
|
||||
$selector = preg_replace('/(?<!\\\\)::?[a-zA-Z0-9_-]+(\(.+?\))?/', '', $selector);
|
||||
|
||||
// Get attributes but remove them from the selector to prevent false positives
|
||||
// from within attribute selector.
|
||||
$selector = preg_replace_callback(
|
||||
'/\[([A-Za-z0-9_:-]+)(\W?=[^\]]+)?\]/',
|
||||
function($matches) use (&$data) {
|
||||
$data['attrs'][] = $matches[1];
|
||||
return '';
|
||||
},
|
||||
$selector
|
||||
);
|
||||
|
||||
// Extract class names.
|
||||
$selector = preg_replace_callback(
|
||||
// The `\\\\.` will allow any char via escaping, like the colon in `.lg\:w-full`.
|
||||
'/\.((?:[a-zA-Z0-9_-]+|\\\\.)+)/',
|
||||
function($matches) use (&$data) {
|
||||
$data['classes'][] = stripslashes($matches[1]);
|
||||
return '';
|
||||
},
|
||||
$selector
|
||||
);
|
||||
|
||||
// Extract IDs.
|
||||
$selector = preg_replace_callback(
|
||||
'/#([a-zA-Z0-9_-]+)/',
|
||||
function( $matches ) use (&$data) {
|
||||
$data['ids'][] = $matches[1];
|
||||
return '';
|
||||
},
|
||||
$selector
|
||||
);
|
||||
|
||||
// Extract tag names.
|
||||
$selector = preg_replace_callback(
|
||||
'/[a-zA-Z0-9_-]+/',
|
||||
function($matches) use (&$data) {
|
||||
$data['tags'][] = $matches[0];
|
||||
return '';
|
||||
},
|
||||
$selector
|
||||
);
|
||||
|
||||
$selectors_data[] = array_filter($data);
|
||||
}
|
||||
|
||||
return array_filter($selectors_data);
|
||||
}
|
||||
|
||||
public function render_css($data)
|
||||
{
|
||||
$rendered = [];
|
||||
foreach ($data as $item) {
|
||||
|
||||
// Has CSS.
|
||||
if (isset($item['css'])) {
|
||||
$css = $item['css'];
|
||||
|
||||
// Render only if at least one selector meets the should_include criteria.
|
||||
$should_render = !isset($item['selectors']) ||
|
||||
0 !== count(
|
||||
array_filter(
|
||||
$item['selectors'],
|
||||
function($selector) {
|
||||
return $this->should_include($selector);
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
if ($should_render) {
|
||||
$rendered[] = $css;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Nested ruleset.
|
||||
if (!empty($item['rulesets'])) {
|
||||
$child_rulesets = $this->render_css($item['rulesets']);
|
||||
|
||||
if ($child_rulesets) {
|
||||
$rendered[] = sprintf(
|
||||
'%s { %s }',
|
||||
$item['at_rule'],
|
||||
$child_rulesets
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return implode("", $rendered);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pre-process allowed selectors.
|
||||
*
|
||||
* Convert data structures in proper format, mainly for performance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function process_allowed_selectors()
|
||||
{
|
||||
foreach ($this->allow_selectors as $key => $value) {
|
||||
|
||||
// Check if selector rule valid for current sheet.
|
||||
if (isset($value['sheet']) && !Util\asset_match($value['sheet'], $this->sheet)) {
|
||||
unset($this->allow_selectors[$key]);
|
||||
continue;
|
||||
}
|
||||
|
||||
$value = $this->add_search_regex($value);
|
||||
$regex = $value['search_regex'] ?? '';
|
||||
|
||||
// Pre-compute the matching regex for performance.
|
||||
if (isset($value['search'])) {
|
||||
$value['search'] = array_filter((array) $value['search']);
|
||||
|
||||
// If we still have something.
|
||||
if ($value['search']) {
|
||||
$loose_regex = '(' . implode('|', array_map('preg_quote', $value['search'])) . ')(?=\s|\.|\:|,|\[|$)';
|
||||
|
||||
// Combine with search_regex if available.
|
||||
$regex = $regex ? "($loose_regex|$regex)" : $loose_regex;
|
||||
}
|
||||
}
|
||||
|
||||
if ($regex) {
|
||||
$value['computed_search_regex'] = $regex;
|
||||
}
|
||||
|
||||
$this->allow_selectors[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add search regex to array by converting astrisks to proper regex search.
|
||||
*
|
||||
* @param array $value
|
||||
* @return array
|
||||
*/
|
||||
protected function add_search_regex(array $value)
|
||||
{
|
||||
if (isset($value['search_regex'])) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
if (isset($value['search'])) {
|
||||
|
||||
$value['search'] = (array) $value['search'];
|
||||
$regex = [];
|
||||
|
||||
foreach ($value['search'] as $key => $search) {
|
||||
if (strpos($search, '*') !== false) {
|
||||
$search = trim($search);
|
||||
|
||||
// Optimize regex for starting.
|
||||
// Note: Ending asterisk removal isn't necessary. PCRE engine is optimized for that.
|
||||
$has_first_asterisk = 0;
|
||||
$search = preg_replace('/^\*(.+?)/', '\\1', $search, 1, $has_first_asterisk);
|
||||
|
||||
// 1. Space and asterisk matches a class itself, followed by space (child), or comma separator.
|
||||
// 2. Only asterisk is considered more of a prefix/suffix and .class* will match .classname too.
|
||||
$search = preg_quote($search);
|
||||
$search = str_replace(' \*', '(\s|$|,|\:).*?', $search);
|
||||
$search = str_replace('\*', '.*?', $search);
|
||||
|
||||
// Note: To prevent ^(.*?) which is slow, we add starting position match only
|
||||
// if the search doesn't start with asterisk match.
|
||||
$regex[] = ($has_first_asterisk ? '' : '^') . $search;
|
||||
|
||||
unset($value['search'][$key]);
|
||||
}
|
||||
}
|
||||
|
||||
if ($regex) {
|
||||
$value['search_regex'] = '(' . implode('|', $regex) . ')';
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Whether to include a selector in the output.
|
||||
*
|
||||
* @param array $selector {
|
||||
* @type string[]|null $classes
|
||||
* @type string[]|null $ids
|
||||
* @type string[]|null $tags
|
||||
* }
|
||||
* @return boolean
|
||||
*/
|
||||
public function should_include($selector)
|
||||
{
|
||||
// :root is always valid.
|
||||
// Note: Selectors of type `:root .class` will not match this but will be validated below
|
||||
// if .class is used, as intended.
|
||||
if ($selector['selector'] === ':root') {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If it's an attribute selector with nothing else, it should be kept. Perhaps *[attr] or [attr].
|
||||
if (!empty($selector['attrs'])
|
||||
&& (empty($selector['classes']) && empty($selector['ids']) && empty($selector['tags']))
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check allow list.
|
||||
// @todo move to cached pre-processed. Clear on settings change.
|
||||
|
||||
// $this->allow_selectors = [
|
||||
// [
|
||||
// 'type' => 'any',
|
||||
// 'search' => '.auth-modal',
|
||||
// ],
|
||||
// [
|
||||
// 'type' => 'prefix',
|
||||
// 'class' => 's-dark'
|
||||
// ],
|
||||
// [
|
||||
// 'type' => 'class',
|
||||
// 'class' => 'has-lb',
|
||||
// 'search' => ['.mfp-']
|
||||
// ],
|
||||
// [
|
||||
// 'type' => 'any',
|
||||
// 'class' => 'has-lb',
|
||||
// 'search' => ['.mfp-']
|
||||
// ],
|
||||
// ];
|
||||
|
||||
if ($this->allow_selectors) {
|
||||
foreach ($this->allow_selectors as $include) {
|
||||
|
||||
/**
|
||||
* Prefix-based + all other classes/tags/etc. in selector exist in doc.
|
||||
*
|
||||
* Note: It's basically to ignore the first class and include the sub-classes based
|
||||
* on their existence in doc. Example: .scheme-dark or .scheme-light.
|
||||
*/
|
||||
if ($include['type'] === 'prefix') {
|
||||
|
||||
// Check if exact match.
|
||||
if (('.' . $include['class']) === $selector['selector']) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if first class matches.
|
||||
$has_prefix = $include['class'] === substr($selector['selector'], 1, strlen($include['class']));
|
||||
if ($has_prefix) {
|
||||
|
||||
// Will check for validity later below. Remove first class as it's allowed.
|
||||
if (isset($selector['classes'])) {
|
||||
$selector['classes'] = array_diff($selector['classes'], [$include['class']]);
|
||||
}
|
||||
|
||||
// WARNING: Due to this break, if there's a rule to allow all selectors of this prefix
|
||||
// that appear later, it won't be validated.
|
||||
// @todo Sort prefixes to be at the end or run them later.
|
||||
break;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if a class exists in document.
|
||||
if ($include['type'] === 'class') {
|
||||
if (!$this->is_used($include['class'], 'classes')) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Simple search selector string.
|
||||
// $search = !empty($include['search']) ? (array) $include['search'] : [];
|
||||
|
||||
// Any type, normal selector string match.
|
||||
// Note: The regex is equal at n=1 and faster at n>1, surprisingly.
|
||||
// if ($search) {
|
||||
// foreach ($search as $to_match) {
|
||||
// if (strpos($selector['selector'], $to_match) !== false) {
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// Pre-computed regex - combined 'search' and 'search_regex'.
|
||||
if (!empty($include['computed_search_regex'])) {
|
||||
if (preg_match('#' . $include['computed_search_regex'] . '#', $selector['selector'])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$valid = true;
|
||||
if (
|
||||
// Check if all classes are used.
|
||||
(!empty($selector['classes']) && !$this->is_used($selector['classes'], 'classes'))
|
||||
|
||||
// Check if all the ids are used.
|
||||
|| (!empty($selector['ids']) && !$this->is_used($selector['ids'], 'ids'))
|
||||
|
||||
// Check for the target tags in used.
|
||||
|| (!empty($selector['tags']) && !$this->is_used($selector['tags'], 'tags'))
|
||||
) {
|
||||
$valid = false;
|
||||
}
|
||||
|
||||
return $valid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if a selector classes, ids, or tags are used in the doc (provided in $this->used_markup).
|
||||
*
|
||||
* @param string|array $targets
|
||||
* @param string $type 'classes', 'tags', or 'ids'.
|
||||
* @return boolean
|
||||
*/
|
||||
public function is_used($targets, $type = '')
|
||||
{
|
||||
if (!$type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!is_array($targets)) {
|
||||
$targets = (array) $targets;
|
||||
}
|
||||
|
||||
foreach ($targets as $target) {
|
||||
// All targets must exist.
|
||||
if (!isset($this->used_markup[$type][$target])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
126
wp-content/plugins/debloat/inc/util.php
Normal file
@@ -0,0 +1,126 @@
|
||||
<?php
|
||||
|
||||
namespace Sphere\Debloat\Util;
|
||||
use Sphere\Debloat\Plugin;
|
||||
|
||||
/**
|
||||
* Convert an option value to array format, and clean it.
|
||||
*
|
||||
* @param string|array $value
|
||||
* @return array
|
||||
*/
|
||||
function option_to_array($value, $separator = "\n")
|
||||
{
|
||||
$value = $value ?: [];
|
||||
|
||||
if (is_string($value)) {
|
||||
$value = array_map('trim', explode($separator, $value));
|
||||
}
|
||||
|
||||
if (!is_array($value)) {
|
||||
throw new \Exception('A string or array is expected.');
|
||||
}
|
||||
|
||||
$value = array_filter($value);
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get attributes given an HTML tag.
|
||||
*
|
||||
* @param string $tag
|
||||
* @return array
|
||||
*/
|
||||
function parse_attrs($tag)
|
||||
{
|
||||
// Should be a valid html tag with attributes.
|
||||
preg_match('#<\w+\s*([^>]*)/?>#', $tag, $match);
|
||||
if (!$match) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$attr_string = $match[1];
|
||||
|
||||
$regex = '(?P<keys>[_a-zA-Z][-\w:.]*)'
|
||||
. '(?:' // Attribute value.
|
||||
. '\s*=\s*' // All values begin with '='.
|
||||
. '(?:'
|
||||
. '"([^"]*)"' // Double-quoted.
|
||||
. '|'
|
||||
. "'([^']*)'" // Single-quoted.
|
||||
. '|'
|
||||
. '([^\s"\']+)' // Non-quoted.
|
||||
. '(?:\s|$)' // Must have a space.
|
||||
. ')'
|
||||
. '|'
|
||||
. '(?:\s|$)' // If attribute has no value, space is required.
|
||||
. ')';
|
||||
|
||||
preg_match_all('#' . $regex . '#i', $attr_string, $matches);
|
||||
|
||||
$attrs = [];
|
||||
foreach ((array) $matches['keys'] as $i => $key) {
|
||||
|
||||
// Any of the capturing groups for double-quoted, single-quoted or non-quoted.
|
||||
$value = $matches[2][$i] ?: $matches[3][$i] ?: $matches[4][$i];
|
||||
$attrs[$key] = $value;
|
||||
}
|
||||
|
||||
return $attrs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Match an asset against a string based search.
|
||||
*
|
||||
* @param string $match Search string.
|
||||
* @param object $asset Asset object.
|
||||
* @param string $search_prop Property to search in.
|
||||
* @return boolean
|
||||
*/
|
||||
function asset_match($match, $asset, $search_prop = 'url')
|
||||
{
|
||||
$search_prop = $search_prop ?: 'url';
|
||||
$search = trim($match);
|
||||
|
||||
// Starts with id: or url: - search in specific properties.
|
||||
if (preg_match('/^(id|url):\s*(.+?)$/', $search, $matches)) {
|
||||
$search_prop = $matches[1];
|
||||
$search = $matches[2];
|
||||
}
|
||||
|
||||
$search = preg_quote(trim($search));
|
||||
$search = str_replace('\*', '(.+?)', $search);
|
||||
|
||||
return preg_match('#' . $search . '#i', $asset->{$search_prop});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if it's a call from Elementor Page Builder preview.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
function is_elementor($preview_check = true)
|
||||
{
|
||||
// Elmentor may use AJAX to get widget configs etc.
|
||||
if (isset($_REQUEST['action']) && $_REQUEST['action'] === 'elementor_ajax') {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!class_exists('\Elementor\Plugin', false)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($preview_check && isset($_REQUEST['elementor-preview'])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return \Elementor\Plugin::$instance->editor->is_edit_mode();
|
||||
}
|
||||
|
||||
function debug_log($message)
|
||||
{
|
||||
if (Plugin::get_instance()->env === 'dev') {
|
||||
echo wp_kses_post($message); // phpcs:ignore WordPress.Security.EscapeOutput - Hardcoded debug output only enabled when environment is set to 'dev'.
|
||||
}
|
||||
}
|
55
wp-content/plugins/debloat/inc/wp-cli/commands.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace Sphere\Debloat\WpCli;
|
||||
use Sphere\Debloat\Admin\Cache;
|
||||
|
||||
/**
|
||||
* Commands for WPCLI
|
||||
*/
|
||||
class Commands extends \WP_CLI_Command {
|
||||
|
||||
/**
|
||||
* Flush the Debloat cache.
|
||||
*
|
||||
* [--network]
|
||||
* Flush CSS Cache for all the sites in the network.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* 1. wp debloat empty-cache
|
||||
* - Delete all the cached content.
|
||||
*
|
||||
* 2. wp debloat empty-cache --network
|
||||
* - Delete all the cached content including all transients for sites in a network.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @access public
|
||||
* @alias empty-cache
|
||||
*/
|
||||
public function empty_cache($args, $assoc_args)
|
||||
{
|
||||
$network = !empty($assoc_args['network']) && is_multisite();
|
||||
$cache = new Cache;
|
||||
|
||||
if ($network) {
|
||||
/** @var \WP_Site[] $blogs */
|
||||
$blogs = get_sites();
|
||||
|
||||
foreach ($blogs as $key => $blog) {
|
||||
$blog_id = $blog->blog_id;
|
||||
switch_to_blog($blog_id);
|
||||
|
||||
$cache->empty();
|
||||
|
||||
\WP_CLI::success('Emptied debloat cache for site - ' . get_option('home'));
|
||||
|
||||
restore_current_blog();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$cache->empty();
|
||||
\WP_CLI::success('Emptied all debloat cache.');
|
||||
}
|
||||
}
|
384
wp-content/plugins/debloat/js/admin/cmb2-conditionals.js
Normal file
39
wp-content/plugins/debloat/js/admin/options.js
Normal file
@@ -0,0 +1,39 @@
|
||||
"use strict";
|
||||
|
||||
jQuery(function($) {
|
||||
const context = $('.cmb2-options-page');
|
||||
|
||||
function conditionalGroups() {
|
||||
const targets = $('[name=remove_css], [name=allow_css_conditionals]', context);
|
||||
|
||||
targets.on('change', function() {
|
||||
const valid = $('[name=remove_css]:checked, [name=allow_css_conditionals]:checked', context).length === 2;
|
||||
const target = $('.cmb2-id-allow-conditionals-data');
|
||||
|
||||
valid ? target.show() : target.hide();
|
||||
});
|
||||
|
||||
targets.trigger('change');
|
||||
}
|
||||
|
||||
function multiCheckAllOption() {
|
||||
const targets = $('.cmb2-checkbox-list input[value=all]', context);
|
||||
targets.on('change', function() {
|
||||
|
||||
const parent = $(this).closest('ul');
|
||||
const others = parent.find('input:not([value=all])');
|
||||
|
||||
if ($(this).is(':checked')) {
|
||||
others.prop('disabled', true).parent('li').hide();
|
||||
}
|
||||
else {
|
||||
others.prop('disabled', false).parent('li').show();
|
||||
}
|
||||
});
|
||||
|
||||
targets.trigger('change');
|
||||
}
|
||||
|
||||
conditionalGroups();
|
||||
multiCheckAllOption();
|
||||
});
|
338
wp-content/plugins/debloat/languages/debloat.pot
Normal file
@@ -0,0 +1,338 @@
|
||||
# Copyright (C) 2023 debloat
|
||||
# This file is distributed under the same license as the debloat package.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: debloat\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Poedit-Basepath: ..\n"
|
||||
"X-Poedit-KeywordsList: __;_e;_ex:1,2c;_n:1,2;_n_noop:1,2;_nx:1,2,4c;_nx_noop:1,2,3c;_x:1,2c;esc_attr__;esc_attr_e;esc_attr_x:1,2c;esc_html__;esc_html_e;esc_html_x:1,2c\n"
|
||||
"X-Poedit-SearchPath-0: .\n"
|
||||
"X-Poedit-SearchPathExcluded-0: *.js\n"
|
||||
"X-Poedit-SourceCharset: UTF-8\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: bootstrap.php:14
|
||||
msgid "The %2$sDebloat%3$s plugin requires %2$sPHP 7.1+%3$s to run properly. Please contact your web hosting company and ask them to update the PHP version of your site.%4$s Your current version of PHP has reached end-of-life is %2$shighly insecure: %1$s%3$s"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/admin.php:145
|
||||
msgid "Debloat Plugin Settings"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/admin.php:149
|
||||
msgid "Debloat: Optimize"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/admin.php:151, inc/admin/options-data.php:36
|
||||
msgid "Optimize CSS"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/admin.php:164, inc/admin/admin.php:168, inc/admin/admin.php:170, inc/admin/options-data.php:275
|
||||
msgid "Optimize JS"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/admin.php:183, inc/admin/admin.php:187, inc/admin/admin.php:189
|
||||
msgid "General Settings"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/admin.php:237
|
||||
msgid "Condition Type"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/admin.php:241
|
||||
msgid "Class - If a class (in \"condition match\") exists in HTML, keep classes matching \"selector match\"."
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/admin.php:242
|
||||
msgid "Prefix - Condition matches the first class and keeps all the used child classes. Example: .s-dark will keep .s-dark .site-header."
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/admin.php:248
|
||||
msgid "Condition Match"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/admin.php:249
|
||||
msgid "Required. Usually a single class, example:"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/admin.php:256
|
||||
msgid "Selectors Match"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/admin.php:257
|
||||
msgid "Enter one per line. See example matchings in \"Always Keep Selectors\" above."
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/admin.php:326
|
||||
msgid "Cache Stats"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/admin.php:337
|
||||
msgid "Minified CSS files: %d"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/admin.php:338
|
||||
msgid "Minified JS files: %d"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/admin.php:339
|
||||
msgid "Processed CSS Sheets: %d"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:20
|
||||
msgid "All Pages"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:21
|
||||
msgid "Single Post/Article"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:44
|
||||
msgid "Fix Render-Blocking CSS"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:45
|
||||
msgid "Enable CSS Optimizations to fix Render-blocking CSS."
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:51
|
||||
msgid "Inline Optimized CSS"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:52
|
||||
msgid "Inline the CSS to prevent flash of unstyled content. Highly recommended."
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:59
|
||||
msgid "Inline Google Fonts CSS"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:60
|
||||
msgid "Inline the Google Fonts CSS for a big boost on FCP and slight on LCP on mobile. Highly recommended."
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:67
|
||||
msgid "Minify CSS"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:68
|
||||
msgid "Minify CSS to reduced the CSS size."
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:75
|
||||
msgid "Exclude Styles"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:77, inc/admin/options-data.php:183
|
||||
msgid "Enter one per line to exclude certain CSS files from this optimizations. Examples:"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:88, inc/admin/options-data.php:322
|
||||
msgid "Enable Plugin Integrations"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:89
|
||||
msgid "Special pre-made rules for CSS, specific to plugins, are applied if enabled."
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:101
|
||||
msgid "Optimize Google Fonts"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:102
|
||||
msgid "Add preconnect hints and add display swap for Google Fonts."
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:108
|
||||
msgid "Optimize CSS: Remove Unused"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:116
|
||||
msgid "Remove Unused CSS"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:117
|
||||
msgid "This is an expensive process. DO NOT use without a cache plugin."
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:124
|
||||
msgid "Remove from All Stylesheets"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:125
|
||||
msgid "WARNING: Only use if you are sure your plugins and themes dont add classes using JS. May also be enabled when delay loading all the original CSS."
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:133
|
||||
msgid "Enable for Plugins CSS"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:134
|
||||
msgid "Removed unused CSS on all plugins CSS files."
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:147
|
||||
msgid "Enable for Theme CSS"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:148
|
||||
msgid "Removed unused CSS from all theme CSS files."
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:161
|
||||
msgid "Target Stylesheets"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:163
|
||||
msgid "Will remove unused CSS from these targets. You may use an ID or the part of the URL. Examples:"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:181
|
||||
msgid "Exclude Stylesheets"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:195
|
||||
msgid "Always Keep Selectors"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:197
|
||||
msgid "Enter one per line. Partial or full matches for selectors (if any of these keywords found, the selector will be kept). Examples:"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:210
|
||||
msgid "Advanced: Conditionally Keep Selectors"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:226
|
||||
msgid "Add Condition"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:227
|
||||
msgid "Remove"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:235
|
||||
msgid "Remove CSS On"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:236
|
||||
msgid "Pages where unused CSS should be removed."
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:246
|
||||
msgid "Delay load Original CSS"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:247
|
||||
msgid "Delay-loading all of the original CSS might be needed in situations where there are too many JS-based CSS classes that are added later such as sliders, that you cannot track down and add to exclusions right now. Or on pages that may have Auto-load Next Post."
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:255
|
||||
msgid "Delay load Original On"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:256
|
||||
msgid "Pages where original CSS should be delayed load."
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:283
|
||||
msgid "Defer Javascript"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:284
|
||||
msgid "Delay JS execution till HTML is loaded to fix Render-Blocking JS issues."
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:291, inc/admin/options-data.php:399
|
||||
msgid "Exclude Scripts"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:292
|
||||
msgid "Enter one per line to exclude certain JS files from being deferred."
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:300
|
||||
msgid "Defer Inline JS"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:303
|
||||
msgid "Defer all inline JS."
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:304
|
||||
msgid "Note:"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:305
|
||||
msgid "Normally not needed. All correct dependent inline scripts are deferred by default. Enable if inline JS not enqueued using WordPress enqueue functions."
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:314
|
||||
msgid "Minify Javascript"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:315
|
||||
msgid "Minify all the deferred or delayed JS files."
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:323
|
||||
msgid "Special pre-made rules for javascript, specific to plugins, are applied if enabled."
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:337
|
||||
msgid "Delay Load JS"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:345
|
||||
msgid "Delay Javascript"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:346
|
||||
msgid "Delay execution of the targeted JS files until user interaction."
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:353
|
||||
msgid "Maximum Delay (in seconds)"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:354
|
||||
msgid "Max seconds to wait for interaction until delayed JS is loaded anyways."
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:366
|
||||
msgid "Delay All Scripts"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:367
|
||||
msgid "CAREFUL. Delays all JS files. Its better to target scripts manually below. If there are scripts that setup sliders/carousels, animations, or other similar things, these won't be setup until the first user interaction."
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:375
|
||||
msgid "Target Scripts"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:377
|
||||
msgid "Will delay from these scripts. You may use an ID, part of the URL, or any code for inline scripts. One per line. Examples:"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:401
|
||||
msgid "Enter one per line to exclude certain scripts from this optimizations. Examples:"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:414
|
||||
msgid "Delay Google Ads"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:415
|
||||
msgid "Delay Google Adsense until first interaction. Note: This may not be ideal if you have ads that are in header."
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:429
|
||||
msgid "Disable for Admins"
|
||||
msgstr ""
|
||||
|
||||
#: inc/admin/options-data.php:430
|
||||
msgid "Disable processing for logged in admin users or any user with capability \"manage_options\". (Useful if using a pagebuilder that conflicts)"
|
||||
msgstr ""
|
92
wp-content/plugins/debloat/readme.txt
Normal file
@@ -0,0 +1,92 @@
|
||||
=== Debloat - Remove Unused CSS, Optimize JS ===
|
||||
Contributors: asadkn
|
||||
Tags: speed, performance, uncss, optimize
|
||||
Requires at least: 5.0
|
||||
Tested up to: 6.3
|
||||
Requires PHP: 7.1
|
||||
Stable tag: 1.2.3
|
||||
License: GPLv2
|
||||
License URI: https://www.gnu.org/licenses/gpl-2.0.html
|
||||
|
||||
Remove Unused CSS, Optimize CSS, Optimize JS and speed up your site.
|
||||
|
||||
== Description ==
|
||||
A plugin for Advanced Users to Optimize CSS Delivery, Remove Unused CSS, Optimize Javascript Delivery with defer or delay load JS.
|
||||
The perfect toolkit for improving your Core Web Vitals and overall website performance.
|
||||
|
||||
WARNING: It's a powerful speed optimization plugin that's meant for power users who know what they're doing.
|
||||
|
||||
**Features:**
|
||||
|
||||
* Optimize CSS: Fix Render-Blocking.
|
||||
* Minify and Inline CSS.
|
||||
* Remove Unused CSS (Advanced).
|
||||
* Optimize JS: Fix Render-Blocking with defer.
|
||||
* Delay Load some JS until user interaction.
|
||||
* Adds resource hints for faster Google Fonts.
|
||||
* Built-in optimizations for Elementor (free version).
|
||||
* Built-in optimizations for WPBakery Page Builder.
|
||||
* Compatible with all themes and plugins.
|
||||
* Supports all modern browsers (no IE11 support).
|
||||
* Optimized code benchmarked for performance.
|
||||
* Built-in cache for processing.
|
||||
* Compatible with cache plugins (disable their JS and CSS optimizations).
|
||||
* API and hooks for theme & plugin authors.
|
||||
|
||||
|
||||
== Installation ==
|
||||
|
||||
1. Upload/Install and activate the plugin.
|
||||
2. Go to *Settings* > Debloat Optimize, and configure per your requirement.
|
||||
3. Clear all caches from any cache plugin you may have active.
|
||||
|
||||
== Changelog ==
|
||||
|
||||
= 1.2.3 =
|
||||
* Added: Support for media queries when unused CSS is removed.
|
||||
* Fixed: PHP warnings on PHP 8.2.
|
||||
* Fixed: Parsing complex CSS selectors with commas and several other complex rules.
|
||||
* Updated: Sabberworm CSS Parser to 8.4 with patches.
|
||||
|
||||
= 1.2.1 =
|
||||
* Fixed: A few minor PHP warnings / notices.
|
||||
* Improved: Elementor admin bar drop downs should render in delay JS.
|
||||
|
||||
= 1.2.0 =
|
||||
* Fixed: Error when malformed link tags with missing href.
|
||||
|
||||
= 1.1.9 =
|
||||
* Fixed: Google Fonts inline feature when additional parameters present in URL.
|
||||
* Improved: Strip unnecessary rel=stylesheet in inline styles.
|
||||
|
||||
= 1.1.7 =
|
||||
* Added: Option to defer inline scripts - useful if some dependent inline scripts not registered using WordPress enqueues.
|
||||
* Fixed: Defer inline scripts with jQuery if jquery-core is deferred.
|
||||
|
||||
= 1.1.6 =
|
||||
* Fixed: Delay/defer only replacing one instance with duplicated <script> tags of the same URL and id.
|
||||
|
||||
= 1.1.5 =
|
||||
* Added: New filter debloat/should_process.
|
||||
* Improved: Skip converting already qualified URLs.
|
||||
* Bumped required PHP version to 7.1+.
|
||||
|
||||
= 1.1.4 =
|
||||
* Fixed: Some PHP notices under certain conditions.
|
||||
|
||||
= 1.1.3 =
|
||||
* Added: Maximum user interaction wait time for JS delay load feature.
|
||||
|
||||
= 1.1.2 =
|
||||
* Fixed: Disable processing in feeds and on missing HTML tag.
|
||||
|
||||
= 1.1.1 =
|
||||
* Fixed: Fatal error for Sabberworm lib and resolved/matched AMP plugin dependency.
|
||||
|
||||
= 1.1.0 =
|
||||
* Added: WP CLI Commands to empty caches.
|
||||
* Added: Google Fonts optimizations such as font-display: swap.
|
||||
* Added: Option to inline Google Fonts CSS.
|
||||
|
||||
= 1.0.0 =
|
||||
* Initial release.
|
25
wp-content/plugins/debloat/vendor/autoload.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
// autoload.php @generated by Composer
|
||||
|
||||
if (PHP_VERSION_ID < 50600) {
|
||||
if (!headers_sent()) {
|
||||
header('HTTP/1.1 500 Internal Server Error');
|
||||
}
|
||||
$err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
|
||||
if (!ini_get('display_errors')) {
|
||||
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
|
||||
fwrite(STDERR, $err);
|
||||
} elseif (!headers_sent()) {
|
||||
echo $err;
|
||||
}
|
||||
}
|
||||
trigger_error(
|
||||
$err,
|
||||
E_USER_ERROR
|
||||
);
|
||||
}
|
||||
|
||||
require_once __DIR__ . '/composer/autoload_real.php';
|
||||
|
||||
return ComposerAutoloaderInite6b20e9b4113198d9a260118efd9778a::getLoader();
|
76
wp-content/plugins/debloat/vendor/cmb2/CODE_OF_CONDUCT.md
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to making participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, sex characteristics, gender identity and expression,
|
||||
level of experience, education, socio-economic status, nationality, personal
|
||||
appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces
|
||||
when an individual is representing the project or its community. Examples of
|
||||
representing a project or community include using an official project e-mail
|
||||
address, posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event. Representation of a project may be
|
||||
further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting the project team at hello@cmb2.io. All
|
||||
complaints will be reviewed and investigated and will result in a response that
|
||||
is deemed necessary and appropriate to the circumstances. The project team is
|
||||
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||
Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see
|
||||
https://www.contributor-covenant.org/faq
|
674
wp-content/plugins/debloat/vendor/cmb2/LICENSE
vendored
Normal file
@@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. 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
|
||||
them 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 prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. 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.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey 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;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If 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 convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU 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 that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
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.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
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.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
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
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program 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, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU 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. But first, please read
|
||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
84
wp-content/plugins/debloat/vendor/cmb2/bootstrap.php
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
/**
|
||||
* Bootstraps the CMB2 process
|
||||
*
|
||||
* @category WordPress_Plugin
|
||||
* @package CMB2
|
||||
* @author CMB2
|
||||
* @license GPL-2.0+
|
||||
* @link https://cmb2.io
|
||||
*/
|
||||
|
||||
/**
|
||||
* Function to encapsulate the CMB2 bootstrap process.
|
||||
*
|
||||
* @since 2.2.0
|
||||
* @return void
|
||||
*/
|
||||
function cmb2_bootstrap() {
|
||||
|
||||
if ( is_admin() ) {
|
||||
/**
|
||||
* Fires on the admin side when CMB2 is included/loaded.
|
||||
*
|
||||
* In most cases, this should be used to add metaboxes. See example-functions.php
|
||||
*/
|
||||
do_action( 'cmb2_admin_init' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires when CMB2 is included/loaded
|
||||
*
|
||||
* Can be used to add metaboxes if needed on the front-end or WP-API (or the front and backend).
|
||||
*/
|
||||
do_action( 'cmb2_init' );
|
||||
|
||||
/**
|
||||
* For back-compat. Does the dirty-work of instantiating all the
|
||||
* CMB2 instances for the cmb2_meta_boxes filter
|
||||
*
|
||||
* @since 2.0.2
|
||||
*/
|
||||
$cmb_config_arrays = apply_filters( 'cmb2_meta_boxes', array() );
|
||||
foreach ( (array) $cmb_config_arrays as $cmb_config ) {
|
||||
new CMB2( $cmb_config );
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires after all CMB2 instances are created
|
||||
*/
|
||||
do_action( 'cmb2_init_before_hookup' );
|
||||
|
||||
/**
|
||||
* Get all created metaboxes, and instantiate CMB2_Hookup
|
||||
* on metaboxes which require it.
|
||||
*
|
||||
* @since 2.0.2
|
||||
*/
|
||||
foreach ( CMB2_Boxes::get_all() as $cmb ) {
|
||||
|
||||
/**
|
||||
* Initiates the box "hookup" into WordPress.
|
||||
*
|
||||
* Unless the 'hookup' box property is `false`, the box will be hooked in as
|
||||
* a post/user/comment/option/term box.
|
||||
*
|
||||
* And if the 'show_in_rest' box property is set, the box will be hooked
|
||||
* into the CMB2 REST API.
|
||||
*
|
||||
* The dynamic portion of the hook name, $cmb->cmb_id, is the box id.
|
||||
*
|
||||
* @since 2.2.6
|
||||
*
|
||||
* @param array $cmb The CMB2 object to hookup.
|
||||
*/
|
||||
do_action( "cmb2_init_hookup_{$cmb->cmb_id}", $cmb );
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires after CMB2 initiation process has been completed
|
||||
*/
|
||||
do_action( 'cmb2_after_init' );
|
||||
}
|
||||
|
||||
/* End. That's it, folks! */
|
45
wp-content/plugins/debloat/vendor/cmb2/css/cmb2-display-rtl.css
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
/*!
|
||||
* CMB2 - v2.10.0 - 2022-10-27
|
||||
* https://cmb2.io
|
||||
* Copyright (c) 2022
|
||||
* Licensed GPLv2+
|
||||
*/
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
* CMB2 Display Styling
|
||||
--------------------------------------------------------------*/
|
||||
/* line 6, sass/partials/_display.scss */
|
||||
.cmb2-colorpicker-swatch span {
|
||||
display: inline-block;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
border-radius: 1em;
|
||||
float: right;
|
||||
margin-top: 3px;
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
/* line 17, sass/partials/_display.scss */
|
||||
.cmb2-code {
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
/* line 21, sass/partials/_display.scss */
|
||||
.cmb-image-display {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
/* line 26, sass/partials/_display.scss */
|
||||
.cmb2-display-file-list li {
|
||||
display: inline;
|
||||
margin: 0 0 .5em .5em;
|
||||
}
|
||||
|
||||
/* line 31, sass/partials/_display.scss */
|
||||
.cmb2-oembed * {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
/*# sourceMappingURL=cmb2-display.css.map */
|
1
wp-content/plugins/debloat/vendor/cmb2/css/cmb2-display-rtl.min.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.cmb2-colorpicker-swatch span{display:inline-block;width:1em;height:1em;border-radius:1em;float:right;margin-top:3px;margin-left:2px}.cmb2-code{overflow:scroll}.cmb-image-display{max-width:100%;height:auto}.cmb2-display-file-list li{display:inline;margin:0 0 .5em .5em}.cmb2-oembed *{max-width:100%;height:auto}
|
45
wp-content/plugins/debloat/vendor/cmb2/css/cmb2-display.css
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
/*!
|
||||
* CMB2 - v2.10.0 - 2022-10-27
|
||||
* https://cmb2.io
|
||||
* Copyright (c) 2022
|
||||
* Licensed GPLv2+
|
||||
*/
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
* CMB2 Display Styling
|
||||
--------------------------------------------------------------*/
|
||||
/* line 6, sass/partials/_display.scss */
|
||||
.cmb2-colorpicker-swatch span {
|
||||
display: inline-block;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
border-radius: 1em;
|
||||
float: left;
|
||||
margin-top: 3px;
|
||||
margin-right: 2px;
|
||||
}
|
||||
|
||||
/* line 17, sass/partials/_display.scss */
|
||||
.cmb2-code {
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
/* line 21, sass/partials/_display.scss */
|
||||
.cmb-image-display {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
/* line 26, sass/partials/_display.scss */
|
||||
.cmb2-display-file-list li {
|
||||
display: inline;
|
||||
margin: 0 .5em .5em 0;
|
||||
}
|
||||
|
||||
/* line 31, sass/partials/_display.scss */
|
||||
.cmb2-oembed * {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
/*# sourceMappingURL=cmb2-display.css.map */
|
7
wp-content/plugins/debloat/vendor/cmb2/css/cmb2-display.css.map
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"version": 3,
|
||||
"mappings": "AAAA;;gEAEgE;;AAG/D,6BAAK;EACJ,OAAO,EAAE,YAAY;EACrB,KAAK,EAAE,GAAG;EACV,MAAM,EAAE,GAAG;EACX,aAAa,EAAE,GAAG;EAClB,KAAK,EAAE,IAAI;EACX,UAAU,EAAE,GAAG;EACf,YAAY,EAAE,GAAG;;;;AAInB,UAAW;EACV,QAAQ,EAAE,MAAM;;;;AAGjB,kBAAmB;EAClB,SAAS,EAAE,IAAI;EACf,MAAM,EAAE,IAAI;;;;AAGb,0BAA2B;EAC1B,OAAO,EAAE,MAAM;EACf,MAAM,EAAE,aAAa;;;;AAGtB,cAAe;EACd,SAAS,EAAE,IAAI;EACf,MAAM,EAAE,IAAI",
|
||||
"sources": ["sass/partials/_display.scss"],
|
||||
"names": [],
|
||||
"file": "cmb2-display.css"
|
||||
}
|
1
wp-content/plugins/debloat/vendor/cmb2/css/cmb2-display.min.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.cmb2-colorpicker-swatch span{display:inline-block;width:1em;height:1em;border-radius:1em;float:left;margin-top:3px;margin-right:2px}.cmb2-code{overflow:scroll}.cmb-image-display{max-width:100%;height:auto}.cmb2-display-file-list li{display:inline;margin:0 .5em .5em 0}.cmb2-oembed *{max-width:100%;height:auto}
|
1386
wp-content/plugins/debloat/vendor/cmb2/css/cmb2-front-rtl.css
vendored
Normal file
1
wp-content/plugins/debloat/vendor/cmb2/css/cmb2-front-rtl.min.css
vendored
Normal file
1386
wp-content/plugins/debloat/vendor/cmb2/css/cmb2-front.css
vendored
Normal file
7
wp-content/plugins/debloat/vendor/cmb2/css/cmb2-front.css.map
vendored
Normal file
1
wp-content/plugins/debloat/vendor/cmb2/css/cmb2-front.min.css
vendored
Normal file
1589
wp-content/plugins/debloat/vendor/cmb2/css/cmb2-rtl.css
vendored
Normal file
1
wp-content/plugins/debloat/vendor/cmb2/css/cmb2-rtl.min.css
vendored
Normal file
1589
wp-content/plugins/debloat/vendor/cmb2/css/cmb2.css
vendored
Normal file
7
wp-content/plugins/debloat/vendor/cmb2/css/cmb2.css.map
vendored
Normal file
1
wp-content/plugins/debloat/vendor/cmb2/css/cmb2.min.css
vendored
Normal file
2
wp-content/plugins/debloat/vendor/cmb2/css/index.php
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
<?php
|
||||
// Silence is golden
|
1
wp-content/plugins/debloat/vendor/cmb2/css/sass/cmb2-display.scss
vendored
Normal file
@@ -0,0 +1 @@
|
||||
@import "partials/display";
|
15
wp-content/plugins/debloat/vendor/cmb2/css/sass/cmb2-front.scss
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
@import "partials/variables";
|
||||
@import "partials/mixins";
|
||||
|
||||
@import "partials/main_wrap";
|
||||
@import "partials/post_metaboxes";
|
||||
@import "partials/context_metaboxes";
|
||||
@import "partials/misc";
|
||||
@import "partials/collapsible_ui";
|
||||
@import "partials/jquery_ui";
|
||||
@import "partials/char_counter";
|
||||
|
||||
/**
|
||||
* CMB2 Frontend
|
||||
*/
|
||||
@import "partials/front";
|
13
wp-content/plugins/debloat/vendor/cmb2/css/sass/cmb2.scss
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
@import "partials/variables";
|
||||
@import "partials/mixins";
|
||||
|
||||
@import "partials/main_wrap";
|
||||
@import "partials/post_metaboxes";
|
||||
@import "partials/context_metaboxes";
|
||||
@import "partials/options-page";
|
||||
@import "partials/new_term";
|
||||
@import "partials/misc";
|
||||
@import "partials/sidebar_placements";
|
||||
@import "partials/collapsible_ui";
|
||||
@import "partials/jquery_ui";
|
||||
@import "partials/char_counter";
|
2
wp-content/plugins/debloat/vendor/cmb2/css/sass/index.php
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
<?php
|
||||
// Silence is golden
|
28
wp-content/plugins/debloat/vendor/cmb2/css/sass/partials/_char_counter.scss
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
/*--------------------------------------------------------------
|
||||
* Character counter
|
||||
--------------------------------------------------------------*/
|
||||
|
||||
.cmb2-char-counter-wrap {
|
||||
margin: .5em 0 1em;
|
||||
|
||||
input[type="text"] {
|
||||
font-size: 12px;
|
||||
width: 25px;
|
||||
}
|
||||
|
||||
&.cmb2-max-exceeded {
|
||||
input[type="text"] {
|
||||
border-color: $dark-red !important;
|
||||
}
|
||||
.cmb2-char-max-msg {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cmb2-char-max-msg {
|
||||
color: $dark-red;
|
||||
display: none;
|
||||
font-weight: 600;
|
||||
margin-left: 1em;
|
||||
}
|
56
wp-content/plugins/debloat/vendor/cmb2/css/sass/partials/_collapsible_ui.scss
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
/*--------------------------------------------------------------
|
||||
* Collapsible UI
|
||||
--------------------------------------------------------------*/
|
||||
|
||||
.cmb2-metabox {
|
||||
.cmbhandle {
|
||||
color: $gray;
|
||||
float: right;
|
||||
width: 27px;
|
||||
height: 30px;
|
||||
cursor: pointer;
|
||||
right: -1em;
|
||||
position: relative;
|
||||
&:before {
|
||||
content: '\f142';
|
||||
right: 12px;
|
||||
font: normal 20px/1 'dashicons';
|
||||
speak: none;
|
||||
display: inline-block;
|
||||
padding: 8px 10px;
|
||||
top: 0;
|
||||
position: relative;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.postbox.closed {
|
||||
.cmbhandle {
|
||||
&:before {
|
||||
content: '\f140';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
button.dashicons-before.dashicons-no-alt.cmb-remove-group-row {
|
||||
-webkit-appearance: none !important;
|
||||
background: none !important;
|
||||
border: none !important;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: .5em;
|
||||
line-height: 1em;
|
||||
padding: 2px 6px 3px;
|
||||
opacity: .5;
|
||||
&:not([disabled]) {
|
||||
cursor: pointer;
|
||||
color: $dark-red;
|
||||
opacity: 1;
|
||||
&:hover {
|
||||
color: $red;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
111
wp-content/plugins/debloat/vendor/cmb2/css/sass/partials/_context_metaboxes.scss
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
/*--------------------------------------------------------------
|
||||
* Context Metaboxes
|
||||
--------------------------------------------------------------*/
|
||||
|
||||
/* Metabox collapse arrow indicators */
|
||||
.js .cmb2-postbox.context-box {
|
||||
|
||||
.handlediv {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.toggle-indicator {
|
||||
&:before {
|
||||
content: "\f142";
|
||||
display: inline-block;
|
||||
font: normal 20px/1 dashicons;
|
||||
speak: none;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
&.closed {
|
||||
.toggle-indicator {
|
||||
&:before {
|
||||
content: "\f140";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.cmb2-postbox.context-box {
|
||||
|
||||
margin-bottom: 10px;
|
||||
|
||||
&.context-before_permalink-box {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
&.context-after_title-box {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
&.context-after_editor-box {
|
||||
margin-top: 20px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
&.context-form_top-box {
|
||||
|
||||
margin-top: 10px;
|
||||
|
||||
.hndle {
|
||||
font-size: 14px;
|
||||
padding: 8px 12px;
|
||||
margin: 0;
|
||||
line-height: 1.4;
|
||||
}
|
||||
}
|
||||
|
||||
.hndle {
|
||||
cursor: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.cmb2-context-wrap {
|
||||
|
||||
margin-top: 10px;
|
||||
|
||||
&.cmb2-context-wrap-form_top {
|
||||
margin-right: 300px;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
&.cmb2-context-wrap-no-title {
|
||||
|
||||
.cmb2-metabox {
|
||||
padding: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.cmb-th {
|
||||
padding: 0 2% 0 0;
|
||||
width: 18%;
|
||||
}
|
||||
|
||||
.cmb-td {
|
||||
width: 80%;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.cmb-row {
|
||||
margin-bottom: 10px;
|
||||
|
||||
&:last-of-type {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* one column on the post write/edit screen */
|
||||
@media only screen and (max-width: 850px) {
|
||||
|
||||
.cmb2-context-wrap.cmb2-context-wrap-form_top {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
}
|
34
wp-content/plugins/debloat/vendor/cmb2/css/sass/partials/_display.scss
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
/*--------------------------------------------------------------
|
||||
* CMB2 Display Styling
|
||||
--------------------------------------------------------------*/
|
||||
|
||||
.cmb2-colorpicker-swatch {
|
||||
span {
|
||||
display: inline-block;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
border-radius: 1em;
|
||||
float: left;
|
||||
margin-top: 3px;
|
||||
margin-right: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.cmb2-code {
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
.cmb-image-display {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.cmb2-display-file-list li {
|
||||
display: inline;
|
||||
margin: 0 .5em .5em 0;
|
||||
}
|
||||
|
||||
.cmb2-oembed * {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
60
wp-content/plugins/debloat/vendor/cmb2/css/sass/partials/_front.scss
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
/*--------------------------------------------------------------
|
||||
* CMB2 Frontend
|
||||
--------------------------------------------------------------*/
|
||||
|
||||
.closed .inside {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.cmb-repeatable-grouping {
|
||||
position: relative;
|
||||
|
||||
.cmb-group-title {
|
||||
margin-left: -1em;
|
||||
margin-right: -1em;
|
||||
min-height: 1.5em;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 14px;
|
||||
padding: 8px 12px;
|
||||
margin: 0;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.cmb-repeatable-group {
|
||||
|
||||
&.repeatable .cmb-group-title {
|
||||
padding-left: 2.2em;
|
||||
}
|
||||
|
||||
&.non-repeatable .cmb-group-title {
|
||||
padding-left: 12px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.cmb-type-group .cmb-row .cmbhandle {
|
||||
right: 0;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.cmb-spinner {
|
||||
background: url(/wp-admin/images/spinner.gif) no-repeat;
|
||||
-webkit-background-size: 20px 20px;
|
||||
background-size: 20px 20px;
|
||||
display: none;
|
||||
float: right;
|
||||
vertical-align: middle;
|
||||
opacity: 0.7;
|
||||
filter: alpha(opacity=70);
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin: 4px 10px 0;
|
||||
}
|
||||
|
||||
.cmb2-char-max-msg {
|
||||
display: none;
|
||||
}
|
457
wp-content/plugins/debloat/vendor/cmb2/css/sass/partials/_jquery_ui.scss
vendored
Normal file
@@ -0,0 +1,457 @@
|
||||
/*
|
||||
* jQuery UI CSS Framework 1.8.16
|
||||
*
|
||||
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Theming/API
|
||||
*
|
||||
* WordPress Styles adopted from "jQuery UI Datepicker CSS for WordPress"
|
||||
* https://github.com/stuttter/wp-datepicker-styling
|
||||
*
|
||||
*/
|
||||
|
||||
* html .cmb2-element.ui-helper-clearfix {
|
||||
height:1%;
|
||||
}
|
||||
|
||||
$weekend: #f4f4f4;
|
||||
$freshblue: #00a0d2;
|
||||
$freshdark: #32373c;
|
||||
$freshdarkblue: #0073aa;
|
||||
|
||||
.cmb2-element.ui-datepicker, .cmb2-element .ui-datepicker {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
-webkit-border-radius: 0;
|
||||
-moz-border-radius: 0;
|
||||
border-radius: 0;
|
||||
background-color: #fff;
|
||||
border: 1px solid #dfdfdf;
|
||||
border-top: none;
|
||||
-webkit-box-shadow: 0 3px 6px rgba(0, 0, 0, 0.075);
|
||||
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.075);
|
||||
min-width: 17em;
|
||||
width: auto;
|
||||
|
||||
* {
|
||||
padding: 0;
|
||||
font-family: "Open Sans", sans-serif;
|
||||
-webkit-border-radius: 0;
|
||||
-moz-border-radius: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
table {
|
||||
font-size: 13px;
|
||||
margin: 0;
|
||||
border: none;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.ui-widget-header,
|
||||
.ui-datepicker-header {
|
||||
background-image: none;
|
||||
border: none;
|
||||
color: #fff;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.ui-datepicker-header .ui-state-hover {
|
||||
background: transparent;
|
||||
border-color: transparent;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.ui-datepicker-title {
|
||||
margin: 0;
|
||||
padding: 10px 0;
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
line-height: 14px;
|
||||
text-align: center;
|
||||
|
||||
select {
|
||||
margin-top: -8px;
|
||||
margin-bottom: -8px;
|
||||
}
|
||||
}
|
||||
|
||||
.ui-datepicker-prev,
|
||||
.ui-datepicker-next {
|
||||
position: relative;
|
||||
top: 0;
|
||||
height: 34px;
|
||||
width: 34px;
|
||||
}
|
||||
|
||||
.ui-state-hover.ui-datepicker-prev,
|
||||
.ui-state-hover.ui-datepicker-next {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.ui-datepicker-prev,
|
||||
.ui-datepicker-prev-hover {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.ui-datepicker-next,
|
||||
.ui-datepicker-next-hover {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.ui-datepicker-next span,
|
||||
.ui-datepicker-prev span {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ui-datepicker-prev {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.ui-datepicker-next {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.ui-datepicker-prev:before,
|
||||
.ui-datepicker-next:before {
|
||||
font: normal 20px/34px 'dashicons';
|
||||
padding-left: 7px;
|
||||
color: #fff;
|
||||
speak: none;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
}
|
||||
|
||||
.ui-datepicker-prev:before {
|
||||
content: '\f341';
|
||||
}
|
||||
|
||||
.ui-datepicker-next:before {
|
||||
content: '\f345';
|
||||
}
|
||||
|
||||
.ui-datepicker-prev-hover:before,
|
||||
.ui-datepicker-next-hover:before {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
select.ui-datepicker-month,
|
||||
select.ui-datepicker-year {
|
||||
width: 33%;
|
||||
background: transparent;
|
||||
border-color: transparent;
|
||||
box-shadow: none;
|
||||
color: #fff;
|
||||
option {
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
thead {
|
||||
color: #fff;
|
||||
font-weight: 600;
|
||||
th {
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
|
||||
th {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 0;
|
||||
border: 1px solid $weekend;
|
||||
}
|
||||
|
||||
td.ui-datepicker-other-month {
|
||||
border: transparent;
|
||||
}
|
||||
|
||||
td.ui-datepicker-week-end {
|
||||
background-color: $weekend;
|
||||
border: 1px solid $weekend;
|
||||
&.ui-datepicker-today {
|
||||
-webkit-box-shadow: inset 0px 0px 1px 0px rgba(0, 0, 0, 0.1);
|
||||
-moz-box-shadow: inset 0px 0px 1px 0px rgba(0, 0, 0, 0.1);
|
||||
box-shadow: inset 0px 0px 1px 0px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
td.ui-datepicker-today {
|
||||
background-color: #f0f0c0;
|
||||
}
|
||||
|
||||
td.ui-datepicker-current-day {
|
||||
background: #bbdd88;
|
||||
}
|
||||
|
||||
td .ui-state-default {
|
||||
background: transparent;
|
||||
border: none;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
width: auto;
|
||||
display: block;
|
||||
padding: 5px 10px;
|
||||
font-weight: normal;
|
||||
color: #444;
|
||||
}
|
||||
|
||||
td.ui-state-disabled .ui-state-default {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
/* Default Color Scheme */
|
||||
.ui-widget-header,
|
||||
.ui-datepicker-header {
|
||||
background: $freshblue;
|
||||
}
|
||||
|
||||
thead {
|
||||
background: $freshdark;
|
||||
}
|
||||
|
||||
td .ui-state-hover, td .ui-state-active {
|
||||
background: $freshdarkblue;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.ui-timepicker-div {
|
||||
font-size: 14px;
|
||||
dl {
|
||||
text-align: left;
|
||||
padding: 0 .6em;
|
||||
dt {
|
||||
float: left;
|
||||
clear:left;
|
||||
padding: 0 0 0 5px;
|
||||
}
|
||||
dd {
|
||||
margin: 0 10px 10px 40%;
|
||||
select {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+ .ui-datepicker-buttonpane {
|
||||
padding: .6em;
|
||||
text-align: left;
|
||||
|
||||
.button-primary, .button-secondary {
|
||||
padding: 0 10px 1px;
|
||||
-webkit-border-radius: 3px;
|
||||
-moz-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
margin: 0 .6em .4em .4em;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
.admin-color-fresh {
|
||||
.cmb2-element.ui-datepicker, .cmb2-element .ui-datepicker {
|
||||
.ui-widget-header,
|
||||
.ui-datepicker-header {
|
||||
background: $freshblue;
|
||||
}
|
||||
|
||||
thead {
|
||||
background: $freshdark;
|
||||
}
|
||||
|
||||
td .ui-state-hover {
|
||||
background: $freshdarkblue;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
.admin-color-blue {
|
||||
.cmb2-element.ui-datepicker, .cmb2-element .ui-datepicker {
|
||||
.ui-widget-header,
|
||||
.ui-datepicker-header {
|
||||
background: #52accc;
|
||||
}
|
||||
|
||||
thead {
|
||||
background: #4796b3;
|
||||
}
|
||||
|
||||
// td .ui-state-hover {
|
||||
// background: #096484;
|
||||
// }
|
||||
|
||||
td {
|
||||
.ui-state-hover, .ui-state-active {
|
||||
background: #096484;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
&.ui-datepicker-today {
|
||||
background: #eee;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
.admin-color-coffee {
|
||||
.cmb2-element.ui-datepicker, .cmb2-element .ui-datepicker {
|
||||
.ui-widget-header,
|
||||
.ui-datepicker-header {
|
||||
background: #59524c;
|
||||
}
|
||||
|
||||
thead {
|
||||
background: #46403c;
|
||||
}
|
||||
|
||||
td .ui-state-hover {
|
||||
background: #c7a589;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
.admin-color-ectoplasm {
|
||||
.cmb2-element.ui-datepicker, .cmb2-element .ui-datepicker {
|
||||
.ui-widget-header,
|
||||
.ui-datepicker-header {
|
||||
background: #523f6d;
|
||||
}
|
||||
|
||||
thead {
|
||||
background: #413256;
|
||||
}
|
||||
|
||||
td .ui-state-hover {
|
||||
background: #a3b745;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
.admin-color-midnight {
|
||||
.cmb2-element.ui-datepicker, .cmb2-element .ui-datepicker {
|
||||
.ui-widget-header,
|
||||
.ui-datepicker-header {
|
||||
background: #363b3f;
|
||||
}
|
||||
|
||||
thead {
|
||||
background: #26292c;
|
||||
}
|
||||
|
||||
td .ui-state-hover {
|
||||
background: #e14d43;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
.admin-color-ocean {
|
||||
.cmb2-element.ui-datepicker, .cmb2-element .ui-datepicker {
|
||||
.ui-widget-header,
|
||||
.ui-datepicker-header {
|
||||
background: #738e96;
|
||||
}
|
||||
|
||||
thead {
|
||||
background: #627c83;
|
||||
}
|
||||
|
||||
td .ui-state-hover {
|
||||
background: #9ebaa0;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
.admin-color-sunrise {
|
||||
.cmb2-element.ui-datepicker, .cmb2-element .ui-datepicker {
|
||||
.ui-widget-header,
|
||||
.ui-datepicker-header,
|
||||
.ui-datepicker-header .ui-state-hover {
|
||||
background: #cf4944;
|
||||
}
|
||||
|
||||
th {
|
||||
border-color: #be3631;
|
||||
background: #be3631;
|
||||
}
|
||||
|
||||
td .ui-state-hover {
|
||||
background: #dd823b;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
.admin-color-light {
|
||||
.cmb2-element.ui-datepicker, .cmb2-element .ui-datepicker {
|
||||
.ui-widget-header,
|
||||
.ui-datepicker-header {
|
||||
background: #e5e5e5;
|
||||
}
|
||||
|
||||
select.ui-datepicker-month,
|
||||
select.ui-datepicker-year {
|
||||
color: #555;
|
||||
}
|
||||
|
||||
thead {
|
||||
background: #888;
|
||||
}
|
||||
|
||||
.ui-datepicker-title,
|
||||
td .ui-state-default,
|
||||
.ui-datepicker-prev:before,
|
||||
.ui-datepicker-next:before {
|
||||
color: #555;
|
||||
}
|
||||
|
||||
td {
|
||||
.ui-state-hover, .ui-state-active {
|
||||
background: #ccc;
|
||||
}
|
||||
|
||||
&.ui-datepicker-today {
|
||||
background: #eee;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.admin-color-bbp-evergreen {
|
||||
.cmb2-element.ui-datepicker, .cmb2-element .ui-datepicker {
|
||||
.ui-widget-header,
|
||||
.ui-datepicker-header {
|
||||
background: #56b274;
|
||||
}
|
||||
|
||||
thead {
|
||||
background: #36533f;
|
||||
}
|
||||
|
||||
td .ui-state-hover {
|
||||
background: #446950;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
.admin-color-bbp-mint {
|
||||
.cmb2-element.ui-datepicker, .cmb2-element .ui-datepicker {
|
||||
.ui-widget-header,
|
||||
.ui-datepicker-header {
|
||||
background: #4ca26a;
|
||||
}
|
||||
|
||||
thead {
|
||||
background: #4f6d59;
|
||||
}
|
||||
|
||||
td .ui-state-hover {
|
||||
background: #5fb37c;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
534
wp-content/plugins/debloat/vendor/cmb2/css/sass/partials/_main_wrap.scss
vendored
Normal file
@@ -0,0 +1,534 @@
|
||||
/*--------------------------------------------------------------
|
||||
* Main Wrap
|
||||
--------------------------------------------------------------*/
|
||||
|
||||
.cmb2-wrap {
|
||||
margin: 0;
|
||||
|
||||
input,
|
||||
textarea {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
input[type="text"] {
|
||||
|
||||
&.cmb2-oembed {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
textarea {
|
||||
width: 500px;
|
||||
padding: 8px;
|
||||
|
||||
&.cmb2-textarea-code {
|
||||
font-family: $font-mono;
|
||||
line-height: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
input {
|
||||
|
||||
&.cmb2-text-small,
|
||||
&.cmb2-timepicker {
|
||||
width: 100px;
|
||||
// margin-right: 15px
|
||||
}
|
||||
|
||||
&.cmb2-text-money {
|
||||
width: 90px;
|
||||
// margin-right: 15px
|
||||
}
|
||||
|
||||
&.cmb2-text-medium {
|
||||
width: 230px;
|
||||
// margin-right: 15px
|
||||
}
|
||||
|
||||
&.cmb2-upload-file {
|
||||
width: 65%;
|
||||
}
|
||||
|
||||
&.ed_button {
|
||||
padding: 2px 4px;
|
||||
}
|
||||
|
||||
&:not([type="hidden"]) {
|
||||
+ input,
|
||||
+ .button-secondary,
|
||||
+ select {
|
||||
margin-left: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
li {
|
||||
font-size: $font-size;
|
||||
line-height: 16px;
|
||||
margin: 1px 0 5px 0;
|
||||
}
|
||||
|
||||
// .cmb-field-list .cmb-field-list {
|
||||
// padding-top:5px;
|
||||
// margin: 0;
|
||||
// }
|
||||
|
||||
select {
|
||||
font-size: $font-size;
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
input:focus,
|
||||
textarea:focus {
|
||||
background: $light-yellow;
|
||||
}
|
||||
|
||||
input[type="radio"] {
|
||||
margin: 0 5px 0 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
input[type="checkbox"] {
|
||||
margin: 0 5px 0 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
button,
|
||||
.button-secondary {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.mceLayout {
|
||||
border: 1px solid $light-gray !important;
|
||||
}
|
||||
|
||||
.mceIframeContainer {
|
||||
background: $white;
|
||||
}
|
||||
|
||||
.meta_mce {
|
||||
width: 97%;
|
||||
|
||||
textarea {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
// Multicheck toggle
|
||||
.cmb-multicheck-toggle {
|
||||
margin-top: -1em;
|
||||
}
|
||||
|
||||
// Color picker
|
||||
.wp-picker-clear.button,
|
||||
.wp-picker-default.button {
|
||||
margin-left: 6px;
|
||||
padding: 2px 8px;
|
||||
}
|
||||
|
||||
.cmb-row {
|
||||
margin: 0;
|
||||
|
||||
&:after {
|
||||
content: '';
|
||||
clear: both;
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&.cmb-repeat .cmb2-metabox-description {
|
||||
padding-top: 0;
|
||||
padding-bottom: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Fixes bug created by 5.3+ block editor-specific styling
|
||||
// Over-specific selector to override WordPress's over-specific selector without !important
|
||||
// @todo - Remove when `body.branch-5-3` targeting 5.3+ is widely used
|
||||
body.block-editor-page.branch-5-3 .cmb2-wrap .cmb-row .cmb2-radio-list input[type="radio"]::before {
|
||||
margin: .1875rem;
|
||||
|
||||
@media screen and (max-width: 782px) {
|
||||
margin: .4375rem;
|
||||
}
|
||||
}
|
||||
|
||||
.cmb2-metabox {
|
||||
clear: both;
|
||||
margin: 0;
|
||||
|
||||
> .cmb-row:first-of-type >,
|
||||
.cmb-field-list > .cmb-row:first-of-type > {
|
||||
.cmb-td,
|
||||
.cmb-th {
|
||||
border: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cmb-add-row {
|
||||
margin: 1.8em 0 0;
|
||||
}
|
||||
|
||||
.cmb-nested .cmb-td,
|
||||
.cmb-repeatable-group .cmb-th,
|
||||
.cmb-repeatable-group:first-of-type {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.cmb-row:last-of-type,
|
||||
.cmb2-wrap .cmb-row:last-of-type,
|
||||
.cmb-repeatable-group:last-of-type {
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
.cmb-repeatable-grouping {
|
||||
border: 1px solid $light-gray;
|
||||
padding: 0 1em;
|
||||
|
||||
&.cmb-row {
|
||||
margin: 0 0 0.8em;
|
||||
}
|
||||
|
||||
+ .cmb-repeatable-grouping {
|
||||
}
|
||||
}
|
||||
|
||||
.cmb-th {
|
||||
color: $dark-gray;
|
||||
float: left;
|
||||
font-weight: 600;
|
||||
padding: 20px 10px 20px 0;
|
||||
vertical-align: top;
|
||||
width: 200px;
|
||||
|
||||
@media (max-width: $mobile-break) {
|
||||
@include fullth;
|
||||
}
|
||||
}
|
||||
|
||||
.cmb-td {
|
||||
line-height: 1.3;
|
||||
max-width: 100%;
|
||||
padding: 15px 10px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.cmb-type-title {
|
||||
|
||||
.cmb-td {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.cmb-th label {
|
||||
display: block;
|
||||
padding: 5px 0;
|
||||
}
|
||||
|
||||
.cmb-th + .cmb-td {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.cmb-td .cmb-td {
|
||||
padding-bottom: 1em;
|
||||
}
|
||||
|
||||
.cmb-remove-row {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.empty-row.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
// Repeatable fields styles
|
||||
.cmb-repeat-table {
|
||||
background-color: $almostwhite;
|
||||
border: 1px solid darken($light-gray, 3%);
|
||||
|
||||
.cmb-row.cmb-repeat-row {
|
||||
position: relative;
|
||||
counter-increment: el;
|
||||
|
||||
margin: 0;
|
||||
padding: 10px 10px 10px 50px;
|
||||
border-bottom: none !important; // Sometime, we need !important :).
|
||||
|
||||
& + .cmb-repeat-row {
|
||||
border-top: solid 1px $light-gray;
|
||||
}
|
||||
|
||||
&.ui-sortable-helper {
|
||||
outline: dashed 2px $light-gray !important; // Sometime, we need !important :).
|
||||
}
|
||||
|
||||
&:before {
|
||||
content: counter(el);
|
||||
display: block;
|
||||
|
||||
top: 0;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
|
||||
width: 35px;
|
||||
height: 100%;
|
||||
line-height: 35px;
|
||||
cursor: move;
|
||||
color: $gray;
|
||||
text-align: center;
|
||||
border-right: solid 1px $light-gray;
|
||||
}
|
||||
|
||||
.cmb-td {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+ .cmb-add-row {
|
||||
margin: 0;
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
width: 1px;
|
||||
height: 1.6em;
|
||||
display: block;
|
||||
margin-left: 17px;
|
||||
background-color: darken($light-gray, 5%);
|
||||
}
|
||||
}
|
||||
|
||||
.cmb-remove-row {
|
||||
top: 7px;
|
||||
right: 7px;
|
||||
position: absolute;
|
||||
|
||||
width: auto;
|
||||
margin-left: 0;
|
||||
padding: 0 !important; // Sometime, we need !important :).
|
||||
|
||||
display: none;
|
||||
|
||||
> .cmb-remove-row-button {
|
||||
font-size: 20px;
|
||||
text-indent: -1000px;
|
||||
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
|
||||
height: auto;
|
||||
line-height: 1;
|
||||
padding: 0 10px 0;
|
||||
|
||||
&:before {
|
||||
@include pseudo-dashicons("\f335");
|
||||
line-height: 1.3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cmb-repeat-row:hover .cmb-remove-row {
|
||||
display: block;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.cmb-repeatable-group {
|
||||
|
||||
.cmb-th {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.cmb-group-title {
|
||||
background-color: $light-gray;
|
||||
padding: 8px 12px 8px 2.2em;
|
||||
margin: 0 -1em;
|
||||
min-height: 1.5em;
|
||||
font-size: 14px;
|
||||
line-height: 1.4;
|
||||
|
||||
h4 {
|
||||
border: 0;
|
||||
margin: 0;
|
||||
font-size: 1.2em;
|
||||
font-weight: 500;
|
||||
padding: 0.5em 0.75em;
|
||||
}
|
||||
|
||||
.cmb-th {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.cmb-group-description .cmb-th {
|
||||
@include fullth;
|
||||
}
|
||||
|
||||
.cmb-shift-rows {
|
||||
margin-right: 1em;
|
||||
|
||||
.dashicons-arrow-up-alt2 {
|
||||
margin-top: .15em;
|
||||
}
|
||||
|
||||
.dashicons-arrow-down-alt2 {
|
||||
margin-top: .2em;
|
||||
}
|
||||
}
|
||||
|
||||
.cmb2-upload-button {
|
||||
float: right;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
p.cmb2-metabox-description {
|
||||
color: $medium-gray;
|
||||
letter-spacing: 0.01em;
|
||||
margin: 0;
|
||||
padding-top: .5em;
|
||||
}
|
||||
|
||||
span.cmb2-metabox-description {
|
||||
color: $medium-gray;
|
||||
letter-spacing: 0.01em;
|
||||
}
|
||||
|
||||
.cmb2-metabox-title {
|
||||
margin: 0 0 5px 0;
|
||||
padding: 5px 0 0 0;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.cmb-inline ul {
|
||||
padding: 4px 0 0 0;
|
||||
}
|
||||
|
||||
.cmb-inline li {
|
||||
display: inline-block;
|
||||
padding-right: 18px;
|
||||
}
|
||||
|
||||
.cmb-type-textarea-code pre {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.cmb2-media-status {
|
||||
|
||||
.img-status {
|
||||
clear: none;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
margin-right: 10px;
|
||||
width: auto;
|
||||
|
||||
img {
|
||||
max-width: 350px;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.img-status img,
|
||||
.embed-status {
|
||||
background: $lightchecker;
|
||||
border: 5px solid $white;
|
||||
outline: 1px solid $light-gray;
|
||||
box-shadow: inset 0 0 15px rgba( 0, 0, 0, 0.3 ), inset 0 0 0 1px rgba( 0, 0, 0, 0.05 );
|
||||
background-image: linear-gradient(45deg, $darkchecker 25%, transparent 25%, transparent 75%, $darkchecker 75%, $darkchecker), linear-gradient(45deg, $darkchecker 25%, transparent 25%, transparent 75%, $darkchecker 75%, $darkchecker);
|
||||
background-position: 0 0, 10px 10px;
|
||||
background-size: 20px 20px;
|
||||
border-radius: 2px;
|
||||
-moz-border-radius: 2px;
|
||||
margin: 15px 0 0 0;
|
||||
}
|
||||
|
||||
.embed-status {
|
||||
float: left;
|
||||
max-width: 800px;
|
||||
}
|
||||
|
||||
.img-status, .embed-status {
|
||||
position: relative;
|
||||
|
||||
.cmb2-remove-file-button {
|
||||
background: url(../images/ico-delete.png);
|
||||
height: 16px;
|
||||
left: -5px;
|
||||
position: absolute;
|
||||
text-indent: -9999px;
|
||||
top: -5px;
|
||||
width: 16px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.img-status {
|
||||
|
||||
.cmb2-remove-file-button {
|
||||
top: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.img-status img, .file-status > span {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&.cmb-attach-list {
|
||||
.img-status img, .file-status > span {
|
||||
cursor: move;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.cmb-type-file-list .cmb2-media-status .img-status {
|
||||
clear: none;
|
||||
vertical-align: middle;
|
||||
width: auto;
|
||||
margin-right: 10px;
|
||||
margin-bottom: 10px;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.cmb-attach-list li {
|
||||
clear: both;
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
margin-top: 5px;
|
||||
margin-bottom: 10px;
|
||||
img {
|
||||
float: left;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.cmb2-remove-wrapper {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.child-cmb2 .cmb-th {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.cmb2-indented-hierarchy {
|
||||
padding-left: 1.5em;
|
||||
}
|
||||
|
||||
@media (max-width: $mobile-break) {
|
||||
.cmb-th,
|
||||
.cmb-td,
|
||||
.cmb-th + .cmb-td {
|
||||
display: block;
|
||||
float: none;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
29
wp-content/plugins/debloat/vendor/cmb2/css/sass/partials/_misc.scss
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
/*--------------------------------------------------------------
|
||||
* Misc.
|
||||
--------------------------------------------------------------*/
|
||||
|
||||
#poststuff .cmb-repeatable-group h2 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.edit-tags-php,
|
||||
.profile-php,
|
||||
.user-edit-php {
|
||||
.cmb2-metabox-title {
|
||||
font-size: 1.4em;
|
||||
}
|
||||
}
|
||||
|
||||
.cmb2-postbox, .cmb2-no-box-wrap {
|
||||
.cmb-spinner {
|
||||
float: left;
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.cmb-spinner {
|
||||
display: none;
|
||||
&.is-active {
|
||||
display: block;
|
||||
}
|
||||
}
|
51
wp-content/plugins/debloat/vendor/cmb2/css/sass/partials/_mixins.scss
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
//--------------------------------------------------------------
|
||||
// Mixins
|
||||
//--------------------------------------------------------------
|
||||
|
||||
@mixin fullth() {
|
||||
font-size: 1.2em;
|
||||
@include _fullth;
|
||||
}
|
||||
|
||||
@mixin fullth_side() {
|
||||
|
||||
@include _fullth;
|
||||
|
||||
label {
|
||||
font-size: $font-size;
|
||||
line-height: 1.4em;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin _fullth() {
|
||||
display: block;
|
||||
float: none;
|
||||
padding-bottom: 1em;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
|
||||
label {
|
||||
display: block;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin pseudo-dashicons( $glyph: "\f333" ) {
|
||||
content: $glyph;
|
||||
font-family: 'Dashicons';
|
||||
speak: none;
|
||||
font-weight: normal;
|
||||
font-variant: normal;
|
||||
text-transform: none;
|
||||
line-height: 1;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
margin: 0;
|
||||
text-indent: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
text-align: center;
|
||||
}
|
31
wp-content/plugins/debloat/vendor/cmb2/css/sass/partials/_new_term.scss
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
/*--------------------------------------------------------------
|
||||
* New-Term Page
|
||||
--------------------------------------------------------------*/
|
||||
|
||||
#addtag {
|
||||
.cmb-th {
|
||||
float: none;
|
||||
width: auto;
|
||||
padding: 20px 0 0;
|
||||
}
|
||||
|
||||
.cmb-td {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.cmb-th + .cmb-td {
|
||||
float: none;
|
||||
}
|
||||
|
||||
select {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.cmb2-metabox {
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
.cmb-row li label {
|
||||
display: inline;
|
||||
}
|
||||
}
|
71
wp-content/plugins/debloat/vendor/cmb2/css/sass/partials/_options-page.scss
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
/*--------------------------------------------------------------
|
||||
* Options page
|
||||
--------------------------------------------------------------*/
|
||||
|
||||
.cmb2-options-page {
|
||||
max-width: 1200px;
|
||||
|
||||
&.wrap > h2 {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.cmb2-metabox > .cmb-row {
|
||||
padding: 1em;
|
||||
margin-top: -1px;
|
||||
background: $white;
|
||||
border: 1px solid $light-gray;
|
||||
box-shadow: 0 1px 1px rgba(black, 0.05);
|
||||
|
||||
> .cmb-th {
|
||||
padding: 0;
|
||||
font-weight: initial;
|
||||
}
|
||||
|
||||
> .cmb-th + .cmb-td {
|
||||
float: none;
|
||||
padding: 0 0 0 1em;
|
||||
margin-left: 200px;
|
||||
|
||||
@media (max-width: $mobile-break) {
|
||||
padding: 0;
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Title field style.
|
||||
.cmb2-wrap .cmb-type-title {
|
||||
margin-top: 1em;
|
||||
padding: 0.6em 1em;
|
||||
background-color: $almostwhite;
|
||||
|
||||
.cmb2-metabox-title {
|
||||
font-size: 12px;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.cmb2-metabox-description {
|
||||
padding-top: 0.25em;
|
||||
}
|
||||
}
|
||||
|
||||
.cmb-repeatable-group {
|
||||
.cmb-group-description .cmb-th {
|
||||
padding: 0 0 0.8em 0;
|
||||
}
|
||||
|
||||
.cmb-group-name {
|
||||
font-size: 16px;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.cmb-th > .cmb2-metabox-description {
|
||||
font-weight: 400;
|
||||
padding-bottom: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
99
wp-content/plugins/debloat/vendor/cmb2/css/sass/partials/_post_metaboxes.scss
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
/*--------------------------------------------------------------
|
||||
* Post Metaboxes
|
||||
--------------------------------------------------------------*/
|
||||
|
||||
#poststuff .cmb-group-title {
|
||||
margin-left: -1em;
|
||||
margin-right: -1em;
|
||||
min-height: 1.5em;
|
||||
}
|
||||
|
||||
#poststuff .repeatable .cmb-group-title {
|
||||
padding-left: 2.2em;
|
||||
}
|
||||
|
||||
.cmb2-postbox, .cmb-type-group {
|
||||
|
||||
.cmb2-wrap {
|
||||
margin: 0;
|
||||
|
||||
> .cmb-field-list > .cmb-row {
|
||||
padding: 1.8em 0;
|
||||
}
|
||||
|
||||
input[type=text] {
|
||||
|
||||
&.cmb2-oembed {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cmb-row {
|
||||
padding: 0 0 1.8em;
|
||||
margin: 0 0 0.8em;
|
||||
|
||||
.cmbhandle {
|
||||
right: -1em;
|
||||
position: relative;
|
||||
color: $dark-gray;
|
||||
}
|
||||
}
|
||||
|
||||
.cmb-repeatable-grouping {
|
||||
padding: 0 1em;
|
||||
max-width: 100%;
|
||||
min-width: 1px !important;
|
||||
}
|
||||
|
||||
.cmb-repeatable-group > .cmb-row {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.cmb-th {
|
||||
width: 18%;
|
||||
padding: 0 2% 0 0;
|
||||
// text-align: right;
|
||||
}
|
||||
|
||||
.cmb-td {
|
||||
margin-bottom: 0;
|
||||
padding: 0;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.cmb-th + .cmb-td {
|
||||
width: 80%;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.cmb-row:not(:last-of-type),
|
||||
.cmb-repeatable-group:not(:last-of-type) {
|
||||
border-bottom: 1px solid $light-gray;
|
||||
|
||||
@media (max-width: $mobile-break) {
|
||||
border-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.cmb-repeat-group-field,
|
||||
.cmb-remove-field-row {
|
||||
padding-top: 1.8em;
|
||||
}
|
||||
|
||||
.button-secondary {
|
||||
.dashicons {
|
||||
line-height: 1.3;
|
||||
}
|
||||
&.move-up, &.move-down {
|
||||
.dashicons {
|
||||
line-height: 1.1;
|
||||
}
|
||||
}
|
||||
&.cmb-add-group-row {
|
||||
.dashicons {
|
||||
line-height: 1.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
146
wp-content/plugins/debloat/vendor/cmb2/css/sass/partials/_sidebar_placements.scss
vendored
Normal file
@@ -0,0 +1,146 @@
|
||||
/*--------------------------------------------------------------
|
||||
* Sidebar Placement Adjustments
|
||||
--------------------------------------------------------------*/
|
||||
|
||||
.inner-sidebar,
|
||||
#side-sortables {
|
||||
|
||||
.cmb2-wrap {
|
||||
|
||||
> .cmb-field-list > .cmb-row {
|
||||
padding: 1.4em 0;
|
||||
}
|
||||
|
||||
input {
|
||||
|
||||
&[type=text]:not( .wp-color-picker ) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
+ input:not( .wp-picker-clear ), + select {
|
||||
margin-left: 0;
|
||||
margin-top: 1em;
|
||||
display: block;
|
||||
}
|
||||
|
||||
&.cmb2-text-money {
|
||||
max-width: 70%;
|
||||
+ .cmb2-metabox-description {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
label {
|
||||
display: block;
|
||||
font-weight: 700;
|
||||
padding: 0 0 5px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
textarea {
|
||||
max-width: 99%;
|
||||
}
|
||||
|
||||
.cmb-repeatable-group {
|
||||
border-bottom: 1px solid $light-gray;
|
||||
}
|
||||
|
||||
.cmb-type-group > .cmb-td > .cmb-repeatable-group {
|
||||
border-bottom: 0;
|
||||
margin-bottom: -1.4em;
|
||||
}
|
||||
|
||||
.cmb-th,
|
||||
.cmb-td:not(.cmb-remove-row),
|
||||
.cmb-th + .cmb-td {
|
||||
width: 100%;
|
||||
display: block;
|
||||
float: none;
|
||||
}
|
||||
|
||||
.closed .inside {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.cmb-th {
|
||||
@include fullth_side;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.cmb-group-description {
|
||||
.cmb-th {
|
||||
padding-top: 0;
|
||||
}
|
||||
.cmb2-metabox-description {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.cmb-group-title {
|
||||
// padding-bottom: 0;
|
||||
.cmb-th {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.cmb-repeatable-grouping {
|
||||
+ .cmb-repeatable-grouping {
|
||||
margin-top: 1em;
|
||||
}
|
||||
}
|
||||
.cmb2-media-status {
|
||||
|
||||
.img-status,
|
||||
.embed-status {
|
||||
|
||||
img {
|
||||
max-width: 90%;
|
||||
// width: auto;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cmb2-list label {
|
||||
display: inline;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.cmb2-metabox-description {
|
||||
display: block;
|
||||
padding: 7px 0 0;
|
||||
}
|
||||
|
||||
.cmb-type-checkbox {
|
||||
|
||||
.cmb-td label,
|
||||
.cmb2-metabox-description {
|
||||
font-weight: normal;
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
|
||||
.cmb-row .cmb2-metabox-description {
|
||||
padding-bottom: 1.8em;
|
||||
}
|
||||
|
||||
.cmb2-metabox-title {
|
||||
font-size: 1.2em;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.cmb-remove-row {
|
||||
clear: both;
|
||||
padding-top: 12px;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.cmb2-upload-button {
|
||||
clear: both;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
}
|
26
wp-content/plugins/debloat/vendor/cmb2/css/sass/partials/_variables.scss
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
//--------------------------------------------------------------
|
||||
// Variables
|
||||
//--------------------------------------------------------------
|
||||
|
||||
// Mobile break-point
|
||||
$mobile-break : 450px;
|
||||
|
||||
// Fonts
|
||||
$font-sans : sans-serif;
|
||||
$font-serif : Georgia, Times, "Times New Roman", serif;
|
||||
$font-mono : "Courier 10 Pitch", Courier, monospace;
|
||||
$font-size : 14px;
|
||||
|
||||
// Colors
|
||||
$dark-gray : #222222;
|
||||
$gray : #757575;
|
||||
$medium-gray : #666;
|
||||
$light-gray : #e9e9e9;
|
||||
$lightchecker : #eee;
|
||||
$darkchecker : #d0d0d0;
|
||||
$blue : #0063ce;
|
||||
$light-yellow : #fffff8;
|
||||
$white : #ffffff;
|
||||
$almostwhite : #fafafa;
|
||||
$red : #f00;
|
||||
$dark-red : #a00;
|
2
wp-content/plugins/debloat/vendor/cmb2/css/sass/partials/index.php
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
<?php
|
||||
// Silence is golden
|
807
wp-content/plugins/debloat/vendor/cmb2/example-functions.php
vendored
Normal file
@@ -0,0 +1,807 @@
|
||||
<?php
|
||||
/**
|
||||
* Include and setup custom metaboxes and fields. (make sure you copy this file to outside the CMB2 directory)
|
||||
*
|
||||
* Be sure to replace all instances of 'yourprefix_' with your project's prefix.
|
||||
* http://nacin.com/2010/05/11/in-wordpress-prefix-everything/
|
||||
*
|
||||
* @category YourThemeOrPlugin
|
||||
* @package Demo_CMB2
|
||||
* @license http://www.opensource.org/licenses/gpl-license.php GPL v2.0 (or later)
|
||||
* @link https://github.com/CMB2/CMB2
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the bootstrap! If using the plugin from wordpress.org, REMOVE THIS!
|
||||
*/
|
||||
|
||||
if ( file_exists( dirname( __FILE__ ) . '/cmb2/init.php' ) ) {
|
||||
require_once dirname( __FILE__ ) . '/cmb2/init.php';
|
||||
} elseif ( file_exists( dirname( __FILE__ ) . '/CMB2/init.php' ) ) {
|
||||
require_once dirname( __FILE__ ) . '/CMB2/init.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Conditionally displays a metabox when used as a callback in the 'show_on_cb' cmb2_box parameter
|
||||
*
|
||||
* @param CMB2 $cmb CMB2 object.
|
||||
*
|
||||
* @return bool True if metabox should show
|
||||
*/
|
||||
function yourprefix_show_if_front_page( $cmb ) {
|
||||
// Don't show this metabox if it's not the front page template.
|
||||
if ( get_option( 'page_on_front' ) !== $cmb->object_id ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Conditionally displays a field when used as a callback in the 'show_on_cb' field parameter
|
||||
*
|
||||
* @param CMB2_Field $field Field object.
|
||||
*
|
||||
* @return bool True if metabox should show
|
||||
*/
|
||||
function yourprefix_hide_if_no_cats( $field ) {
|
||||
// Don't show this field if not in the cats category.
|
||||
if ( ! has_tag( 'cats', $field->object_id ) ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Manually render a field.
|
||||
*
|
||||
* @param array $field_args Array of field arguments.
|
||||
* @param CMB2_Field $field The field object.
|
||||
*/
|
||||
function yourprefix_render_row_cb( $field_args, $field ) {
|
||||
$classes = $field->row_classes();
|
||||
$id = $field->args( 'id' );
|
||||
$label = $field->args( 'name' );
|
||||
$name = $field->args( '_name' );
|
||||
$value = $field->escaped_value();
|
||||
$description = $field->args( 'description' );
|
||||
?>
|
||||
<div class="custom-field-row <?php echo esc_attr( $classes ); ?>">
|
||||
<p><label for="<?php echo esc_attr( $id ); ?>"><?php echo esc_html( $label ); ?></label></p>
|
||||
<p><input id="<?php echo esc_attr( $id ); ?>" type="text" name="<?php echo esc_attr( $name ); ?>" value="<?php echo $value; ?>"/></p>
|
||||
<p class="description"><?php echo esc_html( $description ); ?></p>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Manually render a field column display.
|
||||
*
|
||||
* @param array $field_args Array of field arguments.
|
||||
* @param CMB2_Field $field The field object.
|
||||
*/
|
||||
function yourprefix_display_text_small_column( $field_args, $field ) {
|
||||
?>
|
||||
<div class="custom-column-display <?php echo esc_attr( $field->row_classes() ); ?>">
|
||||
<p><?php echo $field->escaped_value(); ?></p>
|
||||
<p class="description"><?php echo esc_html( $field->args( 'description' ) ); ?></p>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Conditionally displays a message if the $post_id is 2
|
||||
*
|
||||
* @param array $field_args Array of field parameters.
|
||||
* @param CMB2_Field $field Field object.
|
||||
*/
|
||||
function yourprefix_before_row_if_2( $field_args, $field ) {
|
||||
if ( 2 == $field->object_id ) {
|
||||
echo '<p>Testing <b>"before_row"</b> parameter (on $post_id 2)</p>';
|
||||
} else {
|
||||
echo '<p>Testing <b>"before_row"</b> parameter (<b>NOT</b> on $post_id 2)</p>';
|
||||
}
|
||||
}
|
||||
|
||||
add_action( 'cmb2_admin_init', 'yourprefix_register_demo_metabox' );
|
||||
/**
|
||||
* Hook in and add a demo metabox. Can only happen on the 'cmb2_admin_init' or 'cmb2_init' hook.
|
||||
*/
|
||||
function yourprefix_register_demo_metabox() {
|
||||
/**
|
||||
* Sample metabox to demonstrate each field type included
|
||||
*/
|
||||
$cmb_demo = new_cmb2_box( array(
|
||||
'id' => 'yourprefix_demo_metabox',
|
||||
'title' => esc_html__( 'Test Metabox', 'cmb2' ),
|
||||
'object_types' => array( 'page' ), // Post type
|
||||
// 'show_on_cb' => 'yourprefix_show_if_front_page', // function should return a bool value
|
||||
// 'context' => 'normal',
|
||||
// 'priority' => 'high',
|
||||
// 'show_names' => true, // Show field names on the left
|
||||
// 'cmb_styles' => false, // false to disable the CMB stylesheet
|
||||
// 'closed' => true, // true to keep the metabox closed by default
|
||||
// 'classes' => 'extra-class', // Extra cmb2-wrap classes
|
||||
// 'classes_cb' => 'yourprefix_add_some_classes', // Add classes through a callback.
|
||||
|
||||
/*
|
||||
* The following parameter is any additional arguments passed as $callback_args
|
||||
* to add_meta_box, if/when applicable.
|
||||
*
|
||||
* CMB2 does not use these arguments in the add_meta_box callback, however, these args
|
||||
* are parsed for certain special properties, like determining Gutenberg/block-editor
|
||||
* compatibility.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* - Make sure default editor is used as metabox is not compatible with block editor
|
||||
* [ '__block_editor_compatible_meta_box' => false/true ]
|
||||
*
|
||||
* - Or declare this box exists for backwards compatibility
|
||||
* [ '__back_compat_meta_box' => false ]
|
||||
*
|
||||
* More: https://wordpress.org/gutenberg/handbook/extensibility/meta-box/
|
||||
*/
|
||||
// 'mb_callback_args' => array( '__block_editor_compatible_meta_box' => false ),
|
||||
) );
|
||||
|
||||
$cmb_demo->add_field( array(
|
||||
'name' => esc_html__( 'Test Text', 'cmb2' ),
|
||||
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
|
||||
'id' => 'yourprefix_demo_text',
|
||||
'type' => 'text',
|
||||
'show_on_cb' => 'yourprefix_hide_if_no_cats', // function should return a bool value
|
||||
// 'sanitization_cb' => 'my_custom_sanitization', // custom sanitization callback parameter
|
||||
// 'escape_cb' => 'my_custom_escaping', // custom escaping callback parameter
|
||||
// 'on_front' => false, // Optionally designate a field to wp-admin only
|
||||
// 'repeatable' => true,
|
||||
// 'column' => true, // Display field value in the admin post-listing columns
|
||||
) );
|
||||
|
||||
$cmb_demo->add_field( array(
|
||||
'name' => esc_html__( 'Test Text Small', 'cmb2' ),
|
||||
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
|
||||
'id' => 'yourprefix_demo_textsmall',
|
||||
'type' => 'text_small',
|
||||
// 'repeatable' => true,
|
||||
// 'column' => array(
|
||||
// 'name' => esc_html__( 'Column Title', 'cmb2' ), // Set the admin column title
|
||||
// 'position' => 2, // Set as the second column.
|
||||
// );
|
||||
// 'display_cb' => 'yourprefix_display_text_small_column', // Output the display of the column values through a callback.
|
||||
) );
|
||||
|
||||
$cmb_demo->add_field( array(
|
||||
'name' => esc_html__( 'Test Text Medium', 'cmb2' ),
|
||||
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
|
||||
'id' => 'yourprefix_demo_textmedium',
|
||||
'type' => 'text_medium',
|
||||
) );
|
||||
|
||||
$cmb_demo->add_field( array(
|
||||
'name' => esc_html__( 'Read-only Disabled Field', 'cmb2' ),
|
||||
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
|
||||
'id' => 'yourprefix_demo_readonly',
|
||||
'type' => 'text_medium',
|
||||
'default' => esc_attr__( 'Hey there, I\'m a read-only field', 'cmb2' ),
|
||||
'save_field' => false, // Disables the saving of this field.
|
||||
'attributes' => array(
|
||||
'disabled' => 'disabled',
|
||||
'readonly' => 'readonly',
|
||||
),
|
||||
) );
|
||||
|
||||
$cmb_demo->add_field( array(
|
||||
'name' => esc_html__( 'Custom Rendered Field', 'cmb2' ),
|
||||
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
|
||||
'id' => 'yourprefix_demo_render_row_cb',
|
||||
'type' => 'text',
|
||||
'render_row_cb' => 'yourprefix_render_row_cb',
|
||||
) );
|
||||
|
||||
$cmb_demo->add_field( array(
|
||||
'name' => esc_html__( 'Website URL', 'cmb2' ),
|
||||
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
|
||||
'id' => 'yourprefix_demo_url',
|
||||
'type' => 'text_url',
|
||||
// 'protocols' => array('http', 'https', 'ftp', 'ftps', 'mailto', 'news', 'irc', 'gopher', 'nntp', 'feed', 'telnet'), // Array of allowed protocols
|
||||
// 'repeatable' => true,
|
||||
) );
|
||||
|
||||
$cmb_demo->add_field( array(
|
||||
'name' => esc_html__( 'Test Text Email', 'cmb2' ),
|
||||
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
|
||||
'id' => 'yourprefix_demo_email',
|
||||
'type' => 'text_email',
|
||||
// 'repeatable' => true,
|
||||
) );
|
||||
|
||||
$cmb_demo->add_field( array(
|
||||
'name' => esc_html__( 'Test Time', 'cmb2' ),
|
||||
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
|
||||
'id' => 'yourprefix_demo_time',
|
||||
'type' => 'text_time',
|
||||
// 'time_format' => 'H:i', // Set to 24hr format
|
||||
) );
|
||||
|
||||
$cmb_demo->add_field( array(
|
||||
'name' => esc_html__( 'Time zone', 'cmb2' ),
|
||||
'desc' => esc_html__( 'Time zone', 'cmb2' ),
|
||||
'id' => 'yourprefix_demo_timezone',
|
||||
'type' => 'select_timezone',
|
||||
) );
|
||||
|
||||
$cmb_demo->add_field( array(
|
||||
'name' => esc_html__( 'Test Date Picker', 'cmb2' ),
|
||||
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
|
||||
'id' => 'yourprefix_demo_textdate',
|
||||
'type' => 'text_date',
|
||||
// 'date_format' => 'Y-m-d',
|
||||
) );
|
||||
|
||||
$cmb_demo->add_field( array(
|
||||
'name' => esc_html__( 'Test Date Picker (UNIX timestamp)', 'cmb2' ),
|
||||
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
|
||||
'id' => 'yourprefix_demo_textdate_timestamp',
|
||||
'type' => 'text_date_timestamp',
|
||||
// 'timezone_meta_key' => 'yourprefix_demo_timezone', // Optionally make this field honor the timezone selected in the select_timezone specified above
|
||||
) );
|
||||
|
||||
$cmb_demo->add_field( array(
|
||||
'name' => esc_html__( 'Test Date/Time Picker Combo (UNIX timestamp)', 'cmb2' ),
|
||||
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
|
||||
'id' => 'yourprefix_demo_datetime_timestamp',
|
||||
'type' => 'text_datetime_timestamp',
|
||||
) );
|
||||
|
||||
// This text_datetime_timestamp_timezone field type
|
||||
// is only compatible with PHP versions 5.3 or above.
|
||||
// Feel free to uncomment and use if your server meets the requirement
|
||||
// $cmb_demo->add_field( array(
|
||||
// 'name' => esc_html__( 'Test Date/Time Picker/Time zone Combo (serialized DateTime object)', 'cmb2' ),
|
||||
// 'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
|
||||
// 'id' => 'yourprefix_demo_datetime_timestamp_timezone',
|
||||
// 'type' => 'text_datetime_timestamp_timezone',
|
||||
// ) );
|
||||
|
||||
$cmb_demo->add_field( array(
|
||||
'name' => esc_html__( 'Test Money', 'cmb2' ),
|
||||
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
|
||||
'id' => 'yourprefix_demo_textmoney',
|
||||
'type' => 'text_money',
|
||||
// 'before_field' => '£', // override '$' symbol if needed
|
||||
// 'repeatable' => true,
|
||||
) );
|
||||
|
||||
$cmb_demo->add_field( array(
|
||||
'name' => esc_html__( 'Test Color Picker', 'cmb2' ),
|
||||
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
|
||||
'id' => 'yourprefix_demo_colorpicker',
|
||||
'type' => 'colorpicker',
|
||||
'default' => '#ffffff',
|
||||
// 'options' => array(
|
||||
// 'alpha' => true, // Make this a rgba color picker.
|
||||
// ),
|
||||
// 'attributes' => array(
|
||||
// 'data-colorpicker' => json_encode( array(
|
||||
// 'palettes' => array( '#3dd0cc', '#ff834c', '#4fa2c0', '#0bc991', ),
|
||||
// ) ),
|
||||
// ),
|
||||
) );
|
||||
|
||||
$cmb_demo->add_field( array(
|
||||
'name' => esc_html__( 'Test Text Area', 'cmb2' ),
|
||||
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
|
||||
'id' => 'yourprefix_demo_textarea',
|
||||
'type' => 'textarea',
|
||||
) );
|
||||
|
||||
$cmb_demo->add_field( array(
|
||||
'name' => esc_html__( 'Test Text Area Small', 'cmb2' ),
|
||||
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
|
||||
'id' => 'yourprefix_demo_textareasmall',
|
||||
'type' => 'textarea_small',
|
||||
) );
|
||||
|
||||
$cmb_demo->add_field( array(
|
||||
'name' => esc_html__( 'Test Text Area for Code', 'cmb2' ),
|
||||
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
|
||||
'id' => 'yourprefix_demo_textarea_code',
|
||||
'type' => 'textarea_code',
|
||||
// 'attributes' => array(
|
||||
// // Optionally override the code editor defaults.
|
||||
// 'data-codeeditor' => json_encode( array(
|
||||
// 'codemirror' => array(
|
||||
// 'lineNumbers' => false,
|
||||
// 'mode' => 'css',
|
||||
// ),
|
||||
// ) ),
|
||||
// ),
|
||||
// To keep the previous formatting, you can disable codemirror.
|
||||
// 'options' => array( 'disable_codemirror' => true ),
|
||||
) );
|
||||
|
||||
$cmb_demo->add_field( array(
|
||||
'name' => esc_html__( 'Test Title Weeeee', 'cmb2' ),
|
||||
'desc' => esc_html__( 'This is a title description', 'cmb2' ),
|
||||
'id' => 'yourprefix_demo_title',
|
||||
'type' => 'title',
|
||||
) );
|
||||
|
||||
$cmb_demo->add_field( array(
|
||||
'name' => esc_html__( 'Test Select', 'cmb2' ),
|
||||
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
|
||||
'id' => 'yourprefix_demo_select',
|
||||
'type' => 'select',
|
||||
'show_option_none' => true,
|
||||
'options' => array(
|
||||
'standard' => esc_html__( 'Option One', 'cmb2' ),
|
||||
'custom' => esc_html__( 'Option Two', 'cmb2' ),
|
||||
'none' => esc_html__( 'Option Three', 'cmb2' ),
|
||||
),
|
||||
) );
|
||||
|
||||
$cmb_demo->add_field( array(
|
||||
'name' => esc_html__( 'Test Radio inline', 'cmb2' ),
|
||||
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
|
||||
'id' => 'yourprefix_demo_radio_inline',
|
||||
'type' => 'radio_inline',
|
||||
'show_option_none' => 'No Selection',
|
||||
'options' => array(
|
||||
'standard' => esc_html__( 'Option One', 'cmb2' ),
|
||||
'custom' => esc_html__( 'Option Two', 'cmb2' ),
|
||||
'none' => esc_html__( 'Option Three', 'cmb2' ),
|
||||
),
|
||||
) );
|
||||
|
||||
$cmb_demo->add_field( array(
|
||||
'name' => esc_html__( 'Test Radio', 'cmb2' ),
|
||||
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
|
||||
'id' => 'yourprefix_demo_radio',
|
||||
'type' => 'radio',
|
||||
'options' => array(
|
||||
'option1' => esc_html__( 'Option One', 'cmb2' ),
|
||||
'option2' => esc_html__( 'Option Two', 'cmb2' ),
|
||||
'option3' => esc_html__( 'Option Three', 'cmb2' ),
|
||||
),
|
||||
) );
|
||||
|
||||
$cmb_demo->add_field( array(
|
||||
'name' => esc_html__( 'Test Taxonomy Radio', 'cmb2' ),
|
||||
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
|
||||
'id' => 'yourprefix_demo_text_taxonomy_radio',
|
||||
'type' => 'taxonomy_radio', // Or `taxonomy_radio_inline`/`taxonomy_radio_hierarchical`
|
||||
'taxonomy' => 'category', // Taxonomy Slug
|
||||
// 'inline' => true, // Toggles display to inline
|
||||
// Optionally override the args sent to the WordPress get_terms function.
|
||||
'query_args' => array(
|
||||
// 'orderby' => 'slug',
|
||||
// 'hide_empty' => true,
|
||||
),
|
||||
) );
|
||||
|
||||
$cmb_demo->add_field( array(
|
||||
'name' => esc_html__( 'Test Taxonomy Select', 'cmb2' ),
|
||||
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
|
||||
'id' => 'yourprefix_demo_taxonomy_select',
|
||||
'type' => 'taxonomy_select', // Or `taxonomy_select_hierarchical`
|
||||
'taxonomy' => 'category', // Taxonomy Slug
|
||||
) );
|
||||
|
||||
$cmb_demo->add_field( array(
|
||||
'name' => esc_html__( 'Test Taxonomy Multi Checkbox', 'cmb2' ),
|
||||
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
|
||||
'id' => 'yourprefix_demo_multitaxonomy',
|
||||
'type' => 'taxonomy_multicheck', // Or `taxonomy_multicheck_inline`/`taxonomy_multicheck_hierarchical`
|
||||
'taxonomy' => 'post_tag', // Taxonomy Slug
|
||||
// 'inline' => true, // Toggles display to inline
|
||||
) );
|
||||
|
||||
$cmb_demo->add_field( array(
|
||||
'name' => esc_html__( 'Test Checkbox', 'cmb2' ),
|
||||
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
|
||||
'id' => 'yourprefix_demo_checkbox',
|
||||
'type' => 'checkbox',
|
||||
) );
|
||||
|
||||
$cmb_demo->add_field( array(
|
||||
'name' => esc_html__( 'Test Multi Checkbox', 'cmb2' ),
|
||||
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
|
||||
'id' => 'yourprefix_demo_multicheckbox',
|
||||
'type' => 'multicheck',
|
||||
// 'multiple' => true, // Store values in individual rows
|
||||
'options' => array(
|
||||
'check1' => esc_html__( 'Check One', 'cmb2' ),
|
||||
'check2' => esc_html__( 'Check Two', 'cmb2' ),
|
||||
'check3' => esc_html__( 'Check Three', 'cmb2' ),
|
||||
),
|
||||
// 'inline' => true, // Toggles display to inline
|
||||
) );
|
||||
|
||||
$cmb_demo->add_field( array(
|
||||
'name' => esc_html__( 'Test wysiwyg', 'cmb2' ),
|
||||
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
|
||||
'id' => 'yourprefix_demo_wysiwyg',
|
||||
'type' => 'wysiwyg',
|
||||
'options' => array(
|
||||
'textarea_rows' => 5,
|
||||
),
|
||||
) );
|
||||
|
||||
$cmb_demo->add_field( array(
|
||||
'name' => esc_html__( 'Test Image', 'cmb2' ),
|
||||
'desc' => esc_html__( 'Upload an image or enter a URL.', 'cmb2' ),
|
||||
'id' => 'yourprefix_demo_image',
|
||||
'type' => 'file',
|
||||
) );
|
||||
|
||||
$cmb_demo->add_field( array(
|
||||
'name' => esc_html__( 'Multiple Files', 'cmb2' ),
|
||||
'desc' => esc_html__( 'Upload or add multiple images/attachments.', 'cmb2' ),
|
||||
'id' => 'yourprefix_demo_file_list',
|
||||
'type' => 'file_list',
|
||||
'preview_size' => array( 100, 100 ), // Default: array( 50, 50 )
|
||||
) );
|
||||
|
||||
$cmb_demo->add_field( array(
|
||||
'name' => esc_html__( 'oEmbed', 'cmb2' ),
|
||||
'desc' => sprintf(
|
||||
/* translators: %s: link to codex.wordpress.org/Embeds */
|
||||
esc_html__( 'Enter a youtube, twitter, or instagram URL. Supports services listed at %s.', 'cmb2' ),
|
||||
'<a href="https://wordpress.org/support/article/embeds/">codex.wordpress.org/Embeds</a>'
|
||||
),
|
||||
'id' => 'yourprefix_demo_embed',
|
||||
'type' => 'oembed',
|
||||
) );
|
||||
|
||||
$cmb_demo->add_field( array(
|
||||
'name' => 'Testing Field Parameters',
|
||||
'id' => 'yourprefix_demo_parameters',
|
||||
'type' => 'text',
|
||||
'before_row' => 'yourprefix_before_row_if_2', // callback.
|
||||
'before' => '<p>Testing <b>"before"</b> parameter</p>',
|
||||
'before_field' => '<p>Testing <b>"before_field"</b> parameter</p>',
|
||||
'after_field' => '<p>Testing <b>"after_field"</b> parameter</p>',
|
||||
'after' => '<p>Testing <b>"after"</b> parameter</p>',
|
||||
'after_row' => '<p>Testing <b>"after_row"</b> parameter</p>',
|
||||
) );
|
||||
|
||||
}
|
||||
|
||||
add_action( 'cmb2_admin_init', 'yourprefix_register_about_page_metabox' );
|
||||
/**
|
||||
* Hook in and add a metabox that only appears on the 'About' page
|
||||
*/
|
||||
function yourprefix_register_about_page_metabox() {
|
||||
|
||||
/**
|
||||
* Metabox to be displayed on a single page ID
|
||||
*/
|
||||
$cmb_about_page = new_cmb2_box( array(
|
||||
'id' => 'yourprefix_about_metabox',
|
||||
'title' => esc_html__( 'About Page Metabox', 'cmb2' ),
|
||||
'object_types' => array( 'page' ), // Post type
|
||||
'context' => 'normal',
|
||||
'priority' => 'high',
|
||||
'show_names' => true, // Show field names on the left
|
||||
'show_on' => array(
|
||||
'id' => array( 2 ),
|
||||
), // Specific post IDs to display this metabox
|
||||
) );
|
||||
|
||||
$cmb_about_page->add_field( array(
|
||||
'name' => esc_html__( 'Test Text', 'cmb2' ),
|
||||
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
|
||||
'id' => 'yourprefix_about_text',
|
||||
'type' => 'text',
|
||||
) );
|
||||
|
||||
}
|
||||
|
||||
add_action( 'cmb2_admin_init', 'yourprefix_register_repeatable_group_field_metabox' );
|
||||
/**
|
||||
* Hook in and add a metabox to demonstrate repeatable grouped fields
|
||||
*/
|
||||
function yourprefix_register_repeatable_group_field_metabox() {
|
||||
|
||||
/**
|
||||
* Repeatable Field Groups
|
||||
*/
|
||||
$cmb_group = new_cmb2_box( array(
|
||||
'id' => 'yourprefix_group_metabox',
|
||||
'title' => esc_html__( 'Repeating Field Group', 'cmb2' ),
|
||||
'object_types' => array( 'page' ),
|
||||
) );
|
||||
|
||||
// $group_field_id is the field id string, so in this case: 'yourprefix_group_demo'
|
||||
$group_field_id = $cmb_group->add_field( array(
|
||||
'id' => 'yourprefix_group_demo',
|
||||
'type' => 'group',
|
||||
'description' => esc_html__( 'Generates reusable form entries', 'cmb2' ),
|
||||
'options' => array(
|
||||
'group_title' => esc_html__( 'Entry {#}', 'cmb2' ), // {#} gets replaced by row number
|
||||
'add_button' => esc_html__( 'Add Another Entry', 'cmb2' ),
|
||||
'remove_button' => esc_html__( 'Remove Entry', 'cmb2' ),
|
||||
'sortable' => true,
|
||||
// 'closed' => true, // true to have the groups closed by default
|
||||
// 'remove_confirm' => esc_html__( 'Are you sure you want to remove?', 'cmb2' ), // Performs confirmation before removing group.
|
||||
),
|
||||
) );
|
||||
|
||||
/**
|
||||
* Group fields works the same, except ids only need
|
||||
* to be unique to the group. Prefix is not needed.
|
||||
*
|
||||
* The parent field's id needs to be passed as the first argument.
|
||||
*/
|
||||
$cmb_group->add_group_field( $group_field_id, array(
|
||||
'name' => esc_html__( 'Entry Title', 'cmb2' ),
|
||||
'id' => 'title',
|
||||
'type' => 'text',
|
||||
// 'repeatable' => true, // Repeatable fields are supported w/in repeatable groups (for most types)
|
||||
) );
|
||||
|
||||
$cmb_group->add_group_field( $group_field_id, array(
|
||||
'name' => esc_html__( 'Description', 'cmb2' ),
|
||||
'description' => esc_html__( 'Write a short description for this entry', 'cmb2' ),
|
||||
'id' => 'description',
|
||||
'type' => 'textarea_small',
|
||||
) );
|
||||
|
||||
$cmb_group->add_group_field( $group_field_id, array(
|
||||
'name' => esc_html__( 'Entry Image', 'cmb2' ),
|
||||
'id' => 'image',
|
||||
'type' => 'file',
|
||||
) );
|
||||
|
||||
$cmb_group->add_group_field( $group_field_id, array(
|
||||
'name' => esc_html__( 'Image Caption', 'cmb2' ),
|
||||
'id' => 'image_caption',
|
||||
'type' => 'text',
|
||||
) );
|
||||
|
||||
}
|
||||
|
||||
add_action( 'cmb2_admin_init', 'yourprefix_register_user_profile_metabox' );
|
||||
/**
|
||||
* Hook in and add a metabox to add fields to the user profile pages
|
||||
*/
|
||||
function yourprefix_register_user_profile_metabox() {
|
||||
|
||||
/**
|
||||
* Metabox for the user profile screen
|
||||
*/
|
||||
$cmb_user = new_cmb2_box( array(
|
||||
'id' => 'yourprefix_user_edit',
|
||||
'title' => esc_html__( 'User Profile Metabox', 'cmb2' ), // Doesn't output for user boxes
|
||||
'object_types' => array( 'user' ), // Tells CMB2 to use user_meta vs post_meta
|
||||
'show_names' => true,
|
||||
'new_user_section' => 'add-new-user', // where form will show on new user page. 'add-existing-user' is only other valid option.
|
||||
) );
|
||||
|
||||
$cmb_user->add_field( array(
|
||||
'name' => esc_html__( 'Extra Info', 'cmb2' ),
|
||||
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
|
||||
'id' => 'yourprefix_user_extra_info',
|
||||
'type' => 'title',
|
||||
'on_front' => false,
|
||||
) );
|
||||
|
||||
$cmb_user->add_field( array(
|
||||
'name' => esc_html__( 'Avatar', 'cmb2' ),
|
||||
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
|
||||
'id' => 'yourprefix_user_avatar',
|
||||
'type' => 'file',
|
||||
) );
|
||||
|
||||
$cmb_user->add_field( array(
|
||||
'name' => esc_html__( 'Facebook URL', 'cmb2' ),
|
||||
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
|
||||
'id' => 'yourprefix_user_facebookurl',
|
||||
'type' => 'text_url',
|
||||
) );
|
||||
|
||||
$cmb_user->add_field( array(
|
||||
'name' => esc_html__( 'Twitter URL', 'cmb2' ),
|
||||
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
|
||||
'id' => 'yourprefix_user_twitterurl',
|
||||
'type' => 'text_url',
|
||||
) );
|
||||
|
||||
$cmb_user->add_field( array(
|
||||
'name' => esc_html__( 'Google+ URL', 'cmb2' ),
|
||||
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
|
||||
'id' => 'yourprefix_user_googleplusurl',
|
||||
'type' => 'text_url',
|
||||
) );
|
||||
|
||||
$cmb_user->add_field( array(
|
||||
'name' => esc_html__( 'Linkedin URL', 'cmb2' ),
|
||||
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
|
||||
'id' => 'yourprefix_user_linkedinurl',
|
||||
'type' => 'text_url',
|
||||
) );
|
||||
|
||||
$cmb_user->add_field( array(
|
||||
'name' => esc_html__( 'User Field', 'cmb2' ),
|
||||
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
|
||||
'id' => 'yourprefix_user_user_text_field',
|
||||
'type' => 'text',
|
||||
) );
|
||||
|
||||
}
|
||||
|
||||
add_action( 'cmb2_admin_init', 'yourprefix_register_taxonomy_metabox' );
|
||||
/**
|
||||
* Hook in and add a metabox to add fields to taxonomy terms
|
||||
*/
|
||||
function yourprefix_register_taxonomy_metabox() {
|
||||
|
||||
/**
|
||||
* Metabox to add fields to categories and tags
|
||||
*/
|
||||
$cmb_term = new_cmb2_box( array(
|
||||
'id' => 'yourprefix_term_edit',
|
||||
'title' => esc_html__( 'Category Metabox', 'cmb2' ), // Doesn't output for term boxes
|
||||
'object_types' => array( 'term' ), // Tells CMB2 to use term_meta vs post_meta
|
||||
'taxonomies' => array( 'category', 'post_tag' ), // Tells CMB2 which taxonomies should have these fields
|
||||
// 'new_term_section' => true, // Will display in the "Add New Category" section
|
||||
) );
|
||||
|
||||
$cmb_term->add_field( array(
|
||||
'name' => esc_html__( 'Extra Info', 'cmb2' ),
|
||||
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
|
||||
'id' => 'yourprefix_term_extra_info',
|
||||
'type' => 'title',
|
||||
'on_front' => false,
|
||||
) );
|
||||
|
||||
$cmb_term->add_field( array(
|
||||
'name' => esc_html__( 'Term Image', 'cmb2' ),
|
||||
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
|
||||
'id' => 'yourprefix_term_avatar',
|
||||
'type' => 'file',
|
||||
) );
|
||||
|
||||
$cmb_term->add_field( array(
|
||||
'name' => esc_html__( 'Arbitrary Term Field', 'cmb2' ),
|
||||
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
|
||||
'id' => 'yourprefix_term_term_text_field',
|
||||
'type' => 'text',
|
||||
) );
|
||||
|
||||
}
|
||||
|
||||
add_action( 'cmb2_admin_init', 'yourprefix_register_theme_options_metabox' );
|
||||
/**
|
||||
* Hook in and register a metabox to handle a theme options page and adds a menu item.
|
||||
*/
|
||||
function yourprefix_register_theme_options_metabox() {
|
||||
|
||||
/**
|
||||
* Registers options page menu item and form.
|
||||
*/
|
||||
$cmb_options = new_cmb2_box( array(
|
||||
'id' => 'yourprefix_theme_options_page',
|
||||
'title' => esc_html__( 'Theme Options', 'cmb2' ),
|
||||
'object_types' => array( 'options-page' ),
|
||||
|
||||
/*
|
||||
* The following parameters are specific to the options-page box
|
||||
* Several of these parameters are passed along to add_menu_page()/add_submenu_page().
|
||||
*/
|
||||
|
||||
'option_key' => 'yourprefix_theme_options', // The option key and admin menu page slug.
|
||||
'icon_url' => 'dashicons-palmtree', // Menu icon. Only applicable if 'parent_slug' is left empty.
|
||||
// 'menu_title' => esc_html__( 'Options', 'cmb2' ), // Falls back to 'title' (above).
|
||||
// 'parent_slug' => 'themes.php', // Make options page a submenu item of the themes menu.
|
||||
// 'capability' => 'manage_options', // Cap required to view options-page.
|
||||
// 'position' => 1, // Menu position. Only applicable if 'parent_slug' is left empty.
|
||||
// 'admin_menu_hook' => 'network_admin_menu', // 'network_admin_menu' to add network-level options page.
|
||||
// 'priority' => 10, // Define the page-registration admin menu hook priority.
|
||||
// 'display_cb' => false, // Override the options-page form output (CMB2_Hookup::options_page_output()).
|
||||
// 'save_button' => esc_html__( 'Save Theme Options', 'cmb2' ), // The text for the options-page save button. Defaults to 'Save'.
|
||||
// 'disable_settings_errors' => true, // On settings pages (not options-general.php sub-pages), allows disabling.
|
||||
// 'message_cb' => 'yourprefix_options_page_message_callback',
|
||||
// 'tab_group' => '', // Tab-group identifier, enables options page tab navigation.
|
||||
// 'tab_title' => null, // Falls back to 'title' (above).
|
||||
// 'autoload' => false, // Defaults to true, the options-page option will be autloaded.
|
||||
) );
|
||||
|
||||
/**
|
||||
* Options fields ids only need
|
||||
* to be unique within this box.
|
||||
* Prefix is not needed.
|
||||
*/
|
||||
$cmb_options->add_field( array(
|
||||
'name' => esc_html__( 'Site Background Color', 'cmb2' ),
|
||||
'desc' => esc_html__( 'field description (optional)', 'cmb2' ),
|
||||
'id' => 'bg_color',
|
||||
'type' => 'colorpicker',
|
||||
'default' => '#ffffff',
|
||||
) );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback to define the optionss-saved message.
|
||||
*
|
||||
* @param CMB2 $cmb The CMB2 object.
|
||||
* @param array $args {
|
||||
* An array of message arguments
|
||||
*
|
||||
* @type bool $is_options_page Whether current page is this options page.
|
||||
* @type bool $should_notify Whether options were saved and we should be notified.
|
||||
* @type bool $is_updated Whether options were updated with save (or stayed the same).
|
||||
* @type string $setting For add_settings_error(), Slug title of the setting to which
|
||||
* this error applies.
|
||||
* @type string $code For add_settings_error(), Slug-name to identify the error.
|
||||
* Used as part of 'id' attribute in HTML output.
|
||||
* @type string $message For add_settings_error(), The formatted message text to display
|
||||
* to the user (will be shown inside styled `<div>` and `<p>` tags).
|
||||
* Will be 'Settings updated.' if $is_updated is true, else 'Nothing to update.'
|
||||
* @type string $type For add_settings_error(), Message type, controls HTML class.
|
||||
* Accepts 'error', 'updated', '', 'notice-warning', etc.
|
||||
* Will be 'updated' if $is_updated is true, else 'notice-warning'.
|
||||
* }
|
||||
*/
|
||||
function yourprefix_options_page_message_callback( $cmb, $args ) {
|
||||
if ( ! empty( $args['should_notify'] ) ) {
|
||||
|
||||
if ( $args['is_updated'] ) {
|
||||
|
||||
// Modify the updated message.
|
||||
$args['message'] = sprintf( esc_html__( '%s — Updated!', 'cmb2' ), $cmb->prop( 'title' ) );
|
||||
}
|
||||
|
||||
add_settings_error( $args['setting'], $args['code'], $args['message'], $args['type'] );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Only show this box in the CMB2 REST API if the user is logged in.
|
||||
*
|
||||
* @param bool $is_allowed Whether this box and its fields are allowed to be viewed.
|
||||
* @param CMB2_REST_Controller $cmb_controller The controller object.
|
||||
* CMB2 object available via `$cmb_controller->rest_box->cmb`.
|
||||
*
|
||||
* @return bool Whether this box and its fields are allowed to be viewed.
|
||||
*/
|
||||
function yourprefix_limit_rest_view_to_logged_in_users( $is_allowed, $cmb_controller ) {
|
||||
if ( ! is_user_logged_in() ) {
|
||||
$is_allowed = false;
|
||||
}
|
||||
|
||||
return $is_allowed;
|
||||
}
|
||||
|
||||
add_action( 'cmb2_init', 'yourprefix_register_rest_api_box' );
|
||||
/**
|
||||
* Hook in and add a box to be available in the CMB2 REST API. Can only happen on the 'cmb2_init' hook.
|
||||
* More info: https://github.com/CMB2/CMB2/wiki/REST-API
|
||||
*/
|
||||
function yourprefix_register_rest_api_box() {
|
||||
$cmb_rest = new_cmb2_box( array(
|
||||
'id' => 'yourprefix_rest_metabox',
|
||||
'title' => esc_html__( 'REST Test Box', 'cmb2' ),
|
||||
'object_types' => array( 'page' ), // Post type
|
||||
'show_in_rest' => WP_REST_Server::ALLMETHODS, // WP_REST_Server::READABLE|WP_REST_Server::EDITABLE, // Determines which HTTP methods the box is visible in.
|
||||
// Optional callback to limit box visibility.
|
||||
// See: https://github.com/CMB2/CMB2/wiki/REST-API#permissions
|
||||
// 'get_box_permissions_check_cb' => 'yourprefix_limit_rest_view_to_logged_in_users',
|
||||
) );
|
||||
|
||||
$cmb_rest->add_field( array(
|
||||
'name' => esc_html__( 'REST Test Text', 'cmb2' ),
|
||||
'desc' => esc_html__( 'Will show in the REST API for this box and for pages.', 'cmb2' ),
|
||||
'id' => 'yourprefix_rest_text',
|
||||
'type' => 'text',
|
||||
) );
|
||||
|
||||
$cmb_rest->add_field( array(
|
||||
'name' => esc_html__( 'REST Editable Test Text', 'cmb2' ),
|
||||
'desc' => esc_html__( 'Will show in REST API "editable" contexts only (`POST` requests).', 'cmb2' ),
|
||||
'id' => 'yourprefix_rest_editable_text',
|
||||
'type' => 'text',
|
||||
'show_in_rest' => WP_REST_Server::EDITABLE,// WP_REST_Server::ALLMETHODS|WP_REST_Server::READABLE, // Determines which HTTP methods the field is visible in. Will override the cmb2_box 'show_in_rest' param.
|
||||
) );
|
||||
}
|
BIN
wp-content/plugins/debloat/vendor/cmb2/images/ico-delete.png
vendored
Normal file
After Width: | Height: | Size: 715 B |
2
wp-content/plugins/debloat/vendor/cmb2/images/index.php
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
<?php
|
||||
// Silence is golden
|
BIN
wp-content/plugins/debloat/vendor/cmb2/images/ui-bg_flat_0_aaaaaa_40x100.png
vendored
Normal file
After Width: | Height: | Size: 180 B |
BIN
wp-content/plugins/debloat/vendor/cmb2/images/ui-bg_flat_75_ffffff_40x100.png
vendored
Normal file
After Width: | Height: | Size: 178 B |
BIN
wp-content/plugins/debloat/vendor/cmb2/images/ui-bg_glass_55_fbf9ee_1x400.png
vendored
Normal file
After Width: | Height: | Size: 120 B |
BIN
wp-content/plugins/debloat/vendor/cmb2/images/ui-bg_glass_65_ffffff_1x400.png
vendored
Normal file
After Width: | Height: | Size: 105 B |
BIN
wp-content/plugins/debloat/vendor/cmb2/images/ui-bg_glass_75_dadada_1x400.png
vendored
Normal file
After Width: | Height: | Size: 111 B |
BIN
wp-content/plugins/debloat/vendor/cmb2/images/ui-bg_glass_75_e6e6e6_1x400.png
vendored
Normal file
After Width: | Height: | Size: 110 B |
BIN
wp-content/plugins/debloat/vendor/cmb2/images/ui-bg_glass_95_fef1ec_1x400.png
vendored
Normal file
After Width: | Height: | Size: 119 B |
BIN
wp-content/plugins/debloat/vendor/cmb2/images/ui-bg_highlight-soft_75_cccccc_1x100.png
vendored
Normal file
After Width: | Height: | Size: 101 B |
BIN
wp-content/plugins/debloat/vendor/cmb2/images/ui-icons_222222_256x240.png
vendored
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
wp-content/plugins/debloat/vendor/cmb2/images/ui-icons_2e83ff_256x240.png
vendored
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
wp-content/plugins/debloat/vendor/cmb2/images/ui-icons_454545_256x240.png
vendored
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
wp-content/plugins/debloat/vendor/cmb2/images/ui-icons_888888_256x240.png
vendored
Normal file
After Width: | Height: | Size: 5.2 KiB |
BIN
wp-content/plugins/debloat/vendor/cmb2/images/ui-icons_cd0a0a_256x240.png
vendored
Normal file
After Width: | Height: | Size: 4.3 KiB |
1817
wp-content/plugins/debloat/vendor/cmb2/includes/CMB2.php
vendored
Normal file
323
wp-content/plugins/debloat/vendor/cmb2/includes/CMB2_Ajax.php
vendored
Normal file
@@ -0,0 +1,323 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* CMB2 ajax methods
|
||||
* (i.e. a lot of work to get oEmbeds to work with non-post objects)
|
||||
*
|
||||
* @since 0.9.5
|
||||
*
|
||||
* @category WordPress_Plugin
|
||||
* @package CMB2
|
||||
* @author CMB2 team
|
||||
* @license GPL-2.0+
|
||||
*/
|
||||
class CMB2_Ajax {
|
||||
|
||||
// Whether to hijack the oembed cache system.
|
||||
protected $hijack = false;
|
||||
protected $object_id = 0;
|
||||
protected $embed_args = array();
|
||||
protected $object_type = 'post';
|
||||
protected $ajax_update = false;
|
||||
|
||||
/**
|
||||
* Instance of this class.
|
||||
*
|
||||
* @since 2.2.2
|
||||
* @var object
|
||||
*/
|
||||
protected static $instance;
|
||||
|
||||
/**
|
||||
* Get the singleton instance of this class.
|
||||
*
|
||||
* @since 2.2.2
|
||||
* @return CMB2_Ajax
|
||||
*/
|
||||
public static function get_instance() {
|
||||
if ( ! ( self::$instance instanceof self ) ) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @since 2.2.0
|
||||
*/
|
||||
protected function __construct() {
|
||||
add_action( 'wp_ajax_cmb2_oembed_handler', array( $this, 'oembed_handler' ) );
|
||||
add_action( 'wp_ajax_nopriv_cmb2_oembed_handler', array( $this, 'oembed_handler' ) );
|
||||
// Need to occasionally clean stale oembed cache data from the option value.
|
||||
add_action( 'cmb2_save_options-page_fields', array( __CLASS__, 'clean_stale_options_page_oembeds' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles our oEmbed ajax request
|
||||
*
|
||||
* @since 0.9.5
|
||||
* @return mixed oEmbed embed code | fallback | error message
|
||||
*/
|
||||
public function oembed_handler() {
|
||||
|
||||
// Verify our nonce.
|
||||
if ( ! ( isset( $_REQUEST['cmb2_ajax_nonce'], $_REQUEST['oembed_url'] ) && wp_verify_nonce( $_REQUEST['cmb2_ajax_nonce'], 'ajax_nonce' ) ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
// Sanitize our search string.
|
||||
$oembed_string = sanitize_text_field( $_REQUEST['oembed_url'] );
|
||||
|
||||
// Send back error if empty.
|
||||
if ( empty( $oembed_string ) ) {
|
||||
wp_send_json_error( '<p class="ui-state-error-text">' . esc_html__( 'Please Try Again', 'cmb2' ) . '</p>' );
|
||||
}
|
||||
|
||||
// Set width of embed.
|
||||
$embed_width = isset( $_REQUEST['oembed_width'] ) && intval( $_REQUEST['oembed_width'] ) < 640 ? intval( $_REQUEST['oembed_width'] ) : '640';
|
||||
|
||||
// Set url.
|
||||
$oembed_url = esc_url( $oembed_string );
|
||||
|
||||
// Set args.
|
||||
$embed_args = array(
|
||||
'width' => $embed_width,
|
||||
);
|
||||
|
||||
$this->ajax_update = true;
|
||||
|
||||
// Get embed code (or fallback link).
|
||||
$html = $this->get_oembed( array(
|
||||
'url' => $oembed_url,
|
||||
'object_id' => $_REQUEST['object_id'],
|
||||
'object_type' => isset( $_REQUEST['object_type'] ) ? $_REQUEST['object_type'] : 'post',
|
||||
'oembed_args' => $embed_args,
|
||||
'field_id' => $_REQUEST['field_id'],
|
||||
) );
|
||||
|
||||
wp_send_json_success( $html );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves oEmbed from url/object ID
|
||||
*
|
||||
* @since 0.9.5
|
||||
* @param array $args Arguments for method.
|
||||
* @return mixed HTML markup with embed or fallback.
|
||||
*/
|
||||
public function get_oembed_no_edit( $args ) {
|
||||
global $wp_embed;
|
||||
|
||||
$oembed_url = esc_url( $args['url'] );
|
||||
|
||||
// Sanitize object_id.
|
||||
$this->object_id = is_numeric( $args['object_id'] ) ? absint( $args['object_id'] ) : sanitize_text_field( $args['object_id'] );
|
||||
|
||||
$args = wp_parse_args( $args, array(
|
||||
'object_type' => 'post',
|
||||
'oembed_args' => array(),
|
||||
'field_id' => false,
|
||||
'wp_error' => false,
|
||||
) );
|
||||
|
||||
$this->embed_args =& $args;
|
||||
|
||||
/*
|
||||
* Set the post_ID so oEmbed won't fail
|
||||
* wp-includes/class-wp-embed.php, WP_Embed::shortcode()
|
||||
*/
|
||||
$wp_embed->post_ID = $this->object_id;
|
||||
|
||||
// Special scenario if NOT a post object.
|
||||
if ( isset( $args['object_type'] ) && 'post' != $args['object_type'] ) {
|
||||
|
||||
if ( 'options-page' == $args['object_type'] ) {
|
||||
|
||||
// Bogus id to pass some numeric checks. Issue with a VERY large WP install?
|
||||
$wp_embed->post_ID = 1987645321;
|
||||
}
|
||||
|
||||
// Ok, we need to hijack the oembed cache system.
|
||||
$this->hijack = true;
|
||||
$this->object_type = $args['object_type'];
|
||||
|
||||
// Gets ombed cache from our object's meta (vs postmeta).
|
||||
add_filter( 'get_post_metadata', array( $this, 'hijack_oembed_cache_get' ), 10, 3 );
|
||||
|
||||
// Sets ombed cache in our object's meta (vs postmeta).
|
||||
add_filter( 'update_post_metadata', array( $this, 'hijack_oembed_cache_set' ), 10, 4 );
|
||||
|
||||
}
|
||||
|
||||
$embed_args = '';
|
||||
|
||||
foreach ( $args['oembed_args'] as $key => $val ) {
|
||||
$embed_args .= " $key=\"$val\"";
|
||||
}
|
||||
|
||||
// Ping WordPress for an embed.
|
||||
$embed = $wp_embed->run_shortcode( '[embed' . $embed_args . ']' . $oembed_url . '[/embed]' );
|
||||
|
||||
// Fallback that WordPress creates when no oEmbed was found.
|
||||
$fallback = $wp_embed->maybe_make_link( $oembed_url );
|
||||
|
||||
return compact( 'embed', 'fallback', 'args' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves oEmbed from url/object ID
|
||||
*
|
||||
* @since 0.9.5
|
||||
* @param array $args Arguments for method.
|
||||
* @return string HTML markup with embed or fallback.
|
||||
*/
|
||||
public function get_oembed( $args ) {
|
||||
$oembed = $this->get_oembed_no_edit( $args );
|
||||
|
||||
// Send back our embed.
|
||||
if ( $oembed['embed'] && $oembed['embed'] != $oembed['fallback'] ) {
|
||||
return '<div class="cmb2-oembed embed-status">' . $oembed['embed'] . '<p class="cmb2-remove-wrapper"><a href="#" class="cmb2-remove-file-button" rel="' . $oembed['args']['field_id'] . '">' . esc_html__( 'Remove Embed', 'cmb2' ) . '</a></p></div>';
|
||||
}
|
||||
|
||||
// Otherwise, send back error info that no oEmbeds were found.
|
||||
return sprintf(
|
||||
'<p class="ui-state-error-text">%s</p>',
|
||||
sprintf(
|
||||
/* translators: 1: results for. 2: link to codex.wordpress.org/Embeds */
|
||||
esc_html__( 'No oEmbed Results Found for %1$s. View more info at %2$s.', 'cmb2' ),
|
||||
$oembed['fallback'],
|
||||
'<a href="https://wordpress.org/support/article/embeds/" target="_blank">codex.wordpress.org/Embeds</a>'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hijacks retrieving of cached oEmbed.
|
||||
* Returns cached data from relevant object metadata (vs postmeta)
|
||||
*
|
||||
* @since 0.9.5
|
||||
* @param boolean $check Whether to retrieve postmeta or override.
|
||||
* @param int $object_id Object ID.
|
||||
* @param string $meta_key Object metakey.
|
||||
* @return mixed Object's oEmbed cached data.
|
||||
*/
|
||||
public function hijack_oembed_cache_get( $check, $object_id, $meta_key ) {
|
||||
if ( ! $this->hijack || ( $this->object_id != $object_id && 1987645321 !== $object_id ) ) {
|
||||
return $check;
|
||||
}
|
||||
|
||||
if ( $this->ajax_update ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->cache_action( $meta_key );
|
||||
}
|
||||
|
||||
/**
|
||||
* Hijacks saving of cached oEmbed.
|
||||
* Saves cached data to relevant object metadata (vs postmeta)
|
||||
*
|
||||
* @since 0.9.5
|
||||
* @param boolean $check Whether to continue setting postmeta.
|
||||
* @param int $object_id Object ID to get postmeta from.
|
||||
* @param string $meta_key Postmeta's key.
|
||||
* @param mixed $meta_value Value of the postmeta to be saved.
|
||||
* @return boolean Whether to continue setting.
|
||||
*/
|
||||
public function hijack_oembed_cache_set( $check, $object_id, $meta_key, $meta_value ) {
|
||||
|
||||
if (
|
||||
! $this->hijack
|
||||
|| ( $this->object_id != $object_id && 1987645321 !== $object_id )
|
||||
// Only want to hijack oembed meta values.
|
||||
|| 0 !== strpos( $meta_key, '_oembed_' )
|
||||
) {
|
||||
return $check;
|
||||
}
|
||||
|
||||
$this->cache_action( $meta_key, $meta_value );
|
||||
|
||||
// Anything other than `null` to cancel saving to postmeta.
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets/updates the cached oEmbed value from/to relevant object metadata (vs postmeta).
|
||||
*
|
||||
* @since 1.3.0
|
||||
*
|
||||
* @param string $meta_key Postmeta's key.
|
||||
* @return mixed
|
||||
*/
|
||||
protected function cache_action( $meta_key ) {
|
||||
$func_args = func_get_args();
|
||||
$action = isset( $func_args[1] ) ? 'update' : 'get';
|
||||
|
||||
if ( 'options-page' === $this->object_type ) {
|
||||
|
||||
$args = array( $meta_key );
|
||||
|
||||
if ( 'update' === $action ) {
|
||||
$args[] = $func_args[1];
|
||||
$args[] = true;
|
||||
}
|
||||
|
||||
// Cache the result to our options.
|
||||
$status = call_user_func_array( array( cmb2_options( $this->object_id ), $action ), $args );
|
||||
} else {
|
||||
|
||||
$args = array( $this->object_type, $this->object_id, $meta_key );
|
||||
$args[] = 'update' === $action ? $func_args[1] : true;
|
||||
|
||||
// Cache the result to our metadata.
|
||||
$status = call_user_func_array( $action . '_metadata', $args );
|
||||
}
|
||||
|
||||
return $status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hooks in when options-page data is saved to clean stale
|
||||
* oembed cache data from the option value.
|
||||
*
|
||||
* @since 2.2.0
|
||||
* @param string $option_key The options-page option key.
|
||||
* @return void
|
||||
*/
|
||||
public static function clean_stale_options_page_oembeds( $option_key ) {
|
||||
$options = cmb2_options( $option_key )->get_options();
|
||||
$modified = false;
|
||||
if ( is_array( $options ) ) {
|
||||
|
||||
$ttl = apply_filters( 'oembed_ttl', DAY_IN_SECONDS, '', array(), 0 );
|
||||
$now = time();
|
||||
|
||||
foreach ( $options as $key => $value ) {
|
||||
// Check for cached oembed data.
|
||||
if ( 0 === strpos( $key, '_oembed_time_' ) ) {
|
||||
$cached_recently = ( $now - $value ) < $ttl;
|
||||
|
||||
if ( ! $cached_recently ) {
|
||||
$modified = true;
|
||||
// Remove the the cached ttl expiration, and the cached oembed value.
|
||||
unset( $options[ $key ] );
|
||||
unset( $options[ str_replace( '_oembed_time_', '_oembed_', $key ) ] );
|
||||
}
|
||||
} // End if.
|
||||
// Remove the cached unknown values.
|
||||
elseif ( '{{unknown}}' === $value ) {
|
||||
$modified = true;
|
||||
unset( $options[ $key ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update the option and remove stale cache data.
|
||||
if ( $modified ) {
|
||||
$updated = cmb2_options( $option_key )->set( $options );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
534
wp-content/plugins/debloat/vendor/cmb2/includes/CMB2_Base.php
vendored
Normal file
@@ -0,0 +1,534 @@
|
||||
<?php
|
||||
/**
|
||||
* CMB2 Base - Base object functionality.
|
||||
*
|
||||
* @category WordPress_Plugin
|
||||
* @package CMB2
|
||||
* @author CMB2 team
|
||||
* @license GPL-2.0+
|
||||
* @link https://cmb2.io
|
||||
*
|
||||
* @property-read $args The objects array of properties/arguments.
|
||||
* @property-read $meta_box The objects array of properties/arguments.
|
||||
* @property-read $properties The objects array of properties/arguments.
|
||||
* @property-read $cmb_id Current CMB2 instance ID
|
||||
* @property-read $object_id Object ID
|
||||
* @property-read $object_type Type of object being handled. (e.g., post, user, comment, or term)
|
||||
*/
|
||||
abstract class CMB2_Base {
|
||||
|
||||
/**
|
||||
* Current CMB2 instance ID
|
||||
*
|
||||
* @var string
|
||||
* @since 2.2.3
|
||||
*/
|
||||
protected $cmb_id = '';
|
||||
|
||||
/**
|
||||
* The object properties name.
|
||||
*
|
||||
* @var string
|
||||
* @since 2.2.3
|
||||
*/
|
||||
protected $properties_name = 'meta_box';
|
||||
|
||||
/**
|
||||
* Object ID
|
||||
*
|
||||
* @var mixed
|
||||
* @since 2.2.3
|
||||
*/
|
||||
protected $object_id = 0;
|
||||
|
||||
/**
|
||||
* Type of object being handled. (e.g., post, user, comment, or term)
|
||||
*
|
||||
* @var string
|
||||
* @since 2.2.3
|
||||
*/
|
||||
protected $object_type = '';
|
||||
|
||||
/**
|
||||
* Array of key => value data for saving. Likely $_POST data.
|
||||
*
|
||||
* @var array
|
||||
* @since 2.2.3
|
||||
*/
|
||||
public $data_to_save = array();
|
||||
|
||||
/**
|
||||
* Array of field param callback results
|
||||
*
|
||||
* @var array
|
||||
* @since 2.0.0
|
||||
*/
|
||||
protected $callback_results = array();
|
||||
|
||||
/**
|
||||
* The deprecated_param method deprecated param message signature.
|
||||
*/
|
||||
const DEPRECATED_PARAM = 1;
|
||||
|
||||
/**
|
||||
* The deprecated_param method deprecated callback param message signature.
|
||||
*/
|
||||
const DEPRECATED_CB_PARAM = 2;
|
||||
|
||||
/**
|
||||
* Get started
|
||||
*
|
||||
* @since 2.2.3
|
||||
* @param array $args Object properties array.
|
||||
*/
|
||||
public function __construct( $args = array() ) {
|
||||
if ( ! empty( $args ) ) {
|
||||
foreach ( array(
|
||||
'cmb_id',
|
||||
'properties_name',
|
||||
'object_id',
|
||||
'object_type',
|
||||
'data_to_save',
|
||||
) as $object_prop ) {
|
||||
if ( isset( $args[ $object_prop ] ) ) {
|
||||
$this->{$object_prop} = $args[ $object_prop ];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the object ID
|
||||
*
|
||||
* @since 2.2.3
|
||||
* @param integer $object_id Object ID.
|
||||
* @return integer Object ID
|
||||
*/
|
||||
public function object_id( $object_id = 0 ) {
|
||||
if ( $object_id ) {
|
||||
$this->object_id = $object_id;
|
||||
}
|
||||
|
||||
return $this->object_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the object type
|
||||
*
|
||||
* @since 2.2.3
|
||||
* @param string $object_type Object Type.
|
||||
* @return string Object type
|
||||
*/
|
||||
public function object_type( $object_type = '' ) {
|
||||
if ( $object_type ) {
|
||||
$this->object_type = $object_type;
|
||||
}
|
||||
|
||||
return $this->object_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the object type for the current page, based on the $pagenow global.
|
||||
*
|
||||
* @since 2.2.2
|
||||
* @return string Page object type name.
|
||||
*/
|
||||
public function current_object_type() {
|
||||
global $pagenow;
|
||||
$type = 'post';
|
||||
|
||||
if ( in_array( $pagenow, array( 'user-edit.php', 'profile.php', 'user-new.php' ), true ) ) {
|
||||
$type = 'user';
|
||||
}
|
||||
|
||||
if ( in_array( $pagenow, array( 'edit-comments.php', 'comment.php' ), true ) ) {
|
||||
$type = 'comment';
|
||||
}
|
||||
|
||||
if ( in_array( $pagenow, array( 'edit-tags.php', 'term.php' ), true ) ) {
|
||||
$type = 'term';
|
||||
}
|
||||
|
||||
return $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set object property.
|
||||
*
|
||||
* @since 2.2.2
|
||||
* @param string $property Metabox config property to retrieve.
|
||||
* @param mixed $value Value to set if no value found.
|
||||
* @return mixed Metabox config property value or false.
|
||||
*/
|
||||
public function set_prop( $property, $value ) {
|
||||
$this->{$this->properties_name}[ $property ] = $value;
|
||||
|
||||
return $this->prop( $property );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get object property and optionally set a fallback
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @param string $property Metabox config property to retrieve.
|
||||
* @param mixed $fallback Fallback value to set if no value found.
|
||||
* @return mixed Metabox config property value or false
|
||||
*/
|
||||
public function prop( $property, $fallback = null ) {
|
||||
if ( array_key_exists( $property, $this->{$this->properties_name} ) ) {
|
||||
return $this->{$this->properties_name}[ $property ];
|
||||
} elseif ( $fallback ) {
|
||||
return $this->{$this->properties_name}[ $property ] = $fallback;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default field arguments specific to this CMB2 object.
|
||||
*
|
||||
* @since 2.2.0
|
||||
* @param array $field_args Metabox field config array.
|
||||
* @param CMB2_Field $field_group (optional) CMB2_Field object (group parent).
|
||||
* @return array Array of field arguments.
|
||||
*/
|
||||
protected function get_default_args( $field_args, $field_group = null ) {
|
||||
if ( $field_group ) {
|
||||
$args = array(
|
||||
'field_args' => $field_args,
|
||||
'group_field' => $field_group,
|
||||
);
|
||||
} else {
|
||||
$args = array(
|
||||
'field_args' => $field_args,
|
||||
'object_type' => $this->object_type(),
|
||||
'object_id' => $this->object_id(),
|
||||
'cmb_id' => $this->cmb_id,
|
||||
);
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a new field object specific to this CMB2 object.
|
||||
*
|
||||
* @since 2.2.0
|
||||
* @param array $field_args Metabox field config array.
|
||||
* @param CMB2_Field $field_group (optional) CMB2_Field object (group parent).
|
||||
* @return CMB2_Field CMB2_Field object
|
||||
*/
|
||||
protected function get_new_field( $field_args, $field_group = null ) {
|
||||
return new CMB2_Field( $this->get_default_args( $field_args, $field_group ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether this cmb object should show, based on the 'show_on_cb' callback.
|
||||
*
|
||||
* @since 2.0.9
|
||||
*
|
||||
* @return bool Whether this cmb should be shown.
|
||||
*/
|
||||
public function should_show() {
|
||||
// Default to showing this cmb
|
||||
$show = true;
|
||||
|
||||
// Use the callback to determine showing the cmb, if it exists.
|
||||
if ( is_callable( $this->prop( 'show_on_cb' ) ) ) {
|
||||
$show = (bool) call_user_func( $this->prop( 'show_on_cb' ), $this );
|
||||
}
|
||||
|
||||
return $show;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the results of the param callbacks.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @param string $param Field parameter.
|
||||
*/
|
||||
public function peform_param_callback( $param ) {
|
||||
echo $this->get_param_callback_result( $param );
|
||||
}
|
||||
|
||||
/**
|
||||
* Store results of the param callbacks for continual access
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @param string $param Field parameter.
|
||||
* @return mixed Results of param/param callback
|
||||
*/
|
||||
public function get_param_callback_result( $param ) {
|
||||
|
||||
// If we've already retrieved this param's value.
|
||||
if ( array_key_exists( $param, $this->callback_results ) ) {
|
||||
|
||||
// Send it back.
|
||||
return $this->callback_results[ $param ];
|
||||
}
|
||||
|
||||
// Check if parameter has registered a callback.
|
||||
if ( $cb = $this->maybe_callback( $param ) ) {
|
||||
|
||||
// Ok, callback is good, let's run it and store the result.
|
||||
ob_start();
|
||||
$returned = $this->do_callback( $cb );
|
||||
|
||||
// Grab the result from the output buffer and store it.
|
||||
$echoed = ob_get_clean();
|
||||
|
||||
// This checks if the user returned or echoed their callback.
|
||||
// Defaults to using the echoed value.
|
||||
$this->callback_results[ $param ] = $echoed ? $echoed : $returned;
|
||||
|
||||
} else {
|
||||
|
||||
// Otherwise just get whatever is there.
|
||||
$this->callback_results[ $param ] = isset( $this->{$this->properties_name}[ $param ] ) ? $this->{$this->properties_name}[ $param ] : false;
|
||||
}
|
||||
|
||||
return $this->callback_results[ $param ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Unset the cached results of the param callback.
|
||||
*
|
||||
* @since 2.2.6
|
||||
* @param string $param Field parameter.
|
||||
* @return CMB2_Base
|
||||
*/
|
||||
public function unset_param_callback_cache( $param ) {
|
||||
if ( isset( $this->callback_results[ $param ] ) ) {
|
||||
unset( $this->callback_results[ $param ] );
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the parameter callbacks, and passes this object as parameter.
|
||||
*
|
||||
* @since 2.2.3
|
||||
* @param callable $cb The callback method/function/closure.
|
||||
* @param mixed $additional_params Any additoinal parameters which should be passed to the callback.
|
||||
* @return mixed Return of the callback function.
|
||||
*/
|
||||
protected function do_callback( $cb, $additional_params = null ) {
|
||||
return call_user_func( $cb, $this->{$this->properties_name}, $this, $additional_params );
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if field has a callback value
|
||||
*
|
||||
* @since 1.0.1
|
||||
* @param string $cb Callback string.
|
||||
* @return mixed NULL, false for NO validation, or $cb string if it exists.
|
||||
*/
|
||||
public function maybe_callback( $cb ) {
|
||||
$args = $this->{$this->properties_name};
|
||||
if ( ! isset( $args[ $cb ] ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Check if requesting explicitly false.
|
||||
$cb = false !== $args[ $cb ] && 'false' !== $args[ $cb ] ? $args[ $cb ] : false;
|
||||
|
||||
// If requesting NO validation, return false.
|
||||
if ( ! $cb ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( is_callable( $cb ) ) {
|
||||
return $cb;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this object has parameter corresponding to the given filter
|
||||
* which is callable. If so, it registers the callback, and if not,
|
||||
* converts the maybe-modified $val to a boolean for return.
|
||||
*
|
||||
* The registered handlers will have a parameter name which matches the filter, except:
|
||||
* - The 'cmb2_api' prefix will be removed
|
||||
* - A '_cb' suffix will be added (to stay inline with other '*_cb' parameters).
|
||||
*
|
||||
* @since 2.2.3
|
||||
*
|
||||
* @param string $hook_name The hook name.
|
||||
* @param bool $val The default value.
|
||||
* @param string $hook_function The hook function. Default: 'add_filter'.
|
||||
*
|
||||
* @return null|bool Null if hook is registered, or bool for value.
|
||||
*/
|
||||
public function maybe_hook_parameter( $hook_name, $val = null, $hook_function = 'add_filter' ) {
|
||||
|
||||
// Remove filter prefix, add param suffix.
|
||||
$parameter = substr( $hook_name, strlen( 'cmb2_api_' ) ) . '_cb';
|
||||
|
||||
return self::maybe_hook(
|
||||
$this->prop( $parameter, $val ),
|
||||
$hook_name,
|
||||
$hook_function
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if given value is callable, and registers the callback.
|
||||
* If is non-callable, converts the $val to a boolean for return.
|
||||
*
|
||||
* @since 2.2.3
|
||||
*
|
||||
* @param bool $val The default value.
|
||||
* @param string $hook_name The hook name.
|
||||
* @param string $hook_function The hook function.
|
||||
*
|
||||
* @return null|bool Null if hook is registered, or bool for value.
|
||||
*/
|
||||
public static function maybe_hook( $val, $hook_name, $hook_function ) {
|
||||
if ( is_callable( $val ) ) {
|
||||
call_user_func( $hook_function, $hook_name, $val, 10, 2 );
|
||||
return null;
|
||||
}
|
||||
|
||||
// Cast to bool.
|
||||
return ! ! $val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark a param as deprecated and inform when it has been used.
|
||||
*
|
||||
* There is a default WordPress hook deprecated_argument_run that will be called
|
||||
* that can be used to get the backtrace up to what file and function used the
|
||||
* deprecated argument.
|
||||
*
|
||||
* The current behavior is to trigger a user error if WP_DEBUG is true.
|
||||
*
|
||||
* @since 2.2.3
|
||||
*
|
||||
* @param string $function The function that was called.
|
||||
* @param string $version The version of CMB2 that deprecated the argument used.
|
||||
* @param string $message Optional. A message regarding the change, or numeric
|
||||
* key to generate message from additional arguments.
|
||||
* Default null.
|
||||
*/
|
||||
protected function deprecated_param( $function, $version, $message = null ) {
|
||||
|
||||
$args = func_get_args();
|
||||
|
||||
if ( is_numeric( $message ) ) {
|
||||
|
||||
switch ( $message ) {
|
||||
|
||||
case self::DEPRECATED_PARAM:
|
||||
$message = sprintf( __( 'The "%1$s" field parameter has been deprecated in favor of the "%2$s" parameter.', 'cmb2' ), $args[3], $args[4] );
|
||||
break;
|
||||
|
||||
case self::DEPRECATED_CB_PARAM:
|
||||
$message = sprintf( __( 'Using the "%1$s" field parameter as a callback has been deprecated in favor of the "%2$s" parameter.', 'cmb2' ), $args[3], $args[4] );
|
||||
break;
|
||||
|
||||
default:
|
||||
$message = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires when a deprecated argument is called. This is a WP core action.
|
||||
*
|
||||
* @since 2.2.3
|
||||
*
|
||||
* @param string $function The function that was called.
|
||||
* @param string $message A message regarding the change.
|
||||
* @param string $version The version of CMB2 that deprecated the argument used.
|
||||
*/
|
||||
do_action( 'deprecated_argument_run', $function, $message, $version );
|
||||
|
||||
/**
|
||||
* Filters whether to trigger an error for deprecated arguments. This is a WP core filter.
|
||||
*
|
||||
* @since 2.2.3
|
||||
*
|
||||
* @param bool $trigger Whether to trigger the error for deprecated arguments. Default true.
|
||||
*/
|
||||
if ( defined( 'WP_DEBUG' ) && WP_DEBUG && apply_filters( 'deprecated_argument_trigger_error', true ) ) {
|
||||
if ( function_exists( '__' ) ) {
|
||||
if ( ! is_null( $message ) ) {
|
||||
trigger_error( sprintf( __( '%1$s was called with a parameter that is <strong>deprecated</strong> since version %2$s! %3$s', 'cmb2' ), $function, $version, $message ) );
|
||||
} else {
|
||||
trigger_error( sprintf( __( '%1$s was called with a parameter that is <strong>deprecated</strong> since version %2$s with no alternative available.', 'cmb2' ), $function, $version ) );
|
||||
}
|
||||
} else {
|
||||
if ( ! is_null( $message ) ) {
|
||||
trigger_error( sprintf( '%1$s was called with a parameter that is <strong>deprecated</strong> since version %2$s! %3$s', $function, $version, $message ) );
|
||||
} else {
|
||||
trigger_error( sprintf( '%1$s was called with a parameter that is <strong>deprecated</strong> since version %2$s with no alternative available.', $function, $version ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic getter for our object.
|
||||
*
|
||||
* @param string $field Requested property.
|
||||
* @throws Exception Throws an exception if the field is invalid.
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get( $field ) {
|
||||
switch ( $field ) {
|
||||
case 'args':
|
||||
case 'meta_box':
|
||||
if ( $field === $this->properties_name ) {
|
||||
return $this->{$this->properties_name};
|
||||
}
|
||||
case 'properties':
|
||||
return $this->{$this->properties_name};
|
||||
case 'cmb_id':
|
||||
case 'object_id':
|
||||
case 'object_type':
|
||||
return $this->{$field};
|
||||
default:
|
||||
throw new Exception( sprintf( esc_html__( 'Invalid %1$s property: %2$s', 'cmb2' ), __CLASS__, $field ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows overloading the object with methods... Whooaaa oooh it's magic, y'knoooow.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @throws Exception Invalid method exception.
|
||||
*
|
||||
* @param string $method Non-existent method.
|
||||
* @param array $args All arguments passed to the method.
|
||||
* @return mixed
|
||||
*/
|
||||
public function __call( $method, $args ) {
|
||||
$object_class = strtolower( get_class( $this ) );
|
||||
|
||||
if ( ! has_filter( "{$object_class}_inherit_{$method}" ) ) {
|
||||
throw new Exception( sprintf( esc_html__( 'Invalid %1$s method: %2$s', 'cmb2' ), get_class( $this ), $method ) );
|
||||
}
|
||||
|
||||
array_unshift( $args, $this );
|
||||
|
||||
/**
|
||||
* Allows overloading the object (CMB2 or CMB2_Field) with additional capabilities
|
||||
* by registering hook callbacks.
|
||||
*
|
||||
* The first dynamic portion of the hook name, $object_class, refers to the object class,
|
||||
* either cmb2 or cmb2_field.
|
||||
*
|
||||
* The second dynamic portion of the hook name, $method, is the non-existent method being
|
||||
* called on the object. To avoid possible future methods encroaching on your hooks,
|
||||
* use a unique method (aka, $cmb->prefix_my_method()).
|
||||
*
|
||||
* When registering your callback, you will need to ensure that you register the correct
|
||||
* number of `$accepted_args`, accounting for this object instance being the first argument.
|
||||
*
|
||||
* @param array $args The arguments to be passed to the hook.
|
||||
* The first argument will always be this object instance.
|
||||
*/
|
||||
return apply_filters_ref_array( "{$object_class}_inherit_{$method}", $args );
|
||||
}
|
||||
}
|
139
wp-content/plugins/debloat/vendor/cmb2/includes/CMB2_Boxes.php
vendored
Normal file
@@ -0,0 +1,139 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* A CMB2 object instance registry for storing every CMB2 instance.
|
||||
*
|
||||
* @category WordPress_Plugin
|
||||
* @package CMB2
|
||||
* @author CMB2 team
|
||||
* @license GPL-2.0+
|
||||
* @link https://cmb2.io
|
||||
*/
|
||||
class CMB2_Boxes {
|
||||
|
||||
/**
|
||||
* Array of all metabox objects.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @var array
|
||||
*/
|
||||
protected static $cmb2_instances = array();
|
||||
|
||||
/**
|
||||
* Add a CMB2 instance object to the registry.
|
||||
*
|
||||
* @since 1.X.X
|
||||
*
|
||||
* @param CMB2 $cmb_instance CMB2 instance.
|
||||
*/
|
||||
public static function add( CMB2 $cmb_instance ) {
|
||||
self::$cmb2_instances[ $cmb_instance->cmb_id ] = $cmb_instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a CMB2 instance object from the registry.
|
||||
*
|
||||
* @since 1.X.X
|
||||
*
|
||||
* @param string $cmb_id A CMB2 instance id.
|
||||
*/
|
||||
public static function remove( $cmb_id ) {
|
||||
if ( array_key_exists( $cmb_id, self::$cmb2_instances ) ) {
|
||||
unset( self::$cmb2_instances[ $cmb_id ] );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a CMB2 instance by cmb id.
|
||||
*
|
||||
* @since 1.X.X
|
||||
*
|
||||
* @param string $cmb_id A CMB2 instance id.
|
||||
*
|
||||
* @return CMB2|bool False or CMB2 object instance.
|
||||
*/
|
||||
public static function get( $cmb_id ) {
|
||||
if ( empty( self::$cmb2_instances ) || empty( self::$cmb2_instances[ $cmb_id ] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return self::$cmb2_instances[ $cmb_id ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve all CMB2 instances registered.
|
||||
*
|
||||
* @since 1.X.X
|
||||
* @return CMB2[] Array of all registered cmb2 instances.
|
||||
*/
|
||||
public static function get_all() {
|
||||
return self::$cmb2_instances;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve all CMB2 instances that have the specified property set.
|
||||
*
|
||||
* @since 2.4.0
|
||||
* @param string $property Property name.
|
||||
* @param mixed $compare (Optional) The value to compare.
|
||||
* @return CMB2[] Array of matching cmb2 instances.
|
||||
*/
|
||||
public static function get_by( $property, $compare = 'nocompare' ) {
|
||||
$boxes = array();
|
||||
|
||||
foreach ( self::$cmb2_instances as $cmb_id => $cmb ) {
|
||||
$prop = $cmb->prop( $property );
|
||||
|
||||
if ( 'nocompare' === $compare ) {
|
||||
if ( ! empty( $prop ) ) {
|
||||
$boxes[ $cmb_id ] = $cmb;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( $compare === $prop ) {
|
||||
$boxes[ $cmb_id ] = $cmb;
|
||||
}
|
||||
}
|
||||
|
||||
return $boxes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve all CMB2 instances as long as they do not include the ignored property.
|
||||
*
|
||||
* @since 2.4.0
|
||||
* @param string $property Property name.
|
||||
* @param mixed $to_ignore The value to ignore.
|
||||
* @return CMB2[] Array of matching cmb2 instances.
|
||||
*/
|
||||
public static function filter_by( $property, $to_ignore = null ) {
|
||||
$boxes = array();
|
||||
|
||||
foreach ( self::$cmb2_instances as $cmb_id => $cmb ) {
|
||||
|
||||
if ( $to_ignore === $cmb->prop( $property ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$boxes[ $cmb_id ] = $cmb;
|
||||
}
|
||||
|
||||
return $boxes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated and left for back-compatibility. The original `get_by_property`
|
||||
* method was misnamed and never actually used by CMB2 core.
|
||||
*
|
||||
* @since 2.2.3
|
||||
*
|
||||
* @param string $property Property name.
|
||||
* @param mixed $to_ignore The value to ignore.
|
||||
* @return CMB2[] Array of matching cmb2 instances.
|
||||
*/
|
||||
public static function get_by_property( $property, $to_ignore = null ) {
|
||||
_deprecated_function( __METHOD__, '2.4.0', 'CMB2_Boxes::filter_by()' );
|
||||
return self::filter_by( $property );
|
||||
}
|
||||
}
|
1649
wp-content/plugins/debloat/vendor/cmb2/includes/CMB2_Field.php
vendored
Normal file
505
wp-content/plugins/debloat/vendor/cmb2/includes/CMB2_Field_Display.php
vendored
Normal file
@@ -0,0 +1,505 @@
|
||||
<?php
|
||||
/**
|
||||
* CMB2 field display base.
|
||||
*
|
||||
* @since 2.2.2
|
||||
*
|
||||
* @category WordPress_Plugin
|
||||
* @package CMB2
|
||||
* @author CMB2 team
|
||||
* @license GPL-2.0+
|
||||
* @link https://cmb2.io
|
||||
*/
|
||||
class CMB2_Field_Display {
|
||||
|
||||
/**
|
||||
* A CMB field object
|
||||
*
|
||||
* @var CMB2_Field object
|
||||
* @since 2.2.2
|
||||
*/
|
||||
public $field;
|
||||
|
||||
/**
|
||||
* The CMB field object's value.
|
||||
*
|
||||
* @var mixed
|
||||
* @since 2.2.2
|
||||
*/
|
||||
public $value;
|
||||
|
||||
/**
|
||||
* Get the corresponding display class for the field type.
|
||||
*
|
||||
* @since 2.2.2
|
||||
* @param CMB2_Field $field Requested field type.
|
||||
* @return CMB2_Field_Display
|
||||
*/
|
||||
public static function get( CMB2_Field $field ) {
|
||||
$fieldtype = $field->type();
|
||||
$display_class_name = $field->args( 'display_class' );
|
||||
|
||||
if ( empty( $display_class_name ) ) {
|
||||
switch ( $fieldtype ) {
|
||||
case 'text_url':
|
||||
$display_class_name = 'CMB2_Display_Text_Url';
|
||||
break;
|
||||
case 'text_money':
|
||||
$display_class_name = 'CMB2_Display_Text_Money';
|
||||
break;
|
||||
case 'colorpicker':
|
||||
$display_class_name = 'CMB2_Display_Colorpicker';
|
||||
break;
|
||||
case 'checkbox':
|
||||
$display_class_name = 'CMB2_Display_Checkbox';
|
||||
break;
|
||||
case 'wysiwyg':
|
||||
case 'textarea_small':
|
||||
$display_class_name = 'CMB2_Display_Textarea';
|
||||
break;
|
||||
case 'textarea_code':
|
||||
$display_class_name = 'CMB2_Display_Textarea_Code';
|
||||
break;
|
||||
case 'text_time':
|
||||
$display_class_name = 'CMB2_Display_Text_Time';
|
||||
break;
|
||||
case 'text_date':
|
||||
case 'text_date_timestamp':
|
||||
case 'text_datetime_timestamp':
|
||||
$display_class_name = 'CMB2_Display_Text_Date';
|
||||
break;
|
||||
case 'text_datetime_timestamp_timezone':
|
||||
$display_class_name = 'CMB2_Display_Text_Date_Timezone';
|
||||
break;
|
||||
case 'select':
|
||||
case 'radio':
|
||||
case 'radio_inline':
|
||||
$display_class_name = 'CMB2_Display_Select';
|
||||
break;
|
||||
case 'multicheck':
|
||||
case 'multicheck_inline':
|
||||
$display_class_name = 'CMB2_Display_Multicheck';
|
||||
break;
|
||||
case 'taxonomy_radio':
|
||||
case 'taxonomy_radio_inline':
|
||||
case 'taxonomy_select':
|
||||
case 'taxonomy_select_hierarchical':
|
||||
case 'taxonomy_radio_hierarchical':
|
||||
$display_class_name = 'CMB2_Display_Taxonomy_Radio';
|
||||
break;
|
||||
case 'taxonomy_multicheck':
|
||||
case 'taxonomy_multicheck_inline':
|
||||
case 'taxonomy_multicheck_hierarchical':
|
||||
$display_class_name = 'CMB2_Display_Taxonomy_Multicheck';
|
||||
break;
|
||||
case 'file':
|
||||
$display_class_name = 'CMB2_Display_File';
|
||||
break;
|
||||
case 'file_list':
|
||||
$display_class_name = 'CMB2_Display_File_List';
|
||||
break;
|
||||
case 'oembed':
|
||||
$display_class_name = 'CMB2_Display_oEmbed';
|
||||
break;
|
||||
default:
|
||||
$display_class_name = __CLASS__;
|
||||
break;
|
||||
}// End switch.
|
||||
}
|
||||
|
||||
if ( has_action( "cmb2_display_class_{$fieldtype}" ) ) {
|
||||
|
||||
/**
|
||||
* Filters the custom field display class used for displaying the field. Class is required to extend CMB2_Type_Base.
|
||||
*
|
||||
* The dynamic portion of the hook name, $fieldtype, refers to the (custom) field type.
|
||||
*
|
||||
* @since 2.2.4
|
||||
*
|
||||
* @param string $display_class_name The custom field display class to use.
|
||||
* @param object $field The `CMB2_Field` object.
|
||||
*/
|
||||
$display_class_name = apply_filters( "cmb2_display_class_{$fieldtype}", $display_class_name, $field );
|
||||
}
|
||||
|
||||
return new $display_class_name( $field );
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup our class vars
|
||||
*
|
||||
* @since 2.2.2
|
||||
* @param CMB2_Field $field A CMB2 field object.
|
||||
*/
|
||||
public function __construct( CMB2_Field $field ) {
|
||||
$this->field = $field;
|
||||
$this->value = $this->field->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Catchall method if field's 'display_cb' is NOT defined, or field type does
|
||||
* not have a corresponding display method
|
||||
*
|
||||
* @since 2.2.2
|
||||
*/
|
||||
public function display() {
|
||||
// If repeatable.
|
||||
if ( $this->field->args( 'repeatable' ) ) {
|
||||
|
||||
// And has a repeatable value.
|
||||
if ( is_array( $this->field->value ) ) {
|
||||
|
||||
// Then loop and output.
|
||||
echo '<ul class="cmb2-' . esc_attr( sanitize_html_class( str_replace( '_', '-', $this->field->type() ) ) ) . '">';
|
||||
foreach ( $this->field->value as $val ) {
|
||||
$this->value = $val;
|
||||
echo '<li>', $this->_display(), '</li>';
|
||||
;
|
||||
}
|
||||
echo '</ul>';
|
||||
}
|
||||
} else {
|
||||
$this->_display();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Default fallback display method.
|
||||
*
|
||||
* @since 2.2.2
|
||||
*/
|
||||
protected function _display() {
|
||||
print_r( $this->value );
|
||||
}
|
||||
}
|
||||
|
||||
class CMB2_Display_Text_Url extends CMB2_Field_Display {
|
||||
/**
|
||||
* Display url value.
|
||||
*
|
||||
* @since 2.2.2
|
||||
*/
|
||||
protected function _display() {
|
||||
echo make_clickable( esc_url( $this->value ) );
|
||||
}
|
||||
}
|
||||
|
||||
class CMB2_Display_Text_Money extends CMB2_Field_Display {
|
||||
/**
|
||||
* Display text_money value.
|
||||
*
|
||||
* @since 2.2.2
|
||||
*/
|
||||
protected function _display() {
|
||||
$this->value = $this->value ? $this->value : '0';
|
||||
echo ( ! $this->field->get_param_callback_result( 'before_field' ) ? '$' : ' ' ), $this->value;
|
||||
}
|
||||
}
|
||||
|
||||
class CMB2_Display_Colorpicker extends CMB2_Field_Display {
|
||||
/**
|
||||
* Display color picker value.
|
||||
*
|
||||
* @since 2.2.2
|
||||
*/
|
||||
protected function _display() {
|
||||
echo '<span class="cmb2-colorpicker-swatch"><span style="background-color:', esc_attr( $this->value ), '"></span> ', esc_html( $this->value ), '</span>';
|
||||
}
|
||||
}
|
||||
|
||||
class CMB2_Display_Checkbox extends CMB2_Field_Display {
|
||||
/**
|
||||
* Display multicheck value.
|
||||
*
|
||||
* @since 2.2.2
|
||||
*/
|
||||
protected function _display() {
|
||||
echo $this->value === 'on' ? 'on' : 'off';
|
||||
}
|
||||
}
|
||||
|
||||
class CMB2_Display_Select extends CMB2_Field_Display {
|
||||
/**
|
||||
* Display select value.
|
||||
*
|
||||
* @since 2.2.2
|
||||
*/
|
||||
protected function _display() {
|
||||
$options = $this->field->options();
|
||||
|
||||
$fallback = $this->field->args( 'show_option_none' );
|
||||
if ( ! $fallback && isset( $options[''] ) ) {
|
||||
$fallback = $options[''];
|
||||
}
|
||||
if ( ! $this->value && $fallback ) {
|
||||
echo $fallback;
|
||||
} elseif ( isset( $options[ $this->value ] ) ) {
|
||||
echo $options[ $this->value ];
|
||||
} else {
|
||||
echo esc_attr( $this->value );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class CMB2_Display_Multicheck extends CMB2_Field_Display {
|
||||
/**
|
||||
* Display multicheck value.
|
||||
*
|
||||
* @since 2.2.2
|
||||
*/
|
||||
protected function _display() {
|
||||
if ( empty( $this->value ) || ! is_array( $this->value ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$options = $this->field->options();
|
||||
|
||||
$output = array();
|
||||
foreach ( $this->value as $val ) {
|
||||
if ( isset( $options[ $val ] ) ) {
|
||||
$output[] = $options[ $val ];
|
||||
} else {
|
||||
$output[] = esc_attr( $val );
|
||||
}
|
||||
}
|
||||
|
||||
echo implode( ', ', $output );
|
||||
}
|
||||
}
|
||||
|
||||
class CMB2_Display_Textarea extends CMB2_Field_Display {
|
||||
/**
|
||||
* Display textarea value.
|
||||
*
|
||||
* @since 2.2.2
|
||||
*/
|
||||
protected function _display() {
|
||||
echo wpautop( wp_kses_post( $this->value ) );
|
||||
}
|
||||
}
|
||||
|
||||
class CMB2_Display_Textarea_Code extends CMB2_Field_Display {
|
||||
/**
|
||||
* Display textarea_code value.
|
||||
*
|
||||
* @since 2.2.2
|
||||
*/
|
||||
protected function _display() {
|
||||
echo '<xmp class="cmb2-code">' . print_r( $this->value, true ) . '</xmp>';
|
||||
}
|
||||
}
|
||||
|
||||
class CMB2_Display_Text_Time extends CMB2_Field_Display {
|
||||
/**
|
||||
* Display text_time value.
|
||||
*
|
||||
* @since 2.2.2
|
||||
*/
|
||||
protected function _display() {
|
||||
echo $this->field->get_timestamp_format( 'time_format', $this->value );
|
||||
}
|
||||
}
|
||||
|
||||
class CMB2_Display_Text_Date extends CMB2_Field_Display {
|
||||
/**
|
||||
* Display text_date value.
|
||||
*
|
||||
* @since 2.2.2
|
||||
*/
|
||||
protected function _display() {
|
||||
echo $this->field->get_timestamp_format( 'date_format', $this->value );
|
||||
}
|
||||
}
|
||||
|
||||
class CMB2_Display_Text_Date_Timezone extends CMB2_Field_Display {
|
||||
/**
|
||||
* Display text_datetime_timestamp_timezone value.
|
||||
*
|
||||
* @since 2.2.2
|
||||
*/
|
||||
protected function _display() {
|
||||
$field = $this->field;
|
||||
|
||||
if ( empty( $this->value ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$datetime = maybe_unserialize( $this->value );
|
||||
$this->value = $tzstring = '';
|
||||
|
||||
if ( $datetime && $datetime instanceof DateTime ) {
|
||||
$tz = $datetime->getTimezone();
|
||||
$tzstring = $tz->getName();
|
||||
$this->value = $datetime->getTimestamp();
|
||||
}
|
||||
|
||||
$date = $this->field->get_timestamp_format( 'date_format', $this->value );
|
||||
$time = $this->field->get_timestamp_format( 'time_format', $this->value );
|
||||
|
||||
echo $date, ( $time ? ' ' . $time : '' ), ( $tzstring ? ', ' . $tzstring : '' );
|
||||
}
|
||||
}
|
||||
|
||||
class CMB2_Display_Taxonomy_Radio extends CMB2_Field_Display {
|
||||
/**
|
||||
* Display single taxonomy value.
|
||||
*
|
||||
* @since 2.2.2
|
||||
*/
|
||||
protected function _display() {
|
||||
$taxonomy = $this->field->args( 'taxonomy' );
|
||||
$types = new CMB2_Types( $this->field );
|
||||
$type = $types->get_new_render_type( $this->field->type(), 'CMB2_Type_Taxonomy_Radio' );
|
||||
$terms = $type->get_object_terms();
|
||||
$term = false;
|
||||
|
||||
if ( is_wp_error( $terms ) || empty( $terms ) && ( $default = $this->field->get_default() ) ) {
|
||||
$term = get_term_by( 'slug', $default, $taxonomy );
|
||||
} elseif ( ! empty( $terms ) ) {
|
||||
$term = $terms[ key( $terms ) ];
|
||||
}
|
||||
|
||||
if ( $term ) {
|
||||
$link = get_edit_term_link( $term->term_id, $taxonomy );
|
||||
echo '<a href="', esc_url( $link ), '">', esc_html( $term->name ), '</a>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class CMB2_Display_Taxonomy_Multicheck extends CMB2_Field_Display {
|
||||
/**
|
||||
* Display taxonomy values.
|
||||
*
|
||||
* @since 2.2.2
|
||||
*/
|
||||
protected function _display() {
|
||||
$taxonomy = $this->field->args( 'taxonomy' );
|
||||
$types = new CMB2_Types( $this->field );
|
||||
$type = $types->get_new_render_type( $this->field->type(), 'CMB2_Type_Taxonomy_Multicheck' );
|
||||
$terms = $type->get_object_terms();
|
||||
|
||||
if ( is_wp_error( $terms ) || empty( $terms ) && ( $default = $this->field->get_default() ) ) {
|
||||
$terms = array();
|
||||
if ( is_array( $default ) ) {
|
||||
foreach ( $default as $slug ) {
|
||||
$terms[] = get_term_by( 'slug', $slug, $taxonomy );
|
||||
}
|
||||
} else {
|
||||
$terms[] = get_term_by( 'slug', $default, $taxonomy );
|
||||
}
|
||||
}
|
||||
|
||||
if ( is_array( $terms ) ) {
|
||||
|
||||
$links = array();
|
||||
foreach ( $terms as $term ) {
|
||||
$link = get_edit_term_link( $term->term_id, $taxonomy );
|
||||
$links[] = '<a href="' . esc_url( $link ) . '">' . esc_html( $term->name ) . '</a>';
|
||||
}
|
||||
// Then loop and output.
|
||||
echo '<div class="cmb2-taxonomy-terms-', esc_attr( sanitize_html_class( $taxonomy ) ), '">';
|
||||
echo implode( ', ', $links );
|
||||
echo '</div>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class CMB2_Display_File extends CMB2_Field_Display {
|
||||
/**
|
||||
* Display file value.
|
||||
*
|
||||
* @since 2.2.2
|
||||
*/
|
||||
protected function _display() {
|
||||
if ( empty( $this->value ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->value = esc_url_raw( $this->value );
|
||||
|
||||
$types = new CMB2_Types( $this->field );
|
||||
$type = $types->get_new_render_type( $this->field->type(), 'CMB2_Type_File_Base' );
|
||||
|
||||
$id = $this->field->get_field_clone( array(
|
||||
'id' => $this->field->_id( '', false ) . '_id',
|
||||
) )->escaped_value( 'absint' );
|
||||
|
||||
$this->file_output( $this->value, $id, $type );
|
||||
}
|
||||
|
||||
protected function file_output( $url_value, $id, CMB2_Type_File_Base $field_type ) {
|
||||
// If there is no ID saved yet, try to get it from the url.
|
||||
if ( $url_value && ! $id ) {
|
||||
$id = CMB2_Utils::image_id_from_url( esc_url_raw( $url_value ) );
|
||||
}
|
||||
|
||||
if ( $field_type->is_valid_img_ext( $url_value ) ) {
|
||||
$img_size = $this->field->args( 'preview_size' );
|
||||
|
||||
if ( $id ) {
|
||||
$image = wp_get_attachment_image( $id, $img_size, null, array(
|
||||
'class' => 'cmb-image-display',
|
||||
) );
|
||||
} else {
|
||||
$size = is_array( $img_size ) ? $img_size[0] : 200;
|
||||
$image = '<img class="cmb-image-display" style="max-width: ' . absint( $size ) . 'px; width: 100%; height: auto;" src="' . esc_url( $url_value ) . '" alt="" />';
|
||||
}
|
||||
|
||||
echo $image;
|
||||
|
||||
} else {
|
||||
|
||||
printf( '<div class="file-status"><span>%1$s <strong><a href="%2$s">%3$s</a></strong></span></div>',
|
||||
esc_html( $field_type->_text( 'file_text', __( 'File:', 'cmb2' ) ) ),
|
||||
esc_url( $url_value ),
|
||||
esc_html( CMB2_Utils::get_file_name_from_path( $url_value ) )
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class CMB2_Display_File_List extends CMB2_Display_File {
|
||||
/**
|
||||
* Display file_list value.
|
||||
*
|
||||
* @since 2.2.2
|
||||
*/
|
||||
protected function _display() {
|
||||
if ( empty( $this->value ) || ! is_array( $this->value ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$types = new CMB2_Types( $this->field );
|
||||
$type = $types->get_new_render_type( $this->field->type(), 'CMB2_Type_File_Base' );
|
||||
|
||||
echo '<ul class="cmb2-display-file-list">';
|
||||
foreach ( $this->value as $id => $fullurl ) {
|
||||
echo '<li>', $this->file_output( esc_url_raw( $fullurl ), $id, $type ), '</li>';
|
||||
}
|
||||
echo '</ul>';
|
||||
}
|
||||
}
|
||||
|
||||
class CMB2_Display_oEmbed extends CMB2_Field_Display {
|
||||
/**
|
||||
* Display oembed value.
|
||||
*
|
||||
* @since 2.2.2
|
||||
*/
|
||||
protected function _display() {
|
||||
if ( ! $this->value ) {
|
||||
return;
|
||||
}
|
||||
|
||||
cmb2_do_oembed( array(
|
||||
'url' => $this->value,
|
||||
'object_id' => $this->field->object_id,
|
||||
'object_type' => $this->field->object_type,
|
||||
'oembed_args' => array(
|
||||
'width' => '300',
|
||||
),
|
||||
'field_id' => $this->field->id(),
|
||||
) );
|
||||
}
|
||||
}
|
1044
wp-content/plugins/debloat/vendor/cmb2/includes/CMB2_Hookup.php
vendored
Normal file
105
wp-content/plugins/debloat/vendor/cmb2/includes/CMB2_Hookup_Base.php
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
/**
|
||||
* Base class for hooking CMB2 into WordPress.
|
||||
*
|
||||
* @since 2.2.0
|
||||
*
|
||||
* @category WordPress_Plugin
|
||||
* @package CMB2
|
||||
* @author CMB2 team
|
||||
* @license GPL-2.0+
|
||||
* @link https://cmb2.io
|
||||
*
|
||||
* @property-read string $object_type
|
||||
* @property-read CMB2 $cmb
|
||||
*/
|
||||
abstract class CMB2_Hookup_Base {
|
||||
|
||||
/**
|
||||
* CMB2 object.
|
||||
*
|
||||
* @var CMB2 object
|
||||
* @since 2.0.2
|
||||
*/
|
||||
protected $cmb;
|
||||
|
||||
/**
|
||||
* The object type we are performing the hookup for
|
||||
*
|
||||
* @var string
|
||||
* @since 2.0.9
|
||||
*/
|
||||
protected $object_type = 'post';
|
||||
|
||||
/**
|
||||
* A functionalized constructor, used for the hookup action callbacks.
|
||||
*
|
||||
* @since 2.2.6
|
||||
*
|
||||
* @throws Exception Failed implementation.
|
||||
*
|
||||
* @param CMB2 $cmb The CMB2 object to hookup.
|
||||
*/
|
||||
public static function maybe_init_and_hookup( CMB2 $cmb ) {
|
||||
throw new Exception( sprintf( esc_html__( '%1$s should be implemented by the extended class.', 'cmb2' ), __FUNCTION__ ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @param CMB2 $cmb The CMB2 object to hookup.
|
||||
*/
|
||||
public function __construct( CMB2 $cmb ) {
|
||||
$this->cmb = $cmb;
|
||||
$this->object_type = $this->cmb->mb_object_type();
|
||||
}
|
||||
|
||||
abstract public function universal_hooks();
|
||||
|
||||
/**
|
||||
* Ensures WordPress hook only gets fired once per object.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @param string $action The name of the filter to hook the $hook callback to.
|
||||
* @param callback $hook The callback to be run when the filter is applied.
|
||||
* @param integer $priority Order the functions are executed.
|
||||
* @param int $accepted_args The number of arguments the function accepts.
|
||||
*/
|
||||
public function once( $action, $hook, $priority = 10, $accepted_args = 1 ) {
|
||||
static $hooks_completed = array();
|
||||
|
||||
$args = func_get_args();
|
||||
|
||||
// Get object hash.. This bypasses issues with serializing closures.
|
||||
if ( is_object( $hook ) ) {
|
||||
$args[1] = spl_object_hash( $args[1] );
|
||||
} elseif ( is_array( $hook ) && is_object( $hook[0] ) ) {
|
||||
$args[1][0] = spl_object_hash( $hook[0] );
|
||||
}
|
||||
|
||||
$key = md5( serialize( $args ) );
|
||||
|
||||
if ( ! isset( $hooks_completed[ $key ] ) ) {
|
||||
$hooks_completed[ $key ] = 1;
|
||||
add_filter( $action, $hook, $priority, $accepted_args );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic getter for our object.
|
||||
*
|
||||
* @param string $field Property to return.
|
||||
* @throws Exception Throws an exception if the field is invalid.
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get( $field ) {
|
||||
switch ( $field ) {
|
||||
case 'object_type':
|
||||
case 'cmb':
|
||||
return $this->{$field};
|
||||
default:
|
||||
throw new Exception( sprintf( esc_html__( 'Invalid %1$s property: %2$s', 'cmb2' ), __CLASS__, $field ) );
|
||||
}
|
||||
}
|
||||
}
|
257
wp-content/plugins/debloat/vendor/cmb2/includes/CMB2_JS.php
vendored
Normal file
@@ -0,0 +1,257 @@
|
||||
<?php
|
||||
/**
|
||||
* Handles the dependencies and enqueueing of the CMB2 JS scripts
|
||||
*
|
||||
* @category WordPress_Plugin
|
||||
* @package CMB2
|
||||
* @author CMB2 team
|
||||
* @license GPL-2.0+
|
||||
* @link https://cmb2.io
|
||||
*/
|
||||
class CMB2_JS {
|
||||
|
||||
/**
|
||||
* The CMB2 JS handle
|
||||
*
|
||||
* @var string
|
||||
* @since 2.0.7
|
||||
*/
|
||||
protected static $handle = 'cmb2-scripts';
|
||||
|
||||
/**
|
||||
* The CMB2 JS variable name
|
||||
*
|
||||
* @var string
|
||||
* @since 2.0.7
|
||||
*/
|
||||
protected static $js_variable = 'cmb2_l10';
|
||||
|
||||
/**
|
||||
* Array of CMB2 JS dependencies
|
||||
*
|
||||
* @var array
|
||||
* @since 2.0.7
|
||||
*/
|
||||
protected static $dependencies = array(
|
||||
'jquery' => 'jquery',
|
||||
);
|
||||
|
||||
/**
|
||||
* Array of CMB2 fields model data for JS.
|
||||
*
|
||||
* @var array
|
||||
* @since 2.4.0
|
||||
*/
|
||||
protected static $fields = array();
|
||||
|
||||
/**
|
||||
* Add a dependency to the array of CMB2 JS dependencies
|
||||
*
|
||||
* @since 2.0.7
|
||||
* @param array|string $dependencies Array (or string) of dependencies to add.
|
||||
*/
|
||||
public static function add_dependencies( $dependencies ) {
|
||||
foreach ( (array) $dependencies as $dependency ) {
|
||||
self::$dependencies[ $dependency ] = $dependency;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add field model data to the array for JS.
|
||||
*
|
||||
* @since 2.4.0
|
||||
*
|
||||
* @param CMB2_Field $field Field object.
|
||||
*/
|
||||
public static function add_field_data( CMB2_Field $field ) {
|
||||
$hash = $field->hash_id();
|
||||
if ( ! isset( self::$fields[ $hash ] ) ) {
|
||||
self::$fields[ $hash ] = $field->js_data();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue the CMB2 JS
|
||||
*
|
||||
* @since 2.0.7
|
||||
*/
|
||||
public static function enqueue() {
|
||||
// Filter required script dependencies.
|
||||
$dependencies = self::$dependencies = apply_filters( 'cmb2_script_dependencies', self::$dependencies );
|
||||
|
||||
// Only use minified files if SCRIPT_DEBUG is off.
|
||||
$debug = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG;
|
||||
|
||||
$min = $debug ? '' : '.min';
|
||||
|
||||
// if colorpicker.
|
||||
if ( isset( $dependencies['wp-color-picker'] ) ) {
|
||||
if ( ! is_admin() ) {
|
||||
self::colorpicker_frontend();
|
||||
}
|
||||
|
||||
// Enqueue colorpicker
|
||||
if ( ! wp_script_is( 'wp-color-picker', 'enqueued' ) ) {
|
||||
wp_enqueue_script( 'wp-color-picker' );
|
||||
}
|
||||
|
||||
if ( isset( $dependencies['wp-color-picker-alpha'] ) ) {
|
||||
self::register_colorpicker_alpha();
|
||||
}
|
||||
}
|
||||
|
||||
// if file/file_list.
|
||||
if ( isset( $dependencies['media-editor'] ) ) {
|
||||
wp_enqueue_media();
|
||||
CMB2_Type_File_Base::output_js_underscore_templates();
|
||||
}
|
||||
|
||||
// if timepicker.
|
||||
if ( isset( $dependencies['jquery-ui-datetimepicker'] ) ) {
|
||||
self::register_datetimepicker();
|
||||
}
|
||||
|
||||
// if cmb2-wysiwyg.
|
||||
$enqueue_wysiwyg = isset( $dependencies['cmb2-wysiwyg'] ) && $debug;
|
||||
unset( $dependencies['cmb2-wysiwyg'] );
|
||||
|
||||
// if cmb2-char-counter.
|
||||
$enqueue_char_counter = isset( $dependencies['cmb2-char-counter'] ) && $debug;
|
||||
unset( $dependencies['cmb2-char-counter'] );
|
||||
|
||||
// Enqueue cmb JS.
|
||||
wp_enqueue_script( self::$handle, CMB2_Utils::url( "js/cmb2{$min}.js" ), array_values( $dependencies ), CMB2_VERSION, true );
|
||||
|
||||
// if SCRIPT_DEBUG, we need to enqueue separately.
|
||||
if ( $enqueue_wysiwyg ) {
|
||||
wp_enqueue_script( 'cmb2-wysiwyg', CMB2_Utils::url( 'js/cmb2-wysiwyg.js' ), array( 'jquery', 'wp-util' ), CMB2_VERSION );
|
||||
}
|
||||
if ( $enqueue_char_counter ) {
|
||||
wp_enqueue_script( 'cmb2-char-counter', CMB2_Utils::url( 'js/cmb2-char-counter.js' ), array( 'jquery', 'wp-util' ), CMB2_VERSION );
|
||||
}
|
||||
|
||||
self::localize( $debug );
|
||||
|
||||
do_action( 'cmb2_footer_enqueue' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register or enqueue the wp-color-picker-alpha script.
|
||||
*
|
||||
* @since 2.2.7
|
||||
*
|
||||
* @param boolean $enqueue Whether or not to enqueue.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function register_colorpicker_alpha( $enqueue = false ) {
|
||||
// Only use minified files if SCRIPT_DEBUG is off.
|
||||
$min = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
|
||||
$func = $enqueue ? 'wp_enqueue_script' : 'wp_register_script';
|
||||
$func( 'wp-color-picker-alpha', CMB2_Utils::url( "js/wp-color-picker-alpha{$min}.js" ), array( 'wp-color-picker' ), '2.1.3' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register or enqueue the jquery-ui-datetimepicker script.
|
||||
*
|
||||
* @since 2.2.7
|
||||
*
|
||||
* @param boolean $enqueue Whether or not to enqueue.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function register_datetimepicker( $enqueue = false ) {
|
||||
$func = $enqueue ? 'wp_enqueue_script' : 'wp_register_script';
|
||||
$func( 'jquery-ui-datetimepicker', CMB2_Utils::url( 'js/jquery-ui-timepicker-addon.min.js' ), array( 'jquery-ui-slider' ), '1.5.0' );
|
||||
}
|
||||
|
||||
/**
|
||||
* We need to register colorpicker on the front-end
|
||||
*
|
||||
* @since 2.0.7
|
||||
*/
|
||||
protected static function colorpicker_frontend() {
|
||||
wp_register_script( 'iris', admin_url( 'js/iris.min.js' ), array( 'jquery-ui-draggable', 'jquery-ui-slider', 'jquery-touch-punch' ), CMB2_VERSION );
|
||||
wp_register_script( 'wp-color-picker', admin_url( 'js/color-picker.min.js' ), array( 'iris' ), CMB2_VERSION );
|
||||
wp_localize_script( 'wp-color-picker', 'wpColorPickerL10n', array(
|
||||
'clear' => esc_html__( 'Clear', 'cmb2' ),
|
||||
'defaultString' => esc_html__( 'Default', 'cmb2' ),
|
||||
'pick' => esc_html__( 'Select Color', 'cmb2' ),
|
||||
'current' => esc_html__( 'Current Color', 'cmb2' ),
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Localize the php variables for CMB2 JS
|
||||
*
|
||||
* @since 2.0.7
|
||||
*
|
||||
* @param mixed $debug Whether or not we are debugging.
|
||||
*/
|
||||
protected static function localize( $debug ) {
|
||||
static $localized = false;
|
||||
if ( $localized ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$localized = true;
|
||||
$l10n = array(
|
||||
'fields' => self::$fields,
|
||||
'ajax_nonce' => wp_create_nonce( 'ajax_nonce' ),
|
||||
'ajaxurl' => admin_url( '/admin-ajax.php' ),
|
||||
'script_debug' => $debug,
|
||||
'up_arrow_class' => 'dashicons dashicons-arrow-up-alt2',
|
||||
'down_arrow_class' => 'dashicons dashicons-arrow-down-alt2',
|
||||
'user_can_richedit' => user_can_richedit(),
|
||||
'defaults' => array(
|
||||
'code_editor' => false,
|
||||
'color_picker' => false,
|
||||
'date_picker' => array(
|
||||
'changeMonth' => true,
|
||||
'changeYear' => true,
|
||||
'dateFormat' => _x( 'mm/dd/yy', 'Valid formatDate string for jquery-ui datepicker', 'cmb2' ),
|
||||
'dayNames' => explode( ',', esc_html__( 'Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday', 'cmb2' ) ),
|
||||
'dayNamesMin' => explode( ',', esc_html__( 'Su, Mo, Tu, We, Th, Fr, Sa', 'cmb2' ) ),
|
||||
'dayNamesShort' => explode( ',', esc_html__( 'Sun, Mon, Tue, Wed, Thu, Fri, Sat', 'cmb2' ) ),
|
||||
'monthNames' => explode( ',', esc_html__( 'January, February, March, April, May, June, July, August, September, October, November, December', 'cmb2' ) ),
|
||||
'monthNamesShort' => explode( ',', esc_html__( 'Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec', 'cmb2' ) ),
|
||||
'nextText' => esc_html__( 'Next', 'cmb2' ),
|
||||
'prevText' => esc_html__( 'Prev', 'cmb2' ),
|
||||
'currentText' => esc_html__( 'Today', 'cmb2' ),
|
||||
'closeText' => esc_html__( 'Done', 'cmb2' ),
|
||||
'clearText' => esc_html__( 'Clear', 'cmb2' ),
|
||||
),
|
||||
'time_picker' => array(
|
||||
'timeOnlyTitle' => esc_html__( 'Choose Time', 'cmb2' ),
|
||||
'timeText' => esc_html__( 'Time', 'cmb2' ),
|
||||
'hourText' => esc_html__( 'Hour', 'cmb2' ),
|
||||
'minuteText' => esc_html__( 'Minute', 'cmb2' ),
|
||||
'secondText' => esc_html__( 'Second', 'cmb2' ),
|
||||
'currentText' => esc_html__( 'Now', 'cmb2' ),
|
||||
'closeText' => esc_html__( 'Done', 'cmb2' ),
|
||||
'timeFormat' => _x( 'hh:mm TT', 'Valid formatting string, as per http://trentrichardson.com/examples/timepicker/', 'cmb2' ),
|
||||
'controlType' => 'select',
|
||||
'stepMinute' => 5,
|
||||
),
|
||||
),
|
||||
'strings' => array(
|
||||
'upload_file' => esc_html__( 'Use this file', 'cmb2' ),
|
||||
'upload_files' => esc_html__( 'Use these files', 'cmb2' ),
|
||||
'remove_image' => esc_html__( 'Remove Image', 'cmb2' ),
|
||||
'remove_file' => esc_html__( 'Remove', 'cmb2' ),
|
||||
'file' => esc_html__( 'File:', 'cmb2' ),
|
||||
'download' => esc_html__( 'Download', 'cmb2' ),
|
||||
'check_toggle' => esc_html__( 'Select / Deselect All', 'cmb2' ),
|
||||
),
|
||||
);
|
||||
|
||||
if ( isset( self::$dependencies['code-editor'] ) && function_exists( 'wp_enqueue_code_editor' ) ) {
|
||||
$l10n['defaults']['code_editor'] = wp_enqueue_code_editor( array(
|
||||
'type' => 'text/html',
|
||||
) );
|
||||
}
|
||||
|
||||
wp_localize_script( self::$handle, self::$js_variable, apply_filters( 'cmb2_localized_data', $l10n ) );
|
||||
}
|
||||
|
||||
}
|
250
wp-content/plugins/debloat/vendor/cmb2/includes/CMB2_Options.php
vendored
Normal file
@@ -0,0 +1,250 @@
|
||||
<?php
|
||||
/**
|
||||
* CMB2 Utility classes for handling multi-dimensional array data for options
|
||||
*
|
||||
* @category WordPress_Plugin
|
||||
* @package CMB2
|
||||
* @author CMB2 team
|
||||
* @license GPL-2.0+
|
||||
* @link https://cmb2.io
|
||||
*/
|
||||
|
||||
/**
|
||||
* Retrieves an instance of CMB2_Option based on the option key
|
||||
*
|
||||
* @package CMB2
|
||||
* @author CMB2 team
|
||||
*/
|
||||
class CMB2_Options {
|
||||
/**
|
||||
* Array of all CMB2_Option instances
|
||||
*
|
||||
* @var array
|
||||
* @since 1.0.0
|
||||
*/
|
||||
protected static $option_sets = array();
|
||||
|
||||
public static function get( $option_key ) {
|
||||
|
||||
if ( empty( self::$option_sets ) || empty( self::$option_sets[ $option_key ] ) ) {
|
||||
self::$option_sets[ $option_key ] = new CMB2_Option( $option_key );
|
||||
}
|
||||
|
||||
return self::$option_sets[ $option_key ];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles getting/setting of values to an option array
|
||||
* for a specific option key
|
||||
*
|
||||
* @package CMB2
|
||||
* @author CMB2 team
|
||||
*/
|
||||
class CMB2_Option {
|
||||
|
||||
/**
|
||||
* Options array
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $options = array();
|
||||
|
||||
/**
|
||||
* Current option key
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $key = '';
|
||||
|
||||
/**
|
||||
* Initiate option object
|
||||
*
|
||||
* @param string $option_key Option key where data will be saved.
|
||||
* Leave empty for temporary data store.
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public function __construct( $option_key = '' ) {
|
||||
$this->key = ! empty( $option_key ) ? $option_key : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the option from the db
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @return mixed Delete success or failure
|
||||
*/
|
||||
public function delete_option() {
|
||||
$deleted = $this->key ? delete_option( $this->key ) : true;
|
||||
$this->options = $deleted ? array() : $this->options;
|
||||
return $this->options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an option from an option array
|
||||
*
|
||||
* @since 1.0.1
|
||||
* @param string $field_id Option array field key.
|
||||
* @param bool $resave Whether or not to resave.
|
||||
* @return array Modified options
|
||||
*/
|
||||
public function remove( $field_id, $resave = false ) {
|
||||
|
||||
$this->get_options();
|
||||
|
||||
if ( isset( $this->options[ $field_id ] ) ) {
|
||||
unset( $this->options[ $field_id ] );
|
||||
}
|
||||
|
||||
if ( $resave ) {
|
||||
$this->set();
|
||||
}
|
||||
|
||||
return $this->options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves an option from an option array
|
||||
*
|
||||
* @since 1.0.1
|
||||
* @param string $field_id Option array field key.
|
||||
* @param mixed $default Fallback value for the option.
|
||||
* @return array Requested field or default
|
||||
*/
|
||||
public function get( $field_id, $default = false ) {
|
||||
$opts = $this->get_options();
|
||||
|
||||
if ( 'all' == $field_id ) {
|
||||
return $opts;
|
||||
} elseif ( array_key_exists( $field_id, $opts ) ) {
|
||||
return false !== $opts[ $field_id ] ? $opts[ $field_id ] : $default;
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates Option data
|
||||
*
|
||||
* @since 1.0.1
|
||||
* @param string $field_id Option array field key.
|
||||
* @param mixed $value Value to update data with.
|
||||
* @param bool $resave Whether to re-save the data.
|
||||
* @param bool $single Whether data should not be an array.
|
||||
* @return boolean Return status of update.
|
||||
*/
|
||||
public function update( $field_id, $value = '', $resave = false, $single = true ) {
|
||||
$this->get_options();
|
||||
|
||||
if ( true !== $field_id ) {
|
||||
|
||||
if ( ! $single ) {
|
||||
// If multiple, add to array.
|
||||
$this->options[ $field_id ][] = $value;
|
||||
} else {
|
||||
$this->options[ $field_id ] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $resave || true === $field_id ) {
|
||||
return $this->set();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the option array
|
||||
* Needs to be run after finished using remove/update_option
|
||||
*
|
||||
* @uses apply_filters() Calls 'cmb2_override_option_save_{$this->key}' hook
|
||||
* to allow overwriting the option value to be stored.
|
||||
*
|
||||
* @since 1.0.1
|
||||
* @param array $options Optional options to override.
|
||||
* @return bool Success/Failure
|
||||
*/
|
||||
public function set( $options = array() ) {
|
||||
if ( ! empty( $options ) || empty( $options ) && empty( $this->key ) ) {
|
||||
$this->options = $options;
|
||||
}
|
||||
|
||||
$this->options = wp_unslash( $this->options ); // get rid of those evil magic quotes.
|
||||
|
||||
if ( empty( $this->key ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$test_save = apply_filters( "cmb2_override_option_save_{$this->key}", 'cmb2_no_override_option_save', $this->options, $this );
|
||||
|
||||
if ( 'cmb2_no_override_option_save' !== $test_save ) {
|
||||
// If override, do not proceed to update the option, just return result.
|
||||
return $test_save;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to auto-load the option when WordPress starts up.
|
||||
*
|
||||
* The dynamic portion of the hook name, $this->key, refers to the option key.
|
||||
*
|
||||
* @since 2.4.0
|
||||
*
|
||||
* @param bool $autoload Whether to load the option when WordPress starts up.
|
||||
* @param CMB2_Option $cmb_option This object.
|
||||
*/
|
||||
$autoload = apply_filters( "cmb2_should_autoload_{$this->key}", true, $this );
|
||||
|
||||
return update_option(
|
||||
$this->key,
|
||||
$this->options,
|
||||
! $autoload || 'no' === $autoload ? false : true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve option value based on name of option.
|
||||
*
|
||||
* @uses apply_filters() Calls 'cmb2_override_option_get_{$this->key}' hook to allow
|
||||
* overwriting the option value to be retrieved.
|
||||
*
|
||||
* @since 1.0.1
|
||||
* @param mixed $default Optional. Default value to return if the option does not exist.
|
||||
* @return mixed Value set for the option.
|
||||
*/
|
||||
public function get_options( $default = null ) {
|
||||
if ( empty( $this->options ) && ! empty( $this->key ) ) {
|
||||
|
||||
$test_get = apply_filters( "cmb2_override_option_get_{$this->key}", 'cmb2_no_override_option_get', $default, $this );
|
||||
|
||||
if ( 'cmb2_no_override_option_get' !== $test_get ) {
|
||||
$this->options = $test_get;
|
||||
} else {
|
||||
// If no override, get the option.
|
||||
$this->options = get_option( $this->key, $default );
|
||||
}
|
||||
}
|
||||
|
||||
$this->options = (array) $this->options;
|
||||
|
||||
return $this->options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic getter for our object.
|
||||
*
|
||||
* @since 2.6.0
|
||||
*
|
||||
* @param string $field Requested property.
|
||||
* @throws Exception Throws an exception if the field is invalid.
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get( $field ) {
|
||||
switch ( $field ) {
|
||||
case 'options':
|
||||
case 'key':
|
||||
return $this->{$field};
|
||||
default:
|
||||
throw new Exception( sprintf( esc_html__( 'Invalid %1$s property: %2$s', 'cmb2' ), __CLASS__, $field ) );
|
||||
}
|
||||
}
|
||||
}
|