diff --git a/src/Apps/HeidiSqlApp.php b/src/Apps/HeidiSqlApp.php index abb2d05..1e73530 100644 --- a/src/Apps/HeidiSqlApp.php +++ b/src/Apps/HeidiSqlApp.php @@ -6,6 +6,7 @@ * Open Site database in HeidiSQL */ class HeidiSqlApp extends PancakesApp { + /** * {@inheritdoc} */ diff --git a/src/Apps/MySQLApp.php b/src/Apps/MySQLApp.php index 7d873b0..fae06d4 100644 --- a/src/Apps/MySQLApp.php +++ b/src/Apps/MySQLApp.php @@ -6,6 +6,7 @@ * Open Site database in MySQL CLI */ class MySQLApp extends PancakesApp { + /** * {@inheritdoc} */ @@ -17,12 +18,12 @@ class MySQLApp extends PancakesApp { public $app = 'MySQL'; /** - * - App Location Candinates + * App Location */ public $app_location; public function open(){ - $cmd = join(' ', [ + $cmd = implode(' ', [ 'mysql', '-h ' . $this->escapeShellArg($this->connection_info['mysql_host']), '-P ' . $this->escapeShellArg($this->connection_info['mysql_port']), @@ -54,4 +55,14 @@ public function validate() { $this->app_location = 'mysql'; return $this->which($this->app_location); } + + /** + * Priority for mysql cli should be last. + * + * @return int + */ + public function weight() { + return 100; + } + } diff --git a/src/Apps/MySQLWorkbenchApp.php b/src/Apps/MySQLWorkbenchApp.php index e12cc33..c8c40de 100644 --- a/src/Apps/MySQLWorkbenchApp.php +++ b/src/Apps/MySQLWorkbenchApp.php @@ -33,7 +33,7 @@ class MySQLWorkbenchApp extends PancakesApp { * @return bool */ public function validate() { - /* @TODO: Terminus now has Utils for this, wait until most people are using it and switch it */ + /* @TODO: Terminus now has Utils for this. */ switch (php_uname('s')) { case 'Darwin': $this->app_location = '/Applications/MySQLWorkbench.app/Contents/MacOS/MySQLWorkbench'; @@ -157,4 +157,5 @@ protected function writeXML($file, $xml, $sftp_host) { fclose($handle); } } + } diff --git a/src/Apps/PancakesApp.php b/src/Apps/PancakesApp.php index c3ec631..63c50da 100644 --- a/src/Apps/PancakesApp.php +++ b/src/Apps/PancakesApp.php @@ -2,39 +2,52 @@ namespace Pantheon\TerminusPancakes\Apps; +use Pantheon\TerminusPancakes\Commands\PancakesCommand; +use Psr\Log\LoggerInterface; + /** * Interface PancakesApp + * * @package Pantheon\TerminusPancakes\Apps */ class PancakesApp { /** + * Connection Info Array + * * @var array */ protected $connection_info; /** - * @var + * @var LoggerInterface */ protected $logger; /** - * @var \Pantheon\TerminusPancakes\Commands\PancakesCommand + * @var PancakesCommand */ protected $command; /** - * {@inheritdoc} + * Main app name. + * + * @var string */ - public $aliases = []; + public $app = ''; /** - * {@inheritdoc} + * Array of aliases for the pancakes app. + * + * @var string[] */ - public $app = ''; + public $aliases = []; /** * PancakesApp constructor. + * + * @param $connection_info + * @param $logger */ public function __construct($connection_info, $logger){ $this->connection_info = $connection_info; @@ -49,12 +62,16 @@ public function __toString() { } /** + * Open the app with the connection info. + * * @return void */ public function open(){} /** - * @return void + * Validates if the app can be used. + * + * @return bool */ public function validate(){} @@ -74,7 +91,7 @@ public function isWindows(){ protected function flag($name) { // I was very tempted to use str_pad.... // return str_pad($name, strlen($name) + 1 + !Utils\isWindows(), '-', STR_PAD_LEFT); - return ($this->isWindows() ? "-" : "--") . $name; + return ($this->isWindows() ? '-' : '--') . $name; } /** @@ -144,11 +161,12 @@ protected function escapeShellArg($arg, $raw = FALSE) { /** * Execute Command * @param $command - * @param $arguments - * @return bool True if command executes without an error + * @param array|string $arguments + * @return bool true + * If command executes without an error */ - protected function execCommand($command, $arguments = array()) { - $arguments = is_array($arguments) ? $arguments : [$arguments]; + protected function execCommand($command, $arguments = '') { + $arguments = is_array($arguments) ? $arguments : (array) $arguments; if (!empty($arguments)) { $command .= ' ' . implode(' ', $arguments); @@ -168,9 +186,19 @@ protected function writeFile($data, $suffix = NULL) { $tempfile = tempnam(sys_get_temp_dir(), 'terminus-pancakes'); $tempfile .= !empty($suffix) ? ('.' . $suffix) : ''; - $handle = fopen($tempfile, "w"); + $handle = fopen($tempfile, 'w'); fwrite($handle, $data); fclose($handle); return $tempfile; } + + /** + * Gets the weight of the pancakes app. + * + * @return int + */ + public function weight() { + return 0; + } + } \ No newline at end of file diff --git a/src/Apps/SequelProApp.php b/src/Apps/SequelProApp.php index 7192464..4619662 100644 --- a/src/Apps/SequelProApp.php +++ b/src/Apps/SequelProApp.php @@ -6,6 +6,7 @@ * Open Site database in SequelPro */ class SequelProApp extends PancakesApp { + /** * {@inheritdoc} */ @@ -29,7 +30,7 @@ public function open() { * Validates the app can be used */ public function validate() { - return php_uname('s') == 'Darwin'; + return php_uname('s') === 'Darwin'; } /** diff --git a/src/Commands/PancakesCommand.php b/src/Commands/PancakesCommand.php index 2ef7ee3..0204357 100644 --- a/src/Commands/PancakesCommand.php +++ b/src/Commands/PancakesCommand.php @@ -5,8 +5,12 @@ use Pantheon\Terminus\Commands\TerminusCommand; use Pantheon\Terminus\Site\SiteAwareInterface; use Pantheon\Terminus\Site\SiteAwareTrait; -use Pantheon\Terminus\Collections\Sites; use Pantheon\Terminus\Exceptions\TerminusException; +use Pantheon\Terminus\Models\Environment; +use Pantheon\Terminus\Models\Site; +use Pantheon\TerminusPancakes\Apps\PancakesApp; + +include __DIR__ . DIRECTORY_SEPARATOR . '../..' . DIRECTORY_SEPARATOR . 'vendor/autoload.php'; /** * Open Site database in your favorite MySQL Editor @@ -17,7 +21,7 @@ class PancakesCommand extends TerminusCommand Implements SiteAwareInterface { use SiteAwareTrait; /** - * @var + * @var array */ private $connection_info; @@ -33,8 +37,12 @@ class PancakesCommand extends TerminusCommand Implements SiteAwareInterface { * @option string $app Application to Open (optional) * * @usage terminus site:pancakes . + * + * @throws TerminusException */ - public function pancakes($site_env, $options = ['app' => NULL]) { + public function pancakes($site_env, array $options = ['app' => NULL]) { + /* @var $env Environment */ + /* @var $site Site */ list($site, $env) = $this->getSiteEnv($site_env); $env->wake(); @@ -52,7 +60,7 @@ public function pancakes($site_env, $options = ['app' => NULL]) { } $this->connection_info['sftp_port'] = $sftp_port; - $candidate_instances = $this->getCandinatePlugins(); + $candidate_instances = $this->getCandidatePlugins(); $instance = NULL; @@ -118,43 +126,34 @@ public function pancakes($site_env, $options = ['app' => NULL]) { } /** - * Gets Candinate Classes that are Loaded + * Gets Candidate Classes that are Loaded + * * @return array */ - private function getCandinatePlugins() { - // Find our Children! - $classes = get_declared_classes(); - $candidate_instances = []; - - foreach ($classes as $class) { - $reflection = new \ReflectionClass($class); - if ($reflection->isSubclassOf('Pantheon\TerminusPancakes\Apps\PancakesApp')) { - $candidate_instance = $reflection->newInstanceArgs([ - $this->connection_info, - $this->log() - ]); + private function getCandidatePlugins() { + $iterator = new \DirectoryIterator(__DIR__ . '/../Apps'); - if (method_exists($candidate_instance, 'validate')) { - if (!$candidate_instance->validate()) { - continue; - } - } + // Autoload plugins + foreach ($iterator as $file) { + $plugin = 'Pantheon\TerminusPancakes\Apps\\' . $file->getBasename('.php'); - $candidate_instances[] = $candidate_instance; + // Don't load PancakesApp since that's the base plugin. + if (PancakesApp::class === $plugin || !$file->isFile()) { + continue; } - } - return $candidate_instances; - } -} + /* @var $candidate_instance PancakesApp */ + $candidate_instance = new $plugin($this->connection_info, $this->log()); -// Force PancakesApp to be first. -require_once dirname(__FILE__) . '/../Apps/PancakesApp.php'; + if (!$candidate_instance->validate()) { + continue; + } -// Include Sub-Commands - Terminus uses DirectoryIterator so we need to have better control over the order. -$iterator = new \DirectoryIterator(dirname(__FILE__) . '/../Apps'); -foreach ($iterator as $file) { - if ($file->isFile()) { - include_once $file->getPathname(); + $candidate_instances[$candidate_instance->weight()] = $candidate_instance; + } + + ksort($candidate_instances); + + return $candidate_instances; } } \ No newline at end of file