public function mapFields(Content $content, $languageCode) { $fields = []; $contentType = $this->contentTypeHandler->load($content->versionInfo->contentInfo->contentTypeId); foreach ($content->fields as $field) { if ($field->languageCode !== $languageCode) { continue; } foreach ($contentType->fieldDefinitions as $fieldDefinition) { if ($fieldDefinition->id !== $field->fieldDefinitionId) { continue; } $fieldType = $this->fieldRegistry->getType($field->type); $indexFields = $fieldType->getIndexData($field, $fieldDefinition); foreach ($indexFields as $indexField) { if ($indexField->value === null) { continue; } $documentField = new Field($name = $this->fieldNameGenerator->getName($indexField->name, $fieldDefinition->identifier, $contentType->identifier), $indexField->value, $indexField->type); $this->appendField($fields, $fieldDefinition, $documentField); } } } return $fields; }
/** * Maps given Content fields to a map Document fields. * * @param \eZ\Publish\SPI\Persistence\Content $content * @param \eZ\Publish\SPI\Persistence\Content\Type $contentType * * @return \eZ\Publish\SPI\Search\Field[][][] */ protected function mapContentFields(Content $content, ContentType $contentType) { $fieldSets = array(); foreach ($content->fields as $field) { if (!isset($fieldSets[$field->languageCode])) { $fieldSets[$field->languageCode] = array('regular' => array(), 'fulltext' => array()); } foreach ($contentType->fieldDefinitions as $fieldDefinition) { if ($fieldDefinition->id !== $field->fieldDefinitionId) { continue; } $fieldType = $this->fieldRegistry->getType($field->type); $indexFields = $fieldType->getIndexData($field, $fieldDefinition); foreach ($indexFields as $indexField) { if ($indexField->value === null) { continue; } $documentField = new Field($name = $this->fieldNameGenerator->getName($indexField->name, $fieldDefinition->identifier, $contentType->identifier), $indexField->value, $indexField->type); if ($documentField->type instanceof FieldType\FullTextField) { $fieldSets[$field->languageCode]['fulltext'][] = $documentField; } else { $fieldSets[$field->languageCode]['regular'][] = $documentField; } } } } return $fieldSets; }
/** * Returns an array of documents containing fields for the given $content. * Each document contains fields for a single language. * * @param \eZ\Publish\SPI\Persistence\Content $content * @param \eZ\Publish\SPI\Persistence\Content\Type $contentType * * @return \eZ\Publish\Core\Search\Elasticsearch\Content\Document[] */ protected function mapFields(Content $content, Type $contentType) { $fieldMap = array(); foreach ($content->fields as $field) { $fieldMap[$field->languageCode][] = $field; } $fieldDocuments = array(); foreach (array_keys($fieldMap) as $languageCode) { $fields = array(); $fields[] = new Field('meta_language_code', $languageCode, new FieldType\StringField()); $fields[] = new Field('meta_is_main_translation', $content->versionInfo->contentInfo->mainLanguageCode === $languageCode, new FieldType\BooleanField()); $fields[] = new Field('meta_is_always_available', $content->versionInfo->contentInfo->mainLanguageCode === $languageCode && $content->versionInfo->contentInfo->alwaysAvailable, new FieldType\BooleanField()); foreach ($fieldMap[$languageCode] as $field) { foreach ($contentType->fieldDefinitions as $fieldDefinition) { if ($fieldDefinition->id !== $field->fieldDefinitionId) { continue; } $fieldType = $this->fieldRegistry->getType($field->type); $indexFields = $fieldType->getIndexData($field, $fieldDefinition); foreach ($indexFields as $indexField) { $fields[] = new Field($name = $this->fieldNameGenerator->getName($indexField->name, $fieldDefinition->identifier, $contentType->identifier), $indexField->value, $indexField->type); if ($indexField->type instanceof FieldType\StringField || $indexField->type instanceof FieldType\MultipleStringField) { $fields[] = new Field($name . "_meta_all_" . str_replace("-", "_", $languageCode), $indexField->value, $indexField->type); } } } } $fieldDocuments[] = new Document(array("fields" => $fields)); } return $fieldDocuments; }
/** * Returns index field name for the given parameters. * * @param object $criterionOrSortClause * @param string $contentTypeIdentifier * @param string $fieldDefinitionIdentifier * @param string $fieldTypeIdentifier * @param string $name * @param bool $isSortField * * @return string */ public function getIndexFieldName($criterionOrSortClause, $contentTypeIdentifier, $fieldDefinitionIdentifier, $fieldTypeIdentifier, $name, $isSortField) { // If criterion or sort clause implements CustomFieldInterface and custom field is set for // ContentType/FieldDefinition, return it if ($criterionOrSortClause instanceof CustomFieldInterface && ($customFieldName = $criterionOrSortClause->getCustomField($contentTypeIdentifier, $fieldDefinitionIdentifier))) { return [$customFieldName => null]; } // Else, generate field name from field type's index definition $indexFieldType = $this->fieldRegistry->getType($fieldTypeIdentifier); // If $name is not given use default field name if ($name === null) { if ($isSortField) { $name = $indexFieldType->getDefaultSortField(); } else { $name = $indexFieldType->getDefaultMatchField(); } } $indexDefinition = $indexFieldType->getIndexDefinition(); // Should only happen by mistake, so let's throw if it does if (!isset($indexDefinition[$name])) { throw new RuntimeException("Could not find '{$name}' field in '{$fieldTypeIdentifier}' field type's index definition"); } $field = $this->nameGenerator->getTypedName($this->nameGenerator->getName($name, $fieldDefinitionIdentifier, $contentTypeIdentifier), $indexDefinition[$name]); return [$field => $indexDefinition[$name]]; }
protected function writeField(XmlWriter $xmlWriter, Field $field) { foreach ((array) $this->fieldValueMapper->map($field) as $value) { $xmlWriter->startElement('field'); $xmlWriter->writeAttribute('name', $this->nameGenerator->getTypedName($field->name, $field->type)); $xmlWriter->text($value); $xmlWriter->endElement(); } }
/** * Converts given $document to a hash format that can be JSON encoded * to get a document _source. * * Implemented in a separate method because of a recursion needed to * handle nested documents. * * @param \eZ\Publish\Core\Search\Elasticsearch\Content\Document $document * * @return array */ protected function getDocumentHash(Document $document) { $hash = array(); foreach ($document->fields as $field) { if ($field->type instanceof DocumentField) { $documents = $this->fieldValueMapper->map($field); $values = array(); foreach ($documents as $document) { $values[] = $this->getDocumentHash($document); } } else { $values = (array) $this->fieldValueMapper->map($field); } $name = $this->nameGenerator->getTypedName($field->name, $field->type); if (count($values) === 1) { $hash[$name] = reset($values); } else { $hash[$name] = $values; } } return $hash; }
/** * Maps given Content to a Document. * * @param \eZ\Publish\SPI\Persistence\Content $content * @param \eZ\Publish\SPI\Persistence\Content\Type $contentType * @param boolean $indexFulltext * * @return \eZ\Publish\SPI\Search\Field[][] */ protected function mapContentFields(Content $content, ContentType $contentType, $indexFulltext) { $fieldSets = array(); foreach ($content->fields as $field) { foreach ($contentType->fieldDefinitions as $fieldDefinition) { if ($fieldDefinition->id !== $field->fieldDefinitionId) { continue; } $fieldType = $this->fieldRegistry->getType($field->type); $indexFields = $fieldType->getIndexData($field, $fieldDefinition); foreach ($indexFields as $indexField) { if ($indexField->value === null) { continue; } $fieldSets[$field->languageCode][] = new Field($name = $this->fieldNameGenerator->getName($indexField->name, $fieldDefinition->identifier, $contentType->identifier), $indexField->value, $indexField->type); if ($indexFulltext && $indexField->type instanceof FieldType\StringField) { $fieldSets[$field->languageCode][] = new Field($name . "_fulltext", $indexField->value, new FieldType\TextField()); } } } } return $fieldSets; }
/** * Map content to document. * * A document is an array of fields * * @param \eZ\Publish\SPI\Persistence\Content $content * * @return array */ protected function mapContent(Content $content) { $locations = $this->locationHandler->loadLocationsByContent($content->versionInfo->contentInfo->id); $section = $this->sectionHandler->load($content->versionInfo->contentInfo->sectionId); $mainLocation = null; $isSomeLocationVisible = false; $locationDocuments = array(); foreach ($locations as $location) { $locationDocuments[] = $this->mapLocation($location, $content, $section); if ($location->id == $content->versionInfo->contentInfo->mainLocationId) { $mainLocation = $location; } if (!$location->hidden && !$location->invisible) { $isSomeLocationVisible = true; } } // UserGroups and Users are Content, but permissions cascade is achieved through // Locations hierarchy. We index all ancestor Location Content ids of all // Locations of an owner. $ancestorLocationsContentIds = $this->getAncestorLocationsContentIds($content->versionInfo->contentInfo->ownerId); // Add owner user id as it can also be considered as user group. $ancestorLocationsContentIds[] = $content->versionInfo->contentInfo->ownerId; $fields = array(new Field('id', 'content' . $content->versionInfo->contentInfo->id, new FieldType\IdentifierField()), new Field('document_type', 'content', new FieldType\IdentifierField()), new Field('type', $content->versionInfo->contentInfo->contentTypeId, new FieldType\IdentifierField()), new Field('version', $content->versionInfo->versionNo, new FieldType\IdentifierField()), new Field('status', $content->versionInfo->status, new FieldType\IdentifierField()), new Field('name', $content->versionInfo->contentInfo->name, new FieldType\StringField()), new Field('creator', $content->versionInfo->creatorId, new FieldType\IdentifierField()), new Field('owner', $content->versionInfo->contentInfo->ownerId, new FieldType\IdentifierField()), new Field('owner_user_group', $ancestorLocationsContentIds, new FieldType\MultipleIdentifierField()), new Field('section', $content->versionInfo->contentInfo->sectionId, new FieldType\IdentifierField()), new Field('section_identifier', $section->identifier, new FieldType\IdentifierField()), new Field('section_name', $section->name, new FieldType\StringField()), new Field('remote_id', $content->versionInfo->contentInfo->remoteId, new FieldType\IdentifierField()), new Field('modified', $content->versionInfo->contentInfo->modificationDate, new FieldType\DateField()), new Field('published', $content->versionInfo->contentInfo->publicationDate, new FieldType\DateField()), new Field('language_code', array_keys($content->versionInfo->names), new FieldType\MultipleStringField()), new Field('main_language_code', $content->versionInfo->contentInfo->mainLanguageCode, new FieldType\StringField()), new Field('always_available', $content->versionInfo->contentInfo->alwaysAvailable, new FieldType\BooleanField()), new Field('some_location_visible', $isSomeLocationVisible, new FieldType\BooleanField())); if ($mainLocation !== null) { $fields[] = new Field('main_location', $mainLocation->id, new FieldType\IdentifierField()); $fields[] = new Field('main_location_parent', $mainLocation->parentId, new FieldType\IdentifierField()); $fields[] = new Field('main_location_remote_id', $mainLocation->remoteId, new FieldType\IdentifierField()); $fields[] = new Field('main_location_visible', !$mainLocation->hidden && !$mainLocation->invisible, new FieldType\BooleanField()); $fields[] = new Field('main_location_path', $mainLocation->pathString, new FieldType\IdentifierField()); $fields[] = new Field('main_location_depth', $mainLocation->depth, new FieldType\IntegerField()); $fields[] = new Field('main_location_priority', $mainLocation->priority, new FieldType\IntegerField()); } $contentType = $this->contentTypeHandler->load($content->versionInfo->contentInfo->contentTypeId); $fields[] = new Field('group', $contentType->groupIds, new FieldType\MultipleIdentifierField()); foreach ($content->fields as $field) { foreach ($contentType->fieldDefinitions as $fieldDefinition) { if ($fieldDefinition->id !== $field->fieldDefinitionId) { continue; } $fieldType = $this->fieldRegistry->getType($field->type); foreach ($fieldType->getIndexData($field) as $indexField) { if ($indexField->value === null) { continue; } $fields[] = new Field($this->fieldNameGenerator->getName($indexField->name, $fieldDefinition->identifier, $contentType->identifier), $indexField->value, $indexField->type); } } } $objectStateIds = array(); foreach ($this->objectStateHandler->loadAllGroups() as $objectStateGroup) { $objectStateIds[] = $this->objectStateHandler->getContentState($content->versionInfo->contentInfo->id, $objectStateGroup->id)->id; } $fields[] = new Field('object_state', $objectStateIds, new FieldType\MultipleIdentifierField()); $document = new Document(array("fields" => $fields, "documents" => $locationDocuments)); return $document; }