Antworten auf deine Fragen:
Neues Thema erstellen

Kann ich mit einer Schleife eine DIV-Struktur endlos duplizieren und untereinander darstellen?

  • Ja

  • Nein


Die Ergebnisse sind erst nach der Abstimmung sichtbar.

Multiticket mit DIV-Container als PDF erzeugen... Wie php-Schleife ansetzen

F

Freiheitenwelt

Guest

Hallo liebes Forum,

ich bin neu hier - Martin mein Name aus Dinkelsbühl. ;-)

Ich bin ziemlich neu in der PHP Welt und benötige für mein "kleines" Ticketprojekt ein paar Tipps die mich auf die richtige Fährte bringen. Ich stecke seit zwei Tagen etwas fest. Ich hab früher C++ programmiert und mit CSS kenn ich mich ganz gut aus... Also bin nicht ganz der Newbie...

Anforderung: Ich baue für meine Webseite www.freiheitenwelt.de gerade einen Webshop auf mit WooCommerce Ticketshop. Das System funktioniert bestens und generiert nach der Bestellung eine pdf - Din A4 - Datei als Ticket. Über ein Plugin werden die Ticketinformationen von einem HTML Code in das PDF gewandelt.

Der Anbieter von dem Ticket-Plugin bietet leider nur sehr langweilige PDF-Ticket Vorlagen und somit hab ich mich selber an die Arbeit gemacht. Dabei ist folgendes schicke Ticket entstanden, dass ich nun via PDF schicken kann oder auch auf Ticketvorlagen ausdrucken kann. ;-) RICHTIG SUPER!



Multiticket:

So wie es jetzt ist bekommt jedes Ticket eine Din-A4 Seite. Das ist sowohl zum drucken für meine Gäste als auch für mich nicht gerade optimal. Deswegen hätte ich gerne 4-Tickets auf einer Din-A4 Seite. Also 4x74mm an Höhe maximal. Bei 5 Tickets geht das ganze Spiel wieder von vorne los.

Problem:

Im Orignalcode bedient sich der Programmierer ausschließlich Tabellen die er in einer PHP-Schleife untereinander anordnet. Die nötigen Daten der Tickets gibts über eine post_get_meta... Unten hab ich den Teil des Codes für euch eingefügt.... Nach dem <?php $i = 0; ?> folgen die Tabellen.

Mein Ticket beruht auf mehreren DIV-Containern mit Längenangaben in mm. Das war für die genaue Anpassung auf das A4 Papier nötig. Über alles hab ich einen Hauptcontainer gelegt mit Position:relativ

Code:
.main_container {
    position: relative;
        border: 1px solid;
    float: left;
    width: 210mm;
    height: 74mm;
        margin-left: 0;
        margin-top: 0mm;   
}

Lösungsansatz:

Meine Idee war nun das ich über die Schleife auch immer das "margin-top" um 74mm addiere. Dann sollte sich ein jedes Ticket genau untereinander reihen. Um das zu testen hab ich den Code auf den Hauptcontainer reduziert und ich versuche das nun zu duplizieren. Ich denke wenn das funktioniert sollte der Code aus dem Single-Ticket einfach einzubinden sein.

PHP:
<?php $i = 0; ?>

            <?php foreach ($chunk as $ticket): ?>
                <div class="main_container" margin-top="X";>
            CODE AUS SINGLE TICKET
                </div>
         <?php $i++; ?>   
  <?php endforeach; ?>


Frage:

Das PHP funktioniert so nicht. Meine Frage an euch wäre nun ob das grundsätzlich funktionieren kann? Also über margin-top kann ich sicher mein ganzes Ticket verschieben. Nun ist die Frage wie ich das auf die 4 Tickets in eine Schleife bekomme. Ich denke dem Parameter X muss man wie schon geschrieben immer erhöhen und nach 4 Tickets wieder reseten. Was die Tickets angeht so gibt es da theoretisch eigentlich kein Maximum. Irgendwie muss ich da zwei Schleifen miteinander kombinieren.

