<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet title="XSL formatting" type="text/xsl" href="https://dotclear.watch/feed/rss2/xslt" ?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>DotclearWatch / Blog - Mot-clé - service</title>
    <link>https://dotclear.watch/</link>
    <atom:link href="https://dotclear.watch/feed/tag/service/rss2" rel="self" type="application/rss+xml" />
    <description>Suivez l'évolution du moteur de blogs Dotclear.</description>
    <language>fr</language>
    <pubDate>Sun, 21 Jun 2026 07:12:50 +0200</pubDate>
    <copyright>Tous droits réservés © Jean-Christian Denis</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>Dotclear</generator>
          <item>
        <title>[2.36] Modification du service de base de données</title>
        <link>https://dotclear.watch/Billet/%5B2.36%5D-Modification-du-service-de-base-de-donn%C3%A9es</link>
        <guid isPermaLink="false">urn:md5:6d4246c76f73c25281905c82eb71ba4c</guid>
        <pubDate>Tue, 02 Sep 2025 14:17:00 +0200</pubDate>
        <dc:creator>Jean-Christian Denis</dc:creator>
                  <category>2.36</category>
                          <category>2.36</category>
                  <category>connexion</category>
                  <category>database</category>
                  <category>service</category>
                <description>&lt;p&gt;Dans Dotclear 2.36 le Container principal est encore plus soyeux avec uniquement de vraies classes comme services, cela entraîne certaines modifications.&lt;/p&gt; &lt;p&gt;&lt;a class=&quot;ref-post&quot; href=&quot;https://dotclear.watch/Billet/2.36&quot; title=&quot;Article rédigé pour Dotclear 2.36&quot;&gt;&lt;img alt=&quot;badge Dotclear 2.36&quot; src=&quot;https://img.shields.io/badge/Dotclear-2.36-blue?style=for-the-badge&quot; /&gt; &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Avant la version 2.36 de Dotclear, l'accès à la base de données se faisait par l'appel &lt;strong&gt;App::con()&lt;/strong&gt;; mais d'un point de vu technique cet appel passait par une fonction intermediaire directement dans la pile de services du Container principal, fonctionnel mais pas vraiment joli et surtout trop strict et rigide. C'est pourquoi la version 2.36 de Dotclear introduit un nouveau service du core nommé &lt;strong&gt;db()&lt;/strong&gt; qui fait le lien entre Dotclear et les drivers de base de données. De ce fait, l'appel qui se faisait par &lt;strong&gt;App::con()&lt;/strong&gt; devient &lt;strong&gt;App::db()-&amp;gt;con()&lt;/strong&gt;, plus long et donc moins sexy, mais cela va permettre de travailler et d'améliorer les drivers de base de données beaucoup plus facilement.&lt;/p&gt;

