Eine Joomla-Datenbank für deine Erweiterung

Deine Ansicht im Administrationsbereich enthält in der Regel nicht nur statischen Text. Du zeigst hier Daten an, die dynamisch sind. So arbeiten zumindest die meisten Erweiterungen. Deshalb legen wir in diesem Teil eine Datenbank für deine Komponente an.

In der Datenbank speichern wir bei der Einrichtung drei Datensätze und zeigen diese im Administrationsbereich an. Es wird eine statische Liste ausgegeben. Änderbar sind die einzelnen Einträge über das Backend nicht. Daran arbeiten wir im nächsten Teil.

Joomla Componente mit Datenbank

Für Ungeduldige

Sieh dir den geänderten Programmcode in der Diff-Ansicht an und übernimm diese Änderungen in deine Entwicklungsversion.

// https://github.com/astridx/boilerplate/compare/t5...t6.diff

diff --git a/src/administrator/components/com_foos/foos.xml b/src/administrator/components/com_foos/foos.xml
index e24d1127..ec9a6270 100644
-- a/src/administrator/components/com_foos/foos.xml
++ b/src/administrator/components/com_foos/foos.xml
@@ -11,6 +11,16 @@
 	<description>COM_FOOS_XML_DESCRIPTION</description>
 	<namespace path="src">FooNamespace\Component\Foos</namespace>
 	<scriptfile>script.php</scriptfile>
	<install> <!-- Runs on install -->
		<sql>
			<file driver="mysql" charset="utf8">sql/install.mysql.utf8.sql</file>
		</sql>
	</install>
	<uninstall> <!-- Runs on uninstall -->
		<sql>
			<file driver="mysql" charset="utf8">sql/uninstall.mysql.utf8.sql</file>
		</sql>
	</uninstall>
 	<!-- Frond-end files -->
 	<files folder="components/com_foos">
 		<folder>src</folder>
@@ -26,6 +36,7 @@
 		<files folder="administrator/components/com_foos">
 			<filename>foos.xml</filename>
 			<folder>services</folder>
			<folder>sql</folder>
 			<folder>src</folder>
 			<folder>tmpl</folder>
 		</files>
diff --git a/src/administrator/components/com_foos/services/provider.php b/src/administrator/components/com_foos/services/provider.php
index 3e3ba4e4..b67c35d4 100644
-- a/src/administrator/components/com_foos/services/provider.php
++ b/src/administrator/components/com_foos/services/provider.php
@@ -15,6 +15,7 @@
 use Joomla\CMS\Extension\Service\Provider\ComponentDispatcherFactory;
 use Joomla\CMS\Extension\Service\Provider\MVCFactory;
 use Joomla\CMS\HTML\Registry;
use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
 use Joomla\DI\Container;
 use Joomla\DI\ServiceProviderInterface;
 use FooNamespace\Component\Foos\Administrator\Extension\FoosComponent;
@@ -49,6 +50,7 @@ function (Container $container)
 				$component = new FoosComponent($container->get(ComponentDispatcherFactoryInterface::class));

 				$component->setRegistry($container->get(Registry::class));
				$component->setMVCFactory($container->get(MVCFactoryInterface::class));

 				return $component;
 			}
diff --git a/src/administrator/components/com_foos/sql/install.mysql.utf8.sql b/src/administrator/components/com_foos/sql/install.mysql.utf8.sql
new file mode 100644
index 00000000..634065b8
-- /dev/null
++ b/src/administrator/components/com_foos/sql/install.mysql.utf8.sql
@@ -0,0 +1,11 @@
CREATE TABLE IF NOT EXISTS `#__foos_details` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `alias` varchar(400) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL DEFAULT '',
 `name` varchar(255) NOT NULL DEFAULT '',
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci;

INSERT INTO `#__foos_details` (`name`) VALUES
('Nina'),
('Astrid'),
('Elmar');
diff --git a/src/administrator/components/com_foos/sql/uninstall.mysql.utf8.sql b/src/administrator/components/com_foos/sql/uninstall.mysql.utf8.sql
new file mode 100644
index 00000000..0fd7415a
-- /dev/null
++ b/src/administrator/components/com_foos/sql/uninstall.mysql.utf8.sql
@@ -0,0 +1 @@
DROP TABLE IF EXISTS `#__foos_details`;
diff --git a/src/administrator/components/com_foos/src/Model/FoosModel.php b/src/administrator/components/com_foos/src/Model/FoosModel.php
new file mode 100644
index 00000000..4767b474
-- /dev/null
++ b/src/administrator/components/com_foos/src/Model/FoosModel.php
@@ -0,0 +1,57 @@
<?php
/**
* @package     Joomla.Administrator
* @subpackage  com_foos
*
* @copyright   Copyright (C) 2005 - 2020 Open Source Matters, Inc. All rights reserved.
* @license     GNU General Public License version 2 or later; see LICENSE.txt
*/

