Datenbankabfrage

Alles rund um Module und Plugins in CONTENIDO 4.9.
Antworten
notebook20000
Beiträge: 56
Registriert: Mi 3. Jul 2013, 10:15
Kontaktdaten:

Datenbankabfrage

Beitrag von notebook20000 » Fr 12. Jul 2013, 13:29

Hallo,
wie kann ich einen direkten Datenbankrequest absetzen. Was ich zur 4.8 gefunden habe, ist, da es über das $db gehen soll, aber das scheint nicht zu funktionieren.

frederic.schneider_4fb
Beiträge: 967
Registriert: Do 15. Apr 2004, 17:12
Wohnort: Eschborn-Niederhöchstadt
Kontaktdaten:

Re: Datenbankabfrage

Beitrag von frederic.schneider_4fb » Fr 12. Jul 2013, 14:12

Mit diesem Codeschnipsel kannst Du eine Datenbankabfrage abschicken:

Code: Alles auswählen

$db = cRegistry::getDb();
$db->query("Befehl");
Frederic Schneider
Entwickler bei der four for business AG

xmurrix
Beiträge: 3143
Registriert: Do 21. Okt 2004, 11:08
Wohnort: Augsburg
Kontaktdaten:

Re: Datenbankabfrage

Beitrag von xmurrix » Fr 12. Jul 2013, 14:26

Das sollte eigentlich gehen, kommt darauf an, wie du das gemacht hast...

Hier ein Beispiel, wie man den Datensaz zum aktuellen Mandanten ausliest:

Code: Alles auswählen

// datenbank instanz, konfiguration und aktuellen mandanten setzen
$db = cRegistry::getDb();
$cfg = cRegistry::getConfig();
$client = cRegistry::getClientId();

// abfrage vorbereiten, absetzen und ergebnis ausgeben
$query = $db->prepare('SELECT * FROM %s WHERE idclient = %d', $cfg['tab']['clients'], $client);
if ($db->query($query)) {
    $record = $db->nextRecord();
    echo "<pre>" . print_r($record , true) . "</pre>";
}
Für die meisten Entitäten (Artikel, Kategorie, Mandant, User, Frontenduser, usw...) gibt es entsprechende Klassen, die den Zugriff auf die Datensätze und oder Tabellen abstrahieren, schau dir mal alle Dateien im Ordner "contenido/classes/contenido" an.

Folgendes macht fast das Gleiche wie oben:

Code: Alles auswählen

// datenbank instanz und aktuellen mandanten setzen
$db = cRegistry::getDb();
$client = cRegistry::getClientId();

// instanz des mandanten erstellen
$oClient = new cApiClient($client);
if ($oClient->isLoaded()) {
    $record = $oClient->toArray();
    echo "<pre>" . print_r($record , true) . "</pre>";
}
Es gibt auch einen Beitrag, der die neuen Features der DB-Klassen etwas beschreibt, das kann auch hilfreich sein:
http://forum.contenido.org/viewtopic.php?f=95&t=32058

Gruß
xmurrix
CONTENIDO Downloads: CONTENIDO 4.10.1
CONTENIDO Links: Dokumentationsportal, FAQ, API-Dokumentation
CONTENIDO @ Github: CONTENIDO 4.10 - Mit einem Entwicklungszweig (develop-branch), das viele Verbesserungen/Optimierungen erhalten hat und auf Stabilität und Kompatibilität mit PHP 8.0 bis 8.2 getrimmt wurde.

apicalart
Beiträge: 161
Registriert: Fr 18. Mär 2005, 13:09
Wohnort: Linnich ( NRW )
Kontaktdaten:

Re: Datenbankabfrage

Beitrag von apicalart » Fr 5. Sep 2014, 08:35

Guten Morgen,

Ich möchte aus einer Tabelle "con_pifa_bpass01" mehrere Spalten auslesen und ausgeben. Dazu habe ich mich jetzt mal an deiner Anleitung entlang gehangelt. Mein Code:

Code: Alles auswählen

Code unten in korrigierter funktionierender Version
Das Template zeigt er an, aber er fügt keine Werte ein. Was muss ich tun?
Zuletzt geändert von apicalart am Fr 5. Sep 2014, 15:15, insgesamt 1-mal geändert.
Dat gijjt et doch nit wirklich, odder !

Grüsse aus dem Rheinland
http://www.eukoba.de

Faar
Beiträge: 1915
Registriert: Sa 8. Sep 2007, 16:23
Wohnort: Brandenburg
Kontaktdaten:

Re: Datenbankabfrage

Beitrag von Faar » Fr 5. Sep 2014, 12:42

Probier mal diese kleine Änderung:

Code: Alles auswählen

    $tpl->set("s", $db->f('bp_branche'));
    $tpl->set("s", $db->f('bp_land'));
