diff --git a/PHPCI/Controller/PluginController.php b/PHPCI/Controller/PluginController.php new file mode 100644 index 00000000..2d9d74fe --- /dev/null +++ b/PHPCI/Controller/PluginController.php @@ -0,0 +1,161 @@ + + * @package PHPCI + * @subpackage Web + */ +class PluginController extends \PHPCI\Controller +{ + protected $required = array( + 'block8/b8framework', + 'ircmaxell/password-compat', + 'swiftmailer/swiftmailer', + 'symfony/yaml', + 'symfony/console' + ); + + protected $canInstall; + protected $composerPath; + + public function init() + { + parent::init(); + $this->canInstall = function_exists('shell_exec'); + + if ($this->canInstall) { + $this->composerPath = $this->findBinary(array('composer', 'composer.phar')); + + if (!$this->composerPath) { + $this->canInstall = false; + } + } + } + + public function index() + { + $this->view->canWrite = is_writable(APPLICATION_PATH . 'composer.json'); + $this->view->canInstall = $this->canInstall; + $this->view->required = $this->required; + + $json = $this->getComposerJson(); + $this->view->installed = $json['require']; + $this->view->suggested = $json['suggest']; + + return $this->view->render(); + } + + public function remove() + { + $package = $this->getParam('package', null); + $json = $this->getComposerJson(); + + if (!in_array($package, $this->required)) { + unset($json['require'][$package]); + $this->setComposerJson($json); + + if ($this->canInstall) { + $res = shell_exec($this->composerPath . ' update --working-dir=' . APPLICATION_PATH . ' > /dev/null 2>&1 &'); + } + + header('Location: ' . PHPCI_URL . 'plugin?r=' . $package); + die; + } + + header('Location: ' . PHPCI_URL); + die; + } + + public function install() + { + $package = $this->getParam('package', null); + $version = $this->getParam('version', '*'); + + $json = $this->getComposerJson(); + $json['require'][$package] = $version; + $this->setComposerJson($json); + + if ($this->canInstall) { + $res = shell_exec($this->composerPath . ' update --working-dir=' . APPLICATION_PATH . ' > /dev/null 2>&1 &'); + + header('Location: ' . PHPCI_URL . 'plugin?i=' . $package); + die; + } + + header('Location: ' . PHPCI_URL . 'plugin?w=' . $package); + die; + } + + protected function getComposerJson() + { + $json = file_get_contents(APPLICATION_PATH . 'composer.json'); + return json_decode($json, true); + } + + protected function setComposerJson($array) + { + $json = json_encode($array); + file_put_contents(APPLICATION_PATH . 'composer.json', $json); + } + + protected function findBinary($binary) + { + if (is_string($binary)) { + $binary = array($binary); + } + + foreach ($binary as $bin) { + // Check project root directory: + if (is_file(APPLICATION_PATH . $bin)) { + return APPLICATION_PATH . $bin; + } + + // Check Composer bin dir: + if (is_file(APPLICATION_PATH . 'vendor/bin/' . $bin)) { + return APPLICATION_PATH . 'vendor/bin/' . $bin; + } + + // Use "which" + $which = trim(shell_exec('which ' . $bin)); + + if (!empty($which)) { + return $which; + } + } + + return null; + } + + public function packagistSearch() + { + $q = $this->getParam('q', ''); + $http = new \b8\HttpClient(); + $http->setHeaders(array('User-Agent: PHPCI/1.0 (+http://www.phptesting.org)')); + $res = $http->get('https://packagist.org/search.json', array('q' => $q)); + + die(json_encode($res['body'])); + } + + public function packagistVersions() + { + $name = $this->getParam('p', ''); + $http = new \b8\HttpClient(); + $http->setHeaders(array('User-Agent: PHPCI/1.0 (+http://www.phptesting.org)')); + $res = $http->get('https://packagist.org/packages/'.$name.'.json'); + + die(json_encode($res['body'])); + } +} diff --git a/PHPCI/View/Home/index.phtml b/PHPCI/View/Home/index.phtml index a7024590..1e186694 100644 --- a/PHPCI/View/Home/index.phtml +++ b/PHPCI/View/Home/index.phtml @@ -5,7 +5,8 @@
PHPCI cannot automatically install/remove plugins for you, as the shell_exec() + function is disabled. PHPCI will update composer.json for you, but you will need to run Composer manually to make the changes.
+ + + +PHPCI cannot update composer.json for you as it is not writable.
+ + + += $_GET['r']; ?> has been removed.
+ + + += $_GET['i']; ?> has been installed.
+ + + += $_GET['w']; ?> has been added to composer.json and will be installed next time you run composer update.
+ + +| Title | +Version | ++ |
|---|---|---|
| = $package; ?> | += $version; ?> | ++ + Remove » + + | +
| Title | +Description | ++ |
|---|---|---|
| = $package; ?> | += $version; ?> | ++ + + + | +