PHP Forum

PHP Forum (http://www.selfphp.de/forum/index.php)
-   PHP Entwicklung und Softwaredesign (http://www.selfphp.de/forum/forumdisplay.php?f=14)
-   -   Aufbau Repository Klasse (http://www.selfphp.de/forum/showthread.php?t=19127)

Socrates 12.04.2008 17:52:08

Aufbau Repository Klasse
 
Morgen!
Ich bin gerade dabei eine Klasse, aufbauend auf einer Klasse, die Verbindungen zu einem FTP-Server herstellt, zu schreiben. Diese Klasse soll bei der Verwaltung bzw. Installation von Packages, die auf einem anderen Server liegen, helfen. Bei den Vorüberlegungen für eine solche Klasse haben sich mir einige Fragen gestellt. Doch erst zu den bisherigen Überlegungen.

Die Klasse soll folgende Funktionen enthalten:
  • die *.csv-Datei auslesen, in der die Repository-Server stehen
  • von diesen Servern die control.csv mit den Package-Informationen auslesen
  • die Package-Informationen zerlegen und als Array zurückgeben
  • einen Download auf den eigenen Server von ungeschützten Packages ermöglichen
  • einen Download auf den eigenen Server von geschützten Packages ermöglichen
  • einen Upload von neuen Packages ermöglichen
  • in die control.csv die neuen Package-Informationen eintragen
  • einen Repository-Server in die Liste hinzufügen

Nun steht natürlich die Überlegung im Raum, ob man nicht diese Aufgaben in zwei Klassen aufteilen sollte oder nicht. Eine Klasse, die für die Übertragung der Packages zuständig ist und eine Klasse die für den Programmierer neuer Pakete den Upload und die Änderungen in den Konfigurations- und Informations-Dateien erleichtert.

Des weiteren könnte man sich überlegen, ob man nicht noch eine übergeordnete Klasse ExtendedRepository anlegt, die auf meiner TarHandler Klasse aufbaut. Diese Klasse würde dann die heruntergeladenen Packages (im *.tar-Format) in einen gleichnamigen Ordner entpacken. Das weitere Verfahren mit diesen Dateien soll nun nicht Teil meiner Überlegungen sein.

Nun zu den Problemen, die sich mir bei meinen Gedanken offenbart haben.

Es wird eine *.csv-Datei geben, die die Informationen für alle bekannten Repository-Server enthält. Sollte dies tatsächlich eine *.csv-Datei sein? Wie soll diese Datei aufgebaut sein? Was darf wie in dieser Datei stehen? Bei alledem ist zu beachten, dass es geschützte und öffentliche Repository-Server geben soll. Zudem würde ich mich nebst der Vorschläge für die Strukturierung dieser Datei auch über Hilfe für den passenden RegEx-Code freuen.

Auf jedem der Repository Server liegt nebst den Packages noch eine Datei control.csv, die die Informationen zu den einzelnen Packages enthält. Im Folgenden habe ich eine Beispiel-Datei gebastelt und würde nun gerne von euch wissen, ob die dort enthaltenen Informationen ausreichend sind und wie hier der Regex-Code aufgebaut sein müsste.

control.csv
package: nested-sets
version: 1.0.1
depends: navigation-tool, ranking-tool, article-tool
suggests: button-designer
installed-Size: 5
author: Andreas Wilhelm <andreas@mail.de>
description: package that is base for navigation-management


Das kursiv geschriebene gibt es für jedes Package. Die Informationen werden durch einen Absatz von einander sichtbar getrennt.

Die einzelnen Packages sind, wie bereits erwähnt Tarballs, die, wahrscheinlich von einer Klasse ExtendedRepository heruntergeladen und in einer gleichnamigen Ordner temporär entpackt werden. Ist dies geschehen wird eine, in diesem Ordner enthaltene, install.php aufgerufen, die alle benötigten Datenbanken erstellt, Einträge vornimmt, Rechte zuweist etc. und abschließend den Ordner und sich selbst löscht (wenn das geht).

Wo ich gerade bei den Packages bin fällt mir ein, dass ich noch nicht wirklich eine Ahnung habe, wie ich eine Datei vom einen Server auf den anderen übertragen soll, ohne diese Meldung für den Client zu erzeugen. Wie kann ich also eine Bestätigung durch den Client verhindern?

Wäre euch sehr dankbar für Ideen und Anregungen sowie Hilfe bei den verschiedenen Fragen.
MfG, Andy

|Coding 12.04.2008 18:30:09

AW: Aufbau Repository Klasse
 
Zitat:

Zitat von Socrates (Beitrag 115045)
Morgen!

Auch schon aus dem Bett gefallen? :-)

Zitat:

Zitat von Socrates (Beitrag 115045)
Wo ich gerade bei den Packages bin fällt mir ein, dass ich noch nicht wirklich eine Ahnung habe, wie ich eine Datei vom einen Server auf den anderen übertragen soll, ohne diese Meldung für den Client zu erzeugen. Wie kann ich also eine Bestätigung durch den Client verhindern?

Da könnte Dir cURL weiterhelfen.

Socrates 12.04.2008 18:45:39

AW: Aufbau Repository Klasse
 
Abend!
Zitat:

Auch schon aus dem Bett gefallen? :-)
Ich bin heute morgen um halb sechs aufgestanden und habe meine Abiklausur in deutsch geschrieben. :-P

cUrl ist irgendwie dein Allheilmittel. :-) Komm aber damit nicht wirklich zurecht. Gibt es da keine andere Möglichkeit das zu umgehen? Eine FTP-Klasse habe ich bereits erstellt! Funktioniert auch schon weitestgehend.
MfG, Andy

