Symfony2 test parameters - symfony

Is there a way to configure test parameters with Symfony2?
I tried importing parameters_test.yml from the config_test.yml file but the variables still come from the parameters.yml file which is imported by config.yml which is imported by config_dev.yml which is imported by config_test.yml.
Basically I want to setup different variables in a test parameter file so I can access the values and also use them in the config files. If I hardcode the variables directly into config_test.yml I don't have access to them.
The variable I'm interested in particular is database_name or doctrine->dbal->dbname.
Thanks

Of course ensure your two first lines your config_test.yml are:
imports:
- { resource: config_dev.yml }
- { resource: parameters_test.yml }

In config_test.yml simple write this configuration:
# Doctrine Configuration
doctrine:
dbal:
driver: %database_driver_test%
host: %database_host_test%
port: %database_port_test%
dbname: %database_name_test%
user: %database_user_test%
password: %database_password_test%

Related

hydra - structured config group/package override via yaml

I'm not very successfully trying to figure out how to achieve an override of a group/package with and via a yaml file. Trying to explain my problem using the example (files and folder structre) from the hydra documentation https://hydra.cc/docs/tutorials/structured_config/schema/.
yaml.config as:
defaults:
- base_config # --> reference to dataclass
- db: base_mysql # --> reference to dataclass
- _self_ debug: true
gives the expected (print when running the myapp.py):
db:
driver: mysql
host: localhost
port: 3306
user: ???
password: ???
Using the yaml file instead instead of the base_mysql dataclass is also fine thus the yaml.config as:
defaults:
- base_config
- db: mysql # --> reads db/mysql.yaml
- _self_
debug: true
prints again as expected
db:
driver: mysql
host: localhost
port: 3306
user: omry
password: secret
Overriding individual fields is as well fine, e.g. with config.yaml like
defaults:
- base_config
- db: mysql
- _self_
debug: true
db:
password: UpdatedPassword
What I'm to able to figure out is how to override the full db group with a/via another yaml file - defining the structure via a dataclass and then override/set the values like:
defaults:
- base_config
- db: base_mysql # --> reference to dataclass to define the structure
- _self_
debug: true
db: mysql # --> mysql.yaml
throws the following error:
In 'config': Validation error while composing config:
Merge error: str is not a subclass of MySQLConfig. value: mysql
full_key:
object_type=Config
Searching the internet/stackoverflow already showed me that moving the self to the first position will get rid of the error - but then the composition order is "wrong".
Keeping the order as it is and using the mysql.yaml for an override works well - when done via commandline (python myapp.py db=mysql when the line "db:mysql" is not present), but for my usecase it much more convinient to handle it all via the yaml file(s).
Somehow I assume that the same functionality is available via CLI and files/code and that I just did not mange to figure out how it works.
(hydra version 1.1 in a conda environment with python 3.9)
Thank you very much in advance for any help that you can provide.
If understand correctly, you want to use the defaults list in your primary yaml file to merge together the base_mysql config with the mysql config. This will do the trick:
defaults:
- base_config
- db: [base_mysql, mysql]
- _self_
debug: true
Passing a list [base_mysql, mysql] of config names causes those configs base_mysql and mysql to be merged together. This is documented here -- see the "CONFIG_NAMES" alternative for specifying an option in the defaults list.
Note that passing the CLI override db=mysql (as in python myapp.py db=mysql) results in modification of the defaults list; the resulting defaults list will be the same as if you had used the following in your yaml file:
defaults:
- base_config
- db: mysql
- _self_
debug: true
You can pass a list [base_mysql, mysql] of config names at the CLI like this:
python my_app.py 'db=[base_mysql, mysql]'

Symfony: The class XYZ was not found in the chain configured namespaces

