annotate vendor/psy/psysh/src/Configuration.php @ 0:c75dbcec494b

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