symfony 3.4 : forms : Use Data Transformers - forms

trying to use data transformer, I have an error when loadding my html form
In my formType class
use Doctrine\ORM\EntityManagerInterface;
class PmpType extends AbstractType
{
private $entityManager;
public function __construct(EntityManagerInterface $entityManager)
{
$this->entityManager = $entityManager;
}
}
in my app\config\services.yml
services:
# default configuration for services in *this* file
_defaults:
# automatically injects dependencies in your services
autowire: true
# automatically registers your services as commands, event subscribers, etc.
autoconfigure: true
# this means you cannot fetch services directly from the container via $container->get()
# if you need to do this, you can override this setting on individual services
public: true
but I received this error
Type error: Too few arguments to function myApp\Bundle\Form\PmpType::__construct(), 0 passed in \vendor\symfony\symfony\src\Symfony\Component\Form\FormRegistry.php on line 92 and exactly 1 expected
What do I miss
Thx for hepl

OK
I don't understand why but I have toset the service for my class :
in service.yml, I add
seims_pmp.pmptype:
class: SEISM\PmpIG56Bundle\Form\PmpType
arguments: ["#doctrine.orm.entity_manager"]
tags: [form.type]
and now it's working

Related

symfony6 $this->container->get('app.our.useful.thing')

I am sorry, I read the docs, but I don't get symfony6 anymore.
services:
# default configuration for services in *this* file
_defaults:
autowire: true # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
App\:
resource: '../src/'
exclude:
- '../src/DependencyInjection/'
- '../src/Entity/'
- '../src/Kernel.php'
- '../src/EventListener
app.our.useful.thing:
class: App\OurUsefulThing
public: true
My src/OurUsefulThing.php:
<?php
namespace App;
class OurUsefulThing
{
public function sayHello()
{
return "Hello Service";
}
}
In the controller:
public function someActionName(Request $request)() {
$value = $this->container->get('app.our.useful.thing')->sayHello();
}
Error Message
Service "app.our.useful.thing" not found: even though it exists in the app's container, the container inside "App\Controller\CategoriesController" is a smaller service locator that only knows about the "form.factory", "http_kernel", "parameter_bag", "request_stack", "router", "security.authorization_checker", "security.csrf.token_manager", "security.token_storage", "serializer" and "twig" services. Try using dependency injection instead.
It was in symfony4 so easy. What I am doing wrong?

Symfony 4 argument has no type-hint, you should configure its value explicitly

