File manager - Edit - /home/proidvn/site.proid.vn/wp-content/plugins/novamira/includes/abilities/read-file.php
Back
<?php // SPDX-FileCopyrightText: 2026 Ovation S.r.l. <dev@novamira.ai> // SPDX-License-Identifier: AGPL-3.0-or-later declare(strict_types=1); /** * Ability: Read file contents. */ if (!defined('ABSPATH')) { exit(); } wp_register_ability('novamira/read-file', [ 'label' => __('Read File', domain: 'novamira'), 'description' => __( 'Reads the contents of a file from the server filesystem. Supports text and binary files. Binary files and files with invalid UTF-8 are returned as base64-encoded. Supports partial reads via offset and limit parameters.', domain: 'novamira', ), 'category' => 'filesystem', 'input_schema' => [ 'type' => 'object', 'properties' => [ 'path' => [ 'type' => 'string', 'description' => 'File path. Relative paths are resolved from the WordPress root (ABSPATH).', 'minLength' => 1, ], 'offset' => [ 'type' => 'integer', 'description' => 'Byte offset to start reading from.', 'default' => 0, 'minimum' => 0, ], 'limit' => [ 'type' => 'integer', 'description' => 'Maximum bytes to read. Use -1 for the entire file.', 'default' => 1_048_576, ], ], 'required' => ['path'], 'additionalProperties' => false, ], 'output_schema' => [ 'type' => 'object', 'properties' => [ 'path' => ['type' => 'string', 'description' => 'Absolute path to the file.'], 'content' => ['type' => 'string', 'description' => 'File content (text or base64-encoded).'], 'encoding' => ['type' => 'string', 'description' => 'Content encoding: "utf-8" or "base64".'], 'size' => ['type' => 'integer', 'description' => 'Total file size in bytes.'], 'bytes_read' => ['type' => 'integer', 'description' => 'Number of bytes actually read.'], 'truncated' => [ 'type' => 'boolean', 'description' => 'Whether the content was truncated due to limit.', ], 'mime_type' => ['type' => 'string', 'description' => 'Detected MIME type.'], ], ], 'execute_callback' => 'novamira_read_file', 'permission_callback' => 'novamira_permission_callback', 'meta' => [ 'show_in_rest' => true, 'mcp' => ['public' => true], 'annotations' => [ 'instructions' => 'TIP: AI-written PHP plugins live in wp-content/novamira-sandbox/. Check wp-content/novamira-sandbox/.crashed to see if safe mode is active.', 'readonly' => true, 'destructive' => false, 'idempotent' => true, ], ], ]); /** * Read file contents. * * @param array $input Input with 'path', optional 'offset' and 'limit'. * @return array|WP_Error */ function novamira_read_file($input) { $resolved = novamira_resolve_path(path: (string) $input['path'], must_exist: true); if (is_wp_error($resolved)) { return $resolved; } if (!is_file($resolved)) { return new WP_Error('not_a_file', sprintf('Path is not a file: %s', $resolved)); } if (!is_readable($resolved)) { return new WP_Error('not_readable', sprintf('File is not readable: %s', $resolved)); } $size = (int) filesize($resolved); $offset = (int) ($input['offset'] ?? 0); $limit = (int) ($input['limit'] ?? 1_048_576); $default_mime = 'application/octet-stream'; $detected_mime = function_exists('mime_content_type') ? mime_content_type($resolved) : false; $mime_type = $detected_mime !== false ? $detected_mime : $default_mime; $handle = fopen(filename: $resolved, mode: 'rb'); if ($handle === false) { return new WP_Error('read_failed', sprintf('Could not open file: %s', $resolved)); } if ($offset > 0) { fseek($handle, $offset); } $read_length = $limit === -1 ? $size - $offset : $limit; $content = fread($handle, max(1, $read_length)); fclose($handle); if ($content === false) { return new WP_Error('read_failed', sprintf('Could not read file: %s', $resolved)); } $bytes_read = strlen($content); $truncated = $limit !== -1 && ($offset + $bytes_read) < $size; // Determine encoding: use base64 for binary content or invalid UTF-8. $is_text = novamira_is_text_mime_type($mime_type) && mb_check_encoding(value: $content, encoding: 'UTF-8'); if (!$is_text) { $content = base64_encode($content); } return [ 'path' => $resolved, 'content' => $content, 'encoding' => $is_text ? 'utf-8' : 'base64', 'size' => $size, 'bytes_read' => $bytes_read, 'truncated' => $truncated, 'mime_type' => $mime_type, ]; } /** * Check whether a MIME type represents text content. * * @param string $mime_type The MIME type to check. * @return bool */ function novamira_is_text_mime_type($mime_type) { // MIME types and subtypes that are treated as text. $text_prefixes = ['text/', 'application/json', 'application/xml', 'application/javascript']; $text_suffixes = ['+xml', '+json']; foreach ($text_prefixes as $prefix) { if (str_starts_with($mime_type, $prefix)) { return true; } } foreach ($text_suffixes as $suffix) { if (str_ends_with($mime_type, $suffix)) { return true; } } return false; }
| ver. 1.4 |
Github
|
.
| PHP 8.0.30 | Generation time: 0.12 |
proxy
|
phpinfo
|
Settings