Aber besser wäre, Dinge wie $db->f('bp_branche') zuerst einer Variablen zu zu weisen und diese Variable dann in dem Template auszugeben:

Code: Alles auswählen

if ($db->nextRecord()) {
    $bp_branche = $db->f('bp_branche');
    $bp_land = $db->f('bp_land');
}

$tpl = new cTemplate();
    $tpl->set("s", $bp_branche);
    $tpl->set("s", $bp_land);
Aber schon die Abfrage ist zweifelhaft, denn "SELECT * FROM con_pifa_bpass01 LIMIT 1" ist nicht eindeutig.
Eindeutiger wäre es, wenn ein DISTINCT oder ORDER BY vor dem LIMIT 1 noch wäre.
Am besten ist ein WHERE, falls es einen Wert gibt der abzufragen ist.
Fliegt der Bauer übers Dach, ist der Wind weißgott nicht schwach.

Faar
Beiträge: 1915
Registriert: Sa 8. Sep 2007, 16:23
Wohnort: Brandenburg
Kontaktdaten:

Re: Datenbankabfrage

Beitrag von Faar » Fr 5. Sep 2014, 12:46

Ach ja, an der Template Ausgabe scheint mir auch noch was nicht zu stimmen.
Hab den richtigen Code nicht im Kopf aber woher weiß das Template, welcher Platzhalter gefüllt werden soll, wenn da jeweils nur set "s" steht?
Und wird das Template dann irgendwo auch generiert oder fehlt das nur hier im Code?
Fliegt der Bauer übers Dach, ist der Wind weißgott nicht schwach.

apicalart
Beiträge: 161
Registriert: Fr 18. Mär 2005, 13:09
Wohnort: Linnich ( NRW )
Kontaktdaten:

Re: Datenbankabfrage

Beitrag von apicalart » Fr 5. Sep 2014, 14:43

Hallo Faar,

danke für deine Hilfestellung. Aufgrund deines Hinweises habe ich Schritt 1 jetzt hinbekommen.
Das ganze wird eine Fragebogenauswertung. LIMIT 1 bezieht sich zur Zeit zu Testzwecken auf die id 1 der Datenbank. Die id ist Primary der Tabelle.
Ich brauche also immer nur eine Datensatz aus der Datenbank. In dem Fall also Datensatz 1.

Damit jetzt zu Problem 2:
Ich möchte jetzt je id(=also Datensatz) einen Artikel in der Datenbank anlegen.
Also
1. Neuen Artikel anlegen
2. Id des Datensatzes eintragen. Im Modul bei LIMIT 1,2,3,4,.... usw. ?
3. fertig.

Wie kann ich das umsetzen??????



Moduloutput

Code: Alles auswählen

<?php

// assert framework initialization
defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');

// use template
$tpl_form = "Hier Name des Templates eintragen.html";

// Prepare module info. Needed later to check if defined default smarty template is a real file
$mod = new cApiModule($cCurrentModule);
$tplpath = $cfgClient[$client]["path"]["frontend"]."data/modules/".$mod->get("alias")."/template/";

/* URL Building */
$params = array('idcat' => $idcat, 'idart' => $oStartArt->$idart, 'lang' => $lang);
$baseUrl = cUri::getInstance()->build($params);


// datenbank instanz, konfiguration und aktuellen mandanten setzen

$db = cRegistry::getDb();
$cfg = cRegistry::getConfig();
$client = cRegistry::getClientId();

//cInclude('classes', 'contenido/class.article.php');
cInclude('classes', 'class.template.php');

// abfrage vorbereiten, absetzen und ergebnis ausgeben