Symfony 4.2.3
Recently upgraded from version 3.4 to 4.2.3 and got my project working, but
when setting autoconfigure in services.yaml to true, I will receive this error message:
Cannot autowire service "App\EventListener\RedirectToLocaleActiveListener": argument "$localeActive" of method "__construct()" has no type-hint, you should configure its value explicitly.
My services.yaml
parameters:
locale: de
locale_active: de
app_locales: de|en
uploads_directory_name: uploads
uploads_profile_directory_name: profiles
uploads_directory: '%kernel.root_dir%/../public/%uploads_directory_name%'
profile_directory: '%kernel.root_dir%/../public/%uploads_directory_name%/%uploads_profile_directory_name%'
google_recaptcha_site_key: '%env(GOOGLE_RECAPTCHA_SITE_KEY)%'
services:
_defaults:
autowire: true
autoconfigure: true
App\:
resource: '../src/*'
exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'
App\Controller\:
resource: ../src/Controller
tags:
- controller.service_arguments
locales:
class: App\Util\Locales
arguments:
- '%locale_active%'
- '%app_locales%'
- '#session'
app.locale:
class: App\EventListener\LocaleListener
tags:
- {name: kernel.event_subscriber}
app.redirect_to_locale_active:
class: App\EventListener\RedirectToLocaleActiveListener
arguments:
- '#router'
- '%locale_active%'
tags:
- {name: kernel.event_subscriber}
My RedirectToLocaleActiveListener.php
<?php
namespace App\EventListener;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
/**
* Class RedirectToLocaleActiveListener
* When a user enters to the homepage without the parameter locale,
* the subscriber redirects the user to the main locale.
*
* #package App\EventListener
*/
class RedirectToLocaleActiveListener implements EventSubscriberInterface
{
/**
* #var UrlGeneratorInterface
*/
private $urlGenerator;
/**
* #var string
*/
private $localeActive;
/**
* #param UrlGeneratorInterface $urlGenerator
* #param $localeActive
*/
public function __construct(UrlGeneratorInterface $urlGenerator, $localeActive)
{
$this->urlGenerator = $urlGenerator;
$this->localeActive = $localeActive;
}
public static function getSubscribedEvents()
{
return [
KernelEvents::REQUEST => 'onKernelRequest',
];
}
/**
* #param GetResponseEvent $event
*/
public function onKernelRequest(GetResponseEvent $event)
{
$request = $event->getRequest();
if ('/' == $request->getPathInfo()) {
$route = $this->urlGenerator->generate('app_index', ['_locale' => $this->localeActive]);
$response = new RedirectResponse($route);
$event->setResponse($response);
}
}
}
What I've tried:
adding 'string' to $localActive in __construct of RedirectToLocaleActiveListener
Result:
Cannot autowire service "App\EventListener\RedirectToLocaleActiveListener": argument "$localeActive" of method "__construct()" is type-hinted "string", you should configure its value explicitly.
arguments of scalar type cannot be auto-wired. You need to wire them manually.
You can try wiring the argument explicitly in the service definition:
App\EventListener\RedirectToLocaleActiveListener
arguments:
$urlGenerator: '#router'
$localeActive: '%locale_active%'
tags:
- {name: kernel.event_subscriber}
Documentation:
https://symfony.com/doc/current/service_container.html#manually-wiring-arguments
Or you can make use of the local service binding feature to bind a parameter to a scalar argument:
services:
_defaults:
bind:
$localeActive: '%locale_active%'
Documentation:
https://symfony.com/blog/new-in-symfony-3-4-local-service-binding
If your service name is not equal to fqcn, such as:
app.ext.telegram_bot_api:
class: 'App\Ext\TelegramBot\Bot'
and somewhere your using automatic services resolution like this:
# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
App\:
resource: '../src/*'
exclude: '../src/{Entity,Document,Migrations,Tests,Kernel.php}'
your should create alias between your service name and fqcn like that:
'App\Ext\TelegramBot\Bot': '#app.ext.telegram_bot_api'
so your automatic services resolution should know about your service extra configuration.

How to use BindingsGremlinPlugin class for adding bindings to embedded gremlin-server?