Im Originalcode stehen ganz unten auch noch folgende Zeilen. Jene dienen wohl zum Wechsel der Seiten. Aber wirklich steig ich da nicht durch. Ich hoffe ich konnte mein Problem einigermaßen erklären. Bin für jeden kleinen Tipp dankbar...

PHP:
<?php $x++; ?>
<?php echo ($x < $numChunks)? '<div style="page-break-before: always;"></div>' : ''; ?>
<?php endforeach; ?>

GLG Martin




PHP:
<?php $chunkTickets = array_chunk($tickets, 3); ?>

<?php $numChunks = count($chunkTickets); ?>
<?php $x = 1; ?>
<?php foreach($chunkTickets as $chunk) : ?>
<?php $ticket = $chunk[0]; ?>
<?php

$price = get_post_meta( $ticket['WooCommerceEventsVariationID'], '_regular_price', true);

if(empty($price)) {

    $price = get_post_meta( $ticket['WooCommerceEventsVariationID'], '_sale_price', true);

}

$currencySymbol = get_woocommerce_currency_symbol();

if(!empty($price)) {

    $price = $currencySymbol.''.$price;

} else {

    $_product   = wc_get_product($ticket['WooCommerceEventsProductID']);
    $price      = $_product->get_price_html();

}
?>
<?php $i = 0; ?>
 

owieortho

Aktives Mitglied

Wenn Du weisst, wieviele Tickets auf eine Seite passen, dann musst Du immer nach dieser Zahl einen Seitenumbruch einfügen. Ich kann den Code dazu jetzt nicht schnell hinschreiben, aber es geht um die "modulo"-Funktion. Angenommen, Du hast fünf Tickets auf einer Seite, dann produziert die erste Schleife solange Tickets, die jeweils um Tickethöhe vertikal versetzt positioniert werden. Sobald modulo 5 = int ist (Division durch 5 ergibt eine ganze Zahl), dann setzt die zweite Schleife ein und fügt den Seitenumbruch ein.
Hilfreich können hierzu auch Anleitungen zur pagination sein.
HTH
O.
 
F

Freiheitenwelt

Guest

Hi

Wie geschrieben passen genau 4 Tickets auf eine Seite... Ich hab das aber eben mal ganz einfach getestet und nach zwei Containern erscheint nur ein weißes Papier... ;-( Also ist der Ansatz vielleicht doch nicht geeignet. Es hängt hier halt immer noch der PDF Generator mit drin. Und der macht wie ich feststellen konnte manchmal komische Sachen.

Das mit dem modulo werde ich mir gleich mal anlesen...

GLG


PHP:
        <div class="main_container"  >
        </div>
         <div class="main_container_2" style="margin-top:74mm;" >
         </div>
          <div class="main_container_3" style="margin-top:148mm;" >       
          </div>
          <div class="main_container_4" style="margin-top:222mm;" >     
          </div>
 

Curanai

Aktives Mitglied

Hi, naja ... ich habe schon zig on-demand PDF-Builder erstellt (für Job-Portale, Immobilienportfolios, Agenturen jeglicher Art, CRM-Systeme für Angebote, Rechnungen, Mahnungen usw.), aber mit WooCommerce und seinen eigenen Sachen ... hmmm ... da bin ich eigentlich raus.

Wenn Du nur vier Tickets auf einer Seite hast, ist folgendes denkbar:
- 1 + 2 werden von 3 + 4 überschrieben und
- die leere Seite ist bedingt durch einen (manuellen/auto) PageBreak

Auslöser für das Überlagern könnte eine nicht korrekt platzierte Position sein, welche Du als grundsätzlich voraussetzt. Wenn Du TCPDF kennst, kennst Du MultiCell. Wenn Du MultiCell kennst, weißt Du um das Problem, welches ich gerade anspreche (da musst Du Dir manuell "merken", wo Du gerade auf der aktuellen Seite bist). Hier wären setX() und setY() Deine gewissenhaften Freunde.

Lösungsannäherung: Verwirf das Modell mit dem DIV und klebe testweise mal Deine Tickets in ein altmodisches Table-Modell - ein TR je Ticket. Wenn ich mich richtig erinnere, macht so ein HTML2PDF Renderer eigentlich nix anderes, als möglichst alten Quellcode darzustellen; je neuer der ist, umso ätzender das Ergebnis (vgl. HTML-E-Mails).

Ich habe keine guten Erfahrungen mit komplexen PDF-Strukturen gemacht, die "per Knopfdruck" gut aussehen. Dinge wie "HTML2PDF" gingen bei mir nie gut aus - darum eben manuell erstellt (aber dafür eben millimetergenau).

Aber eine Hilfe konkrekt kann ich Dir hier nicht sein - sorry dafür.
 
F

Freiheitenwelt

Guest

Hallo miteinander und Danke Curanai für die Inspiration.

Ich bin im ersten Schritt nun einmal hergegangen und hab meinen Code für das Einzelticket aufgeräumt. Im Eingangspost ist ja das Ticket zu sehen. Es besteht aus einem Maincontainer mit dem Attribut "Position: fixed;". Innerhalb davon befinden sich dann acht weitere Container für die verschiedenen Informationen wie Logo, Bild, Titel etc... Innerhalb des Maincontainers sind alle DIV's mit "Position:absolute;" eingebunden.

So ... ;-) Das funktioniert alles bestens und ich habe nun zum Test einmal vier Maincontainer untereinander in eine Seite eingefügt. Mit den Absolut Attributen verschiebt sich nun nichts mehr. Der einzige Wert der sich ändert ist. ->>> CSS top: XX; <<<-

