forked from sstok/gush-experiments-sandbox
-
Notifications
You must be signed in to change notification settings - Fork 0
/
SearchFactory.php
158 lines (137 loc) · 4.75 KB
/
SearchFactory.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
<?php
/*
* This file is part of the RollerworksSearch package.
*
* (c) Sebastiaan Stok <s.stok@rollerscapes.net>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Rollerworks\Component\Search;
use Rollerworks\Component\Search\Exception\UnexpectedTypeException;
use Rollerworks\Component\Search\Metadata\MetadataReaderInterface;
/**
* @author Sebastiaan Stok <s.stok@rollerscapes.net>
*/
class SearchFactory implements SearchFactoryInterface
{
/**
* @var FieldRegistryInterface
*/
private $registry;
/**
* @var MetadataReaderInterface
*/
private $metadataReader;
/**
* @var ResolvedFieldTypeFactoryInterface
*/
private $resolvedTypeFactory;
/**
* Constructor.
*
* @param FieldRegistryInterface $registry
* @param ResolvedFieldTypeFactoryInterface $resolvedTypeFactory
* @param MetadataReaderInterface $metadataReader
*/
public function __construct(FieldRegistryInterface $registry, ResolvedFieldTypeFactoryInterface $resolvedTypeFactory, MetadataReaderInterface $metadataReader = null)
{
$this->registry = $registry;
$this->resolvedTypeFactory = $resolvedTypeFactory;
$this->metadataReader = $metadataReader;
}
/**
* {@inheritdoc}
*/
public function createField($name, $type, array $options = [])
{
$field = $this->createFieldBuilder($name, $type, $options);
return $field;
}
/**
* Create a new search field referenced by property.
*
* @param string $class Model reference class-name
* @param string $property Model reference property-name
* @param string $name Name of the field
* @param string $type Type of the field
* @param array $options Array of options for building the field
*
* @return SearchField
*
* @deprecated Deprecated since version 1.0.0-beta5, to be removed in 2.0.
* Use createField() with the 'model_class' and 'model_property'
* options instead.
*/
public function createFieldForProperty($class, $property, $name, $type, array $options = [])
{
$field = $this->createFieldBuilder($name, $type, $options);
$field->setModelRef($class, $property);
return $field;
}
/**
* {@inheritdoc}
*/
public function createFieldSetBuilder($name)
{
$fieldSetBuilder = new FieldSetBuilder($name, $this, $this->metadataReader);
return $fieldSetBuilder;
}
/**
* Creates a new {@link SearchField} instance.
*
* @param string $name
* @param string|FieldTypeInterface $type
* @param array $options
*
* @throws UnexpectedTypeException
*
* @return SearchField
*/
private function createFieldBuilder($name, $type = 'field', array $options = [])
{
if ($type instanceof FieldTypeInterface) {
$type = $this->resolveType($type);
} elseif (is_string($type)) {
$type = $this->registry->getType($type);
} elseif (!$type instanceof ResolvedFieldTypeInterface) {
throw new UnexpectedTypeException(
$type,
[
'string',
'Rollerworks\Component\Search\ResolvedFieldTypeInterface',
'Rollerworks\Component\Search\FieldTypeInterface',
]
);
}
$field = $type->createField($name, $options);
// Explicitly call buildType() in order to be able to override either
// createField() or buildType() in the resolved field type
$type->buildType($field, $field->getOptions());
return $field;
}
/**
* Wraps a type into a ResolvedFieldTypeInterface implementation and connects
* it with its parent type.
*
* @param FieldTypeInterface $type The type to resolve
*
* @return ResolvedFieldTypeInterface The resolved type
*/
private function resolveType(FieldTypeInterface $type)
{
$parentType = $type->getParent();
if ($parentType instanceof FieldTypeInterface) {
$parentType = $this->resolveType($parentType);
} elseif (null !== $parentType) {
$parentType = $this->registry->getType($parentType);
}
return $this->resolvedTypeFactory->createResolvedType(
$type, // Type extensions are not supported for unregistered type instances,
// i.e. type instances that are passed to the SearchFactory directly,
// nor for their parents, if getParent() also returns a type instance.
[],
$parentType
);
}
}