Existing questions did not help.
I am still learning Symfony and setting up an existing project. Trying to run doctrine fixtures from my application directory.
./app/console doctrine:fixtures:load --env test
And running this gives me following errors
Error thrown while running command "doctrine:fixtures:load --env test --em default". Message: "The class 'ClientPortal\GenericBundle\Document\Accountant' was not found in the chain configured namespaces _XyzProjectName\CalendarContext\Domain\Model, Integration\GetFeedbackBundle\Model, _XyzProjectName\AccountingProcessContext\Domain\Model, _XyzProjectName\CaseContext\Domain" {"exception":"[object] (Doctrine\Common\Persistence\Mapping\MappingException(code: 0): The class 'ClientPortal\GenericBundle\Document\Accountant' was not found in the chain configured namespaces _XyzProjectName\CalendarContext\Domain\Model, Integration\GetFeedbackBundle\Model, _XyzProjectName\AccountingProcessContext\Domain\Model, _XyzProjectName\CaseContext\Domain at /usr/local/var/www/1800-api/vendor/doctrine/persistence/lib/Doctrine/Common/Persistence/Mapping/MappingException.php:22)
And this exception is being thrown when trying to persist object of class
'ClientPortal\GenericBundle\Document\Accountant'
and here is my doctrine in config.yml
doctrine:
dbal:
driver: pdo_pgsql
host: '%database_host%'
dbname: '%database_name%'
user: '%database_user%'
password: '%database_password%'
orm:
auto_generate_proxy_classes: "%kernel.debug%"
auto_mapping: true
mappings:
CalendarBundle:
prefix: '_XyzProjectName\CalendarContext\Domain\Model'
IntegrationGetFeedbackBundle:
prefix: 'Integration\GetFeedbackBundle\Model'
AccountingProcessBundle:
prefix: '_XyzProjectName\AccountingProcessContext\Domain\Model'
CaseBundle:
prefix: '_XyzProjectName\CaseContext\Domain'
GenericBundle:
type: "annotation"
prefix: 'ClientPortal\GenericBundle\Document'
dir: 'src'
is_bundle: false
The snippet which is raising this exception
$account = new ClientPortal\GenericBundle\Document\Accountant();//full namespace added for clarity - also this file lies in the same directory structure.
$account->setSfAccountantId($accountantId);
$account->setUsername($username);
$manager = new ObjectManager;
$manager->persist( $account ); //This throws the above mentioned exception
My thought is, the file ClientPortal\GenericBundle\Document\Accountant.php is being autoloaded as there is no exception thrown at the time of instantion of its object. But, there is something missing with configuration or mapping because of which doctrine does not know how to persist its object.
[Source code][1] Accountant class
GenericBundle(s) registered under AppKernel
new Website\GenericBundle\WebsiteGenericBundle(),
new Admin\GenericBundle\AdminGenericBundle(),
new ClientPortal\GenericBundle\ClientPortalGenericBundle(),
new TaxApp\GenericBundle\TaxAppGenericBundle(),
So, as I suggested in comments - try to add ClientPortal\GenericBundle\Document\ namespace to mappings in your doctrine config file, like that:
#...
orm:
auto_generate_proxy_classes: "%kernel.debug%"
mappings:
# ...
ClientPortalGenericBundle:
type: annotation
prefix: 'ClientPortal\GenericBundle\Document\'
dir: '%kernel.root_dir%/src/ClientPortal/GenericBundle/Document/'
#is_bundle: false
auto_mapping: true
Had the same issue with Symfony 4 while using multiple database connections. This one https://stackoverflow.com/a/55361742/2540699 helped me to solved my problem.
I bumped into this kind of message in my Symfony 6.1 project, using multiple entity managers, with one of the entity managers specified as default in doctrine.yaml:
doctrine:
orm:
default_entity_manager: general
entity_managers:
general:
# config for general
other_entity_manager:
# config for other entity manager
Everything was fine on my dev environment, but on production I got the error
Uncaught PHP Exception Doctrine\Persistence\Mapping\MappingException: "The class XXX was not found in the chain configured namespaces " at /opt/approot/current/vendor/doctrine/persistence/src/Persistence/Mapping/MappingException.php
Problem seemed to be that I have a when#prod: section in my doctrine.config.yml. It seems I had to repeat the default_entity_manager over there:
when#prod:
doctrine:
orm:
default_entity_manager: general
# other prod-specific configuration
This fixed it for me.
Update: This is probably related to this issue: https://github.com/symfony/symfony/issues/27769

How can I test a page behind a security firewall in Symfony?

In Symfony's cookbook, there is a page entitled How to Simulate Authentication with a Token in a Functional Test. In it, it is said that:
The technique described in How to Simulate HTTP Authentication in a Functional Test is cleaner and therefore the preferred way.
Also, on the page that the quotation above links to, the documentation says:
The trick is to include the http_basic key in your firewall, along with the form_login key
This tells me that it is all right to have the form_login key, along with the http_basic key, and somehow http_basic should take precedence.
Here is my config_test.yml configuration file:
imports:
- { resource: config_dev.yml }
framework:
test: ~
session:
storage_id: session.storage.mock_file
profiler:
collect: false
web_profiler:
toolbar: false
intercept_redirects: false
swiftmailer:
disable_delivery: true
liip_functional_test:
cache_sqlite_db: true
doctrine:
dbal:
default_connection: default
connections:
default:
driver: pdo_sqlite
path: %kernel.cache_dir%/test.db
security:
firewalls:
default:
http_basic: ~
However, when I open my application in the test environment, I still get redirected to the login_form URL.
Why isn't setting the http_basic acting like the documentation says it should, namely it getting activated rather than form_login?
As commented here, having the code I pasted in my original question works just fine. The reason it is loading the login form is because I am not logging in via http_basic. In other words, when I have both form_login and http_basic enabled, I can login both by providing the PHP_AUTH_USER/PHP_AUTH_PASSWORD, and by logging in through the form. In effect, I don't need different security_*.yml files; I just need to add http_basic: ~ to the already-defined firewall.
Just split security.yml to security_test.yml and security_prod.yml.
In security_test.yml put default security configuration (as delivered with Symfony) or other one, which doesn't have firewall restrictions.
Create a specific config file for test environment, like config_test.yml with
imports:
- { resource: config.yml }
- { resource: security_test.yml }
note here config.yml itself doesn't have any security imports, because You will receive some Exception about overriding security directive or smth.
Create a separate config_prod.yml with
imports:
- { resource: config.yml }
- { resource: security_prod.yml }
Now You have separate security for test and prod environments.
If Your environment naming is good, then Kernel will pick config_test.yml only when tests are executed. For development environment Your should use config_dev.yml instead of config_test.yml

How to import mapping parameter in Symfony 2 configuration file?

Here is what I would expect to work fine:
parameters.yml
host:
main: example.com
app/config/config.yml
twig:
globals:
hosts_main: %host.main%
But an exception is thrown:
[Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException]
You have requested a non-existent parameter "host.main".
And I cannot find any examples in docs.
Strange.
For example, Incenteev\ParameterHandler\ScriptHandler::buildParameters() replaces "flow" notation with mapping if there is one in .dist file and both structures are equal in terms of YAML but Symfony itself seems to not understand YAML.
Could anyone please suggest some adequate workaround.
The parametes key is missing and it should be flat:
parameters:
host.main: example.com
Or
parameters:
hosts:
main: example.com
other: example.com
twig:
globals:
hosts: "%hosts%"

Symfony Doctrine generate entities from multiple databases

With Doctrine in Symfony2 there is a simple way to start a project with reverse-engineered Entities created from existing database schema. It is quite well documented here. There is not mentioned how to reverse-engineer data from a non-default database when using multiple databases (which is documented here).
I found the solution here, it works like this:
php app/console doctrine:mapping:convert --em="troller" --from-database yml ./src/NAMESPACE/NAMEBundle/Resources/config/doctrine/metadata/orm
However, I'm just getting the exception as if the second entity manager didn't exist. Even though I have config.yml according to docs.
[InvalidArgumentException]
Doctrine ORM Manager named "troller" does not exist.
Any ideas?
Did you specify an entity manager with "troller" name?
You can do this with a snippet of code like this (into app/config/config.yml file)
orm:
default_entity_manager: default
entity_managers:
default:
connection: default
mappings:
AcmeDemoBundle: ~
AcmeStoreBundle: ~
troller:
connection: troller
mappings:
YourTrollerBundle: ~
In this example, you've defined two entity managers called default and troller. The default entity manager manages entities in the AcmeDemoBundle and AcmeStoreBundle, while the troller entity manager manages entities in the YourTrollerBundle. You've also defined two connections, one for each entity manager.
Obiously define a new connection and entity manager, isn't enaugh: you have to specify "connection parameters" also (like db name, user, password, driver, and so on)
troller:
driver: "%database_driver2%"
host: "%database_host2%"
port: "%database_port2%"
dbname: "%database_name2%"
user: "%database_user2%"
password: "%database_password2%"
charset: UTF8

Resources