Twinfield usability en API

Sinds een jaar gebruiken we bij Pronamic het online boekhoudsysteem Twinfield. Met dit pakket zou je eenvoudig online je administratie moeten kunnen beheren. In dit bericht zet ik daar mijn vraagtekens bij, is Twinfield wel zo eenvoudig en gebruiksvriendelijk?

Ik moet hierbij vermelden dat ik erg weinig doe met Twinfield. Ik gebruik Twinfield voornamelijk voor het opvragen van facturen en het controleren van betalingen. Toch zie ik enorm veel verbeterpunten bij deze eenvoudige handelingen. In dit bericht kort een aantal verbeterpunten.

Inloggen

Om in Twinfield in te loggen moet je naar de pagina https://login.twinfield.com/ surfen. Ik ken deze URL in principe uit mijn hoofd, maar ik type hem zelden met ‘https’ ervoor. Als je echter naar http://login.twinfield.com/ surft krijg je de melding: “De wachttijd voor de verbinding is verstreken“. Zou het zo lastig zijn om http://login.twinfield.com/ netjes door te linken naar https://login.twinfield.com/?

Zodra je uiteindelijk het inlogformulier voor je hebt begint de voglende uitdaging. Je moet een gebruikersnaam, wachtwoord en een omgeving invoeren. De gebruikersnaam en wachtwoord zijn erg gebruikelijk, maar waar dient ‘omgeving’ voor? Het zal vast een doel hebben binnen Twinfield, maar ik vind het een onnodig extra veld.

Deze problemen zijn in principe eenvoudig te verhelpen door de login URL en de logingegevens op te slaan binnen je webbrowser. De ontwikkelaars van Twinfield zouden dit echter ook kunnen vereenvoudigen. Met de kreet “Snel starten en overal toegankelijk” op hun website zou je dat wel mogen verwachten, want snel Twinfield starten is mij nog niet gelukt ;).

Navigeren

Als ik vervolgens ben ingelogd en een factuur wil bekijken klik ik in het hoofdmenu op het item “Facturatie”. Ik krijg zodra ik met mijn muis over dit item ga keurig een ‘pointer’ cursor te zien. Door de ‘pointer’ cursor krijg ik het idee dat dit item linkt naar een pagina “Facturatie”, maar dit blijkt niet zo te zijn.

Zodra ik op dit item klik opent er niet een nieuwe pagina, maar sluit het zojuist automatische geopende submenu. Dit terwijl het submenu de enige manier is om naar een pagina te navigeren is.

Als je veel met Twinfield werkt zul je wel snel gewend zijn aan het feit dat hoofdmenu items niet bruikbaar zijn. Voor de gebruikers die minder regelmatig met Twinfield werken is dat toch minder gebruiksvriendelijk.

Bladeren

Waar ik me nog het meeste over verbaas is dat je binnen Twinfield niet direct vanuit het hoofdmenu lijsten met gegevens kunt opvragen. Vanuit veel webapplicaties ben ik gewend dat zodra je op een hoofd menu item klikt je direct door gegevens heen kunt bladeren. Zo kun je in WordPress in het hoofdmenu klikken op “Berichten” en krijg je direct de meest recente berichten te zien:

Waarom kan ik binnen Twinfield niet via het hoofdmenu een overzicht met crediteuren, debiteuren, facturen, bankafschriften, etc. tevoorschijn toveren? Data opvragen binnen Twinfield moet blijkbaar beslist via allerlei onhandige zoekformulieren. Zo moet ik voor het bekijken van de laatst verzonden facturen naar “Opvragen” onder het menu item “Facturatie” gaan en vervolgens het volgende formulier invullen:

Als ze nou eens onder het hoofdmenu item “Facturatie” meteen de meest recente facturen weergeven zou me dat enorm veel tijd besparen. Hetzelfde geldt ook voor allerlei andere objecten zoals crediteuren en debiteuren. Eenvoudig een overzicht naar voren halen en daardoor heen bladeren zit er bij Twinfield naar mijn idee niet in.

Permalinks

Permalinks zijn denk ik de basis van elke goede webapplicatie. Alle data binnen een webapplicatie moet naar mijn idee bereikbaar zijn onder een unieke permanente link. Gelukkig beseffen veel ontwikkelaars wereldwijd dit en is data steeds vaker terug te vinden onder een unieke permanente link.

