Vor einiger Zeit habe ich eine Strategie vorgestellt, wie man ein Magento-Theme einfacher erstellen kann. Wer diese Strategie nicht kennt, muss ständig zwischen dem Base- und dem eigenen Theme-Verzeichnis wechseln und jede Datei inklusive der Verzeichnisstruktur einzeln in das eigene Theme-Verzeichnis kopieren und dort anpassen.
Da dies sehr umständlich ist, nimmt der eine oder andere den einfachen Weg und kopiert das gesamte Base-Theme in das eigene Theme-Verzeichnis. Dies hat u. a. den Nachteil, dass die Update-Fähigkeit von Magento dadurch verloren geht.
Welche Möglichkeiten gibt es, um einen solchen Theme nachträglich zu bereinigen und Update-Fähigkeit wiederherzustellen?
Unveränderte Dateien manuell zu Löschen ist riskant und aufwändig. Im Web gibt es einige Tools mit den sich Verzeichnisse rekursiv vergleichen lassen. Auch können diese Tools die Inhalte der Dateien vergleichen, sodass sie sich von einer neueren aber dennoch inhaltlich gleicher Datei nicht verwirren lassen. Doch alle diese Tools sind für Synchronisierung von Verzeichnissen konzipiert. Einen Magento-Theme konnte ich leider mit keinem der Tools bereinigen, die ich ausprobiert hatte.
So wird es viel einfacher eine eigene Lösung zu Programmieren, als noch mehr Programme zu testen.
Die folgende Funktion erstellt eine Liste aller Dateien im eigenen Theme-Verzeichnis und vergleicht jede einzelne inhaltlich mit der Datei im base-Verzeichnis. Das Resultat ist ein Array mit allen Dateien des eigenen Theme-Verzeichnisses mit Angaben ob:
- verändert (changed),
- unverändert (unchanged)
- oder im base-Verzeichnis nicht vorhanden (basenotfound):
function dirCompare($myThemePath, $baseThemePath, &$output = array(), $path = '.') { $ignore = array( 'cgi-bin', '.', '..' ); $dh = @opendir( "$myThemePath/$path" ); while( false !== ( $file = readdir( $dh ) ) ){ if( !in_array( $file, $ignore ) ){ if( is_dir( "$myThemePath/$path/$file" ) ){ dirCompare( $myThemePath, $baseThemePath, $output, "$path/$file"); } else { $id = sizeof($output)+1; if(file_exists("$baseThemePath/$path/$file")) { $leftFile = file_get_contents("$myThemePath/$path/$file"); $rightFile = file_get_contents("$baseThemePath/$path/$file"); if($leftFile == $rightFile) $output[$id]['compare'] = 'unchanged'; else $output[$id]['compare'] = 'changed'; } else $output[$id]['compare'] = 'basenotfound'; $output[$id]['fullpath'] = "$myThemePath/$path/$file"; $output[$id]['path'] = "$path/$file"; $output[$id]['file'] = "$file"; } } } closedir($dh); return $output; }
Diese Liste kann nun flexibel verarbeitet werden. Entweder können unveränderte Dateien direkt mit PHP gelöscht werden, oder als Stapelverarbeitung gespeichert werden, die über das Betriebssystem ausgeführt wird.
Der nachfolgende Beispiel zeigt, wie mit Hilfe der Funktion eine Windows-Stapelverarbeitung erstellt werden kann, die alle unveränderten Dateien im eigenen Theme-Verzeichnis durch Umbenennung „deaktiviert“:
// Theme-Verzeichnisse relativ zu der PHP-Skript-Datei $base_theme = 'app/design/frontend/base/default'; $user_theme = 'app/design/frontend/default/mytheme'; $result = array(); $output = ''; dirCompare($user_theme, $base_theme, $result); // print '<pre>'; print_r($result); exit; foreach($result as $element) { switch($element['compare']) { case 'unchanged': $file = $element['file']; $fullpath = $element['fullpath']; $fullpath = str_replace('./', '', $fullpath); $fullpath = str_replace('/', '\\', $fullpath); $output .= "REN \"$fullpath\" \"$file-disabled\"\n"; break; case 'changed': break; case 'basenotfound': break; } } print $output; // file_put_contents('rename.bat', $output);
Zur Vereinfachung werden die Befehle der Stapelverarbeitung direkt im Browser ausgegeben. Beispielausgabe:
REN "app\design\frontend\default\mytheme\etc\widget.xml" "widget.xml-disabled" REN "app\design\frontend\default\mytheme\layout\authorizenet.xml" "authorizenet.xml-disabled" REN "app\design\frontend\default\mytheme\layout\bundle.xml" "bundle.xml-disabled" REN "app\design\frontend\default\mytheme\layout\captcha.xml" "captcha.xml-disabled" ... ...
Durch Entfernen der Kommentarzeichen in der letzten Zeile werden die Befehle mit der file_put_contents automatisch in einer Datei gespeichert.
Bereits die Umbenennung reicht aus, um Updatefähigkeit des Themes wiederherzustellen.
Mit einem Kommandozeilenbefehl können alle Dateien mit dem Muster *.*-disabled rekursiv gelöscht werden. Automatische Löschung leerer Verzeichnisse ist mit einem etwas komplexeren Batch-Skript oder mit kostenfreien Zusatzprogrammen möglich.