countModules macht in erster Linie eines: rechnen.
Die "Rechenformel" gibt man als Parameter an und die "Variablen" sind die Modulpositionen. Für jede Position steht intern die Zahl der Module die man der Position zugewiesen hat.
Verwirrend ist vermutlich der Umstand, dass countModules() mal die Anzahl der Module zurückgibt, ein andermal nur die Zahlen 0 oder 1. Es "rechnet" also nicht immer.
Mit einem einfachen countModules('right1') (1 Position abgefragt) bekommst du also zunächst mal eine Zahl zurück, entweder 0 (keine Module drin) oder eben die Gesamtmenge. Typischerweise prüft man so, ob der Position überhaupt ein Modul zugewiesen ist, um irgendeinen HTML-Schnipsel "auszublenden". Die Menge selbst ist dann aber unerheblich.
Innerhalb von if(xxx) ergibt jede Zahl ungleich Null den logischen Wert true, d.h. die Bedingung ist erfüllt.
Ob also 1 Modul oder 300 ist if() dann herzlich egal: Bedingung erfüllt und macht was in den {} Klammern steht *oder* das aus dem else-Block -- sofern es einen gibt.
Aus der Addition "top1 + top2 + top3 + top4" könnte also intern "2 + 0 + 1 + 1" werden. Nur wenn die Summe exakt den Wert 4 hat (also 4 == 4 ist) wird der if-Block ausgeführt.
Jedes andere Ergebnis, d.h. auch der Wert 0 ist in dieser Konstellation eben FALSE und führt das "else" aus -- sofern vorhanden.
Wenn du auf verschiedene Mengen reagieren willst, z.B. wenn exakt 2 Module da sind oder exakt 1, musst du das Ergebnis von countModules() zuerst in eine Variable packen [ist zumindest einfacher] und danach den Wert der Variablen nach allerlei Kriterien abfragen, z.B.
PHP-Code:
$menge = $this->countModules('top1 + top2 + top3 + top4'); // eine Zahl zwischen 0 und ... ziemlich viel
if ($menge == 4) {
// exakt 4 Module
}
else if ($menge == 0) {
// nix da
else if (($menge % 2) == 0) {
// eine gerade Anzahl (2, 4, 6, ...)
}
else if (($menge % 2) == 1) {
// eine ungerade Anzahl (1, 3, 5, ...)
else {
// vermutlich 1, aber tatsächlich kommen wir hier nie an ;)
}
Die Reihenfolge der "else if"s ist natürlich entscheidend 
Man kann auch logische Kombinationen angeben: "top1 or top2 or top3" ~ z.B. "2 or 0 or 1" was bedeutet: in einer der genannten Positionen muss mindestens 1 Modul publiziert sein.
"top1 and top2 and top3" ~ "2 and 0 and 1" = in jeder Position muss mindestens 1 Modul stehen, denn sobald bei 'and' eine Null auftaucht ist alles "falsch".
Sobald man logischen Operatoren wie "and" oder "or" ins Spiel bringt ist das "Rechenergebnis" von countModule() jedoch keine Summe mehr, sonder nur noch die Zahl 0 (falsch) oder 1 (wahr), entsprechend der gestellten Bedingung die man an countModule gestellt hat.
Was man dann mit diesem logischen Ergebnis, 0 bzw. 1, innerhalb des if()-Blockes anstellt, ist eine andere Sache; viel Auswahl besteht allerdings nicht :-)
Deshalb hat das == 4 in deiner ersten Abfrage mit 'or' nicht gegriffen, weil 4 nie als (logisches) Ergebnis hätte zurückkommen können.
Tricky wird es bei Subtraktionen, z.B. "top1 + top2 - top3 + top4".
Da man keine Klammern setzen kann, ist das Ergebnis evtl. nicht das was man zunächst erwartet:
"top1 + top2 - top3 + top4" ~ "2 + 0 - 1 + 1"
ergibt: 2 + 0 - 1 + 1 = 2
aber: 2 + 0 - (1 + 1) = 2 - (2) = 0
Wann man subtrahieren will? Wenn bspw. in "top3 + top4" mehr Module sind, als in "top1 + top2" und deshalb die (untere/obere) Spalte zu lang würde oder die Module nur in bestimmten (Mengen-)Konstellationen ausgegeben werden sollen ~ "das Login-Modul nur dann ausgeben, wenn oben Platz für mindestens 3 Banner ist." -- so blöder Kram eben 
Dann verschachtelt man die Abfrage und mit weiteren if()s testet man die Einzelwerte ab oder prüft die Positionen nochmal explizit; was auch immer.
Viel Spaß,
CirTap
Lesezeichen