Bij Pronamic werken we met allerlei webapplicaties. Je kunt daarbij denken aan de webapplicaties van 37signals (Basecamp, Highrise, etc.) en het Pronamic intranet met alle klant- en projectdata. Alle data binnen deze webapplicaties zijn via een unieke URL op te vragen. Ik merk dat we deze URL’s intern steeds vaker gebruiken, zo linken we in e-mails, chats en andere applicaties naar gerelateerde data.

Helaas is data binnen Twinfield nog lang niet altijd goed onder een unieke permanente link beschikbaar. Dit terwijl ik juist regelmatig naar administratieve data in Twinfield wil linken. Zo zou ik bij vragen over data binnen Twinfield een collega kunnen mailen met een link naar de betreffende data.

Conclusie

Ik denk dat Twinfield qua usability nog flink aan de weg moeten werken. Administratief gezien zullen bepaalde dingen vast en zeker handig opgezet zijn. Voor iemand die echt eenvoudig en snel zijn administratie wil doen lijkt Twinfield mij minder handig. Ik denk dat voor mensen zoals mij hippen en moderne webapplicaties zoals MoneyBird veel fijner werken.

Gelukkig heeft Twinfield ook een API beschikbaar gesteld. Het is dus mogelijk om Twinfield data via een eigen applicatie op te vragen en gebruiksvriendelijker weer te geven. Ik heb op Google Code: https://code.google.com/p/twinfield/ wat meer informatie over deze API gepubliceerd. Naast dat heb ik ook een aantal experimentele PHP 5.3+ classes ontwikkeld waarmee bepaalde Twinfield data is op te vragen.

Dummy code

<?php

namespace Pronamic\Twinfield;

$twinfieldClient = new TwinfieldClient();

// Inloggen
$result = $twinfieldClient->logon($username, $password, $organisation);

// Kantoren opvragen
$offices = $twinfieldClient->getOffices();

// Zoeken
$finder = $twinfieldClient->getFinder();

$search = new Search();
$search->setType(Search::TYPE_DIMENSION);
$search->setPattern('*');
$search->setField(Search::FIELD_ALL_CODE_OR_NAME);
$search->setFirstRow(1);
$search->setMaxRows(Search::ROWS_ALL);

?>

Ik wil dit te zijner tijd verder gaan ontwikkelen en het opvragen van bepaalde data in Twinfield vereenvoudigen. Wellicht zijn er vervolgens ook mogelijkheden om andere PHP applicaties te koppelen aan Twinfield. Zo is er volgens mij veel interesse in een stabiele Magento Twinfield koppeling.

Valide HTML, SEO en code / tekst verhouding

Onlangs twitterde ik over de YouTube video “Is HTML validation necessary for ranking?” uit het Google Webmaster Help kanaal. Uit deze video blijkt dat Google eigenlijk helemaal niet naar de correctheid van HTML kijkt.

Collega Martijn Duker reageerde hier op met de volgende tweet:

@remcotolsma Validatie is direct niet van invloed., maar indirect weer wel, schone code is vaak kortere code = snellere laadtijd. #SEO #W3C

Ik denk dat Martijn daarmee de spijker op de kop slaat. Het werken volgens de W3C standaarden kan indirect heel veel invloed hebben op je positie bij zoekmachines. Door volgens de HTML standaarden te werken is je content in veel gevallen beter gestructureerd. Daarnaast is je code vaak ‘schoner’ en daardoor sneller.

Concullega Harmen Visser van TRES internet tweette vervolgens dat er bij schonere code er in verhouding meer content is en dat je juist daarmee goed scoort. In de zoekmachine optimalisatie wereld noemen ze dit ook wel de “Code to Text Ratio”. De “Code to Text Ratio” geeft de verhouding tussen content en code (HTML, CSS, JavaScript, etc.) aan.

@MDuker @remcotolsma Bij schonere code is er in verhouding meer content. Juist dat scoort goed bij Google.

@remcotolsma @mduker Google beoordeelt een pagina oa obv de verhouding content vs. code. Hoe minder code hoe beter de score. #SEO

Het leek mij persoonlijk heel erg onwaarschijnlijk dat juist hierdoor websites hoger scoren. Het aantal HTML elementen die gebruikt worden zouden naar mijn idee namelijk niet invloed moeten hebben op de indxering van een webpagina. Het goed structureren van content kan in sommige gevallen immers zelfs zorgen voor meer code.

