Custom Configuration for Phabricator

By  on  

Phabricator is an excellent code review tool used by Facebook and other respected software engineering organizations.  The user interface is beautiful, the workflow and tools are concise and comprehensive, and it's a utility that covers most use cases, both web and command line.  I've written a many Phabricator extensions and I've found that creating a single configuration extension to be used by other extensions is of great utility.  Let's look at how easy it is to create your own custom configuration to be used throughout your extensions!

Creating the Configuration Extension

Start by creating a new class that extends PhabricatorApplicationConfigOptions:

final class PhabricatorBugzillaConfigOptions
  extends PhabricatorApplicationConfigOptions {

  // ....
  
}

Fill in a few boilerplate methods:

public function getName() {
  return pht('Bugzilla');
}

public function getDescription() {
  return pht('Configure Bugzilla Settings.');
}

public function getIcon() {
  return 'fa-cog';
}

public function getGroup() {
  return 'apps';
}

The getOptions method is where the individual settings are defined; let's create a few sample settings:

public function getOptions() {
  return array(
    $this->newOption(
      'bugzilla.url',
      'string',
      'https://bugzilla.mozilla.org')
      ->setDescription(pht('Full URL for the Bugzilla server.')),
    $this->newOption(
      'bugzilla.automation_user',
      'string',
      'phab-bot@bmo.tld')
      ->setDescription(pht('Automation Username on Bugzilla.')),
    $this->newOption(
      'bugzilla.timeout',
      'int',
      15)
      ->setDescription(pht('Bugzilla timeout in seconds.')),
    $this->newOption(
      'bugzilla.require_bugs',
      'bool',
      false)
      ->setDescription(pht('Require existing Bugzilla bug numbers for revisions.')),
  );
}

These settings translate to the UI in this manner:

Phabricator Configuration

The config value type is important in that Phabricator reads it and renders a field relevant to the type; for example, bool types provide a True/False dropdown.

Using Config Values

When you want to use config values in other extensions, you can reference those config values by key with PhabricatorEnv::getEnvConfig calls:

// Use PhabricatorEnv::getEnvConfig() to get config values
if(PhabricatorEnv::getEnvConfig('bugzilla.require_bugs') === true) {
  // ...
}

The value returned by getEnvConfig is of the type defined in the configuration extension.

I'm a huge fan of using configuration values defined through a user interface; the alternative usually requires a redeploy and, in cases of emergency, that's a worst case scenario.  When values are easy to define, change, and use, you've found yourself in a win/win/win situation, and that's how it should always be!

Recent Features

  • By
    Designing for Simplicity

    Before we get started, it's worth me spending a brief moment introducing myself to you. My name is Mark (or @integralist if Twitter happens to be your communication tool of choice) and I currently work for BBC News in London England as a principal engineer/tech...

  • By
    Send Text Messages with PHP

    Kids these days, I tell ya.  All they care about is the technology.  The video games.  The bottled water.  Oh, and the texting, always the texting.  Back in my day, all we had was...OK, I had all of these things too.  But I still don't get...

Incredible Demos

  • By
    Six Degrees of Kevin Bacon Using MooTools 1.2

    As you can probably tell, I try to mix some fun in with my MooTools madness but I also try to make my examples as practical as possible. Well...this may not be one of those times. I love movies and useless movie trivia so naturally I'm...

  • By
    Telephone Link Protocol

    We've always been able to create links with protocols other than the usual HTTP, like mailto, skype, irc ,and more;  they're an excellent convenience to visitors.  With mobile phone browsers having become infinitely more usable, we can now extend that convenience to phone numbers: The tel...

Discussion

    Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!