Und das jeweils um 74mm.

Wegen des PDF Exports und dem Druck hinterher ist es wesentlich einfacher direkt mit Millimeter Angaben zu arbeiten.
Hier einmal ein Screenshot wie das bis jetzt aussieht.

Nun müsste ich eben die Schleifen so Programmieren, dass jeweils für die Anzahl der bestellten Tickets XX um 74mm erhöht wird bis maximal 4 (mehr geht ja nicht drauf) - dann müsste der Pagebreak kommen und das Ganze von vorne los gehen...

Wie muss ich das aufsetzten? Jemand einen Tipp in die richtige Richtung?
 

Curanai

Aktives Mitglied

Guten Morgen,

hast Du Dir Dein Wireframe mal ausgedruckt - oder sieht das nur im Browser gut aus? Ich warne dann vor zu früher Euphorie.

Wie oben vorgeschlagen könntest Du Deinen Drittanbieter mal auf ein setY() befragen - entweder einfach probieren (da die Basis gern gleich ist) oder der in entsprechenden Manuals dazu nachschauen. Jetzt hab ich aus versehen gelesen, dass HTML2PDF eine IE Engine nutzt, um ein PDF zu rendern ... oh je, oh je. Aber zum Glück war das Posting schon alt genug. ^^

Steht Dir "node" zur Verfügung? Dann wäre der hier vielleicht noch in Verbindung mit Chromium zügiger:
chrome --headless --print-to-pdf="pfad/zum/pdf" https://deine_url_mit_tickets - da kann ich Dir aber nicht sagen, ob es geht, allerdings soll das Ergebnis sehr dicht am regulären Web-Development sein (also wie man es dann auch erwartet).

Und da wären wir dann wieder beim manuellen Weg. Ich erwarte aufgrund Deiner Angaben eigentlich Schwierigkeiten - bedingt durch "position: absolute" sowie ": fixed". Du könntest ja mal in Deinen WooCommerce schauen, welche Library die PDFs macht - vielleicht ließe sich dann konkreter helfen.

Ich wünsche einen erfolgreichen Tag.
 
F

Freiheitenwelt

Guest

Guten Morgen Curanai,

also ich bin da schon ein gutes Stück weiter als du denken magst. ;-)

