Page MenuHomePhabricator

D8603.diff
No OneTemporary

D8603.diff

diff --git a/src/applications/harbormaster/controller/HarbormasterBuildableViewController.php b/src/applications/harbormaster/controller/HarbormasterBuildableViewController.php
--- a/src/applications/harbormaster/controller/HarbormasterBuildableViewController.php
+++ b/src/applications/harbormaster/controller/HarbormasterBuildableViewController.php
@@ -20,97 +20,21 @@
->withIDs(array($id))
->needBuildableHandles(true)
->needContainerHandles(true)
- ->needBuilds(true)
->executeOne();
if (!$buildable) {
return new Aphront404Response();
}
- $build_list = id(new PHUIObjectItemListView())
- ->setUser($viewer);
- foreach ($buildable->getBuilds() as $build) {
- $view_uri = $this->getApplicationURI('/build/'.$build->getID().'/');
- $item = id(new PHUIObjectItemView())
- ->setObjectName(pht('Build %d', $build->getID()))
- ->setHeader($build->getName())
- ->setHref($view_uri);
-
- switch ($build->getBuildStatus()) {
- case HarbormasterBuild::STATUS_INACTIVE:
- $item->setBarColor('grey');
- $item->addAttribute(pht('Inactive'));
- break;
- case HarbormasterBuild::STATUS_PENDING:
- $item->setBarColor('blue');
- $item->addAttribute(pht('Pending'));
- break;
- case HarbormasterBuild::STATUS_WAITING:
- $item->setBarColor('violet');
- $item->addAttribute(pht('Waiting'));
- break;
- case HarbormasterBuild::STATUS_BUILDING:
- $item->setBarColor('yellow');
- $item->addAttribute(pht('Building'));
- break;
- case HarbormasterBuild::STATUS_PASSED:
- $item->setBarColor('green');
- $item->addAttribute(pht('Passed'));
- break;
- case HarbormasterBuild::STATUS_FAILED:
- $item->setBarColor('red');
- $item->addAttribute(pht('Failed'));
- break;
- case HarbormasterBuild::STATUS_ERROR:
- $item->setBarColor('red');
- $item->addAttribute(pht('Unexpected Error'));
- break;
- case HarbormasterBuild::STATUS_STOPPED:
- $item->setBarColor('black');
- $item->addAttribute(pht('Stopped'));
- break;
- }
-
- if ($build->isRestarting()) {
- $item->addIcon('backward', pht('Restarting'));
- } else if ($build->isStopping()) {
- $item->addIcon('stop', pht('Stopping'));
- } else if ($build->isResuming()) {
- $item->addIcon('play', pht('Resuming'));
- }
-
- $build_id = $build->getID();
-
- $restart_uri = "build/restart/{$build_id}/buildable/";
- $resume_uri = "build/resume/{$build_id}/buildable/";
- $stop_uri = "build/stop/{$build_id}/buildable/";
-
- $item->addAction(
- id(new PHUIListItemView())
- ->setIcon('backward')
- ->setName(pht('Restart'))
- ->setHref($this->getApplicationURI($restart_uri))
- ->setWorkflow(true)
- ->setDisabled(!$build->canRestartBuild()));
+ // Pull builds and build targets.
+ $builds = id(new HarbormasterBuildQuery())
+ ->setViewer($viewer)
+ ->withBuildablePHIDs(array($buildable->getPHID()))
+ ->needBuildTargets(true)
+ ->execute();
- if ($build->canResumeBuild()) {
- $item->addAction(
- id(new PHUIListItemView())
- ->setIcon('play')
- ->setName(pht('Resume'))
- ->setHref($this->getApplicationURI($resume_uri))
- ->setWorkflow(true));
- } else {
- $item->addAction(
- id(new PHUIListItemView())
- ->setIcon('stop')
- ->setName(pht('Stop'))
- ->setHref($this->getApplicationURI($stop_uri))
- ->setWorkflow(true)
- ->setDisabled(!$build->canStopBuild()));
- }
+ $buildable->attachBuilds($builds);
- $build_list->addItem($item);
- }
+ $build_list = $this->buildBuildList($buildable);
$title = pht("Buildable %d", $id);
@@ -233,4 +157,137 @@
}
+ private function buildBuildList(HarbormasterBuildable $buildable) {
+ $viewer = $this->getRequest()->getUser();
+
+ $build_list = id(new PHUIObjectItemListView())
+ ->setUser($viewer);
+ foreach ($buildable->getBuilds() as $build) {
+ $view_uri = $this->getApplicationURI('/build/'.$build->getID().'/');
+ $item = id(new PHUIObjectItemView())
+ ->setObjectName(pht('Build %d', $build->getID()))
+ ->setHeader($build->getName())
+ ->setHref($view_uri);
+
+ switch ($build->getBuildStatus()) {
+ case HarbormasterBuild::STATUS_INACTIVE:
+ $item->setBarColor('grey');
+ $item->addAttribute(pht('Inactive'));
+ break;
+ case HarbormasterBuild::STATUS_PENDING:
+ $item->setBarColor('blue');
+ $item->addAttribute(pht('Pending'));
+ break;
+ case HarbormasterBuild::STATUS_WAITING:
+ $item->setBarColor('violet');
+ $item->addAttribute(pht('Waiting'));
+ break;
+ case HarbormasterBuild::STATUS_BUILDING:
+ $item->setBarColor('yellow');
+ $item->addAttribute(pht('Building'));
+ break;
+ case HarbormasterBuild::STATUS_PASSED:
+ $item->setBarColor('green');
+ $item->addAttribute(pht('Passed'));
+ break;
+ case HarbormasterBuild::STATUS_FAILED:
+ $item->setBarColor('red');
+ $item->addAttribute(pht('Failed'));
+ break;
+ case HarbormasterBuild::STATUS_ERROR:
+ $item->setBarColor('red');
+ $item->addAttribute(pht('Unexpected Error'));
+ break;
+ case HarbormasterBuild::STATUS_STOPPED:
+ $item->setBarColor('black');
+ $item->addAttribute(pht('Stopped'));
+ break;
+ }
+
+ if ($build->isRestarting()) {
+ $item->addIcon('backward', pht('Restarting'));
+ } else if ($build->isStopping()) {
+ $item->addIcon('stop', pht('Stopping'));
+ } else if ($build->isResuming()) {
+ $item->addIcon('play', pht('Resuming'));
+ }
+
+ $build_id = $build->getID();
+
+ $restart_uri = "build/restart/{$build_id}/buildable/";
+ $resume_uri = "build/resume/{$build_id}/buildable/";
+ $stop_uri = "build/stop/{$build_id}/buildable/";
+
+ $item->addAction(
+ id(new PHUIListItemView())
+ ->setIcon('backward')
+ ->setName(pht('Restart'))
+ ->setHref($this->getApplicationURI($restart_uri))
+ ->setWorkflow(true)
+ ->setDisabled(!$build->canRestartBuild()));
+
+ if ($build->canResumeBuild()) {
+ $item->addAction(
+ id(new PHUIListItemView())
+ ->setIcon('play')
+ ->setName(pht('Resume'))
+ ->setHref($this->getApplicationURI($resume_uri))
+ ->setWorkflow(true));
+ } else {
+ $item->addAction(
+ id(new PHUIListItemView())
+ ->setIcon('stop')
+ ->setName(pht('Stop'))
+ ->setHref($this->getApplicationURI($stop_uri))
+ ->setWorkflow(true)
+ ->setDisabled(!$build->canStopBuild()));
+ }
+
+ $targets = $build->getBuildTargets();
+
+ if ($targets) {
+ $target_list = id(new PHUIStatusListView());
+ foreach ($targets as $target) {
+ switch ($target->getTargetStatus()) {
+ case HarbormasterBuildTarget::STATUS_PENDING:
+ $icon = 'time-green';
+ break;
+ case HarbormasterBuildTarget::STATUS_PASSED:
+ $icon = 'accept-green';
+ break;
+ case HarbormasterBuildTarget::STATUS_FAILED:
+ $icon = 'reject-red';
+ break;
+ default:
+ $icon = 'question';
+ break;
+ }
+
+ try {
+ $impl = $target->getImplementation();
+ $name = $impl->getName();
+ } catch (Exception $ex) {
+ $name = $target->getClassName();
+ }
+
+ $target_list->addItem(
+ id(new PHUIStatusItemView())
+ ->setIcon($icon)
+ ->setTarget(pht('Target %d', $target->getID()))
+ ->setNote($name));
+ }
+
+ $target_box = id(new PHUIBoxView())
+ ->addPadding(PHUI::PADDING_SMALL)
+ ->appendChild($target_list);
+
+ $item->appendChild($target_box);
+ }
+
+ $build_list->addItem($item);
+ }
+
+ return $build_list;
+ }
+
}
diff --git a/src/applications/harbormaster/controller/HarbormasterStepAddController.php b/src/applications/harbormaster/controller/HarbormasterStepAddController.php
--- a/src/applications/harbormaster/controller/HarbormasterStepAddController.php
+++ b/src/applications/harbormaster/controller/HarbormasterStepAddController.php
@@ -22,19 +22,16 @@
->setViewer($viewer)
->withIDs(array($id))
->executeOne();
- if ($plan === null) {
- throw new Exception("Build plan not found!");
+ if (!$plan) {
+ return new Aphront404Response();
}
- $implementations =
- HarbormasterBuildStepImplementation::getImplementations();
-
$cancel_uri = $this->getApplicationURI('plan/'.$plan->getID().'/');
if ($request->isDialogFormPost()) {
$class = $request->getStr('step-type');
- if (!in_array($class, $implementations)) {
- return $this->createDialog($implementations, $cancel_uri);
+ if (!HarbormasterBuildStepImplementation::getImplementation($class)) {
+ return $this->createDialog($cancel_uri);
}
$steps = $plan->loadOrderedBuildSteps();
@@ -51,38 +48,30 @@
return id(new AphrontRedirectResponse())->setURI($edit_uri);
}
- return $this->createDialog($implementations, $cancel_uri);
+ return $this->createDialog($cancel_uri);
}
- function createDialog(array $implementations, $cancel_uri) {
+ private function createDialog($cancel_uri) {
$request = $this->getRequest();
$viewer = $request->getUser();
$control = id(new AphrontFormRadioButtonControl())
->setName('step-type');
- foreach ($implementations as $implementation_name) {
- $implementation = new $implementation_name();
- $control
- ->addButton(
- $implementation_name,
- $implementation->getName(),
- $implementation->getGenericDescription());
+ $all = HarbormasterBuildStepImplementation::getImplementations();
+ foreach ($all as $class => $implementation) {
+ $control->addButton(
+ $class,
+ $implementation->getName(),
+ $implementation->getGenericDescription());
}
- $dialog = new AphrontDialogView();
- $dialog->setTitle(pht('Add New Step'))
- ->setUser($viewer)
- ->addSubmitButton(pht('Add Build Step'))
- ->addCancelButton($cancel_uri);
- $dialog->appendChild(
- phutil_tag(
- 'p',
- array(),
- pht(
- 'Select what type of build step you want to add: ')));
- $dialog->appendChild($control);
- return id(new AphrontDialogResponse())->setDialog($dialog);
+ return $this->newDialog()
+ ->setTitle(pht('Add New Step'))
+ ->addSubmitButton(pht('Add Build Step'))
+ ->addCancelButton($cancel_uri)
+ ->appendParagraph(pht('Choose a type of build step to add:'))
+ ->appendChild($control);
}
}
diff --git a/src/applications/harbormaster/query/HarbormasterBuildQuery.php b/src/applications/harbormaster/query/HarbormasterBuildQuery.php
--- a/src/applications/harbormaster/query/HarbormasterBuildQuery.php
+++ b/src/applications/harbormaster/query/HarbormasterBuildQuery.php
@@ -8,6 +8,7 @@
private $buildStatuses;
private $buildablePHIDs;
private $buildPlanPHIDs;
+ private $needBuildTargets;
public function withIDs(array $ids) {
$this->ids = $ids;
@@ -34,6 +35,11 @@
return $this;
}
+ public function needBuildTargets($need_targets) {
+ $this->needBuildTargets = $need_targets;
+ return $this;
+ }
+
protected function loadPage() {
$table = new HarbormasterBuild();
$conn_r = $table->establishConnection('r');
@@ -102,6 +108,24 @@
$build->attachUnprocessedCommands($unprocessed_commands);
}
+ if ($this->needBuildTargets) {
+ $targets = id(new HarbormasterBuildTargetQuery())
+ ->setViewer($this->getViewer())
+ ->setParentQuery($this)
+ ->withBuildPHIDs($build_phids)
+ ->execute();
+
+ // TODO: Some day, when targets have dependencies, we should toposort
+ // these. For now, just put them into chronological order.
+ $targets = array_reverse($targets);
+
+ $targets = mgroup($targets, 'getBuildPHID');
+ foreach ($page as $build) {
+ $build_targets = idx($targets, $build->getPHID(), array());
+ $build->attachBuildTargets($build_targets);
+ }
+ }
+
return $page;
}
diff --git a/src/applications/harbormaster/step/HarbormasterBuildStepImplementation.php b/src/applications/harbormaster/step/HarbormasterBuildStepImplementation.php
--- a/src/applications/harbormaster/step/HarbormasterBuildStepImplementation.php
+++ b/src/applications/harbormaster/step/HarbormasterBuildStepImplementation.php
@@ -3,11 +3,32 @@
abstract class HarbormasterBuildStepImplementation {
public static function getImplementations() {
- $symbols = id(new PhutilSymbolLoader())
+ return id(new PhutilSymbolLoader())
->setAncestorClass('HarbormasterBuildStepImplementation')
- ->setConcreteOnly(true)
- ->selectAndLoadSymbols();
- return ipull($symbols, 'name');
+ ->loadObjects();
+ }
+
+ public static function getImplementation($class) {
+ $base = idx(self::getImplementations(), $class);
+
+ if ($base) {
+ return (clone $base);
+ }
+
+ return null;
+ }
+
+ public static function requireImplementation($class) {
+ if (!$class) {
+ throw new Exception(pht('No implementation is specified!'));
+ }
+
+ $implementation = self::getImplementation($class);
+ if (!$implementation) {
+ throw new Exception(pht('No such implementation "%s" exists!', $class));
+ }
+
+ return $implementation;
}
/**
@@ -163,4 +184,16 @@
return array();
}
+ protected function formatSettingForDescription($key, $default = null) {
+ return $this->formatValueForDescription($this->getSetting($key, $default));
+ }
+
+ protected function formatValueForDescription($value) {
+ if (strlen($value)) {
+ return phutil_tag('strong', array(), $value);
+ } else {
+ return phutil_tag('em', array(), pht('(null)'));
+ }
+ }
+
}
diff --git a/src/applications/harbormaster/step/HarbormasterCommandBuildStepImplementation.php b/src/applications/harbormaster/step/HarbormasterCommandBuildStepImplementation.php
--- a/src/applications/harbormaster/step/HarbormasterCommandBuildStepImplementation.php
+++ b/src/applications/harbormaster/step/HarbormasterCommandBuildStepImplementation.php
@@ -12,12 +12,10 @@
}
public function getDescription() {
- $settings = $this->getSettings();
-
return pht(
- 'Run \'%s\' on \'%s\'.',
- $settings['command'],
- $settings['hostartifact']);
+ 'Run command %s on host %s.',
+ $this->formatSettingForDescription('command'),
+ $this->formatSettingForDescription('hostartifact'));
}
public function execute(
diff --git a/src/applications/harbormaster/step/HarbormasterHTTPRequestBuildStepImplementation.php b/src/applications/harbormaster/step/HarbormasterHTTPRequestBuildStepImplementation.php
--- a/src/applications/harbormaster/step/HarbormasterHTTPRequestBuildStepImplementation.php
+++ b/src/applications/harbormaster/step/HarbormasterHTTPRequestBuildStepImplementation.php
@@ -12,11 +12,16 @@
}
public function getDescription() {
- $settings = $this->getSettings();
+ $domain = null;
+ $uri = $this->getSetting('uri');
+ if ($uri) {
+ $domain = id(new PhutilURI($uri))->getDomain();
+ }
- $uri = new PhutilURI($settings['uri']);
- $domain = $uri->getDomain();
- return pht('Make an HTTP %s request to %s', $settings['method'], $domain);
+ return pht(
+ 'Make an HTTP %s request to %s.',
+ $this->formatSettingForDescription('method', 'POST'),
+ $this->formatValueForDescription($domain));
}
public function execute(
diff --git a/src/applications/harbormaster/step/HarbormasterLeaseHostBuildStepImplementation.php b/src/applications/harbormaster/step/HarbormasterLeaseHostBuildStepImplementation.php
--- a/src/applications/harbormaster/step/HarbormasterLeaseHostBuildStepImplementation.php
+++ b/src/applications/harbormaster/step/HarbormasterLeaseHostBuildStepImplementation.php
@@ -11,16 +11,6 @@
return pht('Obtain a lease on a Drydock host for performing builds.');
}
- public function getDescription() {
- $settings = $this->getSettings();
-
- return pht(
- 'Obtain a lease on a Drydock host whose platform is \'%s\' and store '.
- 'the resulting lease in a host artifact called \'%s\'.',
- $settings['platform'],
- $settings['name']);
- }
-
public function execute(
HarbormasterBuild $build,
HarbormasterBuildTarget $build_target) {
diff --git a/src/applications/harbormaster/step/HarbormasterPublishFragmentBuildStepImplementation.php b/src/applications/harbormaster/step/HarbormasterPublishFragmentBuildStepImplementation.php
--- a/src/applications/harbormaster/step/HarbormasterPublishFragmentBuildStepImplementation.php
+++ b/src/applications/harbormaster/step/HarbormasterPublishFragmentBuildStepImplementation.php
@@ -12,12 +12,10 @@
}
public function getDescription() {
- $settings = $this->getSettings();
-
return pht(
- 'Publish file artifact \'%s\' to the fragment path \'%s\'.',
- $settings['artifact'],
- $settings['path']);
+ 'Publish file artifact %s as fragment %s.',
+ $this->formatSettingForDescription('artifact'),
+ $this->formatSettingForDescription('path'));
}
public function execute(
diff --git a/src/applications/harbormaster/step/HarbormasterSleepBuildStepImplementation.php b/src/applications/harbormaster/step/HarbormasterSleepBuildStepImplementation.php
--- a/src/applications/harbormaster/step/HarbormasterSleepBuildStepImplementation.php
+++ b/src/applications/harbormaster/step/HarbormasterSleepBuildStepImplementation.php
@@ -12,9 +12,9 @@
}
public function getDescription() {
- $settings = $this->getSettings();
-
- return pht('Sleep for %s seconds.', $settings['seconds']);
+ return pht(
+ 'Sleep for %s seconds.',
+ $this->formatSettingForDescription('seconds'));
}
public function execute(
diff --git a/src/applications/harbormaster/step/HarbormasterThrowExceptionBuildStep.php b/src/applications/harbormaster/step/HarbormasterThrowExceptionBuildStep.php
--- a/src/applications/harbormaster/step/HarbormasterThrowExceptionBuildStep.php
+++ b/src/applications/harbormaster/step/HarbormasterThrowExceptionBuildStep.php
@@ -11,10 +11,6 @@
return pht('Throw an exception.');
}
- public function getDescription() {
- return pht('Throw an exception.');
- }
-
public function execute(
HarbormasterBuild $build,
HarbormasterBuildTarget $build_target) {
diff --git a/src/applications/harbormaster/step/HarbormasterUploadArtifactBuildStepImplementation.php b/src/applications/harbormaster/step/HarbormasterUploadArtifactBuildStepImplementation.php
--- a/src/applications/harbormaster/step/HarbormasterUploadArtifactBuildStepImplementation.php
+++ b/src/applications/harbormaster/step/HarbormasterUploadArtifactBuildStepImplementation.php
@@ -4,20 +4,18 @@
extends HarbormasterBuildStepImplementation {
public function getName() {
- return pht('Upload Artifact');
+ return pht('Upload File');
}
public function getGenericDescription() {
- return pht('Upload an artifact from a Drydock host to Phabricator.');
+ return pht('Upload a file from a host to Phabricator.');
}
public function getDescription() {
- $settings = $this->getSettings();
-
return pht(
- 'Upload artifact located at \'%s\' on \'%s\'.',
- $settings['path'],
- $settings['hostartifact']);
+ 'Upload %s from %s.',
+ $this->formatSettingForDescription('path'),
+ $this->formatSettingForDescription('hostartifact'));
}
public function execute(
diff --git a/src/applications/harbormaster/step/HarbormasterWaitForPreviousBuildStepImplementation.php b/src/applications/harbormaster/step/HarbormasterWaitForPreviousBuildStepImplementation.php
--- a/src/applications/harbormaster/step/HarbormasterWaitForPreviousBuildStepImplementation.php
+++ b/src/applications/harbormaster/step/HarbormasterWaitForPreviousBuildStepImplementation.php
@@ -13,12 +13,6 @@
'before continuing.');
}
- public function getDescription() {
- return pht(
- 'Wait for previous commits to finish building the current plan '.
- 'before continuing.');
- }
-
public function execute(
HarbormasterBuild $build,
HarbormasterBuildTarget $build_target) {
diff --git a/src/applications/harbormaster/storage/build/HarbormasterBuild.php b/src/applications/harbormaster/storage/build/HarbormasterBuild.php
--- a/src/applications/harbormaster/storage/build/HarbormasterBuild.php
+++ b/src/applications/harbormaster/storage/build/HarbormasterBuild.php
@@ -9,6 +9,7 @@
private $buildable = self::ATTACHABLE;
private $buildPlan = self::ATTACHABLE;
+ private $buildTargets = self::ATTACHABLE;
private $unprocessedCommands = self::ATTACHABLE;
/**
@@ -102,6 +103,15 @@
return $this->assertAttached($this->buildPlan);
}
+ public function getBuildTargets() {
+ return $this->assertAttached($this->buildTargets);
+ }
+
+ public function attachBuildTargets(array $targets) {
+ $this->buildTargets = $targets;
+ return $this;
+ }
+
public function isBuilding() {
return $this->getBuildStatus() === self::STATUS_PENDING ||
$this->getBuildStatus() === self::STATUS_WAITING ||
diff --git a/src/applications/harbormaster/storage/build/HarbormasterBuildTarget.php b/src/applications/harbormaster/storage/build/HarbormasterBuildTarget.php
--- a/src/applications/harbormaster/storage/build/HarbormasterBuildTarget.php
+++ b/src/applications/harbormaster/storage/build/HarbormasterBuildTarget.php
@@ -16,6 +16,7 @@
private $build = self::ATTACHABLE;
private $buildStep = self::ATTACHABLE;
+ private $implementation;
public static function initializeNewBuildTarget(
HarbormasterBuild $build,
@@ -82,24 +83,14 @@
}
public function getImplementation() {
- if ($this->className === null) {
- throw new Exception("No implementation set for the given target.");
+ if ($this->implementation === null) {
+ $obj = HarbormasterBuildStepImplementation::requireImplementation(
+ $this->className);
+ $obj->loadSettings($this);
+ $this->implementation = $obj;
}
- static $implementations = null;
- if ($implementations === null) {
- $implementations =
- HarbormasterBuildStepImplementation::getImplementations();
- }
-
- $class = $this->className;
- if (!in_array($class, $implementations)) {
- throw new Exception(
- "Class name '".$class."' does not extend BuildStepImplementation.");
- }
- $implementation = newv($class, array());
- $implementation->loadSettings($this);
- return $implementation;
+ return $this->implementation;
}
@@ -147,8 +138,7 @@
}
public function describeAutomaticCapability($capability) {
- return pht(
- 'Users must be able to see a build to view its build targets.');
+ return pht('Users must be able to see a build to view its build targets.');
}
}
diff --git a/src/applications/harbormaster/storage/configuration/HarbormasterBuildStep.php b/src/applications/harbormaster/storage/configuration/HarbormasterBuildStep.php
--- a/src/applications/harbormaster/storage/configuration/HarbormasterBuildStep.php
+++ b/src/applications/harbormaster/storage/configuration/HarbormasterBuildStep.php
@@ -12,6 +12,7 @@
private $buildPlan = self::ATTACHABLE;
private $customFields = self::ATTACHABLE;
+ private $implementation;
public function getConfiguration() {
return array(
@@ -46,24 +47,14 @@
}
public function getStepImplementation() {
- if ($this->className === null) {
- throw new Exception("No implementation set for the given step.");
+ if ($this->implementation === null) {
+ $obj = HarbormasterBuildStepImplementation::requireImplementation(
+ $this->className);
+ $obj->loadSettings($this);
+ $this->implementation = $obj;
}
- static $implementations = null;
- if ($implementations === null) {
- $implementations =
- HarbormasterBuildStepImplementation::getImplementations();
- }
-
- $class = $this->className;
- if (!in_array($class, $implementations)) {
- throw new Exception(
- "Class name '".$class."' does not extend BuildStepImplementation.");
- }
- $implementation = newv($class, array());
- $implementation->loadSettings($this);
- return $implementation;
+ return $this->implementation;
}

File Metadata

Mime Type
text/plain
Expires
Tue, Oct 22, 7:26 PM (3 w, 6 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6728389
Default Alt Text
D8603.diff (24 KB)

Event Timeline