Merge branch 'php56-fixes'

This commit is contained in:
Dmitry Khomutov 2018-03-14 21:30:30 +07:00
commit 583c2875bf
No known key found for this signature in database
GPG key ID: EC19426474B37AAC
355 changed files with 6305 additions and 5535 deletions

View file

@ -6,7 +6,7 @@ coverage:
- "runtime"
- "tests"
- "vendor"
- "src/PHPCensor/Migrations"
- "src/PHPCensor/Languages"
- "src/Migrations"
- "src/Languages"
comment: off

View file

@ -5,7 +5,7 @@ if (!defined('ROOT_DIR')) {
}
if (!defined('SRC_DIR')) {
define('SRC_DIR', ROOT_DIR . 'src/PHPCensor/');
define('SRC_DIR', ROOT_DIR . 'src/');
}
if (!defined('PUBLIC_DIR')) {
@ -26,13 +26,10 @@ if (!defined('RUNTIME_DIR')) {
require_once(ROOT_DIR . 'vendor/autoload.php');
// Load configuration if present:
$conf = [];
$conf['b8']['app']['namespace'] = 'PHPCensor';
$conf['b8']['app']['default_controller'] = 'Home';
$conf['b8']['view']['path'] = SRC_DIR . 'View/';
use PHPCensor\Config;
use PHPCensor\Helper\Lang;
$config = new b8\Config($conf);
$config = new Config();
$configFile = APP_DIR . 'config.yml';
if (file_exists($configFile)) {
@ -43,4 +40,4 @@ if (!defined('APP_URL') && !empty($config)) {
define('APP_URL', $config->get('php-censor.url', '') . '/');
}
\PHPCensor\Helper\Lang::init($config);
Lang::init($config);

View file

@ -36,14 +36,12 @@
},
"autoload": {
"psr-4": {
"PHPCensor\\": "src/PHPCensor/",
"b8\\": "src/B8Framework/"
"PHPCensor\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\PHPCensor\\": "tests/PHPCensor/",
"Tests\\b8\\": "tests/B8Framework/"
"Tests\\PHPCensor\\": "tests/src/"
}
},
"require": {
@ -63,7 +61,6 @@
"symfony/browser-kit": "~3.4.0",
"symfony/process": "~3.4.0",
"symfony/filesystem": "~3.4.0",
"symfony/debug": "~3.4.0",
"symfony/dependency-injection": "~3.4.0",
"symfony/event-dispatcher": "~3.4.0",
"symfony/cache": "~3.4.0",
@ -84,7 +81,9 @@
"phploc/phploc": "~4.0.0",
"jakub-onderka/php-parallel-lint": "~0.9.0",
"sensiolabs/security-checker": "~4.0.0",
"paragonie/random_compat": "~2.0.0",
"symfony/debug": "~3.4.0",
"doctrine/instantiator": "~1.0.0",
"phpunit/php-token-stream": "~1.4.0",
"phpdocumentor/reflection-docblock": "~2.0.0",
@ -99,7 +98,8 @@
"bower-asset/raphael": "~2.2.0"
},
"require-dev": {
"phpunit/dbunit": "~2.0.0"
"phpunit/dbunit": "~2.0.0",
"symfony/var-dumper": "~3.4.0"
},
"suggest": {
"maknz/slack": "For SlackNotify plugin",

262
composer.lock generated
View file

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"content-hash": "86960b0e8aee816f39921ca1c3e6bfc3",
"content-hash": "8c2289ac491f1f1019f88be4f375b8a9",
"packages": [
{
"name": "behat/gherkin",
@ -1025,16 +1025,16 @@
},
{
"name": "nikic/php-parser",
"version": "v3.1.4",
"version": "v3.1.5",
"source": {
"type": "git",
"url": "https://github.com/nikic/PHP-Parser.git",
"reference": "e57b3a09784f846411aa7ed664eedb73e3399078"
"reference": "bb87e28e7d7b8d9a7fda231d37457c9210faf6ce"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/e57b3a09784f846411aa7ed664eedb73e3399078",
"reference": "e57b3a09784f846411aa7ed664eedb73e3399078",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/bb87e28e7d7b8d9a7fda231d37457c9210faf6ce",
"reference": "bb87e28e7d7b8d9a7fda231d37457c9210faf6ce",
"shasum": ""
},
"require": {
@ -1072,7 +1072,7 @@
"parser",
"php"
],
"time": "2018-01-25T21:31:33+00:00"
"time": "2018-02-28T20:30:58+00:00"
},
{
"name": "npm-asset/codemirror",
@ -1144,6 +1144,54 @@
"homepage": "http://www.oomphinc.com/",
"time": "2017-03-31T16:57:39+00:00"
},
{
"name": "paragonie/random_compat",
"version": "v2.0.11",
"source": {
"type": "git",
"url": "https://github.com/paragonie/random_compat.git",
"reference": "5da4d3c796c275c55f057af5a643ae297d96b4d8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/5da4d3c796c275c55f057af5a643ae297d96b4d8",
"reference": "5da4d3c796c275c55f057af5a643ae297d96b4d8",
"shasum": ""
},
"require": {
"php": ">=5.2.0"
},
"require-dev": {
"phpunit/phpunit": "4.*|5.*"
},
"suggest": {
"ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
},
"type": "library",
"autoload": {
"files": [
"lib/random.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Paragon Initiative Enterprises",
"email": "security@paragonie.com",
"homepage": "https://paragonie.com"
}
],
"description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
"keywords": [
"csprng",
"pseudorandom",
"random"
],
"time": "2017-09-27T21:40:39+00:00"
},
{
"name": "pda/pheanstalk",
"version": "v3.1.0",
@ -2091,16 +2139,16 @@
},
{
"name": "psr/simple-cache",
"version": "1.0.0",
"version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/php-fig/simple-cache.git",
"reference": "753fa598e8f3b9966c886fe13f370baa45ef0e24"
"reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/simple-cache/zipball/753fa598e8f3b9966c886fe13f370baa45ef0e24",
"reference": "753fa598e8f3b9966c886fe13f370baa45ef0e24",
"url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b",
"reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b",
"shasum": ""
},
"require": {
@ -2135,7 +2183,7 @@
"psr-16",
"simple-cache"
],
"time": "2017-01-02T13:31:39+00:00"
"time": "2017-10-23T01:57:42+00:00"
},
{
"name": "robmorgan/phinx",
@ -3029,7 +3077,7 @@
},
{
"name": "symfony/browser-kit",
"version": "v3.4.4",
"version": "v3.4.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/browser-kit.git",
@ -3086,16 +3134,16 @@
},
{
"name": "symfony/cache",
"version": "v3.4.4",
"version": "v3.4.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/cache.git",
"reference": "8dee9ec2c9824c3f4039960d679a6689ee1cbdc1"
"reference": "cce49c7aa2fc82077355c8a6dfcd9e619abe6e98"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/cache/zipball/8dee9ec2c9824c3f4039960d679a6689ee1cbdc1",
"reference": "8dee9ec2c9824c3f4039960d679a6689ee1cbdc1",
"url": "https://api.github.com/repos/symfony/cache/zipball/cce49c7aa2fc82077355c8a6dfcd9e619abe6e98",
"reference": "cce49c7aa2fc82077355c8a6dfcd9e619abe6e98",
"shasum": ""
},
"require": {
@ -3152,20 +3200,20 @@
"caching",
"psr6"
],
"time": "2018-01-18T22:16:57+00:00"
"time": "2018-02-11T14:42:07+00:00"
},
{
"name": "symfony/config",
"version": "v3.4.4",
"version": "v3.4.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/config.git",
"reference": "72689b934d6c6ecf73eca874e98933bf055313c9"
"reference": "05e10567b529476a006b00746c5f538f1636810e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/config/zipball/72689b934d6c6ecf73eca874e98933bf055313c9",
"reference": "72689b934d6c6ecf73eca874e98933bf055313c9",
"url": "https://api.github.com/repos/symfony/config/zipball/05e10567b529476a006b00746c5f538f1636810e",
"reference": "05e10567b529476a006b00746c5f538f1636810e",
"shasum": ""
},
"require": {
@ -3178,6 +3226,7 @@
},
"require-dev": {
"symfony/dependency-injection": "~3.3|~4.0",
"symfony/event-dispatcher": "~3.3|~4.0",
"symfony/finder": "~3.3|~4.0",
"symfony/yaml": "~3.0|~4.0"
},
@ -3214,20 +3263,20 @@
],
"description": "Symfony Config Component",
"homepage": "https://symfony.com",
"time": "2018-01-21T19:05:02+00:00"
"time": "2018-02-14T10:03:57+00:00"
},
{
"name": "symfony/console",
"version": "v3.4.4",
"version": "v3.4.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
"reference": "26b6f419edda16c19775211987651cb27baea7f1"
"reference": "067339e9b8ec30d5f19f5950208893ff026b94f7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/26b6f419edda16c19775211987651cb27baea7f1",
"reference": "26b6f419edda16c19775211987651cb27baea7f1",
"url": "https://api.github.com/repos/symfony/console/zipball/067339e9b8ec30d5f19f5950208893ff026b94f7",
"reference": "067339e9b8ec30d5f19f5950208893ff026b94f7",
"shasum": ""
},
"require": {
@ -3283,20 +3332,20 @@
],
"description": "Symfony Console Component",
"homepage": "https://symfony.com",
"time": "2018-01-29T09:03:43+00:00"
"time": "2018-02-26T15:46:28+00:00"
},
{
"name": "symfony/css-selector",
"version": "v3.4.4",
"version": "v3.4.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/css-selector.git",
"reference": "e66394bc7610e69279bfdb3ab11b4fe65403f556"
"reference": "544655f1fc078a9cd839fdda2b7b1e64627c826a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/css-selector/zipball/e66394bc7610e69279bfdb3ab11b4fe65403f556",
"reference": "e66394bc7610e69279bfdb3ab11b4fe65403f556",
"url": "https://api.github.com/repos/symfony/css-selector/zipball/544655f1fc078a9cd839fdda2b7b1e64627c826a",
"reference": "544655f1fc078a9cd839fdda2b7b1e64627c826a",
"shasum": ""
},
"require": {
@ -3336,20 +3385,20 @@
],
"description": "Symfony CssSelector Component",
"homepage": "https://symfony.com",
"time": "2018-01-03T07:37:34+00:00"
"time": "2018-02-03T14:55:07+00:00"
},
{
"name": "symfony/debug",
"version": "v3.4.4",
"version": "v3.4.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/debug.git",
"reference": "53f6af2805daf52a43b393b93d2f24925d35c937"
"reference": "9b1071f86e79e1999b3d3675d2e0e7684268b9bc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/debug/zipball/53f6af2805daf52a43b393b93d2f24925d35c937",
"reference": "53f6af2805daf52a43b393b93d2f24925d35c937",
"url": "https://api.github.com/repos/symfony/debug/zipball/9b1071f86e79e1999b3d3675d2e0e7684268b9bc",
"reference": "9b1071f86e79e1999b3d3675d2e0e7684268b9bc",
"shasum": ""
},
"require": {
@ -3392,20 +3441,20 @@
],
"description": "Symfony Debug Component",
"homepage": "https://symfony.com",
"time": "2018-01-18T22:16:57+00:00"
"time": "2018-02-28T21:49:22+00:00"
},
{
"name": "symfony/dependency-injection",
"version": "v3.4.4",
"version": "v3.4.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/dependency-injection.git",
"reference": "4b2717ee2499390e371e1fc7abaf886c1c83e83d"
"reference": "12e901abc1cb0d637a0e5abe9923471361d96b07"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/dependency-injection/zipball/4b2717ee2499390e371e1fc7abaf886c1c83e83d",
"reference": "4b2717ee2499390e371e1fc7abaf886c1c83e83d",
"url": "https://api.github.com/repos/symfony/dependency-injection/zipball/12e901abc1cb0d637a0e5abe9923471361d96b07",
"reference": "12e901abc1cb0d637a0e5abe9923471361d96b07",
"shasum": ""
},
"require": {
@ -3463,20 +3512,20 @@
],
"description": "Symfony DependencyInjection Component",
"homepage": "https://symfony.com",
"time": "2018-01-29T09:16:57+00:00"
"time": "2018-03-04T03:54:53+00:00"
},
{
"name": "symfony/dom-crawler",
"version": "v3.4.4",
"version": "v3.4.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/dom-crawler.git",
"reference": "09bd97b844b3151fab82f2fdd62db9c464b3910a"
"reference": "2bb5d3101cc01f4fe580e536daf4f1959bc2d24d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/dom-crawler/zipball/09bd97b844b3151fab82f2fdd62db9c464b3910a",
"reference": "09bd97b844b3151fab82f2fdd62db9c464b3910a",
"url": "https://api.github.com/repos/symfony/dom-crawler/zipball/2bb5d3101cc01f4fe580e536daf4f1959bc2d24d",
"reference": "2bb5d3101cc01f4fe580e536daf4f1959bc2d24d",
"shasum": ""
},
"require": {
@ -3519,20 +3568,20 @@
],
"description": "Symfony DomCrawler Component",
"homepage": "https://symfony.com",
"time": "2018-01-03T07:37:34+00:00"
"time": "2018-02-22T10:48:49+00:00"
},
{
"name": "symfony/event-dispatcher",
"version": "v3.4.4",
"version": "v3.4.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher.git",
"reference": "26b87b6bca8f8f797331a30b76fdae5342dc26ca"
"reference": "58990682ac3fdc1f563b7e705452921372aad11d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/26b87b6bca8f8f797331a30b76fdae5342dc26ca",
"reference": "26b87b6bca8f8f797331a30b76fdae5342dc26ca",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/58990682ac3fdc1f563b7e705452921372aad11d",
"reference": "58990682ac3fdc1f563b7e705452921372aad11d",
"shasum": ""
},
"require": {
@ -3582,20 +3631,20 @@
],
"description": "Symfony EventDispatcher Component",
"homepage": "https://symfony.com",
"time": "2018-01-03T07:37:34+00:00"
"time": "2018-02-14T10:03:57+00:00"
},
{
"name": "symfony/filesystem",
"version": "v3.4.4",
"version": "v3.4.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/filesystem.git",
"reference": "e078773ad6354af38169faf31c21df0f18ace03d"
"reference": "253a4490b528597aa14d2bf5aeded6f5e5e4a541"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/filesystem/zipball/e078773ad6354af38169faf31c21df0f18ace03d",
"reference": "e078773ad6354af38169faf31c21df0f18ace03d",
"url": "https://api.github.com/repos/symfony/filesystem/zipball/253a4490b528597aa14d2bf5aeded6f5e5e4a541",
"reference": "253a4490b528597aa14d2bf5aeded6f5e5e4a541",
"shasum": ""
},
"require": {
@ -3631,20 +3680,20 @@
],
"description": "Symfony Filesystem Component",
"homepage": "https://symfony.com",
"time": "2018-01-03T07:37:34+00:00"
"time": "2018-02-22T10:48:49+00:00"
},
{
"name": "symfony/finder",
"version": "v3.4.4",
"version": "v3.4.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
"reference": "613e26310776f49a1773b6737c6bd554b8bc8c6f"
"reference": "a479817ce0a9e4adfd7d39c6407c95d97c254625"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/finder/zipball/613e26310776f49a1773b6737c6bd554b8bc8c6f",
"reference": "613e26310776f49a1773b6737c6bd554b8bc8c6f",
"url": "https://api.github.com/repos/symfony/finder/zipball/a479817ce0a9e4adfd7d39c6407c95d97c254625",
"reference": "a479817ce0a9e4adfd7d39c6407c95d97c254625",
"shasum": ""
},
"require": {
@ -3680,7 +3729,7 @@
],
"description": "Symfony Finder Component",
"homepage": "https://symfony.com",
"time": "2018-01-03T07:37:34+00:00"
"time": "2018-03-05T18:28:11+00:00"
},
{
"name": "symfony/polyfill-apcu",
@ -3799,16 +3848,16 @@
},
{
"name": "symfony/process",
"version": "v3.4.4",
"version": "v3.4.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
"reference": "09a5172057be8fc677840e591b17f385e58c7c0d"
"reference": "cc4aea21f619116aaf1c58016a944e4821c8e8af"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/process/zipball/09a5172057be8fc677840e591b17f385e58c7c0d",
"reference": "09a5172057be8fc677840e591b17f385e58c7c0d",
"url": "https://api.github.com/repos/symfony/process/zipball/cc4aea21f619116aaf1c58016a944e4821c8e8af",
"reference": "cc4aea21f619116aaf1c58016a944e4821c8e8af",
"shasum": ""
},
"require": {
@ -3844,20 +3893,20 @@
],
"description": "Symfony Process Component",
"homepage": "https://symfony.com",
"time": "2018-01-29T09:03:43+00:00"
"time": "2018-02-12T17:55:00+00:00"
},
{
"name": "symfony/yaml",
"version": "v3.4.4",
"version": "v3.4.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
"reference": "eab73b6c21d27ae4cd037c417618dfd4befb0bfe"
"reference": "6af42631dcf89e9c616242c900d6c52bd53bd1bb"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/yaml/zipball/eab73b6c21d27ae4cd037c417618dfd4befb0bfe",
"reference": "eab73b6c21d27ae4cd037c417618dfd4befb0bfe",
"url": "https://api.github.com/repos/symfony/yaml/zipball/6af42631dcf89e9c616242c900d6c52bd53bd1bb",
"reference": "6af42631dcf89e9c616242c900d6c52bd53bd1bb",
"shasum": ""
},
"require": {
@ -3902,7 +3951,7 @@
],
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com",
"time": "2018-01-21T19:05:02+00:00"
"time": "2018-02-16T09:50:28+00:00"
},
{
"name": "theseer/fdomdocument",
@ -4000,6 +4049,75 @@
"xunit"
],
"time": "2016-12-02T14:39:14+00:00"
},
{
"name": "symfony/var-dumper",
"version": "v3.4.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-dumper.git",
"reference": "80964679d81da3d5618519e0e4be488c3d7ecd7d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/80964679d81da3d5618519e0e4be488c3d7ecd7d",
"reference": "80964679d81da3d5618519e0e4be488c3d7ecd7d",
"shasum": ""
},
"require": {
"php": "^5.5.9|>=7.0.8",
"symfony/polyfill-mbstring": "~1.0"
},
"conflict": {
"phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0"
},
"require-dev": {
"ext-iconv": "*",
"twig/twig": "~1.34|~2.4"
},
"suggest": {
"ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).",
"ext-intl": "To show region name in time zone dump",
"ext-symfony_debug": ""
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.4-dev"
}
},
"autoload": {
"files": [
"Resources/functions/dump.php"
],
"psr-4": {
"Symfony\\Component\\VarDumper\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony mechanism for exploring and dumping PHP variables",
"homepage": "https://symfony.com",
"keywords": [
"debug",
"dump"
],
"time": "2018-02-22T17:29:24+00:00"
}
],
"aliases": [],

