Automatic push 4.3.5

This commit is contained in:
chevereto
2025-05-30 14:31:20 +00:00
parent 29a04d90b8
commit ea9c099acc
12 changed files with 101 additions and 72 deletions

View File

@@ -1,5 +0,0 @@
Chevereto 4.3.4 (2025-05-26)
- Added disable_functions detection at /dashboard
- Fixed layout issue on user profile pages when viewed on large screens
- Fixed incorrect alignment of the "powered by" footer on large screens

12
.package/4.3.5.txt Normal file
View File

@@ -0,0 +1,12 @@
Chevereto 4.3.5 (2025-05-30)
- Added favicon customization for Chevereto Lite edition
- Added image watermark feature to Chevereto Lite edition
- Added storage tools as baseline feature
- Added support for floating point numbers in maximum upload size configuration
- Fixed bug affecting URL upload functionality
- Fixed bug in anywhere upload not populating album list
- Fixed bug in Chevereto Lite missing Queue class
- Fixed bug in installer when reading existing database
- Fixed bug in root album list showing nested albums
- Fixed bug with missing cache invalidation on album editing

48
app/composer.lock generated
View File

@@ -1656,16 +1656,16 @@
},
{
"name": "composer/ca-bundle",
"version": "1.5.6",
"version": "1.5.7",
"source": {
"type": "git",
"url": "https://github.com/composer/ca-bundle.git",
"reference": "f65c239c970e7f072f067ab78646e9f0b2935175"
"reference": "d665d22c417056996c59019579f1967dfe5c1e82"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/composer/ca-bundle/zipball/f65c239c970e7f072f067ab78646e9f0b2935175",
"reference": "f65c239c970e7f072f067ab78646e9f0b2935175",
"url": "https://api.github.com/repos/composer/ca-bundle/zipball/d665d22c417056996c59019579f1967dfe5c1e82",
"reference": "d665d22c417056996c59019579f1967dfe5c1e82",
"shasum": ""
},
"require": {
@@ -1712,7 +1712,7 @@
"support": {
"irc": "irc://irc.freenode.org/composer",
"issues": "https://github.com/composer/ca-bundle/issues",
"source": "https://github.com/composer/ca-bundle/tree/1.5.6"
"source": "https://github.com/composer/ca-bundle/tree/1.5.7"
},
"funding": [
{
@@ -1728,7 +1728,7 @@
"type": "tidelift"
}
],
"time": "2025-03-06T14:30:56+00:00"
"time": "2025-05-26T15:08:54+00:00"
},
{
"name": "evenement/evenement",
@@ -5106,16 +5106,16 @@
},
{
"name": "symfony/console",
"version": "v6.4.21",
"version": "v6.4.22",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
"reference": "a3011c7b7adb58d89f6c0d822abb641d7a5f9719"
"reference": "7d29659bc3c9d8e9a34e2c3414ef9e9e003e6cf3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/a3011c7b7adb58d89f6c0d822abb641d7a5f9719",
"reference": "a3011c7b7adb58d89f6c0d822abb641d7a5f9719",
"url": "https://api.github.com/repos/symfony/console/zipball/7d29659bc3c9d8e9a34e2c3414ef9e9e003e6cf3",
"reference": "7d29659bc3c9d8e9a34e2c3414ef9e9e003e6cf3",
"shasum": ""
},
"require": {
@@ -5180,7 +5180,7 @@
"terminal"
],
"support": {
"source": "https://github.com/symfony/console/tree/v6.4.21"
"source": "https://github.com/symfony/console/tree/v6.4.22"
},
"funding": [
{
@@ -5196,7 +5196,7 @@
"type": "tidelift"
}
],
"time": "2025-04-07T15:42:41+00:00"
"time": "2025-05-07T07:05:04+00:00"
},
{
"name": "symfony/deprecation-contracts",
@@ -6057,16 +6057,16 @@
},
{
"name": "symfony/var-exporter",
"version": "v6.4.21",
"version": "v6.4.22",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-exporter.git",
"reference": "717e7544aa99752c54ecba5c0e17459c48317472"
"reference": "f28cf841f5654955c9f88ceaf4b9dc29571988a9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/var-exporter/zipball/717e7544aa99752c54ecba5c0e17459c48317472",
"reference": "717e7544aa99752c54ecba5c0e17459c48317472",
"url": "https://api.github.com/repos/symfony/var-exporter/zipball/f28cf841f5654955c9f88ceaf4b9dc29571988a9",
"reference": "f28cf841f5654955c9f88ceaf4b9dc29571988a9",
"shasum": ""
},
"require": {
@@ -6114,7 +6114,7 @@
"serialize"
],
"support": {
"source": "https://github.com/symfony/var-exporter/tree/v6.4.21"
"source": "https://github.com/symfony/var-exporter/tree/v6.4.22"
},
"funding": [
{
@@ -6130,7 +6130,7 @@
"type": "tidelift"
}
],
"time": "2025-04-27T21:06:26+00:00"
"time": "2025-05-14T13:00:13+00:00"
},
{
"name": "symfony/yaml",
@@ -8181,16 +8181,16 @@
},
{
"name": "symplify/easy-coding-standard",
"version": "12.5.18",
"version": "12.5.20",
"source": {
"type": "git",
"url": "https://github.com/easy-coding-standard/easy-coding-standard.git",
"reference": "451dfeba3770f2d7476468b891a789c451ae4b34"
"reference": "bb44b0fc70dd2148d8a6362bc66a35e23dc31bc4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/easy-coding-standard/easy-coding-standard/zipball/451dfeba3770f2d7476468b891a789c451ae4b34",
"reference": "451dfeba3770f2d7476468b891a789c451ae4b34",
"url": "https://api.github.com/repos/easy-coding-standard/easy-coding-standard/zipball/bb44b0fc70dd2148d8a6362bc66a35e23dc31bc4",
"reference": "bb44b0fc70dd2148d8a6362bc66a35e23dc31bc4",
"shasum": ""
},
"require": {
@@ -8226,7 +8226,7 @@
],
"support": {
"issues": "https://github.com/easy-coding-standard/easy-coding-standard/issues",
"source": "https://github.com/easy-coding-standard/easy-coding-standard/tree/12.5.18"
"source": "https://github.com/easy-coding-standard/easy-coding-standard/tree/12.5.20"
},
"funding": [
{
@@ -8238,7 +8238,7 @@
"type": "github"
}
],
"time": "2025-05-14T09:38:08+00:00"
"time": "2025-05-30T11:42:07+00:00"
},
{
"name": "theseer/tokenizer",

View File

@@ -652,6 +652,7 @@ $settings_updates = [
'4.3.2' => null,
'4.3.3' => null,
'4.3.4' => null,
'4.3.5' => null,
];
/**
@@ -2289,9 +2290,9 @@ if ($installed_version !== '' && empty($paramsCheck)) {
$columnCollation = mb_strtolower($column_meta['collation'] ?? '');
$collationUpdated = $columnCollation !== ''
&& $schemaCollation !== $columnCollation;
$dataType = mb_strtoupper($schema_column['DATA_TYPE']);
$dataType = mb_strtoupper($schema_column['DATA_TYPE'] ?? '');
$columnMetaType = mb_strtoupper($column_meta['type']);
$schemaColumn = mb_strtoupper($schema_column['COLUMN_TYPE']);
$schemaColumn = mb_strtoupper($schema_column['COLUMN_TYPE'] ?? '');
if (in_array($dataType, ['INT', 'TINYINT', 'BIGINT'])) {
$schemaColumn = preg_replace('/\(\d+\)/', '', $schemaColumn);
}
@@ -2301,7 +2302,7 @@ if ($installed_version !== '' && empty($paramsCheck)) {
$schemaColumn !== $columnMetaType
|| $collationUpdated
|| preg_match('/DEFAULT NULL/i', $column_meta['prop'] ?? '')
&& $schema_column['IS_NULLABLE'] === 'NO'
&& ($schema_column['IS_NULLABLE'] ?? '') === 'NO'
)
) {
$query = '`%column` %type';

View File

@@ -9,5 +9,5 @@
* file that was distributed with this source code.
*/
const APP_VERSION = '4.3.4';
const APP_VERSION = '4.3.5';
const APP_VERSION_AKA = 'entrador';

View File

@@ -267,7 +267,7 @@ return function (Handler $handler) {
'pages' => ['lite', 'CHEVERETO_ENABLE_PAGES'],
'routing' => ['pro', 'CHEVERETO_ENABLE_ROUTING'],
'users' => ['lite', 'CHEVERETO_ENABLE_USERS'],
'watermarks' => ['pro', 'CHEVERETO_ENABLE_UPLOAD_WATERMARK'],
'watermarks' => ['lite', 'CHEVERETO_ENABLE_UPLOAD_WATERMARK'],
];
$paidSettings = [];
$default_route = 'stats';

View File

@@ -791,6 +791,7 @@ return function (Handler $handler) {
$editing['album_id'] = null;
}
}
// Note: Includes move album to album
Album::moveContents($id, $editing['album_id']);
} else {
unset($editing['album_privacy'], $editing['new_album'], $editing['album_name']);

View File

@@ -465,9 +465,9 @@ return function (Handler $handler) {
$where = $type === 'images'
? 'WHERE image_user_id=:user_id'
: 'WHERE album_user_id=:user_id';
// if ($type === 'albums' && $tags_active === []) {
// $where .= ' AND album_parent_id IS NULL';
// }
if ($type === 'albums' && $tags_active === []) {
$where .= ' AND album_parent_id IS NULL';
}
break;
}

View File

@@ -79,8 +79,8 @@ class Album
// 'user_palette_id',
// 'user_newsletter_subscribe',
// 'user_show_nsfw_listings',
// 'user_image_count',
// 'user_album_count',
'user_image_count',
'user_album_count',
// 'user_image_keep_exif',
// 'user_file_meta_tag_camera_model',
// 'user_image_expiration',
@@ -403,16 +403,26 @@ class Album
static::assertCanBecomeParent($to, ...$ids);
}
$db = DB::getInstance();
$albumsTable = DB::getTable('albums');
$IdsString = implode(',', $ids);
$db->query(
'UPDATE '
. DB::getTable('albums')
. ' SET album_parent_id=:album_parent_id WHERE album_id IN ('
. implode(',', $ids)
. ')'
<<<SQL
UPDATE {$albumsTable}
SET album_parent_id=:album_parent_id
WHERE album_id IN ({$IdsString});
SQL
);
$db->bind(':album_parent_id', $to);
$return = $db->exec();
if ($return) {
$userId = self::getUser((int) $ids[0]);
if ($userId) {
User::deleteAlbumsCache($userId);
}
}
return $db->exec();
return $return;
}
public static function addImage(int $album_id, int $id)
@@ -481,24 +491,12 @@ class Album
if (($values['name'] ?? null) === '') {
throw new Exception('Invalid album name', 140);
}
$return = DB::update('albums', $values, [
'id' => $id,
]);
if ($return) {
$db = DB::getInstance();
$tableAlbums = DB::getTable('albums');
$db->query(
<<<MySQL
SELECT album_user_id
FROM {$tableAlbums}
WHERE album_id = :album_id;
MySQL
);
$db->bind(':album_id', $id);
$fetchSingle = $db->fetchSingle();
if ($fetchSingle) {
$userId = $fetchSingle['album_user_id'];
$userId = self::getUser($id);
if ($userId) {
User::deleteAlbumsCache($userId);
}
}
@@ -916,4 +914,24 @@ class Album
return [];
}
private static function getUser(int $id): ?int
{
$db = DB::getInstance();
$tableAlbums = DB::getTable('albums');
$db->query(
<<<MySQL
SELECT album_user_id
FROM {$tableAlbums}
WHERE album_id = :album_id;
MySQL
);
$db->bind(':album_id', $id);
$fetchSingle = $db->fetchSingle();
if ($fetchSingle) {
return $fetchSingle['album_user_id'];
}
return null;
}
}

View File

@@ -962,11 +962,13 @@ class Image
hash: $matches[3],
);
$source = $uploadParams['source'];
} elseif (! getSetting('enable_uploads_url')) {
throw new Exception(
message('URL uploading is disabled'),
403
);
} else {
if (! getSetting('enable_uploads_url')) {
throw new Exception(
message('URL uploading is disabled'),
403
);
}
$tempName = Upload::getTempNam($uploadPath);
fetch_url($source, $tempName);
}

View File

@@ -288,7 +288,7 @@ $maxValue = $maxUploadSize > 0 ? bytes_to_mb($maxUploadSize) : '';
?>
<div class="input-label">
<label for="upload_max_filesize_mb"><?php _se('Maximum upload file size'); ?> (MB)</label>
<div class="c3"><input type="number" min="1" pattern="\d+" max="<?php echo $maxValue; ?>" name="upload_max_filesize_mb" id="upload_max_filesize_mb" class="text-input" value="<?php echo Handler::var('safe_post')['upload_max_filesize_mb'] ?? Settings::get('upload_max_filesize_mb'); ?>" placeholder="MB" required></div>
<div class="c3"><input type="number" min="0.1" step="0.1" max="<?php echo $maxValue; ?>" name="upload_max_filesize_mb" id="upload_max_filesize_mb" class="text-input" value="<?php echo Handler::var('safe_post')['upload_max_filesize_mb'] ?? Settings::get('upload_max_filesize_mb'); ?>" placeholder="MB" required></div>
<div class="input-below input-warning red-warning"><?php echo Handler::var('input_errors')['upload_max_filesize_mb'] ?? ''; ?></div>
<div class="input-below"><?php
_se('Maximum upload file size allowed for users.');
@@ -303,7 +303,7 @@ $maxValue = $maxUploadSize > 0 ? bytes_to_mb($maxUploadSize) : '';
</div>
<div class="input-label">
<label for="upload_max_filesize_mb_guest"><?php _se('Maximum upload file size'); ?> (<?php _se('guests'); ?>)</label>
<div class="c3"><input type="number" min="1" pattern="\d+" max="<?php echo $maxValue; ?>" name="upload_max_filesize_mb_guest" id="upload_max_filesize_mb_guest" class="text-input" value="<?php echo Handler::var('safe_post')['upload_max_filesize_mb_guest'] ?? Settings::get('upload_max_filesize_mb_guest'); ?>" placeholder="MB" required></div>
<div class="c3"><input type="number" min="0.1" step="0.1" max="<?php echo $maxValue; ?>" name="upload_max_filesize_mb_guest" id="upload_max_filesize_mb_guest" class="text-input" value="<?php echo Handler::var('safe_post')['upload_max_filesize_mb_guest'] ?? Settings::get('upload_max_filesize_mb_guest'); ?>" placeholder="MB" required></div>
<div class="input-below input-warning red-warning"><?php echo Handler::var('input_errors')['upload_max_filesize_mb_guest'] ?? ''; ?></div>
<div class="input-below"><?php _se('Same as "%s" but for guests.', _s('Maximum upload file size')); ?></div>
</div>

