a-blog cms PHP API Reference

Helper
in package

埋め込み対象 URL から OGP / oEmbed のメタ情報を取得する。

ユニット・ブロックエディタなど複数の入口から同じ経路で取得できるようサービスにしている。 取得結果の保存先(カラム構成)は呼び出し側の責務で、ここでは扱わない。

どのサービスの埋め込みを解決できるかは ProviderRegistry が持ち、本クラスは 「キャッシュ」「サニタイズ」「表示のための整形」という、プロバイダーに依らない部分だけを担う。

Table of Contents

Constants

PREVIEW_HTML_MAX_BYTES  = 102400
プレビュー用に再サニタイズを受け付ける HTML の上限(バイト)
FALLBACK_EMBED_HEIGHT  = 152
比率を計算できない iframe に与える高さ(px)

Properties

$cacheAdapter  : AdapterInterface|null
フィールドキャッシュのアダプタ
$previewScriptPolicy  : ScriptPolicy|null
編集画面のプレビューで実行してよい外部 script の許可ホスト
$providerRegistry  : ProviderRegistry|null
埋め込みを解決するプロバイダーのレジストリ
$sanitizer  : callable(string): string|null
埋め込み HTML のサニタイザ

Methods

__construct()  : mixed
fallbackIframeTitle()  : string
iframe に補完する title 属性値を、oEmbed のタイトル → 提供元名 → 汎用ラベルの優先順で決める。
fetch()  : EmbedData
URL からメタ情報を取得する
fetchWithoutCache()  : EmbedData
キャッシュを使わずに取得する
fetchWithRetryOnEmptyCache()  : EmbedData
URL からメタ情報を取得する。キャッシュヒットが「前回取得失敗(空)」だった場合に限り、 キャッシュを無視して再取得する。
forget()  : void
指定 URL のキャッシュを破棄する
isResolvableUrl()  : bool
埋め込みの取得対象として受け付ける URL か判定する
normalizeIframes()  : string
サニタイズ済みの iframe を、表示・アクセシビリティの両面で確定した形へ整える。
sanitizeEmbedHtml()  : string
埋め込み HTML を「保存してよい形」に確定させる。
sanitizeForPreview()  : string
保存済みの埋め込み HTML を、編集画面のプレビューで実行してよい形に確定させる。
resolve()  : EmbedData
外部から取得する
applyResponsiveStyle()  : bool
iframe の固定寸法をアスペクト比へ移し替える。
cache()  : AdapterInterface
フィールドキャッシュのアダプタを取得する
cacheKey()  : string
ensureIframeLoading()  : bool
iframe に loading="lazy" が無ければ補完する。
ensureIframeTitle()  : bool
iframe に非空 title が無ければ補完する。
fallbackHeight()  : bool
比率へ変換できない iframe の高さを、潰れない値へ退避させる。
finalize()  : EmbedData
プロバイダーが返した結果を、保存してよい形へ確定させる。
hasMeaningfulEmbedTag()  : bool
サニタイズ後の HTML に、埋め込みとして意味のある要素が残っているか判定する。
previewScriptPolicy()  : ScriptPolicy
プレビューで実行してよい外部 script の許可ホストを取得する
providers()  : ProviderRegistry
埋め込みプロバイダーのレジストリを取得する
purify()  : string
外部から取得した埋め込み HTML をサニタイズする
removeScriptsNotAllowedBy()  : string
サニタイズ済みの HTML から、src が許可ホストに一致しない script 要素を取り除く。
removeSrclessScriptTags()  : string
src を持たない script 要素を取り除く。
resolveAndCache()  : EmbedData
取得してキャッシュへ保存する

Constants

PREVIEW_HTML_MAX_BYTES

プレビュー用に再サニタイズを受け付ける HTML の上限(バイト)

public mixed PREVIEW_HTML_MAX_BYTES = 102400

oEmbed が返す埋め込み HTML は大きなもの(インライン SVG を含む Instagram 等)でも 数十 KB に収まる。それを大きく超える入力は埋め込みとして不自然なため、 HtmlPurifier に渡す前に断り、サニタイズのコストを入力の大きさで膨らませない。

