• Welcome to the Chevereto User Community!

    Here, users from all over the world come together to learn, share, and collaborate on everything related to Chevereto. It's a place to exchange ideas, ask questions, and help improve the software.

    Please keep in mind:

    • This community is user-driven. Always be polite and respectful to others.
    • Support development by purchasing a Chevereto license, which also gives you priority support.
    • Go further by joining the Community Subscription for even faster response times and to help sustain this space
  • Chevereto Support CLST

    Support response

    Support checklist

    • Got a Something went wrong message? Read this guide and provide the actual error. Do not skip this.
    • Confirm that the server meets the System Requirements
    • Check for any available Hotfix - your issue could be already reported/fixed
    • Read documentation - It will be required to Debug and understand Errors for a faster support response

Some sub albums throw 500 error due to unexpected parameter result on array_key_exists()

lovedigit

👽 Chevereto Freak
▶ Reproduction steps
  1. Not sure how to replicate it.
😢 Unexpected result

500 error where this exception is thrown. See log.
I can access the album, as well as sub album if I visit them directly.
It is just the sub album listings that throw this error. And it doesn't happen with all of them.
Only a handful of my users reported it. 2 to be exact.

📃 Error log message

Aw, snap!
Internal Server Error [debug @ print,error_log] - https://v3-docs.chevereto.com/setup/debug.html

Fatal error [0]: array_key_exists() expects parameter 2 to be array, null given
Triggered in /app/lib/classes/class.listing.php at line 531

Stack trace:
#0 unknown file(unknown line): G\errorsAsExceptions()
#1 /app/lib/classes/class.listing.php(531): array_key_exists()
#2 /app/routes/route.album.php(176): CHV\Listing->exec()
#3 /lib/G/classes/class.handler.php(235): G\Handler->{closure}()
#4 /lib/G/classes/class.handler.php(135): G\Handler->processRequest()
#5 /app/web.php(478): G\Handler->__construct()
#6 /app/loader.php(299): require_once('/app/web.php')
#7 /index.php(20): include_once('/app/loader.php')
 
Last edited:
This bug is present since the album cover functionality was added, the system doesn't determine the display_ properties for the album. I've already identified the issue, sadly is not that easy as fix as the previous issue you reported as this one needs to alter many files.

[CODE lang="php" title="app/lib/classes/class.listing.php"]// if ($albums_slice) {
if (!empty($albums_slice)) {[/CODE]

[CODE lang="php" title="app/lib/classes/class.album.php"] public static function fill(&$album, &$user = []) {
// { leave as is}
if (!empty($user)) {
// { leave as is }
}
// HERE: Add this code >>>
$display_url = '';
$display_width = '';
$display_height = '';
if(!empty($album['cover_id'])) {
$image = Image::getSingle($album['cover_id'], false, false);
$image = DB::formatRow($image);
unset($image['album']);
Image::fill($image);
$display_url = $image['display_url'];
$display_width = $image['display_width'];
$display_height = $image['display_height'];
}
$album['display_url'] = $display_url;
$album['display_width'] = $display_width;
$album['display_height'] = $display_height;
// ^^^ Add that code just by the end of the function
}[/CODE]

That should fix this bug, let me know how it works. If everything goes fine it will be packed in the next release.
 
Problem still persists. Maybe I did something wrong.
This is how I edited the file:
[CODE lang="php" title="/app/lib/classes/class.listing.php"]// Get album cover
if ($this->type == 'albums' and $this->output) {
$coverTpl = '(SELECT *
FROM %tImages%
LEFT JOIN %tStorages% ON %tImages%.image_storage_id = %tStorages%.storage_id
WHERE image_id = (SELECT album_cover_id FROM %tAlbums% WHERE album_id = %ALBUM_ID%)
AND %tImages%.image_is_approved = 1
LIMIT 1)';
$album_cover_qry_tpl = strtr($coverTpl, [
'%tImages%' => $tables['images'],
'%tStorages%' => $tables['storages'],
'%tAlbums%' => $tables['albums'],
]);
$albums_cover_qry_arr = [];
$albums_mapping = [];
foreach ($this->output as $k => &$album) {
if ($album['album_image_count'] < 0) {
$album['album_image_count'] = 0;
}
$album['album_image_count_label'] = _n('image', 'images', $album['album_image_count']);
$albums_cover_qry_arr[] = str_replace('%ALBUM_ID%', $album['album_id'], $album_cover_qry_tpl);
$albums_mapping[$album['album_id']] = $k;
}
$albums_slice_qry = implode("\n" . 'UNION ALL ' . "\n", $albums_cover_qry_arr);
$db->query($albums_slice_qry);
$albums_slice = $db->fetchAll();
// if ($albums_slice) {
if (!empty($albums_slice)) {
foreach ($albums_slice as $slice) {
$album_key = $albums_mapping[$slice['image_album_id']];
if (!array_key_exists('album_images_slice', $this->output[$album_key])) {
$this->output[$album_key]['album_images_slice'] = [];
}
$this->output[$album_key]['album_images_slice'][] = $slice;
}
}
}
}[/CODE]

