Automatische Indizierung von per FTP hochgeladenen Ordnern

Gesperrt
spectral
Beiträge: 38
Registriert: Mi 5. Mär 2008, 16:40
Kontaktdaten:

Automatische Indizierung von per FTP hochgeladenen Ordnern

Beitrag von spectral »

Hallo!

Damit Dateien, die per FTP in den Conenido-Upload-Bereich hochgeladen wurden, in Contenido sichtbar sind, muss man ja normalerweise anschließend in der Dateiverwaltung in jedes neue Verzeichnis gehen, damit die darin befindlichen Dateien in der Datenbank indiziert werden. Kann man das nicht irgendwie automatisieren?

Mein Problem:
Wir haben für einen Kunden einen größeren Downloadbereich programmiert, der die Ordnerstruktur innerhalb des Contenido-Upload-Bereichs abbildet. Jetzt möchte der Kunde sehr schnell per FTP tiefe und weit verzweigte Ordnerstrukturen und darin befindliche Dateien hochladen und modifizieren, die dann im Downloadbereich so zu sehen sind. Normalerweise müsste er danach in der Contenido Dateiverwaltung in jedes Verezeichnis klicken, damit die Datenbank aktualisiert wird, was bei um die 50 Verzeichnissen recht mühsam ist.

Die Funktion, die ich bräuchte:
Kennt einer von Euch eine Möglichkeit, wie ich den Indexierungsvorgang manuell oder automatisch auslösen kann. Gibt es vielleicht eine Funktion, die ich in mein Modul einbauen kann und mit der ich sage "Überprüfe für Verzeichnis X, ob die Datenbank aktuell ist, entferne gelöschte Dateien und Verzeichnisse und trage neue ein"?

Für Hilfe wäre ich sehr dankbar,

Andras
xmurrix
Beiträge: 3215
Registriert: Do 21. Okt 2004, 11:08
Wohnort: Augsburg
Hat sich bedankt: 4 Mal
Danksagung erhalten: 17 Mal
Kontaktdaten:

Re: Automatische Indizierung von per FTP hochgeladenen Ordne

Beitrag von xmurrix »

Hallo,

du kannst die Funktion zum Synchronisieren von Uploadverzeichnissen dafür verwenden, z. B. in einem Modul mit folgendem Code:

Code: Alles auswählen

cInclude('includes', 'functions.upl.php');

$sUplPath    = $cfgClient[$client]['upl']['path'];
$sPathToSync = $sUplPath . '/';

$oIterator = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator($sPathToSync), RecursiveIteratorIterator::SELF_FIRST
);

foreach ($oIterator as $sFilename => $oFileInfo) {
    if ($oFileInfo->isDir()) {
        $sPath = str_replace('\\', '/', $oFileInfo->getRealPath()) . '/';
        $sPath = str_replace($sUplPath, '', $sPath);
        uplSyncDirectory($sPath);
    }
}
Das Beispiel synchronisiert z. B. rekursiv das Uploadverzeichnis und sämtliche Unterterverzeichnisse des aktuellen Mandanten.

Bei mehreren Tausend Verzeichnissen oder Dateien würde ich das nicht in einem Modul machen, da das Script dann sehr lange brauchen kann. In der Regel laufen solche Scripte maximal 30 Sekunden.

Gruß
xmurrix
CONTENIDO Downloads: CONTENIDO 4.10.1
CONTENIDO Links: Dokumentationsportal, FAQ, API-Dokumentation
CONTENIDO @ Github: CONTENIDO 4.10 - Mit einem Entwicklungszweig (develop-branch), das viele Verbesserungen/Optimierungen erhalten hat und auf Stabilität und Kompatibilität mit PHP 8.0 bis 8.2 getrimmt wurde.
spectral
Beiträge: 38
Registriert: Mi 5. Mär 2008, 16:40
Kontaktdaten:

Re: Automatische Indizierung von per FTP hochgeladenen Ordne

Beitrag von spectral »

Vielen Dank das funktioniert perfekt!

Andras
spectral
Beiträge: 38
Registriert: Mi 5. Mär 2008, 16:40
Kontaktdaten:

