modsadm.php 10.8 KB
Newer Older
1 2
#!/usr/bin/php
<?php
changi67's avatar
changi67 committed
3 4 5
/**
 * @package tikiwiki
 */
6
// (c) Copyright 2002-2016 by authors of the Tiki Wiki CMS Groupware Project
rjsmelo's avatar
rjsmelo committed
7
//
changi67's avatar
changi67 committed
8 9 10
// All Rights Reserved. See copyright.txt for details and a complete list of authors.
// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
// $Id$
11

rjsmelo's avatar
rjsmelo committed
12 13 14 15 16 17
if (! defined('STDOUT') || ! defined('STDIN') || ! defined('STDERR')) {
	 die("<p>shell only</p>");
}
if (isset($_SERVER['REQUEST_METHOD'])) {
	die;
}
18 19

// Initialization
rjsmelo's avatar
rjsmelo committed
20
require_once('tiki-setup.php');
21 22
include('lib/mods/modslib.php');

rjsmelo's avatar
rjsmelo committed
23 24 25 26 27 28
$repos = ['installed' => ['url' => $prefs['mods_dir'] . '/Installed/00_list.txt',
				  'content' => $installed],
		 'local' => ['url' => $prefs['mods_dir'] . '/Packages/00_list.txt',
				  'content' => $local],
		 'remote' => ['url' => $prefs['mods_dir'] . '/Packages/00_list.' . urlencode($mods_server) . '.txt',
				   'content' => $remote]];
29

rjsmelo's avatar
rjsmelo committed
30
$goptions = [];
31

rjsmelo's avatar
rjsmelo committed
32
$commands = ['help' => [],
33 34 35 36 37
// 		'update' => array(),
// 		'clean' => array(),
// 		'add-source' => array(),
// 		'remove-source' => array(),
// 		'list-sources' => array(),
rjsmelo's avatar
rjsmelo committed
38 39 40 41 42 43 44
		'list' => ['usage' => '[options] [regex]',
				'options' => ['-l' => ['help' => 'Do not query for remote mods'],
						   '-i' => ['help' => 'Show only installed mods']]],
		'show' => ['usage' => 'mod1 [mod2...]'],
		'install' => ['usage' => '[options] mod1 [mod2...]',
				   'options' => ['-d' => ['help' => "Download only mods, don't install them"]]],
		'remove' => ['usage' => 'mod1 [mod2...]'],
niclone's avatar
niclone committed
45
// 		'publish' => array('usage' => 'mod1 [mod2...]'),
46 47
// 		'unpublish' => array(),
// 		'republish' => array(),
rjsmelo's avatar
rjsmelo committed
48
		];
49

50 51 52 53
/**
 * @param $num
 * @param $err
 */
54 55
function tikimods_feedback_listener($num, $err)
{
rjsmelo's avatar
rjsmelo committed
56 57 58 59 60 61 62 63 64 65
	switch ($num) {
		case -1:
			echo $err . "\n";
			break;
		case 0:
			echo "! " . $err . "\n";
			break;
		case 1:
			echo "*** " . $err . "\n";
			break;
66 67 68 69
	}
}
$modslib->add_feedback_listener('tikimods_feedback_listener');

70 71 72 73
/**
 * @param $str
 * @return string
 */
74 75
function ask($str)
{
76
	echo $str;
rjsmelo's avatar
rjsmelo committed
77
	$res = fgets(STDIN, 1024);
78 79 80
	return trim($res);
}

81 82 83 84 85
/**
 * @param $goption
 * @param $coption
 * @param $cparams
 */
86 87
function command_help($goption, $coption, $cparams)
{
88 89 90
	usage(0);
}

91 92 93 94 95
/**
 * @param $goption
 * @param $coption
 * @param $cparams
 */
