mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-06-02 12:49:27 +00:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1feb4ff4fd | |||
| 34865bc0c0 | |||
| 8cd0f4c8bd | |||
| ffaf360ea0 | |||
| f888dcc72d | |||
| 664796c69f | |||
| 37fa899540 |
@@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||||
|
|
||||||
|
// broaden the allowed URI characters just for tests
|
||||||
|
$config['permitted_uri_chars'] = 'a-z A-Z 0-9~%.:_\-';
|
||||||
|
// ensure we read REQUEST_URI
|
||||||
|
$config['uri_protocol'] = 'REQUEST_URI';
|
||||||
@@ -17,6 +17,27 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if (! defined('BASEPATH')) exit('No direct script access allowed');
|
if (! defined('BASEPATH')) exit('No direct script access allowed');
|
||||||
|
/**
|
||||||
|
* @SWG\Info(
|
||||||
|
* title="Bookmark API",
|
||||||
|
* version="1.0.0"
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @SWG\Swagger(
|
||||||
|
* schemes={"https"},
|
||||||
|
* basePath="/fhcompletecis4/cis.php/api/frontend/v1/Bookmark/"
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @SWG\SecurityScheme(
|
||||||
|
* securityDefinition="basicAuth",
|
||||||
|
* type="basic"
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
class Bookmark extends FHCAPI_Controller
|
class Bookmark extends FHCAPI_Controller
|
||||||
{
|
{
|
||||||
@@ -31,6 +52,7 @@ class Bookmark extends FHCAPI_Controller
|
|||||||
'delete' => self::PERM_LOGGED,
|
'delete' => self::PERM_LOGGED,
|
||||||
'insert' => self::PERM_LOGGED,
|
'insert' => self::PERM_LOGGED,
|
||||||
'update' => self::PERM_LOGGED,
|
'update' => self::PERM_LOGGED,
|
||||||
|
'test_true' => self::PERM_LOGGED
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->load->model('dashboard/Bookmark_model', 'BookmarkModel');
|
$this->load->model('dashboard/Bookmark_model', 'BookmarkModel');
|
||||||
@@ -48,6 +70,21 @@ class Bookmark extends FHCAPI_Controller
|
|||||||
* gets the bookmarks associated to a user
|
* gets the bookmarks associated to a user
|
||||||
* @access public
|
* @access public
|
||||||
* @return void
|
* @return void
|
||||||
|
* @SWG\Get(
|
||||||
|
* path="/getBookmarks",
|
||||||
|
* security={{"basicAuth":{}}},
|
||||||
|
* tags={"bookmarks"},
|
||||||
|
* summary="Get user's bookmarks",
|
||||||
|
* description="Returns all bookmarks associated with the authenticated user.",
|
||||||
|
* @SWG\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="List of bookmarks"
|
||||||
|
* ),
|
||||||
|
* @SWG\Response(
|
||||||
|
* response=401,
|
||||||
|
* description="Unauthorized"
|
||||||
|
* )
|
||||||
|
* )
|
||||||
*/
|
*/
|
||||||
public function getBookmarks()
|
public function getBookmarks()
|
||||||
{
|
{
|
||||||
@@ -63,6 +100,31 @@ class Bookmark extends FHCAPI_Controller
|
|||||||
* deletes bookmark from associated user
|
* deletes bookmark from associated user
|
||||||
* @access public
|
* @access public
|
||||||
* @return void
|
* @return void
|
||||||
|
* @SWG\Post(
|
||||||
|
* path="/delete/{bookmark_id}",
|
||||||
|
* security={{"basicAuth":{}}},
|
||||||
|
* tags={"bookmarks"},
|
||||||
|
* summary="Delete a bookmark",
|
||||||
|
* description="Deletes a bookmark if the user is the owner or an admin.",
|
||||||
|
* @SWG\Parameter(
|
||||||
|
* name="bookmark_id",
|
||||||
|
* in="path",
|
||||||
|
* required=true,
|
||||||
|
* type="integer"
|
||||||
|
* ),
|
||||||
|
* @SWG\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Bookmark deleted successfully"
|
||||||
|
* ),
|
||||||
|
* @SWG\Response(
|
||||||
|
* response=403,
|
||||||
|
* description="Forbidden - not the owner"
|
||||||
|
* ),
|
||||||
|
* @SWG\Response(
|
||||||
|
* response=404,
|
||||||
|
* description="Bookmark not found"
|
||||||
|
* )
|
||||||
|
* )
|
||||||
*/
|
*/
|
||||||
public function delete($bookmark_id)
|
public function delete($bookmark_id)
|
||||||
{
|
{
|
||||||
@@ -87,6 +149,44 @@ class Bookmark extends FHCAPI_Controller
|
|||||||
* inserts new bookmark into the bookmark table
|
* inserts new bookmark into the bookmark table
|
||||||
* @access public
|
* @access public
|
||||||
* @return void
|
* @return void
|
||||||
|
* @SWG\Post(
|
||||||
|
* path="/insert",
|
||||||
|
* security={{"basicAuth":{}}},
|
||||||
|
* tags={"bookmarks"},
|
||||||
|
* summary="Insert a new bookmark",
|
||||||
|
* @SWG\Parameter(
|
||||||
|
* name="body",
|
||||||
|
* in="body",
|
||||||
|
* required=true,
|
||||||
|
* @SWG\Schema(
|
||||||
|
* type="object",
|
||||||
|
* required={"url", "title"},
|
||||||
|
* @SWG\Property(
|
||||||
|
* property="url",
|
||||||
|
* type="string",
|
||||||
|
* example="https://github.com/swagger-api/swagger-codegen"
|
||||||
|
* ),
|
||||||
|
* @SWG\Property(
|
||||||
|
* property="title",
|
||||||
|
* type="string",
|
||||||
|
* example="Swagger Codegen"
|
||||||
|
* ),
|
||||||
|
* @SWG\Property(
|
||||||
|
* property="tag",
|
||||||
|
* type="string",
|
||||||
|
* example="API"
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
* ),
|
||||||
|
* @SWG\Response(
|
||||||
|
* response=201,
|
||||||
|
* description="Bookmark created"
|
||||||
|
* ),
|
||||||
|
* @SWG\Response(
|
||||||
|
* response=400,
|
||||||
|
* description="Validation error"
|
||||||
|
* )
|
||||||
|
* )
|
||||||
*/
|
*/
|
||||||
public function insert()
|
public function insert()
|
||||||
{
|
{
|
||||||
@@ -109,9 +209,47 @@ class Bookmark extends FHCAPI_Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* updates bookmark in the bookmark table
|
* @SWG\Post(
|
||||||
* @access public
|
* path="/update/{bookmark_id}",
|
||||||
* @return void
|
* security={{"basicAuth":{}}},
|
||||||
|
* tags={"bookmarks"},
|
||||||
|
* summary="Update a bookmark",
|
||||||
|
* description="Updates a bookmark's URL and title for the given ID.",
|
||||||
|
* @SWG\Parameter(
|
||||||
|
* name="bookmark_id",
|
||||||
|
* in="path",
|
||||||
|
* required=true,
|
||||||
|
* type="integer",
|
||||||
|
* description="ID of the bookmark to update"
|
||||||
|
* ),
|
||||||
|
* @SWG\Parameter(
|
||||||
|
* name="body",
|
||||||
|
* in="body",
|
||||||
|
* required=true,
|
||||||
|
* @SWG\Schema(
|
||||||
|
* type="object",
|
||||||
|
* required={"url", "title"},
|
||||||
|
* @SWG\Property(
|
||||||
|
* property="url",
|
||||||
|
* type="string",
|
||||||
|
* example="https://updated-url.com"
|
||||||
|
* ),
|
||||||
|
* @SWG\Property(
|
||||||
|
* property="title",
|
||||||
|
* type="string",
|
||||||
|
* example="Updated Title"
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
* ),
|
||||||
|
* @SWG\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Bookmark updated"
|
||||||
|
* ),
|
||||||
|
* @SWG\Response(
|
||||||
|
* response=400,
|
||||||
|
* description="Validation error"
|
||||||
|
* )
|
||||||
|
* )
|
||||||
*/
|
*/
|
||||||
public function update($bookmark_id)
|
public function update($bookmark_id)
|
||||||
{
|
{
|
||||||
|
|||||||
+2
-1
@@ -481,6 +481,7 @@
|
|||||||
"phpmd/phpmd": "2.*",
|
"phpmd/phpmd": "2.*",
|
||||||
"phpmetrics/phpmetrics": "2.*",
|
"phpmetrics/phpmetrics": "2.*",
|
||||||
"sebastian/phpcpd": "3.*",
|
"sebastian/phpcpd": "3.*",
|
||||||
"phpunit/phpunit": "^6"
|
"phpunit/phpunit": "^6",
|
||||||
|
"zircote/swagger-php": "^2.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
-13
@@ -1,13 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
|
||||||
<phpunit bootstrap="index.ci.php">
|
|
||||||
<testsuites>
|
|
||||||
<testsuite name="UnitTests">
|
|
||||||
<directory>system/UnitTests/vertragsbestandteil/gui</directory>
|
|
||||||
</testsuite>
|
|
||||||
</testsuites>
|
|
||||||
<php>
|
|
||||||
<ini name="display_errors" value="1"/>
|
|
||||||
<ini name="display_startup_errors" value="1" />
|
|
||||||
<const name="PHPUNIT_TEST" value="1" />
|
|
||||||
</php>
|
|
||||||
</phpunit>
|
|
||||||
@@ -8,7 +8,7 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
delete: function (bookmark_id) {
|
delete: function (bookmark_id) {
|
||||||
return this.$fhcApi.get(
|
return this.$fhcApi.post(
|
||||||
`/api/frontend/v1/Bookmark/delete/${bookmark_id}`
|
`/api/frontend/v1/Bookmark/delete/${bookmark_id}`
|
||||||
,{}
|
,{}
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ export default {
|
|||||||
},
|
},
|
||||||
delete(bookmark_id) {
|
delete(bookmark_id) {
|
||||||
return {
|
return {
|
||||||
method: 'get',
|
method: 'post',
|
||||||
url: `/api/frontend/v1/Bookmark/delete/${bookmark_id}`
|
url: `/api/frontend/v1/Bookmark/delete/${bookmark_id}`
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -0,0 +1,123 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
function lineBreak()
|
||||||
|
{
|
||||||
|
return IS_CLI ? PHP_EOL : '<br>';
|
||||||
|
}
|
||||||
|
|
||||||
|
function preFormat($text)
|
||||||
|
{
|
||||||
|
if (IS_CLI) {
|
||||||
|
return $text; // Plain text in CLI
|
||||||
|
} else {
|
||||||
|
return "<pre>$text</pre>"; // HTML preformatted in browser
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function colorText($text, $color)
|
||||||
|
{
|
||||||
|
if (IS_CLI) {
|
||||||
|
// ANSI color codes
|
||||||
|
$colors = [
|
||||||
|
'red' => "\033[31m",
|
||||||
|
'green' => "\033[32m",
|
||||||
|
'reset' => "\033[0m",
|
||||||
|
];
|
||||||
|
return $colors[$color] . $text . $colors['reset'];
|
||||||
|
} else {
|
||||||
|
// HTML styles
|
||||||
|
$styles = [
|
||||||
|
'red' => "<b style='color:red;'>$text</b>",
|
||||||
|
'green' => "<b style='color:green;'>$text</b>",
|
||||||
|
];
|
||||||
|
return $styles[$color];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function assertEqual($expected, $actual, $message = '')
|
||||||
|
{
|
||||||
|
if ($expected !== $actual) {
|
||||||
|
echo colorText('❌ Assertion failed:', 'red') . ' ' . $message . lineBreak();
|
||||||
|
echo "Expected: " . preFormat(var_export($expected, true)) . lineBreak();
|
||||||
|
echo "Actual: " . preFormat(var_export($actual, true)) . lineBreak();
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
echo colorText('✅ Passed:', 'green') . ' ' . $message . lineBreak();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function assertTrue($condition, $message = '')
|
||||||
|
{
|
||||||
|
return assertEqual(true, $condition, $message ?: 'Expected condition to be true');
|
||||||
|
}
|
||||||
|
|
||||||
|
function assertFalse($condition, $message = '')
|
||||||
|
{
|
||||||
|
return assertEqual(false, $condition, $message ?: 'Expected condition to be false');
|
||||||
|
}
|
||||||
|
|
||||||
|
function assertNull($value, $message = '')
|
||||||
|
{
|
||||||
|
return assertEqual(null, $value, $message ?: 'Expected value to be null');
|
||||||
|
}
|
||||||
|
|
||||||
|
function assertNotNull($value, $message = '')
|
||||||
|
{
|
||||||
|
if ($value === null) {
|
||||||
|
echo colorText('❌ Assertion failed:', 'red') . ' ' . $message . lineBreak();
|
||||||
|
echo 'Value is null' . lineBreak();
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
echo colorText('✅ Passed:', 'green') . ' ' . $message . lineBreak();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function assertIsArray($value, $message = '')
|
||||||
|
{
|
||||||
|
return assertEqual(true, is_array($value), $message ?: 'Expected value to be an array');
|
||||||
|
}
|
||||||
|
|
||||||
|
function assertIsObject($value, $message = '')
|
||||||
|
{
|
||||||
|
return assertEqual(true, is_object($value), $message ?: 'Expected value to be an object');
|
||||||
|
}
|
||||||
|
|
||||||
|
function assertIsString($value, $message = '')
|
||||||
|
{
|
||||||
|
return assertEqual(true, is_string($value), $message ?: 'Expected value to be a string');
|
||||||
|
}
|
||||||
|
|
||||||
|
function assertIsInt($value, $message = '')
|
||||||
|
{
|
||||||
|
return assertEqual(true, is_int($value), $message ?: 'Expected value to be an integer');
|
||||||
|
}
|
||||||
|
|
||||||
|
function assertIsFloat($value, $message = '')
|
||||||
|
{
|
||||||
|
return assertEqual(true, is_float($value), $message ?: 'Expected value to be a float');
|
||||||
|
}
|
||||||
|
|
||||||
|
function assertIsBool($value, $message = '')
|
||||||
|
{
|
||||||
|
return assertEqual(true, is_bool($value), $message ?: 'Expected value to be a boolean');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function assertArrayHasKey($key, $array, $message = '')
|
||||||
|
{
|
||||||
|
return assertEqual(true, array_key_exists($key, $array), $message ?: "Expected key '$key' in array");
|
||||||
|
}
|
||||||
|
|
||||||
|
function assertObjectHasProperty($property, $object, $message = '')
|
||||||
|
{
|
||||||
|
return assertEqual(true, property_exists($object, $property), $message ?: "Expected property '$property' in object");
|
||||||
|
}
|
||||||
|
|
||||||
|
function assertCount($expectedCount, $arrayOrCountable, $message = '')
|
||||||
|
{
|
||||||
|
return assertEqual($expectedCount, count($arrayOrCountable), $message ?: "Expected count of $expectedCount");
|
||||||
|
}
|
||||||
@@ -0,0 +1,214 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
function getParam($name, $default = null)
|
||||||
|
{
|
||||||
|
if (php_sapi_name() === 'cli') { // Parse CLI args for --key=value style
|
||||||
|
// php ./system/UnitTests/api/BookmarkTest/BookmarkTest.php
|
||||||
|
// --server=https://cis40.dev.technikum-wien.at --user=if23b236 --pw=FHCompleteDemo42!
|
||||||
|
|
||||||
|
global $argv;
|
||||||
|
foreach ($argv as $arg) {
|
||||||
|
if (strpos($arg, '--' . $name . '=') === 0) {
|
||||||
|
return substr($arg, strlen($name) + 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $default;
|
||||||
|
} else {// Browser: use $_GET
|
||||||
|
// https://c3p0.ma0646.technikum-wien.at/fhcompletecis4/system/UnitTests/api/BookmarkTest
|
||||||
|
// /BookmarkTest.php?server=https://c3p0.ma0646.technikum-wien.at&user=if23b236&pw=FHCompleteDemo42!
|
||||||
|
return isset($_GET[$name]) ? $_GET[$name] : $default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
define('IS_CLI', php_sapi_name() === 'cli');
|
||||||
|
define('LINE_BREAK', IS_CLI ? PHP_EOL : '<br>');
|
||||||
|
define('PROJECT_ROOT', realpath(__DIR__ . '/../../../../'));
|
||||||
|
|
||||||
|
echo "Test Suite Bookmark start".LINE_BREAK;
|
||||||
|
if (!IS_CLI) echo "<pre>";
|
||||||
|
require_once(PROJECT_ROOT . '/config/cis.config.inc.php');
|
||||||
|
require_once(PROJECT_ROOT . '/vendor/nategood/httpful/bootstrap.php');
|
||||||
|
require_once(PROJECT_ROOT . '/system/UnitTests/AssertionHelpers.php');
|
||||||
|
echo "Requirements loaded".LINE_BREAK;
|
||||||
|
|
||||||
|
$server = getParam('server', APP_ROOT);
|
||||||
|
echo $server.LINE_BREAK;
|
||||||
|
$TEST_USER = getParam('user', 'defaultuser'); //if23b236
|
||||||
|
echo $TEST_USER.LINE_BREAK;
|
||||||
|
$TEST_PW = getParam('pw', 'defaultpass'); //FHCompleteDemo42!
|
||||||
|
echo $TEST_PW.LINE_BREAK;
|
||||||
|
|
||||||
|
// "Unit Test" Script to Test API Controller frontend/v1/Bookmark.php by calling methods with curated inputs and checking
|
||||||
|
// for the expected output
|
||||||
|
$URL = $server.'/cis.php/api/frontend/v1/Bookmark/';
|
||||||
|
|
||||||
|
testGetBookmarks($URL, 'getBookmarks', $TEST_USER, $TEST_PW);
|
||||||
|
$id = testInsertBookmark($URL, 'insert', $TEST_USER, $TEST_PW);
|
||||||
|
$id = testUpdateBookmark($URL, 'update', $TEST_USER, $TEST_PW, $id);
|
||||||
|
testDeleteBookmark($URL, 'delete', $TEST_USER, $TEST_PW, $id);
|
||||||
|
if (!IS_CLI) echo "<pre>";
|
||||||
|
|
||||||
|
function testGetBookmarks($url, $method, $user, $pw)
|
||||||
|
{
|
||||||
|
echo LINE_BREAK.LINE_BREAK."Test '".$method."' start ".LINE_BREAK;
|
||||||
|
|
||||||
|
try {
|
||||||
|
$resultPost = \Httpful\Request::get($url.$method)
|
||||||
|
->expectsJson()
|
||||||
|
->authenticateWith($user, $pw)
|
||||||
|
->send();
|
||||||
|
} catch(\Httpful\Exception\ConnectionErrorException $cee) // Httpful exception
|
||||||
|
{
|
||||||
|
echo $cee;
|
||||||
|
}
|
||||||
|
catch (Exception $e) // any other exception
|
||||||
|
{
|
||||||
|
echo $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
$assertions = [];
|
||||||
|
|
||||||
|
$assertions[] = assertIsArray($resultPost->body->data);
|
||||||
|
$assertions[] = assertIsString($resultPost->body->meta->status);
|
||||||
|
$assertions[] = assertEqual($resultPost->body->meta->status, "success", "Response Status Success");
|
||||||
|
|
||||||
|
if(allTrue($assertions)) {
|
||||||
|
echo "Test '".$method."' finished SUCCESS".LINE_BREAK;
|
||||||
|
} else {
|
||||||
|
echo "Test '".$method."' finished FAIL".LINE_BREAK;
|
||||||
|
printResponse($resultPost);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function testInsertBookmark($url, $method, $user, $pw)
|
||||||
|
{
|
||||||
|
echo LINE_BREAK.LINE_BREAK."Test '".$method."' start ".LINE_BREAK;
|
||||||
|
echo LINE_BREAK;
|
||||||
|
try {
|
||||||
|
$bodyTitle = 'orf';
|
||||||
|
$bodyUrl = 'https://orf.at';
|
||||||
|
|
||||||
|
$resultPost = \Httpful\Request::post($url.$method)
|
||||||
|
->expectsJson()
|
||||||
|
->authenticateWith($user, $pw)
|
||||||
|
->sendsJson()
|
||||||
|
->body('{"title": "'.$bodyTitle.'", "url": "'.$bodyUrl.'"}')
|
||||||
|
->send();
|
||||||
|
} catch(\Httpful\Exception\ConnectionErrorException $cee) // Httpful exception
|
||||||
|
{
|
||||||
|
echo $cee;
|
||||||
|
}
|
||||||
|
catch (Exception $e) // any other exception
|
||||||
|
{
|
||||||
|
echo $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
$assertions = [];
|
||||||
|
$assertions[] = assertIsInt($resultPost->body->data);
|
||||||
|
$assertions[] = assertIsString($resultPost->body->meta->status);
|
||||||
|
$assertions[] = assertEqual("success", $resultPost->body->meta->status, "Response Status Success");
|
||||||
|
if(allTrue($assertions)) {
|
||||||
|
echo "Test '".$method."' finished SUCCESS".LINE_BREAK;
|
||||||
|
} else {
|
||||||
|
echo "Test '".$method."' finished FAIL".LINE_BREAK;
|
||||||
|
printResponse($resultPost);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $resultPost->body->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
function testDeleteBookmark($url, $method, $user, $pw, $id)
|
||||||
|
{
|
||||||
|
echo LINE_BREAK.LINE_BREAK."Test '".$method."' start ".LINE_BREAK;
|
||||||
|
|
||||||
|
try {
|
||||||
|
$resultPost = \Httpful\Request::post($url.$method.'/'.$id)
|
||||||
|
->expectsJson()
|
||||||
|
->authenticateWith($user, $pw)
|
||||||
|
->sendsJson()
|
||||||
|
->send();
|
||||||
|
} catch(\Httpful\Exception\ConnectionErrorException $cee) // Httpful exception
|
||||||
|
{
|
||||||
|
echo $cee;
|
||||||
|
}
|
||||||
|
catch (Exception $e) // any other exception
|
||||||
|
{
|
||||||
|
echo $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
$assertions = [];
|
||||||
|
$assertions[] = assertIsString($resultPost->body->data);
|
||||||
|
$assertions[] = assertIsString($resultPost->body->meta->status);
|
||||||
|
$assertions[] = assertEqual("success", $resultPost->body->meta->status, "Response Status Success");
|
||||||
|
if(allTrue($assertions)) {
|
||||||
|
echo "Test '".$method."' finished SUCCESS".LINE_BREAK;
|
||||||
|
} else {
|
||||||
|
echo "Test '".$method."' finished FAIL".LINE_BREAK;
|
||||||
|
printResponse($resultPost);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function testUpdateBookmark($url, $method, $user, $pw, $id)
|
||||||
|
{
|
||||||
|
echo LINE_BREAK.LINE_BREAK."Test '".$method."' start ".LINE_BREAK;
|
||||||
|
|
||||||
|
try {
|
||||||
|
$bodyTitle = 'orf title updated';
|
||||||
|
$bodyUrl = 'https://orf.at';
|
||||||
|
|
||||||
|
$resultPost = \Httpful\Request::post($url.$method.'/'.$id)
|
||||||
|
->expectsJson()
|
||||||
|
->authenticateWith($user, $pw)
|
||||||
|
->body('{"title": "'.$bodyTitle.'", "url": "'.$bodyUrl.'"}')
|
||||||
|
->sendsJson()
|
||||||
|
->send();
|
||||||
|
} catch(\Httpful\Exception\ConnectionErrorException $cee) // Httpful exception
|
||||||
|
{
|
||||||
|
echo $cee;
|
||||||
|
}
|
||||||
|
catch (Exception $e) // any other exception
|
||||||
|
{
|
||||||
|
echo $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
$assertions = [];
|
||||||
|
$assertions[] = assertIsString($resultPost->body->data);
|
||||||
|
$assertions[] = assertIsString($resultPost->body->meta->status);
|
||||||
|
$assertions[] = assertEqual("success", $resultPost->body->meta->status, "Response Status Success");
|
||||||
|
if(allTrue($assertions)) {
|
||||||
|
echo "Test '".$method."' finished SUCCESS".LINE_BREAK;
|
||||||
|
} else {
|
||||||
|
echo "Test '".$method."' finished FAIL".LINE_BREAK;
|
||||||
|
printResponse($resultPost);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $resultPost->body->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
function printResponse($resultPost)
|
||||||
|
{
|
||||||
|
echo LINE_BREAK;
|
||||||
|
echo "Response Body:";
|
||||||
|
echo preFormat(var_export($resultPost->body, true));
|
||||||
|
echo LINE_BREAK;
|
||||||
|
echo "Raw Response:";
|
||||||
|
echo preFormat(var_export($resultPost->raw_body, true));
|
||||||
|
echo LINE_BREAK;
|
||||||
|
echo "Status Code:";
|
||||||
|
echo preFormat(var_export($resultPost->code, true));
|
||||||
|
echo LINE_BREAK;
|
||||||
|
echo "Headers:";
|
||||||
|
echo preFormat(var_export($resultPost->headers, true));
|
||||||
|
echo LINE_BREAK;
|
||||||
|
}
|
||||||
|
|
||||||
|
function allTrue($arr)
|
||||||
|
{
|
||||||
|
return count(array_filter($arr, function ($v) {
|
||||||
|
return $v === true;
|
||||||
|
})) === count($arr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,143 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Verifies that properties are declared correctly.
|
|
||||||
*
|
|
||||||
* NOTE: It simply overrides the method processMemberVar of the Standards\PSR2\Sniffs\Classes\PropertyDeclarationSniff class
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace PHP_CodeSniffer\Standards\FHComplete\Sniffs\Classes;
|
|
||||||
|
|
||||||
use PHP_CodeSniffer\Files\File;
|
|
||||||
use PHP_CodeSniffer\Sniffs\AbstractVariableSniff;
|
|
||||||
use PHP_CodeSniffer\Util\Tokens;
|
|
||||||
use PHP_CodeSniffer\Standards\PSR2\Sniffs\Classes\PropertyDeclarationSniff;
|
|
||||||
|
|
||||||
class FHCPropertyDeclarationSniff extends PropertyDeclarationSniff
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Processes the function tokens within the class.
|
|
||||||
*
|
|
||||||
* NOTE: it does not check if the property name starts with an underscore "_"
|
|
||||||
*
|
|
||||||
* @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found.
|
|
||||||
* @param int $stackPtr The position where the token was found.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function processMemberVar(File $phpcsFile, $stackPtr)
|
|
||||||
{
|
|
||||||
$tokens = $phpcsFile->getTokens();
|
|
||||||
|
|
||||||
// Detect multiple properties defined at the same time. Throw an error
|
|
||||||
// for this, but also only process the first property in the list so we don't
|
|
||||||
// repeat errors.
|
|
||||||
$find = Tokens::$scopeModifiers;
|
|
||||||
$find[] = T_VARIABLE;
|
|
||||||
$find[] = T_VAR;
|
|
||||||
$find[] = T_SEMICOLON;
|
|
||||||
$find[] = T_OPEN_CURLY_BRACKET;
|
|
||||||
|
|
||||||
$prev = $phpcsFile->findPrevious($find, ($stackPtr - 1));
|
|
||||||
if ($tokens[$prev]['code'] === T_VARIABLE) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($tokens[$prev]['code'] === T_VAR) {
|
|
||||||
$error = 'The var keyword must not be used to declare a property';
|
|
||||||
$phpcsFile->addError($error, $stackPtr, 'VarUsed');
|
|
||||||
}
|
|
||||||
|
|
||||||
$next = $phpcsFile->findNext([T_VARIABLE, T_SEMICOLON], ($stackPtr + 1));
|
|
||||||
if ($next !== false && $tokens[$next]['code'] === T_VARIABLE) {
|
|
||||||
$error = 'There must not be more than one property declared per statement';
|
|
||||||
$phpcsFile->addError($error, $stackPtr, 'Multiple');
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
$propertyInfo = $phpcsFile->getMemberProperties($stackPtr);
|
|
||||||
if (empty($propertyInfo) === true) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
// Turns out not to be a property after all.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($propertyInfo['type'] !== '') {
|
|
||||||
$typeToken = $propertyInfo['type_end_token'];
|
|
||||||
$error = 'There must be 1 space after the property type declaration; %s found';
|
|
||||||
if ($tokens[($typeToken + 1)]['code'] !== T_WHITESPACE) {
|
|
||||||
$data = ['0'];
|
|
||||||
$fix = $phpcsFile->addFixableError($error, $typeToken, 'SpacingAfterType', $data);
|
|
||||||
if ($fix === true) {
|
|
||||||
$phpcsFile->fixer->addContent($typeToken, ' ');
|
|
||||||
}
|
|
||||||
} else if ($tokens[($typeToken + 1)]['content'] !== ' ') {
|
|
||||||
$next = $phpcsFile->findNext(T_WHITESPACE, ($typeToken + 1), null, true);
|
|
||||||
if ($tokens[$next]['line'] !== $tokens[$typeToken]['line']) {
|
|
||||||
$found = 'newline';
|
|
||||||
} else {
|
|
||||||
$found = $tokens[($typeToken + 1)]['length'];
|
|
||||||
}
|
|
||||||
|
|
||||||
$data = [$found];
|
|
||||||
|
|
||||||
$nextNonWs = $phpcsFile->findNext(Tokens::$emptyTokens, ($typeToken + 1), null, true);
|
|
||||||
if ($nextNonWs !== $next) {
|
|
||||||
$phpcsFile->addError($error, $typeToken, 'SpacingAfterType', $data);
|
|
||||||
} else {
|
|
||||||
$fix = $phpcsFile->addFixableError($error, $typeToken, 'SpacingAfterType', $data);
|
|
||||||
if ($fix === true) {
|
|
||||||
if ($found === 'newline') {
|
|
||||||
$phpcsFile->fixer->beginChangeset();
|
|
||||||
for ($x = ($typeToken + 1); $x < $next; $x++) {
|
|
||||||
$phpcsFile->fixer->replaceToken($x, '');
|
|
||||||
}
|
|
||||||
|
|
||||||
$phpcsFile->fixer->addContent($typeToken, ' ');
|
|
||||||
$phpcsFile->fixer->endChangeset();
|
|
||||||
} else {
|
|
||||||
$phpcsFile->fixer->replaceToken(($typeToken + 1), ' ');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}//end if
|
|
||||||
}//end if
|
|
||||||
|
|
||||||
if ($propertyInfo['scope_specified'] === false) {
|
|
||||||
$error = 'Visibility must be declared on property "%s"';
|
|
||||||
$data = [$tokens[$stackPtr]['content']];
|
|
||||||
$phpcsFile->addError($error, $stackPtr, 'ScopeMissing', $data);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($propertyInfo['scope_specified'] === true && $propertyInfo['is_static'] === true) {
|
|
||||||
$scopePtr = $phpcsFile->findPrevious(Tokens::$scopeModifiers, ($stackPtr - 1));
|
|
||||||
$staticPtr = $phpcsFile->findPrevious(T_STATIC, ($stackPtr - 1));
|
|
||||||
if ($scopePtr < $staticPtr) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$error = 'The static declaration must come after the visibility declaration';
|
|
||||||
$fix = $phpcsFile->addFixableError($error, $stackPtr, 'StaticBeforeVisibility');
|
|
||||||
if ($fix === true) {
|
|
||||||
$phpcsFile->fixer->beginChangeset();
|
|
||||||
|
|
||||||
for ($i = ($scopePtr + 1); $scopePtr < $stackPtr; $i++) {
|
|
||||||
if ($tokens[$i]['code'] !== T_WHITESPACE) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
$phpcsFile->fixer->replaceToken($i, '');
|
|
||||||
}
|
|
||||||
|
|
||||||
$phpcsFile->fixer->replaceToken($scopePtr, '');
|
|
||||||
$phpcsFile->fixer->addContentBefore($staticPtr, $propertyInfo['scope'].' ');
|
|
||||||
|
|
||||||
$phpcsFile->fixer->endChangeset();
|
|
||||||
}
|
|
||||||
}//end if
|
|
||||||
|
|
||||||
}//end processMemberVar()
|
|
||||||
}//end class
|
|
||||||
|
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Ensures classes are in camel caps, and the first letter is capitalised.
|
|
||||||
*
|
|
||||||
* NOTE:
|
|
||||||
* - it simply overrides the method process of the Standards\Squiz\Sniffs\Classes\ValidClassNameSniff class
|
|
||||||
* - it contains a new implementation of PHP_CodeSniffer\Util\Common::isCamelCaps
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace PHP_CodeSniffer\Standards\FHComplete\Sniffs\Classes;
|
|
||||||
|
|
||||||
use PHP_CodeSniffer\Files\File;
|
|
||||||
use PHP_CodeSniffer\Sniffs\Sniff;
|
|
||||||
use PHP_CodeSniffer\Util\Common;
|
|
||||||
use PHP_CodeSniffer\Standards\Squiz\Sniffs\Classes\ValidClassNameSniff;
|
|
||||||
|
|
||||||
class FHCValidClassNameSniff extends ValidClassNameSniff
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Processes this test, when one of its tokens is encountered.
|
|
||||||
*
|
|
||||||
* NOTE: it does not check if the class name contains an underscore "_"
|
|
||||||
*
|
|
||||||
* @param \PHP_CodeSniffer\Files\File $phpcsFile The current file being processed.
|
|
||||||
* @param int $stackPtr The position of the current token in the
|
|
||||||
* stack passed in $tokens.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function process(File $phpcsFile, $stackPtr)
|
|
||||||
{
|
|
||||||
$tokens = $phpcsFile->getTokens();
|
|
||||||
|
|
||||||
if (isset($tokens[$stackPtr]['scope_opener']) === false) {
|
|
||||||
$error = 'Possible parse error: %s missing opening or closing brace';
|
|
||||||
$data = [$tokens[$stackPtr]['content']];
|
|
||||||
$phpcsFile->addWarning($error, $stackPtr, 'MissingBrace', $data);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Determine the name of the class or interface. Note that we cannot
|
|
||||||
// simply look for the first T_STRING because a class name
|
|
||||||
// starting with the number will be multiple tokens.
|
|
||||||
$opener = $tokens[$stackPtr]['scope_opener'];
|
|
||||||
$nameStart = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), $opener, true);
|
|
||||||
$nameEnd = $phpcsFile->findNext(T_WHITESPACE, $nameStart, $opener);
|
|
||||||
if ($nameEnd === false) {
|
|
||||||
$name = $tokens[$nameStart]['content'];
|
|
||||||
} else {
|
|
||||||
$name = trim($phpcsFile->getTokensAsString($nameStart, ($nameEnd - $nameStart)));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for PascalCase format.
|
|
||||||
$valid = $this->isCamelCaps($name);
|
|
||||||
if ($valid === false) {
|
|
||||||
$type = ucfirst($tokens[$stackPtr]['content']);
|
|
||||||
$error = '%s name "%s" is not in PascalCase format';
|
|
||||||
$data = [
|
|
||||||
$type,
|
|
||||||
$name,
|
|
||||||
];
|
|
||||||
$phpcsFile->addError($error, $stackPtr, 'NotCamelCaps', $data);
|
|
||||||
$phpcsFile->recordMetric($stackPtr, 'PascalCase class name', 'no');
|
|
||||||
} else {
|
|
||||||
$phpcsFile->recordMetric($stackPtr, 'PascalCase class name', 'yes');
|
|
||||||
}
|
|
||||||
|
|
||||||
}//end process()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if the specified string is in the camel caps format.
|
|
||||||
*
|
|
||||||
* NOTE:
|
|
||||||
* - it does not allow the string to start with an underscore "_"
|
|
||||||
* - it does allow that the string contains an underscore "_"
|
|
||||||
* - the string must starts with a capitol letter
|
|
||||||
*
|
|
||||||
* @param string $string The string the verify.
|
|
||||||
*
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
private function isCamelCaps($string)
|
|
||||||
{
|
|
||||||
$legalFirstChar = '[A-Z]';
|
|
||||||
|
|
||||||
if (preg_match("/^$legalFirstChar/", $string) === 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check that the name only contains legal characters.
|
|
||||||
$legalChars = 'a-zA-Z0-9_';
|
|
||||||
if (preg_match("|[^$legalChars]|", substr($string, 1)) > 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
|
|
||||||
}//end isCamelCaps()
|
|
||||||
}//end class
|
|
||||||
|
|
||||||
@@ -1,154 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Verifies that control statements conform to their coding standards.
|
|
||||||
*
|
|
||||||
* NOTE: It simply overrides the method process of the PHP_CodeSniffer\Standards\Squiz\Sniffs\ControlStructures\ControlSignatureSniff class
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace PHP_CodeSniffer\Standards\FHComplete\Sniffs\ControlStructures;
|
|
||||||
|
|
||||||
use PHP_CodeSniffer\Files\File;
|
|
||||||
use PHP_CodeSniffer\Sniffs\Sniff;
|
|
||||||
use PHP_CodeSniffer\Util\Tokens;
|
|
||||||
use PHP_CodeSniffer\Standards\Squiz\Sniffs\ControlStructures\ControlSignatureSniff;
|
|
||||||
|
|
||||||
class FHCControlSignatureSniff extends ControlSignatureSniff
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Processes this test, when one of its tokens is encountered.
|
|
||||||
*
|
|
||||||
* NOTE:
|
|
||||||
* - Does not force to have whitespaces after the brackets
|
|
||||||
* - Allows to have a bracket at newline after a control structure, ex:
|
|
||||||
*
|
|
||||||
* if (condition)
|
|
||||||
* {
|
|
||||||
*
|
|
||||||
* @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.
|
|
||||||
* @param int $stackPtr The position of the current token in the
|
|
||||||
* stack passed in $tokens.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function process(File $phpcsFile, $stackPtr)
|
|
||||||
{
|
|
||||||
$tokens = $phpcsFile->getTokens();
|
|
||||||
|
|
||||||
$nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true);
|
|
||||||
if ($nextNonEmpty === false) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$isAlternative = false;
|
|
||||||
if (isset($tokens[$stackPtr]['scope_opener']) === true
|
|
||||||
&& $tokens[$tokens[$stackPtr]['scope_opener']]['code'] === T_COLON
|
|
||||||
) {
|
|
||||||
$isAlternative = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Single newline after opening brace.
|
|
||||||
if (isset($tokens[$stackPtr]['scope_opener']) === true) {
|
|
||||||
$opener = $tokens[$stackPtr]['scope_opener'];
|
|
||||||
for ($next = ($opener + 1); $next < $phpcsFile->numTokens; $next++) {
|
|
||||||
$code = $tokens[$next]['code'];
|
|
||||||
|
|
||||||
if ($code === T_WHITESPACE
|
|
||||||
|| ($code === T_INLINE_HTML
|
|
||||||
&& trim($tokens[$next]['content']) === '')
|
|
||||||
) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Skip all empty tokens on the same line as the opener.
|
|
||||||
if ($tokens[$next]['line'] === $tokens[$opener]['line']
|
|
||||||
&& (isset(Tokens::$emptyTokens[$code]) === true
|
|
||||||
|| $code === T_CLOSE_TAG)
|
|
||||||
) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We found the first bit of a code, or a comment on the
|
|
||||||
// following line.
|
|
||||||
break;
|
|
||||||
}//end for
|
|
||||||
|
|
||||||
if ($tokens[$next]['line'] === $tokens[$opener]['line']) {
|
|
||||||
$error = 'Newline required after opening brace';
|
|
||||||
$fix = $phpcsFile->addFixableError($error, $opener, 'NewlineAfterOpenBrace');
|
|
||||||
if ($fix === true) {
|
|
||||||
$phpcsFile->fixer->beginChangeset();
|
|
||||||
for ($i = ($opener + 1); $i < $next; $i++) {
|
|
||||||
if (trim($tokens[$i]['content']) !== '') {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove whitespace.
|
|
||||||
$phpcsFile->fixer->replaceToken($i, '');
|
|
||||||
}
|
|
||||||
|
|
||||||
$phpcsFile->fixer->addContent($opener, $phpcsFile->eolChar);
|
|
||||||
$phpcsFile->fixer->endChangeset();
|
|
||||||
}
|
|
||||||
}//end if
|
|
||||||
} else if ($tokens[$stackPtr]['code'] === T_WHILE) {
|
|
||||||
// Zero spaces after parenthesis closer, but only if followed by a semicolon.
|
|
||||||
$closer = $tokens[$stackPtr]['parenthesis_closer'];
|
|
||||||
$nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($closer + 1), null, true);
|
|
||||||
if ($nextNonEmpty !== false && $tokens[$nextNonEmpty]['code'] === T_SEMICOLON) {
|
|
||||||
$found = 0;
|
|
||||||
if ($tokens[($closer + 1)]['code'] === T_WHITESPACE) {
|
|
||||||
if (strpos($tokens[($closer + 1)]['content'], $phpcsFile->eolChar) !== false) {
|
|
||||||
$found = 'newline';
|
|
||||||
} else {
|
|
||||||
$found = $tokens[($closer + 1)]['length'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($found !== 0) {
|
|
||||||
$error = 'Expected 0 spaces before semicolon; %s found';
|
|
||||||
$data = [$found];
|
|
||||||
$fix = $phpcsFile->addFixableError($error, $closer, 'SpaceBeforeSemicolon', $data);
|
|
||||||
if ($fix === true) {
|
|
||||||
$phpcsFile->fixer->replaceToken(($closer + 1), '');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}//end if
|
|
||||||
|
|
||||||
// Only want to check multi-keyword structures from here on.
|
|
||||||
if ($tokens[$stackPtr]['code'] === T_WHILE) {
|
|
||||||
if (isset($tokens[$stackPtr]['scope_closer']) !== false) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$closer = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true);
|
|
||||||
if ($closer === false
|
|
||||||
|| $tokens[$closer]['code'] !== T_CLOSE_CURLY_BRACKET
|
|
||||||
|| $tokens[$tokens[$closer]['scope_condition']]['code'] !== T_DO
|
|
||||||
) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else if ($tokens[$stackPtr]['code'] === T_ELSE
|
|
||||||
|| $tokens[$stackPtr]['code'] === T_ELSEIF
|
|
||||||
|| $tokens[$stackPtr]['code'] === T_CATCH
|
|
||||||
|| $tokens[$stackPtr]['code'] === T_FINALLY
|
|
||||||
) {
|
|
||||||
if (isset($tokens[$stackPtr]['scope_opener']) === true
|
|
||||||
&& $tokens[$tokens[$stackPtr]['scope_opener']]['code'] === T_COLON
|
|
||||||
) {
|
|
||||||
// Special case for alternate syntax, where this token is actually
|
|
||||||
// the closer for the previous block, so there is no spacing to check.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$closer = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true);
|
|
||||||
if ($closer === false || $tokens[$closer]['code'] !== T_CLOSE_CURLY_BRACKET) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}//end if
|
|
||||||
}//end process()
|
|
||||||
}//end class
|
|
||||||
|
|
||||||
@@ -1,129 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Checks that the method declaration is correct.
|
|
||||||
*
|
|
||||||
* NOTE: It simply overrides the method processTokenWithinScope of the Standards\PSR2\Sniffs\Methods\MethodDeclarationSniff class
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace PHP_CodeSniffer\Standards\FHComplete\Sniffs\Methods;
|
|
||||||
|
|
||||||
use PHP_CodeSniffer\Files\File;
|
|
||||||
use PHP_CodeSniffer\Sniffs\AbstractScopeSniff;
|
|
||||||
use PHP_CodeSniffer\Util\Tokens;
|
|
||||||
use PHP_CodeSniffer\Standards\PSR2\Sniffs\Methods\MethodDeclarationSniff;
|
|
||||||
|
|
||||||
class FHCMethodDeclarationSniff extends MethodDeclarationSniff
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Processes the function tokens within the class.
|
|
||||||
*
|
|
||||||
* NOTE: it does not check if the method name starts with an underscore "_"
|
|
||||||
*
|
|
||||||
* @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found.
|
|
||||||
* @param int $stackPtr The position where the token was found.
|
|
||||||
* @param int $currScope The current scope opener token.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function processTokenWithinScope(File $phpcsFile, $stackPtr, $currScope)
|
|
||||||
{
|
|
||||||
$tokens = $phpcsFile->getTokens();
|
|
||||||
|
|
||||||
// Determine if this is a function which needs to be examined.
|
|
||||||
$conditions = $tokens[$stackPtr]['conditions'];
|
|
||||||
end($conditions);
|
|
||||||
$deepestScope = key($conditions);
|
|
||||||
if ($deepestScope !== $currScope) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$methodName = $phpcsFile->getDeclarationName($stackPtr);
|
|
||||||
if ($methodName === null) {
|
|
||||||
// Ignore closures.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$visibility = 0;
|
|
||||||
$static = 0;
|
|
||||||
$abstract = 0;
|
|
||||||
$final = 0;
|
|
||||||
|
|
||||||
$find = (Tokens::$methodPrefixes + Tokens::$emptyTokens);
|
|
||||||
$prev = $phpcsFile->findPrevious($find, ($stackPtr - 1), null, true);
|
|
||||||
|
|
||||||
$prefix = $stackPtr;
|
|
||||||
while (($prefix = $phpcsFile->findPrevious(Tokens::$methodPrefixes, ($prefix - 1), $prev)) !== false) {
|
|
||||||
switch ($tokens[$prefix]['code']) {
|
|
||||||
case T_STATIC:
|
|
||||||
$static = $prefix;
|
|
||||||
break;
|
|
||||||
case T_ABSTRACT:
|
|
||||||
$abstract = $prefix;
|
|
||||||
break;
|
|
||||||
case T_FINAL:
|
|
||||||
$final = $prefix;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$visibility = $prefix;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$fixes = [];
|
|
||||||
|
|
||||||
if ($visibility !== 0 && $final > $visibility) {
|
|
||||||
$error = 'The final declaration must precede the visibility declaration';
|
|
||||||
$fix = $phpcsFile->addFixableError($error, $final, 'FinalAfterVisibility');
|
|
||||||
if ($fix === true) {
|
|
||||||
$fixes[$final] = '';
|
|
||||||
$fixes[($final + 1)] = '';
|
|
||||||
if (isset($fixes[$visibility]) === true) {
|
|
||||||
$fixes[$visibility] = 'final '.$fixes[$visibility];
|
|
||||||
} else {
|
|
||||||
$fixes[$visibility] = 'final '.$tokens[$visibility]['content'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($visibility !== 0 && $abstract > $visibility) {
|
|
||||||
$error = 'The abstract declaration must precede the visibility declaration';
|
|
||||||
$fix = $phpcsFile->addFixableError($error, $abstract, 'AbstractAfterVisibility');
|
|
||||||
if ($fix === true) {
|
|
||||||
$fixes[$abstract] = '';
|
|
||||||
$fixes[($abstract + 1)] = '';
|
|
||||||
if (isset($fixes[$visibility]) === true) {
|
|
||||||
$fixes[$visibility] = 'abstract '.$fixes[$visibility];
|
|
||||||
} else {
|
|
||||||
$fixes[$visibility] = 'abstract '.$tokens[$visibility]['content'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($static !== 0 && $static < $visibility) {
|
|
||||||
$error = 'The static declaration must come after the visibility declaration';
|
|
||||||
$fix = $phpcsFile->addFixableError($error, $static, 'StaticBeforeVisibility');
|
|
||||||
if ($fix === true) {
|
|
||||||
$fixes[$static] = '';
|
|
||||||
$fixes[($static + 1)] = '';
|
|
||||||
if (isset($fixes[$visibility]) === true) {
|
|
||||||
$fixes[$visibility] .= ' static';
|
|
||||||
} else {
|
|
||||||
$fixes[$visibility] = $tokens[$visibility]['content'].' static';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Batch all the fixes together to reduce the possibility of conflicts.
|
|
||||||
if (empty($fixes) === false) {
|
|
||||||
$phpcsFile->fixer->beginChangeset();
|
|
||||||
foreach ($fixes as $stackPtr => $content) {
|
|
||||||
$phpcsFile->fixer->replaceToken($stackPtr, $content);
|
|
||||||
}
|
|
||||||
|
|
||||||
$phpcsFile->fixer->endChangeset();
|
|
||||||
}
|
|
||||||
|
|
||||||
}//end processTokenWithinScope()
|
|
||||||
}//end class
|
|
||||||
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
<?xml version="1.0"?>
|
|
||||||
<ruleset name="FHComplete">
|
|
||||||
<description>FHComplete's coding standard</description>
|
|
||||||
|
|
||||||
<!-- Ignored directories -->
|
|
||||||
<exclude-pattern>\.git</exclude-pattern>
|
|
||||||
<exclude-pattern>vendor</exclude-pattern>
|
|
||||||
<exclude-pattern>tests</exclude-pattern>
|
|
||||||
<exclude-pattern>application/controllers/api/v1</exclude-pattern>
|
|
||||||
<exclude-pattern>application/extensions</exclude-pattern>
|
|
||||||
<exclude-pattern>addons</exclude-pattern>
|
|
||||||
|
|
||||||
<!-- This ruleset is based mainly on the PSR2 standard ruleset, exluding the following rules: -->
|
|
||||||
<rule ref="PSR2">
|
|
||||||
<!-- Forces the use of namespaces -->
|
|
||||||
<exclude name="PSR1.Classes.ClassDeclaration" />
|
|
||||||
<!-- Forbids the use of underscores at the beginning of properties name -->
|
|
||||||
<exclude name="PSR2.Classes.PropertyDeclaration" />
|
|
||||||
<!-- Forbids the use of classes name that contain underscores -->
|
|
||||||
<exclude name="Squiz.Classes.ValidClassName" />
|
|
||||||
<!-- Forbids the use inline control structure (ex. an if statement on one line) -->
|
|
||||||
<exclude name="Generic.ControlStructures.InlineControlStructure" />
|
|
||||||
<!-- Forces to have the bracket on the same line of the statement -->
|
|
||||||
<exclude name="Squiz.ControlStructures.ControlSignature" />
|
|
||||||
<!-- Forces to have in a single file only a class declaration, an if statement outside the class is forbidden -->
|
|
||||||
<exclude name="PSR1.Files.SideEffects" />
|
|
||||||
<!-- Forbids to have an empty line at the end of the file -->
|
|
||||||
<exclude name="PSR2.Files.EndFileNewline" />
|
|
||||||
<!-- Forbids the use of underscores at the beginning of methods name -->
|
|
||||||
<exclude name="PSR2.Methods.MethodDeclaration" />
|
|
||||||
<!-- Forbids the use of tabs -->
|
|
||||||
<exclude name="Generic.WhiteSpace.DisallowTabIndent" />
|
|
||||||
</rule>
|
|
||||||
|
|
||||||
<!-- Do not prompt any warning about the line length -->
|
|
||||||
<!-- Prompt an error if the line length is more than 150 -->
|
|
||||||
<rule ref="Generic.Files.LineLength">
|
|
||||||
<properties>
|
|
||||||
<property name="lineLimit" value="9999"/>
|
|
||||||
<property name="absoluteLineLimit" value="150"/>
|
|
||||||
</properties>
|
|
||||||
<exclude-pattern>application/phrases/</exclude-pattern>
|
|
||||||
</rule>
|
|
||||||
|
|
||||||
<!-- No white spaces are allowed in array declaration between brackets -->
|
|
||||||
<rule ref="Squiz.Arrays.ArrayBracketSpacing"/>
|
|
||||||
|
|
||||||
<!-- Ensures all class keywords are lowercase -->
|
|
||||||
<rule ref="Squiz.Classes.LowercaseClassKeywords"/>
|
|
||||||
|
|
||||||
<!-- Forbids the use of TODO in the comments -->
|
|
||||||
<rule ref="Generic.Commenting.Todo"/>
|
|
||||||
<!-- Tests that the stars in a doc comment align correctly -->
|
|
||||||
<rule ref="Squiz.Commenting.DocCommentAlignment"/>
|
|
||||||
|
|
||||||
<!-- Ensures the file ends with a newline character -->
|
|
||||||
<rule ref="Generic.Files.EndFileNewline"/>
|
|
||||||
|
|
||||||
<!-- Ensures there is no space after cast tokens -->
|
|
||||||
<rule ref="Generic.Formatting.NoSpaceAfterCast"/>
|
|
||||||
|
|
||||||
<!-- Ensures logical operators 'and' and 'or' are not used -->
|
|
||||||
<rule ref="Squiz.Operators.ValidLogicalOperators"/>
|
|
||||||
|
|
||||||
<!-- Ensure cast statements don't contain whitespace -->
|
|
||||||
<rule ref="Squiz.WhiteSpace.CastSpacing"/>
|
|
||||||
<!-- Verifies that operators have valid spacing surrounding them -->
|
|
||||||
<rule ref="Squiz.WhiteSpace.LogicalOperatorSpacing"/>
|
|
||||||
<!-- Checks that control structures are defined and indented correctly -->
|
|
||||||
<!-- The listed tokens are ignored: comment, doc comment open tag, php close tag -->
|
|
||||||
<rule ref="Generic.WhiteSpace.ScopeIndent">
|
|
||||||
<properties>
|
|
||||||
<property name="ignoreIndentationTokens" type="array">
|
|
||||||
<element value="T_COMMENT"/>
|
|
||||||
<element value="T_DOC_COMMENT_OPEN_TAG"/>
|
|
||||||
<element value="T_CLOSE_TAG"/>
|
|
||||||
</property>
|
|
||||||
</properties>
|
|
||||||
</rule>
|
|
||||||
<!-- Ensure there is no whitespace before a semicolon -->
|
|
||||||
<rule ref="Squiz.WhiteSpace.SemicolonSpacing"/>
|
|
||||||
|
|
||||||
<!-- All rules in ./Sniffs are included automatically -->
|
|
||||||
<!-- FHComplete sniffs:
|
|
||||||
- Classes/FHCPropertyDeclarationSniff: class properties checks, it does not check if the property name starts with an underscore "_"
|
|
||||||
- Classes/FHCValidClassNameSniff: class names checks, it does not check if the class name contains an underscore "_"
|
|
||||||
- ControlStructures/FHCControlSignatureSniff:
|
|
||||||
- Does not force to have whitespaces after the brackets
|
|
||||||
- Allows to have a bracket at newline after a control structure
|
|
||||||
- Methods/FHCMethodDeclarationSniff: it does not check if the method name starts with an underscore "_"
|
|
||||||
-->
|
|
||||||
</ruleset>
|
|
||||||
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
<?xml version="1.0"?>
|
|
||||||
<ruleset name="Strictly necessary PHPMD rule set"
|
|
||||||
xmlns="http://pmd.sf.net/ruleset/1.0.0"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd"
|
|
||||||
xsi:noNamespaceSchemaLocation=" http://pmd.sf.net/ruleset_xml_schema.xsd">
|
|
||||||
|
|
||||||
<description>
|
|
||||||
Performs the DevelopmentCodeFragment check before the code can be merged into the main branch and then deployed to production
|
|
||||||
</description>
|
|
||||||
|
|
||||||
<!-- Ignored directories -->
|
|
||||||
<exclude-pattern>\.git</exclude-pattern>
|
|
||||||
<exclude-pattern>vendor</exclude-pattern>
|
|
||||||
<exclude-pattern>tests</exclude-pattern>
|
|
||||||
<exclude-pattern>application/controllers/api/v1</exclude-pattern>
|
|
||||||
<exclude-pattern>application/extensions</exclude-pattern>
|
|
||||||
<exclude-pattern>addons</exclude-pattern>
|
|
||||||
|
|
||||||
<!-- Import the DevelopmentCodeFragment rule from the design rule set -->
|
|
||||||
<rule ref="rulesets/design.xml/DevelopmentCodeFragment" />
|
|
||||||
</ruleset>
|
|
||||||
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
<?xml version="1.0"?>
|
|
||||||
<ruleset name="Strictly necessary PHPMD rule set"
|
|
||||||
xmlns="http://pmd.sf.net/ruleset/1.0.0"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd"
|
|
||||||
xsi:noNamespaceSchemaLocation=" http://pmd.sf.net/ruleset_xml_schema.xsd">
|
|
||||||
|
|
||||||
<description>
|
|
||||||
Performs the strictly necessary checks before the code can be merged into the main branch and then deployed to production
|
|
||||||
</description>
|
|
||||||
|
|
||||||
<!-- Ignored directories -->
|
|
||||||
<exclude-pattern>\.git</exclude-pattern>
|
|
||||||
<exclude-pattern>vendor</exclude-pattern>
|
|
||||||
<exclude-pattern>tests</exclude-pattern>
|
|
||||||
<exclude-pattern>application/controllers/api/v1</exclude-pattern>
|
|
||||||
<exclude-pattern>application/extensions</exclude-pattern>
|
|
||||||
<exclude-pattern>addons</exclude-pattern>
|
|
||||||
|
|
||||||
<!-- Import the clean code rule set -->
|
|
||||||
<rule ref="rulesets/cleancode.xml">
|
|
||||||
<!-- Exclude the ElseExpression rule -->
|
|
||||||
<exclude name="ElseExpression" />
|
|
||||||
</rule>
|
|
||||||
<!-- Import the entire unused code rule set -->
|
|
||||||
<rule ref="rulesets/unusedcode.xml" />
|
|
||||||
<!-- Import the DevelopmentCodeFragment rule from the design rule set -->
|
|
||||||
<rule ref="rulesets/design.xml/DevelopmentCodeFragment" />
|
|
||||||
</ruleset>
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user