Uff.. užasno mi se “neda” pisati iznova-i-iznova kod u kojem šaljem POST zahtjev u WordPress-u. Tu se obično radi o ogromnom komadu koda, gdje je PHP pomiješan sa HTML-om i koji mi svaki put bespotrebno uzme komadić života. Može li to biti bolje riješeno? …može!

‘ajmo složiti funkciju!

Sesija

Treba nam sesija za spremanje varijabli izvan POST/GET zahtjeva. Jer PHP se doslovno cijeli izgrađuje nakon svakog HTTP zahtjeva (‘ko da kompajliramo C program svaki put prije nego ga pokrenemo… vjerovatno postoje razlozi za to…). Pa nam je život varijable vezan uz život HTTP zahtjeva.

POST i varijabla zahtjeva

Moramo provjeriti da li se radi o GET ili POST HTTP zahtjevu a nakon toga moramo provjeriti, postoji li name atribut odnosno varijabla zahtjeva. Ukoliko se dogodi da je HTTP zahtjev neispravan, funkcija zove die() funkciju koja prekida daljnje izvršavanje zahtjeva.

Return, HTML tijelo forme

Funkcija vraća html string sa zaglavljem forme i submit dugmencem. U sredini smo ostavili mogućnost da dodamo dodatne elemente forme (input, checkbox…).

Token forme

U formu smo ubacili, kao hidden element random string generiran sa ‘bin2hex(random_bytes(32))’. U biti radi se o request ID-u. Kada je stranica generirana, stvara se token string koji je spremljen u sesiju i koji se šalje i uzima kao provjera u POST zahtjevu. Znači neš’ kao csrf token.

Callback funkcija

Naravno, ako je sve OK u POST zahtjevu, treba nam i način da pozovemo ili odradimo neke akcije. Za to ćemo iskoristiti callback funkciju koju zovemo nakon valjanog POST zahtjeva.

Funkcija izgleda ovako:

function ds_wpSafeForm($requestKey, $urlTarget, $formHtmlString, $cb)
{
	if (session_status() === PHP_SESSION_NONE) 
	{
		session_start();
	}

	if ($_SERVER['REQUEST_METHOD']=="POST" and $_POST[$requestKey]) 
	{
		if (isset($_SESSION[$requestKey]))
		{				
			if ($_SESSION[$requestKey] === $_POST[$requestKey])
			{
				//error_log('VALID_POST');
				$cb();				
			}
			else
			{		
				die();
			}
		}
		else
		{
			die();
		}			
	}
	
	$postId = $_SESSION[$requestKey] = bin2hex(random_bytes(32));
	
	return <<<DSHEREDOC

	<form method="post" action="$urlTarget">
	<input name="$requestKey" value="$postId" type="hidden" />

	$formHtmlString

	<input class="button" name="submit" type="submit" value="Send" /> 
	</form>

	DSHEREDOC;
	
}

Argumenti funkcije

$requestKey

Varijabla koja sadržava token a usput je koristimo i za naziv varijable sesije. Mora biti u “slug” formatu, što znači ‘alpha-beta-gamma’.

$urlTarget

Gdje će POST zahtjevi biti poslan. Ako želimo poslati na istu stranicu, koristimo:

'?page='.esc_js(esc_html($_GET['page']))

$formHtmlString

Tu ubacivamo dodatne elemente forme npr:

<input name="ds-post-form-input" placeholder="Something..." type="search" class="wp-filter-search">

$cb

Sad nakon što smo dodali svoje elemente, moramo ih i obraditi. E to radimo sa callback funkcijom. Na primjer, možemo dohvatiti sadržaj gore navedene input formice:

echo $_POST['ds-post-form-input'];

Poziv funkcije

	echo ds_wpSafeForm('ds-post-form-1', '?page='.esc_js(esc_html($_GET['page'])), 
	' <br>
		<input name="ds-post-form-input" placeholder="Something..." type="search" class="wp-filter-search">
	  <br><br>
	'
	, function(){
		echo $_POST['ds-post-form-input'];
	});

U admin sučelju, imamo:

Funkciju (zbog csrf-a) možemo koristiti i izvan WordPress-a sa manjim preinakama.