FALLBACK_EMBED_HEIGHT

比率を計算できない iframe に与える高さ(px)

private mixed FALLBACK_EMBED_HEIGHT = 152

width="100%" / height="100%" のような相対指定を返すプロバイダ(Spotify 等の音声系)向け。 この種の埋め込みは高さが固定のプレイヤー UI であることが多く、実測でおおむね収まる値。

Properties

$previewScriptPolicy

編集画面のプレビューで実行してよい外部 script の許可ホスト

private ScriptPolicy|null $previewScriptPolicy

$providerRegistry

埋め込みを解決するプロバイダーのレジストリ

private ProviderRegistry|null $providerRegistry

$sanitizer

埋め込み HTML のサニタイザ

private callable(string): string|null $sanitizer

Methods

__construct()

public __construct([callable(string): string|null $sanitizer = null ][, AdapterInterface|null $cacheAdapter = null ][, ProviderRegistry|null $providerRegistry = null ][, ScriptPolicy|null $previewScriptPolicy = null ]) : mixed
Parameters
$sanitizer : callable(string): string|null = null

埋め込み HTML のサニタイザ。 省略時は HtmlPurifier サービス(config の html_purifier_iframe_allowed_hosts に従う)。 テストからグローバル状態に触れずに差し替えられるよう引数で受け取る。

$cacheAdapter : AdapterInterface|null = null

フィールドキャッシュのアダプタ。 省略時は Cache::field()(ファサード)。$sanitizer と同じ理由でテストから注入できるようにする。

$providerRegistry : ProviderRegistry|null = null

埋め込みプロバイダーのレジストリ。 省略時はコンテナの embed.providers。上と同じ理由でテストから注入できるようにする。

$previewScriptPolicy : ScriptPolicy|null = null

プレビューで実行してよい外部 script の許可ホスト。 省略時は config の block_editor_embed_preview_script_allowed_hosts(と extends_ 側)。 上と同じ理由でテストから注入できるようにする。

fallbackIframeTitle()

iframe に補完する title 属性値を、oEmbed のタイトル → 提供元名 → 汎用ラベルの優先順で決める。

public static fallbackIframeTitle(string $title, string $providerName) : string

Why not 提供元名だけを入れないか: title="YouTube" では「YouTube という名前のフレーム」 までしか伝わらず、そこに何が埋め込まれているのかが支援技術の利用者に届かない。img の alt と 同じ発想で、種別を表す語を添えて読み上げが文として成立する形にする。

Why not private: 保存時(normalizeIframes)と、保存済み HTML の出力時 (EmbedFunctionTagHandler)の両方が同じ文言・ 同じ優先順を使う必要があるため、文言の単一の情報源としてここに公開する。

Parameters
$title : string

oEmbed から取得したタイトル

$providerName : string

oEmbed から取得したプロバイダ名

Return values
string

fetch()

URL からメタ情報を取得する

public fetch(string $url) : EmbedData

同じ URL の再取得を避けるためフィールドキャッシュを経由する。取得に失敗した場合も 空の結果をキャッシュして、保存のたびに毎回外部へ取りに行かないようにする。

Parameters
$url : string

取得対象の URL

Return values
EmbedData —

取得できなかった項目は空文字

fetchWithoutCache()

キャッシュを使わずに取得する

public fetchWithoutCache(string $url) : EmbedData
Parameters
$url : string
Return values
EmbedData

fetchWithRetryOnEmptyCache()

URL からメタ情報を取得する。キャッシュヒットが「前回取得失敗(空)」だった場合に限り、 キャッシュを無視して再取得する。

public fetchWithRetryOnEmptyCache(string $url) : EmbedData

fetch() の 24 時間キャッシュは巡回的な保存(オートセーブ等)でのサーバ負荷対策として 妥当だが、ユーザーがブロックエディタで URL を明示的に再確定した操作(一時的な障害からの 回復を期待している)にまで適用すると、確定し直しても 24 時間失敗し続けてしまう。 非空のキャッシュ(取得成功)はそのまま尊重し、毎回律儀に再取得はしない。

