From 5bff584246f6143a5fa1e17cf2a990e85f40f5f4 Mon Sep 17 00:00:00 2001 From: Steve Boyd Date: Wed, 13 Apr 2022 13:42:48 +1200 Subject: [PATCH] ENH PHP 8.1 compatibility --- src/DataFormatter.php | 15 ++++---- .../FormEncodedDataFormatter.php | 2 +- src/DataFormatter/JSONDataFormatter.php | 14 ++++---- src/DataFormatter/XMLDataFormatter.php | 20 +++++------ src/RestfulServer.php | 36 +++++++++---------- tests/unit/RestfulServerTest.php | 18 +++++----- .../RestfulServerTestValidationFailure.php | 4 +-- 7 files changed, 56 insertions(+), 53 deletions(-) diff --git a/src/DataFormatter.php b/src/DataFormatter.php index b0da40a..97d6bdb 100644 --- a/src/DataFormatter.php +++ b/src/DataFormatter.php @@ -103,7 +103,7 @@ abstract class DataFormatter */ protected function sanitiseClassName($className) { - return str_replace('\\', '-', $className); + return str_replace('\\', '-', $className ?? ''); } /** @@ -123,7 +123,7 @@ abstract class DataFormatter arsort($sortedClasses); foreach ($sortedClasses as $className => $priority) { $formatter = new $className(); - if (in_array($extension, $formatter->supportedExtensions())) { + if (in_array($extension, $formatter->supportedExtensions() ?? [])) { return $formatter; } } @@ -163,7 +163,7 @@ abstract class DataFormatter arsort($sortedClasses); foreach ($sortedClasses as $className => $priority) { $formatter = new $className(); - if (in_array($mimeType, $formatter->supportedMimeTypes())) { + if (in_array($mimeType, $formatter->supportedMimeTypes() ?? [])) { return $formatter; } } @@ -329,7 +329,10 @@ abstract class DataFormatter $dbFields = array_merge($dbFields, ['ID' => 'Int']); if (is_array($this->removeFields)) { - $dbFields = array_diff_key($dbFields, array_combine($this->removeFields, $this->removeFields)); + $dbFields = array_diff_key( + $dbFields ?? [], + array_combine($this->removeFields ?? [], $this->removeFields ?? []) + ); } return $dbFields; @@ -418,7 +421,7 @@ abstract class DataFormatter public function getFieldAlias($className, $field) { $apiMapping = $this->getApiMapping($className); - $apiMapping = array_flip($apiMapping); + $apiMapping = array_flip($apiMapping ?? []); return $this->getMappedKey($apiMapping, $field); } @@ -448,7 +451,7 @@ abstract class DataFormatter protected function getMappedKey($map, $key) { if (is_array($map)) { - if (array_key_exists($key, $map)) { + if (array_key_exists($key, $map ?? [])) { return $map[$key]; } else { return $key; diff --git a/src/DataFormatter/FormEncodedDataFormatter.php b/src/DataFormatter/FormEncodedDataFormatter.php index c1b7882..b136f47 100644 --- a/src/DataFormatter/FormEncodedDataFormatter.php +++ b/src/DataFormatter/FormEncodedDataFormatter.php @@ -35,7 +35,7 @@ class FormEncodedDataFormatter extends XMLDataFormatter public function convertStringToArray($strData) { $postArray = array(); - parse_str($strData, $postArray); + parse_str($strData ?? '', $postArray); return $postArray; //TODO: It would be nice to implement this function in Convert.php //return Convert::querystr2array($strData); diff --git a/src/DataFormatter/JSONDataFormatter.php b/src/DataFormatter/JSONDataFormatter.php index 0ff743d..561a47b 100644 --- a/src/DataFormatter/JSONDataFormatter.php +++ b/src/DataFormatter/JSONDataFormatter.php @@ -86,7 +86,7 @@ class JSONDataFormatter extends DataFormatter foreach ($this->getFieldsForObj($obj) as $fieldName => $fieldType) { // Field filtering - if ($fields && !in_array($fieldName, $fields)) { + if ($fields && !in_array($fieldName, $fields ?? [])) { continue; } @@ -102,10 +102,10 @@ class JSONDataFormatter extends DataFormatter } // Field filtering - if ($fields && !in_array($relName, $fields)) { + if ($fields && !in_array($relName, $fields ?? [])) { continue; } - if ($this->customRelations && !in_array($relName, $this->customRelations)) { + if ($this->customRelations && !in_array($relName, $this->customRelations ?? [])) { continue; } if ($obj->$relName() && (!$obj->$relName()->exists() || !$obj->$relName()->canView())) { @@ -129,7 +129,7 @@ class JSONDataFormatter extends DataFormatter $relClass = RestfulServer::parseRelationClass($relClass); //remove dot notation from relation names - $parts = explode('.', $relClass); + $parts = explode('.', $relClass ?? ''); $relClass = array_shift($parts); if (!singleton($relClass)->stat('api_access')) { @@ -137,10 +137,10 @@ class JSONDataFormatter extends DataFormatter } // Field filtering - if ($fields && !in_array($relName, $fields)) { + if ($fields && !in_array($relName, $fields ?? [])) { continue; } - if ($this->customRelations && !in_array($relName, $this->customRelations)) { + if ($this->customRelations && !in_array($relName, $this->customRelations ?? [])) { continue; } @@ -195,7 +195,7 @@ class JSONDataFormatter extends DataFormatter */ public function convertStringToArray($strData) { - return json_decode($strData, true); + return json_decode($strData ?? '', true); } public static function cast(FieldType\DBField $dbfield) diff --git a/src/DataFormatter/XMLDataFormatter.php b/src/DataFormatter/XMLDataFormatter.php index 8908ff9..42be941 100644 --- a/src/DataFormatter/XMLDataFormatter.php +++ b/src/DataFormatter/XMLDataFormatter.php @@ -121,7 +121,7 @@ class XMLDataFormatter extends DataFormatter $xml = "<$className href=\"$objHref.xml\">\n"; foreach ($this->getFieldsForObj($obj) as $fieldName => $fieldType) { // Field filtering - if ($fields && !in_array($fieldName, $fields)) { + if ($fields && !in_array($fieldName, $fields ?? [])) { continue; } $fieldValue = $obj->obj($fieldName)->forTemplate(); @@ -134,7 +134,7 @@ class XMLDataFormatter extends DataFormatter } else { if ('HTMLText' == $fieldType) { // Escape HTML values using CDATA - $fieldValue = sprintf('', str_replace(']]>', ']]]]>', $fieldValue)); + $fieldValue = sprintf('', str_replace(']]>', ']]]]>', $fieldValue ?? '')); } else { $fieldValue = Convert::raw2xml($fieldValue); } @@ -150,10 +150,10 @@ class XMLDataFormatter extends DataFormatter } // Field filtering - if ($fields && !in_array($relName, $fields)) { + if ($fields && !in_array($relName, $fields ?? [])) { continue; } - if ($this->customRelations && !in_array($relName, $this->customRelations)) { + if ($this->customRelations && !in_array($relName, $this->customRelations ?? [])) { continue; } @@ -169,7 +169,7 @@ class XMLDataFormatter extends DataFormatter foreach ($obj->hasMany() as $relName => $relClass) { //remove dot notation from relation names - $parts = explode('.', $relClass); + $parts = explode('.', $relClass ?? ''); $relClass = array_shift($parts); if (!singleton($relClass)->stat('api_access')) { continue; @@ -178,10 +178,10 @@ class XMLDataFormatter extends DataFormatter $relClass = $this->sanitiseClassName($relClass); // Field filtering - if ($fields && !in_array($relName, $fields)) { + if ($fields && !in_array($relName, $fields ?? [])) { continue; } - if ($this->customRelations && !in_array($relName, $this->customRelations)) { + if ($this->customRelations && !in_array($relName, $this->customRelations ?? [])) { continue; } @@ -200,7 +200,7 @@ class XMLDataFormatter extends DataFormatter $relClass = RestfulServer::parseRelationClass($relClass); //remove dot notation from relation names - $parts = explode('.', $relClass); + $parts = explode('.', $relClass ?? ''); $relClass = array_shift($parts); if (!singleton($relClass)->stat('api_access')) { continue; @@ -209,10 +209,10 @@ class XMLDataFormatter extends DataFormatter $relClass = $this->sanitiseClassName($relClass); // Field filtering - if ($fields && !in_array($relName, $fields)) { + if ($fields && !in_array($relName, $fields ?? [])) { continue; } - if ($this->customRelations && !in_array($relName, $this->customRelations)) { + if ($this->customRelations && !in_array($relName, $this->customRelations ?? [])) { continue; } diff --git a/src/RestfulServer.php b/src/RestfulServer.php index ffccf0f..873021f 100644 --- a/src/RestfulServer.php +++ b/src/RestfulServer.php @@ -138,7 +138,7 @@ class RestfulServer extends Controller */ protected function sanitiseClassName($className) { - return str_replace('\\', '-', $className); + return str_replace('\\', '-', $className ?? ''); } /** @@ -150,7 +150,7 @@ class RestfulServer extends Controller */ protected function unsanitiseClassName($className) { - return str_replace('-', '\\', $className); + return str_replace('-', '\\', $className ?? ''); } /** @@ -163,13 +163,13 @@ class RestfulServer extends Controller { // detect many many through syntax if (is_array($class) - && array_key_exists('through', $class) - && array_key_exists('to', $class) + && array_key_exists('through', $class ?? []) + && array_key_exists('to', $class ?? []) ) { $toRelation = $class['to']; $hasOne = Config::inst()->get($class['through'], 'has_one'); - if (empty($hasOne) || !is_array($hasOne) || !array_key_exists($toRelation, $hasOne)) { + if (empty($hasOne) || !is_array($hasOne) || !array_key_exists($toRelation, $hasOne ?? [])) { return $class; } @@ -190,14 +190,14 @@ class RestfulServer extends Controller $relation = $request->param('Relation') ?: null; // Check input formats - if (!class_exists($className)) { + if (!class_exists($className ?? '')) { return $this->notFound(); } if ($id && !is_numeric($id)) { return $this->notFound(); } if ($relation - && !preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', $relation) + && !preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', $relation ?? '') ) { return $this->notFound(); } @@ -326,7 +326,7 @@ class RestfulServer extends Controller $this->getResponse()->addHeader('Content-Type', $responseFormatter->getOutputContentType()); $rawFields = $this->request->getVar('fields'); - $realFields = $responseFormatter->getRealFields($className, explode(',', $rawFields)); + $realFields = $responseFormatter->getRealFields($className, explode(',', $rawFields ?? '')); $fields = $rawFields ? $realFields : null; if ($obj instanceof SS_List) { @@ -391,7 +391,7 @@ class RestfulServer extends Controller { $extension = $this->request->getExtension(); $contentTypeWithEncoding = $this->request->getHeader('Content-Type'); - preg_match('/([^;]*)/', $contentTypeWithEncoding, $contentTypeMatches); + preg_match('/([^;]*)/', $contentTypeWithEncoding ?? '', $contentTypeMatches); $contentType = $contentTypeMatches[0]; $accept = $this->request->getHeader('Accept'); $mimetypes = $this->request->getAcceptMimetypes(); @@ -402,7 +402,7 @@ class RestfulServer extends Controller // get formatter if (!empty($extension)) { $formatter = DataFormatter::for_extension($extension); - } elseif ($includeAcceptHeader && !empty($accept) && strpos($accept, '*/*') === false) { + } elseif ($includeAcceptHeader && !empty($accept) && strpos($accept ?? '', '*/*') === false) { $formatter = DataFormatter::for_mimetypes($mimetypes); if (!$formatter) { $formatter = DataFormatter::for_extension($this->config()->default_extension); @@ -419,11 +419,11 @@ class RestfulServer extends Controller // set custom fields if ($customAddFields = $this->request->getVar('add_fields')) { - $customAddFields = $formatter->getRealFields($className, explode(',', $customAddFields)); + $customAddFields = $formatter->getRealFields($className, explode(',', $customAddFields ?? '')); $formatter->setCustomAddFields($customAddFields); } if ($customFields = $this->request->getVar('fields')) { - $customFields = $formatter->getRealFields($className, explode(',', $customFields)); + $customFields = $formatter->getRealFields($className, explode(',', $customFields ?? '')); $formatter->setCustomFields($customFields); } $formatter->setCustomRelations($this->getAllowedRelations($className)); @@ -537,7 +537,7 @@ class RestfulServer extends Controller // or else we'll use the default (XML) $types = $responseFormatter->supportedExtensions(); $type = ''; - if (count($types)) { + if (count($types ?? [])) { $type = ".{$types[0]}"; } @@ -581,7 +581,7 @@ class RestfulServer extends Controller } if (!Config::inst()->get($className, 'allowed_actions') || - !in_array($relation, Config::inst()->get($className, 'allowed_actions'))) { + !in_array($relation, Config::inst()->get($className, 'allowed_actions') ?? [])) { return $this->permissionFailure(); } @@ -622,7 +622,7 @@ class RestfulServer extends Controller // or else we'll use the default (XML) $types = $responseFormatter->supportedExtensions(); $type = ''; - if (count($types)) { + if (count($types ?? [])) { $type = ".{$types[0]}"; } @@ -675,11 +675,11 @@ class RestfulServer extends Controller } // @todo Disallow editing of certain keys in database - $data = array_diff_key($data, ['ID', 'Created']); + $data = array_diff_key($data ?? [], ['ID', 'Created']); $apiAccess = singleton($className)->config()->api_access; if (is_array($apiAccess) && isset($apiAccess['edit'])) { - $data = array_intersect_key($data, array_combine($apiAccess['edit'], $apiAccess['edit'])); + $data = array_intersect_key($data ?? [], array_combine($apiAccess['edit'] ?? [], $apiAccess['edit'] ?? [])); } $obj->update($data); @@ -878,7 +878,7 @@ class RestfulServer extends Controller $relClass = static::parseRelationClass($relClass); //remove dot notation from relation names - $parts = explode('.', $relClass); + $parts = explode('.', $relClass ?? ''); $relClass = array_shift($parts); if (Config::inst()->get($relClass, 'api_access')) { $allowedRelations[] = $relName; diff --git a/tests/unit/RestfulServerTest.php b/tests/unit/RestfulServerTest.php index 004caa8..8591f6d 100644 --- a/tests/unit/RestfulServerTest.php +++ b/tests/unit/RestfulServerTest.php @@ -46,7 +46,7 @@ class RestfulServerTest extends SapphireTest protected function urlSafeClassname($classname) { - return str_replace('\\', '-', $classname); + return str_replace('\\', '-', $classname ?? ''); } protected function setUp(): void @@ -168,7 +168,7 @@ class RestfulServerTest extends SapphireTest $responseArr = Convert::xml2array($response->getBody()); $xmlTagSafeClassName = $this->urlSafeClassname(RestfulServerTestAuthorRating::class); $ratingsArr = $responseArr['Ratings'][$xmlTagSafeClassName]; - $this->assertEquals(2, count($ratingsArr)); + $this->assertEquals(2, count($ratingsArr ?? [])); $ratingIDs = array( (int)$ratingsArr[0]['@attributes']['id'], (int)$ratingsArr[1]['@attributes']['id'] @@ -195,8 +195,8 @@ class RestfulServerTest extends SapphireTest $responseArr = Convert::xml2array($response->getBody()); $xmlTagSafeClassName = $this->urlSafeClassname(RestfulServerTestAuthorRating::class); - $this->assertTrue(array_key_exists('Ratings', $responseArr)); - $this->assertFalse(array_key_exists('stars', $responseArr)); + $this->assertTrue(array_key_exists('Ratings', $responseArr ?? [])); + $this->assertFalse(array_key_exists('stars', $responseArr ?? [])); } public function testGETManyManyRelationshipsXML() @@ -214,7 +214,7 @@ class RestfulServerTest extends SapphireTest $xmlSafeClassName = $this->urlSafeClassname(RestfulServerTestAuthor::class); $authorsArr = $arr[$xmlSafeClassName]; - $this->assertEquals(2, count($authorsArr)); + $this->assertEquals(2, count($authorsArr ?? [])); $ratingIDs = array( (int)$authorsArr[0]['ID'], (int)$authorsArr[1]['ID'] @@ -307,7 +307,7 @@ class RestfulServerTest extends SapphireTest 'Accept' => 'application/json' )); $this->assertEquals(202, $response->getStatusCode()); // Accepted - $obj = json_decode($response->getBody()); + $obj = json_decode($response->getBody() ?? ''); $this->assertEquals($comment1->ID, $obj->ID); $this->assertEquals('updated', $obj->Comment); @@ -318,7 +318,7 @@ class RestfulServerTest extends SapphireTest $response = Director::test($url, null, null, 'PUT', $body); $this->assertEquals(202, $response->getStatusCode()); // Accepted $this->assertEquals($url, $response->getHeader('Location')); - $obj = json_decode($response->getBody()); + $obj = json_decode($response->getBody() ?? ''); $this->assertEquals($comment1->ID, $obj->ID); $this->assertEquals('updated', $obj->Comment); @@ -368,7 +368,7 @@ class RestfulServerTest extends SapphireTest $headers = array('Accept' => 'application/json'); $response = Director::test($url, null, null, 'GET', null, $headers); $this->assertEquals(200, $response->getStatusCode()); // Success - $obj = json_decode($response->getBody()); + $obj = json_decode($response->getBody() ?? ''); $this->assertEquals($comment1->ID, $obj->ID); $this->assertEquals('application/json', $response->getHeader('Content-Type')); } @@ -710,7 +710,7 @@ class RestfulServerTest extends SapphireTest $response = Director::test($url, null, null, 'GET'); $this->assertEquals(200, $response->getStatusCode()); $this->assertStringNotContainsString('Unspeakable', $response->getBody()); - $responseArray = json_decode($response->getBody(), true); + $responseArray = json_decode($response->getBody() ?? '', true); $this->assertSame(0, $responseArray['totalSize']); // With authentication diff --git a/tests/unit/Stubs/RestfulServerTestValidationFailure.php b/tests/unit/Stubs/RestfulServerTestValidationFailure.php index 32e1871..eedbf96 100644 --- a/tests/unit/Stubs/RestfulServerTestValidationFailure.php +++ b/tests/unit/Stubs/RestfulServerTestValidationFailure.php @@ -30,11 +30,11 @@ class RestfulServerTestValidationFailure extends DataObject implements TestOnly { $result = parent::validate(); - if (strlen($this->Content) === 0) { + if (strlen($this->Content ?? '') === 0) { $result->addFieldError('Content', 'Content required'); } - if (strlen($this->Title) === 0) { + if (strlen($this->Title ?? '') === 0) { $result->addFieldError('Title', 'Title required'); }