Upload folder via GUI - integrations

This commit is contained in:
Git Manager GUI
2026-04-13 18:52:48 +02:00
parent 09ac38e9fa
commit 9514db9454
19 changed files with 1042 additions and 0 deletions

View File

@@ -0,0 +1,36 @@
.wmf-integrations-widget .mode-group{margin:0 0 1em;}
.wmf-buttongroup{display:flex;flex-wrap:wrap;gap:4px;margin-top:4px;}
.wmf-buttongroup input[type=radio]{position:absolute;opacity:0;width:0;height:0;}
.wmf-buttongroup label span{display:inline-block;padding:4px 12px;border:1px solid #8c8f94;border-radius:3px;cursor:pointer;background:#f6f7f7;font-size:13px;line-height:2;}
.wmf-buttongroup input[type=radio]:checked+span{background:#2271b1;border-color:#2271b1;color:#fff;}
.wmf-service-integration{display:none;}
.wmf-stripe-block,.wmf-paypal-block{display:none;}
#wmf-service-stripe[data-active-mode=live] .wmf-stripe-block-live,
#wmf-service-stripe[data-active-mode=test] .wmf-stripe-block-test,
#wmf-service-paypal[data-active-mode=live] .wmf-paypal-block-live,
#wmf-service-paypal[data-active-mode=sandbox] .wmf-paypal-block-sandbox{display:block;}
#wmf-int-widget-recaptcha .has-service-selection[data-active-service=recaptcha] #wmf-service-recaptcha,
#wmf-int-widget-recaptcha .has-service-selection[data-active-service=recaptchav3] #wmf-service-recaptchav3{display:block;}
#wmf-integration-toolbar{margin-bottom:15px;}
#wmf-integration-toolbar .media-toolbar-secondary{float:left;margin-top:11px;}
#wmf-no-integrations-found{color:#646970;font-size:16px;text-align:center;padding:60px 0;display:none;}
#wmf-integrations-results-wrap.no-results #wmf-no-integrations-found{display:block;}
#wmf-integrations-results{display:none;}
#wmf-integrations-results .postbox-container{width:25%;padding:0 8px;box-sizing:border-box;float:left;}
.wmf-integrations-widget{box-sizing:border-box;}
.wmf-integrations-widget .handle-actions{display:none;}
.wmf-integrations-widget.closed .inside{display:block;}
@media(max-width:799px){#wmf-integrations-results .postbox-container{width:100%;}}
/* Widget-Inhalte */
.wmf-widget-body{padding:4px 0 0;}
.wmf-widget-body p{margin-bottom:12px;}
.wmf-widget-body label{display:block;font-weight:600;font-size:12px;margin-bottom:4px;color:#1d2327;}
.wmf-widget-body .widefat{width:100%;box-sizing:border-box;}
.wmf-widget-body .description{font-size:12px;color:#646970;margin-top:3px;display:block;}
.wmf-widget-body a{color:#2271b1;}
.wmf-connected-badge{display:inline-flex;align-items:center;gap:5px;background:#f0fdf4;border:1px solid #46b450;color:#166534;padding:4px 10px;border-radius:12px;font-size:12px;font-weight:600;margin-bottom:12px;}
.wmf-mode-switch{display:flex;gap:4px;margin-bottom:14px;}
.wmf-mode-btn{padding:5px 14px;border:1px solid #8c8f94;border-radius:3px;cursor:pointer;font-size:13px;background:#f6f7f7;line-height:1.8;}
.wmf-mode-btn input[type=radio]{display:none;}
.wmf-mode-btn.active{background:#2271b1;border-color:#2271b1;color:#fff;}

View File

@@ -0,0 +1,63 @@
(function($){
$(document).on('change','input[name*=services]',function(e){
var $i=$(e.target),v=$i.val(),$w=$i.parents('.inside');
if(v){var $s=$('#wmf-service-'+v,$w);if($s.length){$('.wmf-service-integration',$w).hide();$i.parents('[data-active-service]').attr('data-active-service',v);$s.show();}}
else{$('.wmf-service-integration',$w).hide();}
$i.parents('form').trigger('wmf.enable');
});
$(document).on('change','input[name*="[mode]"]',function(e){ $(e.target).parents('[data-active-mode]').attr('data-active-mode',$(e.target).val()); });
$(document).on('submit','#wmf-integrations-screen form.hf-ajax-submit',function(e){
e.preventDefault();
var $f=$(e.target),$w=$f.parent(),$sp=$('.spinner',$w),$sb=$('input[type=submit]',$w);
$sb.prop('disabled',true);$sp.css('visibility','visible');
$.post(ajaxurl,$f.serialize(),function(r){$sb.prop('disabled',false);$sp.css('visibility','hidden');$f.replaceWith(r);});
});
function refresh(){
var sg=$('#wmf-integration-filters').val(),st=$('#wmf-search-input').val().trim();
var $rw=$('#wmf-integrations-results-wrap'),$rc=$('#wmf-integrations-results'),$dw=$('#dashboard-widgets');
$('.wmf-integrations-widget',$rc).each(function(){$('.notice',$(this)).remove();$('#'+$(this).attr('id'),$dw).replaceWith($(this));});
$('.wmf-integrations-widget',$rc).remove();$rc.hide();$rw.removeClass('no-results');
if(!sg&&!st){$dw.show();return;}
$dw.hide();
var $r=$('.wmf-integrations-widget',$dw);
if(sg)$r=$r.filter(function(){return $(this).hasClass('wmf-integrations-widget-group-'+sg);});
if(st)$r=$r.filter(function(){return $('h2',$(this)).text().toLowerCase().indexOf(st.toLowerCase())>=0;});
$r=$r.filter(function(){return'none'!==$(this).css('display');});
$r=$r.clone(true,true).get();
if(!$r.length)$rw.addClass('no-results');
$rc.show();
var $cols=$('.postbox-container:visible',$rc);
while($r.length>0){$cols.each(function(){if($r.length>0)$(this).append($r.pop());});}
}
$(document).on('input','#wmf-integration-toolbar',refresh);
$(window).on('resize',refresh);
})(jQuery);
/* Widget-Formulare AJAX speichern */
(function($){
$(document).on('submit', '.wmf-int-form', function(e){
e.preventDefault();
var $form = $(this);
var $btn = $form.find('button[type=submit]');
var $wrap = $form.closest('.wmf-widget-body');
$btn.prop('disabled', true).text('Speichere...');
$.post(ajaxurl, $form.serialize(), function(response){
$btn.prop('disabled', false).text('Speichern');
var $notice = $('<div class="wmf-widget-notice">').text('Gespeichert!').css({
background:'#f0fdf4',border:'1px solid #46b450',color:'#166534',
padding:'6px 10px',borderRadius:'3px',marginBottom:'8px',fontSize:'13px'
});
$wrap.prepend($notice);
setTimeout(function(){ $notice.fadeOut(300, function(){ $(this).remove(); }); }, 2500);
// Badge aktualisieren
if(response && response.indexOf('Verbunden') !== -1) {
if(!$wrap.find('.wmf-connected-badge').length) {
$wrap.prepend('<div class="wmf-connected-badge">&#10003; Verbunden</div>');
}
}
}).fail(function(){
$btn.prop('disabled', false).text('Speichern');
alert('Fehler beim Speichern. Bitte Seite neu laden.');
});
});
})(jQuery);

View File

@@ -0,0 +1,6 @@
<?php
if(!defined('ABSPATH')) exit;
class WMF_API_Request {
public $url; public $arguments;
public function __construct($url,$arguments){$this->url=$url;$this->arguments=$arguments;}
}

View File

@@ -0,0 +1,299 @@
<?php
if(!defined('ABSPATH')) exit;
class WMF_Integrations_Page_Controller {
private static $instance = null;
public static function instance() {
if(is_null(self::$instance)) self::$instance = new self();
self::$instance->hook();
return self::$instance;
}
public function hook() {
add_action('admin_menu', array($this, 'register_menu'));
add_action('admin_post_wmf_save_global_settings', array($this, 'save_global_settings'));
}
public function register_menu() {
$hook = add_submenu_page(
'wp-multi-formular',
'Integrationen',
'Integrationen',
'manage_options',
'wmf-integrations',
array($this, 'page')
);
if($hook) {
add_action('load-' . $hook, array($this, 'on_load'));
}
}
public function on_load() {
// Metaboxen direkt hier registrieren (nicht ueber add_meta_boxes Hook)
$this->register_metaboxes();
wp_enqueue_script('postbox');
wp_enqueue_style('wmf-int', WMF_URL . 'integrations/assets/css/admin.css', array(), WMF_VERSION);
wp_enqueue_script('wmf-int', WMF_URL . 'integrations/assets/js/dashboard.js', array('jquery'), WMF_VERSION, true);
wp_enqueue_style('wmf-admin', WMF_URL . 'assets/css/admin.css', array(), WMF_VERSION);
}
private function register_metaboxes() {
$screen = get_current_screen();
if(!$screen) return;
$sid = $screen->id;
$int = wmf_get_integrations();
// Dienste nach Gruppe
$groups = array(
'email' => 'normal',
'antispam' => 'side',
'address' => 'side',
'payments' => 'side',
'automation' => 'column3',
'analytics' => 'column4',
);
foreach($groups as $group => $context) {
$services = $int->get_service_group($group);
foreach($services as $svc) {
$id = 'wmf-int-widget-' . $svc->id;
add_meta_box(
$id,
esc_html($svc->label),
array($this, 'metabox_callback'),
$sid,
$context,
'default',
array('service' => $svc)
);
add_filter("postbox_classes_{$sid}_{$id}", function($classes) use($svc) {
$classes[] = 'wmf-integrations-widget';
$classes[] = 'wmf-integrations-widget-group-' . $svc->group;
return $classes;
});
}
}
}
public function metabox_callback($post, $metabox) {
$metabox['args']['service']->admin_widget();
}
/* ------------------------------------------------------------------
SEITEN-AUSGABE
------------------------------------------------------------------ */
public function page() {
// Test-Mail
if(!empty($_GET['wmf_test_mail']) && wp_verify_nonce($_GET['_wpnonce'] ?? '', 'wmf_test_mail')) {
$this->handle_test_mail();
}
$screen = get_current_screen();
$sid = $screen ? $screen->id : '';
require WMF_INT_DIR . 'templates/admin-integrations.php';
}
/* ------------------------------------------------------------------
GLOBALE E-MAIL-EINSTELLUNGEN (als eigener Abschnitt, nicht als Meta-Box)
------------------------------------------------------------------ */
public function render_global_email_settings() {
$opts = get_option('wmf_global_settings', array());
$from_name = $opts['from_name'] ?? get_bloginfo('name');
$from_email = $opts['from_email'] ?? get_option('admin_email');
$smtp_on = $opts['smtp_enabled'] ?? '0';
$smtp_host = $opts['smtp_host'] ?? '';
$smtp_port = $opts['smtp_port'] ?? '587';
$smtp_enc = $opts['smtp_enc'] ?? 'tls';
$smtp_user = $opts['smtp_user'] ?? '';
$smtp_pass = $opts['smtp_pass'] ?? '';
?>
<div class="wmf-global-settings-box">
<h2 class="wmf-global-settings-title">
<span class="dashicons dashicons-email-alt"></span>
Globale E-Mail-Einstellungen
</h2>
<form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>">
<?php wp_nonce_field('wmf_global_settings_save', 'wmf_global_nonce'); ?>
<input type="hidden" name="action" value="wmf_save_global_settings">
<div class="wmf-global-settings-grid">
<!-- Absender -->
<div class="wmf-settings-section">
<h3>Standard-Absender</h3>
<p class="description">Gilt fuer alle Formulare. Im einzelnen Formular kann dies ueberschrieben werden.</p>
<div class="wmf-setting-row">
<label for="wmf_from_name">Absendername</label>
<input type="text" id="wmf_from_name" name="wmf_from_name"
value="<?php echo esc_attr($from_name); ?>"
class="regular-text" placeholder="<?php echo esc_attr(get_bloginfo('name')); ?>">
</div>
<div class="wmf-setting-row">
<label for="wmf_from_email">Absender-E-Mail</label>
<input type="email" id="wmf_from_email" name="wmf_from_email"
value="<?php echo esc_attr($from_email); ?>"
class="regular-text" placeholder="noreply@ihredomain.de">
<p class="description">
Tipp: Nutzen Sie eine Adresse Ihrer Domain um Spam-Filter zu vermeiden.<br>
z.B. <code>noreply@viper-network.de</code>
</p>
</div>
</div>
<!-- SMTP -->
<div class="wmf-settings-section">
<h3>SMTP <span style="font-weight:normal;font-size:13px;color:#646970;">(optional)</span></h3>
<p class="description">Eigenen Mailserver verwenden statt WordPress-Standard (wp_mail).</p>
<div class="wmf-setting-row">
<label class="wmf-toggle-label">
<input type="checkbox" name="wmf_smtp_enabled" value="1" id="wmf_smtp_toggle" <?php checked($smtp_on,'1'); ?>>
<span class="wmf-toggle-slider"></span>
SMTP aktivieren
</label>
</div>
<div id="wmf-smtp-fields" style="<?php echo $smtp_on==='1'?'':'display:none;'; ?>">
<div class="wmf-setting-row">
<label for="wmf_smtp_host">SMTP-Host</label>
<input type="text" id="wmf_smtp_host" name="wmf_smtp_host"
value="<?php echo esc_attr($smtp_host); ?>"
class="regular-text" placeholder="smtp.gmail.com">
</div>
<div class="wmf-setting-row wmf-setting-row-inline">
<div>
<label for="wmf_smtp_port">Port</label>
<input type="number" id="wmf_smtp_port" name="wmf_smtp_port"
value="<?php echo esc_attr($smtp_port); ?>"
class="small-text">
<span class="description">587=TLS &nbsp; 465=SSL &nbsp; 25=keins</span>
</div>
<div>
<label for="wmf_smtp_enc">Verschluesselung</label>
<select id="wmf_smtp_enc" name="wmf_smtp_enc">
<option value="tls" <?php selected($smtp_enc,'tls'); ?>>TLS (empfohlen)</option>
<option value="ssl" <?php selected($smtp_enc,'ssl'); ?>>SSL</option>
<option value="" <?php selected($smtp_enc,''); ?>>Keine</option>
</select>
</div>
</div>
<div class="wmf-setting-row">
<label for="wmf_smtp_user">Benutzername / E-Mail</label>
<input type="text" id="wmf_smtp_user" name="wmf_smtp_user"
value="<?php echo esc_attr($smtp_user); ?>"
class="regular-text" autocomplete="off">
</div>
<div class="wmf-setting-row">
<label for="wmf_smtp_pass">Passwort</label>
<input type="password" id="wmf_smtp_pass" name="wmf_smtp_pass"
value="<?php echo esc_attr($smtp_pass); ?>"
class="regular-text" autocomplete="new-password">
<p class="description">Bei Gmail: App-Passwort verwenden (kein normales Konto-Passwort).</p>
</div>
</div>
</div>
</div><!-- .wmf-global-settings-grid -->
<div class="wmf-global-settings-footer">
<button type="submit" class="button button-primary button-large">
Einstellungen speichern
</button>
<?php if(!empty($from_email)): ?>
<a href="<?php echo esc_url(wp_nonce_url(
add_query_arg(array('wmf_test_mail'=>'1','page'=>'wmf-integrations'), admin_url('admin.php')),
'wmf_test_mail'
)); ?>" class="button button-secondary button-large">
&#9993; Test-Mail an <?php echo esc_html(get_option('admin_email')); ?>
</a>
<?php endif; ?>
<span class="wmf-smtp-status <?php echo ($smtp_on==='1'&&!empty($smtp_host))?'active':''; ?>">
<?php echo ($smtp_on==='1'&&!empty($smtp_host)) ? '&#10003; SMTP aktiv' : 'SMTP nicht aktiv'; ?>
</span>
</div>
</form>
<script>
jQuery(document).ready(function($){
$('#wmf_smtp_toggle').on('change', function(){
$('#wmf-smtp-fields').toggle(this.checked);
});
});
</script>
</div>
<style>
.wmf-global-settings-box{background:#fff;border:1px solid #dcdcde;border-radius:4px;margin-bottom:20px;overflow:hidden;}
.wmf-global-settings-title{display:flex;align-items:center;gap:8px;margin:0;padding:14px 20px;background:#f6f7f7;border-bottom:1px solid #dcdcde;font-size:15px;}
.wmf-global-settings-title .dashicons{color:#2271b1;font-size:20px;width:20px;height:20px;}
.wmf-global-settings-grid{display:grid;grid-template-columns:1fr 1fr;gap:0;border-bottom:1px solid #dcdcde;}
.wmf-settings-section{padding:20px 24px;border-right:1px solid #dcdcde;}
.wmf-settings-section:last-child{border-right:none;}
.wmf-settings-section h3{margin:0 0 4px;font-size:13px;}
.wmf-setting-row{margin-bottom:14px;}
.wmf-setting-row label{display:block;font-weight:600;font-size:13px;margin-bottom:5px;}
.wmf-setting-row .regular-text{width:100%;max-width:360px;box-sizing:border-box;}
.wmf-setting-row .description{font-size:12px;color:#646970;margin-top:4px;}
.wmf-setting-row-inline{display:flex;gap:20px;flex-wrap:wrap;}
.wmf-toggle-label{display:flex!important;align-items:center;gap:10px;cursor:pointer;font-weight:normal!important;}
.wmf-global-settings-footer{display:flex;align-items:center;gap:12px;padding:16px 24px;background:#f6f7f7;flex-wrap:wrap;}
.wmf-smtp-status{font-size:12px;color:#646970;margin-left:auto;}
.wmf-smtp-status.active{color:#46b450;font-weight:600;}
@media(max-width:900px){.wmf-global-settings-grid{grid-template-columns:1fr;}.wmf-settings-section{border-right:none;border-bottom:1px solid #dcdcde;}}
</style>
<?php
}
/* ------------------------------------------------------------------
GLOBALE EINSTELLUNGEN SPEICHERN
------------------------------------------------------------------ */
public function save_global_settings() {
if(!wp_verify_nonce($_POST['wmf_global_nonce'] ?? '', 'wmf_global_settings_save') || !current_user_can('manage_options')) {
wp_die('Sicherheitsfehler.');
}
update_option('wmf_global_settings', array(
'from_name' => sanitize_text_field($_POST['wmf_from_name'] ?? ''),
'from_email' => sanitize_email( $_POST['wmf_from_email'] ?? ''),
'smtp_enabled' => !empty($_POST['wmf_smtp_enabled']) ? '1' : '0',
'smtp_host' => sanitize_text_field($_POST['wmf_smtp_host'] ?? ''),
'smtp_port' => intval( $_POST['wmf_smtp_port'] ?? 587),
'smtp_enc' => sanitize_text_field($_POST['wmf_smtp_enc'] ?? 'tls'),
'smtp_user' => sanitize_text_field($_POST['wmf_smtp_user'] ?? ''),
'smtp_pass' => $_POST['wmf_smtp_pass'] ?? '',
));
wmf_safe_redirect(add_query_arg(array('page'=>'wmf-integrations','wmf_notice'=>'global_saved'), admin_url('admin.php')));
}
/* ------------------------------------------------------------------
TEST-MAIL
------------------------------------------------------------------ */
private function handle_test_mail() {
$opts = get_option('wmf_global_settings', array());
$from_name = $opts['from_name'] ?? get_bloginfo('name');
$from_mail = $opts['from_email'] ?? get_option('admin_email');
$to = get_option('admin_email');
$headers = array('Content-Type: text/html; charset=UTF-8', 'From: '.$from_name.' <'.$from_mail.'>');
$body = '<html><body style="font-family:sans-serif;padding:20px;">
<h2 style="color:#2271b1;">WP Multi Formular Test-E-Mail</h2>
<p>Diese Test-E-Mail wurde erfolgreich gesendet.</p>
<table style="border-collapse:collapse;margin-top:16px;">
<tr><td style="padding:6px 12px;background:#f6f7f7;font-weight:600;">Von:</td><td style="padding:6px 12px;">' . esc_html($from_name) . ' &lt;' . esc_html($from_mail) . '&gt;</td></tr>
<tr><td style="padding:6px 12px;background:#f6f7f7;font-weight:600;">An:</td><td style="padding:6px 12px;">' . esc_html($to) . '</td></tr>
<tr><td style="padding:6px 12px;background:#f6f7f7;font-weight:600;">Datum:</td><td style="padding:6px 12px;">' . current_time('d.m.Y H:i') . '</td></tr>
</table>
</body></html>';
$sent = wp_mail($to, 'Test-E-Mail WP Multi Formular', $body, $headers);
$msg = $sent
? '<div class="notice notice-success is-dismissible"><p>&#10003; Test-E-Mail gesendet an <strong>' . esc_html($to) . '</strong>.</p></div>'
: '<div class="notice notice-error is-dismissible"><p>&#10007; Fehler beim Senden. Bitte SMTP-Einstellungen pruefen.</p></div>';
add_action('admin_notices', function() use($msg){ echo $msg; });
}
}
function wmf_get_integrations_page_controller() {
return WMF_Integrations_Page_Controller::instance();
}

View File

@@ -0,0 +1,113 @@
<?php
if(!defined('ABSPATH')) exit;
class WMF_Integrations {
private static $instance=null;
private static $hooked=false;
private $option_name='_wmf_service_credentials';
private $services=array();
private $grouped_services=array();
private $credentials=array();
private $notice=array();
public $action_update='wmf-service-update';
public $integrations_action='wmf-integrations-update';
public static function instance() {
if(is_null(self::$instance)) self::$instance=new self();
return self::$instance;
}
private function __construct() {
$b=WMF_INT_DIR;
$services=array(
'recaptcha/class-service-recaptcha.php' =>'WMF_Service_Recaptcha',
'recaptchav3/class-service-recaptchav3.php' =>'WMF_Service_RecaptchaV3',
'mailchimp/class-service-mailchimp.php' =>'WMF_Service_Mailchimp',
'mailerlite/class-service-mailerlite.php' =>'WMF_Service_MailerLite',
'active-campaign/class-service-active-campaign.php'=>'WMF_Service_ActiveCampaign',
'convertkit/class-service-convertkit.php' =>'WMF_Service_ConvertKit',
'stripe/class-service-stripe.php' =>'WMF_Service_Stripe',
'paypal/class-service-paypal.php' =>'WMF_Service_PayPal',
'zapier/class-service-zapier.php' =>'WMF_Service_Zapier',
'google-analytics/class-service-google-analytics.php'=>'WMF_Service_Google_Analytics',
'google-places/class-service-google-places.php' =>'WMF_Service_Google_Places',
);
foreach($services as $file=>$cls) {
require_once $b.'services/'.$file;
$this->register_service($cls);
}
}
public function hook() {
if(self::$hooked) return; self::$hooked=true;
add_action('wp_ajax_'.$this->action_update, array($this,'ajax_service_update'));
add_action('wp_ajax_'.$this->integrations_action,array($this,'ajax_integrations_update'));
add_action('wmf_integrations_print_notices', array($this,'print_notices'));
$this->read_credentials();
$this->configure_services();
}
public function register_service($cls) {
$s=$cls instanceof WMF_Service?$cls:new $cls();
$this->services[$s->id]=$s;
}
public function configure_services() {
foreach($this->services as $s) {
$s->set_credentials($this->credentials[$s->id]??array());
$s->configure(); $s->load();
}
}
public function read_credentials(){$this->credentials=get_option($this->option_name,array());}
public function write_credentials(){
$this->credentials=array_map(fn($s)=>$s->get_credentials(),$this->services);
update_option($this->option_name,$this->credentials);
}
public function get_services(){return $this->services;}
public function get_service($id){return $this->services[$id]??false;}
public function get_service_group($group){
// Neu aufbauen falls noch nicht geschehen oder leer
if(empty($this->grouped_services)) {
$this->grouped_services = array();
foreach($this->services as $s) {
$this->grouped_services[$s->group][] = $s;
}
}
return $this->grouped_services[$group] ?? array();
}
public function reset_grouped_cache() {
$this->grouped_services = array();
}
public function ajax_service_update() {
if(!check_ajax_referer($this->action_update)||!current_user_can('manage_options')) wp_die();
$services=(array)($_REQUEST['services']??array());
$group=sanitize_text_field($_REQUEST['group']??'');
ob_start();
foreach($services as $sid) {
if(!isset($this->services[$sid])) continue;
$svc=$this->services[$sid];
$def=$svc->get_credentials();
$raw=$_REQUEST['credentials'][$sid]??array();
$creds=array_map('sanitize_text_field',array_intersect_key(wp_parse_args($raw,$def),$def));
$svc->set_credentials($creds,$raw);
$this->write_credentials();
}
$this->notice=array('status'=>'success','message'=>'Änderungen gespeichert.');
if($group==='antispam') require WMF_INT_DIR.'templates/admin-antispam-integrations.php';
echo ob_get_clean(); die();
}
public function ajax_integrations_update() {
if(!check_ajax_referer($this->integrations_action)||!current_user_can('manage_options')) wp_die();
if(!isset($_REQUEST['service'],$_REQUEST['credentials'])) wp_die();
$sid=sanitize_text_field($_REQUEST['service']);
if(!isset($this->services[$sid])) wp_send_json_error();
$svc=$this->services[$sid]; $def=$svc->get_credentials();
$raw=$_REQUEST['credentials'][$sid]??array();
$creds=array_map('sanitize_text_field',array_intersect_key(wp_parse_args($raw,$def),$def));
$prev=$svc->get_credentials(); $svc->set_credentials($creds,$raw); $this->write_credentials();
$this->notice=array('status'=>'success','message'=>'Änderungen gespeichert.');
ob_start(); $svc->admin_widget($prev); echo ob_get_clean(); die();
}
public function print_notices() {
if(empty($this->notice)) return;
printf('<div class="notice notice-%s"><p>%s</p></div>',esc_attr($this->notice['status']),esc_html($this->notice['message']));
}
}
function wmf_get_integrations(){return WMF_Integrations::instance();}

View File

@@ -0,0 +1,17 @@
<?php
if(!defined('ABSPATH')) exit;
class WMF_Service {
protected $credentials=array();
public $id=''; public $label=''; public $group='';
public function set_credentials($creds=array(),$raw=array()){$this->credentials=$creds;}
public function get_credentials(){return $this->credentials;}
public function is_connected(){return false;}
public function admin_widget($prev=array()){}
public function configure(){}
public function load(){}
public function make_api_request($url,$args){
$req=new WMF_API_Request($url,$args);
$req=apply_filters('wmf_api_request',$req,$this);
return wp_remote_request($req->url,$req->arguments);
}
}

View File

@@ -0,0 +1,46 @@
<?php
if(!defined('ABSPATH')) exit;
class WMF_Service_ActiveCampaign extends WMF_Service {
public $id='active-campaign'; public $label='ActiveCampaign'; public $group='email';
protected $credentials=array('api_url'=>'','api_key'=>'','list_id'=>'');
public function is_connected(){return!empty($this->credentials['api_url'])&&!empty($this->credentials['api_key']);}
public function admin_widget($prev=array()){
$c = $this->get_credentials();
$int = wmf_get_integrations();
$act = $int->action_update;
$nonce= wp_create_nonce($act);
$conn = $this->is_connected();
echo '<div class="wmf-widget-body">';
if($conn) echo '<div class="wmf-connected-badge">&#10003; Verbunden</div>';
echo '<form class="wmf-int-form">';
echo '<input type="hidden" name="_wpnonce" value="'.esc_attr($nonce).'">';
echo '<input type="hidden" name="action" value="'.esc_attr($act).'">';
echo '<input type="hidden" name="services[]" value="active-campaign">';
echo '<p><label>Konto-URL</label>';
echo '<input type="url" name="credentials[active-campaign][api_url]" value="'.esc_attr($c['api_url']??'').'" class="widefat" placeholder="https://KONTO.api-us1.com">';
echo '<span class="description">Einstellungen &rarr; Entwickler &rarr; API-Zugang</span></p>';
echo '<p><label>API-Schluessel</label>';
echo '<input type="text" name="credentials[active-campaign][api_key]" value="'.esc_attr($c['api_key']??'').'" class="widefat" autocomplete="off"></p>';
echo '<p><label>Listen-ID (optional)</label>';
echo '<input type="text" name="credentials[active-campaign][list_id]" value="'.esc_attr($c['list_id']??'').'" class="widefat"></p>';
echo '<p><button type="submit" class="button button-primary">Speichern</button></p>';
echo '</form>';
echo '</div>';
}
public function load(){add_action('wmf_form_submitted',array($this,'subscribe'),10,5);}
public function subscribe($form_id,$meta,$fields,$values,$sub_id){
if(!$this->is_connected()) return;
$email=''; foreach($fields as $f){if(($f['type']??'')==='email'&&!empty($values[$f['id']])){$email=$values[$f['id']];break;}}
if(!is_email($email)) return;
$api=rtrim($this->credentials['api_url'],'/'); $key=$this->credentials['api_key'];
$res=wp_remote_post($api.'/api/3/contacts',array('headers'=>array('Api-Token'=>$key,'Content-Type'=>'application/json'),'body'=>wp_json_encode(array('contact'=>array('email'=>$email))),'timeout'=>10));
if(!is_wp_error($res)&&!empty($this->credentials['list_id'])){
$body=json_decode(wp_remote_retrieve_body($res),true);
$cid=$body['contact']['id']??0;
if($cid) wp_remote_post($api.'/api/3/contactLists',array('headers'=>array('Api-Token'=>$key,'Content-Type'=>'application/json'),'body'=>wp_json_encode(array('contactList'=>array('list'=>intval($this->credentials['list_id']),'contact'=>$cid,'status'=>1))),'timeout'=>10));
}
}
}

View File

@@ -0,0 +1,42 @@
<?php
if(!defined('ABSPATH')) exit;
class WMF_Service_ConvertKit extends WMF_Service {
public $id='convertkit'; public $label='ConvertKit / Kit'; public $group='email';
protected $credentials=array('api_key'=>'','api_secret'=>'','form_id'=>'');
public function is_connected(){return!empty($this->credentials['api_key']);}
public function admin_widget($prev=array()){
$c = $this->get_credentials();
$int = wmf_get_integrations();
$act = $int->action_update;
$nonce= wp_create_nonce($act);
$conn = $this->is_connected();
echo '<div class="wmf-widget-body">';
if($conn) echo '<div class="wmf-connected-badge">&#10003; Verbunden</div>';
echo '<form class="wmf-int-form">';
echo '<input type="hidden" name="_wpnonce" value="'.esc_attr($nonce).'">';
echo '<input type="hidden" name="action" value="'.esc_attr($act).'">';
echo '<input type="hidden" name="services[]" value="convertkit">';
echo '<p><label>API-Schluessel</label>';
echo '<input type="text" name="credentials[convertkit][api_key]" value="'.esc_attr($c['api_key']??'').'" class="widefat" autocomplete="off">';
echo '<span class="description"><a href="https://app.kit.com/account_settings/developer_settings" target="_blank">API-Schluessel in Kit/ConvertKit &rarr;</a></span></p>';
echo '<p><label>API-Secret</label>';
echo '<input type="text" name="credentials[convertkit][api_secret]" value="'.esc_attr($c['api_secret']??'').'" class="widefat" autocomplete="off"></p>';
echo '<p><label>Formular-ID (optional)</label>';
echo '<input type="text" name="credentials[convertkit][form_id]" value="'.esc_attr($c['form_id']??'').'" class="widefat"></p>';
echo '<p><button type="submit" class="button button-primary">Speichern</button></p>';
echo '</form>';
echo '</div>';
}
public function load(){add_action('wmf_form_submitted',array($this,'subscribe'),10,5);}
public function subscribe($form_id,$meta,$fields,$values,$sub_id){
if(!$this->is_connected()) return;
$email=''; foreach($fields as $f){if(($f['type']??'')==='email'&&!empty($values[$f['id']])){$email=$values[$f['id']];break;}}
if(!is_email($email)) return;
$fid=$this->credentials['form_id']??'';
if($fid) wp_remote_post("https://api.convertkit.com/v3/forms/{$fid}/subscribe",array('body'=>array('api_key'=>$this->credentials['api_key'],'email'=>$email),'timeout'=>10));
else wp_remote_post('https://api.convertkit.com/v3/subscribers',array('body'=>array('api_secret'=>$this->credentials['api_secret']??'','email_address'=>$email),'timeout'=>10));
}
}

View File

@@ -0,0 +1,35 @@
<?php
if(!defined('ABSPATH')) exit;
class WMF_Service_Google_Analytics extends WMF_Service {
public $id='google-analytics'; public $label='Google Analytics (GA4)'; public $group='analytics';
protected $credentials=array('measurement_id'=>'');
public function is_connected(){return!empty($this->credentials['measurement_id']);}
public function admin_widget($prev=array()){
$c = $this->get_credentials();
$int = wmf_get_integrations();
$act = $int->action_update;
$nonce= wp_create_nonce($act);
$conn = $this->is_connected();
echo '<div class="wmf-widget-body">';
if($conn) echo '<div class="wmf-connected-badge">&#10003; Verbunden</div>';
echo '<form class="wmf-int-form">';
echo '<input type="hidden" name="_wpnonce" value="'.esc_attr($nonce).'">';
echo '<input type="hidden" name="action" value="'.esc_attr($act).'">';
echo '<input type="hidden" name="services[]" value="google-analytics">';
echo '<p><label>Mess-ID (GA4)</label>';
echo '<input type="text" name="credentials[google-analytics][measurement_id]" value="'.esc_attr($c['measurement_id']??'').'" class="widefat" placeholder="G-XXXXXXXXXX">';
echo '<span class="description">Google Analytics &rarr; Verwaltung &rarr; Datenstroeme &rarr; Mess-ID. Das gtag.js-Skript wird automatisch eingebunden.</span></p>';
echo '<p><button type="submit" class="button button-primary">Speichern</button></p>';
echo '</form>';
echo '</div>';
}
public function load(){if($this->is_connected()) add_action('wp_footer',array($this,'inject_gtag'));}
public function inject_gtag(){
$id=esc_js($this->credentials['measurement_id']);
echo '<script async src="https://www.googletagmanager.com/gtag/js?id='.$id.'"></script>';
echo '<script>window.dataLayer=window.dataLayer||[];function gtag(){dataLayer.push(arguments);}gtag("js",new Date());gtag("config","'.$id.'");</script>';
}
}

View File

@@ -0,0 +1,29 @@
<?php
if(!defined('ABSPATH')) exit;
class WMF_Service_Google_Places extends WMF_Service {
public $id='google-places'; public $label='Google Places (Autocomplete)'; public $group='address';
protected $credentials=array('api_key'=>'');
public function is_connected(){return!empty($this->credentials['api_key']);}
public function admin_widget($prev=array()){
$c = $this->get_credentials();
$int = wmf_get_integrations();
$act = $int->action_update;
$nonce= wp_create_nonce($act);
$conn = $this->is_connected();
echo '<div class="wmf-widget-body">';
if($conn) echo '<div class="wmf-connected-badge">&#10003; Verbunden</div>';
echo '<form class="wmf-int-form">';
echo '<input type="hidden" name="_wpnonce" value="'.esc_attr($nonce).'">';
echo '<input type="hidden" name="action" value="'.esc_attr($act).'">';
echo '<input type="hidden" name="services[]" value="google-places">';
echo '<p><label>API-Schluessel</label>';
echo '<input type="text" name="credentials[google-places][api_key]" value="'.esc_attr($c['api_key']??'').'" class="widefat" autocomplete="off">';
echo '<span class="description"><a href="https://console.cloud.google.com/apis/credentials" target="_blank">Google Cloud Console &rarr;</a> Places API aktivieren.</span></p>';
echo '<p><button type="submit" class="button button-primary">Speichern</button></p>';
echo '</form>';
echo '</div>';
}
}

View File

@@ -0,0 +1,46 @@
<?php
if(!defined('ABSPATH')) exit;
class WMF_Service_Mailchimp extends WMF_Service {
public $id='mailchimp'; public $label='Mailchimp'; public $group='email';
protected $credentials=array('api_key'=>'','list_id'=>'');
public function is_connected(){return!empty($this->credentials['api_key']);}
public function admin_widget($prev=array()){
$c = $this->get_credentials();
$int = wmf_get_integrations();
$act = $int->action_update;
$nonce= wp_create_nonce($act);
$conn = $this->is_connected();
echo '<div class="wmf-widget-body">';
if($conn) echo '<div class="wmf-connected-badge">&#10003; Verbunden</div>';
echo '<form class="wmf-int-form">';
echo '<input type="hidden" name="_wpnonce" value="'.esc_attr($nonce).'">';
echo '<input type="hidden" name="action" value="'.esc_attr($act).'">';
echo '<input type="hidden" name="services[]" value="mailchimp">';
echo '<p><label>API-Schluessel</label>';
echo '<input type="text" name="credentials[mailchimp][api_key]" value="'.esc_attr($c['api_key']??'').'" class="widefat" autocomplete="off">';
echo '<span class="description"><a href="https://mailchimp.com/help/about-api-keys/" target="_blank">API-Schluessel erstellen &rarr;</a></span></p>';
echo '<p><label>Audience-ID (Listen-ID)</label>';
echo '<input type="text" name="credentials[mailchimp][list_id]" value="'.esc_attr($c['list_id']??'').'" class="widefat">';
echo '<span class="description">Einstellungen &rarr; Audience &rarr; Audience ID</span></p>';
echo '<p><button type="submit" class="button button-primary">Speichern</button></p>';
echo '</form>';
echo '</div>';
}
public function load(){add_action('wmf_form_submitted',array($this,'subscribe'),10,5);}
public function subscribe($form_id,$meta,$fields,$values,$sub_id){
if(!$this->is_connected()) return;
$email='';
foreach($fields as $f){if(($f['type']??'')==='email'&&!empty($values[$f['id']])&&is_email($values[$f['id']])){$email=$values[$f['id']];break;}}
if(!is_email($email)||empty($this->credentials['list_id'])) return;
$key=$this->credentials['api_key'];
$dash=strrpos($key,'-'); if($dash===false) return;
$dc=substr($key,$dash+1);
wp_remote_post("https://{$dc}.api.mailchimp.com/3.0/lists/{$this->credentials['list_id']}/members",array(
'headers'=>array('Authorization'=>'Basic '.base64_encode('key:'.$key),'Content-Type'=>'application/json'),
'body'=>wp_json_encode(array('email_address'=>$email,'status'=>'subscribed')),'timeout'=>10,
));
}
}

View File

@@ -0,0 +1,43 @@
<?php
if(!defined('ABSPATH')) exit;
class WMF_Service_MailerLite extends WMF_Service {
public $id='mailerlite'; public $label='MailerLite'; public $group='email';
protected $credentials=array('api_key'=>'','group_id'=>'');
public function is_connected(){return!empty($this->credentials['api_key']);}
public function admin_widget($prev=array()){
$c = $this->get_credentials();
$int = wmf_get_integrations();
$act = $int->action_update;
$nonce= wp_create_nonce($act);
$conn = $this->is_connected();
echo '<div class="wmf-widget-body">';
if($conn) echo '<div class="wmf-connected-badge">&#10003; Verbunden</div>';
echo '<form class="wmf-int-form">';
echo '<input type="hidden" name="_wpnonce" value="'.esc_attr($nonce).'">';
echo '<input type="hidden" name="action" value="'.esc_attr($act).'">';
echo '<input type="hidden" name="services[]" value="mailerlite">';
echo '<p><label>API-Schluessel</label>';
echo '<input type="text" name="credentials[mailerlite][api_key]" value="'.esc_attr($c['api_key']??'').'" class="widefat" autocomplete="off">';
echo '<span class="description"><a href="https://app.mailerlite.com/integrations/api/" target="_blank">API-Schluessel in MailerLite &rarr;</a></span></p>';
echo '<p><label>Gruppen-ID (optional)</label>';
echo '<input type="text" name="credentials[mailerlite][group_id]" value="'.esc_attr($c['group_id']??'').'" class="widefat">';
echo '<span class="description">Leer lassen fuer Standard-Liste</span></p>';
echo '<p><button type="submit" class="button button-primary">Speichern</button></p>';
echo '</form>';
echo '</div>';
}
public function load(){add_action('wmf_form_submitted',array($this,'subscribe'),10,5);}
public function subscribe($form_id,$meta,$fields,$values,$sub_id){
if(!$this->is_connected()) return;
$email=''; foreach($fields as $f){if(($f['type']??'')==='email'&&!empty($values[$f['id']])){$email=$values[$f['id']];break;}}
if(!is_email($email)) return;
$name=''; foreach($fields as $f){if(($f['type']??'')==='text'&&!empty($values[$f['id']])){$name=$values[$f['id']];break;}}
$body=array('email'=>$email); if($name) $body['name']=$name;
$gid=$this->credentials['group_id']??'';
$url=$gid?"https://api.mailerlite.com/api/v2/groups/{$gid}/subscribers":'https://api.mailerlite.com/api/v2/subscribers';
wp_remote_post($url,array('headers'=>array('X-MailerLite-ApiKey'=>$this->credentials['api_key'],'Content-Type'=>'application/json'),'body'=>wp_json_encode($body),'timeout'=>10));
}
}

View File

@@ -0,0 +1,38 @@
<?php
if(!defined('ABSPATH')) exit;
class WMF_Service_PayPal extends WMF_Service {
public $id='paypal'; public $label='PayPal'; public $group='payments';
protected $credentials=array('mode'=>'sandbox','live_client'=>'','live_secret'=>'','sandbox_client'=>'','sandbox_secret'=>'');
public function is_connected(){$m=$this->credentials['mode']??'sandbox';return($m==='live')?!empty($this->credentials['live_secret']):!empty($this->credentials['sandbox_secret']);}
public function admin_widget($prev=array()){
$c=$this->get_credentials();
$int=wmf_get_integrations();
$act=$int->action_update;
$nonce=wp_create_nonce($act);
$m=$c['mode']??'sandbox';
$conn=$this->is_connected();
echo '<div class="wmf-widget-body">';
if($conn) echo '<div class="wmf-connected-badge">&#10003; Verbunden ('.($m==='live'?'Live':'Sandbox').')</div>';
echo '<form class="wmf-int-form">';
echo '<input type="hidden" name="_wpnonce" value="'.esc_attr($nonce).'">';
echo '<input type="hidden" name="action" value="'.esc_attr($act).'">';
echo '<input type="hidden" name="services[]" value="paypal">';
echo '<div class="wmf-mode-switch">';
echo '<label class="wmf-mode-btn '.($m==='sandbox'?'active':'').'"><input type="radio" name="credentials[paypal][mode]" value="sandbox" '.checked($m,'sandbox',false).' onchange="wmfPaypalMode(this)"> Sandbox</label>';
echo '<label class="wmf-mode-btn '.($m==='live'?'active':'').'"><input type="radio" name="credentials[paypal][mode]" value="live" '.checked($m,'live',false).' onchange="wmfPaypalMode(this)"> Live</label>';
echo '</div>';
echo '<div id="wmf-paypal-sandbox" '.($m==='live'?'style="display:none"':'').'>';
echo '<p><label>Sandbox Client-ID</label><input type="text" name="credentials[paypal][sandbox_client]" value="'.esc_attr($c['sandbox_client']??'').'" class="widefat"></p>';
echo '<p><label>Sandbox Secret</label><input type="password" name="credentials[paypal][sandbox_secret]" value="'.esc_attr($c['sandbox_secret']??'').'" class="widefat"></p>';
echo '</div>';
echo '<div id="wmf-paypal-live" '.($m==='sandbox'?'style="display:none"':'').'>';
echo '<p><label>Live Client-ID</label><input type="text" name="credentials[paypal][live_client]" value="'.esc_attr($c['live_client']??'').'" class="widefat"></p>';
echo '<p><label>Live Secret</label><input type="password" name="credentials[paypal][live_secret]" value="'.esc_attr($c['live_secret']??'').'" class="widefat"></p>';
echo '</div>';
echo '<p class="description"><a href="https://developer.paypal.com/dashboard/applications" target="_blank">PayPal Developer Dashboard &rarr;</a></p>';
echo '<p><button type="submit" class="button button-primary">Speichern</button></p>';
echo '</form>';
echo '<script>function wmfPaypalMode(el){document.getElementById("wmf-paypal-sandbox").style.display=el.value==="sandbox"?"":"none";document.getElementById("wmf-paypal-live").style.display=el.value==="live"?"":"none";}</script>';
echo '</div>';
}
}

View File

@@ -0,0 +1,31 @@
<?php
if(!defined('ABSPATH')) exit;
class WMF_Service_Recaptcha extends WMF_Service {
public $id='recaptcha'; public $label='reCAPTCHA v2'; public $group='antispam';
protected $credentials=array('site_key'=>'','secret_key'=>'');
public function is_connected(){return!empty($this->credentials['site_key'])&&!empty($this->credentials['secret_key']);}
public function admin_widget($prev=array()){
$c = $this->get_credentials();
$int = wmf_get_integrations();
$act = $int->action_update;
$nonce= wp_create_nonce($act);
$conn = $this->is_connected();
echo '<div class="wmf-widget-body">';
if($conn) echo '<div class="wmf-connected-badge">&#10003; Verbunden</div>';
echo '<form class="wmf-int-form">';
echo '<input type="hidden" name="_wpnonce" value="'.esc_attr($nonce).'">';
echo '<input type="hidden" name="action" value="'.esc_attr($act).'">';
echo '<input type="hidden" name="services[]" value="recaptcha">';
echo '<p><label>Website-Schluessel (Site Key)</label>';
echo '<input type="text" name="credentials[recaptcha][site_key]" value="'.esc_attr($c['site_key']??'').'" class="widefat"></p>';
echo '<p><label>Geheimer Schluessel (Secret Key)</label>';
echo '<input type="text" name="credentials[recaptcha][secret_key]" value="'.esc_attr($c['secret_key']??'').'" class="widefat"></p>';
echo '<p class="description"><a href="https://www.google.com/recaptcha/admin/create" target="_blank">Schluessel bei Google erstellen &rarr;</a> (Typ: v2 Kontrollkaestchen)</p>';
echo '<p><button type="submit" class="button button-primary">Speichern</button></p>';
echo '</form>';
echo '</div>';
}
}

View File

@@ -0,0 +1,33 @@
<?php
if(!defined('ABSPATH')) exit;
class WMF_Service_RecaptchaV3 extends WMF_Service {
public $id='recaptchav3'; public $label='reCAPTCHA v3'; public $group='antispam';
protected $credentials=array('site_key'=>'','secret_key'=>'','score'=>'0.5');
public function is_connected(){return!empty($this->credentials['site_key'])&&!empty($this->credentials['secret_key']);}
public function admin_widget($prev=array()){
$c = $this->get_credentials();
$int = wmf_get_integrations();
$act = $int->action_update;
$nonce= wp_create_nonce($act);
$conn = $this->is_connected();
echo '<div class="wmf-widget-body">';
if($conn) echo '<div class="wmf-connected-badge">&#10003; Verbunden</div>';
echo '<form class="wmf-int-form">';
echo '<input type="hidden" name="_wpnonce" value="'.esc_attr($nonce).'">';
echo '<input type="hidden" name="action" value="'.esc_attr($act).'">';
echo '<input type="hidden" name="services[]" value="recaptchav3">';
echo '<p><label>Website-Schluessel (Site Key)</label>';
echo '<input type="text" name="credentials[recaptchav3][site_key]" value="'.esc_attr($c['site_key']??'').'" class="widefat"></p>';
echo '<p><label>Geheimer Schluessel (Secret Key)</label>';
echo '<input type="text" name="credentials[recaptchav3][secret_key]" value="'.esc_attr($c['secret_key']??'').'" class="widefat"></p>';
echo '<p><label>Mindest-Score (0.0-1.0, empfohlen: 0.5)</label>';
echo '<input type="number" min="0" max="1" step="0.1" name="credentials[recaptchav3][score]" value="'.esc_attr($c['score']??'0.5').'" class="small-text"></p>';
echo '<p class="description"><a href="https://www.google.com/recaptcha/admin/create" target="_blank">Schluessel bei Google erstellen &rarr;</a> (Typ: v3)</p>';
echo '<p><button type="submit" class="button button-primary">Speichern</button></p>';
echo '</form>';
echo '</div>';
}
}

View File

@@ -0,0 +1,38 @@
<?php
if(!defined('ABSPATH')) exit;
class WMF_Service_Stripe extends WMF_Service {
public $id='stripe'; public $label='Stripe'; public $group='payments';
protected $credentials=array('mode'=>'test','live_public'=>'','live_secret'=>'','test_public'=>'','test_secret'=>'');
public function is_connected(){$m=$this->credentials['mode']??'test';return($m==='live')?!empty($this->credentials['live_secret']):!empty($this->credentials['test_secret']);}
public function admin_widget($prev=array()){
$c=$this->get_credentials();
$int=wmf_get_integrations();
$act=$int->action_update;
$nonce=wp_create_nonce($act);
$m=$c['mode']??'test';
$conn=$this->is_connected();
echo '<div class="wmf-widget-body">';
if($conn) echo '<div class="wmf-connected-badge">&#10003; Verbunden ('.($m==='live'?'Live':'Test').')</div>';
echo '<form class="wmf-int-form">';
echo '<input type="hidden" name="_wpnonce" value="'.esc_attr($nonce).'">';
echo '<input type="hidden" name="action" value="'.esc_attr($act).'">';
echo '<input type="hidden" name="services[]" value="stripe">';
echo '<div class="wmf-mode-switch">';
echo '<label class="wmf-mode-btn '.($m==='test'?'active':'').'"><input type="radio" name="credentials[stripe][mode]" value="test" '.checked($m,'test',false).' onchange="wmfStripeMode(this)"> Test</label>';
echo '<label class="wmf-mode-btn '.($m==='live'?'active':'').'"><input type="radio" name="credentials[stripe][mode]" value="live" '.checked($m,'live',false).' onchange="wmfStripeMode(this)"> Live</label>';
echo '</div>';
echo '<div id="wmf-stripe-test" '.($m==='live'?'style="display:none"':'').'>';
echo '<p><label>Test Publishable Key</label><input type="text" name="credentials[stripe][test_public]" value="'.esc_attr($c['test_public']??'').'" class="widefat" placeholder="pk_test_..."></p>';
echo '<p><label>Test Secret Key</label><input type="password" name="credentials[stripe][test_secret]" value="'.esc_attr($c['test_secret']??'').'" class="widefat" placeholder="sk_test_..."></p>';
echo '</div>';
echo '<div id="wmf-stripe-live" '.($m==='test'?'style="display:none"':'').'>';
echo '<p><label>Live Publishable Key</label><input type="text" name="credentials[stripe][live_public]" value="'.esc_attr($c['live_public']??'').'" class="widefat" placeholder="pk_live_..."></p>';
echo '<p><label>Live Secret Key</label><input type="password" name="credentials[stripe][live_secret]" value="'.esc_attr($c['live_secret']??'').'" class="widefat" placeholder="sk_live_..."></p>';
echo '</div>';
echo '<p class="description"><a href="https://dashboard.stripe.com/apikeys" target="_blank">Stripe Dashboard &rarr; API-Schluessel</a></p>';
echo '<p><button type="submit" class="button button-primary">Speichern</button></p>';
echo '</form>';
echo '<script>function wmfStripeMode(el){document.getElementById("wmf-stripe-test").style.display=el.value==="test"?"":"none";document.getElementById("wmf-stripe-live").style.display=el.value==="live"?"":"none";}</script>';
echo '</div>';
}
}

View File

@@ -0,0 +1,37 @@
<?php
if(!defined('ABSPATH')) exit;
class WMF_Service_Zapier extends WMF_Service {
public $id='zapier'; public $label='Zapier'; public $group='automation';
protected $credentials=array('webhook_url'=>'');
public function is_connected(){return!empty($this->credentials['webhook_url']);}
public function admin_widget($prev=array()){
$c = $this->get_credentials();
$int = wmf_get_integrations();
$act = $int->action_update;
$nonce= wp_create_nonce($act);
$conn = $this->is_connected();
echo '<div class="wmf-widget-body">';
if($conn) echo '<div class="wmf-connected-badge">&#10003; Verbunden</div>';
echo '<form class="wmf-int-form">';
echo '<input type="hidden" name="_wpnonce" value="'.esc_attr($nonce).'">';
echo '<input type="hidden" name="action" value="'.esc_attr($act).'">';
echo '<input type="hidden" name="services[]" value="zapier">';
echo '<p><label>Webhook-URL</label>';
echo '<input type="url" name="credentials[zapier][webhook_url]" value="'.esc_attr($c['webhook_url']??'').'" class="widefat" placeholder="https://hooks.zapier.com/hooks/catch/...">';
echo '<span class="description">In Zapier: Neuer Zap &rarr; Trigger "Webhooks by Zapier" &rarr; "Catch Hook" &rarr; URL kopieren.</span></p>';
echo '<p><button type="submit" class="button button-primary">Speichern</button></p>';
echo '</form>';
echo '</div>';
}
public function load(){add_action('wmf_form_submitted',array($this,'send'),10,5);}
public function send($form_id,$meta,$fields,$values,$sub_id){
if(!$this->is_connected()) return;
wp_remote_post($this->credentials['webhook_url'],array(
'body'=>wp_json_encode(array('form_id'=>$form_id,'submission_id'=>$sub_id,'data'=>$values,'site'=>get_site_url(),'date'=>current_time('c'))),
'headers'=>array('Content-Type'=>'application/json'),'timeout'=>5,'blocking'=>false,
));
}
}

View File

@@ -0,0 +1,20 @@
<?php if(!defined('ABSPATH')) exit;
$int=wmf_get_integrations(); $action=$int->action_update;
$grp=$int->get_service_group('antispam');
$active=''; foreach($grp as $s){ if($s->is_connected()){$active=$s->id;break;} }
?>
<form class="wmf-service hf-ajax-submit">
<div class="widget-content has-service-selection <?php echo $active?'authenticated':''; ?>" data-active-service="<?php echo esc_attr($active); ?>">
<div class="wmf-settings-notices"><?php do_action('wmf_integrations_print_notices'); ?></div>
<?php wp_nonce_field($action); ?>
<input type="hidden" name="action" value="<?php echo esc_attr($action); ?>">
<input type="hidden" name="group" value="antispam">
<div class="mode-group"><label>Dienst</label><div class="wmf-buttongroup">
<?php foreach($grp as $sub): ?>
<label><input type="radio" id="service_<?php echo esc_attr($sub->id);?>" name="services[]" value="<?php echo esc_attr($sub->id);?>" <?php checked($sub->id,$active);?>><span><?php echo esc_html($sub->label);?></span></label>
<?php endforeach; ?>
</div></div>
<?php foreach($grp as $sub) $sub->admin_widget(); ?>
<div class="widget-control-actions"><span class="spinner"></span>
<input type="submit" class="button button-primary" value="Speichern"></div>
</div></form>

View File

@@ -0,0 +1,70 @@
<?php if(!defined('ABSPATH')) exit;
$screen = get_current_screen();
$sid = $screen ? $screen->id : '';
$ctrl = wmf_get_integrations_page_controller();
?>
<div class="wrap wmf-admin-wrap" id="wmf-integrations-screen">
<h1>Integrationen</h1>
<?php // Globale E-Mail-Einstellungen (volle Breite, ausserhalb des Widget-Grids)
$ctrl->render_global_email_settings(); ?>
<div id="wmf-integration-toolbar" class="media-toolbar wp-filter">
<div class="media-toolbar-secondary">
<select id="wmf-integration-filters" class="attachment-filters">
<option value="">Alle Integrationen</option>
<option value="analytics">Analyse</option>
<option value="antispam">Anti-Spam</option>
<option value="automation">Automatisierung</option>
<option value="email">E-Mail-Marketing</option>
<option value="address">Standortdienste</option>
<option value="payments">Zahlungsabwicklung</option>
</select>
</div>
<div class="media-toolbar-primary search-form">
<label for="wmf-search-input" class="media-search-input-label">Suche</label>
<input type="search" id="wmf-search-input" class="search">
</div>
</div>
<div id="dashboard-widgets-wrap" class="wmf-admin-widgets">
<!-- Suchergebnis-Bereich (per JS befuellt) -->
<div id="wmf-integrations-results-wrap">
<p id="wmf-no-integrations-found">Keine Integrationen gefunden.</p>
<div id="wmf-integrations-results" class="metabox-holder">
<div id="postbox-container-1" class="postbox-container"></div>
<div id="postbox-container-2" class="postbox-container"></div>
<div id="postbox-container-3" class="postbox-container"></div>
<div id="postbox-container-4" class="postbox-container"></div>
</div>
</div>
<!-- Normale Meta-Box-Spalten -->
<div id="dashboard-widgets" class="metabox-holder">
<div id="postbox-container-1" class="postbox-container">
<?php do_meta_boxes($sid, 'normal', ''); ?>
</div>
<div id="postbox-container-2" class="postbox-container">
<?php do_meta_boxes($sid, 'side', ''); ?>
</div>
<div id="postbox-container-3" class="postbox-container">
<?php do_meta_boxes($sid, 'column3', ''); ?>
</div>
<div id="postbox-container-4" class="postbox-container">
<?php do_meta_boxes($sid, 'column4', ''); ?>
</div>
</div>
<?php wp_nonce_field('closedpostboxes', 'closedpostboxesnonce', false); ?>
<?php wp_nonce_field('meta-box-order', 'meta-box-order-nonce', false); ?>
</div>
</div>
<script>
jQuery(document).ready(function($){
if(typeof postboxes !== 'undefined') {
postboxes.add_postbox_toggles('<?php echo esc_js($sid); ?>');
}
});
</script>