Parameters
$url : string

取得対象の URL

Return values
EmbedData —

取得できなかった項目は空文字

forget()

指定 URL のキャッシュを破棄する

public forget(string $url) : void
Parameters
$url : string

isResolvableUrl()

埋め込みの取得対象として受け付ける URL か判定する

public isResolvableUrl(string $url) : bool

編集画面の取得(ACMS_GET_Admin_BlockEditor_EmbedJson)と入稿用タグの解決 (BlockEditor\Authoring\AuthoringConverter)で同じ基準を使うため、ここに置く。

Why not: REGEX_VALID_URL だけで済ませないのは、この定数が ftp スキームも許すため。 埋め込みで扱うのは http(s) だけに限る(SSRF 対策の本体は SsrfGuardedClient が担う)。

Parameters
$url : string
Return values
bool

normalizeIframes()

サニタイズ済みの iframe を、表示・アクセシビリティの両面で確定した形へ整える。

public normalizeIframes(string $html, string $title, string $providerName) : string
  • 固定寸法(width="560" height="315" 等)をアスペクト比へ変換し、コンテナ幅に追従させる。 oEmbed が返す固定ピクセルのままでは、表示サイズ(data-width)を広げても提供元の実寸のままになり、 CSS の max-width では縮小しかできない(拡大されない)。
  • 非空の title が無ければ oEmbed のタイトル・プロバイダ名の順で補完する(WCAG 2.4.1 / H64: フレームには判別可能なタイトルが必要。プロバイダが title を省略することが多いため)。
  • loading="lazy" を補完し、ビューポートに入るまで外部の埋め込みを取得しないようにする。

サニタイズはしない。信頼できない HTML は sanitizeEmbedHtml() を通すこと (sanitizeEmbedHtml() は最後にこのメソッドを呼ぶ)。

Why not private: 保存時と、保存済み HTML の出力時 (EmbedFunctionTagHandler)で同じ正規化を 重複実装せず、変換規則の単一の情報源をここに保つため。

Parameters
$html : string

サニタイズ済みの埋め込み HTML

$title : string

oEmbed から取得したタイトル

$providerName : string

oEmbed から取得したプロバイダ名

Return values
string

sanitizeEmbedHtml()

埋め込み HTML を「保存してよい形」に確定させる。

public sanitizeEmbedHtml(string $html[, string $title = '' ][, string $providerName = '' ]) : string

埋め込み先の許可はここで独自に持たず、iframe のホワイトリスト (config の html_purifier_iframe_allowed_hosts)を単一の情報源として HtmlPurifier に委ねる。 許可外ホストは src ごと落ちるため、実体の無くなった HTML は空文字に倒して 呼び出し側が OGP カード / 通常リンクへ退避できるようにする。

取得時(エディターへ返す時点)と出力時(公開側の描画時)の両方で同じ規則を通す。 出力時の再サニタイズは EmbedFunctionTagHandler::render() が担う。

Why not 出力時だけに寄せないか: 編集中のプレビューや保存 HTML に、許可外の HTML が 一時的にでも載らないようにするため。ブロックエディターの保存 HTML は PHP 側で サニタイズされず(Services/Unit/Models/BlockEditor.php)、エディター上の表示は 取得結果そのものなので、取得時にも確定させておく。 Why not 取得時だけで済ませないか: 保存 HTML は API・インポート・ソース編集等からも 書き換えられ、取得時の確定を経ていない値が混ざりうるため、出力時にも同じ規則を通す。

Parameters
$html : string

oEmbed 等から得た生の埋め込み HTML

$title : string = ''

oEmbed から取得したタイトル。iframe に title が無いときの補完に使う

$providerName : string = ''

oEmbed から取得したプロバイダ名。title が空のときの次点の補完に使う

Return values
string —

採用できる HTML。採用できない場合は空文字

sanitizeForPreview()