&lt;pre&gt;
&lt;code class=&quot;language-php&quot;&gt;//App::con()-&amp;gt;openCursor('xyz');
App::db()-&amp;gt;con()-&amp;gt;openCursor('xyz);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Bien entendu l'écriture &lt;strong&gt;App::con()&lt;/strong&gt;&amp;nbsp;est dépréciée mais reste fonctionnelle encore pour quelques siècles.&lt;/p&gt;

&lt;p&gt;Ce changement a permis dès la version 2.36 de proposer d'autres drivers de base de données et d'améliorer le processus d'installation.&lt;/p&gt;

&lt;h3&gt;Le nouveau service App::db()&lt;/h3&gt;

&lt;p&gt;Le coeur de l'application Dotclear embarque donc un nouveau service qui va permettre de faire le lien entre les drivers de base de données et le reste de Dotclear.&lt;/p&gt;

&lt;p&gt;Il est identifié comme suit dans le container :&lt;/p&gt;

&lt;ul&gt;
	&lt;li&gt;Identifiant du service : Dotclear\Core\DatabaseInterface&lt;/li&gt;
	&lt;li&gt;Classe par défaut : Dotclear\Core\Database&lt;/li&gt;
	&lt;li&gt;Methode du service : App::db()&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Son interface montre ses méthodes :&lt;/p&gt;

&lt;ul&gt;
	&lt;li&gt;App::db()-&amp;gt;con() : l'accès à la base de données&lt;/li&gt;
	&lt;li&gt;App::db()-&amp;gt;newCon() : Une instance isolé de l'accès à une&amp;nbsp;base de données&lt;/li&gt;
	&lt;li&gt;App::db()-&amp;gt;structure() : l'accès à la gestion de structure de base de données&lt;/li&gt;
	&lt;li&gt;App::db()-&amp;gt;combo() : liste des drivers utilisables (sert dans le process d'installation Dotclear)&lt;/li&gt;
&lt;/ul&gt;

&lt;pre&gt;
&lt;code class=&quot;language-php&quot;&gt;interface DatabaseInterface
{
    /**
     * Get dabatase connection handler instance.
     *
     * This connection instance uses parameters from config service.
     */
    public function con(): ConnectionInterface;

    /**
     * Get new dabatase connection handler instance.
     *
     * @param   string  $driver         Driver name
     * @param   string  $host           Database hostname
     * @param   string  $database       Database name
     * @param   string  $user           User ID
     * @param   string  $password       Password
     * @param   bool    $persistent     Persistent connection
     * @param   string  $prefix         Database tables prefix
     */
    public function newCon(
        string $driver, 
        string $host, 
        string $database, 
        string $user = '', 
        string $password = '', 
        bool $persistent = false, 
        string $prefix = ''
    ): ConnectionInterface;

    /**
     * Get database structure handler.
     *
     * The handler uses current connexion.
     * Each call to this method MUST return a new instance.
     *
     * @return  Structure   The database structure handler
     */
    public function structure(): Structure;

    /**
     * Get combo of available database drivers.
     *
     * @return  array&amp;lt;string, string&amp;gt;   The drivers name/driver pairs
     */
    public function combo(): array;
}
&lt;/code&gt;
&lt;/pre&gt;

&lt;p&gt;Cette classe est récente et va surement évoluer dans les versions à venir.&lt;/p&gt;

&lt;h3&gt;Le gestionnaire de connexion App::db()-&amp;gt;con()&lt;/h3&gt;

&lt;p&gt;Une fois le driver choisi et inscrit dans le fichier de configuration de Dotclear, ses méthodes sont accessibles depuis l'application dans App::db()-&amp;gt;con().&amp;nbsp;&lt;br /&gt;
Un driver est généralement constitué d'une classe principale qui étend une classe d'abstraction qui étend elle même une interface. Le driver fournit également une classe de gestion de Schema. Toutes ces classes sont disponibles à divers endroits de Dotclear :&lt;/p&gt;

&lt;ul&gt;
	&lt;li&gt;Les classes d'abstraction sont dans&amp;nbsp;Dotclear\Database,&lt;/li&gt;
	&lt;li&gt;Les interfaces dans Dotclear\Interface\Database&lt;/li&gt;
	&lt;li&gt;Les drivers dans Dotclear\Schema\Database&lt;/li&gt;
	&lt;li&gt;Les drivers sont ajoutés à un container dédié&lt;/li&gt;
	&lt;li&gt;Les drivers vérifient&amp;nbsp;l'installation&amp;nbsp;avant d'être proposés&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Une nouvelle méthode fait sont appartition dans le gestionnaire de connexion (driver), afin de tester que les conditions requises à son utilisation sont présentes. Sa définition est visible dans l'interface :&lt;/p&gt;

&lt;pre&gt;
&lt;code class=&quot;language-php&quot;&gt;/**
 * Check driver requirements.
 *
 * This method MUST throw a DatabaseException if driver can not be used.
 * This method does NOT say a SGBD is installed but only PHP supports it.
 *
 * @since   2.36
 *
 * @throws  \Dotclear\Exception\DatabaseException   if condition does not meet driver requirements
 */
public static function precondition(): void;&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Les drivers PDO&lt;/h3&gt;

&lt;p&gt;PDO est une extension de PHP signifiant PHP Data Objects, c'est une interface d'abstraction de l'accès à des bases de données, en d'autre termes cela doit simplifier l'accès à differents types de base de données depuis une application comme Dotclear. Jusqu'à la version 2.36 Dotclear n'utilisait PDO que pour la connexion à des bases de donnée Sqlite, depuis la version 2.36 il est possible de se connecter à des bases Mysql et PostgreSql à travers les drivers PDO. Les drivers de Dotclear utilisant PDO ne sont pour l'instant que des passerelles de connexion, toutes les fonctionnalités de PDO ne sont pas exploitées, Dotclear ayant déjà son propre système de préparation de requêtes.&lt;/p&gt;

&lt;p&gt;Par défaut sur les sytèmes Linux, PHP embarque l'extension PDO avec le pilote pour Sqlite, si ce n'est pas le cas,&amp;nbsp;&lt;a href=&quot;https://www.php.net/manual/fr/pdo.installation.php&quot; hreflang=&quot;fr&quot; title=&quot;Installer PDO&quot;&gt;le site de PHP&lt;/a&gt; fournira un peu d'aide à l'installation plus complète de PDO.&lt;/p&gt;

&lt;h3&gt;Le cas Sqlite&lt;/h3&gt;

&lt;p&gt;Le driver Sqlite de Dotclear était déjà basé sur PDO, il a simplement été renommé pour correspondre aux autres drivers. Il n'y a rien besoin de modifier, Dotclear se charge de comprendre que si vous avez définie le driver à &quot;&lt;strong&gt;sqlite&lt;/strong&gt;&quot; cela veut dire qu'il faut utiliser &quot;&lt;strong&gt;pdosqlite&lt;/strong&gt;&quot;.&amp;nbsp;&lt;/p&gt;

&lt;h3&gt;Les drivers livrés avec Dotclear&lt;/h3&gt;

&lt;ul&gt;
	&lt;li&gt;mysqli : Mysql avec les fonctions mysqli_*&amp;nbsp;de PHP&lt;/li&gt;
	&lt;li&gt;mysqlimb4 : Idem avec le support utf8-mb4&lt;/li&gt;
	&lt;li&gt;pgsql : PostgreSql avec les classes&amp;nbsp;PgSql&amp;nbsp;de PHP&lt;/li&gt;
	&lt;li&gt;pdosqlite : Sqlite sous PDO&lt;/li&gt;
	&lt;li&gt;pdomysql : Mysql sous PDO&lt;/li&gt;
	&lt;li&gt;pdomysqlmb4 : Mysql sous PDO avec support utf8-mb4&lt;/li&gt;
	&lt;li&gt;pdopgsql : PostgreSql sous PDO&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Lors de l'installation de Dotclear tous les drivers ayant un support dans la version installée de PHP seront proposés pour définir la connexion à la base de données.&lt;/p&gt;

&lt;h3&gt;Utiliser un driver PDO sur une installation existante&lt;/h3&gt;

&lt;p&gt;Si votre système embarque les composants PDO pour votre base de données, il est possible de passer sur les drivers PDO simplement en mettant à jour le fichier config.php, il faut remplacer la définiton de&amp;nbsp;DC_DBDRIVER par le nouveau driver. Et l'inverse est également vrai. Voici les equivalents :&lt;/p&gt;

&lt;ul&gt;
	&lt;li&gt;mysqli &amp;lt;=&amp;gt; pdomysql&lt;/li&gt;
	&lt;li&gt;mysqlimb4 &amp;lt;=&amp;gt; pdomysqlmb4&lt;/li&gt;
	&lt;li&gt;sqlite &amp;lt;=&amp;gt; pdosqlite&lt;/li&gt;
	&lt;li&gt;pgsql &amp;lt;=&amp;gt; pdopgsql&lt;/li&gt;
&lt;/ul&gt;

&lt;pre&gt;
&lt;code class=&quot;language-php&quot;&gt;// define('DC_DBDRIVER', 'mysqli');
define('DC_DBDRIVER', 'pdomysql');&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Auncune recommandation ici, rien ne vous oblige aujourd'hui à changer, ce ne sont que des drivers qui permettent le lien entre Dotclear et votre base de données et ils sont tous maintenus pour le moment.&lt;/p&gt;

&lt;h3&gt;Créer un driver&lt;/h3&gt;

&lt;p&gt;Pour l'exemple on va prendre un driver utilisant PDO. L'extension PDO de PHP n'est pas magique, chaque type de base de données à ses propres lois et chaque type est diffèrent. Néanmoins Dotclear propose un classe d'abstraction pour simplifier la création d'un driver de base de données utilisant PDO. Par exemple, si vous souhaiter commencer un driver pour MsSql voici ce à quoi ça pourrait ressembler.&lt;/p&gt;

&lt;p&gt;On ajoute notre service au container des drivers de base de données et on crée notre classe de service :&lt;/p&gt;

&lt;pre&gt;
&lt;code class=&quot;language-php&quot;&gt;&amp;lt;php

namespace /MySpace/PdoMsSql;

use Dotclear\Database\AbstractPdoHandler;
use Dotclear\Helper\Container\Container;
use Dotclear\Helper\Conttainer\Factories;

Factories::addService('database', 'pdomssql', PdoMsSql::class);

class PdoMsSql extends AbstractPdoHandler
{
    public const HANDLER_NAME   = 'MsSql (PDO)';
    public const HANDLER_DRIVER = 'pdomssql';
    public const HANDLER_SYNTAX = 'mssql';
    public const HANDLER_PDO    = 'sqlsrv';

    // ...
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Il faut ensuite modifier toutes les methodes qui demandent un ajustement par rapport au language MsSql et lui adjoindre un classe de Schema. Bon courage.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Il y aurait beaucoup à dire sur cette partie mais ce serait bien trop long. Les très rares personnes qui souhaiteraient créer leur propre driver de base de données sont sans aucun doute assez callées pour comprendre le code de Dotclear.&lt;/p&gt;</description>
        
                  <comments>https://dotclear.watch/Billet/%5B2.36%5D-Modification-du-service-de-base-de-donn%C3%A9es#comment-form</comments>
          <wfw:comment>https://dotclear.watch/Billet/%5B2.36%5D-Modification-du-service-de-base-de-donn%C3%A9es#comment-form</wfw:comment>
          <wfw:commentRss>https://dotclear.watch/feed/atom/comments/447</wfw:commentRss>
              </item>
          <item>
        <title>[2.36] Modification du service de configuration</title>
        <link>https://dotclear.watch/Billet/%5B2.36%5D-Modification-du-service-de-configuration</link>
        <guid isPermaLink="false">urn:md5:fe76d1f14369d7c8562bafb2d1d0cab2</guid>
        <pubDate>Tue, 02 Sep 2025 09:26:00 +0200</pubDate>
        <dc:creator>Jean-Christian Denis</dc:creator>
                  <category>2.36</category>
                          <category>2.36</category>
                  <category>configuration</category>
                  <category>service</category>
                <description>&lt;p&gt;Avec l'arrivé des authentifications exotiques, de nouvelles directives sont disponibles dans la configuration de Dotclear 2.36&lt;/p&gt; &lt;p&gt;&lt;a class=&quot;ref-post&quot; href=&quot;https://dotclear.watch/Billet/2.36&quot; title=&quot;Article rédigé pour Dotclear 2.36&quot;&gt;&lt;img alt=&quot;badge Dotclear 2.36&quot; src=&quot;https://img.shields.io/badge/Dotclear-2.36-blue?style=for-the-badge&quot; /&gt; &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dotclear 2.36 propose une librairie oAuth2 client qui permet l'authentification depuis des applications tierces, cette librairie a besoin d'un fichier de configuration commun à toute la plateforme multiblogs. Ce fichier suit des régles strictes, il doit se nommer oauth2.php et être présent dans le même répertoire que le config.php.&lt;/p&gt;

&lt;p&gt;Dans diffèrentes parties de Dotclear ou même de plugins, il y aura besoin de connaitre le chemin de ce fichier, on peut alors simplement récupérer son chemin complet comme suit :&lt;/p&gt;

&lt;pre&gt;
&lt;code class=&quot;language-php&quot;&gt;$path = App::config()-&amp;gt;oauth2Path();&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Dans diffèrentes parties de Dotclear ou même de plugins, il y aura besoin de savoir si ce fichier existe, on peut alors tester simplement comme suit :&lt;/p&gt;

&lt;pre&gt;
&lt;code class=&quot;language-php&quot;&gt;$exists = App::config()-&amp;gt;hasOauth2();&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;oAuth2 n'est pas la seule nouvelle librairie d'authentification tiers, il y a également Webauthn (clé de sécurité) et OTP (Mot de passe à usage unique). Il est possible de désactiver toutes ces authentifiactions exotiques depuis le fichier de configuration de Dotclear, il suffit d'ajouter la définition suivante :&lt;/p&gt;

&lt;pre&gt;
&lt;code class=&quot;language-php&quot;&gt;define('DC_AUTH_PASSWORD_ONLY', true);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Pour les plugins, li est possible de connaitre l'état de cette directive afin de désactiver certaines de leurs fonctions avec :&lt;/p&gt;

&lt;pre&gt;
&lt;code class=&quot;language-php&quot;&gt;$limited = App:config()-&amp;gt;authPasswordOnly();&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;.&lt;/p&gt;</description>
        
                  <comments>https://dotclear.watch/Billet/%5B2.36%5D-Modification-du-service-de-configuration#comment-form</comments>
          <wfw:comment>https://dotclear.watch/Billet/%5B2.36%5D-Modification-du-service-de-configuration#comment-form</wfw:comment>
          <wfw:commentRss>https://dotclear.watch/feed/atom/comments/444</wfw:commentRss>
              </item>
          <item>
        <title>Le conteneur principal</title>
        <link>https://dotclear.watch/Billet/Le-conteneur-principal-en-2.28</link>
        <guid isPermaLink="false">urn:md5:42dc775565c5a181f7b6d9a55cd1fc07</guid>
        <pubDate>Fri, 13 Oct 2023 08:00:00 +0200</pubDate>
        <dc:creator>Jean-Christian Denis</dc:creator>
                  <category>2.28</category>
                          <category>app</category>
                  <category>container</category>
                  <category>factory</category>
                  <category>interface</category>
                  <category>service</category>
                <description>&lt;p&gt;La &lt;a href=&quot;https://dotclear.watch/Billet/Release-2.28&quot;&gt;version 2.28&lt;/a&gt; de Dotclear intégre un nouveau système de conteneur pour l'application qui remplace dcCore.&lt;/p&gt; &lt;p&gt;Grâce aux avancées de &lt;a href=&quot;https://dotclear.watch/Billet/Release-2.27&quot;&gt;Dotclear 2.27&lt;/a&gt;, cette nouvelle version 2.28 peut désormais proposer l'accès à la quasi totalité de l'application à partir d'un seul point &lt;strong&gt;App::&lt;/strong&gt;. Le core, aka dcCore, &lt;a href=&quot;https://dotclear.watch/Billet/Les-d%C3%A9pr%C3%A9ci%C3%A9s-du-core-en-2.28&quot;&gt;passe en déprécié&lt;/a&gt; et ses méthodes et propriétés sont regroupées dans des classes dédiées à un ensemble de tâches de même style. Une nouvelle gestion par conteneur et services accompagnée d'un nouvelle gestion d'exception permet de proposer ces classes à tout moment sans avoir besoin de les instancier. Autre nouveauté de taille qui pourra être exploitée par la suite, ces classes deviennent remplaçables ! Ce qui devra être utilisé pour des classes d'authentification ou de connexion tiers par exemple.&lt;br /&gt;
&lt;br /&gt;
Pour résumer, voici deux exemples simples de la nouvelle façon d'appeler les classes de l'ancien dcCore :&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;// Avant 2.28 :
dcCore::app()-&amp;gt;auth-&amp;gt;use_prefs;
// A partir 2.28, dcAuth fait partie du conteneur et ses propriétés deviennent des méthodes :
App::auth()-&amp;gt;prefs();

// Avant 2.28 :
dcCore::app()-&amp;gt;getAllBlogStatus();
// A partir de 2.28 les méthodes de l&amp;#039;ancien dcCore sont regroupées dans des classes à thème :
App::blogs()-&amp;gt;getAllBlogStatus();&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Voici la liste complète des classes composants ce nouveau Core de Dotclear :&lt;br /&gt;&lt;/p&gt;

&lt;h5&gt;Configuration&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;App::config(): ConfigInterface&lt;/code&gt;&lt;br /&gt;
Cette classe est une nouveauté de dotclear 2.28, elle regroupe toutes les informations de &lt;a href=&quot;https://dotclear.watch/Billet/Configuration-de-l-application-en-2.28&quot;&gt;configuration de l'application&lt;/a&gt;.&lt;br /&gt;&lt;/p&gt;

&lt;h5&gt;Authentification&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;App::auth(): AuthInterface&lt;/code&gt;&lt;br /&gt;
&lt;del&gt;dcCore::app()-&amp;gt;auth&lt;/del&gt;&lt;br /&gt;
Anciennement dcAuth, c'est la classe de gestion de l'utilisateur.&lt;br /&gt;
Deux nouvelles méthodes sont disponibles :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;openUserCursor(): Cursor&lt;/code&gt; : renvoie un Cursor sur la table des utilisateurs&lt;/li&gt;
&lt;li&gt;&lt;code&gt;openPermCursor(): Cursor&lt;/code&gt; : renvoie un Cursor sur la table des permissions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;L'utilisation d'une classe tiers d'authentification est encore permise en 2.28, mais il faudra utiliser le nouveau système de remplacement de classe par la suite.&lt;br /&gt;&lt;/p&gt;

&lt;h5&gt;Comportement&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;App::behavior(): BehaviorInterface&lt;/code&gt;&lt;br /&gt;
&lt;del&gt;dcCore::app()-&amp;gt;xxxBehaviorxxx(xxx)&lt;/del&gt;&lt;br /&gt;
Nouvelle classe de la version 2.28, elle regroupe toutes les méthodes dépréciées de dcCore en rapport aux behaviors.&lt;br /&gt;
L'ancienne méthode &lt;strong&gt;getBehaviors()&lt;/strong&gt; est dédoublée :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;getBehavior(string $behavior): array&lt;/code&gt; : renvoie un groupe de behaviors,&lt;/li&gt;
&lt;li&gt;&lt;code&gt;getBehaviors(): array&lt;/code&gt; : renvoie tous les behaviors&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;Blog&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;App::blog(): BlogInterface&lt;/code&gt;&lt;br /&gt;
&lt;del&gt;dcCore::app()-&amp;gt;blog, new dcBLog()&lt;/del&gt;&lt;br /&gt;
Anciennement dcBlog, c'est la classe de gestion du blog courant. Cette classe subit des changements majeures dans son utilisation.&lt;br /&gt;
Désormais cette classe existe toujours dans l'application. Il ne faut plus tester le chargement du blog avec &lt;strong&gt;!is_null(dcCore::app()-&amp;gt;blog)&lt;/strong&gt; mais &lt;code&gt;App::blog()-&amp;gt;isDefined()&lt;/code&gt;.&lt;br /&gt;
Il ne faut plus créer une nouvelle instance de dcBlog lorsqu'on veut naviguer entre deux blogs en cours de script, Il faut partir de l'instance existante et charger un autre blog dedans, puis recharger le premier si besoin. On peut mettre en id vide pour décharger un blog.&lt;br /&gt;
Une nouvelle méthode est donc disponible :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;App::blog()-&amp;gt;loadFromBlog(string $blog_id): BlogInterface&lt;/code&gt; : renvoie l'instance de Blog chargé d'un autre blog&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Exemple de chargement :&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;// On récupère l&amp;#039;ID de blog courant
$old_id = App::blog()-&amp;gt;id();
// On charge le blog qu&amp;#039;on souhaite modifier
App::blog()-&amp;gt;loadFromBlog(&amp;#039;SecondBlog&amp;#039;);
// On le modifie
App::blog()-&amp;gt;triggerBlog();
// On recharge le blog courant
App::blog()-&amp;gt;loadFromBlog($old_id);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;De nouvelles méthodes sont disponibles :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;openBlogCursor(): Cursor&lt;/code&gt; : Ouvre un Cursor sur la table blog&lt;/li&gt;
&lt;li&gt;&lt;code&gt;openPostCursor(): Cursor&lt;/code&gt; : Ouvre un Cursor sur la table post&lt;/li&gt;
&lt;li&gt;&lt;code&gt;openCommentCursor(): Cursor&lt;/code&gt; : Ouvre un Cursor sur la table comment&lt;/li&gt;
&lt;li&gt;&lt;code&gt;isDefined(): bool&lt;/code&gt; : Vérifie si un blog est chargé dans la classe ou non&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Les propriétés publiques de la classe passent en déprécié, il faut désormais utiliser les méthodes idoines :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;dcCore::app()-&amp;gt;blog-&amp;gt;id : &lt;code&gt;App::blog()-&amp;gt;id(): string&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;dcCore::app()-&amp;gt;blog-&amp;gt;uid : &lt;code&gt;App::blog()-&amp;gt;uid(): string&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;dcCore::app()-&amp;gt;blog-&amp;gt;name : &lt;code&gt;App::blog()-&amp;gt;name(): string&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;dcCore::app()-&amp;gt;blog-&amp;gt;desc : &lt;code&gt;App::blog()-&amp;gt;desc(): string&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;dcCore::app()-&amp;gt;blog-&amp;gt;url : &lt;code&gt;App::blog()-&amp;gt;url(): string&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;dcCore::app()-&amp;gt;blog-&amp;gt;host : &lt;code&gt;App::blog()-&amp;gt;host(): string&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;dcCore::app()-&amp;gt;blog-&amp;gt;creadt : &lt;code&gt;App::blog()-&amp;gt;creadt(): int&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;dcCore::app()-&amp;gt;blog-&amp;gt;upddt : &lt;code&gt;App::blog()-&amp;gt;upddt(): int&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;dcCore::app()-&amp;gt;blog-&amp;gt;status : &lt;code&gt;App::blog()-&amp;gt;status(): int&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;dcCore::app()-&amp;gt;blog-&amp;gt;settings : &lt;code&gt;App::blog()-&amp;gt;settings(): BlogSettingsInterface&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;dcCore::app()-&amp;gt;blog-&amp;gt;themes_path : &lt;code&gt;App::blog()-&amp;gt;themesPath(): string&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;dcCore::app()-&amp;gt;blog-&amp;gt;pblic_path : &lt;code&gt;App::blog()-&amp;gt;publicPath(): string&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;Paramètres de blog&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;App::blogSettings(): BlogSettingsInterface&lt;/code&gt;&lt;br /&gt;
&lt;del&gt;dcCore::app()-&amp;gt;blog-&amp;gt;settings, new dcSettings();&lt;/del&gt;&lt;br /&gt;
Anciennement dcSettings, c'est la classe de gestion des paramètres de blog. Cette classe subit également un changement majeur dans son utilisation. Pour créer une nouvelle instance de BlogSettings, il faut utiliser une nouvelle méthode de la classe qui renverra une instance prête à l'emploie :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;App::blogSettings()-&amp;gt;createFromBlog(?string $blog_id): BlogSettingsInterface&lt;/code&gt; : renvoie une nouvelle instance de BlogSettings.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On peut également utiliser &lt;code&gt;App::blog()-&amp;gt;settings()-&amp;gt;createFromBlog(?string $blog_id)&lt;/code&gt;.&lt;br /&gt;
Ses méthodes en xxxNamespace() passent en déprécié, il faut utiliser leurs méthodes associées xxxWorkspace().&lt;br /&gt;&lt;/p&gt;

&lt;h5&gt;Espace de paramètres de blog&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;App::blogWorspace(), App::blog()-&amp;gt;settings()-&amp;gt;get(xxx), App::blog()-&amp;gt;settings()-&amp;gt;addWorspace(xxx)&lt;/code&gt;&lt;br /&gt;
Comme la classe précédente une nouvelle méthode fait son apparition pour créer une nouvelle instance de BlogWorkspace :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;App::blogWorkspace()-&amp;gt;createFromBlog(?string $blog_id, string $workspace, ?MetaRecord $rs = null): BlogWorkspaceInterface&lt;/code&gt; : renvoie une nouvelle instance de BlogWorkspace.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Une nouvelle méthode est disponible :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;openBlogWorkspaceCursor(): Cursor&lt;/code&gt; : renvoie un Cursor sur la table des espaces de paramètres de blog&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;La méthode dumpNamespace() passe en déprécié, il faut utiliser dumpWorkspace().&lt;/p&gt;

&lt;h5&gt;Blogs&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;App:blogs()&lt;/code&gt;&lt;br /&gt;
&lt;del&gt;dcCore::app()-&amp;gt;xxxBlogsxxx()&lt;/del&gt;&lt;br /&gt;
Nouvelle classe de la version 2.28, elle regroupe toutes les tâches en rapport à la gestion des blogs.&lt;br /&gt;
Changement par rapport à la version 2.27, la méthode getBlog() renverra toujours une instance de Blog. Ceci est dû au changement de comportement de la classe Blog.&lt;br /&gt;&lt;/p&gt;

&lt;h5&gt;Cache&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;App:cache()&lt;/code&gt;&lt;br /&gt;
&lt;del&gt;dcCore::app()-&amp;gt;emptyTemplatesCache(), dcCore::app()-&amp;gt;cache&lt;/del&gt;&lt;br /&gt;
Nouvelle classe de la version 2.28, Elle inclue une méthode de l'ancien core :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;emptyTemplatesCache(): void&lt;/code&gt; : vide le cache des templates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Et une nouvelle méthode pour le cache des dépôts de modules :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;emptyModulesStoreCache(): void&lt;/code&gt; : vide le cache des dépôts tiers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Elle remplace également la gestion des fichiers et timestamps utilisés pour le cache coté public et qui était dans un simple tableau dcCore::app()-&amp;gt;cache :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;resetFiles(): void&lt;/code&gt; : Raz de la litses des fichiers&lt;/li&gt;
&lt;li&gt;&lt;code&gt;addFile(string $file): void&lt;/code&gt; : Ajoute un fichier&lt;/li&gt;
&lt;li&gt;&lt;code&gt;addFiles(array $files): void&lt;/code&gt; : Ajoute plusieurs fichiers&lt;/li&gt;
&lt;li&gt;&lt;code&gt;getFiles(): array&lt;/code&gt; : Renvoie la liste des fichiers&lt;/li&gt;
&lt;li&gt;&lt;code&gt;function resetTimes(): void&lt;/code&gt; : Raz des timestamps&lt;/li&gt;
&lt;li&gt;&lt;code&gt;addTime(int $time): void&lt;/code&gt; : Ajoute un timestamp&lt;/li&gt;
&lt;li&gt;&lt;code&gt;addTimes(array $times): void&lt;/code&gt; : Ajoute plusieurs timestamps&lt;/li&gt;
&lt;li&gt;&lt;code&gt;getTimes(): array&lt;/code&gt; : Renvoie la listes des timestamps&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;Catégories&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;App::categories(), App::blog()-&amp;gt;categories()&lt;/code&gt;&lt;br /&gt;
&lt;del&gt;dcCore::app()-&amp;gt;blog-&amp;gt;categories, new dcCategories()&lt;/del&gt;&lt;br /&gt;
Anciennement dcCategories, c'est la classe de gestion des catégories d'un blog. Elle inclut désormais la classe NestedTree.&lt;br /&gt;
Comme vu sur de précédentes classes une nouvelle méthode fait son apparition pour créer une nouvelle instance de Categories :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;App::blog()-&amp;gt;categories()-&amp;gt;createFromBlog(string $blog_id): CategoriesInterface&lt;/code&gt; : renvoie une nouvelle instance de Categories.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Une nouvelle méthode est disponible :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;openCategoryCursor(): Cursor&lt;/code&gt; : renvoie un Cursor sur la table des catégories&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Toutes les propriétés de la classe passent en &lt;em&gt;protected&lt;/em&gt;.&lt;br /&gt;&lt;/p&gt;

&lt;h5&gt;Connexion&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;App::con()&lt;/code&gt;&lt;br /&gt;
&lt;del&gt;dcCore::app()-&amp;gt;con&lt;/del&gt;&lt;br /&gt;
Nouvelle classe de la version 2.28, elle permet le lien entre l'ancien chargement de gestionnaire de base de donnée et le nouveau système de chargement des classes du Core.
L'utilisation d'une classe tiers de connexion est encore permise en 2.28, mais il faudra utiliser le nouveau système remplacement de classe par la suite.&lt;br /&gt;
Elle inclut désormais le préfixe des tables disponibles en faisant &lt;code&gt;App::con()-&amp;gt;prefix()&lt;/code&gt;.&lt;br /&gt;&lt;/p&gt;

&lt;h5&gt;Déprécié&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;App:deprecated()&lt;/code&gt;&lt;br /&gt;
Cette classe est disponible dans le Core ou en version statique. Elle permet de loguer en mode DEV d'éventuelles méthodes dépréciées.&lt;br /&gt;&lt;/p&gt;

&lt;h5&gt;Erreur&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;App::error()&lt;/code&gt;&lt;br /&gt;
&lt;del&gt;dcCore::app()-&amp;gt;error&lt;/del&gt;&lt;br /&gt;
C'est la classe de gestion d'erreur non bloquante du Core.&lt;br /&gt;
Sa méthode &lt;strong&gt;toHTML()&lt;/strong&gt; passe en dépréciée, il faut utiliser votre propre parser à la place.&lt;br /&gt;&lt;/p&gt;

&lt;h5&gt;Filtre&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;App::filter()&lt;/code&gt;&lt;br /&gt;
&lt;del&gt;dcCore::app()-&amp;gt;wiki, dcCore::app()-&amp;gt;xxxWikiXxx(), dcCore::app()-&amp;gt;HTMLfilter()&lt;/del&gt;&lt;br /&gt;
Nouvelle classe de la version 2.28, elle regroupe toutes les méthodes et propriétés dédiées à la syntaxe wiki et HTML de texte.&lt;br /&gt;&lt;/p&gt;

&lt;h5&gt;Formateur&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;App:formater()&lt;/code&gt;&lt;br /&gt;
&lt;del&gt;dcCore::app()-&amp;gt;xxxFormaterXxx()&lt;/del&gt;-&lt;br /&gt;
Nouvelle classe de la version 2.28 elle regroupe toutes les méthodes de gestion des formateurs de texte.&lt;br /&gt;&lt;/p&gt;

&lt;h5&gt;Langue&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;App::lang()&lt;/code&gt;&lt;br /&gt;
&lt;del&gt;dcCore::app()-&amp;gt;lang&lt;/del&gt;&lt;br /&gt;
Nouvelle classe de la version 2.28, elle s'occupe de la langue courante.&lt;br /&gt;
Deux méthodes sont disponibles :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;getLang(): string&lt;/code&gt; : renvoie le code de la langue courante&lt;/li&gt;
&lt;li&gt;&lt;code&gt;setLang(string $lang): void&lt;/code&gt; : enregistre le code de la langue courante.&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;Lexique&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;App::lexical()&lt;/code&gt;&lt;br /&gt;
&lt;del&gt;dcUtils::xxxlexicalxxx()&lt;/del&gt;&lt;br /&gt;
Nouvelle classe de la version 2.28, elle regroupe toutes les méthodes en rapport au champs lexical d'une langue.&lt;br /&gt;&lt;/p&gt;

&lt;h5&gt;Log&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;App::log()&lt;/code&gt;&lt;br /&gt;
&lt;del&gt;dcCore::app()-&amp;gt;log&lt;/del&gt;&lt;br /&gt;
Anciennement dcLog, cette classe s'occupe de la gestion de log.&lt;br /&gt;
Une nouvelle méthode est disponible :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;openLogCursor(): Cursor&lt;/code&gt; : Ouvre un Cursor sur la table de log&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;L'ancienne méthode &lt;strong&gt;getTable()&lt;/strong&gt; passe en dépréciée, il faut utiliser la constante de classe disponible sur &lt;code&gt;App::log()::LOG_TABLE_NAME&lt;/code&gt;.&lt;br /&gt;&lt;/p&gt;

&lt;h5&gt;Média&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;App::media()&lt;/code&gt;&lt;br /&gt;
&lt;del&gt;dcCore::app()-&amp;gt;media&lt;/del&gt;&lt;br /&gt;
Anciennement &lt;strong&gt;dcMedia&lt;/strong&gt;, cette classe s'occupe de la gestion des média et comme vu précédemment, il ne faut plus créer une instance de &lt;strong&gt;dcMedia&lt;/strong&gt; mais toujours utiliser celle du &lt;strong&gt;Core&lt;/strong&gt;.&lt;br /&gt;
Pour définir le type de media, auparavant dans son constructeur, il faut utiliser la nouvelle méthode :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;setFilterMimeType(string $type): void&lt;/code&gt; : définit le type de media&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ses propriétés publiques deviennent dépréciées, il faut par exemple utiliser la méthode :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;getThumbnailFilePattern(string $type = ''): string&lt;/code&gt; : renvoie la définition d'un pattern.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;D'autres nouvelles méthodes sont disponibles :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;openMediaCursor(): Cursor&lt;/code&gt; : ouvre un Cursor sur la table des média&lt;/li&gt;
&lt;li&gt;&lt;code&gt;postMedia(): PostMediaInterface&lt;/code&gt; : retourne l'instance de PostMedia&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;Métadonnée&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;App::meta()&lt;/code&gt;&lt;br /&gt;
&lt;del&gt;dcCore::app()-&amp;gt;meta&lt;/del&gt;&lt;br /&gt;
Anciennement &lt;strong&gt;dcMeta&lt;/strong&gt;, cette classe gère les métadonnées de dotclear.&lt;br /&gt;
Une nouvelle méthode est disponible :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;openMetaCursor(): Cursor&lt;/code&gt; : ouvre un Cursor sur la table des métadonnées&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;Nonce&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;App::nonce()&lt;/code&gt;&lt;br /&gt;
Nouvelle classe de la version 2.28, elle regroupe les méthodes en rapport à la validation de formulaires.&lt;br /&gt;
L'ancienne méthode &lt;strong&gt;formNonce()&lt;/strong&gt; est dédoublée :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;getFormNonce(): string&lt;/code&gt; : renvoie le contenu HTML&lt;/li&gt;
&lt;li&gt;&lt;code&gt;formNonce(): Hidden&lt;/code&gt; : renvoie l'élément de Form de type Hidden&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;Notification&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;App::notice()&lt;/code&gt;&lt;br /&gt;
&lt;del&gt;dcCore::app()-&amp;gt;notices&lt;/del&gt;&lt;br /&gt;
Anciennement &lt;strong&gt;dcNotices&lt;/strong&gt;, cette classe gère en base les notices.&lt;br /&gt;
Une nouvelle méthode est disponible :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;openNoticeCursor(): Cursor&lt;/code&gt; : ouvre un Cursor sur la table des notifications&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;Media de billets&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;App:postMedia(), App::media()-&amp;gt;postMedia()&lt;/code&gt;&lt;br /&gt;
&lt;del&gt;dcCore::app()-&amp;gt;postmedia&lt;/del&gt;&lt;br /&gt;
Anciennement &lt;strong&gt;dcPostMedia&lt;/strong&gt;, cette classe gère les media de billets.&lt;br /&gt;
Une nouvelle méthode est disponible :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;openPostMediaCursor(): Cursor&lt;/code&gt; : ouvre un Cursor sur la table des media de billets&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Les constantes des noms des tables de media et post media sont disponibles dans cette classe :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;App::postMedia()::MEDIA_TABLE_NAME&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;App::postMedia()::POST_MEDIA_TABLE_NAME&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A noter que lorsqu'un blog est chargé dans la classe &lt;strong&gt;Blog&lt;/strong&gt; via &lt;code&gt;App::blog()-&amp;gt;loadFromBlog()&lt;/code&gt;, il est également chargé dans l'instance de la classe &lt;strong&gt;PostMedia&lt;/strong&gt;.&lt;br /&gt;&lt;/p&gt;

&lt;h5&gt;Type de billets&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;App::postTypes()&lt;/code&gt;&lt;br /&gt;
&lt;del&gt;dcCore::app()-&amp;gt;getPostxxxURL(), dcCore::app()-&amp;gt;xxxPostType()&lt;/del&gt;&lt;br /&gt;
Nouvelle classe de la version 2.28, elle regroupe les méthodes en relation aux types de billets.&lt;br /&gt;
Les anciennes méthodes sont toujours utilisables mais il est recommandé d'utiliser l'autre nouvelle classe de définition d'un type de billet &lt;strong&gt;PostType&lt;/strong&gt;. (cf billet sur dcCore déprécié)&lt;br /&gt;&lt;/p&gt;

&lt;h5&gt;Service REST&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;App::rest()&lt;/code&gt;&lt;br /&gt;
&lt;del&gt;dcCore::app()-&amp;gt;xxxRestXxx()&lt;/del&gt;&lt;br /&gt;
Nouvelle classe de la version 2.28, elle regroupe les méthodes relatives au service REST.&lt;br /&gt;&lt;/p&gt;

&lt;h5&gt;Session&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;App::session()&lt;/code&gt;&lt;br /&gt;
Nouvelle classe de la version 2.28, elle adapte l'ancienne classe de gestion de session à la nouvelle gestion de classe de Core.&lt;br /&gt;
Une nouvelle méthode est disponible pour créer simplement une nouvelle session à partir d'un nom de cookie (pratique pour les plugins et thèmes) :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;App::session()-&amp;gt;createFromCookieName(string $cookie_name): SessionInterface&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;Rétroliens&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;App::trackback()&lt;/code&gt;&lt;br /&gt;
Anciennement &lt;strong&gt;dcTrackback&lt;/strong&gt;, cette classe gère les rétroliens et pingback.&lt;br /&gt;
Une nouvelle méthode est disponible :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;openTrackbackCursor(): Cursor&lt;/code&gt; : ouvre un Cursor sur la table des rétroliens&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;Préférences utilisateur&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;App::userPrerefences()&lt;/code&gt;&lt;br /&gt;
Anciennement &lt;strong&gt;dcPrefs&lt;/strong&gt;, cette classe gère les préférences utilisateur. Elle est disponible pour l'utilisateur en cours dans &lt;code&gt;App::auth()-&amp;gt;prefs()&lt;/code&gt;.
Comme nombre de classes de Core, cette classe est toujours disponible et instanciée dans App::userPreferences(), pour avoir une nouvelle instance il faut donc utiliser sa méthode :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;createFromUser(string $user_id, ?string $user_workspace = null): UserPreferencesInterface&lt;/code&gt; : Créé une nouvelle instance des préférences utilisateur&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;Espace de préférences utilisateur&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;App::userWorkspace(), App::auth()-&amp;gt;perfs()-&amp;gt;get(xxx), App::auth()-&amp;gt;prefs()-&amp;gt;addWorspace(xxx)&lt;/code&gt;&lt;br /&gt;
Comme la classe précédente une nouvelle méthode fait son apparition pour créer une nouvelle instance de UserWorkspace :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;createFromUser(?string $user_id, string $workspace, ?MetaRecord $rs = null): UserWorkspaceInterface&lt;/code&gt; : renvoie une nouvelle instance de UserWorkspace.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Une nouvelle méthode est disponible :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;openUserWorkspaceCursor(): Cursor&lt;/code&gt; : renvoie un Cursor sur la table des espaces de préférences utilisateur&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;Utilisateurs&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;App::users()&lt;/code&gt;&lt;br /&gt;
Nouvelle classe de la version 2.28, elle regroupe toutes les méthodes relatives aux utilisateurs.&lt;br /&gt;&lt;/p&gt;

&lt;h5&gt;Versions&lt;/h5&gt;

&lt;p&gt;&lt;code&gt;App::version()&lt;/code&gt;&lt;br /&gt;
&lt;del&gt;dcCore::app()-&amp;gt;xxxVersionXxx()&lt;/del&gt;&lt;br /&gt;
Nouvelle classe de la version 2.28, elle gère les version de module (et core) en base.&lt;br /&gt;
Une nouvelle méthode est disponible :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;openVersionCursor(): Cursor&lt;/code&gt; : ouvre un Cursor sur la table des versions&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;Autres&lt;/h5&gt;

&lt;p&gt;De plugs certaines classes plus spéciales sont accessibles depuis App::xxx() :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;App::backend()&lt;/code&gt; : Gestion de l'interface d'administration&lt;/li&gt;
&lt;li&gt;&lt;code&gt;App::frontend()&lt;/code&gt; : Gestion de l'interface publique&lt;/li&gt;
&lt;li&gt;&lt;code&gt;App::url()&lt;/code&gt; : Anciennement &lt;strong&gt;dcUrlHandler&lt;/strong&gt; de dcCore::app()-&amp;gt;url&lt;/li&gt;
&lt;li&gt;&lt;code&gt;App::task()&lt;/code&gt; : Uniquement utilisé par les plugins et thèmes pour tester le contexte avec &lt;code&gt;App::task()-&amp;gt;checkContext(...)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;En savoir plus&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://dotclear.watch/Billet/Les-d%C3%A9pr%C3%A9ci%C3%A9s-du-core-en-2.28&quot;&gt;dcCore déprécié&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;
&lt;em&gt;&lt;q&gt;Le contenu de ce document a été écrit suivant le code de la version 2.28 de Dotclear.&lt;/q&gt;&lt;/em&gt;&lt;/p&gt;</description>
        
              </item>
      </channel>
</rss>