View file

@ -21,7 +21,7 @@
<rule ref="rulesets/naming.xml/ShortVariable">
<properties>
<property name="exceptions" value="db,dn,id,i,j" />
<property name="exceptions" value="db,dn,id,i,j,e,ex" />
</properties>
</rule>
<rule ref="rulesets/naming.xml/ShortMethodName">

View file

@ -20,44 +20,16 @@
<const name="POSTGRESQL_DBNAME" value="b8_test" />
</php>
<testsuites>
<testsuite name="B8Framework Test Suite">
<directory suffix="Test.php">./tests/B8Framework</directory>
</testsuite>
<testsuite name="PHP Censor Helper Test Suite">
<directory suffix="Test.php">./tests/PHPCensor/Helper</directory>
</testsuite>
<testsuite name="PHP Censor Controller Test Suite">
<directory suffix="Test.php">./tests/PHPCensor/Controller</directory>
</testsuite>
<testsuite name="PHP Censor Logging Test Suite">
<directory suffix="Test.php">./tests/PHPCensor/Logging</directory>
</testsuite>
<testsuite name="PHP Censor Model Test Suite">
<directory suffix="Test.php">./tests/PHPCensor/Model</directory>
</testsuite>
<testsuite name="PHP Censor Plugin Test Suite">
<directory suffix="Test.php">./tests/PHPCensor/Plugin</directory>
</testsuite>
<testsuite name="PHP Censor Service Test Suite">
<directory suffix="Test.php">./tests/PHPCensor/Service</directory>
</testsuite>
<testsuite name="PHP Censor Command Test Suite">
<directory suffix="Test.php">./tests/PHPCensor/Command</directory>
</testsuite>
<testsuite name="PHP Censor ProcessControl Test Suite">
<directory suffix="Test.php">./tests/PHPCensor/ProcessControl</directory>
</testsuite>
<testsuite name="PHP Censor Security Test Suite">
<directory suffix="Test.php">./tests/PHPCensor/Security</directory>
<testsuite name="PHP Common Test Suite">
<directory suffix="Test.php">./tests/src</directory>
</testsuite>
</testsuites>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">./src</directory>
<exclude>
<directory suffix=".php">./src/PHPCensor/Migrations</directory>
<directory suffix=".php">./src/PHPCensor/Languages</directory>
<directory suffix=".php">./src/Migrations</directory>
<directory suffix=".php">./src/Languages</directory>
</exclude>
</whitelist>
</filter>

View file

@ -4,5 +4,5 @@ session_start();
require_once(dirname(__DIR__) . '/bootstrap.php');
$fc = new PHPCensor\Application($config, new b8\Http\Request());
$fc = new PHPCensor\Application($config, new PHPCensor\Http\Request());
print $fc->handleRequest();

279
src/Application.php Normal file
View file

@ -0,0 +1,279 @@
<?php
namespace PHPCensor;
use PHPCensor\Exception\HttpException;
use PHPCensor\Http\Response;
use PHPCensor\Http\Response\RedirectResponse;
use PHPCensor\Store\Factory;
use PHPCensor\Exception\HttpException\NotFoundException;
use PHPCensor\Http\Request;
use PHPCensor\Http\Router;
/**
* @author Dan Cryer <dan@block8.co.uk>
*/
class Application
{
/**
* @var array
*/
protected $route;
/**
* @var Controller|WebController
*/
protected $controller;
/**
* @var Request
*/
protected $request;
/**
* @var Config
*/
protected $config;
/**
* @var Router
*/
protected $router;
/**
* @param Config $config
*
* @param Request|null $request
*/
public function __construct(Config $config, Request $request = null)
{
$this->config = $config;
if (!is_null($request)) {
$this->request = $request;
} else {
$this->request = new Request();
}
$this->router = new Router($this, $this->request, $this->config);
if (method_exists($this, 'init')) {
$this->init();
}
}
/**
* Initialise Application - Handles session verification, routing, etc.
*/
public function init()
{
$request =& $this->request;
$route = '/:controller/:action';
$opts = ['controller' => 'Home', 'action' => 'index'];
// Inlined as a closure to fix "using $this when not in object context" on 5.3
$validateSession = function () {
if (!empty($_SESSION['php-censor-user-id'])) {
$user = Factory::getStore('User')->getByPrimaryKey($_SESSION['php-censor-user-id']);
if ($user) {
return true;
}
}
return false;
};
$skipAuth = [$this, 'shouldSkipAuth'];
// Handler for the route we're about to register, checks for a valid session where necessary:
$routeHandler = function (&$route, Response &$response) use (&$request, $validateSession, $skipAuth) {
$skipValidation = in_array($route['controller'], ['session', 'webhook', 'build-status']);
if (!$skipValidation && !$validateSession() && (!is_callable($skipAuth) || !$skipAuth())) {
if ($request->isAjax()) {
$response->setResponseCode(401);
$response->setContent('');
} else {
$_SESSION['php-censor-login-redirect'] = substr($request->getPath(), 1);
$response = new RedirectResponse($response);
$response->setHeader('Location', APP_URL . 'session/login');
}
return false;
}
return true;
};
$this->router->clearRoutes();
$this->router->register($route, $opts, $routeHandler);
}
/**
* @return Response
*
* @throws NotFoundException
*/
protected function handleRequestInner()
{
$this->route = $this->router->dispatch();
if (!empty($this->route['callback'])) {
$callback = $this->route['callback'];
$response = new Response();
if (!$callback($this->route, $response)) {
return $response;
}
}
if (!$this->controllerExists($this->route)) {
throw new NotFoundException('Controller ' . $this->toPhpName($this->route['controller']) . ' does not exist!');
}
$action = lcfirst($this->toPhpName($this->route['action']));
if (!$this->getController()->hasAction($action)) {
throw new NotFoundException('Controller ' . $this->toPhpName($this->route['controller']) . ' does not have action ' . $action . '!');
}
return $this->getController()->handleAction($action, $this->route['args']);
}
/**
* Handle an incoming web request.
*
* @return Response
*/
public function handleRequest()
{
try {
$response = $this->handleRequestInner();
} catch (HttpException $ex) {
$this->config->set('page_title', 'Error');
$view = new View('exception');
$view->exception = $ex;
$response = new Response();
$response->setResponseCode($ex->getErrorCode());
$response->setContent($view->render());
} catch (\Exception $ex) {
$this->config->set('page_title', 'Error');
$view = new View('exception');
$view->exception = $ex;
$response = new Response();
$response->setResponseCode(500);
$response->setContent($view->render());
}
return $response;
}
/**
* Loads a particular controller, and injects our layout view into it.
*
* @param string $class
*
* @return Controller
*/
protected function loadController($class)
{
/** @var Controller $controller */
$controller = new $class($this->config, $this->request);
$controller->init();
return $controller;
}
/**
* Check whether we should skip auth (because it is disabled)
*
* @return boolean
*/
protected function shouldSkipAuth()
{
$config = Config::getInstance();
$disableAuth = (bool)$config->get('php-censor.security.disable_auth', false);
$defaultUserId = (integer)$config->get('php-censor.security.default_user_id', 1);
if ($disableAuth && $defaultUserId) {
$user = Factory::getStore('User')->getByPrimaryKey($defaultUserId);
if ($user) {
return true;
}
}
return false;
}
/**
* @return Controller
*/
public function getController()
{
if (empty($this->controller)) {
$controllerClass = $this->getControllerClass($this->route);
$this->controller = $this->loadController($controllerClass);
}
return $this->controller;
}
/**
* @param array $route
*
* @return bool
*/
protected function controllerExists($route)
{
return class_exists($this->getControllerClass($route));
}
/**
* @param array $route
*
* @return string
*/
protected function getControllerClass($route)
{
$namespace = $this->toPhpName($route['namespace']);
$controller = $this->toPhpName($route['controller']);
return 'PHPCensor\\' . $namespace . '\\' . $controller . 'Controller';
}
/**
* @param array $route
*
* @return boolean
*/
public function isValidRoute(array $route)
{
if ($this->controllerExists($route)) {
return true;
}
return false;
}
/**
* @param string $string
*
* @return string
*/
protected function toPhpName($string)
{
$string = str_replace('-', ' ', $string);
$string = ucwords($string);
$string = str_replace(' ', '', $string);
return $string;
}
}

View file

@ -1,171 +0,0 @@
<?php
namespace b8;
use b8\Exception\HttpException\NotFoundException;
use b8\Http\Response;
use b8\Http\Request;
use b8\Http\Router;
class Application
{
/**
* @var array
*/
protected $route;
/**
* @var Controller
*/
protected $controller;
/**
* @var Request
*/
protected $request;
/**
* @var Response
*/
protected $response;
/**
* @var Config
*/
protected $config;
/**
* @var Router
*/
protected $router;
/**
* @param Config $config
*
* @param Request|null $request
*/
public function __construct(Config $config, Request $request = null)
{
$this->config = $config;
$this->response = new Response();
if (!is_null($request)) {
$this->request = $request;
} else {
$this->request = new Request();
}
$this->router = new Router($this, $this->request, $this->config);
if (method_exists($this, 'init')) {
$this->init();
}
}
/**
* @return Response
*
* @throws NotFoundException
*/
public function handleRequest()
{
$this->route = $this->router->dispatch();
if (!empty($this->route['callback'])) {
$callback = $this->route['callback'];
if (!$callback($this->route, $this->response)) {
return $this->response;
}
}
if (!$this->controllerExists($this->route)) {
throw new NotFoundException('Controller ' . $this->toPhpName($this->route['controller']) . ' does not exist!');
}
$action = lcfirst($this->toPhpName($this->route['action']));
if (!$this->getController()->hasAction($action)) {
throw new NotFoundException('Controller ' . $this->toPhpName($this->route['controller']) . ' does not have action ' . $action . '!');
}
return $this->getController()->handleAction($action, $this->route['args']);
}
/**
* @return Controller
*/
public function getController()
{
if (empty($this->controller)) {
$controllerClass = $this->getControllerClass($this->route);
$this->controller = $this->loadController($controllerClass);
}
return $this->controller;
}
/**
* @param string $class
*
* @return Controller
*/
protected function loadController($class)
{
/** @var Controller $controller */
$controller = new $class($this->config, $this->request, $this->response);
$controller->init();
return $controller;
}
/**
* @param array $route
*
* @return bool
*/
protected function controllerExists($route)
{
return class_exists($this->getControllerClass($route));
}
/**
* @param array $route
*
* @return string
*/
protected function getControllerClass($route)
{
$namespace = $this->toPhpName($route['namespace']);
$controller = $this->toPhpName($route['controller']);
return $this->config->get('b8.app.namespace') . '\\' . $namespace . '\\' . $controller . 'Controller';
}
/**
* @param array $route
*
* @return boolean
*/
public function isValidRoute(array $route)
{
if ($this->controllerExists($route)) {
return true;
}
return false;
}
/**
* @param string $string
*
* @return string
*/
protected function toPhpName($string)
{
$string = str_replace('-', ' ', $string);
$string = ucwords($string);
$string = str_replace(' ', '', $string);
return $string;
}
}

