Wordpress unexpected return from get_categories

Viewed 96

TL;DR

Wordpress get_categories function doesn't return an Array if a category is not assigned to a post. Check at the end how to replicate this.

Context

Test Environment

Wordpress: 5.4.2 and 5.1.1

PHP: 7.4.7

I'm using the following custom endpoint to get all taxonomies from Wordpress, but somehow the type of response I get from get_categories isn't always the same.

function ca_get_taxonomy() {
  $categories = get_categories(array(
    'orderby' => 'name',
    'order'   => 'ASC'
  ));

  $tags = get_tags(array(
    'orderby' => 'name',
    'order'   => 'ASC'
  ));

  return array(
    'categories' => $categories,
    'tags' => $tags
  );
}

function custom_api() {
  register_rest_route('custom/v1', 'taxonomy', array(
    'methods' => WP_REST_SERVER::READABLE,
    'callback' => 'ca_get_taxonomy'
  ));
}

Expected Behavior

Wordpress documentation says the get_categories function returns an Array of objects. So the expected response would be something like this:

{
  "categories": [
    {
      "term_id": 3,
      ...
    },
    {
      "term_id": 1,
      ...
    }
  ],
  tags: [
    ...
  ]
}

The Problem

Scenario 1 (correct)

If all created categories are assigned to posts the response from get_categories is an Array which is expected.

Scenario 2

This is more tricky (seems to be random), but I think it's true when one of the created categories is not assigned to a post, or one category is not assigned to a post and contains a space (in category name not the category slug). In this case the response from get_categories is an Object like this:

{
  "categories": {
    "0": {
      "term_id": 3,
      ...
    },
    "1":, {
      "term_id": 1,
      ...
    }
  },
  tags: [
    ...
  ]
}

Notes

If I get the Object as a response and remove all categories in Wordpress (the default category will apply to all posts) will fix the problem and return again an Array. But as soon Scenario 2 applies the problem returns.

How to Replicate

  1. Download and install a new instance of Wordpress
  2. Create a folder inside wp-content/ named mu-plugins/
  3. Create a new file named rest.php inside that folder and past the code bellow.
  4. Visit yourSiteUrl/wp-json/custom/v1/taxonomy and you can see an Array with one Object inside (the default category)
  5. Now, go to Wordpress > Post > Categories and create a new category
  6. Visit again yourSiteUrl/wp-json/custom/v1/taxonomy and the response will now be an Object

rest.php

<?php
/*
Plugin Name: Custom Rest
*/

function ca_taxonomy() {
  $categories = get_categories(array(
    'orderby' => 'name',
    'order'   => 'ASC'
  ));

  return $categories;
}

function ca_api() {
  register_rest_route('custom/v1', 'taxonomy', array(
    'methods' => WP_REST_SERVER::READABLE,
    'callback' => 'ca_taxonomy'
  ));
}
add_action('rest_api_init', 'ca_api');

?>
0 Answers
Related