• Resolved fromb

    (@fromb)


    Hi,

    I used the official WP importer to move a set of custom posts to a staging server. Whenever these posts are edited, a fatal error occurs:

    Fatal error: Uncaught Error: Cannot access offset of type string on string in /wp-content/plugins/acf-extended/includes/modules/performance/module-performance-ultra.php

    Newly created posts are unaffected.

    Plot twist: a second CPT, imported at the same time, is unaffected. Both CPT’s are created using ACF.

    Not sure where to begin on this one. Tried setting the affected CPT fields to ‘save as individual meta’ but that didn’t work.

    Thanks in advance.

Viewing 7 replies - 1 through 7 (of 7 total)
  • Thread Starter fromb

    (@fromb)

    I’m finding the official WP importer to be a hit or miss experience with ACFe. Sometimes it works, sometimes it doesn’t.

    Plugin Author Konrad Chmielewski

    (@hwk-fr)

    Hello,

    Thanks for the feedback!

    In the error message you shared, you forgot the line number. In order to better understand the issue, can you please provide it? The line should be written right after the message in the error, like this:

    Fatal error: Uncaught Error: Cannot access offset of type string on string in /wp-content/plugins/acf-extended/includes/modules/performance/module-performance-ultra.php on line: XXXX (<- here)

    The error message suggests the acf meta (that is saved/loaded by the Performance Ultra meta) might have been corrupted during the export/import process. But I’m still not 100% sure, since I wasn’t able to replicate the issue by simulating a corrupted data.

    The error line should provide more context. I’ll then give you more information and debugging steps in order to find the issue.

    Thanks!

    Regards.

    Plugin Author Konrad Chmielewski

    (@hwk-fr)

    Hello,

    I’m coming back to you about this issue.

    I was able to reproduce the error while running PHP 8. The error line is 176 right? This error can be triggered when the acf metadata (from the Performance Ultra) is an empty string, and you try to update the post in the WP Admin.

    The issue come from the fact that you have malformed data in your acf meta. Since it’s malformed for WordPress during the import, it converts the acf metdata into an “empty value”. There is no viable scenario where acf meta should be empty (unless there is a bug during the import, for example), thus why this error is triggered.

    I’ll add a safe guard logic in the next patch to avoid this error. In the meantime, you can fix it by following these steps:

    In the file /acf-extended/includes/modules/performance/module-performance.php line:165, add this code:

    $acf = acf_get_array($acf);

    Final code should look like:

    // get meta
    $acf = $this->get_meta($post_id);
    $acf = acf_get_array($acf);

    // set store: acf meta
    $store->set($post_id, $acf);

    This will fix the error that is triggered when a post is updated from the WP Admin with an empty acf metadata.

    However, this will not fix the issue with the data export/import. Your problematic posts most likely have an empty acf metadata after the import. So it means all your ACF felds will be empty (or back to default state). To confirm that, please enable the Developer Mode (see documentation) on both websites, the one which exports, and the one which imports.

    This module will show you all metadata saved on each post, when you open a post in the WP Admin (see the demo in the documentation).

    On the export website, you’ll see the acf meta like this:

    acf = a:2:{s:7:"my_text";s:13:"My Text Value";s:8:"_my_text";s:19:"field_66d9bf0595ec2";}

    On the import website, you’ll see the acf meta like this:

    acf = (empty)

    A small explanation regarding this weird a:2:{s:7:"my_text"... value. Since it is not possible to save a PHP array straight into the database, WordPress save it as a “serialized string” (see PHP serialize documentation). This logic converts a classic array like this:

    $my_array = array(
    'key' => 'value'
    );

    Into a string that is readable and recordable by the MySQL database, like this:

    a:1:{s:3:"key";s:5:"value";}

    This string is a very detailed version of the array that allows PHP to decode it back into a proper array to be used in code later.

    In this serialized example, the first a:1 means it is an array with 1 row. The s:3 means the key is a string that is 3 bytes long (“key“). etc… As you can see it is very detailed, but also very sensitive. For example, if you change that s:3 to s:4, it invalidates the whole data, and PHP cannot read and convert it back to a proper array.

    Now more complexity will arise if you have special characters in field values, like emojis or characters with an accent.

    For example, this value: déjà vu will be serialized to this: s:9:"déjà vu" with utf8. But it will be serialized as s:7:"déjà vu" with a different server encoding. This is because special characters have different number of bytes depending on the encoding.

    Now your problem is that you most likely have different server configuration for your live website and your staging website. If the staging reads the serialized data differently, it will invalidate the whole meta, and WordPress will just fallback to an empty value (as explained above).

    This is also why the WP Importer seems works randomly in your case. Some posts probably have special characters, and other don’t.

    I would recommend to check your database configuration in PHPMyAdmin, and make sure the “Collation” setting of the wp_postmeta table is identical on both servers (See screenshot). Additionally, make sure the DB_CHARSET & DB_COLLATE are identical on both websites in the wp-config.php file. You can also check that your PHP versions have identical configuration/version, and not some weird encoding parameters.

    In all cases, you can try to clone your website on an identical server, and you should be able to make the export/import work there.

    Unfortunately, I cannot really do much more here, as serialized data are very sensitive and depending on the server config. This is simply how they are handled by WordPress/PHP. Hopefully one day WordPress will handle Json meta values, which are more flexible and less prone to this kind of edge cases.

    Let me know if you found something.

    Hope it helps!

    Regards.

    Plugin Author Konrad Chmielewski

    (@hwk-fr)

    Hello,

    Any news about this issue?

    Thanks!

    Regards.

    Thread Starter fromb

    (@fromb)

    Hi Konrad, sorry about the delay. I haven’t had the time to test this workaround yet but I’ll come back to this issue later in the week. Thanks for following up.

    Plugin Author Konrad Chmielewski

    (@hwk-fr)

    Roger that!

    Thread Starter fromb

    (@fromb)

    Finally had some time to spend on this today, sorry for the delay.

    I’m ticking some of the boxes you mentioned above: many special characters, different SQL version (5 vs 8). And even though the charset and collation are identical I can see the empty array after importing.

    Luckily my client has a staging server that is identical to production so I’ll make sure to use that as a starting point for content, in stead of localhost.

    Thanks for deep diving into this, it will save me some headaches in the future ??

Viewing 7 replies - 1 through 7 (of 7 total)
  • You must be logged in to reply to this topic.