# betterdocs/4.9.2/includes/REST/CategoryField.php

BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ &amp; Chatbot, version 4.9.2. 133 lines.

- Page: https://pluginprobe.com/plugins/betterdocs/4.9.2/code/includes/REST/CategoryField.php
- Raw: https://pluginprobe.com/plugins/betterdocs/4.9.2/raw/includes/REST/CategoryField.php
- Modified: 2026-07-07T09:55:00+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/betterdocs/4.9.2/code/includes/REST/CategoryField.php#L10-L20`.

```php
<?php

namespace WPDeveloper\BetterDocs\REST;

use WPDeveloper\BetterDocs\Core\BaseAPI;

class CategoryField extends BaseAPI {
	/**
	 * @return mixed
	 */
	public function register() {
		$this->register_field(
			'doc_category',
			'doc_category_order',
			[
				'get_callback'    => [ $this, 'doc_category_order' ],
				'update_callback' => [ $this, 'update_doc_category_order' ],
				// Explicit schema — otherwise BaseAPI's default (a string "thumbnail
				// URL" schema) applies and the React slide-over's integer order write
				// fails validation with "not of type string".
				'schema'          => [
					'description' => 'BetterDocs doc category display order.',
					'type'        => [ 'integer', 'null' ],
					'context'     => [ 'view', 'edit' ],
					// Skip the built-in type check and coerce to int|null ourselves
					// (a null/empty value is a no-op upstream).
					'arg_options' => [
						'validate_callback' => '__return_true',
						'sanitize_callback' => function ( $value ) {
							return ( null === $value || '' === $value ) ? null : (int) $value;
						},
					],
				],
			]
		);
		$this->register_field(
			'doc_category',
			'thumbnail',
			[
				'get_callback' => [ $this, 'thumbnail_image' ]
			]
		);
		$this->register_field(
			'doc_category',
			'handbookthumbnail',
			[
				'get_callback' => [ $this, 'handbook_thumbnail_image' ]
			]
		);
		$this->register_field(
			'doc_category',
			'subcategories_count',
			[
				'get_callback' => [ $this, 'get_subcategory_count' ]
			]
		);
		$this->register_field(
			'doc_category',
			'total_docs_count',
			[
				'get_callback' => [ $this, 'total_docs_count' ]
			]
		);
		$this->register_field(
			'doc_category',
			'last_updated_time',
			[
				'get_callback' => [ $this, 'last_updated_time' ]
			]
		);
	}

	public function last_updated_time( $object ) {
		$date = betterdocs()->query->latest_updated_date( $object['taxonomy'], $object['slug'] );
		return $date;
	}

	public function doc_category_order( $object ) {
		// Get language-specific meta key with fallback for multilingual sites
		$meta_key = \WPDeveloper\BetterDocs\Utils\Helper::get_meta_key_with_fallback( 'doc_category_order', $object['id'] );
		$doc_category_order = get_term_meta( $object['id'], $meta_key, true );

		// If still no order found, try the base key as final fallback
		if ( '' === $doc_category_order || null === $doc_category_order ) {
			$doc_category_order = get_term_meta( $object['id'], 'doc_category_order', true );
		}

		return ( '' === $doc_category_order || null === $doc_category_order ) ? null : (int) $doc_category_order;
	}

	/**
	 * Persist the display order written from the React Doc Categories slide-over.
	 * Uses the same language-aware meta key as the reader. $term is a WP_Term.
	 */
	public function update_doc_category_order( $value, $term ) {
		if ( null === $value || '' === $value ) {
			return;
		}
		$meta_key = \WPDeveloper\BetterDocs\Utils\Helper::get_meta_key_with_fallback( 'doc_category_order', $term->term_id );
		update_term_meta( $term->term_id, $meta_key, (int) $value );
	}

	public function thumbnail_image( $object ) {
		$attachment_id = get_term_meta( $object['id'], 'doc_category_image-id', true );
		if ( ! $attachment_id ) {
			return;
		}

		return wp_get_attachment_url( $attachment_id );
	}

	public function handbook_thumbnail_image( $object ) {
		$handbook_img_id = get_term_meta( $object['id'], 'doc_category_thumb-id', true );

		if ( ! $handbook_img_id ) {
			return;
		}

		return wp_get_attachment_url( $handbook_img_id );
	}

	public function get_subcategory_count( $object ) {
		$sub_terms_count = count( betterdocs()->query->get_all_child_term_ids( 'doc_category', $object['id'] ) );

		return $sub_terms_count;
	}

	public function total_docs_count( $object ) {
		$docs_count = betterdocs()->query->get_docs_count( (object) $object, false );
		return $docs_count;
	}
}

```
