Учебник по схеме
Учебник по схемеУрок 6: Поиск, замена и повторное сохранение

Урок 6: Поиск, замена и повторное сохранение

Этот урок учебника содержит примеры адаптации контента с использованием поиска и замены с последующим сохранением ресурса обратно в БД.

Расширение 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-адреса, не окружённые тегом anchor, например:

<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) и модификаторы PRCE.

Замена HTTP на HTTPS

Этот GraphQL-запрос заменяет все URL с http на https в атрибутах источника HTML-изображений:

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
    }
  }
}