保存済みの埋め込み HTML を、編集画面のプレビューで実行してよい形に確定させる。

public sanitizeForPreview(string $html[, string $title = '' ][, string $providerName = '' ]) : string

規則は公開側の出力(EmbedFunctionTagHandler::render()) と同じ sanitizeEmbedHtml() を通したうえで、さらに外部 script をプレビュー用の許可ホスト (block_editor_embed_preview_script_allowed_hosts)に一致するものだけに絞る。プレビューで動くのは 公開側の許可ホストとプレビュー用の許可ホストの積集合だけになる。外部サービスへの再取得はしない。

Why not 公開側の許可ホストをそのまま使わないか: 公開側にはタグマネージャー・解析・MA 系の script も並ぶ。投稿者が自分のコンテナ ID を指定した script を埋め込むと、管理者がプレビューを 開いた時点で管理画面のオリジンで任意の JS を動かせてしまうため、埋め込みウィジェットに限る。

Why not プレビューを保存済みの HTML のまま描画しないか: プレビューは提供元のウィジェットを 動かすため管理画面と同じオリジンで描画する。保存済みの値は貼り付け・改ざんで任意の HTML になりうるので、サーバーで確定させた結果だけを描画させる。

Parameters
$html : string

保存済みの埋め込み HTML

$title : string = ''

iframe に title が無いときの補完に使うタイトル

$providerName : string = ''

title が空のときの次点の補完に使うプロバイダ名

Return values
string —

プレビューに使える HTML。上限超過・採用できない場合は空文字

resolve()

外部から取得する

protected resolve(string $url) : EmbedData

Why not: 拡張ポイント(extendsEmbedUnit 等)をここで発火させないのは、フックが 「埋め込みユニットの」拡張として名付けられており、ブロックエディタなど別の入口から 呼ばれたときにも発火してしまうため。発火はユニットモデル側に置く。

Why not private: fetch() / fetchWithRetryOnEmptyCache() のキャッシュ判定ロジックを 実ネットワーク接続(SsrfGuardedClient 経由)無しでテストするため、protected にして テストダブル(無名サブクラス)から差し替えられるようにする。

Parameters
$url : string
Return values
EmbedData

applyResponsiveStyle()

iframe の固定寸法をアスペクト比へ移し替える。

private applyResponsiveStyle(DOMElement $iframe) : bool
Parameters
$iframe : DOMElement
Return values
bool —

変換したら true(比率を計算できない場合は触らず false)

cacheKey()

private cacheKey(string $url) : string
Parameters
$url : string
Return values
string

ensureIframeLoading()

iframe に loading="lazy" が無ければ補完する。

private ensureIframeLoading(DOMElement $iframe) : bool

Why not 寸法が確定した iframe だけに限らないか: WordPress は width / height が両方 揃った iframe にしか lazy を付けない(寸法不明のまま遅延させると、ビューポートに入った 瞬間にレイアウトシフトが起きるため)。当サービスは applyResponsiveStyle が aspect-ratio かフォールバックの height で必ず領域を確保するので、その前提を常に満たす。

Why not ファーストビューを除外しないか: WordPress は LCP 悪化を避けるため本文先頭の 要素を除外するが、iframe は LCP の候補要素ではなく(iframe 内の画像は親フレームの LCP に 数えられない)、また展開時に本文中の位置が分からないため、一律で付与する。

Parameters
$iframe : DOMElement
Return values
bool —

補完したら true(プロバイダ指定の loading を尊重した場合は false)

ensureIframeTitle()

iframe に非空 title が無ければ補完する。

private ensureIframeTitle(DOMElement $iframe, string $title, string $providerName) : bool

プロバイダが title を省略した iframe は、スクリーンリーダー利用者に 「フレーム、名前なし」としか伝わらない(WCAG 2.4.1 達成方法 H64)。

Parameters
$iframe : DOMElement
$title : string

oEmbed から取得したタイトル

$providerName : string

oEmbed から取得したプロバイダ名

Return values
bool —

補完したら true(既存の title を尊重した場合は false)

