Issues (4868)

doc/js2ts.php (2 issues)

1
#!/usr/bin/env php
2
<?php
3
/**
4
 * EGroupware - modify our old JS inheritance to TypeScript
5
 *
6
 * @link http://www.egroupware.org
7
 * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
8
 * @author Ralf Becker <[email protected]>
9
 * @copyright 2020 by Ralf Becker <[email protected]>
10
 */
11
12
if (PHP_SAPI !== 'cli')	// security precaution: forbit calling as web-page
13
{
14
	die('<h1>fix_api.php must NOT be called as web-page --> exiting !!!</h1>');
15
}
16
17
// raw replacements
18
$replace = array(
19
	'/^app.classes.([a-z0-9_]+)(\s*=\s*AppJS.extend)\(.*^}\);/misU' =>
20
		function($matches) {
21
			return strtr($matches[0], [
22
				'app.classes.'.$matches[1].$matches[2].'(' => 'class '.ucfirst($matches[1]).'App extends EgwApp',
23
				"\n});" => "\n}\n\napp.classes.$matches[1] = ".ucfirst($matches[1])."App;"
24
			]);
25
		},
26
	"/^\tappname:\s*'([^']+)',/m" => "\treadonly appname = '$1';",
27
	"/^\t([^: ,;(\t]+?):\s*([^()]+?),/m" => "\t\$1 : any = $2;",
28
	"/^\t([^:\n]+):\s*function\s*\(.*this._super.(apply|call)\(/msU" =>
29
		function($matches) {
30
	        return str_replace('this._super',
31
				$matches[1] === 'init' ? 'super' : 'super.'.$matches[1], $matches[0]);
32
	    },
33
	"/^\t([^:\n]+):\s*function\s*\(/m" => function($matches) {
34
		return "\t".($matches[1] === 'init' ? 'constructor' : $matches[1]).'(';
35
	},
36
    // TS does not like to call parent constructor with super.apply(this, arguments) and we dont have arguments ...
37
    '/\tsuper.apply\(this, *arguments\)/' => "\tsuper()",
38
	"/^\t},$/m" => "\t}",
39
	'/^ \* @version \$Id[^$]*\$\n/m' => '',
40
	'#^ \* @link http://www.egroupware.org#m' => ' * @link: https://www.egroupware.org',
41
);
42
43
/**
44
 * Add boilerplate for app.js files after header
45
 *
46
 * @param $app
47
 * @param $content
48
 * @return string
49
 */
50
function app_js_add($app, $content)
51
{
52
	return preg_replace('#^(/\*\*.*\n\ \*/)#Us', <<<EOF
53
$1
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $1 seems to be never defined.
Loading history...
54
55
/*egw:uses
56
	/api/js/jsapi/egw_app.js
57
 */
58
59
import 'jquery';
60
import 'jqueryui';
61
import '../jsapi/egw_global';
62
import '../etemplate/et2_types';
63
64
import { EgwApp } from '../../api/js/jsapi/egw_app';
65
EOF
66
		, $content);
67
}
68
69
/**
70
 * Convert JavaScript to TypeScript
71
 *
72
 * @param string $file filename
73
 * @param boolean $dry_run =false true: only echo fixed file, not fix it
74
 * @return boolean false on error
75
 */
76
function convert($file, $dry_run=false)
77
{
78
	global $prog, $replace;
79
	if (basename($file) == $prog) return true;	// dont fix ourself ;-)
80
81
	if (($content = $content_in = file_get_contents($file)) === false) return false;
82
83
	$replace_callbacks = array_filter($replace, 'is_callable');
84
	$replace_strings = array_filter($replace, 'is_string');
85
86
	$content = preg_replace(array_keys($replace_strings), array_values($replace_strings),
87
		preg_replace_callback_array($replace_callbacks, $content));
88
89
	// add app.js spezific boilerplate
90
	if (preg_match('#/([^/]+)/js/app(\.old)?\.js$#', realpath($file), $matches))
91
	{
92
		$content = app_js_add($matches[1], $content);
93
	}
94
95
	if ($content == $content_in) return true;	// nothing changed
96
97
	if ($dry_run)
98
	{
99
		echo $content;
100
	}
101
	else
102
	{
103
		$ret = file_put_contents($new_file=preg_replace('/\.js$/', '.ts', $file), $content) === false ? -1 : 0;
104
		//system('/usr/bin/php -l '.$file.'.new', $ret);
105
		system('/usr/bin/diff -u '.$file.' '.$new_file);
106
		return !$ret;
107
	}
108
109
	return true;
110
}
111
112
/**
113
 * Loop recursive through directory and call fix_api for each php file
114
 *
115
 * @param string $dir
116
 * @param boolean $dry_run =false true: only echo fixed file, not fix it
117
 * @return boolean false on error
118
 */
119
function convert_recursive($dir, $dry_run=false)
120
{
121
	if (!is_dir($dir)) return false;
122
123
	foreach(scandir($dir) as $file)
124
	{
125
		if ($file == '.' || $file == '..') continue;
126
127
		if (is_dir($dir.'/'.$file))
128
		{
129
			convert_recursive($dir.'/'.$file, $dry_run);
130
		}
131
		elseif(substr($file,-3) == '.js')
132
		{
133
			echo "\r".str_repeat(' ',100)."\r".$dir.'/'.$file.': ';
134
			convert($dir.'/'.$file, $dry_run);
135
		}
136
	}
137
	echo "\r".str_repeat(' ',100)."\r";
138
	return true;
139
}
140
141
/**
142
 * Give usage
143
 *
144
 * @param string $error =null
145
 */
146
function usage($error=null)
147
{
148
	global $prog;
149
	echo "Usage: $prog [-h|--help] [-d|--dry-run] file(s) or dir(s)\n\n";
150
	if ($error) echo $error."\n\n";
151
	exit($error ? 1 : 0);
0 ignored issues
show
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
152
}
153
154
$args = $_SERVER['argv'];
155
$prog = basename(array_shift($args));
156
157
if (!$args) usage();
158
159
$dry_run = false;
160
while(($arg = array_shift($args)) && $arg[0] == '-')
161
{
162
	switch($arg)
163
	{
164
		case '-h':
165
		case '--help':
166
			usage();
167
			break;
168
169
		case '-d':
170
		case '--dry-run':
171
			$dry_run = true;
172
			break;
173
174
		default:
175
			if ($args)	// not last argument
176
			{
177
				usage("Unknown argument '$arg'!");
178
			}
179
			break 2;
180
	}
181
}
182
183
do {
184
	if (!file_exists($arg)) usage("Error: $arg not found!");
185
186
	if (!is_dir($arg))
187
	{
188
		convert($arg, $dry_run);
189
	}
190
	else
191
	{
192
		convert_recursive($arg, $dry_run);
193
	}
194
}
195
while(($arg = array_shift($args)));
196