Archiv der Kategorie: Wordpress

Postbank mit PHP über HBCI-Schnittstelle (wieder) abfragen

Seit dem 14.09.2019 ist es komplizierter geworden per HBCI auf das eigene Konto zuzugreifen. Geschuldet ist das der EU-Richtlinie PSD2.

Wer bis dahin das beliebte Paket fints-hbci-php genutzt hatte, hat jetzt Probleme, denn dieses Paket wird nicht mehr gepflegt; es kommt mit den Anforderungen von PSD2 nicht klar.

Da ich selbst für meinen Shop auf Null Papier einmal am Tag per HBCI automatisch die Zahlungseingänge abfrage und verarbeite, musste schnell eine neue Lösung, ein neues Paket gefunden werden.

Schnell fiel die Wahl auf nemiah/phpFinTS. Nach kurzem Austausch mit der Entwicklerin, lief es dann auch (wieder) für meine Postbank-Konten.

Anleitung

composer require nemiah/php-fints
nano vendor/nemiah/php-fints/Samples/statement_of_account.php # Anpassen

Neu ist hier die sogenannte FinTS-Registrierungsnummer. Jeder, der jetzt mit HBCI/FinTS arbeiten will, muss seine Software, egal ob App, Server-Script oder Desktop-Anwendung, registrieren lassen. Das klingt komplizierter, als es ist. Ich selbst erhielt meine Registrierungsnummer nach wenigen Minuten, daher denke ich, dass es sich hier um einen automatisierten Vergabeprozess handelt.

Die Registrierungsnummer erhält man unter: https://www.hbci-zka.de/register/prod_register.htm.

Die einzelnen Settings

FHP_BANK_URL: https://hbci.postbank.de/banking/hbci.do

FHP_BANK_PORT: 443

FHP_BANK_CODE: die Bankleitzahl

FHP_ONLINE_BANKING_USERNAME: die eigene Postbank-ID

FHP_ONLINE_BANKING_PIN: das Online-Passwort

FHP_REGISTRATION_NO: die oben erhaltene Registrierungsnummer

FHP_SOFTWARE_VERSION: die Versionsnummer der eigenen Software, bspw. 0.1b

Jetzt muss man nur noch folgende Zeile anpassen:

45: $fints->setTANMechanism(901);

mit

$fints->getVariables();

liefert die Postbank folgende, verfügbaren TAN-Mechnismen:

stdClass Object
(
    [tanModes] => Array
        (
            [912] => chipTAN optisch HHD1.4
            [913] => chipTAN manuell HHD1.4
            [920] => BestSign
            [930] => mobileTAN
        )

)

 

Ich selbst nutze die BestSign-App. WICHTIG: Die selbst erstellte Bezeichnung für das gewählte BestSign-Verfahren muss auch noch angegeben werden.

Also erhalten wir folgende Zeile

45: $fints->setTANMechanism(920, 'EigeneBezeichnung');

Jetzt sollte es eigentlich schon funktionieren. Bei mir hat es das jedenfalls.

Fragen stellt man am besten bei https://github.com/nemiah/phpFinTS/issues, damit alle etwas davon haben.

WordPress 4.9.6 – Link zur Datenschutzerklärung automatisch ausgeben

Wer nicht immer von Hand die URL zur Datenschutzerklärung eingeben möchte, oder wer sicher gehen muss, dass in den eigenen Themes immer die richtige URL angegeben wird, der kann auf folgende Funktion zurückgreifen.

print get_permalink(get_option('wp_page_for_privacy_policy'));

In Detail könnte der Abschnitt so aussehen:

Bitte schicken Sie den Fluxkompensator an meine Adresse.<br>
<a href="<?php print get_permalink(get_option('wp_page_for_privacy_policy')); ?>">Datenschutzerklärung</a>&nbsp;<input name="datenschutz" type="checkbox">&nbsp;gelesen und akzeptiert

 