Naar aanleiding van de tweet van Harmen ben ik hier even wat dieper ingedoken. Allereerst heb ik de Google Webmaster Help kanaal op YouTube eens doorzocht. Helaas kon daar ik geen video’s vinden over dit onderwerp. Eén video die hier misschien een beetje aan gerelateerd is gaat over witruimte in een webpagina.

Uit deze video blijkt dat extra witruimte eigenlijk geen invloed heeft op je positie bij Google. Kan ik daaruit concluderen dat minder of meer code ook geen invloed heeft?

Op de Wemaster Tools Help Forum van Google zijn gelukkig wel een aantal berichten te vinden gerelateerd aan de “Code to Text Ratio“. In de meeste berichten wordt duidelijk gemaakt dat de code / content verhouding nauwelijks of geen invloed heeft op je positie bij
Google. Eén persoon die stelt zichzelf de volgende vragen:

  • Heb je een tool gezien in de Google Webmaster hulppgromma’s voor de “Code to Text Ratio”?
  • Heb je hier ooit een bericht, waarschuwing en/of melding over gezien in de Google Webmaster hulppgromma’s?
  • Denk je echt dat een pagina met een eenvoudig ontwerp en minimale structuur hoger scoort dan een grotere ingewikkelde pagina met meer code?
  • Is het niet waarschijnlijker dat Google geen of weinig aandacht besteeds aan zulke dingen?

Ik denk dat dit de mensen wel aan het denken zet: de “Code to Text Ratio” daar hecht Google geen waarde aan. Dat een goede “Code to Text Ratio” juist hoog scoort bij Google is naar mijn idee in ieder geval onjuist. Ik ben echter erg benieuwd naar jullie mening over dit onderwerp.

Extra informatie

CentOS tijd instellen / synchroniseren

Tijd op een server is erg belangrijk, het is heel vervelend als de tijd van een server onjuist is. Ik had onlangs wel te maken met een Linux machine waarop de tijd verkeerd stond. Dit is gelukkig eenvoudig op te lossen door de tijd te synchroniseren met een NTP server.

Om binnen CentOS te controleren of de tijd goed is ingesteld kun je de volgende commando uitvoeren:

[ ~]# date
Fri Mar 18 21:50:43 CET 2011

Hier staat CET voor de tijdzone “Central European Time”, dit is de tijdzone voor de wintertijd. In de zomertijd zal CEST zijn, wat staat voor “Central European Summer Time. Mocht de tijd bij jou niet correct staan dan kun je hier voor NTP installeren. Dit kun je doen door de volgende commando uit te voeren:

[ ~]# yum install ntp

Als het goed is wordt nu NTP geïnstalleerd of krijg je de melding “Nothing to do” als dit pakket al op je machine staan. Vervolgens kun je het volgende commando uitvoeren om de tijd te synchroniseren:

[ ~]# ntpdate pool.ntp.org

Als je de melding krijgt dat de NTP socket al in gebruik is dan is er waarschijnlijk al een NTP proces (daemon) actief. Deze kun je uitschakelen door het volgende commando uit te voeren:

[ ~]# /etc/init.d/ntpd stop

Als het goed moet je vervolgens wel de ntpdate commando kunnen uitvoeren.

[ ~]# ntpdate pool.ntp.org
18 Mar 22:05:57 ntpdate[24291]: adjust time server 204.62.14.98 offset -0.010934 sec

Vervolgens kun je de NTP deamon weer starten door het volgende commando
uit te voeren:

[ ~]# /etc/init.d/ntpd start

Als ik het goed begrepen heb worden processen binnen CentOS niet automatisch gestart. Als je het NTP proces automatisch wilt laten starten dan dien je het volgende commando uit te voeren:

[ ~]# chkconfig ntpd on

Het kan overigens ook zijn dat de tijdzone niet correct staat ingesteld op je machine. Voor het instellen van de tijdzone moet je een symlink maken naar een zoneinfo bestand. Voor de Nederlandse tijdzone zal dat er zo moeten uitzien:

/etc/localtime -> /usr/share/zoneinfo/Europe/Amsterdam

Je kunt deze symlink aanmaken door het voglende commando uit
te voeren:

[ ~]# ln -sf /usr/share/zoneinfo/Europe/Amsterdam /etc/localtime