$db->query('SELECT * FROM Hier Tabellenname eintragen LIMIT 1);
if ($db->nextRecord()) {
    $tabellenspalte1 = $db->f('tabellenspalte1');
    $tabellenspalte2 = $db->f('tabellenspalte2');
}

$tpl = new cTemplate();
    $tpl->set("s",tabellenspalte1, $tabellenspalte1);
    $tpl->set("s", tabellenspalte2, $tabellenspalte2);



//$tpl->generate($cfgClient[$client]["path"]["frontend"]."data/modules/hier name des moduls/template/".$tpl_form);
$tpl->generate($tplpath.$tpl_form);

?>
Template Code

Code: Alles auswählen

<h1>{tabellenspalte1}</h1>
<h2>{tabellenspalte2}</h2>
Dat gijjt et doch nit wirklich, odder !

Grüsse aus dem Rheinland
http://www.eukoba.de

Faar
Beiträge: 1915
Registriert: Sa 8. Sep 2007, 16:23
Wohnort: Brandenburg
Kontaktdaten:

Re: Datenbankabfrage

Beitrag von Faar » Fr 5. Sep 2014, 16:29

Hallo apicalart,

so wie ich das nun ahne, ist es vielleicht komplizierter als du denkst, es fängt vermutlich schon beim Konzept und der Datenstruktur an.

Problem 1 ist nicht fertig, die DB Abfrage müsste dann lauten:

Code: Alles auswählen

SELECT * FROM table WHERE id='1'
Limit und order by braucht es hier nicht, weil eine ID hier nur einmal in der Tabelle vorkommt (PRIMARY ist wie unique, ein Wert kommt nur einmal in der Spalte vor).
Woher kommt diese ID? Ist es eine automatisch generierte aus Contenido oder aus einem eigenem Formular-Modul erzeugte?
Ich habe die Tabellenstruktur con_pifa nicht im Kopf, aber wenn es ein Autoinkrement ist, dann nützt diese ID vorerst nicht viel zur Abfrage.
Denn die Frage muss lauten, warum frage ich einen Datensatz mit einer dieser IDs ab?
Wo ist der Bezug oder die Logik dazu?

Bei einer Fragenbogenauswertung habe ich meistens einen Namen oder Email des Ausfüllenden dazu, nach diesem ich in der Datenbank fragen möchte.

Code: Alles auswählen

SELECT * FROM table WHERE email='nick.name.tld' OR name='nick'
Das geht natürlich nur, wenn in der gleichen Tabelle alle Daten stehen.
Daraus hat man dann die ID mit der man schneller weiter arbeiten kann, falls es weiter Abfragen nach diesen Datensatz gibt.
Aber das ist nur Spekulation, es könnte auch ein anderes Konzept von Dir gedacht sein.
Aber nach dem Konzept richtet sich alles aus. :?

Wenn die Richtung aber eine andere ist, also erst einmal Daten erzeugt werden sollen, muss man das anders aufbauen, vor allen ohne "LIMIT".

Code: Alles auswählen

Ich möchte jetzt je id(=also Datensatz) einen Artikel in der Datenbank anlegen. 
http://php.net/manual/de/tutorial.forms.php
http://aktuell.de.selfhtml.org/artikel/php/form-mail/
Das PIFA Formular legt den Datensatz schon an und wird auch für die ID sorgen, folglich brauchst du kein Modul, das irgendwas in die Datenbank schreibt und keine neue Tabelle anlegen.
Sollte es aber so gedacht sein, dass irgendwas ins Formular eingetragen wird und dann ein Contenido Artikel mit der ID des Formulardatensatzes im richtigen Bezug dazu erzeugt wird, dann wirds schwer.
Contenido ist ein CMS und hier geht es in die Richtung einer eigenen CMS Engine für die Fragenbogenauswertung.
Das wird erheblich umfangreicher.

Die Daten wie Name, Email und fortlaufende ID stehen in der PIFA Tabelle, aber das Zusätzliche könnte je nachdem schwer mit einem CMS umsetzbar sein, das ist leichter in einer indivduellen Programmierung zu machen (wenn man nicht zwingend ein CMS dafür braucht).

Wenn es nur darum geht, einen Contenido Artikel mit den Daten aus der PIFA Tabelle zu erstellen, ohne dass dieser Contenido Artikel durchsuchbar nach dieser PIFA ID gefunden werden kann, dann ist es leichter.
Die Daten würden dann nur eingeblendet werden:
1. Modul erstellen, das die PIFA Tabelle, wie oben vorgeschlagen, durchsucht. Dieses Modul gibt z.B. im Backend eine DropDown-Liste aller Einträge aus: http://www.w3schools.com/tags/tag_option.asp
2. Das Modul wird im HTML-Layout vorbereitet und im Template (Vorlage) eingebunden.
3. Beim erstellen eines Contenido Artikels wird dann über diese DropDown Liste die ID einer Contenido-Variablen mit festem Bezug* zum Artikel abgespeichert (*macht Contenido automatisch).
4. Das Modul holt sich beim Anzeigen der Seite (oder Artikel) je nach ausgewähltem PIFA-Eintrag die Daten heraus und zeigt sie im Template an.

Das ist eine Einweg-Geschichte und wird oft so gemacht.
Formulareintrag-->Anzeige in Seite
Aber wenn dann z.B. ein Contenido Artikel anhand eines PIFA Eintrages gesucht und angezeigt werden soll, wird es deutlich komplizierter.
"zeige mir Seite (Artikel) mit PIFA-ID Nr. 45"

Sowas habe ich mit Contenido dann mittels einem Zusammenspiel von Modulen und einem Plugin umgesetzt, für ein Coaching-System.

VG,
Faar
Fliegt der Bauer übers Dach, ist der Wind weißgott nicht schwach.

Antworten