I have initialized janus-graph instance in my app. I use FERMA OGM to interact with it. I also want to provide network access to it so I consider using of gremlin-server in embedded mode.
I do that in that way:
InputStream inputStream = getClass().getClassLoader().getResourceAsStream("gremlin-server-simple.yaml");
Settings settings = Settings.read(inputStream);
settings.graphs.clear();
GremlinServer gremlinServer = new GremlinServer(settings);
GraphManager graphManager = gremlinServer.getServerGremlinExecutor().getGraphManager();
graphManager.putGraph("graph", jg);
// jg - graph instance
...
gremlinServer.start();
gremlin-server-simple.yaml:
host: localhost
port: 8182
scriptEvaluationTimeout: 30000
channelizer: org.apache.tinkerpop.gremlin.server.channel.WebSocketChannelizer
graphManager: org.janusgraph.graphdb.management.JanusGraphManager
graphs: {}
scriptEngines: {
gremlin-groovy: {
plugins: { com.mallcloud.shortesttrack.metadata.commons.gremlin.ModJanusGraphJsrGremlinPlugin: {},
org.apache.tinkerpop.gremlin.server.jsr223.GremlinServerGremlinPlugin: {},
org.apache.tinkerpop.gremlin.tinkergraph.jsr223.TinkerGraphGremlinPlugin: {},
org.apache.tinkerpop.gremlin.jsr223.ImportGremlinPlugin: {classImports: [java.lang.Math], methodImports: [java.lang.Math#*]}
},
imports: [java.lang.Math],
staticImports: [java.lang.Math.PI],
scripts: []}}
serializers:
- { className: org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV1d0, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry] }}
- { className: org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV1d0, config: { serializeResultToString: true }}
- { className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerGremlinV1d0, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry] }}
- { className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV1d0, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry] }}
processors:
- { className: org.apache.tinkerpop.gremlin.server.op.session.SessionOpProcessor, config: { sessionTimeout: 28800000 }}
- { className: org.apache.tinkerpop.gremlin.server.op.traversal.TraversalOpProcessor, config: { cacheExpirationTime: 600000, cacheMaxSize: 1000 }}
metrics: {
consoleReporter: {enabled: true, interval: 180000},
csvReporter: {enabled: true, interval: 180000, fileName: /tmp/gremlin-server-metrics.csv},
jmxReporter: {enabled: true},
slf4jReporter: {enabled: true, interval: 180000},
gangliaReporter: {enabled: false, interval: 180000, addressingMode: MULTICAST},
graphiteReporter: {enabled: false, interval: 180000}}
maxInitialLineLength: 4096
maxHeaderSize: 8192
maxChunkSize: 8192
maxContentLength: 65536
maxAccumulationBufferComponents: 1024
resultIterationBatchSize: 64
writeBufferLowWaterMark: 32768
writeBufferHighWaterMark: 65536
But I can't define binding (g, graph) for my graph instance - jg.
On this programmatically-add-global-variables-to-gremlin-server topic there was answer that It needs to use BindingsGremlinPlugin to add binding.
But I have no idea how to do it - should I add strings with that plugin class and binding in my gremlin-conf or I have to add binding from code (in some way)?
Update - in accordance to the answer I added bindings by modifying Settings instance:
InputStream inputStream = getClass().getClassLoader().getResourceAsStream(gremlinConfigFile);
Settings settings = Settings.read(inputStream);
// Create arg - bindingsMap
Map<String, Object> arg = new HashMap<>();
arg.put("graph", jg);
arg.put("g", jg.traversal());
// Create method2argMap
Map<String, Object> method2arg = new HashMap<>();
method2arg.put("bindings", arg);
// Add method2argMap to BindingsGremlinPlugin string
settings.scriptEngines.get("gremlin-groovy").plugins.put("org.apache.tinkerpop.gremlin.jsr223.BindingsGremlinPlugin", method2arg);
should I add strings with that plugin class and binding in my gremlin-conf or I have to add binding from code?
I thnk that you have to use the Gremlin Server yaml file. Gremlin Server always looks to instantiate a plugin with a static instance() method or barring that, a static build() method that returns a Builder object. If it uses build() then it will use reflection to take any keys/values that you provide in a Map in the yaml file for that plugin and use the keys to reflect the names of methods on the Builder object and call them with the values as arguments. You must take care to match the expected data types for the Builder methods.
So for BindingsGremlinPlugin you can see the build() method here which returns the Builder which is here and then that class has just one configuration method on it called bindings() which takes a Map. Therefore your configuration for such a class in the yaml must be:
org.apache.tinkerpop.gremlin.jsr223.BindingsGremlinPlugin: {bindings: {x: 123}}
which would put the variable "x" with the value "123" on the global bindings. Obviously, the limitation here is that you can only use types allowed by yaml. Note that you don't have to add the above to your yaml file as you are embedding and could programmatically update the Settings object to include it prior to handing it over to Gremlin Server to start it up.
The only way to programmatically use the BindingsGremlinPlugin would be if you were initializing your own GremlinExecutor or GremlinScriptEngine instance, which isn't the case here.
If you need more complex objects on the bindings you could write your own extension of BindingsGremlinPlugin which could dynamically instantiate those complex values. Then reference your own implementation in the yaml files.

Eureka never unregisters a service