Zang verwijderen uit MP3 liedje

Voor de 50e verjaardag van mijn vader hebben we een liedje geschreven op
de melodie van een bestaand liedje. Helaas konden we van dit liedje niet
een karaoke versie vinden. Gelukkig zijn er allerlei programma’s die de
zang uit een liedje kunnen verwijderen.

Voor het verwijderen van de zang heb ik gebruik gemaakt van de
“Vocal Remover” Winamp plugin van Brian Andrews. Zodra je deze plugin activeert kun je procentueel aangeven hoeveel zang er verwijderd moet worden. Voor de beste resultaten zul je hier een beetje mee moeten spelen.

Zodra je plugin heb gedownload en geïnstalleerd kun je de plugin activeren:
“Opties » Voorkeuren…” (sneltoets Ctrl + P) en vervolgens naar
“Plugin-ins » DSP/Effect” en klikken op “AnalogX Vocal Remover [dsp_vr.dll]”.

De plugin werkt helaas niet voor alle liedjes even goed, maar voor een
gratis plugin is het zeker niet verkeerd. Zodra je de plugin goed hebt
afgesteld kun je er voor kiezen het aangepaste liedje op te slaan in een WAV
bestand. Hiervoor ga je naar: “Opties » Voorkeuren…” (sneltoets Ctrl + P)
en vervolgens naar “Plugin-ins » Uitvoer” klikken op “Nullsoft Disk Write v2.14 [out_disk.dll]” en het liedje afspalen.

WordPress media bestanden met rare tekens

Onlangs hebben we een nieuwe WordPress website gelanceerd bij Pronamic. De opdrachtgever heeft deze website netjes gevuld op de ontwikkel- en testomgeving van Pronamic. Vervolgens hebben we deze verplaatst naar de productieomgeving. Hierbij liepen we echter tegen een probleem aan. Veel geüploade bestanden hadden in de bestandsnaam rare tekens, zoals copyright (©) tekens. Op de ontwikkel- en testomgeving leverde dit geen problemen op, maar helaas op de productieomgeving wel.

Aangezien het om een flink aantal bestanden ging was het handmatig aanpassen of opnieuw uploaden niet een optie. Ik kon helaas ook geen geschikte WordPress plugin vinden die dit probleem kon verhelpen. Om die reden heb ik zelf maar even een oplossing ontwikkeld. Allereerst heb ik een MySQL query bedacht die alles © tekens vervangt met een gewone c teken.

UPDATE wp_postmeta SET meta_value = REPLACE(meta_value, '©', 'c') WHERE meta_key = '_wp_attached_file';
UPDATE wp_postmeta SET meta_value = REPLACE(meta_value, '©', 'c') WHERE meta_key = '_wp_attachment_metadata';
UPDATE wp_posts SET guid = REPLACE(guid, '©', 'c') WHERE post_type = 'attachment';

Vervolgens moesten de bestanden in de WordPress uploads mag ook gewijzigd worden. Hiervoor heb ik eenvoudig PHP script geschreven en uitgevoerd in de uploads map:

<?php

$rdi = new RecursiveDirectoryIterator('./');
$rii = new RecursiveIteratorIterator($rdi);

foreach($rii as $file) {
	$name = $file->getPathname();

	$copyrightPosition = strpos($name, '©');

	if($copyrightPosition !== false) {
		$newName = str_replace('©', 'c', $name);

		$renamed = rename($name, $newName);

		echo $name, ' = ', $newName, ' = ', ($renamed ? 'renamed' : 'failed'), '<br />';
	}
}

Uiteindelijk heb ik voor de zekerheid alle afbeelding en bijbehorende thumbnails opnieuw laten generen met de Regenerate Thumbnails plugin. Mocht je ook ooit een dergelijke probleem hebben dan hoop ik dat je met bovenstaande code fragmenten dit snel kunt oplossen. Eventueel kan Pronamic ook een plugin voor je ontwikkelen die geautomatiseerd je probleem kan verhelpen. Mocht je nog vragen, opmerkingen en/of tips hebben laat dan gerust een reactie achter.

Magento factuurdatum toevoegen aan PDF

Bij Pronamic krijgen we regelmatig de vraag om de factuurdatum toe te voegen aan de Magento factuur PDF. Volgens de belastingdienst moet de factuurdatum immers verplicht op de factuur staan. Op internet zijn gelukkig genoeg pagina’s te vinden waarop wordt uitgelegd hoe je dit voor elkaar kunt krijgen.

