Ergebnis 1 bis 9 von 9

Thema: mySQL-UPDATE täglich mit CRON

  1. #1
    Contao-Nutzer Avatar von wsa
    Registriert seit
    27.10.2009.
    Ort
    Augsburg
    Beiträge
    128

    Frage mySQL-UPDATE täglich mit CRON

    Hallo zusammen,

    habe folgende Aufgabenstellung:

    Ich möchte Datensätze in einer tl_Tabelle nach Erreichen einer Ablauffrist (z.B. 3 Monate nach Erstellungsdatum) automatisch via mySQL-UPDATE-Befehl "markieren".
    Diesen Befehl kann ich bereits erfolgreich in phpMyAdmin absetzen.

    Nun würde ich denselben gerne einmal täglich per CRON ausführen lassen.
    Da ich kein gelernter Programmierer bin, würde mir ein Muster-php-Script hierfür sehr helfen, denn ich weiß nicht, welche Klassen dem CRON zur Verfügung stehen. (Muss ich den Datenbank-Zugriff komplett in php schreiben. Das hab ich schon mal gemacht, würde das aber - sofern möglich - gerne eleganter mit Contao-"Werkzeugen" machen.)

    Wer kann weiterhelfen?
    Vielen Dank im Voraus und GLG
    wsa

  2. #2
    Contao-Urgestein Avatar von the_scrat
    Registriert seit
    24.02.2010.
    Ort
    Augsburg
    Beiträge
    2.051
    User beschenken
    Wunschliste

    Standard

    Hi wsa,

    hier eine kurze Schritt-für-Schritt Anleitung.

    1. Erstelle unterhalb von /system/modules/ einen neuen Ordner. Nenn ihn wie du möchtest. Im Beispiel verwende ich jetzt einfach mal "mark_it"
    2. Unterhalb von /system/modules/mark_it/ erstellst du einen weiteren Ordner /config
    3. Im /config Ordner erstellst du eine Datei config.php (hier wird der zukünftige Cronjob registriert)

    Der Inhalt von config.php ist:
    PHP-Code:
    <?php
    if (!defined('TL_ROOT')) die('You can not access this file directly!');

    $GLOBALS['TL_CRON']['daily'][] = array('MarkIt''runCron');
    4. Im Hauptverzeichnis, also /system/modules/mark_it/ erstellst du eine Datei, die genauso heißt, wie der erste Parameter im Array, also MarkIt.php, damit weiß Contao, welche Klasse geladen werden soll.
    5. Innerhalb der Klasse "MarkIt" erstellst du eine Methode, die den gleichen Namen hat, wie der 2. Parameter im Array, also runCron

    Inhalt von MarkIt.php

    PHP-Code:
    <?php
    class MarkIt extends System
    {

    public function 
    __construct()
    {
      
    $this->import("Database");
    }

    public function 
    runCron()
    {
      
    $intCompareTstamp time()-(86400*90); // Sekunden pro Tag mal 90 Tage = 3 Monate

      
    $this->Database->prepare("UPDATE tl_deineTabelle SET SpalteZurMarkierung = 1 WHERE SpalteErstellungsDatum < ?")->execute($intCompareTstamp)
    }
    }
    Das müsste es generell gewesen sein. Ich habs selbst nicht getestet, sondern einfach blind geschrieben. Die SpalteZurMarkierung und SpalteErstellungsDatum musst du natürlich ersetzen durch die Spaltennamen die in deiner Tabelle vorhanden sind.

    Kannst ja schreiben obs funktioniert hat. Das ist jedenfalls der Grundsätzliche Aufbau eines Moduls.
    Wenn Fragen hast, meld dich einfach :-)

    Gruß aus Augsburg ;-)
    Michael
    Geändert von the_scrat (26.03.2014 um 17:53 Uhr)
    Programmers don't comment their code. It was hard to write, it should be hard to understand...

  3. #3
    Contao-Nutzer Avatar von wsa
    Registriert seit
    27.10.2009.
    Ort
    Augsburg
    Beiträge
    128

    Standard

    Hab jetzt selbst eine Lösung gefunden. Für alle, die's auch interessiert:

    Mein Eintrag im "Scheduler":
    Code:
    Job: templates/unpublish_old_ads.php
    Inhalt meiner templates/unpublish_old_ads.php:
    Code:
    <?php
    #
    # SQL UPDATE über Contao-Cron (Scheduler) absetzen
    #
    # Datenbank-Verbindung herstellen
    $this->import('Database');
    
    # UPDATE absetzen
    $this->Database->prepare("UPDATE tl_table SET fieldname='fix_value' WHERE condition")->execute();
    
    # Eintrag in Log schreiben
    $this->log( 'Cronjob crontest', 'Crontest', TL_ERROR );
    
    ?>
    LG wsa

  4. #4
    Contao-Urgestein
    Registriert seit
    07.07.2009.
    Beiträge
    4.107

    Standard

    Die Lösung ist aber nicht so dolle, du hättest es lieber so wie von the_scrat beschrieben machen sollen. Es ist immer besser unter system/modules einen Ordner anzulegen als mit Templatedateien zu spielen.

  5. #5
    Contao-Nutzer Avatar von wsa
    Registriert seit
    27.10.2009.
    Ort
    Augsburg
    Beiträge
    128

    Frage

    Hallo andreasisaak,

    vielen Dank für deine Rückmeldung. Hab vor lauter Begeisterung über meine "tolle Lösung" den inzwischen eingegangenen Beitrag von the_scrat völlig übersehen.
    Hab's jetzt wie von the_scrat beschrieben umgesetzt. Hab dabei im Scheduler folgenden Pfad eingegeben: system/modules/mark_it/MarkIt.php
    Ergebnis: Der CronJob läuft fehlerfrei durch (Eintrag im Log), allerdings funktioniert die Markierung nicht (mehr).

    Ich lerne gerne dazu: Worin besteht denn der Unterschied bzw. was ist "nicht so dolle"? Gibt es ein Sicherheitsproblem oder wo sind deine "Bedenken"?

    LG wsa
    Geändert von wsa (01.04.2014 um 12:43 Uhr)

  6. #6
    Contao-Urgestein Avatar von the_scrat
    Registriert seit
    24.02.2010.
    Ort
    Augsburg
    Beiträge
    2.051
    User beschenken
    Wunschliste

    Standard

    Hi wsa,

    in welchem Scheduler hast du welchen Pfad angegeben? Du brauchst generell nichts unternehmen. Der Cronjob wird auch nur einmal täglich ausgeführt, weil er unter $GLOBALS['TL_CRON']['daily'][] registriert ist.
    Daher kannst du den jetzt sooft aufrufen wie du willst, er wird so nicht mehr funktionieren, erst morgen wieder.

    Alternativ, ändere in der localconfig (/system/config/localconfig.php) den Wert von $GLOBALS['TL_CONFIG']['cron_daily'] auf z.B. 20140331. Abspeichern und Cronjob aufrufen (oder Seite neu laden).

    Sicherheitstechnisch gibt es an deiner Lösung nichts zu beanstanden, dennoch ist es einfach sauberer, es als eigenes Modul zu deklarieren, wie ich es dir beschrieben habe. Zumal sollte es auch Ressourcenschonender sein, als deine Lösung, da diese erst ausgeführt wird, wenn das Template geladen wird, welches dann wiederrum deine Aktion startet.

    Es gibt die Module ja nicht umsonst um Funktionalität klar von Templates (und deren Tätigkeit) zu trennen. Natürlich ist es möglich, was aber nicht immer sinnvoll ist. Für kleine "quick&dirty"-Lösungen kann man auch gern mal auf ein Template greifen, aber für so eine Aufgabe wie deine eignet sich das Framework und natürlich auch die Registrierung eines Crons hervorragend. Du brauchst dich um nichts kümmern, sondern lediglich deinen Code schreiben.
    Programmers don't comment their code. It was hard to write, it should be hard to understand...

  7. #7
    Contao-Urgestein
    Registriert seit
    07.04.2010.
    Ort
    Stuttgart
    Beiträge
    2.733
    User beschenken
    Wunschliste

    Standard

    Mal eine ganz andere Frage: Wieso willst du das nach 3 Monaten markieren?

    Wäre es nicht geschickter bei der Abfrage nur die zu holen die älter als 3 Monate sind?
    Oder wenn es um eine Markierung geht den Timestamp mitnehmen und im Ausgabetemplate etwas ändern?

    Wenn ich euch helfen konnte könnt ihr euch gerne mal
    meine Amazon Wunschliste anschauen. Dankeschön.

  8. #8
    Contao-Nutzer Avatar von wsa
    Registriert seit
    27.10.2009.
    Ort
    Augsburg
    Beiträge
    128

    Standard

    Hi the_scrat,

    danke nochmals für deine ausführlichen Erklärungen.
    Zitat Zitat von the_scrat Beitrag anzeigen
    Hi wsa,

    in welchem Scheduler hast du welchen Pfad angegeben? .
    Ich hatte ursprünglich geplant, das ganze über den Backend-Menüpunkt zu machen, in dem ich frei angeben kann, welcher "Job" (php-File) wann bzw. wie oft ausgeführt werden soll. Und dort hatte ich jetzt in meiner Ahnungslosigkeit bei "Job" /system/modules/mark_it/MarkIt.php angegeben. (Doch dort wird ja jetzt nicht mehr einfach nur mein alter php-Code ausgeführt, sondern eine Klasse definiert.)
    Wenn ich alles richtig verstanden habe, wird das neue Modul aber über die Einträge in der localconfig getriggert. (Hätte ich also in der config.php $GLOBALS['TL_CRON']['hourly'][] eingetragen, würde das ganze stündlich laufen. Korrekt?)

    (Hoffe, ich hab mich halbwegs verständlich ausgedrückt!?)
    LG wsa

  9. #9
    Contao-Nutzer Avatar von wsa
    Registriert seit
    27.10.2009.
    Ort
    Augsburg
    Beiträge
    128

    Standard

    Zitat Zitat von psren Beitrag anzeigen
    Mal eine ganz andere Frage: Wieso willst du das nach 3 Monaten markieren?

    Wäre es nicht geschickter bei der Abfrage nur die zu holen die älter als 3 Monate sind?
    Oder wenn es um eine Markierung geht den Timestamp mitnehmen und im Ausgabetemplate etwas ändern?
    Hallo prsen,

    das liegt daran, dass die Ausgabe über ein Modul "Auflistung Formulardaten" läuft. Das Problem dabei ist, dass eine Abfrage über Timestamp dort nicht möglich ist. Der tstamp eines Datensatzes (in der Tabelle tl_formdata) wird bei jedem Frontend-Update der Daten neu gesetzt. (In meinem Fall handelt es sich um Kleinanzeigen, die der Eigentümer innerhalb der Maximallaufzeit von 3 Monaten jederzeit aktualisieren kann.) Deshalb muss ich in einem eigenen Datumsfeld eintragsdatum (in der Tabelle tl_formdata_details) das Eintragsdatum speichern. Die SQL-Abfrage im Modul "Auflistung Formulardaten" müsste auf 2 Tabellen zugreifen. Ein entsprechende Anfragesyntax, die keinen SQL-Fehler produziert, habe ich bisher nicht gefunden. Und eine Ausblenden solcher Datensätze im Template ergibt "Löcher" in der Pagination. (Sollen z.B. pro Seite 10 Einträge angezeigt werden, davon sind aber 2 abgelaufen, würden nur 8 pro Seite angezeigt werden. Das sieht bei meinem 2-spaltigen Layout unschön aus.)

    Deshalb gehe ich einen anderen Weg und setze über CRON alle abgelaufenen Kleinanzeigen auf "offline". Alles klar?

    LG wsa

Aktive Benutzer

Aktive Benutzer

Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)

Lesezeichen

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •