Undo doctrine:generate:entity creations? - php

I am working with Symfony and Doctrine for the first time. I am curious: Is there a simple way to reverse a set of changes generated via a single running of the doctrine:generate:entity command?
I don't have any specific reason (yet) for asking this. I just imagine that it could potentially be helpful for me at some time in the near future, especially since my current version control only covers changes to the filesystem, omitting modifications to my sandbox's database contents -- which is relevant here.
In other words, some real equivalent for my imagined command doctrine:generate:rollback would be ideal. I'm assuming there's probably a way to do this type of thing.
Edit: TIL that the doctrine:generate:entity doesn't actually do anything to the database on its own. In many workflows, the doctrine:schema:update command does that after entities have been generated.

No, there is no Symfony or Doctrine command to do a rollback, but what doctrine:generate:entity really does is generating new php file with entity definition. So an actual rollback for doctrine:generate:entity is:
rm /path/to/your/entity.php

The answer is: No, there is no 'rollback' command, which removing all changes.
Do not forget that all changes in file system you can rollback via GIT (or other VCS).

Related

How to automatically pull the version number?

I'm writing a Symfony Console PHP application which takes a version number in the constructor.
$app = new Application('myapp', '1.0');
I've already found that it's easy to forget to bump the version number when making a new git tag release. How can I do this dynamically/automatically?
Aside from here on SO, I searched packagist pretty deeply because I thought for sure this was a common thing, but wasn't able to turn up anything.
I thought at first to write a function that would do something like this:
chdir(__DIR__);
shell_exec('git describe --abbrev=0 --tags');
But because I globally require this CLI app with composer, it doesn't have the git repository with the source code.
My next idea is that I know I can at least get it from composer
composer global show myname/mypackage
But this spits out a ton of information and there's no option that I'm aware of to just show the version number. I feel like filtering through all this with something like regex might be overkill. Is there any better way?
Pulling the version number from somewhere could be difficult, because you could run an older version of the application but wrongly pull the newest version number.
You could add a "release.version" file to your repo that only contains the version number and read this to pass it to the constructor.
Then you can use a git hook like pre-commit to update this file before you commit a tag.
This however is not recommended in distributed systems because it could lead to collisons, but for smaller teams or teams with a dedicated release manager it might be ok.
Read here: https://wincent.com/blog/automatic-deployment-numbering-in-git
and How do I enable ident string for Git repos?
It would maybe be enough to have a pre-commit hook that checks for a new tag and just reminds you to increment the version in the code ;).

Symfony 2.3.5 Create database schema from files failes

I have 53 tables and a lot of them reference eachother with relationships. When i run:
php app/console doctrine:schema:create
I get the error maximum nesting level of 100 reached. Through research i found this is actually a security measure from xdebug to stop infinite loops. When i remove this limitation and run the command again the php cli stops working and im forced to close it.
Is there anyway to generate the schema in steps like build the database structure then go back and add the mappings and the indexes so that it doesnt fail?
Or is it possible that I am doing something else wrong?
MySQL does work and i can create schemas that have less tables / relationships using this same method.
UPDATE: doctrine:schema:create --dump-sql hangs as well. Both max nesting level and max execution time are set to unlimited. Still PHP CLI stops working:
Problem signature:
Problem Event Name: APPCRASH
Application Name: php.exe
Application Version: 5.3.26.0
Application Timestamp: 51af706d
Fault Module Name: ntdll.dll
Fault Module Version: 6.1.7601.17725
Fault Module Timestamp: 4ec49b8f
Exception Code: c00000fd
Exception Offset: 0002e8fb
OS Version: 6.1.7601.2.1.0.256.48
Locale ID: 1033
Additional Information 1: 8983
Additional Information 2: 898375922a25a99ebc5721487ed92891
Additional Information 3: f337
Additional Information 4: f3378ae3d6023e7f336317eca89ba0b7
You have to increase the value of xdebug.max_nesting_level ( which defaults to 100 ) in your php.ini to circumvent the maximum nesting level of 100 reached error.
You'll most likely run into this issue multiple times for example during cache warmup - not only when trying to create the database schema. Therefore increase the value for all your symfony development - same goes for magento and zf ...
Check the max_execution_time setting aswell and maybe inspect using a profiler (xdebug/xhprof) if the command seems to hang. It might take some time to create the schema, bring some patience :)
There are no options for the doctrine:schema:create command to "split" the operation.
Try if doctrine:schema:create --dump-sql hangs aswell.
A really dirty workaround:
You could define new kernel environments (i.e. step1, step2), create different mappings (getting more and more detailed) or manually configure only a few of them in the first "steps"/environments, register/override them in config_stepx.yml and use something like
doctrine:schema:create --env=step1
doctrine:schema:update --env=step2
...
... but that would really be a mess.
from my experience the command should work even for large datasets. i have created schemas for applications with >100 tables without any problems.
The answer is my entities had a self referencing one to one relationship on the same key that was being used as the primary key. Thus creating an infinite loop during creation.
Not really sure why it was there in the first place some of these were generated by the doctrine database reverse engineering command.

react to composer.phar's questions with php exec()

