-
The Symfony Input Validator no longer validates a
PatternMatch
value type. Set thepattern_match_constraints
option to validate this specific type, with it's own constraints.Note: A PatternMatch will likely not contain a full value, for more advanced validating it's best to create your own input validator.
- Translation ids have been changed to better fit there context, see translation in "lib/Core/Resources/translations" for new ids.
-
Support for PHP < 8.1 was dropped.
-
Support for Symfony 5 was dropped.
-
Support for Api-Platform 2.4 was dropped, 2.0-BETA2 of the components still supports all newer versions of RollerworksSearch.
-
Support for using a query as string was removed, a DBAL QueryBuilder is now required to be passed to the generator.
-
The
DoctrineDbalFactory::createCachedConditionGenerator()
method now requires a DBAL QueryBuilder and SearchCondition is provided instead of aConditionGenerator
instance. -
The
ConditionGenerator
now longer provides access to the generated condition and parameters. These are applied automatically when callingapply()
.// Doctrine\DBAL\Query\QueryBuilder object $qb = $connection->createQueryBuilder(); // Rollerworks\Component\Search\SearchCondition object $searchCondition = ...; $conditionGenerator = $doctrineDbalFactory->createConditionGenerator($qb, $searchCondition); // Set fields mapping // .... // Apply the condition (with ordering, if any) to the QueryBuilder $conditionGenerator->apply(); // Get all the records // See http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/data-retrieval-and-manipulation.html#data-retrieval $result = $qb->execute();
- Doctrine mapping type as object is deprecated and will no longer work in 3.0, use a type-name as string instead.
-
Support for PHP < 7.4 was dropped.
-
Support for Symfony 4 was dropped.
-
Support for PHPUnit < 9.5 was dropped.
-
Support for Elastica 6 was dropped.
-
Support for Elasticsearch 6 was dropped.
See the upgrade instructions of Elasticsearch itself for more information.
- Support for passing a
Doctrine\ORM\Query
object in the generators was removed, pass aDoctrine\ORM\QueryBuilder
object instead.
This BC change was required to make applying of result-ordering possible without worrying to much about details and edge-cases.
-
The methods
getWhereClause()
andgetParameters()
on the ConditionGenerators were removed. It's still possible to generate a stand-alone where-clause by using theDqlConditionGenerator
directly, but this is not officially supported nor documented. -
The
createCachedConditionGenerator
ofDoctrineOrmFactory
now expects a aQueryBuilder
andSearchCondition
are provided instead of a ConditionGenerator.Before:
$generator = $ormFactory->createConditionGenerator($query, $searchCondition); $generator = $ormFactory->createCachedConditionGenerator($generator, 60 * 60);
Now:
$generator = $ormFactory->createCachedConditionGenerator($query, $searchCondition, 60 * 60);
-
The
updateQuery()
method on the ConditionGenerators was renamed toapply()
and no longer supports a prepend for the query, as the query must now always be aQueryBuilder
.
- The
html5
option for theDateTimeType
has been removed. Only the RFC3339 for the norm-input format is supported now.
- The
$forceNew
argument inSearchConditionBuilder::field()
is deprecated and will be removed in v2.0.0-BETA1, useoverwriteField()
instead.
-
Support for SQLite was removed in Doctrine DBAL.
-
Values are no longer embedded but are now provided as parameters, make sure to bind these before executing the query.
Before:
$whereClause = $conditionGenerator->getWhereClause(); $statement = $connection->execute('SELECT * FROM tableName '.$whereClause); $rows = $statement->fetchAll(\PDO::FETCH_ASSOC);
Now:
$whereClause = $conditionGenerator->getWhereClause(); $statement = $connection->prepare('SELECT * FROM tableName '.$whereClause); $conditionGenerator->bindParameters($statement); $statement->execute(); $rows = $statement->fetchAll(\PDO::FETCH_ASSOC);
-
The
Rollerworks\Component\Search\Doctrine\Dbal\ValueConversion::convertValue()
method now expects astring
type is returned, and requires a return-type. -
Conversion strategies was changed to return a different column/value statement rather than keeping all strategies cached.
Use the
ConversionHint
new parameters and helper method to determine the value for the Column.
-
Support for Doctrine ORM NativeQuery was removed, use the Doctrine DBAL condition-generator instead for this usage.
-
Values are no longer embedded but are now provided as parameters, make sure to bind these before executing the query.
Note: Using the
updateQuery()
method already performs the binding process. -
Doctrine DBAL conversions are no longer applied, instead the Doctrine ORM integration now has it's own conversion API with a much more powerful integration.
Note: Any functions used in the conversion-generated DQL must be registered with the EntityManager configuration, refer to the Doctrine ORM manual for details.
-
The DataTransformers have been synchronized with the Symfony versions, which might cause some minor BC breakages.
- The
BaseNumberTransformer
has been removed, extend fromNumberToLocalizedStringTransformer
instead. - The
pattern
option ofDateTimeType
now only affects the view transformer, the norm transformer will use either theDateTimeToRfc3339Transformer
orDateTimeToHtml5LocalDateTimeTransformer
when thehtml5
option is set to true. - The
precision
option of theNumberType
has been renamed toscale
. - The
IntegerType
no longer accepts float values.
- The
-
The ArrayInput processor has been removed.
-
ApiPlatform SearchConditionListener no longer supports array-input. Use JSON or the NormStringQuery input-format instead.
-
The default restriction values of
ProcessorConfig
have been changed to provide a better default;- Maximum values per field is now 100 (was 1000)
- Maximum number of groups is now 10 (was 100)
- Nesting is now 5 (was 100)
Unless you must support a higher number of values it is advised to not increase these values.
-
The ConditionOptimizers have been removed.
-
The XmlInput processor has been removed.
-
The SearchProcessor Component has been removed, use an InputProcessor directly.
Before:
$inputProcessorLoader = Loader\InputProcessorLoader::create(); $conditionExporterLoader = Loader\ConditionExporterLoader::create(); $processor = new Psr7SearchProcessor($searchFactory, $inputProcessorLoader, $conditionExporterLoader); $request = ...; // A PSR-7 ServerRequestInterface object instance $processorConfig = new ProcessorConfig($userFieldSet); $searchPayload = $processor->processRequest($request, $processorConfig); if ($searchPayload->isChanged() && $searchPayload->isValid()) { header('Location: /search?search='.$searchPayload->searchCode); exit(); } if (!$payload->isValid()) { foreach ($payload->messages as $error) { echo (string) $error.PHP_EOL; } } // Notice: This is null when there are errors, when the condition is valid but has // no fields/values this is an empty SearchCondition object. $condition = $payload->searchCondition;
After:
// ... $inputProcessor = new StringQueryInput(); // Can be wrapped in a CachingInputProcessor $processorConfig = new ProcessorConfig($fieldSet); $request = ...; // A PSR-7 ServerRequestInterface object instance try { if ($request->getMethod() === 'POST') { $query = $request->getQueryParams()['search'] ?? ''; header('Location: /search?search='.$searchPayload->searchCode); exit(); // return new RedirectResponse($request->getRequestUri().'?search='.$query); } $query = $request->getParsedBody()['search'] ?? ''; $condition = $inputProcessor->process($processorConfig, $query); // Use condition } catch (InvalidSearchConditionException $e) { foreach ($e->getErrors() as $error) { echo (string) $error.PHP_EOL; } }
Note: The ArrayInput processor has been removed, only string-type input formats (StringInput and JsonInput) are supported now.
-
The
ApiSearchProcessor
has been removed. Internally theSearchConditionListener
now handles the user-input and error handling. -
The
SearchConditionListener
constructor has changed:Before:
SearchFactory $searchFactory SearchProcessor $searchProcessor UrlGeneratorInterface $urlGenerator ResourceMetadataFactory $resourceMetadataFactory EventDispatcherInterface $eventDispatcher
After:
SearchFactory $searchFactory InputProcessorLoader $inputProcessorLoader ResourceMetadataFactory $resourceMetadataFactory EventDispatcherInterface $eventDispatcher CacheInterface $cache = null
Note: The
$cache
argument is optional and only used when the$cacheTTL
of theProcessorConfig
is configured. -
Cache TTL configuration has been moved to
Rollerworks\Component\Search\Input\ProcessorConfig
, the metadata configuration format has remained unchanged. -
The Input format is now automatically detected by the first character. When the provided input starts with an
{
theJsonInput
processor is used, otherwise theNormStringQueryInput
processor is used. -
ArrayInput is deprecated and is internally delegated to the JsonInputProcessor.
In RollerworksSearch v2.0.0-ALPHA12 support for ArrayInput is completely removed and will throw an exception instead.
- The
Rollerworks\Component\Search\ApiPlatform\EventListener\SearchConditionListener
now requires anEventDispatchInterface
instance as last argument.
- The
Rollerworks\Component\Search\Doctrine\Dbal\StrategySupportedConversion::getConversionStrategy
method must now return an integer (and is enforced with a return-type).
-
Support for using Regex in ValueMatch has been removed.
-
The constants
PatternMatch::PATTERN_REGEX
andPatternMatch::PATTERN_NOT_REGEX
have been removed. -
The method
PatternMatch::isRegex
has been removed.
-
-
The
ValueComparison
namespaces and classes have been renamed toValueComparator
-
The
FieldConfig::setValueComparison
method has been renamed tosetValueComparator
-
The
FieldConfig::getValueComparison
method has been renamed togetValueComparator
-
Support PHP 5 has been dropped you need at least PHP 7.1.
-
Classes and interfaces now use strict type hints, considering the size of this change they are not listed in detail in this upgrade guide.
-
FilterQuery
is renamed toStringQuery
. -
The
single
value-type is renamed tosimple
. -
Field alias support has been removed. Now only the
StringQuery
input processor and exporter allow to use an alias (or the label) as field name. -
The
Interface
suffix has been removed from interfaces, conflicting classes have been renamed toGeneric
. Eg.SearchFactory
is nowGenericSearchFactory
. -
The Metadata/mapping system has been removed, creating reusable FieldSet's is now possible using
FieldSetConfigurator
s.namespace Acme\User\Search; use Rollerworks\Component\Search\Searches; use Rollerworks\Component\Search\FieldSetBuilder; use Rollerworks\Component\Search\FieldSetConfigurator; use Rollerworks\Component\Search\Extension\Core\Type as FieldType; class UsersFieldSet implements FieldSetConfigurator { public buildFieldSet(FieldSetBuilder $builder): void { $builder ->add('id', FieldType\IntegerType::class) ->add('last-name', FieldType\TextType::class) ->add('last-name', FieldType\TextType::class) } } // ... $searchFactory = Searches::createSearchFactory(); $userFieldSet = $searchFactory->createFieldSet(\Acme\User\Search\UsersFieldSet::class);
Note: If the FieldSetConfigurator has constructor dependencies, register it in a
FieldSetRegistry
instead. Eg. using theLazyFieldSetRegistry
:use Acme\User\Search\UsersFieldSet; use Rollerworks\Component\Search\Searches; use Rollerworks\Component\Search\LazyFieldSetRegistry; $fieldSetRegistery = LazyFieldSetRegistry::create([ UsersFieldSet::class => function () { return new UsersFieldSet(); } ]); $searchFactory = Searches::createSearchFactoryBuilder() ->setFieldSetRegistry($fieldSetRegistery) ->getSearchFactory();
-
A FieldSet is now immutable, use the
FieldSetBuilder
to semantically build a new FieldSet. -
The
FieldSet
interface was added, the oldFieldSet
class has been renamed toGenericFieldSet
.
-
The
XmlExporter
andJsonExporter
now exports the SearchCondition with the value's normalized format instead of the view format. -
The
StringQueryExporter
now allows to export the condition with newlines for better readability.
-
The
model_class
andmodel_property
options have been removed. Model configuration is no longer supported. -
The
FieldType
class has been renamed toSearchFieldType
. -
The
getBlockPrefix
method was added to theFieldType
interface, theSearchFieldType
"base" type automatically configures this based of the type's name and vendor namespace. -
The
DateTimeType
,DateType
,IntegerType
,NumberType
,TimestampType
andTimeType
were synchronized with the Symfony code base and may produce slightly different results then before.
-
The
choices_as_values
option of the ChoiceType has been removed. -
The view format can now be configured using the
norm_format
option. Which can be eithervalue
,label
orauto
(which uses the best value). -
Using callable strings as choice options in ChoiceType is not supported anymore in favor of passing
PropertyPath
instances.Before:
'choice_value' => new PropertyPath('range'), 'choice_label' => 'strtoupper',
After:
'choice_value' => 'range', 'choice_label' => function ($choice) { return strtoupper($choice); },
-
Caching of the loaded
ChoiceListInterface
in theLazyChoiceList
has been removed, it must be cached in theChoiceLoader
implementation instead.
-
The
MoneyType
now uses the MoneyPHP library for handling transformation and calculation. -
The
precession
option was removed, this is now based of the currency information. -
The
increase_by
option was added to configure with simple-values to range optimization.
Note: The MoneyPHP library is not installed by default, install the "moneyphp/money"
package with Composer to use the MoneyType
: composer install moneyphp/money
.
-
A number of field related classes were renamed and where moved to the
Field
namespace:AbstractFieldType
AbstractFieldTypeExtension
FieldConfig
(wasFieldConfigInterface
)FieldType
(wasFieldTypeInterface
)FieldTypeExtension
(wasFieldTypeExtensionInterface
)GenericResolvedFieldType
(wasResolvedFieldType
)GenericResolvedFieldTypeFactory
(wasResolvedFieldTypeFactory
)GenericTypeRegistry
(wasFieldRegistry
)ResolvedFieldType
(wasResolvedFieldTypeInterface
)ResolvedFieldTypeFactory
(wasResolvedFieldTypeFactoryInterface
)SearchField
SearchFieldView
TypeRegistry
(wasFieldRegistryInterface
)
-
The
SearchFieldView
now expects anFieldSetView
as the first argument in the class constructor. -
A search field no longer supports registering multiple transformers, each field can have exactly one "view" and/or "norm" transformer.
-
The
XmlInput
andJsonInput
now expect the input values to be in the normalized data format instead of the view format. -
The
XmlInput
andJsonInput
now more strictly validate provided input. -
The
StringQueryInput
has changed to a more user-friendly Lexer system:-
More User-friendly error messages.
-
All characters (except special syntax characters) can now be used without surrounding them with quotes.
12.00
is now accepted. -
Line numbers are now properly reported, and the column position is made more accurate.
-
Incorrectly escaped values will now give a friendly error message.
-
Spaces are no longer allowed between operators.
~ >
is invalid now.
-
-
The
StringQueryInput
now uses~
for ranges, eg.10 ~ 20
. -
The
StringQueryInput
PatternMatch no longer requires a specific order for the flags. Bothi!
and!i
are accepted now. -
The structure of the XML and JSON changed to adapt to the new value-holder naming. In short this means that
simple
is used now instead ofsingle
. -
Field values merging is has been removed. Using the field twice in a group now overwrites the previously defined value in that group.
- Validation is now performed directly during the input processing rather then
afterwards. As a result, the produced
SearchCondition
no longer holds any invalid value. See also error handling below.
Error handling for input processing has been completely rewritten, exceptions no longer require to be parsed for usage.
-
An Input processor now throws only an
InvalidSearchConditionException
for user-input errors. TheInvalidSearchConditionException
holds one or moreConditionErrorMessage
object instances. -
The produced
SearchCondition
no longer holds any invalid value, only when all values are valid aSearchCondition
is returned else anInvalidSearchConditionException
is thrown. -
The value-path of an error now depends on the structure of the input, XML uses XPath, while json uses an PropertyPath and StringQuery uses only value positions like
groups[0].fields['name']['value-position']
.
See the usage documentation for full instructions on handling user-input errors.
-
The
Rollerworks\Component\Search\Value\SingleValue
class has been removed, to add add a simple-value (as "model" format) useaddSimpleValue
method on theValuesBag
object. -
The
ValueHolder
is expected to a hold a "model" format of the value, eg. for a date-time input this is an\DateTimeImmutable
object, for an integer this is a PHP primitive integer value. -
All specific value methods have been removed.
You must replace specific method types with:
add()
,has()
,get()
andremove()
respectively. For example the Comparison value-type methods are used like:getComparisons()
becomesget(\Rollerworks\Component\Search\Value\Compare::class)
hasComparisons()
becomeshas(\Rollerworks\Component\Search\Value\Compare::class)
removeComparison(1)
becomesremove(\Rollerworks\Component\Search\Value\Compare::class, 1)
addComparisons(new Compare(..))
becomesadd(new Compare(..))
-
A
ValueHolder
no longer holds a "view" format, an Exporter must use the viewTransformer of the search field to get a view representation of the value. -
A SearchCondition's value structure cannot be locked anymore.
The following classes/interfaces and method have been removed:
-
Rollerworks\Component\Search\FieldConfig
:getModelRefClass()
getModelRefProperty()
-
Rollerworks\Component\Search\SearchFactory::createFieldForProperty()
-
Rollerworks\Component\Search\SearchField
:setRequired()
isRequired()
setModelRef()
getModelRefClass()
getModelRefProperty()
-
Rollerworks\Component\Search\Metadata\*
-
Rollerworks\Component\Search\Exception\FieldRequiredException
-
Rollerworks\Component\Search\Exception\ValuesStructureIsLocked
-
Rollerworks\Component\Search\FieldAliasResolverInterface
-
Rollerworks\Component\Search\FieldLabelResolverInterface
-
Rollerworks\Component\Search\SearchConditionInterface
-
Rollerworks\Component\Search\FieldAliasResolver\*
-
Rollerworks\Component\Search\ValuesBag
:setDataLocked()
isDataLocked()
ensureDataLocked()
ensureDataLocked()
-
Rollerworks\Component\Search\ValuesGroup
:setDataLocked()
isDataLocked()
throwLocked()