first commit
This commit is contained in:
5
wp-content/plugins/host-webfonts-local/.gitignore
vendored
Normal file
5
wp-content/plugins/host-webfonts-local/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
.DS_Store
|
||||
.idea
|
||||
.git
|
||||
.svn
|
||||
.svnignore
|
||||
21
wp-content/plugins/host-webfonts-local/LICENSE
Normal file
21
wp-content/plugins/host-webfonts-local/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018 Daan van den Bergh
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
198
wp-content/plugins/host-webfonts-local/assets/css/omgf-admin.css
Normal file
198
wp-content/plugins/host-webfonts-local/assets/css/omgf-admin.css
Normal file
@@ -0,0 +1,198 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* ██████╗ ███╗ ███╗ ██████╗ ███████╗
|
||||
* ██╔═══██╗████╗ ████║██╔════╝ ██╔════╝
|
||||
* ██║ ██║██╔████╔██║██║ ███╗█████╗
|
||||
* ██║ ██║██║╚██╔╝██║██║ ██║██╔══╝
|
||||
* ╚██████╔╝██║ ╚═╝ ██║╚██████╔╝██║
|
||||
* ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝
|
||||
*
|
||||
* @package : OMGF
|
||||
* @author : Daan van den Bergh
|
||||
* @copyright: (c) 2021 Daan van den Bergh
|
||||
* @url : https://daan.dev
|
||||
* * * * * * * * * * * * * * * * * * * */
|
||||
/**
|
||||
* General
|
||||
*/
|
||||
.omgf .button-cancel {
|
||||
color: #a00;
|
||||
text-decoration: none;
|
||||
border-color: transparent;
|
||||
box-shadow: none;
|
||||
background: 0 0;
|
||||
border-radius: 3px;
|
||||
white-space: nowrap;
|
||||
padding: 1px 10px !important;
|
||||
}
|
||||
.omgf .button-cancel:hover {
|
||||
cursor: pointer;
|
||||
background: #d54e21;
|
||||
color: #fff;
|
||||
border-color: #d54e21;
|
||||
}
|
||||
/**
|
||||
* Navigation
|
||||
*/
|
||||
.omgf-nav {
|
||||
padding: 1em 0 1.5em;
|
||||
}
|
||||
.omgf-nav a {
|
||||
cursor: pointer;
|
||||
}
|
||||
.omgf-nav .dashicons-before:before {
|
||||
margin-right: 0.25em;
|
||||
line-height: 1.15em;
|
||||
}
|
||||
.omgf-optimize-fonts-container {
|
||||
text-align: center;
|
||||
padding: 25px 50px;
|
||||
max-width: 1024px;
|
||||
margin: 20px auto 0 220px;
|
||||
overflow: visible;
|
||||
position: relative;
|
||||
}
|
||||
.omgf-optimize-fonts-container .option-title {
|
||||
position: absolute;
|
||||
left: -220px;
|
||||
top: 0;
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
color: #1d2327;
|
||||
}
|
||||
.omgf-optimize-fonts-container h3 {
|
||||
font-size: 1.3em;
|
||||
margin-top: 0;
|
||||
}
|
||||
.omgf-optimize-fonts-container .omgf-optimize-fonts-manage {
|
||||
text-align: left;
|
||||
}
|
||||
.omgf-optimize-fonts-container .omgf-optimize-fonts-manage table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
.omgf-optimize-fonts-container .omgf-optimize-fonts-manage table .tooltip {
|
||||
position: relative;
|
||||
font-size: 16px;
|
||||
line-height: 25px;
|
||||
}
|
||||
.omgf-optimize-fonts-container .omgf-optimize-fonts-manage table .tooltip .tooltip-text {
|
||||
visibility: hidden;
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 100%;
|
||||
z-index: 10000;
|
||||
background-color: rgba(0, 0, 0, 0.75);
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
|
||||
font-size: 0.8em;
|
||||
color: #fff;
|
||||
line-height: 1.5;
|
||||
width: 250px;
|
||||
padding: 10px;
|
||||
margin-left: -125px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.omgf-optimize-fonts-container .omgf-optimize-fonts-manage table .tooltip .tooltip-text .illustration {
|
||||
margin-top: 10px;
|
||||
}
|
||||
.omgf-optimize-fonts-container .omgf-optimize-fonts-manage table .tooltip:hover .tooltip-text {
|
||||
visibility: visible;
|
||||
}
|
||||
.omgf-optimize-fonts-container .omgf-optimize-fonts-manage table thead th {
|
||||
width: 13%;
|
||||
}
|
||||
.omgf-optimize-fonts-container .omgf-optimize-fonts-manage table tbody {
|
||||
border: 1px solid #ccd0d4;
|
||||
}
|
||||
.omgf-optimize-fonts-container .omgf-optimize-fonts-manage table tbody th {
|
||||
padding: 5px 0 0 10px;
|
||||
width: 40%;
|
||||
}
|
||||
.omgf-optimize-fonts-container .omgf-optimize-fonts-manage table tbody td {
|
||||
padding-bottom: 5px;
|
||||
width: 13%;
|
||||
}
|
||||
.omgf-optimize-fonts-container .omgf-optimize-fonts-manage table tbody td .unload-mass-action {
|
||||
font-size: 0.9em;
|
||||
}
|
||||
.omgf-optimize-fonts-container .omgf-optimize-fonts-manage table tbody td .family {
|
||||
padding: 0 10px 0;
|
||||
font-weight: 600;
|
||||
}
|
||||
.omgf-optimize-fonts-container .omgf-optimize-fonts-manage table tbody tr:last-child td {
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
.omgf-optimize-fonts-container .omgf-optimize-fonts-description .omgf-optimize-fonts-pros {
|
||||
margin-right: 10px;
|
||||
}
|
||||
.omgf-optimize-fonts-container .omgf-optimize-fonts-description .omgf-optimize-fonts-pros,
|
||||
.omgf-optimize-fonts-container .omgf-optimize-fonts-description .omgf-optimize-fonts-cons {
|
||||
text-align: left;
|
||||
width: 48%;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
}
|
||||
.omgf-optimize-fonts-container .omgf-optimize-fonts-description .omgf-optimize-fonts-pros span:before,
|
||||
.omgf-optimize-fonts-container .omgf-optimize-fonts-description .omgf-optimize-fonts-cons span:before {
|
||||
vertical-align: -4px;
|
||||
}
|
||||
.omgf-optimize-fonts-container .omgf-optimize-fonts-description label {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.omgf-optimize-fonts-container .omgf-optimize-fonts-description #omgf_manual_optimize_url {
|
||||
font-size: 18px;
|
||||
padding: 0 15px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
.omgf-optimize-fonts-container .omgf-optimize-fonts-tooltip {
|
||||
padding: 0 15px 5px;
|
||||
}
|
||||
.omgf-optimize-fonts-container p,
|
||||
.omgf-optimize-fonts-container ul {
|
||||
text-align: justify;
|
||||
}
|
||||
@media only screen and (max-width: 782px) {
|
||||
.omgf-optimize-fonts-container {
|
||||
margin: 20px 0;
|
||||
}
|
||||
.omgf-optimize-fonts-container .option-title {
|
||||
position: relative;
|
||||
left: initial;
|
||||
top: initial;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Loader
|
||||
*/
|
||||
.omgf-loading {
|
||||
position: fixed;
|
||||
background-color: rgba(255, 255, 255, 0.6);
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
text-align: center;
|
||||
}
|
||||
.omgf-loading .spinner {
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
position: absolute;
|
||||
-ms-transform: translate(0, -70%);
|
||||
transform: translate(0, -70%);
|
||||
}
|
||||
/**
|
||||
* Welcome Block
|
||||
*/
|
||||
#footer-thankyou a {
|
||||
vertical-align: -0.65em;
|
||||
}
|
||||
#footer-thankyou .dashicons.ffwp-heart {
|
||||
vertical-align: middle;
|
||||
}
|
||||
#footer-thankyou .dashicons.ffwp-heart:before {
|
||||
color: #FF4136;
|
||||
}
|
||||
#footer-thankyou .signature-image {
|
||||
width: 96px;
|
||||
}
|
||||
/*# sourceMappingURL=./omgf-admin.css.map */
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["omgf-admin.less"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAkBA,KACE;EACE,WAAA;EACA,qBAAA;EACA,yBAAA;EACA,gBAAA;EACA,eAAA;EACA,kBAAA;EACA,mBAAA;EACA,4BAAA;;AAEA,KAVF,eAUG;EACC,eAAA;EACA,mBAAA;EACA,WAAA;EACA,qBAAA;;;;;AAQN;EACE,oBAAA;;AADF,SAGE;EACE,eAAA;;AAJJ,SAOE,kBAAiB;EACf,oBAAA;EACA,mBAAA;;AAIJ;EACE,kBAAA;EACA,kBAAA;EACA,iBAAA;EACA,yBAAA;EACA,iBAAA;EACA,kBAAA;;AANF,8BAQE;EACE,kBAAA;EACA,YAAA;EACA,MAAA;EACA,gBAAA;EACA,eAAA;EACA,cAAA;;AAdJ,8BAiBE;EACE,gBAAA;EACA,aAAA;;AAnBJ,8BAsBE;EACE,gBAAA;;AAvBJ,8BAsBE,4BAGE;EACE,WAAA;EACA,yBAAA;;AA3BN,8BAsBE,4BAGE,MAIE;EACE,kBAAA;EACA,eAAA;EACA,iBAAA;;AAhCR,8BAsBE,4BAGE,MAIE,SAKE;EACE,kBAAA;EACA,kBAAA;EACA,SAAA;EACA,UAAA;EACA,cAAA;EACA,qCAAA;EACA,gDAA8C,oDAA+C,4BAA7F;EACA,gBAAA;EACA,WAAA;EACA,gBAAA;EACA,YAAA;EACA,aAAA;EACA,mBAAA;EACA,kBAAA;;AAhDV,8BAsBE,4BAGE,MAIE,SAKE,cAgBE;EACE,gBAAA;;AAIJ,8BAjCN,4BAGE,MAIE,SA0BG,MAAO;EACN,mBAAA;;AAxDV,8BAsBE,4BAGE,MAmCE,MACE;EACE,UAAA;;AA9DV,8BAsBE,4BAGE,MAyCE;EACE,yBAAA;;AAnER,8BAsBE,4BAGE,MAyCE,MAGE;EACE,qBAAA;EACA,UAAA;;AAvEV,8BAsBE,4BAGE,MAyCE,MAQE;EACE,mBAAA;EACA,UAAA;;AA5EV,8BAsBE,4BAGE,MAyCE,MAQE,GAIE;EACE,gBAAA;;AA/EZ,8BAsBE,4BAGE,MAyCE,MAQE,GAQE;EACE,iBAAA;EACA,gBAAA;;AAKF,8BAnER,4BAGE,MAyCE,MAsBE,GACG,WACC;EACE,oBAAA;;AA3Fd,8BAmGE,iCACE;EACE,kBAAA;;AArGN,8BAmGE,iCAKE;AAxGJ,8BAmGE,iCAME;EACE,gBAAA;EACA,UAAA;EACA,qBAAA;EACA,mBAAA;;AA7GN,8BAmGE,iCAKE,0BAOE,KAAI;AA/GV,8BAmGE,iCAME,0BAME,KAAI;EACF,oBAAA;;AAhHR,8BAmGE,iCAiBE;EACE,eAAA;EACA,iBAAA;;AAtHN,8BAmGE,iCAsBE;EACE,eAAA;EACA,eAAA;EACA,iBAAA;;AA5HN,8BAgIE;EACE,mBAAA;;AAjIJ,8BAoIE;AApIF,8BAqIE;EACE,mBAAA;;AAIJ,wBAA0C;EACxC;IACE,cAAA;;EADF,8BAGE;IACE,kBAAA;IACA,aAAA;IACA,YAAA;;;;;;AAQN;EACE,eAAA;EACA,0CAAA;EACA,WAAA;EACA,YAAA;EACA,MAAA;EACA,kBAAA;;AANF,aAQE;EACE,QAAA;EACA,SAAA;EACA,kBAAA;EACA,eAAe,kBAAf;EACA,WAAW,kBAAX;;;;;AAOH,gBACC;EACE,uBAAA;;AAIA,gBADF,WACG;EACC,sBAAA;;AAGF,gBALF,WAKG,WAAW;EACV,cAAA;;AAXL,gBAeC;EACE,WAAA"}
|
||||
@@ -0,0 +1,246 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* ██████╗ ███╗ ███╗ ██████╗ ███████╗
|
||||
* ██╔═══██╗████╗ ████║██╔════╝ ██╔════╝
|
||||
* ██║ ██║██╔████╔██║██║ ███╗█████╗
|
||||
* ██║ ██║██║╚██╔╝██║██║ ██║██╔══╝
|
||||
* ╚██████╔╝██║ ╚═╝ ██║╚██████╔╝██║
|
||||
* ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝
|
||||
*
|
||||
* @package : OMGF
|
||||
* @author : Daan van den Bergh
|
||||
* @copyright: (c) 2021 Daan van den Bergh
|
||||
* @url : https://daan.dev
|
||||
* * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
/**
|
||||
* General
|
||||
*/
|
||||
.omgf {
|
||||
.button-cancel {
|
||||
color: #a00;
|
||||
text-decoration: none;
|
||||
border-color: transparent;
|
||||
box-shadow: none;
|
||||
background: 0 0;
|
||||
border-radius: 3px;
|
||||
white-space: nowrap;
|
||||
padding: 1px 10px !important;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
background: #d54e21;
|
||||
color: #fff;
|
||||
border-color: #d54e21;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Navigation
|
||||
*/
|
||||
.omgf-nav {
|
||||
padding: 1em 0 1.5em;
|
||||
|
||||
a {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.dashicons-before:before {
|
||||
margin-right: .25em;
|
||||
line-height: 1.15em;
|
||||
}
|
||||
}
|
||||
|
||||
.omgf-optimize-fonts-container {
|
||||
text-align: center;
|
||||
padding: 25px 50px;
|
||||
max-width: 1024px;
|
||||
margin: 20px auto 0 220px;
|
||||
overflow: visible;
|
||||
position: relative;
|
||||
|
||||
.option-title {
|
||||
position: absolute;
|
||||
left: -220px;
|
||||
top: 0;
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
color: #1d2327;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.3em;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.omgf-optimize-fonts-manage {
|
||||
text-align: left;
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
|
||||
.tooltip {
|
||||
position: relative;
|
||||
font-size: 16px;
|
||||
line-height: 25px;
|
||||
|
||||
.tooltip-text {
|
||||
visibility: hidden;
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 100%;
|
||||
z-index: 10000;
|
||||
background-color: rgba(0, 0, 0, 0.75);
|
||||
font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;
|
||||
font-size: .8em;
|
||||
color: #fff;
|
||||
line-height: 1.5;
|
||||
width: 250px;
|
||||
padding: 10px;
|
||||
margin-left: -125px;
|
||||
border-radius: 3px;
|
||||
|
||||
.illustration {
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover .tooltip-text {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
|
||||
thead {
|
||||
th {
|
||||
width: 13%;
|
||||
}
|
||||
}
|
||||
|
||||
tbody {
|
||||
border: 1px solid #ccd0d4;
|
||||
|
||||
th {
|
||||
padding: 5px 0 0 10px;
|
||||
width: 40%;
|
||||
}
|
||||
|
||||
td {
|
||||
padding-bottom: 5px;
|
||||
width: 13%;
|
||||
|
||||
.unload-mass-action {
|
||||
font-size: .9em;
|
||||
}
|
||||
|
||||
.family {
|
||||
padding: 0 10px 0;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
tr {
|
||||
&:last-child {
|
||||
td {
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.omgf-optimize-fonts-description {
|
||||
.omgf-optimize-fonts-pros {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.omgf-optimize-fonts-pros,
|
||||
.omgf-optimize-fonts-cons {
|
||||
text-align: left;
|
||||
width: 48%;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
|
||||
span:before {
|
||||
vertical-align: -4px;
|
||||
}
|
||||
}
|
||||
|
||||
label {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#omgf_manual_optimize_url {
|
||||
font-size: 18px;
|
||||
padding: 0 15px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.omgf-optimize-fonts-tooltip {
|
||||
padding: 0 15px 5px;
|
||||
}
|
||||
|
||||
p,
|
||||
ul {
|
||||
text-align: justify;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 782px) {
|
||||
.omgf-optimize-fonts-container {
|
||||
margin: 20px 0;
|
||||
|
||||
.option-title {
|
||||
position: relative;
|
||||
left: initial;
|
||||
top: initial;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loader
|
||||
*/
|
||||
.omgf-loading {
|
||||
position: fixed;
|
||||
background-color: rgba(255,255,255,0.6);
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
text-align: center;
|
||||
|
||||
.spinner {
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
position: absolute;
|
||||
-ms-transform: translate(0, -70%);
|
||||
transform: translate(0, -70%);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Welcome Block
|
||||
*/
|
||||
#footer-thankyou {
|
||||
a {
|
||||
vertical-align: -.65em;
|
||||
}
|
||||
|
||||
.dashicons {
|
||||
&.ffwp-heart {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
&.ffwp-heart:before {
|
||||
color: #FF4136;
|
||||
}
|
||||
}
|
||||
|
||||
.signature-image {
|
||||
width: 96px;
|
||||
}
|
||||
}
|
||||
1
wp-content/plugins/host-webfonts-local/assets/css/omgf-admin.min.css
vendored
Normal file
1
wp-content/plugins/host-webfonts-local/assets/css/omgf-admin.min.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.omgf .button-cancel{color:#a00;text-decoration:none;border-color:transparent;box-shadow:none;background:0 0;border-radius:3px;white-space:nowrap;padding:1px 10px!important}.omgf .button-cancel:hover{cursor:pointer;background:#d54e21;color:#fff;border-color:#d54e21}.omgf-nav{padding:1em 0 1.5em}.omgf-nav a{cursor:pointer}.omgf-nav .dashicons-before:before{margin-right:.25em;line-height:1.15em}.settings-column.left{float:left;width:66%}.settings-column.right{float:right;width:21.75%}#omgf-welcome-panel{padding:20px 10px 5px}#omgf-welcome-panel .welcome-panel-content{margin-left:0;padding:0 15px}#omgf-welcome-panel h3>.dashicons{line-height:1.4}#omgf-welcome-panel .dashicons.ffwp-heart:before{color:#ff4136}#omgf-welcome-panel .welcome-icon:before{padding:0}#omgf-welcome-panel .signature,.omgf-loading{text-align:center}#omgf-welcome-panel .signature-image{max-width:90%}.omgf-loading{position:fixed;background-color:rgba(255,255,255,.6);width:100%;height:100%;top:0}.omgf-loading .spinner{top:50%;left:50%;position:absolute;-ms-transform:translate(0,-70%);transform:translate(0,-70%)}@media only screen and (max-width:1024px){.settings-column{display:block;float:none}.settings-column.left,.settings-column.right{width:100%}}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 69 KiB |
288
wp-content/plugins/host-webfonts-local/assets/js/omgf-admin.js
Normal file
288
wp-content/plugins/host-webfonts-local/assets/js/omgf-admin.js
Normal file
@@ -0,0 +1,288 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* ██████╗ ███╗ ███╗ ██████╗ ███████╗
|
||||
* ██╔═══██╗████╗ ████║██╔════╝ ██╔════╝
|
||||
* ██║ ██║██╔████╔██║██║ ███╗█████╗
|
||||
* ██║ ██║██║╚██╔╝██║██║ ██║██╔══╝
|
||||
* ╚██████╔╝██║ ╚═╝ ██║╚██████╔╝██║
|
||||
* ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝
|
||||
*
|
||||
* @package : OMGF
|
||||
* @author : Daan van den Bergh
|
||||
* @copyright: (c) 2021 Daan van den Bergh
|
||||
* @url : https://daan.dev
|
||||
* * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
jQuery(document).ready(function ($) {
|
||||
var omgf_admin = {
|
||||
ticker_items: document.querySelectorAll('.ticker-item'),
|
||||
ticker_index: 0,
|
||||
empty_cache_directory_xhr: false,
|
||||
optimize_xhr: false,
|
||||
cache_prefix: '-mod-',
|
||||
cache_section: $('.omgf-empty').data('cache-section'),
|
||||
nonce: $('.omgf-empty').data('nonce'),
|
||||
|
||||
/**
|
||||
* Initialize all on click events.
|
||||
*/
|
||||
init: function () {
|
||||
// Settings
|
||||
$('input[name="omgf_optimization_mode"]').on('click', this.toggle_optimization_mode_content);
|
||||
$('.omgf-optimize-fonts-manage .unload').on('change', this.unload_stylesheets);
|
||||
$('.omgf-optimize-fonts-manage .unload, .omgf-optimize-fonts-manage .fallback-font-stack select').on('change', this.generate_cache_key);
|
||||
$('.omgf-optimize-fonts-manage .unload').on('change', this.toggle_preload);
|
||||
$('.omgf-optimize-fonts-manage .preload').on('change', this.toggle_unload);
|
||||
$('.omgf-optimize-fonts-manage .unload-italics').on('click', this.unload_italics);
|
||||
$('.omgf-optimize-fonts-manage .unload-all').on('click', this.unload_all);
|
||||
$('.omgf-optimize-fonts-manage .load-all').on('click', this.load_all);
|
||||
|
||||
// Buttons
|
||||
$('.omgf-empty').on('click', this.empty_cache_directory);
|
||||
$('#omgf-optimize-settings-form').submit(this.show_loader_before_submit);
|
||||
|
||||
// Ticker
|
||||
setInterval(this.loop_ticker_items, 4000);
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
loop_ticker_items: function () {
|
||||
omgf_admin.ticker_items.forEach(function (item, index) {
|
||||
if (index == omgf_admin.ticker_index) {
|
||||
$(item).fadeIn(500);
|
||||
} else {
|
||||
$(item).hide(0);
|
||||
}
|
||||
});
|
||||
|
||||
omgf_admin.ticker_index++;
|
||||
|
||||
if (omgf_admin.ticker_index == omgf_admin.ticker_items.length) {
|
||||
omgf_admin.ticker_index = 0;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
toggle_optimization_mode_content: function () {
|
||||
if (this.value == 'manual') {
|
||||
$('.omgf-optimize-fonts-manual').show();
|
||||
$('.omgf-optimize-fonts-automatic').hide();
|
||||
} else {
|
||||
$('.omgf-optimize-fonts-automatic').show();
|
||||
$('.omgf-optimize-fonts-manual').hide();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Populates the omgf_unload_stylesheets hidden field.
|
||||
*/
|
||||
unload_stylesheets: function () {
|
||||
var handle = $(this).closest('tbody');
|
||||
var id = handle[0].id;
|
||||
var checked = $('tbody' + '#' + id + ' input.unload:checked').length;
|
||||
var total = $('tbody' + '#' + id + ' input.unload').length;
|
||||
var unloaded_stylesheets_option = $('#omgf_unload_stylesheets');
|
||||
var unloaded_stylesheets = unloaded_stylesheets_option.val().split(',');
|
||||
|
||||
if (checked === total) {
|
||||
if (unloaded_stylesheets.indexOf(id) === -1) {
|
||||
unloaded_stylesheets.push(id);
|
||||
}
|
||||
|
||||
unloaded_stylesheets.join();
|
||||
|
||||
unloaded_stylesheets_option.val(unloaded_stylesheets);
|
||||
} else {
|
||||
position = unloaded_stylesheets.indexOf(id);
|
||||
|
||||
if (~position) unloaded_stylesheets.splice(position, 1);
|
||||
|
||||
unloaded_stylesheets_option.val(unloaded_stylesheets);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Generate a new cache key upon each unload change.
|
||||
*/
|
||||
generate_cache_key: function () {
|
||||
var current_handle = $(this).data('handle'),
|
||||
cache_keys_input = $('#omgf_cache_keys'),
|
||||
cache_keys = cache_keys_input.val().split(','),
|
||||
checked = $('#' + current_handle + ' input.unload:checked').length,
|
||||
total = $('#' + current_handle + ' input.unload').length,
|
||||
cache_key_index = cache_keys.findIndex((key, index) => {
|
||||
if (key.indexOf(current_handle) !== -1) {
|
||||
return true;
|
||||
}
|
||||
}),
|
||||
no_cache_key = false;
|
||||
|
||||
/**
|
||||
* If no or all boxes are checked, (re-)set cache key to default (without random string).
|
||||
*/
|
||||
if (this.nodeName !== 'SELECT' && (checked === 0 || checked === total)) {
|
||||
cache_keys[cache_key_index] = current_handle;
|
||||
|
||||
no_cache_key = true;
|
||||
}
|
||||
|
||||
if (no_cache_key === true) {
|
||||
cache_keys_input.val(cache_keys.join());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a unique cache key if some of this stylesheet's fonts are unloaded.
|
||||
*/
|
||||
if (cache_key_index !== -1) {
|
||||
var current_cache_key = cache_keys[cache_key_index],
|
||||
cache_key = omgf_admin.cache_prefix + Math.random().toString(36).substring(2, 7);
|
||||
|
||||
if (current_cache_key.indexOf(omgf_admin.cache_prefix) !== -1) {
|
||||
var parts = current_cache_key.split(omgf_admin.cache_prefix),
|
||||
last_part = omgf_admin.get_last_element_index(parts);
|
||||
parts[last_part] = Math.random().toString(36).substring(2, 7);
|
||||
current_cache_key = parts[0];
|
||||
cache_key = omgf_admin.cache_prefix + parts[last_part];
|
||||
}
|
||||
|
||||
cache_keys[cache_key_index] = current_cache_key + cache_key;
|
||||
}
|
||||
|
||||
cache_keys_input.val(cache_keys.join());
|
||||
},
|
||||
|
||||
/**
|
||||
* Toggle preload option associated with this unload option.
|
||||
*/
|
||||
toggle_preload: function () {
|
||||
omgf_admin.toggle(this, 'preload');
|
||||
},
|
||||
|
||||
/**
|
||||
* Toggle unload option associated with the current preload option.
|
||||
*/
|
||||
toggle_unload: function () {
|
||||
omgf_admin.toggle(this, 'unload');
|
||||
},
|
||||
|
||||
/**
|
||||
* Unload all italic styles for current font family.
|
||||
*/
|
||||
unload_italics: function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
var id = $(this).parents('.font-family').data('id');
|
||||
var unloads = $('.unload');
|
||||
|
||||
unloads.each(function (index, item) {
|
||||
if (item.value.includes('italic') && item.dataset.fontId == id && item.checked == false) {
|
||||
item.click();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Unload all fonts for current font family.
|
||||
*/
|
||||
unload_all: function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
var id = $(this).parents('.font-family').data('id');
|
||||
var unloads = $('.unload');
|
||||
|
||||
unloads.each(function (index, item) {
|
||||
if (item.dataset.fontId == id && item.checked == false) {
|
||||
item.click();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Uncheck all unload checkboxes for the current font family.
|
||||
*/
|
||||
load_all: function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
var id = $(this).parents('.font-family').data('id');
|
||||
var unloads = $('.unload');
|
||||
|
||||
unloads.each(function (index, item) {
|
||||
if (item.dataset.fontId == id && item.checked == true) {
|
||||
item.click();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Toggle a checkbox.
|
||||
*
|
||||
* @param elem
|
||||
* @param option
|
||||
*/
|
||||
toggle: function (elem, option) {
|
||||
var this_option = $(elem);
|
||||
var other_option = $('.' + option + '-' + this_option.data('font-id') + '-' + this_option.val() + ' .' + option);
|
||||
|
||||
if (elem.checked) {
|
||||
other_option.attr('disabled', true);
|
||||
} else {
|
||||
other_option.attr('disabled', false);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array
|
||||
* @returns {number}
|
||||
*/
|
||||
get_last_element_index: function (array) {
|
||||
return array.length - 1;
|
||||
},
|
||||
|
||||
/**
|
||||
* Empty queue, db and cache directory.
|
||||
*/
|
||||
empty_cache_directory: function () {
|
||||
if (omgf_admin.empty_cache_directory_xhr) {
|
||||
omgf_admin.empty_cache_directory_xhr.abort();
|
||||
}
|
||||
|
||||
omgf_admin.empty_cache_directory_xhr = $.ajax({
|
||||
type: 'POST',
|
||||
url: ajaxurl,
|
||||
data: {
|
||||
action: 'omgf_ajax_empty_dir',
|
||||
nonce: omgf_admin.nonce,
|
||||
section: omgf_admin.cache_section
|
||||
},
|
||||
beforeSend: function () {
|
||||
omgf_admin.show_loader();
|
||||
},
|
||||
complete: function () {
|
||||
location.reload();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
show_loader_before_submit: function (e) {
|
||||
omgf_admin.show_loader();
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
show_loader: function () {
|
||||
$('#wpcontent').append('<div class="omgf-loading"><span class="spinner is-active"></span></div>');
|
||||
}
|
||||
};
|
||||
|
||||
omgf_show_loader = omgf_admin.show_loader;
|
||||
|
||||
omgf_admin.init();
|
||||
});
|
||||
76
wp-content/plugins/host-webfonts-local/ffwp-autoload.php
Normal file
76
wp-content/plugins/host-webfonts-local/ffwp-autoload.php
Normal file
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
/* * * * * * * * * * * * * * * * * * * * * *
|
||||
* @author : Daan van den Bergh
|
||||
* @url : https://ffw.press/wordpress-plugins/
|
||||
* @copyright: (c) 2021 Daan van den Bergh
|
||||
* @license : GPL2v2 or later
|
||||
* * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
class FFWP_Autoloader
|
||||
{
|
||||
/** @var string $class */
|
||||
private $class;
|
||||
|
||||
/** @var string $file */
|
||||
private $file;
|
||||
|
||||
/**
|
||||
* FFWP_Autoloader constructor.
|
||||
*
|
||||
* @param $class
|
||||
*/
|
||||
public function __construct(
|
||||
$class
|
||||
) {
|
||||
$this->class = $class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build filepath for requested class.
|
||||
*/
|
||||
public function load()
|
||||
{
|
||||
$path = explode('_', $this->class);
|
||||
$this->file = '';
|
||||
$i = 0;
|
||||
|
||||
if (count($path) > 1) {
|
||||
array_shift($path);
|
||||
}
|
||||
end($path);
|
||||
|
||||
/**
|
||||
* Build directory path.
|
||||
*/
|
||||
while ($i < key($path)) {
|
||||
$this->build($path[$i], '', '/');
|
||||
|
||||
$i++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build filename.
|
||||
*/
|
||||
$this->build($path[$i], 'class', '.php');
|
||||
|
||||
return $this->file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if $path is written uppercase entirely, otherwise it'll split $path up and build a string glued with
|
||||
* dashes.
|
||||
*
|
||||
* @param $path
|
||||
* @param string $prefix
|
||||
* @param string $suffix
|
||||
*/
|
||||
private function build($path, $prefix = '', $suffix = '/')
|
||||
{
|
||||
if (ctype_upper($path)) {
|
||||
$this->file .= ($prefix ? $prefix . '-' : '') . strtolower($path) . $suffix;
|
||||
} else {
|
||||
$parts = preg_split('/(?=[A-Z])/', lcfirst($path));
|
||||
$this->file .= ($prefix ? $prefix . '-' : '') . strtolower(implode('-', $parts)) . $suffix;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Plugin Name: OMGF
|
||||
* Plugin URI: https://daan.dev/wordpress-plugins/host-google-fonts-locally
|
||||
* Description: Minimize DNS requests, leverage browser cache and speed up WordPress by saving Google Fonts to your server and removing external Google Fonts requests.
|
||||
* Version: 4.5.13
|
||||
* Author: Daan from FFW.Press
|
||||
* Author URI: https://ffw.press
|
||||
* License: GPL2v2 or later
|
||||
* Text Domain: host-webfonts-local
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Define constants.
|
||||
*/
|
||||
define('OMGF_PLUGIN_DIR', plugin_dir_path(__FILE__));
|
||||
define('OMGF_PLUGIN_FILE', __FILE__);
|
||||
define('OMGF_PLUGIN_BASENAME', plugin_basename(OMGF_PLUGIN_FILE));
|
||||
define('OMGF_STATIC_VERSION', '4.5.11');
|
||||
define('OMGF_DB_VERSION', '4.5.1');
|
||||
|
||||
/**
|
||||
* Takes care of loading classes on demand.
|
||||
*
|
||||
* @param $class
|
||||
*
|
||||
* @return mixed|void
|
||||
*/
|
||||
function omgf_autoload($class)
|
||||
{
|
||||
$path = explode('_', $class);
|
||||
|
||||
if ($path[0] != 'OMGF') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!class_exists('FFWP_Autoloader')) {
|
||||
require_once(OMGF_PLUGIN_DIR . 'ffwp-autoload.php');
|
||||
}
|
||||
|
||||
$autoload = new FFWP_Autoloader($class);
|
||||
|
||||
return include OMGF_PLUGIN_DIR . 'includes/' . $autoload->load();
|
||||
}
|
||||
|
||||
spl_autoload_register('omgf_autoload');
|
||||
|
||||
/**
|
||||
* All systems GO!!!
|
||||
*
|
||||
* @return OMGF
|
||||
*/
|
||||
function omgf_init()
|
||||
{
|
||||
static $omgf = null;
|
||||
|
||||
if ($omgf === null) {
|
||||
$omgf = new OMGF();
|
||||
}
|
||||
|
||||
return $omgf;
|
||||
}
|
||||
|
||||
omgf_init();
|
||||
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
/* * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* ██████╗ ███╗ ███╗ ██████╗ ███████╗
|
||||
* ██╔═══██╗████╗ ████║██╔════╝ ██╔════╝
|
||||
* ██║ ██║██╔████╔██║██║ ███╗█████╗
|
||||
* ██║ ██║██║╚██╔╝██║██║ ██║██╔══╝
|
||||
* ╚██████╔╝██║ ╚═╝ ██║╚██████╔╝██║
|
||||
* ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝
|
||||
*
|
||||
* @package : OMGF
|
||||
* @author : Daan van den Bergh
|
||||
* @copyright: (c) 2021 Daan van den Bergh
|
||||
* @url : https://daan.dev
|
||||
* * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
class OMGF_Admin_Notice
|
||||
{
|
||||
const OMGF_ADMIN_NOTICE_TRANSIENT = 'omgf_admin_notice';
|
||||
const OMGF_ADMIN_NOTICE_EXPIRATION = 60;
|
||||
|
||||
/** @var array $notices */
|
||||
public static $notices = [];
|
||||
|
||||
/**
|
||||
* @param $message
|
||||
* @param string $type (info|warning|error|success)
|
||||
* @param string $screen_id
|
||||
* @param bool $json
|
||||
* @param int $code
|
||||
*/
|
||||
public static function set_notice($message, $message_id = '', $die = true, $type = 'success', $code = 200, $screen_id = 'all')
|
||||
{
|
||||
self::$notices = get_transient(self::OMGF_ADMIN_NOTICE_TRANSIENT);
|
||||
|
||||
if (!self::$notices) {
|
||||
self::$notices = [];
|
||||
}
|
||||
|
||||
self::$notices[$screen_id][$type][$message_id] = $message;
|
||||
|
||||
set_transient(self::OMGF_ADMIN_NOTICE_TRANSIENT, self::$notices, self::OMGF_ADMIN_NOTICE_EXPIRATION);
|
||||
|
||||
if ($die) {
|
||||
switch ($type) {
|
||||
case 'error':
|
||||
wp_send_json_error($message, $code);
|
||||
break;
|
||||
default:
|
||||
wp_send_json_success($message, $code);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $message_id
|
||||
* @param string $type
|
||||
* @param string $screen_id
|
||||
*/
|
||||
public static function unset_notice($message_id = '', $type = 'info', $screen_id = 'all')
|
||||
{
|
||||
self::$notices = get_transient(self::OMGF_ADMIN_NOTICE_TRANSIENT);
|
||||
|
||||
if (isset(self::$notices[$screen_id][$type][$message_id])) {
|
||||
unset(self::$notices[$screen_id][$type][$message_id]);
|
||||
}
|
||||
|
||||
if (is_array(self::$notices) && empty(self::$notices[$screen_id][$type])) {
|
||||
unset(self::$notices[$screen_id][$type]);
|
||||
}
|
||||
|
||||
set_transient(self::OMGF_ADMIN_NOTICE_TRANSIENT, self::$notices, self::OMGF_ADMIN_NOTICE_EXPIRATION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints notice (if any) grouped by type.
|
||||
*/
|
||||
public static function print_notices()
|
||||
{
|
||||
$admin_notices = get_transient(self::OMGF_ADMIN_NOTICE_TRANSIENT);
|
||||
|
||||
if (is_array($admin_notices)) {
|
||||
$current_screen = get_current_screen();
|
||||
|
||||
foreach ($admin_notices as $screen => $notice) {
|
||||
if ($current_screen->id != $screen && $screen != 'all') {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($notice as $type => $message) {
|
||||
?>
|
||||
<div id="message" class="notice notice-<?php echo $type; ?> is-dismissible">
|
||||
<?php foreach ($message as $line) : ?>
|
||||
<p><strong><?= $line; ?></strong></p>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete_transient(self::OMGF_ADMIN_NOTICE_TRANSIENT);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,526 @@
|
||||
<?php
|
||||
/* * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* ██████╗ ███╗ ███╗ ██████╗ ███████╗
|
||||
* ██╔═══██╗████╗ ████║██╔════╝ ██╔════╝
|
||||
* ██║ ██║██╔████╔██║██║ ███╗█████╗
|
||||
* ██║ ██║██║╚██╔╝██║██║ ██║██╔══╝
|
||||
* ╚██████╔╝██║ ╚═╝ ██║╚██████╔╝██║
|
||||
* ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝
|
||||
*
|
||||
* @package : OMGF
|
||||
* @author : Daan van den Bergh
|
||||
* @copyright: (c) 2021 Daan van den Bergh
|
||||
* @url : https://daan.dev
|
||||
* * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
class OMGF_Admin_Settings extends OMGF_Admin
|
||||
{
|
||||
const OMGF_ADMIN_PAGE = 'optimize-webfonts';
|
||||
|
||||
/**
|
||||
* Transients
|
||||
*/
|
||||
const OMGF_NEWS_REEL = 'omgf_news_reel';
|
||||
const OMGF_CURRENT_DB_VERSION = 'omgf_current_db_version';
|
||||
|
||||
/**
|
||||
* Settings Fields
|
||||
*/
|
||||
const OMGF_SETTINGS_FIELD_OPTIMIZE = 'omgf-optimize-settings';
|
||||
const OMGF_SETTINGS_FIELD_DETECTION = 'omgf-detection-settings';
|
||||
const OMGF_SETTINGS_FIELD_ADVANCED = 'omgf-advanced-settings';
|
||||
const OMGF_SETTINGS_FIELD_HELP = 'omgf-help';
|
||||
|
||||
/**
|
||||
* Option Values
|
||||
*/
|
||||
const OMGF_OPTIMIZATION_MODE = [
|
||||
'manual' => 'Manual (default)',
|
||||
'auto' => 'Automatic (Pro)'
|
||||
];
|
||||
const OMGF_FONT_PROCESSING_OPTIONS = [
|
||||
'replace' => 'Replace (default)',
|
||||
'remove' => 'Remove only'
|
||||
];
|
||||
const OMGF_FONT_DISPLAY_OPTIONS = [
|
||||
'swap' => 'Swap (recommended)',
|
||||
'auto' => 'Auto',
|
||||
'block' => 'Block',
|
||||
'fallback' => 'Fallback',
|
||||
'optional' => 'Optional'
|
||||
];
|
||||
const OMGF_FILE_TYPES_OPTIONS = [
|
||||
'woff2' => 'Web Open Font Format 2.0 (WOFF2)',
|
||||
'woff' => 'Web Open Font Format (WOFF)',
|
||||
'eot' => 'Embedded OpenType (EOT)',
|
||||
'ttf' => 'TrueType Font (TTF)',
|
||||
'svg' => 'Scalable Vector Graphics (SVG)'
|
||||
];
|
||||
const OMGF_FORCE_SUBSETS_OPTIONS = [
|
||||
'arabic' => 'Arabic',
|
||||
'bengali' => 'Bengali',
|
||||
'chinese-hongkong' => 'Chinese (Hong Kong)',
|
||||
'chinese-simplified' => 'Chinese (Simplified)',
|
||||
'chinese-traditional' => 'Chinese (Traditional)',
|
||||
'cyrillic' => 'Cyrillic',
|
||||
'cyrillic-ext' => 'Cyrillic Extended',
|
||||
'devanagari' => 'Devanagari',
|
||||
'greek' => 'Greek',
|
||||
'greek-ext' => 'Greek Extended',
|
||||
'gujarati' => 'Gujarati',
|
||||
'gurmukhi' => 'Gurmukhi',
|
||||
'hebrew' => 'Hebrew',
|
||||
'japanese' => 'Japanese',
|
||||
'kannada' => 'Kannada',
|
||||
'khmer' => 'Khmer',
|
||||
'korean' => 'Korean',
|
||||
'latin' => 'Latin',
|
||||
'latin-ext' => 'Latin Extended',
|
||||
'malayalam' => 'Malayalam',
|
||||
'myanmar' => 'Myanmar',
|
||||
'oriya' => 'Oriya',
|
||||
'sinhala' => 'Sinhala',
|
||||
'tamil' => 'Tamil',
|
||||
'telugu' => 'Telugu',
|
||||
'thai' => 'Thai',
|
||||
'tibetan' => 'Tibetan',
|
||||
'vietnamese' => 'Vietnamese'
|
||||
];
|
||||
const OMGF_FALLBACK_FONT_STACKS_OPTIONS = [
|
||||
'arial' => 'Arial',
|
||||
'baskerville' => 'Baskerville',
|
||||
'bodoni-mt' => 'Bodoni MT',
|
||||
'calibri' => 'Calibri',
|
||||
'calisto-mt' => 'Calisto MT',
|
||||
'cambria' => 'Cambria',
|
||||
'candara' => 'Candara',
|
||||
'century-gothic' => 'Century Gothic',
|
||||
'consolas' => 'Consolas',
|
||||
'copperplate-gothic' => 'Copperplate Gothic',
|
||||
'courier-new' => 'Courier New',
|
||||
'dejavu-sans' => 'Dejavu Sans',
|
||||
'didot' => 'Didot',
|
||||
'franklin-gothic' => 'Franklin Gothic',
|
||||
'garamond' => 'Garamond',
|
||||
'georgia' => 'Georgia',
|
||||
'gill-sans' => 'Gill Sans',
|
||||
'goudy-old-style' => 'Goudy Old Style',
|
||||
'helvetica' => 'Helvetica',
|
||||
'impact' => 'Impact',
|
||||
'lucida-bright' => 'Lucida Bright',
|
||||
'lucida-sans' => 'Lucida Sans',
|
||||
'ms-sans-serif' => 'Microsoft Sans Serif',
|
||||
'optima' => 'Optima',
|
||||
'palatino' => 'Palatino',
|
||||
'perpetua' => 'Perpetua',
|
||||
'rockwell' => 'Rockwell',
|
||||
'segoe-ui' => 'Segoe UI',
|
||||
'tahoma' => 'Tahoma',
|
||||
'trebuchet-ms' => 'Trebuchet MS',
|
||||
'verdana' => 'Verdana'
|
||||
];
|
||||
const OMGF_AMP_HANDLING_OPTIONS = [
|
||||
'fallback' => 'Fallback (default)',
|
||||
'disable' => 'Disable'
|
||||
];
|
||||
|
||||
/**
|
||||
* Optimize Fonts
|
||||
*/
|
||||
const OMGF_OPTIMIZE_SETTING_DISPLAY_OPTION = 'omgf_display_option';
|
||||
const OMGF_OPTIMIZE_SETTING_MANUAL_OPTIMIZE_URL = 'omgf_manual_optimize_url';
|
||||
const OMGF_OPTIMIZE_SETTING_OPTIMIZATION_MODE = 'omgf_optimization_mode';
|
||||
const OMGF_OPTIMIZE_SETTING_OPTIMIZED_FONTS = 'omgf_optimized_fonts';
|
||||
const OMGF_OPTIMIZE_SETTING_OPTIMIZE_EDIT_ROLES = 'omgf_optimize_edit_roles';
|
||||
const OMGF_OPTIMIZE_SETTING_PRELOAD_FONTS = 'omgf_preload_fonts';
|
||||
const OMGF_OPTIMIZE_SETTING_UNLOAD_FONTS = 'omgf_unload_fonts';
|
||||
const OMGF_OPTIMIZE_SETTING_UNLOAD_STYLESHEETS = 'omgf_unload_stylesheets';
|
||||
const OMGF_OPTIMIZE_SETTING_CACHE_KEYS = 'omgf_cache_keys';
|
||||
|
||||
/**
|
||||
* Detection Settings
|
||||
*/
|
||||
const OMGF_DETECTION_SETTING_FONT_PROCESSING = 'omgf_font_processing';
|
||||
|
||||
/**
|
||||
* Advanced Settings
|
||||
*/
|
||||
const OMGF_ADV_SETTING_AMP_HANDLING = 'omgf_amp_handling';
|
||||
const OMGF_ADV_SETTING_CACHE_PATH = 'omgf_cache_dir';
|
||||
const OMGF_ADV_SETTING_SOURCE_URL = 'omgf_fonts_url';
|
||||
const OMGF_ADV_SETTING_UNINSTALL = 'omgf_uninstall';
|
||||
|
||||
/**
|
||||
* Miscellaneous
|
||||
*/
|
||||
const OMGF_OPTIONS_GENERAL_PAGE_OPTIMIZE_WEBFONTS = 'options-general.php?page=optimize-webfonts';
|
||||
const OMGF_PLUGINS_INSTALL_CHANGELOG_SECTION = 'plugin-install.php?tab=plugin-information&plugin=host-webfonts-local&TB_iframe=true&width=772&height=1015§ion=changelog';
|
||||
const FFWP_WORDPRESS_PLUGINS_OMGF_PRO = 'https://ffw.press/wordpress/omgf-pro/';
|
||||
|
||||
/** @var string $active_tab */
|
||||
private $active_tab;
|
||||
|
||||
/** @var string $page */
|
||||
private $page;
|
||||
|
||||
/** @var string $plugin_text_domain */
|
||||
private $plugin_text_domain = 'host-webfonts-local';
|
||||
|
||||
/** @var string|null */
|
||||
private $submit_button_text = null;
|
||||
|
||||
/**
|
||||
* OMGF_Admin_Settings constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->active_tab = isset($_GET['tab']) ? $_GET['tab'] : self::OMGF_SETTINGS_FIELD_OPTIMIZE;
|
||||
$this->page = isset($_GET['page']) ? $_GET['page'] : '';
|
||||
|
||||
add_action('admin_menu', [$this, 'create_menu']);
|
||||
add_filter('plugin_action_links_' . plugin_basename(OMGF_PLUGIN_FILE), [$this, 'create_settings_link']);
|
||||
|
||||
if ($this->page !== self::OMGF_ADMIN_PAGE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->active_tab == self::OMGF_SETTINGS_FIELD_OPTIMIZE) {
|
||||
$this->submit_button_text = __('Save & Optimize', $this->plugin_text_domain);
|
||||
}
|
||||
|
||||
// Footer Text
|
||||
add_filter('admin_footer_text', [$this, 'footer_text_left'], 99);
|
||||
add_filter('update_footer', [$this, 'footer_text_right'], 11);
|
||||
|
||||
// Tabs
|
||||
add_action('omgf_settings_tab', [$this, 'optimize_fonts_tab'], 0);
|
||||
add_action('omgf_settings_tab', [$this, 'detection_settings_tab'], 1);
|
||||
add_action('omgf_settings_tab', [$this, 'advanced_settings_tab'], 2);
|
||||
add_action('omgf_settings_tab', [$this, 'help_tab'], 3);
|
||||
|
||||
// Content
|
||||
add_action('omgf_settings_content', [$this, 'optimize_fonts_content'], 0);
|
||||
add_action('omgf_settings_content', [$this, 'detection_settings_content'], 1);
|
||||
add_action('omgf_settings_content', [$this, 'advanced_settings_content'], 2);
|
||||
add_action('omgf_settings_content', [$this, 'help_content'], 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the menu item.
|
||||
*/
|
||||
public function create_menu()
|
||||
{
|
||||
add_options_page(
|
||||
'OMGF',
|
||||
'Optimize Google Fonts',
|
||||
'manage_options',
|
||||
self::OMGF_ADMIN_PAGE,
|
||||
[$this, 'create_settings_page']
|
||||
);
|
||||
|
||||
add_action('admin_init', [$this, 'register_settings']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the settings page.
|
||||
*/
|
||||
public function create_settings_page()
|
||||
{
|
||||
if (!current_user_can('manage_options')) {
|
||||
wp_die(__("You're not cool enough to access this page.", $this->plugin_text_domain));
|
||||
}
|
||||
?>
|
||||
<div class="wrap omgf">
|
||||
<h1><?= apply_filters('omgf_settings_page_title', __('OMGF | Optimize My Google Fonts', $this->plugin_text_domain)); ?></h1>
|
||||
|
||||
<p>
|
||||
<?= get_plugin_data(OMGF_PLUGIN_FILE)['Description']; ?>
|
||||
</p>
|
||||
|
||||
<div class="settings-column">
|
||||
<h2 class="omgf-nav nav-tab-wrapper">
|
||||
<?php do_action('omgf_settings_tab'); ?>
|
||||
</h2>
|
||||
|
||||
<?php do_action('omgf_settings_content'); ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Register all settings.
|
||||
*
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function register_settings()
|
||||
{
|
||||
if (
|
||||
$this->active_tab !== self::OMGF_SETTINGS_FIELD_OPTIMIZE
|
||||
&& $this->active_tab !== self::OMGF_SETTINGS_FIELD_DETECTION
|
||||
&& $this->active_tab !== self::OMGF_SETTINGS_FIELD_ADVANCED
|
||||
&& $this->active_tab !== self::OMGF_SETTINGS_FIELD_HELP
|
||||
) {
|
||||
$this->active_tab = apply_filters('omgf_admin_settings_active_tab', self::OMGF_SETTINGS_FIELD_OPTIMIZE);
|
||||
}
|
||||
|
||||
foreach ($this->get_settings() as $constant => $value) {
|
||||
register_setting(
|
||||
$this->active_tab,
|
||||
$value
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all settings using the constants in this class.
|
||||
*
|
||||
* @return array
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function get_settings()
|
||||
{
|
||||
$reflection = new ReflectionClass($this);
|
||||
$constants = apply_filters('omgf_settings_constants', $reflection->getConstants());
|
||||
|
||||
switch ($this->active_tab) {
|
||||
case (self::OMGF_SETTINGS_FIELD_DETECTION):
|
||||
$needle = 'OMGF_DETECTION_SETTING_';
|
||||
break;
|
||||
case (self::OMGF_SETTINGS_FIELD_ADVANCED):
|
||||
$needle = 'OMGF_ADV_SETTING_';
|
||||
break;
|
||||
case (self::OMGF_SETTINGS_FIELD_HELP):
|
||||
$needle = 'OMGF_HELP_SETTING_';
|
||||
default:
|
||||
$needle = apply_filters('omgf_settings_needle', 'OMGF_OPTIMIZE_SETTING_');
|
||||
}
|
||||
|
||||
return array_filter(
|
||||
$constants,
|
||||
function ($key) use ($needle) {
|
||||
return strpos($key, $needle) !== false;
|
||||
},
|
||||
ARRAY_FILTER_USE_KEY
|
||||
);
|
||||
}
|
||||
|
||||
public function optimize_fonts_tab()
|
||||
{
|
||||
$this->generate_tab(self::OMGF_SETTINGS_FIELD_OPTIMIZE, 'dashicons-performance', __('Optimize Fonts', $this->plugin_text_domain));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Basic Settings Tab to Settings Screen.
|
||||
*/
|
||||
public function detection_settings_tab()
|
||||
{
|
||||
$this->generate_tab(self::OMGF_SETTINGS_FIELD_DETECTION, 'dashicons-search', __('Detection Settings', $this->plugin_text_domain));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Advanced Settings Tab to Settings Screen.
|
||||
*/
|
||||
public function advanced_settings_tab()
|
||||
{
|
||||
$this->generate_tab(self::OMGF_SETTINGS_FIELD_ADVANCED, 'dashicons-admin-settings', __('Advanced Settings', $this->plugin_text_domain));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Help Tab to Settings Screen.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function help_tab()
|
||||
{
|
||||
$this->generate_tab(self::OMGF_SETTINGS_FIELD_HELP, 'dashicons-editor-help', __('Help', $this->plugin_text_domain));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
* @param null $icon
|
||||
* @param null $label
|
||||
*/
|
||||
private function generate_tab($id, $icon = null, $label = null)
|
||||
{
|
||||
?>
|
||||
<a class="nav-tab dashicons-before <?= $icon; ?> <?= $this->active_tab == $id ? 'nav-tab-active' : ''; ?>" href="<?= $this->generate_tab_link($id); ?>">
|
||||
<?= $label; ?>
|
||||
</a>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $tab
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function generate_tab_link($tab)
|
||||
{
|
||||
return admin_url(self::OMGF_OPTIONS_GENERAL_PAGE_OPTIMIZE_WEBFONTS . "&tab=$tab");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function optimize_fonts_content()
|
||||
{
|
||||
$this->do_settings_content(self::OMGF_SETTINGS_FIELD_OPTIMIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render Basic Settings content
|
||||
*/
|
||||
public function detection_settings_content()
|
||||
{
|
||||
$this->do_settings_content(self::OMGF_SETTINGS_FIELD_DETECTION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render Advanced Settings content
|
||||
*/
|
||||
public function advanced_settings_content()
|
||||
{
|
||||
$this->do_settings_content(self::OMGF_SETTINGS_FIELD_ADVANCED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render Help content
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function help_content()
|
||||
{
|
||||
$this->do_settings_content(self::OMGF_SETTINGS_FIELD_HELP);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $field
|
||||
*/
|
||||
private function do_settings_content($field)
|
||||
{
|
||||
if ($this->active_tab != $field) {
|
||||
return;
|
||||
}
|
||||
?>
|
||||
<form id="<?= $field; ?>-form" name="omgf-settings-form" method="post" action="<?= admin_url('options.php?tab=' . $this->active_tab); ?>" autocomplete="off">
|
||||
<?php
|
||||
settings_fields($field);
|
||||
do_settings_sections($field);
|
||||
|
||||
do_action('omgf_before_settings_form_settings');
|
||||
|
||||
echo apply_filters(str_replace('-', '_', $field) . '_content', '');
|
||||
|
||||
do_action('omgf_after_settings_form_settings');
|
||||
|
||||
?>
|
||||
<?php if ($this->active_tab !== self::OMGF_SETTINGS_FIELD_HELP) : ?>
|
||||
<?php submit_button($this->submit_button_text, 'primary', 'submit', false); ?>
|
||||
<a id="omgf-empty" data-cache-section="/*" data-nonce="<?= wp_create_nonce(self::OMGF_ADMIN_PAGE); ?>" class="omgf-empty button-cancel"><?php _e('Empty Cache Directory', $this->plugin_text_domain); ?></a>
|
||||
<?php endif; ?>
|
||||
</form>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $links
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function create_settings_link($links)
|
||||
{
|
||||
$adminUrl = admin_url() . self::OMGF_OPTIONS_GENERAL_PAGE_OPTIMIZE_WEBFONTS;
|
||||
$settingsLink = "<a href='$adminUrl'>" . __('Settings') . "</a>";
|
||||
array_push($links, $settingsLink);
|
||||
|
||||
return $links;
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes footer text.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function footer_text_left()
|
||||
{
|
||||
$text = sprintf(__('Coded with %s in The Netherlands @ <strong>FFW.Press</strong>.', $this->plugin_text_domain), '<span class="dashicons dashicons-heart ffwp-heart"></span>');
|
||||
|
||||
return '<span id="footer-thankyou">' . $text . '</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* All logic to generate the news reel in the bottom right of the footer on all of OMGF's settings pages.
|
||||
*
|
||||
* Includes multiple checks to make sure the reel is only shown if a recent post is available.
|
||||
*
|
||||
* @param mixed $text
|
||||
* @return mixed
|
||||
*/
|
||||
public function footer_text_right($text)
|
||||
{
|
||||
if (!extension_loaded('simplexml')) {
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* If a WordPress update is available, show the original text.
|
||||
*/
|
||||
if (strpos($text, 'Get Version') !== false) {
|
||||
return $text;
|
||||
}
|
||||
|
||||
// Prevents bashing the API.
|
||||
$xml = get_transient(self::OMGF_NEWS_REEL);
|
||||
|
||||
if (!$xml) {
|
||||
$response = wp_remote_get('https://ffw.press/blog/tag/omgf/feed');
|
||||
|
||||
if (!is_wp_error($response)) {
|
||||
$xml = wp_remote_retrieve_body($response);
|
||||
|
||||
// Refresh the feed once a day to prevent bashing of the API.
|
||||
set_transient(self::OMGF_NEWS_REEL, $xml, DAY_IN_SECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$xml) {
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure the XML is properly encoded.
|
||||
*/
|
||||
$xml = utf8_encode(html_entity_decode($xml));
|
||||
$xml = simplexml_load_string($xml);
|
||||
|
||||
if (!$xml) {
|
||||
return $text;
|
||||
}
|
||||
|
||||
$items = $xml->channel->item ?? [];
|
||||
|
||||
if (empty($items)) {
|
||||
return $text;
|
||||
}
|
||||
|
||||
$text = sprintf(__('Recently tagged <a target="_blank" href="%s"><strong>#OMGF</strong></a> on my blog:', $this->plugin_text_domain), 'https://daan.dev/tag/omgf') . ' ';
|
||||
$text .= '<span id="omgf-ticker-wrap">';
|
||||
$i = 0;
|
||||
|
||||
foreach ($items as $item) {
|
||||
$hide = $i > 0 ? 'style="display: none;"' : '';
|
||||
$text .= "<span class='ticker-item' $hide>" . sprintf('<a target="_blank" href="%s"><em>%s</em></a>', $item->link, $item->title) . '</span>';
|
||||
$i++;
|
||||
}
|
||||
|
||||
$text .= "</span>";
|
||||
|
||||
return $text;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
/* * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* ██████╗ ███╗ ███╗ ██████╗ ███████╗
|
||||
* ██╔═══██╗████╗ ████║██╔════╝ ██╔════╝
|
||||
* ██║ ██║██╔████╔██║██║ ███╗█████╗
|
||||
* ██║ ██║██║╚██╔╝██║██║ ██║██╔══╝
|
||||
* ╚██████╔╝██║ ╚═╝ ██║╚██████╔╝██║
|
||||
* ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝
|
||||
*
|
||||
* @package : OMGF
|
||||
* @author : Daan van den Bergh
|
||||
* @copyright: (c) 2021 Daan van den Bergh
|
||||
* @url : https://daan.dev
|
||||
* * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
class OMGF_Admin_Settings_Advanced extends OMGF_Admin_Settings_Builder
|
||||
{
|
||||
/**
|
||||
* OMGF_Admin_Settings_Advanced constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->title = __('Advanced Settings', $this->plugin_text_domain);
|
||||
|
||||
// Open
|
||||
add_filter('omgf_advanced_settings_content', [$this, 'do_title'], 10);
|
||||
add_filter('omgf_advanced_settings_content', [$this, 'do_description'], 15);
|
||||
add_filter('omgf_advanced_settings_content', [$this, 'do_before'], 20);
|
||||
|
||||
// Settings
|
||||
add_filter('omgf_advanced_settings_content', [$this, 'do_promo_amp_handling'], 40);
|
||||
add_filter('omgf_advanced_settings_content', [$this, 'do_promo_exclude_posts'], 50);
|
||||
add_filter('omgf_advanced_settings_content', [$this, 'do_cache_dir'], 70);
|
||||
add_filter('omgf_advanced_settings_content', [$this, 'do_promo_fonts_source_url'], 80);
|
||||
add_filter('omgf_advanced_settings_content', [$this, 'do_uninstall'], 110);
|
||||
|
||||
// Close
|
||||
add_filter('omgf_advanced_settings_content', [$this, 'do_after'], 200);
|
||||
}
|
||||
|
||||
/**
|
||||
* Description
|
||||
*/
|
||||
public function do_description()
|
||||
{
|
||||
?>
|
||||
<p>
|
||||
<?= __('If you require the downloaded/generated files to be saved in a different location or served from a different resource (e.g. a CDN) or path, use these settings to make OMGF work with your configuration.', $this->plugin_text_domain); ?>
|
||||
</p>
|
||||
<?php
|
||||
}
|
||||
|
||||
public function do_promo_amp_handling()
|
||||
{
|
||||
$this->do_select(
|
||||
__('AMP handling (Pro)', $this->plugin_text_domain),
|
||||
'omgf_pro_amp_handling',
|
||||
OMGF_Admin_Settings::OMGF_AMP_HANDLING_OPTIONS,
|
||||
defined('OMGF_PRO_AMP_HANDLING') ? OMGF_PRO_AMP_HANDLING : '',
|
||||
sprintf(__("Decide how OMGF Pro should behave on AMP pages. Only select <strong>enable</strong> if the custom CSS limit of 75kb is not already reached by your theme and/or other plugins and no other <code>amp-custom</code> tag is present on your pages.", $this->plugin_text_domain), OMGF_Admin_Settings::FFWP_WORDPRESS_PLUGINS_OMGF_PRO) . ' ' . $this->promo,
|
||||
false,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Excluded Post/Page IDs (Pro)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function do_promo_exclude_posts()
|
||||
{
|
||||
$this->do_text(
|
||||
__('Excluded Post/Page IDs (Pro)', $this->plugin_text_domain),
|
||||
'omgf_pro_excluded_ids',
|
||||
__('e.g. 1,2,5,21,443'),
|
||||
defined('OMGF_PRO_EXCLUDED_IDS') ? OMGF_PRO_EXCLUDED_IDS : '',
|
||||
__('A comma separated list of post/page IDs where OMGF Pro shouldn\'t run. Only works when Advanced Proccessing is enabled under Detection Settings.', $this->plugin_text_domain) . ' ' . $this->promo,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function do_cache_dir()
|
||||
{
|
||||
$this->do_text(
|
||||
__('Fonts Cache Directory', $this->plugin_text_domain),
|
||||
OMGF_Admin_Settings::OMGF_ADV_SETTING_CACHE_PATH,
|
||||
__('e.g. /uploads/omgf', $this->plugin_text_domain),
|
||||
OMGF_CACHE_PATH,
|
||||
__("The directory (inside <code>wp-content</code>) where font files should be stored. Give each site a unique value if you're using Multisite. Defaults to <code>/uploads/omgf</code>. After changing this setting, the directory will be created if it doesn't exist and existing files will be moved automatically.", $this->plugin_text_domain)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function do_promo_fonts_source_url()
|
||||
{
|
||||
$this->do_text(
|
||||
__('Fonts Source URL (Pro)', $this->plugin_text_domain),
|
||||
'omgf_pro_source_url',
|
||||
__('e.g. https://cdn.mydomain.com/alternate/relative-path', $this->plugin_text_domain),
|
||||
defined('OMGF_PRO_SOURCE_URL') ? OMGF_PRO_SOURCE_URL : '',
|
||||
sprintf(
|
||||
__("Modify the <code>src</code> URL for each font file in the stylesheet. This can be anything, like an absolute URL (e.g. <code>%s</code>) to an alternate relative URL (e.g. <code>/renamed-wp-content-dir/alternate/path/to/font-files</code>). Make sure you include the full path to where OMGF's files are stored and/or served from. Defaults to <code>%s</code>.", $this->plugin_text_domain),
|
||||
str_replace(home_url(), 'https://your-cdn.com', WP_CONTENT_URL . OMGF_CACHE_PATH),
|
||||
WP_CONTENT_URL . OMGF_CACHE_PATH
|
||||
) . ' ' . $this->promo,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function do_uninstall()
|
||||
{
|
||||
$this->do_checkbox(
|
||||
__('Remove Settings/Files At Uninstall', $this->plugin_text_domain),
|
||||
OMGF_Admin_Settings::OMGF_ADV_SETTING_UNINSTALL,
|
||||
OMGF_UNINSTALL,
|
||||
__('Warning! This will remove all settings and cached fonts upon plugin deletion.', $this->plugin_text_domain)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,223 @@
|
||||
<?php
|
||||
/* * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* ██████╗ ███╗ ███╗ ██████╗ ███████╗
|
||||
* ██╔═══██╗████╗ ████║██╔════╝ ██╔════╝
|
||||
* ██║ ██║██╔████╔██║██║ ███╗█████╗
|
||||
* ██║ ██║██║╚██╔╝██║██║ ██║██╔══╝
|
||||
* ╚██████╔╝██║ ╚═╝ ██║╚██████╔╝██║
|
||||
* ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝
|
||||
*
|
||||
* @package : OMGF
|
||||
* @author : Daan van den Bergh
|
||||
* @copyright: (c) 2021 Daan van den Bergh
|
||||
* @url : https://daan.dev
|
||||
* * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
class OMGF_Admin_Settings_Builder
|
||||
{
|
||||
/** @var string $plugin_text_domain */
|
||||
protected $plugin_text_domain = 'host-webfonts-local';
|
||||
|
||||
/** @var $title */
|
||||
protected $title;
|
||||
|
||||
/** @var $promo string */
|
||||
protected $promo;
|
||||
|
||||
/**
|
||||
* Only sets the promo string on settings load.
|
||||
*
|
||||
* OMGF_Admin_Settings_Builder constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
add_filter('omgf_optimize_settings_content', [$this, 'do_promo']);
|
||||
add_filter('omgf_detection_settings_content', [$this, 'do_promo']);
|
||||
add_filter('omgf_advanced_settings_content', [$this, 'do_promo']);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function do_promo()
|
||||
{
|
||||
if (apply_filters('apply_omgf_pro_promo', true)) {
|
||||
$this->promo = apply_filters('omgf_pro_promo', sprintf(__('<a href="%s" target="_blank">Upgrade to Pro</a> to enable this option.', $this->plugin_text_domain), OMGF_Admin_Settings::FFWP_WORDPRESS_PLUGINS_OMGF_PRO));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function do_before()
|
||||
{
|
||||
?>
|
||||
<table class="form-table">
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function do_after()
|
||||
{
|
||||
?>
|
||||
</table>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function do_title()
|
||||
{
|
||||
?>
|
||||
<h3><?= $this->title ?></h3>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate radio setting
|
||||
*
|
||||
* @param $label
|
||||
* @param $inputs
|
||||
* @param $name
|
||||
* @param $checked
|
||||
* @param $description
|
||||
*/
|
||||
public function do_radio($label, $inputs, $name, $checked, $description)
|
||||
{
|
||||
?>
|
||||
<tr>
|
||||
<th scope="row"><?= $label; ?></th>
|
||||
<td>
|
||||
<?php foreach ($inputs as $option => $option_label) : ?>
|
||||
<label>
|
||||
<input type="radio" <?= strpos($option_label, '(Pro)') !== false ? apply_filters($name . '_' . $option . '_setting_disabled', 'disabled') : ''; ?> class="<?= str_replace('_', '-', $name . '_' . $option); ?>" name="<?= $name; ?>" value="<?= $option; ?>" <?= $option == $checked ? 'checked="checked"' : ''; ?> />
|
||||
<?= $option_label; ?>
|
||||
</label>
|
||||
<br />
|
||||
<?php endforeach; ?>
|
||||
<p class="description">
|
||||
<?= $description . ' ' . $this->promo; ?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate select setting
|
||||
*
|
||||
* @param $label
|
||||
* @param $name
|
||||
* @param $options
|
||||
* @param $selected
|
||||
* @param $description
|
||||
* @param bool $update_required
|
||||
*/
|
||||
public function do_select($label, $name, $options, $selected, $description, $is_multiselect = false, $disabled = false)
|
||||
{
|
||||
?>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<?= apply_filters($name . '_setting_label', $label); ?>
|
||||
</th>
|
||||
<td>
|
||||
<select name="<?= $name; ?><?= $is_multiselect ? '[]' : ''; ?>" class="<?= str_replace('_', '-', $name); ?>" <?= $is_multiselect ? 'size="8" multiple="multiple"' : ''; ?> <?= apply_filters($name . '_setting_disabled', $disabled) ? 'disabled' : ''; ?>>
|
||||
<?php
|
||||
$options = apply_filters($name . '_setting_options', $options);
|
||||
?>
|
||||
<?php foreach ($options as $option => $option_label) : ?>
|
||||
<?php
|
||||
if (is_array($selected)) {
|
||||
$is_selected = in_array($option, $selected);
|
||||
} else {
|
||||
$is_selected = $selected == $option;
|
||||
}
|
||||
?>
|
||||
<option value="<?= $option; ?>" <?= $is_selected ? 'selected="selected"' : ''; ?>><?= $option_label; ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<p class="description">
|
||||
<?= apply_filters($name . '_setting_description', $description); ?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate number setting.
|
||||
*
|
||||
* @param $label
|
||||
* @param $name
|
||||
* @param $value
|
||||
* @param $description
|
||||
*/
|
||||
public function do_number($label, $name, $value, $description, $min = 0, $visible = true)
|
||||
{
|
||||
?>
|
||||
<tr valign="top" <?= $visible ? '' : 'style="display: none;"'; ?>>
|
||||
<th scope="row"><?= apply_filters($name . '_setting_label', $label); ?></th>
|
||||
<td>
|
||||
<input class="<?= str_replace('_', '-', $name); ?>" type="number" name="<?= $name; ?>" min="<?= $min; ?>" value="<?= $value; ?>" />
|
||||
<p class="description">
|
||||
<?= apply_filters($name . '_setting_description', $description); ?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate text setting.
|
||||
*
|
||||
* @param $label
|
||||
* @param $name
|
||||
* @param $placeholder
|
||||
* @param $value
|
||||
* @param string $description
|
||||
* @param bool $update_required
|
||||
*/
|
||||
public function do_text($label, $name, $placeholder, $value, $description = '', $disabled = false)
|
||||
{
|
||||
?>
|
||||
<tr class="<?= str_replace('_', '-', $name); ?>-row">
|
||||
<th scope="row"><?= apply_filters($name . '_setting_label', $label); ?></th>
|
||||
<td>
|
||||
<input <?= apply_filters($name . '_setting_disabled', $disabled) ? 'disabled' : ''; ?> class="<?= str_replace('_', '-', $name); ?>" type="text" name="<?= $name; ?>" placeholder="<?= $placeholder; ?>" value="<?= $value; ?>" />
|
||||
<p class="description">
|
||||
<?= apply_filters($name . 'setting_description', $description); ?>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate checkbox setting.
|
||||
*
|
||||
* @param $label
|
||||
* @param $name
|
||||
* @param $checked
|
||||
* @param $description
|
||||
*/
|
||||
public function do_checkbox($label, $name, $checked, $description, $disabled = false)
|
||||
{
|
||||
?>
|
||||
<tr>
|
||||
<th scope="row"><?= apply_filters($name . '_setting_label', $label); ?></th>
|
||||
<td>
|
||||
<label for="<?= $name; ?>">
|
||||
<input id="<?= $name; ?>" type="checkbox" <?= apply_filters($name . '_setting_disabled', $disabled) ? 'disabled' : ''; ?> class="<?= str_replace('_', '-', $name); ?>" name="<?= $name; ?>" <?= $checked == "on" ? 'checked = "checked"' : ''; ?> />
|
||||
<?= apply_filters($name . '_setting_description', $description); ?>
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
<?php
|
||||
/* * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* ██████╗ ███╗ ███╗ ██████╗ ███████╗
|
||||
* ██╔═══██╗████╗ ████║██╔════╝ ██╔════╝
|
||||
* ██║ ██║██╔████╔██║██║ ███╗█████╗
|
||||
* ██║ ██║██║╚██╔╝██║██║ ██║██╔══╝
|
||||
* ╚██████╔╝██║ ╚═╝ ██║╚██████╔╝██║
|
||||
* ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝
|
||||
*
|
||||
* @package : OMGF
|
||||
* @author : Daan van den Bergh
|
||||
* @copyright: (c) 2021 Daan van den Bergh
|
||||
* @url : https://daan.dev
|
||||
* * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
class OMGF_Admin_Settings_Detection extends OMGF_Admin_Settings_Builder
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->title = __('Google Fonts Detection Settings', $this->plugin_text_domain);
|
||||
|
||||
// Open
|
||||
add_filter('omgf_detection_settings_content', [$this, 'do_title'], 10);
|
||||
add_filter('omgf_detection_settings_content', [$this, 'do_description'], 15);
|
||||
add_filter('omgf_detection_settings_content', [$this, 'do_before'], 20);
|
||||
|
||||
// Settings
|
||||
add_filter('omgf_detection_settings_content', [$this, 'do_process_google_fonts'], 30);
|
||||
add_filter('omgf_detection_settings_content', [$this, 'do_promo_advanced_processing'], 40);
|
||||
add_filter('omgf_detection_settings_content', [$this, 'do_promo_safe_mode'], 50);
|
||||
add_filter('omgf_detection_settings_content', [$this, 'do_promo_fonts_processing'], 60);
|
||||
add_filter('omgf_detection_settings_content', [$this, 'do_promo_process_resource_hints'], 70);
|
||||
|
||||
// Close
|
||||
add_filter('omgf_detection_settings_content', [$this, 'do_after'], 100);
|
||||
}
|
||||
|
||||
/**
|
||||
* Description
|
||||
*/
|
||||
public function do_description()
|
||||
{
|
||||
?>
|
||||
<p>
|
||||
<?= __('These settings affect OMGF\'s automatic detection mechanism and how it treats the Google Fonts your theme and plugins use. If you want to use OMGF to remove the Google Fonts your WordPress configuration currently uses, set <strong>Google Fonts Processing</strong> to Remove.', $this->plugin_text_domain); ?>
|
||||
</p>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function do_promo_fonts_processing()
|
||||
{
|
||||
?>
|
||||
<tr>
|
||||
<th scope="row"><?= __('Google Fonts Processing (Pro)', $this->plugin_text_domain); ?></th>
|
||||
<td>
|
||||
<fieldset id="" class="scheme-list">
|
||||
<?php foreach ($this->fonts_processing_pro_options() as $name => $data) : ?>
|
||||
<?php
|
||||
$checked = defined(strtoupper($name)) ? constant(strtoupper($name)) : false;
|
||||
$disabled = apply_filters($name . '_setting_disabled', true) ? 'disabled' : '';
|
||||
?>
|
||||
<label for="<?= $name; ?>">
|
||||
<input type="checkbox" name="<?= $name; ?>" id="<?= $name; ?>" <?= $checked ? 'checked="checked"' : ''; ?> <?= $disabled; ?> /><?= $data['label']; ?>
|
||||
|
||||
</label>
|
||||
<?php endforeach; ?>
|
||||
</fieldset>
|
||||
<p class="description">
|
||||
<?= $this->promo; ?>
|
||||
</p>
|
||||
<ul>
|
||||
<?php foreach ($this->fonts_processing_pro_options() as $name => $data) : ?>
|
||||
<li><strong><?= $data['label']; ?></strong>: <?= $data['description']; ?></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function fonts_processing_pro_options()
|
||||
{
|
||||
return [
|
||||
'omgf_pro_process_stylesheets' => [
|
||||
'label' => __('Process External Stylesheets', $this->plugin_text_domain),
|
||||
'description' => __('Process stylesheets loaded from <code>fonts.googleapis.com</code> or <code>fonts.gstatic.com</code>.', $this->plugin_text_domain)
|
||||
],
|
||||
'omgf_pro_process_stylesheet_imports' => [
|
||||
'label' => __('Process Stylesheet Imports', $this->plugin_text_domain),
|
||||
'description' => __('Scan stylesheets loaded by your theme and plugins for <code>@import</code> statements loading Google Fonts and process them.', $this->plugin_text_domain)
|
||||
],
|
||||
'omgf_pro_process_stylesheet_font_faces' => [
|
||||
'label' => __('Process Stylesheet Font Faces', $this->plugin_text_domain),
|
||||
'description' => __('Scan stylesheets loaded by your theme and plugins for <code>@font-face</code> statements loading Google Fonts and process them.', $this->plugin_text_domain)
|
||||
],
|
||||
'omgf_pro_process_inline_styles' => [
|
||||
'label' => __('Process Inline Styles', $this->plugin_text_domain),
|
||||
'description' => __('Process all inline <code>@font-face</code> and <code>@import</code> rules loading Google Fonts.', $this->plugin_text_domain)
|
||||
],
|
||||
'omgf_pro_process_webfont_loader' => [
|
||||
'label' => __('Process Webfont Loader', $this->plugin_text_domain),
|
||||
'description' => __('Process <code>webfont.js</code> libraries and the corresponding configuration defining which Google Fonts to load.', $this->plugin_text_domain)
|
||||
],
|
||||
'omgf_pro_process_early_access' => [
|
||||
'label' => __('Process Early Access', $this->plugin_text_domain),
|
||||
'description' => __('Process stylesheets loaded from <code>fonts.googleapis.com/earlyaccess</code> or <code>fonts.gstatic.com/ea</code>.', $this->plugin_text_domain)
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function do_promo_advanced_processing()
|
||||
{
|
||||
$this->do_checkbox(
|
||||
__('Advanced Processing (Pro)', $this->plugin_text_domain),
|
||||
'omgf_pro_advanced_processing',
|
||||
defined('OMGF_PRO_ADVANCED_PROCESSING') ? OMGF_PRO_ADVANCED_PROCESSING : false,
|
||||
__('By default, OMGF scans for Google Fonts which are registered/enqueued using the <code>wp_enqueue_scripts()</code> action in WordPress\' header (<code>wp_head()</code>). Enabling this option will process all Google Fonts throughout the entire document. This setting can be fine-tuned using the settings below.', $this->plugin_text_domain) . ' ' . $this->promo,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add option for Safe Mode (Pro)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function do_promo_safe_mode()
|
||||
{
|
||||
$this->do_checkbox(
|
||||
__('Safe Mode (Pro)', $this->plugin_text_domain),
|
||||
'omgf_pro_safe_mode',
|
||||
defined('OMGF_PRO_SAFE_MODE') ? OMGF_PRO_SAFE_MODE : false,
|
||||
__('Enable Safe Mode if Advanced Processing (Pro) breaks styling of certain pages.', $this->plugin_text_domain) . ' ' . $this->promo,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add promo options for Process Resource Hints
|
||||
*/
|
||||
public function do_promo_process_resource_hints()
|
||||
{
|
||||
$this->do_checkbox(
|
||||
__('Remove Resource Hints (Pro)', $this->plugin_text_domain),
|
||||
'omgf_pro_process_resource_hints',
|
||||
defined('OMGF_PRO_PROCESS_RESOURCE_HINTS') ? OMGF_PRO_PROCESS_RESOURCE_HINTS : false,
|
||||
__('Remove all <code>link</code> elements with a <code>rel</code> attribute value of <code>dns-prefetch</code>, <code>preload</code> or <code>preconnect</code> pointing to <code>fonts.googleapis.com</code> or <code>fonts.gstatic.com</code>.', $this->plugin_text_domain) . ' ' . $this->promo,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function do_process_google_fonts()
|
||||
{
|
||||
$this->do_select(
|
||||
__('Google Fonts Processing', $this->plugin_text_domain),
|
||||
OMGF_Admin_Settings::OMGF_DETECTION_SETTING_FONT_PROCESSING,
|
||||
OMGF_Admin_Settings::OMGF_FONT_PROCESSING_OPTIONS,
|
||||
OMGF_FONT_PROCESSING,
|
||||
sprintf(__("Choose whether OMGF should (find, download and) <strong>replace</strong> all Google Fonts, or just <strong>remove</strong> them. Choosing Remove will force WordPress to fallback to system fonts.", $this->plugin_text_domain), OMGF_Admin_Settings::FFWP_WORDPRESS_PLUGINS_OMGF_PRO)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
/* * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* ██████╗ ███╗ ███╗ ██████╗ ███████╗
|
||||
* ██╔═══██╗████╗ ████║██╔════╝ ██╔════╝
|
||||
* ██║ ██║██╔████╔██║██║ ███╗█████╗
|
||||
* ██║ ██║██║╚██╔╝██║██║ ██║██╔══╝
|
||||
* ╚██████╔╝██║ ╚═╝ ██║╚██████╔╝██║
|
||||
* ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝
|
||||
*
|
||||
* @package : OMGF
|
||||
* @author : Daan van den Bergh
|
||||
* @copyright: (c) 2021 Daan van den Bergh
|
||||
* @url : https://daan.dev
|
||||
* * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
class OMGF_Admin_Settings_Help extends OMGF_Admin_Settings_Builder
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->title = __('Help & Documentation', $this->plugin_text_domain);
|
||||
|
||||
// Title
|
||||
add_filter('omgf_help_content', [$this, 'do_title'], 10);
|
||||
|
||||
// Content
|
||||
add_filter('omgf_help_content', [$this, 'do_content'], 20);
|
||||
}
|
||||
|
||||
public function do_content()
|
||||
{
|
||||
$utmTags = '?utm_source=omgf&utm_medium=plugin&utm_campaign=support_tab';
|
||||
$tweetUrl = sprintf("https://twitter.com/intent/tweet?text=I+am+using+%s+to+speed+up+Google+Fonts+for+@WordPress!+Try+it+for+yourself:&via=Dan0sz&hashtags=GoogleFonts,WordPress,Pagespeed,Insights&url=%s", str_replace(' ', '+', apply_filters('omgf_settings_page_title', 'OMGF')), apply_filters('omgf_help_tab_plugin_url', 'https://wordpress.org/plugins/host-webfonts-local/'));
|
||||
?>
|
||||
<div class="welcome-panel">
|
||||
<div class="welcome-panel-content">
|
||||
<h2><?= sprintf(__('Thank you for using %s!', $this->plugin_text_domain), apply_filters('omgf_settings_page_title', 'OMGF')); ?></h2>
|
||||
<p class="about-description">
|
||||
<?= sprintf(__('Need help configuring %s? Please refer to the links below to get you started.', $this->plugin_text_domain), apply_filters('omgf_settings_page_title', 'OMGF')); ?>
|
||||
</p>
|
||||
<div class="welcome-panel-column-container">
|
||||
<div class="welcome-panel-column">
|
||||
<h3>
|
||||
<?php _e('Need Help?', $this->plugin_text_domain); ?>
|
||||
</h3>
|
||||
<ul>
|
||||
<li><a class="welcome-icon dashicons-controls-forward" target="_blank" href="<?= apply_filters('omgf_settings_help_quick_start', 'https://docs.ffw.press/article/7-quick-start'); ?>"><?= __('Quick Start Guide', $this->plugin_text_domain); ?></a></li>
|
||||
<li><a class="welcome-icon dashicons-text-page" target="_blank" href="<?= apply_filters('omgf_settings_help_user_manual', 'https://docs.ffw.press/category/4-omgf-pro'); ?>"><?= __('User Manual', $this->plugin_text_domain); ?></a></li>
|
||||
<li><a class="welcome-icon dashicons-editor-help" target="_blank" href="<?= apply_filters('omgf_settings_help_faq_link', 'https://docs.ffw.press/article/9-frequently-asked-question-faq'); ?>"><?= __('FAQ', $this->plugin_text_domain); ?></a></li>
|
||||
<li><a class="welcome-icon dashicons-sos" target="_blank" href="<?= apply_filters('omgf_settings_help_troubleshooting_link', 'https://docs.ffw.press/category/37-omgf-pro---troubleshooting'); ?>"><?= __('Troubleshooting Guide', $this->plugin_text_domain); ?></a></li>
|
||||
<li><a class="welcome-icon dashicons-email" target="_blank" href="<?= apply_filters('omgf_settings_help_support_link', 'https://docs.ffw.press/contact'); ?>"><?= __('Get Support', $this->plugin_text_domain); ?></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="welcome-panel-column">
|
||||
<h3><?= sprintf(__('Support %s & Spread the Word!', $this->plugin_text_domain), apply_filters('omgf_settings_page_title', 'OMGF')); ?></h3>
|
||||
<ul>
|
||||
<li><a class="welcome-icon dashicons-star-filled" target="_blank" href="<?= apply_filters('omgf_help_tab_review_link', 'https://wordpress.org/support/plugin/host-webfonts-local/reviews/?rate=5#new-post'); ?>"><?= __('Write a 5-star Review or,', $this->plugin_text_domain); ?></a></li>
|
||||
<li><a class="welcome-icon dashicons-twitter" target="_blank" href="<?= $tweetUrl; ?>"><?= __('Tweet about it!', $this->plugin_text_domain); ?></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="welcome-panel-column welcome-panel-last">
|
||||
<h3 class="signature"><?= __('Check out my other plugins', $this->plugin_text_domain); ?> @</h3>
|
||||
<p class="signature">
|
||||
<a target="_blank" title="<?= __('Visit FFW Press', $this->plugin_text_domain); ?>" href="https://ffw.press/wordpress-plugins/"><img class="signature-image" alt="<?= __('Visit FFW Press', $this->plugin_text_domain); ?>" src="https://ffw.press/wp-content/uploads/2021/01/logo-color-full@05x.png" /></a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,387 @@
|
||||
<?php
|
||||
/* * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* ██████╗ ███╗ ███╗ ██████╗ ███████╗
|
||||
* ██╔═══██╗████╗ ████║██╔════╝ ██╔════╝
|
||||
* ██║ ██║██╔████╔██║██║ ███╗█████╗
|
||||
* ██║ ██║██║╚██╔╝██║██║ ██║██╔══╝
|
||||
* ╚██████╔╝██║ ╚═╝ ██║╚██████╔╝██║
|
||||
* ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝
|
||||
*
|
||||
* @package : OMGF
|
||||
* @author : Daan van den Bergh
|
||||
* @copyright: (c) 2021 Daan van den Bergh
|
||||
* @url : https://daan.dev
|
||||
* * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
class OMGF_Admin_Settings_Optimize extends OMGF_Admin_Settings_Builder
|
||||
{
|
||||
const FFW_PRESS_OMGF_AF_URL = 'https://ffw.press/wordpress/omgf-additional-fonts/';
|
||||
|
||||
/** @var array $optimized_fonts */
|
||||
private $optimized_fonts;
|
||||
|
||||
/**
|
||||
* OMGF_Admin_Settings_Optimize constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->title = __('Optimize Google Fonts', $this->plugin_text_domain);
|
||||
|
||||
add_filter('omgf_optimize_settings_content', [$this, 'do_title'], 10);
|
||||
add_filter('omgf_optimize_settings_content', [$this, 'do_description'], 15);
|
||||
|
||||
add_filter('omgf_optimize_settings_content', [$this, 'do_before'], 20);
|
||||
add_filter('omgf_optimize_settings_content', [$this, 'do_optimization_mode'], 30);
|
||||
add_filter('omgf_optimize_settings_content', [$this, 'do_promo_combine_requests'], 40);
|
||||
add_filter('omgf_optimize_settings_content', [$this, 'do_display_option'], 50);
|
||||
add_filter('omgf_optimize_settings_content', [$this, 'do_promo_force_font_display'], 60);
|
||||
add_filter('omgf_optimize_settings_content', [$this, 'do_promo_include_file_types'], 70);
|
||||
add_filter('omgf_optimize_settings_content', [$this, 'do_promo_force_subsets'], 80);
|
||||
add_filter('omgf_optimize_settings_content', [$this, 'do_after'], 100);
|
||||
|
||||
add_filter('omgf_optimize_settings_content', [$this, 'do_optimize_fonts_container'], 200);
|
||||
add_filter('omgf_optimize_settings_content', [$this, 'do_optimize_fonts_contents'], 250);
|
||||
add_filter('omgf_optimize_settings_content', [$this, 'close_optimize_fonts_container'], 300);
|
||||
|
||||
add_filter('omgf_optimize_settings_content', [$this, 'do_before'], 350);
|
||||
add_filter('omgf_optimize_settings_content', [$this, 'do_optimize_edit_roles'], 375);
|
||||
add_filter('omgf_optimize_settings_content', [$this, 'do_after'], 400);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function do_description()
|
||||
{
|
||||
?>
|
||||
<p>
|
||||
<?= __('These settings affect the fonts OMGF downloads and the stylesheet it generates. If you\'re simply looking to replace your Google Fonts for locally hosted copies, the default settings should suffice.', $this->plugin_text_domain); ?>
|
||||
</p>
|
||||
<p>
|
||||
<?= sprintf(__('To install additional Google Fonts, an add-on is required, which can be downloaded <a href="%s" target="blank">here</a>.', $this->plugin_text_domain), self::FFW_PRESS_OMGF_AF_URL); ?>
|
||||
</p>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function do_optimization_mode()
|
||||
{
|
||||
$this->do_radio(
|
||||
__('Optimization Mode', $this->plugin_text_domain),
|
||||
OMGF_Admin_Settings::OMGF_OPTIMIZATION_MODE,
|
||||
OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZATION_MODE,
|
||||
OMGF_OPTIMIZATION_MODE,
|
||||
__('<strong>Manual</strong> processing mode is best suited for configurations, which use a fixed number of fonts across the entire site. When in manual mode, the generated stylesheet is forced throughout the entire site. <strong>Automatic</strong> processing mode is best suited for configurations using e.g. page builders, which load different fonts on certain pages.', $this->plugin_text_domain)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function do_promo_combine_requests()
|
||||
{
|
||||
$this->do_checkbox(
|
||||
__('Combine & Dedupe (Pro)', $this->plugin_text_domain),
|
||||
'omgf_pro_combine_requests',
|
||||
defined('OMGF_PRO_COMBINE_REQUESTS') ? true : false,
|
||||
__('Combine and deduplicate multiple Google Fonts stylesheets into one stylesheet. This feature is always on in OMGF Pro.', $this->plugin_text_domain) . ' ' . $this->promo,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function do_display_option()
|
||||
{
|
||||
$this->do_select(
|
||||
__('Font-Display Option', $this->plugin_text_domain),
|
||||
OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_DISPLAY_OPTION,
|
||||
OMGF_Admin_Settings::OMGF_FONT_DISPLAY_OPTIONS,
|
||||
OMGF_DISPLAY_OPTION,
|
||||
__('Select which value to set the font-display attribute to. Defaults to Swap (recommended).', $this->plugin_text_domain)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Force Font-Display Option Site Wide
|
||||
*/
|
||||
public function do_promo_force_font_display()
|
||||
{
|
||||
$this->do_checkbox(
|
||||
__('Force Font-Display Option Site Wide (Pro)', $this->plugin_text_domain),
|
||||
'omgf_pro_force_font_display',
|
||||
defined('OMGF_PRO_FORCE_FONT_DISPLAY') ? OMGF_PRO_FORCE_FONT_DISPLAY : false,
|
||||
__('Force the above <code>font-display</code> attribute on all <code>@font-face</code> statements to ensure all text is user-visible while webfonts and icon sets are loading.', $this->plugin_text_domain),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display WOFF2 Only
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function do_promo_include_file_types()
|
||||
{
|
||||
$this->do_select(
|
||||
__('Include File Types (Pro)', $this->plugin_text_domain),
|
||||
'omgf_pro_file_types',
|
||||
OMGF_Admin_Settings::OMGF_FILE_TYPES_OPTIONS,
|
||||
defined('OMGF_PRO_FILE_TYPES') ? OMGF_PRO_FILE_TYPES : [],
|
||||
__('Select which file types should be included in the stylesheet. Loading <strong>WOFF2</strong> files only will result in a smaller stylesheet, but will make the stylesheet slightly less Cross Browser compatible. Using <strong>WOFF</strong> and <strong>WOFF2</strong> together (default) accounts for +98% of browsers. Add <strong>EOT</strong> for IE 6-10 and <strong>TTF</strong> and <strong>SVG</strong> for legacy Android/iOS browsers. <em>Use CTRL + click to select multiple values</em>.', $this->plugin_text_domain) . ' ' . $this->promo,
|
||||
true,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function do_promo_force_subsets()
|
||||
{
|
||||
$this->do_select(
|
||||
__('Force Subsets (Pro)', $this->plugin_text_domain),
|
||||
'omgf_pro_force_subsets',
|
||||
OMGF_Admin_Settings::OMGF_FORCE_SUBSETS_OPTIONS,
|
||||
defined('OMGF_PRO_FORCE_SUBSETS') ? OMGF_PRO_FORCE_SUBSETS : [],
|
||||
__('If a theme or plugin loads subsets you don\'t need, use this option to force all Google Fonts to be loaded in the selected subsets. You can also use this option to force the loading of additional subsets, if a theme/plugin doesn\'t allow you to configure the loaded subsets. <em>Use CTRL + click to select multiple values</em>.', $this->plugin_text_domain) . ' ' . $this->promo,
|
||||
true,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function do_optimize_fonts_container()
|
||||
{
|
||||
?>
|
||||
<div class="omgf-optimize-fonts-container welcome-panel">
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function do_optimize_fonts_contents()
|
||||
{
|
||||
$this->optimized_fonts = OMGF::optimized_fonts();
|
||||
?>
|
||||
<span class="option-title"><?= __('Manage Optimized Fonts', $this->plugin_text_domain); ?></span>
|
||||
<?php if ($this->optimized_fonts) : ?>
|
||||
<?= $this->do_optimized_fonts_manager(); ?>
|
||||
<?php else : ?>
|
||||
<div class="omgf-optimize-fonts-description">
|
||||
<?php
|
||||
$this->do_manual_template();
|
||||
$this->do_automatic_template();
|
||||
?>
|
||||
</div>
|
||||
<?php endif;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function do_optimized_fonts_manager()
|
||||
{
|
||||
?>
|
||||
<div class="omgf-optimize-fonts-manage">
|
||||
<p>
|
||||
|
||||
</p>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<th><?= __('Style', $this->plugin_text_domain); ?></th>
|
||||
<th><?= __('Weight', $this->plugin_text_domain); ?></th>
|
||||
<th><?= __('Preload', $this->plugin_text_domain); ?><span class="dashicons dashicons-info tooltip"><span class="tooltip-text"><span class="inline-text"><?= __('Preload font files (before everything else) so they will be available as soon as they are required for the rendering of the page. Only use preload for font files that are used above the fold.', $this->plugin_text_domain); ?></span><img width="230" class="illustration" src="<?= plugin_dir_url(OMGF_PLUGIN_FILE) . 'assets/images/above-the-fold.png'; ?>" /></span></span></th>
|
||||
<th><?= __('Do not load', $this->plugin_text_domain); ?></th>
|
||||
<th><?= __('Fallback Font Stack (Pro)', $this->plugin_text_domain); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<?php
|
||||
$cache_handles = OMGF::cache_keys();
|
||||
?>
|
||||
<?php foreach ($this->optimized_fonts as $handle => $fonts) : ?>
|
||||
<?php
|
||||
if (!OMGF::get_cache_key($handle)) {
|
||||
$cache_handles[] = $handle;
|
||||
}
|
||||
?>
|
||||
<tbody class="stylesheet" id="<?= $handle; ?>">
|
||||
<tr>
|
||||
<th colspan="6"><?= sprintf(__('Stylesheet handle: %s', $this->plugin_text_domain), $handle); ?></th>
|
||||
</tr>
|
||||
<?php foreach ($fonts as $font) : ?>
|
||||
<?php if (!is_object($font) || count((array) $font->variants) <= 0) continue; ?>
|
||||
<?php
|
||||
$aka = in_array($font->id, OMGF_API_Download::OMGF_RENAMED_GOOGLE_FONTS) ? array_search($font->id, OMGF_API_Download::OMGF_RENAMED_GOOGLE_FONTS) : '';
|
||||
?>
|
||||
<tr class="font-family" data-id="<?= $handle . '-' . $font->id; ?>">
|
||||
<td colspan="5">
|
||||
<span class="family"><em><?= rawurldecode($font->family); ?><?= $aka ? ' (' . sprintf(__('formerly known as <strong>%s</strong>', $this->plugin_text_domain) . ')', ucfirst($aka)) : ''; ?></em></span> <span class="unload-mass-action">(<a href="#" class="unload-italics"><?= __('Unload italics', $this->plugin_text_domain); ?></a> <span class="dashicons dashicons-info tooltip"><span class="tooltip-text"><?= __('In most situations you can safely unload all Italic font styles. Modern browsers are capable of mimicking Italic font styles.', $this->plugin_text_domain); ?></span></span> | <a href="#" class="unload-all"><?= __('Unload all', $this->plugin_text_domain); ?></a> | <a href="#" class="load-all"><?= __('Load all', $this->plugin_text_domain); ?></a>)</span>
|
||||
</td>
|
||||
<td class="fallback-font-stack">
|
||||
<select data-handle="<?= $handle; ?>" <?= apply_filters('omgf_pro_fallback_font_stack_setting_disabled', true) ? 'disabled' : ''; ?> name="omgf_pro_fallback_font_stack[<?= $handle; ?>][<?= $font->id; ?>]">
|
||||
<option value=''><?= __('None (default)', $this->plugin_text_domain); ?></option>
|
||||
<?php foreach (OMGF_Admin_Settings::OMGF_FALLBACK_FONT_STACKS_OPTIONS as $value => $label) : ?>
|
||||
<option <?= defined('OMGF_PRO_FALLBACK_FONT_STACK') && isset(OMGF_PRO_FALLBACK_FONT_STACK[$handle][$font->id]) && OMGF_PRO_FALLBACK_FONT_STACK[$handle][$font->id] == $value ? 'selected' : ''; ?> value="<?= $value; ?>"><?= $label; ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<?php foreach ($font->variants as $variant) : ?>
|
||||
<tr>
|
||||
<td></td>
|
||||
<?php
|
||||
$preload = OMGF::preloaded_fonts()[$handle][$font->id][$variant->id] ?? '';
|
||||
$unload = OMGF::unloaded_fonts()[$handle][$font->id][$variant->id] ?? '';
|
||||
$class = $handle . '-' . $font->id . '-' . $variant->id;
|
||||
?>
|
||||
<td><?= $variant->fontStyle; ?></td>
|
||||
<td><?= $variant->fontWeight; ?></td>
|
||||
<td class="preload-<?= $class; ?>">
|
||||
<input data-handle="<?= $handle; ?>" data-font-id="<?= $handle . '-' . $font->id; ?>" autocomplete="off" type="checkbox" class="preload" name="<?= OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_PRELOAD_FONTS; ?>[<?= $handle; ?>][<?= $font->id; ?>][<?= $variant->id; ?>]" value="<?= $variant->id; ?>" <?= $preload ? 'checked="checked"' : ''; ?> <?= $unload ? 'disabled' : ''; ?> />
|
||||
</td>
|
||||
<td class="unload-<?= $class; ?>">
|
||||
<input data-handle="<?= $handle; ?>" data-font-id="<?= $handle . '-' . $font->id; ?>" autocomplete="off" type="checkbox" class="unload" name="<?= OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_FONTS; ?>[<?= $handle; ?>][<?= $font->id; ?>][<?= $variant->id; ?>]" value="<?= $variant->id; ?>" <?= $unload ? 'checked="checked"' : ''; ?> <?= $preload ? 'disabled' : ''; ?> />
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
<?php endforeach; ?>
|
||||
</table>
|
||||
<div class="omgf-optimize-fonts-tooltip">
|
||||
<p>
|
||||
<span class="dashicons-before dashicons-info-outline"></span>
|
||||
<?php if (OMGF_OPTIMIZATION_MODE == 'manual') : ?>
|
||||
<em><?= sprintf(__("This list is populated with all Google Fonts captured and downloaded from <strong>%s</strong>. Optimizations will be applied on every page using these fonts. If you want to optimize additional Google Fonts from other pages, switch to <strong>Automatic (Pro)</strong> and visit the pages containing the stylesheets you'd like to optimize. This list will automatically be populated with the captured fonts.", $this->plugin_text_domain), OMGF_MANUAL_OPTIMIZE_URL); ?></em>
|
||||
<?php else : ?>
|
||||
<?php $no_cache_param = '?omgf_optimize=' . substr(md5(microtime()), rand(0, 26), 5); ?>
|
||||
<em><?= sprintf(__("This list is automatically populated with Google Fonts captured throughout your entire site. Optimizations will be applied on every page using these fonts. <strong>Automatic</strong> mode might not work when a Full Page Cache plugin is activated. If this list is not being populated with Google Fonts, you could try to visit your frontend and append the following parameter to the URL: <strong>%s</strong>", $this->plugin_text_domain), $no_cache_param); ?></em>
|
||||
<?php endif; ?>
|
||||
</p>
|
||||
</div>
|
||||
<input type="hidden" name="<?= OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZED_FONTS; ?>" value='<?= serialize($this->optimized_fonts); ?>' />
|
||||
<input type="hidden" name="<?= OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_MANUAL_OPTIMIZE_URL; ?>" value="<?= OMGF_MANUAL_OPTIMIZE_URL; ?>" />
|
||||
<input id="<?= OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_STYLESHEETS; ?>" type="hidden" name="<?= OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_STYLESHEETS; ?>" value="<?= OMGF_UNLOAD_STYLESHEETS; ?>" />
|
||||
<input id="<?= OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_CACHE_KEYS; ?>" type="hidden" name="<?= OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_CACHE_KEYS; ?>" value="<?= implode(',', $cache_handles); ?>" />
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function do_manual_template()
|
||||
{
|
||||
?>
|
||||
<div class="omgf-optimize-fonts-manual" <?= OMGF_OPTIMIZATION_MODE == 'manual' ? '' : 'style="display: none;"'; ?>>
|
||||
<p>
|
||||
<?= sprintf(__("You've chosen to <strong>optimize your Google Fonts manually</strong>. OMGF will <u>not</u> run automatically and will <strong>%s</strong> the requested Google Fonts throughout your website that were captured on the post/page you defined. A Cross-Browser compatible stylesheet will be generated for all requested Google Fonts.", $this->plugin_text_domain), OMGF_FONT_PROCESSING); ?>
|
||||
</p>
|
||||
<div class="omgf-optimize-fonts-pros">
|
||||
<h3>
|
||||
<span class="dashicons-before dashicons-yes"></span> <?= __('Pros:', $this->plugin_text_domain); ?>
|
||||
</h3>
|
||||
<ul>
|
||||
<li><?= __('A small initial performance boost, because no calls to OMGF\'s Download API are made in the frontend.', $this->plugin_text_domain); ?></li>
|
||||
<li><?= __('Force one stylesheet to be used throughout the site.', $this->plugin_text_domain); ?></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="omgf-optimize-fonts-cons">
|
||||
<h3>
|
||||
<span class="dashicons-before dashicons-no"></span> <?= __('Cons', $this->plugin_text_domain); ?>
|
||||
</h3>
|
||||
<ul>
|
||||
<li><?= __('A font that is only used on a few pages might be lost if one of those URLs isn\'t scanned for fonts.', $this->plugin_text_domain); ?></li>
|
||||
</ul>
|
||||
</div>
|
||||
<p>
|
||||
<?= __('Enter the URL of the post/page you\'d like to scan for Google Fonts. The detected and optimized stylesheets will be applied on all pages where they\'re used.', $this->plugin_text_domain); ?>
|
||||
</p>
|
||||
<label for="<?= OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_MANUAL_OPTIMIZE_URL; ?>">
|
||||
<?= __('URL to Scan', $this->plugin_text_domain); ?>
|
||||
<input id="<?= OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_MANUAL_OPTIMIZE_URL; ?>" type="text" name="<?= OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_MANUAL_OPTIMIZE_URL; ?>" value="<?= OMGF_MANUAL_OPTIMIZE_URL; ?>" />
|
||||
</label>
|
||||
<div class="omgf-optimize-fonts-tooltip">
|
||||
<p>
|
||||
<span class="dashicons-before dashicons-info-outline"></span>
|
||||
<em><?= __('This section will be populated with all captured fonts, font styles and available options after saving changes.', $this->plugin_text_domain); ?></em>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function do_automatic_template()
|
||||
{
|
||||
?>
|
||||
<div class="omgf-optimize-fonts-automatic" <?= OMGF_OPTIMIZATION_MODE == 'auto' ? '' : 'style="display: none;"'; ?>>
|
||||
<p>
|
||||
<?= sprintf(__("You've chosen to <strong>optimize your Google Fonts automatically</strong>. OMGF will run silently in the background and <strong>%s</strong> all requested Google Fonts. If the captured stylesheet doesn't exist yet, a call is sent to OMGF's Download API to download the font files and generate a Cross-Browser compatible stylesheet.", $this->plugin_text_domain), OMGF_FONT_PROCESSING); ?>
|
||||
</p>
|
||||
<div class="omgf-optimize-fonts-pros">
|
||||
<h3>
|
||||
<span class="dashicons-before dashicons-yes"></span> <?= __('Pros:', $this->plugin_text_domain); ?>
|
||||
</h3>
|
||||
<ul>
|
||||
<li><?= __('No maintenance.', $this->plugin_text_domain); ?></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="omgf-optimize-fonts-cons">
|
||||
<h3>
|
||||
<span class="dashicons-before dashicons-no"></span> <?= __('Cons', $this->plugin_text_domain); ?>
|
||||
</h3>
|
||||
<ul>
|
||||
<li><?= __("The first time an unoptimized Google Fonts stylesheet is found, the API will be triggered in the frontend, which might cause the page to load slower than usual. All subsequent pageviews for that page (and all pages using that same stylesheet will load just as fast as when Manual mode is used.", $this->plugin_text_domain); ?></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="omgf-optimize-fonts-tooltip">
|
||||
<p>
|
||||
<span class="dashicons-before dashicons-info-outline"></span>
|
||||
<em><?= __("After saving your changes, this section will be populated with all captured fonts, font styles and available options as your site's frontend is visited by you or others. You will be able to manage your fonts at a later point.", $this->plugin_text_domain); ?></em>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function close_optimize_fonts_container()
|
||||
{
|
||||
?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function do_optimize_edit_roles()
|
||||
{
|
||||
$this->do_checkbox(
|
||||
__('Optimize Fonts For Editors/Administrators?', $this->plugin_text_domain),
|
||||
OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZE_EDIT_ROLES,
|
||||
OMGF_OPTIMIZE_EDIT_ROLES,
|
||||
__('Should only be disabled while debugging/testing, e.g. using a page builder or switching themes.', $this->plugin_text_domain)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,489 @@
|
||||
<?php
|
||||
/* * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* ██████╗ ███╗ ███╗ ██████╗ ███████╗
|
||||
* ██╔═══██╗████╗ ████║██╔════╝ ██╔════╝
|
||||
* ██║ ██║██╔████╔██║██║ ███╗█████╗
|
||||
* ██║ ██║██║╚██╔╝██║██║ ██║██╔══╝
|
||||
* ╚██████╔╝██║ ╚═╝ ██║╚██████╔╝██║
|
||||
* ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝
|
||||
*
|
||||
* @package : OMGF
|
||||
* @author : Daan van den Bergh
|
||||
* @copyright: (c) 2021 Daan van den Bergh
|
||||
* @url : https://daan.dev
|
||||
* * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
class OMGF_API_Download extends WP_REST_Controller
|
||||
{
|
||||
const OMGF_GOOGLE_FONTS_API_URL = 'https://google-webfonts-helper.herokuapp.com/api/fonts/';
|
||||
const OMGF_GOOGLE_FONTS_API_FALLBACK = 'https://omgf-google-fonts-api.herokuapp.com/api/fonts/';
|
||||
const OMGF_USE_FALLBACK_API_TRANSIENT = 'omgf_use_fallback_api';
|
||||
|
||||
/**
|
||||
* If a font changed names recently, this array will map the old name (key) to the new name (value).
|
||||
*
|
||||
* The key of an element should be dashed (no spaces) if necessary, e.g. open-sans.
|
||||
*/
|
||||
const OMGF_RENAMED_GOOGLE_FONTS = [
|
||||
'ek-mukta' => 'mukta',
|
||||
'muli' => 'mulish'
|
||||
];
|
||||
|
||||
/** @var string */
|
||||
private $plugin_text_domain = 'host-webfonts-local';
|
||||
|
||||
/** @var array */
|
||||
private $endpoints = ['css', 'css2'];
|
||||
|
||||
/** @var string */
|
||||
protected $namespace = 'omgf/v1';
|
||||
|
||||
/** @var string */
|
||||
protected $rest_base = '/download/';
|
||||
|
||||
/** @var string */
|
||||
private $handle = '';
|
||||
|
||||
/** @var string */
|
||||
private $path = '';
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function register_routes()
|
||||
{
|
||||
foreach ($this->endpoints as $endpoint) {
|
||||
register_rest_route(
|
||||
$this->namespace,
|
||||
'/' . $this->rest_base . $endpoint,
|
||||
[
|
||||
[
|
||||
'methods' => 'GET',
|
||||
'callback' => [$this, 'process'],
|
||||
'permission_callback' => [$this, 'permissions_check']
|
||||
],
|
||||
'schema' => null,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent CSRF.
|
||||
*
|
||||
* @since v4.5.4
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function permissions_check()
|
||||
{
|
||||
if (!isset($_REQUEST['_wpnonce'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This API should only be accessible to users with manage_options capabilities.
|
||||
*
|
||||
* @since v4.5.13
|
||||
*/
|
||||
return current_user_can('manage_options') && wp_verify_nonce($_REQUEST['_wpnonce'], 'wp_rest') > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WP_REST_Request $request
|
||||
*/
|
||||
public function process($request)
|
||||
{
|
||||
$this->handle = sanitize_title_with_dashes($request->get_param('handle'));
|
||||
$original_handle = sanitize_title_with_dashes($request->get_param('original_handle'));
|
||||
|
||||
if (!$this->handle || !$original_handle) {
|
||||
wp_die(__('Handle not provided.', $this->plugin_text_domain), 406);
|
||||
}
|
||||
|
||||
$this->path = WP_CONTENT_DIR . OMGF_CACHE_PATH . '/' . $this->handle;
|
||||
$font_families = explode('|', $request->get_param('family'));
|
||||
$query['subsets'] = $request->get_param('subset') ?? 'latin,latin-ext';
|
||||
$fonts = [];
|
||||
|
||||
foreach ($font_families as $font_family) {
|
||||
if (empty($font_family)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$fonts[] = $this->grab_font_family($font_family, $query);
|
||||
}
|
||||
|
||||
// Filter out empty elements, i.e. failed requests.
|
||||
$fonts = array_filter($fonts);
|
||||
|
||||
if (empty($fonts)) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($fonts as $font_key => &$font) {
|
||||
$fonts_request = $this->build_fonts_request($font_families, $font);
|
||||
|
||||
if (strpos($fonts_request, ':') != false) {
|
||||
list($family, $requested_variants) = explode(':', $fonts_request);
|
||||
} else {
|
||||
$family = $fonts_request;
|
||||
$requested_variants = '';
|
||||
}
|
||||
|
||||
$requested_variants = $this->parse_requested_variants($requested_variants, $font);
|
||||
|
||||
if ($unloaded_fonts = OMGF::unloaded_fonts()) {
|
||||
$font_id = $font->id;
|
||||
|
||||
// Now we're sure we got 'em all. We can safely dequeue those we don't want.
|
||||
if (isset($unloaded_fonts[$original_handle][$font_id])) {
|
||||
$requested_variants = $this->dequeue_unloaded_variants($requested_variants, $unloaded_fonts[$original_handle], $font->id);
|
||||
$fonts_request = $family . ':' . implode(',', $requested_variants);
|
||||
}
|
||||
}
|
||||
|
||||
$font->variants = $this->process_unload_queue($font->id, $font->variants, $fonts_request, $original_handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Which file types should we download and include in the stylesheet?
|
||||
*
|
||||
* @since v4.5
|
||||
*/
|
||||
$file_types = apply_filters('omgf_include_file_types', ['woff2', 'woff', 'eot', 'ttf', 'svg']);
|
||||
|
||||
foreach ($fonts as &$font) {
|
||||
$font_id = $font->id;
|
||||
|
||||
/**
|
||||
* Sanitize font family, because it may contain spaces.
|
||||
*
|
||||
* @since v4.5.6
|
||||
*/
|
||||
$font->family = rawurlencode($font->family);
|
||||
|
||||
foreach ($font->variants as &$variant) {
|
||||
$filename = strtolower($font_id . '-' . $variant->fontStyle . '-' . $variant->fontWeight);
|
||||
|
||||
/**
|
||||
* Encode font family, because it may contain spaces.
|
||||
*
|
||||
* @since v4.5.6
|
||||
*/
|
||||
$variant->fontFamily = rawurlencode($variant->fontFamily);
|
||||
|
||||
foreach ($file_types as $file_type) {
|
||||
if (isset($variant->$file_type)) {
|
||||
$variant->$file_type = OMGF::download($variant->$file_type, $filename, $file_type, $this->path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$local_file = $this->path . '/' . $this->handle . '.css';
|
||||
|
||||
/**
|
||||
* If this $stylesheet doesn't exist yet, let's generate it.
|
||||
*
|
||||
* If any modifications are done, e.g. unloads, the cache key ($handle) changes. Therefore it makes no sense to
|
||||
* continue after this point if $local_file already exists.
|
||||
*
|
||||
* @since v4.5.9
|
||||
*/
|
||||
if (file_exists($local_file)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$stylesheet = OMGF::generate_stylesheet($fonts, $original_handle);
|
||||
|
||||
file_put_contents($local_file, $stylesheet);
|
||||
|
||||
$current_stylesheet = [$original_handle => $fonts];
|
||||
|
||||
/**
|
||||
* $current_stylesheet is added to temporary cache layer, if it isn't present in database.
|
||||
*
|
||||
* @since v4.5.7
|
||||
*/
|
||||
$optimized_fonts = OMGF::optimized_fonts($current_stylesheet);
|
||||
|
||||
/**
|
||||
* When unload is used, this takes care of rewriting the font style URLs in the database.
|
||||
*
|
||||
* @since v4.5.7
|
||||
*/
|
||||
$optimized_fonts = $this->rewrite_variants($optimized_fonts, $current_stylesheet);
|
||||
|
||||
update_option(OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZED_FONTS, $optimized_fonts);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $variants
|
||||
* @param $unloaded_fonts
|
||||
* @param $font_id
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function dequeue_unloaded_variants($variants, $unloaded_fonts, $font_id)
|
||||
{
|
||||
return array_filter(
|
||||
$variants,
|
||||
function ($value) use ($unloaded_fonts, $font_id) {
|
||||
if ($value == '400') {
|
||||
// Sometimes the font is defined as 'regular', so we need to check both.
|
||||
return !in_array('regular', $unloaded_fonts[$font_id]) && !in_array($value, $unloaded_fonts[$font_id]);
|
||||
}
|
||||
|
||||
if ($value == '400italic') {
|
||||
// Sometimes the font is defined as 'italic', so we need to check both.
|
||||
return !in_array('italic', $unloaded_fonts[$font_id]) && !in_array($value, $unloaded_fonts[$font_id]);
|
||||
}
|
||||
|
||||
return !in_array($value, $unloaded_fonts[$font_id]);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $font_family
|
||||
* @param $url
|
||||
* @param $query
|
||||
*
|
||||
* @return mixed|void
|
||||
*/
|
||||
private function grab_font_family($font_family, $query)
|
||||
{
|
||||
$url = $this->get_working_service_url();
|
||||
list($family) = explode(':', $font_family);
|
||||
|
||||
/**
|
||||
* Replace multiple spaces or plus signs (or a combination of, with a single dash)
|
||||
*
|
||||
* @since v4.5.10
|
||||
*/
|
||||
$family = strtolower(preg_replace("/[\s\+]+/", '-', $family));
|
||||
|
||||
/**
|
||||
* Add fonts to the request's $_GET 'family' parameter. Then pass an array to 'omgf_alternate_fonts'
|
||||
* filter. Then pass an alternate API url to the 'omgf_alternate_api_url' filter to fetch fonts from
|
||||
* an alternate API.
|
||||
*/
|
||||
$alternate_fonts = apply_filters('omgf_alternate_fonts', []);
|
||||
|
||||
if (in_array($family, array_keys($alternate_fonts))) {
|
||||
$url = apply_filters('omgf_alternate_api_url', $url, $family);
|
||||
unset($query);
|
||||
}
|
||||
|
||||
$query_string = '';
|
||||
|
||||
if (isset($query)) {
|
||||
$query_string = '?' . http_build_query($query);
|
||||
}
|
||||
|
||||
/**
|
||||
* If a font changed names recently, map their old name to the new name, before triggering the API request.
|
||||
*/
|
||||
if (in_array($family, array_keys(self::OMGF_RENAMED_GOOGLE_FONTS))) {
|
||||
$family = self::OMGF_RENAMED_GOOGLE_FONTS[$family];
|
||||
}
|
||||
|
||||
$response = wp_remote_get(
|
||||
sprintf($url . '%s', $family) . $query_string
|
||||
);
|
||||
|
||||
if (is_wp_error($response)) {
|
||||
OMGF_Admin_Notice::set_notice(sprintf(__('OMGF encountered an error while trying to fetch fonts: %s', $this->plugin_text_domain), $response->get_error_message()), $response->get_error_code(), true, 'error', 500);
|
||||
}
|
||||
|
||||
$response_code = wp_remote_retrieve_response_code($response);
|
||||
|
||||
if ($response_code != 200) {
|
||||
$font_family = str_replace('-', ' ', $family);
|
||||
$error_body = wp_remote_retrieve_body($response);
|
||||
$error_message = wp_remote_retrieve_response_message($response);
|
||||
$message = sprintf(__('OMGF couldn\'t find <strong>%s</strong>. The API returned the following error: %s.', $this->plugin_text_domain), ucwords($font_family), $error_message);
|
||||
|
||||
OMGF_Admin_Notice::set_notice($message, 'omgf_api_error', false, 'error');
|
||||
|
||||
if ($error_message == 'Service Unavailable') {
|
||||
$message = __('OMGF\'s Google Fonts API is currently unavailable. Try again later.', $this->plugin_text_domain);
|
||||
|
||||
OMGF_Admin_Notice::set_notice($message, 'omgf_api_error', true, 'error', $response_code);
|
||||
}
|
||||
|
||||
if ($error_body == 'Not found') {
|
||||
$message = sprintf(__('Please verify that %s is available for free at Google Fonts by doing <a href="%s" target="_blank">a manual search</a>. Maybe it\'s a Premium font?', $this->plugin_text_domain), ucwords($font_family), 'https://fonts.google.com/?query=' . str_replace('-', '+', $family));
|
||||
|
||||
OMGF_Admin_Notice::set_notice($message, 'omgf_api_info_not_found', false, 'info');
|
||||
}
|
||||
|
||||
if ($error_body == 'Internal Server Error') {
|
||||
$message = sprintf(__('Try using the Force Subsets option (available in OMGF Pro) to force loading %s in a subset in which it\'s actually available. Use the Language filter <a href="%s" target="_blank">here</a> to verify which subsets are available for %s.', $this->plugin_text_domain), ucwords($font_family), 'https://fonts.google.com/?query=' . str_replace('-', '+', $family), ucwords($font_family));
|
||||
|
||||
OMGF_Admin_Notice::set_notice($message, 'omgf_api_info_internal_server_error', false, 'info');
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
return json_decode(wp_remote_retrieve_body($response));
|
||||
}
|
||||
|
||||
/**
|
||||
* Because the regular Google Webfonts Helper API tends to go offline sometimes, this function allows us
|
||||
* to use fallback services.
|
||||
*
|
||||
* @return string Will return regular API url if fallback API url fails, too. Error handling later on will display a
|
||||
* proper message to the user.
|
||||
*/
|
||||
private function get_working_service_url()
|
||||
{
|
||||
/**
|
||||
* If this transient returns true, then that means that the regular API has failed in the last 24 hours.
|
||||
*/
|
||||
if (get_transient(self::OMGF_USE_FALLBACK_API_TRANSIENT)) {
|
||||
return self::OMGF_GOOGLE_FONTS_API_FALLBACK;
|
||||
}
|
||||
|
||||
$url = self::OMGF_GOOGLE_FONTS_API_URL;
|
||||
$response = wp_remote_get($url);
|
||||
|
||||
if (is_wp_error($response) || wp_remote_retrieve_response_code($response) != 200) {
|
||||
set_transient(self::OMGF_USE_FALLBACK_API_TRANSIENT, true, DAY_IN_SECONDS);
|
||||
|
||||
$response = wp_remote_get(self::OMGF_GOOGLE_FONTS_API_FALLBACK);
|
||||
|
||||
if (!is_wp_error($response) && wp_remote_retrieve_response_code($response) == 200) {
|
||||
$url = self::OMGF_GOOGLE_FONTS_API_FALLBACK;
|
||||
}
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $font_families
|
||||
* @param $font
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function build_fonts_request($font_families, $font)
|
||||
{
|
||||
$font_request = array_filter(
|
||||
$font_families,
|
||||
function ($value) use ($font) {
|
||||
if (isset($font->early_access)) {
|
||||
return strpos($value, strtolower(str_replace(' ', '', $font->family))) !== false;
|
||||
}
|
||||
|
||||
return strpos($value, $font->family) !== false;
|
||||
}
|
||||
);
|
||||
|
||||
return reset($font_request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $request
|
||||
* @param $font
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function parse_requested_variants($request, $font)
|
||||
{
|
||||
$requested_variants = array_filter(explode(',', $request));
|
||||
|
||||
/**
|
||||
* This means by default all fonts are requested, so we need to fill up the queue, before unloading the unwanted variants.
|
||||
*/
|
||||
if (count($requested_variants) == 0) {
|
||||
foreach ($font->variants as $variant) {
|
||||
$requested_variants[] = $variant->id;
|
||||
}
|
||||
}
|
||||
|
||||
return $requested_variants;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param mixed $font_id
|
||||
* @param mixed $available
|
||||
* @param mixed $wanted
|
||||
* @param mixed $stylesheet_handle
|
||||
* @return mixed
|
||||
*/
|
||||
private function process_unload_queue($font_id, $available, $wanted, $stylesheet_handle)
|
||||
{
|
||||
if (strpos($wanted, ':') !== false) {
|
||||
// We don't need the first variable.
|
||||
list(, $variants) = explode(':', $wanted);
|
||||
} else {
|
||||
$variants = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Build array and filter out empty elements.
|
||||
*/
|
||||
$variants = array_filter(explode(',', $variants));
|
||||
|
||||
/**
|
||||
* If $variants is empty and this is the first run, i.e. there are no unloaded fonts (yet)
|
||||
* return all available variants.
|
||||
*/
|
||||
if (empty($variants) && !isset(OMGF::unloaded_fonts()[$stylesheet_handle][$font_id])) {
|
||||
return $available;
|
||||
}
|
||||
|
||||
return array_filter(
|
||||
$available,
|
||||
function ($font) use ($variants) {
|
||||
$id = $font->id;
|
||||
|
||||
if ($id == 'regular' || $id == '400') {
|
||||
return in_array('400', $variants) || in_array('regular', $variants);
|
||||
}
|
||||
|
||||
if ($id == 'italic') {
|
||||
return in_array('400italic', $variants) || in_array('italic', $variants);
|
||||
}
|
||||
|
||||
return in_array($id, $variants);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* When unload is used, insert the cache key in the font URLs for the variants still in use.
|
||||
*
|
||||
* @param array $all_stylesheets Contains all font styles, loaded and unloaded.
|
||||
* @param array $current_stylesheet Contains just the loaded font styles of current stylesheet.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function rewrite_variants($all_stylesheets, $current_stylesheet)
|
||||
{
|
||||
foreach ($all_stylesheets as $stylesheet => &$fonts) {
|
||||
foreach ($fonts as $index => &$font) {
|
||||
if (empty((array) $font->variants)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($font->variants as $variant_index => &$variant) {
|
||||
$replace_variant = $current_stylesheet[$stylesheet][$index]->variants[$variant_index] ?? (object) [];
|
||||
|
||||
if (!empty((array) $replace_variant)) {
|
||||
$variant = $replace_variant;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $all_stylesheets;
|
||||
}
|
||||
}
|
||||
257
wp-content/plugins/host-webfonts-local/includes/class-admin.php
Normal file
257
wp-content/plugins/host-webfonts-local/includes/class-admin.php
Normal file
@@ -0,0 +1,257 @@
|
||||
<?php
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* ██████╗ ███╗ ███╗ ██████╗ ███████╗
|
||||
* ██╔═══██╗████╗ ████║██╔════╝ ██╔════╝
|
||||
* ██║ ██║██╔████╔██║██║ ███╗█████╗
|
||||
* ██║ ██║██║╚██╔╝██║██║ ██║██╔══╝
|
||||
* ╚██████╔╝██║ ╚═╝ ██║╚██████╔╝██║
|
||||
* ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝
|
||||
*
|
||||
* @package : OMGF
|
||||
* @author : Daan van den Bergh
|
||||
* @copyright: (c) 2021 Daan van den Bergh
|
||||
* @url : https://daan.dev
|
||||
* * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
class OMGF_Admin
|
||||
{
|
||||
const OMGF_ADMIN_JS_HANDLE = 'omgf-admin-js';
|
||||
const OMGF_ADMIN_CSS_HANDLE = 'omgf-admin-css';
|
||||
|
||||
/** @var array $show_notice */
|
||||
private $show_notice = [];
|
||||
|
||||
/** @var string $plugin_text_domain */
|
||||
private $plugin_text_domain = 'host-webfonts-local';
|
||||
|
||||
/**
|
||||
* OMGF_Admin constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
/**
|
||||
* Filterable list of options that require the cache to be emptied.
|
||||
*/
|
||||
$this->show_notice = apply_filters(
|
||||
'omgf_admin_options_show_notice',
|
||||
[
|
||||
OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZATION_MODE,
|
||||
OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_DISPLAY_OPTION,
|
||||
OMGF_Admin_Settings::OMGF_ADV_SETTING_CACHE_PATH,
|
||||
]
|
||||
);
|
||||
|
||||
add_action('admin_enqueue_scripts', [$this, 'enqueue_admin_scripts']);
|
||||
add_action('admin_notices', [$this, 'print_notices']);
|
||||
|
||||
$this->do_optimize_settings();
|
||||
$this->do_detection_settings();
|
||||
$this->do_advanced_settings();
|
||||
$this->do_help();
|
||||
$this->maybe_do_after_update_notice();
|
||||
|
||||
// This used to fix a bug, but now it breaks stuff. Leave it here for the time being.
|
||||
// add_filter('pre_update_option_omgf_optimized_fonts', [$this, 'update_optimized_fonts'], 10, 2);
|
||||
add_filter('pre_update_option_omgf_cache_keys', [$this, 'clean_up_cache'], 10, 3);
|
||||
add_action('pre_update_option_omgf_cache_dir', [$this, 'validate_cache_dir'], 10, 2);
|
||||
add_filter('pre_update_option', [$this, 'settings_changed'], 10, 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueues the necessary JS and CSS and passes options as a JS object.
|
||||
*
|
||||
* @param $hook
|
||||
*/
|
||||
public function enqueue_admin_scripts($hook)
|
||||
{
|
||||
if ($hook == 'settings_page_optimize-webfonts') {
|
||||
wp_enqueue_script(self::OMGF_ADMIN_JS_HANDLE, plugin_dir_url(OMGF_PLUGIN_FILE) . 'assets/js/omgf-admin.js', ['jquery'], OMGF_STATIC_VERSION, true);
|
||||
wp_enqueue_style(self::OMGF_ADMIN_CSS_HANDLE, plugin_dir_url(OMGF_PLUGIN_FILE) . 'assets/css/omgf-admin.css', [], OMGF_STATIC_VERSION);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add notice to admin screen.
|
||||
*/
|
||||
public function print_notices()
|
||||
{
|
||||
OMGF_Admin_Notice::print_notices();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return OMGF_Admin_Settings_Optimize
|
||||
*/
|
||||
private function do_optimize_settings()
|
||||
{
|
||||
return new OMGF_Admin_Settings_Optimize();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return OMGF_Admin_Settings_Detection
|
||||
*/
|
||||
private function do_detection_settings()
|
||||
{
|
||||
return new OMGF_Admin_Settings_Detection();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return OMGF_Admin_Settings_Advanced
|
||||
*/
|
||||
private function do_advanced_settings()
|
||||
{
|
||||
return new OMGF_Admin_Settings_Advanced();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add filters for Help section.
|
||||
*
|
||||
* @return OMGF_Admin_Settings_Help
|
||||
*/
|
||||
private function do_help()
|
||||
{
|
||||
return new OMGF_Admin_Settings_Help();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an update notice should be displayed after updating.
|
||||
*/
|
||||
private function maybe_do_after_update_notice()
|
||||
{
|
||||
if (version_compare(OMGF_CURRENT_DB_VERSION, OMGF_DB_VERSION, '<')) {
|
||||
OMGF_Admin_Notice::set_notice(
|
||||
sprintf(
|
||||
__('Thank you for updating OMGF to v%s! This version contains database changes. <a href="%s">Verify your settings</a> and make sure everything is as you left it or, <a href="%s">view the changelog</a> for details. ', $this->plugin_text_domain),
|
||||
OMGF_DB_VERSION,
|
||||
admin_url(OMGF_Admin_Settings::OMGF_OPTIONS_GENERAL_PAGE_OPTIMIZE_WEBFONTS),
|
||||
admin_url(OMGF_Admin_Settings::OMGF_PLUGINS_INSTALL_CHANGELOG_SECTION)
|
||||
),
|
||||
'omgf-post-update',
|
||||
false
|
||||
);
|
||||
|
||||
update_option(OMGF_Admin_Settings::OMGF_CURRENT_DB_VERSION, OMGF_DB_VERSION);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This fixes a bug where the admin screen wouldn't properly be updated after omgf_optimized_fonts
|
||||
* was updated by the API.
|
||||
*
|
||||
* @param $old_value
|
||||
* @param $value
|
||||
*
|
||||
* @return bool|array
|
||||
*/
|
||||
public function update_optimized_fonts($value, $old_value)
|
||||
{
|
||||
return $old_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggered when unload settings is changed, cleans up old cache files.
|
||||
*
|
||||
* TODO: Clean up doesn't work on 2nd run?
|
||||
*
|
||||
* @param $old_value
|
||||
* @param $value
|
||||
* @param $option_name
|
||||
*/
|
||||
public function clean_up_cache($value, $old_value)
|
||||
{
|
||||
if ($old_value == $value) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
if ($old_value == null) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
$cache_keys = explode(',', $old_value);
|
||||
|
||||
foreach ($cache_keys as $key) {
|
||||
$entries = array_filter((array) glob(OMGF_FONTS_DIR . "/*$key"));
|
||||
|
||||
foreach ($entries as $entry) {
|
||||
OMGF::delete($entry);
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a few checks before saving the Cache Directory value to the database.
|
||||
*
|
||||
* @param mixed $new_dir
|
||||
* @param mixed $old_dir
|
||||
* @return mixed
|
||||
*/
|
||||
public function validate_cache_dir($new_dir, $old_dir)
|
||||
{
|
||||
$allowed_path = WP_CONTENT_DIR . $new_dir;
|
||||
$mkdir = true;
|
||||
|
||||
if (!file_exists($allowed_path)) {
|
||||
/**
|
||||
* wp_mkdir_p() already does some simple checks for path traversal, but we check it again using realpath() later on anyway.
|
||||
*/
|
||||
$mkdir = wp_mkdir_p($allowed_path);
|
||||
}
|
||||
|
||||
if (!$mkdir) {
|
||||
OMGF_Admin_Notice::set_notice(sprintf(__('Something went wrong while trying to create OMGF\'s Cache Directory: %s. Setting wasn\'t updated.', $this->plugin_text_domain), $new_dir), 'omgf-create-cache-dir-failed', false, 'error');
|
||||
|
||||
return $old_dir;
|
||||
}
|
||||
|
||||
$real_path = realpath($allowed_path);
|
||||
|
||||
if ($real_path != rtrim($allowed_path, '/')) {
|
||||
OMGF_Admin_Notice::set_notice(__('OMGF\'s Cache Directory wasn\'t changed. Attempted path traversal.', $this->plugin_text_domain), 'omgf-attempted-path-traversal', false, 'error');
|
||||
|
||||
return $old_dir;
|
||||
}
|
||||
|
||||
return $new_dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows notice if $option_name is in $show_notice array.
|
||||
*
|
||||
* @param $new_value
|
||||
* @param $old_settings
|
||||
*
|
||||
* @see $show_notice
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function settings_changed($value, $option_name, $old_value)
|
||||
{
|
||||
if (!in_array($option_name, $this->show_notice)) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
if ($value != $old_value) {
|
||||
global $wp_settings_errors;
|
||||
|
||||
if (!empty($wp_settings_errors)) {
|
||||
$wp_settings_errors = [];
|
||||
}
|
||||
|
||||
add_settings_error(
|
||||
'general',
|
||||
'omgf_settings_changed',
|
||||
sprintf(
|
||||
__('Settings changed. <a href="#" data-cache-section="/*" data-nonce="%s" class="omgf-empty">Click here</a> to empty OMGF\'s cache.', $this->plugin_text_domain),
|
||||
wp_create_nonce(OMGF_Admin_Settings::OMGF_ADMIN_PAGE)
|
||||
),
|
||||
'success'
|
||||
);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
/* * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* ██████╗ ███╗ ███╗ ██████╗ ███████╗
|
||||
* ██╔═══██╗████╗ ████║██╔════╝ ██╔════╝
|
||||
* ██║ ██║██╔████╔██║██║ ███╗█████╗
|
||||
* ██║ ██║██║╚██╔╝██║██║ ██║██╔══╝
|
||||
* ╚██████╔╝██║ ╚═╝ ██║╚██████╔╝██║
|
||||
* ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝
|
||||
*
|
||||
* @package : OMGF
|
||||
* @author : Daan van den Bergh
|
||||
* @copyright: (c) 2021 Daan van den Bergh
|
||||
* @url : https://daan.dev
|
||||
* * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
class OMGF_AJAX
|
||||
{
|
||||
/** @var string $plugin_text_domain */
|
||||
private $plugin_text_domain = 'host-webfonts-local';
|
||||
|
||||
/**
|
||||
* OMGF_AJAX constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
add_action('wp_ajax_omgf_ajax_empty_dir', [$this, 'empty_directory']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty cache directory.
|
||||
*
|
||||
* @since v4.5.3: Hardened security.
|
||||
* @since v4.5.5: Added authentication.
|
||||
*/
|
||||
public function empty_directory()
|
||||
{
|
||||
check_ajax_referer(OMGF_Admin_Settings::OMGF_ADMIN_PAGE, 'nonce');
|
||||
|
||||
if (!current_user_can('manage_options')) {
|
||||
wp_die(__("You're not cool enough to access this page.", $this->plugin_text_domain));
|
||||
}
|
||||
|
||||
$section = str_replace('*', '', $_POST['section']);
|
||||
$set_path = rtrim(OMGF_FONTS_DIR . $section, '/');
|
||||
$resolved_path = realpath(OMGF_FONTS_DIR . $section);
|
||||
|
||||
if ($resolved_path != $set_path) {
|
||||
wp_die(__('Attempted path traversal detected. Sorry, no script kiddies allowed!', $this->plugin_text_domain));
|
||||
}
|
||||
|
||||
try {
|
||||
$section = $_POST['section'];
|
||||
$entries = array_filter((array) glob(OMGF_FONTS_DIR . $section));
|
||||
|
||||
$instructions = apply_filters(
|
||||
'omgf_clean_up_instructions',
|
||||
[
|
||||
'section' => $section,
|
||||
'exclude' => [],
|
||||
'queue' => [
|
||||
OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZED_FONTS,
|
||||
OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_FONTS,
|
||||
OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_PRELOAD_FONTS,
|
||||
OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_STYLESHEETS
|
||||
]
|
||||
]
|
||||
);
|
||||
|
||||
foreach ($entries as $entry) {
|
||||
if (in_array($entry, $instructions['exclude'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
OMGF::delete($entry);
|
||||
}
|
||||
|
||||
|
||||
foreach ($instructions['queue'] as $option) {
|
||||
delete_option($option);
|
||||
}
|
||||
|
||||
OMGF_Admin_Notice::set_notice(__('Cache directory successfully emptied.', $this->plugin_text_domain));
|
||||
} catch (\Exception $e) {
|
||||
OMGF_Admin_Notice::set_notice(
|
||||
__('OMGF encountered an error while emptying the cache directory: ', $this->plugin_text_domain) . $e->getMessage(),
|
||||
'omgf-cache-error',
|
||||
true,
|
||||
'error',
|
||||
$e->getCode()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* ██████╗ ███╗ ███╗ ██████╗ ███████╗
|
||||
* ██╔═══██╗████╗ ████║██╔════╝ ██╔════╝
|
||||
* ██║ ██║██╔████╔██║██║ ███╗█████╗
|
||||
* ██║ ██║██║╚██╔╝██║██║ ██║██╔══╝
|
||||
* ╚██████╔╝██║ ╚═╝ ██║╚██████╔╝██║
|
||||
* ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝
|
||||
*
|
||||
* @package : OMGF
|
||||
* @author : Daan van den Bergh
|
||||
* @copyright: (c) 2021 Daan van den Bergh
|
||||
* @url : https://daan.dev
|
||||
* * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
class OMGF_Download
|
||||
{
|
||||
/** @var string $url */
|
||||
private $url;
|
||||
|
||||
/** @var string $filename */
|
||||
private $filename;
|
||||
|
||||
/** @var string $extension */
|
||||
private $extension;
|
||||
|
||||
/** @var string $path */
|
||||
private $path;
|
||||
|
||||
/** @var string $plugin_text_domain */
|
||||
private $plugin_text_domain = 'host-webfonts-local';
|
||||
|
||||
/**
|
||||
* OMGF_Download constructor.
|
||||
*/
|
||||
public function __construct(
|
||||
string $url,
|
||||
string $filename,
|
||||
string $extension,
|
||||
string $path
|
||||
) {
|
||||
$this->url = $url;
|
||||
$this->filename = $filename;
|
||||
$this->extension = $extension;
|
||||
$this->path = $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Download $url to $path and return content_url() to $filename.
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws SodiumException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public function download()
|
||||
{
|
||||
if (!function_exists('download_url')) {
|
||||
require_once ABSPATH . 'wp-admin/includes/file.php';
|
||||
}
|
||||
|
||||
wp_mkdir_p($this->path);
|
||||
|
||||
$file = $this->path . '/' . $this->filename . '.' . $this->extension;
|
||||
$file_uri = str_replace(WP_CONTENT_DIR, '', $file);
|
||||
|
||||
if (file_exists($file)) {
|
||||
return urlencode(content_url($file_uri));
|
||||
}
|
||||
|
||||
$tmp = download_url($this->url);
|
||||
|
||||
if (is_wp_error($tmp)) {
|
||||
/** @var WP_Error $tmp */
|
||||
OMGF_Admin_Notice::set_notice(__('OMGF encountered an error while downloading fonts', $this->plugin_text_domain) . ': ' . $tmp->get_error_message(), 'omgf-download-failed', false, 'error', $tmp->get_error_code());
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/** @var string $tmp */
|
||||
copy($tmp, $file);
|
||||
@unlink($tmp);
|
||||
|
||||
return urlencode(content_url($file_uri));
|
||||
}
|
||||
}
|
||||
363
wp-content/plugins/host-webfonts-local/includes/class-omgf.php
Normal file
363
wp-content/plugins/host-webfonts-local/includes/class-omgf.php
Normal file
@@ -0,0 +1,363 @@
|
||||
<?php
|
||||
/* * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* ██████╗ ███╗ ███╗ ██████╗ ███████╗
|
||||
* ██╔═══██╗████╗ ████║██╔════╝ ██╔════╝
|
||||
* ██║ ██║██╔████╔██║██║ ███╗█████╗
|
||||
* ██║ ██║██║╚██╔╝██║██║ ██║██╔══╝
|
||||
* ╚██████╔╝██║ ╚═╝ ██║╚██████╔╝██║
|
||||
* ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝
|
||||
*
|
||||
* @package : OMGF
|
||||
* @author : Daan van den Bergh
|
||||
* @copyright: (c) 2021 Daan van den Bergh
|
||||
* @url : https://daan.dev
|
||||
* * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
class OMGF
|
||||
{
|
||||
/**
|
||||
* OMGF constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->define_constants();
|
||||
|
||||
if (is_admin()) {
|
||||
add_action('plugins_loaded', [$this, 'init_admin'], 50);
|
||||
}
|
||||
|
||||
if (!is_admin()) {
|
||||
add_action('plugins_loaded', [$this, 'init_frontend'], 50);
|
||||
}
|
||||
|
||||
add_action('admin_init', [$this, 'do_optimize']);
|
||||
add_action('rest_api_init', [$this, 'register_routes']);
|
||||
add_filter('content_url', [$this, 'force_ssl'], 1000, 2);
|
||||
|
||||
/**
|
||||
* Render plugin update messages.
|
||||
*/
|
||||
add_action('in_plugin_update_message-' . OMGF_PLUGIN_BASENAME, [$this, 'render_update_notice'], 11, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Define constants.
|
||||
*/
|
||||
public function define_constants()
|
||||
{
|
||||
define('OMGF_SITE_URL', 'https://daan.dev');
|
||||
define('OMGF_CURRENT_DB_VERSION', esc_attr(get_option(OMGF_Admin_Settings::OMGF_CURRENT_DB_VERSION)));
|
||||
define('OMGF_OPTIMIZATION_MODE', esc_attr(get_option(OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZATION_MODE, 'manual')));
|
||||
define('OMGF_MANUAL_OPTIMIZE_URL', esc_attr(get_option(OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_MANUAL_OPTIMIZE_URL, site_url())));
|
||||
define('OMGF_FONT_PROCESSING', esc_attr(get_option(OMGF_Admin_Settings::OMGF_DETECTION_SETTING_FONT_PROCESSING, 'replace')));
|
||||
define('OMGF_DISPLAY_OPTION', esc_attr(get_option(OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_DISPLAY_OPTION, 'swap')) ?: 'swap');
|
||||
define('OMGF_OPTIMIZE_EDIT_ROLES', esc_attr(get_option(OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZE_EDIT_ROLES, 'on')));
|
||||
define('OMGF_CACHE_PATH', esc_attr(get_option(OMGF_Admin_Settings::OMGF_ADV_SETTING_CACHE_PATH)) ?: '/uploads/omgf');
|
||||
define('OMGF_FONTS_DIR', WP_CONTENT_DIR . OMGF_CACHE_PATH);
|
||||
define('OMGF_UNINSTALL', esc_attr(get_option(OMGF_Admin_Settings::OMGF_ADV_SETTING_UNINSTALL)));
|
||||
define('OMGF_UNLOAD_STYLESHEETS', esc_attr(get_option(OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_STYLESHEETS, '')));
|
||||
define('OMGF_CACHE_KEYS', esc_attr(get_option(OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_CACHE_KEYS, '')));
|
||||
}
|
||||
|
||||
/**
|
||||
* Required in Admin.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function init_admin()
|
||||
{
|
||||
$this->do_settings();
|
||||
$this->add_ajax_hooks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Required in Frontend.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function init_frontend()
|
||||
{
|
||||
$this->do_frontend();
|
||||
}
|
||||
|
||||
/**
|
||||
* Manage Optimized Fonts to be displayed in the Optimized Fonts table.
|
||||
*
|
||||
* Use a static variable to reduce database reads/writes.
|
||||
*
|
||||
* @since v4.5.7
|
||||
*
|
||||
* @param array $maybe_add If it doesn't exist, it's added to the cache layer.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function optimized_fonts($maybe_add = [])
|
||||
{
|
||||
/** @var array $optimized_fonts Cache layer */
|
||||
static $optimized_fonts;
|
||||
|
||||
/**
|
||||
* Get a fresh copy from the database if $optimized_fonts is empty|null|false (on 1st run)
|
||||
*/
|
||||
if (empty($optimized_fonts)) {
|
||||
$optimized_fonts = get_option(OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_OPTIMIZED_FONTS, []) ?: [];
|
||||
}
|
||||
|
||||
/**
|
||||
* get_option() should take care of this, but sometimes it doesn't.
|
||||
*
|
||||
* @since v4.5.6
|
||||
*/
|
||||
if (is_string($optimized_fonts)) {
|
||||
$optimized_fonts = unserialize($optimized_fonts);
|
||||
}
|
||||
|
||||
/**
|
||||
* If $maybe_add doesn't exist in the cache layer yet, add it.
|
||||
*
|
||||
* @since v4.5.7
|
||||
*/
|
||||
if (!empty($maybe_add) && !isset($optimized_fonts[key($maybe_add)])) {
|
||||
$optimized_fonts = array_merge($optimized_fonts, $maybe_add);
|
||||
}
|
||||
|
||||
return $optimized_fonts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function preloaded_fonts()
|
||||
{
|
||||
static $preloaded_fonts = [];
|
||||
|
||||
if (empty($preloaded_fonts)) {
|
||||
$preloaded_fonts = get_option(OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_PRELOAD_FONTS, []) ?: [];
|
||||
}
|
||||
|
||||
return $preloaded_fonts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function unloaded_fonts()
|
||||
{
|
||||
static $unloaded_fonts = [];
|
||||
|
||||
if (empty($unloaded_fonts)) {
|
||||
$unloaded_fonts = get_option(OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_FONTS, []) ?: [];
|
||||
}
|
||||
|
||||
return $unloaded_fonts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function unloaded_stylesheets()
|
||||
{
|
||||
static $unloaded_stylesheets = [];
|
||||
|
||||
if (empty($unloaded_stylesheets)) {
|
||||
$unloaded_stylesheets = explode(',', get_option(OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_UNLOAD_STYLESHEETS, ''));
|
||||
}
|
||||
|
||||
return array_filter($unloaded_stylesheets);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function cache_keys()
|
||||
{
|
||||
static $cache_keys = [];
|
||||
|
||||
if (empty($cache_keys)) {
|
||||
$cache_keys = explode(',', get_option(OMGF_Admin_Settings::OMGF_OPTIMIZE_SETTING_CACHE_KEYS, ''));
|
||||
}
|
||||
|
||||
return array_filter($cache_keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $handle
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_cache_key($handle)
|
||||
{
|
||||
$cache_keys = self::cache_keys();
|
||||
|
||||
foreach ($cache_keys as $index => $key) {
|
||||
if (strpos($key, $handle) !== false) {
|
||||
return $key;
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Download $url and save as $filename.$extension to $path.
|
||||
*
|
||||
* @param mixed $url
|
||||
* @param mixed $filename
|
||||
* @param mixed $extension
|
||||
* @param mixed $path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function download($url, $filename, $extension, $path)
|
||||
{
|
||||
$download = new OMGF_Download($url, $filename, $extension, $path);
|
||||
|
||||
return $download->download();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $fonts
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function generate_stylesheet($fonts, $handle = '', $plugin = 'OMGF')
|
||||
{
|
||||
$generator = new OMGF_StylesheetGenerator($fonts, $handle, $plugin);
|
||||
|
||||
return $generator->generate();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return OMGF_Admin_Settings
|
||||
*/
|
||||
private function do_settings()
|
||||
{
|
||||
return new OMGF_Admin_Settings();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return OMGF_AJAX
|
||||
*/
|
||||
private function add_ajax_hooks()
|
||||
{
|
||||
return new OMGF_AJAX();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return OMGF_Frontend_Functions
|
||||
*/
|
||||
public function do_frontend()
|
||||
{
|
||||
return new OMGF_Frontend_Functions();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function register_routes()
|
||||
{
|
||||
$proxy = new OMGF_API_Download();
|
||||
$proxy->register_routes();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return OMGF_Optimize
|
||||
*/
|
||||
public function do_optimize()
|
||||
{
|
||||
return new OMGF_Optimize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Render update notices if available.
|
||||
*
|
||||
* @param mixed $plugin
|
||||
* @param mixed $response
|
||||
* @return void
|
||||
*/
|
||||
public function render_update_notice($plugin, $response)
|
||||
{
|
||||
$current_version = $plugin['Version'];
|
||||
$new_version = $plugin['new_version'];
|
||||
|
||||
if (version_compare($current_version, $new_version, '<')) {
|
||||
$response = wp_remote_get('https://daan.dev/omgf-update-notices.json');
|
||||
|
||||
if (is_wp_error($response)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$update_notices = (array) json_decode(wp_remote_retrieve_body($response));
|
||||
|
||||
if (!isset($update_notices[$new_version])) {
|
||||
return;
|
||||
}
|
||||
|
||||
printf(
|
||||
' <strong>' . __('This update includes major changes, please <a href="%s" target="_blank">read this</a> before continuing.') . '</strong>',
|
||||
$update_notices[$new_version]->url
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* content_url() uses is_ssl() to detect whether SSL is used. This fails for servers behind
|
||||
* load balancers and/or reverse proxies. So, we double check with this filter.
|
||||
*
|
||||
* @since v4.4.4
|
||||
*
|
||||
* @param mixed $url
|
||||
* @param mixed $path
|
||||
* @return mixed
|
||||
*/
|
||||
public function force_ssl($url, $path)
|
||||
{
|
||||
/**
|
||||
* Only rewrite URLs requested by this plugin. We don't want to interfere with other plugins.
|
||||
*/
|
||||
if (strpos($url, OMGF_CACHE_PATH) === false) {
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the user entered https:// in the Home URL option, it's safe to assume that SSL is used.
|
||||
*/
|
||||
if (!is_ssl() && strpos(home_url(), 'https://') !== false) {
|
||||
$url = str_replace('http://', 'https://', $url);
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return OMGF_Uninstall
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public static function do_uninstall()
|
||||
{
|
||||
return new OMGF_Uninstall();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $entry
|
||||
*/
|
||||
public static function delete($entry)
|
||||
{
|
||||
if (is_dir($entry)) {
|
||||
$file = new \FilesystemIterator($entry);
|
||||
|
||||
// If dir is empty, valid() returns false.
|
||||
while ($file->valid()) {
|
||||
self::delete($file->getPathName());
|
||||
$file->next();
|
||||
}
|
||||
|
||||
rmdir($entry);
|
||||
} else {
|
||||
unlink($entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* ██████╗ ███╗ ███╗ ██████╗ ███████╗
|
||||
* ██╔═══██╗████╗ ████║██╔════╝ ██╔════╝
|
||||
* ██║ ██║██╔████╔██║██║ ███╗█████╗
|
||||
* ██║ ██║██║╚██╔╝██║██║ ██║██╔══╝
|
||||
* ╚██████╔╝██║ ╚═╝ ██║╚██████╔╝██║
|
||||
* ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝
|
||||
*
|
||||
* @package : OMGF
|
||||
* @author : Daan van den Bergh
|
||||
* @copyright: (c) 2021 Daan van den Bergh
|
||||
* @url : https://daan.dev
|
||||
* * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
class OMGF_Optimize
|
||||
{
|
||||
/** @var string */
|
||||
private $settings_page = '';
|
||||
|
||||
/** @var string */
|
||||
private $settings_tab = '';
|
||||
|
||||
/** @var bool */
|
||||
private $settings_updated = false;
|
||||
|
||||
/**
|
||||
* OMGF_Optimize constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->settings_page = $_GET['page'] ?? '';
|
||||
$this->settings_tab = $_GET['tab'] ?? OMGF_Admin_Settings::OMGF_SETTINGS_FIELD_OPTIMIZE;
|
||||
$this->settings_updated = isset($_GET['settings-updated']);
|
||||
|
||||
$this->init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Run either manual or auto mode after settings are updated.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function init()
|
||||
{
|
||||
if (OMGF_Admin_Settings::OMGF_ADMIN_PAGE != $this->settings_page) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (OMGF_Admin_Settings::OMGF_SETTINGS_FIELD_OPTIMIZE != $this->settings_tab) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$this->settings_updated) {
|
||||
return;
|
||||
}
|
||||
|
||||
add_filter('http_request_args', [$this, 'verify_ssl']);
|
||||
|
||||
$optimization_mode = apply_filters('omgf_optimization_mode', OMGF_OPTIMIZATION_MODE);
|
||||
|
||||
if ('manual' == $optimization_mode) {
|
||||
$this->run_manual();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If this site is non-SSL it makes no sense to verify its SSL certificates.
|
||||
*
|
||||
* Settings sslverify to false will set CURLOPT_SSL_VERIFYPEER and CURLOPT_SSL_VERIFYHOST
|
||||
* to 0 further down the road.
|
||||
*
|
||||
* @param mixed $url
|
||||
* @return array
|
||||
*/
|
||||
public function verify_ssl($args)
|
||||
{
|
||||
$args['sslverify'] = strpos(home_url(), 'https:') !== false;
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run Manual mode.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function run_manual()
|
||||
{
|
||||
new OMGF_OptimizationMode_Manual();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
<?php
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* ██████╗ ███╗ ███╗ ██████╗ ███████╗
|
||||
* ██╔═══██╗████╗ ████║██╔════╝ ██╔════╝
|
||||
* ██║ ██║██╔████╔██║██║ ███╗█████╗
|
||||
* ██║ ██║██║╚██╔╝██║██║ ██║██╔══╝
|
||||
* ╚██████╔╝██║ ╚═╝ ██║╚██████╔╝██║
|
||||
* ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝
|
||||
*
|
||||
* @package : OMGF
|
||||
* @author : Daan van den Bergh
|
||||
* @copyright: (c) 2021 Daan van den Bergh
|
||||
* @url : https://daan.dev
|
||||
* * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
class OMGF_StylesheetGenerator
|
||||
{
|
||||
/** @var $fonts */
|
||||
private $fonts;
|
||||
|
||||
/** @var string $handle */
|
||||
private $handle;
|
||||
|
||||
/** @var string $plugin */
|
||||
private $plugin;
|
||||
|
||||
/**
|
||||
* OMGF_GenerateStylesheet constructor.
|
||||
*/
|
||||
public function __construct(
|
||||
$fonts,
|
||||
string $handle,
|
||||
string $plugin
|
||||
) {
|
||||
$this->fonts = $fonts;
|
||||
$this->handle = $handle;
|
||||
$this->plugin = $plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a stylesheet based on the provided $fonts.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function generate()
|
||||
{
|
||||
/**
|
||||
* Which file types should we download and include in the stylesheet?
|
||||
*
|
||||
* @since v4.5
|
||||
*/
|
||||
$file_types = apply_filters('omgf_include_file_types', ['woff2', 'woff', 'eot', 'ttf', 'svg']);
|
||||
$font_display = OMGF_DISPLAY_OPTION;
|
||||
$stylesheet = "/**\n * Auto Generated by $this->plugin\n * @author: Daan van den Bergh\n * @url: https://ffw.press\n */\n\n";
|
||||
|
||||
foreach ($this->fonts as $font) {
|
||||
/**
|
||||
* If Font Family's name was recently renamed, the old name should be used so no manual changes have to be made
|
||||
* to the stylesheet after processing.
|
||||
*/
|
||||
$renamed_font_family = in_array($font->id, OMGF_API_Download::OMGF_RENAMED_GOOGLE_FONTS)
|
||||
? array_search($font->id, OMGF_API_Download::OMGF_RENAMED_GOOGLE_FONTS)
|
||||
: '';
|
||||
|
||||
foreach ($font->variants as $variant) {
|
||||
/**
|
||||
* Filter font_family name.
|
||||
*
|
||||
* @since v4.5.1
|
||||
*/
|
||||
$font_family = apply_filters('omgf_generate_stylesheet_font_family', $renamed_font_family ? ucfirst(rawurldecode($renamed_font_family)) : rawurldecode($variant->fontFamily));
|
||||
$font_style = $variant->fontStyle;
|
||||
$font_weight = $variant->fontWeight;
|
||||
$stylesheet .= "@font-face {\n";
|
||||
$stylesheet .= " font-family: $font_family;\n";
|
||||
$stylesheet .= " font-style: $font_style;\n";
|
||||
$stylesheet .= " font-weight: $font_weight;\n";
|
||||
$stylesheet .= " font-display: $font_display;\n";
|
||||
|
||||
/**
|
||||
* For IE compatibility, EOT is added before the local family name is defined.
|
||||
*/
|
||||
if (in_array('eot', $file_types)) {
|
||||
$stylesheet .= " src: url('" . urldecode($variant->eot) . "');\n";
|
||||
$eot_key = array_search('eot', $file_types);
|
||||
unset($file_types[$eot_key]);
|
||||
}
|
||||
|
||||
$local_src = '';
|
||||
|
||||
if (isset($variant->local) && is_array($variant->local)) {
|
||||
foreach ($variant->local as $local) {
|
||||
$local_src .= "local('$local'), ";
|
||||
}
|
||||
}
|
||||
|
||||
$stylesheet .= " src: $local_src\n";
|
||||
$font_src_url = [];
|
||||
|
||||
foreach ($file_types as $file_type) {
|
||||
if (isset($variant->$file_type)) {
|
||||
$font_src_url = array_merge($font_src_url, [$file_type => urldecode($variant->$file_type)]);
|
||||
}
|
||||
}
|
||||
|
||||
$stylesheet .= $this->build_source_string($font_src_url);
|
||||
$stylesheet .= "}\n";
|
||||
}
|
||||
}
|
||||
|
||||
return $stylesheet;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $sources
|
||||
* @param string $type
|
||||
* @param bool $end_semi_colon
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function build_source_string($sources, $type = 'url', $end_semi_colon = true)
|
||||
{
|
||||
$last_src = end($sources);
|
||||
$source = '';
|
||||
|
||||
foreach ($sources as $format => $url) {
|
||||
$source .= " $type('$url')" . (!is_numeric($format) ? " format('$format')" : '');
|
||||
|
||||
if ($url === $last_src && $end_semi_colon) {
|
||||
$source .= ";\n";
|
||||
} else {
|
||||
$source .= ",\n";
|
||||
}
|
||||
}
|
||||
|
||||
return $source;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
/* * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* ██████╗ ███╗ ███╗ ██████╗ ███████╗
|
||||
* ██╔═══██╗████╗ ████║██╔════╝ ██╔════╝
|
||||
* ██║ ██║██╔████╔██║██║ ███╗█████╗
|
||||
* ██║ ██║██║╚██╔╝██║██║ ██║██╔══╝
|
||||
* ╚██████╔╝██║ ╚═╝ ██║╚██████╔╝██║
|
||||
* ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝
|
||||
*
|
||||
* @package : OMGF
|
||||
* @author : Daan van den Bergh
|
||||
* @copyright: (c) 2021 Daan van den Bergh
|
||||
* @url : https://daan.dev
|
||||
* * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
class OMGF_Uninstall
|
||||
{
|
||||
/** @var QM_DB $wpdb */
|
||||
private $wpdb;
|
||||
|
||||
/** @var array $options */
|
||||
private $options;
|
||||
|
||||
/** @var string $cacheDir */
|
||||
private $cacheDir;
|
||||
|
||||
/**
|
||||
* OMGF_Uninstall constructor.
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
if (OMGF_UNINSTALL !== 'on') {
|
||||
return;
|
||||
}
|
||||
|
||||
global $wpdb;
|
||||
$settings = new OMGF_Admin_Settings();
|
||||
|
||||
$this->wpdb = $wpdb;
|
||||
$this->options = $settings->get_settings();
|
||||
$this->cacheDir = OMGF_FONTS_DIR;
|
||||
|
||||
$this->remove_db_entries();
|
||||
$this->delete_files();
|
||||
$this->delete_dir();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all settings stored in the wp_options table.
|
||||
*/
|
||||
private function remove_db_entries()
|
||||
{
|
||||
foreach ($this->options as $key => $option) {
|
||||
delete_option($option);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all files stored in the cache directory.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function delete_files()
|
||||
{
|
||||
return array_map('unlink', glob($this->cacheDir . '/*.*'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the cache directory.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function delete_dir()
|
||||
{
|
||||
return rmdir($this->cacheDir);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,243 @@
|
||||
<?php
|
||||
/* * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* ██████╗ ███╗ ███╗ ██████╗ ███████╗
|
||||
* ██╔═══██╗████╗ ████║██╔════╝ ██╔════╝
|
||||
* ██║ ██║██╔████╔██║██║ ███╗█████╗
|
||||
* ██║ ██║██║╚██╔╝██║██║ ██║██╔══╝
|
||||
* ╚██████╔╝██║ ╚═╝ ██║╚██████╔╝██║
|
||||
* ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝
|
||||
*
|
||||
* @package : OMGF
|
||||
* @author : Daan van den Bergh
|
||||
* @copyright: (c) 2021 Daan van den Bergh
|
||||
* @url : https://daan.dev
|
||||
* * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
class OMGF_Frontend_Functions
|
||||
{
|
||||
const OMGF_STYLE_HANDLE = 'omgf-fonts';
|
||||
|
||||
/** @var bool $do_optimize */
|
||||
private $do_optimize;
|
||||
|
||||
/**
|
||||
* OMGF_Frontend_Functions constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->do_optimize = $this->maybe_optimize_fonts();
|
||||
|
||||
if (!$this->do_optimize) {
|
||||
return;
|
||||
}
|
||||
|
||||
add_action('wp_head', [$this, 'add_preloads'], 3);
|
||||
add_action('wp_print_styles', [$this, 'process_fonts'], PHP_INT_MAX - 1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Should we optimize for logged in editors/administrators?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function maybe_optimize_fonts()
|
||||
{
|
||||
/**
|
||||
* Allows us to quickly bypass fonts optimization.
|
||||
*/
|
||||
if (isset($_GET['nomgf'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!OMGF_OPTIMIZE_EDIT_ROLES && current_user_can('edit_pages')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: When setting all preloads at once (different stylesheet handles) combined with unloads, not all URLs are rewritten with their cache keys properly.
|
||||
* When configured handle by handle, it works fine. PHP multi-threading issues?
|
||||
*/
|
||||
public function add_preloads()
|
||||
{
|
||||
$preloaded_fonts = apply_filters('omgf_frontend_preloaded_fonts', OMGF::preloaded_fonts());
|
||||
|
||||
if (!$preloaded_fonts) {
|
||||
return;
|
||||
}
|
||||
|
||||
$optimized_fonts = apply_filters('omgf_frontend_optimized_fonts', OMGF::optimized_fonts());
|
||||
|
||||
/**
|
||||
* When OMGF Pro is enabled and set to Automatic mode, the merged handle is used to only load selected
|
||||
* preloads for the currently used stylesheet.
|
||||
*
|
||||
* @since v4.5.3 Added 2nd dummy parameter, to prevent Fatal Errors after updating.
|
||||
*/
|
||||
$pro_handle = apply_filters('omgf_pro_merged_handle', '', '');
|
||||
$i = 0;
|
||||
|
||||
foreach ($optimized_fonts as $stylesheet_handle => $font_faces) {
|
||||
if ($pro_handle && $stylesheet_handle != $pro_handle) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($font_faces as $font_face) {
|
||||
$preloads_stylesheet = $preloaded_fonts[$stylesheet_handle] ?? [];
|
||||
|
||||
if (!in_array($font_face->id, array_keys($preloads_stylesheet))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$font_id = $font_face->id;
|
||||
$preload_variants = array_filter(
|
||||
(array) $font_face->variants,
|
||||
function ($variant) use ($preloads_stylesheet, $font_id) {
|
||||
return in_array($variant->id, $preloads_stylesheet[$font_id]);
|
||||
}
|
||||
);
|
||||
|
||||
foreach ($preload_variants as $variant) {
|
||||
$url = rawurldecode($variant->woff2);
|
||||
echo "<link id='omgf-preload-$i' rel='preload' href='$url' as='font' type='font/woff2' crossorigin />\n";
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the Remove Google Fonts option is enabled.
|
||||
*/
|
||||
public function process_fonts()
|
||||
{
|
||||
if (is_admin()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (apply_filters('omgf_pro_advanced_processing_enabled', false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (OMGF_FONT_PROCESSING) {
|
||||
case 'remove':
|
||||
add_action('wp_print_styles', [$this, 'remove_registered_fonts'], PHP_INT_MAX - 500);
|
||||
break;
|
||||
default:
|
||||
add_action('wp_print_styles', [$this, 'replace_registered_stylesheets'], PHP_INT_MAX - 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function contains a nice little hack, to avoid messing with potential dependency issues. We simply set the source to an empty string!
|
||||
*/
|
||||
public function remove_registered_fonts()
|
||||
{
|
||||
global $wp_styles;
|
||||
|
||||
$registered = $wp_styles->registered;
|
||||
$stylesheets = apply_filters('omgf_remove_detected_stylesheets', $this->detect_registered_stylesheets($registered));
|
||||
|
||||
foreach ($stylesheets as $handle => $stylesheet) {
|
||||
$wp_styles->registered[$handle]->src = '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve stylesheets from Google Fonts' API and modify the stylesheet for local storage.
|
||||
*/
|
||||
public function replace_registered_stylesheets()
|
||||
{
|
||||
global $wp_styles;
|
||||
|
||||
$registered = $wp_styles->registered;
|
||||
$stylesheets = apply_filters('omgf_replace_detected_stylesheets', $this->detect_registered_stylesheets($registered));
|
||||
$unloaded_stylesheets = OMGF::unloaded_stylesheets();
|
||||
$unloaded_fonts = OMGF::unloaded_fonts();
|
||||
|
||||
foreach ($stylesheets as $handle => $stylesheet) {
|
||||
// If this stylesheet has been marked for unload, empty the src and skip out early.
|
||||
if (in_array($handle, $unloaded_stylesheets)) {
|
||||
$wp_styles->registered[$handle]->src = '';
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$updated_handle = $handle;
|
||||
|
||||
if ($unloaded_fonts) {
|
||||
$updated_handle = OMGF::get_cache_key($handle);
|
||||
}
|
||||
|
||||
$cached_file = OMGF_CACHE_PATH . '/' . $updated_handle . "/$updated_handle.css";
|
||||
|
||||
/**
|
||||
* Bail early if stylesheet already exists.
|
||||
*/
|
||||
if (file_exists(WP_CONTENT_DIR . $cached_file)) {
|
||||
$wp_styles->registered[$handle]->src = content_url($cached_file);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/**
|
||||
* For future reference: this logic can't be moved to backend, because there's no other way to properly access the
|
||||
* $wp_styles global.
|
||||
*
|
||||
* @see $wp_styles global
|
||||
*/
|
||||
if (OMGF_OPTIMIZATION_MODE == 'manual' && isset($_GET['omgf_optimize'])) {
|
||||
$request = parse_url($stylesheet->src);
|
||||
$query = $request['query'] ?? '';
|
||||
$path = $request['path'] ?? '/css';
|
||||
|
||||
parse_str($query, $query_array);
|
||||
|
||||
if (empty($query_array)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$params = http_build_query(
|
||||
array_merge(
|
||||
$query_array,
|
||||
[
|
||||
'handle' => $updated_handle,
|
||||
'original_handle' => $handle,
|
||||
'_wpnonce' => wp_create_nonce('wp_rest')
|
||||
]
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
* Use Home URL directly while building API request. This might prevent local development (non-SSL) issues.
|
||||
*/
|
||||
$wp_styles->registered[$handle]->src = home_url('/wp-json/omgf/v1/download') . $path . '?' . $params;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $registered_styles
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function detect_registered_stylesheets($registered_styles)
|
||||
{
|
||||
$detected_stylesheets = array_filter(
|
||||
$registered_styles,
|
||||
function ($contents) {
|
||||
return strpos($contents->src, 'fonts.googleapis.com/css') !== false;
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* @since v4.5.11 Added filter to allow adding additional stylesheets.
|
||||
*/
|
||||
return apply_filters('omgf_detected_registered_stylesheets', $detected_stylesheets, $registered_styles);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,271 @@
|
||||
<?php
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* ██████╗ ███╗ ███╗ ██████╗ ███████╗
|
||||
* ██╔═══██╗████╗ ████║██╔════╝ ██╔════╝
|
||||
* ██║ ██║██╔████╔██║██║ ███╗█████╗
|
||||
* ██║ ██║██║╚██╔╝██║██║ ██║██╔══╝
|
||||
* ╚██████╔╝██║ ╚═╝ ██║╚██████╔╝██║
|
||||
* ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝
|
||||
*
|
||||
* @package : OMGF
|
||||
* @author : Daan van den Bergh
|
||||
* @copyright: (c) 2021 Daan van den Bergh
|
||||
* @url : https://daan.dev
|
||||
* * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
class OMGF_OptimizationMode_Manual
|
||||
{
|
||||
/** @var string */
|
||||
private $plugin_text_domain = 'host-webfonts-local';
|
||||
|
||||
/**
|
||||
* Build class.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->run();
|
||||
}
|
||||
|
||||
/**
|
||||
* Run Manual mode.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function run()
|
||||
{
|
||||
$url = esc_url_raw(OMGF_MANUAL_OPTIMIZE_URL);
|
||||
$front_html = $this->get_front_html($url);
|
||||
$error = false;
|
||||
|
||||
if (is_wp_error($front_html) || wp_remote_retrieve_response_code($front_html) != 200) {
|
||||
$this->frontend_fetch_failed($front_html);
|
||||
|
||||
$error = true;
|
||||
}
|
||||
|
||||
$api_request_urls = [];
|
||||
$document = new DOMDocument();
|
||||
|
||||
libxml_use_internal_errors(true);
|
||||
@$document->loadHtml(wp_remote_retrieve_body($front_html));
|
||||
|
||||
foreach ($document->getElementsByTagName('link') as $link) {
|
||||
/** @var DOMElement $link */
|
||||
if ($link->hasAttribute('href') && strpos($link->getAttribute('href'), '/omgf/v1/download/')) {
|
||||
$api_request_urls[] = $link->getAttribute('href');
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($api_request_urls)) {
|
||||
$this->no_urls_found();
|
||||
|
||||
$error = true;
|
||||
}
|
||||
|
||||
foreach ($api_request_urls as $url) {
|
||||
if (strpos($url, 'css2') !== false) {
|
||||
$url = $this->convert($url);
|
||||
}
|
||||
|
||||
$download = $this->do_rest_request($url);
|
||||
|
||||
/** @var WP_REST_Response $download */
|
||||
if ($download->is_error()) {
|
||||
$this->download_failed($download);
|
||||
|
||||
$error = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$error) {
|
||||
$this->optimization_succeeded();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts requests to Google's Variable Fonts (CSS2) API to the 'old' (CSS) API.
|
||||
*
|
||||
* @param string $css2_url
|
||||
*/
|
||||
private function convert($css2_url)
|
||||
{
|
||||
$parsed_url = parse_url($css2_url);
|
||||
$query = $parsed_url['query'];
|
||||
parse_str($query, $params);
|
||||
$raw_params = explode('&', $query);
|
||||
$font_families = [];
|
||||
$fonts = [];
|
||||
|
||||
foreach ($raw_params as $param) {
|
||||
if (strpos($param, 'family') === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
parse_str($param, $parts);
|
||||
|
||||
$font_families[] = $parts['family'];
|
||||
}
|
||||
|
||||
if (empty($font_families)) {
|
||||
return $css2_url;
|
||||
}
|
||||
|
||||
foreach ($font_families as $font_family) {
|
||||
if (strpos($font_family, ':') !== false) {
|
||||
list($family, $weights) = explode(':', $font_family);
|
||||
} else {
|
||||
$family = $font_family;
|
||||
$weights = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array [ '300', '400', '500', etc. ]
|
||||
*/
|
||||
$weights = explode(';', substr($weights, strpos($weights, '@') + 1));
|
||||
|
||||
foreach ($weights as &$weight) {
|
||||
$properties = explode(',', $weight);
|
||||
$weight = $properties[0] == '1' ? $properties[1] . 'italic' : $properties[1];
|
||||
}
|
||||
|
||||
$fonts[] = $family . ':' . implode(',', $weights);
|
||||
}
|
||||
|
||||
$params['family'] = implode('|', $fonts);
|
||||
|
||||
return $parsed_url['scheme'] . '://' . $parsed_url['host'] . $parsed_url['path'] . '?' . http_build_query($params);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
*
|
||||
* @return WP_REST_Response
|
||||
*/
|
||||
private function do_rest_request($url)
|
||||
{
|
||||
$parsed_url = parse_url($url);
|
||||
$request = new WP_REST_Request('GET', str_replace('/wp-json', '', $parsed_url['path']));
|
||||
|
||||
parse_str($parsed_url['query'], $query_params);
|
||||
|
||||
if (isset($query_params['_wpnonce'])) {
|
||||
unset($query_params['_wpnonce']);
|
||||
}
|
||||
|
||||
$request->set_query_params($query_params);
|
||||
|
||||
// TODO: Find out proper WP way to add this param to request.
|
||||
$_REQUEST['_wpnonce'] = wp_create_nonce('wp_rest');
|
||||
|
||||
return rest_do_request($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
private function optimization_succeeded()
|
||||
{
|
||||
add_settings_error('general', 'omgf_optimization_success', __('Optimization completed successfully.'), 'success');
|
||||
|
||||
OMGF_Admin_Notice::set_notice(
|
||||
__('If you\'re using any 3rd party optimization plugins (e.g. WP Rocket, Autoptimize, W3 Total Cache, etc.) make sure to flush their caches for OMGF\'s optimizations to take effect.', $this->plugin_text_domain),
|
||||
'omgf-cache-notice',
|
||||
false,
|
||||
'warning'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $response WP_REST_Response
|
||||
*/
|
||||
private function download_failed($response)
|
||||
{
|
||||
add_settings_error('general', 'omgf_download_failed', __('OMGF encountered an error while downloading Google Fonts', $this->plugin_text_domain) . ': ' . $this->get_error_code($response) . ' - ' . $this->get_error_message($response), 'error');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $response WP_Error|array
|
||||
*/
|
||||
private function frontend_fetch_failed($response)
|
||||
{
|
||||
add_settings_error('general', 'omgf_frontend_fetch_failed', __('OMGF encountered an error while fetching this site\'s frontend HTML', $this->plugin_text_domain) . ': ' . $this->get_error_code($response) . ' - ' . $this->get_error_message($response), 'error');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
private function no_urls_found()
|
||||
{
|
||||
add_settings_error('general', 'omgf_no_urls_found', sprintf(__('No (additional) Google Fonts found to optimize. If you believe this is an error, please refer to the %stroubleshooting%s section of the documentation for possible solutions.', $this->plugin_text_domain), '<a href="https://docs.ffw.press/category/37-omgf-pro---troubleshooting">', '</a>'), 'info');
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for wp_remote_get() with preset params.
|
||||
*
|
||||
* @param mixed $url
|
||||
* @return array|WP_Error
|
||||
*/
|
||||
private function get_front_html($url)
|
||||
{
|
||||
return wp_remote_get(
|
||||
$this->no_cache_optimize_url($url),
|
||||
[
|
||||
'timeout' => 30
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $url
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function no_cache_optimize_url($url)
|
||||
{
|
||||
return add_query_arg(['omgf_optimize' => 1, 'nocache' => substr(md5(microtime()), rand(0, 26), 5)], $url);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WP_REST_Response|WP_Error|array $response
|
||||
*
|
||||
* @return int|string
|
||||
*/
|
||||
private function get_error_code($response)
|
||||
{
|
||||
if ($response instanceof WP_REST_Response && $response->is_error()) {
|
||||
// Convert to WP_Error if WP_REST_Response
|
||||
$response = $response->as_error();
|
||||
}
|
||||
|
||||
if (is_wp_error($response)) {
|
||||
return $response->get_error_code();
|
||||
}
|
||||
|
||||
return wp_remote_retrieve_response_code($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WP_REST_Response|WP_Error|array $response
|
||||
*
|
||||
* @return int|string
|
||||
*/
|
||||
private function get_error_message($response)
|
||||
{
|
||||
if ($response instanceof WP_REST_Response && $response->is_error()) {
|
||||
// Convert to WP_Error if WP_REST_Response
|
||||
$response = $response->as_error();
|
||||
}
|
||||
|
||||
if (is_wp_error($response)) {
|
||||
return $response->get_error_message();
|
||||
}
|
||||
|
||||
return wp_remote_retrieve_response_message($response);
|
||||
}
|
||||
}
|
||||
76
wp-content/plugins/host-webfonts-local/readme.md
Normal file
76
wp-content/plugins/host-webfonts-local/readme.md
Normal file
@@ -0,0 +1,76 @@
|
||||
# OMGF | Host Google Fonts Locally
|
||||
|
||||
OMGF automagically caches the Google Fonts used by your theme/plugins locally. No configuration (or brains) required!
|
||||
|
||||
## Description
|
||||
|
||||
> How could using fonts via Google's service possibly run afoul of GDPR? The fact of the matter is that, when a font is requested by the user's browser, their IP is logged by Google and used for analytics.
|
||||
> — Lifehacker
|
||||
|
||||
Leverage Browser Cache, Minimize DNS requests and serve your Google Fonts in a 100% GDPR compliant way with OMGF!
|
||||
|
||||
OMGF is written with performance and user-friendliness in mind. It uses the Google Fonts Helper API to automatically cache the fonts your theme and plugins use to **minimize DNS requests** and speed up your WordPress website.
|
||||
|
||||
### How Does It Work?
|
||||
|
||||
After installing the plugin, OMGF runs silently in the background and captures any requests made to fonts.googleapis.com or fonts.gstatic.com. When a webpage is first loaded, it reroutes these requests to its own Download API and copies the fonts over to your server. Then it generates a stylesheet for your fonts including EOT, TTF, WOFF and WOFF2 formats to guarantee maximum cross browser compatibility!
|
||||
|
||||
When the fonts are downloaded and the stylesheet is generated, it rewrites every URL pointing to fonts.googleapis.com or fonts.gstatic.com to the locally hosted variant.
|
||||
|
||||
Please keep in mind that, although I try to make the configuration of this plugin as easy as possible, the concept of locally hosting a file or optimizing Google Fonts for *Pagespeed Insights* or *GT Metrix* has proven to be confusing for some people. If you're not sure of what your doing, please consult a SEO expert or Webdeveloper to help you with the configuration of this plugin or [hire me to do it for you](https://ffw.press/wordpress/omgf-expert-configuration/).
|
||||
|
||||
### Features
|
||||
- Automatically replace registered/enqueued Google Fonts in wp_head() with local copies,
|
||||
- Automatically remove registered/enqueued Google Fonts from wp_head(),
|
||||
- Manage Optimized Google Fonts,
|
||||
- Preload above the fold fonts,
|
||||
- Don't load certain fonts or entire stylesheets.
|
||||
- Leverage the font-display (swap) option.
|
||||
|
||||
### Features in the PRO version
|
||||
Everything in the free version, plus:
|
||||
- Specify a Fallback Font Stack for every Google Font, to reduce Cumulative Layout Shift,
|
||||
- Automatically remove/replace all Google Fonts throughout the entire document/page,
|
||||
- Also supports WebFont Loader (webfont.js), Early Access Google Fonts and requests in stylesheets using @import and @font-face statements.
|
||||
- Automatically generate different stylesheets for pages with different Google Fonts configurations.
|
||||
- Material Icons support.
|
||||
- Combine all Google Fonts stylesheets (requested by your theme and/or plugins) into one file,
|
||||
- Deduplicate Google Fonts stylesheets,
|
||||
- Rewrite stylesheets added by other plugins and/or themes to include the configured font-display (e.g. swap) option, this will remove *the ensure text remains visible during webfont load* optimization suggestion from Google PageSpeed Insights,
|
||||
- Define file types to include in stylesheet (WOFF, WOFF2, EOT, TTF, SVG),
|
||||
- Reduce loading time and page size, by forcing the used subset(s) for all Google Fonts requests,
|
||||
- Remove Resource Hints (preload, preconnect, dns-prefetch) pointing to fonts.googleapis.com or fonts.gstatic.com,
|
||||
- Modify `src` attribute for fonts in stylesheet using the Fonts Source URL option to fully integrate with your configuration,
|
||||
- Use this to serve fonts and the stylesheets from your CDN, or
|
||||
- To serve fonts from an alternative path (e.g. when you're using Security through Obscurity plugins like WP Hide, etc.), or
|
||||
- Anything you like!
|
||||
- Proper handling for AMP pages (Fallback to or remove Google Fonts).
|
||||
|
||||
**[Documentation](https://docs.ffw.press/category/4-omgf-pro/) | [Purchase OMGF Pro](https://ffw.press/wordpress/omgf-pro/)**
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
### Using GIT
|
||||
|
||||
1. From your terminal, `cd` to your plugins directory (usually `wp-content/plugins`)
|
||||
1. Run the following command: `git clone https://github.com/Dan0sz/host-webfonts-locally.git host-webfonts-local`
|
||||
|
||||
### From the Wordpress Repository
|
||||
|
||||
1. From your WordPress administrator area, go to *Plugins > Add New*
|
||||
1. Search for 'Daan van den Bergh'
|
||||
1. Click the 'Install' button next to *OMGF | Host Google Fonts Locally*
|
||||
1. Click 'Activate'
|
||||
|
||||
## Frequently Asked Questions
|
||||
|
||||
Visit the [FAQ at Wordpress.org](https://wordpress.org/plugins/host-webfonts-local/#faq)
|
||||
|
||||
## Support
|
||||
|
||||
For Support Queries, checkout the [Support Forum at Wordpress.org](https://wordpress.org/support/plugin/host-webfonts-local)
|
||||
|
||||
## Changelog
|
||||
|
||||
Visit the [Changelog at Wordpress.org](https://wordpress.org/plugins/host-webfonts-local/#developers)
|
||||
327
wp-content/plugins/host-webfonts-local/readme.txt
Normal file
327
wp-content/plugins/host-webfonts-local/readme.txt
Normal file
@@ -0,0 +1,327 @@
|
||||
=== OMGF | Host Google Fonts Locally ===
|
||||
Contributors: DaanvandenBergh
|
||||
Tags: google, fonts, gdpr, cache, speed, preload, font-display, webfonts, subsets, remove, minimize, external, requests
|
||||
Requires at least: 4.6
|
||||
Tested up to: 5.8
|
||||
Stable tag: 4.5.13
|
||||
Requires PHP: 7.0
|
||||
License: GPLv2 or later
|
||||
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
|
||||
OMGF automagically caches the Google Fonts used by your theme/plugins locally. No configuration (or brains) required!
|
||||
|
||||
== Description ==
|
||||
|
||||
> How could using fonts via Google's service possibly run afoul of GDPR? The fact of the matter is that, when a font is requested by the user's browser, their IP is logged by Google and used for analytics.
|
||||
> — Lifehacker
|
||||
|
||||
Leverage Browser Cache, Minimize DNS requests, reduce Cumulative Layout Shift and serve your Google Fonts in a 100% GDPR compliant way with OMGF!
|
||||
|
||||
OMGF is written with performance and user-friendliness in mind. It uses the Google Fonts Helper API to automatically cache the fonts your theme and plugins use to **minimize DNS requests** and speed up your WordPress website.
|
||||
|
||||
= How Does It Work? =
|
||||
|
||||
After installing the plugin, choose your Optimization Mode: Manual (default) or Automatic (only available in Pro).
|
||||
|
||||
When *Manual* is selected, you can simply configure OMGF to work in the way you want, and run its detection mechanism on an address of your choosing. Tweak the stylesheet(s) as you wish and these will be used throughout your site.
|
||||
|
||||
In *Automatic* (Pro) Mode, OMGF runs silently in the background and captures any requests made to fonts.googleapis.com or fonts.gstatic.com. When a webpage is first loaded, it reroutes these requests to its own Download API and copies the fonts over to your server. Then it generates a stylesheet for your fonts including SVG, EOT, TTF, WOFF and WOFF2 formats to guarantee maximum cross browser compatibility!
|
||||
|
||||
When the fonts are downloaded and the stylesheet is generated, it rewrites every URL (pointing to fonts.googleapis.com or fonts.gstatic.com) to the locally hosted stylesheet and/or font.
|
||||
|
||||
Please keep in mind that, although I try to make the configuration of this plugin as easy as possible, the concept of locally hosting a file or optimizing Google Fonts for *Pagespeed Insights* or *GT Metrix* has proven to be confusing for some people. If you're not sure of what your doing, please consult a SEO expert or Webdeveloper to help you with the configuration of this plugin or [hire me to do it for you](https://ffw.press/wordpress/omgf-expert-configuration/).
|
||||
|
||||
= Features =
|
||||
- Automatically replace registered/enqueued Google Fonts in wp_head() with local copies,
|
||||
- Automatically remove registered/enqueued Google Fonts from wp_head(),
|
||||
- Manage Optimized Google Fonts,
|
||||
- Preload above the fold fonts,
|
||||
- Don't load certain fonts or entire stylesheets.
|
||||
- Leverage the font-display (swap) option.
|
||||
|
||||
= Additional Features in OMGF Pro =
|
||||
|
||||
Everything in the free version, plus:
|
||||
|
||||
- Specify a Fallback Font Stack for every Google Font, to reduce Cumulative Layout Shift,
|
||||
- Automatically remove/replace all Google Fonts throughout the entire document/page,
|
||||
- Also supports WebFont Loader (webfont.js), Early Access Google Fonts and requests in stylesheets using @import and @font-face statements.
|
||||
- Automatically generate different stylesheets for pages with different Google Fonts configurations.
|
||||
- Material Icons support.
|
||||
- Combine all Google Fonts stylesheets (requested by your theme and/or plugins) into one file,
|
||||
- Deduplicate Google Fonts stylesheets,
|
||||
- Rewrite stylesheets added by other plugins and/or themes to include the configured font-display (e.g. swap) option, this will remove *the ensure text remains visible during webfont load* optimization suggestion from Google PageSpeed Insights.
|
||||
- Define file types to include in stylesheet (WOFF, WOFF2, EOT, TTF, SVG),
|
||||
- Reduce loading time and page size, by forcing a certain subset(s) to be used for all Google Fonts requests,
|
||||
- Remove Resource Hints (preload, preconnect, dns-prefetch) pointing to fonts.googleapis.com or fonts.gstatic.com,
|
||||
- Modify `src` attribute for fonts in stylesheet using the Fonts Source URL option to fully integrate with your configuration,
|
||||
- Use this to serve fonts and the stylesheets from your CDN, or
|
||||
- To serve fonts from an alternative path (e.g. when you're using Security through Obscurity plugins like WP Hide, etc.), or
|
||||
- Anything you like!
|
||||
- Proper handling for AMP pages (Fallback to or remove Google Fonts).
|
||||
|
||||
*[Purchase OMGF Pro](https://ffw.press/wordpress/omgf-pro/) | [Documentation](https://docs.ffw.press/category/4-omgf-pro/) | [Tested Plugins & Themes](https://docs.ffw.press/article/40-list-of-compatible-themes-and-plugins-omgf-pro)*
|
||||
|
||||
== Installation ==
|
||||
|
||||
1. Upload the plugin files to the `/wp-content/plugins/host-webfonts-local` directory, or install the plugin through the WordPress plugins screen directly.
|
||||
2. Activate the plugin through the 'Plugins' screen in WordPress
|
||||
3. Use the Settings -> Optimize Google Fonts screen to configure the plugin
|
||||
|
||||
For a more comprehensive guide on configuring OMGF, check out the [user manual](https://docs.ffw.press/category/4-omgf-pro/)
|
||||
|
||||
== Frequently Asked Questions ==
|
||||
|
||||
For the FAQ, [click here](https://docs.ffw.press/category/76-omgf-pro---faq).
|
||||
|
||||
== Screenshots ==
|
||||
|
||||
1. OMGF's Optimize Fonts screen. These settings affect the downloaded files and generated stylesheet(s).
|
||||
2. After you've saved your changes, the Manage Optimized Google Fonts overview will show a list of detected fonts and will allowing you to easily unload and preload fonts.
|
||||
3. Tweak how OMGF's detection mechanism will work and how it'll treat detected fonts.
|
||||
4. Advanced Settings. Change these to make OMGF work with your configuration (if needed). The default settings will suffice for most configurations.
|
||||
|
||||
== Changelog ==
|
||||
|
||||
= 4.5.13 | January 4th, 2022 =
|
||||
* Sec: Properly check permissions when Download API is accessed.
|
||||
|
||||
= 4.5.12 | November 27th, 2021 =
|
||||
* Sec: Prevent path traversal when cache directory setting is changed. (Thanks, @jsgm!)
|
||||
|
||||
= 4.5.11 | November 17th, 2021 =
|
||||
* Doc: Updated links to fancy new documentation hub: docs.ffw.press
|
||||
* Dev: Added $font_family to omgf_alternate_api_url filter.
|
||||
* Dev: Added filter to detect_registered_stylesheets().
|
||||
* Fix: disable preload/unload when opposite checkbox is checked.
|
||||
* Fix: Updated RSS feed URL and properly encode retrieved XML to prevent parse error simplexml_load_string().
|
||||
* Promo: Added force font-display promo material.
|
||||
|
||||
= 4.5.10 | October 18th, 2021 =
|
||||
* Enhancement: API now cleans up excessive spacing and + symbols in requests before fetching fonts. This comes in handy when e.g. @import statements in CSS stylesheets are auto-formatted by IDEs.
|
||||
* Fix: API would crash when Google Fonts request turned up empty.
|
||||
* Fix: Added proper error handling for when downloading fonts failed.
|
||||
* Doc: Added link to Troubleshooting Guide to Help tab.
|
||||
|
||||
= 4.5.9 | October 5th, 2021 =
|
||||
* Fix: content_url() should always be encoded, also if file already exists.
|
||||
* Enhancement: If stylesheet is already generated, stop execution to decrease API request time.
|
||||
|
||||
= 4.5.8 =
|
||||
* Fix: use array_merge() to prevent unsupported operand types error.
|
||||
|
||||
= 4.5.7 | September 29th, 2021 =
|
||||
* Enhancement: significantly reduced code running frontend.
|
||||
* Fix: internal requests to OMGF's Download API are no longer treated as 'remote'.
|
||||
* Fix: stylesheets are no longer skipped in some situations by the temp storage layer, before writing them to the database.
|
||||
* Fix: using the mass actions (e.g. unload all, unload italics) no longer affect font families with the same name in a stylesheet with a different handle.
|
||||
* Fix: Italic fonts are now properly detected by the API when CSS2 (variable fonts) API is used by themes and/or plugins.
|
||||
* Fix: Added my own self-managed fallback API mirror to prevent more Google Fonts API downtime.
|
||||
* Enhancement: reduced code in Download API by ~20%.
|
||||
* Dev: add-ons for OMGF can now use the show_loader() method.
|
||||
* Several UX and performance tweaks.
|
||||
|
||||
= 4.5.6 =
|
||||
* Fix: Added Fallback API URL for when Google Fonts Helper is down.
|
||||
* Enhancement: Added extra error handling in Manual Optimization Mode.
|
||||
* Fix: API requests made in Manual Optimization Mode are no longer forced to SSL. It now uses the protocol configured in Settings > General > WordPress URL.
|
||||
* Fix: Stylesheet handles containing spaces would prevent Optimize Google Fonts screen from rendering properly.
|
||||
* Several refactors and code optimizations.
|
||||
|
||||
= 4.5.5 =
|
||||
* Fix: Prevent collision with other plugins when authenticating AJAX-calls.
|
||||
|
||||
= 4.5.4 | August 18th, 2021 =
|
||||
* Security: Access to the Download API now requires a valid nonce to prevent CSRF.
|
||||
* Security: Added authentication to Empty Cache Directory AJAX-call.
|
||||
|
||||
= 4.5.3 | August 17th, 2021 =
|
||||
* Fix: "Too few arguments to function OmgfPro_Frontend_AutoReplace::passthru_handle()" would occur if OMGF Pro was updated to v2.5.1 before OMGF was updated to v4.5.2.
|
||||
* Security: Added checks to prevent path traversal and CSRF in Empty Cache Directory AJAX call.
|
||||
|
||||
= 4.5.2 | August 16th, 2021 =
|
||||
* Pro Feature: Added promo material for @font-face detection in local stylesheets.
|
||||
* Fix: Fixed several warnings and notices.
|
||||
|
||||
= 4.5.1 | August 2nd, 2021 =
|
||||
* Enhancement: Added post update notice to inform user of the plugin's database changes. The current notice you were viewed was simply, because the current DB version wasn't logged yet on your system. So if you're reading this: Ha! Made you look! ;)
|
||||
* Pro Feature: Added promo material for Fallback Font Stack (Pro) feature.
|
||||
* Enhancement: moved Stylesheet Generator to its own backend API.
|
||||
* Enhancement: moved Font Downloader to its own backend API.
|
||||
* Enhancement: Updated description of Optimization Modes.
|
||||
* Fix: Fixed glitch in footer news ticker.
|
||||
* Enhancement: Added several filter and action hooks to allow a more seamless integration with OMGF Pro and OMGF Additional Fonts.
|
||||
* Several code and performance optimizations.
|
||||
|
||||
= 4.5.0 | July 28th, 2021 =
|
||||
* [Removed] WOFF2 only option is superseded by Include File Types option, only available in OMGF Pro.
|
||||
* [Removed] CDN URL, Cache URI and Relative URL options are combined into Fonts Source URL option, only available in OMGF Pro.
|
||||
* [Removed] Optimization Mode > Automatic is only available in OMGF Pro.
|
||||
* Tested with WordPress 5.8
|
||||
* Several code optimizations.
|
||||
|
||||
= 4.4.4 =
|
||||
* Fixed logo for Safari compatibility.
|
||||
* Added updater notices for future important updates.
|
||||
|
||||
= 4.4.3 =
|
||||
* Fixed a few warnings/notices.
|
||||
* Re-worded some options and option descriptions.
|
||||
|
||||
= 4.4.2 =
|
||||
* Upped static version of Admin CSS files.
|
||||
|
||||
= 4.4.1 | April 23rd, 2021 =
|
||||
* Fixed footer logo (load from local source instead of external URL).
|
||||
* Added tooltip for preload option.
|
||||
* Added link to OMGF Additional Fonts under Optimize tab.
|
||||
|
||||
= 4.4.0 | April 10th, 2021 =
|
||||
* Moved sidebar to its own 'Help' tab to clean up the interface.
|
||||
* Manage Optimize Fonts panel is now shown inline with other options (and has its own label).
|
||||
* Each stylesheet's handle is now more prominently visible and the font family is more readable.
|
||||
* Added mass actions to each font family for easier management of each stylesheet.
|
||||
* Took a different approach to deal with SSL/Non-SSL for local Dev environments.
|
||||
* Performance improvements to manual detection mode (decreased risk of timeouts!)
|
||||
* Overall UX tweaks and performance improvements.
|
||||
|
||||
= 4.3.2 | April 5th, 2021 =
|
||||
* Fixed MIME type (`X-Content-Type-Options: nosniff`) related errors when using Download API.
|
||||
* When site is not using SSL, sslverify is disabled when contacting the Download API.
|
||||
* When OMGF Pro is running in Automatic Mode, only preloads for the currently used stylesheet are loaded.
|
||||
|
||||
= 4.3.1 | March 29th, 2021 =
|
||||
* Added Mukta (FKA Ek Mukta) to list of renamed Google Fonts.
|
||||
|
||||
= 4.3.0 | March 17th, 2021 =
|
||||
* [FEAT] Renamed fonts will now be captured using their new name (e.g. Mulish), but remain in the stylesheet with their old name (e.g. Muli) to prevent manual changes to the stylesheet after optimization.
|
||||
* [FEAT] Added Load WOFF2 Only option.
|
||||
* Small code optimizations in Download API's code.
|
||||
|
||||
= 4.2.8 | March 12th, 2021 =
|
||||
* [FIX] Strings with a + instead of a space would returned errors in the API.
|
||||
|
||||
= 4.2.7 | March 10th, 2021 =
|
||||
* Addding ?nomgf=1 to any URL will now temporarily bypass fonts optimization, which allows for easier debugging.
|
||||
|
||||
= 4.2.6 | March 6th, 2021 =
|
||||
* Tested with WP 5.7
|
||||
* [FIX] All fonts would be loaded, when all fonts of one font-family were checked for unloading.
|
||||
* [FIX] Fixed some notices and warnings.
|
||||
* Added compatibility for OMGF Pro's Early Access compatibility.
|
||||
* OMGF's admin JS is now only loaded on OMGF's settings screens.
|
||||
* [FIX] Fixed bug where Italic 400 fonts couldn't be unloaded.
|
||||
|
||||
= 4.2.5 | January 27th, 2021 =
|
||||
* Improved compatibility with WordPress subdirectory installs.
|
||||
* Implemented some actions/filters needed for upcoming release of OMGF Additional Fonts.
|
||||
* Fixed duplicate preload ID's issue.
|
||||
* Fixed some notices/warnings.
|
||||
* Minor UX improvements.
|
||||
|
||||
= 4.2.4 | December 8th, 2020 =
|
||||
* Cache keys are now fixed values instead of dynamically generated. This fixes the bug where preloads wouldn't load properly when combined with unloaded fonts of the same stylesheet.
|
||||
* **IMPORTANT**: To fix any bugs with preloads/unloads, emptying the cache directory is required.
|
||||
* Cleaned up the sidebar and added a notification to reassure people that no features were moved from Free to Pro after upgrading to v4.
|
||||
* Advanced Processing can now be disabled even when OMGF Pro is active. Before it was always on (accidentally).
|
||||
* When preload is enabled for a font style, its associated unload checkbox is disabled and vice versa.
|
||||
* Minor fixes, increased usability and optimizations.
|
||||
|
||||
= 4.2.3 =
|
||||
* Fixed invalid preload header,
|
||||
* Fixed warning: `array_keys() expects parameter 1 to be array, null given` when multiple stylesheets are loaded, but preloads are only enabled for one of them.
|
||||
|
||||
= 4.2.2 =
|
||||
* Small fix for themes/page builders which requests Google Fonts with protocol relative URI i.e. '//fonts.googleapis.com' instead of 'https://fonts.googleapis.com'.
|
||||
* Tested with Elementor. Works.
|
||||
|
||||
= 4.2.1 =
|
||||
* OMGF now checks secure (https://) and non-secure (http://) requests to Google Fonts, because apparently some themes still do that, even though it's 2020, but whatever.
|
||||
* Tested with Divi and Bridge Theme. Works.
|
||||
|
||||
= 4.2.0 | The What-4.0-should've-been Edition | October 7th, 2020 =
|
||||
* **IMPORTANT NOTICE: If you're upgrading from v4.x.x it's required to Empty your Cache Directory. Otherwise the Optimized Google Fonts Overview will not work.**
|
||||
* Added CSS2 (Variable Fonts) compatiblity,
|
||||
* No more spaces in filenames of downloaded fonts,
|
||||
* Added Optimize Fonts tab, which resembles the 'Generate Stylesheet' tab from v3, and features,
|
||||
* Optimization Mode: Manual or Automatic,
|
||||
* If Manual is selected, the URL can be specified which should be scanned for Google Fonts,
|
||||
* A complete overview of all detected fonts, grouped by stylesheet,
|
||||
* Options to preload or unload for each font.
|
||||
* Move settings to more sensible places and re-grouped them in 3 groups:
|
||||
* Optimize Fonts,
|
||||
* Detection Settings,
|
||||
* Advanced Settings.
|
||||
* OMGF will now throw a notice when a settings is changed which requires the cache to be flushed.
|
||||
* Several tweaks and fixes in OMGF's Auto Detection mechanism and Fonts Download API.
|
||||
* Fixed issue where OMGF wouldn't detect fonts in weight 400 (and 400 italic).
|
||||
* Major UX improvements,
|
||||
* Pros and Cons of each Optimization Mode are outlined upon selection,
|
||||
* Show loaded while actions are taking place,
|
||||
* Cleaned up sidebar and added a clear overview of available documentation.
|
||||
* Several tweaks and optimizations in overall performance.
|
||||
|
||||
= 4.1.3 =
|
||||
* Fixed bug which would continuously show 'No fonts founds' notice in admin, among others.
|
||||
* Increased compatibility with caching plugins, which would cause static pages to be served and block OMGF from pointing requests to its Download API.
|
||||
* Added some notices (which disappear ;-)) for manual optimization process in admin area, making it clear when optimization is finished.
|
||||
|
||||
= 4.1.2 =
|
||||
* Fixed syntax error (unexpected ')' on line 147).
|
||||
|
||||
= 4.1.1 =
|
||||
* Use transients instead of options.
|
||||
* Fixed some minor notices and warnings.
|
||||
|
||||
= 4.1.0 | October 1st, 2020 =
|
||||
* Added some on-boarding to ease the use of the new interface.
|
||||
* OMGF will now show a notice in the admin area, if the optimization never ran, to increase UX.
|
||||
* Added a loader when any of the following actions are triggered:
|
||||
* Empty Cache Directory
|
||||
* Start Optimization
|
||||
* Minor tweaks and optimizations.
|
||||
|
||||
= 4.0.2 =
|
||||
* Fixed bug where OMGF would trigger too late for the requests to fonts.googleapis.com to be captured.
|
||||
|
||||
= 4.0.1 =
|
||||
* The tiniest bugfix ever: one space too much in a str_replace() caused Font Names with spaces (e.g. Roboto Condensed, or Open Sans) to not be captured correctly.
|
||||
|
||||
= 4.0.0 | September 30th, 2020 =
|
||||
* OMGF now runs fully automatic to replace/remove Google Fonts from your pages using OMGF's new Download API. No initial configuration required!
|
||||
* This means that if you use different fonts on different pages, all of them will be cached and served locally.
|
||||
* HUGE performance increase in OMGF's automatic replacing/removing methods.
|
||||
* Major overhaul of Settings Page:
|
||||
* Removed Extensions Tab
|
||||
* Some settings were moved to a new tab: Basic Settings.
|
||||
* Improved Welcome and Documentation tab.
|
||||
* Clarified option descriptions.
|
||||
* Removed 'Generate Stylesheet' tab, which'll be released in a separate add-on plugin soon.
|
||||
* Removed 'Use Web Font Loader?' option, because it causes Cumulative Layout Shift and will not work with OMGF's new Auto Replace feature.
|
||||
* Removed 'Remove Version Parameter' option, because it has become obsolete. The new detection method uses the initial script's version, if set.
|
||||
* Font Preloading is temporarily removed and will be re-introduced (in a different form, along with new features) in a later release.
|
||||
|
||||
[ Changelog shortened ... ]
|
||||
|
||||
= 3.0.0 =
|
||||
*OMGF - CORONA EDITION*
|
||||
* Moved Welcome-panel to the side.
|
||||
* wp_remote_get() is now used instead of cURL.
|
||||
* Complete code overhaul to increase performance and UX.
|
||||
* Notices and errors are now more explanatory and dismissable.
|
||||
* Fixed several bugs.
|
||||
* OMGF now uses wp_options table, instead of own tables.
|
||||
* Old tables are removed and data is migrated.
|
||||
* Auto detect now works better than ever.
|
||||
* Search now works bug free.
|
||||
* WordPress' default admin fonts no longer show up as results.
|
||||
|
||||
[ Changelog shortened ... ]
|
||||
|
||||
= 2.0.0 =
|
||||
Added Typekit's Web Font Loader to allow loading fonts asynchronously.
|
||||
|
||||
[ Changelog shortened... ]
|
||||
|
||||
= 1.0 =
|
||||
First release! No changes so far!
|
||||
Reference in New Issue
Block a user