Ansico-embed-url/ansico-embed-url.php
2026-04-13 17:24:29 +00:00

111 lines
No EOL
3.3 KiB
PHP

<?php
/**
* Plugin Name: Ansico Embed URL
* Description: A Gutenberg block to embed a URL with a social-media style preview card. Automatically fetches metadata and saves the image locally.
* Version: 1.0.0
* Author: Ansico
* Text Domain: ansico-embed-url
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
// Register the block and its assets
add_action( 'init', 'ansico_embed_url_register_block' );
function ansico_embed_url_register_block() {
wp_register_script(
'ansico-embed-url-script',
plugins_url( 'ansico-embed-url.js', __FILE__ ),
array( 'wp-blocks', 'wp-element', 'wp-editor', 'wp-components', 'wp-api-fetch' ),
'1.0.0'
);
wp_register_style(
'ansico-embed-url-style',
plugins_url( 'ansico-embed-url.css', __FILE__ ),
array(),
'1.0.0'
);
register_block_type( 'ansico/embed-url', array(
'editor_script' => 'ansico-embed-url-script',
'editor_style' => 'ansico-embed-url-style',
'style' => 'ansico-embed-url-style',
) );
}
// Register REST API Route
add_action( 'rest_api_init', function () {
register_rest_route( 'ansico/v1', '/fetch-url', array(
'methods' => 'POST',
'callback' => 'ansico_embed_url_fetch_metadata',
'permission_callback' => function () {
return current_user_can( 'edit_posts' );
}
) );
} );
function ansico_embed_url_fetch_metadata( $request ) {
$url = esc_url_raw( $request->get_param( 'url' ) );
if ( empty( $url ) ) {
return new WP_Error( 'missing_url', 'No URL provided', array( 'status' => 400 ) );
}
$response = wp_remote_get( $url );
if ( is_wp_error( $response ) ) {
return new WP_Error( 'fetch_failed', 'Could not fetch URL', array( 'status' => 500 ) );
}
$html = wp_remote_retrieve_body( $response );
libxml_use_internal_errors(true);
$doc = new DOMDocument();
$doc->loadHTML( mb_convert_encoding( $html, 'HTML-ENTITIES', 'UTF-8' ) );
libxml_clear_errors();
$title = '';
$image_url = '';
$domain = parse_url( $url, PHP_URL_HOST );
$domain = str_replace( 'www.', '', $domain );
$tags = $doc->getElementsByTagName( 'meta' );
foreach ( $tags as $tag ) {
if ( $tag->getAttribute( 'property' ) === 'og:title' ) {
$title = $tag->getAttribute( 'content' );
}
if ( $tag->getAttribute( 'property' ) === 'og:image' ) {
$image_url = $tag->getAttribute( 'content' );
}
}
if ( empty( $title ) ) {
$nodes = $doc->getElementsByTagName( 'title' );
if ( $nodes->length > 0 ) {
$title = $nodes->item(0)->nodeValue;
}
}
$local_image_url = '';
if ( ! empty( $image_url ) ) {
require_once( ABSPATH . 'wp-admin/includes/media.php' );
require_once( ABSPATH . 'wp-admin/includes/file.php' );
require_once( ABSPATH . 'wp-admin/includes/image.php' );
$sideloaded = media_sideload_image( $image_url, 0, null, 'src' );
if ( ! is_wp_error( $sideloaded ) ) {
$local_image_url = $sideloaded;
} else {
$local_image_url = $image_url;
}
}
return rest_ensure_response( array(
'title' => $title,
'image' => $local_image_url,
'domain' => $domain,
) );
}
?>