Alle Preise in Woocommerce ändern – auf die smarte Art

Wer schon einmal nach dem Schlüsselwort price in einem Datenbankdump von Woocommerce und WordPress gesucht hat, weil er seine Artikelpreise gerne auf einen Schlag ändern möchte, der wird einfach nur verzweifeln.

Es gibt allein in wp_post_meta 12 Möglichkeiten, Preise einzugeben. Und das ist noch nicht einmal alles.

Annahme: Wir wollen unsere Preise einer Inflation von 2 Prozent anpassen. Wie geht man vor?

Tabelle wp_postmeta

UPDATE wp_postmeta SET meta_value = meta_value*1.02 WHERE meta_key = '_regular_price' AND meta_value != ''
UPDATE wp_postmeta SET meta_value = meta_value*1.02 WHERE meta_key = '_sale_price' AND meta_value != ''
UPDATE wp_postmeta SET meta_value = meta_value*1.02 WHERE meta_key = '_price' AND meta_value != ''
UPDATE wp_postmeta SET meta_value = meta_value*1.02 WHERE meta_key = '_regular_price_tmp' AND meta_value != ''
UPDATE wp_postmeta SET meta_value = meta_value*1.02 WHERE meta_key = '_sale_price_tmp' AND meta_value != ''
UPDATE wp_postmeta SET meta_value = meta_value*1.02 WHERE meta_key = '_price_tmp' AND meta_value != ''
UPDATE wp_postmeta SET meta_value = meta_value*1.02 WHERE meta_key = '_min_variation_price' AND meta_value != ''
UPDATE wp_postmeta SET meta_value = meta_value*1.02 WHERE meta_key = '_max_variation_price' AND meta_value != ''
UPDATE wp_postmeta SET meta_value = meta_value*1.02 WHERE meta_key = '_min_variation_regular_price' AND meta_value != ''
UPDATE wp_postmeta SET meta_value = meta_value*1.02 WHERE meta_key = '_max_variation_regular_price' AND meta_value != ''
UPDATE wp_postmeta SET meta_value = meta_value*1.02 WHERE meta_key = '_min_variation_sale_price' AND meta_value != ''
UPDATE wp_postmeta SET meta_value = meta_value*1.02 WHERE meta_key = '_max_variation_sale_price' AND meta_value != ''

Tabelle wp_options

DELETE FROM wp_options WHERE (option_name LIKE '_transient_wc_var_prices_%' OR option_name LIKE '_transient_timeout_wc_var_prices_%')

Die letzte Zeile ist besonders wichtig, da Woocommerce  einen Transient-Cache nutzt, um Seiten schneller darstellen zu können. Indem man diesen Speicher auf einen Schlag löscht, wird er automatisch beim nächsten Aufruf eines Produktes neu generiert.

Eine simple API für WordPress, Teil 4

Wir wissen jetzt, wie wir mit Hilfe unserer kleinen API einen Artikel anlegen und wie wir ihn mit einem Bild versorgen. Nun fügen wir einige Metadaten hinzu. Dazu benötigen wird die Funktion „add_post_meta„. Diese verlangt folgende Parameter:

  • post_id – Die eindeutige Artikel-ID aus Teil 2
  • meta_key – Der Name des Metadaten-Feldes
  • meta_value – Der Wert des Metadaten-Feldes

Wir packen also wieder einen Befehlsaufruf für unseren Server zusammen:

$postdata_array=array(
	'function' => 'add_post_meta', 
	'post_id' => $parent_post_id,
	'meta_key' => 'Geschmack',
	'meta_value' => 'sauer'
	);

Und natürlich müssen wir auch unseren Server wieder ein wenig ergänzen.

if ($postdata_array['function']=='add_post_meta') {
	print add_post_meta($postdata_array['post_id'], $postdata_array['meta_key'], $postdata_array['meta_value']);
}

Diese 3 Zeilen erweitern unseren Server um die Fähigkeit, mit Hilfe der Funktion „add_post_meta“ Artikel mit beliebigen Metadaten zu versorgen.

