Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9241098247 | |||
| e5fd8beec4 | |||
|
|
0ba68a1e1e | ||
|
|
1470b39076 | ||
|
|
82bc933a0c | ||
|
|
23909f688e | ||
|
|
b128b0ffd7 | ||
|
|
f50eb13b5f | ||
|
|
ea0170bc9d | ||
|
|
bc41f385c2 | ||
|
|
21db58bbf2 | ||
|
|
7a95a5ba21 | ||
|
|
c299a11456 | ||
|
|
cc93e649a8 | ||
|
|
b4638e688a |
6
.gitignore
vendored
6
.gitignore
vendored
@@ -1 +1,7 @@
|
||||
build/
|
||||
docs/
|
||||
composer.phar
|
||||
composer.lock
|
||||
ast.dump
|
||||
changes
|
||||
vendor/
|
||||
|
||||
@@ -7,13 +7,18 @@
|
||||
|
||||
|
||||
define("OVERWATCH_ROOT", dirname(__FILE__));
|
||||
define("OVERWATCH_LIBRARIES", OVERWATCH_ROOT."/lib");
|
||||
define("OVERWATCH_MODULES", OVERWATCH_LIBRARIES."/modules/");
|
||||
define("OVERWATCH_LIBRARIES", OVERWATCH_ROOT.DIRECTORY_SEPARATOR."lib");
|
||||
define("OVERWATCH_MODULES", OVERWATCH_LIBRARIES.DIRECTORY_SEPARATOR."modules".DIRECTORY_SEPARATOR);
|
||||
// Load in module support and required classes.
|
||||
require_once "vendor/autoload.php";
|
||||
require_once OVERWATCH_LIBRARIES."/libModOverwatch.class.php";
|
||||
require_once OVERWATCH_LIBRARIES."/libOverwatchAPI.class.php";
|
||||
require_once OVERWATCH_LIBRARIES."/libAPIQL.class.php";
|
||||
require_once OVERWATCH_LIBRARIES.DIRECTORY_SEPARATOR."libModOverwatch.class.php";
|
||||
require_once OVERWATCH_LIBRARIES.DIRECTORY_SEPARATOR."libOverwatchAPI.class.php";
|
||||
require_once OVERWATCH_LIBRARIES.DIRECTORY_SEPARATOR."libAPIQL.class.php";
|
||||
require_once OVERWATCH_ROOT.DIRECTORY_SEPARATOR."sdk".DIRECTORY_SEPARATOR."OverwatchSDK.inc.php";
|
||||
if(\Overwatch\SDK\Manager::isSDK_Installed("1") == false)
|
||||
{
|
||||
die("OverwatchSDK is missing, possibly a bad build, or tree?");
|
||||
}
|
||||
use Noodlehaus\Config;
|
||||
echo PHP_EOL;
|
||||
|
||||
@@ -26,12 +31,11 @@ $application_channel = "release";
|
||||
|
||||
|
||||
// Load version information from built-in version file. (used for releases)
|
||||
$version = file_get_contents(OVERWATCH_ROOT."/build/version");
|
||||
if(file_exists(OVERWATCH_ROOT.DIRECTORY_SEPARATOR."build".DIRECTORY_SEPARATOR."version"))
|
||||
{
|
||||
$version = file_get_contents(OVERWATCH_ROOT.DIRECTORY_SEPARATOR."build".DIRECTORY_SEPARATOR."version");
|
||||
}
|
||||
|
||||
// Define engine version so that plugins can check against it.
|
||||
// We will want to define the local version information (built into the phar if compiled)
|
||||
// rather than the git version, unless there's a decent way to compare versions provided by git describe.
|
||||
define("OVERWATCH_VERSION", $version);
|
||||
|
||||
// Load (or override local) version information using git repository.
|
||||
if (file_exists(".git")) {
|
||||
@@ -39,34 +43,34 @@ if (file_exists(".git")) {
|
||||
$application_channel = "dev";
|
||||
}
|
||||
|
||||
// Define engine version so that plugins can check against it.
|
||||
// We will want to define the local version information (built into the phar if compiled)
|
||||
// rather than the git version, unless there's a decent way to compare versions provided by git describe.
|
||||
define("OVERWATCH_VERSION", $version);
|
||||
|
||||
|
||||
// Load the core version from the phar if we're running compiled.
|
||||
$coreversion = file_get_contents(OVERWATCH_ROOT."/build/core-version");
|
||||
|
||||
// Now we'll define the core version of the software as well.
|
||||
|
||||
$version = str_replace(PHP_EOL, "", $version);
|
||||
LogEcho("Overwatchd startup, version: $version (built from: $coreversion), channel: $application_channel", "OVERWATCH");
|
||||
|
||||
/**
|
||||
* Allows a "pretty-print" style output.
|
||||
* @param mixed $str Log message.
|
||||
* @param mixed $level Log level or specific part of application.
|
||||
*/
|
||||
function LogEcho($str, $level) {
|
||||
$str = str_replace(PHP_EOL, "", $str);
|
||||
$level = str_replace(PHP_EOL, "", $level);
|
||||
echo "[$level] $str".PHP_EOL;
|
||||
if(file_exists(OVERWATCH_ROOT.DIRECTORY_SEPARATOR."build".DIRECTORY_SEPARATOR."core-version"))
|
||||
{
|
||||
$coreversion = file_get_contents(OVERWATCH_ROOT.DIRECTORY_SEPARATOR."build".DIRECTORY_SEPARATOR."core-version");
|
||||
} else {
|
||||
$coreversion = $version;
|
||||
}
|
||||
|
||||
|
||||
LogEcho("Loading built-in API Modules...", "OVERWATCH");
|
||||
LoadAPIModules(OVERWATCH_MODULES);
|
||||
// Now we'll define the core version of the software as well.
|
||||
|
||||
$coreversion = str_replace(array("\n", "\r"), "", $coreversion);
|
||||
$version = str_replace(array("\n", "\r"), "", $version);
|
||||
\Overwatch\SDK\v1\Utility::Log("Overwatchd startup, version: $version (built from: $coreversion), channel: $application_channel", "OVERWATCH");
|
||||
|
||||
|
||||
|
||||
// We look for a system-wide configuration file for the daemon in /etc. If one is not available,
|
||||
// we then skip it.
|
||||
if(file_exists(__FILE__."/overwatchd.conf.dist"))
|
||||
if(file_exists(__FILE__.DIRECTORY_SEPARATOR."overwatchd.conf.dist"))
|
||||
{
|
||||
$configFiles = array(__FILE__."/overwatchd.conf.dist");
|
||||
$configFiles = array(__FILE__.DIRECTORY_SEPARATOR."overwatchd.conf.dist");
|
||||
}
|
||||
|
||||
if(file_exists("/etc/overwatchd.conf"))
|
||||
@@ -74,9 +78,9 @@ if(file_exists("/etc/overwatchd.conf"))
|
||||
array_push($configFiles,"/etc/overwatchd.conf");
|
||||
}
|
||||
|
||||
if(file_exists(__FILE__."/overwatchd.conf"))
|
||||
if(file_exists(__FILE__.DIRECTORY_SEPARATOR."overwatchd.conf"))
|
||||
{
|
||||
array_push($configFiles,__FILE__."/overwatchd.conf");
|
||||
array_push($configFiles,__FILE__.DIRECTOR_SEPARATOR."overwatchd.conf");
|
||||
}
|
||||
|
||||
if(isset($configFiles))
|
||||
@@ -90,17 +94,19 @@ if(isset($configFiles))
|
||||
|
||||
if(array_key_exists("DEBUG",$arrOverwatch_Config) OR $application_channel == "dev")
|
||||
{
|
||||
if($arrOverwatch_Config['DEBUG'] == "true")
|
||||
if(array_key_exists("DEBUG", $arrOverwatch_Config) AND $arrOverwatch_Config['DEBUG'] == "true")
|
||||
{
|
||||
define("DEBUG",true);
|
||||
LogEcho("Enabling debug mode due to configuration flag..", "DEBUG");
|
||||
\Overwatch\SDK\v1\Utility::Log("Enabling debug mode due to configuration flag..", "DEBUG");
|
||||
} elseif ($application_channel == "dev")
|
||||
{
|
||||
define("DEBUG", true);
|
||||
LogEcho("We're running under the dev channel. Debug Ahoy!", "DEBUG");
|
||||
\Overwatch\SDK\v1\Utility::Log("We're running under the dev channel. Debug Ahoy!", "DEBUG");
|
||||
}
|
||||
|
||||
}
|
||||
\Overwatch\SDK\v1\Utility::Log("Loading built-in API Modules...", "OVERWATCH");
|
||||
LoadAPIModules(OVERWATCH_MODULES);
|
||||
|
||||
LoadModulesFromConfiguration();
|
||||
$state = array();
|
||||
@@ -110,12 +116,29 @@ $state = array();
|
||||
if(defined("DEBUG"))
|
||||
{
|
||||
error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE);
|
||||
apiql::register("!SHUTDOWN", "Shutdown");
|
||||
apiql::register("!SHUTDOWN[json]", "Shutdown");
|
||||
$quit == 2;
|
||||
} else {
|
||||
error_reporting(0);
|
||||
}
|
||||
|
||||
function is_base64($str) {
|
||||
|
||||
if (!preg_match('~[^0-9a-zA-Z+/=]~', $str)) {
|
||||
|
||||
$check = str_split(base64_decode($str));
|
||||
|
||||
$x = 0;
|
||||
|
||||
foreach ($check as $char) if (ord($char) > 126) $x++;
|
||||
|
||||
if ($x/count($check)*100 < 30) return true;
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
// Let's set up the event loop
|
||||
$loop = React\EventLoop\Factory::create();
|
||||
@@ -130,20 +153,21 @@ $socket->on('connection', function($connection) use ($clients, &$i) {
|
||||
// Socket Listener
|
||||
$connection->on('data', function($message) use ($clients, $connection) {
|
||||
$connection->lastAPI = str_replace(array("\n", "\r\n", "\r"), '', $message);
|
||||
if ( base64_encode(base64_decode($connection->lastAPI, true)) === $connection->lastAPI){
|
||||
if(DEBUG)
|
||||
{
|
||||
LogEcho("Raw data from conection: $connection->id, $connection->lastAPI","S2S-COMMS-DEBUG");
|
||||
}
|
||||
|
||||
$connection->lastAPI = base64_decode($connection->lastAPI);
|
||||
}
|
||||
if(strtoupper($connection->lastAPI) != strtoupper("shutdown"))
|
||||
if(strpos($connection->lastAPI, " {") == 0)
|
||||
{
|
||||
if (is_base64($connection->lastAPI) == true) {
|
||||
\Overwatch\SDK\v1\Utility::Log("Raw data from conection: $connection->id, $connection->lastAPI","S2S-COMMS-DEBUG",\Overwatch\SDK\v1\Utility::OVR_UTIL_LOGLEVEL_DEBUG);
|
||||
$connection->lastAPI = base64_decode($connection->lastAPI);
|
||||
}
|
||||
}
|
||||
|
||||
$connection->lastAPI = str_replace("'", "\"", $connection->lastAPI);
|
||||
# Let's pull apart the current request to check for a connection-id item. If it doesn't exist, we'll inject it in.
|
||||
$command = explode ("{", $connection->lastAPI, 2);
|
||||
$commandJSON = json_decode("{".$command[1], true);
|
||||
$command = explode (" {", $connection->lastAPI, 2);
|
||||
if(isset($command[1]))
|
||||
{
|
||||
$commandJSON = json_decode("{".$command[1], true);
|
||||
}
|
||||
if(!isset($commandJSON['connection-id']))
|
||||
{
|
||||
$commandJSON['connection-id'] = $connection->id;
|
||||
@@ -152,12 +176,8 @@ $socket->on('connection', function($connection) use ($clients, &$i) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
$connection->lastResult = apicall($connection->lastAPI);
|
||||
LogEcho("Received query: ".$connection->lastAPI." from ".$connection->id, "SOCKET-API");
|
||||
\Overwatch\SDK\v1\Utility::Log("Received query: ".$connection->lastAPI." from ".$connection->id, "SOCKET-API");
|
||||
foreach ($clients as $client) {
|
||||
if ($client->id == $connection->id) {
|
||||
if($connection->lastResult != NULL)
|
||||
@@ -181,7 +201,7 @@ if (empty($arrOverwatch_Config['API_PORT'])) {
|
||||
// Start listening on the configured port.
|
||||
$socket->listen($API_PORT, "0.0.0.0");
|
||||
|
||||
LogEcho("Server listening on port: $API_PORT", "OVERWATCH");
|
||||
\Overwatch\SDK\v1\Utility::Log("Server listening on port: $API_PORT", "OVERWATCH");
|
||||
// Now we begin the actual event loop.
|
||||
$loop->run();
|
||||
|
||||
@@ -190,7 +210,7 @@ $loop->run();
|
||||
*
|
||||
* @return unknown
|
||||
*/
|
||||
function Shutdown() {
|
||||
function Shutdown($sql) {
|
||||
global $quit;
|
||||
global $loop;
|
||||
$loop->stop();
|
||||
@@ -222,6 +242,10 @@ function APIcall($call, $apiKey = null) {
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if(is_array($APIResponse))
|
||||
{
|
||||
$APIResponse = json_encode($APIResponse);
|
||||
}
|
||||
return $APIResponse;
|
||||
}
|
||||
}
|
||||
@@ -231,12 +255,12 @@ function LoadModulesFromConfiguration()
|
||||
global $arrOverwatch_Config;
|
||||
if(array_key_exists("MODULES_DIR", $arrOverwatch_Config))
|
||||
{
|
||||
LogEcho("External module directory defined, loading external modules...","OVERWATCH");
|
||||
\Overwatch\SDK\v1\Utility::Log("External module directory defined, loading external modules...","OVERWATCH");
|
||||
LoadAPIModules($arrOverwatch_Config['MODULES_DIR']);
|
||||
}
|
||||
if(array_key_exists("SYSTEM_MODULES_DIR", $arrOverwatch_Config))
|
||||
{
|
||||
LogEcho("Loading modules from system store: ".$arrOverwatch_Config['SYSTEM_MODULES_DIR']);
|
||||
\Overwatch\SDK\v1\Utility::Log("Loading modules from system store: ".$arrOverwatch_Config['SYSTEM_MODULES_DIR']);
|
||||
LoadAPIModules($arrOverwatch_Config['SYSTEM_MODULES_DIR']);
|
||||
}
|
||||
}
|
||||
|
||||
34
Todo.md
Normal file
34
Todo.md
Normal file
@@ -0,0 +1,34 @@
|
||||
- Fix PHAR builds, require_once statements need absolute path (libOverwatchAPI.class.php:8)
|
||||
- Complete current functionality refactor (RPC handling, APIQL raw calling, module replacement)
|
||||
- Move the S2S infrastructure out of the Server2Server module and into a psuedo-module (meaning it's registered with APIQL as if it were a built-in module, but it's actually a built-in part of the core SDK, and will open a Server2Server listening socket on psuedo-module load up).
|
||||
- Build new "kernel" infrastructure, which abstracts out ReactPHP into an easier to manage framework for the SDK.
|
||||
- Provide thread (event loop) management
|
||||
- Provide connection management
|
||||
- Provide OSA (Operating System Abstraction) Layer to provide full cross-platform support.
|
||||
- Provide hookable events infrastructure using ReactPHP to provide system-wide hooks for modules
|
||||
- Provide a centralized configuration interface.
|
||||
- Enhance ModuleBoilerplate
|
||||
- Allow modules to declare system requirement checks, and then perform them using the OSAL to abstract commands
|
||||
- Allow modules to specify required operating system, free memory, etc.
|
||||
- Allow modules to specify runtime extensions (PHP)
|
||||
- Allow modules to require the daemon be granted administrative privileges to perform.
|
||||
- Allow modules to specify kernel types (server, standalone-noasync, etc) to allow for scripts and applications using the Overwatch SDK.
|
||||
- Allow modules to react to signals from the kernel infrastructure.
|
||||
- Allow modules to declare query help strings in their docblock, and have it exposed by the system.
|
||||
- Allow modules to opt-in to S2S usage, as opposed to all commands being readily accessible from the source.
|
||||
- Enhance ModuleLoader
|
||||
- Allow modules to be stored in standalone Phar archives, this will allow for a cleaner modules directory.
|
||||
- Allow built-in modules to started in a disabled state, and not registered with APIQL until enabled.
|
||||
- Enhance API Call System
|
||||
- Allow query definitions to be de-registered from the system on module unload. This will prevent the module from being called even though it's supposed to be "unloaded" and in an uninitialized state.
|
||||
- Provide a "test query" function to allow the Server to Server infrastructure to ask the APIQL library if a query can be handled by it's core.
|
||||
- Enhance the Server to Server infrastructure.
|
||||
- The server to server infrastructure running on each overwatch SDK powered server, should keep a state-machine with the modules and versions loaded on each connected server. It should also provide a synchronization architecture for synchronizing the state of the modules between each server.
|
||||
- Provide a server to server event handling infrastructure. Perhaps in a separate event loop.
|
||||
|
||||
## Module Development Guidelines
|
||||
|
||||
1. Modules must NEVER call to the connection write themselves, they should use the connection handling system in the SDK.
|
||||
2. Modules must NEVER create/parse the response/request jacket around the resulting JSON themselves.
|
||||
3. Modules must NOT attempt to parse the raw TCP data.
|
||||
4. Modules should not write to the screen without the use of the Overwatch SDK utility class.
|
||||
4
build-docs
Executable file
4
build-docs
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
vendor/bin/phpdoc -d ./sdk -t ./docs/html/sdk-server --title="Overwatch API Server SDK" --template=clean
|
||||
vendor/bin/phpdoc -d ./sdk -t ./docs/xml/sdk-server --title="Overwatch API Server SDK" --template=xml
|
||||
|
||||
6
changes
6
changes
@@ -1,6 +0,0 @@
|
||||
8-31-2015
|
||||
---------
|
||||
Overwatch has now moved out of pre-alpha status and into Milestone 1. Basic functionality of the API Host daemon is complete.
|
||||
Milestone 1 will have development focused on module support and APIs.
|
||||
|
||||
Please remember, The Overwatch daemon is still a private project.
|
||||
6
compile-executable.cmd
Normal file
6
compile-executable.cmd
Normal file
@@ -0,0 +1,6 @@
|
||||
@ECHO OFF
|
||||
git describe > .\build\core-version
|
||||
|
||||
git tag > .\build\version
|
||||
|
||||
vendor\bin\phar-builder.bat package composer.json
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"minimum-stability": "dev",
|
||||
"minimum-stability": "alpha",
|
||||
"require": {
|
||||
"react/react": "^0.4.2",
|
||||
"react/http": "^0.4.1",
|
||||
@@ -9,10 +9,14 @@
|
||||
"ext-bcmath": "*",
|
||||
"symfony/polyfill-mbstring": "^1.2",
|
||||
"hassankhan/config": "^0.10.0",
|
||||
"react/filesystem": "dev-master"
|
||||
"react/filesystem": "dev-master",
|
||||
"zetacomponents/document": "^1.3",
|
||||
"phpdocumentor/reflection": "^3.0",
|
||||
"nikic/php-parser": "1.*"
|
||||
},
|
||||
"require-dev": {
|
||||
"macfja/phar-builder": "^0.2.4"
|
||||
"macfja/phar-builder": "^0.2.4",
|
||||
"phpdocumentor/phpdocumentor": "2.*"
|
||||
},
|
||||
"extra": {
|
||||
"phar-builder": {
|
||||
@@ -20,7 +24,7 @@
|
||||
"name": "overwatchd.phar",
|
||||
"output-dir": "../",
|
||||
"entry-point": "Ov3rw4tch.class.php",
|
||||
"include": ["lib","build"],
|
||||
"include": ["lib","build","sdk"],
|
||||
"include-dev": false
|
||||
}
|
||||
}
|
||||
|
||||
1820
composer.lock
generated
1820
composer.lock
generated
File diff suppressed because it is too large
Load Diff
BIN
composer.phar
BIN
composer.phar
Binary file not shown.
@@ -1,35 +0,0 @@
|
||||
<?php
|
||||
|
||||
abstract class API_Definition {
|
||||
|
||||
|
||||
|
||||
|
||||
public function module_loaded()
|
||||
{
|
||||
static $attempted = null;
|
||||
$processUser = posix_getpwuid(posix_geteuid());
|
||||
if($attempted == true)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if(isset($this->needs_root) and $this->needs_root != "false")
|
||||
{
|
||||
if($processUser['name'] == "root")
|
||||
{
|
||||
self::API_Register();
|
||||
$attempted = true;
|
||||
} else {
|
||||
$attempted = true;
|
||||
}
|
||||
} else {
|
||||
self::API_Register();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
abstract public function API_Register();
|
||||
}
|
||||
?>
|
||||
@@ -1,13 +1,12 @@
|
||||
<?php
|
||||
include("libAPIQL.class.php");
|
||||
include("libAPIDefinition.class.php");
|
||||
|
||||
if(!defined("OVERWATCH_ROOT"))
|
||||
{
|
||||
die("This library requires the Overwatch SDK.");
|
||||
}
|
||||
|
||||
$module = ModuleLoader::startInst();
|
||||
require_once("sdk/v1/OverwatchServerSDK.v1.inc.php");
|
||||
$module = \Overwatch\SDK\v1\ModuleLoader::startInst();
|
||||
$modules = array();
|
||||
function LoadAPIModules($path = OVERWATCH_MODULES)
|
||||
{
|
||||
@@ -19,19 +18,19 @@ function LoadAPIModules($path = OVERWATCH_MODULES)
|
||||
if(defined("DEBUG"))
|
||||
{
|
||||
if($modulename != "." && $modulename != "..") {
|
||||
LogEcho("Module found: $modulename", "API");
|
||||
\Overwatch\SDK\v1\Utility::Log("Module found: $modulename", "API");
|
||||
}
|
||||
}
|
||||
if(is_dir($path."$modulename") && $modulename != "." && $modulename != "..")
|
||||
{
|
||||
LogEcho("Loading Module: $modulename", "API");
|
||||
\Overwatch\SDK\v1\Utility::Log("Loading Module: $modulename", "API");
|
||||
$modules[$modulename] = $module->loadModule($modulename);
|
||||
if(is_object($modules[$modulename]) && $modules[$modulename]->module_loaded())
|
||||
if(is_object($modules[$modulename]))
|
||||
{
|
||||
// We're good here
|
||||
if(defined("DEBUG"))
|
||||
{
|
||||
LogEcho("API Module Loaded: $modulename", "OVERWATCH");
|
||||
\Overwatch\SDK\v1\Utility::Log("API Module Loaded: $modulename", "OVERWATCH");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
a:2:{s:7:"setting";s:32:"713f82c4d3dd6a2caef0bb576a88951f";s:5:"files";a:1:{s:27:"InputDeviceServices.API.php";s:32:"398b6fceb26b4d2476de53cebc6b77ed";}}
|
||||
@@ -1,221 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* InputDeviceServices.API.php
|
||||
* Provides Input Device Mirroring for Devices, entirely in Userspace.
|
||||
* @package default
|
||||
*/
|
||||
|
||||
|
||||
$inputserver_sock = null;
|
||||
$inputserver_ref = null;
|
||||
$inputclients = null;
|
||||
$inputserver_sock = null;
|
||||
$inputserver_conn = null;
|
||||
$stream = null;
|
||||
class InputDeviceServices {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @return unknown
|
||||
*/
|
||||
function loadInst() {
|
||||
static $inst = null;
|
||||
|
||||
if ($inst === null) {
|
||||
$inst = new self;
|
||||
}
|
||||
return $inst;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @return unknown
|
||||
*/
|
||||
function module_loaded() {
|
||||
static $attempted = null;
|
||||
$processUser = posix_getpwuid(posix_geteuid());
|
||||
if($attempted == true)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if($processUser['name'] == "root")
|
||||
{
|
||||
self::API_Register();
|
||||
$attempted = true;
|
||||
} else {
|
||||
LogEcho("InputDeviceServices requires Overwatchd to be running as root.", "InputDeviceServices");
|
||||
$attempted = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function API_Register() {
|
||||
apiql::register("!OPEN/!INPUT/!SERVER[json]", "InputDeviceServices::InputServer");
|
||||
apiql::register("!CLOSE/!INPUT/!SERVER", "InputDeviceServices::CloseInputServer");
|
||||
apiql::register("!CONNECT/!INPUT/!DEVICES[json]", "InputDeviceServices::Connect");
|
||||
apiql::register("!DISCONNECT/!INPUT/!DEVICES", "InputDeviceServices::Disconnect");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param unknown $sql
|
||||
* @return unknown
|
||||
*/
|
||||
function CloseInputServer($sql) {
|
||||
global $inputserver_ref;
|
||||
global $inputserver_sock;
|
||||
$inputserver_sock->shutdown();
|
||||
$inputserver_ref->terminate();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
function InputServer($sql) {
|
||||
//echo(var_dump($sql));
|
||||
global $loop;
|
||||
global $clients;
|
||||
global $inputserver_ref;
|
||||
global $inputserver_sock;
|
||||
global $inputclients;
|
||||
$keyboard = $sql['SERVER']['keyboard'];
|
||||
$mouse = $sql['SERVER']['mouse'];
|
||||
$inputserver_ref = new React\ChildProcess\Process('exec /opt/uinput-mapper/input-read '.$keyboard.' -G '.$mouse.' -D -C');
|
||||
$inputserver_ref->on('exit', function($exitCode, $termSignal) use ($clients) {
|
||||
$ResponseArray = array("response_type"=>"success",
|
||||
"response_msg"=>"Event server has stopped.",
|
||||
"response_code"=>"EVT_201",
|
||||
"event_server_status"=>"stopped");
|
||||
foreach ($clients as $client) {
|
||||
$client->write(json_encode($ResponseArray)."\r\n");
|
||||
}
|
||||
return json_encode($ResponseArray);
|
||||
});
|
||||
|
||||
$inputserver_sock = new React\Socket\Server($loop);
|
||||
$inputclients = new SplObjectStorage();
|
||||
$i = 0;
|
||||
$inputserver_sock->on('connection', function($connection) use ($inputclients, &$i) {
|
||||
global $inputserver_ref;
|
||||
global $loop;
|
||||
|
||||
LogEcho("Connection to Event Server.", "INPUTS");
|
||||
$connection->id = ++$i;
|
||||
$connection->on('end',function() use ($inputserver_ref) {
|
||||
$inputserver_ref->terminate();
|
||||
});
|
||||
$inputclients->attach($connection);
|
||||
|
||||
if($inputserver_ref->isRunning() == false)
|
||||
{$inputserver_ref->start($loop);}
|
||||
|
||||
$inputserver_ref->stdout->on('data', function($output) use ($inputclients, $connection, &$i) {
|
||||
global $inputclients;
|
||||
foreach ($inputclients as $inputclient) {
|
||||
if ($inputclient->id == $connection->id) {
|
||||
$inputclient->write($output);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
});
|
||||
$inputserver_ref->stderr->on('data', function($output) {
|
||||
if($output != "") LogEcho($output,"INPUTS");
|
||||
});
|
||||
});
|
||||
$inputserver_sock->listen("5055", "0.0.0.0");
|
||||
LogEcho("Event server started on port 5055", "INPUTS");
|
||||
|
||||
//$loop->addTimer(0.001, function($timer) use ($inputserver_ref) {
|
||||
|
||||
//});
|
||||
if($sql['SERVER']['client-string-return'] = 'true')
|
||||
{
|
||||
return "CONNECT INPUT DEVICES {'host':'".gethostname()."', 'port': 5055}";
|
||||
}
|
||||
|
||||
$ResponseArray = array("response_type"=>"success",
|
||||
"response_msg"=>"Event server started on port 5055",
|
||||
"response_code"=>"EVT_200",
|
||||
"event_server_port"=>5055,
|
||||
"event_server_status"=>"started");
|
||||
return json_encode($ResponseArray);
|
||||
}
|
||||
|
||||
function Connect($sql) {
|
||||
$IP = $sql['DEVICES']['host'];
|
||||
$PORT = $sql['DEVICES']['port'];
|
||||
global $loop;
|
||||
global $input_client_process;
|
||||
global $input_client;
|
||||
global $stream;
|
||||
//$client = new steam_socket_client('tcp://'.$IP.":".$PORT);
|
||||
//$client_connection = new React\Stream\Steam($client, $loop);
|
||||
$input_client_process = new React\ChildProcess\Process('/opt/uinput-mapper/input-create -C');
|
||||
$input_client_process->start($loop);
|
||||
$input_client_process->stderr->on('data', function ($output) {
|
||||
if($output != "") LogEcho($output,"INPUTC");
|
||||
});
|
||||
|
||||
$dnsResolverFactory = new React\Dns\Resolver\Factory();
|
||||
$dns = $dnsResolverFactory->createCached($IP, $loop);
|
||||
|
||||
$input_client = new React\SocketClient\Connector($loop, $dns);
|
||||
$input_client->create($IP, $PORT)->then(function (React\Stream\Stream $stream) use ($IP, $PORT) {
|
||||
LogEcho("Connected to event server on: ".$IP. ":". $PORT,"INPUTC");
|
||||
|
||||
$GLOBALS['stream'] = $stream;
|
||||
|
||||
$stream->on('data', function($data) {
|
||||
global $input_client_process;
|
||||
#if(defined("DEBUG")) LogEcho($data, "INPUTC");
|
||||
$input_client_process->stdin->write($data);
|
||||
});
|
||||
});
|
||||
|
||||
#$netcat_process = new React\ChildProcess\Process('exec nc '.$IP.' '.$PORT);
|
||||
#$netcat_process->start($loop);
|
||||
#$netcat_process->stdout->on('data', function($output) {
|
||||
# $input_client_process->stdin->write($output);
|
||||
# });
|
||||
|
||||
//$connection->on('data', function($output) {
|
||||
// $client_process->stdin->write($output);
|
||||
//});
|
||||
$ResponseArray = array("response_type"=>"success",
|
||||
"response_msg"=>"Successfully connected to Event Server socket.",
|
||||
"response_code"=>"EVT_200C");
|
||||
|
||||
return json_encode($ResponseArray);
|
||||
|
||||
}
|
||||
|
||||
|
||||
function Disconnect($sql) {
|
||||
global $input_client_process;
|
||||
global $input_client;
|
||||
global $stream;
|
||||
|
||||
$input_client_process->terminate();
|
||||
$stream->end();
|
||||
//$input_client->end();
|
||||
$ResponseArray = array("response_type"=>"success",
|
||||
"response_msg"=>"Successfully disconnected from Event Server socket.",
|
||||
"response_code"=>"EVT_200D");
|
||||
|
||||
return json_encode($ResponseArray);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
#!/bin/bash
|
||||
/opt/uinput-mapper/input-read $1 -G $2 -D | nc -l 5055
|
||||
19
lib/modules/NullDriver/NullDriver.API.php
Normal file
19
lib/modules/NullDriver/NullDriver.API.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
class NullDriver extends \Overwatch\SDK\v1\ModuleBoilerplate {
|
||||
|
||||
public static $moduleType = "API";
|
||||
public const requires_root = false;
|
||||
static function Initialize()
|
||||
{
|
||||
\Overwatch\SDK\v1\Utility::Log("NullDriver::Initialize()", "NullDriver-Plugin", \Overwatch\SDK\v1\Utility::OVR_UTIL_LOGLEVEL_DEBUG);
|
||||
}
|
||||
|
||||
static function API_Register()
|
||||
{
|
||||
\Overwatch\SDK\v1\Utility::Log("NullDriver::API_Register()", "NullDriver-Plugin", \Overwatch\SDK\v1\Utility::OVR_UTIL_LOGLEVEL_DEBUG);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -18,7 +18,14 @@ class Server2Server {
|
||||
public function module_loaded()
|
||||
{
|
||||
static $attempted = null;
|
||||
$processUser = posix_getpwuid(posix_geteuid());
|
||||
|
||||
if(file_exists("/etc"))
|
||||
{
|
||||
$processUser = posix_getpwuid(posix_geteuid());
|
||||
} else {
|
||||
$processUser = "root";
|
||||
}
|
||||
|
||||
if($attempted == true)
|
||||
{
|
||||
return true;
|
||||
@@ -72,13 +79,13 @@ class Server2Server {
|
||||
|
||||
$S2SConnection = new React\SocketClient\Connector($loop, $dns);
|
||||
$S2SConnection->create($sql['QUERY']['server'], 1337)->then(function (React\Stream\Stream $stream) use ($sql, &$connection, $connectionId) {
|
||||
LogEcho("Connection ".$connectionId." requested connection to Overwatchd instance: ".$sql['QUERY']['server'].":1337, Query: ".$sql['QUERY']['query'],"Server2Server-Comms");
|
||||
\Overwatch\SDK\v1\Utility::Log("Connection ".$connectionId." requested connection to Overwatchd instance: ".$sql['QUERY']['server'].":1337, Query: ".$sql['QUERY']['query'],"Server2Server-Comms");
|
||||
$buf = "";
|
||||
$sent = false;
|
||||
$stream->on('data', function($data) use ($sql,&$connection,$connectionId,$stream,&$sent) {
|
||||
|
||||
#$data = $buf;
|
||||
LogEcho("Data to connection $connectionId: $data", "S2S-DEBUG");
|
||||
\Overwatch\SDK\v1\Utility::Log("Data to connection $connectionId: $data", "S2S-DEBUG");
|
||||
|
||||
/*
|
||||
if(is_json($data))
|
||||
@@ -108,7 +115,7 @@ class Server2Server {
|
||||
$sent = true;
|
||||
});
|
||||
if ( base64_encode(base64_decode($sql['QUERY']['query'], true)) !== $sql['QUERY']['query']){
|
||||
#LogEcho("Raw data from conection: $connection->id, $connection->lastAPI","S2S-COMMS");
|
||||
#\Overwatch\SDK\v1\Utility::Log("Raw data from conection: $connection->id, $connection->lastAPI","S2S-COMMS");
|
||||
$sql['QUERY']['query'] = base64_encode($sql['QUERY']['query']);
|
||||
}
|
||||
$stream->write($sql['QUERY']['query']);
|
||||
|
||||
@@ -64,8 +64,10 @@ class SystemServices {
|
||||
function GetSystemInfo() {
|
||||
$state['linfo'] = new \Linfo\Linfo;
|
||||
$state['linfo_parser'] = $state['linfo']->getParser();
|
||||
|
||||
$OSArray = parse_ini_file("/etc/os-release");
|
||||
if(file_exists("/etc/os-release")) { $OSArray = parse_ini_file("/etc/os-release");
|
||||
} else {
|
||||
$OSArray = "Windows";
|
||||
}
|
||||
$OverwatchVer = constant("OVERWATCH_VERSION");
|
||||
$KernelVer = $state['linfo_parser']->getKernel();
|
||||
$KernelArch = $state['linfo_parser']->getCPUArchitecture();
|
||||
@@ -75,7 +77,6 @@ class SystemServices {
|
||||
$Devices = $state['linfo_parser']->getDevs();
|
||||
$Network = $state['linfo_parser']->getNet();
|
||||
$Battery = $state['linfo_parser']->getBattery();
|
||||
$Model = $state['linfo_parser']->getModel();
|
||||
$SysInfo = array('OS'=>$OSArray,
|
||||
'DaemonVersion'=>$OverwatchVer,
|
||||
'Kernel'=>$KernelVer,
|
||||
@@ -85,8 +86,7 @@ class SystemServices {
|
||||
'Sensors'=>$Sensors,
|
||||
'Devices'=>$Devices,
|
||||
'Network'=>$Network,
|
||||
'Battery'=>$Battery,
|
||||
'Model'=>$Model);
|
||||
'Battery'=>$Battery);
|
||||
$ResponseArray = array("response_type"=>"success",
|
||||
"response_content"=>$SysInfo,
|
||||
"response_code"=>200);
|
||||
|
||||
@@ -44,11 +44,122 @@ class WorkstationServices {
|
||||
|
||||
}
|
||||
|
||||
function Libretine_InstallPackage($sql) {}
|
||||
function Libertine_InstallPackage($sql) {
|
||||
if(!file_exists("/userdata"))
|
||||
{
|
||||
// As Libertine is ONLY to be used on Ubuntu for Mobile devices, this command will error if it is used without a utouch device.
|
||||
$ResponseArray['response_type'] = "error";
|
||||
$ResponseArray['response_msg'] = "This machine is not an Ubuntu Touch workstation, Libertine commands are only available on Ubuntu Touch.";
|
||||
$ResponseArray['response_code'] = 500;
|
||||
return json_encode($ResponseArray);
|
||||
}
|
||||
|
||||
$process = new React\ChildProcess\Process('exec libertine-container-manager install-package -p "'.$sql['PACKAGE']['package']);
|
||||
$programRequestCode = sha1("INSTALL_LIBERTINE_".$sql['PACKAGE']['package']);
|
||||
$ResponseArray = array();
|
||||
$ResponseArray['response_process_marker'] = $programRequestCode;
|
||||
|
||||
$process->on('exit', function($exitCode, $termSignal) use ($ResponseArray) {
|
||||
global $clients;
|
||||
if($exitCode == 0)
|
||||
{
|
||||
$ResponseArray['response_type'] = "success";
|
||||
$ResponseArray['response_code'] = "LCM_200E";
|
||||
} else {
|
||||
$ResponseArray['response_type'] = "failed";
|
||||
$ResponseArray['response_code'] = "LCM_500E";
|
||||
}
|
||||
$ResponseArray['response_exit_code'] = $exitCode;
|
||||
foreach ($clients as $client)
|
||||
{
|
||||
$client->write(json_encode($ResponseArray));
|
||||
}
|
||||
});
|
||||
$process->stdout->on('data', function($output) use ($ResponseArray) {
|
||||
global $clients;
|
||||
$ResponseArray['response_type'] = "status";
|
||||
$ResponseArray['response_msg'] = $output;
|
||||
$ResponseArray['response_code'] = "LCM_STDO";
|
||||
foreach ($clients as $client)
|
||||
{
|
||||
$client->write(json_encode($ResponseArray));
|
||||
}
|
||||
});
|
||||
|
||||
$process->stderr->on('data', function($output) use ($ResponseArray) {
|
||||
global $clients;
|
||||
$ResponseArray['response_type'] = "status";
|
||||
$ResponseArray['response_msg'] = $output;
|
||||
$ResponseArray['response_code'] = "LCM_STDE";
|
||||
foreach ($clients as $client)
|
||||
{
|
||||
$client->write(json_encode($ResponseArray));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function Libertine_RemovePackage($sql) {}
|
||||
function Libertine_RemovePackage($sql) {
|
||||
if(!file_exists("/userdata"))
|
||||
{
|
||||
// As Libertine is ONLY to be used on Ubuntu for Mobile devices, this command will error if it is used without a utouch device.
|
||||
$ResponseArray['response_type'] = "error";
|
||||
$ResponseArray['response_msg'] = "This machine is not an Ubuntu Touch workstation, Libertine commands are only available on Ubuntu Touch.";
|
||||
$ResponseArray['response_code'] = 500;
|
||||
return json_encode($ResponseArray);
|
||||
}
|
||||
$process = new React\ChildProcess\Process('exec libertine-container-manager remove-package -p "'.$sql['PACKAGE']);
|
||||
$programRequestCode = sha1("REMOVE_LIBERTINE_".$sql['PACKAGE']);
|
||||
$ResponseArray = array();
|
||||
$ResponseArray['response_process_marker'] = $programRequestCode;
|
||||
|
||||
$process->on('exit', function($exitCode, $termSignal) use ($ResponseArray) {
|
||||
global $clients;
|
||||
if($exitCode == 0)
|
||||
{
|
||||
$ResponseArray['response_type'] = "success";
|
||||
$ResponseArray['response_code'] = "LCM_200E";
|
||||
} else {
|
||||
$ResponseArray['response_type'] = "failed";
|
||||
$ResponseArray['response_code'] = "LCM_500E";
|
||||
}
|
||||
$ResponseArray['response_exit_code'] = $exitCode;
|
||||
foreach ($clients as $client)
|
||||
{
|
||||
$client->write(json_encode($ResponseArray));
|
||||
}
|
||||
});
|
||||
$process->stdout->on('data', function($output) use ($ResponseArray) {
|
||||
global $clients;
|
||||
$ResponseArray['response_type'] = "status";
|
||||
$ResponseArray['response_msg'] = $output;
|
||||
$ResponseArray['response_code'] = "LCM_STDO";
|
||||
foreach ($clients as $client)
|
||||
{
|
||||
$client->write(json_encode($ResponseArray));
|
||||
}
|
||||
});
|
||||
|
||||
$process->stderr->on('data', function($output) use ($ResponseArray) {
|
||||
global $clients;
|
||||
$ResponseArray['response_type'] = "status";
|
||||
$ResponseArray['response_msg'] = $output;
|
||||
$ResponseArray['response_code'] = "LCM_STDE";
|
||||
foreach ($clients as $client)
|
||||
{
|
||||
$client->write(json_encode($ResponseArray));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function Libertine_CreateContainer($sql) {
|
||||
if(!file_exists("/userdata"))
|
||||
{
|
||||
// As Libertine is ONLY to be used on Ubuntu for Mobile devices, this command will error if it is used without a utouch device.
|
||||
$ResponseArray['response_type'] = "error";
|
||||
$ResponseArray['response_msg'] = "This machine is not an Ubuntu Touch workstation, Libertine commands are only available on Ubuntu Touch.";
|
||||
$ResponseArray['response_code'] = 500;
|
||||
return json_encode($ResponseArray);
|
||||
}
|
||||
if(isset($sql['CONTAINER']['container-settings']['id'])) $ContainerID = 'applications';
|
||||
if(isset($sql['CONTAINER']['container-settings']['name'])) $ContainerName = 'Applications';
|
||||
|
||||
@@ -56,6 +167,14 @@ class WorkstationServices {
|
||||
|
||||
function Libertine_ConfAptRepository($sql)
|
||||
{
|
||||
if(!file_exists("/userdata"))
|
||||
{
|
||||
// As Libertine is ONLY to be used on Ubuntu for Mobile devices, this command will error if it is used without a utouch device.
|
||||
$ResponseArray['response_type'] = "error";
|
||||
$ResponseArray['response_msg'] = "This machine is not an Ubuntu Touch workstation, Libertine commands are only available on Ubuntu Touch.";
|
||||
$ResponseArray['response_code'] = 500;
|
||||
return json_encode($ResponseArray);
|
||||
}
|
||||
if($sql['REPOSITORY']['operation'] == "add") $process = new React\ChildProcess\Process('exec sudo -u phablet libertine-container-manager configure -a '.$sql['REPOSITORY']['repository']);
|
||||
if($sql['REPOSITORY']['operation'] == "del" OR $sql['REPOSITORY']['operation'] == "delete") $process = new React\ChildProcess\Process('exec sudo -u phablet libertine-container-manager configure -d '.$sql['REPOSITORY']['repository']);
|
||||
if(!$process)
|
||||
@@ -93,6 +212,14 @@ class WorkstationServices {
|
||||
|
||||
function Libertine_GetContainers($sql)
|
||||
{
|
||||
if(!file_exists("/userdata"))
|
||||
{
|
||||
// As Libertine is ONLY to be used on Ubuntu for Mobile devices, this command will error if it is used without a utouch device.
|
||||
$ResponseArray['response_type'] = "error";
|
||||
$ResponseArray['response_msg'] = "This machine is not an Ubuntu Touch workstation, Libertine commands are only available on Ubuntu Touch.";
|
||||
$ResponseArray['response_code'] = 500;
|
||||
return json_encode($ResponseArray);
|
||||
}
|
||||
if(file_exists("/home/phablet/.local/share/libertine/ContainersConfig.json"))
|
||||
{
|
||||
$ContainersConfig = file_get_contents("/home/phablet/.local/share/libertine/ContainersConfig.json");
|
||||
@@ -117,7 +244,7 @@ class WorkstationServices {
|
||||
|
||||
} else { continue; }
|
||||
}
|
||||
$ResponseArray = array("resposne_type"=>"success",
|
||||
$ResponseArray = array("response_type"=>"success",
|
||||
"response_data"=>$ContainerArray,
|
||||
"response_code"=>"LCM_200S");
|
||||
|
||||
@@ -144,6 +271,14 @@ class WorkstationServices {
|
||||
function Libertine_ExecContainer($sql)
|
||||
{
|
||||
global $loop;
|
||||
if(!file_exists("/userdata"))
|
||||
{
|
||||
// As Libertine is ONLY to be used on Ubuntu for Mobile devices, this command will error if it is used without a utouch device.
|
||||
$ResponseArray['response_type'] = "error";
|
||||
$ResponseArray['response_msg'] = "This machine is not an Ubuntu Touch workstation, Libertine commands are only available on Ubuntu Touch.";
|
||||
$ResponseArray['response_code'] = 500;
|
||||
return json_encode($ResponseArray);
|
||||
}
|
||||
$process = new React\ChildProcess\Process('exec libertine-container-manager exec -c "'.$sql['CONTAINER']['command']);
|
||||
$programRequestCode = sha1($sql['CONTAINER']['command']);
|
||||
$ResponseArray = array();
|
||||
@@ -159,7 +294,7 @@ class WorkstationServices {
|
||||
$ResponseArray['response_type'] = "failed";
|
||||
$ResponseArray['response_code'] = "LCM_500E";
|
||||
}
|
||||
$ResponseArray['libertine_exit_code'] = $exitCode;
|
||||
$ResponseArray['response_exit_code'] = $exitCode;
|
||||
foreach ($clients as $client)
|
||||
{
|
||||
$client->write(json_encode($ResponseArray));
|
||||
@@ -204,11 +339,19 @@ class WorkstationServices {
|
||||
*/
|
||||
function SetLauncherIcon($sql) {
|
||||
$DesktopArray = $sql['ICON'];
|
||||
|
||||
if (!file_exists("/home/phablet")) {
|
||||
$ErrorArray = array("response_type"=>"error", "error_msg"=>"This device is not an Ubuntu Touch workstation.", "error_code"=>505);
|
||||
return json_encode($ErrorArray);
|
||||
if(!file_exists("/etc"))
|
||||
{
|
||||
// We're not running a unix-based OS, error out.
|
||||
$ResponseArray = array("response_type"=>"error", "response_msg"=>"Members of the Windows family are not yet supported by this module.", "response_code"=>500);
|
||||
return $ResponseArray;
|
||||
}
|
||||
|
||||
/** As we're going to be expanding Overwatch's reach to all systems, the below code will eventually need to be optimized."
|
||||
* if (!file_exists("/home/phablet")) {
|
||||
* $ErrorArray = array("response_type"=>"error", "error_msg"=>"This device is not an Ubuntu Touch workstation.", "error_code"=>505);
|
||||
* return json_encode($ErrorArray);
|
||||
* }
|
||||
**/
|
||||
|
||||
if (!file_exists("/home/phablet/.local/share/applications/".$DesktopArray['name'].".desktop")) {
|
||||
$ErrorArray = array("response_type"=>"error", "error_msg"=>"Desktop File does not Exist.", "error_code"=>404);
|
||||
@@ -233,7 +376,7 @@ class WorkstationServices {
|
||||
//});
|
||||
file_put_contents($destination, $fileContents);
|
||||
$MD5 = md5_file($destination);
|
||||
LogEcho("Uploaded MD5: ".$fileMD5.", Local MD5:".$MD5, "WorkstationServices");
|
||||
\Overwatch\SDK\v1\Utility::Log("Uploaded MD5: ".$fileMD5.", Local MD5:".$MD5, "WorkstationServices");
|
||||
if ($MD5 != $fileMD5) {
|
||||
$ErrorArray = array("response_type"=>"error",
|
||||
"error_msg"=>"MD5 Checksums do not match. File may be corrupt.",
|
||||
@@ -255,6 +398,13 @@ class WorkstationServices {
|
||||
|
||||
|
||||
function GetFreeSpace($sql) {
|
||||
if($sql['SPACE']['volume'] == null)
|
||||
{
|
||||
$responseArray = array ("response_type"=>"error",
|
||||
"response_msg"=>"You need to supply a volume.",
|
||||
"response_code"=>500);
|
||||
return json_encode($responseArray);
|
||||
}
|
||||
$resultArray = array("response_type"=>"success",
|
||||
"response_msg"=>disk_free_space($sql['SPACE']['volume']),
|
||||
"response_code"=>200);
|
||||
@@ -263,6 +413,13 @@ class WorkstationServices {
|
||||
|
||||
|
||||
function GetStorageCapacity($sql) {
|
||||
if($sql['SPACE']['volume'] == null)
|
||||
{
|
||||
$responseArray = array ("response_type"=>"error",
|
||||
"response_msg"=>"You need to supply a volume.",
|
||||
"response_code"=>500);
|
||||
return json_encode($responseArray);
|
||||
}
|
||||
$resultArray = array("response_type"=>"success",
|
||||
"response_msg"=>disk_total_space($sql['SPACE']['volume']),
|
||||
"response_code"=>200);
|
||||
@@ -272,7 +429,12 @@ class WorkstationServices {
|
||||
|
||||
function CreateDesktopFile($sql) {
|
||||
// Check for the existance of the requested .desktop file.
|
||||
|
||||
if(!file_exists("/etc"))
|
||||
{
|
||||
// We're not running a unix-based OS, error out.
|
||||
$ResponseArray = array("response_type"=>"error", "response_msg"=>"Members of the Windows family are not yet supported by this module.", "response_code"=>500);
|
||||
return $ResponseArray;
|
||||
}
|
||||
$DesktopArray = $sql['SHORTCUT'];
|
||||
if (!file_exists("/usr/share/applications/".$DesktopArray['name'].".desktop")) {
|
||||
$ErrorArray = array("response_type"=>"error","error_msg"=>"Desktop File does not Exist.", "error_code"=>404);
|
||||
@@ -295,6 +457,12 @@ class WorkstationServices {
|
||||
|
||||
|
||||
function RemoveDesktopFile($sql) {
|
||||
if(!file_exists("/etc"))
|
||||
{
|
||||
// We're not running a unix-based OS, error out.
|
||||
$ResponseArray = array("response_type"=>"error", "response_msg"=>"Members of the Windows family are not yet supported by this module.", "response_code"=>500);
|
||||
return $ResponseArray;
|
||||
}
|
||||
$DesktopArray = $sql['SHORTCUT'];
|
||||
unlink("/home/phablet/.local/share/applications/".$DesktopArray['name'].".desktop");
|
||||
}
|
||||
|
||||
@@ -1,564 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* PHP Hooks Class
|
||||
*
|
||||
* The PHP Hooks Class is a fork of the WordPress filters hook system rolled in to a class to be ported
|
||||
* into any php based system
|
||||
*
|
||||
* This class is heavily based on the WordPress plugin API and most (if not all) of the code comes from there.
|
||||
*
|
||||
*
|
||||
* @version 0.1.3
|
||||
* @copyright 2012 - 2014
|
||||
* @author Ohad Raz (email: admin@bainternet.info)
|
||||
* @link http://en.bainternet.info
|
||||
*
|
||||
* @license GNU General Public LIcense v3.0 - license.txt
|
||||
* 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 NON-INFRINGEMENT. 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 PHP Hooks
|
||||
*/
|
||||
if (!class_exists('Hooks')){
|
||||
/**
|
||||
* Hooks
|
||||
*/
|
||||
class Hooks
|
||||
{
|
||||
/**
|
||||
* $filters holds list of hooks
|
||||
* @access public
|
||||
* @since 0.1
|
||||
* @var array
|
||||
*/
|
||||
var $filters = array();
|
||||
/**
|
||||
* $merged_filters
|
||||
* @var array
|
||||
*/
|
||||
var $merged_filters = array();
|
||||
/**
|
||||
* $actions
|
||||
* @var array
|
||||
*/
|
||||
var $actions = array();
|
||||
/**
|
||||
* $current_filter holds the name of the current filter
|
||||
* @access public
|
||||
* @since 0.1
|
||||
* @var array
|
||||
*/
|
||||
var $current_filter = array();
|
||||
|
||||
/**
|
||||
* __construct class constructor
|
||||
* @access public
|
||||
* @since 0.1
|
||||
*/
|
||||
public function __construct($args = null)
|
||||
{
|
||||
$this->filters = array();
|
||||
$this->merged_filters = array();
|
||||
$this->actions = array();
|
||||
$this->current_filter = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* FILTERS
|
||||
*/
|
||||
|
||||
/**
|
||||
* add_filter Hooks a function or method to a specific filter action.
|
||||
* @access public
|
||||
* @since 0.1
|
||||
* @param string $tag The name of the filter to hook the $function_to_add to.
|
||||
* @param callback $function_to_add The name of the function to be called when the filter is applied.
|
||||
* @param int $priority optional. Used to specify the order in which the functions associated with a particular action are executed (default: 10). Lower numbers correspond with earlier execution, and functions with the same priority are executed in the order in which they were added to the action.
|
||||
* @param int $accepted_args optional. The number of arguments the function accept (default 1).
|
||||
* @return boolean true
|
||||
*/
|
||||
public function add_filter($tag, $function_to_add, $priority = 10, $accepted_args = 1) {
|
||||
$idx = $this->_filter_build_unique_id($tag, $function_to_add, $priority);
|
||||
$this->filters[$tag][$priority][$idx] = array('function' => $function_to_add, 'accepted_args' => $accepted_args);
|
||||
unset( $this->merged_filters[ $tag ] );
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* remove_filter Removes a function from a specified filter hook.
|
||||
* @access public
|
||||
* @since 0.1
|
||||
* @param string $tag The filter hook to which the function to be removed is hooked.
|
||||
* @param callback $function_to_remove The name of the function which should be removed.
|
||||
* @param int $priority optional. The priority of the function (default: 10).
|
||||
* @param int $accepted_args optional. The number of arguments the function accepts (default: 1).
|
||||
* @return boolean Whether the function existed before it was removed.
|
||||
*/
|
||||
public function remove_filter( $tag, $function_to_remove, $priority = 10 ) {
|
||||
$function_to_remove = $this->_filter_build_unique_id($tag, $function_to_remove, $priority);
|
||||
|
||||
$r = isset($this->filters[$tag][$priority][$function_to_remove]);
|
||||
|
||||
if ( true === $r) {
|
||||
unset($this->filters[$tag][$priority][$function_to_remove]);
|
||||
if ( empty($this->filters[$tag][$priority]) )
|
||||
unset($this->filters[$tag][$priority]);
|
||||
unset($this->merged_filters[$tag]);
|
||||
}
|
||||
return $r;
|
||||
}
|
||||
/**
|
||||
* remove_all_filters Remove all of the hooks from a filter.
|
||||
* @access public
|
||||
* @since 0.1
|
||||
* @param string $tag The filter to remove hooks from.
|
||||
* @param int $priority The priority number to remove.
|
||||
* @return bool True when finished.
|
||||
*/
|
||||
public function remove_all_filters($tag, $priority = false) {
|
||||
if( isset($this->filters[$tag]) ) {
|
||||
if( false !== $priority && isset($this->filters[$tag][$priority]) )
|
||||
unset($this->filters[$tag][$priority]);
|
||||
else
|
||||
unset($this->filters[$tag]);
|
||||
}
|
||||
|
||||
if( isset($this->merged_filters[$tag]) )
|
||||
unset($this->merged_filters[$tag]);
|
||||
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* has_filter Check if any filter has been registered for a hook.
|
||||
* @access public
|
||||
* @since 0.1
|
||||
* @param string $tag The name of the filter hook.
|
||||
* @param callback $function_to_check optional.
|
||||
* @return mixed If $function_to_check is omitted, returns boolean for whether the hook has anything registered.
|
||||
* When checking a specific function, the priority of that hook is returned, or false if the function is not attached.
|
||||
* When using the $function_to_check argument, this function may return a non-boolean value that evaluates to false
|
||||
* (e.g.) 0, so use the === operator for testing the return value.
|
||||
*/
|
||||
public function has_filter($tag, $function_to_check = false) {
|
||||
$has = !empty($this->filters[$tag]);
|
||||
if ( false === $function_to_check || false == $has )
|
||||
return $has;
|
||||
|
||||
if ( !$idx = $this->_filter_build_unique_id($tag, $function_to_check, false) )
|
||||
return false;
|
||||
|
||||
foreach ( (array) array_keys($this->filters[$tag]) as $priority ) {
|
||||
if ( isset($this->filters[$tag][$priority][$idx]) )
|
||||
return $priority;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* apply_filters Call the functions added to a filter hook.
|
||||
* @access public
|
||||
* @since 0.1
|
||||
* @param string $tag The name of the filter hook.
|
||||
* @param mixed $value The value on which the filters hooked to <tt>$tag</tt> are applied on.
|
||||
* @param mixed $var,... Additional variables passed to the functions hooked to <tt>$tag</tt>.
|
||||
* @return mixed The filtered value after all hooked functions are applied to it.
|
||||
*/
|
||||
public function apply_filters($tag, $value) {
|
||||
$args = array();
|
||||
// Do 'all' actions first
|
||||
if ( isset($this->filters['all']) ) {
|
||||
$this->current_filter[] = $tag;
|
||||
$args = func_get_args();
|
||||
$this->_call_all_hook($args);
|
||||
}
|
||||
|
||||
if ( !isset($this->filters[$tag]) ) {
|
||||
if ( isset($this->filters['all']) )
|
||||
array_pop($this->current_filter);
|
||||
return $value;
|
||||
}
|
||||
|
||||
if ( !isset($this->filters['all']) )
|
||||
$this->current_filter[] = $tag;
|
||||
|
||||
// Sort
|
||||
if ( !isset( $this->merged_filters[ $tag ] ) ) {
|
||||
ksort($this->filters[$tag]);
|
||||
$this->merged_filters[ $tag ] = true;
|
||||
}
|
||||
|
||||
reset( $this->filters[ $tag ] );
|
||||
|
||||
if ( empty($args) )
|
||||
$args = func_get_args();
|
||||
|
||||
do {
|
||||
foreach( (array) current($this->filters[$tag]) as $the_ )
|
||||
if ( !is_null($the_['function']) ){
|
||||
$args[1] = $value;
|
||||
$value = call_user_func_array($the_['function'], array_slice($args, 1, (int) $the_['accepted_args']));
|
||||
}
|
||||
|
||||
} while ( next($this->filters[$tag]) !== false );
|
||||
|
||||
array_pop( $this->current_filter );
|
||||
|
||||
return $value;
|
||||
}
|
||||
/**
|
||||
* apply_filters_ref_array Execute functions hooked on a specific filter hook, specifying arguments in an array.
|
||||
* @access public
|
||||
* @since 0.1
|
||||
* @param string $tag The name of the filter hook.
|
||||
* @param array $args The arguments supplied to the functions hooked to <tt>$tag</tt>
|
||||
* @return mixed The filtered value after all hooked functions are applied to it.
|
||||
*/
|
||||
public function apply_filters_ref_array($tag, $args) {
|
||||
// Do 'all' actions first
|
||||
if ( isset($this->filters['all']) ) {
|
||||
$this->current_filter[] = $tag;
|
||||
$all_args = func_get_args();
|
||||
$this->_call_all_hook($all_args);
|
||||
}
|
||||
|
||||
if ( !isset($this->filters[$tag]) ) {
|
||||
if ( isset($this->filters['all']) )
|
||||
array_pop($this->current_filter);
|
||||
return $args[0];
|
||||
}
|
||||
|
||||
if ( !isset($this->filters['all']) )
|
||||
$this->current_filter[] = $tag;
|
||||
|
||||
// Sort
|
||||
if ( !isset( $this->merged_filters[ $tag ] ) ) {
|
||||
ksort($this->filters[$tag]);
|
||||
$this->merged_filters[ $tag ] = true;
|
||||
}
|
||||
|
||||
reset( $this->filters[ $tag ] );
|
||||
|
||||
do {
|
||||
foreach( (array) current($this->filters[$tag]) as $the_ )
|
||||
if ( !is_null($the_['function']) )
|
||||
$args[0] = call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args']));
|
||||
|
||||
} while ( next($this->filters[$tag]) !== false );
|
||||
|
||||
array_pop( $this->current_filter );
|
||||
|
||||
return $args[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* ACTIONS
|
||||
*/
|
||||
|
||||
/**
|
||||
* add_action Hooks a function on to a specific action.
|
||||
* @access public
|
||||
* @since 0.1
|
||||
* @param string $tag The name of the action to which the $function_to_add is hooked.
|
||||
* @param callback $function_to_add The name of the function you wish to be called.
|
||||
* @param int $priority optional. Used to specify the order in which the functions associated with a particular action are executed (default: 10). Lower numbers correspond with earlier execution, and functions with the same priority are executed in the order in which they were added to the action.
|
||||
* @param int $accepted_args optional. The number of arguments the function accept (default 1).
|
||||
*/
|
||||
public function add_action($tag, $function_to_add, $priority = 10, $accepted_args = 1) {
|
||||
return $this->add_filter($tag, $function_to_add, $priority, $accepted_args);
|
||||
}
|
||||
/**
|
||||
* has_action Check if any action has been registered for a hook.
|
||||
* @access public
|
||||
* @since 0.1
|
||||
* @param string $tag The name of the action hook.
|
||||
* @param callback $function_to_check optional.
|
||||
* @return mixed If $function_to_check is omitted, returns boolean for whether the hook has anything registered.
|
||||
* When checking a specific function, the priority of that hook is returned, or false if the function is not attached.
|
||||
* When using the $function_to_check argument, this function may return a non-boolean value that evaluates to false
|
||||
* (e.g.) 0, so use the === operator for testing the return value.
|
||||
*/
|
||||
public function has_action($tag, $function_to_check = false) {
|
||||
return $this->has_filter($tag, $function_to_check);
|
||||
}
|
||||
/**
|
||||
* remove_action Removes a function from a specified action hook.
|
||||
* @access public
|
||||
* @since 0.1
|
||||
* @param string $tag The action hook to which the function to be removed is hooked.
|
||||
* @param callback $function_to_remove The name of the function which should be removed.
|
||||
* @param int $priority optional The priority of the function (default: 10).
|
||||
* @return boolean Whether the function is removed.
|
||||
*/
|
||||
public function remove_action( $tag, $function_to_remove, $priority = 10 ) {
|
||||
return $this->remove_filter( $tag, $function_to_remove, $priority );
|
||||
}
|
||||
/**
|
||||
* remove_all_actions Remove all of the hooks from an action.
|
||||
* @access public
|
||||
* @since 0.1
|
||||
* @param string $tag The action to remove hooks from.
|
||||
* @param int $priority The priority number to remove them from.
|
||||
* @return bool True when finished.
|
||||
*/
|
||||
public function remove_all_actions($tag, $priority = false) {
|
||||
return $this->remove_all_filters($tag, $priority);
|
||||
}
|
||||
/**
|
||||
* do_action Execute functions hooked on a specific action hook.
|
||||
* @access public
|
||||
* @since 0.1
|
||||
* @param string $tag The name of the action to be executed.
|
||||
* @param mixed $arg,... Optional additional arguments which are passed on to the functions hooked to the action.
|
||||
* @return null Will return null if $tag does not exist in $filter array
|
||||
*/
|
||||
public function do_action($tag, $arg = '') {
|
||||
|
||||
if ( ! isset($this->actions) )
|
||||
$this->actions = array();
|
||||
|
||||
if ( ! isset($this->actions[$tag]) )
|
||||
$this->actions[$tag] = 1;
|
||||
else
|
||||
++$this->actions[$tag];
|
||||
|
||||
// Do 'all' actions first
|
||||
if ( isset($this->filters['all']) ) {
|
||||
$this->current_filter[] = $tag;
|
||||
$all_args = func_get_args();
|
||||
$this->_call_all_hook($all_args);
|
||||
}
|
||||
|
||||
if ( !isset($this->filters[$tag]) ) {
|
||||
if ( isset($this->filters['all']) )
|
||||
array_pop($this->current_filter);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !isset($this->filters['all']) )
|
||||
$this->current_filter[] = $tag;
|
||||
|
||||
$args = array();
|
||||
if ( is_array($arg) && 1 == count($arg) && isset($arg[0]) && is_object($arg[0]) ) // array(&$this)
|
||||
$args[] =& $arg[0];
|
||||
else
|
||||
$args[] = $arg;
|
||||
for ( $a = 2; $a < func_num_args(); $a++ )
|
||||
$args[] = func_get_arg($a);
|
||||
|
||||
// Sort
|
||||
if ( !isset( $this->merged_filters[ $tag ] ) ) {
|
||||
ksort($this->filters[$tag]);
|
||||
$this->merged_filters[ $tag ] = true;
|
||||
}
|
||||
|
||||
reset( $this->filters[ $tag ] );
|
||||
|
||||
do {
|
||||
foreach ( (array) current($this->filters[$tag]) as $the_ )
|
||||
if ( !is_null($the_['function']) )
|
||||
call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args']));
|
||||
|
||||
} while ( next($this->filters[$tag]) !== false );
|
||||
|
||||
array_pop($this->current_filter);
|
||||
}
|
||||
/**
|
||||
* do_action_ref_array Execute functions hooked on a specific action hook, specifying arguments in an array.
|
||||
* @access public
|
||||
* @since 0.1
|
||||
* @param string $tag The name of the action to be executed.
|
||||
* @param array $args The arguments supplied to the functions hooked to <tt>$tag</tt>
|
||||
* @return null Will return null if $tag does not exist in $filter array
|
||||
*/
|
||||
public function do_action_ref_array($tag, $args) {
|
||||
|
||||
if ( ! isset($this->actions) )
|
||||
$this->actions = array();
|
||||
|
||||
if ( ! isset($this->actions[$tag]) )
|
||||
$this->actions[$tag] = 1;
|
||||
else
|
||||
++$this->actions[$tag];
|
||||
|
||||
// Do 'all' actions first
|
||||
if ( isset($this->filters['all']) ) {
|
||||
$this->current_filter[] = $tag;
|
||||
$all_args = func_get_args();
|
||||
$this->_call_all_hook($all_args);
|
||||
}
|
||||
|
||||
if ( !isset($this->filters[$tag]) ) {
|
||||
if ( isset($this->filters['all']) )
|
||||
array_pop($this->current_filter);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !isset($this->filters['all']) )
|
||||
$this->current_filter[] = $tag;
|
||||
|
||||
// Sort
|
||||
if ( !isset( $merged_filters[ $tag ] ) ) {
|
||||
ksort($this->filters[$tag]);
|
||||
$merged_filters[ $tag ] = true;
|
||||
}
|
||||
|
||||
reset( $this->filters[ $tag ] );
|
||||
|
||||
do {
|
||||
foreach( (array) current($this->filters[$tag]) as $the_ )
|
||||
if ( !is_null($the_['function']) )
|
||||
call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args']));
|
||||
|
||||
} while ( next($this->filters[$tag]) !== false );
|
||||
|
||||
array_pop($this->current_filter);
|
||||
}
|
||||
/**
|
||||
* did_action Retrieve the number of times an action is fired.
|
||||
* @access public
|
||||
* @since 0.1
|
||||
* @param string $tag The name of the action hook.
|
||||
* @return int The number of times action hook <tt>$tag</tt> is fired
|
||||
*/
|
||||
public function did_action($tag) {
|
||||
|
||||
if ( ! isset( $this->actions ) || ! isset( $this->actions[$tag] ) )
|
||||
return 0;
|
||||
|
||||
return $this->actions[$tag];
|
||||
}
|
||||
|
||||
/**
|
||||
* HELPERS
|
||||
*/
|
||||
|
||||
/**
|
||||
* current_filter Retrieve the name of the current filter or action.
|
||||
* @access public
|
||||
* @since 0.1
|
||||
* @return string Hook name of the current filter or action.
|
||||
*/
|
||||
public function current_filter() {
|
||||
return end( $this->current_filter );
|
||||
}
|
||||
/**
|
||||
* Retrieve the name of the current action.
|
||||
*
|
||||
* @since 0.1.2
|
||||
*
|
||||
* @uses current_filter()
|
||||
*
|
||||
* @return string Hook name of the current action.
|
||||
*/
|
||||
function current_action() {
|
||||
return $this->current_filter();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the name of a filter currently being processed.
|
||||
*
|
||||
* The function current_filter() only returns the most recent filter or action
|
||||
* being executed. did_action() returns true once the action is initially
|
||||
* processed. This function allows detection for any filter currently being
|
||||
* executed (despite not being the most recent filter to fire, in the case of
|
||||
* hooks called from hook callbacks) to be verified.
|
||||
*
|
||||
* @since 0.1.2
|
||||
*
|
||||
* @see current_filter()
|
||||
* @see did_action()
|
||||
* @global array $wp_current_filter Current filter.
|
||||
*
|
||||
* @param null|string $filter Optional. Filter to check. Defaults to null, which
|
||||
* checks if any filter is currently being run.
|
||||
* @return bool Whether the filter is currently in the stack
|
||||
*/
|
||||
function doing_filter( $filter = null ) {
|
||||
if ( null === $filter ) {
|
||||
return ! empty( $this->current_filter );
|
||||
}
|
||||
return in_array( $filter, $this->current_filter );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the name of an action currently being processed.
|
||||
*
|
||||
* @since 0.1.2
|
||||
*
|
||||
* @uses doing_filter()
|
||||
*
|
||||
* @param string|null $action Optional. Action to check. Defaults to null, which checks
|
||||
* if any action is currently being run.
|
||||
* @return bool Whether the action is currently in the stack.
|
||||
*/
|
||||
function doing_action( $action = null ) {
|
||||
return $this->doing_filter( $action );
|
||||
}
|
||||
|
||||
/**
|
||||
* _filter_build_unique_id Build Unique ID for storage and retrieval.
|
||||
* @param string $tag Used in counting how many hooks were applied
|
||||
* @param callback $function Used for creating unique id
|
||||
* @param int|bool $priority Used in counting how many hooks were applied. If === false and $function is an object reference, we return the unique id only if it already has one, false otherwise.
|
||||
* @return string|bool Unique ID for usage as array key or false if $priority === false and $function is an object reference, and it does not already have a unique id.
|
||||
*/
|
||||
private function _filter_build_unique_id($tag, $function, $priority) {
|
||||
static $filter_id_count = 0;
|
||||
|
||||
if ( is_string($function) )
|
||||
return $function;
|
||||
|
||||
if ( is_object($function) ) {
|
||||
// Closures are currently implemented as objects
|
||||
$function = array( $function, '' );
|
||||
} else {
|
||||
$function = (array) $function;
|
||||
}
|
||||
|
||||
if (is_object($function[0]) ) {
|
||||
// Object Class Calling
|
||||
if ( function_exists('spl_object_hash') ) {
|
||||
return spl_object_hash($function[0]) . $function[1];
|
||||
} else {
|
||||
$obj_idx = get_class($function[0]).$function[1];
|
||||
if ( !isset($function[0]->filter_id) ) {
|
||||
if ( false === $priority )
|
||||
return false;
|
||||
$obj_idx .= isset($this->filters[$tag][$priority]) ? count((array)$this->filters[$tag][$priority]) : $filter_id_count;
|
||||
$function[0]->filter_id = $filter_id_count;
|
||||
++$filter_id_count;
|
||||
} else {
|
||||
$obj_idx .= $function[0]->filter_id;
|
||||
}
|
||||
|
||||
return $obj_idx;
|
||||
}
|
||||
} else if ( is_string($function[0]) ) {
|
||||
// Static Calling
|
||||
return $function[0].$function[1];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* __call_all_hook
|
||||
* @access public
|
||||
* @since 0.1
|
||||
* @param (array) $args [description]
|
||||
*/
|
||||
public function __call_all_hook($args) {
|
||||
reset( $this->filters['all'] );
|
||||
do {
|
||||
foreach( (array) current($this->filters['all']) as $the_ )
|
||||
if ( !is_null($the_['function']) )
|
||||
call_user_func_array($the_['function'], $args);
|
||||
|
||||
} while ( next($this->filters['all']) !== false );
|
||||
}
|
||||
}//end class
|
||||
}//end if
|
||||
global $hooks;
|
||||
$hooks = new Hooks();
|
||||
$hooks->do_action('After_Hooks_Setup',$hooks);
|
||||
@@ -1,42 +0,0 @@
|
||||
<?php namespace OverwatchSDK;
|
||||
|
||||
class Network
|
||||
{
|
||||
|
||||
// Internet based functions
|
||||
function DownloadFile($src, $dest)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// DNS-SD functions
|
||||
function ScanForService($servType) {}
|
||||
|
||||
function PublishService($servType, $name, $port, $des) {}
|
||||
|
||||
// IP Management
|
||||
function ChangeIP($dev, $ip, $gateway, $subnetmask) {}
|
||||
|
||||
function DNS_ListServers() {}
|
||||
|
||||
function DNS_AddServer($ip) {}
|
||||
|
||||
function DNS_RemServer($ip) {}
|
||||
|
||||
|
||||
}
|
||||
|
||||
class System
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
class IO
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
class Hardware
|
||||
{
|
||||
|
||||
}
|
||||
39
sdk/OverwatchSDK.inc.php
Normal file
39
sdk/OverwatchSDK.inc.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
/**
|
||||
* Overwatch SDK
|
||||
*
|
||||
* Provides abstracted functions and boilerplate code for modules and the core.
|
||||
* @version 1.0.0
|
||||
* @copyright 2016-* Tox Communications
|
||||
* @author ShadowEO <dreamcaster23@gmail.com>
|
||||
* @package OverwatchSDK
|
||||
*/
|
||||
|
||||
namespace Overwatch\SDK;
|
||||
|
||||
if(file_exists(dirname(__FILE__)."/v1/OverwatchServerSDK.v1.inc.php"))
|
||||
{
|
||||
require_once(dirname(__FILE__)."/v1/OverwatchServerSDK.v1.inc.php");
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides functions to manage and enumerate available SDK versions.
|
||||
* @api
|
||||
*/
|
||||
class Manager
|
||||
{
|
||||
/**
|
||||
* Check to see if requested SDK version is available
|
||||
* @param int $version Version Number of SDK requested
|
||||
* @return bool Whether SDK is available in this version of Overwatchd or not.
|
||||
*/
|
||||
static function isSDK_installed($version)
|
||||
{
|
||||
if(file_exists(dirname(__FILE__)."/v1"))
|
||||
{
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
90
sdk/v1/ModuleBoilerplate.class.php
Normal file
90
sdk/v1/ModuleBoilerplate.class.php
Normal file
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
namespace Overwatch\SDK\v1;
|
||||
|
||||
abstract class ModuleBoilerplate
|
||||
{
|
||||
|
||||
/**
|
||||
* Register API commands and initialize module.
|
||||
*
|
||||
* It is recommended to place all your apiql::register statements here along with any initialization you may need.
|
||||
*/
|
||||
abstract protected static function Initialize();
|
||||
/**
|
||||
* Register API Commands and initialize module.
|
||||
* @deprecated 1.0.0 Will no longer be used by modules after boilerplate has been established unless module specifically calls it.
|
||||
*/
|
||||
abstract protected static function API_Register();
|
||||
|
||||
/**
|
||||
* Prepares a static instance of the calling module.
|
||||
* @return object $inst Self-reference
|
||||
*/
|
||||
public static function loadInst() {
|
||||
static $inst = null;
|
||||
if ($inst === null) {
|
||||
$inst = new static;
|
||||
}
|
||||
return $inst;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Used internally to provide a static reference with which to get class name.
|
||||
* @return string Class name
|
||||
*/
|
||||
protected static function module_who() {
|
||||
return __CLASS__;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called upon the module being loaded successfully and the object being instanced properly.
|
||||
* @return boolean If the module initalized successfully.
|
||||
*/
|
||||
static function module_loaded() {
|
||||
static $attempted = null;
|
||||
$class = get_called_class();
|
||||
|
||||
if(defined(get_called_class().'::requires_root') && static::requires_root == true)
|
||||
{
|
||||
if($processUser['name'] != "root")
|
||||
{
|
||||
\Overwatch\SDK\v1\Utility::Log(static::module_who().' requires Overwatchd to be running with root privileges.', static::module_who(), \Overwatch\SDK\v1\Utility::OVR_UTIL_LOGLEVEL_ERROR);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(method_exists($class, "Initialize"))
|
||||
{
|
||||
\Overwatch\SDK\v1\Utility::Log($class.' is a valid SDK-based module.', static::module_who(), \Overwatch\SDK\v1\Utility::OVR_UTIL_LOGLEVEL_DEBUG);
|
||||
$status = static::Initialize();
|
||||
$attempted = true;
|
||||
if(isset($status))
|
||||
{
|
||||
return $status;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if(method_exists($class, "API_Register"))
|
||||
{
|
||||
\Overwatch\SDK\v1\Utility::Log(static::module_who().' is using legacy (alpha) module code. This is deprecated and will soon be removed.', static::module_who(), \Overwatch\SDK\v1\Utility::OVR_UTIL_LOGLEVEL_DEBUG);
|
||||
$status = static::API_Register();
|
||||
$attempted = true;
|
||||
if(isset($status))
|
||||
{
|
||||
return $status;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if($attempted == true)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
487
sdk/v1/OverwatchClientSDK.v1.inc.php
Normal file
487
sdk/v1/OverwatchClientSDK.v1.inc.php
Normal file
@@ -0,0 +1,487 @@
|
||||
<?php
|
||||
/**
|
||||
* Overwatch SDK Version 1.0
|
||||
*
|
||||
* This is the SDK for the Overwatch Daemon
|
||||
* @package Overwatch\SDK\1.0
|
||||
* @author ShadowEO <dreamcaster23@gmail.com>
|
||||
* @version 1.0.0
|
||||
* @copyright 2016-* Tox Communications
|
||||
* @category Development
|
||||
*/
|
||||
namespace Overwatch\SDK\v1;
|
||||
|
||||
|
||||
/**
|
||||
* Utilities
|
||||
*
|
||||
* Provides common utility functions such as logging.
|
||||
*/
|
||||
class Utility {
|
||||
|
||||
/**
|
||||
* Used to tell the logging functions to use the info level and apply appropriate formatting.
|
||||
* @see \Overwatch\SDK\v1\Utility::Log() Logging function
|
||||
*/
|
||||
const OVR_UTIL_LOGLEVEL_INFO = 0;
|
||||
/**
|
||||
* Used to tell the logging functions to use the warning level and apply appropriate formatting.
|
||||
* @see \Overwatch\SDK\v1\Utility::Log() Logging function
|
||||
*/
|
||||
const OVR_UTIL_LOGLEVEL_WARN = 1;
|
||||
/**
|
||||
* Used to tell the logging functions to use the error level and apply appropriate formatting. Tells LogToConsole to output to stderr
|
||||
* @see \Overwatch\SDK\v1\Utility::Log() Logging function
|
||||
*/
|
||||
const OVR_UTIL_LOGLEVEL_ERROR = 2;
|
||||
/**
|
||||
* Used to tell the logging functions to use the debugging level and apply appropriate formatting.
|
||||
*
|
||||
* NOTE: <b>Messages logged using the debug label will not be written to console or file unless debug mode is enabled.</b>
|
||||
* @see \Overwatch\SDK\v1\Utility::Log() Logging function
|
||||
*/
|
||||
const OVR_UTIL_LOGLEVEL_DEBUG = 3;
|
||||
|
||||
/**
|
||||
* Used to tell the logging functions to log to stdout/stderr
|
||||
* @see \Overwatch\SDK\v1\Utility::Log() Logging function
|
||||
*/
|
||||
const OVR_UTIL_LOG_CONSOLE = 4;
|
||||
|
||||
/**
|
||||
* Used to tell the logging functions to log to a file
|
||||
* @see \Overwatch\SDK\v1\Utility::Log() Logging function
|
||||
*/
|
||||
const OVR_UTIL_LOG_FILE = 5;
|
||||
|
||||
/**
|
||||
* Logs messages to stdout
|
||||
*
|
||||
* @param string $msg Message to write to Log
|
||||
* @param string $component Component that the message is coming from
|
||||
* @param int $level Logging Level
|
||||
* @see \Overwatch\SDK\v1\Utility::OVR_UTIL_LOGLEVEL_INFO OVR_UTIL_LOGLEVEL_INFO
|
||||
* @see \Overwatch\SDK\v1\Utility::OVR_UTIL_LOGLEVEL_ERROR OVR_UTIL_LOGLEVEL_ERROR
|
||||
* @see \Overwatch\SDK\v1\Utility::OVR_UTIL_LOGLEVEL_DEBUG OVR_UTIL_LOGLEVEL_DEBUG
|
||||
* @see \Overwatch\SDK\v1\Utility::OVR_UTIL_LOGLEVEL_WARN OVR_UTIL_LOGLEVEL_WARN
|
||||
* @return void
|
||||
*/
|
||||
protected function LogToConsole($msg, $component, $level = OVR_UTIL_LOGLEVEL_INFO)
|
||||
{
|
||||
$oTimeStamp = new DateTime();
|
||||
$sTimeStamp = $oTimeStamp->format('m-d-Y H:i:s');
|
||||
$component=strtoupper($component);
|
||||
switch ($level)
|
||||
{
|
||||
// TODO: Look into different console codes for coloring and effects
|
||||
case OVR_UTIL_LOGLEVEL_ERROR:
|
||||
error_log("[$sTimeStamp][$component] $msg");
|
||||
break;
|
||||
default:
|
||||
echo("[$sTimeStamp][$component] $msg");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs messages
|
||||
*
|
||||
* @param string $msg Message to write to Log
|
||||
* @param string $component Component that the message is coming from
|
||||
* @param int $level Logging Level
|
||||
* @see \Overwatch\SDK\v1\Utility::OVR_UTIL_LOGLEVEL_INFO OVR_UTIL_LOGLEVEL_INFO
|
||||
* @see \Overwatch\SDK\v1\Utility::OVR_UTIL_LOGLEVEL_ERROR OVR_UTIL_LOGLEVEL_ERROR
|
||||
* @see \Overwatch\SDK\v1\Utility::OVR_UTIL_LOGLEVEL_DEBUG OVR_UTIL_LOGLEVEL_DEBUG
|
||||
* @see \Overwatch\SDK\v1\Utility::OVR_UTIL_LOGLEVEL_WARN OVR_UTIL_LOGLEVEL_WARN
|
||||
* @param int $type Logging destination
|
||||
* @see \Overwatch\SDK\v1\Utility::OVR_UTIL_LOG_FILE OVR_UTIL_LOG_FILE
|
||||
* @see \Overwatch\SDK\v1\Utility::OVR_UTIL_LOG_CONSOLE OVR_UTIL_LOG_CONSOLE
|
||||
* @param string $file File path to log to (if type is `OVR_UTIL_LOG_FILE`)
|
||||
* @api
|
||||
* @return void
|
||||
*/
|
||||
public function Log($msg, $component, $level = OVR_UTIL_LOGLEVEL_INFO, $type = OVR_UTIL_LOG_CONSOLE, $file = null)
|
||||
{
|
||||
switch($type)
|
||||
{
|
||||
case OVR_UTIL_LOG_CONSOLE:
|
||||
LogToConsole($msg, $component, $level);
|
||||
break;
|
||||
case OVR_UTIL_LOG_FILE:
|
||||
if($file == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
LogToFile($msg, $component, $level = OVR_UTIL_LOGLEVEL_INFO, $file);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs specified messages to a file.
|
||||
* @param string $msg Message to write to Log
|
||||
* @param string $component Component that the message is coming from
|
||||
* @param string $level Logging Level
|
||||
* @see \Overwatch\SDK\v1\Utility::OVR_UTIL_LOGLEVEL_INFO OVR_UTIL_LOGLEVEL_INFO
|
||||
* @see \Overwatch\SDK\v1\Utility::OVR_UTIL_LOGLEVEL_ERROR OVR_UTIL_LOGLEVEL_ERROR
|
||||
* @see \Overwatch\SDK\v1\Utility::OVR_UTIL_LOGLEVEL_DEBUG OVR_UTIL_LOGLEVEL_DEBUG
|
||||
* @see \Overwatch\SDK\v1\Utility::OVR_UTIL_LOGLEVEL_WARN OVR_UTIL_LOGLEVEL_WARN
|
||||
* @param string $file File to write the message to.
|
||||
* @return void
|
||||
*/
|
||||
protected function LogToFile($msg, $component, $level = OVR_UTIL_LOGLEVEL_INFO, $file)
|
||||
{
|
||||
$oTimeStamp = new DateTime();
|
||||
$sTimeStamp = $oTimeStamp->format('m-d-Y H:i:s');
|
||||
$component=strtoupper($component);
|
||||
switch($level)
|
||||
{
|
||||
case OVR_UTIL_LOGLEVEL_ERROR:
|
||||
error_log("[$sTimeStamp][$component] $msg", 0, $file);
|
||||
break;
|
||||
default:
|
||||
file_put_contents($file, "[$sTimeStamp][$component] $msg", FILE_APPEND);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a standard implementation for managing connections in the Overwatch API server.
|
||||
*/
|
||||
class ConnectionManager
|
||||
{
|
||||
// TODO: Implement functionality, remove from core.
|
||||
|
||||
/** @var int Stores the amount of currently on-going connection */
|
||||
protected $iCurrentConnections;
|
||||
|
||||
/** @var int Stores the amount of total connections in the lifetime of the server process. */
|
||||
protected $iTotalConnections;
|
||||
|
||||
|
||||
/** @var mixed Stores hierarchy of connections */
|
||||
protected $ConnectionHierarchy;
|
||||
|
||||
|
||||
/**
|
||||
* Accept a connection from the ReactPHP stack
|
||||
*
|
||||
* Accept a connection and place it in the list of connections.
|
||||
* @param \React\Socket\Connection $oConnection Connection object returned from the `on('connection')` ReactPHP event.
|
||||
* @param int $iConnection Optional, used to denote the connection ID (deprecated)
|
||||
* @return string Identifying Hash for Connection
|
||||
* @api
|
||||
*/
|
||||
public function AcceptConnection($oConnection, $iConnection = null)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Write packet to an accepted connection.
|
||||
*
|
||||
* If a connection hash is not provided, it will broadcast to all clients.
|
||||
* @param string $zPacket Packet to send to socket.
|
||||
* @param string $sConnectionHash Optional, Hash to identify the connection to write to.
|
||||
* @api
|
||||
* @return void
|
||||
*/
|
||||
public function Write($zPacket, $sConnectionHash = null) {}
|
||||
|
||||
/**
|
||||
* Add a connection to the connections store
|
||||
*
|
||||
* @param mixed $Connection Connection Information
|
||||
* @return string Connection Hash
|
||||
*/
|
||||
private function __addConnection($Connection)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Remove a connection from the connections store
|
||||
*
|
||||
* @param string $sConnectionHash Connection hash to identify the connection to remove
|
||||
* @return boolean
|
||||
*/
|
||||
private function __remConnection($sConnectionHash)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Retrieve a Connection Object from the connection store for the matching connection hash
|
||||
*
|
||||
* @param string $sConnectionHash Connection hash to identify the connection.
|
||||
* @return \React\Socket\Connection
|
||||
*/
|
||||
private function __getObjectForHash($sConnectionHash)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Signal disconnection to a client. This will send a disconnection response JSON message for the client to process.
|
||||
*
|
||||
* @param string $sConnectionHash Connection hash to identify the connection.
|
||||
* @return void
|
||||
*/
|
||||
private function __signalDisconnection($sConnectionHash)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Force a client to disconnect, this preforms __signalDisconnection and then closes the connection, removing it from the connection store.
|
||||
*
|
||||
* @param string $sConnectionHash Connection hash to identify the connection.
|
||||
* @return boolean
|
||||
*/
|
||||
private function __forceDisconnection($sConnectionHash)
|
||||
{}
|
||||
|
||||
// TODO: Implement this function: public function setLastCall($zCall, $sConnectionHash) {}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Module boilerplate
|
||||
*
|
||||
* Provides a boilerplate to base modules on.
|
||||
*/
|
||||
abstract class Module
|
||||
{
|
||||
|
||||
/**
|
||||
* Register API commands and initialize module.
|
||||
*
|
||||
* It is recommended to place all your apiql::register statements here along with any initialization you may need.
|
||||
*/
|
||||
abstract protected function Initialize();
|
||||
/**
|
||||
* Register API Commands and initialize module.
|
||||
* @deprecated 1.0.0 Will no longer be used by modules after boilerplate has been established unless module specifically calls it.
|
||||
*/
|
||||
abstract protected function API_Register();
|
||||
|
||||
/**
|
||||
* Prepares a static instance of the calling module.
|
||||
* @return object $inst Self-reference
|
||||
*/
|
||||
protected function loadInst() {
|
||||
static $inst = null;
|
||||
|
||||
if ($inst === null) {
|
||||
$inst = new static;
|
||||
}
|
||||
return $inst;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used internally to provide a static reference with which to get class name.
|
||||
* @return string Class name
|
||||
*/
|
||||
protected static function module_who() {
|
||||
return __CLASS__;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called upon the module being loaded successfully and the object being instanced properly.
|
||||
* @return boolean If the module initalized successfully.
|
||||
*/
|
||||
protected function module_loaded() {
|
||||
static $attempted = null;
|
||||
$processUser = posix_getpwuid(posix_geteuid());
|
||||
if($attempted == true)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if(defined(static::module_who().'::requires_root'))
|
||||
{
|
||||
if($processUser['name'] != "root")
|
||||
{
|
||||
\Overwatch\SDK\v1\Utility::Log(static::module_who().' requires Overwatchd to be running with root privileges.', static::module_who(), \Overwatch\SDK\v1\Utility::OVR_UTIL_LOGLEVEL_ERROR);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(strtoupper(static::$moduleType) == "API" or !isset($static::$moduleType))
|
||||
{
|
||||
if(function_exists(static::module_who()."::API_Register"))
|
||||
{
|
||||
\Overwatch\SDK\v1\Utility::Log(static::module_who().' is using legacy (alpha) module code. This is deprecated and will soon be removed.', static::module_who(), \Overwatch\SDK\v1\Utility::OVR_UTIL_LOGLEVEL_DEBUG);
|
||||
$status = static::API_Register();
|
||||
$attempted = true;
|
||||
if(!isset($status))
|
||||
{
|
||||
return $status;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if(function_exists(static::module_who()."::Initalize"))
|
||||
{
|
||||
$status = static::Initialize();
|
||||
$attempted = true;
|
||||
if(!isset($status))
|
||||
{
|
||||
return $status;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* OverwatchSDK Module Loader
|
||||
*
|
||||
* Abstracts the overwatch module loader into an easier to use API.
|
||||
*/
|
||||
class ModuleLoader
|
||||
{
|
||||
/**
|
||||
* @var \ModuleLoader $moduleLoader Simple Module Loader Object
|
||||
*/
|
||||
protected $moduleLoader;
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
protected static $modules;
|
||||
|
||||
/**
|
||||
* Registers Module Loader API functions with APIQL
|
||||
* @return void
|
||||
*/
|
||||
protected function __registerModuleAPI()
|
||||
{
|
||||
if(class_exists("apiql"))
|
||||
{
|
||||
apiql::register("!LOAD/!MODULE[json]", "\Overwatch\SDK\v1\ModuleLoader::__apiql_loadModule");
|
||||
apiql::register("!UNLOAD/!MODULE[json]", "\Overwatch\SDK\v1\ModuleLoader::__apiql_unloadModule");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore */
|
||||
public static function __apiql_loadModule($sql)
|
||||
{}
|
||||
|
||||
/**
|
||||
* @ignore */
|
||||
public static function __apiql_unloadModule($sql)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Loads specified module from path.
|
||||
*
|
||||
* @param string $modulePath Path to module directory
|
||||
* @param string $moduleName Name of Module to be loaded
|
||||
* @param string $type File extension of module (defaults to .API.php)
|
||||
* @return bool Whether the module is loaded successfully or not.
|
||||
*/
|
||||
protected function __loadModule($modulePath, $moduleName, $type = "API.php")
|
||||
{
|
||||
self::$modules[$moduleName] = $module->loadModule($moduleName, $modulePath, $type);
|
||||
if(is_object(self::$modules[$moduleName]) && self::$modules[$moduleName]->module_loaded())
|
||||
{
|
||||
\Overwatch\SDK\v1\Utility::Log("Module loaded successfully: $moduleName", "API-MODLOADER", \Overwatch\SDK\v1\Utility::OVR_UTIL_LOGLEVEL_DEBUG);
|
||||
return true;
|
||||
} else {
|
||||
\Overwatch\SDK\v1\Utility::Log("Module failed to load successfully: $moduleName", "API-MODLOADER", \Overwatch\SDK\v1\Utility::OVR_UTIL_LOGLEVEL_DEBUG);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Unloads specified module from system
|
||||
*
|
||||
* @param string $module Module name to unload
|
||||
* @return bool Whether the module is unloaded successfully
|
||||
*/
|
||||
protected function __unloadModule($module)
|
||||
{
|
||||
if(self::$moduleLoader->unloadModule($module) == true)
|
||||
{
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads all modules from specified path
|
||||
*
|
||||
* @param string $path Path to Overwatch Modules (defaults to OVERWATCH_MODULES)
|
||||
* @return void
|
||||
* @api
|
||||
*/
|
||||
function LoadModulesFromPath($path = OVERWATCH_MODULES)
|
||||
{
|
||||
$modulesArray = scandir($path);
|
||||
foreach($modulesArray as $moduleName)
|
||||
{
|
||||
if($moduleName != "." && $moduleName != "..")
|
||||
{
|
||||
\Overwatch\SDK\v1\Utility::Log("Module found: $moduleName", "API-MODLOADER", \Overwatch\SDK\v1\Utility::OVR_UTIL_LOGLEVEL_DEBUG);
|
||||
}
|
||||
if(is_dir($path."$moduleName") && $moduleName != "." && $moduleName != "..")
|
||||
{
|
||||
\Overwatch\SDK\v1\Utility::Log("Loading Module: $moduleName", "API-MODLOADER", \Overwatch\SDK\v1\Utility::OVR_UTIL_LOGLEVEL_DEBUG);
|
||||
self::__loadModule($path, $moduleName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* RPC Handler
|
||||
*
|
||||
* Provides methods to handle RPC requests from Overwatchd
|
||||
*/
|
||||
class RPC
|
||||
{
|
||||
/**
|
||||
* Selects the client RPC type in RPC::DoCall
|
||||
* @see DoCall() RPC::DoCall
|
||||
*/
|
||||
const OVR_RPC_TYPE_CLIENT = 1;
|
||||
/**
|
||||
* Selects the Server to Server RPC type in RPC::DoCall
|
||||
* @see DoCall() RPC::DoCall
|
||||
*/
|
||||
const OVR_RPC_TYPE_S2S = 2;
|
||||
|
||||
/**
|
||||
* Calls a function using an APIQL statement
|
||||
*
|
||||
* @param mixed $zPacket APIQL Statement
|
||||
* @return mixed Response from API
|
||||
* @see Overwatch\SDK\v1\Module Module Boilerplate (See Examples)
|
||||
*/
|
||||
private function __apiql_doCall($zPacket)
|
||||
{
|
||||
// TODO: Mangle headers to set connection-id
|
||||
$response = apiql::query($zPacket);
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls a function using pure JSON-RPC
|
||||
*
|
||||
* @param mixed $zPacket JSON-RPC Packet
|
||||
* @return mixed Response from called function
|
||||
*/
|
||||
private function __rpc_doCall($zPacket)
|
||||
{
|
||||
// TODO: Pull apart JSON packet and process through ClassName::__rpc_ClassMethod to prevent RPC calls from calling private functions
|
||||
}
|
||||
|
||||
/**
|
||||
* Call functions from RPC requests
|
||||
* @param mixed $zPacket Incoming RPC Packet
|
||||
* @param integer $iType RPC Call Type
|
||||
* @see OVR_RPC_TYPE_CLIENT
|
||||
* @see OVR_RPC_TYPE_S2S
|
||||
* @return mixed Response from API
|
||||
* @api
|
||||
*/
|
||||
protected function DoCall($zPacket, $iType = \Overwatch\SDK\v1\RPC::OVR_RPC_TYPE_CLIENT)
|
||||
{}
|
||||
|
||||
|
||||
|
||||
}
|
||||
?>
|
||||
162
sdk/v1/OverwatchServerSDK.v1.inc.php
Normal file
162
sdk/v1/OverwatchServerSDK.v1.inc.php
Normal file
@@ -0,0 +1,162 @@
|
||||
<?php
|
||||
/**
|
||||
* Overwatch SDK Version 1.0
|
||||
*
|
||||
* This is the SDK for the Overwatch Daemon
|
||||
* @package Overwatch\SDK\1.0
|
||||
* @author ShadowEO <dreamcaster23@gmail.com>
|
||||
* @version 1.0.0
|
||||
* @copyright 2016-* Tox Communications
|
||||
* @category Development
|
||||
*/
|
||||
namespace Overwatch\SDK\v1;
|
||||
|
||||
|
||||
require_once("Utility.class.php");
|
||||
/**
|
||||
* Provides a standard implementation for managing connections in the Overwatch API server.
|
||||
*/
|
||||
class ConnectionManager
|
||||
{
|
||||
// TODO: Implement functionality, remove from core.
|
||||
|
||||
/** @var int Stores the amount of currently on-going connection */
|
||||
protected $iCurrentConnections;
|
||||
|
||||
/** @var int Stores the amount of total connections in the lifetime of the server process. */
|
||||
protected $iTotalConnections;
|
||||
|
||||
|
||||
/** @var mixed Stores hierarchy of connections */
|
||||
protected $ConnectionHierarchy;
|
||||
|
||||
|
||||
/**
|
||||
* Accept a connection from the ReactPHP stack
|
||||
*
|
||||
* Accept a connection and place it in the list of connections.
|
||||
* @param \React\Socket\Connection $oConnection Connection object returned from the `on('connection')` ReactPHP event.
|
||||
* @param int $iConnection Optional, used to denote the connection ID (deprecated)
|
||||
* @return string Identifying Hash for Connection
|
||||
* @api
|
||||
*/
|
||||
public function AcceptConnection($oConnection, $iConnection = null)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Write packet to an accepted connection.
|
||||
*
|
||||
* If a connection hash is not provided, it will broadcast to all clients.
|
||||
* @param string $zPacket Packet to send to socket.
|
||||
* @param string $sConnectionHash Optional, Hash to identify the connection to write to.
|
||||
* @api
|
||||
* @return void
|
||||
*/
|
||||
public function Write($zPacket, $sConnectionHash = null) {}
|
||||
|
||||
/**
|
||||
* Add a connection to the connections store
|
||||
*
|
||||
* @param mixed $Connection Connection Information
|
||||
* @return string Connection Hash
|
||||
*/
|
||||
private function __addConnection($Connection)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Remove a connection from the connections store
|
||||
*
|
||||
* @param string $sConnectionHash Connection hash to identify the connection to remove
|
||||
* @return boolean
|
||||
*/
|
||||
private function __remConnection($sConnectionHash)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Retrieve a Connection Object from the connection store for the matching connection hash
|
||||
*
|
||||
* @param string $sConnectionHash Connection hash to identify the connection.
|
||||
* @return \React\Socket\Connection
|
||||
*/
|
||||
private function __getObjectForHash($sConnectionHash)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Signal disconnection to a client. This will send a disconnection response JSON message for the client to process.
|
||||
*
|
||||
* @param string $sConnectionHash Connection hash to identify the connection.
|
||||
* @return void
|
||||
*/
|
||||
private function __signalDisconnection($sConnectionHash)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Force a client to disconnect, this preforms __signalDisconnection and then closes the connection, removing it from the connection store.
|
||||
*
|
||||
* @param string $sConnectionHash Connection hash to identify the connection.
|
||||
* @return boolean
|
||||
*/
|
||||
private function __forceDisconnection($sConnectionHash)
|
||||
{}
|
||||
|
||||
// TODO: Implement this function: public function setLastCall($zCall, $sConnectionHash) {}
|
||||
}
|
||||
require_once("ModuleBoilerplate.class.php");
|
||||
require_once("moduleLoader.class.php");
|
||||
|
||||
/**
|
||||
* RPC Handler
|
||||
*
|
||||
* Provides methods to handle RPC requests from Overwatchd
|
||||
*/
|
||||
class RPC
|
||||
{
|
||||
/**
|
||||
* Selects the client RPC type in RPC::DoCall
|
||||
* @see DoCall() RPC::DoCall
|
||||
*/
|
||||
const OVR_RPC_TYPE_CLIENT = 1;
|
||||
/**
|
||||
* Selects the Server to Server RPC type in RPC::DoCall
|
||||
* @see DoCall() RPC::DoCall
|
||||
*/
|
||||
const OVR_RPC_TYPE_S2S = 2;
|
||||
|
||||
/**
|
||||
* Calls a function using an APIQL statement
|
||||
*
|
||||
* @param mixed $zPacket APIQL Statement
|
||||
* @return mixed Response from API
|
||||
* @see Overwatch\SDK\v1\Module Module Boilerplate (See Examples)
|
||||
*/
|
||||
private function __apiql_doCall($zPacket)
|
||||
{
|
||||
// TODO: Mangle headers to set connection-id
|
||||
$response = apiql::query($zPacket);
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls a function using pure JSON-RPC
|
||||
*
|
||||
* @param mixed $zPacket JSON-RPC Packet
|
||||
* @return mixed Response from called function
|
||||
*/
|
||||
private function __rpc_doCall($zPacket)
|
||||
{
|
||||
// TODO: Pull apart JSON packet and process through ClassName::__rpc_ClassMethod to prevent RPC calls from calling private functions
|
||||
}
|
||||
|
||||
/**
|
||||
* Call functions from RPC requests
|
||||
* @param mixed $zPacket Incoming RPC Packet
|
||||
* @param integer $iType RPC Call Type
|
||||
* @see OVR_RPC_TYPE_CLIENT
|
||||
* @see OVR_RPC_TYPE_S2S
|
||||
* @return mixed Response from API
|
||||
* @api
|
||||
*/
|
||||
protected function DoCall($zPacket, $iType = \Overwatch\SDK\v1\RPC::OVR_RPC_TYPE_CLIENT)
|
||||
{}
|
||||
}
|
||||
?>
|
||||
141
sdk/v1/Utility.class.php
Normal file
141
sdk/v1/Utility.class.php
Normal file
@@ -0,0 +1,141 @@
|
||||
<?php
|
||||
namespace Overwatch\SDK\v1;
|
||||
/**
|
||||
* Utilities
|
||||
*
|
||||
* Provides common utility functions such as logging.
|
||||
*/
|
||||
class Utility {
|
||||
|
||||
/**
|
||||
* Used to tell the logging functions to use the info level and apply appropriate formatting.
|
||||
* @see \Overwatch\SDK\v1\Utility::Log() Logging function
|
||||
*/
|
||||
const OVR_UTIL_LOGLEVEL_INFO = 0;
|
||||
/**
|
||||
* Used to tell the logging functions to use the warning level and apply appropriate formatting.
|
||||
* @see \Overwatch\SDK\v1\Utility::Log() Logging function
|
||||
*/
|
||||
const OVR_UTIL_LOGLEVEL_WARN = 1;
|
||||
/**
|
||||
* Used to tell the logging functions to use the error level and apply appropriate formatting. Tells LogToConsole to output to stderr
|
||||
* @see \Overwatch\SDK\v1\Utility::Log() Logging function
|
||||
*/
|
||||
const OVR_UTIL_LOGLEVEL_ERROR = 2;
|
||||
/**
|
||||
* Used to tell the logging functions to use the debugging level and apply appropriate formatting.
|
||||
*
|
||||
* NOTE: <b>Messages logged using the debug label will not be written to console or file unless debug mode is enabled.</b>
|
||||
* @see \Overwatch\SDK\v1\Utility::Log() Logging function
|
||||
*/
|
||||
const OVR_UTIL_LOGLEVEL_DEBUG = 3;
|
||||
|
||||
/**
|
||||
* Used to tell the logging functions to log to stdout/stderr
|
||||
* @see \Overwatch\SDK\v1\Utility::Log() Logging function
|
||||
*/
|
||||
const OVR_UTIL_LOG_CONSOLE = 4;
|
||||
|
||||
/**
|
||||
* Used to tell the logging functions to log to a file
|
||||
* @see \Overwatch\SDK\v1\Utility::Log() Logging function
|
||||
*/
|
||||
const OVR_UTIL_LOG_FILE = 5;
|
||||
|
||||
/**
|
||||
* Logs messages to stdout
|
||||
*
|
||||
* @param string $msg Message to write to Log
|
||||
* @param string $component Component that the message is coming from
|
||||
* @param int $level Logging Level
|
||||
* @see \Overwatch\SDK\v1\Utility::OVR_UTIL_LOGLEVEL_INFO OVR_UTIL_LOGLEVEL_INFO
|
||||
* @see \Overwatch\SDK\v1\Utility::OVR_UTIL_LOGLEVEL_ERROR OVR_UTIL_LOGLEVEL_ERROR
|
||||
* @see \Overwatch\SDK\v1\Utility::OVR_UTIL_LOGLEVEL_DEBUG OVR_UTIL_LOGLEVEL_DEBUG
|
||||
* @see \Overwatch\SDK\v1\Utility::OVR_UTIL_LOGLEVEL_WARN OVR_UTIL_LOGLEVEL_WARN
|
||||
* @return void
|
||||
*/
|
||||
static function LogToConsole($msg, $component, $level = \Overwatch\SDK\v1\Utility::OVR_UTIL_LOGLEVEL_INFO)
|
||||
{
|
||||
$oTimeStamp = new \DateTime();
|
||||
$sTimeStamp = $oTimeStamp->format('m-d-Y H:i:s');
|
||||
$component=strtoupper($component);
|
||||
switch ($level)
|
||||
{
|
||||
// TODO: Look into different console codes for coloring and effects
|
||||
case \Overwatch\SDK\v1\Utility::OVR_UTIL_LOGLEVEL_DEBUG:
|
||||
if(defined('\\DEBUG'))
|
||||
{
|
||||
echo("[$sTimeStamp][$component] $msg".PHP_EOL);
|
||||
|
||||
}
|
||||
break;
|
||||
case \Overwatch\SDK\v1\Utility::OVR_UTIL_LOGLEVEL_ERROR:
|
||||
error_log("[$sTimeStamp][$component] $msg".PHP_EOL);
|
||||
break;
|
||||
default:
|
||||
echo("[$sTimeStamp][$component] $msg".PHP_EOL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs messages
|
||||
*
|
||||
* @param string $msg Message to write to Log
|
||||
* @param string $component Component that the message is coming from
|
||||
* @param int $level Logging Level
|
||||
* @see \Overwatch\SDK\v1\Utility::OVR_UTIL_LOGLEVEL_INFO OVR_UTIL_LOGLEVEL_INFO
|
||||
* @see \Overwatch\SDK\v1\Utility::OVR_UTIL_LOGLEVEL_ERROR OVR_UTIL_LOGLEVEL_ERROR
|
||||
* @see \Overwatch\SDK\v1\Utility::OVR_UTIL_LOGLEVEL_DEBUG OVR_UTIL_LOGLEVEL_DEBUG
|
||||
* @see \Overwatch\SDK\v1\Utility::OVR_UTIL_LOGLEVEL_WARN OVR_UTIL_LOGLEVEL_WARN
|
||||
* @param int $type Logging destination
|
||||
* @see \Overwatch\SDK\v1\Utility::OVR_UTIL_LOG_FILE OVR_UTIL_LOG_FILE
|
||||
* @see \Overwatch\SDK\v1\Utility::OVR_UTIL_LOG_CONSOLE OVR_UTIL_LOG_CONSOLE
|
||||
* @param string $file File path to log to (if type is `OVR_UTIL_LOG_FILE`)
|
||||
* @api
|
||||
* @return void
|
||||
*/
|
||||
public static function Log($msg, $component, $level = \Overwatch\SDK\v1\Utility::OVR_UTIL_LOGLEVEL_INFO, $type = \Overwatch\SDK\v1\Utility::OVR_UTIL_LOG_CONSOLE, $file = null)
|
||||
{
|
||||
switch($type)
|
||||
{
|
||||
case \Overwatch\SDK\v1\Utility::OVR_UTIL_LOG_CONSOLE:
|
||||
\Overwatch\SDK\v1\Utility::LogToConsole($msg, $component, $level);
|
||||
break;
|
||||
case \Overwatch\SDK\v1\Utility::OVR_UTIL_LOG_FILE:
|
||||
if($file == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
\Overwatch\SDK\v1\Utility::LogToFile($msg, $component, $level = \Overwatch\SDK\v1\Utility::OVR_UTIL_LOGLEVEL_INFO, $file);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs specified messages to a file.
|
||||
* @param string $msg Message to write to Log
|
||||
* @param string $component Component that the message is coming from
|
||||
* @param string $level Logging Level
|
||||
* @see \Overwatch\SDK\v1\Utility::OVR_UTIL_LOGLEVEL_INFO OVR_UTIL_LOGLEVEL_INFO
|
||||
* @see \Overwatch\SDK\v1\Utility::OVR_UTIL_LOGLEVEL_ERROR OVR_UTIL_LOGLEVEL_ERROR
|
||||
* @see \Overwatch\SDK\v1\Utility::OVR_UTIL_LOGLEVEL_DEBUG OVR_UTIL_LOGLEVEL_DEBUG
|
||||
* @see \Overwatch\SDK\v1\Utility::OVR_UTIL_LOGLEVEL_WARN OVR_UTIL_LOGLEVEL_WARN
|
||||
* @param string $file File to write the message to.
|
||||
* @return void
|
||||
*/
|
||||
protected static function LogToFile($msg, $component, $level = \Overwatch\SDK\v1\Utility::OVR_UTIL_LOGLEVEL_INFO, $file)
|
||||
{
|
||||
$oTimeStamp = new \DateTime();
|
||||
$sTimeStamp = $oTimeStamp->format('m-d-Y H:i:s');
|
||||
$component=strtoupper($component);
|
||||
switch($level)
|
||||
{
|
||||
case \Overwatch\SDK\v1\Utility::OVR_UTIL_LOGLEVEL_ERROR:
|
||||
error_log("[$sTimeStamp][$component] $msg".PHP_EOL, 0, $file);
|
||||
break;
|
||||
default:
|
||||
file_put_contents($file, "[$sTimeStamp][$component] $msg".PHP_EOL, FILE_APPEND);
|
||||
}
|
||||
}
|
||||
}
|
||||
122
sdk/v1/moduleLoader.class.php
Normal file
122
sdk/v1/moduleLoader.class.php
Normal file
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
namespace Overwatch\SDK\v1;
|
||||
/**
|
||||
* OverwatchSDK Module Loader
|
||||
*
|
||||
* Abstracts the overwatch module loader into an easier to use API.
|
||||
*/
|
||||
class ModuleLoader
|
||||
{
|
||||
private $_module_list = array();
|
||||
|
||||
public static function startInst() {
|
||||
static $inst = null;
|
||||
|
||||
if ($inst === null) {
|
||||
$inst = new self;
|
||||
}
|
||||
return $inst;
|
||||
}
|
||||
|
||||
public function loadModule($module, $path = OVERWATCH_MODULES, $type = "API.php") {
|
||||
|
||||
if($path == null)
|
||||
{
|
||||
$path = dirname(__FILE__);
|
||||
$path_specified = false;
|
||||
} else {
|
||||
$path_specified = true;
|
||||
}
|
||||
|
||||
|
||||
if($module === null)
|
||||
die("Error: Module is null.");
|
||||
if($path_specified != true)
|
||||
{
|
||||
if(!file_exists("$path/modules"))
|
||||
die("Error: Modules directory missing.");
|
||||
|
||||
if(!file_exists("$path/modules/$module"))
|
||||
die("Error: Module '$module' not found.");
|
||||
|
||||
if(!file_exists("$path/modules/$module/$module.$type"))
|
||||
die("Error: Module '$module' corrupted.");
|
||||
|
||||
require_once "modules/$module/$module.$type";
|
||||
} else {
|
||||
require_once "$path/$module/$module.$type";
|
||||
}
|
||||
|
||||
$this->_module_list[$module]['stat'] = 'loading';
|
||||
if($this->isModuleLoaded($module) == false)
|
||||
{
|
||||
$this->_module_list[$module]['inst'] = $module::loadInst();
|
||||
} else {
|
||||
\Overwatch\SDK\v1\Utility::Log("$module has already been loaded. Loader bug workaround #1.", "WORKAROUND");
|
||||
}
|
||||
|
||||
|
||||
if(!call_user_func(array($this->_module_list[$module]['inst'], 'module_loaded'))) {
|
||||
$this->_module_list[$module]['stat'] = 'unloaded';
|
||||
die("Error: Module '$module' didn't load.");
|
||||
}
|
||||
$this->_module_list[$module]['stat'] = 'loaded';
|
||||
|
||||
return $this->_module_list[$module]['inst'];
|
||||
}
|
||||
|
||||
public function unloadModule($module = null) {
|
||||
|
||||
$path = dirname(__FILE__);
|
||||
|
||||
if($module === null)
|
||||
die("Error: Module is null.");
|
||||
|
||||
if(is_array($this->_module_list[$module]) &&
|
||||
is_object($this->_module_list[$module]['inst'])) {
|
||||
$this->_module_list[$module]['stat'] = 'unloaded';
|
||||
unset($this->_module_list[$module]['inst']);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function listModules() {
|
||||
return is_array($this->_module_list)?$this->_module_list:array();
|
||||
}
|
||||
|
||||
public function isModuleLoaded($module) {
|
||||
if($this->_module_list[$module]['stat'] == "loaded")
|
||||
{
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads all modules from specified path
|
||||
*
|
||||
* @param string $path Path to Overwatch Modules (defaults to OVERWATCH_MODULES)
|
||||
* @return void
|
||||
* @api
|
||||
*/
|
||||
function LoadModulesFromPath($path = OVERWATCH_MODULES)
|
||||
{
|
||||
$modulesArray = scandir($path);
|
||||
foreach($modulesArray as $moduleName)
|
||||
{
|
||||
if($moduleName != "." && $moduleName != "..")
|
||||
{
|
||||
\Overwatch\SDK\v1\Utility::Log("Module found: $moduleName", "API-MODLOADER", \Overwatch\SDK\v1\Utility::OVR_UTIL_LOGLEVEL_DEBUG);
|
||||
}
|
||||
if(is_dir($path."$moduleName") && $moduleName != "." && $moduleName != "..")
|
||||
{
|
||||
\Overwatch\SDK\v1\Utility::Log("Loading Module: $moduleName", "API-MODLOADER", \Overwatch\SDK\v1\Utility::OVR_UTIL_LOGLEVEL_DEBUG);
|
||||
self::__loadModule($path, $moduleName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
7
vendor/autoload.php
vendored
7
vendor/autoload.php
vendored
@@ -1,7 +0,0 @@
|
||||
<?php
|
||||
|
||||
// autoload.php @generated by Composer
|
||||
|
||||
require_once __DIR__ . '/composer' . '/autoload_real.php';
|
||||
|
||||
return ComposerAutoloaderInit0cf5e3b00d3012d92e986b80c38c2a9f::getLoader();
|
||||
1
vendor/bin/phar-builder
vendored
1
vendor/bin/phar-builder
vendored
@@ -1 +0,0 @@
|
||||
../macfja/phar-builder/bin/phar-builder
|
||||
1
vendor/bin/phar-builder.php
vendored
1
vendor/bin/phar-builder.php
vendored
@@ -1 +0,0 @@
|
||||
../macfja/phar-builder/bin/phar-builder.php
|
||||
1
vendor/bin/phar-composer
vendored
1
vendor/bin/phar-composer
vendored
@@ -1 +0,0 @@
|
||||
../clue/phar-composer/bin/phar-composer
|
||||
1
vendor/clue/phar-composer/.gitignore
vendored
1
vendor/clue/phar-composer/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
/vendor
|
||||
19
vendor/clue/phar-composer/.travis.yml
vendored
19
vendor/clue/phar-composer/.travis.yml
vendored
@@ -1,19 +0,0 @@
|
||||
language: php
|
||||
|
||||
php:
|
||||
- 5.3
|
||||
- 5.6
|
||||
- 7
|
||||
- hhvm
|
||||
|
||||
matrix:
|
||||
allow_failures:
|
||||
- php: 7
|
||||
- php: hhvm
|
||||
|
||||
install:
|
||||
- composer install --prefer-source --no-interaction
|
||||
|
||||
script:
|
||||
- phpunit --coverage-text
|
||||
|
||||
133
vendor/clue/phar-composer/CHANGELOG.md
vendored
133
vendor/clue/phar-composer/CHANGELOG.md
vendored
@@ -1,133 +0,0 @@
|
||||
# Changelog
|
||||
|
||||
## 1.0.0 (2015-11-15)
|
||||
|
||||
* First stable release, now following SemVer.
|
||||
|
||||
* Feature: Can now be installed as a `require-dev` Composer dependency and
|
||||
supports running as `./vendor/bin/phar-composer`.
|
||||
(#36 by @radford)
|
||||
|
||||
* Fix: Actually exclude `vendor/` directory. This prevents processing all
|
||||
vendor files twice and reduces build time by 50%.
|
||||
(#38 by @radford)
|
||||
|
||||
* Fix: Fix error reporting when processing invalid project paths.
|
||||
(#56 by @staabm and @clue)
|
||||
|
||||
* Fix: Fix description of `phar-composer install` command.
|
||||
(#47 by @staabm)
|
||||
|
||||
* Updated documentation, tests and project structure.
|
||||
(#54, #57, #58 and #59 by @clue)
|
||||
|
||||
## 0.5.0 (2014-07-10)
|
||||
|
||||
* Feature: The `search` command is the new default if you do not pass any command
|
||||
([#13](https://github.com/clue/phar-composer/pull/13)).
|
||||
You can now use the following command to get started:
|
||||
|
||||
```bash
|
||||
$ phar-composer
|
||||
```
|
||||
|
||||
* Fix: Pass through STDERR output of child processes instead of aborting
|
||||
([#33](https://github.com/clue/phar-composer/pull/33))
|
||||
|
||||
* Fix: Do not timeout when child process takes longer than 60s.
|
||||
This also helps users with slower internet connections.
|
||||
([#31](https://github.com/clue/phar-composer/pull/31))
|
||||
|
||||
* Fix: Update broken dependencies
|
||||
([#18](https://github.com/clue/phar-composer/pull/18))
|
||||
|
||||
* Fix: Fixed an undocumented config key
|
||||
([#14](https://github.com/clue/phar-composer/pull/14), thanks @mikey179)
|
||||
|
||||
## 0.4.0 (2013-09-12)
|
||||
|
||||
* Feature: New `install` command will now both build the given package and then
|
||||
install it into the system-wide bin directory `/usr/local/bin` (usually already
|
||||
in your `$PATH`). This works for any package name or URL just like with the
|
||||
`build` command, e.g.:
|
||||
|
||||
```bash
|
||||
$ phar-composer install phpunit/phpunit
|
||||
```
|
||||
|
||||
After some (lengthy) build output, you should now be able to run it by just issuing:
|
||||
|
||||
```bash
|
||||
$ phpunit
|
||||
```
|
||||
|
||||
* Feature: New `search` command provides an interactive command line search.
|
||||
It will ask for the package name and issue an search via packagist.org's API and
|
||||
present a list of matching packages. So if you don't know the exact package name,
|
||||
you can now use the following command:
|
||||
|
||||
```bash
|
||||
$ phar-composer search boris
|
||||
```
|
||||
|
||||
* Feature: Both `build` and `install` commands now also optionally accept an
|
||||
additional target directory to place the resulting phar into.
|
||||
|
||||
## 0.3.0 (2013-08-21)
|
||||
|
||||
* Feature: Resulting phar files can now be executed on systems without
|
||||
ext-phar (#8). This vastly improves portability for legacy setups by including
|
||||
a small startup script which self-extracts the current archive into a temporary
|
||||
directory.
|
||||
|
||||
* Feature: Resulting phar files can now be executed without the phar file name
|
||||
extension. E.g. this convenient feature now allows you to move your `~demo.phar`
|
||||
to `/usr/bin/demo` for easy system wide installations.
|
||||
|
||||
* Fix: Resolving absolute paths to `vendor/autoload.php`
|
||||
|
||||
## 0.2.0 (2013-08-15)
|
||||
|
||||
* Feature: Packages can now also be cloned from any git URLs (#9), like this:
|
||||
|
||||
```bash
|
||||
$ phar-composer build https://github.com/clue/phar-composer.git
|
||||
```
|
||||
|
||||
The above will clone the repository and check out the default branch.
|
||||
You can also specify either a tag or branch name very similar to how composer works:
|
||||
|
||||
```bash
|
||||
$ phar-composer build https://github.com/clue/phar-composer.git:dev-master
|
||||
```
|
||||
|
||||
## 0.1.0 (2013-08-12)
|
||||
|
||||
* Feature: Packages listed on packagist.org can now automatically be downloaded and installed
|
||||
prior to generating phar (#7), like this:
|
||||
|
||||
```bash
|
||||
$ phar-composer build clue/phar-composer
|
||||
```
|
||||
|
||||
The above will download and install the latest stable tagged release (if any).
|
||||
You can also specify a tagged version like this:
|
||||
|
||||
```bash
|
||||
$ phar-composer build clue/phar-composer:0.1.*
|
||||
```
|
||||
|
||||
Or you can specify to install the head of a given branch like this:
|
||||
|
||||
```bash
|
||||
$ phar-composer build clue/phar-composer:dev-master
|
||||
```
|
||||
|
||||
## 0.0.2 (2013-05-25)
|
||||
|
||||
* Feature: Bundle complete project directories
|
||||
|
||||
## 0.0.1 (2013-05-18)
|
||||
|
||||
* First tagged release
|
||||
|
||||
21
vendor/clue/phar-composer/LICENSE
vendored
21
vendor/clue/phar-composer/LICENSE
vendored
@@ -1,21 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013 Christian Lück
|
||||
|
||||
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.
|
||||
240
vendor/clue/phar-composer/README.md
vendored
240
vendor/clue/phar-composer/README.md
vendored
@@ -1,240 +0,0 @@
|
||||
# clue/phar-composer [](https://travis-ci.org/clue/phar-composer)
|
||||
|
||||
Simple phar creation for any project managed via composer.
|
||||
|
||||
It takes your existing project's `composer.json` and builds an executable phar
|
||||
for your project among with its bundled dependencies.
|
||||
|
||||
* Create a single executable phar archive, including its dependencies (i.e. vendor directory included)
|
||||
* Automated build process
|
||||
* Zero additional configuration
|
||||
|
||||
**Table of contents**
|
||||
|
||||
* [Usage](#usage)
|
||||
* [phar-composer](#phar-composer)
|
||||
* [phar-composer build](#phar-composer-build)
|
||||
* [phar-composer install](#phar-composer-install)
|
||||
* [phar-composer search](#phar-composer-search)
|
||||
* [Install](#install)
|
||||
* [As a phar (recommended)](#as-a-phar-recommended)
|
||||
* [Updating phar](#updating-phar)
|
||||
* [Installation using Composer](#installation-using-composer)
|
||||
* [Updating dependency](#updating-dependency)
|
||||
* [Manual Installation from Source](#manual-installation-from-source)
|
||||
* [Updating manually](#updating-manually)
|
||||
* [License](#license)
|
||||
|
||||
## Usage
|
||||
|
||||
Once clue/phar-composer is [installed](#install), you can use it via command line like this.
|
||||
|
||||
### phar-composer
|
||||
|
||||
This tool supports several sub-commands. To get you started, you can now use the following simple command:
|
||||
|
||||
```bash
|
||||
$ phar-composer
|
||||
```
|
||||
|
||||
This will actually execute the `search` command that allows you to interactively search and build any package
|
||||
listed on packagist (see below description of the [search command](#phar-composer-search) for more details).
|
||||
|
||||
### phar-composer build
|
||||
|
||||
The `build` command can be used to build an executable single-file phar (php archive) for any project
|
||||
managed by composer:
|
||||
|
||||
```bash
|
||||
$ phar-composer build ~/path/to/your/project
|
||||
```
|
||||
|
||||
The second argument can be pretty much everything that can be resolved to a valid project managed by composer.
|
||||
Besides creating phar archives for locally installed packages like above, you can also easily download and
|
||||
bundle packages from packagist.org like this:
|
||||
|
||||
```bash
|
||||
$ phar-composer build d11wtq/boris
|
||||
```
|
||||
|
||||
The above will download and install the latest stable tagged release (if any).
|
||||
You can also specify a tagged version like this:
|
||||
|
||||
```bash
|
||||
$ phar-composer build clue/phar-composer:~1.0
|
||||
```
|
||||
|
||||
Or you can specify to install the head of a given branch like this:
|
||||
|
||||
```bash
|
||||
$ phar-composer build clue/phar-composer:dev-master
|
||||
```
|
||||
|
||||
A similar syntax can be used to clone a package from any git URL. This is particularly
|
||||
useful for private packages or temporary git clones not otherwise listed on packagist:
|
||||
|
||||
```bash
|
||||
$ phar-composer build https://github.com/composer/composer.git
|
||||
```
|
||||
|
||||
The above will clone the repository and check out the default branch.
|
||||
Again, you can specify either a tag or branch name very similar to how composer works:
|
||||
|
||||
```bash
|
||||
$ phar-composer build https://github.com/composer/composer.git:dev-master
|
||||
```
|
||||
|
||||
### phar-composer install
|
||||
|
||||
The `install` command will both build the given package and then
|
||||
install it into the system-wide bin directory `/usr/local/bin` (usually already
|
||||
in your `$PATH`). This works for any package name or URL just like with the
|
||||
`build` command, e.g.:
|
||||
|
||||
```bash
|
||||
$ phar-composer install phpunit/phpunit
|
||||
```
|
||||
|
||||
After some (lengthy) build output, you should now be able to run it by just issuing:
|
||||
|
||||
```bash
|
||||
$ phpunit
|
||||
```
|
||||
|
||||
> In essence, the `install` command will basically just issue a `build` and then
|
||||
`sudo mv $target.phar /usr/local/bin/$target`. It will ask you for your sudo password
|
||||
when necessary, so it's not needed (and in fact not *recommended*) to run the whole
|
||||
comamnd via `sudo`.
|
||||
|
||||
### phar-composer search
|
||||
|
||||
The `search` command provides an interactive command line search.
|
||||
It will ask for the package name and issue an search via packagist.org's API and
|
||||
present a list of matching packages. So if you don't know the exact package name,
|
||||
you can use the following command:
|
||||
|
||||
```bash
|
||||
$ phar-composer search boris
|
||||
```
|
||||
|
||||
It uses an interactive command line menu to ask you for the matching package name,
|
||||
its version and will then offer you to either `build` or `install` it.
|
||||
|
||||
## Install
|
||||
|
||||
You can grab a copy of clue/phar-composer in either of the following ways.
|
||||
|
||||
### As a phar (recommended)
|
||||
|
||||
You can simply download a pre-compiled and ready-to-use version as a Phar
|
||||
to any directory.
|
||||
Simply download the latest `phar-composer.phar` file from our
|
||||
[releases page](https://github.com/clue/phar-composer/releases):
|
||||
|
||||
[Latest release](https://github.com/clue/phar-composer/releases/latest)
|
||||
|
||||
That's it already. You can now verify everything works by running this:
|
||||
|
||||
```bash
|
||||
$ cd ~/Downloads
|
||||
$ php phar-composer.phar --version
|
||||
```
|
||||
|
||||
The above usage examples assume you've installed phar-composer system-wide to your $PATH (recommended),
|
||||
so you have the following options:
|
||||
|
||||
1. Only use phar-composer locally and adjust the usage examples: So instead of
|
||||
running `$ phar-composer --version`, you have to type `$ php phar-composer.phar --version`.
|
||||
|
||||
2. Use phar-composer's `install` command to install itself to your $PATH by running:
|
||||
|
||||
```bash
|
||||
$ php phar-composer.phar install clue/phar-composer
|
||||
```
|
||||
|
||||
3. Or you can manually make the `phar-composer.phar` executable and move it to your $PATH by running:
|
||||
|
||||
```bash
|
||||
$ chmod 755 phar-composer.phar
|
||||
$ sudo mv phar-composer.phar /usr/local/bin/phar-composer
|
||||
```
|
||||
|
||||
If you have installed phar-composer system-wide, you can now verify everything works by running:
|
||||
|
||||
```bash
|
||||
$ phar-composer --version
|
||||
```
|
||||
|
||||
#### Updating phar
|
||||
|
||||
There's no separate `update` procedure, simply download the latest release again
|
||||
and overwrite the existing phar.
|
||||
|
||||
Again, if you have already installed phar-composer system-wide, this is as easy as
|
||||
running a self-installation like this:
|
||||
|
||||
```bash
|
||||
$ phar-composer install clue/phar-composer
|
||||
```
|
||||
|
||||
### Installation using Composer
|
||||
|
||||
Alternatively, you can also install phar-composer as part of your development dependencies.
|
||||
You will likely want to use the `require-dev` section to exclude phar-composer in your production environment.
|
||||
|
||||
You can either modify your `composer.json` manually or run the following command to include the latest tagged release:
|
||||
|
||||
```bash
|
||||
$ composer require --dev clue/phar-composer
|
||||
```
|
||||
|
||||
Now you should be able to invoke the following command in your project root:
|
||||
|
||||
```bash
|
||||
$ ./vendor/bin/phar-composer --version
|
||||
```
|
||||
|
||||
> Note: You should only invoke and rely on the main phar-composer bin file.
|
||||
Installing this project as a non-dev dependency in order to use its
|
||||
source code as a library is *not supported*.
|
||||
|
||||
#### Updating dependency
|
||||
|
||||
Just run `composer update clue/phar-composer` to update to the latest release.
|
||||
|
||||
### Manual Installation from Source
|
||||
|
||||
This project requires PHP 5.3+ and Composer:
|
||||
|
||||
```bash
|
||||
$ git clone https://github.com/clue/phar-composer.git
|
||||
$ cd phar-composer
|
||||
$ curl -s https://getcomposer.org/installer | php
|
||||
$ php composer.phar install
|
||||
```
|
||||
|
||||
You can now verify everything works by running phar-composer like this:
|
||||
|
||||
```bash
|
||||
$ php bin/phar-composer --version
|
||||
```
|
||||
|
||||
Optionally, you can now build the above mentioned `phar-composer.phar` yourself by issuing:
|
||||
|
||||
```bash
|
||||
$ php bin/phar-composer build
|
||||
```
|
||||
|
||||
Optionally, you can now follow the above instructions for a [system-wide installation](#as-a-phar-recommended).
|
||||
|
||||
|
||||
#### Updating manually
|
||||
|
||||
```bash
|
||||
$ git pull
|
||||
$ php composer.phar install
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
14
vendor/clue/phar-composer/bin/phar-composer
vendored
14
vendor/clue/phar-composer/bin/phar-composer
vendored
@@ -1,14 +0,0 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
if (file_exists(__DIR__ . '/../vendor/autoload.php')) {
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
} elseif (file_exists(__DIR__ . '/../../../autoload.php')) {
|
||||
require __DIR__ . '/../../../autoload.php';
|
||||
} else {
|
||||
fwrite(STDERR, 'ERROR: Composer dependencies not properly set up! Run "composer install" or see README.md for more details' . PHP_EOL);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$app = new Clue\PharComposer\App();
|
||||
$app->run();
|
||||
29
vendor/clue/phar-composer/composer.json
vendored
29
vendor/clue/phar-composer/composer.json
vendored
@@ -1,29 +0,0 @@
|
||||
{
|
||||
"name": "clue/phar-composer",
|
||||
"description": "Simple phar creation for your projects managed via composer",
|
||||
"keywords": ["executable phar", "build process", "bundle dependencies"],
|
||||
"homepage": "https://github.com/clue/phar-composer",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Christian Lück",
|
||||
"email": "christian@lueck.tv"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"herrera-io/box": "~1.5",
|
||||
"symfony/console": "~2.1",
|
||||
"symfony/finder": "~2.1",
|
||||
"symfony/process": "~2.1",
|
||||
"knplabs/packagist-api": "~1.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {"Clue": "src/"}
|
||||
},
|
||||
"bin": ["bin/phar-composer"],
|
||||
"extra": {
|
||||
"phar": {
|
||||
"bundler": "composer"
|
||||
}
|
||||
}
|
||||
}
|
||||
702
vendor/clue/phar-composer/composer.lock
generated
vendored
702
vendor/clue/phar-composer/composer.lock
generated
vendored
@@ -1,702 +0,0 @@
|
||||
{
|
||||
"_readme": [
|
||||
"This file locks the dependencies of your project to a known state",
|
||||
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"hash": "fa5d19b9023764157514f2b1b36431ff",
|
||||
"packages": [
|
||||
{
|
||||
"name": "doctrine/inflector",
|
||||
"version": "v1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/inflector.git",
|
||||
"reference": "54b8333d2a5682afdc690060c1cf384ba9f47f08"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/doctrine/inflector/zipball/54b8333d2a5682afdc690060c1cf384ba9f47f08",
|
||||
"reference": "54b8333d2a5682afdc690060c1cf384ba9f47f08",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.2"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Doctrine\\Common\\Inflector\\": "lib/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jonathan Wage",
|
||||
"email": "jonwage@gmail.com",
|
||||
"homepage": "http://www.jwage.com/",
|
||||
"role": "Creator"
|
||||
},
|
||||
{
|
||||
"name": "Guilherme Blanco",
|
||||
"email": "guilhermeblanco@gmail.com",
|
||||
"homepage": "http://www.instaclick.com"
|
||||
},
|
||||
{
|
||||
"name": "Roman Borschel",
|
||||
"email": "roman@code-factory.org"
|
||||
},
|
||||
{
|
||||
"name": "Benjamin Eberlei",
|
||||
"email": "kontakt@beberlei.de"
|
||||
},
|
||||
{
|
||||
"name": "Johannes Schmitt",
|
||||
"email": "schmittjoh@gmail.com",
|
||||
"homepage": "http://jmsyst.com",
|
||||
"role": "Developer of wrapped JMSSerializerBundle"
|
||||
}
|
||||
],
|
||||
"description": "Common String Manipulations with regard to casing and singular/plural rules.",
|
||||
"homepage": "http://www.doctrine-project.org",
|
||||
"keywords": [
|
||||
"inflection",
|
||||
"pluarlize",
|
||||
"singuarlize",
|
||||
"string"
|
||||
],
|
||||
"time": "2013-01-10 21:49:15"
|
||||
},
|
||||
{
|
||||
"name": "guzzle/common",
|
||||
"version": "v3.8.0",
|
||||
"target-dir": "Guzzle/Common",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/guzzle/common.git",
|
||||
"reference": "eb4e34cac1b18583f0ee74bf6a9dda96bd771a1e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/guzzle/common/zipball/eb4e34cac1b18583f0ee74bf6a9dda96bd771a1e",
|
||||
"reference": "eb4e34cac1b18583f0ee74bf6a9dda96bd771a1e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.2",
|
||||
"symfony/event-dispatcher": ">=2.1"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.7-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Guzzle\\Common": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"description": "Common libraries used by Guzzle",
|
||||
"homepage": "http://guzzlephp.org/",
|
||||
"keywords": [
|
||||
"collection",
|
||||
"common",
|
||||
"event",
|
||||
"exception"
|
||||
],
|
||||
"time": "2013-12-05 23:39:20"
|
||||
},
|
||||
{
|
||||
"name": "guzzle/http",
|
||||
"version": "v3.8.0",
|
||||
"target-dir": "Guzzle/Http",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/guzzle/http.git",
|
||||
"reference": "b497e6b6a5a85751ae0c6858d677f7c4857dd171"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/guzzle/http/zipball/b497e6b6a5a85751ae0c6858d677f7c4857dd171",
|
||||
"reference": "b497e6b6a5a85751ae0c6858d677f7c4857dd171",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"guzzle/common": "self.version",
|
||||
"guzzle/parser": "self.version",
|
||||
"guzzle/stream": "self.version",
|
||||
"php": ">=5.3.2"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-curl": "*"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.7-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Guzzle\\Http": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Michael Dowling",
|
||||
"email": "mtdowling@gmail.com",
|
||||
"homepage": "https://github.com/mtdowling"
|
||||
}
|
||||
],
|
||||
"description": "HTTP libraries used by Guzzle",
|
||||
"homepage": "http://guzzlephp.org/",
|
||||
"keywords": [
|
||||
"Guzzle",
|
||||
"client",
|
||||
"curl",
|
||||
"http",
|
||||
"http client"
|
||||
],
|
||||
"time": "2013-12-04 22:21:25"
|
||||
},
|
||||
{
|
||||
"name": "guzzle/parser",
|
||||
"version": "v3.8.0",
|
||||
"target-dir": "Guzzle/Parser",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/guzzle/parser.git",
|
||||
"reference": "77cae6425bc3466e1e47bdf6d2eebc15a092dbcc"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/guzzle/parser/zipball/77cae6425bc3466e1e47bdf6d2eebc15a092dbcc",
|
||||
"reference": "77cae6425bc3466e1e47bdf6d2eebc15a092dbcc",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.2"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.7-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Guzzle\\Parser": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"description": "Interchangeable parsers used by Guzzle",
|
||||
"homepage": "http://guzzlephp.org/",
|
||||
"keywords": [
|
||||
"URI Template",
|
||||
"cookie",
|
||||
"http",
|
||||
"message",
|
||||
"url"
|
||||
],
|
||||
"time": "2013-10-24 00:04:09"
|
||||
},
|
||||
{
|
||||
"name": "guzzle/stream",
|
||||
"version": "v3.8.0",
|
||||
"target-dir": "Guzzle/Stream",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/guzzle/stream.git",
|
||||
"reference": "a86111d9ac7db31d65a053c825869409fe8fc83f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/guzzle/stream/zipball/a86111d9ac7db31d65a053c825869409fe8fc83f",
|
||||
"reference": "a86111d9ac7db31d65a053c825869409fe8fc83f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"guzzle/common": "self.version",
|
||||
"php": ">=5.3.2"
|
||||
},
|
||||
"suggest": {
|
||||
"guzzle/http": "To convert Guzzle request objects to PHP streams"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.7-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Guzzle\\Stream": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Michael Dowling",
|
||||
"email": "mtdowling@gmail.com",
|
||||
"homepage": "https://github.com/mtdowling"
|
||||
}
|
||||
],
|
||||
"description": "Guzzle stream wrapper component",
|
||||
"homepage": "http://guzzlephp.org/",
|
||||
"keywords": [
|
||||
"Guzzle",
|
||||
"component",
|
||||
"stream"
|
||||
],
|
||||
"time": "2013-07-30 22:07:23"
|
||||
},
|
||||
{
|
||||
"name": "herrera-io/box",
|
||||
"version": "1.5.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/herrera-io/php-box.git",
|
||||
"reference": "596278d729b45ba2dab3f53897d62ac51e0db909"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/herrera-io/php-box/zipball/596278d729b45ba2dab3f53897d62ac51e0db909",
|
||||
"reference": "596278d729b45ba2dab3f53897d62ac51e0db909",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-phar": "*",
|
||||
"phine/path": "~1.0",
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"herrera-io/annotations": "~1.0",
|
||||
"herrera-io/phpunit-test-case": "1.*",
|
||||
"mikey179/vfsstream": "1.1.0",
|
||||
"phpseclib/phpseclib": "~0.3",
|
||||
"phpunit/phpunit": "3.7.*"
|
||||
},
|
||||
"suggest": {
|
||||
"herrera-io/annotations": "For compacting annotated docblocks.",
|
||||
"phpseclib/phpseclib": "For verifying OpenSSL signed phars without the phar extension."
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Herrera\\Box": "src/lib"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Kevin Herrera",
|
||||
"email": "kevin@herrera.io",
|
||||
"homepage": "http://kevin.herrera.io"
|
||||
}
|
||||
],
|
||||
"description": "A library for simplifying the PHAR build process.",
|
||||
"homepage": "http://herrera-io.github.com/php-box",
|
||||
"keywords": [
|
||||
"phar"
|
||||
],
|
||||
"time": "2013-11-09 17:22:29"
|
||||
},
|
||||
{
|
||||
"name": "knplabs/packagist-api",
|
||||
"version": "v1.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/KnpLabs/packagist-api.git",
|
||||
"reference": "5d46003cfb1aca37efc84e8a0f1e8ba276a8245e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/KnpLabs/packagist-api/zipball/5d46003cfb1aca37efc84e8a0f1e8ba276a8245e",
|
||||
"reference": "5d46003cfb1aca37efc84e8a0f1e8ba276a8245e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"doctrine/inflector": "~1.0",
|
||||
"guzzle/http": "~3.0",
|
||||
"php": ">=5.3.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpspec/php-diff": "*@dev",
|
||||
"phpspec/phpspec2": "1.0.*@dev"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Packagist\\Api\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "KnpLabs Team",
|
||||
"homepage": "http://knplabs.com"
|
||||
}
|
||||
],
|
||||
"description": "Packagist API client.",
|
||||
"homepage": "http://knplabs.com",
|
||||
"keywords": [
|
||||
"api",
|
||||
"composer",
|
||||
"packagist"
|
||||
],
|
||||
"time": "2013-11-22 09:55:31"
|
||||
},
|
||||
{
|
||||
"name": "phine/exception",
|
||||
"version": "1.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phine/lib-exception.git",
|
||||
"reference": "150c6b6090b2ebc53c60e87cb20c7f1287b7b68a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phine/lib-exception/zipball/150c6b6090b2ebc53c60e87cb20c7f1287b7b68a",
|
||||
"reference": "150c6b6090b2ebc53c60e87cb20c7f1287b7b68a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"league/phpunit-coverage-listener": "~1.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Phine\\Exception": "src/lib"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Kevin Herrera",
|
||||
"email": "kevin@herrera.io",
|
||||
"homepage": "http://kevin.herrera.io"
|
||||
}
|
||||
],
|
||||
"description": "A PHP library for improving the use of exceptions.",
|
||||
"homepage": "https://github.com/phine/lib-exception",
|
||||
"keywords": [
|
||||
"exception"
|
||||
],
|
||||
"time": "2013-08-27 17:43:25"
|
||||
},
|
||||
{
|
||||
"name": "phine/path",
|
||||
"version": "1.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phine/lib-path.git",
|
||||
"reference": "cbe1a5eb6cf22958394db2469af9b773508abddd"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phine/lib-path/zipball/cbe1a5eb6cf22958394db2469af9b773508abddd",
|
||||
"reference": "cbe1a5eb6cf22958394db2469af9b773508abddd",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"phine/exception": "~1.0",
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"league/phpunit-coverage-listener": "~1.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Phine\\Path": "src/lib"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Kevin Herrera",
|
||||
"email": "kevin@herrera.io",
|
||||
"homepage": "http://kevin.herrera.io"
|
||||
}
|
||||
],
|
||||
"description": "A PHP library for improving the use of file system paths.",
|
||||
"homepage": "https://github.com/phine/lib-path",
|
||||
"keywords": [
|
||||
"file",
|
||||
"path",
|
||||
"system"
|
||||
],
|
||||
"time": "2013-10-15 22:58:04"
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v2.4.1",
|
||||
"target-dir": "Symfony/Component/Console",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Console.git",
|
||||
"reference": "4c1ed2ff514bd85ee186eebb010ccbdeeab05af7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Console/zipball/4c1ed2ff514bd85ee186eebb010ccbdeeab05af7",
|
||||
"reference": "4c1ed2ff514bd85ee186eebb010ccbdeeab05af7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/event-dispatcher": "~2.1"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/event-dispatcher": ""
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.4-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Symfony\\Component\\Console\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "http://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony Console Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2014-01-01 08:14:50"
|
||||
},
|
||||
{
|
||||
"name": "symfony/event-dispatcher",
|
||||
"version": "v2.4.1",
|
||||
"target-dir": "Symfony/Component/EventDispatcher",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/EventDispatcher.git",
|
||||
"reference": "e3ba42f6a70554ed05749e61b829550f6ac33601"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/e3ba42f6a70554ed05749e61b829550f6ac33601",
|
||||
"reference": "e3ba42f6a70554ed05749e61b829550f6ac33601",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/dependency-injection": "~2.0"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/dependency-injection": "",
|
||||
"symfony/http-kernel": ""
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.4-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Symfony\\Component\\EventDispatcher\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "http://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony EventDispatcher Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2013-12-28 08:12:03"
|
||||
},
|
||||
{
|
||||
"name": "symfony/finder",
|
||||
"version": "v2.4.1",
|
||||
"target-dir": "Symfony/Component/Finder",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Finder.git",
|
||||
"reference": "6904345cf2b3bbab1f6d6e4ce1724cb99df9f00a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Finder/zipball/6904345cf2b3bbab1f6d6e4ce1724cb99df9f00a",
|
||||
"reference": "6904345cf2b3bbab1f6d6e4ce1724cb99df9f00a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.4-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Symfony\\Component\\Finder\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "http://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony Finder Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2014-01-01 08:14:50"
|
||||
},
|
||||
{
|
||||
"name": "symfony/process",
|
||||
"version": "v2.4.1",
|
||||
"target-dir": "Symfony/Component/Process",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Process.git",
|
||||
"reference": "58fdccb311e44f28866f976c2d7b3227e9f713db"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Process/zipball/58fdccb311e44f28866f976c2d7b3227e9f713db",
|
||||
"reference": "58fdccb311e44f28866f976c2d7b3227e9f713db",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.4-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Symfony\\Component\\Process\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "http://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony Process Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2014-01-05 02:10:50"
|
||||
}
|
||||
],
|
||||
"packages-dev": [
|
||||
|
||||
],
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": [
|
||||
|
||||
],
|
||||
"platform": [
|
||||
|
||||
],
|
||||
"platform-dev": [
|
||||
|
||||
]
|
||||
}
|
||||
14
vendor/clue/phar-composer/phpunit.xml.dist
vendored
14
vendor/clue/phar-composer/phpunit.xml.dist
vendored
@@ -1,14 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<phpunit bootstrap="./tests/bootstrap.php" colors="true">
|
||||
<testsuites>
|
||||
<testsuite name="PharComposer Test Suite">
|
||||
<directory>./tests/</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory>./src</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
</phpunit>
|
||||
@@ -1,64 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Clue\PharComposer;
|
||||
|
||||
use Symfony\Component\Console\Application as BaseApplication;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
|
||||
class App extends BaseApplication
|
||||
{
|
||||
private $isDefault = false;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('phar-composer', '@git_tag@');
|
||||
|
||||
$this->add(new Command\Build());
|
||||
$this->add(new Command\Search());
|
||||
$this->add(new Command\Install());
|
||||
|
||||
// GUI feature disabled for now, see #35
|
||||
// $this->add(new Command\Gui());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the command based on input.
|
||||
*
|
||||
* @param InputInterface $input The input interface
|
||||
*
|
||||
* @return string The command name
|
||||
*/
|
||||
protected function getCommandName(InputInterface $input)
|
||||
{
|
||||
if ($input->getFirstArgument() === null && !$input->hasParameterOption(array('--help', '-h'))) {
|
||||
$this->isDefault = true;
|
||||
return $this->getDefaultCommandName();
|
||||
}
|
||||
return parent::getCommandName($input);
|
||||
}
|
||||
|
||||
private function getDefaultCommandName()
|
||||
{
|
||||
$gui = $this->has('gui') ? $this->get('gui') : null;
|
||||
if ($gui instanceof Command\Gui && $gui->hasZenity()) {
|
||||
return 'gui';
|
||||
}
|
||||
return 'search';
|
||||
}
|
||||
|
||||
/**
|
||||
* Overridden so that the application doesn't expect the command
|
||||
* name to be the first argument.
|
||||
*/
|
||||
public function getDefinition()
|
||||
{
|
||||
$inputDefinition = parent::getDefinition();
|
||||
|
||||
if ($this->isDefault) {
|
||||
// clear out the normal first argument, which is the command name
|
||||
$inputDefinition->setArguments();
|
||||
}
|
||||
|
||||
return $inputDefinition;
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Clue\PharComposer\Command;
|
||||
|
||||
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
|
||||
use Symfony\Component\Console\Helper\DialogHelper;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Clue\PharComposer\Phar\PharComposer;
|
||||
use InvalidArgumentException;
|
||||
use UnexpectedValueException;
|
||||
use Symfony\Component\Console\Output\Output;
|
||||
use Symfony\Component\Process\Process;
|
||||
use Symfony\Component\Process\ExecutableFinder;
|
||||
use Clue\PharComposer\Phar\Packager;
|
||||
|
||||
class Build extends Command
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('build')
|
||||
->setDescription('Build phar for the given composer project')
|
||||
->addArgument('path', InputArgument::OPTIONAL, 'Path to project directory or composer.json', '.')
|
||||
->addArgument('target', InputArgument::OPTIONAL, 'Path to write phar output to (defaults to project name)');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$packager = new Packager();
|
||||
$packager->setOutput(function ($line) use ($output) {
|
||||
$output->write($line);
|
||||
});
|
||||
|
||||
$packager->coerceWritable();
|
||||
|
||||
$pharer = $packager->getPharer($input->getArgument('path'));
|
||||
|
||||
$target = $input->getArgument('target');
|
||||
if ($target !== null) {
|
||||
$pharer->setTarget($target);
|
||||
}
|
||||
|
||||
$pharer->build();
|
||||
}
|
||||
}
|
||||
@@ -1,283 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Clue\PharComposer\Command;
|
||||
|
||||
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
|
||||
use Symfony\Component\Console\Helper\DialogHelper;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Clue\PharComposer\Phar\PharComposer;
|
||||
use InvalidArgumentException;
|
||||
use UnexpectedValueException;
|
||||
use Symfony\Component\Console\Output\Output;
|
||||
use Symfony\Component\Process\Process;
|
||||
use Symfony\Component\Process\ExecutableFinder;
|
||||
use Packagist\Api\Client;
|
||||
use Packagist\Api\Result\Result;
|
||||
use Packagist\Api\Result\Package;
|
||||
use Packagist\Api\Result\Package\Version;
|
||||
use Clue\PharComposer\Phar\Packager;
|
||||
use React\EventLoop\Factory;
|
||||
use Clue\Zenity\React\Launcher;
|
||||
use Clue\Zenity\React\Builder;
|
||||
|
||||
class Gui extends Command
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('gui')
|
||||
->setDescription('Interactive GUI (requires Zenity, likely only on Linux/etc.)');
|
||||
}
|
||||
|
||||
public function hasZenity()
|
||||
{
|
||||
return $this->hasBin('zenity');
|
||||
}
|
||||
|
||||
private function hasBin($bin)
|
||||
{
|
||||
foreach (explode(PATH_SEPARATOR, getenv('PATH')) as $path) {
|
||||
$path = rtrim($path, '/') . '/' . $bin;
|
||||
if (file_exists($path)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$loop = Factory::create();
|
||||
$launcher = new Launcher($loop);
|
||||
$builder = new Builder($launcher);
|
||||
|
||||
$packager = new Packager();
|
||||
$packager->setOutput(function ($line) use ($builder) {
|
||||
$builder->info(strip_tags($line))->waitReturn();
|
||||
});
|
||||
$packager->coerceWritable(0);
|
||||
|
||||
foreach (array('gksudo', 'kdesudo', 'cocoasudo', 'sudo') as $bin) {
|
||||
if ($this->hasBin($bin)) {
|
||||
$packager->setBinSudo($bin);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$packager->setOutput($output);
|
||||
|
||||
|
||||
$menu = $builder->listMenu(
|
||||
array(
|
||||
'search' => 'Search package online',
|
||||
'local' => 'Select local package',
|
||||
'url' => 'Build from git-Repository',
|
||||
'about' => 'About clue/phar-composer'
|
||||
),
|
||||
'Action'
|
||||
);
|
||||
$menu->setTitle('clue/phar-composer');
|
||||
$menu->setWindowIcon('info');
|
||||
$menu->setCancelLabel('Quit');
|
||||
$selection = $menu->waitReturn();
|
||||
|
||||
if ($selection === 'search') {
|
||||
$pharer = $this->doSearch($builder, $packager);
|
||||
} elseif ($selection === 'local') {
|
||||
do {
|
||||
$dir = $builder->directorySelection()->waitReturn();
|
||||
if ($dir === false) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
$pharer = $packager->getPharer($dir);
|
||||
break;
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
$builder->error('Could not initialize composer package:' . PHP_EOL . PHP_EOL . $e->getMessage())->waitReturn();
|
||||
}
|
||||
} while(true);
|
||||
} elseif ($selection === 'url') {
|
||||
$pharer = $this->doUrl($builder, $packager);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($pharer === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$action = $builder->listMenu(
|
||||
array(
|
||||
'build' => 'Build project',
|
||||
'install' => 'Install project system-wide'
|
||||
),
|
||||
'Action for "' . $pharer->getPackageRoot()->getName() .'"' /*,
|
||||
'Quit' */
|
||||
)->waitReturn();
|
||||
|
||||
if ($action === 'build') {
|
||||
$this->doBuild($builder, $packager, $pharer);
|
||||
} elseif ($action ==='install') {
|
||||
$this->doInstall($builder, $packager, $pharer);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
$builder->info('Successfully built ' . $pharer->getTarget() . '!')->waitReturn();
|
||||
}
|
||||
|
||||
protected function doSearch(Builder $builder, Packager $packager)
|
||||
{
|
||||
$oldname = null;
|
||||
|
||||
do {
|
||||
$dialog = $builder->entry('Search (partial) project name', $oldname);
|
||||
$dialog->setTitle('Search project name');
|
||||
$name = $dialog->waitReturn();
|
||||
if ($name === false) {
|
||||
return;
|
||||
}
|
||||
$oldname = $name;
|
||||
|
||||
$pulsate = $builder->pulsate('Searching for "' . $name . '"...');
|
||||
$pulsate->setNoCancel(true);
|
||||
$pulsate->run();
|
||||
|
||||
$packagist = new Client();
|
||||
|
||||
$choices = array();
|
||||
foreach ($packagist->search($name) as $package) {
|
||||
/* @var $package Result */
|
||||
|
||||
$choices[$package->getName()] = array(
|
||||
$package->getName(),
|
||||
mb_strimwidth($package->getDescription(), 0, 80, '…', 'utf-8'),
|
||||
$package->getDownloads()
|
||||
);
|
||||
}
|
||||
|
||||
$pulsate->close();
|
||||
|
||||
if (!$choices) {
|
||||
$builder->warning('No package matching "' . $name .'" found!')->waitReturn();
|
||||
$name = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
$table = $builder->table($choices, array('Name', 'Description', 'Downloads'), 'Select matching package');
|
||||
$table->setTitle('Select matching package');
|
||||
$table->setCancelLabel('Back to Search');
|
||||
$table->setWidth(1000);
|
||||
$table->setHeight(600);
|
||||
|
||||
$name = $table->waitReturn();
|
||||
} while (is_bool($name));
|
||||
|
||||
$pulsate = $builder->pulsate('Selected <info>' . $name . '</info>, listing versions...');
|
||||
$pulsate->setNoCancel(true);
|
||||
$pulsate->run();
|
||||
|
||||
$package = $packagist->get($name);
|
||||
/* @var $package Package */
|
||||
|
||||
$choices = array();
|
||||
foreach ($package->getVersions() as $version) {
|
||||
/* @var $version Version */
|
||||
|
||||
$time = new \DateTime($version->getTime());
|
||||
$time = $time->format('Y-m-d H:i:s');
|
||||
|
||||
$bin = $version->getBin();
|
||||
if ($bin) {
|
||||
$bin = '☑ ' . array_shift($bin);
|
||||
} else {
|
||||
$bin = '☐ no executable bin';
|
||||
}
|
||||
|
||||
$choices[$version->getVersion()] = array(
|
||||
$version->getVersion(),
|
||||
$time,
|
||||
$bin
|
||||
);
|
||||
}
|
||||
|
||||
$pulsate->close();
|
||||
|
||||
if (!$choices) {
|
||||
$builder->warning('No versions for package "' . $name .'" found!')->waitReturn();
|
||||
return;
|
||||
}
|
||||
|
||||
$dialog = $builder->table($choices, array('Version', 'Date', 'Binary'), 'Select available version');
|
||||
$dialog->setWidth(800);
|
||||
$dialog->setHeight(300);
|
||||
$version = $dialog->waitReturn();
|
||||
|
||||
if (is_bool($version)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$pulsate = $builder->pulsate('Installing to temporary directory...')->run();
|
||||
$pharer = $packager->getPharer($name, $version);
|
||||
$pulsate->close();
|
||||
|
||||
return $pharer;
|
||||
}
|
||||
|
||||
protected function doUrl(Builder $builder, Packager $packager)
|
||||
{
|
||||
do {
|
||||
$url = $builder->entry('Git URL to clone')->waitReturn();
|
||||
if ($url === false) {
|
||||
return;
|
||||
}
|
||||
$pulsate = $builder->pulsate('Cloning and installing from git...')->run();
|
||||
try {
|
||||
$pharer = $packager->getPharer($url);
|
||||
$pulsate->close();
|
||||
|
||||
return $pharer;
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
$pulsate->close();
|
||||
|
||||
$builder->error('Unable to clone repository:' . PHP_EOL . PHP_EOL . $e->getMessage())->waitReturn();
|
||||
}
|
||||
} while(true);
|
||||
}
|
||||
|
||||
protected function doInstall(Builder $builder, Packager $packager, PharComposer $pharer)
|
||||
{
|
||||
$pulsate = $builder->pulsate('Installing...')->run();
|
||||
|
||||
$path = $packager->getSystemBin($pharer);
|
||||
$packager->install($pharer, $path);
|
||||
|
||||
$pulsate->close();
|
||||
}
|
||||
|
||||
protected function doBuild(Builder $builder, Packager $packager, PharComposer $pharer)
|
||||
{
|
||||
$pulsate = $builder->pulsate('Waiting for target file name...')->run();
|
||||
|
||||
$save = $builder->fileSave('Location to write file to', $pharer->getTarget());
|
||||
|
||||
$target = $save->waitReturn();
|
||||
|
||||
if ($target === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
$pulsate->close();
|
||||
$pulsate = $builder->pulsate('Building target file...')->run();
|
||||
|
||||
$pharer->setTarget($target);
|
||||
$pharer->build();
|
||||
|
||||
$pulsate->close();
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Clue\PharComposer\Command;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Clue\PharComposer\Phar\Packager;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Helper\DialogHelper;
|
||||
|
||||
class Install extends Command
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('install')
|
||||
->setDescription('Install phar into system wide binary directory')
|
||||
->addArgument('name', InputArgument::OPTIONAL, 'Project name or path', '.')
|
||||
->addArgument('path', InputArgument::OPTIONAL, 'Path to install to', '/usr/local/bin');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$packager = new Packager();
|
||||
$packager->setOutput($output);
|
||||
$packager->coerceWritable();
|
||||
|
||||
$pharer = $packager->getPharer($input->getArgument('name'));
|
||||
|
||||
$path = $packager->getSystemBin($pharer, $input->getArgument('path'));
|
||||
|
||||
if (is_file($path)) {
|
||||
$dialog = $this->getHelperSet()->get('dialog');
|
||||
/* @var $dialog DialogHelper */
|
||||
|
||||
if (!$dialog->askConfirmation($output, 'Overwrite existing file <info>' . $path . '</info>? [y] > ')) {
|
||||
$output->writeln('Aborting');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$packager->install($pharer, $path);
|
||||
}
|
||||
}
|
||||
@@ -1,153 +0,0 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Clue\PharComposer\Command;
|
||||
|
||||
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
|
||||
use Symfony\Component\Console\Helper\DialogHelper;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Clue\PharComposer\Phar\PharComposer;
|
||||
use InvalidArgumentException;
|
||||
use UnexpectedValueException;
|
||||
use Symfony\Component\Console\Output\Output;
|
||||
use Symfony\Component\Process\Process;
|
||||
use Symfony\Component\Process\ExecutableFinder;
|
||||
use Packagist\Api\Client;
|
||||
use Packagist\Api\Result\Result;
|
||||
use Packagist\Api\Result\Package;
|
||||
use Packagist\Api\Result\Package\Version;
|
||||
use Clue\PharComposer\Phar\Packager;
|
||||
|
||||
class Search extends Command
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('search')
|
||||
->setDescription('Interactive search for project name')
|
||||
->addArgument('name', InputArgument::OPTIONAL, 'Project name or path', null);
|
||||
}
|
||||
|
||||
protected function select(OutputInterface $output, $label, array $choices, $abortable = null)
|
||||
{
|
||||
$dialog = $this->getHelperSet()->get('dialog');
|
||||
/* @var $dialog DialogHelper */
|
||||
|
||||
if (!$choices) {
|
||||
$output->writeln('<error>No matching packages found</error>');
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: skip dialog, if exact match
|
||||
|
||||
if ($abortable === true) {
|
||||
$abortable = '<hl>Abort</hl>';
|
||||
} elseif ($abortable === false) {
|
||||
$abortable = null;
|
||||
}
|
||||
|
||||
$select = array_merge(array(0 => $abortable), array_values($choices));
|
||||
if ($abortable === null) {
|
||||
unset($select[0]);
|
||||
}
|
||||
|
||||
$index = $dialog->select($output, $label, $select);
|
||||
|
||||
if ($index == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$indices = array_keys($choices);
|
||||
return $indices[$index - 1];
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$packager = new Packager();
|
||||
$packager->setOutput($output);
|
||||
$packager->coerceWritable();
|
||||
|
||||
$dialog = $this->getHelperSet()->get('dialog');
|
||||
/* @var $dialog DialogHelper */
|
||||
|
||||
$name = $input->getArgument('name');
|
||||
|
||||
do {
|
||||
if ($name === null) {
|
||||
// ask for input
|
||||
$name = $dialog->ask($output, 'Enter (partial) project name > ');
|
||||
} else {
|
||||
$output->writeln('Searching for <info>' . $name . '</info>...');
|
||||
}
|
||||
|
||||
$packagist = new Client();
|
||||
|
||||
$choices = array();
|
||||
foreach ($packagist->search($name) as $package) {
|
||||
/* @var $package Result */
|
||||
|
||||
$label = str_pad($package->getName(), 39) . ' ';
|
||||
$label = str_replace($name, '<info>' . $name . '</info>', $label);
|
||||
$label .= $package->getDescription();
|
||||
|
||||
$label .= ' (⤓' . $package->getDownloads() . ')';
|
||||
|
||||
$choices[$package->getName()] = $label;
|
||||
}
|
||||
|
||||
$name = $this->select($output, 'Select matching package', $choices, 'Start new search');
|
||||
} while ($name === null);
|
||||
|
||||
$output->writeln('Selected <info>' . $name . '</info>, listing versions...');
|
||||
|
||||
$package = $packagist->get($name);
|
||||
/* @var $package Package */
|
||||
|
||||
$choices = array();
|
||||
foreach ($package->getVersions() as $version) {
|
||||
/* @var $version Version */
|
||||
|
||||
$label = $version->getVersion();
|
||||
|
||||
$bin = $version->getBin();
|
||||
if ($bin === null) {
|
||||
$label .= ' (<error>no executable bin</error>)';
|
||||
} else {
|
||||
$label .= ' (☑ executable bin)';
|
||||
}
|
||||
|
||||
$choices[$version->getVersion()] = $label;
|
||||
}
|
||||
|
||||
$version = $this->select($output, 'Select available version', $choices);
|
||||
|
||||
$action = $this->select(
|
||||
$output,
|
||||
'Action',
|
||||
array(
|
||||
'build' => 'Build project',
|
||||
'install' => 'Install project system-wide'
|
||||
),
|
||||
'Quit'
|
||||
);
|
||||
|
||||
if ($action === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
$pharer = $packager->getPharer($name, $version);
|
||||
|
||||
|
||||
if ($action === 'install') {
|
||||
$path = $packager->getSystemBin($pharer);
|
||||
$packager->install($pharer, $path);
|
||||
} else {
|
||||
$pharer->build();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Clue\PharComposer;
|
||||
|
||||
/**
|
||||
* Interface for logging outout.
|
||||
*
|
||||
* TODO: should be used in the Command classes as well
|
||||
*/
|
||||
class Logger
|
||||
{
|
||||
private $output = true;
|
||||
|
||||
/**
|
||||
* set output function to use to output log messages
|
||||
*
|
||||
* @param callable|boolean $output callable that receives a single $line argument or boolean echo
|
||||
*
|
||||
* TODO: think about whether this should be a constructor instead
|
||||
*/
|
||||
public function setOutput($output)
|
||||
{
|
||||
$this->output = $output;
|
||||
}
|
||||
|
||||
public function log($message)
|
||||
{
|
||||
$this->output($message . PHP_EOL);
|
||||
}
|
||||
|
||||
private function output($message)
|
||||
{
|
||||
if ($this->output === true) {
|
||||
echo $message;
|
||||
} elseif ($this->output !== false) {
|
||||
call_user_func($this->output, $message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Clue\PharComposer\Package;
|
||||
|
||||
/**
|
||||
* Provides access to pathes defined in package autoload configuration.
|
||||
*
|
||||
* @see Package
|
||||
*/
|
||||
class Autoload
|
||||
{
|
||||
/**
|
||||
* package autoload definition
|
||||
*
|
||||
* @type array
|
||||
*/
|
||||
private $autoload;
|
||||
|
||||
public function __construct(array $autoload)
|
||||
{
|
||||
$this->autoload = $autoload;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns all pathes defined by PSR-0
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getPsr0()
|
||||
{
|
||||
if (!isset($this->autoload['psr-0'])) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$resources = array();
|
||||
foreach ($this->autoload['psr-0'] as $namespace => $paths) {
|
||||
foreach($this->correctSinglePath($paths) as $path) {
|
||||
// TODO: this is not correct actually... should work for most repos nevertheless
|
||||
// TODO: we have to take target-dir into account
|
||||
$resources[] = $this->buildNamespacePath($namespace, $path);
|
||||
}
|
||||
}
|
||||
|
||||
return $resources;
|
||||
}
|
||||
|
||||
/**
|
||||
* corrects a single path into a list of pathes
|
||||
*
|
||||
* PSR autoloader may define a single or multiple paths.
|
||||
*
|
||||
* @param string|string[] $paths
|
||||
* @return string[]
|
||||
*/
|
||||
private function correctSinglePath($paths)
|
||||
{
|
||||
if (is_array($paths)) {
|
||||
return $paths;
|
||||
}
|
||||
|
||||
return array($paths);
|
||||
}
|
||||
|
||||
/**
|
||||
* builds namespace path from given namespace and given path
|
||||
*
|
||||
* @param string $namespace
|
||||
* @param string $path
|
||||
* @return string
|
||||
*/
|
||||
private function buildNamespacePath($namespace, $path)
|
||||
{
|
||||
if ($namespace === '') {
|
||||
return $path;
|
||||
}
|
||||
|
||||
$namespace = str_replace('\\', '/', $namespace);
|
||||
if ($path === '') {
|
||||
// namespace in project root => namespace is path
|
||||
return $namespace;
|
||||
}
|
||||
|
||||
// namespace in sub-directory => add namespace to path
|
||||
return rtrim($path, '/') . '/' . $namespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns list of class file resources
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getClassmap()
|
||||
{
|
||||
if (!isset($this->autoload['classmap'])) {
|
||||
return array();
|
||||
}
|
||||
|
||||
return $this->autoload['classmap'];
|
||||
}
|
||||
|
||||
/**
|
||||
* returns list of files defined in autoload
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getFiles()
|
||||
{
|
||||
if (!isset($this->autoload['files'])) {
|
||||
return array();
|
||||
}
|
||||
|
||||
return $this->autoload['files'];
|
||||
}
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Clue\PharComposer\Package;
|
||||
|
||||
use Symfony\Component\Finder\Finder;
|
||||
use Clue\PharComposer\Logger;
|
||||
|
||||
/**
|
||||
* A bundle represents all resources from a package that should be bundled into
|
||||
* the target phar.
|
||||
*/
|
||||
class Bundle implements \IteratorAggregate
|
||||
{
|
||||
/**
|
||||
* list of resources in this bundle
|
||||
*
|
||||
* @type array
|
||||
*/
|
||||
private $resources = array();
|
||||
|
||||
/**
|
||||
* create bundle from given package
|
||||
*
|
||||
* @param Package $package
|
||||
* @param Logger $logger
|
||||
* @return Bundle
|
||||
*/
|
||||
public static function from(Package $package, Logger $logger)
|
||||
{
|
||||
return $package->getBundler($logger)->bundle();
|
||||
}
|
||||
|
||||
/**
|
||||
* add given file to bundle
|
||||
*
|
||||
* @param string $file
|
||||
* @return Bundle
|
||||
*/
|
||||
public function addFile($file)
|
||||
{
|
||||
$this->resources[] = $file;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* add given directory to bundle
|
||||
*
|
||||
* @param Finder $dir
|
||||
* @return Bundle
|
||||
*/
|
||||
public function addDir(Finder $dir)
|
||||
{
|
||||
$this->resources[] = $dir;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* checks if a bundle contains given resource
|
||||
*
|
||||
* @param string $resource
|
||||
* @return bool
|
||||
*/
|
||||
public function contains($resource)
|
||||
{
|
||||
foreach ($this->resources as $containedResource) {
|
||||
if (is_string($containedResource) && $containedResource == $resource) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($containedResource instanceof Finder && $this->directoryContains($containedResource, $resource)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* checks if given directory contains given resource
|
||||
*
|
||||
* @param Finder $dir
|
||||
* @param string $resource
|
||||
* @return bool
|
||||
*/
|
||||
private function directoryContains(Finder $dir, $resource)
|
||||
{
|
||||
foreach ($dir as $containedResource) {
|
||||
/* @var $containedResource \SplFileInfo */
|
||||
if (substr($containedResource->getRealPath(), 0, strlen($resource)) == $resource) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns list of resources
|
||||
*
|
||||
* @return \Traversable
|
||||
*/
|
||||
public function getIterator()
|
||||
{
|
||||
return new \ArrayIterator($this->resources);
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Clue\PharComposer\Package\Bundler;
|
||||
|
||||
/**
|
||||
* The Bundler is responsible for creating a Bundle containing all files which belong to a given package
|
||||
*/
|
||||
interface BundlerInterface
|
||||
{
|
||||
/**
|
||||
* returns a bundle
|
||||
*
|
||||
* @return Bundle
|
||||
*/
|
||||
public function bundle();
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Clue\PharComposer\Package\Bundler;
|
||||
|
||||
use Clue\PharComposer\Package\Bundle;
|
||||
use Clue\PharComposer\Logger;
|
||||
use Clue\PharComposer\Package\Package;
|
||||
use Symfony\Component\Finder\Finder;
|
||||
|
||||
/**
|
||||
* The default Bundler instance which bundles the whole package directory
|
||||
*/
|
||||
class Complete implements BundlerInterface
|
||||
{
|
||||
/**
|
||||
* package the bundler is for
|
||||
*
|
||||
* @type Package
|
||||
*/
|
||||
private $package;
|
||||
/**
|
||||
*
|
||||
* @type Logger
|
||||
*/
|
||||
private $logger;
|
||||
|
||||
public function __construct(Package $package, Logger $logger)
|
||||
{
|
||||
$this->package = $package;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns a bundle
|
||||
*
|
||||
* @return Bundle
|
||||
*/
|
||||
public function bundle()
|
||||
{
|
||||
$bundle = new Bundle();
|
||||
$iterator = Finder::create()
|
||||
->files()
|
||||
->ignoreVCS(true)
|
||||
->filter($this->package->getBlacklistFilter())
|
||||
->exclude($this->package->getPathVendorRelative())
|
||||
->in($this->package->getDirectory());
|
||||
$this->logger->log(' Adding whole project directory "' . $this->package->getDirectory() . '"');
|
||||
return $bundle->addDir($iterator);
|
||||
}
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Clue\PharComposer\Package\Bundler;
|
||||
|
||||
use Clue\PharComposer\Package\Bundle;
|
||||
use Clue\PharComposer\Logger;
|
||||
use Clue\PharComposer\Package\Package;
|
||||
use Clue\PharComposer\Package\Autoload;
|
||||
use Symfony\Component\Finder\Finder;
|
||||
|
||||
/**
|
||||
* Only bundle files explicitly defined in this package's bin and autoload section
|
||||
*/
|
||||
class Explicit implements BundlerInterface
|
||||
{
|
||||
/**
|
||||
* package the bundler is for
|
||||
*
|
||||
* @type Package
|
||||
*/
|
||||
private $package;
|
||||
/**
|
||||
*
|
||||
* @type Logger
|
||||
*/
|
||||
private $logger;
|
||||
|
||||
public function __construct(Package $package, Logger $logger)
|
||||
{
|
||||
$this->package = $package;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns a bundle
|
||||
*
|
||||
* @return Bundle
|
||||
*/
|
||||
public function bundle()
|
||||
{
|
||||
$bundle = new Bundle();
|
||||
$this->bundleBins($bundle);
|
||||
|
||||
$autoload = $this->package->getAutoload();
|
||||
$this->bundlePsr0($bundle, $autoload);
|
||||
$this->bundleClassmap($bundle, $autoload);
|
||||
$this->bundleFiles($bundle, $autoload);
|
||||
|
||||
return $bundle;
|
||||
}
|
||||
|
||||
private function bundleBins(Bundle $bundle)
|
||||
{
|
||||
foreach ($this->package->getBins() as $bin) {
|
||||
$this->logger->log(' adding "' . $bin . '"');
|
||||
$bundle->addFile($bin);
|
||||
}
|
||||
}
|
||||
|
||||
private function bundlePsr0(Bundle $bundle, Autoload $autoload)
|
||||
{
|
||||
foreach ($autoload->getPsr0() as $path) {
|
||||
$this->addDir($bundle, $path);
|
||||
}
|
||||
}
|
||||
|
||||
private function bundleClassmap(Bundle $bundle, Autoload $autoload)
|
||||
{
|
||||
foreach($autoload->getClassmap() as $path) {
|
||||
$this->addFile($bundle, $path);
|
||||
}
|
||||
}
|
||||
|
||||
private function bundleFiles(Bundle $bundle, Autoload $autoload)
|
||||
{
|
||||
foreach($autoload->getFiles() as $path) {
|
||||
$this->addFile($bundle, $path);
|
||||
}
|
||||
}
|
||||
|
||||
private function addFile(Bundle $bundle, $file)
|
||||
{
|
||||
$this->logger->log(' adding "' . $file . '"');
|
||||
$bundle->addFile($this->package->getAbsolutePath($file));
|
||||
}
|
||||
|
||||
private function addDir(Bundle $bundle, $dir)
|
||||
{
|
||||
$dir = $this->package->getAbsolutePath(rtrim($dir, '/') . '/');
|
||||
$this->logger->log(' adding "' . $dir . '"');
|
||||
$bundle->addDir(Finder::create()
|
||||
->files()
|
||||
//->filter($this->getBlacklistFilter())
|
||||
->ignoreVCS(true)
|
||||
->in($dir));
|
||||
}
|
||||
}
|
||||
@@ -1,168 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Clue\PharComposer\Package;;
|
||||
|
||||
use Symfony\Component\Finder\SplFileInfo;
|
||||
use Clue\PharComposer\Package\Bundler\Explicit as ExplicitBundler;
|
||||
use Clue\PharComposer\Package\Bundler\Complete as CompleteBundler;
|
||||
use Clue\PharComposer\Package\Autoload;
|
||||
use Clue\PharComposer\Logger;
|
||||
|
||||
/**
|
||||
* The package represents either the main/root package or one of the vendor packages.
|
||||
*/
|
||||
class Package
|
||||
{
|
||||
/**
|
||||
* Instantiate package
|
||||
*
|
||||
* @param array $package package information (parsed composer.json)
|
||||
* @param string $directory base directory of this package
|
||||
*/
|
||||
public function __construct(array $package, $directory)
|
||||
{
|
||||
$this->package = $package;
|
||||
$this->directory = $directory;
|
||||
}
|
||||
|
||||
/**
|
||||
* get package name as defined in composer.json
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return isset($this->package['name']) ? $this->package['name'] : 'unknown';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get path to vendor directory (relative to package directory)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPathVendorRelative()
|
||||
{
|
||||
$vendor = 'vendor';
|
||||
if (isset($this->package['config']['vendor-dir'])) {
|
||||
$vendor = $this->package['config']['vendor-dir'];
|
||||
}
|
||||
return $vendor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get absolute path to vendor directory
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPathVendor()
|
||||
{
|
||||
return $this->getAbsolutePath($this->getPathVendorRelative() . '/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get package directory (the directory containing its composer.json)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDirectory()
|
||||
{
|
||||
return $this->directory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Bundler instance to bundle this package
|
||||
*
|
||||
* @param Logger $logger
|
||||
* @return BundlerInterface
|
||||
*/
|
||||
public function getBundler(Logger $logger)
|
||||
{
|
||||
$bundlerName = 'complete';
|
||||
if (isset($this->package['extra']['phar']['bundler'])) {
|
||||
$bundlerName = $this->package['extra']['phar']['bundler'];
|
||||
}
|
||||
|
||||
if ($bundlerName === 'composer') {
|
||||
return new ExplicitBundler($this, $logger);
|
||||
} elseif ($bundlerName === 'complete') {
|
||||
return new CompleteBundler($this, $logger);
|
||||
} else {
|
||||
$logger->log('Invalid bundler "' . $bundlerName . '" specified in package "' . $this->getName() . '", will fall back to "complete" bundler');
|
||||
return new CompleteBundler($this, $logger);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Autoload instance containing all autoloading information
|
||||
*
|
||||
* Only used for ExplicitBundler at the moment.
|
||||
*
|
||||
* @return Autoload
|
||||
*/
|
||||
public function getAutoload()
|
||||
{
|
||||
return new Autoload(isset($this->package['autoload']) ? $this->package['autoload'] : array());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of files defined as "bin" (absolute paths)
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getBins()
|
||||
{
|
||||
if (!isset($this->package['bin'])) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$bins = array();
|
||||
foreach ($this->package['bin'] as $bin) {
|
||||
$bins []= $this->getAbsolutePath($bin);
|
||||
}
|
||||
|
||||
return $bins;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get blacklisted files which are not to be included
|
||||
*
|
||||
* Hardcoded to exclude composer.phar and phar-composer.phar at the moment.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getBlacklist()
|
||||
{
|
||||
return array(
|
||||
$this->getAbsolutePath('composer.phar'),
|
||||
$this->getAbsolutePath('phar-composer.phar')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a filter function to exclude blacklisted files
|
||||
*
|
||||
* Only used for CompleteBundler at the moment
|
||||
*
|
||||
* @return Closure
|
||||
* @uses self::getBlacklist()
|
||||
*/
|
||||
public function getBlacklistFilter()
|
||||
{
|
||||
$blacklist = $this->getBlacklist();
|
||||
|
||||
return function (SplFileInfo $file) use ($blacklist) {
|
||||
return in_array($file->getPathname(), $blacklist) ? false : null;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get absolute path for the given package-relative path
|
||||
*
|
||||
* @param string $path
|
||||
* @return string
|
||||
*/
|
||||
public function getAbsolutePath($path)
|
||||
{
|
||||
return $this->directory . ltrim($path, '/');
|
||||
}
|
||||
}
|
||||
@@ -1,313 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Clue\PharComposer\Phar;
|
||||
|
||||
use Symfony\Component\Process\Process;
|
||||
use Symfony\Component\Process\ExecutableFinder;
|
||||
use UnexpectedValueException;
|
||||
use InvalidArgumentException;
|
||||
use RuntimeException;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class Packager
|
||||
{
|
||||
const PATH_BIN = '/usr/local/bin';
|
||||
|
||||
private $output;
|
||||
private $binSudo = 'sudo';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->setOutput(true);
|
||||
}
|
||||
|
||||
private function log($message)
|
||||
{
|
||||
$fn = $this->output;
|
||||
$fn($message . PHP_EOL);
|
||||
}
|
||||
|
||||
public function setBinSudo($bin)
|
||||
{
|
||||
$this->binSudo = $bin;
|
||||
}
|
||||
|
||||
public function setOutput($fn)
|
||||
{
|
||||
if ($fn instanceof OutputInterface) {
|
||||
$fn = function ($line) use ($fn) {
|
||||
$fn->write($line);
|
||||
};
|
||||
} elseif ($fn === true) {
|
||||
$fn = function ($line) {
|
||||
echo $line;
|
||||
};
|
||||
} elseif ($fn === false) {
|
||||
$fn = function () { };
|
||||
}
|
||||
$this->output = $fn;
|
||||
}
|
||||
|
||||
/**
|
||||
* ensure writing phar files is enabled or respawn with PHP setting which allows writing
|
||||
*
|
||||
* @param int $wait
|
||||
* @return void
|
||||
* @uses assertWritable()
|
||||
*/
|
||||
public function coerceWritable($wait = 1)
|
||||
{
|
||||
try {
|
||||
$this->assertWritable();
|
||||
}
|
||||
catch (UnexpectedValueException $e) {
|
||||
if (!function_exists('pcntl_exec')) {
|
||||
$this->log('<error>' . $e->getMessage() . '</error>');
|
||||
return;
|
||||
}
|
||||
|
||||
$this->log('<info>' . $e->getMessage() . ', trying to re-spawn with correct config</info>');
|
||||
if ($wait) {
|
||||
sleep($wait);
|
||||
}
|
||||
|
||||
$args = array_merge(array('php', '-d phar.readonly=off'), $_SERVER['argv']);
|
||||
if (pcntl_exec('/usr/bin/env', $args) === false) {
|
||||
$this->log('<error>Unable to switch into new configuration</error>');
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ensure writing phar files is enabled or throw an exception
|
||||
*
|
||||
* @throws UnexpectedValueException
|
||||
*/
|
||||
public function assertWritable()
|
||||
{
|
||||
if (ini_get('phar.readonly') === '1') {
|
||||
throw new UnexpectedValueException('Your configuration disabled writing phar files (phar.readonly = On), please update your configuration or run with "php -d phar.readonly=off ' . $_SERVER['argv'][0].'"');
|
||||
}
|
||||
}
|
||||
|
||||
public function getPharer($path, $version = null)
|
||||
{
|
||||
if ($version !== null) {
|
||||
// TODO: should be the other way around
|
||||
$path .= ':' . $version;
|
||||
}
|
||||
|
||||
$step = 1;
|
||||
$steps = 1;
|
||||
|
||||
if ($this->isPackageUrl($path)) {
|
||||
$url = $path;
|
||||
$version = null;
|
||||
$steps = 3;
|
||||
|
||||
if (preg_match('/(.+)\:((?:dev\-|v\d)\S+)$/i', $url, $match)) {
|
||||
$url = $match[1];
|
||||
$version = $match[2];
|
||||
if (substr($version, 0, 4) === 'dev-') {
|
||||
$version = substr($version, 4);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$path = $this->getDirTemporary();
|
||||
|
||||
$finder = new ExecutableFinder();
|
||||
|
||||
$git = $finder->find('git', '/usr/bin/git');
|
||||
|
||||
$that = $this;
|
||||
$this->displayMeasure(
|
||||
'[' . $step++ . '/' . $steps.'] Cloning <info>' . $url . '</info> into temporary directory <info>' . $path . '</info>',
|
||||
function() use ($that, $url, $path, $version, $git) {
|
||||
$that->exec($git . ' clone ' . escapeshellarg($url) . ' ' . escapeshellarg($path));
|
||||
|
||||
if ($version !== null) {
|
||||
$this->exec($git . ' checkout ' . escapeshellarg($version) . ' 2>&1', $path);
|
||||
}
|
||||
},
|
||||
'Cloning base repository completed'
|
||||
);
|
||||
|
||||
$pharcomposer = new PharComposer($path . '/composer.json');
|
||||
$package = $pharcomposer->getPackageRoot()->getName();
|
||||
|
||||
if (is_file('composer.phar')) {
|
||||
$command = $finder->find('php', '/usr/bin/php') . ' composer.phar';
|
||||
} else {
|
||||
$command = $finder->find('composer', '/usr/bin/composer');
|
||||
}
|
||||
$command .= ' install --no-dev --no-progress --no-scripts';
|
||||
|
||||
$this->displayMeasure(
|
||||
'[' . $step++ . '/' . $steps.'] Installing dependencies for <info>' . $package . '</info> into <info>' . $path . '</info> (using <info>' . $command . '</info>)',
|
||||
function () use ($that, $command, $path) {
|
||||
try {
|
||||
$that->exec($command, $path);
|
||||
}
|
||||
catch (UnexpectedValueException $e) {
|
||||
throw new UnexpectedValueException('Installing dependencies via composer failed', 0, $e);
|
||||
}
|
||||
},
|
||||
'Downloading dependencies completed'
|
||||
);
|
||||
} elseif ($this->isPackageName($path)) {
|
||||
if (is_dir($path)) {
|
||||
$this->log('<info>There\'s also a directory with the given name</info>');
|
||||
}
|
||||
$steps = 2;
|
||||
$package = $path;
|
||||
|
||||
$path = $this->getDirTemporary();
|
||||
|
||||
$finder = new ExecutableFinder();
|
||||
if (is_file('composer.phar')) {
|
||||
$command = $finder->find('php', '/usr/bin/php') . ' composer.phar';
|
||||
} else {
|
||||
$command = $finder->find('composer', '/usr/bin/composer');
|
||||
}
|
||||
$command .= ' create-project ' . escapeshellarg($package) . ' ' . escapeshellarg($path) . ' --no-dev --no-progress --no-scripts';
|
||||
|
||||
$that = $this;
|
||||
$this->displayMeasure(
|
||||
'[' . $step++ . '/' . $steps.'] Installing <info>' . $package . '</info> to temporary directory <info>' . $path . '</info> (using <info>' . $command . '</info>)',
|
||||
function () use ($that, $command) {
|
||||
try {
|
||||
$that->exec($command);
|
||||
}
|
||||
catch (UnexpectedValueException $e) {
|
||||
throw new UnexpectedValueException('Installing package via composer failed', 0, $e);
|
||||
}
|
||||
},
|
||||
'Downloading package completed'
|
||||
);
|
||||
}
|
||||
|
||||
if (is_dir($path)) {
|
||||
$path = rtrim($path, '/') . '/composer.json';
|
||||
}
|
||||
if (!is_file($path)) {
|
||||
throw new InvalidArgumentException('The given path "' . $path . '" is not a readable file');
|
||||
}
|
||||
|
||||
$pharer = new PharComposer($path);
|
||||
$pharer->setOutput($this->output);
|
||||
$pharer->setStep($step);
|
||||
|
||||
$pathVendor = $pharer->getPathVendor();
|
||||
if (!is_dir($pathVendor)) {
|
||||
throw new RuntimeException('Project is not installed via composer. Run "composer install" manually');
|
||||
}
|
||||
|
||||
return $pharer;
|
||||
}
|
||||
|
||||
public function measure($fn)
|
||||
{
|
||||
$time = microtime(true);
|
||||
|
||||
$fn();
|
||||
|
||||
return max(microtime(true) - $time, 0);
|
||||
}
|
||||
|
||||
public function displayMeasure($title, $fn, $success)
|
||||
{
|
||||
$this->log($title);
|
||||
|
||||
$time = $this->measure($fn);
|
||||
|
||||
$this->log('');
|
||||
$this->log(' <info>OK</info> - ' . $success .' (after ' . round($time, 1) . 's)');
|
||||
}
|
||||
|
||||
public function exec($cmd, $chdir = null)
|
||||
{
|
||||
$nl = true;
|
||||
|
||||
//
|
||||
$output = $this->output;
|
||||
|
||||
$process = new Process($cmd, $chdir);
|
||||
$process->setTimeout(null);
|
||||
$process->start();
|
||||
$code = $process->wait(function($type, $data) use ($output, &$nl) {
|
||||
if ($nl === true) {
|
||||
$data = "\n" . $data;
|
||||
$nl = false;
|
||||
}
|
||||
if (substr($data, -1) === "\n") {
|
||||
$nl = true;
|
||||
$data = substr($data, 0, -1);
|
||||
}
|
||||
$data = str_replace("\n", "\n ", $data);
|
||||
|
||||
$output($data);
|
||||
});
|
||||
if ($nl) {
|
||||
$this->log('');
|
||||
}
|
||||
|
||||
if ($code !== 0) {
|
||||
throw new UnexpectedValueException('Error status code: ' . $process->getExitCodeText() . ' (code ' . $code . ')');
|
||||
}
|
||||
}
|
||||
|
||||
public function install(PharComposer $pharer, $path)
|
||||
{
|
||||
$pharer->build();
|
||||
|
||||
$this->log('Move resulting phar to <info>' . $path . '</info>');
|
||||
$this->exec($this->binSudo . ' -- mv -f ' . escapeshellarg($pharer->getTarget()) . ' ' . escapeshellarg($path));
|
||||
|
||||
$this->log('');
|
||||
$this->log(' <info>OK</info> - Moved to <info>' . $path . '</info>');
|
||||
}
|
||||
|
||||
public function getSystemBin(PharComposer $pharer, $path = null)
|
||||
{
|
||||
// no path given => place in system bin path
|
||||
if ($path === null) {
|
||||
$path = self::PATH_BIN;
|
||||
}
|
||||
|
||||
// no slash => path is relative to system bin path
|
||||
if (strpos($path, '/') === false) {
|
||||
$path = self::PATH_BIN . '/' . $path;
|
||||
}
|
||||
|
||||
// TODO: check path is in $PATH environment
|
||||
|
||||
// path is actually a directory => append package name
|
||||
if (is_dir($path)) {
|
||||
$path = rtrim($path, '/') . '/' . basename($pharer->getTarget(), '.phar');
|
||||
}
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
private function isPackageName($path)
|
||||
{
|
||||
return !!preg_match('/^[^\s\/]+\/[^\s\/]+(\:[^\s]+)?$/i', $path);
|
||||
}
|
||||
|
||||
private function isPackageUrl($path)
|
||||
{
|
||||
return (strpos($path, '://') !== false && @parse_url($path) !== false);
|
||||
}
|
||||
|
||||
private function getDirTemporary()
|
||||
{
|
||||
$path = sys_get_temp_dir() . '/phar-composer' . mt_rand(0,9);
|
||||
while (is_dir($path)) {
|
||||
$path .= mt_rand(0, 9);
|
||||
}
|
||||
|
||||
return $path;
|
||||
}
|
||||
}
|
||||
@@ -1,262 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Clue\PharComposer\Phar;
|
||||
|
||||
use Symfony\Component\Finder\Finder;
|
||||
use Herrera\Box\StubGenerator;
|
||||
use UnexpectedValueException;
|
||||
use InvalidArgumentException;
|
||||
use RuntimeException;
|
||||
use Symfony\Component\Finder\SplFileInfo;
|
||||
use Clue\PharComposer\Logger;
|
||||
use Clue\PharComposer\Package\Bundle;
|
||||
use Clue\PharComposer\Package\Package;
|
||||
|
||||
/**
|
||||
* The PharComposer is responsible for collecting options and then building the target phar
|
||||
*/
|
||||
class PharComposer
|
||||
{
|
||||
private $pathProject;
|
||||
private $package;
|
||||
private $main = null;
|
||||
private $target = null;
|
||||
private $logger;
|
||||
private $step = '?';
|
||||
|
||||
public function __construct($path)
|
||||
{
|
||||
$path = realpath($path);
|
||||
|
||||
$this->package = $this->loadJson($path);
|
||||
$this->pathProject = dirname($path) . '/';
|
||||
$this->logger = new Logger();
|
||||
}
|
||||
|
||||
/**
|
||||
* set output function to use to output log messages
|
||||
*
|
||||
* @param callable|boolean $output callable that receives a single $line argument or boolean echo
|
||||
*/
|
||||
public function setOutput($output)
|
||||
{
|
||||
$this->logger->setOutput($output);
|
||||
}
|
||||
|
||||
public function getTarget()
|
||||
{
|
||||
if ($this->target === null) {
|
||||
if (isset($this->package['name'])) {
|
||||
// skip vendor name from package name
|
||||
$this->target = substr($this->package['name'], strpos($this->package['name'], '/') + 1);
|
||||
} else {
|
||||
$this->target = basename($this->pathProject);
|
||||
}
|
||||
$this->target .= '.phar';
|
||||
}
|
||||
return $this->target;
|
||||
}
|
||||
|
||||
public function setTarget($target)
|
||||
{
|
||||
// path is actually a directory => append package name
|
||||
if (is_dir($target)) {
|
||||
$this->target = null;
|
||||
$target = rtrim($target, '/') . '/' . $this->getTarget();
|
||||
}
|
||||
$this->target = $target;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getMain()
|
||||
{
|
||||
if ($this->main === null) {
|
||||
foreach ($this->getPackageRoot()->getBins() as $path) {
|
||||
if (!file_exists($path)) {
|
||||
throw new UnexpectedValueException('Bin file "' . $path . '" does not exist');
|
||||
}
|
||||
$this->main = $path;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $this->main;
|
||||
}
|
||||
|
||||
public function setMain($main)
|
||||
{
|
||||
$this->main = $main;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* base project path. all files MUST BE relative to this location
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getBase()
|
||||
{
|
||||
return $this->pathProject;
|
||||
}
|
||||
|
||||
/**
|
||||
* get absolute path to vendor directory
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPathVendor()
|
||||
{
|
||||
return $this->getPackageRoot()->getPathVendor();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Package
|
||||
*/
|
||||
public function getPackageRoot()
|
||||
{
|
||||
return new Package($this->package, $this->pathProject);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Package[]
|
||||
*/
|
||||
public function getPackagesDependencies()
|
||||
{
|
||||
$packages = array();
|
||||
|
||||
$pathVendor = $this->getPathVendor();
|
||||
|
||||
// load all installed packages (use installed.json which also includes version instead of composer.lock)
|
||||
if (is_file($pathVendor . 'composer/installed.json')) {
|
||||
// file does not exist if there's nothing to be installed
|
||||
$installed = $this->loadJson($pathVendor . 'composer/installed.json');
|
||||
|
||||
foreach ($installed as $package) {
|
||||
$dir = $package['name'] . '/';
|
||||
if (isset($package['target-dir'])) {
|
||||
$dir .= trim($package['target-dir'], '/') . '/';
|
||||
}
|
||||
|
||||
$dir = $pathVendor . $dir;
|
||||
$packages []= new Package($package, $dir);
|
||||
}
|
||||
}
|
||||
|
||||
return $packages;
|
||||
}
|
||||
|
||||
public function build()
|
||||
{
|
||||
$this->log('[' . $this->step . '/' . $this->step.'] Creating phar <info>' . $this->getTarget() . '</info>');
|
||||
$time = microtime(true);
|
||||
|
||||
$pathVendor = $this->getPathVendor();
|
||||
if (!is_dir($pathVendor)) {
|
||||
throw new RuntimeException('Directory "' . $pathVendor . '" not properly installed, did you run "composer install"?');
|
||||
}
|
||||
|
||||
$target = $this->getTarget();
|
||||
if (file_exists($target)) {
|
||||
$this->log(' - Remove existing file <info>' . $target . '</info> (' . $this->getSize($target) . ')');
|
||||
if(unlink($target) === false) {
|
||||
throw new UnexpectedValueException('Unable to remove existing phar archive "'.$target.'"');
|
||||
}
|
||||
}
|
||||
|
||||
$targetPhar = TargetPhar::create($target, $this);
|
||||
$this->log(' - Adding main package');
|
||||
$targetPhar->addBundle(Bundle::from($this->getPackageRoot(), $this->logger));
|
||||
|
||||
$this->log(' - Adding composer base files');
|
||||
// explicitly add composer autoloader
|
||||
$targetPhar->addFile($pathVendor . 'autoload.php');
|
||||
|
||||
// TODO: check for vendor/bin !
|
||||
|
||||
// only add composer base directory (no sub-directories!)
|
||||
$targetPhar->buildFromIterator(new \GlobIterator($pathVendor . 'composer/*.*', \FilesystemIterator::KEY_AS_FILENAME));
|
||||
|
||||
foreach ($this->getPackagesDependencies() as $package) {
|
||||
$this->log(' - Adding dependency "' . $package->getName() . '" from "' . $this->getPathLocalToBase($package->getDirectory()) . '"');
|
||||
$targetPhar->addBundle(Bundle::from($package, $this->logger));
|
||||
}
|
||||
|
||||
|
||||
$this->log(' - Setting main/stub');
|
||||
$chmod = 0755;
|
||||
$main = $this->getMain();
|
||||
if ($main === null) {
|
||||
$this->log(' WARNING: No main bin file defined! Resulting phar will NOT be executable');
|
||||
} else {
|
||||
$generator = StubGenerator::create()
|
||||
->index($this->getPathLocalToBase($main))
|
||||
->extract(true)
|
||||
->banner("Bundled by phar-composer with the help of php-box.\n\n@link https://github.com/clue/phar-composer");
|
||||
|
||||
$lines = file($main, FILE_IGNORE_NEW_LINES);
|
||||
if (substr($lines[0], 0, 2) === '#!') {
|
||||
$this->log(' Using referenced shebang "'. $lines[0] . '"');
|
||||
$generator->shebang($lines[0]);
|
||||
|
||||
// remove shebang from main file and add (overwrite)
|
||||
unset($lines[0]);
|
||||
$targetPhar->addFromString($this->getPathLocalToBase($main), implode("\n", $lines));
|
||||
}
|
||||
|
||||
$targetPhar->setStub($generator->generate());
|
||||
|
||||
$chmod = octdec(substr(decoct(fileperms($main)),-4));
|
||||
$this->log(' Using referenced chmod ' . sprintf('%04o', $chmod));
|
||||
}
|
||||
|
||||
$targetPhar->finalize();
|
||||
|
||||
if ($chmod !== null) {
|
||||
$this->log(' Applying chmod ' . sprintf('%04o', $chmod));
|
||||
if (chmod($target, $chmod) === false) {
|
||||
throw new UnexpectedValueException('Unable to chmod target file "' . $target .'"');
|
||||
}
|
||||
}
|
||||
|
||||
$time = max(microtime(true) - $time, 0);
|
||||
|
||||
|
||||
|
||||
$this->log('');
|
||||
$this->log(' <info>OK</info> - Creating <info>' . $this->getTarget() .'</info> (' . $this->getSize($this->getTarget()) . ') completed after ' . round($time, 1) . 's');
|
||||
}
|
||||
|
||||
private function getSize($path)
|
||||
{
|
||||
return round(filesize($path) / 1024, 1) . ' KiB';
|
||||
}
|
||||
|
||||
public function getPathLocalToBase($path)
|
||||
{
|
||||
if (strpos($path, $this->pathProject) !== 0) {
|
||||
throw new UnexpectedValueException('Path "' . $path . '" is not within base project path "' . $this->pathProject . '"');
|
||||
}
|
||||
return substr($path, strlen($this->pathProject));
|
||||
}
|
||||
|
||||
public function log($message)
|
||||
{
|
||||
$this->logger->log($message);
|
||||
}
|
||||
|
||||
public function setStep($step)
|
||||
{
|
||||
$this->step = $step;
|
||||
}
|
||||
|
||||
private function loadJson($path)
|
||||
{
|
||||
$ret = json_decode(file_get_contents($path), true);
|
||||
if ($ret === null) {
|
||||
var_dump(json_last_error(), JSON_ERROR_SYNTAX);
|
||||
throw new InvalidArgumentException('Unable to parse given path "' . $path . '"');
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Clue\PharComposer\Phar;
|
||||
|
||||
use Herrera\Box\Box;
|
||||
use Traversable;
|
||||
use Clue\PharComposer\Package\Bundle;
|
||||
|
||||
/**
|
||||
* Represents the target phar to be created.
|
||||
*
|
||||
* TODO: replace PharComposer with a new BasePath class
|
||||
*/
|
||||
class TargetPhar
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @type PharComposer
|
||||
*/
|
||||
private $pharComposer;
|
||||
/**
|
||||
*
|
||||
* @type Box
|
||||
*/
|
||||
private $box;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
*
|
||||
* @param Box $box
|
||||
* @param PharComposer $pharComposer
|
||||
*/
|
||||
public function __construct(Box $box, PharComposer $pharComposer)
|
||||
{
|
||||
$this->box = $box;
|
||||
$this->box->getPhar()->startBuffering();
|
||||
$this->pharComposer = $pharComposer;
|
||||
}
|
||||
|
||||
/**
|
||||
* create new instance in target path
|
||||
*
|
||||
* @param string $target
|
||||
* @param PharComposer $pharComposer
|
||||
* @return TargetPhar
|
||||
*/
|
||||
public static function create($target, PharComposer $pharComposer)
|
||||
{
|
||||
return new self(Box::create($target), $pharComposer);
|
||||
}
|
||||
|
||||
/**
|
||||
* finalize writing of phar file
|
||||
*/
|
||||
public function finalize()
|
||||
{
|
||||
$this->box->getPhar()->stopBuffering();
|
||||
}
|
||||
|
||||
/**
|
||||
* adds given list of resources to phar
|
||||
*
|
||||
* @param Bundle $bundle
|
||||
*/
|
||||
public function addBundle(Bundle $bundle)
|
||||
{
|
||||
foreach ($bundle as $resource) {
|
||||
if (is_string($resource)) {
|
||||
$this->addFile($resource);
|
||||
} else {
|
||||
$this->buildFromIterator($resource);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a file to the Phar, after compacting it and replacing its
|
||||
* placeholders.
|
||||
*
|
||||
* @param string $file The file name.
|
||||
*/
|
||||
public function addFile($file)
|
||||
{
|
||||
$this->box->addFile($file, $this->pharComposer->getPathLocalToBase($file));
|
||||
}
|
||||
|
||||
/**
|
||||
* Similar to Phar::buildFromIterator(), except the files will be compacted
|
||||
* and their placeholders replaced.
|
||||
*
|
||||
* @param Traversable $iterator The iterator.
|
||||
*/
|
||||
public function buildFromIterator(Traversable $iterator)
|
||||
{
|
||||
$this->box->buildFromIterator($iterator, $this->pharComposer->getBase());
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to set the PHP loader or bootstrap stub of a Phar archive
|
||||
*
|
||||
* @param string $stub
|
||||
*/
|
||||
public function setStub($stub)
|
||||
{
|
||||
$this->box->getPhar()->setStub($stub);
|
||||
}
|
||||
|
||||
public function addFromString($local, $contents)
|
||||
{
|
||||
$this->box->addFromString($local, $contents);
|
||||
}
|
||||
}
|
||||
44
vendor/clue/phar-composer/tests/LoggerTest.php
vendored
44
vendor/clue/phar-composer/tests/LoggerTest.php
vendored
@@ -1,44 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Clue\PharComposer\Logger as Logger;
|
||||
|
||||
class LoggerTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* instance to test
|
||||
*
|
||||
* @type Logger
|
||||
*/
|
||||
private $logger;
|
||||
|
||||
/**
|
||||
* set up test environment
|
||||
*/
|
||||
public function setUp()
|
||||
{
|
||||
$this->logger = new Logger();
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function echosToStdOutByDefault()
|
||||
{
|
||||
ob_start();
|
||||
$this->logger->log('some informational message');
|
||||
$this->assertEquals('some informational message' . PHP_EOL,
|
||||
ob_get_contents()
|
||||
);
|
||||
ob_end_clean();
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function callsGivenOutputFunctionWhenSet()
|
||||
{
|
||||
$that = $this;
|
||||
$this->logger->setOutput(function($message) use($that) { $that->assertEquals('some informational message' . PHP_EOL, $message);});
|
||||
$this->logger->log('some informational message');
|
||||
}
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Clue\PharComposer\Package\Autoload;
|
||||
|
||||
class AutoloadTest extends TestCase
|
||||
{
|
||||
private function createAutoload(array $autoload)
|
||||
{
|
||||
return new Autoload($autoload);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function returnsEmptyPsr0ListIfNotDefined()
|
||||
{
|
||||
$this->assertEquals(array(),
|
||||
$this->createAutoload(array())->getPsr0()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function returnsAllPathesDefinedByPsr0WithSinglePath()
|
||||
{
|
||||
$path = realpath(__DIR__ . '/../src');
|
||||
$this->assertEquals(array($path . '/Clue'),
|
||||
$this->createAutoload(array('psr-0' => array('Clue' => $path)))
|
||||
->getPsr0()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function returnsAllPathesDefinedByPsr0WithSeveralPathes()
|
||||
{
|
||||
$path = realpath(__DIR__ . '/../src');
|
||||
$this->assertEquals(array($path . '/Clue', $path . '/Clue'),
|
||||
$this->createAutoload(array('psr-0' => array('Clue' => array($path, $path))))
|
||||
->getPsr0()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function returnsEmptyClassmapIfNotDefined()
|
||||
{
|
||||
$this->assertEquals(array(),
|
||||
$this->createAutoload(array())->getClassmap()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function returnsClassmapAsDefined()
|
||||
{
|
||||
$this->assertEquals(array('Example/SomeClass' => 'src/Example/SomeClass.php'),
|
||||
$this->createAutoload(array('classmap' => array('Example/SomeClass' => 'src/Example/SomeClass.php')))
|
||||
->getClassmap()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function returnsEmptyFilelistIfNotDefined()
|
||||
{
|
||||
$this->assertEquals(array(),
|
||||
$this->createAutoload(array())->getFiles()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function returnsFilelistAsDefined()
|
||||
{
|
||||
$this->assertEquals(array('foo.php', 'bar.php'),
|
||||
$this->createAutoload(array('files' => array('foo.php', 'bar.php')))->getFiles()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Clue\PharComposer\Package\Bundler\Explicit as ExplicitBundler;
|
||||
use Clue\PharComposer\Package\Package;
|
||||
|
||||
class ExplicitBundlerTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* instance to test
|
||||
*
|
||||
* @type ExplicitBundler
|
||||
*/
|
||||
private $explicitBundler;
|
||||
|
||||
private $package;
|
||||
|
||||
private $path;
|
||||
|
||||
/**
|
||||
* set up test environment
|
||||
*/
|
||||
public function setUp()
|
||||
{
|
||||
$this->path = realpath(__DIR__ . '/../../../');
|
||||
$this->package = new Package(array('bin' => array('bin/example'),
|
||||
'autoload' => array('files' => array('foo.php'),
|
||||
'classmap' => array('src/Example/SomeClass.php'),
|
||||
'psr-0' => array('Clue' => 'src')
|
||||
),
|
||||
),
|
||||
$this->path . '/'
|
||||
);
|
||||
$this->explicitBundler = new ExplicitBundler($this->package, $this->createMock('Clue\PharComposer\Logger'));
|
||||
}
|
||||
|
||||
private function createMock($class)
|
||||
{
|
||||
return $this->getMockBuilder($class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function addsBinariesDefinedByPackage()
|
||||
{
|
||||
$this->assertTrue($this->explicitBundler->bundle()->contains($this->path . '/bin/example'),
|
||||
'Failed asserting that "bin/example" is contained in bundle'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function addsFilesDefinedByAutoload()
|
||||
{
|
||||
|
||||
$this->assertTrue($this->explicitBundler->bundle()->contains($this->path . '/foo.php'),
|
||||
'Failed asserting that "foo.php" is contained in bundle'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function addsFilesDefinedByClassmap()
|
||||
{
|
||||
$this->assertTrue($this->explicitBundler->bundle()->contains($this->path . '/src/Example/SomeClass.php'),
|
||||
'Failed asserting that "src/Example/SomeClass.php" is contained in bundle'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function addsAllPathesDefinedByPsr0WithSinglePath()
|
||||
{
|
||||
$this->assertTrue($this->explicitBundler->bundle()->contains($this->path . '/src/Clue/'),
|
||||
'Failed asserting that ' . $this->path . '/src/Clue/ is contained in bundle'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function addsAllPathesDefinedByPsr0WithSeveralPathes()
|
||||
{
|
||||
$this->package = new Package(array('autoload' => array('psr-0' => array('Clue' => array('src/',
|
||||
'src/'
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
$this->path . '/'
|
||||
);
|
||||
$this->explicitBundler = new ExplicitBundler($this->package, $this->createMock('Clue\PharComposer\Logger'));
|
||||
$bundle = $this->explicitBundler->bundle();
|
||||
$this->assertTrue($bundle->contains($this->path . '/src'),
|
||||
'Failed asserting that ' . $this->path . '/src' . ' is contained in bundle'
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Clue\PharComposer\Package\Package;
|
||||
use Clue\PharComposer\Package\Autoload;
|
||||
|
||||
class PackageTest extends TestCase
|
||||
{
|
||||
public function testConstructorDefaults()
|
||||
{
|
||||
$package = new Package(array(), 'dir/');
|
||||
|
||||
$this->assertEquals(new Autoload(array()), $package->getAutoload());
|
||||
$this->assertEquals(array(), $package->getBins());
|
||||
$this->assertEquals('dir/', $package->getDirectory());
|
||||
$this->assertEquals('unknown', $package->getName());
|
||||
$this->assertEquals('dir/vendor/', $package->getPathVendor());
|
||||
}
|
||||
|
||||
public function testConstructorData()
|
||||
{
|
||||
$package = new Package(array(
|
||||
'name' => 'test/test',
|
||||
'bin' => array('bin/main', 'bin2'),
|
||||
'config' => array(
|
||||
'vendor-dir' => 'src/vendors'
|
||||
)
|
||||
), 'dir/');
|
||||
|
||||
$this->assertEquals(array('dir/bin/main', 'dir/bin2'), $package->getBins());
|
||||
$this->assertEquals('test/test', $package->getName());
|
||||
$this->assertEquals('dir/src/vendors/', $package->getPathVendor());
|
||||
}
|
||||
|
||||
private function createMockLogger()
|
||||
{
|
||||
return $this->getMockBuilder('Clue\PharComposer\Logger')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
}
|
||||
|
||||
public function testConstructorBundlerComposer()
|
||||
{
|
||||
$package = new Package(array(
|
||||
'extra' => array(
|
||||
'phar' => array(
|
||||
'bundler' => 'composer'
|
||||
)
|
||||
)
|
||||
), 'dir/');
|
||||
|
||||
$this->assertInstanceOf('Clue\PharComposer\Package\Bundler\Explicit',
|
||||
$package->getBundler($this->createMockLogger())
|
||||
);
|
||||
}
|
||||
|
||||
public function testConstructorBundlerCompleteWithExplicitConfig()
|
||||
{
|
||||
$package = new Package(array(
|
||||
'extra' => array(
|
||||
'phar' => array(
|
||||
'bundler' => 'complete'
|
||||
)
|
||||
)
|
||||
), 'dir/');
|
||||
|
||||
$this->assertInstanceOf('Clue\PharComposer\Package\Bundler\Complete',
|
||||
$package->getBundler($this->createMockLogger())
|
||||
);
|
||||
}
|
||||
|
||||
public function testConstructorBundlerCompleteAsDefault()
|
||||
{
|
||||
$package = new Package(array(), 'dir/');
|
||||
|
||||
$this->assertInstanceOf('Clue\PharComposer\Package\Bundler\Complete',
|
||||
$package->getBundler($this->createMockLogger())
|
||||
);
|
||||
}
|
||||
|
||||
public function testConstructorBundlerInvalid()
|
||||
{
|
||||
$package = new Package(array(
|
||||
'name' => 'cool-package',
|
||||
'extra' => array(
|
||||
'phar' => array(
|
||||
'bundler' => 'foo'
|
||||
)
|
||||
)
|
||||
), 'dir/');
|
||||
|
||||
$mockLogger = $this->createMockLogger();
|
||||
$mockLogger->expects($this->once())
|
||||
->method('log')
|
||||
->with($this->equalTo('Invalid bundler "foo" specified in package "cool-package", will fall back to "complete" bundler'));
|
||||
$this->assertInstanceOf('Clue\PharComposer\Package\Bundler\Complete',
|
||||
$package->getBundler($mockLogger)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Clue\PharComposer\Phar\Packager;
|
||||
|
||||
class PackagerTest extends TestCase
|
||||
{
|
||||
private $packager;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->packager = new Packager();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $expectedOutput
|
||||
* @param string $command
|
||||
* @dataProvider provideExecCommands
|
||||
*/
|
||||
public function testExec($expectedOutput, $command)
|
||||
{
|
||||
$this->expectOutputString($expectedOutput);
|
||||
|
||||
$this->packager->exec($command);
|
||||
}
|
||||
|
||||
public function provideExecCommands()
|
||||
{
|
||||
return array(
|
||||
array("\n output\n", 'echo output'),
|
||||
array("\n error\n", 'echo error >&2'),
|
||||
array("\n mixed\n errors\n", 'echo mixed && echo errors >&1'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException RuntimeException
|
||||
* @expectedExceptionMessage not installed
|
||||
*/
|
||||
public function testEmptyNotInstalled()
|
||||
{
|
||||
$this->packager->getPharer(__DIR__ . '/../fixtures/01-empty');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException InvalidArgumentException
|
||||
* @expectedExceptionMessage not a readable file
|
||||
*/
|
||||
public function testNoComposer()
|
||||
{
|
||||
$this->packager->getPharer(__DIR__ . '/../fixtures/02-no-composer');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException InvalidArgumentException
|
||||
* @expectedExceptionMessage not a readable file
|
||||
*/
|
||||
public function testNoComposerMissing()
|
||||
{
|
||||
$this->packager->getPharer(__DIR__ . '/../fixtures/02-no-composer/composer.json');
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Clue\PharComposer\Phar\PharComposer;
|
||||
|
||||
class PharComposerTest extends TestCase
|
||||
{
|
||||
public function testConstructor()
|
||||
{
|
||||
$pharcomposer = new PharComposer(__DIR__ . '/../../composer.json');
|
||||
|
||||
$this->assertEquals($this->getPathProjectAbsolute('/') . '/', $pharcomposer->getBase());
|
||||
$this->assertEquals($this->getPathProjectAbsolute('bin/phar-composer'), $pharcomposer->getMain());
|
||||
|
||||
$this->assertInstanceOf('Clue\PharComposer\Package\Package', $pharcomposer->getPackageRoot());
|
||||
$this->assertNotCount(0, $pharcomposer->getPackagesDependencies());
|
||||
|
||||
$this->assertEquals($this->getPathProjectAbsolute('vendor') . '/', $pharcomposer->getPathVendor());
|
||||
$this->assertEquals('phar-composer.phar', $pharcomposer->getTarget());
|
||||
|
||||
return $pharcomposer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PharComposer $pharcomposer
|
||||
* @depends testConstructor
|
||||
*/
|
||||
public function testSetters(PharComposer $pharcomposer)
|
||||
{
|
||||
$pharcomposer->setMain('example/phar-composer.php');
|
||||
$this->assertEquals('example/phar-composer.php', $pharcomposer->getMain());
|
||||
|
||||
$pharcomposer->setTarget('test.phar');
|
||||
$this->assertEquals('test.phar', $pharcomposer->getTarget());
|
||||
|
||||
return $pharcomposer;
|
||||
}
|
||||
|
||||
private function getPathProjectAbsolute($path)
|
||||
{
|
||||
return realpath(__DIR__ . '/../../' . $path);
|
||||
}
|
||||
}
|
||||
@@ -1,117 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Clue\PharComposer\Package\Bundle;
|
||||
use Clue\PharComposer\Phar\TargetPhar;
|
||||
|
||||
class TargetPharTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* instance to test
|
||||
*
|
||||
* @ype TargetPhar
|
||||
*/
|
||||
private $targetPhar;
|
||||
|
||||
private $mockPhar;
|
||||
|
||||
private $mockBox;
|
||||
|
||||
private $mockPharComposer;
|
||||
|
||||
/**
|
||||
* set up test environment
|
||||
*/
|
||||
public function setUp()
|
||||
{
|
||||
$this->mockPhar = $this->createMock('\Phar');
|
||||
$this->mockBox = $this->createMock('Herrera\Box\Box');
|
||||
$this->mockBox->expects($this->any())
|
||||
->method('getPhar')
|
||||
->will($this->returnValue($this->mockPhar));
|
||||
$this->mockPharComposer = $this->createMock('Clue\PharComposer\Phar\PharComposer');
|
||||
$this->targetPhar = new TargetPhar($this->mockBox, $this->mockPharComposer);
|
||||
}
|
||||
|
||||
private function createMock($class)
|
||||
{
|
||||
return $this->getMockBuilder($class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function addFileCalculatesLocalPartForBox()
|
||||
{
|
||||
$this->mockPharComposer->expects($this->once())
|
||||
->method('getPathLocalToBase')
|
||||
->with($this->equalTo('path/to/package/file.php'))
|
||||
->will($this->returnValue('file.php'));
|
||||
$this->mockBox->expects($this->once())
|
||||
->method('addFile')
|
||||
->with($this->equalTo('path/to/package/file.php'), $this->equalTo('file.php'));
|
||||
$this->targetPhar->addFile('path/to/package/file.php');
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function buildFromIteratorProvidesBasePathForBox()
|
||||
{
|
||||
$mockTraversable = $this->getMock('\Iterator');
|
||||
$this->mockPharComposer->expects($this->once())
|
||||
->method('getBase')
|
||||
->will($this->returnValue('path/to/package'));
|
||||
$this->mockBox->expects($this->once())
|
||||
->method('buildFromIterator')
|
||||
->with($this->equalTo($mockTraversable), $this->equalTo('path/to/package'));
|
||||
$this->targetPhar->buildFromIterator($mockTraversable);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function addPackageAddsResourcesFromCalculatedBundle()
|
||||
{
|
||||
$bundle = new Bundle();
|
||||
$bundle->addFile('path/to/package/file.php');
|
||||
$this->mockPharComposer->expects($this->once())
|
||||
->method('getPathLocalToBase')
|
||||
->with($this->equalTo('path/to/package/file.php'))
|
||||
->will($this->returnValue('file.php'));
|
||||
$this->mockBox->expects($this->once())
|
||||
->method('addFile')
|
||||
->with($this->equalTo('path/to/package/file.php'), $this->equalTo('file.php'));
|
||||
$mockFinder = $this->createMock('Symfony\Component\Finder\Finder');
|
||||
$bundle->addDir($mockFinder);
|
||||
$this->mockPharComposer->expects($this->once())
|
||||
->method('getBase')
|
||||
->will($this->returnValue('path/to/package'));
|
||||
$this->mockBox->expects($this->once())
|
||||
->method('buildFromIterator')
|
||||
->with($this->equalTo($mockFinder), $this->equalTo('path/to/package'));
|
||||
$this->targetPhar->addBundle($bundle);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function setsStubOnUnderlyingPhar()
|
||||
{
|
||||
$this->mockPhar->expects($this->once())
|
||||
->method('setStub')
|
||||
->with($this->equalTo('some stub code'));
|
||||
$this->targetPhar->setStub('some stub code');
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function finalizeStopsBufferingOnUnderlyingPhar()
|
||||
{
|
||||
$this->mockPhar->expects($this->once())
|
||||
->method('stopBuffering');
|
||||
$this->targetPhar->finalize();
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
<?php
|
||||
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
class TestCase extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"name": "vendor/empty"
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
# Readme
|
||||
|
||||
Not a valid project directory (does not contain a `composer.json` file).
|
||||
413
vendor/composer/ClassLoader.php
vendored
413
vendor/composer/ClassLoader.php
vendored
@@ -1,413 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Composer.
|
||||
*
|
||||
* (c) Nils Adermann <naderman@naderman.de>
|
||||
* Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer\Autoload;
|
||||
|
||||
/**
|
||||
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
|
||||
*
|
||||
* $loader = new \Composer\Autoload\ClassLoader();
|
||||
*
|
||||
* // register classes with namespaces
|
||||
* $loader->add('Symfony\Component', __DIR__.'/component');
|
||||
* $loader->add('Symfony', __DIR__.'/framework');
|
||||
*
|
||||
* // activate the autoloader
|
||||
* $loader->register();
|
||||
*
|
||||
* // to enable searching the include path (eg. for PEAR packages)
|
||||
* $loader->setUseIncludePath(true);
|
||||
*
|
||||
* In this example, if you try to use a class in the Symfony\Component
|
||||
* namespace or one of its children (Symfony\Component\Console for instance),
|
||||
* the autoloader will first look for the class under the component/
|
||||
* directory, and it will then fallback to the framework/ directory if not
|
||||
* found before giving up.
|
||||
*
|
||||
* This class is loosely based on the Symfony UniversalClassLoader.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
* @see http://www.php-fig.org/psr/psr-0/
|
||||
* @see http://www.php-fig.org/psr/psr-4/
|
||||
*/
|
||||
class ClassLoader
|
||||
{
|
||||
// PSR-4
|
||||
private $prefixLengthsPsr4 = array();
|
||||
private $prefixDirsPsr4 = array();
|
||||
private $fallbackDirsPsr4 = array();
|
||||
|
||||
// PSR-0
|
||||
private $prefixesPsr0 = array();
|
||||
private $fallbackDirsPsr0 = array();
|
||||
|
||||
private $useIncludePath = false;
|
||||
private $classMap = array();
|
||||
|
||||
private $classMapAuthoritative = false;
|
||||
|
||||
public function getPrefixes()
|
||||
{
|
||||
if (!empty($this->prefixesPsr0)) {
|
||||
return call_user_func_array('array_merge', $this->prefixesPsr0);
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
public function getPrefixesPsr4()
|
||||
{
|
||||
return $this->prefixDirsPsr4;
|
||||
}
|
||||
|
||||
public function getFallbackDirs()
|
||||
{
|
||||
return $this->fallbackDirsPsr0;
|
||||
}
|
||||
|
||||
public function getFallbackDirsPsr4()
|
||||
{
|
||||
return $this->fallbackDirsPsr4;
|
||||
}
|
||||
|
||||
public function getClassMap()
|
||||
{
|
||||
return $this->classMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $classMap Class to filename map
|
||||
*/
|
||||
public function addClassMap(array $classMap)
|
||||
{
|
||||
if ($this->classMap) {
|
||||
$this->classMap = array_merge($this->classMap, $classMap);
|
||||
} else {
|
||||
$this->classMap = $classMap;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-0 directories for a given prefix, either
|
||||
* appending or prepending to the ones previously set for this prefix.
|
||||
*
|
||||
* @param string $prefix The prefix
|
||||
* @param array|string $paths The PSR-0 root directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
*/
|
||||
public function add($prefix, $paths, $prepend = false)
|
||||
{
|
||||
if (!$prefix) {
|
||||
if ($prepend) {
|
||||
$this->fallbackDirsPsr0 = array_merge(
|
||||
(array) $paths,
|
||||
$this->fallbackDirsPsr0
|
||||
);
|
||||
} else {
|
||||
$this->fallbackDirsPsr0 = array_merge(
|
||||
$this->fallbackDirsPsr0,
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$first = $prefix[0];
|
||||
if (!isset($this->prefixesPsr0[$first][$prefix])) {
|
||||
$this->prefixesPsr0[$first][$prefix] = (array) $paths;
|
||||
|
||||
return;
|
||||
}
|
||||
if ($prepend) {
|
||||
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||
(array) $paths,
|
||||
$this->prefixesPsr0[$first][$prefix]
|
||||
);
|
||||
} else {
|
||||
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||
$this->prefixesPsr0[$first][$prefix],
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-4 directories for a given namespace, either
|
||||
* appending or prepending to the ones previously set for this namespace.
|
||||
*
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param array|string $paths The PSR-4 base directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function addPsr4($prefix, $paths, $prepend = false)
|
||||
{
|
||||
if (!$prefix) {
|
||||
// Register directories for the root namespace.
|
||||
if ($prepend) {
|
||||
$this->fallbackDirsPsr4 = array_merge(
|
||||
(array) $paths,
|
||||
$this->fallbackDirsPsr4
|
||||
);
|
||||
} else {
|
||||
$this->fallbackDirsPsr4 = array_merge(
|
||||
$this->fallbackDirsPsr4,
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
|
||||
// Register directories for a new namespace.
|
||||
$length = strlen($prefix);
|
||||
if ('\\' !== $prefix[$length - 1]) {
|
||||
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
||||
}
|
||||
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
||||
$this->prefixDirsPsr4[$prefix] = (array) $paths;
|
||||
} elseif ($prepend) {
|
||||
// Prepend directories for an already registered namespace.
|
||||
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||
(array) $paths,
|
||||
$this->prefixDirsPsr4[$prefix]
|
||||
);
|
||||
} else {
|
||||
// Append directories for an already registered namespace.
|
||||
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||
$this->prefixDirsPsr4[$prefix],
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-0 directories for a given prefix,
|
||||
* replacing any others previously set for this prefix.
|
||||
*
|
||||
* @param string $prefix The prefix
|
||||
* @param array|string $paths The PSR-0 base directories
|
||||
*/
|
||||
public function set($prefix, $paths)
|
||||
{
|
||||
if (!$prefix) {
|
||||
$this->fallbackDirsPsr0 = (array) $paths;
|
||||
} else {
|
||||
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-4 directories for a given namespace,
|
||||
* replacing any others previously set for this namespace.
|
||||
*
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param array|string $paths The PSR-4 base directories
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function setPsr4($prefix, $paths)
|
||||
{
|
||||
if (!$prefix) {
|
||||
$this->fallbackDirsPsr4 = (array) $paths;
|
||||
} else {
|
||||
$length = strlen($prefix);
|
||||
if ('\\' !== $prefix[$length - 1]) {
|
||||
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
||||
}
|
||||
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
||||
$this->prefixDirsPsr4[$prefix] = (array) $paths;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns on searching the include path for class files.
|
||||
*
|
||||
* @param bool $useIncludePath
|
||||
*/
|
||||
public function setUseIncludePath($useIncludePath)
|
||||
{
|
||||
$this->useIncludePath = $useIncludePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be used to check if the autoloader uses the include path to check
|
||||
* for classes.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getUseIncludePath()
|
||||
{
|
||||
return $this->useIncludePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns off searching the prefix and fallback directories for classes
|
||||
* that have not been registered with the class map.
|
||||
*
|
||||
* @param bool $classMapAuthoritative
|
||||
*/
|
||||
public function setClassMapAuthoritative($classMapAuthoritative)
|
||||
{
|
||||
$this->classMapAuthoritative = $classMapAuthoritative;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should class lookup fail if not found in the current class map?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isClassMapAuthoritative()
|
||||
{
|
||||
return $this->classMapAuthoritative;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers this instance as an autoloader.
|
||||
*
|
||||
* @param bool $prepend Whether to prepend the autoloader or not
|
||||
*/
|
||||
public function register($prepend = false)
|
||||
{
|
||||
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters this instance as an autoloader.
|
||||
*/
|
||||
public function unregister()
|
||||
{
|
||||
spl_autoload_unregister(array($this, 'loadClass'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the given class or interface.
|
||||
*
|
||||
* @param string $class The name of the class
|
||||
* @return bool|null True if loaded, null otherwise
|
||||
*/
|
||||
public function loadClass($class)
|
||||
{
|
||||
if ($file = $this->findFile($class)) {
|
||||
includeFile($file);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the path to the file where the class is defined.
|
||||
*
|
||||
* @param string $class The name of the class
|
||||
*
|
||||
* @return string|false The path if found, false otherwise
|
||||
*/
|
||||
public function findFile($class)
|
||||
{
|
||||
// work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731
|
||||
if ('\\' == $class[0]) {
|
||||
$class = substr($class, 1);
|
||||
}
|
||||
|
||||
// class map lookup
|
||||
if (isset($this->classMap[$class])) {
|
||||
return $this->classMap[$class];
|
||||
}
|
||||
if ($this->classMapAuthoritative) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$file = $this->findFileWithExtension($class, '.php');
|
||||
|
||||
// Search for Hack files if we are running on HHVM
|
||||
if ($file === null && defined('HHVM_VERSION')) {
|
||||
$file = $this->findFileWithExtension($class, '.hh');
|
||||
}
|
||||
|
||||
if ($file === null) {
|
||||
// Remember that this class does not exist.
|
||||
return $this->classMap[$class] = false;
|
||||
}
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
private function findFileWithExtension($class, $ext)
|
||||
{
|
||||
// PSR-4 lookup
|
||||
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
|
||||
|
||||
$first = $class[0];
|
||||
if (isset($this->prefixLengthsPsr4[$first])) {
|
||||
foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) {
|
||||
if (0 === strpos($class, $prefix)) {
|
||||
foreach ($this->prefixDirsPsr4[$prefix] as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-4 fallback dirs
|
||||
foreach ($this->fallbackDirsPsr4 as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 lookup
|
||||
if (false !== $pos = strrpos($class, '\\')) {
|
||||
// namespaced class name
|
||||
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
|
||||
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
|
||||
} else {
|
||||
// PEAR-like class name
|
||||
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
|
||||
}
|
||||
|
||||
if (isset($this->prefixesPsr0[$first])) {
|
||||
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
|
||||
if (0 === strpos($class, $prefix)) {
|
||||
foreach ($dirs as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 fallback dirs
|
||||
foreach ($this->fallbackDirsPsr0 as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 include paths.
|
||||
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope isolated include.
|
||||
*
|
||||
* Prevents access to $this/self from included files.
|
||||
*/
|
||||
function includeFile($file)
|
||||
{
|
||||
include $file;
|
||||
}
|
||||
21
vendor/composer/LICENSE
vendored
21
vendor/composer/LICENSE
vendored
@@ -1,21 +0,0 @@
|
||||
|
||||
Copyright (c) 2016 Nils Adermann, Jordi Boggiano
|
||||
|
||||
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.
|
||||
|
||||
9
vendor/composer/autoload_classmap.php
vendored
9
vendor/composer/autoload_classmap.php
vendored
@@ -1,9 +0,0 @@
|
||||
<?php
|
||||
|
||||
// autoload_classmap.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
);
|
||||
19
vendor/composer/autoload_files.php
vendored
19
vendor/composer/autoload_files.php
vendored
@@ -1,19 +0,0 @@
|
||||
<?php
|
||||
|
||||
// autoload_files.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'ad155f8f1cf0d418fe49e248db8c661b' => $vendorDir . '/react/promise/src/functions_include.php',
|
||||
'540044e0591873ddd06a920c6c94cf8f' => $vendorDir . '/wyrihaximus/ticking-promise/src/functions_include.php',
|
||||
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
|
||||
'a0edc8309cc5e1d60e3047b5df6b7052' => $vendorDir . '/guzzlehttp/psr7/src/functions_include.php',
|
||||
'2cce0c19c44d4e6b9b83d392d5dcc239' => $vendorDir . '/wyrihaximus/react-child-process-promise/src/functions_include.php',
|
||||
'7c9b72b4e40cc7adcca6fd17b1bf4c8d' => $vendorDir . '/indigophp/hash-compat/src/hash_equals.php',
|
||||
'43d9263e52ab88b5668a28ee36bd4e65' => $vendorDir . '/indigophp/hash-compat/src/hash_pbkdf2.php',
|
||||
'e0925b39a86673e84a647fb972717393' => $vendorDir . '/wyrihaximus/cpu-core-detector/src/functions_include.php',
|
||||
'f3b28a95ab3f0417f7cb7996f4fa734a' => $vendorDir . '/wyrihaximus/react-child-process-pool/src/functions_include.php',
|
||||
'5e93f83f32d7c16b062898884b9a20d8' => $vendorDir . '/react/filesystem/src/functions_include.php',
|
||||
);
|
||||
15
vendor/composer/autoload_namespaces.php
vendored
15
vendor/composer/autoload_namespaces.php
vendored
@@ -1,15 +0,0 @@
|
||||
<?php
|
||||
|
||||
// autoload_namespaces.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'SamBurns\\ConfigFileParser\\' => array($vendorDir . '/samburns/config-file-parser/src'),
|
||||
'Guzzle\\Tests' => array($vendorDir . '/guzzle/guzzle/tests'),
|
||||
'Guzzle' => array($vendorDir . '/guzzle/guzzle/src'),
|
||||
'Evenement' => array($vendorDir . '/evenement/evenement/src'),
|
||||
'Doctrine\\Common\\Inflector\\' => array($vendorDir . '/doctrine/inflector/lib'),
|
||||
'' => array($vendorDir . '/webignition/readable-duration/src'),
|
||||
);
|
||||
37
vendor/composer/autoload_psr4.php
vendored
37
vendor/composer/autoload_psr4.php
vendored
@@ -1,37 +0,0 @@
|
||||
<?php
|
||||
|
||||
// autoload_psr4.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'WyriHaximus\\React\\ChildProcess\\Pool\\' => array($vendorDir . '/wyrihaximus/react-child-process-pool/src'),
|
||||
'WyriHaximus\\React\\ChildProcess\\Messenger\\' => array($vendorDir . '/wyrihaximus/react-child-process-messenger/src'),
|
||||
'WyriHaximus\\React\\' => array($vendorDir . '/wyrihaximus/ticking-promise/src', $vendorDir . '/wyrihaximus/react-child-process-promise/src'),
|
||||
'WyriHaximus\\CpuCoreDetector\\' => array($vendorDir . '/wyrihaximus/cpu-core-detector/src'),
|
||||
'Tivie\\OS\\' => array($vendorDir . '/tivie/php-os-detector/src'),
|
||||
'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'),
|
||||
'Symfony\\Component\\Yaml\\' => array($vendorDir . '/symfony/yaml'),
|
||||
'Symfony\\Component\\Finder\\' => array($vendorDir . '/symfony/finder'),
|
||||
'Symfony\\Component\\EventDispatcher\\' => array($vendorDir . '/symfony/event-dispatcher'),
|
||||
'Symfony\\Component\\Console\\' => array($vendorDir . '/symfony/console'),
|
||||
'Rych\\ByteSize\\' => array($vendorDir . '/rych/bytesize/src'),
|
||||
'React\\Stream\\' => array($vendorDir . '/react/stream/src'),
|
||||
'React\\Socket\\' => array($vendorDir . '/react/socket/src'),
|
||||
'React\\SocketClient\\' => array($vendorDir . '/react/socket-client/src'),
|
||||
'React\\Promise\\' => array($vendorDir . '/react/promise/src'),
|
||||
'React\\Http\\' => array($vendorDir . '/react/http/src'),
|
||||
'React\\HttpClient\\' => array($vendorDir . '/react/http-client/src'),
|
||||
'React\\Filesystem\\' => array($vendorDir . '/react/filesystem/src'),
|
||||
'React\\EventLoop\\' => array($vendorDir . '/react/event-loop/src'),
|
||||
'React\\Dns\\' => array($vendorDir . '/react/dns/src'),
|
||||
'React\\ChildProcess\\' => array($vendorDir . '/react/child-process'),
|
||||
'React\\Cache\\' => array($vendorDir . '/react/cache/src'),
|
||||
'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src'),
|
||||
'Noodlehaus\\' => array($vendorDir . '/hassankhan/config/src'),
|
||||
'MacFJA\\Symfony\\Console\\Filechooser\\' => array($vendorDir . '/macfja/symfony-console-filechooser/lib'),
|
||||
'MacFJA\\PharBuilder\\' => array($vendorDir . '/macfja/phar-builder/app'),
|
||||
'Linfo\\' => array($vendorDir . '/linfo/linfo/src/Linfo'),
|
||||
'GuzzleHttp\\Psr7\\' => array($vendorDir . '/guzzlehttp/psr7/src'),
|
||||
);
|
||||
70
vendor/composer/autoload_real.php
vendored
70
vendor/composer/autoload_real.php
vendored
@@ -1,70 +0,0 @@
|
||||
<?php
|
||||
|
||||
// autoload_real.php @generated by Composer
|
||||
|
||||
class ComposerAutoloaderInit0cf5e3b00d3012d92e986b80c38c2a9f
|
||||
{
|
||||
private static $loader;
|
||||
|
||||
public static function loadClassLoader($class)
|
||||
{
|
||||
if ('Composer\Autoload\ClassLoader' === $class) {
|
||||
require __DIR__ . '/ClassLoader.php';
|
||||
}
|
||||
}
|
||||
|
||||
public static function getLoader()
|
||||
{
|
||||
if (null !== self::$loader) {
|
||||
return self::$loader;
|
||||
}
|
||||
|
||||
spl_autoload_register(array('ComposerAutoloaderInit0cf5e3b00d3012d92e986b80c38c2a9f', 'loadClassLoader'), true, true);
|
||||
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInit0cf5e3b00d3012d92e986b80c38c2a9f', 'loadClassLoader'));
|
||||
|
||||
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION');
|
||||
if ($useStaticLoader) {
|
||||
require_once __DIR__ . '/autoload_static.php';
|
||||
|
||||
call_user_func(\Composer\Autoload\ComposerStaticInit0cf5e3b00d3012d92e986b80c38c2a9f::getInitializer($loader));
|
||||
} else {
|
||||
$map = require __DIR__ . '/autoload_namespaces.php';
|
||||
foreach ($map as $namespace => $path) {
|
||||
$loader->set($namespace, $path);
|
||||
}
|
||||
|
||||
$map = require __DIR__ . '/autoload_psr4.php';
|
||||
foreach ($map as $namespace => $path) {
|
||||
$loader->setPsr4($namespace, $path);
|
||||
}
|
||||
|
||||
$classMap = require __DIR__ . '/autoload_classmap.php';
|
||||
if ($classMap) {
|
||||
$loader->addClassMap($classMap);
|
||||
}
|
||||
}
|
||||
|
||||
$loader->register(true);
|
||||
|
||||
if ($useStaticLoader) {
|
||||
$includeFiles = Composer\Autoload\ComposerStaticInit0cf5e3b00d3012d92e986b80c38c2a9f::$files;
|
||||
} else {
|
||||
$includeFiles = require __DIR__ . '/autoload_files.php';
|
||||
}
|
||||
foreach ($includeFiles as $fileIdentifier => $file) {
|
||||
composerRequire0cf5e3b00d3012d92e986b80c38c2a9f($fileIdentifier, $file);
|
||||
}
|
||||
|
||||
return $loader;
|
||||
}
|
||||
}
|
||||
|
||||
function composerRequire0cf5e3b00d3012d92e986b80c38c2a9f($fileIdentifier, $file)
|
||||
{
|
||||
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
||||
require $file;
|
||||
|
||||
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
|
||||
}
|
||||
}
|
||||
245
vendor/composer/autoload_static.php
vendored
245
vendor/composer/autoload_static.php
vendored
@@ -1,245 +0,0 @@
|
||||
<?php
|
||||
|
||||
// autoload_static.php @generated by Composer
|
||||
|
||||
namespace Composer\Autoload;
|
||||
|
||||
class ComposerStaticInit0cf5e3b00d3012d92e986b80c38c2a9f
|
||||
{
|
||||
public static $files = array (
|
||||
'ad155f8f1cf0d418fe49e248db8c661b' => __DIR__ . '/..' . '/react/promise/src/functions_include.php',
|
||||
'540044e0591873ddd06a920c6c94cf8f' => __DIR__ . '/..' . '/wyrihaximus/ticking-promise/src/functions_include.php',
|
||||
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
|
||||
'a0edc8309cc5e1d60e3047b5df6b7052' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/functions_include.php',
|
||||
'2cce0c19c44d4e6b9b83d392d5dcc239' => __DIR__ . '/..' . '/wyrihaximus/react-child-process-promise/src/functions_include.php',
|
||||
'7c9b72b4e40cc7adcca6fd17b1bf4c8d' => __DIR__ . '/..' . '/indigophp/hash-compat/src/hash_equals.php',
|
||||
'43d9263e52ab88b5668a28ee36bd4e65' => __DIR__ . '/..' . '/indigophp/hash-compat/src/hash_pbkdf2.php',
|
||||
'e0925b39a86673e84a647fb972717393' => __DIR__ . '/..' . '/wyrihaximus/cpu-core-detector/src/functions_include.php',
|
||||
'f3b28a95ab3f0417f7cb7996f4fa734a' => __DIR__ . '/..' . '/wyrihaximus/react-child-process-pool/src/functions_include.php',
|
||||
'5e93f83f32d7c16b062898884b9a20d8' => __DIR__ . '/..' . '/react/filesystem/src/functions_include.php',
|
||||
);
|
||||
|
||||
public static $prefixLengthsPsr4 = array (
|
||||
'W' =>
|
||||
array (
|
||||
'WyriHaximus\\React\\ChildProcess\\Pool\\' => 36,
|
||||
'WyriHaximus\\React\\ChildProcess\\Messenger\\' => 41,
|
||||
'WyriHaximus\\React\\' => 18,
|
||||
'WyriHaximus\\CpuCoreDetector\\' => 28,
|
||||
),
|
||||
'T' =>
|
||||
array (
|
||||
'Tivie\\OS\\' => 9,
|
||||
),
|
||||
'S' =>
|
||||
array (
|
||||
'Symfony\\Polyfill\\Mbstring\\' => 26,
|
||||
'Symfony\\Component\\Yaml\\' => 23,
|
||||
'Symfony\\Component\\Finder\\' => 25,
|
||||
'Symfony\\Component\\EventDispatcher\\' => 34,
|
||||
'Symfony\\Component\\Console\\' => 26,
|
||||
),
|
||||
'R' =>
|
||||
array (
|
||||
'Rych\\ByteSize\\' => 14,
|
||||
'React\\Stream\\' => 13,
|
||||
'React\\Socket\\' => 13,
|
||||
'React\\SocketClient\\' => 19,
|
||||
'React\\Promise\\' => 14,
|
||||
'React\\Http\\' => 11,
|
||||
'React\\HttpClient\\' => 17,
|
||||
'React\\Filesystem\\' => 17,
|
||||
'React\\EventLoop\\' => 16,
|
||||
'React\\Dns\\' => 10,
|
||||
'React\\ChildProcess\\' => 19,
|
||||
'React\\Cache\\' => 12,
|
||||
),
|
||||
'P' =>
|
||||
array (
|
||||
'Psr\\Http\\Message\\' => 17,
|
||||
),
|
||||
'N' =>
|
||||
array (
|
||||
'Noodlehaus\\' => 11,
|
||||
),
|
||||
'M' =>
|
||||
array (
|
||||
'MacFJA\\Symfony\\Console\\Filechooser\\' => 35,
|
||||
'MacFJA\\PharBuilder\\' => 19,
|
||||
),
|
||||
'L' =>
|
||||
array (
|
||||
'Linfo\\' => 6,
|
||||
),
|
||||
'G' =>
|
||||
array (
|
||||
'GuzzleHttp\\Psr7\\' => 16,
|
||||
),
|
||||
);
|
||||
|
||||
public static $prefixDirsPsr4 = array (
|
||||
'WyriHaximus\\React\\ChildProcess\\Pool\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/wyrihaximus/react-child-process-pool/src',
|
||||
),
|
||||
'WyriHaximus\\React\\ChildProcess\\Messenger\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/wyrihaximus/react-child-process-messenger/src',
|
||||
),
|
||||
'WyriHaximus\\React\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/wyrihaximus/ticking-promise/src',
|
||||
1 => __DIR__ . '/..' . '/wyrihaximus/react-child-process-promise/src',
|
||||
),
|
||||
'WyriHaximus\\CpuCoreDetector\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/wyrihaximus/cpu-core-detector/src',
|
||||
),
|
||||
'Tivie\\OS\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/tivie/php-os-detector/src',
|
||||
),
|
||||
'Symfony\\Polyfill\\Mbstring\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring',
|
||||
),
|
||||
'Symfony\\Component\\Yaml\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/symfony/yaml',
|
||||
),
|
||||
'Symfony\\Component\\Finder\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/symfony/finder',
|
||||
),
|
||||
'Symfony\\Component\\EventDispatcher\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/symfony/event-dispatcher',
|
||||
),
|
||||
'Symfony\\Component\\Console\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/symfony/console',
|
||||
),
|
||||
'Rych\\ByteSize\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/rych/bytesize/src',
|
||||
),
|
||||
'React\\Stream\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/react/stream/src',
|
||||
),
|
||||
'React\\Socket\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/react/socket/src',
|
||||
),
|
||||
'React\\SocketClient\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/react/socket-client/src',
|
||||
),
|
||||
'React\\Promise\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/react/promise/src',
|
||||
),
|
||||
'React\\Http\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/react/http/src',
|
||||
),
|
||||
'React\\HttpClient\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/react/http-client/src',
|
||||
),
|
||||
'React\\Filesystem\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/react/filesystem/src',
|
||||
),
|
||||
'React\\EventLoop\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/react/event-loop/src',
|
||||
),
|
||||
'React\\Dns\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/react/dns/src',
|
||||
),
|
||||
'React\\ChildProcess\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/react/child-process',
|
||||
),
|
||||
'React\\Cache\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/react/cache/src',
|
||||
),
|
||||
'Psr\\Http\\Message\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/psr/http-message/src',
|
||||
),
|
||||
'Noodlehaus\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/hassankhan/config/src',
|
||||
),
|
||||
'MacFJA\\Symfony\\Console\\Filechooser\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/macfja/symfony-console-filechooser/lib',
|
||||
),
|
||||
'MacFJA\\PharBuilder\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/macfja/phar-builder/app',
|
||||
),
|
||||
'Linfo\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/linfo/linfo/src/Linfo',
|
||||
),
|
||||
'GuzzleHttp\\Psr7\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/guzzlehttp/psr7/src',
|
||||
),
|
||||
);
|
||||
|
||||
public static $prefixesPsr0 = array (
|
||||
'S' =>
|
||||
array (
|
||||
'SamBurns\\ConfigFileParser\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/samburns/config-file-parser/src',
|
||||
),
|
||||
),
|
||||
'G' =>
|
||||
array (
|
||||
'Guzzle\\Tests' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/guzzle/guzzle/tests',
|
||||
),
|
||||
'Guzzle' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/guzzle/guzzle/src',
|
||||
),
|
||||
),
|
||||
'E' =>
|
||||
array (
|
||||
'Evenement' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/evenement/evenement/src',
|
||||
),
|
||||
),
|
||||
'D' =>
|
||||
array (
|
||||
'Doctrine\\Common\\Inflector\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/doctrine/inflector/lib',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
public static $fallbackDirsPsr0 = array (
|
||||
0 => __DIR__ . '/..' . '/webignition/readable-duration/src',
|
||||
);
|
||||
|
||||
public static function getInitializer(ClassLoader $loader)
|
||||
{
|
||||
return \Closure::bind(function () use ($loader) {
|
||||
$loader->prefixLengthsPsr4 = ComposerStaticInit0cf5e3b00d3012d92e986b80c38c2a9f::$prefixLengthsPsr4;
|
||||
$loader->prefixDirsPsr4 = ComposerStaticInit0cf5e3b00d3012d92e986b80c38c2a9f::$prefixDirsPsr4;
|
||||
$loader->prefixesPsr0 = ComposerStaticInit0cf5e3b00d3012d92e986b80c38c2a9f::$prefixesPsr0;
|
||||
$loader->fallbackDirsPsr0 = ComposerStaticInit0cf5e3b00d3012d92e986b80c38c2a9f::$fallbackDirsPsr0;
|
||||
|
||||
}, null, ClassLoader::class);
|
||||
}
|
||||
}
|
||||
1870
vendor/composer/installed.json
vendored
1870
vendor/composer/installed.json
vendored
File diff suppressed because it is too large
Load Diff
4
vendor/doctrine/inflector/.gitignore
vendored
4
vendor/doctrine/inflector/.gitignore
vendored
@@ -1,4 +0,0 @@
|
||||
vendor/
|
||||
composer.lock
|
||||
composer.phar
|
||||
phpunit.xml
|
||||
21
vendor/doctrine/inflector/.travis.yml
vendored
21
vendor/doctrine/inflector/.travis.yml
vendored
@@ -1,21 +0,0 @@
|
||||
language: php
|
||||
|
||||
sudo: false
|
||||
|
||||
cache:
|
||||
directory:
|
||||
- $HOME/.composer/cache
|
||||
|
||||
php:
|
||||
- 5.3
|
||||
- 5.4
|
||||
- 5.5
|
||||
- 5.6
|
||||
- 7.0
|
||||
- hhvm
|
||||
|
||||
install:
|
||||
- composer install -n
|
||||
|
||||
script:
|
||||
- phpunit
|
||||
19
vendor/doctrine/inflector/LICENSE
vendored
19
vendor/doctrine/inflector/LICENSE
vendored
@@ -1,19 +0,0 @@
|
||||
Copyright (c) 2006-2015 Doctrine Project
|
||||
|
||||
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.
|
||||
6
vendor/doctrine/inflector/README.md
vendored
6
vendor/doctrine/inflector/README.md
vendored
@@ -1,6 +0,0 @@
|
||||
# Doctrine Inflector
|
||||
|
||||
Doctrine Inflector is a small library that can perform string manipulations
|
||||
with regard to upper-/lowercase and singular/plural forms of words.
|
||||
|
||||
[](https://travis-ci.org/doctrine/inflector)
|
||||
29
vendor/doctrine/inflector/composer.json
vendored
29
vendor/doctrine/inflector/composer.json
vendored
@@ -1,29 +0,0 @@
|
||||
{
|
||||
"name": "doctrine/inflector",
|
||||
"type": "library",
|
||||
"description": "Common String Manipulations with regard to casing and singular/plural rules.",
|
||||
"keywords": ["string", "inflection", "singularize", "pluralize"],
|
||||
"homepage": "http://www.doctrine-project.org",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{"name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com"},
|
||||
{"name": "Roman Borschel", "email": "roman@code-factory.org"},
|
||||
{"name": "Benjamin Eberlei", "email": "kontakt@beberlei.de"},
|
||||
{"name": "Jonathan Wage", "email": "jonwage@gmail.com"},
|
||||
{"name": "Johannes Schmitt", "email": "schmittjoh@gmail.com"}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.3.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "4.*"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": { "Doctrine\\Common\\Inflector\\": "lib/" }
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.1.x-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,482 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the MIT license. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace Doctrine\Common\Inflector;
|
||||
|
||||
/**
|
||||
* Doctrine inflector has static methods for inflecting text.
|
||||
*
|
||||
* The methods in these classes are from several different sources collected
|
||||
* across several different php projects and several different authors. The
|
||||
* original author names and emails are not known.
|
||||
*
|
||||
* Pluralize & Singularize implementation are borrowed from CakePHP with some modifications.
|
||||
*
|
||||
* @link www.doctrine-project.org
|
||||
* @since 1.0
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @author Jonathan H. Wage <jonwage@gmail.com>
|
||||
*/
|
||||
class Inflector
|
||||
{
|
||||
/**
|
||||
* Plural inflector rules.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $plural = array(
|
||||
'rules' => array(
|
||||
'/(s)tatus$/i' => '\1\2tatuses',
|
||||
'/(quiz)$/i' => '\1zes',
|
||||
'/^(ox)$/i' => '\1\2en',
|
||||
'/([m|l])ouse$/i' => '\1ice',
|
||||
'/(matr|vert|ind)(ix|ex)$/i' => '\1ices',
|
||||
'/(x|ch|ss|sh)$/i' => '\1es',
|
||||
'/([^aeiouy]|qu)y$/i' => '\1ies',
|
||||
'/(hive)$/i' => '\1s',
|
||||
'/(?:([^f])fe|([lr])f)$/i' => '\1\2ves',
|
||||
'/sis$/i' => 'ses',
|
||||
'/([ti])um$/i' => '\1a',
|
||||
'/(p)erson$/i' => '\1eople',
|
||||
'/(m)an$/i' => '\1en',
|
||||
'/(c)hild$/i' => '\1hildren',
|
||||
'/(f)oot$/i' => '\1eet',
|
||||
'/(buffal|her|potat|tomat|volcan)o$/i' => '\1\2oes',
|
||||
'/(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|vir)us$/i' => '\1i',
|
||||
'/us$/i' => 'uses',
|
||||
'/(alias)$/i' => '\1es',
|
||||
'/(analys|ax|cris|test|thes)is$/i' => '\1es',
|
||||
'/s$/' => 's',
|
||||
'/^$/' => '',
|
||||
'/$/' => 's',
|
||||
),
|
||||
'uninflected' => array(
|
||||
'.*[nrlm]ese', '.*deer', '.*fish', '.*measles', '.*ois', '.*pox', '.*sheep', 'people', 'cookie'
|
||||
),
|
||||
'irregular' => array(
|
||||
'atlas' => 'atlases',
|
||||
'axe' => 'axes',
|
||||
'beef' => 'beefs',
|
||||
'brother' => 'brothers',
|
||||
'cafe' => 'cafes',
|
||||
'chateau' => 'chateaux',
|
||||
'child' => 'children',
|
||||
'cookie' => 'cookies',
|
||||
'corpus' => 'corpuses',
|
||||
'cow' => 'cows',
|
||||
'criterion' => 'criteria',
|
||||
'curriculum' => 'curricula',
|
||||
'demo' => 'demos',
|
||||
'domino' => 'dominoes',
|
||||
'echo' => 'echoes',
|
||||
'foot' => 'feet',
|
||||
'fungus' => 'fungi',
|
||||
'ganglion' => 'ganglions',
|
||||
'genie' => 'genies',
|
||||
'genus' => 'genera',
|
||||
'graffito' => 'graffiti',
|
||||
'hippopotamus' => 'hippopotami',
|
||||
'hoof' => 'hoofs',
|
||||
'human' => 'humans',
|
||||
'iris' => 'irises',
|
||||
'leaf' => 'leaves',
|
||||
'loaf' => 'loaves',
|
||||
'man' => 'men',
|
||||
'medium' => 'media',
|
||||
'memorandum' => 'memoranda',
|
||||
'money' => 'monies',
|
||||
'mongoose' => 'mongooses',
|
||||
'motto' => 'mottoes',
|
||||
'move' => 'moves',
|
||||
'mythos' => 'mythoi',
|
||||
'niche' => 'niches',
|
||||
'nucleus' => 'nuclei',
|
||||
'numen' => 'numina',
|
||||
'occiput' => 'occiputs',
|
||||
'octopus' => 'octopuses',
|
||||
'opus' => 'opuses',
|
||||
'ox' => 'oxen',
|
||||
'penis' => 'penises',
|
||||
'person' => 'people',
|
||||
'plateau' => 'plateaux',
|
||||
'runner-up' => 'runners-up',
|
||||
'sex' => 'sexes',
|
||||
'soliloquy' => 'soliloquies',
|
||||
'son-in-law' => 'sons-in-law',
|
||||
'syllabus' => 'syllabi',
|
||||
'testis' => 'testes',
|
||||
'thief' => 'thieves',
|
||||
'tooth' => 'teeth',
|
||||
'tornado' => 'tornadoes',
|
||||
'trilby' => 'trilbys',
|
||||
'turf' => 'turfs',
|
||||
'volcano' => 'volcanoes',
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
* Singular inflector rules.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $singular = array(
|
||||
'rules' => array(
|
||||
'/(s)tatuses$/i' => '\1\2tatus',
|
||||
'/^(.*)(menu)s$/i' => '\1\2',
|
||||
'/(quiz)zes$/i' => '\\1',
|
||||
'/(matr)ices$/i' => '\1ix',
|
||||
'/(vert|ind)ices$/i' => '\1ex',
|
||||
'/^(ox)en/i' => '\1',
|
||||
'/(alias)(es)*$/i' => '\1',
|
||||
'/(buffal|her|potat|tomat|volcan)oes$/i' => '\1o',
|
||||
'/(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|viri?)i$/i' => '\1us',
|
||||
'/([ftw]ax)es/i' => '\1',
|
||||
'/(analys|ax|cris|test|thes)es$/i' => '\1is',
|
||||
'/(shoe|slave)s$/i' => '\1',
|
||||
'/(o)es$/i' => '\1',
|
||||
'/ouses$/' => 'ouse',
|
||||
'/([^a])uses$/' => '\1us',
|
||||
'/([m|l])ice$/i' => '\1ouse',
|
||||
'/(x|ch|ss|sh)es$/i' => '\1',
|
||||
'/(m)ovies$/i' => '\1\2ovie',
|
||||
'/(s)eries$/i' => '\1\2eries',
|
||||
'/([^aeiouy]|qu)ies$/i' => '\1y',
|
||||
'/([lr])ves$/i' => '\1f',
|
||||
'/(tive)s$/i' => '\1',
|
||||
'/(hive)s$/i' => '\1',
|
||||
'/(drive)s$/i' => '\1',
|
||||
'/([^fo])ves$/i' => '\1fe',
|
||||
'/(^analy)ses$/i' => '\1sis',
|
||||
'/(analy|diagno|^ba|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i' => '\1\2sis',
|
||||
'/([ti])a$/i' => '\1um',
|
||||
'/(p)eople$/i' => '\1\2erson',
|
||||
'/(m)en$/i' => '\1an',
|
||||
'/(c)hildren$/i' => '\1\2hild',
|
||||
'/(f)eet$/i' => '\1oot',
|
||||
'/(n)ews$/i' => '\1\2ews',
|
||||
'/eaus$/' => 'eau',
|
||||
'/^(.*us)$/' => '\\1',
|
||||
'/s$/i' => '',
|
||||
),
|
||||
'uninflected' => array(
|
||||
'.*[nrlm]ese',
|
||||
'.*deer',
|
||||
'.*fish',
|
||||
'.*measles',
|
||||
'.*ois',
|
||||
'.*pox',
|
||||
'.*sheep',
|
||||
'.*ss',
|
||||
),
|
||||
'irregular' => array(
|
||||
'criteria' => 'criterion',
|
||||
'curves' => 'curve',
|
||||
'emphases' => 'emphasis',
|
||||
'foes' => 'foe',
|
||||
'hoaxes' => 'hoax',
|
||||
'media' => 'medium',
|
||||
'neuroses' => 'neurosis',
|
||||
'waves' => 'wave',
|
||||
'oases' => 'oasis',
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
* Words that should not be inflected.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $uninflected = array(
|
||||
'Amoyese', 'bison', 'Borghese', 'bream', 'breeches', 'britches', 'buffalo', 'cantus',
|
||||
'carp', 'chassis', 'clippers', 'cod', 'coitus', 'Congoese', 'contretemps', 'corps',
|
||||
'debris', 'diabetes', 'djinn', 'eland', 'elk', 'equipment', 'Faroese', 'flounder',
|
||||
'Foochowese', 'gallows', 'Genevese', 'Genoese', 'Gilbertese', 'graffiti',
|
||||
'headquarters', 'herpes', 'hijinks', 'Hottentotese', 'information', 'innings',
|
||||
'jackanapes', 'Kiplingese', 'Kongoese', 'Lucchese', 'mackerel', 'Maltese', '.*?media',
|
||||
'mews', 'moose', 'mumps', 'Nankingese', 'news', 'nexus', 'Niasese',
|
||||
'Pekingese', 'Piedmontese', 'pincers', 'Pistoiese', 'pliers', 'Portuguese',
|
||||
'proceedings', 'rabies', 'rice', 'rhinoceros', 'salmon', 'Sarawakese', 'scissors',
|
||||
'sea[- ]bass', 'series', 'Shavese', 'shears', 'siemens', 'species', 'staff', 'swine',
|
||||
'testes', 'trousers', 'trout', 'tuna', 'Vermontese', 'Wenchowese', 'whiting',
|
||||
'wildebeest', 'Yengeese'
|
||||
);
|
||||
|
||||
/**
|
||||
* Method cache array.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $cache = array();
|
||||
|
||||
/**
|
||||
* The initial state of Inflector so reset() works.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $initialState = array();
|
||||
|
||||
/**
|
||||
* Converts a word into the format for a Doctrine table name. Converts 'ModelName' to 'model_name'.
|
||||
*
|
||||
* @param string $word The word to tableize.
|
||||
*
|
||||
* @return string The tableized word.
|
||||
*/
|
||||
public static function tableize($word)
|
||||
{
|
||||
return strtolower(preg_replace('~(?<=\\w)([A-Z])~', '_$1', $word));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a word into the format for a Doctrine class name. Converts 'table_name' to 'TableName'.
|
||||
*
|
||||
* @param string $word The word to classify.
|
||||
*
|
||||
* @return string The classified word.
|
||||
*/
|
||||
public static function classify($word)
|
||||
{
|
||||
return str_replace(" ", "", ucwords(strtr($word, "_-", " ")));
|
||||
}
|
||||
|
||||
/**
|
||||
* Camelizes a word. This uses the classify() method and turns the first character to lowercase.
|
||||
*
|
||||
* @param string $word The word to camelize.
|
||||
*
|
||||
* @return string The camelized word.
|
||||
*/
|
||||
public static function camelize($word)
|
||||
{
|
||||
return lcfirst(self::classify($word));
|
||||
}
|
||||
|
||||
/**
|
||||
* Uppercases words with configurable delimeters between words.
|
||||
*
|
||||
* Takes a string and capitalizes all of the words, like PHP's built-in
|
||||
* ucwords function. This extends that behavior, however, by allowing the
|
||||
* word delimeters to be configured, rather than only separating on
|
||||
* whitespace.
|
||||
*
|
||||
* Here is an example:
|
||||
* <code>
|
||||
* <?php
|
||||
* $string = 'top-o-the-morning to all_of_you!';
|
||||
* echo \Doctrine\Common\Inflector\Inflector::ucwords($string);
|
||||
* // Top-O-The-Morning To All_of_you!
|
||||
*
|
||||
* echo \Doctrine\Common\Inflector\Inflector::ucwords($string, '-_ ');
|
||||
* // Top-O-The-Morning To All_Of_You!
|
||||
* ?>
|
||||
* </code>
|
||||
*
|
||||
* @param string $string The string to operate on.
|
||||
* @param string $delimiters A list of word separators.
|
||||
*
|
||||
* @return string The string with all delimeter-separated words capitalized.
|
||||
*/
|
||||
public static function ucwords($string, $delimiters = " \n\t\r\0\x0B-")
|
||||
{
|
||||
return preg_replace_callback(
|
||||
'/[^' . preg_quote($delimiters, '/') . ']+/',
|
||||
function($matches) {
|
||||
return ucfirst($matches[0]);
|
||||
},
|
||||
$string
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears Inflectors inflected value caches, and resets the inflection
|
||||
* rules to the initial values.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function reset()
|
||||
{
|
||||
if (empty(self::$initialState)) {
|
||||
self::$initialState = get_class_vars('Inflector');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (self::$initialState as $key => $val) {
|
||||
if ($key != 'initialState') {
|
||||
self::${$key} = $val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds custom inflection $rules, of either 'plural' or 'singular' $type.
|
||||
*
|
||||
* ### Usage:
|
||||
*
|
||||
* {{{
|
||||
* Inflector::rules('plural', array('/^(inflect)or$/i' => '\1ables'));
|
||||
* Inflector::rules('plural', array(
|
||||
* 'rules' => array('/^(inflect)ors$/i' => '\1ables'),
|
||||
* 'uninflected' => array('dontinflectme'),
|
||||
* 'irregular' => array('red' => 'redlings')
|
||||
* ));
|
||||
* }}}
|
||||
*
|
||||
* @param string $type The type of inflection, either 'plural' or 'singular'
|
||||
* @param array $rules An array of rules to be added.
|
||||
* @param boolean $reset If true, will unset default inflections for all
|
||||
* new rules that are being defined in $rules.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function rules($type, $rules, $reset = false)
|
||||
{
|
||||
foreach ($rules as $rule => $pattern) {
|
||||
if ( ! is_array($pattern)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($reset) {
|
||||
self::${$type}[$rule] = $pattern;
|
||||
} else {
|
||||
self::${$type}[$rule] = ($rule === 'uninflected')
|
||||
? array_merge($pattern, self::${$type}[$rule])
|
||||
: $pattern + self::${$type}[$rule];
|
||||
}
|
||||
|
||||
unset($rules[$rule], self::${$type}['cache' . ucfirst($rule)]);
|
||||
|
||||
if (isset(self::${$type}['merged'][$rule])) {
|
||||
unset(self::${$type}['merged'][$rule]);
|
||||
}
|
||||
|
||||
if ($type === 'plural') {
|
||||
self::$cache['pluralize'] = self::$cache['tableize'] = array();
|
||||
} elseif ($type === 'singular') {
|
||||
self::$cache['singularize'] = array();
|
||||
}
|
||||
}
|
||||
|
||||
self::${$type}['rules'] = $rules + self::${$type}['rules'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a word in plural form.
|
||||
*
|
||||
* @param string $word The word in singular form.
|
||||
*
|
||||
* @return string The word in plural form.
|
||||
*/
|
||||
public static function pluralize($word)
|
||||
{
|
||||
if (isset(self::$cache['pluralize'][$word])) {
|
||||
return self::$cache['pluralize'][$word];
|
||||
}
|
||||
|
||||
if (!isset(self::$plural['merged']['irregular'])) {
|
||||
self::$plural['merged']['irregular'] = self::$plural['irregular'];
|
||||
}
|
||||
|
||||
if (!isset(self::$plural['merged']['uninflected'])) {
|
||||
self::$plural['merged']['uninflected'] = array_merge(self::$plural['uninflected'], self::$uninflected);
|
||||
}
|
||||
|
||||
if (!isset(self::$plural['cacheUninflected']) || !isset(self::$plural['cacheIrregular'])) {
|
||||
self::$plural['cacheUninflected'] = '(?:' . implode('|', self::$plural['merged']['uninflected']) . ')';
|
||||
self::$plural['cacheIrregular'] = '(?:' . implode('|', array_keys(self::$plural['merged']['irregular'])) . ')';
|
||||
}
|
||||
|
||||
if (preg_match('/(.*)\\b(' . self::$plural['cacheIrregular'] . ')$/i', $word, $regs)) {
|
||||
self::$cache['pluralize'][$word] = $regs[1] . substr($word, 0, 1) . substr(self::$plural['merged']['irregular'][strtolower($regs[2])], 1);
|
||||
|
||||
return self::$cache['pluralize'][$word];
|
||||
}
|
||||
|
||||
if (preg_match('/^(' . self::$plural['cacheUninflected'] . ')$/i', $word, $regs)) {
|
||||
self::$cache['pluralize'][$word] = $word;
|
||||
|
||||
return $word;
|
||||
}
|
||||
|
||||
foreach (self::$plural['rules'] as $rule => $replacement) {
|
||||
if (preg_match($rule, $word)) {
|
||||
self::$cache['pluralize'][$word] = preg_replace($rule, $replacement, $word);
|
||||
|
||||
return self::$cache['pluralize'][$word];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a word in singular form.
|
||||
*
|
||||
* @param string $word The word in plural form.
|
||||
*
|
||||
* @return string The word in singular form.
|
||||
*/
|
||||
public static function singularize($word)
|
||||
{
|
||||
if (isset(self::$cache['singularize'][$word])) {
|
||||
return self::$cache['singularize'][$word];
|
||||
}
|
||||
|
||||
if (!isset(self::$singular['merged']['uninflected'])) {
|
||||
self::$singular['merged']['uninflected'] = array_merge(
|
||||
self::$singular['uninflected'],
|
||||
self::$uninflected
|
||||
);
|
||||
}
|
||||
|
||||
if (!isset(self::$singular['merged']['irregular'])) {
|
||||
self::$singular['merged']['irregular'] = array_merge(
|
||||
self::$singular['irregular'],
|
||||
array_flip(self::$plural['irregular'])
|
||||
);
|
||||
}
|
||||
|
||||
if (!isset(self::$singular['cacheUninflected']) || !isset(self::$singular['cacheIrregular'])) {
|
||||
self::$singular['cacheUninflected'] = '(?:' . join('|', self::$singular['merged']['uninflected']) . ')';
|
||||
self::$singular['cacheIrregular'] = '(?:' . join('|', array_keys(self::$singular['merged']['irregular'])) . ')';
|
||||
}
|
||||
|
||||
if (preg_match('/(.*)\\b(' . self::$singular['cacheIrregular'] . ')$/i', $word, $regs)) {
|
||||
self::$cache['singularize'][$word] = $regs[1] . substr($word, 0, 1) . substr(self::$singular['merged']['irregular'][strtolower($regs[2])], 1);
|
||||
|
||||
return self::$cache['singularize'][$word];
|
||||
}
|
||||
|
||||
if (preg_match('/^(' . self::$singular['cacheUninflected'] . ')$/i', $word, $regs)) {
|
||||
self::$cache['singularize'][$word] = $word;
|
||||
|
||||
return $word;
|
||||
}
|
||||
|
||||
foreach (self::$singular['rules'] as $rule => $replacement) {
|
||||
if (preg_match($rule, $word)) {
|
||||
self::$cache['singularize'][$word] = preg_replace($rule, $replacement, $word);
|
||||
|
||||
return self::$cache['singularize'][$word];
|
||||
}
|
||||
}
|
||||
|
||||
self::$cache['singularize'][$word] = $word;
|
||||
|
||||
return $word;
|
||||
}
|
||||
}
|
||||
31
vendor/doctrine/inflector/phpunit.xml.dist
vendored
31
vendor/doctrine/inflector/phpunit.xml.dist
vendored
@@ -1,31 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<phpunit backupGlobals="false"
|
||||
backupStaticAttributes="false"
|
||||
colors="true"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
processIsolation="false"
|
||||
stopOnFailure="false"
|
||||
syntaxCheck="false"
|
||||
bootstrap="./tests/Doctrine/Tests/TestInit.php"
|
||||
>
|
||||
<testsuites>
|
||||
<testsuite name="Doctrine Inflector Test Suite">
|
||||
<directory>./tests/Doctrine/</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory>./lib/Doctrine/</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
|
||||
<groups>
|
||||
<exclude>
|
||||
<group>performance</group>
|
||||
</exclude>
|
||||
</groups>
|
||||
</phpunit>
|
||||
@@ -1,395 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Common\Inflector;
|
||||
|
||||
use Doctrine\Tests\DoctrineTestCase;
|
||||
use Doctrine\Common\Inflector\Inflector;
|
||||
|
||||
class InflectorTest extends DoctrineTestCase
|
||||
{
|
||||
/**
|
||||
* Singular & Plural test data. Returns an array of sample words.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function dataSampleWords()
|
||||
{
|
||||
Inflector::reset();
|
||||
|
||||
// In the format array('singular', 'plural')
|
||||
return array(
|
||||
array('', ''),
|
||||
array('Alias', 'Aliases'),
|
||||
array('alumnus', 'alumni'),
|
||||
array('analysis', 'analyses'),
|
||||
array('aquarium', 'aquaria'),
|
||||
array('arch', 'arches'),
|
||||
array('atlas', 'atlases'),
|
||||
array('axe', 'axes'),
|
||||
array('baby', 'babies'),
|
||||
array('bacillus', 'bacilli'),
|
||||
array('bacterium', 'bacteria'),
|
||||
array('bureau', 'bureaus'),
|
||||
array('bus', 'buses'),
|
||||
array('Bus', 'Buses'),
|
||||
array('cactus', 'cacti'),
|
||||
array('cafe', 'cafes'),
|
||||
array('calf', 'calves'),
|
||||
array('categoria', 'categorias'),
|
||||
array('chateau', 'chateaux'),
|
||||
array('cherry', 'cherries'),
|
||||
array('child', 'children'),
|
||||
array('church', 'churches'),
|
||||
array('circus', 'circuses'),
|
||||
array('city', 'cities'),
|
||||
array('cod', 'cod'),
|
||||
array('cookie', 'cookies'),
|
||||
array('copy', 'copies'),
|
||||
array('crisis', 'crises'),
|
||||
array('criterion', 'criteria'),
|
||||
array('curriculum', 'curricula'),
|
||||
array('curve', 'curves'),
|
||||
array('deer', 'deer'),
|
||||
array('demo', 'demos'),
|
||||
array('dictionary', 'dictionaries'),
|
||||
array('domino', 'dominoes'),
|
||||
array('dwarf', 'dwarves'),
|
||||
array('echo', 'echoes'),
|
||||
array('elf', 'elves'),
|
||||
array('emphasis', 'emphases'),
|
||||
array('family', 'families'),
|
||||
array('fax', 'faxes'),
|
||||
array('fish', 'fish'),
|
||||
array('flush', 'flushes'),
|
||||
array('fly', 'flies'),
|
||||
array('focus', 'foci'),
|
||||
array('foe', 'foes'),
|
||||
array('food_menu', 'food_menus'),
|
||||
array('FoodMenu', 'FoodMenus'),
|
||||
array('foot', 'feet'),
|
||||
array('fungus', 'fungi'),
|
||||
array('glove', 'gloves'),
|
||||
array('half', 'halves'),
|
||||
array('hero', 'heroes'),
|
||||
array('hippopotamus', 'hippopotami'),
|
||||
array('hoax', 'hoaxes'),
|
||||
array('house', 'houses'),
|
||||
array('human', 'humans'),
|
||||
array('identity', 'identities'),
|
||||
array('index', 'indices'),
|
||||
array('iris', 'irises'),
|
||||
array('kiss', 'kisses'),
|
||||
array('knife', 'knives'),
|
||||
array('leaf', 'leaves'),
|
||||
array('life', 'lives'),
|
||||
array('loaf', 'loaves'),
|
||||
array('man', 'men'),
|
||||
array('matrix', 'matrices'),
|
||||
array('matrix_row', 'matrix_rows'),
|
||||
array('medium', 'media'),
|
||||
array('memorandum', 'memoranda'),
|
||||
array('menu', 'menus'),
|
||||
array('Menu', 'Menus'),
|
||||
array('mess', 'messes'),
|
||||
array('moose', 'moose'),
|
||||
array('motto', 'mottoes'),
|
||||
array('mouse', 'mice'),
|
||||
array('neurosis', 'neuroses'),
|
||||
array('news', 'news'),
|
||||
array('NodeMedia', 'NodeMedia'),
|
||||
array('nucleus', 'nuclei'),
|
||||
array('oasis', 'oases'),
|
||||
array('octopus', 'octopuses'),
|
||||
array('pass', 'passes'),
|
||||
array('person', 'people'),
|
||||
array('plateau', 'plateaux'),
|
||||
array('potato', 'potatoes'),
|
||||
array('powerhouse', 'powerhouses'),
|
||||
array('quiz', 'quizzes'),
|
||||
array('radius', 'radii'),
|
||||
array('reflex', 'reflexes'),
|
||||
array('roof', 'roofs'),
|
||||
array('runner-up', 'runners-up'),
|
||||
array('scarf', 'scarves'),
|
||||
array('scratch', 'scratches'),
|
||||
array('series', 'series'),
|
||||
array('sheep', 'sheep'),
|
||||
array('shelf', 'shelves'),
|
||||
array('shoe', 'shoes'),
|
||||
array('son-in-law', 'sons-in-law'),
|
||||
array('species', 'species'),
|
||||
array('splash', 'splashes'),
|
||||
array('spy', 'spies'),
|
||||
array('stimulus', 'stimuli'),
|
||||
array('stitch', 'stitches'),
|
||||
array('story', 'stories'),
|
||||
array('syllabus', 'syllabi'),
|
||||
array('tax', 'taxes'),
|
||||
array('terminus', 'termini'),
|
||||
array('thesis', 'theses'),
|
||||
array('thief', 'thieves'),
|
||||
array('tomato', 'tomatoes'),
|
||||
array('tooth', 'teeth'),
|
||||
array('tornado', 'tornadoes'),
|
||||
array('try', 'tries'),
|
||||
array('vertex', 'vertices'),
|
||||
array('virus', 'viri'),
|
||||
array('volcano', 'volcanoes'),
|
||||
array('wash', 'washes'),
|
||||
array('watch', 'watches'),
|
||||
array('wave', 'waves'),
|
||||
array('wharf', 'wharves'),
|
||||
array('wife', 'wives'),
|
||||
array('woman', 'women'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* testInflectingSingulars method
|
||||
*
|
||||
* @dataProvider dataSampleWords
|
||||
* @return void
|
||||
*/
|
||||
public function testInflectingSingulars($singular, $plural)
|
||||
{
|
||||
$this->assertEquals(
|
||||
$singular,
|
||||
Inflector::singularize($plural),
|
||||
"'$plural' should be singularized to '$singular'"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* testInflectingPlurals method
|
||||
*
|
||||
* @dataProvider dataSampleWords
|
||||
* @return void
|
||||
*/
|
||||
public function testInflectingPlurals($singular, $plural)
|
||||
{
|
||||
$this->assertEquals(
|
||||
$plural,
|
||||
Inflector::pluralize($singular),
|
||||
"'$singular' should be pluralized to '$plural'"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* testCustomPluralRule method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testCustomPluralRule()
|
||||
{
|
||||
Inflector::reset();
|
||||
Inflector::rules('plural', array('/^(custom)$/i' => '\1izables'));
|
||||
|
||||
$this->assertEquals(Inflector::pluralize('custom'), 'customizables');
|
||||
|
||||
Inflector::rules('plural', array('uninflected' => array('uninflectable')));
|
||||
|
||||
$this->assertEquals(Inflector::pluralize('uninflectable'), 'uninflectable');
|
||||
|
||||
Inflector::rules('plural', array(
|
||||
'rules' => array('/^(alert)$/i' => '\1ables'),
|
||||
'uninflected' => array('noflect', 'abtuse'),
|
||||
'irregular' => array('amaze' => 'amazable', 'phone' => 'phonezes')
|
||||
));
|
||||
|
||||
$this->assertEquals(Inflector::pluralize('noflect'), 'noflect');
|
||||
$this->assertEquals(Inflector::pluralize('abtuse'), 'abtuse');
|
||||
$this->assertEquals(Inflector::pluralize('alert'), 'alertables');
|
||||
$this->assertEquals(Inflector::pluralize('amaze'), 'amazable');
|
||||
$this->assertEquals(Inflector::pluralize('phone'), 'phonezes');
|
||||
}
|
||||
|
||||
/**
|
||||
* testCustomSingularRule method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testCustomSingularRule()
|
||||
{
|
||||
Inflector::reset();
|
||||
Inflector::rules('singular', array('/(eple)r$/i' => '\1', '/(jente)r$/i' => '\1'));
|
||||
|
||||
$this->assertEquals(Inflector::singularize('epler'), 'eple');
|
||||
$this->assertEquals(Inflector::singularize('jenter'), 'jente');
|
||||
|
||||
Inflector::rules('singular', array(
|
||||
'rules' => array('/^(bil)er$/i' => '\1', '/^(inflec|contribu)tors$/i' => '\1ta'),
|
||||
'uninflected' => array('singulars'),
|
||||
'irregular' => array('spins' => 'spinor')
|
||||
));
|
||||
|
||||
$this->assertEquals(Inflector::singularize('inflectors'), 'inflecta');
|
||||
$this->assertEquals(Inflector::singularize('contributors'), 'contributa');
|
||||
$this->assertEquals(Inflector::singularize('spins'), 'spinor');
|
||||
$this->assertEquals(Inflector::singularize('singulars'), 'singulars');
|
||||
}
|
||||
|
||||
/**
|
||||
* test that setting new rules clears the inflector caches.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testRulesClearsCaches()
|
||||
{
|
||||
Inflector::reset();
|
||||
|
||||
$this->assertEquals(Inflector::singularize('Bananas'), 'Banana');
|
||||
$this->assertEquals(Inflector::pluralize('Banana'), 'Bananas');
|
||||
|
||||
Inflector::rules('singular', array(
|
||||
'rules' => array('/(.*)nas$/i' => '\1zzz')
|
||||
));
|
||||
|
||||
$this->assertEquals('Banazzz', Inflector::singularize('Bananas'), 'Was inflected with old rules.');
|
||||
|
||||
Inflector::rules('plural', array(
|
||||
'rules' => array('/(.*)na$/i' => '\1zzz'),
|
||||
'irregular' => array('corpus' => 'corpora')
|
||||
));
|
||||
|
||||
$this->assertEquals(Inflector::pluralize('Banana'), 'Banazzz', 'Was inflected with old rules.');
|
||||
$this->assertEquals(Inflector::pluralize('corpus'), 'corpora', 'Was inflected with old irregular form.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test resetting inflection rules.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testCustomRuleWithReset()
|
||||
{
|
||||
Inflector::reset();
|
||||
|
||||
$uninflected = array('atlas', 'lapis', 'onibus', 'pires', 'virus', '.*x');
|
||||
$pluralIrregular = array('as' => 'ases');
|
||||
|
||||
Inflector::rules('singular', array(
|
||||
'rules' => array('/^(.*)(a|e|o|u)is$/i' => '\1\2l'),
|
||||
'uninflected' => $uninflected,
|
||||
), true);
|
||||
|
||||
Inflector::rules('plural', array(
|
||||
'rules' => array(
|
||||
'/^(.*)(a|e|o|u)l$/i' => '\1\2is',
|
||||
),
|
||||
'uninflected' => $uninflected,
|
||||
'irregular' => $pluralIrregular
|
||||
), true);
|
||||
|
||||
$this->assertEquals(Inflector::pluralize('Alcool'), 'Alcoois');
|
||||
$this->assertEquals(Inflector::pluralize('Atlas'), 'Atlas');
|
||||
$this->assertEquals(Inflector::singularize('Alcoois'), 'Alcool');
|
||||
$this->assertEquals(Inflector::singularize('Atlas'), 'Atlas');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test basic ucwords functionality.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testUcwords()
|
||||
{
|
||||
$this->assertSame('Top-O-The-Morning To All_of_you!', Inflector::ucwords( 'top-o-the-morning to all_of_you!'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test ucwords functionality with custom delimeters.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testUcwordsWithCustomDelimeters()
|
||||
{
|
||||
$this->assertSame('Top-O-The-Morning To All_Of_You!', Inflector::ucwords( 'top-o-the-morning to all_of_you!', '-_ '));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $expected
|
||||
* @param $word
|
||||
*
|
||||
* @dataProvider dataStringsTableize
|
||||
* @return void
|
||||
*/
|
||||
public function testTableize($expected, $word)
|
||||
{
|
||||
$this->assertSame($expected, Inflector::tableize($word));
|
||||
}
|
||||
|
||||
/**
|
||||
* Strings which are used for testTableize.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function dataStringsTableize()
|
||||
{
|
||||
// In the format array('expected', 'word')
|
||||
return array(
|
||||
array('', ''),
|
||||
array('foo_bar', 'FooBar'),
|
||||
array('f0o_bar', 'F0oBar'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $expected
|
||||
* @param $word
|
||||
*
|
||||
* @dataProvider dataStringsClassify
|
||||
* @return void
|
||||
*/
|
||||
public function testClassify($expected, $word)
|
||||
{
|
||||
$this->assertSame($expected, Inflector::classify($word));
|
||||
}
|
||||
|
||||
/**
|
||||
* Strings which are used for testClassify.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function dataStringsClassify()
|
||||
{
|
||||
// In the format array('expected', 'word')
|
||||
return array(
|
||||
array('', ''),
|
||||
array('FooBar', 'foo_bar'),
|
||||
array('FooBar', 'foo bar'),
|
||||
array('F0oBar', 'f0o bar'),
|
||||
array('F0oBar', 'f0o bar'),
|
||||
array('FooBar', 'foo_bar_'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $expected
|
||||
* @param $word
|
||||
*
|
||||
* @dataProvider dataStringsCamelize
|
||||
* @return void
|
||||
*/
|
||||
public function testCamelize($expected, $word)
|
||||
{
|
||||
$this->assertSame($expected, Inflector::camelize($word));
|
||||
}
|
||||
|
||||
/**
|
||||
* Strings which are used for testCamelize.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function dataStringsCamelize()
|
||||
{
|
||||
// In the format array('expected', 'word')
|
||||
return array(
|
||||
array('', ''),
|
||||
array('fooBar', 'foo_bar'),
|
||||
array('fooBar', 'foo bar'),
|
||||
array('f0oBar', 'f0o bar'),
|
||||
array('f0oBar', 'f0o bar'),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests;
|
||||
|
||||
/**
|
||||
* Base testcase class for all Doctrine testcases.
|
||||
*/
|
||||
abstract class DoctrineTestCase extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
* This file bootstraps the test environment.
|
||||
*/
|
||||
namespace Doctrine\Tests;
|
||||
|
||||
error_reporting(E_ALL | E_STRICT);
|
||||
|
||||
// register silently failing autoloader
|
||||
spl_autoload_register(function($class)
|
||||
{
|
||||
if (0 === strpos($class, 'Doctrine\Tests\\')) {
|
||||
$path = __DIR__.'/../../'.strtr($class, '\\', '/').'.php';
|
||||
if (is_file($path) && is_readable($path)) {
|
||||
require_once $path;
|
||||
|
||||
return true;
|
||||
}
|
||||
} else if (0 === strpos($class, 'Doctrine\Common\\')) {
|
||||
$path = __DIR__.'/../../../lib/'.($class = strtr($class, '\\', '/')).'.php';
|
||||
if (is_file($path) && is_readable($path)) {
|
||||
require_once $path;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
});
|
||||
2
vendor/evenement/evenement/.gitignore
vendored
2
vendor/evenement/evenement/.gitignore
vendored
@@ -1,2 +0,0 @@
|
||||
composer.lock
|
||||
vendor
|
||||
10
vendor/evenement/evenement/.travis.yml
vendored
10
vendor/evenement/evenement/.travis.yml
vendored
@@ -1,10 +0,0 @@
|
||||
language: php
|
||||
|
||||
php:
|
||||
- 5.4
|
||||
|
||||
before_script:
|
||||
- wget http://getcomposer.org/composer.phar
|
||||
- php composer.phar install
|
||||
|
||||
script: phpunit --coverage-text
|
||||
8
vendor/evenement/evenement/CHANGELOG.md
vendored
8
vendor/evenement/evenement/CHANGELOG.md
vendored
@@ -1,8 +0,0 @@
|
||||
CHANGELOG
|
||||
=========
|
||||
|
||||
* 2.0.0 (2012-11-02)
|
||||
|
||||
* Require PHP >=5.4.0
|
||||
* Added EventEmitterTrait
|
||||
* Removed EventEmitter2
|
||||
19
vendor/evenement/evenement/LICENSE
vendored
19
vendor/evenement/evenement/LICENSE
vendored
@@ -1,19 +0,0 @@
|
||||
Copyright (c) 2011 Igor Wiedler
|
||||
|
||||
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.
|
||||
83
vendor/evenement/evenement/README.md
vendored
83
vendor/evenement/evenement/README.md
vendored
@@ -1,83 +0,0 @@
|
||||
# Événement
|
||||
|
||||
Événement is a very simple event dispatching library for PHP.
|
||||
|
||||
It has the same design goals as [Silex](http://silex-project.org) and
|
||||
[Pimple](http://pimple-project.org), to empower the user while staying concise
|
||||
and simple.
|
||||
|
||||
It is very strongly inspired by the EventEmitter API found in
|
||||
[node.js](http://nodejs.org).
|
||||
|
||||
[](http://travis-ci.org/igorw/evenement)
|
||||
|
||||
## Fetch
|
||||
|
||||
The recommended way to install Événement is [through composer](http://getcomposer.org).
|
||||
|
||||
Just create a composer.json file for your project:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"require": {
|
||||
"evenement/evenement": "2.0.*"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Note:** The `2.0.*` version of Événement requires PHP 5.4. If you are
|
||||
using PHP 5.3, please use the `1.0.*` version:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"require": {
|
||||
"evenement/evenement": "1.0.*"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
And run these two commands to install it:
|
||||
|
||||
$ curl -s http://getcomposer.org/installer | php
|
||||
$ php composer.phar install
|
||||
|
||||
Now you can add the autoloader, and you will have access to the library:
|
||||
|
||||
```php
|
||||
<?php
|
||||
require 'vendor/autoload.php';
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Creating an Emitter
|
||||
|
||||
```php
|
||||
<?php
|
||||
$emitter = new Evenement\EventEmitter();
|
||||
```
|
||||
|
||||
### Adding Listeners
|
||||
|
||||
```php
|
||||
<?php
|
||||
$emitter->on('user.created', function (User $user) use ($logger) {
|
||||
$logger->log(sprintf("User '%s' was created.", $user->getLogin()));
|
||||
});
|
||||
```
|
||||
|
||||
### Emitting Events
|
||||
|
||||
```php
|
||||
<?php
|
||||
$emitter->emit('user.created', array($user));
|
||||
```
|
||||
|
||||
Tests
|
||||
-----
|
||||
|
||||
$ phpunit
|
||||
|
||||
License
|
||||
-------
|
||||
MIT, see LICENSE.
|
||||
25
vendor/evenement/evenement/composer.json
vendored
25
vendor/evenement/evenement/composer.json
vendored
@@ -1,25 +0,0 @@
|
||||
{
|
||||
"name": "evenement/evenement",
|
||||
"description": "Événement is a very simple event dispatching library for PHP",
|
||||
"keywords": ["event-dispatcher", "event-emitter"],
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Igor Wiedler",
|
||||
"email": "igor@wiedler.ch"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.4.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Evenement": "src"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.0-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
25
vendor/evenement/evenement/phpunit.xml.dist
vendored
25
vendor/evenement/evenement/phpunit.xml.dist
vendored
@@ -1,25 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<phpunit backupGlobals="false"
|
||||
backupStaticAttributes="false"
|
||||
colors="true"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
processIsolation="false"
|
||||
stopOnFailure="false"
|
||||
syntaxCheck="false"
|
||||
bootstrap="tests/bootstrap.php"
|
||||
>
|
||||
<testsuites>
|
||||
<testsuite name="Evenement Test Suite">
|
||||
<directory>./tests/Evenement/</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory>./src/</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
</phpunit>
|
||||
@@ -1,17 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Evenement.
|
||||
*
|
||||
* (c) Igor Wiedler <igor@wiedler.ch>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Evenement;
|
||||
|
||||
class EventEmitter implements EventEmitterInterface
|
||||
{
|
||||
use EventEmitterTrait;
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Evenement.
|
||||
*
|
||||
* (c) Igor Wiedler <igor@wiedler.ch>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Evenement;
|
||||
|
||||
interface EventEmitterInterface
|
||||
{
|
||||
public function on($event, callable $listener);
|
||||
public function once($event, callable $listener);
|
||||
public function removeListener($event, callable $listener);
|
||||
public function removeAllListeners($event = null);
|
||||
public function listeners($event);
|
||||
public function emit($event, array $arguments = []);
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Evenement.
|
||||
*
|
||||
* (c) Igor Wiedler <igor@wiedler.ch>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Evenement;
|
||||
|
||||
trait EventEmitterTrait
|
||||
{
|
||||
protected $listeners = [];
|
||||
|
||||
public function on($event, callable $listener)
|
||||
{
|
||||
if (!isset($this->listeners[$event])) {
|
||||
$this->listeners[$event] = [];
|
||||
}
|
||||
|
||||
$this->listeners[$event][] = $listener;
|
||||
}
|
||||
|
||||
public function once($event, callable $listener)
|
||||
{
|
||||
$onceListener = function () use (&$onceListener, $event, $listener) {
|
||||
$this->removeListener($event, $onceListener);
|
||||
|
||||
call_user_func_array($listener, func_get_args());
|
||||
};
|
||||
|
||||
$this->on($event, $onceListener);
|
||||
}
|
||||
|
||||
public function removeListener($event, callable $listener)
|
||||
{
|
||||
if (isset($this->listeners[$event])) {
|
||||
if (false !== $index = array_search($listener, $this->listeners[$event], true)) {
|
||||
unset($this->listeners[$event][$index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function removeAllListeners($event = null)
|
||||
{
|
||||
if ($event !== null) {
|
||||
unset($this->listeners[$event]);
|
||||
} else {
|
||||
$this->listeners = [];
|
||||
}
|
||||
}
|
||||
|
||||
public function listeners($event)
|
||||
{
|
||||
return isset($this->listeners[$event]) ? $this->listeners[$event] : [];
|
||||
}
|
||||
|
||||
public function emit($event, array $arguments = [])
|
||||
{
|
||||
foreach ($this->listeners($event) as $listener) {
|
||||
call_user_func_array($listener, $arguments);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,235 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Evenement.
|
||||
*
|
||||
* (c) Igor Wiedler <igor@wiedler.ch>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Evenement\Tests;
|
||||
|
||||
use Evenement\EventEmitter;
|
||||
|
||||
class EventEmitterTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
private $emitter;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->emitter = new EventEmitter();
|
||||
}
|
||||
|
||||
public function testAddListenerWithLambda()
|
||||
{
|
||||
$this->emitter->on('foo', function () {});
|
||||
}
|
||||
|
||||
public function testAddListenerWithMethod()
|
||||
{
|
||||
$listener = new Listener();
|
||||
$this->emitter->on('foo', [$listener, 'onFoo']);
|
||||
}
|
||||
|
||||
public function testAddListenerWithStaticMethod()
|
||||
{
|
||||
$this->emitter->on('bar', ['Evenement\Tests\Listener', 'onBar']);
|
||||
}
|
||||
|
||||
public function testAddListenerWithInvalidListener()
|
||||
{
|
||||
try {
|
||||
$this->emitter->on('foo', 'not a callable');
|
||||
$this->fail();
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
}
|
||||
|
||||
public function testOnce()
|
||||
{
|
||||
$listenerCalled = 0;
|
||||
|
||||
$this->emitter->once('foo', function () use (&$listenerCalled) {
|
||||
$listenerCalled++;
|
||||
});
|
||||
|
||||
$this->assertSame(0, $listenerCalled);
|
||||
|
||||
$this->emitter->emit('foo');
|
||||
|
||||
$this->assertSame(1, $listenerCalled);
|
||||
|
||||
$this->emitter->emit('foo');
|
||||
|
||||
$this->assertSame(1, $listenerCalled);
|
||||
}
|
||||
|
||||
public function testOnceWithArguments()
|
||||
{
|
||||
$capturedArgs = [];
|
||||
|
||||
$this->emitter->once('foo', function ($a, $b) use (&$capturedArgs) {
|
||||
$capturedArgs = array($a, $b);
|
||||
});
|
||||
|
||||
$this->emitter->emit('foo', array('a', 'b'));
|
||||
|
||||
$this->assertSame(array('a', 'b'), $capturedArgs);
|
||||
}
|
||||
|
||||
public function testEmitWithoutArguments()
|
||||
{
|
||||
$listenerCalled = false;
|
||||
|
||||
$this->emitter->on('foo', function () use (&$listenerCalled) {
|
||||
$listenerCalled = true;
|
||||
});
|
||||
|
||||
$this->assertSame(false, $listenerCalled);
|
||||
$this->emitter->emit('foo');
|
||||
$this->assertSame(true, $listenerCalled);
|
||||
}
|
||||
|
||||
public function testEmitWithOneArgument()
|
||||
{
|
||||
$test = $this;
|
||||
|
||||
$listenerCalled = false;
|
||||
|
||||
$this->emitter->on('foo', function ($value) use (&$listenerCalled, $test) {
|
||||
$listenerCalled = true;
|
||||
|
||||
$test->assertSame('bar', $value);
|
||||
});
|
||||
|
||||
$this->assertSame(false, $listenerCalled);
|
||||
$this->emitter->emit('foo', ['bar']);
|
||||
$this->assertSame(true, $listenerCalled);
|
||||
}
|
||||
|
||||
public function testEmitWithTwoArguments()
|
||||
{
|
||||
$test = $this;
|
||||
|
||||
$listenerCalled = false;
|
||||
|
||||
$this->emitter->on('foo', function ($arg1, $arg2) use (&$listenerCalled, $test) {
|
||||
$listenerCalled = true;
|
||||
|
||||
$test->assertSame('bar', $arg1);
|
||||
$test->assertSame('baz', $arg2);
|
||||
});
|
||||
|
||||
$this->assertSame(false, $listenerCalled);
|
||||
$this->emitter->emit('foo', ['bar', 'baz']);
|
||||
$this->assertSame(true, $listenerCalled);
|
||||
}
|
||||
|
||||
public function testEmitWithNoListeners()
|
||||
{
|
||||
$this->emitter->emit('foo');
|
||||
$this->emitter->emit('foo', ['bar']);
|
||||
$this->emitter->emit('foo', ['bar', 'baz']);
|
||||
}
|
||||
|
||||
public function testEmitWithTwoListeners()
|
||||
{
|
||||
$listenersCalled = 0;
|
||||
|
||||
$this->emitter->on('foo', function () use (&$listenersCalled) {
|
||||
$listenersCalled++;
|
||||
});
|
||||
|
||||
$this->emitter->on('foo', function () use (&$listenersCalled) {
|
||||
$listenersCalled++;
|
||||
});
|
||||
|
||||
$this->assertSame(0, $listenersCalled);
|
||||
$this->emitter->emit('foo');
|
||||
$this->assertSame(2, $listenersCalled);
|
||||
}
|
||||
|
||||
public function testRemoveListenerMatching()
|
||||
{
|
||||
$listenersCalled = 0;
|
||||
|
||||
$listener = function () use (&$listenersCalled) {
|
||||
$listenersCalled++;
|
||||
};
|
||||
|
||||
$this->emitter->on('foo', $listener);
|
||||
$this->emitter->removeListener('foo', $listener);
|
||||
|
||||
$this->assertSame(0, $listenersCalled);
|
||||
$this->emitter->emit('foo');
|
||||
$this->assertSame(0, $listenersCalled);
|
||||
}
|
||||
|
||||
public function testRemoveListenerNotMatching()
|
||||
{
|
||||
$listenersCalled = 0;
|
||||
|
||||
$listener = function () use (&$listenersCalled) {
|
||||
$listenersCalled++;
|
||||
};
|
||||
|
||||
$this->emitter->on('foo', $listener);
|
||||
$this->emitter->removeListener('bar', $listener);
|
||||
|
||||
$this->assertSame(0, $listenersCalled);
|
||||
$this->emitter->emit('foo');
|
||||
$this->assertSame(1, $listenersCalled);
|
||||
}
|
||||
|
||||
public function testRemoveAllListenersMatching()
|
||||
{
|
||||
$listenersCalled = 0;
|
||||
|
||||
$this->emitter->on('foo', function () use (&$listenersCalled) {
|
||||
$listenersCalled++;
|
||||
});
|
||||
|
||||
$this->emitter->removeAllListeners('foo');
|
||||
|
||||
$this->assertSame(0, $listenersCalled);
|
||||
$this->emitter->emit('foo');
|
||||
$this->assertSame(0, $listenersCalled);
|
||||
}
|
||||
|
||||
public function testRemoveAllListenersNotMatching()
|
||||
{
|
||||
$listenersCalled = 0;
|
||||
|
||||
$this->emitter->on('foo', function () use (&$listenersCalled) {
|
||||
$listenersCalled++;
|
||||
});
|
||||
|
||||
$this->emitter->removeAllListeners('bar');
|
||||
|
||||
$this->assertSame(0, $listenersCalled);
|
||||
$this->emitter->emit('foo');
|
||||
$this->assertSame(1, $listenersCalled);
|
||||
}
|
||||
|
||||
public function testRemoveAllListenersWithoutArguments()
|
||||
{
|
||||
$listenersCalled = 0;
|
||||
|
||||
$this->emitter->on('foo', function () use (&$listenersCalled) {
|
||||
$listenersCalled++;
|
||||
});
|
||||
|
||||
$this->emitter->on('bar', function () use (&$listenersCalled) {
|
||||
$listenersCalled++;
|
||||
});
|
||||
|
||||
$this->emitter->removeAllListeners();
|
||||
|
||||
$this->assertSame(0, $listenersCalled);
|
||||
$this->emitter->emit('foo');
|
||||
$this->emitter->emit('bar');
|
||||
$this->assertSame(0, $listenersCalled);
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Evenement.
|
||||
*
|
||||
* (c) Igor Wiedler <igor@wiedler.ch>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Evenement\Tests;
|
||||
|
||||
class Listener
|
||||
{
|
||||
public function onFoo()
|
||||
{
|
||||
}
|
||||
|
||||
public static function onBar()
|
||||
{
|
||||
}
|
||||
}
|
||||
13
vendor/evenement/evenement/tests/bootstrap.php
vendored
13
vendor/evenement/evenement/tests/bootstrap.php
vendored
@@ -1,13 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Evenement.
|
||||
*
|
||||
* (c) Igor Wiedler <igor@wiedler.ch>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
$loader = require __DIR__.'/../vendor/autoload.php';
|
||||
$loader->add('Evenement\Tests', __DIR__);
|
||||
27
vendor/guzzle/guzzle/.gitignore
vendored
27
vendor/guzzle/guzzle/.gitignore
vendored
@@ -1,27 +0,0 @@
|
||||
# Ingore common cruft
|
||||
.DS_STORE
|
||||
coverage
|
||||
.idea
|
||||
|
||||
# Ignore binary files
|
||||
guzzle.phar
|
||||
guzzle-min.phar
|
||||
|
||||
# Ignore potentially sensitive phpunit file
|
||||
phpunit.xml
|
||||
|
||||
# Ignore composer generated files
|
||||
composer.phar
|
||||
composer.lock
|
||||
composer-test.lock
|
||||
vendor/
|
||||
|
||||
# Ignore build files
|
||||
build/
|
||||
phing/build.properties
|
||||
|
||||
# Ignore subsplit working directory
|
||||
.subsplit
|
||||
|
||||
docs/_build
|
||||
docs/*.pyc
|
||||
17
vendor/guzzle/guzzle/.travis.yml
vendored
17
vendor/guzzle/guzzle/.travis.yml
vendored
@@ -1,17 +0,0 @@
|
||||
language: php
|
||||
|
||||
php:
|
||||
- 5.3
|
||||
- 5.4
|
||||
- 5.5
|
||||
- 5.6
|
||||
- hhvm
|
||||
|
||||
before_script:
|
||||
- curl --version
|
||||
- pecl install uri_template-beta || echo "pecl uri_template not available"
|
||||
- composer self-update
|
||||
- composer install --no-interaction --prefer-source --dev
|
||||
- ~/.nvm/nvm.sh install v0.6.14
|
||||
|
||||
script: composer test
|
||||
751
vendor/guzzle/guzzle/CHANGELOG.md
vendored
751
vendor/guzzle/guzzle/CHANGELOG.md
vendored
@@ -1,751 +0,0 @@
|
||||
# CHANGELOG
|
||||
|
||||
## 3.9.3 - 2015-03-18
|
||||
|
||||
* Ensuring Content-Length is not stripped from a request when it is `0`.
|
||||
* Added more information to stream wrapper exceptions.
|
||||
* Message parser will no longer throw warnings for malformed messages.
|
||||
* Giving a valid cache TTL when max-age is 0.
|
||||
|
||||
## 3.9.2 - 2014-09-10
|
||||
|
||||
* Retrying "Connection died, retrying a fresh connect" curl errors.
|
||||
* Automatically extracting the cacert from the phar in client constructor.
|
||||
* Added EntityBody support for OPTIONS requests.
|
||||
|
||||
## 3.9.1 - 2014-05-07
|
||||
|
||||
* Added a fix to ReadLimitEntityBody to ensure it doesn't infinitely loop.
|
||||
* Added a fix to the stream checksum function so that when the first read
|
||||
returns a falsey value, it still continues to consume the stream until EOF.
|
||||
|
||||
## 3.9.0 - 2014-04-23
|
||||
|
||||
* `null`, `false`, and `"_guzzle_blank_"` all now serialize as an empty value
|
||||
with no trailing "=". See dc1d824277.
|
||||
* No longer performing an MD5 check on the cacert each time the phar is used,
|
||||
but rather copying the cacert to the temp directory.
|
||||
* `"0"` can now be added as a URL path
|
||||
* Deleting cookies that are set to empty
|
||||
* If-Modified-Since is no longer unnecessarily added to the CachePlugin
|
||||
* Cookie path matching now follows RFC 6265 s5.1.4
|
||||
* Updated service descriptions are now added to a service client's composite
|
||||
factory.
|
||||
* MockPlugin now throws an exception if the queue is empty.
|
||||
* Properly parsing URLs that start with "http" but are not absolute
|
||||
* Added the ability to configure the curl_multi_select timeout setting
|
||||
* OAuth parameters are now sorted using lexicographical byte value ordering
|
||||
* Fixing invalid usage of an out of range PHP feature in the ErrorResponsePlugin
|
||||
|
||||
## 3.8.1 -2014-01-28
|
||||
|
||||
* Bug: Always using GET requests when redirecting from a 303 response
|
||||
* Bug: CURLOPT_SSL_VERIFYHOST is now correctly set to false when setting `$certificateAuthority` to false in
|
||||
`Guzzle\Http\ClientInterface::setSslVerification()`
|
||||
* Bug: RedirectPlugin now uses strict RFC 3986 compliance when combining a base URL with a relative URL
|
||||
* Bug: The body of a request can now be set to `"0"`
|
||||
* Sending PHP stream requests no longer forces `HTTP/1.0`
|
||||
* Adding more information to ExceptionCollection exceptions so that users have more context, including a stack trace of
|
||||
each sub-exception
|
||||
* Updated the `$ref` attribute in service descriptions to merge over any existing parameters of a schema (rather than
|
||||
clobbering everything).
|
||||
* Merging URLs will now use the query string object from the relative URL (thus allowing custom query aggregators)
|
||||
* Query strings are now parsed in a way that they do no convert empty keys with no value to have a dangling `=`.
|
||||
For example `foo&bar=baz` is now correctly parsed and recognized as `foo&bar=baz` rather than `foo=&bar=baz`.
|
||||
* Now properly escaping the regular expression delimiter when matching Cookie domains.
|
||||
* Network access is now disabled when loading XML documents
|
||||
|
||||
## 3.8.0 - 2013-12-05
|
||||
|
||||
* Added the ability to define a POST name for a file
|
||||
* JSON response parsing now properly walks additionalProperties
|
||||
* cURL error code 18 is now retried automatically in the BackoffPlugin
|
||||
* Fixed a cURL error when URLs contain fragments
|
||||
* Fixed an issue in the BackoffPlugin retry event where it was trying to access all exceptions as if they were
|
||||
CurlExceptions
|
||||
* CURLOPT_PROGRESS function fix for PHP 5.5 (69fcc1e)
|
||||
* Added the ability for Guzzle to work with older versions of cURL that do not support `CURLOPT_TIMEOUT_MS`
|
||||
* Fixed a bug that was encountered when parsing empty header parameters
|
||||
* UriTemplate now has a `setRegex()` method to match the docs
|
||||
* The `debug` request parameter now checks if it is truthy rather than if it exists
|
||||
* Setting the `debug` request parameter to true shows verbose cURL output instead of using the LogPlugin
|
||||
* Added the ability to combine URLs using strict RFC 3986 compliance
|
||||
* Command objects can now return the validation errors encountered by the command
|
||||
* Various fixes to cache revalidation (#437 and 29797e5)
|
||||
* Various fixes to the AsyncPlugin
|
||||
* Cleaned up build scripts
|
||||
|
||||
## 3.7.4 - 2013-10-02
|
||||
|
||||
* Bug fix: 0 is now an allowed value in a description parameter that has a default value (#430)
|
||||
* Bug fix: SchemaFormatter now returns an integer when formatting to a Unix timestamp
|
||||
(see https://github.com/aws/aws-sdk-php/issues/147)
|
||||
* Bug fix: Cleaned up and fixed URL dot segment removal to properly resolve internal dots
|
||||
* Minimum PHP version is now properly specified as 5.3.3 (up from 5.3.2) (#420)
|
||||
* Updated the bundled cacert.pem (#419)
|
||||
* OauthPlugin now supports adding authentication to headers or query string (#425)
|
||||
|
||||
## 3.7.3 - 2013-09-08
|
||||
|
||||
* Added the ability to get the exception associated with a request/command when using `MultiTransferException` and
|
||||
`CommandTransferException`.
|
||||
* Setting `additionalParameters` of a response to false is now honored when parsing responses with a service description
|
||||
* Schemas are only injected into response models when explicitly configured.
|
||||
* No longer guessing Content-Type based on the path of a request. Content-Type is now only guessed based on the path of
|
||||
an EntityBody.
|
||||
* Bug fix: ChunkedIterator can now properly chunk a \Traversable as well as an \Iterator.
|
||||
* Bug fix: FilterIterator now relies on `\Iterator` instead of `\Traversable`.
|
||||
* Bug fix: Gracefully handling malformed responses in RequestMediator::writeResponseBody()
|
||||
* Bug fix: Replaced call to canCache with canCacheRequest in the CallbackCanCacheStrategy of the CachePlugin
|
||||
* Bug fix: Visiting XML attributes first before visting XML children when serializing requests
|
||||
* Bug fix: Properly parsing headers that contain commas contained in quotes
|
||||
* Bug fix: mimetype guessing based on a filename is now case-insensitive
|
||||
|
||||
## 3.7.2 - 2013-08-02
|
||||
|
||||
* Bug fix: Properly URL encoding paths when using the PHP-only version of the UriTemplate expander
|
||||
See https://github.com/guzzle/guzzle/issues/371
|
||||
* Bug fix: Cookie domains are now matched correctly according to RFC 6265
|
||||
See https://github.com/guzzle/guzzle/issues/377
|
||||
* Bug fix: GET parameters are now used when calculating an OAuth signature
|
||||
* Bug fix: Fixed an issue with cache revalidation where the If-None-Match header was being double quoted
|
||||
* `Guzzle\Common\AbstractHasDispatcher::dispatch()` now returns the event that was dispatched
|
||||
* `Guzzle\Http\QueryString::factory()` now guesses the most appropriate query aggregator to used based on the input.
|
||||
See https://github.com/guzzle/guzzle/issues/379
|
||||
* Added a way to add custom domain objects to service description parsing using the `operation.parse_class` event. See
|
||||
https://github.com/guzzle/guzzle/pull/380
|
||||
* cURL multi cleanup and optimizations
|
||||
|
||||
## 3.7.1 - 2013-07-05
|
||||
|
||||
* Bug fix: Setting default options on a client now works
|
||||
* Bug fix: Setting options on HEAD requests now works. See #352
|
||||
* Bug fix: Moving stream factory before send event to before building the stream. See #353
|
||||
* Bug fix: Cookies no longer match on IP addresses per RFC 6265
|
||||
* Bug fix: Correctly parsing header parameters that are in `<>` and quotes
|
||||
* Added `cert` and `ssl_key` as request options
|
||||
* `Host` header can now diverge from the host part of a URL if the header is set manually
|
||||
* `Guzzle\Service\Command\LocationVisitor\Request\XmlVisitor` was rewritten to change from using SimpleXML to XMLWriter
|
||||
* OAuth parameters are only added via the plugin if they aren't already set
|
||||
* Exceptions are now thrown when a URL cannot be parsed
|
||||
* Returning `false` if `Guzzle\Http\EntityBody::getContentMd5()` fails
|
||||
* Not setting a `Content-MD5` on a command if calculating the Content-MD5 fails via the CommandContentMd5Plugin
|
||||
|
||||
## 3.7.0 - 2013-06-10
|
||||
|
||||
* See UPGRADING.md for more information on how to upgrade.
|
||||
* Requests now support the ability to specify an array of $options when creating a request to more easily modify a
|
||||
request. You can pass a 'request.options' configuration setting to a client to apply default request options to
|
||||
every request created by a client (e.g. default query string variables, headers, curl options, etc).
|
||||
* Added a static facade class that allows you to use Guzzle with static methods and mount the class to `\Guzzle`.
|
||||
See `Guzzle\Http\StaticClient::mount`.
|
||||
* Added `command.request_options` to `Guzzle\Service\Command\AbstractCommand` to pass request options to requests
|
||||
created by a command (e.g. custom headers, query string variables, timeout settings, etc).
|
||||
* Stream size in `Guzzle\Stream\PhpStreamRequestFactory` will now be set if Content-Length is returned in the
|
||||
headers of a response
|
||||
* Added `Guzzle\Common\Collection::setPath($path, $value)` to set a value into an array using a nested key
|
||||
(e.g. `$collection->setPath('foo/baz/bar', 'test'); echo $collection['foo']['bar']['bar'];`)
|
||||
* ServiceBuilders now support storing and retrieving arbitrary data
|
||||
* CachePlugin can now purge all resources for a given URI
|
||||
* CachePlugin can automatically purge matching cached items when a non-idempotent request is sent to a resource
|
||||
* CachePlugin now uses the Vary header to determine if a resource is a cache hit
|
||||
* `Guzzle\Http\Message\Response` now implements `\Serializable`
|
||||
* Added `Guzzle\Cache\CacheAdapterFactory::fromCache()` to more easily create cache adapters
|
||||
* `Guzzle\Service\ClientInterface::execute()` now accepts an array, single command, or Traversable
|
||||
* Fixed a bug in `Guzzle\Http\Message\Header\Link::addLink()`
|
||||
* Better handling of calculating the size of a stream in `Guzzle\Stream\Stream` using fstat() and caching the size
|
||||
* `Guzzle\Common\Exception\ExceptionCollection` now creates a more readable exception message
|
||||
* Fixing BC break: Added back the MonologLogAdapter implementation rather than extending from PsrLog so that older
|
||||
Symfony users can still use the old version of Monolog.
|
||||
* Fixing BC break: Added the implementation back in for `Guzzle\Http\Message\AbstractMessage::getTokenizedHeader()`.
|
||||
Now triggering an E_USER_DEPRECATED warning when used. Use `$message->getHeader()->parseParams()`.
|
||||
* Several performance improvements to `Guzzle\Common\Collection`
|
||||
* Added an `$options` argument to the end of the following methods of `Guzzle\Http\ClientInterface`:
|
||||
createRequest, head, delete, put, patch, post, options, prepareRequest
|
||||
* Added an `$options` argument to the end of `Guzzle\Http\Message\Request\RequestFactoryInterface::createRequest()`
|
||||
* Added an `applyOptions()` method to `Guzzle\Http\Message\Request\RequestFactoryInterface`
|
||||
* Changed `Guzzle\Http\ClientInterface::get($uri = null, $headers = null, $body = null)` to
|
||||
`Guzzle\Http\ClientInterface::get($uri = null, $headers = null, $options = array())`. You can still pass in a
|
||||
resource, string, or EntityBody into the $options parameter to specify the download location of the response.
|
||||
* Changed `Guzzle\Common\Collection::__construct($data)` to no longer accepts a null value for `$data` but a
|
||||
default `array()`
|
||||
* Added `Guzzle\Stream\StreamInterface::isRepeatable`
|
||||
* Removed `Guzzle\Http\ClientInterface::setDefaultHeaders(). Use
|
||||
$client->getConfig()->setPath('request.options/headers/{header_name}', 'value')`. or
|
||||
$client->getConfig()->setPath('request.options/headers', array('header_name' => 'value'))`.
|
||||
* Removed `Guzzle\Http\ClientInterface::getDefaultHeaders(). Use $client->getConfig()->getPath('request.options/headers')`.
|
||||
* Removed `Guzzle\Http\ClientInterface::expandTemplate()`
|
||||
* Removed `Guzzle\Http\ClientInterface::setRequestFactory()`
|
||||
* Removed `Guzzle\Http\ClientInterface::getCurlMulti()`
|
||||
* Removed `Guzzle\Http\Message\RequestInterface::canCache`
|
||||
* Removed `Guzzle\Http\Message\RequestInterface::setIsRedirect`
|
||||
* Removed `Guzzle\Http\Message\RequestInterface::isRedirect`
|
||||
* Made `Guzzle\Http\Client::expandTemplate` and `getUriTemplate` protected methods.
|
||||
* You can now enable E_USER_DEPRECATED warnings to see if you are using a deprecated method by setting
|
||||
`Guzzle\Common\Version::$emitWarnings` to true.
|
||||
* Marked `Guzzle\Http\Message\Request::isResponseBodyRepeatable()` as deprecated. Use
|
||||
`$request->getResponseBody()->isRepeatable()` instead.
|
||||
* Marked `Guzzle\Http\Message\Request::canCache()` as deprecated. Use
|
||||
`Guzzle\Plugin\Cache\DefaultCanCacheStrategy->canCacheRequest()` instead.
|
||||
* Marked `Guzzle\Http\Message\Request::canCache()` as deprecated. Use
|
||||
`Guzzle\Plugin\Cache\DefaultCanCacheStrategy->canCacheRequest()` instead.
|
||||
* Marked `Guzzle\Http\Message\Request::setIsRedirect()` as deprecated. Use the HistoryPlugin instead.
|
||||
* Marked `Guzzle\Http\Message\Request::isRedirect()` as deprecated. Use the HistoryPlugin instead.
|
||||
* Marked `Guzzle\Cache\CacheAdapterFactory::factory()` as deprecated
|
||||
* Marked 'command.headers', 'command.response_body' and 'command.on_complete' as deprecated for AbstractCommand.
|
||||
These will work through Guzzle 4.0
|
||||
* Marked 'request.params' for `Guzzle\Http\Client` as deprecated. Use [request.options][params].
|
||||
* Marked `Guzzle\Service\Client::enableMagicMethods()` as deprecated. Magic methods can no longer be disabled on a Guzzle\Service\Client.
|
||||
* Marked `Guzzle\Service\Client::getDefaultHeaders()` as deprecated. Use $client->getConfig()->getPath('request.options/headers')`.
|
||||
* Marked `Guzzle\Service\Client::setDefaultHeaders()` as deprecated. Use $client->getConfig()->setPath('request.options/headers/{header_name}', 'value')`.
|
||||
* Marked `Guzzle\Parser\Url\UrlParser` as deprecated. Just use PHP's `parse_url()` and percent encode your UTF-8.
|
||||
* Marked `Guzzle\Common\Collection::inject()` as deprecated.
|
||||
* Marked `Guzzle\Plugin\CurlAuth\CurlAuthPlugin` as deprecated. Use `$client->getConfig()->setPath('request.options/auth', array('user', 'pass', 'Basic|Digest');`
|
||||
* CacheKeyProviderInterface and DefaultCacheKeyProvider are no longer used. All of this logic is handled in a
|
||||
CacheStorageInterface. These two objects and interface will be removed in a future version.
|
||||
* Always setting X-cache headers on cached responses
|
||||
* Default cache TTLs are now handled by the CacheStorageInterface of a CachePlugin
|
||||
* `CacheStorageInterface::cache($key, Response $response, $ttl = null)` has changed to `cache(RequestInterface
|
||||
$request, Response $response);`
|
||||
* `CacheStorageInterface::fetch($key)` has changed to `fetch(RequestInterface $request);`
|
||||
* `CacheStorageInterface::delete($key)` has changed to `delete(RequestInterface $request);`
|
||||
* Added `CacheStorageInterface::purge($url)`
|
||||
* `DefaultRevalidation::__construct(CacheKeyProviderInterface $cacheKey, CacheStorageInterface $cache, CachePlugin
|
||||
$plugin)` has changed to `DefaultRevalidation::__construct(CacheStorageInterface $cache,
|
||||
CanCacheStrategyInterface $canCache = null)`
|
||||
* Added `RevalidationInterface::shouldRevalidate(RequestInterface $request, Response $response)`
|
||||
|
||||
## 3.6.0 - 2013-05-29
|
||||
|
||||
* ServiceDescription now implements ToArrayInterface
|
||||
* Added command.hidden_params to blacklist certain headers from being treated as additionalParameters
|
||||
* Guzzle can now correctly parse incomplete URLs
|
||||
* Mixed casing of headers are now forced to be a single consistent casing across all values for that header.
|
||||
* Messages internally use a HeaderCollection object to delegate handling case-insensitive header resolution
|
||||
* Removed the whole changedHeader() function system of messages because all header changes now go through addHeader().
|
||||
* Specific header implementations can be created for complex headers. When a message creates a header, it uses a
|
||||
HeaderFactory which can map specific headers to specific header classes. There is now a Link header and
|
||||
CacheControl header implementation.
|
||||
* Removed from interface: Guzzle\Http\ClientInterface::setUriTemplate
|
||||
* Removed from interface: Guzzle\Http\ClientInterface::setCurlMulti()
|
||||
* Removed Guzzle\Http\Message\Request::receivedRequestHeader() and implemented this functionality in
|
||||
Guzzle\Http\Curl\RequestMediator
|
||||
* Removed the optional $asString parameter from MessageInterface::getHeader(). Just cast the header to a string.
|
||||
* Removed the optional $tryChunkedTransfer option from Guzzle\Http\Message\EntityEnclosingRequestInterface
|
||||
* Removed the $asObjects argument from Guzzle\Http\Message\MessageInterface::getHeaders()
|
||||
* Removed Guzzle\Parser\ParserRegister::get(). Use getParser()
|
||||
* Removed Guzzle\Parser\ParserRegister::set(). Use registerParser().
|
||||
* All response header helper functions return a string rather than mixing Header objects and strings inconsistently
|
||||
* Removed cURL blacklist support. This is no longer necessary now that Expect, Accept, etc are managed by Guzzle
|
||||
directly via interfaces
|
||||
* Removed the injecting of a request object onto a response object. The methods to get and set a request still exist
|
||||
but are a no-op until removed.
|
||||
* Most classes that used to require a ``Guzzle\Service\Command\CommandInterface` typehint now request a
|
||||
`Guzzle\Service\Command\ArrayCommandInterface`.
|
||||
* Added `Guzzle\Http\Message\RequestInterface::startResponse()` to the RequestInterface to handle injecting a response
|
||||
on a request while the request is still being transferred
|
||||
* The ability to case-insensitively search for header values
|
||||
* Guzzle\Http\Message\Header::hasExactHeader
|
||||
* Guzzle\Http\Message\Header::raw. Use getAll()
|
||||
* Deprecated cache control specific methods on Guzzle\Http\Message\AbstractMessage. Use the CacheControl header object
|
||||
instead.
|
||||
* `Guzzle\Service\Command\CommandInterface` now extends from ToArrayInterface and ArrayAccess
|
||||
* Added the ability to cast Model objects to a string to view debug information.
|
||||
|
||||
## 3.5.0 - 2013-05-13
|
||||
|
||||
* Bug: Fixed a regression so that request responses are parsed only once per oncomplete event rather than multiple times
|
||||
* Bug: Better cleanup of one-time events accross the board (when an event is meant to fire once, it will now remove
|
||||
itself from the EventDispatcher)
|
||||
* Bug: `Guzzle\Log\MessageFormatter` now properly writes "total_time" and "connect_time" values
|
||||
* Bug: Cloning an EntityEnclosingRequest now clones the EntityBody too
|
||||
* Bug: Fixed an undefined index error when parsing nested JSON responses with a sentAs parameter that reference a
|
||||
non-existent key
|
||||
* Bug: All __call() method arguments are now required (helps with mocking frameworks)
|
||||
* Deprecating Response::getRequest() and now using a shallow clone of a request object to remove a circular reference
|
||||
to help with refcount based garbage collection of resources created by sending a request
|
||||
* Deprecating ZF1 cache and log adapters. These will be removed in the next major version.
|
||||
* Deprecating `Response::getPreviousResponse()` (method signature still exists, but it'sdeprecated). Use the
|
||||
HistoryPlugin for a history.
|
||||
* Added a `responseBody` alias for the `response_body` location
|
||||
* Refactored internals to no longer rely on Response::getRequest()
|
||||
* HistoryPlugin can now be cast to a string
|
||||
* HistoryPlugin now logs transactions rather than requests and responses to more accurately keep track of the requests
|
||||
and responses that are sent over the wire
|
||||
* Added `getEffectiveUrl()` and `getRedirectCount()` to Response objects
|
||||
|
||||
## 3.4.3 - 2013-04-30
|
||||
|
||||
* Bug fix: Fixing bug introduced in 3.4.2 where redirect responses are duplicated on the final redirected response
|
||||
* Added a check to re-extract the temp cacert bundle from the phar before sending each request
|
||||
|
||||
## 3.4.2 - 2013-04-29
|
||||
|
||||
* Bug fix: Stream objects now work correctly with "a" and "a+" modes
|
||||
* Bug fix: Removing `Transfer-Encoding: chunked` header when a Content-Length is present
|
||||
* Bug fix: AsyncPlugin no longer forces HEAD requests
|
||||
* Bug fix: DateTime timezones are now properly handled when using the service description schema formatter
|
||||
* Bug fix: CachePlugin now properly handles stale-if-error directives when a request to the origin server fails
|
||||
* Setting a response on a request will write to the custom request body from the response body if one is specified
|
||||
* LogPlugin now writes to php://output when STDERR is undefined
|
||||
* Added the ability to set multiple POST files for the same key in a single call
|
||||
* application/x-www-form-urlencoded POSTs now use the utf-8 charset by default
|
||||
* Added the ability to queue CurlExceptions to the MockPlugin
|
||||
* Cleaned up how manual responses are queued on requests (removed "queued_response" and now using request.before_send)
|
||||
* Configuration loading now allows remote files
|
||||
|
||||
## 3.4.1 - 2013-04-16
|
||||
|
||||
* Large refactoring to how CurlMulti handles work. There is now a proxy that sits in front of a pool of CurlMulti
|
||||
handles. This greatly simplifies the implementation, fixes a couple bugs, and provides a small performance boost.
|
||||
* Exceptions are now properly grouped when sending requests in parallel
|
||||
* Redirects are now properly aggregated when a multi transaction fails
|
||||
* Redirects now set the response on the original object even in the event of a failure
|
||||
* Bug fix: Model names are now properly set even when using $refs
|
||||
* Added support for PHP 5.5's CurlFile to prevent warnings with the deprecated @ syntax
|
||||
* Added support for oauth_callback in OAuth signatures
|
||||
* Added support for oauth_verifier in OAuth signatures
|
||||
* Added support to attempt to retrieve a command first literally, then ucfirst, the with inflection
|
||||
|
||||
## 3.4.0 - 2013-04-11
|
||||
|
||||
* Bug fix: URLs are now resolved correctly based on http://tools.ietf.org/html/rfc3986#section-5.2. #289
|
||||
* Bug fix: Absolute URLs with a path in a service description will now properly override the base URL. #289
|
||||
* Bug fix: Parsing a query string with a single PHP array value will now result in an array. #263
|
||||
* Bug fix: Better normalization of the User-Agent header to prevent duplicate headers. #264.
|
||||
* Bug fix: Added `number` type to service descriptions.
|
||||
* Bug fix: empty parameters are removed from an OAuth signature
|
||||
* Bug fix: Revalidating a cache entry prefers the Last-Modified over the Date header
|
||||
* Bug fix: Fixed "array to string" error when validating a union of types in a service description
|
||||
* Bug fix: Removed code that attempted to determine the size of a stream when data is written to the stream
|
||||
* Bug fix: Not including an `oauth_token` if the value is null in the OauthPlugin.
|
||||
* Bug fix: Now correctly aggregating successful requests and failed requests in CurlMulti when a redirect occurs.
|
||||
* The new default CURLOPT_TIMEOUT setting has been increased to 150 seconds so that Guzzle works on poor connections.
|
||||
* Added a feature to EntityEnclosingRequest::setBody() that will automatically set the Content-Type of the request if
|
||||
the Content-Type can be determined based on the entity body or the path of the request.
|
||||
* Added the ability to overwrite configuration settings in a client when grabbing a throwaway client from a builder.
|
||||
* Added support for a PSR-3 LogAdapter.
|
||||
* Added a `command.after_prepare` event
|
||||
* Added `oauth_callback` parameter to the OauthPlugin
|
||||
* Added the ability to create a custom stream class when using a stream factory
|
||||
* Added a CachingEntityBody decorator
|
||||
* Added support for `additionalParameters` in service descriptions to define how custom parameters are serialized.
|
||||
* The bundled SSL certificate is now provided in the phar file and extracted when running Guzzle from a phar.
|
||||
* You can now send any EntityEnclosingRequest with POST fields or POST files and cURL will handle creating bodies
|
||||
* POST requests using a custom entity body are now treated exactly like PUT requests but with a custom cURL method. This
|
||||
means that the redirect behavior of POST requests with custom bodies will not be the same as POST requests that use
|
||||
POST fields or files (the latter is only used when emulating a form POST in the browser).
|
||||
* Lots of cleanup to CurlHandle::factory and RequestFactory::createRequest
|
||||
|
||||
## 3.3.1 - 2013-03-10
|
||||
|
||||
* Added the ability to create PHP streaming responses from HTTP requests
|
||||
* Bug fix: Running any filters when parsing response headers with service descriptions
|
||||
* Bug fix: OauthPlugin fixes to allow for multi-dimensional array signing, and sorting parameters before signing
|
||||
* Bug fix: Removed the adding of default empty arrays and false Booleans to responses in order to be consistent across
|
||||
response location visitors.
|
||||
* Bug fix: Removed the possibility of creating configuration files with circular dependencies
|
||||
* RequestFactory::create() now uses the key of a POST file when setting the POST file name
|
||||
* Added xmlAllowEmpty to serialize an XML body even if no XML specific parameters are set
|
||||
|
||||
## 3.3.0 - 2013-03-03
|
||||
|
||||
* A large number of performance optimizations have been made
|
||||
* Bug fix: Added 'wb' as a valid write mode for streams
|
||||
* Bug fix: `Guzzle\Http\Message\Response::json()` now allows scalar values to be returned
|
||||
* Bug fix: Fixed bug in `Guzzle\Http\Message\Response` where wrapping quotes were stripped from `getEtag()`
|
||||
* BC: Removed `Guzzle\Http\Utils` class
|
||||
* BC: Setting a service description on a client will no longer modify the client's command factories.
|
||||
* BC: Emitting IO events from a RequestMediator is now a parameter that must be set in a request's curl options using
|
||||
the 'emit_io' key. This was previously set under a request's parameters using 'curl.emit_io'
|
||||
* BC: `Guzzle\Stream\Stream::getWrapper()` and `Guzzle\Stream\Stream::getSteamType()` are no longer converted to
|
||||
lowercase
|
||||
* Operation parameter objects are now lazy loaded internally
|
||||
* Added ErrorResponsePlugin that can throw errors for responses defined in service description operations' errorResponses
|
||||
* Added support for instantiating responseType=class responseClass classes. Classes must implement
|
||||
`Guzzle\Service\Command\ResponseClassInterface`
|
||||
* Added support for additionalProperties for top-level parameters in responseType=model responseClasses. These
|
||||
additional properties also support locations and can be used to parse JSON responses where the outermost part of the
|
||||
JSON is an array
|
||||
* Added support for nested renaming of JSON models (rename sentAs to name)
|
||||
* CachePlugin
|
||||
* Added support for stale-if-error so that the CachePlugin can now serve stale content from the cache on error
|
||||
* Debug headers can now added to cached response in the CachePlugin
|
||||
|
||||
## 3.2.0 - 2013-02-14
|
||||
|
||||
* CurlMulti is no longer reused globally. A new multi object is created per-client. This helps to isolate clients.
|
||||
* URLs with no path no longer contain a "/" by default
|
||||
* Guzzle\Http\QueryString does no longer manages the leading "?". This is now handled in Guzzle\Http\Url.
|
||||
* BadResponseException no longer includes the full request and response message
|
||||
* Adding setData() to Guzzle\Service\Description\ServiceDescriptionInterface
|
||||
* Adding getResponseBody() to Guzzle\Http\Message\RequestInterface
|
||||
* Various updates to classes to use ServiceDescriptionInterface type hints rather than ServiceDescription
|
||||
* Header values can now be normalized into distinct values when multiple headers are combined with a comma separated list
|
||||
* xmlEncoding can now be customized for the XML declaration of a XML service description operation
|
||||
* Guzzle\Http\QueryString now uses Guzzle\Http\QueryAggregator\QueryAggregatorInterface objects to add custom value
|
||||
aggregation and no longer uses callbacks
|
||||
* The URL encoding implementation of Guzzle\Http\QueryString can now be customized
|
||||
* Bug fix: Filters were not always invoked for array service description parameters
|
||||
* Bug fix: Redirects now use a target response body rather than a temporary response body
|
||||
* Bug fix: The default exponential backoff BackoffPlugin was not giving when the request threshold was exceeded
|
||||
* Bug fix: Guzzle now takes the first found value when grabbing Cache-Control directives
|
||||
|
||||
## 3.1.2 - 2013-01-27
|
||||
|
||||
* Refactored how operation responses are parsed. Visitors now include a before() method responsible for parsing the
|
||||
response body. For example, the XmlVisitor now parses the XML response into an array in the before() method.
|
||||
* Fixed an issue where cURL would not automatically decompress responses when the Accept-Encoding header was sent
|
||||
* CURLOPT_SSL_VERIFYHOST is never set to 1 because it is deprecated (see 5e0ff2ef20f839e19d1eeb298f90ba3598784444)
|
||||
* Fixed a bug where redirect responses were not chained correctly using getPreviousResponse()
|
||||
* Setting default headers on a client after setting the user-agent will not erase the user-agent setting
|
||||
|
||||
## 3.1.1 - 2013-01-20
|
||||
|
||||
* Adding wildcard support to Guzzle\Common\Collection::getPath()
|
||||
* Adding alias support to ServiceBuilder configs
|
||||
* Adding Guzzle\Service\Resource\CompositeResourceIteratorFactory and cleaning up factory interface
|
||||
|
||||
## 3.1.0 - 2013-01-12
|
||||
|
||||
* BC: CurlException now extends from RequestException rather than BadResponseException
|
||||
* BC: Renamed Guzzle\Plugin\Cache\CanCacheStrategyInterface::canCache() to canCacheRequest() and added CanCacheResponse()
|
||||
* Added getData to ServiceDescriptionInterface
|
||||
* Added context array to RequestInterface::setState()
|
||||
* Bug: Removing hard dependency on the BackoffPlugin from Guzzle\Http
|
||||
* Bug: Adding required content-type when JSON request visitor adds JSON to a command
|
||||
* Bug: Fixing the serialization of a service description with custom data
|
||||
* Made it easier to deal with exceptions thrown when transferring commands or requests in parallel by providing
|
||||
an array of successful and failed responses
|
||||
* Moved getPath from Guzzle\Service\Resource\Model to Guzzle\Common\Collection
|
||||
* Added Guzzle\Http\IoEmittingEntityBody
|
||||
* Moved command filtration from validators to location visitors
|
||||
* Added `extends` attributes to service description parameters
|
||||
* Added getModels to ServiceDescriptionInterface
|
||||
|
||||
## 3.0.7 - 2012-12-19
|
||||
|
||||
* Fixing phar detection when forcing a cacert to system if null or true
|
||||
* Allowing filename to be passed to `Guzzle\Http\Message\Request::setResponseBody()`
|
||||
* Cleaning up `Guzzle\Common\Collection::inject` method
|
||||
* Adding a response_body location to service descriptions
|
||||
|
||||
## 3.0.6 - 2012-12-09
|
||||
|
||||
* CurlMulti performance improvements
|
||||
* Adding setErrorResponses() to Operation
|
||||
* composer.json tweaks
|
||||
|
||||
## 3.0.5 - 2012-11-18
|
||||
|
||||
* Bug: Fixing an infinite recursion bug caused from revalidating with the CachePlugin
|
||||
* Bug: Response body can now be a string containing "0"
|
||||
* Bug: Using Guzzle inside of a phar uses system by default but now allows for a custom cacert
|
||||
* Bug: QueryString::fromString now properly parses query string parameters that contain equal signs
|
||||
* Added support for XML attributes in service description responses
|
||||
* DefaultRequestSerializer now supports array URI parameter values for URI template expansion
|
||||
* Added better mimetype guessing to requests and post files
|
||||
|
||||
## 3.0.4 - 2012-11-11
|
||||
|
||||
* Bug: Fixed a bug when adding multiple cookies to a request to use the correct glue value
|
||||
* Bug: Cookies can now be added that have a name, domain, or value set to "0"
|
||||
* Bug: Using the system cacert bundle when using the Phar
|
||||
* Added json and xml methods to Response to make it easier to parse JSON and XML response data into data structures
|
||||
* Enhanced cookie jar de-duplication
|
||||
* Added the ability to enable strict cookie jars that throw exceptions when invalid cookies are added
|
||||
* Added setStream to StreamInterface to actually make it possible to implement custom rewind behavior for entity bodies
|
||||
* Added the ability to create any sort of hash for a stream rather than just an MD5 hash
|
||||
|
||||
## 3.0.3 - 2012-11-04
|
||||
|
||||
* Implementing redirects in PHP rather than cURL
|
||||
* Added PECL URI template extension and using as default parser if available
|
||||
* Bug: Fixed Content-Length parsing of Response factory
|
||||
* Adding rewind() method to entity bodies and streams. Allows for custom rewinding of non-repeatable streams.
|
||||
* Adding ToArrayInterface throughout library
|
||||
* Fixing OauthPlugin to create unique nonce values per request
|
||||
|
||||
## 3.0.2 - 2012-10-25
|
||||
|
||||
* Magic methods are enabled by default on clients
|
||||
* Magic methods return the result of a command
|
||||
* Service clients no longer require a base_url option in the factory
|
||||
* Bug: Fixed an issue with URI templates where null template variables were being expanded
|
||||
|
||||
## 3.0.1 - 2012-10-22
|
||||
|
||||
* Models can now be used like regular collection objects by calling filter, map, etc
|
||||
* Models no longer require a Parameter structure or initial data in the constructor
|
||||
* Added a custom AppendIterator to get around a PHP bug with the `\AppendIterator`
|
||||
|
||||
## 3.0.0 - 2012-10-15
|
||||
|
||||
* Rewrote service description format to be based on Swagger
|
||||
* Now based on JSON schema
|
||||
* Added nested input structures and nested response models
|
||||
* Support for JSON and XML input and output models
|
||||
* Renamed `commands` to `operations`
|
||||
* Removed dot class notation
|
||||
* Removed custom types
|
||||
* Broke the project into smaller top-level namespaces to be more component friendly
|
||||
* Removed support for XML configs and descriptions. Use arrays or JSON files.
|
||||
* Removed the Validation component and Inspector
|
||||
* Moved all cookie code to Guzzle\Plugin\Cookie
|
||||
* Magic methods on a Guzzle\Service\Client now return the command un-executed.
|
||||
* Calling getResult() or getResponse() on a command will lazily execute the command if needed.
|
||||
* Now shipping with cURL's CA certs and using it by default
|
||||
* Added previousResponse() method to response objects
|
||||
* No longer sending Accept and Accept-Encoding headers on every request
|
||||
* Only sending an Expect header by default when a payload is greater than 1MB
|
||||
* Added/moved client options:
|
||||
* curl.blacklist to curl.option.blacklist
|
||||
* Added ssl.certificate_authority
|
||||
* Added a Guzzle\Iterator component
|
||||
* Moved plugins from Guzzle\Http\Plugin to Guzzle\Plugin
|
||||
* Added a more robust backoff retry strategy (replaced the ExponentialBackoffPlugin)
|
||||
* Added a more robust caching plugin
|
||||
* Added setBody to response objects
|
||||
* Updating LogPlugin to use a more flexible MessageFormatter
|
||||
* Added a completely revamped build process
|
||||
* Cleaning up Collection class and removing default values from the get method
|
||||
* Fixed ZF2 cache adapters
|
||||
|
||||
## 2.8.8 - 2012-10-15
|
||||
|
||||
* Bug: Fixed a cookie issue that caused dot prefixed domains to not match where popular browsers did
|
||||
|
||||
## 2.8.7 - 2012-09-30
|
||||
|
||||
* Bug: Fixed config file aliases for JSON includes
|
||||
* Bug: Fixed cookie bug on a request object by using CookieParser to parse cookies on requests
|
||||
* Bug: Removing the path to a file when sending a Content-Disposition header on a POST upload
|
||||
* Bug: Hardening request and response parsing to account for missing parts
|
||||
* Bug: Fixed PEAR packaging
|
||||
* Bug: Fixed Request::getInfo
|
||||
* Bug: Fixed cases where CURLM_CALL_MULTI_PERFORM return codes were causing curl transactions to fail
|
||||
* Adding the ability for the namespace Iterator factory to look in multiple directories
|
||||
* Added more getters/setters/removers from service descriptions
|
||||
* Added the ability to remove POST fields from OAuth signatures
|
||||
* OAuth plugin now supports 2-legged OAuth
|
||||
|
||||
## 2.8.6 - 2012-09-05
|
||||
|
||||
* Added the ability to modify and build service descriptions
|
||||
* Added the use of visitors to apply parameters to locations in service descriptions using the dynamic command
|
||||
* Added a `json` parameter location
|
||||
* Now allowing dot notation for classes in the CacheAdapterFactory
|
||||
* Using the union of two arrays rather than an array_merge when extending service builder services and service params
|
||||
* Ensuring that a service is a string before doing strpos() checks on it when substituting services for references
|
||||
in service builder config files.
|
||||
* Services defined in two different config files that include one another will by default replace the previously
|
||||
defined service, but you can now create services that extend themselves and merge their settings over the previous
|
||||
* The JsonLoader now supports aliasing filenames with different filenames. This allows you to alias something like
|
||||
'_default' with a default JSON configuration file.
|
||||
|
||||
## 2.8.5 - 2012-08-29
|
||||
|
||||
* Bug: Suppressed empty arrays from URI templates
|
||||
* Bug: Added the missing $options argument from ServiceDescription::factory to enable caching
|
||||
* Added support for HTTP responses that do not contain a reason phrase in the start-line
|
||||
* AbstractCommand commands are now invokable
|
||||
* Added a way to get the data used when signing an Oauth request before a request is sent
|
||||
|
||||
## 2.8.4 - 2012-08-15
|
||||
|
||||
* Bug: Custom delay time calculations are no longer ignored in the ExponentialBackoffPlugin
|
||||
* Added the ability to transfer entity bodies as a string rather than streamed. This gets around curl error 65. Set `body_as_string` in a request's curl options to enable.
|
||||
* Added a StreamInterface, EntityBodyInterface, and added ftell() to Guzzle\Common\Stream
|
||||
* Added an AbstractEntityBodyDecorator and a ReadLimitEntityBody decorator to transfer only a subset of a decorated stream
|
||||
* Stream and EntityBody objects will now return the file position to the previous position after a read required operation (e.g. getContentMd5())
|
||||
* Added additional response status codes
|
||||
* Removed SSL information from the default User-Agent header
|
||||
* DELETE requests can now send an entity body
|
||||
* Added an EventDispatcher to the ExponentialBackoffPlugin and added an ExponentialBackoffLogger to log backoff retries
|
||||
* Added the ability of the MockPlugin to consume mocked request bodies
|
||||
* LogPlugin now exposes request and response objects in the extras array
|
||||
|
||||
## 2.8.3 - 2012-07-30
|
||||
|
||||
* Bug: Fixed a case where empty POST requests were sent as GET requests
|
||||
* Bug: Fixed a bug in ExponentialBackoffPlugin that caused fatal errors when retrying an EntityEnclosingRequest that does not have a body
|
||||
* Bug: Setting the response body of a request to null after completing a request, not when setting the state of a request to new
|
||||
* Added multiple inheritance to service description commands
|
||||
* Added an ApiCommandInterface and added ``getParamNames()`` and ``hasParam()``
|
||||
* Removed the default 2mb size cutoff from the Md5ValidatorPlugin so that it now defaults to validating everything
|
||||
* Changed CurlMulti::perform to pass a smaller timeout to CurlMulti::executeHandles
|
||||
|
||||
## 2.8.2 - 2012-07-24
|
||||
|
||||
* Bug: Query string values set to 0 are no longer dropped from the query string
|
||||
* Bug: A Collection object is no longer created each time a call is made to ``Guzzle\Service\Command\AbstractCommand::getRequestHeaders()``
|
||||
* Bug: ``+`` is now treated as an encoded space when parsing query strings
|
||||
* QueryString and Collection performance improvements
|
||||
* Allowing dot notation for class paths in filters attribute of a service descriptions
|
||||
|
||||
## 2.8.1 - 2012-07-16
|
||||
|
||||
* Loosening Event Dispatcher dependency
|
||||
* POST redirects can now be customized using CURLOPT_POSTREDIR
|
||||
|
||||
## 2.8.0 - 2012-07-15
|
||||
|
||||
* BC: Guzzle\Http\Query
|
||||
* Query strings with empty variables will always show an equal sign unless the variable is set to QueryString::BLANK (e.g. ?acl= vs ?acl)
|
||||
* Changed isEncodingValues() and isEncodingFields() to isUrlEncoding()
|
||||
* Changed setEncodeValues(bool) and setEncodeFields(bool) to useUrlEncoding(bool)
|
||||
* Changed the aggregation functions of QueryString to be static methods
|
||||
* Can now use fromString() with querystrings that have a leading ?
|
||||
* cURL configuration values can be specified in service descriptions using ``curl.`` prefixed parameters
|
||||
* Content-Length is set to 0 before emitting the request.before_send event when sending an empty request body
|
||||
* Cookies are no longer URL decoded by default
|
||||
* Bug: URI template variables set to null are no longer expanded
|
||||
|
||||
## 2.7.2 - 2012-07-02
|
||||
|
||||
* BC: Moving things to get ready for subtree splits. Moving Inflection into Common. Moving Guzzle\Http\Parser to Guzzle\Parser.
|
||||
* BC: Removing Guzzle\Common\Batch\Batch::count() and replacing it with isEmpty()
|
||||
* CachePlugin now allows for a custom request parameter function to check if a request can be cached
|
||||
* Bug fix: CachePlugin now only caches GET and HEAD requests by default
|
||||
* Bug fix: Using header glue when transferring headers over the wire
|
||||
* Allowing deeply nested arrays for composite variables in URI templates
|
||||
* Batch divisors can now return iterators or arrays
|
||||
|
||||
## 2.7.1 - 2012-06-26
|
||||
|
||||
* Minor patch to update version number in UA string
|
||||
* Updating build process
|
||||
|
||||
## 2.7.0 - 2012-06-25
|
||||
|
||||
* BC: Inflection classes moved to Guzzle\Inflection. No longer static methods. Can now inject custom inflectors into classes.
|
||||
* BC: Removed magic setX methods from commands
|
||||
* BC: Magic methods mapped to service description commands are now inflected in the command factory rather than the client __call() method
|
||||
* Verbose cURL options are no longer enabled by default. Set curl.debug to true on a client to enable.
|
||||
* Bug: Now allowing colons in a response start-line (e.g. HTTP/1.1 503 Service Unavailable: Back-end server is at capacity)
|
||||
* Guzzle\Service\Resource\ResourceIteratorApplyBatched now internally uses the Guzzle\Common\Batch namespace
|
||||
* Added Guzzle\Service\Plugin namespace and a PluginCollectionPlugin
|
||||
* Added the ability to set POST fields and files in a service description
|
||||
* Guzzle\Http\EntityBody::factory() now accepts objects with a __toString() method
|
||||
* Adding a command.before_prepare event to clients
|
||||
* Added BatchClosureTransfer and BatchClosureDivisor
|
||||
* BatchTransferException now includes references to the batch divisor and transfer strategies
|
||||
* Fixed some tests so that they pass more reliably
|
||||
* Added Guzzle\Common\Log\ArrayLogAdapter
|
||||
|
||||
## 2.6.6 - 2012-06-10
|
||||
|
||||
* BC: Removing Guzzle\Http\Plugin\BatchQueuePlugin
|
||||
* BC: Removing Guzzle\Service\Command\CommandSet
|
||||
* Adding generic batching system (replaces the batch queue plugin and command set)
|
||||
* Updating ZF cache and log adapters and now using ZF's composer repository
|
||||
* Bug: Setting the name of each ApiParam when creating through an ApiCommand
|
||||
* Adding result_type, result_doc, deprecated, and doc_url to service descriptions
|
||||
* Bug: Changed the default cookie header casing back to 'Cookie'
|
||||
|
||||
## 2.6.5 - 2012-06-03
|
||||
|
||||
* BC: Renaming Guzzle\Http\Message\RequestInterface::getResourceUri() to getResource()
|
||||
* BC: Removing unused AUTH_BASIC and AUTH_DIGEST constants from
|
||||
* BC: Guzzle\Http\Cookie is now used to manage Set-Cookie data, not Cookie data
|
||||
* BC: Renaming methods in the CookieJarInterface
|
||||
* Moving almost all cookie logic out of the CookiePlugin and into the Cookie or CookieJar implementations
|
||||
* Making the default glue for HTTP headers ';' instead of ','
|
||||
* Adding a removeValue to Guzzle\Http\Message\Header
|
||||
* Adding getCookies() to request interface.
|
||||
* Making it easier to add event subscribers to HasDispatcherInterface classes. Can now directly call addSubscriber()
|
||||
|
||||
## 2.6.4 - 2012-05-30
|
||||
|
||||
* BC: Cleaning up how POST files are stored in EntityEnclosingRequest objects. Adding PostFile class.
|
||||
* BC: Moving ApiCommand specific functionality from the Inspector and on to the ApiCommand
|
||||
* Bug: Fixing magic method command calls on clients
|
||||
* Bug: Email constraint only validates strings
|
||||
* Bug: Aggregate POST fields when POST files are present in curl handle
|
||||
* Bug: Fixing default User-Agent header
|
||||
* Bug: Only appending or prepending parameters in commands if they are specified
|
||||
* Bug: Not requiring response reason phrases or status codes to match a predefined list of codes
|
||||
* Allowing the use of dot notation for class namespaces when using instance_of constraint
|
||||
* Added any_match validation constraint
|
||||
* Added an AsyncPlugin
|
||||
* Passing request object to the calculateWait method of the ExponentialBackoffPlugin
|
||||
* Allowing the result of a command object to be changed
|
||||
* Parsing location and type sub values when instantiating a service description rather than over and over at runtime
|
||||
|
||||
## 2.6.3 - 2012-05-23
|
||||
|
||||
* [BC] Guzzle\Common\FromConfigInterface no longer requires any config options.
|
||||
* [BC] Refactoring how POST files are stored on an EntityEnclosingRequest. They are now separate from POST fields.
|
||||
* You can now use an array of data when creating PUT request bodies in the request factory.
|
||||
* Removing the requirement that HTTPS requests needed a Cache-Control: public directive to be cacheable.
|
||||
* [Http] Adding support for Content-Type in multipart POST uploads per upload
|
||||
* [Http] Added support for uploading multiple files using the same name (foo[0], foo[1])
|
||||
* Adding more POST data operations for easier manipulation of POST data.
|
||||
* You can now set empty POST fields.
|
||||
* The body of a request is only shown on EntityEnclosingRequest objects that do not use POST files.
|
||||
* Split the Guzzle\Service\Inspector::validateConfig method into two methods. One to initialize when a command is created, and one to validate.
|
||||
* CS updates
|
||||
|
||||
## 2.6.2 - 2012-05-19
|
||||
|
||||
* [Http] Better handling of nested scope requests in CurlMulti. Requests are now always prepares in the send() method rather than the addRequest() method.
|
||||
|
||||
## 2.6.1 - 2012-05-19
|
||||
|
||||
* [BC] Removing 'path' support in service descriptions. Use 'uri'.
|
||||
* [BC] Guzzle\Service\Inspector::parseDocBlock is now protected. Adding getApiParamsForClass() with cache.
|
||||
* [BC] Removing Guzzle\Common\NullObject. Use https://github.com/mtdowling/NullObject if you need it.
|
||||
* [BC] Removing Guzzle\Common\XmlElement.
|
||||
* All commands, both dynamic and concrete, have ApiCommand objects.
|
||||
* Adding a fix for CurlMulti so that if all of the connections encounter some sort of curl error, then the loop exits.
|
||||
* Adding checks to EntityEnclosingRequest so that empty POST files and fields are ignored.
|
||||
* Making the method signature of Guzzle\Service\Builder\ServiceBuilder::factory more flexible.
|
||||
|
||||
## 2.6.0 - 2012-05-15
|
||||
|
||||
* [BC] Moving Guzzle\Service\Builder to Guzzle\Service\Builder\ServiceBuilder
|
||||
* [BC] Executing a Command returns the result of the command rather than the command
|
||||
* [BC] Moving all HTTP parsing logic to Guzzle\Http\Parsers. Allows for faster C implementations if needed.
|
||||
* [BC] Changing the Guzzle\Http\Message\Response::setProtocol() method to accept a protocol and version in separate args.
|
||||
* [BC] Moving ResourceIterator* to Guzzle\Service\Resource
|
||||
* [BC] Completely refactored ResourceIterators to iterate over a cloned command object
|
||||
* [BC] Moved Guzzle\Http\UriTemplate to Guzzle\Http\Parser\UriTemplate\UriTemplate
|
||||
* [BC] Guzzle\Guzzle is now deprecated
|
||||
* Moving Guzzle\Common\Guzzle::inject to Guzzle\Common\Collection::inject
|
||||
* Adding Guzzle\Version class to give version information about Guzzle
|
||||
* Adding Guzzle\Http\Utils class to provide getDefaultUserAgent() and getHttpDate()
|
||||
* Adding Guzzle\Curl\CurlVersion to manage caching curl_version() data
|
||||
* ServiceDescription and ServiceBuilder are now cacheable using similar configs
|
||||
* Changing the format of XML and JSON service builder configs. Backwards compatible.
|
||||
* Cleaned up Cookie parsing
|
||||
* Trimming the default Guzzle User-Agent header
|
||||
* Adding a setOnComplete() method to Commands that is called when a command completes
|
||||
* Keeping track of requests that were mocked in the MockPlugin
|
||||
* Fixed a caching bug in the CacheAdapterFactory
|
||||
* Inspector objects can be injected into a Command object
|
||||
* Refactoring a lot of code and tests to be case insensitive when dealing with headers
|
||||
* Adding Guzzle\Http\Message\HeaderComparison for easy comparison of HTTP headers using a DSL
|
||||
* Adding the ability to set global option overrides to service builder configs
|
||||
* Adding the ability to include other service builder config files from within XML and JSON files
|
||||
* Moving the parseQuery method out of Url and on to QueryString::fromString() as a static factory method.
|
||||
|
||||
## 2.5.0 - 2012-05-08
|
||||
|
||||
* Major performance improvements
|
||||
* [BC] Simplifying Guzzle\Common\Collection. Please check to see if you are using features that are now deprecated.
|
||||
* [BC] Using a custom validation system that allows a flyweight implementation for much faster validation. No longer using Symfony2 Validation component.
|
||||
* [BC] No longer supporting "{{ }}" for injecting into command or UriTemplates. Use "{}"
|
||||
* Added the ability to passed parameters to all requests created by a client
|
||||
* Added callback functionality to the ExponentialBackoffPlugin
|
||||
* Using microtime in ExponentialBackoffPlugin to allow more granular backoff strategies.
|
||||
* Rewinding request stream bodies when retrying requests
|
||||
* Exception is thrown when JSON response body cannot be decoded
|
||||
* Added configurable magic method calls to clients and commands. This is off by default.
|
||||
* Fixed a defect that added a hash to every parsed URL part
|
||||
* Fixed duplicate none generation for OauthPlugin.
|
||||
* Emitting an event each time a client is generated by a ServiceBuilder
|
||||
* Using an ApiParams object instead of a Collection for parameters of an ApiCommand
|
||||
* cache.* request parameters should be renamed to params.cache.*
|
||||
* Added the ability to set arbitrary curl options on requests (disable_wire, progress, etc). See CurlHandle.
|
||||
* Added the ability to disable type validation of service descriptions
|
||||
* ServiceDescriptions and ServiceBuilders are now Serializable
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user