I have a question, but I think it is really simple for someone who have knowings about doctrine and its meta-pathes to the entities.
In my annotations is written:
namespace Entity\Model;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Mapping AS ORM;
/**
* TblBaseurls
*
* #ORM\Table(name="tbl_baseurls")
* #ORM\Entity
*/
class TblBaseurls
{
/**...
But this command...
$classes = $entityManager->getMetadataFactory()->getAllMetadata();
...let me get an empty array.
If I change the annotations and delete the "#[ORM]\Entity" (means delete only the [ORM]) the classes are found and I get a correctly defined array.
My question about this: What I have to write without to delete all the ORM in the annotations (have to many classes to do that)? I have some changes made in the namespace path, but it takes no effect.
Thanks in advance.
Frank
Related
Please consider following jsdoc-ed callback
/**
* #callback create_stub
* #param {Object} co_obj
* An object containing method to create the stub.
* #param {string} method_name
* A member function name of co_obj.
* ...
*/
The above will work for JSDoc's documentation generator. Will be documented as typedef.
For Closure-Compiler however, it does not seem to work well. By "not work well" I mean:
Even if it works, compiler will not be able to perform type checks I think because -
the only solution for closure-compiler to use callback tag is just to remove the warning(See Documenting callback parameters using Google Closure Compiler).
Note: that solution did not work for me. I still get "Unknown type create_stub" warning.
For VS-Code: Intellisense will not work. See "https://github.com/Microsoft/TypeScript/issues/7515".
Now, with #typedef - everyone will be happy except that "I can not document parameters".
And, with #name (see Best way to document anonymous objects and functions with jsdoc) - generator will document callback as method rather than a typedef, closure-compiler seem to have no effects.
Finally, I would like to say that I am currently using my own workaround that uses both #name and #typedef to keep Generator, CC and VS-Code happy. Sample:
/**
* #function
* #name Klass.typedefs.create_stub
* #param {Object} co_obj
* An object containing method to create the stub.
* #param {string} method_name
* A member function name of co_obj.
* ...
*//**
* #private
* #typedef {function(Object, string)} Klass.typedefs.create_stub
*/
Klass.typedefs.create_stub; // this line is needed for Closure-Compiler compatibility
Thanks for your time.
I am having trouble with getting functional tests to run in Symfony3 with Doctrine.
I have the code organized in two bundles with which need to be accessed by one EntityManager with entities stored in two different MySQL databases.
To achieve this, all Entities have a "schema" annotation in their definition, like this:
/**
* #ORM/Table(name="tablename", schema="schema")
* #Entity( ... )
*/
Without this setting, it has been my experience, that the Doctrine schema:create tool is not able to correctly create the entities in the right databases.
However it appears, that the schema annotation is not considered to be environment dependent.
So when I want to run functional tests that need to load fixtures, the ORMPurger tries to purge schema.tablename, where it should use the table/schema "test_schema".
Is there any way to keep the schema annotation but make it dependent on the environment, so that when the environment is "test", a different schema is used?
EDIT:
It appears that using the "schema" annotation for entities is pretty terrible all around when you are using different Symfony environments. At least when used in conjunction with MySQl, at least I think that that is the reason, since MySQL doesn't actually support schemas.
Every Symfony or Doctrine command I tried to take the schema annotation literally, regardless of the --env setting.
I've done some more digging and found what I needed to do perfectly laid out here:
Programmatically modify table's schema name in Doctrine2?
So I added an EventListener, that adds the correct schema according to the EM used so I don't need hard-coded schema annotations anymore.
Heres the code for the Listener I've made:
<?php
namespace /* ... */
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Event\LoadClassMetadataEventArgs;
class MappingListener
{
public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs)
{
/** #var EntityManagerInterface $entityManager */
$entityManager = $eventArgs->getEntityManager();
/** #var ClassMetadata $classMetadata */
$classMetadata = $eventArgs->getClassMetadata();
$database = $entityManager->getConnection()->getDatabase();
$classMetadata->table['schema'] = $database;
}
}
I have an autobean with a property that is only needed for the UI. I believe that you can null out values and the AutoBeanCodex will not serialized that property, but that equates to an extra step which is needed at serialization.
I was hoping for some annotation similar to the Editor #Ignore annotation. For example:
public interface Foo {
...
#Ignore
String getUiOnlyProperty();
}
So, other than nulling out the value at serialization time, is there any other way to keep an autobean property from being serialized?
Autobeans are meant to be a Java skin on a JSON/XML/whatever format - they aren't really designed to hold other pieces of data. That said, several thoughts that either nearly answer your question with out-of-the-box tools, or might inspire some other ideas on how to solve your problem.
You should be able to build read-only properties by omitting the setter. This isn't quite what you are asking for, but still might be handy.
Along those lines, the JavaDoc for the #PropertyName annotation seems to allude to this possible feature:
/**
* An annotation that allows inferred property names to be overridden.
* <p>
* This annotation is asymmetric, applying it to a getter will not affect the
* setter. The asymmetry allows existing users of an interface to read old
* {#link AutoBeanCodex} messages, but write new ones.
*/
Reading old messages but writing new ones seems like it might be closer to what you are after, and still allowing you to work with the thing-that-looks-like-a-bean.
The real answer though seems to be the AutoBean.setTag and getTag methods:
/**
* A tag is an arbitrary piece of external metadata to be associated with the
* wrapped value.
*
* #param tagName the tag name
* #param value the wrapped value
* #see #getTag(String)
*/
void setTag(String tagName, Object value);
...
/**
* Retrieve a tag value that was previously provided to
* {#link #setTag(String, Object)}.
*
* #param tagName the tag name
* #return the tag value
* #see #setTag(String, Object)
*/
<Q> Q getTag(String tagName);
As can be seen from the implementation of these methods in AbstractAutoBean, these store their data in a totally separate object from what is sent over the wire. The downside is that you'll need to get the underlying AutoBean object (see com.google.web.bindery.autobean.shared.AutoBeanUtils.getAutoBean(U) for one way to do this) in order to invoke these methods.
child class/interface decoded as a parent interface does not explode on decoding allowing the goods to be passed together before the marshalling steps. my immediate test of the actual code below is performing as expected.
public interface ReplicateOptions {
/**
* Create target database if it does not exist. Only for server replications.
*/
Boolean getCreateTarget();
void setCreateTarget(Boolean create_target);
//baggage to pass along
interface ReplicateCall<T> extends ReplicateOptions {
/**
* If true starts subscribing to future changes in the source database and continue replicating them.
*/
AsyncCallback<T> getContinuous();
void setContinuous(AsyncCallback<T> continuous);
}
}
I know it's possible to get IDE autocompletion from the *Table classes in Doctrine by doing things like this:
SomethingTable::getInstance()-><autocomplete>;
But the most important part is missing. I want autocomplete on the model classes themselves, not just the Table classes. It appears that Doctrine is not properly declaring the PHPdoc #return object types in the find and other standard model methods.
For example what I want to be able to do is this:
$something = SomethingTable::getInstance()->find($id);
$something-><autocomplete>
and have that pop up the methods and properties of the Something class.
I should mention too that I don't specifically care about using the SomethingTable::getInstance() syntax at all. ANY decent syntax that's standard Symfony is acceptable. Most of the time I'm fetching objects (or Doctrine_Collections) via custom queries like this:
$somethings = Doctrine_Query::create()
->from('Something s')
->leftJoin('s.SomethingElse s2')
->where(...);
By the way, in case it's not clear, I'm asking if there's any automatic solution to this with ANY of the various Doctrine find, fetch or query syntaxes. I'm NOT asking how to manually edit all the PHPdoc headers to cause the behavior I want.
I'm using NetBeans 6.9.1 and Symfony 1.4.12 with Doctrine, but not everyone working on the same code uses NetBeans.
The problem is that autogenerated *Table classes have the wrong phpdoc #return in the getInstance() method:
/**
* Returns an instance of this class.
*
* #return object MyModelTable
*/
public static function getInstance()
{
return Doctrine_Core::getTable('MyModel');
}
You just need to manually fix the #return line deleting the word "object":
* #return MyModelTable
And magically IDE autocompletion just works, giving you all the instance and static methods:
MyModelable::getInstance()->... //(you'll have autocompletion here)
I know, its a pain to have to manually fix this but at least it only have to be done once for each model *Table file.
In netbeans its quite easy:
$foo = ModelNameTable::getInstance()->find(1); /* #var $foo ModelName */
/* #var $foo ModelName */ tells netbeans to handle the variable $foo as a ModelName class.
just fix the generated model files by adding
/**
* #return ModelNameTable
*/
in the comment of the getInstance() method. This will provide autocomplete for the model file.
Regarding the find method, you can edit the comment of the class like this :
/**
* #method ModelName find()
*/
I think it might be possible for you to do this automatically by creating you own skeleton files.
Or not : Symfony Doctrine skeleton files
You could use sed to achieve this, or perhaps build your own task using the reflection api.
I'm working on Magento templates, but this issue would apply to any template loading system.
As these templates are loaded by the template engine there's no way for the IDE (in this case Aptana) to know what object type $this is.
Potentially it could more than one object as a single template could be loaded by multiple objects, but ignoring this, what would the correct phpdoc syntax be to specify a specific class for the $this object?
You can define it like this:
/* #var $this type */
where type is a class name
To be clear, using $this should only ever indicate an object of the current class, right?
PhpDocumentor doesn't currently (v1.4.3) recognize $this as a specific keyword that should equate to a datatype of the class itself.
Only datatypes known by PHP and classes already parsed by PhpDocumentor are the proper datatype values to use with the #return tag. There is a feature request in to have some option available in PhpDocumtentor to aid in documenting fluent methods that always "return $this". [1]
In the case of the #var tag, I don't see how it would be feasible for a class variable to contain its own class instance. As such, I can't follow what "#var $this" should be saying.
If, however, your intention with $this is not for fluent methods that "return $this", and was simply to be some shortcut to PhpDocumentor and/or your IDE to magically guess what datatypes you might mean by using $this, I'd have to guess there's no way to do it. The closest suggestion I could make would be to use the name of a parent class that is a common parent to all the various child classes that this particular var/return might be at runtime, and then use the description part of the tag to have inline {#link} tags that list out the possible child classes that are possible.
Example: I have a Parent abstract class with Child1, Child2, and Child3 children that each could occur in my runtime Foo class.
So, Foo::_var could be any of those child class types at runtime, but how would I document this?
/**
* #var Parent this could be any child of {#link Parent}, {#link Child1}, {#link Child2}, or {#link Child3}...
*/
protected $_var;
Getting back to the "return $this" issue, I'd document things in a similar way:
/**
* a fluent method (i.e. it returns this class's instance object)
* #return Parent this could be any child of {#link Parent}, {#link Child1}, {#link Child2}, or {#link Child3}...
*/
public function foo() {
return $this;
}
Documenting this way at least allows your class doc to have links to the particular classes. What it fails to do is highlight the fluent 'ness. However, if your IDE is capable of recognizing the class names, then perhaps it will be able to do the necessary logical linking to those other classes. I think Eclipse is able to do this at least with popup help, if you hover over the class name in the tag's description. I do not think Eclipse can use this to then make the various child classes' methods available in code completion. It would know about the Parent methods for code completion, because the datatype I explicitly list is Parent, but that's as far as the IDE can go.
[1] -- http://pear.php.net/bugs/bug.php?id=16223
I have found that defining a type with #var for $this does not work - presumably because $this is special and is treated as such by Aptana. I have a similar need to the poster I think - it is in template files (in my case simply located and included by functions within the data class) that I wish to set a type for $this. As #ashnazg says, setting a type for $this within a class definition is not needed, because the type of $this is always the type of the class (up to inheritance).
There is, however, a workaround for template files. At the top of the template file simply put something like
/**
* #var My_Data_Model_Type
*/
$dataModel = &$this;
Then simply use $dataModel (or whatever you choose to call it - maybe something shorter) instead of $this in the template