Migration from PrototypePhp
Install CodeIgniter and Ppci
Create a different folder from the one containing the initial code of the application to be migrated, for example app2, then, from the lower-level directory:
composer create-project codeigniter4/appstarter app2
cd app2
composer require equinton/ppci
vendor/equinton/ppci/install/install.shThen edit the .env file, and update the necessary parameters (CI_ENVIRONMENT, app.baseURL and the database connection parameters).
Create a new vhost in Apache
Here is an example configuration:
<VirtualHost *:80>
ServerName app2.local
ServerPath /app2.local
RewriteEngine On
RewriteRule ^ https://app2.local%{REQUEST_URI} [R]
</VirtualHost>
<VirtualHost *:443>
ServerName app2.local
ServerPath /app2.local
SSLEngine on
SSLCertificateFile /etc/ssl/certs/server.crt
SSLCertificateKeyFile /etc/ssl/private/server.key
SSLCACertificateFile /etc/ssl/certs/cacert.crt
DocumentRoot /var/www/app2/public
</VirtualHost>
<Directory /var/www/app2/public>
<LimitExcept GET POST>
Deny from all
</LimitExcept>
Options -Indexes FollowSymLinks MultiViews
Header 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' ;"
<FilesMatch "\.(ico|flv|jpg|jpeg|png|gif|js|css|svg)$">
Header set Cache-Control "max-age=604800, private"
</FilesMatch>
<FilesMatch ".*openstreetmap.*\.png$">
Header set Cache-Control "max-age=2592000, public"
</FilesMatch>
Require all granted
AllowOverride all
RewriteEngine On
RewriteBase /
RewriteCond "/%{REQUEST_FILENAME}" !-f
RewriteCond "/%{REQUEST_FILENAME}" !-d
RewriteRule "(.*)" "/index.php?$1" [PT,QSA]
</Directory>Update the database
Edit the vendor/equinton/ppci/migration/updatedb.sql file, and check the first line (set search_path), replacing app with the name of the schema containing the data.
Then run the sql file.
Add Smarty templates
Copy the Smarty templates from display/templates into app/Views/templates, keeping the sub-folder organisation, except for the root files and the framework sub-folder.
Global changes
In this folder, replace all the labels (filter on *tpl) :
</form>with{$csrf}</form>to add the CSRF token in formsdroitswithrights.gestionby.managedatatable"bydatatable display”datatable-nopaging-nosearchingbydatatable-nopaging-nosearching displaydatatable-searchingbydatatable-searching displaydatatable-nopaging-nosearchingbydatatable-nopaging-nosearching displaydatatable-nopagingbydatatable-nopaging displaydatatable-nopaging-nosortbydatatable-nopaging-nosort displaydatatable-nosortbydatatable-nosort displaydatatable-exportbydatatable-export displaydatatable-export-pagingbydatatable-export-paging display.
Delete
index.php?module=
Modifications to each form
Go back to all the links (look for the a href tags) and replace the first & with ?.
Change all the form actions so that they look like this:
<form class=‘form-horizontal’ id=‘formName’ method=‘post’ action=‘moduleWrite’>
<input type=‘hidden’ name=‘moduleBase’ value=‘module’>The action field can be removed. However, the moduleBase field must be retained: it is used to create the moduleDelete action via the javascript script in main_js.tpl.
Rewriting models
Copy the files from modules/classes to app/Models.
Global transformations
These can be carried out using search/replace.
- replace :
<?phpby<?php namespace App\Models;use Ppci\Models\PpciModel;, with line breaks;extends ObjetBDDwithextends PpciModel;(public function __construct().*)bypublic function __construct(), ticking regular expression ;$this->columnsby$this->fields;function ecrirebyfunction write;function lirebyfunction read- replace
parent::ecrirewithparent::write. (parent::__construct().*)byparent::__construct(), checking regular expression ;$this->auto_id = 0by$this->useAutoIncrement = falseauto_date = 0byautoFormatDate = false- delete :
$this->auto_id = 1;$param[‘fullDescription’] = 1;$this->param = $param;
Individual transformations
- rename the file name, for example
espece.class.phptoespece.php; - in SQL queries, modify variables by adding : at the end:
:idmust become:id:; - for tables containing geographical data (fields with type=4), modify the queries or create the
read()functions to addst_astext()for the fields concerned; - date transformations for fields not present in the table must be rewritten according to this scheme:
$this->dateFields[] = ‘peche_date’;
$this->datetimeFields[] = ‘peche_datetime’;- if the
utf8_encodefunction is used, it must be replaced by :
$data = mb_convert_encoding($data, ‘UTF-8’, ‘ISO-8859-15, ISO-8859-1, Windows-1252’);The function processes strings or arrays indiscriminately.
Rewriting libraries
Copy all the modules into app/Libraries. They need to be transformed into classes.
Global transformations
Replace :
<?phpby:
<?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,by$this->dataRead(dataDelete($dataclass,by$this->dataDelete(case "list":byfunction list(){$vue=service('Smarty');(line feed)case "display":byfunction display(){$vue=service('Smarty');(line feed)case "change":byfunction change(){$vue=service('Smarty');(line feed)case "write":by:
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":byfunction delete(){case "byfunction":by() {break;by}: functions close$dataclassby$this->dataclass$idby$this->id$vueby$this->vue$this->dataDelete($this->id);by
try {
$this->dataDelete($this->id);
return $this->list();
} catch (PpciException $e) {
return $this->change();
}$this->dataWrite( $_REQUEST );by
try {
$this->id = $this->dataWrite($_REQUEST);
$_REQUEST["xx_id"] = $this->id;
return $this->list();
} catch (PpciException $e) {
return $this->change();
}$message->by$this->message->
and delete:
switch ($t_module["param"]) {$bdd, $ObjetBDDParam
Treatment of transactions
Replace :
$bdd->beginTransaction();by :
$db = $this->dataclass->db;
$db->transBegin();- replace
$bdd->commit();by$db->transCommit(); - replace
$bdd->rollback();by :
if ($db->transEnabled) {
$db->transRollback();
}Generate the routes and rights needed to run the modules
Run the following command:
php vendor/equinton/ppci/migration/actionsParse.php ../app/param/actions.xmlThe script will read the old actions.xml file, and prepare two contents:
- the first is intended to be inserted into the
app\Config\Rightsclass, and contains the list of rights required to run a module - the second contains a prototype of the routes for executing the modules. The content must be inserted into
app/Config/Routes.php.
Rename the gestion right to ‘manage’.
Use an automatic search function to replace gestion with manage.
Add controllers
Run the script :
php vendor/equinton/ppci/migration/generateController.php app/Config/Routes.php app/Controllers/The program will read the routes defined, then create the corresponding controllers, grouping the routes by module.
The controllers include calls to functions from the corresponding library (same name).
Add a filter for generic startup operations
- Add a filter to perform the operations described in
modules/common.php; - if necessary, fill in the
App\Libraries\Postloginclass, to perform specific operations after connection.
Retrieving translations
Ppci translations are provided by default. To avoid losing everything, you need to merge them with the old translations:
msgmerge app/Language/locales/lang.po ../oldapp/locales/en.po -o app/Language/locales/lang.po
cd app/Language/locales
./generate_po.sh
./compile.shUpgrade readme and About
Edit the following files:
app/Config/news.txtfor news in Frenchapp/Config/newsen.txtfor news in English
Also edit the following templates:
app/Views/templates/about_fr.tplapp/Views/templates/about_en.tpl
