src/flow/field/ICFlowField.php (184 lines of code) (raw):

<?php abstract class ICFlowField extends Phobject { private $futureResults = array(); private $cache; private $configuration; abstract public function getFieldKey(); final public function renderTableCell(ICFlowFeature $feature) { $values = $this->getValues($feature); if ($values) { return $this->renderValues($values); } return ''; } abstract protected function renderValues(array $values); abstract public function getValues(ICFlowFeature $feature); public function getSummary() { return null; } public function isDefaultField() { return true; } final public function isEnabled() { return idx($this->getConfiguration(), 'enabled'); } public function getDefaultFieldOrder() { return 0; } final public function getFieldOrder() { return idx($this->getConfiguration(), 'order'); } final protected function getDefaultConfiguration() { return array( 'enabled' => $this->isDefaultField(), 'order' => $this->getDefaultFieldOrder(), ); } public function validateOption($option, $value) { throw new Exception(pht( 'No config option named "%s" exists.', $option)); } protected function getOptions() { return array(); } protected function getOptionValue($option) { $info = idx($this->getOptions(), $option); if (!$info) { throw new Exception(pht( 'No config option named "%s" exists.', $option)); } $default = idx($info, 'default'); return idx($this->getConfiguration(), $option, $default); } final public function getConfiguration() { if (!$this->configuration) { return $this->getDefaultConfiguration(); } return $this->configuration; } final public function loadConfiguration(array $configuration) { $this->configuration = array_merge( $this->getConfiguration(), $configuration); return $this; } private function getCache() { if (!$this->cache) { $this->cache = ic_standard_cache( ic_data_cache('flow'), $this->getFieldKey(), 128, false); } return $this->cache; } protected function cacheGet($key, $default = null) { $rval = $this->getCache()->getKey($key); return $rval !== null ? $rval : $default; } protected function cacheSet($key, $value) { $this->getCache()->setKey($key, $value); } protected function getFutures(ICFlowWorkspace $workspace) { return array(); } private function setFutureResult($key, $value) { $this->futureResults[$key] = $value; return $this; } protected function getFutureResult($key, $default = null) { return idx($this->futureResults, $key, $default); } public function getTableColumn() { return array('title' => ''); } final public static function getAllFieldKeys() { $fields = (new PhutilClassMapQuery()) ->setAncestorClass(__CLASS__) ->setUniqueMethod('getFieldKey') ->execute(); return array_keys($fields); } final public static function newField($key) { $fields = (new PhutilClassMapQuery()) ->setAncestorClass(__CLASS__) ->setUniqueMethod('getFieldKey') ->execute(); $field = idx($fields, $key); if (!$field) { $valid_fields = implode(', ', array_keys($fields)); throw new Exception( pht( 'No Flow field exists with key "%s". Valid keys are: %s.', $key, $valid_fields)); } return (clone $field); } final public static function resolveFutures( array $fields, ICFlowWorkspace $workspace) { assert_instances_of($fields, __CLASS__); $fields = mpull($fields, null, 'getFieldKey'); $futures = array(); $profiler = PhutilServiceProfiler::getInstance(); $all_id = $profiler->beginServiceCall(array( 'type' => 'flow-futures', )); foreach ($fields as $field_key => $field) { $id = $profiler->beginServiceCall(array( 'type' => "flow-futures:{$field_key}", )); foreach ($field->getFutures($workspace) as $future_key => $future) { $field_future_key = "{$field_key}:{$future_key}"; $futures[$field_future_key] = $future; } $profiler->endServiceCall($id, array()); } $iterator = new FutureIterator($futures); foreach ($iterator as $field_future_key => $future) { $key_parts = explode(':', $field_future_key); $field_key = array_shift($key_parts); $future_key = implode(':', $key_parts); $field = $fields[$field_key]; $field->setFutureResult($future_key, $future->resolve()); } $profiler->endServiceCall($all_id, array()); } final public function renderInformation() { $option_summaries = array(); foreach ($this->getOptions() as $option => $info) { $option_summaries[] = tsprintf( " **%s**\n\n%B\n\n value: %s\n\n", $option, phutil_console_wrap($info['summary'], 6), (string)$this->getOptionValue($option)); } $options_summary = ''; if ($option_summaries) { $options_summary = tsprintf( " **%s**\n\n%R", pht('OPTIONS'), implode('', $option_summaries)); } if ($this->isEnabled()) { $state = tsprintf('<bg:green>** %s **</bg>', pht('ENABLED')); } else { $state = tsprintf('<bg:yellow>** %s **</bg>', pht('DISABLED')); } $summary = ''; if ($this->getSummary()) { $summary = tsprintf( "\n%B\n", phutil_console_wrap($this->getSummary(), 2)); } return tsprintf( "**%s** %R\n%B\n%R", $this->getFieldKey(), $state, $summary, $options_summary); } }