Ich hab das gleich (etwas umständlich) LIVE auf meiner Homepage geschrieben. Ja - die Tickets werden einwandfrei gedruckt. Einige liegen hier vor mir auf dem Tisch auf perforiertem Papier gedruckt. Mein Ziel war es meinen Kunden sowohl die "Online-Tickets" (Also die welche nicht gedruckt werden) im PDF zu schicken (funktioniert). Auf der anderen Seite wollte ich aber auch die Möglichkeit haben Tickets für die Vorverkaufsstellen selber drucken zu können und das jene auch mit Barcode etc. im Ticketsystem integriert sind. (funktioniert) Fummelig war es mit den DIV Containern zu Beginn. Mit Tabellen hatte ich überhaupt keine Chance die acht verschiedenen Blöcke richtig anzuordnen. Erst alls ich die Positions definiert hatte gab es keine Probleme mehr. Ich sehe da gerade keine Probleme. Wie gesagt ist das rendern des PDF's für mich eigentlich schon abgeschlossen. Das Ticketplugin benutzt hierfür dompdf. Nun geht es darum wie ich eben vier Tickets auf eine DIN-A4 Seite bekomme.





Hier einmal die einfache DIV-Struktur die ich für ein Einzelticket verwende. Bei dem PDF oben hatte ich wie geschrieben jenen Code einfach 4-mal eingefügt und jeweils das "TOP" Attribut in der jeweiligen CSS-Klasse um 74mm angepasst.

PHP:
<div class="main_containerXX">

<div id="div_header">
<table>
   //Informationen TEXT im Header Ticket...
</table>
</div>

<div id="div_image">
    //Hintergrundbild wird aus WooCommerce geladen...
</div>

<div id="div_logo">
    //Logo wird aus Eventmanager geladen...
</div>

<div id="div_titel" align="center">
    //Titel der Veranstaltung
</div>

<div id="div_info1">
<table width="100%">
    // Informationen (Datum, Uhrzeit, Adresse etc) werden aus Eventmanager ausgelesen und in die Tabelle eingeschrieben. 
</table>
</div>
 
<div id="div_barcode">
    // Barcode wird aus Eventmanager eingebunden
</div>

<div id="div_ticketcode_left">
    // Ticketnummer auf Hauptticket
</div>

<div id="div_ticketcode_right">
   // Ticketnummer auf Ticketabriss
</div>
</div>
 
F

Freiheitenwelt

Guest

Gut -

Und hier ein Auszug aus dem Standardtemplate des Ticketplugins... Die Tabellenstruktur war hier viel einfacher und natürlich nicht so auf den mm genau angeordnet. Sieht aber sehr übersichtlich aus der Code und da dompf ja keine Probleme mit CSS und php hat denke ich sollte es bei mir doch auch funktionieren.

Wo ich im Moment nicht zurecht komme ist wie ich die Variablen für die vier möglichen Maincontainer und "Top:X" hier einbinde. Also mir fehlt schlichtweg die Idee wie ich die Schleifen hier aufstellen soll?!? Ändern tun sich auch eigentlich nur der Barcode und die Ticketnummer.

PHP:
<?php $chunkTickets = array_chunk($tickets, 3); ?>

<?php $numChunks = count($chunkTickets); ?>
<?php $x = 1; ?>
<?php foreach($chunkTickets as $chunk) : ?>
<?php $ticket = $chunk[0]; ?>
<?php $i = 0; ?>

//Wenn ich es richtig verstehe wird mit diesem Code abgerufen wie viele Tickets zur Verfügung stehen und die Daten in einen Array (Chunk) gespeichert - richtig? 

//Was nun folgt sind die Tabellen in denen die Daten nacheinander geschrieben werden. Die erste Tabelle wird mit den Grundinfos hier nur einmal geschrieben. Das fällt bei mir weg da ich das auf jedem Ticket haben will. 

//Die Zweite Tabellen Struktur wird mit "foreach etc." so oft durchlaufen wie es Tickets gibt. An dem Punkt will ich ansetzen. Eben dann nur das bei jedem neuen Durchlauf der "Maincontainer" um die X=i*74mm verschoben wird. Nach 4 Tickets wird i wieder 0 und fängt eine neue Seite an. 

