#!/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.
+// This file is part of GNU social - https://www.gnu.org/software/social
+//
+// GNU social 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.
+//
+// GNU social 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 GNU social. If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Description of this file.
*
- * 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/>.
+ * @package samples
+ * @author Diogo Cordeiro <diogo@fc.up.pt>
+ * @copyright 2019 Free Software Foundation, Inc http://www.fsf.org
+ * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
*/
-# Abort if called from a web server
+define('INSTALLDIR', dirname(__DIR__));
+define('PUBLICDIR', INSTALLDIR . DIRECTORY_SEPARATOR . 'public');
+define('GNUSOCIAL', true);
+define('STATUSNET', true);
+
+require_once INSTALLDIR . '/lib/common.php';
+
+// Try to find an autoloader for a local psysh version.
+// We'll wrap this whole mess in a Closure so it doesn't leak any globals.
+call_user_func(function () {
+ $cwd = null;
+
+ // Find the cwd arg (if present)
+ $argv = isset($_SERVER['argv']) ? $_SERVER['argv'] : array();
+ foreach ($argv as $i => $arg) {
+ if ($arg === '--cwd') {
+ if ($i >= count($argv) - 1) {
+ echo 'Missing --cwd argument.' . PHP_EOL;
+ exit(1);
+ }
+ $cwd = $argv[$i + 1];
+ break;
+ }
-define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
+ if (preg_match('/^--cwd=/', $arg)) {
+ $cwd = substr($arg, 6);
+ break;
+ }
+ }
-$helptext = <<<ENDOFHELP
-console.php - provide an interactive PHP interpreter for testing
+ // Or fall back to the actual cwd
+ if (!isset($cwd)) {
+ $cwd = getcwd();
+ }
-ENDOFHELP;
+ $cwd = str_replace('\\', '/', $cwd);
-require_once INSTALLDIR.'/scripts/commandline.inc';
+ $chunks = explode('/', $cwd);
+ while (!empty($chunks)) {
+ $path = implode('/', $chunks);
-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'));
-}
+ // Find composer.json
+ if (is_file($path . '/composer.json')) {
+ if ($cfg = json_decode(file_get_contents($path . '/composer.json'), true)) {
+ if (isset($cfg['name']) && $cfg['name'] === 'psy/psysh') {
+ // We're inside the psysh project. Let's use the local
+ // Composer autoload.
+ if (is_file($path . '/vendor/autoload.php')) {
+ require $path . '/vendor/autoload.php';
+ }
-if (CONSOLE_READLINE && CONSOLE_INTERACTIVE && file_exists(CONSOLE_HISTORY)) {
- define(CONSOLE_HISTORY, getenv("HOME") . "/.statusnet_console_history");
- readline_read_history(CONSOLE_HISTORY);
-}
+ return;
+ }
+ }
+ }
-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);
+ // Or a composer.lock
+ if (is_file($path . '/composer.lock')) {
+ if ($cfg = json_decode(file_get_contents($path . '/composer.lock'), true)) {
+ foreach (array_merge($cfg['packages'], $cfg['packages-dev']) as $pkg) {
+ if (isset($pkg['name']) && $pkg['name'] === 'psy/psysh') {
+ // We're inside a project which requires psysh. We'll
+ // use the local Composer autoload.
+ if (is_file($path . '/vendor/autoload.php')) {
+ require $path . '/vendor/autoload.php';
+ }
+
+ return;
+ }
+ }
+ }
}
+
+ array_pop($chunks);
+ }
+});
+
+// We didn't find an autoloader for a local version, so use the autoloader that
+// came with this script.
+if (!class_exists('Psy\Shell')) {
+ /* <<< */
+ if (is_file(__DIR__ . '/../vendor/autoload.php')) {
+ require __DIR__ . '/../vendor/autoload.php';
+ } elseif (is_file(__DIR__ . '/../../../autoload.php')) {
+ require __DIR__ . '/../../../autoload.php';
} else {
- return fgets(STDIN);
+ echo 'PsySH dependencies not found, be sure to run `composer install`.' . PHP_EOL;
+ echo 'See https://getcomposer.org to get Composer.' . PHP_EOL;
+ exit(1);
}
+ /* >>> */
}
-/**
- * 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);
+// If the psysh binary was included directly, assume they just wanted an
+// autoloader and bail early.
+if (version_compare(PHP_VERSION, '5.3.6', '<')) {
+ $trace = debug_backtrace();
+} elseif (version_compare(PHP_VERSION, '5.4.0', '<')) {
+ $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
+} else {
+ $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
}
-function console_help()
-{
- print "Welcome to StatusNet's interactive PHP console!\n";
- print "Type some PHP code and it'll execute...\n";
- print "\n";
- print "Hint: return a value of any type to output it via var_export():\n";
- print " \$profile = new Profile();\n";
- print " \$profile->find();\n";
- print " \$profile->fetch();\n";
- print " return \$profile;\n";
- print "\n";
- print "Note that PHP is cranky and you can easily kill your session by mistyping.\n";
- print "\n";
- print "Type ctrl+D or enter 'exit' to exit.\n";
+if (Psy\Shell::isIncluded($trace)) {
+ unset($trace);
+
+ return;
}
+// Clean up after ourselves.
+unset($trace);
-print "StatusNet interactive PHP console... type ctrl+D or enter 'exit' to exit.\n";
-$prompt = common_config('site', 'name') . '> ';
-while (!feof(STDIN)) {
- $line = read_input_line($prompt);
- if ($line === false) {
- print "\n";
- break;
- } elseif ($line !== '') {
- try {
- if (trim($line) == 'exit') {
- break;
- } elseif (trim($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";
- }
+// If the local version is too old, we can't do this
+if (!function_exists('Psy\bin')) {
+ $argv = $_SERVER['argv'];
+ $first = array_shift($argv);
+ if (preg_match('/php(\.exe)?$/', $first)) {
+ array_shift($argv);
}
- print "\n";
-}
+ array_unshift($argv, 'vendor/bin/psysh');
-if (CONSOLE_READLINE && CONSOLE_INTERACTIVE) {
- @readline_write_history(CONSOLE_HISTORY);
+ echo 'A local PsySH dependency was found, but it cannot be loaded. Please update to' . PHP_EOL;
+ echo 'the latest version, or run the local copy directly, e.g.:' . PHP_EOL;
+ echo PHP_EOL;
+ echo ' ' . implode(' ', $argv) . PHP_EOL;
+ exit(1);
}
+
+// And go!
+call_user_func(Psy\bin());