There is something I do not understand with locale management in Symfony2. I want to write month name in French with date Twig method. Is it possible? I can't do it.
It seems that my locale is not taken into account.
Here is my app/config/config.yml file:
framework:
#esi: ~
translator: { fallback: fr }
secret: %secret%
charset: UTF-8
router: { resource: "%kernel.root_dir%/config/routing.yml" }
form: true
csrf_protection: true
validation: { enable_annotations: true }
templating: { engines: ['twig'] } #assets_version: SomeVersionScheme
session:
default_locale: fr
auto_start: true
Session locale seems good:
echo $this->get('session')->getLocale(); // Returns "fr"
die;
Yet, when I am using, in my view, the following:
<td class="month">{{ history.date|date('F Y') }}</td>
It returns me "July 2011" for instance, instead of "Juillet 2011".
What am I misunderstanding? Shouldn't the date filter be localized? If not, how can I do to retrieve correct terms? I used to use I18N to translate all the month names, but I do not think it is the best practice.
date does not return localized string. You have to use strftime for that. Alternatively you can use SonataIntlBundle if you want more control.
Related
My symfony application (3.4.8) seems to ignore any attempts to prolong the session. What would be the best course of action to troubleshoot this issue? The documentation is very vague.
app/config/security.yml
security:
encoders:
FOS\UserBundle\Model\UserInterface: bcrypt
providers:
fos_userbundle:
id: fos_user.user_provider.username
main:
pattern: ^/
form_login:
provider: fos_userbundle
csrf_token_generator: security.csrf.token_manager
default_target_path: /
logout: true
anonymous: true
remember_me:
secret: '%secret%'
lifetime: 28000
path: /
access_denied_handler: app.security.access_denied_handler
config.yml
framework:
lock: 'semaphore'
#esi: ~
#translator: { fallbacks: ["%locale%"] }
secret: "%secret%"
router:
resource: "%kernel.root_dir%/config/routing.yml"
strict_requirements: ~
form: ~
csrf_protection: ~
validation: { enable_annotations: true }
#serializer: { enable_annotations: true }
templating:
engines: ['twig']
default_locale: "%locale%"
trusted_hosts: ~
trusted_proxies: ~
session:
handler_id: session.handler.native_file
save_path: "/tmp"
cookie_lifetime: 28800
fragments: ~
http_method_override: true
assets: ~
Maybe if you try this in your config:
session:
cookie_lifetime: 18000
gc_maxlifetime: 18000
Hope it helps !
Judging by this:
handler_id: session.handler.native_file
you're using a native session handler. From Symfony documentation:
So-called native handlers, are save handlers which are either compiled into PHP or provided by PHP extensions, such as PHP-Sqlite, PHP-Memcached and so on.
All native save handlers are internal to PHP and as such, have no public facing API. They must be configured by php.ini directives, usually session.save_path and potentially other driver specific directives.
Inspecting the NativeFileSessionHandler I've found no methods relating to session duration. That leads me to the conclusion that you have to set the duration on the PHP level, not on the Symfony level.
So, try setting the session.gc-maxlifetime (in your php.ini or calling ini_set) to 3600.
your setting will log out if you are inactive for more than 30 minutes.
You can add following in your yml file
#app/config/config.yml
session:
cookie_lifetime: 86400
gc_maxlifetime: 1800
gc_probability: 1
gc_divisor: 1
Using Symfony 3.4.2 , I am trying to build a relationship between two entities of two different bundles which uses their own databases located on different servers.
In other words, we have two databases, and then two entities managers :
One existing MariaDB database [person] which store one "person" table, used by many other applications.
One new MariaDB database [app] dedicated for the application.
Note that I can't change anything on that situation (legacy applications must still running). Althought it is planned "in the future" to replace the [person] database by a REST Api.
Following the Symfony doc (https://symfony.com/doc/3.4/doctrine/multiple_entity_managers.html), this gives the following app/config/config.yml file :
imports:
- { resource: parameters.yml }
- { resource: security.yml }
- { resource: services.yml }
# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
parameters:
locale: en
framework:
#esi: ~
#translator: { fallbacks: ['%locale%'] }
secret: '%secret%'
router:
resource: '%kernel.project_dir%/app/config/routing.yml'
strict_requirements: ~
form: ~
csrf_protection: ~
validation: { enable_annotations: true }
#serializer: { enable_annotations: true }
default_locale: '%locale%'
trusted_hosts: ~
session:
# https://symfony.com/doc/current/reference/configuration/framework.html#handler-id
handler_id: session.handler.native_file
save_path: '%kernel.project_dir%/var/sessions/%kernel.environment%'
fragments: ~
http_method_override: true
assets: ~
php_errors:
log: true
# Twig Configuration
twig:
debug: '%kernel.debug%'
strict_variables: '%kernel.debug%'
# Doctrine Configuration
doctrine:
dbal:
default_connection: default
connections:
default:
driver: pdo_mysql
host: '%database_host%'
port: '%database_port%'
dbname: '%database_name%'
user: '%database_user%'
password: '%database_password%'
# charset: UTF8
charset: utf8mb4
default_table_options:
charset: utf8mb4
collate: utf8mb4_unicode_ci
# if using pdo_sqlite as your database driver:
# 1. add the path in parameters.yml
# e.g. database_path: '%kernel.project_dir%/var/data/data.sqlite'
# 2. Uncomment database_path in parameters.yml.dist
# 3. Uncomment next line:
#path: '%database_path%'
acme_another_db :
driver: pdo_mysql
host: '%acme_another_database_host%'
port: '%acme_another_database_port%'
dbname: '%acme_another_database_name%'
user: '%acme_another_database_user%'
password: '%acme_another_database_password%'
# charset: UTF8
charset: utf8mb4
default_table_options:
charset: utf8mb4
collate: utf8mb4_unicode_ci
# if using pdo_sqlite as your database driver:
# 1. add the path in parameters.yml
# e.g. database_path: '%kernel.project_dir%/var/data/data.sqlite'
# 2. Uncomment database_path in parameters.yml.dist
# 3. Uncomment next line:
#path: '%database_path%'
orm:
# Let's disable auto_mapping since we have several entity_managers
# auto_mapping: true
default_entity_manager: default
entity_managers:
default:
naming_strategy: doctrine.orm.naming_strategy.underscore
connection: default
mappings:
AppBundle: ~
acme_another_em:
naming_strategy: doctrine.orm.naming_strategy.underscore
connection: acme_another_db
mappings:
AcmeAnotherBundle: ~
auto_generate_proxy_classes: '%kernel.debug%'
# Swiftmailer Configuration
swiftmailer:
transport: '%mailer_transport%'
host: '%mailer_host%'
username: '%mailer_user%'
password: '%mailer_password%'
spool: { type: memory }
Since the "person" table is to be used by many other applications, I choosed to create a separate bundle.
In terms of entity, I have then 3 entities :
Acme/AnotherBundle/Entity/Person
AppBundle/Entity/Book
AppBundle/Entity/BookInterest
The first entity was generated without any error.
The AppBundle/Entity/Book and AppBundle/Entity/BookInterest entities were generated via bin\console generate:doctrine:entity without any problem.
Before updating the database schema, I added the relationship in the AppBundle/Entity/BookInterest entity class file (relation to Acme/AnotherBundle/Entity/Person and to AppBundle/Entity/Book), following the Symfony doc (http://symfony.com/doc/3.4/doctrine/associations.html).
/**
* #ORM\ManyToOne(targetEntity="Book", inversedBy="book")
* #ORM\JoinColumn(name="fk_book_id", referencedColumnName="id", nullable=false)
*/
private $book;
/**
* #ORM\ManyToOne(targetEntity="Acme\AnotherBundle\Entity\Person")
* #ORM\JoinColumn(name="fk_person_id", nullable=false)
*/
private $person;
But, when I try to update the schema via bin\console doctrine:schema:update --force --em=default, I have the following error message :
In MappingException.php line 37: The class
'Acme\AnotherBundle\Entity\Person' was not found in the chain
configured namespaces AppBundle\Entity
Adding "use Acme\AnotherBundle\Entity\Person;" in the top of \src\AppBundle\Entity\BookInterest.php and clearing the cache via bin\console cache:clear does not solve the problem.
Did I miss something in the app/config/config.yml configuration file, or in the \src\AppBundle\Entity\BookInterest.php entity class file ?
Doctrine2 unable to handle one relationship between two entity managers ?
I also found a (quite old) post on a similar problem (Using Relationships with Multiple Entity Managers), which indicates that Doctrine2 is unable to do that (due to the use of two entity managers).
If this is still the case, what is the best way to handle that situation ?
Is using one simple integer field without relation in the AppBundle/Entity/BookInterest for storing person_id and create manuals validation checks (then manual queries) in the BookInterestController is a good practice ?
Thanks a lot in advance for any tips (and good practice advices) to solve that case ! :-)
Hy,
For some time know I have an issue with my test scenario.
I use behat/mink ~2.0 and Nelmio/Alice ^2.x in my Symfony project.
On some of my project I use the doctrine extension translatable to manage i18n on my buisness entity.
When alice persist my fixture he seems to ignore my default_locale parameter and will always create them with en as locale value.
In order to test my locale switcher I need a way to choose my locale for the project in test environnement or/and persist fixture with different locale.
My fixture are wright as follow
AcmmeBundle\CoreBundle\Entity\Universe:
universe1:
title: <word()>
templates: [#template1]
collections: [#collection1, #collection2]
categories: [#category1, #category2]
Load in my test like this
#alice(User)
#alice(Category)
#alice(Collection)
#alice(Universe)
#alice(Page)
#alice(HomePage)
#reset-schema
#javascript
Feature: I test api GET /api/someEntity
And my behat.yml.dist
default:
autoload:
'': features/bootstrap
suites:
default:
contexts:
- Victoire\Tests\Features\Context\FeatureContext
- Victoire\Tests\Features\Context\JavascriptContext
- Victoire\Tests\Features\Context\VictoireContext
- Knp\FriendlyContexts\Context\MinkContext
- Knp\FriendlyContexts\Context\AliceContext
- Knp\FriendlyContexts\Context\EntityContext
- Knp\FriendlyContexts\Context\TableContext
- FeatureContext
- PageContext
- ApiContext
formatters:
html:
output_path: %paths.base%/web/build/html/behat
pretty:
output_path:
extensions:
emuse\BehatHTMLFormatter\BehatHTMLFormatterExtension:
name: html
renderer: Twig,Behat2
file_name: Index
print_args: true
print_outp: true
loop_break: true
jarnaiz\JUnitFormatter\JUnitFormatterExtension:
filename: report.xml
outputDir: %paths.base%/test-reports/
Behat\Symfony2Extension:
kernel:
path: app/AppKernel.php
debug: true
Behat\MinkExtension\ServiceContainer\MinkExtension:
base_url: 'http://127.0.0.1/app_test.php'
selenium2:
wd_host: 127.0.0.1:4444/wd/hub
capabilities: { "browser": "firefox"}
goutte: ~
symfony2: ~
default_session: symfony2
browser_name: firefox
Knp\FriendlyContexts\Extension:
entities:
namespaces:
- Acme
- Victoire
smartTag: smartStep
alice:
locale: fr_FR
fixtures:
Media: features/fixtures/media.yml
Template: features/fixtures/template.yml
User: features/fixtures/user.yml
Survey: features/fixtures/survey.yml
Tag: features/fixtures/tag.yml
Collection: features/fixtures/collection.yml
Category: features/fixtures/category.yml
Universe: features/fixtures/universe.yml
Page: features/fixtures/Victoire/page.yml
HomePage: features/fixtures/Victoire/Pages/home.yml
dependencies:
Template: [Media]
User: [Template]
Survey: [Tag]
HomePage: [Page]
According to http://docs.behat.org/en/v2.5/guides/7.config.html use
export BEHAT_PARAMS="formatter[name]=progress&context[parameters][base_url]=http://localhost"
and override "_locale" parameter in route
Well actually the answer was realy simple.
Just by using fixture for Translation class
universeTranslation1:
title: <word()>
locale: fr
translatable: #universe1
universeTranslation2:
title: <word()>
locale: en
translatable: #universe1
universeTranslation3:
title: <word()>
locale: fr
translatable: #universe2
universeTranslation4:
title: <word()>
locale: en
translatable: #universe2
When I want to create a Shipment I get the error:
An exception has been thrown during the rendering of a template ("No locale has been set and current locale is undefined.") in SonataAdminBundle::standard_layout.html.twig at line 148.
I think I need to set the default locale for sylius, but I tried alot of examples, none of them helped..
I currently have this setup:
Config.yml:
sylius_shipping:
driver: doctrine/orm # Configure the Doctrine ORM driver used in documentation.
classes:
shipping_method:
model: Application\Sylius\ShippingBundle\Entity\ShippingMethod
translation:
model: Application\Sylius\ShippingBundle\Entity\ShippingMethodTranslation
shipping_method_rule:
model: Application\Sylius\ShippingBundle\Entity\Rule
shipment:
model: Application\Sylius\ShippingBundle\Entity\Shipment
shipment_item:
model: Application\Sylius\ShippingBundle\Entity\ShipmentItem
shipping_category:
model: Application\Sylius\ShippingBundle\Entity\ShippingCategory
#stof_doctrine_extensions:
# orm:
# default:
# timestampable: true
parameters:
sylius.locale: %locale%
#sylius_locale:
# driver: doctrine/orm
sylius_translation:
default_locale: "%locale%"
#sylius_translation:
# default_locale: %sylius.locale%
Parameters.yml:
sylius.currency_importer.ecb.base_currency: EUR
sylius.currency_importer.open_exchange_rates: EDITME
sylius.locale: en_US
Nothing works..
UPDATE
By changing my config to this:
framework:
#esi: ~
translator: { fallback: %sylius.locale% }
secret: "%secret%"
router:
resource: "%kernel.root_dir%/config/routing.yml"
strict_requirements: ~
form: ~
csrf_protection: ~
validation: { enable_annotations: true }
templating:
engines: ['twig']
#assets_version: SomeVersionScheme
default_locale: "%sylius.locale%"
parameters:
sylius.locale: 'en'
#sylius_locale:
# driver: doctrine/orm
sylius_translation:
default_locale: %sylius.locale%
I still get the same error. I cleared my cache.
Try %sylius.locale%. It looks like you've just not put in the full name of the parameter in your config file.
If you've updated the value and it's not working, make sure you clear your cache.
$ app/console cache/clear --env=dev
$ app/console cache/clear --env=prod
You will also require something like this:
imports:
- { resource: parameters.yml }
Otherwise the parameters you enter will not be loaded into the configuration file.
I use VichUploaderBundle for upload my media files and I want to use AvalancheImagineBundle to create thumbs in my templates.
How it should be done?
I have this right now:
<td><img src="{{ vich_uploader_asset(entity, 'image') | apply_filter('my_thumb')}}" alt="{{ entity.nombre }}" /></td>
But the output is:
<img src="/app_dev.php/media/cache/my_thumb/images/uploads/392158_10150441208223772_580903771_8591661_774015725_n.jpg" alt="Froga"/>
this is my config.yml:
# Vich Uploader
vich_uploader:
db_driver: orm
twig: true
gaufrette: false # set to true to enable gaufrette support
storage: vich_uploader.storage.file_system
mappings:
uploads:
uri_prefix: /images/uploads
upload_destination: %kernel.root_dir%/../web/images/uploads
namer: ~ # specify a file namer service id for this entity, null default
directory_namer: ~ # specify a directory namer service id for this entity, null default
delete_on_remove: true # determines whether to delete file upon removal of entity
inject_on_load: true # determines whether to inject a File instance upon load
avalanche_imagine:
source_root: %kernel.root_dir%/../web/images/uploads
web_root: %kernel.root_dir%/../web/images/uploads
cache_prefix: media/cache
driver: gd
filters:
my_thumb:
type: thumbnail
options: { size: [120, 90], mode: outbound, quality: 100, format: png }
Any help or clue?
If the problem you are having is that no image is being displayed, then I had the same issue.
In order to solve it I ensured that within my config.yml, the source_root and web_root options of avalanche_imagine were set to %kernel.root_dir%/../web (or your web root). Here is the relevant snippet from my config.yml:
#Uploads
knp_gaufrette:
adapters:
article_adapter:
local:
directory: %kernel.root_dir%/../web/images/articles
filesystems:
article_image_fs:
adapter: article_adapter
vich_uploader:
db_driver: orm
gaufrette: true
storage: vich_uploader.storage.gaufrette
mappings:
article_image:
uri_prefix: /images/articles
upload_destination: article_image_fs
namer: vich_uploader.namer_uniqid
#images
avalanche_imagine:
filters:
article_list:
type: thumbnail
options: { size: [100, 100], mode: outbound }
source_root: %kernel.root_dir%/../web
web_root: %kernel.root_dir%/../web
cache_prefix: cache
Nothing wrong with that. Imagine bundle in production generates thumbnail the first time its called and stores it in web/media folder. On second call it just reads from web/media.
It has some advantages to modify the thumnail sizes at will. If You are worried about performance you should fire some job to generate thumbnail after the upload is finished,
although i used it like that and never complained.
In my case, I chose to use LiipImagineBundle which is a fork of the AvalancheImagineBundle
.
I were configure this bundle to use gaufrette as data-loader, than it simple to use it as you describe, without caring much about the paths.