I use fosuserbundle for auth.
Database during tests is set to be in-memory:
#config_test.yml
doctrine:
dbal:
driver: pdo_sqlite
path: :memory:
memory: true
orm:
auto_generate_proxy_classes: true
auto_mapping: true
Test file looks like that (just playground until i solve that):
Pasted
And when I run tests I get 302 redirect to the login, which should not happen.
What could be wrong with that?
When I change config to use development mysql connection - it works good - response is without redirect and the body is correct.
Ok, i managed to find out why is it happening.
I digged into Client class and its doRequest method.
protected function doRequest($request)
{
// avoid shutting down the Kernel if no request has been performed yet
// WebTestCase::createClient() boots the Kernel but do not handle a request
if ($this->hasPerformedRequest) {
$this->kernel->shutdown();
} else {
$this->hasPerformedRequest = true;
}
if ($this->profiler) {
$this->profiler = false;
$this->kernel->boot();
$this->kernel->getContainer()->get('profiler')->enable();
}
return parent::doRequest($request);
}
So kernel is shutting down every request and database is deleted from memory. That's my 99% guess.
I can't do anything for that except using other client library
Related
Is there any way to set _locale parameter of routing configuration as a function call or an expression result? I have multiple hosts running on the same symfony app, and there is an i18n turned on. Everything is working fine, but now i need to have another locales set for a specified host.
Right now my routing config looks like
app:
resource: '#AppBundle/Controller/'
...
requirements:
_locale: '%route_locales%'
...
and i have something like this in parameters:
...
route_locales: en|de|fr
...
That would be perfect if i can use something like
"#=service('AppBundle\\\\...\\\\LocalesConfigurator').getLocales()"
as a _locale: value to get this value based on a function call result. Or maybe there are some other options to get another _locale set for a specified host?
You can do it like #Jakumi suggested (via env params passed from server)
or using only application logic:
In route_locales put all possible locales that can be used in any host.
Validate incoming _locale inside "request listener" depending on request host - if some _locale is not allowed for host then return 404 response or show 404 error page etc.
Seems like i've found at least one solutuin, thanks to Jakumi for the idea. I've created a parameter in my config file, which receives an environment varaible. Then i use this parameter in my routing file. The main idea is that i can control this environment variable value using bootstrap file. So it looks like
bootstrap.php (in the example it's just a static value, but in a real life this value will depend on host).
bootstrap.php
...
$_SERVER['SYMFONY__ROUTE__LOCALES'] = 'en|es';
...
config.yml
parameters:
route_locales: '%route.locales%'
routing.yml
app:
resource: '#AppBundle/Controller/'
...
requirements:
_locale: '%route_locales%'
...
I don't realy like this solution, and will be thankful for any better solutions, but at least it does what i want.
I was in the same issue some months ago and I was able to found a solution that worked correctly, but there may also be some better ones.
As I needed different route names to be loaded depending on the locale (i.e. /contact in English and /contacto in Spanish) what I did was creating the methods in the controller and creating an individual link to them in routes.yaml
contact-en:
path: /contact/
controller: App\Controller\ContactController::index
host: domain1.tld
contact-es:
path: /contacto/
controller: App\Controller\ContactController::index
host: domain2.tld
Then I created an EventListener called LocaleSwitcher:
class LocaleSwitcher
{
public function onKernelRequest(GetResponseEvent $event)
{
$request = $event->getRequest();
$host = $request->getHost();
switch($host) {
case 'domain1.tld': {
$request->setLocale('en');
break;
}
case 'domain2.tld': {
$request->setLocale('es');
break;
}
}
}
}
And then adding it in services.yaml for event kernel.request and priority 20:
App\EventListener\LocaleSwitcher:
tags:
- { name: kernel.event_listener, event: kernel.request, priority: 20 }
I want to cache results of some HTTP requests to my Symfony 3.4 application using Symfony HttpCache.
Following their docs I now have those lines in app_dev.php
$kernel = new AppKernel('dev', true);
$kernel = new AppCache($kernel);
This is my controller code
$overview = $this->channelRepository->getOverview();
$response = new JsonResponse($overview);
$response->setSharedMaxAge(3600);
return $response;
And this is my config.yml
framework:
cache:
app: cache.adapter.redis
default_redis_provider: snc_redis.default
#...
snc_redis:
clients:
default:
type: phpredis
alias: default
dsn: redis://localhost
logging: false
However, I don't see new entries appear in my redis server. Instead, those entries appear in filesystem cache (var/cache/dev/http/cache). How do I fix my application to use Redis HTTP cache?
I dug a bit deeper and found out that AppCache that I use extends Symfony\Bundle\FrameworkBundle\HttpCache\HttpCache which only accepts filesystem store. Does that mean that I should somehow use Symfony\Component\HttpKernel\HttpCache\HttpCache, which accepts any Store in its constructor?
Is there a way to set a parameter in symfony based on a certain condition, f.e. an ENV var?
Expression language came to my mind but it seems its only supported in arguments, properties and calls
config.yml:
parameters:
env(CI): false
ci: '%env(CI)%'
database_host: "#=parameter(ci) ? 'localhost' : 'mysql'"
doctrine:
dbal:
connections:
cms:
host: "%database_host%"
UPDATE
Expression language doesnt work in that case (Up to SF 3.3 currently) so i used Oli's approach which works:
get_params_from_env.php:
$container->setParameter('database_host', 'mysql');
if (getenv('CI')) {
$container->setParameter('database_host', '127.0.0.1');
}
Add this line to config.yml:
imports:
- { resource: get_params_from_env.php }
Then, in the php file, use this:
<?php
$container->setParameter('app.dummy_var', getenv('DUMMY_VAR'));
You can read about including your own PHP files here, under 'advanced techniques': http://symfony.com/doc/current/configuration/configuration_organization.html
How to use DoctrineCacheBundle? I want to cache query (so that it is not translated to SQL each time, right?). Also I want to cache the result.
I have set it up like this:
doctrine:
orm:
metadata_cache_driver:
cache_provider: metadata_cache
query_cache_driver:
cache_provider: query_cache
result_cache_driver:
cache_provider: result_cache
and
doctrine_cache:
providers:
metadata_cache:
apc: ~
query_cache:
apc: ~
result_cache:
apc: ~
And in my controller:
$cache = $this->get('doctrine_cache.providers.query_cache');
if ($cache->contains('someid')) {
$surveysEntities = $cache->fetch('someid');
} else {
$surveysEntities = $this->getDoctrine()->getRepository('MyBundle:Survey')->getSurveys();
$cache->save('someid', $surveysEntities);
}
This will cache only query? Or both query and result? Is it enough? OR I should also do sth on query in my repository?
OK, got it. This cache result. Query is cached with doctrine via config. settings.
I'm using RabbitMQ Bundle for the Symfony2 web framework. My question is, how can I avoid creating multiple connections (to prevent overloading the broker) after running many workers in terminal? In example below, I've run two workers and ended up having two connections/channel.
config.yml
old_sound_rabbit_mq:
connections:
default:
host: 127.0.0.1
port: 5672
user: guest
password: guest
vhost: /
lazy: true
producers:
order_create_bmw:
connection: default
exchange_options: { name: order_create_ex, type: direct }
queue_options:
name: order_create_bmw_qu
routing_keys:
- bmw
consumers:
order_create_bmw:
connection: default
exchange_options: { name: order_create_ex, type: direct }
queue_options:
name: order_create_bmw_qu
routing_keys:
- bmw
callback: application_frontend.consumer.order_create_bmw
services.yml
services:
application_frontend.producer.order_create_bmw:
class: Application\FrontendBundle\Producer\OrderCreateBmwProducer
arguments:
- #old_sound_rabbit_mq.order_create_bmw_producer
Producer
namespace Application\FrontendBundle\Producer;
use Application\FrontendBundle\Entity\Order;
use OldSound\RabbitMqBundle\RabbitMq\ProducerInterface;
class OrderCreateBmwProducer
{
private $producer;
public function __construct(ProducerInterface $producer)
{
$this->producer = $producer;
}
public function add(Order $order)
{
$message = [
'order_id' => $order->getId(),
'car_model' => $order->getCarModel(),
'timestamp' => date('Y-m-d H:i:s')
];
$this->producer->publish(json_encode($message), 'bmw');
}
}
Running workers
$ app/console rabbitmq:consumer order_create_bmw
$ app/console rabbitmq:consumer order_create_bmw
RabbitMQ Management
Every client (regardless if publisher or subscriber) that connects to rabbitmq will create a connection. Aside from using less clients, I can't think of any other way to achive this. I also can't think of a reason to do so :) If it's performance, than actually having more subscribers will help to "empty" the exchanges (and queues).