Cookies erleichtern die Bereitstellung unserer Dienste.
Mit der Nutzung unserer Dienste erklären Sie sich damit einverstanden, dass wir Cookies verwenden.
mehr Informationen
Logo

Firmen-Blog

Bewertung

 

Joomla! > Komponente "Weblinks" erweitern

Auffinden nicht mehr benötigter Links

Screenshot

Dieses kleine Programmierbeispiel soll eine Möglichkeit aufzeigen, nicht mehr verwendete Einträge der Joomla!-Komponente Weblinks (com_weblinks) aufzuspüren.

Die Komponente Weblinks ist äußerst nützlich und sinnvoll beim Einsatz in größeren Webprojekten, um immer wiederkehrende externe Links, zum Beispiel zu Facebook oder Twitter, effektiv zu verwalten, d.h. ein Link wird einmal in die zentrale Datenbank der Weblinks aufgenommen und von allen Artikeln des Projektes aus kann eine Verknüpfung zu deren Einträgen erfolgen (1-n Beziehung).

  • 1 steht für einen Weblink
  • n steht für beliebig viele Artikel bzw. Beiträge

Der Vorteil wird erkennbar, wenn sich eben genau diese Links der Weblinks-Datenbank ändern, denn es wird nur noch der zu ändernde Eintrag in der Weblinks-Datenbank angepasst, alle Artikel des Projektes die Bezug zum geänderten Link nehmen werden automatisch aktualisiert und müssen selbst nicht aufwendig von Hand aufgespürt und  geändert werden.

Es gibt aber einen Problemfall der immer dann eintritt, wenn alte Artikel - aus welchem Grund auch immer - gelöscht werden, nun könnte es sein, dass es zahlreiche Verweise in der Weblinks-Komponente gibt, die gar keine aktive Verwendung mehr finden, nur wie findet man all diese toten Links?

Voraussetzungen für diese Beispiele

Die Joomla!-Komponenten ...

... sind installiert und aktiviert.

Die Grundidee

Sobald ein in der Komponente Weblinks existierender Eintag aktiv verwendet wird, sollte in der Joomla!-Tabelle "#__content" ein Fund zu verzeichen sein, ich begnüge mich aus Performance-Gründen mit dem ersten Treffer und breche sofort die Suche in der Tabelle "#__content" ab.

Diese Idee verpacke ich in das bereits vorhandene Template (default_items.php) der Weblinks-Komponente im Unterverzeichnis (category), am Ende haben wir eine verkettete Volltextsuche, bei der eigentlich nur noch das Kernstück fehlt, der Such-String.

Die Artikel erstelle ich mit JCE und habe mir den generierten Quellcode der Beiträge angeschaut. Die Analyse des HTML-Quellcodes ergab dabei zwei Varianten für den von JCE erzeugten Code:

index.php?option=com_weblinks&view=weblink&id=123:artist-facebook&catid=45:artists&Itemid=678
index.php?option=com_weblinks&view=weblink&id=123:artist-facebook&catid=45:artists&Itemid=678

Das hier zwei verschiedene Stings - für ein und dieselben Link - existieren ist dem Patch-Level (dem verwendeten Versionsstand) des JCE-Editors geschuldet, es kann also vorkommen, dass mit dem JCE-Editor erstellte Artikel sich ein wenig unterscheiden, abhängig von der Versionsnummer.

Die erste im den Stings verwendete ID (hier als Beispiel 123) ist die Nummer aus der Weblinks-Datenbank, die man auch sehen kann, wenn man sich die Links im Backend auflisten lässt, ganz rechte Spalte der Ergebnistabelle, die ihrerseits auch - sinnvoller Weise - mit ID bezeichnet ist.

Die zweite in den Stings verwendete ID (hier als Beispiel 45) steht für die Kategorie-Nummer zu welcher der Link in der Weblinks-Datenbank zugeordnet wurde.

Die dritte in den Strings vorkommende ID (hier als Beispiel 678) ist der Eintrag des Menüs (Menüpunkt), welches ich aber sofort abschneide, da alle toten Links gefunden werden sollen, unabhängig von der verwendeten Sprache oder dem Menüeintrag. Daraus ergeben sich zwei verkürzte Such-Strings für die Tabelle "#__content":

weblink&id=1234: -> "weblink&id=".$this->escape($item->id).":";
weblink&id=1234: -> "weblink&id=".$this->escape($item->id).":"

Den Doppelpunkt am Ende belasse ich, denn so vermeide ich den Fehler, dass ich bei einer Suche nach "%weblink&id=123%" auch "%weblink&id=1234%" als gültiges Ergebnis bekäme, denn das Wildcard-Symbol "%" am Ende würde dies technisch zulassen, um dies auszuschliessen ergänze ich den Doppelpunkt ":" am Ende meine Suchstrings zur besseren Begrenzung von Anfang und Ende der zu suchenden Objekte.

Die Umsetzung

Die Datei (default_items.php) kopiere ich nun erst einmal in mein Template-Override-Verzeichnis, also ...

