Added third-party dependency theseer\Autoload

Added third-party dependency theseer\DirectoryScanner
Added warning if one or more components failed to load
Added more error-handling to autoload.php
Updated autoload.php
Updated .gitignore
Updated Makefile
Fixed namepsaces and added requirement theseer\DirectoryScanner for theseer\Autoload
Updated version.json
This commit is contained in:
Netkas 2022-09-22 16:47:23 -04:00
parent a1ce77a455
commit 2b5c2b6829
47 changed files with 4599 additions and 67 deletions

2
.gitignore vendored
View file

@ -12,5 +12,7 @@ src/ncc/ThirdParty/Symfony/Process/autoload_spl.php
src/ncc/ThirdParty/Symfony/Uid/autoload_spl.php
src/ncc/ThirdParty/Symfony/Filesystem/autoload_spl.php
src/ncc/ThirdParty/Symfony/Yaml/autoload_spl.php
src/ncc/ThirdParty/theseer/Autoload/autoload_spl.php
src/ncc/ThirdParty/theseer/DirectoryScanner/autoload_spl.php
src/ncc/autoload_spl.php
src/ncc/autoload.php

69
LICENSE
View file

@ -202,3 +202,72 @@ 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.
------------------------
theseer - Autoload
Autoload Builder
Copyright (c) 2010-2016 Arne Blankerts <arne@blankerts.de> and Contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of Arne Blankerts nor the names of contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
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 HOLDER ORCONTRIBUTORS
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.
------------------------
theseer - DirectoryScanner
DirectoryScanner
Copyright (c) 2009-2014 Arne Blankerts <arne@blankerts.de>
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of Arne Blankerts nor the names of contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
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 HOLDER ORCONTRIBUTORS
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.

144
Makefile
View file

