diff --git a/inc/Abilities/Bluesky/BlueskyDeleteAbility.php b/inc/Abilities/Bluesky/BlueskyDeleteAbility.php index 70b9594ac..e86615c11 100644 --- a/inc/Abilities/Bluesky/BlueskyDeleteAbility.php +++ b/inc/Abilities/Bluesky/BlueskyDeleteAbility.php @@ -77,28 +77,19 @@ public function checkPermission(): bool { return PermissionHelper::can_manage(); } - public function execute( array $input ): array { + public function execute( array $input ): array|\WP_Error { $auth = $this->getAuthProvider(); if ( ! $auth ) { - return array( - 'success' => false, - 'error' => 'Bluesky auth provider not available', - ); + return new \WP_Error( 'missing_auth', 'Bluesky auth provider not available', array( 'status' => 401 ) ); } $session = $auth->get_session(); if ( empty( $session['accessJwt'] ) ) { - return array( - 'success' => false, - 'error' => 'Bluesky session not available', - ); + return new \WP_Error( 'missing_auth', 'Bluesky session not available', array( 'status' => 401 ) ); } if ( empty( $input['post_uri'] ) ) { - return array( - 'success' => false, - 'error' => 'post_uri is required', - ); + return new \WP_Error( 'missing_param', 'post_uri is required', array( 'status' => 400 ) ); } $did = $session['did']; @@ -109,10 +100,7 @@ public function execute( array $input ): array { $rkey = end( $uri_parts ); if ( empty( $rkey ) ) { - return array( - 'success' => false, - 'error' => 'Could not extract rkey from post URI: ' . $post_uri, - ); + return new \WP_Error( 'api_error', 'Could not extract rkey from post URI: ' . $post_uri, array( 'status' => 500 ) ); } $response = wp_remote_post( @@ -132,10 +120,7 @@ public function execute( array $input ): array { ); if ( is_wp_error( $response ) ) { - return array( - 'success' => false, - 'error' => $response->get_error_message(), - ); + return new \WP_Error( 'api_error', $response->get_error_message(), array( 'status' => 500 ) ); } $status_code = wp_remote_retrieve_response_code( $response ); @@ -151,10 +136,7 @@ public function execute( array $input ): array { } $body = json_decode( wp_remote_retrieve_body( $response ), true ); - return array( - 'success' => false, - 'error' => $body['error'] ?? 'Failed to delete post', - ); + return new \WP_Error( 'api_error', $body['error'] ?? 'Failed to delete post', array( 'status' => 500 ) ); } private function getAuthProvider(): ?BlueskyAuth { diff --git a/inc/Abilities/Bluesky/BlueskyPublishAbility.php b/inc/Abilities/Bluesky/BlueskyPublishAbility.php index 411497c63..da4f8922c 100644 --- a/inc/Abilities/Bluesky/BlueskyPublishAbility.php +++ b/inc/Abilities/Bluesky/BlueskyPublishAbility.php @@ -134,36 +134,27 @@ private function registerAbilities(): void { * @param array $input Ability input with publish parameters. * @return array Response with post details or error. */ - public static function execute_publish( array $input ): array { + public static function execute_publish( array $input ): array|\WP_Error { $content = $input['content'] ?? ''; $title = $input['title'] ?? ''; $image_url = $input['image_url'] ?? ''; $source_url = $input['source_url'] ?? ''; if ( empty( $content ) ) { - return array( - 'success' => false, - 'error' => 'Content is required', - ); + return new \WP_Error( 'missing_param', 'Content is required', array( 'status' => 400 ) ); } $auth = new AuthAbilities(); $provider = $auth->getProvider( 'bluesky' ); if ( ! $provider || ! $provider->is_authenticated() ) { - return array( - 'success' => false, - 'error' => 'Bluesky not authenticated', - ); + return new \WP_Error( 'missing_auth', 'Bluesky not authenticated', array( 'status' => 401 ) ); } // Use the provider's session method which handles auth internally. $session = $provider->get_session(); if ( is_wp_error( $session ) ) { - return array( - 'success' => false, - 'error' => $session->get_error_message(), - ); + return new \WP_Error( 'api_error', $session->get_error_message(), array( 'status' => 500 ) ); } $handle = $session['handle']; @@ -244,10 +235,7 @@ public static function execute_publish( array $input ): array { ); if ( is_wp_error( $response ) ) { - return array( - 'success' => false, - 'error' => $response->get_error_message(), - ); + return new \WP_Error( 'api_error', $response->get_error_message(), array( 'status' => 500 ) ); } $status_code = wp_remote_retrieve_response_code( $response ); @@ -271,10 +259,7 @@ public static function execute_publish( array $input ): array { $error_msg = $data['message']; } - return array( - 'success' => false, - 'error' => $error_msg, - ); + return new \WP_Error( 'api_error', $error_msg, array( 'status' => 500 ) ); } /** @@ -283,16 +268,13 @@ public static function execute_publish( array $input ): array { * @param array $input Ability input. * @return array Account details or error. */ - public static function get_account( array $input ): array { + public static function get_account( array $input ): array|\WP_Error { $input; $auth = new AuthAbilities(); $provider = $auth->getProvider( 'bluesky' ); if ( ! $provider || ! $provider->is_authenticated() ) { - return array( - 'success' => false, - 'error' => 'Bluesky not authenticated', - ); + return new \WP_Error( 'missing_auth', 'Bluesky not authenticated', array( 'status' => 401 ) ); } $details = $provider->get_account_details(); @@ -358,7 +340,7 @@ private static function upload_image( string $access_token, string $image_url ): * @param string $text Post text to scan for URLs. * @return array Array of facet objects, empty if no URLs found. */ - private static function extract_url_facets( string $text ): array { + private static function extract_url_facets( string $text ): array|\WP_Error { $facets = array(); // Match URLs in the text. @@ -401,7 +383,7 @@ private static function extract_url_facets( string $text ): array { * @param string $url URL to fetch OG tags from. * @return array Associative array with 'title', 'description', 'image' keys (empty strings if not found). */ - private static function fetch_og_tags( string $url ): array { + private static function fetch_og_tags( string $url ): array|\WP_Error { $defaults = array( 'title' => '', 'description' => '', diff --git a/inc/Abilities/Bluesky/BlueskyReadAbility.php b/inc/Abilities/Bluesky/BlueskyReadAbility.php index dc94b5244..e366454a7 100644 --- a/inc/Abilities/Bluesky/BlueskyReadAbility.php +++ b/inc/Abilities/Bluesky/BlueskyReadAbility.php @@ -93,30 +93,21 @@ public function checkPermission(): bool { return PermissionHelper::can_manage(); } - public function execute( array $input ): array { + public function execute( array $input ): array|\WP_Error { $action = $input['action'] ?? 'list'; $auth = $this->getAuthProvider(); if ( ! $auth ) { - return array( - 'success' => false, - 'error' => 'Bluesky auth provider not available', - ); + return new \WP_Error( 'missing_auth', 'Bluesky auth provider not available', array( 'status' => 401 ) ); } $session = $auth->get_session(); if ( is_wp_error( $session ) ) { - return array( - 'success' => false, - 'error' => 'Bluesky session creation failed: ' . $session->get_error_message(), - ); + return new \WP_Error( 'api_error', 'Bluesky session creation failed: ' . $session->get_error_message(), array( 'status' => 500 ) ); } if ( empty( $session['accessJwt'] ) ) { - return array( - 'success' => false, - 'error' => 'Bluesky authentication failed (no access token in session)', - ); + return new \WP_Error( 'missing_auth', 'Bluesky authentication failed (no access token in session)', array( 'status' => 401 ) ); } $pds_url = $session['pds_url'] ?? 'https://bsky.social'; @@ -130,10 +121,7 @@ public function execute( array $input ): array { case 'get': if ( empty( $input['post_uri'] ) ) { - return array( - 'success' => false, - 'error' => 'post_uri is required for the get action', - ); + return new \WP_Error( 'missing_param', 'post_uri is required for the get action', array( 'status' => 400 ) ); } return $this->getPostThread( $pds_url, $access_token, $input['post_uri'] ); @@ -141,19 +129,13 @@ public function execute( array $input ): array { return $this->getProfile( $pds_url, $access_token, $did ? $did : $handle ); default: - return array( - 'success' => false, - 'error' => "Unknown action: {$action}. Use list, get, or profile.", - ); + return new \WP_Error( 'api_error', "Unknown action: {$action}. Use list, get, or profile.", array( 'status' => 500 ) ); } } - private function listPosts( string $pds_url, string $access_token, string $actor, array $input ): array { + private function listPosts( string $pds_url, string $access_token, string $actor, array $input ): array|\WP_Error { if ( empty( $actor ) ) { - return array( - 'success' => false, - 'error' => 'Bluesky DID/handle not available. Try re-authenticating.', - ); + return new \WP_Error( 'missing_auth', 'Bluesky DID/handle not available. Try re-authenticating.', array( 'status' => 401 ) ); } $limit = min( absint( $input['limit'] ?? 25 ), 100 ); @@ -176,10 +158,7 @@ private function listPosts( string $pds_url, string $access_token, string $actor ); if ( ! $result['success'] ) { - return array( - 'success' => false, - 'error' => 'Bluesky API request failed: ' . ( $result['error'] ?? 'unknown' ), - ); + return new \WP_Error( 'api_error', 'Bluesky API request failed: ' . ( $result['error'] ?? 'unknown' ), array( 'status' => 500 ) ); } $data = json_decode( $result['data'], true ); @@ -187,10 +166,7 @@ private function listPosts( string $pds_url, string $access_token, string $actor if ( 200 !== $http_code || isset( $data['error'] ) ) { $error_msg = $data['message'] ?? $data['error'] ?? 'Failed to fetch Bluesky feed'; - return array( - 'success' => false, - 'error' => $error_msg, - ); + return new \WP_Error( 'api_error', $error_msg, array( 'status' => 500 ) ); } $feed = $data['feed'] ?? array(); @@ -207,7 +183,7 @@ private function listPosts( string $pds_url, string $access_token, string $actor ); } - private function getPostThread( string $pds_url, string $access_token, string $post_uri ): array { + private function getPostThread( string $pds_url, string $access_token, string $post_uri ): array|\WP_Error { $params = array( 'uri' => $post_uri, 'depth' => 6, @@ -223,10 +199,7 @@ private function getPostThread( string $pds_url, string $access_token, string $p ); if ( ! $result['success'] ) { - return array( - 'success' => false, - 'error' => 'Bluesky API request failed: ' . ( $result['error'] ?? 'unknown' ), - ); + return new \WP_Error( 'api_error', 'Bluesky API request failed: ' . ( $result['error'] ?? 'unknown' ), array( 'status' => 500 ) ); } $data = json_decode( $result['data'], true ); @@ -234,10 +207,7 @@ private function getPostThread( string $pds_url, string $access_token, string $p if ( 200 !== $http_code || isset( $data['error'] ) ) { $error_msg = $data['message'] ?? $data['error'] ?? 'Failed to fetch post thread'; - return array( - 'success' => false, - 'error' => $error_msg, - ); + return new \WP_Error( 'api_error', $error_msg, array( 'status' => 500 ) ); } return array( @@ -246,7 +216,7 @@ private function getPostThread( string $pds_url, string $access_token, string $p ); } - private function getProfile( string $pds_url, string $access_token, string $actor ): array { + private function getProfile( string $pds_url, string $access_token, string $actor ): array|\WP_Error { $params = array( 'actor' => $actor ); $url = $pds_url . '/xrpc/app.bsky.actor.getProfile?' . http_build_query( $params ); @@ -259,10 +229,7 @@ private function getProfile( string $pds_url, string $access_token, string $acto ); if ( ! $result['success'] ) { - return array( - 'success' => false, - 'error' => 'Bluesky API request failed: ' . ( $result['error'] ?? 'unknown' ), - ); + return new \WP_Error( 'api_error', 'Bluesky API request failed: ' . ( $result['error'] ?? 'unknown' ), array( 'status' => 500 ) ); } $data = json_decode( $result['data'], true ); @@ -270,10 +237,7 @@ private function getProfile( string $pds_url, string $access_token, string $acto if ( 200 !== $http_code || isset( $data['error'] ) ) { $error_msg = $data['message'] ?? $data['error'] ?? 'Failed to fetch profile'; - return array( - 'success' => false, - 'error' => $error_msg, - ); + return new \WP_Error( 'api_error', $error_msg, array( 'status' => 500 ) ); } return array( diff --git a/inc/Abilities/Bluesky/BlueskyUpdateAbility.php b/inc/Abilities/Bluesky/BlueskyUpdateAbility.php index da9307b6d..f8ad235ef 100644 --- a/inc/Abilities/Bluesky/BlueskyUpdateAbility.php +++ b/inc/Abilities/Bluesky/BlueskyUpdateAbility.php @@ -83,30 +83,21 @@ public function checkPermission(): bool { return PermissionHelper::can_manage(); } - public function execute( array $input ): array { + public function execute( array $input ): array|\WP_Error { $action = $input['action'] ?? ''; $auth = $this->getAuthProvider(); if ( ! $auth ) { - return array( - 'success' => false, - 'error' => 'Bluesky auth provider not available', - ); + return new \WP_Error( 'missing_auth', 'Bluesky auth provider not available', array( 'status' => 401 ) ); } $session = $auth->get_session(); if ( empty( $session['accessJwt'] ) ) { - return array( - 'success' => false, - 'error' => 'Bluesky session not available', - ); + return new \WP_Error( 'missing_auth', 'Bluesky session not available', array( 'status' => 401 ) ); } if ( empty( $input['post_uri'] ) ) { - return array( - 'success' => false, - 'error' => 'post_uri is required', - ); + return new \WP_Error( 'missing_param', 'post_uri is required', array( 'status' => 400 ) ); } $post_uri = $input['post_uri']; @@ -122,10 +113,7 @@ public function execute( array $input ): array { return $this->unlikePost( $session); default: - return array( - 'success' => false, - 'error' => "Unknown action: {$action}. Use delete, like, or unlike.", - ); + return new \WP_Error( 'api_error', "Unknown action: {$action}. Use delete, like, or unlike.", array( 'status' => 500 ) ); } } @@ -144,7 +132,7 @@ private function getAuthProvider(): ?BlueskyAuth { return $provider; } - private function deletePost( array $session, string $post_uri ): array { + private function deletePost( array $session, string $post_uri ): array|\WP_Error { $pds_url = $session['pds_url']; $did = $session['did']; @@ -174,10 +162,7 @@ private function deletePost( array $session, string $post_uri ): array { ); if ( is_wp_error( $response ) ) { - return array( - 'success' => false, - 'error' => $response->get_error_message(), - ); + return new \WP_Error( 'api_error', $response->get_error_message(), array( 'status' => 500 ) ); } $status_code = wp_remote_retrieve_response_code( $response ); @@ -193,13 +178,10 @@ private function deletePost( array $session, string $post_uri ): array { } $body = json_decode( wp_remote_retrieve_body( $response ), true ); - return array( - 'success' => false, - 'error' => $body['error'] ?? 'Failed to delete post', - ); + return new \WP_Error( 'api_error', $body['error'] ?? 'Failed to delete post', array( 'status' => 500 ) ); } - private function likePost( array $session, string $post_uri ): array { + private function likePost( array $session, string $post_uri ): array|\WP_Error { $pds_url = $session['pds_url']; $did = $session['did']; @@ -228,10 +210,7 @@ private function likePost( array $session, string $post_uri ): array { ); if ( is_wp_error( $response ) ) { - return array( - 'success' => false, - 'error' => $response->get_error_message(), - ); + return new \WP_Error( 'api_error', $response->get_error_message(), array( 'status' => 500 ) ); } $status_code = wp_remote_retrieve_response_code( $response ); @@ -248,21 +227,15 @@ private function likePost( array $session, string $post_uri ): array { ); } - return array( - 'success' => false, - 'error' => $body['error'] ?? 'Failed to like post', - ); + return new \WP_Error( 'api_error', $body['error'] ?? 'Failed to like post', array( 'status' => 500 ) ); } - private function unlikePost( array $session): array { + private function unlikePost( array $session): array|\WP_Error { $pds_url = $session['pds_url']; $did = $session['did']; // Unlike requires the like URI which we don't have stored. // This is a limitation - user would need to query likes first. - return array( - 'success' => false, - 'error' => 'Unlike requires the like URI. Query likes first to get the like record to delete.', - ); + return new \WP_Error( 'api_error', 'Unlike requires the like URI. Query likes first to get the like record to delete.', array( 'status' => 500 ) ); } } diff --git a/inc/Abilities/Facebook/FacebookDeleteAbility.php b/inc/Abilities/Facebook/FacebookDeleteAbility.php index 35a8aa040..3157c2711 100644 --- a/inc/Abilities/Facebook/FacebookDeleteAbility.php +++ b/inc/Abilities/Facebook/FacebookDeleteAbility.php @@ -79,28 +79,19 @@ public function checkPermission(): bool { return PermissionHelper::can_manage(); } - public function execute( array $input ): array { + public function execute( array $input ): array|\WP_Error { $auth = $this->getAuthProvider(); if ( ! $auth ) { - return array( - 'success' => false, - 'error' => 'Facebook auth provider not available', - ); + return new \WP_Error( 'missing_auth', 'Facebook auth provider not available', array( 'status' => 401 ) ); } $access_token = $auth->get_page_access_token(); if ( empty( $access_token ) ) { - return array( - 'success' => false, - 'error' => 'Facebook page access token unavailable', - ); + return new \WP_Error( 'missing_auth', 'Facebook page access token unavailable', array( 'status' => 401 ) ); } if ( empty( $input['post_id'] ) ) { - return array( - 'success' => false, - 'error' => 'post_id is required', - ); + return new \WP_Error( 'missing_param', 'post_id is required', array( 'status' => 400 ) ); } $url = self::GRAPH_API_URL . '/' . rawurlencode( $input['post_id'] ); @@ -117,10 +108,7 @@ public function execute( array $input ): array { ); if ( is_wp_error( $response ) ) { - return array( - 'success' => false, - 'error' => $response->get_error_message(), - ); + return new \WP_Error( 'api_error', $response->get_error_message(), array( 'status' => 500 ) ); } $status_code = wp_remote_retrieve_response_code( $response ); @@ -136,10 +124,7 @@ public function execute( array $input ): array { ); } - return array( - 'success' => false, - 'error' => $body['error']['message'] ?? 'Failed to delete post', - ); + return new \WP_Error( 'api_error', $body['error']['message'] ?? 'Failed to delete post', array( 'status' => 500 ) ); } private function getAuthProvider(): ?FacebookAuth { diff --git a/inc/Abilities/Facebook/FacebookPublishAbility.php b/inc/Abilities/Facebook/FacebookPublishAbility.php index 0b1ad4be5..087c8e036 100644 --- a/inc/Abilities/Facebook/FacebookPublishAbility.php +++ b/inc/Abilities/Facebook/FacebookPublishAbility.php @@ -144,7 +144,7 @@ private function registerAbilities(): void { * @param array $input Ability input with publish parameters. * @return array Response with post details or error. */ - public static function execute_publish( array $input ): array { + public static function execute_publish( array $input ): array|\WP_Error { $title = $input['title'] ?? ''; $content = $input['content'] ?? ''; $image_url = $input['image_url'] ?? ''; @@ -152,37 +152,25 @@ public static function execute_publish( array $input ): array { $link_handling = $input['link_handling'] ?? 'append'; if ( empty( $content ) ) { - return array( - 'success' => false, - 'error' => 'Content is required', - ); + return new \WP_Error( 'missing_param', 'Content is required', array( 'status' => 400 ) ); } $auth = new AuthAbilities(); $provider = $auth->getProvider( 'facebook' ); if ( ! $provider || ! $provider->is_authenticated() ) { - return array( - 'success' => false, - 'error' => 'Facebook not authenticated', - ); + return new \WP_Error( 'missing_auth', 'Facebook not authenticated', array( 'status' => 401 ) ); } $page_id = $provider->get_page_id(); $page_access_token = $provider->get_page_access_token(); if ( empty( $page_id ) ) { - return array( - 'success' => false, - 'error' => 'Facebook page not found', - ); + return new \WP_Error( 'not_found', 'Facebook page not found', array( 'status' => 404 ) ); } if ( empty( $page_access_token ) ) { - return array( - 'success' => false, - 'error' => 'Facebook page access token not available', - ); + return new \WP_Error( 'missing_auth', 'Facebook page access token not available', array( 'status' => 401 ) ); } // Format post content @@ -218,10 +206,7 @@ public static function execute_publish( array $input ): array { ); if ( is_wp_error( $response ) ) { - return array( - 'success' => false, - 'error' => $response->get_error_message(), - ); + return new \WP_Error( 'api_error', $response->get_error_message(), array( 'status' => 500 ) ); } $status_code = wp_remote_retrieve_response_code( $response ); @@ -255,10 +240,7 @@ public static function execute_publish( array $input ): array { $error_msg = $data['error']['message']; } - return array( - 'success' => false, - 'error' => $error_msg, - ); + return new \WP_Error( 'api_error', $error_msg, array( 'status' => 500 ) ); } /** @@ -267,16 +249,13 @@ public static function execute_publish( array $input ): array { * @param array $input Ability input. * @return array Pages or error. */ - public static function get_pages( array $input ): array { + public static function get_pages( array $input ): array|\WP_Error { $input; $auth = new AuthAbilities(); $provider = $auth->getProvider( 'facebook' ); if ( ! $provider || ! $provider->is_authenticated() ) { - return array( - 'success' => false, - 'error' => 'Facebook not authenticated', - ); + return new \WP_Error( 'missing_auth', 'Facebook not authenticated', array( 'status' => 401 ) ); } // Get pages from provider or make API call @@ -334,7 +313,7 @@ private static function upload_photo( string $page_id, string $access_token, str * @param string $access_token Access token. * @return array Comment details. */ - private static function post_comment( string $post_id, string $message, string $access_token ): array { + private static function post_comment( string $post_id, string $message, string $access_token ): array|\WP_Error { $url = self::build_graph_url( "{$post_id}/comments" ); $response = wp_remote_post( @@ -349,10 +328,7 @@ private static function post_comment( string $post_id, string $message, string $ ); if ( is_wp_error( $response ) ) { - return array( - 'success' => false, - 'error' => $response->get_error_message(), - ); + return new \WP_Error( 'api_error', $response->get_error_message(), array( 'status' => 500 ) ); } $status_code = wp_remote_retrieve_response_code( $response ); @@ -370,10 +346,7 @@ private static function post_comment( string $post_id, string $message, string $ ); } - return array( - 'success' => false, - 'error' => $data['error']['message'] ?? 'Failed to post comment', - ); + return new \WP_Error( 'api_error', $data['error']['message'] ?? 'Failed to post comment', array( 'status' => 500 ) ); } /** diff --git a/inc/Abilities/Facebook/FacebookReadAbility.php b/inc/Abilities/Facebook/FacebookReadAbility.php index ef87f7482..2e54a4dbf 100644 --- a/inc/Abilities/Facebook/FacebookReadAbility.php +++ b/inc/Abilities/Facebook/FacebookReadAbility.php @@ -97,24 +97,18 @@ public function checkPermission(): bool { return PermissionHelper::can_manage(); } - public function execute( array $input ): array { + public function execute( array $input ): array|\WP_Error { $action = $input['action'] ?? 'list'; $auth = $this->getAuthProvider(); if ( ! $auth ) { - return array( - 'success' => false, - 'error' => 'Facebook auth provider not available', - ); + return new \WP_Error( 'missing_auth', 'Facebook auth provider not available', array( 'status' => 401 ) ); } // Facebook uses page_access_token for page operations. $page_token = $auth->get_page_access_token(); if ( empty( $page_token ) ) { - return array( - 'success' => false, - 'error' => 'Facebook page access token unavailable (expired or refresh failed)', - ); + return new \WP_Error( 'missing_auth', 'Facebook page access token unavailable (expired or refresh failed)', array( 'status' => 401 ) ); } switch ( $action ) { @@ -123,37 +117,25 @@ public function execute( array $input ): array { case 'get': if ( empty( $input['post_id'] ) ) { - return array( - 'success' => false, - 'error' => 'post_id is required for the get action', - ); + return new \WP_Error( 'missing_param', 'post_id is required for the get action', array( 'status' => 400 ) ); } return $this->getPost( $page_token, $input['post_id'] ); case 'comments': if ( empty( $input['post_id'] ) ) { - return array( - 'success' => false, - 'error' => 'post_id is required for the comments action', - ); + return new \WP_Error( 'missing_param', 'post_id is required for the comments action', array( 'status' => 400 ) ); } return $this->getComments( $page_token, $input['post_id'], $input ); default: - return array( - 'success' => false, - 'error' => "Unknown action: {$action}. Use list, get, or comments.", - ); + return new \WP_Error( 'api_error', "Unknown action: {$action}. Use list, get, or comments.", array( 'status' => 500 ) ); } } - private function listPosts( FacebookAuth $auth, string $page_token, array $input ): array { + private function listPosts( FacebookAuth $auth, string $page_token, array $input ): array|\WP_Error { $page_id = $auth->get_page_id(); if ( empty( $page_id ) ) { - return array( - 'success' => false, - 'error' => 'Facebook Page ID not available. Try re-authenticating.', - ); + return new \WP_Error( 'missing_auth', 'Facebook Page ID not available. Try re-authenticating.', array( 'status' => 401 ) ); } $limit = min( absint( $input['limit'] ?? 25 ), 100 ); @@ -171,10 +153,7 @@ private function listPosts( FacebookAuth $auth, string $page_token, array $input $result = HttpClient::get( $url, array( 'context' => 'Facebook Read' ) ); if ( ! $result['success'] ) { - return array( - 'success' => false, - 'error' => 'Facebook API request failed: ' . ( $result['error'] ?? 'unknown' ), - ); + return new \WP_Error( 'api_error', 'Facebook API request failed: ' . ( $result['error'] ?? 'unknown' ), array( 'status' => 500 ) ); } $data = json_decode( $result['data'], true ); @@ -182,10 +161,7 @@ private function listPosts( FacebookAuth $auth, string $page_token, array $input if ( 200 !== $http_code || isset( $data['error'] ) ) { $error_msg = $data['error']['message'] ?? 'Failed to fetch Facebook posts'; - return array( - 'success' => false, - 'error' => $error_msg, - ); + return new \WP_Error( 'api_error', $error_msg, array( 'status' => 500 ) ); } $posts = $data['data'] ?? array(); @@ -202,7 +178,7 @@ private function listPosts( FacebookAuth $auth, string $page_token, array $input ); } - private function getPost( string $page_token, string $post_id ): array { + private function getPost( string $page_token, string $post_id ): array|\WP_Error { $params = array( 'fields' => self::DETAIL_FIELDS, 'access_token' => $page_token, @@ -212,10 +188,7 @@ private function getPost( string $page_token, string $post_id ): array { $result = HttpClient::get( $url, array( 'context' => 'Facebook Read' ) ); if ( ! $result['success'] ) { - return array( - 'success' => false, - 'error' => 'Facebook API request failed: ' . ( $result['error'] ?? 'unknown' ), - ); + return new \WP_Error( 'api_error', 'Facebook API request failed: ' . ( $result['error'] ?? 'unknown' ), array( 'status' => 500 ) ); } $data = json_decode( $result['data'], true ); @@ -223,10 +196,7 @@ private function getPost( string $page_token, string $post_id ): array { if ( 200 !== $http_code || isset( $data['error'] ) ) { $error_msg = $data['error']['message'] ?? 'Failed to fetch Facebook post details'; - return array( - 'success' => false, - 'error' => $error_msg, - ); + return new \WP_Error( 'api_error', $error_msg, array( 'status' => 500 ) ); } return array( @@ -235,7 +205,7 @@ private function getPost( string $page_token, string $post_id ): array { ); } - private function getComments( string $page_token, string $post_id, array $input ): array { + private function getComments( string $page_token, string $post_id, array $input ): array|\WP_Error { $limit = min( absint( $input['limit'] ?? 25 ), 100 ); $params = array( 'fields' => 'id,message,created_time,from,like_count', @@ -251,10 +221,7 @@ private function getComments( string $page_token, string $post_id, array $input $result = HttpClient::get( $url, array( 'context' => 'Facebook Read' ) ); if ( ! $result['success'] ) { - return array( - 'success' => false, - 'error' => 'Facebook API request failed: ' . ( $result['error'] ?? 'unknown' ), - ); + return new \WP_Error( 'api_error', 'Facebook API request failed: ' . ( $result['error'] ?? 'unknown' ), array( 'status' => 500 ) ); } $data = json_decode( $result['data'], true ); @@ -262,10 +229,7 @@ private function getComments( string $page_token, string $post_id, array $input if ( 200 !== $http_code || isset( $data['error'] ) ) { $error_msg = $data['error']['message'] ?? 'Failed to fetch comments'; - return array( - 'success' => false, - 'error' => $error_msg, - ); + return new \WP_Error( 'api_error', $error_msg, array( 'status' => 500 ) ); } $comments = $data['data'] ?? array(); diff --git a/inc/Abilities/Facebook/FacebookUpdateAbility.php b/inc/Abilities/Facebook/FacebookUpdateAbility.php index dacb76d78..b4b4c9115 100644 --- a/inc/Abilities/Facebook/FacebookUpdateAbility.php +++ b/inc/Abilities/Facebook/FacebookUpdateAbility.php @@ -100,31 +100,22 @@ public function checkPermission(): bool { * @param array $input Input parameters. * @return array Result. */ - public function execute( array $input ): array { + public function execute( array $input ): array|\WP_Error { $action = $input['action'] ?? ''; // Get auth provider. $auth = $this->getAuthProvider(); if ( ! $auth ) { - return array( - 'success' => false, - 'error' => 'Facebook auth provider not available', - ); + return new \WP_Error( 'missing_auth', 'Facebook auth provider not available', array( 'status' => 401 ) ); } $access_token = $auth->get_page_access_token(); if ( empty( $access_token ) ) { - return array( - 'success' => false, - 'error' => 'Facebook page access token unavailable', - ); + return new \WP_Error( 'missing_auth', 'Facebook page access token unavailable', array( 'status' => 401 ) ); } if ( empty( $input['post_id'] ) ) { - return array( - 'success' => false, - 'error' => 'post_id is required', - ); + return new \WP_Error( 'missing_param', 'post_id is required', array( 'status' => 400 ) ); } $post_id = $input['post_id']; @@ -132,10 +123,7 @@ public function execute( array $input ): array { switch ( $action ) { case 'edit': if ( empty( $input['message'] ) ) { - return array( - 'success' => false, - 'error' => 'message is required for edit action', - ); + return new \WP_Error( 'missing_param', 'message is required for edit action', array( 'status' => 400 ) ); } return $this->editPost( $access_token, $post_id, $input['message'] ); @@ -149,10 +137,7 @@ public function execute( array $input ): array { return $this->deletePost( $access_token, $post_id ); default: - return array( - 'success' => false, - 'error' => "Unknown action: {$action}. Use edit, hide, unhide, or delete.", - ); + return new \WP_Error( 'api_error', "Unknown action: {$action}. Use edit, hide, unhide, or delete.", array( 'status' => 500 ) ); } } @@ -184,7 +169,7 @@ private function getAuthProvider(): ?FacebookAuth { * @param string $message New message. * @return array Result. */ - private function editPost( string $access_token, string $post_id, string $message ): array { + private function editPost( string $access_token, string $post_id, string $message ): array|\WP_Error { $url = self::GRAPH_API_URL . '/' . rawurlencode( $post_id ); $response = wp_remote_post( @@ -199,20 +184,14 @@ private function editPost( string $access_token, string $post_id, string $messag ); if ( is_wp_error( $response ) ) { - return array( - 'success' => false, - 'error' => $response->get_error_message(), - ); + return new \WP_Error( 'api_error', $response->get_error_message(), array( 'status' => 500 ) ); } $status_code = wp_remote_retrieve_response_code( $response ); $body = json_decode( wp_remote_retrieve_body( $response ), true ); if ( 200 !== $status_code ) { - return array( - 'success' => false, - 'error' => $body['error']['message'] ?? 'Failed to edit post', - ); + return new \WP_Error( 'api_error', $body['error']['message'] ?? 'Failed to edit post', array( 'status' => 500 ) ); } return array( @@ -232,7 +211,7 @@ private function editPost( string $access_token, string $post_id, string $messag * @param bool $hide Whether to hide (true) or unhide (false). * @return array Result. */ - private function hidePost( string $access_token, string $post_id, bool $hide ): array { + private function hidePost( string $access_token, string $post_id, bool $hide ): array|\WP_Error { $url = self::GRAPH_API_URL . '/' . rawurlencode( $post_id ); $response = wp_remote_post( @@ -247,20 +226,14 @@ private function hidePost( string $access_token, string $post_id, bool $hide ): ); if ( is_wp_error( $response ) ) { - return array( - 'success' => false, - 'error' => $response->get_error_message(), - ); + return new \WP_Error( 'api_error', $response->get_error_message(), array( 'status' => 500 ) ); } $status_code = wp_remote_retrieve_response_code( $response ); $body = json_decode( wp_remote_retrieve_body( $response ), true ); if ( 200 !== $status_code ) { - return array( - 'success' => false, - 'error' => $body['error']['message'] ?? 'Failed to update post visibility', - ); + return new \WP_Error( 'api_error', $body['error']['message'] ?? 'Failed to update post visibility', array( 'status' => 500 ) ); } return array( @@ -279,7 +252,7 @@ private function hidePost( string $access_token, string $post_id, bool $hide ): * @param string $post_id Post ID. * @return array Result. */ - private function deletePost( string $access_token, string $post_id ): array { + private function deletePost( string $access_token, string $post_id ): array|\WP_Error { $url = self::GRAPH_API_URL . '/' . rawurlencode( $post_id ); $response = wp_remote_post( @@ -294,10 +267,7 @@ private function deletePost( string $access_token, string $post_id ): array { ); if ( is_wp_error( $response ) ) { - return array( - 'success' => false, - 'error' => $response->get_error_message(), - ); + return new \WP_Error( 'api_error', $response->get_error_message(), array( 'status' => 500 ) ); } $status_code = wp_remote_retrieve_response_code( $response ); @@ -313,9 +283,6 @@ private function deletePost( string $access_token, string $post_id ): array { ); } - return array( - 'success' => false, - 'error' => $body['error']['message'] ?? 'Failed to delete post', - ); + return new \WP_Error( 'api_error', $body['error']['message'] ?? 'Failed to delete post', array( 'status' => 500 ) ); } } diff --git a/inc/Abilities/Instagram/InstagramCommentReplyAbility.php b/inc/Abilities/Instagram/InstagramCommentReplyAbility.php index 592e0b315..fa72524b6 100644 --- a/inc/Abilities/Instagram/InstagramCommentReplyAbility.php +++ b/inc/Abilities/Instagram/InstagramCommentReplyAbility.php @@ -86,38 +86,26 @@ public function checkPermission(): bool { return PermissionHelper::can_manage(); } - public function execute( array $input ): array { + public function execute( array $input ): array|\WP_Error { $auth = $this->getAuthProvider(); if ( ! $auth ) { - return array( - 'success' => false, - 'error' => 'Instagram auth provider not available', - ); + return new \WP_Error( 'missing_auth', 'Instagram auth provider not available', array( 'status' => 401 ) ); } $access_token = $auth->get_valid_access_token(); if ( empty( $access_token ) ) { - return array( - 'success' => false, - 'error' => 'Instagram access token unavailable (expired or refresh failed)', - ); + return new \WP_Error( 'missing_auth', 'Instagram access token unavailable (expired or refresh failed)', array( 'status' => 401 ) ); } $comment_id = sanitize_text_field( $input['comment_id'] ?? '' ); $message = trim( sanitize_textarea_field( $input['message'] ?? '' ) ); if ( '' === $comment_id ) { - return array( - 'success' => false, - 'error' => 'comment_id is required', - ); + return new \WP_Error( 'missing_param', 'comment_id is required', array( 'status' => 400 ) ); } if ( '' === $message ) { - return array( - 'success' => false, - 'error' => 'message is required', - ); + return new \WP_Error( 'missing_param', 'message is required', array( 'status' => 400 ) ); } if ( mb_strlen( $message ) > self::MAX_REPLY_LENGTH ) { @@ -142,7 +130,7 @@ private function getAuthProvider(): ?InstagramAuth { return $provider; } - private function replyToComment( string $access_token, string $comment_id, string $message ): array { + private function replyToComment( string $access_token, string $comment_id, string $message ): array|\WP_Error { $url = self::GRAPH_API_URL . '/' . rawurlencode( $comment_id ) . '/replies'; $response = wp_remote_post( @@ -157,20 +145,14 @@ private function replyToComment( string $access_token, string $comment_id, strin ); if ( is_wp_error( $response ) ) { - return array( - 'success' => false, - 'error' => $response->get_error_message(), - ); + return new \WP_Error( 'api_error', $response->get_error_message(), array( 'status' => 500 ) ); } $status_code = wp_remote_retrieve_response_code( $response ); $body = json_decode( wp_remote_retrieve_body( $response ), true ); if ( 200 !== $status_code || isset( $body['error'] ) ) { - return array( - 'success' => false, - 'error' => $body['error']['message'] ?? 'Failed to reply to Instagram comment', - ); + return new \WP_Error( 'api_error', $body['error']['message'] ?? 'Failed to reply to Instagram comment', array( 'status' => 500 ) ); } return array( diff --git a/inc/Abilities/Instagram/InstagramDeleteAbility.php b/inc/Abilities/Instagram/InstagramDeleteAbility.php index 08bdc56f5..5231c6d57 100644 --- a/inc/Abilities/Instagram/InstagramDeleteAbility.php +++ b/inc/Abilities/Instagram/InstagramDeleteAbility.php @@ -79,28 +79,19 @@ public function checkPermission(): bool { return PermissionHelper::can_manage(); } - public function execute( array $input ): array { + public function execute( array $input ): array|\WP_Error { $auth = $this->getAuthProvider(); if ( ! $auth ) { - return array( - 'success' => false, - 'error' => 'Instagram auth provider not available', - ); + return new \WP_Error( 'missing_auth', 'Instagram auth provider not available', array( 'status' => 401 ) ); } $access_token = $auth->get_valid_access_token(); if ( empty( $access_token ) ) { - return array( - 'success' => false, - 'error' => 'Instagram access token unavailable', - ); + return new \WP_Error( 'missing_auth', 'Instagram access token unavailable', array( 'status' => 401 ) ); } if ( empty( $input['media_id'] ) ) { - return array( - 'success' => false, - 'error' => 'media_id is required', - ); + return new \WP_Error( 'missing_param', 'media_id is required', array( 'status' => 400 ) ); } return $this->deleteMedia( $access_token, $input['media_id'] ); @@ -131,7 +122,7 @@ private function getAuthProvider(): ?InstagramAuth { * @param string $media_id Media ID to delete. * @return array Result. */ - private function deleteMedia( string $access_token, string $media_id ): array { + private function deleteMedia( string $access_token, string $media_id ): array|\WP_Error { $url = self::GRAPH_API_URL . '/' . rawurlencode( $media_id ); $response = wp_remote_request( @@ -146,10 +137,7 @@ private function deleteMedia( string $access_token, string $media_id ): array { ); if ( is_wp_error( $response ) ) { - return array( - 'success' => false, - 'error' => $response->get_error_message(), - ); + return new \WP_Error( 'api_error', $response->get_error_message(), array( 'status' => 500 ) ); } $status_code = wp_remote_retrieve_response_code( $response ); @@ -165,9 +153,6 @@ private function deleteMedia( string $access_token, string $media_id ): array { ); } - return array( - 'success' => false, - 'error' => $body['error']['message'] ?? 'Delete failed. The Instagram API may not support deletion for this media type. Consider archiving instead.', - ); + return new \WP_Error( 'api_error', $body['error']['message'] ?? 'Delete failed. The Instagram API may not support deletion for this media type. Consider archiving instead.', array( 'status' => 500 ) ); } } diff --git a/inc/Abilities/Instagram/InstagramPublishAbility.php b/inc/Abilities/Instagram/InstagramPublishAbility.php index c133a066f..784b1c093 100644 --- a/inc/Abilities/Instagram/InstagramPublishAbility.php +++ b/inc/Abilities/Instagram/InstagramPublishAbility.php @@ -207,16 +207,13 @@ private function registerAbilities(): void { * @param array $input Ability input with publish parameters. * @return array Response with post details or error. */ - public static function execute_publish( array $input ): array { + public static function execute_publish( array $input ): array|\WP_Error { $content = $input['content'] ?? ''; $media_kind = $input['media_kind'] ?? 'image'; $source_url = $input['source_url'] ?? ''; if ( empty( $content ) ) { - return array( - 'success' => false, - 'error' => 'Content is required', - ); + return new \WP_Error( 'missing_param', 'Content is required', array( 'status' => 400 ) ); } // Auth check. @@ -224,20 +221,14 @@ public static function execute_publish( array $input ): array { $provider = $auth->getProvider( 'instagram' ); if ( ! $provider || ! $provider->is_authenticated() ) { - return array( - 'success' => false, - 'error' => 'Instagram not authenticated', - ); + return new \WP_Error( 'missing_auth', 'Instagram not authenticated', array( 'status' => 401 ) ); } $user_id = $provider->get_user_id(); $access_token = $provider->get_valid_access_token(); if ( empty( $user_id ) || empty( $access_token ) ) { - return array( - 'success' => false, - 'error' => 'Instagram credentials not available', - ); + return new \WP_Error( 'missing_auth', 'Instagram credentials not available', array( 'status' => 401 ) ); } // Build caption with source URL if provided. @@ -272,24 +263,18 @@ public static function execute_publish( array $input ): array { * @param string $caption Prepared caption text. * @return array Result. */ - private static function publish_image( array $input, string $user_id, string $access_token, string $caption ): array { + private static function publish_image( array $input, string $user_id, string $access_token, string $caption ): array|\WP_Error { $image_urls = $input['image_urls'] ?? array(); // Validate image URLs. if ( ! empty( $image_urls ) ) { if ( count( $image_urls ) > self::MAX_CAROUSEL_IMAGES ) { - return array( - 'success' => false, - 'error' => sprintf( 'Maximum %d images allowed for Instagram carousel', self::MAX_CAROUSEL_IMAGES ), - ); + return new \WP_Error( 'missing_param', sprintf( 'Maximum %d images allowed for Instagram carousel', self::MAX_CAROUSEL_IMAGES ), array( 'status' => 400 ) ); } foreach ( $image_urls as $url ) { if ( ! filter_var( $url, FILTER_VALIDATE_URL ) ) { - return array( - 'success' => false, - 'error' => 'Invalid image URL: ' . $url, - ); + return new \WP_Error( 'missing_param', 'Invalid image URL: ' . $url, array( 'status' => 400 ) ); } } } @@ -321,10 +306,7 @@ private static function publish_image( array $input, string $user_id, string $ac ); if ( is_wp_error( $response ) ) { - return array( - 'success' => false, - 'error' => 'Error creating media container: ' . $response->get_error_message(), - ); + return new \WP_Error( 'api_error', 'Error creating media container: ' . $response->get_error_message(), array( 'status' => 500 ) ); } $body = json_decode( wp_remote_retrieve_body( $response ), true ); @@ -334,10 +316,7 @@ private static function publish_image( array $input, string $user_id, string $ac if ( isset( $body['error']['message'] ) ) { $error_msg .= ': ' . $body['error']['message']; } - return array( - 'success' => false, - 'error' => $error_msg, - ); + return new \WP_Error( 'api_error', $error_msg, array( 'status' => 500 ) ); } $container_id = $body['id']; @@ -357,10 +336,7 @@ private static function publish_image( array $input, string $user_id, string $ac } if ( 'ERROR' === $status || 'EXPIRED' === $status ) { - return array( - 'success' => false, - 'error' => 'Container status error: ' . $status, - ); + return new \WP_Error( 'api_error', 'Container status error: ' . $status, array( 'status' => 500 ) ); } $container_ids[] = $container_id; @@ -369,10 +345,7 @@ private static function publish_image( array $input, string $user_id, string $ac if ( 'FINISHED' !== $status ) { $ready = self::wait_for_container( $access_token, $container_id ); if ( ! $ready ) { - return array( - 'success' => false, - 'error' => 'Media processing failed for container: ' . $container_id, - ); + return new \WP_Error( 'api_error', 'Media processing failed for container: ' . $container_id, array( 'status' => 500 ) ); } } } @@ -396,10 +369,7 @@ private static function publish_image( array $input, string $user_id, string $ac ); if ( is_wp_error( $carousel_resp ) ) { - return array( - 'success' => false, - 'error' => 'Error creating carousel container: ' . $carousel_resp->get_error_message(), - ); + return new \WP_Error( 'api_error', 'Error creating carousel container: ' . $carousel_resp->get_error_message(), array( 'status' => 500 ) ); } $carousel_body = json_decode( wp_remote_retrieve_body( $carousel_resp ), true ); @@ -408,10 +378,7 @@ private static function publish_image( array $input, string $user_id, string $ac if ( isset( $carousel_body['error']['message'] ) ) { $error_msg .= ': ' . $carousel_body['error']['message']; } - return array( - 'success' => false, - 'error' => $error_msg, - ); + return new \WP_Error( 'api_error', $error_msg, array( 'status' => 500 ) ); } $main_container_id = $carousel_body['id']; @@ -420,10 +387,7 @@ private static function publish_image( array $input, string $user_id, string $ac $main_container_id = $container_ids[0]; } else { // No images - Instagram requires at least one image. - return array( - 'success' => false, - 'error' => 'At least one image is required for Instagram posts', - ); + return new \WP_Error( 'missing_param', 'At least one image is required for Instagram posts', array( 'status' => 400 ) ); } return self::publish_container( $user_id, $access_token, $main_container_id, $media_kind ); @@ -443,23 +407,17 @@ private static function publish_image( array $input, string $user_id, string $ac * @param string $caption Prepared caption text. * @return array Result. */ - private static function publish_reel( array $input, string $user_id, string $access_token, string $caption ): array { + private static function publish_reel( array $input, string $user_id, string $access_token, string $caption ): array|\WP_Error { $video_url = $input['video_url'] ?? ''; $cover_url = $input['cover_url'] ?? ''; $share_to_feed = $input['share_to_feed'] ?? true; if ( empty( $video_url ) ) { - return array( - 'success' => false, - 'error' => 'video_url is required for Reel publishing', - ); + return new \WP_Error( 'missing_param', 'video_url is required for Reel publishing', array( 'status' => 400 ) ); } if ( ! filter_var( $video_url, FILTER_VALIDATE_URL ) ) { - return array( - 'success' => false, - 'error' => 'Invalid video URL: ' . $video_url, - ); + return new \WP_Error( 'missing_param', 'Invalid video URL: ' . $video_url, array( 'status' => 400 ) ); } // Pre-publish validation via core video-metadata if local path is available. @@ -469,10 +427,7 @@ private static function publish_reel( array $input, string $user_id, string $acc // Instagram Reels: max 15 min, H.264 codec recommended. if ( ! empty( $metadata['duration'] ) && $metadata['duration'] > 900 ) { - return array( - 'success' => false, - 'error' => sprintf( 'Video duration (%.0fs) exceeds Instagram Reels maximum (900s)', $metadata['duration'] ), - ); + return new \WP_Error( 'missing_param', sprintf( 'Video duration (%.0fs) exceeds Instagram Reels maximum (900s)', $metadata['duration'] ), array( 'status' => 400 ) ); } } @@ -487,10 +442,7 @@ private static function publish_reel( array $input, string $user_id, string $acc if ( ! empty( $cover_url ) ) { if ( ! filter_var( $cover_url, FILTER_VALIDATE_URL ) ) { - return array( - 'success' => false, - 'error' => 'Invalid cover URL: ' . $cover_url, - ); + return new \WP_Error( 'missing_param', 'Invalid cover URL: ' . $cover_url, array( 'status' => 400 ) ); } $container_body['cover_url'] = $cover_url; } @@ -505,10 +457,7 @@ private static function publish_reel( array $input, string $user_id, string $acc ); if ( is_wp_error( $response ) ) { - return array( - 'success' => false, - 'error' => 'Error creating Reel container: ' . $response->get_error_message(), - ); + return new \WP_Error( 'api_error', 'Error creating Reel container: ' . $response->get_error_message(), array( 'status' => 500 ) ); } $body = json_decode( wp_remote_retrieve_body( $response ), true ); @@ -518,10 +467,7 @@ private static function publish_reel( array $input, string $user_id, string $acc if ( isset( $body['error']['message'] ) ) { $error_msg .= ': ' . $body['error']['message']; } - return array( - 'success' => false, - 'error' => $error_msg, - ); + return new \WP_Error( 'api_error', $error_msg, array( 'status' => 500 ) ); } $container_id = $body['id']; @@ -535,10 +481,7 @@ private static function publish_reel( array $input, string $user_id, string $acc ); if ( ! $ready ) { - return array( - 'success' => false, - 'error' => 'Reel video processing failed or timed out for container: ' . $container_id, - ); + return new \WP_Error( 'api_error', 'Reel video processing failed or timed out for container: ' . $container_id, array( 'status' => 500 ) ); } // Step 3: Publish. @@ -559,16 +502,13 @@ private static function publish_reel( array $input, string $user_id, string $acc * @param string $access_token Valid access token. * @return array Result. */ - private static function publish_story( array $input, string $user_id, string $access_token ): array { + private static function publish_story( array $input, string $user_id, string $access_token ): array|\WP_Error { $story_image_url = $input['story_image_url'] ?? ''; $video_url = $input['video_url'] ?? ''; // Stories require exactly one media source: image or video. if ( empty( $story_image_url ) && empty( $video_url ) ) { - return array( - 'success' => false, - 'error' => 'story_image_url or video_url is required for Story publishing', - ); + return new \WP_Error( 'missing_param', 'story_image_url or video_url is required for Story publishing', array( 'status' => 400 ) ); } // Build the container request body. @@ -579,18 +519,12 @@ private static function publish_story( array $input, string $user_id, string $ac if ( ! empty( $video_url ) ) { if ( ! filter_var( $video_url, FILTER_VALIDATE_URL ) ) { - return array( - 'success' => false, - 'error' => 'Invalid video URL: ' . $video_url, - ); + return new \WP_Error( 'missing_param', 'Invalid video URL: ' . $video_url, array( 'status' => 400 ) ); } $container_body['video_url'] = $video_url; } else { if ( ! filter_var( $story_image_url, FILTER_VALIDATE_URL ) ) { - return array( - 'success' => false, - 'error' => 'Invalid story image URL: ' . $story_image_url, - ); + return new \WP_Error( 'missing_param', 'Invalid story image URL: ' . $story_image_url, array( 'status' => 400 ) ); } $container_body['image_url'] = $story_image_url; } @@ -605,10 +539,7 @@ private static function publish_story( array $input, string $user_id, string $ac ); if ( is_wp_error( $response ) ) { - return array( - 'success' => false, - 'error' => 'Error creating Story container: ' . $response->get_error_message(), - ); + return new \WP_Error( 'api_error', 'Error creating Story container: ' . $response->get_error_message(), array( 'status' => 500 ) ); } $body = json_decode( wp_remote_retrieve_body( $response ), true ); @@ -618,10 +549,7 @@ private static function publish_story( array $input, string $user_id, string $ac if ( isset( $body['error']['message'] ) ) { $error_msg .= ': ' . $body['error']['message']; } - return array( - 'success' => false, - 'error' => $error_msg, - ); + return new \WP_Error( 'api_error', $error_msg, array( 'status' => 500 ) ); } $container_id = $body['id']; @@ -633,10 +561,7 @@ private static function publish_story( array $input, string $user_id, string $ac $ready = self::wait_for_container( $access_token, $container_id, $max_retries, $interval ); if ( ! $ready ) { - return array( - 'success' => false, - 'error' => 'Story media processing failed or timed out for container: ' . $container_id, - ); + return new \WP_Error( 'api_error', 'Story media processing failed or timed out for container: ' . $container_id, array( 'status' => 500 ) ); } // Step 3: Publish. @@ -654,7 +579,7 @@ private static function publish_story( array $input, string $user_id, string $ac * @param string $media_kind Media kind identifier (image, carousel, reel, story). * @return array Result with success, media_id, media_kind, permalink. */ - private static function publish_container( string $user_id, string $access_token, string $container_id, string $media_kind ): array { + private static function publish_container( string $user_id, string $access_token, string $container_id, string $media_kind ): array|\WP_Error { $publish_resp = wp_remote_post( self::GRAPH_API_URL . "/{$user_id}/media_publish", array( @@ -667,10 +592,7 @@ private static function publish_container( string $user_id, string $access_token ); if ( is_wp_error( $publish_resp ) ) { - return array( - 'success' => false, - 'error' => 'Error publishing to Instagram: ' . $publish_resp->get_error_message(), - ); + return new \WP_Error( 'api_error', 'Error publishing to Instagram: ' . $publish_resp->get_error_message(), array( 'status' => 500 ) ); } $publish_body = json_decode( wp_remote_retrieve_body( $publish_resp ), true ); @@ -679,10 +601,7 @@ private static function publish_container( string $user_id, string $access_token if ( isset( $publish_body['error']['message'] ) ) { $error_msg .= ': ' . $publish_body['error']['message']; } - return array( - 'success' => false, - 'error' => $error_msg, - ); + return new \WP_Error( 'api_error', $error_msg, array( 'status' => 500 ) ); } $media_id = $publish_body['id']; @@ -750,17 +669,13 @@ private static function wait_for_container( string $access_token, string $contai * @param array $input Ability input. * @return array Account details or error. */ - public static function get_account( array $input ): array { + public static function get_account( array $input ): array|\WP_Error { $input; $auth = new AuthAbilities(); $provider = $auth->getProvider( 'instagram' ); if ( ! $provider || ! $provider->is_authenticated() ) { - return array( - 'success' => false, - 'error' => 'Instagram not authenticated', - 'authenticated' => false, - ); + return new \WP_Error( 'missing_auth', 'Instagram not authenticated', array( 'status' => 401 ) ); } return array( diff --git a/inc/Abilities/Instagram/InstagramReadAbility.php b/inc/Abilities/Instagram/InstagramReadAbility.php index 0480b60ab..8e4c8e5ea 100644 --- a/inc/Abilities/Instagram/InstagramReadAbility.php +++ b/inc/Abilities/Instagram/InstagramReadAbility.php @@ -122,24 +122,18 @@ public function checkPermission(): bool { * @param array $input Input parameters. * @return array Result. */ - public function execute( array $input ): array { + public function execute( array $input ): array|\WP_Error { $action = $input['action'] ?? 'list'; // Get auth provider. $auth = $this->getAuthProvider(); if ( ! $auth ) { - return array( - 'success' => false, - 'error' => 'Instagram auth provider not available', - ); + return new \WP_Error( 'missing_auth', 'Instagram auth provider not available', array( 'status' => 401 ) ); } $access_token = $auth->get_valid_access_token(); if ( empty( $access_token ) ) { - return array( - 'success' => false, - 'error' => 'Instagram access token unavailable (expired or refresh failed)', - ); + return new \WP_Error( 'missing_auth', 'Instagram access token unavailable (expired or refresh failed)', array( 'status' => 401 ) ); } switch ( $action ) { @@ -148,36 +142,24 @@ public function execute( array $input ): array { case 'get': if ( empty( $input['media_id'] ) ) { - return array( - 'success' => false, - 'error' => 'media_id is required for the get action', - ); + return new \WP_Error( 'missing_param', 'media_id is required for the get action', array( 'status' => 400 ) ); } return $this->getMedia( $access_token, $input['media_id'] ); case 'comments': if ( empty( $input['media_id'] ) ) { - return array( - 'success' => false, - 'error' => 'media_id is required for the comments action', - ); + return new \WP_Error( 'missing_param', 'media_id is required for the comments action', array( 'status' => 400 ) ); } return $this->getComments( $access_token, $input['media_id'], $input ); case 'comments_all': if ( empty( $input['media_id'] ) ) { - return array( - 'success' => false, - 'error' => 'media_id is required for the comments_all action', - ); + return new \WP_Error( 'missing_param', 'media_id is required for the comments_all action', array( 'status' => 400 ) ); } return $this->getAllComments( $access_token, $input['media_id'] ); default: - return array( - 'success' => false, - 'error' => "Unknown action: {$action}. Use list, get, or comments.", - ); + return new \WP_Error( 'api_error', "Unknown action: {$action}. Use list, get, or comments.", array( 'status' => 500 ) ); } } @@ -189,13 +171,10 @@ public function execute( array $input ): array { * @param array $input Input parameters. * @return array Result. */ - private function listMedia( InstagramAuth $auth, string $access_token, array $input ): array { + private function listMedia( InstagramAuth $auth, string $access_token, array $input ): array|\WP_Error { $user_id = $auth->get_user_id(); if ( empty( $user_id ) ) { - return array( - 'success' => false, - 'error' => 'Instagram user ID not available. Try re-authenticating.', - ); + return new \WP_Error( 'missing_auth', 'Instagram user ID not available. Try re-authenticating.', array( 'status' => 401 ) ); } $limit = min( absint( $input['limit'] ?? 25 ), 100 ); @@ -213,10 +192,7 @@ private function listMedia( InstagramAuth $auth, string $access_token, array $in $result = HttpClient::get( $url, array( 'context' => 'Instagram Read' ) ); if ( ! $result['success'] ) { - return array( - 'success' => false, - 'error' => 'Instagram API request failed: ' . ( $result['error'] ?? 'unknown' ), - ); + return new \WP_Error( 'api_error', 'Instagram API request failed: ' . ( $result['error'] ?? 'unknown' ), array( 'status' => 500 ) ); } $data = json_decode( $result['data'], true ); @@ -224,10 +200,7 @@ private function listMedia( InstagramAuth $auth, string $access_token, array $in if ( 200 !== $http_code || isset( $data['error'] ) ) { $error_msg = $data['error']['message'] ?? 'Failed to fetch Instagram media'; - return array( - 'success' => false, - 'error' => $error_msg, - ); + return new \WP_Error( 'api_error', $error_msg, array( 'status' => 500 ) ); } $media = $data['data'] ?? array(); @@ -251,7 +224,7 @@ private function listMedia( InstagramAuth $auth, string $access_token, array $in * @param string $media_id Instagram media ID. * @return array Result. */ - private function getMedia( string $access_token, string $media_id ): array { + private function getMedia( string $access_token, string $media_id ): array|\WP_Error { $params = array( 'fields' => self::DETAIL_FIELDS, 'access_token' => $access_token, @@ -261,10 +234,7 @@ private function getMedia( string $access_token, string $media_id ): array { $result = HttpClient::get( $url, array( 'context' => 'Instagram Read' ) ); if ( ! $result['success'] ) { - return array( - 'success' => false, - 'error' => 'Instagram API request failed: ' . ( $result['error'] ?? 'unknown' ), - ); + return new \WP_Error( 'api_error', 'Instagram API request failed: ' . ( $result['error'] ?? 'unknown' ), array( 'status' => 500 ) ); } $data = json_decode( $result['data'], true ); @@ -272,10 +242,7 @@ private function getMedia( string $access_token, string $media_id ): array { if ( 200 !== $http_code || isset( $data['error'] ) ) { $error_msg = $data['error']['message'] ?? 'Failed to fetch Instagram media details'; - return array( - 'success' => false, - 'error' => $error_msg, - ); + return new \WP_Error( 'api_error', $error_msg, array( 'status' => 500 ) ); } return array( @@ -292,7 +259,7 @@ private function getMedia( string $access_token, string $media_id ): array { * @param array $input Input parameters. * @return array Result. */ - private function getComments( string $access_token, string $media_id, array $input ): array { + private function getComments( string $access_token, string $media_id, array $input ): array|\WP_Error { $limit = min( absint( $input['limit'] ?? 25 ), 100 ); $params = array( 'fields' => 'id,text,timestamp,username,like_count', @@ -308,10 +275,7 @@ private function getComments( string $access_token, string $media_id, array $inp $result = HttpClient::get( $url, array( 'context' => 'Instagram Read' ) ); if ( ! $result['success'] ) { - return array( - 'success' => false, - 'error' => 'Instagram API request failed: ' . ( $result['error'] ?? 'unknown' ), - ); + return new \WP_Error( 'api_error', 'Instagram API request failed: ' . ( $result['error'] ?? 'unknown' ), array( 'status' => 500 ) ); } $data = json_decode( $result['data'], true ); @@ -319,10 +283,7 @@ private function getComments( string $access_token, string $media_id, array $inp if ( 200 !== $http_code || isset( $data['error'] ) ) { $error_msg = $data['error']['message'] ?? 'Failed to fetch comments'; - return array( - 'success' => false, - 'error' => $error_msg, - ); + return new \WP_Error( 'api_error', $error_msg, array( 'status' => 500 ) ); } $comments = $data['data'] ?? array(); @@ -350,7 +311,7 @@ private function getComments( string $access_token, string $media_id, array $inp * @param string $media_id Instagram media ID. * @return array Result with normalized comments. */ - private function getAllComments( string $access_token, string $media_id ): array { + private function getAllComments( string $access_token, string $media_id ): array|\WP_Error { $all_comments = array(); $after = ''; $page = 0; @@ -386,10 +347,7 @@ private function getAllComments( string $access_token, string $media_id ): array ); } - return array( - 'success' => false, - 'error' => 'Instagram API request failed: ' . ( $result['error'] ?? 'unknown' ), - ); + return new \WP_Error( 'api_error', 'Instagram API request failed: ' . ( $result['error'] ?? 'unknown' ), array( 'status' => 500 ) ); } $data = json_decode( $result['data'], true ); @@ -409,10 +367,7 @@ private function getAllComments( string $access_token, string $media_id ): array ); } - return array( - 'success' => false, - 'error' => $data['error']['message'] ?? 'Failed to fetch comments', - ); + return new \WP_Error( 'api_error', $data['error']['message'] ?? 'Failed to fetch comments', array( 'status' => 500 ) ); } $page_comments = $data['data'] ?? array(); @@ -450,7 +405,7 @@ private function getAllComments( string $access_token, string $media_id ): array * @param array $comment Raw Instagram API comment data. * @return array Normalized comment. */ - public static function normalizeComment( array $comment ): array { + public static function normalizeComment( array $comment ): array|\WP_Error { $text = $comment['text'] ?? ''; $mentions = array(); diff --git a/inc/Abilities/Instagram/InstagramUpdateAbility.php b/inc/Abilities/Instagram/InstagramUpdateAbility.php index 318391122..15aaa5157 100644 --- a/inc/Abilities/Instagram/InstagramUpdateAbility.php +++ b/inc/Abilities/Instagram/InstagramUpdateAbility.php @@ -106,31 +106,22 @@ public function checkPermission(): bool { * @param array $input Input parameters. * @return array Result. */ - public function execute( array $input ): array { + public function execute( array $input ): array|\WP_Error { $action = $input['action'] ?? ''; // Get auth provider. $auth = $this->getAuthProvider(); if ( ! $auth ) { - return array( - 'success' => false, - 'error' => 'Instagram auth provider not available', - ); + return new \WP_Error( 'missing_auth', 'Instagram auth provider not available', array( 'status' => 401 ) ); } $access_token = $auth->get_valid_access_token(); if ( empty( $access_token ) ) { - return array( - 'success' => false, - 'error' => 'Instagram access token unavailable (expired or refresh failed)', - ); + return new \WP_Error( 'missing_auth', 'Instagram access token unavailable (expired or refresh failed)', array( 'status' => 401 ) ); } if ( empty( $input['media_id'] ) ) { - return array( - 'success' => false, - 'error' => 'media_id is required', - ); + return new \WP_Error( 'missing_param', 'media_id is required', array( 'status' => 400 ) ); } $media_id = $input['media_id']; @@ -138,10 +129,7 @@ public function execute( array $input ): array { switch ( $action ) { case 'edit': if ( empty( $input['caption'] ) ) { - return array( - 'success' => false, - 'error' => 'caption is required for edit action', - ); + return new \WP_Error( 'missing_param', 'caption is required for edit action', array( 'status' => 400 ) ); } return $this->editCaption( $access_token, $media_id, $input['caption'] ); @@ -152,10 +140,7 @@ public function execute( array $input ): array { return $this->archiveMedia( $access_token, $media_id ); default: - return array( - 'success' => false, - 'error' => "Unknown action: {$action}. Use edit, delete, or archive.", - ); + return new \WP_Error( 'api_error', "Unknown action: {$action}. Use edit, delete, or archive.", array( 'status' => 500 ) ); } } @@ -187,7 +172,7 @@ private function getAuthProvider(): ?InstagramAuth { * @param string $caption New caption. * @return array Result. */ - private function editCaption( string $access_token, string $media_id, string $caption ): array { + private function editCaption( string $access_token, string $media_id, string $caption ): array|\WP_Error { // Truncate to max length. if ( mb_strlen( $caption ) > self::MAX_CAPTION_LENGTH ) { $caption = mb_substr( $caption, 0, self::MAX_CAPTION_LENGTH - 3 ) . '...'; @@ -207,20 +192,14 @@ private function editCaption( string $access_token, string $media_id, string $ca ); if ( is_wp_error( $response ) ) { - return array( - 'success' => false, - 'error' => $response->get_error_message(), - ); + return new \WP_Error( 'api_error', $response->get_error_message(), array( 'status' => 500 ) ); } $status_code = wp_remote_retrieve_response_code( $response ); $body = json_decode( wp_remote_retrieve_body( $response ), true ); if ( 200 !== $status_code ) { - return array( - 'success' => false, - 'error' => $body['error']['message'] ?? 'Failed to edit caption', - ); + return new \WP_Error( 'api_error', $body['error']['message'] ?? 'Failed to edit caption', array( 'status' => 500 ) ); } return array( @@ -239,7 +218,7 @@ private function editCaption( string $access_token, string $media_id, string $ca * @param string $media_id Media ID. * @return array Result. */ - private function deleteMedia( string $access_token, string $media_id ): array { + private function deleteMedia( string $access_token, string $media_id ): array|\WP_Error { $url = self::GRAPH_API_URL . '/' . rawurlencode( $media_id ); $response = wp_remote_post( @@ -258,10 +237,7 @@ private function deleteMedia( string $access_token, string $media_id ): array { // For now, return an error with guidance. if ( is_wp_error( $response ) ) { - return array( - 'success' => false, - 'error' => $response->get_error_message(), - ); + return new \WP_Error( 'api_error', $response->get_error_message(), array( 'status' => 500 ) ); } $status_code = wp_remote_retrieve_response_code( $response ); @@ -279,10 +255,7 @@ private function deleteMedia( string $access_token, string $media_id ): array { // Instagram doesn't support direct delete via API for all media types. // Return informative error. - return array( - 'success' => false, - 'error' => $body['error']['message'] ?? 'Delete not supported for this media type via API. Consider archiving instead.', - ); + return new \WP_Error( 'api_error', $body['error']['message'] ?? 'Delete not supported for this media type via API. Consider archiving instead.', array( 'status' => 500 ) ); } /** @@ -292,7 +265,7 @@ private function deleteMedia( string $access_token, string $media_id ): array { * @param string $media_id Media ID. * @return array Result. */ - private function archiveMedia( string $access_token, string $media_id ): array { + private function archiveMedia( string $access_token, string $media_id ): array|\WP_Error { $url = self::GRAPH_API_URL . '/' . rawurlencode( $media_id ); $response = wp_remote_post( @@ -307,20 +280,14 @@ private function archiveMedia( string $access_token, string $media_id ): array { ); if ( is_wp_error( $response ) ) { - return array( - 'success' => false, - 'error' => $response->get_error_message(), - ); + return new \WP_Error( 'api_error', $response->get_error_message(), array( 'status' => 500 ) ); } $status_code = wp_remote_retrieve_response_code( $response ); $body = json_decode( wp_remote_retrieve_body( $response ), true ); if ( 200 !== $status_code ) { - return array( - 'success' => false, - 'error' => $body['error']['message'] ?? 'Failed to archive media', - ); + return new \WP_Error( 'api_error', $body['error']['message'] ?? 'Failed to archive media', array( 'status' => 500 ) ); } return array( diff --git a/inc/Abilities/LinkedIn/LinkedInDeleteAbility.php b/inc/Abilities/LinkedIn/LinkedInDeleteAbility.php index 1c3d434f6..ef2799694 100644 --- a/inc/Abilities/LinkedIn/LinkedInDeleteAbility.php +++ b/inc/Abilities/LinkedIn/LinkedInDeleteAbility.php @@ -79,29 +79,20 @@ public function checkPermission(): bool { return PermissionHelper::can_manage(); } - public function execute( array $input ): array { + public function execute( array $input ): array|\WP_Error { $post_id = $input['post_id'] ?? ''; if ( empty( $post_id ) ) { - return array( - 'success' => false, - 'error' => 'post_id is required', - ); + return new \WP_Error( 'missing_param', 'post_id is required', array( 'status' => 400 ) ); } $provider = $this->getAuthProvider(); if ( ! $provider ) { - return array( - 'success' => false, - 'error' => 'LinkedIn auth provider not available', - ); + return new \WP_Error( 'missing_auth', 'LinkedIn auth provider not available', array( 'status' => 401 ) ); } if ( ! $provider->is_authenticated() ) { - return array( - 'success' => false, - 'error' => 'LinkedIn not authenticated', - ); + return new \WP_Error( 'missing_auth', 'LinkedIn not authenticated', array( 'status' => 401 ) ); } $encoded_id = rawurlencode( $post_id ); @@ -124,10 +115,7 @@ public function execute( array $input ): array { ); } - return array( - 'success' => false, - 'error' => $result['error'] ?? 'Failed to delete LinkedIn post', - ); + return new \WP_Error( 'api_error', $result['error'] ?? 'Failed to delete LinkedIn post', array( 'status' => 500 ) ); } private function getAuthProvider(): ?LinkedInAuth { diff --git a/inc/Abilities/LinkedIn/LinkedInPublishAbility.php b/inc/Abilities/LinkedIn/LinkedInPublishAbility.php index d56491440..351961468 100644 --- a/inc/Abilities/LinkedIn/LinkedInPublishAbility.php +++ b/inc/Abilities/LinkedIn/LinkedInPublishAbility.php @@ -145,7 +145,7 @@ private function registerAbilities(): void { * @param array $input Ability input with publish parameters. * @return array Response with post details or error. */ - public static function execute_publish( array $input ): array { + public static function execute_publish( array $input ): array|\WP_Error { $content = $input['content'] ?? ''; $image_path = $input['image_path'] ?? ''; $visibility = $input['visibility'] ?? 'PUBLIC'; @@ -153,28 +153,19 @@ public static function execute_publish( array $input ): array { $article_title = $input['article_title'] ?? ''; if ( empty( $content ) ) { - return array( - 'success' => false, - 'error' => 'Content is required', - ); + return new \WP_Error( 'missing_param', 'Content is required', array( 'status' => 400 ) ); } $auth = new AuthAbilities(); $provider = $auth->getProvider( 'linkedin' ); if ( ! $provider || ! $provider->is_authenticated() ) { - return array( - 'success' => false, - 'error' => 'LinkedIn not authenticated', - ); + return new \WP_Error( 'missing_auth', 'LinkedIn not authenticated', array( 'status' => 401 ) ); } $person_urn = $provider->get_person_urn(); if ( empty( $person_urn ) ) { - return array( - 'success' => false, - 'error' => 'LinkedIn person URN not available. Try re-authenticating.', - ); + return new \WP_Error( 'missing_auth', 'LinkedIn person URN not available. Try re-authenticating.', array( 'status' => 401 ) ); } // Build post payload. @@ -196,10 +187,7 @@ public static function execute_publish( array $input ): array { if ( ! empty( $image_path ) && file_exists( $image_path ) ) { $image_urn = self::upload_image( $provider, $person_urn, $image_path ); if ( ! $image_urn ) { - return array( - 'success' => false, - 'error' => 'Failed to upload image to LinkedIn', - ); + return new \WP_Error( 'api_error', 'Failed to upload image to LinkedIn', array( 'status' => 500 ) ); } $payload['content'] = array( 'media' => array( @@ -239,15 +227,9 @@ public static function execute_publish( array $input ): array { ); } - return array( - 'success' => false, - 'error' => $result['error'] ?? 'LinkedIn publish failed', - ); + return new \WP_Error( 'api_error', $result['error'] ?? 'LinkedIn publish failed', array( 'status' => 500 ) ); } catch ( \Exception $e ) { - return array( - 'success' => false, - 'error' => $e->getMessage(), - ); + return new \WP_Error( 'api_error', $e->getMessage(), array( 'status' => 500 ) ); } } @@ -257,16 +239,13 @@ public static function execute_publish( array $input ): array { * @param array $input Ability input. * @return array Account details or error. */ - public static function get_account( array $input ): array { + public static function get_account( array $input ): array|\WP_Error { $input; $auth = new AuthAbilities(); $provider = $auth->getProvider( 'linkedin' ); if ( ! $provider || ! $provider->is_authenticated() ) { - return array( - 'success' => false, - 'error' => 'LinkedIn not authenticated', - ); + return new \WP_Error( 'missing_auth', 'LinkedIn not authenticated', array( 'status' => 401 ) ); } $account = $provider->get_account_details(); diff --git a/inc/Abilities/LinkedIn/LinkedInReadAbility.php b/inc/Abilities/LinkedIn/LinkedInReadAbility.php index 0da671bf0..5d497822e 100644 --- a/inc/Abilities/LinkedIn/LinkedInReadAbility.php +++ b/inc/Abilities/LinkedIn/LinkedInReadAbility.php @@ -94,22 +94,16 @@ public function checkPermission(): bool { return PermissionHelper::can_manage(); } - public function execute( array $input ): array { + public function execute( array $input ): array|\WP_Error { $action = $input['action'] ?? 'list'; $provider = $this->getAuthProvider(); if ( ! $provider ) { - return array( - 'success' => false, - 'error' => 'LinkedIn auth provider not available', - ); + return new \WP_Error( 'missing_auth', 'LinkedIn auth provider not available', array( 'status' => 401 ) ); } if ( ! $provider->is_authenticated() ) { - return array( - 'success' => false, - 'error' => 'LinkedIn not authenticated', - ); + return new \WP_Error( 'missing_auth', 'LinkedIn not authenticated', array( 'status' => 401 ) ); } switch ( $action ) { @@ -118,18 +112,12 @@ public function execute( array $input ): array { case 'get': if ( empty( $input['post_id'] ) ) { - return array( - 'success' => false, - 'error' => 'post_id is required for the get action', - ); + return new \WP_Error( 'missing_param', 'post_id is required for the get action', array( 'status' => 400 ) ); } return $this->getPost( $provider, $input['post_id'] ); default: - return array( - 'success' => false, - 'error' => "Unknown action: {$action}. Use list or get.", - ); + return new \WP_Error( 'api_error', "Unknown action: {$action}. Use list or get.", array( 'status' => 500 ) ); } } @@ -140,13 +128,10 @@ public function execute( array $input ): array { * @param array $input Input parameters. * @return array Response. */ - private function listPosts( LinkedInAuth $provider, array $input ): array { + private function listPosts( LinkedInAuth $provider, array $input ): array|\WP_Error { $person_urn = $provider->get_person_urn(); if ( empty( $person_urn ) ) { - return array( - 'success' => false, - 'error' => 'LinkedIn person URN not available. Try re-authenticating.', - ); + return new \WP_Error( 'missing_auth', 'LinkedIn person URN not available. Try re-authenticating.', array( 'status' => 401 ) ); } $count = min( absint( $input['limit'] ?? 10 ), 100 ); @@ -165,10 +150,7 @@ private function listPosts( LinkedInAuth $provider, array $input ): array { ); if ( ! $result['success'] ) { - return array( - 'success' => false, - 'error' => $result['error'] ?? 'Failed to fetch LinkedIn posts', - ); + return new \WP_Error( 'api_error', $result['error'] ?? 'Failed to fetch LinkedIn posts', array( 'status' => 500 ) ); } $data = json_decode( $result['data'], true ); @@ -208,7 +190,7 @@ function ( $post ) { * @param string $post_id Post URN. * @return array Response. */ - private function getPost( LinkedInAuth $provider, string $post_id ): array { + private function getPost( LinkedInAuth $provider, string $post_id ): array|\WP_Error { $encoded_id = rawurlencode( $post_id ); $url = LinkedInAuth::API_BASE . "/rest/posts/{$encoded_id}"; @@ -219,10 +201,7 @@ private function getPost( LinkedInAuth $provider, string $post_id ): array { ); if ( ! $result['success'] ) { - return array( - 'success' => false, - 'error' => $result['error'] ?? 'Failed to fetch LinkedIn post', - ); + return new \WP_Error( 'api_error', $result['error'] ?? 'Failed to fetch LinkedIn post', array( 'status' => 500 ) ); } $data = json_decode( $result['data'], true ); diff --git a/inc/Abilities/LinkedIn/LinkedInUpdateAbility.php b/inc/Abilities/LinkedIn/LinkedInUpdateAbility.php index 9185070b4..7b35fab9f 100644 --- a/inc/Abilities/LinkedIn/LinkedInUpdateAbility.php +++ b/inc/Abilities/LinkedIn/LinkedInUpdateAbility.php @@ -83,37 +83,25 @@ public function checkPermission(): bool { return PermissionHelper::can_manage(); } - public function execute( array $input ): array { + public function execute( array $input ): array|\WP_Error { $post_id = $input['post_id'] ?? ''; $commentary = $input['commentary'] ?? ''; if ( empty( $post_id ) ) { - return array( - 'success' => false, - 'error' => 'post_id is required', - ); + return new \WP_Error( 'missing_param', 'post_id is required', array( 'status' => 400 ) ); } if ( empty( $commentary ) ) { - return array( - 'success' => false, - 'error' => 'commentary is required', - ); + return new \WP_Error( 'missing_param', 'commentary is required', array( 'status' => 400 ) ); } $provider = $this->getAuthProvider(); if ( ! $provider ) { - return array( - 'success' => false, - 'error' => 'LinkedIn auth provider not available', - ); + return new \WP_Error( 'missing_auth', 'LinkedIn auth provider not available', array( 'status' => 401 ) ); } if ( ! $provider->is_authenticated() ) { - return array( - 'success' => false, - 'error' => 'LinkedIn not authenticated', - ); + return new \WP_Error( 'missing_auth', 'LinkedIn not authenticated', array( 'status' => 401 ) ); } $encoded_id = rawurlencode( $post_id ); @@ -145,10 +133,7 @@ public function execute( array $input ): array { ); } - return array( - 'success' => false, - 'error' => $result['error'] ?? 'Failed to update LinkedIn post', - ); + return new \WP_Error( 'api_error', $result['error'] ?? 'Failed to update LinkedIn post', array( 'status' => 500 ) ); } private function getAuthProvider(): ?LinkedInAuth { diff --git a/inc/Abilities/Pinterest/PinterestAnalyticsAbility.php b/inc/Abilities/Pinterest/PinterestAnalyticsAbility.php index 2f21b5063..1ac1b8925 100644 --- a/inc/Abilities/Pinterest/PinterestAnalyticsAbility.php +++ b/inc/Abilities/Pinterest/PinterestAnalyticsAbility.php @@ -125,23 +125,17 @@ public function checkPermission(): bool { return PermissionHelper::can_manage(); } - public function execute( array $input ): array { + public function execute( array $input ): array|\WP_Error { $action = $input['action'] ?? 'user'; $auth = $this->getAuthProvider(); if ( ! $auth ) { - return array( - 'success' => false, - 'error' => 'Pinterest auth provider not available', - ); + return new \WP_Error( 'missing_auth', 'Pinterest auth provider not available', array( 'status' => 401 ) ); } $token = $auth->get_valid_access_token(); if ( empty( $token ) ) { - return array( - 'success' => false, - 'error' => 'Pinterest access token is missing or expired — re-authorize in WP Admin > Data Machine > Settings', - ); + return new \WP_Error( 'missing_auth', 'Pinterest access token is missing or expired — re-authorize in WP Admin > Data Machine > Settings', array( 'status' => 401 ) ); } // Parse date range @@ -150,10 +144,7 @@ public function execute( array $input ): array { // Validate date format if ( ! preg_match( '/^\d{4}-\d{2}-\d{2}$/', $start_date ) || ! preg_match( '/^\d{4}-\d{2}-\d{2}$/', $end_date ) ) { - return array( - 'success' => false, - 'error' => 'Invalid date format. Use YYYY-MM-DD.', - ); + return new \WP_Error( 'missing_param', 'Invalid date format. Use YYYY-MM-DD.', array( 'status' => 400 ) ); } // Parse metrics (default to key engagement metrics) @@ -177,27 +168,18 @@ public function execute( array $input ): array { case 'pin': if ( empty( $input['pin_id'] ) ) { - return array( - 'success' => false, - 'error' => 'pin_id is required for the pin action', - ); + return new \WP_Error( 'missing_param', 'pin_id is required for the pin action', array( 'status' => 400 ) ); } return $this->getPinAnalytics( $token, $input['pin_id'], $start_date, $end_date, $metrics_param ); case 'board': if ( empty( $input['board_id'] ) ) { - return array( - 'success' => false, - 'error' => 'board_id is required for the board action', - ); + return new \WP_Error( 'missing_param', 'board_id is required for the board action', array( 'status' => 400 ) ); } return $this->getBoardAnalytics( $token, $input['board_id'], $start_date, $end_date, $metrics_param ); default: - return array( - 'success' => false, - 'error' => "Unknown action: {$action}. Use user, pin, or board.", - ); + return new \WP_Error( 'api_error', "Unknown action: {$action}. Use user, pin, or board.", array( 'status' => 500 ) ); } } @@ -210,7 +192,7 @@ public function execute( array $input ): array { * @param string $metrics_param Comma-separated metric types. * @return array */ - private function getUserAnalytics( string $token, string $start_date, string $end_date, string $metrics_param ): array { + private function getUserAnalytics( string $token, string $start_date, string $end_date, string $metrics_param ): array|\WP_Error { $params = array( 'start_date' => $start_date, 'end_date' => $end_date, @@ -230,10 +212,7 @@ private function getUserAnalytics( string $token, string $start_date, string $en ); if ( ! $result['success'] ) { - return array( - 'success' => false, - 'error' => 'Pinterest API request failed: ' . ( $result['error'] ?? 'unknown' ), - ); + return new \WP_Error( 'api_error', 'Pinterest API request failed: ' . ( $result['error'] ?? 'unknown' ), array( 'status' => 500 ) ); } $data = json_decode( $result['data'], true ); @@ -241,10 +220,7 @@ private function getUserAnalytics( string $token, string $start_date, string $en if ( 200 !== $http_code || isset( $data['code'] ) ) { $error_msg = $data['message'] ?? 'Failed to fetch user analytics'; - return array( - 'success' => false, - 'error' => $error_msg, - ); + return new \WP_Error( 'api_error', $error_msg, array( 'status' => 500 ) ); } // Build summary @@ -267,7 +243,7 @@ private function getUserAnalytics( string $token, string $start_date, string $en * @param string $metrics_param Comma-separated metric types. * @return array */ - private function getPinAnalytics( string $token, string $pin_id, string $start_date, string $end_date, string $metrics_param ): array { + private function getPinAnalytics( string $token, string $pin_id, string $start_date, string $end_date, string $metrics_param ): array|\WP_Error { $params = array( 'start_date' => $start_date, 'end_date' => $end_date, @@ -285,10 +261,7 @@ private function getPinAnalytics( string $token, string $pin_id, string $start_d ); if ( ! $result['success'] ) { - return array( - 'success' => false, - 'error' => 'Pinterest API request failed: ' . ( $result['error'] ?? 'unknown' ), - ); + return new \WP_Error( 'api_error', 'Pinterest API request failed: ' . ( $result['error'] ?? 'unknown' ), array( 'status' => 500 ) ); } $data = json_decode( $result['data'], true ); @@ -296,10 +269,7 @@ private function getPinAnalytics( string $token, string $pin_id, string $start_d if ( 200 !== $http_code || isset( $data['code'] ) ) { $error_msg = $data['message'] ?? 'Failed to fetch pin analytics'; - return array( - 'success' => false, - 'error' => $error_msg, - ); + return new \WP_Error( 'api_error', $error_msg, array( 'status' => 500 ) ); } // Build summary @@ -323,7 +293,7 @@ private function getPinAnalytics( string $token, string $pin_id, string $start_d * @param string $metrics_param Comma-separated metric types. * @return array */ - private function getBoardAnalytics( string $token, string $board_id, string $start_date, string $end_date, string $metrics_param ): array { + private function getBoardAnalytics( string $token, string $board_id, string $start_date, string $end_date, string $metrics_param ): array|\WP_Error { $params = array( 'start_date' => $start_date, 'end_date' => $end_date, @@ -341,10 +311,7 @@ private function getBoardAnalytics( string $token, string $board_id, string $sta ); if ( ! $result['success'] ) { - return array( - 'success' => false, - 'error' => 'Pinterest API request failed: ' . ( $result['error'] ?? 'unknown' ), - ); + return new \WP_Error( 'api_error', 'Pinterest API request failed: ' . ( $result['error'] ?? 'unknown' ), array( 'status' => 500 ) ); } $data = json_decode( $result['data'], true ); @@ -352,10 +319,7 @@ private function getBoardAnalytics( string $token, string $board_id, string $sta if ( 200 !== $http_code || isset( $data['code'] ) ) { $error_msg = $data['message'] ?? 'Failed to fetch board analytics'; - return array( - 'success' => false, - 'error' => $error_msg, - ); + return new \WP_Error( 'api_error', $error_msg, array( 'status' => 500 ) ); } // Build summary @@ -378,7 +342,7 @@ private function getBoardAnalytics( string $token, string $board_id, string $sta * @param array $data Raw analytics data from Pinterest API. * @return array Summarized metrics. */ - private function buildSummary( array $data ): array { + private function buildSummary( array $data ): array|\WP_Error { $summary = array(); foreach ( self::METRIC_TYPES as $metric ) { diff --git a/inc/Abilities/Pinterest/PinterestBoardsAbility.php b/inc/Abilities/Pinterest/PinterestBoardsAbility.php index 76bbfe7f6..63519b575 100644 --- a/inc/Abilities/Pinterest/PinterestBoardsAbility.php +++ b/inc/Abilities/Pinterest/PinterestBoardsAbility.php @@ -154,7 +154,7 @@ private function registerAbilities(): void { * @param array $input Ability input. * @return array Response with boards. */ - public static function execute_list_boards( array $input ): array { + public static function execute_list_boards( array $input ): array|\WP_Error { $input; return array( 'success' => true, @@ -168,7 +168,7 @@ public static function execute_list_boards( array $input ): array { * @param array $input Ability input. * @return array Response with status. */ - public static function execute_status( array $input ): array { + public static function execute_status( array $input ): array|\WP_Error { $input; $status = self::get_sync_status(); $status['success'] = true; @@ -181,23 +181,17 @@ public static function execute_status( array $input ): array { * * @return array Result with success, count, and boards. */ - public static function sync_boards(): array { + public static function sync_boards(): array|\WP_Error { $auth = new AuthAbilities(); $provider = $auth->getProvider( 'pinterest' ); if ( ! $provider || ! $provider->is_authenticated() ) { - return array( - 'success' => false, - 'error' => 'Pinterest not authenticated', - ); + return new \WP_Error( 'missing_auth', 'Pinterest not authenticated', array( 'status' => 401 ) ); } $token = $provider->get_valid_access_token(); if ( empty( $token ) ) { - return array( - 'success' => false, - 'error' => 'Pinterest access token is missing or expired — re-authorize in WP Admin > Data Machine > Settings', - ); + return new \WP_Error( 'missing_auth', 'Pinterest access token is missing or expired — re-authorize in WP Admin > Data Machine > Settings', array( 'status' => 401 ) ); } $all_boards = array(); @@ -250,7 +244,7 @@ public static function sync_boards(): array { * * @return array Array of cached boards. */ - public static function get_cached_boards(): array { + public static function get_cached_boards(): array|\WP_Error { return get_option( self::BOARDS_OPTION, array() ); } @@ -259,7 +253,7 @@ public static function get_cached_boards(): array { * * @return array Board count and last synced timestamp. */ - public static function get_sync_status(): array { + public static function get_sync_status(): array|\WP_Error { $boards = self::get_cached_boards(); $synced = get_option( self::BOARDS_SYNCED_OPTION, 0 ); diff --git a/inc/Abilities/Pinterest/PinterestDeleteAbility.php b/inc/Abilities/Pinterest/PinterestDeleteAbility.php index 439bcfe59..e61acf740 100644 --- a/inc/Abilities/Pinterest/PinterestDeleteAbility.php +++ b/inc/Abilities/Pinterest/PinterestDeleteAbility.php @@ -79,29 +79,20 @@ public function checkPermission(): bool { return PermissionHelper::can_manage(); } - public function execute( array $input ): array { + public function execute( array $input ): array|\WP_Error { $auth = $this->getAuthProvider(); if ( ! $auth ) { - return array( - 'success' => false, - 'error' => 'Pinterest auth provider not available', - ); + return new \WP_Error( 'missing_auth', 'Pinterest auth provider not available', array( 'status' => 401 ) ); } $access_token = $auth->get_valid_access_token(); if ( empty( $access_token ) ) { - return array( - 'success' => false, - 'error' => 'Pinterest access token is missing or expired — re-authorize in WP Admin > Data Machine > Settings', - ); + return new \WP_Error( 'missing_auth', 'Pinterest access token is missing or expired — re-authorize in WP Admin > Data Machine > Settings', array( 'status' => 401 ) ); } if ( empty( $input['pin_id'] ) ) { - return array( - 'success' => false, - 'error' => 'pin_id is required', - ); + return new \WP_Error( 'missing_param', 'pin_id is required', array( 'status' => 400 ) ); } $url = self::API_URL . '/pins/' . rawurlencode( $input['pin_id'] ); @@ -118,10 +109,7 @@ public function execute( array $input ): array { ); if ( is_wp_error( $response ) ) { - return array( - 'success' => false, - 'error' => $response->get_error_message(), - ); + return new \WP_Error( 'api_error', $response->get_error_message(), array( 'status' => 500 ) ); } $status_code = wp_remote_retrieve_response_code( $response ); @@ -137,10 +125,7 @@ public function execute( array $input ): array { } $body = json_decode( wp_remote_retrieve_body( $response ), true ); - return array( - 'success' => false, - 'error' => $body['message'] ?? 'Failed to delete pin', - ); + return new \WP_Error( 'api_error', $body['message'] ?? 'Failed to delete pin', array( 'status' => 500 ) ); } private function getAuthProvider(): ?PinterestAuth { diff --git a/inc/Abilities/Pinterest/PinterestPublishAbility.php b/inc/Abilities/Pinterest/PinterestPublishAbility.php index 99d8479c8..95c235729 100644 --- a/inc/Abilities/Pinterest/PinterestPublishAbility.php +++ b/inc/Abilities/Pinterest/PinterestPublishAbility.php @@ -115,25 +115,19 @@ private function registerAbilities(): void { * @param array $input Ability input with publish parameters. * @return array Response with pin details or error. */ - public static function execute_publish( array $input ): array { + public static function execute_publish( array $input ): array|\WP_Error { $auth = new AuthAbilities(); $provider = $auth->getProvider( 'pinterest' ); if ( ! $provider || ! $provider->is_authenticated() ) { - return array( - 'success' => false, - 'error' => 'Pinterest not authenticated', - ); + return new \WP_Error( 'missing_auth', 'Pinterest not authenticated', array( 'status' => 401 ) ); } $config = $provider->get_config(); $token = $provider->get_valid_access_token(); if ( empty( $token ) ) { - return array( - 'success' => false, - 'error' => 'Pinterest access token is missing or expired — re-authorize in WP Admin > Data Machine > Settings', - ); + return new \WP_Error( 'missing_auth', 'Pinterest access token is missing or expired — re-authorize in WP Admin > Data Machine > Settings', array( 'status' => 401 ) ); } $title = sanitize_text_field( $input['title'] ?? '' ); @@ -143,10 +137,7 @@ public static function execute_publish( array $input ): array { $board_id = sanitize_text_field( $input['board_id'] ?? '' ); if ( empty( $title ) || empty( $description ) || empty( $image_url ) ) { - return array( - 'success' => false, - 'error' => 'Missing required fields: title, description, image_url', - ); + return new \WP_Error( 'api_error', 'Missing required fields: title, description, image_url', array( 'status' => 500 ) ); } // Get default board if no board_id provided @@ -155,10 +146,7 @@ public static function execute_publish( array $input ): array { } if ( empty( $board_id ) ) { - return array( - 'success' => false, - 'error' => 'No board ID provided and no default board configured', - ); + return new \WP_Error( 'api_error', 'No board ID provided and no default board configured', array( 'status' => 500 ) ); } $post_data = array( @@ -185,19 +173,13 @@ public static function execute_publish( array $input ): array { ) ); if ( ! $result['success'] ) { - return array( - 'success' => false, - 'error' => $result['error'] ?? 'Failed to create pin', - ); + return new \WP_Error( 'api_error', $result['error'] ?? 'Failed to create pin', array( 'status' => 500 ) ); } $data = json_decode( $result['data'], true ); if ( ! isset( $data['id'] ) ) { - return array( - 'success' => false, - 'error' => 'Invalid response from Pinterest API', - ); + return new \WP_Error( 'api_error', 'Invalid response from Pinterest API', array( 'status' => 500 ) ); } $pin_id = $data['id']; diff --git a/inc/Abilities/Pinterest/PinterestReadAbility.php b/inc/Abilities/Pinterest/PinterestReadAbility.php index 865cd142f..947e799e0 100644 --- a/inc/Abilities/Pinterest/PinterestReadAbility.php +++ b/inc/Abilities/Pinterest/PinterestReadAbility.php @@ -99,23 +99,17 @@ public function checkPermission(): bool { return PermissionHelper::can_manage(); } - public function execute( array $input ): array { + public function execute( array $input ): array|\WP_Error { $action = $input['action'] ?? 'pins'; $auth = $this->getAuthProvider(); if ( ! $auth ) { - return array( - 'success' => false, - 'error' => 'Pinterest auth provider not available', - ); + return new \WP_Error( 'missing_auth', 'Pinterest auth provider not available', array( 'status' => 401 ) ); } $token = $auth->get_valid_access_token(); if ( empty( $token ) ) { - return array( - 'success' => false, - 'error' => 'Pinterest access token is missing or expired — re-authorize in WP Admin > Data Machine > Settings', - ); + return new \WP_Error( 'missing_auth', 'Pinterest access token is missing or expired — re-authorize in WP Admin > Data Machine > Settings', array( 'status' => 401 ) ); } switch ( $action ) { @@ -124,10 +118,7 @@ public function execute( array $input ): array { case 'pin': if ( empty( $input['pin_id'] ) ) { - return array( - 'success' => false, - 'error' => 'pin_id is required for the pin action', - ); + return new \WP_Error( 'missing_param', 'pin_id is required for the pin action', array( 'status' => 400 ) ); } return $this->getPin( $token, $input['pin_id'] ); @@ -136,22 +127,16 @@ public function execute( array $input ): array { case 'board_pins': if ( empty( $input['board_id'] ) ) { - return array( - 'success' => false, - 'error' => 'board_id is required for the board_pins action', - ); + return new \WP_Error( 'missing_param', 'board_id is required for the board_pins action', array( 'status' => 400 ) ); } return $this->getBoardPins( $token, $input['board_id'], $input ); default: - return array( - 'success' => false, - 'error' => "Unknown action: {$action}. Use pins, pin, boards, or board_pins.", - ); + return new \WP_Error( 'api_error', "Unknown action: {$action}. Use pins, pin, boards, or board_pins.", array( 'status' => 500 ) ); } } - private function listPins( string $token, array $input ): array { + private function listPins( string $token, array $input ): array|\WP_Error { $limit = min( absint( $input['limit'] ?? 25 ), 100 ); $params = array( 'page_size' => $limit ); @@ -162,7 +147,7 @@ private function listPins( string $token, array $input ): array { return $this->apiGet( $token, '/pins?' . http_build_query( $params ), 'items', 'pins' ); } - private function getPin( string $token, string $pin_id ): array { + private function getPin( string $token, string $pin_id ): array|\WP_Error { $url = self::API_URL . "/pins/{$pin_id}"; $result = HttpClient::get( $url, @@ -173,10 +158,7 @@ private function getPin( string $token, string $pin_id ): array { ); if ( ! $result['success'] ) { - return array( - 'success' => false, - 'error' => 'Pinterest API request failed: ' . ( $result['error'] ?? 'unknown' ), - ); + return new \WP_Error( 'api_error', 'Pinterest API request failed: ' . ( $result['error'] ?? 'unknown' ), array( 'status' => 500 ) ); } $data = json_decode( $result['data'], true ); @@ -184,10 +166,7 @@ private function getPin( string $token, string $pin_id ): array { if ( 200 !== $http_code || isset( $data['code'] ) ) { $error_msg = $data['message'] ?? 'Failed to fetch pin details'; - return array( - 'success' => false, - 'error' => $error_msg, - ); + return new \WP_Error( 'api_error', $error_msg, array( 'status' => 500 ) ); } return array( @@ -196,7 +175,7 @@ private function getPin( string $token, string $pin_id ): array { ); } - private function listBoards( string $token, array $input ): array { + private function listBoards( string $token, array $input ): array|\WP_Error { $limit = min( absint( $input['limit'] ?? 25 ), 100 ); $params = array( 'page_size' => $limit ); @@ -207,7 +186,7 @@ private function listBoards( string $token, array $input ): array { return $this->apiGet( $token, '/boards?' . http_build_query( $params ), 'items', 'boards' ); } - private function getBoardPins( string $token, string $board_id, array $input ): array { + private function getBoardPins( string $token, string $board_id, array $input ): array|\WP_Error { $limit = min( absint( $input['limit'] ?? 25 ), 100 ); $params = array( 'page_size' => $limit ); @@ -227,7 +206,7 @@ private function getBoardPins( string $token, string $board_id, array $input ): * @param string $label Label for the result array. * @return array */ - private function apiGet( string $token, string $path, string $data_key, string $label ): array { + private function apiGet( string $token, string $path, string $data_key, string $label ): array|\WP_Error { $url = self::API_URL . $path; $result = HttpClient::get( $url, @@ -238,10 +217,7 @@ private function apiGet( string $token, string $path, string $data_key, string $ ); if ( ! $result['success'] ) { - return array( - 'success' => false, - 'error' => 'Pinterest API request failed: ' . ( $result['error'] ?? 'unknown' ), - ); + return new \WP_Error( 'api_error', 'Pinterest API request failed: ' . ( $result['error'] ?? 'unknown' ), array( 'status' => 500 ) ); } $data = json_decode( $result['data'], true ); @@ -249,10 +225,7 @@ private function apiGet( string $token, string $path, string $data_key, string $ if ( 200 !== $http_code || isset( $data['code'] ) ) { $error_msg = $data['message'] ?? "Failed to fetch {$label}"; - return array( - 'success' => false, - 'error' => $error_msg, - ); + return new \WP_Error( 'api_error', $error_msg, array( 'status' => 500 ) ); } $items = $data[ $data_key ] ?? array(); diff --git a/inc/Abilities/Pinterest/PinterestUpdateAbility.php b/inc/Abilities/Pinterest/PinterestUpdateAbility.php index 736ee6672..2aacbd1f9 100644 --- a/inc/Abilities/Pinterest/PinterestUpdateAbility.php +++ b/inc/Abilities/Pinterest/PinterestUpdateAbility.php @@ -85,31 +85,22 @@ public function checkPermission(): bool { return PermissionHelper::can_manage(); } - public function execute( array $input ): array { + public function execute( array $input ): array|\WP_Error { $action = $input['action'] ?? ''; $auth = $this->getAuthProvider(); if ( ! $auth ) { - return array( - 'success' => false, - 'error' => 'Pinterest auth provider not available', - ); + return new \WP_Error( 'missing_auth', 'Pinterest auth provider not available', array( 'status' => 401 ) ); } $access_token = $auth->get_valid_access_token(); if ( empty( $access_token ) ) { - return array( - 'success' => false, - 'error' => 'Pinterest access token is missing or expired — re-authorize in WP Admin > Data Machine > Settings', - ); + return new \WP_Error( 'missing_auth', 'Pinterest access token is missing or expired — re-authorize in WP Admin > Data Machine > Settings', array( 'status' => 401 ) ); } if ( empty( $input['pin_id'] ) ) { - return array( - 'success' => false, - 'error' => 'pin_id is required', - ); + return new \WP_Error( 'missing_param', 'pin_id is required', array( 'status' => 400 ) ); } $pin_id = $input['pin_id']; @@ -119,10 +110,7 @@ public function execute( array $input ): array { return $this->deletePin( $access_token, $pin_id ); default: - return array( - 'success' => false, - 'error' => "Unknown action: {$action}. Use delete.", - ); + return new \WP_Error( 'api_error', "Unknown action: {$action}. Use delete.", array( 'status' => 500 ) ); } } @@ -141,7 +129,7 @@ private function getAuthProvider(): ?PinterestAuth { return $provider; } - private function deletePin( string $access_token, string $pin_id ): array { + private function deletePin( string $access_token, string $pin_id ): array|\WP_Error { $url = self::API_URL . '/pins/' . rawurlencode( $pin_id ); $response = wp_remote_request( @@ -156,10 +144,7 @@ private function deletePin( string $access_token, string $pin_id ): array { ); if ( is_wp_error( $response ) ) { - return array( - 'success' => false, - 'error' => $response->get_error_message(), - ); + return new \WP_Error( 'api_error', $response->get_error_message(), array( 'status' => 500 ) ); } $status_code = wp_remote_retrieve_response_code( $response ); @@ -175,9 +160,6 @@ private function deletePin( string $access_token, string $pin_id ): array { } $body = json_decode( wp_remote_retrieve_body( $response ), true ); - return array( - 'success' => false, - 'error' => $body['message'] ?? 'Failed to delete pin', - ); + return new \WP_Error( 'api_error', $body['message'] ?? 'Failed to delete pin', array( 'status' => 500 ) ); } } diff --git a/inc/Abilities/Reddit/FetchRedditAbility.php b/inc/Abilities/Reddit/FetchRedditAbility.php index 01cac9a32..8453eede7 100644 --- a/inc/Abilities/Reddit/FetchRedditAbility.php +++ b/inc/Abilities/Reddit/FetchRedditAbility.php @@ -155,7 +155,7 @@ public function checkPermission(): bool { * @param array $input Input parameters. * @return array Result with fetched data or error. */ - public function execute( array $input ): array { + public function execute( array $input ): array|\WP_Error { $logs = array(); $config = $this->normalizeConfig( $input ); @@ -183,11 +183,7 @@ public function execute( array $input ): array { 'level' => 'error', 'message' => 'Reddit: Either subreddit or query must be provided.', ); - return array( - 'success' => false, - 'error' => 'Either subreddit or query must be provided', - 'logs' => $logs, - ); + return new \WP_Error( 'missing_param', 'Either subreddit or query must be provided', array( 'status' => 400, 'logs' => $logs ) ); } if ( ! empty( $subreddit ) && ! preg_match( '/^[a-zA-Z0-9_]+$/', $subreddit ) ) { @@ -196,11 +192,7 @@ public function execute( array $input ): array { 'message' => 'Reddit: Invalid subreddit name format.', 'data' => array( 'subreddit' => $subreddit ), ); - return array( - 'success' => false, - 'error' => 'Invalid subreddit name format', - 'logs' => $logs, - ); + return new \WP_Error( 'missing_param', 'Invalid subreddit name format', array( 'status' => 400, 'logs' => $logs ) ); } $valid_sorts = array( 'hot', 'new', 'top', 'rising', 'controversial', 'relevance' ); @@ -213,11 +205,7 @@ public function execute( array $input ): array { 'valid_sorts' => $valid_sorts, ), ); - return array( - 'success' => false, - 'error' => 'Invalid sort parameter', - 'logs' => $logs, - ); + return new \WP_Error( 'missing_param', 'Invalid sort parameter', array( 'status' => 400, 'logs' => $logs ) ); } $mode_label = $is_global_search ? 'global search' : ( $is_subreddit_search ? "r/{$subreddit} search" : "r/{$subreddit}" ); @@ -282,11 +270,7 @@ public function execute( array $input ): array { 'message' => 'Reddit: API request failed.', 'data' => array( 'error' => $result['error'] ), ); - return array( - 'success' => false, - 'error' => $result['error'], - 'logs' => $logs, - ); + return new \WP_Error( 'api_error', $result['error'], array( 'status' => 500, 'logs' => $logs ) ); } else { break; } @@ -315,11 +299,7 @@ public function execute( array $input ): array { 'message' => 'Reddit: Invalid JSON response.', 'data' => array( 'error' => $error_message ), ); - return array( - 'success' => false, - 'error' => $error_message, - 'logs' => $logs, - ); + return new \WP_Error( 'api_error', $error_message, array( 'status' => 500, 'logs' => $logs ) ); } else { break; } @@ -540,7 +520,7 @@ function ( $comment ) { /** * Normalize input configuration with defaults. */ - private function normalizeConfig( array $input ): array { + private function normalizeConfig( array $input ): array|\WP_Error { $defaults = array( 'subreddit' => '', 'query' => '', @@ -665,7 +645,7 @@ private function buildApiUrl( /** * Make HTTP GET request. */ - private function httpGet( string $url, array $options ): array { + private function httpGet( string $url, array $options ): array|\WP_Error { $args = array( 'timeout' => $options['timeout'] ?? 30, 'headers' => $options['headers'] ?? array(), @@ -674,10 +654,7 @@ private function httpGet( string $url, array $options ): array { $response = wp_remote_get( $url, $args ); if ( is_wp_error( $response ) ) { - return array( - 'success' => false, - 'error' => $response->get_error_message(), - ); + return new \WP_Error( 'api_error', $response->get_error_message(), array( 'status' => 500 ) ); } $status_code = wp_remote_retrieve_response_code( $response ); @@ -693,7 +670,7 @@ private function httpGet( string $url, array $options ): array { /** * Fetch comments for a Reddit post. */ - private function fetchComments( string $permalink, string $access_token, int $comment_count ): array { + private function fetchComments( string $permalink, string $access_token, int $comment_count ): array|\WP_Error { $comments_array = array(); $comments_url = 'https://oauth.reddit.com' . $permalink . '.json?limit=' . $comment_count . '&sort=top'; $comments_result = $this->httpGet( diff --git a/inc/Abilities/Reddit/ReplyRedditAbility.php b/inc/Abilities/Reddit/ReplyRedditAbility.php index d618dce32..2b0f0aaf5 100644 --- a/inc/Abilities/Reddit/ReplyRedditAbility.php +++ b/inc/Abilities/Reddit/ReplyRedditAbility.php @@ -102,31 +102,22 @@ public function checkPermission(): bool { * @param array $input Input parameters. * @return array Result with reply data or error. */ - public function execute( array $input ): array { + public function execute( array $input ): array|\WP_Error { $thing_id = sanitize_text_field( $input['thing_id'] ?? '' ); $text = trim( $input['text'] ?? '' ); $access_token = $input['access_token'] ?? ''; if ( empty( $thing_id ) ) { - return array( - 'success' => false, - 'error' => 'thing_id is required (e.g. t3_abc123 for post, t1_abc123 for comment)', - ); + return new \WP_Error( 'missing_param', 'thing_id is required (e.g. t3_abc123 for post, t1_abc123 for comment)', array( 'status' => 400 ) ); } // Validate thing_id format: must be t1_ (comment) or t3_ (post). if ( ! preg_match( '/^t[13]_[a-z0-9]+$/i', $thing_id ) ) { - return array( - 'success' => false, - 'error' => 'Invalid thing_id format. Must be t3_xxx (post) or t1_xxx (comment).', - ); + return new \WP_Error( 'missing_param', 'Invalid thing_id format. Must be t3_xxx (post) or t1_xxx (comment).', array( 'status' => 400 ) ); } if ( empty( $text ) ) { - return array( - 'success' => false, - 'error' => 'Reply text is required.', - ); + return new \WP_Error( 'missing_param', 'Reply text is required.', array( 'status' => 400 ) ); } if ( mb_strlen( $text ) > self::MAX_COMMENT_LENGTH ) { @@ -134,10 +125,7 @@ public function execute( array $input ): array { } if ( empty( $access_token ) ) { - return array( - 'success' => false, - 'error' => 'access_token is required.', - ); + return new \WP_Error( 'missing_param', 'access_token is required.', array( 'status' => 400 ) ); } return $this->postComment( $access_token, $thing_id, $text ); @@ -151,7 +139,7 @@ public function execute( array $input ): array { * @param string $text Comment text (markdown). * @return array Result. */ - private function postComment( string $access_token, string $thing_id, string $text ): array { + private function postComment( string $access_token, string $thing_id, string $text ): array|\WP_Error { $url = self::API_BASE . '/api/comment'; $response = wp_remote_post( @@ -171,10 +159,7 @@ private function postComment( string $access_token, string $thing_id, string $te ); if ( is_wp_error( $response ) ) { - return array( - 'success' => false, - 'error' => $response->get_error_message(), - ); + return new \WP_Error( 'api_error', $response->get_error_message(), array( 'status' => 500 ) ); } $status_code = wp_remote_retrieve_response_code( $response ); @@ -189,17 +174,11 @@ function ( $err ) { }, $errors ); - return array( - 'success' => false, - 'error' => implode( '; ', $error_messages ), - ); + return new \WP_Error( 'api_error', implode( '; ', $error_messages ), array( 'status' => 500 ) ); } if ( $status_code < 200 || $status_code >= 300 ) { - return array( - 'success' => false, - 'error' => "Reddit API returned HTTP {$status_code}", - ); + return new \WP_Error( 'api_error', "Reddit API returned HTTP {$status_code}", array( 'status' => 500 ) ); } // Extract the new comment data. diff --git a/inc/Abilities/Reddit/SubmitRedditAbility.php b/inc/Abilities/Reddit/SubmitRedditAbility.php index 69d5078f2..cf1ba32c4 100644 --- a/inc/Abilities/Reddit/SubmitRedditAbility.php +++ b/inc/Abilities/Reddit/SubmitRedditAbility.php @@ -138,7 +138,7 @@ public function checkPermission(): bool { * @param array $input Input parameters. * @return array Result with post data or error. */ - public function execute( array $input ): array { + public function execute( array $input ): array|\WP_Error { $subreddit = sanitize_text_field( $input['subreddit'] ?? '' ); $title = trim( sanitize_text_field( $input['title'] ?? '' ) ); $text = trim( $input['text'] ?? '' ); @@ -150,24 +150,15 @@ public function execute( array $input ): array { $access_token = $input['access_token'] ?? ''; if ( empty( $subreddit ) ) { - return array( - 'success' => false, - 'error' => 'subreddit is required.', - ); + return new \WP_Error( 'missing_param', 'subreddit is required.', array( 'status' => 400 ) ); } if ( ! preg_match( '/^[a-zA-Z0-9_]+$/', $subreddit ) ) { - return array( - 'success' => false, - 'error' => 'Invalid subreddit name format.', - ); + return new \WP_Error( 'missing_param', 'Invalid subreddit name format.', array( 'status' => 400 ) ); } if ( empty( $title ) ) { - return array( - 'success' => false, - 'error' => 'title is required.', - ); + return new \WP_Error( 'missing_param', 'title is required.', array( 'status' => 400 ) ); } if ( mb_strlen( $title ) > self::MAX_TITLE_LENGTH ) { @@ -175,10 +166,7 @@ public function execute( array $input ): array { } if ( empty( $access_token ) ) { - return array( - 'success' => false, - 'error' => 'access_token is required.', - ); + return new \WP_Error( 'missing_param', 'access_token is required.', array( 'status' => 400 ) ); } // Determine post kind: 'self' for text, 'link' for URL. @@ -217,7 +205,7 @@ private function submitPost( string $flair_text, bool $nsfw, bool $spoiler - ): array { + ): array|\WP_Error { $api_url = self::API_BASE . '/api/submit'; $body = array( @@ -259,10 +247,7 @@ private function submitPost( ); if ( is_wp_error( $response ) ) { - return array( - 'success' => false, - 'error' => $response->get_error_message(), - ); + return new \WP_Error( 'api_error', $response->get_error_message(), array( 'status' => 500 ) ); } $status_code = wp_remote_retrieve_response_code( $response ); @@ -277,17 +262,11 @@ function ( $err ) { }, $errors ); - return array( - 'success' => false, - 'error' => implode( '; ', $error_messages ), - ); + return new \WP_Error( 'api_error', implode( '; ', $error_messages ), array( 'status' => 500 ) ); } if ( $status_code < 200 || $status_code >= 300 ) { - return array( - 'success' => false, - 'error' => "Reddit API returned HTTP {$status_code}", - ); + return new \WP_Error( 'api_error', "Reddit API returned HTTP {$status_code}", array( 'status' => 500 ) ); } $post_data = $result['json']['data'] ?? array(); diff --git a/inc/Abilities/Reddit/VoteRedditAbility.php b/inc/Abilities/Reddit/VoteRedditAbility.php index de590cae2..774c150d3 100644 --- a/inc/Abilities/Reddit/VoteRedditAbility.php +++ b/inc/Abilities/Reddit/VoteRedditAbility.php @@ -96,37 +96,25 @@ public function checkPermission(): bool { * @param array $input Input parameters. * @return array Result. */ - public function execute( array $input ): array { + public function execute( array $input ): array|\WP_Error { $thing_id = sanitize_text_field( $input['thing_id'] ?? '' ); $direction = (int) ( $input['direction'] ?? 0 ); $access_token = $input['access_token'] ?? ''; if ( empty( $thing_id ) ) { - return array( - 'success' => false, - 'error' => 'thing_id is required.', - ); + return new \WP_Error( 'missing_param', 'thing_id is required.', array( 'status' => 400 ) ); } if ( ! preg_match( '/^t[13]_[a-z0-9]+$/i', $thing_id ) ) { - return array( - 'success' => false, - 'error' => 'Invalid thing_id format. Must be t3_xxx (post) or t1_xxx (comment).', - ); + return new \WP_Error( 'missing_param', 'Invalid thing_id format. Must be t3_xxx (post) or t1_xxx (comment).', array( 'status' => 400 ) ); } if ( ! in_array( $direction, array( 1, 0, -1 ), true ) ) { - return array( - 'success' => false, - 'error' => 'direction must be 1 (upvote), 0 (unvote), or -1 (downvote).', - ); + return new \WP_Error( 'missing_param', 'direction must be 1 (upvote), 0 (unvote), or -1 (downvote).', array( 'status' => 400 ) ); } if ( empty( $access_token ) ) { - return array( - 'success' => false, - 'error' => 'access_token is required.', - ); + return new \WP_Error( 'missing_param', 'access_token is required.', array( 'status' => 400 ) ); } $url = self::API_BASE . '/api/vote'; @@ -147,20 +135,14 @@ public function execute( array $input ): array { ); if ( is_wp_error( $response ) ) { - return array( - 'success' => false, - 'error' => $response->get_error_message(), - ); + return new \WP_Error( 'api_error', $response->get_error_message(), array( 'status' => 500 ) ); } $status_code = wp_remote_retrieve_response_code( $response ); if ( $status_code < 200 || $status_code >= 300 ) { $body = json_decode( wp_remote_retrieve_body( $response ), true ); - return array( - 'success' => false, - 'error' => $body['message'] ?? "Reddit API returned HTTP {$status_code}", - ); + return new \WP_Error( 'api_error', $body['message'] ?? "Reddit API returned HTTP {$status_code}", array( 'status' => 500 ) ); } $direction_labels = array( diff --git a/inc/Abilities/Threads/ThreadsDeleteAbility.php b/inc/Abilities/Threads/ThreadsDeleteAbility.php index 68f67479e..e1bbe0fbd 100644 --- a/inc/Abilities/Threads/ThreadsDeleteAbility.php +++ b/inc/Abilities/Threads/ThreadsDeleteAbility.php @@ -79,28 +79,19 @@ public function checkPermission(): bool { return PermissionHelper::can_manage(); } - public function execute( array $input ): array { + public function execute( array $input ): array|\WP_Error { $auth = $this->getAuthProvider(); if ( ! $auth ) { - return array( - 'success' => false, - 'error' => 'Threads auth provider not available', - ); + return new \WP_Error( 'missing_auth', 'Threads auth provider not available', array( 'status' => 401 ) ); } $access_token = $auth->get_valid_access_token(); if ( empty( $access_token ) ) { - return array( - 'success' => false, - 'error' => 'Threads access token unavailable', - ); + return new \WP_Error( 'missing_auth', 'Threads access token unavailable', array( 'status' => 401 ) ); } if ( empty( $input['thread_id'] ) ) { - return array( - 'success' => false, - 'error' => 'thread_id is required', - ); + return new \WP_Error( 'missing_param', 'thread_id is required', array( 'status' => 400 ) ); } $url = self::GRAPH_API_URL . '/' . rawurlencode( $input['thread_id'] ); @@ -116,10 +107,7 @@ public function execute( array $input ): array { ); if ( is_wp_error( $response ) ) { - return array( - 'success' => false, - 'error' => $response->get_error_message(), - ); + return new \WP_Error( 'api_error', $response->get_error_message(), array( 'status' => 500 ) ); } $status_code = wp_remote_retrieve_response_code( $response ); @@ -135,10 +123,7 @@ public function execute( array $input ): array { ); } - return array( - 'success' => false, - 'error' => $body['error']['message'] ?? 'Failed to delete thread', - ); + return new \WP_Error( 'api_error', $body['error']['message'] ?? 'Failed to delete thread', array( 'status' => 500 ) ); } private function getAuthProvider(): ?ThreadsAuth { diff --git a/inc/Abilities/Threads/ThreadsPublishAbility.php b/inc/Abilities/Threads/ThreadsPublishAbility.php index 769749e47..bfa0d77cf 100644 --- a/inc/Abilities/Threads/ThreadsPublishAbility.php +++ b/inc/Abilities/Threads/ThreadsPublishAbility.php @@ -131,36 +131,27 @@ private function registerAbilities(): void { * @param array $input Ability input with publish parameters. * @return array Response with post details or error. */ - public static function execute_publish( array $input ): array { + public static function execute_publish( array $input ): array|\WP_Error { $content = $input['content'] ?? ''; $image_url = $input['image_url'] ?? ''; $source_url = $input['source_url'] ?? ''; if ( empty( $content ) ) { - return array( - 'success' => false, - 'error' => 'Content is required', - ); + return new \WP_Error( 'missing_param', 'Content is required', array( 'status' => 400 ) ); } $auth = new AuthAbilities(); $provider = $auth->getProvider( 'threads' ); if ( ! $provider || ! $provider->is_authenticated() ) { - return array( - 'success' => false, - 'error' => 'Threads not authenticated', - ); + return new \WP_Error( 'missing_auth', 'Threads not authenticated', array( 'status' => 401 ) ); } $user_id = $provider->get_user_id(); $access_token = $provider->get_valid_access_token(); if ( empty( $user_id ) || empty( $access_token ) ) { - return array( - 'success' => false, - 'error' => 'Threads credentials not available', - ); + return new \WP_Error( 'missing_auth', 'Threads credentials not available', array( 'status' => 401 ) ); } // Format content with source URL @@ -179,19 +170,13 @@ public static function execute_publish( array $input ): array { if ( ! empty( $image_url ) && filter_var( $image_url, FILTER_VALIDATE_URL ) ) { $media_id = self::create_media_container( $access_token, $user_id, $image_url ); if ( is_wp_error( $media_id ) ) { - return array( - 'success' => false, - 'error' => $media_id->get_error_message(), - ); + return new \WP_Error( 'api_error', $media_id->get_error_message(), array( 'status' => 500 ) ); } // Wait for media processing $media_ready = self::wait_for_media( $access_token, $media_id ); if ( ! $media_ready ) { - return array( - 'success' => false, - 'error' => 'Media processing failed', - ); + return new \WP_Error( 'api_error', 'Media processing failed', array( 'status' => 500 ) ); } } @@ -217,10 +202,7 @@ public static function execute_publish( array $input ): array { ); if ( is_wp_error( $response ) ) { - return array( - 'success' => false, - 'error' => $response->get_error_message(), - ); + return new \WP_Error( 'api_error', $response->get_error_message(), array( 'status' => 500 ) ); } $status_code = wp_remote_retrieve_response_code( $response ); @@ -233,10 +215,7 @@ public static function execute_publish( array $input ): array { // Step 3: Publish the thread $publish_result = self::publish_thread( $access_token, $creation_id ); if ( is_wp_error( $publish_result ) ) { - return array( - 'success' => false, - 'error' => $publish_result->get_error_message(), - ); + return new \WP_Error( 'api_error', $publish_result->get_error_message(), array( 'status' => 500 ) ); } $post_id = $publish_result; @@ -254,10 +233,7 @@ public static function execute_publish( array $input ): array { $error_msg = $data['error']['message']; } - return array( - 'success' => false, - 'error' => $error_msg, - ); + return new \WP_Error( 'api_error', $error_msg, array( 'status' => 500 ) ); } /** @@ -266,16 +242,13 @@ public static function execute_publish( array $input ): array { * @param array $input Ability input. * @return array Account details or error. */ - public static function get_account( array $input ): array { + public static function get_account( array $input ): array|\WP_Error { $input; $auth = new AuthAbilities(); $provider = $auth->getProvider( 'threads' ); if ( ! $provider || ! $provider->is_authenticated() ) { - return array( - 'success' => false, - 'error' => 'Threads not authenticated', - ); + return new \WP_Error( 'missing_auth', 'Threads not authenticated', array( 'status' => 401 ) ); } return array( diff --git a/inc/Abilities/Threads/ThreadsReadAbility.php b/inc/Abilities/Threads/ThreadsReadAbility.php index 01c0a18e8..14c77e018 100644 --- a/inc/Abilities/Threads/ThreadsReadAbility.php +++ b/inc/Abilities/Threads/ThreadsReadAbility.php @@ -99,23 +99,17 @@ public function checkPermission(): bool { return PermissionHelper::can_manage(); } - public function execute( array $input ): array { + public function execute( array $input ): array|\WP_Error { $action = $input['action'] ?? 'list'; $auth = $this->getAuthProvider(); if ( ! $auth ) { - return array( - 'success' => false, - 'error' => 'Threads auth provider not available', - ); + return new \WP_Error( 'missing_auth', 'Threads auth provider not available', array( 'status' => 401 ) ); } $access_token = $auth->get_valid_access_token(); if ( empty( $access_token ) ) { - return array( - 'success' => false, - 'error' => 'Threads access token unavailable (expired or refresh failed)', - ); + return new \WP_Error( 'missing_auth', 'Threads access token unavailable (expired or refresh failed)', array( 'status' => 401 ) ); } switch ( $action ) { @@ -124,37 +118,25 @@ public function execute( array $input ): array { case 'get': if ( empty( $input['thread_id'] ) ) { - return array( - 'success' => false, - 'error' => 'thread_id is required for the get action', - ); + return new \WP_Error( 'missing_param', 'thread_id is required for the get action', array( 'status' => 400 ) ); } return $this->getThread( $access_token, $input['thread_id'] ); case 'replies': if ( empty( $input['thread_id'] ) ) { - return array( - 'success' => false, - 'error' => 'thread_id is required for the replies action', - ); + return new \WP_Error( 'missing_param', 'thread_id is required for the replies action', array( 'status' => 400 ) ); } return $this->getReplies( $access_token, $input['thread_id'], $input ); default: - return array( - 'success' => false, - 'error' => "Unknown action: {$action}. Use list, get, or replies.", - ); + return new \WP_Error( 'api_error', "Unknown action: {$action}. Use list, get, or replies.", array( 'status' => 500 ) ); } } - private function listThreads( ThreadsAuth $auth, string $access_token, array $input ): array { + private function listThreads( ThreadsAuth $auth, string $access_token, array $input ): array|\WP_Error { $user_id = $auth->get_page_id(); if ( empty( $user_id ) ) { - return array( - 'success' => false, - 'error' => 'Threads user ID not available. Try re-authenticating.', - ); + return new \WP_Error( 'missing_auth', 'Threads user ID not available. Try re-authenticating.', array( 'status' => 401 ) ); } $limit = min( absint( $input['limit'] ?? 25 ), 100 ); @@ -172,10 +154,7 @@ private function listThreads( ThreadsAuth $auth, string $access_token, array $in $result = HttpClient::get( $url, array( 'context' => 'Threads Read' ) ); if ( ! $result['success'] ) { - return array( - 'success' => false, - 'error' => 'Threads API request failed: ' . ( $result['error'] ?? 'unknown' ), - ); + return new \WP_Error( 'api_error', 'Threads API request failed: ' . ( $result['error'] ?? 'unknown' ), array( 'status' => 500 ) ); } $data = json_decode( $result['data'], true ); @@ -183,10 +162,7 @@ private function listThreads( ThreadsAuth $auth, string $access_token, array $in if ( 200 !== $http_code || isset( $data['error'] ) ) { $error_msg = $data['error']['message'] ?? 'Failed to fetch Threads posts'; - return array( - 'success' => false, - 'error' => $error_msg, - ); + return new \WP_Error( 'api_error', $error_msg, array( 'status' => 500 ) ); } $threads = $data['data'] ?? array(); @@ -203,7 +179,7 @@ private function listThreads( ThreadsAuth $auth, string $access_token, array $in ); } - private function getThread( string $access_token, string $thread_id ): array { + private function getThread( string $access_token, string $thread_id ): array|\WP_Error { $params = array( 'fields' => self::DETAIL_FIELDS, 'access_token' => $access_token, @@ -213,10 +189,7 @@ private function getThread( string $access_token, string $thread_id ): array { $result = HttpClient::get( $url, array( 'context' => 'Threads Read' ) ); if ( ! $result['success'] ) { - return array( - 'success' => false, - 'error' => 'Threads API request failed: ' . ( $result['error'] ?? 'unknown' ), - ); + return new \WP_Error( 'api_error', 'Threads API request failed: ' . ( $result['error'] ?? 'unknown' ), array( 'status' => 500 ) ); } $data = json_decode( $result['data'], true ); @@ -224,10 +197,7 @@ private function getThread( string $access_token, string $thread_id ): array { if ( 200 !== $http_code || isset( $data['error'] ) ) { $error_msg = $data['error']['message'] ?? 'Failed to fetch thread details'; - return array( - 'success' => false, - 'error' => $error_msg, - ); + return new \WP_Error( 'api_error', $error_msg, array( 'status' => 500 ) ); } return array( @@ -236,7 +206,7 @@ private function getThread( string $access_token, string $thread_id ): array { ); } - private function getReplies( string $access_token, string $thread_id, array $input ): array { + private function getReplies( string $access_token, string $thread_id, array $input ): array|\WP_Error { $limit = min( absint( $input['limit'] ?? 25 ), 100 ); $params = array( 'fields' => 'id,text,timestamp,username,like_count', @@ -252,10 +222,7 @@ private function getReplies( string $access_token, string $thread_id, array $inp $result = HttpClient::get( $url, array( 'context' => 'Threads Read' ) ); if ( ! $result['success'] ) { - return array( - 'success' => false, - 'error' => 'Threads API request failed: ' . ( $result['error'] ?? 'unknown' ), - ); + return new \WP_Error( 'api_error', 'Threads API request failed: ' . ( $result['error'] ?? 'unknown' ), array( 'status' => 500 ) ); } $data = json_decode( $result['data'], true ); @@ -263,10 +230,7 @@ private function getReplies( string $access_token, string $thread_id, array $inp if ( 200 !== $http_code || isset( $data['error'] ) ) { $error_msg = $data['error']['message'] ?? 'Failed to fetch replies'; - return array( - 'success' => false, - 'error' => $error_msg, - ); + return new \WP_Error( 'api_error', $error_msg, array( 'status' => 500 ) ); } $replies = $data['data'] ?? array(); diff --git a/inc/Abilities/Threads/ThreadsUpdateAbility.php b/inc/Abilities/Threads/ThreadsUpdateAbility.php index 9c8c7fd4e..9883c87b0 100644 --- a/inc/Abilities/Threads/ThreadsUpdateAbility.php +++ b/inc/Abilities/Threads/ThreadsUpdateAbility.php @@ -85,30 +85,21 @@ public function checkPermission(): bool { return PermissionHelper::can_manage(); } - public function execute( array $input ): array { + public function execute( array $input ): array|\WP_Error { $action = $input['action'] ?? ''; $auth = $this->getAuthProvider(); if ( ! $auth ) { - return array( - 'success' => false, - 'error' => 'Threads auth provider not available', - ); + return new \WP_Error( 'missing_auth', 'Threads auth provider not available', array( 'status' => 401 ) ); } $access_token = $auth->get_valid_access_token(); if ( empty( $access_token ) ) { - return array( - 'success' => false, - 'error' => 'Threads access token unavailable', - ); + return new \WP_Error( 'missing_auth', 'Threads access token unavailable', array( 'status' => 401 ) ); } if ( empty( $input['thread_id'] ) ) { - return array( - 'success' => false, - 'error' => 'thread_id is required', - ); + return new \WP_Error( 'missing_param', 'thread_id is required', array( 'status' => 400 ) ); } $thread_id = $input['thread_id']; @@ -118,10 +109,7 @@ public function execute( array $input ): array { return $this->deleteThread( $access_token, $thread_id ); default: - return array( - 'success' => false, - 'error' => "Unknown action: {$action}. Use delete.", - ); + return new \WP_Error( 'api_error', "Unknown action: {$action}. Use delete.", array( 'status' => 500 ) ); } } @@ -140,7 +128,7 @@ private function getAuthProvider(): ?ThreadsAuth { return $provider; } - private function deleteThread( string $access_token, string $thread_id ): array { + private function deleteThread( string $access_token, string $thread_id ): array|\WP_Error { $url = self::GRAPH_API_URL . '/' . rawurlencode( $thread_id ); $response = wp_remote_post( @@ -154,10 +142,7 @@ private function deleteThread( string $access_token, string $thread_id ): array ); if ( is_wp_error( $response ) ) { - return array( - 'success' => false, - 'error' => $response->get_error_message(), - ); + return new \WP_Error( 'api_error', $response->get_error_message(), array( 'status' => 500 ) ); } $status_code = wp_remote_retrieve_response_code( $response ); @@ -173,9 +158,6 @@ private function deleteThread( string $access_token, string $thread_id ): array ); } - return array( - 'success' => false, - 'error' => $body['error']['message'] ?? 'Failed to delete thread', - ); + return new \WP_Error( 'api_error', $body['error']['message'] ?? 'Failed to delete thread', array( 'status' => 500 ) ); } } diff --git a/inc/Abilities/Twitter/TwitterDeleteAbility.php b/inc/Abilities/Twitter/TwitterDeleteAbility.php index e52700963..cd03923f3 100644 --- a/inc/Abilities/Twitter/TwitterDeleteAbility.php +++ b/inc/Abilities/Twitter/TwitterDeleteAbility.php @@ -77,28 +77,19 @@ public function checkPermission(): bool { return PermissionHelper::can_manage(); } - public function execute( array $input ): array { + public function execute( array $input ): array|\WP_Error { $auth = $this->getAuthProvider(); if ( ! $auth ) { - return array( - 'success' => false, - 'error' => 'Twitter auth provider not available', - ); + return new \WP_Error( 'missing_auth', 'Twitter auth provider not available', array( 'status' => 401 ) ); } $connection = $auth->get_connection(); if ( ! $connection ) { - return array( - 'success' => false, - 'error' => 'Twitter connection not available', - ); + return new \WP_Error( 'missing_auth', 'Twitter connection not available', array( 'status' => 401 ) ); } if ( empty( $input['tweet_id'] ) ) { - return array( - 'success' => false, - 'error' => 'tweet_id is required', - ); + return new \WP_Error( 'missing_param', 'tweet_id is required', array( 'status' => 400 ) ); } $connection->setApiVersion( '2' ); @@ -117,10 +108,7 @@ public function execute( array $input ): array { } $error = $result['detail'] ?? $result['title'] ?? 'Failed to delete tweet'; - return array( - 'success' => false, - 'error' => $error, - ); + return new \WP_Error( 'api_error', $error, array( 'status' => 500 ) ); } private function getAuthProvider(): ?TwitterAuth { diff --git a/inc/Abilities/Twitter/TwitterPublishAbility.php b/inc/Abilities/Twitter/TwitterPublishAbility.php index 38c003324..2245cda39 100644 --- a/inc/Abilities/Twitter/TwitterPublishAbility.php +++ b/inc/Abilities/Twitter/TwitterPublishAbility.php @@ -144,35 +144,26 @@ private function registerAbilities(): void { * @param array $input Ability input with publish parameters. * @return array Response with tweet details or error. */ - public static function execute_publish( array $input ): array { + public static function execute_publish( array $input ): array|\WP_Error { $content = $input['content'] ?? ''; $media_path = $input['media_path'] ?? $input['image_path'] ?? ''; $source_url = $input['source_url'] ?? ''; $link_handling = $input['link_handling'] ?? 'append'; if ( empty( $content ) ) { - return array( - 'success' => false, - 'error' => 'Content is required', - ); + return new \WP_Error( 'missing_param', 'Content is required', array( 'status' => 400 ) ); } $auth = new AuthAbilities(); $provider = $auth->getProvider( 'twitter' ); if ( ! $provider || ! $provider->is_authenticated() ) { - return array( - 'success' => false, - 'error' => 'Twitter not authenticated', - ); + return new \WP_Error( 'missing_auth', 'Twitter not authenticated', array( 'status' => 401 ) ); } $connection = $provider->get_connection(); if ( is_wp_error( $connection ) ) { - return array( - 'success' => false, - 'error' => $connection->get_error_message(), - ); + return new \WP_Error( 'api_error', $connection->get_error_message(), array( 'status' => 500 ) ); } // Format tweet text with link handling @@ -188,10 +179,7 @@ public static function execute_publish( array $input ): array { if ( ! empty( $media_path ) && file_exists( $media_path ) ) { $media_id = self::upload_media( $connection, $media_path ); if ( ! $media_id ) { - return array( - 'success' => false, - 'error' => 'Failed to upload media', - ); + return new \WP_Error( 'api_error', 'Failed to upload media', array( 'status' => 500 ) ); } } @@ -230,15 +218,9 @@ public static function execute_publish( array $input ): array { $error_msg = $response->title; } - return array( - 'success' => false, - 'error' => $error_msg, - ); + return new \WP_Error( 'api_error', $error_msg, array( 'status' => 500 ) ); } catch ( \Exception $e ) { - return array( - 'success' => false, - 'error' => $e->getMessage(), - ); + return new \WP_Error( 'api_error', $e->getMessage(), array( 'status' => 500 ) ); } } @@ -248,16 +230,13 @@ public static function execute_publish( array $input ): array { * @param array $input Ability input. * @return array Account details or error. */ - public static function get_account( array $input ): array { + public static function get_account( array $input ): array|\WP_Error { $input; $auth = new AuthAbilities(); $provider = $auth->getProvider( 'twitter' ); if ( ! $provider || ! $provider->is_authenticated() ) { - return array( - 'success' => false, - 'error' => 'Twitter not authenticated', - ); + return new \WP_Error( 'missing_auth', 'Twitter not authenticated', array( 'status' => 401 ) ); } $account = $provider->get_account_details(); @@ -420,7 +399,7 @@ private static function upload_media( $connection, string $media_path ): ?string * @param string $screen_name Twitter screen name. * @return array Reply tweet details. */ - private static function post_reply( $connection, string $original_tweet_id, string $source_url, string $screen_name ): array { + private static function post_reply( $connection, string $original_tweet_id, string $source_url, string $screen_name ): array|\WP_Error { try { $reply_payload = array( 'text' => $source_url, @@ -443,15 +422,9 @@ private static function post_reply( $connection, string $original_tweet_id, stri ); } - return array( - 'success' => false, - 'error' => 'Failed to post reply', - ); + return new \WP_Error( 'api_error', 'Failed to post reply', array( 'status' => 500 ) ); } catch ( \Exception $e ) { - return array( - 'success' => false, - 'error' => $e->getMessage(), - ); + return new \WP_Error( 'api_error', $e->getMessage(), array( 'status' => 500 ) ); } } } diff --git a/inc/Abilities/Twitter/TwitterReadAbility.php b/inc/Abilities/Twitter/TwitterReadAbility.php index 02392739e..9e8ee5fb8 100644 --- a/inc/Abilities/Twitter/TwitterReadAbility.php +++ b/inc/Abilities/Twitter/TwitterReadAbility.php @@ -96,23 +96,17 @@ public function checkPermission(): bool { return PermissionHelper::can_manage(); } - public function execute( array $input ): array { + public function execute( array $input ): array|\WP_Error { $action = $input['action'] ?? 'list'; $auth = $this->getAuthProvider(); if ( ! $auth ) { - return array( - 'success' => false, - 'error' => 'Twitter auth provider not available', - ); + return new \WP_Error( 'missing_auth', 'Twitter auth provider not available', array( 'status' => 401 ) ); } $connection = $auth->get_connection(); if ( is_wp_error( $connection ) ) { - return array( - 'success' => false, - 'error' => 'Twitter connection failed: ' . $connection->get_error_message(), - ); + return new \WP_Error( 'api_error', 'Twitter connection failed: ' . $connection->get_error_message(), array( 'status' => 500 ) ); } $connection->setApiVersion( '2' ); @@ -123,10 +117,7 @@ public function execute( array $input ): array { case 'get': if ( empty( $input['tweet_id'] ) ) { - return array( - 'success' => false, - 'error' => 'tweet_id is required for the get action', - ); + return new \WP_Error( 'missing_param', 'tweet_id is required for the get action', array( 'status' => 400 ) ); } return $this->getTweet( $connection, $input['tweet_id'] ); @@ -134,21 +125,15 @@ public function execute( array $input ): array { return $this->getMentions( $auth, $connection, $input ); default: - return array( - 'success' => false, - 'error' => "Unknown action: {$action}. Use list, get, or mentions.", - ); + return new \WP_Error( 'api_error', "Unknown action: {$action}. Use list, get, or mentions.", array( 'status' => 500 ) ); } } - private function listTweets( TwitterAuth $auth, $connection, array $input ): array { + private function listTweets( TwitterAuth $auth, $connection, array $input ): array|\WP_Error { $account = $auth->get_account_details(); $user_id = $account['user_id'] ?? null; if ( empty( $user_id ) ) { - return array( - 'success' => false, - 'error' => 'Twitter user ID not available. Try re-authenticating.', - ); + return new \WP_Error( 'missing_auth', 'Twitter user ID not available. Try re-authenticating.', array( 'status' => 401 ) ); } $limit = min( absint( $input['limit'] ?? 25 ), 100 ); @@ -166,10 +151,7 @@ private function listTweets( TwitterAuth $auth, $connection, array $input ): arr if ( 200 !== $http_code ) { $error_msg = $this->extractError( $response, 'Failed to fetch tweets' ); - return array( - 'success' => false, - 'error' => $error_msg, - ); + return new \WP_Error( 'api_error', $error_msg, array( 'status' => 500 ) ); } $response = (array) $response; @@ -189,7 +171,7 @@ private function listTweets( TwitterAuth $auth, $connection, array $input ): arr ); } - private function getTweet( $connection, string $tweet_id ): array { + private function getTweet( $connection, string $tweet_id ): array|\WP_Error { $params = array( 'tweet.fields' => self::TWEET_FIELDS, 'expansions' => 'author_id', @@ -201,10 +183,7 @@ private function getTweet( $connection, string $tweet_id ): array { if ( 200 !== $http_code ) { $error_msg = $this->extractError( $response, 'Failed to fetch tweet' ); - return array( - 'success' => false, - 'error' => $error_msg, - ); + return new \WP_Error( 'api_error', $error_msg, array( 'status' => 500 ) ); } $response = (array) $response; @@ -221,14 +200,11 @@ private function getTweet( $connection, string $tweet_id ): array { ); } - private function getMentions( TwitterAuth $auth, $connection, array $input ): array { + private function getMentions( TwitterAuth $auth, $connection, array $input ): array|\WP_Error { $account = $auth->get_account_details(); $user_id = $account['user_id'] ?? null; if ( empty( $user_id ) ) { - return array( - 'success' => false, - 'error' => 'Twitter user ID not available. Try re-authenticating.', - ); + return new \WP_Error( 'missing_auth', 'Twitter user ID not available. Try re-authenticating.', array( 'status' => 401 ) ); } $limit = min( absint( $input['limit'] ?? 25 ), 100 ); @@ -248,10 +224,7 @@ private function getMentions( TwitterAuth $auth, $connection, array $input ): ar if ( 200 !== $http_code ) { $error_msg = $this->extractError( $response, 'Failed to fetch mentions' ); - return array( - 'success' => false, - 'error' => $error_msg, - ); + return new \WP_Error( 'api_error', $error_msg, array( 'status' => 500 ) ); } $response = (array) $response; diff --git a/inc/Abilities/Twitter/TwitterUpdateAbility.php b/inc/Abilities/Twitter/TwitterUpdateAbility.php index e3bc5681a..3e4ea7d00 100644 --- a/inc/Abilities/Twitter/TwitterUpdateAbility.php +++ b/inc/Abilities/Twitter/TwitterUpdateAbility.php @@ -94,31 +94,22 @@ public function checkPermission(): bool { * @param array $input Input parameters. * @return array Result. */ - public function execute( array $input ): array { + public function execute( array $input ): array|\WP_Error { $action = $input['action'] ?? ''; // Get auth provider. $auth = $this->getAuthProvider(); if ( ! $auth ) { - return array( - 'success' => false, - 'error' => 'Twitter auth provider not available', - ); + return new \WP_Error( 'missing_auth', 'Twitter auth provider not available', array( 'status' => 401 ) ); } $connection = $auth->get_connection(); if ( ! $connection ) { - return array( - 'success' => false, - 'error' => 'Twitter connection not available', - ); + return new \WP_Error( 'missing_auth', 'Twitter connection not available', array( 'status' => 401 ) ); } if ( empty( $input['tweet_id'] ) ) { - return array( - 'success' => false, - 'error' => 'tweet_id is required', - ); + return new \WP_Error( 'missing_param', 'tweet_id is required', array( 'status' => 400 ) ); } $tweet_id = $input['tweet_id']; @@ -140,10 +131,7 @@ public function execute( array $input ): array { return $this->unlikeTweet( $connection, $tweet_id ); default: - return array( - 'success' => false, - 'error' => "Unknown action: {$action}. Use delete, retweet, unretweet, like, or unlike.", - ); + return new \WP_Error( 'api_error', "Unknown action: {$action}. Use delete, retweet, unretweet, like, or unlike.", array( 'status' => 500 ) ); } } @@ -174,7 +162,7 @@ private function getAuthProvider(): ?TwitterAuth { * @param string $tweet_id Tweet ID. * @return array Result. */ - private function deleteTweet( $connection, string $tweet_id ): array { + private function deleteTweet( $connection, string $tweet_id ): array|\WP_Error { // Set API v2. $connection->setApiVersion( '2' ); @@ -193,10 +181,7 @@ private function deleteTweet( $connection, string $tweet_id ): array { } $error = $result['detail'] ?? $result['title'] ?? 'Failed to delete tweet'; - return array( - 'success' => false, - 'error' => $error, - ); + return new \WP_Error( 'api_error', $error, array( 'status' => 500 ) ); } /** @@ -206,17 +191,14 @@ private function deleteTweet( $connection, string $tweet_id ): array { * @param string $tweet_id Tweet ID to retweet. * @return array Result. */ - private function retweet( $connection, string $tweet_id ): array { + private function retweet( $connection, string $tweet_id ): array|\WP_Error { // Need user ID for retweeting. $auth = $this->getAuthProvider(); $account = $auth->get_account_details(); $user_id = $account['user_id'] ?? null; if ( ! $user_id ) { - return array( - 'success' => false, - 'error' => 'User ID not available for retweet', - ); + return new \WP_Error( 'missing_auth', 'User ID not available for retweet', array( 'status' => 401 ) ); } $connection->setApiVersion( '2' ); @@ -239,10 +221,7 @@ private function retweet( $connection, string $tweet_id ): array { } $error = $result['detail'] ?? $result['title'] ?? 'Failed to retweet'; - return array( - 'success' => false, - 'error' => $error, - ); + return new \WP_Error( 'api_error', $error, array( 'status' => 500 ) ); } /** @@ -252,17 +231,14 @@ private function retweet( $connection, string $tweet_id ): array { * @param string $tweet_id Tweet ID to unretweet. * @return array Result. */ - private function unretweet( $connection, string $tweet_id ): array { + private function unretweet( $connection, string $tweet_id ): array|\WP_Error { // Need user ID for unretweeting. $auth = $this->getAuthProvider(); $account = $auth->get_account_details(); $user_id = $account['user_id'] ?? null; if ( ! $user_id ) { - return array( - 'success' => false, - 'error' => 'User ID not available for unretweet', - ); + return new \WP_Error( 'missing_auth', 'User ID not available for unretweet', array( 'status' => 401 ) ); } $connection->setApiVersion( '2' ); @@ -283,10 +259,7 @@ private function unretweet( $connection, string $tweet_id ): array { } $error = $result['detail'] ?? $result['title'] ?? 'Failed to unretweet'; - return array( - 'success' => false, - 'error' => $error, - ); + return new \WP_Error( 'api_error', $error, array( 'status' => 500 ) ); } /** @@ -296,17 +269,14 @@ private function unretweet( $connection, string $tweet_id ): array { * @param string $tweet_id Tweet ID to like. * @return array Result. */ - private function likeTweet( $connection, string $tweet_id ): array { + private function likeTweet( $connection, string $tweet_id ): array|\WP_Error { // Need user ID for liking. $auth = $this->getAuthProvider(); $account = $auth->get_account_details(); $user_id = $account['user_id'] ?? null; if ( ! $user_id ) { - return array( - 'success' => false, - 'error' => 'User ID not available for like', - ); + return new \WP_Error( 'missing_auth', 'User ID not available for like', array( 'status' => 401 ) ); } $connection->setApiVersion( '2' ); @@ -328,10 +298,7 @@ private function likeTweet( $connection, string $tweet_id ): array { } $error = $result['detail'] ?? $result['title'] ?? 'Failed to like tweet'; - return array( - 'success' => false, - 'error' => $error, - ); + return new \WP_Error( 'api_error', $error, array( 'status' => 500 ) ); } /** @@ -341,17 +308,14 @@ private function likeTweet( $connection, string $tweet_id ): array { * @param string $tweet_id Tweet ID to unlike. * @return array Result. */ - private function unlikeTweet( $connection, string $tweet_id ): array { + private function unlikeTweet( $connection, string $tweet_id ): array|\WP_Error { // Need user ID for unliking. $auth = $this->getAuthProvider(); $account = $auth->get_account_details(); $user_id = $account['user_id'] ?? null; if ( ! $user_id ) { - return array( - 'success' => false, - 'error' => 'User ID not available for unlike', - ); + return new \WP_Error( 'missing_auth', 'User ID not available for unlike', array( 'status' => 401 ) ); } $connection->setApiVersion( '2' ); @@ -371,9 +335,6 @@ private function unlikeTweet( $connection, string $tweet_id ): array { } $error = $result['detail'] ?? $result['title'] ?? 'Failed to unlike tweet'; - return array( - 'success' => false, - 'error' => $error, - ); + return new \WP_Error( 'api_error', $error, array( 'status' => 500 ) ); } } diff --git a/inc/Chat/Tools/DeleteBluesky.php b/inc/Chat/Tools/DeleteBluesky.php index c77cfa28e..57589c729 100644 --- a/inc/Chat/Tools/DeleteBluesky.php +++ b/inc/Chat/Tools/DeleteBluesky.php @@ -55,19 +55,19 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) ); } - $ability = function_exists( 'wp_get_ability' ) ? wp_get_ability( 'datamachine/bluesky-delete' ) : null; + $ability = wp_get_ability( 'datamachine/bluesky-delete' ); if ( ! $ability ) { return $this->buildErrorResponse( 'datamachine/bluesky-delete ability not registered', $tool_name ); } $result = $ability->execute( array( 'post_uri' => $parameters['post_uri'] ) ); - if ( $result['success'] ) { + if ( ! is_wp_error( $result ) && $result['success'] ) { return array( 'result' => 'Post deleted!', 'post_uri' => $parameters['post_uri'], ); } - return $this->buildErrorResponse( $result['error'] ?? 'Delete failed', $tool_name ); + return $this->buildErrorResponse( is_wp_error( $result ) ? $result->get_error_message() : ( $result['error'] ?? 'Delete failed' ), $tool_name ); } } diff --git a/inc/Chat/Tools/DeleteFacebook.php b/inc/Chat/Tools/DeleteFacebook.php index 7c35aab87..6a3f32448 100644 --- a/inc/Chat/Tools/DeleteFacebook.php +++ b/inc/Chat/Tools/DeleteFacebook.php @@ -55,19 +55,19 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) ); } - $ability = function_exists( 'wp_get_ability' ) ? wp_get_ability( 'datamachine/facebook-delete' ) : null; + $ability = wp_get_ability( 'datamachine/facebook-delete' ); if ( ! $ability ) { return $this->buildErrorResponse( 'datamachine/facebook-delete ability not registered', $tool_name ); } $result = $ability->execute( array( 'post_id' => $parameters['post_id'] ) ); - if ( $result['success'] ) { + if ( ! is_wp_error( $result ) && $result['success'] ) { return array( 'result' => 'Post deleted!', 'post_id' => $parameters['post_id'], ); } - return $this->buildErrorResponse( $result['error'] ?? 'Delete failed', $tool_name ); + return $this->buildErrorResponse( is_wp_error( $result ) ? $result->get_error_message() : ( $result['error'] ?? 'Delete failed' ), $tool_name ); } } diff --git a/inc/Chat/Tools/DeleteInstagram.php b/inc/Chat/Tools/DeleteInstagram.php index b93bc6394..76264706a 100644 --- a/inc/Chat/Tools/DeleteInstagram.php +++ b/inc/Chat/Tools/DeleteInstagram.php @@ -55,19 +55,19 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) ); } - $ability = function_exists( 'wp_get_ability' ) ? wp_get_ability( 'datamachine/instagram-delete' ) : null; + $ability = wp_get_ability( 'datamachine/instagram-delete' ); if ( ! $ability ) { return $this->buildErrorResponse( 'datamachine/instagram-delete ability not registered', $tool_name ); } $result = $ability->execute( array( 'media_id' => $parameters['media_id'] ) ); - if ( $result['success'] ) { + if ( ! is_wp_error( $result ) && $result['success'] ) { return array( 'result' => 'Post deleted!', 'media_id' => $parameters['media_id'], ); } - return $this->buildErrorResponse( $result['error'] ?? 'Delete failed', $tool_name ); + return $this->buildErrorResponse( is_wp_error( $result ) ? $result->get_error_message() : ( $result['error'] ?? 'Delete failed' ), $tool_name ); } } diff --git a/inc/Chat/Tools/DeleteLinkedIn.php b/inc/Chat/Tools/DeleteLinkedIn.php index 02344c7a3..02e76d59a 100644 --- a/inc/Chat/Tools/DeleteLinkedIn.php +++ b/inc/Chat/Tools/DeleteLinkedIn.php @@ -88,8 +88,8 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) 'post_id' => sanitize_text_field( $parameters['post_id'] ), ) ); - if ( ! $this->isAbilitySuccess( $result ) ) { - return $this->buildErrorResponse( $this->getAbilityError( $result, 'Failed to delete LinkedIn post' ), $tool_name ); + if ( is_wp_error( $result ) || ! $this->isAbilitySuccess( $result ) ) { + return $this->buildErrorResponse( is_wp_error( $result ) ? $result->get_error_message() : $this->getAbilityError( $result, 'Failed to delete LinkedIn post' ), $tool_name ); } return array( diff --git a/inc/Chat/Tools/DeletePinterest.php b/inc/Chat/Tools/DeletePinterest.php index 4d6eebabf..17f91d297 100644 --- a/inc/Chat/Tools/DeletePinterest.php +++ b/inc/Chat/Tools/DeletePinterest.php @@ -55,19 +55,19 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) ); } - $ability = function_exists( 'wp_get_ability' ) ? wp_get_ability( 'datamachine/pinterest-delete' ) : null; + $ability = wp_get_ability( 'datamachine/pinterest-delete' ); if ( ! $ability ) { return $this->buildErrorResponse( 'datamachine/pinterest-delete ability not registered', $tool_name ); } $result = $ability->execute( array( 'pin_id' => $parameters['pin_id'] ) ); - if ( $result['success'] ) { + if ( ! is_wp_error( $result ) && $result['success'] ) { return array( 'result' => 'Pin deleted!', 'pin_id' => $parameters['pin_id'], ); } - return $this->buildErrorResponse( $result['error'] ?? 'Delete failed', $tool_name ); + return $this->buildErrorResponse( is_wp_error( $result ) ? $result->get_error_message() : ( $result['error'] ?? 'Delete failed' ), $tool_name ); } } diff --git a/inc/Chat/Tools/DeleteThreads.php b/inc/Chat/Tools/DeleteThreads.php index 877211077..505742b8d 100644 --- a/inc/Chat/Tools/DeleteThreads.php +++ b/inc/Chat/Tools/DeleteThreads.php @@ -55,19 +55,19 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) ); } - $ability = function_exists( 'wp_get_ability' ) ? wp_get_ability( 'datamachine/threads-delete' ) : null; + $ability = wp_get_ability( 'datamachine/threads-delete' ); if ( ! $ability ) { return $this->buildErrorResponse( 'datamachine/threads-delete ability not registered', $tool_name ); } $result = $ability->execute( array( 'thread_id' => $parameters['thread_id'] ) ); - if ( $result['success'] ) { + if ( ! is_wp_error( $result ) && $result['success'] ) { return array( 'result' => 'Thread deleted!', 'thread_id' => $parameters['thread_id'], ); } - return $this->buildErrorResponse( $result['error'] ?? 'Delete failed', $tool_name ); + return $this->buildErrorResponse( is_wp_error( $result ) ? $result->get_error_message() : ( $result['error'] ?? 'Delete failed' ), $tool_name ); } } diff --git a/inc/Chat/Tools/DeleteTwitter.php b/inc/Chat/Tools/DeleteTwitter.php index 45468963b..0073a1b34 100644 --- a/inc/Chat/Tools/DeleteTwitter.php +++ b/inc/Chat/Tools/DeleteTwitter.php @@ -55,19 +55,19 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) ); } - $ability = function_exists( 'wp_get_ability' ) ? wp_get_ability( 'datamachine/twitter-delete' ) : null; + $ability = wp_get_ability( 'datamachine/twitter-delete' ); if ( ! $ability ) { return $this->buildErrorResponse( 'datamachine/twitter-delete ability not registered', $tool_name ); } $result = $ability->execute( array( 'tweet_id' => $parameters['tweet_id'] ) ); - if ( $result['success'] ) { + if ( ! is_wp_error( $result ) && $result['success'] ) { return array( 'result' => 'Tweet deleted!', 'tweet_id' => $parameters['tweet_id'], ); } - return $this->buildErrorResponse( $result['error'] ?? 'Delete failed', $tool_name ); + return $this->buildErrorResponse( is_wp_error( $result ) ? $result->get_error_message() : ( $result['error'] ?? 'Delete failed' ), $tool_name ); } } diff --git a/inc/Chat/Tools/FetchReddit.php b/inc/Chat/Tools/FetchReddit.php index a618cf84e..ec538a66b 100644 --- a/inc/Chat/Tools/FetchReddit.php +++ b/inc/Chat/Tools/FetchReddit.php @@ -150,10 +150,6 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) } // Get the ability. - if ( ! function_exists( 'wp_get_ability' ) ) { - return $this->buildErrorResponse( 'WordPress Abilities API not available', $tool_name ); - } - $ability = wp_get_ability( 'datamachine/fetch-reddit' ); if ( ! $ability ) { return $this->buildErrorResponse( 'datamachine/fetch-reddit ability not registered', $tool_name ); @@ -182,8 +178,8 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) $result = $ability->execute( $input ); - if ( ! $this->isAbilitySuccess( $result ) ) { - $error = $this->getAbilityError( $result, 'Failed to fetch from Reddit' ); + if ( is_wp_error( $result ) || ! $this->isAbilitySuccess( $result ) ) { + $error = is_wp_error( $result ) ? $result->get_error_message() : $this->getAbilityError( $result, 'Failed to fetch from Reddit' ); return $this->buildErrorResponse( $error, $tool_name ); } diff --git a/inc/Chat/Tools/PublishBluesky.php b/inc/Chat/Tools/PublishBluesky.php index f881dea74..10ccd0514 100644 --- a/inc/Chat/Tools/PublishBluesky.php +++ b/inc/Chat/Tools/PublishBluesky.php @@ -130,7 +130,7 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) // Execute via the publish ability. $result = \DataMachineSocials\Abilities\Bluesky\BlueskyPublishAbility::execute_publish( $input ); - if ( $result['success'] ) { + if ( ! is_wp_error( $result ) && $result['success'] ) { return array( 'result' => 'Post published to Bluesky!', 'post_id' => $result['post_id'] ?? '', @@ -138,6 +138,6 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) ); } - return $this->buildErrorResponse( $result['error'] ?? 'Bluesky publish failed', $tool_name ); + return $this->buildErrorResponse( is_wp_error( $result ) ? $result->get_error_message() : ( $result['error'] ?? 'Bluesky publish failed' ), $tool_name ); } } diff --git a/inc/Chat/Tools/PublishFacebook.php b/inc/Chat/Tools/PublishFacebook.php index a3de9f19a..ec7e4ece9 100644 --- a/inc/Chat/Tools/PublishFacebook.php +++ b/inc/Chat/Tools/PublishFacebook.php @@ -139,7 +139,7 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) // Execute via the publish ability. $result = \DataMachineSocials\Abilities\Facebook\FacebookPublishAbility::execute_publish( $input ); - if ( $result['success'] ) { + if ( ! is_wp_error( $result ) && $result['success'] ) { $response = array( 'result' => 'Post published to Facebook!', 'post_id' => $result['post_id'] ?? '', @@ -154,6 +154,6 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) return $response; } - return $this->buildErrorResponse( $result['error'] ?? 'Facebook publish failed', $tool_name ); + return $this->buildErrorResponse( is_wp_error( $result ) ? $result->get_error_message() : ( $result['error'] ?? 'Facebook publish failed' ), $tool_name ); } } diff --git a/inc/Chat/Tools/PublishInstagram.php b/inc/Chat/Tools/PublishInstagram.php index b6d330e5f..0b9e8b828 100644 --- a/inc/Chat/Tools/PublishInstagram.php +++ b/inc/Chat/Tools/PublishInstagram.php @@ -136,7 +136,7 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) // Execute via the publish ability. $result = \DataMachineSocials\Abilities\Instagram\InstagramPublishAbility::execute_publish( $input ); - if ( $result['success'] ) { + if ( ! is_wp_error( $result ) && $result['success'] ) { return array( 'result' => 'Post published to Instagram!', 'media_id' => $result['media_id'] ?? '', @@ -145,6 +145,6 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) ); } - return $this->buildErrorResponse( $result['error'] ?? 'Instagram publish failed', $tool_name ); + return $this->buildErrorResponse( is_wp_error( $result ) ? $result->get_error_message() : ( $result['error'] ?? 'Instagram publish failed' ), $tool_name ); } } diff --git a/inc/Chat/Tools/PublishLinkedIn.php b/inc/Chat/Tools/PublishLinkedIn.php index 252b5f15c..492c83120 100644 --- a/inc/Chat/Tools/PublishLinkedIn.php +++ b/inc/Chat/Tools/PublishLinkedIn.php @@ -130,7 +130,7 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) // Execute via the publish ability. $result = \DataMachineSocials\Abilities\LinkedIn\LinkedInPublishAbility::execute_publish( $input ); - if ( $result['success'] ) { + if ( ! is_wp_error( $result ) && $result['success'] ) { return array( 'result' => 'Post published to LinkedIn!', 'post_id' => $result['post_id'] ?? '', @@ -138,6 +138,6 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) ); } - return $this->buildErrorResponse( $result['error'] ?? 'LinkedIn publish failed', $tool_name ); + return $this->buildErrorResponse( is_wp_error( $result ) ? $result->get_error_message() : ( $result['error'] ?? 'LinkedIn publish failed' ), $tool_name ); } } diff --git a/inc/Chat/Tools/PublishPinterest.php b/inc/Chat/Tools/PublishPinterest.php index 197830c88..376f7bbc6 100644 --- a/inc/Chat/Tools/PublishPinterest.php +++ b/inc/Chat/Tools/PublishPinterest.php @@ -141,7 +141,7 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) // Execute via the publish ability. $result = \DataMachineSocials\Abilities\Pinterest\PinterestPublishAbility::execute_publish( $input ); - if ( $result['success'] ) { + if ( ! is_wp_error( $result ) && $result['success'] ) { return array( 'result' => 'Pin published to Pinterest!', 'pin_id' => $result['pin_id'] ?? '', @@ -149,6 +149,6 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) ); } - return $this->buildErrorResponse( $result['error'] ?? 'Pinterest publish failed', $tool_name ); + return $this->buildErrorResponse( is_wp_error( $result ) ? $result->get_error_message() : ( $result['error'] ?? 'Pinterest publish failed' ), $tool_name ); } } diff --git a/inc/Chat/Tools/PublishReelInstagram.php b/inc/Chat/Tools/PublishReelInstagram.php index 2dc40f42d..9efdf3143 100644 --- a/inc/Chat/Tools/PublishReelInstagram.php +++ b/inc/Chat/Tools/PublishReelInstagram.php @@ -143,7 +143,7 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) // Execute via the publish ability. $result = \DataMachineSocials\Abilities\Instagram\InstagramPublishAbility::execute_publish( $input ); - if ( $result['success'] ) { + if ( ! is_wp_error( $result ) && $result['success'] ) { return array( 'result' => 'Reel published to Instagram!', 'media_id' => $result['media_id'] ?? '', @@ -152,6 +152,6 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) ); } - return $this->buildErrorResponse( $result['error'] ?? 'Reel publish failed', $tool_name ); + return $this->buildErrorResponse( is_wp_error( $result ) ? $result->get_error_message() : ( $result['error'] ?? 'Reel publish failed' ), $tool_name ); } } diff --git a/inc/Chat/Tools/PublishStoryInstagram.php b/inc/Chat/Tools/PublishStoryInstagram.php index 92c296bb5..aa81f3708 100644 --- a/inc/Chat/Tools/PublishStoryInstagram.php +++ b/inc/Chat/Tools/PublishStoryInstagram.php @@ -120,7 +120,7 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) // Execute via the publish ability. $result = \DataMachineSocials\Abilities\Instagram\InstagramPublishAbility::execute_publish( $input ); - if ( $result['success'] ) { + if ( ! is_wp_error( $result ) && $result['success'] ) { return array( 'result' => 'Story published to Instagram! (visible for 24 hours)', 'media_id' => $result['media_id'] ?? '', @@ -129,6 +129,6 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) ); } - return $this->buildErrorResponse( $result['error'] ?? 'Story publish failed', $tool_name ); + return $this->buildErrorResponse( is_wp_error( $result ) ? $result->get_error_message() : ( $result['error'] ?? 'Story publish failed' ), $tool_name ); } } diff --git a/inc/Chat/Tools/PublishThreads.php b/inc/Chat/Tools/PublishThreads.php index 30387c44a..14030a0ae 100644 --- a/inc/Chat/Tools/PublishThreads.php +++ b/inc/Chat/Tools/PublishThreads.php @@ -121,7 +121,7 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) // Execute via the publish ability. $result = \DataMachineSocials\Abilities\Threads\ThreadsPublishAbility::execute_publish( $input ); - if ( $result['success'] ) { + if ( ! is_wp_error( $result ) && $result['success'] ) { return array( 'result' => 'Post published to Threads!', 'post_id' => $result['post_id'] ?? '', @@ -129,6 +129,6 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) ); } - return $this->buildErrorResponse( $result['error'] ?? 'Threads publish failed', $tool_name ); + return $this->buildErrorResponse( is_wp_error( $result ) ? $result->get_error_message() : ( $result['error'] ?? 'Threads publish failed' ), $tool_name ); } } diff --git a/inc/Chat/Tools/PublishTwitter.php b/inc/Chat/Tools/PublishTwitter.php index 6753a700d..c1222827a 100644 --- a/inc/Chat/Tools/PublishTwitter.php +++ b/inc/Chat/Tools/PublishTwitter.php @@ -121,7 +121,7 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) // Execute via the publish ability. $result = \DataMachineSocials\Abilities\Twitter\TwitterPublishAbility::execute_publish( $input ); - if ( $result['success'] ) { + if ( ! is_wp_error( $result ) && $result['success'] ) { $response = array( 'result' => 'Tweet published to Twitter!', 'tweet_id' => $result['tweet_id'] ?? '', @@ -136,6 +136,6 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) return $response; } - return $this->buildErrorResponse( $result['error'] ?? 'Twitter publish failed', $tool_name ); + return $this->buildErrorResponse( is_wp_error( $result ) ? $result->get_error_message() : ( $result['error'] ?? 'Twitter publish failed' ), $tool_name ); } } diff --git a/inc/Chat/Tools/ReadBluesky.php b/inc/Chat/Tools/ReadBluesky.php index 97b5c4679..88cca1785 100644 --- a/inc/Chat/Tools/ReadBluesky.php +++ b/inc/Chat/Tools/ReadBluesky.php @@ -96,6 +96,10 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) ); } + $ability = wp_get_ability( 'datamachine/bluesky-read' ); + if ( ! $ability ) { + return $this->buildErrorResponse( 'datamachine/bluesky-read ability not registered', $tool_name ); + } $ability_instance = $ability; $input = array( 'action' => sanitize_text_field( $action ) ); @@ -111,8 +115,8 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) $result = $ability_instance->execute( $input ); - if ( ! $this->isAbilitySuccess( $result ) ) { - return $this->buildErrorResponse( $this->getAbilityError( $result, 'Failed to read from Bluesky' ), $tool_name ); + if ( is_wp_error( $result ) || ! $this->isAbilitySuccess( $result ) ) { + return $this->buildErrorResponse( is_wp_error( $result ) ? $result->get_error_message() : $this->getAbilityError( $result, 'Failed to read from Bluesky' ), $tool_name ); } return array( diff --git a/inc/Chat/Tools/ReadFacebook.php b/inc/Chat/Tools/ReadFacebook.php index d5734ed5b..d6076e8a1 100644 --- a/inc/Chat/Tools/ReadFacebook.php +++ b/inc/Chat/Tools/ReadFacebook.php @@ -96,6 +96,10 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) ); } + $ability = wp_get_ability( 'datamachine/facebook-read' ); + if ( ! $ability ) { + return $this->buildErrorResponse( 'datamachine/facebook-read ability not registered', $tool_name ); + } $ability_instance = $ability; $input = array( 'action' => sanitize_text_field( $action ) ); @@ -111,8 +115,8 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) $result = $ability_instance->execute( $input ); - if ( ! $this->isAbilitySuccess( $result ) ) { - return $this->buildErrorResponse( $this->getAbilityError( $result, 'Failed to read from Facebook' ), $tool_name ); + if ( is_wp_error( $result ) || ! $this->isAbilitySuccess( $result ) ) { + return $this->buildErrorResponse( is_wp_error( $result ) ? $result->get_error_message() : $this->getAbilityError( $result, 'Failed to read from Facebook' ), $tool_name ); } return array( diff --git a/inc/Chat/Tools/ReadInstagram.php b/inc/Chat/Tools/ReadInstagram.php index 4c0a9a95b..9784eca9d 100644 --- a/inc/Chat/Tools/ReadInstagram.php +++ b/inc/Chat/Tools/ReadInstagram.php @@ -114,10 +114,6 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) } // Get the ability. - if ( ! function_exists( 'wp_get_ability' ) ) { - return $this->buildErrorResponse( 'WordPress Abilities API not available', $tool_name ); - } - $ability = wp_get_ability( 'datamachine/instagram-read' ); if ( ! $ability ) { return $this->buildErrorResponse( 'datamachine/instagram-read ability not registered', $tool_name ); @@ -141,11 +137,15 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) } // Execute via ability (which handles token retrieval internally). + $ability = wp_get_ability( 'datamachine/instagram-read' ); + if ( ! $ability ) { + return $this->buildErrorResponse( 'datamachine/instagram-read ability not registered', $tool_name ); + } $ability_instance = $ability; $result = $ability_instance->execute( $input ); - if ( ! $this->isAbilitySuccess( $result ) ) { - $error = $this->getAbilityError( $result, 'Failed to read from Instagram' ); + if ( is_wp_error( $result ) || ! $this->isAbilitySuccess( $result ) ) { + $error = is_wp_error( $result ) ? $result->get_error_message() : $this->getAbilityError( $result, 'Failed to read from Instagram' ); return $this->buildErrorResponse( $error, $tool_name ); } diff --git a/inc/Chat/Tools/ReadLinkedIn.php b/inc/Chat/Tools/ReadLinkedIn.php index d0b0e9d26..b0acfdef3 100644 --- a/inc/Chat/Tools/ReadLinkedIn.php +++ b/inc/Chat/Tools/ReadLinkedIn.php @@ -107,8 +107,8 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) $result = $ability->execute( $input ); - if ( ! $this->isAbilitySuccess( $result ) ) { - return $this->buildErrorResponse( $this->getAbilityError( $result, 'Failed to read from LinkedIn' ), $tool_name ); + if ( is_wp_error( $result ) || ! $this->isAbilitySuccess( $result ) ) { + return $this->buildErrorResponse( is_wp_error( $result ) ? $result->get_error_message() : $this->getAbilityError( $result, 'Failed to read from LinkedIn' ), $tool_name ); } return array( diff --git a/inc/Chat/Tools/ReadPinterest.php b/inc/Chat/Tools/ReadPinterest.php index c5b019e6c..ba3982940 100644 --- a/inc/Chat/Tools/ReadPinterest.php +++ b/inc/Chat/Tools/ReadPinterest.php @@ -104,6 +104,10 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) ); } + $ability = wp_get_ability( 'datamachine/pinterest-read' ); + if ( ! $ability ) { + return $this->buildErrorResponse( 'datamachine/pinterest-read ability not registered', $tool_name ); + } $ability_instance = $ability; $input = array( 'action' => sanitize_text_field( $action ) ); @@ -122,8 +126,8 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) $result = $ability_instance->execute( $input ); - if ( ! $this->isAbilitySuccess( $result ) ) { - return $this->buildErrorResponse( $this->getAbilityError( $result, 'Failed to read from Pinterest' ), $tool_name ); + if ( is_wp_error( $result ) || ! $this->isAbilitySuccess( $result ) ) { + return $this->buildErrorResponse( is_wp_error( $result ) ? $result->get_error_message() : $this->getAbilityError( $result, 'Failed to read from Pinterest' ), $tool_name ); } return array( diff --git a/inc/Chat/Tools/ReadThreads.php b/inc/Chat/Tools/ReadThreads.php index fe9fcac06..150eac997 100644 --- a/inc/Chat/Tools/ReadThreads.php +++ b/inc/Chat/Tools/ReadThreads.php @@ -96,6 +96,10 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) ); } + $ability = wp_get_ability( 'datamachine/threads-read' ); + if ( ! $ability ) { + return $this->buildErrorResponse( 'datamachine/threads-read ability not registered', $tool_name ); + } $ability_instance = $ability; $input = array( 'action' => sanitize_text_field( $action ) ); @@ -111,8 +115,8 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) $result = $ability_instance->execute( $input ); - if ( ! $this->isAbilitySuccess( $result ) ) { - return $this->buildErrorResponse( $this->getAbilityError( $result, 'Failed to read from Threads' ), $tool_name ); + if ( is_wp_error( $result ) || ! $this->isAbilitySuccess( $result ) ) { + return $this->buildErrorResponse( is_wp_error( $result ) ? $result->get_error_message() : $this->getAbilityError( $result, 'Failed to read from Threads' ), $tool_name ); } return array( diff --git a/inc/Chat/Tools/ReadTwitter.php b/inc/Chat/Tools/ReadTwitter.php index a11b33944..e49e9f082 100644 --- a/inc/Chat/Tools/ReadTwitter.php +++ b/inc/Chat/Tools/ReadTwitter.php @@ -96,6 +96,10 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) ); } + $ability = wp_get_ability( 'datamachine/twitter-read' ); + if ( ! $ability ) { + return $this->buildErrorResponse( 'datamachine/twitter-read ability not registered', $tool_name ); + } $ability_instance = $ability; $input = array( 'action' => sanitize_text_field( $action ) ); @@ -111,8 +115,8 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) $result = $ability_instance->execute( $input ); - if ( ! $this->isAbilitySuccess( $result ) ) { - return $this->buildErrorResponse( $this->getAbilityError( $result, 'Failed to read from Twitter' ), $tool_name ); + if ( is_wp_error( $result ) || ! $this->isAbilitySuccess( $result ) ) { + return $this->buildErrorResponse( is_wp_error( $result ) ? $result->get_error_message() : $this->getAbilityError( $result, 'Failed to read from Twitter' ), $tool_name ); } return array( diff --git a/inc/Chat/Tools/ReplyInstagramComment.php b/inc/Chat/Tools/ReplyInstagramComment.php index 7e66c90b7..81a4c5aaa 100644 --- a/inc/Chat/Tools/ReplyInstagramComment.php +++ b/inc/Chat/Tools/ReplyInstagramComment.php @@ -91,15 +91,15 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) ); } - if ( ! function_exists( 'wp_get_ability' ) ) { - return $this->buildErrorResponse( 'WordPress Abilities API not available', $tool_name ); + $ability = wp_get_ability( 'datamachine/instagram-comment-reply' ); + if ( ! $ability ) { + return $this->buildErrorResponse( 'datamachine/instagram-comment-reply ability not registered', $tool_name ); } $ability = wp_get_ability( 'datamachine/instagram-comment-reply' ); if ( ! $ability ) { return $this->buildErrorResponse( 'datamachine/instagram-comment-reply ability not registered', $tool_name ); } - $ability_instance = $ability; $result = $ability_instance->execute( array( @@ -108,7 +108,7 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) ) ); - if ( ! empty( $result['success'] ) ) { + if ( ! is_wp_error( $result ) && ! empty( $result['success'] ) ) { return array( 'result' => 'Instagram comment reply posted successfully!', 'comment_id' => $result['data']['comment_id'] ?? $parameters['comment_id'], @@ -117,6 +117,6 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) ); } - return $this->buildErrorResponse( $result['error'] ?? 'Failed to reply to Instagram comment', $tool_name ); + return $this->buildErrorResponse( is_wp_error( $result ) ? $result->get_error_message() : ( $result['error'] ?? 'Failed to reply to Instagram comment' ), $tool_name ); } } diff --git a/inc/Chat/Tools/ReplyReddit.php b/inc/Chat/Tools/ReplyReddit.php index 46a48bb80..a72c4bd97 100644 --- a/inc/Chat/Tools/ReplyReddit.php +++ b/inc/Chat/Tools/ReplyReddit.php @@ -94,10 +94,6 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) ); } - if ( ! function_exists( 'wp_get_ability' ) ) { - return $this->buildErrorResponse( 'WordPress Abilities API not available', $tool_name ); - } - $ability = wp_get_ability( 'datamachine/reply-reddit' ); if ( ! $ability ) { return $this->buildErrorResponse( 'datamachine/reply-reddit ability not registered', $tool_name ); @@ -109,7 +105,7 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) 'access_token' => $access_token, ) ); - if ( ! empty( $result['success'] ) ) { + if ( ! is_wp_error( $result ) && ! empty( $result['success'] ) ) { return array( 'result' => 'Reddit reply posted successfully!', 'comment_id' => $result['data']['comment_id'] ?? '', @@ -119,6 +115,6 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) ); } - return $this->buildErrorResponse( $result['error'] ?? 'Failed to reply on Reddit', $tool_name ); + return $this->buildErrorResponse( is_wp_error( $result ) ? $result->get_error_message() : ( $result['error'] ?? 'Failed to reply on Reddit' ), $tool_name ); } } diff --git a/inc/Chat/Tools/SubmitReddit.php b/inc/Chat/Tools/SubmitReddit.php index ae3deaffa..932aa0606 100644 --- a/inc/Chat/Tools/SubmitReddit.php +++ b/inc/Chat/Tools/SubmitReddit.php @@ -114,10 +114,6 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) ); } - if ( ! function_exists( 'wp_get_ability' ) ) { - return $this->buildErrorResponse( 'WordPress Abilities API not available', $tool_name ); - } - $ability = wp_get_ability( 'datamachine/submit-reddit' ); if ( ! $ability ) { return $this->buildErrorResponse( 'datamachine/submit-reddit ability not registered', $tool_name ); @@ -133,7 +129,7 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) 'access_token' => $access_token, ) ); - if ( ! empty( $result['success'] ) ) { + if ( ! is_wp_error( $result ) && ! empty( $result['success'] ) ) { return array( 'result' => 'Reddit post submitted successfully!', 'post_url' => $result['data']['post_url'] ?? '', @@ -142,6 +138,6 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) ); } - return $this->buildErrorResponse( $result['error'] ?? 'Failed to submit Reddit post', $tool_name ); + return $this->buildErrorResponse( is_wp_error( $result ) ? $result->get_error_message() : ( $result['error'] ?? 'Failed to submit Reddit post' ), $tool_name ); } } diff --git a/inc/Chat/Tools/UpdateBluesky.php b/inc/Chat/Tools/UpdateBluesky.php index 397d944dd..6476c1357 100644 --- a/inc/Chat/Tools/UpdateBluesky.php +++ b/inc/Chat/Tools/UpdateBluesky.php @@ -83,13 +83,17 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) ); } + $ability = wp_get_ability( 'datamachine/bluesky-update' ); + if ( ! $ability ) { + return $this->buildErrorResponse( 'datamachine/bluesky-update ability not registered', $tool_name ); + } $ability_instance = $ability; $result = $ability_instance->execute( array( 'action' => sanitize_text_field( $parameters['action'] ), 'post_uri' => sanitize_text_field( $parameters['post_uri'] ), ) ); - if ( $result['success'] ) { + if ( ! is_wp_error( $result ) && $result['success'] ) { $action = $parameters['action']; $msg = 'delete' === $action ? 'Post deleted!' : 'Post liked!'; return array( @@ -98,6 +102,6 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) ); } - return $this->buildErrorResponse( $result['error'] ?? 'Update failed', $tool_name ); + return $this->buildErrorResponse( is_wp_error( $result ) ? $result->get_error_message() : ( $result['error'] ?? 'Update failed' ), $tool_name ); } } diff --git a/inc/Chat/Tools/UpdateFacebook.php b/inc/Chat/Tools/UpdateFacebook.php index 09ed9c597..ec300ac02 100644 --- a/inc/Chat/Tools/UpdateFacebook.php +++ b/inc/Chat/Tools/UpdateFacebook.php @@ -97,15 +97,15 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) } // Get the ability. - if ( ! function_exists( 'wp_get_ability' ) ) { - return $this->buildErrorResponse( 'WordPress Abilities API not available', $tool_name ); + $ability = wp_get_ability( 'datamachine/facebook-update' ); + if ( ! $ability ) { + return $this->buildErrorResponse( 'datamachine/facebook-update ability not registered', $tool_name ); } $ability = wp_get_ability( 'datamachine/facebook-update' ); if ( ! $ability ) { return $this->buildErrorResponse( 'datamachine/facebook-update ability not registered', $tool_name ); } - $ability_instance = $ability; $result = $ability_instance->execute( array( 'action' => sanitize_text_field( $action ), @@ -113,7 +113,7 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) 'message' => sanitize_text_field( $parameters['message'] ?? '' ), ) ); - if ( $result['success'] ) { + if ( ! is_wp_error( $result ) && $result['success'] ) { $message = ''; switch ( $action ) { case 'edit': @@ -137,6 +137,6 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) ); } - return $this->buildErrorResponse( $result['error'] ?? 'Update failed', $tool_name ); + return $this->buildErrorResponse( is_wp_error( $result ) ? $result->get_error_message() : ( $result['error'] ?? 'Update failed' ), $tool_name ); } } diff --git a/inc/Chat/Tools/UpdateInstagram.php b/inc/Chat/Tools/UpdateInstagram.php index a6fdbefa6..dd8689b57 100644 --- a/inc/Chat/Tools/UpdateInstagram.php +++ b/inc/Chat/Tools/UpdateInstagram.php @@ -113,10 +113,6 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) } // Get the ability. - if ( ! function_exists( 'wp_get_ability' ) ) { - return $this->buildErrorResponse( 'WordPress Abilities API not available', $tool_name ); - } - $ability = wp_get_ability( 'datamachine/instagram-update' ); if ( ! $ability ) { return $this->buildErrorResponse( 'datamachine/instagram-update ability not registered', $tool_name ); @@ -133,11 +129,15 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) } // Execute via ability (which handles token retrieval internally). + $ability = wp_get_ability( 'datamachine/instagram-update' ); + if ( ! $ability ) { + return $this->buildErrorResponse( 'datamachine/instagram-update ability not registered', $tool_name ); + } $ability_instance = $ability; $result = $ability_instance->execute( $input ); // Format response for AI. - if ( $result['success'] ) { + if ( ! is_wp_error( $result ) && $result['success'] ) { $message = ''; switch ( $action ) { case 'edit': @@ -158,6 +158,6 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) ); } - return $this->buildErrorResponse( $result['error'] ?? 'Update failed', $tool_name ); + return $this->buildErrorResponse( is_wp_error( $result ) ? $result->get_error_message() : ( $result['error'] ?? 'Update failed' ), $tool_name ); } } diff --git a/inc/Chat/Tools/UpdateLinkedIn.php b/inc/Chat/Tools/UpdateLinkedIn.php index dfaa48d47..e6d9bb599 100644 --- a/inc/Chat/Tools/UpdateLinkedIn.php +++ b/inc/Chat/Tools/UpdateLinkedIn.php @@ -98,8 +98,8 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) 'commentary' => sanitize_textarea_field( $parameters['commentary'] ), ) ); - if ( ! $this->isAbilitySuccess( $result ) ) { - return $this->buildErrorResponse( $this->getAbilityError( $result, 'Failed to update LinkedIn post' ), $tool_name ); + if ( is_wp_error( $result ) || ! $this->isAbilitySuccess( $result ) ) { + return $this->buildErrorResponse( is_wp_error( $result ) ? $result->get_error_message() : $this->getAbilityError( $result, 'Failed to update LinkedIn post' ), $tool_name ); } return array( diff --git a/inc/Chat/Tools/UpdatePinterest.php b/inc/Chat/Tools/UpdatePinterest.php index 101720a5b..78a97b9cb 100644 --- a/inc/Chat/Tools/UpdatePinterest.php +++ b/inc/Chat/Tools/UpdatePinterest.php @@ -67,19 +67,23 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) ); } + $ability = wp_get_ability( 'datamachine/pinterest-update' ); + if ( ! $ability ) { + return $this->buildErrorResponse( 'datamachine/pinterest-update ability not registered', $tool_name ); + } $ability_instance = $ability; $result = $ability_instance->execute( array( 'action' => sanitize_text_field( $parameters['action'] ), 'pin_id' => sanitize_text_field( $parameters['pin_id'] ), ) ); - if ( $result['success'] ) { + if ( ! is_wp_error( $result ) && $result['success'] ) { return array( 'result' => 'Pin deleted successfully!', 'pin_id' => $result['data']['pin_id'], ); } - return $this->buildErrorResponse( $result['error'] ?? 'Delete failed', $tool_name ); + return $this->buildErrorResponse( is_wp_error( $result ) ? $result->get_error_message() : ( $result['error'] ?? 'Delete failed' ), $tool_name ); } } diff --git a/inc/Chat/Tools/UpdateThreads.php b/inc/Chat/Tools/UpdateThreads.php index d6f942f53..e1fb6943d 100644 --- a/inc/Chat/Tools/UpdateThreads.php +++ b/inc/Chat/Tools/UpdateThreads.php @@ -83,19 +83,23 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) ); } + $ability = wp_get_ability( 'datamachine/threads-update' ); + if ( ! $ability ) { + return $this->buildErrorResponse( 'datamachine/threads-update ability not registered', $tool_name ); + } $ability_instance = $ability; $result = $ability_instance->execute( array( 'action' => sanitize_text_field( $parameters['action'] ), 'thread_id' => sanitize_text_field( $parameters['thread_id'] ), ) ); - if ( $result['success'] ) { + if ( ! is_wp_error( $result ) && $result['success'] ) { return array( 'result' => 'Thread deleted successfully!', 'thread_id' => $result['data']['thread_id'], ); } - return $this->buildErrorResponse( $result['error'] ?? 'Delete failed', $tool_name ); + return $this->buildErrorResponse( is_wp_error( $result ) ? $result->get_error_message() : ( $result['error'] ?? 'Delete failed' ), $tool_name ); } } diff --git a/inc/Chat/Tools/UpdateTwitter.php b/inc/Chat/Tools/UpdateTwitter.php index 0ba6ed87a..dce8e0784 100644 --- a/inc/Chat/Tools/UpdateTwitter.php +++ b/inc/Chat/Tools/UpdateTwitter.php @@ -88,22 +88,22 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) } // Get the ability. - if ( ! function_exists( 'wp_get_ability' ) ) { - return $this->buildErrorResponse( 'WordPress Abilities API not available', $tool_name ); + $ability = wp_get_ability( 'datamachine/twitter-update' ); + if ( ! $ability ) { + return $this->buildErrorResponse( 'datamachine/twitter-update ability not registered', $tool_name ); } $ability = wp_get_ability( 'datamachine/twitter-update' ); if ( ! $ability ) { return $this->buildErrorResponse( 'datamachine/twitter-update ability not registered', $tool_name ); } - $ability_instance = $ability; $result = $ability_instance->execute( array( 'action' => sanitize_text_field( $action ), 'tweet_id' => sanitize_text_field( $parameters['tweet_id'] ), ) ); - if ( $result['success'] ) { + if ( ! is_wp_error( $result ) && $result['success'] ) { $message = ''; switch ( $action ) { case 'delete': @@ -130,6 +130,6 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) ); } - return $this->buildErrorResponse( $result['error'] ?? 'Update failed', $tool_name ); + return $this->buildErrorResponse( is_wp_error( $result ) ? $result->get_error_message() : ( $result['error'] ?? 'Update failed' ), $tool_name ); } } diff --git a/inc/Chat/Tools/VoteReddit.php b/inc/Chat/Tools/VoteReddit.php index 6d335946a..54e8d00d8 100644 --- a/inc/Chat/Tools/VoteReddit.php +++ b/inc/Chat/Tools/VoteReddit.php @@ -94,10 +94,6 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) ); } - if ( ! function_exists( 'wp_get_ability' ) ) { - return $this->buildErrorResponse( 'WordPress Abilities API not available', $tool_name ); - } - $ability = wp_get_ability( 'datamachine/vote-reddit' ); if ( ! $ability ) { return $this->buildErrorResponse( 'datamachine/vote-reddit ability not registered', $tool_name ); @@ -109,7 +105,7 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) 'access_token' => $access_token, ) ); - if ( ! empty( $result['success'] ) ) { + if ( ! is_wp_error( $result ) && ! empty( $result['success'] ) ) { $direction_labels = array( 1 => 'upvoted', 0 => 'unvoted', @@ -124,6 +120,6 @@ public function handle_tool_call( array $parameters, array $tool_def = array() ) ); } - return $this->buildErrorResponse( $result['error'] ?? 'Failed to vote on Reddit', $tool_name ); + return $this->buildErrorResponse( is_wp_error( $result ) ? $result->get_error_message() : ( $result['error'] ?? 'Failed to vote on Reddit' ), $tool_name ); } } diff --git a/inc/Cli/Commands/BlueskyCommand.php b/inc/Cli/Commands/BlueskyCommand.php index c2efe3ce4..6c5b79dca 100644 --- a/inc/Cli/Commands/BlueskyCommand.php +++ b/inc/Cli/Commands/BlueskyCommand.php @@ -58,8 +58,8 @@ public function posts( $args, $assoc_args ) { 'cursor' => $assoc_args['cursor'] ?? '', ) ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } $data = $result['data']; @@ -126,8 +126,8 @@ public function thread( $args, $assoc_args ) { 'post_uri' => $post_uri, ) ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } $data = $result['data']; @@ -173,8 +173,8 @@ public function profile( $args, $assoc_args ) { $result = $ability->execute( array( 'action' => 'profile' ) ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } $data = $result['data']; @@ -294,8 +294,8 @@ public function publish( $args, $assoc_args ) { $result = \DataMachineSocials\Abilities\Bluesky\BlueskyPublishAbility::execute_publish( $input ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } WP_CLI::success( 'Published to Bluesky!' ); @@ -304,10 +304,6 @@ public function publish( $args, $assoc_args ) { } private function get_ability() { - if ( ! function_exists( 'wp_get_ability' ) ) { - WP_CLI::error( 'WordPress Abilities API not available (requires WP 6.9+).' ); - } - $ability = wp_get_ability( 'datamachine/bluesky-read' ); if ( ! $ability ) { WP_CLI::error( 'datamachine/bluesky-read ability not registered.' ); @@ -317,10 +313,6 @@ private function get_ability() { } private function get_update_ability() { - if ( ! function_exists( 'wp_get_ability' ) ) { - WP_CLI::error( 'WordPress Abilities API not available (requires WP 6.9+).' ); - } - $ability = wp_get_ability( 'datamachine/bluesky-update' ); if ( ! $ability ) { WP_CLI::error( 'datamachine/bluesky-update ability not registered.' ); @@ -330,10 +322,6 @@ private function get_update_ability() { } private function get_delete_ability() { - if ( ! function_exists( 'wp_get_ability' ) ) { - WP_CLI::error( 'WordPress Abilities API not available (requires WP 6.9+).' ); - } - $ability = wp_get_ability( 'datamachine/bluesky-delete' ); if ( ! $ability ) { WP_CLI::error( 'datamachine/bluesky-delete ability not registered.' ); @@ -363,8 +351,8 @@ public function delete( $args, $assoc_args ) { 'post_uri' => $post_uri, ) ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } WP_CLI::success( 'Post deleted successfully!' ); @@ -392,18 +380,14 @@ public function like( $args) { 'post_uri' => $post_uri, ) ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } WP_CLI::success( 'Post liked successfully!' ); } private function get_publish_ability() { - if ( ! function_exists( 'wp_get_ability' ) ) { - WP_CLI::error( 'WordPress Abilities API not available (requires WP 6.9+).' ); - } - $ability = wp_get_ability( 'datamachine/bluesky-publish' ); if ( ! $ability ) { WP_CLI::error( 'datamachine/bluesky-publish ability not registered.' ); diff --git a/inc/Cli/Commands/CommentsCommand.php b/inc/Cli/Commands/CommentsCommand.php index 09428915b..154fdb627 100644 --- a/inc/Cli/Commands/CommentsCommand.php +++ b/inc/Cli/Commands/CommentsCommand.php @@ -115,8 +115,8 @@ public function list_( $args, $assoc_args ) { 'media_id' => $media_id, ) ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } $comments = $result['data']['comments'] ?? array(); @@ -259,8 +259,8 @@ public function reply( $args ) { 'message' => $message, ) ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } WP_CLI::success( "Reply posted on {$platform}!" ); @@ -275,10 +275,6 @@ public function reply( $args ) { * @return object Ability instance. */ private function get_ability( string $slug ) { - if ( ! function_exists( 'wp_get_ability' ) ) { - WP_CLI::error( 'WordPress Abilities API not available (requires WP 6.9+).' ); - } - $ability = wp_get_ability( $slug ); if ( ! $ability ) { WP_CLI::error( "{$slug} ability not registered." ); diff --git a/inc/Cli/Commands/FacebookCommand.php b/inc/Cli/Commands/FacebookCommand.php index 8f730e312..003a3f2f8 100644 --- a/inc/Cli/Commands/FacebookCommand.php +++ b/inc/Cli/Commands/FacebookCommand.php @@ -58,8 +58,8 @@ public function posts( $args, $assoc_args ) { 'after' => $assoc_args['after'] ?? '', ) ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } $data = $result['data']; @@ -132,8 +132,8 @@ public function post( $args, $assoc_args ) { 'post_id' => $post_id, ) ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } $data = $result['data']; @@ -190,8 +190,8 @@ public function comments( $args, $assoc_args ) { 'limit' => absint( $assoc_args['limit'] ?? 25 ), ) ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } $data = $result['data']; @@ -337,8 +337,8 @@ public function publish( $args, $assoc_args ) { $result = \DataMachineSocials\Abilities\Facebook\FacebookPublishAbility::execute_publish( $input ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } WP_CLI::success( 'Published to Facebook!' ); @@ -352,10 +352,6 @@ public function publish( $args, $assoc_args ) { } private function get_ability() { - if ( ! function_exists( 'wp_get_ability' ) ) { - WP_CLI::error( 'WordPress Abilities API not available (requires WP 6.9+).' ); - } - $ability = wp_get_ability( 'datamachine/facebook-read' ); if ( ! $ability ) { WP_CLI::error( 'datamachine/facebook-read ability not registered.' ); @@ -365,10 +361,6 @@ private function get_ability() { } private function get_update_ability() { - if ( ! function_exists( 'wp_get_ability' ) ) { - WP_CLI::error( 'WordPress Abilities API not available (requires WP 6.9+).' ); - } - $ability = wp_get_ability( 'datamachine/facebook-update' ); if ( ! $ability ) { WP_CLI::error( 'datamachine/facebook-update ability not registered.' ); @@ -378,10 +370,6 @@ private function get_update_ability() { } private function get_delete_ability() { - if ( ! function_exists( 'wp_get_ability' ) ) { - WP_CLI::error( 'WordPress Abilities API not available (requires WP 6.9+).' ); - } - $ability = wp_get_ability( 'datamachine/facebook-delete' ); if ( ! $ability ) { WP_CLI::error( 'datamachine/facebook-delete ability not registered.' ); @@ -391,10 +379,6 @@ private function get_delete_ability() { } private function get_publish_ability() { - if ( ! function_exists( 'wp_get_ability' ) ) { - WP_CLI::error( 'WordPress Abilities API not available (requires WP 6.9+).' ); - } - $ability = wp_get_ability( 'datamachine/facebook-publish' ); if ( ! $ability ) { WP_CLI::error( 'datamachine/facebook-publish ability not registered.' ); @@ -434,8 +418,8 @@ public function edit( $args, $assoc_args ) { 'message' => $message, ) ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } WP_CLI::success( 'Post updated successfully!' ); @@ -464,8 +448,8 @@ public function hide( $args, $assoc_args ) { 'post_id' => $post_id, ) ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } WP_CLI::success( 'Post hidden successfully!' ); @@ -492,8 +476,8 @@ public function delete( $args, $assoc_args ) { 'post_id' => $post_id, ) ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } WP_CLI::success( 'Post deleted successfully!' ); diff --git a/inc/Cli/Commands/InstagramCommand.php b/inc/Cli/Commands/InstagramCommand.php index ab9165071..c64de8076 100644 --- a/inc/Cli/Commands/InstagramCommand.php +++ b/inc/Cli/Commands/InstagramCommand.php @@ -74,8 +74,8 @@ public function posts( $args, $assoc_args ) { 'after' => $assoc_args['after'] ?? '', ) ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } $data = $result['data']; @@ -156,8 +156,8 @@ public function post( $args, $assoc_args ) { 'media_id' => $media_id, ) ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } $data = $result['data']; @@ -221,8 +221,8 @@ public function comments( $args, $assoc_args ) { 'limit' => absint( $assoc_args['limit'] ?? 25 ), ) ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } $data = $result['data']; @@ -287,8 +287,8 @@ public function reply_comment( $args) { ) ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } WP_CLI::success( 'Instagram comment reply posted successfully!' ); @@ -387,8 +387,8 @@ public function edit_caption( $args) { 'caption' => $caption, ) ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } WP_CLI::success( 'Caption updated successfully!' ); @@ -416,8 +416,8 @@ public function delete( $args, $assoc_args ) { 'media_id' => $media_id, ) ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } WP_CLI::success( 'Post deleted successfully!' ); @@ -446,8 +446,8 @@ public function archive( $args, $assoc_args ) { 'media_id' => $media_id, ) ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } WP_CLI::success( 'Post archived successfully!' ); @@ -534,8 +534,8 @@ public function publish( $args, $assoc_args ) { $result = $publish_ability->execute( $input ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } WP_CLI::success( 'Published to Instagram!' ); @@ -613,8 +613,8 @@ public function publish_reel( $args, $assoc_args ) { $result = $publish_ability->execute( $input ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } WP_CLI::success( 'Reel published to Instagram!' ); @@ -675,8 +675,8 @@ public function publish_story( $args, $assoc_args ) { $result = $publish_ability->execute( $input ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } WP_CLI::success( 'Story published to Instagram!' ); @@ -690,10 +690,6 @@ public function publish_story( $args, $assoc_args ) { * @return \DataMachineSocials\Abilities\Instagram\InstagramPublishAbility */ private function get_publish_ability() { - if ( ! function_exists( 'wp_get_ability' ) ) { - WP_CLI::error( 'WordPress Abilities API not available (requires WP 6.9+).' ); - } - $ability = wp_get_ability( 'datamachine/instagram-publish' ); if ( ! $ability ) { WP_CLI::error( 'datamachine/instagram-publish ability not registered.' ); @@ -708,10 +704,6 @@ private function get_publish_ability() { * @return \DataMachineSocials\Abilities\Instagram\InstagramReadAbility */ private function get_ability() { - if ( ! function_exists( 'wp_get_ability' ) ) { - WP_CLI::error( 'WordPress Abilities API not available (requires WP 6.9+).' ); - } - $ability = wp_get_ability( 'datamachine/instagram-read' ); if ( ! $ability ) { WP_CLI::error( 'datamachine/instagram-read ability not registered.' ); @@ -726,10 +718,6 @@ private function get_ability() { * @return \DataMachineSocials\Abilities\Instagram\InstagramUpdateAbility */ private function get_update_ability() { - if ( ! function_exists( 'wp_get_ability' ) ) { - WP_CLI::error( 'WordPress Abilities API not available (requires WP 6.9+).' ); - } - $ability = wp_get_ability( 'datamachine/instagram-update' ); if ( ! $ability ) { WP_CLI::error( 'datamachine/instagram-update ability not registered.' ); @@ -744,10 +732,6 @@ private function get_update_ability() { * @return \DataMachineSocials\Abilities\Instagram\InstagramDeleteAbility */ private function get_delete_ability() { - if ( ! function_exists( 'wp_get_ability' ) ) { - WP_CLI::error( 'WordPress Abilities API not available (requires WP 6.9+).' ); - } - $ability = wp_get_ability( 'datamachine/instagram-delete' ); if ( ! $ability ) { WP_CLI::error( 'datamachine/instagram-delete ability not registered.' ); @@ -762,10 +746,6 @@ private function get_delete_ability() { * @return \DataMachineSocials\Abilities\Instagram\InstagramCommentReplyAbility */ private function get_comment_reply_ability() { - if ( ! function_exists( 'wp_get_ability' ) ) { - WP_CLI::error( 'WordPress Abilities API not available (requires WP 6.9+).' ); - } - $ability = wp_get_ability( 'datamachine/instagram-comment-reply' ); if ( ! $ability ) { WP_CLI::error( 'datamachine/instagram-comment-reply ability not registered.' ); diff --git a/inc/Cli/Commands/LinkedInCommand.php b/inc/Cli/Commands/LinkedInCommand.php index bdcc42ab1..a9280da2d 100644 --- a/inc/Cli/Commands/LinkedInCommand.php +++ b/inc/Cli/Commands/LinkedInCommand.php @@ -62,8 +62,8 @@ public function posts( $args, $assoc_args ) { 'start' => absint( $assoc_args['start'] ?? 0 ), ) ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } $data = $result['data']; @@ -129,8 +129,8 @@ public function post( $args, $assoc_args ) { 'post_id' => $post_id, ) ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } $data = $result['data']; @@ -235,8 +235,8 @@ public function publish( $args, $assoc_args ) { $result = \DataMachineSocials\Abilities\LinkedIn\LinkedInPublishAbility::execute_publish( $input ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } WP_CLI::success( 'Published to LinkedIn!' ); @@ -275,8 +275,8 @@ public function update( $args, $assoc_args ) { 'commentary' => $commentary, ) ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } WP_CLI::success( 'LinkedIn post updated successfully!' ); @@ -304,8 +304,8 @@ public function delete( $args, $assoc_args ) { 'post_id' => $post_id, ) ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } WP_CLI::success( 'LinkedIn post deleted successfully!' ); @@ -362,10 +362,6 @@ public function status( $args, $assoc_args ) { } private function get_read_ability() { - if ( ! function_exists( 'wp_get_ability' ) ) { - WP_CLI::error( 'WordPress Abilities API not available (requires WP 6.9+).' ); - } - $ability = wp_get_ability( 'datamachine/linkedin-read' ); if ( ! $ability ) { WP_CLI::error( 'datamachine/linkedin-read ability not registered.' ); @@ -375,10 +371,6 @@ private function get_read_ability() { } private function get_update_ability() { - if ( ! function_exists( 'wp_get_ability' ) ) { - WP_CLI::error( 'WordPress Abilities API not available (requires WP 6.9+).' ); - } - $ability = wp_get_ability( 'datamachine/linkedin-update' ); if ( ! $ability ) { WP_CLI::error( 'datamachine/linkedin-update ability not registered.' ); @@ -388,10 +380,6 @@ private function get_update_ability() { } private function get_delete_ability() { - if ( ! function_exists( 'wp_get_ability' ) ) { - WP_CLI::error( 'WordPress Abilities API not available (requires WP 6.9+).' ); - } - $ability = wp_get_ability( 'datamachine/linkedin-delete' ); if ( ! $ability ) { WP_CLI::error( 'datamachine/linkedin-delete ability not registered.' ); @@ -401,10 +389,6 @@ private function get_delete_ability() { } private function get_publish_ability() { - if ( ! function_exists( 'wp_get_ability' ) ) { - WP_CLI::error( 'WordPress Abilities API not available (requires WP 6.9+).' ); - } - $ability = wp_get_ability( 'datamachine/linkedin-publish' ); if ( ! $ability ) { WP_CLI::error( 'datamachine/linkedin-publish ability not registered.' ); diff --git a/inc/Cli/Commands/PinterestCommand.php b/inc/Cli/Commands/PinterestCommand.php index 4a3e584a8..d99eceb43 100644 --- a/inc/Cli/Commands/PinterestCommand.php +++ b/inc/Cli/Commands/PinterestCommand.php @@ -45,11 +45,11 @@ public function sync_boards( $args, $assoc_args ) { $result = PinterestBoardsAbility::sync_boards(); - if ( $result['success'] ) { + if ( ! is_wp_error( $result ) && $result['success'] ) { WP_CLI::success( "Synced {$result['count']} boards." ); $this->format_items( $result['boards'], array( 'id', 'name', 'description' ), $assoc_args ); } else { - WP_CLI::error( $result['error'] ); + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } } @@ -143,8 +143,8 @@ public function pins( $args, $assoc_args ) { 'bookmark' => $assoc_args['bookmark'] ?? '', ) ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } $data = $result['data']; @@ -205,8 +205,8 @@ public function pin( $args, $assoc_args ) { 'pin_id' => $pin_id, ) ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } WP_CLI::log( wp_json_encode( $result['data'], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES ) ); @@ -252,8 +252,8 @@ public function board_pins( $args, $assoc_args ) { 'bookmark' => $assoc_args['bookmark'] ?? '', ) ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } $data = $result['data']; @@ -345,8 +345,8 @@ public function publish( $args, $assoc_args ) { $result = \DataMachineSocials\Abilities\Pinterest\PinterestPublishAbility::execute_publish( $input ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } WP_CLI::success( 'Pin published to Pinterest!' ); @@ -360,10 +360,6 @@ public function publish( $args, $assoc_args ) { * @return \DataMachineSocials\Abilities\Pinterest\PinterestReadAbility */ private function get_read_ability() { - if ( ! function_exists( 'wp_get_ability' ) ) { - WP_CLI::error( 'WordPress Abilities API not available (requires WP 6.9+).' ); - } - $ability = wp_get_ability( 'datamachine/pinterest-read' ); if ( ! $ability ) { WP_CLI::error( 'datamachine/pinterest-read ability not registered.' ); @@ -373,10 +369,6 @@ private function get_read_ability() { } private function get_update_ability() { - if ( ! function_exists( 'wp_get_ability' ) ) { - WP_CLI::error( 'WordPress Abilities API not available (requires WP 6.9+).' ); - } - $ability = wp_get_ability( 'datamachine/pinterest-update' ); if ( ! $ability ) { WP_CLI::error( 'datamachine/pinterest-update ability not registered.' ); @@ -386,10 +378,6 @@ private function get_update_ability() { } private function get_delete_ability() { - if ( ! function_exists( 'wp_get_ability' ) ) { - WP_CLI::error( 'WordPress Abilities API not available (requires WP 6.9+).' ); - } - $ability = wp_get_ability( 'datamachine/pinterest-delete' ); if ( ! $ability ) { WP_CLI::error( 'datamachine/pinterest-delete ability not registered.' ); @@ -399,10 +387,6 @@ private function get_delete_ability() { } private function get_publish_ability() { - if ( ! function_exists( 'wp_get_ability' ) ) { - WP_CLI::error( 'WordPress Abilities API not available (requires WP 6.9+).' ); - } - $ability = wp_get_ability( 'datamachine/pinterest-publish' ); if ( ! $ability ) { WP_CLI::error( 'datamachine/pinterest-publish ability not registered.' ); @@ -432,8 +416,8 @@ public function delete( $args, $assoc_args ) { 'pin_id' => $pin_id, ) ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } WP_CLI::success( 'Pin deleted successfully!' ); diff --git a/inc/Cli/Commands/RedditCommand.php b/inc/Cli/Commands/RedditCommand.php index 351480f66..9625e4aa5 100644 --- a/inc/Cli/Commands/RedditCommand.php +++ b/inc/Cli/Commands/RedditCommand.php @@ -575,10 +575,6 @@ public function fetch( $args, $assoc_args ) { WP_CLI::log( "Fetching from r/{$subreddit} (sort: {$input['sort_by']})..." ); } - if ( ! function_exists( 'wp_get_ability' ) ) { - WP_CLI::error( 'WordPress Abilities API not available (requires WP 6.9+).' ); - } - $ability = wp_get_ability( 'datamachine/fetch-reddit' ); if ( ! $ability ) { WP_CLI::error( 'datamachine/fetch-reddit ability not registered.' ); @@ -586,8 +582,8 @@ public function fetch( $args, $assoc_args ) { $result = $ability->execute( $input ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ?? 'Reddit fetch failed.' ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : ( $result['error'] ?? 'Reddit fetch failed.' ) ); } // The ability returns 'items' array for multiple results. @@ -728,10 +724,6 @@ public function reply( $args, $assoc_args ) { $type_label = str_starts_with( $thing_id, 't3_' ) ? 'post' : 'comment'; WP_CLI::log( "Replying to {$type_label} {$thing_id}..." ); - if ( ! function_exists( 'wp_get_ability' ) ) { - WP_CLI::error( 'WordPress Abilities API not available (requires WP 6.9+).' ); - } - $ability = wp_get_ability( 'datamachine/reply-reddit' ); if ( ! $ability ) { WP_CLI::error( 'datamachine/reply-reddit ability not registered.' ); @@ -743,8 +735,8 @@ public function reply( $args, $assoc_args ) { 'access_token' => $access_token, ) ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ?? 'Reddit reply failed.' ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : ( $result['error'] ?? 'Reddit reply failed.' ) ); } $data = $result['data'] ?? array(); @@ -836,10 +828,6 @@ public function submit( $args, $assoc_args ) { $kind = ! empty( $url ) ? 'link' : 'self'; WP_CLI::log( "Submitting {$kind} post to r/{$subreddit}..." ); - if ( ! function_exists( 'wp_get_ability' ) ) { - WP_CLI::error( 'WordPress Abilities API not available (requires WP 6.9+).' ); - } - $ability = wp_get_ability( 'datamachine/submit-reddit' ); if ( ! $ability ) { WP_CLI::error( 'datamachine/submit-reddit ability not registered.' ); @@ -857,8 +845,8 @@ public function submit( $args, $assoc_args ) { 'access_token' => $access_token, ) ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ?? 'Reddit submit failed.' ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : ( $result['error'] ?? 'Reddit submit failed.' ) ); } $data = $result['data'] ?? array(); @@ -929,10 +917,6 @@ public function vote( $args, $assoc_args ) { WP_CLI::log( "{$label} {$thing_id}..." ); - if ( ! function_exists( 'wp_get_ability' ) ) { - WP_CLI::error( 'WordPress Abilities API not available (requires WP 6.9+).' ); - } - $ability = wp_get_ability( 'datamachine/vote-reddit' ); if ( ! $ability ) { WP_CLI::error( 'datamachine/vote-reddit ability not registered.' ); @@ -944,8 +928,8 @@ public function vote( $args, $assoc_args ) { 'access_token' => $access_token, ) ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ?? 'Reddit vote failed.' ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : ( $result['error'] ?? 'Reddit vote failed.' ) ); } $action = $result['data']['action'] ?? 'voted'; diff --git a/inc/Cli/Commands/ThreadsCommand.php b/inc/Cli/Commands/ThreadsCommand.php index b041475f6..ca21440f7 100644 --- a/inc/Cli/Commands/ThreadsCommand.php +++ b/inc/Cli/Commands/ThreadsCommand.php @@ -63,8 +63,8 @@ public function posts( $args, $assoc_args ) { 'after' => $assoc_args['after'] ?? '', ) ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } $data = $result['data']; @@ -128,8 +128,8 @@ public function post( $args, $assoc_args ) { 'thread_id' => $thread_id, ) ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } $data = $result['data']; @@ -185,8 +185,8 @@ public function replies( $args, $assoc_args ) { 'limit' => absint( $assoc_args['limit'] ?? 25 ), ) ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } $data = $result['data']; @@ -318,8 +318,8 @@ public function publish( $args, $assoc_args ) { $result = \DataMachineSocials\Abilities\Threads\ThreadsPublishAbility::execute_publish( $input ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } WP_CLI::success( 'Published to Threads!' ); @@ -328,10 +328,6 @@ public function publish( $args, $assoc_args ) { } private function get_ability() { - if ( ! function_exists( 'wp_get_ability' ) ) { - WP_CLI::error( 'WordPress Abilities API not available (requires WP 6.9+).' ); - } - $ability = wp_get_ability( 'datamachine/threads-read' ); if ( ! $ability ) { WP_CLI::error( 'datamachine/threads-read ability not registered.' ); @@ -341,10 +337,6 @@ private function get_ability() { } private function get_update_ability() { - if ( ! function_exists( 'wp_get_ability' ) ) { - WP_CLI::error( 'WordPress Abilities API not available (requires WP 6.9+).' ); - } - $ability = wp_get_ability( 'datamachine/threads-update' ); if ( ! $ability ) { WP_CLI::error( 'datamachine/threads-update ability not registered.' ); @@ -354,10 +346,6 @@ private function get_update_ability() { } private function get_delete_ability() { - if ( ! function_exists( 'wp_get_ability' ) ) { - WP_CLI::error( 'WordPress Abilities API not available (requires WP 6.9+).' ); - } - $ability = wp_get_ability( 'datamachine/threads-delete' ); if ( ! $ability ) { WP_CLI::error( 'datamachine/threads-delete ability not registered.' ); @@ -367,10 +355,6 @@ private function get_delete_ability() { } private function get_publish_ability() { - if ( ! function_exists( 'wp_get_ability' ) ) { - WP_CLI::error( 'WordPress Abilities API not available (requires WP 6.9+).' ); - } - $ability = wp_get_ability( 'datamachine/threads-publish' ); if ( ! $ability ) { WP_CLI::error( 'datamachine/threads-publish ability not registered.' ); @@ -400,8 +384,8 @@ public function delete( $args, $assoc_args ) { 'thread_id' => $thread_id, ) ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } WP_CLI::success( 'Thread deleted successfully!' ); diff --git a/inc/Cli/Commands/TwitterCommand.php b/inc/Cli/Commands/TwitterCommand.php index e1b97b163..91126da21 100644 --- a/inc/Cli/Commands/TwitterCommand.php +++ b/inc/Cli/Commands/TwitterCommand.php @@ -58,8 +58,8 @@ public function tweets( $args, $assoc_args ) { 'pagination_token' => $assoc_args['pagination-token'] ?? '', ) ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } $data = $result['data']; @@ -124,8 +124,8 @@ public function tweet( $args, $assoc_args ) { 'tweet_id' => $tweet_id, ) ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } $data = $result['data']; @@ -179,8 +179,8 @@ public function mentions( $args, $assoc_args ) { 'limit' => absint( $assoc_args['limit'] ?? 25 ), ) ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } $data = $result['data']; @@ -270,8 +270,8 @@ public function delete( $args, $assoc_args ) { 'tweet_id' => $tweet_id, ) ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } WP_CLI::success( 'Tweet deleted successfully!' ); @@ -300,8 +300,8 @@ public function retweet( $args, $assoc_args ) { 'tweet_id' => $tweet_id, ) ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } WP_CLI::success( 'Retweeted successfully!' ); @@ -328,8 +328,8 @@ public function like( $args) { 'tweet_id' => $tweet_id, ) ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } WP_CLI::success( 'Tweet liked successfully!' ); @@ -409,8 +409,8 @@ public function publish( $args, $assoc_args ) { $result = \DataMachineSocials\Abilities\Twitter\TwitterPublishAbility::execute_publish( $input ); - if ( ! $result['success'] ) { - WP_CLI::error( $result['error'] ); + if ( is_wp_error( $result ) || ! $result['success'] ) { + WP_CLI::error( is_wp_error( $result ) ? $result->get_error_message() : $result['error'] ); } WP_CLI::success( 'Published to Twitter!' ); @@ -424,10 +424,6 @@ public function publish( $args, $assoc_args ) { } private function get_ability() { - if ( ! function_exists( 'wp_get_ability' ) ) { - WP_CLI::error( 'WordPress Abilities API not available (requires WP 6.9+).' ); - } - $ability = wp_get_ability( 'datamachine/twitter-read' ); if ( ! $ability ) { WP_CLI::error( 'datamachine/twitter-read ability not registered.' ); @@ -437,10 +433,6 @@ private function get_ability() { } private function get_update_ability() { - if ( ! function_exists( 'wp_get_ability' ) ) { - WP_CLI::error( 'WordPress Abilities API not available (requires WP 6.9+).' ); - } - $ability = wp_get_ability( 'datamachine/twitter-update' ); if ( ! $ability ) { WP_CLI::error( 'datamachine/twitter-update ability not registered.' ); @@ -450,10 +442,6 @@ private function get_update_ability() { } private function get_delete_ability() { - if ( ! function_exists( 'wp_get_ability' ) ) { - WP_CLI::error( 'WordPress Abilities API not available (requires WP 6.9+).' ); - } - $ability = wp_get_ability( 'datamachine/twitter-delete' ); if ( ! $ability ) { WP_CLI::error( 'datamachine/twitter-delete ability not registered.' ); @@ -463,10 +451,6 @@ private function get_delete_ability() { } private function get_publish_ability() { - if ( ! function_exists( 'wp_get_ability' ) ) { - WP_CLI::error( 'WordPress Abilities API not available (requires WP 6.9+).' ); - } - $ability = wp_get_ability( 'datamachine/twitter-publish' ); if ( ! $ability ) { WP_CLI::error( 'datamachine/twitter-publish ability not registered.' ); diff --git a/inc/RestApi.php b/inc/RestApi.php index 3d31dcec0..516ae8cfc 100644 --- a/inc/RestApi.php +++ b/inc/RestApi.php @@ -547,7 +547,7 @@ public static function platform_read( \WP_REST_Request $request ) { ), 400 ); } - $ability = function_exists( 'wp_get_ability' ) ? wp_get_ability( $slug_map[ $platform ] ) : null; + $ability = wp_get_ability( $slug_map[ $platform ] ); if ( ! $ability ) { return new \WP_REST_Response( array( 'success' => false, @@ -558,6 +558,11 @@ public static function platform_read( \WP_REST_Request $request ) { } ); $result = $ability->execute( $input ); + if ( is_wp_error( $result ) ) { + $status = $result->get_error_data()['status'] ?? 500; + return new \WP_REST_Response( array( 'success' => false, 'error' => $result->get_error_message() ), $status ); + } + return new \WP_REST_Response( $result, $result['success'] ? 200 : 500 ); } @@ -621,7 +626,7 @@ public static function platform_update( \WP_REST_Request $request ) { ), 400 ); } - $ability = function_exists( 'wp_get_ability' ) ? wp_get_ability( $slug_map[ $platform ] ) : null; + $ability = wp_get_ability( $slug_map[ $platform ] ); if ( ! $ability ) { return new \WP_REST_Response( array( 'success' => false, @@ -644,6 +649,11 @@ public static function platform_update( \WP_REST_Request $request ) { $result = $ability->execute( $input ); + if ( is_wp_error( $result ) ) { + $status = $result->get_error_data()['status'] ?? 500; + return new \WP_REST_Response( array( 'success' => false, 'error' => $result->get_error_message() ), $status ); + } + return new \WP_REST_Response( $result, $result['success'] ? 200 : 500 ); } @@ -667,7 +677,7 @@ public static function instagram_comment_reply( \WP_REST_Request $request ) { ), 400 ); } - $ability = function_exists( 'wp_get_ability' ) ? wp_get_ability( 'datamachine/instagram-comment-reply' ) : null; + $ability = wp_get_ability( 'datamachine/instagram-comment-reply' ); if ( ! $ability ) { return new \WP_REST_Response( array( 'success' => false, 'error' => 'Ability not registered' ), 500 ); } @@ -678,6 +688,11 @@ public static function instagram_comment_reply( \WP_REST_Request $request ) { ) ); + if ( is_wp_error( $result ) ) { + $status = $result->get_error_data()['status'] ?? 500; + return new \WP_REST_Response( array( 'success' => false, 'error' => $result->get_error_message() ), $status ); + } + return new \WP_REST_Response( $result, $result['success'] ? 200 : 500 ); } @@ -713,7 +728,7 @@ public static function get_comments( \WP_REST_Request $request ) { ), 400 ); } - $ability = function_exists( 'wp_get_ability' ) ? wp_get_ability( $slug_map[ $platform ] ) : null; + $ability = wp_get_ability( $slug_map[ $platform ] ); if ( ! $ability ) { return new \WP_REST_Response( array( 'success' => false, @@ -736,6 +751,11 @@ public static function get_comments( \WP_REST_Request $request ) { $result = $ability->execute( $input ); + if ( is_wp_error( $result ) ) { + $status = $result->get_error_data()['status'] ?? 500; + return new \WP_REST_Response( array( 'success' => false, 'error' => $result->get_error_message() ), $status ); + } + return new \WP_REST_Response( $result, $result['success'] ? 200 : 500 ); } @@ -770,7 +790,7 @@ public static function post_comment_reply( \WP_REST_Request $request ) { ), 400 ); } - $ability = function_exists( 'wp_get_ability' ) ? wp_get_ability( $slug_map[ $platform ] ) : null; + $ability = wp_get_ability( $slug_map[ $platform ] ); if ( ! $ability ) { return new \WP_REST_Response( array( 'success' => false, @@ -783,6 +803,11 @@ public static function post_comment_reply( \WP_REST_Request $request ) { 'message' => sanitize_textarea_field( $message ), ) ); + if ( is_wp_error( $result ) ) { + $status = $result->get_error_data()['status'] ?? 500; + return new \WP_REST_Response( array( 'success' => false, 'error' => $result->get_error_message() ), $status ); + } + return new \WP_REST_Response( $result, $result['success'] ? 200 : 500 ); } @@ -821,12 +846,17 @@ public static function instagram_publish_reel( \WP_REST_Request $request ) { $input['source_url'] = sanitize_url( $params['source_url'] ); } - $ability = function_exists( 'wp_get_ability' ) ? wp_get_ability( 'datamachine/instagram-publish' ) : null; + $ability = wp_get_ability( 'datamachine/instagram-publish' ); if ( ! $ability ) { return new \WP_REST_Response( array( 'success' => false, 'error' => 'Ability not registered' ), 500 ); } $result = $ability->execute( $input ); + if ( is_wp_error( $result ) ) { + $status = $result->get_error_data()['status'] ?? 500; + return new \WP_REST_Response( array( 'success' => false, 'error' => $result->get_error_message() ), $status ); + } + return new \WP_REST_Response( $result, $result['success'] ? 200 : 500 ); } @@ -857,12 +887,17 @@ public static function instagram_publish_story( \WP_REST_Request $request ) { $input['story_image_url'] = sanitize_url( $image_url ); } - $ability = function_exists( 'wp_get_ability' ) ? wp_get_ability( 'datamachine/instagram-publish' ) : null; + $ability = wp_get_ability( 'datamachine/instagram-publish' ); if ( ! $ability ) { return new \WP_REST_Response( array( 'success' => false, 'error' => 'Ability not registered' ), 500 ); } $result = $ability->execute( $input ); + if ( is_wp_error( $result ) ) { + $status = $result->get_error_data()['status'] ?? 500; + return new \WP_REST_Response( array( 'success' => false, 'error' => $result->get_error_message() ), $status ); + } + return new \WP_REST_Response( $result, $result['success'] ? 200 : 500 ); } @@ -1077,14 +1112,6 @@ public static function cross_post( \WP_REST_Request $request ) { private static function post_to_platform( string $platform, array $images, string $caption, string $source_url, array $extra = array() ): array { $ability_slug = "datamachine/{$platform}-publish"; - if ( ! function_exists( 'wp_get_ability' ) ) { - return array( - 'platform' => $platform, - 'success' => false, - 'error' => 'Abilities API not available', - ); - } - $ability = wp_get_ability( $ability_slug ); if ( ! $ability ) {