Re: Automatische Indizierung von per FTP hochgeladenen Ordne

Beitrag von spectral »

Jetzt habe ich doch noch ein Problem:

Wird ein Ordner per FTP gelöscht, bleibt der Datenbankeintrag des Ordners mit allen ehemals darin gewesenen Dateien erhalten. Ich kenne dieses Verhalten schon aus der Dateiverwaltung und das Script von oben verhält sich genauso. Die einzige Chance, die nicht mehr existierenden Dateien aus der Datenbank zu bekommen, ist, alle gelöschten Ordner mit exakt gleichem Namen wieder per FTP anzulegen und dann im Contenido-Backend zulöschen.

Dieses schöne Aktualisieren der Datenbank mit einem Klick, das obiges Script verspricht wäre natürlich dann perfekt, wenn auch entfernte Verzeichnisse und die darin gewesenen Dateien aus der Datenbank gelöscht werden. Gibt es dafür vielleicht auch einen Weg? :roll:

Gruß, Andras
spectral
Beiträge: 38
Registriert: Mi 5. Mär 2008, 16:40
Kontaktdaten:

Re: Automatische Indizierung von per FTP hochgeladenen Ordne

Beitrag von spectral »

so jetzt habe ich selbst eine Lösung dafür programmiert, vielleicht ist damit auch anderen geholfen...

Zuerst wird der Code von xmurrix ausgeführt.
Dann kommt der Teil der sich um die Einträge aus gelöschten Verzeichnissen kümmert:
1. Die Datenbank-Tabelle con_upl wird eingelesen und nach nicht mehr existierenden Dateien durchsucht.
2. Die Datenbank-Tabelle con_upl_meta wird eingelesen und nach nicht mehr in con_upl eingetragenen Dateien durchsucht.
3. Die verweisten Einträge werden aus der Datenbank entfernt, wenn die Seite mit dem Parameter ?kill=yes aufgerufen wurde.

Code: Alles auswählen

<?php
cInclude ("classes", "class.upload.php");
cInclude ("classes", "class.htmlelements.php");
cInclude('includes', 'functions.upl.php');

$sUplPath    = $cfgClient[$client]['upl']['path'];
$sPathToSync = $sUplPath . '/';

echo '<p>1. Aktualisieren der Datenbank...'</p>;

//Upload Verzeichnis wird durchsucht neue Dateien werden in DB eingetragen, gelöschte Dateien aus DB entfernt

$oIterator = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator($sPathToSync), RecursiveIteratorIterator::SELF_FIRST
);

foreach ($oIterator as $sFilename => $oFileInfo) {
    if ($oFileInfo->isDir()) {
        $sPath = str_replace('\\', '/', $oFileInfo->getRealPath()) . '/';
        $sPath = str_replace($sUplPath, '', $sPath);
        uplSyncDirectory($sPath);
    }
}

echo '<p>Neue Dateien wurden in die Datenbank eingetragen.</p>';

//Datenbankeinträge aus con_upl werden eingelesen
//Hier die SQL-Server Zugangsdaten und Datenbankname eintragen:

$c = mysql_connect('mysql.server.de', 'login', '***') OR die (mysql_error());
mysql_select_db('datenbank', $c) OR die (mysql_error());

  
$upl = "SELECT 
          idupl, 
          filename,
          dirname
       FROM 
          con_upl
       ORDER BY idupl";
          
         
$uplArr = mysql_query($upl, $c) OR die (mysql_error());


