YourWBB


yourWBB » yourWBB Misc * » Das Proggen » MySQL und PHP » Ersetzen von mehreren ähnlichen Stellen » Hallo Gast [Anmelden|Registrieren]
Letzter Beitrag | Erster ungelesener Beitrag 2.951 Views | | Thema zu Favoriten hinzufügen

Neues Thema erstellen Antwort erstellen

Zum Ende der Seite springen Ersetzen von mehreren ähnlichen Stellen
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
Agi Agi ist männlich
TEAM - PHP Freak

images/avatars/avatar-5240.gif

Dabei seit: 22.11.04
Beiträge: 2.628
Fähigkeiten: WBB3 Profi
Forenversion: 3.1

 Ersetzen von mehreren ähnlichen Stellen Antworten Zitieren Editieren Melden       UP

Hi Leute,
ich habe ein Problem und brauche da ein wenig Hilfe.

Ich habe ein kleines Forum, das sich mit Emulation beschäftigt. Wir möchten aber in naher Zukunft mit einem anderen Forum (das phpBB3 einsetzt) fusionieren.

Die Fusion wird auf Basis von WBB3 stattfinden (weil da der importer schon dabei ist). Allerdings haben wir noch ein paar Extrawünsche, für die der Importer erweitert werden muss.
Bis auf einen haben wir eigentlich alles hinbekommen; aber genau bei diesem Letzten weiß ich überhaupt nicht mehr weiter ...

---
Vorneweg ein paar Abkürzungsdefinitionen, damit ich nicht immer alles ausschreiben muss:

(NR) = Die Nummer des Anhangs in diesem Beitrag (ohne die Klammern rundherum; muss sie nur machen, damit ihr die Abgrenzung merkt)
ID = Die Attachment-ID
UID = Ein spezieller Code, der in phpBB3 verwendet wird (kann man abfragen, der ist also auch vorhanden bzw. bekannt).

---
Das eigentliche Problem:
Im phpBB3 werden Dateianhänge in einem Beitrag so eingetragen:

[attachment=NR:UID]<!-- ia(NR) -->Name.jpg<!-- ia(NR)-->[/attachment:UID]

Damit es im WBB funktioniert, muss das aber geändert werden.
Daher soll das Script

1) Den Namen "Name.jpg" aus diesem String heraustrennen
2) Eine SQL Abfrage starten und die ID abfragen, wo der echte Name "Name.jpg" ist (in der phpBB3 DB)
3) Das ganze [attachment=NR:UID]usw soll durch [attach]ID[/attach] ersetzt werden.

Ich habe es nach langem Hin und Her so hinbekommen, dass das erste Element erfolgreich ersetzt wird; allerdings bleiben alle weiteren Elemente unangetastet.

Und ich wollte nun wissen, was geändert werden muss, damit er diesen Vorgang bei allen [attachment=NR:UID]Name.jpg[/attachment:UID] durchführt.

Ich poste euch auch mal meinen Code (ist leider nicht perfekt, aber ich war auch schon ziemlich müde, da ich über 8h lang probiert habe und da hab ich dann nicht mehr auf Perfektion geachtet - das würde ich noch nachholen, wenn der fertige Code steht):

php:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
<?php
error_reporting(E_ALL);
$ver mysql_connect('localhost','root','') or die ("Fehler!");
mysql_select_db('db_phpbb3'$ver) or die ("Fehler 2!");

$result mysql_query("SELECT post_text, bbcode_uid FROM phpbb3_posts WHERE post_id = 41645"$ver);
while ($row mysql_fetch_array($result)) {
  $text $row['post_text'];
  $uid $row['bbcode_uid'];
}
preg_match_all("/\[attachment=(.+?):".$uid."\]/i"$text$treffer);
$zahl count($treffer[1]);
for ($i 1$i $zahl$i++) {
  $i2 $i-1;

  $text str_replace('[attachment='.$i.':'.$uid.']''[attach]'$text);
  $text str_replace('[attachment='.$i2.':'.$uid.']''[attach]'$text);
  $text str_replace('<!-- ia'.$i.' -->'''$text);
  $text str_replace('<!-- ia'.$i2.' -->'''$text);
}
$text str_replace('[/attachment:'.$uid.']''[/attach]'$text);

