Chris@13: historyFile = ($historyFile !== null) ? $historyFile : false; Chris@13: $this->historySize = $historySize; Chris@13: $this->eraseDups = $eraseDups; Chris@13: } Chris@13: Chris@13: /** Chris@13: * {@inheritdoc} Chris@13: */ Chris@13: public function addHistory($line) Chris@13: { Chris@17: if ($res = \readline_add_history($line)) { Chris@13: $this->writeHistory(); Chris@13: } Chris@13: Chris@13: return $res; Chris@13: } Chris@13: Chris@13: /** Chris@13: * {@inheritdoc} Chris@13: */ Chris@13: public function clearHistory() Chris@13: { Chris@17: if ($res = \readline_clear_history()) { Chris@13: $this->writeHistory(); Chris@13: } Chris@13: Chris@13: return $res; Chris@13: } Chris@13: Chris@13: /** Chris@13: * {@inheritdoc} Chris@13: */ Chris@13: public function listHistory() Chris@13: { Chris@13: return readline_list_history(); Chris@13: } Chris@13: Chris@13: /** Chris@13: * {@inheritdoc} Chris@13: */ Chris@13: public function readHistory() Chris@13: { Chris@13: // Workaround PHP bug #69054 Chris@13: // Chris@13: // If open_basedir is set, readline_read_history() segfaults. This was fixed in 5.6.7: Chris@13: // Chris@13: // https://github.com/php/php-src/blob/423a057023ef3c00d2ffc16a6b43ba01d0f71796/NEWS#L19-L21 Chris@13: // Chris@17: if (\version_compare(PHP_VERSION, '5.6.7', '>=') || !\ini_get('open_basedir')) { Chris@17: \readline_read_history(); Chris@13: } Chris@17: \readline_clear_history(); Chris@13: Chris@17: return \readline_read_history($this->historyFile); Chris@13: } Chris@13: Chris@13: /** Chris@13: * {@inheritdoc} Chris@13: */ Chris@13: public function readline($prompt = null) Chris@13: { Chris@17: return \readline($prompt); Chris@13: } Chris@13: Chris@13: /** Chris@13: * {@inheritdoc} Chris@13: */ Chris@13: public function redisplay() Chris@13: { Chris@17: \readline_redisplay(); Chris@13: } Chris@13: Chris@13: /** Chris@13: * {@inheritdoc} Chris@13: */ Chris@13: public function writeHistory() Chris@13: { Chris@13: // We have to write history first, since it is used Chris@13: // by Libedit to list history Chris@13: if ($this->historyFile !== false) { Chris@17: $res = \readline_write_history($this->historyFile); Chris@13: } else { Chris@13: $res = true; Chris@13: } Chris@13: Chris@13: if (!$res || !$this->eraseDups && !$this->historySize > 0) { Chris@13: return $res; Chris@13: } Chris@13: Chris@13: $hist = $this->listHistory(); Chris@13: if (!$hist) { Chris@13: return true; Chris@13: } Chris@13: Chris@13: if ($this->eraseDups) { Chris@13: // flip-flip technique: removes duplicates, latest entries win. Chris@17: $hist = \array_flip(\array_flip($hist)); Chris@13: // sort on keys to get the order back Chris@17: \ksort($hist); Chris@13: } Chris@13: Chris@13: if ($this->historySize > 0) { Chris@17: $histsize = \count($hist); Chris@13: if ($histsize > $this->historySize) { Chris@17: $hist = \array_slice($hist, $histsize - $this->historySize); Chris@13: } Chris@13: } Chris@13: Chris@17: \readline_clear_history(); Chris@13: foreach ($hist as $line) { Chris@17: \readline_add_history($line); Chris@13: } Chris@13: Chris@13: if ($this->historyFile !== false) { Chris@17: return \readline_write_history($this->historyFile); Chris@13: } Chris@13: Chris@13: return true; Chris@13: } Chris@13: }