Skip to content
This repository was archived by the owner on Mar 8, 2023. It is now read-only.

Commit 7c69725

Browse files
committed
Merge branch 'release/1.0.1'
2 parents 28f3eac + a1c1798 commit 7c69725

File tree

90 files changed

+772
-662
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

90 files changed

+772
-662
lines changed

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
11
build/
22
dist/
3-
src/config.xml

CHANGELOG.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
# Release Notes
22

3-
## v1.0.0 (2019-08-30)
3+
## Unreleased
4+
5+
## v1.0.1 (2019-08-30)
6+
### Changed
7+
- Improved build stability
8+
9+
## v1.0.0 (2019-08-29)
410
### Added
5-
- Build script and [readme](README.md) with instructions
6-
- [Changelog](CHANGELOG.md)
11+
- Build script and [README](README.md) with instructions
12+
- [CHANGELOG](CHANGELOG.md)
713
### Changed
814
- Moved renamed source to `src`
915

README.md

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,24 @@
77

88
## Build
99

10-
- Clone or download the source from this repository.
11-
12-
- Update `src/logo.png`, `src/logo.gif` and images in `src/views/img/creditcard`.
13-
14-
- Run the build script to automatically change white labeled source and create a zip file ready for distribution.
15-
16-
$ php build.php "My Payment Provider" gateway.mypaymentprovider.com
17-
10+
* Clone or download the source from this repository.
11+
* Update [src/logo.png](src/logo.png), [src/logo.gif](src/logo.gif) and images in [src/views/img/creditcard](src/views/img/creditcard).
12+
* Run the build script to apply desired branding and create a zip file ready for distribution:
13+
```shell script
14+
php build.php gateway.mypaymentprovider.com "My Payment Provider"
15+
```
1816
- Verify the contents of `build` to make sure they meet desired results.
19-
20-
- Test by installing the built extension zip file in an existing shop installation.
21-
17+
- Find the newly versioned zip file in the `dist` folder.
18+
- Test by installing the extension in an existing shop installation (see [src/README](src/README.md)).
2219
- Distribute the versioned zip file.
2320

2421
## Provide Updates
2522

26-
- Fetch the updated source from this repository (see [Changelog](CHANGELOG.md)).<br>Note: make sure to not overwrite any previous changes you've made for the previous version, or re-apply these changes.
27-
28-
- Run the build script with the same parameters as the first time.
29-
30-
- Distribute the newly versioned zip file.
23+
- Fetch the updated source from this repository (see [CHANGELOG](CHANGELOG.md)).<br>Note: make sure to not overwrite any previous changes you've made for the previous version, or re-apply these changes.
24+
- Run the build script with the same parameters as the first time:
25+
```shell script
26+
php build.php gateway.mypaymentprovider.com "My Payment Provider"
27+
```
28+
- Find the newly versioned zip file in the `dist` folder.
29+
- Test by updating the extension in an existing shop installation (see [src/README](src/README.md)).
30+
- Distribute the newly versioned zip file.

build.php

Lines changed: 146 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,35 @@
11
<?php
2+
/**
3+
* extension source version
4+
*/
25
$version = '1.0.0';
3-
$placeholderName = 'Payment Gateway';
4-
$name = $argv[1] ?? null;
5-
$domain = $argv[2] ?? null;
6+
7+
/**
8+
* dist filename
9+
*/
10+
$distFilenamePrefix = 'prestashop-';
11+
$distFilenameSuffix = '';
12+
13+
/**
14+
* path within zip file
15+
* set to false to have source at the root of the zip file
16+
* a requirement in some systems to make the zip file installable
17+
* others require it to be lowercase without special characters
18+
*/
19+
// $distFilenameRootDirName = false;
20+
21+
/**
22+
* Dragons below
23+
* Do not change
24+
*/
25+
26+
/**
27+
* build config
28+
*/
29+
$placeholderName = 'Payment Gateway Cloud';
30+
$hostname = $argv[1] ?? null;
31+
$name = $argv[2] ?? null;
32+
$debug = strpos(implode(' ', $argv), ' --debug') !== false;
633
$srcDir = 'src';
734
$buildDir = 'build';
835
$distDir = 'dist';
@@ -13,7 +40,7 @@
1340
/**
1441
* check workspace
1542
*/
16-
if (!file_exists($srcDir)) {
43+
if (!realpath($srcDir)) {
1744
line();
1845
error('Source directory does not exist');
1946
exit;
@@ -32,72 +59,81 @@
3259
/**
3360
* validate domain input
3461
*/
35-
$domain = filter_var($domain, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME);
36-
if (empty($domain)) {
62+
$hostname = filter_var($hostname, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME);
63+
if (empty($hostname)) {
3764
line();
38-
error('Domain must not be empty');
65+
error('Host name must be valid');
3966
usage();
4067
exit;
4168
}
4269

70+
/**
71+
* the zip file's name without extension
72+
*/
73+
$distFilename = $distFilenamePrefix . kebabCase($name) . '-' . $version . $distFilenameSuffix;
74+
line(' '.$distFilename);
75+
76+
/**
77+
* relative path within zip file
78+
*/
79+
$distFilenameRootDirName = ($distFilenameRootDirName ?? true) === false ? '' : identifierCase($name);
80+
4381
/**
4482
* create replacement map
4583
*/
46-
$composerHashPrefix = md5(identifierCase($name) . '-' . $version);
4784
$replacementMap = [
48-
// "Payment Gateway" -> "My Provider"
85+
// X.Y.Z -> 1.1.0
86+
'X.Y.Z' => $version,
87+
// "gateway.paymentgateway.cloud" -> "gateway.myprovider.com" (client xml namespace and endpoints)
88+
'gateway.paymentgateway.cloud' => $hostname,
89+
// "Payment Gateway Cloud" -> "My Provider"
4990
$placeholderName => $name,
50-
// "PaymentGateway" -> "MyProvider" (namespaces and other identifiers)
91+
// "PaymentGatewayCloud" -> "MyProvider" (namespaces and other identifiers)
5192
pascalCase($placeholderName) => pascalCase($name),
52-
// "paymentGateway" -> "myProvider"
93+
// "paymentGatewayCloud" -> "myProvider"
5394
camelCase($placeholderName) => camelCase($name),
54-
// "paymentgateway" -> "myprovider"
95+
// "paymentgatewaycloud" -> "myprovider"
5596
identifierCase($placeholderName) => identifierCase($name),
56-
// "payment-gateway" -> "my-provider"
97+
// "payment-gateway-cloud" -> "my-provider"
5798
kebabCase($placeholderName) => kebabCase($name),
58-
// "payment_gateway" -> "my_provider"
99+
// "payment_gateway_cloud" -> "my_provider"
59100
snakeCase($placeholderName) => snakeCase($name),
60-
// "PAYMENT_GATEWAY -> "MY_PROVIDER" (constants)
101+
// "PAYMENT_GATEWAY_CLOUD" -> "MY_PROVIDER" (constants)
61102
constantCase($placeholderName) => constantCase($name),
62-
// "gateway.paymentgateway.cloud" -> "gateway.myprovider.com" (client xml namespace and endpoints)
63-
'gateway.paymentgateway.cloud' => $domain,
64-
// X.Y.Z -> 1.1.0
65-
'X.Y.Z' => $version,
66-
/**
67-
* Prefix composer autoloader names with a unique hash.
68-
* This prevents conflicts in case two whitelabel plugins, which were both
69-
* built from the same version of the source, are installed at the same time.
70-
*/
71-
'ComposerStaticInit' => 'ComposerStaticInit' . $composerHashPrefix,
72-
'ComposerAutoloaderInit' => 'ComposerAutoloaderInit' . $composerHashPrefix,
73103
];
74104

75105
/**
76106
* print replacement map and prompt user if planned changes are ok
77107
*/
78108
line();
109+
info('Replacements for file/folder names and contents:');
79110
foreach ($replacementMap as $old => $new) {
80111
line(' ' . $old . ' => ' . $new);
81112
}
82113
line();
83-
prompt('OK?');
114+
prompt('This will clear any existing "' . $buildDir . '" folder and start the build. OK?');
84115

85116
/**
86-
* clear existing build folder
117+
* Prefix composer autoloader names with a unique hash.
118+
* This prevents conflicts in case two whitelabel plugins, which were both
119+
* built from the same version of the source, are installed at the same time.
87120
*/
88-
if (file_exists($buildDir)) {
89-
deleteDir($buildDir);
90-
info('Cleared build directory');
91-
}
121+
$composerHashPrefix = md5(identifierCase($name) . '-' . $version);
122+
$replacementMap = array_merge($replacementMap, [
123+
'ComposerStaticInit' => 'ComposerStaticInit' . $composerHashPrefix,
124+
'ComposerAutoloaderInit' => 'ComposerAutoloaderInit' . $composerHashPrefix,
125+
]);
92126

93127
/**
94128
* build
95-
* copy source to build folder, clear existing if applicable
129+
* clear existing build folder
130+
* copy source to build folder
96131
* applies replacement map to folder names, file names and file contents while at it
97132
*/
133+
deleteDir($buildDir);
98134
info('Building...');
99135
build($srcDir, $buildDir, $replacementMap);
100-
success('Done');
136+
success('Build complete');
101137

102138
/**
103139
* create dist folder if needed
@@ -111,8 +147,7 @@
111147
* zip build to myprovider.zip
112148
*/
113149
info('Creating zip file...');
114-
zipBuildToDist($buildDir, $distDir, identifierCase($name) . '-' . $version, identifierCase($name));
115-
success('Done');
150+
zipBuildToDist($buildDir, $distDir, $distFilename, $distFilenameRootDirName);
116151

117152
exit;
118153

@@ -125,8 +160,8 @@
125160
*/
126161
function usage()
127162
{
128-
warn('Usage: php build.php [name] [domain]');
129-
line('Example: php build.php "My Payment Provider" gateway.mypaymentprovider.com');
163+
warn('Usage: php build.php [hostname] [name]');
164+
line('Example: php build.php gateway.mypaymentprovider.com "My Payment Provider"');
130165
line();
131166
}
132167

@@ -237,7 +272,10 @@ function highlight($message)
237272
*/
238273
function debug($message)
239274
{
240-
echo "[SUCCESS] " . $message . "\n";
275+
global $debug;
276+
if ($debug) {
277+
echo "\e[1;33m[DEBUG] " . $message . "\e[0m\n";
278+
}
241279
}
242280

243281
/**
@@ -262,6 +300,8 @@ function prompt($message)
262300
*/
263301
function build($src, $dst, $replacementMap = [])
264302
{
303+
debug('Scan "' . $src . '"');
304+
265305
$dir = opendir($src);
266306
@mkdir($dst);
267307
while (false !== ($file = readdir($dir))) {
@@ -271,7 +311,9 @@ function build($src, $dst, $replacementMap = [])
271311
if (is_dir($srcFile)) {
272312
build($srcFile, $destFile, $replacementMap);
273313
} else {
314+
debug('Copy "' . $destFile . '" -> "' . $destFile . '"');
274315
copy($srcFile, $destFile);
316+
debug('Process "' . $destFile . '"');
275317
replaceContents($destFile, $replacementMap);
276318
}
277319
}
@@ -306,11 +348,33 @@ function applyReplacements($string, $replacementMap)
306348
*/
307349
function deleteDir($dir)
308350
{
309-
if (empty($dir)) {
351+
$dir = sanitizeDirInput($dir);
352+
353+
$dirPath = realpath(__DIR__ . '/' . $dir);
354+
355+
if (!$dirPath) {
310356
return;
311357
}
312-
$dir = './' . $dir;
313-
$it = new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS);
358+
359+
/**
360+
* do not allow to delete this script's parent directory
361+
*/
362+
if ($dirPath == __DIR__) {
363+
error('Deleting directory "' . $dir . '" is not allowed');
364+
exit;
365+
}
366+
367+
/**
368+
* do not allow to delete any path that is not within this script's parent directory
369+
*/
370+
if (strpos($dirPath, __DIR__) !== 0) {
371+
error('Deleting directory "' . $dir . '" is not allowed');
372+
exit;
373+
}
374+
375+
warn('Deleting ' . $dirPath);
376+
377+
$it = new RecursiveDirectoryIterator($dirPath, RecursiveDirectoryIterator::SKIP_DOTS);
314378
$files = new RecursiveIteratorIterator($it,
315379
RecursiveIteratorIterator::CHILD_FIRST);
316380
foreach ($files as $file) {
@@ -320,42 +384,64 @@ function deleteDir($dir)
320384
unlink($file->getRealPath());
321385
}
322386
}
323-
rmdir($dir);
387+
rmdir($dirPath);
324388
}
325389

326390
/**
327-
* @param string $dir
328-
* @param string $destFile
391+
* @param string $srcDir
392+
* @param string $destDir
393+
* @param string $filename
394+
* @param string $rootDirectoryName the root directory's name within the zip file
329395
*/
330-
function zipBuildToDist($srcDir, $destDir, $filename, $directoryName)
396+
function zipBuildToDist($srcDir, $destDir, $filename, $rootDirectoryName)
331397
{
332-
// Get real path for our folder
333-
$rootPath = realpath($srcDir);
398+
$srcDir = sanitizeDirInput($srcDir);
399+
$destDir = sanitizeDirInput($destDir);
400+
401+
$srcDirPath = realpath($srcDir);
402+
$destDirPath = realpath($destDir);
403+
404+
$zipFilename = $filename . '.zip';
334405

335-
// Initialize archive object
336406
$zip = new ZipArchive();
337-
$zip->open($destDir . '/' . $filename . '.zip', ZipArchive::CREATE | ZipArchive::OVERWRITE);
407+
$zip->open($destDirPath . '/' . $zipFilename, ZipArchive::CREATE | ZipArchive::OVERWRITE);
338408

339-
// Create recursive directory iterator
340409
/** @var SplFileInfo[] $files */
341410
$files = new RecursiveIteratorIterator(
342-
new RecursiveDirectoryIterator($rootPath),
411+
new RecursiveDirectoryIterator($srcDirPath),
343412
RecursiveIteratorIterator::LEAVES_ONLY
344413
);
345-
foreach ($files as $name => $file) {
346414

347-
// Skip directories (they would be added automatically)
415+
foreach ($files as $name => $file) {
416+
/**
417+
* Skip directories (they would be added automatically)
418+
*/
348419
if (!$file->isDir()) {
349-
350-
// Get real and relative path for current file
420+
/**
421+
* Get real and relative path for current file
422+
*/
351423
$filePath = $file->getRealPath();
352-
$relativePath = $directoryName . '/' . substr($filePath, strlen($rootPath) + 1);
424+
$relativePath = substr($filePath, strlen($srcDirPath) + 1);
353425

354-
// Add current file to archive
355-
$zip->addFile($filePath, $relativePath);
426+
$zip->addFile($filePath, $rootDirectoryName . '/' . $relativePath);
356427
}
357428
}
358429

359-
// Zip archive will be created only after closing object
430+
/**
431+
* Zip archive will be created after closing object
432+
*/
360433
$zip->close();
434+
435+
success('Created file "' . $destDir . '/' . $zipFilename . '"');
436+
}
437+
438+
/**
439+
* do not allow to reference a directory outside of this script's path
440+
*
441+
* @param string $dir
442+
* @return string
443+
*/
444+
function sanitizeDirInput($dir)
445+
{
446+
return ltrim(str_replace('../', '', $dir), '/');
361447
}

src/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
composer.lock
2+
config.xml

0 commit comments

Comments
 (0)