namespace FooNamespace\Component\Foos\Administrator\Model;

\defined('_JEXEC') or die;

use Joomla\CMS\MVC\Model\ListModel;

/**
* Methods supporting a list of foo records.
*
* @since  __BUMP_VERSION__
*/
class FoosModel extends ListModel
{
	/**
	 * Constructor.
	 *
	 * @param   array  $config  An optional associative array of configuration settings.
	 *
	 * @see     \JControllerLegacy
	 *
	 * @since   __BUMP_VERSION__
	 */
	public function __construct($config = array())
	{
		parent::__construct($config);
	}
	/**
	 * Build an SQL query to load the list data.
	 *
	 * @return  \JDatabaseQuery
	 *
	 * @since   __BUMP_VERSION__
	 */
	protected function getListQuery()
	{
		// Create a new query object.
		$db = $this->getDbo();
		$query = $db->getQuery(true);

		// Select the required fields from the table.
		$query->select(
			$db->quoteName(array('id', 'name', 'alias'))
		);
		$query->from($db->quoteName('#__foos_details'));

		return $query;
	}
}
diff --git a/src/administrator/components/com_foos/src/View/Foos/HtmlView.php b/src/administrator/components/com_foos/src/View/Foos/HtmlView.php
index fa0bfd4a..d317d93c 100644
-- a/src/administrator/components/com_foos/src/View/Foos/HtmlView.php
++ b/src/administrator/components/com_foos/src/View/Foos/HtmlView.php
@@ -20,6 +20,13 @@
  */
 class HtmlView extends BaseHtmlView
 {
	/**
	 * An array of items
	 *
	 * @var  array
	 */
	protected $items;

 	/**
 	 * Method to display the view.
 	 *
@@ -31,6 +38,7 @@ class HtmlView extends BaseHtmlView
 	 */
 	public function display($tpl = null): void
 	{
		$this->items = $this->get('Items');
 		parent::display($tpl);
 	}
 }
diff --git a/src/administrator/components/com_foos/tmpl/foos/default.php b/src/administrator/components/com_foos/tmpl/foos/default.php
index 4796008d..0f12849b 100644
-- a/src/administrator/components/com_foos/tmpl/foos/default.php
++ b/src/administrator/components/com_foos/tmpl/foos/default.php
@@ -8,4 +8,7 @@
  */
 \defined('_JEXEC') or die;
 ?>
Hello Foos
<?php foreach ($this->items as $i => $item) : ?>
<?php echo $item->name; ?>
</br>
<?php endforeach; ?>

Schritt für Schritt

Neue Dateien

src/administrator/components/com_foos/sql/install.mysql.utf8.sql

Wir legen eine Datei an, die SQL-Befehle für das Erstellen der Datenbanktabelle enthält. Damit diese Statements aufgerufen werden, fügen wir den Namen später im Manifest ein. Gleichzeitig speichern wir mit INSERT INTO ... Beispielinhalte in der Datenbanktabelle.

Lies im Vorwort, was das Präfix #__ genau bedeutet, wenn du dies nicht weißt.

src/administrator/components/com_foos/sql/install.mysql.utf8.sql

CREATE TABLE IF NOT EXISTS `#__foos_details` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `alias` varchar(400) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL DEFAULT '',
  `name` varchar(255) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci;

INSERT INTO `#__foos_details` (`name`) VALUES
('Nina'),
('Astrid'),
('Elmar');

src/administrator/components/com_foos/sql/uninstall.mysql.utf8.sql

Damit Joomla im Falle einer Deinstallation keinen unnötigen Code enthält, erstellen wir gleichzeitig eine Datei, die den SQL-Befehl zum Löschen der Datenbanktabelle beinhaltet.

src/administrator/components/com_foos/sql/uninstall.mysql.utf8.sql

DROP TABLE IF EXISTS `#__foos_details`;

src/administrator/components/com_foos/src/Model/FoosModel.php

Als Nächstes erstellen wir ein Model für den Administrationsbereich. Da wir die Klasse ListModel erweitern, ist es nicht erforderlich, dass wir uns um die Verbindung zur Datenbank kümmern. Wir legen die Methode getListQuery() an und geben hier unsere spezifischen Anforderungen an.

Falls bisher nicht geschehen, wird dir hier klar, warum die Trennung von Model und View sinnvoll ist. Sieh dir einmal die Methode getListQuery() in Joomla-Komponenten an, zum Beispiel in com_content. Das SQL-Statement ist meist umfangreich.

src/administrator/components/com_foos/src/Model/FoosModel.php

namespace FooNamespace\Component\Foos\Administrator\Model;

\defined('_JEXEC') or die;

use Joomla\CMS\MVC\Model\ListModel;

class FoosModel extends ListModel
{
	public function __construct($config = array())
	{
		parent::__construct($config);
  }

	protected function getListQuery()
	{
		$db = $this->getDbo();
		$query = $db->getQuery(true);

		$query->select(
			$db->quoteName(array('id', 'name', 'alias'))
		);
		$query->from($db->quoteName('#__foos_details'));

		return $query;
	}
}

Geänderte Dateien

src/administrator/components/com_foos/foos.xml

Der nachfolgende Eintrag im Installationsmanifest bewirkt, dass die SQL-Statements in den genannten Dateien zum passenden Zeitpunkt aufgerufen werden:

src/administrator/components/com_foos/foos.xml

  ...
  <install> <!-- Runs on install -->
		<sql>
			<file driver="mysql" charset="utf8">sql/install.mysql.utf8.sql</file>
		</sql>
	</install>
	<uninstall> <!-- Runs on uninstall -->
		<sql>
			<file driver="mysql" charset="utf8">sql/uninstall.mysql.utf8.sql</file>
		</sql>
	</uninstall>
  ...

Ich unterstütze in diesem Beispiel ausschließlich eine MySQL-Datenbank. Joomla unterstützt neben MySQL (ab 5.6) genauso PostgreSQL (ab 11). Wenn du ebenfalls beide Datenbanken unterstüzt, findest du eine Implementierung zum Abgucken in der Weblinks Komponenten. Wie du die Treiber benennst ist flexibel. postgresql und mysql sind korrekt, mysqli, pdomysql und pgsql werden angepasst.

Aktualisierungen

Der Vollständigkeit halber nehme ich hier Änderungen eines nachfolgenden Kapitels bezügltich Aktualisierunge vorweg:

Wenn sich etwas ändert, reicht es aus, in der Datenbank nur die Änderungen aufzunehmen. Diese speicherst du in einer separaten Datei pro Version ab. Das Verzeichnis, in dem die Dateien für die Áktualisierung abgelegt sind, schreibst du in das folgende Tag.

  ...
  <update>  <!-- Runs on update -->
		<schemas>
			<schemapath type="mysql">sql/updates/mysql</schemapath>
		</schemas>
  </update>
  ...

Nachfolgend siehst du die Aktualisierungsdatei src/administrator/components/com_foos/sql/updates/mysql/10.0.0.sql als Beispiel. Diese Datei wird später in diesem Beispiel hinzugefügt.

ALTER TABLE `#__foos_details` ADD COLUMN  `access` int(10) unsigned NOT NULL DEFAULT 0 AFTER `alias`;
ALTER TABLE `#__foos_details` ADD KEY `idx_access` (`access`);

src/administrator/components/com_foos/services/provider.php

Bisher war es nicht notwendig, jetzt ist es erforderlich, die MVC factory zu setzten. Andernfalls siehst du die nachfolgende Fehlermeldung oder bist gezwungen, die Verbindung zur Datenbank selbst zu programmieren: MVC factory not set in Joomla\CMS\Extension\MVCComponent.

src/administrator/components/com_foos/services/provider.php

...
use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
...
...
$component->setMVCFactory($container->get(MVCFactoryInterface::class));
...

src/administrator/components/com_foos/src/View/Foos/HtmlView.php

In der View holen wir am Ende die Elemente. Hierzu rufen wir die passende Methode im Model auf:

src/administrator/components/com_foos/src/View/Foos/HtmlView.php

...
protected $items;
...
...
		$this->items = $this->get('Items');
...

src/administrator/components/com_foos/tmpl/foos/default.php

Last but not least zeigen wir alles mithilfe der Templatedatei an. Anstelle des statischen Textes Hello Foos steht jetzt eine Schleife.

src/administrator/components/com_foos/tmpl/foos/default.php

...
<?php foreach ($this->items as $i => $item) : ?>
<?php echo $item->name; ?>
</br>
<?php endforeach; ?>

Wunderst du dich über die Schreibweise? Im Vorwort hatte ich erklärt, warum ich in einer Template-Datei die alternative Syntax für PHP wähle und die einzelnen Zeilen in PHP-Tags einschließe.

Teste deine Joomla-Komponente

  1. Installiere deine Komponente in Joomla! Version 4, um sie zu testen:

Kopiere die Dateien im administrator Ordner in den administrator Ordner deiner Joomla! 4 Installation.
Kopiere die Dateien im components Ordner in den components Ordner deiner Joomla! 4 Installation.

Installiere deine Komponenten wie in Teil eins beschrieben, nachdem du alle Dateien kopiert hast. Joomla! erstellt bei der Installation die Datenbank für dich.

  1. Teste als Nächstes, ob du die Ansicht im Administrationsbereich für deine Komponente fehlerfrei angezeigt bekommst. Siehst du drei Einträge? Diese hatten wir beim Einrichten der Datenbank als Beispieldaten in der SQL-Datei angelegt.

Joomla Componente mit Datenbank

Geänderte Dateien

Übersicht

Vor oder zurück ...