@ -1,83 +1,97 @@
PHPCC=/usr/bin/php
$(PHPAB)=$(PHPAB)
PHPAB=/usr/bin/phpab
BUILD_PATH=build
SRC_PATH=src
autoload:
# Generates/creates all the autoloader files
make src/ncc/ThirdParty/defuse/php-encryption/autoload_spl.php
make src/ncc/ThirdParty/Symfony/polyfill-ctype/autoload_spl.php
make src/ncc/ThirdParty/Symfony/polyfill-mbstring/autoload_spl.php
make src/ncc/ThirdParty/Symfony/Process/autoload_spl.php
make src/ncc/ThirdParty/Symfony/Uid/autoload_spl.php
make src/ncc/ThirdParty/Symfony/Filesystem/autoload_spl.php
make src/ncc/ThirdParty/Symfony/Yaml/autoload_spl.php
make src/ncc/autoload_spl.php
cp src/autoload/autoload.php src/ncc/autoload.php
make $(SRC_PATH)/ncc/ThirdParty/defuse/php-encryption/autoload_spl.php
make $(SRC_PATH)/ncc/ThirdParty/Symfony/polyfill-ctype/autoload_spl.php
make $(SRC_PATH)/ncc/ThirdParty/Symfony/polyfill-mbstring/autoload_spl.php
make $(SRC_PATH)/ncc/ThirdParty/Symfony/Process/autoload_spl.php
make $(SRC_PATH)/ncc/ThirdParty/Symfony/Uid/autoload_spl.php
make $(SRC_PATH)/ncc/ThirdParty/Symfony/Filesystem/autoload_spl.php
make $(SRC_PATH)/ncc/ThirdParty/Symfony/Yaml/autoload_spl.php
make $(SRC_PATH)/ncc/ThirdParty/theseer/Autoload/autoload_spl.php
make $(SRC_PATH)/ncc/ThirdParty/theseer/DirectoryScanner/autoload_spl.php
make $(SRC_PATH)/ncc/autoload_spl.php
cp $(SRC_PATH)/autoload/autoload.php $(SRC_PATH)/ncc/autoload.php
src/ncc/ThirdParty/defuse/php-encryption/autoload_spl.php:
$(PHPCC) $($(PHPAB)) --output src/ncc/ThirdParty/defuse/php-encryption/autoload_spl.php \
src/ncc/ThirdParty/defuse/php-encryption
$(SRC_PATH)/ncc/ThirdParty/defuse/php-encryption/autoload_spl.php:
$(PHPCC) $(PHPAB) --output $(SRC_PATH)/ncc/ThirdParty/defuse/php-encryption/autoload_spl.php \
$(SRC_PATH)/ncc/ThirdParty/defuse/php-encryption
src/ncc/ThirdParty/Symfony/polyfill-ctype/autoload_spl.php:
$(PHPCC) $(PHPAB) --output src/ncc/ThirdParty/Symfony/polyfill-ctype/autoload_spl.php \
src/ncc/ThirdParty/Symfony/polyfill-ctype
$(SRC_PATH)/ncc/ThirdParty/Symfony/polyfill-ctype/autoload_spl.php:
$(PHPCC) $(PHPAB) --output $(SRC_PATH)/ncc/ThirdParty/Symfony/polyfill-ctype/autoload_spl.php \
$(SRC_PATH)/ncc/ThirdParty/Symfony/polyfill-ctype
src/ncc/ThirdParty/Symfony/polyfill-mbstring/autoload_spl.php:
$(PHPCC) $(PHPAB) --output src/ncc/ThirdParty/Symfony/polyfill-mbstring/autoload_spl.php \
src/ncc/ThirdParty/Symfony/polyfill-mbstring
$(SRC_PATH)/ncc/ThirdParty/Symfony/polyfill-mbstring/autoload_spl.php:
$(PHPCC) $(PHPAB) --output $(SRC_PATH)/ncc/ThirdParty/Symfony/polyfill-mbstring/autoload_spl.php \
$(SRC_PATH)/ncc/ThirdParty/Symfony/polyfill-mbstring
src/ncc/ThirdParty/Symfony/Process/autoload_spl.php:
$(PHPCC) $(PHPAB) --output src/ncc/ThirdParty/Symfony/Process/autoload_spl.php \
src/ncc/ThirdParty/Symfony/Process
$(SRC_PATH)/ncc/ThirdParty/Symfony/Process/autoload_spl.php:
$(PHPCC) $(PHPAB) --output $(SRC_PATH)/ncc/ThirdParty/Symfony/Process/autoload_spl.php \
$(SRC_PATH)/ncc/ThirdParty/Symfony/Process
src/ncc/ThirdParty/Symfony/Uid/autoload_spl.php:
$(PHPAB) --output src/ncc/ThirdParty/Symfony/Uid/autoload_spl.php \
src/ncc/ThirdParty/Symfony/Uid
$(SRC_PATH)/ncc/ThirdParty/Symfony/Uid/autoload_spl.php:
$(PHPAB) --output $(SRC_PATH)/ncc/ThirdParty/Symfony/Uid/autoload_spl.php \
$(SRC_PATH)/ncc/ThirdParty/Symfony/Uid
src/ncc/ThirdParty/Symfony/Filesystem/autoload_spl.php:
$(PHPCC) $(PHPAB) --output src/ncc/ThirdParty/Symfony/Filesystem/autoload_spl.php \
src/ncc/ThirdParty/Symfony/Filesystem
$(SRC_PATH)/ncc/ThirdParty/Symfony/Filesystem/autoload_spl.php:
$(PHPCC) $(PHPAB) --output $(SRC_PATH)/ncc/ThirdParty/Symfony/Filesystem/autoload_spl.php \
$(SRC_PATH)/ncc/ThirdParty/Symfony/Filesystem
src/ncc/ThirdParty/Symfony/Yaml/autoload_spl.php:
$(PHPCC) $(PHPAB) --output src/ncc/ThirdParty/Symfony/Yaml/autoload_spl.php \
src/ncc/ThirdParty/Symfony/Yaml
$(SRC_PATH)/ncc/ThirdParty/Symfony/Yaml/autoload_spl.php:
$(PHPCC) $(PHPAB) --output $(SRC_PATH)/ncc/ThirdParty/Symfony/Yaml/autoload_spl.php \
$(SRC_PATH)/ncc/ThirdParty/Symfony/Yaml
src/ncc/autoload_spl.php:
$(PHPCC) $(PHPAB) --output src/ncc/autoload_spl.php \
src/ncc/Abstracts \
src/ncc/Classes \
src/ncc/CLI \
src/ncc/Exceptions \
src/ncc/Extensions \
src/ncc/Managers \
src/ncc/Objects \
src/ncc/Runtime \
src/ncc/Utilities \
src/ncc/ncc.php
$(SRC_PATH)/ncc/ThirdParty/theseer/Autoload/autoload_spl.php:
$(PHPCC) $(PHPAB) --output $(SRC_PATH)/ncc/ThirdParty/theseer/Autoload/autoload_spl.php \
$(SRC_PATH)/ncc/ThirdParty/theseer/Autoload
$(SRC_PATH)/ncc/ThirdParty/theseer/DirectoryScanner/autoload_spl.php:
$(PHPCC) $(PHPAB) --output $(SRC_PATH)/ncc/ThirdParty/theseer/DirectoryScanner/autoload_spl.php \
$(SRC_PATH)/ncc/ThirdParty/theseer/DirectoryScanner
$(SRC_PATH)/ncc/autoload_spl.php:
$(PHPCC) $(PHPAB) --output $(SRC_PATH)/ncc/autoload_spl.php \
$(SRC_PATH)/ncc/Abstracts \
$(SRC_PATH)/ncc/Classes \
$(SRC_PATH)/ncc/CLI \
$(SRC_PATH)/ncc/Exceptions \
$(SRC_PATH)/ncc/Extensions \
$(SRC_PATH)/ncc/Managers \
$(SRC_PATH)/ncc/Objects \
$(SRC_PATH)/ncc/Runtime \
$(SRC_PATH)/ncc/Utilities \
$(SRC_PATH)/ncc/ncc.php
redist: autoload
rm -rf build/src
mkdir -p build/src
cp -rf src/ncc/* build/src
cp src/installer/installer build/src/INSTALL
cp src/installer/ncc.sh build/src/ncc.sh
cp src/config/ncc.yaml build/src/default_config.yaml;
cp src/installer/extension build/src/extension
chmod +x build/src/INSTALL
cp LICENSE build/src/LICENSE
cp README.md build/src/README.md
cp src/installer/hash_check.php build/src/hash_check.php; $(PHPCC) php build/src/hash_check.php; rm build/src/hash_check.php
cp src/installer/generate_build_files.php build/src/generate_build_files.php; $(PHPCC) php build/src/generate_build_files.php; rm build/src/generate_build_files.php
rm -rf $(BUILD_PATH)/src
mkdir -p $(BUILD_PATH)/src
cp -rf $(SRC_PATH)/ncc/* $(BUILD_PATH)/src
cp $(SRC_PATH)/installer/installer $(BUILD_PATH)/$(SRC_PATH)/INSTALL
cp $(SRC_PATH)/installer/ncc.sh $(BUILD_PATH)/$(SRC_PATH)/ncc.sh
cp $(SRC_PATH)/config/ncc.yaml $(BUILD_PATH)/$(SRC_PATH)/default_config.yaml;
cp $(SRC_PATH)/installer/extension $(BUILD_PATH)/$(SRC_PATH)/extension
chmod +x $(BUILD_PATH)/$(SRC_PATH)/INSTALL
cp LICENSE $(BUILD_PATH)/$(SRC_PATH)/LICENSE
cp README.md $(BUILD_PATH)/$(SRC_PATH)/README.md
cp $(SRC_PATH)/installer/hash_check.php $(BUILD_PATH)/$(SRC_PATH)/hash_check.php; $(PHPCC) $(BUILD_PATH)/$(SRC_PATH)/hash_check.php; rm $(BUILD_PATH)/$(SRC_PATH)/hash_check.php
cp $(SRC_PATH)/installer/generate_build_files.php $(BUILD_PATH)/$(SRC_PATH)/generate_build_files.php; $(PHPCC) $(BUILD_PATH)/$(SRC_PATH)/generate_build_files.php; rm $(BUILD_PATH)/$(SRC_PATH)/generate_build_files.php
tar: redist
cd build/src; tar -czvf ../ncc.tar.gz *
cd $(BUILD_PATH)/src; tar -czvf ../ncc.tar.gz *
clean:
rm -rf build
rm -f src/ncc/autoload_spl.php
rm -f src/ncc/ThirdParty/defuse/php-encryption/autoload_spl.php
rm -f src/ncc/ThirdParty/Symfony/polyfill-ctype/autoload_spl.php
rm -f src/ncc/ThirdParty/Symfony/polyfill-mbstring/autoload_spl.php
rm -f src/ncc/ThirdParty/Symfony/Process/autoload_spl.php
rm -f src/ncc/ThirdParty/Symfony/Uid/autoload_spl.php
rm -f src/ncc/ThirdParty/Symfony/Filesystem/autoload_spl.php
rm -f src/ncc/ThirdParty/Symfony/Yaml/autoload_spl.php
rm -rf $(BUILD_PATH)
rm -f $(SRC_PATH)/ncc/autoload_spl.php
rm -f $(SRC_PATH)/ncc/ThirdParty/defuse/php-encryption/autoload_spl.php
rm -f $(SRC_PATH)/ncc/ThirdParty/Symfony/polyfill-ctype/autoload_spl.php
rm -f $(SRC_PATH)/ncc/ThirdParty/Symfony/polyfill-mbstring/autoload_spl.php
rm -f $(SRC_PATH)/ncc/ThirdParty/Symfony/Process/autoload_spl.php
rm -f $(SRC_PATH)/ncc/ThirdParty/Symfony/Uid/autoload_spl.php
rm -f $(SRC_PATH)/ncc/ThirdParty/Symfony/Filesystem/autoload_spl.php
rm -f $(SRC_PATH)/ncc/ThirdParty/Symfony/Yaml/autoload_spl.php
rm -f $(SRC_PATH)/ncc/ThirdParty/theseer/Autoload/autoload_spl.php
rm -f $(SRC_PATH)/ncc/ThirdParty/theseer/DirectoryScanner/autoload_spl.php

View file

@ -8,7 +8,7 @@
* before proceeding to improve performance.
*/
if(defined('NCC_INIT') == false)
if(!defined('NCC_INIT'))
{
$third_party_path = __DIR__ . DIRECTORY_SEPARATOR . 'ThirdParty' . DIRECTORY_SEPARATOR;
$target_files = [
@ -22,14 +22,29 @@
$third_party_path . 'Symfony' . DIRECTORY_SEPARATOR . 'Uid' . DIRECTORY_SEPARATOR . 'autoload_spl.php',
$third_party_path . 'Symfony' . DIRECTORY_SEPARATOR . 'Filesystem' . DIRECTORY_SEPARATOR . 'autoload_spl.php',
$third_party_path . 'Symfony' . DIRECTORY_SEPARATOR . 'Yaml' . DIRECTORY_SEPARATOR . 'autoload_spl.php',
$third_party_path . 'theseer' . DIRECTORY_SEPARATOR . 'Autoload' . DIRECTORY_SEPARATOR . 'autoload_spl.php',
$third_party_path . 'theseer' . DIRECTORY_SEPARATOR . 'DirectoryScanner' . DIRECTORY_SEPARATOR . 'autoload_spl.php',
];
$init_success = true;
foreach($target_files as $file)
{
if(!file_exists($file))
{
trigger_error('Cannot find file ' . $file, E_USER_WARNING);
$init_success = false;
continue;
}
require_once($file);
}
if(\ncc\ncc::initialize() == false)
if(!$init_success)
{
trigger_error('One or more NCC components are missing/failed to load, NCC runtime may not be stable.', E_USER_WARNING);
}
if(!\ncc\ncc::initialize())
{
trigger_error('NCC Failed to initialize', E_USER_WARNING);
}

View file

@ -0,0 +1,26 @@
<?php
namespace ncc\Classes;
use ncc\Objects\ProjectConfiguration;
class AutoloaderGenerator
{
/**
* @var ProjectConfiguration
*/
private ProjectConfiguration $project;
/**
* @param ProjectConfiguration $project
*/
public function __construct(ProjectConfiguration $project)
{
$this->project = $project;
}
public function generateAutoload(string $src, string $output, bool $static=false)
{
}
}

View file

@ -0,0 +1,247 @@
<?php
/**
* Copyright (c) 2009-2019 Arne Blankerts <arne@blankerts.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of Arne Blankerts nor the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* 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 HOLDER ORCONTRIBUTORS
* 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.
*
* @package Autoload
* @author Arne Blankerts <arne@blankerts.de>
* @copyright Arne Blankerts <arne@blankerts.de>, All rights reserved.
* @license BSD License
*
*/
namespace ncc\ThirdParty\theseer\Autoload {
class Application {
private $logger;
private $factory;
private $config;
public function __construct(Logger $logger, Config $config, Factory $factory) {
$this->logger = $logger;
$this->config = $config;
$this->factory = $factory;
}
public function run() {
$result = $this->runCollector();
if (!$result->hasUnits()) {
throw new ApplicationException('No units were found - process aborted.', ApplicationException::NoUnitsFound);
}
if ($result->hasDuplicates()) {
return $this->showDuplicatesError($result->getDuplicates());
}
if ($this->config->isCacheEnabled()) {
$this->factory->getCache()->persist($this->config->getCacheFile());
}
$template = @file_get_contents($this->config->getTemplate());
if ($template === false) {
throw new ApplicationException("Failed to read the template file.");
}
$builder = $this->factory->getRenderer($result);
$code = $builder->render($template);
if ($this->config->isLintMode()) {
return $this->runLint($code);
}
return $this->runSaver($code);
}
/**
* @return CollectorResult
*/
private function runCollector() {
if ($this->config->isFollowSymlinks()) {
$this->logger->log('Following symbolic links is enabled.' . "\n\n");
}
$collector = $this->factory->getCollector();
foreach ($this->config->getDirectories() as $directory) {
if (is_dir($directory)) {
$this->logger->log('Scanning directory ' . $directory . "\n");
$scanner = $this->factory->getScanner()->getIterator($directory);
$collector->processDirectory($scanner);
// this unset is needed to "fix" a segfault on shutdown in some PHP Versions
unset($scanner);
} else {
$file = new \SplFileInfo($directory);
$filter = $this->factory->getFilter(new \ArrayIterator(array($file)));
foreach($filter as $file) {
$this->logger->log('Scanning file ' . $file . "\n");
$collector->processFile($file);
}
}
}
return $collector->getResult();
}
private function runSaver($code) {
$output = $this->config->getOutputFile();
if (!$this->config->isPharMode()) {
if ($output === 'STDOUT') {
$this->logger->log("\n");
echo $code;
$this->logger->log("\n\n");
return CLI::RC_OK;
}
// @codingStandardsIgnoreStart
$written = @file_put_contents($output, $code);
// @codingStandardsIgnoreEnd
if ($written != strlen($code)) {
$this->logger->log("Writing to file '$output' failed.", STDERR);
return CLI::RC_EXEC_ERROR;
}
$this->logger->log("\nAutoload file {$output} generated.\n\n");
return CLI::RC_OK;
}
if (strpos($code, '__HALT_COMPILER();') === FALSE) {
$this->logger->log(
"Warning: Template used in phar mode did not contain required __HALT_COMPILER() call\n" .
"which has been added automatically. The used stub code may not work as intended.\n\n", STDERR);
$code .= $this->config->getLinebreak() . '__HALT_COMPILER();';
}
$pharBuilder = $this->factory->getPharBuilder();
if ($keyfile = $this->config->getPharKey()) {
$pharBuilder->setSignatureKey($this->loadPharSignatureKey($keyfile));
}
if ($aliasName = $this->config->getPharAliasName()) {
$pharBuilder->setAliasName($aliasName);
}
if ($this->config->hasPharHashAlgorithm()) {
$pharBuilder->setSignatureType($this->config->getPharHashAlgorithm());
}
$pharBuilder->build($output, $code);
$this->logger->log("\nphar archive '{$output}' generated.\n\n");
return CLI::RC_OK;
}
private function loadPharSignatureKey($keyfile) {
if (!extension_loaded('openssl')) {
throw new ApplicationException('Extension for OpenSSL not loaded - cannot sign phar archive - process aborted.',
ApplicationException::OpenSSLError);
}
$keydata = file_get_contents($keyfile);
if (strpos($keydata, 'ENCRYPTED') !== FALSE) {
$this->logger->log("Passphrase for key '$keyfile': ");
$g = shell_exec('stty -g');
shell_exec('stty -echo');
$passphrase = trim(fgets(STDIN));
$this->logger->log("\n");
shell_exec('stty ' . $g);
$private = openssl_pkey_get_private($keydata, $passphrase);
} else {
$private = openssl_pkey_get_private($keydata);
}
if (!$private) {
throw new ApplicationException("Opening private key '$keyfile' failed - process aborted.\n\n", ApplicationException::OpenSSLError);
}
return $private;
}
/**
* Execute a lint check on generated code
*
* @param string $code Generated code to lint
*
* @return boolean
*/
protected function runLint($code) {
$dsp = array(
0 => array('pipe', 'r'),
1 => array('pipe', 'w'),
2 => array('pipe', 'w')
);
$binary = $this->config->getPhp();
$process = proc_open($binary . ' -l', $dsp, $pipes);
if (!is_resource($process)) {
$this->logger->log("Opening php binary for linting failed.\n", STDERR);
return 1;
}
fwrite($pipes[0], $code);
fclose($pipes[0]);
fclose($pipes[1]);
$stderr = stream_get_contents($pipes[2]);
fclose($pipes[2]);
$rc = proc_close($process);
if ($rc == 255) {
$this->logger->log("Syntax errors during lint:\n" .
str_replace('in - on line', 'in generated code on line', $stderr) .
"\n", STDERR);
return CLI::RC_LINT_ERROR;
}
$this->logger->log("Lint check of geneated code okay\n\n");
return CLI::RC_OK;
}
/**
* @param array $duplicates
*
* @return int
*/
private function showDuplicatesError(array $duplicates) {
$this->logger->log(
sprintf("\nMultiple declarations of trait(s), interface(s) or class(es). Could not generate autoload map.\n"),
STDERR
);
foreach($duplicates as $unit => $files) {
$this->logger->log(
sprintf("\nUnit '%s' defined in:\n", $unit),
STDERR
);
/** @var array $files */
foreach($files as $file) {
$this->logger->log(
sprintf(" - %s\n", $file),
STDERR
);
}
}
return CLI::RC_DUPLICATES_ERROR;
}
}
class ApplicationException extends \Exception {
const NoUnitsFound = 1;
const OpenSSLError = 2;
}
}

View file

@ -0,0 +1,297 @@
<?php
/**
* Copyright (c) 2009-2019 Arne Blankerts <arne@blankerts.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of Arne Blankerts nor the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* 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 HOLDER ORCONTRIBUTORS
* 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.
*
* @package Autoload
* @author Arne Blankerts <arne@blankerts.de>
* @copyright Arne Blankerts <arne@blankerts.de>, All rights reserved.
* @license BSD License
*/
namespace ncc\ThirdParty\theseer\Autoload {
/**
* Builds spl based autoload code for inclusion into projects
*
* @author Arne Blankerts <arne@blankerts.de>
* @copyright Arne Blankerts <arne@blankerts.de>, All rights reserved.
*/
class AutoloadRenderer {
/**
* Associative array of classes (key) and the files (value) they are in
*
* @var array
*/
protected $classes;
/**
* An optional base dir to strip for the realpath of the filename
*
* @var string
*/
protected $baseDir = '';
/**
* Indenting char(s)
*
* @var string
*/
protected $indent = ' ';
/**
* Char(s) used as linebreak
*
* @var string
*/
protected $linebreak = "\n";
/**
* Timestamp of production start
*
* @var integer
*/
protected $timestamp;
/**
* Format string supplied to date() for use with ___CREATED___
*
* @var string
*/
protected $dateformat = 'r';
/**
* Variables for templates
*
* @var array
*/
protected $variables = array();
/**
* Flag to toggle PHP 5.2 compat mode
*
* @var boolean
*/
protected $compat = false;
/**
* Flag to pass on to spl_autoload_register to prepend
*
* @var bool
*/
private $usePrepend = false;
/**
* Flag to pass on to spl_autoload_register to optionally throw exceptions on registration error
*
* @var bool
*/
private $throwExceptions = false;
/**
* Constructor of AutoloadRenderer class
*
* @param array $classlist Array of classes
*
*/
public function __construct(array $classlist) {
$this->classes = $classlist;
ksort($this->classes);
}
/**
* Toggle PHP 5.2 compat mode
*
* @param boolean $mode Mode to set compat to
*/
public function setCompat($mode) {
$this->compat = $mode;
}
public function enableExceptions() {
$this->throwExceptions = true;
}
public function prependAutoloader() {
$this->usePrepend = true;
}
/**
* Setter for the Basedir
*
* @param string $dir Path to strip from beginning of filenames
*
* @return void
*/
public function setBaseDir($dir) {
$this->baseDir = $dir;
}
/**
* Overwrite default or previously set indenting option
*
* @param string $indent Char(s) to use for indenting
*
* @return void
*/
public function setIndent($indent) {
$this->indent = $indent;
}
/**
* Overwrite default or previously set linebreak chars
*
* @param string $lbs Code to set linebreak
*
* @return void
*/
public function setLineBreak($lbs) {
$this->linebreak = $lbs;
}
/**
* Accessor for current linebreak setting
*
* @return string
*/
public function getLineBreak() {
return $this->linebreak;
}
/**
* Setter to use allow usage of fixed date/time for ___CREATED___
*
* @param integer $time unix timestamp
*
* @throws AutoloadBuilderException
*/
public function setTimestamp($time) {
if (!is_int($time) && null !== $time) {
throw new AutoloadBuilderException("'$time' is not a unix timestamp", AutoloadBuilderException::InvalidTimestamp);
}
$this->timestamp = $time;
}
/**
* Setter to adjust the date/time format output of ___CREATED___
*
* @param string $frmt Date/Time format string
*/
public function setDateTimeFormat($frmt) {
$this->dateformat = $frmt;
}
/**
* Set a variable for use with template code
*
* @param string $name Key name (use as ___key___ in template)
* @param string $value Value to use
*/
public function setVariable($name, $value) {
$this->variables['___'.$name.'___'] = $value;
}
/**
* Resolve relative location of file path to basedir if one is set and fix potential
* broken windows pathnames when run on windows.
*
* @param string $fname
*
* @return string
*/
protected function resolvePath($fname) {
if (empty($this->baseDir)) {
return str_replace('\\', '/', $fname);
}
$basedir = explode(DIRECTORY_SEPARATOR, $this->baseDir);
$filedir = explode(DIRECTORY_SEPARATOR, dirname(realpath($fname)));
$pos = 0;
$max = count($basedir);
while (isset($filedir[$pos]) && $filedir[$pos] == $basedir[$pos]) {
$pos++;
if ($pos == $max) {
break;
}
}
if ($pos == 0) {
return str_replace('\\', '/', $fname);
}
$rel = join('/', array_slice($filedir, $pos));
if (!empty($rel)) {
$rel .= '/';
}
if ($pos<count($basedir)) {
$rel = str_repeat('../', count($basedir)-$pos) . $rel;
}
return '/' . $rel . basename($fname);
}
/**
* Render autoload code into a string
*
* @param string $template
*
* @return string
*/
public function render($template) {
$entries = array();
foreach($this->classes as $class => $file) {
$fname = $this->resolvePath($file);
$entries[] = "'". addslashes($class). "' => '$fname'";
}
$baseDir = '';
if ($this->baseDir) {
$baseDir = $this->compat ? 'dirname(__FILE__) . ' : '__DIR__ . ';
}
$replace = array_merge($this->variables, array(
'___CREATED___' => date( $this->dateformat, $this->timestamp ? $this->timestamp : time()),
'___CLASSLIST___' => join( ',' . $this->linebreak . $this->indent, $entries),
'___BASEDIR___' => $baseDir,
'___AUTOLOAD___' => 'autoload' . md5(serialize($entries)),
'___EXCEPTION___' => $this->throwExceptions ? 'true' : 'false',
'___PREPEND___' => $this->usePrepend ? 'true' : 'false'
));
return str_replace(array_keys($replace), array_values($replace), $template);
}
}
class AutoloadBuilderException extends \Exception {
const TemplateNotFound = 1;
const InvalidTimestamp = 2;
}
}

View file

@ -0,0 +1,607 @@
<?php
/**
* Copyright (c) 2009-2019 Arne Blankerts <arne@blankerts.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of Arne Blankerts nor the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* 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 HOLDER ORCONTRIBUTORS
* 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.
*
* @package Autoload
* @author Arne Blankerts <arne@blankerts.de>
* @copyright Arne Blankerts <arne@blankerts.de>, All rights reserved.
* @license BSD License
*/
namespace ncc\ThirdParty\theseer\Autoload {
/**
* CLI interface to AutoloadRenderer / StaticRenderer
*
* @author Arne Blankerts <arne@blankerts.de>
* @copyright Arne Blankerts <arne@blankerts.de>, All rights reserved.
*/
class CLI {
const RC_OK = 0;
const RC_EXEC_ERROR = 1;
const RC_PARAM_ERROR = 3;
const RC_LINT_ERROR = 4;
const RC_DUPLICATES_ERROR = 5;
private $pharOption;
private $staticOption;
private $helpOption;
private $versionOption;
private $onceOption;
/**
* @var Factory
*/
private $factory;
public function __construct(Factory $factory) {
$this->factory = $factory;
}
/**
* Main executor method
*
* @return void
*/
public function run() {
try {
$this->preBootstrap();
$input = $this->setupInput();
$input->process();
if ($input->getOption('help')->value === TRUE) {
$this->showVersion();
$this->showUsage();
exit(CLI::RC_OK);
}
if ($input->getOption('version')->value === TRUE ) {
$this->showVersion();
exit(CLI::RC_OK);
}
$config = $this->configure($input);
$this->factory->setConfig($config);
if (!$config->isQuietMode()) {
$this->showVersion();
}
$rc = $this->factory->getApplication()->run();
exit($rc);
} catch (CLIEnvironmentException $e) {
$this->showVersion();
fwrite(STDERR, 'Sorry, but your PHP environment is currently not able to run phpab due to');
fwrite(STDERR, "\nthe following issue(s):\n\n" . $e->getMessage() . "\n\n");
fwrite(STDERR, "Please adjust your PHP configuration and try again.\n\n");
exit(CLI::RC_EXEC_ERROR);
} catch (\ezcConsoleException $e) {
$this->showVersion();
echo $e->getMessage() . "\n\n";
$this->showUsage();
exit(CLI::RC_PARAM_ERROR);
} catch (CollectorException $e) {
switch($e->getCode()) {
case CollectorException::InFileRedeclarationFound:
case CollectorException::RedeclarationFound:
case CollectorException::ParseErrror: {
$message = $e->getMessage();
break;
}
default: {
$message = 'Unexpected error in collector process: ' . $e->getMessage() . "\n\nPlease report this as a bug.\n\n";
}
}
$this->showVersion();
fwrite(STDERR, $message . "\n\n");
exit(CLI::RC_EXEC_ERROR);
} catch (\Exception $e) {
$this->showVersion();
fwrite(STDERR, "\nError while processing request:\n - " . $e->getMessage()."\n");
exit(CLI::RC_EXEC_ERROR);
}
}
/**
* @param \ezcConsoleInput $input
*
* @return \ncc\ThirdParty\theseer\Autoload\Config
*/
private function configure(\ezcConsoleInput $input) {
$config = new Config($input->getArguments());
if ($input->getOption('quiet')->value) {
$config->setQuietMode(TRUE);
}
if ($input->getOption('compat')->value) {
$config->setCompatMode(TRUE);
}
if ($input->getOption('tolerant')->value) {
$config->setTolerantMode(TRUE);
}
if ($output = $input->getOption('output')->value) {
$config->setOutputFile($output);
}
if ($input->getOption('phar')->value) {
$compression = \Phar::NONE;
if ($input->getOption('bzip2')->value === TRUE) {
$compression = \Phar::BZ2;
} else if ($input->getOption('gzip')->value === TRUE) {
$compression = \Phar::GZ;
}
$config->enablePharMode(
$compression,
$input->getOption('all')->value,
$input->getOption('key')->value,
$input->getOption('alias')->value
);
$config->setVariable('PHAR',
$input->getOption('alias')->value ? $input->getOption('alias')->value : basename($output)
);
if ($hashAlgorithm = $input->getOption('hash')->value) {
$config->setPharHashAlgorithm($hashAlgorithm);
}
}
if ($input->getOption('cache')->value) {
$config->setCacheFile($input->getOption('cache')->value);
}
if ($basedir = $input->getOption('basedir')->value) {
$config->setBaseDirectory($basedir);
}
$include = $input->getOption('include')->value;
if (!is_array($include)) {
$include = array($include);
}
$config->setInclude($include);
if ($exclude = $input->getOption('exclude')->value) {
if (!is_array($exclude)) {
$exclude = array($exclude);
}
$config->setExclude($exclude);
}
$whitelist = $input->getOption('whitelist')->value;
if (!is_array($whitelist)) {
$whitelist = array($whitelist);
}
$config->setWhitelist($whitelist);
if ($blacklist = $input->getOption('blacklist')->value) {
if (!is_array($blacklist)) {
$blacklist = array($blacklist);
}
$config->setBlacklist($blacklist);
}
if ($input->getOption('static')->value) {
$config->setStaticMode(TRUE);
}
if ($input->getOption('once')->value) {
$config->setOnceMode(TRUE);
}
if ($input->getOption('warm')->value) {
$config->setWarmMode(TRUE);
}
if ($input->getOption('reset')->value) {
$config->setResetMode(TRUE);
}
if ($input->getOption('follow')->value) {
$config->setFollowSymlinks(TRUE);
}
if ($input->getOption('prepend')->value) {
$config->enablePrepend();
}
if ($input->getOption('no-exception')->value) {
$config->disableExceptions();
}
$indent = $input->getOption('indent')->value;
if ($indent !== FALSE) {
$config->setIndent($indent);
}
if ($template = $input->getOption('template')->value) {
$config->setTemplate($template);
}
if ($linebreak = $input->getOption('linebreak')->value) {
$config->setLinebreak($linebreak);
}
if ($input->getOption('nolower')->value) {
$config->setLowercaseMode(FALSE);
}
if ($variables = $input->getOption('var')->value) {
foreach($variables as $var) {
if (strpos($var, '=')===FALSE) {
throw new \RuntimeException("Variable defintion '$var' is invalid and cannot be processed.");
}
list($name, $value) = explode('=', $var, 2);
$config->setVariable($name, $value);
}
}
if ($input->getOption('paranoid')->value || !$input->getOption('trusting')->value) {
$config->setTrusting(FALSE);
}
return $config;
}
/**
* Helper to output version information
*/
protected function showVersion() {
static $shown = false;
if (!$shown) {
$shown = true;
echo Version::getInfoString() . "\n\n";
}
}
/**
* Helper to output usage information
*/
protected function showUsage() {
print <<<EOF
Usage: phpab [switches] <directory1|file1|/path/to/composer.json> [...<directoryN|fileN>]
-i, --include File pattern to include (default: *.php)
-e, --exclude File pattern to exclude
--blacklist Blacklist classname or namespace (wildcards supported)
--whitelist Whitelist classname or namespace (wildcards supported)
-b, --basedir Basedir for filepaths
-t, --template Path to code template to use
-o, --output Output file for generated code (default: STDOUT)
-p, --phar Create a phar archive (requires -o )
--all Include all files in given directory when creating a phar
--alias Specify explicit internal phar alias filename (default: output filename)
--hash Force given hash algorithm (SHA-1, SHA-256 or SHA-512) (requires -p, conflicts with --key)
--bzip2 Compress phar archive using bzip2 (requires -p) (bzip2 required)
--gzip Compress phar archive using gzip (requires -p) (gzip required)
--key OpenSSL key file to use for signing phar archive (requires -p) (openssl required)
-c, --compat Generate PHP 5.2 compatible code
-s, --static Generate a static require file
-w, --warm Generate a static opcache warming file
--reset Add opcache reset call when generating opcache warming file
-1, --prepend Register as first autoloader (prepend to stack, default: append)
-d, --no-exception Do not throw exception on registration problem (default: throw exception)
-n, --nolower Do not lowercase classnames for case insensitivity
-q, --quiet Quiet mode, do not output any processing errors or information
--cache <file> Enable caching and set filename to use for cache storage
--follow Enables following symbolic links (not compatible with phar mode)
--format Dateformat string for timestamp
--linebreak Linebreak style (CR, CRLF or LF, default: LF)
--indent String used for indenting or number of spaces (default: 16 (compat 12) spaces)
--tolerant Ignore Class Redeclarations in the same file
--once Use require_once instead of require when creating a static require file
--trusting Do not check mimetype of files prior to parsing (default)
--paranoid Do check mimetype of files prior to parsing
--var name=foo Assign value 'foo' to variable 'name' to be used in (custom) templates
--lint Run lint on generated code and exit
--lint-php PHP binary to use for linting (default: /usr/bin/php or c:\php\php.exe)
-h, --help Prints this usage information
-v, --version Prints the version and exits
EOF;
}
/**
* @return \ezcConsoleInput
*/
protected function setupInput() {
$input = new \ezcConsoleInput();
$this->versionOption = $input->registerOption( new \ezcConsoleOption( 'v', 'version' ) );
$this->versionOption->shorthelp = 'Prints the version and exits';
$this->versionOption->isHelpOption = TRUE;
$this->helpOption = $input->registerOption( new \ezcConsoleOption( 'h', 'help' ) );
$this->helpOption->isHelpOption = TRUE;
$this->helpOption->shorthelp = 'Prints this usage information';
$input->registerOption( new \ezcConsoleOption(
'', 'cache', \ezcConsoleInput::TYPE_STRING, NULL, FALSE,
'Enable cache and set cache filename'
));
$this->outputOption = $input->registerOption( new \ezcConsoleOption(
'o', 'output', \ezcConsoleInput::TYPE_STRING, 'STDOUT', FALSE,
'Output file for generated code (default: STDOUT)'
));
$this->pharOption = $input->registerOption( new \ezcConsoleOption(
'p', 'phar', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
'Build a phar archive of directory contents',
NULL,
array( new \ezcConsoleOptionRule( $input->getOption( 'o' ) ) )
));
$input->registerOption( new \ezcConsoleOption(
'', 'all', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
'Add all files from src dir to phar',
NULL,
array( new \ezcConsoleOptionRule( $input->getOption( 'p' ) ) )
));
$input->registerOption( new \ezcConsoleOption(
'', 'alias', \ezcConsoleInput::TYPE_STRING, NULL, FALSE,
'Provide explicit internal alias filename for phar',
NULL,
array( new \ezcConsoleOptionRule( $input->getOption( 'p' ) ) )
));
$bzip2 = $input->registerOption( new \ezcConsoleOption(
'', 'bzip2', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
'Compress files phar with bzip2',
NULL,
array( new \ezcConsoleOptionRule( $input->getOption( 'p' ) ) )
));
$gzip = $input->registerOption( new \ezcConsoleOption(
'', 'gzip', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
'Compress files phar with gzip',
NULL,
array( new \ezcConsoleOptionRule( $input->getOption( 'p' ) ) ),
array( new \ezcConsoleOptionRule( $bzip2 ) )
));
$bzip2->addExclusion(new \ezcConsoleOptionRule($gzip));
$input->registerOption( new \ezcConsoleOption(
'', 'key', \ezcConsoleInput::TYPE_STRING, NULL, FALSE,
'Keyfile to use for signing phar archive',
NULL,
array( new \ezcConsoleOptionRule( $input->getOption( 'p' ) ) )
));
$this->outputOption = $input->registerOption( new \ezcConsoleOption(
'', 'hash', \ezcConsoleInput::TYPE_STRING, NULL, FALSE,
'Force given hash algorithm (SHA-1, SHA-256 or SHA-512) (requires -p)',
NULL,
array( new \ezcConsoleOptionRule( $input->getOption( 'p' ) ) ),
array( new \ezcConsoleOptionRule( $input->getOption( 'key' ) ) )
));
$input->registerOption( new \ezcConsoleOption(
'i', 'include', \ezcConsoleInput::TYPE_STRING, '*.php', TRUE,
'File pattern to include (default: *.php)'
));
$input->registerOption( new \ezcConsoleOption(
'', 'blacklist', \ezcConsoleInput::TYPE_STRING, NULL, TRUE,
'Name pattern to exclude'
));
$input->registerOption( new \ezcConsoleOption(
'', 'whitelist', \ezcConsoleInput::TYPE_STRING, '*', TRUE,
'Name pattern to include (default: *)'
));
$input->registerOption( new \ezcConsoleOption(
'e', 'exclude', \ezcConsoleInput::TYPE_STRING, NULL, TRUE,
'File pattern to exclude'
));
$input->registerOption( new \ezcConsoleOption(
'b', 'basedir', \ezcConsoleInput::TYPE_STRING, NULL, FALSE,
'Basedir for filepaths'
));
$input->registerOption( new \ezcConsoleOption(
't', 'template', \ezcConsoleInput::TYPE_STRING, NULL, FALSE,
'Path to code template to use'
));
$input->registerOption( new \ezcConsoleOption(
'', 'follow', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
'Enables following symbolic links',
NULL,
array(),
array( new \ezcConsoleOptionRule($this->pharOption) )
));
$input->registerOption( new \ezcConsoleOption(
'', 'format', \ezcConsoleInput::TYPE_STRING, NULL, FALSE,
'Dateformat string for timestamp'
));
$input->registerOption( new \ezcConsoleOption(
'', 'linebreak', \ezcConsoleInput::TYPE_STRING, NULL, FALSE,
'Linebreak style (CR, CR/LF or LF)'
));
$input->registerOption( new \ezcConsoleOption(
'', 'indent', \ezcConsoleInput::TYPE_STRING, NULL, FALSE,
'String used for indenting (default: 3 spaces)'
));
$this->lintOption = $input->registerOption( new \ezcConsoleOption(
'', 'lint', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
'Run lint on generated code'
));
$input->registerOption( new \ezcConsoleOption(
'', 'lint-php', \ezcConsoleInput::TYPE_STRING, NULL, FALSE,
'PHP binary path for linting (default: /usr/bin/php or c:\\php\\php.exe)',
NULL,
array( new \ezcConsoleOptionRule( $input->getOption( 'lint' ) ) )
));
$compat = $input->registerOption( new \ezcConsoleOption(
'c', 'compat', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
'Generate PHP 5.2 compliant code'
));
$this->staticOption = $input->registerOption( new \ezcConsoleOption(
's', 'static', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
'Build a static require file'
));
$input->registerOption( new \ezcConsoleOption(
'', 'tolerant', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
'Ignore Class Redeclarations in the same file'
));
$trusting = $input->registerOption( new \ezcConsoleOption(
'', 'trusting', \ezcConsoleInput::TYPE_NONE, TRUE, FALSE,
'Do not check mimetype of files prior to parsing'
));
$paranoid = $input->registerOption( new \ezcConsoleOption(
'', 'paranoid', \ezcConsoleInput::TYPE_NONE, FALSE, FALSE,
'Do check mimetype of files prior to parsing',
NULL,
array(),
array( new \ezcConsoleOptionRule($trusting) )
));
$trusting->addExclusion(new \ezcConsoleOptionRule($paranoid));
$this->onceOption = $input->registerOption( new \ezcConsoleOption(
'', 'once', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
'Use require_once in static require mode',
NULL,
array( new \ezcConsoleOptionRule( $input->getOption( 's' ) ) )
));
$input->registerOption( new \ezcConsoleOption(
'n', 'nolower', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
'Do not lowercase classnames for case insensitivity'
));
$input->registerOption( new \ezcConsoleOption(
'q', 'quiet', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
'Run in quiet mode, no output'
));
$input->registerOption( new \ezcConsoleOption(
'1', 'prepend', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
'Prepend autoloader to stack',
NULL,
array(),
array( new \ezcConsoleOptionRule( $compat ) )
));
$input->registerOption( new \ezcConsoleOption(
'd', 'no-exception', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
'Disable exceptions on registration error'
));
$input->registerOption( new \ezcConsoleOption(
'', 'var', \ezcConsoleInput::TYPE_STRING, array(), TRUE,
'Assign variable'
));
$warm = $input->registerOption( new \ezcConsoleOption(
'w', 'warm', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
'generate opcache warming file',
NULL,
array(),
array(
new \ezcConsoleOptionRule($this->pharOption),
new \ezcConsoleOptionRule($this->staticOption)
)
));
$input->registerOption( new \ezcConsoleOption(
'', 'reset', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
'add reset call to generated opcache warming file',
NULL,
array(
new \ezcConsoleOptionRule($warm)
)
));
$input->argumentDefinition = new \ezcConsoleArguments();
$input->argumentDefinition[0] = new \ezcConsoleArgument('directory');
$input->argumentDefinition[0]->shorthelp = 'The directory to process.';
$input->argumentDefinition[0]->multiple = TRUE;
return $input;
}
private function preBootstrap() {
$required = array('tokenizer', 'fileinfo');
$missing = array();
foreach($required as $test) {
if (!extension_loaded($test)) {
$missing[] = sprintf('ext/%s not installed/enabled', $test);
}
}
if (count($missing)) {
throw new CLIEnvironmentException(
join("\n", $missing),
CLIEnvironmentException::ExtensionMissing
);
}
if (extension_loaded('xdebug')) {
ini_set('xdebug.scream', 0);
ini_set('xdebug.max_nesting_level', 8192);
ini_set('xdebug.show_exception_trace', 0);
if (function_exists('xdebug_disable')) { // Xdebug v2
xdebug_disable();
}
}
}
}
class CLIEnvironmentException extends \Exception {
const ExtensionMissing = 1;
}
}

View file

@ -0,0 +1,62 @@
<?php
namespace ncc\ThirdParty\theseer\Autoload {
class Cache {
/**
* @var CacheEntry[]
*/
private $loadedEntries = array();
/**
* @var CacheEntry[]
*/
private $usedEntries = array();
public function __construct(array $initialEntries) {
$this->loadedEntries = $initialEntries;
}
/**
* @param SourceFile $file
*
* @return bool
*/
public function hasResult(SourceFile $file) {
$pathname = $file->getPathname();
if (!isset($this->loadedEntries[$pathname])) {
return false;
}
return $this->loadedEntries[$pathname]->getTimestamp() === $file->getMTime();
}
public function getResult(SourceFile $file) {
if (!$this->hasResult($file)) {
throw new CacheException('Entry not found');
}
$pathname = $file->getPathname();
$entry = $this->loadedEntries[$pathname];
$this->usedEntries[$pathname] = $entry;
return $entry->getResult();
}
public function addResult(SourceFile $file, ParseResult $result) {
$this->usedEntries[$file->getPathname()] = new CacheEntry($file->getMTime(), $result);
}
public function persist($fname) {
if (file_exists($fname)) {
unlink($fname);
}
file_put_contents($fname, serialize($this->usedEntries));
}
}
class CacheException extends \Exception {
}
}

View file

@ -0,0 +1,38 @@
<?php
namespace ncc\ThirdParty\theseer\Autoload {
class CacheEntry {
/**
* @var ParseResult
*/
private $result;
/**
* @var int
*/
private $timestamp;
public function __construct($timestamp, ParseResult $result) {
$this->timestamp = $timestamp;
$this->result = $result;
}
/**
* @return ParseResult
*/
public function getResult() {
return $this->result;
}
/**
* @return int
*/
public function getTimestamp() {
return $this->timestamp;
}
}
}

View file

@ -0,0 +1,41 @@
<?php
namespace ncc\ThirdParty\theseer\Autoload;
use ncc\ThirdParty\theseer\Autoload\StaticListRenderer;
class CacheWarmingListRenderer implements StaticListRenderer {
/**
* @var bool
*/
private $addReset;
/**
* @var string
*/
private $indent;
private $linebreak;
/**
* @param boolean $addReset
* @param string $indent
* @param string $getLinebreak
*/
public function __construct($addReset, $indent, $linebreak) {
$this->addReset = $addReset;
$this->indent = $indent;
$this->linebreak = $linebreak;
}
/**
* @return string
*/
public function render(array $list) {
$line = $this->indent . 'opcache_compile_file(___BASEDIR___\'';
$glue = '\');' . $this->linebreak . $line;
$firstLine = $this->addReset ? $this->indent . 'opcache_reset();' . $this->linebreak : '';
return $firstLine . $line . implode($glue, $list) . '\');';
}
}

View file

@ -0,0 +1,42 @@
<?php
namespace ncc\ThirdParty\theseer\Autoload {
use ncc\ThirdParty\theseer\Autoload\ParserInterface;
class CachingParser implements ParserInterface {
/**
* @var ParserInterface
*/
private $parser;
/**
* @var Cache
*/
private $cache;
public function __construct(Cache $cache, ParserInterface $parser) {
$this->cache = $cache;
$this->parser = $parser;
}
/**
* Parse a given file for defintions of classes, traits and interfaces
*
* @param SourceFile $source file to process
*
* @return ParseResult
*/
public function parse(SourceFile $source) {
if ($this->cache->hasResult($source)) {
return $this->cache->getResult($source);
}
$result = $this->parser->parse($source);
$this->cache->addResult($source, $result);
return $result;
}
}
}

View file

@ -0,0 +1,96 @@
<?php
namespace ncc\ThirdParty\theseer\Autoload {
use ncc\ThirdParty\theseer\DirectoryScanner\PHPFilterIterator;
class Collector {
/**
* @var ParserInterface
*/
private $parser;
/**
* @var CollectorResult
*/
private $collectorResult;
/**
* @var bool
*/
private $tolerantMode;
/**
* @var bool
*/
private $trustingMode;
/**
* Collector constructor.
*
* @param ParserInterface $parser
* @param bool $tolerantMode
* @param bool $trustingMode
* @param array $whitelist
* @param array $blacklist
*/
public function __construct(ParserInterface $parser, $tolerantMode = false, $trustingMode = true, Array $whitelist = array('*'), Array $blacklist = array()) {
$this->parser = $parser;
$this->tolerantMode = $tolerantMode;
$this->trustingMode = $trustingMode;
$this->collectorResult = new CollectorResult($whitelist, $blacklist);
}
public function getResult() {
return $this->collectorResult;
}
public function processDirectory(\Iterator $sources) {
$worker = $this->trustingMode ? $sources : new PHPFilterIterator($sources);
foreach($worker as $file) {
$this->processFile($file);
}
}
public function processFile(\SplFileInfo $file) {
if ($this->collectorResult->hasResultFor($file)) {
return;
}
try {
$parseResult = $this->parser->parse(new SourceFile($file->getRealPath()));
if ($parseResult->hasRedeclarations() && !$this->tolerantMode) {
throw new CollectorException(
sprintf(
"Duplicate (potentially conditional) definitions of the following unit(s) found:\n\n\tUnit(s): %s\n\tFile: %s",
join(', ', $parseResult->getRedeclarations()),
$file->getRealPath()
),
CollectorException::InFileRedeclarationFound
);
}
$this->collectorResult->addParseResult($file, $parseResult);
} catch(ParserException $e) {
throw new CollectorException(
sprintf(
"Could not process file '%s' due to parse errors: %s",
$file->getRealPath(),
$e->getMessage()
),
CollectorException::ParseErrror,
$e
);
} catch(CollectorResultException $e) {
throw new CollectorException(
$e->getMessage(),
CollectorException::RedeclarationFound
);
}
}
}
class CollectorException extends \Exception {
const ParseErrror = 1;
const RedeclarationFound = 2;
const InFileRedeclarationFound = 3;
}
}

View file

@ -0,0 +1,118 @@
<?php
namespace ncc\ThirdParty\theseer\Autoload {
class CollectorResult {
/**
* @var array
*/
private $whitelist;
/**
* @var array
*/
private $blacklist;
/**
* @var array
*/
private $units = array();
/**
* @var array
*/
private $dependencies = array();
/**
* @var array
*/
private $seenFiles = array();
/**
* @var array
*/
private $duplicates = array();
public function __construct(array $whitelist, array $blacklist) {
$this->whitelist = $whitelist;
$this->blacklist = $blacklist;
}
public function hasResultFor(\SplFileInfo $file) {
return isset($this->seenFiles[$file->getRealPath()]);
}
public function addParseResult(\SplFileInfo $file, ParseResult $result) {
if (!$result->hasUnits()) {
return;
}
$filename = $file->getRealPath();
$this->seenFiles[$filename] = true;
foreach($result->getUnits() as $unit) {
if (!$this->accept($unit)) {
continue;
}
if (isset($this->units[$unit])) {
if (!isset($this->duplicates[$unit])) {
$this->duplicates[$unit] = array( $this->units[$unit] );
}
$this->duplicates[$unit][] = $filename;
continue;
}
$this->units[$unit] = $filename;
$this->dependencies[$unit] = $result->getDependenciesForUnit($unit);
}
}
public function hasUnits() {
return count($this->units) > 0;
}
public function hasDuplicates() {
return count($this->duplicates) > 0;
}
/**
* @return array
*/
public function getDependencies() {
return $this->dependencies;
}
/**
* @return array
*/
public function getUnits() {
return $this->units;
}
/**
* @param string $unit
*
* @return bool
*/
private function accept($unit) {
foreach($this->blacklist as $entry) {
if (fnmatch($entry, $unit)) {
return false;
}
}
foreach($this->whitelist as $entry) {
if (fnmatch($entry, $unit)) {
return true;
}
}
return false;
}
public function getDuplicates() {
return $this->duplicates;
}
}
class CollectorResultException extends \Exception {
const DuplicateUnitName = 1;
}
}

View file

@ -0,0 +1,183 @@
<?php
namespace ncc\ThirdParty\theseer\Autoload {
use Exception;
use Iterator;
use ReturnTypeWillChange;
use SplFileInfo;
class ComposerIterator implements Iterator {
/**
* @var array
*/
private $directories = array();
private $seen = array();
private $pos = 0;
public function __construct(SplFileInfo $composerFile) {
if (!$composerFile->isFile() || !$composerFile->isReadable()) {
throw new ComposerIteratorException(
sprintf('Composer file "%s" not found or not readable', $composerFile->getPathname()),
ComposerIteratorException::InvalidComposerJsonFile
);
}
$composerDir = dirname($composerFile->getRealPath());
$composerData = json_decode(file_get_contents($composerFile->getRealPath()), true);
if (isset($composerData['require'])) {
foreach($composerData['require'] as $require => $version) {
if ($require === 'php' || strpos($require, 'ext-') === 0) {
continue;
}
$this->processRequire($composerDir, $require);
}
}
if (isset($composerData['autoload'])) {
$this->processAutoload($composerDir, $composerData['autoload']);
}
}
private function processAutoload($baseDir, array $map) {
if (isset($map['classmap'])) {
foreach($map['classmap'] as $dir) {
$this->addDirectory($baseDir . '/' . $dir);
}
}
foreach(array('psr-0', 'psr-4') as $psr) {
if (isset($map[$psr])) {
foreach ($map[$psr] as $node => $dir) {
if ($dir === '') {
$this->addDirectory($baseDir);
continue;
}
if (is_array($dir)) {
foreach($dir as $d) {
$this->addDirectory($baseDir . '/' . $d);
}
continue;
}
$this->addDirectory($baseDir . '/' . $dir);
}
}
}
}
private function processRequire($basedir, $require) {
if (isset($this->seen[$require])) {
return;
}
$this->seen[$require] = true;
$requireDir = $basedir . '/vendor/' . $require;
$jsonFile = $this->findComposerJson($requireDir);
if ($jsonFile === null) {
return;
}
$jsonData = json_decode(file_get_contents($jsonFile), true);
if (isset($jsonData['require'])) {
foreach($jsonData['require'] as $entry => $version) {
if ($entry === 'php' || strpos($entry, 'ext-') === 0 || strpos($entry, 'lib-') === 0) {
continue;
}
$this->processRequire($basedir, $entry);
}
}
if (isset($jsonData['autoload'])) {
$this->processAutoload($requireDir, $jsonData['autoload']);
return;
}
$this->addDirectory($requireDir);
}
private function findComposerJson($dir) {
if (file_exists($dir . '/composer.json')) {
return $dir . '/composer.json';
}
foreach(glob($dir . '/*', GLOB_ONLYDIR) as $subDir) {
$result = $this->findComposerJson($subDir);
if ($result !== NULL) {
return $result;
}
}
}
private function addDirectory($dir) {
$dir = rtrim($dir, '/');
if (!in_array($dir, $this->directories)) {
$this->directories[] = $dir;
}
}
/**
* (PHP 5 &gt;= 5.0.0)<br/>
* Return the current element
*
* @link http://php.net/manual/en/iterator.current.php
* @return mixed Can return any type.
*/
#[ReturnTypeWillChange]
public function current() {
return $this->directories[$this->pos];
}
/**
* (PHP 5 &gt;= 5.0.0)<br/>
* Move forward to next element
*
* @link http://php.net/manual/en/iterator.next.php
* @return void Any returned value is ignored.
*/
#[ReturnTypeWillChange]
public function next() {
$this->pos++;
}
/**
* (PHP 5 &gt;= 5.0.0)<br/>
* Return the key of the current element
*
* @link http://php.net/manual/en/iterator.key.php
* @return mixed scalar on success, or null on failure.
*/
#[ReturnTypeWillChange]
public function key() {
return $this->pos;
}
/**
* (PHP 5 &gt;= 5.0.0)<br/>
* Checks if current position is valid
*
* @link http://php.net/manual/en/iterator.valid.php
* @return boolean The return value will be casted to boolean and then evaluated.
* Returns true on success or false on failure.
*/
#[ReturnTypeWillChange]
public function valid() {
return $this->pos < count($this->directories);
}
/**
* (PHP 5 &gt;= 5.0.0)<br/>
* Rewind the Iterator to the first element
*
* @link http://php.net/manual/en/iterator.rewind.php
* @return void Any returned value is ignored.
*/
#[ReturnTypeWillChange]
public function rewind() {
$this->pos = 0;
}
}
class ComposerIteratorException extends Exception {
const InvalidComposerJsonFile = 1;
}
}

View file

@ -0,0 +1,435 @@
<?php
/**
* Copyright (c) 2009-2019 Arne Blankerts <arne@blankerts.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of Arne Blankerts nor the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* 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 HOLDER ORCONTRIBUTORS
* 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.
*
* @package Autoload
* @author Arne Blankerts <arne@blankerts.de>
* @copyright Arne Blankerts <arne@blankerts.de>, All rights reserved.
* @license BSD License
*
*/
namespace ncc\ThirdParty\theseer\Autoload {
class Config {
private $quietMode = FALSE;
private $directories = array();
private $outputFile = 'STDOUT';
private $pharMode = FALSE;
private $include = array('*.php');
private $exclude = array();
private $whitelist = array('*');
private $blacklist = array();
private $baseDirectory = NULL;
private $template;
private $linebreak = "\n";
private $indent;
private $lint = FALSE;
private $php;
private $compatMode = FALSE;
private $staticMode = FALSE;
private $warmMode = FALSE;
private $tolerant = FALSE;
private $trusting = TRUE;
private $once = FALSE;
private $reset = FALSE;
private $lowercase = TRUE;
private $dateFormat;
private $variable = array();
private $pharCompression = 'NONE';
private $pharKey;
private $pharAll = false;
private $pharAliasName = '';
private $pharHashAlgorithm;
private $followSymlinks = false;
private $cacheFilename;
private $prepend = false;
private $exceptions = true;
public function __construct(Array $directories) {
$this->directories = $directories;
$this->php = (PHP_OS === 'WIN' ? 'C:\php\php.exe' : '/usr/bin/php');
}
public function setBaseDirectory($baseDirectory) {
$this->baseDirectory = $baseDirectory;
}
public function getBaseDirectory() {
if ($this->baseDirectory !== NULL) {
return realpath($this->baseDirectory);
}
if ($this->isPharMode()) {
$comparator = new PathComparator($this->directories);
return $comparator->getCommonBase();
}
if ($this->outputFile != 'STDOUT') {
return realpath(dirname($this->outputFile) ?: '.');
}
$tmp = $this->getDirectories();
return realpath(is_dir($tmp[0]) ? $tmp[0] : (dirname($tmp[0]) ?: '.'));
}
public function setCompatMode($compatMode) {
$this->compatMode = $compatMode;
}
public function isCompatMode() {
return $this->compatMode === true;
}
public function setDateFormat($dateFormat) {
$this->dateFormat = $dateFormat;
}
public function getDateFormat() {
return $this->dateFormat;
}
public function setExclude(Array $exclude) {
$this->exclude = $exclude;
}
public function getExclude() {
return $this->exclude;
}
public function setInclude(Array $include) {
$this->include = $include;
}
public function getInclude() {
return $this->include;
}
/**
* @return array
*/
public function getBlacklist() {
return $this->blacklist;
}
/**
* @param array $blacklist
*/
public function setBlacklist($blacklist) {
$this->blacklist = $blacklist;
}
/**
* @return array
*/
public function getWhitelist() {
return $this->whitelist;
}
/**
* @param array $whitelist
*/
public function setWhitelist($whitelist) {
$this->whitelist = $whitelist;
}
public function setIndent($indent) {
$this->indent = $indent;
}
public function getIndent() {
if ($this->indent !== NULL) {
if (is_numeric($this->indent) && (int)$this->indent == $this->indent) {
return str_repeat(' ', (int)$this->indent);
}
return $this->indent;
}
if ($this->isStaticMode() || $this->isWarmMode()) {
return '';
}
return str_repeat(' ', $this->isCompatMode() ? 12 : 16);
}
public function setLinebreak($linebreak) {
$lbr = array('LF' => "\n", 'CR' => "\r", 'CRLF' => "\r\n" );
if (isset($lbr[$linebreak])) {
$this->linebreak = $lbr[$linebreak];
} else {
$this->linebreak = $linebreak;
}
}
public function getLinebreak() {
return $this->linebreak;
}
public function setLintMode($lint) {
$this->lint = (boolean)$lint;
}
public function isLintMode() {
return $this->lint;
}
public function setLowercaseMode($lowercase) {
$this->lowercase = (boolean)$lowercase;
}
public function isLowercaseMode() {
return $this->lowercase;
}
public function setOnceMode($once) {
$this->once = (boolean)$once;
}
public function isOnceMode() {
return $this->once;
}
public function setOutputFile($outputFile) {
$this->outputFile = $outputFile;
}
public function getOutputFile() {
return $this->outputFile;
}
public function enablePharMode($compression = 'NONE', $all = true, $key = NULL, $alias = NULL) {
$this->pharMode = true;
$this->pharCompression = $compression;
$this->pharAll = (boolean)$all;
$this->pharKey = $key;
$this->pharAliasName = $alias;
}
public function isPharMode() {
return $this->pharMode;
}
public function isPharAllMode() {
return $this->pharAll;
}
public function getPharCompression() {
return $this->pharCompression;
}
public function getPharKey() {
return $this->pharKey;
}
public function getPharAliasName() {
return $this->pharAliasName;
}
public function hasPharHashAlgorithm() {
return $this->pharHashAlgorithm !== null;
}
/**
* @return string
*/
public function getPharHashAlgorithm() {
return $this->pharHashAlgorithm;
}
/**
* @param string $pharHashAlgorithm
*/
public function setPharHashAlgorithm($pharHashAlgorithm) {
if (!in_array($pharHashAlgorithm, array('SHA-512','SHA-256','SHA-1'))) {
throw new \InvalidArgumentException(
sprintf('Algorithm %s not supported', $pharHashAlgorithm)
);
}
$this->pharHashAlgorithm = $pharHashAlgorithm;
}
public function setPhp($php) {
$this->php = $php;
}
public function getPhp() {
return $this->php;
}
public function setQuietMode($quietMode) {
$this->quietMode = (boolean)$quietMode;
}
public function setStaticMode($staticMode) {
$this->staticMode = (boolean)$staticMode;
$this->warmMode = FALSE;
}
public function isStaticMode() {
return $this->staticMode;
}
public function setWarmMode($warmMode) {
$this->warmMode = (boolean)$warmMode;
$this->staticMode = FALSE;
}
public function isWarmMode() {
return $this->warmMode;
}
public function setResetMode($resetMode) {
$this->reset = (boolean)$resetMode;
}
public function isResetMode() {
return $this->reset;
}
public function setTemplate($template) {
$this->template = $template;
}
public function getTemplate() {
$tplType = $this->isLowercaseMode() ? 'ci' : 'cs';
$template = $this->template;
if ($template !== NULL) {
if (!file_exists($template)) {
$alternative = __DIR__.'/templates/'. $tplType .'/'.$template;
if (file_exists($alternative)) {
$template = $alternative;
}
$alternative .= '.php.tpl';
if (file_exists($alternative)) {
$template = $alternative;
}
}
return $template;
}
// determine auto template to use
$tplFile = 'default.php.tpl';
if ($this->isCompatMode()) {
$tplFile = 'php52.php.tpl';
}
if ($this->isPharMode()) {
if ($this->isStaticMode()) {
$tplFile = 'staticphar.php.tpl';
$tplType = '.';
} else {
$tplFile = 'phar.php.tpl';
}
} elseif ($this->isStaticMode() || $this->isWarmMode()) {
$tplFile = 'static.php.tpl';
$tplType = '.';
}
return __DIR__.'/templates/'.$tplType.'/'.$tplFile;
}
public function setTolerantMode($tolerant) {
$this->tolerant = (boolean)$tolerant;
}
public function isTolerantMode() {
return $this->tolerant;
}
public function setTrusting($trusting) {
$this->trusting = (boolean)$trusting;
}
public function setFollowSymlinks($followSymlinks) {
$this->followSymlinks = (boolean)$followSymlinks;
}
public function isFollowSymlinks() {
return $this->followSymlinks;
}
public function isTrustingMode() {
return $this->trusting;
}
public function setVariable($name, $value) {
$this->variable[$name] = $value;
}
public function getVariables() {
return $this->variable;
}
public function isQuietMode() {
return $this->quietMode;
}
public function getDirectories() {
$list = array();
foreach($this->directories as $dir) {
if (is_file($dir) && basename($dir) == 'composer.json') {
foreach(new ComposerIterator(new \SplFileInfo($dir)) as $d) {
$list[] = $d;
}
} else {
foreach(glob($dir) as $match) {
$list[] = $match;
}
}
}
return $list;
}
public function setCacheFile($filename) {
$this->cacheFilename = $filename;
}
public function isCacheEnabled() {
return $this->cacheFilename !== NULL;
}
public function getCacheFile() {
return $this->cacheFilename;
}
public function enablePrepend() {
$this->prepend = true;
}
public function usePrepend() {
return $this->prepend;
}
public function disableExceptions() {
$this->exceptions = false;
}
public function useExceptions() {
return $this->exceptions;
}
}
}

View file

@ -0,0 +1,100 @@
<?php
/**
* Copyright (c) 2009-2019 Arne Blankerts <arne@blankerts.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of Arne Blankerts nor the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* 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 HOLDER ORCONTRIBUTORS
* 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.
*
* @package Autoload
* @author Arne Blankerts <arne@blankerts.de>
* @copyright Arne Blankerts <arne@blankerts.de>, All rights reserved.
* @license BSD License
*/
namespace ncc\ThirdParty\theseer\Autoload {
/**
* Sorting classes by depdendency for static requires
*
* @author Arne Blankerts <arne@blankerts.de>
* @copyright Arne Blankerts <arne@blankerts.de>, All rights reserved.
*/
class ClassDependencySorter {
private $classList;
private $dependencies;
private $level;
private $sorted = array();
public function __construct(Array $classes, Array $dependencies) {
$this->classList = $classes;
$this->dependencies = $dependencies;
}
public function process() {
$this->level = 0;
foreach($this->classList as $class => $file) {
if (!in_array($class, $this->sorted)) {
$this->resolve($class);
}
}
$res = array();
foreach($this->sorted as $class) {
if (!isset($this->classList[$class])) {
continue;
}
$res[$class] = $this->classList[$class];
}
return $res;
}
private function resolve($class) {
$this->level++;
if ($this->level == 50) {
throw new ClassDependencySorterException("Can't resolve more than 50 levels of dependencies", ClassDependencySorterException::TooManyDependencyLevels);
}
if (isset($this->dependencies[$class])) {
foreach($this->dependencies[$class] as $depclass) {
if (!in_array($depclass, $this->sorted)) {
$this->resolve($depclass);
}
}
}
$this->sorted[] = $class;
$this->level--;
}
}
class ClassDependencySorterException extends \Exception {
const TooManyDependencyLevels = 1;
}
}

View file

@ -0,0 +1,242 @@
<?php
/**
* Copyright (c) 2009-2019 Arne Blankerts <arne@blankerts.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of Arne Blankerts nor the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* 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 HOLDER ORCONTRIBUTORS
* 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.
*
* @package Autoload
* @author Arne Blankerts <arne@blankerts.de>
* @copyright Arne Blankerts <arne@blankerts.de>, All rights reserved.
* @license BSD License
*
*/
namespace ncc\ThirdParty\theseer\Autoload {
use ncc\ThirdParty\theseer\DirectoryScanner\DirectoryScanner;
use ncc\ThirdParty\theseer\DirectoryScanner\IncludeExcludeFilterIterator;
class Factory {
/**
* @var Config
*/
private $config;
/**
* @var Cache
*/
private $cache;
/**
* @param \ncc\ThirdParty\theseer\Autoload\Config $config
*/
public function setConfig(Config $config) {
$this->config = $config;
}
/**
* @return CLI
*/
public function getCLI() {
return new CLI($this);
}
/**
* @return Application
*/
public function getApplication() {
return new Application($this->getLogger(), $this->config, $this);
}
public function getLogger() {
return new Logger($this->config->isQuietMode());
}
/**
* @return Parser
*/
public function getParser() {
$parser = new Parser(
$this->config->isLowercaseMode()
);
if (!$this->config->isCacheEnabled()) {
return $parser;
}
return new CachingParser(
$this->getCache(),
$parser
);
}
/**
* @return Cache
*/
public function getCache() {
if (!$this->cache instanceof Cache) {
$fname = $this->config->getCacheFile();
if (file_exists($fname)) {
$data = unserialize(file_get_contents($fname));
} else {
$data = array();
}
$this->cache = new Cache($data);
}
return $this->cache;
}
public function getCollector() {
return new Collector(
$this->getParser(),
$this->config->isTolerantMode(),
$this->config->isTrustingMode(),
$this->config->getWhitelist(),
$this->config->getBlacklist()
);
}
/**
* Get instance of DirectoryScanner with filter options applied
*
* @param bool $filter
* @return DirectoryScanner
*/
public function getScanner($filter = TRUE) {
$scanner = new DirectoryScanner;
if ($filter) {
$scanner->setIncludes($this->config->getInclude());
$scanner->setExcludes($this->config->getExclude());
}
if ($this->config->isFollowSymlinks()) {
$scanner->setFlag(\FilesystemIterator::FOLLOW_SYMLINKS);
}
return $scanner;
}
public function getFilter(\Iterator $files) {
$filter = new IncludeExcludeFilterIterator($files);
$filter->setInclude($this->config->getInclude());
$filter->setExclude($this->config->getExclude());
return $filter;
}
public function getPharBuilder() {
$builder = new PharBuilder(
$this->getScanner(!$this->config->isPharAllMode()),
$this->config->getBaseDirectory()
);
$builder->setCompressionMode($this->config->getPharCompression());
foreach($this->config->getDirectories() as $directory) {
$builder->addDirectory($directory);
}
return $builder;
}
/**
* Helper to get instance of AutoloadRenderer with cli options applied
*
* @param CollectorResult $result
*
* @return \ncc\ThirdParty\theseer\Autoload\AutoloadRenderer|\ncc\ThirdParty\theseer\Autoload\StaticRenderer
* @throws \RuntimeException
*/
public function getRenderer(CollectorResult $result) {
$isStatic = $this->config->isStaticMode();
$isPhar = $this->config->isPharMode();
$isCompat = $this->config->isCompatMode();
$isOnce = $this->config->isOnceMode();
$isWarm = $this->config->isWarmMode();
$isReset = $this->config->isResetMode();
if ($isWarm === TRUE) {
$renderer = new StaticRenderer(
$result->getUnits(),
$this->getCacheWarmingListRenderer($isReset)
);
$renderer->setDependencies($result->getDependencies());
$renderer->setPharMode($isPhar);
} else if ($isStatic === TRUE) {
$renderer = new StaticRenderer(
$result->getUnits(),
$this->getStaticRequireListRenderer($isOnce)
);
$renderer->setDependencies($result->getDependencies());
$renderer->setPharMode($isPhar);
} else {
$renderer = new AutoloadRenderer($result->getUnits());
if ($this->config->usePrepend()) {
$renderer->prependAutoloader();
}
if ($this->config->useExceptions()) {
$renderer->enableExceptions();
}
}
$renderer->setCompat($isCompat);
$basedir = $this->config->getBaseDirectory();
if (!$basedir || !is_dir($basedir)) {
throw new \RuntimeException("Given basedir '{$basedir}' does not exist or is not a directory");
}
$renderer->setBaseDir($basedir);
$format = $this->config->getDateFormat();
if ($format) {
$renderer->setDateTimeFormat($format);
}
$renderer->setIndent($this->config->getIndent());
$renderer->setLineBreak($this->config->getLinebreak());
foreach($this->config->getVariables() as $name => $value) {
$renderer->setVariable($name, $value);
}
return $renderer;
}
private function getStaticRequireListRenderer($useOnce) {
return new StaticRequireListRenderer(
$useOnce,
$this->config->getIndent(),
$this->config->getLinebreak()
);
}
private function getCacheWarmingListRenderer($addReset) {
return new CacheWarmingListRenderer(
$addReset,
$this->config->getIndent(),
$this->config->getLinebreak()
);
}
}
}

View file

@ -0,0 +1,31 @@
Autoload Builder
Copyright (c) 2010-2016 Arne Blankerts <arne@blankerts.de> and Contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of Arne Blankerts nor the names of contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
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 HOLDER ORCONTRIBUTORS
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.

View file

@ -0,0 +1,59 @@
<?php
/**
* Copyright (c) 2009-2019 Arne Blankerts <arne@blankerts.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of Arne Blankerts nor the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* 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 HOLDER ORCONTRIBUTORS
* 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.
*
* @package Autoload
* @author Arne Blankerts <arne@blankerts.de>
* @copyright Arne Blankerts <arne@blankerts.de>, All rights reserved.
* @license BSD License
*
*/
namespace ncc\ThirdParty\theseer\Autoload {
class Logger {
private $quiet = FALSE;
/**
* @param bool $quietMode
*/
public function __construct($quietMode = FALSE) {
$this->quiet = $quietMode;
}
public function log($message, $target = STDOUT) {
if ($this->quiet) {
return;
}
fwrite($target, $message);
}
}
}

View file

@ -0,0 +1,64 @@
<?php
namespace ncc\ThirdParty\theseer\Autoload {
class ParseResult {
/**
* @var string[]
*/
private $units = array();
/**
* @var array
*/
private $dependencies = array();
/**
* @var string[]
*/
private $redeclarations = array();
public function __construct(Array $units, Array $dependencies, Array $redeclarations) {
$this->units = $units;
$this->dependencies = $dependencies;
$this->redeclarations = $redeclarations;
}
public function hasUnits() {
return count($this->units) > 0;
}
public function hasRedeclarations() {
return count($this->redeclarations) > 0;
}
/**
*
* @param string $unit
*
* @return array
*/
public function getDependenciesForUnit($unit) {
if (!isset($this->dependencies[$unit])) {
return array();
}
return $this->dependencies[$unit];
}
/**
* @return \string[]
*/
public function getRedeclarations() {
return $this->redeclarations;
}
/**
* @return \string[]
*/
public function getUnits() {
return $this->units;
}
}
}

View file

@ -0,0 +1,598 @@
<?php
/**
* Copyright (c) 2009-2019 Arne Blankerts <arne@blankerts.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of Arne Blankerts nor the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* 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 HOLDER ORCONTRIBUTORS
* 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.
*
* @package Autoload
* @author Arne Blankerts <arne@blankerts.de>
* @copyright Arne Blankerts <arne@blankerts.de>, All rights reserved.
* @license BSD License
*/
namespace ncc\ThirdParty\theseer\Autoload {
// PHP 5.3 compat
define('T_TRAIT_53', 10355);
if (!defined('T_TRAIT')) {
define('T_TRAIT', -1);
}
// PHP 8.0 forward compat
if (!defined('T_NAME_FULLY_QUALIFIED')) {
define('T_NAME_FULLY_QUALIFIED', -1);
define('T_NAME_QUALIFIED', -1);
}
// PHP 8.1 forward compat
if (!defined('T_ENUM')) {
define('T_ENUM', -1);
}
/**
* Namespace aware parser to find and extract defined classes within php source files
*
* @author Arne Blankerts <arne@blankerts.de>
* @copyright Arne Blankerts <arne@blankerts.de>, All rights reserved.
*/
class Parser implements ParserInterface {
private $methodMap = array(
T_TRAIT => 'processClass',
T_TRAIT_53 => 'processClass',
T_CLASS => 'processClass',
T_ENUM => 'processEnum',
//T_CASE => 'processEnumCase',
T_INTERFACE => 'processInterface',
T_NAMESPACE => 'processNamespace',
T_USE => 'processUse',
'}' => 'processBracketClose',
'{' => 'processBracketOpen',
T_CURLY_OPEN => 'processBracketOpen',
T_DOLLAR_OPEN_CURLY_BRACES => 'processBracketOpen'
);
private $typeMap = array(
T_INTERFACE => 'interface',
T_CLASS => 'class',
T_ENUM => 'enum',
T_TRAIT => 'trait',
T_TRAIT_53 => 'trait'
);
private $caseInsensitive;
private $tokenArray = array();
private $inNamespace = '';
private $inUnit = '';
private $nsBracket = 0;
private $classBracket = 0;
private $bracketLevel = 0;
private $aliases = array();
private $found = array();
private $dependencies = array();
private $redeclarations = array();
public function __construct($caseInsensitive = true) {
$this->caseInsensitive = $caseInsensitive;
}
/**
* Parse a given file for defintions of classes, traits and interfaces
*
* @param SourceFile $source file to process
*
* @return ParseResult
*/
public function parse(SourceFile $source) {
$this->found = array();
$this->redeclarations = array();
$this->inNamespace = '';
$this->aliases = array();
$this->bracketLevel = 0;
$this->inUnit = '';
$this->nsBracket = 0;
$this->classBracket = 0;
$this->tokenArray = $source->getTokens();
$tokenCount = count($this->tokenArray);
$tokList = array_keys($this->methodMap);
for($t=0; $t<$tokenCount; $t++) {
$current = (array)$this->tokenArray[$t];
if ($current[0]===T_STRING && $current[1]==='trait' && T_TRAIT===-1) {
// PHP < 5.4 compat fix
$current[0] = T_TRAIT_53;
$this->tokenArray[$t] = $current;
}
if (!in_array($current[0], $tokList)) {
continue;
}
$t = call_user_func(array($this, $this->methodMap[$current[0]]), $t);
}
return new ParseResult($this->found, $this->dependencies, $this->redeclarations);
}
private function processBracketOpen($pos) {
$this->bracketLevel++;
return $pos + 1;
}
private function processBracketClose($pos) {
$this->bracketLevel--;
if ($this->nsBracket !== 0 && $this->bracketLevel < $this->nsBracket) {
$this->inNamespace = '';
$this->nsBracket = 0;
$this->aliases = array();
}
if ($this->bracketLevel <= $this->classBracket) {
$this->classBracket = 0;
$this->inUnit = '';
}
return $pos + 1;
}
private function processClass($pos) {
if (!$this->classTokenNeedsProcessing($pos)) {
return $pos;
}
$list = array('{');
$stack = $this->getTokensTill($pos, $list);
$stackSize = count($stack);
$classname = $this->inNamespace !== '' ? $this->inNamespace . '\\' : '';
$extends = '';
$extendsFound = false;
$implementsFound = false;
$implementsList = array();
$implements = '';
$mode = 'classname';
foreach(array_slice($stack, 1, -1) as $tok) {
switch ($tok[0]) {
case T_COMMENT:
case T_DOC_COMMENT:
case T_WHITESPACE: {
break;
}
case T_NAME_FULLY_QUALIFIED:
case T_NAME_QUALIFIED:
case T_STRING: {
$$mode .= $tok[1];
break;
}
case T_NS_SEPARATOR: {
$$mode .= '\\';
break;
}
case T_EXTENDS: {
$extendsFound = true;
$mode = 'extends';
break;
}
case T_IMPLEMENTS: {
$implementsFound = true;
$mode = 'implements';
break;
}
case ',': {
if ($mode === 'implements') {
$implementsList[] = $this->resolveDependencyName($implements);
$implements = '';
}
break;
}
default: {
throw new ParserException(sprintf(
'Parse error while trying to process class definition (unexpected token "%s" in name).',
\token_name($tok[0])
), ParserException::ParseError
);
}
}
}
if ($implements != '') {
$implementsList[] = $this->resolveDependencyName($implements);
}
if ($implementsFound && count($implementsList)==0) {
throw new ParserException(sprintf(
'Parse error while trying to process class definition (extends or implements).'
), ParserException::ParseError
);
}
$classname = $this->registerUnit($classname, $stack[0][0]);
$this->dependencies[$classname] = $implementsList;
if ($extendsFound) {
$this->dependencies[$classname][] = $this->resolveDependencyName($extends);
}
$this->inUnit = $classname;
$this->classBracket = $this->bracketLevel + 1;
return $pos + $stackSize - 1;
}
private function processEnum($pos) {
$list = array('{');
$stack = $this->getTokensTill($pos, $list);
$stackSize = count($stack);
$enumName = $this->inNamespace !== '' ? $this->inNamespace . '\\' : '';
$implementsFound = false;
$implementsList = array();
$implements = '';
$backType = '';
$mode = 'enumName';
foreach(array_slice($stack, 1, -1) as $tok) {
switch ($tok[0]) {
case T_COMMENT:
case T_DOC_COMMENT:
case T_WHITESPACE: {
break;
}
case T_NAME_FULLY_QUALIFIED:
case T_NAME_QUALIFIED:
case T_STRING: {
$$mode .= $tok[1];
break;
}
case T_NS_SEPARATOR: {
$$mode .= '\\';
break;
}
case T_IMPLEMENTS: {
$implementsFound = true;
$mode = 'implements';
break;
}
case ':': {
$isBacked = true;
$mode = 'backType';
break;
}
case ',': {
if ($mode === 'implements') {
$implementsList[] = $this->resolveDependencyName($implements);
$implements = '';
}
break;
}
default: {
throw new ParserException(sprintf(
'Parse error while trying to process class definition (unexpected token "%s" in name).',
is_int($tok[0]) ? \token_name($tok[0]) : $tok[0]
), ParserException::ParseError
);
}
}
}
if ($implements != '') {
$implementsList[] = $this->resolveDependencyName($implements);
}
if ($implementsFound && count($implementsList)==0) {
throw new ParserException(sprintf(
'Parse error while trying to process enum definition (implements).'
), ParserException::ParseError
);
}
$enumName = $this->registerUnit($enumName, $stack[0][0]);
$this->dependencies[$enumName] = $implementsList;
return $pos + $stackSize - 1;
}
private function processInterface($pos) {
$list = array('{');
$stack = $this->getTokensTill($pos, $list);
$stackSize = count($stack);
$next = $stack[1];
if (is_array($next) && $next[0] === '(') {
// sort of inline use - ignore
return $pos + $stackSize;
}
$name = $this->inNamespace != '' ? $this->inNamespace . '\\' : '';
$extends = '';
$extendsList = array();
$mode = 'name';
foreach(array_slice($stack, 1, -1) as $tok) {
switch ($tok[0]) {
case T_NS_SEPARATOR:
case T_NAME_QUALIFIED:
case T_NAME_FULLY_QUALIFIED:
case T_STRING: {
$$mode .= $tok[1];
break;
}
case T_EXTENDS: {
$mode = 'extends';
break;
}
case ',': {
if ($mode == 'extends') {
$extendsList[] = $this->resolveDependencyName($extends);
$extends = '';
}
}
}
}
$name = $this->registerUnit($name, T_INTERFACE);
if ($extends != '') {
$extendsList[] = $this->resolveDependencyName($extends);
}
$this->dependencies[$name] = $extendsList;
$this->inUnit = $name;
return $pos + $stackSize - 1;
}
private function resolveDependencyName($name) {
if ($name == '') {
throw new ParserException(sprintf(
'Parse error while trying to process class definition (extends or implements).'
), ParserException::ParseError
);
}
if ($name[0] == '\\') {
$name = substr($name, 1);
} else {
$parts = explode('\\', $name, 2);
$search = $this->caseInsensitive ? strtolower($parts[0]) : $parts[0];
$key = array_search($search, $this->aliases);
if (!$key) {
$name = ($this->inNamespace != '' ? $this->inNamespace . '\\' : ''). $name;
} else {
$name = $key;
if (isset($parts[1])) {
$name .= '\\' . $parts[1];
}
}
}
if ($this->caseInsensitive) {
$name = strtolower($name);
}
return $name;
}
private function registerUnit($name, $type) {
if ($name == '' || substr($name, -1) == '\\') {
throw new ParserException(sprintf(
'Parse error while trying to process %s definition.',
$this->typeMap[$type]
), ParserException::ParseError
);
}
if ($this->caseInsensitive) {
$name = strtolower($name);
}
if (in_array($name, $this->found)) {
$this->redeclarations[] = $name;
} else {
$this->found[] = $name;
}
return $name;
}
private function processNamespace($pos) {
$list = array(';', '{');
$stack = $this->getTokensTill($pos, $list);
$stackSize = count($stack);
$newpos = $pos + $stackSize;
if ($stackSize < 3) { // empty namespace defintion == root namespace
$this->inNamespace = '';
$this->aliases = array();
return $newpos - 1;
}
$next = $stack[1];
if (is_array($next) && ($next[0] === T_NS_SEPARATOR || $next[0] === '(')) {
// sort of inline use - ignore
return $newpos;
}
$this->inNamespace = '';
foreach(array_slice($stack, 1, -1) as $tok) {
$this->inNamespace .= $tok[1];
}
$this->aliases = array();
return $pos + $stackSize - 1;
}
private function processUse($pos) {
$list = array(';','(');
$stack = $this->getTokensTill($pos, $list);
$stackSize = count($stack);
$ignore = array(
'(', // closue use
T_CONST, // use const foo\bar;
T_FUNCTION // use function foo\bar;
);
if (in_array($stack[1][0], $ignore)) {
return $pos + $stackSize - 1;
}
if ($this->classBracket > 0) {
$this->parseUseOfTrait($stackSize, $stack);
} else {
$this->parseUseAsImport($stack);
}
return $pos + $stackSize - 1;
}
private function getTokensTill($start, $list) {
$list = (array)$list;
$stack = array();
$skip = array(
T_WHITESPACE,
T_COMMENT,
T_DOC_COMMENT
);
$limit = count($this->tokenArray);
for ($t=$start; $t<$limit; $t++) {
$current = (array)$this->tokenArray[$t];
if (in_array($current[0], $skip)) {
continue;
}
$stack[] = $current;
if (in_array($current[0], $list)) {
break;
}
}
return $stack;
}
/**
* @param $stackSize
* @param $stack
*/
private function parseUseOfTrait($stackSize, $stack) {
$use = '';
for ($t = 0; $t < $stackSize; $t++) {
$current = (array)$stack[$t];
switch ($current[0]) {
case '{': {
// find closing bracket to skip contents
for ($x = $t + 1; $x < $stackSize; $x++) {
$tok = $stack[$x];
if ($tok[0] == '}') {
$t = $x;
break;
}
}
break;
}
case ';':
case ',': {
$this->dependencies[$this->inUnit][] = $this->resolveDependencyName($use);
$use = '';
break;
}
case T_NS_SEPARATOR:
case T_NAME_QUALIFIED:
case T_NAME_FULLY_QUALIFIED:
case T_STRING: {
$use .= $current[1];
break;
}
}
}
}
/**
* @param $stack
*/
private function parseUseAsImport($stack) {
$use = '';
$alias = '';
$mode = 'use';
$group = '';
$ignore = false;
foreach ($stack as $tok) {
$current = $tok;
switch ($current[0]) {
case T_CONST:
case T_FUNCTION: {
$ignore = true;
break;
}
case '{': {
$group = $use;
break;
}
case ';':
case ',': {
if (!$ignore) {
if ($alias == '') {
$nss = strrpos($use, '\\');
if ($nss !== FALSE) {
$alias = substr($use, $nss + 1);
} else {
$alias = $use;
}
}
if ($this->caseInsensitive) {
$alias = strtolower($alias);
}
$this->aliases[$use] = $alias;
}
$alias = '';
$use = $group;
$mode = 'use';
$ignore = false;
break;
}
case T_NS_SEPARATOR:
case T_NAME_QUALIFIED:
case T_NAME_FULLY_QUALIFIED:
case T_STRING: {
$$mode .= $current[1];
break;
}
case T_AS: {
$mode = 'alias';
break;
}
}
}
}
private function classTokenNeedsProcessing($position) {
// PHP 5.5 has classname::class, reusing T_CLASS
if ($this->tokenArray[$position-1][0] == T_DOUBLE_COLON) {
return false;
}
// PHP 7 has anonymous classes: $x = new class { ... }
if ($position > 2 && $this->tokenArray[$position-2][0] === T_NEW) {
return false;
}
if ($this->tokenArray[$position + 1] === '(' || $this->tokenArray[$position + 2] === '(') {
return false;
}
return true;
}
}
class ParserException extends \Exception {
const ParseError = 1;
}
}

View file

@ -0,0 +1,20 @@
<?php
namespace ncc\ThirdParty\theseer\Autoload;
/**
* Namespace aware parser to find and extract defined classes within php source files
*
* @author Arne Blankerts <arne@blankerts.de>
* @copyright Arne Blankerts <arne@blankerts.de>, All rights reserved.
*/
interface ParserInterface {
/**
* Parse a given file for defintions of classes, traits and interfaces
*
* @param SourceFile $source file to process
*
* @return ParseResult
*/
public function parse(SourceFile $source);
}

View file

@ -0,0 +1,45 @@
<?php
namespace ncc\ThirdParty\theseer\Autoload {
class PathComparator {
/**
* @var string[]
*/
private $directories = array();
/**
* PathComparator constructor.
*
* @param array $directories
*/
public function __construct(array $directories) {
foreach($directories as $dir) {
$this->directories[] = realpath($dir).'/';
}
}
public function getCommonBase() {
if (count($this->directories) == 0) {
return '/';
}
$result = $this->directories[0];
foreach($this->directories as $dir) {
$result = substr($dir, 0, $this->commonPrefix($result, $dir));
}
return ($result ?: '/');
}
private function commonPrefix( $s1, $s2 ) {
$l1 = strlen($s1);
$l2 = strlen($s2);
$i=0;
while($i < $l1 && $i < $l2 && $s1[$i] == $s2[$i]) {
$i++;
}
return strrpos(substr($s1, 0, $i), '/');
}
}
}

View file

@ -0,0 +1,135 @@
<?php
/**
* Copyright (c) 2009-2019 Arne Blankerts <arne@blankerts.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of Arne Blankerts nor the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* 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 HOLDER ORCONTRIBUTORS
* 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.
*
* @package Autoload
* @author Arne Blankerts <arne@blankerts.de>
* @copyright Arne Blankerts <arne@blankerts.de>, All rights reserved.
* @license BSD License
*
*/
namespace ncc\ThirdParty\theseer\Autoload {
use ncc\ThirdParty\theseer\DirectoryScanner\DirectoryScanner;
class PharBuilder {
private $scanner;
private $compression;
private $key;
private $basedir;
private $aliasName;
private $signatureType;
private $directories = array();
private $supportedSignatureTypes = array(
'SHA-512' => \Phar::SHA512,
'SHA-256' => \Phar::SHA256,
'SHA-1' => \Phar::SHA1
);
public function __construct(DirectoryScanner $scanner, $basedir) {
$this->scanner = $scanner;
$this->basedir = $basedir;
}
public function setCompressionMode($mode) {
$this->compression = $mode;
}
public function setSignatureType($type) {
if (!in_array($type, array_keys($this->supportedSignatureTypes))) {
throw new \InvalidArgumentException(
sprintf('Signature type "%s" not known or not supported by this PHP installation.', $type)
);
}
$this->signatureType = $type;
}
public function setSignatureKey($key) {
$this->key = $key;
}
public function addDirectory($directory) {
$this->directories[] = $directory;
}
public function setAliasName($name) {
$this->aliasName = $name;
}
public function build($filename, $stub) {
if (file_exists($filename)) {
unlink($filename);
}
$phar = new \Phar($filename, 0, $this->aliasName != '' ? $this->aliasName : basename($filename));
$phar->startBuffering();
$phar->setStub($stub);
if ($this->key !== NULL) {
$privateKey = '';
openssl_pkey_export($this->key, $privateKey);
$phar->setSignatureAlgorithm(\Phar::OPENSSL, $privateKey);
$keyDetails = openssl_pkey_get_details($this->key);
file_put_contents($filename . '.pubkey', $keyDetails['key']);
} else {
$phar->setSignatureAlgorithm($this->selectSignatureType());
}
$basedir = $this->basedir ? $this->basedir : $this->directories[0];
foreach($this->directories as $directory) {
$phar->buildFromIterator($this->scanner->__invoke($directory), $basedir);
}
if ($this->compression !== \Phar::NONE) {
$phar->compressFiles($this->compression);
}
$phar->stopBuffering();
}
private function selectSignatureType() {
if ($this->signatureType !== NULL) {
return $this->supportedSignatureTypes[$this->signatureType];
}
$supported = \Phar::getSupportedSignatures();
foreach($this->supportedSignatureTypes as $candidate => $type) {
if (in_array($candidate, $supported)) {
return $type;
}
}
// Is there any PHP Version out there that does not support at least SHA-1?
// But hey, fallback to md5, better than nothing
return \Phar::MD5;
}
}
}

View file

@ -0,0 +1,14 @@
<?php
namespace ncc\ThirdParty\theseer\Autoload {
use SplFileInfo;
class SourceFile extends SplFileInfo {
public function getTokens() {
return token_get_all(file_get_contents($this->getRealPath()));
}
}
}

View file

@ -0,0 +1,10 @@
<?php
namespace ncc\ThirdParty\theseer\Autoload;
interface StaticListRenderer {
/**
* @return string
*/
public function render(array $list);
}

View file

@ -0,0 +1,133 @@
<?php
/**
* Copyright (c) 2009-2019 Arne Blankerts <arne@blankerts.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of Arne Blankerts nor the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* 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 HOLDER ORCONTRIBUTORS
* 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.
*
* @package Autoload
* @author Arne Blankerts <arne@blankerts.de>
* @copyright Arne Blankerts <arne@blankerts.de>, All rights reserved.
* @license BSD License
*/
namespace ncc\ThirdParty\theseer\Autoload {
/**
* Builds static require list for inclusion into projects
*
* @author Arne Blankerts <arne@blankerts.de>
* @copyright Arne Blankerts <arne@blankerts.de>, All rights reserved.
*/
class StaticRenderer extends AutoloadRenderer {
private $dependencies;
private $phar;
private $require = 'require';
/**
* @var StaticListRenderer
*/
private $renderHelper;
public function __construct(array $classlist, StaticListRenderer $renderHelper) {
parent::__construct($classlist);
$this->renderHelper = $renderHelper;
}
/**
* Setter for Dependency Array
* @param array $dep Dependency Array from classfinder
*/
public function setDependencies(Array $dep) {
$this->dependencies = $dep;
}
/**
* Toggle phar outut mode
*
* @param boolean $phar
*/
public function setPharMode($phar) {
$this->phar = (boolean)$phar;
}
/**
* Toggle wether or not to use require_once over require
*
* @param boolean $mode
*/
public function setRequireOnce($mode) {
}
/**
* @param string $template
*
* @return string
*/
public function render($template) {
$baseDir = '';
if ($this->phar) {
$baseDir = "'phar://". $this->variables['___PHAR___']."' . ";
} else if ($this->baseDir) {
$baseDir = $this->compat ? 'dirname(__FILE__) . ' : '__DIR__ . ';
}
$entries = array();
foreach($this->sortByDependency() as $fname) {
$entries[] = $this->resolvePath($fname);
}
$replace = array_merge(
$this->variables,
array(
'___CREATED___' => date( $this->dateformat, $this->timestamp ? $this->timestamp : time()),
'___FILELIST___' => $this->renderHelper->render($entries),
'___BASEDIR___' => $baseDir,
'___AUTOLOAD___' => uniqid('autoload', true)
)
);
return str_replace(array_keys($replace), array_values($replace), $template);
}
/**
* Helper to sort classes/interfaces and traits based on their depdendency info
*
* @return array
*/
protected function sortByDependency() {
$sorter = new ClassDependencySorter($this->classes, $this->dependencies);
$list = $sorter->process();
return array_unique($list);
}
}
}

View file

@ -0,0 +1,34 @@
<?php
namespace ncc\ThirdParty\theseer\Autoload;
class StaticRequireListRenderer implements StaticListRenderer {
/** @var boolean */
private $useOnce;
/** @var string */
private $indent;
/** @var string */
private $linebreak;
/**
* @param $useOnce
*/
public function __construct($useOnce, $indent, $linebreak) {
$this->useOnce = $useOnce;
$this->indent = $indent;
$this->linebreak = $linebreak;
}
/**
* @return string
*/
public function render(array $list) {
$require = (boolean)$this->useOnce ? 'require_once' : 'require';
$require .= ' ___BASEDIR___\'';
$glue = '\';' . $this->linebreak . $this->indent . $require;
return $this->indent . $require . implode($glue, $list) . '\';';
}
}

View file

@ -0,0 +1 @@
1.27.1

View file

@ -0,0 +1,66 @@
<?php
/**
* Copyright (c) 2009-2019 Arne Blankerts <arne@blankerts.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of Arne Blankerts nor the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* 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 HOLDER ORCONTRIBUTORS
* 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.
*
* @package Autoload
* @author Arne Blankerts <arne@blankerts.de>
* @copyright Arne Blankerts <arne@blankerts.de>, All rights reserved.
* @license BSD License
*
*/
namespace ncc\ThirdParty\theseer\Autoload {
class Version {
private static $version = NULL;
public static function getVersion() {
if (self::$version === NULL) {
self::$version = PHPAB_VERSION;
if (PHPAB_VERSION == '%development%') {
$cwd = getcwd();
chdir(__DIR__);
$git = exec('command -p git describe --always --dirty 2>/dev/null', $foo, $rc);
chdir($cwd);
if ($rc === 0) {
self::$version = $git;
}
}
}
return self::$version;
}
public static function getInfoString() {
return 'phpab ' . self::getVersion() . ' - Copyright (C) 2009 - ' . date('Y') . ' by Arne Blankerts and Contributors';
}
}
}

View file

@ -0,0 +1,21 @@
<?php
// @codingStandardsIgnoreFile
// @codeCoverageIgnoreStart
// this is an autogenerated file - do not edit
spl_autoload_register(
function($class) {
static $classes = null;
if ($classes === null) {
$classes = array(
___CLASSLIST___
);
}
$cn = strtolower($class);
if (isset($classes[$cn])) {
require ___BASEDIR___$classes[$cn];
}
},
___EXCEPTION___,
___PREPEND___
);
// @codeCoverageIgnoreEnd

View file

@ -0,0 +1,19 @@
<?php
spl_autoload_register(
function($class) {
static $classes = null;
if ($classes === null) {
$classes = array(
___CLASSLIST___
);
}
$cn = strtolower($class);
if (isset($classes[$cn])) {
require 'phar://___PHAR___' . $classes[$cn];
}
},
___EXCEPTION___,
___PREPEND___
);
Phar::mapPhar('___PHAR___');
__HALT_COMPILER();

View file

@ -0,0 +1,18 @@
<?php
// @codingStandardsIgnoreFile
// @codeCoverageIgnoreStart
// this is an autogenerated file - do not edit
function ___AUTOLOAD___($class) {
static $classes = null;
if ($classes === null) {
$classes = array(
___CLASSLIST___
);
}
$cn = strtolower($class);
if (isset($classes[$cn])) {
require ___BASEDIR___$classes[$cn];
}
}
spl_autoload_register('___AUTOLOAD___', ___EXCEPTION___);
// @codeCoverageIgnoreEnd

View file

@ -0,0 +1,20 @@
<?php
// @codingStandardsIgnoreFile
// @codeCoverageIgnoreStart
// this is an autogenerated file - do not edit
spl_autoload_register(
function($class) {
static $classes = null;
if ($classes === null) {
$classes = array(
___CLASSLIST___
);
}
if (isset($classes[$class])) {
require ___BASEDIR___$classes[$class];
}
},
___EXCEPTION___,
___PREPEND___
);
// @codeCoverageIgnoreEnd

View file

@ -0,0 +1,18 @@
<?php
spl_autoload_register(
function($class) {
static $classes = null;
if ($classes === null) {
$classes = array(
___CLASSLIST___
);
}
if (isset($classes[$class])) {
require 'phar://___PHAR___' . $classes[$class];
}
},
___EXCEPTION___,
___PREPEND___
);
Phar::mapPhar('___PHAR___');
__HALT_COMPILER();

View file

@ -0,0 +1,17 @@
<?php
// @codingStandardsIgnoreFile
// @codeCoverageIgnoreStart
// this is an autogenerated file - do not edit
function ___AUTOLOAD___($class) {
static $classes = null;
if ($classes === null) {
$classes = array(
___CLASSLIST___
);
}
if (isset($classes[$class])) {
require ___BASEDIR___$classes[$class];
}
}
spl_autoload_register('___AUTOLOAD___', ___EXCEPTION___);
// @codeCoverageIgnoreEnd

View file

@ -0,0 +1,6 @@
<?php
// @codingStandardsIgnoreFile
// @codeCoverageIgnoreStart
// this is an autogenerated file - do not edit
___FILELIST___
// @codeCoverageIgnoreEnd

View file

@ -0,0 +1,3 @@
<?php // this is an autogenerated file - do not edit
___FILELIST___
__HALT_COMPILER();

View file

@ -0,0 +1,273 @@
<?php
/**
* Copyright (c) 2009-2014 Arne Blankerts <arne@blankerts.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of Arne Blankerts nor the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* 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 HOLDER ORCONTRIBUTORS
* 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.
*
* @package DirectoryScanner
* @author Arne Blankerts <arne@blankerts.de>
* @copyright Arne Blankerts <arne@blankerts.de>, All rights reserved.
* @license BSD License
* @link http://github.com/theseer/DirectoryScanner
*/
namespace ncc\ThirdParty\theseer\DirectoryScanner {
/**
* Recursive scanner for files on given filesystem path with the ability to filter
* results based on include and exclude patterns
*
* @author Arne Blankerts <arne@blankerts.de>
* @copyright Arne Blankerts <arne@blankerts.de>, All rights reserved.
* @version Release: %version%
*/
class DirectoryScanner {
/**
* List of filter for include shell patterns
*
* @var Array
*/
protected $include = array();
/**
* List of filter for exclude shell patterns
*
* @var Array
*/
protected $exclude = array();
/**
* Flags to pass on to RecursiveDirectoryIterator on construction
*
* @var int
*/
protected $flags = 0;
/**
* Add a new pattern to the include array
*
* @param string $inc Pattern to add
*
* @return void
*/
public function addInclude($inc) {
$this->include[] = $inc;
}
/**
* set the include pattern array
*
* @param Array $inc Array of include pattern strings
*
* @return void
*/
public function setIncludes(array $inc = array()) {
$this->include = $inc;
}
/**
* get array of current include patterns
*
* @return Array
*/
public function getIncludes() {
return $this->include;
}
public function setFlag($flag) {
if (!$this->isValidFlag($flag)) {
throw new Exception("Invalid flag specified", Exception::InvalidFlag);
}
$this->flags = $this->flags | $flag;
}
public function unsetFlag($flag) {
if (!$this->isValidFlag($flag)) {
throw new Exception("Invalid flag specified", Exception::InvalidFlag);
}
$this->flags = $this->flags & ~$flag;
}
/**
* @param boolean $followSymlinks
*
* @deprecated Use setFlag / unsetFlag with \FilesystemIterator::FOLLOW_SYMLINKS
* @return void
*/
public function setFollowSymlinks($followSymlinks) {
if ($followSymlinks == true) {
$this->setFlag(\FilesystemIterator::FOLLOW_SYMLINKS);
return;
}
$this->unsetFlag(\FilesystemIterator::FOLLOW_SYMLINKS);
}
/**
* Public function, so it can be tested properly
*
* @return bool
*/
public function isFollowSymlinks() {
return ($this->flags & \FilesystemIterator::FOLLOW_SYMLINKS) == \FilesystemIterator::FOLLOW_SYMLINKS;
}
/**
* Add a new pattern to the exclude array
*
* @param string $exc Pattern to add
*
* @return void
*/
public function addExclude($exc) {
$this->exclude[] = $exc;
}
/**
* set the exclude pattern array
*
* @param Array $exc Array of exclude pattern strings
*
* @return void
*/
public function setExcludes(array $exc = array()) {
$this->exclude = $exc;
}
/**
* get array of current exclude patterns
*
* @return Array
*/
public function getExcludes() {
return $this->exclude;
}
/**
* get an array of splFileObjects from given path matching the
* include/exclude patterns
*
* @param string $path Path to work on
* @param boolean $recursive Scan recursivly or not
*
* @return Array of splFileInfo Objects
*/
public function getFiles($path, $recursive = true) {
$res = array();
foreach($this->getIterator($path, $recursive) as $entry) {
$res[] = $entry;
}
return $res;
}
/**
* Magic invoker method to use object in foreach-alike constructs as iterator,
* delegating work to getIterator() method
*
* @see getIterator
*
* @param string $path Path to work on
* @param boolean $recursive Scan recursivly or not
*
* @return \Iterator
*/
public function __invoke($path, $recursive = true) {
return $this->getIterator($path, $recursive);
}
/**
* Scan given directory for files, returning splFileObjects matching the include/exclude patterns
*
* @param string $path Path to work on
* @param boolean $recursive Scan recursively or not
*
* @throws Exception
* @return \Iterator
*/
public function getIterator($path, $recursive = true) {
if (!file_exists($path)) {
throw new Exception("Path '$path' does not exist.", Exception::NotFound);
}
if ($recursive) {
$worker = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator(
$path, $this->flags
)
);
} else {
$worker = new \DirectoryIterator($path);
}
$filter = new IncludeExcludeFilterIterator( new FilesOnlyFilterIterator($worker) );
$filter->setInclude( count($this->include) ? $this->include : array('*'));
$filter->setExclude($this->exclude);
return $filter;
}
protected function isValidFlag($flag) {
return in_array($flag, array(
\FilesystemIterator::CURRENT_AS_PATHNAME,
\FilesystemIterator::CURRENT_AS_FILEINFO,
\FilesystemIterator::CURRENT_AS_SELF,
\FilesystemIterator::CURRENT_MODE_MASK,
\FilesystemIterator::KEY_AS_PATHNAME,
\FilesystemIterator::KEY_AS_FILENAME,
\FilesystemIterator::FOLLOW_SYMLINKS,
\FilesystemIterator::KEY_MODE_MASK,
\FilesystemIterator::NEW_CURRENT_AND_KEY,
\FilesystemIterator::SKIP_DOTS,
\FilesystemIterator::UNIX_PATHS
));
}
}
/**
* DirectoryScanner Exception class
*
* @author Arne Blankerts <arne@blankerts.de>
* @copyright Arne Blankerts <arne@blankerts.de>, All rights reserved.
*/
class Exception extends \Exception {
/**
* Error constant for "notFound" condition
*
* @var integer
*/
const NotFound = 1;
/**
* Error condition for invalid flag passed to setFlag/unsetFlag method
*
* @var integer
*/
const InvalidFlag = 2;
}
}