// URL zum endgültigen Löschen wird erzeugt
if (isset($_SERVER["QUERY_STRING"]) && ("" != $_SERVER["QUERY_STRING"])){
  $killUrl = $_SERVER["PHP_SELF"] . '?' . $_SERVER["QUERY_STRING"] . '&kill=yes';
} else {
  $killUrl = $_SERVER["PHP_SELF"] . '?kill=yes';
}

            
if (isset($_GET['kill']) && $_GET['kill']=='yes') {// Wenn Löschfunktion ausgeführt
  echo '
  <p style="font-weight:bold;"><span style="text-decoration:line-through; color:#990000;">Durchgestrichene Zeilen</span> <span style="color:#22aa11;">sind soeben aus der Datenbank entfernt worden.</span><br>
  <a href="'.$_SERVER["PHP_SELF"].'?idart='.$idart.'">Klicken Sie hier</a>, um die Liste zu aktualisieren.<br></p>';
} else {
  echo'
  <p><b>2. Datenbank nach verweisten Einträgen durchsuchen:</b><br><br><span style="color:#990000;">Rot markierte Zeilen</span> in folgender Liste sind verweiste Einträge.<br>
  Diese werden aus der Datenbamk entfernt, <a href="'.$killUrl.'">wenn Sie hier klicken.</a><br></p>';
}

$loeschen = array();// idupl der zu löschenden Einträge in con_upl
$behalten = array();// idupl der nicht zu löschenden Einträge in con_upl

echo'<p><b>DB-Einträge in con_upl</b><br>';

//Prüfen ob Datei aus DB auf dem Server vorhanden ist
while ($row = mysql_fetch_assoc($uplArr)) {// für alle DB-Einträge in con_upl
if (is_file('upload/'.$row['dirname'].$row['filename'])){// Wenn Datei existiert
    $vh='';
    array_push($behalten, $row['idupl']);
} else {// wenn Datei nicht vorhanden
    if (isset($_GET['kill'])){
      $vh = 'style="text-decoration:line-through; color:#990000;"';
    } else {
      $vh = 'style="color:#990000;"';
    }
    array_push($loeschen, $row['idupl']);
};
// Ausgabe der Datenbankeinträge in con_upl
echo '<span '.$vh.'>'.$row['idupl'].' - '.$row['dirname'].$row['filename'].'</span><br>
';
}
echo'</p><hr>';



//Entfernen der DB-Einträge von gelöschten Dateien in con_upl
if (isset($_GET['kill']) && $_GET['kill']=='yes') {
  foreach($loeschen as $kill){
      $sql1 = "DELETE FROM `con_upl` WHERE `idupl` = " . $kill;
      mysql_query($sql1, $c) OR die (mysql_error());
  }
}

//Einlesen aller DB-Einträge in con_upl_meta
$uplmeta = "SELECT 
          idupl,
          description
        FROM 
          con_upl_meta
       ORDER BY idupl";
        
$uplmetaArr = mysql_query($uplmeta, $c) OR die (mysql_error()); 

echo'<p><b>DB-Einträge in con_upl_meta</b><br>';

$loeschenMeta = array();// zu löschende Einträge in con_upl_meta

while ($row = mysql_fetch_assoc($uplmetaArr)) {// für alle DB-Einträge in con_upl_meta
  
  foreach($behalten as $temp){//Prüfen ob Eintrag mit gleicher idupl in con_upl behalten wird
    if ($temp == $row['idupl']){ //DB-Eintrag bleibt
      $vh = '';
      break;
    } else {//DB-Eintrag wird gelöscht
      if (isset($_GET['kill'])){
        $vh = 'style="text-decoration:line-through; color:#990000;"';
      } else {
        $vh = 'style="color:#990000;"';
      }
    }
  }
  if ($vh != ''){//idupl des zu löschenden Eintrags an $loeschenMeta anfügen
    array_push($loeschenMeta, $row['idupl']);
  }
  // Ausgabe der Datenbankeinträge in con_upl_meta
  echo '<span '.$vh.'>'.$row['idupl'].' - '.urldecode($row['description']).'</span><br>
';
}
echo'</p>';

//Entfernen der DB-Einträge nicht mehr existierenden Dateien
if (isset($_GET['kill']) && $_GET['kill']=='yes') {
  foreach($loeschenMeta as $kill){
      $sql3 = "DELETE FROM `con_upl_meta` WHERE `idupl` = " . $kill;
      mysql_query($sql3, $c) OR die (mysql_error());
  }
}
?>
ACHTUNG!! Ich übernheme keine Haftung für etwaige Probleme. Unbedingt vor dem Testen ein Datenbank-Backup machen!!!
Gruß, Andras
Gesperrt