easybib/dev

EasyBib is an online research management platform used by over 40 million students at thousands of institutions across the United States.

We are revolutionizing how students develop research skills. We believe strong research habits are a cornerstone for creating a better, smarter, and more-informed world.

We were founded 2001, are bootstrapped, profitable, and looking to grow. Interested in working with us? Let us know.
  • rss
  • archive
  • Taiming repository classes in Doctrine with the QueryBuilder

    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) {...}
    

    Step back

    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!

    Objective

    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!

    Step 1

    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);
    }
    

    Step 2

    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 $this
    • findBy* build in by doctrine for simple queries

    Step 3

    Refactor 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.

    Testing

    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.

    Fin

    That’s all for today!

    — Anne

    • 2 months ago
    • 1 notes
    • #php
    • #doctrine
    • #refactoring
    • #doctrine-orm
    • #orm
  • Cloudant’s NYC meet-up & webinar!

    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:


    View Larger Map

    If you can’t make the meet-up, make sure to check out the webinar on Thursday:

    https://www1.gotomeeting.com/register/648768041

    • 3 months ago
    • #easybib
    • #cloudant
    • #couchdb
    • #nyc
    • #meetup
    • #webinar
  • EasyBib and Cloudant

    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

    • 3 months ago
    • #couchdb
    • #cloudant
    • #database
    • #easybib
  • Composer, Github and Travis-CI

    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.

    Authentication

    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!

    Setup

    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.

    Careful

    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.

    Fin

    Enjoy!

    • 5 months ago
    • 1 notes
    • #php
    • #composer
    • #deployment
    • #travis-ci
    • #oauth2
    • #github
    • #testing
  • Collecting Metrics

    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

    Source: speakerdeck.com
    • 5 months ago
    • #statsd
    • #metrics
    • #business metrics
    • #node.js
    • #php
    • #easybib
  • 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!

    • 2 years ago
  • EasyBib Source Guide

    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!

    • 2 years ago
    • 1 notes
  • Updates! Journal Autocite & Tagging

    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!

    • 2 years ago
    • #Darshan Somashekar
  • Bibbin’ in the sun: Google Docs Integration, Facebook, & more!

    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

    • 2 years ago
  • New updates: design changes & more!

    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

    • 3 years ago
© 2008–2013 easybib/dev
Next page
  • Page 1 / 9