View file

@ -1,9 +0,0 @@
<?php
namespace b8\Exception\HttpException;
use b8\Exception\HttpException;
class ServerErrorException extends HttpException
{
}

View file

@ -1,9 +0,0 @@
<?php
namespace b8\Form\Element;
use b8\Form\FieldSet;
class CheckboxGroup extends FieldSet
{
}

View file

@ -1,38 +0,0 @@
<?php
namespace b8\Form\Element;
use PHPCensor\View;
class Csrf extends Hidden
{
/**
* @var integer
*/
protected $rows = 4;
/**
* @return boolean
*/
public function validate()
{
if ($this->value != $_COOKIE[$this->getName()]) {
return false;
}
return true;
}
/**
* @param View $view
*/
protected function onPreRender(View &$view)
{
parent::onPreRender($view);
$csrf = md5(microtime(true));
$view->csrf = $csrf;
setcookie($this->getName(), $csrf);
}
}

View file

@ -1,9 +0,0 @@
<?php
namespace b8\Form\Element;
use b8\Form\Input;
class Hidden extends Input
{
}

View file

@ -1,194 +0,0 @@
<?php
namespace b8;
use b8\Exception\HttpException;
use Symfony\Component\Cache\Simple\ArrayCache;
class Model
{
protected $getters = [];
protected $setters = [];
protected $data = [];
protected $modified = [];
protected $tableName;
protected $cache;
/**
* @param array $initialData
*/
public function __construct($initialData = [])
{
if (is_array($initialData)) {
$this->data = array_merge($this->data, $initialData);
}
$this->cache = new ArrayCache();
}
/**
* @return string
*/
public function getTableName()
{
return $this->tableName;
}
/**
* @return array
*/
public function getDataArray()
{
return $this->data;
}
/**
* @return array
*/
public function getModified()
{
return $this->modified;
}
/**
* @param array $values
*/
public function setValues(array $values)
{
foreach ($values as $key => $value) {
if (isset($this->setters[$key])) {
$func = $this->setters[$key];
if ($value === 'null') {
$value = null;
} elseif ($value === 'true') {
$value = true;
} elseif ($value === 'false') {
$value = false;
}
$this->{$func}($value);
}
}
}
/**
* @param string $column
*/
protected function setModified($column)
{
$this->modified[$column] = $column;
}
/**
* @param string $name
* @param mixed $value
*
* @throws HttpException\ValidationException
*/
protected function validateString($name, $value)
{
if (!is_string($value) && !is_null($value)) {
throw new HttpException\ValidationException('Column "', $name . '" must be a string.');
}
}
/**
* @param string $name
* @param mixed $value
*
* @throws HttpException\ValidationException
*/
protected function validateInt($name, &$value)
{
if (is_bool($value)) {
$value = $value ? 1 : 0;
}
if (!is_numeric($value) && !is_null($value)) {
throw new HttpException\ValidationException('Column "', $name . '" must be an integer.');
}
if (!is_int($value) && !is_null($value)) {
$value = (int)$value;
}
}
/**
* @param string $name
* @param mixed $value
*
* @throws HttpException\ValidationException
*/
protected function validateFloat($name, &$value)
{
if (!is_numeric($value) && !is_null($value)) {
throw new HttpException\ValidationException('Column "', $name . '" must be a float.');
}
if (!is_float($value) && !is_null($value)) {
$value = (float)$value;
}
}
/**
* @param string $name
* @param mixed $value
*
* @throws HttpException\ValidationException
*/
protected function validateDate($name, &$value)
{
if (is_string($value)) {
$value = empty($value) ? null : new \DateTime($value);
}
if ((!is_object($value) || !($value instanceof \DateTime)) && !is_null($value)) {
throw new HttpException\ValidationException('Column "', $name . '" must be a date object.');
}
$value = empty($value) ? null : $value->format('Y-m-d H:i:s');
}
/**
* @param string $name
* @param mixed $value
*
* @throws HttpException\ValidationException
*/
protected function validateNotNull($name, $value)
{
if (is_null($value)) {
throw new HttpException\ValidationException('Column "', $name . '" must not be null.');
}
}
/**
* @param string $key
*
* @return mixed
*/
public function __get($key)
{
if (array_key_exists($key, $this->getters)) {
$getter = $this->getters[$key];
return $this->{$getter}();
}
return null;
}
/**
* @param string $key
* @param mixed $value
*
* @return mixed
*/
public function __set($key, $value)
{
if (array_key_exists($key, $this->setters)) {
$setter = $this->setters[$key];
return $this->{$setter}($value);
}
}
}

View file

@ -2,7 +2,8 @@
namespace PHPCensor;
use b8\Store\Factory;
use PHPCensor\Model\Project;
use PHPCensor\Store\Factory;
use PHPCensor\Model\Build;
/**
@ -41,31 +42,31 @@ class BuildFactory
if (!empty($project)) {
switch ($project->getType()) {
case 'local':
case Project::TYPE_LOCAL:
$type = 'LocalBuild';
break;
case 'git':
case Project::TYPE_GIT:
$type = 'GitBuild';
break;
case 'github':
case Project::TYPE_GITHUB:
$type = 'GithubBuild';
break;
case 'bitbucket':
case Project::TYPE_BITBUCKET:
$type = 'BitbucketBuild';
break;
case 'gitlab':
case Project::TYPE_GITLAB:
$type = 'GitlabBuild';
break;
case 'gogs':
case Project::TYPE_GOGS:
$type = 'GogsBuild';
break;
case 'hg':
case Project::TYPE_HG:
$type = 'HgBuild';
break;
case 'bitbucket-hg':
case Project::TYPE_BITBUCKET_HG:
$type = 'BitbucketHgBuild';
break;
case 'svn':
case Project::TYPE_SVN:
$type = 'SvnBuild';
break;
default:

View file

@ -6,8 +6,7 @@ use PHPCensor\Helper\BuildInterpolator;
use PHPCensor\Helper\MailerFactory;
use PHPCensor\Logging\BuildLogger;
use PHPCensor\Model\Build;
use b8\Config;
use b8\Store\Factory;
use PHPCensor\Store\Factory;
use PHPCensor\Store\BuildErrorWriter;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerInterface;
@ -103,7 +102,7 @@ class Builder implements LoggerAwareInterface
public function __construct(Build $build, LoggerInterface $logger = null)
{
$this->build = $build;
$this->store = Factory::getStore('Build', 'PHPCensor');
$this->store = Factory::getStore('Build');
$this->buildLogger = new BuildLogger($logger, $build);
$pluginFactory = $this->buildPluginFactory($build);
@ -196,12 +195,11 @@ class Builder implements LoggerAwareInterface
$this->build->sendStatusPostback();
$success = true;
$previous_build = $this->build->getProject()->getPreviousBuild($this->build->getBranch());
$previousBuild = $this->build->getProject()->getPreviousBuild($this->build->getBranch());
$previousState = Build::STATUS_PENDING;
$previous_state = Build::STATUS_PENDING;
if ($previous_build) {
$previous_state = $previous_build->getStatus();
if ($previousBuild) {
$previousState = $previousBuild->getStatus();
}
try {
@ -233,13 +231,13 @@ class Builder implements LoggerAwareInterface
if ($success) {
$this->pluginExecutor->executePlugins($this->config, Build::STAGE_SUCCESS);
if ($previous_state == Build::STATUS_FAILED) {
if ($previousState == Build::STATUS_FAILED) {
$this->pluginExecutor->executePlugins($this->config, Build::STAGE_FIXED);
}
} else {
$this->pluginExecutor->executePlugins($this->config, Build::STAGE_FAILURE);
if ($previous_state == Build::STATUS_SUCCESS || $previous_state == Build::STATUS_PENDING) {
if ($previousState == Build::STATUS_SUCCESS || $previousState == Build::STATUS_PENDING) {
$this->pluginExecutor->executePlugins($this->config, Build::STAGE_BROKEN);
}
}
@ -278,11 +276,13 @@ class Builder implements LoggerAwareInterface
/**
* Used by this class, and plugins, to execute shell commands.
*
* @param array ...$params
*
* @return boolean
*/
public function executeCommand()
public function executeCommand(...$params)
{
return $this->commandExecutor->executeCommand(func_get_args());
return $this->commandExecutor->executeCommand($params);
}
/**

View file

@ -85,7 +85,7 @@ class CreateAdminCommand extends Command
try {
$userService = new UserService($this->userStore);
$userService->createUser($adminName, $adminEmail, 'internal', json_encode(['type' => 'internal']), $adminPassword, true);
$userService->createUser($adminName, $adminEmail, 'internal', ['type' => 'internal'], $adminPassword, true);
$output->writeln('<info>User account created!</info>');
} catch (\Exception $ex) {

View file

@ -5,8 +5,8 @@ namespace PHPCensor\Command;
use Exception;
use PDO;
use b8\Config;
use b8\Store\Factory;
use PHPCensor\Config;
use PHPCensor\Store\Factory;
use PHPCensor\Model\ProjectGroup;
use PHPCensor\Store\UserStore;
use PHPCensor\Store\ProjectGroupStore;
@ -520,7 +520,7 @@ class InstallCommand extends Command
}
$userService = new UserService($userStore);
$userService->createUser($admin['name'], $admin['email'], 'internal', json_encode(['type' => 'internal']), $admin['password'], true);
$userService->createUser($admin['name'], $admin['email'], 'internal', ['type' => 'internal'], $admin['password'], true);
$output->writeln('<info>User account created!</info>');
} catch (\Exception $ex) {

View file

@ -2,7 +2,7 @@
namespace PHPCensor\Command;
use b8\Store\Factory;
use PHPCensor\Store\Factory;
use Monolog\Logger;
use PHPCensor\Service\BuildService;
use Symfony\Component\Console\Command\Command;
@ -12,7 +12,7 @@ use Symfony\Component\Console\Output\OutputInterface;
/**
* Re-runs the last run build.
*
*
* @author Dan Cryer <dan@block8.co.uk>
*/
class RebuildCommand extends Command

View file

@ -2,7 +2,7 @@
namespace PHPCensor\Command;
use b8\Store\Factory;
use PHPCensor\Store\Factory;
use Monolog\Logger;
use PHPCensor\BuildFactory;
use PHPCensor\Logging\OutputLogHandler;
@ -55,7 +55,7 @@ class RebuildQueueCommand extends Command
);
}
$store = Factory::getStore('Build');
$store = Factory::getStore('Build');
$result = $store->getByStatus(0);
$this->logger->addInfo(sprintf('Found %d builds', count($result['items'])));

View file

@ -2,7 +2,7 @@
namespace PHPCensor\Command;
use b8\Config;
use PHPCensor\Config;
use Monolog\Logger;
use PHPCensor\Logging\BuildDBLogHandler;
use PHPCensor\Logging\LoggedBuildContextTidier;
@ -11,7 +11,7 @@ use PHPCensor\Store\BuildStore;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use b8\Store\Factory;
use PHPCensor\Store\Factory;
use PHPCensor\Builder;
use PHPCensor\BuildFactory;
use PHPCensor\Model\Build;

View file

@ -2,7 +2,7 @@
namespace PHPCensor\Command;
use b8\Config;
use PHPCensor\Config;
use Monolog\Logger;
use PHPCensor\Logging\OutputLogHandler;
use PHPCensor\Worker\BuildWorker;

View file

