summaryrefslogtreecommitdiff
path: root/scripts/console.php
diff options
context:
space:
mode:
authorBrion Vibber <brion@pobox.com>2009-11-06 14:31:39 +0100
committerBrion Vibber <brion@pobox.com>2009-11-06 14:47:22 +0100
commitb932bd6addcf00bec1d9f6a37f3f222a90a726be (patch)
treec6987989a158bc9af61a30562c3fe1d020fd0533 /scripts/console.php
parentfebcdcb6a09afac4e82218d6971378d5302cd0b6 (diff)
console.php terminal script provides interactive PHP console in StatusNet environment, handy for testing!
Uses readline for line input editing if available; falls back to bash+readline if not native, and takes fgets() in worst case. Currently a bit awkward in that each input line is parsed separately, so loops and function defs have to be squished to one line.
Diffstat (limited to 'scripts/console.php')
-rwxr-xr-xscripts/console.php153
1 files changed, 153 insertions, 0 deletions
diff --git a/scripts/console.php b/scripts/console.php
new file mode 100755
index 000000000..e65529a8d
--- /dev/null
+++ b/scripts/console.php
@@ -0,0 +1,153 @@
+#!/usr/bin/env php
+<?php
+/*
+ * StatusNet - the distributed open-source microblogging tool
+ * Copyright (C) 2009, StatusNet, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+# Abort if called from a web server
+
+define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
+
+$helptext = <<<ENDOFHELP
+console.php - provide an interactive PHP interpreter for testing
+
+ENDOFHELP;
+
+require_once INSTALLDIR.'/scripts/commandline.inc';
+
+if (function_exists('posix_isatty')) {
+ define('CONSOLE_INTERACTIVE', posix_isatty(0));
+} else {
+ // Windows? Assume we're on a terminal. :P
+ define('CONSOLE_INTERACTIVE', false);
+}
+if (CONSOLE_INTERACTIVE) {
+ define('CONSOLE_READLINE', function_exists('readline'));
+}
+
+if (CONSOLE_READLINE && CONSOLE_INTERACTIVE && file_exists(CONSOLE_HISTORY)) {
+ define(CONSOLE_HISTORY, getenv("HOME") . "/.statusnet_console_history");
+ readline_read_history(CONSOLE_HISTORY);
+}
+
+function read_input_line($prompt)
+{
+ if (CONSOLE_INTERACTIVE) {
+ if (CONSOLE_READLINE) {
+ $line = readline($prompt);
+ readline_add_history($line);
+ return $line;
+ } else {
+ return readline_emulation($prompt);
+ }
+ } else {
+ return fgets(STDIN);
+ }
+}
+
+/**
+ * On Unix-like systems where PHP readline extension isn't present,
+ * -cough- Mac OS X -cough- we can shell out to bash to do it for us.
+ * This lets us at least handle things like arrow keys, but we don't
+ * get any entry history. :(
+ *
+ * Shamelessly ripped from when I wrote the same code for MediaWiki. :)
+ * @author Brion Vibber <brion@status.net>
+ *
+ * @param string $prompt
+ * @return mixed string on success, false on fail or EOF
+ */
+function readline_emulation($prompt)
+{
+ if(file_exists(trim(shell_exec('which bash')))) {
+ $encPrompt = escapeshellarg($prompt);
+ $command = "read -er -p $encPrompt && echo \"\$REPLY\"";
+ $encCommand = escapeshellarg($command);
+ $metaCommand = "bash -c $encCommand";
+
+ // passthru passes our STDIN and TTY to the child...
+ // We can pull the returned string via output buffering.
+ ob_start();
+ $retval = false;
+ passthru($metaCommand, $retval);
+ $line = ob_get_contents();
+ ob_end_clean();
+
+ if ($retval == 0) {
+ return $line;
+ } elseif ($retval == 127) {
+ // Couldn't execute bash even though we thought we saw it.
+ // Shell probably spit out an error message, sorry :(
+ // Fall through to fgets()...
+ } else {
+ // EOF/ctrl+D
+ return false;
+ }
+ }
+
+ // Fallback... we'll have no editing controls, EWWW
+ if (feof(STDIN)) {
+ return false;
+ }
+ print $prompt;
+ return fgets(STDIN);
+}
+
+function console_help()
+{
+ print "Welcome to StatusNet's interactive PHP console!\n";
+ print "Type some PHP code and it'll run!\n";
+ print "\n";
+ print "Note that PHP is cranky and you can easily kill your session.\n";
+}
+
+
+$prompt = common_config('site', 'name') . '> ';
+while (!feof(STDIN)) {
+ $line = read_input_line($prompt);
+ if ($line === false) {
+ print "\n";
+ break;
+ } elseif ($line !== '') {
+ try {
+ if ($line == 'exit') {
+ break;
+ } elseif ($line == 'help') {
+ console_help();
+ continue;
+ }
+
+ // Let's do this
+ $result = eval($line);
+ if ($result === false) {
+ // parse error
+ } elseif ($result === null) {
+ // no return
+ } else {
+ // return value from eval'd code
+ var_export($result);
+ }
+ } catch(Exception $e) {
+ print get_class($e) . ": " . $e->getMessage() . "\n";
+ }
+ }
+ print "\n";
+}
+
+if (CONSOLE_READLINE && CONSOLE_INTERACTIVE) {
+ @readline_write_history(CONSOLE_HISTORY);
+}