annotate vendor/psy/psysh/src/Psy/Configuration.php @ 0:4c8ae668cc8c

Initial import (non-working)
author Chris Cannam
date Wed, 29 Nov 2017 16:09:58 +0000
parents
children 7a779792577d
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 /*
Chris@0 4 * This file is part of Psy Shell.
Chris@0 5 *
Chris@0 6 * (c) 2012-2017 Justin Hileman
Chris@0 7 *
Chris@0 8 * For the full copyright and license information, please view the LICENSE
Chris@0 9 * file that was distributed with this source code.
Chris@0 10 */
Chris@0 11
Chris@0 12 namespace Psy;
Chris@0 13
Chris@0 14 use Psy\Exception\DeprecatedException;
Chris@0 15 use Psy\Exception\RuntimeException;
Chris@0 16 use Psy\ExecutionLoop\ForkingLoop;
Chris@0 17 use Psy\ExecutionLoop\Loop;
Chris@0 18 use Psy\Output\OutputPager;
Chris@0 19 use Psy\Output\ShellOutput;
Chris@0 20 use Psy\Readline\GNUReadline;
Chris@0 21 use Psy\Readline\HoaConsole;
Chris@0 22 use Psy\Readline\Libedit;
Chris@0 23 use Psy\Readline\Readline;
Chris@0 24 use Psy\Readline\Transient;
Chris@0 25 use Psy\TabCompletion\AutoCompleter;
Chris@0 26 use Psy\VarDumper\Presenter;
Chris@0 27 use Psy\VersionUpdater\Checker;
Chris@0 28 use Psy\VersionUpdater\GitHubChecker;
Chris@0 29 use Psy\VersionUpdater\IntervalChecker;
Chris@0 30 use Psy\VersionUpdater\NoopChecker;
Chris@0 31 use XdgBaseDir\Xdg;
Chris@0 32
Chris@0 33 /**
Chris@0 34 * The Psy Shell configuration.
Chris@0 35 */
Chris@0 36 class Configuration
Chris@0 37 {
Chris@0 38 const COLOR_MODE_AUTO = 'auto';
Chris@0 39 const COLOR_MODE_FORCED = 'forced';
Chris@0 40 const COLOR_MODE_DISABLED = 'disabled';
Chris@0 41
Chris@0 42 private static $AVAILABLE_OPTIONS = array(
Chris@0 43 'codeCleaner',
Chris@0 44 'colorMode',
Chris@0 45 'configDir',
Chris@0 46 'dataDir',
Chris@0 47 'defaultIncludes',
Chris@0 48 'eraseDuplicates',
Chris@0 49 'errorLoggingLevel',
Chris@0 50 'forceArrayIndexes',
Chris@0 51 'historySize',
Chris@0 52 'loop',
Chris@0 53 'manualDbFile',
Chris@0 54 'pager',
Chris@0 55 'prompt',
Chris@0 56 'requireSemicolons',
Chris@0 57 'runtimeDir',
Chris@0 58 'startupMessage',
Chris@0 59 'tabCompletion',
Chris@0 60 'updateCheck',
Chris@0 61 'useBracketedPaste',
Chris@0 62 'usePcntl',
Chris@0 63 'useReadline',
Chris@0 64 'useUnicode',
Chris@0 65 'warnOnMultipleConfigs',
Chris@0 66 );
Chris@0 67
Chris@0 68 private $defaultIncludes;
Chris@0 69 private $configDir;
Chris@0 70 private $dataDir;
Chris@0 71 private $runtimeDir;
Chris@0 72 private $configFile;
Chris@0 73 /** @var string|false */
Chris@0 74 private $historyFile;
Chris@0 75 private $historySize;
Chris@0 76 private $eraseDuplicates;
Chris@0 77 private $manualDbFile;
Chris@0 78 private $hasReadline;
Chris@0 79 private $useReadline;
Chris@0 80 private $useBracketedPaste;
Chris@0 81 private $hasPcntl;
Chris@0 82 private $usePcntl;
Chris@0 83 private $newCommands = array();
Chris@0 84 private $requireSemicolons = false;
Chris@0 85 private $useUnicode;
Chris@0 86 private $tabCompletion;
Chris@0 87 private $tabCompletionMatchers = array();
Chris@0 88 private $errorLoggingLevel = E_ALL;
Chris@0 89 private $warnOnMultipleConfigs = false;
Chris@0 90 private $colorMode;
Chris@0 91 private $updateCheck;
Chris@0 92 private $startupMessage;
Chris@0 93 private $forceArrayIndexes = false;
Chris@0 94
Chris@0 95 // services
Chris@0 96 private $readline;
Chris@0 97 private $output;
Chris@0 98 private $shell;
Chris@0 99 private $cleaner;
Chris@0 100 private $pager;
Chris@0 101 private $loop;
Chris@0 102 private $manualDb;
Chris@0 103 private $presenter;
Chris@0 104 private $completer;
Chris@0 105 private $checker;
Chris@0 106 private $prompt;
Chris@0 107
Chris@0 108 /**
Chris@0 109 * Construct a Configuration instance.
Chris@0 110 *
Chris@0 111 * Optionally, supply an array of configuration values to load.
Chris@0 112 *
Chris@0 113 * @param array $config Optional array of configuration values
Chris@0 114 */
Chris@0 115 public function __construct(array $config = array())
Chris@0 116 {
Chris@0 117 $this->setColorMode(self::COLOR_MODE_AUTO);
Chris@0 118
Chris@0 119 // explicit configFile option
Chris@0 120 if (isset($config['configFile'])) {
Chris@0 121 $this->configFile = $config['configFile'];
Chris@0 122 } elseif ($configFile = getenv('PSYSH_CONFIG')) {
Chris@0 123 $this->configFile = $configFile;
Chris@0 124 }
Chris@0 125
Chris@0 126 // legacy baseDir option
Chris@0 127 if (isset($config['baseDir'])) {
Chris@0 128 $msg = "The 'baseDir' configuration option is deprecated. " .
Chris@0 129 "Please specify 'configDir' and 'dataDir' options instead.";
Chris@0 130 throw new DeprecatedException($msg);
Chris@0 131 }
Chris@0 132
Chris@0 133 unset($config['configFile'], $config['baseDir']);
Chris@0 134
Chris@0 135 // go go gadget, config!
Chris@0 136 $this->loadConfig($config);
Chris@0 137 $this->init();
Chris@0 138 }
Chris@0 139
Chris@0 140 /**
Chris@0 141 * Initialize the configuration.
Chris@0 142 *
Chris@0 143 * This checks for the presence of Readline and Pcntl extensions.
Chris@0 144 *
Chris@0 145 * If a config file is available, it will be loaded and merged with the current config.
Chris@0 146 *
Chris@0 147 * If no custom config file was specified and a local project config file
Chris@0 148 * is available, it will be loaded and merged with the current config.
Chris@0 149 */
Chris@0 150 public function init()
Chris@0 151 {
Chris@0 152 // feature detection
Chris@0 153 $this->hasReadline = function_exists('readline');
Chris@0 154 $this->hasPcntl = function_exists('pcntl_signal') && function_exists('posix_getpid');
Chris@0 155
Chris@0 156 if ($configFile = $this->getConfigFile()) {
Chris@0 157 $this->loadConfigFile($configFile);
Chris@0 158 }
Chris@0 159
Chris@0 160 if (!$this->configFile && $localConfig = $this->getLocalConfigFile()) {
Chris@0 161 $this->loadConfigFile($localConfig);
Chris@0 162 }
Chris@0 163 }
Chris@0 164
Chris@0 165 /**
Chris@0 166 * Get the current PsySH config file.
Chris@0 167 *
Chris@0 168 * If a `configFile` option was passed to the Configuration constructor,
Chris@0 169 * this file will be returned. If not, all possible config directories will
Chris@0 170 * be searched, and the first `config.php` or `rc.php` file which exists
Chris@0 171 * will be returned.
Chris@0 172 *
Chris@0 173 * If you're trying to decide where to put your config file, pick
Chris@0 174 *
Chris@0 175 * ~/.config/psysh/config.php
Chris@0 176 *
Chris@0 177 * @return string
Chris@0 178 */
Chris@0 179 public function getConfigFile()
Chris@0 180 {
Chris@0 181 if (isset($this->configFile)) {
Chris@0 182 return $this->configFile;
Chris@0 183 }
Chris@0 184
Chris@0 185 $files = ConfigPaths::getConfigFiles(array('config.php', 'rc.php'), $this->configDir);
Chris@0 186
Chris@0 187 if (!empty($files)) {
Chris@0 188 if ($this->warnOnMultipleConfigs && count($files) > 1) {
Chris@0 189 $msg = sprintf('Multiple configuration files found: %s. Using %s', implode($files, ', '), $files[0]);
Chris@0 190 trigger_error($msg, E_USER_NOTICE);
Chris@0 191 }
Chris@0 192
Chris@0 193 return $files[0];
Chris@0 194 }
Chris@0 195 }
Chris@0 196
Chris@0 197 /**
Chris@0 198 * Get the local PsySH config file.
Chris@0 199 *
Chris@0 200 * Searches for a project specific config file `.psysh.php` in the current
Chris@0 201 * working directory.
Chris@0 202 *
Chris@0 203 * @return string
Chris@0 204 */
Chris@0 205 public function getLocalConfigFile()
Chris@0 206 {
Chris@0 207 $localConfig = getcwd() . '/.psysh.php';
Chris@0 208
Chris@0 209 if (@is_file($localConfig)) {
Chris@0 210 return $localConfig;
Chris@0 211 }
Chris@0 212 }
Chris@0 213
Chris@0 214 /**
Chris@0 215 * Load configuration values from an array of options.
Chris@0 216 *
Chris@0 217 * @param array $options
Chris@0 218 */
Chris@0 219 public function loadConfig(array $options)
Chris@0 220 {
Chris@0 221 foreach (self::$AVAILABLE_OPTIONS as $option) {
Chris@0 222 if (isset($options[$option])) {
Chris@0 223 $method = 'set' . ucfirst($option);
Chris@0 224 $this->$method($options[$option]);
Chris@0 225 }
Chris@0 226 }
Chris@0 227
Chris@0 228 foreach (array('commands', 'tabCompletionMatchers', 'casters') as $option) {
Chris@0 229 if (isset($options[$option])) {
Chris@0 230 $method = 'add' . ucfirst($option);
Chris@0 231 $this->$method($options[$option]);
Chris@0 232 }
Chris@0 233 }
Chris@0 234 }
Chris@0 235
Chris@0 236 /**
Chris@0 237 * Load a configuration file (default: `$HOME/.config/psysh/config.php`).
Chris@0 238 *
Chris@0 239 * This configuration instance will be available to the config file as $config.
Chris@0 240 * The config file may directly manipulate the configuration, or may return
Chris@0 241 * an array of options which will be merged with the current configuration.
Chris@0 242 *
Chris@0 243 * @throws \InvalidArgumentException if the config file returns a non-array result
Chris@0 244 *
Chris@0 245 * @param string $file
Chris@0 246 */
Chris@0 247 public function loadConfigFile($file)
Chris@0 248 {
Chris@0 249 $__psysh_config_file__ = $file;
Chris@0 250 $load = function ($config) use ($__psysh_config_file__) {
Chris@0 251 $result = require $__psysh_config_file__;
Chris@0 252 if ($result !== 1) {
Chris@0 253 return $result;
Chris@0 254 }
Chris@0 255 };
Chris@0 256 $result = $load($this);
Chris@0 257
Chris@0 258 if (!empty($result)) {
Chris@0 259 if (is_array($result)) {
Chris@0 260 $this->loadConfig($result);
Chris@0 261 } else {
Chris@0 262 throw new \InvalidArgumentException('Psy Shell configuration must return an array of options');
Chris@0 263 }
Chris@0 264 }
Chris@0 265 }
Chris@0 266
Chris@0 267 /**
Chris@0 268 * Set files to be included by default at the start of each shell session.
Chris@0 269 *
Chris@0 270 * @param array $includes
Chris@0 271 */
Chris@0 272 public function setDefaultIncludes(array $includes = array())
Chris@0 273 {
Chris@0 274 $this->defaultIncludes = $includes;
Chris@0 275 }
Chris@0 276
Chris@0 277 /**
Chris@0 278 * Get files to be included by default at the start of each shell session.
Chris@0 279 *
Chris@0 280 * @return array
Chris@0 281 */
Chris@0 282 public function getDefaultIncludes()
Chris@0 283 {
Chris@0 284 return $this->defaultIncludes ?: array();
Chris@0 285 }
Chris@0 286
Chris@0 287 /**
Chris@0 288 * Set the shell's config directory location.
Chris@0 289 *
Chris@0 290 * @param string $dir
Chris@0 291 */
Chris@0 292 public function setConfigDir($dir)
Chris@0 293 {
Chris@0 294 $this->configDir = (string) $dir;
Chris@0 295 }
Chris@0 296
Chris@0 297 /**
Chris@0 298 * Get the current configuration directory, if any is explicitly set.
Chris@0 299 *
Chris@0 300 * @return string
Chris@0 301 */
Chris@0 302 public function getConfigDir()
Chris@0 303 {
Chris@0 304 return $this->configDir;
Chris@0 305 }
Chris@0 306
Chris@0 307 /**
Chris@0 308 * Set the shell's data directory location.
Chris@0 309 *
Chris@0 310 * @param string $dir
Chris@0 311 */
Chris@0 312 public function setDataDir($dir)
Chris@0 313 {
Chris@0 314 $this->dataDir = (string) $dir;
Chris@0 315 }
Chris@0 316
Chris@0 317 /**
Chris@0 318 * Get the current data directory, if any is explicitly set.
Chris@0 319 *
Chris@0 320 * @return string
Chris@0 321 */
Chris@0 322 public function getDataDir()
Chris@0 323 {
Chris@0 324 return $this->dataDir;
Chris@0 325 }
Chris@0 326
Chris@0 327 /**
Chris@0 328 * Set the shell's temporary directory location.
Chris@0 329 *
Chris@0 330 * @param string $dir
Chris@0 331 */
Chris@0 332 public function setRuntimeDir($dir)
Chris@0 333 {
Chris@0 334 $this->runtimeDir = (string) $dir;
Chris@0 335 }
Chris@0 336
Chris@0 337 /**
Chris@0 338 * Get the shell's temporary directory location.
Chris@0 339 *
Chris@0 340 * Defaults to `/psysh` inside the system's temp dir unless explicitly
Chris@0 341 * overridden.
Chris@0 342 *
Chris@0 343 * @return string
Chris@0 344 */
Chris@0 345 public function getRuntimeDir()
Chris@0 346 {
Chris@0 347 if (!isset($this->runtimeDir)) {
Chris@0 348 $this->runtimeDir = ConfigPaths::getRuntimeDir();
Chris@0 349 }
Chris@0 350
Chris@0 351 if (!is_dir($this->runtimeDir)) {
Chris@0 352 mkdir($this->runtimeDir, 0700, true);
Chris@0 353 }
Chris@0 354
Chris@0 355 return $this->runtimeDir;
Chris@0 356 }
Chris@0 357
Chris@0 358 /**
Chris@0 359 * Set the readline history file path.
Chris@0 360 *
Chris@0 361 * @param string $file
Chris@0 362 */
Chris@0 363 public function setHistoryFile($file)
Chris@0 364 {
Chris@0 365 $this->historyFile = ConfigPaths::touchFileWithMkdir($file);
Chris@0 366 }
Chris@0 367
Chris@0 368 /**
Chris@0 369 * Get the readline history file path.
Chris@0 370 *
Chris@0 371 * Defaults to `/history` inside the shell's base config dir unless
Chris@0 372 * explicitly overridden.
Chris@0 373 *
Chris@0 374 * @return string
Chris@0 375 */
Chris@0 376 public function getHistoryFile()
Chris@0 377 {
Chris@0 378 if (isset($this->historyFile)) {
Chris@0 379 return $this->historyFile;
Chris@0 380 }
Chris@0 381
Chris@0 382 // Deprecation warning for incorrect psysh_history path.
Chris@0 383 // @todo remove this before v0.9.0
Chris@0 384 $xdg = new Xdg();
Chris@0 385 $oldHistory = $xdg->getHomeConfigDir() . '/psysh_history';
Chris@0 386 if (@is_file($oldHistory)) {
Chris@0 387 $dir = $this->configDir ?: ConfigPaths::getCurrentConfigDir();
Chris@0 388 $newHistory = $dir . '/psysh_history';
Chris@0 389
Chris@0 390 $msg = sprintf(
Chris@0 391 "PsySH history file found at '%s'. Please delete it or move it to '%s'.",
Chris@0 392 strtr($oldHistory, '\\', '/'),
Chris@0 393 $newHistory
Chris@0 394 );
Chris@0 395 @trigger_error($msg, E_USER_DEPRECATED);
Chris@0 396 $this->setHistoryFile($oldHistory);
Chris@0 397
Chris@0 398 return $this->historyFile;
Chris@0 399 }
Chris@0 400
Chris@0 401 $files = ConfigPaths::getConfigFiles(array('psysh_history', 'history'), $this->configDir);
Chris@0 402
Chris@0 403 if (!empty($files)) {
Chris@0 404 if ($this->warnOnMultipleConfigs && count($files) > 1) {
Chris@0 405 $msg = sprintf('Multiple history files found: %s. Using %s', implode($files, ', '), $files[0]);
Chris@0 406 trigger_error($msg, E_USER_NOTICE);
Chris@0 407 }
Chris@0 408
Chris@0 409 $this->setHistoryFile($files[0]);
Chris@0 410 } else {
Chris@0 411 // fallback: create our own history file
Chris@0 412 $dir = $this->configDir ?: ConfigPaths::getCurrentConfigDir();
Chris@0 413 $this->setHistoryFile($dir . '/psysh_history');
Chris@0 414 }
Chris@0 415
Chris@0 416 return $this->historyFile;
Chris@0 417 }
Chris@0 418
Chris@0 419 /**
Chris@0 420 * Set the readline max history size.
Chris@0 421 *
Chris@0 422 * @param int $value
Chris@0 423 */
Chris@0 424 public function setHistorySize($value)
Chris@0 425 {
Chris@0 426 $this->historySize = (int) $value;
Chris@0 427 }
Chris@0 428
Chris@0 429 /**
Chris@0 430 * Get the readline max history size.
Chris@0 431 *
Chris@0 432 * @return int
Chris@0 433 */
Chris@0 434 public function getHistorySize()
Chris@0 435 {
Chris@0 436 return $this->historySize;
Chris@0 437 }
Chris@0 438
Chris@0 439 /**
Chris@0 440 * Sets whether readline erases old duplicate history entries.
Chris@0 441 *
Chris@0 442 * @param bool $value
Chris@0 443 */
Chris@0 444 public function setEraseDuplicates($value)
Chris@0 445 {
Chris@0 446 $this->eraseDuplicates = (bool) $value;
Chris@0 447 }
Chris@0 448
Chris@0 449 /**
Chris@0 450 * Get whether readline erases old duplicate history entries.
Chris@0 451 *
Chris@0 452 * @return bool
Chris@0 453 */
Chris@0 454 public function getEraseDuplicates()
Chris@0 455 {
Chris@0 456 return $this->eraseDuplicates;
Chris@0 457 }
Chris@0 458
Chris@0 459 /**
Chris@0 460 * Get a temporary file of type $type for process $pid.
Chris@0 461 *
Chris@0 462 * The file will be created inside the current temporary directory.
Chris@0 463 *
Chris@0 464 * @see self::getRuntimeDir
Chris@0 465 *
Chris@0 466 * @param string $type
Chris@0 467 * @param int $pid
Chris@0 468 *
Chris@0 469 * @return string Temporary file name
Chris@0 470 */
Chris@0 471 public function getTempFile($type, $pid)
Chris@0 472 {
Chris@0 473 return tempnam($this->getRuntimeDir(), $type . '_' . $pid . '_');
Chris@0 474 }
Chris@0 475
Chris@0 476 /**
Chris@0 477 * Get a filename suitable for a FIFO pipe of $type for process $pid.
Chris@0 478 *
Chris@0 479 * The pipe will be created inside the current temporary directory.
Chris@0 480 *
Chris@0 481 * @param string $type
Chris@0 482 * @param int $pid
Chris@0 483 *
Chris@0 484 * @return string Pipe name
Chris@0 485 */
Chris@0 486 public function getPipe($type, $pid)
Chris@0 487 {
Chris@0 488 return sprintf('%s/%s_%s', $this->getRuntimeDir(), $type, $pid);
Chris@0 489 }
Chris@0 490
Chris@0 491 /**
Chris@0 492 * Check whether this PHP instance has Readline available.
Chris@0 493 *
Chris@0 494 * @return bool True if Readline is available
Chris@0 495 */
Chris@0 496 public function hasReadline()
Chris@0 497 {
Chris@0 498 return $this->hasReadline;
Chris@0 499 }
Chris@0 500
Chris@0 501 /**
Chris@0 502 * Enable or disable Readline usage.
Chris@0 503 *
Chris@0 504 * @param bool $useReadline
Chris@0 505 */
Chris@0 506 public function setUseReadline($useReadline)
Chris@0 507 {
Chris@0 508 $this->useReadline = (bool) $useReadline;
Chris@0 509 }
Chris@0 510
Chris@0 511 /**
Chris@0 512 * Check whether to use Readline.
Chris@0 513 *
Chris@0 514 * If `setUseReadline` as been set to true, but Readline is not actually
Chris@0 515 * available, this will return false.
Chris@0 516 *
Chris@0 517 * @return bool True if the current Shell should use Readline
Chris@0 518 */
Chris@0 519 public function useReadline()
Chris@0 520 {
Chris@0 521 return isset($this->useReadline) ? ($this->hasReadline && $this->useReadline) : $this->hasReadline;
Chris@0 522 }
Chris@0 523
Chris@0 524 /**
Chris@0 525 * Set the Psy Shell readline service.
Chris@0 526 *
Chris@0 527 * @param Readline $readline
Chris@0 528 */
Chris@0 529 public function setReadline(Readline $readline)
Chris@0 530 {
Chris@0 531 $this->readline = $readline;
Chris@0 532 }
Chris@0 533
Chris@0 534 /**
Chris@0 535 * Get the Psy Shell readline service.
Chris@0 536 *
Chris@0 537 * By default, this service uses (in order of preference):
Chris@0 538 *
Chris@0 539 * * GNU Readline
Chris@0 540 * * Libedit
Chris@0 541 * * A transient array-based readline emulation.
Chris@0 542 *
Chris@0 543 * @return Readline
Chris@0 544 */
Chris@0 545 public function getReadline()
Chris@0 546 {
Chris@0 547 if (!isset($this->readline)) {
Chris@0 548 $className = $this->getReadlineClass();
Chris@0 549 $this->readline = new $className(
Chris@0 550 $this->getHistoryFile(),
Chris@0 551 $this->getHistorySize(),
Chris@0 552 $this->getEraseDuplicates()
Chris@0 553 );
Chris@0 554 }
Chris@0 555
Chris@0 556 return $this->readline;
Chris@0 557 }
Chris@0 558
Chris@0 559 /**
Chris@0 560 * Get the appropriate Readline implementation class name.
Chris@0 561 *
Chris@0 562 * @see self::getReadline
Chris@0 563 *
Chris@0 564 * @return string
Chris@0 565 */
Chris@0 566 private function getReadlineClass()
Chris@0 567 {
Chris@0 568 if ($this->useReadline()) {
Chris@0 569 if (GNUReadline::isSupported()) {
Chris@0 570 return 'Psy\Readline\GNUReadline';
Chris@0 571 } elseif (Libedit::isSupported()) {
Chris@0 572 return 'Psy\Readline\Libedit';
Chris@0 573 } elseif (HoaConsole::isSupported()) {
Chris@0 574 return 'Psy\Readline\HoaConsole';
Chris@0 575 }
Chris@0 576 }
Chris@0 577
Chris@0 578 return 'Psy\Readline\Transient';
Chris@0 579 }
Chris@0 580
Chris@0 581 /**
Chris@0 582 * Enable or disable bracketed paste.
Chris@0 583 *
Chris@0 584 * Note that this only works with readline (not libedit) integration for now.
Chris@0 585 *
Chris@0 586 * @param bool $useBracketedPaste
Chris@0 587 */
Chris@0 588 public function setUseBracketedPaste($useBracketedPaste)
Chris@0 589 {
Chris@0 590 $this->useBracketedPaste = (bool) $useBracketedPaste;
Chris@0 591 }
Chris@0 592
Chris@0 593 /**
Chris@0 594 * Check whether to use bracketed paste with readline.
Chris@0 595 *
Chris@0 596 * When this works, it's magical. Tabs in pastes don't try to autcomplete.
Chris@0 597 * Newlines in paste don't execute code until you get to the end. It makes
Chris@0 598 * readline act like you'd expect when pasting.
Chris@0 599 *
Chris@0 600 * But it often (usually?) does not work. And when it doesn't, it just spews
Chris@0 601 * escape codes all over the place and generally makes things ugly :(
Chris@0 602 *
Chris@0 603 * If `useBracketedPaste` has been set to true, but the current readline
Chris@0 604 * implementation is anything besides GNU readline, this will return false.
Chris@0 605 *
Chris@0 606 * @return bool True if the shell should use bracketed paste
Chris@0 607 */
Chris@0 608 public function useBracketedPaste()
Chris@0 609 {
Chris@0 610 // For now, only the GNU readline implementation supports bracketed paste.
Chris@0 611 $supported = ($this->getReadlineClass() === 'Psy\Readline\GNUReadline');
Chris@0 612
Chris@0 613 return $supported && $this->useBracketedPaste;
Chris@0 614
Chris@0 615 // @todo mebbe turn this on by default some day?
Chris@0 616 // return isset($this->useBracketedPaste) ? ($supported && $this->useBracketedPaste) : $supported;
Chris@0 617 }
Chris@0 618
Chris@0 619 /**
Chris@0 620 * Check whether this PHP instance has Pcntl available.
Chris@0 621 *
Chris@0 622 * @return bool True if Pcntl is available
Chris@0 623 */
Chris@0 624 public function hasPcntl()
Chris@0 625 {
Chris@0 626 return $this->hasPcntl;
Chris@0 627 }
Chris@0 628
Chris@0 629 /**
Chris@0 630 * Enable or disable Pcntl usage.
Chris@0 631 *
Chris@0 632 * @param bool $usePcntl
Chris@0 633 */
Chris@0 634 public function setUsePcntl($usePcntl)
Chris@0 635 {
Chris@0 636 $this->usePcntl = (bool) $usePcntl;
Chris@0 637 }
Chris@0 638
Chris@0 639 /**
Chris@0 640 * Check whether to use Pcntl.
Chris@0 641 *
Chris@0 642 * If `setUsePcntl` has been set to true, but Pcntl is not actually
Chris@0 643 * available, this will return false.
Chris@0 644 *
Chris@0 645 * @return bool True if the current Shell should use Pcntl
Chris@0 646 */
Chris@0 647 public function usePcntl()
Chris@0 648 {
Chris@0 649 return isset($this->usePcntl) ? ($this->hasPcntl && $this->usePcntl) : $this->hasPcntl;
Chris@0 650 }
Chris@0 651
Chris@0 652 /**
Chris@0 653 * Enable or disable strict requirement of semicolons.
Chris@0 654 *
Chris@0 655 * @see self::requireSemicolons()
Chris@0 656 *
Chris@0 657 * @param bool $requireSemicolons
Chris@0 658 */
Chris@0 659 public function setRequireSemicolons($requireSemicolons)
Chris@0 660 {
Chris@0 661 $this->requireSemicolons = (bool) $requireSemicolons;
Chris@0 662 }
Chris@0 663
Chris@0 664 /**
Chris@0 665 * Check whether to require semicolons on all statements.
Chris@0 666 *
Chris@0 667 * By default, PsySH will automatically insert semicolons at the end of
Chris@0 668 * statements if they're missing. To strictly require semicolons, set
Chris@0 669 * `requireSemicolons` to true.
Chris@0 670 *
Chris@0 671 * @return bool
Chris@0 672 */
Chris@0 673 public function requireSemicolons()
Chris@0 674 {
Chris@0 675 return $this->requireSemicolons;
Chris@0 676 }
Chris@0 677
Chris@0 678 /**
Chris@0 679 * Enable or disable Unicode in PsySH specific output.
Chris@0 680 *
Chris@0 681 * Note that this does not disable Unicode output in general, it just makes
Chris@0 682 * it so PsySH won't output any itself.
Chris@0 683 *
Chris@0 684 * @param bool $useUnicode
Chris@0 685 */
Chris@0 686 public function setUseUnicode($useUnicode)
Chris@0 687 {
Chris@0 688 $this->useUnicode = (bool) $useUnicode;
Chris@0 689 }
Chris@0 690
Chris@0 691 /**
Chris@0 692 * Check whether to use Unicode in PsySH specific output.
Chris@0 693 *
Chris@0 694 * Note that this does not disable Unicode output in general, it just makes
Chris@0 695 * it so PsySH won't output any itself.
Chris@0 696 *
Chris@0 697 * @return bool
Chris@0 698 */
Chris@0 699 public function useUnicode()
Chris@0 700 {
Chris@0 701 if (isset($this->useUnicode)) {
Chris@0 702 return $this->useUnicode;
Chris@0 703 }
Chris@0 704
Chris@0 705 // @todo detect `chsh` != 65001 on Windows and return false
Chris@0 706 return true;
Chris@0 707 }
Chris@0 708
Chris@0 709 /**
Chris@0 710 * Set the error logging level.
Chris@0 711 *
Chris@0 712 * @see self::errorLoggingLevel
Chris@0 713 *
Chris@0 714 * @param bool $errorLoggingLevel
Chris@0 715 */
Chris@0 716 public function setErrorLoggingLevel($errorLoggingLevel)
Chris@0 717 {
Chris@0 718 $this->errorLoggingLevel = (E_ALL | E_STRICT) & $errorLoggingLevel;
Chris@0 719 }
Chris@0 720
Chris@0 721 /**
Chris@0 722 * Get the current error logging level.
Chris@0 723 *
Chris@0 724 * By default, PsySH will automatically log all errors, regardless of the
Chris@0 725 * current `error_reporting` level. Additionally, if the `error_reporting`
Chris@0 726 * level warrants, an ErrorException will be thrown.
Chris@0 727 *
Chris@0 728 * Set `errorLoggingLevel` to 0 to prevent logging non-thrown errors. Set it
Chris@0 729 * to any valid error_reporting value to log only errors which match that
Chris@0 730 * level.
Chris@0 731 *
Chris@0 732 * http://php.net/manual/en/function.error-reporting.php
Chris@0 733 *
Chris@0 734 * @return int
Chris@0 735 */
Chris@0 736 public function errorLoggingLevel()
Chris@0 737 {
Chris@0 738 return $this->errorLoggingLevel;
Chris@0 739 }
Chris@0 740
Chris@0 741 /**
Chris@0 742 * Set a CodeCleaner service instance.
Chris@0 743 *
Chris@0 744 * @param CodeCleaner $cleaner
Chris@0 745 */
Chris@0 746 public function setCodeCleaner(CodeCleaner $cleaner)
Chris@0 747 {
Chris@0 748 $this->cleaner = $cleaner;
Chris@0 749 }
Chris@0 750
Chris@0 751 /**
Chris@0 752 * Get a CodeCleaner service instance.
Chris@0 753 *
Chris@0 754 * If none has been explicitly defined, this will create a new instance.
Chris@0 755 *
Chris@0 756 * @return CodeCleaner
Chris@0 757 */
Chris@0 758 public function getCodeCleaner()
Chris@0 759 {
Chris@0 760 if (!isset($this->cleaner)) {
Chris@0 761 $this->cleaner = new CodeCleaner();
Chris@0 762 }
Chris@0 763
Chris@0 764 return $this->cleaner;
Chris@0 765 }
Chris@0 766
Chris@0 767 /**
Chris@0 768 * Enable or disable tab completion.
Chris@0 769 *
Chris@0 770 * @param bool $tabCompletion
Chris@0 771 */
Chris@0 772 public function setTabCompletion($tabCompletion)
Chris@0 773 {
Chris@0 774 $this->tabCompletion = (bool) $tabCompletion;
Chris@0 775 }
Chris@0 776
Chris@0 777 /**
Chris@0 778 * Check whether to use tab completion.
Chris@0 779 *
Chris@0 780 * If `setTabCompletion` has been set to true, but readline is not actually
Chris@0 781 * available, this will return false.
Chris@0 782 *
Chris@0 783 * @return bool True if the current Shell should use tab completion
Chris@0 784 */
Chris@0 785 public function getTabCompletion()
Chris@0 786 {
Chris@0 787 return isset($this->tabCompletion) ? ($this->hasReadline && $this->tabCompletion) : $this->hasReadline;
Chris@0 788 }
Chris@0 789
Chris@0 790 /**
Chris@0 791 * Set the Shell Output service.
Chris@0 792 *
Chris@0 793 * @param ShellOutput $output
Chris@0 794 */
Chris@0 795 public function setOutput(ShellOutput $output)
Chris@0 796 {
Chris@0 797 $this->output = $output;
Chris@0 798 }
Chris@0 799
Chris@0 800 /**
Chris@0 801 * Get a Shell Output service instance.
Chris@0 802 *
Chris@0 803 * If none has been explicitly provided, this will create a new instance
Chris@0 804 * with VERBOSITY_NORMAL and the output page supplied by self::getPager
Chris@0 805 *
Chris@0 806 * @see self::getPager
Chris@0 807 *
Chris@0 808 * @return ShellOutput
Chris@0 809 */
Chris@0 810 public function getOutput()
Chris@0 811 {
Chris@0 812 if (!isset($this->output)) {
Chris@0 813 $this->output = new ShellOutput(
Chris@0 814 ShellOutput::VERBOSITY_NORMAL,
Chris@0 815 $this->getOutputDecorated(),
Chris@0 816 null,
Chris@0 817 $this->getPager()
Chris@0 818 );
Chris@0 819 }
Chris@0 820
Chris@0 821 return $this->output;
Chris@0 822 }
Chris@0 823
Chris@0 824 /**
Chris@0 825 * Get the decoration (i.e. color) setting for the Shell Output service.
Chris@0 826 *
Chris@0 827 * @return null|bool 3-state boolean corresponding to the current color mode
Chris@0 828 */
Chris@0 829 public function getOutputDecorated()
Chris@0 830 {
Chris@0 831 if ($this->colorMode() === self::COLOR_MODE_AUTO) {
Chris@0 832 return;
Chris@0 833 } elseif ($this->colorMode() === self::COLOR_MODE_FORCED) {
Chris@0 834 return true;
Chris@0 835 } elseif ($this->colorMode() === self::COLOR_MODE_DISABLED) {
Chris@0 836 return false;
Chris@0 837 }
Chris@0 838 }
Chris@0 839
Chris@0 840 /**
Chris@0 841 * Set the OutputPager service.
Chris@0 842 *
Chris@0 843 * If a string is supplied, a ProcOutputPager will be used which shells out
Chris@0 844 * to the specified command.
Chris@0 845 *
Chris@0 846 * @throws \InvalidArgumentException if $pager is not a string or OutputPager instance
Chris@0 847 *
Chris@0 848 * @param string|OutputPager $pager
Chris@0 849 */
Chris@0 850 public function setPager($pager)
Chris@0 851 {
Chris@0 852 if ($pager && !is_string($pager) && !$pager instanceof OutputPager) {
Chris@0 853 throw new \InvalidArgumentException('Unexpected pager instance.');
Chris@0 854 }
Chris@0 855
Chris@0 856 $this->pager = $pager;
Chris@0 857 }
Chris@0 858
Chris@0 859 /**
Chris@0 860 * Get an OutputPager instance or a command for an external Proc pager.
Chris@0 861 *
Chris@0 862 * If no Pager has been explicitly provided, and Pcntl is available, this
Chris@0 863 * will default to `cli.pager` ini value, falling back to `which less`.
Chris@0 864 *
Chris@0 865 * @return string|OutputPager
Chris@0 866 */
Chris@0 867 public function getPager()
Chris@0 868 {
Chris@0 869 if (!isset($this->pager) && $this->usePcntl()) {
Chris@0 870 if ($pager = ini_get('cli.pager')) {
Chris@0 871 // use the default pager (5.4+)
Chris@0 872 $this->pager = $pager;
Chris@0 873 } elseif ($less = exec('which less 2>/dev/null')) {
Chris@0 874 // check for the presence of less...
Chris@0 875 $this->pager = $less . ' -R -S -F -X';
Chris@0 876 }
Chris@0 877 }
Chris@0 878
Chris@0 879 return $this->pager;
Chris@0 880 }
Chris@0 881
Chris@0 882 /**
Chris@0 883 * Set the Shell evaluation Loop service.
Chris@0 884 *
Chris@0 885 * @param Loop $loop
Chris@0 886 */
Chris@0 887 public function setLoop(Loop $loop)
Chris@0 888 {
Chris@0 889 $this->loop = $loop;
Chris@0 890 }
Chris@0 891
Chris@0 892 /**
Chris@0 893 * Get a Shell evaluation Loop service instance.
Chris@0 894 *
Chris@0 895 * If none has been explicitly defined, this will create a new instance.
Chris@0 896 * If Pcntl is available and enabled, the new instance will be a ForkingLoop.
Chris@0 897 *
Chris@0 898 * @return Loop
Chris@0 899 */
Chris@0 900 public function getLoop()
Chris@0 901 {
Chris@0 902 if (!isset($this->loop)) {
Chris@0 903 if ($this->usePcntl()) {
Chris@0 904 $this->loop = new ForkingLoop($this);
Chris@0 905 } else {
Chris@0 906 $this->loop = new Loop($this);
Chris@0 907 }
Chris@0 908 }
Chris@0 909
Chris@0 910 return $this->loop;
Chris@0 911 }
Chris@0 912
Chris@0 913 /**
Chris@0 914 * Set the Shell autocompleter service.
Chris@0 915 *
Chris@0 916 * @param AutoCompleter $completer
Chris@0 917 */
Chris@0 918 public function setAutoCompleter(AutoCompleter $completer)
Chris@0 919 {
Chris@0 920 $this->completer = $completer;
Chris@0 921 }
Chris@0 922
Chris@0 923 /**
Chris@0 924 * Get an AutoCompleter service instance.
Chris@0 925 *
Chris@0 926 * @return AutoCompleter
Chris@0 927 */
Chris@0 928 public function getAutoCompleter()
Chris@0 929 {
Chris@0 930 if (!isset($this->completer)) {
Chris@0 931 $this->completer = new AutoCompleter();
Chris@0 932 }
Chris@0 933
Chris@0 934 return $this->completer;
Chris@0 935 }
Chris@0 936
Chris@0 937 /**
Chris@0 938 * Get user specified tab completion matchers for the AutoCompleter.
Chris@0 939 *
Chris@0 940 * @return array
Chris@0 941 */
Chris@0 942 public function getTabCompletionMatchers()
Chris@0 943 {
Chris@0 944 return $this->tabCompletionMatchers;
Chris@0 945 }
Chris@0 946
Chris@0 947 /**
Chris@0 948 * Add additional tab completion matchers to the AutoCompleter.
Chris@0 949 *
Chris@0 950 * @param array $matchers
Chris@0 951 */
Chris@0 952 public function addTabCompletionMatchers(array $matchers)
Chris@0 953 {
Chris@0 954 $this->tabCompletionMatchers = array_merge($this->tabCompletionMatchers, $matchers);
Chris@0 955 if (isset($this->shell)) {
Chris@0 956 $this->shell->addTabCompletionMatchers($this->tabCompletionMatchers);
Chris@0 957 }
Chris@0 958 }
Chris@0 959
Chris@0 960 /**
Chris@0 961 * Add commands to the Shell.
Chris@0 962 *
Chris@0 963 * This will buffer new commands in the event that the Shell has not yet
Chris@0 964 * been instantiated. This allows the user to specify commands in their
Chris@0 965 * config rc file, despite the fact that their file is needed in the Shell
Chris@0 966 * constructor.
Chris@0 967 *
Chris@0 968 * @param array $commands
Chris@0 969 */
Chris@0 970 public function addCommands(array $commands)
Chris@0 971 {
Chris@0 972 $this->newCommands = array_merge($this->newCommands, $commands);
Chris@0 973 if (isset($this->shell)) {
Chris@0 974 $this->doAddCommands();
Chris@0 975 }
Chris@0 976 }
Chris@0 977
Chris@0 978 /**
Chris@0 979 * Internal method for adding commands. This will set any new commands once
Chris@0 980 * a Shell is available.
Chris@0 981 */
Chris@0 982 private function doAddCommands()
Chris@0 983 {
Chris@0 984 if (!empty($this->newCommands)) {
Chris@0 985 $this->shell->addCommands($this->newCommands);
Chris@0 986 $this->newCommands = array();
Chris@0 987 }
Chris@0 988 }
Chris@0 989
Chris@0 990 /**
Chris@0 991 * Set the Shell backreference and add any new commands to the Shell.
Chris@0 992 *
Chris@0 993 * @param Shell $shell
Chris@0 994 */
Chris@0 995 public function setShell(Shell $shell)
Chris@0 996 {
Chris@0 997 $this->shell = $shell;
Chris@0 998 $this->doAddCommands();
Chris@0 999 }
Chris@0 1000
Chris@0 1001 /**
Chris@0 1002 * Set the PHP manual database file.
Chris@0 1003 *
Chris@0 1004 * This file should be an SQLite database generated from the phpdoc source
Chris@0 1005 * with the `bin/build_manual` script.
Chris@0 1006 *
Chris@0 1007 * @param string $filename
Chris@0 1008 */
Chris@0 1009 public function setManualDbFile($filename)
Chris@0 1010 {
Chris@0 1011 $this->manualDbFile = (string) $filename;
Chris@0 1012 }
Chris@0 1013
Chris@0 1014 /**
Chris@0 1015 * Get the current PHP manual database file.
Chris@0 1016 *
Chris@0 1017 * @return string Default: '~/.local/share/psysh/php_manual.sqlite'
Chris@0 1018 */
Chris@0 1019 public function getManualDbFile()
Chris@0 1020 {
Chris@0 1021 if (isset($this->manualDbFile)) {
Chris@0 1022 return $this->manualDbFile;
Chris@0 1023 }
Chris@0 1024
Chris@0 1025 $files = ConfigPaths::getDataFiles(array('php_manual.sqlite'), $this->dataDir);
Chris@0 1026 if (!empty($files)) {
Chris@0 1027 if ($this->warnOnMultipleConfigs && count($files) > 1) {
Chris@0 1028 $msg = sprintf('Multiple manual database files found: %s. Using %s', implode($files, ', '), $files[0]);
Chris@0 1029 trigger_error($msg, E_USER_NOTICE);
Chris@0 1030 }
Chris@0 1031
Chris@0 1032 return $this->manualDbFile = $files[0];
Chris@0 1033 }
Chris@0 1034 }
Chris@0 1035
Chris@0 1036 /**
Chris@0 1037 * Get a PHP manual database connection.
Chris@0 1038 *
Chris@0 1039 * @return \PDO
Chris@0 1040 */
Chris@0 1041 public function getManualDb()
Chris@0 1042 {
Chris@0 1043 if (!isset($this->manualDb)) {
Chris@0 1044 $dbFile = $this->getManualDbFile();
Chris@0 1045 if (is_file($dbFile)) {
Chris@0 1046 try {
Chris@0 1047 $this->manualDb = new \PDO('sqlite:' . $dbFile);
Chris@0 1048 } catch (\PDOException $e) {
Chris@0 1049 if ($e->getMessage() === 'could not find driver') {
Chris@0 1050 throw new RuntimeException('SQLite PDO driver not found', 0, $e);
Chris@0 1051 } else {
Chris@0 1052 throw $e;
Chris@0 1053 }
Chris@0 1054 }
Chris@0 1055 }
Chris@0 1056 }
Chris@0 1057
Chris@0 1058 return $this->manualDb;
Chris@0 1059 }
Chris@0 1060
Chris@0 1061 /**
Chris@0 1062 * Add an array of casters definitions.
Chris@0 1063 *
Chris@0 1064 * @param array $casters
Chris@0 1065 */
Chris@0 1066 public function addCasters(array $casters)
Chris@0 1067 {
Chris@0 1068 $this->getPresenter()->addCasters($casters);
Chris@0 1069 }
Chris@0 1070
Chris@0 1071 /**
Chris@0 1072 * Get the Presenter service.
Chris@0 1073 *
Chris@0 1074 * @return Presenter
Chris@0 1075 */
Chris@0 1076 public function getPresenter()
Chris@0 1077 {
Chris@0 1078 if (!isset($this->presenter)) {
Chris@0 1079 $this->presenter = new Presenter($this->getOutput()->getFormatter(), $this->forceArrayIndexes());
Chris@0 1080 }
Chris@0 1081
Chris@0 1082 return $this->presenter;
Chris@0 1083 }
Chris@0 1084
Chris@0 1085 /**
Chris@0 1086 * Enable or disable warnings on multiple configuration or data files.
Chris@0 1087 *
Chris@0 1088 * @see self::warnOnMultipleConfigs()
Chris@0 1089 *
Chris@0 1090 * @param bool $warnOnMultipleConfigs
Chris@0 1091 */
Chris@0 1092 public function setWarnOnMultipleConfigs($warnOnMultipleConfigs)
Chris@0 1093 {
Chris@0 1094 $this->warnOnMultipleConfigs = (bool) $warnOnMultipleConfigs;
Chris@0 1095 }
Chris@0 1096
Chris@0 1097 /**
Chris@0 1098 * Check whether to warn on multiple configuration or data files.
Chris@0 1099 *
Chris@0 1100 * By default, PsySH will use the file with highest precedence, and will
Chris@0 1101 * silently ignore all others. With this enabled, a warning will be emitted
Chris@0 1102 * (but not an exception thrown) if multiple configuration or data files
Chris@0 1103 * are found.
Chris@0 1104 *
Chris@0 1105 * This will default to true in a future release, but is false for now.
Chris@0 1106 *
Chris@0 1107 * @return bool
Chris@0 1108 */
Chris@0 1109 public function warnOnMultipleConfigs()
Chris@0 1110 {
Chris@0 1111 return $this->warnOnMultipleConfigs;
Chris@0 1112 }
Chris@0 1113
Chris@0 1114 /**
Chris@0 1115 * Set the current color mode.
Chris@0 1116 *
Chris@0 1117 * @param string $colorMode
Chris@0 1118 */
Chris@0 1119 public function setColorMode($colorMode)
Chris@0 1120 {
Chris@0 1121 $validColorModes = array(
Chris@0 1122 self::COLOR_MODE_AUTO,
Chris@0 1123 self::COLOR_MODE_FORCED,
Chris@0 1124 self::COLOR_MODE_DISABLED,
Chris@0 1125 );
Chris@0 1126
Chris@0 1127 if (in_array($colorMode, $validColorModes)) {
Chris@0 1128 $this->colorMode = $colorMode;
Chris@0 1129 } else {
Chris@0 1130 throw new \InvalidArgumentException('invalid color mode: ' . $colorMode);
Chris@0 1131 }
Chris@0 1132 }
Chris@0 1133
Chris@0 1134 /**
Chris@0 1135 * Get the current color mode.
Chris@0 1136 *
Chris@0 1137 * @return string
Chris@0 1138 */
Chris@0 1139 public function colorMode()
Chris@0 1140 {
Chris@0 1141 return $this->colorMode;
Chris@0 1142 }
Chris@0 1143
Chris@0 1144 /**
Chris@0 1145 * Set an update checker service instance.
Chris@0 1146 *
Chris@0 1147 * @param Checker $checker
Chris@0 1148 */
Chris@0 1149 public function setChecker(Checker $checker)
Chris@0 1150 {
Chris@0 1151 $this->checker = $checker;
Chris@0 1152 }
Chris@0 1153
Chris@0 1154 /**
Chris@0 1155 * Get an update checker service instance.
Chris@0 1156 *
Chris@0 1157 * If none has been explicitly defined, this will create a new instance.
Chris@0 1158 *
Chris@0 1159 * @return Checker
Chris@0 1160 */
Chris@0 1161 public function getChecker()
Chris@0 1162 {
Chris@0 1163 if (!isset($this->checker)) {
Chris@0 1164 $interval = $this->getUpdateCheck();
Chris@0 1165 switch ($interval) {
Chris@0 1166 case Checker::ALWAYS:
Chris@0 1167 $this->checker = new GitHubChecker();
Chris@0 1168 break;
Chris@0 1169
Chris@0 1170 case Checker::DAILY:
Chris@0 1171 case Checker::WEEKLY:
Chris@0 1172 case Checker::MONTHLY:
Chris@0 1173 $checkFile = $this->getUpdateCheckCacheFile();
Chris@0 1174 if ($checkFile === false) {
Chris@0 1175 $this->checker = new NoopChecker();
Chris@0 1176 } else {
Chris@0 1177 $this->checker = new IntervalChecker($checkFile, $interval);
Chris@0 1178 }
Chris@0 1179 break;
Chris@0 1180
Chris@0 1181 case Checker::NEVER:
Chris@0 1182 $this->checker = new NoopChecker();
Chris@0 1183 break;
Chris@0 1184 }
Chris@0 1185 }
Chris@0 1186
Chris@0 1187 return $this->checker;
Chris@0 1188 }
Chris@0 1189
Chris@0 1190 /**
Chris@0 1191 * Get the current update check interval.
Chris@0 1192 *
Chris@0 1193 * One of 'always', 'daily', 'weekly', 'monthly' or 'never'. If none is
Chris@0 1194 * explicitly set, default to 'weekly'.
Chris@0 1195 *
Chris@0 1196 * @return string
Chris@0 1197 */
Chris@0 1198 public function getUpdateCheck()
Chris@0 1199 {
Chris@0 1200 return isset($this->updateCheck) ? $this->updateCheck : Checker::WEEKLY;
Chris@0 1201 }
Chris@0 1202
Chris@0 1203 /**
Chris@0 1204 * Set the update check interval.
Chris@0 1205 *
Chris@0 1206 * @throws \InvalidArgumentDescription if the update check interval is unknown
Chris@0 1207 *
Chris@0 1208 * @param string $interval
Chris@0 1209 */
Chris@0 1210 public function setUpdateCheck($interval)
Chris@0 1211 {
Chris@0 1212 $validIntervals = array(
Chris@0 1213 Checker::ALWAYS,
Chris@0 1214 Checker::DAILY,
Chris@0 1215 Checker::WEEKLY,
Chris@0 1216 Checker::MONTHLY,
Chris@0 1217 Checker::NEVER,
Chris@0 1218 );
Chris@0 1219
Chris@0 1220 if (!in_array($interval, $validIntervals)) {
Chris@0 1221 throw new \InvalidArgumentException('invalid update check interval: ' . $interval);
Chris@0 1222 }
Chris@0 1223
Chris@0 1224 $this->updateCheck = $interval;
Chris@0 1225 }
Chris@0 1226
Chris@0 1227 /**
Chris@0 1228 * Get a cache file path for the update checker.
Chris@0 1229 *
Chris@0 1230 * @return string|false Return false if config file/directory is not writable
Chris@0 1231 */
Chris@0 1232 public function getUpdateCheckCacheFile()
Chris@0 1233 {
Chris@0 1234 $dir = $this->configDir ?: ConfigPaths::getCurrentConfigDir();
Chris@0 1235
Chris@0 1236 return ConfigPaths::touchFileWithMkdir($dir . '/update_check.json');
Chris@0 1237 }
Chris@0 1238
Chris@0 1239 /**
Chris@0 1240 * Set the startup message.
Chris@0 1241 *
Chris@0 1242 * @param string $message
Chris@0 1243 */
Chris@0 1244 public function setStartupMessage($message)
Chris@0 1245 {
Chris@0 1246 $this->startupMessage = $message;
Chris@0 1247 }
Chris@0 1248
Chris@0 1249 /**
Chris@0 1250 * Get the startup message.
Chris@0 1251 *
Chris@0 1252 * @return string|null
Chris@0 1253 */
Chris@0 1254 public function getStartupMessage()
Chris@0 1255 {
Chris@0 1256 return $this->startupMessage;
Chris@0 1257 }
Chris@0 1258
Chris@0 1259 /**
Chris@0 1260 * Set the prompt.
Chris@0 1261 *
Chris@0 1262 * @param string $prompt
Chris@0 1263 */
Chris@0 1264 public function setPrompt($prompt)
Chris@0 1265 {
Chris@0 1266 $this->prompt = $prompt;
Chris@0 1267 }
Chris@0 1268
Chris@0 1269 /**
Chris@0 1270 * Get the prompt.
Chris@0 1271 *
Chris@0 1272 * @return string
Chris@0 1273 */
Chris@0 1274 public function getPrompt()
Chris@0 1275 {
Chris@0 1276 return $this->prompt;
Chris@0 1277 }
Chris@0 1278
Chris@0 1279 /**
Chris@0 1280 * Get the force array indexes.
Chris@0 1281 *
Chris@0 1282 * @return bool
Chris@0 1283 */
Chris@0 1284 public function forceArrayIndexes()
Chris@0 1285 {
Chris@0 1286 return $this->forceArrayIndexes;
Chris@0 1287 }
Chris@0 1288
Chris@0 1289 /**
Chris@0 1290 * Set the force array indexes.
Chris@0 1291 *
Chris@0 1292 * @param bool $forceArrayIndexes
Chris@0 1293 */
Chris@0 1294 public function setForceArrayIndexes($forceArrayIndexes)
Chris@0 1295 {
Chris@0 1296 $this->forceArrayIndexes = $forceArrayIndexes;
Chris@0 1297 }
Chris@0 1298 }