├── .github ├── flake.lock ├── flake.nix └── workflows │ └── ci.yml ├── .gitignore ├── CHANGELOG.markdown ├── LICENSE ├── README.markdown ├── bin ├── phpcb └── phpcb.bat ├── box.json ├── build.xml ├── composer.json ├── package.xml ├── phpcs.xml.dist ├── phpstan.neon ├── phpstan_baseline.neon ├── phpunit.xml.dist ├── src └── PHPCodeBrowser │ ├── AbstractPlugin.php │ ├── Application.php │ ├── CLIController.php │ ├── Command │ └── RunCommand.php │ ├── File.php │ ├── Helper │ └── IOHelper.php │ ├── Issue.php │ ├── IssueXML.php │ ├── Plugins │ ├── ErrorCPD.php │ ├── ErrorCRAP.php │ ├── ErrorCheckstyle.php │ ├── ErrorCoverage.php │ ├── ErrorPMD.php │ └── ErrorPadawan.php │ ├── SourceHandler.php │ ├── Tests │ ├── AbstractTestCase.php │ ├── ApplicationTest.php │ ├── CLIControllerTest.php │ ├── FileTest.php │ ├── Fixtures │ │ ├── Bad.php │ │ └── Good.php │ ├── Helper │ │ └── IOHelperTest.php │ ├── IssueTest.php │ ├── Plugins │ │ ├── ErrorCPDTest.php │ │ ├── ErrorCRAPTest.php │ │ ├── ErrorCheckstyleTest.php │ │ ├── ErrorCoverageTest.php │ │ └── ErrorPMDTest.php │ ├── SourceHandlerTest.php │ ├── View │ │ └── ViewReviewTest.php │ └── testData │ │ └── logs │ │ └── basic.xml │ └── View │ ├── ViewAbstract.php │ └── ViewReview.php └── templates ├── css ├── cruisecontrol.css ├── global.css ├── review.css └── tree.css ├── img ├── background.gif ├── base.gif ├── cd.gif ├── empty.gif ├── folder.gif ├── folderopen.gif ├── globe.gif ├── imgfolder.gif ├── join.gif ├── joinbottom.gif ├── line.gif ├── minus.gif ├── minusbottom.gif ├── musicfolder.gif ├── nolines_minus.gif ├── nolines_plus.gif ├── page.gif ├── page.png ├── plus.gif ├── plusbottom.gif ├── question.gif ├── separator.gif ├── slider.gif ├── tab-active.png ├── trash.gif ├── treeToggle-collapsed.png ├── treeToggle-extended.png └── treeToggle.gif ├── index.tpl ├── js ├── jquery-1.4.2.js ├── jquery-1.4.2.min.js ├── jquery.cluetip │ ├── images │ │ ├── arrowdown.gif │ │ ├── arrowleft.gif │ │ ├── arrowright.gif │ │ ├── arrowup.gif │ │ ├── bl.gif │ │ ├── bl.png │ │ ├── br.gif │ │ ├── br.png │ │ ├── darrowdown.gif │ │ ├── darrowleft.gif │ │ ├── darrowright.gif │ │ ├── darrowup.gif │ │ ├── itunes.png │ │ ├── rarrowdown.gif │ │ ├── rarrowleft.gif │ │ ├── rarrowright.gif │ │ ├── rarrowup.gif │ │ ├── tl.gif │ │ ├── tl.png │ │ ├── tr.gif │ │ ├── tr.png │ │ └── wait.gif │ ├── jquery.cluetip.css │ ├── jquery.cluetip.js │ ├── jquery.cluetip.min.js │ └── lib │ │ ├── jquery.bgiframe.min.js │ │ └── jquery.hoverIntent.js ├── jquery.history.js ├── jquery.jstree │ ├── jquery.jstree.js │ ├── jquery.jstree.min.js │ └── themes │ │ └── default │ │ ├── d.png │ │ ├── dot_for_ie.gif │ │ ├── style.css │ │ └── throbber.gif ├── jquery.sidebar │ ├── css │ │ └── codebrowser │ │ │ ├── inject-bottom.png │ │ │ ├── inject-left.png │ │ │ ├── inject-right.png │ │ │ ├── inject-top.png │ │ │ └── sidebar.css │ ├── jquery-ui-1.7.2.custom.min.js │ └── jquery.sidebar.js ├── review.js └── tree.js ├── noErrors.tpl └── review.tpl /.github/flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "nixpkgs": { 4 | "locked": { 5 | "lastModified": 1673606088, 6 | "narHash": "sha256-wdYD41UwNwPhTdMaG0AIe7fE1bAdyHe6bB4HLUqUvck=", 7 | "owner": "NixOS", 8 | "repo": "nixpkgs", 9 | "rev": "37b97ae3dd714de9a17923d004a2c5b5543dfa6d", 10 | "type": "github" 11 | }, 12 | "original": { 13 | "id": "nixpkgs", 14 | "type": "indirect" 15 | } 16 | }, 17 | "root": { 18 | "inputs": { 19 | "nixpkgs": "nixpkgs" 20 | } 21 | } 22 | }, 23 | "root": "root", 24 | "version": 7 25 | } 26 | -------------------------------------------------------------------------------- /.github/flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "A php test environment flake"; 3 | 4 | outputs = { self, nixpkgs }: 5 | let 6 | system = "x86_64-linux"; 7 | pkgs = nixpkgs.legacyPackages."${system}"; 8 | 9 | phpEnv = phpPackage: (phpPackage.buildEnv { 10 | extensions = { enabled, all }: (enabled ++ [ all.xdebug ]); 11 | extraConfig = '' 12 | memory_limit=-1 13 | xdebug.mode=coverage 14 | '' + 15 | pkgs.lib.optionalString (pkgs.lib.versionOlder phpPackage.version "8.0") '' 16 | xdebug.coverage_enable=1 17 | ''; 18 | }); 19 | 20 | phpVersions = [ 21 | "php80" 22 | "php81" 23 | "php82" 24 | ]; 25 | in 26 | { 27 | packages."${system}" = builtins.listToAttrs 28 | (builtins.map 29 | (name: 30 | { 31 | name = "env-${name}"; 32 | value = pkgs.symlinkJoin { 33 | name = "env-${name}"; 34 | paths = [ 35 | (phpEnv pkgs."${name}") 36 | (phpEnv pkgs."${name}").packages.composer 37 | ]; 38 | }; 39 | } 40 | ) 41 | phpVersions); 42 | }; 43 | } 44 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: Simple Nix Flakes powered php ci. 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | ci: 7 | 8 | runs-on: ubuntu-latest 9 | 10 | strategy: 11 | matrix: 12 | php: [php80, php81, php82] 13 | 14 | steps: 15 | - uses: actions/checkout@v2 16 | with: 17 | # Nix Flakes doesn't work on shallow clones 18 | fetch-depth: 0 19 | 20 | - uses: cachix/install-nix-action@v18 21 | 22 | - name: Cache Composer dependencies 23 | uses: actions/cache@v2 24 | with: 25 | path: /home/runner/.cache/composer 26 | key: ${{ runner.os }}-composer-${{ matrix.php }}-${{ hashFiles('**/composer.lock') }} 27 | restore-keys: | 28 | ${{ runner.os }}-composer- 29 | 30 | - run: | 31 | rm -fr vendor 32 | nix shell .github#env-${{ matrix.php }} --command composer ci-prepare 33 | nix shell .github#env-${{ matrix.php }} --command composer ci 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .buildpath 2 | .project 3 | .settings* 4 | .idea/ 5 | build 6 | vendor 7 | composer.lock 8 | *.phar 9 | -------------------------------------------------------------------------------- /CHANGELOG.markdown: -------------------------------------------------------------------------------- 1 | PHP_CodeBrowser 1.1.0 2 | ------------------- 3 | * Switch to stable composer dependencies (Symfony2 Console and Monolog) 4 | 5 | PHP_CodeBrowser 1.0.4 6 | ------------------- 7 | * Fix invalid XML errors 8 | 9 | PHP_CodeBrowser 1.0.3 10 | ------------------- 11 | * If mbstring is available, we'll now try to detect file encodings 12 | * Allow the exclusion of files without errors 13 | 14 | PHP_CodeBrowser 1.0.2 15 | ------------------- 16 | * Fixed some bugs. 17 | * Allow custom extensions for php files 18 | 19 | PHP_CodeBrowser 1.0 20 | ------------------- 21 | 22 | * Added --ignore option. 23 | * Fixed a few bugs. 24 | * Improved windows support. 25 | 26 | PHP_CodeBrowser 0.9.1 27 | --------------------- 28 | 29 | * Fixed various Windows-related issues. 30 | * Added error/warning count to the file tree. 31 | * Added a commandline switch to debug exclude options. 32 | * Made XHTML output W3C-compliant. 33 | 34 | PHP_CodeBrowser 0.9.0 35 | --------------------- 36 | 37 | * Added support for CRAP with PHPUnit 3.5 38 | * Improved performance 39 | * Now using jQuery as JavaScript framework 40 | * Added --exclude and --excludePCRE option 41 | * Allowed multiple --source options 42 | 43 | PHP_CodeBrowser 0.1.4 44 | --------------------- 45 | 46 | * Fixed missing line numbers bug in PMD plugin 47 | * Fixed bug in PMD plugin (Issue #5) 48 | * Now using Sebastian Bergmann's PHP_Timer utility 49 | 50 | 51 | PHP_CodeBrowser 0.1.3 52 | --------------------- 53 | 54 | * Fixed filename mismatch (Issue #4). 55 | * Improved execution time output. 56 | 57 | 58 | PHP_CodeBrowser 0.1.2 59 | --------------------- 60 | 61 | * Added additional view if source has no errors or valid XML files. 62 | 63 | 64 | PHP_CodeBrowser 0.1.1 65 | --------------------- 66 | 67 | * Fixed PHP_CodeBrowser error, in case of project does not has any error log 68 | files or only empty error log files. 69 | 70 | 71 | PHP_CodeBrowser 0.1.0 72 | --------------------- 73 | 74 | * Initial version of PHP_CodeBrowser. 75 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2007-2014, Mayflower GmbH 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of Mayflower GmbH nor the names of its 15 | contributors may be used to endorse or promote products derived from this 16 | software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | # PHP_CodeBrowser # 2 | 3 | [![Latest Stable Version](https://poser.pugx.org/mayflower/php-codebrowser/v/stable.png)](https://packagist.org/packages/mayflower/php-codebrowser) 4 | [![Build Status](https://travis-ci.org/mayflower/PHP_CodeBrowser.png?branch=master)](https://travis-ci.org/mayflower/PHP_CodeBrowser) 5 | [![Scrutinizer Quality Score](https://scrutinizer-ci.com/g/Mayflower/PHP_CodeBrowser/badges/quality-score.png?s=2c0379f0efea966daeaef3fc5abf8adb4a910b24)](https://scrutinizer-ci.com/g/Mayflower/PHP_CodeBrowser/) 6 | [![Code Coverage](https://scrutinizer-ci.com/g/Mayflower/PHP_CodeBrowser/badges/coverage.png?s=543238e3d9fb4584d8cb31e3af48e67ed846f9e5)](https://scrutinizer-ci.com/g/Mayflower/PHP_CodeBrowser/) 7 | [![SensioLabsInsight](https://insight.sensiolabs.com/projects/79205008-1c3d-4142-ab81-a9465008d440/mini.png)](https://insight.sensiolabs.com/projects/79205008-1c3d-4142-ab81-a9465008d440) 8 | 9 | ## Structure ## 10 | 11 | |--> bin/ PHP_CodeBrowser scripts 12 | |--> src/ Source files for PHP_CodeBrowser 13 | | |--> Plugins/ Plugins for different error handling/types 14 | | 15 | |--> templates/ Template files for PHP_CodeBrowser 16 | | |--> css/ Used CSS by templates, Color definition for errors 17 | | |--> img/ Used images for PHP_CodeBrowser 18 | | |--> js/ Used javascript for PHP_CodeBrowser 19 | | 20 | |--> tests/ PHPUnit test suite 21 | | 22 | |--> package.xml PEAR package information file 23 | | 24 | |--> LICENCE Licence information 25 | |--> README Structure and install information 26 | |--> CHANGELOG Update information 27 | 28 | ## Installation ## 29 | 30 | ### Git Checkout ### 31 | 32 | $ git clone git://github.com/Mayflower/PHP_CodeBrowser.git 33 | 34 | ### Installation via Composer ### 35 | 36 | Add this line to the require section in composer.json: 37 | 38 | "mayflower/php-codebrowser": "~1.1" 39 | 40 | Or to install it globally 41 | 42 | composer global require "mayflower/php-codebrowser=~1.1" 43 | 44 | ### Get PHAR ### 45 | 46 | see [Releases](https://github.com/Mayflower/PHP_CodeBrowser/releases) 47 | 48 | ## Usage ## 49 | 50 | ### Shell Usage ### 51 | 52 | Try ./bin/phpcb.php -h for usage information. 53 | 54 | ### Integration in Jenkins, CruiseControl and Hudson ### 55 | 56 | ... 57 | 58 | 59 | ... 60 | 61 | 62 | 65 | 66 | 67 | ... 68 | 69 | ## View the Results ## 70 | 71 | ### Webbrowser ### 72 | 73 | Open `/path/to/defined/output/index.html`. 74 | 75 | ### CruiseControl ### 76 | 77 | #### config.xml #### 78 | 79 | 80 | 81 | ... 82 | 83 | 84 | #### main.jsp #### 85 | 86 | 87 | 88 | 90 | 91 | 92 | 93 | ### Jenkins/Hudson ### 94 | 95 | Have a look at the [standard template for Jenkins jobs for PHP projects](https://github.com/sebastianbergmann/php-jenkins-template) to see how PHP_CodeBrowser can be used together with Jenkins. 96 | 97 | ## Contact Information ## 98 | 99 | If you have any questions you may get in contact with: Elger Thiele or Thorsten Rinne 100 | -------------------------------------------------------------------------------- /bin/phpcb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 43 | * @copyright 2007-2009 Mayflower GmbH 44 | * @license http://www.opensource.org/licenses/bsd-license.php BSD License 45 | * @version SVN: $Id$ 46 | * @link http://www.phpunit.de/ 47 | * @since File available since 0.1.0 48 | */ 49 | 50 | if (file_exists(__DIR__ . '/../../../autoload.php')) { 51 | include_once __DIR__ . '/../../../autoload.php'; 52 | } else { 53 | include_once __DIR__ . '/../vendor/autoload.php'; 54 | } 55 | 56 | $app = new PHPCodeBrowser\Application('PHP_CodeBrowser', '4.0.1'); 57 | $app->run(); 58 | -------------------------------------------------------------------------------- /bin/phpcb.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | REM PHP_CodeBrowser shell script Wrapper for WIN 4 | REM Bash file called from the command line 5 | REM 6 | REM Copyright (c) 2007-2009, Mayflower GmbH 7 | REM All rights reserved. 8 | REM 9 | REM Redistribution and use in source and binary forms, with or without 10 | REM modification, are permitted provided that the following conditions 11 | REM are met: 12 | REM 13 | REM * Redistributions of source code must retain the above copyright 14 | REM notice, this list of conditions and the following disclaimer. 15 | REM 16 | REM * Redistributions in binary form must reproduce the above copyright 17 | REM notice, this list of conditions and the following disclaimer in 18 | REM the documentation and/or other materials provided with the 19 | REM distribution. 20 | REM 21 | REM * Neither the name of Mayflower GmbH nor the names of his 22 | REM contributors may be used to endorse or promote products derived 23 | REM from this software without specific prior written permission. 24 | REM 25 | REM THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 | REM "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 | REM LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 28 | REM FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 29 | REM COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 30 | REM INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 31 | REM BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 32 | REM LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 33 | REM CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 | REM LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 35 | REM ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 | REM POSSIBILITY OF SUCH DAMAGE. 37 | REM 38 | REM @category PHP_CodeBrowser 39 | REM @package PHP_CodeBrowser 40 | REM @subpackage bin 41 | REM @author Elger Thiele 42 | REM @copyright 2007-2009 Mayflower GmbH 43 | REM @license http://www.opensource.org/licenses/bsd-license.php BSD License 44 | REM @version SVN: $Id: phpcb 5182 2009-09-03 12:34:35Z elger $ 45 | REM @link http://www.phpunit.de/ 46 | REM @since File available since 0.1.0 47 | 48 | set PHPBIN=@php_bin@ 49 | "@php_bin@" "@bin_dir@\phpcb" %* 50 | -------------------------------------------------------------------------------- /box.json: -------------------------------------------------------------------------------- 1 | { 2 | "alias": "phpcb.phar", 3 | "compactors": [ 4 | "KevinGH\\Box\\Compactor\\Json", 5 | "KevinGH\\Box\\Compactor\\Php" 6 | ], 7 | "directories": ["src", "templates"], 8 | "files": [ 9 | "LICENSE", 10 | "vendor/autoload.php" 11 | ], 12 | "finder": [ 13 | { 14 | "name": "*.php", 15 | "path": [ 16 | "monolog/monolog", 17 | "phpunit/php-file-iterator", 18 | "psr/log", 19 | "symfony/console", 20 | "symfony/service-contracts", 21 | "symfony/string" 22 | ], 23 | "notPath": [ 24 | "Tests", 25 | "test", 26 | "tests" 27 | ], 28 | "in": "vendor" 29 | } 30 | ], 31 | "git-commit": "git-commit", 32 | "git-version": "git-version", 33 | "output": "phpcb-4.0.1.phar" 34 | } 35 | -------------------------------------------------------------------------------- /build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mayflower/php-codebrowser", 3 | "description": "A code browser that augments the code with information from various QA tools.", 4 | "license": "BSD-3-Clause", 5 | "homepage": "https://github.com/Mayflower/PHP_CodeBrowser", 6 | "authors": [ 7 | { 8 | "name": "Robin Gloster", 9 | "email": "robin.gloster@mayflower.de", 10 | "role": "developer" 11 | }, 12 | { 13 | "name": "Christian Albrecht", 14 | "email": "christian.albrecht@mayflower.de", 15 | "role": "developer" 16 | } 17 | ], 18 | "minimum-stability": "dev", 19 | "prefer-stable": true, 20 | "require": { 21 | "php": "^8.0", 22 | "ext-dom": "*", 23 | "monolog/monolog": "~1.7||~2.0||~3.0", 24 | "phpunit/php-file-iterator": "~2.0||^3.0", 25 | "symfony/console": "~3.4||~4.0||~5.0||~6.0" 26 | }, 27 | "require-dev": { 28 | "humbug/box": "^3.13", 29 | "mayflower/mo4-coding-standard": "^9.0", 30 | "phploc/phploc": "*", 31 | "phpmd/phpmd": "1.5.*||~2.6", 32 | "phpstan/phpstan": "^1.0", 33 | "phpunit/phpunit": "^9.5", 34 | "sebastian/phpcpd": "*", 35 | "phpstan/phpstan-strict-rules": "^1.5", 36 | "phpstan/extension-installer": "^1.2", 37 | "phpstan/phpstan-phpunit": "^1.3" 38 | }, 39 | "autoload": { 40 | "psr-0": {"PHPCodeBrowser\\": "src/"} 41 | }, 42 | "bin": [ "bin/phpcb" ], 43 | "scripts": { 44 | "demo": [ 45 | "@clean", 46 | "php -c php.ini vendor/bin/phpunit -c phpunit.xml.dist", 47 | "phpcpd --log-pmd=build/logs/pmd-cpd.xml src || true", 48 | "phpmd src xml cleancode,codesize,controversial,design,naming,unusedcode --reportfile build/logs/pmd.xml || true", 49 | "phpcs -q --report-checkstyle=build/logs/checkstyle.xml || true", 50 | "@browser" 51 | ], 52 | "nope": [ 53 | "@clean", 54 | "pdepend --quiet --dependency-xml=build/logs/pdepend.xml src || true", 55 | "phploc -q --log-xml=build/logs/phploc.xml src || true", 56 | "@browser" 57 | ], 58 | "ci-prepare": [ 59 | "composer update --prefer-dist --no-interaction --no-progress" 60 | ], 61 | "ci": [ 62 | "phpcs -s", 63 | "phpstan analyse --no-progress", 64 | "phpunit" 65 | ], 66 | "clean": "rm -rf build/logs/* build/code-browser", 67 | "browser": "bin/phpcb -l build/logs -o build/code-browser -s src", 68 | "phar": "php vendor/bin/box compile" 69 | }, 70 | "config": { 71 | "allow-plugins": { 72 | "dealerdirect/phpcodesniffer-composer-installer": true, 73 | "phpstan/extension-installer": true 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /phpcs.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | The coding standard. 4 | 5 | src 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /phpstan.neon: -------------------------------------------------------------------------------- 1 | parameters: 2 | level: 5 3 | paths: 4 | - %rootDir%/../../../src/PHPCodeBrowser 5 | 6 | includes: 7 | - phpstan_baseline.neon 8 | -------------------------------------------------------------------------------- /phpstan_baseline.neon: -------------------------------------------------------------------------------- 1 | parameters: 2 | ignoreErrors: 3 | - 4 | message: "#^Only booleans are allowed in a negated boolean, array\\ given\\.$#" 5 | count: 1 6 | path: src/PHPCodeBrowser/CLIController.php 7 | 8 | - 9 | message: "#^Only booleans are allowed in a negated boolean, mixed given\\.$#" 10 | count: 4 11 | path: src/PHPCodeBrowser/Command/RunCommand.php 12 | 13 | - 14 | message: "#^Only booleans are allowed in an if condition, mixed given\\.$#" 15 | count: 1 16 | path: src/PHPCodeBrowser/Command/RunCommand.php 17 | 18 | - 19 | message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#" 20 | count: 2 21 | path: src/PHPCodeBrowser/Helper/IOHelper.php 22 | 23 | - 24 | message: "#^Only booleans are allowed in a ternary operator condition, DOMNode\\|null given\\.$#" 25 | count: 1 26 | path: src/PHPCodeBrowser/IssueXML.php 27 | 28 | - 29 | message: "#^Only booleans are allowed in a negated boolean, string given\\.$#" 30 | count: 1 31 | path: src/PHPCodeBrowser/Plugins/ErrorCRAP.php 32 | 33 | - 34 | message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#" 35 | count: 1 36 | path: src/PHPCodeBrowser/View/ViewAbstract.php 37 | 38 | - 39 | message: "#^Only booleans are allowed in a negated boolean, string given\\.$#" 40 | count: 2 41 | path: src/PHPCodeBrowser/View/ViewAbstract.php 42 | 43 | - 44 | message: "#^Comparison operation \"\\<\" between 1 and int\\<2, max\\> is always true\\.$#" 45 | count: 1 46 | path: src/PHPCodeBrowser/View/ViewReview.php 47 | 48 | - 49 | message: "#^Comparison operation \"\\<\\=\" between int\\<32, 255\\> and 55295 is always true\\.$#" 50 | count: 1 51 | path: src/PHPCodeBrowser/View/ViewReview.php 52 | 53 | - 54 | message: "#^Comparison operation \"\\>\\=\" between int\\<0, 8\\>\\|int\\<11, 12\\>\\|int\\<14, 31\\> and 57344 is always false\\.$#" 55 | count: 1 56 | path: src/PHPCodeBrowser/View/ViewReview.php 57 | 58 | - 59 | message: "#^Comparison operation \"\\>\\=\" between int\\<0, 8\\>\\|int\\<11, 12\\>\\|int\\<14, 31\\> and 65536 is always false\\.$#" 60 | count: 1 61 | path: src/PHPCodeBrowser/View/ViewReview.php 62 | 63 | - 64 | message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#" 65 | count: 1 66 | path: src/PHPCodeBrowser/View/ViewReview.php 67 | 68 | - 69 | message: "#^Only booleans are allowed in a negated boolean, array given\\.$#" 70 | count: 1 71 | path: src/PHPCodeBrowser/View/ViewReview.php 72 | 73 | - 74 | message: "#^Result of && is always false\\.$#" 75 | count: 2 76 | path: src/PHPCodeBrowser/View/ViewReview.php 77 | 78 | - 79 | message: "#^Switch condition type \\(int\\<0, max\\>\\) does not match case condition 1 \\< \\$lineErrorCount \\(bool\\)\\.$#" 80 | count: 1 81 | path: src/PHPCodeBrowser/View/ViewReview.php 82 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 14 | 15 | 16 | ./src/PHPCodeBrowser/Tests 17 | 18 | 19 | 20 | 21 | 22 | ./src 23 | 24 | 25 | ./src/PHPCodeBrowser/Tests 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /src/PHPCodeBrowser/Application.php: -------------------------------------------------------------------------------- 1 | 43 | * 44 | * @copyright 2007-2010 Mayflower GmbH 45 | * 46 | * @license http://www.opensource.org/licenses/bsd-license.php BSD License 47 | * 48 | * @version SVN: $Id$ 49 | * 50 | * @link http://www.phpunit.de/ 51 | * 52 | * @since File available since 1.1 53 | */ 54 | 55 | namespace PHPCodeBrowser; 56 | 57 | use PHPCodeBrowser\Command\RunCommand; 58 | use Symfony\Component\Console\Application as BaseApplication; 59 | use Symfony\Component\Console\Command\Command; 60 | use Symfony\Component\Console\Input\InputDefinition; 61 | use Symfony\Component\Console\Input\InputInterface; 62 | 63 | /** 64 | * Class Application 65 | */ 66 | class Application extends BaseApplication 67 | { 68 | /** 69 | * Gets the InputDefinition related to this Application. 70 | * 71 | * @return InputDefinition The InputDefinition instance 72 | */ 73 | public function getDefinition(): InputDefinition 74 | { 75 | $inputDefinition = parent::getDefinition(); 76 | // clear out the normal first argument, which is the command name 77 | $inputDefinition->setArguments(); 78 | 79 | return $inputDefinition; 80 | } 81 | 82 | /** 83 | * Gets the name of the command based on input. 84 | * 85 | * @param InputInterface $input 86 | * 87 | * @phpcs:disable SlevomatCodingStandard.Functions.UnusedParameter.UnusedParameter 88 | * 89 | * @return string The command name 90 | */ 91 | protected function getCommandName(InputInterface $input): string 92 | { 93 | return 'phpcb'; 94 | } 95 | 96 | /** 97 | * Gets the default commands that should always be available. 98 | * 99 | * @return array An array of default Command instances 100 | */ 101 | protected function getDefaultCommands(): array 102 | { 103 | // Adds HelpCommand for --help 104 | $defaultCommands = parent::getDefaultCommands(); 105 | 106 | $defaultCommands[] = new RunCommand(); 107 | 108 | return $defaultCommands; 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/PHPCodeBrowser/File.php: -------------------------------------------------------------------------------- 1 | 43 | * 44 | * @copyright 2007-2010 Mayflower GmbH 45 | * 46 | * @license http://www.opensource.org/licenses/bsd-license.php BSD License 47 | * 48 | * @version SVN: $Id$ 49 | * 50 | * @link http://www.phpunit.de/ 51 | * 52 | * @since File available since 0.2.0 53 | */ 54 | 55 | namespace PHPCodeBrowser; 56 | 57 | use PHPCodeBrowser\Helper\IOHelper; 58 | 59 | /** 60 | * File 61 | * 62 | * An object of this class represents a single source file 63 | * with it's issues, if any. 64 | * 65 | * @category PHP_CodeBrowser 66 | * 67 | * @author Simon Kohlmeyer 68 | * 69 | * @copyright 2007-2010 Mayflower GmbH 70 | * 71 | * @license http://www.opensource.org/licenses/bsd-license.php BSD License 72 | * 73 | * @version Release: @package_version@ 74 | * 75 | * @link http://github.com/mayflowergmbh 76 | * 77 | * @since Class available since 0.2.0 78 | */ 79 | class File 80 | { 81 | /** 82 | * Filename. 83 | * 84 | * @var string 85 | */ 86 | private $name; 87 | 88 | /** 89 | * Issues associated with this file. 90 | * 91 | * @var array 92 | */ 93 | private $issues; 94 | 95 | /** 96 | * Default constructor. 97 | * 98 | * @param string $name The name of the file. 99 | * @param array $issues 100 | */ 101 | public function __construct(string $name, array $issues = []) 102 | { 103 | if (DIRECTORY_SEPARATOR !== '/') { 104 | $name = \str_replace('/', DIRECTORY_SEPARATOR, $name); 105 | } 106 | 107 | $this->name = $name; 108 | $this->issues = $issues; 109 | } 110 | 111 | /** 112 | * Add an issue for this file. 113 | * 114 | * @param Issue $issue The issue to add. 115 | * 116 | * @throws \InvalidArgumentException 117 | */ 118 | public function addIssue(Issue $issue): void 119 | { 120 | if ($issue->getFileName() !== $this->name) { 121 | throw new \InvalidArgumentException( 122 | 'Tried to add issue to wrong file.' 123 | ); 124 | } 125 | 126 | $this->issues[] = $issue; 127 | } 128 | 129 | /** 130 | * Gets an array containing the issues for this file. 131 | * 132 | * @return array The issues. 133 | */ 134 | public function getIssues(): array 135 | { 136 | return $this->issues; 137 | } 138 | 139 | /** 140 | * Returns the absolute name of this file. 141 | * 142 | * @return string 143 | */ 144 | public function name(): string 145 | { 146 | return $this->name; 147 | } 148 | 149 | /** 150 | * Returns the basename of this file. 151 | * 152 | * @return string 153 | */ 154 | public function basename(): string 155 | { 156 | return \basename($this->name); 157 | } 158 | 159 | /** 160 | * Returns the dirName of this file. 161 | * 162 | * @return string 163 | */ 164 | public function dirName(): string 165 | { 166 | return \dirname($this->name); 167 | } 168 | 169 | /** 170 | * Returns the number of issues this file has. 171 | * 172 | * @return int 173 | */ 174 | public function getIssueCount(): int 175 | { 176 | return \count($this->issues); 177 | } 178 | 179 | /** 180 | * Returns the number of errors this file has. 181 | * 182 | * @return int 183 | */ 184 | public function getErrorCount(): int 185 | { 186 | $count = 0; 187 | 188 | foreach ($this->issues as $issue) { 189 | if (\strcasecmp($issue->getSeverity(), 'error') !== 0) { 190 | continue; 191 | } 192 | 193 | ++$count; 194 | } 195 | 196 | return $count; 197 | } 198 | 199 | /** 200 | * Returns the number of issues this file has that are not errors. 201 | * 202 | * @return int 203 | */ 204 | public function getWarningCount(): int 205 | { 206 | return $this->getIssueCount() - $this->getErrorCount(); 207 | } 208 | 209 | /** 210 | * Merges the issues from two file objects representing the same file. 211 | * 212 | * @param File $file The file to merge with. 213 | * 214 | * @throws \InvalidArgumentException 215 | */ 216 | public function mergeWith(File $file): void 217 | { 218 | if ($this->name !== $file->name) { 219 | throw new \InvalidArgumentException( 220 | 'Tried to merge different files' 221 | ); 222 | } 223 | 224 | $this->issues = \array_merge($this->issues, $file->issues); 225 | } 226 | 227 | /** 228 | * Sorts an array of Files. Key value association will be preserved. 229 | * 230 | * @param array $files The files to sort. 231 | */ 232 | public static function sort(array &$files): void 233 | { 234 | \uasort($files, 'PHPCodeBrowser\File::internalSort'); 235 | } 236 | 237 | /** 238 | * Sorting function used in File::sort() 239 | * 240 | * @param File $first 241 | * @param File $second 242 | * 243 | * @return int 244 | */ 245 | protected static function internalSort(File $first, File $second): int 246 | { 247 | $firstName = $first->name(); 248 | $secondName = $second->name(); 249 | 250 | $prefix = IOHelper::getCommonPathPrefix([$firstName, $secondName]); 251 | $prefixLength = \strlen($prefix); 252 | 253 | $firstSubName = \substr($firstName, $prefixLength); 254 | $secondSubName = \substr($secondName, $prefixLength); 255 | 256 | $firstIsInSubDir = (\str_contains($firstSubName, DIRECTORY_SEPARATOR)); 257 | $secondIsInSubDir = (\str_contains($secondSubName, DIRECTORY_SEPARATOR)); 258 | 259 | if ($firstIsInSubDir) { 260 | return $secondIsInSubDir ? \strcmp($firstSubName, $secondSubName) : -1; 261 | } 262 | 263 | return $secondIsInSubDir ? 1 : \strcmp($firstSubName, $secondSubName); 264 | } 265 | } 266 | -------------------------------------------------------------------------------- /src/PHPCodeBrowser/Issue.php: -------------------------------------------------------------------------------- 1 | 43 | * @author Michel Hartmann 44 | * 45 | * @copyright 2007-2010 Mayflower GmbH 46 | * 47 | * @license http://www.opensource.org/licenses/bsd-license.php BSD License 48 | * 49 | * @version SVN: $Id$ 50 | * 51 | * @link http://www.phpunit.de/ 52 | * 53 | * @since File available since 0.1.2 54 | */ 55 | 56 | namespace PHPCodeBrowser; 57 | 58 | /** 59 | * Issue 60 | * 61 | * Object Model for issues. 62 | * This object is used for working with common issues types. 63 | * 64 | * @category PHP_CodeBrowser 65 | * 66 | * @author Elger Thiele 67 | * @author Michel Hartmann 68 | * 69 | * @copyright 2007-2010 Mayflower GmbH 70 | * 71 | * @license http://www.opensource.org/licenses/bsd-license.php BSD License 72 | * 73 | * @version Release: @package_version@ 74 | * 75 | * @link http://github.com/mayflowergmbh 76 | * 77 | * @since Class available since 0.1.2 78 | */ 79 | class Issue 80 | { 81 | /** 82 | * Source file name. 83 | * 84 | * @var string 85 | */ 86 | private $fileName; 87 | 88 | /** 89 | * Starting Line of the Issue. 90 | * 91 | * @var int 92 | */ 93 | private $lineStart; 94 | 95 | /** 96 | * Ending Line of the Issue. 97 | * 98 | * @var int 99 | */ 100 | private $lineEnd; 101 | 102 | /** 103 | * Name of the Plugin that found the Issue. 104 | * It is also used for CSS class definitions. 105 | * 106 | * @var string 107 | */ 108 | private $foundBy; 109 | 110 | /** 111 | * Issue Description text. 112 | * 113 | * @var string 114 | */ 115 | private $description; 116 | 117 | /** 118 | * Severity of the issue. 119 | * 120 | * @var string 121 | */ 122 | private $severity; 123 | 124 | /** 125 | * Default constructor 126 | * 127 | * @param string $fileName The source file name the issue was found in. 128 | * @param int $lineStart The starting line of the issue. 129 | * @param int $lineEnd The ending line of registered issue. 130 | * @param string $foundBy The plugin name definition. 131 | * @param string $description The description of the issue. 132 | * @param string $severity 133 | */ 134 | public function __construct(string $fileName, int $lineStart, int $lineEnd, string $foundBy, string $description, string $severity) 135 | { 136 | $this->fileName = $fileName; 137 | $this->lineStart = $lineStart; 138 | $this->lineEnd = $lineEnd; 139 | $this->foundBy = $foundBy; 140 | $this->description = $description; 141 | $this->severity = $severity; 142 | } 143 | 144 | /** 145 | * @return string 146 | */ 147 | public function getFileName(): string 148 | { 149 | return $this->fileName; 150 | } 151 | 152 | /** 153 | * @return int 154 | */ 155 | public function getLineStart(): int 156 | { 157 | return $this->lineStart; 158 | } 159 | 160 | /** 161 | * @return int 162 | */ 163 | public function getLineEnd(): int 164 | { 165 | return $this->lineEnd; 166 | } 167 | 168 | /** 169 | * @return string 170 | */ 171 | public function getFoundBy(): string 172 | { 173 | return $this->foundBy; 174 | } 175 | 176 | /** 177 | * @return string 178 | */ 179 | public function getDescription(): string 180 | { 181 | return $this->description; 182 | } 183 | 184 | /** 185 | * @return string 186 | */ 187 | public function getSeverity(): string 188 | { 189 | return $this->severity; 190 | } 191 | } 192 | -------------------------------------------------------------------------------- /src/PHPCodeBrowser/IssueXML.php: -------------------------------------------------------------------------------- 1 | 43 | * @author Michel Hartmann 44 | * 45 | * @copyright 2007-2010 Mayflower GmbH 46 | * 47 | * @license http://www.opensource.org/licenses/bsd-license.php BSD License 48 | * 49 | * @version SVN: $Id$ 50 | * 51 | * @link http://www.phpunit.de/ 52 | * 53 | * @since File available since 0.1.0 54 | */ 55 | 56 | namespace PHPCodeBrowser; 57 | 58 | use DOMDocument; 59 | use DOMDocumentType; 60 | use DOMNode; 61 | use DOMNodeList; 62 | use DOMXPath; 63 | use SebastianBergmann\FileIterator\Factory as FileIteratorFactory; 64 | 65 | /** 66 | * IssueXML 67 | * 68 | * This class is a wrapper around DOMDocument to provide additional features 69 | * like simple xpath queries. 70 | * It is used to merge issue XML files and execute plugins 71 | * against it to retrieve the issues from them. 72 | * 73 | * @category PHP_CodeBrowser 74 | * 75 | * @author Elger Thiele 76 | * @author Michel Hartmann 77 | * 78 | * @copyright 2007-2010 Mayflower GmbH 79 | * 80 | * @license http://www.opensource.org/licenses/bsd-license.php BSD License 81 | * 82 | * @version Release: @package_version@ 83 | * 84 | * @link http://www.phpunit.de/ 85 | * 86 | * @since Class available since 0.1.0 87 | */ 88 | class IssueXML extends DOMDocument 89 | { 90 | /** 91 | * 92 | * 93 | * @var DOMXPath 94 | */ 95 | protected $xpath; 96 | 97 | /** 98 | * Default constructor 99 | * 100 | * @param string $version The version definition for DomDocument 101 | * @param string $encoding The used encoding for DomDocument 102 | */ 103 | public function __construct(string $version = '1.0', string $encoding = 'UTF-8') 104 | { 105 | parent::__construct($version, $encoding); 106 | $this->appendChild( 107 | $this->createElement('codebrowser') 108 | ); 109 | $this->preserveWhiteSpace = false; 110 | $this->formatOutput = true; 111 | } 112 | 113 | /** 114 | * Parses directory for XML report files, generating a single DomDocument 115 | * inheriting all files and issues. 116 | * 117 | * @param string $directory The path to directory where xml files are stored 118 | * 119 | * @return IssueXML This object 120 | */ 121 | public function addDirectory(string $directory): IssueXML 122 | { 123 | $factory = new FileIteratorFactory(); 124 | $iterator = $factory->getFileIterator($directory, 'xml'); 125 | 126 | foreach ($iterator as $current) { 127 | $realFileName = \realpath($current); 128 | $xml = new DOMDocument('1.0', 'UTF-8'); 129 | $xml->validateOnParse = true; 130 | 131 | if (@$xml->load(\realpath($current))) { 132 | $this->addXMLFile($xml); 133 | } else { 134 | \error_log( 135 | "[Warning] Could not read file '{$realFileName}'. ".'Make sure it contains valid xml.' 136 | ); 137 | } 138 | 139 | unset($xml); 140 | } 141 | 142 | if (!$this->documentElement->hasChildNodes()) { 143 | \error_log("[Warning] No valid log files found in '{$directory}'"); 144 | } 145 | 146 | return $this; 147 | } 148 | 149 | /** 150 | * Add xml file to merge 151 | * 152 | * @param DOMDocument $domDocument The DOMDocument to merge. 153 | * 154 | * @return void 155 | */ 156 | public function addXMLFile(DOMDocument $domDocument): void 157 | { 158 | foreach ($domDocument->childNodes as $node) { 159 | if ($node instanceof DOMDocumentType) { 160 | continue; 161 | } 162 | 163 | $this->documentElement->appendChild($this->importNode($node, true)); 164 | } 165 | } 166 | 167 | /** 168 | * Perform a XPath-Query on the document. 169 | * 170 | * @see DOMXPath::query 171 | * 172 | * @param string $expression Xpath expression to query for. 173 | * @param DOMNode|null $contextNode Node to use as context (optional) 174 | * 175 | * @return DOMNodeList List of all matching nodes. 176 | */ 177 | public function query(string $expression, ?DOMNode $contextNode = null): DOMNodeList 178 | { 179 | if (null === $this->xpath) { 180 | $this->xpath = new DOMXPath($this); 181 | } 182 | 183 | $result = $contextNode ? $this->xpath->query($expression, $contextNode) : $this->xpath->query($expression); 184 | 185 | return $result; 186 | } 187 | } 188 | -------------------------------------------------------------------------------- /src/PHPCodeBrowser/Plugins/ErrorCPD.php: -------------------------------------------------------------------------------- 1 | 43 | * @author Michel Hartmann 44 | * 45 | * @copyright 2007-2010 Mayflower GmbH 46 | * 47 | * @license http://www.opensource.org/licenses/bsd-license.php BSD License 48 | * 49 | * @version SVN: $Id$ 50 | * 51 | * @link http://www.phpunit.de/ 52 | * 53 | * @since File available since 0.1.0 54 | */ 55 | 56 | namespace PHPCodeBrowser\Plugins; 57 | 58 | use DOMElement; 59 | use DOMNodeList; 60 | use PHPCodeBrowser\AbstractPlugin; 61 | use PHPCodeBrowser\Issue; 62 | 63 | /** 64 | * ErrorCPD 65 | * 66 | * @category PHP_CodeBrowser 67 | * 68 | * @author Elger Thiele 69 | * @author Michel Hartmann 70 | * 71 | * @copyright 2007-2010 Mayflower GmbH 72 | * 73 | * @license http://www.opensource.org/licenses/bsd-license.php BSD License 74 | * 75 | * @version Release: @package_version@ 76 | * 77 | * @link http://www.phpunit.de/ 78 | * 79 | * @since Class available since 0.1.0 80 | */ 81 | class ErrorCPD extends AbstractPlugin 82 | { 83 | /** 84 | * @var string $pluginName 85 | */ 86 | protected $pluginName = 'pmd-cpd'; 87 | 88 | /** 89 | * Mapper method for this plugin. 90 | * 91 | * @param \DOMNode $element The XML plugin node with its errors 92 | * @param string $filename 93 | * 94 | * @return array 95 | */ 96 | public function mapIssues(\DOMNode $element, string $filename): array 97 | { 98 | /** @var DOMElement $parentNode */ 99 | $parentNode = $element->parentNode; 100 | $files = $this->issueXml->query( 101 | 'file[@path="'.$filename.'"]', 102 | $parentNode 103 | ); 104 | $lineCount = (int) $parentNode->getAttribute('lines'); 105 | 106 | $result = []; 107 | 108 | foreach ($files as $file) { 109 | if (!($file instanceof DOMElement)) { 110 | continue; 111 | } 112 | 113 | $result[] = new Issue( 114 | $file->getAttribute('path'), 115 | (int) $file->getAttribute('line'), 116 | (int) $file->getAttribute('line') + $lineCount, 117 | 'Duplication', 118 | \htmlentities($this->getCpdDescription($parentNode->childNodes, $file), ENT_COMPAT), 119 | 'notice' 120 | ); 121 | } 122 | 123 | return $result; 124 | } 125 | 126 | /** 127 | * @return array 128 | */ 129 | public function getFilesWithIssues(): array 130 | { 131 | $fileNames = []; 132 | $nodes = $this->issueXml->query( 133 | '/*/'.$this->pluginName.'/*/file[@path]' 134 | ); 135 | 136 | foreach ($nodes as $node) { 137 | if (!($node instanceof DOMElement)) { 138 | continue; 139 | } 140 | 141 | $fileNames[] = $node->getAttribute('path'); 142 | } 143 | 144 | return \array_unique($fileNames); 145 | } 146 | 147 | /** 148 | * Get all DOMNodes that represent issues for a specific file. 149 | * 150 | * @param string $filename Name of the file to get nodes for. 151 | * 152 | * @return DOMNodeList 153 | */ 154 | protected function getIssueNodes(string $filename): DOMNodeList 155 | { 156 | return $this->issueXml->query( 157 | '/*/'.$this->pluginName.'/*/file[@path="'.$filename.'"]' 158 | ); 159 | } 160 | 161 | /** 162 | * We need another version of getDescription, as we need $allNodes 163 | * to find duplicates. 164 | * 165 | * @param DOMNodeList $allNodes 166 | * @param DOMElement $currentNode 167 | * 168 | * @return string 169 | */ 170 | protected function getCpdDescription(DOMNodeList $allNodes, DOMElement $currentNode): string 171 | { 172 | $source = []; 173 | 174 | foreach ($allNodes as $node) { 175 | if (!($node instanceof DOMElement) 176 | || $node->isSameNode($currentNode) 177 | ) { 178 | continue; 179 | } 180 | 181 | $source[] = \sprintf( 182 | '%s (%d)', 183 | $node->getAttribute('path'), 184 | $node->getAttribute('line') 185 | ); 186 | } 187 | 188 | return "Copy paste from:\n".\implode("\n", $source); 189 | } 190 | } 191 | -------------------------------------------------------------------------------- /src/PHPCodeBrowser/Plugins/ErrorCRAP.php: -------------------------------------------------------------------------------- 1 | 43 | * 44 | * @copyright 2007-2010 Mayflower GmbH 45 | * 46 | * @license http://www.opensource.org/licenses/bsd-license.php BSD License 47 | * 48 | * @version SVN: $Id$ 49 | * 50 | * @link http://www.phpunit.de/ 51 | * 52 | * @since File available since 0.2.0 53 | */ 54 | 55 | namespace PHPCodeBrowser\Plugins; 56 | 57 | use DOMElement; 58 | use DOMNodeList; 59 | use PHPCodeBrowser\AbstractPlugin; 60 | use PHPCodeBrowser\Issue; 61 | 62 | /** 63 | * ErrorCRAP 64 | * 65 | * @category PHP_CodeBrowser 66 | * 67 | * @author Simon Kohlmeyer 68 | * 69 | * @copyright 2007-2010 Mayflower GmbH 70 | * 71 | * @license http://www.opensource.org/licenses/bsd-license.php BSD License 72 | * 73 | * @version Release: @package_version@ 74 | * 75 | * @link http://www.phpunit.de/ 76 | * 77 | * @since Class available since 0.2.0 78 | */ 79 | class ErrorCRAP extends AbstractPlugin 80 | { 81 | /** 82 | * Name of this plugin. 83 | * Used to read issues from XML. 84 | * 85 | * @var string 86 | */ 87 | protected $pluginName = 'coverage'; 88 | 89 | /** 90 | * Name of the attribute that holds the number of the first line 91 | * of the issue. 92 | * 93 | * @var string 94 | */ 95 | protected $lineStartAttr = 'num'; 96 | 97 | /** 98 | * Name of the attribute that holds the number of the last line 99 | * of the issue. 100 | * 101 | * @var string 102 | */ 103 | protected $lineEndAttr = 'num'; 104 | 105 | /** 106 | * Default string to use as source for issue. 107 | * 108 | * @var string 109 | */ 110 | protected $source = 'CRAP'; 111 | 112 | /** 113 | * The detailed mapper method for each single plugin, returning an array 114 | * of Issue objects. 115 | * This method provides a default behaviour an can be overloaded to 116 | * implement special behavior for other plugins. 117 | * 118 | * @param \DOMNode $element The XML plugin node with its errors 119 | * @param string $filename Name of the file to return issues for. 120 | * 121 | * @return array 122 | */ 123 | public function mapIssues(\DOMNode $element, string $filename): array 124 | { 125 | $errorList = []; 126 | 127 | foreach ($element->childNodes as $child) { 128 | if (!($child instanceof DOMElement) 129 | || 'line' !== $child->nodeName 130 | || 'method' !== $child->getAttribute('type') 131 | ) { 132 | continue; 133 | } 134 | 135 | $crap = $child->getAttribute('crap'); 136 | 137 | if (!$crap) { 138 | continue; 139 | } 140 | 141 | if (\array_key_exists('threshold', $this->options) 142 | && $crap <= $this->options['threshold'] 143 | ) { 144 | continue; 145 | } 146 | 147 | $errorList[] = new Issue( 148 | $filename, 149 | $this->getLineStart($child), 150 | $this->getLineEnd($child), 151 | $this->getSource(), 152 | $crap, 153 | $crap >= 30 ? 'Error' : 'Notice' 154 | ); 155 | } 156 | 157 | return $errorList; 158 | } 159 | 160 | /** 161 | * Get an array with all files that have issues. 162 | * 163 | * @return array 164 | */ 165 | public function getFilesWithIssues(): array 166 | { 167 | $fileNames = []; 168 | $issueNodes = $this->issueXml->query( 169 | '/*/'.$this->pluginName.'/*/file[@name]' 170 | ); 171 | 172 | foreach ($issueNodes as $node) { 173 | if (!($node instanceof DOMElement)) { 174 | continue; 175 | } 176 | 177 | $fileNames[] = $node->getAttribute('name'); 178 | } 179 | 180 | return \array_unique($fileNames); 181 | } 182 | 183 | /** 184 | * Get all DOMNodes that represent issues for a specific file. 185 | * 186 | * @param string $filename Name of the file to get nodes for. 187 | * 188 | * @return DOMNodeList 189 | */ 190 | protected function getIssueNodes(string $filename): DOMNodeList 191 | { 192 | return $this->issueXml->query( 193 | '/*/'.$this->pluginName.'/*/file[@name="'.$filename.'"]' 194 | ); 195 | } 196 | } 197 | -------------------------------------------------------------------------------- /src/PHPCodeBrowser/Plugins/ErrorCheckstyle.php: -------------------------------------------------------------------------------- 1 | 43 | * @author Michel Hartmann 44 | * 45 | * @copyright 2007-2010 Mayflower GmbH 46 | * 47 | * @license http://www.opensource.org/licenses/bsd-license.php BSD License 48 | * 49 | * @version SVN: $Id$ 50 | * 51 | * @link http://www.phpunit.de/ 52 | * 53 | * @since File available since 0.1.0 54 | */ 55 | 56 | namespace PHPCodeBrowser\Plugins; 57 | 58 | use PHPCodeBrowser\AbstractPlugin; 59 | 60 | /** 61 | * ErrorCheckstyle 62 | * 63 | * @category PHP_CodeBrowser 64 | * 65 | * @author Elger Thiele 66 | * @author Christopher Weckerle 67 | * @author Michel Hartmann 68 | * 69 | * @copyright 2007-2010 Mayflower GmbH 70 | * 71 | * @license http://www.opensource.org/licenses/bsd-license.php BSD License 72 | * 73 | * @version Release: @package_version@ 74 | * 75 | * @link http://www.phpunit.de/ 76 | * 77 | * @since Class available since 0.1.0 78 | */ 79 | class ErrorCheckstyle extends AbstractPlugin 80 | { 81 | /** 82 | * Name of this plugin. 83 | * Used to read issues from XML. 84 | * 85 | * @var string 86 | */ 87 | protected $pluginName = 'checkstyle'; 88 | 89 | /** 90 | * Name of the attribute that holds the number of the first line 91 | * of the issue. 92 | * 93 | * @var string 94 | */ 95 | protected $lineStartAttr = 'line'; 96 | 97 | /** 98 | * Name of the attribute that holds the number of the last line 99 | * of the issue. 100 | * 101 | * @var string 102 | */ 103 | protected $lineEndAttr = 'line'; 104 | 105 | /** 106 | * Name of the attribute that holds message of the issue. 107 | * 108 | * @var string 109 | */ 110 | protected $descriptionAttr = 'message'; 111 | 112 | /** 113 | * Name of the attribute that holds severity of the issue. 114 | * 115 | * @var string 116 | */ 117 | protected $severityAttr = 'severity'; 118 | 119 | /** 120 | * Default string to use as source for issue. 121 | * 122 | * @var string 123 | */ 124 | protected $source = 'Checkstyle'; 125 | } 126 | -------------------------------------------------------------------------------- /src/PHPCodeBrowser/Plugins/ErrorCoverage.php: -------------------------------------------------------------------------------- 1 | 43 | * @author Michel Hartmann 44 | * 45 | * @copyright 2007-2010 Mayflower GmbH 46 | * 47 | * @license http://www.opensource.org/licenses/bsd-license.php BSD License 48 | * 49 | * @version SVN: $Id$ 50 | * 51 | * @link http://www.phpunit.de/ 52 | * 53 | * @since File available since 0.1.0 54 | */ 55 | 56 | namespace PHPCodeBrowser\Plugins; 57 | 58 | use DOMElement; 59 | use DOMNode; 60 | use DOMNodeList; 61 | use PHPCodeBrowser\AbstractPlugin; 62 | use PHPCodeBrowser\Issue; 63 | 64 | /** 65 | * ErrorCoverage 66 | * 67 | * @category PHP_CodeBrowser 68 | * 69 | * @author Elger Thiele 70 | * @author Michel Hartmann 71 | * 72 | * @copyright 2007-2010 Mayflower GmbH 73 | * 74 | * @license http://www.opensource.org/licenses/bsd-license.php BSD License 75 | * 76 | * @version Release: @package_version@ 77 | * 78 | * @link http://www.phpunit.de/ 79 | * 80 | * @since Class available since 0.1.0 81 | */ 82 | class ErrorCoverage extends AbstractPlugin 83 | { 84 | /** 85 | * Name of this plugin. 86 | * Used to read issues from XML. 87 | * 88 | * @var string 89 | */ 90 | protected $pluginName = 'coverage'; 91 | 92 | /** 93 | * Name of the attribute that holds the number of the first line 94 | * of the issue. 95 | * 96 | * @var string 97 | */ 98 | protected $lineStartAttr = 'num'; 99 | 100 | /** 101 | * Name of the attribute that holds the number of the last line 102 | * of the issue. 103 | * 104 | * @var string 105 | */ 106 | protected $lineEndAttr = 'num'; 107 | 108 | /** 109 | * Default string to use as source for issue. 110 | * 111 | * @var string 112 | */ 113 | protected $source = 'Coverage'; 114 | 115 | /** 116 | * The detailed mapper method for each single plugin, returning an array 117 | * of Issue objects. 118 | * This method provides a default behaviour an can be overloaded to 119 | * implement special behavior for other plugins. 120 | * 121 | * @param DOMNode $element The XML plugin node with its errors 122 | * @param string $filename Name of the file to return issues for. 123 | * 124 | * @return array 125 | */ 126 | public function mapIssues(DOMNode $element, string $filename): array 127 | { 128 | $errorList = []; 129 | 130 | $children = $element->childNodes; 131 | $childCount = $children->length; 132 | 133 | for ($next = 0; $next < $childCount; ++$next) { 134 | /** @var DOMElement $child */ 135 | $child = $children->item($next); 136 | 137 | if (!$this->representsUncoveredLOC($child)) { 138 | continue; 139 | } 140 | 141 | $begin = (int) $child->getAttribute('num'); 142 | $end = $begin; 143 | 144 | ++$next; 145 | 146 | while ($next < $childCount) { 147 | $child = $children->item($next); 148 | 149 | if (!$child instanceof DOMElement) { 150 | ++$next; 151 | 152 | continue; 153 | } 154 | 155 | if (!$this->representsUncoveredLOC($child)) { 156 | break; 157 | } 158 | 159 | $end = (int) $child->getAttribute('num'); 160 | ++$next; 161 | } 162 | 163 | $errorList[] = new Issue( 164 | $filename, 165 | $begin, 166 | $end, 167 | 'Coverage', 168 | 'Not covered', 169 | 'Notice' 170 | ); 171 | } 172 | 173 | return $errorList; 174 | } 175 | 176 | /** 177 | * Get an array with all files that have issues. 178 | * 179 | * @return array 180 | */ 181 | public function getFilesWithIssues(): array 182 | { 183 | $fileNames = []; 184 | $issueNodes = $this->issueXml->query( 185 | '/*/'.$this->pluginName.'/*//file[@name]' 186 | ); 187 | 188 | foreach ($issueNodes as $node) { 189 | if (!($node instanceof DOMElement)) { 190 | continue; 191 | } 192 | 193 | $fileNames[] = $node->getAttribute('name'); 194 | } 195 | 196 | return \array_unique($fileNames); 197 | } 198 | 199 | /** 200 | * Get all DOMNodes that represent issues for a specific file. 201 | * 202 | * @param string $filename Name of the file to get nodes for. 203 | * 204 | * @return DOMNodeList 205 | */ 206 | protected function getIssueNodes(string $filename): DOMNodeList 207 | { 208 | return $this->issueXml->query( 209 | '/*/'.$this->pluginName.'/*//file[@name="'.$filename.'"]' 210 | ); 211 | } 212 | 213 | /** 214 | * Check if the given object is a DOMElement representing an 215 | * uncovered line of code. 216 | * 217 | * @param DOMNode $elem 218 | * 219 | * @return bool 220 | */ 221 | private function representsUncoveredLOC(DOMNode $elem): bool 222 | { 223 | return ($elem instanceof DOMElement && 224 | 0 === (int) $elem->getAttribute('count') 225 | && 'line' === $elem->nodeName 226 | && 'stmt' === $elem->getAttribute('type')); 227 | } 228 | } 229 | -------------------------------------------------------------------------------- /src/PHPCodeBrowser/Plugins/ErrorPMD.php: -------------------------------------------------------------------------------- 1 | 43 | * @author Michel Hartmann 44 | * 45 | * @copyright 2007-2010 Mayflower GmbH 46 | * 47 | * @license http://www.opensource.org/licenses/bsd-license.php BSD License 48 | * 49 | * @link http://www.phpunit.de/ 50 | * 51 | * @since File available since 0.1.0 52 | */ 53 | 54 | namespace PHPCodeBrowser\Plugins; 55 | 56 | use DOMElement; 57 | use PHPCodeBrowser\AbstractPlugin; 58 | 59 | /** 60 | * ErrorPMD 61 | * 62 | * @category PHP_CodeBrowser 63 | * 64 | * @author Elger Thiele 65 | * @author Christopher Weckerle 66 | * @author Michel Hartmann 67 | * 68 | * @copyright 2007-2010 Mayflower GmbH 69 | * 70 | * @license http://www.opensource.org/licenses/bsd-license.php BSD License 71 | * 72 | * @version Release: @package_version@ 73 | * 74 | * @link http://www.phpunit.de/ 75 | * 76 | * @since Class available since 0.1.0 77 | */ 78 | class ErrorPMD extends AbstractPlugin 79 | { 80 | /** 81 | * Name of this plugin. 82 | * Used to read issues from XML. 83 | * 84 | * @var string 85 | */ 86 | protected $pluginName = 'pmd'; 87 | 88 | /** 89 | * Name of the attribute that holds the number of the first line 90 | * of the issue. 91 | * 92 | * @var string 93 | */ 94 | protected $lineStartAttr = 'beginline'; 95 | 96 | /** 97 | * Name of the attribute that holds the number of the last line 98 | * of the issue. 99 | * 100 | * @var string 101 | */ 102 | protected $lineEndAttr = 'endline'; 103 | 104 | /** 105 | * Default string to use as source for issue. 106 | * 107 | * @var string 108 | */ 109 | protected $source = 'PMD'; 110 | 111 | /** 112 | * Get the severity of an issue. 113 | * Always return 'error'. 114 | * 115 | * @param DOMElement $element 116 | * 117 | * @phpcs:disable SlevomatCodingStandard.Functions.UnusedParameter.UnusedParameter 118 | * 119 | * @return string 120 | */ 121 | protected function getSeverity(DOMElement $element): string 122 | { 123 | return 'error'; 124 | } 125 | 126 | /** 127 | * Get the description of an issue. 128 | * Use the textContent of the element. 129 | * 130 | * @param DOMElement $element 131 | * 132 | * @return string 133 | */ 134 | protected function getDescription(DOMElement $element): string 135 | { 136 | return \str_replace( 137 | ' ', 138 | '', 139 | \htmlentities($element->textContent, ENT_COMPAT) 140 | ); 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /src/PHPCodeBrowser/Plugins/ErrorPadawan.php: -------------------------------------------------------------------------------- 1 | 43 | * @author Michel Hartmann 44 | * 45 | * @copyright 2007-2009 Mayflower GmbH 46 | * 47 | * @license http://www.opensource.org/licenses/bsd-license.php BSD License 48 | * 49 | * @version SVN: $Id$ 50 | * 51 | * @link http://www.phpunit.de/ 52 | * 53 | * @since File available since 0.1.0 54 | */ 55 | 56 | namespace PHPCodeBrowser\Plugins; 57 | 58 | use PHPCodeBrowser\AbstractPlugin; 59 | 60 | /** 61 | * ErrorPadawan 62 | * 63 | * @category PHP_CodeBrowser 64 | * 65 | * @author Elger Thiele 66 | * @author Christopher Weckerle 67 | * @author Michel Hartmann 68 | * 69 | * @copyright 2007-2010 Mayflower GmbH 70 | * 71 | * @license http://www.opensource.org/licenses/bsd-license.php BSD License 72 | * 73 | * @version Release: @package_version@ 74 | * 75 | * @link http://www.phpunit.de/ 76 | * 77 | * @since Class available since 0.1.0 78 | */ 79 | class ErrorPadawan extends AbstractPlugin 80 | { 81 | /** 82 | * The name of the plugin. 83 | * 84 | * @var string 85 | */ 86 | protected $pluginName = 'padawan'; 87 | 88 | /** 89 | * Name of the attribute that holds the number of the first line 90 | * of the issue. 91 | * 92 | * @var string 93 | */ 94 | protected $lineStartAttr = 'line'; 95 | 96 | /** 97 | * Name of the attribute that holds the number of the last line 98 | * of the issue. 99 | * 100 | * @var string 101 | */ 102 | protected $lineEndAttr = 'line'; 103 | 104 | /** 105 | * Name of the attribute that holds message of the issue. 106 | * 107 | * @var string 108 | */ 109 | protected $descriptionAttr = 'message'; 110 | 111 | /** 112 | * Name of the attribute that holds severity of the issue. 113 | * 114 | * @var string 115 | */ 116 | protected $severityAttr = 'severity'; 117 | 118 | /** 119 | * Default string to use as source for issue. 120 | * 121 | * @var string 122 | */ 123 | protected $source = 'Padawan'; 124 | } 125 | -------------------------------------------------------------------------------- /src/PHPCodeBrowser/SourceHandler.php: -------------------------------------------------------------------------------- 1 | 43 | * @author Michel Hartmann 44 | * @author Simon Kohlmeyer 45 | * 46 | * @copyright 2007-2010 Mayflower GmbH 47 | * 48 | * @license http://www.opensource.org/licenses/bsd-license.php BSD License 49 | * 50 | * @version SVN: $Id$ 51 | * 52 | * @link http://www.phpunit.de/ 53 | * 54 | * @since File available since 0.2.0 55 | */ 56 | 57 | namespace PHPCodeBrowser; 58 | 59 | use Exception; 60 | use Monolog\Logger; 61 | use PHPCodeBrowser\Helper\IOHelper; 62 | use SplFileInfo; 63 | 64 | /** 65 | * SourceHandler 66 | * 67 | * This class manages lists of source files and their issues. 68 | * For providing these lists the prior generated IssueXML is parsed. 69 | * 70 | * @category PHP_CodeBrowser 71 | * 72 | * @author Elger Thiele 73 | * @author Christopher Weckerle 74 | * @author Michel Hartmann 75 | * @author Simon Kohlmeyer 76 | * 77 | * @copyright 2007-2010 Mayflower GmbH 78 | * 79 | * @license http://www.opensource.org/licenses/bsd-license.php BSD License 80 | * 81 | * @version Release: @package_version@ 82 | * 83 | * @link http://www.phpunit.de/ 84 | * 85 | * @since Class available since 0.2.0 86 | */ 87 | class SourceHandler 88 | { 89 | /** 90 | * Files to be included in the report 91 | * 92 | * @var array 93 | */ 94 | protected $files = []; 95 | 96 | /** 97 | * Pear Log object where debug output should go to. 98 | * 99 | * @var Logger 100 | */ 101 | protected $debugLog; 102 | 103 | /** 104 | * Default constructor 105 | * 106 | * @param Logger $debugLog 107 | * @param array $plugins The plugins to get issues from. 108 | */ 109 | public function __construct(Logger $debugLog, array $plugins = []) 110 | { 111 | $this->debugLog = $debugLog; 112 | \array_walk($plugins, [$this, 'addPlugin']); 113 | } 114 | 115 | /** 116 | * Add a new plugin to the handler. 117 | * 118 | * @param AbstractPlugin $plugin The plugin to add. 119 | */ 120 | public function addPlugin(AbstractPlugin $plugin): void 121 | { 122 | foreach ($plugin->getFileList() as $file) { 123 | if (\array_key_exists($file->name(), $this->files)) { 124 | $this->files[$file->name()]->mergeWith($file); 125 | } else { 126 | $this->files[$file->name()] = $file; 127 | } 128 | } 129 | } 130 | 131 | /** 132 | * Add source files to the list. 133 | * 134 | * @param array|\AppendIterator $files The files to add 135 | */ 136 | public function addSourceFiles($files): void 137 | { 138 | foreach ($files as $f) { 139 | $this->addSourceFile($f); 140 | } 141 | } 142 | 143 | /** 144 | * Add a source file. 145 | * 146 | * @param string|SplFileInfo $file The file to add 147 | * 148 | * @throws Exception 149 | */ 150 | public function addSourceFile($file): void 151 | { 152 | if (\is_string($file)) { 153 | $filename = $file; 154 | $file = \realpath($file); 155 | } else { 156 | $filename = $file->getPathname(); 157 | $file = $file->getRealPath(); 158 | } 159 | 160 | if (!$file) { 161 | throw new Exception("{$filename} is no regular file"); 162 | } 163 | 164 | if (\array_key_exists($file, $this->files)) { 165 | return; 166 | } 167 | 168 | $this->files[$file] = new File($file); 169 | } 170 | 171 | /** 172 | * Retrieves the parent directory all files have in common. 173 | * 174 | * @return string 175 | */ 176 | public function getCommonPathPrefix(): string 177 | { 178 | return IOHelper::getCommonPathPrefix(\array_keys($this->files)); 179 | } 180 | 181 | /** 182 | * Returns a sorted array of the files that should be in the report. 183 | * 184 | * @return array 185 | */ 186 | public function getFiles(): array 187 | { 188 | File::sort($this->files); 189 | 190 | return $this->files; 191 | } 192 | 193 | /** 194 | * Get a unique list of all file names with issues. 195 | * 196 | * @return array 197 | */ 198 | public function getFilesWithIssues(): array 199 | { 200 | return \array_keys($this->files); 201 | } 202 | 203 | /** 204 | * Remove all files that match the given PCRE. 205 | * 206 | * @param string $expr The PCRE specifying which files to remove. 207 | * 208 | * @return void 209 | */ 210 | public function excludeMatchingPCRE(string $expr): void 211 | { 212 | foreach (\array_keys($this->files) as $filename) { 213 | if (!\preg_match($expr, $filename)) { 214 | continue; 215 | } 216 | 217 | $this->debugLog->debug( 218 | "Excluding {$filename}, it matches PCRE {$expr}" 219 | ); 220 | unset($this->files[$filename]); 221 | } 222 | } 223 | 224 | /** 225 | * Remove all files that match the given shell wildcard pattern 226 | * as accepted by fnmatch(). 227 | * 228 | * @param string $pattern The pattern. 229 | * 230 | * @return void 231 | */ 232 | public function excludeMatchingPattern(string $pattern): void 233 | { 234 | foreach (\array_keys($this->files) as $filename) { 235 | if (!\fnmatch($pattern, $filename)) { 236 | continue; 237 | } 238 | 239 | $this->debugLog->debug( 240 | "Excluding {$filename}, it matches pattern {$pattern}" 241 | ); 242 | unset($this->files[$filename]); 243 | } 244 | } 245 | } 246 | -------------------------------------------------------------------------------- /src/PHPCodeBrowser/Tests/AbstractTestCase.php: -------------------------------------------------------------------------------- 1 | 41 | * 42 | * @copyright 2007-2009 Mayflower GmbH 43 | * 44 | * @license http://www.opensource.org/licenses/bsd-license.php BSD License 45 | * 46 | * @version SVN: $Id$ 47 | * 48 | * @link http://www.phpunit.de/ 49 | * 50 | * @since File available since 0.1.0 51 | */ 52 | 53 | namespace PHPCodeBrowser\Tests; 54 | 55 | use PHPUnit\Framework\TestCase; 56 | 57 | /** 58 | * AbstractTests 59 | * 60 | * @category PHP_CodeBrowser 61 | * 62 | * @author Elger Thiele 63 | * 64 | * @copyright 2007-2009 Mayflower GmbH 65 | * 66 | * @license http://www.opensource.org/licenses/bsd-license.php BSD License 67 | * 68 | * @version Release: @package_version@ 69 | * 70 | * @link http://www.phpunit.de/ 71 | * 72 | * @since Class available since 0.1.0 73 | */ 74 | class AbstractTestCase extends TestCase 75 | { 76 | /** 77 | * PHP_CodeBrowser test output dir 78 | * 79 | * @var string 80 | */ 81 | protected static $testOutputDir; 82 | 83 | /** 84 | * PHP_CodeBrowser source root dir 85 | * 86 | * @var string 87 | */ 88 | protected static $phpcbSourceDir; 89 | 90 | /** 91 | * PHP_CodeBrowser error file 92 | * 93 | * @var string 94 | */ 95 | protected static $xmlFile; 96 | 97 | /** 98 | * Basic XML file with valid headers 99 | * 100 | * @var string 101 | */ 102 | protected static $xmlBasic; 103 | 104 | /** 105 | * File of serialized error list 106 | * 107 | * @var string 108 | */ 109 | protected static $serializedErrors; 110 | 111 | /** 112 | * Global setup method for all test cases. Basic variables are initialized. 113 | * 114 | * @return void 115 | */ 116 | protected function setUp(): void 117 | { 118 | parent::setUp(); 119 | 120 | if (!\defined('PHPCB_SOURCE_DIR')) { 121 | \define('PHPCB_SOURCE_DIR', \realpath(__DIR__.'/../')); 122 | } 123 | 124 | if (!\defined('PHPCB_TEST_DIR')) { 125 | \define( 126 | 'PHPCB_TEST_DIR', 127 | \realpath(PHPCB_SOURCE_DIR).DIRECTORY_SEPARATOR.'Tests'.DIRECTORY_SEPARATOR.'testData' 128 | ); 129 | } 130 | 131 | if (!\defined('PHPCB_TEST_LOGS')) { 132 | \define('PHPCB_TEST_LOGS', PHPCB_TEST_DIR.'/logs'); 133 | } 134 | 135 | self::$xmlBasic = PHPCB_TEST_LOGS.'/basic.xml'; 136 | 137 | self::$phpcbSourceDir = \realpath(__DIR__.'/Fixtures'); 138 | 139 | self::$testOutputDir = PHPCB_TEST_DIR.DIRECTORY_SEPARATOR.'output'; 140 | 141 | if (\is_dir(self::$testOutputDir)) { 142 | $this->cleanUp(self::$testOutputDir); 143 | \rmdir(self::$testOutputDir); 144 | } 145 | 146 | \mkdir(self::$testOutputDir); 147 | } 148 | 149 | /** 150 | * Global tear down method for all test cases. 151 | * Cleaning up generated data and output. 152 | * 153 | * @return void 154 | */ 155 | protected function tearDown(): void 156 | { 157 | parent::tearDown(); 158 | 159 | $this->cleanUp(self::$testOutputDir); 160 | \rmdir(self::$testOutputDir); 161 | } 162 | 163 | /** 164 | * Load the cb error list 165 | * 166 | * @return array List of cb errors 167 | */ 168 | protected function getSerializedErrors(): array 169 | { 170 | return \unserialize(\file_get_contents(self::$serializedErrors)); 171 | } 172 | 173 | /** 174 | * Cleanup the test directory output folder 175 | * 176 | * @param string $dir The directory to clean up 177 | * 178 | * @return void 179 | */ 180 | protected function cleanUp(string $dir): void 181 | { 182 | $iterator = new \DirectoryIterator($dir); 183 | 184 | while ($iterator->valid()) { 185 | // delete file 186 | if ($iterator->isFile()) { 187 | \unlink($dir.'/'.$iterator->current()); 188 | } 189 | 190 | // delete folder recursive 191 | if (!$iterator->isDot() && $iterator->isDir()) { 192 | $this->cleanUp($dir.'/'.$iterator->current()); 193 | \rmdir($dir.'/'.$iterator->current()); 194 | } 195 | 196 | $iterator->next(); 197 | } 198 | 199 | unset($iterator); 200 | } 201 | } 202 | -------------------------------------------------------------------------------- /src/PHPCodeBrowser/Tests/ApplicationTest.php: -------------------------------------------------------------------------------- 1 | application = new Application(); 26 | } 27 | 28 | /** 29 | * 30 | */ 31 | public function testCommand(): void 32 | { 33 | static::assertInstanceOf(RunCommand::class, $this->application->get('phpcb')); 34 | } 35 | 36 | /** 37 | * 38 | */ 39 | public function testGetDefinitionClearsArguments(): void 40 | { 41 | $this->application->getDefinition()->setArguments([new InputArgument('foo')]); 42 | 43 | static::assertEquals(0, $this->application->getDefinition()->getArgumentCount()); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/PHPCodeBrowser/Tests/CLIControllerTest.php: -------------------------------------------------------------------------------- 1 | 66 | * 67 | * @copyright 2007-2010 Mayflower GmbH 68 | * 69 | * @license http://www.opensource.org/licenses/bsd-license.php BSD License 70 | * 71 | * @version Release: @package_version@ 72 | * 73 | * @link http://www.phpunit.de/ 74 | * 75 | * @since Class available since 0.1.0 76 | */ 77 | class CLIControllerTest extends AbstractTestCase 78 | { 79 | /** 80 | * @var CLIController $controller 81 | */ 82 | private $controller; 83 | 84 | /** 85 | * Create and configure a CLIController instance. 86 | */ 87 | public function setUp(): void 88 | { 89 | parent::setUp(); 90 | 91 | $this->controller = new CLIController( 92 | null, 93 | [self::$phpcbSourceDir], 94 | self::$testOutputDir, 95 | [], 96 | [], 97 | [ErrorCRAP::class => ['threshold' => 1]], 98 | new IOHelper(), 99 | new Logger('PHPCodeBrowser'), 100 | ['php'] 101 | ); 102 | 103 | $this->controller->addErrorPlugins( 104 | [ 105 | 'ErrorCheckstyle', 106 | 'ErrorPMD', 107 | 'ErrorCPD', 108 | 'ErrorPadawan', 109 | 'ErrorCoverage', 110 | 'ErrorCRAP', 111 | ] 112 | ); 113 | } 114 | 115 | /** 116 | * Assert a set of directories and files are present in output dir. 117 | */ 118 | public function assertOutputIsPresent(): void 119 | { 120 | self::assertFileExists(self::$testOutputDir.'/index.html'); 121 | self::assertFileExists(self::$testOutputDir.'/Bad.php.html'); 122 | self::assertFileExists(self::$testOutputDir.'/Good.php.html'); 123 | self::assertDirectoryExists(self::$testOutputDir.'/css'); 124 | self::assertDirectoryExists(self::$testOutputDir.'/img'); 125 | self::assertDirectoryExists(self::$testOutputDir.'/js'); 126 | } 127 | 128 | /** 129 | * Run a full system test based on phpcs output. 130 | */ 131 | public function testRunCreatesFilesAndDirs(): void 132 | { 133 | $this->controller->run(); 134 | 135 | $this->assertOutputIsPresent(); 136 | } 137 | 138 | /** 139 | * Assert existing files and directories within output dir are removed. 140 | */ 141 | public function testRunCleansExistingOutputDir(): void 142 | { 143 | \mkdir(self::$testOutputDir.'/clear-directory'); 144 | \touch(self::$testOutputDir.'/clear-file'); 145 | \touch(self::$testOutputDir.'/clear-directory/clear-file'); 146 | 147 | $this->controller->run(); 148 | 149 | $this->assertOutputIsPresent(); 150 | static::assertDirectoryDoesNotExist(self::$testOutputDir.'/clear-directory'); 151 | static::assertFileDoesNotExist(self::$testOutputDir.'/clear-file'); 152 | } 153 | 154 | /** 155 | * Assert that if there is a file with outputs name, it is replaced with a directory. 156 | */ 157 | public function testRunCleansExistingOutputFile(): void 158 | { 159 | \rmdir(self::$testOutputDir); 160 | \touch(self::$testOutputDir); 161 | 162 | $this->controller->run(); 163 | 164 | $this->assertOutputIsPresent(); 165 | } 166 | 167 | /** 168 | * Assert only index.html is present if all source files are excluded. 169 | */ 170 | public function testRunExcludingAllSources(): void 171 | { 172 | $this->controller = new CLIController( 173 | null, 174 | [self::$phpcbSourceDir], 175 | self::$testOutputDir, 176 | ['/Bad.php/'], 177 | ['*Good.php'], 178 | [ErrorCRAP::class => ['threshold' => 1]], 179 | new IOHelper(), 180 | new Logger('PHPCodeBrowser'), 181 | ['php'] 182 | ); 183 | 184 | $this->controller->run(); 185 | 186 | static::assertFileExists(self::$testOutputDir.'/index.html'); 187 | static::assertFileDoesNotExist(self::$testOutputDir.'/Bad.php.html'); 188 | static::assertFileDoesNotExist(self::$testOutputDir.'/Good.php.html'); 189 | static::assertDirectoryDoesNotExist(self::$testOutputDir.'/css'); 190 | static::assertDirectoryDoesNotExist(self::$testOutputDir.'/img'); 191 | static::assertDirectoryDoesNotExist(self::$testOutputDir.'/js'); 192 | } 193 | } 194 | -------------------------------------------------------------------------------- /src/PHPCodeBrowser/Tests/Fixtures/Bad.php: -------------------------------------------------------------------------------- 1 | 64 | * 65 | * @copyright 2007-2010 Mayflower GmbH 66 | * 67 | * @license http://www.opensource.org/licenses/bsd-license.php BSD License 68 | * 69 | * @version Release: @package_version@ 70 | * 71 | * @link http://www.phpunit.de/ 72 | * 73 | * @since Class available since 0.1.0 74 | */ 75 | class IOHelperTest extends AbstractTestCase 76 | { 77 | /** 78 | * The IOHelper object under test. 79 | * 80 | * @var IOHelper 81 | */ 82 | protected $ioHelper; 83 | 84 | /** 85 | * (non-PHPDoc) 86 | * 87 | * @see AbstractTestCase::setUp() 88 | */ 89 | protected function setUp(): void 90 | { 91 | parent::setUp(); 92 | 93 | $this->ioHelper = new IOHelper(); 94 | } 95 | 96 | /** 97 | * Test createFile function without creating a path 98 | * 99 | * @return void 100 | */ 101 | public function testFileCreation(): void 102 | { 103 | $filename = self::$testOutputDir.'/tmpfile'; 104 | $content = 'Lorem ipsum'; 105 | 106 | if (\file_exists($filename)) { 107 | \unlink($filename); 108 | } 109 | 110 | $this->ioHelper->createFile($filename, $content); 111 | static::assertFileExists($filename); 112 | static::assertEquals($content, \file_get_contents($filename)); 113 | 114 | \unlink($filename); 115 | } 116 | 117 | /** 118 | * Test createFile function with creating a path 119 | * 120 | * @return void 121 | */ 122 | public function testCreationOfFileWithPath(): void 123 | { 124 | $dirName = self::$testOutputDir.'/tmpdir'; 125 | $filename = $dirName.'/tmpfile'; 126 | $content = 'Lorem ipsum'; 127 | 128 | if (\file_exists($filename)) { 129 | \unlink($filename); 130 | \rmdir($dirName); 131 | } elseif (\file_exists($dirName)) { 132 | \rmdir($dirName); 133 | } 134 | 135 | $this->ioHelper->createFile($filename, $content); 136 | static::assertFileExists($dirName); 137 | static::assertFileExists($filename); 138 | static::assertEquals($content, \file_get_contents($filename)); 139 | 140 | \unlink($filename); 141 | \rmdir($dirName); 142 | } 143 | 144 | /** 145 | * Test deleteFile function 146 | * 147 | * @return void 148 | */ 149 | public function testFileDeletion(): void 150 | { 151 | $filename = self::$testOutputDir.'/tmpfile'; 152 | 153 | if (!\file_exists($filename)) { 154 | \file_put_contents($filename, 'Lorem ipsum'); 155 | } 156 | 157 | $this->ioHelper->deleteFile($filename); 158 | static::assertFileDoesNotExist($filename); 159 | } 160 | 161 | /** 162 | * Test deleteDirectory function 163 | * 164 | * @return void 165 | */ 166 | public function testDirectoryDeletion(): void 167 | { 168 | $dir = self::$testOutputDir.'/dir'; 169 | $file = $dir.'/file'; 170 | $subDir = $dir.'/subDir'; 171 | 172 | \mkdir($dir); 173 | \mkdir($subDir); 174 | \touch($file); 175 | 176 | $this->ioHelper->deleteDirectory($dir); 177 | static::assertFileDoesNotExist($dir); 178 | } 179 | 180 | /** 181 | * Test copyFile function 182 | * 183 | * @return void 184 | */ 185 | public function testCopyFile(): void 186 | { 187 | $srcFile = self::$testOutputDir.'/tmpfile'; 188 | $dstDir = self::$testOutputDir.'/tmpdir'; 189 | $dstFile = $dstDir.'/tmpfile'; 190 | $content = 'Lorem ipsum'; 191 | 192 | if (\file_exists($srcFile)) { 193 | \unlink($srcFile); 194 | } 195 | 196 | if (\file_exists($dstFile)) { 197 | \rmdir($dstFile); 198 | } 199 | 200 | \file_put_contents($srcFile, $content); 201 | 202 | $this->ioHelper->copyFile($srcFile, $dstDir); 203 | static::assertFileExists($srcFile); 204 | static::assertFileExists($dstDir); 205 | static::assertFileExists($dstFile); 206 | static::assertEquals($content, \file_get_contents($dstFile)); 207 | static::assertEquals($content, \file_get_contents($srcFile)); 208 | 209 | \unlink($dstFile); 210 | \rmdir($dstDir); 211 | \unlink($srcFile); 212 | } 213 | 214 | /** 215 | * Test loadFile function for non-existent file. 216 | * 217 | * @return void 218 | */ 219 | public function testLoadFileWithNonexistentFile(): void 220 | { 221 | $this->expectException(\Exception::class); 222 | 223 | $sourceFile = self::$testOutputDir.'/doesNotExist'; 224 | 225 | if (\file_exists($sourceFile)) { 226 | \unlink(self::$testOutputDir.'/doesNotExist'); 227 | } 228 | 229 | $this->ioHelper->loadFile($sourceFile); 230 | } 231 | 232 | /** 233 | * Test copyFile function for non-existent source file 234 | * 235 | * @return void 236 | */ 237 | public function testCopyFileNonExisting(): void 238 | { 239 | $this->expectException(\Exception::class); 240 | 241 | $file = self::$testOutputDir.'/tmpfile'; 242 | $dstDir = self::$testOutputDir.'/tmpdir'; 243 | 244 | if (\file_exists($file)) { 245 | \unlink($file); 246 | } 247 | 248 | $this->ioHelper->copyFile($file, $dstDir); 249 | } 250 | 251 | /** 252 | * Test getCommonPathPrefix with empty file list. 253 | * 254 | * @return void 255 | */ 256 | public function testGetCommonPathPrefixForNoFiles(): void 257 | { 258 | static::assertEquals( 259 | '/', 260 | $this->ioHelper::getCommonPathPrefix([]) 261 | ); 262 | } 263 | } 264 | -------------------------------------------------------------------------------- /src/PHPCodeBrowser/Tests/IssueTest.php: -------------------------------------------------------------------------------- 1 | 63 | * 64 | * @copyright 2007-2010 Mayflower GmbH 65 | * 66 | * @license http://www.opensource.org/licenses/bsd-license.php BSD License 67 | * 68 | * @version Release: @package_version@ 69 | * 70 | * @link http://www.phpunit.de/ 71 | * 72 | * @since Class available since 0.1.0 73 | */ 74 | class IssueTest extends AbstractTestCase 75 | { 76 | /** 77 | * Issue object to test 78 | * 79 | * @var Issue 80 | */ 81 | protected $issue; 82 | 83 | /** 84 | * (non-PHPDoc) 85 | * 86 | * @see tests/cbAbstractTests#setUp() 87 | */ 88 | protected function setUp(): void 89 | { 90 | parent::setUp(); 91 | $this->issue = new Issue( 92 | 'testFileName', 93 | 23, 94 | 27, 95 | 'testFinder', 96 | 'testDescription', 97 | 'notice' 98 | ); 99 | } 100 | 101 | /** 102 | * (non-PHPDoc) 103 | * 104 | * @see tests/cbAbstractTests#tearDown() 105 | */ 106 | protected function tearDown(): void 107 | { 108 | parent::tearDown(); 109 | } 110 | 111 | /** 112 | * Test constructor if variables are stored properly 113 | * 114 | * @return void 115 | */ 116 | public function testInstantiation(): void 117 | { 118 | static::assertSame('testFileName', $this->issue->getFileName()); 119 | static::assertSame(23, $this->issue->getLineStart()); 120 | static::assertSame(27, $this->issue->getLineEnd()); 121 | static::assertSame('testFinder', $this->issue->getFoundBy()); 122 | static::assertSame('testDescription', $this->issue->getDescription()); 123 | static::assertSame('notice', $this->issue->getSeverity()); 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /src/PHPCodeBrowser/Tests/Plugins/ErrorCPDTest.php: -------------------------------------------------------------------------------- 1 | 68 | * 69 | * @copyright 2007-2010 Mayflower GmbH 70 | * 71 | * @license http://www.opensource.org/licenses/bsd-license.php BSD License 72 | * 73 | * @version Release: @package_version@ 74 | * 75 | * @link http://www.phpunit.de/ 76 | * 77 | * @since Class available since 0.9.0 78 | */ 79 | class ErrorCPDTest extends AbstractTestCase 80 | { 81 | /** 82 | * The object to test. 83 | * 84 | * @var ErrorCPD 85 | */ 86 | protected $errorCPD; 87 | 88 | /** 89 | * The xml string to test the plugin against. 90 | * 91 | * @var string 92 | */ 93 | protected $testXml = << 95 | 96 | 97 | 98 | 99 | 100 | echo 'Some code here'; 101 | 102 | 103 | 104 | HERE; 105 | 106 | /** 107 | * (non-PHPDoc) 108 | * 109 | * @see tests/cbAbstractTests#setUp() 110 | */ 111 | protected function setUp(): void 112 | { 113 | parent::setUp(); 114 | $issueXML = new IssueXML(); 115 | $xml = new DOMDocument('1.0', 'UTF-8'); 116 | $xml->loadXML($this->testXml); 117 | $issueXML->addXMLFile($xml); 118 | $this->errorCPD = new ErrorCPD($issueXML); 119 | } 120 | 121 | /** 122 | * Test getFileList 123 | * 124 | * @return void 125 | */ 126 | public function testGettingFileList(): void 127 | { 128 | $expected = [ 129 | new File( 130 | '/original/file', 131 | [ 132 | new Issue( 133 | '/original/file', 134 | 23, 135 | 24, 136 | 'Duplication', 137 | "Copy paste from:\n/copied/file (42)\n (0)", 138 | 'notice' 139 | ), 140 | ] 141 | ), 142 | new File( 143 | '/copied/file', 144 | [ 145 | new Issue( 146 | '/copied/file', 147 | 42, 148 | 43, 149 | 'Duplication', 150 | "Copy paste from:\n/original/file (23)\n (0)", 151 | 'notice' 152 | ), 153 | ] 154 | ), 155 | ]; 156 | $actual = $this->errorCPD->getFileList(); 157 | static::assertEquals($expected, $actual); 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /src/PHPCodeBrowser/Tests/Plugins/ErrorCRAPTest.php: -------------------------------------------------------------------------------- 1 | 68 | * 69 | * @copyright 2007-2010 Mayflower GmbH 70 | * 71 | * @license http://www.opensource.org/licenses/bsd-license.php BSD License 72 | * 73 | * @version Release: @package_version@ 74 | * 75 | * @link http://www.phpunit.de/ 76 | * 77 | * @since Class available since 0.9.0 78 | */ 79 | class ErrorCRAPTest extends AbstractTestCase 80 | { 81 | /** 82 | * The object to test. 83 | * 84 | * @var ErrorCRAP 85 | */ 86 | protected $errorCrap; 87 | 88 | /** 89 | * The xml string to test the plugin against. 90 | * 91 | * @var string 92 | */ 93 | protected $testXml = << 95 | 96 | 97 | 98 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | HERE; 130 | 131 | /** 132 | * (non-PHPDoc) 133 | * 134 | * @see tests/cbAbstractTests#setUp() 135 | */ 136 | protected function setUp(): void 137 | { 138 | parent::setUp(); 139 | $issueXML = new IssueXML(); 140 | $xml = new DOMDocument('1.0', 'UTF-8'); 141 | $xml->loadXML($this->testXml); 142 | $issueXML->addXMLFile($xml); 143 | $this->errorCrap = new ErrorCRAP($issueXML); 144 | } 145 | 146 | /** 147 | * Test getFileList 148 | * 149 | * @return void 150 | */ 151 | public function testGettingFileList(): void 152 | { 153 | $expected = [ 154 | new File( 155 | '/test/file', 156 | [ 157 | new Issue( 158 | '/test/file', 159 | 143, 160 | 143, 161 | 'CRAP', 162 | '1', 163 | 'Notice' 164 | ), 165 | new Issue( 166 | '/test/file', 167 | 162, 168 | 162, 169 | 'CRAP', 170 | '100', 171 | 'Error' 172 | ), 173 | ] 174 | ), 175 | new File( 176 | '/has/no/crap', 177 | [] 178 | ), 179 | ]; 180 | $actual = $this->errorCrap->getFileList(); 181 | static::assertEquals($expected, $actual); 182 | } 183 | 184 | /** 185 | * Test getFileList with limit set 186 | * 187 | * @return void 188 | */ 189 | public function testGetFileListWithLimit(): void 190 | { 191 | $issueXML = new IssueXML(); 192 | $xml = new DOMDocument('1.0', 'UTF-8'); 193 | $xml->loadXML($this->testXml); 194 | $issueXML->addXMLFile($xml); 195 | $this->errorCrap = new ErrorCRAP( 196 | $issueXML, 197 | ['threshold' => 30] 198 | ); 199 | 200 | $expected = [ 201 | new File( 202 | '/test/file', 203 | [ 204 | new Issue( 205 | '/test/file', 206 | 162, 207 | 162, 208 | 'CRAP', 209 | '100', 210 | 'Error' 211 | ), 212 | ] 213 | ), 214 | new File( 215 | '/has/no/crap', 216 | [] 217 | ), 218 | ]; 219 | $actual = $this->errorCrap->getFileList(); 220 | static::assertEquals($expected, $actual); 221 | } 222 | } 223 | -------------------------------------------------------------------------------- /src/PHPCodeBrowser/Tests/Plugins/ErrorCheckstyleTest.php: -------------------------------------------------------------------------------- 1 | 68 | * 69 | * @copyright 2007-2010 Mayflower GmbH 70 | * 71 | * @license http://www.opensource.org/licenses/bsd-license.php BSD License 72 | * 73 | * @version Release: @package_version@ 74 | * 75 | * @link http://www.phpunit.de/ 76 | * 77 | * @since Class available since 0.9.0 78 | */ 79 | class ErrorCheckstyleTest extends AbstractTestCase 80 | { 81 | /** 82 | * The object to test. 83 | * 84 | * @var ErrorCheckstyle 85 | */ 86 | protected $errorCheckstyle; 87 | 88 | /** 89 | * The xml string to test the plugin against. 90 | * 91 | * @var string 92 | */ 93 | protected $testXml = << 95 | 96 | 97 | 102 | 107 | 108 | 109 | 114 | 115 | 116 | 117 | 118 | HERE; 119 | 120 | /** 121 | * (non-PHPDoc) 122 | * 123 | * @see tests/cbAbstractTests#setUp() 124 | */ 125 | protected function setUp(): void 126 | { 127 | parent::setUp(); 128 | $issueXML = new IssueXML(); 129 | $xml = new DOMDocument('1.0', 'UTF-8'); 130 | $xml->validateOnParse = true; 131 | $xml->loadXML($this->testXml); 132 | $issueXML->addXMLFile($xml); 133 | $this->errorCheckstyle = new ErrorCheckstyle($issueXML); 134 | } 135 | 136 | /** 137 | * Test getFileList 138 | * 139 | * @return void 140 | */ 141 | public function testGettingFileList(): void 142 | { 143 | $expected = [ 144 | new File( 145 | '/some/file', 146 | [ 147 | new Issue( 148 | '/some/file', 149 | 117, 150 | 117, 151 | 'Checkstyle', 152 | 'Message 1', 153 | 'error' 154 | ), 155 | new Issue( 156 | '/some/file', 157 | 121, 158 | 121, 159 | 'Checkstyle', 160 | 'Message 2', 161 | 'warning' 162 | ), 163 | ] 164 | ), 165 | new File( 166 | '/other/file', 167 | [ 168 | new Issue( 169 | '/other/file', 170 | 48, 171 | 48, 172 | 'Checkstyle', 173 | 'Message 3', 174 | 'error' 175 | ), 176 | ] 177 | ), 178 | new File( 179 | '/no/violations', 180 | [] 181 | ), 182 | ]; 183 | $actual = $this->errorCheckstyle->getFileList(); 184 | static::assertEquals($expected, $actual); 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /src/PHPCodeBrowser/Tests/Plugins/ErrorCoverageTest.php: -------------------------------------------------------------------------------- 1 | 68 | * 69 | * @copyright 2007-2010 Mayflower GmbH 70 | * 71 | * @license http://www.opensource.org/licenses/bsd-license.php BSD License 72 | * 73 | * @version Release: @package_version@ 74 | * 75 | * @link http://www.phpunit.de/ 76 | * 77 | * @since Class available since 0.9.0 78 | */ 79 | class ErrorCoverageTest extends AbstractTestCase 80 | { 81 | /** 82 | * The object to test. 83 | * 84 | * @var ErrorCoverage 85 | */ 86 | protected $errorCoverage; 87 | 88 | /** 89 | * The xml string to test the plugin against. 90 | * 91 | * @var string 92 | */ 93 | protected $testXml = << 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | HERE; 131 | 132 | /** 133 | * (non-PHPDoc) 134 | * 135 | * @see tests/cbAbstractTests#setUp() 136 | */ 137 | protected function setUp(): void 138 | { 139 | parent::setUp(); 140 | $issueXML = new IssueXML(); 141 | $xml = new DOMDocument('1.0', 'UTF-8'); 142 | $xml->loadXML($this->testXml); 143 | $issueXML->addXMLFile($xml); 144 | $this->errorCoverage = new ErrorCoverage($issueXML); 145 | } 146 | 147 | /** 148 | * Test getFileList 149 | * 150 | * @return void 151 | */ 152 | public function testGettingFileList(): void 153 | { 154 | $expected = [ 155 | new File( 156 | '/partly/tested', 157 | [ 158 | new Issue( 159 | '/partly/tested', 160 | 10, 161 | 14, 162 | 'Coverage', 163 | 'Not covered', 164 | 'Notice' 165 | ), 166 | ] 167 | ), 168 | new File( 169 | '/totally/tested', 170 | [] 171 | ), 172 | new File( 173 | '/not/tested', 174 | [ 175 | new Issue( 176 | '/not/tested', 177 | 212, 178 | 225, 179 | 'Coverage', 180 | 'Not covered', 181 | 'Notice' 182 | ), 183 | ] 184 | ), 185 | ]; 186 | $actual = $this->errorCoverage->getFileList(); 187 | static::assertEquals($expected, $actual); 188 | } 189 | } 190 | -------------------------------------------------------------------------------- /src/PHPCodeBrowser/Tests/Plugins/ErrorPMDTest.php: -------------------------------------------------------------------------------- 1 | 68 | * 69 | * @copyright 2007-2010 Mayflower GmbH 70 | * 71 | * @license http://www.opensource.org/licenses/bsd-license.php BSD License 72 | * 73 | * @version Release: @package_version@ 74 | * 75 | * @link http://www.phpunit.de/ 76 | * 77 | * @since Class available since 0.9.0 78 | */ 79 | class ErrorPMDTest extends AbstractTestCase 80 | { 81 | /** 82 | * The object to test. 83 | * 84 | * @var ErrorPMD 85 | */ 86 | protected $errorPmd; 87 | 88 | /** 89 | * The xml string to test the plugin against. 90 | * 91 | * @var string 92 | */ 93 | protected $testXml = << 95 | 96 | 97 | Description 1 102 | Description 2 109 | 110 | 111 | Description 3 116 | 117 | 118 | 119 | 120 | HERE; 121 | 122 | /** 123 | * (non-PHPDoc) 124 | * 125 | * @see tests/cbAbstractTests#setUp() 126 | */ 127 | protected function setUp(): void 128 | { 129 | parent::setUp(); 130 | $issueXML = new IssueXML(); 131 | $xml = new DOMDocument('1.0', 'UTF-8'); 132 | $xml->loadXML($this->testXml); 133 | $issueXML->addXMLFile($xml); 134 | $this->errorPmd = new ErrorPMD($issueXML); 135 | } 136 | 137 | /** 138 | * Test getFileList 139 | * 140 | * @return void 141 | */ 142 | public function testGettingFileList(): void 143 | { 144 | $expected = [ 145 | new File( 146 | '/some/file', 147 | [ 148 | new Issue( 149 | '/some/file', 150 | 3, 151 | 4, 152 | 'PMD', 153 | 'Description 1', 154 | 'error' 155 | ), 156 | new Issue( 157 | '/some/file', 158 | 5, 159 | 5, 160 | 'PMD', 161 | 'Description 2', 162 | 'error' 163 | ), 164 | ] 165 | ), 166 | new File( 167 | '/other/file', 168 | [ 169 | new Issue( 170 | '/other/file', 171 | 15, 172 | 15, 173 | 'PMD', 174 | 'Description 3', 175 | 'error' 176 | ), 177 | ] 178 | ), 179 | new File( 180 | '/has/no/violation', 181 | [] 182 | ), 183 | ]; 184 | $actual = $this->errorPmd->getFileList(); 185 | static::assertEquals($expected, $actual); 186 | } 187 | } 188 | -------------------------------------------------------------------------------- /src/PHPCodeBrowser/Tests/SourceHandlerTest.php: -------------------------------------------------------------------------------- 1 | 72 | * 73 | * @copyright 2007-2010 Mayflower GmbH 74 | * 75 | * @license http://www.opensource.org/licenses/bsd-license.php BSD License 76 | * 77 | * @version Release: @package_version@ 78 | * 79 | * @link http://www.phpunit.de/ 80 | * 81 | * @since Class available since 0.1.0 82 | */ 83 | class SourceHandlerTest extends AbstractTestCase 84 | { 85 | /** 86 | * SourceHandler object to test 87 | * 88 | * @var SourceHandler 89 | */ 90 | protected $sourceHandler; 91 | 92 | /** 93 | * Plugin array populated with example files. 94 | * TODO: Mock this 95 | * 96 | * @var array of AbstractPlugin 97 | */ 98 | protected $plugins; 99 | 100 | /** 101 | * @var Logger 102 | */ 103 | private $logger; 104 | 105 | /** 106 | * (non-PHPDoc) 107 | * 108 | * @see AbstractTests#setUp() 109 | */ 110 | protected function setUp(): void 111 | { 112 | parent::setUp(); 113 | 114 | $xmlStrings = [ 115 | << 117 | 118 | 119 | descr 122 | 123 | 124 | HERE 125 | , 126 | << 128 | 129 | 130 | 132 | 133 | 134 | 136 | 138 | 139 | 140 | HERE 141 | , 142 | ]; 143 | $issueXML = new IssueXML(); 144 | 145 | foreach ($xmlStrings as $xmlString) { 146 | $xml = new \DOMDocument('1.0', 'UTF-8'); 147 | $xml->validateOnParse = true; 148 | $xml->loadXML($xmlString); 149 | $issueXML->addXMLFile($xml); 150 | } 151 | 152 | $this->plugins = [ 153 | new ErrorCheckstyle($issueXML), 154 | new ErrorPMD($issueXML), 155 | ]; 156 | 157 | $this->logger = new Logger('PHPCodeBrowser'); 158 | $this->logger->pushHandler(new NullHandler()); 159 | 160 | $this->sourceHandler = new SourceHandler($this->logger); 161 | \array_walk( 162 | $this->plugins, 163 | [$this->sourceHandler, 'addPlugin'] 164 | ); 165 | } 166 | 167 | /** 168 | * Test the constructor. 169 | * 170 | * @return void 171 | */ 172 | public function testInstantiation(): void 173 | { 174 | $sourceHandler = new SourceHandler( 175 | $this->logger, 176 | $this->plugins 177 | ); 178 | static::assertEquals($this->sourceHandler, $sourceHandler); 179 | } 180 | 181 | /** 182 | * Test getFiles. 183 | * 184 | * @return void 185 | */ 186 | public function testGetFiles(): void 187 | { 188 | $expected = [ 189 | '/a/nother/dir/src.php' => new File( 190 | '/a/nother/dir/src.php', 191 | [ 192 | new Issue('/a/nother/dir/src.php', 39, 39, 'Checkstyle', 'm3', 'error'), 193 | new Issue('/a/nother/dir/src.php', 40, 40, 'Checkstyle', 'm4', 'error'), 194 | new Issue('/a/nother/dir/src.php', 291, 291, 'PMD', 'descr', 'error'), 195 | ] 196 | ), 197 | '/a/dir/source.php' => new File( 198 | '/a/dir/source.php', 199 | [ 200 | new Issue('/a/dir/source.php', 37, 37, 'Checkstyle', 'm1', 'error'), 201 | ] 202 | ), 203 | ]; 204 | File::sort($expected); 205 | 206 | $actual = $this->sourceHandler->getFiles(); 207 | static::assertEquals($expected, $actual); 208 | } 209 | 210 | /** 211 | * Test getFilesWithIssues 212 | * 213 | * @return void 214 | */ 215 | public function testGetFilesWithIssues(): void 216 | { 217 | $expectedFiles = [ 218 | '/a/dir/source.php', 219 | '/a/nother/dir/src.php', 220 | ]; 221 | $actualFiles = $this->sourceHandler->getFilesWithIssues(); 222 | static::assertEquals($expectedFiles, $actualFiles); 223 | } 224 | 225 | /** 226 | * Test addSourceFiles 227 | * 228 | * @return void 229 | */ 230 | public function testAddSourceFiles(): void 231 | { 232 | $this->sourceHandler->addSourceFiles( 233 | [new SplFileInfo(__FILE__), __FILE__] 234 | ); 235 | static::assertContains(__FILE__, \array_keys($this->sourceHandler->getFiles())); 236 | } 237 | 238 | /** 239 | * Test if addSourceFile chokes on non-existent files. 240 | * 241 | * @return void 242 | */ 243 | public function testAddSourceFilesWithNonExisting(): void 244 | { 245 | $this->expectException(Exception::class); 246 | 247 | $this->sourceHandler->addSourceFiles( 248 | [new SplFileInfo('/i/do/not/exist')] 249 | ); 250 | } 251 | 252 | /** 253 | * Test getCommonPathPrefix 254 | * 255 | * @return void 256 | */ 257 | public function testGetCommonPathPrefix(): void 258 | { 259 | $expected = '/a/'; 260 | $actual = $this->sourceHandler->getCommonPathPrefix(); 261 | static::assertEquals($expected, $actual); 262 | } 263 | 264 | /** 265 | * Test excludeMatchingPCRE 266 | * 267 | * @return void 268 | */ 269 | public function testExcludeMatchingPCRE(): void 270 | { 271 | $expected = [ 272 | '/a/dir/source.php' => new File( 273 | '/a/dir/source.php', 274 | [ 275 | new Issue('/a/dir/source.php', 37, 37, 'Checkstyle', 'm1', 'error'), 276 | ] 277 | ), 278 | ]; 279 | $this->sourceHandler->excludeMatchingPCRE('/^\/a.*src\.php$/'); 280 | static::assertEquals($expected, $this->sourceHandler->getFiles()); 281 | } 282 | 283 | /** 284 | * Test excludeMatchingPattern 285 | * 286 | * @return void 287 | */ 288 | public function testExcludeMatchingPattern(): void 289 | { 290 | $expected = [ 291 | '/a/dir/source.php' => new File( 292 | '/a/dir/source.php', 293 | [ 294 | new Issue('/a/dir/source.php', 37, 37, 'Checkstyle', 'm1', 'error'), 295 | ] 296 | ), 297 | ]; 298 | $this->sourceHandler->excludeMatchingPattern('*src.php'); 299 | static::assertEquals($expected, $this->sourceHandler->getFiles()); 300 | } 301 | } 302 | -------------------------------------------------------------------------------- /src/PHPCodeBrowser/Tests/testData/logs/basic.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /templates/css/cruisecontrol.css: -------------------------------------------------------------------------------- 1 | html { 2 | height: 100%; 3 | width: 100%; 4 | } 5 | 6 | body.codebrowser { 7 | margin: 0; 8 | padding: 0; 9 | border: 0; 10 | width: 100%; 11 | font-family: Arial,Helvetica,sans-serif; 12 | font-size: 12px; 13 | background-color: #fff; 14 | } 15 | 16 | .codebrowser .test { 17 | color: blue; 18 | } 19 | 20 | .codebrowser a { 21 | color: #2e3436; 22 | padding: 2px; 23 | text-decoration: none; 24 | } 25 | 26 | .codebrowser a:hover { 27 | text-decoration: underline; 28 | } 29 | 30 | /** start Tooltip Styles **/ 31 | .codebrowser .prototip { 32 | width: 300px; 33 | position: absolute; 34 | } 35 | 36 | .codebrowser .prototip .effectWrapper { 37 | position: relative; 38 | } 39 | 40 | .codebrowser .prototip .tooltip { 41 | position: relative; 42 | } 43 | 44 | .codebrowser .prototip .toolbar { 45 | position: relative; 46 | display: block; 47 | } 48 | 49 | .codebrowser .prototip .tooltip .title, .tooltip .message { 50 | border: 5px solid #808080; 51 | padding: 5px; 52 | width: 100%; 53 | } 54 | 55 | .codebrowser .prototip .tooltip .title { 56 | color: #808080; 57 | font: italic 17px Georgia, serif; 58 | display: block; 59 | border-bottom: none; 60 | } 61 | 62 | .codebrowser .tooltip .message { 63 | border-top: none; 64 | color: #fff; 65 | font: 11px Arial, Helvetica, sans-serif; 66 | display: block; 67 | background-color: #808080; 68 | } 69 | /** end Tooltip Styles **/ 70 | 71 | .codebrowser .header { 72 | padding: 5px 5px 10px 20px; 73 | } 74 | 75 | .codebrowser .filepath { 76 | background-color: #fff; 77 | color: #555753; 78 | font-size: 1.5em; 79 | font-weight: bold; 80 | padding: 5px 20px 5px 30px; 81 | background-image: url(./../img/page.gif); 82 | background-repeat: no-repeat; 83 | background-position: 4px center; 84 | margin: 5px; 85 | } 86 | 87 | .codebrowser .sourcecode { 88 | padding: 0px; 89 | margin: 0px; 90 | width: 98%; 91 | } 92 | 93 | .codebrowser .filelist { 94 | margin: 5px; 95 | } 96 | 97 | .codebrowser .filelist td { 98 | background-color: #ffffff; 99 | padding: 5px; 100 | } 101 | 102 | .codebrowser .filelist table { 103 | background-color: #fff; 104 | border: none; 105 | } 106 | 107 | 108 | .codebrowser .filelist a { 109 | background-image: url(./../img/page.gif); 110 | background-position: center left; 111 | background-repeat: no-repeat; 112 | padding-left: 20px; 113 | } 114 | 115 | .codebrowser .tree { 116 | margin-top: 10px; 117 | margin-left: 5px; 118 | } 119 | 120 | .codebrowser .filelist tr.file { 121 | background-color: #F3F3F0; 122 | } 123 | 124 | 125 | 126 | .codebrowser ol.code li.transparent { 127 | background-color: transparent; 128 | } 129 | 130 | .codebrowser ol.code li code { 131 | font: 1.2em courier, monospace; 132 | color: #c30; 133 | white-space: pre; 134 | padding-left: 0.5em; 135 | } 136 | 137 | .codebrowser .code .comment { 138 | color: #939399; 139 | } 140 | 141 | .codebrowser .code .default { 142 | color: #44c; 143 | } 144 | 145 | .codebrowser .code .keyword { 146 | color: #373; 147 | } 148 | 149 | .codebrowser .code .string { 150 | color: #c30; 151 | } 152 | 153 | .dTreeNode a img { 154 | margin-left: -2px; 155 | } 156 | 157 | .codebrowser .dtree { 158 | font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; 159 | font-size: 11px; 160 | font-weight: bold; 161 | color: #555753; 162 | white-space: nowrap; 163 | } 164 | 165 | .codebrowser .dtree img { 166 | border: 0px; 167 | vertical-align: middle; 168 | } 169 | 170 | .codebrowser .dtree a { 171 | color: #437610; 172 | font-weight: normal; 173 | text-decoration: none; 174 | } 175 | 176 | .codebrowser .dtree a.node, .dtree a.nodeSel { 177 | white-space: nowrap; 178 | padding: 1px 2px 1px 2px; 179 | } 180 | 181 | .codebrowser .dtree a.node:hover, .dtree a.nodeSel:hover { 182 | color: #ffffff; 183 | background: transparent url(./../img/tab-active.png) repeat-x scroll 0 0 ; 184 | text-decoration: none; 185 | padding: 3px; 186 | } 187 | 188 | .codebrowser .dtree a.nodeSel { 189 | background-color: #c0d2ec; 190 | } 191 | 192 | .codebrowser .dtree .clip { 193 | overflow: hidden; 194 | } 195 | 196 | /** Sidebar Styles **/ 197 | .codebrowser #sideBar { 198 | position: fixed; 199 | width: auto; 200 | height: auto; 201 | top: 80px; 202 | right: 0px; 203 | background-image:url(./../img/background.gif); 204 | background-position:top left; 205 | background-repeat:repeat-y; 206 | text-align: left; 207 | } 208 | 209 | .codebrowser #sideBarTab { 210 | float: left; 211 | height: 137px; 212 | width: 28px; 213 | background-image:url(./../img/slider.gif); 214 | background-repeat: no-repeat; 215 | } 216 | 217 | .codebrowser #sideBarContents { 218 | float: left; 219 | overflow: hidden !important; 220 | width: 600px; 221 | height: 400px; 222 | } 223 | 224 | .codebrowser #sideBarContentsInner { 225 | width: 580px; 226 | overflow: auto; 227 | height: 380px; 228 | margin: 10px; 229 | } 230 | -------------------------------------------------------------------------------- /templates/css/global.css: -------------------------------------------------------------------------------- 1 | /* List borders */ 2 | ol, ul { 3 | border: 1px solid #D3D3D0; 4 | } 5 | 6 | li:first-child { 7 | border-top: none; 8 | } 9 | 10 | li { 11 | border-top: 1px solid #E7E7E7; 12 | } 13 | 14 | /* Table borders */ 15 | table { 16 | border-collapse: collapse; 17 | } 18 | 19 | tr:first-child { 20 | border-left: none; 21 | border-right: none; 22 | } 23 | 24 | tr { 25 | border: 1px solid #E7E7E7; 26 | border-top: none; 27 | } 28 | 29 | /* Alternating Colors */ 30 | 31 | li.even, 32 | tr.even { 33 | background-color: #F9F9F9; 34 | } 35 | 36 | #review li.white, /* This is here because the htmlstill uses this tag */ 37 | li.odd, 38 | tr.odd { 39 | background-color: #FFFFFF; 40 | } 41 | 42 | /* Global Colors */ 43 | .errorCount { 44 | color: red; 45 | } 46 | 47 | .warningCount { 48 | color: blue; 49 | } 50 | -------------------------------------------------------------------------------- /templates/css/review.css: -------------------------------------------------------------------------------- 1 | #review ol { 2 | width: 99%; 3 | margin: 15px; 4 | padding: 0; 5 | font-family: monospace; 6 | font-size: 12px; 7 | line-height: 20px; 8 | color: #939399; 9 | text-align: left; 10 | height: 99%; 11 | list-style: none; 12 | } 13 | 14 | #review ol li { 15 | white-space: nowrap; 16 | margin: 0; 17 | padding: 0 0 0 1%; 18 | color: #4E4E4E; 19 | } 20 | 21 | #review ol li.moreErrors { 22 | background-color: #FFB380; 23 | } 24 | 25 | /* Error type colors */ 26 | 27 | #cluetip .Coverage, 28 | #sidebar .Coverage, 29 | #review .Coverage { 30 | background-color: #BFE4FF; 31 | } 32 | 33 | #cluetip .Duplication, 34 | #sidebar .Duplication, 35 | #review .Duplication { 36 | background-color: #FFBFDC; 37 | } 38 | 39 | #cluetip .Checkstyle, 40 | #sidebar .Checkstyle, 41 | #review .Checkstyle { 42 | background-color: #FFF2BF; 43 | } 44 | 45 | #cluetip .Padawan, 46 | #sidebar .Padawan, 47 | #review .Padawan { 48 | background-color: #E6FF80; 49 | } 50 | 51 | #cluetip .CRAP, 52 | #sidebar .CRAP, 53 | #review .CRAP { 54 | background-color: #FFBFEF; 55 | } 56 | 57 | #cluetip .PMD, 58 | #sidebar .PMD, 59 | #review .PMD { 60 | background-color: #FFCC80; 61 | } 62 | 63 | #cluetip .ZendCodeAnalyzer, 64 | #sidebar .ZendCodeAnalyzer, 65 | #review .ZendCodeAnalyzer { 66 | background-color: #D5BFFF; 67 | } 68 | 69 | #cluetip .EfferentCoupling, 70 | #sidebar .EfferentCoupling, 71 | #review .EfferentCoupling { 72 | background-color: #CCFF99; 73 | } 74 | 75 | /** 76 | * tooltips 77 | */ 78 | /* global */ 79 | #cluetip{ 80 | background-color:#F9F9F9; 81 | filter: alpha(opacity=87); 82 | -moz-opacity:0.87; 83 | opacity:0.87; 84 | -moz-border-radius: 10px; 85 | -webkit-border-radius: 10px; 86 | -moz-border-radius: 10px; 87 | -webkit-border-radius: 10px; 88 | -moz-box-shadow:0px 0px 5px #000; 89 | -webkit-box-shadow:0px 0px 5px #000; 90 | box-shadow:0px 0px 5px #000; 91 | padding: 10px; 92 | /* IE8 and below */ 93 | border: 1px solid black \9; 94 | } 95 | #cluetip-close img { 96 | border: 0; 97 | } 98 | #cluetip-title { 99 | overflow: hidden; 100 | display: none; 101 | height: 0px; 102 | } 103 | #cluetip-title #cluetip-close { 104 | float: right; 105 | position: relative; 106 | } 107 | #cluetip-waitimage { 108 | width: 43px; 109 | height: 11px; 110 | position: absolute; 111 | background-image: url(../js/jquery.cluetip/images/wait.gif); 112 | } 113 | .cluetip-arrows { 114 | display: none; 115 | position: absolute; 116 | top: 0; 117 | left: -11px; 118 | height: 22px; 119 | width: 11px; 120 | background-repeat: no-repeat; 121 | background-position: 0 0; 122 | } 123 | #cluetip-extra { 124 | display: none; 125 | } 126 | 127 | #cluetip-inner{ 128 | background-color: #F9F9F9; 129 | } 130 | /*************************************** 131 | =cluetipClass: 'default' 132 | -------------------------------------- */ 133 | 134 | .cluetip-default { 135 | background-color: #d9d9c2; 136 | } 137 | .cluetip-default #cluetip-outer { 138 | position: relative; 139 | margin: 0; 140 | background-color: #d9d9c2; 141 | } 142 | .cluetip-default h3#cluetip-title { 143 | display: none; 144 | } 145 | .cluetip-default #cluetip-title a { 146 | color: #d9d9c2; 147 | font-size: 0.95em; 148 | } 149 | .cluetip-default #cluetip-inner { 150 | padding: 0px; 151 | } 152 | .cluetip-default div#cluetip-close { 153 | text-align: right; 154 | margin: 0 5px 5px; 155 | color: #900; 156 | } 157 | 158 | .tooltip { 159 | padding-bottom: 3px; 160 | } 161 | 162 | .tooltip .title{ 163 | font-size: medium; 164 | height: 20px; 165 | line-height: 20px; 166 | vertical-align: middle; 167 | width: 100%; 168 | padding: 3px; 169 | } 170 | .tooltip .text{ 171 | padding: 3px; 172 | border-bottom: 1px solid #E7E7E7; 173 | font-size: 12px; 174 | } 175 | 176 | /** 177 | * Sidebar 178 | */ 179 | 180 | #sidebar { 181 | width: 560px; 182 | height: 360px; 183 | overflow:auto; 184 | } 185 | #sidebar table { 186 | background-color:#E7E7E7; 187 | border-spacing:1px; 188 | color:#666666; 189 | } 190 | 191 | #sidebar table td { 192 | vertical-align: top; 193 | } 194 | 195 | #sidebar table tr.head td { 196 | background-color: #fff; 197 | height: 25px; 198 | border-bottom: solid 1px #BABDB6; 199 | color:black; 200 | } 201 | 202 | #sidebar table tr { 203 | text-align:left; 204 | } 205 | 206 | #sidebar table tr.odd { 207 | border-top:1px solid #FFFFFF; 208 | } 209 | -------------------------------------------------------------------------------- /templates/css/tree.css: -------------------------------------------------------------------------------- 1 | .jstree ol, 2 | .jstree ul, 3 | .jstree li { 4 | border: none; 5 | } 6 | 7 | .jstree li.php a .jstree-icon { 8 | background-repeat: repeat; 9 | background-image: url(../img/page.gif); 10 | } 11 | 12 | .jstree a { 13 | cursor: pointer; 14 | } 15 | 16 | #treeContainer { 17 | float: left; 18 | } 19 | 20 | #tree { 21 | float: left; 22 | padding-right: 5px; 23 | display: none; 24 | } 25 | 26 | #treeToggle { 27 | display: inline-block; 28 | min-height: 200px; 29 | -moz-opacity:0.87; 30 | opacity:0.87; 31 | -moz-border-radius-bottomright: 10px; 32 | -webkit-border-bottom-right-radius: 10px; 33 | -moz-box-shadow: 1px 1px 3px #000000; 34 | -webkit-box-shadow: 1px 1px 3px #000000; 35 | box-shadow:0px 0px 5px #000; 36 | background-color: #F9F9F9; 37 | background-position: center center; 38 | background-repeat: no-repeat; 39 | padding: 16px; 40 | /* IE8 and below. */ 41 | border: 1px solid black \9; 42 | } 43 | 44 | #treeHeader { 45 | font-weight: bold; 46 | color: #555753; 47 | white-space: nowrap; 48 | } 49 | 50 | #treeHeader .jstree-icon { 51 | background-image: url("../img/base.gif"); 52 | background-position: 0 0; 53 | } 54 | -------------------------------------------------------------------------------- /templates/img/background.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/img/background.gif -------------------------------------------------------------------------------- /templates/img/base.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/img/base.gif -------------------------------------------------------------------------------- /templates/img/cd.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/img/cd.gif -------------------------------------------------------------------------------- /templates/img/empty.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/img/empty.gif -------------------------------------------------------------------------------- /templates/img/folder.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/img/folder.gif -------------------------------------------------------------------------------- /templates/img/folderopen.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/img/folderopen.gif -------------------------------------------------------------------------------- /templates/img/globe.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/img/globe.gif -------------------------------------------------------------------------------- /templates/img/imgfolder.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/img/imgfolder.gif -------------------------------------------------------------------------------- /templates/img/join.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/img/join.gif -------------------------------------------------------------------------------- /templates/img/joinbottom.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/img/joinbottom.gif -------------------------------------------------------------------------------- /templates/img/line.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/img/line.gif -------------------------------------------------------------------------------- /templates/img/minus.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/img/minus.gif -------------------------------------------------------------------------------- /templates/img/minusbottom.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/img/minusbottom.gif -------------------------------------------------------------------------------- /templates/img/musicfolder.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/img/musicfolder.gif -------------------------------------------------------------------------------- /templates/img/nolines_minus.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/img/nolines_minus.gif -------------------------------------------------------------------------------- /templates/img/nolines_plus.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/img/nolines_plus.gif -------------------------------------------------------------------------------- /templates/img/page.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/img/page.gif -------------------------------------------------------------------------------- /templates/img/page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/img/page.png -------------------------------------------------------------------------------- /templates/img/plus.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/img/plus.gif -------------------------------------------------------------------------------- /templates/img/plusbottom.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/img/plusbottom.gif -------------------------------------------------------------------------------- /templates/img/question.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/img/question.gif -------------------------------------------------------------------------------- /templates/img/separator.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/img/separator.gif -------------------------------------------------------------------------------- /templates/img/slider.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/img/slider.gif -------------------------------------------------------------------------------- /templates/img/tab-active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/img/tab-active.png -------------------------------------------------------------------------------- /templates/img/trash.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/img/trash.gif -------------------------------------------------------------------------------- /templates/img/treeToggle-collapsed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/img/treeToggle-collapsed.png -------------------------------------------------------------------------------- /templates/img/treeToggle-extended.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/img/treeToggle-extended.png -------------------------------------------------------------------------------- /templates/img/treeToggle.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/img/treeToggle.gif -------------------------------------------------------------------------------- /templates/index.tpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | PHP CodeBrowser 24 | 25 | 26 |
27 |
28 |
29 | CodeBrowser 30 |
31 | 32 |
33 |
34 |
35 |
36 |
37 | 38 | false, 45 | 'CRAP' => false, 46 | 'Checkstyle' => false, 47 | 'Coverage' => false, 48 | 'PMD' => false, 49 | 'Padawan' => false 50 | ); 51 | 52 | foreach ($fileList as $file) { 53 | /** @var $file PHPCodeBrowser\File */ 54 | foreach ($file->getIssues() as $issue) { 55 | $occuringErrorTypes[$issue->getFoundBy()] = true; 56 | } 57 | } 58 | 59 | $occuringErrorTypes = array_keys(array_filter($occuringErrorTypes)); 60 | 61 | // Print the tables head 62 | echo ' '; 63 | echo ' ' . PHP_EOL; 64 | echo ' ' . PHP_EOL; 66 | echo ' ' . PHP_EOL; 68 | 69 | foreach ($occuringErrorTypes as $errorType) { 70 | echo " " . PHP_EOL; 72 | } 73 | echo ' ' . PHP_EOL; 74 | 75 | // Print the file table 76 | /** @var $f PHPCodeBrowser\File */ 77 | foreach ($fileList as $filename => $f) { 78 | $tag = $oddrow ? 'odd' : 'even'; 79 | $oddrow = !$oddrow; 80 | $shortName = substr($filename, $preLen); 81 | $shortName = str_replace('\\', '/', $shortName); 82 | $errors = $f->getErrorCount(); 83 | $warnings = $f->getWarningCount(); 84 | 85 | $counts = array_fill_keys($occuringErrorTypes, 0); 86 | 87 | foreach ($f->getIssues() as $issue) { 88 | $counts[$issue->getFoundBy()] += 1; 89 | } 90 | 91 | echo " " . PHP_EOL; 92 | echo " " . PHP_EOL; 94 | echo " " . PHP_EOL; 96 | echo " " . PHP_EOL; 98 | 99 | foreach ($counts as $count) { 100 | echo " " . PHP_EOL; 101 | } 102 | echo " " . PHP_EOL; 103 | } 104 | ?> 105 |
FileErrors' 65 | . 'Warnings' 67 | . '" 71 | . "$errorType
$shortName" 95 | . "$errors" 97 | . "$warnings$count
106 |
107 |
108 | 109 | 110 | -------------------------------------------------------------------------------- /templates/js/jquery.cluetip/images/arrowdown.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/js/jquery.cluetip/images/arrowdown.gif -------------------------------------------------------------------------------- /templates/js/jquery.cluetip/images/arrowleft.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/js/jquery.cluetip/images/arrowleft.gif -------------------------------------------------------------------------------- /templates/js/jquery.cluetip/images/arrowright.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/js/jquery.cluetip/images/arrowright.gif -------------------------------------------------------------------------------- /templates/js/jquery.cluetip/images/arrowup.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/js/jquery.cluetip/images/arrowup.gif -------------------------------------------------------------------------------- /templates/js/jquery.cluetip/images/bl.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/js/jquery.cluetip/images/bl.gif -------------------------------------------------------------------------------- /templates/js/jquery.cluetip/images/bl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/js/jquery.cluetip/images/bl.png -------------------------------------------------------------------------------- /templates/js/jquery.cluetip/images/br.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/js/jquery.cluetip/images/br.gif -------------------------------------------------------------------------------- /templates/js/jquery.cluetip/images/br.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/js/jquery.cluetip/images/br.png -------------------------------------------------------------------------------- /templates/js/jquery.cluetip/images/darrowdown.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/js/jquery.cluetip/images/darrowdown.gif -------------------------------------------------------------------------------- /templates/js/jquery.cluetip/images/darrowleft.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/js/jquery.cluetip/images/darrowleft.gif -------------------------------------------------------------------------------- /templates/js/jquery.cluetip/images/darrowright.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/js/jquery.cluetip/images/darrowright.gif -------------------------------------------------------------------------------- /templates/js/jquery.cluetip/images/darrowup.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/js/jquery.cluetip/images/darrowup.gif -------------------------------------------------------------------------------- /templates/js/jquery.cluetip/images/itunes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/js/jquery.cluetip/images/itunes.png -------------------------------------------------------------------------------- /templates/js/jquery.cluetip/images/rarrowdown.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/js/jquery.cluetip/images/rarrowdown.gif -------------------------------------------------------------------------------- /templates/js/jquery.cluetip/images/rarrowleft.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/js/jquery.cluetip/images/rarrowleft.gif -------------------------------------------------------------------------------- /templates/js/jquery.cluetip/images/rarrowright.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/js/jquery.cluetip/images/rarrowright.gif -------------------------------------------------------------------------------- /templates/js/jquery.cluetip/images/rarrowup.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/js/jquery.cluetip/images/rarrowup.gif -------------------------------------------------------------------------------- /templates/js/jquery.cluetip/images/tl.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/js/jquery.cluetip/images/tl.gif -------------------------------------------------------------------------------- /templates/js/jquery.cluetip/images/tl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/js/jquery.cluetip/images/tl.png -------------------------------------------------------------------------------- /templates/js/jquery.cluetip/images/tr.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/js/jquery.cluetip/images/tr.gif -------------------------------------------------------------------------------- /templates/js/jquery.cluetip/images/tr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/js/jquery.cluetip/images/tr.png -------------------------------------------------------------------------------- /templates/js/jquery.cluetip/images/wait.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mayflower/PHP_CodeBrowser/0835029efed6de613a4d3e6ad0e568089ff8f35e/templates/js/jquery.cluetip/images/wait.gif -------------------------------------------------------------------------------- /templates/js/jquery.cluetip/jquery.cluetip.css: -------------------------------------------------------------------------------- 1 | /* global */ 2 | #cluetip{ 3 | background-color:#F9F9F9; 4 | /*filter: alpha(opacity=87); 5 | -moz-opacity:0.87; 6 | opacity:0.87; 7 | -moz-border-radius: 10px; 8 | -webkit-border-radius: 10px; 9 | -moz-border-radius: 10px; 10 | -webkit-border-radius: 10px; 11 | -moz-box-shadow:0px 0px 20px #000; 12 | -webkit-box-shadow:0px 0px 20px #000;*/ 13 | /*box-shadow:0px 0px 20px #000;*/ 14 | padding: 10px; 15 | } 16 | #cluetip-close img { 17 | border: 0; 18 | } 19 | #cluetip-title { 20 | overflow: hidden; 21 | display: none; 22 | height: 0px; 23 | } 24 | #cluetip-title #cluetip-close { 25 | float: right; 26 | position: relative; 27 | } 28 | #cluetip-waitimage { 29 | width: 43px; 30 | height: 11px; 31 | position: absolute; 32 | background-image: url(images/wait.gif); 33 | } 34 | .cluetip-arrows { 35 | display: none; 36 | position: absolute; 37 | top: 0; 38 | left: -11px; 39 | height: 22px; 40 | width: 11px; 41 | background-repeat: no-repeat; 42 | background-position: 0 0; 43 | } 44 | #cluetip-extra { 45 | display: none; 46 | } 47 | /*************************************** 48 | =cluetipClass: 'default' 49 | -------------------------------------- */ 50 | 51 | .cluetip-default { 52 | background-color: #d9d9c2; 53 | } 54 | .cluetip-default #cluetip-outer { 55 | position: relative; 56 | margin: 0; 57 | background-color: #d9d9c2; 58 | } 59 | .cluetip-default h3#cluetip-title { 60 | display: none; 61 | } 62 | .cluetip-default #cluetip-title a { 63 | color: #d9d9c2; 64 | font-size: 0.95em; 65 | } 66 | .cluetip-default #cluetip-inner { 67 | padding: 0px; 68 | } 69 | .cluetip-default div#cluetip-close { 70 | text-align: right; 71 | margin: 0 5px 5px; 72 | color: #900; 73 | } 74 | 75 | /* default arrows */ 76 | 77 | .clue-right-default .cluetip-arrows { 78 | background-image: url(images/darrowleft.gif); 79 | } 80 | .clue-left-default .cluetip-arrows { 81 | background-image: url(images/darrowright.gif); 82 | left: 100%; 83 | margin-right: -11px; 84 | } 85 | .clue-top-default .cluetip-arrows { 86 | background-image: url(images/darrowdown.gif); 87 | top: 100%; 88 | left: 50%; 89 | margin-left: -11px; 90 | height: 11px; 91 | width: 22px; 92 | } 93 | .clue-bottom-default .cluetip-arrows { 94 | background-image: url(images/darrowup.gif); 95 | top: -11px; 96 | left: 50%; 97 | margin-left: -11px; 98 | height: 11px; 99 | width: 22px; 100 | } 101 | 102 | /*************************************** 103 | =cluetipClass: 'jtip' 104 | -------------------------------------- */ 105 | .cluetip-jtip { 106 | background-color: transparent; 107 | } 108 | .cluetip-jtip #cluetip-outer { 109 | border: 2px solid #ccc; 110 | position: relative; 111 | background-color: #fff; 112 | } 113 | 114 | .cluetip-jtip h3#cluetip-title { 115 | margin: 0 0 5px; 116 | padding: 2px 5px; 117 | font-size: 16px; 118 | font-weight: normal; 119 | background-color: #ccc; 120 | color: #333; 121 | } 122 | 123 | .cluetip-jtip #cluetip-inner { 124 | padding: 0 5px 5px; 125 | display: inline-block; 126 | } 127 | .cluetip-jtip div#cluetip-close { 128 | text-align: right; 129 | margin: 0 5px 5px; 130 | color: #900; 131 | } 132 | 133 | /* jtip arrows */ 134 | 135 | .clue-right-jtip .cluetip-arrows { 136 | background-image: url(images/arrowleft.gif); 137 | } 138 | .clue-left-jtip .cluetip-arrows { 139 | background-image: url(images/arrowright.gif); 140 | left: 100%; 141 | margin-right: -11px; 142 | } 143 | .clue-top-jtip .cluetip-arrows { 144 | background-image: url(images/arrowdown.gif); 145 | top: 100%; 146 | left: 50%; 147 | margin-left: -11px; 148 | height: 11px; 149 | width: 22px; 150 | } 151 | .clue-bottom-jtip .cluetip-arrows { 152 | background-image: url(images/arrowup.gif); 153 | top: -11px; 154 | left: 50%; 155 | margin-left: -11px; 156 | height: 11px; 157 | width: 22px; 158 | } 159 | 160 | /*************************************** 161 | =cluetipClass: 'rounded' 162 | -------------------------------------- */ 163 | 164 | .cluetip-rounded { 165 | background: transparent url(images/bl.gif) no-repeat 0 100%; 166 | margin-top: 10px; 167 | margin-left: 12px; 168 | } 169 | 170 | .cluetip-rounded #cluetip-outer { 171 | background: transparent url(images/tl.gif) no-repeat 0 0; 172 | margin-top: -12px; 173 | } 174 | 175 | .cluetip-rounded #cluetip-title { 176 | background-color: transparent; 177 | padding: 12px 12px 0; 178 | margin: 0 -12px 0 0; 179 | position: relative; 180 | } 181 | .cluetip-rounded #cluetip-extra { 182 | position: absolute; 183 | display: block; 184 | background: transparent url(images/tr.gif) no-repeat 100% 0; 185 | top: 0; 186 | right: 0; 187 | width: 12px; 188 | height: 30px; 189 | margin: -12px -12px 0 0; 190 | } 191 | .cluetip-rounded #cluetip-inner { 192 | background: url(images/br.gif) no-repeat 100% 100%; 193 | padding: 5px 12px 12px; 194 | margin: -18px -12px 0 0; 195 | position: relative; 196 | } 197 | 198 | .cluetip-rounded div#cluetip-close { 199 | text-align: right; 200 | margin: 0 5px 5px; 201 | color: #009; 202 | background: transparent; 203 | } 204 | .cluetip-rounded div#cluetip-close a { 205 | color: #777; 206 | } 207 | 208 | /* rounded arrows */ 209 | 210 | .clue-right-rounded .cluetip-arrows { 211 | background-image: url(images/rarrowleft.gif); 212 | } 213 | .clue-left-rounded .cluetip-arrows { 214 | background-image: url(images/rarrowright.gif); 215 | left: 100%; 216 | margin-left: 12px; 217 | } 218 | .clue-top-rounded .cluetip-arrows { 219 | background-image: url(images/rarrowdown.gif); 220 | top: 100%; 221 | left: 50%; 222 | margin-left: -11px; 223 | height: 11px; 224 | width: 22px; 225 | } 226 | .clue-bottom-rounded .cluetip-arrows { 227 | background-image: url(images/rarrowup.gif); 228 | top: -23px; 229 | left: 50%; 230 | margin-left: -11px; 231 | height: 11px; 232 | width: 22px; 233 | } 234 | 235 | 236 | 237 | /* stupid IE6 HasLayout hack */ 238 | .cluetip-rounded #cluetip-title, 239 | .cluetip-rounded #cluetip-inner { 240 | zoom: 1; 241 | } -------------------------------------------------------------------------------- /templates/js/jquery.cluetip/lib/jquery.bgiframe.min.js: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006 Brandon Aaron (http://brandonaaron.net) 2 | * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) 3 | * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses. 4 | * 5 | * $LastChangedDate: 2007-07-21 19:45:56 -0400 (Sat, 21 Jul 2007) $ 6 | * $Rev: 2447 $ 7 | * 8 | * Version 2.1.1 9 | */ 10 | (function($){$.fn.bgIframe=$.fn.bgiframe=function(s){if($.browser.msie&&/6.0/.test(navigator.userAgent)){s=$.extend({top:'auto',left:'auto',width:'auto',height:'auto',opacity:true,src:'javascript:false;'},s||{});var prop=function(n){return n&&n.constructor==Number?n+'px':n;},html='