| Server IP : 3.147.158.171 / Your IP : 216.73.216.216 Web Server : Apache/2.4.67 (Amazon Linux) OpenSSL/3.5.5 System : Linux ip-172-31-2-178.us-east-2.compute.internal 6.1.172-216.329.amzn2023.x86_64 #1 SMP PREEMPT_DYNAMIC Wed May 20 06:31:34 UTC 2026 x86_64 User : ec2-user ( 1000) PHP Version : 8.4.21 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /tsai/repo/sites/dev/wp-content/plugins/tsai-plugin/includes/ |
Upload File : |
<?php
if (!defined('ABSPATH')) {
exit;
}
class TSAI_Rest_API {
public function __construct() {
add_action('rest_api_init', array($this, 'register_routes'));
}
public function register_routes() {
register_rest_route('tsai/v1', '/site-icon', array(
'methods' => 'POST',
'callback' => array($this, 'set_site_icon'),
'permission_callback' => function () {
return current_user_can('manage_options');
},
));
register_rest_route('tsai/v1', '/site-icon-meta', array(
'methods' => 'GET',
'callback' => array($this, 'get_site_icon_meta'),
'permission_callback' => '__return_true',
));
}
public function get_site_icon_meta() {
return rest_ensure_response(array(
'updated_at' => (int) get_option('tsai_app_icons_updated', 0),
));
}
public function set_site_icon(WP_REST_Request $request) {
$image_data = $request->get_param('image');
if (empty($image_data)) {
return new WP_Error('missing_image', 'No image data provided.', array('status' => 400));
}
// Decode base64 image
$decoded = base64_decode($image_data);
if ($decoded === false) {
return new WP_Error('invalid_image', 'Invalid base64 image data.', array('status' => 400));
}
// Required for wp_tempnam and media_handle_sideload
require_once ABSPATH . 'wp-admin/includes/image.php';
require_once ABSPATH . 'wp-admin/includes/file.php';
require_once ABSPATH . 'wp-admin/includes/media.php';
// Write to a temp file
$tmp_file = wp_tempnam('site-icon-') . '.png';
file_put_contents($tmp_file, $decoded);
// Prepare file array for media_handle_sideload
$file_array = array(
'name' => 'site-icon.png',
'tmp_name' => $tmp_file,
);
$attachment_id = media_handle_sideload($file_array, 0, 'Site Icon');
// Clean up temp file if it still exists
if (file_exists($tmp_file)) {
unlink($tmp_file);
}
if (is_wp_error($attachment_id)) {
return new WP_Error('upload_failed', $attachment_id->get_error_message(), array('status' => 500));
}
// Set as site icon
update_option('site_icon', $attachment_id);
$icon_url = wp_get_attachment_image_url($attachment_id, 'full');
$app_icons_written = $this->write_app_icon_variants($request->get_param('app_icons'));
$updated_at = time();
update_option('tsai_app_icons_updated', $updated_at);
return rest_ensure_response(array(
'success' => true,
'attachment_id' => $attachment_id,
'icon_url' => $icon_url,
'app_icons_written' => $app_icons_written,
'updated_at' => $updated_at,
));
}
private function write_app_icon_variants($app_icons) {
if (!is_array($app_icons) || empty($app_icons)) {
return array();
}
$whitelist = array('creator', 'player', 'sas');
$upload = wp_upload_dir();
$dir = trailingslashit($upload['basedir']) . 'tsai-icons';
if (!wp_mkdir_p($dir)) {
return array();
}
$written = array();
foreach ($app_icons as $app => $b64) {
if (!in_array($app, $whitelist, true) || !is_string($b64) || $b64 === '') {
continue;
}
$bytes = base64_decode($b64, true);
if ($bytes === false || strlen($bytes) < 8) {
continue;
}
// Verify PNG magic bytes.
if (substr($bytes, 0, 8) !== "\x89PNG\r\n\x1a\n") {
continue;
}
$path = trailingslashit($dir) . $app . '.png';
if (file_put_contents($path, $bytes) !== false) {
$written[] = $app;
}
}
return $written;
}
}
new TSAI_Rest_API();