Migration depuis PrototypePhp
Installer CodeIgniter et Ppci
Créez un dossier différent de celui qui contient le code initial de l’application à migrer, par exemple app2
, puis, depuis le répertoire de niveau inférieur :
composer create-project codeigniter4/appstarter app2
cd app2
composer require equinton/ppci
vendor/equinton/ppci/install/install.sh
Éditez ensuite le fichier .env
, et mettez à jour les paramètres nécessaires (CI_ENVIRONMENT
, app.baseURL
et les paramètres de connexion à la base de données).
Créer un nouveau vhost dans Apache
Voici un exemple de configuration :
<VirtualHost *:80>
app2.local
ServerName /app2.local
ServerPathRewriteEngine On
^ https://app2.local%{REQUEST_URI} [R]
RewriteRule</VirtualHost>
<VirtualHost *:443>
app2.local
ServerName /app2.local
ServerPathSSLEngine on
/etc/ssl/certs/server.crt
SSLCertificateFile /etc/ssl/private/server.key
SSLCertificateKeyFile /etc/ssl/certs/cacert.crt
SSLCACertificateFile /var/www/app2/public
DocumentRoot</VirtualHost>
<Directory /var/www/app2/public>
<LimitExcept GET POST>
from all
Deny</LimitExcept>
Options -Indexes FollowSymLinks MultiViews
unset ETag
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate, private"
Header set Pragma "no-cache"
Header set X-Frame-Options "DENY"
Header set X-XSS-Protection "1; mode=block"
Header set X-Content-Type-Options "nosniff"
Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains;"
Header always set Content-Security-Policy "default-src 'self' ; script-src blob: * 'self' 'unsafe-inline' 'unsafe-eval'; connect-src data: blob: filesystem: *.tile.openstreetmap.org 'self' ; img-src 'self' data: blob: *.openstreetmap.org ; style-src 'self' 'unsafe-inline' ;"
Header<FilesMatch "\.(ico|flv|jpg|jpeg|png|gif|js|css|svg)$">
set Cache-Control "max-age=604800, private"
Header</FilesMatch>
<FilesMatch ".*openstreetmap.*\.png$">
set Cache-Control "max-age=2592000, public"
Header</FilesMatch>
all granted
RequireAllowOverride all
RewriteEngine On
/
RewriteBase "/%{REQUEST_FILENAME}" !-f
RewriteCond "/%{REQUEST_FILENAME}" !-d
RewriteCond "(.*)" "/index.php?$1" [PT,QSA]
RewriteRule</Directory>
Mettre à jour la base de données
Éditez le fichier vendor/equinton/ppci/migration/updatedb.sql
, et vérifiez la première ligne (set search_path), en remplaçant app par le nom du schéma contenant les données.
Exécutez ensuite le fichier sql.
Ajouter les modèles Smarty
Recopiez les modèles Smarty depuis display/templates
dans app/Views/templates
en conservant l’organisation en sous-dossiers, à l’exception des fichiers à la racine et du sous-dossier framework.
Modifications globales
Dans ce dossier, remplacez tous les libellés (filtre sur *tpl) :
</form>
par{$csrf}</form>
pour ajouter le jeton CSRF dans les formulairesdroits
parrights
.gestion
par.manage
datatable"
pardatatable display"
datatable-nopaging-nosearching"
pardatatable-nopaging-nosearching display"
datatable-searching"
pardatatable-searching display"
datatable-nopaging"
pardatatable-nopaging display"
datatable-nopaging-nosort"
pardatatable-nopaging-nosort display"
datatable-nosort"
pardatatable-nosort display"
datatable-export"
pardatatable-export display"
datatable-export-paging"
pardatatable-export-paging display"
Supprimez
index.php?module=
Modifications dans chaque formulaire
Reprenez tous les liens (recherchez les balises a href
) et remplacez le premier &
par ?
Modifiez toutes les actions des formulaires, pour qu’ils aient cette forme :
<form class="form-horizontal" id="formName" method="post" action="moduleWrite">
<input type="hidden" name="moduleBase" value="module">
Le champ action
peut être supprimé. Par contre, le champ moduleBase
doit être conservé : il est utilisé pour créer l’action moduleDelete
par l’intermédiaire du script javascript dans main_js.tpl
.
Réécriture des modèles
Recopier les fichiers depuis modules/classes
vers app/Models
.
Transformations globales
Elles peuvent être effectuées par rechercher/remplacer.
- remplacer :
<?php
par<?php namespace App\Models;use Ppci\Models\PpciModel;
, avec sauts de ligne ;extends ObjetBDD
parextends PpciModel
;(public function __construct().*)
parpublic function __construct()
, en cochant expression régulière ;$this->colonnes
par$this->fields
;function ecrire
parfunction write
function lire
parfunction read
parent::ecrire
parparent::write
(parent::__construct().*)
parparent::__construct()
, en cochant expression régulière ;$this->id_auto = 0
par$this->useAutoIncrement = false
auto_date = 0
parautoFormatDate = false
- supprimer :
$this->id_auto = 1;
$param["fullDescription"] = 1;
$this->param = $param;
Transformations individuelles
- renommer le nom du fichier, par exemple
espece.class.php
enEspece.php
; - dans les requêtes SQL, modifier les variables en rajoutant : à la fin :
:id
doit devenir:id:
; - pour les tables portant des données géographiques (champs avec type=4), modifier les requêtes ou créer les fonctions
lire()
pour ajouterst_astext()
pour les champs concernés ; - les transformations de dates pour les champs non présents dans la table doivent être réécrites selon ce schéma :
$this->dateFields[] = "peche_date";
$this->datetimeFields[] = "peche_datetime";
- si la fonction
utf8_encode
est utilisée, elle doit être remplacée par :
$data = mb_convert_encoding($data, 'UTF-8', 'ISO-8859-15, ISO-8859-1, Windows-1252');
La fonction traite indistinctement les chaînes ou les tableaux.
Réécriture des librairies
Recopier l’ensemble des modules dans app/Libraries
. Il faut les transformer en classes.
Transformations globales
Remplacer :
<?php
par :
<?php
namespace App\Libraries;
use Ppci\Libraries\PpciException;
use Ppci\Libraries\PpciLibrary;
use Ppci\Models\PpciModel;
class Xx extends PpciLibrary {
/**
* @var xx
*/
protected PpciModel $dataclass;
private $keyName;
function __construct()
{parent::__construct();
$this->dataclass = new XXX();
$keyName = "xxx_id";
if (isset($_REQUEST[$this->keyName])) {
$this->id = $_REQUEST[$this->keyName];
} }
dataRead($dataclass,
par$this->dataRead(
dataDelete($dataclass,
par$this->dataDelete(
case "list":
parfunction list(){$vue=service('Smarty');
(saut de ligne)case "display":
parfunction display(){$vue=service('Smarty');
(saut de ligne)case "change":
parfunction change(){$vue=service('Smarty');
(saut de ligne)case "write":
par
function write() {
try {
$this->id = $this->dataWrite($_REQUEST);
if ($this->id > 0) {
$_REQUEST[$this->keyName] = $this->id;
return $this->display();
else {
} return $this->change();
}catch (PpciException) {
} return $this->change();
} }
case "delete":
parfunction delete(){
case "
parfunction
":
par() {
break;
par}
: fermeture des fonctions$dataclass
par$this->dataclass
$id
par$this->id
$vue
par$this->vue
$this->dataDelete($this->id);
par
try {
$this->dataDelete($this->id);
return $this->list();
catch (PpciException $e) {
} return $this->change();
}
$this->dataWrite( $_REQUEST );
par
try {
$this->id = $this->dataWrite($_REQUEST);
$_REQUEST["xx_id"] = $this->id;
return $this->list();
catch (PpciException $e) {
} return $this->change();
}
$message->
par$this->message->
et suppression de :
switch ($t_module["param"]) {
$bdd, $ObjetBDDParam
Modifications individuelles
- renommer le fichier en le commençant par une majuscule
- Modifier la fonction
__construct()
pour charger la bonne classe et le bon identifiant - définir les vues autres que Smarty dans les fonctions
- définir le retour attendu de chaque fonction :
- soit ajouter la commande
return $this->vue->send();
pour déclencher l’affichage - soit renvoyer vers une des fonctions de la classe :
return $this->display();
- soit renvoyer vers la page d’accueil :
defaultPage();
- soit ajouter la commande
Traitement des transactions
Remplacer :
$bdd->beginTransaction();
par :
$db = $this->dataclass->db;
$db->transBegin();
- supprimer
$bdd->commit();
by$db->transCommit();
- remplacer
$bdd->rollback();
par :
if ($db->transEnabled) {
$db->transRollback();
}
Générer les routes et les droits nécessaires pour exécuter les modules
Exécutez la commande suivante :
php vendor/equinton/ppci/migration/actionsParse.php ../app/param/actions.xml
Le script va lire l’ancien fichier actions.xml
, et va préparer deux contenus :
- le premier est destiné à être inséré dans la classe
app\Config\Rights
, et contient la liste des droits nécessaires pour exécuter un module - le second contient un prototype des routes pour exécuter les modules. Le contenu doit être inséré dans
app/Config/Routes.php
.
Renommer le droit “gestion” en “manage”
Utilisez une fonction de recherche automatique pour remplacer “gestion” par “manage”.
Ajouter les contrôleurs
Lancez le script :
php vendor/equinton/ppci/migration/generateController.php app/Config/Routes.php app/Controllers/
Le programme va lire les routes définies, puis créer les contrôleurs correspondants, en regroupant les routes par module. Les contrôleurs intègrent lles appels aux fonctions de la librairie correspondante (même nom).
Ajouter un filtre pour les opérations génériques au démarrage
- Ajouter un filtre pour réaliser les opérations décrites dans
modules/common.php
; - renseigner le cas échéant la classe
App\Libraries\Postlogin
, pour réaliser les opérations spécifiques après connexion.
Récupérer les traductions
Les traductions de Ppci sont fournies par défaut. Pour éviter de tout perdre, il faut les fusionner avec les anciennes traductions :
msgmerge app/Language/locales/lang.po ../oldapp/locales/en.po -o app/Language/locales/lang.po
cd app/Language/locales
./generate_po.sh
./compile.sh
Mettre à niveau le readme et le À propos
Éditez les fichiers suivants :
app/Config/news.txt
pour les nouveautés en françaisapp/Config/newsen.txt
pour les nouveautés en anglais
Éditez également les templates suivants :
app/Views/templates/about_fr.tpl
app/Views/templates/about_en.tpl