diff --git a/RELEASE-1.0.0b4 b/RELEASE-1.0.0b4 index 0d6c9e0..ca0a6e6 100644 --- a/RELEASE-1.0.0b4 +++ b/RELEASE-1.0.0b4 @@ -1,4 +1,4 @@ -Brand new way of manipulating data, and listen... +Brand new way of manipulating data, encryption, and listen... * A new Util class that abstracts away tons of fancy features, including: - CRUD operations @@ -6,6 +6,7 @@ Brand new way of manipulating data, and listen... - Executing scripts (with the ability to pass typed parameters ala SQL prepared statements) - Putting and getting files out of RouterOS - Helper methods for converting back and forth between PHP and RouterOS values. +* Support for encrypted connections, both with and without a certificate. Note that due to known issues with PHP itself, encrypted connections may be unstable (as in "sometimes disconnect suddenly" or "sometimes hang when you use Client::sendSync() and/or Client::completeRequest() and/or Client::loop() without a timeout"). * Client::loop() and Client::completeRequest() no longer fail if there's no reply within "default_socket_timeout" seconds. This means you can now use the "listen" command without also setting up something else to keep the connection busy. * Client::loop() now accepts timeouts modeled after stream_select()'s, as opposed to a single float value. As before, the default is "no time limit", but is now specified with NULL instead of 0. Analogous arguments have been added to Response's constructor. * When receiving, the release lock is released when ANY exception is thrown. Previously, this would be so only in case of SocketException. diff --git a/composer.json b/composer.json index f66380b..4646f81 100644 --- a/composer.json +++ b/composer.json @@ -17,8 +17,13 @@ }, "require": { "php": ">=5.3.0", - "pear2/net_transmitter": "@dev", - "pear2/cache_shm": "@dev" + "pear2/net_transmitter": ">=1.0.0a4" + }, + "suggest": { + "pear2/cache_shm": ">=0.1.2", + "ext-apc": ">=3.0.13", + "ext-wincache": ">=1.1.0", + "ext-openssl": "*" }, "autoload": { "psr-0": { @@ -27,31 +32,5 @@ "PEAR2\\Cache\\SHM": "vendor/pear2/cache_shm/src/" } }, - "minimum-stability": "dev", - "repositories": [ - { - "type": "package", - "package": { - "name": "pear2/net_transmitter", - "version": "@dev", - "source": { - "type": "git", - "url": "https://github.com/pear2/Net_Transmitter.git", - "reference": "master" - } - } - }, - { - "type": "package", - "package": { - "name": "pear2/cache_shm", - "version": "@dev", - "source": { - "type": "git", - "url": "https://github.com/pear2/Cache_SHM.git", - "reference": "master" - } - } - } - ] + "minimum-stability": "dev" } diff --git a/docs/phpdoc.dist.xml b/docs/phpdoc.dist.xml index 2d217a0..08e58ab 100644 --- a/docs/phpdoc.dist.xml +++ b/docs/phpdoc.dist.xml @@ -3,7 +3,7 @@ PEAR2_Net_RouterOS documentation PEAR2_Net_RouterOS - PEAR2_Net_RouterOS__PhpDocumentor_Documentation + PEAR2_Net_RouterOS__PhpDocumentor_Cache php diff --git a/docs/tutorials/PEAR2_Net_RouterOS/Client.cls b/docs/tutorials/PEAR2_Net_RouterOS/Client.cls deleted file mode 100644 index 7ba2b80..0000000 --- a/docs/tutorials/PEAR2_Net_RouterOS/Client.cls +++ /dev/null @@ -1,78 +0,0 @@ - - - - Approaches with Client - Description of the various approaches in using the Client class - - - Vasil Rangelov - - {@link mailto:boen.robot@gmail.com boen.robot@gmail.com} - - - - {@toc} - - Synchonious requests - -The easiest approach in using PEAR2_Net_RouterOS is to connect, send a request, get the responses, and use them if you need to, all at one time. This is reffered to as "Synchonious request". - - - Simple requests - -If the request you want to send is just a simple command with no arguments, the easiest way is to pass it right there at the {@link Client::sendSync()} method, like this: - - {@example sync-request-simple.php} - -You can also use the syntax from RouterOS's shell (spaces between words instead of "/"), but again - no arguments. Also, the command needs to be absolute (begin with "/"). Examples in the rest of this documentation will use the API syntax. - - - - Requests with arguments - -To add arguments to a command, you need to use the {@link Request::setArgument()} method before you send the request. You can reuse the same request object by clearing its arguments and/or setting new values appropriately, as in the following example. - - {@example sync-request-arguments.php} - - - - Asynchronous requests - -You may want to deal with the responses from commands later instead of right after you send them. -Or you might only need to deal with one of the responses, and yet you need to send several requests. Or you might want to use a command which returns responses continiously, and is therefore not suitable for {@link Client::sendSync()}. -Either way, {@link Client::sendAsync()} is the method you need. Depending on the way you want to deal with the responses, there are various other methods which you may use along with it. - - - Send and forget - -If you don't care about the responses, you can just do something like the following - - {@example send-and-forget.php} - -Note that, as in the example above, different asynchronious requests need to have a different "tag", regardless of whether you care about the responses or not. A "tag" in this context is a RouterOS API specific construct that allows clients like PEAR2_Net_RouterOS to keep track of responses coming from multiple requests, since they don't appear in the order of their execution. You can only reuse a tag once you get its final response. - - - - Loop and extract - -One way to get responses is to let PEAR2_Net_RouterOS process any new ones, and then extract those that interest you. You can start processing with the {@link Client::loop()} method. -If you've made requests that you know will eventually be finished, you can use {@link Client::loop()} without an argument to let processing stop only once all requests have returned their final response. Here's an example that continues from the previous one. - - {@example loop-and-extract.php} - - - Callback and loop - -Instead of extracting responses, you may instead assign responses for a request to a callback. Once you do that, starting the processing is all you need to do. - - {@example callback-and-loop.php} - - - Send and complete - -Processing of responses can also be started with {@link Client::completeRequest()}. The difference is that {@link Client::loop()} ends when a certain timeout is reached, or when all requests are finished, and {@link Client::completeRequest()} instead ends when the final response of a specified request has been processed, regardless of the time it takes. The return value is an array of all responses, or an empty array if the request was assigned to a callback. - - {@example send-and-complete.php} - - - \ No newline at end of file diff --git a/docs/tutorials/PEAR2_Net_RouterOS/PEAR2_Net_RouterOS.pkg b/docs/tutorials/PEAR2_Net_RouterOS/PEAR2_Net_RouterOS.pkg deleted file mode 100644 index fdbb132..0000000 --- a/docs/tutorials/PEAR2_Net_RouterOS/PEAR2_Net_RouterOS.pkg +++ /dev/null @@ -1,138 +0,0 @@ - - - - Getting started - First steps in using PEAR2_Net_RouterOS - - - Vasil Rangelov - - {@link mailto:boen.robot@gmail.com boen.robot@gmail.com} - - - - {@toc} - - Introduction - -RouterOS is the flag product of the company {@link http://mikrotik.com/ MikroTik} -and is a powerful router software. One of its many abilities is to allow control over it via an API. -This package provides a client for {@link http://wiki.mikrotik.com/wiki/Manual:API that API}, in turn allowing you to use PHP to control RouterOS hosts. - - - - Requirements - - PHP 5.3.0 or later. - A host with RouterOS v3 or later. - Enabled API service on the RouterOS host. - The PCRE extension (bundled and enabled by default in PHP). - The iconv extension (optional; bundled and enabled by default in PHP; required only if you want to use automatic charset convertion) - PEAR2_Net_Transmitter (bundled with the PEAR2_Net_RouterOS archive; installed automatically by Pyrus) - - -The API service is disabled by default. To enable it, you need to execute -/ip service set numbers="api" address="0.0.0.0/0" disabled="no" -at a RouterOS terminal. The "address" argument in the command above allows you to limit access to this service only to certain IP addresses. For security's sake, it's better that you limit connections only to the IP address with which PHP will access RouterOS. - - - - Installation - - Installation with {@link http://pear2.php.net Pyrus/PEAR2} - - Assuming you have {@link http://pear.php.net/manual/en/installationpyrus.introduction.php installed Pyrus}, you can install PEAR2_Net_RouterOS from the PEAR2 channel with - pyrus install PEAR2_Net_RouterOS-alpha - - You might notice that the version number of PEAR2_Net_RouterOS suggests it's a beta, and yet we use "-alpha" in the command above. Well, yes, PEAR2_Net_RouterOS is a beta, but it has a dependency to another package - PEAR2_Net_Transmitter - which is an alpha. To avoid getting errors, you need to use "-alpha" until that package reaches a beta. - - If you've decided to not use the PEAR2 channel, but instead install directly from the archive distributed at the project page, you can use - pyrus install /path/to/downloaded/archive.tgz - If you haven't installed PEAR_Net_Transmitter previously, Pyrus will install the one at the PEAR2 channel (not the bundled version, although the two are equivalent at the time of this writing). - - - Installation with PEAR. - Like most PEAR2 packages, PEAR2_Net_RouterOS is compatible with the PEAR installer. However, you have to first discover the PEAR2 channel with - pear channel-discover pear2.php.net - and only then install PEAR2_Net_RouterOS with - pear install pear2/PEAR2_Net_RouterOS-alpha - - - Manual installation. - The archive includes a version of PEAR2_Net_Transmitter, so if you've downloaded the archive, instead of using the PEAR(2) installer, you can just extract the contents of the "src" folder wherever you like. To emulate the PEAR(2) installer, you can place the files in a folder that's within your include_path. - - If you're installing from the respository, you'll have to also install PEAR2_Net_Transmitter in one way or another before you can use this package. - - - - Usage. - -To use this in a PHP file, you could manally include every required class, but to save yourself some hassle, it's a better idea that you just include the file Autoload.php, like: - - -<?php -include_once 'PEAR2/Net/RouterOS/Autoload.php'; -//Use any Net_RouterOS class -?> - - -Net_RouterOS uses namespaces - a feature introduced in PHP 5.3 - for its organization. -Among other things, this means that instead of you having to write long class names, you can just declare at the top that you'll be using this namespace, and then just write shorter class names. The possible approaches are as follows: - - -Using a fully qualified class name - -<?php -include_once 'PEAR2/Net/RouterOS/Autoload.php'; -$client = new PEAR2\Net\RouterOS\Client('example.com', 'admin'); -// Use the client here -?> - - - -Declaring the \PEAR2\Net\RouterOS as your default namespace - -<?php -namespace PEAR2\Net\RouterOS; -include_once 'PEAR2/Net/RouterOS/Autoload.php'; -$client = new Client('example.com', 'admin'); -// Use the client here -?> - - - -Declaring the PEAR2\Net\RouterOS as an aliased namespace - -<?php -use PEAR2\Net\RouterOS as Ros; -include_once 'PEAR2/Net/RouterOS/Autoload.php'; -$client = new Ros\Client('example.com', 'admin'); -// Use the client here -?> - - - -Declaring an alias of each class you intend to use directly. - -<?php -use PEAR2\Net\RouterOS\Client as Ros; -include_once 'PEAR2/Net/RouterOS/Autoload.php'; -$client = new Ros('example.com', 'admin'); -// Use the client here -?> - - - - -Note that namespace declarations must appear before any includes. -They must in fact be the first thing in a PHP file. The rest of the examples in this documentation will be setting \PEAR2\Net\RouterOS as the default namespace. - - - - Further information. - -Net_RouterOS is flexible in the code patterns it allows you to use, but using the -{@link Client} class with {@link Client::sendSync()} is the reccomended approach for simple scenarios. See {@tutorial Client.cls the tutorial for the Client class} for description of this and other ways to use PEAR2_Net_RouterOS. - - - \ No newline at end of file diff --git a/docs/tutorials/PEAR2_Net_RouterOS/Query.cls b/docs/tutorials/PEAR2_Net_RouterOS/Query.cls deleted file mode 100644 index 9e2190a..0000000 --- a/docs/tutorials/PEAR2_Net_RouterOS/Query.cls +++ /dev/null @@ -1,80 +0,0 @@ - - - - Using queries - A brief guide to using queries - - - Vasil Rangelov - - {@link mailto:boen.robot@gmail.com boen.robot@gmail.com} - - - - {@toc} - - Commands handling queries - -Queries are a RouterOS API specific construct that allows you to limit the results returned for a request. - - -Currently, the "print" command is the only one that handles queries, since version 3.21. PEAR2_Net_RouterOS doesn't check whether the command handles queries, so if future versions of RouterOS have other such commands, you can use queries with them right away. - - - - Setting a query - -To set a query for a request, you need to use the {@link Request::setQuery()} method. If later in the script you want to remove the query, you can pass NULL to it. The rest of the examples in this tutorial will assume a script similar to the following, where the $query variable is defined separately: - - -<?php -namespace PEAR2\Net\RouterOS; -include_once 'PEAR2/Net/RouterOS/autoload.php'; -$client = new Client('192.168.0.1', 'admin'); - -$request = new Request('/ip/arp/print'); - -//Define $query here - -$request->setQuery($query); -$responses = $client->sendSync($request); - -foreach($responses as $response) { - foreach($response->getAllArguments() as $name => $value) { - echo "{$name}: {$value}\n"; - } - echo "====\n"; -} -?> - - - - A simple query - -You can create a query by calling the static {@link Query::where()} method, along with the first criteria of the query. For example, if you wanted to limit results to the entry about 192.168.0.100, you can use a query like: - - $query = Query::where('address', '192.168.0.100'); - -Using the optional third parameter, you can specify exactly what do you want to do with the value. Possible values are the Query::ACTION_* constants. For example, if you wanted to get all addresses greather than 192.168.0.100, you can use: - - $query = Query::where('address', '192.168.0.100', Query::ACTION_GREATHER_THAN); - - - Chaining conditions - -The {@link Query} class uses a "fluent" interface, i.e. it always returns the query object itself, similarly to how {@link http://jquery.com jQuery} and {@link http://framework.zend.com/manual/en/zend.db.select.html Zend_Db_Select} do it. Thanks to that, you can chain conditions right when defining the $query variable (though you can also alter it later). For example, if you wanted to get all addresses greather than or equal to 192.168.0.100, you can do: - - $query = Query::where('address', '192.168.0.100', Query::ACTION_GREATHER_THAN)->orWhere('address', '192.168.0.100'); - - - Limiting returned properties - - The query works a little like the "WHERE" clause in an SQL statement - it limits the amount of responses returned (which can be thought of as a "record" in DB terms) - but it doesn't limit the arguments of each response (which can be thought of as "fields" in DB terms, and are often reffered to as "properties" in the RouterOS documentation). - - To do that, you need to set an API specific argument called ".proplist". The value is a comma separated list of arguments to be listed in the responses. For example, if you were only interested in the MAC addresses, you can do: - - $request->setArgument('.proplist', 'mac-address'); - or if you wanted MAC addresses and comments - $request->setArgument('.proplist', 'mac-address,comment'); - - \ No newline at end of file diff --git a/examples/send-and-forget.php b/examples/send-and-forget.php index 88b62b3..f96f7ca 100644 --- a/examples/send-and-forget.php +++ b/examples/send-and-forget.php @@ -16,3 +16,5 @@ $addRequest->setArgument('mac-address', '00:00:00:00:00:02'); $addRequest->setTag('arp2'); $client->sendAsync($addRequest); + +$client->loop(); diff --git a/extrasetup.php b/extrasetup.php index 7b073c5..d2b8910 100644 --- a/extrasetup.php +++ b/extrasetup.php @@ -12,6 +12,7 @@ new RecursiveDirectoryIterator( $pkg, RecursiveDirectoryIterator::UNIX_PATHS + | RecursiveDirectoryIterator::SKIP_DOTS ), RecursiveIteratorIterator::LEAVES_ONLY ) as $path diff --git a/package.xml b/package.xml index 0afb535..5033175 100644 --- a/package.xml +++ b/package.xml @@ -11,10 +11,10 @@ boen.robot@gmail.com yes - 2012-08-03 - + 2013-08-15 + - 1.0.0b3 + 1.0.0b4 1.0.0 @@ -22,29 +22,27 @@ stable LGPL License 2.1 - Bug fixes on edge cases, and some API changes + Brand new way of manipulating data, encryption, and listen... -* (GH #6) Persistent connections are now properly supported. Added a new Registry class to facilitate this. -* The second and third argument of Request::__construct() have been swapped. -* At Request::__construct(), a backslash can now be escaped in an argument value, and arguments can be spread across multiple lines. -* Client::getStreamResponses() and Client::setStreamResponses() are now Client::isStreamingResponses() and Client::setStreamingResponses(), respectively. -* Query now uses things statically, allowing extensions in the process. -* ResponseCollection::__invoke() now seeks instead of getting. -* (GH #4) Client::completeRequest() now works with requests that use a callback. -* Client::sendSync() now accepts requests with a tag. -* Added support for non ASCII passwords. -* Client now throws this package's SocketException on connection errors. The originating Transmitter exception is available in the trace. -* Documentation fixes. +* A new Util class that abstracts away tons of fancy features, including: + - CRUD operations + - Support of targeting and finding entries by numbers, just like from terminal + - Executing scripts (with the ability to pass typed parameters ala SQL prepared statements) + - Putting and getting files out of RouterOS + - Helper methods for converting back and forth between PHP and RouterOS values. +* Support for encrypted connections, both with and without a certificate. Note that due to known issues with PHP itself, encrypted connections may be unstable (as in "sometimes disconnect suddenly" or "sometimes hang when you use Client::sendSync() and/or Client::completeRequest() and/or Client::loop() without a timeout"). +* Client::loop() and Client::completeRequest() no longer fail if there's no reply within "default_socket_timeout" seconds. This means you can now use the "listen" command without also setting up something else to keep the connection busy. +* Client::loop() now accepts timeouts modeled after stream_select()'s, as opposed to a single float value. As before, the default is "no time limit", but is now specified with NULL instead of 0. Analogous arguments have been added to Response's constructor. +* When receiving, the release lock is released when ANY exception is thrown. Previously, this would be so only in case of SocketException. +* Chnaged the PHAR stub to not fail when reading the hash fails. +* Exceptions now use constants to hold each code. +* Doc and CS fixes, and unit test reorganization. - - - - - - - + + + @@ -140,21 +138,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + - - @@ -169,7 +225,7 @@ PEAR2_Net_Transmitter pear2.php.net - 1.0.0a3 + 1.0.0a4 PCRE @@ -184,7 +240,7 @@ PEAR2_Cache_SHM pear2.php.net - 0.1.0 + 0.1.2 iconv @@ -193,32 +249,63 @@ + - - - + + + + + + - + + + - - + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + diff --git a/packagexmlsetup.php b/packagexmlsetup.php index 912dc72..5ad6d85 100644 --- a/packagexmlsetup.php +++ b/packagexmlsetup.php @@ -1,69 +1,38 @@ array( - array( - 'attribs' => array( - 'from' => '../src', - 'to' => 'php_dir', - 'type' => 'pear-config' - ) - ) - ) -); - -$srcFileTasks = array( - 'tasks:replace' => array( - array( - 'attribs' => array( - 'from' => '~~summary~~', - 'to' => 'summary', - 'type' => 'package-info' - ) - ), - array( - 'attribs' => array( - 'from' => '~~description~~', - 'to' => 'description', - 'type' => 'package-info' - ) - ), - array( - 'attribs' => array( - 'from' => 'GIT: $Id$', - 'to' => 'version', - 'type' => 'package-info' - ) - ) - ) -); - -$package->files['tests/bootstrap.php'] = array_merge_recursive( - $package->files['tests/bootstrap.php']->getArrayCopy(), - $srcDirTask, - array( +$packageGen = function ( + v2 $package, + v2 $compatible = null +) { + $srcDirTask = array( 'tasks:replace' => array( array( 'attribs' => array( - 'from' => '../../PEAR2_Net_Transmitter.git/src/', + 'from' => '../src', 'to' => 'php_dir', 'type' => 'pear-config' ) ) ) - ) -); + ); -$package->files['docs/phpdoc.dist.xml'] = array_merge_recursive( - $package->files['docs/phpdoc.dist.xml']->getArrayCopy(), - $srcDirTask -); - -$package->files['docs/doxygen.ini'] = array_merge_recursive( - $package->files['docs/doxygen.ini']->getArrayCopy(), - $srcDirTask, - array( + $srcFileTasks = array( 'tasks:replace' => array( + array( + 'attribs' => array( + 'from' => '~~summary~~', + 'to' => 'summary', + 'type' => 'package-info' + ) + ), + array( + 'attribs' => array( + 'from' => '~~description~~', + 'to' => 'description', + 'type' => 'package-info' + ) + ), array( 'attribs' => array( 'from' => 'GIT: $Id$', @@ -72,72 +41,153 @@ ) ) ) - ) -); -$hasCompatible = isset($compatible); -if ($hasCompatible) { - $compatible->license = $package->license; - $compatible->files[ - "test/{$package->channel}/{$package->name}/bootstrap.php" - ] = array_merge_recursive( - $compatible->files[ + ); + + $package->files['tests/bootstrap.php'] = array_merge_recursive( + $package->files['tests/bootstrap.php']->getArrayCopy(), + $srcDirTask, + array( + 'tasks:replace' => array( + array( + 'attribs' => array( + 'from' => '../../PEAR2_Net_Transmitter.git/src/', + 'to' => 'php_dir', + 'type' => 'pear-config' + ) + ) + ) + ) + ); + + $package->files['docs/phpdoc.dist.xml'] = array_merge_recursive( + $package->files['docs/phpdoc.dist.xml']->getArrayCopy(), + $srcDirTask + ); + $package->files['docs/apigen.neon'] = array_merge_recursive( + $package->files['docs/apigen.neon']->getArrayCopy(), + $srcDirTask + ); + + $package->files['docs/doxygen.ini'] = array_merge_recursive( + $package->files['docs/doxygen.ini']->getArrayCopy(), + $srcDirTask, + array( + 'tasks:replace' => array( + array( + 'attribs' => array( + 'from' => 'GIT: $Id$', + 'to' => 'version', + 'type' => 'package-info' + ) + ) + ) + ) + ); + $hasCompatible = null !== $compatible; + if ($hasCompatible) { + $compatible->license = $package->license; + $compatible->files[ "test/{$package->channel}/{$package->name}/bootstrap.php" - ]->getArrayCopy(), - $srcDirTask - ); + ] = array_merge_recursive( + $compatible->files[ + "test/{$package->channel}/{$package->name}/bootstrap.php" + ]->getArrayCopy(), + $srcDirTask, + array( + 'tasks:replace' => array( + array( + 'attribs' => array( + 'from' => '../../PEAR2_Net_Transmitter.git/src/', + 'to' => 'php_dir', + 'type' => 'pear-config' + ) + ) + ) + ) + ); - $compatible->files[ - "doc/{$package->channel}/{$package->name}/phpdoc.dist.xml" - ] = array_merge_recursive( - $compatible->files[ + $compatible->files[ "doc/{$package->channel}/{$package->name}/phpdoc.dist.xml" - ]->getArrayCopy(), - $srcDirTask - ); + ] = array_merge_recursive( + $compatible->files[ + "doc/{$package->channel}/{$package->name}/phpdoc.dist.xml" + ]->getArrayCopy(), + $srcDirTask + ); - $compatible->files["doc/{$package->channel}/{$package->name}/doxygen.ini"] - = array_merge_recursive( - $compatible->files[ - "doc/{$package->channel}/{$package->name}/doxygen.ini" - ]->getArrayCopy(), - $srcDirTask, - array( - 'tasks:replace' => array( - array( - 'attribs' => array( - 'from' => 'GIT: $Id$', - 'to' => 'version', - 'type' => 'package-info' + $compatible->files["doc/{$package->channel}/{$package->name}/doxygen.ini"] + = array_merge_recursive( + $compatible->files[ + "doc/{$package->channel}/{$package->name}/doxygen.ini" + ]->getArrayCopy(), + $srcDirTask, + array( + 'tasks:replace' => array( + array( + 'attribs' => array( + 'from' => 'GIT: $Id$', + 'to' => 'version', + 'type' => 'package-info' + ) ) ) ) - ) - ); -} + ); + } -$oldCwd = getcwd(); -chdir(__DIR__); -foreach ( - new RecursiveIteratorIterator( - new RecursiveDirectoryIterator( - 'src', - RecursiveDirectoryIterator::UNIX_PATHS - ), - RecursiveIteratorIterator::LEAVES_ONLY - ) as $path) { - $filename = $path->getPathname(); - - $package->files[$filename] = array_merge_recursive( - $package->files[$filename]->getArrayCopy(), - $srcFileTasks - ); - - if ($hasCompatible) { - $compatibleFilename = str_replace('src/', 'php/', $filename); - $compatible->files[$compatibleFilename] = array_merge_recursive( - $compatible->files[$compatibleFilename]->getArrayCopy(), - $srcFileTasks - ); + $oldCwd = getcwd(); + chdir(__DIR__); + foreach ( + new RecursiveIteratorIterator( + new RecursiveDirectoryIterator( + 'src', + RecursiveDirectoryIterator::UNIX_PATHS + | RecursiveDirectoryIterator::SKIP_DOTS + ), + RecursiveIteratorIterator::LEAVES_ONLY + ) as $path) { + $filename = $path->getPathname(); + + $package->files[$filename] = array_merge_recursive( + $package->files[$filename]->getArrayCopy(), + $srcFileTasks + ); + + if ($hasCompatible) { + $compatibleFilename = str_replace('src/', 'php/', $filename); + $compatible->files[$compatibleFilename] = array_merge_recursive( + $compatible->files[$compatibleFilename]->getArrayCopy(), + $srcFileTasks + ); + } + } + + foreach ( + new RecursiveIteratorIterator( + new RecursiveDirectoryIterator( + '.', + RecursiveDirectoryIterator::UNIX_PATHS + | RecursiveDirectoryIterator::SKIP_DOTS + ), + RecursiveIteratorIterator::LEAVES_ONLY + ) as $path) { + $filename = substr($path->getPathname(), 2); + + if (isset($package->files[$filename])) { + $as = (strpos($filename, 'examples') === 0) + ? $filename + : substr($filename, strpos($filename, '/') + 1); + $package->getReleaseToInstall('php')->installAs($filename, $as); + } } + chdir($oldCwd); + return array($package, $compatible); +}; + +list($package, $compatible) = $packageGen( + $package, + isset($compatible) ? $compatible : null +); +if (null === $compatible) { + unset($compatible); } -chdir($oldCwd); diff --git a/stub.php b/stub.php index 610b6a1..2fcdf90 100644 --- a/stub.php +++ b/stub.php @@ -10,12 +10,12 @@ header('Content-Type: text/plain;charset=UTF-8'); } echo "@PACKAGE_NAME@ @PACKAGE_VERSION@\n"; - + if (version_compare(phpversion(), '5.3.0', '<')) { echo "\nThis package requires PHP 5.3.0 or later."; exit(1); } - + $missing_extensions = array(); foreach (array('phar', 'spl', 'pcre') as $ext) { if (!extension_loaded($ext)) { @@ -28,71 +28,73 @@ "or install the necessary extensions for your distribution.\n"; exit(1); } - + if (extension_loaded('phar')) { try { $phar = new Phar(__FILE__); $sig = $phar->getSignature(); - echo "{$sig['hash_type']} hash: {$sig['hash']}\n\n"; + echo "{$sig['hash_type']} hash: {$sig['hash']}\n"; } catch (Exception $e) { echo <<