Getting error, while trying to use new MongoDB\BSON\ObjectId

Hello, everyone!

I am creating some logic for WordPress with MongoDB. My idea is to be able to search for document inside my database, based on a URL and load certain layout, if that document is present, or load 404 page if it is not.

Here is how my logic looks like:

function check_mongodb_for_exam($exam_id) {
    $uri = "..." // it is NOT like this in the original
    $client = new MongoDB\Client($uri);
	
    $db = $client->selectDatabase("test"); // NOT the real name
    $collection = $db->selectCollection("innertest"); // NOT the real name
	
    $objectID = new MongoDB\BSON\ObjectId($exam_id);
    $result = $collection->findOne(['_id' => $objectID]);

    return $result !== null;
}

add_action('template_redirect', 'custom_template_redirect');

function custom_template_redirect() {
    $url_path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
    $url_parts = explode('/', trim($url_path, '/'));
    $exam_id = end($url_parts);

    $exam_exists = check_mongodb_for_exam($exam_id);

    if ($exam_exists) {
        wp_redirect(get_permalink('1300')); 
        exit;
    }
}

So far so good, everything seems to work as expected, but the problem is that document with such id cannot be found inside the database. Here is the URL (this is not the real URL, but the structure is the same): https://hello.net/cakes/649d8aa7185es301045bca2d

So, as mentioned, the idea is for WordPress to see if the last part exists inside the database. However I get this error:

PHP message: PHP Fatal error:  Uncaught MongoDB\\Driver\\Exception\\InvalidArgumentException: Error parsing ObjectId string: testy in /var/www/vhosts/testyourself.net/httpdocs/wp-content/themes/TestYourself/functions.php:252\nStack trace:\n#0 /var/www/vhosts/testyourself.net/httpdocs/wp-content/themes/TestYourself/functions.php(252): MongoDB\\BSON\\ObjectId->__construct()\n#1 /var/www/vhosts/testyourself.net/httpdocs/wp-content/themes/TestYourself/functions.php(270): check_mongodb_for_exam()\n#2 /var/www/vhosts/testyourself.net/httpdocs/wp-includes/class-wp-hook.php(324): custom_template_redirect()\n#3 /var/www/vhosts/testyourself.net/httpdocs/wp-includes/class-wp-hook.php(348): WP_Hook->apply_filters()\n#4 /var/www/vhosts/testyourself.net/httpdocs/wp-includes/plugin.php(517): WP_Hook->do_action()\n#5 /var/www/vhosts/testyourself.net/httpdocs/wp-includes/template-loader.php(13): do_action()\n#6 /var/www/vhosts/testyourself.net/httpdocs/wp-blog-header.php(19): require_once('...')\n#7 /var/www/vhosts/testyourself.net/htt...', referer: http://wordpress-with-react.local/`

At first I was trying without converting the id to BSON, but, as said, there was nothing retrieved. The exam id, which is passed to check_mongodb_for_exam is a string, if I try with just find(), it retrieves everything properly. One of the documents, retrieved from find() has such id: "_id":{"$oid":"812d8ya7289eb302612bse2d"}. So my question is what I am doing wrong?

Thank you!

Hi @Ilia_Popov

As the error suggests, there is an issue in construction of the objectID. InvalidArgumentException is thrown likely because of the invalid format of string. Please double check the value of exam_id. It should be a 24-character hexadecimal string.
I’d also advice you to wrap your function in a try-catch block.

See docs for more details - PHP: MongoDB\BSON\ObjectId - Manual

Hello, @Rishabh_Bisht

This was quite unexpected, but it solved the issue. When I echo $exam_id;, it outputs 649d8aa7289eb300015bca2d, for example. I thought that this is the string that was needed. However, I used the strval() php method and it seems to work!

So now
$objectID = new MongoDB\BSON\ObjectId(strval($exam_id)); $result = $collection->findOne(['_id' => $objectID]);
is working as expected.

Thank you, for the reminder to check the values again!

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.