Als je de factuurdatum achter het factuurnummer wilt plaatsen in de PDF kun je daarvoor de volgende code gebruiken.

$page->drawText(Mage::helper('sales')->__('Invoice Date') . ': ' . Mage::helper('core')->formatDate($invoice->getCreatedAt(), 'full', false), 285, 780, 'UTF-8');

Deze regel kun je toevoegen aan het bestand ‘app/code/local/Mage/Sales/Model/Order/Pdf’ onder de regel:

$page->drawText(Mage::helper('sales')->__('Invoice # ') . $invoice->getIncrementId(), 35, 780, 'UTF-8');

De datum kan in verschillende formaten worden weergegeven in de PDF. Hier voor wordt gebruik gemaakt van de ‘formatDate’ functie. Binnen de 2e parameter kun je opgeven in welk formaat de datum weergegeven moet worden. Je kunt hiervoor kiezen uit de volgende PHP class constanten uit de Mage_Core_Model_Locale class:

  • Mage_Core_Model_Locale::FORMAT_TYPE_FULL = ‘full’
  • Mage_Core_Model_Locale::FORMAT_TYPE_LONG = ‘long’
  • Mage_Core_Model_Locale::FORMAT_TYPE_MEDIUM = ‘medium’
  • Mage_Core_Model_Locale::FORMAT_TYPE_SHORT = ‘short’

Als je werkt met de Nederlandse Magento dan kun je de volgende output verwachten:

  • ‘full’ = maandag 31 januari 2011
  • ‘long’ = 31 januari 2011
  • ‘medium’ = 31 jan. 2011
  • ‘short’ = 31-01-11

Met de 3e parameter kun je overigens opgeven of je de tijd ook wilt weergeven. Als je hier false opgeeft zal de tijd niet worden weergeven, bij true wel.

Gravity Forms custom posts

Via Gravity Form is het mogelijk om je bezoekers (concept)berichten te laten plaatsen. Je kunt hierbij gebruik maken van verschillende vooraf gedefinieerde velden. Helaas is het nog niet mogelijk om custom posts aan te maken. Gelukkig is deze functionaliteit met behulp van filters en hooks wel te realiseren.

function custom_gform_set_post_type($post_data, $form) {
	$classes = explode(' ', $form['cssClass']);

	$items = apply_filters('custom_gform_post_type_classes', array());

	foreach($items as $class => $post_type) {
		if(in_array($class, $classes)) {
			$post_data['post_type'] = $post_type;
		}
	}

    return $post_data;
}

add_filter('gform_post_data', 'custom_gform_set_post_type', 10, 2);

Vervolgens kun je met behulp van de volgende filter CSS classes koppelen aan een custom post type.

function dvt_gform_post_type_classes($ptc) {
	$ptc['opponent-form'] = 'opponent';

	return $ptc;
}

add_filter('custom_gform_post_type_classes', 'dvt_gform_post_type_classes');

Gravity Forms custom taxonomies dropdown

Via Gravity Form is het mogelijk om je bezoekers (concept)berichten te laten plaatsen. Je kunt hierbij gebruik maken van verschillende vooraf gedefinieerde velden. Helaas is er nog geen standaard veld beschikbaar voor custom post types en taxonomies. Gelukkig is deze functionaliteit met behulp van filters en hooks wel te realiseren.

Populate dropdown

function custom_gform_dropdown_terms($arguments, $withEmpty = true) {
	$terms = get_terms($arguments);

	$items = array();

	if($withEmpty) {
		$items[] = array('text' => '', 'value' => '');
	}

	foreach($terms as $term) {
		$items[] = array('value' => $term->term_id, 'text' => $term->name);
	}

	return $items;
}

function custom_gform_populate_dropdown($form) {
	$items = apply_filters('custom_gform_taxonomies_classes', array());

	foreach($form['fields'] as &$field) {
		$classes = explode(' ', $field['cssClass']);

		foreach($items as $class => $taxonomy) {
			if(in_array($class, $classes)) {
				$field['type'] = 'select';
				$field['choices'] = custom_gform_dropdown_terms($taxonomy);
			}
		}
	}

	return $form;
}

add_filter('gform_pre_render', 'custom_gform_populate_dropdown');

