Cannot generate zf2 DoctrineORMModule entities from mapping files - php

I have zf2 DoctrineORMModule and DoctrienModule installed. I am trying to use the command tool to create mapping files and generate entities from these mapping files. (I know this isn't the preferred method, but this is how I'm going to do it. I have my reasons.)
I have a restful module configured and here is my Doctrine Configuration for this module.
// Doctrine config
'doctrine' => array(
'driver' => array(
'Restful_driver' => array(
'class' => 'Doctrine\ORM\Mapping\Driver\AnnotationDriver',
'cache' => 'array',
'paths' => array(__DIR__ . '/../src/Restful/Entities')
),
'orm_default' => array(
'drivers' => array(
'Restful\Entities' => 'Restful_driver'
)
)
)
)
I first run
doctrine orm:convert-mapping xml /to/my/dest/path --from-database --force
This will create my xml file with all the table info. This part works fine and I can view the xml that it created. Next I try to run
doctrine orm:generate-entities /to/my/dest/path --generate-annotations
--generate-methods
I don't get any errors but also I don't get any results either. The output from the previous command is.
No Metadata Classes to process.
I have tried to read around but havn't found any articles that really solve my problem. Most say something about not having my annotations/mappings not configured correctly. But I can dump the entity manager through a controller.
var_dump($this->getServiceLocator()->get('doctrine.entitymanager.orm_default'));
What do I need to do to get this to generate entities from xml mappings? Any help is appreciated.

I had a similar problem with YAML files and posted my solution here. I'm sure this will work with xml files as well. Just try to add
$driverImpl = new \Doctrine\ORM\Mapping\Driver\XmlDriver(array("YOUR_PATH_TO_XML_FILES"));
/* #var $em \Doctrine\ORM\EntityManager */
$em = $application->getServiceManager()->get('doctrine.entitymanager.orm_default');
$em->getConfiguration()->setMetadataDriverImpl($driverImpl);
to the doctrine-module.php.

Did you try using the doctrine-module script in vendor/bin? It should be all set up already to read your app's configs.
./doctrine-module orm:generate-entities ~/doctrine-entities

This "error" occured because you use Annotation Driver for generating. This driver uses your current exist entities and doesnt look at xml. If you want to create Entities from XML - you should send to DI in doctrine configuration section XML driver with need path.
I use another zf2 doctrine module and my DI config has another format, so i cant to send you properly DI example.

Related

How to create MongoDB views in PHP using MongoDB\Client() library?

