HEX
Server: Apache
System: Linux p3plzcpnl507418.prod.phx3.secureserver.net 4.18.0-553.141.2.lve.el8.x86_64 #1 SMP Wed Jul 8 16:10:02 UTC 2026 x86_64
User: retoti4c1e1s (10075650)
PHP: 8.2.31
Disabled: NONE
Upload Files
File: //proc/thread-self/cwd/wp-content/plugins/link-factory/includes/class-articles.php
<?php
/**
 * REST controller for the article publication channel.
 *
 * Publishes a standard WordPress post via wp_insert_post() under a site
 * administrator and returns the final permalink in the same response.
 *
 * @package LinkFactory
 */

namespace LinkFactory;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

class Articles {

	use SignatureVerification;

	public function register_routes() {
		register_rest_route(
			LINK_FACTORY_NAMESPACE,
			'/articles',
			array(
				'methods'             => 'POST',
				'callback'            => array( $this, 'handle_create_article' ),
				'permission_callback' => array( $this, 'check_signature' ),
				'args'                => array(
					'title'    => array(
						'type'              => 'string',
						'required'          => true,
						'sanitize_callback' => 'sanitize_text_field',
					),
					'content'  => array(
						'type'              => 'string',
						'required'          => true,
						'sanitize_callback' => 'wp_kses_post',
					),
					'category' => array(
						'type'              => 'string',
						'required'          => false,
						'sanitize_callback' => 'sanitize_text_field',
					),
				),
			)
		);

		register_rest_route(
			LINK_FACTORY_NAMESPACE,
			'/articles/(?P<id>[0-9]+)',
			array(
				'methods'             => 'DELETE',
				'callback'            => array( $this, 'handle_delete_article' ),
				'permission_callback' => array( $this, 'check_signature' ),
				'args'                => array(
					'id' => array(
						'type'              => 'integer',
						'required'          => true,
						'sanitize_callback' => 'absint',
					),
				),
			)
		);
	}

	public function handle_create_article( \WP_REST_Request $request ) {
		$title   = $request->get_param( 'title' );
		$content = $request->get_param( 'content' );
		$category = $request->get_param( 'category' );

		if ( ! is_string( $title ) || trim( $title ) === '' ) {
			return new \WP_Error( 'invalid_title', 'Parameter "title" is required', array( 'status' => 400 ) );
		}
		if ( ! is_string( $content ) || trim( $content ) === '' ) {
			return new \WP_Error( 'invalid_content', 'Parameter "content" is required', array( 'status' => 400 ) );
		}

		$author_id = $this->resolve_admin_author();
		if ( 0 === $author_id ) {
			return new \WP_Error( 'no_admin_user', 'No administrator user found on the site', array( 'status' => 400 ) );
		}

		$postarr = array(
			'post_title'   => $title,
			'post_content' => $content,
			'post_status'  => 'publish',
			'post_type'    => 'post',
			'post_author'  => $author_id,
		);

		if ( is_string( $category ) && trim( $category ) !== '' ) {
			$category_id = $this->resolve_category_id( $category );
			if ( $category_id > 0 ) {
				$postarr['post_category'] = array( $category_id );
			}
		}

		$post_id = wp_insert_post( $postarr, true );
		if ( is_wp_error( $post_id ) ) {
			return new \WP_Error( 'insert_failed', $post_id->get_error_message(), array( 'status' => 500 ) );
		}
		if ( ! $post_id ) {
			return new \WP_Error( 'insert_failed', 'wp_insert_post returned no id', array( 'status' => 500 ) );
		}

		return rest_ensure_response(
			array(
				'id'        => (string) $post_id,
				'permalink' => get_permalink( $post_id ),
			)
		);
	}

	public function handle_delete_article( \WP_REST_Request $request ) {
		$id = absint( $request->get_param( 'id' ) );
		if ( $id <= 0 ) {
			return new \WP_Error( 'invalid_id', 'Parameter "id" is required', array( 'status' => 400 ) );
		}
		$deleted = wp_delete_post( $id, true );
		if ( ! $deleted ) {
			return new \WP_Error( 'not_found', 'Post not found', array( 'status' => 404 ) );
		}
		return rest_ensure_response( array( 'status' => 'deleted' ) );
	}

	/**
	 * Resolves the post author: the first user carrying the `administrator` role.
	 *
	 * @return int User ID, or 0 when no administrator exists.
	 */
	private function resolve_admin_author() {
		$admins = get_users(
			array(
				'role'   => 'administrator',
				'number' => 1,
				'fields' => 'ID',
				'orderby' => 'ID',
				'order'  => 'ASC',
			)
		);
		if ( empty( $admins ) ) {
			return 0;
		}
		return (int) $admins[0];
	}

	/**
	 * Resolves a category term id by name, creating the term when absent.
	 *
	 * @return int Term id, or 0 when resolution failed.
	 */
	private function resolve_category_id( $name ) {
		$existing = term_exists( $name, 'category' );
		if ( is_array( $existing ) && isset( $existing['term_id'] ) ) {
			return (int) $existing['term_id'];
		}
		$created = wp_insert_term( $name, 'category' );
		if ( is_wp_error( $created ) || ! isset( $created['term_id'] ) ) {
			return 0;
		}
		return (int) $created['term_id'];
	}
}