Koppel CSS class met taxonomy

Vervolgens kun je met behulp van de volgende filter CSS classes koppelen aan een taxonomy.

function dvt_gform_taxonomy_classes($tc) {
	$tc['taxonomy-level'] = 'level';
	$tc['taxonomy-region'] = 'region';

	return $tc;
}

add_filter('custom_gform_taxonomies_classes', 'dvt_gform_taxonomy_classes');

Terms opslaan per post

Tot slot zorgt het volgende code fragment er voor dat de terms worden opgeslagen bij de betreffende post.

function custom_gform_save_terms($lead, $form) {
	// Check if the submission contains a WordPress post
	if(isset($lead['post_id'])) {
		$items = apply_filters('custom_gform_taxonomies_classes', array());

		foreach($form['fields'] as &$field) {
			$classes = explode(' ', $field['cssClass']);

			foreach($items as $class => $taxonomy) {
				if(in_array($class, $classes)) {
					$value = (int) $lead[$field['id']];

					wp_set_object_terms($lead['post_id'], $value, $taxonomy);
				}
			}
		}
	}
}

add_action('gform_post_submission', 'custom_gform_save_terms', 10, 2);

Bronnen

Magento webwinkel verhuizen

Het verhuizen van een Magento webwinkel naar een nieuwe server / locatie kan een hele klus zijn. Een Magento installatie die al een aantal jaren actief kan al snel 2+ GB aan ruimte in nemen. Met meer dan 100.000+ bestanden en 25.000+ mappen kan het verhuizen veel tijd kosten. Daarnaast is er vaak ook een MySQL database die 500+ MB aan data bevat.

Op de Wiki van Magento staat beschreven hoe je een Magento installatie kunt verhuizen naar een andere locatie. In eerste instantie wordt beschreven dat je een nieuwe Magento installatie moet opzetten en vervolgens de oude data moet importeren. Aan het eind van het artikel wordt echter ook een alternatieve methode toegelicht. In de alternatieve variant hoef je geen nieuwe Magento installatie opzetten. In plaats daarvan moet je daadwerkelijk alle bestanden en de database naar de nieuwe locatie verplaatsen.

Er zijn wel een aantal aandachtspunten waar je rekening mee moeten houden als je een Magento webwinkel op deze manier gaat verhuizen. Zo zul je in veel gevallen het bestand pear.ini (downloader/pearlib/pear.ini) moeten wijzigen om de MagentoConnect manager te laten werken.

Magento heeft hier een eenvoudig script voor beschikbaar gesteld die een nieuw pear.ini bestand voor je kan generen. Ik zelf vond het Magento script niet heel gebruiksvriendelijk en heb daarom een aantal verbeteringen aangebracht.

<?php

define('CR', "\r");
define('LF', "\n");
define('CRLF', CR . LF);

$contents = explode(LF, file_get_contents('pear.ini'));

$data = unserialize($contents[1]);

if(isset($data['bin_dir'])) {
	$oldPath = $data['bin_dir'];
	$newPath = getcwd();

	foreach($data as $key => $value) {
		if(is_string($value)) {
			$data[$key] = str_replace($oldPath, $newPath, $value);
		}
	}
}

?>
<!DOCTYPE html>

<html lang="en">
	<head>
		<meta charset="utf-8" />

		<title>Magento pear.ini generator | Pronamic</title>
	</head>

	<body>
		<h1>Magento pear.ini generator</h1>

		<h2>Paths</h2>

		<dl>
			<dt>Old path</dt>
			<dd>
				<?php if(isset($oldPath)): ?>
				<code><?php echo $oldPath; ?></code>
				<?php else: ?>
				<em>Unknown</em>
				<?php endif; ?>
			</dd>

			<dt>New path</dt>
			<dd>
				<?php if(isset($newPath)): ?>
				<code><?php echo $newPath; ?></code>
				<?php else: ?>
				<em>Unknown</em>
				<?php endif; ?>
			</dd>
		</dl>

		<h2>pear.ini</h2>

		<?php 

		$pearIni = $contents[0] . LF . serialize($data);

		?>
		<p>
			<textarea name="pear.ini" cols="80" rows="10"><?php echo $pearIni; ?></textarea>
		</p>
	</body>
</html>

Mocht je ooit een Mangeto webwinkel moeten verhuizen dan kan dit script zeker van pas komen!