Neuigkeiten
  • Die modified eCommerce Shopsoftware ist kostenlos, aber nicht umsonst.
    Spenden
  • Damit wir die modified eCommerce Shopsoftware auch zukünftig kostenlos anbieten können:
    Spenden
  • Thema: MODUL: Produkterinnerung für modified eCommerce Shopsoftware

    Baschtl

    • Mitglied
    • Beiträge: 160
    Re: MODUL: Produkterinnerung für modified eCommerce Shopsoftware
    Antwort #375 am: 03. August 2021, 17:41:29
    Hallo,

    das Modul gibt es auch bei first-web.de updatesicher für die 2.0.6.0 Version kannst Du dir ja auch mal anschauen welches dir besser gefällt.

    Tomcraft

    • modified Team
    • Gravatar
    • Beiträge: 46.161
    • Geschlecht:
    Re: MODUL: Produkterinnerung für modified eCommerce Shopsoftware
    Antwort #376 am: 03. August 2021, 20:44:23
    Oder einfach direkt bei uns kaufen: Kundenerinnerungen

    Grüße

    Torsten

    scooterama

    • Fördermitglied
    • Beiträge: 279
    • Geschlecht:
    Re: MODUL: Produkterinnerung für modified eCommerce Shopsoftware
    Antwort #377 am: 14. Oktober 2021, 14:12:06
    Hallo, bestünde die Möglichkeit Produkterinnerungen auch als Admin für den Kunden xy einzutragen?
    Das wäre zum Teil echt cool wenn Kunden, die telefonisch bestellen, so auch mittels Emailadresse benachrichtigt werden könnten wenn Artikel xy wieder Bestand hat.

    Karl1

    • Experte
    • Beiträge: 1.749
    Re: MODUL: Produkterinnerung für modified eCommerce Shopsoftware
    Antwort #378 am: 14. Oktober 2021, 14:30:47
    Hallo scooterama,
    du kannst doch den Artikel im Frontend aufrufen und die Daten deines Kunden eintragen.

    Würde man z.B. in der Kundenerinnerung einen Button "Neue Kundenerinnerung" einbauen, dann müsstest du Kundendaten und Produktdaten erfassen - das wäre aufwendiger.

    Gruß Karl

    scooterama

    • Fördermitglied
    • Beiträge: 279
    • Geschlecht:
    Re: MODUL: Produkterinnerung für modified eCommerce Shopsoftware
    Antwort #379 am: 14. Oktober 2021, 14:35:19
    Hallo Karl
    Irgendwie erscheint bei meiner Version die Meldung:

    Aus Datenschutzgründen können sich leider nur angemeldete Nutzer für diesen Service registrieren.
    Das finde ich eigentlich auch nicht verkehrt so.

    NACHTRAG:

    @Karl1 hab gerade herausgefunden wie Du das gemeint hast, ich dachte immer das würde direkt in die DB geschrieben wenn man eingeloggt ist, ohne ein Formular ausfüllen zu müssen. Da hätte ich auch selbst drauf kommen können, schande über mich.

    Vielen Dank für den Tip

    noRiddle (revilonetz)

    • Experte
    • Beiträge: 13.707
    • Geschlecht:
    @Karl
    Soweit ich das sehe fehlt im Paket Kundenerinnerung_modified-shop-2.0.4.2.zip bei der automatischen Installation der Produkt-Klassenerweiterung im System-Modul der DB-Eintrag in configuration für MODULE_PRODUCT_INSTALLED.

    Gruß,
    noRiddle

    Karl1

    • Experte
    • Beiträge: 1.749
    Hallo noRiddle,
    danke für den Hinweis, ist bisher noch niemandem aufgefallen.

    Anbei das Paket mit der aktualisierten Datei "/admin/includes/modules/system/customers_remind.php".

    Gruß Karl

    [EDIT Tomcraft 18.06.2022: Modul in Beitrag 1 aktualisiert.]

    noRiddle (revilonetz)

    • Experte
    • Beiträge: 13.707
    • Geschlecht:
    @Karl1
    Danke dir für's Update.

    Mir sind noch mehr "Unzulänglichkeiten" aufgefallen.
    Da ich aus an anderer Stelle ausgeführten Gründen keine von anderen erstellten Module mehr anpasse führe ich die Sachen hier mal auf.
    Datei: /reminder.php
    • In Queries ist $_SESSION['customer_id'] nicht abgesichert gegen potentielle Injection (INT-Cast).
      Darüber hinaus sollte man die String-Anführungszeichen bei INT-Werten entfernen.
    • In der ersten if-Clause sollte die $customers_remind_query und die Bildung des $sql_data_array innerhalb der Condition
      if($registred['anz'] < 1) { ... }
      stehen, damit der Code nicht unnötig ausgeführt wird wenn die genannte if-Condition nicht zutrifft.
    • Um die Logik des Code-Aufbaus zu verbessern sollte man Folgendes ändern:
      Der Button für die Kundenerinnerung wird ja immer angezeigt, auch nicht eingeloggt, und wenn man ihn nicht eingeloggt anklickt erscheint eine Meldung, daß man sich aus Datenchutzgründen nur angemeldet registrieren kann.
      Im Code der eingangs genannten Datei wird jedoch mittels dieser Conditions gearbeitet
      if (isset($_POST['action']) && $_POST['action'] == 'add_remind' && isset($_SESSION['customer_id'])) {
        ...
      } else {
        ...
      }

      Logisch konistent wäre es so
      if (isset($_SESSION['customer_id'])) {
        if (isset($_POST['action']) && $_POST['action'] == 'add_remind') {
          ...
        } else {
          ...
        }
      }

    • Die Query auf die Tabelle customers um an customers_gender zu kommen ist nicht nötig, da er in der Session steht ($_SESSION['customer_gender']).
    • Die Query auf die Tabelle customers um an customers_email_address zu kommen ist nicht nötig, da sie in der Session steht ($_SESSION['customer_email_address']).
    • Woher kommt $_GET['success'] in
      if(!isset($_GET['success']) == 'true') {
    • $customers_remind['customers_st'] ? $customers_remind['customers_st'] : 1
      muß lauten
      $registred['customers_st'] ? $registred['customers_st'] : 1
      wobei die Abfrage mit $anzahl unsinnig ist - wofür ist das - und man die Abfrage vielleicht besser so machen sollte
      !empty($registred['customers_st']) ? $registred['customers_st'] : 1
    Es gibt noch weitere Dinge, die mir aufzuzählen nun zu viel wird.
    Hier also mein Vorschlag:

    Code: PHP  [Auswählen]
    <?php
    /* ------------------------------------------------------------
            Module "Kundenerinnerung_Multilingual_advanced_modified-shop-2.0.3.0" made by Karl

            Based on: Kundenerinnerung_Multilingual_advanced_modified-shop-1.06
            Based on: (( Wir dulden keine kommerziellen Werbelinks - Bitte <a href="index.php?topic=3013.0">Forenregeln</a> beachten! )) customers remind
            erste Anpassung von: Fishnet Services - Gemsjäger 30.03.2012
            Zusatzfunktionen eingefügt sowie Fehler beseitigt von Ralph_84
            Aufgearbeitet für die Modified 1.06 rev4356 von Ralph_84

            modified eCommerce Shopsoftware
            http://www.modified-shop.org

            Released under the GNU General Public License
     
      * edited and tried to improve efficiency and logic, 06-2022, noRiddle *
    -------------------------------------------------------------- */


    include ('includes/application_top.php');

    if(defined('MODULE_CUSTOMERS_REMIND_STATUS') && MODULE_CUSTOMERS_REMIND_STATUS == 'true') {

      require_once (DIR_FS_INC.'xtc_get_products_name.inc.php');

      $smarty = new Smarty;

      $products_id = (int)$_GET['products_id'];
      $products_name = xtc_get_products_name($products_id);
      $smarty->assign('PRODUCTS_NAME', htmlentities($products_name));

      // include header
      require (DIR_WS_INCLUDES.'header.php');

      if(isset($_SESSION['customer_id'])) {
        $reg_query = xtc_db_query("SELECT * FROM customers_remind WHERE customers_id = ".(int)$_SESSION['customer_id']." AND products_id = ".$products_id);
        $registred = xtc_db_fetch_array($reg_query);

        if(isset($_POST['action']) && $_POST['action'] == 'add_remind') {
          if(empty($registred)) {
            $sql_data_array = array (
              'customers_id' => $_SESSION['customer_id'],
              'products_id' => $product->data['products_id'],
              'products_ean' => $product->data['products_ean'],
              'products_name' => $product->data['products_name'],
              'products_model' => $product->data['products_model'],
              'products_image' => $product->data['products_image'],
              'customers_gender' => $_SESSION['customer_gender'],
              'customers_firstname' => xtc_db_prepare_input($_POST['customers_input_firstname']),
              'customers_lastname' => xtc_db_prepare_input($_POST['customers_input_lastname']),
              'customers_email_address' => xtc_db_prepare_input($_POST['customers_input_email']),
              'customers_language' => xtc_db_prepare_input($_POST['language_input']),
              'customers_st' => xtc_db_prepare_input($_POST['customers_input_st']),
              'mail_head1' => xtc_db_prepare_input($_POST['mail_input_head1']),
              'remind_date_added' => 'now()'
            );

            xtc_db_perform('customers_remind', $sql_data_array);
            $smarty->assign('SUCCESS_MESSAGE', '2');
          }
        } else {
          if(!empty($registred)) {
            $smarty->assign('SUCCESS_MESSAGE', '1');
          } else {
            $idStr = '<input type="hidden" name="products_id" value="'.$products_id.'"/><input type="hidden" name="action" value="add_remind"/>';

            $smarty->assign('FORM_ACTION_REMIND', xtc_draw_form('customers_remind', xtc_href_link(FILENAME_CUSTOMERS_REMIND, xtc_get_all_get_params(array('action')), 'SSL'), 'post', 'class="form-horizontal"').$idStr);

            if (defined('MODULE_CUSTOMERS_REMIND_USE_BOOTSTRAP') && MODULE_CUSTOMERS_REMIND_USE_BOOTSTRAP == 'true') {
              $smarty->assign('CUSTOMERS_FIRSTNAME_INPUT', xtc_draw_input_field('customers_input_firstname', $_SESSION['customer_first_name'], 'class="form-control"'));
              $smarty->assign('CUSTOMERS_LASTNAME_INPUT', xtc_draw_input_field('customers_input_lastname', $_SESSION['customer_last_name'], 'class="form-control"'));
              $smarty->assign('CUSTOMERS_MAIL_INPUT', xtc_draw_input_field('customers_input_email', $_SESSION['customer_email_address'], 'class="form-control"'));
              $smarty->assign('CUSTOMERS_INPUT_ST', xtc_draw_input_field('customers_input_st', 1, 'class="form-control"'));
            } else {
              $smarty->assign('CUSTOMERS_FIRSTNAME_INPUT', xtc_draw_input_field('customers_input_firstname', $_SESSION['customer_first_name'], 'size="20"'));
              $smarty->assign('CUSTOMERS_LASTNAME_INPUT', xtc_draw_input_field('customers_input_lastname', $_SESSION['customer_last_name'], 'size="20"'));
              $smarty->assign('CUSTOMERS_MAIL_INPUT', xtc_draw_input_field('customers_input_email', $_SESSION['customer_email_address'], 'size="20"'));
              $smarty->assign('CUSTOMERS_INPUT_ST', xtc_draw_input_field('customers_input_st', 1, 'size="20"'));
            }

            $smarty->assign('FORM_END_REMIND', '</form>');
            $smarty->assign('SUCCESS_MESSAGE', '0');
            $smarty->assign('BUTTON_SUBMIT_REMIND', xtc_image_submit('button_continue.gif', IMAGE_BUTTON_CONTINUE));
          }
        }
      }

      $smarty->assign('language', $_SESSION['language']);
      $smarty->caching = 0;
      $smarty->display(CURRENT_TEMPLATE.'/module/reminder.html');
    }
    ?>

    Für PHP 8 und Error undefined constatnt MODULE_CUSTOMERS_REMIND_STATUS in line 28 im System-Modul kann man dann noch diese Korrektur einbauen:

    Code: PHP  [Auswählen]
    $this->enabled = defined('MODULE_CUSTOMERS_REMIND_STATUS') && MODULE_CUSTOMERS_REMIND_STATUS == 'true' ? true : false;

    Ähnliches gilt weiter unten an zwei Stellen mit MODULE_PRODUCT_CUSTOMERS_REMIND_STATUS.

    Außerdem würde ich anregen, was Doctype usw. betrifft, das Template-File aufzubauen wie popup_content.html, sodaß nicht durch Laden der /includes/header.php der ganze Sermon mit Favicons usw. in das Popup-Form geladen wird.

    Und dann würde ich den Kundenerinnerungs-Button noch als CSS-Button implementieren.
    Aber jetzt ist auch genug. ;-)

    Gruß,
    noRiddle

    Karl1

    • Experte
    • Beiträge: 1.749
    Hallo Zusammen,
    anbei ein überarbeitetes Paket, eingeflossen sind die Änderungsvorschläge von noRiddle.

    Neu ist
    - alle Datenbankeinträge und Moduldateien können auf Knopfdruck gelöscht werden
    - Templatedateien für "tpl_modified_responsive"
    - PHP8-fähig

    Das Modul habe ich getestet mit Shopversion 2.0.7.0 und PHP 8.1.6.

    Gruß Karl

    P.S.: Wieder einmal herzlichen Dank für deine konstruktive Kritik - noRiddle!

    [EDIT Tomcraft 22.06.2022: Modul in Beitrag 1 ergänzt.]

    noRiddle (revilonetz)

    • Experte
    • Beiträge: 13.707
    • Geschlecht:
    Klasse, Danke dir.

    Das sollte aus den modified-Templates noch entfernen werden:

    Code: XML  [Auswählen]
    <script type="text/javascript">
            var x = document.getElementsByTagName("BODY")[0];
        x.className += " popupcontent";
    </script>

    Noch als Anregunng (ohne dich nerven zu wollen):
    Das aus /includes/modules/customers_remind.php

    Code: PHP  [Auswählen]
    $only_admin = 0;

    habe ich bei mir in die Konfiguration des System-Moduls übernommen:

    Code: PHP  [Auswählen]
    $only_admin = defined('MODULE_CUSTOMERS_REMIND_EXEC_ADMIN') ? MODULE_CUSTOMERS_REMIND_EXEC_ADMIN : 'false';

    Aus dem System-Modul:

    Code: PHP  [Auswählen]
    xtc_db_query("INSERT INTO " . TABLE_CONFIGURATION . " (configuration_key, configuration_value,  configuration_group_id, sort_order, set_function, date_added) VALUES ('MODULE_CUSTOMERS_REMIND_STATUS', 'true',  '6', '1', 'xtc_cfg_select_option(array(\'true\', \'false\'), ', now())");
        xtc_db_query("INSERT INTO " . TABLE_CONFIGURATION . " (configuration_key, configuration_value,  configuration_group_id, sort_order, set_function, date_added) VALUES ('MODULE_CUSTOMERS_REMIND_EXEC_ADMIN', 'true',  '6', '2', 'xtc_cfg_select_option(array(\'true\', \'false\'), ', now())");
                    xtc_db_query("INSERT INTO " . TABLE_CONFIGURATION . " (configuration_key, configuration_value,  configuration_group_id, sort_order, set_function, date_added) VALUES ('MODULE_CUSTOMERS_REMIND_USE_BOOTSTRAP', 'false',  '6', '3', 'xtc_cfg_select_option(array(\'true\', \'false\'), ', now())");

    Zusatzidee:
    Evtl. wäre sogar zu überlegen eine Art "simulated cron job" zu bauen der einmal am Tag schaut ob Mails versendet werden müssen, sodaß der Shop nicht ständig durch das Skript belastet wird und man auch das mit dem $only_admin rauswerfen kann.
    Ich habe für solche Zwecke eine DB-Tabelle simulated_cron_records mit lediglich zwei Feldern (application, last_executed) auf meinen Umgebungen. Das Skript welches ausgeführt werden soll wird dann beim ersten Shopaufruf am Tag das Skript ausführen, einen Eintrag in die genannte Tabelle machen (application = 'customers_remind', last_executed = now()) und bei allen weiteren Shopaufrufen schauen ob es für diesen Tag bereits gemacht wurde, und wenn ja wird es eben nicht mehr ausgeführt. Das Nachschauen ob es bereits gemacht wurde ist über den Eintrag application, welcher den PRIMARY-Key hat, blitzschnell ausgeführt.
    So etwas hilft z.B. auch für Skripte die nicht lieferbare Artikel automatisch auf wieder lieferbar setzen wenn sich der Bestand von 0 auf X erhöht hat.
    Weiterhin könnte man damit auch das leidige xtc_expire_specials() bei jedem Seitenaufruf um zu überprüfen ob Sonderangebote abgelaufen sind verbessern.

    Gruß,
    noRiddle

    Karl1

    • Experte
    • Beiträge: 1.749
    Hallo noRiddle,
    wäre statt $only_admin diese Abfrage der DB-Tabelle simulated_cron_records okay, oder gibt es eine schnellere Lösung?

    Code: PHP  [Auswählen]
    $check_query = xtc_db_query("SELECT last_executed FROM ".TABLE_SIMULATED_CRON_RECORDS." WHERE application = 'customers_remind'");
    $check = xtc_db_fetch_array($check_query);

    if (isset($check["last_executed"])) {
            if (date('Ymd', strtotime($check["last_executed"])) != date('Ymd')){
                    xtc_db_query("UPDATE ".TABLE_SIMULATED_CRON_RECORDS." SET last_executed = now() WHERE application = 'customers_remind'");
                    sendremindmails();
            }
    }

    Gruß Karl

    noRiddle (revilonetz)

    • Experte
    • Beiträge: 13.707
    • Geschlecht:
    Hatte zu meiner Idee bereits Ticket #2252 angelegt.

    Dort habe ich das CREATE TABLE und ein Beispiel-Skript angehängt.

    Ich vergleiche so:

    Code: PHP  [Auswählen]
    if($check["last_executed"] < date('Y-m-d', time()))

    (Könnte man auch beides zuerst durch strtotime() schicken)
    Das Beispiel-Skript könnte theoretisch natürlich fehlerhaft sein, deshalb bitte prüfen.

    Gruß,
    noRiddle

    Karl1

    • Experte
    • Beiträge: 1.749
    Hallo Zusammen,
    die von noRiddle gemachten Anregungen (danke dafür) sind umgesetzt.

    Der Versand der Kundenerinnerungsmails wird nur noch einmal täglich angestoßen.

    Das Modul wurde getestet mit Shopversion 2.0.7.0 und PHP 8.1.6.

    Gruß Karl

    [EDIT Tomcraft 23.06.2022: Modul in Beitrag 1 aktualisiert.]

    noRiddle (revilonetz)

    • Experte
    • Beiträge: 13.707
    • Geschlecht:
    Hammer wie du alle Ideen umsetzt, die du für annehmbar hältst. Danke dafür.

    Mir fiel trotzdem noch etwas auf:
    Das in der /includes/modules/customers_remind.php

    Code: PHP  [Auswählen]
    } else {
            if ($_SESSION['customers_status']['customers_status_id'] == 0) {
                    echo '<div class="errormessage shopsystem">Check Table <strong>' . TABLE_SIMULATED_CRON_RECORDS . '</strong>: There is no result "last_executed" for application "customers_remind"!</div>';
            }
    }

    müsste eigtl. unnötig sein, wenn ich mich nicht vertue.
    Du legst den Eintrag ja im System-Modul fest (was ich nicht hatte) und wenn er wider Erwarten nicht da sein sollte haben wir dafür ja das INSERT INTO mit ON DUPLICATE KEY UPDATE, was den Eintrag spätestens dann anlegen würde.

    in selbiger Datei gibt es in der $strstockQuery  zwei völlig unnötige JOINs, nömlich auf products_description  und auf languages. Die Query könnte wohl verdichtet werden auf

    Code: PHP  [Auswählen]
      $strstockQuery = "SELECT cr.*,
                               p.products_quantity,
                               p.products_model,
                               p.products_image
                          FROM customers_remind cr
                          JOIN "
    .TABLE_PRODUCTS." p
                            ON p.products_id = cr.products_id
                           AND p.products_quantity >= cr.customers_st"
    ;

    Die $strValidateQuery  scheint mir unnötig, da wir doch mit der $strstockQuery  bereits ohnehin lediglich vorhandene Einträge gefiltert haben. Statt dessen sollten wir den while-Loop vielleicht mit

    Code: PHP  [Auswählen]
    if(xtc_db_num_rows($resstockQuery) > 0) {

    umgeben.

    Und schon wieder haben wir das Skript schneller gemacht.

    Diese ganzen Unzulänglichkeiten die wir bislang hatten sind ein Grund warum ich vorhandene Fremd-Module nur noch äußerst ungerne anfasse. Nachher steht mein Name darüber und ich habe irgend einen Code-Unsinn übersehen. Von mangelnder Response und Dankbarkeit wollen wir mal nicht reden.

    Wenn wir einen Standard hätten an den sich alle halten würden
    - z.B. in jeder Datei eines Modules einen Kopf mit bestimmten Aufbau zu haben, wo jeder der sich am Community-Modul beteiligt hat sich verewigen würde, und wo wir eine Versionierung hätten -
    würde ich es mir nochmal überlegen.

    Dein sanft- und langmütiger Einsatz hat mich immer erstaunt, Respekt dafür.

    Gruß,
    noRiddle

    Karl1

    • Experte
    • Beiträge: 1.749
    Hallo Zusammen!

    @noRiddle:
    Das Lob von dir macht mich stolz.
    Die Zeilen mit der Errormessage habe ich stehen lassen, obwohl der Code vermutlich nie ausgeführt wird.
    Sollte bei einem Update des Moduls die Tabelle "simulated_cron_records" aus irgdeinem Grund nicht angelegt werden, so steht das zwar als Warnung in einer Log-Datei, fällt aber ansonsten nicht auf.
    Ein roter Warnhinweis für einen Admin wird vermutlich eher bemerkt.
    Alle weiteren Vorschläge von dir habe ich übernommen.

    @Torsten:
    Sorry, dass du ständig aktualisieren musst.

    Gruß Karl

    [EDIT Tomcraft 23.06.2022: Modul in Beitrag 1 aktualisiert.]
    116 Antworten
    51383 Aufrufe
    27. Januar 2022, 10:37:18 von Hans Bambel
    106 Antworten
    85185 Aufrufe
    12. Januar 2022, 13:07:58 von Tomcraft
    7 Antworten
    8682 Aufrufe
    07. März 2024, 15:38:38 von DerNachbar