The title is a little vague, I believe. But my english's not good, so I'm lacking of an better one.
I'm currenty writing a tool that also executes the composer.phar from the source code.
So when installing some stuff with composer.phar it sometimes asks questions and wants additional input, like desired format or simples Y/N questions.
When I use exec() it seems that it's not possible to react to those questions.
So I wondered how I can achieve this with PHP.
Any ideas?
Update
To show an simple example, I do this:
exec("php /Users/johannesklauss/Development/web/composer.phar create-project symfony/framework-standard-edition /Users/johannesklauss/Development/web/Symfony 2.1.x-dev");
Problem here is that the composer at the and asks if it should keep the version control history:
Do you want to remove the existing VCS (.git, .svn..) history? [Y,n]?
So I need to type in y or n to the console. But that's not possible with exec. So I need some interactive mode or what.
One word of caution: look for flags you can send to the initial command to "auto answer". You have no real guarantees about what question composer.phar will ask or the order it will ask them. It should be considered a "hack" and the normal reaction in our brains should apply with all it's caution and context, etc...
Anyway, I think what you'll need is proc_open(), which let's you start a process and have access to the stdin and stdout for it. See the Example #1 code on that doc page, it's very close to what you likely need.
Once you have access to the stdin/stdout resources for the process, you can read from/write to them however you like. The good news is that this will let you "read" the prompt and at LEAST double-check that it's asking what you expect it to be asking (and e.g. throw an exception if you don't recognize the prompt)

How can I unit test a PHP class method that executes a command-line program?

For a PHP application I'm developing, I need to read the current git revision SHA which of course I can get easily by using shell_exec or backticks to execute the git command line client.
I have obviously put this call into a method of its very own, so that I can easily isolate and mock this for the rest of my unit tests. So my class looks a bit like this:
class Task_Bundle
{
public function execute()
{
// Do things
$revision = $this->git_sha();
// Do more things
}
protected function git_sha()
{
return `git rev-parse --short HEAD`;
}
}
Of course, although I can test most of the class by mocking git_sha, I'm struggling to see how to test the actual git_sha() method because I don't see a way to create a known state for it. I don't think there's any real value in a unit test that also calls git rev-parse to compare the results? I was wondering about at least asserting that the command had been run, but I can't see any way to get a history of shell commands executed by PHP - even if I specify that PHP should use BASH rather than SH the history list comes up empty, I presume because the separate backticks executions are separate terminal sessions.
I'd love to hear any suggestions for how I might test this, or is it OK to just leave that method untested and be careful with it when the app is being maintained in future?
Although you have accepted an answer, let me post something about what the way unittests should work because even if the solution posted does work and is indeed nice, it has some backdraws.
First of all you don't want to actually execute your command, as this would test an external software. From this moment you are depending on external stuff you cannot control (what happens if I want to test your software on my pc? Do I have to instal git or any git-mock?). What you really want to do is see if the command line command is correct and is executed well.
As I struggled with this before, here is what I did: I created a class which executes shell_exec. Everywhere I want to interact with the shell, I inject the class and use it. So for testing I can mock the class and see if the correct method is executed and if the correct parameters are set.
This has many benefits:
I have one point of interacting with the shell. If anything changes in the future or if I have the need to do anything before executing the command, I can add the behaviour to the class. The PHP function is encapsulated nicely.
It works on every PC, even if the shell_exec command does not work for any reason. The tests get executed on every pc (development machines, testserver, integration server) without the need to worry about external dependencies.
Of course to validate that your software works as a whole, you have to do integration tests which do not mock anything. But this is a totally different situation. Unittests should make sure your class (or method) does what it needs to do. Sometimes this is not clear cut, as you may decide to use a real class somewhere because mocking it would lead to much overhead. But, as far as I'm concerned, it's no longer a unit test by any means if it relys on external libraries/software which may not be installed or may not work for some reason.
at least you could do something like checking for the retured string to match /^[abcdef0-9]{7}$/
I suppose if you really wanted to, you could write a dummy git and prepend its location to your environment's PATH. Have it do whatever validation you need to do, and then generate output consistent with what the real thing would do. You could conceivably even have it forward stuff to the real git, if you wanted, but then you couldn't guarantee the results.
You'd have to be careful, though....You'd want do just enough so that the class can be fooled into thinking it's really git, but if you make it behave too much like the real thing does, that amounts to writing your own half-assed version of Git.

How would you implement an auto-update for a standalone PHP project using GitHub?

My project is a collection of PHP scripts using MySQL as a database and needs to be installed locally using WAMP/LAMP/MAMP.
Previously I've been sending the users a link to a zipped archive and having them overwrite it, but since I took the plunge to GitHub, I've realized that there are far better ways; namely Service Hooks in GitHub. However, this would work fine as long as I don't alter the database in any way, which is a good possibility.
I've been toying with the idea of how I would implement this, but I can't find a clear solution. So far I've concluded with that I need to have a directory (say update/) which contains .sql files for each update. The PHP script will then check said directory for a file corresponding with the new version number (not sure how I will define a version number; I was thinking of using the commit ID, but that won't be available until after the commit, so...).
I would love some input on this!
Here's how I would tackle this (not the most elegant or performant):
Add a flag in the DB with a version number
Add a min-version number in your DB layer PHP file
Check that the DB version is greater than the min-version
If it is: continue about your business
Else: Run the PHP file in update/ which would have a series of ALTER TABLE commands to be run on the DB server
Update the min-version number in the DB to the latest number
All done
Alternately instead of querying the DB you can have a file which is generated by your DB interface PHP file (and ignored with .gitignore) which you can just as above.
I would really recommend checking out Doctrine and its migration feature.
This does exactly what you are looking for, plus you get a very nice tool for working with all other aspects of your database handling.

Categories