Som tidigare nämnts, så gillar jag MODx, ett publiceringssystem, licensierat under GPL, dvs.Open Source. MODx är skrivet i PHP och har ett ganska omfattande, tyvärr lite dåligt dokumenterat, system för att göra anpassningar.

En anpassning jag genast ville göra med amalsbilder.se, var en sitemap, anpassad för Googles Webmaster Tools. En sådan sitemap underlättar att få din webbplats indexerad av just Google och är i sökmotoroptimeringssysnvinkel, helt klar ett bra grepp.

Många tillägg finns redan till MODx, så även för Google Sitemaps, men mitt problem med dessa är att de bygger på Friendly URLs, vilket vi inte kan använda oss av på åmålsbilder.se, då den driftas (generöst av Resolutor AB) i en windows miljö med IIS

Så, jag vill alltså skapa en fysisk sitemap fil varje gång ett dokument i MODx sparas, publiceras eller  tas bort. Först och frömst behöver vi reda ut var nånstans vi hämtar den information som ska ligga i filen sitemap.xml. Vi behöver en URL till varje publicerad sida, samt ett datum för  när den är uppdaterad. Detta hittar vi i MODx databas och MODx databasmodell är ganska självföklarande. Vi hittar id:et för sidorna och det datum vi behöver i tabellen modx_site_content.  Adressen till webbplatsen finns lätt att hämta i MODx konfigurationsfil, och med det så har vi allt vi behöver.

Så, vi skriver en funktion som skapar filen:

 

function create()
{
	global $modx;
	$File =$modx->config['base_path'].'sitemap.xml';
	date_default_timezone_set("Europe/London");

	$result = $modx->db->select("*", "modx_site_content","deleted=0 AND published=1");
	$total_rows = $modx->db->getRecordCount( $result );

	if( $total_rows >= 1 )
	{
		$Handle = fopen($File, 'w');
		$xml_output = "\n";
		$xml_output .= "\n";

		while( $row = $modx->db->getRow( $result ) )
		{
			$xml_output .= "\n";
			$xml_output .= "\t" . $modx->config['site_url'] . "index.php?id=" . $row['id'] ."\n";
			$date = date("Y-m-d", $row['editedon']);
		        $xml_output .= "\t\t" . $date . "\n";
			$xml_output .= "\n";
		}
		$xml_output .= "";
		fwrite($Handle, $xml_output);
		fclose($Handle);
	}
}

Till att börja med behöver vi deklarera $modx som global, för att i vår funktion kunna komma åt intern MODx funktionalitet.

Därefter talar vi om var filen ska vara, dvs i roten av webbplatsen, via 

$File =$modx->config['base_path'].'sitemap.xml';

och sen måste vi sätta en tidszon, till vad som helst egentligen, för att undvika en PHP varning:

date_default_timezone_set("Europe/London");

Därefter hämtar vi den data vi vill åt från MODx databas. Detta gör vi via MODx data API, så slipper vi bry oss om vilken typ av databas som används.

$result = $modx->db->select("*", "modx_site_content","deleted=0 AND published=1");

Vi anropar alltså en select funktion, med några parametrar som genererar en SQL sats. Ovan anrop, ger alltså:

SELECT * FROM modx_site_content WHERE deleted=0 AND published=1

Därefter anropar vi en annan API funktion, som ger oss antal rader i resultatet:

$total_rows = $modx->db->getRecordCount( $result );

Vi skickar alltså med det resultat vi fått, $result och får tillbaka ett antal.

Om vi nu fått 1 träff eller fler, if( $total_rows >= 1 ), är det läge att öppna filen (finns ingen, så skapas den), och börja skriva data:

$Handle = fopen($File, 'w');
$xml_output = "\n";
$xml_output .= "\n";

Först skriver vi de generella taggarna, för XML:en och root taggen som krävs.
Därefter går vi igenom alla rader i resultatet, och skriver resterande taggar som krävs:

while( $row = $modx->db->getRow( $result ) )
{
$xml_output .= "\n";
$xml_output .= "\t" . $modx->config['site_url'] . "index.php?id=" . $row['id'] ."\n";
$date = date("Y-m-d", $row['editedon']);
$xml_output .= "\t\t" . $date . "\n";
$xml_output .= "\n";
}

 

Till sist, stäng root taggen, skriv till fil och stäng filen:

$xml_output .= "";
fwrite($Handle, $xml_output);
fclose($Handle);

Nu har vi vår funktion som skapar själva sitemapfilen.

Nästa steg är att kontrollera vilka händelser som vi ska använda. I administrationen och konfigurationen anger vi vilka händelser som vår plugin ska kopplas till. Detta görs via checkboxar på fliken ”Systemhändelser”, när vi skapar vår plugin.

Dock måste vi i pluginkoden kontrollera händelserna också.

 

$e = &$modx->Event;
switch ($e->name)
{
	case "OnDocPublished":
		create();
		break;
	case "OnDocUnPublished":
		create();
		break;
	case "OnDocFormSave":
		create();
		break;
	case "OnDocFormDelete":
		create();
	break;

 }

I variabeln $e vår vi de events som pluginen utsätts för, vilket alltså kan vara fler än de vi angett i fliken ”Systemhändelser”, $e = &$modx->Event;. Sen kollar vi namnet på händelsen i en switch sats, switch ($e->name) och för varje händelse som är aktuell, t. ex case "OnDocPublished": anropar vi vår funktion create();

Så, nu är vi hemma.

En liten hake vi inte kommer runt är att det måste finnas skrivrättigheter i roten, i alla fall till filen sitemap.xml.