I created yaml configuration for Doctrine. When I'm trying doctrine orm:generate-entities, it creates php files with getters and setters in camel case. So, is_public field transforms into setIsPublic and getIsPublic methods. It's owful. How can I get set_is_public and get_is_public? I can manually edit generated php files, but I don't know what will happen when I change the schema.
You can choose a naming strategy that Doctrine will use to generate the items using:
Using a naming strategy you can provide rules for automatically
generating database identifiers, columns and tables names when the
table/column name is not given. This feature helps reduce the
verbosity of the mapping document, eliminating repetitive noise (eg:
TABLE_).
For your specific case, I think you're looking at something like:
$namingStrategy = new \Doctrine\ORM\Mapping\UnderscoreNamingStrategy(CASE_LOWER);
$configuration()->setNamingStrategy($namingStrategy);
The linked topic goes on to show you how you can write your own custom naming strategy.
If you're using Symfony, it's even easier (like most things are with Symfony, but that's just my opinion) via config.yml:
doctrine:
orm:
naming_strategy: doctrine.orm.naming_strategy.underscore
Symfony's coding standards encourage Symfony users to use camelCase:
Naming Conventions
Use camelCase, not underscores, for variable,
function and method names, arguments
Personal advice - do not generate entities by doctrine orm:generate-entities.
Use plain PHP to create class. Why?
Orm uses reflection on privates to communicate with database. You dont need to generate setters and getters. I recomend You to use design patterns such as factory or constructor to achive Your goal. Decorators also should work fine.
<?php
class MyClass
{
private $id;
private $name;
public function __construct(int $id, string $name)
{
$this->id = $id;
$this->name = $name;
}
}
$camelCase is not only Symfony's recomendation for code standard. It's based on PSR2. I highly recomend using PSR2, code gets clean and standarized.
Standard ORM naming strategy is $camelCase private var to snake_case column name. If you want to change it otherwise, consider: other naming stategies
Related
Symfony uses a set of coding standards to set out for us how to program and what style we should use. My question is short and simple. I would like to know if symfony (together with doctrine ORM) has a similiar set of standards when it comes to building and structuring my database.
For example:
Should I use Camel Case?
Should my table name be user or users
Do I use capitals?
What charset is recommanded?
Basically, you do not need to care about database naming as Doctrine will do everything for you.
You should use Doctrine cli commands to generate your database schema based on your entities, or even better use Doctrine Migrations to maintain changes.
Should I use Camel Case?
For entity class names, I'd recommend sticking with PSR, so yes, use CamelCase.
Symfony by default uses underscore naming strategy, so entity CamelCase will be generated as table camel_case (if not manually overriden).
You can set another naming strategy, but the default underscore strategy is a fine choice.
Should my table name be user or users
user is a ANSI SQL reserved word, so I recommend using users. Or, if you prefer having entities in singular, try person instead.
Do I use capitals?
Again, Doctrine naming strategy will solve this for you. Moreover, eg postresql converts all table names and such identifiers to lowercase, so using capitals explicitly can cause problems.
What charset is recommanded?
Use UTF-8 (or more specifically utf8mb4 if needed). There are few reasons to use any other.
Without scrutinizing why I want this (it may sound like a bad approach, but I have good reason) I want to know if there is a way in the standard-framework-edition 3.1+ to create a relational association to an entity that may not exist...
Firstly I do realize this determines the schema and that's fine. So if an entity does not exist, it doesn't create a foreign key and the field is always null, or if the target entity does exist, it creates the foreign key and the field works like a normal association...
Secondly, this only changes project to project, and may change down the line as an update to which I realize a manual schema update could be necessary.
Preferably without 3rd party bundle dependencies... hoping for the standard framework to do this,
Anybody?
Thanks in advance
Edit
I am using annotations in my entities with doctrine ORM
Furthermore
The simplest version of why I am doing this is because certain bundles are optional project-to-project, and bundle A may make use of entities in bundle B only if it is present. I have considered using services and if container->has then container->get, or the XML on-invalid="null" approach, but that doesn't address property persistence. I was happy with storing a non-mapped value as a custom relational field, which is fine, just lengthier and wondered if perhaps there was a way Doctrine could ignore a missing targetEntity...
Hm, perhaps I misunderstand your question, but this sounds like a normal 'nullable' association to me?
Create your assocation via annotation:
/**
*
* #var Child
* #ORM\ManyToOne(targetEntity="Child")
*/
private $child;
and use
setChild(Child $child = null)
{
$this->child = $child;
}
as a Setter to allow nullable values.
And your getter might look like:
getChild()
{
return $this->child;
}
In case there isn't any child it will return null.
I will keep the other answer as it responds to the question for a 'nullable association target' live data.
This is the answer for a 'nullable association target' meta data which is a different thing.
OP asks to provide a targetEntity in the metadata which cannot exist in his case, e.g. is not there in a different bundle (or whatever OP's mysterious reason might be).
In that case I recommend to build upon Doctrine's TargetEntityListener which is able to resolve the targetEntity during runtime and targetEntity can be set to an Abstract Class or an Interface:
/**
* #ORM\ManyToOne(targetEntity="Acme\InvoiceBundle\Model\InvoiceSubjectInterface")
* #var InvoiceSubjectInterface
*/
protected $subject;
InvoiceSubjectInterface will then be replaced during runtime by a specific class provided by config e.g.:
# app/config/config.yml
doctrine:
# ...
orm:
# ...
resolve_target_entities:
Acme\InvoiceBundle\Model\InvoiceSubjectInterface: AppBundle\Entity\Customer
So this should be eiter an extendable behaviour for providing no class or implementing an own solution.
I'm trying to work effectively with DDD and Doctrine2 on a project with lot of business logic.
I understand that we need decouple the domain objects from other concepts related to the system, i.e. in a layered architecture, "the domain layer" must be isolate from other layers, like the persistence layer/service (Doctrine2 for me).
But there is one thing it's hard to understand for me: in several code examples of DDD with Doctrine 2, aggregates in domain entities are managed with Doctrine ArrayCollection, I found this kind of code :
namespace Acme\Domain\Model\Users;
use Doctrine\Common\Collections\ArrayCollection;
class User {
//...
/**
* Collection of Roles
*
* #var Collection of Roles
*/
protected $roles;
/**
* Constructor.
*/
public function __construct()
{
$this->createdAt = new \DateTime();
$this->roles = new ArrayCollection();
}
public function getRoles()
{
return $this->roles;
}
//...
}
For me, this implementation create a high coupling between domain models and the persistence service, Doctrine2.
On the other hand, if DDD Entity and Doctrine Entity classes are decoupled, there is to many layers/classes, in my opinion.
What do you think? Is there a better way to avoid/handle this?
Don't be alarmed by the use of ArrayCollections. Notice that is in the Doctrine/Common namespace. It's just a little utility array wrapper with no particular ties to the Doctrine persistence layer. You could easily replace it with another array class.
The manual addresses this issue: https://www.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html#collections.
As far as decoupling goes, it is possible to do DDD modeling while limiting yourself to doctrine entities. It is very limiting and generally discouraged. So yep, you will probably need another layer.
It's difficult to justify the overhead of a pure DDD implementation in PHP.
I was looking for a built-in method to urlize/slugify a string, instead of copying a strandard one found on google.
Thus I found this : http://sourcecookbook.com/en/recipes/59/call-the-slugify-urlize-function-from-doctrine , referencing to this Doctrine Class http://www.tig12.net/downloads/apidocs/symfony/lib/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine/Doctrine_Inflector.class.html , with the method urlize() which is exactly what I'm looking for.
But, in my Doctrine Bundle from Symfony 2, in \vendor\doctrine\common\lib\Doctrine\Common\Util my Inflector class is pretty empty.
What happened to this urlize() method ? Do I have to recode it ?
There's https://github.com/Behat/Transliterator which includes the urlize function from Doctrine1
This is the part taken from Doctrine 1.2.3
Doctrine inflector has static methods for inflecting text
You could just composer require behat/transliterator
and have a HelperClass extending Behat\Transliterator.
And then be able to do: MyStringHelper::urlize("isn't that great?")
The file you are looking at (Doctrine\Common\Util\Inflector) is supposed to be used internally by Doctrine, to convert between table names (underscore separated), property names (camelCase), and class names (CamelCase).
What you are looking for can be achieved with the sluggable doctrine extension. You can ingtegrate it easily into a symfony2 application with stof/StofDoctrineExtensionsBundle.
I am using Apache CXF (apache-cxf-2.5.0) to create Web Services using a bottom-up approach (Java first approach). I want to return some data/records (for example, username, email) from a database table. I can write a Java class which returns a simple response. But I am not able to find way to return a response such as data/records extracted from a database table. How to do that?
You don't mention how you are accessing the database, but the basic idea is that you ensure that the classes that you return have JAXB annotations (notably #XmlRootElement or #XmlType) on them, which allows CXF to convert the instances of those classes into XML document fragments. The classes which you annotate this way probably should not have lots of functionality in them; they should exist just to hold data. (I find anything else too confusing given the complex lifecycle they'll have.) Once the annotations are in place, just return the relevant objects and all the conversions will happen automatically.
I'm talking a simple class like this:
#XmlRootElement // <---- THIS LINE HERE!
public class UserInfo {
public String username;
public String email;
}
You can use this in conjunction with other annotations (e.g., for your ORM) as necessary. Of course, if you're talking straight JDBC to the DB to get the information out, you won't need to worry about that.
The one tricky bit is that the objects being returned will have a lifespan that goes beyond that of the database transaction you're using; you may need to detach (i.e., do some copying, though the ORM layer might provide assistance) the objects extracted from the DB for that to work. This won't be much of a concern in this case as the DB you're describing is very simple (one table, no inter-row relations) but could be an issue if you make things more complex.