preg_match_all("/\[attach\].+?\[\/attach\]/i"$text$treffer2);

$Name explode('[attach]'$text);
$Name2 explode('[/attach]'$Name[1]);
$FileName $Name2[0];

$sql "SELECT        attach_id
FROM        phpbb3_attachments
WHERE real_filename = '".mysql_real_escape_string($FileName)."'";

$result mysql_query($sql$ver) OR die(mysql_error());

while ($row mysql_fetch_array($result)) {
  $id $row['attach_id'];
}
$text str_replace($FileName$id$text);


echo $text.'<br><br>';
mysql_close($ver);
?>
Das ergibt dann zum Beispiel:

Zitat:
Hm, aber die Diskusion macht dich Spaß xD STimmt eigentlich... [attach]135300[/attach] Test [attach]vogel_03.jpg[/attach] Test2 ^^


Ich würde mich sehr freuen, wenn ihr mir helfen könntet, da dieser Teil sehr wichtig für uns ist und ich wie gesagt mit meinem Latein am Ende bin.

__________________

21.04.09 00:55 Agi ist offline Finden Als Freund hinzufügen
Hawkes
gesperrt 10/01/10


Dabei seit: 31.03.04
Beiträge: 213

Antworten Zitieren Editieren Melden       UP

Das solltest du wenn du schon im WBB3 arbeitest mit einer WorkerAction machen. Da attachments erst nach den posts importiert werden kann man leider das Ganze nicht schon beim Import erledigen. Man könnte sich zwar per EL reinhängen, aber ich hab gerade keine Lust alle Konsequenzen abzuschätzen großes Grinsen

Hier mal ein Blindansatz als UpdateCounter Action (musst sie noch per EL dem WBB bekannt machen).

php:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:

<?php
require_once(WBB_DIR.'lib/acp/action/UpdateCounterAction.class.php');
require_once(WCF_DIR.'lib/data/message/attachment/Attachments.class.php');

class UpdatePHPBB3AttachmentsAction extends UpdateCounterAction {
    public $action 'UpdatePHPBB3Attachments';
    
    /**
     * @see Action::execute()
     */
    public function execute() {
        parent::execute();
        
        // count posts
        $sql "SELECT    COUNT(*) AS count
            FROM    wbb".WBB_N."_post
            WHERE attachments > 0";
        $row WCF::getDB()->getFirstRow($sql);
        $count $row['count'];
        
        // get postids
        $postIDs '';
        $sql "SELECT        postID
            FROM        wbb".WBB_N."_post
            ORDER BY    postID";
        $result WCF::getDB()->sendQuery($sql$this->limit, ($this->limit $this->loop));
        while ($row WCF::getDB()->fetchArray($result)) {
            $postIDs .= ','.$row['postID'];
        }
        
        if (empty($postIDs)) {
            $this->calcProgress();
            $this->finish();
        }
        // get attachments
        $attachments = new Attachments($postIDs);
        
        // get post messages
        $sql "SELECT postID, message    wbb".WBB_N."_post 
            WHERE    post.postID IN (0".$postIDs.")";
        $result WCF::getDB()->sendQuery($sql);
        while ($row WCF::getDB()->fetchArray($result)) {
            $postAttachments $attachments->getAttachments($row['postID']);
            if (!count($postAttachments)) continue;
            $message $row['message'];            
            preg_match_all('/\[attachment=\d*:\d*\]<!--.*?-->(.*)<!--.*/is'$message$matchesPREG_SET_ORDER);
            foreach ($matches as $match) {                
                $filename $match[1];
                foreach ($postAttachments as $postAttachment) {
                    if ($postAttachment['attachmentName'] == $filename) {
                        preg_replace('/\[attachment.*\].*?('.$filename.').*?\[\/attachment.*\]/is''[attach]'.$postAttachment['attachmentID'].'[/attach]'$message);
                        continue 2;
                    }
                }                
            }
            
            $sql "UPDATE wbb".WBB_N."_post
                        SET message = '".escapeString($message)."'
                        WHERE postID = ".$row['postID'];
            WCF::getDB()->sendQuery($sql);
            
            // clear post cache
            $sql "DELETE FROM wbb".WBB_N."_post_cache
                        WHERE postID = ".$row['postID'];
            WCF::getDB()->sendQuery($sql);
        }
        
        $this->executed();
        
        $this->calcProgress(($this->limit $this->loop), $count);
        $this->nextLoop();
    }
}
?>

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Hawkes: 21.04.09 10:10.