Und so sieht dann das neue benutzerdefinierte Feld aus.

Zusammenfassung

Server

<?php
define('WP_USE_THEMES', false);
header('Content-Type: text/html; charset=utf-8');
if (count($_GET)>0) $postdata_array=unserialize(array_shift($_GET));
if (count($_POST)>0) $postdata_array=unserialize(array_shift($_POST));
require('../wp-load.php');

if ($postdata_array['function']=='wp_insert_post') {
	print wp_insert_post($postdata_array['wp_post_array']);
}

if ($postdata_array['function']=='wp_insert_attachment') {
	$filetype = wp_check_filetype( basename( $postdata_array['file'] ), null );
	$wp_upload_dir = wp_upload_dir();
	$attachment = array(
		'guid'           => $wp_upload_dir['url'] . '/' . basename( $postdata_array['file']), 
		'post_mime_type' => $filetype['type'],
		'post_title'     => preg_replace( '/\.[^.]+$/', '', basename( $postdata_array['file'] ) ),
		'post_content'   => '',
		'post_status'    => 'inherit'
	);
	$attach_id = wp_insert_attachment( $attachment, $postdata_array['file'], $postdata_array['parent_post_id'] );
	require_once( ABSPATH . 'wp-admin/includes/image.php' );
	$attach_data = wp_generate_attachment_metadata( $attach_id, $postdata_array['file'] );
	wp_update_attachment_metadata( $attach_id, $attach_data );
	set_post_thumbnail( $postdata_array['parent_post_id'], $attach_id );	
}

if ($postdata_array['function']=='add_post_meta') {
	print add_post_meta($postdata_array['post_id'], $postdata_array['meta_key'], $postdata_array['meta_value']);
}

exit();
?>

Client

<?php
function call_server($postdata_array) {
	$username='mueller';
	$password='geheim';
	$serverurl='http://domain.tld/maschine/';

	$postdata = http_build_query(
		array(
			'postdata_string' => serialize($postdata_array)
		)
	);

	$auth = base64_encode($username.':'.$password);
	$header = array("Authorization: Basic $auth",
		'Content-type: application/x-www-form-urlencoded'
		);

	$opts = array('http' =>
		array(
			'method'  => 'POST',
			'header'  => $header,
			'content' => $postdata,
			'timeout' => 5000,  //5 Sekunden
		)
	);

	$context = stream_context_create($opts);
	return file_get_contents($serverurl, false, $context);
}


$postdata_array=array(
	'function' => 'wp_insert_post', 
	'wp_post_array' => array(
		'post_content' => '<p>Das ist ein <b>Test äöüß</b><br>Und noch eine Zeile</p>',
		'post_title' => 'Meine erste Überschrift',
		'post_status' => 'publish',
		'post_category' => null
		)
	);
$parent_post_id = call_server($postdata_array);

# FTP Upload des Bildes
$ftp_server='domain.tld';
$ftp_user='john';
$ftp_password='secret007';
$remote_folder='/var/www/domain.tld/wp-content/uploads/maschine/';
$local_folder='/var/upload/bilder/';
$file_name='bild.jpg';

$conn_id = ftp_connect($ftp_server);
ftp_login($conn_id, $ftp_user, $ftp_password);
ftp_put($conn_id, $remote_folder.$file_name, $local_folder.$file_name, FTP_BINARY);
ftp_close($conn_id);

$postdata_array=array(
	'function' => 'wp_insert_attachment', 
	'file' => $remote_folder.$file_name,
	'parent_post_id' => $parent_post_id
	);

print call_server($postdata_array);

# Metadaten hinzufügen
$postdata_array=array(
	'function' => 'add_post_meta', 
	'post_id' => $parent_post_id,
	'meta_key' => 'Geschmack',
	'meta_value' => 'sauer'
	);
	
call_server($postdata_array);

exit();
?>