|Coding 12.04.2008 22:16:00

AW: Aufbau Repository Klasse
 
Zitat:

Zitat von Socrates (Beitrag 115062)
cUrl ist irgendwie dein Allheilmittel. :-)

Bietet sich halt an :-)

Ein Beispiel:

PHP-Code:

<?php
  
// Liest zip.zip von Server XY aus und speichert die
  // Daten lokal in zip.zip.

  
$ch curl_init 'http://www.domain.de/zip.zip' );

  
curl_setopt $chCURLOPT_TIMEOUT30 );
  
curl_setopt $chCURLOPT_RETURNTRANSFERTRUE );

  
// Daten auslesen.
  
$data curl_exec $ch );

  
// Daten scheiben.
  
file_put_contents './zip.zip'$data );

  
$ch_error curl_error $ch );

  
// Sind Fehler aufgetreten?
  
if ( $ch_error <> '' )
  {
    die ( 
$ch_error );
  }

  print 
'Fertsch!';
?>


Socrates 15.04.2008 20:58:56

AW: Aufbau Repository Klasse
 
Abend!
Sieht doch ganz gut aus. Vorallem das "Fertsch" am Ende gefällt mir besonders gut. :-)

Da ich heute, wie ich zu wissen glaube, erfolgreich Politik bestanden habe und so nach Deutsch die zweite, hoffentlich gute Arbeit hinter mir liegt, dachte ich mir ich könnte mir einige Zeilen Code gönnen. Deshalb habe ich ein kleines Bisschen meiner Zeit damit verbracht, einige Zeilen an meiner Repository-Klasse zu schreiben. Ist wahrscheinlich noch nicht alles so optimal, aber ich hoffe, dass ihr mir vielleicht noch etwas helfen könnt.

Zum besseren Verständnis der Klasse sei gesagt, dass die Datei, die die URLs zu den Repository-Servern enthält, nun repos.csv heißt. Sie ist wie folgt aufgebaut:

Öffentlich zugängliche Packages
Code:

repos http://www.host.de/path/to/repos/dir/ public
Kostenpflichtige Packages
Code:

repos http://www.host.de/path/to/repos/dir/ privat 234f
Wie ihr seht steht am Anfang jeder Eintagrung repos gefolgt von einer url. Das nachfolgende public oder privat bestimmt, ob ein Repository-Server gesichert ist oder nicht. Wenn privat steht, folgt ein vierstelliges Passwort.