21.04.09 10:06 Hawkes ist offline Finden Als Freund hinzufügen
Agi Agi ist männlich
TEAM - PHP Freak

images/avatars/avatar-5240.gif

Dabei seit: 22.11.04
Beiträge: 2.628
Fähigkeiten: WBB3 Profi
Forenversion: 3.1

Themenstarter Thema begonnen von Agi
Antworten Zitieren Editieren Melden       UP

Hi, vielen Dank für deie Mühen. Sry dass ich erst jetzt antworte, war die letzte Zeit beschäftigt.

Ich habs eingebunden und auch ein klein wenig ändern müssen, weil sonst ein SQL Fehler kam (entweder beim Auslesen der Attachments oder beim Auslesen der Posts).

Nun läuft das Script durch, allerdings gibt es 2 Probleme:

1. Problem: Die Prozentanzeige wird astronomisch hoch (läuft aber durch, bis fertig ist). Nach Abschluss hat er soviel Prozent: 111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111
111111112222222222222222222222222222222222222222222222222222222222222222222
222222222222222222222222222222222222222222222222222222222222222222222222222
222222222222222333333333333333333333333333333333333333333333333333333333333
333333333333333333333333333333333333333333333333333333333333333333333333333
333333333333333333333334444444444444444444444444444444444444444444444444444
444444444444444444444444444444444444444444444444444444444444444444444444444
444444444444444444444444100%


2. Problem: Das Script aktualisiert leider nicht alles. Wenn jetzt nur ein Attachment im Post ist, wird es problemlos umgewandelt.
Wenn aber mehrere Anhänge im Beitrag eingebunden wurden, lässt er diese unverändert.


---
Hier nochmal die Version vom Script die ich benutze:

php:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
<?php
require_once(WBB_DIR.'lib/acp/action/UpdateCounterAction.class.php');
require_once(WCF_DIR.'lib/data/message/attachment/Attachments.class.php');

class UpdatePhpbb3attachmentsAction extends UpdateCounterAction {
    public $action 'UpdatePhpbb3attachments';
    
