CoderFunda
  • Home
  • About us
    • Contact Us
    • Disclaimer
    • Privacy Policy
    • About us
  • Home
  • Php
  • HTML
  • CSS
  • JavaScript
    • JavaScript
    • Jquery
    • JqueryUI
    • Stock
  • SQL
  • Vue.Js
  • Python
  • Wordpress
  • C++
    • C++
    • C
  • Laravel
    • Laravel
      • Overview
      • Namespaces
      • Middleware
      • Routing
      • Configuration
      • Application Structure
      • Installation
    • Overview
  • DBMS
    • DBMS
      • PL/SQL
      • SQLite
      • MongoDB
      • Cassandra
      • MySQL
      • Oracle
      • CouchDB
      • Neo4j
      • DB2
      • Quiz
    • Overview
  • Entertainment
    • TV Series Update
    • Movie Review
    • Movie Review
  • More
    • Vue. Js
    • Php Question
    • Php Interview Question
    • Laravel Interview Question
    • SQL Interview Question
    • IAS Interview Question
    • PCS Interview Question
    • Technology
    • Other

05 April, 2024

Symfony custom field type with data transformer not working properly when in an embedded collection form

 Programing Coderfunda     April 05, 2024     No comments   

I am having a problem in Symfony with a custom data transformer on a custom form field - but only when this is used in a collection/embedded form within my main form. If I use the same custom field type and transformer for field directly in the main form, then it works perfectly.
Basically I have an app that is a database of all of my music/films/etc. Each item is stored in an entity called AVItem. For each of these items I can have zero or more tracks and I do this with a CollectionType. Within this embedded form/collection I have simple text fields and also a Collection of EntityType and they all work perfectly when submitting the main form; however, only the one field that uses my custom field type and transformer does not.
My custom field is for a "duration". In the database I save any lengths of time purely as an integer of seconds; however, I display it and want it entered as a string in the form [HH:]mm:ss. When displaying, the custom field and transformer works, it reads the number of seconds from the entity and then the "transform" method correctly displays that as HH:mm:ss. However, when I submit the main form and one of those tracks has something entered into it, when the "reverseTransform" method is called, the value it receives is always null!
However, in my main entity, where I also have a filled called "totalRunningTime" which also uses the same custom field type and transformer, the transform and reverseTransform always work perfectly.
This seems to be an issue purely within the Collection/embedded form.
Does anyone have an ideas?
Here are some code snippets.


This is my custom data transformer:
class TimeDurationTransformer implements DataTransformerInterface
{
private ?string $invalidMessage = null;

public function __construct( ?string $invalidMessage = null )
{
$this->invalidMessage = $invalidMessage;
}

/**
* Transform an integer (number of seconds) into a string of the form HH:mm:ss.
*
* @param mixed $value
* @return mixed
*/
public function transform( mixed $value ) : mixed
{
if ( ( null === $value ) || ( intval( $value ) == 0 ) ):
return null;
endif;

return sprintf( '%02d:%02d:%02d', ( $value/ 3600 ), ( $value / 60 % 60 ), ( $value% 60 ) );
}

/**
* Transform a string of the form HH:mm:ss into a number of seconds as an integer.
*
* @param mixed $value
* @return mixed
*/
public function reverseTransform( mixed $value ) : mixed
{
if ( ( null === $value ) || empty( $value ) || ( strlen( $value ) < 1 ) ) :
return null;
endif;

$matchResult = preg_match( pattern: '/^((\d{1,3}):)?(\d{1,2}):(\d{1,2})$/', subject: $value, matches: $matches, flags: PREG_UNMATCHED_AS_NULL );
// If the string entered does not match the pattern, throw an exception
if ( ( false === $matchResult) || ( 0 === $matchResult ) ) :
throw new TransformationFailedException( message: $this->invalidMessage, invalidMessage: $this->invalidMessage );
else:
if ( $matchResult === 1 && ( count( $matches ) == 5 ) ) :
if ( round( $matches[4] ) != null ):
return( round( $matches[4] ) + ( $matches[3] ? ( $matches[3] * 60 ) : 0 ) + ( $matches[3] ? ( $matches[2] * 3600 ) : 0 ) );
endif;
endif;
throw new TransformationFailedException( message: $this->invalidMessage, invalidMessage: $this->invalidMessage );
endif;
}
}



