Whenever I started a new project and used the Doctrine ORM in the past, I started to write methods in the Entity repository classes to get all the necessary data for the logic and the views.
At first it seemed simple when I wrote a findAll function. But as the project grew, a ton of parameters were added to the same method to accomodate different usecases.
For example: sometimes I needed the data hydrated, other times I wanted to work with the actual Doctrine entities from the query’s result.
public function findAll($groupId = null, $hydrate = false) {...}
So what exactly are the parameters on the findAll function? My answer is: they are usecases where I want to filter the data.
This led to many overloaded repository methods that do too much. But let’s pause and take a deep breath: let’s not add the findAllSimple method yet. There is an easier way to get out of this rabbit hole: Refactoring!
What I want to do is build a query which suits my usecase. I also don’t want to write the same code again and again or get cluttered up in the Eierlegendewollmilchsau-findAll-function.
Here is how to get started!
I want to have a the QueryBuilder-Object. That is fairly simple as I already have the repository class extend the Doctrine\ORM\EntityRepository.
/**
* @param string $alias
* @return \Doctrine\ORM\QueryBuilder
*/
private function getBuilder($alias = 'd')
{
return $this->createQueryBuilder($alias);
}
Next step: pulling all parameter based stuff in their own filterBy*() function
/**
* @param \Doctrine\ORM\QueryBuilder $builder
* @param int $groupId
*
* @return \Doctrine\ORM\QueryBuilder
*/
public function filterByGroup(&$builder, $groupId)
{
if (null === $groupId) {
return $this;
}
$builder
->addWhere('d.groupId = :groupId')
->setParameter('groupId', $groupId)
;
return $this;
}
Once I created these two, I refactored findAll to
public function findAll($groupId = null, $hydrate = false)
{
$builder = $this->getBuilder();
$this
->filterByGroup($builder, $groupId)
->filterBy*($builder, $param)
;
return $builder;
}
But findAll doesn’t take into account that I want all the entries from this result. So in this case, I’ll add another usecase method to specialize the query for my second usecase:
public function getUsersForApi($groupId)
{
$builder = $this->findAll();
$this
->filterByGroup($builder, $groupId)
->filterBy*($builder, $param)
;
return $builder;
}
In summary, the pattern I applied to to the repository includes following:
get* for usecases returning the $builder i.e. getXyForMySpecialUsecase($someParam)filterBy* adding conditions on the builder returning $thisfindBy* build in by doctrine for simple queriesRefactor the actions or services where I want to call the repository to
$groups = $app['orm.ems']['api']
->getRepository('\EasyBib\Api\Entity\Group')
->getGroupsForApi($groupId)
->getQuery()
->getSingleResult(AbstractQuery::HYDRATE_ARRAY)
;
Executing the query will be in the responsability of the part of the code that actually needs the result.
Last but not least, I refactored:
public function findAll($groupId = null, $hydrate = false) {...}
to:
private function findAll()
{
return $this
->getBuilder()
->select(array(/*what ever you standard selects may be*/))
;
}
This ensures that the repository class will grow more healthy and won’t end up with helpless clutter.
It even becomes trivial to test the queries using this approach: get the query with $myEntityRepository->getQuery()->getSql() and test the string for everything you need to be there. This seems to be the most feasible approach for us in order to be able to refactor or extend our existing code base without breaking anything.
That’s all for today!
— Anne
Cloudant’s NYC meet-up will take place at our office this Wednesday (tomorrow)! Please RSVP using the following link:
http://cloudantimagineeasy.eventbrite.com/
The office’ address is 12 West 31 St:
If you can’t make the meet-up, make sure to check out the webinar on Thursday:
Slides from a talk I gave at the CouchDB conference in Berlin last month. As always, the slides are on speakerdeck:
https://speakerdeck.com/till/easybib-and-cloudant
— Till
Composer seems to have become the defacto dependency management tool in the last year. At EasyBib we make heavy use of composer both when we run test suites on Travis-CI and also during deployment.
Because we use Github to host our code, the most obvious ways to speed up each of these runs is to use Github downloads instead of cloning the code during ./composer.phar install.
By default composer will attempt this — unless --prefer-source is provided.
One of the caveats to this is that by default composer will use unauthenticated API calls against the Github API. Github’s API allows only 60 unauthenticated calls an hour but up to 5,000 authenticated calls in the same timespan.
In an office with six developers it’s easy to burn through these 60 calls. On Travis-CI — due to a lot higher volumes of test runs and customers — it’s even easier.
The solution is to configure composer to use an OAuth2 key!
There are of course programmatic ways to generate the key using Github’s API.
But the easiest way is to wait until I exceeded all calls and have composer set it up for me. Once I aquired the key, I made a copy of the ~/.composer/config.json file and backed it up for later.
The manual steps to set it up are as follows:
$ mkdir ~/.composer
$ echo '{ "config": { "github-oauth": { "github.com": "YOUR-KEY" } } }' > ~/.composer/config.json
On Travis-CI (or anywhere else where automation is required), the same commands can be executed within the before_script in your .travis.yml.
Please note: This method works best on private repositories and the Travis-CI pro setup. The token you specify may or may not give anyone access to your private repositories as well.
One way to sail around the access limit is to setup a dedicated user on GitHub which has only pull-access to your public repositories. Another is to use the facilities to encrypt the data.
Enjoy!
Heya — and welcome to EasyBib’s tech blog! To start this off, here are my slides of a talk I gave in November at the Berlin PHP Usergroup.
At EasyBib, we’re huge fans of StatsD. StatsD is a neat little node.js daemon to collect data from inside your application in almost real time. My talk showed the various kinds of metrics to collect and how you can go about it.
Enjoy! —Till
Ever find yourself fighting a losing battle with a bibliography? We’re sure you used to, prior to using EasyBib of course. Check out our new video and pass it along to all your friends!
While EasyBib helps students quickly and accurately create their bibliographies, some students still need help distinguishing one source type from another. Do they know the difference between a journal and a magazine, or an article from a general website from one found in a reference database? Now EasyBib has introduced the EasyBib Source Guide, which provides source definitions and examples, and suggests alternatives on related sources. It will help students identify and understand how sources differ, and ultimately help students fully grasp the reference process and create better bibliographies.