    /**
     * @see Action::execute()
     */
    public function execute() {
        parent::execute();
        
        // count posts
        $sql "SELECT    COUNT(*) AS count
            FROM    wbb".WBB_N."_post
            WHERE attachments > 0";
        $row WCF::getDB()->getFirstRow($sql);
        $count $row['count'];
        
        // get postids
        $postIDs 0;
        $sql "SELECT        postID
            FROM        wbb".WBB_N."_post
            ORDER BY    postID";
        $result WCF::getDB()->sendQuery($sql$this->limit, ($this->limit $this->loop));
        while ($row WCF::getDB()->fetchArray($result)) {
            $postIDsAttach .= ','.$row['postID'];
            $postIDs .= ','.$row['postID'];
        }
        
        if (empty($postIDs)) {
            $this->calcProgress();
            $this->finish();
        }
        // get attachments
        $attachments = new Attachments($postIDs);
        
        // get post messages
        $sql "SELECT postID, message  
            FROM    wbb".WBB_N."_post 
            WHERE    postID IN (".$postIDs.")";
        $result WCF::getDB()->sendQuery($sql);
        while ($row WCF::getDB()->fetchArray($result)) {
            $postAttachments $attachments->getAttachments($row['postID']);
            if (!count($postAttachments)) continue;
            $message $row['message'];            
            preg_match_all('/\[attachment=\d*\]<!--.*?-->(.*)<!--.*/is'$message$matchesPREG_SET_ORDER);
            foreach ($matches as $match) {                
                $filename $match[1];
                foreach ($postAttachments as $postAttachment) {
                    if ($postAttachment['attachmentName'] == $filename) {
                        $message preg_replace('/\[attachment.*\].*?('.$filename.').*?\[\/attachment.*\]/is''[attach]'.$postAttachment['attachmentID'].'[/attach]'$message);
                        continue 2;
                    }
                }                
            }
            
            $sql "UPDATE wbb".WBB_N."_post
                        SET message = '".escapeString($message)."'
                        WHERE postID = ".$row['postID'];
            WCF::getDB()->sendQuery($sql);
            
            // clear post cache
            $sql "DELETE FROM wbb".WBB_N."_post_cache
                        WHERE postID = ".$row['postID'];
            WCF::getDB()->sendQuery($sql);
        }
        
        $this->executed();
        
        $this->calcProgress(($this->limit $this->loop), $count);
        $this->nextLoop();
    }
}
?>


__________________

22.04.09 23:20 Agi ist offline Finden Als Freund hinzufügen
Hawkes
gesperrt 10/01/10


Dabei seit: 31.03.04
Beiträge: 213

Antworten Zitieren Editieren Melden       UP

Teste mal das RegEx aus dem preg_match_all auf so einen post, wie viele Indizes dort das array hat. $matches sollte eigentlich soviele subarrays wie attachments in einem post haben und mit continue 2 sollte ich ja nur die beiden forschleifen um 1 weiter laufen lassen.

Zu der astronomischen Zahl: Was für ein limit hast du denn gesetzt? Irgendwie berechnet er den Prozess falsch.

Das Script hab ich wie gesagt blind geschrieben, ohne auch nur irgendwas zu testen. Bin froh, dass da jetzt überhaupt was geht großes Grinsen

PS: Wenn du das fertig hast, könntest du es vielleicht als Plugin veröffentlichen. Denke da hätten eventuell manche Interesse dran.
22.04.09 23:29 Hawkes ist offline Finden Als Freund hinzufügen
Agi Agi ist männlich
TEAM - PHP Freak

images/avatars/avatar-5240.gif

Dabei seit: 22.11.04
Beiträge: 2.628
Fähigkeiten: WBB3 Profi
Forenversion: 3.1

Themenstarter Thema begonnen von Agi
Antworten Zitieren Editieren Melden       UP

Zitat:
Teste mal das RegEx aus dem preg_match_all auf so einen post, wie viele Indizes dort das array hat. $matches sollte eigentlich soviele subarrays wie attachments in einem post haben und mit continue 2 sollte ich ja nur die beiden forschleifen um 1 weiter laufen lassen.


Hmm, $matches ist leer. Es ändert sich auch nichts, wenn ich das RegEx aus preg_match_all einsetze.
Ersetzt wird anscheinend nur, wenn sich nur ein Attachment im Beitrag befindet (all diese sind korrekt ersetzt). Wenn mehr als eines drinnen ist, wird es ignoriert.

Limit hab ich 50 eingestellt. Allerdings ändert sich auch nichts, wenn ich 100 oder 500 einstelle; nur halt, dass die astronomische Zahl schneller erreicht wird.


Zitat:
PS: Wenn du das fertig hast, könntest du es vielleicht als Plugin veröffentlichen. Denke da hätten eventuell manche Interesse dran.


Werd ich mir überlegen. Sofern wir es so hinbekommen, dass es auch korrekt funktioniert. ^^ Evtl. zusammen mit ein paar anderen Erweiterungen/Updates für den PHPBB3 Importer (da dort noch ein paar Fehler drinnen waren, die ich ausgebügelt habe).
Naja, mal sehen.


//Edit:

Mit folgendem Script ersetzt er jetzt auch, wenn mehr als 1 Attachment im Beitrag ist. Allerdings ersetzt er scheinbar nur das Erste und alle Anderen verschwinden einfach gänzlich. ^^"

php:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
<?php
require_once(WBB_DIR.'lib/acp/action/UpdateCounterAction.class.php');
require_once(WCF_DIR.'lib/data/message/attachment/Attachments.class.php');

class UpdatePhpbb3attachmentsAction extends UpdateCounterAction {
    public $action 'UpdatePhpbb3attachments';
    
    /**
     * @see Action::execute()
     */
    public function execute() {
        parent::execute();
        
        // count posts
        $sql "SELECT    COUNT(*) AS count
            FROM    wbb".WBB_N."_post
            WHERE attachments > 0";
        $row WCF::getDB()->getFirstRow($sql);
        $count $row['count'];
        
        // get postids
        $postIDs '';
        $postIDsAttach 0;
        $sql "SELECT        postID
            FROM        wbb".WBB_N."_post
            ORDER BY    postID";
        $result WCF::getDB()->sendQuery($sql$this->limit, ($this->limit $this->loop));
        while ($row WCF::getDB()->fetchArray($result)) {
            $postIDsAttach .= ','.$row['postID'];
            $postIDs .= ','.$row['postID'];
        }
        
        if (empty($postIDs)) {
            $this->calcProgress();
            $this->finish();
        }
        
        // get attachments
        $attachments = new Attachments($postIDsAttach);
        
        // get post messages
        $sql "SELECT postID, message  
            FROM    wbb".WBB_N."_post 
            WHERE    postID IN (0".$postIDs.")";
        $result WCF::getDB()->sendQuery($sql);
        while ($row WCF::getDB()->fetchArray($result)) {
            $postAttachments $attachments->getAttachments($row['postID']);
            if (!count($postAttachments)) continue;
            $message $row['message'];
         
            preg_match_all('/\[attachment=.*\]<!-- ia.*? -->(.*)<!-- ia.*?/is'$message$matchesPREG_SET_ORDER);
            foreach ($matches as $match) {                
                $filename $match[1];
                foreach ($postAttachments as $postAttachment) {
                    
                    if ($postAttachment['attachmentName'] == $filename) {
                        $message preg_replace('/\[attachment=.*\]<!-- ia.*? -->(.*)<!-- ia.*? -->\[\/attachment\]/is''[attach]'.$postAttachment['attachmentID'].'[/attach]'$message);
                        
                        continue 2;
                    }
                }                
            }
            
            $sql "UPDATE wbb".WBB_N."_post
                        SET message = '".escapeString($message)."'
                        WHERE postID = ".$row['postID'];
            WCF::getDB()->sendQuery($sql);
            
            // clear post cache
            $sql "DELETE FROM wbb".WBB_N."_post_cache
                        WHERE postID = ".$row['postID'];
            WCF::getDB()->sendQuery($sql);
        }
        
        $this->executed();
        
        $this->calcProgress(($this->limit $this->loop), $count);
        $this->nextLoop();
    }
}
?>


__________________

23.04.09 15:59 Agi ist offline Finden Als Freund hinzufügen
Baumstruktur | Brettstruktur
Gehe zu:

Neues Thema erstellen Antwort erstellen

yourWBB » yourWBB Misc * » Das Proggen » MySQL und PHP » Ersetzen von mehreren ähnlichen Stellen