Skip to content

Instantly share code, notes, and snippets.

@wodor
Created September 1, 2017 14:20
Show Gist options
  • Select an option

  • Save wodor/8955af078d45fe8f0474830d16b488f2 to your computer and use it in GitHub Desktop.

Select an option

Save wodor/8955af078d45fe8f0474830d16b488f2 to your computer and use it in GitHub Desktop.
<?php
use DOMDocument;
use DOMNode;
use eZ\Publish\API\Repository\ContentService;
use eZ\Publish\API\Repository\ContentTypeService;
use eZ\Publish\API\Repository\Repository;
use eZ\Publish\API\Repository\Values\Content\Field as ContentField;
use eZ\Publish\SPI\Persistence\Content as SPIContent;
use eZ\Publish\API\Repository\Values\Content\Content as APIContent;
use eZ\Publish\SPI\Search\FieldType\TextField;
use EzSystems\EzPlatformSolrSearchEngine\FieldMapper\ContentFieldMapper;
use eZ\Publish\SPI\Search\Field;
class FullTextRelatedFields extends ContentFieldMapper
{
/**
* @var ContentTypeService
*/
private $contentTypeService;
/**
* @var ContentService
*/
private $contentService;
/**
* @var Repository
*/
private $repository;
/**
* @var array
*/
private $contentTypes;
/**
* @var array
*/
private $contentTypeIds;
public function __construct(ContentTypeService $contentTypeService, ContentService $contentService, Repository $repository)
{
foreach (['news_article', 'story_article'] as $contentTypeIdentifier) {
$contentType = $contentTypeService->loadContentTypeByIdentifier($contentTypeIdentifier);
$this->contentTypes[$contentTypeIdentifier] = $contentType;
$this->contentTypeIds[$contentTypeIdentifier] = $contentType->id;
}
$this->contentTypeService = $contentTypeService;
$this->contentService = $contentService;
$this->repository = $repository;
}
/**
* Indicates if the mapper accepts the given $content for mapping.
*
* @param \eZ\Publish\SPI\Persistence\Content $content
*
* @return bool
*/
public function accept(SPIContent $content)
{
$contentInfo = $content->versionInfo->contentInfo;
return in_array($contentInfo->contentTypeId, $this->contentTypeIds);
}
/**
* Maps given $content to an array of search fields.
*
* @param \eZ\Publish\SPI\Persistence\Content $content
*
* @return \eZ\Publish\SPI\Search\Field[]
*/
public function mapFields(SPIContent $content)
{
$contentInfo = $content->versionInfo->contentInfo;
$articleContent = $this->sudoLoadContent($contentInfo->id);
$contentInfo->contentTypeId;
return [
new Field(
'textsearch_body',
$this->getRichtextValue($articleContent, 'body'),
new TextField()
),
new Field(
'textsearch_headline',
$articleContent->getFieldValue('headline'),
new TextField()
),
];
}
/**
* @param int $contentId
*
* @return APIContent
*/
private function sudoLoadContent(int $contentId): APIContent
{
$contentService = $this->contentService;
return $this->repository->sudo(
function () use ($contentService, $contentId): APIContent {
return $contentService->loadContent($contentId);
}
);
}
/**
* @param $articleContent
* @return string
*/
private function getRichtextValue($articleContent, $fieldName)
{
$field = $articleContent->getField($fieldName);
if (!$field instanceof ContentField) {
return '';
}
$document = new DOMDocument();
$document->loadXML($field->value);
$bodyValue = $this->extractText($document->documentElement);
return $bodyValue;
}
/**
* Extracts text content of the given $node.
* borrowed from \eZ\Publish\Core\FieldType\RichText\SearchField
*
* @param \DOMNode $node
*
* @return string
*/
private function extractText(DOMNode $node)
{
$text = '';
if ($node->childNodes) {
foreach ($node->childNodes as $child) {
$text .= $this->extractText($child);
}
} else {
$text .= $node->nodeValue . ' ';
}
return $text;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment