[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/src/applications/maniphest/constants/ -> ManiphestTaskStatus.php (source)

   1  <?php
   2  
   3  /**
   4   * @task validate Configuration Validation
   5   */
   6  final class ManiphestTaskStatus extends ManiphestConstants {
   7  
   8    const STATUS_OPEN               = 'open';
   9    const STATUS_CLOSED_RESOLVED    = 'resolved';
  10    const STATUS_CLOSED_WONTFIX     = 'wontfix';
  11    const STATUS_CLOSED_INVALID     = 'invalid';
  12    const STATUS_CLOSED_DUPLICATE   = 'duplicate';
  13    const STATUS_CLOSED_SPITE       = 'spite';
  14  
  15    const SPECIAL_DEFAULT     = 'default';
  16    const SPECIAL_CLOSED      = 'closed';
  17    const SPECIAL_DUPLICATE   = 'duplicate';
  18  
  19    private static function getStatusConfig() {
  20      return PhabricatorEnv::getEnvConfig('maniphest.statuses');
  21    }
  22  
  23    private static function getEnabledStatusMap() {
  24      $spec = self::getStatusConfig();
  25  
  26      $is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business');
  27      foreach ($spec as $const => $status) {
  28        if ($is_serious && !empty($status['silly'])) {
  29          unset($spec[$const]);
  30          continue;
  31        }
  32      }
  33  
  34      return $spec;
  35    }
  36  
  37    public static function getTaskStatusMap() {
  38      return ipull(self::getEnabledStatusMap(), 'name');
  39    }
  40  
  41    public static function getTaskStatusName($status) {
  42      return self::getStatusAttribute($status, 'name', pht('Unknown Status'));
  43    }
  44  
  45    public static function getTaskStatusFullName($status) {
  46      $name = self::getStatusAttribute($status, 'name.full');
  47      if ($name !== null) {
  48        return $name;
  49      }
  50  
  51      return self::getStatusAttribute($status, 'name', pht('Unknown Status'));
  52    }
  53  
  54    public static function renderFullDescription($status) {
  55      if (self::isOpenStatus($status)) {
  56        $color = 'status';
  57        $icon = 'fa-square-o bluegrey';
  58      } else {
  59        $color = 'status-dark';
  60        $icon = 'fa-check-square-o';
  61      }
  62  
  63      $img = id(new PHUIIconView())
  64        ->setIconFont($icon);
  65  
  66      $tag = phutil_tag(
  67        'span',
  68        array(
  69          'class' => 'phui-header-'.$color.' plr',
  70        ),
  71        array(
  72          $img,
  73          self::getTaskStatusFullName($status),
  74        ));
  75  
  76      return $tag;
  77    }
  78  
  79    private static function getSpecialStatus($special) {
  80      foreach (self::getStatusConfig() as $const => $status) {
  81        if (idx($status, 'special') == $special) {
  82          return $const;
  83        }
  84      }
  85      return null;
  86    }
  87  
  88    public static function getDefaultStatus() {
  89      return self::getSpecialStatus(self::SPECIAL_DEFAULT);
  90    }
  91  
  92    public static function getDefaultClosedStatus() {
  93      return self::getSpecialStatus(self::SPECIAL_CLOSED);
  94    }
  95  
  96    public static function getDuplicateStatus() {
  97      return self::getSpecialStatus(self::SPECIAL_DUPLICATE);
  98    }
  99  
 100    public static function getOpenStatusConstants() {
 101      $result = array();
 102      foreach (self::getEnabledStatusMap() as $const => $status) {
 103        if (empty($status['closed'])) {
 104          $result[] = $const;
 105        }
 106      }
 107      return $result;
 108    }
 109  
 110    public static function getClosedStatusConstants() {
 111      $all = array_keys(self::getTaskStatusMap());
 112      $open = self::getOpenStatusConstants();
 113      return array_diff($all, $open);
 114    }
 115  
 116    public static function isOpenStatus($status) {
 117      foreach (self::getOpenStatusConstants() as $constant) {
 118        if ($status == $constant) {
 119          return true;
 120        }
 121      }
 122      return false;
 123    }
 124  
 125    public static function isClosedStatus($status) {
 126      return !self::isOpenStatus($status);
 127    }
 128  
 129    public static function getStatusActionName($status) {
 130      return self::getStatusAttribute($status, 'name.action');
 131    }
 132  
 133    public static function getStatusColor($status) {
 134      return self::getStatusAttribute($status, 'transaction.color');
 135    }
 136  
 137    public static function getStatusIcon($status) {
 138      return self::getStatusAttribute($status, 'transaction.icon');
 139    }
 140  
 141    public static function getStatusPrefixMap() {
 142      $map = array();
 143      foreach (self::getEnabledStatusMap() as $const => $status) {
 144        foreach (idx($status, 'prefixes', array()) as $prefix) {
 145          $map[$prefix] = $const;
 146        }
 147      }
 148  
 149      $map += array(
 150        'ref'           => null,
 151        'refs'          => null,
 152        'references'    => null,
 153        'cf.'           => null,
 154      );
 155  
 156      return $map;
 157    }
 158  
 159    public static function getStatusSuffixMap() {
 160      $map = array();
 161      foreach (self::getEnabledStatusMap() as $const => $status) {
 162        foreach (idx($status, 'suffixes', array()) as $prefix) {
 163          $map[$prefix] = $const;
 164        }
 165      }
 166      return $map;
 167    }
 168  
 169    private static function getStatusAttribute($status, $key, $default = null) {
 170      $config = self::getStatusConfig();
 171  
 172      $spec = idx($config, $status);
 173      if ($spec) {
 174        return idx($spec, $key, $default);
 175      }
 176  
 177      return $default;
 178    }
 179  
 180  
 181  /* -(  Configuration Validation  )------------------------------------------- */
 182  
 183  
 184    /**
 185     * @task validate
 186     */
 187    public static function isValidStatusConstant($constant) {
 188      if (strlen($constant) > 12) {
 189        return false;
 190      }
 191      if (!preg_match('/^[a-z0-9]+\z/', $constant)) {
 192        return false;
 193      }
 194      return true;
 195    }
 196  
 197  
 198    /**
 199     * @task validate
 200     */
 201    public static function validateConfiguration(array $config) {
 202      foreach ($config as $key => $value) {
 203        if (!self::isValidStatusConstant($key)) {
 204          throw new Exception(
 205            pht(
 206              'Key "%s" is not a valid status constant. Status constants must '.
 207              'be 1-12 characters long and contain only lowercase letters (a-z) '.
 208              'and digits (0-9). For example, "%s" or "%s" are reasonable '.
 209              'choices.',
 210              $key,
 211              'open',
 212              'closed'));
 213        }
 214        if (!is_array($value)) {
 215          throw new Exception(
 216            pht(
 217              'Value for key "%s" should be a dictionary.',
 218              $key));
 219        }
 220  
 221        PhutilTypeSpec::checkMap(
 222          $value,
 223          array(
 224            'name' => 'string',
 225            'name.full' => 'optional string',
 226            'name.action' => 'optional string',
 227            'closed' => 'optional bool',
 228            'special' => 'optional string',
 229            'transaction.icon' => 'optional string',
 230            'transaction.color' => 'optional string',
 231            'silly' => 'optional bool',
 232            'prefixes' => 'optional list<string>',
 233            'suffixes' => 'optional list<string>',
 234          ));
 235      }
 236  
 237      $special_map = array();
 238      foreach ($config as $key => $value) {
 239        $special = idx($value, 'special');
 240        if (!$special) {
 241          continue;
 242        }
 243  
 244        if (isset($special_map[$special])) {
 245          throw new Exception(
 246            pht(
 247              'Configuration has two statuses both marked with the special '.
 248              'attribute "%s" ("%s" and "%s"). There should be only one.',
 249              $special,
 250              $special_map[$special],
 251              $key));
 252        }
 253  
 254        switch ($special) {
 255          case self::SPECIAL_DEFAULT:
 256            if (!empty($value['closed'])) {
 257              throw new Exception(
 258                pht(
 259                  'Status "%s" is marked as default, but it is a closed '.
 260                  'status. The default status should be an open status.',
 261                  $key));
 262            }
 263            break;
 264          case self::SPECIAL_CLOSED:
 265            if (empty($value['closed'])) {
 266              throw new Exception(
 267                pht(
 268                  'Status "%s" is marked as the default status for closing '.
 269                  'tasks, but is not a closed status. It should be a closed '.
 270                  'status.',
 271                  $key));
 272            }
 273            break;
 274          case self::SPECIAL_DUPLICATE:
 275            if (empty($value['closed'])) {
 276              throw new Exception(
 277                pht(
 278                  'Status "%s" is marked as the status for closing tasks as '.
 279                  'duplicates, but it is not a closed status. It should '.
 280                  'be a closed status.',
 281                  $key));
 282            }
 283            break;
 284        }
 285  
 286        $special_map[$special] = $key;
 287      }
 288  
 289      // NOTE: We're not explicitly validating that we have at least one open
 290      // and one closed status, because the DEFAULT and CLOSED specials imply
 291      // that to be true. If those change in the future, that might become a
 292      // reasonable thing to validate.
 293  
 294      $required = array(
 295        self::SPECIAL_DEFAULT,
 296        self::SPECIAL_CLOSED,
 297        self::SPECIAL_DUPLICATE,
 298      );
 299  
 300      foreach ($required as $required_special) {
 301        if (!isset($special_map[$required_special])) {
 302          throw new Exception(
 303            pht(
 304              'Configuration defines no task status with special attribute '.
 305              '"%s", but you must specify a status which fills this special '.
 306              'role.',
 307              $required_special));
 308        }
 309      }
 310    }
 311  
 312  }


Generated: Sun Nov 30 09:20:46 2014 Cross-referenced by PHPXref 0.7.1