I'm currently facing an issue where Eureka does not unregister a registered service. I've pulled the Eureka server example straight from git hub and made only one change, eureka.enableSelfPreservation = false. My application.yml looks like this:
server:
port: 8761
eureka:
enableSelfPreservation: false
client:
registerWithEureka: false
fetchRegistry: false
server:
waitTimeInMsWhenSyncEmpty: 0
I've read that if 85% of the registered services stop delivering heartbeats within 15 minutes, Eureka assumes the issue is network related and does not de-register the services that are not responding. In my case I have only one service running, so I disabled self-preservation mode. I am abruptly killing the process and Eureka leaves the service registered for what seems like an indefinite amount of time.
My client's application.yml looks like this:
eureka:
instance:
leaseRenewalIntervalInSeconds: 3
client:
healthcheck:
enabled: true
serviceUrl:
defaultZone: http://localhost:8761/eureka/
appInfo:
replicate:
interval: 3
initial:
replicate:
time: 3
spring:
rabbitmq:
addresses: ${vcap.services.${PREFIX:}rabbitmq.credentials.uri:amqp://${RABBITMQ_HOST:localhost}:${RABBITMQ_PORT:5672}}
My goal is to create a demo where Eureka quickly detects the service is no longer running and another service that is started can quickly register itself.
As of now, once the eureka client is started, it registers in 3 seconds. It just never un-registers when the service is abruptly terminated. After I kill the service, the Eureka dashboard reads:
EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.
How can I prevent this behavior?
I realized that self preservation mode was never actually being disabled. It turns out the actual property is
eureka.server.enableSelfPreservation=false
(See DefaultEurekaServerConfig Code), which I haven't found documented anywhere. This resolved my issue.
I made service de-registration work by setting the below values
Eureka server application.yml
eureka:
server:
enableSelfPreservation: false
Service application.yml
eureka:
instance:
leaseRenewalIntervalInSeconds: 1
leaseExpirationDurationInSeconds: 2
The full example is here https://github.com/ExampleDriven/spring-cloud-eureka-example
After struggling a lot, finally I got solution if any service unregistered from Eureka server due to some issue. It will notify to the Admin by extending the HealthCallback of Eureka-Server APIs.
Let Say Service-A register with Eureka. Hence Eureka Client is integrate with Service-A and Implement following Callbacks in Service A.
Service-A [Eureka-Client]
Add following properties in properties files.
#Eureka Configuration
eureka.client.eureka-server-port=8761
eureka.client.register-with-eureka=true
eureka.client.healthcheck.enabled=false
eureka.client.prefer-same-zone-eureka=true
eureka.client.fetchRegistry=true
eureka.client.serviceUrl.defaultZone=${eurekaServerURL1}, ${eurekaServerURL2}
eureka.client.eureka.service-url.defaultZone=${eurekaServerURL1}, ${eurekaServerURL2}
eureka.instance.hostname=${hostname}
eureka.client.lease.duration=30
eureka.instance.lease-renewal-interval-in-seconds=30
eureka.instance.lease-expiration-duration-in-seconds=30
Add following java files.
#Component
public class EurekaHealthCheckHandler implements HealthCheckHandler, ApplicationContextAware, InitializingBean {
static Logger logger = LoggerFactory.getLogger(EurekaHealthCheckHandler.class);
private static final Map<Status, InstanceInfo.InstanceStatus> healthStatuses = new HashMap<Status, InstanceInfo.InstanceStatus>() {{
put(Status.UNKNOWN, InstanceInfo.InstanceStatus.UNKNOWN);
put(Status.OUT_OF_SERVICE, InstanceInfo.InstanceStatus.OUT_OF_SERVICE);
put(Status.DOWN, InstanceInfo.InstanceStatus.DOWN);
put(Status.UP, InstanceInfo.InstanceStatus.UP);
}};
#Autowired
ComunocationService comunocationService ;
private final CompositeHealthIndicator healthIndicator;
private ApplicationContext applicationContext;
public EurekaHealthCheckHandler(HealthAggregator healthAggregator) {
Assert.notNull(healthAggregator, "HealthAggregator must not be null");
this.healthIndicator = new CompositeHealthIndicator(healthAggregator);
Health health = healthIndicator.health();
logger.info(" =========== Testing =========== {}", health.toString() );
}
#Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
#Override
public void afterPropertiesSet() throws Exception {
final Map<String, HealthIndicator> healthIndicators = applicationContext.getBeansOfType(HealthIndicator.class);
for (Map.Entry<String, HealthIndicator> entry : healthIndicators.entrySet()) {
logger.info("======"+ entry.getKey() +"============= "+entry.getValue());
healthIndicator.addHealthIndicator(entry.getKey(), entry.getValue());
}
}
#Override
public InstanceInfo.InstanceStatus getStatus(InstanceInfo.InstanceStatus instanceStatus) {
logger.info("============== Custome Eureka Implementation ==================="+ getHealthStatus());
return getHealthStatus();
}
protected InstanceInfo.InstanceStatus getHealthStatus() {
final Status status = healthIndicator.health().getStatus();
return mapToInstanceStatus(status);
}
protected InstanceInfo.InstanceStatus mapToInstanceStatus(Status status) {
logger.info("============== Test Custome Eureka Implementation ==================={}", status);
if(status.equals(InstanceInfo.InstanceStatus.UP)) {
// Send mail after configured times
comunocationService.sendEmail("ServiceName");
}
if(!healthStatuses.containsKey(status)) {
return InstanceInfo.InstanceStatus.UNKNOWN;
}
return healthStatuses.get(status);
}
public void getstatusChangeListner() {
ApplicationInfoManager.StatusChangeListener statusChangeListener = new ApplicationInfoManager.StatusChangeListener() {
#Override
public String getId() {
return "statusChangeListener";
}
#Override
public void notify(StatusChangeEvent statusChangeEvent) {
if (InstanceStatus.DOWN == statusChangeEvent.getStatus() ||
InstanceStatus.DOWN == statusChangeEvent.getPreviousStatus()) {
// log at warn level if DOWN was involved
logger.warn("Saw local status change event {}", statusChangeEvent);
} else {
logger.info("Saw local status change event {}", statusChangeEvent);
}
}
};
}
}
and
#Configuration
public class EurekaHealthCheckHandlerConfiguration {
#Autowired(required = false)
private HealthAggregator healthAggregator = new OrderedHealthAggregator();
#Bean
#ConditionalOnMissingBean
public EurekaHealthCheckHandler eurekaHealthCheckHandler() {
return new EurekaHealthCheckHandler(healthAggregator);
}
}
This is absolutely working and well tested code

Symfony "Could not load type" service yaml

I tried to create a service in Symfony 2.2 for one of my form :
service.yml:
tyg_user.settings.form:
class: Symfony\Component\Form\Form
factory_method: createNamed
factory_service: form.factory
arguments:
- tyg_user_settings
- tyg_user_settings_name
tyg_user.settings.form.type:
class: TyG\UserBundle\Form\Settings\SettingsFormType
tags:
- { name: form.type, alias: tyg_user_settings }
tyg_user.settings.form.handler:
class: TyG\UserBundle\Form\Settings\SettingsFormHandler
scope: request
arguments:
- #tyg_user.settings.form
- #request
- #fos_user.user_manager
SettingsForm.php
<?php
namespace TyG\UserBundle\Form\Settings;
use Symfony\Component\Form\FormBuilderInterface as FormBuilder;;
use Symfony\Component\Form\AbstractType;
class SettingsForm extends AbstractType
{
public function buildForm(FormBuilder $builder, array $options)
{
$builder
->add('birthday', 'birthday')
->add('email', 'email')
->add('showmail')
->add('showbirthday')
;
}
public function getName()
{
return 'tyg_user_settings';
}
}
?>
But an error occuered :
Could not load type "tyg_user_settings_name
This occurs when I get my form through the service container :
$this->container->get('tyg_user.settings.form');
I used to do create my service through the xml format but when I change to the yml format I can't figure out how to to make it works
The tyg_user_settings_name is referencing a form type alias.
If you are wanting it to reference a parameter you should use %tyg_user_settings_name% instead.