I'm using following:
PHP 7.2
MongoDB 3.4
Pecl 1.5.2
I'm working on a Laravel project. It uses MongoDB as database. I have few collections on which I have to create Mongo Views using Laravel migration. I was wondering whether its possible to create Mongodb Views using PHP. Currently I have a work around. I have created a JavaScript file which has MongoDB db.createView() query in it. It also takes view name and collection name as parameters. Following is my work around. $db has database name, $view has view name, $collection has collection name and $script has the path to the JavaScript file. This code I'm writing in migration class's up() method.
$cmd = "mongo $db --eval \"var view='$view', collection='$collection'\" $script";
exec($cmd);
In my Javascript file, I have code something like following
db.createView(view, collection, <aggregate query>);
So as everyone can see, I'm running terminal command from PHP to make views. So is there any PHP function in mongo library to make mongo views?
If you're using mongo with Laravel, I'm going to assume you're using jenssegers/mongodb to use it with Eloquent.
So, let's assume you have your mongo database set up as your 'mongodb' database connection. You need the MongoDB\Database for your database. You can get this with:
$mongo = app('db')->connection('mongodb')->getMongoDB();
Of course, if you're not using jenssegers/mongodb, you can still do the same thing with mongodb/mongodb as well.
$mongo = (new MongoDB\Client)->selectDatabase($db);
This has a method called command (see https://docs.mongodb.com/php-library/current/reference/method/MongoDBDatabase-command/), which corresponds to the db.runCommand method from the mongo cli. db.createView calls that method (see https://docs.mongodb.com/manual/reference/method/db.createView/#db.createView)
So, you can use $mongo->command to create the view like this:
$mongo->command([
'create' => $view,
'viewOn' => $collection,
'pipeline' => $aggregateQuery,
'collation' => ['locale' => 'en'],
]);
You can use this library mongoPhpLibrary
This will make your work easy

laravel: config file name convention?

foo_constants.php or fooConstants.php?
It seems laravel would do some name conversion when you use Config::get('...'), which one do you use?
foo.php
Why specify constants at all? Convention I've generally seen is single word filenames. I think in general most 'config' type settings will be constant in an environment even if it is variable between environments.
Take a look at the aws/aws-sdk-php-laravel composer package as an example. That file is named config.php in the package, but gets published to aws.php.
rydurham/Sentinel is another popular package. It also only has a single-word filename.
Update
In the situation you describe in your comment, I would do something like this:
<?php // File: foo.php
return [
'sheep' => [
'clothing' => 'wool',
'chews_on' => 'cud',
],
'wolf' => [
'clothing' => 'fur',
'chews_on' => 'sheep',
],
];
And you can access both of those via Config::get('foo.sheep') and Config::get('foo.wolf'), respectively. When they're defined on the server, they're still 'on the server' so to speak. If you wish to release the values stored in foo.sheep to the public you can, and you can do so without also exposing foo.wolf.

propel sql:insert throws error 'Unable to parse contents of sqldb.map'

I'm trying to build a project with Propel these days. I did the basic 'bookstore' tutorial on propelorm.org/documentation/02-buildtime.html, but when I'm trying to finally insert the generated sql code via propel, to fill the database, the following error is thrown:
[Exception] Unable to parse contents of "/sqldb.map".
Unfortunately I've got no idea what went wrong; I followed the tutorial as precisely as possible.
Information about my installation and what I've done so far:
1) Localhost installation (Mac OS 10.8.5) with PHP 5.4.27 (DOM Module, PDO and SPL enabled) and MySQL 5.6.19.
2) successfully parsed Composer.json with:
{
"require": {
"propel/propel": "~2.0#dev"
},
"autoload": {
"classmap": ["bookstoreDb/generated-classes/"]
}
}
3) created a schema.xml with foreign keys, exactly like in the tutorial (propelorm.org/documentation/02-buildtime.html).
4) created a config file, propel.yaml, in subfolder 'conf', again like in the tutorial.
5) used the propel scripts to generate the necessary sql (propel sql:build), model (propel model:build) and configuration files (propel config:convert). The result of these commands are as indicated as in the tutorial.
6) created the database 'bookstore' successfully via terminal.
7) trying to insert the sql code via propel sql:insert. Now the error as described above is thrown:
[Exception] Unable to parse contents of "/sqldb.map".
Here is the index.php of the project:
// setup the autoloading
require_once 'vendor/autoload.php';
// setup Propel
require_once 'bookstoreDb/generated-conf/config.php';
// Here I get the parse error: parse error in ../bookstore/bookstoreDb/generated-classes/Base/Author.php on line 138
$author = new Author();
$author->setFirstName('Jane');
$author->setLastName('Austen');
$author->save();
And here the config.php:
$serviceContainer = \Propel\Runtime\Propel::getServiceContainer();
$serviceContainer->checkVersion('2.0.0-dev');
$serviceContainer->setAdapterClass('bookstore', 'mysql');
$manager = new \Propel\Runtime\Connection\ConnectionManagerSingle();
$manager->setConfiguration(array (
'classname' => 'Propel\\Runtime\\Connection\\ConnectionWrapper',
'dsn' => 'mysql:host=localhost;dbname=bookstore',
'user' => 'root',
'password' => 'password',
'attributes' =>
array (
'ATTR_EMULATE_PREPARES' => false,
),
));
$manager->setName('bookstore');
$serviceContainer->setConnectionManager('bookstore', $manager);
$serviceContainer->setDefaultDatasource('bookstore');
Where may be the problem? And is there some other way to setup a basic project? I'd appreciate every help! Thanks!
I submitted an issue for this: https://github.com/propelorm/Propel2/issues/694
SqlBuildCommand uses configured sql-dir
$manager->setWorkingDirectory($generatorConfig->getSection('paths')['sqlDir'])
SqlInsertCommand only uses the command line option
$manager->setWorkingDirectory($input->getOption('sql-dir'));
adding --sql-dir option with correct sql dir to propel sql:insert does work
fix is submitted https://github.com/propelorm/Propel2/pull/695 but not merged yet

Multiple Controllers Zend Framework 2 - Entity Manager Doctrine 2

