2026-02-01 11:53:46 +00:00
< ? php
namespace BookStack\Theming ;
2026-02-02 18:29:35 +00:00
readonly class ThemeModule
2026-02-01 11:53:46 +00:00
{
2026-02-01 17:31:21 +00:00
public function __construct (
2026-02-02 18:29:35 +00:00
public string $name ,
public string $description ,
public string $version ,
2026-02-03 20:43:01 +00:00
public string $folderName ,
2026-02-01 17:31:21 +00:00
) {
}
2026-02-01 11:53:46 +00:00
/**
* Create a ThemeModule instance from JSON data .
*
2026-02-03 20:43:01 +00:00
* @ throws ThemeModuleException
2026-02-01 11:53:46 +00:00
*/
2026-02-01 17:31:21 +00:00
public static function fromJson ( array $data , string $folderName ) : self
2026-02-01 11:53:46 +00:00
{
if ( empty ( $data [ 'name' ]) || ! is_string ( $data [ 'name' ])) {
2026-02-03 20:43:01 +00:00
throw new ThemeModuleException ( " Module in folder \" { $folderName } \" is missing a valid 'name' property " );
2026-02-01 11:53:46 +00:00
}
if ( ! isset ( $data [ 'description' ]) || ! is_string ( $data [ 'description' ])) {
2026-02-03 20:43:01 +00:00
throw new ThemeModuleException ( " Module in folder \" { $folderName } \" is missing a valid 'description' property " );
2026-02-01 11:53:46 +00:00
}
2026-02-01 16:27:52 +00:00
if ( ! isset ( $data [ 'version' ]) || ! is_string ( $data [ 'version' ])) {
2026-02-03 20:43:01 +00:00
throw new ThemeModuleException ( " Module in folder \" { $folderName } \" is missing a valid 'version' property " );
2026-02-01 11:53:46 +00:00
}
2026-02-01 16:27:52 +00:00
if ( ! preg_match ( '/^v?\d+\.\d+\.\d+(-.*)?$/' , $data [ 'version' ])) {
2026-02-03 20:43:01 +00:00
throw new ThemeModuleException ( " Module in folder \" { $folderName } \" has an invalid 'version' format. Expected semantic version format like '1.0.0' or 'v1.0.0' " );
2026-02-01 16:27:52 +00:00
}
2026-02-01 17:31:21 +00:00
return new self (
name : $data [ 'name' ],
description : $data [ 'description' ],
version : $data [ 'version' ],
2026-02-03 20:43:01 +00:00
folderName : $folderName ,
2026-02-01 17:31:21 +00:00
);
2026-02-01 11:53:46 +00:00
}
/**
* Get a path for a file within this module .
*/
public function path ( $path = '' ) : string
{
$component = trim ( $path , '/' );
return theme_path ( " modules/ { $this -> folderName } / { $component } " );
}
2026-02-03 20:43:01 +00:00
public function getVersion () : string
{
return str_starts_with ( $this -> version , 'v' ) ? $this -> version : 'v' . $this -> version ;
}
2026-02-01 11:53:46 +00:00
}