From 5f78b312c8ad82f91148d6bfe79c614651736161 Mon Sep 17 00:00:00 2001 From: Jan-Hendrik Willms <tleilax+studip@gmail.com> Date: Fri, 27 Sep 2024 11:50:34 +0000 Subject: [PATCH] fix errors found through static code analysis, fixes #4562 Closes #4562 Merge request studip/studip!3375 --- app/controllers/admin/courses.php | 2 +- app/controllers/admin/tree.php | 4 +-- app/controllers/course/admission.php | 4 +-- app/controllers/course/basicdata.php | 2 +- app/controllers/course/feedback.php | 1 - app/controllers/debugbar.php | 2 +- app/controllers/institute/basicdata.php | 2 +- app/controllers/resources/ajax.php | 2 +- lib/classes/AdminCourseFilter.php | 2 +- lib/classes/Avatar.php | 2 +- .../Middlewares/DangerousRouteHandler.php | 3 +- lib/classes/JsonApi/RouteMap.php | 2 +- .../Courseware/Rel/SolversOfTaskGroup.php | 1 + .../JsonApi/Routes/Feedback/RatingHelper.php | 1 + .../Routes/Files/FileRefsContentShow.php | 3 +- .../JsonApi/Routes/Holidays/HolidaysShow.php | 2 +- .../RangeTree/ChildrenOfRangeTreeNode.php | 3 +- lib/classes/OAuth2/NegotiatesWithPsr7.php | 5 +++ lib/classes/SQLQuery.php | 2 +- lib/classes/admission/CourseSet.php | 2 +- lib/classes/cache/Exception.php | 2 +- .../cache/InvalidCacheArgumentException.php | 2 +- lib/classes/calendar/ICalendarExport.php | 3 +- lib/classes/calendar/ICalendarImport.php | 34 ++++++++----------- lib/exTpl/IteratorNode.php | 3 ++ lib/exTpl/TemplateParserException.php | 2 +- lib/exceptions/FeatureDisabledException.php | 2 +- lib/helpers.php | 2 +- lib/ilias_interface/StudipSoapClient.php | 7 ++-- lib/models/Course.php | 6 ++-- lib/models/Courseware/StructuralElement.php | 4 +-- lib/models/ModuleManagementModel.php | 13 ++++--- lib/models/MvvFileRange.php | 2 +- lib/models/StudipCacheOperation.php | 7 ++-- lib/plugins/core/CorePlugin.php | 1 + phpstan.neon.dist | 14 ++++---- .../lib/flexi/PHPTemplatePartialBugTest.php | 2 ++ .../lib/flexi/TemplateMagicMethodsTest.php | 1 + 38 files changed, 84 insertions(+), 70 deletions(-) diff --git a/app/controllers/admin/courses.php b/app/controllers/admin/courses.php index 562a14bcb17..8a641901e73 100644 --- a/app/controllers/admin/courses.php +++ b/app/controllers/admin/courses.php @@ -490,7 +490,7 @@ class Admin_CoursesController extends AuthenticatedController $multimode = $plugin->useMultimode(); if ($multimode) { $data['buttons_top'] = '<label>'._('Alle auswählen').'<input type="checkbox" data-proxyfor=".course-admin td:last-child :checkbox"></label>'; - if ($multimode instanceof Flex\Template) { + if ($multimode instanceof Flexi\Template) { $data['buttons_bottom'] = $multimode->render(); } elseif ($multimode instanceof \Studip\Button) { $data['buttons_bottom'] = (string) $multimode; diff --git a/app/controllers/admin/tree.php b/app/controllers/admin/tree.php index 320f10efd9c..5d22775a385 100644 --- a/app/controllers/admin/tree.php +++ b/app/controllers/admin/tree.php @@ -192,9 +192,9 @@ class Admin_TreeController extends AuthenticatedController } if ($node->store() !== false) { - Pagelayout::postSuccess(_('Die Daten wurden gespeichert.')); + PageLayout::postSuccess(_('Die Daten wurden gespeichert.')); } else { - Pagelayout::postError(_('Die Daten konnten nicht gespeichert werden.')); + PageLayout::postError(_('Die Daten konnten nicht gespeichert werden.')); } $this->relocate(Request::get('from')); diff --git a/app/controllers/course/admission.php b/app/controllers/course/admission.php index 0b3755a1ea0..a2b7df4e689 100644 --- a/app/controllers/course/admission.php +++ b/app/controllers/course/admission.php @@ -169,10 +169,10 @@ class Course_AdmissionController extends AuthenticatedController continue; } $num_moved++; - setTempLanguage($user_id); + setTempLanguage($user->id); $message_body = sprintf(_('Sie wurden in der Veranstaltung **%s** in den Status **Autor** versetzt, da das Anmeldeverfahren geändert wurde.'), $this->course->name); $message_title = sprintf(_("Statusänderung %s"), $this->course->name); - messaging::sendSystemMessage($user_id, $message_title, $message_body); + messaging::sendSystemMessage($user, $message_title, $message_body); restoreLanguage(); } if ($num_moved) { diff --git a/app/controllers/course/basicdata.php b/app/controllers/course/basicdata.php index 114bcc8ee9f..04bf8fc7eaf 100644 --- a/app/controllers/course/basicdata.php +++ b/app/controllers/course/basicdata.php @@ -782,7 +782,7 @@ class Course_BasicdataController extends AuthenticatedController } else { $this->deleteUserFromCourse( Course::find($course_id), - User::find($teacher_id) + User::find($tutor_id) ); } diff --git a/app/controllers/course/feedback.php b/app/controllers/course/feedback.php index df600c7a1f5..903df17300e 100644 --- a/app/controllers/course/feedback.php +++ b/app/controllers/course/feedback.php @@ -72,7 +72,6 @@ class Course_FeedbackController extends AuthenticatedController 'results_visible' => 1, 'commentable' => 1, 'mode' => FeedbackElement::MODE_5STAR_RATING, - 'mode' => 1, 'anonymous_entries' => 1, ]); } diff --git a/app/controllers/debugbar.php b/app/controllers/debugbar.php index 59627f27964..9fc5286c693 100644 --- a/app/controllers/debugbar.php +++ b/app/controllers/debugbar.php @@ -1,5 +1,5 @@ <?php -final class DebugbarController extends Trails_Controller +final class DebugbarController extends Trails\Controller { public function __construct( Trails\Dispatcher $dispatcher, diff --git a/app/controllers/institute/basicdata.php b/app/controllers/institute/basicdata.php index 0b7c2960201..2f211c29ea9 100644 --- a/app/controllers/institute/basicdata.php +++ b/app/controllers/institute/basicdata.php @@ -426,7 +426,7 @@ class Institute_BasicdataController extends AuthenticatedController // delete all configuration files for the "extern modules" if (Config::get()->EXTERN_ENABLE) { - $counts = ExternConfig::DeleteAllConfigurations($i_id); + $counts = ExternPageConfig::deleteBySQL('range_id = ?', [$i_id]); if ($counts) { $details[] = sprintf(_('%u Konfigurationsdateien für externe Seiten gelöscht.'), $counts); } diff --git a/app/controllers/resources/ajax.php b/app/controllers/resources/ajax.php index cffd8783708..ebe0e107861 100644 --- a/app/controllers/resources/ajax.php +++ b/app/controllers/resources/ajax.php @@ -778,7 +778,7 @@ class Resources_AjaxController extends AuthenticatedController $semester = \Semester::findByTimestamp($timestamp); if (!$semester) { $this->notFound('No semester found for given timestamp'); - throw new RecordNotFoundException(); + return; } $timestamp = strtotime('today', $timestamp); diff --git a/lib/classes/AdminCourseFilter.php b/lib/classes/AdminCourseFilter.php index 0c0ec8deb33..bdb84d2871b 100644 --- a/lib/classes/AdminCourseFilter.php +++ b/lib/classes/AdminCourseFilter.php @@ -53,7 +53,7 @@ class AdminCourseFilter /** * Constructor of the singleton-object. */ - public function __construct(bool $reset_settings = false) + final public function __construct(bool $reset_settings = false) { $this->initSettings($reset_settings); } diff --git a/lib/classes/Avatar.php b/lib/classes/Avatar.php index d2dcd9d65c7..bb3a91564e7 100644 --- a/lib/classes/Avatar.php +++ b/lib/classes/Avatar.php @@ -197,7 +197,7 @@ class Avatar * @param string $user_id the user's id * @param string $username the user's username (optional) */ - protected function __construct($user_id, $username = null) + final protected function __construct($user_id, $username = null) { $this->user_id = $user_id; $this->username = $username; diff --git a/lib/classes/JsonApi/Middlewares/DangerousRouteHandler.php b/lib/classes/JsonApi/Middlewares/DangerousRouteHandler.php index d1112f838b5..54f21d53719 100644 --- a/lib/classes/JsonApi/Middlewares/DangerousRouteHandler.php +++ b/lib/classes/JsonApi/Middlewares/DangerousRouteHandler.php @@ -24,8 +24,7 @@ class DangerousRouteHandler if (\Config::get()->getValue('JSONAPI_DANGEROUS_ROUTES_ALLOWED')) { return $handler->handle($request); } - $response = new Response(); - return $response->withStatus(503)->write('Service Unavailable.'); + throw new \AccessDeniedException('Service unavailable'); } } diff --git a/lib/classes/JsonApi/RouteMap.php b/lib/classes/JsonApi/RouteMap.php index e9a0a011a88..4b61b3d2774 100644 --- a/lib/classes/JsonApi/RouteMap.php +++ b/lib/classes/JsonApi/RouteMap.php @@ -325,7 +325,7 @@ class RouteMap $group->get('/tree-node/{id}', Routes\Tree\TreeShow::class); $group->get('/tree-node/{id}/children', Routes\Tree\ChildrenOfTreeNode::class); - $group->get('/tree-node/{id}/courseinfo', Routes\Tree\CourseInfoOfTreeNode::class); + $group->get('/tree-node/{id}/courseinfo', Routes\Tree\CourseinfoOfTreeNode::class); $group->get('/tree-node/{id}/courses', Routes\Tree\CoursesOfTreeNode::class); $group->get('/tree-node/course/pathinfo/{classname}/{id}', Routes\Tree\PathinfoOfTreeNodeCourse::class); $group->get('/tree-node/course/details/{id}', Routes\Tree\DetailsOfTreeNodeCourse::class); diff --git a/lib/classes/JsonApi/Routes/Courseware/Rel/SolversOfTaskGroup.php b/lib/classes/JsonApi/Routes/Courseware/Rel/SolversOfTaskGroup.php index 2ab5ffa6da1..3d2a325b810 100644 --- a/lib/classes/JsonApi/Routes/Courseware/Rel/SolversOfTaskGroup.php +++ b/lib/classes/JsonApi/Routes/Courseware/Rel/SolversOfTaskGroup.php @@ -13,6 +13,7 @@ use JsonApi\Schemas\Courseware\TaskGroup as TaskGroupSchema; use JsonApi\Schemas\StatusGroup as StatusGroupSchema; use JsonApi\Schemas\User as UserSchema; use Psr\Http\Message\ServerRequestInterface as Request; +use RuntimeException; use Statusgruppen; use User; diff --git a/lib/classes/JsonApi/Routes/Feedback/RatingHelper.php b/lib/classes/JsonApi/Routes/Feedback/RatingHelper.php index 849cba73a7e..c258f7e5dac 100644 --- a/lib/classes/JsonApi/Routes/Feedback/RatingHelper.php +++ b/lib/classes/JsonApi/Routes/Feedback/RatingHelper.php @@ -3,6 +3,7 @@ namespace JsonApi\Routes\Feedback; use FeedbackElement; +use InvalidArgumentException; trait RatingHelper { diff --git a/lib/classes/JsonApi/Routes/Files/FileRefsContentShow.php b/lib/classes/JsonApi/Routes/Files/FileRefsContentShow.php index 69f71ec6362..6cb6ef3a131 100644 --- a/lib/classes/JsonApi/Routes/Files/FileRefsContentShow.php +++ b/lib/classes/JsonApi/Routes/Files/FileRefsContentShow.php @@ -6,6 +6,7 @@ use JsonApi\Errors\AuthorizationFailedException; use JsonApi\Errors\InternalServerError; use JsonApi\Errors\RecordNotFoundException; use JsonApi\NonJsonApiController; +use Psr\Container\ContainerInterface; use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ServerRequestInterface as Request; use Psr\Http\Message\StreamFactoryInterface; @@ -72,7 +73,7 @@ class FileRefsContentShow extends NonJsonApiController ); } - list($done, $response) = $this->handleEtag($request, $response, $fileRef); + [$done, $response] = $this->handleEtag($request, $response, $fileRef); if ($done) { return $response; } diff --git a/lib/classes/JsonApi/Routes/Holidays/HolidaysShow.php b/lib/classes/JsonApi/Routes/Holidays/HolidaysShow.php index a587dcae487..eb413d02d95 100644 --- a/lib/classes/JsonApi/Routes/Holidays/HolidaysShow.php +++ b/lib/classes/JsonApi/Routes/Holidays/HolidaysShow.php @@ -96,7 +96,7 @@ final class HolidaysShow extends NonJsonApiController $errors = new ErrorCollection(); // Get filters - $filters = $this->query_parser->getFilteringParameters(); + $filters = $this->queryParser->getFilteringParameters(); // Validate allowed filters foreach ($filters as $key => $value) { diff --git a/lib/classes/JsonApi/Routes/RangeTree/ChildrenOfRangeTreeNode.php b/lib/classes/JsonApi/Routes/RangeTree/ChildrenOfRangeTreeNode.php index 8773c0a5b60..58fcbf3601b 100644 --- a/lib/classes/JsonApi/Routes/RangeTree/ChildrenOfRangeTreeNode.php +++ b/lib/classes/JsonApi/Routes/RangeTree/ChildrenOfRangeTreeNode.php @@ -7,6 +7,7 @@ use Psr\Http\Message\ResponseInterface as Response; use JsonApi\Errors\AuthorizationFailedException; use JsonApi\Errors\RecordNotFoundException; use JsonApi\JsonApiController; +use RangeTreeNode; class ChildrenOfRangeTreeNode extends JsonApiController { @@ -27,7 +28,7 @@ class ChildrenOfRangeTreeNode extends JsonApiController throw new RecordNotFoundException(); } - list($offset, $limit) = $this->getOffsetAndLimit(); + [$offset, $limit] = $this->getOffsetAndLimit(); $total = \RangeTreeNode::countByParent_id($args['id']); $children = \RangeTreeNode::findByParent_id( $args['id'], diff --git a/lib/classes/OAuth2/NegotiatesWithPsr7.php b/lib/classes/OAuth2/NegotiatesWithPsr7.php index 09197f4e659..1f743ad8fbb 100644 --- a/lib/classes/OAuth2/NegotiatesWithPsr7.php +++ b/lib/classes/OAuth2/NegotiatesWithPsr7.php @@ -5,6 +5,7 @@ namespace Studip\OAuth2; use Psr\Http\Message\ResponseFactoryInterface; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; +use Trails\Controller; use Trails\Response as TrailsResponse; trait NegotiatesWithPsr7 @@ -33,6 +34,10 @@ trait NegotiatesWithPsr7 protected function renderPsrResponse(ResponseInterface $response): void { + if (!($this instanceof Controller)) { + throw new \Exception('Can only render responses on trails controllers'); + } + $this->set_status($response->getStatusCode()); $this->render_text((string) $response->getBody()); foreach ($response->getHeaders() as $key => $values) { diff --git a/lib/classes/SQLQuery.php b/lib/classes/SQLQuery.php index 6c8f49ec7d3..d1e9aca5e6f 100644 --- a/lib/classes/SQLQuery.php +++ b/lib/classes/SQLQuery.php @@ -217,7 +217,7 @@ class SQLQuery * a sorm_class the result will be an array of the sorm-objects. * * @template T of SimpleORMap - * @param class-string<T>|string|null $sorm_class_or_column : column name, a class of SimpleORMap or null for associative array. + * @param T|class-string<T>|string|null $sorm_class_or_column : column name, a class of SimpleORMap or null for associative array. * @param int|null $max_results Maximum number of results to return * @return array[]|T[]|mixed[] arrays or array of objects or array of values. * diff --git a/lib/classes/admission/CourseSet.php b/lib/classes/admission/CourseSet.php index beff9acecdd..e7f3dee9d39 100644 --- a/lib/classes/admission/CourseSet.php +++ b/lib/classes/admission/CourseSet.php @@ -559,7 +559,7 @@ class CourseSet /** * Gets the course sets the given course belongs to. * - * @param String courseId + * @param string $courseId * @return CourseSet */ public static function getSetForCourse($courseId) diff --git a/lib/classes/cache/Exception.php b/lib/classes/cache/Exception.php index 061d09019a2..d4ebe120b83 100644 --- a/lib/classes/cache/Exception.php +++ b/lib/classes/cache/Exception.php @@ -21,7 +21,7 @@ namespace Studip\Cache; * The CacheException class is an implementation of the CacheException interface * of PSR-6 that behaves like a StudipException. */ -class Exception extends \StudipException implements \Psr\Cache\CacheException +class Exception extends \Studip\Exception implements \Psr\Cache\CacheException { //Nothing here, since there is nothing to implement. } diff --git a/lib/classes/cache/InvalidCacheArgumentException.php b/lib/classes/cache/InvalidCacheArgumentException.php index a201cad983e..5c4e25a6e3a 100644 --- a/lib/classes/cache/InvalidCacheArgumentException.php +++ b/lib/classes/cache/InvalidCacheArgumentException.php @@ -22,7 +22,7 @@ namespace Studip\Cache; * The InvalidCacheArgumentException is an implementation of the InvalidArgumentException interface * of PSR-6 that behaves like a StudipException. */ -class InvalidCacheArgumentException extends \StudipException implements \Psr\Cache\InvalidArgumentException +class InvalidCacheArgumentException extends \Studip\Exception implements \Psr\Cache\InvalidArgumentException { //Nothing here, since there is nothing to implement. } diff --git a/lib/classes/calendar/ICalendarExport.php b/lib/classes/calendar/ICalendarExport.php index d8d1af7d8ce..21bb47f2078 100644 --- a/lib/classes/calendar/ICalendarExport.php +++ b/lib/classes/calendar/ICalendarExport.php @@ -35,9 +35,10 @@ class ICalendarExport */ private $time = 0; + public string $format; + public function __construct() { - $this->default_filename_suffix = "ics"; $this->format = "iCalendar"; } diff --git a/lib/classes/calendar/ICalendarImport.php b/lib/classes/calendar/ICalendarImport.php index 6d4a2607d50..a2043181c07 100644 --- a/lib/classes/calendar/ICalendarImport.php +++ b/lib/classes/calendar/ICalendarImport.php @@ -2,15 +2,12 @@ class ICalendarImport { private $range_id; - private $count = 0; - - private $dates = []; - private $import_time; - private $convert_to_private = false; + private $client_identifier = ''; + public function __construct($range_id) { $this->range_id = $range_id; @@ -94,10 +91,11 @@ class ICalendarImport $params = []; // skip seminar events - if ((!$this->import_sem) && $tag == 'UID') { - if (mb_strpos($value, 'Stud.IP-SEM') === 0) { - continue 2; - } + if ( + $tag == 'UID' + && mb_strpos($value, 'Stud.IP-SEM') === 0 + ) { + continue 2; } if (!empty($parts[2])) { @@ -312,8 +310,7 @@ class ICalendarImport $this->createDateFromProperties($properties); } else { - // _("Die Datei ist keine gültige iCalendar-Datei!") - throw new InvalidValuesException(); + throw new InvalidValuesException(_('Die Datei ist keine gültige iCalendar-Datei!')); } $this->count++; } @@ -471,7 +468,7 @@ class ICalendarImport } return $time; } - throw new InvalidValuesException(); + throw new InvalidValuesException(_('Die Zeitangabe ist ungültig')); } /** @@ -486,7 +483,7 @@ class ICalendarImport $date['mday'] = $matches[3]; return $date; } - throw new InvalidValuesException(); + throw new InvalidValuesException(_('Die Datumsangabe ist ungültig')); } /** @@ -650,13 +647,12 @@ class ICalendarImport private function parseClientIdentifier(&$data) { - global $_calendar_error; - if ($this->client_identifier == '') { - if (!preg_match('/PRODID((;[\W\w]*)*):([\W\w]+?)(\r\n|\r|\n)/', $data, $matches) - || !trim($matches[3])) { - // _("Die Datei ist keine gültige iCalendar-Datei!") - throw new InvalidValuesException(); + if ( + !preg_match('/PRODID((;[\W\w]*)*):([\W\w]+?)(\r\n|\r|\n)/', $data, $matches) + || !trim($matches[3]) + ) { + throw new InvalidValuesException(_('Die Datei ist keine gültige iCalendar-Datei!')); } else { $this->client_identifier = trim($matches[3]); } diff --git a/lib/exTpl/IteratorNode.php b/lib/exTpl/IteratorNode.php index 58dd593599a..17c15d072ef 100644 --- a/lib/exTpl/IteratorNode.php +++ b/lib/exTpl/IteratorNode.php @@ -38,6 +38,9 @@ class IteratorNode extends ArrayNode $result = ''; if (is_array($values) && is_int(key($values))) { + $key = null; + $value = null; + $bindings = [$this->key_name => &$key, $this->val_name => &$value]; $context = new Context($bindings, $context); diff --git a/lib/exTpl/TemplateParserException.php b/lib/exTpl/TemplateParserException.php index 2c7abf88f72..c38b3ff6105 100644 --- a/lib/exTpl/TemplateParserException.php +++ b/lib/exTpl/TemplateParserException.php @@ -14,6 +14,6 @@ class TemplateParserException extends Exception $type = $scanner->tokenType(); $value = is_int($type) ? $scanner->tokenValue() : $type; - return parent::__construct("$message at \"$value\""); + parent::__construct("$message at \"$value\""); } } diff --git a/lib/exceptions/FeatureDisabledException.php b/lib/exceptions/FeatureDisabledException.php index 16af0bf8f8a..52cbbdf18d3 100644 --- a/lib/exceptions/FeatureDisabledException.php +++ b/lib/exceptions/FeatureDisabledException.php @@ -1,5 +1,5 @@ <?php -class FeatureDisabledException extends StudipException +class FeatureDisabledException extends Studip\Exception { public function __construct($message = '', $code = 0, Exception $previous = null) { diff --git a/lib/helpers.php b/lib/helpers.php index a44f10b9b97..bffed4a9acb 100644 --- a/lib/helpers.php +++ b/lib/helpers.php @@ -15,7 +15,7 @@ use Psr\Container\ContainerInterface; * $logger = app(LoggerInterface::class); * ``` * @template T - * @param class-string<T>|string|null $entryId entry name or a class name + * @param T|class-string<T>|string|null $entryId entry name or a class name * @param array $parameters Optional parameters to use to build the entry. * Use this to force specific parameters to specific values. * Parameters not defined in this array will be resolved using the container. diff --git a/lib/ilias_interface/StudipSoapClient.php b/lib/ilias_interface/StudipSoapClient.php index 0aafd4af567..6a22f86243f 100644 --- a/lib/ilias_interface/StudipSoapClient.php +++ b/lib/ilias_interface/StudipSoapClient.php @@ -11,8 +11,9 @@ */ class StudipSoapClient { - var $soap_client; - var $error; + public $soap_client; + public $error; + public $faultstring; function __construct($path) { @@ -30,7 +31,7 @@ class StudipSoapClient $this->faultstring = ""; try { $result = $this->soap_client->__soapCall($method, $params); - } catch (SoapFault $fault) { + } catch (SoapFault $fault) { $this->faultstring = $fault->faultstring; if (!in_array(mb_strtolower($this->faultstring), ["session not valid","session invalid", "session idled"])) { unset($params['password']); diff --git a/lib/models/Course.php b/lib/models/Course.php index 1ff49f4bb49..d7ffff7a956 100644 --- a/lib/models/Course.php +++ b/lib/models/Course.php @@ -306,7 +306,7 @@ class Course extends SimpleORMap implements Range, PrivacyObject, StudipItem, Fe $config['registered_callbacks']['before_store'][] = 'logStore'; $config['registered_callbacks']['after_create'][] = 'setDefaultTools'; - $config['registered_callbacks']['after_delete'][] = function ($course) { + $config['registered_callbacks']['after_delete'][] = function (Course $course) { CourseAvatar::getAvatar($course->id)->reset(); FeedbackElement::deleteBySQL('course_id = ?', [$course->id]); // Remove subcourse relations, leaving subcourses intact. @@ -351,7 +351,7 @@ class Course extends SimpleORMap implements Range, PrivacyObject, StudipItem, Fe AutoInsert::deleteSeminar($course->id); //Remove assignments to admission sets: - $cs = $this->getCourseSet(); + $cs = $course->getCourseSet(); if ($cs) { CourseSet::removeCourseFromSet($cs->getId(), $course->id); $cs->load(); @@ -605,7 +605,7 @@ class Course extends SimpleORMap implements Range, PrivacyObject, StudipItem, Fe */ public function hasCourseSet() : bool { - return CourseSet::countBySeminar_id($this->id) > 0; + return $this->getCourseSet() !== null; } /** diff --git a/lib/models/Courseware/StructuralElement.php b/lib/models/Courseware/StructuralElement.php index 9b68ea2fdf5..e72cc4f34ef 100644 --- a/lib/models/Courseware/StructuralElement.php +++ b/lib/models/Courseware/StructuralElement.php @@ -184,7 +184,7 @@ class StructuralElement extends \SimpleORMap implements \PrivacyObject, \Feedbac $this->image_id = $image->getId(); $this->image_type = \StockImage::class; } else { - throw \BadMethodCallException('Invalid argument to method ' . __METHOD__); + throw new \BadMethodCallException('Invalid argument to method ' . __METHOD__); } } @@ -1219,7 +1219,7 @@ SQL; if ($this->range_type === 'user') { return 'contents/courseware/courseware/' . $unit->id . '#/structural_element/' . $this->id; } - + return 'course/courseware/courseware/' . $unit->id . '?cid=' . $this->range_id . '#/structural_element/' . $this->id; } diff --git a/lib/models/ModuleManagementModel.php b/lib/models/ModuleManagementModel.php index 786b1e358f6..3bd5eb75b4f 100644 --- a/lib/models/ModuleManagementModel.php +++ b/lib/models/ModuleManagementModel.php @@ -253,7 +253,6 @@ abstract class ModuleManagementModel extends SimpleORMap implements ModuleManage * Logs all changes of this object. * * @param string $action new, update or delete - * @return boolean Return true if logging was successful. */ protected function logChanges ($action = null) { @@ -367,7 +366,7 @@ abstract class ModuleManagementModel extends SimpleORMap implements ModuleManage $num_index = 1; break; default: - return false; + return; } if ($logging) { @@ -389,7 +388,7 @@ abstract class ModuleManagementModel extends SimpleORMap implements ModuleManage $debuginfo = $this->getDisplayName(); break; default: - return false; + return; } $id_array = $this->getId(); @@ -407,7 +406,7 @@ abstract class ModuleManagementModel extends SimpleORMap implements ModuleManage $debuginfo = $id_array[2]; break; default: - return false; + return; } if ($action == 'update') { @@ -424,9 +423,9 @@ abstract class ModuleManagementModel extends SimpleORMap implements ModuleManage StudipLog::log($logging, $aff, $coaff, $this->db_table(), $debuginfo); } - return true; + return; } - return false; + return; } /** @@ -927,7 +926,7 @@ abstract class ModuleManagementModel extends SimpleORMap implements ModuleManage */ protected static function formatDisplayName( string $template, - array $placeholders, + array $placeholders, array $replacements ): string { if (mb_strlen($template) === 0) { diff --git a/lib/models/MvvFileRange.php b/lib/models/MvvFileRange.php index 9155c1fd909..4c0c6956f94 100644 --- a/lib/models/MvvFileRange.php +++ b/lib/models/MvvFileRange.php @@ -48,7 +48,7 @@ class MvvFileRange extends ModuleManagementModel /** * Returns the rangetype of the document based on its foldertype. * - * @return bool|string Returns false on failure, otherwise the name of the range. + * @return string Returns false on failure, otherwise the name of the range. */ public function getRangeType() { diff --git a/lib/models/StudipCacheOperation.php b/lib/models/StudipCacheOperation.php index d2287c32a5f..36d81b9fad1 100644 --- a/lib/models/StudipCacheOperation.php +++ b/lib/models/StudipCacheOperation.php @@ -1,4 +1,7 @@ <?php + +use Studip\Cache\Cache; + /** * Model for a stored cache operation. * @@ -38,9 +41,9 @@ class StudipCacheOperation extends SimpleORMap * The operations are applied in chronological order and are deleted * from the database after they have been applied. * - * @param StudipCache $cache The cache object to apply the operations to + * @param Cache $cache The cache object to apply the operations to */ - public static function apply(StudipCache $cache) + public static function apply(Cache $cache) { self::findEachBySQL(function (StudipCacheOperation $item) use ($cache): void { $parameters = unserialize($item->parameters); diff --git a/lib/plugins/core/CorePlugin.php b/lib/plugins/core/CorePlugin.php index 056efaf6ac1..9e68992047d 100644 --- a/lib/plugins/core/CorePlugin.php +++ b/lib/plugins/core/CorePlugin.php @@ -8,6 +8,7 @@ */ abstract class CorePlugin { + abstract public function getMetadata(); /** * plugin meta data diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 5b8547f1c3b..2d66785205c 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -7,17 +7,17 @@ parameters: - tests/functional - tests/jsonapi - tests/unit + - tests/_support scanDirectories: - app/controllers - lib - vendor excludePaths: - lib/classes/ZipArchiveLegacyTrait.php - - lib/elearning/studip_referrer.php - - lib/soap/StudipSoapClient_PHP5.php + - lib/ilias_interface/studip_referrer_7x.php + - lib/ilias_interface/studip_referrer_8x.php tmpDir: .caches - earlyTerminatingMethodCalls: - RESTAPI\RouteMap: - - error - - halt - - notFound + ignoreErrors: + - + message: '#Unsafe usage of new static\(\)\.#' + path: lib/classes/SimpleORMap.php diff --git a/tests/unit/lib/flexi/PHPTemplatePartialBugTest.php b/tests/unit/lib/flexi/PHPTemplatePartialBugTest.php index ef265cf22c4..fd909cb1c95 100644 --- a/tests/unit/lib/flexi/PHPTemplatePartialBugTest.php +++ b/tests/unit/lib/flexi/PHPTemplatePartialBugTest.php @@ -4,6 +4,8 @@ use Flexi\Factory; final class PhpTemplatePartialBugTestCase extends Codeception\Test\Unit { + private Factory $factory; + public function setUp(): void { $this->setUpFS(); diff --git a/tests/unit/lib/flexi/TemplateMagicMethodsTest.php b/tests/unit/lib/flexi/TemplateMagicMethodsTest.php index ad2690a7430..fda4695d165 100644 --- a/tests/unit/lib/flexi/TemplateMagicMethodsTest.php +++ b/tests/unit/lib/flexi/TemplateMagicMethodsTest.php @@ -6,6 +6,7 @@ use Flexi\Template; final class TemplateMagicMethodsTestCase extends \Codeception\Test\Unit { private Factory $factory; + private Template $template; public function setUp(): void { -- GitLab