To access the source guide, click the blue help link on the tab bar, or the red help link on the form page. You will then see a variety of sources related to your chosen source, along with definitions and examples. Once you click on a source type, EasyBib will ask you the specific medium where you found the source, and direct you to the appropriate form.
We hope you find it helpful!
Hey everyone,
Here are a couple updates just in time for the school year!
Journal Autocite: First books, then websites, then newspapers, then magazines… and now, journals! The autocite march continues. You can now cite journals just by entering in the article title or DOI number of the source. It’s that easy!
Tagging: We’ve had a number of requests over the years to add tagging to sources. It is now implemented. To tag a source, just click “tag” next to the source that you’ve cited. That means you can sort sources by primary or secondary (by tagging them as such), or by how they apply to your paper (background, opposing viewpoints, pro/con, etc.). You can even sort by tag, or just export citations with the tag you want.
On the agenda: more things to make your research paper life faster, easier, and more efficient. Stay tuned!
We’re thrilled to announce a round of new updates to EasyBib!
Export to Google Docs: If you’re one of the growing number of users who have ditched your desktop office suite, you’ll be happy to note our new integration with Google Docs. After citing your bibliography, just click “Save to Google Docs” and we’ll import your bibliography right into your Google Docs account. It’s that easy!
Login via Facebook, Google, Yahoo, & AOL: If you don’t want to create your own account on EasyBib, we now support logging in via multiple providers. Just click on their icon and you should be logged in automagically.
Developer documentation: If you’re a third party Web site looking to add citation capabilities, check out the EasyBib Citation API and widget!
Citation guide: One of the biggest problems students have when citing sources is finding out where to get the information they need for their citation. Our brand new visual citation guide solves that by showing students exactly where they need to find stuff.
That’s all for now. Hope everyone is having a great summer!
The Bib Team
Hey Bibs,
You may notice a few design changes underfoot. We’ve brought our Autocite features out in the open. Now you’re able to cite the most popular sources right off the homepage! Of course, we still offer the largest number of citeable sources online - just click “All 55 options” at the end of the tab box.
We’ve also increased the color contrast a bit, as many of our users have indicated that some of the layout has been too light and they had trouble seeing the different parts of our site. We hope that’s no longer an issue for anyone :)
Additionally, our School Edition subscribers now have the ability to add their school logos and library links right on EasyBib! This can drive further engagement with library resources, as they’ll be front and center while a student is using our service.
Lastly, our international users should now be a lot happier! While we’ve always had Unicode support, we’ve made significant improvements to ensure that different character sets are fully supported.
We know many of you are on the verge of heading home for the summer - have a good break, and when you return you’ll have a lot more features to look forward to!
Cheers!
Darshan