View File

@@ -39,18 +39,18 @@ echo read_the_docs_settings('tools', _s('Tools')); ?>
</div>
<hr class="line-separator">
<div class="input-label">
<?php echo badgePaid('pro'); ?><label for="storageId"><?php _se('Regenerate external storage stats'); ?></label>
<label for="storageId"><?php _se('Regenerate upload storage stats'); ?></label>
<div class="phablet-c1">
<input <?php echo inputDisabledPaid('pro'); ?> type="number" data-dashboard-tool="regenStorageStats" min="0" step="1" name="storageId" id="storageId" class="c4 text-input" placeholder="<?php _se('Storage id'); ?>"> <a class="btn btn-input default" data-action="dashboardTool" data-tool="regenStorageStats" data-data='{"storageId":"#storageId"}'><span class="loading display-inline-block"></span>
<input type="number" data-dashboard-tool="regenStorageStats" min="0" step="1" name="storageId" id="storageId" class="c4 text-input" placeholder="<?php _se('Storage id'); ?>"> <a class="btn btn-input default" data-action="dashboardTool" data-tool="regenStorageStats" data-data='{"storageId":"#storageId"}'><span class="loading display-inline-block"></span>
<span class="text"><?php _se('Regenerate'); ?></span></a>
</div>
<div class="input-below"><?php _se('This will re-calculate the sum of all the image records associated to the target external storage.'); ?></div>
<div class="input-below"><?php _se('This will re-calculate the sum of all the files associated to the target storage.'); ?></div>
</div>
<div class="input-label">
<?php echo badgePaid('pro'); ?><label for="sourceStorageId"><?php _se('Migrate external storage records'); ?></label>
<label for="sourceStorageId"><?php _se('Migrate upload storage records'); ?></label>
<div class="phablet-c1">
<input <?php echo inputDisabledPaid('pro'); ?> type="number" data-dashboard-tool="migrateStorage" min="0" step="1" name="sourceStorageId" id="sourceStorageId" class="c5 text-input" placeholder="<?php _se('Source storage id'); ?>">
<input <?php echo inputDisabledPaid('pro'); ?> type="number" data-dashboard-tool="migrateStorage" min="0" step="1" name="targetStorageId" id="targetStorageId" class="c5 text-input" placeholder="<?php _se('Target storage id'); ?>">
<input type="number" data-dashboard-tool="migrateStorage" min="0" step="1" name="sourceStorageId" id="sourceStorageId" class="c5 text-input" placeholder="<?php _se('Source storage id'); ?>">
<input type="number" data-dashboard-tool="migrateStorage" min="0" step="1" name="targetStorageId" id="targetStorageId" class="c5 text-input" placeholder="<?php _se('Target storage id'); ?>">
<a class="btn btn-input default" data-action="dashboardTool" data-tool="migrateStorage" data-data='{"sourceStorageId":"#sourceStorageId", "targetStorageId":"#targetStorageId"}'>
<span class="loading display-inline-block"></span>
<span class="text"><?php _se('Migrate'); ?></span>