templates/ihr_template/html/com_weblinks/category

... und erhalte im Ergebnis ...

templates/ihr_template/html/com_weblinks/category/default_items.php

... mit der Option, dass bei einem Update der Hauptkomponente - der (com_weblinks) - meine Änderungen noch erhalten bleiben.

Diese Datei öffnet man nun mit einem beliebigen Text-Editor (für macOS zum Beispiel TextMate, für Windows vielleicht Notepad++) und springt direkt zur Zeile ...

[100] switch ( $item->params->get('target', $this->params->get('target')) )

... und hier zum ersten Fall (case 1) ...

[102] case 1:
[103]            // Open in a new window

..., dort ergänze ich nun folgenden Code:

[104] $LinkUsed1 = "weblink&id=".$this->escape($item->id).":";
[105] $LinkUsed2 = "weblink&id=".$this->escape($item->id).":";
[106] $db        = JFactory::getDbo();
[107] $query     = $db->getQuery(true);

Variante A (ohne Berücksichtigung der Kategorien)

[108] $query
[109]            ->select(array ('a.id', 'a.fulltext'))
[110]            ->from($db->quoteName('#__content', 'a'))
[111]            ->where($db->quoteName('a.fulltext').' LIKE \'%'.$LinkUsed1.'%\'', 'OR')
[112]            ->where($db->quoteName('a.fulltext').' LIKE \'%'.$LinkUsed2.'%\'')
[113]            ->setLimit(1);
[114] $db->setQuery($query);
[115] $results   = $db->loadResult();

Variante B (mit Berücksichtigung von ausgewählten Kategorien)

[108] $where     = $db->quoteName('a.fulltext').' LIKE \'%'.$LinkUsed1.'%\' OR '
                  .$db->quoteName('a.fulltext').' LIKE \'%'.$LinkUsed2.'%\'';