fallbackHeight()

比率へ変換できない iframe の高さを、潰れない値へ退避させる。

private fallbackHeight(DOMElement $iframe) : bool

iframe { width: 100% } を当てる CSS 下では、height="100%" のような相対指定は 高さ auto の親に対して 0 になる。style に固定高さが既に書かれている場合は 提供元の意図を尊重して触らない。

Parameters
$iframe : DOMElement
Return values
bool —

変更したら true

finalize()

プロバイダーが返した結果を、保存してよい形へ確定させる。

private finalize(EmbedData $data) : EmbedData

HTML のサニタイズを必ずここで通すことで、プロバイダーはサニタイズを迂回できない。 拡張アプリが埋め込み先のホストを許可するには、プロバイダーの登録とは別に extends_html_purifier_iframe_allowed_hosts 等へホストを足す必要がある (「誰が解決するか」と「何を出力してよいか」を別の権限として分ける)。

Parameters
$data : EmbedData

プロバイダーが返した生の結果

Return values
EmbedData

hasMeaningfulEmbedTag()

サニタイズ後の HTML に、埋め込みとして意味のある要素が残っているか判定する。

private hasMeaningfulEmbedTag(string $html) : bool

iframe / script は src を失うと埋め込みとして機能しないので「残っている」とみなさない。 script を含めるのは、Threads や Bluesky のように blockquote の中身が空で、ウィジェットの script が後から描画する形式があるため(strip_tags だけでは「空」と判定されてしまう)。

Parameters
$html : string
Return values
bool

previewScriptPolicy()

プレビューで実行してよい外部 script の許可ホストを取得する

private previewScriptPolicy() : ScriptPolicy

extends_block_editor_embed_preview_script_allowed_hosts(拡張ポイント)をコア既定値の後ろに 連結する。ScriptPolicy::fromConfig() と同じく、コア既定値を残したまま追加できるようにするため。

Return values
ScriptPolicy

purify()

外部から取得した埋め込み HTML をサニタイズする

private purify(string $html) : string

サニタイズの設定・キャッシュ管理は HtmlPurifier サービスに委ねる。編集者入力向けの clean() ではなく cleanUntrusted()(HTML.Trusted / CSS.Trusted を落とし、許可要素を 絞ったプリセット)を通すことで、oEmbed 応答による UI 覆い被せを防ぐ。

Why not 自前で HTMLPurifier を組み立てないか: iframe の許可ホスト(IframePolicy)・ キャッシュディレクトリ・定義 ID をここで組み立てると、HtmlPurifier 側の設定変更に 追従が必要になり、キャッシュクリアの入口も増える(用途ごとに呼び出し元へ クリア処理を足すことになり漏れる)。設定を持つのは HtmlPurifier サービスだけに保つ。

Parameters
$html : string
Return values
string

removeScriptsNotAllowedBy()

サニタイズ済みの HTML から、src が許可ホストに一致しない script 要素を取り除く。

private removeScriptsNotAllowedBy(string $html, ScriptPolicy $policy) : string
Parameters
$html : string

サニタイズ済みの HTML

$policy : ScriptPolicy

残してよい script の許可ホスト

Return values
string

removeSrclessScriptTags()

src を持たない script 要素を取り除く。

private removeSrclessScriptTags(string $html) : string

サニタイズ後の script は「許可ホストの src を持つ外部 script」だけが意味を持つ。 許可ホスト外の src は属性ごと、インライン JS は中身ごと落ちて、空の <script></script> が 残るため、埋め込みとして機能しないそれらをここで掃除する。

Why not サニタイズ前に全ての script を落とさないか: 以前はそうしていたが、X / Instagram / Threads のように blockquote + script 形式でしか埋め込みを返さないプロバイダーに対応できない。 script の可否は許可ホストの whitelist(html_purifier_script_allowed_hosts)へ委ね、 ここでは「サニタイズを通り抜けたが実体の無いもの」だけを落とす。

Parameters
$html : string
Return values
string

        
On this page

Search results