PHP compatibility
SPIP 4.1 requires PHP 7.4 minimum, and works up to PHP 8.1.
It requires the PHP extensions: Sodium, Zlib, Zip and Phar.
Reminder: SPIP 4.0 is PHP 7.3 to 8.0.
Compatibility PHP 8.1
For PHP 8.1 compatibility, we had to correct / adapt many functions.
This is particularly true of calls to PHP functions dealing with strings, if they receive null
instead of a string, to avoid deprecated
: https://php.watch/versions/8.1/internal-func-non-nullable-null-deprecation
Authentication & Encryption
We take up and adapt the work of g0uz on the plugin Chiffrer.
- It fixes some rare cases where the Javascript library used until now failed to identify the user
- It increases security by preventing certain types of attacks.
Login form
HTTPS is now even more strongly recommended
SPIP no longer attempts to encrypt the author’s password in Javascript from the login form, and the password therefore systematically arrives "in clear" to SPIP. It is therefore strongly recommended that your site is in HTTPS, as HTTPS ensures the security of the transmission.
As a result, the _AUTORISER_AUTH_FAIBLE
constant, which forced the password to be sent in clear text, is removed.
Pepper, salt, password hash
An author’s password is now hashed in SPIP using a pepper (a site-specific key). In addition, the password_hash
PHP function takes care of finding the best hash algorithm and creates a salt in it. The PHP function password_verify
is used to verify this.
The author’s rotating " aléas " are still created, but are no longer used to salt the password as PHP handles this very well. However, the additional application of a pepper is a new feature.
As before, with each successful authentication of an author, a new hash is stored in base, recreating a hash with password_hash
: this applies a new salt to it then, and eventually PHP takes the opportunity to use a more powerful hash algorithm if needed.
Encryption keys
To carry out this pepper, and other actions in SPIP, encryption keys are used and stored in config/cles.php
. There are 2 by default:
- secret_des_auth : it is used to pepper the authors’ password. So it’s a new key.
- secret_du_site : Half of it is used to calculate the site secrecy. The other half is stored in the base in the
secret_du_site
entry of the tablespip_meta
. This site secret (combined) makes it possible to sign and/or encrypt certain parts of SPIP (ajax contexts, author actions).
When a webmaster logs in, the keys are saved in the new backup_cles
field of the table spip_auteurs
, by encrypting it with the author’s plaintext password.
This allows the site keys to be restored if the cles.php
file has been deleted, when authenticating a webmaster.
The class \Spip\Chiffrer\SpipCles
allows keys to be manipulated if required.
Password
SPIP provides two methods that are used in ecrire/auth/spip.php
- \Spip\Chiffrer\Password::verifier($clair, $hash, $key = null): bool
- \Spip\Chiffrer\Password::hacher($clair, $key = null): string
The default key is that of secret_des_auth
, used to pepper.
Encrypting
Three methods are also provided for encrypting and decrypting (symmetric encryption) content.
In this we use the Sodium library (provided by default in PHP >= 7.2).
- Encrypting::chiffrer($message, $key): ?string
- Encrypting::dechiffrer($encoded, $key): ?string
- Encrypting::keygen(): string
The keygen
method simply produces an encryption key of the appropriate length.
The methods chiffrer()
and dechiffrer()
will be very slow if the transmitted key is not the right length: the encryption key is then considered to be a password requiring heavy additional processing (with sodium_crypto_pwhash
).
Signing of actions
Actions are now authenticated using hash_hmac
and hash_equals
(and the aléas of authors and/or the secrecy of the site)
Code quality
There is plenty of room for improvement in the quality of SPIP’s PHP code... the future can only be better ;-)
Type declarations
In doing so for PHP 8.1, we have started to type certain function arguments and returns to detect incorrect calls as early as possible.
This is a potentially impactful change: it may create template errors where previously the error was more silent or tolerated. Similarly it could cause PHP errors in plugins or homegrown scripts on erroneous calls to these functions.
By ensuring compatibility with new versions of PHP, we will inevitably move towards more type declaration in the SPIP code as the source code evolves and becomes factorised.
The consequence will be that people developing plugins or templates will have to be more careful about the calls made on the one hand, and on the other hand we will certainly restrict new functions to single types (avoid the mixed
), as well as some existing functions will probably have certain types of mixed arguments reduced (to avoid an argument getting a bit of everything as int | string | array
for example), and the same goes for returns of functions.
Given the historical SPIP code, this will not be so obvious.
Syntactic sugar
We have run the Rector tool on the SPIP 4.1 code with the PHP 7.4 configuration. The tool allows you to transform the syntax of the PHP source code by modifying certain elements that can be simplified with more recent PHP scripts. For example, using the operators ??
or ??=
when possible (See the doc PHP).
That’s always a plus :-)
API changes on URLs and objects
Some call functions for calculating or decoding URLs are modified.
Older APIs are deprecated.
There are now two separate sets of functions for generating an object’s URL and for decoding a URL. This new mechanism allows you to define a function to generate a clean URL for #URL_PAGE
.
The new functions are typed. In the following explanations, only the beginning of the signatures of the different modified functions are presented.
See the corresponding addition request for full details.
Encoding
generer_objet_url (previously generer_url_entite
)
Function generating a URL, which can be either for the public space (parameter $public = true
) or for the private area ($public = false
), or by default ($public = null
) return a URL for the space we are currently in ...
Note: For this function the signature changes slightly.
In generer_url_entite()
now deprecated:
- The fifth parameter
$public
could be valued attrue, false, null or 'string'
. In the case of a string, it corresponded to a "connect" parameter.
These are now 2 separate parameters for generer_objet_url
:
- The fifth is
?bool $public = null
(sotrue, false or null)
, - The sixth is
string $connect = ''
.
In most cases this will not affect usage and simply renaming the function should be sufficient.
- generer_url_entite($id, $objet, ...)
+ generer_objet_url($id, string $objet, ...)
generer_objet_url_absolue
Generate the absolute url to an object
- generer_url_entite_absolue($id, $entite, ...)
+ generer_objet_url_absolue($id = 0, string $entite = '', ...)
Decoding
The URL decoding function is now called
urls_xxxx_decoder_url_dist()
which avoids any confusion with the former function urls_xxxx_dist()
.
In addition, for a URL module that would like to be compatible with older versions of SPIP and this new convention, it is sufficient to provide a
urls_xxxx_dist()
function not typed which does the routing to the 2 functions generer_url_objet()
and decoder_url()
of the module.
Object
generer_objet_lien
Generates a link (clickable title to url) to an object
- generer_lien_entite($id_objet, $objet, ...)
+ generer_objet_lien(int $id_objet, string $objet, ...)
generer_objet_info
To provide information about an editorial object. Used among others by #INFO_XX
- generer_info_entite($id_objet, $type_objet, $info, ...)
+ generer_objet_info($id_objet, string $type_objet, string $info, ...)
The functions for defining specific calculations for obtaining information are also renamed. For the calculated information ’xxx’: called via generer_objet_info(3, 'article', 'xxx')
or #INFO_XXX{article,3}
.
If these functions exist, they are used by SPIP in this case:
// xxx specifically on the 'type' object
- generer_xxx_{type}($id_objet, $type_objet, ...)
+ generer_{type}_xxx($id_objet, string $type_objet, ...)
// otherwise xxx on any object
- generer_xxx_entite($id_objet, $type_objet, $row, ...)
+ generer_objet_xxx($id_objet, string $type_objet, array $row, ...)
The old naming is deprecated.
Following this principle, the internal SPIP function for calculating the introduction has been renamed:
generer_objet_introduction
Generates the introduction of the object (private function to SPIP), used by #INTRODUCTION
et #INFO_INTRODUCTION
)
- generer_introduction_entite($id_objet, $objet, $ligne_sql, ...)
+ generer_objet_introduction(int $id_objet, string $objet, array $ligne_sql, ...)
Rewriting transmettre
to .api
To facilitate and partially secure the sending of specific data (CSV, JSON) to known SPIP authors, the transmit.api URL has been set up (it replaces an old mechanism with the same objective which used a template transmettre.html
).
The URL is generated with the generer_url_api_low_sec()
function ("low sec" meaning "low security" here). A fixed token is created for this action (with its parameters) for the designated author and will be accepted even if the author is disconnected (meaning that anyone who owns the URL will be able to access the returned content).
Historically, this makes it possible to generate non-public files (RSS of articles proposed for publication, site statistics) which can be used by third-party tools (RSS aggregators, for example).
Also:
- the function
securiser_acces()
is renamed insecuriser_acces_low_sec()
and defined in inc/acces. - We keep a
filtre_securiser_acces_dist()
in inc/filtres for compat of old templates - the function
param_low_sec()
is deprecated
Updates to libraries
We have updated several libraries used by SPIP.
Javascript
- spip/spip -> Sortable 1.14.0
- spip/spip -> jquery Form 4.3.0
- spip/spip -> JS Cookie 3.0.1
- spip/statistiques -> d3 7.3.0
- spip/statistiques -> luxon 2.3.0
- spip/plan -> jstree 3.3.12
PHP
- spip/compresseur -> css-tidy 2.0.0
- spip/medias -> getid3 1.9.21
- spip/medias -> svg-sanitizer 0.14.1
Deleting libraries
We have removed jQuery.cookie
which was deprecated since SPIP 3.2 in favour of JS Cookie.
As a reminder, if you have not yet adapted your uses:
$.cookie(key) becomes Cookies.get(key)
$.cookie(key, value) becomes Cookies.set(key, value)
$.cookie(key, value, options) becomes Cookies.set(key, value, options)
Interface
The sections in the private area now also display the list of rejected articles.
Cleanings
We have deleted
#FORMULAIRE_CONFIGURER_METAS
which was deprecated from SPIP 3.0 in favour of forms
#FORMULAIRE_CONFIGURER_XX
.
See the relevant documentation Configurer une fonctionnalité de votre site, ou un plugin .
Some adjustments
In a template, to list the tables of editorial objects, prefer #NULL
(which returns null
) rather than #REM
(which returns an empty string).
- [(#REM|lister_tables_objets_sql)]
+ [(#NULL|lister_tables_objets_sql)]
Plug-ins
Archivist
The "Archivist" plug-in has been updated to use the PHP extensions Zip, zlib and Phar, which are now required. This has allowed us to remove the (very) old Pcl* libraries that we had been carrying around for a few years.
Note also that the plug-in comes with unit tests written with PHPUnit.
Bigup
The Bigup configuration form is displayed on the advanced options page, with a slightly more meaningful wording for the title of the explanation form.
Compressor
Update of the CSSTidy library to version 2.0 and correction of a bug in the compression of Javascript files on certain environments.
Forum
- fixed a bug that was displaying the link to the forum control page for unauthorized authors.
- normalization of the addition of a forum in base in order to pass the information through the pre/post insertion pipeline
- fixed a bug displaying icons in RTL language
- fixed a bug that allowed access to the private forum of the editors when it was disabled in the configuration
- fixed a bug in the message search from the forum control page
Mediabox
- improved display of long text in the modal caption
- use of a dark theme by default in the private area
- restored support for URLs with fragments using a selector in the
data-href-popin
attribute - added support for
data-(max|min)-(width|height)
anddata-(width|height)
attributes on mediabox links and restored compatibility with oldboxInline boxIframe boxWidth-xx boxHeight-xx
classes - fixed a bug with some remote images that were not displayed by the modal (notably SVGs), because the image has no known dimension
Medias
- allow to customize the autolien behaviour of images depending on the media, extension, size or document_id
- fixed a bug in the CSV file embedding model
- removed obsolete jQuery multifile library
- updated Sanitizer and getid3 SVG libraries
- removed browser prefixes from the plug-in’s CSS
- improved UX of buttons in the documents block of an object
- fixed a bug in the code generated for the attributes of a captioned image
- improved the template used for inserting SVG images in the text of an object
- fixed a bug in the display of the media library when a document has a very long URL in the title or credit fields
Plan
Update of the Jstree library to version 3.3.12.
Révisions
Fixed a bug that prevented the Revision Optimisation Genie from working.
Sites
- fixed a bug that was displaying the date twice in lists of syndicated articles
- improved site editing forms by using a placeholder in the URL fields (instead of pre-filling them with http://)
- fixed a bug in the display of the list of sites in the side column of the private area
Statistics
- update of D3.js, d3-time-format and Luxon.js libraries
- fixed a bug in the display of month names in Arabic statistics
SVP
- fixed a bug in unpacking plug-in archives with the new Archivist plug-in functions
- improved presentation of checkboxes in the plug-in list
- fixed a bug in plug-in selection when the user was doing "check all" then "check updates
- fixed a bug in the display of return messages from the plug-in loading form
- always display the link to the plug-in documentation whether it is active or not
- fixed a bug that prevented the activation of a plug-in when downloads are forbidden
TextWheel
- fixed a bug that was mistakenly escaping some automatic links
- fixed a bug in the direction of the bullets when the page contains blocks of text with different directions
URLs étendues
Following the API changes to URLs and objects, the URL functions have been rewritten to be clearer and better typed with 2 entry points for the decode/encode part.
See the corresponding add request for full details.
Templates dist
- fixed a bug that was causing paginations to overflow on small screens
- applying the filter
|header_silencieux
on public pages to respect the value of the globalspip_header_silencieux
- removal of Internet Explorer specific classes in CSS
* fixed a bug in the display of images and SVGs on small screens