96 97
function command_install($goption, $coption, $cparams)
{
98
	global $modslib;
99
	global $prefs;
100 101
	global $mods_server;

rjsmelo's avatar
rjsmelo committed
102
	$deps = $modslib->find_deps($prefs['mods_dir'], $mods_server, $cparams);
103 104

	if (count($deps['unavailable'])) {
rjsmelo's avatar
rjsmelo committed
105
		$err = "Sorry, theses packages are required but not available:\n";
106
		foreach ($deps['unavailable'] as $mod) {
rjsmelo's avatar
rjsmelo committed
107
			$err .= " - " . $mod->modname . "\n";
108 109 110
		}
		failure($err);
	}
111
	if (count($deps['conflicts'])) {
rjsmelo's avatar
rjsmelo committed
112
		$err = "Sorry, theses packages are required but conflicts:\n";
113
		foreach ($deps['conflicts'] as $mod) {
rjsmelo's avatar
rjsmelo committed
114
			$err .= " - " . $mod->modname . "\n";
115 116 117
		}
		failure($err);
	}
118
	if (count($deps['wanted'])) {
119
		echo "You asked to install these mods:\n";
120
		foreach ($deps['wanted'] as $mod) {
rjsmelo's avatar
rjsmelo committed
121
			echo "  " . $mod->modname . "\n";
122 123
		}
	}
124
	if (count($deps['toinstall'])) {
125
		echo "The following packages will be installed:\n";
126
		foreach ($deps['toinstall'] as $mod) {
rjsmelo's avatar
rjsmelo committed
127
			echo "  " . $mod->modname . " (" . $mod->revision . ")\n";
128 129 130 131 132
		}
	}
	if (count($deps['toupgrade'])) {
		echo "The following packages will be upgraded:\n";
		foreach ($deps['toupgrade'] as $meat) {
rjsmelo's avatar
rjsmelo committed
133
			echo "  " . $meat['to']->modname . " (" . $meat['to']->revision . ") (from version " . $meat['from']->revision . ")\n";
134 135 136 137 138
		}
	}
	if (count($deps['suggests'])) {
		echo "Suggested packages:\n";
		foreach ($deps['suggests'] as $mod) {
rjsmelo's avatar
rjsmelo committed
139
			echo "  " . $mod->modname . "\n";
140 141 142
		}
	}

rjsmelo's avatar
rjsmelo committed
143
	$res = ask("Would you like to continue (y/N) ? ");
144 145 146 147 148
	if ($res != 'y') {
		echo "Good bye\n";
		exit(0);
	}

149
	$modslib->install_with_deps($prefs['mods_dir'], $mods_server, $deps);
150 151
}

152 153 154 155 156
/**
 * @param $goption
 * @param $coption
 * @param $cparams
 */
157 158
function command_remove($goption, $coption, $cparams)
{
159
	global $modslib;
160
	global $prefs;
161 162
	global $mods_server;

rjsmelo's avatar
rjsmelo committed
163
	$deps = $modslib->find_deps_remove($prefs['mods_dir'], $mods_server, $cparams);
164 165

	if (count($deps['wantedtoremove'])) {
166
		echo "You asked to remove these mods:\n";
167
		foreach ($deps['wantedtoremove'] as $mod) {
rjsmelo's avatar
rjsmelo committed
168
			echo "  " . $mod->modname . " (" . $mod->revision . ")\n";
169 170 171
		}
	}
	if (count($deps['toremove'])) {
172
		echo "The following packages will be REMOVED:\n";
173
		foreach ($deps['toremove'] as $mod) {
rjsmelo's avatar
rjsmelo committed
174
			echo "  " . $mod->modname . " (" . $mod->revision . ")\n";
175 176 177
		}
	}

rjsmelo's avatar
rjsmelo committed
178
	$res = ask("Would you like to continue (y/N) ? ");
179 180 181 182 183
	if ($res != 'y') {
		echo "Good bye\n";
		exit(0);
	}

rjsmelo's avatar
rjsmelo committed
184
	$res = null;
185

rjsmelo's avatar
rjsmelo committed
186
	$modslib->remove_with_deps($prefs['mods_dir'], $mods_server, $deps);
187 188
}

189 190 191 192 193
/**
 * @param $goption
 * @param $coption
 * @param $cparams
 */
194 195
function command_list($goption, $coption, $cparams)
{
196 197
	global $repos;
	global $modslib;
rjsmelo's avatar
rjsmelo committed
198
	$merged = [];
199

200
	if (count($cparams)) {
rjsmelo's avatar
rjsmelo committed
201 202 203 204
		$regex = $cparams[0];
	} else {
		$regex = '';
	}
205

206
	foreach ($repos as $reponame => $repo) {
rjsmelo's avatar
rjsmelo committed
207 208 209 210 211 212 213
		if ($reponame == 'remote' && in_array('-l', $coption)) {
			continue;
		}
		if ($reponame != 'installed' && in_array('-i', $coption)) {
			continue;
		}
		$content = $modslib->read_list($repo['url'], $reponame);
214 215
		foreach ($content as $meat) {
			foreach ($meat as $mod) {
rjsmelo's avatar
rjsmelo committed
216
				if (($regex !== '') && ! preg_match('/' . $regex . '/', $mod->modname)) {
217
					continue;
rjsmelo's avatar
rjsmelo committed
218 219
				}
				$merged[$mod->type][$mod->name][$reponame] = $mod;
220 221 222 223
			}
		}
	}

224

225
	foreach ($merged as $k => $meat) {
226
		ksort($merged[$k]);
227
	}
228
	ksort($merged);
229
	foreach ($merged as $type => $meat) {
rjsmelo's avatar
rjsmelo committed
230
		echo $type . ":\n";
231
		foreach ($meat as $name => $submeat) {
232 233 234 235 236 237 238
			$rev_installed = isset($submeat['installed']) ? $submeat['installed']->revision : '';
			$rev_remote    = isset($submeat['remote']) ? $submeat['remote']->revision : '';
			printf("  %-24.24s | %7.7s | %7.7s\n", $name, $rev_installed, $rev_remote);
		}
	}
}

239 240 241 242 243
/**
 * @param $goption
 * @param $coption
 * @param $cparams
 */
244 245
function command_show($goption, $coption, $cparams)
{
246 247 248
	global $repos;
	global $modslib;

249
	foreach ($cparams as $cparam) {
rjsmelo's avatar
rjsmelo committed
250 251
		$found = null;
		$mod = new TikiMod($cparam);
252
		foreach ($repos as $reponame => $repo) {
rjsmelo's avatar
rjsmelo committed
253
			$content = $modslib->read_list($repo['url'], $reponame);
254
			if (isset($content[$mod->type][$mod->name])) {
rjsmelo's avatar
rjsmelo committed
255
				$found = $content[$mod->type][$mod->name];
256 257 258
				break;
			}
		}
rjsmelo's avatar
rjsmelo committed
259 260 261

		if ($found === null) {
			echo "mod '" . $mod->modname . "' not found\n";
262
			continue;
rjsmelo's avatar
rjsmelo committed
263 264 265 266 267 268 269 270 271 272 273 274
		} else {
			$mod = $found;
		}

		if ($mod->repository !== null) {
			echo "Repository:\n" . $mod->repository . "\n\n";
		}
		echo "modname;\n" . $mod->modname . "\n\n";
		echo "Type:\n" . $mod->type . "\n\n";
		echo "Name:\n" . $mod->name . "\n\n";
		echo "Revision:\n" . $mod->revision . "\n\n";

275 276
		if (is_array($mod->author) && count($mod->author)) {
			echo "Author:\n";
277
			foreach ($mod->author as $author) {
rjsmelo's avatar
rjsmelo committed
278
				echo $author . "\n";
279 280 281
			}
			echo "\n";
		}
rjsmelo's avatar
rjsmelo committed
282

283 284
		if (is_array($mod->description) && count($mod->description)) {
			echo "Description:\n";
285
			foreach ($mod->description as $description) {
rjsmelo's avatar
rjsmelo committed
286
				echo $description . "\n";
287 288 289
			}
			echo "\n";
		}
rjsmelo's avatar
rjsmelo committed
290 291 292 293 294

		if ($mod->license !== null) {
			echo "License:\n" . $mod->license . "\n\n";
		}

295 296
		if (is_array($mod->version) && count($mod->version)) {
			echo "Version:\n";
297
			foreach ($mod->version as $version) {
rjsmelo's avatar
rjsmelo committed
298
				echo $version . "\n";
299 300 301
			}
			echo "\n";
		}
rjsmelo's avatar
rjsmelo committed
302 303 304 305 306 307 308 309 310

		if ($mod->md5 !== null) {
			echo "md5:\n" . $mod->md5 . "\n\n";
		}

		if ($mod->lastmodif !== null) {
			echo "lastmodif:\n" . $mod->lastmodif . "\n\n";
		}

311 312
		if (is_array($mod->configuration) && count($mod->configuration)) {
			echo "Configuration:\n";
313
			foreach ($mod->configuration as $configuration) {
rjsmelo's avatar
rjsmelo committed
314
				echo $configuration . "\n";
315 316 317
			}
			echo "\n";
		}
rjsmelo's avatar
rjsmelo committed
318

319 320
		if (is_array($mod->configuration_help) && count($mod->configuration_help)) {
			echo "Configuration Help:\n";
321
			foreach ($mod->configuration_help as $configuration_help) {
rjsmelo's avatar
rjsmelo committed
322
				echo $configuration_help . "\n";
323 324 325
			}
			echo "\n";
		}
rjsmelo's avatar
rjsmelo committed
326

327 328
		if (is_array($mod->files) && count($mod->files)) {
			echo "Files:\n";
329
			foreach ($mod->files as $files) {
rjsmelo's avatar
rjsmelo committed
330
				echo $files . "\n";
331 332 333
			}
			echo "\n";
		}
rjsmelo's avatar
rjsmelo committed
334

335 336
		if (is_array($mod->contributor) && count($mod->contributor)) {
			echo "Contributor:\n";
337
			foreach ($mod->contributor as $contributor) {
rjsmelo's avatar
rjsmelo committed
338
				echo $contributor . "\n";
339 340 341
			}
			echo "\n";
		}
rjsmelo's avatar
rjsmelo committed
342

343 344
		if (is_array($mod->devurl) && count($mod->devurl)) {
			echo "devurl:\n";
345
			foreach ($mod->devurl as $devurl) {
rjsmelo's avatar
rjsmelo committed
346
				echo $devurl . "\n";
347 348 349
			}
			echo "\n";
		}
rjsmelo's avatar
rjsmelo committed
350

351 352
		if (is_array($mod->docurl) && count($mod->docurl)) {
			echo "docurl:\n";
353
			foreach ($mod->docurl as $docurl) {
rjsmelo's avatar
rjsmelo committed
354
				echo $docurl . "\n";
355 356 357
			}
			echo "\n";
		}
rjsmelo's avatar
rjsmelo committed
358

359 360
		if (is_array($mod->help) && count($mod->help)) {
			echo "Help:\n";
361
			foreach ($mod->help as $help) {
rjsmelo's avatar
rjsmelo committed
362
				echo $help . "\n";
363 364 365
			}
			echo "\n";
		}
rjsmelo's avatar
rjsmelo committed
366

367 368
		if (is_array($mod->url) && count($mod->url)) {
			echo "url:\n";
369
			foreach ($mod->url as $url) {
rjsmelo's avatar
rjsmelo committed
370
				echo $url . "\n";
371 372 373
			}
			echo "\n";
		}
rjsmelo's avatar
rjsmelo committed
374

375 376
		if (is_array($mod->sql_upgrade) && count($mod->sql_upgrade)) {
			echo "sql_Upgrade:\n";
377
			foreach ($mod->sql_upgrade as $sql_upgrade) {
rjsmelo's avatar
rjsmelo committed
378
				echo $sql_upgrade . "\n";
379 380 381
			}
			echo "\n";
		}
rjsmelo's avatar
rjsmelo committed
382

383 384
		if (is_array($mod->sql_install) && count($mod->sql_install)) {
			echo "sql_Install:\n";
385
			foreach ($mod->sql_install as $sql_install) {
rjsmelo's avatar
rjsmelo committed
386
				echo $sql_install . "\n";
387 388 389
			}
			echo "\n";
		}
rjsmelo's avatar
rjsmelo committed
390

391 392
		if (is_array($mod->sql_remove) && count($mod->sql_remove)) {
			echo "sql_Remove:\n";
393
			foreach ($mod->sql_remove as $sql_remove) {
rjsmelo's avatar
rjsmelo committed
394
				echo $sql_remove . "\n";
395 396 397 398 399 400
			}
			echo "\n";
		}
	}
}

