'install',
//'--no-dev' => true,
'--optimize-autoloader' => true,
'--no-interaction' => true,
'--no-progress' => true,
//'--verbose' => true,
]);
class WebComposer
{
public static $version = "0.0.2";
public static $agent = "WebComposer/v0.0.2";
public static $maxScanDepth = 3;
public static $path = __DIR__ . "/";
public static $composerPhar = 'composer.phar';
public static $composerJson = 'composer.json';
public static function init($params = [], $path = null, $composerJson = null, $composerPhar = null)
{
!is_null($path) && is_dir($path) && self::$path = $path;
!is_null($composerJson) && file_exists($composerJson) && self::$composerJson = $composerJson;
!is_null($composerPhar) && file_exists($composerPhar) && self::$composerPhar = $composerPhar;
self::header();
register_shutdown_function(static function(){ WebComposer::footer(); });
echo "".WebComposer::$agent." - PHP ".PHP_VERSION."";
self::scanJson();
self::scanPhar();
self::downloadComposer();
if(!self::checkFile(self::$composerPhar))
{
exit("composer.phar file is missing.");
}
self::runComposer($params);
}
public static function runComposer($params = [])
{
require_once 'phar://' . str_replace('\\', '/', self::$composerPhar) . '/src/bootstrap.php';
if(function_exists('putenv'))
{
@\putenv('COMPOSER_HOME=' . self::$path . '/vendor/bin/composer');
@\putenv('COMPOSER_DISABLE_XDEBUG_WARN=1');
}
create_output_class();
$output = new HtmlOutput();
if(empty($params))
{
$params = [
'command' => 'install',
'--no-dev' => true,
'--optimize-autoloader' => true,
'--no-interaction' => true,
'--no-progress' => true
//'--verbose' => true
];
}
try {
$input = new Symfony\Component\Console\Input\ArrayInput($params);
$application = new Composer\Console\Application();
$application->setAutoExit(false);
$application->run($input, $output);
} catch (Exception $ex) {
$output->writeln($ex->getMessage());
}
}
public static function disableOutputBuffering()
{
ob_implicit_flush(true);
while (ob_get_level() > 0)
{
$level = ob_get_level();
ob_end_clean();
if (ob_get_level() === $level)
{
break;
}
}
}
public static function convertLinks($str)
{
$pattern = '(?xi)\b((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:\'".,<>?«»“”‘’]))';
return preg_replace_callback("#$pattern#i", static function($matches) {
$input = $matches[0];
$url = preg_match('!^https?://!i', $input) ? $input : "http://$input";
return '' . htmlspecialchars($input)."";
}, $str);
}
public static function downloadComposer()
{
if (!self::checkFile(self::$composerPhar))
{
echo "Downloading composer.phar";
$download = self::downloadFile('https://getcomposer.org/composer.phar', self::$composerPhar);
echo $download
? "composer.phar downloaded!"
: "Error: cannot download composer.phar!";
return $download;
}
return true;
}
public static function scanPhar()
{
for ($i=0;$i<=self::$maxScanDepth;$i++)
{
$currentPath = self::$path . ($i > 0 ? str_repeat("../",$i) : "");
if (file_exists($currentPath . self::$composerPhar))
{
echo "Found composer.phar on $currentPath";
self::$composerPhar = $currentPath . self::$composerPhar;
return true;
}
}
return false;
}
public static function scanJson()
{
for ($i=0;$i<=self::$maxScanDepth;$i++)
{
$currentPath = self::$path . ($i > 0 ? str_repeat("../",$i) : "");
if (file_exists($currentPath . self::$composerJson))
{
echo "Current working directory: $currentPath";
@chdir($currentPath);
self::$composerJson = $currentPath . self::$composerJson;
self::$path = $currentPath;
return true;
}
}
return false;
}
public static function downloadFile($url, $file, $options = [])
{
return self::curlDownload($url, $file, $options) || self::fopenDownload($url, $file);
}
private static function checkFile($file)
{
@\clearstatcache(true, $file);
@\clearstatcache(false, $file);
if((@\filesize($file))<1)
{
@\unlink($file);
return false;
}
return true;
}
private static function fopenDownload($url, $file)
{
if(!ini_get("allow_url_fopen"))
{
return false;
}
$context = stream_context_create([
"http" => [
"user_agent" => self::$agent
],
'ssl' => [
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
]
]);
$data = file_get_contents($url, false, $context);
if(!file_put_contents($file, $data))
{
return false;
}
return self::checkFile($file);
}
private static function curlDownload($url, $file, array $options = [])
{
if(!function_exists('curl_init'))
{
return false;
}
$fp = @\fopen($file, 'wb');
if(!@\is_resource($fp)) return false;
$ch = @\curl_init();
$defaultOptions = [
CURLOPT_URL => $url,
CURLOPT_FILE => $fp,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_USERAGENT => self::$agent,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
];
@\curl_setopt_array($ch,@\array_replace($defaultOptions,$options));
$status = @\curl_exec($ch);
$hs = @\curl_getinfo($ch, CURLINFO_HTTP_CODE);
@\curl_close($ch);
@\fclose($fp);
return $status && @\in_array($hs, [200, 301, 302], true) && self::checkFile($file);
}
public static function header()
{
echo <<
Web Composer Installer
HTML;
}
public static function footer()
{
echo <<
HTML;
}
}
function create_output_class()
{
class HtmlOutput extends \Symfony\Component\Console\Output\Output
{
public function __construct($verbosity = self::VERBOSITY_NORMAL, $decorated = false, Symfony\Component\Console\Formatter\OutputFormatterInterface $formatter = null)
{
parent::__construct($verbosity, $decorated, $formatter);
WebComposer::disableOutputBuffering();
}
protected function terminalOutputParser($text)
{
return WebComposer::convertLinks(strtr(htmlspecialchars($text, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'), [
"<info>" => "
",
"</info>" => "",
"<warning>" => "
",
"</warning>" => "",
"<error>" => "
",
"</error>" => "",
"<comment>" => "
",
"</comment>" => "",
"<success>" => "
",
"</success>" => "",
"<br>" => "
",
]));
}
public function writeln($messages, $options = 0)
{
$this->write($messages, true, $options);
}
public function write($messages, $newline = false, $options = self::OUTPUT_NORMAL)
{
$this->doWrite($messages, $newline);
}
protected function doWrite($message, $newline = false)
{
echo "
";
if(is_array($message))
{
foreach ($message as $single)
{
if(is_array($single))
{
$this->doWrite($single, $newline);
}
}
}
else
{
$message = str_replace("\n", "
\n", $message);
echo $this->terminalOutputParser($message);
}
if ($newline) {
echo "
\n";
}
echo "";
if (ob_get_length())
{
ob_flush();
flush();
}
}
}
}