aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan-Hendrik Willms <tleilax+studip@gmail.com>2024-05-27 06:11:25 +0000
committerDavid Siegfried <david.siegfried@uni-vechta.de>2024-05-27 06:11:25 +0000
commit4f847abc09405f0cf848f7b4b5a5a283acc6131d (patch)
tree94912425ef703757cf63fd19f8463a73e594cf9c
parent05fefe4a2d9582e48131c82cee4d25cef2db40f5 (diff)
integrate trails, fixes #4102
Closes #4102 Merge request studip/studip!3034
-rw-r--r--app/controllers/admin/domain.php2
-rw-r--r--app/controllers/admin/install.php2
-rw-r--r--app/controllers/admin/lockrules.php4
-rw-r--r--app/controllers/api/oauth2/applications.php4
-rw-r--r--app/controllers/api/oauth2/authorize.php2
-rw-r--r--app/controllers/api/oauth2/oauth2_controller.php2
-rw-r--r--app/controllers/api/oauth2/token.php4
-rw-r--r--app/controllers/contents/courseware.php2
-rw-r--r--app/controllers/course/admission.php8
-rw-r--r--app/controllers/course/block_appointments.php2
-rw-r--r--app/controllers/course/cancel_dates.php2
-rw-r--r--app/controllers/course/change_view.php5
-rw-r--r--app/controllers/course/details.php2
-rw-r--r--app/controllers/course/enrolment.php2
-rw-r--r--app/controllers/course/forum/forum_controller.php2
-rw-r--r--app/controllers/course/gradebook/lecturers.php4
-rw-r--r--app/controllers/course/lvgselector.php4
-rw-r--r--app/controllers/course/members.php4
-rw-r--r--app/controllers/course/room_requests.php4
-rw-r--r--app/controllers/course/scm.php2
-rw-r--r--app/controllers/course/statusgroups.php2
-rw-r--r--app/controllers/course/study_areas.php3
-rw-r--r--app/controllers/course/studygroup.php4
-rw-r--r--app/controllers/course/timesrooms.php10
-rw-r--r--app/controllers/document.php2
-rw-r--r--app/controllers/extern.php2
-rw-r--r--app/controllers/fachabschluss/kategorien.php6
-rw-r--r--app/controllers/file.php30
-rw-r--r--app/controllers/files.php4
-rw-r--r--app/controllers/materialien/files.php2
-rw-r--r--app/controllers/media_proxy.php2
-rw-r--r--app/controllers/module/module.php12
-rw-r--r--app/controllers/module/mvv_controller.php6
-rw-r--r--app/controllers/oer/endpoints.php2
-rw-r--r--app/controllers/search/studiengaenge.php2
-rw-r--r--app/controllers/settings/settings.php2
-rw-r--r--app/controllers/shared/contacts.php4
-rw-r--r--app/controllers/siteinfo.php2
-rw-r--r--app/controllers/studiengaenge/abschluesse.php6
-rw-r--r--app/controllers/studiengaenge/fachbereiche.php2
-rw-r--r--app/controllers/studiengaenge/fachbereichestgteile.php2
-rw-r--r--app/controllers/studiengaenge/faecher.php2
-rw-r--r--app/controllers/studiengaenge/kategorien.php4
-rw-r--r--app/controllers/studiengaenge/shared_version.php22
-rw-r--r--app/controllers/studiengaenge/studiengaenge.php4
-rw-r--r--app/controllers/studiengaenge/studiengangteile.php2
-rw-r--r--app/controllers/studiengaenge/versionen.php4
-rw-r--r--app/views/consultation/admin/create.php2
-rw-r--r--app/views/news/admin_news.php2
-rw-r--r--cli/Commands/Checks/HelpTours.php4
-rw-r--r--lib/bootstrap-autoload.php29
-rw-r--r--lib/bootstrap-definitions.php2
-rw-r--r--lib/classes/OAuth2/NegotiatesWithPsr7.php6
-rw-r--r--lib/classes/StudipController.php34
-rw-r--r--lib/classes/StudipDispatcher.php64
-rw-r--r--lib/classes/StudipResponse.php2
-rw-r--r--lib/functions.php17
-rw-r--r--lib/modules/EvaluationsWidget.php2
-rw-r--r--lib/modules/MyCoursesWidget.php2
-rw-r--r--lib/modules/NewsWidget.php2
-rw-r--r--lib/modules/TerminWidget.php2
-rw-r--r--lib/plugins/core/StudIPPlugin.class.php4
-rw-r--r--lib/seminar_open.php2
-rw-r--r--lib/trails/Controller.php411
-rw-r--r--lib/trails/Dispatcher.php262
-rw-r--r--lib/trails/Exception.php43
-rw-r--r--lib/trails/Exceptions/DoubleRenderError.php13
-rw-r--r--lib/trails/Exceptions/MissingFile.php10
-rw-r--r--lib/trails/Exceptions/RoutingError.php10
-rw-r--r--lib/trails/Exceptions/SessionRequiredException.php11
-rw-r--r--lib/trails/Exceptions/UnknownAction.php10
-rw-r--r--lib/trails/Exceptions/UnknownController.php10
-rw-r--r--lib/trails/Flash.php184
-rw-r--r--lib/trails/Inflector.php44
-rw-r--r--lib/trails/Response.php185
-rw-r--r--public/assets.php2
-rw-r--r--public/dispatch.php2
-rw-r--r--public/install.php15
-rw-r--r--public/sendfile.php6
-rw-r--r--public/web_migrate.php2
-rw-r--r--tests/unit/_bootstrap.php13
-rw-r--r--tests/unit/lib/FunctionsTest.php5
-rw-r--r--tests/unit/lib/classes/StudipControllerTest.php6
-rw-r--r--tests/unit/lib/classes/TrailsTest.php25
-rw-r--r--vendor/trails/extras/tramp.php55
-rw-r--r--vendor/trails/src/HEADER.php27
-rw-r--r--vendor/trails/src/controller.php430
-rw-r--r--vendor/trails/src/dispatcher.php269
-rw-r--r--vendor/trails/src/exception.php101
-rw-r--r--vendor/trails/src/flash.php241
-rw-r--r--vendor/trails/src/inflector.php49
-rw-r--r--vendor/trails/src/response.php166
-rw-r--r--vendor/trails/src/trails.php16
-rw-r--r--vendor/trails/trails-abridged.php3
-rw-r--r--vendor/trails/trails.php1289
95 files changed, 1443 insertions, 2856 deletions
diff --git a/app/controllers/admin/domain.php b/app/controllers/admin/domain.php
index e4bb9c8..37ab11f 100644
--- a/app/controllers/admin/domain.php
+++ b/app/controllers/admin/domain.php
@@ -70,7 +70,7 @@ class Admin_DomainController extends AuthenticatedController
{
foreach ($args as $arg) {
if ($arg && !preg_match('/' . UserDomain::REGEXP . '/', $arg)) {
- throw new Trails_Exception(400);
+ throw new Trails\Exception(400);
}
}
diff --git a/app/controllers/admin/install.php b/app/controllers/admin/install.php
index 9ede078..e45c281 100644
--- a/app/controllers/admin/install.php
+++ b/app/controllers/admin/install.php
@@ -1,7 +1,7 @@
<?php
require_once __DIR__ . '/../../../lib/classes/StudipControllerPropertiesTrait.php';
-class Admin_InstallController extends Trails_Controller
+class Admin_InstallController extends Trails\Controller
{
use StudipControllerPropertiesTrait;
diff --git a/app/controllers/admin/lockrules.php b/app/controllers/admin/lockrules.php
index 56879fe..202a2e9 100644
--- a/app/controllers/admin/lockrules.php
+++ b/app/controllers/admin/lockrules.php
@@ -164,7 +164,7 @@ class Admin_LockrulesController extends AuthenticatedController
{
$this->lock_rule = LockRule::find($lock_rule_id);
if (!(!$this->lock_rule->isNew() && ($GLOBALS['perm']->have_perm('root') || $this->lock_rule->user_id === $GLOBALS['user']->id))) {
- throw new Trails_Exception(403);
+ throw new Trails\Exception(403);
}
CSRFProtection::verifyUnsafeRequest();
if ($this->lock_rule->delete()) {
@@ -186,4 +186,4 @@ class Admin_LockrulesController extends AuthenticatedController
}
return $this->lock_rule->store();
}
-} \ No newline at end of file
+}
diff --git a/app/controllers/api/oauth2/applications.php b/app/controllers/api/oauth2/applications.php
index d08ec1e..fd6a1bb 100644
--- a/app/controllers/api/oauth2/applications.php
+++ b/app/controllers/api/oauth2/applications.php
@@ -31,7 +31,7 @@ class Api_Oauth2_ApplicationsController extends AuthenticatedController
$this->application = $this->formatApplication($accessToken);
if (!$this->application) {
- throw new Trails_Exception(500, 'Error finding client.');
+ throw new Trails\Exception(500, 'Error finding client.');
}
}
@@ -42,7 +42,7 @@ class Api_Oauth2_ApplicationsController extends AuthenticatedController
$user = User::findCurrent();
$accessToken = AccessToken::find(Request::option('application'));
if (!$accessToken) {
- throw new Trails_Exception(404);
+ throw new Trails\Exception(404);
}
if ($accessToken['user_id'] !== $user->id) {
throw new AccessDeniedException();
diff --git a/app/controllers/api/oauth2/authorize.php b/app/controllers/api/oauth2/authorize.php
index 5628d49..451b766 100644
--- a/app/controllers/api/oauth2/authorize.php
+++ b/app/controllers/api/oauth2/authorize.php
@@ -13,7 +13,7 @@ class Api_Oauth2_AuthorizeController extends OAuth2Controller
parent::before_filter($action, $args);
if ('index' !== $action) {
- throw new Trails_Exception(404);
+ throw new Trails\Exception(404);
}
$action = $this->determineAction();
diff --git a/app/controllers/api/oauth2/oauth2_controller.php b/app/controllers/api/oauth2/oauth2_controller.php
index fd02ea9..6b3dacd 100644
--- a/app/controllers/api/oauth2/oauth2_controller.php
+++ b/app/controllers/api/oauth2/oauth2_controller.php
@@ -42,7 +42,7 @@ abstract class OAuth2Controller extends StudipController
return $this->convertPsrResponse($psrResponse);
}
- return new Trails_Response($exception->getMessage(), [], 500);
+ return new Trails\Response($exception->getMessage(), [], 500);
}
protected function getAuthorizationServer(): AuthorizationServer
diff --git a/app/controllers/api/oauth2/token.php b/app/controllers/api/oauth2/token.php
index 0ae7ffb..755d6b7 100644
--- a/app/controllers/api/oauth2/token.php
+++ b/app/controllers/api/oauth2/token.php
@@ -8,11 +8,11 @@ class Api_Oauth2_TokenController extends OAuth2Controller
parent::before_filter($action, $args);
if ('index' !== $action) {
- throw new Trails_Exception(404);
+ throw new Trails\Exception(404);
}
if (!Request::isPost()) {
- throw new Trails_Exception(405);
+ throw new Trails\Exception(405);
}
$action = 'issue_token';
diff --git a/app/controllers/contents/courseware.php b/app/controllers/contents/courseware.php
index c1d807f..d4291df 100644
--- a/app/controllers/contents/courseware.php
+++ b/app/controllers/contents/courseware.php
@@ -311,7 +311,7 @@ class Contents_CoursewareController extends CoursewareController
);
if (!$struct) {
- throw new Trails_Exception(404, _('Der geteilte Inhalt kann nicht gefunden werden.'));
+ throw new Trails\Exception(404, _('Der geteilte Inhalt kann nicht gefunden werden.'));
}
if (!$struct->canRead($user) && !$struct->canEdit($user)) {
diff --git a/app/controllers/course/admission.php b/app/controllers/course/admission.php
index 56342bb..14a9b20 100644
--- a/app/controllers/course/admission.php
+++ b/app/controllers/course/admission.php
@@ -31,7 +31,7 @@ class Course_AdmissionController extends AuthenticatedController
if (!get_object_type($this->course_id, ['sem']) ||
SeminarCategories::GetBySeminarId($this->course_id)->studygroup_mode ||
!$GLOBALS['perm']->have_studip_perm('tutor', $this->course_id)) {
- throw new Trails_Exception(403);
+ throw new Trails\Exception(403);
}
$this->course = Course::find($this->course_id);
@@ -488,7 +488,7 @@ class Course_AdmissionController extends AuthenticatedController
}
$this->course_set_name = $course_set->getName();
} else {
- throw new Trails_Exception(400);
+ throw new Trails\Exception(400);
}
}
@@ -503,7 +503,7 @@ class Course_AdmissionController extends AuthenticatedController
$this->redirect($response->headers['Location']);
}
} else {
- throw new Trails_Exception(403);
+ throw new Trails\Exception(403);
}
}
@@ -518,7 +518,7 @@ class Course_AdmissionController extends AuthenticatedController
$this->redirect($response->headers['Location']);
}
} else {
- throw new Trails_Exception(403);
+ throw new Trails\Exception(403);
}
}
diff --git a/app/controllers/course/block_appointments.php b/app/controllers/course/block_appointments.php
index fef0d31..ad28b1e 100644
--- a/app/controllers/course/block_appointments.php
+++ b/app/controllers/course/block_appointments.php
@@ -33,7 +33,7 @@ class Course_BlockAppointmentsController extends AuthenticatedController
SeminarCategories::GetBySeminarId($this->course_id)->studygroup_mode ||
!$GLOBALS['perm']->have_studip_perm("tutor", $this->course_id)
) {
- throw new Trails_Exception(400);
+ throw new Trails\Exception(400);
}
PageLayout::setHelpKeyword('Basis.VeranstaltungenVerwaltenAendernVonZeitenUndTerminen');
PageLayout::setTitle(Course::findCurrent()->getFullName() . " - " . _('Blockveranstaltungstermine anlegen'));
diff --git a/app/controllers/course/cancel_dates.php b/app/controllers/course/cancel_dates.php
index 0d5463c..8da0d09 100644
--- a/app/controllers/course/cancel_dates.php
+++ b/app/controllers/course/cancel_dates.php
@@ -39,7 +39,7 @@ class Course_CancelDatesController extends AuthenticatedController
$this->course_id = $this->dates[0]->range_id;
}
if (!get_object_type($this->course_id, ['sem']) || !$perm->have_studip_perm("tutor", $this->course_id)) {
- throw new Trails_Exception(400);
+ throw new Trails\Exception(400);
}
PageLayout::setHelpKeyword('Basis.VeranstaltungenVerwaltenAendernVonZeitenUndTerminen');
PageLayout::setTitle(Course::findCurrent()->getFullName() . " - " . _('Veranstaltungstermine absagen'));
diff --git a/app/controllers/course/change_view.php b/app/controllers/course/change_view.php
index 156a68a..63395b6 100644
--- a/app/controllers/course/change_view.php
+++ b/app/controllers/course/change_view.php
@@ -16,7 +16,6 @@
*/
class Course_ChangeViewController extends AuthenticatedController
{
- // see Trails_Controller#before_filter
public function before_filter(&$action, &$args)
{
parent::before_filter($action, $args);
@@ -28,7 +27,7 @@ class Course_ChangeViewController extends AuthenticatedController
* Sets the current course into participant view.
* Only available for tutor upwards.
*
- * @throws Trails_Exception Someone with unfitting rights tried to call here.
+ * @throws Trails\Exception Someone with unfitting rights tried to call here.
*/
public function set_changed_view_action()
{
@@ -43,7 +42,7 @@ class Course_ChangeViewController extends AuthenticatedController
* Resets a course currently in participant view to normal view
* with real rights.
*
- * @throws Trails_Exception Someone with unfitting rights tried to call here.
+ * @throws Trails\Exception Someone with unfitting rights tried to call here.
*/
public function reset_changed_view_action()
{
diff --git a/app/controllers/course/details.php b/app/controllers/course/details.php
index 2a330e3..e1c9493 100644
--- a/app/controllers/course/details.php
+++ b/app/controllers/course/details.php
@@ -32,7 +32,7 @@ class Course_DetailsController extends AuthenticatedController
$this->course = Course::find($course_id);
if (!$this->course) {
- throw new Trails_Exception(
+ throw new Trails\Exception(
404,
_('Es konnte keine Veranstaltung gefunden werden')
);
diff --git a/app/controllers/course/enrolment.php b/app/controllers/course/enrolment.php
index eb4428e..420b5ca 100644
--- a/app/controllers/course/enrolment.php
+++ b/app/controllers/course/enrolment.php
@@ -37,7 +37,7 @@ class Course_EnrolmentController extends AuthenticatedController
return false;
}
if (!get_object_type($this->course_id, ['sem'])) {
- throw new Trails_Exception(400);
+ throw new Trails\Exception(400);
}
$course = Seminar::GetInstance($this->course_id);
$enrolment_info = $course->getEnrolmentInfo($GLOBALS['user']->id);
diff --git a/app/controllers/course/forum/forum_controller.php b/app/controllers/course/forum/forum_controller.php
index 71d1aa0..65eec63 100644
--- a/app/controllers/course/forum/forum_controller.php
+++ b/app/controllers/course/forum/forum_controller.php
@@ -23,7 +23,7 @@ abstract class ForumController extends StudipController {
parent::before_filter($action, $args);
- $this->flash = Trails_Flash::instance();
+ $this->flash = Trails\Flash::instance();
// Set help keyword for Stud.IP's user-documentation and page title
PageLayout::setHelpKeyword('Basis.Forum');
diff --git a/app/controllers/course/gradebook/lecturers.php b/app/controllers/course/gradebook/lecturers.php
index b3b1f82..7ab02e7 100644
--- a/app/controllers/course/gradebook/lecturers.php
+++ b/app/controllers/course/gradebook/lecturers.php
@@ -258,7 +258,7 @@ class Course_Gradebook_LecturersController extends AuthenticatedController
public function edit_custom_definition_action($definitionId)
{
if (!$this->definition = Definition::findOneBySQL('id = ? AND course_id = ?', [$definitionId, \Context::getId()])) {
- throw new \Trails_Exception(404);
+ throw new \Trails\Exception(404);
}
// show template
@@ -271,7 +271,7 @@ class Course_Gradebook_LecturersController extends AuthenticatedController
{
CSRFProtection::verifyUnsafeRequest();
if (!$definition = Definition::findOneBySQL('id = ? AND course_id = ?', [$definitionId, \Context::getId()])) {
- throw new \Trails_Exception(404);
+ throw new \Trails\Exception(404);
}
$name = trim(\Request::get('name', ''));
diff --git a/app/controllers/course/lvgselector.php b/app/controllers/course/lvgselector.php
index 171f3d5..c8223a9 100644
--- a/app/controllers/course/lvgselector.php
+++ b/app/controllers/course/lvgselector.php
@@ -17,15 +17,13 @@ require 'config/mvv_config.php';
class Course_LvgselectorController extends AuthenticatedController
{
-
- // see Trails_Controller#before_filter
public function before_filter(&$action, &$args)
{
parent::before_filter($action, $args);
$this->course = Course::findCurrent();
if (!$this->course) {
- throw new Trails_Exception(404, _('Es wurde keine Veranstaltung ausgewählt!'));
+ throw new Trails\Exception(404, _('Es wurde keine Veranstaltung ausgewählt!'));
}
$this->course_id = $this->course->id;
if (!$GLOBALS['perm']->have_studip_perm('tutor', $this->course_id)) {
diff --git a/app/controllers/course/members.php b/app/controllers/course/members.php
index 3eae083..1ec1587 100644
--- a/app/controllers/course/members.php
+++ b/app/controllers/course/members.php
@@ -232,7 +232,7 @@ class Course_MembersController extends AuthenticatedController
$course_member = AdmissionApplication::find([$user_id, $this->course_id]);
}
if (is_null($course_member)) {
- throw new Trails_Exception(400);
+ throw new Trails\Exception(400);
}
$this->comment = $course_member->comment;
$this->user = User::find($user_id);
@@ -265,7 +265,7 @@ class Course_MembersController extends AuthenticatedController
$course_member = AdmissionApplication::find([$user_id, $this->course_id]);
}
if (!Request::submitted('save') || is_null($course_member)) {
- throw new Trails_Exception(400);
+ throw new Trails\Exception(400);
}
$course_member->comment = Request::get('comment');
diff --git a/app/controllers/course/room_requests.php b/app/controllers/course/room_requests.php
index a31e61a..926e000 100644
--- a/app/controllers/course/room_requests.php
+++ b/app/controllers/course/room_requests.php
@@ -46,7 +46,7 @@ class Course_RoomRequestsController extends AuthenticatedController
SeminarCategories::GetBySeminarId($this->course_id)->studygroup_mode ||
!$GLOBALS['perm']->have_studip_perm("tutor", $this->course_id)
) {
- throw new Trails_Exception(400);
+ throw new Trails\Exception(400);
}
PageLayout::setHelpKeyword('Basis.VeranstaltungenVerwaltenAendernVonZeitenUndTerminen');
@@ -663,7 +663,7 @@ class Course_RoomRequestsController extends AuthenticatedController
{
$request = RoomRequest::find($request_id);
if (!$request) {
- throw new Trails_Exception(403);
+ throw new Trails\Exception(403);
}
if (Request::isGet()) {
PageLayout::postQuestion(sprintf(
diff --git a/app/controllers/course/scm.php b/app/controllers/course/scm.php
index 66af981..4c5d4eb 100644
--- a/app/controllers/course/scm.php
+++ b/app/controllers/course/scm.php
@@ -93,7 +93,7 @@ class Course_ScmController extends AuthenticatedController
$this->scm = $id ? $this->scms->find($id) : $this->scms->first();
if (!$this->scm && $this->scms->count() > 0) {
- throw new Trails_Exception(404, _('Es konnte keine freie Informationsseite mit der angegebenen Id gefunden werden.'));
+ throw new Trails\Exception(404, _('Es konnte keine freie Informationsseite mit der angegebenen Id gefunden werden.'));
}
if (Request::get('verify') === 'delete') {
diff --git a/app/controllers/course/statusgroups.php b/app/controllers/course/statusgroups.php
index 48939bd..6f96299 100644
--- a/app/controllers/course/statusgroups.php
+++ b/app/controllers/course/statusgroups.php
@@ -762,7 +762,7 @@ class Course_StatusgroupsController extends AuthenticatedController
// Safety check if no group_id at all.
if (!$group_id) {
- throw new Trails_Exception(400);
+ throw new Trails\Exception(400);
}
}
diff --git a/app/controllers/course/study_areas.php b/app/controllers/course/study_areas.php
index df54bb4..e951d11 100644
--- a/app/controllers/course/study_areas.php
+++ b/app/controllers/course/study_areas.php
@@ -18,7 +18,6 @@ require_once 'lib/webservices/api/studip_lecture_tree.php';
class Course_StudyAreasController extends AuthenticatedController
{
- // see Trails_Controller#before_filter
public function before_filter(&$action, &$args)
{
parent::before_filter($action, $args);
@@ -101,7 +100,7 @@ class Course_StudyAreasController extends AuthenticatedController
public function save_action()
{
if($this->locked) {
- throw new Trails_Exception(403);
+ throw new Trails\Exception(403);
}
$params = [];
diff --git a/app/controllers/course/studygroup.php b/app/controllers/course/studygroup.php
index c375778..cd08ba3 100644
--- a/app/controllers/course/studygroup.php
+++ b/app/controllers/course/studygroup.php
@@ -10,8 +10,6 @@ require_once 'lib/user_visible.inc.php';
*/
class Course_StudygroupController extends AuthenticatedController
{
-
- // see Trails_Controller#before_filter
public function before_filter(&$action, &$args)
{
parent::before_filter($action, $args);
@@ -851,7 +849,7 @@ class Course_StudygroupController extends AuthenticatedController
return;
}
}
- throw new Trails_Exception(401);
+ throw new Trails\Exception(401);
}
diff --git a/app/controllers/course/timesrooms.php b/app/controllers/course/timesrooms.php
index ddd6883..f6cab24 100644
--- a/app/controllers/course/timesrooms.php
+++ b/app/controllers/course/timesrooms.php
@@ -14,7 +14,7 @@ class Course_TimesroomsController extends AuthenticatedController
* @param String $action Action to be executed
* @param Array $args Arguments passed to the action
*
- * @throws Trails_Exception when either no course was found or the user
+ * @throws Trails\Exception when either no course was found or the user
* may not access this area
*/
public function before_filter(&$action, &$args)
@@ -23,7 +23,7 @@ class Course_TimesroomsController extends AuthenticatedController
// Try to find a valid course
if (!Course::findCurrent()) {
- throw new Trails_Exception(404, _('Es wurde keine Veranstaltung ausgewählt!'));
+ throw new Trails\Exception(404, _('Es wurde keine Veranstaltung ausgewählt!'));
}
if (!$GLOBALS['perm']->have_studip_perm('tutor', Course::findCurrent()->id)) {
@@ -250,7 +250,7 @@ class Course_TimesroomsController extends AuthenticatedController
/**
* Edit the start-semester of a course
*
- * @throws Trails_DoubleRenderError
+ * @throws Trails\Exceptions\DoubleRenderError
*/
public function editSemester_action()
{
@@ -368,7 +368,7 @@ class Course_TimesroomsController extends AuthenticatedController
*
* @param $termin_id
*
- * @throws Trails_DoubleRenderError
+ * @throws Trails\Exceptions\DoubleRenderError
*/
public function saveDate_action($termin_id)
{
@@ -544,7 +544,7 @@ class Course_TimesroomsController extends AuthenticatedController
/**
* Save Single Date
*
- * @throws Trails_DoubleRenderError
+ * @throws Trails\Exceptions\DoubleRenderError
*/
public function saveSingleDate_action()
{
diff --git a/app/controllers/document.php b/app/controllers/document.php
index da15ebe..5057d9e 100644
--- a/app/controllers/document.php
+++ b/app/controllers/document.php
@@ -21,7 +21,7 @@ class DocumentController extends StudipController
if ($file_ref) {
$this->redirect($file_ref->getDownloadURL($disposition === 'inline' ? 'normal' : 'force'));
} else {
- throw new Trails_Exception(404);
+ throw new Trails\Exception(404);
}
}
}
diff --git a/app/controllers/extern.php b/app/controllers/extern.php
index 6cde6f3..9296a34 100644
--- a/app/controllers/extern.php
+++ b/app/controllers/extern.php
@@ -21,7 +21,7 @@ class ExternController extends StudipController
* Action shows rendered external page.
*
* @param string $config_id The id of the configuration of the external page to show.
- * @throws Trails_DoubleRenderError
+ * @throws Trails\Exceptions\DoubleRenderError
*/
public function index_action(string $config_id)
{
diff --git a/app/controllers/fachabschluss/kategorien.php b/app/controllers/fachabschluss/kategorien.php
index 205f1f1..f9ba041 100644
--- a/app/controllers/fachabschluss/kategorien.php
+++ b/app/controllers/fachabschluss/kategorien.php
@@ -114,7 +114,7 @@ class Fachabschluss_KategorienController extends MVVController
if (Request::submitted('delete')) {
CSRFProtection::verifyUnsafeRequest();
if (!MvvPerm::get('AbschlussKategorie')->haveFieldPerm('position')) {
- throw new Trails_Exception(403);
+ throw new Trails\Exception(403);
}
if (!count($abschluss_kategorie->abschluesse)) {
PageLayout::postSuccess(sprintf(
@@ -142,7 +142,7 @@ class Fachabschluss_KategorienController extends MVVController
$orderedIds = Request::getArray('newOrder');
if ($list === 'abschluss_kategorien') {
if (!MvvPerm::get('AbschlussKategorie')->haveFieldPerm('position')) {
- throw new Trails_Exception(403);
+ throw new Trails\Exception(403);
}
$kategorien = SimpleORMapCollection::createFromArray(
AbschlussKategorie::findBySql('1 ORDER BY position')
@@ -162,7 +162,7 @@ class Fachabschluss_KategorienController extends MVVController
}
} else {
if (!MvvPerm::get('AbschlussZuord')->haveFieldPerm('position')) {
- throw new Trails_Exception(403);
+ throw new Trails\Exception(403);
}
list(, $kategorie_id) = explode('_', $list);
$abschluss_kategorie = AbschlussKategorie::find($kategorie_id);
diff --git a/app/controllers/file.php b/app/controllers/file.php
index 095e295..376a74e 100644
--- a/app/controllers/file.php
+++ b/app/controllers/file.php
@@ -66,7 +66,7 @@ class FileController extends AuthenticatedController
}
$plugin = PluginManager::getInstance()->getPlugin(Request::get("from_plugin"));
if (!$plugin) {
- throw new Trails_Exception(404, _('Plugin existiert nicht.'));
+ throw new Trails\Exception(404, _('Plugin existiert nicht.'));
}
$folder = $plugin->getFolder($folder_id);
} else {
@@ -184,10 +184,10 @@ class FileController extends AuthenticatedController
//Plugin file area.
$plugin = PluginManager::getInstance()->getPlugin($this->to_plugin);
if (!$plugin) {
- throw new Trails_Exception(404, _('Plugin existiert nicht.'));
+ throw new Trails\Exception(404, _('Plugin existiert nicht.'));
}
if (!($plugin instanceof FilesystemPlugin)) {
- throw new Trails_Exception(400, _('Das Plugin ist kein Dateibereich-Plugin.'));
+ throw new Trails\Exception(400, _('Das Plugin ist kein Dateibereich-Plugin.'));
}
$file_ids = Request::getArray('file_refs');
foreach ($file_ids as $file_id) {
@@ -294,7 +294,7 @@ class FileController extends AuthenticatedController
}
$plugin = PluginManager::getInstance()->getPlugin($this->from_plugin);
if (!$plugin) {
- throw new Trails_Exception(404, _('Plugin existiert nicht.'));
+ throw new Trails\Exception(404, _('Plugin existiert nicht.'));
}
$this->file = $plugin->getPreparedFile($file_id);
} else {
@@ -383,7 +383,7 @@ class FileController extends AuthenticatedController
$file_ref_id = $file_id;
$plugin = PluginManager::getInstance()->getPlugin(Request::get("from_plugin"));
if (!$plugin) {
- throw new Trails_Exception(404, _('Plugin existiert nicht.'));
+ throw new Trails\Exception(404, _('Plugin existiert nicht.'));
}
$this->file = $plugin->getPreparedFile($file_id);
@@ -666,7 +666,7 @@ class FileController extends AuthenticatedController
}
$plugin = PluginManager::getInstance()->getPlugin(Request::get("from_plugin"));
if (!$plugin) {
- throw new Trails_Exception(404, _('Plugin existiert nicht.'));
+ throw new Trails\Exception(404, _('Plugin existiert nicht.'));
}
$this->file = $plugin->getPreparedFile($file_id);
$this->from_plugin = Request::get("from_plugin");
@@ -760,7 +760,7 @@ class FileController extends AuthenticatedController
$plugin = PluginManager::getInstance()->getPlugin(Request::get("from_plugin"));
if (!$plugin) {
- throw new Trails_Exception(404, _('Plugin existiert nicht.'));
+ throw new Trails\Exception(404, _('Plugin existiert nicht.'));
}
$this->file_ref = $plugin->getPreparedFile($file_id);
@@ -814,7 +814,7 @@ class FileController extends AuthenticatedController
}
$plugin = PluginManager::getInstance()->getPlugin(Request::get("from_plugin"));
if (!$plugin) {
- throw new Trails_Exception(404, _('Plugin existiert nicht.'));
+ throw new Trails\Exception(404, _('Plugin existiert nicht.'));
}
$foldertype = $plugin->getFolder($folder_id);
@@ -1325,7 +1325,7 @@ class FileController extends AuthenticatedController
}
$plugin = PluginManager::getInstance()->getPlugin(Request::get("from_plugin"));
if (!$plugin) {
- throw new Trails_Exception(404, _('Plugin existiert nicht.'));
+ throw new Trails\Exception(404, _('Plugin existiert nicht.'));
}
$filetype = $plugin->getPreparedFile($file_id);
$folder = $filetype->getFolderType();
@@ -1335,7 +1335,7 @@ class FileController extends AuthenticatedController
$filetype = $file_ref->getFileType();
}
if (!$filetype) {
- throw new Trails_Exception(404, _('Datei nicht gefunden.'));
+ throw new Trails\Exception(404, _('Datei nicht gefunden.'));
}
if (!$filetype->isWritable($GLOBALS['user']->id)) {
@@ -1792,7 +1792,7 @@ class FileController extends AuthenticatedController
}
$plugin = PluginManager::getInstance()->getPlugin(Request::get("to_plugin"));
if (!$plugin) {
- throw new Trails_Exception(404, _('Plugin existiert nicht.'));
+ throw new Trails\Exception(404, _('Plugin existiert nicht.'));
}
$this->top_folder = $plugin->getFolder($folder_id);
} else {
@@ -1857,7 +1857,7 @@ class FileController extends AuthenticatedController
}
$plugin = PluginManager::getInstance()->getPlugin(Request::get("from_plugin"));
if (!$plugin) {
- throw new Trails_Exception(404, _('Plugin existiert nicht.'));
+ throw new Trails\Exception(404, _('Plugin existiert nicht.'));
}
$parent_folder = $plugin->getFolder($folder_id);
} else {
@@ -1963,7 +1963,7 @@ class FileController extends AuthenticatedController
}
$plugin = PluginManager::getInstance()->getPlugin(Request::get("from_plugin"));
if (!$plugin) {
- throw new Trails_Exception(404, _('Plugin existiert nicht.'));
+ throw new Trails\Exception(404, _('Plugin existiert nicht.'));
}
$folder = $plugin->getFolder($folder_id);
} else {
@@ -2050,7 +2050,7 @@ class FileController extends AuthenticatedController
}
$plugin = PluginManager::getInstance()->getPlugin(Request::get("from_plugin"));
if (!$plugin) {
- throw new Trails_Exception(404, _('Plugin existiert nicht.'));
+ throw new Trails\Exception(404, _('Plugin existiert nicht.'));
}
$folder = $plugin->getFolder($folder_id);
} else {
@@ -2085,7 +2085,7 @@ class FileController extends AuthenticatedController
}
$plugin = PluginManager::getInstance()->getPlugin(Request::get("from_plugin"));
if (!$plugin) {
- throw new Trails_Exception(404, _('Plugin existiert nicht.'));
+ throw new Trails\Exception(404, _('Plugin existiert nicht.'));
}
$parent_folder = $plugin->getFolder($folder_id);
} else {
diff --git a/app/controllers/files.php b/app/controllers/files.php
index 2d4de4e..df4657c 100644
--- a/app/controllers/files.php
+++ b/app/controllers/files.php
@@ -711,7 +711,7 @@ class FilesController extends AuthenticatedController
$destination_plugin = PluginManager::getInstance()->getPlugin($to_plugin);
if (!$destination_plugin) {
- throw new Trails_Exception(404, _('Plugin existiert nicht.'));
+ throw new Trails\Exception(404, _('Plugin existiert nicht.'));
}
$destination_folder = $destination_plugin->getFolder($destination_id);
} else {
@@ -731,7 +731,7 @@ class FilesController extends AuthenticatedController
if ($from_plugin) {
$source_plugin = PluginManager::getInstance()->getPlugin($from_plugin);
if (!$source_plugin) {
- throw new Trails_Exception(404, _('Plugin existiert nicht.'));
+ throw new Trails\Exception(404, _('Plugin existiert nicht.'));
}
if (Request::get("isfolder")) {
if ($source_folder = $source_plugin->getFolder($fileref)) {
diff --git a/app/controllers/materialien/files.php b/app/controllers/materialien/files.php
index 804668e..6f45767 100644
--- a/app/controllers/materialien/files.php
+++ b/app/controllers/materialien/files.php
@@ -510,7 +510,7 @@ class Materialien_FilesController extends MVVController
$mvv_file = MvvFile::find($mvvfile_id);
if (!$mvv_file) {
- throw new Trails_Exception(404);
+ throw new Trails\Exception(404);
}
$this->doc_year = $mvv_file->year;
diff --git a/app/controllers/media_proxy.php b/app/controllers/media_proxy.php
index 50dc3df..b98b49c 100644
--- a/app/controllers/media_proxy.php
+++ b/app/controllers/media_proxy.php
@@ -46,7 +46,7 @@ class MediaProxyController extends StudipController
ini_set('default_socket_timeout', 5);
$this->render_nothing();
- //stop output buffering started in Trails_Dispatcher::dispatch()
+ //stop output buffering started in Trails\Dispatcher::dispatch()
while (ob_get_level()) {
ob_end_clean();
}
diff --git a/app/controllers/module/module.php b/app/controllers/module/module.php
index e57156f..854b045 100644
--- a/app/controllers/module/module.php
+++ b/app/controllers/module/module.php
@@ -395,17 +395,17 @@ class Module_ModuleController extends MVVController
* Deletes a descriptor from module
*
* @param type $deskriptor_id
- * @throws Trails_Exception
+ * @throws Trails\Exception
*/
public function delete_modul_deskriptor_action($deskriptor_id, $language)
{
$deskriptor = ModulDeskriptor::find($deskriptor_id);
if (is_null($deskriptor)) {
- throw new Trails_Exception(404, _('Unbekannter Deskriptor'));
+ throw new Trails\Exception(404, _('Unbekannter Deskriptor'));
}
$def_lang = $deskriptor->modul->getDefaultLanguage();
if ($language === $def_lang) {
- throw new Trails_Exception(403, _('Ein Deskriptor in der Original-Sprache kann nicht gelöscht werden.'));
+ throw new Trails\Exception(403, _('Ein Deskriptor in der Original-Sprache kann nicht gelöscht werden.'));
}
if (Request::submitted('delete')) {
CSRFProtection::verifyUnsafeRequest();
@@ -819,17 +819,17 @@ class Module_ModuleController extends MVVController
* Deletes a descriptor from Modulteil
*
* @param type $deskriptor_id
- * @throws Trails_Exception
+ * @throws Trails\Exception
*/
public function delete_modulteil_deskriptor_action($deskriptor_id, $language)
{
$deskriptor = ModulteilDeskriptor::find($deskriptor_id);
if (is_null($deskriptor)) {
- throw new Trails_Exception(404, _('Unbekannter Deskriptor'));
+ throw new Trails\Exception(404, _('Unbekannter Deskriptor'));
}
$def_lang = $deskriptor->modulteil->getDefaultLanguage();
if ($language === $def_lang) {
- throw new Trails_Exception(403, _('Ein Deskriptor in der Original-Sprache kann nicht gelöscht werden.'));
+ throw new Trails\Exception(403, _('Ein Deskriptor in der Original-Sprache kann nicht gelöscht werden.'));
}
if (Request::submitted('delete')) {
CSRFProtection::verifyUnsafeRequest();
diff --git a/app/controllers/module/mvv_controller.php b/app/controllers/module/mvv_controller.php
index e84b37c..b70ddef 100644
--- a/app/controllers/module/mvv_controller.php
+++ b/app/controllers/module/mvv_controller.php
@@ -77,7 +77,7 @@ abstract class MVVController extends AuthenticatedController
PageLayout::setTitle(_('Module'));
// Setup flash instance
- $this->flash = Trails_Flash::instance();
+ $this->flash = Trails\Flash::instance();
$this->me = 'mvv';
self::$items_per_page = Config::get()->getValue('ENTRIES_PER_PAGE');
@@ -218,7 +218,7 @@ abstract class MVVController extends AuthenticatedController
* This action is used to show a select box instead of an input field
* if the user has clicked on the magnifier icon of a quicksearch.
*
- * @throws Trails_Exception
+ * @throws Trails\Exception
*/
public function qs_result_action()
{
@@ -228,7 +228,7 @@ abstract class MVVController extends AuthenticatedController
Request::get('qs_term')
));
} else {
- throw new Trails_Exception(404);
+ throw new Trails\Exception(404);
}
}
diff --git a/app/controllers/oer/endpoints.php b/app/controllers/oer/endpoints.php
index 31563f5..9a0f3f5 100644
--- a/app/controllers/oer/endpoints.php
+++ b/app/controllers/oer/endpoints.php
@@ -410,7 +410,7 @@ class Oer_EndpointsController extends StudipController
$this->response->add_header('Content-Length', filesize($this->material->getFrontImageFilePath()));
$this->render_text(file_get_contents($this->material->getFrontImageFilePath()));
} else {
- throw new Trails_Exception(404);
+ throw new Trails\Exception(404);
}
}
diff --git a/app/controllers/search/studiengaenge.php b/app/controllers/search/studiengaenge.php
index ae27106..e17eb2a 100644
--- a/app/controllers/search/studiengaenge.php
+++ b/app/controllers/search/studiengaenge.php
@@ -423,7 +423,7 @@ class Search_StudiengaengeController extends MVVController
{
$this->abschnitt = StgteilAbschnitt::find($abschnitt_id);
if (!$this->abschnitt) {
- throw new Trails_Exception(404);
+ throw new Trails\Exception(404);
}
$this->render_template('search/studiengaenge/kommentar', $this->layout);
}
diff --git a/app/controllers/settings/settings.php b/app/controllers/settings/settings.php
index 327b62d..9cd00c0 100644
--- a/app/controllers/settings/settings.php
+++ b/app/controllers/settings/settings.php
@@ -121,7 +121,7 @@ abstract class Settings_SettingsController extends AuthenticatedController
public function get_default_template($action)
{
$class = get_class($this);
- $controller_name = Trails_Inflector::underscore(mb_substr($class, 0, -10));
+ $controller_name = Trails\Inflector::underscore(mb_substr($class, 0, -10));
return file_exists($this->dispatcher->trails_root . '/views/' . $controller_name . '.php')
? $controller_name
: $controller_name . '/' . $action;
diff --git a/app/controllers/shared/contacts.php b/app/controllers/shared/contacts.php
index 62dd7a8..820d2ab 100644
--- a/app/controllers/shared/contacts.php
+++ b/app/controllers/shared/contacts.php
@@ -114,7 +114,7 @@ class Shared_ContactsController extends MVVController
if ($this->contact_id) {
$contact_range = MvvContactRange::findOneBySQL('contact_id=?', [$this->contact_id]);
if (!$contact_range) {
- throw new Trails_Exception(404);
+ throw new Trails\Exception(404);
}
$this->relations = $contact_range->getRelations($this->filter);
$this->origin = 'index';
@@ -155,7 +155,7 @@ class Shared_ContactsController extends MVVController
{
$this->contact_range = MvvContactRange::findOneBySQL('contact_id = ?', [$contact_id]);
if (!$this->contact_range) {
- throw new Trails_Exception(404);
+ throw new Trails\Exception(404);
}
$this->relations = $this->contact_range->getRelations($this->filter);
diff --git a/app/controllers/siteinfo.php b/app/controllers/siteinfo.php
index ab81660..7bc95cb 100644
--- a/app/controllers/siteinfo.php
+++ b/app/controllers/siteinfo.php
@@ -37,7 +37,7 @@ class SiteinfoController extends StudipController
} else {
$action = 'show';
if ($this->page_is_draft || ($this->page_disabled_nobody && $GLOBALS['user']->id === 'nobody')) {
- throw new Trails_Exception(404);
+ throw new Trails\Exception(404);
}
}
$this->add_navigation($action);
diff --git a/app/controllers/studiengaenge/abschluesse.php b/app/controllers/studiengaenge/abschluesse.php
index 8ec055b..60bc091 100644
--- a/app/controllers/studiengaenge/abschluesse.php
+++ b/app/controllers/studiengaenge/abschluesse.php
@@ -50,7 +50,7 @@ class Studiengaenge_AbschluesseController extends Studiengaenge_StudiengaengeCon
$perm_institutes = MvvPerm::getOwnInstitutes();
$abschluss = Abschluss::find($abschluss_id);
if (!$abschluss) {
- throw new Trails_Exception(404);
+ throw new Trails\Exception(404);
}
$this->abschluss_id = $abschluss->id;
if (count($perm_institutes)) {
@@ -59,7 +59,7 @@ class Studiengaenge_AbschluesseController extends Studiengaenge_StudiengaengeCon
$perm_institutes
);
if (!count($institutes_abschluss)) {
- throw new Trails_Exception(403);
+ throw new Trails\Exception(403);
}
$this->studiengaenge = SimpleORMapCollection::createFromArray(
Studiengang::findByAbschluss_id($this->abschluss_id)
@@ -91,4 +91,4 @@ class Studiengaenge_AbschluesseController extends Studiengaenge_StudiengaengeCon
$this->perform_relayed('index');
}
}
-} \ No newline at end of file
+}
diff --git a/app/controllers/studiengaenge/fachbereiche.php b/app/controllers/studiengaenge/fachbereiche.php
index 970c8d9..35f997b 100644
--- a/app/controllers/studiengaenge/fachbereiche.php
+++ b/app/controllers/studiengaenge/fachbereiche.php
@@ -51,7 +51,7 @@ class Studiengaenge_FachbereicheController extends Studiengaenge_StudiengaengeCo
$this->fachbereich_id = $fachbereich_id;
if (count($perm_institutes)) {
if (!in_array($this->fachbereich_id, $perm_institutes)) {
- throw new Trails_Exception(403);
+ throw new Trails\Exception(403);
}
}
diff --git a/app/controllers/studiengaenge/fachbereichestgteile.php b/app/controllers/studiengaenge/fachbereichestgteile.php
index c8037dc..73ad2aa 100644
--- a/app/controllers/studiengaenge/fachbereichestgteile.php
+++ b/app/controllers/studiengaenge/fachbereichestgteile.php
@@ -67,7 +67,7 @@ class Studiengaenge_FachbereichestgteileController extends Studiengaenge_Studien
$this->fachbereich = $fachbereich;
$this->perform_relayed('stgteil');
} else {
- throw new Trails_Exception(404);
+ throw new Trails\Exception(404);
}
}
}
diff --git a/app/controllers/studiengaenge/faecher.php b/app/controllers/studiengaenge/faecher.php
index c9546a3..9990f7d 100644
--- a/app/controllers/studiengaenge/faecher.php
+++ b/app/controllers/studiengaenge/faecher.php
@@ -83,7 +83,7 @@ class Studiengaenge_FaecherController extends Studiengaenge_StudiengangteileCont
$this->stgteil = StudiengangTeil::get();
$this->stgteil->assignFach($fach->getId());
} else {
- throw new Trails_Exception(404);
+ throw new Trails\Exception(404);
}
$this->perform_relayed('stgteil');
}
diff --git a/app/controllers/studiengaenge/kategorien.php b/app/controllers/studiengaenge/kategorien.php
index 03d28fc..8f6a98d 100644
--- a/app/controllers/studiengaenge/kategorien.php
+++ b/app/controllers/studiengaenge/kategorien.php
@@ -73,7 +73,7 @@ class Studiengaenge_KategorienController extends Studiengaenge_StudiengaengeCont
if (count($perm_institutes)) {
if (!in_array($studiengang->institut_id, $perm_institutes)) {
- throw new Trails_Exception(403);
+ throw new Trails\Exception(403);
}
}
@@ -98,4 +98,4 @@ class Studiengaenge_KategorienController extends Studiengaenge_StudiengaengeCont
$this->perform_relayed('index');
}
}
-} \ No newline at end of file
+}
diff --git a/app/controllers/studiengaenge/shared_version.php b/app/controllers/studiengaenge/shared_version.php
index 696fac0..a6265b0 100644
--- a/app/controllers/studiengaenge/shared_version.php
+++ b/app/controllers/studiengaenge/shared_version.php
@@ -11,18 +11,18 @@ abstract class SharedVersionController extends MVVController
{
$this->stgteil = StudiengangTeil::find($stgteil_id);
if (!$this->stgteil) {
- throw new Trails_Exception(404);
+ throw new Trails\Exception(404);
}
if (!MvvPerm::haveFieldPermVersionen($this->stgteil, MvvPerm::PERM_READ)) {
- throw new Trails_Exception(403);
+ throw new Trails\Exception(403);
}
if (!isset($this->version)) {
$this->version = StgteilVersion::find($version_id);
if (!$this->version) {
if (!MvvPerm::haveFieldPermVersionen($this->stgteil, MvvPerm::PERM_CREATE)) {
- throw new Trails_Exception(403);
+ throw new Trails\Exception(403);
}
$this->version = new StgteilVersion();
}
@@ -51,7 +51,7 @@ abstract class SharedVersionController extends MVVController
if (Request::submitted('store')) {
CSRFProtection::verifyUnsafeRequest();
if (!MvvPerm::haveFieldPermVersionen($this->stgteil)) {
- throw new Trails_Exception(403);
+ throw new Trails\Exception(403);
}
$stored = false;
$this->version->stgteil_id = $this->stgteil->getId();
@@ -220,7 +220,7 @@ abstract class SharedVersionController extends MVVController
{
$version = StgteilVersion::find($version_id);
if (!$version) {
- throw new Trails_Exception(404, _('Unbekannte Version'));
+ throw new Trails\Exception(404, _('Unbekannte Version'));
}
if (Request::isPost()) {
CSRFProtection::verifyUnsafeRequest();
@@ -267,16 +267,16 @@ abstract class SharedVersionController extends MVVController
$perm = MvvPerm::get($this->version);
if (!$perm->haveFieldPerm('abschnitte', MvvPerm::PERM_READ)) {
- throw new Trails_Exception(403);
+ throw new Trails\Exception(403);
}
if ($this->abschnitt->isNew() && !$perm->haveFieldPerm('abschnitte', MvvPerm::PERM_CREATE)) {
- throw new Trails_Exception(403);
+ throw new Trails\Exception(403);
}
if (Request::submitted('store')) {
CSRFProtection::verifyUnsafeRequest();
if (!$perm->haveFieldPerm('abschnitte', MvvPerm::PERM_WRITE)) {
- throw new Trails_Exception(403);
+ throw new Trails\Exception(403);
}
$this->abschnitt->version_id = $this->version->getId();
$this->abschnitt->name = Request::i18n('name')->trim();
@@ -494,7 +494,7 @@ abstract class SharedVersionController extends MVVController
$abschnitt = StgteilAbschnitt::find($abschnitt_id);
if ($abschnitt) {
if (!MvvPerm::haveFieldPermModul_zuordnungen($abschnitt, MvvPerm::PERM_CREATE)) {
- throw new Trails_Exception(403);
+ throw new Trails\Exception(403);
}
$modul = Modul::find($modul_id);
if (!$modul) {
@@ -614,7 +614,7 @@ abstract class SharedVersionController extends MVVController
{
$version = StgteilVersion::find($version_id);
if (!$version) {
- throw new Trails_Exception(404, _('Unbekannte Version'));
+ throw new Trails\Exception(404, _('Unbekannte Version'));
} else {
if (Request::isPost()) {
CSRFProtection::verifyUnsafeRequest();
@@ -754,7 +754,7 @@ abstract class SharedVersionController extends MVVController
$this->redirect($this->action_url('abschnitte/' . $version_id));
}
} else {
- throw new Trails_Exception(403);
+ throw new Trails\Exception(403);
}
}
if (Request::isXhr()) {
diff --git a/app/controllers/studiengaenge/studiengaenge.php b/app/controllers/studiengaenge/studiengaenge.php
index d053f48..8465665 100644
--- a/app/controllers/studiengaenge/studiengaenge.php
+++ b/app/controllers/studiengaenge/studiengaenge.php
@@ -541,7 +541,7 @@ class Studiengaenge_StudiengaengeController extends MVVController
if (Request::isPost()) {
CSRFProtection::verifyRequest();
if (!MvvPerm::haveFieldPermStudiengangteile($studiengang, MvvPerm::PERM_CREATE)) {
- throw new Trails_Exception(403);
+ throw new Trails\Exception(403);
}
$stgteil_name = $this->stg_stgteil->stgteil_name;
$stgbez_name = $this->stg_stgteil->stgbez_name;
@@ -588,7 +588,7 @@ class Studiengaenge_StudiengaengeController extends MVVController
if (Request::isPost()) {
CSRFProtection::verifyUnsafeRequest();
if (!MvvPerm::haveFieldPermStudiengangteile($studiengang, MvvPerm::PERM_CREATE)) {
- throw new Trails_Exception(403);
+ throw new Trails\Exception(403);
}
$stgteil_name = $stg_stgteil->stgteil_name;
$stgbez_name = $stg_stgteil->stgbez_name;
diff --git a/app/controllers/studiengaenge/studiengangteile.php b/app/controllers/studiengaenge/studiengangteile.php
index 0fddd44..bc1449f 100644
--- a/app/controllers/studiengaenge/studiengangteile.php
+++ b/app/controllers/studiengaenge/studiengangteile.php
@@ -144,7 +144,7 @@ class Studiengaenge_StudiengangteileController extends SharedVersionController
$this->stgteil->contact_assignments = $stgteil_orig->contact_assignments;
} else {
- throw new Trails_Exception(404);
+ throw new Trails\Exception(404);
}
$this->perform_relayed('stgteil');
}
diff --git a/app/controllers/studiengaenge/versionen.php b/app/controllers/studiengaenge/versionen.php
index 9b60b3d..41625bf 100644
--- a/app/controllers/studiengaenge/versionen.php
+++ b/app/controllers/studiengaenge/versionen.php
@@ -52,7 +52,7 @@ class Studiengaenge_VersionenController extends SharedVersionController
$this->redirect($this->action_url('index/' . $this->chooser_filter['stgteile']));
return;
default :
- throw new Trails_Exception(400);
+ throw new Trails\Exception(400);
}
$this->name = $list;
if (!empty($this->lists[$list]['elements'])) {
@@ -218,7 +218,7 @@ class Studiengaenge_VersionenController extends SharedVersionController
if ($stgteil_id) {
$this->stgteil = StudiengangTeil::find($stgteil_id);
if (!$this->stgteil) {
- throw new Trails_Exception(404, _('Unbekannter Studiengangteil'));
+ throw new Trails\Exception(404, _('Unbekannter Studiengangteil'));
}
$this->initPageParams();
diff --git a/app/views/consultation/admin/create.php b/app/views/consultation/admin/create.php
index c973ccf..3da70e0 100644
--- a/app/views/consultation/admin/create.php
+++ b/app/views/consultation/admin/create.php
@@ -1,7 +1,7 @@
<?php
/**
* @var Consultation_AdminController $controller
- * @var Trails_Flash $flash
+ * @var Trails\Flash $flash
* @var string|null $room
* @var array $responsible
* @var Range $range
diff --git a/app/views/news/admin_news.php b/app/views/news/admin_news.php
index db07d03..e12047a 100644
--- a/app/views/news/admin_news.php
+++ b/app/views/news/admin_news.php
@@ -2,7 +2,7 @@
/**
* @var NewsController $controller
* @var string $area_type
- * @var Trails_Flash $flash
+ * @var Trails\Flash $flash
* @var string $news_searchterm
* @var string $news_startdate
* @var string $news_enddate
diff --git a/cli/Commands/Checks/HelpTours.php b/cli/Commands/Checks/HelpTours.php
index b4b2fa7..b0c201a 100644
--- a/cli/Commands/Checks/HelpTours.php
+++ b/cli/Commands/Checks/HelpTours.php
@@ -59,7 +59,7 @@ class HelpTours extends Command
$plugin = new $plugin_info['class']();
if ($result[1]) {
- $dispatcher = app(\Trails_Dispatcher::class);
+ $dispatcher = app(\Trails\Dispatcher::class);
$dispatcher->trails_root = $GLOBALS['ABSOLUTE_PATH_STUDIP'] . $plugin->getPluginPath();
$dispatcher->trails_uri = rtrim(\PluginEngine::getLink($plugin, [], null, true), '/');
$dispatcher->default_controller = 'index';
@@ -71,7 +71,7 @@ class HelpTours extends Command
}
}
} elseif (match_route('dispatch.php/*', $step->route)) {
- $dispatcher = app(\Trails_Dispatcher::class);
+ $dispatcher = app(\Trails\Dispatcher::class);
$parsed = $dispatcher->parse(substr($step->route, strlen('dispatch.php') + 1));
$controller = $dispatcher->load_controller($parsed[0]);
if ($parsed[1] && !$controller->has_action($parsed[1])) {
diff --git a/lib/bootstrap-autoload.php b/lib/bootstrap-autoload.php
index 0bbad81..cc39fe7 100644
--- a/lib/bootstrap-autoload.php
+++ b/lib/bootstrap-autoload.php
@@ -63,6 +63,22 @@ class_alias(Flexi\Template::class, 'Flexi_Template');
class_alias(Flexi\Factory::class, 'Flexi_TemplateFactory');
class_alias(Flexi\TemplateNotFoundException::class, 'Flexi_TemplateNotFoundException');
+// Trails
+StudipAutoloader::addAutoloadPath('lib/trails', 'Trails');
+class_alias(Trails\Controller::class, 'Trails_Controller');
+class_alias(Trails\Dispatcher::class, 'Trails_Dispatcher');
+class_alias(Trails\Exception::class, 'Trails_Exception');
+class_alias(Trails\Flash::class, 'Trails_Flash');
+class_alias(Trails\Inflector::class, 'Trails_Inflector');
+class_alias(Trails\Response::class, 'Trails_Response');
+
+class_alias(Trails\Exceptions\DoubleRenderError::class, 'Trails_DoubleRenderError');
+class_alias(Trails\Exceptions\MissingFile::class, 'Trails_MissingFile');
+class_alias(Trails\Exceptions\RoutingError::class, 'Trails_RoutingError');
+class_alias(Trails\Exceptions\SessionRequiredException::class, 'Trails_SessionRequiredException');
+class_alias(Trails\Exceptions\UnknownAction::class, 'Trails_UnknownAction');
+class_alias(Trails\Exceptions\UnknownController::class, 'Trails_UnknownController');
+
// Messy file names
StudipAutoloader::addClassLookups([
'email_validation_class' => 'lib/phplib/email_validation.class.php',
@@ -71,19 +87,6 @@ StudipAutoloader::addClassLookups([
'MVVController' => 'app/controllers/module/mvv_controller.php'
]);
-// Trails
-$trails_classes = [
- 'Trails_Dispatcher', 'Trails_Response', 'Trails_Controller',
- 'Trails_Inflector', 'Trails_Flash',
- 'Trails_Exception', 'Trails_DoubleRenderError', 'Trails_MissingFile',
- 'Trails_RoutingError', 'Trails_UnknownAction', 'Trails_UnknownController',
- 'Trails_SessionRequiredException',
-];
-StudipAutoloader::addClassLookup(
- $trails_classes,
- 'vendor/trails/trails.php'
-);
-
// Vendor
StudipAutoloader::addClassLookups([
'PasswordHash' => 'vendor/phpass/PasswordHash.php',
diff --git a/lib/bootstrap-definitions.php b/lib/bootstrap-definitions.php
index ee80135..d34d023 100644
--- a/lib/bootstrap-definitions.php
+++ b/lib/bootstrap-definitions.php
@@ -20,7 +20,7 @@ return [
StudipPDO::class => DI\factory(function () {
return DBManager::get();
}),
- Trails_Dispatcher::class => DI\factory(function (ContainerInterface $container) {
+ Trails\Dispatcher::class => DI\factory(function (ContainerInterface $container) {
return new \StudipDispatcher($container);
}),
];
diff --git a/lib/classes/OAuth2/NegotiatesWithPsr7.php b/lib/classes/OAuth2/NegotiatesWithPsr7.php
index 0edf243..b2ee5a1 100644
--- a/lib/classes/OAuth2/NegotiatesWithPsr7.php
+++ b/lib/classes/OAuth2/NegotiatesWithPsr7.php
@@ -5,7 +5,7 @@ namespace Studip\OAuth2;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Slim\Psr7\Response;
-use Trails_Response;
+use Trails\Response as TrailsResponse;
trait NegotiatesWithPsr7
{
@@ -19,9 +19,9 @@ trait NegotiatesWithPsr7
return new Response();
}
- protected function convertPsrResponse(ResponseInterface $response): Trails_Response
+ protected function convertPsrResponse(ResponseInterface $response): TrailsResponse
{
- $trailsResponse = new Trails_Response((string) $response->getBody(), [], $response->getStatusCode());
+ $trailsResponse = new TrailsResponse((string) $response->getBody(), [], $response->getStatusCode());
foreach ($response->getHeaders() as $key => $values) {
foreach ($values as $value) {
$trailsResponse->add_header($key, $value);
diff --git a/lib/classes/StudipController.php b/lib/classes/StudipController.php
index ae316c1..4fbcc42 100644
--- a/lib/classes/StudipController.php
+++ b/lib/classes/StudipController.php
@@ -16,7 +16,7 @@ use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
/**
* @property StudipResponse $response
*/
-abstract class StudipController extends Trails_Controller
+abstract class StudipController extends Trails\Controller
{
use StudipControllerPropertiesTrait;
@@ -48,7 +48,7 @@ abstract class StudipController extends Trails_Controller
$GLOBALS['auth']->login_if((Request::get('again') || !$this->allow_nobody) && $GLOBALS['user']->id == 'nobody');
// Setup flash instance
- $this->flash = Trails_Flash::instance();
+ $this->flash = Trails\Flash::instance();
// set up user session
include 'lib/seminar_open.php';
@@ -107,7 +107,7 @@ abstract class StudipController extends Trails_Controller
*
* @param String $unconsumed_path Path segment containing action and
* optionally arguments or format
- * @return Trails_Response from parent controller
+ * @return Trails\Response from parent controller
*/
public function perform($unconsumed_path)
{
@@ -212,7 +212,7 @@ abstract class StudipController extends Trails_Controller
case 'option':
if (preg_match('/[^\\w,-]/', $arg)) {
- throw new Trails_Exception(400);
+ throw new Trails\Exception(400);
}
break;
@@ -231,7 +231,7 @@ abstract class StudipController extends Trails_Controller
$sorm = $reflection->newInstance($id);
if (!$info['optional'] && $sorm->isNew()) {
- throw new Trails_Exception(
+ throw new Trails\Exception(
404,
"Parameter {$info['var']} could not be resolved with value {$arg}"
);
@@ -247,7 +247,7 @@ abstract class StudipController extends Trails_Controller
break;
default:
- throw new Trails_Exception(500, 'Unknown type "' . $type . '"');
+ throw new Trails\Exception(500, 'Unknown type "' . $type . '"');
}
}
@@ -497,11 +497,11 @@ abstract class StudipController extends Trails_Controller
$chunk_size = 262144
) {
if (!file_exists($file)) {
- throw new Trails_Exception(404);
+ throw new Trails\Exception(404);
}
if (!is_readable($file)) {
- throw new Trails_Exception(500);
+ throw new Trails\Exception(500);
}
if ($content_type === null) {
@@ -593,7 +593,7 @@ abstract class StudipController extends Trails_Controller
* through
*
* @param string $to_uri a trails route
- * @return Trails_Response
+ * @return Trails\Response
*/
public function relay($to_uri/* , ... */)
{
@@ -617,11 +617,11 @@ abstract class StudipController extends Trails_Controller
* Relays current request and performs redirect if neccessary.
*
* @param string $to_uri a trails route
- * @return Trails_Response
+ * @return Trails\Response
*
* @see StudipController::relay()
*/
- public function relayWithRedirect(...$args): Trails_Response
+ public function relayWithRedirect(...$args): Trails\Response
{
$response = $this->relay(...$args);
@@ -641,7 +641,7 @@ abstract class StudipController extends Trails_Controller
*
* @see perform
* @param string $unconsumed
- * @return Trails_Response
+ * @return Trails\Response
*/
public function perform_relayed($unconsumed/* , ... */)
{
@@ -695,9 +695,9 @@ abstract class StudipController extends Trails_Controller
* <code>$controller->baz($param)</code>
*
* @param String $method Called method name
- * @param array $argumetns Provided arguments
- * @return url to the requested action
- * @throws Trails_UnknownAction if no action matches the method
+ * @param array $arguments Provided arguments
+ * @return string url to the requested action
+ * @throws Trails\Exceptions\UnknownAction if no action matches the method
*/
public function __call($method, $arguments)
{
@@ -710,7 +710,7 @@ abstract class StudipController extends Trails_Controller
}
if (!$this->has_action($method)) {
- throw new Trails_UnknownAction("Unknown action '{$method}'");
+ throw new Trails\Exceptions\UnknownAction("Unknown action '{$method}'");
}
array_unshift($arguments, $method);
@@ -858,7 +858,7 @@ abstract class StudipController extends Trails_Controller
// Extract controller name from class name
$controller = preg_replace('/Controller$/', '', get_class($this));
- $controller = Trails_Inflector::underscore($controller);
+ $controller = Trails\Inflector::underscore($controller);
// Build main parts of the body element id
$body_id_parts = explode('/', $controller);
diff --git a/lib/classes/StudipDispatcher.php b/lib/classes/StudipDispatcher.php
index af0ea48..a41635a 100644
--- a/lib/classes/StudipDispatcher.php
+++ b/lib/classes/StudipDispatcher.php
@@ -18,29 +18,31 @@ use Psr\Container\ContainerInterface;
/**
* Use this subclass to easily get an Stud.IP specific
- * Trails_Dispatcher.
+ * Trails\Dispatcher.
*
* Example of use:
+ *
* @code
* // deep in the Stud.IP jungle
* $dispatcher = new StudipDispatcher();
* $dispatcher->dispatch($requested_uri);
* @endcode
*/
-class StudipDispatcher extends Trails_Dispatcher {
-
- /**
- * This variable contains the DI-Container.
- * @var ContainerInterface
- */
- protected $container;
+class StudipDispatcher extends Trails\Dispatcher
+{
+ /**
+ * This variable contains the DI-Container.
+ *
+ * @var ContainerInterface
+ */
+ protected $container;
- /**
- * Create a new Trails_Dispatcher with Stud.IP specific parameters
- * for: trails_root is "$STUDIP_BASE_PATH/app", trails_uri is
- * "dispatch.php" and default_controller is "default" (which does
- * not map to anything).
- */
+ /**
+ * Create a new Trails\Dispatcher with Stud.IP specific parameters
+ * for: trails_root is "$STUDIP_BASE_PATH/app", trails_uri is
+ * "dispatch.php" and default_controller is "default" (which does
+ * not map to anything).
+ */
public function __construct(ContainerInterface $container)
{
global $STUDIP_BASE_PATH, $ABSOLUTE_URI_STUDIP;
@@ -58,6 +60,7 @@ class StudipDispatcher extends Trails_Dispatcher {
* exception instead of the standard trails handling.
*
* @param Exception $exception The exception that occured
+ *
* @throws Exception
*/
public function trails_error($exception)
@@ -66,21 +69,22 @@ class StudipDispatcher extends Trails_Dispatcher {
}
/**
- * Loads the controller file for a given controller path and return an
- * instance of that controller. If an error occures, an exception will be
- * thrown.
- *
- * @param string the relative controller path
- *
- * @return TrailsController an instance of that controller
- */
- function load_controller($controller) {
- require_once "{$this->trails_root}/controllers/{$controller}.php";
- $class = Trails_Inflector::camelize($controller) . 'Controller';
- if (!class_exists($class)) {
- throw new Trails_UnknownController("Controller missing: '$class'");
- }
+ * Loads the controller file for a given controller path and return an
+ * instance of that controller. If an error occures, an exception will be
+ * thrown.
+ *
+ * @param string $controller the relative controller path
+ * @return Trails\Controller an instance of that controller
+ * @throws \Trails\Exceptions\UnknownController
+ */
+ public function load_controller($controller)
+ {
+ require_once "{$this->trails_root}/controllers/{$controller}.php";
+ $class = Trails\Inflector::camelize($controller) . 'Controller';
+ if (!class_exists($class)) {
+ throw new Trails\Exceptions\UnknownController("Controller missing: '$class'");
+ }
- return $this->container->make($class, ['dispatcher' => $this]);
- }
+ return $this->container->make($class, ['dispatcher' => $this]);
+ }
}
diff --git a/lib/classes/StudipResponse.php b/lib/classes/StudipResponse.php
index 1c15326..a9f1a4c 100644
--- a/lib/classes/StudipResponse.php
+++ b/lib/classes/StudipResponse.php
@@ -1,5 +1,5 @@
<?php
-class StudipResponse extends Trails_Response
+class StudipResponse extends Trails\Response
{
/**
* Outputs this response to the client using "echo" and "header".
diff --git a/lib/functions.php b/lib/functions.php
index 6b00608..e1b29ed 100644
--- a/lib/functions.php
+++ b/lib/functions.php
@@ -1319,7 +1319,7 @@ function get_route($route = '')
$route = 'plugins.php/' . $pieces[0] . (!empty($pieces[1]) ? '/' . $pieces[1] : '') . (!empty($pieces[2]) ? '/' . $pieces[2] : '');
} elseif (mb_strpos($route, 'dispatch.php/') !== false) {
$trails = explode('dispatch.php/', $route);
- $dispatcher = app(\Trails_Dispatcher::class);
+ $dispatcher = app(\Trails\Dispatcher::class);
$pieces = explode('/', $trails[1]);
$trail = '';
foreach ($pieces as $index => $piece) {
@@ -1399,7 +1399,7 @@ function studip_default_exception_handler($exception) {
} elseif ($exception instanceof LoginException) {
$GLOBALS['auth']->login_if(true);
} else {
- if ($exception instanceOf Trails_Exception) {
+ if ($exception instanceOf Trails\Exception) {
$status = $exception->getCode();
} else {
$status = 500;
@@ -1458,6 +1458,19 @@ function strtocamelcase($string, $ucfirst = false) {
}
/**
+ * Converts a string to PascalCase.
+ *
+ * @param String $string The string that should be converted
+ * @return String containing the converted input string
+ */
+function strtopascalcase(string $string): string {
+ return strtocamelcase(
+ str_replace('_', ' ', $string),
+ true
+ );
+}
+
+/**
* Converts a string to snake_case.
*
* @param String $string The string that should be converted
diff --git a/lib/modules/EvaluationsWidget.php b/lib/modules/EvaluationsWidget.php
index dab271f..21410e2 100644
--- a/lib/modules/EvaluationsWidget.php
+++ b/lib/modules/EvaluationsWidget.php
@@ -43,7 +43,7 @@ class EvaluationsWidget extends CorePlugin implements PortalPlugin
}
// include and show votes and tests
- $controller = app(AuthenticatedController::class, ['dispatcher' => app(\Trails_Dispatcher::class)]);
+ $controller = app(AuthenticatedController::class, ['dispatcher' => app(\Trails\Dispatcher::class)]);
$controller->suppress_empty_output = true;
$response = $controller->relay('questionnaire/widget/start')->body;
diff --git a/lib/modules/MyCoursesWidget.php b/lib/modules/MyCoursesWidget.php
index 81aceed..ba73e5b 100644
--- a/lib/modules/MyCoursesWidget.php
+++ b/lib/modules/MyCoursesWidget.php
@@ -26,7 +26,7 @@ class MyCoursesWidget extends CorePlugin implements PortalPlugin
public function getPortalTemplate()
{
// get the MyCoursesController in order to prepare the correct data for the overview
- $controller = app(MyCoursesController::class, ['dispatcher' => app(\Trails_Dispatcher::class)]);
+ $controller = app(MyCoursesController::class, ['dispatcher' => app(\Trails\Dispatcher::class)]);
$data = $controller->getPortalWidgetData();
// add the json data to the head so vue can grab it
diff --git a/lib/modules/NewsWidget.php b/lib/modules/NewsWidget.php
index fc3befd..ae211f2 100644
--- a/lib/modules/NewsWidget.php
+++ b/lib/modules/NewsWidget.php
@@ -25,7 +25,7 @@ class NewsWidget extends CorePlugin implements PortalPlugin
function getPortalTemplate()
{
- $controller = app(\Trails_Dispatcher::class)->load_controller('news');
+ $controller = app(\Trails\Dispatcher::class)->load_controller('news');
$response = $controller->relayWithRedirect('news/display/studip');
$template = $GLOBALS['template_factory']->open('shared/string');
$template->content = $response->body;
diff --git a/lib/modules/TerminWidget.php b/lib/modules/TerminWidget.php
index 773e692..4274ee4 100644
--- a/lib/modules/TerminWidget.php
+++ b/lib/modules/TerminWidget.php
@@ -26,7 +26,7 @@ class TerminWidget extends CorePlugin implements PortalPlugin
public function getPortalTemplate()
{
- $controller = app(\Trails_Dispatcher::class)->load_controller('calendar/contentbox');
+ $controller = app(\Trails\Dispatcher::class)->load_controller('calendar/contentbox');
$response = $controller->relay('calendar/contentbox/display/'.$GLOBALS['user']->id);
$template = $GLOBALS['template_factory']->open('shared/string');
$template->content = $response->body;
diff --git a/lib/plugins/core/StudIPPlugin.class.php b/lib/plugins/core/StudIPPlugin.class.php
index ea5c8ff..fe74259 100644
--- a/lib/plugins/core/StudIPPlugin.class.php
+++ b/lib/plugins/core/StudIPPlugin.class.php
@@ -196,14 +196,14 @@ abstract class StudIPPlugin
$action = $args[0] !== '' ? array_shift($args).'_action' : 'show_action';
if (!method_exists($this, $action)) {
- $dispatcher = app(\Trails_Dispatcher::class);
+ $dispatcher = app(\Trails\Dispatcher::class);
$dispatcher->trails_root = $this->getPluginPath();
$dispatcher->trails_uri = rtrim(PluginEngine::getLink($this, [], null, true), '/');
$dispatcher->default_controller = 'index';
$dispatcher->current_plugin = $this;
try {
$dispatcher->dispatch($unconsumed_path);
- } catch (Trails_UnknownAction $exception) {
+ } catch (Trails\Exceptions\UnknownAction $exception) {
if (count($args) > 0) {
throw $exception;
} else {
diff --git a/lib/seminar_open.php b/lib/seminar_open.php
index 1c0056b..2e831bf 100644
--- a/lib/seminar_open.php
+++ b/lib/seminar_open.php
@@ -216,7 +216,7 @@ if (is_object($GLOBALS['user'])
if (!Request::isXhr()) {
header('Location: ' . URLHelper::getURL('dispatch.php/terms', ['return_to' => $_SERVER['REQUEST_URI'], 'redirect_token' => Token::create(600)], true));
} else {
- throw new Trails_Exception(400);
+ throw new Trails\Exception(400);
}
page_close();
die;
diff --git a/lib/trails/Controller.php b/lib/trails/Controller.php
new file mode 100644
index 0000000..a5a0ba7
--- /dev/null
+++ b/lib/trails/Controller.php
@@ -0,0 +1,411 @@
+<?php
+namespace Trails;
+
+use Flexi\Factory;
+use Flexi\Template;
+use Flexi\TemplateNotFoundException;
+use Trails\Exceptions\DoubleRenderError;
+use Trails\Exceptions\UnknownAction;
+
+/**
+ * A Controller is responsible for matching the unconsumed part of an URI
+ * to an action using the left over words as arguments for that action. The
+ * action is then mapped to method of the controller instance which is called
+ * with the just mentioned arguments. That method can send the #render_action,
+ * #render_template, #render_text, #render_nothing or #redirect method.
+ * Otherwise the #render_action is called with the current action as argument.
+ * If the action method sets instance variables during performing, they will be
+ * be used as attributes for the flexi-template opened by #render_action or
+ * #render_template. A controller's response's body is populated with the output
+ * of the #render_* methods. The action methods can add additional headers or
+ * change the status of that response.
+ *
+ * @package trails
+ *
+ * @author mlunzena
+ * @copyright (c) Authors
+ * @version $Id: trails.php 7001 2008-04-04 11:20:27Z mlunzena $
+ */
+class Controller
+{
+ protected Dispatcher $dispatcher;
+ protected Response $response;
+ protected bool $performed = false;
+ protected Template|string|null $layout;
+ protected string $format = 'html';
+
+ /**
+ * @param Dispatcher $dispatcher the dispatcher who creates this instance
+ */
+ public function __construct(Dispatcher $dispatcher)
+ {
+ $this->dispatcher = $dispatcher;
+ $this->erase_response();
+ }
+
+ /**
+ * Resets the response of the controller
+ *
+ * @return void
+ */
+ public function erase_response()
+ {
+ $this->performed = false;
+ $this->response = new Response();
+ }
+
+ /**
+ * Return this controller's response
+ *
+ * @return Response the controller's response
+ */
+ public function get_response()
+ {
+ return $this->response;
+ }
+
+ /**
+ * This method extracts an action string and further arguments from it's
+ * parameter. The action string is mapped to a method being called afterwards
+ * using the said arguments. That method is called and a response object is
+ * generated, populated and sent back to the dispatcher.
+ *
+ * @param string $unconsumed
+ *
+ * @return Response
+ * @throws UnknownAction
+ */
+ public function perform($unconsumed)
+ {
+ [$action, $args, $format] = $this->extract_action_and_args($unconsumed);
+
+ $this->format = $format ?? 'html';
+
+ $before_filter_result = $this->before_filter($action, $args);
+
+ # send action to controller
+ # TODO (mlunzena) shouldn't the after filter be triggered too?
+ if (!($before_filter_result === false || $this->performed)) {
+
+ $callable = $this->map_action($action);
+
+ if (is_callable($callable)) {
+ $callable(...$args);
+ } else {
+ $this->does_not_understand($action, $args);
+ }
+
+ if (!$this->performed) {
+ $this->render_action($action);
+ }
+
+ $this->after_filter($action, $args);
+ }
+
+ return $this->response;
+ }
+
+ /**
+ * Extracts action and args from a string.
+ *
+ * @param string $string the processed string
+ * @return array an array with two elements - a string containing the
+ * action and an array of strings representing the args
+ */
+ public function extract_action_and_args($string)
+ {
+ if ('' === $string) {
+ return $this->default_action_and_args();
+ }
+
+ // find optional file extension
+ $format = null;
+ if (preg_match('/^(.*[^\/.])\.(\w+)$/', $string, $matches)) {
+ [, $string, $format] = $matches;
+ }
+
+ // TODO this should possibly remove empty tokens
+ $args = explode('/', $string);
+ $action = array_shift($args);
+ return [$action, $args, $format];
+ }
+
+ /**
+ * Return the default action and arguments
+ *
+ * @return array containing the action, an array of args and the format
+ */
+ public function default_action_and_args()
+ {
+ return ['index', [], null];
+ }
+
+ /**
+ * Maps the action to an actual method name.
+ *
+ * @param string $action
+ * @return array the mapped method name
+ */
+ public function map_action($action)
+ {
+ return [&$this, $action . '_action'];
+ }
+
+ /**
+ * Callback function being called before an action is executed. If this
+ * function does not return FALSE, the action will be called, otherwise
+ * an error will be generated and processing will be aborted. If this function
+ * already #rendered or #redirected, further processing of the action is
+ * withheld.
+ *
+ * @param string $action Name of the action to perform.
+ * @param array $args An array of arguments to the action.
+ * @return bool|void
+ */
+ public function before_filter(&$action, &$args)
+ {
+ }
+
+ /**
+ * Callback function being called after an action is executed.
+ *
+ * @param string $action Name of the action to perform.
+ * @param array $args An array of arguments to the action.
+ * @return void
+ */
+ public function after_filter($action, $args)
+ {
+ }
+
+ /**
+ * @param string $action
+ * @param array $args
+ * @return void
+ * @throws UnknownAction
+ */
+ public function does_not_understand($action, $args)
+ {
+ throw new Exceptions\UnknownAction("No action responded to '$action'.");
+ }
+
+ /**
+ * @param string $to
+ *
+ * @return void
+ * @throws DoubleRenderError
+ */
+ public function redirect($to)
+ {
+ if ($this->performed) {
+ throw new Exceptions\DoubleRenderError();
+ }
+
+ $this->performed = true;
+
+ # get uri; keep absolute URIs
+ $url = preg_match('#^(/|\w+://)#', $to)
+ ? $to
+ : $this->url_for($to);
+
+ $this->response->add_header('Location', $url)->set_status(302);
+ }
+
+ /**
+ * Renders the given text as the body of the response.
+ *
+ * @param string $text the text to be rendered
+ * @return void
+ * @throws DoubleRenderError
+ */
+ public function render_text($text = ' ')
+ {
+ if ($this->performed) {
+ throw new Exceptions\DoubleRenderError();
+ }
+
+ $this->performed = true;
+
+ $this->response->set_body($text);
+ }
+
+ /**
+ * Renders the empty string as the response's body.
+ *
+ * @return void
+ * @throws DoubleRenderError
+ */
+ public function render_nothing()
+ {
+ $this->render_text('');
+ }
+
+ /**
+ * Renders the template of the given action as the response's body.
+ *
+ * @param string $action the action
+ * @return void
+ */
+ public function render_action($action)
+ {
+ $this->render_template(
+ $this->get_default_template($action),
+ $this->layout
+ );
+ }
+
+ public function get_default_template($action)
+ {
+ $controller_name = Inflector::underscore(
+ substr(static::class, 0, -10)
+ );
+ return $controller_name . '/' . $action;
+ }
+
+ /**
+ * Renders a template using an optional layout template.
+ *
+ * @param Template|string $template_name a flexi template
+ * @param Template|string|null $layout a flexi template which is used as layout
+ *
+ * @return void
+ * @throws DoubleRenderError
+ * @throws TemplateNotFoundException
+ */
+ public function render_template($template_name, $layout = null)
+ {
+ $factory = $this->get_template_factory();
+ $template = $factory->open($template_name);
+
+ $template->set_attributes($this->get_assigned_variables());
+
+ if (isset($layout)) {
+ $template->set_layout($layout);
+ }
+
+ $this->render_text($template->render());
+ }
+
+ /**
+ * Create and return a template factory for this controller.
+ *
+ * @return Factory
+ */
+ public function get_template_factory()
+ {
+ return new Factory($this->dispatcher->trails_root . '/views/');
+ }
+
+ /**
+ * This method returns all the set instance variables to be used as attributes
+ * for a template. This controller is returned too as value for
+ * key 'controller'.
+ *
+ * @return array an associative array of variables for the template
+ */
+ public function get_assigned_variables()
+ {
+ $assigns = [];
+ $protected = get_class_vars(static::class);
+
+ foreach (get_object_vars($this) as $var => $value) {
+ if (!array_key_exists($var, $protected)) {
+ $assigns[$var] =& $this->$var;
+ }
+ }
+
+ $assigns['controller'] = $this;
+
+ return $assigns;
+ }
+
+ /**
+ * Sets the layout to be used by this controller per default.
+ *
+ * @param Template|string|null $layout a flexi template to be used as layout
+ * @return void
+ */
+ public function set_layout($layout)
+ {
+ $this->layout = $layout;
+ }
+
+ /**
+ * Returns a URL to a specified route to your Trails application.
+ *
+ * Example:
+ * Your Trails application is located at 'http://example.com/dispatch.php'.
+ * So your dispatcher's trails_uri is set to 'http://example.com/dispatch.php'
+ * If you want the URL to your 'wiki' controller with action 'show' and
+ * parameter 'page' you should send:
+ *
+ * $url = $controller->url_for('wiki/show', 'page');
+ *
+ * $url should then contain 'http://example.com/dispatch.php/wiki/show/page'.
+ *
+ * The first parameter is a string containing the controller and optionally an
+ * action:
+ *
+ * - "{controller}/{action}"
+ * - "path/to/controller/action"
+ * - "controller"
+ *
+ * This "controller/action" string is not url encoded. You may provide
+ * additional parameter which will be urlencoded and concatenated with
+ * slashes:
+ *
+ * $controller->url_for('wiki/show', 'page');
+ * -> 'wiki/show/page'
+ *
+ * $controller->url_for('wiki/show', 'page', 'one and a half');
+ * -> 'wiki/show/page/one+and+a+half'
+ *
+ * @param string $to a string containing a controller and optionally an action
+ * @return string a URL to this route
+ */
+ public function url_for($to/*, ...*/)
+ {
+ # urlencode all but the first argument
+ $args = func_get_args();
+ $args = array_map('urlencode', $args);
+ $args[0] = $to;
+
+ return $this->dispatcher->trails_uri . '/' . implode('/', $args);
+ }
+
+ /**
+ * @param int $status
+ * @return void
+ */
+ public function set_status($status, $reason_phrase = null)
+ {
+ $this->response->set_status($status, $reason_phrase);
+ }
+
+ /**
+ * Sets the content type of the controller's response.
+ *
+ * @param string $type the content type
+ * @return void
+ */
+ public function set_content_type($type)
+ {
+ $this->response->add_header('Content-Type', $type);
+ }
+
+ /**
+ * Exception handler called when the performance of an action raises an
+ * exception.
+ *
+ * @param \Throwable $exception the thrown exception
+ * @return Response a response object
+ */
+ public function rescue($exception)
+ {
+ return $this->dispatcher->trails_error($exception);
+ }
+
+ public function respond_to($ext)
+ {
+ return $this->format === $ext;
+ }
+}
diff --git a/lib/trails/Dispatcher.php b/lib/trails/Dispatcher.php
new file mode 100644
index 0000000..efa90c7
--- /dev/null
+++ b/lib/trails/Dispatcher.php
@@ -0,0 +1,262 @@
+<?php
+namespace Trails;
+
+use Trails\Exceptions\MissingFile;
+use Trails\Exceptions\RoutingError;
+use Trails\Exceptions\UnknownController;
+
+/**
+ * The Dispatcher is used to map an incoming HTTP request to a Controller
+ * producing a response which is then rendered. To initialize an instance of
+ * class Dispatcher you have to give three configuration settings:
+ *
+ * trails_root - the absolute file path to a directory containing the
+ * applications controllers, views etc.
+ * trails_uri - the URI to which routes to mapped Controller/Actions
+ * are appended
+ * default_controller - the route to a controller, that is used if no
+ * controller is given, that is the route is equal to '/'
+ *
+ * After instantiation of a dispatcher you have to call method #dispatch with
+ * the request uri to be mapped to a controller/action pair.
+ *
+ * @package trails
+ *
+ * @author mlunzena
+ * @copyright (c) Authors
+ * @version $Id: trails.php 7001 2008-04-04 11:20:27Z mlunzena $
+ */
+class Dispatcher
+{
+ # TODO (mlunzena) Konfiguration muss anders geschehen
+
+ /**
+ * This is the absolute file path to the trails application directory.
+ */
+ public string $trails_root;
+
+ /**
+ * This is the URI to which routes to controller/actions are appended.
+ */
+ public string $trails_uri;
+
+ /**
+ * This variable contains the route to the default controller.
+ */
+ public string $default_controller;
+
+ /**
+ * @param string $trails_root absolute file path to a directory containing the
+ * applications controllers, views etc.
+ * @param string $trails_uri the URI to which routes to mapped Controller/Actions
+ * are appended
+ * @param string $default_controller the route to a controller, that is used if no
+ * controller is given, that is the route is equal to '/'
+ */
+ public function __construct(
+ string $trails_root,
+ string $trails_uri,
+ string $default_controller
+ ) {
+ $this->trails_root = $trails_root;
+ $this->trails_uri = $trails_uri;
+ $this->default_controller = $default_controller;
+ }
+
+ /**
+ * Maps a string to a response which is then rendered.
+ *
+ * @param string $uri The requested URI.
+ */
+ public function dispatch($uri)
+ {
+ # E_USER_ERROR|E_USER_WARNING|E_USER_NOTICE|E_RECOVERABLE_ERROR = 5888
+ $old_handler = set_error_handler([$this, 'error_handler'], 5888);
+
+ ob_start();
+ $level = ob_get_level();
+
+ $this->map_uri_to_response($this->clean_request_uri((string) $uri))->output();
+
+ while (ob_get_level() >= $level) {
+ ob_end_flush();
+ }
+
+ if (isset($old_handler)) {
+ set_error_handler($old_handler);
+ }
+ }
+
+ /**
+ * Maps an URI to a response by figuring out first what controller to
+ * instantiate, then delegating the unconsumed part of the URI to the
+ * controller who returns an appropriate response object or throws an
+ * Exception.
+ *
+ * @param string $uri the URI string
+ * @return Response a response object
+ */
+ public function map_uri_to_response($uri)
+ {
+ try {
+ [$controller_path, $unconsumed] = '' === $uri ? $this->default_route() : $this->parse($uri);
+
+ $controller = $this->load_controller($controller_path);
+
+ $response = $controller->perform($unconsumed);
+ } catch (Exception $e) {
+ $response = isset($controller) ? $controller->rescue($e) : $this->trails_error($e);
+ }
+
+ return $response;
+ }
+
+ /**
+ * @return array an array containing the default controller and an
+ * empty unconsumed route
+ * @throws MissingFile
+ */
+ public function default_route()
+ {
+ if (!$this->file_exists($this->default_controller . '.php')) {
+ throw new Exceptions\MissingFile(
+ "Default controller '{$this->default_controller}' not found'"
+ );
+ }
+ return [$this->default_controller, ''];
+ }
+
+ public function trails_error($exception)
+ {
+ ob_clean();
+
+ # show details for local requests
+ $detailed = @$_SERVER['REMOTE_ADDR'] === '127.0.0.1';
+
+ $body = sprintf('<html><head><title>Trails Error</title></head>' .
+ '<body><h1>%s</h1><pre>%s</pre></body></html>',
+ htmlentities($exception->__toString()),
+ $detailed
+ ? htmlentities($exception->getTraceAsString())
+ : '');
+
+ if ($exception instanceof Exception) {
+ $response = new Response(
+ $body,
+ $exception->getHeaders(),
+ $exception->getCode(),
+ $exception->getMessage()
+ );
+ } else {
+ $response = new Response(
+ $body,
+ [],
+ 500,
+ $exception->getMessage()
+ );
+ }
+
+ return $response;
+ }
+
+ /**
+ * Clean up URI string by removing the query part and leading slashes.
+ *
+ * @param string $uri an URI string
+ * @return string the cleaned string
+ */
+ public function clean_request_uri($uri)
+ {
+ $pos = strpos($uri, '?');
+ if ($pos !== false) {
+ $uri = substr($uri, 0, $pos);
+ }
+ return ltrim($uri, '/');
+ }
+
+ /**
+ * @param string $unconsumed
+ * @param string $controller
+ * @return array
+ * @throws RoutingError
+ */
+ public function parse($unconsumed, $controller = null)
+ {
+ [$head, $tail] = $this->split_on_first_slash($unconsumed);
+
+ if (!preg_match('/^\w+$/', $head)) {
+ throw new RoutingError("No route matches '$head'");
+ }
+
+ $controller = (isset($controller) ? $controller . '/' : '') . $head;
+
+ if ($this->file_exists($controller . '.php')) {
+ return [$controller, $tail];
+ }
+
+ if ($this->file_exists($controller)) {
+ return $this->parse($tail, $controller);
+ }
+
+ throw new RoutingError("No route matches '$head'");
+ }
+
+ /**
+ * @param string $str
+ * @return array
+ */
+ public function split_on_first_slash($str)
+ {
+ preg_match(":([^/]*)(/+)?(.*):", $str, $matches);
+ return [$matches[1], $matches[3]];
+ }
+
+ /**
+ * @param string $path
+ * @return bool
+ */
+ public function file_exists($path)
+ {
+ return file_exists("{$this->trails_root}/controllers/$path");
+ }
+
+ /**
+ * Loads the controller file for a given controller path and return an
+ * instance of that controller. If an error occures, an exception will be
+ * thrown.
+ *
+ * @param string $controller the relative controller path
+ * @return Controller an instance of that controller
+ * @throws UnknownController
+ */
+ public function load_controller($controller)
+ {
+ require_once "{$this->trails_root}/controllers/{$controller}.php";
+ $class = Inflector::camelize($controller) . 'Controller';
+ if (!class_exists($class)) {
+ throw new UnknownController("Controller missing: '$class'");
+ }
+ return new $class($this);
+ }
+
+ /**
+ * This method transforms E_USER_* and E_RECOVERABLE_ERROR to
+ * Exceptions.
+ *
+ * @param integer $errno the level of the error raised
+ * @param string $string the error message
+ * @param string $file the filename that the error was raised in
+ * @param integer $line the line number the error was raised at
+ *
+ * @return bool
+ * @throws Exception
+ *
+ */
+ public function error_handler($errno, $string, $file, $line)
+ {
+ if (!(5888 & $errno)) {
+ return false;
+ }
+ throw new Exception(500, $string);
+ }
+}
diff --git a/lib/trails/Exception.php b/lib/trails/Exception.php
new file mode 100644
index 0000000..fd92b35
--- /dev/null
+++ b/lib/trails/Exception.php
@@ -0,0 +1,43 @@
+<?php
+
+namespace Trails;
+
+/**
+ * @author mlunzena
+ * @copyright (c) Authors
+ * @version $Id: trails.php 7001 2008-04-04 11:20:27Z mlunzena $
+ */
+class Exception extends \Exception
+{
+ protected array $headers;
+
+ /**
+ * @param int $status the status code to be set in the response
+ * @param string|null $reason a human readable presentation of the status code
+ * @param array $headers a hash of additional headers to be set in the response
+ */
+ public function __construct(int $status = 500, string $reason = null, array $headers = [])
+ {
+ parent::__construct(
+ $reason ?? Response::get_reason($status),
+ $status
+ );
+
+ $this->setHeaders($headers);
+ }
+
+ public function setHeaders(array $headers): void
+ {
+ $this->headers = $headers;
+ }
+
+ public function getHeaders(): array
+ {
+ return $this->headers;
+ }
+
+ public function __toString(): string
+ {
+ return "{$this->code} {$this->message}";
+ }
+}
diff --git a/lib/trails/Exceptions/DoubleRenderError.php b/lib/trails/Exceptions/DoubleRenderError.php
new file mode 100644
index 0000000..c2dfe9e
--- /dev/null
+++ b/lib/trails/Exceptions/DoubleRenderError.php
@@ -0,0 +1,13 @@
+<?php
+namespace Trails\Exceptions;
+
+class DoubleRenderError extends \Trails\Exception
+{
+ public function __construct()
+ {
+ $message = 'Render and/or redirect were called multiple times in this ';
+ $message .= 'action. Please note that you may only call render OR ';
+ $message .= 'redirect, and at most once per action.';
+ parent::__construct(500, $message);
+ }
+}
diff --git a/lib/trails/Exceptions/MissingFile.php b/lib/trails/Exceptions/MissingFile.php
new file mode 100644
index 0000000..59e8480
--- /dev/null
+++ b/lib/trails/Exceptions/MissingFile.php
@@ -0,0 +1,10 @@
+<?php
+namespace Trails\Exceptions;
+
+class MissingFile extends \Trails\Exception
+{
+ public function __construct(string $message)
+ {
+ parent::__construct(500, $message);
+ }
+}
diff --git a/lib/trails/Exceptions/RoutingError.php b/lib/trails/Exceptions/RoutingError.php
new file mode 100644
index 0000000..e62459e
--- /dev/null
+++ b/lib/trails/Exceptions/RoutingError.php
@@ -0,0 +1,10 @@
+<?php
+namespace Trails\Exceptions;
+
+class RoutingError extends \Trails\Exception
+{
+ public function __construct(string $message)
+ {
+ parent::__construct(400, $message);
+ }
+}
diff --git a/lib/trails/Exceptions/SessionRequiredException.php b/lib/trails/Exceptions/SessionRequiredException.php
new file mode 100644
index 0000000..b77a344
--- /dev/null
+++ b/lib/trails/Exceptions/SessionRequiredException.php
@@ -0,0 +1,11 @@
+<?php
+namespace Trails\Exceptions;
+
+class SessionRequiredException extends \Trails\Exception
+{
+ public function __construct()
+ {
+ $message = 'Tried to access a non existing session.';
+ parent::__construct(500, $message);
+ }
+}
diff --git a/lib/trails/Exceptions/UnknownAction.php b/lib/trails/Exceptions/UnknownAction.php
new file mode 100644
index 0000000..f749a51
--- /dev/null
+++ b/lib/trails/Exceptions/UnknownAction.php
@@ -0,0 +1,10 @@
+<?php
+namespace Trails\Exceptions;
+
+class UnknownAction extends \Trails\Exception
+{
+ public function __construct(string $message)
+ {
+ parent::__construct(404, $message);
+ }
+}
diff --git a/lib/trails/Exceptions/UnknownController.php b/lib/trails/Exceptions/UnknownController.php
new file mode 100644
index 0000000..420c238
--- /dev/null
+++ b/lib/trails/Exceptions/UnknownController.php
@@ -0,0 +1,10 @@
+<?php
+namespace Trails\Exceptions;
+
+class UnknownController extends \Trails\Exception
+{
+ public function __construct(string $message)
+ {
+ parent::__construct(404, $message);
+ }
+}
diff --git a/lib/trails/Flash.php b/lib/trails/Flash.php
new file mode 100644
index 0000000..eede7af
--- /dev/null
+++ b/lib/trails/Flash.php
@@ -0,0 +1,184 @@
+<?php
+
+namespace Trails;
+
+use Trails\Exceptions\SessionRequiredException;
+
+/**
+ * The flash provides a way to pass temporary objects between actions.
+ * Anything you place in the flash will be exposed to the very next action and
+ * then cleared out. This is a great way of doing notices and alerts, such as
+ * a create action that sets
+ * <tt>$flash->set('notice', "Successfully created")</tt>
+ * before redirecting to a display action that can then expose the flash to its
+ * template.
+ *
+ * @package trails
+ *
+ * @author mlunzena
+ * @copyright (c) Authors
+ * @version $Id: trails.php 7001 2008-04-04 11:20:27Z mlunzena $
+ */
+final class Flash implements \ArrayAccess
+{
+ private array $flash = [];
+ private array $used = [];
+
+ /**
+ * @return self
+ * @throws SessionRequiredException
+ */
+ public static function instance()
+ {
+ if (!isset($_SESSION)) {
+ throw new Exceptions\SessionRequiredException();
+ }
+
+ if (!isset($_SESSION[self::class])) {
+ $_SESSION[self::class] = new self();
+ }
+ return $_SESSION[self::class];
+ }
+
+ public function offsetExists($offset): bool
+ {
+ return isset($this->flash[$offset]);
+ }
+
+ public function offsetGet($offset): mixed
+ {
+ return $this->get($offset);
+ }
+
+ public function offsetSet($offset, $value): void
+ {
+ $this->set($offset, $value);
+ }
+
+ public function offsetUnset($offset): void
+ {
+ unset($this->flash[$offset], $this->used[$offset]);
+ }
+
+ /**
+ * Used internally by the <tt>keep</tt> and <tt>discard</tt> methods
+ * use() # marks the entire flash as used
+ * use('msg') # marks the "msg" entry as used
+ * use(null, false) # marks the entire flash as unused
+ * # (keeps it around for one more action)
+ * use('msg', false) # marks the "msg" entry as unused
+ * # (keeps it around for one more action)
+ *
+ */
+ private function use(?string $key = null, bool $isUsed = true): void
+ {
+ if ($key) {
+ $this->used[$key] = $isUsed;
+ } else {
+ foreach (array_keys($this->used) as $key) {
+ $this->use($key, $isUsed);
+ }
+ }
+ }
+
+ /**
+ * Marks the entire flash or a single flash entry to be discarded by the end
+ * of the current action.
+ *
+ * $flash->discard() # discards entire flash
+ * # (it'll still be available for the
+ * # current action)
+ * $flash->discard('warning') # discard the "warning" entry
+ * # (it'll still be available for the
+ * # current action)
+ */
+ public function discard(?string $key = null): void
+ {
+ $this->use($key);
+ }
+
+ /**
+ * Returns the value to the specified key.
+ *
+ * @return mixed the key's value.
+ */
+ public function &get(string $key): mixed
+ {
+ $return = null;
+ if (isset($this->flash[$key])) {
+ $return =& $this->flash[$key];
+ }
+ return $return;
+ }
+
+ /**
+ * Keeps either the entire current flash or a specific flash entry available
+ * for the next action:
+ *
+ * $flash->keep() # keeps the entire flash
+ * $flash->keep('notice') # keeps only the "notice" entry, the rest of
+ * # the flash is discarded
+ */
+ public function keep(?string $key = null): void
+ {
+ $this->use($key, false);
+ }
+
+ /**
+ * Sets a key's value.
+ */
+ public function set(string $key, mixed $value): void
+ {
+ $this->keep($key);
+ $this->flash[$key] = $value;
+ }
+
+ /**
+ * Sets a key's value by reference.
+ */
+ public function set_ref(string $key, mixed &$value): void
+ {
+ $this->keep($key);
+ $this->flash[$key] =& $valze;
+ }
+
+ /**
+ * Removes all used values
+ */
+ public function sweep(): void
+ {
+ foreach (array_keys($this->flash) as $k) {
+ if ($this->used[$k]) {
+ unset($this->flash[$k], $this->used[$k]);
+ } else {
+ $this->use($k);
+ }
+ }
+ }
+
+ public function __toString()
+ {
+ $values = [];
+ foreach ($this->flash as $key => $value) {
+ $values[] = sprintf(
+ "'%s': [%s, '%s']",
+ $key,
+ var_export($value, true),
+ !empty($this->used[$key]) ? 'used' : 'unused'
+ );
+ }
+ return '{' . implode(', ', $values) . '}'. "\n";
+ }
+
+ public function __sleep(): array
+ {
+ $this->sweep();
+ return ['flash', 'used'];
+ }
+
+
+ public function __wakeUp()
+ {
+ $this->discard();
+ }
+}
diff --git a/lib/trails/Inflector.php b/lib/trails/Inflector.php
new file mode 100644
index 0000000..bbc6b58
--- /dev/null
+++ b/lib/trails/Inflector.php
@@ -0,0 +1,44 @@
+<?php
+namespace Trails;
+
+/**
+ * The Inflector class is a namespace for inflections methods.
+ *
+ * @package trails
+ *
+ * @author mlunzena
+ * @copyright (c) Authors
+ * @version $Id: trails.php 7001 2008-04-04 11:20:27Z mlunzena $
+ */
+class Inflector
+{
+ /**
+ * Returns a camelized string from a lower case and underscored string by
+ * replacing slash with underscore and upper-casing each letter preceded
+ * by an underscore.
+ *
+ * @param string $word String to camelize.
+ * @return string Camelized string.
+ */
+ public static function camelize(string $word): string
+ {
+ $parts = explode('/', $word);
+ foreach ($parts as $key => $part) {
+ $parts[$key] = strtopascalcase($part);
+ }
+ return implode('_', $parts);
+ }
+
+ /**
+ * @param string $word
+ * @return string
+ */
+ public static function underscore(string $word): string
+ {
+ $parts = explode('_', $word);
+ foreach ($parts as $key => $part) {
+ $parts[$key] = strtosnakecase($part);
+ }
+ return implode('/', $parts);
+ }
+}
diff --git a/lib/trails/Response.php b/lib/trails/Response.php
new file mode 100644
index 0000000..b3f14d8
--- /dev/null
+++ b/lib/trails/Response.php
@@ -0,0 +1,185 @@
+<?php
+namespace Trails;
+
+/**
+ * This class represents a response returned by a controller that was asked to
+ * perform for a given request. A Response contains the body, status and
+ * additional headers which can be renderer back to the client.
+ *
+ * @package trails
+ *
+ * @author mlunzena
+ * @copyright (c) Authors
+ * @version $Id: trails.php 7001 2008-04-04 11:20:27Z mlunzena $
+ */
+class Response
+{
+ public $body = '';
+ public $status;
+ public $reason;
+ public $headers = [];
+
+ /**
+ * Constructor.
+ *
+ * @param string $body the body of the response defaulting to ''
+ * @param array $headers an array of additional headers defaulting to an
+ * empty array
+ * @param int|null $status the status code of the response defaulting to a
+ * regular 200
+ * @param string|null $reason the descriptional reason for a status code defaulting to
+ * the standard reason phrases defined in RFC 2616
+ */
+ public function __construct(
+ string $body = '',
+ array $headers = [],
+ ?int $status = null,
+ ?string $reason = null
+ ) {
+ $this->set_body($body);
+
+ $this->headers = $headers;
+
+ if (isset($status)) {
+ $this->set_status($status, $reason);
+ }
+ }
+
+ /**
+ * Sets the body of the response.
+ *
+ * @param string $body the body
+ * @return static this response object. Useful for cascading method calls.
+ */
+ public function set_body($body)
+ {
+ $this->body = $body;
+ return $this;
+ }
+
+ /**
+ * Sets the status code and an optional custom reason. If none is given, the
+ * standard reason phrase as of RFC 2616 is used.
+ *
+ * @param integer $status the status code
+ * @param string $reason the custom reason, defaulting to the one given in RFC 2616
+ * @return static this response object. Useful for cascading method calls.
+ */
+ public function set_status($status, $reason = null)
+ {
+ $this->status = $status;
+ $this->reason = $reason ?? self::get_reason($status);
+ return $this;
+ }
+
+ /**
+ * Returns the reason phrase of this response according to RFC2616.
+ *
+ * @param int $status the response's status
+ * @return string the reason phrase for this response's status
+ */
+ public static function get_reason($status)
+ {
+ return match ($status) {
+ 100 => 'Continue',
+ 101 => 'Switching Protocols',
+
+ 200 => 'OK',
+ 201 => 'Created',
+ 202 => 'Accepted',
+ 203 => 'Non-Authoritative Information',
+ 204 => 'No Content',
+ 205 => 'Reset Content',
+ 206 => 'Partial Content',
+
+ 300 => 'Multiple Choices',
+ 301 => 'Moved Permanently',
+ 302 => 'Found',
+ 303 => 'See Other',
+ 304 => 'Not Modified',
+ 305 => 'Use Proxy',
+ 306 => '(Unused)',
+ 307 => 'Temporary Redirect',
+
+ 400 => 'Bad Request',
+ 401 => 'Unauthorized',
+ 402 => 'Payment Required',
+ 403 => 'Forbidden',
+ 404 => 'Not Found',
+ 405 => 'Method Not Allowed',
+ 406 => 'Not Acceptable',
+ 407 => 'Proxy Authentication Required',
+ 408 => 'Request Timeout',
+ 409 => 'Conflict',
+ 410 => 'Gone',
+ 411 => 'Length Required',
+ 412 => 'Precondition Failed',
+ 413 => 'Request Entity Too Large',
+ 414 => 'Request-URI Too Long',
+ 415 => 'Unsupported Media Type',
+ 416 => 'Requested Range Not Satisfiable',
+ 417 => 'Expectation Failed',
+
+ 500 => 'Internal Server Error',
+ 501 => 'Not Implemented',
+ 502 => 'Bad Gateway',
+ 503 => 'Service Unavailable',
+ 504 => 'Gateway Timeout',
+ 505 => 'HTTP Version Not Supported',
+
+ default => '',
+ };
+ }
+
+ /**
+ * Adds an additional header to the response.
+ *
+ * @param string $key the left hand key part
+ * @param string $value the right hand value part
+ * @return static this response object. Useful for cascading method calls.
+ */
+ public function add_header($key, $value)
+ {
+ $this->headers[$key] = $value;
+ return $this;
+ }
+
+ /**
+ * Outputs this response to the client using "echo" and "header".
+ * @return void
+ */
+ public function output()
+ {
+ if (isset($this->status)) {
+ $this->send_header(
+ "HTTP/1.1 {$this->status} {$this->reason}",
+ true,
+ $this->status
+ );
+ }
+
+ foreach ($this->headers as $k => $v) {
+ $this->send_header("{$k}: {$v}");
+ }
+
+ echo $this->body;
+ }
+
+ /**
+ * Internally used function to actually send headers
+ *
+ * @param string $header the HTTP header
+ * @param bool $replace optional; TRUE if previously sent header should be
+ * replaced - FALSE otherwise (default)
+ * @param integer $status optional; the HTTP response code
+ * @return void
+ */
+ public function send_header($header, $replace = false, $status = null)
+ {
+ if (isset($status)) {
+ header($header, $replace, $status);
+ } else {
+ header($header, $replace);
+ }
+ }
+}
diff --git a/public/assets.php b/public/assets.php
index a0baa6d..3610a13 100644
--- a/public/assets.php
+++ b/public/assets.php
@@ -19,7 +19,7 @@ $uri = ltrim(Request::pathInfo(), '/');
list($type, $id) = explode('/', $uri, 2);
// Setup response
-$response = new Trails_Response();
+$response = new Trails\Response();
// Create response
if (!$type || !$id) {
diff --git a/public/dispatch.php b/public/dispatch.php
index 68d0399..77c5933 100644
--- a/public/dispatch.php
+++ b/public/dispatch.php
@@ -21,5 +21,5 @@ require '../lib/bootstrap.php';
// prepare environment
URLHelper::setBaseUrl($GLOBALS['ABSOLUTE_URI_STUDIP']);
-$dispatcher = app(\Trails_Dispatcher::class);
+$dispatcher = app(\Trails\Dispatcher::class);
$dispatcher->dispatch(Request::pathInfo());
diff --git a/public/install.php b/public/install.php
index 4e54575..e32cf75 100644
--- a/public/install.php
+++ b/public/install.php
@@ -17,7 +17,6 @@ set_include_path($GLOBALS['STUDIP_BASE_PATH']);
require_once 'composer/autoload.php';
require_once 'lib/visual.inc.php';
-require_once 'vendor/trails/trails.php';
require_once 'lib/classes/URLHelper.php';
require_once 'lib/classes/LayoutMessage.interface.php';
require_once 'lib/classes/MessageBox.class.php';
@@ -33,6 +32,18 @@ require_once 'lib/flexi/Factory.php';
require_once 'lib/flexi/PhpTemplate.php';
require_once 'lib/flexi/Template.php';
require_once 'lib/flexi/TemplateNotFoundException.php';
+require_once 'lib/trails/Controller.php';
+require_once 'lib/trails/Dispatcher.php';
+require_once 'lib/trails/Exception.php';
+require_once 'lib/trails/Flash.php';
+require_once 'lib/trails/Inflector.php';
+require_once 'lib/trails/Response.php';
+require_once 'lib/trails/Exceptions/DoubleRenderError.php';
+require_once 'lib/trails/Exceptions/MissingFile.php';
+require_once 'lib/trails/Exceptions/RoutingError.php';
+require_once 'lib/trails/Exceptions/SessionRequiredException.php';
+require_once 'lib/trails/Exceptions/UnknownAction.php';
+require_once 'lib/trails/Exceptions/UnknownController.php';
require_once 'vendor/phpass/PasswordHash.php';
// Mock gettext functions if extension is not available
@@ -61,5 +72,5 @@ $GLOBALS['template_factory'] = new Flexi\Factory('../templates/');
# get plugin class from request
$dispatch_to = ltrim(Request::pathInfo(), '/');
-$dispatcher = new Trails_Dispatcher( '../app', $_SERVER['SCRIPT_NAME'], 'admin/install');
+$dispatcher = new Trails\Dispatcher( '../app', $_SERVER['SCRIPT_NAME'], 'admin/install');
$dispatcher->dispatch("admin/install/{$dispatch_to}");
diff --git a/public/sendfile.php b/public/sendfile.php
index 7d6517c..03157b8 100644
--- a/public/sendfile.php
+++ b/public/sendfile.php
@@ -156,7 +156,7 @@ if (
) {
$link_data = FileManager::fetchURLMetadata($file_ref->file->metadata['url']);
if ($link_data['response_code'] != 200) {
- throw new Trails_Exception(404, _("Diese Datei wird von einem externen Server geladen und ist dort momentan nicht erreichbar!"));
+ throw new Trails\Exception(404, _("Diese Datei wird von einem externen Server geladen und ist dort momentan nicht erreichbar!"));
}
$content_type = $link_data['Content-Type'] ? strstr($link_data['Content-Type'], ';', true) : get_mime_type($file_name);
@@ -166,7 +166,7 @@ if (
if (isset($file)) {
$filesize = $file->getSize();
if ($filesize === false) {
- throw new Trails_Exception(404, _('Fehler beim Laden der Inhalte der Datei'));
+ throw new Trails\Exception(404, _('Fehler beim Laden der Inhalte der Datei'));
}
}
@@ -186,7 +186,7 @@ if (isset($file_ref, $file_ref->file, $file_ref->file->metadata['access_type'])
// Check if file actually exists
if (!parse_url($path_file, PHP_URL_SCHEME) && !file_exists($path_file)) {
- throw new Trails_Exception(404, _('Fehler beim Laden der Inhalte der Datei'));
+ throw new Trails\Exception(404, _('Fehler beim Laden der Inhalte der Datei'));
}
$allowed_mime_types = get_mime_types();
diff --git a/public/web_migrate.php b/public/web_migrate.php
index c01c600..0ee4de5 100644
--- a/public/web_migrate.php
+++ b/public/web_migrate.php
@@ -36,6 +36,6 @@ $GLOBALS['template_factory'] = new Flexi\Factory('../templates/');
# get plugin class from request
$dispatch_to = Request::pathInfo() ?: '';
-$dispatcher = app(\Trails_Dispatcher::class);
+$dispatcher = app(\Trails\Dispatcher::class);
$dispatcher->trails_uri = $_SERVER['SCRIPT_NAME'];
$dispatcher->dispatch("web_migrate/{$dispatch_to}");
diff --git a/tests/unit/_bootstrap.php b/tests/unit/_bootstrap.php
index a1dbdd1..87dedca 100644
--- a/tests/unit/_bootstrap.php
+++ b/tests/unit/_bootstrap.php
@@ -62,18 +62,7 @@ StudipAutoloader::addAutoloadPath('lib/flexi', 'Flexi');
StudipAutoloader::addAutoloadPath('lib/plugins/engine');
StudipAutoloader::addAutoloadPath('lib/plugins/core');
StudipAutoloader::addAutoloadPath('lib/plugins/db');
-
-$trails_classes = [
- 'Trails_Dispatcher', 'Trails_Response', 'Trails_Controller',
- 'Trails_Inflector', 'Trails_Flash',
- 'Trails_Exception', 'Trails_DoubleRenderError', 'Trails_MissingFile',
- 'Trails_RoutingError', 'Trails_UnknownAction', 'Trails_UnknownController',
- 'Trails_SessionRequiredException',
-];
-StudipAutoloader::addClassLookup(
- $trails_classes,
- 'vendor/trails/trails.php'
-);
+StudipAutoloader::addAutoloadPath('lib/trails', 'Trails');
// load config-variables
$added_configs = [];
diff --git a/tests/unit/lib/FunctionsTest.php b/tests/unit/lib/FunctionsTest.php
index 670d00c..c254fda 100644
--- a/tests/unit/lib/FunctionsTest.php
+++ b/tests/unit/lib/FunctionsTest.php
@@ -75,11 +75,12 @@ class FunctionsTest extends \Codeception\Test\Unit
}
/**
- * @covers Trails_Controller::extract_action_and_args()
+ * @covers Trails\Controller::extract_action_and_args()
*/
public function testTrailsControllerExtractActionAndArgs()
{
- $controller = new Trails_Controller(null);
+ $dispatcher = new Trails\Dispatcher('', '', '');
+ $controller = new Trails\Controller($dispatcher);
[$action, $args, $format] = $controller->extract_action_and_args('foo/bar//42.html');
$this->assertEquals('foo', $action);
diff --git a/tests/unit/lib/classes/StudipControllerTest.php b/tests/unit/lib/classes/StudipControllerTest.php
index f7e4ef4..51359ab 100644
--- a/tests/unit/lib/classes/StudipControllerTest.php
+++ b/tests/unit/lib/classes/StudipControllerTest.php
@@ -27,13 +27,13 @@ final class StudipControllerTest extends Codeception\Test\Unit
parent::tearDown();
}
- private function getDispatcher(): Trails_Dispatcher
+ private function getDispatcher(): Trails\Dispatcher
{
$trails_root = $GLOBALS['STUDIP_BASE_PATH'] . DIRECTORY_SEPARATOR . 'app';
$trails_uri = rtrim($GLOBALS['ABSOLUTE_URI_STUDIP'], '/') . '/dispatch.php';
$default_controller = 'default';
- return new Trails_Dispatcher($trails_root, $trails_uri, $default_controller);
+ return new Trails\Dispatcher($trails_root, $trails_uri, $default_controller);
}
private function getController(): StudipController
@@ -247,7 +247,7 @@ final class StudipControllerTest extends Codeception\Test\Unit
{
$args = [$should_fail];
- $this->expectException(Trails_Exception::class);
+ $this->expectException(Trails\Exception::class);
$this->getController()->validate_args($args);
}
diff --git a/tests/unit/lib/classes/TrailsTest.php b/tests/unit/lib/classes/TrailsTest.php
new file mode 100644
index 0000000..d51b795
--- /dev/null
+++ b/tests/unit/lib/classes/TrailsTest.php
@@ -0,0 +1,25 @@
+<?php
+class TrailsTest extends \Codeception\Test\Unit
+{
+ /**
+ * @covers Trails\Inflector::camelize
+ */
+ public function testInflectorCamelize(): void
+ {
+ $this->assertEquals(
+ 'Path_SubPath_UnderscoreController',
+ Trails\Inflector::camelize('path/sub_path/underscore_controller')
+ );
+ }
+
+ /**
+ * @covers Trails\Inflector::underscore
+ */
+ public function testInflectorUnderscore(): void
+ {
+ $this->assertEquals(
+ 'path/sub_path/underscore_controller',
+ Trails\Inflector::underscore('Path_SubPath_UnderscoreController')
+ );
+ }
+}
diff --git a/vendor/trails/extras/tramp.php b/vendor/trails/extras/tramp.php
deleted file mode 100644
index 9292a96..0000000
--- a/vendor/trails/extras/tramp.php
+++ /dev/null
@@ -1,55 +0,0 @@
-<?php
-
-# Copyright (c) 2007 - Marcus Lunzenauer <mlunzena@uos.de>
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in all
-# copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-# SOFTWARE.
-
-
-class Tramp_Controller extends Trails_Controller {
-
- /**
- * Extracts action and args from a string.
- *
- * @param string the processed string
- *
- * @return arraye an array with two elements - a string containing the
- * action and an array of strings representing the args
- */
- protected function extract_action_and_args($string) {
- return array($this->get_verb(), explode('/', $string));
- }
-
-
- protected function map_action($action) {
- return strtolower($action);
- }
-
-
- protected function get_verb() {
-
- $verb = strtoupper(isset($_REQUEST['_method'])
- ? $_REQUEST['_method'] : @$_SERVER['REQUEST_METHOD']);
-
- if (!preg_match('/^DELETE|GET|POST|PUT|HEAD|OPTIONS$/', $verb)) {
- throw new Trails_Exception(405);
- }
-
- return $verb;
- }
-}
diff --git a/vendor/trails/src/HEADER.php b/vendor/trails/src/HEADER.php
deleted file mode 100644
index 75bb516..0000000
--- a/vendor/trails/src/HEADER.php
+++ /dev/null
@@ -1,27 +0,0 @@
-<?
-
-# Copyright (c) 2007 - Marcus Lunzenauer <mlunzena@uos.de>
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in all
-# copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-# SOFTWARE.
-
-
-/**
- * The version of the trails library.
- */
-define('TRAILS_VERSION', '0.6.9');
diff --git a/vendor/trails/src/controller.php b/vendor/trails/src/controller.php
deleted file mode 100644
index 6ab9542..0000000
--- a/vendor/trails/src/controller.php
+++ /dev/null
@@ -1,430 +0,0 @@
-<?php
-/**
- * A Trails_Controller is responsible for matching the unconsumed part of an URI
- * to an action using the left over words as arguments for that action. The
- * action is then mapped to method of the controller instance which is called
- * with the just mentioned arguments. That method can send the #render_action,
- * #render_template, #render_text, #render_nothing or #redirect method.
- * Otherwise the #render_action is called with the current action as argument.
- * If the action method sets instance variables during performing, they will be
- * be used as attributes for the flexi-template opened by #render_action or
- * #render_template. A controller's response's body is populated with the output
- * of the #render_* methods. The action methods can add additional headers or
- * change the status of that response.
- *
- * @package trails
- *
- * @author mlunzena
- * @copyright (c) Authors
- * @version $Id: trails.php 7001 2008-04-04 11:20:27Z mlunzena $
- */
-
-class Trails_Controller {
-
-
- /**
- * @ignore
- */
- protected
- $dispatcher,
- $response,
- $performed,
- $layout;
-
-
- /**
- * Constructor.
- *
- * @param mixed the dispatcher who creates this instance
- *
- * @return void
- */
- function __construct($dispatcher) {
- $this->dispatcher = $dispatcher;
- $this->erase_response();
- }
-
-
- /**
- * Resets the response of the controller
- *
- * @return void
- */
- function erase_response() {
- $this->performed = FALSE;
- $this->response = new Trails_Response();
- }
-
-
- /**
- * Return this controller's response
- *
- * @return mixed the controller's response
- */
- function get_response() {
- return $this->response;
- }
-
-
- /**
- * This method extracts an action string and further arguments from it's
- * parameter. The action string is mapped to a method being called afterwards
- * using the said arguments. That method is called and a response object is
- * generated, populated and sent back to the dispatcher.
- *
- * @param type <description>
- *
- * @return type <description>
- */
- function perform($unconsumed) {
-
- list($action, $args, $format) = $this->extract_action_and_args($unconsumed);
-
- $this->format = isset($format) ? $format : 'html';
-
- $before_filter_result = $this->before_filter($action, $args);
-
- # send action to controller
- # TODO (mlunzena) shouldn't the after filter be triggered too?
- if (!(FALSE === $before_filter_result || $this->performed)) {
-
- $callable = $this->map_action($action);
-
- if (is_callable($callable)) {
- call_user_func_array($callable, $args);
- }
- else {
- $this->does_not_understand($action, $args);
- }
-
- if (!$this->performed) {
- $this->render_action($action);
- }
-
- $this->after_filter($action, $args);
- }
-
- return $this->response;
- }
-
-
- /**
- * Extracts action and args from a string.
- *
- * @param string the processed string
- *
- * @return array an array with two elements - a string containing the
- * action and an array of strings representing the args
- */
- function extract_action_and_args($string) {
-
- if ('' === $string) {
- return $this->default_action_and_args();
- }
-
- // find optional file extension
- $format = NULL;
- if (preg_match('/^(.*[^\/.])\.(\w+)$/', $string, $matches)) {
- list($_, $string, $format) = $matches;
- }
-
- // TODO this should possibly remove empty tokens
- $args = explode('/', $string);
- $action = array_shift($args);
- return array($action, $args, $format);
- }
-
- /**
- * Return the default action and arguments
- *
- * @return an array containing the action, an array of args and the format
- *
- */
- function default_action_and_args() {
- return array('index', array(), NULL);
- }
-
- /**
- * Maps the action to an actual method name.
- *
- * @param string the action
- *
- * @return string the mapped method name
- */
- function map_action($action) {
- return array(&$this, $action . '_action');
- }
-
-
- /**
- * Callback function being called before an action is executed. If this
- * function does not return FALSE, the action will be called, otherwise
- * an error will be generated and processing will be aborted. If this function
- * already #rendered or #redirected, further processing of the action is
- * withheld.
- *
- * @param string Name of the action to perform.
- * @param array An array of arguments to the action.
- *
- * @return bool
- */
- function before_filter(&$action, &$args) {
- }
-
-
- /**
- * Callback function being called after an action is executed.
- *
- * @param string Name of the action to perform.
- * @param array An array of arguments to the action.
- *
- * @return void
- */
- function after_filter($action, $args) {
- }
-
-
- /**
- * <MethodDescription>
- *
- * @param type <description>
- * @param type <description>
- *
- * @return void
- */
- function does_not_understand($action, $args) {
- throw new Trails_UnknownAction("No action responded to '$action'.");
- }
-
-
- /**
- * <MethodDescription>
- *
- * @param string <description>
- *
- * @return void
- */
- function redirect($to) {
-
- if ($this->performed) {
- throw new Trails_DoubleRenderError();
- }
-
- $this->performed = TRUE;
-
- # get uri; keep absolute URIs
- $url = preg_match('#^(/|\w+://)#', $to)
- ? $to
- : $this->url_for($to);
-
- $this->response->add_header('Location', $url)->set_status(302);
- }
-
-
- /**
- * Renders the given text as the body of the response.
- *
- * @param string the text to be rendered
- *
- * @return void
- */
- function render_text($text = ' ') {
-
- if ($this->performed) {
- throw new Trails_DoubleRenderError();
- }
-
- $this->performed = TRUE;
-
- $this->response->set_body($text);
- }
-
-
- /**
- * Renders the empty string as the response's body.
- *
- * @return void
- */
- function render_nothing() {
- $this->render_text('');
- }
-
-
- /**
- * Renders the template of the given action as the response's body.
- *
- * @param string the action
- *
- * @return void
- */
- function render_action($action) {
- $this->render_template($this->get_default_template($action), $this->layout);
- }
-
-
- function get_default_template($action)
- {
- $class = get_class($this);
- $controller_name =
- Trails_Inflector::underscore(substr($class, 0, -10));
- return $controller_name.'/'.$action;
- }
-
-
- /**
- * Renders a template using an optional layout template.
- *
- * @param mixed a flexi template
- * @param mixes a flexi template which is used as layout
- *
- * @return void
- */
- function render_template($template_name, $layout = NULL) {
-
- # open template
- $factory = $this->get_template_factory();
- $template = $factory->open($template_name);
-
- $template->set_attributes($this->get_assigned_variables());
-
- if (isset($layout)) {
- $template->set_layout($layout);
- }
-
- $this->render_text($template->render());
- }
-
-
- /**
- * Create and return a template factory for this controller.
- *
- * @return Flexi\Factory
- */
- function get_template_factory() {
- return new Flexi\Factory($this->dispatcher->trails_root .
- '/views/');
- }
-
-
- /**
- * This method returns all the set instance variables to be used as attributes
- * for a template. This controller is returned too as value for
- * key 'controller'.
- *
- * @return array an associative array of variables for the template
- */
- function get_assigned_variables() {
-
- $assigns = array();
- $protected = get_class_vars(get_class($this));
-
- foreach (get_object_vars($this) as $var => $value) {
- if (!array_key_exists($var, $protected)) {
- $assigns[$var] =& $this->$var;
- }
- }
-
- $assigns['controller'] = $this;
-
- return $assigns;
- }
-
-
- /**
- * Sets the layout to be used by this controller per default.
- *
- * @param mixed a flexi template to be used as layout
- *
- * @return void
- */
- function set_layout($layout) {
- $this->layout = $layout;
- }
-
-
- /**
- * Returns a URL to a specified route to your Trails application.
- *
- * Example:
- * Your Trails application is located at 'http://example.com/dispatch.php'.
- * So your dispatcher's trails_uri is set to 'http://example.com/dispatch.php'
- * If you want the URL to your 'wiki' controller with action 'show' and
- * parameter 'page' you should send:
- *
- * $url = $controller->url_for('wiki/show', 'page');
- *
- * $url should then contain 'http://example.com/dispatch.php/wiki/show/page'.
- *
- * The first parameter is a string containing the controller and optionally an
- * action:
- *
- * - "{controller}/{action}"
- * - "path/to/controller/action"
- * - "controller"
- *
- * This "controller/action" string is not url encoded. You may provide
- * additional parameter which will be urlencoded and concatenated with
- * slashes:
- *
- * $controller->url_for('wiki/show', 'page');
- * -> 'wiki/show/page'
- *
- * $controller->url_for('wiki/show', 'page', 'one and a half');
- * -> 'wiki/show/page/one+and+a+half'
- *
- * @param string a string containing a controller and optionally an action
- * @param strings optional arguments
- *
- * @return string a URL to this route
- */
- function url_for($to/*, ...*/) {
-
- # urlencode all but the first argument
- $args = func_get_args();
- $args = array_map('urlencode', $args);
- $args[0] = $to;
-
- return $this->dispatcher->trails_uri . '/' . join('/', $args);
- }
-
-
- /**
- * <MethodDescription>
- *
- * @param type <description>
- *
- * @return type <description>
- */
- function set_status($status, $reason_phrase = NULL) {
- $this->response->set_status($status, $reason_phrase);
- }
-
-
- /**
- * Sets the content type of the controller's response.
- *
- * @param string the content type
- *
- * @return void
- */
- function set_content_type($type) {
- $this->response->add_header('Content-Type', $type);
- }
-
-
- /**
- * Exception handler called when the performance of an action raises an
- * exception.
- *
- * @param object the thrown exception
- *
- * @return object a response object
- */
- function rescue($exception) {
- return $this->dispatcher->trails_error($exception);
- }
-
- function respond_to($ext) {
- return $this->format === $ext;
- }
-}
diff --git a/vendor/trails/src/dispatcher.php b/vendor/trails/src/dispatcher.php
deleted file mode 100644
index 58f55b1..0000000
--- a/vendor/trails/src/dispatcher.php
+++ /dev/null
@@ -1,269 +0,0 @@
-<?php
-
-/**
- * The Dispatcher is used to map an incoming HTTP request to a Controller
- * producing a response which is then rendered. To initialize an instance of
- * class Trails_Dispatcher you have to give three configuration settings:
- *
- * trails_root - the absolute file path to a directory containing the
- * applications controllers, views etc.
- * trails_uri - the URI to which routes to mapped Controller/Actions
- * are appended
- * default_controller - the route to a controller, that is used if no
- * controller is given, that is the route is equal to '/'
- *
- * After instantiation of a dispatcher you have to call method #dispatch with
- * the request uri to be mapped to a controller/action pair.
- *
- * @package trails
- *
- * @author mlunzena
- * @copyright (c) Authors
- * @version $Id: trails.php 7001 2008-04-04 11:20:27Z mlunzena $
- */
-
-class Trails_Dispatcher {
-
- # TODO (mlunzena) Konfiguration muss anders geschehen
-
- /**
- * This is the absolute file path to the trails application directory.
- *
- * @access public
- * @var string
- */
- public $trails_root;
-
-
- /**
- * This is the URI to which routes to controller/actions are appended.
- *
- * @access public
- * @var string
- */
- public $trails_uri;
-
-
- /**
- * This variable contains the route to the default controller.
- *
- * @access public
- * @var string
- */
- public $default_controller;
-
-
- /**
- * Constructor.
- *
- * @param string absolute file path to a directory containing the
- * applications controllers, views etc.
- * @param string the URI to which routes to mapped Controller/Actions
- * are appended
- * @param string the route to a controller, that is used if no
- * controller is given, that is the route is equal to '/'
- *
- * @return void
- */
- function __construct($trails_root,
- $trails_uri,
- $default_controller) {
-
- $this->trails_root = $trails_root;
- $this->trails_uri = $trails_uri;
- $this->default_controller = $default_controller;
- }
-
-
- /**
- * Maps a string to a response which is then rendered.
- *
- * @param string The requested URI.
- *
- * @return void
- */
- function dispatch($uri) {
-
- # E_USER_ERROR|E_USER_WARNING|E_USER_NOTICE|E_RECOVERABLE_ERROR = 5888
- $old_handler = set_error_handler(array($this, 'error_handler'), 5888);
-
- ob_start();
- $level = ob_get_level();
-
- $this->map_uri_to_response($this->clean_request_uri((string) $uri))->output();
-
- while (ob_get_level() >= $level) {
- ob_end_flush();
- }
-
- if (isset($old_handler)) {
- set_error_handler($old_handler);
- }
- }
-
-
- /**
- * Maps an URI to a response by figuring out first what controller to
- * instantiate, then delegating the unconsumed part of the URI to the
- * controller who returns an appropriate response object or throws a
- * Trails_Exception.
- *
- * @param string the URI string
- *
- * @return mixed a response object
- */
- function map_uri_to_response($uri) {
-
- try {
-
- list($controller_path, $unconsumed) =
- '' === $uri
- ? $this->default_route()
- : $this->parse($uri);
-
- $controller = $this->load_controller($controller_path);
-
- $response = $controller->perform($unconsumed);
-
- } catch (Exception $e) {
-
- $response = isset($controller) ? $controller->rescue($e)
- : $this->trails_error($e);
- }
-
- return $response;
- }
-
-
- /**
- *
- * @return array an array containing the default controller and an
- * empty unconsumed route
- */
- function default_route() {
- if (!$this->file_exists($this->default_controller . '.php')) {
- throw new Trails_MissingFile(
- "Default controller '{$this->default_controller}' not found'");
- }
- return array($this->default_controller, '');
- }
-
-
- function trails_error($exception) {
- ob_clean();
-
- # show details for local requests
- $detailed = @$_SERVER['REMOTE_ADDR'] === '127.0.0.1';
-
- $body = sprintf('<html><head><title>Trails Error</title></head>'.
- '<body><h1>%s</h1><pre>%s</pre></body></html>',
- htmlentities($exception->__toString()),
- $detailed
- ? htmlentities($exception->getTraceAsString())
- : '');
-
- if ($exception instanceof Trails_Exception) {
- $response = new Trails_Response($body,
- $exception->headers,
- $exception->getCode(),
- $exception->getMessage());
- }
- else {
- $response = new Trails_Response($body, array(), 500,
- $exception->getMessage());
- }
-
- return $response;
- }
-
-
- /**
- * Clean up URI string by removing the query part and leading slashes.
- *
- * @param string an URI string
- *
- * @return string the cleaned string
- */
- function clean_request_uri($uri) {
- if (FALSE !== ($pos = strpos($uri, '?'))) {
- $uri = substr($uri, 0, $pos);
- }
- return ltrim($uri, '/');
- }
-
-
- /**
- * <MethodDescription>
- *
- * @param type <description>
- * @param type <description>
- *
- * @return type <description>
- */
- function parse($unconsumed, $controller = NULL) {
- list($head, $tail) = $this->split_on_first_slash($unconsumed);
-
- if (!preg_match('/^\w+$/', $head)) {
- throw new Trails_RoutingError("No route matches '$head'");
- }
-
- $controller = (isset($controller) ? $controller . '/' : '') . $head;
-
- if ($this->file_exists($controller . '.php')) {
- return array($controller, $tail);
- }
- else if ($this->file_exists($controller)) {
- return $this->parse($tail, $controller);
- }
-
- throw new Trails_RoutingError("No route matches '$head'");
- }
-
- function split_on_first_slash($str) {
- preg_match(":([^/]*)(/+)?(.*):", $str, $matches);
- return array($matches[1], $matches[3]);
- }
-
- function file_exists($path) {
- return file_exists("{$this->trails_root}/controllers/$path");
- }
-
- /**
- * Loads the controller file for a given controller path and return an
- * instance of that controller. If an error occures, an exception will be
- * thrown.
- *
- * @param string the relative controller path
- *
- * @return TrailsController an instance of that controller
- */
- function load_controller($controller) {
- require_once "{$this->trails_root}/controllers/{$controller}.php";
- $class = Trails_Inflector::camelize($controller) . 'Controller';
- if (!class_exists($class)) {
- throw new Trails_UnknownController("Controller missing: '$class'");
- }
- return new $class($this);
- }
-
-
- /**
- * This method transforms E_USER_* and E_RECOVERABLE_ERROR to
- * Trails_Exceptions.
- *
- * @param integer the level of the error raised
- * @param string the error message
- * @param string the filename that the error was raised in
- * @param integer the line number the error was raised at
- *
- * @throws Trails_Exception
- *
- * @return void
- */
- function error_handler($errno, $string, $file, $line) {
- if (!(5888 & $errno)) {
- return false;
- }
- throw new Trails_Exception(500, $string);
- }
-}
diff --git a/vendor/trails/src/exception.php b/vendor/trails/src/exception.php
deleted file mode 100644
index 4c21831..0000000
--- a/vendor/trails/src/exception.php
+++ /dev/null
@@ -1,101 +0,0 @@
-<?php
-
-/**
- * TODO
- *
- * @package trails
- *
- * @author mlunzena
- * @copyright (c) Authors
- * @version $Id: trails.php 7001 2008-04-04 11:20:27Z mlunzena $
- */
-
-class Trails_Exception extends Exception {
-
- /**
- * <FieldDescription>
- *
- * @access private
- * @var <type>
- */
- public $headers;
-
-
- /**
- * @param int the status code to be set in the response
- * @param string a human readable presentation of the status code
- * @param array a hash of additional headers to be set in the response
- *
- * @return void
- */
- function __construct($status = 500, $reason = NULL, $headers = array()) {
- if ($reason === NULL) {
- $reason = Trails_Response::get_reason($status);
- }
- parent::__construct($reason, $status);
- $this->headers = $headers;
- }
-
-
- /**
- * <MethodDescription>
- *
- * @param type <description>
- *
- * @return type <description>
- */
- function __toString() {
- return "{$this->code} {$this->message}";
- }
-}
-
-
-class Trails_DoubleRenderError extends Trails_Exception {
-
- function __construct() {
- $message =
- "Render and/or redirect were called multiple times in this action. ".
- "Please note that you may only call render OR redirect, and at most ".
- "once per action.";
- parent::__construct(500, $message);
- }
-}
-
-
-class Trails_MissingFile extends Trails_Exception {
- function __construct($message) {
- parent::__construct(500, $message);
- }
-}
-
-
-class Trails_RoutingError extends Trails_Exception {
-
- function __construct($message) {
- parent::__construct(400, $message);
- }
-}
-
-
-class Trails_UnknownAction extends Trails_Exception {
-
- function __construct($message) {
- parent::__construct(404, $message);
- }
-}
-
-
-class Trails_UnknownController extends Trails_Exception {
-
- function __construct($message) {
- parent::__construct(404, $message);
- }
-}
-
-
-class Trails_SessionRequiredException extends Trails_Exception {
- function __construct() {
- $message = "Tried to access a non existing session.";
- parent::__construct(500, $message);
- }
-}
diff --git a/vendor/trails/src/flash.php b/vendor/trails/src/flash.php
deleted file mode 100644
index cee08e5..0000000
--- a/vendor/trails/src/flash.php
+++ /dev/null
@@ -1,241 +0,0 @@
-<?php
-
-/**
- * The flash provides a way to pass temporary objects between actions.
- * Anything you place in the flash will be exposed to the very next action and
- * then cleared out. This is a great way of doing notices and alerts, such as
- * a create action that sets
- * <tt>$flash->set('notice', "Successfully created")</tt>
- * before redirecting to a display action that can then expose the flash to its
- * template.
- *
- * @package trails
- *
- * @author mlunzena
- * @copyright (c) Authors
- * @version $Id: trails.php 7001 2008-04-04 11:20:27Z mlunzena $
- */
-
-class Trails_Flash implements ArrayAccess {
-
-
- /**
- * @ignore
- */
- public
- $flash = array(), $used = array();
-
-
- /**
- * <MethodDescription>
- *
- * @return type <description>
- */
- static function instance() {
-
- if (!isset($_SESSION)) {
- throw new Trails_SessionRequiredException();
- }
-
-
- if (!isset($_SESSION['trails_flash'])) {
- $_SESSION['trails_flash'] = new Trails_Flash();
- }
- return $_SESSION['trails_flash'];
- }
-
-
- function offsetExists($offset) {
- return isset($this->flash[$offset]);
- }
-
-
- function offsetGet($offset) {
- return $this->get($offset);
- }
-
-
- function offsetSet($offset, $value) {
- $this->set($offset, $value);
- }
-
-
- function offsetUnset($offset) {
- unset($this->flash[$offset], $this->used[$offset]);
- }
-
-
- /**
- * Used internally by the <tt>keep</tt> and <tt>discard</tt> methods
- * use() # marks the entire flash as used
- * use('msg') # marks the "msg" entry as used
- * use(null, false) # marks the entire flash as unused
- * # (keeps it around for one more action)
- * use('msg', false) # marks the "msg" entry as unused
- * # (keeps it around for one more action)
- *
- * @param mixed a key.
- * @param bool used flag.
- *
- * @return void
- */
- function _use($k = NULL, $v = TRUE) {
- if ($k) {
- $this->used[$k] = $v;
- }
- else {
- foreach ($this->used as $k => $value) {
- $this->_use($k, $v);
- }
- }
- }
-
-
- /**
- * Marks the entire flash or a single flash entry to be discarded by the end
- * of the current action.
- *
- * $flash->discard() # discards entire flash
- * # (it'll still be available for the
- * # current action)
- * $flash->discard('warning') # discard the "warning" entry
- * # (it'll still be available for the
- * # current action)
- *
- * @param mixed a key.
- *
- * @return void
- */
- function discard($k = NULL) {
- $this->_use($k);
- }
-
-
- /**
- * Returns the value to the specified key.
- *
- * @param mixed a key.
- *
- * @return mixed the key's value.
- */
- function &get($k) {
- $return = NULL;
- if (isset($this->flash[$k])) {
- $return =& $this->flash[$k];
- }
- return $return;
- }
-
-
- /**
- * Keeps either the entire current flash or a specific flash entry available
- * for the next action:
- *
- * $flash->keep() # keeps the entire flash
- * $flash->keep('notice') # keeps only the "notice" entry, the rest of
- * # the flash is discarded
- *
- * @param mixed a key.
- *
- * @return void
- */
- function keep($k = NULL) {
- $this->_use($k, FALSE);
- }
-
-
- /**
- * Sets a key's value.
- *
- * @param mixed a key.
- * @param mixed its value.
- *
- * @return void
- */
- function set($k, $v) {
- $this->keep($k);
- $this->flash[$k] = $v;
- }
-
-
- /**
- * Sets a key's value by reference.
- *
- * @param mixed a key.
- * @param mixed its value.
- *
- * @return void
- */
- function set_ref($k, &$v) {
- $this->keep($k);
- $this->flash[$k] =& $v;
- }
-
-
-
- /**
- * <MethodDescription>
- *
- * @return type <description>
- */
- function sweep() {
-
- # remove used values
- foreach (array_keys($this->flash) as $k) {
- if ($this->used[$k]) {
- unset($this->flash[$k], $this->used[$k]);
- } else {
- $this->_use($k);
- }
- }
-
- # cleanup if someone meddled with flash or used
- $fkeys = array_keys($this->flash);
- $ukeys = array_keys($this->used);
- foreach (array_diff($fkeys, $ukeys) as $k => $v) {
- unset($this->used[$k]);
- }
- }
-
-
- /**
- * <MethodDescription>
- *
- * @return type <description>
- */
- function __toString() {
- $values = array();
- foreach ($this->flash as $k => $v) {
- $values[] = sprintf("'%s': [%s, '%s']",
- $k, var_export($v, TRUE),
- $this->used[$k] ? "used" : "unused");
- }
- return "{" . join(", ", $values) . "}\n";
- }
-
-
- /**
- * <MethodDescription>
- *
- * @param type <description>
- *
- * @return type <description>
- */
- function __sleep() {
- $this->sweep();
- return array('flash', 'used');
- }
-
-
- /**
- * <MethodDescription>
- *
- * @param type <description>
- *
- * @return type <description>
- */
- function __wakeUp() {
- $this->discard();
- }
-}
-
diff --git a/vendor/trails/src/inflector.php b/vendor/trails/src/inflector.php
deleted file mode 100644
index 6646eee..0000000
--- a/vendor/trails/src/inflector.php
+++ /dev/null
@@ -1,49 +0,0 @@
-<?php
-
-/**
- * The Inflector class is a namespace for inflections methods.
- *
- * @package trails
- *
- * @author mlunzena
- * @copyright (c) Authors
- * @version $Id: trails.php 7001 2008-04-04 11:20:27Z mlunzena $
- */
-
-class Trails_Inflector {
-
-
- /**
- * Returns a camelized string from a lower case and underscored string by
- * replacing slash with underscore and upper-casing each letter preceded
- * by an underscore. TODO
- *
- * @param string String to camelize.
- *
- * @return string Camelized string.
- */
- static function camelize($word) {
- $parts = explode('/', $word);
- foreach ($parts as $key => $part) {
- $parts[$key] = str_replace(' ', '',
- ucwords(str_replace('_', ' ', $part)));
- }
- return join('_', $parts);
- }
-
-
- /**
- * <MethodDescription>
- *
- * @param type <description>
- *
- * @return type <description>
- */
- static function underscore($word) {
- $parts = explode('_', $word);
- foreach ($parts as $key => $part) {
- $parts[$key] = preg_replace('/(?<=\w)([A-Z])/', '_\\1', $part);
- }
- return strtolower(join('/', $parts));
- }
-}
diff --git a/vendor/trails/src/response.php b/vendor/trails/src/response.php
deleted file mode 100644
index 474bfc1..0000000
--- a/vendor/trails/src/response.php
+++ /dev/null
@@ -1,166 +0,0 @@
-<?php
-
-/**
- * This class represents a response returned by a controller that was asked to
- * perform for a given request. A Trails_Response contains the body, status and
- * additional headers which can be renderer back to the client.
- *
- * @package trails
- *
- * @author mlunzena
- * @copyright (c) Authors
- * @version $Id: trails.php 7001 2008-04-04 11:20:27Z mlunzena $
- */
-
-class Trails_Response {
-
-
- /**
- * @ignore
- */
- public
- $body = '',
- $status,
- $reason,
- $headers = array();
-
-
- /**
- * Constructor.
- *
- * @param string the body of the response defaulting to ''
- * @param array an array of additional headers defaulting to an
- * empty array
- * @param integer the status code of the response defaulting to a
- * regular 200
- * @param string the descriptional reason for a status code defaulting to
- * the standard reason phrases defined in RFC 2616
- *
- * @return void
- */
- function __construct($body = '', $headers = array(),
- $status = NULL, $reason = NULL) {
-
- $this->set_body($body);
-
- $this->headers = $headers;
-
- if (isset($status)) {
- $this->set_status($status, $reason);
- }
- }
-
-
- /**
- * Sets the body of the response.
- *
- * @param string the body
- *
- * @return mixed this response object. Useful for cascading method calls.
- */
- function set_body($body) {
- $this->body = $body;
- return $this;
- }
-
-
- /**
- * Sets the status code and an optional custom reason. If none is given, the
- * standard reason phrase as of RFC 2616 is used.
- *
- * @param integer the status code
- * @param string the custom reason, defaulting to the one given in RFC 2616
- *
- * @return mixed this response object. Useful for cascading method calls.
- */
- function set_status($status, $reason = NULL) {
- $this->status = $status;
- $this->reason = isset($reason) ? $reason : self::get_reason($status);
- return $this;
- }
-
-
- /**
- * Returns the reason phrase of this response according to RFC2616.
- *
- * @param int the response's status
- *
- * @return string the reason phrase for this response's status
- */
- public static function get_reason($status) {
- $reason = array(
- 100 => 'Continue', 'Switching Protocols',
- 200 => 'OK', 'Created', 'Accepted', 'Non-Authoritative Information',
- 'No Content', 'Reset Content', 'Partial Content',
- 300 => 'Multiple Choices', 'Moved Permanently', 'Found', 'See Other',
- 'Not Modified', 'Use Proxy', '(Unused)', 'Temporary Redirect',
- 400 => 'Bad Request', 'Unauthorized', 'Payment Required','Forbidden',
- 'Not Found', 'Method Not Allowed', 'Not Acceptable',
- 'Proxy Authentication Required', 'Request Timeout', 'Conflict',
- 'Gone', 'Length Required', 'Precondition Failed',
- 'Request Entity Too Large', 'Request-URI Too Long',
- 'Unsupported Media Type', 'Requested Range Not Satisfiable',
- 'Expectation Failed',
- 500 => 'Internal Server Error', 'Not Implemented', 'Bad Gateway',
- 'Service Unavailable', 'Gateway Timeout',
- 'HTTP Version Not Supported');
-
- return isset($reason[$status]) ? $reason[$status] : '';
- }
-
-
- /**
- * Adds an additional header to the response.
- *
- * @param string the left hand key part
- * @param string the right hand value part
- *
- * @return mixed this response object. Useful for cascading method calls.
- */
- function add_header($key, $value) {
- $this->headers[$key] = $value;
- return $this;
- }
-
-
- /**
- * Outputs this response to the client using "echo" and "header".
- *
- * @return void
- */
- function output() {
- if (isset($this->status)) {
- $this->send_header(sprintf('HTTP/1.1 %d %s',
- $this->status, $this->reason),
- TRUE,
- $this->status);
- }
-
- foreach ($this->headers as $k => $v) {
- $this->send_header("$k: $v");
- }
-
- echo $this->body;
- }
-
-
- /**
- * Internally used function to actually send headers
- *
- * @param string the HTTP header
- * @param bool optional; TRUE if previously sent header should be
- * replaced - FALSE otherwise (default)
- * @param integer optional; the HTTP response code
- *
- * @return void
- */
- function send_header($header, $replace = FALSE, $status = NULL) {
- if (isset($status)) {
- header($header, $replace, $status);
- }
- else {
- header($header, $replace);
- }
- }
-}
-
diff --git a/vendor/trails/src/trails.php b/vendor/trails/src/trails.php
deleted file mode 100644
index 2e9e8e2..0000000
--- a/vendor/trails/src/trails.php
+++ /dev/null
@@ -1,16 +0,0 @@
-<?php
-function fgc($files/*, ... */) {
- $result = '';
- $files = func_get_args();
- foreach ($files as $file) {
- $string = file_get_contents(dirname(__FILE__)."/$file.php");
- $result .= preg_replace("/^(<\?(php)?)|(\?>)\s*\v+$/", "", $string);
- }
- return $result;
-}
-?>
-<?= "<?php" ?>
-<?= fgc("HEADER") ?>
-
-<?= fgc("dispatcher", "response", "controller",
- "inflector", "flash", "exception") ?>
diff --git a/vendor/trails/trails-abridged.php b/vendor/trails/trails-abridged.php
deleted file mode 100644
index 07b337a..0000000
--- a/vendor/trails/trails-abridged.php
+++ /dev/null
@@ -1,3 +0,0 @@
-<?php
-
-define('TRAILS_VERSION','0.6.9');class Trails_Dispatcher{public$trails_root;public$trails_uri;public$default_controller;function __construct($trails_root, $trails_uri, $default_controller){$this->trails_root=$trails_root;$this->trails_uri=$trails_uri;$this->default_controller=$default_controller;}function dispatch($uri){$old_handler=set_error_handler(array($this, 'error_handler'),5888);ob_start();$level=ob_get_level();$this->map_uri_to_response($this->clean_request_uri((string)$uri))->output();while(ob_get_level()>=$level){ob_end_flush();}if(isset($old_handler)){set_error_handler($old_handler);}}function map_uri_to_response($uri){try{[$controller_path, $unconsumed]=''===$uri?$this->default_route():$this->parse($uri);$controller=$this->load_controller($controller_path);$response=$controller->perform($unconsumed);}catch(Exception$e){$response=isset($controller)?$controller->rescue($e):$this->trails_error($e);}return$response;}function default_route(){if(!$this->file_exists($this->default_controller.'.php')){throw new Trails_MissingFile("Default controller '{$this->default_controller}' not found'");}return array($this->default_controller, '');}function trails_error($exception){ob_clean();$detailed=@$_SERVER['REMOTE_ADDR']==='127.0.0.1';$body=sprintf('<html><head><title>Trails Error</title></head>'.'<body><h1>%s</h1><pre>%s</pre></body></html>',htmlentities($exception->__toString()),$detailed?htmlentities($exception->getTraceAsString()):'');if($exception instanceof Trails_Exception){$response=new Trails_Response($body,$exception->headers,$exception->getCode(),$exception->getMessage());}else{$response=new Trails_Response($body,array(),500,$exception->getMessage());}return$response;}function clean_request_uri($uri){if(FALSE!==($pos=strpos($uri,'?'))){$uri=substr($uri,0,$pos);}return ltrim($uri,'/');}function parse($unconsumed, $controller=NULL){[$head, $tail]=$this->split_on_first_slash($unconsumed);if(!preg_match('/^\w+$/',$head)){throw new Trails_RoutingError("No route matches '$head'");}$controller=(isset($controller)?$controller.'/':'').$head;if($this->file_exists($controller.'.php')){return array($controller, $tail);}else if($this->file_exists($controller)){return$this->parse($tail,$controller);}throw new Trails_RoutingError("No route matches '$head'");}function split_on_first_slash($str){preg_match(":([^/]*)(/+)?(.*):",$str,$matches);return array($matches[1], $matches[3]);}function file_exists($path){return file_exists("{$this->trails_root}/controllers/$path");}function load_controller($controller){require_once"{$this->trails_root}/controllers/{$controller}.php";$class=Trails_Inflector::camelize($controller).'Controller';if(!class_exists($class)){throw new Trails_UnknownController("Controller missing: '$class'");}return new$class($this);}function error_handler($errno, $string, $file, $line, $context){if(!(5888&$errno))return false;throw new Trails_Exception(500,$string);}}class Trails_Response{public$body='',$status,$reason,$headers=array();function __construct($body='', $headers=array(), $status=NULL, $reason=NULL){$this->set_body($body);$this->headers=$headers;if(isset($status)){$this->set_status($status,$reason);}}function set_body($body){$this->body=$body;return$this;}function set_status($status, $reason=NULL){$this->status=$status;$this->reason=isset($reason)?$reason:$this->get_reason($status);return$this;}function get_reason($status){$reason=array(100 =>'Continue', 'Switching Protocols', 200 =>'OK', 'Created', 'Accepted', 'Non-Authoritative Information', 'No Content', 'Reset Content', 'Partial Content', 300 =>'Multiple Choices', 'Moved Permanently', 'Found', 'See Other', 'Not Modified', 'Use Proxy', '(Unused)', 'Temporary Redirect', 400 =>'Bad Request', 'Unauthorized', 'Payment Required', 'Forbidden', 'Not Found', 'Method Not Allowed', 'Not Acceptable', 'Proxy Authentication Required', 'Request Timeout', 'Conflict', 'Gone', 'Length Required', 'Precondition Failed', 'Request Entity Too Large', 'Request-URI Too Long', 'Unsupported Media Type', 'Requested Range Not Satisfiable', 'Expectation Failed', 500 =>'Internal Server Error', 'Not Implemented', 'Bad Gateway', 'Service Unavailable', 'Gateway Timeout', 'HTTP Version Not Supported');return isset($reason[$status])? $reason[$status]:'';}function add_header($key, $value){$this->headers[$key]=$value;return$this;}function output(){if(isset($this->status)){$this->send_header(sprintf('HTTP/1.1 %d %s',$this->status,$this->reason),TRUE,$this->status);}foreach($this->headers as $k=> $v){$this->send_header("$k: $v");}echo$this->body;}function send_header($header, $replace=FALSE, $status=NULL){if(isset($status)){header($header,$replace,$status);}else{header($header,$replace);}}}class Trails_Controller{protected$dispatcher,$response,$performed,$layout;function __construct($dispatcher){$this->dispatcher=$dispatcher;$this->erase_response();}function erase_response(){$this->performed=FALSE;$this->response=new Trails_Response();}function get_response(){return$this->response;}function perform($unconsumed){[$action, $args, $format]=$this->extract_action_and_args($unconsumed);$this->format=isset($format)?$format:'html';$before_filter_result=$this->before_filter($action,$args);if(!(FALSE===$before_filter_result||$this->performed)){$callable=$this->map_action($action);if(is_callable($callable)){call_user_func_array($callable,$args);}else{$this->does_not_understand($action,$args);}if(!$this->performed){$this->render_action($action);}$this->after_filter($action,$args);}return$this->response;}function extract_action_and_args($string){if(''===$string){return$this->default_action_and_args();}$format=NULL;if(preg_match('/^(.*[^\/.])\.(\w+)$/',$string,$matches)){[$_, $string, $format]=$matches;}$args=explode('/',$string);$action=array_shift($args);return array($action, $args, $format);}function default_action_and_args(){return array('index', array(), NULL);}function map_action($action){return array(&$this, $action.'_action');}function before_filter(&$action, &$args){}function after_filter($action, $args){}function does_not_understand($action, $args){throw new Trails_UnknownAction("No action responded to '$action'.");}function redirect($to){if($this->performed){throw new Trails_DoubleRenderError();}$this->performed=TRUE;$url=preg_match('#^(/|\w+://)#',$to)?$to:$this->url_for($to);$this->response->add_header('Location',$url)->set_status(302);}function render_text($text=' '){if($this->performed){throw new Trails_DoubleRenderError();}$this->performed=TRUE;$this->response->set_body($text);}function render_nothing(){$this->render_text('');}function render_action($action){$this->render_template($this->get_default_template($action),$this->layout);}function get_default_template($action){$class=get_class($this);$controller_name=Trails_Inflector::underscore(substr($class,0,-10));return$controller_name.'/'.$action;}function render_template($template_name, $layout=NULL){$factory=$this->get_template_factory();$template=$factory->open($template_name);$template->set_attributes($this->get_assigned_variables());if(isset($layout)){$template->set_layout($layout);}$this->render_text($template->render());}function get_template_factory(){return new Flexi\Factory($this->dispatcher->trails_root.'/views/');}function get_assigned_variables(){$assigns=array();$protected=get_class_vars(get_class($this));foreach(get_object_vars($this) as $var=> $value){if(!array_key_exists($var,$protected)){$assigns[$var]=&$this->$var;}}$assigns['controller']=$this;return$assigns;}function set_layout($layout){$this->layout=$layout;}function url_for($to){$args=func_get_args();$args=array_map('urlencode',$args);$args[0]=$to;return$this->dispatcher->trails_uri.'/'.join('/',$args);}function set_status($status, $reason_phrase=NULL){$this->response->set_status($status,$reason_phrase);}function set_content_type($type){$this->response->add_header('Content-Type',$type);}function rescue($exception){return$this->dispatcher->trails_error($exception);}function respond_to($ext){return$this->format===$ext;}}class Trails_Inflector{static function camelize($word){$parts=explode('/',$word);foreach($parts as $key=> $part){$parts[$key]=str_replace(' ','',ucwords(str_replace('_',' ',$part)));}return join('_',$parts);}static function underscore($word){$parts=explode('_',$word);foreach($parts as $key=> $part){$parts[$key]=preg_replace('/(?<=\w)([A-Z])/','_\\1',$part);}return strtolower(join('/',$parts));}}class Trails_Flash implements ArrayAccess{public$flash=array(),$used=array();static function instance(){if(!isset($_SESSION)){throw new Trails_SessionRequiredException();}if(!isset($_SESSION['trails_flash'])){$_SESSION['trails_flash']=new Trails_Flash();}return $_SESSION['trails_flash'];}function offsetExists($offset){return isset($this->flash[$offset]);}function offsetGet($offset){return$this->get($offset);}function offsetSet($offset, $value){$this->set($offset,$value);}function offsetUnset($offset){unset($this->flash[$offset], $this->used[$offset]);}function _use($k=NULL, $v=TRUE){if($k){$this->used[$k]=$v;}else{foreach($this->used as $k=> $value){$this->_use($k,$v);}}}function discard($k=NULL){$this->_use($k);}function&get($k){$return=NULL;if(isset($this->flash[$k])){$return=& $this->flash[$k];}return$return;}function keep($k=NULL){$this->_use($k,FALSE);}function set($k, $v){$this->keep($k);$this->flash[$k]=$v;}function set_ref($k, &$v){$this->keep($k);$this->flash[$k]=&$v;}function sweep(){foreach(array_keys($this->flash) as $k){if($this->used[$k]){unset($this->flash[$k], $this->used[$k]);}else{$this->_use($k);}}$fkeys=array_keys($this->flash);$ukeys=array_keys($this->used);foreach(array_diff($fkeys,$ukeys) as $k=> $v){unset($this->used[$k]);}}function __toString(){$values=array();foreach($this->flash as $k=> $v){$values[]=sprintf("'%s': [%s, '%s']",$k,var_export($v,TRUE), $this->used[$k]?"used":"unused");}return"{".join(", ",$values)."}\n";}function __sleep(){$this->sweep();return array('flash', 'used');}function __wakeUp(){$this->discard();}}class Trails_Exception extends Exception{public$headers;function __construct($status=500, $reason=NULL, $headers=array()){if($reason===NULL){$reason=Trails_Response::get_reason($status);}parent::__construct($reason,$status);$this->headers=$headers;}function __toString(){return"{$this->code} {$this->message}";}}class Trails_DoubleRenderError extends Trails_Exception{function __construct(){$message="Render and/or redirect were called multiple times in this action. "."Please note that you may only call render OR redirect, and at most "."once per action.";parent::__construct(500,$message);}}class Trails_MissingFile extends Trails_Exception{function __construct($message){parent::__construct(500,$message);}}class Trails_RoutingError extends Trails_Exception{function __construct($message){parent::__construct(400,$message);}}class Trails_UnknownAction extends Trails_Exception{function __construct($message){parent::__construct(404,$message);}}class Trails_UnknownController extends Trails_Exception{function __construct($message){parent::__construct(404,$message);}}class Trails_SessionRequiredException extends Trails_Exception{function __construct(){$message="Tried to access a non existing session.";parent::__construct(500,$message);}}
diff --git a/vendor/trails/trails.php b/vendor/trails/trails.php
deleted file mode 100644
index 9117655..0000000
--- a/vendor/trails/trails.php
+++ /dev/null
@@ -1,1289 +0,0 @@
-<?php
-
-# Copyright (c) 2007 - Marcus Lunzenauer <mlunzena@uos.de>
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in all
-# copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-# SOFTWARE.
-
-
-/**
- * The version of the trails library.
- */
-
-define('TRAILS_VERSION', '0.6.9');
-
-
-
-/**
- * The Dispatcher is used to map an incoming HTTP request to a Controller
- * producing a response which is then rendered. To initialize an instance of
- * class Trails_Dispatcher you have to give three configuration settings:
- *
- * trails_root - the absolute file path to a directory containing the
- * applications controllers, views etc.
- * trails_uri - the URI to which routes to mapped Controller/Actions
- * are appended
- * default_controller - the route to a controller, that is used if no
- * controller is given, that is the route is equal to '/'
- *
- * After instantiation of a dispatcher you have to call method #dispatch with
- * the request uri to be mapped to a controller/action pair.
- *
- * @package trails
- *
- * @author mlunzena
- * @copyright (c) Authors
- * @version $Id: trails.php 7001 2008-04-04 11:20:27Z mlunzena $
- */
-
-class Trails_Dispatcher {
-
- # TODO (mlunzena) Konfiguration muss anders geschehen
-
- /**
- * This is the absolute file path to the trails application directory.
- *
- * @access public
- * @var string
- */
- public $trails_root;
-
-
- /**
- * This is the URI to which routes to controller/actions are appended.
- *
- * @access public
- * @var string
- */
- public $trails_uri;
-
-
- /**
- * This variable contains the route to the default controller.
- *
- * @access public
- * @var string
- */
- public $default_controller;
-
-
- /**
- * Constructor.
- *
- * @param string absolute file path to a directory containing the
- * applications controllers, views etc.
- * @param string the URI to which routes to mapped Controller/Actions
- * are appended
- * @param string the route to a controller, that is used if no
- * controller is given, that is the route is equal to '/'
- *
- * @return void
- */
- function __construct($trails_root,
- $trails_uri,
- $default_controller) {
-
- $this->trails_root = $trails_root;
- $this->trails_uri = $trails_uri;
- $this->default_controller = $default_controller;
- }
-
-
- /**
- * Maps a string to a response which is then rendered.
- *
- * @param string The requested URI.
- *
- * @return void
- */
- function dispatch($uri) {
-
- # E_USER_ERROR|E_USER_WARNING|E_USER_NOTICE|E_RECOVERABLE_ERROR = 5888
- $old_handler = set_error_handler(array($this, 'error_handler'), 5888);
-
- ob_start();
- $level = ob_get_level();
-
- $this->map_uri_to_response($this->clean_request_uri((string) $uri))->output();
-
- while (ob_get_level() >= $level) {
- ob_end_flush();
- }
-
- if (isset($old_handler)) {
- set_error_handler($old_handler);
- }
- }
-
-
- /**
- * Maps an URI to a response by figuring out first what controller to
- * instantiate, then delegating the unconsumed part of the URI to the
- * controller who returns an appropriate response object or throws a
- * Trails_Exception.
- *
- * @param string the URI string
- *
- * @return mixed a response object
- */
- function map_uri_to_response($uri) {
-
- try {
-
- list($controller_path, $unconsumed) =
- '' === $uri
- ? $this->default_route()
- : $this->parse($uri);
-
- $controller = $this->load_controller($controller_path);
-
- $response = $controller->perform($unconsumed);
-
- } catch (Exception $e) {
-
- $response = isset($controller) ? $controller->rescue($e)
- : $this->trails_error($e);
- }
-
- return $response;
- }
-
-
- /**
- *
- * @return array an array containing the default controller and an
- * empty unconsumed route
- */
- function default_route() {
- if (!$this->file_exists($this->default_controller . '.php')) {
- throw new Trails_MissingFile(
- "Default controller '{$this->default_controller}' not found'");
- }
- return array($this->default_controller, '');
- }
-
-
- function trails_error($exception) {
- ob_clean();
-
- # show details for local requests
- $detailed = @$_SERVER['REMOTE_ADDR'] === '127.0.0.1';
-
- $body = sprintf('<html><head><title>Trails Error</title></head>'.
- '<body><h1>%s</h1><pre>%s</pre></body></html>',
- htmlentities($exception->__toString()),
- $detailed
- ? htmlentities($exception->getTraceAsString())
- : '');
-
- if ($exception instanceof Trails_Exception) {
- $response = new Trails_Response($body,
- $exception->headers,
- $exception->getCode(),
- $exception->getMessage());
- }
- else {
- $response = new Trails_Response($body, array(), 500,
- $exception->getMessage());
- }
-
- return $response;
- }
-
-
- /**
- * Clean up URI string by removing the query part and leading slashes.
- *
- * @param string an URI string
- *
- * @return string the cleaned string
- */
- function clean_request_uri($uri) {
- if (FALSE !== ($pos = strpos($uri, '?'))) {
- $uri = substr($uri, 0, $pos);
- }
- return ltrim($uri, '/');
- }
-
-
- /**
- * <MethodDescription>
- *
- * @param type <description>
- * @param type <description>
- *
- * @return type <description>
- */
- function parse($unconsumed, $controller = NULL) {
- list($head, $tail) = $this->split_on_first_slash($unconsumed);
-
- if (!preg_match('/^\w+$/', $head)) {
- throw new Trails_RoutingError("No route matches '$head'");
- }
-
- $controller = (isset($controller) ? $controller . '/' : '') . $head;
-
- if ($this->file_exists($controller . '.php')) {
- return array($controller, $tail);
- }
- else if ($this->file_exists($controller)) {
- return $this->parse($tail, $controller);
- }
-
- throw new Trails_RoutingError("No route matches '$head'");
- }
-
- function split_on_first_slash($str) {
- preg_match(":([^/]*)(/+)?(.*):", $str, $matches);
- return array($matches[1], $matches[3]);
- }
-
- function file_exists($path) {
- return file_exists("{$this->trails_root}/controllers/$path");
- }
-
- /**
- * Loads the controller file for a given controller path and return an
- * instance of that controller. If an error occures, an exception will be
- * thrown.
- *
- * @param string the relative controller path
- *
- * @return TrailsController an instance of that controller
- */
- function load_controller($controller) {
- require_once "{$this->trails_root}/controllers/{$controller}.php";
- $class = Trails_Inflector::camelize($controller) . 'Controller';
- if (!class_exists($class)) {
- throw new Trails_UnknownController("Controller missing: '$class'");
- }
- return new $class($this);
- }
-
-
- /**
- * This method transforms E_USER_* and E_RECOVERABLE_ERROR to
- * Trails_Exceptions.
- *
- * @param integer the level of the error raised
- * @param string the error message
- * @param string the filename that the error was raised in
- * @param integer the line number the error was raised at
- *
- * @throws Trails_Exception
- *
- * @return void
- */
- function error_handler($errno, $string, $file, $line) {
- if (!(5888 & $errno)) {
- return false;
- }
- throw new Trails_Exception(500, $string);
- }
-}
-
-
-/**
- * This class represents a response returned by a controller that was asked to
- * perform for a given request. A Trails_Response contains the body, status and
- * additional headers which can be renderer back to the client.
- *
- * @package trails
- *
- * @author mlunzena
- * @copyright (c) Authors
- * @version $Id: trails.php 7001 2008-04-04 11:20:27Z mlunzena $
- */
-
-class Trails_Response {
-
-
- /**
- * @ignore
- */
- public
- $body = '',
- $status,
- $reason,
- $headers = array();
-
-
- /**
- * Constructor.
- *
- * @param string the body of the response defaulting to ''
- * @param array an array of additional headers defaulting to an
- * empty array
- * @param integer the status code of the response defaulting to a
- * regular 200
- * @param string the descriptional reason for a status code defaulting to
- * the standard reason phrases defined in RFC 2616
- *
- * @return void
- */
- function __construct($body = '', $headers = array(),
- $status = NULL, $reason = NULL) {
-
- $this->set_body($body);
-
- $this->headers = $headers;
-
- if (isset($status)) {
- $this->set_status($status, $reason);
- }
- }
-
-
- /**
- * Sets the body of the response.
- *
- * @param string the body
- *
- * @return mixed this response object. Useful for cascading method calls.
- */
- function set_body($body) {
- $this->body = $body;
- return $this;
- }
-
-
- /**
- * Sets the status code and an optional custom reason. If none is given, the
- * standard reason phrase as of RFC 2616 is used.
- *
- * @param integer the status code
- * @param string the custom reason, defaulting to the one given in RFC 2616
- *
- * @return mixed this response object. Useful for cascading method calls.
- */
- function set_status($status, $reason = NULL) {
- $this->status = $status;
- $this->reason = isset($reason) ? $reason : self::get_reason($status);
- return $this;
- }
-
-
- /**
- * Returns the reason phrase of this response according to RFC2616.
- *
- * @param int the response's status
- *
- * @return string the reason phrase for this response's status
- */
- public static function get_reason($status) {
- $reason = array(
- 100 => 'Continue', 'Switching Protocols',
- 200 => 'OK', 'Created', 'Accepted', 'Non-Authoritative Information',
- 'No Content', 'Reset Content', 'Partial Content',
- 300 => 'Multiple Choices', 'Moved Permanently', 'Found', 'See Other',
- 'Not Modified', 'Use Proxy', '(Unused)', 'Temporary Redirect',
- 400 => 'Bad Request', 'Unauthorized', 'Payment Required','Forbidden',
- 'Not Found', 'Method Not Allowed', 'Not Acceptable',
- 'Proxy Authentication Required', 'Request Timeout', 'Conflict',
- 'Gone', 'Length Required', 'Precondition Failed',
- 'Request Entity Too Large', 'Request-URI Too Long',
- 'Unsupported Media Type', 'Requested Range Not Satisfiable',
- 'Expectation Failed',
- 500 => 'Internal Server Error', 'Not Implemented', 'Bad Gateway',
- 'Service Unavailable', 'Gateway Timeout',
- 'HTTP Version Not Supported');
-
- return isset($reason[$status]) ? $reason[$status] : '';
- }
-
-
- /**
- * Adds an additional header to the response.
- *
- * @param string the left hand key part
- * @param string the right hand value part
- *
- * @return mixed this response object. Useful for cascading method calls.
- */
- function add_header($key, $value) {
- $this->headers[$key] = $value;
- return $this;
- }
-
-
- /**
- * Outputs this response to the client using "echo" and "header".
- *
- * @return void
- */
- function output() {
- if (isset($this->status)) {
- $this->send_header(sprintf('HTTP/1.1 %d %s',
- $this->status, $this->reason),
- TRUE,
- $this->status);
- }
-
- foreach ($this->headers as $k => $v) {
- $this->send_header("$k: $v");
- }
-
- echo $this->body;
- }
-
-
- /**
- * Internally used function to actually send headers
- *
- * @param string the HTTP header
- * @param bool optional; TRUE if previously sent header should be
- * replaced - FALSE otherwise (default)
- * @param integer optional; the HTTP response code
- *
- * @return void
- */
- function send_header($header, $replace = FALSE, $status = NULL) {
- if (isset($status)) {
- header($header, $replace, $status);
- }
- else {
- header($header, $replace);
- }
- }
-}
-
-
-
-/**
- * A Trails_Controller is responsible for matching the unconsumed part of an URI
- * to an action using the left over words as arguments for that action. The
- * action is then mapped to method of the controller instance which is called
- * with the just mentioned arguments. That method can send the #render_action,
- * #render_template, #render_text, #render_nothing or #redirect method.
- * Otherwise the #render_action is called with the current action as argument.
- * If the action method sets instance variables during performing, they will be
- * be used as attributes for the flexi-template opened by #render_action or
- * #render_template. A controller's response's body is populated with the output
- * of the #render_* methods. The action methods can add additional headers or
- * change the status of that response.
- *
- * @package trails
- *
- * @author mlunzena
- * @copyright (c) Authors
- * @version $Id: trails.php 7001 2008-04-04 11:20:27Z mlunzena $
- */
-
-class Trails_Controller {
-
-
- /**
- * @ignore
- */
- protected
- $dispatcher,
- $response,
- $performed,
- $layout;
-
-
- /**
- * Constructor.
- *
- * @param mixed the dispatcher who creates this instance
- *
- * @return void
- */
- function __construct($dispatcher) {
- $this->dispatcher = $dispatcher;
- $this->erase_response();
- }
-
-
- /**
- * Resets the response of the controller
- *
- * @return void
- */
- function erase_response() {
- $this->performed = FALSE;
- $this->response = new Trails_Response();
- }
-
-
- /**
- * Return this controller's response
- *
- * @return mixed the controller's response
- */
- function get_response() {
- return $this->response;
- }
-
-
- /**
- * This method extracts an action string and further arguments from it's
- * parameter. The action string is mapped to a method being called afterwards
- * using the said arguments. That method is called and a response object is
- * generated, populated and sent back to the dispatcher.
- *
- * @param type <description>
- *
- * @return type <description>
- */
- function perform($unconsumed) {
-
- list($action, $args, $format) = $this->extract_action_and_args($unconsumed);
-
- $this->format = isset($format) ? $format : 'html';
-
- $before_filter_result = $this->before_filter($action, $args);
-
- # send action to controller
- # TODO (mlunzena) shouldn't the after filter be triggered too?
- if (!(FALSE === $before_filter_result || $this->performed)) {
-
- $callable = $this->map_action($action);
-
- if (is_callable($callable)) {
- call_user_func_array($callable, $args);
- }
- else {
- $this->does_not_understand($action, $args);
- }
-
- if (!$this->performed) {
- $this->render_action($action);
- }
-
- $this->after_filter($action, $args);
- }
-
- return $this->response;
- }
-
-
- /**
- * Extracts action and args from a string.
- *
- * @param string the processed string
- *
- * @return array an array with two elements - a string containing the
- * action and an array of strings representing the args
- */
- function extract_action_and_args($string) {
-
- if ('' === $string) {
- return $this->default_action_and_args();
- }
-
- // find optional file extension
- $format = NULL;
- if (preg_match('/^(.*[^\/.])\.(\w+)$/', $string, $matches)) {
- list($_, $string, $format) = $matches;
- }
-
- // TODO this should possibly remove empty tokens
- $args = explode('/', $string);
- $action = array_shift($args);
- return array($action, $args, $format);
- }
-
- /**
- * Return the default action and arguments
- *
- * @return an array containing the action, an array of args and the format
- *
- */
- function default_action_and_args() {
- return array('index', array(), NULL);
- }
-
- /**
- * Maps the action to an actual method name.
- *
- * @param string the action
- *
- * @return string the mapped method name
- */
- function map_action($action) {
- return array(&$this, $action . '_action');
- }
-
-
- /**
- * Callback function being called before an action is executed. If this
- * function does not return FALSE, the action will be called, otherwise
- * an error will be generated and processing will be aborted. If this function
- * already #rendered or #redirected, further processing of the action is
- * withheld.
- *
- * @param string Name of the action to perform.
- * @param array An array of arguments to the action.
- *
- * @return bool
- */
- function before_filter(&$action, &$args) {
- }
-
-
- /**
- * Callback function being called after an action is executed.
- *
- * @param string Name of the action to perform.
- * @param array An array of arguments to the action.
- *
- * @return void
- */
- function after_filter($action, $args) {
- }
-
-
- /**
- * <MethodDescription>
- *
- * @param type <description>
- * @param type <description>
- *
- * @return void
- */
- function does_not_understand($action, $args) {
- throw new Trails_UnknownAction("No action responded to '$action'.");
- }
-
-
- /**
- * <MethodDescription>
- *
- * @param string <description>
- *
- * @return void
- */
- function redirect($to) {
-
- if ($this->performed) {
- throw new Trails_DoubleRenderError();
- }
-
- $this->performed = TRUE;
-
- # get uri; keep absolute URIs
- $url = preg_match('#^(/|\w+://)#', $to)
- ? $to
- : $this->url_for($to);
-
- $this->response->add_header('Location', $url)->set_status(302);
- }
-
-
- /**
- * Renders the given text as the body of the response.
- *
- * @param string the text to be rendered
- *
- * @return void
- */
- function render_text($text = ' ') {
-
- if ($this->performed) {
- throw new Trails_DoubleRenderError();
- }
-
- $this->performed = TRUE;
-
- $this->response->set_body($text);
- }
-
-
- /**
- * Renders the empty string as the response's body.
- *
- * @return void
- */
- function render_nothing() {
- $this->render_text('');
- }
-
-
- /**
- * Renders the template of the given action as the response's body.
- *
- * @param string the action
- *
- * @return void
- */
- function render_action($action) {
- $this->render_template($this->get_default_template($action), $this->layout);
- }
-
-
- function get_default_template($action)
- {
- $class = get_class($this);
- $controller_name =
- Trails_Inflector::underscore(substr($class, 0, -10));
- return $controller_name.'/'.$action;
- }
-
-
- /**
- * Renders a template using an optional layout template.
- *
- * @param mixed a flexi template
- * @param mixes a flexi template which is used as layout
- *
- * @return void
- */
- function render_template($template_name, $layout = NULL) {
-
- # open template
- $factory = $this->get_template_factory();
- $template = $factory->open($template_name);
-
- $template->set_attributes($this->get_assigned_variables());
-
- if (isset($layout)) {
- $template->set_layout($layout);
- }
-
- $this->render_text($template->render());
- }
-
-
- /**
- * Create and return a template factory for this controller.
- *
- * @return Flexi\Factory
- */
- function get_template_factory() {
- return new Flexi\Factory($this->dispatcher->trails_root .
- '/views/');
- }
-
-
- /**
- * This method returns all the set instance variables to be used as attributes
- * for a template. This controller is returned too as value for
- * key 'controller'.
- *
- * @return array an associative array of variables for the template
- */
- function get_assigned_variables() {
-
- $assigns = array();
- $protected = get_class_vars(get_class($this));
-
- foreach (get_object_vars($this) as $var => $value) {
- if (!array_key_exists($var, $protected)) {
- $assigns[$var] =& $this->$var;
- }
- }
-
- $assigns['controller'] = $this;
-
- return $assigns;
- }
-
-
- /**
- * Sets the layout to be used by this controller per default.
- *
- * @param mixed a flexi template to be used as layout
- *
- * @return void
- */
- function set_layout($layout) {
- $this->layout = $layout;
- }
-
-
- /**
- * Returns a URL to a specified route to your Trails application.
- *
- * Example:
- * Your Trails application is located at 'http://example.com/dispatch.php'.
- * So your dispatcher's trails_uri is set to 'http://example.com/dispatch.php'
- * If you want the URL to your 'wiki' controller with action 'show' and
- * parameter 'page' you should send:
- *
- * $url = $controller->url_for('wiki/show', 'page');
- *
- * $url should then contain 'http://example.com/dispatch.php/wiki/show/page'.
- *
- * The first parameter is a string containing the controller and optionally an
- * action:
- *
- * - "{controller}/{action}"
- * - "path/to/controller/action"
- * - "controller"
- *
- * This "controller/action" string is not url encoded. You may provide
- * additional parameter which will be urlencoded and concatenated with
- * slashes:
- *
- * $controller->url_for('wiki/show', 'page');
- * -> 'wiki/show/page'
- *
- * $controller->url_for('wiki/show', 'page', 'one and a half');
- * -> 'wiki/show/page/one+and+a+half'
- *
- * @param string a string containing a controller and optionally an action
- * @param strings optional arguments
- *
- * @return string a URL to this route
- */
- function url_for($to/*, ...*/) {
-
- # urlencode all but the first argument
- $args = func_get_args();
- $args = array_map('urlencode', $args);
- $args[0] = $to;
-
- return $this->dispatcher->trails_uri . '/' . join('/', $args);
- }
-
-
- /**
- * <MethodDescription>
- *
- * @param type <description>
- *
- * @return type <description>
- */
- function set_status($status, $reason_phrase = NULL) {
- $this->response->set_status($status, $reason_phrase);
- }
-
-
- /**
- * Sets the content type of the controller's response.
- *
- * @param string the content type
- *
- * @return void
- */
- function set_content_type($type) {
- $this->response->add_header('Content-Type', $type);
- }
-
-
- /**
- * Exception handler called when the performance of an action raises an
- * exception.
- *
- * @param object the thrown exception
- *
- * @return object a response object
- */
- function rescue($exception) {
- return $this->dispatcher->trails_error($exception);
- }
-
- function respond_to($ext) {
- return $this->format === $ext;
- }
-}
-
-
-/**
- * The Inflector class is a namespace for inflections methods.
- *
- * @package trails
- *
- * @author mlunzena
- * @copyright (c) Authors
- * @version $Id: trails.php 7001 2008-04-04 11:20:27Z mlunzena $
- */
-
-class Trails_Inflector {
-
-
- /**
- * Returns a camelized string from a lower case and underscored string by
- * replacing slash with underscore and upper-casing each letter preceded
- * by an underscore. TODO
- *
- * @param string String to camelize.
- *
- * @return string Camelized string.
- */
- static function camelize($word) {
- $parts = explode('/', $word);
- foreach ($parts as $key => $part) {
- $parts[$key] = str_replace(' ', '',
- ucwords(str_replace('_', ' ', $part)));
- }
- return join('_', $parts);
- }
-
-
- /**
- * <MethodDescription>
- *
- * @param type <description>
- *
- * @return type <description>
- */
- static function underscore($word) {
- $parts = explode('_', $word);
- foreach ($parts as $key => $part) {
- $parts[$key] = preg_replace('/(?<=\w)([A-Z])/', '_\\1', $part);
- }
- return strtolower(join('/', $parts));
- }
-}
-
-
-/**
- * The flash provides a way to pass temporary objects between actions.
- * Anything you place in the flash will be exposed to the very next action and
- * then cleared out. This is a great way of doing notices and alerts, such as
- * a create action that sets
- * <tt>$flash->set('notice', "Successfully created")</tt>
- * before redirecting to a display action that can then expose the flash to its
- * template.
- *
- * @package trails
- *
- * @author mlunzena
- * @copyright (c) Authors
- * @version $Id: trails.php 7001 2008-04-04 11:20:27Z mlunzena $
- */
-
-class Trails_Flash implements ArrayAccess {
-
-
- /**
- * @ignore
- */
- public
- $flash = array(), $used = array();
-
-
- /**
- * <MethodDescription>
- *
- * @return type <description>
- */
- static function instance() {
-
- if (!isset($_SESSION)) {
- throw new Trails_SessionRequiredException();
- }
-
-
- if (!isset($_SESSION['trails_flash'])) {
- $_SESSION['trails_flash'] = new Trails_Flash();
- }
- return $_SESSION['trails_flash'];
- }
-
-
- #[ReturnTypeWillChange]
- function offsetExists($offset) {
- return isset($this->flash[$offset]);
- }
-
-
- #[ReturnTypeWillChange]
- function offsetGet($offset) {
- return $this->get($offset);
- }
-
-
- function offsetSet($offset, $value) {
- $this->set($offset, $value);
- }
-
-
- #[ReturnTypeWillChange]
- function offsetUnset($offset) {
- unset($this->flash[$offset], $this->used[$offset]);
- }
-
-
- /**
- * Used internally by the <tt>keep</tt> and <tt>discard</tt> methods
- * use() # marks the entire flash as used
- * use('msg') # marks the "msg" entry as used
- * use(null, false) # marks the entire flash as unused
- * # (keeps it around for one more action)
- * use('msg', false) # marks the "msg" entry as unused
- * # (keeps it around for one more action)
- *
- * @param mixed a key.
- * @param bool used flag.
- *
- * @return void
- */
- function _use($k = NULL, $v = TRUE) {
- if ($k) {
- $this->used[$k] = $v;
- }
- else {
- foreach ($this->used as $k => $value) {
- $this->_use($k, $v);
- }
- }
- }
-
-
- /**
- * Marks the entire flash or a single flash entry to be discarded by the end
- * of the current action.
- *
- * $flash->discard() # discards entire flash
- * # (it'll still be available for the
- * # current action)
- * $flash->discard('warning') # discard the "warning" entry
- * # (it'll still be available for the
- * # current action)
- *
- * @param mixed a key.
- *
- * @return void
- */
- function discard($k = NULL) {
- $this->_use($k);
- }
-
-
- /**
- * Returns the value to the specified key.
- *
- * @param mixed a key.
- *
- * @return mixed the key's value.
- */
- function &get($k) {
- $return = NULL;
- if (isset($this->flash[$k])) {
- $return =& $this->flash[$k];
- }
- return $return;
- }
-
-
- /**
- * Keeps either the entire current flash or a specific flash entry available
- * for the next action:
- *
- * $flash->keep() # keeps the entire flash
- * $flash->keep('notice') # keeps only the "notice" entry, the rest of
- * # the flash is discarded
- *
- * @param mixed a key.
- *
- * @return void
- */
- function keep($k = NULL) {
- $this->_use($k, FALSE);
- }
-
-
- /**
- * Sets a key's value.
- *
- * @param mixed a key.
- * @param mixed its value.
- *
- * @return void
- */
- function set($k, $v) {
- $this->keep($k);
- $this->flash[$k] = $v;
- }
-
-
- /**
- * Sets a key's value by reference.
- *
- * @param mixed a key.
- * @param mixed its value.
- *
- * @return void
- */
- function set_ref($k, &$v) {
- $this->keep($k);
- $this->flash[$k] =& $v;
- }
-
-
-
- /**
- * <MethodDescription>
- *
- * @return type <description>
- */
- function sweep() {
-
- # remove used values
- foreach (array_keys($this->flash) as $k) {
- if ($this->used[$k]) {
- unset($this->flash[$k], $this->used[$k]);
- } else {
- $this->_use($k);
- }
- }
-
- # cleanup if someone meddled with flash or used
- $fkeys = array_keys($this->flash);
- $ukeys = array_keys($this->used);
- foreach (array_diff($fkeys, $ukeys) as $k => $v) {
- unset($this->used[$k]);
- }
- }
-
-
- /**
- * <MethodDescription>
- *
- * @return type <description>
- */
- function __toString() {
- $values = array();
- foreach ($this->flash as $k => $v) {
- $values[] = sprintf("'%s': [%s, '%s']",
- $k, var_export($v, TRUE),
- $this->used[$k] ? "used" : "unused");
- }
- return "{" . join(", ", $values) . "}\n";
- }
-
-
- /**
- * <MethodDescription>
- *
- * @param type <description>
- *
- * @return type <description>
- */
- function __sleep() {
- $this->sweep();
- return array('flash', 'used');
- }
-
-
- /**
- * <MethodDescription>
- *
- * @param type <description>
- *
- * @return type <description>
- */
- function __wakeUp() {
- $this->discard();
- }
-}
-
-
-
-/**
- * TODO
- *
- * @package trails
- *
- * @author mlunzena
- * @copyright (c) Authors
- * @version $Id: trails.php 7001 2008-04-04 11:20:27Z mlunzena $
- */
-
-class Trails_Exception extends Exception {
-
- /**
- * <FieldDescription>
- *
- * @access private
- * @var <type>
- */
- public $headers;
-
-
- /**
- * @param int the status code to be set in the response
- * @param string a human readable presentation of the status code
- * @param array a hash of additional headers to be set in the response
- *
- * @return void
- */
- function __construct($status = 500, $reason = NULL, $headers = array()) {
- if ($reason === NULL) {
- $reason = Trails_Response::get_reason($status);
- }
- parent::__construct($reason, $status);
- $this->headers = $headers;
- }
-
-
- /**
- * <MethodDescription>
- *
- * @param type <description>
- *
- * @return type <description>
- */
- function __toString() {
- return "{$this->code} {$this->message}";
- }
-}
-
-
-class Trails_DoubleRenderError extends Trails_Exception {
-
- function __construct() {
- $message =
- "Render and/or redirect were called multiple times in this action. ".
- "Please note that you may only call render OR redirect, and at most ".
- "once per action.";
- parent::__construct(500, $message);
- }
-}
-
-
-class Trails_MissingFile extends Trails_Exception {
- function __construct($message) {
- parent::__construct(500, $message);
- }
-}
-
-
-class Trails_RoutingError extends Trails_Exception {
-
- function __construct($message) {
- parent::__construct(400, $message);
- }
-}
-
-
-class Trails_UnknownAction extends Trails_Exception {
-
- function __construct($message) {
- parent::__construct(404, $message);
- }
-}
-
-
-class Trails_UnknownController extends Trails_Exception {
-
- function __construct($message) {
- parent::__construct(404, $message);
- }
-}
-
-
-class Trails_SessionRequiredException extends Trails_Exception {
- function __construct() {
- $message = "Tried to access a non existing session.";
- parent::__construct(500, $message);
- }
-}