[109] $query
[110]            ->select(array ('a.id, a.fulltext, a.catid'))
[111]            ->from($db->quoteName('#__content', 'a'))
[112]            ->where('('.$where.')' AND (a.catid = 1 OR a.catid = 2 OR ... OR a.catid = n)')
[113]            ->setLimit(1);
[114] $db->setQuery($query);
[115] $results   = $db->loadResult();

Die zu berücksichtigenden Kategorienummern (catids der Artikel, hier beispielhaft 1, 2, ..., n) kann man sich im Joomla!-Backend schnell heraussuchen.

Weiter für beide Varianten ...

// Optionen für $rel sind nofollow, noopener und noreferrer
// bitte an Ihre individuellen Bedürfnisse anpassen und auskommentieren
// $rel = "nofollow noopener noreferrer";
//
[116] echo '<a href="'.$link.'" class="'.$menuclass.'" rel="'.$rel.'" target="_blank" title="'.$this->escape($item->title).'">';
[117]    echo '<div class="uk-badge uk-margin-right" style="width: 1.5em;">';
[118]      echo (($this->pagination->pagesCurrent-1) * $this->pagination->limit + ($i+1));
[119]    echo '</div>';

Die Zeilen 117 bis 119 sind rein optional und stellen nur einen fortlaufenden Zähler zur besseren Übersicht vor dem Link zur Verfügung.

// kleine Ergänzung von mir für eine fortlaufende Nummer vor dem Link
// $this->pagination->pagesCurrent = aktuelle Seite
// $this->pagination->pagesTotal   = alle Seiten
// $this->pagination->limit        = aktuelle Listenlänge
// $this->pagination->total        = komplette Listenlänge

Jetzt fehlt eigentlich nur noch die Ausgabe der Prüfung, je nach Bedarf optisch aufgehübscht oder zusätzlich unter Berücksichtigung der Benutzerrechte.

[120]    if ( count($results) == 0 ) :
[121]      echo '<div class="uk-badge uk-badge-danger uk-margin-right">';
[122]        echo "0"; // Link wird nicht verwendet
[123]    else :
[124]      echo '<div class="uk-badge uk-badge-success uk-margin-right">';
[125]        echo "1"; // Link wird mindestens einmal verwendet
[126]     endif;
[127]   echo '</div>';
[128]   echo $this->escape($item->title);
[129] echo '</a>';
[130] break;

Der PHP-Code auf einem Blick (Variante A) ...

[102] case 1:
[103]            // Open in a new window
[104] $LinkUsed1 = "weblink&id=".$this->escape($item->id).":";
[105] $LinkUsed2 = "weblink&amp;id=".$this->escape($item->id).":";
[106] $db        = JFactory::getDbo();
[107] $query     = $db->getQuery(true);
[108] $query
[109]            ->select(array ('a.id', 'a.fulltext'))
[110]            ->from($db->quoteName('#__content', 'a'))
[111]            ->where($db->quoteName('a.fulltext').' LIKE \'%'.$LinkUsed1.'%\'', 'OR')
[112]            ->where($db->quoteName('a.fulltext').' LIKE \'%'.$LinkUsed2.'%\'')
[113]            ->setLimit(1);
[114] $db->setQuery($query);
[115] $results   = $db->loadResult();
[116] echo '<a href="'.$link.'" class="'.$menuclass.'" rel="nofollow" target="_blank" title="'.$this->escape($item->title).'">';
[117]    echo '<div class="uk-badge uk-margin-right" style="width: 1.5em;">';
[118]      echo (($this->pagination->pagesCurrent-1) * $this->pagination->limit + ($i+1));
[119]    echo '</div>';
[120]    if ( count($results) == 0 ) :
[121]      echo '<div class="uk-badge uk-badge-danger uk-margin-right">';
[122]        echo "0"; // Link wird nicht verwendet
[123]    else :
[124]      echo '<div class="uk-badge uk-badge-success uk-margin-right">';
[125]        echo "1"; // Link wird mindestens einmal verwendet
[126]     endif;
[127]   echo '</div>';
[128]   echo $this->escape($item->title);
[129] echo '</a>';
[130] break;

Der PHP-Code auf einem Blick (Variante B) ...

[102] case 1:
[103]            // Open in a new window
[104] $LinkUsed1 = "weblink&id=".$this->escape($item->id).":";
[105] $LinkUsed2 = "weblink&amp;id=".$this->escape($item->id).":";
[106] $db        = JFactory::getDbo();
[107] $query     = $db->getQuery(true);
[108] $where     = $db->quoteName('a.fulltext').' LIKE \'%'.$LinkUsed1.'%\' OR '
                  .$db->quoteName('a.fulltext').' LIKE \'%'.$LinkUsed2.'%\'';
[109] $query
[110]            ->select(array ('a.id, a.fulltext, a.catid'))
[111]            ->from($db->quoteName('#__content', 'a'))
[112]            ->where('('.$where.')' AND (a.catid = 1 OR a.catid = 2 OR ... OR a.catid = n)')
[113]            ->setLimit(1);
[114] $db->setQuery($query);
[115] $results   = $db->loadResult();
[116] echo '<a href="'.$link.'" class="'.$menuclass.'" rel="nofollow" target="_blank" title="'.$this->escape($item->title).'">';
[117]    echo '<div class="uk-badge uk-margin-right" style="width: 1.5em;">';
[118]      echo (($this->pagination->pagesCurrent-1) * $this->pagination->limit + ($i+1));
[119]    echo '</div>';
[120]    if ( count($results) == 0 ) :
[121]      echo '<div class="uk-badge uk-badge-danger uk-margin-right">';
[122]        echo "0"; // Link wird nicht verwendet
[123]    else :
[124]      echo '<div class="uk-badge uk-badge-success uk-margin-right">';
[125]        echo "1"; // Link wird mindestens einmal verwendet
[126]     endif;
[127]   echo '</div>';
[128]   echo $this->escape($item->title);
[129] echo '</a>';
[130] break;

Das Ergebis

Im folgenden habe ich die bei <JELEWA.de /> redaktionell verwendeten Links einmal zur öffentlichen Einsicht freigegeben, um das angepasste Template im Live-Einsatz vorführen zu können. Die gefundenen "toten Links" (engl. dead links) lasse ich allerdings nicht vollautomatisch löschen, sondern empfehle vorher die Sichtprüfung und ggf. anschliessend eine manuelle Löschung.

Falls Sie einige der Anregungen aufnehmen möchten und weitere Modifizierungen vornehmen, empfehle ich zur Sicherheit die Verwendung der Volltextsuche (com_search). Dort können Sie überprüfen, ob der von Ihnen angepasste Suchterm auch die gewünschen Ergebnisse liefert.

Symbole ...

  • 0 der Link ist nicht in Verwendung
  • 1 der Link ist in Verwendung

Viel Spaß und Erfolg beim Anpassen!


(com_jce) / (com_search) / (com_weblinks) / CSS / PHP / Web‑Technologien

Für Anfragen steht Ihnen Herr Leber gern unter (07243) 718294 zur Verfügung.
<JELEWA.de /> • Internet- & Webdesign Agentur

<JELEWA.de />

Beratung • Marketing • Technik • Webdesign
  • bistroservice.de

    Joomla!
    Design
    Redaktion
    Wartung

    bistroservice.de
  • djtimomaier.de

    WordPress
    Design
    Redaktion
    Wartung

    djtimomaier.de
  • horst-wagner-gmbh.com

    Joomla!
    Design
    Redaktion
    Wartung

    horst-wagner-gmbh.com
  • isd-ka.de

    WordPress
    Design
    Wartung
     

    isd-ka.de
  • klwgmbh.de

    Joomla!
    Design
    Redaktion
    Wartung

    klwgmbh.de
  • mess-sortiertechnik.de

    Joomla!
    Design
    Redaktion
    Wartung

    mess-sortiertechnik.de
  • rachele-fleisch.de

    Joomla!
    Design
    Redaktion
    Wartung

    rachele-fleisch.de
  • wsspalluto.de

    Joomla!
    Design
    Redaktion
    Wartung

    wsspalluto.de