I am using Zend Framework 2.2.2 and Doctrine2 Module 0.7.0.
My goal is to have my functions related to a task in a standalone php-class. My current workflow is between two different programms: get data -> modify and store data -> send data.
This workflow needs functions from 3 ZF2 modules:
1. source software module
2. internal storage mechanism module
3. destination software module
The first task is successfull but when I move my data to the second module like this (shrinked to the main code):
use MTNewsletterEngine\Controller\NewsletterEngineController;
/** #var \MTNewsletterEngine\Controller\NewsletterEngineController */
private $_newsletterEngine;
$this->_newsletterEngine = new NewsletterEngineController();
[...]
$this->_newsletterEngine->addNewNewsletterRecipient($emailAddresses,1);
The second Controller has problems getting the service locator:
Fatal error: Call to a member function get() on a non-object in C:\xampp\htdocs\app\trunk\module\MTNewsletterEngine\src\MTNewsletterEngine\Controller\NewsletterEngineController.php on line 51
Line 51:
$em_mtnewsletterengine = $this->getServiceLocator()->get('doctrine.entitymanager.orm_mtnewsletterengine');
NewsletterEngineController is the Main Controller from Module MTNewsletterEngine.
I am confused as I don't know how to get this solved. Thanks.
Do not create a new instance of NewsletterEngineController by using the new keyword. The ServiceLocator will not be injected to the created object this way. Use Zend\ServiceManager to retrieve an instance of Zend\Mvc\Controller\ControllerManager (alias: "ControllerLoader" (ci)) and use the get method, to load the target controller. Zend\Mvc\Controller\ControllerManager extends the ServiceManager itself (because it is a plugin manager).
Check your module.config.php. The controller should be listed as an invokable controller.
Example:
'controllers' => array(
'invokables' => array(
'MTNewsletterEngine\Controller\NewsletterEngine' => 'MTNewsletterEngine\Controller\NewsletterEngineController'
),
),
$this->_newsletterEngine = $this->getServiceLocator()
->get('ControllerLoader')
->get('MTNewsletterEngine\Controller\NewsletterEngine');
For more information read the manual and try to understand the way the ServiceManager / ServiceLocator (which is part of Zend\Di) works.
Maybe you should also think about the structure of your application. I am not sure what you are trying to do there but it seems like you are mixing up different application layers.
Docs
http://framework.zend.com/manual/2.2/en/index.html#zend-di
http://framework.zend.com/manual/2.2/en/index.html#zend-servicemanager

ServiceLocatorAwareInterface confuses the DI container when running module tests

I have a new module for which I'm writing tests.
The module contains a class which implements ServiceLocatorAwareInterface because it needs to create other objects using the DI container. Everything works fine when running in the skeleton app, but when running module tests i get the following:
Zend\Di\Exception\RuntimeException: Invalid instantiator of type "NULL" for "Zend\ServiceManager\ServiceLocatorInterface"
Researching a little bit I find that the DI container tries to create a new object of type "ServiceLocatorAwareInterface", which is of course wrong.
Digging a little more in the tests bootstrap, I find that adding the following line solves the problem, as in the DI now knows what class to instantiate for that interface.
$di->instanceManager()->addTypePreference('Zend\ServiceManager\ServiceLocatorInterface', new \Zend\ServiceManager\ServiceManager());
I'm not sure whether this is the best solution to the problem, as the ServiceManager passed by me is a dummy one.
Does anyone have any other ideas?
Yes, you are going in the right direction. (See the preferences documentation)
Not many people are using DI these days in favor of the ServiceManager (myself included), but if the config for DI remains similar to how it was during the ZF2 betas, you should be able to add a "preferences" section to your DI config like so:
'di' => array(
'instance' => array(
'preferences' => array(
'My_Interface' => 'My_Implementation_Or_Alias',
)
)
)
This configuration block can replace your call to $di->instanceManager()->addTypePreference()
Looking through the current docs, and mimicking the example here, you may have success defining the DI config as shown below using the ZF2 official release:
$di = new Zend\Di\Di;
$di->configure(new Zend\Di\Config(array(
'instance' => array(
'preferences' => array(
'My_Interface' => 'My_Implementation_Or_Alias',
)
)
)));
What you can do in this case is the following.
In your bootstrap for the module unit tests create a dummy application that is configured with a configuration that will only load the module you're testing.
...//other code before this for autoloading stuff
// DON'T RUN THE application in your tests, just init it
$application = Zend\Mvc\Application::init(include 'config/test.application.config.for.module.php');
$fullyConfigedManager = $application->getServiceManager();
TestCases::setServiceManager( $fullyConfigedManager );
After the application has been boostrapped you can pull the ServiceManager from the application directly. This service manager should be fully configured with any factories, invokables, and configuration from your module.

Categories