View file

@ -0,0 +1,74 @@
<?php
/**
* Copyright (c) 2009-2014 Arne Blankerts <arne@blankerts.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of Arne Blankerts nor the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* 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 HOLDER ORCONTRIBUTORS
* 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.
*
* @package DirectoryScanner
* @author Arne Blankerts <arne@blankerts.de>
* @copyright Arne Blankerts <arne@blankerts.de>, All rights reserved.
* @license BSD License
*/
namespace ncc\ThirdParty\theseer\DirectoryScanner {
use ReturnTypeWillChange;
/**
* FilterIterator to accept on files from a directory iterator
*
* @author Arne Blankerts <arne@blankerts.de>
* @copyright Arne Blankerts <arne@blankerts.de>, All rights reserved.
* @version Release: %version%
*/
class FilesOnlyFilterIterator extends \FilterIterator {
/**
* FilterIterator Method to decide whether or not to include
* the current item into the list
*
* @return boolean
*/
#[ReturnTypeWillChange]
public function accept() {
switch($this->current()->getType()) {
case 'file': {
return true;
}
case 'link': {
return is_file(realpath($this->current()->getPathname()));
}
default: {
return false;
}
}
}
}
}

View file

@ -0,0 +1,114 @@
<?php
/**
* Copyright (c) 2009-2014 Arne Blankerts <arne@blankerts.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of Arne Blankerts nor the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* 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 HOLDER ORCONTRIBUTORS
* 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.
*
* @package DirectoryScanner
* @author Arne Blankerts <arne@blankerts.de>
* @copyright Arne Blankerts <arne@blankerts.de>, All rights reserved.
* @license BSD License
*/
namespace ncc\ThirdParty\theseer\DirectoryScanner {
use ReturnTypeWillChange;
/**
* FilterIterator to accept Items based on include/exclude conditions
*
* @author Arne Blankerts <arne@blankerts.de>
* @copyright Arne Blankerts <arne@blankerts.de>, All rights reserved.
* @version Release: %version%
*/
class IncludeExcludeFilterIterator extends \FilterIterator {
/**
* List of filter for include shell patterns
*
* @var Array
*/
protected $include;
/**
* List of filter for exclude shell patterns
*
* @var Array
*/
protected $exclude;
/**
* Set and by that overwrite the include filter array
*
* @param Array $inc Array of include pattern strings
*
* @return void
*/
public function setInclude(array $inc = array()) {
$this->include = $inc;
}
/**
* Set and by that overwrite the exclude filter array
*
* @param Array $exc Array of exclude pattern strings
*
* @return void
*/
public function setExclude(array $exc = array()) {
$this->exclude = $exc;
}
/**
* FilterIterator Method to decide whether or not to include
* the current item into the list
*
* @return boolean
*/
#[ReturnTypeWillChange]
public function accept() {
$pathname = $this->current()->getPathname();
foreach($this->exclude as $out) {
if (fnmatch($out, $pathname)) {
return false;
}
}
foreach($this->include as $in) {
if (fnmatch($in, $pathname)) {
return true;
}
}
return false;
}
}
}

