Upgrade to 4.2.0

This commit is contained in:
Bastian Allgeier
2024-04-10 11:09:52 +02:00
parent 77d9337371
commit 7f4eb7509d
88 changed files with 1187 additions and 490 deletions

View File

@@ -220,143 +220,145 @@ class Dir
array|null $contentIgnore = null,
bool $multilang = false
): array {
$dir = realpath($dir);
$inventory = [
'children' => [],
'files' => [],
'template' => 'default',
];
$dir = realpath($dir);
if ($dir === false) {
return $inventory;
}
$items = static::read($dir, $contentIgnore);
// a temporary store for all content files
$content = [];
// sort all items naturally to avoid sorting issues later
// read and sort all items naturally to avoid sorting issues later
$items = static::read($dir, $contentIgnore);
natsort($items);
// loop through all directory items and collect all relevant information
foreach ($items as $item) {
// ignore all items with a leading dot
// ignore all items with a leading dot or underscore
if (in_array(substr($item, 0, 1), ['.', '_']) === true) {
continue;
}
$root = $dir . '/' . $item;
// collect all directories as children
if (is_dir($root) === true) {
// extract the slug and num of the directory
if (preg_match('/^([0-9]+)' . static::$numSeparator . '(.*)$/', $item, $match)) {
$num = (int)$match[1];
$slug = $match[2];
} else {
$num = null;
$slug = $item;
}
$inventory['children'][] = [
'dirname' => $item,
'model' => null,
'num' => $num,
'root' => $root,
'slug' => $slug,
];
} else {
$extension = pathinfo($item, PATHINFO_EXTENSION);
switch ($extension) {
case 'htm':
case 'html':
case 'php':
// don't track those files
break;
case $contentExtension:
$content[] = pathinfo($item, PATHINFO_FILENAME);
break;
default:
$inventory['files'][$item] = [
'filename' => $item,
'extension' => $extension,
'root' => $root,
];
}
}
}
// remove the language codes from all content filenames
if ($multilang === true) {
foreach ($content as $key => $filename) {
$content[$key] = pathinfo($filename, PATHINFO_FILENAME);
$inventory['children'][] = static::inventoryChild(
$item,
$root,
$contentExtension,
$multilang
);
continue;
}
$content = array_unique($content);
$extension = pathinfo($item, PATHINFO_EXTENSION);
// don't track files with these extensions
if (in_array($extension, ['htm', 'html', 'php']) === true) {
continue;
}
// collect all content files separately,
// not as inventory entries
if ($extension === $contentExtension) {
$filename = pathinfo($item, PATHINFO_FILENAME);
// remove the language codes from all content filenames
if ($multilang === true) {
$filename = pathinfo($filename, PATHINFO_FILENAME);
}
$content[] = $filename;
continue;
}
// collect all other files
$inventory['files'][$item] = [
'filename' => $item,
'extension' => $extension,
'root' => $root,
];
}
$inventory = static::inventoryContent($inventory, $content);
$inventory = static::inventoryModels($inventory, $contentExtension, $multilang);
$content = array_unique($content);
$inventory['template'] = static::inventoryTemplate(
$content,
$inventory['files']
);
return $inventory;
}
/**
* Take all content files,
* remove those who are meta files and
* detect the main content file
* Collect information for a child for the inventory
*/
protected static function inventoryContent(array $inventory, array $content): array
{
// filter meta files from the content file
if (empty($content) === true) {
$inventory['template'] = 'default';
return $inventory;
protected static function inventoryChild(
string $item,
string $root,
string $contentExtension = 'txt',
bool $multilang = false
): array {
// extract the slug and num of the directory
if ($separator = strpos($item, static::$numSeparator)) {
$num = (int)substr($item, 0, $separator);
$slug = substr($item, $separator + 1);
}
foreach ($content as $contentName) {
// could be a meta file. i.e. cover.jpg
if (isset($inventory['files'][$contentName]) === true) {
// determine the model
if (empty(Page::$models) === false) {
if ($multilang === true) {
$code = App::instance()->defaultLanguage()->code();
$contentExtension = $code . '.' . $contentExtension;
}
// look if a content file can be found
// for any of the available models
foreach (Page::$models as $modelName => $modelClass) {
if (is_file($root . '/' . $modelName . '.' . $contentExtension) === true) {
$model = $modelName;
break;
}
}
}
return [
'dirname' => $item,
'model' => $model ?? null,
'num' => $num ?? null,
'root' => $root,
'slug' => $slug ?? $item,
];
}
/**
* Determines the main template for the inventory
* from all collected content files, ignore file meta files
*/
protected static function inventoryTemplate(
array $content,
array $files,
): string {
foreach ($content as $name) {
// is a meta file corresponding to an actual file, i.e. cover.jpg
if (isset($files[$name]) === true) {
continue;
}
// it's most likely the template
$inventory['template'] = $contentName;
// (will overwrite and use the last match for historic reasons)
$template = $name;
}
return $inventory;
}
/**
* Go through all inventory children
* and inject a model for each
*/
protected static function inventoryModels(
array $inventory,
string $contentExtension,
bool $multilang = false
): array {
// inject models
if (
empty($inventory['children']) === false &&
empty(Page::$models) === false
) {
if ($multilang === true) {
$contentExtension = App::instance()->defaultLanguage()->code() . '.' . $contentExtension;
}
foreach ($inventory['children'] as $key => $child) {
foreach (Page::$models as $modelName => $modelClass) {
if (file_exists($child['root'] . '/' . $modelName . '.' . $contentExtension) === true) {
$inventory['children'][$key]['model'] = $modelName;
break;
}
}
}
}
return $inventory;
return $template ?? 'default';
}
/**

View File

@@ -2,6 +2,7 @@
namespace Kirby\Filesystem;
use Kirby\Toolkit\A;
use Kirby\Toolkit\Str;
use SimpleXMLElement;
@@ -268,18 +269,32 @@ class Mime
/**
* Returns all available extensions for a given MIME type
*/
public static function toExtensions(string $mime = null): array
public static function toExtensions(string $mime = null, bool $matchWildcards = false): array
{
$extensions = [];
$testMime = fn (string $v) => static::matches($v, $mime);
foreach (static::$types as $key => $value) {
if (is_array($value) === true && in_array($mime, $value) === true) {
$extensions[] = $key;
continue;
}
if ($value === $mime) {
$extensions[] = $key;
if (is_array($value) === true) {
if ($matchWildcards === true) {
if (A::some($value, $testMime)) {
$extensions[] = $key;
}
} else {
if (in_array($mime, $value) === true) {
$extensions[] = $key;
}
}
} else {
if ($matchWildcards === true) {
if ($testMime($value) === true) {
$extensions[] = $key;
}
} else {
if ($value === $mime) {
$extensions[] = $key;
}
}
}
}