Skip to content

Commit 00cc8a7

Browse files
authored
Merge pull request #7 from JeyKeu/master
Added: Show WordPress download progress
2 parents f47a439 + e90d543 commit 00cc8a7

File tree

1 file changed

+82
-28
lines changed

1 file changed

+82
-28
lines changed

src/Console/NewCommand.php

Lines changed: 82 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22

33
use Azi\Generators\Theme;
44
use GuzzleHttp\Client;
5+
use GuzzleHttp\Exception\BadResponseException;
56
use RecursiveDirectoryIterator;
67
use RecursiveIteratorIterator;
78
use RuntimeException;
89
use Symfony\Component\Console\Command\Command;
10+
use Symfony\Component\Console\Helper\ProgressBar;
911
use Symfony\Component\Console\Input\InputArgument;
1012
use Symfony\Component\Console\Input\InputInterface;
1113
use Symfony\Component\Console\Input\InputOption;
@@ -41,7 +43,7 @@ class NewCommand extends Command
4143
*
4244
* @param null $name
4345
*/
44-
public function __construct( $name = null )
46+
public function __construct($name = null)
4547
{
4648
$this->cacheDirectory = $this->getCacheDirectory();
4749
$this->createCacheDirectory();
@@ -60,7 +62,7 @@ public function getApp()
6062
* @param mixed $app
6163
* @return NewCommand
6264
*/
63-
public function setApp( $app )
65+
public function setApp($app)
6466
{
6567
$this->app = $app;
6668
return $this;
@@ -78,7 +80,7 @@ public function getVersion()
7880
* @param mixed $version
7981
* @return NewCommand
8082
*/
81-
public function setVersion( $version )
83+
public function setVersion($version)
8284
{
8385
$this->version = $version;
8486

@@ -94,35 +96,33 @@ protected function configure()
9496
->setName('new')
9597
->setDescription('Create a new WordPress application with Timber.')
9698
->addArgument('name', InputArgument::OPTIONAL, 'Your applications\'s name')
97-
->addArgument('version', InputArgument::OPTIONAL, 'The version of wordpress to download');
99+
->addArgument('version', InputArgument::OPTIONAL, 'The version of WordPress to download');
98100
}
99101

100102
/**
101103
* @param InputInterface $input
102104
* @param OutputInterface $output
103105
* @return int|null|void
104106
*/
105-
public function execute( InputInterface $input, OutputInterface $output )
107+
public function execute(InputInterface $input, OutputInterface $output)
106108
{
107109
if (!class_exists('ZipArchive')) {
108110
throw new RuntimeException('The Zip PHP extension is not installed. Please install it and try again.');
109111
}
110112

111113
$this->verifyApplicationDoesNotExists(
112-
$directory = ( $input->getArgument('name') ) ? getcwd() . '/' . $input->getArgument('name') : getcwd()
114+
$directory = ($input->getArgument('name')) ? getcwd() . '/' . $input->getArgument('name') : getcwd()
113115
);
114-
115116
$this->setApp($input->getArgument('name'))->setVersion($input->getArgument('version'));
116117

117118
$this->createApplicationDirectory();
118119

119-
$output->writeln('<info>Downloading wordpress..</info> this might take a while');
120-
$zipFile = $this->download();
120+
$zipFile = $this->download($output);
121121

122-
$output->writeln('<info>Extracting package</info>');
122+
$output->writeln( '<info>Extracting package</info>');
123123
$this->extract($zipFile);
124124

125-
$output->writeln('<info>Generating wordpress theme & installing timber</info>');
125+
$output->writeln('<info>Generating WordPress theme & installing timber</info>');
126126
(new Theme($this->getApp(), $input, $output))->generate();
127127

128128
$output->writeln('<comment>All done! Build something amazing.</comment>');
@@ -131,52 +131,87 @@ public function execute( InputInterface $input, OutputInterface $output )
131131
/**
132132
* Download WordPress Zip package
133133
*
134+
* @param OutputInterface $output
134135
* @return string
135136
*/
136-
public function download()
137+
public function download($output)
137138
{
138139
$zipFilePath = $this->getZipFilePath();
139140

140141
if (file_exists($zipFilePath)) {
142+
$this->verifyZipIntegrity();
141143
return $zipFilePath;
142144
}
143145

144-
$file = (new Client(['verify' => false]))->get($this->getUrl());
145-
file_put_contents($zipFilePath, $file->getBody());
146+
$file = (new Client([
147+
'verify' => false,
148+
]));
149+
150+
$zipFileResource = fopen($zipFilePath, 'w');
151+
$downloadProgress = new ProgressBar($output);
152+
$downloadProgress->setFormatDefinition('custom', '<info>Downloading WordPress: %downloaded%%</info>');
153+
$downloadProgress->setFormat('custom');
154+
$downloadProgress->start();
155+
$file->request('GET', $this->getUrl(), [
156+
'sink' => $zipFileResource,
157+
'progress' => function (
158+
$downloadTotal,
159+
$downloadedBytes,
160+
$uploadTotal,
161+
$uploadedBytes
162+
) use ($downloadProgress) {
163+
$progressValue = 0;
164+
if ($downloadedBytes > 0) {
165+
$progressValue = ($downloadedBytes / $downloadTotal) * 100;
166+
}
167+
$downloadProgress->advance();
168+
$downloadProgress->setMessage(round($progressValue, 2), 'downloaded');
169+
},
170+
]);
171+
$output->writeln("");
146172
return $zipFilePath;
147173
}
148174

149175
/**
150176
* Get WordPress ZIP file URL
151177
*
152-
* @return string
178+
* @param null $checksum
179+
* @return mixed null|md5|sha1
153180
*/
154-
protected function getUrl()
181+
protected function getUrl($checksum = null)
155182
{
183+
$url = $this->baseUrl . '/latest.zip';
156184
if ($version = $this->getVersion()) {
157-
return $this->baseUrl . '/wordpress-' . $version . '.zip';
185+
$url = $this->baseUrl . '/wordpress-' . $version . '.zip';
158186
}
159187

160-
return $this->baseUrl . '/latest.zip';
188+
if ($checksum) {
189+
$url .= ".$checksum";
190+
}
191+
return $url;
161192
}
162193

163194
/**
164195
* @param $directory
196+
* @return bool
165197
*/
166-
protected function verifyApplicationDoesNotExists( $directory )
198+
protected function verifyApplicationDoesNotExists($directory)
167199
{
168-
if (( is_dir($directory) || is_file($directory) ) && $directory != getcwd()) {
200+
$isEmpty = (count(glob("$directory/*")) === 0) ? true : false;
201+
202+
if ((is_dir($directory) || is_file($directory)) && $directory != getcwd() && !$isEmpty) {
169203
throw new RuntimeException('Application already exists!');
170204
}
205+
return true;
171206
}
172207

173208
/**
174209
* @return string
175210
*/
176211
protected function getCacheDirectory()
177212
{
178-
return isset( $_SERVER[ 'HOME' ] ) ?
179-
$_SERVER[ 'HOME' ] . DIRECTORY_SEPARATOR . '.timber_installer' . DIRECTORY_SEPARATOR :
213+
return isset($_SERVER['HOME']) ?
214+
$_SERVER['HOME'] . DIRECTORY_SEPARATOR . '.timber_installer' . DIRECTORY_SEPARATOR :
180215
getcwd();
181216
}
182217

@@ -207,10 +242,10 @@ private function createCacheDirectory()
207242
/**
208243
* @param $file
209244
*/
210-
public function extract( $file )
245+
public function extract($file)
211246
{
212247
$projectPath = getcwd() . '/' . $this->getApp();
213-
$zip = new \ZipArchive();
248+
$zip = new \ZipArchive();
214249
$zip->open($file);
215250
$zip->extractTo($projectPath);
216251

@@ -225,7 +260,7 @@ public function extract( $file )
225260
* @return bool
226261
* @link http://stackoverflow.com/a/1653776/2641971
227262
*/
228-
public function delete( $directory )
263+
public function delete($directory)
229264
{
230265
if (!file_exists($directory)) {
231266
return true;
@@ -256,7 +291,7 @@ public function delete( $directory )
256291
* @param $destination
257292
* @link http://stackoverflow.com/a/27290570/2641971
258293
*/
259-
public function move( $source, $destination )
294+
public function move($source, $destination)
260295
{
261296
$this->fileSystem = new Filesystem();
262297

@@ -265,7 +300,7 @@ public function move( $source, $destination )
265300
}
266301

267302
$directoryIterator = new \RecursiveDirectoryIterator($source, \RecursiveDirectoryIterator::SKIP_DOTS);
268-
$iterator = new \RecursiveIteratorIterator($directoryIterator, \RecursiveIteratorIterator::SELF_FIRST);
303+
$iterator = new \RecursiveIteratorIterator($directoryIterator, \RecursiveIteratorIterator::SELF_FIRST);
269304
foreach ($iterator as $item) {
270305

271306
if ($item->isDir()) {
@@ -282,6 +317,25 @@ public function move( $source, $destination )
282317
*/
283318
protected function createApplicationDirectory()
284319
{
285-
mkdir(getcwd() . '/' . $this->getApp());
320+
$directory = getcwd() . '/' . $this->getApp();
321+
if (is_dir($directory) && !file_exists($directory)) {
322+
mkdir($directory);
323+
}
324+
}
325+
326+
/**
327+
* @param string $algorithm md5|sha1
328+
* @throws \Exception
329+
*/
330+
protected function verifyZipIntegrity($algorithm = 'md5')
331+
{
332+
$request = new Client();
333+
$response = $request->get($this->getUrl($algorithm));
334+
$remoteChecksum = $response->getBody();
335+
$localChecksum = md5_file($this->getZipFilePath());
336+
if ($algorithm == 'md5' && ($remoteChecksum != $localChecksum)) {
337+
unlink($this->getZipFilePath());
338+
throw new \Exception("Cannot verify integrity of {$this->getZipFilePath()}.\n We have deleted the file.\n Please try again.");
339+
}
286340
}
287341
}

0 commit comments

Comments
 (0)