You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

254 lines
6.2 KiB

<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP
*
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014-2019 British Columbia Institute of Technology
* Copyright (c) 2019 CodeIgniter Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @package CodeIgniter
* @author CodeIgniter Dev Team
* @copyright 2019 CodeIgniter Foundation
* @license https://opensource.org/licenses/MIT MIT License
* @link https://codeigniter.com
* @since Version 4.0.0
* @filesource
*/
namespace CodeIgniter\HTTP;
use Config\App;
/**
* Class CLIRequest
*
* Represents a request from the command-line. Provides additional
* tools to interact with that request since CLI requests are not
* static like HTTP requests might be.
*
* Portions of this code were initially from the FuelPHP Framework,
* version 1.7.x, and used here under the MIT license they were
* originally made available under.
*
* http://fuelphp.com
*
* @package CodeIgniter\HTTP
*/
class CLIRequest extends Request
{
/**
* Stores the segments of our cli "URI" command.
*
* @var array
*/
protected $segments = [];
/**
* Command line options and their values.
*
* @var array
*/
protected $options = [];
/**
* Set the expected HTTP verb
*
* @var string
*/
protected $method = 'cli';
//--------------------------------------------------------------------
/**
* Constructor
*
* @param App $config
*/
public function __construct(App $config)
{
parent::__construct($config);
// Don't terminate the script when the cli's tty goes away
ignore_user_abort(true);
$this->parseCommand();
}
//--------------------------------------------------------------------
/**
* Returns the "path" of the request script so that it can be used
* in routing to the appropriate controller/method.
*
* The path is determined by treating the command line arguments
* as if it were a URL - up until we hit our first option.
*
* Example:
* php index.php users 21 profile -foo bar
*
* // Routes to /users/21/profile (index is removed for routing sake)
* // with the option foo = bar.
*
* @return string
*/
public function getPath(): string
{
$path = implode('/', $this->segments);
return empty($path) ? '' : $path;
}
//--------------------------------------------------------------------
/**
* Returns an associative array of all CLI options found, with
* their values.
*
* @return array
*/
public function getOptions(): array
{
return $this->options;
}
//--------------------------------------------------------------------
/**
* Returns the path segments.
*
* @return array
*/
public function getSegments(): array
{
return $this->segments;
}
//--------------------------------------------------------------------
/**
* Returns the value for a single CLI option that was passed in.
*
* @param string $key
*
* @return string|null
*/
public function getOption(string $key)
{
return $this->options[$key] ?? null;
}
//--------------------------------------------------------------------
/**
* Returns the options as a string, suitable for passing along on
* the CLI to other commands.
*
* Example:
* $options = [
* 'foo' => 'bar',
* 'baz' => 'queue some stuff'
* ];
*
* getOptionString() = '-foo bar -baz "queue some stuff"'
*
* @return string
*/
public function getOptionString(): string
{
if (empty($this->options))
{
return '';
}
$out = '';
foreach ($this->options as $name => $value)
{
// If there's a space, we need to group
// so it will pass correctly.
if (strpos($value, ' ') !== false)
{
$value = '"' . $value . '"';
}
$out .= "-{$name} $value ";
}
return trim($out);
}
//--------------------------------------------------------------------
/**
* Parses the command line it was called from and collects all options
* and valid segments.
*
* NOTE: I tried to use getopt but had it fail occasionally to find
* any options, where argv has always had our back.
*/
protected function parseCommand()
{
// Since we're building the options ourselves,
// we stop adding it to the segments array once
// we have found the first dash.
$options_found = false;
$argc = $this->getServer('argc', FILTER_SANITIZE_NUMBER_INT);
$argv = $this->getServer('argv');
// We start at 1 since we never want to include index.php
for ($i = 1; $i < $argc; $i ++)
{
// If there's no '-' at the beginning of the argument
// then add it to our segments.
if (! $options_found && strpos($argv[$i], '-') === false)
{
$this->segments[] = filter_var($argv[$i], FILTER_SANITIZE_STRING);
continue;
}
$options_found = true;
if (strpos($argv[$i], '-') !== 0)
{
continue;
}
$arg = filter_var(str_replace('-', '', $argv[$i]), FILTER_SANITIZE_STRING);
$value = null;
// If the next item starts with a dash it's a value
if (isset($argv[$i + 1]) && strpos($argv[$i + 1], '-') !== 0)
{
$value = filter_var($argv[$i + 1], FILTER_SANITIZE_STRING);
$i ++;
}
$this->options[$arg] = $value;
}
}
//--------------------------------------------------------------------
}