This is my custom field type:
class TimeDurationType extends AbstractType
{
private $translator;

public function __construct( TranslatorInterface $translator ) {
$this->translator = $translator;
}

public function buildForm( FormBuilderInterface $builder, array $options ) : void
{
$builder->addModelTransformer( new StuggiBearTimeDurationTransformer( invalidMessage: $options[ 'invalid_message' ] ) );
}

public function configureOptions( OptionsResolver $resolver ): void
{
$resolver->setDefaults( [
'data_class' => null,
'required' => false,
'constraints' => [
new PositiveOrZero(),
],
'invalid_message' => $this->translator->trans( 'message.assert.time_duration_format' ),
'attr' => [
'placeholer' => '',
],
] );
}

public function getParent(): string
{
return TextType::class;
}
}



Within my main form for my entity AVItem, I have one field that uses this custom field type - and it works fine:
public function buildForm( FormBuilderInterface $builder, array $options ): void
{
$this->editType = $options['edit_type'];
$this->isWishlistItem = $options[ 'isWishlistItem' ];

$builder
...
->add( 'totalRunningTime', TimeDurationType::class, [
'required' => false,
'label' => $this->translator->trans( 'form.field.label.total_running_time' ),
'label_html' => true,
'attr' => [
'placeholder' => 'HH:mm:ss',
],
'empty_data' => null,
] )
...



Within this form I then have the collection of Tracks:
$builder
...

->add( 'tracks', CollectionType::class, [
'label' => $this->translator->trans( 'form.field.label.tracks' ),
'label_html' => true,
'entry_type' => TrackEmbeddedFormType::class,
'entry_options' => [
'label' => false,
],
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
'empty_data' => [],
] )
...



...and then the embedded form type for the tracks:
$builder
->add( 'seriesEpisodeNumber', null, [
'required' => false,
'label' => $this->translator->trans( 'form.field.label.atce_series_episode_number' ),
] )
->add( 'title', null, [
'required' => ( $this->editType == FormEditType::SEARCH ) ? false : true,
'label' => $this->translator->trans( 'form.field.label.atce_title' ),
'label_html' => true,
] )
->add( 'additionalArtistsActors', EntityType::class, [
'required' => false,
'label' => $this->translator->trans( 'form.field.label.atce_additional_artists_actors' ),
'mapped' => true,
'class' => PersonGroup::class,
'by_reference' => true,
'multiple' => true,
'expanded' => false,
'choices' => [],
] )
->add( 'comment', null, [
'required' => false,
'mapped' => true,
'label' => $this->translator->trans( 'form.field.label.atce_comment' ),
'label_html' => true,
] )
->add( 'trackChapterNumber', null, [
'required' => true,
'label' => $this->translator->trans( 'form.field.label.atce_number' ),
'label_html' => true,
] )
->add( 'duration', TimeDurationType::class, [
'required' => false,
'label' => $this->translator->trans( 'form.field.label.atce_duration' ),
'label_html' => true,
'attr' => [
'placeholder' => 'HH:mm:ss',
],
'empty_data' => null,
] );
...



So, as I mentioned, the field "totalRunningTime" works perfectly with the data transformer, converting between integer seconds and a HH:mm:ss string and back.
However, the "duration" field within my collection/embedded tracks form only works reading from the database (the "transform" function works), but when I go to submit the form, the "reverseTransform" function always receives null.


If I change this field to be one of the standard types such as TextType or the like, then the value from the field seems to get passed.


Any help would be greatly appreciated.
  • Share This:  
  •  Facebook
  •  Twitter
  •  Google+
  •  Stumble
  •  Digg
Email ThisBlogThis!Share to XShare to Facebook

Related Posts:

  • PHP : Introduction for PHPPHP : Introduction for PHPPHP : Hello WorldPHP : VariablesPHP : Comments in PHPPHP : Echo and printPHP : ConstantsPHP : OperatorsPHP : LoopsPHP : Cont… Read More
  • Sending Email in HindiPHP में mail() function ये बहुत ही महत्वपूर्ण हिस्सा है | PHP के mail() function plain text, HTML या कुछ attachments messages भेजे जाते है |Syntax for… Read More
  • $ SESSION-Superglobal in HindiWhat is a Session in PHP ?जब Web Server कोई information store करनी हो तो PHP Sessions का इस्तेमाल किया जाता है |Sessions पर store की हुई information क… Read More
  • File Handling in PHP in HindiFile Handling in PHP in HindiFile Handling ये PHP में बहुत ही महत्वपूर्ण हिस्सा है | PHP में File Handling में creating file, opening file, Reading fi… Read More
  • Tutorial of LaravelAbout the TutorialLaravel is a powerful MVC PHP framework, designed for developers who need a simple and elegant toolkit to create full-featured web a… Read More
Newer Post Older Post Home

0 comments:

Post a Comment

Thanks

Meta

Popular Posts

  • Spring boot app (error: method getFirst()) failed to run at local machine, but can run on server
    The Spring boot app can run on the online server. Now, we want to replicate the same app at the local machine but the Spring boot jar file f...
  • Log activity in a Laravel app with Spatie/Laravel-Activitylog
      Requirements This package needs PHP 8.1+ and Laravel 9.0 or higher. The latest version of this package needs PHP 8.2+ and Laravel 8 or hig...
  • Vue3 :style backgroundImage not working with require
    I'm trying to migrate a Vue 2 project to Vue 3. In Vue 2 I used v-bind style as follow: In Vue 3 this doesn't work... I tried a...
  • Laravel auth login with phone or email
          <?php     Laravel auth login with phone or email     <? php     namespace App \ Http \ Controllers \ Auth ;         use ...
  • Enabling authentication in swagger
    I created a asp.net core empty project running on .net6. I am coming across an issue when I am trying to enable authentication in swagger. S...

Categories

  • Ajax (26)
  • Bootstrap (30)
  • DBMS (42)
  • HTML (12)
  • HTML5 (45)
  • JavaScript (10)
  • Jquery (34)
  • Jquery UI (2)
  • JqueryUI (32)
  • Laravel (1017)
  • Laravel Tutorials (23)
  • Laravel-Question (6)
  • Magento (9)
  • Magento 2 (95)
  • MariaDB (1)
  • MySql Tutorial (2)
  • PHP-Interview-Questions (3)
  • Php Question (13)
  • Python (36)
  • RDBMS (13)
  • SQL Tutorial (79)
  • Vue.js Tutorial (68)
  • Wordpress (150)
  • Wordpress Theme (3)
  • codeigniter (108)
  • oops (4)
  • php (853)

Social Media Links

  • Follow on Twitter
  • Like on Facebook
  • Subscribe on Youtube
  • Follow on Instagram

Pages

  • Home
  • Contact Us
  • Privacy Policy
  • About us

Blog Archive

  • September (100)
  • August (50)
  • July (56)
  • June (46)
  • May (59)
  • April (50)
  • March (60)
  • February (42)
  • January (53)
  • December (58)
  • November (61)
  • October (39)
  • September (36)
  • August (36)
  • July (34)
  • June (34)
  • May (36)
  • April (29)
  • March (82)
  • February (1)
  • January (8)
  • December (14)
  • November (41)
  • October (13)
  • September (5)
  • August (48)
  • July (9)
  • June (6)
  • May (119)
  • April (259)
  • March (122)
  • February (368)
  • January (33)
  • October (2)
  • July (11)
  • June (29)
  • May (25)
  • April (168)
  • March (93)
  • February (60)
  • January (28)
  • December (195)
  • November (24)
  • October (40)
  • September (55)
  • August (6)
  • July (48)
  • May (2)
  • January (2)
  • July (6)
  • June (6)
  • February (17)
  • January (69)
  • December (122)
  • November (56)
  • October (92)
  • September (76)
  • August (6)

  • Failed to install 'cordova-plugin-firebase': CordovaError: Uh oh - 9/21/2024
  • pyspark XPath Query Returns Lists Omitting Missing Values Instead of Including None - 9/20/2024
  • SQL REPL from within Python/Sqlalchemy/Psychopg2 - 9/20/2024
  • MySql Explain with Tobias Petry - 9/20/2024
  • How to combine information from different devices into one common abstract virtual disk? [closed] - 9/20/2024

Laravel News

  • Chargebee Starter Kit for Billing in Laravel - 5/20/2025
  • Streamline Pipeline Cleanup with Laravel's finally Method - 5/18/2025
  • Validate Controller Requests with the Laravel Data Package - 5/19/2025
  • Deployer - 5/18/2025
  • Transform JSON into Typed Collections with Laravel's AsCollection::of() - 5/18/2025

Copyright © 2025 CoderFunda | Powered by Blogger
Design by Coderfunda | Blogger Theme by Coderfunda | Distributed By Coderfunda