401 402 403
/**
 * @param $errstr
 */
404 405
function failure($errstr)
{
406 407 408 409
	fprintf(STDERR, "%s\n", $errstr);
	exit(1);
}

410 411 412
/**
 * @param $err
 */
413 414
function usage($err)
{
415 416 417 418 419 420
	global $goptions;
	global $commands;

	echo "usage:\n";
	echo "php modsadm.php [options] commande\n\n";
	echo "commands:\n";
421
	foreach ($commands as $command => $sglonk) {
rjsmelo's avatar
rjsmelo committed
422
		echo "  " . $command . (isset($sglonk['usage']) ? ' ' . $sglonk['usage'] : '') . "\n";
423 424
	}
	echo "\ncommands options:\n";
425
	foreach ($commands as $command => $sglonk) {
426
		if (isset($sglonk['options'])) {
rjsmelo's avatar
rjsmelo committed
427
			echo "  " . $command . ":\n";
428
			foreach ($sglonk['options'] as $k => $option) {
rjsmelo's avatar
rjsmelo committed
429
				echo "    $k: " . $option['help'] . "\n";
430 431 432 433 434 435 436
			}
		}
	}

	exit($err);
}

437 438 439
/**
 * @param $argv
 */
440 441
function readargs($argv)
{
442 443 444
	global $goptions;
	global $commands;

rjsmelo's avatar
rjsmelo committed
445 446 447 448
	$command = null;
	$goption = [];
	$coption = [];
	$cparams = [];
449
	foreach ($argv as $argc => $arg) {
rjsmelo's avatar
rjsmelo committed
450 451 452
		if ($argc == 0) {
			continue;
		}
453 454

		if (substr($arg, 0, 1) == '-') {
rjsmelo's avatar
rjsmelo committed
455
			if ($command === null) {
456
				// global option
rjsmelo's avatar
rjsmelo committed
457
				if (! isset($goptions[$arg])) {
458 459
					usage(1);
				} else {
rjsmelo's avatar
rjsmelo committed
460
					$goption[] = $arg;
461 462 463
				}
			} else {
				// command option
rjsmelo's avatar
rjsmelo committed
464 465
				if (! isset($commands[$command]['options'])
					|| ! isset($commands[$command]['options'][$arg])) {
466 467
					usage(1);
				} else {
rjsmelo's avatar
rjsmelo committed
468
					$coption[] = $arg;
469 470 471
				}
			}
		} else {
rjsmelo's avatar
rjsmelo committed
472
			if ($command === null) {
473
				// this is the command
rjsmelo's avatar
rjsmelo committed
474
				if (! isset($commands[$arg])) {
475 476
					usage(1);
				} else {
rjsmelo's avatar
rjsmelo committed
477
					$command = $arg;
478 479 480
				}
			} else {
				// command parameter
rjsmelo's avatar
rjsmelo committed
481
				$cparams[] = $arg;
482 483 484 485
			}
		}
	}

rjsmelo's avatar
rjsmelo committed
486
	if ($command === null) {
487 488
		usage(1);
	} else {
rjsmelo's avatar
rjsmelo committed
489
		$func = 'command_' . $command;
490 491 492 493
		$func($goption, $coption, $cparams);
	}
}
readargs($argv);