View file

@ -0,0 +1,30 @@
DirectoryScanner
Copyright (c) 2009-2014 Arne Blankerts <arne@blankerts.de>
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of Arne Blankerts nor the names of contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
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 HOLDER ORCONTRIBUTORS
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.

View file

@ -0,0 +1,65 @@
<?php
/**
* Copyright (c) 2009-2014 Arne Blankerts <arne@blankerts.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of Arne Blankerts nor the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* 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 HOLDER ORCONTRIBUTORS
* 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.
*
* @package Autoload
* @author Arne Blankerts <arne@blankerts.de>
* @copyright Arne Blankerts <arne@blankerts.de>, All rights reserved.
* @license BSD License
*/
namespace ncc\ThirdParty\theseer\DirectoryScanner {
use ReturnTypeWillChange;
/**
* FilterIterator to accept only php source files based on content
*
* @author Arne Blankerts <arne@blankerts.de>
* @copyright Arne Blankerts <arne@blankerts.de>, All rights reserved.
* @version Release: %version%
*/
class PHPFilterIterator extends \FilterIterator {
/**
* FilterIterator Method to decide whether or not to include
* the current item into the list
*
* @return boolean
*/
#[ReturnTypeWillChange]
public function accept() {
$finfo = new \finfo(FILEINFO_MIME);
return strpos($finfo->file($this->current()->getPathname()), 'text/x-php') === 0;
}
}
}

View file

@ -0,0 +1 @@
1.3.3

View file

@ -22,6 +22,7 @@
$third_party_path . 'Symfony' . DIRECTORY_SEPARATOR . 'Uid' . DIRECTORY_SEPARATOR . 'autoload_spl.php',
$third_party_path . 'Symfony' . DIRECTORY_SEPARATOR . 'Filesystem' . DIRECTORY_SEPARATOR . 'autoload_spl.php',
$third_party_path . 'Symfony' . DIRECTORY_SEPARATOR . 'Yaml' . DIRECTORY_SEPARATOR . 'autoload_spl.php',
$third_party_path . 'theseer' . DIRECTORY_SEPARATOR . 'Autoload' . DIRECTORY_SEPARATOR . 'autoload_spl.php',
];
foreach($target_files as $file)

View file

@ -30,6 +30,14 @@
{
"vendor": "Symfony",
"package_name": "Yaml"
},
{
"vendor": "theseer",
"package_name": "Autoload"
},
{
"vendor": "theseer",
"package_name": "DirectoryScanner"
}
],
"update_source": null