スキーマチュートリアル
スキーマチュートリアルレッスン6:検索・置換して再保存する

レッスン6:検索・置換して再保存する

このチュートリアルレッスンでは、検索・置換を行い、リソースをDBに再保存するコンテンツ変換の例を紹介します。

PHP Functions via Schema 拡張機能は、以下の「検索・置換」フィールドを提供します:

  • _strReplace:文字列を別の文字列に置換する
  • _strReplaceMultiple:文字列のリストを別の文字列のリストに置換する
  • _strRegexReplace:正規表現を使用して置換対象の文字列を検索する
  • _strRegexReplaceMultiple:正規表現のリストを使用して置換対象の文字列を検索する
  • _strArrayReplace:配列内の文字列を別の文字列に置換する
  • _strArrayReplaceMultiple:配列内の文字列のリストを別の文字列のリストに置換する

文字列の検索・置換

このGraphQLクエリは投稿を取得し、投稿のコンテンツとタイトル内に含まれる特定の文字列をすべて別の文字列に置換した後、投稿を再保存します:

query GetPostData(
  $postId: ID!
  $replaceFrom: String!,
  $replaceTo: String!
) {
  post(by: { id: $postId }) {
    title
    adaptedPostTitle: _strReplace(
      search: $replaceFrom
      replaceWith: $replaceTo
      in: $__title
    )
      @export(as: "adaptedPostTitle")
 
    rawContent
    adaptedRawContent: _strReplace(
      search: $replaceFrom
      replaceWith: $replaceTo
      in: $__rawContent
    )
      @export(as: "adaptedRawContent")
  }
}
 
mutation UpdatePost($postId: ID!)
  @depends(on: "GetPostData")
{
  updatePost(input: {
    id: $postId,
    title: $adaptedPostTitle,
    contentAs: { html: $adaptedRawContent },
  }) {
    status
    errors {
      __typename
      ...on ErrorPayload {
        message
      }
    }
    post {
      id
      title
      rawContent
    }
  }
}

クエリを実行するには、検索・置換する文字列を含む variables の辞書を指定します:

{
  "postId": 1,
  "replaceFrom": "Old string",
  "replaceTo": "New string"
}

複数の文字列の検索・置換

上記と同じクエリですが、_strReplaceMultiple を使用することで、文字列のリストを別の文字列のリストに置換できます:

query GetPostData(
  $postId: ID!
  $replaceFrom: [String!]!,
  $replaceTo: [String!]!
) {
  post(by: { id: $postId }) {
    title
    adaptedPostTitle: _strReplaceMultiple(
      search: $replaceFrom
      replaceWith: $replaceTo
      in: $__title
    )
      @export(as: "adaptedPostTitle")
 
    rawContent
    adaptedRawContent: _strReplaceMultiple(
      search: $replaceFrom
      replaceWith: $replaceTo
      in: $__rawContent
    )
      @export(as: "adaptedRawContent")
  }
}
 
mutation UpdatePost($postId: ID!)
  @depends(on: "GetPostData")
{
  updatePost(input: {
    id: $postId,
    title: $adaptedPostTitle,
    contentAs: { html: $adaptedRawContent },
  }) {
    status
    errors {
      __typename
      ...on ErrorPayload {
        message
      }
    }
    post {
      id
      title
      rawContent
    }
  }
}

variables の辞書には、検索・置換する文字列のリストを指定します:

{
  "postId": 1,
  "replaceFrom": ["Old string 2", "Old string 2"],
  "replaceTo": ["New string1", "New string 2"]
}

欠落しているリンクの追加

このGraphQLクエリは、正規表現による検索・置換を使って、投稿のHTMLコンテンツに欠落しているリンクを追加します:

query GetPostData($postId: ID!) {
  post(by: { id: $postId }) {
    id
    rawContent
    adaptedRawContent: _strRegexReplace(
      searchRegex: "#\\s+((https?)://(\\S*?\\.\\S*?))([\\s)\\[\\]{},;\"\\':<]|\\.\\s|$)#i"
      replaceWith: "<a href=\"$1\" target=\"_blank\">$3</a>$4"
      in: $__rawContent
    )
      @export(as: "adaptedRawContent")
  }
}
 
mutation UpdatePost($postId: ID!)
  @depends(on: "GetPostData")
{
  updatePost(input: {
    id: $postId,
    contentAs: { html: $adaptedRawContent },
  }) {
    status
    errors {
      __typename
      ...on ErrorPayload {
        message
      }
    }
    post {
      id
      title
      rawContent
    }
  }
}

次のように、アンカータグで囲まれていないすべてのURLは:

<p>Visit my website: https://mysite.com.</p>

...対応する <a> タグが追加され(テキストからドメインを除去し、新しいウィンドウで開くための target も付与されます)、次のようになります:

<p>Visit my website: <a href="https://mysite.com" target="_blank">mysite.com</a>.</p>
  • "\" 文字は、正規表現パターン内で "\\" としてエスケープする必要があります。たとえば、"/^https?:\/\//""/^https?:\\/\\//"と記述します
  • PHP関数 preg_replace のドキュメントでは、置換参照(例:$1)および PCREモディファイア の使い方を説明しています。

HTTPをHTTPSに置換する

このGraphQLクエリは、HTMLの画像ソース内にある http URLをすべて https に置換します:

query GetPostData($postId: ID!) {
  post(by: {id: $postId}) {
    id
    rawContent
    adaptedRawContent: _strRegexReplace(
      searchRegex: "/<img(\\s+)?([^>]*?\\s+?)?src=([\"'])http:\\/\\/(.*?)/"
      replaceWith: "<img$1$2src=$3https://$4$3"
      in: $__rawContent
    )
      @export(as: "adaptedRawContent")
  }
}
 
mutation UpdatePost($postId: ID!)
  @depends(on: "GetPostData")
{
  updatePost(input: {
    id: $postId,
    contentAs: { html: $adaptedRawContent },
  }) {
    status
    errors {
      __typename
      ...on ErrorPayload {
        message
      }
    }
    post {
      id
      title
      rawContent
    }
  }
}