And

[CODE lang="php" title="/app/lib/classes/class.album.php"] public static function fill(&$album, &$user = [])
{
$album['id_encoded'] = isset($album['id']) ? encodeID($album['id']) : null;
if (!isset($album['name']) && isset($user['id'])) {
$album['name'] = _s("%s's images", $user['name_short']);
}
if (!isset($album['id'])) {
$album['url'] = $user ? User::getUrl($user['username']) : null;
$album['url_short'] = $album['url'];
} else {
$album['url'] = self::getUrl($album['id_encoded'], getSetting('seo_album_urls') ? $album['name'] : '');
$album['url_short'] = self::getUrl($album['id_encoded'], '');
}
$album['name_html'] = G\safe_html($album['name'] ?? '');
if (!isset($album['privacy'])) {
$album['privacy'] = "public";
}
switch ($album['privacy']) {
case 'private_but_link':
$album['privacy_notes'] = _s('Note: This content is private but anyone with the link will be able to see this.');
break;
case 'password':
$album['privacy_notes'] = _s('Note: This content is password protected. Remember to pass the content password to share.');
break;
case 'private':
$album['privacy_notes'] = _s('Note: This content is private. Change privacy to "public" to share.');
break;
default:
$album['privacy_notes'] = null;
break;
}

$private_str = _s('Private');
$privacy_to_label = [
'public' => _s('Public'),
'private' => $private_str . '/' . _s('Me'),
'private_but_link' => $private_str . '/' . _s('Link'),
'password' => $private_str . '/' . _s('Password'),
];

$album['privacy_readable'] = $privacy_to_label[$album['privacy']];
$album['name_with_privacy_readable'] = ($album['name'] ?? '') . ' (' . $album['privacy_readable'] . ')';
$album['name_with_privacy_readable_html'] = G\safe_html($album['name_with_privacy_readable']);
$album['name_truncated'] = G\truncate($album['name'] ?? '', 28);
$album['name_truncated_html'] = G\safe_html($album['name_truncated']);

if (!empty($user)) {
User::fill($user);
}
// HERE: Add this code >>>
$display_url = '';
$display_width = '';
$display_height = '';
if(!empty($album['cover_id'])) {
$image = Image::getSingle($album['cover_id'], false, false);
$image = DB::formatRow($image);
unset($image['album']);
Image::fill($image);
$display_url = $image['display_url'];
$display_width = $image['display_width'];
$display_height = $image['display_height'];
}
$album['display_url'] = $display_url;
$album['display_width'] = $display_width;
$album['display_height'] = $display_height;
// ^^^ Add that code just by the end of the function
}[/CODE]
 
