--- /dev/null
+<?php
+namespace Consolidation\SiteAlias;
+
+use Consolidation\Config\Config;
+use Consolidation\Config\ConfigInterface;
+use Consolidation\Config\Util\ArrayUtil;
+use Consolidation\SiteAlias\Util\FsUtils;
+
+/**
+ * An alias record is a configuration record containing well-known items.
+ *
+ * @see AliasRecordInterface for documentation
+ */
+class AliasRecord extends Config implements AliasRecordInterface
+{
+ /**
+ * @var string
+ */
+ protected $name;
+
+ /**
+ * @inheritdoc
+ */
+ public function __construct(array $data = null, $name = '', $env = '')
+ {
+ parent::__construct($data);
+ if (!empty($env)) {
+ $name .= ".$env";
+ }
+ $this->name = $name;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function getConfig(ConfigInterface $config, $key, $default = null)
+ {
+ if ($this->has($key)) {
+ return $this->get($key, $default);
+ }
+ return $config->get($key, $default);
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function name()
+ {
+ return $this->name;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function setName($name)
+ {
+ $this->name = $name;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function hasRoot()
+ {
+ return $this->has('root');
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function root()
+ {
+ $root = $this->get('root');
+ if ($this->isLocal()) {
+ return FsUtils::realpath($root);
+ }
+ return $root;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function uri()
+ {
+ return $this->get('uri');
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function setUri($uri)
+ {
+ return $this->set('uri', $uri);
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function remoteHostWithUser()
+ {
+ $result = $this->remoteHost();
+ if (!empty($result) && $this->hasRemoteUser()) {
+ $result = $this->remoteUser() . '@' . $result;
+ }
+ return $result;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function remoteUser()
+ {
+ return $this->get('user');
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function hasRemoteUser()
+ {
+ return $this->has('user');
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function remoteHost()
+ {
+ return $this->get('host');
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function isRemote()
+ {
+ return $this->has('host');
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function isLocal()
+ {
+ return !$this->isRemote();
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function isNone()
+ {
+ return empty($this->root()) && $this->isLocal();
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function localRoot()
+ {
+ if ($this->isLocal() && $this->hasRoot()) {
+ return $this->root();
+ }
+
+ return false;
+ }
+
+ /**
+ * os returns the OS that this alias record points to. For local alias
+ * records, PHP_OS will be returned. For remote alias records, the
+ * value from the `os` element will be returned. If there is no `os`
+ * element, then the default assumption is that the remote system is Linux.
+ *
+ * @return string
+ * Linux
+ * WIN* (e.g. WINNT)
+ * CYGWIN
+ * MINGW* (e.g. MINGW32)
+ */
+ public function os()
+ {
+ if ($this->isLocal()) {
+ return PHP_OS;
+ }
+ return $this->get('os', 'Linux');
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function exportConfig()
+ {
+ return $this->remap($this->export());
+ }
+
+ /**
+ * Reconfigure data exported from the form it is expected to be in
+ * inside an alias record to the form it is expected to be in when
+ * inside a configuration file.
+ */
+ protected function remap($data)
+ {
+ foreach ($this->remapOptionTable() as $from => $to) {
+ if (isset($data[$from])) {
+ unset($data[$from]);
+ }
+ $value = $this->get($from, null);
+ if (isset($value)) {
+ $data['options'][$to] = $value;
+ }
+ }
+
+ return new Config($data);
+ }
+
+ /**
+ * Fetch the parameter-specific options from the 'alias-parameters' section of the alias.
+ * @param string $parameterName
+ * @return array
+ */
+ protected function getParameterSpecificOptions($aliasData, $parameterName)
+ {
+ if (!empty($parameterName) && $this->has("alias-parameters.{$parameterName}")) {
+ return $this->get("alias-parameters.{$parameterName}");
+ }
+ return [];
+ }
+
+ /**
+ * Convert the data in this record to the layout that was used
+ * in the legacy code, for backwards compatiblity.
+ */
+ public function legacyRecord()
+ {
+ $result = $this->exportConfig()->get('options', []);
+
+ // Backend invoke needs a couple of critical items in specific locations.
+ if ($this->has('paths.drush-script')) {
+ $result['path-aliases']['%drush-script'] = $this->get('paths.drush-script');
+ }
+ if ($this->has('ssh.options')) {
+ $result['ssh-options'] = $this->get('ssh.options');
+ }
+ return $result;
+ }
+
+ /**
+ * Conversion table from old to new option names. These all implicitly
+ * go in `options`, although they can come from different locations.
+ */
+ protected function remapOptionTable()
+ {
+ return [
+ 'user' => 'remote-user',
+ 'host' => 'remote-host',
+ 'root' => 'root',
+ 'uri' => 'uri',
+ ];
+ }
+}