├── docs ├── cover.png ├── images │ ├── logo.png │ ├── icons │ │ ├── home.png │ │ ├── next.png │ │ ├── note.png │ │ ├── prev.png │ │ ├── tip.png │ │ ├── up.png │ │ ├── caution.png │ │ ├── example.png │ │ ├── favicon.ico │ │ ├── important.png │ │ ├── warning.png │ │ ├── callouts │ │ │ ├── 1.png │ │ │ ├── 10.png │ │ │ ├── 11.png │ │ │ ├── 12.png │ │ │ ├── 13.png │ │ │ ├── 14.png │ │ │ ├── 15.png │ │ │ ├── 2.png │ │ │ ├── 3.png │ │ │ ├── 4.png │ │ │ ├── 5.png │ │ │ ├── 6.png │ │ │ ├── 7.png │ │ │ ├── 8.png │ │ │ └── 9.png │ │ ├── font-awesome │ │ │ ├── code.png │ │ │ ├── filter.png │ │ │ ├── square-o.png │ │ │ ├── search-plus.png │ │ │ ├── puzzle-piece.png │ │ │ └── check-square-o.png │ │ └── README │ ├── plantUML_classDiag.png │ └── plantUML_packageDiag.png ├── revision.asciidoc ├── phpreflect-book-docinfo.xml ├── stylesheets │ ├── cover.css │ ├── tocaffix.css │ ├── tocmmenu.css │ ├── ui.totop.css │ └── pygments.monokai.css ├── bootstrap3.conf ├── developer-guide--api.asciidoc ├── attributes.asciidoc ├── themes.json ├── index-jumboinfo.html ├── php_filters.asciidoc ├── loc_analysis.out.asciidoc ├── structure_analysis_filtered.out.asciidoc ├── license.asciidoc ├── phpreflect-book.asciidoc ├── versions.html ├── javascripts │ ├── jquery.ui.totop.min.js │ └── jquery.ui.totop.js ├── migrate_properties.out.asciidoc ├── structure_analysis.out.asciidoc ├── reflection_class.out.asciidoc ├── user-guide.asciidoc ├── build │ ├── html5-bootstrap3.bat │ └── epub.bat ├── developer-guide--handle-results.asciidoc ├── migrate_properties.php.asciidoc ├── navinfo.html ├── footer.html ├── cover.asciidoc ├── developer-guide--source-provider.asciidoc ├── developer-guide--cache-plugin.asciidoc ├── developer-guide--notifier-plugin.asciidoc ├── developer-guide--analysers.asciidoc ├── user-guide--installation.asciidoc └── developer-guide--filters.asciidoc ├── .gitignore ├── tests ├── Analyser │ ├── BarAnalyser.php │ ├── FooAnalyser.php │ └── phpreflect.json ├── fixtures │ ├── packages.php │ ├── properties.php │ ├── functions.php │ ├── constants.php │ ├── namespaces.php │ └── classes.php ├── Environment │ ├── dir1 │ │ └── phpreflect.json.dist │ ├── dir2 │ │ └── phpreflect.json.dist │ ├── phpreflect.json │ └── YourLogger.php ├── bootstrap.php └── Model │ ├── GenericModelTest.php │ └── IssueTest.php ├── bin ├── phpreflect.json.dist ├── phpreflect └── phpreflect.json-schema ├── examples ├── YourNamespace │ ├── YourLogger.php │ ├── LogPlugin.php │ ├── yournamespace.json │ └── CachePlugin.php ├── YourFilters.php ├── api_plugin_list.php ├── api_reflection_class.php ├── api_analyser_run_with_cache.php ├── api_analyser_run_with_listener.php ├── api_analyser_run_with_logger.php ├── api_analyser_run_with_filter.php └── api_analyser_run.php ├── phar-stub.php ├── .editorconfig ├── src └── Bartlett │ └── Reflect │ ├── Event │ ├── SniffEvent.php │ ├── CompleteEvent.php │ ├── BuildEvent.php │ ├── ProgressEvent.php │ ├── ErrorEvent.php │ ├── SuccessEvent.php │ ├── DispatcherInterface.php │ ├── CacheAwareEventDispatcher.php │ └── AbstractDispatcher.php │ ├── Visitor │ └── VisitorInterface.php │ ├── Exception │ ├── Exception.php │ └── ModelException.php │ ├── Api │ ├── Plugin.php │ ├── Diagnose.php │ ├── Config.php │ ├── Cache.php │ ├── V3 │ │ ├── Plugin.php │ │ ├── Diagnose.php │ │ ├── Cache.php │ │ └── Reflection.php │ ├── Diagram.php │ ├── BaseApi.php │ ├── Reflection.php │ └── Analyser.php │ ├── Client │ ├── ClientInterface.php │ └── LocalClient.php │ ├── MonologConsoleLogger.php │ ├── Plugin │ ├── PluginInterface.php │ ├── Notifier │ │ └── NotifierInterface.php │ ├── Cache │ │ ├── DoctrineCacheAdapter.php │ │ ├── CacheStorageInterface.php │ │ └── CacheAdapterInterface.php │ └── PluginManager.php │ ├── Analyser │ ├── AnalyserInterface.php │ └── ReflectionAnalyser.php │ ├── Sniffer │ └── SniffInterface.php │ ├── Console │ ├── Command.php │ └── Formatter │ │ └── OutputFormatter.php │ ├── Output │ ├── Cache.php │ ├── Config.php │ ├── Diagram.php │ ├── Reflection.php │ └── Plugin.php │ ├── PhpParser │ ├── NodeProcessor.php │ └── NodeProcessorAbstract.php │ ├── Util │ └── Timer.php │ ├── Collection │ └── ReflectionCollection.php │ ├── Model │ ├── FunctionModel.php │ ├── AbstractModel.php │ └── ConstantModel.php │ ├── Tokenizer │ └── DefaultTokenizer.php │ └── Client.php ├── phpunit.xml.dist ├── manifest.txt ├── phar-manifest.php ├── LICENSE ├── composer.json ├── box.json.dist └── CHANGELOG.md /docs/cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/llaville/php-reflect/HEAD/docs/cover.png -------------------------------------------------------------------------------- /docs/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/llaville/php-reflect/HEAD/docs/images/logo.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | Thumbs.db 2 | *.tgz 3 | *.log 4 | *.zip 5 | vendor/ 6 | phpunit.xml 7 | composer.lock 8 | .idea -------------------------------------------------------------------------------- /docs/images/icons/home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/llaville/php-reflect/HEAD/docs/images/icons/home.png -------------------------------------------------------------------------------- /docs/images/icons/next.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/llaville/php-reflect/HEAD/docs/images/icons/next.png -------------------------------------------------------------------------------- /docs/images/icons/note.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/llaville/php-reflect/HEAD/docs/images/icons/note.png -------------------------------------------------------------------------------- /docs/images/icons/prev.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/llaville/php-reflect/HEAD/docs/images/icons/prev.png -------------------------------------------------------------------------------- /docs/images/icons/tip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/llaville/php-reflect/HEAD/docs/images/icons/tip.png -------------------------------------------------------------------------------- /docs/images/icons/up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/llaville/php-reflect/HEAD/docs/images/icons/up.png -------------------------------------------------------------------------------- /docs/images/icons/caution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/llaville/php-reflect/HEAD/docs/images/icons/caution.png -------------------------------------------------------------------------------- /docs/images/icons/example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/llaville/php-reflect/HEAD/docs/images/icons/example.png -------------------------------------------------------------------------------- /docs/images/icons/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/llaville/php-reflect/HEAD/docs/images/icons/favicon.ico -------------------------------------------------------------------------------- /docs/images/icons/important.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/llaville/php-reflect/HEAD/docs/images/icons/important.png -------------------------------------------------------------------------------- /docs/images/icons/warning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/llaville/php-reflect/HEAD/docs/images/icons/warning.png -------------------------------------------------------------------------------- /docs/images/icons/callouts/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/llaville/php-reflect/HEAD/docs/images/icons/callouts/1.png -------------------------------------------------------------------------------- /docs/images/icons/callouts/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/llaville/php-reflect/HEAD/docs/images/icons/callouts/10.png -------------------------------------------------------------------------------- /docs/images/icons/callouts/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/llaville/php-reflect/HEAD/docs/images/icons/callouts/11.png -------------------------------------------------------------------------------- /docs/images/icons/callouts/12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/llaville/php-reflect/HEAD/docs/images/icons/callouts/12.png -------------------------------------------------------------------------------- /docs/images/icons/callouts/13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/llaville/php-reflect/HEAD/docs/images/icons/callouts/13.png -------------------------------------------------------------------------------- /docs/images/icons/callouts/14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/llaville/php-reflect/HEAD/docs/images/icons/callouts/14.png -------------------------------------------------------------------------------- /docs/images/icons/callouts/15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/llaville/php-reflect/HEAD/docs/images/icons/callouts/15.png -------------------------------------------------------------------------------- /docs/images/icons/callouts/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/llaville/php-reflect/HEAD/docs/images/icons/callouts/2.png -------------------------------------------------------------------------------- /docs/images/icons/callouts/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/llaville/php-reflect/HEAD/docs/images/icons/callouts/3.png -------------------------------------------------------------------------------- /docs/images/icons/callouts/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/llaville/php-reflect/HEAD/docs/images/icons/callouts/4.png -------------------------------------------------------------------------------- /docs/images/icons/callouts/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/llaville/php-reflect/HEAD/docs/images/icons/callouts/5.png -------------------------------------------------------------------------------- /docs/images/icons/callouts/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/llaville/php-reflect/HEAD/docs/images/icons/callouts/6.png -------------------------------------------------------------------------------- /docs/images/icons/callouts/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/llaville/php-reflect/HEAD/docs/images/icons/callouts/7.png -------------------------------------------------------------------------------- /docs/images/icons/callouts/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/llaville/php-reflect/HEAD/docs/images/icons/callouts/8.png -------------------------------------------------------------------------------- /docs/images/icons/callouts/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/llaville/php-reflect/HEAD/docs/images/icons/callouts/9.png -------------------------------------------------------------------------------- /docs/images/plantUML_classDiag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/llaville/php-reflect/HEAD/docs/images/plantUML_classDiag.png -------------------------------------------------------------------------------- /docs/images/plantUML_packageDiag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/llaville/php-reflect/HEAD/docs/images/plantUML_packageDiag.png -------------------------------------------------------------------------------- /tests/Analyser/BarAnalyser.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PHP Reflect, The Book 6 | 7 | -------------------------------------------------------------------------------- /docs/images/icons/README: -------------------------------------------------------------------------------- 1 | Replaced the plain DocBook XSL admonition icons with Jimmac's DocBook 2 | icons (http://jimmac.musichall.cz/ikony.php3). I dropped transparency 3 | from the Jimmac icons to get round MS IE and FOP PNG incompatibilies. 4 | 5 | Stuart Rackham 6 | -------------------------------------------------------------------------------- /tests/fixtures/packages.php: -------------------------------------------------------------------------------- 1 | $field = new stdClass; 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /bin/phpreflect.json.dist: -------------------------------------------------------------------------------- 1 | { 2 | "source-providers": [ 3 | { 4 | "in": ". as current", 5 | "name": "/\\.(php|inc|phtml)$/" 6 | } 7 | ], 8 | "plugins": [ 9 | ], 10 | "analysers": [ 11 | ], 12 | "services": [ 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/Environment/dir1/phpreflect.json.dist: -------------------------------------------------------------------------------- 1 | { 2 | "source-providers": [ 3 | { 4 | "in": ". as current", 5 | "name": "/\\.(php|inc|phtml)$/" 6 | } 7 | ], 8 | "plugins": [ 9 | ], 10 | "analysers": [ 11 | ], 12 | "services": [ 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/Environment/dir2/phpreflect.json.dist: -------------------------------------------------------------------------------- 1 | { 2 | "source-providers": [ 3 | { 4 | "in": ". as current", 5 | "name": "/\\.(php|inc|phtml)$/" 6 | } 7 | ], 8 | "plugins": [ 9 | ], 10 | "analysers": [ 11 | ], 12 | "services": [ 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /docs/stylesheets/cover.css: -------------------------------------------------------------------------------- 1 | h1#_php_reflect_3 { 2 | margin-top: 20px; 3 | } 4 | 5 | .cover { 6 | height: 30em; 7 | } 8 | 9 | footer { 10 | display: none; 11 | } 12 | 13 | .panels { 14 | margin-top: 5em; 15 | } 16 | 17 | .ulist ul { 18 | list-style-type: none; 19 | padding-left: 1em; 20 | } 21 | -------------------------------------------------------------------------------- /examples/YourNamespace/YourLogger.php: -------------------------------------------------------------------------------- 1 | .toc-top-link, 14 | h3#about-us > .toc-top-link, 15 | h3.panel-title > .toc-top-link { 16 | display: none; 17 | } 18 | 19 | /* command-line output decorator */ 20 | .output pre { 21 | background-color: #202020; 22 | border: 4px solid olive; 23 | color: #ccc; 24 | } 25 | -------------------------------------------------------------------------------- /docs/attributes.asciidoc: -------------------------------------------------------------------------------- 1 | :author: Laurent Laville 2 | :keywords: PHP, reverse-engineer, reflection 3 | :mandir: http://php5.laurent-laville.org/reflect/manual/current 4 | :brand: PHP Reflect 5 | :brandref: http://php5.laurent-laville.org/reflect/ 6 | :brandver: 7 | :navinfo1: 8 | :icons!: 9 | :iconsfont: font-awesome 10 | :imagesdir: ./images 11 | :idprefix: _ 12 | :gitbranch: master 13 | :rawbaseurl: https://raw.githubusercontent.com/llaville/php-reflect/{gitbranch} 14 | :gitproject: https://github.com/llaville/php-reflect 15 | -------------------------------------------------------------------------------- /tests/Analyser/phpreflect.json: -------------------------------------------------------------------------------- 1 | { 2 | "source-providers": [ 3 | { 4 | "in": ". as current", 5 | "name": "/\\.(php|inc|phtml)$/" 6 | } 7 | ], 8 | "plugins": [ 9 | ], 10 | "analysers" : [ 11 | { 12 | "name": "ValidAnalyser", 13 | "class": "Bartlett\\Tests\\Reflect\\Analyser\\FooAnalyser" 14 | }, 15 | { 16 | "name": "InvalidAnalyser", 17 | "class": "Bartlett\\Tests\\Reflect\\Analyser\\BarAnalyser" 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /docs/themes.json: -------------------------------------------------------------------------------- 1 | { 2 | "themes": 3 | [ 4 | {"name": "Default", "cssCdn": "stylesheets/asciidoc-bootstrap.min.css"}, 5 | {"name": "Cerulean", "cssCdn": "stylesheets/asciidoc-bootstrap.cerulean.min.css"}, 6 | {"name": "Flatly", "cssCdn": "stylesheets/asciidoc-bootstrap.flatly.min.css"}, 7 | {"name": "Readable", "cssCdn": "stylesheets/asciidoc-bootstrap.readable.min.css"}, 8 | {"name": "Sandstone", "cssCdn": "stylesheets/asciidoc-bootstrap.sandstone.min.css"}, 9 | {"name": "United", "cssCdn": "stylesheets/asciidoc-bootstrap.united.min.css"} 10 | ] 11 | } -------------------------------------------------------------------------------- /docs/index-jumboinfo.html: -------------------------------------------------------------------------------- 1 |
2 |

PHP Reflect

3 |

Reverse-engineer classes, interfaces, functions, constants, namespaces and more.