[CODE lang="php" title="app/lib/classes/class.album.php"] public static function formatArray(array $dbrow, $safe = false)
{
$output = DB::formatRow($dbrow);
self::fill($output, $output['user']);
$output['views_label'] = _n('view', 'views', $output['views'] ?? 0);
$output['how_long_ago'] = time_elapsed_string($output['date_gmt'] ?? '');

if (isset($output['images_slice'])) {
foreach ($output['images_slice'] as $k => &$v) {
$v = Image::formatArray($v);
$v['flag'] = $v['nsfw'] ? 'unsafe' : 'safe';
}
}

if ($safe) {
unset($output['id'], $output['privacy_extra'], $output['user']['id']);
}

return $output;
}[/CODE]
 
You will require to debug it on your own, that's all the patch I got.
 
Well, it doesn't say anything new.
Reported error is still on the same line.

[CODE title="debug error"]Fatal error [0]: array_key_exists() expects parameter 2 to be array, null given
Triggered in /app/lib/classes/class.listing.php at line 532

Stack trace:
#0 unknown file(unknown line): G\errorsAsExceptions()
#1 /app/lib/classes/class.listing.php(532): array_key_exists()
#2 /app/routes/route.album.php(176): CHV\Listing->exec()
#3 /lib/G/classes/class.handler.php(235): G\Handler->{closure}()
#4 /lib/G/classes/class.handler.php(135): G\Handler->processRequest()
#5 /app/web.php(478): G\Handler->__construct()
#6 /app/loader.php(299): require_once('/app/web.php')
#7 /index.php(20): include_once('/app/loader.php')[/CODE]

Code base is huge. If I could debug it, I would've. It is way above my knowledge.
If it might help, I can provide access to my server?
 
I added this line:


[CODE title="/app/lib/classes/class.listing.php" highlight="5-7"]// if ($albums_slice) {
if (!empty($albums_slice)) {
foreach ($albums_slice as $slice) {
$album_key = $albums_mapping[$slice['image_album_id']];
if(!is_array($this->output[$album_key])){
$this->output[$album_key] = [];
}

if (!array_key_exists('album_images_slice', $this->output[$album_key])) {
$this->output[$album_key]['album_images_slice'] = [];
}
$this->output[$album_key]['album_images_slice'][] = $slice;
}
}[/CODE]

Now that sub album is loading, see the url I provided with this post which is only visible to you.

After that, I can see an empty album, which doesn't exist. I think this is what causing the issue. How do I remove it?

327_1CXntsz4YO.png
 
I went to the album 2021-01 and set a cover image. The empty null album disappeared.
Maybe this bug is related to album cover image being null.
 
I'm not seeing this on my chevereto. I have uploaded to empty folder with no cover pic and I don't get a null album, like you got??

Update: mybad you meant subalbums that I have not tried yet.
 
It doesn't always happen.
I am not sure what triggers it. If you create empty sub album > then upload image to it > It will leave your subfolder without cover.

Now, the error doesn't happen right away. The users who reported it, said they could access their sub album without issue,. When I compared notes from multiple users, I noticed that they all started seeing this error after recent update. I am sure update didn't have to do anything with it, as album cover image has been around before that.

At this point only Rodolfo can find the actual cause of it. When I try to look into the code, I get lost. I do understand it, but I am not that experienced in php. I handle servers and infrastructure design by profession.
 
Like I said, change the array key exists for an isset. I never said to use is array there.

PHP:
                    if(!isset($this->output[$album_key]['album_images_slice'])) {
                        $this->output[$album_key]['album_images_slice'] = [];
                    }

Also, don't forget to share the "new error" you could be getting. Perhaps reads the same to your eyes but is not, I need to know.
 
I don't think I can debug it any further. Users were impatient, so I did the same thing with other user.
Both of the users have this bug fixed for now. I know actual bug is still there, and it will occur again.
I will try to use isset next time someone reports this issue. Thank you for sharing the code, I was not sure how to alter the code for isset. So, I used is array instead.

I will definitely follow up, if it occurs again.
 
Last edited:
Back
Top