//Also was mir unklar ist sind jene Anweisungen <?php foreach ($chunk as $ticket): ?> z.B. 


<table width="100%">
    <tr>
        <td>           
            <h1><?php echo $ticket['name'] ?></h1>
            <p>
                <?php if(!empty($ticket['WooCommerceEventsDate'])) : ?>
                    <strong><?php _e('Date:','fooevents-pdf-tickets') ?></strong> <?php echo $ticket['WooCommerceEventsDate']; ?><br />
                <?php endif; ?>
            //usw.  .........
            .........
            ...........

            <?php endif; ?> 
            Page <?php echo $x; ?> of <?php echo $numChunks; ?>
        </td>
    </tr>
</table> 



<table width="100%" class="tickets" cellpadding="0" cellmargin="0">
    <?php foreach ($chunk as $ticket): ?>
            <tr>
                <td valign="top">
                    <?php if(!empty($ticket['WooCommerceEventsTicketLogoPath'])) :?>
                        <img src="<?php echo $ticket['WooCommerceEventsTicketLogoPath']; ?>" alt="" width="150px"/><br />
                    <?php endif; ?>
                </td>
                <td valign="top" class="ticketinfo">
                    <h3><?php echo $ticket['name'] ?></h3>
                    <?php if(!empty($ticket['WooCommerceEventsDate'])) : ?>
                        <strong><?php _e('Date:','fooevents-pdf-tickets') ?></strong> <?php echo $ticket['WooCommerceEventsDate']; ?><br />
                    <?php endif; ?>
                    <?php if(!empty($ticket['WooCommerceEventsHour'])) : ?>
                        <strong><?php _e('Time:','fooevents-pdf-tickets') ?></strong> <?php echo $ticket['WooCommerceEventsHour']; ?>:<?php echo $ticket['WooCommerceEventsMinutes']; ?><?php echo (!empty($ticket['WooCommerceEventsPeriod']))? $ticket['WooCommerceEventsPeriod'] : '' ?>
                        <?php if($ticket['WooCommerceEventsHourEnd'] != '00') : ?>
                            - <?php echo $ticket['WooCommerceEventsHourEnd']; ?>:<?php echo $ticket['WooCommerceEventsMinutesEnd']; ?><?php echo (!empty($ticket['WooCommerceEventsEndPeriod']))? $ticket['WooCommerceEventsEndPeriod'] : '' ?>
                            <br />
                        <?php endif; ?>
                    <?php endif; ?>
                    <?php if(!empty($ticket['WooCommerceEventsLocation'])) :?>
                        <strong><?php _e('Location:','fooevents-pdf-tickets') ?></strong> <?php echo $ticket['WooCommerceEventsLocation'] ?><br />
                    <?php endif; ?>
                    <strong><br /><?php _e('Ticket Number:','fooevents-pdf-tickets') ?></strong> <?php echo $ticket['WooCommerceEventsTicketID']; ?><br />
                    <strong><?php _e('Ticket Holder:','fooevents-pdf-tickets') ?></strong> <?php echo $ticket['customerFirstName']; ?> <?php echo $ticket['customerLastName']; ?><br />           
                   
                    <?php if(!empty($ticket['WooCommerceEventsAttendeeTelephone'])) :?>
                    <strong><?php _e('Telephone Number:','fooevents-pdf-tickets') ?></strong> <?php echo $ticket['WooCommerceEventsAttendeeTelephone']; ?><br />
                    <?php endif; ?>

                    <?php if(!empty($ticket['WooCommerceEventsAttendeeCompany'])) :?>
                    <strong><?php _e('Company:','fooevents-pdf-tickets') ?></strong> <?php echo $ticket['WooCommerceEventsAttendeeCompany']; ?><br />
                    <?php endif; ?>

                    <?php if(!empty($ticket['WooCommerceEventsAttendeeDesignation'])) :?>
                    <strong><?php _e('Designation:','fooevents-pdf-tickets') ?></strong> <?php echo $ticket['WooCommerceEventsAttendeeDesignation']; ?><br />
                    <?php endif; ?>

                    <?php if(!empty($ticket['WooCommerceEventsVariations'])) :?>
               
                        <?php foreach($ticket['WooCommerceEventsVariations'] as $variationName => $variationValue) :?>
                            <?php
                            $variationNameOutput = str_replace('attribute_', '', $variationName);
                            $variationNameOutput = str_replace('pa_', '', $variationNameOutput);
                            $variationNameOutput = str_replace('_', ' ', $variationNameOutput);
                            $variationNameOutput = str_replace('-', ' ', $variationNameOutput);
                            $variationNameOutput = str_replace('Pa_', '', $variationNameOutput);
                            $variationNameOutput = ucwords($variationNameOutput);

                            $variationValueOutput = str_replace('_', ' ', $variationValue);
                            $variationValueOutput = str_replace('-', ' ', $variationValueOutput);
                            $variationValueOutput = ucwords($variationValueOutput);
                            ?>
                            <?php echo '<strong>'.$variationNameOutput.':</strong> '.$variationValueOutput.'<br />'; ?>
                        <?php endforeach; ?>
               
                    <?php endif; ?>
                   
                    <?php if(!empty($ticket['fooevents_custom_attendee_fields_options'])) :?>
                        <?php echo $ticket['fooevents_custom_attendee_fields_options']; ?>
                    <?php endif; ?>
                   
                    <?php if($ticket['WooCommerceEventsTicketDisplayPrice'] != 'off') :?>
                        <?php echo $ticket['WooCommerceEventsPrice']; ?><br />
                    <?php endif; ?>
                </td>
                <td align="right" valign="top" class='stub'>
                    <img src="<?php echo $eventPluginURL; ?><?php echo $ticket['barcodeFileName']; ?>.jpg" alt="Barcode: <?php echo $ticket['WooCommerceEventsTicketID']; ?>" width="140px" /><br />
                    <small><?php echo $ticket['WooCommerceEventsTicketID']; ?></small>
                </td>
            </tr>
        <?php $i++; ?>   
    <?php endforeach; ?>
    </tr>
