| [ Index ] |
|
Code source de PHP PEAR 1.4.5 |
1 <?php 2 /** 3 * PEAR_Frontend_CLI 4 * 5 * PHP versions 4 and 5 6 * 7 * LICENSE: This source file is subject to version 3.0 of the PHP license 8 * that is available through the world-wide-web at the following URI: 9 * http://www.php.net/license/3_0.txt. If you did not receive a copy of 10 * the PHP License and are unable to obtain it through the web, please 11 * send a note to license@php.net so we can mail you a copy immediately. 12 * 13 * @category pear 14 * @package PEAR 15 * @author Stig Bakken <ssb@php.net> 16 * @author Greg Beaver <cellog@php.net> 17 * @copyright 1997-2006 The PHP Group 18 * @license http://www.php.net/license/3_0.txt PHP License 3.0 19 * @version CVS: $Id: CLI.php,v 1.66 2006/11/19 23:56:32 cellog Exp $ 20 * @link http://pear.php.net/package/PEAR 21 * @since File available since Release 0.1 22 */ 23 /** 24 * base class 25 */ 26 require_once 'PEAR/Frontend.php'; 27 28 /** 29 * Command-line Frontend for the PEAR Installer 30 * @category pear 31 * @package PEAR 32 * @author Stig Bakken <ssb@php.net> 33 * @author Greg Beaver <cellog@php.net> 34 * @copyright 1997-2006 The PHP Group 35 * @license http://www.php.net/license/3_0.txt PHP License 3.0 36 * @version Release: 1.5.0 37 * @link http://pear.php.net/package/PEAR 38 * @since Class available since Release 0.1 39 */ 40 class PEAR_Frontend_CLI extends PEAR_Frontend 41 { 42 // {{{ properties 43 44 /** 45 * What type of user interface this frontend is for. 46 * @var string 47 * @access public 48 */ 49 var $type = 'CLI'; 50 var $lp = ''; // line prefix 51 52 var $params = array(); 53 var $term = array( 54 'bold' => '', 55 'normal' => '', 56 ); 57 58 // }}} 59 60 // {{{ constructor 61 62 function PEAR_Frontend_CLI() 63 { 64 parent::PEAR(); 65 $term = getenv('TERM'); //(cox) $_ENV is empty for me in 4.1.1 66 if (function_exists('posix_isatty') && !posix_isatty(1)) { 67 // output is being redirected to a file or through a pipe 68 } elseif ($term) { 69 // XXX can use ncurses extension here, if available 70 if (preg_match('/^(xterm|vt220|linux)/', $term)) { 71 $this->term['bold'] = sprintf("%c%c%c%c", 27, 91, 49, 109); 72 $this->term['normal']=sprintf("%c%c%c", 27, 91, 109); 73 } elseif (preg_match('/^vt100/', $term)) { 74 $this->term['bold'] = sprintf("%c%c%c%c%c%c", 27, 91, 49, 109, 0, 0); 75 $this->term['normal']=sprintf("%c%c%c%c%c", 27, 91, 109, 0, 0); 76 } 77 } elseif (OS_WINDOWS) { 78 // XXX add ANSI codes here 79 } 80 } 81 82 // }}} 83 84 // {{{ displayLine(text) 85 86 function displayLine($text) 87 { 88 trigger_error("PEAR_Frontend_CLI::displayLine deprecated", E_USER_ERROR); 89 } 90 91 function _displayLine($text) 92 { 93 print "$this->lp$text\n"; 94 } 95 96 // }}} 97 // {{{ display(text) 98 99 function display($text) 100 { 101 trigger_error("PEAR_Frontend_CLI::display deprecated", E_USER_ERROR); 102 } 103 104 function _display($text) 105 { 106 print $text; 107 } 108 109 // }}} 110 // {{{ displayError(eobj) 111 112 /** 113 * @param object PEAR_Error object 114 */ 115 function displayError($eobj) 116 { 117 return $this->_displayLine($eobj->getMessage()); 118 } 119 120 // }}} 121 // {{{ displayFatalError(eobj) 122 123 /** 124 * @param object PEAR_Error object 125 */ 126 function displayFatalError($eobj) 127 { 128 $this->displayError($eobj); 129 if (class_exists('PEAR_Config')) { 130 $config = &PEAR_Config::singleton(); 131 if ($config->get('verbose') > 5) { 132 if (function_exists('debug_print_backtrace')) { 133 debug_print_backtrace(); 134 } elseif (function_exists('debug_backtrace')) { 135 $trace = debug_backtrace(); 136 $raised = false; 137 foreach ($trace as $i => $frame) { 138 if (!$raised) { 139 if (isset($frame['class']) && strtolower($frame['class']) == 140 'pear' && strtolower($frame['function']) == 'raiseerror') { 141 $raised = true; 142 } else { 143 continue; 144 } 145 } 146 if (!isset($frame['class'])) { 147 $frame['class'] = ''; 148 } 149 if (!isset($frame['type'])) { 150 $frame['type'] = ''; 151 } 152 if (!isset($frame['function'])) { 153 $frame['function'] = ''; 154 } 155 if (!isset($frame['line'])) { 156 $frame['line'] = ''; 157 } 158 $this->_displayLine("#$i: $frame[class]$frame[type]$frame[function] $frame[line]"); 159 } 160 } 161 } 162 } 163 exit(1); 164 } 165 166 // }}} 167 // {{{ displayHeading(title) 168 169 function displayHeading($title) 170 { 171 trigger_error("PEAR_Frontend_CLI::displayHeading deprecated", E_USER_ERROR); 172 } 173 174 function _displayHeading($title) 175 { 176 print $this->lp.$this->bold($title)."\n"; 177 print $this->lp.str_repeat("=", strlen($title))."\n"; 178 } 179 180 // }}} 181 182 /** 183 * Instruct the runInstallScript method to skip a paramgroup that matches the 184 * id value passed in. 185 * 186 * This method is useful for dynamically configuring which sections of a post-install script 187 * will be run based on the user's setup, which is very useful for making flexible 188 * post-install scripts without losing the cross-Frontend ability to retrieve user input 189 * @param string 190 */ 191 function skipParamgroup($id) 192 { 193 $this->_skipSections[$id] = true; 194 } 195 196 function runPostinstallScripts(&$scripts) 197 { 198 foreach ($scripts as $i => $script) { 199 $this->runInstallScript($scripts[$i]->_params, $scripts[$i]->_obj); 200 } 201 } 202 203 /** 204 * @param array $xml contents of postinstallscript tag 205 * @param object $script post-installation script 206 * @param string install|upgrade 207 */ 208 function runInstallScript($xml, &$script) 209 { 210 $this->_skipSections = array(); 211 if (!is_array($xml) || !isset($xml['paramgroup'])) { 212 $script->run(array(), '_default'); 213 } else { 214 $completedPhases = array(); 215 if (!isset($xml['paramgroup'][0])) { 216 $xml['paramgroup'] = array($xml['paramgroup']); 217 } 218 foreach ($xml['paramgroup'] as $group) { 219 if (isset($this->_skipSections[$group['id']])) { 220 // the post-install script chose to skip this section dynamically 221 continue; 222 } 223 if (isset($group['name'])) { 224 $paramname = explode('::', $group['name']); 225 if ($lastgroup['id'] != $paramname[0]) { 226 continue; 227 } 228 $group['name'] = $paramname[1]; 229 if (isset($answers)) { 230 if (isset($answers[$group['name']])) { 231 switch ($group['conditiontype']) { 232 case '=' : 233 if ($answers[$group['name']] != $group['value']) { 234 continue 2; 235 } 236 break; 237 case '!=' : 238 if ($answers[$group['name']] == $group['value']) { 239 continue 2; 240 } 241 break; 242 case 'preg_match' : 243 if (!@preg_match('/' . $group['value'] . '/', 244 $answers[$group['name']])) { 245 continue 2; 246 } 247 break; 248 default : 249 return; 250 } 251 } 252 } else { 253 return; 254 } 255 } 256 $lastgroup = $group; 257 if (isset($group['instructions'])) { 258 $this->_display($group['instructions']); 259 } 260 if (!isset($group['param'][0])) { 261 $group['param'] = array($group['param']); 262 } 263 if (isset($group['param'])) { 264 if (method_exists($script, 'postProcessPrompts')) { 265 $prompts = $script->postProcessPrompts($group['param'], $group['id']); 266 if (!is_array($prompts) || count($prompts) != count($group['param'])) { 267 $this->outputData('postinstall', 'Error: post-install script did not ' . 268 'return proper post-processed prompts'); 269 $prompts = $group['param']; 270 } else { 271 foreach ($prompts as $i => $var) { 272 if (!is_array($var) || !isset($var['prompt']) || 273 !isset($var['name']) || 274 ($var['name'] != $group['param'][$i]['name']) || 275 ($var['type'] != $group['param'][$i]['type'])) { 276 $this->outputData('postinstall', 'Error: post-install script ' . 277 'modified the variables or prompts, severe security risk. ' . 278 'Will instead use the defaults from the package.xml'); 279 $prompts = $group['param']; 280 } 281 } 282 } 283 $answers = $this->confirmDialog($prompts); 284 } else { 285 $answers = $this->confirmDialog($group['param']); 286 } 287 } 288 if ((isset($answers) && $answers) || !isset($group['param'])) { 289 if (!isset($answers)) { 290 $answers = array(); 291 } 292 array_unshift($completedPhases, $group['id']); 293 if (!$script->run($answers, $group['id'])) { 294 $script->run($completedPhases, '_undoOnError'); 295 return; 296 } 297 } else { 298 $script->run($completedPhases, '_undoOnError'); 299 return; 300 } 301 } 302 } 303 } 304 305 /** 306 * Ask for user input, confirm the answers and continue until the user is satisfied 307 * @param array an array of arrays, format array('name' => 'paramname', 'prompt' => 308 * 'text to display', 'type' => 'string'[, default => 'default value']) 309 * @return array 310 */ 311 function confirmDialog($params) 312 { 313 $answers = array(); 314 $prompts = $types = array(); 315 foreach ($params as $param) { 316 $prompts[$param['name']] = $param['prompt']; 317 $types[$param['name']] = $param['type']; 318 if (isset($param['default'])) { 319 $answers[$param['name']] = $param['default']; 320 } else { 321 $answers[$param['name']] = ''; 322 } 323 } 324 $tried = false; 325 do { 326 if ($tried) { 327 $i = 1; 328 foreach ($answers as $var => $value) { 329 if (!strlen($value)) { 330 echo $this->bold("* Enter an answer for #" . $i . ": ({$prompts[$var]})\n"); 331 } 332 $i++; 333 } 334 } 335 $answers = $this->userDialog('', $prompts, $types, $answers); 336 $tried = true; 337 } while (is_array($answers) && count(array_filter($answers)) != count($prompts)); 338 return $answers; 339 } 340 // {{{ userDialog(prompt, [type], [default]) 341 342 function userDialog($command, $prompts, $types = array(), $defaults = array(), 343 $screensize = 20) 344 { 345 if (!is_array($prompts)) { 346 return array(); 347 } 348 $testprompts = array_keys($prompts); 349 $result = $defaults; 350 if (!defined('STDIN')) { 351 $fp = fopen('php://stdin', 'r'); 352 } else { 353 $fp = STDIN; 354 } 355 reset($prompts); 356 if (count($prompts) == 1 && $types[key($prompts)] == 'yesno') { 357 foreach ($prompts as $key => $prompt) { 358 $type = $types[$key]; 359 $default = @$defaults[$key]; 360 print "$prompt "; 361 if ($default) { 362 print "[$default] "; 363 } 364 print ": "; 365 if (version_compare(phpversion(), '5.0.0', '<')) { 366 $line = fgets($fp, 2048); 367 } else { 368 if (!defined('STDIN')) { 369 define('STDIN', fopen('php://stdin', 'r')); 370 } 371 $line = fgets(STDIN, 2048); 372 } 373 if ($default && trim($line) == "") { 374 $result[$key] = $default; 375 } else { 376 $result[$key] = trim($line); 377 } 378 } 379 return $result; 380 } 381 while (true) { 382 $descLength = max(array_map('strlen', $prompts)); 383 $descFormat = "%-{$descLength}s"; 384 $last = count($prompts); 385 386 $i = 0; 387 foreach ($prompts as $n => $var) { 388 printf("%2d. $descFormat : %s\n", ++$i, $prompts[$n], isset($result[$n]) ? 389 $result[$n] : null); 390 } 391 392 print "\n1-$last, 'all', 'abort', or Enter to continue: "; 393 $tmp = trim(fgets($fp, 1024)); 394 if (empty($tmp)) { 395 break; 396 } 397 if ($tmp == 'abort') { 398 return false; 399 } 400 if (isset($testprompts[(int)$tmp - 1])) { 401 $var = $testprompts[(int)$tmp - 1]; 402 $desc = $prompts[$var]; 403 $current = @$result[$var]; 404 print "$desc [$current] : "; 405 $tmp = trim(fgets($fp, 1024)); 406 if (trim($tmp) !== '') { 407 $result[$var] = trim($tmp); 408 } 409 } elseif ($tmp == 'all') { 410 foreach ($prompts as $var => $desc) { 411 $current = $result[$var]; 412 print "$desc [$current] : "; 413 $tmp = trim(fgets($fp, 1024)); 414 if (trim($tmp) !== '') { 415 $result[$var] = trim($tmp); 416 } 417 } 418 } 419 } 420 if (!defined('STDIN')) { 421 fclose($fp); 422 } 423 return $result; 424 } 425 426 // }}} 427 // {{{ userConfirm(prompt, [default]) 428 429 function userConfirm($prompt, $default = 'yes') 430 { 431 trigger_error("PEAR_Frontend_CLI::userConfirm not yet converted", E_USER_ERROR); 432 static $positives = array('y', 'yes', 'on', '1'); 433 static $negatives = array('n', 'no', 'off', '0'); 434 print "$this->lp$prompt [$default] : "; 435 $fp = fopen("php://stdin", "r"); 436 $line = fgets($fp, 2048); 437 fclose($fp); 438 $answer = strtolower(trim($line)); 439 if (empty($answer)) { 440 $answer = $default; 441 } 442 if (in_array($answer, $positives)) { 443 return true; 444 } 445 if (in_array($answer, $negatives)) { 446 return false; 447 } 448 if (in_array($default, $positives)) { 449 return true; 450 } 451 return false; 452 } 453 454 // }}} 455 // {{{ startTable([params]) 456 457 function startTable($params = array()) 458 { 459 trigger_error("PEAR_Frontend_CLI::startTable deprecated", E_USER_ERROR); 460 } 461 462 function _startTable($params = array()) 463 { 464 $params['table_data'] = array(); 465 $params['widest'] = array(); // indexed by column 466 $params['highest'] = array(); // indexed by row 467 $params['ncols'] = 0; 468 $this->params = $params; 469 } 470 471 // }}} 472 // {{{ tableRow(columns, [rowparams], [colparams]) 473 474 function tableRow($columns, $rowparams = array(), $colparams = array()) 475 { 476 trigger_error("PEAR_Frontend_CLI::tableRow deprecated", E_USER_ERROR); 477 } 478 479 function _tableRow($columns, $rowparams = array(), $colparams = array()) 480 { 481 $highest = 1; 482 for ($i = 0; $i < sizeof($columns); $i++) { 483 $col = &$columns[$i]; 484 if (isset($colparams[$i]) && !empty($colparams[$i]['wrap'])) { 485 $col = wordwrap($col, $colparams[$i]['wrap'], "\n", 0); 486 } 487 if (strpos($col, "\n") !== false) { 488 $multiline = explode("\n", $col); 489 $w = 0; 490 foreach ($multiline as $n => $line) { 491 if (strlen($line) > $w) { 492 $w = strlen($line); 493 } 494 } 495 $lines = sizeof($multiline); 496 } else { 497 $w = strlen($col); 498 } 499 500 if (isset($this->params['widest'][$i])) { 501 if ($w > $this->params['widest'][$i]) { 502 $this->params['widest'][$i] = $w; 503 } 504 } else { 505 $this->params['widest'][$i] = $w; 506 } 507 $tmp = count_chars($columns[$i], 1); 508 // handle unix, mac and windows formats 509 $lines = (isset($tmp[10]) ? $tmp[10] : (isset($tmp[13]) ? $tmp[13] : 0)) + 1; 510 if ($lines > $highest) { 511 $highest = $lines; 512 } 513 } 514 if (sizeof($columns) > $this->params['ncols']) { 515 $this->params['ncols'] = sizeof($columns); 516 } 517 $new_row = array( 518 'data' => $columns, 519 'height' => $highest, 520 'rowparams' => $rowparams, 521 'colparams' => $colparams, 522 ); 523 $this->params['table_data'][] = $new_row; 524 } 525 526 // }}} 527 // {{{ endTable() 528 529 function endTable() 530 { 531 trigger_error("PEAR_Frontend_CLI::endTable deprecated", E_USER_ERROR); 532 } 533 534 function _endTable() 535 { 536 extract($this->params); 537 if (!empty($caption)) { 538 $this->_displayHeading($caption); 539 } 540 if (count($table_data) == 0) { 541 return; 542 } 543 if (!isset($width)) { 544 $width = $widest; 545 } else { 546 for ($i = 0; $i < $ncols; $i++) { 547 if (!isset($width[$i])) { 548 $width[$i] = $widest[$i]; 549 } 550 } 551 } 552 $border = false; 553 if (empty($border)) { 554 $cellstart = ''; 555 $cellend = ' '; 556 $rowend = ''; 557 $padrowend = false; 558 $borderline = ''; 559 } else { 560 $cellstart = '| '; 561 $cellend = ' '; 562 $rowend = '|'; 563 $padrowend = true; 564 $borderline = '+'; 565 foreach ($width as $w) { 566 $borderline .= str_repeat('-', $w + strlen($cellstart) + strlen($cellend) - 1); 567 $borderline .= '+'; 568 } 569 } 570 if ($borderline) { 571 $this->_displayLine($borderline); 572 } 573 for ($i = 0; $i < sizeof($table_data); $i++) { 574 extract($table_data[$i]); 575 if (!is_array($rowparams)) { 576 $rowparams = array(); 577 } 578 if (!is_array($colparams)) { 579 $colparams = array(); 580 } 581 $rowlines = array(); 582 if ($height > 1) { 583 for ($c = 0; $c < sizeof($data); $c++) { 584 $rowlines[$c] = preg_split('/(\r?\n|\r)/', $data[$c]); 585 if (sizeof($rowlines[$c]) < $height) { 586 $rowlines[$c] = array_pad($rowlines[$c], $height, ''); 587 } 588 } 589 } else { 590 for ($c = 0; $c < sizeof($data); $c++) { 591 $rowlines[$c] = array($data[$c]); 592 } 593 } 594 for ($r = 0; $r < $height; $r++) { 595 $rowtext = ''; 596 for ($c = 0; $c < sizeof($data); $c++) { 597 if (isset($colparams[$c])) { 598 $attribs = array_merge($rowparams, $colparams); 599 } else { 600 $attribs = $rowparams; 601 } 602 $w = isset($width[$c]) ? $width[$c] : 0; 603 //$cell = $data[$c]; 604 $cell = $rowlines[$c][$r]; 605 $l = strlen($cell); 606 if ($l > $w) { 607 $cell = substr($cell, 0, $w); 608 } 609 if (isset($attribs['bold'])) { 610 $cell = $this->bold($cell); 611 } 612 if ($l < $w) { 613 // not using str_pad here because we may 614 // add bold escape characters to $cell 615 $cell .= str_repeat(' ', $w - $l); 616 } 617 618 $rowtext .= $cellstart . $cell . $cellend; 619 } 620 if (!$border) { 621 $rowtext = rtrim($rowtext); 622 } 623 $rowtext .= $rowend; 624 $this->_displayLine($rowtext); 625 } 626 } 627 if ($borderline) { 628 $this->_displayLine($borderline); 629 } 630 } 631 632 // }}} 633 // {{{ outputData() 634 635 function outputData($data, $command = '_default') 636 { 637 switch ($command) { 638 case 'channel-info': 639 foreach ($data as $type => $section) { 640 if ($type == 'main') { 641 $section['data'] = array_values($section['data']); 642 } 643 $this->outputData($section); 644 } 645 break; 646 case 'install': 647 case 'upgrade': 648 case 'upgrade-all': 649 if (isset($data['release_warnings'])) { 650 $this->_displayLine(''); 651 $this->_startTable(array( 652 'border' => false, 653 'caption' => 'Release Warnings' 654 )); 655 $this->_tableRow(array($data['release_warnings']), null, array(1 => array('wrap' => 55))); 656 $this->_endTable(); 657 $this->_displayLine(''); 658 } 659 $this->_displayLine($data['data']); 660 break; 661 case 'search': 662 $this->_startTable($data); 663 if (isset($data['headline']) && is_array($data['headline'])) { 664 $this->_tableRow($data['headline'], array('bold' => true), array(1 => array('wrap' => 55))); 665 } 666 667 foreach($data['data'] as $category) { 668 foreach($category as $pkg) { 669 $this->_tableRow($pkg, null, array(1 => array('wrap' => 55))); 670 } 671 }; 672 $this->_endTable(); 673 break; 674 case 'list-all': 675 $this->_startTable($data); 676 if (isset($data['headline']) && is_array($data['headline'])) { 677 $this->_tableRow($data['headline'], array('bold' => true), array(1 => array('wrap' => 55))); 678 } 679 680 foreach($data['data'] as $category) { 681 foreach($category as $pkg) { 682 unset($pkg[4]); 683 unset($pkg[5]); 684 $this->_tableRow($pkg, null, array(1 => array('wrap' => 55))); 685 } 686 }; 687 $this->_endTable(); 688 break; 689 case 'config-show': 690 $data['border'] = false; 691 $opts = array(0 => array('wrap' => 30), 692 1 => array('wrap' => 20), 693 2 => array('wrap' => 35)); 694 $this->_startTable($data); 695 if (isset($data['headline']) && is_array($data['headline'])) { 696 $this->_tableRow($data['headline'], 697 array('bold' => true), 698 $opts); 699 } 700 foreach($data['data'] as $group) { 701 foreach($group as $value) { 702 if ($value[2] == '') { 703 $value[2] = "<not set>"; 704 } 705 $this->_tableRow($value, null, $opts); 706 } 707 } 708 $this->_endTable(); 709 break; 710 case 'remote-info': 711 $d = $data; 712 $data = array( 713 'caption' => 'Package details:', 714 'border' => false, 715 'data' => array( 716 array("Latest", $data['stable']), 717 array("Installed", $data['installed']), 718 array("Package", $data['name']), 719 array("License", $data['license']), 720 array("Category", $data['category']), 721 array("Summary", $data['summary']), 722 array("Description", $data['description']), 723 ), 724 ); 725 if (isset($d['deprecated']) && $d['deprecated']) { 726 $conf = &PEAR_Config::singleton(); 727 $reg = $conf->getRegistry(); 728 $name = $reg->parsedPackageNameToString($d['deprecated'], true); 729 $data['data'][] = array('Deprecated! use', $name); 730 } 731 default: { 732 if (is_array($data)) { 733 $this->_startTable($data); 734 $count = count($data['data'][0]); 735 if ($count == 2) { 736 $opts = array(0 => array('wrap' => 25), 737 1 => array('wrap' => 48) 738 ); 739 } elseif ($count == 3) { 740 $opts = array(0 => array('wrap' => 30), 741 1 => array('wrap' => 20), 742 2 => array('wrap' => 35) 743 ); 744 } else { 745 $opts = null; 746 } 747 if (isset($data['headline']) && is_array($data['headline'])) { 748 $this->_tableRow($data['headline'], 749 array('bold' => true), 750 $opts); 751 } 752 foreach($data['data'] as $row) { 753 $this->_tableRow($row, null, $opts); 754 } 755 $this->_endTable(); 756 } else { 757 $this->_displayLine($data); 758 } 759 } 760 } 761 } 762 763 // }}} 764 // {{{ log(text) 765 766 767 function log($text, $append_crlf = true) 768 { 769 if ($append_crlf) { 770 return $this->_displayLine($text); 771 } 772 return $this->_display($text); 773 } 774 775 776 // }}} 777 // {{{ bold($text) 778 779 function bold($text) 780 { 781 if (empty($this->term['bold'])) { 782 return strtoupper($text); 783 } 784 return $this->term['bold'] . $text . $this->term['normal']; 785 } 786 787 // }}} 788 } 789 790 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Sun Feb 25 14:08:00 2007 | par Balluche grâce à PHPXref 0.7 |