How to override existing Hibernate Validator? - hibernate-validator

I would like to override the built-in validator of #Email.
Reason: The built-in validator implements deprecated RFC 2822. I want to create custom validator that implements RFC 5322.
I know how to create custom constrain annotation e.g. #EmailRFC5322 with its validator, but I want to use existing #Email annotation with custom validator.

Custom validators for existing constraints can be provided either programmatically:
HibernateValidatorConfiguration configuration = Validation
.byProvider( HibernateValidator.class )
.configure();
ConstraintMapping constraintMapping = configuration.createConstraintMapping();
constraintMapping
.constraintDefinition( Email.class )
.includeExistingValidators( false )
.validatedBy( MyEmailValidator.class );
configuration.addMapping( constraintMapping );
Or it can also be done through xml:
<constraint-definition annotation="org.hibernate.validator.constraints.URL">
<validated-by include-existing-validators="false">
<value>org.hibernate.validator.constraintvalidators.RegexpURLValidator</value>
</validated-by>
</constraint-definition>
See this part of the documentation for more details

Related

Symfony 3 DateTimeType form field with an optional time component

Symfony3's DateTimeType can be set to either required or not, the same flag applies to both the date and time components.
Is there a way to make the time component optional/ e.g. if someone adds data to the date part, the value should be saved correctly, either by using some kind of empty_data attribute or with some custom configuration.
Edit: Using the DateTimeType as a compound choice element
You can always modify your data using form events:
Modify your incoming request to suit your needs:
$builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $evt) {
$data = $event->getData();
// modify data
$event->setData($data);
});

Is there a generic URL builder/manipulator in Drupal/Symfony?

How to build and/or modify generic URLs on Drupal/Symfony?
For example, having at the input an URL like: http://some.url/with?param1=value1#fragment I would like to be able to manipulate any parts of the url including:
cut off the query (search) part
add more query parameters
change the path part
replace domain
add/change fragment
etc
I couldn't find anything appropriate in Drupal or Symfony.
In Drupal 8 there is lib/Drupal/Core/Url.php class which provide some methods to get/set parameters
Availables methods to setting the route parameters:
setRouteParameters($parameters)
setRouteParameter($key, $value)
Availables methods to set the route options:
setOptions($options)
setOption($name, $value)
How to use the setParameter method:
/**
* #var Drupal\Core\Url $url
*/
$url->setRouteParameter('arg_0', $arg0);
With Symfony 3.3 you can use Request::create($url):
use Symfony\Component\HttpFoundation\Request;
$url = 'http://some.url/with?param1=value1#fragment'
$req = Request::create($url)
Then you can call
$req->getQueryString() // param1=value1
$req->getHost() // some.url
$req->getSchemeAndHttpHost() // http://some.url
$req->getBaseUrl() // /with
Ref http://api.symfony.com/3.3/Symfony/Component/HttpFoundation/Request.html
I don't think this class provides any setter for host/param/path so you can do the following:
str_replace($req->getHost(), 'new-host.com', $url) // change host
About the hash fragment #fragment, it doesn't seem to be available on server-side (see Get fragment (value after hash '#') from a URL in php).

SilverStripe edit gridfield success message on save

What's the easiest way to edit the default success message when saving an item in GridField edit view?
The message seems to be in a variable in class GridFieldDetailForm within method doSave.
$message = _t(
'GridFieldDetailForm.Saved',
'Saved {name} {link}',
array(
'name' => $this->record->i18n_singular_name(),
'link' => $link
)
);
Since the message uses the _t() function it will attempt to fetch the value defined in the lang file corresponding to the current user's locale. The default string defined in the function is just a fallback for when no translation could be found within the lang files.
To change the message you can update your site's yml lang file located in mysite/lang/{LANGUAGE_CODE}.yml
For english this would be:
# mysite/lang/en.yml
# remember to flush after editing me :-)
en:
GridFieldDetailForm:
Saved: 'My custom message using {name} and here is a link to the object: {link}'
https://docs.silverstripe.org/en/3.4/developer_guides/i18n/
Something like this should work for specific implementations
$form = $gridField->getConfig()->getComponentByType('GridFieldDetailForm');
$form->setItemEditFormCallback(function($form, $itemRequest)
{
// Replace save action with custom method in here
});
For more general implementations, you'll likely want to extend GridFieldDetailForm and override doSave, then replace the GridFieldDetailForm component with your custom class.

Drupal 8 create field programmatically

I created a custom module for Drupal 8 that allows the users to choose a Content type in order to add some fields programmatically.
How I can create some fields (text type in this case) and attach they to a Content type with a custom module?
Some help?
Thanks.
Checkout Field API for Drupal 8
It has several functions implemented and hook_entity_bundle_field_info might be what you need, here is an example of textfield from the docs of that hook
function hook_entity_bundle_field_info(\Drupal\Core\Entity\EntityTypeInterface $entity_type, $bundle, array $base_field_definitions) {
// Add a property only to nodes of the 'article' bundle.
if ($entity_type->id() == 'node' && $bundle == 'article') {
$fields = array();
$fields['mymodule_text_more'] = BaseFieldDefinition::create('string')
->setLabel(t('More text'))
->setComputed(TRUE)
->setClass('\Drupal\mymodule\EntityComputedMoreText');
return $fields;
}
}
You might also need Field Storage, checkout hook_entity_field_storage_info
You need to create FieldType, FieldWidget and FieldFormatter(If necessary), there are good examples in Core/Field/Plugin/Field.
There is a good example here https://www.drupal.org/node/2620964
You can use this module to create fields programmatically for any entity type and multiple bundles at once from custom YAML or JSON files:
https://drupal.org/project/field_create
The simplest approach for your module is to add your fields in the hook_field_create_definitions(). Simply create this function:
function mymodule_field_create_definitions_alter(&$definitions) {}

SonataAdminBundle - check changes in `preUpdate` hook

Is it possible to check if field was changed on preUpdate hook? I'm looking for something like preUpdate hasChangedField($fieldName) Doctrine functionality. Any ideas?
This question is a bit similar to this one
Your solution is just to compare the field of the old object with the new one and see where it differs.
So for example:
public function preUpdate($newObject)
{
$em = $this->getModelManager()->getEntityManager($this->getClass());
$originalObject = $em->getUnitOfWork()->getOriginalEntityData($newObject);
if ($newObject->getSomeField() !== $originalObject['fieldName']) {
// Field has been changed
}
}
For me the best approach is this in Sonata Admin:
$newField = $this->getForm()->get('field')->getData();
$oldField = $this->getForm()->get('field')->getConfig()->getData();
You shouldn't use unit of work unless there is no option. Also, if you have a not mapped field, you can't access it by entity object.
In a normal Doctrine lyfe cycle event, the best option is Doctrine preupdate event doc

Resources