</table>
<table width="100%">
    <?php if(!empty($ticket['FooEventsTicketFooterText'])) :?>
    <tr>
        <td colspan="2" class="footer">
            <small><?php echo $ticket['FooEventsTicketFooterText'];?></small>
        </td>
    </tr>
    <?php endif; ?>
</table>
<?php $x++; ?>
<?php echo ($x < $numChunks)? '<div style="page-break-before: always;"></div>' : ''; ?>
<?php endforeach; ?>
 
F

Freiheitenwelt

Guest

Ich hab es hinbekommen!

TOTAL COOL!


Der Knackpunkt war über die DIV noch eine Tabelle mit 100% zu legen.

Die Daten für die Tickets wurden ganz einfach übernommen. Der Seitenwechsel war auch noch etwas trickreich - aber nun bin ich super glücklich.

GLG
 
Bilder bitte hier hochladen und danach über das Bild-Icon (Direktlink vorher kopieren) platzieren.
Antworten auf deine Fragen:
Neues Thema erstellen

Willkommen auf PSD-Tutorials.de

In unseren Foren vernetzt du dich mit anderen Personen, um dich rund um die Themen Fotografie, Grafik, Gestaltung, Bildbearbeitung und 3D auszutauschen. Außerdem schalten wir für dich regelmäßig kostenlose Inhalte frei. Liebe Grüße senden dir die PSD-Gründer Stefan und Matthias Petri aus Waren an der Müritz. Hier erfährst du mehr über uns.

Stefan und Matthias Petri von PSD-Tutorials.de

Nächster neuer Gratisinhalt

03
Stunden
:
:
25
Minuten
:
:
19
Sekunden

Flatrate für Tutorials, Assets, Vorlagen

Statistik des Forums

Themen
118.611
Beiträge
1.538.342
Mitglieder
67.524
Neuestes Mitglied
BSKGA
Oben