Die Datei control.csv, die die Package Informationen enthält, sieht aus, wie oben beschrieben. Die einzelnen Info-Blöcke sind durch Leerzeilen getrennt. Die Klasse findet ihr im momentanen Zustand angehängt. Vorschläge und Anregungen sind gerne gesehen. Besondere Hilfe bedürfte ich auch noch bei der getPackInfo()-Methode. Kleine Blockade! :-(

Repository.php
PHP-Code:

<pre>

<?php  
error_reporting
(E_ALL);
    
// define server-constants
define ('REPOS'0);
define ('SERVER'1);
define ('PERM'2);
define ('PWD'3);
    
// define constants for control.csv
define ('PACK'0);
define ('VERSION'1);
define ('DEPENDS'2);
define ('SUGGESTS'3);
define ('SIZE'4);
define ('AUTHOR'5);
define ('DESCRIPTION'6);

/***
* The Repository class allows reading files that hold the repository-servers,
* reading information about different packages and
* downloading the spezific packages
*  
* @package Repository
* @version 1.0
* @author Andreas Wilhelm <Andreas2209@web.de>
* @copyright Andreas Wilhelm
**/  
class Repository
{
    
// protected class variables
    
protected $repos = array();
    protected 
$packages = array();

    
/**
    * Constructor - Is called when the class is instanced
    *
    * @access: public
    * @param Str $path
    * @return NONE
    */
    
public function __construct($path 'repos.csv')
    {    
        
// save each line of data to an array-element
        
$lines file($path);
        
        foreach(
$lines as $server)
        {
            
// split up the differnet elements of a line by delimeter " "
            
$server preg_split("/ /"$server100PREG_SPLIT_NO_EMPTY);
            
            
print_r($server);
            
            
// is it a file that contains repository-servers?
            
if( $server[REPOS] == 'repos' )
            {    
                if( 
$server[PERM] == 'public' )
                {
                    
$this->repos[$server[SERVER]] = 'NONE';
                }
                
                else if( 
$server[PERM] == 'privat' )
                {
                    
$this->repos[$server[SERVER]] = $server[PWD];
                }
                
                else
                {
                    throw new 
Exception("$path is not a valid path to repository-server.");
                }                    
            }
            
            else
            {
                throw new 
Exception("$path holds no repository-servers."); 
            }
        }
    }
    
    
/**
    * getRepos() - Returns the array of repository-servers and passwords
    *
    * @access: public
    * @return Array
    */
    
public function getRepos()
    {
        return 
$this->repos;
    }
    
    
/**
    * getPackInfo() - Gets the information about the different packages
    *
    * @access: public
    * @return Array
    */
    
public function getPackInfo()
    {
        
// get repository-servers
        
$host $this->getRepos();
        
        foreach( 
$host as $server => $pwd)
        {        
            
// path to the file that contains the package-information
            
$path 'control.csv';
            
            
// save each line of data to an array-element
            
$lines file($server.$path);
            
            
// split up the control.csv into the different information
            
$block split("\n\n"$lines);
            
            
// save information to an array with the last element as url to the package
            
foreach($block as $pack)
            {
                
// extract each line of the information-block
                
$line split("\n"$pack);
                
                
// delete description at the beginning of each line
                
preg_replace '/^package: /'' '$line[PACK]);
                
preg_replace '/^version: /'' '$line[VERSION]);
                
preg_replace '/^depends: /'' '$line[DEPENDS]);
                
preg_replace '/^suggests: /'' '$line[SUGGESTS]);
                
preg_replace '/^size: /'' '$line[SIZE]);
                
preg_replace '/^author: /'' '$line[AUTHOR]);
                
preg_replace '/^desciption: /'' '$line[DESCRIPTION]);
            
                
// save information to array
                
$this->packages[]["package"] = $line[PACK];
                
$this->packages[]["version"] = $line[VERSION];
                
$this->packages[]["depends"] = $line[DEPENDS];
                
$this->packages[]["suggests"] = $line[SUGGESTS];
                
$this->packages[]["size"] = $line[SIZE];
                
$this->packages[]["author"] = $line[AUTHOR];
                
$this->packages[]["desciption"] = $line[DESCRIPTION];
                
$this->packages[]["url"] = $server.$line[PACK];
            }
        }
        
        return 
$this->packages;
    }
    
    
/**
    * getPack() - Downloads a package to your server
    *
    * @access: public
    * @param Str $path
    * @return NONE
    */
    
public function getPack($path '')
    {
    }
}

try {
    
$repos = new Repository('repos.txt');
    
$server $repos->getRepos();
    
$packs $repos->getPackInfo();
    
    
print_r ($server);
    
print_r ($packs);    
}

catch(
Exception $e) {
    echo 
$e->getMessage();
}

?>

</pre>

Die Methode getPack() wird, wie von dir |Coding vorgeschlagen, vorraussichtlich auf cURL basieren. Nichts genaues weiß man aber noch nicht. XD
MfG, Andy

Socrates 18.04.2008 01:11:50

AW: Aufbau Repository Klasse
 
Kann mir denn keiner helfen?
Da müssen einige Denkfehler drin sein. Wenn ich das Script ausprobiere, sagt er mir zum Beispiel, dass die Datei http://www.avedo.net/repository/repos.txt nicht existiert. Das tut sie aber. Woran liegt das? Wäre einfach nett, wenn jemand mal drüber schauen könnte und so die schlimmsten Fehler aufdecken würde. Bin ein bisschen am verzweifeln.
MfG, Andy

|Coding 18.04.2008 13:40:44

AW: Aufbau Repository Klasse
 
Hi!

Hast Du "allow_url_fopen" auf "On"?


edit:
Mir wird nur mitgeteilt, dass "http://www.avedo.net/repository/publiccontrol.csv" nicht existiert. Dem ist auch so.

Ausserdem habe ich noch was zu den preg_match Funktionen zu meckern, denn Du kannst diese auch über Arrays anwenden. Beispiel:

PHP-Code:

<pre>
<?php
  $search 
= array ( '/^package: /',
                    
'/^version: /',
                    
'/^depends: /',
                    
'/^suggests: /',
                    
'/^size: /',
                    
'/^author: /',
                    
'/^desciption: /');
  
  
$replace = array ( ' '
                     
' '
                     
' '
                     
' '
                     
' '
                     
' '
                     
' ');
  
  
$source = array ( 'package' => 'package: package',
                    
'version' => 'version: version',
                    
'depends' => 'depends: depends',
                    
'suggests' => 'suggests: suggests',
                    
'size' => 'size: size',
                    
'author' => 'author: author',
                    
'desciption' => 'desciption: desciption' );
  
  
var_dump preg_replace $search$replace$source ) );
?>
</pre>



Socrates 18.04.2008 18:27:38

AW: Aufbau Repository Klasse
 
Hallo!
Das mit dem preg_match() ist ein guter Hinweis. Das werde ich bei der nächsten Überarbeitung gleich mit beachten. Der Tipp mit curl ist auch gut und wird jetzt sogar noch wichtiger. Meist Anbieter hat allow_url_fopen auf off stehen und möchte das auch nicht ändern. Das ist wohl bei vielen so und deshalb muss ich mir da eine Alternative überlegen. Da viel mir deine Empfehlung curl ein. Damit sollte das ja auch gehen. Eine Datei von einem anderen auslesen. Kennt jemand ein Tutorial für curl? Das im Manual hat mir nur bedingt geholfen.
MfG, Andy

Socrates 01.05.2008 16:59:28

AW: Aufbau Repository Klasse
 
Hallo!
Mir wurde ja ans Herzen gelegt die getPackInfo()-Methode mal zu überarbeiten. Das ist auch geschehen, doch gibt es ein kleines Problem. Und zwar habe ich eine control.txt, die wie folgt aussieht:

control.csv
Code:

Package: blubb blubb
Version: 1.0.1
Depends: blubb 1, haha 2, buhh 3
Suggests: blubb_master
Installed-Size: 5
Author: Andreas Wilhelm <andreas@mail.de>
Description: you are the master with this

Package: lollig
Version: 0.3.4
Depends: lol1, lol2
Suggests: lol_minion
Installed-Size: 14
Author: Andreas Wilhelm <andreas@mail.de>
Description: everxbody will laugh at you

Die Methode gibt also ein Array zurück. Das funktioniert auch, jedoch enthält dieses Array nur den zweiten Eintrag und nicht auch den ersten, wie es eigentlich gewünscht ist. Wo liegt mein Fehler? Bin für jede Hilfe dankbar.

MfG, Andy

PS: $path ist momentan noch konstant und die Variable $server wird nicht genutzt, das liegt daran, dass auf meinem Server, wie wohl auch auf vielen anderen, allow_url_fopen auf off steht. Daher muss ich erst die HTTP-Klasse fertigstellen, um das ändern zu können. Es geht aber momentan ja auch nur um die Ausgabe.

getPackInfo()
PHP-Code:

    /**
    * getPackInfo() - Gets the information about the different packages
    *
    * @access: public
    * @return Array
    */
    
public function getPackInfo()
    {
        
$host $this->getRepos();
    
        foreach( 
$host as $server => $pwd)
        {        
            
// path to the file that contains the package-information
            
$path 'public/control.txt';
            
            
// get content of the package-information-file
            
$file file_get_contents($path);
                        
            
// separate package-information-blocks
            
$block split("\r\n\r\n"$file);
            
            
$package = array();
            
            foreach(
$block as $key => $info)
            {            
                
// save information to an array
                
if( preg_match_all('#(.*): (.*)\n#U'$info$result) )
                {
                    
$num count($result[0]);
        
                    for(
$i=0$i<$num$i++)
                    {
                        
$name $result[1][$i];
                        
$info   $result[2][$i];
            
                        
$package[$name] = $info;
                    }
                }
            
                
$package['url'] = "$server/$path";                
            }
        }
        
        return 
$package;
    } 



Alle Zeitangaben in WEZ +2. Es ist jetzt 00:57:50 Uhr.

Powered by vBulletin® Version 3.8.3 (Deutsch)
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.