Compare commits
11 Commits
4869f1ef2f
...
v4.2.1
Author | SHA1 | Date | |
---|---|---|---|
d1eece5875 | |||
9d6c90e9cd | |||
6dafa7f1ee | |||
40a3b93d4b | |||
18820c7191 | |||
bb741539f6 | |||
80fb6cd452 | |||
69322d64f3 | |||
ba736ef661 | |||
b5112ab12e | |||
bf2892ab29 |
52
assets/calendar.css
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
.bdp_cal_outer {
|
||||||
|
background-color: #ffffff;
|
||||||
|
width: 85%;
|
||||||
|
margin: auto;
|
||||||
|
padding: 10px;
|
||||||
|
border-style: solid; border-color: #d0d0d0; border-radius: 10px; padding: 15px; border-width: 1px;
|
||||||
|
box-shadow: 2px 2px 5px #c0c0c0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bdp_cal_inner {
|
||||||
|
border-style: solid; border-color: #d0d0d0; border-radius: 10px; padding: 15px; border-width: 1px;
|
||||||
|
box-shadow: 2px 2px 5px #c0c0c0;
|
||||||
|
width: 80%;
|
||||||
|
margin: 0 auto 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bdp_cal_inner legend {
|
||||||
|
background-color: #ffcb04;
|
||||||
|
background: linear-gradient(#ffffff 5%, #ffcb04);
|
||||||
|
color: #3163bd;
|
||||||
|
width: 150px;
|
||||||
|
padding: 5px 0 5px 25px;
|
||||||
|
font-weight: bold;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px;
|
||||||
|
border-color: #d0d0d0;
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 2px 2px 5px #c0c0c0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bdp_cal_inner table {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bdp_cal_inner table tr td:first-child {
|
||||||
|
width: 100px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bdp_cal_inner table tr td:nth-child(2) {
|
||||||
|
padding:5px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bdp_cal_inner table tr td:last-child {
|
||||||
|
width: 100%;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.long_text {
|
||||||
|
width: 80%;
|
||||||
|
}
|
36
assets/dashboard.style.css.tpl
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<style>
|
||||||
|
/* Dein benutzerdefiniertes CSS hier */
|
||||||
|
body.login {
|
||||||
|
background-color: #efefef;
|
||||||
|
background-image: url(%%BDP_LV_PLUGIN_URL%%/holz.jpg);
|
||||||
|
}
|
||||||
|
|
||||||
|
#login {
|
||||||
|
width: 800px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.login h1 {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#loginform {
|
||||||
|
width: 750px;
|
||||||
|
margin: auto;
|
||||||
|
background-color: #ffcb04;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
box-shadow: 2px 2px 5px #000000;
|
||||||
|
border-radius: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
#loginform #wp-submit {
|
||||||
|
background-color: #3163bd !important;
|
||||||
|
color: #ffcb04;
|
||||||
|
border-radius: 10px;
|
||||||
|
font-size: 12pt;
|
||||||
|
font-weight: bold;
|
||||||
|
box-shadow: 5px 5px 5px #a0a0a0;
|
||||||
|
}
|
||||||
|
/* Weitere benutzerdefinierte Stile hier */
|
||||||
|
</style>
|
43
assets/password.js
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
jQuery(document).ready(function($) {
|
||||||
|
$( "<button class='button button-primary' disabled id='password_too_short'>" +
|
||||||
|
php_vars.password_too_short_text + "</button>" ).insertBefore( ".submit" );
|
||||||
|
|
||||||
|
$("#password_too_short").css('display', 'none');
|
||||||
|
|
||||||
|
$(document).on('DOMSubtreeModified', '#pass-strength-result', function() {
|
||||||
|
var strengthMeter = $(this).attr('class');
|
||||||
|
var allowedStrengths = php_vars.allowed_strengths;
|
||||||
|
|
||||||
|
$( "[name='pw_weak']" ).css('visibility', 'hidden');
|
||||||
|
$( '.pw-weak' ).css('visibility', 'hidden');
|
||||||
|
$( '#pw-weak-text-label' ).css('visibility', 'hidden');
|
||||||
|
|
||||||
|
if (strengthMeter !== '') {
|
||||||
|
if (allowedStrengths.includes(strengthMeter)) {
|
||||||
|
$("[name='pw_weak']").prop("checked", true);
|
||||||
|
$("[name='submit']").css('display', 'inline');
|
||||||
|
$('#createusersub').css('display', 'inline');
|
||||||
|
$('submit').onclick = function() {
|
||||||
|
$('your-profile').submit();
|
||||||
|
};
|
||||||
|
$("#createusersub").onclick = function() {
|
||||||
|
$('createuser').submit();
|
||||||
|
};
|
||||||
|
|
||||||
|
$("#password_too_short").css('display', 'none');
|
||||||
|
} else {
|
||||||
|
$("#createusersub").css('display', 'none');
|
||||||
|
$("[name='submit']").prop("disabled", true);
|
||||||
|
$("[name='pw_weak']").prop("checked", false);
|
||||||
|
$("[name='submit']").css('display', 'none');
|
||||||
|
$('submit').onclick = function() {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
$("#createusersub").onclick = function() {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
$("#password_too_short").css('display', 'inline');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
65
assets/security.css
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
.bdp_security_outer {
|
||||||
|
background-color: #ffffff;
|
||||||
|
width: 85%;
|
||||||
|
margin: auto;
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.bdp_security_inner {
|
||||||
|
|
||||||
|
width: 80%;
|
||||||
|
margin: 0 auto 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bdp_security_inner legend {
|
||||||
|
background-color: #ffcb04;
|
||||||
|
background: linear-gradient(#ffffff 5%, #ffcb04);
|
||||||
|
color: #3163bd;
|
||||||
|
width: 150px;
|
||||||
|
padding: 5px 0 5px 25px;
|
||||||
|
font-weight: bold;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px;
|
||||||
|
border-color: #d0d0d0;
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 2px 2px 5px #c0c0c0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bdp_security_inner table {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bdp_security_inner table tr td:first-child {
|
||||||
|
width: 75px;
|
||||||
|
vertical-align: top;
|
||||||
|
font-weight: bold;
|
||||||
|
padding-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bdp_security_inner table tr td:nth-child(2) {
|
||||||
|
vertical-align: top;
|
||||||
|
padding:5px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bdp_security_inner table tr td:last-child {
|
||||||
|
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.long_text {
|
||||||
|
width: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.protect-login-no-blocked-ips
|
||||||
|
{
|
||||||
|
padding: 5px 10px;
|
||||||
|
width: 90%;
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: #00a32a;
|
||||||
|
border-width: 1px;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 12pt;
|
||||||
|
}
|
353
assets/wordpress-bdp.css
Normal file
@ -0,0 +1,353 @@
|
|||||||
|
body {
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Admin Menu */
|
||||||
|
#adminmenuback,
|
||||||
|
#adminmenuwrap,
|
||||||
|
#adminmenu {
|
||||||
|
margin-top: 12px;
|
||||||
|
background: #f0f0f0;
|
||||||
|
width: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#adminmenu {
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 10px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#adminmenu a {
|
||||||
|
color: #1d4899 !important;
|
||||||
|
font-weight: bold !important;
|
||||||
|
margin-left: 30px !important;
|
||||||
|
border-color: #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#wpbody {
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
position: relative;
|
||||||
|
padding-left: 150px;
|
||||||
|
|
||||||
|
padding-top: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#wpfooter, #wpwrap
|
||||||
|
{
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#wpfooter {
|
||||||
|
padding-left: 150px;
|
||||||
|
}
|
||||||
|
#wpbody-content {
|
||||||
|
background-color: #ffffff;
|
||||||
|
width: 95%;
|
||||||
|
padding-left: 50px;
|
||||||
|
box-shadow: 10px 10px 10px #c0c0c0;
|
||||||
|
border-radius: 10px;
|
||||||
|
border-width: 1px;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: #c0c0c0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#adminmenu div.wp-menu-image:before {
|
||||||
|
color: rgba(29, 72, 153, 0.75);
|
||||||
|
}
|
||||||
|
|
||||||
|
#adminmenu a:hover,
|
||||||
|
#adminmenu li.menu-top:hover,
|
||||||
|
#adminmenu li.opensub > a.menu-top,
|
||||||
|
#adminmenu li > a.menu-top:focus {
|
||||||
|
color: #1d4899;
|
||||||
|
border-color: #f0f0f0;
|
||||||
|
|
||||||
|
font-weight: bold;
|
||||||
|
background: linear-gradient(to right, #efefef, rgba(255, 203, 4, 0.45));
|
||||||
|
border-radius: 10px;
|
||||||
|
border-width: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#adminmenu li.menu-top:hover div.wp-menu-image:before,
|
||||||
|
#adminmenu li.opensub > a.menu-top div.wp-menu-image:before {
|
||||||
|
color: #1d4899;
|
||||||
|
font-weight: bold;
|
||||||
|
background: linear-gradient(to right, #efefef, rgba(255, 203, 4, 0.45));
|
||||||
|
border-radius: 10px;
|
||||||
|
border-width: 0;
|
||||||
|
border-color: #f0f0f0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Active tabs use a bottom border color that matches the page background color. */
|
||||||
|
.about-wrap .nav-tab-active,
|
||||||
|
.nav-tab-active,
|
||||||
|
.nav-tab-active:hover {
|
||||||
|
border-style: none;
|
||||||
|
background-color: #fff;
|
||||||
|
border-bottom-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Admin Menu: submenu */
|
||||||
|
#adminmenu .wp-submenu,
|
||||||
|
#adminmenu .wp-has-current-submenu .wp-submenu,
|
||||||
|
#adminmenu .wp-has-current-submenu.opensub .wp-submenu,
|
||||||
|
.folded #adminmenu .wp-has-current-submenu .wp-submenu,
|
||||||
|
#adminmenu a.wp-has-current-submenu:focus + .wp-submenu {
|
||||||
|
background: #ffffff;
|
||||||
|
width: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#adminmenu li.wp-has-submenu.wp-not-current-submenu.opensub:hover:after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#adminmenu .wp-submenu .wp-submenu-head {
|
||||||
|
color: #ccdbe0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#adminmenu .wp-submenu a,
|
||||||
|
#adminmenu .wp-has-current-submenu .wp-submenu a,
|
||||||
|
.folded #adminmenu .wp-has-current-submenu .wp-submenu a,
|
||||||
|
#adminmenu a.wp-has-current-submenu:focus + .wp-submenu a,
|
||||||
|
#adminmenu .wp-has-current-submenu.opensub .wp-submenu a {
|
||||||
|
color: #ccdbe0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#adminmenu .wp-submenu a:focus, #adminmenu .wp-submenu a:hover,
|
||||||
|
#adminmenu .wp-has-current-submenu .wp-submenu a:focus,
|
||||||
|
#adminmenu .wp-has-current-submenu .wp-submenu a:hover,
|
||||||
|
.folded #adminmenu .wp-has-current-submenu .wp-submenu a:focus,
|
||||||
|
.folded #adminmenu .wp-has-current-submenu .wp-submenu a:hover,
|
||||||
|
#adminmenu a.wp-has-current-submenu:focus + .wp-submenu a:focus,
|
||||||
|
#adminmenu a.wp-has-current-submenu:focus + .wp-submenu a:hover,
|
||||||
|
#adminmenu .wp-has-current-submenu.opensub .wp-submenu a:focus,
|
||||||
|
#adminmenu .wp-has-current-submenu.opensub .wp-submenu a:hover {
|
||||||
|
color: #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Admin Menu: current */
|
||||||
|
#adminmenu .wp-submenu li.current a,
|
||||||
|
#adminmenu a.wp-has-current-submenu:focus + .wp-submenu li.current a,
|
||||||
|
#adminmenu .wp-has-current-submenu.opensub .wp-submenu li.current a {
|
||||||
|
color: #f2fcff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#adminmenu .wp-submenu li.current a:hover, #adminmenu .wp-submenu li.current a:focus,
|
||||||
|
#adminmenu a.wp-has-current-submenu:focus + .wp-submenu li.current a:hover,
|
||||||
|
#adminmenu a.wp-has-current-submenu:focus + .wp-submenu li.current a:focus,
|
||||||
|
#adminmenu .wp-has-current-submenu.opensub .wp-submenu li.current a:hover,
|
||||||
|
#adminmenu .wp-has-current-submenu.opensub .wp-submenu li.current a:focus {
|
||||||
|
color: #e0e0e0;
|
||||||
|
border-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul#adminmenu a.wp-has-current-submenu:after,
|
||||||
|
ul#adminmenu > li.current > a.current:after {
|
||||||
|
border-right-color: #fff;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#adminmenu li.current a.menu-top,
|
||||||
|
#adminmenu li.wp-has-current-submenu a.wp-has-current-submenu,
|
||||||
|
#adminmenu li.wp-has-current-submenu .wp-submenu .wp-submenu-head,
|
||||||
|
.folded #adminmenu li.current.menu-top {
|
||||||
|
color: #000000;
|
||||||
|
background: linear-gradient(to right, #efefef, rgba(255, 203, 4, 0.45));
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#adminmenu li.wp-has-current-submenu div.wp-menu-image:before,
|
||||||
|
#adminmenu a.current:hover div.wp-menu-image:before,
|
||||||
|
#adminmenu li.wp-has-current-submenu a:focus div.wp-menu-image:before,
|
||||||
|
#adminmenu li.wp-has-current-submenu.opensub div.wp-menu-image:before,
|
||||||
|
#adminmenu li:hover div.wp-menu-image:before,
|
||||||
|
#adminmenu li a:focus div.wp-menu-image:before,
|
||||||
|
#adminmenu li.opensub div.wp-menu-image:before,
|
||||||
|
.ie8 #adminmenu li.opensub div.wp-menu-image:before {
|
||||||
|
color: #f2fcff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-menu-open .wp-submenu {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.wp-menu-open .wp-submenu li {
|
||||||
|
padding-left: 30px !important;
|
||||||
|
color: #1d4899 !important;
|
||||||
|
font-weight: bold;
|
||||||
|
border-color: #f0f0f0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-submenu {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Admin Menu: bubble */
|
||||||
|
#adminmenu .awaiting-mod,
|
||||||
|
#adminmenu .update-plugins {
|
||||||
|
color: #f2fcff;
|
||||||
|
background: #aa9d88;
|
||||||
|
}
|
||||||
|
|
||||||
|
#adminmenu li.current a .awaiting-mod,
|
||||||
|
#adminmenu li a.wp-has-current-submenu .update-plugins,
|
||||||
|
#adminmenu li:hover a .awaiting-mod,
|
||||||
|
#adminmenu li.menu-top:hover > a .update-plugins {
|
||||||
|
#color: #f2fcff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Admin Menu: collapse button */
|
||||||
|
#collapse-button {
|
||||||
|
display: none;
|
||||||
|
color: #1d4899;
|
||||||
|
font-weight: bold;
|
||||||
|
border-radius: 10px;
|
||||||
|
border-width: 0;
|
||||||
|
border-color: #f0f0f0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#collapse-button:hover,
|
||||||
|
#collapse-button:focus {
|
||||||
|
color: rgba(255, 203, 4, 0.45);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Admin Bar */
|
||||||
|
#wpadminbar {
|
||||||
|
color: #f2fcff;
|
||||||
|
background: rgba(29, 72, 153, 0.7);
|
||||||
|
}
|
||||||
|
|
||||||
|
#wpadminbar .ab-item,
|
||||||
|
#wpadminbar a.ab-item,
|
||||||
|
#wpadminbar > #wp-toolbar span.ab-label,
|
||||||
|
#wpadminbar > #wp-toolbar span.noticon {
|
||||||
|
color: #f2fcff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#wpadminbar .ab-icon,
|
||||||
|
#wpadminbar .ab-icon:before,
|
||||||
|
#wpadminbar .ab-item:before,
|
||||||
|
#wpadminbar .ab-item:after {
|
||||||
|
color: #f1f3f3;
|
||||||
|
}
|
||||||
|
|
||||||
|
#wpadminbar:not(.mobile) .ab-top-menu > li:hover > .ab-item,
|
||||||
|
#wpadminbar:not(.mobile) .ab-top-menu > li > .ab-item:focus,
|
||||||
|
#wpadminbar.nojq .quicklinks .ab-top-menu > li > .ab-item:focus,
|
||||||
|
#wpadminbar.nojs .ab-top-menu > li.menupop:hover > .ab-item,
|
||||||
|
#wpadminbar .ab-top-menu > li.menupop.hover > .ab-item {
|
||||||
|
color: #f2fcff;
|
||||||
|
background: rgba(29, 72, 153, 0.7);
|
||||||
|
}
|
||||||
|
|
||||||
|
#wpadminbar:not(.mobile) > #wp-toolbar li:hover span.ab-label,
|
||||||
|
#wpadminbar:not(.mobile) > #wp-toolbar li.hover span.ab-label,
|
||||||
|
#wpadminbar:not(.mobile) > #wp-toolbar a:focus span.ab-label {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#wpadminbar:not(.mobile) li:hover .ab-icon:before,
|
||||||
|
#wpadminbar:not(.mobile) li:hover .ab-item:before,
|
||||||
|
#wpadminbar:not(.mobile) li:hover .ab-item:after,
|
||||||
|
#wpadminbar:not(.mobile) li:hover #adminbarsearch:before {
|
||||||
|
color: #f2fcff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Admin Bar: submenu */
|
||||||
|
#wpadminbar .menupop .ab-sub-wrapper {
|
||||||
|
background: rgba(29, 72, 153, 0.78);
|
||||||
|
}
|
||||||
|
|
||||||
|
#wpadminbar .quicklinks .menupop ul.ab-sub-secondary,
|
||||||
|
#wpadminbar .quicklinks .menupop ul.ab-sub-secondary .ab-submenu {
|
||||||
|
background: #8f9a9e;
|
||||||
|
}
|
||||||
|
|
||||||
|
#wpadminbar .ab-submenu .ab-item,
|
||||||
|
#wpadminbar .quicklinks .menupop ul li a,
|
||||||
|
#wpadminbar .quicklinks .menupop.hover ul li a,
|
||||||
|
#wpadminbar.nojs .quicklinks .menupop:hover ul li a {
|
||||||
|
color: #ccdbe0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#wpadminbar .quicklinks li .blavatar,
|
||||||
|
#wpadminbar .menupop .menupop > .ab-item:before {
|
||||||
|
color: #f1f3f3;
|
||||||
|
}
|
||||||
|
|
||||||
|
#wpadminbar .quicklinks .menupop ul li a:hover,
|
||||||
|
#wpadminbar .quicklinks .menupop ul li a:focus,
|
||||||
|
#wpadminbar .quicklinks .menupop ul li a:hover strong,
|
||||||
|
#wpadminbar .quicklinks .menupop ul li a:focus strong,
|
||||||
|
#wpadminbar .quicklinks .ab-sub-wrapper .menupop.hover > a,
|
||||||
|
#wpadminbar .quicklinks .menupop.hover ul li a:hover,
|
||||||
|
#wpadminbar .quicklinks .menupop.hover ul li a:focus,
|
||||||
|
#wpadminbar.nojs .quicklinks .menupop:hover ul li a:hover,
|
||||||
|
#wpadminbar.nojs .quicklinks .menupop:hover ul li a:focus,
|
||||||
|
#wpadminbar li:hover .ab-icon:before,
|
||||||
|
#wpadminbar li:hover .ab-item:before,
|
||||||
|
#wpadminbar li a:focus .ab-icon:before,
|
||||||
|
#wpadminbar li .ab-item:focus:before,
|
||||||
|
#wpadminbar li .ab-item:focus .ab-icon:before,
|
||||||
|
#wpadminbar li.hover .ab-icon:before,
|
||||||
|
#wpadminbar li.hover .ab-item:before,
|
||||||
|
#wpadminbar li:hover #adminbarsearch:before,
|
||||||
|
#wpadminbar li #adminbarsearch.adminbar-focused:before {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#wpadminbar .quicklinks li a:hover .blavatar,
|
||||||
|
#wpadminbar .quicklinks li a:focus .blavatar,
|
||||||
|
#wpadminbar .quicklinks .ab-sub-wrapper .menupop.hover > a .blavatar,
|
||||||
|
#wpadminbar .menupop .menupop > .ab-item:hover:before,
|
||||||
|
#wpadminbar.mobile .quicklinks .ab-icon:before,
|
||||||
|
#wpadminbar.mobile .quicklinks .ab-item:before {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#wpadminbar.mobile .quicklinks .hover .ab-icon:before,
|
||||||
|
#wpadminbar.mobile .quicklinks .hover .ab-item:before {
|
||||||
|
color: #f1f3f3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Admin Bar: search */
|
||||||
|
#wpadminbar #adminbarsearch:before {
|
||||||
|
color: #f1f3f3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
background: rgba(29, 72, 153, 0.62) !important;
|
||||||
|
color: #ffffff !important;
|
||||||
|
border-color: #071e4d;
|
||||||
|
box-shadow: 5px 5px 10px #d0d0d0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.bdp_setting_box {
|
||||||
|
width: 100%;
|
||||||
|
background-color: #ffffff;
|
||||||
|
padding: 15px;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px;
|
||||||
|
border-top-width: 0 !important;
|
||||||
|
border-color: #1d94cf;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bdp_setting_box:first-of-type {
|
||||||
|
border-top-width: 1px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bdp_setting_box label {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bdp_setting_box label span {
|
||||||
|
cursor: pointer;
|
||||||
|
width: 10pt;
|
||||||
|
color: #a0a0a0;
|
||||||
|
}
|
62
bdp-kompass.php
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Plugin Name: BdP Kompass
|
||||||
|
* Description: Wordpress-Plugin zur Unterstützung von Stämmen im Bund der Pfadfinderinnen und Pfadfinder e.V. zur optimalen Verwaltung eurer Webseite
|
||||||
|
* Version: 4.2.1
|
||||||
|
* Tags: bdp, utility, helper
|
||||||
|
* Requires at least: 6.0
|
||||||
|
* Requires PHP: 8.2
|
||||||
|
* Author: Thomas Günther
|
||||||
|
* Author URI: https://www.sachsen.pfadfinden.de
|
||||||
|
* Update URI: http://lv-sachsen-main.bdp.mein-verein.online/wordpress/
|
||||||
|
* Text Domain: bdp-kompass
|
||||||
|
*/
|
||||||
|
|
||||||
|
use Bdp\Modules\LimitLoginAttempts\Controllers\OptionsPage as OptionsPageAlias;
|
||||||
|
use Bdp\Modules\Security\Security;
|
||||||
|
use Bdp\Modules\Seo\Seo;
|
||||||
|
|
||||||
|
require_once dirname(__FILE__) . '/includes/setup.php';
|
||||||
|
|
||||||
|
function bdp_plugin_install() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function bdp_plugin_init() {
|
||||||
|
Security::ProhibitBots();
|
||||||
|
Security::SetPageFilters();
|
||||||
|
|
||||||
|
if (null == get_option('kompass_already_installed', null)) {
|
||||||
|
Seo::setup();
|
||||||
|
Calendar::setup();
|
||||||
|
Security::setup();
|
||||||
|
update_option('kompass_already_installed', true);
|
||||||
|
wp_redirect( 'site-health.php?tab=bdp_enhanced_security');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
add_action('admin_menu', function () {
|
||||||
|
new OptionsPageAlias();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function register_custom_theme_directory() {
|
||||||
|
$file = ABSPATH . '/wp-content/plugins/bdp-kompass/buena/' ;
|
||||||
|
|
||||||
|
system('mkdir ' . ABSPATH . 'wp-content/themes/buena/');
|
||||||
|
system('cp -r ' . $file . '* ' . ABSPATH . 'wp-content/themes/buena/');
|
||||||
|
|
||||||
|
switch_theme('buena');
|
||||||
|
}
|
||||||
|
|
||||||
|
function enqueue_custom_password_js() {
|
||||||
|
wp_enqueue_script( 'custom-password-js', BDP_LV_PLUGIN_URL . 'assets/password.js');
|
||||||
|
wp_localize_script( 'custom-password-js', 'php_vars', [
|
||||||
|
'allowed_strengths' => kompass_get_minimal_password_strength(),
|
||||||
|
'password_too_short_text' => 'Dass Passwort entspricht nicht den Anforderungen.'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#add_action( 'after_setup_theme', 'register_custom_theme_directory' );
|
51
icon.svg
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
width="2000px" height="2000px" viewBox="0 0 2000 2000" style="enable-background:new 0 0 2000 2000;" xml:space="preserve">
|
||||||
|
<g>
|
||||||
|
<path style="fill:#1D4899;" d="M0,1000.023C0,447.935,447.769,0,1000.262,0C1552.209,0,2000,447.935,2000,1000.023
|
||||||
|
c0,552.054-447.791,999.977-999.738,999.977C447.769,2000,0,1552.077,0,1000.023"/>
|
||||||
|
<path style="fill:#FFCB04;" d="M1000.214,1797.409l-167.939-206.695c36.529-50.487,56.122-90.156,71.065-144.273
|
||||||
|
c7.235-25.315,13.948-69.101,13.45-78.887h-16.533c-6.215,60.333-39.708,148.484-85.014,204.097c0,0-65.468-78.839-73.225-88.614
|
||||||
|
c12.43-9.288,66.464-77.843,68.552-104.699c0.546-8.743-34.537-6.157-34.537-54.604c0-63.939,46.397-41.211,45.899-78.341
|
||||||
|
c-0.546-30.926-25.761-54.142-58.756-54.142c-30.979,0-43.835,34.544-42.791,56.229c1.542,37.082,1.044,51.033,1.044,55.113
|
||||||
|
c0,28.376-12.904,81.948-52.066,81.948c-17.506,0-45.852-46.858-257.697-304.064l248.921-297.99
|
||||||
|
c154.11,60.855,243.251,273.221,243.251,423.248v66.467h13.948c2.562-26.312,0.498-102.564,0.498-102.564
|
||||||
|
c-6.713-171.653-93.767-346.402-230.348-421.647l312.277-380.412l311.779,380.412c-132.952,80.382-227.762,264.407-226.742,433.462
|
||||||
|
c0,0-3.605,56.692,1.565,90.75h14.446c-4.128-37.629-1.044-78.887-1.044-78.887c2.538-155.129,76.237-343.271,242.753-411.327
|
||||||
|
l245.292,298.489c-211.799,256.661-243.75,304.064-261.326,304.064c-39.115,0-48.438-53.572-48.438-81.402
|
||||||
|
c0-4.626-0.498-18.577,1.044-55.659c1.044-21.14-11.86-56.229-42.744-56.229c-32.995,0-58.257,23.216-58.755,54.64
|
||||||
|
c-0.546,37.083,45.875,14.401,45.875,77.843c0,48.945-35.059,45.861-34.561,54.604c2.04,26.856,56.17,95.411,68.6,104.699
|
||||||
|
c-7.307,9.775-74.245,88.614-74.245,88.614c-43.289-58.233-70.639-136.575-77.85-204.097h-14.92c0,0,3.083,38.138,10.318,63.903
|
||||||
|
c14.397,54.153,29.888,99.967,66.464,159.257"/>
|
||||||
|
<path style="fill:#1D4899;" d="M832.772,1294.835h334.456c14.943,0,26.804,10.818,26.804,24.733
|
||||||
|
c0,13.939-11.86,24.758-26.804,24.758H832.772c-14.968,0-26.804-10.818-26.804-24.758
|
||||||
|
C805.969,1305.653,817.805,1294.835,832.772,1294.835"/>
|
||||||
|
<path style="fill:#1D4899;" d="M1000.214,425.277l262.347,318.536c-128.351,106.183-195.384,260.291-198.966,400.01
|
||||||
|
c0,0-4.128,81.426-1.542,128.33h-61.839"/>
|
||||||
|
<path style="fill:#1D4899;" d="M1000.214,1367.554h64.425c8.23,79.385,23.673,147.44,64.424,225.225l-128.849,154.689"/>
|
||||||
|
<path style="fill:#1D4899;" d="M663.718,828.94l-207.221,251.536c152.569,183.979,169.103,218.036,188.149,218.036
|
||||||
|
c9.773,0,16.486-15.493,16.486-25.221c0-45.908-53.655-102.611-53.655-152.601c0-47.451,44.38-87.144,87.147-87.144
|
||||||
|
c110.798,0,164.88,183.516,161.299,238.653h17.03c3.037-21.638,2.04-67.013,1.542-77.843
|
||||||
|
C867.76,1071.722,775.037,856.248,663.718,828.94"/>
|
||||||
|
<path style="fill:#1D4899;" d="M1336.33,828.94l207.103,251.536c-152.521,183.979-171.616,221.12-190.688,221.12
|
||||||
|
c-10.224,0-13.9-16.489-13.9-26.264c0-45.933,53.607-104.652,53.607-154.642c0-47.451-43.835-87.144-87.101-87.144
|
||||||
|
c-110.228,0-166.469,183.018-161.25,238.653h-17.031c-3.132-21.638-1.59-82.445-1.044-93.276
|
||||||
|
C1133.261,1046.977,1225.011,856.248,1336.33,828.94"/>
|
||||||
|
<path style="fill:#1D4899;" d="M853.955,1367.554h15.441c-2.586,38.684-38.664,135.044-49.457,130.418
|
||||||
|
c-11.409-3.618-11.409-7.248-12.382-14.438C806.016,1470.07,837.92,1410.805,853.955,1367.554"/>
|
||||||
|
<path style="fill:#1D4899;" d="M1148.157,1367.554h-15.537c3.132,38.684,38.19,131.912,49.552,129.92
|
||||||
|
c12.358-3.12,10.816-8.826,10.816-15.54C1191.945,1468.6,1164.643,1410.805,1148.157,1367.554"/>
|
||||||
|
<path style="fill:#FFCB04;" d="M812.61,169.624c77.328,0,145.855,22.741,187.604,76.313
|
||||||
|
c41.25-53.572,109.801-76.313,187.059-76.313c62.882,0,110.821,22.741,147.967,45.921
|
||||||
|
c47.938,29.894,104.061,104.629,114.877,190.729c3.132,26.785,0,69.017,0,69.017c-1.518,45.908-38.664,128.354-77.28,193.314
|
||||||
|
c-2.063,3.132,39.66-20.629,83.448-27.272c18.549-2.622,55.126-3.642,59.253-3.642c144.884,0,269.604,110.347,269.604,262.366
|
||||||
|
c0,61.876-20.162,140.217-74.742,180.42c50.477,44.283,74.742,112.387,74.742,187.11c0,137.606-109.303,256.696-257.198,260.326
|
||||||
|
c-26.852,1.044-88.146,7.687-196.879-75.803l302.553-371.634L999.716,315.523L366.36,1080.477l302.457,371.634
|
||||||
|
c-95.331,83.489-170.026,76.301-196.831,75.803c-138.621-1.044-256.653-122.72-256.653-260.326
|
||||||
|
c0-74.724,24.219-142.827,74.197-187.11c-54.58-40.203-74.197-118.544-74.197-180.42c0-152.02,124.247-262.366,269.012-262.366
|
||||||
|
c4.602,0,40.752,1.02,59.254,3.642c43.835,6.644,86.057,30.404,84.017,27.272c-39.186-64.96-76.261-147.406-77.802-193.314
|
||||||
|
c0,0-3.084-42.231,0-69.017c10.816-86.1,67.483-160.835,115.446-190.729C701.836,192.365,750.273,169.624,812.61,169.624"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 4.8 KiB |
56
includes/FileAccess.class.php
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Bdp\Libs;
|
||||||
|
|
||||||
|
class FileAccess extends \WP_Filesystem_Direct
|
||||||
|
{
|
||||||
|
public const HTACCESS_MAIN = '/.htaccess';
|
||||||
|
public const HTACCESS_UPLOADS = '/wp-content/uploads/.htaccess';
|
||||||
|
|
||||||
|
public function __construct( $arg = null )
|
||||||
|
{
|
||||||
|
if ( ! defined( 'FS_CHMOD_FILE' ) ) {
|
||||||
|
define( 'FS_CHMOD_FILE', ( fileperms( ABSPATH . 'index.php' ) & 0777 | 0644 ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function htaccessContains(string $needle, $file = self::HTACCESS_MAIN) : bool
|
||||||
|
{
|
||||||
|
return str_contains(FileAccess::readHtaccess($file), $needle);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function readHtaccess($file = self::HTACCESS_MAIN) : string
|
||||||
|
{
|
||||||
|
$wfs = new self();
|
||||||
|
if (!$wfs->exists(ABSPATH . $file)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $wfs->get_contents(ABSPATH . $file);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function writeHtaccess(string $value, $file = self::HTACCESS_MAIN) : bool
|
||||||
|
{
|
||||||
|
$wfs = new self();
|
||||||
|
$wfs->put_contents(ABSPATH . $file, $value);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function insertInHtaccess(string $element, $file = self::HTACCESS_MAIN) : bool
|
||||||
|
{
|
||||||
|
if (FileAccess::htaccessContains($element, $file)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$htaccessFile = FileAccess::readHtaccess($file);
|
||||||
|
$htaccessFile .= PHP_EOL . $element . PHP_EOL;
|
||||||
|
FileAccess::writeHtaccess($htaccessFile, $file);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function deleteFromHtaccess(string $element, $file = self::HTACCESS_MAIN) : bool {
|
||||||
|
$htaccessFile = str_replace($element . PHP_EOL, '', FileAccess::readHtaccess($file));
|
||||||
|
return FileAccess::writeHtaccess($htaccessFile, $file);
|
||||||
|
}
|
||||||
|
}
|
82
includes/WpConfigEditor.class.php
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Bdp\Libs;
|
||||||
|
|
||||||
|
class WpConfigEditor extends \WP_Filesystem_Direct
|
||||||
|
{
|
||||||
|
public const WP_CONFIG_FILE = '/wp-config.php';
|
||||||
|
|
||||||
|
public function __construct($arg = null)
|
||||||
|
{
|
||||||
|
if (!defined('FS_CHMOD_FILE')) {
|
||||||
|
define('FS_CHMOD_FILE', (fileperms(ABSPATH . 'index.php') & 0777 | 0644));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function readConfig(): string
|
||||||
|
{
|
||||||
|
if (!$this->exists(ABSPATH . self::WP_CONFIG_FILE)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->get_contents(ABSPATH . self::WP_CONFIG_FILE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function writeConfig($value): bool
|
||||||
|
{
|
||||||
|
$this->put_contents(ABSPATH . self::WP_CONFIG_FILE, $value);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function updateConfig($key, $value): bool
|
||||||
|
{
|
||||||
|
$wfs = new self();
|
||||||
|
$configContent = $wfs->readConfig();
|
||||||
|
|
||||||
|
if (null === self::getConfigValue($key)) {
|
||||||
|
$configContent .= "define( '$key', $value );";
|
||||||
|
}
|
||||||
|
|
||||||
|
preg_match("/define\([ ]?'($key)'\,[ ]?(.*)[ ]?\);/",$configContent, $matches);
|
||||||
|
$configContent = str_replace($matches[0], "define( '$key', $value );", $configContent);
|
||||||
|
return $wfs->writeConfig($configContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getConfigValue($key): ?string
|
||||||
|
{
|
||||||
|
$wfs = new self();
|
||||||
|
$configContent = $wfs->readConfig();
|
||||||
|
|
||||||
|
preg_match("/define\([ ]?'($key)'\,[ ]?(.*)[ ]?\);/",$configContent, $matches);
|
||||||
|
if (count($matches) == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return trim($matches[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function updateSiteKeys(string $newKeySet)
|
||||||
|
{
|
||||||
|
foreach (explode(PHP_EOL, trim($newKeySet)) as $currentKeyLine) {
|
||||||
|
preg_match("/define\([ ]?'(.*)'\,[ ]?(.*)[ ]?\);/", $currentKeyLine, $matches);
|
||||||
|
self::updateConfig($matches[1], trim($matches[2]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function deleteConfigKey($key): bool
|
||||||
|
{
|
||||||
|
if (null === self::getConfigValue($key)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$wfs = new self();
|
||||||
|
$configContent = $wfs->readConfig();
|
||||||
|
|
||||||
|
preg_match("/define\([ ]?'($key)'\,[ ]?(.*)[ ]?\);/",$configContent, $matches);
|
||||||
|
$configContent = str_replace($matches[0], '', $configContent);
|
||||||
|
return $wfs->writeConfig($configContent);
|
||||||
|
}
|
||||||
|
}
|
23
includes/action_caller.php
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
if (!isset($loginHandler)) {
|
||||||
|
$loginHandler = new \Bdp\Modules\LimitLoginAttempts\Controllers\LoginHandler();
|
||||||
|
}
|
||||||
|
|
||||||
|
add_action('wp_login_failed', [$loginHandler, 'onFailedLogin']);
|
||||||
|
add_filter('wp_authenticate_user', [$loginHandler, 'onSuccessFullLogin'], 99999, 2);
|
||||||
|
add_filter( 'admin_enqueue_scripts', 'enqueue_custom_password_js',10 );
|
||||||
|
|
||||||
|
add_action('admin_init', 'admin_init');
|
||||||
|
|
||||||
|
if (get_option('kompass_cookies', false)) {
|
||||||
|
$loginHandler->handleCookies();
|
||||||
|
add_action('auth_cookie_bad_username', [$loginHandler, 'checkFailedCookies']);
|
||||||
|
add_action('auth_cookie_valid', [$loginHandler, 'onValidCookie'], 10, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($_POST['save_kompass_balist_list_type'])) {
|
||||||
|
updateBlockOrAllowList($_POST);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
7
includes/environment.php
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
define('BDP_LV_PLUGIN_SLUG', 'bdp-kompass');
|
||||||
|
define('BDP_LV_STARTUP_FILE', WP_PLUGIN_DIR . '/' . BDP_LV_PLUGIN_SLUG . '/' . BDP_LV_PLUGIN_SLUG . '.php');
|
||||||
|
|
||||||
|
define('BDP_LV_PLUGIN_DIR', plugin_dir_path(BDP_LV_STARTUP_FILE));
|
||||||
|
define('BDP_LV_PLUGIN_URL', plugin_dir_url(BDP_LV_STARTUP_FILE));
|
45
includes/filters.php
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
add_action( 'plugins_loaded', 'bdp_kompass_load_plugin_textdomain' );
|
||||||
|
|
||||||
|
register_activation_hook(BDP_LV_STARTUP_FILE, 'bdp_plugin_install');
|
||||||
|
add_action('init', 'bdp_plugin_init');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function _protect_wp_disablexmlrpc_string() {
|
||||||
|
return "<FilesMatch \"xmlrpc.php\">
|
||||||
|
Require all denied
|
||||||
|
</FilesMatch>";
|
||||||
|
}
|
||||||
|
|
||||||
|
function _protect_wp_disable_script_execution_string() {
|
||||||
|
return '<FilesMatch "\.(php|phtml|php3|php4|php5|pl|py|jsp|asp|html|htm|shtml|sh|cgi|suspected)$">' . "
|
||||||
|
deny from all
|
||||||
|
</FilesMatch>";
|
||||||
|
}
|
||||||
|
|
||||||
|
function _protect_wp_disable_special_files_string() {
|
||||||
|
return '<FilesMatch "^.*(README|error_log|wp-config\.php|user.ini|log|php.ini|\.[hH][tT][aApP].*)$">' . "
|
||||||
|
deny from all
|
||||||
|
</FilesMatch>";
|
||||||
|
}
|
||||||
|
|
||||||
|
function _protect_wp_disable_directory_listing_string() {
|
||||||
|
return 'Options -Indexes';
|
||||||
|
}
|
||||||
|
|
||||||
|
function _protect_wp_secure_include_dir_string() {
|
||||||
|
return "RewriteEngine On
|
||||||
|
RewriteBase /
|
||||||
|
RewriteRule ^wp-admin/includes/ - [F,L]
|
||||||
|
RewriteRule !^wp-includes/ - [S=3]
|
||||||
|
RewriteRule ^wp-includes/[^/]+\.php$ - [F,L]
|
||||||
|
RewriteRule ^wp-includes/js/tinymce/langs/.+\.php - [F,L]
|
||||||
|
RewriteRule ^wp-includes/theme-compat/ - [F,L]";
|
||||||
|
}
|
||||||
|
|
||||||
|
function _protect_wp_initial_bot_list_array()
|
||||||
|
{
|
||||||
|
return explode(';', 'SemrushBot;AhrefsBot;DotBot;WhatCMS;Rogerbot;trendictionbot;BLEXBot;linkfluence;magpie-crawler;MJ12bot;Mediatoolkitbot;AspiegelBot;DomainStatsBot;Cincraw;Nimbostratus;HTTrack;serpstatbot;omgili;GrapeshotCrawler;MegaIndex;PetalBot;Semanticbot;Cocolyzebot;DomCopBot;Traackr;BomboraBot;Linguee;webtechbot;DomainStatsBot;Clickagy;sqlmap;Internet-structure-research-project-bot;Seekport;AwarioSmartBot;OnalyticaBot;Buck;Riddler;SBL-BOT;DF Bot 1.0;PubMatic Crawler Bot;BVBot;Sogou;Barkrowler;Yandex');
|
||||||
|
}
|
183
includes/frontend-functions.php
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
add_action('admin_enqueue_scripts', 'bdp_update_dashboard_style');
|
||||||
|
add_action('login_enqueue_scripts', 'bdp_update_login_style');
|
||||||
|
|
||||||
|
function bdp_update_login_style() {
|
||||||
|
$css = file_get_contents(BDP_LV_PLUGIN_DIR . 'assets/dashboard.style.css.tpl');
|
||||||
|
echo str_replace('%%BDP_LV_PLUGIN_URL%%', BDP_LV_PLUGIN_URL, $css);
|
||||||
|
}
|
||||||
|
|
||||||
|
function bdp_update_dashboard_style() {
|
||||||
|
wp_enqueue_style('custom-dashboard-styles', BDP_LV_PLUGIN_URL . '/assets/wordpress-bdp.css');
|
||||||
|
wp_enqueue_style('custom-calendar-styles', BDP_LV_PLUGIN_URL . '/assets/calendar.css');
|
||||||
|
wp_enqueue_style('custom-security-styles', BDP_LV_PLUGIN_URL . '/assets/security.css');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function bdp_add_menu_security() {
|
||||||
|
|
||||||
|
$moduleLoad = get_admin_url() . 'admin.php?page=' . BDP_LV_PLUGIN_SLUG . '/modules/index.php&loadmodule=';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function bdp_add_menu_contents() {
|
||||||
|
add_menu_page(
|
||||||
|
'Beiträge',
|
||||||
|
'Inhalte',
|
||||||
|
'edit_posts',
|
||||||
|
'edit.php',
|
||||||
|
'',
|
||||||
|
'dashicons-format-aside',
|
||||||
|
4
|
||||||
|
);
|
||||||
|
|
||||||
|
add_submenu_page('edit.php',
|
||||||
|
'media',
|
||||||
|
'Medienverwaltung',
|
||||||
|
'edit_posts',
|
||||||
|
'upload.php'
|
||||||
|
);
|
||||||
|
|
||||||
|
add_submenu_page('edit.php',
|
||||||
|
'media',
|
||||||
|
'Statische Seiten',
|
||||||
|
'edit_posts',
|
||||||
|
'edit.php?post_type=page'
|
||||||
|
);
|
||||||
|
|
||||||
|
add_submenu_page('edit.php',
|
||||||
|
'comments',
|
||||||
|
'Kommentare',
|
||||||
|
'edit_posts',
|
||||||
|
'edit-comments.php'
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function bdp_add_menu_mein_lv() {
|
||||||
|
$location = BDP_LV_PLUGIN_DIR . '/modules/';
|
||||||
|
$mainSlug = $location . 'index.php';
|
||||||
|
$moduleLoad = get_admin_url() . 'admin.php?page=' . BDP_LV_PLUGIN_SLUG . '/modules/index.php&loadmodule=';
|
||||||
|
|
||||||
|
add_menu_page(
|
||||||
|
'Mein BdP',
|
||||||
|
'BdP',
|
||||||
|
'manage_options',
|
||||||
|
$mainSlug,
|
||||||
|
'',
|
||||||
|
BDP_LV_PLUGIN_URL . '/icon.png',
|
||||||
|
3
|
||||||
|
);
|
||||||
|
|
||||||
|
add_submenu_page($mainSlug,
|
||||||
|
'calendar_settings',
|
||||||
|
'Kalender-Einstellungen',
|
||||||
|
'manage_options',
|
||||||
|
$moduleLoad . 'calendar'
|
||||||
|
);
|
||||||
|
|
||||||
|
add_submenu_page($mainSlug,
|
||||||
|
'calendar_settings',
|
||||||
|
'Über',
|
||||||
|
'manage_options',
|
||||||
|
$moduleLoad . 'about'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function bdp_add_menu_setup() {
|
||||||
|
add_menu_page(
|
||||||
|
'Allgemeine Einstellungen',
|
||||||
|
'Webseiten-Setup',
|
||||||
|
'manage_options',
|
||||||
|
'users.php',
|
||||||
|
'',
|
||||||
|
'dashicons-admin-generic',
|
||||||
|
6
|
||||||
|
);
|
||||||
|
|
||||||
|
add_submenu_page('users.php',
|
||||||
|
'Allgemeine Einstellungen',
|
||||||
|
'Allgemeine Einstellungen',
|
||||||
|
'manage_options',
|
||||||
|
'options-general.php'
|
||||||
|
);
|
||||||
|
|
||||||
|
add_submenu_page('users.php',
|
||||||
|
'Design-Einstellungen',
|
||||||
|
'Template bearbeiten',
|
||||||
|
'manage_options',
|
||||||
|
'customize.php?return=/wp-admin/'
|
||||||
|
);
|
||||||
|
|
||||||
|
add_submenu_page('users.php',
|
||||||
|
'plugins',
|
||||||
|
'Erweiterungen',
|
||||||
|
'manage_options',
|
||||||
|
'plugins.php'
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
add_submenu_page('users.php',
|
||||||
|
'themes',
|
||||||
|
'Designs',
|
||||||
|
'manage_options',
|
||||||
|
'themes.php'
|
||||||
|
);
|
||||||
|
|
||||||
|
add_submenu_page('users.php',
|
||||||
|
'Sicherheit',
|
||||||
|
'Webseiten-Sicherheit',
|
||||||
|
'manage_options',
|
||||||
|
'site-health.php'
|
||||||
|
);
|
||||||
|
|
||||||
|
$loginOption = new \Bdp\Modules\LimitLoginAttempts\Controllers\OptionsPage();
|
||||||
|
add_submenu_page('users.php',
|
||||||
|
'Login-Sicherheit',
|
||||||
|
'Login-Sicherheit',
|
||||||
|
'manage_options',
|
||||||
|
BDP_LV_PLUGIN_SLUG . '-limit-login-attempts',
|
||||||
|
[$loginOption, 'limit_login_option_page']
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function bdp_cleanup_menu()
|
||||||
|
{
|
||||||
|
global $submenu;
|
||||||
|
|
||||||
|
remove_menu_page('edit-comments.php');
|
||||||
|
remove_menu_page('edit.php');
|
||||||
|
remove_menu_page('edit.php?post_type=page');
|
||||||
|
remove_menu_page('upload.php');
|
||||||
|
remove_menu_page('themes.php');
|
||||||
|
remove_menu_page('plugins.php');
|
||||||
|
remove_menu_page('options-general.php');
|
||||||
|
remove_menu_page('users.php');
|
||||||
|
remove_menu_page('tools.php');
|
||||||
|
|
||||||
|
bdp_add_menu_contents();
|
||||||
|
bdp_add_menu_setup();
|
||||||
|
bdp_add_menu_security();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
remove_submenu_page('users.php','user-new.php');
|
||||||
|
remove_submenu_page('users.php','profile.php');
|
||||||
|
|
||||||
|
remove_submenu_page('edit.php','post-new.php');
|
||||||
|
remove_submenu_page('edit.php','edit-tags.php?taxonomy=category');
|
||||||
|
remove_submenu_page('edit.php','edit-tags.php?taxonomy=post_tag');
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function bdp_create_menu_structure()
|
||||||
|
{
|
||||||
|
add_action('admin_menu', 'bdp_cleanup_menu');
|
||||||
|
bdp_add_menu_mein_lv();
|
||||||
|
}
|
6
includes/pre_requires.php
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?php
|
||||||
|
require_once (ABSPATH . '/wp-admin/includes/plugin.php');
|
||||||
|
require_once (ABSPATH . '/wp-admin/includes/class-wp-filesystem-base.php');
|
||||||
|
require_once (ABSPATH . '/wp-admin/includes/class-wp-filesystem-direct.php');
|
||||||
|
require_once (ABSPATH . '/wp-includes/pluggable.php');
|
||||||
|
require_once (ABSPATH . '/wp-admin/includes/template.php');
|
44
includes/setup.php
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
if ( ! defined( 'WP_PLUGIN_DIR' ) ) { // Abspath to wp-content/plugins
|
||||||
|
define( 'WP_PLUGIN_DIR', WP_CONTENT_DIR . '/plugins' ); // Full path, no trailing slash.
|
||||||
|
}
|
||||||
|
|
||||||
|
use Bdp\Modules\LimitLoginAttempts\Controllers\LoginHandler;
|
||||||
|
|
||||||
|
|
||||||
|
require_once dirname(__FILE__) . '/pre_requires.php';
|
||||||
|
require_once dirname(__FILE__) . '/environment.php';
|
||||||
|
require_once dirname(__FILE__) . '/spl.php';
|
||||||
|
require_once dirname(__FILE__) . '/update.class.php';
|
||||||
|
|
||||||
|
require_once BDP_LV_PLUGIN_DIR . 'includes/FileAccess.class.php';
|
||||||
|
require_once BDP_LV_PLUGIN_DIR . 'includes/WpConfigEditor.class.php';
|
||||||
|
|
||||||
|
require_once (BDP_LV_PLUGIN_DIR . '/includes/filters.php');
|
||||||
|
require_once (BDP_LV_PLUGIN_DIR . '/lib/ics-parser/Event.php');
|
||||||
|
require_once (BDP_LV_PLUGIN_DIR . '/lib/ics-parser/ICal.php');
|
||||||
|
require_once (BDP_LV_PLUGIN_DIR . '/modules/seo/seo.php');
|
||||||
|
require_once (BDP_LV_PLUGIN_DIR . '/modules/calendar/calendar.php');
|
||||||
|
require_once (BDP_LV_PLUGIN_DIR . '/includes/frontend-functions.php');
|
||||||
|
|
||||||
|
require_once (BDP_LV_PLUGIN_DIR . '/modules/security/security.php');
|
||||||
|
|
||||||
|
function admin_init()
|
||||||
|
{
|
||||||
|
kompass_settings_validators();
|
||||||
|
}
|
||||||
|
|
||||||
|
bdp_create_menu_structure();
|
||||||
|
|
||||||
|
|
||||||
|
function bdp_kompass_load_plugin_textdomain() {
|
||||||
|
load_textdomain( BDP_LV_PLUGIN_SLUG, BDP_LV_PLUGIN_DIR . '/lang/' . BDP_LV_PLUGIN_SLUG . '_' . get_locale() . '.mo' );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$loginHandler = new LoginHandler();
|
||||||
|
new BdpVersionChecker();
|
||||||
|
#add_filter( 'plugins_api', array( $class, 'info' ), 20, 3 );
|
||||||
|
require_once dirname(__FILE__) . '/action_caller.php';
|
32
includes/spl.php
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
spl_autoload_register(function ($className) {
|
||||||
|
|
||||||
|
if (!str_starts_with($className, 'ProtectLogin\\')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$fileName = str_replace('\\','/', $className);
|
||||||
|
$fileName = str_replace('ProtectLogin/Modules/', 'ProtectLogin/modules/', $fileName);
|
||||||
|
$fileName = str_replace('ProtectLogin/', '', $fileName);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$fileName = BDP_LV_PLUGIN_DIR . $fileName . '.php';
|
||||||
|
if (!file_exists($fileName)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once $fileName;
|
||||||
|
});
|
||||||
|
|
||||||
|
$modules = ['LimitLoginAttempts', 'PasswordStrength'];
|
||||||
|
$subdirs = ['includes', 'Controllers', 'Views'];
|
||||||
|
|
||||||
|
foreach ($modules as $curModule) {
|
||||||
|
foreach ($subdirs as $dir) {
|
||||||
|
$directoryPath = BDP_LV_PLUGIN_DIR . 'modules/' . $curModule . '/' . $dir . '/';
|
||||||
|
foreach (glob($directoryPath . '*.php') as $file) {
|
||||||
|
require_once $file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
152
includes/update.class.php
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class BdpVersionChecker
|
||||||
|
{
|
||||||
|
public $plugin_slug;
|
||||||
|
public $version;
|
||||||
|
public $cache_key;
|
||||||
|
public $cache_allowed;
|
||||||
|
public $updateUrl;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$plugin_data = get_plugin_data( BDP_LV_STARTUP_FILE );
|
||||||
|
$this->plugin_slug = BDP_LV_PLUGIN_SLUG;
|
||||||
|
$this->updateUrl = $plugin_data['UpdateURI'] . '/info_development.json';
|
||||||
|
$this->version = $plugin_data['Version'];
|
||||||
|
$this->cache_key = 'bdp-kompass-upd';
|
||||||
|
$this->cache_allowed = false;
|
||||||
|
|
||||||
|
add_filter( 'plugins_api', array( $this, 'info' ), 20, 3 );
|
||||||
|
add_filter( 'site_transient_update_plugins', array( $this, 'update' ) );
|
||||||
|
add_action( 'upgrader_process_complete', array( $this, 'purge' ), 10, 2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function request(){
|
||||||
|
|
||||||
|
$remote = get_transient( $this->cache_key );
|
||||||
|
|
||||||
|
if( false === $remote || ! $this->cache_allowed ) {
|
||||||
|
|
||||||
|
$remote = wp_remote_get(
|
||||||
|
$this->updateUrl
|
||||||
|
,
|
||||||
|
array(
|
||||||
|
'timeout' => 10,
|
||||||
|
'headers' => array(
|
||||||
|
'Accept' => 'application/json'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if(
|
||||||
|
is_wp_error( $remote )
|
||||||
|
|| 200 !== wp_remote_retrieve_response_code( $remote )
|
||||||
|
|| empty( wp_remote_retrieve_body( $remote ) )
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
set_transient( $this->cache_key, $remote, 3600 );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$remote = json_decode( wp_remote_retrieve_body( $remote ) );
|
||||||
|
|
||||||
|
return $remote;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function info( $res = '', $action = '', $args = '' )
|
||||||
|
{
|
||||||
|
if (!isset($args->slug) || $args->slug !== $this->plugin_slug) {
|
||||||
|
return $res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get updates
|
||||||
|
$remote = $this->request();
|
||||||
|
|
||||||
|
if( ! $remote ) {
|
||||||
|
return $res;
|
||||||
|
}
|
||||||
|
|
||||||
|
$newVersion = $remote->version;
|
||||||
|
$res = new stdClass();
|
||||||
|
|
||||||
|
$res->name = $remote->name;
|
||||||
|
$res->slug = $remote->slug;
|
||||||
|
$res->version = $newVersion;
|
||||||
|
$res->tested = $remote->tested;
|
||||||
|
$res->requires = $remote->requires;
|
||||||
|
$res->author = $remote->author;
|
||||||
|
$res->author_profile = $remote->author_profile;
|
||||||
|
$res->download_link = $remote->download_url;
|
||||||
|
$res->trunk = $remote->download_url;
|
||||||
|
$res->requires_php = $remote->requires_php;
|
||||||
|
$res->last_updated = $remote->last_updated;
|
||||||
|
|
||||||
|
$res->sections = array(
|
||||||
|
'description' => $remote->sections->description,
|
||||||
|
'installation' => $remote->sections->installation,
|
||||||
|
'changelog' => $remote->sections->changelog
|
||||||
|
);
|
||||||
|
|
||||||
|
if( ! empty( $remote->banners ) ) {
|
||||||
|
$res->banners = array(
|
||||||
|
'low' => $remote->banners->low,
|
||||||
|
'high' => $remote->banners->high
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $res;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function update( $transient ) {
|
||||||
|
if ( empty($transient->checked ) ) {
|
||||||
|
return $transient;
|
||||||
|
}
|
||||||
|
|
||||||
|
$remote = $this->request();
|
||||||
|
if(
|
||||||
|
$remote
|
||||||
|
&& version_compare( $this->version, $remote->version, '<' )
|
||||||
|
&& version_compare( $remote->requires, get_bloginfo( 'version' ), '<=' )
|
||||||
|
&& version_compare( $remote->requires_php, PHP_VERSION, '<' )
|
||||||
|
) {
|
||||||
|
|
||||||
|
$newVersion = $remote->version;
|
||||||
|
|
||||||
|
$res = new stdClass();
|
||||||
|
$res->slug = $this->plugin_slug;
|
||||||
|
$res->plugin = plugin_basename( BDP_LV_STARTUP_FILE );
|
||||||
|
$res->new_version = $newVersion;
|
||||||
|
$res->tested = $remote->tested;
|
||||||
|
$res->package = $remote->download_url;
|
||||||
|
|
||||||
|
$transient->response[ $res->plugin ] = $res;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$res = new stdClass();
|
||||||
|
$res->slug = $this->plugin_slug;
|
||||||
|
$res->plugin = plugin_basename( BDP_LV_STARTUP_FILE );
|
||||||
|
$transient->no_update[ $res->plugin ] = $res;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $transient;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function purge( $upgrader, $options ){
|
||||||
|
|
||||||
|
if (
|
||||||
|
$this->cache_allowed
|
||||||
|
&& 'update' === $options['action']
|
||||||
|
&& 'plugin' === $options[ 'type' ]
|
||||||
|
) {
|
||||||
|
// just clean the cache when new plugin version is installed
|
||||||
|
delete_transient( $this->cache_key );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
BIN
lang/bdp-kompass_de_DE.mo
Normal file
111
lang/bdp-kompass_de_DE.po
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
msgid "Extended Security"
|
||||||
|
msgstr "Erweiterte Sicherheit"
|
||||||
|
|
||||||
|
msgid "Save changes"
|
||||||
|
msgstr "Änderungen speichern"
|
||||||
|
|
||||||
|
msgid "All settings are saved."
|
||||||
|
msgstr "Die Einstellungen wurden gespeichert."
|
||||||
|
|
||||||
|
msgid "Disable xmlrpc"
|
||||||
|
msgstr "xmlrpc deaktivieren"
|
||||||
|
|
||||||
|
msgid "By introducing the REST API in WordPress, xmlrpc. However, php is no longer needed to communicate outside of WordPress, which is why there is no longer any reason to leave it active or use it. Therefore, for the security of your site, it is better to deactivate or delete it."
|
||||||
|
msgstr "Durch die Einführung der REST API in WordPress wird xmlrpc. php jedoch nicht mehr benötigt, um außerhalb von WordPress zu kommunizieren, weshalb es hier keinen Grund mehr gibt, diese aktiv zu lassen oder zu nutzen. Deshalb ist es für die Sicherheit deiner Seite besser, diese zu deaktivieren oder zu löschen."
|
||||||
|
|
||||||
|
msgid "Disable Authorscan"
|
||||||
|
msgstr "Autorenscan deaktivieren"
|
||||||
|
|
||||||
|
|
||||||
|
msgid "The author page in WordPress typically displays a list of all posts by a specific author on your website. Unfortunately, Google also records the page and to prevent this, we can deactivate the author page. When a visitor clicks on an name of an author, they are redirected to the author page. This page contains a list of posts written by this author, as well as possibly a brief description of the author and a photo. It is also possible to record which user names have been created."
|
||||||
|
msgstr "Die Autorenseite in WordPress zeigt normalerweise eine Liste aller Beiträge eines bestimmten Autors auf deiner Website an. Google erfasst die Seite auch leider und um das zu verhindern, können wir die Autorenseite deaktivieren. Wenn ein Besucher auf den Namen eines Autors klickt, wird er auf die Autorenseite weitergeleitet. Diese Seite enthält eine Liste der Beiträge, die von diesem Autor verfasst wurden, sowie möglicherweise eine kurze Beschreibung des Autors und ein Foto. Auch ist es darüber möglich zu erfassen, welche Nutzernamen angelegt sind."
|
||||||
|
|
||||||
|
msgid "Disable scripting in /wp-content/uploads/"
|
||||||
|
msgstr "Scripting in /wp-content/uploads/ deaktivieren"
|
||||||
|
|
||||||
|
msgid "Disabling scripting in /wp-content/uploads/ can be a security measure to protect your WordPress website from potential threats. The /wp-content/uploads folder is usually the default folder where WordPress stores uploaded files, such as images, videos, and other media files."
|
||||||
|
msgstr "Das Deaktivieren von Scripting in /wp-content/uploads/ kann eine Sicherheitsmaßnahme sein, um dein WordPress-Website vor potenziellen Bedrohungen zu schützen. Der Ordner /wp-content/uploads ist normalerweise der Standardordner, in dem WordPress hochgeladene Dateien, wie Bilder, Videos und andere Mediendateien, speichert."
|
||||||
|
|
||||||
|
msgid "Block access to potentially sensitive files"
|
||||||
|
msgstr "Zugriff auf potenziell sensible Dateien blockieren"
|
||||||
|
|
||||||
|
msgid "This setting prohibits access to configuration files and log files"
|
||||||
|
msgstr "Diese Einstellung verbietet den Zugriff auf Konfigurationsdateien sowie Log-Dateien"
|
||||||
|
|
||||||
|
msgid "Disable file editor in WP Dashboard"
|
||||||
|
msgstr "Dateieditor im WP Dashboard deaktivieren"
|
||||||
|
|
||||||
|
msgid "This is a security feature that allows you to prevent users from editing theme and plugin files directly from the WordPress dashboard. This can be useful for a variety of reasons, including preventing accidental code changes and protecting your website from malicious attacks."
|
||||||
|
msgstr "Hierbei handelt es sich um eine Sicherheitsfunktion, mit der Sie verhindern können, dass Benutzer Theme- und Plugin-Dateien direkt über das WordPress-Dashboard bearbeiten können. Dies kann aus verschiedenen Gründen nützlich sein, unter anderem um versehentliche Änderungen am Code zu verhindern und Ihre Website vor böswilligen Angriffen zu schützen."
|
||||||
|
|
||||||
|
msgid "Disable script concatenation"
|
||||||
|
msgstr "Skriptverkettung deaktivieren"
|
||||||
|
|
||||||
|
msgid "Disabling script concatenation in the WordPress admin panel is a simple and effective way to enhance performance. However, it is crucial to carefully consider the impact of this change, as it may increase the number of HTTP requests, potentially affecting loading times"
|
||||||
|
msgstr "Das Deaktivieren der Skriptverkettung im WordPress-Admin-Panel ist eine einfache und effektive Möglichkeit, die Leistung zu verbessern. Es ist jedoch wichtig, die Auswirkungen dieser Änderung sorgfältig abzuwägen, da sie die Anzahl der HTTP-Anfragen erhöhen und sich möglicherweise auf die Ladezeiten auswirken kann."
|
||||||
|
|
||||||
|
msgid "Disable script execution in include dir"
|
||||||
|
msgstr "Skriptausführung im Include-Verzeichnis deaktivieren"
|
||||||
|
|
||||||
|
msgid "Limiting script execution in specific directories can improve security by preventing potentially malicious scripts from running in critical parts of the WordPress system. This is particularly important to prevent attacks such as Cross-Site Scripting (XSS), which inject malicious code into website content."
|
||||||
|
msgstr "Das Begrenzen der Skriptausführung in bestimmten Verzeichnissen kann die Sicherheit verbessern, indem potenziell schädliche Skripte daran gehindert werden, in kritischen Teilen des WordPress-Systems ausgeführt zu werden. Dies ist besonders wichtig, um Angriffe wie Cross-Site Scripting (XSS) zu verhindern, bei denen schädlicher Code in Webseiteninhalte eingeschleust wird."
|
||||||
|
|
||||||
|
msgid "Change site keys"
|
||||||
|
msgstr "Seitenschlüssel erneuern"
|
||||||
|
|
||||||
|
msgid "An error occured connecting api.wordpress.org"
|
||||||
|
msgstr "Beim Kontaktieren von api.wordpress.org trat ein Fehler auf"
|
||||||
|
|
||||||
|
msgid "The site keys were updated successfully."
|
||||||
|
msgstr "Die Seitenschlüssel wurden erneuert."
|
||||||
|
|
||||||
|
msgid "Protect WP detected missing security settings"
|
||||||
|
msgstr "Protect WP hat fehlende Sicherheitseinstellungen festgestellt"
|
||||||
|
|
||||||
|
msgid "Protect WP has detected that advanced security settings are missing.<br />You can update the settings directly in the dashboard."
|
||||||
|
msgstr "Protect WP hat festgestellt, dass erweiterte Sicherheitseinstellungen fehlen.<br />Du kannst die Einstellungen direkt im Dashboard aktualisieren."
|
||||||
|
|
||||||
|
msgid "Protect WP - security settings"
|
||||||
|
msgstr "Protect WP - Sicherheitseinstellungen"
|
||||||
|
|
||||||
|
msgid "Prohibit access from unwanted bots"
|
||||||
|
msgstr "Zugriff von ungewollten Bots verbieten"
|
||||||
|
|
||||||
|
msgid "Excluding specific bots from a WordPress website provides improved security by reducing potentially malicious activity and security risks, optimizes resource consumption and site performance, protects against content theft and duplicate content, enables more precise control of traffic, and promotes more effective SEO -Optimization by reducing irrelevant bots, ultimately leading to a safer, more efficient and better performing website."
|
||||||
|
msgstr "Das Ausschließen bestimmter Bots von einer WordPress-Website bietet eine verbesserte Sicherheit, indem potenziell bösartige Aktivitäten und Sicherheitsrisiken reduziert werden, optimiert den Ressourcenverbrauch und die Website-Performance, schützt vor Inhaltsdiebstahl und Duplicate Content, ermöglicht eine genauere Kontrolle des Datenverkehrs und fördert eine effektivere SEO-Optimierung durch die Reduzierung nicht relevanter Bots, was letztendlich zu einer sichereren, effizienteren und besser performenden Website führt."
|
||||||
|
|
||||||
|
msgid "Bot Detection Database"
|
||||||
|
msgstr "Datenbank zur Bot-Erkennung"
|
||||||
|
|
||||||
|
msgid "Registered bots"
|
||||||
|
msgstr "Vorhandene Bots"
|
||||||
|
|
||||||
|
msgid "Add more bots"
|
||||||
|
msgstr "Weitere Bots hinzufügen"
|
||||||
|
|
||||||
|
msgid "Leave blank in order to delete"
|
||||||
|
msgstr "Zum Löschen leer lassen"
|
||||||
|
|
||||||
|
msgid "Please use line breaks to enter multiple bots"
|
||||||
|
msgstr "Bitte Zeilenumbruch verwenden, um mehrere Bots einzutragen"#
|
||||||
|
|
||||||
|
msgid "Bot Detection Database updated successfully."
|
||||||
|
msgstr "Die Datenbank zur Bot-Erkennung wurde erfolgreich aktualisiert."
|
||||||
|
|
||||||
|
msgid "Disable directory listing"
|
||||||
|
msgstr "Auflistung von Verzeichnissen deaktivieren"
|
||||||
|
|
||||||
|
msgid "Directory listing should be disabled to ensure the security and privacy of a website. When Directory Listing is enabled, this allows users to directly access the contents of directories on a web server without having to specify a specific file. This can expose sensitive information such as directory structures, internal files and scripts, posing a potential security risk. Disabling Directory Listing prevents users from accessing this sensitive information, thereby providing an additional layer of security for the website."
|
||||||
|
msgstr "Das Auflisten von Verzeichnissen sollte deaktiviert werden, um die Sicherheit und Privatsphäre einer Website zu gewährleisten. Wenn Directory Listing aktiviert ist, ermöglicht dies Benutzern den direkten Zugriff auf die Inhalte von Verzeichnissen auf einem Webserver, ohne dass eine spezifische Datei angegeben werden muss. Dies kann sensible Informationen wie Verzeichnisstrukturen, interne Dateien und Skripte offenlegen, was ein potenzielles Sicherheitsrisiko darstellt. Durch das Deaktivieren von Directory Listing wird verhindert, dass Benutzer auf diese sensiblen Informationen zugreifen können, und bietet somit eine zusätzliche Sicherheitsschicht für die Website."
|
||||||
|
|
||||||
|
msgid "Disable debug output"
|
||||||
|
msgstr "Debug-Ausgaben deaktivieren"
|
||||||
|
|
||||||
|
msgid "Debugging should be disabled to protect sensitive information about the internal structure and potential security vulnerabilities of a a WordPress website from potential attackers. When debugging is enabled, error messages and warnings are displayed directly on the website, which can provide attackers with valuable information about the configuration of the website and possible vulnerabilities."
|
||||||
|
msgstr "Debugging sollte deaktiviert werden, um sensible Informationen über die interne Struktur und mögliche Sicherheitslücken einer WordPress-Website vor potenziellen Angreifern zu schützen. Wenn Debuggin aktiviert ist, werden Fehlermeldungen und Warnungen direkt auf der Webseite angezeigt, was Angreifern wertvolle Informationen über die Konfiguration und mögliche Schwachstellen der Website geben kann. "
|
||||||
|
|
||||||
|
msgid "Change Login URL"
|
||||||
|
msgstr "Login-URL ändern"
|
||||||
|
|
||||||
|
msgid "Changing the default login URL of WordPress is advisable to enhance the security of your website. By default, WordPress login URLs is /wp-admin or /wp-login.php, which are easily guessed by hackers and facilitate attacks such as brute-force attacks. Changing the login URL to something unique and difficult to guess increases security since potential attackers will struggle to find the correct URL. This can help protect your website from unauthorized access and other malicious activities."
|
||||||
|
msgstr "Es ist ratsam, die Standard-Login-URL von WordPress zu ändern, um die Sicherheit deiner Website zu erhöhen. Standardmäßig lautet die Login-URL von WordPress /wp-admin oder /wp-login.php, was für Hacker leicht zu erraten ist und Angriffe wie Brute-Force-Attacken erleichtern kann. Durch Ändern der Login-URL auf etwas Einzigartiges und schwer zu erraten, erhöhst du die Sicherheit, da potenzielle Angreifer Schwierigkeiten haben werden, die richtige URL zu finden. Dies kann helfen, deine Website vor unautorisiertem Zugriff und anderen böswilligen Aktivitäten zu schützen."
|
318
lib/ics-parser/Event.php
Normal file
@ -0,0 +1,318 @@
|
|||||||
|
<?php
|
||||||
|
ini_set('display_errors', '1');
|
||||||
|
ini_set('date.timezone', 'Europe/Berlin');
|
||||||
|
|
||||||
|
class Event
|
||||||
|
{
|
||||||
|
// phpcs:disable Generic.Arrays.DisallowLongArraySyntax
|
||||||
|
|
||||||
|
const HTML_TEMPLATE = '<p>%s: %s</p>';
|
||||||
|
|
||||||
|
public $category;
|
||||||
|
|
||||||
|
public $start = '';
|
||||||
|
public $startInt = 0;
|
||||||
|
|
||||||
|
public $end = '';
|
||||||
|
public $endInt = 0;
|
||||||
|
|
||||||
|
public $wholeDay = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://www.kanzaki.com/docs/ical/summary.html
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $summary;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://www.kanzaki.com/docs/ical/dtstart.html
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $dtstart;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://www.kanzaki.com/docs/ical/dtend.html
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $dtend;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://www.kanzaki.com/docs/ical/duration.html
|
||||||
|
*
|
||||||
|
* @var string|null
|
||||||
|
*/
|
||||||
|
public $duration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://www.kanzaki.com/docs/ical/dtstamp.html
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $dtstamp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When the event starts, represented as a timezone-adjusted string
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $dtstart_tz;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When the event ends, represented as a timezone-adjusted string
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $dtend_tz;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://www.kanzaki.com/docs/ical/uid.html
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $uid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://www.kanzaki.com/docs/ical/created.html
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $created;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://www.kanzaki.com/docs/ical/lastModified.html
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $last_modified;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://www.kanzaki.com/docs/ical/description.html
|
||||||
|
*
|
||||||
|
* @var string|null
|
||||||
|
*/
|
||||||
|
public $description;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://www.kanzaki.com/docs/ical/location.html
|
||||||
|
*
|
||||||
|
* @var string|null
|
||||||
|
*/
|
||||||
|
public $location;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://www.kanzaki.com/docs/ical/sequence.html
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $sequence;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://www.kanzaki.com/docs/ical/status.html
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://www.kanzaki.com/docs/ical/transp.html
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $transp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://www.kanzaki.com/docs/ical/organizer.html
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $organizer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://www.kanzaki.com/docs/ical/attendee.html
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $attendee;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manage additional properties
|
||||||
|
*
|
||||||
|
* @var array<string, mixed>
|
||||||
|
*/
|
||||||
|
public $additionalProperties = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the Event object
|
||||||
|
*
|
||||||
|
* @param array $data
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct(array $data = array())
|
||||||
|
{
|
||||||
|
foreach ($data as $key => $value) {
|
||||||
|
if ($key == 'DTSTART_array' || $key == 'DTEND_array') {
|
||||||
|
|
||||||
|
$dateString = $value[1];
|
||||||
|
$dateTime = \DateTime::createFromFormat('Ymd\THis', $dateString);
|
||||||
|
if (false === $dateTime) {
|
||||||
|
$this->wholeDay = true;
|
||||||
|
$dateTime = \DateTime::createFromFormat('Ymd', $dateString);
|
||||||
|
}
|
||||||
|
|
||||||
|
$timeZone = 'Europe/Berlin';
|
||||||
|
if (isset($value[0]['TZID'])) {
|
||||||
|
$timeZone = $value[0]['TZID'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$dateTime->setTimezone(new \DateTimeZone($timeZone));
|
||||||
|
|
||||||
|
if ($key == 'DTSTART_array') {
|
||||||
|
$this->start = $dateTime->format('d.m.Y H:i:s');
|
||||||
|
$this->startInt = $dateTime->getTimestamp();
|
||||||
|
} else {
|
||||||
|
$this->end = $dateTime->format('d.m.Y H:i:s');
|
||||||
|
$this->endInt = $dateTime->getTimestamp();
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
$variable = self::snakeCase($key);
|
||||||
|
if (property_exists($this, $variable)) {
|
||||||
|
$this->{$variable} = $this->prepareData($value);
|
||||||
|
} elseif ($variable == 'categories') {
|
||||||
|
$this->category = $value;
|
||||||
|
} else {
|
||||||
|
$this->additionalProperties[$variable] = $this->prepareData($value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Magic getter method
|
||||||
|
*
|
||||||
|
* @param string $additionalPropertyName
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function __get($additionalPropertyName)
|
||||||
|
{
|
||||||
|
if (array_key_exists($additionalPropertyName, $this->additionalProperties)) {
|
||||||
|
return $this->additionalProperties[$additionalPropertyName];
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Magic isset method
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function __isset($name)
|
||||||
|
{
|
||||||
|
return is_null($this->$name) === false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepares the data for output
|
||||||
|
*
|
||||||
|
* @param mixed $value
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
protected function prepareData($value)
|
||||||
|
{
|
||||||
|
if (is_string($value)) {
|
||||||
|
return stripslashes(trim(str_replace('\n', "\n", $value)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_array($value)) {
|
||||||
|
return array_map(function ($value) {
|
||||||
|
return $this->prepareData($value);
|
||||||
|
}, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getEventTime() {
|
||||||
|
$dateTime = explode(' ', $this->start);
|
||||||
|
|
||||||
|
if ($this->wholeDay) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($dateTime[1])) {
|
||||||
|
$time = explode(':', $dateTime[1]);
|
||||||
|
return $time[0] . ':' . $time[1] . ' Uhr';
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns Event data excluding anything blank
|
||||||
|
* within an HTML template
|
||||||
|
*
|
||||||
|
* @param string $html HTML template to use
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function printData($html = self::HTML_TEMPLATE)
|
||||||
|
{
|
||||||
|
$data = array(
|
||||||
|
'SUMMARY' => $this->summary,
|
||||||
|
'start' => $this->start,
|
||||||
|
'end' => $this->end,
|
||||||
|
'DTEND' => $this->dtend,
|
||||||
|
'DTSTART_TZ' => $this->dtstart_tz,
|
||||||
|
'DTEND_TZ' => $this->dtend_tz,
|
||||||
|
'DURATION' => $this->duration,
|
||||||
|
'DTSTAMP' => $this->dtstamp,
|
||||||
|
'UID' => $this->uid,
|
||||||
|
'CREATED' => $this->created,
|
||||||
|
'LAST-MODIFIED' => $this->last_modified,
|
||||||
|
'DESCRIPTION' => $this->description,
|
||||||
|
'LOCATION' => $this->location,
|
||||||
|
'SEQUENCE' => $this->sequence,
|
||||||
|
'STATUS' => $this->status,
|
||||||
|
'TRANSP' => $this->transp,
|
||||||
|
'ORGANISER' => $this->organizer,
|
||||||
|
'ATTENDEE(S)' => $this->attendee,
|
||||||
|
'CATEGORIES' => $this->category,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Remove any blank values
|
||||||
|
$data = array_filter($data);
|
||||||
|
|
||||||
|
$output = '';
|
||||||
|
foreach ($data as $key => $value) {
|
||||||
|
$output .= sprintf($html, $key, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts the given input to snake_case
|
||||||
|
*
|
||||||
|
* @param string $input
|
||||||
|
* @param string $glue
|
||||||
|
* @param string $separator
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected static function snakeCase($input, $glue = '_', $separator = '-')
|
||||||
|
{
|
||||||
|
$inputSplit = preg_split('/(?<=[a-z])(?=[A-Z])/x', $input);
|
||||||
|
|
||||||
|
if ($inputSplit === false) {
|
||||||
|
return $input;
|
||||||
|
}
|
||||||
|
|
||||||
|
$inputSplit = implode($glue, $inputSplit);
|
||||||
|
$inputSplit = str_replace($separator, $glue, $inputSplit);
|
||||||
|
|
||||||
|
return strtolower($inputSplit);
|
||||||
|
}
|
||||||
|
}
|
2731
lib/ics-parser/ICal.php
Normal file
282
modules/LimitLoginAttempts/Controllers/LoginHandler.php
Normal file
@ -0,0 +1,282 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Bdp\Modules\LimitLoginAttempts\Controllers;
|
||||||
|
|
||||||
|
use ProtectLogin\Modules\LimitLoginAttempts\Requests\IpAddress;
|
||||||
|
|
||||||
|
class LoginHandler {
|
||||||
|
public const DIRECT_ADDR = 'REMOTE_ADDR';
|
||||||
|
public const PROXY_ADDR = 'HTTP_X_FORWARDED_FOR';
|
||||||
|
|
||||||
|
public function onSuccessFullLogin($user, $password) {
|
||||||
|
if (!is_wp_error($user) && $this->isLoginAllowedFromIp() ) {
|
||||||
|
return $user;
|
||||||
|
}
|
||||||
|
|
||||||
|
global $limit_login_my_error_shown;
|
||||||
|
$limit_login_my_error_shown = true;
|
||||||
|
|
||||||
|
$error = new \WP_Error();
|
||||||
|
// This error should be the same as in "shake it" filter below
|
||||||
|
$error->add('too_many_retries', $this->composeErrorMessage());
|
||||||
|
return $error;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onFailedLogin(string $username) {
|
||||||
|
$ip = $this->getAddress();
|
||||||
|
|
||||||
|
/* if currently locked-out, do not add to retries */
|
||||||
|
$lockouts = get_option('protect_login_limit_login_lockouts', []);
|
||||||
|
|
||||||
|
if(isset($lockouts[$ip]) && time() < $lockouts[$ip]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the arrays with retries and retries-valid information */
|
||||||
|
$retries = get_option('kompass_limit_login_retries', []);
|
||||||
|
$valid = get_option('kompass_limit_login_retries_valid', []);
|
||||||
|
|
||||||
|
/* Check validity and add one to retries */
|
||||||
|
if (isset($retries[$ip])) { //} && isset($valid[$ip]) && time() < $valid[$ip]) {
|
||||||
|
$retries[$ip] ++;
|
||||||
|
} else {
|
||||||
|
$retries[$ip] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
update_option('kompass_limit_login_retries', $retries);
|
||||||
|
|
||||||
|
/* lockout? */
|
||||||
|
if($retries[$ip] % get_option('kompass_limit_login_allowed_retries', 0) != 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$retries_long = get_option('kompass_limit_login_allowed_retries', 1)
|
||||||
|
* get_option('kompass_limit_login_allowed_lockouts', 1);
|
||||||
|
|
||||||
|
if ($retries[$ip] >= $retries_long) {
|
||||||
|
$lockouts[$ip] = time() + get_option('kompass_limit_login_long_duration', 86400);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$lockouts[$ip] = time() + get_option('kompass_limit_login_lockout_duration', 900);
|
||||||
|
}
|
||||||
|
|
||||||
|
update_option('kompass_limit_login_lockouts', $lockouts);
|
||||||
|
|
||||||
|
|
||||||
|
/* do any notification */
|
||||||
|
$this->notify($username);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private function notifyByEmail($user)
|
||||||
|
{
|
||||||
|
$ip = $this->getAddress();
|
||||||
|
|
||||||
|
$lockouts = get_option('kompass_limit_login_lockouts', []);
|
||||||
|
if (!isset($lockouts[$ip])) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$blocked_until = $lockouts[$ip];
|
||||||
|
|
||||||
|
$retries = get_option('kompass_limit_login_retries', []);
|
||||||
|
$currentRetries = $retries[$ip];
|
||||||
|
|
||||||
|
$notify_after = get_option('kompass_limit_login_notify_email_after', 1);
|
||||||
|
if ($currentRetries % $notify_after !== 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$blogname = get_option('blogname', 'none');
|
||||||
|
|
||||||
|
$subject = sprintf(__("[%s] Too many failed login attempts"
|
||||||
|
, 'limit-login-attempts')
|
||||||
|
, $blogname);
|
||||||
|
|
||||||
|
$message = 'Neue Sperrung auf deiner Webseite: ' . PHP_EOL .
|
||||||
|
'IP-Adresse: ' . $ip . PHP_EOL .
|
||||||
|
'Gesperrt bis: ' . date('d.m.Y H:i', $blocked_until);
|
||||||
|
|
||||||
|
$admin_email = get_option('admin_email');
|
||||||
|
wp_mail($admin_email, $subject, $message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Handle notification in event of lockout */
|
||||||
|
private function notify($user) {
|
||||||
|
$args = get_option('kompass_limit_login_lockout_notify', []);
|
||||||
|
if (!is_array($args)) {
|
||||||
|
$args = [$args];
|
||||||
|
}
|
||||||
|
foreach ($args as $mode) {
|
||||||
|
switch (trim($mode)) {
|
||||||
|
case 'email':
|
||||||
|
$this->notifyByEmail($user);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function composeErrorMessage() {
|
||||||
|
$ip = $this->getAddress();
|
||||||
|
$lockouts = get_option('kompass_limit_login_lockouts');
|
||||||
|
|
||||||
|
$msg = __('<strong>ERROR</strong>: Too many failed login attempts.', 'limit-login-attempts') . ' ';
|
||||||
|
|
||||||
|
if (!is_array($lockouts) || !isset($lockouts[$ip]) || time() >= $lockouts[$ip]) {
|
||||||
|
/* Huh? No timeout active? */
|
||||||
|
$msg .= __('Please try again later.', 'limit-login-attempts');
|
||||||
|
return $msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
$when = ceil(($lockouts[$ip] - time()) / 60);
|
||||||
|
if ($when > 60) {
|
||||||
|
$when = ceil($when / 60);
|
||||||
|
$msg .= sprintf(_n('Please try again in %d hour.', 'Please try again in %d hours.', $when, 'limit-login-attempts'), $when);
|
||||||
|
} else {
|
||||||
|
$msg .= sprintf(_n('Please try again in %d minute.', 'Please try again in %d minutes.', $when, 'limit-login-attempts'), $when);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function getAddress($typeName = '') {
|
||||||
|
global $limitLoginAttemptsSettings;
|
||||||
|
|
||||||
|
$typeOriginal = $typeName;
|
||||||
|
if (empty($typeName)) {
|
||||||
|
$typeName = get_option('kompass_limit_loginclient_type', self::DIRECT_ADDR);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($_SERVER[$typeName]) && filter_var($_SERVER[$typeName], FILTER_VALIDATE_IP)) {
|
||||||
|
return $_SERVER[$typeName];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Not found. Did we get proxy type from option?
|
||||||
|
* If so, try to fall back to direct address.
|
||||||
|
*/
|
||||||
|
if ( empty($typeName) && $typeOriginal == self::PROXY_ADDR
|
||||||
|
&& isset($_SERVER[self::DIRECT_ADDR])
|
||||||
|
&& filter_var($_SERVER[self::DIRECT_ADDR], FILTER_VALIDATE_IP)) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NOTE: Even though we fall back to direct address -- meaning you
|
||||||
|
* can get a mostly working plugin when set to PROXY mode while in
|
||||||
|
* fact directly connected to Internet it is not safe!
|
||||||
|
*
|
||||||
|
* Client can itself send HTTP_X_FORWARDED_FOR header fooling us
|
||||||
|
* regarding which IP should be banned.
|
||||||
|
*/
|
||||||
|
|
||||||
|
return $_SERVER[self::DIRECT_ADDR];
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isLoginAllowedFromIp() {
|
||||||
|
$ip = $this->getAddress();
|
||||||
|
|
||||||
|
if (in_array($ip, get_option('kompass_limit_login_blocklist', []))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_array($ip, get_option('kompass_limit_login_allowlist', []))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* lockout active? */
|
||||||
|
$lockouts = get_option('kompass_limit_login_lockouts', []);
|
||||||
|
return (!is_array($lockouts) || !isset($lockouts[$ip]) || time() >= $lockouts[$ip]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function checkFailedCookies($cookie_elements) {
|
||||||
|
$this->clearAuthCookie();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Invalid username gets counted every time.
|
||||||
|
*/
|
||||||
|
|
||||||
|
$this->onFailedLogin($cookie_elements['username']);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function clearAuthCookie() {
|
||||||
|
wp_clear_auth_cookie();
|
||||||
|
|
||||||
|
if (!empty($_COOKIE[AUTH_COOKIE])) {
|
||||||
|
$_COOKIE[AUTH_COOKIE] = '';
|
||||||
|
}
|
||||||
|
if (!empty($_COOKIE[SECURE_AUTH_COOKIE])) {
|
||||||
|
$_COOKIE[SECURE_AUTH_COOKIE] = '';
|
||||||
|
}
|
||||||
|
if (!empty($_COOKIE[LOGGED_IN_COOKIE])) {
|
||||||
|
$_COOKIE[LOGGED_IN_COOKIE] = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onValidCookie($cookie_elements, $user) {
|
||||||
|
/*
|
||||||
|
* As all meta values get cached on user load this should not require
|
||||||
|
* any extra work for the common case of no stored value.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (get_user_meta($user->ID, 'kompass_limit_login_previous_cookie')) {
|
||||||
|
delete_user_meta($user->ID, 'kompass_limit_login_previous_cookie');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearLoginCookie($cookie_elements) {
|
||||||
|
$this->clearAuthCookie();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Under some conditions an invalid auth cookie will be used multiple
|
||||||
|
* times, which results in multiple failed attempts from that one
|
||||||
|
* cookie.
|
||||||
|
*
|
||||||
|
* Unfortunately I've not been able to replicate this consistently and
|
||||||
|
* thus have not been able to make sure what the exact cause is.
|
||||||
|
*
|
||||||
|
* Probably it is because a reload of for example the admin dashboard
|
||||||
|
* might result in multiple requests from the browser before the invalid
|
||||||
|
* cookie can be cleard.
|
||||||
|
*
|
||||||
|
* Handle this by only counting the first attempt when the exact same
|
||||||
|
* cookie is attempted for a user.
|
||||||
|
*/
|
||||||
|
|
||||||
|
extract($cookie_elements, EXTR_OVERWRITE);
|
||||||
|
|
||||||
|
// Check if cookie is for a valid user
|
||||||
|
$user = get_user_by('login', $username);
|
||||||
|
if (!$user) {
|
||||||
|
// "shouldn't happen" for this action
|
||||||
|
$this->onFailedLogin($username);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$previous_cookie = get_user_meta($user->ID, 'kompass_limit_login_previous_cookie', true);
|
||||||
|
if ($previous_cookie && $previous_cookie == $cookie_elements) {
|
||||||
|
// Identical cookies, ignore this attempt
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store cookie
|
||||||
|
if ($previous_cookie)
|
||||||
|
update_user_meta($user->ID, 'kompass_limit_login_previous_cookie', $cookie_elements);
|
||||||
|
else
|
||||||
|
add_user_meta($user->ID, 'kompass_limit_login_previous_cookie', $cookie_elements, true);
|
||||||
|
|
||||||
|
$this->onFailedLogin($username);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleCookies() {
|
||||||
|
if ($this->isLoginAllowedFromIp()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->clearAuthCookie();
|
||||||
|
}
|
||||||
|
}
|
130
modules/LimitLoginAttempts/Controllers/OptionsPage.php
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Bdp\Modules\LimitLoginAttempts\Controllers;
|
||||||
|
|
||||||
|
|
||||||
|
class OptionsPage
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
add_options_page(BDP_LV_PLUGIN_SLUG . '-limit-login-attempts',
|
||||||
|
'Protect Login',
|
||||||
|
'site-health.php',
|
||||||
|
BDP_LV_PLUGIN_SLUG . '-limit-login-attempts',
|
||||||
|
[$this, 'limit_login_option_page'],2048);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function releaseIp($ip)
|
||||||
|
{
|
||||||
|
$allIps = get_option('kompass_limit_login_lockouts', []);
|
||||||
|
unset($allIps[$ip]);
|
||||||
|
update_option('kompass_limit_login_lockouts', $allIps);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getBlockedIps()
|
||||||
|
{
|
||||||
|
$ips = '';
|
||||||
|
foreach (get_option('kompass_limit_login_lockouts', []) as $ip => $blockedUntil) {
|
||||||
|
$ips .= '<tr>' .
|
||||||
|
'<td style="padding-right: 10px;">' . $ip . '</td>' .
|
||||||
|
'<td style="padding-right: 10px;">' . date('d.m.Y H:i', $blockedUntil) . ' Uhr</td>' .
|
||||||
|
'<td>
|
||||||
|
<a href="admin.php?page=bdp-kompass-limit-login-attempts&tab=tab4&action=release&ip=' .
|
||||||
|
base64_encode($ip) . '">Freigeben</a></td>' .
|
||||||
|
'</tr>';
|
||||||
|
};
|
||||||
|
|
||||||
|
return $ips;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function limit_login_option_page() {
|
||||||
|
global $errors;
|
||||||
|
|
||||||
|
$showMessage = null;
|
||||||
|
|
||||||
|
if (isset($_POST['update_options'])) {
|
||||||
|
update_settings($_POST);
|
||||||
|
$showMessage = 'Die Einstellungen wurden gespeichert';
|
||||||
|
}
|
||||||
|
if (isset($_GET['action']) && $_GET['action'] == 'release') {
|
||||||
|
$showMessage = 'Die IP-Adresse wurde freigegeben.';
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isset($_POST['save_kompass_balist_list_type'])) {
|
||||||
|
$showMessage = 'Die Liste wurde gespeichert.';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null !== $showMessage && $errors === false) {
|
||||||
|
echo '<div class="notice notice-success" style="padding: 5px 10px;">';
|
||||||
|
echo $showMessage;
|
||||||
|
echo '</div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($errors) {
|
||||||
|
echo '<div class="notice notice-error" style="padding: 5px 10px;">';
|
||||||
|
echo 'Beim Durchführen der Aktion ist ein Fehler aufgetreten.';
|
||||||
|
echo '</div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
$tab = isset($_GET['tab']) ? $_GET['tab'] : 'tab1';
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="wrap">
|
||||||
|
<h1 class="wp-heading-inline">Protect Login - Einstellungen</h1>
|
||||||
|
<hr class="wp-header-end">
|
||||||
|
<?= kompass_print_tab_header($tab); ?>
|
||||||
|
|
||||||
|
<div class="tab-content">
|
||||||
|
<?php
|
||||||
|
switch ($tab) {
|
||||||
|
case 'tab1':
|
||||||
|
echo '<form action="admin.php?page=bdp-kompass-limit-login-attempts&tab=tab1" method="post">';
|
||||||
|
do_settings_sections(BDP_LV_PLUGIN_SLUG . '-limit-login-attempts');
|
||||||
|
submit_button();
|
||||||
|
echo '</form>';
|
||||||
|
break;
|
||||||
|
case 'tab2':
|
||||||
|
echo '<h2>Blocklist</h2>';
|
||||||
|
echo '<form action="admin.php?page=bdp-kompass-limit-login-attempts&tab=tab2" method="post">';
|
||||||
|
kompass_print_block_allow_form('blocklist');
|
||||||
|
submit_button();
|
||||||
|
echo '</form>';
|
||||||
|
break;
|
||||||
|
case 'tab3':
|
||||||
|
echo '<h2>Allowlist</h2>';
|
||||||
|
echo '<form action="admin.php?page=bdp-kompass-limit-login-attempts&tab=tab3" method="post">';
|
||||||
|
kompass_print_block_allow_form('allowlist');
|
||||||
|
submit_button();
|
||||||
|
echo '</form>';
|
||||||
|
break;
|
||||||
|
case 'tab4':
|
||||||
|
if (isset($_GET['action']) && $_GET['action'] == 'release') {
|
||||||
|
$this->releaseIp(base64_decode($_GET['ip']));
|
||||||
|
}
|
||||||
|
$blockedIps = $this->getBlockedIps();
|
||||||
|
?>
|
||||||
|
<h3>Gesperrte IPs</h3>
|
||||||
|
<?php
|
||||||
|
if (strlen($blockedIps) == 0) {
|
||||||
|
echo '<div class="protect-login-no-blocked-ips">';
|
||||||
|
echo 'Derzeit sind keine Adressen gesperrt.';
|
||||||
|
echo '</div>';
|
||||||
|
} else { ?>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>IP</th>
|
||||||
|
<th>Gesperrt bis</th>
|
||||||
|
<th>Aktion</th>
|
||||||
|
</tr>
|
||||||
|
<?= $blockedIps ?>
|
||||||
|
</table>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
}
|
29
modules/LimitLoginAttempts/Views/checkbox-option.php
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
function kompass_print_checkbox($settingName) {
|
||||||
|
$currentSetting = get_option($settingName, []);
|
||||||
|
if (!is_array($currentSetting)) {
|
||||||
|
$currentSetting = [$currentSetting];
|
||||||
|
}
|
||||||
|
|
||||||
|
$options = ['kompass_limit_login_lockout_notify' => [
|
||||||
|
'email' => 'E-Mail an Administrator'
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
if(!isset($options[$settingName])) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$setting = $options[$settingName];
|
||||||
|
foreach ($setting as $radioOption => $optionText) {
|
||||||
|
$isChecked = in_array($radioOption, $currentSetting) ? 'checked ' : '' ;
|
||||||
|
|
||||||
|
echo '<input ' .
|
||||||
|
$isChecked .
|
||||||
|
'type="checkbox"
|
||||||
|
name="' . $settingName . '[]"
|
||||||
|
value="' . $radioOption . '"
|
||||||
|
id="setting_' . $settingName . '_' . $radioOption . '" />' .
|
||||||
|
'<label for="setting_' . $settingName . '_' . $radioOption . '">' . $optionText . '</label><br />';
|
||||||
|
}
|
||||||
|
}
|
35
modules/LimitLoginAttempts/Views/radio-option.php
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
function kompass_print_radio($settingName) {
|
||||||
|
$currentSetting = get_option($settingName);
|
||||||
|
$options = [
|
||||||
|
'kompass_limit_login_client_type' => [
|
||||||
|
'REMOTE_ADDR' => 'Direkte Verbrindung',
|
||||||
|
'HTTP_X_FORWARDED_FOR' => 'Hinter einem Proxy'
|
||||||
|
],
|
||||||
|
'kompass_limit_login_cookies' => [
|
||||||
|
true => 'Ja',
|
||||||
|
false => 'Nein'
|
||||||
|
],
|
||||||
|
'kompass_password_minimal_strength' => [
|
||||||
|
'1' => 'Alle Passwörter erlauben',
|
||||||
|
'2' => 'Mittelstarke Passwörter',
|
||||||
|
'3' => 'Nur Starke Passwörter'
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
if(!isset($options[$settingName])) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$setting = $options[$settingName];
|
||||||
|
foreach ($setting as $radioOption => $optionText) {
|
||||||
|
$isChecked = $currentSetting == $radioOption ? 'checked ' : '' ;
|
||||||
|
echo '<input
|
||||||
|
' . $isChecked .
|
||||||
|
' type="radio"
|
||||||
|
name="' . $settingName . '"
|
||||||
|
value="' . $radioOption . '"
|
||||||
|
id="setting_' . $settingName . '_' . $radioOption . '" />' .
|
||||||
|
'<label for="setting_' . $settingName . '_' . $radioOption . '">' . $optionText . '</label> ';
|
||||||
|
}
|
||||||
|
}
|
18
modules/LimitLoginAttempts/Views/tab-control.php
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
function kompass_print_tab_header($activeTab = 'tab1')
|
||||||
|
{
|
||||||
|
$baseUrl = 'admin.php?page=bdp-kompass-limit-login-attempts&tab=';
|
||||||
|
return '<h2 class="nav-tab-wrapper">'.
|
||||||
|
'<a href="' . $baseUrl . 'tab1" class="nav-tab ' . ($activeTab == 'tab1' ? 'nav-tab-active' : '') . '">
|
||||||
|
Optionen
|
||||||
|
</a>'.
|
||||||
|
'<a href="' . $baseUrl . 'tab2" class="nav-tab ' . ($activeTab == 'tab2' ? 'nav-tab-active' : '') .'">
|
||||||
|
Blocklist
|
||||||
|
</a>'.
|
||||||
|
'<a href="' . $baseUrl . 'tab3" class="nav-tab ' . ($activeTab == 'tab3' ? 'nav-tab-active' : '') .'">
|
||||||
|
Allowlist
|
||||||
|
</a>'.
|
||||||
|
'<a href="' . $baseUrl . 'tab4" class="nav-tab ' . ($activeTab == 'tab4' ? 'nav-tab-active' : '') .'">
|
||||||
|
Gesperrte IPs
|
||||||
|
</a></h2>';
|
||||||
|
}
|
7
modules/LimitLoginAttempts/Views/text-element.php
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
function kompass_print_textbox($settingName, $settingValue) {
|
||||||
|
echo '<input type="text" name="' . $settingName . '" value="' . $settingValue. '" />';
|
||||||
|
if (defined('WP_DEBUG') && WP_DEBUG == true) {
|
||||||
|
echo '<br />' . $settingName;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
<?php
|
||||||
|
function updateBlockOrAllowList($postVars)
|
||||||
|
{
|
||||||
|
$listType = $postVars['save_kompass_balist_list_type'];
|
||||||
|
|
||||||
|
$saveIPList = [];
|
||||||
|
if (isset($postVars['listElements'])) {
|
||||||
|
foreach ($postVars['listElements'] as $curIp) {
|
||||||
|
$curIp = trim($curIp);
|
||||||
|
if ($curIp !== '') {
|
||||||
|
$saveIPList[] = $curIp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($postVars['new_ips']) == 1) {
|
||||||
|
foreach (explode(PHP_EOL, $postVars['new_ips'][0]) as $newIp) {
|
||||||
|
$newIp = trim($newIp);
|
||||||
|
if ('' !== $newIp) {
|
||||||
|
$saveIPList[] = $newIp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
update_option('kompass_limit_login_' . $listType, $saveIPList);
|
||||||
|
}
|
||||||
|
|
||||||
|
function kompass_print_block_allow_form($listType) {
|
||||||
|
$elements = get_option('kompass_limit_login_' . $listType, []);
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
<input type="hidden" name="save_kompass_balist_list_type" value="<?= $listType; ?>" />
|
||||||
|
|
||||||
|
<?php
|
||||||
|
foreach ($elements as $currentIp) {
|
||||||
|
?>
|
||||||
|
<p>
|
||||||
|
<input type="text" name="listElements[]" value="<?= $currentIp ?>" style="width: 350px;" /><br />
|
||||||
|
<label style="cursor: default; color: #a0a0a0; fot-size: 9pt; font-style: italic"><?= __('Zum Löschen frei lassen', BDP_LV_PLUGIN_SLUG); ?></label>
|
||||||
|
</p>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
<div class="kompass_setting_box">
|
||||||
|
<h3><?= __('IP-Adresse hinzufügen', BDP_LV_PLUGIN_SLUG); ?></h3>
|
||||||
|
<p>
|
||||||
|
<textarea
|
||||||
|
placeholder="<?= __('Please use line breaks to enter multiple ips', BDP_LV_PLUGIN_SLUG); ?>"
|
||||||
|
name="new_ips[]"
|
||||||
|
style="width: 350px;" rows="5"></textarea>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
}
|
116
modules/LimitLoginAttempts/includes/gui_elements.php
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// Callback-Funktion für die Einstellungsseite
|
||||||
|
function custom_settings_section_callback() {
|
||||||
|
echo '<input type="hidden" name="update_options" value="true" />';
|
||||||
|
}
|
||||||
|
|
||||||
|
function _kompass_limit_logins_settings_callback($args) {
|
||||||
|
$setting = get_option($args['setting'], null);
|
||||||
|
if (null === $setting) {
|
||||||
|
$setting = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$value = esc_attr($setting);
|
||||||
|
if (isset($args['unit_division'])) {
|
||||||
|
$value = (int)$value / (int)$args['unit_division'];
|
||||||
|
}
|
||||||
|
|
||||||
|
kompass_print_textbox($args['setting'], $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _kompass_limit_logins_settings_radio_callback($args)
|
||||||
|
{
|
||||||
|
kompass_print_radio($args['setting']);
|
||||||
|
}
|
||||||
|
function _kompass_limit_logins_settings_checkbox_callback($args) {
|
||||||
|
kompass_print_checkbox($args['setting']);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
add_settings_section(
|
||||||
|
'custom_settings_section',
|
||||||
|
'Optionen',
|
||||||
|
'custom_settings_section_callback',
|
||||||
|
BDP_LV_PLUGIN_SLUG . '-limit-login-attempts'
|
||||||
|
);
|
||||||
|
|
||||||
|
$settings_page = BDP_LV_PLUGIN_SLUG . '-limit-login-attempts';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
add_settings_field(
|
||||||
|
'kompass_lla_1',
|
||||||
|
'Maximale Wiederholungen',
|
||||||
|
'_kompass_limit_logins_settings_callback',
|
||||||
|
$settings_page,
|
||||||
|
'custom_settings_section',
|
||||||
|
['setting' => 'kompass_limit_login_allowed_retries']);
|
||||||
|
|
||||||
|
add_settings_field(
|
||||||
|
'kompass_lla_2',
|
||||||
|
'Dauer der Sperre (in Minuten)',
|
||||||
|
'_kompass_limit_logins_settings_callback',
|
||||||
|
$settings_page,
|
||||||
|
'custom_settings_section',
|
||||||
|
['setting' => 'kompass_limit_login_lockout_duration', 'unit_division' => 60 ]);
|
||||||
|
|
||||||
|
add_settings_field(
|
||||||
|
'kompass_lla_3',
|
||||||
|
'Maximale Anzahl an Sperrungen',
|
||||||
|
'_kompass_limit_logins_settings_callback',
|
||||||
|
$settings_page,
|
||||||
|
'custom_settings_section',
|
||||||
|
['setting' => 'kompass_limit_login_allowed_lockouts']);
|
||||||
|
|
||||||
|
add_settings_field(
|
||||||
|
'kompass_lla_4',
|
||||||
|
'Langzeitsperre in Stunden',
|
||||||
|
'_kompass_limit_logins_settings_callback',
|
||||||
|
$settings_page,
|
||||||
|
'custom_settings_section',
|
||||||
|
['setting' => 'kompass_limit_login_long_duration', 'unit_division' => 3600]);
|
||||||
|
|
||||||
|
add_settings_field(
|
||||||
|
'kompass_lla_5',
|
||||||
|
'Mininmale Passwort-Stärke:',
|
||||||
|
'_kompass_limit_logins_settings_radio_callback',
|
||||||
|
$settings_page,
|
||||||
|
'custom_settings_section',
|
||||||
|
['setting' => 'kompass_password_minimal_strength']);
|
||||||
|
|
||||||
|
add_settings_field(
|
||||||
|
'kompass_lla_6',
|
||||||
|
'Seite erreichbar über:',
|
||||||
|
'_kompass_limit_logins_settings_radio_callback',
|
||||||
|
$settings_page,
|
||||||
|
'custom_settings_section',
|
||||||
|
['setting' => 'kompass_limit_login_client_type']);
|
||||||
|
|
||||||
|
add_settings_field(
|
||||||
|
'kompass_lla_7',
|
||||||
|
'Cookies verarbeiten',
|
||||||
|
'_kompass_limit_logins_settings_radio_callback',
|
||||||
|
$settings_page,
|
||||||
|
'custom_settings_section',
|
||||||
|
['setting' => 'kompass_limit_login_cookies']);
|
||||||
|
|
||||||
|
add_settings_field(
|
||||||
|
'kompass_lla_8',
|
||||||
|
'Bei Sperrung benachrichtigen',
|
||||||
|
'_kompass_limit_logins_settings_checkbox_callback',
|
||||||
|
$settings_page,
|
||||||
|
'custom_settings_section',
|
||||||
|
['setting' => 'kompass_limit_login_lockout_notify']);
|
||||||
|
|
||||||
|
add_settings_field(
|
||||||
|
'kompass_lla_9',
|
||||||
|
'Fehlversuche bis zur Benachrichtigung',
|
||||||
|
'_kompass_limit_logins_settings_callback',
|
||||||
|
$settings_page,
|
||||||
|
'custom_settings_section',
|
||||||
|
['setting' => 'kompass_limit_login_notify_email_after']);
|
64
modules/LimitLoginAttempts/includes/validators.php
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
<?php
|
||||||
|
function check_for_integer($input) {
|
||||||
|
if (!is_numeric($input)) {
|
||||||
|
wp_die('Bitte nur Zahlen, Danke!');
|
||||||
|
}
|
||||||
|
return $input;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function hours_to_seconds_converter($input) {
|
||||||
|
// Hier kannst du die Eingabe validieren, z.B. sicherstellen, dass es sich um eine gültige E-Mail-Adresse handelt.
|
||||||
|
return minutes_to_seconds_converter($input) * 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
function minutes_to_seconds_converter($input) {
|
||||||
|
|
||||||
|
// Hier kannst du die Eingabe validieren, z.B. sicherstellen, dass es sich um eine gültige E-Mail-Adresse handelt.
|
||||||
|
return check_for_integer($input) * 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
function kompass_settings_validators()
|
||||||
|
{
|
||||||
|
$slug = BDP_LV_PLUGIN_SLUG . '-limit-login-attempts';
|
||||||
|
|
||||||
|
register_setting($slug,
|
||||||
|
'kompass_limit_login_allowed_retries',
|
||||||
|
'check_for_integer');
|
||||||
|
|
||||||
|
register_setting($slug,
|
||||||
|
'kompass_limit_login_allowed_lockouts',
|
||||||
|
'check_for_integer');
|
||||||
|
|
||||||
|
register_setting($slug,
|
||||||
|
'kompass_limit_login_lockout_duration',
|
||||||
|
'minutes_to_seconds_converter');
|
||||||
|
|
||||||
|
register_setting($slug,
|
||||||
|
'kompass_limit_login_long_duration',
|
||||||
|
'hours_to_seconds_converter');
|
||||||
|
|
||||||
|
register_setting($slug,
|
||||||
|
'kompass_limit_login_notify_email_after',
|
||||||
|
'check_for_integer');
|
||||||
|
}
|
||||||
|
|
||||||
|
function update_settings($postParams) {
|
||||||
|
$settings = ['kompass_limit_login_lockout_duration',
|
||||||
|
'kompass_limit_login_allowed_retries',
|
||||||
|
'kompass_limit_login_allowed_lockouts',
|
||||||
|
'kompass_password_minimal_strength',
|
||||||
|
'kompass_limit_login_client_type',
|
||||||
|
'kompass_limit_login_long_duration',
|
||||||
|
'kompass_limit_login_lockout_notify',
|
||||||
|
'kompass_limit_login_notify_email_after',
|
||||||
|
'kompass_limit_login_cookies'];
|
||||||
|
|
||||||
|
foreach ($settings as $curSetting) {
|
||||||
|
if (isset($postParams[$curSetting])) {
|
||||||
|
update_option( $curSetting, $postParams[ $curSetting ] );
|
||||||
|
} else {
|
||||||
|
update_option( $curSetting, '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
function kompass_get_minimal_password_strength() {
|
||||||
|
$minPasswordStrength = get_option('kompass_password_minimal_strength', 1);
|
||||||
|
|
||||||
|
$possibleStrengths = ['1' => 'short, bad, good, strong',
|
||||||
|
'2' => 'good, strong',
|
||||||
|
'3' => 'strong'];
|
||||||
|
|
||||||
|
return ' ' . $possibleStrengths[$minPasswordStrength];
|
||||||
|
}
|
35
modules/about/internal/index.php
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<h1>Über dieses Plugin</h1>
|
||||||
|
|
||||||
|
|
||||||
|
<form method="post" action="admin.php?page=bdp-kompass%2Fmodules%2Findex.php&loadmodule=security">
|
||||||
|
<div class="bdp_security_outer">
|
||||||
|
<fieldset class="bdp_security_inner">
|
||||||
|
<p>
|
||||||
|
Das Plugin Kompass (<span style="font-weight: bold;">Komp</span>onente zur<span style="font-weight: bold;">A</span>dministration, <span style="font-weight: bold;">S</span>icherung und <span style="font-weight: bold;">S</span>ynchronisierung) wurde entwickelt, um euch bei der Administration eurer Webseite zu helfen.<br />
|
||||||
|
Neben einer Vereinfachung der Navigation stellt das Plugin Sicherheitskomponenten bereit und installiert Plugins, die zur Absicherung eurer Webseite oder der Optimierung empfohlen werden.<br />
|
||||||
|
Die Plugin-Empfehlung und Optimierung der Einstellungen erfolgt auf Datenbasis, die vom LB IT des LV Sachsen verwaltwet wird.<br />
|
||||||
|
Auch bietet das Plugin Schnittstellen zur Integration und Darstellung von ausgesuchten externen Inhalten (eurem Stammes-Kalender im Wiki, der Veranstaltungsanmeldung auzf Mareike, ...) auf eurer Webseite.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Dieses Plugin wurde speziell für den Lanbdesverband Sachsen e.V. im Bund der Pfadfinderinnen und Pfadfinder e.V. ("BdP") entwickelt.<br />
|
||||||
|
Die Nutzung außerhalb des BdP bedarf der ausrücklichen Zustimmung des Authors.<br /><br />
|
||||||
|
Dies Plugin wurde speziell andie Anforderungen im LV Sachsen angepasst, innerhalb anderer Landesverbände kann es zu Kompatibilitätsproblemen kommen.
|
||||||
|
Sollte dies der Fall sein, so kontaktiert bitte den Author.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Die Urheberrechte aller extern nachgeladenen Plugins und Themes liegen weiterhin bei den Authoren der jeweiligen Komponenten.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p><span style="font-weight: bold;">Informationen zum Author:</span><br />
|
||||||
|
Thomas Günther, Aufbaugruppe Wilde Möhre im <a href="https://www.sachsen.pfadfinden.de/kontakt/gruppen-vor-ort/" target="_blank">LV Sachsen</a><br />
|
||||||
|
<a href="mailto:thomas.guenther@pfadfinden.de">E-Mail</a><br />
|
||||||
|
<a href="https://t.me/thomas_8611" target="_blank">Telegram</a>
|
||||||
|
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
13
modules/calendar/ajax-calendar.php
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require_once dirname(__FILE__) . '/../../../../../wp-config.php';
|
||||||
|
require_once dirname(__FILE__) . '/../../../../../wp-includes/option.php';
|
||||||
|
require_once dirname(__FILE__) . '/../../../../../wp-includes/plugin.php';
|
||||||
|
require_once dirname(__FILE__) . '/../../../../../wp-includes/load.php';
|
||||||
|
require_once dirname(__FILE__) . '/../../../../../wp-includes/cache.php';
|
||||||
|
|
||||||
|
require_once dirname(__FILE__) . '/../../lib/ics-parser/Event.php';
|
||||||
|
require_once dirname(__FILE__) . '/../../lib/ics-parser/ICal.php';
|
||||||
|
require_once 'calendar.php';
|
||||||
|
$calendar = new Calendar();
|
||||||
|
echo $calendar->show();
|
22
modules/calendar/assets/ajaxscript.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// Funktion zum Laden des Kalenders über AJAX
|
||||||
|
function loadCalendar(month, year) {
|
||||||
|
// Erstelle ein XMLHttpRequest-Objekt
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
|
||||||
|
// Definiere die URL zum Laden des Kalenders (angepasst an deine Bedürfnisse)
|
||||||
|
var url = '/wp-content/plugins/bdp-kompass/modules/calendar/ajax-calendar.php?month=' + month + '&year=' + year;
|
||||||
|
|
||||||
|
// Öffne eine GET-Anfrage
|
||||||
|
xhr.open('GET', url, true);
|
||||||
|
|
||||||
|
// Setze die Callback-Funktion für die Antwort
|
||||||
|
xhr.onreadystatechange = function () {
|
||||||
|
if (xhr.readyState == 4 && xhr.status == 200) {
|
||||||
|
// Aktualisiere den Inhalt des Container-Divs mit der Kalenderantwort
|
||||||
|
document.getElementById('calendarContainer').innerHTML = xhr.responseText;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Sende die Anfrage
|
||||||
|
xhr.send();
|
||||||
|
}
|
217
modules/calendar/assets/calendar.css
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
/*******************************Calendar Top Navigation*********************************/
|
||||||
|
div#calendar{
|
||||||
|
margin:0px auto;
|
||||||
|
padding:0px;
|
||||||
|
width: 100%;
|
||||||
|
font-family:Helvetica, "Times New Roman", Times, serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#calendar div.box{
|
||||||
|
position:relative;
|
||||||
|
top:0px;
|
||||||
|
left:0px;
|
||||||
|
width:100%;
|
||||||
|
height:40px;
|
||||||
|
background-color: #ffcb04;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#calendar div.header{
|
||||||
|
line-height:40px;
|
||||||
|
vertical-align:middle;
|
||||||
|
position:absolute;
|
||||||
|
left:11px;
|
||||||
|
top:0px;
|
||||||
|
width:100%;
|
||||||
|
height:40px;
|
||||||
|
text-align:center;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#calendar div.header a.prev,div#calendar div.header a.next{
|
||||||
|
position:absolute;
|
||||||
|
top:0px;
|
||||||
|
padding-right: 20px;
|
||||||
|
height: 17px;
|
||||||
|
display:block;
|
||||||
|
cursor:pointer;
|
||||||
|
text-decoration:none;
|
||||||
|
color:#3163bd;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#calendar div.header span.title{
|
||||||
|
color:#3163bd;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size:18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
div#calendar div.header a.prev{
|
||||||
|
left:0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#calendar div.header a.next{
|
||||||
|
right:0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************Calendar Content Cells*********************************/
|
||||||
|
div#calendar div.box-content{
|
||||||
|
border-top:none;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
div#calendar ul.label{
|
||||||
|
float:left;
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
margin-top:5px;
|
||||||
|
margin-left: 5px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#calendar ul.label li{
|
||||||
|
margin:0px;
|
||||||
|
padding:0px;
|
||||||
|
float:left;
|
||||||
|
list-style-type:none;
|
||||||
|
|
||||||
|
height:40px;
|
||||||
|
line-height:40px;
|
||||||
|
vertical-align:middle;
|
||||||
|
text-align:center;
|
||||||
|
color:#000;
|
||||||
|
font-size: 15px;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
div#calendar ul.dates{
|
||||||
|
float:left;
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
margin-left: 5px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bdp_cal_day
|
||||||
|
{
|
||||||
|
padding-left: 5px;
|
||||||
|
color: #a0a0a0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bdp_cal_day td {
|
||||||
|
min-height: 100px;
|
||||||
|
}
|
||||||
|
.bdp_event_table {
|
||||||
|
width:95%;
|
||||||
|
}
|
||||||
|
.bdp_cal_day ul {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bdp_cal_day li {
|
||||||
|
list-style-type: none;
|
||||||
|
width:95%;
|
||||||
|
font-size: 8pt;
|
||||||
|
font-weight: bold;
|
||||||
|
padding: 2px;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bdp_cal_event_red,
|
||||||
|
.bdp_cal_event_yellow,
|
||||||
|
.bdp_cal_event_blue,
|
||||||
|
.bdp_cal_event_green,
|
||||||
|
.bdp_cal_event_grey,
|
||||||
|
.bdp_cal_event_fuchsia,
|
||||||
|
.bdp_cal_event_orange
|
||||||
|
{
|
||||||
|
padding: 2px 4px;
|
||||||
|
border-radius: 5px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.bdp_cal_event_blue {
|
||||||
|
background-color: #1e88e5;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bdp_cal_event_green {
|
||||||
|
background-color: #00d084;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bdp_cal_event_red
|
||||||
|
{
|
||||||
|
.bdp_cal_event_entry;
|
||||||
|
background-color: #e91e63;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bdp_cal_event_yellow
|
||||||
|
{
|
||||||
|
.bdp_cal_event_entry;
|
||||||
|
background-color: #eeee88;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bdp_cal_event_orange
|
||||||
|
{
|
||||||
|
.bdp_cal_event_entry;
|
||||||
|
background-color: #ffa747;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.bdp_cal_event_grey
|
||||||
|
{
|
||||||
|
.bdp_cal_event_entry;
|
||||||
|
background-color: #D5D5D5;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bdp_cal_event_fuchsia
|
||||||
|
{
|
||||||
|
.bdp_cal_event_entry;
|
||||||
|
background-color: #FF6EFF;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** overall width = width+padding-right**/
|
||||||
|
div#calendar ul.dates li{
|
||||||
|
margin:0px;
|
||||||
|
padding:0px;
|
||||||
|
padding-left: 2px;
|
||||||
|
padding-top: 10px;
|
||||||
|
vertical-align:bottom;
|
||||||
|
float:left;
|
||||||
|
list-style-type:none;
|
||||||
|
width:15%;
|
||||||
|
height:100px;
|
||||||
|
font-size:12pt;
|
||||||
|
background-color: #fff;
|
||||||
|
color:#000;
|
||||||
|
border-style: solid;
|
||||||
|
border-width:1px;
|
||||||
|
border-color: #add8e6;
|
||||||
|
}
|
||||||
|
|
||||||
|
:focus{
|
||||||
|
outline:none;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.clear{
|
||||||
|
clear:both;
|
||||||
|
}
|
6
modules/calendar/calendar.php
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?php
|
||||||
|
add_filter('the_content', ['Calendar', 'printCalendar']);
|
||||||
|
wp_enqueue_style('bdp_calendar_css', BDP_LV_PLUGIN_URL . '/modules/calendar/assets/calendar.css');
|
||||||
|
wp_enqueue_script( 'loadCalendar', BDP_LV_PLUGIN_URL . '/modules/calendar/assets/ajaxscript.js');
|
||||||
|
|
||||||
|
require_once dirname(__FILE__) . '/classes/Calendar.class.php';
|
315
modules/calendar/classes/Calendar.class.php
Normal file
@ -0,0 +1,315 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Calendar
|
||||||
|
{
|
||||||
|
public $ical;
|
||||||
|
private $categories = [];
|
||||||
|
|
||||||
|
public static function setup()
|
||||||
|
{
|
||||||
|
$pageName = 'Kalender';
|
||||||
|
$page_exists = get_page_by_path($pageName, OBJECT, 'page');
|
||||||
|
|
||||||
|
// Wenn die Seite nicht existiert, erstelle sie
|
||||||
|
if (!$page_exists) {
|
||||||
|
$page_id = wp_insert_post(array(
|
||||||
|
'post_title' => $pageName,
|
||||||
|
'post_content' => '{{calendar}}',
|
||||||
|
'post_status' => 'publish',
|
||||||
|
'post_type' => 'page',
|
||||||
|
));
|
||||||
|
|
||||||
|
update_option('bdp_calendar_source_url', 'https://wiki.sachsen.pfadfinden.de/rest/calendar-services/1.0/calendar/export/subcalendar/private/ff69f5a689391ac0d7f78a70189cfde7c48cb923.ics');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static function printCalendar($content) {
|
||||||
|
// Der zu ersetzende String
|
||||||
|
$original_string = '{{calendar}}';
|
||||||
|
$calendar = new Calendar();
|
||||||
|
|
||||||
|
// Der Ersatzstring
|
||||||
|
$replacement_string = $calendar->show();
|
||||||
|
|
||||||
|
// Ersetze den Originalstring durch den Ersatzstring im Seiteninhalt
|
||||||
|
$content = str_replace($original_string, $replacement_string, $content);
|
||||||
|
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
|
||||||
|
$categories = get_option('bdp_calendar_categories', null);
|
||||||
|
if (null !== $categories) {
|
||||||
|
$categories = json_decode($categories, true);
|
||||||
|
} else {
|
||||||
|
$categories = [
|
||||||
|
'yellow' => 'Meute',
|
||||||
|
'blue' => 'Sippe',
|
||||||
|
'red' => 'Runde',
|
||||||
|
'green' => 'StaFü',
|
||||||
|
'fuchsia' => '',
|
||||||
|
'orange' => ''
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($categories as $color => $keyname) {
|
||||||
|
$this->categories[$keyname] = $color;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$calendarUrl = get_option('bdp_calendar_source_url', 'https://wiki.sachsen.pfadfinden.de/rest/calendar-services/1.0/calendar/export/subcalendar/private/ff69f5a689391ac0d7f78a70189cfde7c48cb923.ics');
|
||||||
|
|
||||||
|
$this->ical = new \ICal('', array(
|
||||||
|
'defaultSpan' => 2, // Default value
|
||||||
|
'defaultTimeZone' => '',
|
||||||
|
'defaultWeekStart' => 'MO', // Default value
|
||||||
|
'disableCharacterReplacement' => false, // Default value
|
||||||
|
'filterDaysAfter' => null, // Default value
|
||||||
|
'filterDaysBefore' => null, // Default value
|
||||||
|
'httpUserAgent' => null, // Default value
|
||||||
|
'skipRecurrence' => false, // Default value
|
||||||
|
));
|
||||||
|
$this->ical->initUrl($calendarUrl);
|
||||||
|
$this->ical->events();
|
||||||
|
$this->naviHref = htmlentities($_SERVER['PHP_SELF']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************* PROPERTY ********************/
|
||||||
|
private $dayLabels = array("Mon", "Die", "Mit", "Don", "Fre", "Sam", "Son");
|
||||||
|
|
||||||
|
private $monthLabels = ['', 'Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'];
|
||||||
|
|
||||||
|
private $currentYear = 0;
|
||||||
|
|
||||||
|
private $currentMonth = 0;
|
||||||
|
|
||||||
|
private $currentDay = 0;
|
||||||
|
|
||||||
|
private $currentDate = null;
|
||||||
|
|
||||||
|
private $daysInMonth = 0;
|
||||||
|
|
||||||
|
private $naviHref = null;
|
||||||
|
|
||||||
|
/********************* PUBLIC **********************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* print out the calendar
|
||||||
|
*/
|
||||||
|
public function show()
|
||||||
|
{
|
||||||
|
$year = null;
|
||||||
|
|
||||||
|
$month = null;
|
||||||
|
|
||||||
|
if (null == $year && isset($_GET['year'])) {
|
||||||
|
|
||||||
|
$year = $_GET['year'];
|
||||||
|
|
||||||
|
} else if (null == $year) {
|
||||||
|
|
||||||
|
$year = date("Y", time());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null == $month && isset($_GET['month'])) {
|
||||||
|
|
||||||
|
$month = $_GET['month'];
|
||||||
|
|
||||||
|
} else if (null == $month) {
|
||||||
|
|
||||||
|
$month = date("m", time());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->currentYear = $year;
|
||||||
|
|
||||||
|
$this->currentMonth = $month;
|
||||||
|
|
||||||
|
$this->daysInMonth = $this->_daysInMonth($month, $year);
|
||||||
|
|
||||||
|
$content = ' <div id="calendarContainer"><div id="calendar">' .
|
||||||
|
'<div class="box">' .
|
||||||
|
$this->_createNavi() .
|
||||||
|
'</div>' .
|
||||||
|
'<div class="box-content">' .
|
||||||
|
|
||||||
|
'<table style=" border-collapse: collapse; border-spacing: 0; table-layout: fixed;width: 100%;">
|
||||||
|
<tr>' . $this->_createLabels() . '</tr>';
|
||||||
|
|
||||||
|
|
||||||
|
$weeksInMonth = $this->_weeksInMonth($month, $year);
|
||||||
|
// Create weeks in a month
|
||||||
|
for ($i = 0; $i < $weeksInMonth; $i++) {
|
||||||
|
|
||||||
|
//Create days in a week
|
||||||
|
for ($j = 1; $j <= 7; $j++) {
|
||||||
|
if ($j % 7 == 1) {
|
||||||
|
$content .= '</tr><tr class="bdp_cal_day">';
|
||||||
|
}
|
||||||
|
$content .= $this->_showDay($i * 7 + $j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$content .= '</table></div>';
|
||||||
|
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getCssClass($category)
|
||||||
|
{
|
||||||
|
$cssClass = 'bdp_cal_event_' . ($this->categories[$category] ?? 'grey');
|
||||||
|
return $cssClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private function getEvent($date)
|
||||||
|
{
|
||||||
|
$eventString = '<ul>';
|
||||||
|
#echo '<pre>';
|
||||||
|
foreach ($this->ical->filterByDate($date) as $curEvent) {
|
||||||
|
$time = $curEvent->getEventTime() ?? 'Ganztags';
|
||||||
|
|
||||||
|
#print_r($curEvent);
|
||||||
|
$eventString .= '<li class="' . $this->getCssClass($curEvent->category) . '">' .
|
||||||
|
$time . ':<br />' .
|
||||||
|
$curEvent->summary . '</li>';
|
||||||
|
}
|
||||||
|
return $eventString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************* PRIVATE **********************/
|
||||||
|
/**
|
||||||
|
* create the li element for ul
|
||||||
|
*/
|
||||||
|
private function _showDay($cellNumber)
|
||||||
|
{
|
||||||
|
|
||||||
|
if ($this->currentDay == 0) {
|
||||||
|
|
||||||
|
$firstDayOfTheWeek = date('N', strtotime($this->currentYear . '-' . $this->currentMonth . '-01'));
|
||||||
|
|
||||||
|
if (intval($cellNumber) == intval($firstDayOfTheWeek)) {
|
||||||
|
|
||||||
|
$this->currentDay = 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (($this->currentDay != 0) && ($this->currentDay <= $this->daysInMonth)) {
|
||||||
|
$date =
|
||||||
|
str_pad($this->currentDay, 2, '0', STR_PAD_LEFT) . '.' .
|
||||||
|
str_pad($this->currentMonth, 2, '0', STR_PAD_LEFT) . '.' .
|
||||||
|
$this->currentYear;
|
||||||
|
|
||||||
|
$this->currentDate = date('Y-m-d', strtotime($this->currentYear . '-' . $this->currentMonth . '-' . ($this->currentDay)));
|
||||||
|
|
||||||
|
$cellContent = '<span class="bdp_cal_day">' . $this->currentDay . '</span>' . $this->getEvent($date);
|
||||||
|
|
||||||
|
$this->currentDay++;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
$this->currentDate = null;
|
||||||
|
|
||||||
|
$cellContent = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return '<td style="padding-top: 5px; border-color: #a0a0a0; height: 120px; border-style: solid; border-width:1px; vertical-align: top;">' . $cellContent . '</td>';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create navigation
|
||||||
|
*/
|
||||||
|
private function _createNavi()
|
||||||
|
{
|
||||||
|
|
||||||
|
$nextMonth = $this->currentMonth == 12 ? 1 : intval($this->currentMonth) + 1;
|
||||||
|
|
||||||
|
$nextYear = $this->currentMonth == 12 ? intval($this->currentYear) + 1 : $this->currentYear;
|
||||||
|
|
||||||
|
$preMonth = $this->currentMonth == 1 ? 12 : intval($this->currentMonth) - 1;
|
||||||
|
|
||||||
|
$preYear = $this->currentMonth == 1 ? intval($this->currentYear) - 1 : $this->currentYear;
|
||||||
|
|
||||||
|
return
|
||||||
|
'<div class="header">' .
|
||||||
|
'<a class="prev" href="javascript:void(0);" onclick="loadCalendar(' . $preMonth . ',' . $preYear . ');"><< Vorheriger Monat</a>' .
|
||||||
|
'<span class="title">' . $this->monthLabels[(int)date('m', strtotime($this->currentYear . '-' . $this->currentMonth . '-1'))] . ' ' . date('Y', strtotime($this->currentYear . '-' . $this->currentMonth . '-1')) . '</span>' .
|
||||||
|
'<a class="next" href="javascript:void(0);" onclick="loadCalendar(' . $nextMonth . ',' . $nextYear . ');">Nächster Monat >></a>' .
|
||||||
|
'</div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create calendar week labels
|
||||||
|
*/
|
||||||
|
private function _createLabels()
|
||||||
|
{
|
||||||
|
|
||||||
|
$content = '';
|
||||||
|
|
||||||
|
foreach ($this->dayLabels as $index => $label) {
|
||||||
|
|
||||||
|
$content .= '<td style="max-width: 14.287%;">' . $label . '</td>';
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* calculate number of weeks in a particular month
|
||||||
|
*/
|
||||||
|
private function _weeksInMonth($month = null, $year = null)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (null == ($year)) {
|
||||||
|
$year = date("Y", time());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null == ($month)) {
|
||||||
|
$month = date("m", time());
|
||||||
|
}
|
||||||
|
|
||||||
|
// find number of days in this month
|
||||||
|
$daysInMonths = $this->_daysInMonth($month, $year);
|
||||||
|
|
||||||
|
$numOfweeks = ($daysInMonths % 7 == 0 ? 0 : 1) + intval($daysInMonths / 7);
|
||||||
|
|
||||||
|
$monthEndingDay = date('N', strtotime($year . '-' . $month . '-' . $daysInMonths));
|
||||||
|
|
||||||
|
$monthStartDay = date('N', strtotime($year . '-' . $month . '-01'));
|
||||||
|
|
||||||
|
if ($monthEndingDay < $monthStartDay) {
|
||||||
|
|
||||||
|
$numOfweeks++;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return $numOfweeks;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* calculate number of days in a particular month
|
||||||
|
*/
|
||||||
|
private function _daysInMonth($month = null, $year = null)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (null == ($year))
|
||||||
|
$year = date("Y", time());
|
||||||
|
|
||||||
|
if (null == ($month))
|
||||||
|
$month = date("m", time());
|
||||||
|
|
||||||
|
return date('t', strtotime($year . '-' . $month . '-01'));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
86
modules/calendar/internal/index.php
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
<?php
|
||||||
|
echo '<h1>Kalender-Einstellungen</h1>';
|
||||||
|
if (isset($_POST['submit'])) {
|
||||||
|
echo '<div id="bdp_success">Die Einstellungen wurden gespeichert.</div>';
|
||||||
|
update_option('bdp_calendar_categories', json_encode($_POST['category']));
|
||||||
|
update_option('bdp_calendar_source_url', $_POST['ical_url']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$categories = get_option('bdp_calendar_categories', null);
|
||||||
|
if (null !== $categories) {
|
||||||
|
$categories = json_decode($categories, true);
|
||||||
|
} else {
|
||||||
|
$categories = [
|
||||||
|
'yellow' => 'Meute',
|
||||||
|
'blue' => 'Sippe',
|
||||||
|
'red' => 'Runde',
|
||||||
|
'green' => 'Stammesführung',
|
||||||
|
'fuchsia' => '',
|
||||||
|
'orange' => ''
|
||||||
|
];
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<form method="post" action="admin.php?page=bdp-kompass%2Fmodules%2Findex.php&loadmodule=calendar">
|
||||||
|
<fieldset class="bdp_cal_inner">
|
||||||
|
<legend>Datenabfrage</legend>
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr style="vertical-align: top;">
|
||||||
|
<td>Kalender-URL:</td>
|
||||||
|
<td><input class="long_text" type="text" name="ical_url" id="ical_url" required
|
||||||
|
value = "<?php echo get_option('bdp_calendar_source_url', ''); ?>"
|
||||||
|
><br />
|
||||||
|
<label style="font-weight: normal; color: #a0a0a0; font-style: italic">
|
||||||
|
Bitte gib hier die URL zur .ics - Datei eures Kalenbders im Wiki ein.
|
||||||
|
</label>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<fieldset class="bdp_cal_inner">
|
||||||
|
<legend>Labels</legend>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td>Gelb:</td>
|
||||||
|
<td><input type="text" name="category[yellow]" value="<?php echo $categories['yellow']; ?>" /></td>
|
||||||
|
<td class="bdp_cal_event_yellow"></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>Blau:</td>
|
||||||
|
<td><input type="text" name="category[blue]" value="<?php echo $categories['blue']; ?>" /></td>
|
||||||
|
<td class="bdp_cal_event_blue"></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>Rot:</td>
|
||||||
|
<td><input type="text" name="category[red]" value="<?php echo $categories['red']; ?>" /></td>
|
||||||
|
<td class="bdp_cal_event_red"></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>Grün:</td>
|
||||||
|
<td><input type="text" name="category[green]" value="<?php echo $categories['green']; ?>" /></td>
|
||||||
|
<td class="bdp_cal_event_green"></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>Fuchsia:</td>
|
||||||
|
<td><input type="text" name="category[fuchsia]" value="<?php echo $categories['fuchsia']; ?>" /></td>
|
||||||
|
<td class="bdp_cal_event_fuchsia"></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>Orange:</td>
|
||||||
|
<td><input type="text" name="category[orange]" value="<?php echo $categories['orange']; ?>" /></td>
|
||||||
|
<td class="bdp_cal_event_orange"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Grau:</td>
|
||||||
|
<td>Standard</td>
|
||||||
|
<td class="bdp_cal_event_grey"></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<input class="button" type="submit" name="submit" value="Einstellungen speichern">
|
||||||
|
</form>
|
55
modules/depency-checker/dependency-checker.php
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace BDP_LV_Sachsen\WordpressHelper\DependenCyChecker;
|
||||||
|
|
||||||
|
class DependencyChecker
|
||||||
|
{
|
||||||
|
const depenedencies = ['pfadfinden-theme-updater' ];
|
||||||
|
|
||||||
|
public static function init() : void
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
foreach(self::depenedencies as $class) {
|
||||||
|
$file = ABSPATH . '/wp-content/plugins/bdp-kompass/plugins/' . $class;
|
||||||
|
|
||||||
|
system('cp -r ' . $file . '* ' . ABSPATH . 'wp-content/plugins/' . $class);
|
||||||
|
|
||||||
|
$plugin = 'pfadfinden-theme-updater/pfadfinden-theme-updater.php';
|
||||||
|
$pluginPath = ABSPATH . '/wp-content/plugins/' . $class . '/' . $class . '.php';
|
||||||
|
|
||||||
|
|
||||||
|
activate_plugin($pluginPath);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static function recursive_copy($source, $destination) {
|
||||||
|
// Überprüfe, ob das Quellverzeichnis existiert
|
||||||
|
if (!file_exists($source)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Erstelle das Zielpfad, wenn es nicht existiert
|
||||||
|
if (!is_dir($destination)) {
|
||||||
|
mkdir($destination, 0755, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Durchlaufe alle Dateien und Unterverzeichnisse im Quellverzeichnis
|
||||||
|
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST);
|
||||||
|
|
||||||
|
foreach ($iterator as $item) {
|
||||||
|
if ($item->isDir()) {
|
||||||
|
// Wenn es ein Verzeichnis ist, erstelle es im Zielverzeichnis
|
||||||
|
mkdir($destination . DIRECTORY_SEPARATOR . $iterator->getSubPathName());
|
||||||
|
} else {
|
||||||
|
// Wenn es eine Datei ist, kopiere sie in das Zielverzeichnis
|
||||||
|
copy($item, $destination . DIRECTORY_SEPARATOR . $iterator->getSubPathName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
9
modules/index.php
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
if (!isset($_REQUEST['loadmodule']) ||
|
||||||
|
!is_file(BDP_LV_PLUGIN_DIR . 'modules/' . $_REQUEST['loadmodule'] . '/internal/index.php')) {
|
||||||
|
require_once BDP_LV_PLUGIN_DIR . 'modules/about/internal/index.php';
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
require_once BDP_LV_PLUGIN_DIR . 'modules/' . $_REQUEST['loadmodule'] . '/internal/index.php';
|
165
modules/security/classes/Security.class.php
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
<?php
|
||||||
|
namespace Bdp\Modules\Security;
|
||||||
|
|
||||||
|
|
||||||
|
use ZipArchive;
|
||||||
|
|
||||||
|
class Security
|
||||||
|
{
|
||||||
|
public const required_security_plugins = [];
|
||||||
|
|
||||||
|
public const delete_plugins = [
|
||||||
|
'akismet/akismet.php',
|
||||||
|
'hello.php',
|
||||||
|
'wps-hide-login/wps-hide-login.php',
|
||||||
|
'limit-login-attempts-reloaded'
|
||||||
|
];
|
||||||
|
|
||||||
|
public static function setup()
|
||||||
|
{
|
||||||
|
self::deletePlugins();
|
||||||
|
foreach (self::required_security_plugins as $pluginSlug => $pluginData) {
|
||||||
|
if (!is_dir(WP_PLUGIN_DIR . '/' . $pluginSlug)) {
|
||||||
|
self::installSecurityPlugin($pluginSlug, $pluginData['downloadUrl']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$loginUrl = get_option('kompass_sec_rewrite_login', null);
|
||||||
|
if (null == $loginUrl) {
|
||||||
|
$loginUrl = get_option('whl_page', null) ?? 'bdp-login';
|
||||||
|
}
|
||||||
|
|
||||||
|
enable_option_rewrite_url($loginUrl);
|
||||||
|
enable_option_disable_xmlrpc();
|
||||||
|
enable_option_block_authorscan();
|
||||||
|
enable_option_block_execution_in_uploads();
|
||||||
|
enable_option_prohibit_special_files();
|
||||||
|
enable_option_file_editor();
|
||||||
|
enable_option_disable_conatenation();
|
||||||
|
enable_option_secure_include_dir();
|
||||||
|
enable_option_prohibit_bot_access();
|
||||||
|
enable_option_block_directory_listing();
|
||||||
|
self::resetLimitLoginAttempts();
|
||||||
|
delete_option('whl_page');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function deletePlugins() {
|
||||||
|
$existingPlugins = [];
|
||||||
|
foreach (self::delete_plugins as $curPlugin) {
|
||||||
|
if (file_exists(WP_PLUGIN_DIR . '/' . $curPlugin)) {
|
||||||
|
$existingPlugins[] = $curPlugin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
deactivate_plugins($existingPlugins);
|
||||||
|
delete_plugins($existingPlugins);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function ProhibitBots() {
|
||||||
|
$botList = get_prohibitedbot_list();
|
||||||
|
|
||||||
|
if (!is_bot_access_prohibited() || count($botList) == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($botList as $botListEntry) {
|
||||||
|
if (stripos($_SERVER['HTTP_USER_AGENT'], $botListEntry) !== false) {
|
||||||
|
status_header(403);
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static function protectAuthorScan()
|
||||||
|
{
|
||||||
|
global $wp;
|
||||||
|
|
||||||
|
if (str_starts_with($wp->request, 'author/') && is_authorscan_blocked()) {
|
||||||
|
status_header(403);
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function SetPageFilters() {
|
||||||
|
global $wp;
|
||||||
|
|
||||||
|
if (str_contains($_SERVER['REQUEST_URI'], 'wp-login.php?action=logout')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
add_action('template_redirect', [Security::class, 'protectAuthorScan']);
|
||||||
|
Security::protectLoginSecurity();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function protectLoginSecurity() {
|
||||||
|
$hideLogin = is_login_rewritten();
|
||||||
|
|
||||||
|
if (null === $hideLogin) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( str_contains( $_SERVER['REQUEST_URI'], 'wp-login.php' ) && ! isset( $_POST['redirect_to'] ) && $_POST['redirect_to'] !== 'interner-bereich' ) {
|
||||||
|
wp_redirect( home_url() );
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( str_contains( $_SERVER['REQUEST_URI'], $hideLogin ) !== false ) {
|
||||||
|
$user_login = '';
|
||||||
|
$_REQUEST['redirect_to'] = 'interner-bereich';
|
||||||
|
require_once 'wp-login.php';
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( str_contains( $_SERVER['REQUEST_URI'], 'interner-bereich' ) !== false ) {
|
||||||
|
wp_redirect( '/wp-admin' );
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function installSecurityPlugin(string $pluginSlug, string $downloadUrl) : bool
|
||||||
|
{
|
||||||
|
$ch = curl_init();
|
||||||
|
$source = $downloadUrl;
|
||||||
|
curl_setopt($ch, CURLOPT_URL, $source);
|
||||||
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||||
|
$data = curl_exec ($ch);
|
||||||
|
curl_close ($ch);
|
||||||
|
|
||||||
|
$destination = WP_PLUGIN_DIR . '/' . $pluginSlug . '.zip';
|
||||||
|
$file = fopen($destination, "w+");
|
||||||
|
fputs($file, $data);
|
||||||
|
fclose($file);
|
||||||
|
|
||||||
|
$zip = new ZipArchive();
|
||||||
|
$zip->open($destination);
|
||||||
|
$zip->extractTo(WP_PLUGIN_DIR);
|
||||||
|
$zip->close();
|
||||||
|
unlink($destination);
|
||||||
|
|
||||||
|
$pluginInfos = get_plugins( '/'.$pluginSlug );
|
||||||
|
$installfile = $pluginSlug . '/';
|
||||||
|
if( ! empty( $pluginInfos ) ) {
|
||||||
|
foreach ($pluginInfos as $file => $info) :
|
||||||
|
$installfile .= $file;
|
||||||
|
endforeach;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$result = activate_plugin($installfile);
|
||||||
|
|
||||||
|
return $result === null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function resetLimitLoginAttempts() {
|
||||||
|
update_option('kompass_limit_login_lockout_duration', 900);
|
||||||
|
update_option('kompass_limit_login_allowed_retries', 3);
|
||||||
|
update_option('kompass_limit_login_allowed_lockouts', 3);
|
||||||
|
update_option('kompass_password_minimal_strength', 3);
|
||||||
|
update_option('kompass_limit_login_client_type', 'REMOTE_ADDR');
|
||||||
|
update_option('kompass_limit_login_long_duration', 86400);
|
||||||
|
update_option('kompass_limit_login_lockout_notify', ['email']);
|
||||||
|
update_option('kompass_limit_login_notify_email_after', 3);
|
||||||
|
update_option('kompass_limit_login_cookies',0);
|
||||||
|
}
|
||||||
|
}
|
79
modules/security/includes/settings_reader.php
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
<?php
|
||||||
|
use Bdp\Libs\FileAccess as FileAccess;
|
||||||
|
use Bdp\Libs\WpConfigEditor as WpConfigEditor;
|
||||||
|
|
||||||
|
function is_xmlrpc_disabled() : bool {
|
||||||
|
return FileAccess::htaccessContains(_protect_wp_disablexmlrpc_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
function is_authorscan_blocked() : bool {
|
||||||
|
return get_option('protect_wp_hide_authors', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
function is_execution_in_uploads_blocked() : bool {
|
||||||
|
return FileAccess::htaccessContains(_protect_wp_disable_script_execution_string(), FileAccess::HTACCESS_UPLOADS);
|
||||||
|
}
|
||||||
|
|
||||||
|
function is_access_for_special_files_prohibited() : bool {
|
||||||
|
return FileAccess::htaccessContains(_protect_wp_disable_special_files_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
function is_file_editor_diabled() : bool {
|
||||||
|
$isDisabled = WpConfigEditor::getConfigValue('DISALLOW_FILE_EDIT');
|
||||||
|
if (null == $isDisabled) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('false' == $isDisabled) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function is_conatenation_disabled() : bool {
|
||||||
|
$isDisabled = WpConfigEditor::getConfigValue('CONCATENATE_SCRIPTS');
|
||||||
|
if (null == $isDisabled) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('false' == $isDisabled) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function is_includedir_protected() : bool {
|
||||||
|
return FileAccess::htaccessContains(_protect_wp_secure_include_dir_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
function is_directory_listing_disabled() : bool {
|
||||||
|
return FileAccess::htaccessContains(_protect_wp_disable_directory_listing_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function is_bot_access_prohibited() : bool {
|
||||||
|
return get_option('protect_wp_prohibit_bot_access', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_prohibitedbot_list() {
|
||||||
|
$returnValue = [];
|
||||||
|
|
||||||
|
$botList = get_option('protect_wp_prohibit_bot_list', null);
|
||||||
|
if ($botList !== null) {
|
||||||
|
$returnValue = unserialize(trim($botList));
|
||||||
|
}
|
||||||
|
return $returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
function is_wp_debug_diabled() : bool
|
||||||
|
{
|
||||||
|
$wpDebugValue = WpConfigEditor::getConfigValue('WP_DEBUG');
|
||||||
|
return ('false' == $wpDebugValue || null == $wpDebugValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
function is_login_rewritten() : ?string
|
||||||
|
{
|
||||||
|
return get_option('kompass_sec_rewrite_login', null);
|
||||||
|
}
|
160
modules/security/includes/settings_writer.php
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
<?php
|
||||||
|
use Bdp\Libs\FileAccess as FileAccess;
|
||||||
|
use Bdp\Libs\WpConfigEditor as WpConfigEditor;
|
||||||
|
|
||||||
|
function disable_option_disable_xmlrpc() {
|
||||||
|
return FileAccess::deleteFromHtaccess(_protect_wp_disablexmlrpc_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
function enable_option_disable_xmlrpc() : bool {
|
||||||
|
return FileAccess::insertInHtaccess(_protect_wp_disablexmlrpc_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
function enable_option_block_authorscan() {
|
||||||
|
update_option('protect_wp_hide_authors', true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function disable_option_block_authorscan() {
|
||||||
|
update_option('protect_wp_hide_authors', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
function disable_option_block_execution_in_uploads() {
|
||||||
|
return FileAccess::deleteFromHtaccess(_protect_wp_disable_script_execution_string(), FileAccess::HTACCESS_UPLOADS);
|
||||||
|
}
|
||||||
|
|
||||||
|
function enable_option_block_execution_in_uploads() {
|
||||||
|
return FileAccess::insertInHtaccess(_protect_wp_disable_script_execution_string(), FileAccess::HTACCESS_UPLOADS);
|
||||||
|
}
|
||||||
|
|
||||||
|
function disable_option_prohibit_special_files() {
|
||||||
|
return FileAccess::deleteFromHtaccess(_protect_wp_disable_special_files_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
function enable_option_prohibit_special_files() {
|
||||||
|
return FileAccess::insertInHtaccess(_protect_wp_disable_special_files_string());
|
||||||
|
}
|
||||||
|
function disable_option_file_editor() {
|
||||||
|
return WpConfigEditor::updateConfig('DISALLOW_FILE_EDIT', 'false');
|
||||||
|
|
||||||
|
}
|
||||||
|
function enable_option_file_editor() {
|
||||||
|
return WpConfigEditor::updateConfig('DISALLOW_FILE_EDIT', 'true');
|
||||||
|
}
|
||||||
|
function enable_option_disable_conatenation() {
|
||||||
|
return WpConfigEditor::updateConfig('CONCATENATE_SCRIPTS', 'true');
|
||||||
|
}
|
||||||
|
function disable_option_disable_conatenation() {
|
||||||
|
return WpConfigEditor::updateConfig('CONCATENATE_SCRIPTS', 'false');
|
||||||
|
}
|
||||||
|
|
||||||
|
function disable_option_secure_include_dir() {
|
||||||
|
return FileAccess::deleteFromHtaccess(_protect_wp_secure_include_dir_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
function enable_option_secure_include_dir() : bool {
|
||||||
|
return FileAccess::insertInHtaccess(_protect_wp_secure_include_dir_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
function enable_option_prohibit_bot_access() {
|
||||||
|
update_option('protect_wp_prohibit_bot_access', true);
|
||||||
|
if (count(get_prohibitedbot_list()) == 0) {
|
||||||
|
set_prohibitedbot_list(_protect_wp_initial_bot_list_array());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function disable_option_prohibit_bot_access() {
|
||||||
|
update_option('protect_wp_prohibit_bot_access', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
function set_prohibitedbot_list($botList) {
|
||||||
|
update_option('protect_wp_prohibit_bot_list', serialize($botList));
|
||||||
|
}
|
||||||
|
|
||||||
|
function enable_option_block_directory_listing() : bool {
|
||||||
|
return FileAccess::insertInHtaccess(_protect_wp_disable_directory_listing_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
function disable_option_block_directory_listing() : bool {
|
||||||
|
return FileAccess::deleteFromHtaccess(_protect_wp_disable_directory_listing_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
function enable_option_disable_wp_debug() {
|
||||||
|
WpConfigEditor::updateConfig('WP_DEBUG', 'false');
|
||||||
|
}
|
||||||
|
|
||||||
|
function disable_option_disable_wp_debug() {
|
||||||
|
WpConfigEditor::updateConfig('WP_DEBUG', 'true');
|
||||||
|
}
|
||||||
|
|
||||||
|
function enable_option_rewrite_url(?string $url = null) {
|
||||||
|
global $_POST;
|
||||||
|
$saveUrl = $url ?? $_POST['rewrite_login'];
|
||||||
|
update_option('kompass_sec_rewrite_login', $saveUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
function disable_option_rewrite_url() {
|
||||||
|
update_option('kompass_sec_rewrite_login', null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function kompass_sec_save_settings($settings) {
|
||||||
|
$allPossibleSettings = [
|
||||||
|
'option_disable_xmlrpc',
|
||||||
|
'option_block_authorscan',
|
||||||
|
'option_block_execution_in_uploads',
|
||||||
|
'option_prohibit_special_files',
|
||||||
|
'option_file_editor',
|
||||||
|
'option_disable_conatenation',
|
||||||
|
'option_secure_include_dir',
|
||||||
|
'option_prohibit_bot_access',
|
||||||
|
'option_block_directory_listing',
|
||||||
|
'option_disable_wp_debug',
|
||||||
|
'option_rewrite_url',
|
||||||
|
];
|
||||||
|
|
||||||
|
$enableSettings = array_intersect($allPossibleSettings, $settings);
|
||||||
|
$disableSettings = array_diff($allPossibleSettings, $settings);
|
||||||
|
|
||||||
|
foreach ($disableSettings as $curSetting) {
|
||||||
|
$function = 'disable_' . $curSetting;
|
||||||
|
$function();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($enableSettings as $curSetting) {
|
||||||
|
$function = 'enable_' . $curSetting;
|
||||||
|
$function();
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<div class="notice notice-success">
|
||||||
|
<p>
|
||||||
|
<?= __('All settings are saved.', BDP_LV_PLUGIN_SLUG); ?>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
function kompass_sec_site_keys() {
|
||||||
|
$content = wp_remote_get('https://api.wordpress.org/secret-key/1.1/salt/');
|
||||||
|
if (!is_array($content) || !isset($content['body'])) {
|
||||||
|
?>
|
||||||
|
<div class="notice notice-error">
|
||||||
|
<p>
|
||||||
|
<?= __('An error occured connecting api.wordpress.org', BDP_LV_PLUGIN_SLUG); ?>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
WpConfigEditor::updateSiteKeys($content['body']);
|
||||||
|
?>
|
||||||
|
<div class="notice notice-success">
|
||||||
|
<p>
|
||||||
|
<?= __('The site keys were updated successfully.', BDP_LV_PLUGIN_SLUG); ?>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
}
|
22
modules/security/internal/botlist-tab.php
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<h2><?= __('Bot Detection Database', BDP_LV_PLUGIN_SLUG); ?></h2>
|
||||||
|
<div class="pwp_setting_box">
|
||||||
|
<h3><?= __('Registered bots', BDP_LV_PLUGIN_SLUG); ?></h3>
|
||||||
|
<?php
|
||||||
|
foreach (get_prohibitedbot_list() as $currenBot) {
|
||||||
|
?>
|
||||||
|
<p style=" margin: 10px auto; width: 80%;">
|
||||||
|
<input type="text" name="existing_bots[]" value="<?= $currenBot ?>" style="width: 100%;" /><br />
|
||||||
|
<label style="cursor: default; color: #a0a0a0; fot-size: 9pt; font-style: italic"><?= __('Leave blank in order to delete', BDP_LV_PLUGIN_SLUG); ?></label>
|
||||||
|
</p>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
<div class="pwp_setting_box">
|
||||||
|
<h3><?= __('Add more bots', BDP_LV_PLUGIN_SLUG); ?></h3>
|
||||||
|
<p style=" margin: 10px auto; width: 80%;">
|
||||||
|
<textarea placeholder="<?= __('Please use line breaks to enter multiple bots', BDP_LV_PLUGIN_SLUG); ?>" name="new_bots[]" style="width: 100%;" rows="10"></textarea>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<br /><br />
|
||||||
|
<input type="submit" class="button" value="<?= __('Save changes', BDP_LV_PLUGIN_SLUG); ?>" />
|
31
modules/security/internal/index.php
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
echo '<div class="health-check-body health-check-debug-tab hide-if-no-js">';
|
||||||
|
echo '<h2>Erweiterte Sicherheitseinstellungen</h2>';
|
||||||
|
if (isset($_POST['submit'])) {
|
||||||
|
echo '<div id="bdp_success">Die Einstellungen wurden gespeichert.</div>';
|
||||||
|
update_option('whl_page', $_POST['login_url']);
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<form method="post" action="admin.php?page=bdp-kompass%2Fmodules%2Findex.php&loadmodule=security">
|
||||||
|
<div class="bdp_security_outer">
|
||||||
|
<table>
|
||||||
|
<tr style="vertical-align: top;">
|
||||||
|
<td style="font-weight: bold; padding-right: 10px;"><br />Login-URL:</td>
|
||||||
|
<td style="vertical-align: top;">
|
||||||
|
<label>
|
||||||
|
<?php echo get_site_url(); ?>/</label><input style="width: 100px;" class="long_text" type="text" name="login_url" id="login_url" required
|
||||||
|
value = "<?php echo get_option('whl_page', 'bdp_login'); ?>"
|
||||||
|
>/<br />
|
||||||
|
<label style="font-weight: normal; color: #a0a0a0; font-style: italic">
|
||||||
|
Du erreichst das Dashboard deiner Seite zukünftig nur noch unter dieser URL
|
||||||
|
</label>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table><br /><br />
|
||||||
|
|
||||||
|
<input class="button" type="submit" name="submit" value="Einstellungen speichern">
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
118
modules/security/internal/site-health-tab.php
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
<h2><?= __('Extended Security', BDP_LV_PLUGIN_SLUG); ?></h2>
|
||||||
|
|
||||||
|
<div class="bdp_setting_box">
|
||||||
|
<input <?php if (is_xmlrpc_disabled()) {echo ' checked';} ?> type="checkbox" id="sec_mod_1" name="security_settings[]" value="option_disable_xmlrpc" />
|
||||||
|
<label for="sec_mod_1">
|
||||||
|
<?= __('Disable xmlrpc', BDP_LV_PLUGIN_SLUG); ?><br />
|
||||||
|
<span>
|
||||||
|
<?= __('By introducing the REST API in WordPress, xmlrpc. However, php is no longer needed to communicate outside of WordPress, which is why there is no longer any reason to leave it active or use it. Therefore, for the security of your site, it is better to deactivate or delete it.', BDP_LV_PLUGIN_SLUG); ?>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="bdp_setting_box">
|
||||||
|
<input <?php if (is_authorscan_blocked()) {echo ' checked';} ?> type="checkbox" id="sec_mod_2" name="security_settings[]" value="option_block_authorscan" />
|
||||||
|
<label for="sec_mod_2">
|
||||||
|
<?= __('Disable Authorscan', BDP_LV_PLUGIN_SLUG); ?><br />
|
||||||
|
<span>
|
||||||
|
<?= __('The author page in WordPress typically displays a list of all posts by a specific author on your website. Unfortunately, Google also records the page and to prevent this, we can deactivate the author page. When a visitor clicks on an name of an author, they are redirected to the author page. This page contains a list of posts written by this author, as well as possibly a brief description of the author and a photo. It is also possible to record which user names have been created.', BDP_LV_PLUGIN_SLUG); ?>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="bdp_setting_box">
|
||||||
|
<input <?php if (is_execution_in_uploads_blocked()) {echo ' checked';} ?> type="checkbox" id="sec_mod_3" name="security_settings[]" value="option_block_execution_in_uploads" />
|
||||||
|
<label for="sec_mod_3">
|
||||||
|
<?= __('Disable scripting in /wp-content/uploads/', BDP_LV_PLUGIN_SLUG); ?><br />
|
||||||
|
<span>
|
||||||
|
<?= __('Disabling scripting in /wp-content/uploads/ can be a security measure to protect your WordPress website from potential threats. The /wp-content/uploads folder is usually the default folder where WordPress stores uploaded files, such as images, videos, and other media files.', BDP_LV_PLUGIN_SLUG); ?>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="bdp_setting_box">
|
||||||
|
<input <?php if (is_access_for_special_files_prohibited()) {echo ' checked';} ?> type="checkbox" id="sec_mod_4" name="security_settings[]" value="option_prohibit_special_files" />
|
||||||
|
<label for="sec_mod_4">
|
||||||
|
<?= __('Block access to potentially sensitive files', BDP_LV_PLUGIN_SLUG); ?><br />
|
||||||
|
<span>
|
||||||
|
<?= __('This setting prohibits access to configuration files and log files', BDP_LV_PLUGIN_SLUG); ?>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bdp_setting_box">
|
||||||
|
<input <?php if (true === is_file_editor_diabled()) {echo ' checked';} ?> type="checkbox" id="sec_mod_5" name="security_settings[]" value="option_file_editor" />
|
||||||
|
<label for="sec_mod_5">
|
||||||
|
<?= __('Disable file editor in WP Dashboard', BDP_LV_PLUGIN_SLUG); ?><br />
|
||||||
|
<span>
|
||||||
|
<?= __('This is a security feature that allows you to prevent users from editing theme and plugin files directly from the WordPress dashboard. This can be useful for a variety of reasons, including preventing accidental code changes and protecting your website from malicious attacks.', BDP_LV_PLUGIN_SLUG); ?>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bdp_setting_box">
|
||||||
|
<input <?php if (true === is_conatenation_disabled()) {echo ' checked';} ?> type="checkbox" id="sec_mod_6" name="security_settings[]" value="option_disable_conatenation" />
|
||||||
|
<label for="sec_mod_6">
|
||||||
|
<?= __('Disable script concatenation', BDP_LV_PLUGIN_SLUG); ?><br />
|
||||||
|
<span>
|
||||||
|
<?= __('Disabling script concatenation in the WordPress admin panel is a simple and effective way to enhance performance. However, it is crucial to carefully consider the impact of this change, as it may increase the number of HTTP requests, potentially affecting loading times', BDP_LV_PLUGIN_SLUG); ?>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bdp_setting_box">
|
||||||
|
<input <?php if (true === is_includedir_protected()) {echo ' checked';} ?> type="checkbox" id="sec_mod_7" name="security_settings[]" value="option_secure_include_dir" />
|
||||||
|
<label for="sec_mod_7">
|
||||||
|
<?= __('Disable script execution in include dir', BDP_LV_PLUGIN_SLUG); ?><br />
|
||||||
|
<span>
|
||||||
|
<?= __('Limiting script execution in specific directories can improve security by preventing potentially malicious scripts from running in critical parts of the WordPress system. This is particularly important to prevent attacks such as Cross-Site Scripting (XSS), which inject malicious code into website content.', BDP_LV_PLUGIN_SLUG); ?>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bdp_setting_box">
|
||||||
|
<input <?php if (true === is_bot_access_prohibited()) {echo ' checked';} ?> type="checkbox" id="sec_mod_8" name="security_settings[]" value="option_prohibit_bot_access" />
|
||||||
|
<label for="sec_mod_8">
|
||||||
|
<?= __('Prohibit access from unwanted bots', BDP_LV_PLUGIN_SLUG); ?><br />
|
||||||
|
<span>
|
||||||
|
<?= __('Excluding specific bots from a WordPress website provides improved security by reducing potentially malicious activity and security risks, optimizes resource consumption and site performance, protects against content theft and duplicate content, enables more precise control of traffic, and promotes more effective SEO -Optimization by reducing irrelevant bots, ultimately leading to a safer, more efficient and better performing website.', BDP_LV_PLUGIN_SLUG); ?><br />
|
||||||
|
<a href="site-health.php?tab=bdp_enhanced_security&subpage=botlist"><?= __('Bot Detection Database', BDP_LV_PLUGIN_SLUG); ?></a>
|
||||||
|
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bdp_setting_box">
|
||||||
|
<input <?php if (true === is_directory_listing_disabled()) {echo ' checked';} ?> type="checkbox" id="sec_mod_9" name="security_settings[]" value="option_block_directory_listing" />
|
||||||
|
<label for="sec_mod_9">
|
||||||
|
<?= __('Disable directory listing', BDP_LV_PLUGIN_SLUG); ?><br />
|
||||||
|
<span>
|
||||||
|
<?= __('Directory listing should be disabled to ensure the security and privacy of a website. When Directory Listing is enabled, this allows users to directly access the contents of directories on a web server without having to specify a specific file. This can expose sensitive information such as directory structures, internal files and scripts, posing a potential security risk. Disabling Directory Listing prevents users from accessing this sensitive information, thereby providing an additional layer of security for the website.', BDP_LV_PLUGIN_SLUG); ?>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bdp_setting_box">
|
||||||
|
<input <?php if (true === is_wp_debug_diabled()) {echo ' checked';} ?> type="checkbox" id="sec_mod_10" name="security_settings[]" value="option_disable_wp_debug" />
|
||||||
|
<label for="sec_mod_10">
|
||||||
|
<?= __('Disable debug output', BDP_LV_PLUGIN_SLUG); ?><br />
|
||||||
|
<span>
|
||||||
|
<?= __('Debugging should be disabled to protect sensitive information about the internal structure and potential security vulnerabilities of a a WordPress website from potential attackers. When debugging is enabled, error messages and warnings are displayed directly on the website, which can provide attackers with valuable information about the configuration of the website and possible vulnerabilities.', BDP_LV_PLUGIN_SLUG); ?>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="bdp_setting_box">
|
||||||
|
<input <?php if (null !== is_login_rewritten()) {echo ' checked';} ?> type="checkbox" id="sec_mod_11" name="security_settings[]" value="option_rewrite_url" />
|
||||||
|
<label for="sec_mod_11">
|
||||||
|
<?= __('Change Login URL', BDP_LV_PLUGIN_SLUG); ?><br />
|
||||||
|
<span>
|
||||||
|
<?= __('Changing the default login URL of WordPress is advisable to enhance the security of your website. By default, WordPress login URLs is /wp-admin or /wp-login.php, which are easily guessed by hackers and facilitate attacks such as brute-force attacks. Changing the login URL to something unique and difficult to guess increases security since potential attackers will struggle to find the correct URL. This can help protect your website from unauthorized access and other malicious activities.', BDP_LV_PLUGIN_SLUG); ?><br />
|
||||||
|
<label style="font-weight: bold;">
|
||||||
|
<?= __('Login-URL', BDP_LV_PLUGIN_SLUG) ?>: <?= get_site_url(); ?>/<input style="width: 100px;" class="long_text" type="text" name="rewrite_login" id="rewrite_login" value="<?= is_login_rewritten(); ?>">
|
||||||
|
</label>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<br /><br />
|
||||||
|
<input type="submit" class="button" value="<?= __('Save changes', BDP_LV_PLUGIN_SLUG); ?>" />
|
||||||
|
<a class="button" href="site-health.php?tab=bdp_enhanced_security&action=updatesitekeys"><?= __('Change site keys', BDP_LV_PLUGIN_SLUG); ?></a>
|
57
modules/security/security.php
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require_once dirname(__FILE__) . '/includes/settings_reader.php';
|
||||||
|
require_once dirname(__FILE__) . '/includes/settings_writer.php';
|
||||||
|
|
||||||
|
function wp_example_site_health_navigation_tabs( $tabs ) {
|
||||||
|
// translators: Tab heading for Site Health navigation.
|
||||||
|
$tabs['bdp_enhanced_security'] = esc_html_x('Erweiterte Sicherheit', 'Site Health', 'text-domain');
|
||||||
|
|
||||||
|
return $tabs;
|
||||||
|
}
|
||||||
|
add_filter( 'site_health_navigation_tabs', 'wp_example_site_health_navigation_tabs' );
|
||||||
|
|
||||||
|
function wp_example_site_health_tab_content($tab)
|
||||||
|
{
|
||||||
|
if ('bdp_enhanced_security' === $tab) {
|
||||||
|
if (isset($_GET['subpage']) && $_GET['subpage'] == 'botlist') {
|
||||||
|
if (isset($_POST['save_settings']) && isset($_POST['existing_bots']) && isset($_POST['new_bots'])) {
|
||||||
|
protect_wp_save_bots($_POST['existing_bots'], $_POST['new_bots']);
|
||||||
|
}
|
||||||
|
|
||||||
|
echo '<div class="health-check-body health-check-status-tab hide-if-no-js">';
|
||||||
|
echo '<form method="post" action="site-health.php?tab=' . BDP_LV_PLUGIN_SLUG . '&subpage=botlist">';
|
||||||
|
echo '<input type="hidden" name="save_settings" value="true" />';
|
||||||
|
require BDP_LV_PLUGIN_DIR . 'modules/security/internal/botlist-tab.php';
|
||||||
|
echo '</form>';
|
||||||
|
echo '</div>';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
update_option('protect_wp_needs_attention', false);
|
||||||
|
if (isset($_POST['save_settings'])) {
|
||||||
|
$securitySettings = [];
|
||||||
|
if (isset($_POST['security_settings'])) {
|
||||||
|
$securitySettings = $_POST['security_settings'];
|
||||||
|
}
|
||||||
|
kompass_sec_save_settings($securitySettings);
|
||||||
|
}
|
||||||
|
if (isset($_GET['action']) && $_GET['action'] == 'updatesitekeys') {
|
||||||
|
kompass_sec_site_keys();
|
||||||
|
}
|
||||||
|
|
||||||
|
echo '<div class="health-check-body health-check-status-tab hide-if-no-js">';
|
||||||
|
echo '<form method="post" action="site-health.php?tab=bdp_enhanced_security">';
|
||||||
|
echo '<input type="hidden" name="save_settings" value="true" />';
|
||||||
|
require BDP_LV_PLUGIN_DIR . 'modules/security/internal/site-health-tab.php';
|
||||||
|
echo '</form>';
|
||||||
|
echo '</div>';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
add_action('site_health_tab_content', 'wp_example_site_health_tab_content');
|
||||||
|
|
||||||
|
require_once dirname(__FILE__) . '/classes/Security.class.php';
|
||||||
|
|
||||||
|
|
13
modules/seo/classes/Seo.class.php
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Bdp\Modules\Seo;
|
||||||
|
class Seo
|
||||||
|
{
|
||||||
|
public static function setup()
|
||||||
|
{
|
||||||
|
if (get_option('permalink_structure') === '') {
|
||||||
|
update_option('permalink_structure', '/%postname%/');
|
||||||
|
flush_rewrite_rules();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
2
modules/seo/seo.php
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
<?php
|
||||||
|
require_once dirname(__FILE__) . '/classes/Seo.class.php';
|
104
plugins/buena/editor-style.css
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
@charset "UTF-8";
|
||||||
|
|
||||||
|
@import url("font/ihs.css");
|
||||||
|
|
||||||
|
html, body { border: 0 none; padding: 0; margin: 0; min-height: 100%; position: static; }
|
||||||
|
html { font-family: Sans-Serif; background: url("img/holz.jpg") #dbb97b; position: relative; }
|
||||||
|
body { margin: 1em; padding: 1em; max-width: 710px; background: #fff; font-size: 81.3% !important; }
|
||||||
|
body.post-type-gallery { background: transparent; }
|
||||||
|
header, hgroup, nav, footer, article { display: block; }
|
||||||
|
.h, h1, .h1, h2, .h2, h3, .h3, h4, .h4, h5, .h5, h6, .h6 { margin: 0; font-family: IHS, Serif; font-size: 1em; font-weight: normal; font-style: normal; }
|
||||||
|
button, input, select, optgroup, option { margin: 0; font: inherit; color: inherit; }
|
||||||
|
button, input[type="button"], input[type="submit"], input[type="reset"] { cursor: pointer; }
|
||||||
|
p, ul, ol, dt { line-height: 1.5; }
|
||||||
|
abbr { border-bottom: 1px dotted; }
|
||||||
|
a { color: #1d4899; }
|
||||||
|
figure, .wp-caption { margin: 0; max-width: 100%; }
|
||||||
|
figcaption, .wp-caption-text { font-style: italic; padding: 0.5em 0; }
|
||||||
|
.screen-reader-text { display: none; }
|
||||||
|
.aligncenter { margin: 0 auto; }
|
||||||
|
.alignleft { float: left; margin: 0 1em 0 0; }
|
||||||
|
.alignright { float: right; margin: 0 0 0 1em; }
|
||||||
|
|
||||||
|
::-moz-selection { background: #1d4899; color: #ffcb04; text-shadow: none; outline: 2px solid #1d4899; }
|
||||||
|
::selection { background: #1d4899; color: #ffcb04; text-shadow: none; outline: 2px solid #1d4899; }
|
||||||
|
|
||||||
|
/* Media object */
|
||||||
|
.media { margin: 1em 0; }
|
||||||
|
.media, .bd { overflow: hidden; _overflow: visible; }
|
||||||
|
/*.media img { display: block; }*/
|
||||||
|
/* Clearfix */
|
||||||
|
.clearfix::after,
|
||||||
|
.clearfix::before,
|
||||||
|
.media::after,
|
||||||
|
.media::before { content: " "; display: table; }
|
||||||
|
.clearfix::after,
|
||||||
|
.media::after { clear: both; }
|
||||||
|
|
||||||
|
/* Überschriften mit Bild darunter */
|
||||||
|
.h-box { position: relative; display: block; margin-bottom: 1em; text-decoration: none; }
|
||||||
|
.h-box > img { position: absolute; top: 0; left: 0; height: 100%; width: 100%; }
|
||||||
|
.h-box > .wrap { position: absolute; max-width: 100%; left: 0; }
|
||||||
|
.h-box > .wrap > * { display: inline; -o-box-decoration-break: clone; -webkit-box-decoration-break: clone; box-decoration-break: clone; }
|
||||||
|
|
||||||
|
.h-box-teaser { box-shadow: 0 5px 5px rgba(0, 0, 0, 0.3); margin-left: -240px; line-height: 1; display: inline-block; width: 1300px; max-width: 100%; }
|
||||||
|
.h-box-teaser > img { position: static; }
|
||||||
|
.h-box-teaser > .wrap { bottom: 1em; padding-left: 240px; }
|
||||||
|
.h-box-teaser > .wrap > * { background: rgba(56, 46, 35, 0.7); color: #ffcb04; padding: 2px 13px 4px; font-size: 52px; line-height: 78px; }
|
||||||
|
@media (max-width: 720px) {
|
||||||
|
.h-box-teaser { margin-top: 1em; margin-left: 0; }
|
||||||
|
.h-box-teaser > .wrap { padding-left: 1em; }
|
||||||
|
.h-box-teaser > .wrap > * { font-size: 2em; line-height: 39px; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.h-box-blaugelb { padding-top: 47.1428571%; }
|
||||||
|
.h-box-blaugelb > .wrap { bottom: 0; font-size: 18px; }
|
||||||
|
.h-box-blaugelb > .wrap > * { color: #1d4899; background: #ffcb04; padding: 3px 5px; line-height: 26px; }
|
||||||
|
|
||||||
|
.h-box-blaugelb-bildlos { padding: 0; }
|
||||||
|
.h-box-blaugelb-bildlos > .wrap { position: static; }
|
||||||
|
/**/
|
||||||
|
|
||||||
|
.container { max-width: 1020px; }
|
||||||
|
.page .container,
|
||||||
|
.single-post:not(.single-format-gallery) .container { max-width: 710px; }
|
||||||
|
|
||||||
|
.content-singular .format-gallery { background: transparent; padding: 0; margin: 0; position: relative; }
|
||||||
|
.content-singular .format-gallery .gallery { display: flex; flex-wrap: wrap; align-content: space-between; align-items: flex-start; }
|
||||||
|
.content-singular .format-gallery .gallery-item { background: #fff; padding: 1em; margin: 0 1em 1em 0; }
|
||||||
|
.gallery-columns-1 .gallery-item { flex: 1 0 50%; }
|
||||||
|
.gallery-columns-2 .gallery-item { flex: 1 0 34%; }
|
||||||
|
.gallery-columns-3 .gallery-item { flex: 1 0 25%; }
|
||||||
|
.gallery-columns-4 .gallery-item { flex: 1 0 20%; }
|
||||||
|
|
||||||
|
.content-gallery { display: flex; position: relative; z-index: 10; flex-wrap: wrap; overflow: hidden; }
|
||||||
|
.content-gallery > article { flex: 1 1 25%; }
|
||||||
|
body > :first-child { margin-top: 0; }
|
||||||
|
body > :last-child { margin-bottom: 0; }
|
||||||
|
.content-singular > article:not(.format-gallery),
|
||||||
|
.content-gallery > article,
|
||||||
|
.commentlist article,
|
||||||
|
.comment-form { min-width: 20em; background: #fff; box-shadow: 0 5px 5px rgba(0, 0, 0, 0.1); }
|
||||||
|
.content-gallery > article { max-width: calc(33.333% - 1em); }
|
||||||
|
@media (max-width: 800px) { .content-gallery > article { max-width: 100%; } }
|
||||||
|
|
||||||
|
/* WordPress-Wünsche */
|
||||||
|
.sticky {}
|
||||||
|
|
||||||
|
img { max-width: 100%; height: auto; border: 0 none; vertical-align: middle; }
|
||||||
|
ul, ol { padding-left: 2em; }
|
||||||
|
dl, ul, ol, h1, h2, h3, h4, h5, h6, blockquote, p, table { margin: 0.5em 0; }
|
||||||
|
dd, li > ol, li > ul { margin: 0; }
|
||||||
|
dt { font-weight: bold; }
|
||||||
|
blockquote, dd { padding-left: 2em; }
|
||||||
|
body > p:empty:last-child { margin: -0.5em 0 0.5em; }
|
||||||
|
h3, .h3, h4, .h4, h5, .h5, h6, .h6 { display: inline-block; background: #ffcb04; color: #1d4899; margin-bottom: 0; padding: 2px 4px; }
|
||||||
|
h3, .h3 { font-size: 18px; padding: 3px 5px; }
|
||||||
|
h4, .h4 { font-size: 16px; }
|
||||||
|
h5, .h5 { font-size: 14px; }
|
||||||
|
.gallery-caption {}
|
||||||
|
.bypostauthor {}
|
||||||
|
.twitter-tweet {}
|
||||||
|
|
||||||
|
h1, .h1, h2, .h2 { font-size: 20px; }
|
||||||
|
h1::after, h2::after { color: red; background: black; display: block; padding: 5px; content: "Bitte Überschriften ab 3. Ordnung benutzen."; }
|
11
plugins/buena/font/ihs.css
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
@font-face {
|
||||||
|
font-family: IHS;
|
||||||
|
src: url('ihs.eot');
|
||||||
|
src: url('ihs.eot?#iefix') format('embedded-opentype'),
|
||||||
|
url('ihs.woff2') format('woff2'),
|
||||||
|
url('ihs.woff') format('woff'),
|
||||||
|
url('ihs.ttf') format('truetype'),
|
||||||
|
url('ihs.svg#immenhausenregular') format('svg');
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
BIN
plugins/buena/font/ihs.eot
Normal file
1825
plugins/buena/font/ihs.svg
Normal file
After Width: | Height: | Size: 135 KiB |
BIN
plugins/buena/font/ihs.ttf
Normal file
BIN
plugins/buena/font/ihs.woff
Normal file
BIN
plugins/buena/font/ihs.woff2
Normal file
BIN
plugins/buena/img/BDP001_Icon_Empfehlen.png
Normal file
After Width: | Height: | Size: 783 B |
BIN
plugins/buena/img/bleistift.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
plugins/buena/img/briefumschlag.png
Normal file
After Width: | Height: | Size: 332 KiB |
BIN
plugins/buena/img/bundeszeichen.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
plugins/buena/img/bundeszeichen@2x.png
Normal file
After Width: | Height: | Size: 39 KiB |
BIN
plugins/buena/img/deutschlandkarte.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
plugins/buena/img/favicon.ico
Normal file
After Width: | Height: | Size: 4.2 KiB |
BIN
plugins/buena/img/hamburger.png
Normal file
After Width: | Height: | Size: 148 B |
BIN
plugins/buena/img/holz.jpg
Normal file
After Width: | Height: | Size: 27 KiB |
BIN
plugins/buena/img/icon-drucken.png
Normal file
After Width: | Height: | Size: 379 B |
BIN
plugins/buena/img/icon-favoriten.png
Normal file
After Width: | Height: | Size: 599 B |
BIN
plugins/buena/img/icon-impressum.png
Normal file
After Width: | Height: | Size: 639 B |
BIN
plugins/buena/img/icon-kontakt.png
Normal file
After Width: | Height: | Size: 561 B |
BIN
plugins/buena/img/klufthemd.png
Normal file
After Width: | Height: | Size: 78 KiB |
BIN
plugins/buena/img/leitbild_Kontakt_low.jpg
Normal file
After Width: | Height: | Size: 60 KiB |
BIN
plugins/buena/img/leitbild_Kontakt_low_klein.jpg
Normal file
After Width: | Height: | Size: 6.2 KiB |
BIN
plugins/buena/img/leitbild_aktionen_low.jpg
Normal file
After Width: | Height: | Size: 57 KiB |
BIN
plugins/buena/img/leitbild_aktionen_low_klein.jpg
Normal file
After Width: | Height: | Size: 8.3 KiB |
BIN
plugins/buena/img/leitbild_bund.jpg
Normal file
After Width: | Height: | Size: 64 KiB |
BIN
plugins/buena/img/leitbild_bund_crop.jpg
Normal file
After Width: | Height: | Size: 62 KiB |
BIN
plugins/buena/img/leitbild_bund_crop_klein.jpg
Normal file
After Width: | Height: | Size: 8.8 KiB |
BIN
plugins/buena/img/leitbild_ihs.jpg
Normal file
After Width: | Height: | Size: 119 KiB |
BIN
plugins/buena/img/leitbild_ihs_klein.jpg
Normal file
After Width: | Height: | Size: 9.5 KiB |
BIN
plugins/buena/img/leitbild_int2_low.jpg
Normal file
After Width: | Height: | Size: 66 KiB |
BIN
plugins/buena/img/leitbild_int2_low_klein.jpg
Normal file
After Width: | Height: | Size: 8.3 KiB |
BIN
plugins/buena/img/leitbild_pfadfinden_low.jpg
Normal file
After Width: | Height: | Size: 63 KiB |
BIN
plugins/buena/img/leitbild_pfadfinden_low_klein.jpg
Normal file
After Width: | Height: | Size: 8.5 KiB |
BIN
plugins/buena/img/loeffel-topf.png
Normal file
After Width: | Height: | Size: 34 KiB |
1
plugins/buena/img/lupe.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 2400 2400" width="14" height="14"><path style="fill:#fff;stroke:none" d="m 975,25 q 129,0 252,34 123,34 227,95.5 104,61.5 191.5,149 87.5,87.5 149,192 61.5,104.5 95.5,227.5 34,123 34,251 0,278 -152,514 l 588,588 q 15,14 15,35 0,21 -15,36 l -213,213 q -15,15 -36,15 -21,0 -35,-15 l -588,-588 q -235,152 -513,152 -129,0 -252,-34 Q 600,1856 496,1794.5 392,1733 304,1645.5 216,1558 155,1453.5 94,1349 59.5,1226 25,1103 25,974.5 25,846 59.5,723 94,600 155,495.5 216,391 304,303.5 392,216 496,154.5 600,93 723,59 846,25 975,25 Z m -0.5,302 Q 843,327 723,378 603,429 516.5,516 430,603 378.5,723 327,843 327,974.5 q 0,131.5 51.5,251.5 51.5,120 138,207 86.5,87 206.5,138 120,51 251.5,51 131.5,0 251.5,-51 120,-51 207,-138 87,-87 138.5,-207 Q 1623,1106 1623,974.5 1623,843 1571.5,723 1520,603 1433,516 1346,429 1226,378 1106,327 974.5,327 Z" /></svg>
|
After Width: | Height: | Size: 907 B |
1
plugins/buena/img/schatten.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns='http://www.w3.org/2000/svg' height='300' width='470' viewBox='0 0 300 425' preserveAspectRatio='xMinYMin meet'><defs><linearGradient id='v' x1='0' y1='0' x2='0' y2='140%'><stop offset='0' stop-color='#000' stop-opacity='0.7' /><stop offset='50%' stop-color='#000' stop-opacity='0.4' /><stop offset='80%' stop-color='#000' stop-opacity='0.1' /><stop offset='100%' stop-color="#000" stop-opacity='0' /></linearGradient></defs><path d='M10,200 C150,170 450,180 615,190 L608,00 L15,0 Z' style='stroke:none;' fill='url(#v)'></path></svg>
|
After Width: | Height: | Size: 545 B |
BIN
plugins/buena/img/streichholzschachtel.png
Normal file
After Width: | Height: | Size: 21 KiB |
103
plugins/buena/readme.txt
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
Buena
|
||||||
|
=======
|
||||||
|
|
||||||
|
Das WordPress-Theme zum neuen Corporate Design des BdP.
|
||||||
|
|
||||||
|
Änderungswünsche? Kritik?
|
||||||
|
philipp.cordes@pfadfinden.de
|
||||||
|
|
||||||
|
|
||||||
|
Anderthalb Hinweise zur Benutzung
|
||||||
|
-----------------------------------
|
||||||
|
|
||||||
|
Das Theme ist noch nicht ganz fertig, an einigen Stellen wird noch gehobelt.
|
||||||
|
|
||||||
|
In Beiträgen mögt ihr bitte erst Überschriften ab 3. Ordnung verwenden,
|
||||||
|
die erster Ordnung sind für den Header und die zweiter Ordnung sind für
|
||||||
|
die Titel der Beiträge. Es gibt dafür auch fette Hinweise beim Bearbeiten.
|
||||||
|
|
||||||
|
|
||||||
|
Eine kleine Änderungshistorie
|
||||||
|
-------------------------------
|
||||||
|
|
||||||
|
v1.0 - TODO
|
||||||
|
- Das Abschalten des Posterbilds für ist Seiten und Beiträge ohne Bild möglich.
|
||||||
|
- Beitragsarten und deren unterschiedliche Darstellung ist auch für Seiten verfügbar.
|
||||||
|
- Schmale Beitragsbilder (<1300px Breite) zerlegen das Layout nicht mehr.
|
||||||
|
- Login-Formular im Widgetbereich unterstützen.
|
||||||
|
|
||||||
|
v0.99.7 - 21.09.2015
|
||||||
|
- Safari bricht jetzt Artikelauflistungen richtig um. Die anderen machen es auch etwas besser.
|
||||||
|
- Safari zeigt jetzt Suchfelder richtig an.
|
||||||
|
- Safari malt die Trennline in der Navigation nicht mehr zu dick.
|
||||||
|
- Wenn das Ajax-Login-Formular benutzt wird, verschwindet das Hamburgermenü nicht mehr.
|
||||||
|
|
||||||
|
v0.99.6 - 19.09.2015
|
||||||
|
- Weitere Blau- und Gelbtöne einheitlich umgesetzt, v.a. im Editor.
|
||||||
|
- Update für Milu: Zusatz „Kategorie“ wird im Titel auf abendlager.pfadfinden.de nicht mehr angezeigt.
|
||||||
|
- Der linke Rand wird jetzt immer eingehalten, egal wie lang der Navigationsbereich ist.
|
||||||
|
- Anpassung an WordPress 4.3: Favicon kommt nur aus dem Theme, wenn kein eigenes gesetzt ist.
|
||||||
|
- Der Hinweis, dass Kommentare nicht möglich sind, wird standardmäßig ausgeblendet.
|
||||||
|
- Links in der Navigation färben sich jetzt anhand der Hierarchie im Menü ein, nicht derer der Seiten.
|
||||||
|
|
||||||
|
v0.99.5 - 19.08.2015
|
||||||
|
- Seitentitel beschreiben jetzt besser, was tatsächlich angezeigt wird.
|
||||||
|
- Farben aus dem Handbuch einheitlich umgesetzt.
|
||||||
|
|
||||||
|
v0.99.4 - 13.08.2015
|
||||||
|
- Das Menü wird automatisch wieder eingeblendet, wenn die Fensterbreite über 720px steigt.
|
||||||
|
- Fehlerkorrektur: Es werden keine Urls mehr unter dem Editorfeld ausgegeben.
|
||||||
|
- Das Theme ist nicht mehr auf das Plugin angewiesen. Die benötigte Bilbiothek shy-wordpress wird direkt mitgeliefert.
|
||||||
|
|
||||||
|
v0.99.3 - 01.08.2015
|
||||||
|
- Der Editor sollte jetzt in den meisten Fällen eine realistische Vorschau bieten.
|
||||||
|
- Überschriften sind jetzt blau auf gelb.
|
||||||
|
Überschriften erster und zweiter Ordnung in Beiträgen und Seiten werden durch Überschriften dritter Ordnung ersetzt.
|
||||||
|
- Schrift „Immenhausen“ durch verbesserte Variante ausgetauscht.
|
||||||
|
- Kleinere Korrekturen an Abständen.
|
||||||
|
|
||||||
|
v0.99.2 - 27.07.2015
|
||||||
|
- Kleinere Textanpassungen.
|
||||||
|
|
||||||
|
v0.99.1 - 27.07.2015
|
||||||
|
- Auf großen Displays wird das Beitragsbild nicht mehr verzerrt.
|
||||||
|
|
||||||
|
v0.99 - 26.07.2015
|
||||||
|
- Erster Kandidat zur Veröffentlichung als Version 1.0.
|
||||||
|
- Die Überschriften erstrahlen in vollem Glanz.
|
||||||
|
- Kommentare sehen besser aus.
|
||||||
|
- Das Theme ist responsive bis runter auf 300px.
|
||||||
|
- Fußleiste überarbeitet und zweigeteilt.
|
||||||
|
|
||||||
|
v0.9.1 - 07.07.2015
|
||||||
|
- Fehlerkorrektur: Der Titel wird nicht mehr doppelt angezeigt.
|
||||||
|
|
||||||
|
v0.9 - 03.07.2015
|
||||||
|
- Kommentare werden jetzt angezeigt.
|
||||||
|
- Etwas mehr responsive: Mindestbreite 700px für ordentliche Anzeige.
|
||||||
|
|
||||||
|
v0.8 - 21.06.2015
|
||||||
|
- Standardwidgets sehen jetzt in der Leiste gut aus.
|
||||||
|
- Die Fußzeile sitzt jetzt fester an ihrem Platz.
|
||||||
|
|
||||||
|
v0.7 - 18.06.2015
|
||||||
|
- Große Posterbilder hinzugefügt, die auch auf der Bundeswebseite zu sehen sind.
|
||||||
|
- Erhebliche Verbesserungen der Darstellung.
|
||||||
|
|
||||||
|
v0.6 - 16.06.2015
|
||||||
|
- Mehr Unterstützung für HTML5.
|
||||||
|
|
||||||
|
v0.5 - 16.06.2015
|
||||||
|
- Fehler behoben, der die WordPress-Installation unbrauchbar machen könnte.
|
||||||
|
|
||||||
|
v0.4 - 11.06.2015
|
||||||
|
- Navigation überarbeitet.
|
||||||
|
|
||||||
|
v0.3 - 10.06.2015
|
||||||
|
- Webfont Immenhausen für Überschriften.
|
||||||
|
|
||||||
|
v0.2 - 04.06.2015
|
||||||
|
- Grafiken eingebaut.
|
||||||
|
|
||||||
|
v0.1 - 20.04.2015
|
||||||
|
- Erste Veröffentlichung.
|
BIN
plugins/buena/screenshot.png
Normal file
After Width: | Height: | Size: 336 KiB |
24
plugins/buena/src/Pfadfinden/WordPress/BuenaSettings.php
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace plugins\buena\src\Pfadfinden\WordPress;
|
||||||
|
|
||||||
|
use Pfadfinden\WordPress\wordpress;
|
||||||
|
use wordpress\src\Shy\WordPress\CompositeOption;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class BuenaSettings extends wordpress\src\Shy\WordPress\CompositeOption
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct( 'buena-theme' );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDefaults()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'use_cdn' => false,
|
||||||
|
'always_show_poster' => true,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
32
plugins/buena/src/Pfadfinden/WordPress/BuenaSettingsPage.php
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace plugins\buena\src\Pfadfinden\WordPress;
|
||||||
|
|
||||||
|
use Shy\WordPress\Administration\SettingsPage;
|
||||||
|
use Shy\WordPress\Administration\CheckboxField;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class BuenaSettingsPage extends SettingsPage
|
||||||
|
{
|
||||||
|
public function getFields()
|
||||||
|
{
|
||||||
|
$this->addSection( '', 'buena' );
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'use_cdn' => new CheckboxField(),
|
||||||
|
'always_show_poster' => new CheckboxField(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function getParentSlug()
|
||||||
|
{
|
||||||
|
return 'themes.php';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTitle()
|
||||||
|
{
|
||||||
|
return __( 'Buena-Einstellungen', 'buena-theme' );
|
||||||
|
}
|
||||||
|
}
|
320
plugins/buena/src/Pfadfinden/WordPress/BuenaTheme.php
Normal file
@ -0,0 +1,320 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace plugins\buena\src\Pfadfinden\WordPress;
|
||||||
|
|
||||||
|
use Pfadfinden\WordPress\wordpress;
|
||||||
|
use plugins\buena\src\Pfadfinden\WordPress\BuenaSettings;
|
||||||
|
use plugins\buena\src\Pfadfinden\WordPress\BuenaSettingsPage;
|
||||||
|
use wordpress\src\Shy\WordPress\Theme;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class BuenaTheme extends wordpress\src\Shy\WordPress\Theme
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var BuenaSettings
|
||||||
|
*/
|
||||||
|
protected $settings;
|
||||||
|
|
||||||
|
|
||||||
|
public function getContentWidth()
|
||||||
|
{
|
||||||
|
return 684;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->settings = new BuenaSettings();
|
||||||
|
|
||||||
|
$this->addHookMethod( 'after_setup_theme', 'afterSetupTheme' );
|
||||||
|
$this->addHookMethod( 'wp_enqueue_scripts', 'enqueueScriptsStyles' );
|
||||||
|
|
||||||
|
$this->addHookMethod( 'buena_search_form', 'printSearchForm' );
|
||||||
|
|
||||||
|
$this->addHookMethod( 'admin_init', 'initAdministration' );
|
||||||
|
$this->addHookMethod( 'mce_css', 'filterEditorStylesheets' );
|
||||||
|
|
||||||
|
$this->addHookMethod( 'wp_page_menu', 'filterPageMenu' );
|
||||||
|
$this->addHookMethod( 'widgets_init', 'registerSidebars' );
|
||||||
|
|
||||||
|
$this->addHookMethod( 'the_content', 'filterContent' );
|
||||||
|
|
||||||
|
$this->addHookMethod( 'image_size_names_choose', 'filterImageSizeNames' );
|
||||||
|
$this->addHookMethod( 'media_upload_tabs', 'filterMediaTabs' );
|
||||||
|
$this->addHookMethod( 'media_view_settings', 'filterMediaViewSettings' );
|
||||||
|
$this->addHookMethod( 'media_view_strings', 'filterMediaViewSettings' );
|
||||||
|
$this->addHookMethod( 'print_media_templates', 'printMediaTemplates' );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function afterSetupTheme()
|
||||||
|
{
|
||||||
|
add_theme_support( 'title-tag' );
|
||||||
|
add_theme_support( 'automatic-feed-links' );
|
||||||
|
|
||||||
|
register_nav_menu( 'primary', __( 'Hauptmenü', 'buena-theme' ) );
|
||||||
|
register_nav_menu( 'footer', __( 'Fußzeile', 'buena-theme' ) );
|
||||||
|
|
||||||
|
add_theme_support( 'html5', [
|
||||||
|
'comment-list', 'comment-form', 'search-form', 'gallery', 'caption',
|
||||||
|
] );
|
||||||
|
|
||||||
|
add_theme_support( 'post-thumbnails' );
|
||||||
|
$custom_header = [
|
||||||
|
'width' => apply_filters( 'buena_header_image_width', 1300 ),
|
||||||
|
'height' => apply_filters( 'buena_header_image_height', 635 ),
|
||||||
|
'flex-width' => true,
|
||||||
|
'flex-height' => true,
|
||||||
|
'default-image' => get_template_directory_uri() . '/img/leitbild_aktionen_low.jpg',
|
||||||
|
'uploads' => true,
|
||||||
|
'header-text' => false,
|
||||||
|
];
|
||||||
|
add_theme_support( 'custom-header', $custom_header );
|
||||||
|
set_post_thumbnail_size( $custom_header['width'], $custom_header['height'], true );
|
||||||
|
|
||||||
|
add_image_size( 'gallery-thumb', 350, 165, true );
|
||||||
|
|
||||||
|
register_default_headers( [
|
||||||
|
'aktionen' => [
|
||||||
|
'url' => '%s/img/leitbild_aktionen_low.jpg',
|
||||||
|
'thumbnail_url' => '%s/img/leitbild_aktionen_low_klein.jpg',
|
||||||
|
'description' => __( 'Leitbild Aktionen', 'buena-theme' ),
|
||||||
|
],
|
||||||
|
'bund' => [
|
||||||
|
'url' => '%s/img/leitbild_bund_crop.jpg',
|
||||||
|
'thumbnail_url' => '%s/img/leitbild_bund_crop_klein.jpg',
|
||||||
|
'description' => __( 'Leitbild Bund', 'buena-theme' ),
|
||||||
|
],
|
||||||
|
'ihs' => [
|
||||||
|
'url' => '%s/img/leitbild_ihs.jpg',
|
||||||
|
'thumbnail_url' => '%s/img/leitbild_ihs_klein.jpg',
|
||||||
|
'description' => __( 'Leitbild Immenhausen', 'buena-theme' ),
|
||||||
|
],
|
||||||
|
'international' => [
|
||||||
|
'url' => '%s/img/leitbild_int2_low.jpg',
|
||||||
|
'thumbnail_url' => '%s/img/leitbild_int2_low_klein.jpg',
|
||||||
|
'description' => __( 'Leitbild International', 'buena-theme' ),
|
||||||
|
],
|
||||||
|
'kontakt' => [
|
||||||
|
'url' => '%s/img/leitbild_Kontakt_low.jpg',
|
||||||
|
'thumbnail_url' => '%s/img/leitbild_Kontakt_low_klein.jpg',
|
||||||
|
'description' => __( 'Leitbild Kontakt', 'buena-theme' ),
|
||||||
|
],
|
||||||
|
'pfadfinden' => [
|
||||||
|
'url' => '%s/img/leitbild_pfadfinden_low.jpg',
|
||||||
|
'thumbnail_url' => '%s/img/leitbild_pfadfinden_low_klein.jpg',
|
||||||
|
'description' => __( 'Leitbild Pfadfinden', 'buena-theme' ),
|
||||||
|
],
|
||||||
|
] );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTeaserImage()
|
||||||
|
{
|
||||||
|
if ( is_page() || have_posts() && is_single() ) { // FIXME: is_singular()?
|
||||||
|
the_post();
|
||||||
|
$thumb = get_the_post_thumbnail( null, 'post-thumbnail', [ 'alt' => '' ] );
|
||||||
|
rewind_posts();
|
||||||
|
|
||||||
|
if ( $thumb ) {
|
||||||
|
return $thumb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( is_home() || $this->settings['always_show_poster'] ) {
|
||||||
|
return sprintf(
|
||||||
|
'<img src="%s" height="%d" width="%d" alt="" />',
|
||||||
|
get_header_image(),
|
||||||
|
get_custom_header()->height,
|
||||||
|
get_custom_header()->width
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gibt einen Titel für die aktuelle Seite aus.
|
||||||
|
*/
|
||||||
|
public function printTitle()
|
||||||
|
{
|
||||||
|
if ( is_singular() ) {
|
||||||
|
the_title();
|
||||||
|
} elseif ( is_category() && strpos( $_SERVER['HTTP_HOST'], 'abendlager.pfadfinden.de' ) !== false ) {
|
||||||
|
// FIXME: Workaround mit 1.0 entfernen.
|
||||||
|
single_cat_title( '', true );
|
||||||
|
} elseif ( is_archive() ) {
|
||||||
|
the_archive_title();
|
||||||
|
} elseif ( is_search() ) {
|
||||||
|
esc_html_e( sprintf(
|
||||||
|
__( 'Suche nach „%s“', 'buena-theme' ),
|
||||||
|
get_search_query( false )
|
||||||
|
) );
|
||||||
|
} else {
|
||||||
|
bloginfo( 'description' );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function enqueueScriptsStyles()
|
||||||
|
{
|
||||||
|
wp_enqueue_style( 'immenhausen-font', get_template_directory_uri() . '/font/ihs.css' );
|
||||||
|
wp_enqueue_style( 'buena-style', get_stylesheet_uri() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gibt das Suchformular aus. Nötig, damit im Kopf anderer Code stehen kann als anderswo.
|
||||||
|
*/
|
||||||
|
public function printSearchForm()
|
||||||
|
{
|
||||||
|
get_search_form( true );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tut, was dransteht.
|
||||||
|
*/
|
||||||
|
public function registerSidebars()
|
||||||
|
{
|
||||||
|
register_sidebar( [
|
||||||
|
'id' => 'below-navigation',
|
||||||
|
'name' => __( 'Unter Navigation', 'buena-theme' ),
|
||||||
|
'description' => __( 'Ziemlich schmal.', 'buena-theme' ),
|
||||||
|
'before_title' => '<h4 class="h-widget">',
|
||||||
|
'after_title' => '</h4>',
|
||||||
|
] );
|
||||||
|
register_sidebar( [
|
||||||
|
'id' => 'footer',
|
||||||
|
'name' => __( 'Fußleiste', 'buena-theme' ),
|
||||||
|
'description' => __( 'Rechte Spalte des Briefumschlags. Recht flach. Füllt die ganze Breite aus, wenn kein Navigationsmenü zugewiesen ist.', 'buena-theme' ),
|
||||||
|
'before_title' => '<h4 class="h-widget">',
|
||||||
|
'after_title' => '</h4>',
|
||||||
|
] );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ausgabe von wp_page_menu() filtern, dass sie wie wp_nav_menu() aussieht.
|
||||||
|
*
|
||||||
|
* @param string $menu
|
||||||
|
* @param array $args
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function filterPageMenu( $menu, array $args )
|
||||||
|
{
|
||||||
|
if ( ! isset( $args['fallback_cb'] ) || $args['fallback_cb'] !== 'wp_page_menu' ) {
|
||||||
|
return $menu;
|
||||||
|
}
|
||||||
|
|
||||||
|
$vorher = '<div class="' . esc_attr( $args['menu_class'] ) . '">';
|
||||||
|
|
||||||
|
$danach = '<' . $args['container'];
|
||||||
|
if ( $args['container_class'] ) {
|
||||||
|
// In diesem Fall doch optional…
|
||||||
|
$danach .= ' class="' . esc_attr( $args['container_class'] ) . '"';
|
||||||
|
}
|
||||||
|
if ( $args['container_id'] ) {
|
||||||
|
$danach .= ' id="' . esc_attr( $args['container_id'] ) . '"';
|
||||||
|
}
|
||||||
|
$danach .= '>';
|
||||||
|
|
||||||
|
if ( strpos( $menu, '<ul>' ) !== false ) {
|
||||||
|
// Wenn das Menü leer ist, enthält es den <ul>-Teil nicht.
|
||||||
|
$vorher .= '<ul>';
|
||||||
|
$danach .= '<ul class="' . esc_attr( $args['menu_class'] ) . '">';
|
||||||
|
}
|
||||||
|
|
||||||
|
$menu = str_replace( $vorher, $danach, $menu );
|
||||||
|
$menu = substr( $menu, 0, -5 ) . $args['container'] . ">\n";
|
||||||
|
|
||||||
|
$menu = str_replace( "class='children'", 'class="sub-menu"', $menu );
|
||||||
|
$menu = str_replace( 'current_page_item', 'current_page_item current-menu-item', $menu );
|
||||||
|
$menu = str_replace( 'current_page_ancestor', 'current_page_ancestor current-menu-ancestor', $menu );
|
||||||
|
|
||||||
|
return $menu;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zusatzfunktionen für das Backend laden.
|
||||||
|
*/
|
||||||
|
public function initAdministration()
|
||||||
|
{
|
||||||
|
if ( isset( $_GET['exp'] ) && class_exists( 'plugins\buena\src\Pfadfinden\WordPress\BuenaSettingsPage' ) ) {
|
||||||
|
new BuenaSettingsPage( $this->settings );
|
||||||
|
}
|
||||||
|
|
||||||
|
add_editor_style();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard-Skin des Editors rauswerfen.
|
||||||
|
*
|
||||||
|
* @param string $stylesheets
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function filterEditorStylesheets( $stylesheets )
|
||||||
|
{
|
||||||
|
$stylesheets = explode( ',', $stylesheets );
|
||||||
|
$stylesheets = array_filter( $stylesheets, function ( $url ) {
|
||||||
|
return strpos( $url, 'tinymce' ) === false;
|
||||||
|
} );
|
||||||
|
|
||||||
|
return implode( ',', $stylesheets );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Überschriften <h1> und <h2> durch <h3> ersetzen.
|
||||||
|
*
|
||||||
|
* @param string $content
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function filterContent( $content )
|
||||||
|
{
|
||||||
|
$content = preg_replace( '/\\<h[12]([^>]*)>(.*?)\\<\\/h[12]>/', '<h3$1>$2</h3>', $content );
|
||||||
|
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $names
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function filterImageSizeNames( array $names )
|
||||||
|
{
|
||||||
|
return $names;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $tabs
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function filterMediaTabs( $tabs )
|
||||||
|
{
|
||||||
|
return $tabs;
|
||||||
|
return $tabs + [
|
||||||
|
'insert-poster' => __( 'Posterbilder', 'buena-theme' ),
|
||||||
|
];
|
||||||
|
// Erzeugt einen <iframe> von wp-admin/media-upload.php?chromeless=1&post_id=123456&tab=insert-poster
|
||||||
|
}
|
||||||
|
|
||||||
|
public function filterMediaViewSettings( $settings )
|
||||||
|
{
|
||||||
|
//var_dump( $settings );
|
||||||
|
return $settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Weitere Templates für Medienbrowser ausgeben.
|
||||||
|
*/
|
||||||
|
public function printMediaTemplates()
|
||||||
|
{
|
||||||
|
global $_wp_default_headers;
|
||||||
|
?>
|
||||||
|
<script type="text/html" id="tmpl-insert-poster">
|
||||||
|
<ul>
|
||||||
|
<?php foreach ( $_wp_default_headers as $k => $header ) : ?>
|
||||||
|
<img alt="<?php esc_attr_e( $header['description'] ); ?>" src="<?php echo esc_url( sprintf( $header['thumbnail_url'], get_template_directory_uri() ) ); ?>" />
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</ul>
|
||||||
|
</script>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
}
|
250
plugins/buena/style.css
Normal file
@ -0,0 +1,250 @@
|
|||||||
|
@charset "UTF-8";
|
||||||
|
/**
|
||||||
|
Theme Name: Buena
|
||||||
|
Version: 0.99.7
|
||||||
|
Theme URI: http://lab.hanseaten-bremen.de/themes/buena/
|
||||||
|
Author: Philipp Cordes <philipp.cordes@pfadfinden.de>
|
||||||
|
Description: Das neue Corporate Design, jetzt auch für WordPress.
|
||||||
|
License: Proprietary
|
||||||
|
Tags: one-column, three-columns, responsive-layout, automatic-feed-links, post-thumbnails, featured-images, custom-menu, blue, white, yellow, editor-style
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Farben:
|
||||||
|
- gelb: #ffcb04 (Handbuch, manchmal T3), #ffca28 (T3)
|
||||||
|
- Verlauf: #9f7515 bis #e1af22, #e0cb84 bis #fff (IE-Fallback)
|
||||||
|
- blass: #fff5d9 (T3-Zebra)
|
||||||
|
- blau: #1d4899 (Handbuch, manchmal T3), #0d52a5 (T3)
|
||||||
|
- Markierung (T3): #b3d4fc
|
||||||
|
*/
|
||||||
|
|
||||||
|
html, body { border: 0 none; padding: 0; margin: 0; min-height: 100%; position: static; }
|
||||||
|
html { font-family: Sans-Serif; font-size: 81.3%; background: url("img/holz.jpg") #dbb97b; position: relative; }
|
||||||
|
header, hgroup, nav, footer, article { display: block; }
|
||||||
|
.h, h1, .h1, h2, .h2, h3, .h3, h4, .h4, h5, .h5, h6, .h6 { margin: 0; font-family: IHS, Serif; font-size: 1em; font-weight: normal; font-style: normal; }
|
||||||
|
button, input, select, optgroup, option { margin: 0; font: inherit; color: inherit; }
|
||||||
|
button, input[type="button"], input[type="submit"], input[type="reset"] { cursor: pointer; }
|
||||||
|
input[type="search"] { -webkit-appearance: textfield; }
|
||||||
|
p, ul, ol, dt { line-height: 1.5; }
|
||||||
|
abbr { border-bottom: 1px dotted; }
|
||||||
|
a { color: #1d4899; }
|
||||||
|
figure, .wp-caption { margin: 0; max-width: 100%; }
|
||||||
|
figcaption, .wp-caption-text { font-style: italic; padding: 0.5em 0; }
|
||||||
|
.screen-reader-text { display: none; }
|
||||||
|
.aligncenter { margin: 0 auto; }
|
||||||
|
.alignleft { float: left; margin: 0 1em 0 0; }
|
||||||
|
.alignright { float: right; margin: 0 0 0 1em; }
|
||||||
|
|
||||||
|
::-moz-selection { background: #1d4899; color: #ffcb04; text-shadow: none; outline: 2px solid #1d4899; }
|
||||||
|
::selection { background: #1d4899; color: #ffcb04; text-shadow: none; outline: 2px solid #1d4899; }
|
||||||
|
|
||||||
|
/* Media object */
|
||||||
|
.media { margin: 1em 0; }
|
||||||
|
.media, .bd { overflow: hidden; _overflow: visible; }
|
||||||
|
/*.media img { display: block; }*/
|
||||||
|
/* Clearfix */
|
||||||
|
.clearfix::after,
|
||||||
|
.clearfix::before,
|
||||||
|
.media::after,
|
||||||
|
.media::before { content: " "; display: table; }
|
||||||
|
.clearfix::after,
|
||||||
|
.media::after { clear: both; }
|
||||||
|
|
||||||
|
/* Layout */
|
||||||
|
#wrap { background: url("img/klufthemd.png") no-repeat; padding: 0 0 2em; }
|
||||||
|
#footer { background: url("img/loeffel-topf.png") no-repeat 100% 100%; position: absolute; width: 100%; bottom: 0; }
|
||||||
|
#footer .wrapper { background: url("img/briefumschlag.png") no-repeat; margin: 0 0 0 240px; padding: 112px 7px 0 21px; height: 286px; width: 700px; box-sizing: border-box; }
|
||||||
|
#footer header { color: #ffcb04; text-align: center; font-size: 25px; margin: -111px 0 13px; line-height: 111px; }
|
||||||
|
#footer .widgets { padding: 0 2em 0 0; }
|
||||||
|
|
||||||
|
#left { margin: -18px -200px 0 40px; width: 160px; z-index: 30; float: left; position: relative; }
|
||||||
|
#main { overflow: hidden; padding: 0 0 286px 240px; }
|
||||||
|
@media (max-width: 960px) {
|
||||||
|
/* Umschlag unter die Navigation umbrechen */
|
||||||
|
#left { margin-bottom: 300px; }
|
||||||
|
#footer .wrapper { margin-left: 0; }
|
||||||
|
}
|
||||||
|
@media (max-width: 720px) {
|
||||||
|
#main { padding-left: 0; }
|
||||||
|
#left { margin-right: 0; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: Positionierung des Schattens weiter vereinfachen, auch Untertitel verlinken. */
|
||||||
|
/* FIXME: Branding umbenennen, siehe https://github.com/pfadfinden/wordpress-theme-updater/issues/13 */
|
||||||
|
#branding { min-height: 145px; padding: 0 33px 20px 240px; text-align: center; position: relative; width: 425px; margin-bottom: -27px; }
|
||||||
|
#branding::after { content: ""; display: block; position: absolute; bottom: 0; right: 0; z-index: 15; height: 143px; width: 457px; background: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIGhlaWdodD0nMzAwJyB3aWR0aD0nNDcwJyB2aWV3Qm94PScwIDAgMzAwIDQyNScgcHJlc2VydmVBc3BlY3RSYXRpbz0neE1pbllNaW4gbWVldCc+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSd2JyB4MT0nMCcgeTE9JzAnIHgyPScwJyB5Mj0nMTQwJSc+PHN0b3Agb2Zmc2V0PScwJyBzdG9wLWNvbG9yPScjMDAwJyBzdG9wLW9wYWNpdHk9JzAuNycgLz48c3RvcCBvZmZzZXQ9JzUwJScgc3RvcC1jb2xvcj0nIzAwMCcgc3RvcC1vcGFjaXR5PScwLjQnIC8+PHN0b3Agb2Zmc2V0PSc4MCUnIHN0b3AtY29sb3I9JyMwMDAnIHN0b3Atb3BhY2l0eT0nMC4xJyAvPjxzdG9wIG9mZnNldD0nMTAwJScgc3RvcC1jb2xvcj0iIzAwMCIgc3RvcC1vcGFjaXR5PScwJyAvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxwYXRoIGQ9J00xMCwyMDAgQzE1MCwxNzAgNDUwLDE4MCA2MTUsMTkwIEw2MDgsMDAgTDE1LDAgWicgc3R5bGU9J3N0cm9rZTpub25lOycgZmlsbD0ndXJsKCN2KSc+PC9wYXRoPjwvc3ZnPg0K") no-repeat 50% 0; }
|
||||||
|
#branding > * { margin: 0; position: relative; z-index: 20; }
|
||||||
|
.site-title { font-size: 20px; background: #ffcb04; color: #0d53a5; margin-top: auto; line-height: 115px; }
|
||||||
|
.site-title a { display: block; vertical-align: bottom; }
|
||||||
|
.site-title img { vertical-align: bottom; padding-bottom: 16px; }
|
||||||
|
.site-description { font-size: 18px; background: #0d53a5; color: #ffcb04; line-height: 30px; font-family: IHS, Serif; letter-spacing: 1px; word-spacing: 2px; }
|
||||||
|
|
||||||
|
#header .search-form { background: url("img/streichholzschachtel.png") no-repeat; position: absolute; height: 89px; left: 750px; top: 1.5em; width: 98px; padding: 25px 47px 0 35px; }
|
||||||
|
#header .search-form label { display: block; position: relative; margin: 25px 0 -50px; text-align: left; }
|
||||||
|
#header .search-field { background: transparent; border: 2px solid #ffcb04; padding: 2px; color: #fff; display: block; max-width: 100%; box-sizing: border-box; }
|
||||||
|
#header .search-submit { background: transparent; color: #ffcb04; border: 0 none; font-family: IHS, Serif; font-size: 1.4em; padding: 0; display: block; box-sizing: border-box; }
|
||||||
|
#header > nav { position: absolute; top: 0; right: 0; z-index: 9999; display: none; }/* FIXME: Workaround Branding-Doppelung */
|
||||||
|
#responsiveMenu { border: 0 none; background: transparent; height: 51px; margin: 1em; }
|
||||||
|
@media (max-width: 960px) { /* Suche ausblenden */
|
||||||
|
#header .search-form { display: none; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-menu ul { list-style: none; padding: 0; margin: 0; }
|
||||||
|
.nav-menu-primary > ul { font-family: IHS, Serif; }
|
||||||
|
.nav-menu-primary > ul > .current-menu-ancestor,
|
||||||
|
.nav-menu-primary > ul > .current-menu-item { background: #e1af22 no-repeat; background-image: linear-gradient(#9f7515 0%, #e1af22 100%); border-bottom: 1px solid #9f7515; border-top: 1px solid #9f7515; margin: 0.5em 0; padding: 0.5em 0; }
|
||||||
|
.nav-menu-primary .sub-menu { display: none; }
|
||||||
|
.nav-menu-primary a { padding: 0.4em 0.5em 0.4em 1em; display: block; text-decoration: none; color: #6b5742; font-size: 1.4em; }
|
||||||
|
.nav-menu-primary li ul a { font-family: Georgia, Serif; font-size: 12px; font-style: italic; padding: 5px 5px 5px 25px; color: #000; }
|
||||||
|
.nav-menu-primary .current-menu-ancestor .sub-menu,
|
||||||
|
.nav-menu-primary .current-menu-item .sub-menu { display: block; }
|
||||||
|
.nav-menu-primary .current-menu-ancestor a { color: #000; }
|
||||||
|
.nav-menu-primary .current-menu-item > a { color: #fff; }
|
||||||
|
.nav-menu-primary a:hover,
|
||||||
|
.nav-menu-primary a:focus { color: #000; }
|
||||||
|
.nav-menu .current-menu-ancestor a:hover,
|
||||||
|
.nav-menu .current-menu-ancestor a:focus,
|
||||||
|
.nav-menu .sub-menu a:hover,
|
||||||
|
.nav-menu .sub-menu a:focus,
|
||||||
|
.nav-menu-footer a:hover,
|
||||||
|
.nav-menu-footer a:focus { text-decoration: underline; }
|
||||||
|
.nav-menu-footer { font-family: Georgia, Serif; font-style: italic; padding-left: 2em; }
|
||||||
|
.nav-menu-footer > ul { width: 323px; height: 174px; position: relative; display: flex; -webkit-flex-flow: column; flex-flow: column; -webkit-justify-content: center; justify-content: center; -webkit-align-items: stretch; align-items: stretch; }
|
||||||
|
.nav-menu-footer li { margin-bottom: 0.75em; }
|
||||||
|
.nav-menu-footer a { padding: 4px 4px 4px 25px; text-decoration: none; }
|
||||||
|
|
||||||
|
.widget_recent_entries > ul,
|
||||||
|
.widget_recent_comments > ul,
|
||||||
|
.widget_archive > ul,
|
||||||
|
.widget_categories > ul,
|
||||||
|
.widget_meta > ul { list-style: none; padding: 0; margin: 0; }
|
||||||
|
|
||||||
|
#left > .nav-menu { background: #ffcb04; color: #6b5742; padding: 10px 0 2em; }
|
||||||
|
#left > .widgets { background: rgba(56, 46, 35, 0.7); color: #ffcb04; padding: 1em 15px 15px 20px; font-size: 13px; font-style: italic; }
|
||||||
|
#left > .widgets a { color: #fff; text-decoration: none; }
|
||||||
|
#left > .widgets a:hover,
|
||||||
|
#left > .widgets a:focus { text-decoration: underline; }
|
||||||
|
|
||||||
|
/* Widgets: Basisdarstellung */
|
||||||
|
.widgets { list-style: none; padding: 0; margin: 0; font-family: Georgia, Serif; font-style: italic; }
|
||||||
|
.widget_calendar table { text-align: center; }
|
||||||
|
|
||||||
|
/* Widgets: Korrekturen für unsere Seitenleiste */
|
||||||
|
#left .widget_search form { display: flex; }
|
||||||
|
#left .widget_search form > * { border: 2px solid #ffcb04; }
|
||||||
|
#left .widget_search input { box-sizing: border-box; width: 100%; border: 0 none; background: transparent; color: #fff; text-align: center; padding: 3px 0.25em 4px; }
|
||||||
|
#left .widget_search button { color: transparent; background: url("res/lupe.svg") 50% 50% no-repeat #ffcb04; width: 31px; }
|
||||||
|
|
||||||
|
#left .widget_calendar > div { margin: 0 -15px 0 -20px; }
|
||||||
|
#left .widget_calendar > div > table { text-align: center; margin: 0 auto; }
|
||||||
|
|
||||||
|
#left .widget_pages ul { padding-left: 2em; }
|
||||||
|
#left .widget_pages > ul { list-style: none; padding: 0; }
|
||||||
|
|
||||||
|
#left > .widgets .widget { margin: 0; padding: 1em 0; }
|
||||||
|
.widgets .h-widget { color: #ffcb04; font-size: 16px; }
|
||||||
|
#left > .widgets .menu,
|
||||||
|
.widgets .widget_categories ul { list-style: none; padding: 0; }
|
||||||
|
|
||||||
|
/* Überschriften mit Bild darunter */
|
||||||
|
.h-box { position: relative; display: block; margin-bottom: 1em; text-decoration: none; }
|
||||||
|
.h-box > img { position: absolute; top: 0; left: 0; height: 100%; width: 100%; }
|
||||||
|
.h-box > .wrap { position: absolute; max-width: 100%; left: 0; }
|
||||||
|
.h-box > .wrap > * { display: inline; -o-box-decoration-break: clone; -webkit-box-decoration-break: clone; box-decoration-break: clone; }
|
||||||
|
|
||||||
|
.h-box-teaser { box-shadow: 0 5px 5px rgba(0, 0, 0, 0.3); line-height: 1; display: inline-block; width: 1300px; max-width: 100%; }
|
||||||
|
.h-box-teaser > img { position: static; }
|
||||||
|
.h-box-teaser > .wrap { bottom: 1em; padding-left: 240px; }
|
||||||
|
.h-box-teaser > .wrap > * { background: rgba(56, 46, 35, 0.7); color: #ffcb04; padding: 2px 13px 4px; font-size: 52px; line-height: 78px; }
|
||||||
|
@media (max-width: 720px) {
|
||||||
|
.h-box-teaser { margin-top: 1em; margin-left: 0; }
|
||||||
|
.h-box-teaser > .wrap { padding-left: 1em; }
|
||||||
|
.h-box-teaser > .wrap > * { font-size: 2em; line-height: 39px; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.h-box-blaugelb { padding-top: 47.1428571%; }
|
||||||
|
.h-box-blaugelb > .wrap { bottom: 0; font-size: 18px; }
|
||||||
|
.h-box-blaugelb > .wrap > * { color: #1d4899; background: #ffcb04; padding: 3px 5px; line-height: 26px; }
|
||||||
|
|
||||||
|
.h-box-blaugelb-bildlos { padding: 0; }
|
||||||
|
.h-box-blaugelb-bildlos > .wrap { position: static; }
|
||||||
|
/**/
|
||||||
|
|
||||||
|
.container { max-width: 1020px; }
|
||||||
|
.page .container,
|
||||||
|
.single-post:not(.single-format-gallery) .container { max-width: 710px; }
|
||||||
|
|
||||||
|
.content-singular .format-gallery { background: transparent; padding: 0; margin: 0; position: relative; }
|
||||||
|
.content-singular .format-gallery .gallery { display: flex; -webkit-flex-wrap: wrap; flex-wrap: wrap; -webkit-align-content: space-between; align-content: space-between; -webkit-align-items: flex-start; align-items: flex-start; }
|
||||||
|
.content-singular .format-gallery .gallery-item { background: #fff; padding: 1em; margin: 0 1em 1em 0; }
|
||||||
|
.gallery-columns-1 .gallery-item { flex: 1 0 50%; }
|
||||||
|
.gallery-columns-2 .gallery-item { flex: 1 0 34%; }
|
||||||
|
.gallery-columns-3 .gallery-item { flex: 1 0 25%; }
|
||||||
|
.gallery-columns-4 .gallery-item { flex: 1 0 20%; }
|
||||||
|
|
||||||
|
.content-gallery { display: flex; position: relative; z-index: 10; -webkit-flex-wrap: wrap; flex-wrap: wrap; overflow: hidden; }
|
||||||
|
.container article,
|
||||||
|
.commentlist article,
|
||||||
|
.comment-form { padding: 1em; margin: 0 1em 1em 0; transition: width 0.5s, height 0.5s; box-sizing: border-box; }
|
||||||
|
.container article > :first-child,
|
||||||
|
.comment-form > :first-child { margin-top: 0; }
|
||||||
|
.container article > :last-child,
|
||||||
|
.comment-form > .form-submit { margin-bottom: 0; }
|
||||||
|
.content-singular > article:not(.format-gallery),
|
||||||
|
.content-gallery > article,
|
||||||
|
.commentlist article,
|
||||||
|
.comment-form { min-width: 20em; background: #fff; box-shadow: 0 5px 5px rgba(0, 0, 0, 0.1); }
|
||||||
|
.content-gallery > article { flex: 1 1 25%; max-width: calc(33.333% - 1em); }
|
||||||
|
@media (max-width: 1070px) { .content-gallery > article { flex: 1 1 34%; max-width: calc(50% - 1em); } }
|
||||||
|
@media (max-width: 800px) { .content-gallery > article { flex: 1 1 50%; max-width: 100%; } }
|
||||||
|
.container > .pagination { margin-right: 1em; }
|
||||||
|
|
||||||
|
/* WordPress-Wünsche */
|
||||||
|
.sticky {}
|
||||||
|
|
||||||
|
img { max-width: 100%; height: auto; border: 0 none; vertical-align: middle; }
|
||||||
|
ul, ol { padding-left: 2em; }
|
||||||
|
dl, ul, ol, h1, h2, h3, h4, h5, h6, blockquote, p, table { margin: 0.5em 0; }
|
||||||
|
dd, li > ol, li > ul { margin: 0; }
|
||||||
|
dt { font-weight: bold; }
|
||||||
|
blockquote, dd { padding-left: 2em; }
|
||||||
|
article > p:empty:last-child { margin: -0.5em 0 0.5em; }
|
||||||
|
article h3, article .h3, article h4, article .h4, article h5, article .h5, article h6, article .h6 { display: inline-block; background: #ffcb04; color: #1d4899; margin-bottom: 0; padding: 2px 4px; }
|
||||||
|
article h3, article .h3 { font-size: 18px; padding: 3px 5px; }
|
||||||
|
article h4, article .h4 { font-size: 16px; }
|
||||||
|
article h5, article .h5 { font-size: 14px; }
|
||||||
|
.gallery-caption {}
|
||||||
|
.bypostauthor {}
|
||||||
|
.twitter-tweet {}
|
||||||
|
|
||||||
|
/* Kommentare */
|
||||||
|
#comments, #reply-title { font-size: 2.5em; color: #fff; margin: 0.5em 0 0.25em; }
|
||||||
|
.commentlist { list-style: none; padding: 0; }
|
||||||
|
.commentlist .children { list-style: none; padding-left: 1em; }
|
||||||
|
.comment-form > p > * { vertical-align: top; }
|
||||||
|
.comment-form > p > label::after { content: ": "; }
|
||||||
|
.comment-body { position: relative; }
|
||||||
|
.comment-metadata { position: absolute; top: 1em; right: 1em; display: flex; -webkit-flex-direction: column; flex-direction: column; -webkit-justify-content: flex-end; justify-content: flex-end; }
|
||||||
|
.comment-form textarea { resize: vertical; display: block; box-sizing: border-box; width: 100%; }
|
||||||
|
|
||||||
|
/* Responsive: Der komplizierte Kram. Hurra! */
|
||||||
|
@media (max-width: 720px) { /* Gestapelt anordnen */
|
||||||
|
#main { padding-bottom: 0; }
|
||||||
|
#wrap, #footer .wrapper { background-image: none; }
|
||||||
|
#branding { text-align: left; width: auto; padding: 0; margin: 0; min-height: 0; }
|
||||||
|
#branding::after { display: none; background-image: none; }
|
||||||
|
#branding h1 { line-height: 51px; }
|
||||||
|
#branding h2 { padding: 0 1em; }
|
||||||
|
.site-title a { display: inline-block; }
|
||||||
|
.site-title img { height: 51px; width: auto; padding: 13px; }
|
||||||
|
#header > nav { display: block; }
|
||||||
|
#left { float: none; transition: 0.5s height; margin: 0; width: auto; }
|
||||||
|
#left, #left .widgets { display: none; }
|
||||||
|
.show-responsive-menu #left { display: block; }
|
||||||
|
#content, .comments { margin-left: 1em; }
|
||||||
|
#footer { background: #c4a164; position: static; }
|
||||||
|
#footer .wrapper { padding: 1em; height: auto; width: auto; }
|
||||||
|
#footer header { color: #000; margin: 0; line-height: 1.5; }
|
||||||
|
.nav-menu-footer, #footer .widgets { float: none; margin: 1em 0 0; padding: 1em; }
|
||||||
|
.nav-menu-footer > ul { height: auto; }
|
||||||
|
}
|
7
plugins/buena/use/shy-wordpress/.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# Eclipse project files
|
||||||
|
.buildpath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
|
||||||
|
# Local PHPUnit configuration
|
||||||
|
phpunit.xml
|
7
plugins/buena/use/shy-wordpress/phpunit.xml.dist
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<phpunit boostrap="tests/bootstrap.php">
|
||||||
|
<testsuites>
|
||||||
|
<testsuite>
|
||||||
|
<directory suffix="Test.php" phpVersion="5.4.0">tests</directory>
|
||||||
|
</testsuite>
|
||||||
|
</testsuites>
|
||||||
|
</phpunit>
|
@ -0,0 +1,97 @@
|
|||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: pfadfinden-theme-updater\n"
|
||||||
|
"POT-Creation-Date: 2015-08-26 01:49+0100\n"
|
||||||
|
"PO-Revision-Date: 2015-08-26 02:02+0100\n"
|
||||||
|
"Last-Translator: Philipp Cordes <philipp.cordes@pfadfinden.de>\n"
|
||||||
|
"Language-Team: \n"
|
||||||
|
"Language: de_DE\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"X-Generator: Poedit 1.6.10\n"
|
||||||
|
"X-Poedit-Basepath: ..\n"
|
||||||
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
|
"X-Poedit-SourceCharset: UTF-8\n"
|
||||||
|
"X-Poedit-KeywordsList: __;_e;_x;esc_html_e;esc_html__;esc_attr_e;esc_attr__;_ex:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2;_x:1,2c;_n:1,2;_n_noop:1,2;__ngettext_noop:1,2;_c,_nc:4c,1,2;\n"
|
||||||
|
"X-Poedit-SearchPath-0: .\n"
|
||||||
|
|
||||||
|
#: pfadfinden-theme-updater.php:70
|
||||||
|
msgid ""
|
||||||
|
"Couldn’t load required library “shy-wordpress”. Reinstalling the plugin may "
|
||||||
|
"solve this problem."
|
||||||
|
msgstr ""
|
||||||
|
"Konnte die erforderliche Bibliothek „shy-wordpress“ nicht laden. "
|
||||||
|
"Neuinstallation des Plugins sollte das Problem beheben."
|
||||||
|
|
||||||
|
#: pfadfinden-theme-updater.php:81
|
||||||
|
msgid "The plugin is incomplete. Reinstalling it may solve this problem."
|
||||||
|
msgstr ""
|
||||||
|
"Das Plugin ist unvollständig. Neuinstallation sollte das Problem beheben."
|
||||||
|
|
||||||
|
#: pfadfinden-theme-updater.php:96
|
||||||
|
#, php-format
|
||||||
|
msgid ""
|
||||||
|
"You need at least PHP 5.4 to use Pfadfinden Theme Updater. Your are using %s."
|
||||||
|
msgstr ""
|
||||||
|
"Du brauchst mindestens PHP 5.4, um den Pfadfinden-Theme-Updater zu benutzen. "
|
||||||
|
"Aktuell benutzt du PHP %s."
|
||||||
|
|
||||||
|
#: pfadfinden-theme-updater.php:104
|
||||||
|
msgid "Pfadfinden Theme Updater"
|
||||||
|
msgstr "Pfadfinden-Theme-Updater"
|
||||||
|
|
||||||
|
#: pfadfinden-theme-updater.php:105
|
||||||
|
msgid ""
|
||||||
|
"Adds the Pfadfinden theme repository to your choice of themes. Requires an "
|
||||||
|
"API key."
|
||||||
|
msgstr ""
|
||||||
|
"Fügt den Pfadfinden-Theme-Katalog zu Deiner Auswahl an Themes hinzu. "
|
||||||
|
"Benötigt einen API-Schlüssel."
|
||||||
|
|
||||||
|
#: src/Pfadfinden/WordPress/ThemeRepository.php:81
|
||||||
|
msgid "Your theme repository query is too long."
|
||||||
|
msgstr "Deine Anfrage an den Theme-Katalog ist zu lang."
|
||||||
|
|
||||||
|
#: src/Pfadfinden/WordPress/ThemeRepository.php:114
|
||||||
|
msgid "Unknown theme repository server error, no message attached."
|
||||||
|
msgstr ""
|
||||||
|
"Unbekannter Theme-Katalog-Serverfehler, keine Fehlerbeschreibung "
|
||||||
|
"mitgeschickt."
|
||||||
|
|
||||||
|
#: src/Pfadfinden/WordPress/ThemeRepository.php:186
|
||||||
|
msgid "Ambiguous result for single theme information call."
|
||||||
|
msgstr "Mehrere Ergebnisse für Abfrage nach Informationen zu einem Theme."
|
||||||
|
|
||||||
|
#: src/Pfadfinden/WordPress/ThemeUpdaterSettings.php:69
|
||||||
|
msgid "Pfadfinden Theme Updater Settings"
|
||||||
|
msgstr "Pfadfinden-Theme-Updater-Einstellungen"
|
||||||
|
|
||||||
|
#: src/Pfadfinden/WordPress/ThemeUpdaterSettings.php:74
|
||||||
|
msgid "Pfadfinden Updater"
|
||||||
|
msgstr "Pfadfinden-Updater"
|
||||||
|
|
||||||
|
#: src/Pfadfinden/WordPress/ThemeUpdaterSettings.php:84
|
||||||
|
msgid "API Key"
|
||||||
|
msgstr "API-Schlüssel"
|
||||||
|
|
||||||
|
#: src/Pfadfinden/WordPress/ThemeUpdaterSettings.php:89
|
||||||
|
#: src/Pfadfinden/WordPress/ThemeUpdaterSettings.php:116
|
||||||
|
msgid "An API key consists of 10 alphanumeric characters."
|
||||||
|
msgstr "Ein API-Schlüssel besteht aus zehn alphanumerischen Zeichen."
|
||||||
|
|
||||||
|
#: src/Pfadfinden/WordPress/ThemeUpdaterSettings.php:96
|
||||||
|
msgid "Keep Settings"
|
||||||
|
msgstr "Einstellungen merken"
|
||||||
|
|
||||||
|
#: src/Pfadfinden/WordPress/ThemeUpdaterSettings.php:97
|
||||||
|
msgid "Don’t delete settings when uninstalling the plugin."
|
||||||
|
msgstr "Einstellungen nicht löschen, wenn das Plugin deinstalliert wird."
|
||||||
|
|
||||||
|
#: src/Pfadfinden/WordPress/ThemeUpdaterSettings.php:107
|
||||||
|
msgid "Just testing? Try APITESTKEY."
|
||||||
|
msgstr ""
|
||||||
|
"Nur Ausprobieren? Nimm APITESTKEY. Aber BdP-Themes gibt es damit nicht…"
|
||||||
|
|
||||||
|
#~ msgid "Activated Features"
|
||||||
|
#~ msgstr "Aktivierte Funktionen"
|