@ -1,13 +1,9 @@
<?php
namespace b8;
namespace PHPCensor;
use Symfony\Component\Yaml\Parser as YamlParser;
if (!defined('B8_PATH')) {
define('B8_PATH', __DIR__ . '/');
}
class Config
{
/**
@ -75,8 +71,8 @@ class Config
$keyParts = explode('.', $key);
$selected = $this->config;
$i = -1;
$last_part = count($keyParts) - 1;
$i = -1;
$lastPart = count($keyParts) - 1;
while ($part = array_shift($keyParts)) {
$i++;
@ -84,7 +80,7 @@ class Config
return $default;
}
if ($i === $last_part) {
if ($i === $lastPart) {
return $selected[$part];
} else {
$selected = $selected[$part];
@ -181,25 +177,25 @@ class Config
return;
}
foreach ($target as $target_key => $target_value) {
if (isset($source[$target_key])) {
if (!is_array($source[$target_key]) && !is_array($target_value)) {
foreach ($target as $targetKey => $targetValue) {
if (isset($source[$targetKey])) {
if (!is_array($source[$targetKey]) && !is_array($targetValue)) {
// Neither value is an array, overwrite
$source[$target_key] = $target_value;
} elseif (is_array($source[$target_key]) && is_array($target_value)) {
$source[$targetKey] = $targetValue;
} elseif (is_array($source[$targetKey]) && is_array($targetValue)) {
// Both are arrays, deep merge them
self::deepMerge($source[$target_key], $target_value);
} elseif (is_array($source[$target_key])) {
self::deepMerge($source[$targetKey], $targetValue);
} elseif (is_array($source[$targetKey])) {
// Source is the array, push target value
$source[$target_key][] = $target_value;
$source[$targetKey][] = $targetValue;
} else {
// Target is the array, push source value and copy back
$target_value[] = $source[$target_key];
$source[$target_key] = $target_value;
$targetValue[] = $source[$targetKey];
$source[$targetKey] = $targetValue;
}
} else {
// No merge required, just set the value
$source[$target_key] = $target_value;
$source[$targetKey] = $targetValue;
}
}
}

View file

@ -2,8 +2,8 @@
namespace PHPCensor\Console;
use b8\Config;
use b8\Store\Factory;
use PHPCensor\Config;
use PHPCensor\Store\Factory;
use Monolog\Handler\RotatingFileHandler;
use Monolog\Handler\StreamHandler;
use Monolog\Logger;
@ -86,7 +86,7 @@ LOGO;
if ($databaseSettings) {
$phinxSettings = [
'paths' => [
'migrations' => ROOT_DIR . 'src/PHPCensor/Migrations',
'migrations' => ROOT_DIR . 'src/Migrations',
],
'environments' => [
'default_migration_table' => 'migration',

View file

@ -1,9 +1,9 @@
<?php
namespace b8;
namespace PHPCensor;
use b8\Http\Request;
use b8\Http\Response;
use PHPCensor\Http\Request;
use PHPCensor\Http\Response;
abstract class Controller
{
@ -12,38 +12,26 @@ abstract class Controller
*/
protected $request;
/**
* @var Response
*/
protected $response;
/**
* @var Config
*/
protected $config;
/**
* @var View
* @param Config $config
* @param Request $request
*/
protected $controllerView;
/**
* @var View
*/
protected $view;
/**
* @param Config $config
* @param Request $request
* @param Response $response
*/
public function __construct(Config $config, Request $request, Response $response)
public function __construct(Config $config, Request $request)
{
$this->config = $config;
$this->request = $request;
$this->response = $response;
}
/**
* Initialise the controller.
*/
abstract public function init();
/**
* @param string $name
*
@ -75,11 +63,6 @@ abstract class Controller
return call_user_func_array([$this, $action], $actionParams);
}
/**
* Initialise the controller.
*/
abstract public function init();
/**
* Get a hash of incoming request parameters ($_GET, $_POST)
*

View file

@ -2,27 +2,32 @@
namespace PHPCensor\Controller;
use b8;
use b8\Exception\HttpException\NotFoundException;
use b8\Http\Response\JsonResponse;
use PHPCensor\Exception\HttpException\NotFoundException;
use PHPCensor\Http\Response\JsonResponse;
use JasonGrimes\Paginator;
use PHPCensor\BuildFactory;
use PHPCensor\Helper\AnsiConverter;
use PHPCensor\Helper\Lang;
use PHPCensor\Http\Response\RedirectResponse;
use PHPCensor\Model\Build;
use PHPCensor\Model\Project;
use PHPCensor\Model\User;
use PHPCensor\Service\BuildService;
use PHPCensor\Controller;
use PHPCensor\WebController;
use PHPCensor\View;
use PHPCensor\Store\Factory;
/**
* Build Controller - Allows users to run and view builds.
*
* @author Dan Cryer <dan@block8.co.uk>
*/
class BuildController extends Controller
class BuildController extends WebController
{
/**
* @var string
*/
public $layoutName = 'layout';
/**
* @var \PHPCensor\Store\BuildStore
*/
@ -33,12 +38,11 @@ class BuildController extends Controller
*/
protected $buildService;
/**
* Initialise the controller, set up stores and services.
*/
public function init()
{
$this->buildStore = b8\Store\Factory::getStore('Build');
parent::init();
$this->buildStore = Factory::getStore('Build');
$this->buildService = new BuildService($this->buildStore);
}
@ -81,7 +85,7 @@ class BuildController extends Controller
}
/** @var \PHPCensor\Store\BuildErrorStore $errorStore */
$errorStore = b8\Store\Factory::getStore('BuildError');
$errorStore = Factory::getStore('BuildError');
$this->view->uiPlugins = $this->getUiPlugins();
$this->view->build = $build;
@ -119,13 +123,13 @@ class BuildController extends Controller
break;
}
$rebuild = Lang::get('rebuild_now');
$rebuild = Lang::get('rebuild_now');
$rebuildLink = APP_URL . 'build/rebuild/' . $build->getId();
$delete = Lang::get('delete_build');
$delete = Lang::get('delete_build');
$deleteLink = APP_URL . 'build/delete/' . $build->getId();
$project = b8\Store\Factory::getStore('Project')->getByPrimaryKey($build->getProjectId());
$project = Factory::getStore('Project')->getByPrimaryKey($build->getProjectId());
$actions = '';
if (!$project->getArchived()) {
@ -146,7 +150,7 @@ class BuildController extends Controller
protected function getUiPlugins()
{
$rtn = [];
$path = PUBLIC_DIR . 'assets' . DIRECTORY_SEPARATOR . 'js' . DIRECTORY_SEPARATOR . 'build-plugins' . DIRECTORY_SEPARATOR;
$path = PUBLIC_DIR . 'assets/js/build-plugins/';
$dir = opendir($path);
while ($item = readdir($dir)) {
@ -183,7 +187,7 @@ class BuildController extends Controller
$data['duration'] = $build->getDuration();
/** @var \PHPCensor\Store\BuildErrorStore $errorStore */
$errorStore = b8\Store\Factory::getStore('BuildError');
$errorStore = Factory::getStore('BuildError');
$errors = $errorStore->getByBuildId($build->getId(), $perPage, $start, $plugin, $severity, $isNew);
$errorView = new View('Build/errors');
@ -240,7 +244,7 @@ class BuildController extends Controller
public function rebuild($buildId)
{
$copy = BuildFactory::getBuildById($buildId);
$project = b8\Store\Factory::getStore('Project')->getByPrimaryKey($copy->getProjectId());
$project = Factory::getStore('Project')->getByPrimaryKey($copy->getProjectId());
if (!$copy || $project->getArchived()) {
throw new NotFoundException(Lang::get('build_x_not_found', $buildId));
@ -252,7 +256,7 @@ class BuildController extends Controller
$_SESSION['global_error'] = Lang::get('add_to_queue_failed');
}
$response = new b8\Http\Response\RedirectResponse();
$response = new RedirectResponse();
$response->setHeader('Location', APP_URL.'build/view/' . $build->getId());
return $response;
@ -273,7 +277,7 @@ class BuildController extends Controller
$this->buildService->deleteBuild($build);
$response = new b8\Http\Response\RedirectResponse();
$response = new RedirectResponse();
$response->setHeader('Location', APP_URL.'project/view/' . $build->getProjectId());
return $response;

View file

@ -2,37 +2,44 @@
namespace PHPCensor\Controller;
use b8;
use b8\Exception\HttpException\NotFoundException;
use b8\Store;
use PHPCensor\Http\Response;
use PHPCensor\Http\Response\RedirectResponse;
use PHPCensor\Exception\HttpException\NotFoundException;
use PHPCensor\Store\Factory;
use PHPCensor\BuildFactory;
use PHPCensor\Model\Project;
use PHPCensor\Model\Build;
use PHPCensor\Service\BuildStatusService;
use PHPCensor\Controller;
use PHPCensor\WebController;
/**
* Build Status Controller - Allows external access to build status information / images.
*
* @author Dan Cryer <dan@block8.co.uk>
*/
class BuildStatusController extends Controller
class BuildStatusController extends WebController
{
/* @var \PHPCensor\Store\ProjectStore */
protected $projectStore;
/* @var \PHPCensor\Store\BuildStore */
protected $buildStore;
/**
* @var string
*/
public $layoutName = 'layoutPublic';
/**
* Initialise the controller, set up stores and services.
* @var \PHPCensor\Store\ProjectStore
*/
protected $projectStore;
/**
* @var \PHPCensor\Store\BuildStore
*/
protected $buildStore;
public function init()
{
$this->response->disableLayout();
parent::init();
$this->buildStore = Store\Factory::getStore('Build');
$this->projectStore = Store\Factory::getStore('Project');
$this->buildStore = Factory::getStore('Build');
$this->projectStore = Factory::getStore('Project');
}
/**
@ -73,16 +80,15 @@ class BuildStatusController extends Controller
*
* @param $projectId
*
* @return bool
* @return Response
*
* @throws \Exception
* @throws b8\Exception\HttpException
*/
public function ccxml($projectId)
{
/* @var Project $project */
$project = $this->projectStore->getById($projectId);
$xml = new \SimpleXMLElement('<Projects/>');
$xml = new \SimpleXMLElement('<Projects/>');
if (!$project instanceof Project || !$project->getAllowPublicStatus()) {
return $this->renderXml($xml);
@ -114,16 +120,16 @@ class BuildStatusController extends Controller
/**
* @param \SimpleXMLElement $xml
*
* @return boolean
* @return Response
*/
protected function renderXml(\SimpleXMLElement $xml = null)
{
$this->response->setHeader('Content-Type', 'text/xml');
$this->response->setContent($xml->asXML());
$this->response->flush();
echo $xml->asXML();
$response = new Response();
return true;
$response->setHeader('Content-Type', 'text/xml');
$response->setContent($xml->asXML());
return $response;
}
/**
@ -131,7 +137,7 @@ class BuildStatusController extends Controller
*
* @param $projectId
*
* @return b8\Http\Response|b8\Http\Response\RedirectResponse
* @return Response
*/
public function image($projectId)
{
@ -149,7 +155,7 @@ class BuildStatusController extends Controller
$status = $this->getStatus($projectId);
if (is_null($status)) {
$response = new b8\Http\Response\RedirectResponse();
$response = new RedirectResponse();
$response->setHeader('Location', '/');
return $response;
@ -179,10 +185,12 @@ class BuildStatusController extends Controller
$image = file_get_contents($cacheFile);
$this->response->disableLayout();
$this->response->setHeader('Content-Type', 'image/svg+xml');
$this->response->setContent($image);
return $this->response;
$response = new Response();
$response->setHeader('Content-Type', 'image/svg+xml');
$response->setContent($image);
return $response;
}
/**
@ -192,7 +200,7 @@ class BuildStatusController extends Controller
*
* @return string
*
* @throws \b8\Exception\HttpException\NotFoundException
* @throws NotFoundException
*/
public function view($projectId)
{

View file

@ -2,31 +2,36 @@
namespace PHPCensor\Controller;
use b8;
use b8\Form;
use PHPCensor\Controller;
use PHPCensor\Form;
use PHPCensor\WebController;
use PHPCensor\Http\Response\RedirectResponse;
use PHPCensor\Model\ProjectGroup;
use PHPCensor\Helper\Lang;
use PHPCensor\Model\User;
use PHPCensor\Store\Factory;
/**
* Project Controller - Allows users to create, edit and view projects.
*
* @author Dan Cryer <dan@block8.co.uk>
*/
class GroupController extends Controller
class GroupController extends WebController
{
/**
* @var string
*/
public $layoutName = 'layout';
/**
* @var \PHPCensor\Store\ProjectGroupStore
*/
protected $groupStore;
/**
* Set up this controller.
*/
public function init()
{
$this->groupStore = b8\Store\Factory::getStore('ProjectGroup');
parent::init();
$this->groupStore = Factory::getStore('ProjectGroup');
}
/**
@ -44,10 +49,10 @@ class GroupController extends Controller
'title' => $group->getTitle(),
'id' => $group->getId(),
];
$projects_active = b8\Store\Factory::getStore('Project')->getByGroupId($group->getId(), false);
$projects_archived = b8\Store\Factory::getStore('Project')->getByGroupId($group->getId(), true);
$projectsActive = Factory::getStore('Project')->getByGroupId($group->getId(), false);
$projectsArchived = Factory::getStore('Project')->getByGroupId($group->getId(), true);
$thisGroup['projects'] = array_merge($projects_active['items'], $projects_archived['items']);
$thisGroup['projects'] = array_merge($projectsActive['items'], $projectsArchived['items']);
$groups[] = $thisGroup;
}
@ -57,8 +62,10 @@ class GroupController extends Controller
/**
* Add or edit a project group.
*
* @param null $groupId
* @return void|b8\Http\Response\RedirectResponse
*
* @return RedirectResponse
*/
public function edit($groupId = null)
{
@ -82,16 +89,19 @@ class GroupController extends Controller
$this->groupStore->save($group);
$response = new b8\Http\Response\RedirectResponse();
$response = new RedirectResponse();
$response->setHeader('Location', APP_URL.'group');
return $response;
}
$form = new Form();
$form->setMethod('POST');
$form->setAction(APP_URL . 'group/edit' . (!is_null($groupId) ? '/' . $groupId : ''));
$form->addField(new Form\Element\Csrf('group_form'));
$title = new Form\Element\Text('title');
$title->setContainerClass('form-group');
$title->setClass('form-control');
@ -111,7 +121,7 @@ class GroupController extends Controller
/**
* Delete a project group.
* @param $groupId
* @return b8\Http\Response\RedirectResponse
* @return RedirectResponse
*/
public function delete($groupId)
{
@ -119,7 +129,7 @@ class GroupController extends Controller
$group = $this->groupStore->getById($groupId);
$this->groupStore->delete($group);
$response = new b8\Http\Response\RedirectResponse();
$response = new RedirectResponse();
$response->setHeader('Location', APP_URL.'group');
return $response;
}

View file

@ -2,15 +2,20 @@
namespace PHPCensor\Controller;
use b8;
use PHPCensor\Config;
use PHPCensor\Helper\Lang;
use PHPCensor\Controller;
use PHPCensor\WebController;
/**
* Home Controller - Displays the Dashboard.
*/
class HomeController extends Controller
class HomeController extends WebController
{
/**
* @var string
*/
public $layoutName = 'layout';
/**
* Display dashboard:
*/
@ -19,10 +24,11 @@ class HomeController extends Controller
$this->layout->title = Lang::get('dashboard');
$widgets = [
'left' => [],
'left' => [],
'right' => [],
];
$widgets_config = b8\Config::getInstance()->get('php-censor.dashboard_widgets', [
$widgetsConfig = Config::getInstance()->get('php-censor.dashboard_widgets', [
'all_projects' => [
'side' => 'left',
],
@ -30,8 +36,11 @@ class HomeController extends Controller
'side' => 'right',
],
]);
foreach($widgets_config as $name => $params) {
$side = (isset($params['side']) and ($params['side'] == 'right')) ? 'right' : 'left';
foreach($widgetsConfig as $name => $params) {
$side = (isset($params['side']) && 'right' === $params['side'])
? 'right'
: 'left';
$widgets[$side][$name] = $params;
}

View file

@ -2,10 +2,8 @@
namespace PHPCensor\Controller;
use b8;
use b8\Exception\HttpException\NotFoundException;
use b8\Form;
use b8\Store;
use PHPCensor\Exception\HttpException\NotFoundException;
use PHPCensor\Form;
use JasonGrimes\Paginator;
use PHPCensor;
use PHPCensor\BuildFactory;
@ -15,16 +13,24 @@ use PHPCensor\Helper\SshKey;
use PHPCensor\Service\BuildService;
use PHPCensor\Service\ProjectService;
use PHPCensor\Model\Build;
use b8\Http\Response\RedirectResponse;
use PHPCensor\Http\Response\RedirectResponse;
use PHPCensor\View;
use PHPCensor\Store\Factory;
use PHPCensor\Model\Project;
use PHPCensor\WebController;
/**
* Project Controller - Allows users to create, edit and view projects.
*
* @author Dan Cryer <dan@block8.co.uk>
*/
class ProjectController extends PHPCensor\Controller
class ProjectController extends WebController
{
/**
* @var string
*/
public $layoutName = 'layout';
/**
* @var \PHPCensor\Store\ProjectStore
*/
@ -50,8 +56,10 @@ class ProjectController extends PHPCensor\Controller
*/
public function init()
{
$this->buildStore = Store\Factory::getStore('Build');
$this->projectStore = Store\Factory::getStore('Project');
parent::init();
$this->buildStore = Factory::getStore('Build');
$this->projectStore = Factory::getStore('Project');
$this->projectService = new ProjectService($this->projectStore);
$this->buildService = new BuildService($this->buildStore);
}
@ -59,7 +67,7 @@ class ProjectController extends PHPCensor\Controller
/**
* @param int $projectId
*
* @return b8\Http\Response
* @return PHPCensor\Http\Response
*/
public function ajaxBuilds($projectId)
{
@ -69,10 +77,10 @@ class ProjectController extends PHPCensor\Controller
$perPage = (integer)$this->getParam('per_page', 10);
$builds = $this->getLatestBuildsHtml($projectId, $branch, $environment, (($page - 1) * $perPage), $perPage);
$this->response->disableLayout();
$this->response->setContent($builds[0]);
$response = new PHPCensor\Http\Response();
$response->setContent($builds[0]);
return $this->response;
return $response;
}
/**
@ -327,10 +335,10 @@ class ProjectController extends PHPCensor\Controller
'ssh_private_key' => $this->getParam('key', null),
'ssh_public_key' => $this->getParam('pubkey', null),
'build_config' => $this->getParam('build_config', null),
'allow_public_status' => $this->getParam('allow_public_status', 0),
'allow_public_status' => (boolean)$this->getParam('allow_public_status', 0),
'branch' => $this->getParam('branch', null),
'default_branch_only' => $this->getParam('default_branch_only', 0),
'group' => $this->getParam('group_id', null),
'default_branch_only' => (boolean)$this->getParam('default_branch_only', 0),
'group' => (integer)$this->getParam('group_id', null),
'environments' => $this->getParam('environments', null),
];
@ -380,11 +388,11 @@ class ProjectController extends PHPCensor\Controller
$form = $this->projectForm($values, 'edit/' . $projectId);
if ($method != 'POST' || ($method == 'POST' && !$form->validate())) {
$view = new View('Project/edit');
$view->type = 'edit';
$view->project = $project;
$view->form = $form;
$view->key = $values['pubkey'];
$view = new View('Project/edit');
$view->type = 'edit';
$view->project = $project;
$view->form = $form;
$view->key = $values['pubkey'];
return $view->render();
}
@ -397,11 +405,11 @@ class ProjectController extends PHPCensor\Controller
'ssh_private_key' => $this->getParam('key', null),
'ssh_public_key' => $this->getParam('pubkey', null),
'build_config' => $this->getParam('build_config', null),
'allow_public_status' => $this->getParam('allow_public_status', 0),
'archived' => $this->getParam('archived', 0),
'allow_public_status' => (boolean)$this->getParam('allow_public_status', false),
'archived' => (boolean)$this->getParam('archived', false),
'branch' => $this->getParam('branch', null),
'default_branch_only' => $this->getParam('default_branch_only', 0),
'group' => $this->getParam('group_id', null),
'default_branch_only' => (boolean)$this->getParam('default_branch_only', false),
'group' => (integer)$this->getParam('group_id', null),
'environments' => $this->getParam('environments', null),
];
@ -421,22 +429,22 @@ class ProjectController extends PHPCensor\Controller
$form = new Form();
$form->setMethod('POST');
$form->setAction(APP_URL.'project/' . $type);
$form->setAction(APP_URL . 'project/' . $type);
$form->addField(new Form\Element\Csrf('csrf'));
$form->addField(new Form\Element\Csrf('project_form'));
$form->addField(new Form\Element\Hidden('pubkey'));
$options = [
'choose' => Lang::get('select_repository_type'),
'github' => 'GitHub',
'bitbucket' => 'Bitbucket (Git)',
'bitbucket-hg' => 'Bitbucket (Hg)',
'gitlab' => 'GitLab',
'gogs' => 'Gogs',
'git' => 'Git',
'local' => Lang::get('local'),
'hg' => 'Hg (Mercurial)',
'svn' => 'Svn (Subversion)',
'choose' => Lang::get('select_repository_type'),
Project::TYPE_GITHUB => 'GitHub',
Project::TYPE_BITBUCKET => 'Bitbucket (Git)',
Project::TYPE_BITBUCKET_HG => 'Bitbucket (Hg)',
Project::TYPE_GITLAB => 'GitLab',
Project::TYPE_GOGS => 'Gogs',
Project::TYPE_GIT => 'Git',
Project::TYPE_LOCAL => Lang::get('local'),
Project::TYPE_HG => 'Hg (Mercurial)',
Project::TYPE_SVN => 'Svn (Subversion)',
];
$field = Form\Element\Select::create('type', Lang::get('where_hosted'), true);
@ -495,7 +503,7 @@ class ProjectController extends PHPCensor\Controller
$field->setClass('form-control')->setContainerClass('form-group')->setValue(1);
$groups = [];
$groupStore = b8\Store\Factory::getStore('ProjectGroup');
$groupStore = Factory::getStore('ProjectGroup');
$groupList = $groupStore->getWhere([], 100, 0, ['title' => 'ASC']);
foreach ($groupList['items'] as $group) {
@ -567,7 +575,7 @@ class ProjectController extends PHPCensor\Controller
if (in_array($type, $validators) && !preg_match($validators[$type]['regex'], $val)) {
throw new \Exception($validators[$type]['message']);
} elseif ($type == 'local' && !is_dir($val)) {
} elseif (Project::TYPE_LOCAL === $type && !is_dir($val)) {
throw new \Exception(Lang::get('error_path'));
}
@ -582,7 +590,7 @@ class ProjectController extends PHPCensor\Controller
{
$github = new Github();
$response = new b8\Http\Response\JsonResponse();
$response = new PHPCensor\Http\Response\JsonResponse();
$response->setContent($github->getRepositories());
return $response;

View file

@ -2,20 +2,27 @@
namespace PHPCensor\Controller;
use b8;
use PHPCensor\Form\Element\Csrf;
use PHPCensor\Helper\Email;
use PHPCensor\Helper\Lang;
use PHPCensor\Controller;
use PHPCensor\WebController;
use PHPCensor\Http\Response\RedirectResponse;
use PHPCensor\Security\Authentication\Service;
use PHPCensor\Store\UserStore;
use PHPCensor\Store\Factory;
/**
* Session Controller - Handles user login / logout.
*
* @author Dan Cryer <dan@block8.co.uk>
*/
class SessionController extends Controller
class SessionController extends WebController
{
/**
* @var string
*/
public $layoutName = 'layoutSession';
/**
* @var UserStore
*/
@ -31,12 +38,50 @@ class SessionController extends Controller
*/
public function init()
{
$this->response->disableLayout();
parent::init();
$this->userStore = b8\Store\Factory::getStore('User');
$this->userStore = Factory::getStore('User');
$this->authentication = Service::getInstance();
}
protected function loginForm($values)
{
$form = new \PHPCensor\Form();
$form->setMethod('POST');
$form->setAction(APP_URL . 'session/login');
$form->addField(new Csrf('login_form'));
$email = new \PHPCensor\Form\Element\Text('email');
$email->setLabel(Lang::get('login'));
$email->setRequired(true);
$email->setContainerClass('form-group');
$email->setClass('form-control');
$form->addField($email);
$pwd = new \PHPCensor\Form\Element\Password('password');
$pwd->setLabel(Lang::get('password'));
$pwd->setRequired(true);
$pwd->setContainerClass('form-group');
$pwd->setClass('form-control');
$form->addField($pwd);
$remember = \PHPCensor\Form\Element\Checkbox::create('remember_me', Lang::get('remember_me'), false);
$remember->setContainerClass('form-group');
$remember->setCheckedValue(1);
$remember->setValue(0);
$form->addField($remember);
$pwd = new \PHPCensor\Form\Element\Submit();
$pwd->setValue(Lang::get('log_in'));
$pwd->setClass('btn-success');
$form->addField($pwd);
$form->setValues($values);
return $form;
}
/**
* Handles user login (form and processing)
*/
@ -47,22 +92,29 @@ class SessionController extends Controller
if ($user) {
$_SESSION['php-censor-user-id'] = $user->getId();
$response = new b8\Http\Response\RedirectResponse();
$response = new RedirectResponse();
$response->setHeader('Location', $this->getLoginRedirect());
return $response;
}
}
$method = $this->request->getMethod();
if ($method === 'POST') {
$values = $this->getParams();
} else {
$values = [];
}
$form = $this->loginForm($values);
$isLoginFailure = false;
if ($this->request->getMethod() == 'POST') {
$token = $this->getParam('token');
if (!isset($token, $_SESSION['login_token']) || $token !== $_SESSION['login_token']) {
if ($this->request->getMethod() === 'POST') {
if (!$form->getChild('login_form')->validate()) {
$isLoginFailure = true;
} else {
unset($_SESSION['login_token']);
$email = $this->getParam('email');
$password = $this->getParam('password', '');
$rememberMe = (bool)$this->getParam('remember_me', 0);
@ -107,7 +159,7 @@ class SessionController extends Controller
);
}
$response = new b8\Http\Response\RedirectResponse();
$response = new RedirectResponse();
$response->setHeader('Location', $this->getLoginRedirect());
return $response;
@ -115,42 +167,7 @@ class SessionController extends Controller
}
}
$form = new b8\Form();
$form->setMethod('POST');
$form->setAction(APP_URL . 'session/login');
$email = new b8\Form\Element\Text('email');
$email->setLabel(Lang::get('login'));
$email->setRequired(true);
$email->setContainerClass('form-group');
$email->setClass('form-control');
$form->addField($email);
$pwd = new b8\Form\Element\Password('password');
$pwd->setLabel(Lang::get('password'));
$pwd->setRequired(true);
$pwd->setContainerClass('form-group');
$pwd->setClass('form-control');
$form->addField($pwd);
$remember = b8\Form\Element\Checkbox::create('remember_me', Lang::get('remember_me'), false);
$remember->setContainerClass('form-group');
$remember->setCheckedValue(1);
$remember->setValue(0);
$form->addField($remember);
$pwd = new b8\Form\Element\Submit();
$pwd->setValue(Lang::get('log_in'));
$pwd->setClass('btn-success');
$form->addField($pwd);
$tokenValue = $this->generateToken();
$_SESSION['login_token'] = $tokenValue;
$token = new b8\Form\Element\Hidden('token');
$token->setValue($tokenValue);
$form->addField($token);
$this->view->form = $form->render();
$this->view->form = $form->render();
$this->view->failed = $isLoginFailure;
return $this->view->render();
@ -175,7 +192,7 @@ class SessionController extends Controller
true
);
$response = new b8\Http\Response\RedirectResponse();
$response = new RedirectResponse();
$response->setHeader('Location', APP_URL);
return $response;
}
@ -188,17 +205,15 @@ class SessionController extends Controller
{
if ($this->request->getMethod() == 'POST') {
$email = $this->getParam('email', null);
$user = $this->userStore->getByEmail($email);
$user = $this->userStore->getByEmail($email);
if (empty($user)) {
$this->view->error = Lang::get('reset_no_user_exists');
return $this->view->render();
}
$key = md5(date('Y-m-d') . $user->getHash());
$url = APP_URL;
$message = Lang::get('reset_email_body', $user->getName(), $url, $user->getId(), $key);
$key = md5(date('Y-m-d') . $user->getHash());
$message = Lang::get('reset_email_body', $user->getName(), APP_URL, $user->getId(), $key);
$email = new Email();
$email->setEmailTo($user->getEmail(), $user->getName());
@ -236,7 +251,7 @@ class SessionController extends Controller
$_SESSION['php-censor-user-id'] = $user->getId();
$response = new b8\Http\Response\RedirectResponse();
$response = new RedirectResponse();
$response->setHeader('Location', APP_URL);
return $response;
}
@ -262,20 +277,4 @@ class SessionController extends Controller
return $rtn;
}
/** Generate a random token.
*
* @return string
*/
protected function generateToken()
{
if (function_exists('openssl_random_pseudo_bytes')) {
return bin2hex(openssl_random_pseudo_bytes(16));
}
return sprintf("%04x", mt_rand(0, 0xFFFF))
. sprintf("%04x", mt_rand(0, 0xFFFF))
. sprintf("%04x", mt_rand(0, 0xFFFF))
. sprintf("%04x", mt_rand(0, 0xFFFF));
}
}

View file

@ -2,22 +2,29 @@
namespace PHPCensor\Controller;
use b8;
use b8\Exception\HttpException\NotFoundException;
use b8\Form;
use PHPCensor\Controller;
use PHPCensor\Config;
use PHPCensor\Exception\HttpException\NotFoundException;
use PHPCensor\Form;
use PHPCensor\WebController;
use PHPCensor\Helper\Lang;
use PHPCensor\Http\Response\RedirectResponse;
use PHPCensor\Model\User;
use PHPCensor\Service\UserService;
use PHPCensor\View;
use PHPCensor\Store\Factory;
/**
* User Controller - Allows an administrator to view, add, edit and delete users.
*
* @author Dan Cryer <dan@block8.co.uk>
*/
class UserController extends Controller
class UserController extends WebController
{
/**
* @var string
*/
public $layoutName = 'layout';
/**
* @var \PHPCensor\Store\UserStore
*/
@ -33,7 +40,9 @@ class UserController extends Controller
*/
public function init()
{
$this->userStore = b8\Store\Factory::getStore('User');
parent::init();
$this->userStore = Factory::getStore('User');
$this->userService = new UserService($this->userStore);
}
@ -68,7 +77,7 @@ class UserController extends Controller
$language = null;
}
$perPage = $this->getParam('per_page', null);
$perPage = (integer)$this->getParam('per_page', null);
if (!$perPage) {
$perPage = null;
}
@ -82,9 +91,12 @@ class UserController extends Controller
$this->layout->subtitle = Lang::get('edit_profile');
$form = new Form();
$form->setAction(APP_URL.'user/profile');
$form->setAction(APP_URL . 'user/profile');
$form->setMethod('POST');
$form->addField(new Form\Element\Csrf('profile_form'));
$name = new Form\Element\Text('name');
$name->setClass('form-control');
$name->setContainerClass('form-group');
@ -115,7 +127,7 @@ class UserController extends Controller
$language->setLabel(Lang::get('language'));
$language->setRequired(true);
$language->setOptions(array_merge(
[null => Lang::get('default') . ' (' . b8\Config::getInstance()->get('php-censor.language') . ')'],
[null => Lang::get('default') . ' (' . Config::getInstance()->get('php-censor.language') . ')'],
Lang::getLanguageOptions())
);
$language->setValue($user->getLanguage());
@ -127,7 +139,7 @@ class UserController extends Controller
$perPage->setLabel(Lang::get('per_page'));
$perPage->setRequired(true);
$perPage->setOptions([
null => Lang::get('default') . ' (' . b8\Config::getInstance()->get('php-censor.per_page') . ')',
null => Lang::get('default') . ' (' . Config::getInstance()->get('php-censor.per_page') . ')',
10 => 10,
25 => 25,
50 => 50,
@ -157,15 +169,15 @@ class UserController extends Controller
$method = $this->request->getMethod();
if ($method == 'POST') {
if ($method === 'POST') {
$values = $this->getParams();
} else {
$values = [];
}
$form = $this->userForm($values);
$form = $this->userForm($values);
if ($method != 'POST' || ($method == 'POST' && !$form->validate())) {
if ($method !== 'POST' || ($method == 'POST' && !$form->validate())) {
$view = new View('User/edit');
$view->type = 'add';
$view->user = null;
@ -178,11 +190,11 @@ class UserController extends Controller
$name = $this->getParam('name', null);
$email = $this->getParam('email', null);
$password = $this->getParam('password', null);
$isAdmin = (int)$this->getParam('is_admin', 0);
$isAdmin = (boolean)$this->getParam('is_admin', 0);
$this->userService->createUser($name, $email, 'internal', json_encode(['type' => 'internal']), $password, $isAdmin);
$this->userService->createUser($name, $email, 'internal', ['type' => 'internal'], $password, $isAdmin);
$response = new b8\Http\Response\RedirectResponse();
$response = new RedirectResponse();
$response->setHeader('Location', APP_URL . 'user');
return $response;
}
@ -195,7 +207,7 @@ class UserController extends Controller
$this->requireAdmin();
$method = $this->request->getMethod();
$user = $this->userStore->getById($userId);
$user = $this->userStore->getById($userId);
if (empty($user)) {
throw new NotFoundException(Lang::get('user_n_not_found', $userId));
@ -219,11 +231,11 @@ class UserController extends Controller
$name = $this->getParam('name', null);
$email = $this->getParam('email', null);
$password = $this->getParam('password', null);
$isAdmin = (int)$this->getParam('is_admin', 0);
$isAdmin = (boolean)$this->getParam('is_admin', 0);
$this->userService->updateUser($user, $name, $email, $password, $isAdmin);
$response = new b8\Http\Response\RedirectResponse();
$response = new RedirectResponse();
$response->setHeader('Location', APP_URL . 'user');
return $response;
}
@ -234,9 +246,11 @@ class UserController extends Controller
protected function userForm($values, $type = 'add')
{
$form = new Form();
$form->setMethod('POST');
$form->setAction(APP_URL.'user/' . $type);
$form->addField(new Form\Element\Csrf('csrf'));
$form->setAction(APP_URL . 'user/' . $type);
$form->addField(new Form\Element\Csrf('user_form'));
$field = new Form\Element\Email('email');
$field->setRequired(true);
@ -279,6 +293,7 @@ class UserController extends Controller
$form->addField($field);
$form->setValues($values);
return $form;
}
@ -289,7 +304,7 @@ class UserController extends Controller
{
$this->requireAdmin();
$user = $this->userStore->getById($userId);
$user = $this->userStore->getById($userId);
if (empty($user)) {
throw new NotFoundException(Lang::get('user_n_not_found', $userId));
@ -297,7 +312,7 @@ class UserController extends Controller
$this->userService->deleteUser($user);
$response = new b8\Http\Response\RedirectResponse();
$response = new RedirectResponse();
$response->setHeader('Location', APP_URL . 'user');
return $response;
}

View file

@ -2,8 +2,6 @@
namespace PHPCensor\Controller;
use b8;
use b8\Store;
use Exception;
use GuzzleHttp\Client;
use PHPCensor\Helper\Lang;
@ -12,10 +10,12 @@ use PHPCensor\Model\Project;
use PHPCensor\Service\BuildService;
use PHPCensor\Store\BuildStore;
use PHPCensor\Store\ProjectStore;
use b8\Controller;
use b8\Config;
use b8\Exception\HttpException\NotFoundException;
use b8\Store\Factory;
use PHPCensor\Controller;
use PHPCensor\Config;
use PHPCensor\Exception\HttpException\NotFoundException;
use PHPCensor\Store\Factory;
use PHPCensor\Http\Request;
use PHPCensor\Http\Response;
/**
* Webhook Controller - Processes webhook pings from BitBucket, Github, Gitlab, Gogs, etc.
@ -48,21 +48,22 @@ class WebhookController extends Controller
*/
public function init()
{
$this->buildStore = Store\Factory::getStore('Build');
$this->projectStore = Store\Factory::getStore('Project');
$this->buildStore = Factory::getStore('Build');
$this->projectStore = Factory::getStore('Project');
$this->buildService = new BuildService($this->buildStore);
}
/** Handle the action, Ensuring to return a JsonResponse.
/**
* Handle the action, Ensuring to return a JsonResponse.
*
* @param string $action
* @param mixed $actionParams
* @param array $actionParams
*
* @return \b8\Http\Response
* @return Response
*/
public function handleAction($action, $actionParams)
{
$response = new b8\Http\Response\JsonResponse();
$response = new Response\JsonResponse();
try {
$data = parent::handleAction($action, $actionParams);
if (isset($data['responseCode'])) {
@ -79,10 +80,19 @@ class WebhookController extends Controller
/**
* Called by Bitbucket.
*
* @param integer $projectId
*
* @return array
*/
public function bitbucket($projectId)
{
$project = $this->fetchProject($projectId, ['bitbucket', 'bitbucket-hg', 'hg', 'git']);
$project = $this->fetchProject($projectId, [
Project::TYPE_BITBUCKET,
Project::TYPE_BITBUCKET_HG,
Project::TYPE_HG,
Project::TYPE_GIT,
]);
// Support both old services and new webhooks
if ($payload = $this->getParam('payload')) {
@ -112,7 +122,7 @@ class WebhookController extends Controller
* Handle the payload when Bitbucket sends a commit webhook.
*
* @param Project $project
* @param array $payload
* @param array $payload
*
* @return array
*/
@ -164,7 +174,7 @@ class WebhookController extends Controller
return ['status' => 'ok'];
}
$username = Config::getInstance()->get('php-censor.bitbucket.username');
$username = Config::getInstance()->get('php-censor.bitbucket.username');
$appPassword = Config::getInstance()->get('php-censor.bitbucket.app_password');
if (empty($username) || empty($appPassword)) {
@ -173,7 +183,7 @@ class WebhookController extends Controller
$commitsUrl = $payload['pullrequest']['links']['commits']['href'];
$client = new Client();
$client = new Client();
$commitsResponse = $client->get($commitsUrl, [
'auth' => [$username, $appPassword],
]);
@ -232,11 +242,14 @@ class WebhookController extends Controller
/**
* Bitbucket POST service.
*
* @param array $payload
* @param Project $project
*
* @return array
*/
protected function bitbucketService($payload, $project)
protected function bitbucketService(array $payload, Project $project)
{
$payload = json_decode($this->getParam('payload'), true);
$results = [];
$status = 'failed';
foreach ($payload['commits'] as $commit) {
@ -272,7 +285,10 @@ class WebhookController extends Controller
*/
public function git($projectId)
{
$project = $this->fetchProject($projectId, ['local', 'git']);
$project = $this->fetchProject($projectId, [
Project::TYPE_LOCAL,
Project::TYPE_GIT,
]);
$branch = $this->getParam('branch', $project->getBranch());
$commit = $this->getParam('commit');
$commitMessage = $this->getParam('message');
@ -291,10 +307,17 @@ class WebhookController extends Controller
/**
* Called by Github Webhooks:
*
* @param integer $projectId
*
* @return array
*/
public function github($projectId)
{
$project = $this->fetchProject($projectId, ['github', 'git']);
$project = $this->fetchProject($projectId, [
Project::TYPE_GITHUB,
Project::TYPE_GIT,
]);
switch ($_SERVER['CONTENT_TYPE']) {
case 'application/json':
@ -328,7 +351,7 @@ class WebhookController extends Controller
* Handle the payload when Github sends a commit webhook.
*
* @param Project $project
* @param array $payload
* @param array $payload
*
* @return array
*/
@ -411,10 +434,10 @@ class WebhookController extends Controller
$url = $payload['pull_request']['commits_url'];
//for large pull requests, allow grabbing more then the default number of commits
$custom_per_page = Config::getInstance()->get('php-censor.github.per_page');
$params = [];
if ($custom_per_page) {
$params['per_page'] = $custom_per_page;
$customPerPage = Config::getInstance()->get('php-censor.github.per_page');
$params = [];
if ($customPerPage) {
$params['per_page'] = $customPerPage;
}
$client = new Client();
@ -472,18 +495,25 @@ class WebhookController extends Controller
/**
* Called by Gitlab Webhooks:
*
* @param integer $projectId
*
* @return array
*/
public function gitlab($projectId)
{
$project = $this->fetchProject($projectId, ['gitlab', 'git']);
$project = $this->fetchProject($projectId, [
Project::TYPE_GITLAB,
Project::TYPE_GIT,
]);
$payloadString = file_get_contents("php://input");
$payload = json_decode($payloadString, true);
$payload = json_decode($payloadString, true);
// build on merge request events
if (isset($payload['object_kind']) && $payload['object_kind'] == 'merge_request') {
$attributes = $payload['object_attributes'];
if ($attributes['state'] == 'opened' || $attributes['state'] == 'reopened') {
if ($attributes['state'] === 'opened' || $attributes['state'] === 'reopened') {
$branch = $attributes['source_branch'];
$commit = $attributes['last_commit'];
$committer = $commit['author']['email'];
@ -508,8 +538,8 @@ class WebhookController extends Controller
$status = 'failed';
foreach ($payload['commits'] as $commit) {
try {
$branch = str_replace('refs/heads/', '', $payload['ref']);
$committer = $commit['author']['email'];
$branch = str_replace('refs/heads/', '', $payload['ref']);
$committer = $commit['author']['email'];
$results[$commit['id']] = $this->createBuild(
Build::SOURCE_WEBHOOK,
$project,
@ -542,11 +572,13 @@ class WebhookController extends Controller
*/
public function svn($projectId)
{
$project = $this->fetchProject($projectId, 'svn');
$branch = $this->getParam('branch', $project->getBranch());
$commit = $this->getParam('commit');
$project = $this->fetchProject($projectId, [
Project::TYPE_SVN
]);
$branch = $this->getParam('branch', $project->getBranch());
$commit = $this->getParam('commit');
$commitMessage = $this->getParam('message');
$committer = $this->getParam('committer');
$committer = $this->getParam('committer');
return $this->createBuild(
Build::SOURCE_WEBHOOK,
@ -568,7 +600,11 @@ class WebhookController extends Controller
*/
public function gogs($projectId)
{
$project = $this->fetchProject($projectId, ['gogs', 'git']);
$project = $this->fetchProject($projectId, [
Project::TYPE_GOGS,
Project::TYPE_GIT,
]);
switch ($_SERVER['CONTENT_TYPE']) {
case 'application/json':
$payload = json_decode(file_get_contents('php://input'), true);
@ -652,17 +688,17 @@ class WebhookController extends Controller
$activeStates = ['open'];
$inactiveStates = ['closed'];
if (!in_array($action, $activeActions) and !in_array($action, $inactiveActions)) {
if (!in_array($action, $activeActions) && !in_array($action, $inactiveActions)) {
return ['status' => 'ignored', 'message' => 'Action ' . $action . ' ignored'];
}
if (!in_array($state, $activeStates) and !in_array($state, $inactiveStates)) {
if (!in_array($state, $activeStates) && !in_array($state, $inactiveStates)) {
return ['status' => 'ignored', 'message' => 'State ' . $state . ' ignored'];
}
$envs = [];
// Get environment form labels
if (in_array($action, $activeActions) and in_array($state, $activeStates)) {
if (in_array($action, $activeActions) && in_array($state, $activeStates)) {
if (isset($pullRequest['labels']) && is_array($pullRequest['labels'])) {
foreach ($pullRequest['labels'] as $label) {
if (strpos($label['name'], 'env:') === 0) {
@ -674,7 +710,7 @@ class WebhookController extends Controller
$envsUpdated = [];
$envObjects = $project->getEnvironmentsObjects();
$store = Factory::getStore('Environment', 'PHPCensor');
$store = Factory::getStore('Environment');
foreach ($envObjects['items'] as $environment) {
$branches = $environment->getBranches();
if (in_array($environment->getName(), $envs)) {
@ -696,7 +732,7 @@ class WebhookController extends Controller
}
}
if (($state == 'closed') and $pullRequest['merged']) {
if ('closed' === $state && $pullRequest['merged']) {
// update base branch environments
$environmentNames = $project->getEnvironmentsNamesByBranch($pullRequest['base_branch']);
$envsUpdated = array_merge($envsUpdated, $environmentNames);
@ -758,13 +794,13 @@ class WebhookController extends Controller
// Check if a build already exists for this commit ID:
$builds = $this->buildStore->getByProjectAndCommit($project->getId(), $commitId);
$ignore_environments = [];
$ignore_tags = [];
$ignoreEnvironments = [];
$ignoreTags = [];
if ($builds['count']) {
foreach($builds['items'] as $build) {
/** @var Build $build */
$ignore_environments[$build->getId()] = $build->getEnvironment();
$ignore_tags[$build->getId()] = $build->getTag();
$ignoreEnvironments[$build->getId()] = $build->getEnvironment();
$ignoreTags[$build->getId()] = $build->getTag();
}
}
@ -778,20 +814,20 @@ class WebhookController extends Controller
$environments = $project->getEnvironmentsObjects();
if ($environments['count']) {
$created_builds = [];
$environment_names = $project->getEnvironmentsNamesByBranch($branch);
$createdBuilds = [];
$environmentNames = $project->getEnvironmentsNamesByBranch($branch);
// use base branch from project
if (!empty($environment_names)) {
if (!empty($environmentNames)) {
$duplicates = [];
foreach ($environment_names as $environment_name) {
foreach ($environmentNames as $environmentName) {
if (
!in_array($environment_name, $ignore_environments) ||
($tag && !in_array($tag, $ignore_tags, true))
!in_array($environmentName, $ignoreEnvironments) ||
($tag && !in_array($tag, $ignoreTags, true))
) {
// If not, create a new build job for it:
$build = $this->buildService->createBuild(
$project,
$environment_name,
$environmentName,
$commitId,
$project->getBranch(),
$tag,
@ -802,19 +838,19 @@ class WebhookController extends Controller
$extra
);
$created_builds[] = [
$createdBuilds[] = [
'id' => $build->getID(),
'environment' => $environment_name,
'environment' => $environmentName,
];
} else {
$duplicates[] = array_search($environment_name, $ignore_environments);
$duplicates[] = array_search($environmentName, $ignoreEnvironments);
}
}
if (!empty($created_builds)) {
if (!empty($createdBuilds)) {
if (empty($duplicates)) {
return ['status' => 'ok', 'builds' => $created_builds];
return ['status' => 'ok', 'builds' => $createdBuilds];
} else {
return ['status' => 'ok', 'builds' => $created_builds, 'message' => sprintf('For this commit some builds already exists (%s)', implode(', ', $duplicates))];
return ['status' => 'ok', 'builds' => $createdBuilds, 'message' => sprintf('For this commit some builds already exists (%s)', implode(', ', $duplicates))];
}
} else {
return ['status' => 'ignored', 'message' => sprintf('For this commit already created builds (%s)', implode(', ', $duplicates))];
@ -823,10 +859,10 @@ class WebhookController extends Controller
return ['status' => 'ignored', 'message' => 'Branch not assigned to any environment'];
}
} else {
$environment_name = null;
$environmentName = null;
if (
!in_array($environment_name, $ignore_environments, true) ||
($tag && !in_array($tag, $ignore_tags, true))
!in_array($environmentName, $ignoreEnvironments, true) ||
($tag && !in_array($tag, $ignoreTags, true))
) {
$build = $this->buildService->createBuild(
$project,
@ -845,7 +881,7 @@ class WebhookController extends Controller
} else {
return [
'status' => 'ignored',
'message' => sprintf('Duplicate of build #%d', array_search($environment_name, $ignore_environments)),
'message' => sprintf('Duplicate of build #%d', array_search($environmentName, $ignoreEnvironments)),
];
}
}
@ -854,14 +890,14 @@ class WebhookController extends Controller
/**
* Fetch a project and check its type.
*
* @param int|string $projectId id or title of project
* @param array|string $expectedType
* @param integer $projectId id or title of project
* @param array $expectedType
*
* @return Project
*
* @throws Exception If the project does not exist or is not of the expected type.
*/
protected function fetchProject($projectId, $expectedType)
protected function fetchProject($projectId, array $expectedType)
{
if (empty($projectId)) {
throw new Exception('Project does not exist: ' . $projectId);
@ -880,10 +916,7 @@ class WebhookController extends Controller
$project = reset($projects['items']);
}
if (is_array($expectedType)
? !in_array($project->getType(), $expectedType)
: $project->getType() !== $expectedType
) {
if (!in_array($project->getType(), $expectedType, true)) {
throw new Exception('Wrong project type: ' . $project->getType());
}

View file

@ -3,11 +3,11 @@
namespace PHPCensor\Controller;
use PHPCensor\Model\Build;
use PHPCensor\Controller;
use b8\Store\Factory;
use PHPCensor\WebController;
use PHPCensor\Store\Factory;
use PHPCensor\View;
use PHPCensor\Model\Project;
use b8\Http\Response;
use PHPCensor\Http\Response;
use PHPCensor\Store\BuildStore;
use PHPCensor\Store\ProjectStore;
use PHPCensor\Store\ProjectGroupStore;
@ -15,7 +15,7 @@ use PHPCensor\Store\ProjectGroupStore;
/**
* Widget All Projects Controller
*/
class WidgetAllProjectsController extends Controller
class WidgetAllProjectsController extends WebController
{
/**
* @var BuildStore
@ -37,6 +37,8 @@ class WidgetAllProjectsController extends Controller
*/
public function init()
{
parent::init();
$this->buildStore = Factory::getStore('Build');
$this->projectStore = Factory::getStore('Project');
$this->groupStore = Factory::getStore('ProjectGroup');
@ -49,10 +51,10 @@ class WidgetAllProjectsController extends Controller
{
$this->view->groups = $this->getGroupInfo();
$this->response->disableLayout();
$this->response->setContent($this->view->render());
$response = new Response();
$response->setContent($this->view->render());
return $this->response;
return $response;
}
/**
@ -142,9 +144,9 @@ class WidgetAllProjectsController extends Controller
$this->view->failed = $this->buildStore->getLastBuildByStatus($projectId, Build::STATUS_FAILED);
$this->view->counts = $counts;
$this->response->disableLayout();
$this->response->setContent($this->view->render());
$response = new Response();
$response->setContent($this->view->render());
return $this->response;
return $response;
}
}

View file

@ -2,17 +2,17 @@
namespace PHPCensor\Controller;
use b8\Store\Factory;
use PHPCensor\Store\Factory;
use PHPCensor\View;
use b8\Http\Response;
use PHPCensor\Controller;
use PHPCensor\Http\Response;
use PHPCensor\WebController;
use PHPCensor\Store\BuildStore;
use PHPCensor\Store\ProjectStore;
/**
* Widget Build Errors Controller
*/
class WidgetBuildErrorsController extends Controller
class WidgetBuildErrorsController extends WebController
{
/**
* @var BuildStore
@ -29,6 +29,8 @@ class WidgetBuildErrorsController extends Controller
*/
public function init()
{
parent::init();
$this->buildStore = Factory::getStore('Build');
$this->projectStore = Factory::getStore('Project');
}
@ -42,10 +44,10 @@ class WidgetBuildErrorsController extends Controller
$this->view->projects = $this->renderAllProjectsLatestBuilds($view);
$this->response->disableLayout();
$this->response->setContent($this->view->render());
$response = new Response();
$response->setContent($this->view->render());
return $this->response;
return $response;
}
/**
@ -53,10 +55,10 @@ class WidgetBuildErrorsController extends Controller
*/
public function update()
{
$this->response->disableLayout();
$this->response->setContent($this->renderAllProjectsLatestBuilds($this->view));
$response = new Response();
$response->setContent($this->renderAllProjectsLatestBuilds($this->view));
return $this->response;
return $response;
}
/**
@ -72,15 +74,15 @@ class WidgetBuildErrorsController extends Controller
$view->builds = $builds['projects'];
$projects = $this->projectStore->getByIds(array_keys($builds['projects']));
$view_projects = [];
$viewProjects = [];
foreach($projects as $id => $project) {
if (!$project->getArchived()) {
$view_projects[$id] = $project;
$viewProjects[$id] = $project;
} else {
unset($builds['projects'][$id]);
}
}
$view->projects = $view_projects;
$view->projects = $viewProjects;
} else {
$view = new View('WidgetBuildErrors/empty');
}

View file

@ -2,17 +2,17 @@
namespace PHPCensor\Controller;
use b8\Store\Factory;
use PHPCensor\Store\Factory;
use PHPCensor\View;
use b8\Http\Response;
use PHPCensor\Http\Response;
use PHPCensor\BuildFactory;
use PHPCensor\Controller;
use PHPCensor\WebController;
use PHPCensor\Store\BuildStore;
/**
* Widget Last Builds Controller
*/
class WidgetLastBuildsController extends Controller
class WidgetLastBuildsController extends WebController
{
/**
* @var BuildStore
@ -24,6 +24,8 @@ class WidgetLastBuildsController extends Controller
*/
public function init()
{
parent::init();
$this->buildStore = Factory::getStore('Build');
}
@ -43,10 +45,10 @@ class WidgetLastBuildsController extends Controller
$view->builds = $builds;
$this->view->timeline = $view->render();
$this->response->disableLayout();
$this->response->setContent($this->view->render());
$response = new Response();
$response->setContent($this->view->render());
return $this->response;
return $response;
}
/**
@ -62,9 +64,9 @@ class WidgetLastBuildsController extends Controller
$this->view->builds = $builds;
$this->response->disableLayout();
$this->response->setContent($this->view->render());
$response = new Response();
$response->setContent($this->view->render());
return $this->response;
return $response;
}
}

View file

@ -1,6 +1,6 @@
<?php
namespace b8;
namespace PHPCensor;
class Database extends \PDO
{
@ -76,7 +76,7 @@ class Database extends \PDO
/**
* @param string $type
*
* @return \b8\Database
* @return Database
*
* @throws \Exception
*/
@ -192,12 +192,12 @@ class Database extends \PDO
/**
* @param string $statement
* @param array $driver_options
* @param array $driverOptions
*
* @return \PDOStatement
*/
public function prepareCommon($statement, array $driver_options = [])
public function prepareCommon($statement, array $driverOptions = [])
{
return parent::prepare($this->quoteNames($statement), $driver_options);
return parent::prepare($this->quoteNames($statement), $driverOptions);
}
}

View file

@ -1,6 +1,6 @@
<?php
namespace b8\Exception;
namespace PHPCensor\Exception;
class HttpException extends \Exception
{

View file

@ -1,8 +1,8 @@
<?php
namespace b8\Exception\HttpException;
namespace PHPCensor\Exception\HttpException;
use b8\Exception\HttpException;
use PHPCensor\Exception\HttpException;
class BadRequestException extends HttpException
{

View file

@ -1,8 +1,8 @@
<?php
namespace b8\Exception\HttpException;
namespace PHPCensor\Exception\HttpException;
use b8\Exception\HttpException;
use PHPCensor\Exception\HttpException;
class ForbiddenException extends HttpException
{

View file

@ -1,8 +1,8 @@
<?php
namespace b8\Exception\HttpException;
namespace PHPCensor\Exception\HttpException;
use b8\Exception\HttpException;
use PHPCensor\Exception\HttpException;
class NotAuthorizedException extends HttpException
{

View file

@ -1,8 +1,8 @@
<?php
namespace b8\Exception\HttpException;
namespace PHPCensor\Exception\HttpException;
use b8\Exception\HttpException;
use PHPCensor\Exception\HttpException;
class NotFoundException extends HttpException
{

View file

@ -0,0 +1,9 @@
<?php
namespace PHPCensor\Exception\HttpException;
use PHPCensor\Exception\HttpException;
class ServerErrorException extends HttpException
{
}

View file

@ -1,8 +1,8 @@
<?php
namespace b8\Exception\HttpException;
namespace PHPCensor\Exception\HttpException;
use b8\Exception\HttpException;
use PHPCensor\Exception\HttpException;
class ValidationException extends HttpException
{

View file

@ -1,9 +1,8 @@
<?php
namespace b8;
namespace PHPCensor;
use b8\Form\FieldSet;
use PHPCensor\View;
use PHPCensor\Form\FieldSet;
class Form extends FieldSet
{

View file

@ -1,6 +1,6 @@
<?php
namespace b8\Form;
namespace PHPCensor\Form;
class ControlGroup extends FieldSet
{

View file

@ -1,9 +1,8 @@
<?php
namespace b8\Form;
namespace PHPCensor\Form;
use PHPCensor\View;
use b8\Config;
abstract class Element
{
@ -168,18 +167,12 @@ abstract class Element
*/
public function render($viewFile = null)
{
$viewPath = Config::getInstance()->get('b8.view.path');
if (is_null($viewFile)) {
$class = explode('\\', get_called_class());
$viewFile = end($class);
}
if (file_exists($viewPath . 'Form/' . $viewFile . '.phtml')) {
$view = new View('Form/' . $viewFile);
} else {
$view = new View($viewFile, B8_PATH . 'Form/View/');
}
$view = new View('Form/' . $viewFile);
$view->name = $this->getName();
$view->id = $this->getId();

View file

@ -1,8 +1,8 @@
<?php
namespace b8\Form\Element;
namespace PHPCensor\Form\Element;
use b8\Form\Input;
use PHPCensor\Form\Input;
use PHPCensor\View;
class Button extends Input

View file

@ -1,9 +1,9 @@
<?php
namespace b8\Form\Element;
namespace PHPCensor\Form\Element;
use PHPCensor\View;
use b8\Form\Input;
use PHPCensor\Form\Input;
class Checkbox extends Input
{

View file

@ -0,0 +1,9 @@
<?php
namespace PHPCensor\Form\Element;
use PHPCensor\Form\FieldSet;
class CheckboxGroup extends FieldSet
{
}

40
src/Form/Element/Csrf.php Normal file
View file

@ -0,0 +1,40 @@
<?php
namespace PHPCensor\Form\Element;
use PHPCensor\View;
class Csrf extends Hidden
{
/**
* @return boolean
*/
public function validate()
{
$sessionToken = isset($_SESSION['csrf_tokens'][$this->getName()])
? $_SESSION['csrf_tokens'][$this->getName()]
: null;
if ($this->value !== $sessionToken) {
return false;
}
return true;
}
/**
* @param View $view
*/
protected function onPreRender(View &$view)
{
parent::onPreRender($view);
$this->setValue(
rtrim(strtr(base64_encode(random_bytes(32)), '+/', '-_'), '=')
);
$view->value = $this->getValue();
$_SESSION['csrf_tokens'][$this->getName()] = $this->getValue();
}
}

View file

@ -1,6 +1,6 @@
<?php
namespace b8\Form\Element;
namespace PHPCensor\Form\Element;
use PHPCensor\View;

View file

@ -0,0 +1,9 @@
<?php
namespace PHPCensor\Form\Element;
use PHPCensor\Form\Input;
class Hidden extends Input
{
}

View file

@ -1,6 +1,6 @@
<?php
namespace b8\Form\Element;
namespace PHPCensor\Form\Element;
use PHPCensor\View;

View file

@ -1,6 +1,6 @@
<?php
namespace b8\Form\Element;
namespace PHPCensor\Form\Element;
class Radio extends Select
{

View file

@ -1,9 +1,9 @@
<?php
namespace b8\Form\Element;
namespace PHPCensor\Form\Element;
use PHPCensor\View;
use b8\Form\Input;
use PHPCensor\Form\Input;
class Select extends Input
{

View file

@ -1,6 +1,6 @@
<?php
namespace b8\Form\Element;
namespace PHPCensor\Form\Element;
use PHPCensor\View;

View file

@ -1,8 +1,8 @@
<?php
namespace b8\Form\Element;
namespace PHPCensor\Form\Element;
use b8\Form\Input;
use PHPCensor\Form\Input;
use PHPCensor\View;
class Text extends Input

View file

@ -1,6 +1,6 @@
<?php
namespace b8\Form\Element;
namespace PHPCensor\Form\Element;
use PHPCensor\View;

View file

@ -1,6 +1,6 @@
<?php
namespace b8\Form\Element;
namespace PHPCensor\Form\Element;
use PHPCensor\View;

View file

@ -1,6 +1,6 @@
<?php
namespace b8\Form;
namespace PHPCensor\Form;
use PHPCensor\View;

View file

@ -1,6 +1,6 @@
<?php
namespace b8\Form;
namespace PHPCensor\Form;
use PHPCensor\View;

View file

@ -2,7 +2,7 @@
namespace PHPCensor\Helper;
use b8\Config;
use PHPCensor\Config;
use GuzzleHttp\Client;
/**
@ -92,7 +92,7 @@ class Bitbucket
*/
public function getPullRequestDiff($repo, $pullRequestId)
{
$username = Config::getInstance()->get('php-censor.bitbucket.username');
$username = Config::getInstance()->get('php-censor.bitbucket.username');
$appPassword = Config::getInstance()->get('php-censor.bitbucket.app_password');
if (empty($username) || empty($appPassword)) {

View file

@ -0,0 +1,85 @@
<?php
namespace PHPCensor\Helper;
use PHPCensor\Model\Build as BaseBuild;
/**
* The BuildInterpolator class replaces variables in a string with build-specific information.
*
* @package PHPCensor\Helper
*/
class BuildInterpolator
{
/**
* An array of key => value pairs that will be used for
* interpolation and environment variables
* @var mixed[]
* @see setupInterpolationVars()
*/
protected $interpolationVars = [];
/**
* Sets the variables that will be used for interpolation.
*
* @param BaseBuild $build
* @param string $buildPath
* @param string $url
*/
public function setupInterpolationVars(BaseBuild $build, $buildPath, $url)
{
$this->interpolationVars = [];
$this->interpolationVars['%PHPCI%'] = 1;
$this->interpolationVars['%COMMIT%'] = $build->getCommitId();
$this->interpolationVars['%SHORT_COMMIT%'] = substr($build->getCommitId(), 0, 7);
$this->interpolationVars['%COMMIT_EMAIL%'] = $build->getCommitterEmail();
$this->interpolationVars['%COMMIT_MESSAGE%'] = $build->getCommitMessage();
$this->interpolationVars['%COMMIT_URI%'] = $build->getCommitLink();
$this->interpolationVars['%BRANCH%'] = $build->getBranch();
$this->interpolationVars['%BRANCH_URI%'] = $build->getBranchLink();
$this->interpolationVars['%ENVIRONMENT%'] = $build->getEnvironment();
$this->interpolationVars['%PROJECT%'] = $build->getProjectId();
$this->interpolationVars['%BUILD%'] = $build->getId();
$this->interpolationVars['%PROJECT_TITLE%'] = $build->getProjectTitle();
$this->interpolationVars['%PROJECT_URI%'] = $url . "project/view/" . $build->getProjectId();
$this->interpolationVars['%BUILD_PATH%'] = $buildPath;
$this->interpolationVars['%BUILD_URI%'] = $url . "build/view/" . $build->getId();
$this->interpolationVars['%PHPCI_COMMIT%'] = $this->interpolationVars['%COMMIT%'];
$this->interpolationVars['%PHPCI_SHORT_COMMIT%'] = $this->interpolationVars['%SHORT_COMMIT%'];
$this->interpolationVars['%PHPCI_COMMIT_MESSAGE%'] = $this->interpolationVars['%COMMIT_MESSAGE%'];
$this->interpolationVars['%PHPCI_COMMIT_EMAIL%'] = $this->interpolationVars['%COMMIT_EMAIL%'];
$this->interpolationVars['%PHPCI_COMMIT_URI%'] = $this->interpolationVars['%COMMIT_URI%'];
$this->interpolationVars['%PHPCI_PROJECT%'] = $this->interpolationVars['%PROJECT%'];
$this->interpolationVars['%PHPCI_BUILD%'] = $this->interpolationVars['%BUILD%'];
$this->interpolationVars['%PHPCI_PROJECT_TITLE%'] = $this->interpolationVars['%PROJECT_TITLE%'];
$this->interpolationVars['%PHPCI_PROJECT_URI%'] = $this->interpolationVars['%PROJECT_URI%'];
$this->interpolationVars['%PHPCI_BUILD_PATH%'] = $this->interpolationVars['%BUILD_PATH%'];
$this->interpolationVars['%PHPCI_BUILD_URI%'] = $this->interpolationVars['%BUILD_URI%'];
putenv('PHPCI=1');
putenv('PHPCI_COMMIT=' . $this->interpolationVars['%COMMIT%']);
putenv('PHPCI_SHORT_COMMIT=' . $this->interpolationVars['%SHORT_COMMIT%']);
putenv('PHPCI_COMMIT_MESSAGE=' . $this->interpolationVars['%COMMIT_MESSAGE%']);
putenv('PHPCI_COMMIT_EMAIL=' . $this->interpolationVars['%COMMIT_EMAIL%']);
putenv('PHPCI_COMMIT_URI=' . $this->interpolationVars['%COMMIT_URI%']);
putenv('PHPCI_PROJECT=' . $this->interpolationVars['%PROJECT%']);
putenv('PHPCI_BUILD=' . $this->interpolationVars['%BUILD%']);
putenv('PHPCI_PROJECT_TITLE=' . $this->interpolationVars['%PROJECT_TITLE%']);
putenv('PHPCI_BUILD_PATH=' . $this->interpolationVars['%BUILD_PATH%']);
putenv('PHPCI_BUILD_URI=' . $this->interpolationVars['%BUILD_URI%']);
putenv('PHPCI_ENVIRONMENT=' . $this->interpolationVars['%ENVIRONMENT%']);
}
/**
* Replace every occurrence of the interpolation vars in the given string
* Example: "This is build %PHPCI_BUILD%" => "This is build 182"
* @param string $input
* @return string
*/
public function interpolate($input)
{
$keys = array_keys($this->interpolationVars);
$values = array_values($this->interpolationVars);
return str_replace($keys, $values, $input);
}
}

View file

@ -61,7 +61,7 @@ class CommandExecutor implements CommandExecutorInterface
* @param bool $quiet
* @param bool $verbose
*/
public function __construct(BuildLogger $logger, $rootDir, &$quiet = false, &$verbose = false)
public function __construct(BuildLogger $logger, $rootDir, $quiet = false, $verbose = false)
{
$this->logger = $logger;
$this->quiet = $quiet;
@ -335,14 +335,14 @@ class CommandExecutor implements CommandExecutorInterface
public function getComposerBinDir($path)
{
if (is_dir($path)) {
$composer = $path . DIRECTORY_SEPARATOR . 'composer.json';
$composer = $path . '/composer.json';
if (is_file($composer)) {
$json = json_decode(file_get_contents($composer));
if (isset($json->config->{"bin-dir"})) {
return $path . DIRECTORY_SEPARATOR . $json->config->{"bin-dir"};
} elseif (is_dir($path . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'bin')) {
return $path . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'bin';
return $path . '/' . $json->config->{"bin-dir"};
} elseif (is_dir($path . '/vendor/bin')) {
return $path . '/vendor/bin';
}
}
}

View file

@ -2,7 +2,7 @@
namespace PHPCensor\Helper;
use b8\Config;
use PHPCensor\Config;
use PHPCensor\Builder;
/**
@ -99,13 +99,13 @@ class Email
'php-censor.email_settings.from_address',
self::DEFAULT_FROM
);
if (strpos($from, '<') === false) {
return (string)$from;
}
preg_match('#^(.*?)<(.*)>$#ui', $from, $fromParts);
return [$fromParts[2] => $fromParts[1]];
}

View file

@ -2,7 +2,7 @@
namespace PHPCensor\Helper;
use b8\Config;
use PHPCensor\Config;
use GuzzleHttp\Client;
use Symfony\Component\Cache\Simple\FilesystemCache;
@ -34,9 +34,9 @@ class Github
$results[] = $item;
}
foreach ($headers as $header_name => $header) {
foreach ($headers as $headerName => $header) {
if (
'Link' === $header_name &&
'Link' === $headerName &&
preg_match('/^<([^>]+)>; rel="next"/', implode(', ', $header), $r)
) {
$host = parse_url($r[1]);

View file

@ -2,9 +2,8 @@
namespace PHPCensor\Helper;
use b8\Config;
use b8\Store\Factory;
use PHPCensor\Model\User;
use PHPCensor\Config;
use PHPCensor\Store\Factory;
use PHPCensor\Store\UserStore;
/**
@ -32,24 +31,24 @@ class Lang
/**
* @var array
*/
protected static $default_strings = [];
protected static $defaultStrings = [];
/**
* Get a specific string from the language file.
*
* @param $string
* @return mixed|string
* @param array ...$params
*
* @return string
*/
public static function get($string)
public static function get(...$params)
{
$vars = func_get_args();
$string = $params[0];
if (array_key_exists($string, self::$strings)) {
$vars[0] = self::$strings[$string];
return call_user_func_array('sprintf', $vars);
} elseif (self::DEFAULT_LANGUAGE !== self::$language && array_key_exists($string, self::$default_strings)) {
$vars[0] = self::$default_strings[$string];
return call_user_func_array('sprintf', $vars);
$params[0] = self::$strings[$string];
return call_user_func_array('sprintf', $params);
} elseif (self::DEFAULT_LANGUAGE !== self::$language && array_key_exists($string, self::$defaultStrings)) {
$params[0] = self::$defaultStrings[$string];
return call_user_func_array('sprintf', $params);
}
return $string;
@ -57,10 +56,12 @@ class Lang
/**
* Output a specific string from the language file.
*
* @param array ...$params
*/
public static function out()
public static function out(...$params)
{
print call_user_func_array(['PHPCensor\Helper\Lang', 'get'], func_get_args());
print call_user_func_array(['PHPCensor\Helper\Lang', 'get'], $params);
}
/**
@ -100,7 +101,7 @@ class Lang
{
$languages = [];
foreach (self::$languages as $language) {
$strings = include(SRC_DIR . 'Languages' . DIRECTORY_SEPARATOR . 'lang.' . $language . '.php');
$strings = include(SRC_DIR . 'Languages/lang.' . $language . '.php');
$languages[$language] = !empty($strings['language_name'])
? $strings['language_name'] . ' (' . $language . ')'
: $language;
@ -123,14 +124,14 @@ class Lang
* Initialise the Language helper, try load the language file for the user's browser or the configured default.
*
* @param Config $config
* @param string $language_force
* @param string $languageForce
*/
public static function init(Config $config, $language_force = null)
public static function init(Config $config, $languageForce = null)
{
self::$default_strings = self::loadLanguage(self::DEFAULT_LANGUAGE);
self::$defaultStrings = self::loadLanguage(self::DEFAULT_LANGUAGE);
self::loadAvailableLanguages();
if ($language_force && self::setLanguage($language_force)) {
if ($languageForce && self::setLanguage($languageForce)) {
return;
}
@ -164,8 +165,11 @@ class Lang
*/
protected static function loadLanguage($language = null)
{
$language = $language ? $language : self::$language;
$langFile = SRC_DIR . 'Languages' . DIRECTORY_SEPARATOR . 'lang.' . $language . '.php';
$language = $language
? $language
: self::$language;
$langFile = SRC_DIR . 'Languages/lang.' . $language . '.php';
if (!file_exists($langFile)) {
return null;
@ -185,7 +189,7 @@ class Lang
protected static function loadAvailableLanguages()
{
$matches = [];
foreach (glob(SRC_DIR . 'Languages' . DIRECTORY_SEPARATOR . 'lang.*.php') as $file) {
foreach (glob(SRC_DIR . 'Languages/lang.*.php') as $file) {
if (preg_match('/lang\.([a-z]{2}\-?[a-z]*)\.php/', $file, $matches)) {
self::$languages[] = $matches[1];
}

View file

@ -2,7 +2,7 @@
namespace PHPCensor\Helper;
use b8\Config;
use PHPCensor\Config;
/**
* Helper class for dealing with SSH keys.

View file

@ -1,6 +1,6 @@
<?php
namespace b8\Http;
namespace PHPCensor\Http;
class Request
{

View file

@ -1,6 +1,6 @@
<?php
namespace b8\Http;
namespace PHPCensor\Http;
class Response
{
@ -13,21 +13,6 @@ class Response
}
}
public function hasLayout()
{
return !isset($this->data['layout']) ? true : $this->data['layout'];
}
public function disableLayout()
{
$this->data['layout'] = false;
}
public function enableLayout()
{
$this->data['layout'] = true;
}
public function getData()
{
return $this->data;

View file

@ -1,8 +1,8 @@
<?php
namespace b8\Http\Response;
namespace PHPCensor\Http\Response;
use b8\Http\Response;
use PHPCensor\Http\Response;
class JsonResponse extends Response
{
@ -14,11 +14,6 @@ class JsonResponse extends Response
$this->setHeader('Content-Type', 'application/json');
}
public function hasLayout()
{
return false;
}
protected function flushBody()
{
if (isset($this->data['body'])) {

View file

@ -1,8 +1,8 @@
<?php
namespace b8\Http\Response;
namespace PHPCensor\Http\Response;
use b8\Http\Response;
use PHPCensor\Http\Response;
class RedirectResponse extends Response
{
@ -14,11 +14,6 @@ class RedirectResponse extends Response
$this->setResponseCode(302);
}
public function hasLayout()
{
return false;
}
public function flush()
{
parent::flush();

View file

@ -1,9 +1,9 @@
<?php
namespace b8\Http;
namespace PHPCensor\Http;
use b8\Application;
use b8\Config;
use PHPCensor\Application;
use PHPCensor\Config;
class Router
{
@ -18,7 +18,7 @@ class Router
protected $config;
/**
* @var \b8\Application
* @var Application
*/
protected $application;
@ -62,9 +62,9 @@ class Router
//-------
// Set up default values for everything:
//-------
$thisNamespace = 'Controller';
$thisNamespace = 'Controller';
$thisController = null;
$thisAction = null;
$thisAction = null;
if (array_key_exists('namespace', $route['defaults'])) {
$thisNamespace = $route['defaults']['namespace'];

View file

@ -2,7 +2,7 @@
namespace PHPCensor\Logging;
use b8\Store\Factory;
use PHPCensor\Store\Factory;
use Monolog\Handler\AbstractProcessingHandler;
use PHPCensor\Model\Build;
use Psr\Log\LogLevel;
@ -22,12 +22,12 @@ class BuildDBLogHandler extends AbstractProcessingHandler
/**
* @var int last flush timestamp
*/
protected $flush_timestamp = 0;
protected $flushTimestamp = 0;
/**
* @var int flush delay, seconds
*/
protected $flush_delay = 1;
protected $flushDelay = 1;
/**
* @param Build $build
@ -60,7 +60,7 @@ class BuildDBLogHandler extends AbstractProcessingHandler
{
$this->build->setLog($this->logValue);
Factory::getStore('Build')->save($this->build);
$this->flush_timestamp = time();
$this->flushTimestamp = time();
}
/**
@ -74,7 +74,7 @@ class BuildDBLogHandler extends AbstractProcessingHandler
$this->logValue .= $message . PHP_EOL;
if ($this->flush_timestamp < (time() - $this->flush_delay)) {
if ($this->flushTimestamp < (time() - $this->flushDelay)) {
$this->flushData();
}
}

View file

@ -62,10 +62,10 @@ class Handler
public function handleError($level, $message, $file, $line)
{
if (error_reporting() & $level) {
$exception_level = isset($this->levels[$level]) ? $this->levels[$level] : $level;
$exceptionLevel = isset($this->levels[$level]) ? $this->levels[$level] : $level;
throw new \ErrorException(
sprintf('%s: %s in %s line %d', $exception_level, $message, $file, $line),
sprintf('%s: %s in %s line %d', $exceptionLevel, $message, $file, $line),
0,
$level,
$file,
@ -79,22 +79,22 @@ class Handler
*/
public function handleFatalError()
{
$fatal_error = error_get_last();
$fatalError = error_get_last();
try {
if (($error = error_get_last()) !== null) {
$error = new \ErrorException(
sprintf(
'%s: %s in %s line %d',
$fatal_error['type'],
$fatal_error['message'],
$fatal_error['file'],
$fatal_error['line']
$fatalError['type'],
$fatalError['message'],
$fatalError['file'],
$fatalError['line']
),
0,
$fatal_error['type'],
$fatal_error['file'],
$fatal_error['line']
$fatalError['type'],
$fatalError['file'],
$fatalError['line']
);
$this->log($error);
}
@ -102,15 +102,15 @@ class Handler
$error = new \ErrorException(
sprintf(
'%s: %s in %s line %d',
$fatal_error['type'],
$fatal_error['message'],
$fatal_error['file'],
$fatal_error['line']
$fatalError['type'],
$fatalError['message'],
$fatalError['file'],
$fatalError['line']
),
0,
$fatal_error['type'],
$fatal_error['file'],
$fatal_error['line']
$fatalError['type'],
$fatalError['file'],
$fatalError['line']
);
$this->log($error);
}

Some files were not shown because too many files have changed in this diff Show more