4 |
5 |
6 | 10 |
11 | -------------------------------------------------------------------------------- /examples/YourNamespace/LogPlugin.php: -------------------------------------------------------------------------------- 1 | 9 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 10 | * @since Class available since Release 4.4.0 11 | */ 12 | 13 | namespace Bartlett\Reflect\Event; 14 | 15 | use Symfony\Component\EventDispatcher\GenericEvent; 16 | 17 | /** 18 | * The SNIFF event allows you to learn what are sniff processes during AST traverse. 19 | */ 20 | class SniffEvent extends GenericEvent 21 | { 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/Bartlett/Reflect/Visitor/VisitorInterface.php: -------------------------------------------------------------------------------- 1 | 9 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 10 | */ 11 | 12 | namespace Bartlett\Reflect\Visitor; 13 | 14 | /** 15 | * Interface that all analysers using sniffs must implement. 16 | */ 17 | interface VisitorInterface 18 | { 19 | public function setUpBeforeVisitor(): void; 20 | public function tearDownAfterVisitor(): void; 21 | } 22 | -------------------------------------------------------------------------------- /tests/fixtures/constants.php: -------------------------------------------------------------------------------- 1 | addClassMap( 8 | array( 9 | 'Bartlett\Tests\Reflect\Analyser\FooAnalyser' 10 | => __DIR__ . '/Analyser/FooAnalyser.php', 11 | 'Bartlett\Tests\Reflect\Analyser\BarAnalyser' 12 | => __DIR__ . '/Analyser/BarAnalyser.php', 13 | 'Bartlett\Tests\Reflect\Model\GenericModelTest' 14 | => __DIR__ . '/Model/GenericModelTest.php', 15 | 'Bartlett\Tests\Reflect\Environment\YourLogger' 16 | => __DIR__ . '/Environment/YourLogger.php', 17 | ) 18 | ); 19 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 14 | 15 | 16 | src/ 17 | 18 | 19 | 20 | 21 | tests/ 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /examples/YourNamespace/yournamespace.json: -------------------------------------------------------------------------------- 1 | { 2 | "source-providers": [ 3 | ], 4 | "plugins": [ 5 | { 6 | "name": "Cache", 7 | "class": "YourNamespace\\CachePlugin", 8 | "options": { 9 | "backend": { 10 | "class": "Doctrine\\Common\\Cache\\SQLite3Cache", 11 | "args": [ 12 | "%{TEMP}/bartlett/cache/your_db_cache.sqlite", 13 | "your_table" 14 | ] 15 | } 16 | } 17 | }, 18 | { 19 | "name": "Logger", 20 | "class": "YourNamespace\\LogPlugin" 21 | } 22 | ], 23 | "analysers" : [ 24 | ], 25 | "services": [ 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /src/Bartlett/Reflect/Exception/Exception.php: -------------------------------------------------------------------------------- 1 | 11 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 12 | */ 13 | 14 | namespace Bartlett\Reflect\Exception; 15 | 16 | /** 17 | * Base Reflect Exception. 18 | * 19 | * @category PHP 20 | * @package PHP_Reflect 21 | * @author Laurent Laville 22 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 23 | * @since Class available since Release 2.0.0RC1 24 | */ 25 | abstract class Exception extends \Exception 26 | { 27 | } 28 | -------------------------------------------------------------------------------- /src/Bartlett/Reflect/Exception/ModelException.php: -------------------------------------------------------------------------------- 1 | 11 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 12 | */ 13 | 14 | namespace Bartlett\Reflect\Exception; 15 | 16 | /** 17 | * Exception on building Model objects. 18 | * 19 | * @category PHP 20 | * @package PHP_Reflect 21 | * @author Laurent Laville 22 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 23 | * @since Class available since Release 2.0.0RC1 24 | */ 25 | class ModelException extends Exception 26 | { 27 | } 28 | -------------------------------------------------------------------------------- /src/Bartlett/Reflect/Event/CompleteEvent.php: -------------------------------------------------------------------------------- 1 | 9 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 10 | * @since Class available since Release 4.4.0 11 | */ 12 | 13 | namespace Bartlett\Reflect\Event; 14 | 15 | use Symfony\Component\EventDispatcher\GenericEvent; 16 | 17 | /** 18 | * The COMPLETE event allows you to be notified when a data source parsing 19 | * is over. 20 | * 21 | * The event listener method receives a Symfony\Component\EventDispatcher\GenericEvent 22 | * instance with following arguments : 23 | * - `source` data source identifier 24 | */ 25 | class CompleteEvent extends GenericEvent 26 | { 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/Bartlett/Reflect/Event/BuildEvent.php: -------------------------------------------------------------------------------- 1 | 9 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 10 | * @since Class available since Release 4.4.0 11 | */ 12 | 13 | namespace Bartlett\Reflect\Event; 14 | 15 | use Symfony\Component\EventDispatcher\GenericEvent; 16 | 17 | /** 18 | * The BUILD event allows you to learn what are processes applied during AST building. 19 | * 20 | * The event listener method receives a Symfony\Component\EventDispatcher\GenericEvent 21 | * instance with following arguments : 22 | * - `method` current process 23 | * - `node` current node visited 24 | */ 25 | class BuildEvent extends GenericEvent 26 | { 27 | 28 | } 29 | -------------------------------------------------------------------------------- /bin/phpreflect: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | setUseIncludePath(true); 21 | 22 | if (PHP_SAPI !== 'cli') { 23 | return; 24 | } 25 | 26 | use Bartlett\Reflect\Environment; 27 | use Bartlett\Reflect\Console\Application; 28 | 29 | Environment::setScanDir(); 30 | 31 | $application = new Application($appName, '4.4.1'); 32 | $application->run(); 33 | -------------------------------------------------------------------------------- /docs/php_filters.asciidoc: -------------------------------------------------------------------------------- 1 | &$keys) { 13 | if (strpos($title, 'StructureAnalyser') === false) { 14 | continue; 15 | } 16 | // looking into Structure Analyser metrics only 17 | foreach ($keys as $key => $val) { 18 | if (!in_array($key, $filterOnKeys)) { 19 | unset($keys[$key]); // "removed" unsolicited values 20 | continue; 21 | } 22 | } 23 | } 24 | return $data; 25 | }; 26 | 27 | return $closure; 28 | -------------------------------------------------------------------------------- /examples/YourFilters.php: -------------------------------------------------------------------------------- 1 | &$keys) { 13 | if (strpos($title, 'StructureAnalyser') === false) { 14 | continue; 15 | } 16 | // looking into Structure Analyser metrics only 17 | foreach ($keys as $key => $val) { 18 | if (!in_array($key, $filterOnKeys)) { 19 | unset($keys[$key]); // "removed" unsolicited values 20 | continue; 21 | } 22 | } 23 | } 24 | return $data; 25 | }; 26 | 27 | return $closure; 28 | -------------------------------------------------------------------------------- /examples/api_plugin_list.php: -------------------------------------------------------------------------------- 1 | 8 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 9 | * @since Example available since Release 3.0.0-alpha3+1 10 | */ 11 | require_once dirname(__DIR__) . '/vendor/autoload.php'; 12 | 13 | use Bartlett\Reflect\Client; 14 | use Bartlett\Reflect\Environment; 15 | 16 | // defines environment where to find the JSON config file 17 | if (!getenv("BARTLETTRC")) { 18 | putenv("BARTLETTRC=phpreflect.json"); 19 | } 20 | Environment::setScanDir(); 21 | 22 | // creates an instance of client 23 | $client = new Client(); 24 | 25 | // request for a Bartlett\Reflect\Api\Plugin 26 | $api = $client->api('plugin'); 27 | 28 | $plugins = $api->dir(); 29 | 30 | print_r($plugins); 31 | -------------------------------------------------------------------------------- /examples/api_reflection_class.php: -------------------------------------------------------------------------------- 1 | 8 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 9 | * @since Example available since Release 3.0.0-alpha3+1 10 | */ 11 | 12 | require_once dirname(__DIR__) . '/vendor/autoload.php'; 13 | 14 | use Bartlett\Reflect\Client; 15 | 16 | // creates an instance of client 17 | $client = new Client(); 18 | 19 | // request for a Bartlett\Reflect\Api\Reflection 20 | $api = $client->api('reflection'); 21 | 22 | // perform request, on a data source 23 | $dataSource = dirname(__DIR__) . '/src'; 24 | 25 | // equivalent to CLI command `phpreflect reflection:class Bartlett\Reflect ../src` 26 | $model = $api->class('Bartlett\\Reflect', $dataSource); 27 | 28 | echo $model; 29 | -------------------------------------------------------------------------------- /src/Bartlett/Reflect/Event/ProgressEvent.php: -------------------------------------------------------------------------------- 1 | 9 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 10 | * @since Class available since Release 4.4.0 11 | */ 12 | 13 | namespace Bartlett\Reflect\Event; 14 | 15 | use Symfony\Component\EventDispatcher\GenericEvent; 16 | 17 | /** 18 | * The PROGRESS event allows you to know what file of the data source 19 | * is ready to be parsed. 20 | * 21 | * The event listener method receives a Symfony\Component\EventDispatcher\GenericEvent 22 | * instance with following arguments : 23 | * - `source` data source identifier 24 | * - `file` current file parsed in the data source 25 | */ 26 | class ProgressEvent extends GenericEvent 27 | { 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/Bartlett/Reflect/Event/ErrorEvent.php: -------------------------------------------------------------------------------- 1 | 9 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 10 | * @since Class available since Release 4.4.0 11 | */ 12 | 13 | namespace Bartlett\Reflect\Event; 14 | 15 | use Symfony\Component\EventDispatcher\GenericEvent; 16 | 17 | /** 18 | * The ERROR event allows you to learn more about PHP-Parser error raised. 19 | * 20 | * The event listener method receives a Symfony\Component\EventDispatcher\GenericEvent 21 | * instance with following arguments : 22 | * - `source` data source identifier 23 | * - `file` current file parsed in the data source 24 | * - `error` PHP Parser error message 25 | */ 26 | class ErrorEvent extends GenericEvent 27 | { 28 | 29 | } 30 | -------------------------------------------------------------------------------- /docs/stylesheets/ui.totop.css: -------------------------------------------------------------------------------- 1 | /* 2 | |-------------------------------------------------------------------------- 3 | | UItoTop jQuery Plugin 1.2 4 | | http://www.mattvarone.com/web-design/uitotop-jquery-plugin/ 5 | |-------------------------------------------------------------------------- 6 | */ 7 | 8 | #toTop { 9 | display:none; 10 | text-decoration:none; 11 | position:fixed; 12 | bottom:10px; 13 | right:10px; 14 | overflow:hidden; 15 | width:51px; 16 | height:51px; 17 | border:none; 18 | text-indent:100%; 19 | background:url(../images/icons/ui.totop.png) no-repeat left top; 20 | } 21 | 22 | #toTopHover { 23 | background:url(../images/icons/ui.totop.png) no-repeat left -51px; 24 | width:51px; 25 | height:51px; 26 | display:block; 27 | overflow:hidden; 28 | float:left; 29 | opacity: 0; 30 | -moz-opacity: 0; 31 | filter:alpha(opacity=0); 32 | } 33 | 34 | #toTop:active, #toTop:focus { 35 | outline:none; 36 | } -------------------------------------------------------------------------------- /src/Bartlett/Reflect/Api/Plugin.php: -------------------------------------------------------------------------------- 1 | 11 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 12 | */ 13 | 14 | namespace Bartlett\Reflect\Api; 15 | 16 | /** 17 | * Identify all plugins available 18 | * 19 | * @category PHP 20 | * @package PHP_Reflect 21 | * @author Laurent Laville 22 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 23 | * @since Class available since Release 3.0.0-alpha1 24 | */ 25 | class Plugin extends BaseApi 26 | { 27 | /** 28 | * List all plugins installed. 29 | * 30 | * @return array 31 | * @alias list 32 | */ 33 | public function dir() 34 | { 35 | return $this->request('plugin/list'); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /docs/loc_analysis.out.asciidoc: -------------------------------------------------------------------------------- 1 | 2 | Data Source Analysed 3 | 4 | Directories 22 5 | Files 77 6 | 7 | Size 8 | Lines of Code (LOC) 3832 9 | Comment Lines of Code (CLOC) 137 (3.58%) 10 | Non-Comment Lines of Code (NCLOC) 3695 (96.42%) 11 | Logical Lines of Code (LLOC) 1210 (31.58%) 12 | Classes 1142 (94.38%) 13 | Average Class Length 17 14 | Average Method Length 3 15 | Functions 68 (5.62%) 16 | Average Function Length 6 17 | Not in classes or functions 0 (0.00%) 18 | 19 | Complexity 20 | Cyclomatic Complexity / LLOC 0.53 21 | Cyclomatic Complexity / Number of Methods 2.73 22 | -------------------------------------------------------------------------------- /src/Bartlett/Reflect/Client/ClientInterface.php: -------------------------------------------------------------------------------- 1 | 9 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 10 | */ 11 | 12 | namespace Bartlett\Reflect\Client; 13 | 14 | /** 15 | * Client Interface 16 | * 17 | * @category PHP 18 | * @package PHP_Reflect 19 | * @author Laurent Laville 20 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 21 | * @since Class available since Release 3.0.0-alpha2 22 | */ 23 | interface ClientInterface 24 | { 25 | /** 26 | * Performs a Request to the API Endpoint 27 | * 28 | * @param string $method 29 | * @param string $url 30 | * @param array $params 31 | */ 32 | public function request(string $method, string $url, array $params = array()); 33 | } 34 | -------------------------------------------------------------------------------- /src/Bartlett/Reflect/Event/SuccessEvent.php: -------------------------------------------------------------------------------- 1 | 9 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 10 | * @since Class available since Release 4.4.0 11 | */ 12 | 13 | namespace Bartlett\Reflect\Event; 14 | 15 | use Symfony\Component\EventDispatcher\GenericEvent; 16 | 17 | /** 18 | * The SUCCESS event allows you to get the AST (Abstract Syntax Tree) 19 | * from a live request. A cached request will not trigger this event. 20 | * 21 | * The event listener method receives a Symfony\Component\EventDispatcher\GenericEvent 22 | * instance with following arguments : 23 | * - `source` data source identifier 24 | * - `file` current file parsed in the data source 25 | * - `ast` the Abstract Syntax Tree result (serialized) 26 | */ 27 | class SuccessEvent extends GenericEvent 28 | { 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/Bartlett/Reflect/MonologConsoleLogger.php: -------------------------------------------------------------------------------- 1 | setFilenameFormat('{filename}-{date}', 'Ymd'); 22 | 23 | $handlers = array($stream); 24 | 25 | $processors = array( 26 | new PsrLogMessageProcessor(), 27 | ); 28 | 29 | parent::__construct($name, $handlers, $processors); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Bartlett/Reflect/Api/Diagnose.php: -------------------------------------------------------------------------------- 1 | 11 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 12 | */ 13 | 14 | namespace Bartlett\Reflect\Api; 15 | 16 | /** 17 | * Diagnoses the system to identify common errors. 18 | * 19 | * @category PHP 20 | * @package PHP_Reflect 21 | * @author Laurent Laville 22 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 23 | * @since Class available since Release 3.0.0-RC1 24 | */ 25 | class Diagnose extends BaseApi 26 | { 27 | /** 28 | * Diagnoses the system to identify common errors. 29 | * 30 | * @return array 31 | */ 32 | public function run() 33 | { 34 | return $this->request('diagnose/run'); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /docs/structure_analysis_filtered.out.asciidoc: -------------------------------------------------------------------------------- 1 | 2 | Data Source Analysed 3 | 4 | Directories 22 5 | Files 77 6 | 7 | Structure 8 | Namespaces 22 9 | Interfaces 10 10 | Traits 0 11 | Classes 67 12 | Abstract Classes 8 (11.94%) 13 | Concrete Classes 59 (88.06%) 14 | Functions 11 15 | Named Functions 0 (0.00%) 16 | Anonymous Functions 11 (100.00%) 17 | Constants 21 18 | Global Constants 0 (0.00%) 19 | Magic Constants 3 (14.29%) 20 | Class Constants 18 (85.71%) 21 | -------------------------------------------------------------------------------- /docs/license.asciidoc: -------------------------------------------------------------------------------- 1 | = License 2 | :description: The full details of how Reflect is licensed. 3 | :jumbotron: 4 | :icons!: 5 | :iconsfont: font-awesome 6 | :iconsfontdir: ./fonts/font-awesome 7 | include::revision.asciidoc[] 8 | include::attributes.asciidoc[] 9 | 10 | [role="lead"] 11 | [label label-primary]#Reflect# is open source. 12 | You can use it for commercial projects, and open source projects. 13 | 14 | == Documentation Licence 15 | 16 | All documentation files (extension +.asciidoc+) provided in +docs+ folder are 17 | in http://asciidoc.org[AsciiDoc] format. They are built with a Python AsciiDoc backend 18 | maintained by myself, that convert output to an html http:/getbootstrap.com[Bootstrap] renders. 19 | http://laurent-laville.org/asciidoc/bootstrap/manual/current/en/[AsciiDoc-Bootstrap] 20 | is released under the http://www.apache.org/licenses/LICENSE-2.0.html[Apache 2] license. 21 | 22 | == Source License 23 | 24 | As previous API 1.0, the source code is still under the 25 | http://opensource.org/licenses/BSD-3-Clause[BSD 3-Clause] license. 26 | -------------------------------------------------------------------------------- /examples/YourNamespace/CachePlugin.php: -------------------------------------------------------------------------------- 1 | 11 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 12 | */ 13 | 14 | namespace Bartlett\Reflect\Plugin; 15 | 16 | use Symfony\Component\EventDispatcher\EventDispatcherInterface; 17 | 18 | /** 19 | * Interface that all plugins must implement. 20 | * 21 | * @category PHP 22 | * @package PHP_Reflect 23 | * @author Laurent Laville 24 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 25 | * @since Class available since Release 3.0.0-alpha1 26 | */ 27 | interface PluginInterface 28 | { 29 | /** 30 | * Announce plugin activation 31 | * 32 | * @param EventDispatcherInterface $eventDispatcher Instance of the event 33 | * dispatcher 34 | * 35 | * @return void 36 | */ 37 | public function activate(EventDispatcherInterface $eventDispatcher): void; 38 | } 39 | -------------------------------------------------------------------------------- /docs/phpreflect-book.asciidoc: -------------------------------------------------------------------------------- 1 | = PHP Reflect Book 2 | :description: The Complete Guide 3 | include::revision.asciidoc[] 4 | include::attributes.asciidoc[] 5 | 6 | [preface] 7 | -- 8 | This complete guide documents {brand} {revnumber}, published on {revdate}. 9 | 10 | This work is licensed under the http://creativecommons.org/licenses/by-sa/3.0/[Attribution-Share Alike 3.0 Unported] license. 11 | -- 12 | 13 | include::getting-started.asciidoc[] 14 | 15 | include::user-guide.asciidoc[] 16 | include::user-guide--installation.asciidoc[] 17 | include::user-guide--configuration.asciidoc[] 18 | include::user-guide--commands.asciidoc[] 19 | 20 | include::migration-guide-20.asciidoc[] 21 | 22 | include::migration-guide-30.asciidoc[] 23 | 24 | include::developer-guide.asciidoc[] 25 | :leveloffset: 1 26 | include::api-compared.asciidoc[] 27 | 28 | include::developer-guide--api.asciidoc[] 29 | 30 | include::developer-guide--plugins.asciidoc[] 31 | 32 | include::developer-guide--cache-plugin.asciidoc[] 33 | 34 | include::developer-guide--log-plugin.asciidoc[] 35 | 36 | include::developer-guide--notifier-plugin.asciidoc[] 37 | 38 | include::developer-guide--analysers.asciidoc[] 39 | 40 | include::developer-guide--filters.asciidoc[] 41 | :leveloffset: 0 42 | -------------------------------------------------------------------------------- /docs/versions.html: -------------------------------------------------------------------------------- 1 |
  • current
  • 2 |
  • 4.2
  • 3 |
  • 4.1
  • 4 |
  • 4.0
  • 5 |
  • 3.1
  • 6 |
  • 3.0
  • 7 |
  • 2.6
  • 8 |
  • 2.5
  • 9 |
  • 2.4
  • 10 |
  • 2.3
  • 11 |
  • 2.2
  • 12 |
  • 2.1
  • 13 |
  • 2.0
  • 14 |
  • 1.9
  • 15 | -------------------------------------------------------------------------------- /docs/javascripts/jquery.ui.totop.min.js: -------------------------------------------------------------------------------- 1 | /* UItoTop jQuery Plugin 1.2 | Matt Varone | http://www.mattvarone.com/web-design/uitotop-jquery-plugin */ 2 | (function($){$.fn.UItoTop=function(options){var defaults={text:'To Top',min:200,inDelay:600,outDelay:400,containerID:'toTop',containerHoverID:'toTopHover',scrollSpeed:1200,easingType:'linear'},settings=$.extend(defaults,options),containerIDhash='#'+settings.containerID,containerHoverIDHash='#'+settings.containerHoverID;$('body').append(''+settings.text+'');$(containerIDhash).hide().on('click.UItoTop',function(){$('html, body').animate({scrollTop:0},settings.scrollSpeed,settings.easingType);$('#'+settings.containerHoverID,this).stop().animate({'opacity':0},settings.inDelay,settings.easingType);return false;}).prepend('').hover(function(){$(containerHoverIDHash,this).stop().animate({'opacity':1},600,'linear');},function(){$(containerHoverIDHash,this).stop().animate({'opacity':0},700,'linear');});$(window).scroll(function(){var sd=$(window).scrollTop();if(typeof document.body.style.maxHeight==="undefined"){$(containerIDhash).css({'position':'absolute','top':sd+$(window).height()-50});} 3 | if(sd>settings.min) 4 | $(containerIDhash).fadeIn(settings.inDelay);else 5 | $(containerIDhash).fadeOut(settings.Outdelay);});};})(jQuery); -------------------------------------------------------------------------------- /examples/api_analyser_run_with_cache.php: -------------------------------------------------------------------------------- 1 | 8 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 9 | * @since Example available since Release 3.0.0-beta2 10 | */ 11 | 12 | $loader = require_once dirname(__DIR__) . '/vendor/autoload.php'; 13 | $loader->addClassMap( 14 | array( 15 | 'YourNamespace\CachePlugin' 16 | => __DIR__ . '/YourNamespace/CachePlugin.php', 17 | ) 18 | ); 19 | 20 | use Bartlett\Reflect\Client; 21 | 22 | // set our own location of JSON config file 23 | putenv("BARTLETT_SCAN_DIR=" . __DIR__ . '/YourNamespace'); 24 | 25 | // set our own JSON config file 26 | putenv("BARTLETTRC=yournamespace.json"); 27 | 28 | // creates an instance of client 29 | $client = new Client(); 30 | 31 | // request for a Bartlett\Reflect\Api\Analyser 32 | $api = $client->api('analyser'); 33 | 34 | // perform request, on a data source with default analyser (structure) 35 | $dataSource = dirname(__DIR__) . '/src'; 36 | $analysers = array('structure'); 37 | 38 | // equivalent to CLI command `phpreflect analyser:run ../src` 39 | $metrics = $api->run($dataSource, $analysers); 40 | 41 | var_export($metrics); 42 | -------------------------------------------------------------------------------- /manifest.txt: -------------------------------------------------------------------------------- 1 | bartlett/php-reflect: 4.4.0 2 | doctrine/collections: 1.6.5 3 | justinrainbow/json-schema: 5.2.10 4 | nikic/php-parser: v3.1.5 5 | phpdocumentor/reflection-common: 1.0.1 6 | phpdocumentor/reflection-docblock: 4.3.4 7 | phpdocumentor/type-resolver: 0.5.1 8 | psr/container: 1.0.0 9 | psr/event-dispatcher: 1.0.0 10 | psr/log: 1.1.3 11 | sebastian/version: 2.0.1 12 | seld/jsonlint: 1.8.0 13 | symfony/console: v5.1.2 14 | symfony/dependency-injection: v5.1.2 15 | symfony/deprecation-contracts: v2.1.2 16 | symfony/event-dispatcher: v5.1.2 17 | symfony/event-dispatcher-contracts: v2.1.2 18 | symfony/finder: v5.1.2 19 | symfony/polyfill-ctype: v1.17.1 20 | symfony/polyfill-intl-grapheme: v1.17.1 21 | symfony/polyfill-intl-normalizer: v1.17.1 22 | symfony/polyfill-mbstring: v1.17.1 23 | symfony/polyfill-php73: v1.17.1 24 | symfony/polyfill-php80: v1.17.1 25 | symfony/service-contracts: v2.1.2 26 | symfony/stopwatch: v5.1.2 27 | symfony/string: v5.1.2 28 | webmozart/assert: 1.9.0 29 | monolog/monolog: 1.25.4 30 | -------------------------------------------------------------------------------- /src/Bartlett/Reflect/Analyser/AnalyserInterface.php: -------------------------------------------------------------------------------- 1 | 9 | * @license http://www.opensource.org/licenses/bsd-license.php BSD License 10 | */ 11 | 12 | namespace Bartlett\Reflect\Analyser; 13 | 14 | use Bartlett\Reflect; 15 | 16 | /** 17 | * Interface that all analysers must implement. 18 | * 19 | * @category PHP 20 | * @package PHP_Reflect 21 | * @author Laurent Laville 22 | * @license http://www.opensource.org/licenses/bsd-license.php BSD License 23 | * @since Class available since Release 2.0.0RC2 24 | */ 25 | interface AnalyserInterface 26 | { 27 | public function getSubject(): Reflect; 28 | 29 | public function getCurrentFile(): string; 30 | 31 | public function getTokens(): array; 32 | 33 | public function setSubject(Reflect $reflect): void; 34 | 35 | public function setTokens(array $tokens): void; 36 | 37 | public function setCurrentFile(string $path): void; 38 | 39 | public function getMetrics(): array; 40 | 41 | public function getName(): string; 42 | 43 | public function getNamespace(): string; 44 | 45 | public function getShortName(): string; 46 | } 47 | -------------------------------------------------------------------------------- /src/Bartlett/Reflect/Api/Config.php: -------------------------------------------------------------------------------- 1 | 11 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 12 | */ 13 | 14 | namespace Bartlett\Reflect\Api; 15 | 16 | /** 17 | * Validates structure of the JSON configuration file. 18 | * 19 | * @category PHP 20 | * @package PHP_Reflect 21 | * @author Laurent Laville 22 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 23 | * @since Class available since Release 3.0.0-alpha1 24 | */ 25 | class Config extends BaseApi 26 | { 27 | /** 28 | * Validates a JSON configuration file. 29 | * 30 | * @param string $file Path to {json} file 31 | * 32 | * @return array json data found 33 | * @throws \RuntimeException if configuration file 34 | * does not exists or not readable 35 | * @throws \Seld\JsonLint\ParsingException if configuration file is invalid format 36 | */ 37 | public function validate($file) 38 | { 39 | return $this->request('config/validate', 'GET', array($file)); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /examples/api_analyser_run_with_listener.php: -------------------------------------------------------------------------------- 1 | 8 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 9 | * @since Example available since Release 3.0.0-beta2 10 | */ 11 | 12 | require_once dirname(__DIR__) . '/vendor/autoload.php'; 13 | 14 | use Bartlett\Reflect\Client; 15 | 16 | use Symfony\Component\EventDispatcher\GenericEvent; 17 | 18 | // creates an instance of client 19 | $client = new Client(); 20 | 21 | // request for a Bartlett\Reflect\Api\Analyser 22 | $api = $client->api('analyser'); 23 | 24 | $dispatcher = $api->getEventDispatcher(); 25 | 26 | $dispatcher->addListener( 27 | 'reflect.progress', 28 | function (GenericEvent $e) { 29 | printf( 30 | 'Parsing Data source "%s" in progress ... File "%s"' . PHP_EOL, 31 | $e['source'], 32 | $e['file']->getPathname() 33 | ); 34 | } 35 | ); 36 | 37 | // perform request, on a data source with default analyser (structure) 38 | $dataSource = dirname(__DIR__) . '/src'; 39 | $analysers = array('structure'); 40 | 41 | // equivalent to CLI command `phpreflect analyser:run ../src` 42 | $metrics = $api->run($dataSource, $analysers); 43 | 44 | var_export($metrics); 45 | -------------------------------------------------------------------------------- /src/Bartlett/Reflect/Sniffer/SniffInterface.php: -------------------------------------------------------------------------------- 1 | 9 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 10 | */ 11 | 12 | namespace Bartlett\Reflect\Sniffer; 13 | 14 | use Bartlett\Reflect\Visitor\VisitorInterface; 15 | 16 | use PhpParser\NodeVisitor; 17 | 18 | /** 19 | * Interface that all sniffs must implement. 20 | * 21 | * @category PHP 22 | * @package PHP_Reflect 23 | * @author Laurent Laville 24 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 25 | * @since Class available since Release 4.0.0 26 | */ 27 | interface SniffInterface extends NodeVisitor 28 | { 29 | // inherit NodeVisitor interface 30 | // --- 31 | // public function beforeTraverse(array $nodes); 32 | // public function enterNode(Node $node); 33 | // public function leaveNode(Node $node); 34 | // public function afterTraverse(array $nodes); 35 | 36 | public function setUpBeforeSniff(): void; 37 | public function enterSniff(): void; 38 | public function leaveSniff(): void; 39 | public function tearDownAfterSniff(): void; 40 | public function setVisitor(VisitorInterface $visitor): void; 41 | } 42 | -------------------------------------------------------------------------------- /src/Bartlett/Reflect/Console/Command.php: -------------------------------------------------------------------------------- 1 | 11 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 12 | */ 13 | 14 | namespace Bartlett\Reflect\Console; 15 | 16 | use Symfony\Component\Console\Command\Command as BaseCommand; 17 | 18 | /** 19 | * Base class for all commands. 20 | * 21 | * @category PHP 22 | * @package PHP_Reflect 23 | * @author Laurent Laville 24 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 25 | * @since Class available since Release 3.0.0-alpha1 26 | */ 27 | class Command extends BaseCommand 28 | { 29 | protected $enabled = true; 30 | 31 | /** 32 | * Disables the command in the current environment 33 | * 34 | * @return Command The current instance 35 | */ 36 | public function disable(): self 37 | { 38 | $this->enabled = false; 39 | return $this; 40 | } 41 | 42 | /** 43 | * Checks whether the command is enabled or not in the current environment 44 | * 45 | * @return bool 46 | */ 47 | public function isEnabled(): bool 48 | { 49 | return $this->enabled; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Bartlett/Reflect/Output/Cache.php: -------------------------------------------------------------------------------- 1 | 9 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 10 | */ 11 | 12 | namespace Bartlett\Reflect\Output; 13 | 14 | use Bartlett\Reflect\Console\Formatter\OutputFormatter; 15 | 16 | use Symfony\Component\Console\Output\OutputInterface; 17 | 18 | /** 19 | * Cache results default render on console 20 | * 21 | * @category PHP 22 | * @package PHP_Reflect 23 | * @author Laurent Laville 24 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 25 | * @since Class available since Release 3.0.0-alpha1 26 | */ 27 | class Cache extends OutputFormatter 28 | { 29 | /** 30 | * Cache clear results 31 | * 32 | * @param OutputInterface $output Console Output concrete instance 33 | * @param array $response Render cache:clear command 34 | * 35 | * @return void 36 | */ 37 | public function clear(OutputInterface $output, array $response): void 38 | { 39 | $output->writeln( 40 | sprintf( 41 | '%d cache entries cleared', 42 | $response 43 | ) 44 | ); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /examples/api_analyser_run_with_logger.php: -------------------------------------------------------------------------------- 1 | 8 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 9 | * @since Example available since Release 3.0.0-beta2 10 | */ 11 | 12 | $loader = require_once dirname(__DIR__) . '/vendor/autoload.php'; 13 | $loader->addClassMap( 14 | array( 15 | 'YourNamespace\LogPlugin' 16 | => __DIR__ . '/YourNamespace/LogPlugin.php', 17 | 'YourNamespace\YourLogger' 18 | => __DIR__ . '/YourNamespace/YourLogger.php', 19 | ) 20 | ); 21 | 22 | use Bartlett\Reflect\Client; 23 | 24 | // set our own location of JSON config file 25 | putenv("BARTLETT_SCAN_DIR=" . __DIR__ . '/YourNamespace'); 26 | 27 | // set our own JSON config file 28 | putenv("BARTLETTRC=yournamespace.json"); 29 | 30 | // creates an instance of client 31 | $client = new Client(); 32 | 33 | // request for a Bartlett\Reflect\Api\Analyser 34 | $api = $client->api('analyser'); 35 | 36 | // perform request, on a data source with default analyser (structure) 37 | $dataSource = dirname(__DIR__) . '/src'; 38 | $analysers = array('structure'); 39 | 40 | // equivalent to CLI command `phpreflect analyser:run ../src` 41 | $metrics = $api->run($dataSource, $analysers); 42 | 43 | var_export($metrics); 44 | -------------------------------------------------------------------------------- /tests/fixtures/namespaces.php: -------------------------------------------------------------------------------- 1 | 9 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 10 | */ 11 | 12 | namespace Bartlett\Reflect\Output; 13 | 14 | use Bartlett\Reflect\Environment; 15 | use Bartlett\Reflect\Console\Formatter\OutputFormatter; 16 | 17 | use Symfony\Component\Console\Output\OutputInterface; 18 | 19 | /** 20 | * Config results default render on console 21 | * 22 | * @category PHP 23 | * @package PHP_Reflect 24 | * @author Laurent Laville 25 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 26 | * @since Class available since Release 3.0.0-alpha1 27 | */ 28 | class Config extends OutputFormatter 29 | { 30 | /** 31 | * Config validate results 32 | * 33 | * @param OutputInterface $output Console Output concrete instance 34 | * @param array $response Render config:validate command 35 | * 36 | * @return void 37 | */ 38 | public function validate(OutputInterface $output, array $response): void 39 | { 40 | $output->writeln( 41 | sprintf( 42 | '"%s" config file is valid', 43 | Environment::getJsonConfigFilename() 44 | ) 45 | ); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /phar-manifest.php: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | '; 7 | 8 | $tag = exec('git describe --tags 2>&1'); 9 | 10 | if (strpos($tag, '-') === false && strpos($tag, 'No names found') === false) { 11 | print $tag; 12 | } else { 13 | $branch = exec('git rev-parse --abbrev-ref HEAD'); 14 | $hash = exec('git log -1 --format="%H"'); 15 | print $branch . '@' . $hash; 16 | } 17 | 18 | print "\n"; 19 | 20 | $lock = json_decode(file_get_contents(__DIR__ . '/composer.lock')); 21 | 22 | // packages that may be installed but not distributed in the phar version 23 | $excludes = array( 24 | 'bartlett/phpunit-loggertestlistener', 25 | 'bartlett/monolog-callbackfilterhandler', 26 | 'bartlett/monolog-growlhandler', 27 | 'pear-pear.php.net/Net_Growl', 28 | ); 29 | 30 | $packages = function ($package) use ($excludes) { 31 | if (in_array($package->name, $excludes)) { 32 | return; 33 | } 34 | print $package->name . ': ' . $package->version; 35 | 36 | if (!preg_match('/^[v= ]*(([0-9]+)(\\.([0-9]+)(\\.([0-9]+)(-([0-9]+))?(-?([a-zA-Z-+][a-zA-Z0-9\\.\\-:]*)?)?)?)?)$/', $package->version)) { 37 | print '@' . $package->source->reference; 38 | } 39 | 40 | print "\n"; 41 | }; 42 | 43 | foreach ($lock->packages as $package) { 44 | $packages($package); 45 | } 46 | 47 | foreach ($lock->{'packages-dev'} as $package) { 48 | $packages($package); 49 | } 50 | -------------------------------------------------------------------------------- /src/Bartlett/Reflect/Api/Cache.php: -------------------------------------------------------------------------------- 1 | 11 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 12 | */ 13 | 14 | namespace Bartlett\Reflect\Api; 15 | 16 | /** 17 | * Manage cache of parsing results 18 | * 19 | * @category PHP 20 | * @package PHP_Reflect 21 | * @author Laurent Laville 22 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 23 | * @since Class available since Release 3.0.0-alpha1 24 | */ 25 | class Cache extends BaseApi 26 | { 27 | /** 28 | * Clear cache (any adapter and backend). 29 | * 30 | * @param string $source Path to the data source or its alias. 31 | * @param string $alias If set, the source refers to its alias. 32 | * 33 | * @return int Number of entries cleared in cache 34 | * @throws \Exception if data source provider is unknown 35 | * @throws \RuntimeException if cache plugin is not installed 36 | */ 37 | public function clear($source, $alias = null) 38 | { 39 | $source = trim($source); 40 | if ($alias) { 41 | $alias = $source; 42 | } else { 43 | $alias = false; 44 | } 45 | return $this->request('cache/clear', 'POST', array($source, $alias)); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /docs/migrate_properties.out.asciidoc: -------------------------------------------------------------------------------- 1 | Array 2 | ( 3 | [PEAR_Error] => Array 4 | ( 5 | [signature] => public PEAR_Error($message = 'unknown error',$code = null,$mode = null,$options = null,$userinfo = null) 6 | ) 7 | 8 | [getMode] => Array 9 | ( 10 | [signature] => public getMode() 11 | ) 12 | 13 | [getCallback] => Array 14 | ( 15 | [signature] => public getCallback() 16 | ) 17 | 18 | [getMessage] => Array 19 | ( 20 | [signature] => public getMessage() 21 | ) 22 | 23 | [getCode] => Array 24 | ( 25 | [signature] => public getCode() 26 | ) 27 | 28 | [getType] => Array 29 | ( 30 | [signature] => public getType() 31 | ) 32 | 33 | [getUserInfo] => Array 34 | ( 35 | [signature] => public getUserInfo() 36 | ) 37 | 38 | [getDebugInfo] => Array 39 | ( 40 | [signature] => public getDebugInfo() 41 | ) 42 | 43 | [getBacktrace] => Array 44 | ( 45 | [signature] => public getBacktrace($frame = null) 46 | ) 47 | 48 | [addUserInfo] => Array 49 | ( 50 | [signature] => public addUserInfo($info) 51 | ) 52 | 53 | [__toString] => Array 54 | ( 55 | [signature] => public __toString() 56 | ) 57 | 58 | [toString] => Array 59 | ( 60 | [signature] => public toString() 61 | ) 62 | 63 | ) -------------------------------------------------------------------------------- /src/Bartlett/Reflect/PhpParser/NodeProcessor.php: -------------------------------------------------------------------------------- 1 | 9 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 10 | */ 11 | 12 | namespace Bartlett\Reflect\PhpParser; 13 | 14 | /** 15 | * Node processor to check pre-condition before traversing AST. 16 | * Should be used in each Node visitor into beforeTraverse(). 17 | * 18 | * @category PHP 19 | * @package PHP_Reflect 20 | * @author Laurent Laville 21 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 22 | * @since Class available since Release 3.0.0-alpha3 23 | */ 24 | interface NodeProcessor 25 | { 26 | /** 27 | * Pushes a callback on to the stack of node processors 28 | * 29 | * @param callable $callback 30 | * 31 | * @return void 32 | */ 33 | public function push(callable $callback): void; 34 | 35 | /** 36 | * Gets list of processors that will check pre-conditions. 37 | * 38 | * @return callable[] 39 | */ 40 | public function getProcessors(): array; 41 | 42 | /** 43 | * Traverses an array of nodes. 44 | * 45 | * @param Node[] $nodes Array of nodes 46 | * 47 | * @return array list of pre-conditions found 48 | */ 49 | public function traverse(array $nodes): array; 50 | } 51 | -------------------------------------------------------------------------------- /src/Bartlett/Reflect/Util/Timer.php: -------------------------------------------------------------------------------- 1 | 11 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 12 | */ 13 | 14 | namespace Bartlett\Reflect\Util; 15 | 16 | /** 17 | * Helper class to format time string. 18 | * 19 | * @category PHP 20 | * @package PHP_Reflect 21 | * @author Laurent Laville 22 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 23 | * @since Class available since Release 3.0.0-alpha3+1 24 | */ 25 | class Timer 26 | { 27 | /** 28 | * Formats the elapsed time as a string. 29 | * 30 | * This code has been copied and adapted from phpunit/php-timer 31 | * 32 | * @param int $time The period duration (in milliseconds) 33 | * 34 | * @return string 35 | */ 36 | public static function toTimeString(int $time): string 37 | { 38 | $times = array( 39 | 'hour' => 3600000, 40 | 'minute' => 60000, 41 | 'second' => 1000 42 | ); 43 | 44 | $ms = $time; 45 | 46 | foreach ($times as $unit => $value) { 47 | if ($ms >= $value) { 48 | $time = floor($ms / $value * 100.0) / 100.0; 49 | return $time . ' ' . ($time == 1 ? $unit : $unit . 's'); 50 | } 51 | } 52 | return $ms . ' ms'; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /docs/structure_analysis.out.asciidoc: -------------------------------------------------------------------------------- 1 | 2 | Data Source Analysed 3 | 4 | Directories 22 5 | Files 77 6 | 7 | Structure 8 | Namespaces 22 9 | Interfaces 10 10 | Traits 0 11 | Classes 67 12 | Abstract Classes 8 (11.94%) 13 | Concrete Classes 59 (88.06%) 14 | Methods 312 15 | Scope 16 | Non-Static Methods 299 (95.83%) 17 | Static Methods 13 (4.17%) 18 | Visibility 19 | Public Method 268 (85.90%) 20 | Protected Method 35 (11.22%) 21 | Private Method 9 (2.88%) 22 | Functions 11 23 | Named Functions 0 (0.00%) 24 | Anonymous Functions 11 (100.00%) 25 | Constants 21 26 | Global Constants 0 (0.00%) 27 | Magic Constants 3 (14.29%) 28 | Class Constants 18 (85.71%) 29 | Tests 30 | Classes 0 31 | Methods 0 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011-2020, Laurent Laville 2 | 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 9 | * Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | * Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the distribution. 14 | * Neither the name of the authors nor the names of its contributors 15 | may be used to endorse or promote products derived from this software 16 | without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 22 | BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /src/Bartlett/Reflect/Plugin/Notifier/NotifierInterface.php: -------------------------------------------------------------------------------- 1 | 9 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 10 | */ 11 | 12 | namespace Bartlett\Reflect\Plugin\Notifier; 13 | 14 | use Symfony\Component\EventDispatcher\GenericEvent; 15 | 16 | /** 17 | * Interface that all notifiers must implement. 18 | * 19 | * @category PHP 20 | * @package PHP_Reflect 21 | * @author Laurent Laville 22 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 23 | * @since Class available since Release 3.0.0-alpha3+1 24 | */ 25 | interface NotifierInterface 26 | { 27 | /** 28 | * Defines the new message format 29 | * 30 | * @param string $format The message format with predefined place holders 31 | * 32 | * @return void 33 | * @see Bartlett\Reflect\Plugin\NotifierPlugin::getPlaceholders() for known place holders 34 | */ 35 | public function setMessageFormat(string $format): void; 36 | 37 | /** 38 | * Gets the current message format 39 | * 40 | * @return string 41 | */ 42 | public function getMessageFormat(): string; 43 | 44 | /** 45 | * Notify an important event 46 | * 47 | * @param GenericEvent $event 48 | * 49 | * @return bool TRUE on a successful notification, FALSE on failure 50 | */ 51 | public function notify(GenericEvent $event): bool ; 52 | } 53 | -------------------------------------------------------------------------------- /src/Bartlett/Reflect/Output/Diagram.php: -------------------------------------------------------------------------------- 1 | 9 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 10 | */ 11 | 12 | namespace Bartlett\Reflect\Output; 13 | 14 | use Bartlett\Reflect\Console\Formatter\OutputFormatter; 15 | 16 | use Symfony\Component\Console\Output\OutputInterface; 17 | 18 | /** 19 | * Diagram results, default render on console. 20 | * 21 | * @category PHP 22 | * @package PHP_Reflect 23 | * @author Laurent Laville 24 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 25 | * @since Class available since Release 3.0.0-beta3 26 | */ 27 | class Diagram extends OutputFormatter 28 | { 29 | /** 30 | * Namespace(s) Diagram results. 31 | * 32 | * @param OutputInterface $output Console Output concrete instance 33 | * @param array $response Results of diagram processor 34 | * 35 | * @return void 36 | */ 37 | public function package(OutputInterface $output, array $response): void 38 | { 39 | $output->writeln($response); 40 | } 41 | 42 | /** 43 | * Class Diagram results 44 | * 45 | * @param OutputInterface $output Console Output concrete instance 46 | * @param array $response Results of diagram processor 47 | * 48 | * @return void 49 | */ 50 | public function class_(OutputInterface $output, array $response): void 51 | { 52 | $output->writeln($response); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /docs/reflection_class.out.asciidoc: -------------------------------------------------------------------------------- 1 | Class [ class Bartlett\Reflect extends Bartlett\Reflect\Event\AbstractDispatcher ] { 2 | @@ C:\home\github\php-reflect\src\Bartlett\Reflect.php 45 - 340 3 | 4 | - Constants [0] { 5 | } 6 | 7 | - Properties [2] { 8 | Property [ private $analysers ] 9 | Property [ private $dataSourceId ] 10 | } 11 | 12 | - Methods [6] { 13 | Method [ public method __construct ] { 14 | @@ C:\home\github\php-reflect\src\Bartlett\Reflect.php 53 - 57 15 | 16 | - Parameters [0] { 17 | } 18 | } 19 | 20 | Method [ public method addAnalyser ] { 21 | @@ C:\home\github\php-reflect\src\Bartlett\Reflect.php 66 - 71 22 | 23 | - Parameters [1] { 24 | Parameter #0 [ PhpParser\NodeVisitor $analyser ] 25 | } 26 | } 27 | 28 | Method [ public method getAnalysers ] { 29 | @@ C:\home\github\php-reflect\src\Bartlett\Reflect.php 78 - 81 30 | 31 | - Parameters [0] { 32 | } 33 | } 34 | 35 | Method [ public method setDataSourceId ] { 36 | @@ C:\home\github\php-reflect\src\Bartlett\Reflect.php 90 - 94 37 | 38 | - Parameters [1] { 39 | Parameter #0 [ $id ] 40 | } 41 | } 42 | 43 | Method [ public method getDataSourceId ] { 44 | @@ C:\home\github\php-reflect\src\Bartlett\Reflect.php 101 - 104 45 | 46 | - Parameters [0] { 47 | } 48 | } 49 | 50 | Method [ public method parse ] { 51 | @@ C:\home\github\php-reflect\src\Bartlett\Reflect.php 113 - 339 52 | 53 | - Parameters [1] { 54 | Parameter #0 [ Symfony\Component\Finder\Finder $finder ] 55 | } 56 | } 57 | } 58 | } -------------------------------------------------------------------------------- /src/Bartlett/Reflect/Collection/ReflectionCollection.php: -------------------------------------------------------------------------------- 1 | 9 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 10 | */ 11 | 12 | namespace Bartlett\Reflect\Collection; 13 | 14 | use Bartlett\Reflect\Model\ClassModel; 15 | use Bartlett\Reflect\Model\FunctionModel; 16 | use Bartlett\Reflect\Model\ConstantModel; 17 | 18 | use PhpParser\Node; 19 | 20 | use Doctrine\Common\Collections\ArrayCollection; 21 | 22 | /** 23 | * Reflection collection that collect models for the reflection analyser. 24 | * 25 | * @category PHP 26 | * @package PHP_Reflect 27 | * @author Laurent Laville 28 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 29 | * @since Class available since Release 3.0.0-alpha2 30 | */ 31 | class ReflectionCollection extends ArrayCollection 32 | { 33 | /** 34 | * {@inheritDoc} 35 | */ 36 | public function add($node) 37 | { 38 | if ($node instanceof Node\Stmt\Class_ 39 | || $node instanceof Node\Stmt\Interface_ 40 | || $node instanceof Node\Stmt\Trait_ 41 | ) { 42 | $model = new ClassModel($node); 43 | } elseif ($node instanceof Node\Stmt\Function_ 44 | || $node instanceof Node\Expr\Closure 45 | ) { 46 | $model = new FunctionModel($node); 47 | } elseif ($node instanceof Node\Stmt\Const_) { 48 | $model = new ConstantModel($node); 49 | } 50 | return parent::add($model); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/Bartlett/Reflect/Output/Reflection.php: -------------------------------------------------------------------------------- 1 | 9 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 10 | */ 11 | 12 | namespace Bartlett\Reflect\Output; 13 | 14 | use Bartlett\Reflect\Console\Formatter\OutputFormatter; 15 | 16 | use Symfony\Component\Console\Output\OutputInterface; 17 | 18 | /** 19 | * Reflection results default render on console 20 | * 21 | * @category PHP 22 | * @package PHP_Reflect 23 | * @author Laurent Laville 24 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 25 | * @since Class available since Release 3.0.0-alpha1 26 | */ 27 | class Reflection extends OutputFormatter 28 | { 29 | /** 30 | * Class Reflection results 31 | * 32 | * @param OutputInterface $output Console Output concrete instance 33 | * @param array $response Results of User Class Reflection 34 | * 35 | * @return void 36 | */ 37 | public function class_(OutputInterface $output, array $response): void 38 | { 39 | $output->writeln((string) $response['object']); 40 | } 41 | 42 | /** 43 | * Function Reflection results 44 | * 45 | * @param OutputInterface $output Console Output concrete instance 46 | * @param array $response Results of User Function Reflection 47 | * 48 | * @return void 49 | */ 50 | public function function_(OutputInterface $output, array $response): void 51 | { 52 | $output->writeln((string) $response['object']); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Bartlett/Reflect/Api/V3/Plugin.php: -------------------------------------------------------------------------------- 1 | 11 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 12 | */ 13 | 14 | namespace Bartlett\Reflect\Api\V3; 15 | 16 | use Bartlett\Reflect\Plugin\PluginManager; 17 | 18 | use Symfony\Component\EventDispatcher\EventDispatcher; 19 | use Symfony\Component\EventDispatcher\EventSubscriberInterface; 20 | 21 | /** 22 | * Identify all plugins available 23 | * 24 | * @category PHP 25 | * @package PHP_Reflect 26 | * @author Laurent Laville 27 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 28 | * @since Class available since Release 3.0.0-alpha1 29 | */ 30 | class Plugin extends Common 31 | { 32 | public function __call($name, $args) 33 | { 34 | if ('list' == $name) { 35 | return $this->dir(); 36 | } 37 | } 38 | 39 | /** 40 | * List all plugins installed. 41 | * 42 | * @return array 43 | */ 44 | public function dir() 45 | { 46 | $pm = new PluginManager(new EventDispatcher()); 47 | if ($this->registerPlugins) { 48 | $pm->registerPlugins(); 49 | } 50 | 51 | $plugins = $pm->getPlugins(); 52 | $rows = array(); 53 | 54 | foreach ($plugins as $plugin) { 55 | if (!$plugin instanceof EventSubscriberInterface) { 56 | $events = array(); 57 | } else { 58 | $events = $plugin::getSubscribedEvents(); 59 | } 60 | $rows[get_class($plugin)] = array_keys($events); 61 | } 62 | 63 | return $rows; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /docs/user-guide.asciidoc: -------------------------------------------------------------------------------- 1 | = User Guide 2 | :description: Start using Reflect without writing a line of code 3 | include::revision.asciidoc[] 4 | include::attributes.asciidoc[] 5 | 6 | ifdef::basebackend-docbook[] 7 | [partintro] 8 | -- 9 | NOTE: First visit, you are highly recommended to follow chapters in following order. 10 | 11 | . Installing all necessary [label label-primary]#Reflect# components. See xref:_installation[] 12 | . Configuring your project and get ready for your first parsing. See xref:_the_json_configuration_file[] 13 | . Running your first parses with the Command-Line interface. See xref:_the_command_line[] 14 | 15 | CAUTION: All you have to know if you want to upgrade from a previous version 1.x easily. 16 | 17 | See xref:_migration_guide[] 18 | 19 | NOTE: Basic [label label-primary]#Reflect# features does not match your needs. 20 | Learn how to extend or change some features/behaviors. 21 | 22 | See xref:_developer_guide[] 23 | -- 24 | endif::basebackend-docbook[] 25 | 26 | 27 | ifdef::basebackend-html[] 28 | [role="col-md-12"] 29 | ==== 30 | [panel,success] 31 | .For all users 32 | -- 33 | NOTE: First visit, you are highly recommended to follow chapters in following order. 34 | 35 | . link:user-guide--installation.html[Installing] all necessary [label label-primary]#Reflect# components. 36 | . link:user-guide--configuration.html[Configuring] your project and get ready for your first parsing. 37 | . link:user-guide--commands.html[Running] your first parses with the Command-Line interface. 38 | 39 | ifdef::basebackend-bootstrap[] 40 | link:user-guide--installation.html["Installing PHP Reflect",role="primary",icon="glyphicon-step-forward",options="block"] 41 | endif::basebackend-bootstrap[] 42 | ifndef::basebackend-bootstrap[] 43 | link:user-guide--installation.html[Installing PHP Reflect] 44 | endif::basebackend-bootstrap[] 45 | -- 46 | ==== 47 | -------------------------------------------------------------------------------- /docs/build/html5-bootstrap3.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | REM --- 4 | REM --- Windows CMD script 5 | REM --- to build PHP Reflect documentation in HTML 5 / Bootstrap 3 format 6 | REM --- 7 | REM --- Released under the Apache 2 license (http://www.apache.org/licenses/LICENSE-2.0.html) 8 | REM --- (c) 2014 Laurent Laville 9 | REM --- 10 | 11 | 12 | IF "%ASCIIDOC%"=="" SET "ASCIIDOC=C:\asciidoc-8.6.9" 13 | IF "%ASCIIDOC_BIN%"=="" SET "ASCIIDOC_BIN=%ASCIIDOC%\asciidoc.py" 14 | IF "%ASCIIDOC_THEME%"=="" SET "ASCIIDOC_THEME=cerulean" 15 | 16 | REM -- 17 | REM -- WEB HTML5 BOOTSTRAP FORMAT 18 | REM -- 19 | ECHO GENERATING WEB HTML5 BOOTSTRAP FORMAT ... 20 | 21 | REM -- 22 | REM -- USER GUIDE 23 | REM -- 24 | ECHO BUILDING USER GUIDE ... 25 | 26 | FOR %%f IN (user-guide*.asciidoc) DO ( 27 | "%ASCIIDOC_BIN%" -b bootstrap -a linkcss -a navbar=fixed -a totop -a theme=%ASCIIDOC_THEME% %%f 28 | ) 29 | 30 | REM -- 31 | REM -- DEVELOPER GUIDE 32 | REM -- 33 | ECHO BUILDING DEVELOPER GUIDE ... 34 | 35 | FOR %%f IN (developer-guide*.asciidoc) DO ( 36 | "%ASCIIDOC_BIN%" -b bootstrap -a linkcss -a navbar=fixed -a totop -a theme=%ASCIIDOC_THEME% %%f 37 | ) 38 | "%ASCIIDOC_BIN%" -b bootstrap -a linkcss -a navbar=fixed -a totop -a theme=%ASCIIDOC_THEME% api-compared.asciidoc 39 | 40 | REM -- 41 | REM -- MIGRATION GUIDE 42 | REM -- 43 | ECHO BUILDING MIGRATION GUIDE ... 44 | 45 | "%ASCIIDOC_BIN%" -b bootstrap -a linkcss -a navbar=fixed -a totop -a theme=%ASCIIDOC_THEME% migration-guide.asciidoc 46 | 47 | REM -- 48 | REM -- GETTING STARTED page 49 | REM -- 50 | ECHO BUILDING GETTING STARTED ... 51 | 52 | "%ASCIIDOC_BIN%" -b bootstrap -a linkcss -a navbar=fixed -a totop -a theme=%ASCIIDOC_THEME% getting-started.asciidoc 53 | 54 | REM -- 55 | REM -- MAN page 56 | REM -- 57 | ECHO BUILDING MAN PAGE ... 58 | 59 | "%ASCIIDOC_BIN%" -b bootstrap -a linkcss -a navbar=fixed -a totop -a theme=%ASCIIDOC_THEME% -d article phpreflect.1.asciidoc 60 | -------------------------------------------------------------------------------- /examples/api_analyser_run_with_filter.php: -------------------------------------------------------------------------------- 1 | 8 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 9 | * @since Example available since Release 3.1.0 10 | */ 11 | 12 | require_once dirname(__DIR__) . '/vendor/autoload.php'; 13 | 14 | use Bartlett\Reflect\Client; 15 | 16 | // creates an instance of client 17 | $client = new Client(); 18 | 19 | // request for a Bartlett\Reflect\Api\Analyser 20 | $api = $client->api('analyser'); 21 | 22 | // perform request, on a data source with two analysers (structure, loc) 23 | $dataSource = dirname(__DIR__) . '/src'; 24 | $analysers = array('structure', 'loc'); 25 | 26 | // filter rules on final results 27 | $closure = function ($data) { 28 | $filterOnKeys = array( 29 | 'classes', 'abstractClasses', 'concreteClasses', 30 | 'classConstants', 'globalConstants', 'magicConstants', 31 | ); 32 | 33 | foreach ($data as $title => &$keys) { 34 | if (strpos($title, 'StructureAnalyser') === false) { 35 | continue; 36 | } 37 | // looking into Structure Analyser metrics and keep classes and constants info 38 | foreach ($keys as $key => $val) { 39 | if (!in_array($key, $filterOnKeys)) { 40 | unset($keys[$key]); // "removed" unsolicited values 41 | continue; 42 | } 43 | } 44 | } 45 | return $data; 46 | }; 47 | 48 | // equivalent to CLI command `phpreflect analyser:run --filter=YourFilters.php ../src structure loc` 49 | //$metrics = $api->run($dataSource, $analysers, null, false, $closure = 'YourFilters.php'); 50 | 51 | // OR with embeded $closure code 52 | $metrics = $api->run($dataSource, $analysers, null, false, $closure); 53 | 54 | var_export($metrics); 55 | -------------------------------------------------------------------------------- /tests/Model/GenericModelTest.php: -------------------------------------------------------------------------------- 1 | 11 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 12 | * @since Class available since Release 3.0.0-alpha2 13 | */ 14 | 15 | namespace Bartlett\Tests\Reflect\Model; 16 | 17 | use Bartlett\Reflect\Client; 18 | 19 | /** 20 | * Unit Test Case that covers Bartlett\Reflect\Model\*Model 21 | * 22 | * @category PHP 23 | * @package PHP_Reflect 24 | * @subpackage Tests 25 | * @author Laurent Laville 26 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 27 | */ 28 | abstract class GenericModelTest extends \PHPUnit\Framework\TestCase 29 | { 30 | protected static $fixtures; 31 | protected static $fixture; 32 | protected static $models; 33 | protected static $api; 34 | 35 | /** 36 | * Sets up the shared fixture. 37 | * 38 | * @return void 39 | * @link http://phpunit.de/manual/current/en/fixtures.html#fixtures.sharing-fixture 40 | */ 41 | public static function setUpBeforeClass(): void 42 | { 43 | self::$fixtures = dirname(__DIR__) . DIRECTORY_SEPARATOR 44 | . 'fixtures' . DIRECTORY_SEPARATOR; 45 | 46 | self::$fixture = self::$fixtures . self::$fixture; 47 | 48 | $client = new Client(); 49 | 50 | // request for a Bartlett\Reflect\Api\Analyser 51 | self::$api = $client->api('analyser'); 52 | 53 | $analyserId = 'Bartlett\Reflect\Analyser\ReflectionAnalyser'; 54 | $dataSource = self::$fixture; 55 | $analysers = array('reflection'); 56 | $metrics = self::$api->run($dataSource, $analysers); 57 | self::$models = $metrics[$analyserId]; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /docs/developer-guide--handle-results.asciidoc: -------------------------------------------------------------------------------- 1 | ifndef::basebackend-docbook[] 2 | 3 | = Handle Results 4 | :description: Learn how to explore and exploit parsing results. 5 | include::revision.asciidoc[] 6 | include::attributes.asciidoc[] 7 | 8 | endif::basebackend-docbook[] 9 | 10 | [role="lead"] 11 | Whatever SAPI you use, all metrics (for each analysers asked) are available 12 | at end of parse, in the same format. 13 | 14 | With CLI, and [label label-primary]#Reflect# source code, 15 | to get a structure report, you have to invoke the following command : 16 | [source,bash] 17 | ---- 18 | $ phpreflect analyser:run /home/github/php-reflect/src 19 | ---- 20 | With others SAPI, use example {rawbaseurl}/examples/api_analyser_run.php 21 | 22 | and you should obtain something like this : 23 | 24 | [role="output"] 25 | ==== 26 | ---- 27 | include::structure_analysis.out.asciidoc[] 28 | ---- 29 | ==== 30 | 31 | This is the default render. But, if you want to compare with other SAPI, 32 | activate the debug verbose mode (`-vvv`) to get the raw response. 33 | You should obtain something like this : 34 | 35 | [role="output"] 36 | ==== 37 | ---- 38 | include::structure_analysis.raw.asciidoc[] 39 | ---- 40 | ==== 41 | 42 | * First entry in array is the list of parsed `files` 43 | * Second entry in array is the `structure` analyser result 44 | 45 | Each analyser as its own data structure and results, but you will always get the fully qualified 46 | class name that identify origin of analyser used. 47 | 48 | .Example with two analysers (`structure` and `loc`) 49 | [source,bash] 50 | ---- 51 | $ phpreflect analyser:run /home/github/php-reflect/src structure loc 52 | ---- 53 | 54 | [role="output"] 55 | ==== 56 | ---- 57 | Raw response 58 | Array 59 | ( 60 | [files] => Array 61 | ( 62 | ... 63 | ) 64 | 65 | [Bartlett\Reflect\Analyser\StructureAnalyser] => Array 66 | ( 67 | ... 68 | ) 69 | 70 | include::loc_analysis.raw.asciidoc[] 71 | 72 | ) 73 | ---- 74 | ==== 75 | -------------------------------------------------------------------------------- /src/Bartlett/Reflect/Api/V3/Diagnose.php: -------------------------------------------------------------------------------- 1 | 11 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 12 | */ 13 | 14 | namespace Bartlett\Reflect\Api\V3; 15 | 16 | /** 17 | * Diagnoses the system to identify common errors. 18 | * 19 | * @category PHP 20 | * @package PHP_Reflect 21 | * @author Laurent Laville 22 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 23 | * @since Class available since Release 3.0.0-RC1 24 | */ 25 | class Diagnose extends Common 26 | { 27 | const PHP_MIN = '7.1.3'; 28 | const PHP_RECOMMANDED = '7.3.0'; 29 | 30 | /** 31 | * Diagnoses the system to identify common errors. 32 | * 33 | * @return array 34 | */ 35 | public function run() 36 | { 37 | $response = array(); 38 | 39 | if (version_compare(PHP_VERSION, self::PHP_MIN, '<')) { 40 | $response['php_version'] = false; 41 | } else { 42 | $response['php_version'] = PHP_VERSION; 43 | } 44 | 45 | $response['php_ini'] = php_ini_loaded_file(); 46 | 47 | $extensions = array( 48 | 'date', 49 | 'json', 50 | 'pcre', 51 | 'phar', 52 | 'reflection', 53 | 'spl', 54 | 'tokenizer', 55 | ); 56 | 57 | foreach ($extensions as $extension) { 58 | $response[$extension . '_loaded'] = extension_loaded($extension); 59 | } 60 | 61 | if (extension_loaded('xdebug')) { 62 | $response['xdebug_loaded'] = true; 63 | $response['xdebug_profiler_enable'] = ini_get('xdebug.profiler_enable'); 64 | } 65 | 66 | return $response; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/Bartlett/Reflect/Output/Plugin.php: -------------------------------------------------------------------------------- 1 | 9 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 10 | */ 11 | 12 | namespace Bartlett\Reflect\Output; 13 | 14 | use Bartlett\Reflect\Console\Formatter\OutputFormatter; 15 | 16 | use Symfony\Component\Console\Output\OutputInterface; 17 | 18 | /** 19 | * Plugin results default render on console 20 | * 21 | * @category PHP 22 | * @package PHP_Reflect 23 | * @author Laurent Laville 24 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 25 | * @since Class available since Release 3.0.0-alpha1 26 | */ 27 | class Plugin extends OutputFormatter 28 | { 29 | /** 30 | * Plugin list results 31 | * 32 | * @param OutputInterface $output Console Output concrete instance 33 | * @param array $response Available plugins list 34 | * 35 | * @return void 36 | */ 37 | public function dir(OutputInterface $output, array $response): void 38 | { 39 | if (empty($response)) { 40 | $output->writeln('No plugin installed'); 41 | } else { 42 | $headers = array('Plugin Class', 'Events Subscribed'); 43 | $rows = array(); 44 | 45 | foreach ($response as $pluginClass => $events) { 46 | $first = true; 47 | foreach ($events as $event) { 48 | if (!$first) { 49 | $rows[] = array('', $event); 50 | } else { 51 | $rows[] = array($pluginClass, $event); 52 | $first = false; 53 | } 54 | } 55 | } 56 | $this->tableHelper($output, $headers, $rows); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/Bartlett/Reflect/Api/Diagram.php: -------------------------------------------------------------------------------- 1 | 11 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 12 | */ 13 | 14 | namespace Bartlett\Reflect\Api; 15 | 16 | /** 17 | * Diagram generator API 18 | * 19 | * @category PHP 20 | * @package PHP_Reflect 21 | * @author Laurent Laville 22 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 23 | * @since Class available since Release 3.0.0-beta3 24 | */ 25 | class Diagram extends BaseApi 26 | { 27 | /** 28 | * Generates diagram about namespaces in a data source. 29 | * 30 | * @param string $argument Name of the namespace to inspect. 31 | * @param string $source Path to the data source or its alias. 32 | * @param mixed $alias If set, the source refers to its alias. 33 | * @param string $engine Graphical syntax. 34 | * 35 | * @return mixed 36 | */ 37 | public function package($argument, $source, $alias = null, $engine = 'plantuml') 38 | { 39 | return $this->request('diagram/package', 'POST', array($argument, $source, $alias, $engine)); 40 | } 41 | 42 | /** 43 | * Generates diagram about a user class present in a data source. 44 | * 45 | * @param string $argument Name of the class to inspect. 46 | * @param string $source Path to the data source or its alias. 47 | * @param mixed $alias If set, the source refers to its alias. 48 | * @param string $engine Graphical syntax. 49 | * 50 | * @return mixed 51 | * @alias class 52 | */ 53 | public function class_($argument, $source, $alias = null, $engine = 'plantuml') 54 | { 55 | return $this->request('diagram/class', 'POST', array($argument, $source, $alias, $engine)); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /docs/migrate_properties.php.asciidoc: -------------------------------------------------------------------------------- 1 | files() 12 | ->name('PEAR.php') 13 | ->in('/path/to/PEAR-1.9.2/'); 14 | 15 | // Identify Data Source 16 | $pm = new ProviderManager; 17 | $pm->set('PEAR192', new SymfonyFinderProvider($finder)); 18 | 19 | $reflect = new Reflect; 20 | $reflect->setProviderManager($pm); 21 | $reflect->parse(); 22 | 23 | // Exploit results 24 | $out = array(); 25 | 26 | foreach ($reflect->getPackages() as $package) { 27 | foreach ($package->getClasses() as $class) { 28 | 29 | if ($class->getShortName() !== 'PEAR_Error') { 30 | continue; 31 | } 32 | 33 | foreach ($class->getMethods() as $method) { 34 | 35 | if ($method->isPrivate()) { 36 | $visibility = 'private'; 37 | } elseif ($method->isProtected()) { 38 | $visibility = 'protected'; 39 | } else { 40 | $visibility = 'public'; 41 | } 42 | 43 | $name = $method->getShortName(); 44 | 45 | $parameters = $method->getParameters(); 46 | $args = array(); 47 | 48 | foreach ($parameters as $parameter) { 49 | 50 | $args[] = sprintf( 51 | '%s%s%s', 52 | $parameter->isPassedByReference() ? '&' : '', 53 | '$' . $parameter->getName(), 54 | $parameter->isDefaultValueAvailable() ? ' = ' . $parameter->getDefaultValue() : '' 55 | ); 56 | } 57 | 58 | $out[$name] = array( 59 | 'signature' => sprintf('%s %s(%s)', $visibility, $name, implode(',', $args)) 60 | ); 61 | } 62 | } 63 | } 64 | print_r($out); 65 | -------------------------------------------------------------------------------- /docs/javascripts/jquery.ui.totop.js: -------------------------------------------------------------------------------- 1 | /* 2 | |-------------------------------------------------------------------------- 3 | | UItoTop jQuery Plugin 1.2 by Matt Varone 4 | | http://www.mattvarone.com/web-design/uitotop-jquery-plugin/ 5 | |-------------------------------------------------------------------------- 6 | */ 7 | (function($){ 8 | $.fn.UItoTop = function(options) { 9 | 10 | var defaults = { 11 | text: 'To Top', 12 | min: 200, 13 | inDelay:600, 14 | outDelay:400, 15 | containerID: 'toTop', 16 | containerHoverID: 'toTopHover', 17 | scrollSpeed: 1200, 18 | easingType: 'linear' 19 | }, 20 | settings = $.extend(defaults, options), 21 | containerIDhash = '#' + settings.containerID, 22 | containerHoverIDHash = '#'+settings.containerHoverID; 23 | 24 | $('body').append(''+settings.text+''); 25 | $(containerIDhash).hide().on('click.UItoTop',function(){ 26 | $('html, body').animate({scrollTop:0}, settings.scrollSpeed, settings.easingType); 27 | $('#'+settings.containerHoverID, this).stop().animate({'opacity': 0 }, settings.inDelay, settings.easingType); 28 | return false; 29 | }) 30 | .prepend('') 31 | .hover(function() { 32 | $(containerHoverIDHash, this).stop().animate({ 33 | 'opacity': 1 34 | }, 600, 'linear'); 35 | }, function() { 36 | $(containerHoverIDHash, this).stop().animate({ 37 | 'opacity': 0 38 | }, 700, 'linear'); 39 | }); 40 | 41 | $(window).scroll(function() { 42 | var sd = $(window).scrollTop(); 43 | if(typeof document.body.style.maxHeight === "undefined") { 44 | $(containerIDhash).css({ 45 | 'position': 'absolute', 46 | 'top': sd + $(window).height() - 50 47 | }); 48 | } 49 | if ( sd > settings.min ) 50 | $(containerIDhash).fadeIn(settings.inDelay); 51 | else 52 | $(containerIDhash).fadeOut(settings.Outdelay); 53 | }); 54 | }; 55 | })(jQuery); -------------------------------------------------------------------------------- /src/Bartlett/Reflect/Model/FunctionModel.php: -------------------------------------------------------------------------------- 1 | 11 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 12 | */ 13 | 14 | namespace Bartlett\Reflect\Model; 15 | 16 | /** 17 | * The FunctionModel class reports information about a function. 18 | * 19 | * @category PHP 20 | * @package PHP_Reflect 21 | * @author Laurent Laville 22 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 23 | * @since Class available since Release 2.0.0RC1 24 | */ 25 | class FunctionModel extends AbstractFunctionModel 26 | { 27 | /** 28 | * Returns the string representation of the FunctionModel object. 29 | * 30 | * @return string 31 | */ 32 | public function __toString(): string 33 | { 34 | $eol = "\n"; 35 | $str = ''; 36 | $str .= sprintf( 37 | 'Function [ <%s> function %s ] {%s', 38 | $this->getExtensionName(), 39 | $this->getName(), 40 | $eol 41 | ); 42 | 43 | $str .= sprintf( 44 | ' @@ %s %d - %d%s', 45 | $this->getFileName(), 46 | $this->getStartLine(), 47 | $this->getEndLine(), 48 | $eol 49 | ); 50 | 51 | // parameters 52 | $parameters = $this->getParameters(); 53 | if (count($parameters)) { 54 | $str .= sprintf( 55 | '%s - Parameters [%d] {%s', 56 | $eol, 57 | count($parameters), 58 | $eol 59 | ); 60 | foreach ($parameters as $parameter) { 61 | $str .= ' ' . (string) $parameter; 62 | } 63 | $str .= ' }' . $eol; 64 | } 65 | 66 | $str .= '}' . $eol; 67 | 68 | return $str; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /tests/fixtures/classes.php: -------------------------------------------------------------------------------- 1 | name = "MyDestructableClass"; 48 | } 49 | 50 | function __destruct() { 51 | print "Destroying " . $this->name . "\n"; 52 | } 53 | 54 | function dump() { 55 | print "Dump content of " . $this->name . "\n"; 56 | 57 | } 58 | } 59 | 60 | class Bar 61 | { 62 | const ONE = "Number one"; 63 | const TWO = "Number two"; 64 | 65 | function myfunction ( stdClass $param = NULL, $otherparam = TRUE ) { 66 | } 67 | 68 | protected function otherfunction( Baz $baz, $param ) 69 | { 70 | } 71 | 72 | } 73 | 74 | class IteratorClass implements Iterator { 75 | public function __construct() { } 76 | public function key() { } 77 | public function current() { } 78 | function next() { } 79 | function valid() { } 80 | function rewind() { } 81 | } 82 | class DerivedClass extends IteratorClass { } 83 | 84 | class NotCloneable { 85 | public $var1; 86 | 87 | private function __clone() { 88 | } 89 | } 90 | class Cloneable { 91 | public $var1; 92 | } 93 | 94 | final class TestFinalClass { } 95 | -------------------------------------------------------------------------------- /src/Bartlett/Reflect/Event/DispatcherInterface.php: -------------------------------------------------------------------------------- 1 | 12 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 13 | */ 14 | 15 | namespace Bartlett\Reflect\Event; 16 | 17 | use Symfony\Component\EventDispatcher\EventDispatcherInterface; 18 | use Symfony\Component\EventDispatcher\EventSubscriberInterface; 19 | 20 | /** 21 | * Holds an event dispatcher. 22 | * 23 | * @category PHP 24 | * @package PHP_Reflect 25 | * @author Laurent Laville 26 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 27 | * @since Interface available since Release 2.0.0RC1 28 | */ 29 | interface DispatcherInterface 30 | { 31 | /** 32 | * Set the EventDispatcher of the request 33 | * 34 | * @param EventDispatcherInterface $eventDispatcher Instance of the event 35 | * dispatcher 36 | * 37 | * @return self for a fuent interface 38 | */ 39 | public function setEventDispatcher(EventDispatcherInterface $eventDispatcher); 40 | 41 | /** 42 | * Get the EventDispatcher of the request 43 | * 44 | * @return EventDispatcherInterface 45 | */ 46 | public function getEventDispatcher(): EventDispatcherInterface; 47 | 48 | /** 49 | * Dispatches an event to all registered listeners. 50 | * 51 | * @param object $event The event to dispatch 52 | * 53 | * @return object 54 | */ 55 | public function dispatch($event); 56 | 57 | /** 58 | * Adds an event subscriber. 59 | * 60 | * @param EventSubscriberInterface $subscriber The subscriber which is 61 | * interested by events 62 | * 63 | * @return self for a fuent interface 64 | */ 65 | public function addSubscriber(EventSubscriberInterface $subscriber); 66 | } 67 | -------------------------------------------------------------------------------- /src/Bartlett/Reflect/Plugin/Cache/DoctrineCacheAdapter.php: -------------------------------------------------------------------------------- 1 | 11 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 12 | * @link http://www.doctrine-project.org/ 13 | */ 14 | 15 | namespace Bartlett\Reflect\Plugin\Cache; 16 | 17 | use Doctrine\Common\Cache\Cache; 18 | 19 | /** 20 | * Doctrine 2 cache adapter. 21 | * 22 | * @category PHP 23 | * @package PHP_Reflect 24 | * @author Laurent Laville 25 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 26 | * @since Class available since Release 2.0.0RC1 27 | */ 28 | class DoctrineCacheAdapter implements CacheAdapterInterface 29 | { 30 | /** 31 | * Instance of a Doctrine cache 32 | * @var Cache 33 | */ 34 | protected $cache; 35 | 36 | /** 37 | * Doctrine 2 cache adapter constructor. 38 | * 39 | * @param Cache $cache Doctrine cache object 40 | */ 41 | public function __construct(Cache $cache) 42 | { 43 | $this->cache = $cache; 44 | } 45 | 46 | /** 47 | * {@inheritDoc} 48 | */ 49 | public function exists(string $id, array $options = null): bool 50 | { 51 | return $this->cache->contains($id); 52 | } 53 | 54 | /** 55 | * {@inheritDoc} 56 | */ 57 | public function delete(string $id, array $options = null): bool 58 | { 59 | return $this->cache->delete($id); 60 | } 61 | 62 | /** 63 | * {@inheritDoc} 64 | */ 65 | public function fetch(string $id, array $options = null) 66 | { 67 | return $this->cache->fetch($id); 68 | } 69 | 70 | /** 71 | * {@inheritDoc} 72 | */ 73 | public function save(string $id, $data, $lifeTime = false, array $options = null): bool 74 | { 75 | return $this->cache->save($id, $data, $lifeTime); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /docs/navinfo.html: -------------------------------------------------------------------------------- 1 | 26 | 33 | -------------------------------------------------------------------------------- /src/Bartlett/Reflect/Plugin/Cache/CacheStorageInterface.php: -------------------------------------------------------------------------------- 1 | 11 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 12 | */ 13 | 14 | namespace Bartlett\Reflect\Plugin\Cache; 15 | 16 | /** 17 | * Interface used to cache FILE parses 18 | * 19 | * @category PHP 20 | * @package PHP_Reflect 21 | * @author Laurent Laville 22 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 23 | * @since Interface available since Release 2.0.0RC1 24 | */ 25 | interface CacheStorageInterface 26 | { 27 | /** 28 | * Checks if cache exists for a request. 29 | * 30 | * @param array $request Request data to check for 31 | * 32 | * @return bool TRUE if a response exists in cache, FALSE otherwise 33 | */ 34 | public function exists(array $request): bool; 35 | 36 | /** 37 | * Get a response from the cache for a request. 38 | * 39 | * @param array $request Request data to read from cache 40 | * 41 | * @return mixed 42 | */ 43 | public function fetch(array $request); 44 | 45 | /** 46 | * Cache a FILE parse. 47 | * 48 | * @param array $request Request being cached 49 | * 50 | * @return void 51 | */ 52 | public function cache(array $request): void; 53 | 54 | /** 55 | * Deletes cache entries that match a request. 56 | * 57 | * @param array $request Request to delete from cache 58 | * 59 | * @return int number of entries deleted in cache 60 | */ 61 | public function delete(array $request): int; 62 | 63 | /** 64 | * Purge all cache entries for a given data source. 65 | * 66 | * @param string $source Name that identify a data source 67 | * (see ProviderManager) 68 | * 69 | * @return int 70 | */ 71 | public function purge(string $source): int; 72 | } 73 | -------------------------------------------------------------------------------- /docs/footer.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |

    Social

    4 | 18 |
    19 |
    20 |

    About Us

    21 |
      22 |
    • 23 | 24 | 25 | 26 | Thanks to Nikita Popov who wrote a marvellous PHP Parser 27 | and simplify the job of PHP Reflect. 28 |
    • 29 |
    • 30 | 31 | 32 | 33 | Laurent Laville is current lead developer. 34 |
    • 35 |
    36 |
    37 |
    38 |
     
    39 |
    40 |
    41 | 46 |
    47 |
    48 | 52 |
    53 |
    54 | -------------------------------------------------------------------------------- /src/Bartlett/Reflect/Event/CacheAwareEventDispatcher.php: -------------------------------------------------------------------------------- 1 | 11 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 12 | */ 13 | 14 | namespace Bartlett\Reflect\Event; 15 | 16 | use Symfony\Component\EventDispatcher\Event; 17 | use Symfony\Component\EventDispatcher\EventDispatcher; 18 | 19 | /** 20 | * Class that is aware if a cache is used or not. 21 | * 22 | * @category PHP 23 | * @package PHP_Reflect 24 | * @author Laurent Laville 25 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 26 | * @since Class available since Release 3.0.0-beta2 27 | */ 28 | class CacheAwareEventDispatcher extends EventDispatcher 29 | { 30 | /** 31 | * {@inheritdoc} 32 | * 33 | * @return void 34 | */ 35 | protected function doDispatch($listeners, $eventName, Event $event): void 36 | { 37 | foreach ($listeners as $listener) { 38 | $evt = $this->preNotify($listener, clone($event)); 39 | call_user_func($listener, $evt, $eventName, $this); 40 | if ($evt->isPropagationStopped()) { 41 | break; 42 | } 43 | } 44 | } 45 | 46 | /** 47 | * Called before notify a listener about the event. 48 | * 49 | * @param mixed $listener The listener to notify with that $event 50 | * @param Event $event The event 51 | * 52 | * @return Event 53 | */ 54 | protected function preNotify($listener, Event $event) 55 | { 56 | if ($event instanceof SuccessEvent) { 57 | /* 58 | * 'ast' argument of 'reflect.success' event is used only by the cache plugin. 59 | * Remove it improve performance. 60 | */ 61 | if (is_array($listener) 62 | && !$listener[0] instanceof \Bartlett\Reflect\Plugin\CachePlugin 63 | ) { 64 | unset($event['ast']); 65 | } 66 | } 67 | return $event; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/Bartlett/Reflect/Api/BaseApi.php: -------------------------------------------------------------------------------- 1 | 11 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 12 | */ 13 | 14 | namespace Bartlett\Reflect\Api; 15 | 16 | use Bartlett\Reflect\Client\ClientInterface; 17 | use Bartlett\Reflect\Event\AbstractDispatcher; 18 | 19 | /** 20 | * Common code to API requests 21 | * 22 | * @category PHP 23 | * @package PHP_Reflect 24 | * @author Laurent Laville 25 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 26 | * @since Class available since Release 3.0.0-alpha1 27 | */ 28 | abstract class BaseApi extends AbstractDispatcher 29 | { 30 | protected $client; 31 | 32 | private $token; 33 | private $registerPlugins = true; 34 | 35 | /** 36 | * Initialize any API requests 37 | * 38 | * @param ClientInterface $client 39 | * @param string $token 40 | * @param string $appName 41 | */ 42 | public function __construct(ClientInterface $client, $token = null) 43 | { 44 | $this->client = $client; 45 | $this->token = $token; 46 | } 47 | 48 | /** 49 | * Allows to disable all plugins declared in the JSON config file 50 | * 51 | * @param bool $register Activate (default) or not, all plugins declared 52 | * 53 | * @return void 54 | * @disabled 55 | */ 56 | public function activatePlugins($register) 57 | { 58 | $this->registerPlugins = (bool) $register; 59 | } 60 | 61 | /** 62 | * Performs the request 63 | * 64 | * @param string $url 65 | * @param string $method 66 | * @param array $params 67 | */ 68 | protected function request($url, $method = 'GET', array $params = array()) 69 | { 70 | $this->client->setEventDispatcher($this->getEventDispatcher()); 71 | $this->client->activatePlugins($this->registerPlugins); 72 | 73 | $response = $this->client->request($method, $url, $params); 74 | return $response; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/Bartlett/Reflect/Api/V3/Cache.php: -------------------------------------------------------------------------------- 1 | 11 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 12 | */ 13 | 14 | namespace Bartlett\Reflect\Api\V3; 15 | 16 | use Bartlett\Reflect\Plugin\PluginManager; 17 | use Bartlett\Reflect\Plugin\CachePlugin; 18 | 19 | /** 20 | * Manage cache of parsing results 21 | * 22 | * @category PHP 23 | * @package PHP_Reflect 24 | * @author Laurent Laville 25 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 26 | * @since Class available since Release 3.0.0-alpha1 27 | */ 28 | class Cache extends Common 29 | { 30 | /** 31 | * Clear cache (any adapter and backend). 32 | * 33 | * @param string $source Path to the data source or its alias. 34 | * @param string $alias If set, the source refers to its alias. 35 | * 36 | * @return int Number of entries cleared in cache 37 | * @throws \Exception if data source provider is unknown 38 | * @throws \RuntimeException if cache plugin is not installed 39 | */ 40 | public function clear($source, $alias = null) 41 | { 42 | $source = trim($source); 43 | if ($alias) { 44 | $alias = $source; 45 | } else { 46 | $alias = false; 47 | } 48 | 49 | $finder = $this->findProvider($source, $alias); 50 | 51 | if ($finder === false) { 52 | throw new \RuntimeException( 53 | 'None data source matching' 54 | ); 55 | } 56 | 57 | $pm = new PluginManager($this->eventDispatcher); 58 | if (!$this->registerPlugins) { 59 | return 0; 60 | } 61 | $pm->registerPlugins(); 62 | 63 | foreach ($pm->getPlugins() as $plugin) { 64 | if ($plugin instanceof CachePlugin) { 65 | $cache = $plugin->getCacheStorage(); 66 | break; 67 | } 68 | } 69 | 70 | $entriesCleared = $cache->purge($this->dataSourceId); 71 | return $entriesCleared; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /examples/api_analyser_run.php: -------------------------------------------------------------------------------- 1 | 6 | * array ( 7 | * 'files' => 8 | * array ( 9 | * // ... 10 | * ), 11 | * 'Bartlett\\Reflect\\Analyser\\StructureAnalyser' => 12 | * array ( 13 | * 'namespaces' => 19, 14 | * 'interfaces' => 7, 15 | * 'traits' => 0, 16 | * 'classes' => 56, 17 | * 'abstractClasses' => 6, 18 | * 'concreteClasses' => 50, 19 | * 'functions' => 6, 20 | * 'namedFunctions' => 0, 21 | * 'anonymousFunctions' => 6, 22 | * 'methods' => 280, 23 | * 'publicMethods' => 241, 24 | * 'protectedMethods' => 29, 25 | * 'privateMethods' => 10, 26 | * 'nonStaticMethods' => 273, 27 | * 'staticMethods' => 7, 28 | * 'constants' => 0, 29 | * 'classConstants' => 17, 30 | * 'globalConstants' => 0, 31 | * 'magicConstants' => 3, 32 | * 'testClasses' => 0, 33 | * 'testMethods' => 0, 34 | * ), 35 | * 'Bartlett\\Reflect\\Analyser\\LocAnalyser' => 36 | * array ( 37 | * 'llocClasses' => 995, 38 | * 'llocByNoc' => 0, 39 | * 'llocByNom' => 0, 40 | * 'llocFunctions' => 48, 41 | * 'llocByNof' => 0, 42 | * 'llocGlobal' => 0, 43 | * 'classes' => 56, 44 | * 'functions' => 6, 45 | * 'methods' => 303, 46 | * 'cloc' => 117, 47 | * 'eloc' => 2700, 48 | * 'lloc' => 1043, 49 | * 'wloc' => 329, 50 | * 'loc' => 3146, 51 | * 'ccn' => 475, 52 | * 'ccnMethods' => 451, 53 | * ), 54 | * ) 55 | * 56 | * 57 | * @category PHP 58 | * @package PHP_Reflect 59 | * @author Laurent Laville 60 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 61 | * @since Example available since Release 3.0.0-alpha3 62 | */ 63 | 64 | require_once dirname(__DIR__) . '/vendor/autoload.php'; 65 | 66 | use Bartlett\Reflect\Client; 67 | 68 | // creates an instance of client 69 | $client = new Client(); 70 | 71 | // request for a Bartlett\Reflect\Api\Analyser 72 | $api = $client->api('analyser'); 73 | 74 | // perform request, on a data source with two analysers (structure, loc) 75 | $dataSource = dirname(__DIR__) . '/src'; 76 | $analysers = array('structure', 'loc'); 77 | 78 | // equivalent to CLI command `phpreflect analyser:run ../src structure loc` 79 | $metrics = $api->run($dataSource, $analysers); 80 | 81 | var_export($metrics); 82 | -------------------------------------------------------------------------------- /src/Bartlett/Reflect/Api/Reflection.php: -------------------------------------------------------------------------------- 1 | 11 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 12 | */ 13 | 14 | namespace Bartlett\Reflect\Api; 15 | 16 | /** 17 | * Reflection API 18 | * 19 | * @category PHP 20 | * @package PHP_Reflect 21 | * @author Laurent Laville 22 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 23 | * @since Class available since Release 3.0.0-alpha1 24 | */ 25 | class Reflection extends BaseApi 26 | { 27 | public function __call($name, $args) 28 | { 29 | if ('class' == $name) { 30 | return call_user_func_array(array($this, 'class_'), $args); 31 | } elseif ('function' == $name) { 32 | return call_user_func_array(array($this, 'function_'), $args); 33 | } 34 | } 35 | 36 | /** 37 | * Reports information about a user class present in a data source. 38 | * 39 | * @param string $argument Name of the class to reflect. 40 | * @param string $source Path to the data source or its alias. 41 | * @param mixed $alias If set, the source refers to its alias. 42 | * @param string $format To ouput results in other formats. 43 | * 44 | * @return mixed 45 | * @alias class 46 | */ 47 | public function class_($argument, $source, $alias = null, $format = 'txt') 48 | { 49 | return $this->request('reflection/class', 'POST', array($argument, $source, $alias, $format)); 50 | } 51 | 52 | /** 53 | * Reports information about a user function present in a data source. 54 | * 55 | * @param string $argument Name of the function to reflect. 56 | * @param string $source Path to the data source or its alias. 57 | * @param mixed $alias If set, the source refers to its alias. 58 | * @param string $format To ouput results in other formats. 59 | * 60 | * @return mixed 61 | * @alias function 62 | */ 63 | public function function_($argument, $source, $alias = null, $format = 'txt') 64 | { 65 | return $this->request('reflection/function', 'POST', array($argument, $source, $alias, $format)); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/Bartlett/Reflect/Console/Formatter/OutputFormatter.php: -------------------------------------------------------------------------------- 1 | 11 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 12 | */ 13 | 14 | namespace Bartlett\Reflect\Console\Formatter; 15 | 16 | use Symfony\Component\Console\Output\OutputInterface; 17 | use Symfony\Component\Console\Helper\Table; 18 | use Symfony\Component\Console\Formatter\OutputFormatter as BaseOutputFormatter; 19 | 20 | /** 21 | * Common formatter helpers for console output. 22 | * 23 | * @category PHP 24 | * @package PHP_Reflect 25 | * @author Laurent Laville 26 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 27 | * @since Class available since Release 3.0.0-alpha1 28 | */ 29 | class OutputFormatter extends BaseOutputFormatter 30 | { 31 | /** 32 | * Helper that convert analyser results to a console table 33 | * 34 | * @param OutputInterface $output Console Output concrete instance 35 | * @param array $headers All table headers 36 | * @param array $rows All table rows 37 | * @param string $style The default style name to render tables 38 | * 39 | * @return void 40 | */ 41 | protected function tableHelper(OutputInterface $output, array $headers, array $rows, string $style = 'compact'): void 42 | { 43 | $table = new Table($output); 44 | $table->setStyle($style) 45 | ->setHeaders($headers) 46 | ->setRows($rows) 47 | ->render() 48 | ; 49 | } 50 | 51 | /** 52 | * Helper that convert an array key-value pairs to a console report. 53 | * 54 | * See Structure and Loc analysers for implementation examples 55 | * 56 | * @param OutputInterface $output Console Output concrete instance 57 | * @param array $lines Any analyser formatted metrics 58 | * 59 | * @return void 60 | */ 61 | protected function printFormattedLines(OutputInterface $output, array $lines): void 62 | { 63 | foreach ($lines as $ident => $contents) { 64 | list ($format, $args) = $contents; 65 | $output->writeln(vsprintf($format, $args)); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /docs/cover.asciidoc: -------------------------------------------------------------------------------- 1 | = Cover 2 | :description: PHP Reflect Book 3 | include::attributes.asciidoc[] 4 | :navbar!: 5 | :themeswitcher!: 6 | :jumbotron!: 7 | :toc!: 8 | :toc2!: 9 | :stylesheet: cover.css 10 | 11 | 12 | == PHP Reflect 4 13 | 14 | [role="cover"] 15 | -- 16 | [subs="none"] 17 | ++++++++++++++++++++++++++++++++++++++ 18 | 22 | ++++++++++++++++++++++++++++++++++++++ 23 | -- 24 | 25 | [role="bg-info"] 26 | -- 27 | [big]#The Book# 28 | -- 29 | [pull-left]#Published with AsciiDoc-Bootstrap backend v4# 30 | [pull-right]#by Laurent Laville# 31 | 32 | unfloat::[] 33 | 34 | [role="col-md-6 panels"] 35 | ==== 36 | [panel,primary] 37 | .Read it online 38 | -- 39 | * image:icons/font-awesome/files-o.png[alt="multiple html files",icon="files-o",iconsfont="font-awesome"] link:getting-started.html[Multiple HTML files] 40 | * image:icons/font-awesome/file-o.png[alt="single html file",icon="file-o",iconsfont="font-awesome"] link:phpreflect-book.html[Single HTML file] 41 | * image:icons/font-awesome/file-pdf-o.png[alt="pdf file",icon="file",iconsfont="font-awesome"] link:phpreflect-book.pdf[PDF file] 42 | * image:icons/font-awesome/book.png[alt="epub file",icon="book",iconsfont="font-awesome"] link:phpreflect-book.epub[ePub file] 43 | * image:icons/font-awesome/windows.png[alt="html help file",icon="windows",iconsfont="font-awesome"] [text-danger]*HTML Help file* 44 | -- 45 | ==== 46 | 47 | [role="col-md-6 panels"] 48 | ==== 49 | [panel,info] 50 | .Read it offline (download a zip archive) 51 | -- 52 | * image:icons/font-awesome/files-o.png[alt="multiple html files",icon="files-o",iconsfont="font-awesome"] link:phpreflect-book.chunked.zip[Multiple HTML files] 53 | * image:icons/font-awesome/file-o.png[alt="single html file",icon="file-o",iconsfont="font-awesome"] link:phpreflect-book.xhtml.zip[Single HTML file] 54 | * image:icons/font-awesome/file-pdf-o.png[alt="pdf file",icon="file",iconsfont="font-awesome"] link:phpreflect-book.pdf.zip[PDF file] 55 | * image:icons/font-awesome/book.png[alt="epub file",icon="book",iconsfont="font-awesome"] link:phpreflect-book.epub.zip[ePub file] 56 | * image:icons/font-awesome/windows.png[alt="html help file",icon="windows",iconsfont="font-awesome"] link:phpreflect-book.chm.zip[HTML Help file] 57 | -- 58 | ==== 59 | -------------------------------------------------------------------------------- /src/Bartlett/Reflect/Model/AbstractModel.php: -------------------------------------------------------------------------------- 1 | 11 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 12 | */ 13 | 14 | namespace Bartlett\Reflect\Model; 15 | 16 | /** 17 | * A base class for all Model objects. 18 | * 19 | * @category PHP 20 | * @package PHP_Reflect 21 | * @author Laurent Laville 22 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 23 | * @since Class available since Release 2.0.0RC1 24 | */ 25 | abstract class AbstractModel 26 | { 27 | protected $node; 28 | protected $extension; 29 | 30 | /** 31 | * Base Model class constructor 32 | */ 33 | public function __construct($node) 34 | { 35 | $this->node = $node; 36 | 37 | $versions = $node->getAttribute('compatinfo'); 38 | if ($versions === null) { 39 | $this->extension = 'user'; 40 | } else { 41 | $this->extension = $versions['ext.name']; 42 | } 43 | } 44 | 45 | /** 46 | * Gets doc comments. 47 | * 48 | * @return string 49 | */ 50 | public function getDocComment(): string 51 | { 52 | return (string) $this->node->getDocComment(); 53 | } 54 | 55 | /** 56 | * Gets the starting line number. 57 | * 58 | * @return int 59 | * @see getEndLine() 60 | */ 61 | public function getStartLine(): int 62 | { 63 | return $this->node->getAttribute('startLine'); 64 | } 65 | 66 | /** 67 | * Gets the ending line number. 68 | * 69 | * @return int 70 | * @see getStartLine() 71 | */ 72 | public function getEndLine(): int 73 | { 74 | return $this->node->getAttribute('endLine'); 75 | } 76 | 77 | /** 78 | * Gets the filename of the file in which the element has been defined. 79 | * 80 | * @return string|false 81 | */ 82 | public function getFileName() 83 | { 84 | return realpath($this->node->getAttribute('fileName', '')); 85 | } 86 | 87 | /** 88 | * Gets extension name. 89 | * 90 | * @return string 91 | */ 92 | public function getExtensionName(): string 93 | { 94 | return $this->extension; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /tests/Model/IssueTest.php: -------------------------------------------------------------------------------- 1 | 11 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 12 | * @since Class available since Release 3.0.0-alpha2 13 | */ 14 | 15 | namespace Bartlett\Tests\Reflect\Model; 16 | 17 | use Bartlett\Reflect\Client; 18 | 19 | /** 20 | * Tests for PHP_Reflect, retrieving reference elements, 21 | * and versioning information. 22 | * 23 | * @category PHP 24 | * @package PHP_Reflect 25 | * @subpackage Tests 26 | * @author Laurent Laville 27 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 28 | */ 29 | class IssueTest extends \PHPUnit\Framework\TestCase 30 | { 31 | const GH4 = 'packages.php'; 32 | 33 | protected static $fixtures; 34 | protected static $analyserId; 35 | protected static $api; 36 | 37 | /** 38 | * Sets up the shared fixture. 39 | * 40 | * @return void 41 | */ 42 | public static function setUpBeforeClass(): void 43 | { 44 | self::$fixtures = dirname(__DIR__) . DIRECTORY_SEPARATOR 45 | . 'fixtures' . DIRECTORY_SEPARATOR; 46 | 47 | self::$analyserId = 'Bartlett\Reflect\Analyser\ReflectionAnalyser'; 48 | 49 | $client = new Client(); 50 | 51 | // request for a Bartlett\Reflect\Api\Analyser 52 | self::$api = $client->api('analyser'); 53 | } 54 | 55 | /** 56 | * Regression test for bug GH#4 57 | * 58 | * @link https://github.com/llaville/php-reflect/issues/ 59 | * "Handle namespaces without name" 60 | * @link https://github.com/llaville/php-reflect/pull/4 by Eric Colinet 61 | * @group regression 62 | * @return void 63 | */ 64 | public function testBugGH4() 65 | { 66 | $dataSource = self::$fixtures . self::GH4; 67 | $analysers = array('reflection'); 68 | $metrics = self::$api->run($dataSource, $analysers); 69 | $models = $metrics[self::$analyserId]; 70 | 71 | $c = 0; // empty namespace, class MyGlobalClass 72 | 73 | $this->assertInstanceOf( 74 | 'Bartlett\Reflect\Model\ClassModel', 75 | $models[$c] 76 | ); 77 | $this->assertEquals('MyGlobalClass', $models[$c]->getName()); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bartlett/php-reflect", 3 | "description": "Adds the ability to reverse-engineer classes, interfaces, functions, constants, namespaces, traits and more.", 4 | "keywords": ["reverse-engineer", "reflection"], 5 | "type": "library", 6 | "license": "BSD-3-Clause", 7 | "homepage": "http://php5.laurent-laville.org/reflect/", 8 | "support": { 9 | "source": "https://github.com/llaville/php-reflect", 10 | "issues": "https://github.com/llaville/php-reflect/issues" 11 | }, 12 | "require": { 13 | "php": "^7.1.3|^8.0", 14 | "ext-tokenizer": "*", 15 | "ext-pcre": "*", 16 | "ext-phar": "*", 17 | "ext-spl": "*", 18 | "ext-json": "*", 19 | "ext-date": "*", 20 | "ext-reflection": "*", 21 | "sebastian/version": "^2.0", 22 | "nikic/php-parser": "^4.5", 23 | "doctrine/collections": "^1.4", 24 | "symfony/event-dispatcher": "^4.4|^5.0", 25 | "symfony/finder": "^4.4|^5.0", 26 | "symfony/console": "^4.4|^5.0", 27 | "symfony/stopwatch": "^4.4|^5.0", 28 | "symfony/dependency-injection": "^4.4|^5.0", 29 | "phpdocumentor/reflection-docblock": "^4.3|^5.2", 30 | "phpdocumentor/type-resolver": "~0.4 || ^1.0.0", 31 | "justinrainbow/json-schema": "^5.2", 32 | "seld/jsonlint": "^1.4", 33 | "psr/log": "^1.0" 34 | }, 35 | "require-dev": { 36 | "monolog/monolog": "^1.10" 37 | }, 38 | "suggest": { 39 | "doctrine/cache": "Allow caching results", 40 | "bartlett/monolog-callbackfilterhandler": "Advanced filtering strategies for Monolog", 41 | "bartlett/monolog-growlhandler": "Sends notifications to Growl for Monolog", 42 | "bartlett/phpunit-loggertestlistener": "Allow logging unit tests to your favorite PSR-3 logger interface", 43 | "bartlett/umlwriter": "Allow writing UML class diagrams (Graphviz or PlantUML)" 44 | }, 45 | "authors": [ 46 | { 47 | "name": "Laurent Laville", 48 | "email": "pear@laurent-laville.org", 49 | "homepage": "https://github.com/llaville", 50 | "role": "Lead" 51 | } 52 | ], 53 | "bin": [ 54 | "bin/phpreflect" 55 | ], 56 | "autoload": { 57 | "psr-4": { 58 | "Bartlett\\": "src/Bartlett" 59 | } 60 | }, 61 | "autoload-dev": { 62 | "psr-4": { 63 | "Bartlett\\Tests\\Reflect\\": "tests/" 64 | } 65 | }, 66 | "config": { 67 | "optimize-autoloader": true 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /docs/build/epub.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | REM --- 4 | REM --- Windows CMD script 5 | REM --- to build PHP Reflect documentation in HTML chunked / HTML Help / ePUB / PDF (a4 and us) format 6 | REM --- 7 | REM --- Released under the Apache 2 license (http://www.apache.org/licenses/LICENSE-2.0.html) 8 | REM --- (c) 2014 Laurent Laville 9 | REM --- 10 | 11 | REM 12 | REM See http://www.pnotepad.org/devlog/archives/000173.html to learn hown to configure XML catalogs on Windows 13 | REM Require to generate PDF correctly 14 | REM 15 | 16 | set XML_CATALOG_FILES=c:\xml\catalog.xml 17 | 18 | IF "%ASCIIDOC%"=="" SET "ASCIIDOC=C:\asciidoc-8.6.9" 19 | IF "%ASCIIDOC_BIN%"=="" SET "ASCIIDOC_BIN=%ASCIIDOC%\asciidoc.py" 20 | IF "%A2X_BIN%"=="" SET "A2X_BIN=%ASCIIDOC%\a2x.py" 21 | IF "%ASCIIDOC_THEME%"=="" SET "ASCIIDOC_THEME=cerulean" 22 | IF "%HHC_BIN%"=="" SET "HHC_BIN=C:\Program Files\HTML Help Workshop\hhc.exe" 23 | 24 | REM -- 25 | REM -- WEB HTML CHUNKED FORMAT 26 | REM -- 27 | ECHO GENERATING WEB HTML CHUNKED FORMAT ... 28 | 29 | "%A2X_BIN%" %1 --resource=./images -L --icons --stylesheet=./stylesheets/docbook-xsl.css -d book -f chunked -D . phpreflect-book.asciidoc 30 | 31 | REM -- 32 | REM -- HTML HELP FORMAT 33 | REM -- 34 | ECHO GENERATING HTML HELP FORMAT ... 35 | 36 | "%A2X_BIN%" %1 --resource=./images -L --icons --stylesheet=./stylesheets/docbook-xsl.css -d book -f htmlhelp -D . phpreflect-book.asciidoc 37 | 38 | "%HHC_BIN%" phpreflect-book.hhp 39 | 40 | REM -- 41 | REM -- PDF A4 FORMAT 42 | REM -- 43 | ECHO GENERATING PDF A4 FORMAT ... 44 | 45 | "%A2X_BIN%" %1 %2 --resource=./images -L --icons --stylesheet=./stylesheets/docbook-xsl.css -d book -f pdf --fop phpreflect-book.asciidoc 46 | 47 | MOVE /Y phpreflect-book.pdf phpreflect-book-a4.pdf 48 | 49 | REM -- 50 | REM -- PDF US FORMAT 51 | REM -- 52 | ECHO GENERATING PDF US FORMAT ... 53 | 54 | "%A2X_BIN%" %1 %2 --xsl-file="%ASCIIDOC%"/docbook-xsl/fo-custom.xsl --resource=./images -L --icons --stylesheet=./stylesheets/docbook-xsl.css -d book -f pdf --fop phpreflect-book.asciidoc 55 | 56 | MOVE /Y phpreflect-book.pdf phpreflect-book-us.pdf 57 | 58 | REM -- 59 | REM -- ePUB FORMAT 60 | REM -- 61 | ECHO GENERATING ePUB FORMAT ... 62 | 63 | "%A2X_BIN%" %1 %2 -a docinfo --resource=./images -L --icons --stylesheet=./stylesheets/docbook-xsl.css -d book -f epub phpreflect-book.asciidoc 64 | 65 | REM -- 66 | REM -- Single xHTML page FORMAT 67 | REM -- 68 | ECHO GENERATING Single xHTML page FORMAT ... 69 | 70 | "%A2X_BIN%" %1 %2 --resource=./images -L --icons --stylesheet=./stylesheets/docbook-xsl.css -d book -f xhtml phpreflect-book.asciidoc 71 | -------------------------------------------------------------------------------- /src/Bartlett/Reflect/PhpParser/NodeProcessorAbstract.php: -------------------------------------------------------------------------------- 1 | 9 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 10 | */ 11 | 12 | namespace Bartlett\Reflect\PhpParser; 13 | 14 | use PhpParser\Node; 15 | 16 | /** 17 | * An abstract Node processor to check pre-condition before traversing AST. 18 | * 19 | * @category PHP 20 | * @package PHP_Reflect 21 | * @author Laurent Laville 22 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 23 | * @since Class available since Release 3.0.0-alpha3 24 | */ 25 | class NodeProcessorAbstract implements NodeProcessor 26 | { 27 | protected $processors = array(); 28 | protected $preConditions = array(); 29 | 30 | /** 31 | * {@inheritdoc} 32 | */ 33 | public function push(callable $callback): void 34 | { 35 | array_push($this->processors, $callback); 36 | } 37 | 38 | /** 39 | * {@inheritdoc} 40 | */ 41 | public function getProcessors(): array 42 | { 43 | return $this->processors; 44 | } 45 | 46 | /** 47 | * {@inheritdoc} 48 | */ 49 | public function traverse(array $nodes): array 50 | { 51 | $this->traverseArray($nodes); 52 | return $this->preConditions; 53 | } 54 | 55 | protected function traverseArray(array $nodes) 56 | { 57 | foreach ($nodes as &$node) { 58 | if (is_array($node)) { 59 | $node = $this->traverseArray($node); 60 | } elseif ($node instanceof Node) { 61 | $node = $this->traverseNode($node); 62 | } 63 | } 64 | } 65 | 66 | protected function traverseNode(Node $node) 67 | { 68 | $node = clone $node; 69 | 70 | foreach ($node->getSubNodeNames() as $name) { 71 | $subNode =& $node->$name; 72 | 73 | if (is_array($subNode)) { 74 | $this->traverseArray($subNode); 75 | } elseif ($subNode instanceof Node) { 76 | $this->traverseNode($subNode); 77 | } 78 | } 79 | 80 | foreach ($this->processors as $callback) { 81 | $result = call_user_func($callback, $node); 82 | if (is_array($result)) { 83 | array_push($this->preConditions, $result); 84 | } 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/Bartlett/Reflect/Api/Analyser.php: -------------------------------------------------------------------------------- 1 | 11 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 12 | */ 13 | 14 | namespace Bartlett\Reflect\Api; 15 | 16 | /** 17 | * Collect and analyse metrics of parsing results. 18 | * 19 | * @category PHP 20 | * @package PHP_Reflect 21 | * @author Laurent Laville 22 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 23 | * @since Class available since Release 3.0.0-alpha1 24 | */ 25 | class Analyser extends BaseApi 26 | { 27 | /** 28 | * List all analysers available. 29 | * 30 | * @return array 31 | * @alias list 32 | */ 33 | public function dir() 34 | { 35 | return $this->request('analyser/list'); 36 | } 37 | 38 | /** 39 | * Analyse a data source and display results. 40 | * 41 | * @param string $source Path to the data source or its alias 42 | * @param array $analysers One or more analyser to perform (case insensitive). 43 | * @param mixed $alias If set, the source refers to its alias 44 | * @param string $format If set, convert result to a specific format. 45 | * @param mixed $filter Resource that provide a closure to filter results. 46 | * 47 | * @return array metrics 48 | * @throws \InvalidArgumentException if an analyser required is not installed 49 | * @throws \RuntimeException if filter provided is not a closure 50 | */ 51 | public function run($source, array $analysers, $alias = null, $format = false, $filter = false) 52 | { 53 | $source = trim($source); 54 | if ($alias) { 55 | $alias = $source; 56 | } else { 57 | $alias = false; 58 | } 59 | 60 | if ($filter instanceof \Closure 61 | || $filter === false 62 | ) { 63 | $closure = $filter; 64 | } else { 65 | if ($filterRes = stream_resolve_include_path($filter)) { 66 | include_once $filterRes; 67 | } 68 | if (!isset($closure) || !is_callable($closure)) { 69 | throw new \RuntimeException( 70 | sprintf( 71 | 'Invalid filter provided by file "%s"', 72 | $filterRes ? : $filter 73 | ) 74 | ); 75 | } 76 | } 77 | 78 | return $this->request('analyser/run', 'POST', array($source, $analysers, $alias, $format, $closure)); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/Bartlett/Reflect/Event/AbstractDispatcher.php: -------------------------------------------------------------------------------- 1 | 11 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 12 | */ 13 | 14 | namespace Bartlett\Reflect\Event; 15 | 16 | use Symfony\Component\EventDispatcher\EventDispatcher; 17 | use Symfony\Component\EventDispatcher\EventDispatcherInterface; 18 | use Symfony\Component\EventDispatcher\EventSubscriberInterface; 19 | 20 | /** 21 | * Class that holds an event dispatcher. 22 | * 23 | * @category PHP 24 | * @package PHP_Reflect 25 | * @author Laurent Laville 26 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 27 | * @since Class available since Release 2.0.0RC1 28 | */ 29 | class AbstractDispatcher implements DispatcherInterface 30 | { 31 | /** 32 | * @var EventDispatcherInterface 33 | */ 34 | protected $eventDispatcher; 35 | 36 | /** 37 | * Set the EventDispatcher of the request 38 | * 39 | * @param EventDispatcherInterface $eventDispatcher Instance of the event 40 | * dispatcher 41 | * 42 | * @return self for a fluent interface 43 | * @disabled 44 | */ 45 | public function setEventDispatcher(EventDispatcherInterface $eventDispatcher) 46 | { 47 | $this->eventDispatcher = $eventDispatcher; 48 | return $this; 49 | } 50 | 51 | /** 52 | * Get the EventDispatcher of the request 53 | * 54 | * @return EventDispatcherInterface 55 | * @disabled 56 | */ 57 | public function getEventDispatcher(): EventDispatcherInterface 58 | { 59 | if (!$this->eventDispatcher) { 60 | $this->eventDispatcher = new EventDispatcher(); 61 | } 62 | return $this->eventDispatcher; 63 | } 64 | 65 | /** 66 | * Dispatches an event to all registered listeners. 67 | * 68 | * @param object $event The event to dispatch 69 | * 70 | * @return object 71 | * @disabled 72 | */ 73 | public function dispatch($event) 74 | { 75 | return $this->getEventDispatcher()->dispatch($event); 76 | } 77 | 78 | /** 79 | * Adds an event subscriber. 80 | * 81 | * @param EventSubscriberInterface $subscriber The subscriber which is 82 | * interested by events 83 | * 84 | * @return self for a fluent interface 85 | * @disabled 86 | */ 87 | public function addSubscriber(EventSubscriberInterface $subscriber) 88 | { 89 | $this->getEventDispatcher()->addSubscriber($subscriber); 90 | return $this; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/Bartlett/Reflect/Analyser/ReflectionAnalyser.php: -------------------------------------------------------------------------------- 1 | 9 | * @license http://www.opensource.org/licenses/bsd-license.php BSD License 10 | */ 11 | 12 | namespace Bartlett\Reflect\Analyser; 13 | 14 | use Bartlett\Reflect\Collection\ReflectionCollection; 15 | 16 | use PhpParser\Node; 17 | 18 | /** 19 | * This analyzer collects information about 20 | * classes, interfaces, traits, to produce report like PHP Reflection API 21 | * 22 | * @category PHP 23 | * @package PHP_Reflect 24 | * @author Laurent Laville 25 | * @license http://www.opensource.org/licenses/bsd-license.php BSD License 26 | * @since Class available since Release 3.0.0-alpha1 27 | */ 28 | class ReflectionAnalyser extends AbstractAnalyser 29 | { 30 | public function __construct() 31 | { 32 | $this->metrics = new ReflectionCollection(); 33 | } 34 | 35 | /** 36 | * {@inheritDoc} 37 | */ 38 | public function enterNode(Node $node) 39 | { 40 | parent::enterNode($node); 41 | 42 | if ($node instanceof Node\Stmt\Class_ 43 | || $node instanceof Node\Stmt\Interface_ 44 | || $node instanceof Node\Stmt\Trait_ 45 | ) { 46 | foreach ($node->stmts as $stmt) { 47 | if ($stmt instanceof Node\Stmt\Property) { 48 | $stmt->setAttribute( 49 | 'implicitlyPublic', 50 | $this->isImplicitlyPublicProperty($this->tokens, $stmt) 51 | ); 52 | 53 | } elseif ($stmt instanceof Node\Stmt\ClassMethod) { 54 | $stmt->setAttribute( 55 | 'implicitlyPublic', 56 | $this->isImplicitlyPublicFunction($this->tokens, $stmt) 57 | ); 58 | // remove class methods statements 59 | unset($stmt->stmts); 60 | } 61 | } 62 | $node->setAttribute('fileName', $this->file); 63 | $this->metrics->add($node); 64 | } elseif ($node instanceof Node\Stmt\Function_ 65 | || $node instanceof Node\Expr\Closure 66 | ) { 67 | if (is_array($node->stmts)) { 68 | foreach ($node->stmts as $stmt) { 69 | // remove statements 70 | unset($node->stmts); 71 | } 72 | } 73 | $node->setAttribute('fileName', $this->file); 74 | $this->metrics->add($node); 75 | } elseif ($node instanceof Node\Stmt\Const_) { 76 | $node->setAttribute('fileName', $this->file); 77 | $this->metrics->add($node); 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/Bartlett/Reflect/Plugin/Cache/CacheAdapterInterface.php: -------------------------------------------------------------------------------- 1 | 11 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 12 | */ 13 | 14 | namespace Bartlett\Reflect\Plugin\Cache; 15 | 16 | /** 17 | * Cache adapters allow Reflect to utilize various frameworks for caching parses results. 18 | * 19 | * Reflect doesn't try to reinvent the wheel when it comes to caching. 20 | * Plenty of other frameworks have excellent solutions in place that you are probably 21 | * already using in your applications. Reflect uses adapters for caching. 22 | * The cache plugin requires a cache adapter so that is can store parses results in a cache. 23 | * 24 | * @category PHP 25 | * @package PHP_Reflect 26 | * @author Laurent Laville 27 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 28 | * @since Interface available since Release 2.0.0RC1 29 | */ 30 | interface CacheAdapterInterface 31 | { 32 | /** 33 | * Checks if an entry exists in the cache. 34 | * 35 | * @param string $id The cache id of the entry to check for. 36 | * @param array $options (optional) Array of cache adapter options 37 | * 38 | * @return bool TRUE if a cache entry exists for the given cache id, FALSE otherwise. 39 | */ 40 | public function exists(string $id, array $options = null): bool; 41 | 42 | /** 43 | * Deletes a cache entry. 44 | * 45 | * @param string $id The cache id of the entry to delete. 46 | * @param array $options (optional) Array of cache adapter options 47 | * 48 | * @return bool TRUE on success, FALSE on failure 49 | */ 50 | public function delete(string $id, array $options = null): bool; 51 | 52 | /** 53 | * Fetches an entry from the cache. 54 | * 55 | * @param string $id The cache id of the entry to fetch. 56 | * @param array $options (optional) Array of cache adapter options 57 | * 58 | * @return string The cached data or FALSE, if no cache entry exists for the given id. 59 | */ 60 | public function fetch(string $id, array $options = null); 61 | 62 | /** 63 | * Puts data into the cache. 64 | * 65 | * @param string $id The cache id of the new entry to store. 66 | * @param mixed $data The cache entry/data 67 | * @param mixed $lifeTime (optional) Sets a specific lifetime for this cache entry 68 | * @param array $options (optional) Array of cache adapter options 69 | * 70 | * @return bool TRUE if the entry was successfully stored in the cache, FALSE otherwise. 71 | */ 72 | public function save(string $id, $data, $lifeTime = false, array $options = null): bool; 73 | } 74 | -------------------------------------------------------------------------------- /src/Bartlett/Reflect/Tokenizer/DefaultTokenizer.php: -------------------------------------------------------------------------------- 1 | 'T_OPEN_BRACKET', 13 | ')' => 'T_CLOSE_BRACKET', 14 | '[' => 'T_OPEN_SQUARE', 15 | ']' => 'T_CLOSE_SQUARE', 16 | '{' => 'T_OPEN_CURLY', 17 | '}' => 'T_CLOSE_CURLY', 18 | ';' => 'T_SEMICOLON', 19 | '.' => 'T_DOT', 20 | ',' => 'T_COMMA', 21 | '=' => 'T_EQUAL', 22 | '<' => 'T_LT', 23 | '>' => 'T_GT', 24 | '+' => 'T_PLUS', 25 | '-' => 'T_MINUS', 26 | '*' => 'T_MULT', 27 | '/' => 'T_DIV', 28 | '?' => 'T_QUESTION_MARK', 29 | '!' => 'T_EXCLAMATION_MARK', 30 | ':' => 'T_COLON', 31 | '"' => 'T_DOUBLE_QUOTES', 32 | '@' => 'T_AT', 33 | '&' => 'T_AMPERSAND', 34 | '%' => 'T_PERCENT', 35 | '|' => 'T_PIPE', 36 | '$' => 'T_DOLLAR', 37 | '^' => 'T_CARET', 38 | '~' => 'T_TILDE', 39 | '`' => 'T_BACKTICK' 40 | ); 41 | 42 | public function getTokens(): SplDoublyLinkedList 43 | { 44 | $this->tokenStack->rewind(); 45 | return $this->tokenStack; 46 | } 47 | 48 | public function setTokens(array $tokens): void 49 | { 50 | $this->tokenize($tokens); 51 | } 52 | 53 | public function setSourceFile($file): void 54 | { 55 | $this->tokenize( 56 | token_get_all( 57 | $file->getContents() 58 | ) 59 | ); 60 | } 61 | 62 | /** 63 | * @param string[] $tokens 64 | * 65 | * @return void 66 | */ 67 | protected function tokenize(array $tokens): void 68 | { 69 | $this->tokenStack = new SplDoublyLinkedList; 70 | 71 | foreach ($tokens as $id => $token) { 72 | if (is_array($token)) { 73 | $text = $token[1]; 74 | $line = $token[2]; 75 | $tokenName = token_name($token[0]); 76 | 77 | if ($token[0] == T_WHITESPACE) { 78 | $lines = substr_count($text, "\n"); 79 | if ($lines > 0) { 80 | --$lines; 81 | $line += $lines; 82 | } 83 | } 84 | } else { 85 | $text = $token; 86 | $tokenName = self::$customTokens[$token]; 87 | } 88 | $this->tokenStack->push( 89 | array( 90 | $tokenName, 91 | $text, 92 | $line ?? null, 93 | $id 94 | ) 95 | ); 96 | 97 | if ('T_HALT_COMPILER' == $tokenName) { 98 | break; 99 | } 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /box.json.dist: -------------------------------------------------------------------------------- 1 | { 2 | "directories": ["src"], 3 | "compression": "GZ", 4 | "dump-autoload": false, 5 | "files": [ 6 | "bin/phpreflect.json-schema", 7 | "bin/phpreflect.json.dist", 8 | "manifest.txt", 9 | "LICENSE", 10 | "vendor/doctrine/collections/LICENSE", 11 | "vendor/justinrainbow/json-schema/LICENSE", 12 | "vendor/monolog/monolog/LICENSE", 13 | "vendor/nikic/php-parser/LICENSE", 14 | "vendor/phpdocumentor/reflection-common/LICENSE", 15 | "vendor/phpdocumentor/reflection-docblock/LICENSE", 16 | "vendor/phpdocumentor/type-resolver/LICENSE", 17 | "vendor/psr/container/LICENSE", 18 | "vendor/psr/log/LICENSE", 19 | "vendor/sebastian/version/LICENSE", 20 | "vendor/seld/jsonlint/LICENSE", 21 | "vendor/symfony/console/LICENSE", 22 | "vendor/symfony/dependency-injection/LICENSE", 23 | "vendor/symfony/event-dispatcher/LICENSE", 24 | "vendor/symfony/event-dispatcher-contracts/LICENSE", 25 | "vendor/symfony/finder/LICENSE", 26 | "vendor/symfony/polyfill-ctype/LICENSE", 27 | "vendor/symfony/polyfill-mbstring/LICENSE", 28 | "vendor/symfony/polyfill-php73/LICENSE", 29 | "vendor/symfony/service-contracts/LICENSE", 30 | "vendor/symfony/stopwatch/LICENSE", 31 | "vendor/webmozart/assert/LICENSE", 32 | "vendor/autoload.php" 33 | ], 34 | "finder": [ 35 | { 36 | "name": "*.php", 37 | "in": "vendor/composer" 38 | }, 39 | { 40 | "name": "*.php", 41 | "in": "vendor/nikic/php-parser/lib" 42 | }, 43 | { 44 | "name": "Version.php", 45 | "in": "vendor/sebastian/version/src" 46 | }, 47 | { 48 | "name": "*.php", 49 | "notPath": "/Tests/", 50 | "in": "vendor/symfony" 51 | }, 52 | { 53 | "name": "*.php", 54 | "in": "vendor/seld/jsonlint/src" 55 | }, 56 | { 57 | "name": "*.php", 58 | "in": "vendor/justinrainbow/json-schema/src" 59 | }, 60 | { 61 | "name": "*.php", 62 | "in": "vendor/phpdocumentor/reflection-common/src" 63 | }, 64 | { 65 | "name": "*.php", 66 | "in": "vendor/phpdocumentor/reflection-docblock/src" 67 | }, 68 | { 69 | "name": "*.php", 70 | "in": "vendor/phpdocumentor/type-resolver/src" 71 | }, 72 | { 73 | "name": "*.php", 74 | "in": "vendor/webmozart/assert/src" 75 | }, 76 | { 77 | "name": "*.php", 78 | "in": "vendor/doctrine/collections/lib" 79 | }, 80 | { 81 | "name": "*.php", 82 | "in": "vendor/psr/container/src" 83 | }, 84 | { 85 | "name": "*.php", 86 | "in": "vendor/psr/log/Psr" 87 | }, 88 | { 89 | "name": "*.php", 90 | "in": "vendor/monolog/monolog/src" 91 | } 92 | ], 93 | "stub": "phar-stub.php" 94 | } 95 | -------------------------------------------------------------------------------- /docs/developer-guide--source-provider.asciidoc: -------------------------------------------------------------------------------- 1 | ifndef::basebackend-docbook[] 2 | 3 | = Source Provider 4 | :description: How to identify a data source and parse its contents. 5 | include::revision.asciidoc[] 6 | include::attributes.asciidoc[] 7 | 8 | endif::basebackend-docbook[] 9 | 10 | == Data Source Identification 11 | 12 | [role="lead"] 13 | Basic or Complex Strategy to identify the Data Source. 14 | 15 | WARNING: Now, and for the following chapters, we will not mention how you load the classes. 16 | Depending of the install strategy you've adopted, Composer or other, don't forget to load your autoloader. 17 | 18 | Compare to version 2, 19 | [label label-primary]#Reflect# 3 offers two simple strategies to identify the data source. 20 | 21 | First, is to give the relative or absolute path to file or directory to parse (without limitation). 22 | 23 | Second, is to specify options to customize parsing process, to the 24 | Symfony http://symfony.com/doc/current/components/finder.html[Finder] Component. 25 | 26 | === Basic Strategy 27 | 28 | With all SAPI, no JSON config file is required (as it was for Reflect 2). You have just 29 | to give the relative or absolute path to file or directory to parse. 30 | 31 | It's also possible to specify any archive (phar, zip, tar, tgz, gz, rar) as file source. 32 | 33 | .Example with a simple file or directory (absolute path) 34 | [source,bash] 35 | ---- 36 | $ phpreflect analyser:run /absolute/path/to/source 37 | ---- 38 | 39 | .Example with a simple file or directory (relative path) 40 | [source,bash] 41 | ---- 42 | $ phpreflect analyser:run ./relative/path/to/source 43 | ---- 44 | 45 | === Complex Strategy 46 | 47 | Still as it was with Reflect 2, you will need to configure your data source in a JSON file. 48 | 49 | Syntax is closed to the Symfony Finder Component that is used to limit data source contents to parse. 50 | 51 | .Example to parse an archive 52 | [source,json] 53 | ---- 54 | { 55 | "source-providers": [ 56 | { 57 | "in": "phar:///var/dist/owncloud-7.0.2.tar as owncloud7", 58 | "name": "*.php", 59 | "exclude": ["3rdparty"] 60 | } 61 | ], 62 | "plugins": [ 63 | ], 64 | "analysers" : [ 65 | ] 66 | } 67 | ---- 68 | IMPORTANT: Do not forget the `phar://` protocol in front of archive identification. 69 | 70 | TIP: Use alias named here `owncloud7` to identify data source entry in the JSON config file, 71 | rather than the full path `phar:///var/dist/owncloud-7.0.2.tar`. 72 | 73 | .Example to parse a directory 74 | [source,json] 75 | ---- 76 | { 77 | "source-providers": [ 78 | { 79 | "in": "/home/github/phing/ as phing2", 80 | "path": ["bin", "classes"], 81 | "exclude": ["test"], 82 | "name": "*.php" 83 | } 84 | ], 85 | "plugins": [ 86 | ], 87 | "analysers" : [ 88 | ] 89 | } 90 | ---- 91 | 92 | Learn more about 93 | ifdef::basebackend-docbook[] 94 | directives, see xref:_section_source_providers[] 95 | endif::basebackend-docbook[] 96 | ifdef::basebackend-html[] 97 | link:user-guide--configuration.html#_section_source_providers[source providers]. 98 | endif::basebackend-html[] 99 | -------------------------------------------------------------------------------- /docs/developer-guide--cache-plugin.asciidoc: -------------------------------------------------------------------------------- 1 | = Cache Plugin 2 | :description: Caching specifications to speed up future data source parsing. 3 | include::revision.asciidoc[] 4 | include::attributes.asciidoc[] 5 | 6 | ************************************************ 7 | This plugin is almost unnecessary if you unload the `xdebug` extension 8 | that slows down execution. 9 | Learn more on https://github.com/llaville/php-compat-info/issues/167[RFC]. 10 | ************************************************ 11 | 12 | == Register Plugin 13 | 14 | If you want to use the https://github.com/doctrine/cache[Doctrine cache component], 15 | skip this section. 16 | 17 | If you want to use your own version of cache plugin, use following pattern. 18 | 19 | [source,php] 20 | ---- 21 | 9 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 10 | */ 11 | 12 | namespace Bartlett\Reflect\Client; 13 | 14 | use Symfony\Component\EventDispatcher\EventDispatcherInterface; 15 | 16 | /** 17 | * Client for the local file system. 18 | * 19 | * @category PHP 20 | * @package PHP_Reflect 21 | * @author Laurent Laville 22 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 23 | * @since Class available since Release 3.0.0-alpha2 24 | */ 25 | class LocalClient implements ClientInterface 26 | { 27 | private $namespace; 28 | private $eventDispatcher; 29 | private $registerPlugins; 30 | 31 | /** 32 | * Initialize the local file system client 33 | * 34 | * @param string $url Base of Api Endpoint 35 | */ 36 | public function __construct(string $url = 'Bartlett\Reflect\Api\V3') 37 | { 38 | $this->setNamespace($url); 39 | } 40 | 41 | /** 42 | * Allows to disable all plugins declared in the JSON config file 43 | * 44 | * @param bool $register Activate (default) or not, all plugins declared 45 | * 46 | * @return void 47 | */ 48 | public function activatePlugins(bool $register): void 49 | { 50 | $this->registerPlugins = $register; 51 | } 52 | 53 | /** 54 | * Defines a new namespace of Api 55 | * 56 | * @param string $url Base of Api Endpoint 57 | * 58 | * @return self for a fluent interface 59 | */ 60 | public function setNamespace(string $url) 61 | { 62 | $this->namespace = $url; 63 | return $this; 64 | } 65 | 66 | /** 67 | * {@inheritDoc} 68 | */ 69 | public function request(string $method, string $url, array $params = array()) 70 | { 71 | $parts = explode('/', $url); 72 | 73 | $className = $this->namespace . '\\' . ucfirst($parts[0]); 74 | $methodName = count($parts) > 1 ? $parts[1] : 'invoke'; 75 | 76 | $api = new $className; 77 | $api->setEventDispatcher($this->eventDispatcher); 78 | $api->activatePlugins($this->registerPlugins); 79 | 80 | try { 81 | if (!class_exists($className)) { 82 | throw new \BadFunctionCallException( 83 | sprintf('API class endpoint %s does not exist.', $className) 84 | ); 85 | } 86 | $response = call_user_func_array( 87 | array($api, $methodName), 88 | $params 89 | ); 90 | } catch (\Exception $e) { 91 | $response = $e; 92 | } 93 | 94 | return $response; 95 | } 96 | 97 | /** 98 | * Set the EventDispatcher of the request 99 | * 100 | * @param EventDispatcherInterface $eventDispatcher Instance of the event 101 | * dispatcher 102 | * 103 | * @return self for a fluent interface 104 | */ 105 | public function setEventDispatcher(EventDispatcherInterface $eventDispatcher) 106 | { 107 | $this->eventDispatcher = $eventDispatcher; 108 | return $this; 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /docs/developer-guide--notifier-plugin.asciidoc: -------------------------------------------------------------------------------- 1 | = Notifier Plugin 2 | :description: Notifies application events via different systems. 3 | include::revision.asciidoc[] 4 | include::attributes.asciidoc[] 5 | 6 | == Register Plugin 7 | 8 | Two ways depending of SAPI used. 9 | 10 | If you're on Windows or Mac platform, you may have Growl. If you're on Linux, 11 | the default bundled growl notifier is not for you. Skip this section. 12 | [NOTE] 13 | ==== 14 | * Growl for Windows 15 | * Growl for Mac 16 | ==== 17 | 18 | You'll add to configure your plugin in your `phpreflect.json` file, as follow : 19 | 20 | [source,json] 21 | ---- 22 | { 23 | "name": "Notifier", 24 | "class": "Bartlett\\Reflect\\Plugin\\NotifierPlugin", 25 | "options" : "Bartlett\\CompatInfo\\Plugin\\Notifier\\GrowlNotifier" 26 | } 27 | ---- 28 | 29 | * The `name` key is (since version 3.0.0-alpha1) comment only. 30 | * The `class` key identify the name of the class that implement the plugin (must be fully qualified). 31 | * The `options` key identify the name of the class that implement the notifier (must be fully qualified). 32 | 33 | Default behaviors are : 34 | 35 | * do not notify `reflect.progress` and `reflect.success` events (`enabled` option set to false) 36 | * notify `reflect.error` and `reflect.complete` events, and keep them displayed (`sticky` option set to true). 37 | * used the new `gntp` protocol rather than `udp` basic protocol. 38 | 39 | If one or all of those behaviors does not match your need, here is how to change it. 40 | 41 | Creates your own growl notifier class, (E.g: `YourNamespace\MyGrowlNotifier`) 42 | and put it in somewhere in your `include_path`. 43 | 44 | [source,php] 45 | ---- 46 | api('analyser'); 93 | 94 | // perform request, on a data source with default analyser (structure) 95 | $dataSource = dirname(__DIR__) . '/src'; 96 | $analysers = array('structure'); 97 | 98 | // equivalent to CLI command `phpreflect analyser:run ../src` 99 | $metrics = $api->run($dataSource, $analysers); 100 | 101 | var_export($metrics); 102 | ---- 103 | -------------------------------------------------------------------------------- /docs/stylesheets/pygments.monokai.css: -------------------------------------------------------------------------------- 1 | .highlight .hll { background-color: #49483e } 2 | .highlight { background: #272822; color: #f8f8f2 } 3 | .highlight .c { color: #75715e } /* Comment */ 4 | .highlight .err { color: #960050; background-color: #1e0010 } /* Error */ 5 | .highlight .k { color: #66d9ef } /* Keyword */ 6 | .highlight .l { color: #ae81ff } /* Literal */ 7 | .highlight .n { color: #f8f8f2 } /* Name */ 8 | .highlight .o { color: #f92672 } /* Operator */ 9 | .highlight .p { color: #f8f8f2 } /* Punctuation */ 10 | .highlight .cm { color: #75715e } /* Comment.Multiline */ 11 | .highlight .cp { color: #75715e } /* Comment.Preproc */ 12 | .highlight .c1 { color: #75715e } /* Comment.Single */ 13 | .highlight .cs { color: #75715e } /* Comment.Special */ 14 | .highlight .ge { font-style: italic } /* Generic.Emph */ 15 | .highlight .gs { font-weight: bold } /* Generic.Strong */ 16 | .highlight .kc { color: #66d9ef } /* Keyword.Constant */ 17 | .highlight .kd { color: #66d9ef } /* Keyword.Declaration */ 18 | .highlight .kn { color: #f92672 } /* Keyword.Namespace */ 19 | .highlight .kp { color: #66d9ef } /* Keyword.Pseudo */ 20 | .highlight .kr { color: #66d9ef } /* Keyword.Reserved */ 21 | .highlight .kt { color: #66d9ef } /* Keyword.Type */ 22 | .highlight .ld { color: #e6db74 } /* Literal.Date */ 23 | .highlight .m { color: #ae81ff } /* Literal.Number */ 24 | .highlight .s { color: #e6db74 } /* Literal.String */ 25 | .highlight .na { color: #a6e22e } /* Name.Attribute */ 26 | .highlight .nb { color: #f8f8f2 } /* Name.Builtin */ 27 | .highlight .nc { color: #a6e22e } /* Name.Class */ 28 | .highlight .no { color: #66d9ef } /* Name.Constant */ 29 | .highlight .nd { color: #a6e22e } /* Name.Decorator */ 30 | .highlight .ni { color: #f8f8f2 } /* Name.Entity */ 31 | .highlight .ne { color: #a6e22e } /* Name.Exception */ 32 | .highlight .nf { color: #a6e22e } /* Name.Function */ 33 | .highlight .nl { color: #f8f8f2 } /* Name.Label */ 34 | .highlight .nn { color: #f8f8f2 } /* Name.Namespace */ 35 | .highlight .nx { color: #a6e22e } /* Name.Other */ 36 | .highlight .py { color: #f8f8f2 } /* Name.Property */ 37 | .highlight .nt { color: #f92672 } /* Name.Tag */ 38 | .highlight .nv { color: #f8f8f2 } /* Name.Variable */ 39 | .highlight .ow { color: #f92672 } /* Operator.Word */ 40 | .highlight .w { color: #f8f8f2 } /* Text.Whitespace */ 41 | .highlight .mf { color: #ae81ff } /* Literal.Number.Float */ 42 | .highlight .mh { color: #ae81ff } /* Literal.Number.Hex */ 43 | .highlight .mi { color: #ae81ff } /* Literal.Number.Integer */ 44 | .highlight .mo { color: #ae81ff } /* Literal.Number.Oct */ 45 | .highlight .sb { color: #e6db74 } /* Literal.String.Backtick */ 46 | .highlight .sc { color: #e6db74 } /* Literal.String.Char */ 47 | .highlight .sd { color: #e6db74 } /* Literal.String.Doc */ 48 | .highlight .s2 { color: #e6db74 } /* Literal.String.Double */ 49 | .highlight .se { color: #ae81ff } /* Literal.String.Escape */ 50 | .highlight .sh { color: #e6db74 } /* Literal.String.Heredoc */ 51 | .highlight .si { color: #e6db74 } /* Literal.String.Interpol */ 52 | .highlight .sx { color: #e6db74 } /* Literal.String.Other */ 53 | .highlight .sr { color: #e6db74 } /* Literal.String.Regex */ 54 | .highlight .s1 { color: #e6db74 } /* Literal.String.Single */ 55 | .highlight .ss { color: #e6db74 } /* Literal.String.Symbol */ 56 | .highlight .bp { color: #f8f8f2 } /* Name.Builtin.Pseudo */ 57 | .highlight .vc { color: #f8f8f2 } /* Name.Variable.Class */ 58 | .highlight .vg { color: #f8f8f2 } /* Name.Variable.Global */ 59 | .highlight .vi { color: #f8f8f2 } /* Name.Variable.Instance */ 60 | .highlight .il { color: #ae81ff } /* Literal.Number.Integer.Long */ -------------------------------------------------------------------------------- /src/Bartlett/Reflect/Client.php: -------------------------------------------------------------------------------- 1 | 11 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 12 | */ 13 | 14 | namespace Bartlett\Reflect; 15 | 16 | use Bartlett\Reflect\Api\BaseApi; 17 | use Bartlett\Reflect\Client\ClientInterface; 18 | use Bartlett\Reflect\Client\LocalClient; 19 | 20 | /** 21 | * Client for interacting with the API 22 | * 23 | * @category PHP 24 | * @package PHP_Reflect 25 | * @author Laurent Laville 26 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 27 | * @since Class available since Release 3.0.0-alpha1 28 | */ 29 | class Client 30 | { 31 | const API_V3 = 'http://php5.laurent-laville.org/reflect/api/v3/'; 32 | 33 | private $client; 34 | private $token; 35 | 36 | /** 37 | * Initialize a client for interacting with the API 38 | * 39 | * @param ClientInterface $client 40 | * @param string $url 41 | */ 42 | public function __construct(ClientInterface $client = null, string $url = self::API_V3) 43 | { 44 | $this->initializeClient($url, $client); 45 | } 46 | 47 | /** 48 | * Returns an Api 49 | * 50 | * @param string $name Api method to perform 51 | * 52 | * @return BaseApi 53 | * @throws \InvalidArgumentException 54 | */ 55 | public function api($name): BaseApi 56 | { 57 | $classes = array( 58 | 'Bartlett\Reflect\Api\\' => array( 59 | 'Analyser', 60 | 'Cache', 61 | 'Config', 62 | 'Diagnose', 63 | 'Diagram', 64 | 'Plugin', 65 | 'Reflection', 66 | ), 67 | 'Bartlett\CompatInfo\Api\\' => array( 68 | 'Reference' 69 | ), 70 | ); 71 | 72 | $class = false; 73 | 74 | foreach ($classes as $ns => $basename) { 75 | if (in_array(ucfirst($name), $basename)) { 76 | $class = $ns . ucfirst($name); 77 | break; 78 | } 79 | } 80 | 81 | if (!$class || !class_exists($class)) { 82 | throw new \InvalidArgumentException( 83 | sprintf('Unknown Api "%s" requested', $name) 84 | ); 85 | } 86 | if ($this->client instanceof LocalClient) { 87 | $this->client->setNamespace($ns . 'V3'); 88 | } 89 | return new $class($this->client, $this->token); 90 | } 91 | 92 | /** 93 | * Authorizes an Api 94 | * 95 | * @param $token 96 | * 97 | * @return void 98 | */ 99 | public function authorize($token): void 100 | { 101 | $this->token = $token; 102 | } 103 | 104 | /** 105 | * Initializes a http or local client 106 | * 107 | * @param string $url Base URL of endpoints 108 | * @param ClientInterface $client (optional) client to use 109 | * 110 | * @return void 111 | */ 112 | private function initializeClient(string $url, ClientInterface $client = null): void 113 | { 114 | if ($client) { 115 | $this->client = $client; 116 | } else { 117 | $this->client = new LocalClient($url); 118 | } 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/Bartlett/Reflect/Plugin/PluginManager.php: -------------------------------------------------------------------------------- 1 | 11 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 12 | */ 13 | 14 | namespace Bartlett\Reflect\Plugin; 15 | 16 | use Bartlett\Reflect\Environment; 17 | use Bartlett\Reflect\Api\V3\Config; 18 | 19 | use Seld\JsonLint\ParsingException; 20 | 21 | use Symfony\Component\EventDispatcher\EventDispatcherInterface; 22 | use Symfony\Component\EventDispatcher\EventSubscriberInterface; 23 | 24 | /** 25 | * Plugin manager 26 | * 27 | * @category PHP 28 | * @package PHP_Reflect 29 | * @author Laurent Laville 30 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 31 | * @since Class available since Release 3.0.0-alpha1 32 | */ 33 | class PluginManager 34 | { 35 | protected $eventDispatcher; 36 | 37 | protected $plugins = array(); 38 | 39 | /** 40 | * Initializes plugin manager 41 | * 42 | * @param EventDispatcherInterface $eventDispatcher Instance of an event 43 | * dispatcher 44 | */ 45 | public function __construct(EventDispatcherInterface $eventDispatcher) 46 | { 47 | $this->eventDispatcher = $eventDispatcher; 48 | } 49 | 50 | /** 51 | * Loads all plugins declared in the JSON config file. 52 | * 53 | * @return void 54 | * @throws ParsingException 55 | */ 56 | public function registerPlugins(): void 57 | { 58 | $jsonFile = Environment::getJsonConfigFilename(); 59 | if (!$jsonFile) { 60 | return; 61 | } 62 | 63 | $config = new Config; 64 | $var = $config->validate($jsonFile); 65 | 66 | foreach ($var['plugins'] as $plugin) { 67 | if (class_exists($plugin['class'])) { 68 | if (isset($plugin['options'])) { 69 | $options = $plugin['options']; 70 | if (is_string($options)) { 71 | if (class_exists($options)) { 72 | $options = new $options; 73 | } else { 74 | $options = null; 75 | } 76 | } 77 | } else { 78 | $options = null; 79 | } 80 | $plugin = new $plugin['class']($options); 81 | 82 | if ($plugin instanceof PluginInterface) { 83 | $this->addPlugin($plugin); 84 | } 85 | } 86 | } 87 | } 88 | 89 | /** 90 | * Adds a plugin, activates it and registers it with the event dispatcher 91 | * 92 | * @param PluginInterface $plugin Plugin instance 93 | * 94 | * @return void 95 | */ 96 | public function addPlugin(PluginInterface $plugin): void 97 | { 98 | $this->plugins[] = $plugin; 99 | 100 | $plugin->activate($this->eventDispatcher); 101 | 102 | if ($plugin instanceof EventSubscriberInterface) { 103 | $this->eventDispatcher->addSubscriber($plugin); 104 | } 105 | } 106 | 107 | /** 108 | * Gets all currently active plugin instances 109 | * 110 | * @return array plugins 111 | */ 112 | public function getPlugins(): array 113 | { 114 | return $this->plugins; 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /docs/developer-guide--analysers.asciidoc: -------------------------------------------------------------------------------- 1 | = Build your Analysers 2 | :description: How to extend analyser Reflect's features. 3 | include::revision.asciidoc[] 4 | include::attributes.asciidoc[] 5 | 6 | 7 | [role="lead"] 8 | Analysers implements the http://en.wikipedia.org/wiki/Visitor_pattern[Visitor] pattern 9 | in a simple and effective way to make the render of your results truly customizable. 10 | 11 | == Visitor pattern 12 | 13 | Each +Analyser+ class must implement two interfaces +Bartlett\Reflect\Analyser\AnalyserInterface+, 14 | and +PhpParser\NodeVisitor+. 15 | 16 | Your first own analyser may start like that : 17 | 18 | [source,php] 19 | ---- 20 | 11 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 12 | */ 13 | 14 | namespace Bartlett\Reflect\Api\V3; 15 | 16 | use Bartlett\Reflect\Model; 17 | 18 | /** 19 | * Reflection API 20 | * 21 | * @category PHP 22 | * @package PHP_Reflect 23 | * @author Laurent Laville 24 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 25 | * @since Class available since Release 3.0.0-alpha1 26 | */ 27 | class Reflection extends Common 28 | { 29 | public function __call($name, $args) 30 | { 31 | if ('class' == $name) { 32 | return call_user_func_array(array($this, 'class_'), $args); 33 | } elseif ('function' == $name) { 34 | return call_user_func_array(array($this, 'function_'), $args); 35 | } 36 | } 37 | 38 | /** 39 | * Reports information about a user class present in a data source. 40 | * 41 | * @param string $argument Name of the class to reflect. 42 | * @param string $source Path to the data source or its alias. 43 | * @param mixed $alias If set, the source refers to its alias. 44 | * @param string $format To ouput results in other formats. 45 | * 46 | * @return mixed 47 | */ 48 | public function class_($argument, $source, $alias = null, $format = 'txt') 49 | { 50 | $api = new Analyser(); 51 | $api->setEventDispatcher($this->eventDispatcher); 52 | $metrics = $api->run($source, array('reflection'), $alias, false, false); 53 | 54 | $collect = $metrics['Bartlett\Reflect\Analyser\ReflectionAnalyser']->filter( 55 | function ($element) use ($argument) { 56 | return $element instanceof Model\ClassModel 57 | && $element->getName() === $argument; 58 | } 59 | ); 60 | 61 | if (count($collect) === 0) { 62 | throw new \Exception( 63 | sprintf('Class "%s" not found.', $argument) 64 | ); 65 | } 66 | return $collect->first(); 67 | } 68 | 69 | /** 70 | * Reports information about a user function present in a data source. 71 | * 72 | * @param string $argument Name of the function to reflect. 73 | * @param string $source Path to the data source or its alias. 74 | * @param mixed $alias If set, the source refers to its alias. 75 | * @param string $format To ouput results in other formats. 76 | * 77 | * @return mixed 78 | */ 79 | public function function_($argument, $source, $alias = null, $format = 'txt') 80 | { 81 | $api = new Analyser(); 82 | $api->setEventDispatcher($this->eventDispatcher); 83 | $metrics = $api->run($source, array('reflection'), $alias, false, false); 84 | 85 | $collect = $metrics['Bartlett\Reflect\Analyser\ReflectionAnalyser']->filter( 86 | function ($element) use ($argument) { 87 | return $element instanceof Model\FunctionModel 88 | && $element->getName() === $argument; 89 | } 90 | ); 91 | 92 | if (count($collect) === 0) { 93 | throw new \Exception( 94 | sprintf('Function "%s" not found.', $argument) 95 | ); 96 | } 97 | return $collect->first(); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | This project adheres to [Semantic Versioning](http://semver.org/), 5 | using the [Keep a CHANGELOG](http://keepachangelog.com) principles. 6 | 7 | ## [Unreleased] 8 | 9 | ## [4.4.x-dev] 10 | 11 | Project reached End-Of-Life (2020-09-15). 12 | No features will be accepted. Only bug and security fixes will be proceeded. 13 | 14 | ## [4.4.1] - 2020-10-06 15 | 16 | ### Fixed 17 | 18 | - Allows installation with PHP 8.0 19 | - Named parameters confusion with PHP 8 (thanks to @remicollet for his PR on CompatInfo) 20 | 21 | ## [4.4.0] - 2020-07-07 22 | 23 | ### Added 24 | 25 | - Event classes `Bartlett\Reflect\Event\*Event` to follow principle of simpler event dispatching 26 | 27 | ### Changed 28 | 29 | - Drop support to Symfony 2 and 3, and allows only Symfony 4 LTS and Symfony 5 30 | - Drop support to PHP 5 31 | - Drop support to `sebastian/version` v1 32 | - Raise `phpdocumentor/reflection-docblock` constraint to v4 to allows only PHP 7 compatibility 33 | - Raise `phpdocumentor/type-resolver` constraint to v0.4 or v1.0 (on recommendation of @remicollet) 34 | - Raise `justinrainbow/json-schema` constraint to v5.2 35 | - Raise `seld/jsonlint` constraint to v1.4 36 | - Raise `nikic/php-parser` constraint to v4.5 37 | - [Simpler event dispatching](https://symfony.com/blog/new-in-symfony-4-3-simpler-event-dispatching) is possible since Symfony 4.3 38 | - Clean-up phpDoc tags 39 | - Sets PHP minimum requirement to 7.1.3 40 | 41 | ### Removed 42 | 43 | - Application Events class constants `Bartlett\Reflect\Events` (replaced by individual Event class. See simpler event dispatching) 44 | - public method `Bartlett\Reflect\Console\Application::setDispatcher` was removed and replaced by private method `Bartlett\Reflect\Console\Application::initDispatcher` 45 | to avoid conflict between Symfony 4.4 and Symfony 5.x 46 | 47 | ### Fixed 48 | 49 | - **CachePlugin** : if TEMP env var is not defined, fallback to [sys_get_temp_dir()](https://www.php.net/manual/en/function.sys-get-temp-dir.php) 50 | 51 | ## [4.3.1] - 2020-02-26 52 | 53 | ### Changed 54 | 55 | - Add support to Symfony 4 components (Thanks to @remicollet for his PR to solve issue GH-36) 56 | 57 | ## [4.3.0] - 2018-11-25 58 | 59 | ### Changed 60 | 61 | - update PHP-Parser to 3.1 for parsing code from PHP 5.2 to 7.2 on PHP 62 | platform 5.5 or better 63 | - add support to Symfony Components 4.x 64 | 65 | ## [4.2.2] - 2017-12-14 66 | 67 | ### Fixed 68 | 69 | - fix regression with previous cache configuration (thanks to Remi Collet) 70 | 71 | ## [4.2.1] - 2017-12-12 72 | 73 | ### Changed 74 | 75 | - fix minimum requirements to PHP 5.5 76 | 77 | ## [4.2.0] - 2017-12-12 78 | 79 | ### Added 80 | 81 | - show PHP-Parser errors, when found on php scripts 82 | 83 | ## [4.1.0] - 2017-04-10 84 | 85 | - update to PHP-Parser 2.1 86 | 87 | ## [4.0.0] - 2015-12-04 88 | 89 | - introduce sniff architecture, and drop support to PHP 5.3 90 | 91 | [unreleased]: https://github.com/llaville/php-reflect/compare/4.4.0...HEAD 92 | [4.4.0]: https://github.com/llaville/php-reflect/compare/4.3.1...4.4.0 93 | [4.3.1]: https://github.com/llaville/php-reflect/compare/4.3.0...4.3.1 94 | [4.3.0]: https://github.com/llaville/php-reflect/compare/4.2.2...4.3.0 95 | [4.2.2]: https://github.com/llaville/php-reflect/compare/4.2.1...4.2.2 96 | [4.2.1]: https://github.com/llaville/php-reflect/compare/4.2.0...4.2.1 97 | [4.2.0]: https://github.com/llaville/php-reflect/compare/4.2.1...4.2.0 98 | [4.1.0]: https://github.com/llaville/php-reflect/compare/4.0.0...4.1.0 99 | [4.0.0]: https://github.com/llaville/php-reflect/compare/3.1.2...4.0.0 100 | -------------------------------------------------------------------------------- /docs/developer-guide--filters.asciidoc: -------------------------------------------------------------------------------- 1 | = Build your Filters 2 | :description: How to filter analyser Reflect's results. 3 | include::revision.asciidoc[] 4 | include::attributes.asciidoc[] 5 | 6 | 7 | [role="lead"] 8 | If you want to restrict final results to one ore more criteria, the filter feature 9 | is what you are waiting for. 10 | 11 | NOTE: This feature was introduced in [label label-primary]#Reflect# [label label-info]#3.1.0#. 12 | 13 | == Your first filter 14 | 15 | Here, our goal is to remove some elements of the default report. 16 | 17 | [source, php] 18 | .Script `YourFilters.php` 19 | ---- 20 | &$keys) { 32 | if (strpos($title, 'StructureAnalyser') === false) { 33 | continue; 34 | } 35 | // looking into Structure Analyser metrics only 36 | foreach ($keys as $key => $val) { 37 | if (!in_array($key, $filterOnKeys)) { 38 | unset($keys[$key]); // "removed" unsolicited values 39 | continue; 40 | } 41 | } 42 | } 43 | return $data; 44 | }; 45 | return $closure; 46 | ---- 47 | 48 | WARNING: The filter's file that host the `$closure`, must be resolvable through the include_path. 49 | 50 | CAUTION: Be carefull, with filter source code, or unwanted results may occured. 51 | 52 | TIP: You have ability to remove definitively (`unset`), or remove partially (`false`), 53 | values in response through the filter. 54 | 55 | NOTE: Only one filter is allowed at same run, but you can combine one or more analyser rules. 56 | 57 | == SAPI usage 58 | 59 | On CLI, invoke the `analyser:run` command with the `--filter` option. E.g: 60 | [source, bash] 61 | ---- 62 | $ phpreflect analyser:run --filter=YourFilters.php src 63 | ---- 64 | 65 | On other SAPI, follow example pattern like: 66 | [source, php] 67 | ---- 68 | api('analyser'); 77 | 78 | // perform request, on a data source with two analysers (structure, loc) 79 | $dataSource = dirname(__DIR__) . '/src'; 80 | $analysers = array('structure', 'loc'); 81 | 82 | // filter rules on final results 83 | $closure = function ($data) { 84 | $filterOnKeys = array( 85 | 'classes', 'abstractClasses', 'concreteClasses', 86 | 'classConstants', 'globalConstants', 'magicConstants', 87 | ); 88 | 89 | foreach ($data as $title => &$keys) { 90 | if (strpos($title, 'StructureAnalyser') === false) { 91 | continue; 92 | } 93 | // looking into Structure Analyser metrics and keep classes and constants info 94 | foreach ($keys as $key => $val) { 95 | if (!in_array($key, $filterOnKeys)) { 96 | unset($keys[$key]); // "removed" unsolicited values 97 | continue; 98 | } 99 | } 100 | } 101 | return $data; 102 | }; 103 | 104 | // equivalent to CLI command `phpreflect analyser:run --filter=YourFilters.php ../src structure loc` 105 | //$metrics = $api->run($dataSource, $analysers, null, false, $closure = 'YourFilters.php'); 106 | 107 | // OR with embeded $closure code 108 | $metrics = $api->run($dataSource, $analysers, null, false, $closure); 109 | ---- 110 | -------------------------------------------------------------------------------- /src/Bartlett/Reflect/Model/ConstantModel.php: -------------------------------------------------------------------------------- 1 | 11 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 12 | */ 13 | 14 | namespace Bartlett\Reflect\Model; 15 | 16 | use PhpParser\Node; 17 | use PhpParser\PrettyPrinter; 18 | 19 | /** 20 | * The ConstantModel class reports information about a constant. 21 | * 22 | * @category PHP 23 | * @package PHP_Reflect 24 | * @author Laurent Laville 25 | * @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License 26 | * @since Class available since Release 2.0.0RC1 27 | */ 28 | class ConstantModel extends AbstractModel 29 | { 30 | /** 31 | * Get the namespace name where the constant is defined. 32 | * 33 | * @return string 34 | */ 35 | public function getNamespaceName(): string 36 | { 37 | $parts = $this->node->consts[0]->namespacedName->parts; 38 | array_pop($parts); 39 | return implode('\\', $parts); 40 | } 41 | 42 | /** 43 | * Gets the constant name. 44 | * 45 | * @return string 46 | */ 47 | public function getName(): string 48 | { 49 | return (string) $this->node->consts[0]->namespacedName; 50 | } 51 | 52 | /** 53 | * Get the short name of the constant (without the namespace part). 54 | * 55 | * @return string 56 | */ 57 | public function getShortName(): string 58 | { 59 | return (string) $this->node->consts[0]->name; 60 | } 61 | 62 | /** 63 | * Gets the constant value. 64 | * 65 | * @return mixed 66 | */ 67 | public function getValue() 68 | { 69 | $prettyPrinter = new PrettyPrinter\Standard; 70 | return trim( 71 | $prettyPrinter->prettyPrintExpr($this->node->consts[0]->value), 72 | '"\'' 73 | ); 74 | } 75 | 76 | /** 77 | * Checks whether a constant is defined in a namespace. 78 | * 79 | * @return bool TRUE if it's in a namespace, otherwise FALSE 80 | */ 81 | public function inNamespace(): bool 82 | { 83 | return $this->node->consts[0]->namespacedName->isQualified(); 84 | } 85 | 86 | /** 87 | * Checks whether it's an internal constant. 88 | * 89 | * @return bool TRUE if it's internal, otherwise FALSE 90 | */ 91 | public function isInternal(): bool 92 | { 93 | return false; 94 | } 95 | 96 | /** 97 | * Checks whether it's a magic constant. 98 | * 99 | * @link http://www.php.net/manual/en/language.constants.predefined.php 100 | * @return bool TRUE if it's magic, otherwise FALSE 101 | */ 102 | public function isMagic(): bool 103 | { 104 | return false; 105 | } 106 | 107 | /** 108 | * Checks whether it's a scalar constant. 109 | * 110 | * @return bool TRUE if it's scalar, otherwise FALSE 111 | */ 112 | public function isScalar(): bool 113 | { 114 | return ($this->node->consts[0]->value instanceof Node\Scalar); 115 | } 116 | 117 | /** 118 | * Returns the string representation of the ConstantModel object. 119 | * 120 | * @return string 121 | */ 122 | public function __toString(): string 123 | { 124 | $eol = "\n"; 125 | 126 | return sprintf( 127 | 'Constant [ %s ] { %s }%s', 128 | $this->getName(), 129 | $this->getValue(), 130 | $eol 131 | ); 132 | } 133 | } 134 | --------------------------------------------------------------------------------