Category: General

We’ve worked on a number of projects which require the UI to be translated using the standard Symfony2 translator and YAML files. Recently we came into a few projects which also required different entities to have certain fields translated. Most of our applications we build use Sonata Admin for the admin backend so making sure we could integrate with it nicely was important. Looking around on Google and Stackoverflow it was clear that there are several different ways to go about getting your entities translated from the Gedmo Translatable, KnpLabs Translatable, to A2LiX I18n. Many of the packages have different takes on the “proper” way translation should be setup for the project. There are other nuances between each package such as supporting a fallback locale.

In the end we settled on using the KnpLabs Translatable bundle as it ticked all the boxes we wanted in functionality including fallback locale and a nice integration with the form (more on that later in this post). Installing the bundle follows the standard add it to composer and enable it in the kernel. From there setting up an entity was pretty straight forward:

Taking a look at how it actually works. First in the main entity you use the Translatable trait. Then in the translation entity (which is your original Entity with the name Translation appended to it) you add what fields you want translated, as well as the Translation trait. From there you can do something like $entity->translate(‘en’)->getName(). In our case we had a fairly large application already built and having to go through everywhere to update it to $entity->translate(…)->getXXX() would of been a huge pain and time waste. Luckily there is a fairly easy way to get around this. Using PHP’s magic __call method you can intercept all the calls so that it will go through the translations automatically:

The reason that it checks if arguments were passed in is that the Symfony2 property accessor doesn’t support passing arguments. We wanted to use it though when no arguments were passed since twig would otherwise first try on entity.name a call of “$entity->name()” which would fail as no name exists. You could wrap a few checks to make sure the method exists, instead since majority of our gets from twig do not pass any parameters we opted to just use the property accessor if no arguments were passed. This fixed the problem of {{ entity.name }} in Twig causing an error that the callback doesn’t exist and causing a 500. We ended up making our own Translatable trait which included this special __call override.

The final piece of advice on getting the translations working is when you add new translations to make sure you call $entity->mergeNewTranslations(). If you don’t you’ll be confused on why for it seems that none of your translations are being saved. This is documented, I just had looked over it first.

Now our second goal was a nice integration with Sonata Admin and any other forms we needed to use the translatable fields on. Luckily the A2LiX Translation Form Bundle already existed and we went forward with using it. Using the bundle was very easy. It was a simple as installing it, configuring it(just indicating what locales you want to use), and then updating the different form fields/admin setups. One thing to note is in the documentation it uses $form->add(‘translations’,’a2lix_translations’) as a bare minimum use case. At first, like me, you may think that the “translations” field is one of your field names. In fact that is used to load all translatable fields from your entity. It drops it into a nice tabbed input box. If you want to customize the field types and other options you can pass an array of options to set each field up in terms of labels, field type, etc. All in all it was really a huge time saver to have this bundle and was very easy to use from both a developer and user standpoint.

For the most part this is how we went about enabling translations on different entities in our application. In my next post I’ll write up the steps we used to migrate all the data from our existing entities to the new translations.

Update: My post on how to migrate your data to translatable entities is now available.

Posted In: General

Tags: , , , ,

Unless you’ve been living under a rock for the last couple of years, it’s clear that smartphones are kind of a big deal. Today there are close to 2.6 billion subscriptions globally, and this number stands to grow rapidly as less developed markets turn into substantial electronic consumers.

With new applications and games hitting app stores daily, it’s no surprise that people are spending more and more time with their eyes glued to the glass screens of these compact, universal media agents. Phones have single handedly changed the way that people live, becoming pivotal for people to communicate, go online, and access and share information.

The ubiquitous nature of the smartphone has opened the floodgates of opportunity, creating new markets in the process and forcing pre-existing ones to modernize or be strangled at the hands of innovation. One market in particular that has been significantly impacted by the mobile revolution is the advertising and marketing industry.

The rise of the Internet era has led to a rapid decrease in the effectiveness of traditional forms of advertising media, and have forced the hand of the industry to take the plunge into to more digital forms. Marketing companies have to continuously find new and improved ways of reaching their targets in a world where TV and print simply will not do. One unique strategy that companies have used to connect with the masses and promote brand awareness is branded Apps. Smartphone users spend close to 90% of their time on devices using apps so they offer an incredible opportunity to connect with consumers.

Recently here at Setfive we have taken a look at building some brandable tools for mobile, and looked for the most original branded apps out there for some inspiration. Here are some of the most interesting apps that we found during our quest for inspiration.

Pop Secret Perfect Pop App

This app uses your phones speakers to listen to the pops coming from the bag of popcorn in your microwave, and tells you the precise moment when your bag of popcorn is a peak popped-ness.

Charmin SitOrSquat App

This app uses a map to display available public restrooms in your area and lets you know how clean they are (hence the name SitOrSquat). Additionally this app utilizes crowd sourcing, letting users to rate and write reviews about the public bathrooms that they use.

The Snow Report by North Face

So what has the North face been up to besides making incredibly epic TV commercials? That’s easy, they’ve been building a location based mobile app that helps users check the condition on powder before they head to the slopes. Check the status of runs around you or the 10 top slopes globally.

Tide Stain Brain

When stains happen, StainBrain gives you simple solutions on the spot. Blot or soak? Cold water or hot? Get the scoop on how to rid yourself of more than 85 different stains with on-the-go tips and easy, step-by-step washing instructions from the laundry pros at Tide.

Bosch Unit Converter: Professional converter for over 50 units

The Bosch Professional Unit Converter turns a smartphone into a universal unit converter. The ideal app for quick conversions on the building site or in the workshop. Completely free of charge and ads.

Posted In: General

Tags: ,

Our yearlong delve into the sea that is Angular Js has kept our engineering team busy for quite some time now. Throughout this fun time of exploration there have been ups and downs, muddled coding snares caused by niche problems that are almost impossible to conform to the constantly looming “Angular Way”, and complicated problems that could be solved so easily you wished you had a Staples button just so you could push it for the “That was easy”.

One invaluable resource that has continually helped guide us through our use of this robust MVC framework is the vast Angular Js community, that has helped answer most of our questions, from questions about basic tutorials, to more overarching questions about best practices when structuring applications.

On one of our more recent Angular projects, we ran into an issue implementing a fairly common need among web applications – generating an auto submit form. After poking around Google and StackOverflow for a bit, surprisingly, there was a lot less information on this subject than expected. So, we decided to write a blog post on the subject, giving back to the AngularJS community, which has given so much to us.

Interestingly, this problem can be solved quite easily once you have a more comprehensive understanding about the Angular directive’s Link function. Here’s a good StackOverflow answer if you’re interested in some light reading: AngularJS: What is the need of the directive’s link function when we already had directive’s controller with scope?. However, if you’re anything like us then you’re probably solely interested in learning just enough to solve the immediate problem at hand, so for you, the main “gotcha” that you need to know is that the template for any directive is wrapped as an angular element, and can be accessed inside of the Link function using the angular.element() function.

The basic idea is simple, create a custom directive for your auto submit form, make the template for this directive a form element with the information you want to send, and control its rendering using an ng-if directive. Using ng-if is important in this instance because this directive doesn’t just show/hide a portion of the DOM tree, but actually removes/recreates it, allowing you to take advantage of the directives Link function. Then, inside of the link function for the auto submit form directive, grab the form element using the angular.element() function and submit it using the javascript function submit().

If the above paragraph didn’t completely explain it to you, please don’t worry, here is a nice, concrete example to help you solve this problem quickly should you ever run into it again in the future.

Posted In: General

For the last few months we’ve been working on a Spring Boot project and one of the more challenging aspects has been wrangling Spring’s security component. For the project, we were looking to authenticate users using a custom HTTP header that contained a token generated from a third party service. There doesn’t seem to be a whole lot of concrete examples on how to set something like this up so here’s some notes from the trenches. Note: I’m still new to Spring so if any of this is inaccurate, let me know in the comments.

Concretely, what we’re looking to do is authenticate a user by passing a value in an X-Authorization HTTP header. So for example using cURL or jQuery:

In addition to insuring that the token is valid, we also want to setup Spring Security so that we can access the user’s details using “SecurityContextHolder.getContext().getAuthentication()”. So how do you do this? Turns out, you need a couple of classes to make this work:

  • An Authentication Token: You need a class that extends AbstractAuthenticationToken so that you can let Spring know about your authenticated user. The UsernamePasswordAuthenticationToken class is a pretty good starting point.
  • The Filter: You’ll need to create a filter to inspect requests that you want authenticated, grab the X-Authentication filter, confirm that it’s a valid token, and set the corresponding Authentication. Since we only want this to run once per request you can extend the OncePerRequestFilter class to set this up. You can see an example class below:
  • An Authentication Provider: The final piece is a class that extends AuthenticationProvider which handles retrieving a JPA entity from the database. By implementing an AuthenticationProvider instead of doing the database lookup in the filter, you can keep your filter framework agnostic by not having to autowire in a JPA repository. My implementation looks similar to:

And finally, the last step is to wire this all up. You’ll need a class that extends WebSecurityConfigurerAdapter with two ovveridden configure methods to configure the filter and the authentication provider. For example, the following works at a bare minimum:

And then finally to access the authenticated user from a controller you’d do:

Anyway, hope this helps and as mentioned above if there’s anything inaccurate feel free to post in the comments.

Posted In: General

Labor day has come and gone so summer is officially over. We sat down with our intern Phil to chat about his time interning at Setfive.

Favorite Part About Interning At Setfive?

My favorite part about interning at Setfive was being introduced to so many different programming tools, and having the ability to increase my programming skill set. This summer I learned about PHP, the Symfony 2 Framework, MYSQL, I improved my JavaScript skills, learned some Angular.js, and even learned how to write unit tests. I was exposed to so many new things that everyday was fun and no two days were ever the same.

The environment here encouraged questions, and allowed me to ask and receive answers to anything I wanted to know more about. Some of the guys would even go out of their way to send me related documentation about something if they felt that they couldn’t confidently answer it themselves.

Working under the guys here was an incredible experience, I was given the freedom to make mistakes and figure out problems on my own, but at the same time was given sufficient structure to make consistent progress. It was awesome to have the comfort of knowing I had a smart, qualified person to guide me in the right direction if I ever got too stuck on any one problem.

Most important thing that you learned?

The most important skill that I learned was definitely an improved conceptual understanding of MVC, and that while sometimes using this pattern slows down your programming, in the long run it helps you create readable, modular code.

I also learned that installation is just the worst.

Most Memorable Moment?

The most memorable moment of the summer was the first time we used the Txty Jukebox in the office. It didn’t quite work the first time around, however, watching people use and get enjoyment out of something that I helped to create was something that I’ will never forget.

Where do you want to go from here?

From here I definitely want to continue building custom applications. I’ve spent the last part of the summer teaching myself objective-c, and the skills that I’ve learned here will definitely help me make the transition into developing iOS applications.

Top 5 Things To Eat

  1. Buffalo Soulja – Darwins (Only available on Thursdays)
  2. Mango Bubble Tea – Dosa Factory
  3. Steak Sammy – Orinoco
  4. Burger topped with shortrib meat – Charlies Beer Garden
  5. Chicken Pad Thai – Thelonious Monkfish
  6. Honorable Mention: Cuban Sammy – Plough and Stars

Posted In: General

Tags: ,