J3.x

Développement d'un composant MVC - Utiliser la base de données

From Joomla! Documentation

< J3.x:Developing an MVC Component
This page is a translated version of the page J3.x:Developing an MVC Component/Using the database and the translation is 100% complete.

Other languages:
العربية • ‎English • ‎español • ‎français • ‎Nederlands
Joomla! 
3.x
Didacticiel
Développement d'un composant MVC


Ceci est une série qui regroupe plusieurs articles pour devenir un didacticiel sur la façon de développer un Composant pour Joomla! Joomla 3.x suivant le principe Modèle-Vue-Contrôleur.

Commencez avec l'introduction, et naviguez dans les articles de cette série soit à l'aide des boutons de navigation en bas des articles, soit grâce au menu de droite : Les articles de cette série.



Introduction

Ce didacticiel fait partie de la série de didacticiels sur le Développement d'un Composant MVC pour Joomla! 3.3. Vous êtes invité à lire les articles précédents de cette série avant de lire celui-ci. Egalement, tout en faisant cette partie, vous êtes également encouragé à lire cet article sur les requêtes de base de données, sur la sélection de données dans une table de base de données et leur récupération dans plusieurs formats.

Il existe également 3 vidéos associées à cette étape dans le didacticiel, couvrant la configuration de la base de données, rKEHDeFGlGM Affichage du message (à l'aide de JTable) et Sélection du message de l'administrateur (et JDatabase).

Utiliser la base de données

Les composants gèrent généralement leur contenu à l'aide de la base de données. Lors de la procédure d'installation/désinstallation/mise à jour d'un composant, vous pouvez exécuter des requêtes SQL par l'utilisation de fichiers texte SQL.

A l'aide de votre gestionnaire de fichiers et éditeur préférés, créez deux fichiers nommés admin/sql/install.mysql.utf8.sql et admin/sql/updates/mysql/0.0.6.sql. Ils devraient tous les deux avoir le même contenu :

admin/sql/install.mysql.utf8.sql and admin/sql/updates/mysql/0.0.6.sql

DROP TABLE IF EXISTS `#__helloworld`;

CREATE TABLE `#__helloworld` (
	`id`       INT(11)     NOT NULL AUTO_INCREMENT,
	`greeting` VARCHAR(25) NOT NULL,
	`published` tinyint(4) NOT NULL DEFAULT '1',
	PRIMARY KEY (`id`)
)
	ENGINE =MyISAM
	AUTO_INCREMENT =0
	DEFAULT CHARSET =utf8;

INSERT INTO `#__helloworld` (`greeting`) VALUES
('Hello World!'),
('Good bye World!');

Note. Joomla recommande aujourd'hui de spécifier

ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci;

au lieu de ce qui est en haut. InnoDB est le moteur de base de données MySQL le plus moderne (et désormais le moteur par défaut), remplaçant MyISAM. En outre, utf8mb4 prend en charge un plus grand nombre de jeux de caractères, y compris les emojis. Cependant, je n'ai pas testé toutes les étapes du didacticiel avec ce paramètre. Par conséquent, si vous l'utilisez et parcourez toute la série de didacticiels sans trouver de problème, envisagez de mettre à jour ce fichier et de le situer dans les autres étapes du didacticiel.

Notez également que si vous examinez une base de données Joomla, de nombreuses clés de tables de base de données possèdent un champ appelé 'titre' pour le type d'informations que nous stockons dans notre champ 'message d'accueil'. Il est généralement conseillé de suivre le modèle de Joomla et d'utiliser 'title' comme nom de champ, car lorsque nous essayons d'utiliser des fonctionnalités plus complexes (telles que les ACL et les associations), certaines des principales routines JavaScript de Joomla que nous souhaitons réutiliser s'attendent à la présence d'un 'titre'. (Un élément à prendre en compte lors de la prochaine mise à jour de cette série de didacticiels).

Vous constaterez souvent que la table de base de données possède un champ permettant de suivre l'état publié/non publié d'un élément. L'utilisation du nom 'state' dans Joomla n'est pas recommandée car cela peut entraîner des conflits, le nom 'published' est utilisé à la place.
Remarque: Comment dire à Joomla de stocker la valeur du champ de formulaire publié dans un champ de base de données de noms différent? Nous faisons cela en utilisant la méthode setColumnAlias() (depuis 3.4.0).

Le fichier install.mysql.utf8.sql sera exécuté lorsque vous installez le composant. Le fichier 0.0.6.sql est exécuté lorsque vous effectuez une mise à jour.

Voici le fichier d'installation. Il sera exécuté si vous respectez un ordre approprié dans votre fichier helloworld.xml.

Remarque importante : Lors de l'enregistrement des fichiers SQL en utf8, assurez-vous de bien les enregistrer en utf8 SANS BOM, sinon la requête échouera avec l'erreur MySQL #1064.

helloworld.xml

<?xml version="1.0" encoding="utf-8"?>
<extension type="component" version="3.0" method="upgrade">

	<name>Hello World!</name>
	<!-- The following elements are optional and free of formatting constraints -->
	<creationDate>January 2018</creationDate>
	<author>John Doe</author>
	<authorEmail>john.doe@example.org</authorEmail>
	<authorUrl>http://www.example.org</authorUrl>
	<copyright>Copyright Info</copyright>
	<license>License Info</license>
	<!--  The version string is recorded in the components table -->
	<version>0.0.6</version>
	<!-- The description is optional and defaults to the name -->
	<description>Description of the Hello World component ...</description>

	<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>
	<update> <!-- Runs on update; New since J2.5 -->
		<schemas>
			<schemapath type="mysql">sql/updates/mysql</schemapath>
		</schemas>
	</update>

	<!-- Site Main File Copy Section -->
	<!-- Note the folder attribute: This attribute describes the folder
		to copy FROM in the package to install therefore files copied
		in this section are copied from /site/ in the package -->
	<files folder="site">
		<filename>index.html</filename>
		<filename>helloworld.php</filename>
		<filename>controller.php</filename>
		<folder>views</folder>
		<folder>models</folder>
	</files>

	<administration>
		<!-- Administration Menu Section -->
		<menu link='index.php?option=com_helloworld'>Hello World!</menu>
		<!-- Administration Main File Copy Section -->
		<!-- Note the folder attribute: This attribute describes the folder
			to copy FROM in the package to install therefore files copied
			in this section are copied from /admin/ in the package -->
		<files folder="admin">
			<!-- Admin Main File Copy Section -->
			<filename>index.html</filename>
			<filename>helloworld.php</filename>
			<!-- SQL files section -->
			<folder>sql</folder>
			<!-- tables files section -->
			<folder>tables</folder>
			<!-- models files section -->
			<folder>models</folder>
		</files>
	</administration>

</extension>

Faites de même avec le fichier de désinstallation :

A l'aide de votre gestionnaire de fichiers et éditeur préférés, ajoutez un fichier admin/sql/uninstall.mysql.utf8.sql contenant :

admin/sql/uninstall.mysql.utf8.sql

DROP TABLE IF EXISTS `#__helloworld`;

Numérotation des schémas

Votre composant a un numéro de version (spécifié dans la balise <version> dans votre fichier manifeste helloword.xml) et le schéma de base de données de votre composant a son propre numéro de version (basé sur les noms de fichier des fichiers de mise à jour SQL).

Joomla assure le suivi de la version du schéma de base de données de votre composant via un enregistrement dans sa table #__schemas. Ainsi, lorsque vous installez un composant pour la première fois, s'il existe un fichier appelé, par exemple, admin/sql/updates/mysql/0.0.6.sql, Joomla stockera la valeur 0.0.6 dans son enregistrement de schéma.

La prochaine fois que vous installerez une version plus récente de ce composant - il ne sera pas nécessaire que ce soit la version suivante, vous pourrez ignorer les versions - Joomla procédera comme suit:

  • il récupérera la dernière version du schéma de la base de données du composant à partir de sa table #__ - vous pourrez donc trouver dans notre exemple la valeur 0.0.6.
  • il obtiendra les noms de fichiers de tous les fichiers du répertoire admin/sql/updates/mysql/ et les organisera par ordre croissant.
  • il traitera dans l'ordre les fichiers de mise à jour dont le nom de fichier est numériquement après la version actuelle du schéma. Il peut donc rechercher des fichiers nommés 0.0.7.sql, 0.0.9.sql et 0.0.10.sql, et les traiter dans l'ordre.
  • il mettra à jour l'enregistrement de schéma pour qu'il porte le numéro du dernier fichier de mise à jour qu'il a traité, par exemple 0.0.10.

Si vous avez déjà publié des versions de votre composant lorsque vous introduisez l'utilisation de la base de données, comme nous l'avons simulé dans cette série de didacticiels, votre premier fichier de mise à jour doit avoir exactement le même contenu que le fichier d'installation. Si vous ne l'avez pas fait, alors il devrait être vide.

Bien que garder les deux numéros de version en ordre soit une bonne idée, ce n’est pas une obligation. Joomla tire la version du schéma du nom du dernier fichier de mise à jour numérique. C'est pourquoi il est recommandé de créer un fichier de mise à jour initial, même s'il est vide. Si vous souhaitez conserver vos numéros de schéma en phase avec les numéros de version de composant lorsque vous mettez à jour votre code mais pas le schéma de base de données, vous devez simplement inclure un fichier de mise à jour associé au nouveau numéro de version. Ce fichier de mise à jour sera également vide.

Lors des prochaines éditions de votre composant, le fichier d'installation de la base de données doit toujours contenir le schéma complet. Les fichiers de mise à jour ne doivent contenir que les modifications que vous avez apportées au schéma depuis la dernière mise à jour.

Ajouter un nouveau type de champ

Pour le moment, nous avons utilisé un type de champ encodé en dur pour les messages. Nous devons utiliser notre base de données pour choisir le message, et pour se faire, ilnous faut définir un type de champ personnalisé (que nous appelons helloworld ci-dessous) comme décrit ici.

Modifiez le fichier site/views/helloworld/tmpl/default.xml et ajoutez ces lignes :

site/views/helloworld/tmpl/default.xml

<?xml version="1.0" encoding="utf-8"?>
<metadata>
	<layout title="COM_HELLOWORLD_HELLOWORLD_VIEW_DEFAULT_TITLE">
		<message>COM_HELLOWORLD_HELLOWORLD_VIEW_DEFAULT_DESC</message>
	</layout>
	<fields
			name="request"
			addfieldpath="/administrator/components/com_helloworld/models/fields"
			>
		<fieldset name="request">
			<field
					name="id"
					type="helloworld"
					label="COM_HELLOWORLD_HELLOWORLD_FIELD_GREETING_LABEL"
					description="COM_HELLOWORLD_HELLOWORLD_FIELD_GREETING_DESC"
					/>
		</fieldset>
	</fields>
</metadata>

Cela introduit un nouveau type de champ et indique à Joomla! de rechercher la définition du champ dans le dossier /administrator/components/com_helloworld/models/fields.

Pour en savoir plus sur les requêtes de base de données, la sélection de données à partir d'une table de base de données et leur récupération dans plusieurs formats cliquez ici. A l'aide de votre gestionnaire de fichiers et éditeur préférés, ajoutez un fichier site/models/helloworld.php contenant :

admin/models/fields/helloworld.php

<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_helloworld
 *
 * @copyright   Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

// No direct access to this file
defined('_JEXEC') or die('Restricted access');

JFormHelper::loadFieldClass('list');

/**
 * HelloWorld Form Field class for the HelloWorld component
 *
 * @since  0.0.1
 */
class JFormFieldHelloWorld extends JFormFieldList
{
	/**
	 * The field type.
	 *
	 * @var         string
	 */
	protected $type = 'HelloWorld';

	/**
	 * Method to get a list of options for a list input.
	 *
	 * @return  array  An array of JHtml options.
	 */
	protected function getOptions()
	{
		$db    = JFactory::getDBO();
		$query = $db->getQuery(true);
		$query->select('id,greeting');
		$query->from('#__helloworld');
		$db->setQuery((string) $query);
		$messages = $db->loadObjectList();
		$options  = array();

		if ($messages)
		{
			foreach ($messages as $message)
			{
				$options[] = JHtml::_('select.option', $message->id, $message->greeting);
			}
		}

		$options = array_merge(parent::getOptions(), $options);

		return $options;
	}
}

Le nouveau type de champ affiche une liste déroulante des messages à choisir. Vous pouvez voir le résultat pour l'élément helloworld dans le gestionnaire des menus.

Afficher le message sélectionné

Lors de la création/mise à jour d'un lien de menu de ce composant, Joomla! stocke l'identifiant du message. Le modèle HelloWorldModelHelloWorld doit maintenant calculer le message en fonction de cet identifiant et des données stockées dans la base de données. Pour ce faire, cela utilise la fonctionnalité JTable, qui est une alternative à JDatabase si seules les opérations CRUD sur un seul enregistrement sont nécessaires.

Modifiez le fichier site/models/helloworld.php :

site/models/helloworld.php

<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_helloworld
 *
 * @copyright   Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

// No direct access to this file
defined('_JEXEC') or die('Restricted access');

/**
 * HelloWorld Model
 *
 * @since  0.0.1
 */
class HelloWorldModelHelloWorld extends JModelItem
{
	/**
	 * @var array messages
	 */
	protected $messages;

	/**
	 * Method to get a table object, load it if necessary.
	 *
	 * @param   string  $type    The table name. Optional.
	 * @param   string  $prefix  The class prefix. Optional.
	 * @param   array   $config  Configuration array for model. Optional.
	 *
	 * @return  JTable  A JTable object
	 *
	 * @since   1.6
	 */
	public function getTable($type = 'HelloWorld', $prefix = 'HelloWorldTable', $config = array())
	{
		return JTable::getInstance($type, $prefix, $config);
	}

	/**
	 * Get the message
	 *
	 * @param   integer  $id  Greeting Id
	 *
	 * @return  string        Fetched String from Table for relevant Id
	 */
	public function getMsg($id = 1)
	{
		if (!is_array($this->messages))
		{
			$this->messages = array();
		}

		if (!isset($this->messages[$id]))
		{
			// Request the selected id
			$jinput = JFactory::getApplication()->input;
			$id     = $jinput->get('id', 1, 'INT');

			// Get a TableHelloWorld instance
			$table = $this->getTable();

			// Load the message
			$table->load($id);

			// Assign the message
			$this->messages[$id] = $table->greeting;
		}

		return $this->messages[$id];
	}
}

Le modèle demande le message à la TableHelloWorld. Cette classe de table doit être définie dans le fichier admin/tables/helloworld.php.

admin/tables/helloworld.php

<?php
/**
 * @package     Joomla.Administrator
 * @subpackage  com_helloworld
 *
 * @copyright   Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */
// No direct access
defined('_JEXEC') or die('Restricted access');

/**
 * Hello Table class
 *
 * @since  0.0.1
 */
class HelloWorldTableHelloWorld extends JTable
{
	/**
	 * Constructor
	 *
	 * @param   JDatabaseDriver  &$db  A database connector object
	 */
	function __construct(&$db)
	{
		parent::__construct('#__helloworld', 'id', $db);
	}
}

Vous ne devriez voir aucune différence, mais si vous accédez à la base de données, vous devriez voir une table nommée jos_helloworld contenant deux colonnes : id et greeting. Ainsi que deux entrées: Hello World! et Good bye World.

Empaqueter le composant

Contenu de votre répertoire de code

Créez un fichier compressé de ce répertoire ou téléchargez directement l'archive et installez-le en utilisant le gestionnaire des extensions Joomla. Vous pouvez ajouter un élément de menu pour ce composant à l'aide du gestionnaire de menus dans le backend.

Info non-talk.png
General Information

Merci de créer un pull request ou un rapport d'anomalie sur https://github.com/joomla/Joomla-3.2-Hello-World-Component pour toute incohérence dans le code ou pour modifier le code source de cette page.

Contributeurs