nelmio / alice Goto Github PK
View Code? Open in Web Editor NEWExpressive fixtures generator
License: MIT License
Expressive fixtures generator
License: MIT License
just use GLOB_BRACE
flag.
Hi,
how to store the password encoded in symfony2 for fosuserbundle?
Sermovi\Bundle\UserBundle\Entity\User:
user2:
username: tirengarfio
password: *******
email: [email protected]
Sorry for my english.
I have table, two columns which have ids of same Entity (not FK, only id)
Example.
Billing\Bundle\MiscBundle\Entity\TZone:
tzone1:
id: 0
defZone: -1
zoneReport: -1
zoneType: 0
tzone{2..6}:
zoneName: <city()>
id (unique): <current()>
defZone: @tzone<numberBetween(1,$id-1)>->id
zoneReport: @tzone<numberBetween(1,$id-1)>->id
But, if i want to make id like...
...
id (unique): <numberBetween(1,10000000)>
...
i will have problems with it. How I can solve this problem?
As an example, trying to load a YAML file with this fixture will fail:
Example:
__construct: [<fun_with_args(1, 2)>]
foo: 1
bar: 'oof'
I've tried to dig a bit where the problem was, and in YAML component of Symfony in Inline.php file, the comma is interpreted as a separator for the elements of the array.
I'm a little bit clueless on how to fix this though, as I cannot propose huge changes to the YAML parser of Symfony, so if you have any idea, I'd be very happy to help implement something.
I could not find yet, how to create and pass custom value objects as arguments which are not entities. I'd like to use a custom Doctrine column type, to geocode an entity using a custom PointType
which encodes and decodes Point
objects.
When I try to create a new object using this:
Domain\Data\Geopoint:
geo1:
__construct: [<latitude()>, <longitude()>]
Domain\Data\Location:
loc{1..100}:
name: <city()>
geopoint: @geo1
description: <sentences(2)>
I get an error message:
Class "Domain\Data\Geopoint" sub class of "Knp\DoctrineBehaviors\ORM\Geocodable\Type\Point" is not a valid entity or mapped super class
So it seems like the Geopoint class is tried to be persisted, which makes sense but in this case it is not meant to be an entity.
Now to my question: Is there a way to create those value objects (meaning objects which are not being persisted using the object manager)?
Thanks a lot for your awesome work!
It would be useful to pass result of one formatter into another formatter
Scenario:
user{1..10}
avatar: <myformatter(<current()>)>
#generates something like '/uploads/user/$current/avatar.png'
I need a post callback so that i can run some code on the object after creation.
So waht do you think about a generell event dispatcher implementation https://github.com/symfony/EventDispatcher.
So that for example we can call methods with __eventName
for example and also register globally come callbacks
callbacks:
class:
__post: { method: [parameter]}
class:
__post: { method: [parameter]}
how to reference from a hybrid fixture data set?
for instance
user1:
property: here goes reference to a fixture object created on something not alice
Many parts of the documents are outdated, for example the custom fixture data load class should use Fixtures instead of Fixture I believe, and should return the result
profile: @profile1, 'moderator'
can i do this?
setProfile($profile, $type)
Hello,
I can't figure out how to make variables work with reference. Actually, it doesn't even seem to be possible.
This is an example of what I'm trying to achieve:
Nelmio\Entity\Group:
group1:
name: Admins
owner: @user*
name: $owner->name
Since $owner variable should return a reference to a random user, how can I reuse that variable to get a property of a specific object?
Is there any solution to do that with Alice?
Hi,
First i think your bundle is a really good one :)
Now, let me explain the problem.
In one of my project, i had to fetch already persist data from the database when i add the fixtures, the doctrine fixtures system allow it through the $manager->getRepository().
Concretely, we had a huge amount of data about cities, country etc. that we add in the database with a postgresql import from CSV files. And during the fixtures load we need to add a city to user for example, so we fetch a city object with the repository and link it within the user.
And that's this case we can't apply with your bundle.
So, maybe it's our use of the fixtures that is bad but if not do you think you will include a use of the $manager to allow us to fetch from a repository?
Thanks a lot for your work !
Because I want to generate a random array with 0, 1, 2 or 3 items with a random word for each item, I tried to do something like this:
tags: <numberBetween(0, 3)>x <word()>
Unfortunately, it doesn't work.
This problem occurs when you do something like this:
...Entity\Country:
country{1..32}:
code: <countryCode()>
name: <country()>
It could be solved by adding new syntax rule, say it could like
...Entity\Country:
country{1..32}:
code: <countryCode()>!
name: <country()>
I will try and add this functionality when I'll come home after work...
Edit: Just re-read my message and it seems totally not clear... I meant when I have some unique fields in entities, that can't be generated by database, I need to use random values, but it often occurs that this values intersect with each other.
If an entity has a setter with type hint for DateTime and we dont' already have a DateTime as input then alice should attempt to convert it to DateTime.
I couldn't find a way to use a literal @ sign in a text field, other than by creating a custom provider that simply returned an @ sign.
For example, I'm storing Twitter handles, and wanted to have @username
stored in the database. In my YAML file I tried:
twitter (unique): 50%? @<username()>
And:
twitter (unique): 50%? \@<username()>
Neither of those work. The only way to make it work was to do something like:
public function at()
{
return '@';
}
twitter (unique): 50%? <at()><username()>
Would it be possible to include an escape character for @ signs?
Ping @Seldaek @jubianchi we use cool things like inheritance and we wonder if you're ok to create a new tagged version of alive as such features work like a charm for us, no particular bugs.
Hi!) I've also had that idea of fixtures to be done almost the same way. Anyhow, as long as you are maintaining it, i'll give you some input. Nesting fixtures turned out to be really useful. Also the unnamed entities.
fixtures: nudged_user: _type: User id: 1 username: nudged_user email: [email protected] password: _RANDOM_ algorithm: _RANDOM_ - _type: UserTrainingPlan user: 1 startDate: '-3 weeks' createdAt: '-3 weeks' updatedAt: '-3 weeks' overallProgress: - _type: Progress date: '-8 days' weekNum: 2 dayNum: 3 progressDone: - _type: ProgressDone createdAt: '-8 days' setNum: 1 repsNum: 10 weight: 300
I've tried everything I can think of, but I can't get alice to provide data for a join table which has an extra data column in it. Really, it's not a join table though if there is data and so I've got it setup as an actual entity in doctrine.
Is this possible with alice?
This sort of relates to #24
I'm trying to do the following to get a random image category passed to the imageUrl function
image: <imageUrl(270, 270, randomElement(array('abstract', 'animals', 'business')))>
Produces
Call to undefined function randomElement()
At the moment I'm getting around this in a very ugly fashion...
image: <imageUrl(270, 270, call_user_func(function() { $c = array('abstract', 'animals', 'business'); return $c[array_rand($c)]; }))>
Right now, I have a table with a composite primary key. When I load my fixtures I get: "Couldn't generate random unique value for Entity\FormulaColor: color in 128 tries."
The reason I have a join table as an Entity is because the many-to-many relationship also houses a 3rd piece of information. A percentage.
In any case, a composite PK would be nice to have.
EDIT
I was thinking something along this kind of syntax:
Entity\Car
brand (composite): Ford
model (composite): Taurus
year (composite): 1999
It would be useful to have additional functions to load strings and resources/streams from files. In a single example
Nelmio\Entity\Blog:
post1:
title: My title
content: <file(blog/post1.html)>
title_image: <resource(blog(post1.jpg)>
file()
should return the content of the file as string (like file_get_contents()
) and resource()
as stream (like fopen()
). Ideally both paths should get resolved relative to the yaml-file.
I'm trying to do something like this:
Nelmio\Entity\User:
date_template (template):
insertDate: <dateTimeBetween(now, now)>
modifiedDate: <dateTimeBetween($insertDate, now)
user_template (template, extends date_template):
username: <userName()>
user{1..5} (extends user_template):
name: <firstName()>
lastName: <lastName()>
When I use a range like that though, none of the templates get used. Note that if user_template
didn't extend date_template
, it will work. Also, if this was a single user (user1
) instead of a range, it will work.
Subj; for example I have users with referers and want to do something like:
Foo\User:
user{1..10}:
invited_by: @user*
or if I have users with friends:
Foo\User:
user{1..10}:
friends: 3x @user*
which obviously gives me error about reference not being created yet. Is there any known workaround for implementing self-referencing objects? If not, maybe you can give a hint about how to implement it and we can make up an PR.
I have an entity that has two public static constructors, and a private __construct, would it be possible to add support for calling static methods as constructors? I have a user entity that can be created from a facebook api response, and it can be created by registering through our site.
Here is an example, sorry if it's a bit convoluted:
public static function createFromFacebookResponse(array $fbdata) {
$user = new static($fbdata['email']);
$user->setFbId($fbdata['id']);
$user->setLoginSystem(self::LOGIN_FACEBOOK);
$user->setDisplayName($fbdata['name']);
if (isset($fbdata['location']) && is_array($fbdata['location']) && isset($fbdata['location']['name'])) {
$user->setCity($fbdata['location']['name']);
}
return $user;
}
public static function createFromRegistration($email) {
$user = new static($email);
$emailParts = explode('@', $email);
$user->setSalt(md5(uniqid(null, true)));
$user->setDisplayName($emailParts[0]);
$user->setLoginSystem(self::LOGIN_SITE);
return $user;
}
private function __construct($email) {
/* Initialization that is common for both constructors happen here,
for example, creating Doctrine ArrayCollections */
}
Is it possible using mathematical operators? For example: $field1 + $field2
Is it possible generating float numbers in a range? For example:
<numberBetween(150.0, 1500.0)>
Im using this but it only generate integer numbers.
What is the purpose of the conditional here?
if (true !== $data) {
$yaml = ob_get_clean();
$data = YamlParser::parse($yaml);
}
https://github.com/nelmio/alice/blob/master/src/Nelmio/Alice/Loader/Yaml.php#L44
According to the PHP docs (http://php.net/manual/en/function.include.php) include returns the integer 1 on success and boolean false on failure. The only time it can ever return true would be if there is a "return true" in the included file.
If we are just checking for success then it seems that it should be changed to:
if (1 === $data){...}
my tables are persisting like:
VendorBundle\Entity\SummaryClassification:
classification1:
name: 'thank you Jordi'
and
CordovalBundle\Entity\Summary:
Summary1:
name: 'King''s Pawn Game'
classification: @classification1->getId()
parentid: 0
but the problem is i am getting classification 0 in the table
what could it be? why?
I am dumping the object right before ORM\Dorctrine
/**
* {@inheritDoc}
*/
public function persist(array $objects)
{
foreach ($objects as $object) {
if (get_class($object) == 'CordovalBundle\Entity\Summary') {
ladybug_dump_die($object);
}
$this->om->persist($object);
}
if ($this->flush) {
$this->om->flush();
}
}
and I am getting the column value has a string:
\[CordovalBundle\Entity\Summaryclassification\]: string(24) "@classification1->getId()"
with or without @ it does not pick the actual id value
Whilst I understand that the following is the correct behaviour, it's actually really confusing.
I had:
Entity\Team:
team{1..10}:
name: <firstName()>
Entity\TeamMember:
teamMember{1..100}:
name: <firstName()>
team: @team*
This tries to pass a TeamMember
instance to the setTeam()
accessor of TeamMember
rather than a Team
instance. I presume the wildcard is matching the teamMember
key before team1
etc. Changing this to:
Entity\Team:
team{1..10}:
name: <firstName()>
Entity\TeamMember:
member{1..100}:
name: <firstName()>
team: @team*
Fixes the issue.
But I think it should be made clear or have a wildcard operator that only operates on numbers to allow the original version to work.
I think, it isn't possible yet to do a data inheritance between data sets.
Use case:
You have an User with complex structure and you have to do a lot of duplicates for "basic" data. The solution is to create a base user data for re-usage. The other User data can inherit the data from this base data set.
Example:
User:
base:
username: <username()>
email: <email()>
is_admin: 0
admin:
@inherits: base
is_admin: 1
What do you think about this feature?
I am not sure if this is a bug or a feature, but it does break working code.
I had set a DateTime
there and now it is no longer available.
Maybe this idea could be something for 2.0.
Instead of handling the instantiation of new Object in Load\Base::createInstance()
, the whole process of handling and referencing instances could be done with a Dependency Injection Container.
The creating and referencing would just be configured in a ContainerBuilder. At the end of the fixture load, all public instances would be fetched like this $container->get('user1')
.
Using a container could also help solve issues like forward references #59.
What do you think?
In an entity, I have a text field that I use to store biographies of people. These are plain text and need to be multiple paragraphs. I saw the paragraphs()
provider in the Faker documentation and thought I would be able to use that, but wanted a random number of them.
So, for example:
biography: <paragraphs(3)>
This doesn't work because it returns 3 separate strings, and I needed a single string concatenated with newlines.
I also wanted to have a random number of these so I tried:
biography: <paragraphs(<numberBetween(0, 4)>)>
That also doesn't work because it isn't parsed correctly. I also tried:
biography: <numberBetween(0, 4)>x <paragraphs(1)>
But that puts 3x lorem...
into the column in the database. Is it possible to have a random number of paragraphs, separated by newlines added to a field?
Currently faker attempts to parse html/xml as faker placeholders. This means that you cannot use regular html tags like <strong>
or xml elements like <username>
in your fixtures
Hi,
I'm working with a lot of value objects here and the definition is kinda hard to read & maintains. Here's my use case:
Location\Location:
Paris:
__construct: [@coordinatesParis, @addressParis]
name:
description:
Location\Coordinates (local):
coordinatesParis:
__construct: [48.8257802, 2.3783640000000332]
Location\Address (local):
addressParis:
__construct: [
1 Rue du Chevaleret,
75013,
Paris,
Paris,
Île-de-France,
@countryFR
]
Location\Country (local):
countryFR:
__construct: [FR]
Since value objects aren't shared, the syntax could be nested. Quick & dirty example:
Location\Location:
Paris:
__construct:
Location\Coordinates:
__construct: [48.8257802, 2.3783640000000332]
Location\Country:
__construct: [
1 Rue du Chevaleret,
75013,
Paris,
Paris,
Île-de-France,
@FR
]
name:
description:
Location\Country (local):
countryFR:
__construct: [FR]
There is a reference example in readme:
Nelmio\Entity\Group:
group1:
name: Admins
owner: @user1
It would be nice to be able to reference random useer with something like:
Nelmio\Entity\Group:
group1:
name: Admins
owner: @user*
Is this possible?
I have an entity that I want to pass to a method on another entity (defined after the first entity).
fixtures.yml
Example\AcmeBundle\Entity\Foo:
fooInstance:
id: 0
name: Bar
Example\AcmeBundle\Entity\Bar:
barInstance:
fooName: <myFormatter(@fooInstance)>
The provided example does not work, as I get a string in myFormatter(), rather than the expected Foo instance.
Possible work around in most cases
Example\AcmeBundle\Entity\Foo:
fooInstance:
id: 0
name: Bar
Example\AcmeBundle\Entity\Bar:
barInstance:
foo: @fooInstance
fooName: <myFormatter($foo)>
However, in my particular case, I don't have any property (like foo:) to use as a variable in the method call. I need to be able to pass the @fooInstance to the method.
This does not currently appear to be supported.
I would need this change to be released d3bdb0d
Is there a chance to have a 1.5.3 or a 1.6 tagged?
Since Fixtures::load()
is static, persister is recreated for each load. This is a problem if you have several yaml files with referenced fixtures, you will get error like this:
[UnexpectedValueException]
Reference mask "someref*" did not match any existing reference, make sure the object is created after its references
./bin/alice --purge "App:BlogPost" --purge "App:Comment" ./fixtures/blogPost-*.yml
#!/usr/bin/env php
<?php
require_once __DIR__.'/../vendor/autoload.php';
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
$em = $container->get('doctrine.orm.default_entity_manager'); // TODO: or something
$input = new ArgvInput(null, new InputDefinition([
new InputOption('purge', null, InputOption::VALUE_IS_ARRAY | InputOption::VALUE_OPTIONAL),
new InputArgument('glob', InputArgument::OPTIONAL, 'glob pattern', '*'),
]));
$classes = array_map(function($class) use($em) {
return $em->getClassMetadata($class);
}, $input->getOption('purge')) ?: $em->getMetadataFactory()->getAllMetadata();
$tool = new \Doctrine\ORM\Tools\SchemaTool($em);
$tool->dropSchema($classes);
$tool->createSchema($classes);
$glob = sprintf(__DIR__.'/../%s', $input->getArgument('glob')); // TODO smarter relative/absolute detection
$objects = \Nelmio\Alice\Fixtures::load($glob, $em);
Is there a way the loaded objects returned by Fixtures::load() can be named instead of ordered array?
I need to retrieve a particular object in the array. Right now, the object array is numbered and does not facilitate a good way to retrieve the same object during different loads.
I know this is not an issue. Sorry for posting this here.
My specifications require that codes for a promotion start with the store id followed by ten other digits.
If I do @store<current()>->id <randomNumber(10)>
in the database I get the string @store0->id 9784680707
, which is clearly wrong.
If I do @store<current()>->id <randomNumber(10)>
I get an error Property id9784680707 is not defined for reference store0
, which is quite normal because Faker can not detect the end of the property name.
Is there a workaround to concatenate a property and a Faker provider? Thank you.
😄
Hi there.
I want to create a huge set of fake data.
For the first time, I have tried with huge range like
Acme\DemoBundle\Entity\Annonce:
annonce{1..1000000}:
But I encountered out-of-memory very quickly... I guess this is normal because Alice / Faker have to keep in-memory each instance of Annonce
After that, I have tested an other approach, import many times small set of data.
//I'm using symfony..
protected function execute(InputInterface $input, OutputInterface $output)
{
$loop = (int)$input->getArgument('loop');
for($i = 0 ; $i < $loop ; $i++) {
$object = \Nelmio\Alice\Fixtures::load(__DIR__.'/../Resources/public/data-fixtures/alice.yml', $this->getContainer()->get('doctrine.orm.entity_manager'), array('providers' => array($this)));
}
}
Acme\DemoBundle\Entity\Annonce:
annonce{1..100}:
This time, memory footprint should be very small.. But I have encountered out-of-memory.
I'm not sure if the problem is coming from Alice or Doctrine.. But with a little tweak, the out-of-memory problem seems to be partial fixed.
Just with a call to ObjectManager::clear inside the file : https://github.com/nelmio/alice/blob/master/src/Nelmio/Alice/ORM/Doctrine.php#L41
No PR because I'm not sure that it's ok for every use case.. What do you think about that ?
Regards,
Hello,
Since @Seldaek's commits today, I have a bug loading a batch entity when the construct is false
MyClass:
MyClass{1..2}:
__construct: false
[RuntimeException]
You must specify a __construct method with its arguments in object MyClass2 since class MyClass has mandatory constructor arguments
Exception trace:
() at [..]/vendor/nelmio/alice/src/Nelmio/Alice/Loader/Base.php:395 Nelmio\Alice\Loader\Base->createInstance() at [..]/vendor/nelmio/alice/src/Nelmio/Alice/Loader/Base.php:141
I think there is a little regression here :)
Lion\GuinnessMyPintBundle\Entity\EntryCode:
entryCode (template):
code: <lexify()>
traction_ref: <numberBetween(1000, 9999)>
pub: @pubStub
entryCode{1..9} (extends entryCode):
entry: @entryNextToWin
entryCodeOne (extends entryCode):
entry: @entryOneEntry
yields
[Doctrine\DBAL\DBALException]
An exception occurred while executing 'INSERT INTO entry_codes (code, entry_id, pubs_id, traction_ref, created) VALUES (?, ?, ?, ?, ?)' with params [null,
19, null, null, "2014-03-26 10:46:45"]:
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'pubs_id' cannot be null
[PDOException]
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'pubs_id' cannot be null
I have a 1:1 reference like this:
Acme\Entity\User:
user{1..100}:
username: <username()>
Acme\Entity\Inventory:
inventory{1..100}
user: @user*
gold: 100
But I dont want a random reference, but user1 referenced in inventory1 etc. Is there a way to do so with still using the range option {1..100}
?
Hello,
Thanks for alice, it is just great !
But I just realized a lack for my need. I cannot use advanced custom faker provider as they need the faker generator as argument, can I ?
I missed something ?
If not, can I submit a PR to tweak a little "Nelmio\Alice\Loader::getGenerator" to add this possibility ?
Thanks !
Is this something that can or should be should be handled here generically?
Something like:
$metadata = $this->getEntityManager()->getClassMetaData(get_class($entity));
$metadata->setIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_NONE
);
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.