Use Sublime Text to help you create doctrine Entities part two

In my previous post I wrote about a regexp search and replace to create Doctrine entities easily from a phpmyadmin CSV export. After that post I found myself checking my own website to copy and paste the regexp. Then I tried recording a macro in Sublime, but it turns out sublime doesn’t record search and replace actions.

Then I learnt about the feature to install packages to your sublime install, which has a really cool RegReplace package. Just follow the instructions on that page. I was a bit confused at point three, but turns out I had to go to Package Control: install package. You can go there by pressing cmd+shift+p and then type Package Control. It should appear in the list.

Then this superuser post helped me configuring the RegReplace package. It took me a while to figure out how to use extended back references. But I got it all working now. I use Sublime Text 2, so go to Preferences → Package Settings → Reg Replace → Settings – Default.

Sublime_Reg_Replace

At the replacements section I added this:

Don’t forget to enable “extended_back_reference” at the end of this file.

Then I went to Preferences → Package Settings → Reg Replace → Commands – Default and added this at the end:

Now when I am in my editor and press cmd+shift+p I can just type “Doctrine” and my command shows up. Then it’ll convert the cvs formatted table heads to a nice doctrine entity.

 

Use Sublime Text to help you create doctrine Entities

I don’t know about you, but when working in a projects that already exists, I am afraid to let Symfony extract the entities for my project. I’d rather just define a new entity myself. To get started, Sublime Text is very useful in creating the entity with annotations. Here’s what I do.

First, in phpmyadmin I go to the table I want to create an entity for. I use browse, select the first record, and then export this to CSV. Export to screen, and make sure the headers are in the first row.

Copy the headers to your clipboard, and then paste them in sublime text. Then first replace the comma’d with newlines, which is easy .. just search for , and repalce with \n. Make sure you have the regex function enabled (that’s the .* button).

Now the magic trick so convert the rows with column names to an almost complete entity. Again use the search and replace.

Find What: ^\"(.*)\"$
Replace With: \/\*\*\n \* \@ORM\\Column\(name\=\"$1\", type\=\"\", nullable\=false\)\n \*/\nprivate \$\l\1\;\n

SublimeText

Now you should have something like this:

If course you can alter this any way you like.

Now copy this to your IDE of choice (PhpStorm probably, right?) and finish the details.

Created entities are all wrong

So I was performing a console doctrine:generate:entities for my bundle. The first thing I noticed is that it did’t create the appropriate getters and setters, especially for my OneToMany relations. The add and remove methods weren’t there.

So I started deleting all the methods, recreating them, and weird stuff kept happening. It even created some private properties that I didn’t define in my entity at all.

Eventually I found out that there was old ORM data in my project. Although I deleted the cache, this ORM data was still there. So, go to your bundle directory, and then to Resources/config/doctrine. Delete all the files in here. Then recreate your entities.

Raw mysql in Doctrine

To perform a raw mysql statement in symfony through Doctrine:

This example was being used in a controller.

Force Doctrine to close mysql connections

So I wrote a nice shell within app/console, which also used pcntl_fork(). Of course there was a very old archive somewhere in my mind that knew that this would mean trouble when you use mysql connections. But since I don’t explicitly use mysql_connect anymore, because Doctrine does this for me, I didn’t realise I faced the same problem as years ago.

When you fork a process with pcntl_fork(), it will copy the current process. This also contains the handles to your mysql connection. When the first child process dies, it will clean up these handles, and therefore close the connection.

Simple solution: make sure all connections are closed before you fork a child. That way, the child is forced to create a new connection.

I solved this using the following piece of code in the script.

 

Use KnpPaginatorBundle just for calculation

I was working on a table in Symfony where I needed to show a table. To add pagination without doing the hard work myself, I added KnpPaginatorBundle to my project. This worked really nice, and I had my tables paginated in no time. I just followed the example on the github page.

But then it gave me an error that looked much like this:

Not all identifier properties can be found in the ResultSetMapping: id

Right. So I googled the error message, and found that it had something to do with Doctrine, that could use Pagination if you select only specific fields of a table. And of course, that’s exactly what I did.

I built a repository class that would give me some results, based on a comprehensive html form. I would store the entire form in the database, to be able to reproduce the search, just by applying the search form again.

When processing the result, I already limited the search results though, using setFirstResult and setMaxResults. So it should be possible to create pagination.

Fortunately, I took a closer look to the paginator bundle, before I continued writing my own paginator code. I started with taking a look at the twig template, to give me inspiration on what variables my paginator should return. But then it seemed to me that KnpPaginatorBundle could do the math for me. All I had to do, is fill some variables my self.

So need to set:

  • the total number of records
  • the number of items on a page
  • the current page

Easy does it!

I ended up with the following code in my controller: