Compare commits

...

28 Commits

Author SHA1 Message Date
Simon Sessingø 9ccff91287 Merge pull request #410 from skipperbent/v4-development
Version 4.2.0.2
2018-04-06 19:45:51 +02:00
Simon Sessingø 8653bfa86f Development
- Fixed 403 not allowed exception is now thrown as NotFoundHttpException.
- Added REQUEST_TYPE_HEAD to Route class.
- Minor optimizations.
2018-04-06 19:44:30 +02:00
Simon Sessingø 13501b3f88 Merge pull request #408 from skipperbent/v4-development
Version 4.2.0.1
2018-04-06 18:04:01 +02:00
Simon Sessingø b8cfc4eb0b Fixed default parameter for all method allowed to by empty. 2018-04-06 18:01:49 +02:00
Simon Sessingø 5db4621831 Added methods for adding get, post and file parameters manually. 2018-04-06 18:00:59 +02:00
Simon Sessingø af641e3805 Merge pull request #406 from skipperbent/v4-development
Version 4.2.0.0
2018-04-06 17:27:42 +02:00
Simon Sessingø d38f81836d Development
- Added new Redirect method to SimpleRouter class.
- Changed method-names in InputHandler for better description.
- Fixed return-types for InputHandler for collections.
- Added unit-tests for InputHandler (get, post).
- Optimisations.
2018-04-06 17:20:00 +02:00
Simon Sessingø 89be00a72a Merge pull request #402 from skipperbent/v4-development
Version 4.1.0.0
2018-04-02 14:56:12 +02:00
Simon Sessingø 30a2ddeed9 Development
- Added new event when adding route.
- Added `prependUrl` method to `LoadableRoute` class.
- Added unit-test for add-route event.
- Updated documentation to reflect new changes.
2018-04-02 14:53:36 +02:00
Simon Sessingø 313833d78a Merge pull request #400 from skipperbent/v4-development
Fixed `exists` method in `InputHandler` returning incorrect value.
2018-04-01 04:28:06 +02:00
Simon Sessingø 17a7b28e82 Fixed exists method in InputHandler returning incorrect value. 2018-04-01 04:26:48 +02:00
Simon Sessingø e77d78e2f2 Merge pull request #399 from skipperbent/v4-development
Bugfixes and optimizations
2018-04-01 03:02:49 +02:00
Simon Sessingø 1dc88d23e1 Bugfixes and optimizations
- Fixed `hasParam` not working returning expected value in `Url` class.
- Chained the remaining methods in the `Url` class.
- Simplified `removeParam` method in `Url` class.
- Added new `removeParams` method to `Url` class for removal of multiple params.
2018-04-01 03:02:21 +02:00
Simon Sessingø bd033d9e13 Merge pull request #398 from skipperbent/v4-development
Version 4.0.0.11
2018-03-30 06:48:15 +02:00
Simon Sessingø 53f0b7d8e2 - Fixed getName method in LoadableRoute class can contain nullable value. 2018-03-30 06:47:27 +02:00
Simon Sessingø 5df0c12864 Updated helpers 2018-03-30 05:54:12 +02:00
Simon Sessingø 5bae3ff773 Merge pull request #397 from skipperbent/v4-development
Version 4.0.0.10
2018-03-30 05:38:27 +02:00
Simon Sessingø 833961ddc3 Fixed getError in InputFile returning string instead of int. 2018-03-30 05:37:04 +02:00
Simon Sessingø 36388f0f79 Merge pull request #396 from skipperbent/v4-development
Version 4.0.0.9
2018-03-30 05:23:54 +02:00
Simon Sessingø ce63e247b1 Bugfixes
- Fixed `Url` not outputting correct class when used in json_encode.
- Fixed `IInputItem` being too strict about strings which may be nullable.
2018-03-30 05:22:41 +02:00
Simon Sessingø d2d3938bf4 Merge pull request #395 from skipperbent/v4-development
Bugfixes
2018-03-29 23:48:32 +02:00
Simon Sessingø 80a42030ea Bugfixes
- Fixed getting specific input-value by request-method in InputHandler.
- Added .idea files
2018-03-29 23:47:27 +02:00
Simon Sessingø 1d6a2fafff Merge pull request #394 from skipperbent/v4-development
Removed namespace from groups
2018-03-29 23:28:47 +02:00
Simon Sessingø 17471a53cd Removed namespace from groups 2018-03-29 23:28:03 +02:00
Simon Sessingø e97e624cef Merge pull request #393 from skipperbent/v4-development
Bugfixes
2018-03-29 23:14:22 +02:00
Simon Sessingø da219d0b19 Bugfixes
- Fixed rewrite from ExceptionHandler sometimes not working correctly.
- Fixed default-namespace for Group and partial groups.
2018-03-29 23:13:56 +02:00
Simon Sessingø 30d2285699 Merge pull request #392 from skipperbent/v4-development
Bugfixes
2018-03-29 22:36:01 +02:00
Simon Sessingø a1dc4c5119 Bugfixes
- Updated `input` helper function.
- Update documentation to reflect v4 changes in `InputHandler` class.
2018-03-29 22:35:21 +02:00
31 changed files with 1755 additions and 285 deletions
-1
View File
@@ -1,4 +1,3 @@
.idea
composer.lock
vendor/
tests/tmp/*
+5
View File
@@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Simon" />
</state>
</component>
+12
View File
@@ -0,0 +1,12 @@
<component name="ProjectDictionaryState">
<dictionary name="simon">
<words>
<w>bootmanager</w>
<w>bootmanagers</w>
<w>csrf</w>
<w>middlewares</w>
<w>pecee</w>
<w>urldecode</w>
</words>
</dictionary>
</component>
+72
View File
@@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="MarkdownProjectSettings">
<PreviewSettings splitEditorLayout="SPLIT" splitEditorPreview="PREVIEW" useGrayscaleRendering="false" zoomFactor="1.25" maxImageWidth="0" showGitHubPageIfSynced="false" allowBrowsingInPreview="false" synchronizePreviewPosition="true" highlightPreviewType="NONE" highlightFadeOut="5" highlightOnTyping="true" synchronizeSourcePosition="true" verticallyAlignSourceAndPreviewSyncPosition="true" showSearchHighlightsInPreview="false" showSelectionInPreview="true">
<PanelProvider>
<provider providerId="com.vladsch.idea.multimarkdown.editor.swing.html.panel" providerName="Default - Swing" />
</PanelProvider>
</PreviewSettings>
<ParserSettings gitHubSyntaxChange="false">
<PegdownExtensions>
<option name="ABBREVIATIONS" value="false" />
<option name="ANCHORLINKS" value="true" />
<option name="ASIDE" value="false" />
<option name="ATXHEADERSPACE" value="true" />
<option name="AUTOLINKS" value="true" />
<option name="DEFINITIONS" value="false" />
<option name="DEFINITION_BREAK_DOUBLE_BLANK_LINE" value="false" />
<option name="FENCED_CODE_BLOCKS" value="true" />
<option name="FOOTNOTES" value="false" />
<option name="HARDWRAPS" value="false" />
<option name="HTML_DEEP_PARSER" value="false" />
<option name="INSERTED" value="false" />
<option name="QUOTES" value="false" />
<option name="RELAXEDHRULES" value="true" />
<option name="SMARTS" value="false" />
<option name="STRIKETHROUGH" value="true" />
<option name="SUBSCRIPT" value="false" />
<option name="SUPERSCRIPT" value="false" />
<option name="SUPPRESS_HTML_BLOCKS" value="false" />
<option name="SUPPRESS_INLINE_HTML" value="false" />
<option name="TABLES" value="true" />
<option name="TASKLISTITEMS" value="true" />
<option name="TOC" value="false" />
<option name="WIKILINKS" value="true" />
</PegdownExtensions>
<ParserOptions>
<option name="COMMONMARK_LISTS" value="true" />
<option name="DUMMY" value="false" />
<option name="EMOJI_SHORTCUTS" value="true" />
<option name="FLEXMARK_FRONT_MATTER" value="false" />
<option name="GFM_LOOSE_BLANK_LINE_AFTER_ITEM_PARA" value="false" />
<option name="GFM_TABLE_RENDERING" value="true" />
<option name="GITBOOK_URL_ENCODING" value="false" />
<option name="GITHUB_EMOJI_URL" value="false" />
<option name="GITHUB_LISTS" value="false" />
<option name="GITHUB_WIKI_LINKS" value="true" />
<option name="JEKYLL_FRONT_MATTER" value="false" />
<option name="SIM_TOC_BLANK_LINE_SPACER" value="true" />
</ParserOptions>
</ParserSettings>
<HtmlSettings headerTopEnabled="false" headerBottomEnabled="false" bodyTopEnabled="false" bodyBottomEnabled="false" embedUrlContent="false" addPageHeader="true">
<GeneratorProvider>
<provider providerId="com.vladsch.idea.multimarkdown.editor.swing.html.generator" providerName="Default Swing HTML Generator" />
</GeneratorProvider>
<headerTop />
<headerBottom />
<bodyTop />
<bodyBottom />
</HtmlSettings>
<CssSettings previewScheme="UI_SCHEME" cssUri="" isCssUriEnabled="false" isCssTextEnabled="false" isDynamicPageWidth="true">
<StylesheetProvider>
<provider providerId="com.vladsch.idea.multimarkdown.editor.swing.html.css" providerName="Default Swing Stylesheet" />
</StylesheetProvider>
<ScriptProviders />
<cssText />
</CssSettings>
<HtmlExportSettings updateOnSave="false" parentDir="$ProjectFileDir$" targetDir="$ProjectFileDir$" cssDir="" scriptDir="" plainHtml="false" imageDir="" copyLinkedImages="false" imageUniquifyType="0" targetExt="" useTargetExt="false" noCssNoScripts="false" linkToExportedHtml="true" exportOnSettingsChange="true" regenerateOnProjectOpen="false" />
<LinkMapSettings>
<textMaps />
</LinkMapSettings>
</component>
</project>
+3
View File
@@ -0,0 +1,3 @@
<component name="MarkdownNavigator.ProfileManager">
<settings default="" pdf-export="" />
</component>
+8
View File
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/simple-php-router.iml" filepath="$PROJECT_DIR$/.idea/simple-php-router.iml" />
</modules>
</component>
</project>
+14
View File
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="PhpTestFrameworkVersionCache">
<tools_cache>
<tool tool_name="PHPUnit">
<cache>
<versions>
<info id="Local" version="6.5.7" />
</versions>
</cache>
</tool>
</tools_cache>
</component>
</project>
Generated
+52
View File
@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="PhpIncludePathManager">
<include_path>
<path value="$PROJECT_DIR$/vendor/composer" />
<path value="$PROJECT_DIR$/vendor/phpdocumentor/reflection-common" />
<path value="$PROJECT_DIR$/vendor/phpunit/phpunit" />
<path value="$PROJECT_DIR$/vendor/phpdocumentor/type-resolver" />
<path value="$PROJECT_DIR$/vendor/phpdocumentor/reflection-docblock" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-code-coverage" />
<path value="$PROJECT_DIR$/vendor/webmozart/assert" />
<path value="$PROJECT_DIR$/vendor/phpunit/phpunit-mock-objects" />
<path value="$PROJECT_DIR$/vendor/sebastian/version" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-token-stream" />
<path value="$PROJECT_DIR$/vendor/sebastian/diff" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-text-template" />
<path value="$PROJECT_DIR$/vendor/sebastian/recursion-context" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-timer" />
<path value="$PROJECT_DIR$/vendor/sebastian/exporter" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-file-iterator" />
<path value="$PROJECT_DIR$/vendor/sebastian/environment" />
<path value="$PROJECT_DIR$/vendor/sebastian/comparator" />
<path value="$PROJECT_DIR$/vendor/sebastian/global-state" />
<path value="$PROJECT_DIR$/vendor/doctrine/instantiator" />
<path value="$PROJECT_DIR$/vendor/phpspec/prophecy" />
<path value="$PROJECT_DIR$/vendor/sebastian/resource-operations" />
<path value="$PROJECT_DIR$/vendor/sebastian/code-unit-reverse-lookup" />
<path value="$PROJECT_DIR$/vendor/sebastian/object-reflector" />
<path value="$PROJECT_DIR$/vendor/sebastian/object-enumerator" />
<path value="$PROJECT_DIR$/vendor/hamcrest/hamcrest-php" />
<path value="$PROJECT_DIR$/vendor/theseer/tokenizer" />
<path value="$PROJECT_DIR$/vendor/phar-io/version" />
<path value="$PROJECT_DIR$/vendor/phar-io/manifest" />
<path value="$PROJECT_DIR$/vendor/myclabs/deep-copy" />
<path value="$PROJECT_DIR$/vendor/mockery/mockery" />
<path value="$PROJECT_DIR$/vendor/jeremeamia/SuperClosure" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-util" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php56" />
<path value="$PROJECT_DIR$/vendor/php-di/invoker" />
<path value="$PROJECT_DIR$/vendor/php-di/phpdoc-reader" />
<path value="$PROJECT_DIR$/vendor/nikic/php-parser" />
<path value="$PROJECT_DIR$/vendor/psr/container" />
<path value="$PROJECT_DIR$/vendor/php-di/php-di" />
</include_path>
</component>
<component name="PhpProjectSharedConfiguration" php_language_level="7.1" />
<component name="PhpUnit">
<phpunit_settings>
<PhpUnitSettings load_method="CUSTOM_LOADER" configuration_file_path="$PROJECT_DIR$/phpunit.xml" custom_loader_path="$PROJECT_DIR$/vendor/autoload.php" phpunit_phar_path="" use_configuration_file="true" />
</phpunit_settings>
</component>
</project>
+49
View File
@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/Pecee" isTestSource="false" packagePrefix="Pecee\" />
<excludeFolder url="file://$MODULE_DIR$/vendor/composer" />
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/instantiator" />
<excludeFolder url="file://$MODULE_DIR$/vendor/hamcrest/hamcrest-php" />
<excludeFolder url="file://$MODULE_DIR$/vendor/jeremeamia/SuperClosure" />
<excludeFolder url="file://$MODULE_DIR$/vendor/mockery/mockery" />
<excludeFolder url="file://$MODULE_DIR$/vendor/myclabs/deep-copy" />
<excludeFolder url="file://$MODULE_DIR$/vendor/nikic/php-parser" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phar-io/manifest" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phar-io/version" />
<excludeFolder url="file://$MODULE_DIR$/vendor/php-di/invoker" />
<excludeFolder url="file://$MODULE_DIR$/vendor/php-di/php-di" />
<excludeFolder url="file://$MODULE_DIR$/vendor/php-di/phpdoc-reader" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpdocumentor/reflection-common" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpdocumentor/reflection-docblock" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpdocumentor/type-resolver" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpspec/prophecy" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-code-coverage" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-file-iterator" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-text-template" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-timer" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-token-stream" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/phpunit" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/phpunit-mock-objects" />
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/container" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/code-unit-reverse-lookup" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/comparator" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/diff" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/environment" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/exporter" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/global-state" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/object-enumerator" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/object-reflector" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/recursion-context" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/resource-operations" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/version" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php56" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-util" />
<excludeFolder url="file://$MODULE_DIR$/vendor/theseer/tokenizer" />
<excludeFolder url="file://$MODULE_DIR$/vendor/webmozart/assert" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
Generated
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
+973
View File
@@ -0,0 +1,973 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="BookmarkManager">
<bookmark url="file://$PROJECT_DIR$/src/Pecee/Http/Input/InputHandler.php" line="221" />
</component>
<component name="ChangeListManager">
<list default="true" id="a7058529-bdc4-40b4-a50d-c50564dc83f0" name="Default" comment="">
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/Pecee/Http/Input/InputHandler.php" beforeDir="false" afterPath="$PROJECT_DIR$/src/Pecee/Http/Input/InputHandler.php" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/Pecee/SimpleRouter/Route/Route.php" beforeDir="false" afterPath="$PROJECT_DIR$/src/Pecee/SimpleRouter/Route/Route.php" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/Pecee/SimpleRouter/Router.php" beforeDir="false" afterPath="$PROJECT_DIR$/src/Pecee/SimpleRouter/Router.php" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/Pecee/SimpleRouter/SimpleRouter.php" beforeDir="false" afterPath="$PROJECT_DIR$/src/Pecee/SimpleRouter/SimpleRouter.php" afterDir="false" />
</list>
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
<option name="TRACKING_ENABLED" value="true" />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="ComposerSettings" doNotAsk="true" synchronizationState="SYNCHRONIZE">
<pharConfigPath>$PROJECT_DIR$/composer.json</pharConfigPath>
</component>
<component name="FavoritesManager">
<favorites_list name="simple-php-router" />
</component>
<component name="FileEditorManager">
<leaf SIDE_TABS_SIZE_LIMIT_KEY="375">
<file leaf-file-name="SimpleRouter.php" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/src/Pecee/SimpleRouter/SimpleRouter.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-2294">
<caret line="100" column="16" selection-start-line="100" selection-start-column="8" selection-end-line="100" selection-end-column="16" />
<folding>
<element signature="e#302#319#0#PHP" expanded="true" />
</folding>
</state>
</provider>
</entry>
</file>
<file leaf-file-name="LoadableRoute.php" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/src/Pecee/SimpleRouter/Route/LoadableRoute.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="1420">
<caret line="71" column="33" selection-start-line="71" selection-start-column="27" selection-end-line="71" selection-end-column="33" />
<folding>
<element signature="e#44#82#0#PHP" expanded="true" />
</folding>
</state>
</provider>
</entry>
</file>
<file leaf-file-name="RouteResource.php" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/src/Pecee/SimpleRouter/Route/RouteResource.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="403">
<caret line="94" column="116" selection-start-line="94" selection-start-column="116" selection-end-line="94" selection-end-column="116" />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="RouteUrl.php" pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/src/Pecee/SimpleRouter/Route/RouteUrl.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="298">
<caret line="16" column="64" selection-start-line="16" selection-start-column="64" selection-end-line="16" selection-end-column="64" />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="IRoute.php" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/src/Pecee/SimpleRouter/Route/IRoute.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="300">
<caret line="16" column="20" selection-start-line="16" selection-start-column="20" selection-end-line="16" selection-end-column="20" />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="Route.php" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/src/Pecee/SimpleRouter/Route/Route.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="205">
<caret line="133" column="43" selection-start-line="133" selection-start-column="43" selection-end-line="133" selection-end-column="43" />
<folding>
<element signature="e#44#82#0#PHP" expanded="true" />
</folding>
</state>
</provider>
</entry>
</file>
<file leaf-file-name="InputHandler.php" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/src/Pecee/Http/Input/InputHandler.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="480">
<caret line="315" column="17" selection-start-line="315" selection-start-column="17" selection-end-line="315" selection-end-column="17" />
<folding>
<element signature="e#36#82#0#PHP" expanded="true" />
</folding>
</state>
</provider>
</entry>
</file>
<file leaf-file-name="Router.php" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/src/Pecee/SimpleRouter/Router.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="197">
<caret line="893" column="20" selection-start-line="893" selection-start-column="20" selection-end-line="893" selection-end-column="20" />
<folding>
<element signature="e#38#84#0#PHP" expanded="true" />
</folding>
</state>
</provider>
</entry>
</file>
</leaf>
</component>
<component name="FindInProjectRecents">
<findStrings>
<find>-&gt;setUrl</find>
<find>EVENT_LOAD</find>
<find>addRoute</find>
<find>$this-&gt;isPro</find>
<find>7.2</find>
<find>options</find>
<find>parent::set</find>
<find>parseParameters</find>
<find>stripos</find>
<find>setPrefix</find>
<find>var_dum</find>
<find>parse</find>
<find>getParams</find>
<find>setQuery</find>
<find>contains</find>
<find>matchRoute</find>
<find>-&gt;getValue</find>
<find>-&gt;find</find>
<find />
<find>Req</find>
<find>value(</find>
<find>file(</find>
<find>setUrl</find>
<find>TODO</find>
<find>input()-&gt;get</find>
<find />
<find>REQUEST_TYPE_</find>
<find />
<find>setDebugEnabled</find>
<find>debugEnabled</find>
</findStrings>
<dirStrings>
<dir>D:\Workspace\simple-php-router\src\Pecee\SimpleRouter\Route</dir>
<dir>D:\Workspace\simple-php-router\src</dir>
<dir>D:\Workspace\simple-php-router\tests\Pecee\SimpleRouter\Dummy</dir>
<dir>D:\Workspace\simple-php-router</dir>
<dir>E:\Workspace\simple-php-router\tests</dir>
<dir>E:\Workspace\simple-php-router\src\Pecee</dir>
<dir>E:\Workspace\simple-php-router\tests\Pecee\SimpleRouter</dir>
<dir>E:\Workspace\simple-php-router\src\Pecee\SimpleRouter\Route</dir>
<dir>E:\Workspace\simple-php-router\src\Pecee\SimpleRouter</dir>
<dir>E:\Workspace\simple-php-router\src</dir>
<dir>E:\Workspace\simple-php-router</dir>
</dirStrings>
</component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component>
<component name="IdeDocumentHistory">
<option name="CHANGED_PATHS">
<list>
<option value="$PROJECT_DIR$/tests/Pecee/SimpleRouter/Dummy/Handler/ExceptionHandlerFirst.php" />
<option value="$PROJECT_DIR$/tests/Pecee/SimpleRouter/Dummy/Handler/ExceptionHandlerSecond.php" />
<option value="$PROJECT_DIR$/tests/TestRouter.php" />
<option value="$PROJECT_DIR$/src/Pecee/SimpleRouter/Event/IEventArgument.php" />
<option value="$PROJECT_DIR$/src/Pecee/SimpleRouter/IRouterBootManager.php" />
<option value="$PROJECT_DIR$/tests/Pecee/SimpleRouter/Dummy/Security/SilentTokenProvider.php" />
<option value="$PROJECT_DIR$/tests/Pecee/SimpleRouter/Dummy/Managers/TestBootManager.php" />
<option value="$PROJECT_DIR$/src/Pecee/Http/Security/CookieTokenProvider.php" />
<option value="$PROJECT_DIR$/src/Pecee/Http/Security/ITokenProvider.php" />
<option value="$PROJECT_DIR$/src/Pecee/Http/Response.php" />
<option value="$PROJECT_DIR$/src/Pecee/SimpleRouter/Route/IRoute.php" />
<option value="$PROJECT_DIR$/src/Pecee/SimpleRouter/Route/RoutePartialGroup.php" />
<option value="$PROJECT_DIR$/src/Pecee/SimpleRouter/Handlers/IEventHandler.php" />
<option value="$PROJECT_DIR$/src/Pecee/SimpleRouter/Handlers/DebugEventHandler.php" />
<option value="$PROJECT_DIR$/src/Pecee/SimpleRouter/Event/EventArgument.php" />
<option value="$PROJECT_DIR$/src/Pecee/SimpleRouter/Handlers/ClassHandler.php" />
<option value="$PROJECT_DIR$/src/Pecee/SimpleRouter/Handlers/ClassLoader.php" />
<option value="$PROJECT_DIR$/src/Pecee/SimpleRouter/ClassLoader.php" />
<option value="$PROJECT_DIR$/src/Pecee/SimpleRouter/ClassLoader/DIContainerBuilder.php" />
<option value="$PROJECT_DIR$/src/Pecee/SimpleRouter/ClassLoader/Containers/DIContainerBuilder.php" />
<option value="$PROJECT_DIR$/src/Pecee/SimpleRouter/ClassLoader/ContainerInterface.php" />
<option value="$PROJECT_DIR$/src/Pecee/SimpleRouter/ClassLoader/IContainer.php" />
<option value="$PROJECT_DIR$/src/Pecee/SimpleRouter/ClassLoader/IClassLoader.php" />
<option value="$PROJECT_DIR$/src/Pecee/SimpleRouter/ClassLoader/ClassLoader.php" />
<option value="$PROJECT_DIR$/composer.json" />
<option value="$PROJECT_DIR$/tests/Pecee/SimpleRouter/GroupTest.php" />
<option value="$PROJECT_DIR$/tests/Pecee/SimpleRouter/RouterRouteTest.php" />
<option value="$PROJECT_DIR$/tests/Pecee/SimpleRouter/DependencyInjectionTest.php" />
<option value="$PROJECT_DIR$/.gitignore" />
<option value="$PROJECT_DIR$/src/Pecee/Http/Input/IInputItem.php" />
<option value="$PROJECT_DIR$/src/Pecee/Http/Input/InputItem.php" />
<option value="$PROJECT_DIR$/src/Pecee/Http/Input/InputFile.php" />
<option value="$PROJECT_DIR$/tests/Pecee/SimpleRouter/EventHandlerTest.php" />
<option value="$PROJECT_DIR$/src/Pecee/SimpleRouter/Handlers/EventHandler.php" />
<option value="$PROJECT_DIR$/src/Pecee/SimpleRouter/Route/RouteGroup.php" />
<option value="$PROJECT_DIR$/src/Pecee/SimpleRouter/Route/RouteResource.php" />
<option value="$PROJECT_DIR$/src/Pecee/Http/Url.php" />
<option value="$PROJECT_DIR$/tests/Pecee/SimpleRouter/RouterUrlTest.php" />
<option value="$PROJECT_DIR$/src/Pecee/Http/Middleware/BaseCsrfVerifier.php" />
<option value="$PROJECT_DIR$/README.md" />
<option value="$PROJECT_DIR$/src/Pecee/Http/Request.php" />
<option value="$PROJECT_DIR$/src/Pecee/SimpleRouter/Route/LoadableRoute.php" />
<option value="$PROJECT_DIR$/src/Pecee/SimpleRouter/Route/RouteController.php" />
<option value="$PROJECT_DIR$/src/Pecee/SimpleRouter/Route/ILoadableRoute.php" />
<option value="$PROJECT_DIR$/src/Pecee/SimpleRouter/Route/RouteUrl.php" />
<option value="$PROJECT_DIR$/helpers.php" />
<option value="$PROJECT_DIR$/tests/Pecee/SimpleRouter/InputHandlerTest.php" />
<option value="$PROJECT_DIR$/src/Pecee/Http/Input/InputHandler.php" />
<option value="$PROJECT_DIR$/src/Pecee/SimpleRouter/Route/Route.php" />
<option value="$PROJECT_DIR$/src/Pecee/SimpleRouter/Router.php" />
<option value="$PROJECT_DIR$/src/Pecee/SimpleRouter/SimpleRouter.php" />
</list>
</option>
</component>
<component name="JsBuildToolGruntFileManager" detection-done="true" sorting="DEFINITION_ORDER" />
<component name="JsBuildToolPackageJson" detection-done="true" sorting="DEFINITION_ORDER" />
<component name="JsFlowSettings">
<service-enabled>false</service-enabled>
<exe-path />
<annotation-enable>false</annotation-enable>
<other-services-enabled>false</other-services-enabled>
<auto-save>true</auto-save>
</component>
<component name="JsGulpfileManager">
<detection-done>true</detection-done>
<sorting>DEFINITION_ORDER</sorting>
</component>
<component name="PhpWorkspaceProjectConfiguration" interpreter_name="PHP 7.2">
<include_path>
<path value="$PROJECT_DIR$/vendor/composer" />
<path value="$PROJECT_DIR$/vendor/phpdocumentor/reflection-common" />
<path value="$PROJECT_DIR$/vendor/phpunit/phpunit" />
<path value="$PROJECT_DIR$/vendor/phpdocumentor/type-resolver" />
<path value="$PROJECT_DIR$/vendor/phpdocumentor/reflection-docblock" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-code-coverage" />
<path value="$PROJECT_DIR$/vendor/webmozart/assert" />
<path value="$PROJECT_DIR$/vendor/phpunit/phpunit-mock-objects" />
<path value="$PROJECT_DIR$/vendor/sebastian/version" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-token-stream" />
<path value="$PROJECT_DIR$/vendor/sebastian/diff" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-text-template" />
<path value="$PROJECT_DIR$/vendor/sebastian/recursion-context" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-timer" />
<path value="$PROJECT_DIR$/vendor/sebastian/exporter" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-file-iterator" />
<path value="$PROJECT_DIR$/vendor/sebastian/environment" />
<path value="$PROJECT_DIR$/vendor/sebastian/comparator" />
<path value="$PROJECT_DIR$/vendor/sebastian/global-state" />
<path value="$PROJECT_DIR$/vendor/doctrine/instantiator" />
<path value="$PROJECT_DIR$/vendor/phpspec/prophecy" />
<path value="$PROJECT_DIR$/vendor/sebastian/resource-operations" />
<path value="$PROJECT_DIR$/vendor/sebastian/code-unit-reverse-lookup" />
<path value="$PROJECT_DIR$/vendor/sebastian/object-reflector" />
<path value="$PROJECT_DIR$/vendor/sebastian/object-enumerator" />
<path value="$PROJECT_DIR$/vendor/hamcrest/hamcrest-php" />
<path value="$PROJECT_DIR$/vendor/theseer/tokenizer" />
<path value="$PROJECT_DIR$/vendor/phar-io/version" />
<path value="$PROJECT_DIR$/vendor/phar-io/manifest" />
<path value="$PROJECT_DIR$/vendor/myclabs/deep-copy" />
<path value="$PROJECT_DIR$/vendor/mockery/mockery" />
<path value="$PROJECT_DIR$/vendor/jeremeamia/SuperClosure" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-util" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php56" />
<path value="$PROJECT_DIR$/vendor/php-di/invoker" />
<path value="$PROJECT_DIR$/vendor/php-di/phpdoc-reader" />
<path value="$PROJECT_DIR$/vendor/nikic/php-parser" />
<path value="$PROJECT_DIR$/vendor/psr/container" />
<path value="$PROJECT_DIR$/vendor/php-di/php-di" />
</include_path>
</component>
<component name="ProjectFrameBounds" extendedState="6">
<option name="x" value="-10" />
<option name="width" value="2295" />
<option name="height" value="1235" />
</component>
<component name="ProjectLevelVcsManager">
<ConfirmationsSetting value="2" id="Add" />
</component>
<component name="ProjectView">
<navigator proportions="" version="1">
<foldersAlwaysOnTop value="true" />
</navigator>
<panes>
<pane id="ProjectPane">
<subPane>
<expand>
<path>
<item name="simple-php-router" type="b2602c69:ProjectViewProjectNode" />
<item name="simple-php-router" type="2a2b976b:PhpTreeStructureProvider$1" />
</path>
<path>
<item name="simple-php-router" type="b2602c69:ProjectViewProjectNode" />
<item name="simple-php-router" type="2a2b976b:PhpTreeStructureProvider$1" />
<item name="src" type="2a2b976b:PhpTreeStructureProvider$1" />
</path>
<path>
<item name="simple-php-router" type="b2602c69:ProjectViewProjectNode" />
<item name="simple-php-router" type="2a2b976b:PhpTreeStructureProvider$1" />
<item name="src" type="2a2b976b:PhpTreeStructureProvider$1" />
<item name="Pecee" type="2a2b976b:PhpTreeStructureProvider$1" />
</path>
<path>
<item name="simple-php-router" type="b2602c69:ProjectViewProjectNode" />
<item name="simple-php-router" type="2a2b976b:PhpTreeStructureProvider$1" />
<item name="src" type="2a2b976b:PhpTreeStructureProvider$1" />
<item name="Pecee" type="2a2b976b:PhpTreeStructureProvider$1" />
<item name="Http" type="2a2b976b:PhpTreeStructureProvider$1" />
</path>
<path>
<item name="simple-php-router" type="b2602c69:ProjectViewProjectNode" />
<item name="simple-php-router" type="2a2b976b:PhpTreeStructureProvider$1" />
<item name="src" type="2a2b976b:PhpTreeStructureProvider$1" />
<item name="Pecee" type="2a2b976b:PhpTreeStructureProvider$1" />
<item name="Http" type="2a2b976b:PhpTreeStructureProvider$1" />
<item name="Input" type="2a2b976b:PhpTreeStructureProvider$1" />
</path>
<path>
<item name="simple-php-router" type="b2602c69:ProjectViewProjectNode" />
<item name="simple-php-router" type="2a2b976b:PhpTreeStructureProvider$1" />
<item name="src" type="2a2b976b:PhpTreeStructureProvider$1" />
<item name="Pecee" type="2a2b976b:PhpTreeStructureProvider$1" />
<item name="SimpleRouter" type="2a2b976b:PhpTreeStructureProvider$1" />
</path>
<path>
<item name="simple-php-router" type="b2602c69:ProjectViewProjectNode" />
<item name="simple-php-router" type="2a2b976b:PhpTreeStructureProvider$1" />
<item name="src" type="2a2b976b:PhpTreeStructureProvider$1" />
<item name="Pecee" type="2a2b976b:PhpTreeStructureProvider$1" />
<item name="SimpleRouter" type="2a2b976b:PhpTreeStructureProvider$1" />
<item name="ClassLoader" type="2a2b976b:PhpTreeStructureProvider$1" />
</path>
<path>
<item name="simple-php-router" type="b2602c69:ProjectViewProjectNode" />
<item name="simple-php-router" type="2a2b976b:PhpTreeStructureProvider$1" />
<item name="src" type="2a2b976b:PhpTreeStructureProvider$1" />
<item name="Pecee" type="2a2b976b:PhpTreeStructureProvider$1" />
<item name="SimpleRouter" type="2a2b976b:PhpTreeStructureProvider$1" />
<item name="Handlers" type="2a2b976b:PhpTreeStructureProvider$1" />
</path>
<path>
<item name="simple-php-router" type="b2602c69:ProjectViewProjectNode" />
<item name="simple-php-router" type="2a2b976b:PhpTreeStructureProvider$1" />
<item name="src" type="2a2b976b:PhpTreeStructureProvider$1" />
<item name="Pecee" type="2a2b976b:PhpTreeStructureProvider$1" />
<item name="SimpleRouter" type="2a2b976b:PhpTreeStructureProvider$1" />
<item name="Route" type="2a2b976b:PhpTreeStructureProvider$1" />
</path>
<path>
<item name="simple-php-router" type="b2602c69:ProjectViewProjectNode" />
<item name="simple-php-router" type="2a2b976b:PhpTreeStructureProvider$1" />
<item name="tests" type="2a2b976b:PhpTreeStructureProvider$1" />
</path>
<path>
<item name="simple-php-router" type="b2602c69:ProjectViewProjectNode" />
<item name="simple-php-router" type="2a2b976b:PhpTreeStructureProvider$1" />
<item name="tests" type="2a2b976b:PhpTreeStructureProvider$1" />
<item name="Pecee" type="2a2b976b:PhpTreeStructureProvider$1" />
</path>
<path>
<item name="simple-php-router" type="b2602c69:ProjectViewProjectNode" />
<item name="simple-php-router" type="2a2b976b:PhpTreeStructureProvider$1" />
<item name="tests" type="2a2b976b:PhpTreeStructureProvider$1" />
<item name="Pecee" type="2a2b976b:PhpTreeStructureProvider$1" />
<item name="SimpleRouter" type="2a2b976b:PhpTreeStructureProvider$1" />
</path>
</expand>
<select />
</subPane>
</pane>
<pane id="Scope" />
</panes>
</component>
<component name="PropertiesComponent">
<property name="WebServerToolWindowFactoryState" value="false" />
<property name="last_opened_file_path" value="$PROJECT_DIR$/../ninjaimg-service" />
<property name="node.js.detected.package.eslint" value="true" />
<property name="node.js.detected.package.standard" value="true" />
<property name="node.js.path.for.package.eslint" value="project" />
<property name="node.js.path.for.package.standard" value="project" />
<property name="node.js.selected.package.eslint" value="" />
<property name="node.js.selected.package.standard" value="" />
<property name="run.code.analysis.last.selected.profile" value="pProject Default" />
<property name="settings.editor.selected.configurable" value="preferences.pluginManager" />
</component>
<component name="RecentsManager">
<key name="CopyFile.RECENT_KEYS">
<recent name="E:\Workspace\simple-php-router\tests\Pecee\SimpleRouter" />
<recent name="D:\Workspace\simple-php-router\tests" />
<recent name="D:\Workspace\simple-php-router" />
<recent name="D:\Workspace\simple-php-router\test" />
<recent name="D:\Workspace\simple-php-router\src\Pecee\SimpleRouter\Route" />
</key>
<key name="MoveFile.RECENT_KEYS">
<recent name="E:\Workspace\simple-php-router\src\Pecee\SimpleRouter\ClassLoader\Containers" />
<recent name="E:\Workspace\simple-php-router\src\Pecee\SimpleRouter\ClassLoader" />
<recent name="E:\Workspace\simple-php-router\src\Pecee\SimpleRouter" />
<recent name="E:\Workspace\simple-php-router\src\Pecee\SimpleRouter\Handler" />
<recent name="D:\Workspace\simple-php-router\tests" />
</key>
</component>
<component name="RunDashboard">
<option name="ruleStates">
<list>
<RuleState>
<option name="name" value="ConfigurationTypeDashboardGroupingRule" />
</RuleState>
<RuleState>
<option name="name" value="StatusDashboardGroupingRule" />
</RuleState>
</list>
</option>
</component>
<component name="RunManager" selected="PHPUnit.phpunit.xml">
<configuration name="EventHandlerTest" type="PHPUnitRunConfigurationType" factoryName="PHPUnit" temporary="true">
<TestRunner class="EventHandlerTest" file="$PROJECT_DIR$/tests/Pecee/SimpleRouter/EventHandlerTest.php" scope="Class" />
</configuration>
<configuration name="RouterUrlTest" type="PHPUnitRunConfigurationType" factoryName="PHPUnit" temporary="true">
<TestRunner class="RouterUrlTest" file="$PROJECT_DIR$/tests/Pecee/SimpleRouter/RouterUrlTest.php" scope="Class" />
</configuration>
<configuration name="phpunit.xml" type="PHPUnitRunConfigurationType" factoryName="PHPUnit" temporary="true">
<TestRunner configuration_file="$PROJECT_DIR$/phpunit.xml" scope="XML" use_alternative_configuration_file="true" />
</configuration>
<configuration name="tests" type="PHPUnitRunConfigurationType" factoryName="PHPUnit" temporary="true">
<TestRunner directory="$PROJECT_DIR$/tests" />
</configuration>
<configuration name="debug.php" type="PhpLocalRunConfigurationType" factoryName="PHP Console" temporary="true" path="$PROJECT_DIR$/tests/debug.php" />
<list>
<item itemvalue="PHPUnit.tests" />
<item itemvalue="PHPUnit.RouterUrlTest" />
<item itemvalue="PHPUnit.phpunit.xml" />
<item itemvalue="PHP Script.debug.php" />
<item itemvalue="PHPUnit.EventHandlerTest" />
</list>
<recent_temporary>
<list>
<item itemvalue="PHPUnit.phpunit.xml" />
<item itemvalue="PHP Script.debug.php" />
<item itemvalue="PHPUnit.EventHandlerTest" />
<item itemvalue="PHPUnit.tests" />
<item itemvalue="PHPUnit.RouterUrlTest" />
</list>
</recent_temporary>
</component>
<component name="SvnConfiguration">
<configuration />
</component>
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="a7058529-bdc4-40b4-a50d-c50564dc83f0" name="Default" comment="" />
<created>1502498236860</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1502498236860</updated>
<workItem from="1502498238130" duration="495000" />
<workItem from="1502589327470" duration="1325000" />
<workItem from="1502643621164" duration="1124000" />
<workItem from="1502665379176" duration="1624000" />
<workItem from="1502669212357" duration="163000" />
<workItem from="1503009054866" duration="109000" />
<workItem from="1503143546207" duration="965000" />
<workItem from="1503146420259" duration="656000" />
<workItem from="1503148077591" duration="1223000" />
<workItem from="1503157038418" duration="7000" />
<workItem from="1503418539960" duration="475000" />
<workItem from="1503499434906" duration="6410000" />
<workItem from="1503519096046" duration="649000" />
<workItem from="1503520310378" duration="280000" />
<workItem from="1503521737747" duration="856000" />
<workItem from="1503524427576" duration="2573000" />
<workItem from="1503536487719" duration="1589000" />
<workItem from="1503542802083" duration="820000" />
<workItem from="1503585789014" duration="820000" />
<workItem from="1504176764746" duration="658000" />
<workItem from="1504283976613" duration="694000" />
<workItem from="1504448385820" duration="7834000" />
<workItem from="1504459201935" duration="83000" />
<workItem from="1504459311471" duration="1376000" />
<workItem from="1504486369526" duration="451000" />
<workItem from="1504917061077" duration="1291000" />
<workItem from="1507375921398" duration="131000" />
<workItem from="1508785846050" duration="916000" />
<workItem from="1508786969551" duration="615000" />
<workItem from="1508787603350" duration="1889000" />
<workItem from="1509491007644" duration="14000" />
<workItem from="1509491033605" duration="6000" />
<workItem from="1510192196700" duration="11000" />
<workItem from="1510192217149" duration="152000" />
<workItem from="1510193026656" duration="140000" />
<workItem from="1511567082879" duration="3024000" />
<workItem from="1511629790083" duration="1115000" />
<workItem from="1511632906778" duration="6000" />
<workItem from="1511709768816" duration="954000" />
<workItem from="1511710733832" duration="10000" />
<workItem from="1511710754848" duration="6388000" />
<workItem from="1511717327384" duration="1762000" />
<workItem from="1511736112440" duration="855000" />
<workItem from="1511741616771" duration="3149000" />
<workItem from="1512583258866" duration="985000" />
<workItem from="1512706044104" duration="1603000" />
<workItem from="1521506970558" duration="7811000" />
<workItem from="1522072655826" duration="1072000" />
<workItem from="1522073747209" duration="63000" />
<workItem from="1522073847648" duration="23574000" />
<workItem from="1522309434425" duration="745000" />
<workItem from="1522310203119" duration="120000" />
<workItem from="1522310337826" duration="117000" />
<workItem from="1522310475899" duration="12840000" />
<workItem from="1522325810130" duration="30260000" />
<workItem from="1522360506281" duration="168000" />
<workItem from="1522378435862" duration="2772000" />
<workItem from="1522385007533" duration="313000" />
<workItem from="1522507670882" duration="309000" />
<workItem from="1522508007514" duration="2427000" />
<workItem from="1522530661439" duration="3502000" />
<workItem from="1522668357317" duration="4847000" />
<workItem from="1523014652739" duration="16240000" />
<workItem from="1523035686391" duration="174000" />
<workItem from="1523035884787" duration="578000" />
</task>
<servers />
</component>
<component name="TestHistory">
<history-entry file="phpunit_xml - 2018.04.06 at 16h 54m 36s.xml">
<configuration name="phpunit.xml" configurationId="PHPUnitRunConfigurationType" />
</history-entry>
<history-entry file="phpunit_xml - 2018.04.06 at 16h 55m 10s.xml">
<configuration name="phpunit.xml" configurationId="PHPUnitRunConfigurationType" />
</history-entry>
<history-entry file="phpunit_xml - 2018.04.06 at 16h 55m 25s.xml">
<configuration name="phpunit.xml" configurationId="PHPUnitRunConfigurationType" />
</history-entry>
<history-entry file="phpunit_xml - 2018.04.06 at 16h 57m 00s.xml">
<configuration name="phpunit.xml" configurationId="PHPUnitRunConfigurationType" />
</history-entry>
<history-entry file="phpunit_xml - 2018.04.06 at 16h 57m 10s.xml">
<configuration name="phpunit.xml" configurationId="PHPUnitRunConfigurationType" />
</history-entry>
<history-entry file="phpunit_xml - 2018.04.06 at 19h 04m 25s.xml">
<configuration name="phpunit.xml" configurationId="PHPUnitRunConfigurationType" />
</history-entry>
<history-entry file="phpunit_xml - 2018.04.06 at 19h 04m 32s.xml">
<configuration name="phpunit.xml" configurationId="PHPUnitRunConfigurationType" />
</history-entry>
<history-entry file="phpunit_xml - 2018.04.06 at 19h 35m 48s.xml">
<configuration name="phpunit.xml" configurationId="PHPUnitRunConfigurationType" />
</history-entry>
<history-entry file="phpunit_xml - 2018.04.06 at 19h 35m 53s.xml">
<configuration name="phpunit.xml" configurationId="PHPUnitRunConfigurationType" />
</history-entry>
<history-entry file="phpunit_xml - 2018.04.06 at 19h 35m 56s.xml">
<configuration name="phpunit.xml" configurationId="PHPUnitRunConfigurationType" />
</history-entry>
</component>
<component name="TimeTrackingManager">
<option name="totallyTimeSpent" value="166207000" />
</component>
<component name="TodoView">
<todo-panel id="selected-file">
<is-autoscroll-to-source value="true" />
</todo-panel>
<todo-panel id="all">
<are-packages-shown value="true" />
<is-autoscroll-to-source value="true" />
</todo-panel>
</component>
<component name="ToolWindowManager">
<frame x="-7" y="-7" width="2062" height="1126" extended-state="6" />
<editor active="true" />
<layout>
<window_info anchor="bottom" id="TODO" order="11" weight="0.32983023" />
<window_info anchor="bottom" id="Event Log" order="7" sideWeight="0.50919265" side_tool="true" weight="0.32902184" />
<window_info anchor="bottom" id="Database Changes" order="13" show_stripe_button="false" />
<window_info anchor="bottom" id="Run" order="2" sideWeight="0.49080735" visible="true" weight="0.3272727" />
<window_info anchor="bottom" id="Version Control" order="14" weight="0.32828283" />
<window_info anchor="bottom" id="Terminal" order="12" sideWeight="0.49680257" weight="0.28282827" />
<window_info active="true" content_ui="combo" id="Project" order="0" visible="true" weight="0.20879121" />
<window_info anchor="bottom" id="Docker" order="8" show_stripe_button="false" />
<window_info anchor="bottom" id="Inspection Results" order="15" weight="0.32828283" />
<window_info anchor="right" id="Database" order="3" />
<window_info anchor="bottom" id="Find" order="1" sideWeight="0.48880896" weight="0.3272727" />
<window_info id="Structure" order="1" side_tool="true" weight="0.24975026" />
<window_info anchor="bottom" id="Debug" order="3" weight="0.4" />
<window_info id="Favorites" order="2" side_tool="true" weight="0.32967034" />
<window_info anchor="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" />
<window_info anchor="bottom" id="Inspection" order="6" weight="0.4" />
<window_info anchor="bottom" id="PHP-CGI Server" order="10" />
<window_info anchor="right" id="Commander" order="0" weight="0.4" />
<window_info anchor="right" id="Ant Build" order="1" weight="0.25" />
<window_info anchor="bottom" id="REST Client" order="5" weight="0.32929292" />
<window_info anchor="bottom" id="Command Line Tools Console" order="9" weight="0.32928804" />
<window_info anchor="bottom" id="Cvs" order="4" weight="0.25" />
<window_info anchor="bottom" id="Message" order="0" />
</layout>
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="1" />
</component>
<component name="VcsContentAnnotationSettings">
<option name="myLimit" value="2678400000" />
</component>
<component name="XDebuggerManager">
<breakpoint-manager>
<option name="time" value="3" />
</breakpoint-manager>
</component>
<component name="editorHistoryManager">
<entry file="file://$PROJECT_DIR$/src/Pecee/SimpleRouter/Handlers/IExceptionHandler.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="48">
<caret line="2" column="10" lean-forward="true" selection-start-line="2" selection-start-column="10" selection-end-line="2" selection-end-column="28" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/Pecee/SimpleRouter/Handlers/DebugEventHandler.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="168">
<caret line="7" column="38" lean-forward="true" selection-start-line="7" selection-start-column="38" selection-end-line="7" selection-end-column="38" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/Pecee/SimpleRouter/Handlers/IEventHandler.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="552">
<caret line="23" column="20" selection-start-line="23" selection-start-column="20" selection-end-line="23" selection-end-column="20" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/Pecee/SimpleRouter/Event/EventArgument.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="54">
<caret line="45" column="26" lean-forward="true" selection-start-line="45" selection-start-column="26" selection-end-line="45" selection-end-column="26" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/Pecee/SimpleRouter/Handlers/CallbackExceptionHandler.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="48">
<caret line="2" selection-start-line="2" selection-end-line="2" selection-end-column="38" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/vendor/php-di/php-di/src/ContainerBuilder.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="210">
<caret line="121" column="21" selection-start-line="121" selection-start-column="21" selection-end-line="121" selection-end-column="21" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/Pecee/SimpleRouter/ClassLoader/Containers/IContainer.php" />
<entry file="file://$PROJECT_DIR$/src/Pecee/SimpleRouter/ClassLoader/Containers/DIContainerBuilder.php" />
<entry file="file://$PROJECT_DIR$/vendor/php-di/php-di/src/FactoryInterface.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="267">
<caret line="14" column="10" selection-start-line="14" selection-start-column="10" selection-end-line="14" selection-end-column="10" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/vendor/php-di/invoker/src/InvokerInterface.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="264">
<caret line="13" column="10" selection-start-line="13" selection-start-column="10" selection-end-line="13" selection-end-column="10" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/vendor/psr/container/src/ContainerInterface.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="192">
<caret line="10" column="10" selection-start-line="10" selection-start-column="10" selection-end-line="10" selection-end-column="10" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/Pecee/SimpleRouter/ClassLoader/IContainer.php" />
<entry file="file://$PROJECT_DIR$/vendor/mockery/mockery/library/Mockery/Container.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-3360">
<caret line="26" column="6" selection-start-line="26" selection-start-column="6" selection-end-line="26" selection-end-column="6" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/vendor/php-di/php-di/src/Container.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-21">
<caret line="266" column="20" selection-start-line="266" selection-start-column="20" selection-end-line="266" selection-end-column="20" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/Pecee/SimpleRouter/ClassLoader/IClassLoader.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="144">
<caret line="6" selection-start-line="6" selection-end-line="6" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/tmp/CompiledContainer.php" />
<entry file="file://$PROJECT_DIR$/composer.json">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="370">
<caret line="30" column="27" selection-start-line="30" selection-start-column="27" selection-end-line="30" selection-end-column="27" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/Pecee/SimpleRouter/ClassLoader/ClassLoader.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="384">
<caret line="34" column="47" selection-start-line="34" selection-start-column="47" selection-end-line="34" selection-end-column="47" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/tests/Pecee/SimpleRouter/GroupTest.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="258">
<caret line="21" column="8" selection-start-line="21" selection-start-column="8" selection-end-line="21" selection-end-column="8" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/tests/Pecee/SimpleRouter/RouterRouteTest.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="572">
<caret line="105" column="33" selection-start-line="105" selection-start-column="33" selection-end-line="105" selection-end-column="33" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/tests/Pecee/SimpleRouter/Dummy/Exception/ResponseException.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="192">
<caret line="8" column="8" selection-start-line="8" selection-start-column="8" selection-end-line="8" selection-end-column="8" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/tests/Pecee/SimpleRouter/DependencyInjectionTest.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="696">
<caret line="29" column="38" selection-start-line="29" selection-start-column="38" selection-end-line="29" selection-end-column="38" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/Pecee/Http/Input/IInputItem.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="380">
<caret line="19" column="40" selection-start-line="19" selection-start-column="40" selection-end-line="19" selection-end-column="40" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/Pecee/Http/Input/InputItem.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="80">
<caret line="4" column="37" selection-start-line="4" selection-start-column="37" selection-end-line="4" selection-end-column="37" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/Pecee/Http/Input/InputFile.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="180">
<caret line="9" column="17" selection-start-line="9" selection-start-column="17" selection-end-line="9" selection-end-column="17" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/Pecee/SimpleRouter/Handlers/EventHandler.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="540">
<caret line="28" selection-start-line="28" selection-end-line="28" />
<folding>
<element signature="e#47#90#0#PHP" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/tests/Pecee/SimpleRouter/EventHandlerTest.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="1860">
<caret line="94" column="24" selection-start-line="94" selection-start-column="24" selection-end-line="94" selection-end-column="24" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/Pecee/SimpleRouter/Route/IPartialGroupRoute.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="80">
<caret line="4" column="10" selection-start-line="4" selection-start-column="10" selection-end-line="4" selection-end-column="10" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/Pecee/Http/Response.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-2096" />
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/vendor/phpunit/phpunit/src/Framework/TestCase.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-687">
<caret line="100" column="15" selection-start-line="100" selection-start-column="15" selection-end-line="100" selection-end-column="15" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/Pecee/Http/Middleware/BaseCsrfVerifier.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="213">
<caret line="69" column="56" selection-start-line="69" selection-start-column="56" selection-end-line="69" selection-end-column="56" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/Pecee/Http/Request.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="286">
<caret line="88" column="24" lean-forward="true" selection-start-line="88" selection-start-column="24" selection-end-line="88" selection-end-column="35" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/tests/Pecee/SimpleRouter/MiddlewareTest.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="120">
<caret line="6" column="53" lean-forward="true" selection-start-line="6" selection-start-column="53" selection-end-line="6" selection-end-column="53" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/tests/Pecee/SimpleRouter/RouterUrlTest.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-34">
<caret line="85" selection-start-line="85" selection-end-line="85" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/vendor/phpunit/phpunit/src/Framework/Assert.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="333">
<caret line="1197" column="27" selection-start-line="1197" selection-start-column="27" selection-end-line="1197" selection-end-column="27" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/Pecee/Http/Url.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="86">
<caret line="25" column="20" selection-start-line="25" selection-start-column="20" selection-end-line="25" selection-end-column="20" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/Pecee/SimpleRouter/Route/RouteGroup.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="716">
<caret line="55" column="45" selection-start-line="55" selection-start-column="45" selection-end-line="55" selection-end-column="45" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/tests/TestRouter.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="240">
<caret line="12" selection-start-line="12" selection-end-line="12" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/Pecee/SimpleRouter/Route/RouteController.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="20">
<caret line="15" column="22" selection-start-line="15" selection-start-column="22" selection-end-line="15" selection-end-column="22" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/Pecee/SimpleRouter/Route/ILoadableRoute.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="640">
<caret line="32" column="36" selection-start-line="32" selection-start-column="30" selection-end-line="32" selection-end-column="36" />
<folding>
<element signature="e#44#67#0#PHP" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/helpers.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="960">
<caret line="51" column="59" selection-start-line="51" selection-start-column="59" selection-end-line="51" selection-end-column="59" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/README.md">
<provider selected="true" editor-type-id="split-provider[text-editor;markdown-preview-editor]">
<state split_layout="SPLIT">
<first_editor relative-caret-position="24400">
<caret line="1220" column="10" selection-start-line="1220" selection-start-column="10" selection-end-line="1220" selection-end-column="10" />
</first_editor>
<second_editor />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/tests/Pecee/SimpleRouter/InputHandlerTest.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="405">
<caret line="81" column="60" selection-start-line="81" selection-start-column="60" selection-end-line="81" selection-end-column="60" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/Pecee/Http/Input/InputHandler.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="480">
<caret line="315" column="17" selection-start-line="315" selection-start-column="17" selection-end-line="315" selection-end-column="17" />
<folding>
<element signature="e#36#82#0#PHP" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/Pecee/SimpleRouter/Router.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="197">
<caret line="893" column="20" selection-start-line="893" selection-start-column="20" selection-end-line="893" selection-end-column="20" />
<folding>
<element signature="e#38#84#0#PHP" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/Pecee/SimpleRouter/Route/Route.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="205">
<caret line="133" column="43" selection-start-line="133" selection-start-column="43" selection-end-line="133" selection-end-column="43" />
<folding>
<element signature="e#44#82#0#PHP" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/Pecee/SimpleRouter/SimpleRouter.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-2294">
<caret line="100" column="16" selection-start-line="100" selection-start-column="8" selection-end-line="100" selection-end-column="16" />
<folding>
<element signature="e#302#319#0#PHP" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/Pecee/SimpleRouter/Route/LoadableRoute.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="1420">
<caret line="71" column="33" selection-start-line="71" selection-start-column="27" selection-end-line="71" selection-end-column="33" />
<folding>
<element signature="e#44#82#0#PHP" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/Pecee/SimpleRouter/Route/RouteResource.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="403">
<caret line="94" column="116" selection-start-line="94" selection-start-column="116" selection-end-line="94" selection-end-column="116" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/Pecee/SimpleRouter/Route/IRoute.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="300">
<caret line="16" column="20" selection-start-line="16" selection-start-column="20" selection-end-line="16" selection-end-column="20" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/Pecee/SimpleRouter/Route/RouteUrl.php">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="298">
<caret line="16" column="64" selection-start-line="16" selection-start-column="64" selection-end-line="16" selection-end-column="64" />
</state>
</provider>
</entry>
</component>
</project>
+130 -76
View File
@@ -1,7 +1,16 @@
# simple-router
Simple, fast and yet powerful PHP router that is easy to get integrated and in any project.
Heavily inspired by the way Laravel handles routing, with both simplicity and expand-ability in mind.
Simple, fast and yet powerful PHP router that is easy to get integrated and in any project. Heavily inspired by the way Laravel handles routing, with both simplicity and expand-ability in mind.
With simple-router you can create a new project fast, without depending on a framework.
**It only takes a few lines of code to get started:**
```php
SimpleRouter::get('/', function() {
return 'Hello world';
});
```
### Support the project
@@ -84,6 +93,9 @@ You can donate any amount of your choice by [clicking here](https://www.paypal.c
- [Extending](#extending)
- [Help and support](#help-and-support)
- [Common issues and fixes](#common-issues-and-fixes)
- [Multiple routes matches? Which one has the priority?](#multiple-routes-matches-which-one-has-the-priority)
- [Parameters won't match or route not working with special characters](#parameters-wont-match-or-route-not-working-with-special-characters)
- [Using the router on sub-paths](#using-the-router-on-sub-paths)
- [Debugging](#debugging)
- [Creating unit-tests](#creating-unit-tests)
- [Debug information](#debug-information)
@@ -229,7 +241,9 @@ Simply create a new `web.config` file in your projects `public` directory and pa
#### Troubleshooting
If you do not have a `favicon.ico` file in your project, you can get a `NotFoundHttpException` (404 - not found).
To add `favicon.ico` to the IIS ignore-list, add the following line to the `<conditions>` group:
```
<add input="{REQUEST_FILENAME}" negate="true" pattern="favicon.ico" ignoreCase="true" />
```
@@ -239,7 +253,9 @@ You can also make one exception for files with some extensions:
<add input="{REQUEST_FILENAME}" pattern="\.ico|\.png|\.css|\.jpg" negate="true" ignoreCase="true" />
```
If you are using `$_SERVER['ORIG_PATH_INFO']`, you will get `\index.php\` as part of the returned value. For example:
If you are using `$_SERVER['ORIG_PATH_INFO']`, you will get `\index.php\` as part of the returned value.
**Example:**
```
/index.php/test/mypage.php
```
@@ -284,9 +300,9 @@ To implement the functions below, simply copy the code to a new file and require
<?php
use Pecee\SimpleRouter\SimpleRouter as Router;
use \Pecee\Http\Url;
use \Pecee\Http\Response;
use \Pecee\Http\Request;
use Pecee\Http\Url;
use Pecee\Http\Response;
use Pecee\Http\Request;
/**
* Get url for a route by using either name/alias, class or method name.
@@ -332,12 +348,12 @@ function request(): Request
* @param string|null $index Parameter index name
* @param string|null $defaultValue Default return value
* @param array ...$methods Default methods
* @return \Pecee\Http\Input\InputHandler|\Pecee\Http\Input\IInputItem|string
* @return \Pecee\Http\Input\InputHandler|array|string|null
*/
function input($index = null, $defaultValue = null, ...$methods)
{
if ($index !== null) {
return request()->getInputHandler()->get($index, ...$methods) ?? $defaultValue;
return request()->getInputHandler()->value($index, $defaultValue, ...$methods);
}
return request()->getInputHandler();
@@ -383,7 +399,7 @@ Below is a very basic example of setting up a route. First parameter is the url
```php
SimpleRouter::get('/', function() {
return 'Hello world';
return 'Hello world';
});
```
@@ -406,11 +422,11 @@ Sometimes you might need to create a route that accepts multiple HTTP-verbs. If
```php
SimpleRouter::match(['get', 'post'], '/', function() {
// ...
// ...
});
SimpleRouter::any('foo', function() {
// ...
// ...
});
```
@@ -418,7 +434,7 @@ We've created a simple method which matches `GET` and `POST` which is most commo
```php
SimpleRouter::form('foo', function() {
// ...
// ...
});
```
@@ -430,7 +446,7 @@ You'll properly wondering by know how you parse parameters from your urls. For e
```php
SimpleRouter::get('/user/{id}', function ($userId) {
return 'User with id: ' . $userId;
return 'User with id: ' . $userId;
});
```
@@ -438,7 +454,7 @@ You may define as many route parameters as required by your route:
```php
SimpleRouter::get('/posts/{post}/comments/{comment}', function ($postId, $commentId) {
// ...
// ...
});
```
@@ -450,11 +466,11 @@ Occasionally you may need to specify a route parameter, but make the presence of
```php
SimpleRouter::get('/user/{name?}', function ($name = null) {
return $name;
return $name;
});
SimpleRouter::get('/user/{name?}', function ($name = 'Simon') {
return $name;
return $name;
});
```
@@ -464,15 +480,21 @@ You may constrain the format of your route parameters using the where method on
```php
SimpleRouter::get('/user/{name}', function ($name) {
//
// ... do stuff
})->where('name', '[A-Za-z]+');
SimpleRouter::get('/user/{id}', function ($id) {
//
// ... do stuff
})->where('id', '[0-9]+');
SimpleRouter::get('/user/{id}/{name}', function ($id, $name) {
//
// ... do stuff
})->where(['id' => '[0-9]+', 'name' => '[a-z]+']);
```
@@ -1136,9 +1158,7 @@ In the example below, we check if the current url contains the `/api` part.
```php
if(url()->contains('/api')) {
// ... do stuff
}
```
@@ -1156,88 +1176,82 @@ For more available methods please check the `Pecee\Http\Url` class.
# Input & parameters
simple-router offers libraries and helpers that makes it easy to manage and manipulate input-parameters like `$_POST`, `$_GET` and `$_FILE`.
## Using the Input class to manage parameters
We've added the `Input` class to easy access and manage parameters from your Controller-classes.
You can use the `InputHandler` class to easily access and manage parameters from your request. The `InputHandler` class offers extended features such as copying/moving uploaded files directly on the object, getting file-extension, mime-type etc.
### Get single parameter value:
### Get single parameter value
If items is grouped in the html, it will return an array of items.
```input($index, $defaultValue, ...$methods);```
**Note:** `get` will automatically trim the value and ensure that it's not empty. If it's empty the `$defaultValue` will be returned.
To quickly get a value from a parameter, you can use the `input` helper function.
This will automatically trim the value and ensure that it's not empty. If it's empty the `$defaultValue` will be returned instead.
**Note:**
This function returns a `string` unless the parameters are grouped together, in that case it will return an `array` of values.
**Example:**
This example matches both POST and GET request-methods and if name is empty the default-value "Guest" will be returned.
```php
$value = input($index, $defaultValue, $methods);
$name = input('name', 'Guest', 'post', 'get');
```
### Get parameter object
Will return an instance of `InputItem` or `InputFile` depending on the type.
When dealing with file-uploads it can be useful to retrieve the raw parameter object.
You can use this in your html as it will render the value of the item.
However if you want to compare value in your if statements, you have to use
the `getValue` or use the `input()` instead.
**Search for object with default-value across multiple or specific request-methods:**
If items is grouped in the html, it will return an array of items.
**Note:** `getObject` will only return `$defaultValue` if the item doesn't exist. If you want `$defaultValue` to be returned if the item is empty, please use `input()` instead.
The example below will return an `InputItem` object if the parameter was found or return the `$defaultValue`. If parameters are grouped, it will return an array of `InputItem` objects.
```php
$object = input()->getObject($index, $defaultValue = null, $methods = null);
$object = input()->find($index, $defaultValue = null, ...$methods);
```
### Return specific GET parameter (where name is the name of your parameter):
**Getting specific `$_GET` parameter as `InputItem` object:**
The example below will return an `InputItem` object if the parameter was found or return the `$defaultValue`. If parameters are grouped, it will return an array of `InputItem` objects.
```php
# -- match any (default) --
$object = input()->get($index, $defaultValue = null);
```
/*
* This is the recommended way to go for normal usage
* as it will strip empty values, ensuring that
* $defaultValue is returned if the value is empty.
*/
**Getting specific `$_POST` parameter as `InputItem` object:**
$id = input()->getValue($index, $defaultValue, $method);
The example below will return an `InputItem` object if the parameter was found or return the `$defaultValue`. If parameters are grouped, it will return an array of `InputItem` objects.
# -- shortcut to above --
```php
$object = input()->post($index, $defaultValue = null);
```
$id = input($index, $defaultValue, $method);
**Getting specific `$_FILE` parameter as `InputFile` object:**
# -- match specific --
The example below will return an `InputFile` object if the parameter was found or return the `$defaultValue`. If parameters are grouped, it will return an array of `InputFile` objects.
$object = input($index, $defaultValue, 'get');
$object = input($index, $defaultValue, 'post');
$object = input($index, $defaultValue, 'file');
# -- or --
$object = input()->findGet($index, $defaultValue);
$object = input()->findPost($index, $defaultValue);
$object = input()->findFile($index, $defaultValue);
# -- get the full object --
$object = input()->get($index, 'post', 'get');
```php
$object = input()->file($index, $defaultValue = null);
```
### Managing files
```php
/**
* In this small example we loop through a collection of files
* added on the page like this
* Loop through a collection of files uploaded from a form on the page like this
* <input type="file" name="images[]" />
*/
/* @var $image \Pecee\Http\Input\InputFile */
foreach(input('images', []) as $image)
foreach(input()->file('images', []) as $image)
{
if($image->getMime() === 'image/jpeg') {
if($image->getMime() === 'image/jpeg')
{
$destinationFilname = sprintf('%s.%s', uniqid(), $image->getExtension());
$image->move('/uploads/' . $destinationFilename);
$image->move(sprintf('/uploads/%s', $destinationFilename));
}
}
@@ -1246,10 +1260,10 @@ foreach(input('images', []) as $image)
### Get all parameters
```php
// Get all
# Get all
$values = input()->all();
// Only match certain keys
# Only match specific keys
$values = input()->all([
'company_name',
'user_id'
@@ -1263,6 +1277,7 @@ All object implements the `IInputItem` interface and will always contain these m
- `getValue()` - returns the value of the input.
`InputFile` has the same methods as above along with some other file-specific methods like:
- `getFilename` - get the filename.
- `getTmpName()` - get file temporary name.
- `getSize()` - get file size.
@@ -1270,16 +1285,9 @@ All object implements the `IInputItem` interface and will always contain these m
- `getContents()` - get file content.
- `getType()` - get mime-type for file.
- `getError()` - get file upload error.
- `hasError()` - returns `bool` if an error occurred while uploading (if getError is not 0).
- `hasError()` - returns `bool` if an error occurred while uploading (if `getError` is not 0).
- `toArray()` - returns raw array
Below example requires you to have the helper functions added. Please refer to the helper functions section in the documentation.
```php
/* Get parameter site_id or default-value 2 from either post-value or query-string */
$siteId = input('site_id', 2, ['post', 'get']);
```
---
# Events
@@ -1298,6 +1306,7 @@ All event callbacks will retrieve a `EventArgument` object as parameter. This ob
| `EVENT_ALL` | - | Fires when a event is triggered. |
| `EVENT_INIT` | - | Fires when router is initializing and before routes are loaded. |
| `EVENT_LOAD` | `loadedRoutes` | Fires when all routes has been loaded and rendered, just before the output is returned. |
| `EVENT_ADD_ROUTE` | `route` | Fires when route is added to the router. |
| `EVENT_REWRITE` | `rewriteUrl`<br>`rewriteRoute` | Fires when a url-rewrite is and just before the routes are re-initialized. |
| `EVENT_BOOT` | `bootmanagers` | Fires when the router is booting. This happens just before boot-managers are rendered and before any routes has been loaded. |
| `EVENT_RENDER_BOOTMANAGER` | `bootmanagers`<br>`bootmanager` | Fires before a boot-manager is rendered. |
@@ -1561,6 +1570,51 @@ This section will go into details on how to debug the router and answer some of
This section will go over common issues and how to resolve them.
### Parameters won't match or route not working with special characters
Often people experience this issue when one or more parameters contains special characters. The router uses a sparse regular-expression that matches letters from a-z along with numbers when matching parameters, to improve performance.
All other characters has to be defined via the `defaultParameterRegex` option on your route.
You can read more about adding your own custom regular expression for matching parameters by [clicking here](#custom-regex-for-matching-parameters).
### Multiple routes matches? Which one has the priority?
The router will match routes in the order they're added.
It's possible to render multiple routes.
If you want the router to stop when a route is matched, you simply return a value in your callback or stop the execution manually (using `response()->json()` etc.).
Any returned objects that implements the `__toString()` magic method will also prevent other routes from being rendered.
### Using the router on sub-paths
Using the library on a sub-path like `localhost/project/` is not officially supported, however it is possible to get it working quite easily.
Add an event that appends your sub-path when a new loadable route is added.
**Example:**
```php
// ... your routes.php file
if($isRunningLocally) {
$eventHandler = new EventHandler();
$eventHandler->register(EventHandler::EVENT_ADD_ROUTE, function (EventArgument $arg) use (&$status) {
if ($arg->route instanceof \Pecee\SimpleRouter\Route\LoadableRoute) {
$arg->route->prependUrl('/local-path');
}
});
TestRouter::addEventHandler($eventHandler);
}
```
## Debugging
This section will show you how to write unit-tests for the router, view useful debugging information and answer some of the frequently asked questions.
+5 -5
View File
@@ -1,9 +1,9 @@
<?php
use Pecee\SimpleRouter\SimpleRouter as Router;
use \Pecee\Http\Url;
use \Pecee\Http\Response;
use \Pecee\Http\Request;
use Pecee\Http\Url;
use Pecee\Http\Response;
use Pecee\Http\Request;
/**
* Get url for a route by using either name/alias, class or method name.
@@ -49,12 +49,12 @@ function request(): Request
* @param string|null $index Parameter index name
* @param string|null $defaultValue Default return value
* @param array ...$methods Default methods
* @return \Pecee\Http\Input\InputHandler|\Pecee\Http\Input\IInputItem|string
* @return \Pecee\Http\Input\InputHandler|array|string|null
*/
function input($index = null, $defaultValue = null, ...$methods)
{
if ($index !== null) {
return request()->getInputHandler()->get($index, ...$methods) ?? $defaultValue;
return request()->getInputHandler()->value($index, $defaultValue, ...$methods);
}
return request()->getInputHandler();
+3 -3
View File
@@ -9,14 +9,14 @@ interface IInputItem
public function setIndex(string $index): self;
public function getName(): string;
public function getName(): ?string;
public function setName(string $name): self;
public function getValue(): string;
public function getValue(): ?string;
public function setValue(string $value): self;
public function __toString();
public function __toString(): string;
}
+8 -8
View File
@@ -49,7 +49,7 @@ class InputFile implements IInputItem
return (new static($values['index']))
->setSize((int)$values['size'])
->setError($values['error'])
->setError((int)$values['error'])
->setType($values['type'])
->setTmpName($values['tmp_name'])
->setFilename($values['name']);
@@ -140,7 +140,7 @@ class InputFile implements IInputItem
*
* @return string
*/
public function getName(): string
public function getName(): ?string
{
return $this->name;
}
@@ -177,7 +177,7 @@ class InputFile implements IInputItem
*
* @return string mixed
*/
public function getFilename(): string
public function getFilename(): ?string
{
return $this->filename;
}
@@ -216,11 +216,11 @@ class InputFile implements IInputItem
/**
* Get upload-error code.
*
* @return string
* @return int
*/
public function getError(): string
public function getError(): int
{
return $this->errors;
return (int)$this->errors;
}
/**
@@ -256,12 +256,12 @@ class InputFile implements IInputItem
return $this;
}
public function __toString()
public function __toString(): string
{
return $this->getTmpName();
}
public function getValue(): string
public function getValue(): ?string
{
return $this->getFilename();
}
+132 -70
View File
@@ -10,17 +10,17 @@ class InputHandler
/**
* @var array
*/
public $get = [];
protected $get = [];
/**
* @var array
*/
public $post = [];
protected $post = [];
/**
* @var array
*/
public $file = [];
protected $file = [];
/**
* @var Request
@@ -46,7 +46,7 @@ class InputHandler
{
/* Parse get requests */
if (\count($_GET) !== 0) {
$this->get = $this->handleGetPost($_GET);
$this->get = $this->parseInputItem($_GET);
}
/* Parse post requests */
@@ -57,7 +57,7 @@ class InputHandler
}
if (\count($postVars) !== 0) {
$this->post = $this->handleGetPost($postVars);
$this->post = $this->parseInputItem($postVars);
}
/* Parse get requests */
@@ -87,7 +87,7 @@ class InputHandler
}
$keys = [$key];
$files = $this->rearrangeFiles($value['name'], $keys, $value);
$files = $this->rearrangeFile($value['name'], $keys, $value);
if (isset($list[$key]) === true) {
$list[$key][] = $files;
@@ -100,9 +100,16 @@ class InputHandler
return $list;
}
protected function rearrangeFiles(array $values, &$index, $original): array
/**
* Rearrange multi-dimensional file object created by PHP.
*
* @param array $values
* @param array $index
* @param array|null $original
* @return array
*/
protected function rearrangeFile(array $values, &$index, $original): array
{
$originalIndex = $index[0];
array_shift($index);
@@ -138,7 +145,7 @@ class InputHandler
$index[] = $key;
$files = $this->rearrangeFiles($value, $index, $original);
$files = $this->rearrangeFile($value, $index, $original);
if (isset($output[$key]) === true) {
$output[$key][] = $files;
@@ -151,7 +158,13 @@ class InputHandler
return $output;
}
protected function handleGetPost(array $array): array
/**
* Parse input item from array
*
* @param array $array
* @return array
*/
protected function parseInputItem(array $array): array
{
$list = [];
@@ -163,7 +176,7 @@ class InputHandler
continue;
}
$output = $this->handleGetPost($value);
$output = $this->parseInputItem($value);
$list[$key] = $output;
}
@@ -172,62 +185,26 @@ class InputHandler
}
/**
* Find post-value by index or return default value.
*
* @param string $index
* @param string|null $defaultValue
* @return InputItem|string
*/
public function findPost(string $index, ?string $defaultValue = null)
{
return $this->post[$index] ?? $defaultValue;
}
/**
* Find file by index or return default value.
*
* @param string $index
* @param string|null $defaultValue
* @return InputFile|string
*/
public function findFile(string $index, ?string $defaultValue = null)
{
return $this->file[$index] ?? $defaultValue;
}
/**
* Find parameter/query-string by index or return default value.
*
* @param string $index
* @param string|null $defaultValue
* @return InputItem|string
*/
public function findGet(string $index, ?string $defaultValue = null)
{
return $this->get[$index] ?? $defaultValue;
}
/**
* Get input object
* Find input object
*
* @param string $index
* @param array ...$methods
* @return IInputItem|null
* @return IInputItem|array|null
*/
public function get(string $index, ...$methods): ?IInputItem
public function find(string $index, ...$methods)
{
$element = null;
if (\count($methods) === 0 || \in_array('get', $methods, true) === true) {
$element = $this->findGet($index);
$element = $this->get($index);
}
if (($element === null && \count($methods) === 0) || (\count($methods) === 0 && \in_array('post', $methods, true) === true)) {
$element = $this->findPost($index);
if (($element === null && \count($methods) === 0) || (\count($methods) !== 0 && \in_array('post', $methods, true) === true)) {
$element = $this->post($index);
}
if (($element === null && \count($methods) === 0) || (\count($methods) === 0 && \in_array('file', $methods, true) === true)) {
$element = $this->findFile($index);
if (($element === null && \count($methods) === 0) || (\count($methods) !== 0 && \in_array('file', $methods, true) === true)) {
$element = $this->file($index);
}
return $element;
@@ -239,11 +216,24 @@ class InputHandler
* @param string $index
* @param string|null $defaultValue
* @param array ...$methods
* @return string
* @return string|array
*/
public function getValue(string $index, ?string $defaultValue = null, ...$methods): ?string
public function value(string $index, ?string $defaultValue = null, ...$methods)
{
$input = $this->get($index, ...$methods);
$input = $this->find($index, ...$methods);
$output = [];
/* Handle collection */
if (\is_array($input) === true) {
/* @var $item InputItem */
foreach ($input as $item) {
$output[] = $item->getValue();
}
return (\count($output) === 0) ? $defaultValue : $output;
}
return ($input === null || ($input !== null && trim($input->getValue()) === '')) ? $defaultValue : $input->getValue();
}
@@ -251,20 +241,56 @@ class InputHandler
* Check if a input-item exist
*
* @param string $index
* @param array ...$method
* @param array ...$methods
* @return bool
*/
public function exists(string $index, ...$method): bool
public function exists(string $index, ...$methods): bool
{
return $this->get($index, $method) !== null;
return $this->value($index, null, ...$methods) !== null;
}
/**
* Find post-value by index or return default value.
*
* @param string $index
* @param string|null $defaultValue
* @return InputItem|array|string|null
*/
public function post(string $index, ?string $defaultValue = null)
{
return $this->post[$index] ?? $defaultValue;
}
/**
* Find file by index or return default value.
*
* @param string $index
* @param string|null $defaultValue
* @return InputFile|array|string|null
*/
public function file(string $index, ?string $defaultValue = null)
{
return $this->file[$index] ?? $defaultValue;
}
/**
* Find parameter/query-string by index or return default value.
*
* @param string $index
* @param string|null $defaultValue
* @return InputItem|array|string|null
*/
public function get(string $index, ?string $defaultValue = null)
{
return $this->get[$index] ?? $defaultValue;
}
/**
* Get all get/post items
* @param array|null $filter Only take items in filter
* @param array $filter Only take items in filter
* @return array
*/
public function all(array $filter = null): array
public function all(array $filter = []): array
{
$output = $_GET;
@@ -273,18 +299,54 @@ class InputHandler
// Append POST data
$output += $_POST;
$contents = file_get_contents('php://input');
if (\in_array($this->request->getMethod(), ['put', 'patch', 'delete'], false) === true) {
// Append any PHP-input json
if (strpos(trim($contents), '{') === 0) {
$post = json_decode($contents, true);
if ($post !== false) {
$output += $post;
$contents = file_get_contents('php://input');
// Append any PHP-input json
if (strpos(trim($contents), '{') === 0) {
$post = json_decode($contents, true);
if ($post !== false) {
$output += $post;
}
}
}
}
return ($filter !== null) ? array_intersect_key($output, array_flip($filter)) : $output;
return (\count($filter) > 0) ? array_intersect_key($output, array_flip($filter)) : $output;
}
/**
* Add GET parameter
*
* @param string $key
* @param InputItem $item
*/
public function addGet(string $key, InputItem $item): void
{
$this->get[$key] = $item;
}
/**
* Add POST parameter
*
* @param string $key
* @param InputItem $item
*/
public function addPost(string $key, InputItem $item): void
{
$this->post[$key] = $item;
}
/**
* Add FILE parameter
*
* @param string $key
* @param InputFile $item
*/
public function addFile(string $key, InputFile $item): void
{
$this->file[$key] = $item;
}
}
+3 -3
View File
@@ -35,7 +35,7 @@ class InputItem implements IInputItem
/**
* @return string
*/
public function getName(): string
public function getName(): ?string
{
return $this->name;
}
@@ -55,7 +55,7 @@ class InputItem implements IInputItem
/**
* @return string
*/
public function getValue(): string
public function getValue(): ?string
{
return $this->value;
}
@@ -72,7 +72,7 @@ class InputItem implements IInputItem
return $this;
}
public function __toString()
public function __toString(): string
{
return (string)$this->value;
}
@@ -67,7 +67,7 @@ class BaseCsrfVerifier implements IMiddleware
if ($this->skip($request) === false && \in_array($request->getMethod(), ['post', 'put', 'delete'], true) === true) {
$token = $request->getInputHandler()->getValue(
$token = $request->getInputHandler()->value(
static::POST_KEY,
$request->getHeader(static::HEADER_KEY),
'post'
+2 -2
View File
@@ -86,7 +86,7 @@ class Request
$this->setUrl(new Url($this->getHeader('unencoded-url', $this->getHeader('request-uri'))));
$this->inputHandler = new InputHandler($this);
$this->method = strtolower($this->inputHandler->getValue('_method', $this->getHeader('request-method')));
$this->method = strtolower($this->inputHandler->value('_method', $this->getHeader('request-method')));
}
public function isSecure(): bool
@@ -279,7 +279,7 @@ class Request
*/
public function setMethod(string $method): void
{
$this->method = $method;
$this->method = strtolower($method);
}
/**
+56 -29
View File
@@ -4,7 +4,7 @@ namespace Pecee\Http;
use Pecee\Http\Exceptions\MalformedUrlException;
class Url
class Url implements \JsonSerializable
{
private $originalUrl;
@@ -14,7 +14,7 @@ class Url
private $username;
private $password;
private $path;
private $params;
private $params = [];
private $fragment;
/**
@@ -43,9 +43,7 @@ class Url
$this->fragment = $data['fragment'] ?? null;
if (isset($data['query']) === true) {
$params = [];
parse_str($data['query'], $params);
$this->setParams($params);
$this->setQueryString($data['query']);
}
}
}
@@ -240,6 +238,23 @@ class Url
return $this;
}
/**
* Set raw query-string parameters as string
*
* @param string $queryString
* @return static
*/
public function setQueryString(string $queryString): self
{
$params = [];
if(parse_str($queryString, $params) !== false) {
return $this->setParams($params);
}
return $this;
}
/**
* Get query-string params as string
*
@@ -314,25 +329,36 @@ class Url
*/
public function hasParam(string $name): bool
{
return \in_array($name, $this->getParams(), true);
return array_key_exists($name, $this->getParams());
}
/**
* Removes parameter from query-string
* Removes multiple parameters from the query-string
*
* @param array ...$names
* @return static
*/
public function removeParams(...$names): self
{
$params = array_diff_key($this->getParams(), array_flip($names));
$this->setParams($params);
return $this;
}
/**
* Removes parameter from the query-string
*
* @param string $name
* @return static
*/
public function removeParam(string $name): void
public function removeParam(string $name): self
{
if ($this->hasParam($name) === true) {
$params = $this->getParams();
$key = \array_search($name, $params, true);
$params = $this->getParams();
unset($params[$name]);
$this->setParams($params);
if ($key === true) {
unset($params[$key]);
$this->setParams($params);
}
}
return $this;
}
/**
@@ -345,18 +371,7 @@ class Url
*/
public function getParam(string $name, ?string $defaultValue = null): ?string
{
$output = null;
if ($this->hasParam($name) === true) {
$params = $this->getParams();
$key = \array_search($name, $params, true);
if ($key === true) {
$output = $params[$key];
}
}
return $output ?? $defaultValue;
return isset($this->getParams()[$name]) ?? $defaultValue;
}
/**
@@ -441,7 +456,19 @@ class Url
return $scheme . $user . $pass . $host . $port . $this->getRelativeUrl();
}
public function __toString()
/**
* Specify data which should be serialized to JSON
* @link http://php.net/manual/en/jsonserializable.jsonserialize.php
* @return mixed data which can be serialized by <b>json_encode</b>,
* which is a value of any type other than a resource.
* @since 5.4.0
*/
public function jsonSerialize(): string
{
return $this->getRelativeUrl();
}
public function __toString(): string
{
return $this->getRelativeUrl();
}
@@ -22,6 +22,11 @@ class EventHandler implements IEventHandler
*/
public const EVENT_LOAD = 'onLoad';
/**
* Fires when route is added to the router
*/
public const EVENT_ADD_ROUTE = 'onAddRoute';
/**
* Fires when a url-rewrite is and just before the routes are re-initialized.
*/
@@ -95,6 +100,7 @@ class EventHandler implements IEventHandler
self::EVENT_ALL,
self::EVENT_INIT,
self::EVENT_LOAD,
self::EVENT_ADD_ROUTE,
self::EVENT_REWRITE,
self::EVENT_BOOT,
self::EVENT_RENDER_BOOTMANAGER,
@@ -39,6 +39,13 @@ interface ILoadableRoute extends IRoute
*/
public function setUrl(string $url): self;
/**
* Prepend url
* @param string $url
* @return ILoadableRoute
*/
public function prependUrl(string $url): self;
/**
* Returns the provided name for the router.
*
+18 -13
View File
@@ -85,6 +85,17 @@ abstract class LoadableRoute extends Route implements ILoadableRoute
return $this;
}
/**
* Prepend url
*
* @param string $url
* @return ILoadableRoute
*/
public function prependUrl(string $url): ILoadableRoute
{
return $this->setUrl(rtrim($url, '/') . $this->url);
}
public function getUrl(): string
{
return $this->url;
@@ -109,9 +120,6 @@ abstract class LoadableRoute extends Route implements ILoadableRoute
$url = '//' . $group->getDomains()[0] . $url;
}
/* Contains parameters that aren't recognized and will be appended at the end of the url */
$unknownParams = [];
/* Create the param string - {parameter} */
$param1 = $this->paramModifiers[0] . '%s' . $this->paramModifiers[1];
@@ -131,7 +139,7 @@ abstract class LoadableRoute extends Route implements ILoadableRoute
$value = array_key_exists($param, $p) ? $p[$param] : $params[$param];
/* If parameter is specifically set to null - use the original-defined value */
if ($value === null && isset($this->originalParameters[$param])) {
if ($value === null && isset($this->originalParameters[$param]) === true) {
$value = $this->originalParameters[$param];
}
}
@@ -140,13 +148,12 @@ abstract class LoadableRoute extends Route implements ILoadableRoute
/* Add parameter to the correct position */
$url = str_ireplace([sprintf($param1, $param), sprintf($param2, $param)], $value, $url);
} else {
$unknownParams[$param] = $value;
/* Parameter aren't recognized and will be appended at the end of the url */
$url .= $value . '/';
}
}
$url = '/' . ltrim($url, '/') . implode('/', $unknownParams);
return rtrim($url, '/') . '/';
return rtrim('/' . ltrim($url, '/'), '/') . '/';
}
/**
@@ -154,7 +161,7 @@ abstract class LoadableRoute extends Route implements ILoadableRoute
*
* @return string
*/
public function getName(): string
public function getName(): ?string
{
return $this->name;
}
@@ -240,12 +247,10 @@ abstract class LoadableRoute extends Route implements ILoadableRoute
}
if (isset($values['prefix']) === true) {
$this->setUrl($values['prefix'] . $this->getUrl());
$this->prependUrl($values['prefix']);
}
parent::setSettings($values, $merge);
return $this;
return parent::setSettings($values, $merge);
}
}
+21 -16
View File
@@ -18,6 +18,7 @@ abstract class Route implements IRoute
public const REQUEST_TYPE_PATCH = 'patch';
public const REQUEST_TYPE_OPTIONS = 'options';
public const REQUEST_TYPE_DELETE = 'delete';
public const REQUEST_TYPE_HEAD = 'head';
public static $requestTypes = [
self::REQUEST_TYPE_GET,
@@ -26,6 +27,7 @@ abstract class Route implements IRoute
self::REQUEST_TYPE_PATCH,
self::REQUEST_TYPE_OPTIONS,
self::REQUEST_TYPE_DELETE,
self::REQUEST_TYPE_HEAD,
];
/**
@@ -76,7 +78,9 @@ abstract class Route implements IRoute
}
$router->debug('Parsing parameters');
$parameters = $this->getParameters();
$router->debug('Finished parsing parameters');
/* Filter parameters with null-value */
@@ -118,20 +122,25 @@ abstract class Route implements IRoute
protected function parseParameters($route, $url, $parameterRegex = null)
{
$regex = sprintf(static::PARAMETERS_REGEX_FORMAT, $this->paramModifiers[0], $this->paramOptionalSymbol, $this->paramModifiers[1]);
$parameters = [];
$regex = (strpos($route, $this->paramModifiers[0]) === false) ? null :
sprintf
(
static::PARAMETERS_REGEX_FORMAT,
$this->paramModifiers[0],
$this->paramOptionalSymbol,
$this->paramModifiers[1]
);
// Ensures that host names/domains will work with parameters
$url = '/' . ltrim($url, '/');
$urlRegex = '';
$parameters = [];
if ((bool)preg_match_all('/' . $regex . '/u', $route, $parameters) === false) {
if ($regex === null || (bool)preg_match_all('/' . $regex . '/u', $route, $parameters) === false) {
$urlRegex = preg_quote($route, '/');
} else {
$urlParts = preg_split('/((\-?\/?)\{[^}]+\})/', $route);
foreach ($urlParts as $key => $t) {
foreach (preg_split('/((\-?\/?)\{[^}]+\})/', $route) as $key => $t) {
$regex = '';
@@ -155,14 +164,11 @@ abstract class Route implements IRoute
$regex = sprintf('(?:\/|\-)%1$s(?P<%2$s>%3$s)%1$s', $parameters[2][$key], $name, $regex);
}
$urlParts[$key] = preg_quote($t, '/') . $regex;
$urlRegex .= preg_quote($t, '/') . $regex;
}
$urlRegex = implode('', $urlParts);
}
if ((bool)preg_match(sprintf($this->urlRegex, $urlRegex), $url, $matches) === false) {
if (trim($urlRegex) === '' || (bool)preg_match(sprintf($this->urlRegex, $urlRegex), $url, $matches) === false) {
return null;
}
@@ -172,7 +178,7 @@ abstract class Route implements IRoute
/* Only take matched parameters with name */
foreach ((array)$parameters[1] as $name) {
$values[$name] = (isset($matches[$name]) && $matches[$name] !== '') ? $matches[$name] : null;
$values[$name] = (isset($matches[$name]) === true && $matches[$name] !== '') ? $matches[$name] : null;
}
}
@@ -192,7 +198,7 @@ abstract class Route implements IRoute
return $this->callback;
}
return 'function_' . md5($this->callback);
return 'function:' . md5($this->callback);
}
/**
@@ -247,9 +253,8 @@ abstract class Route implements IRoute
$this->group = $group;
/* Add/merge parent settings with child */
$this->setSettings($group->toArray(), true);
return $this;
return $this->setSettings($group->toArray(), true);
}
/**
@@ -95,7 +95,7 @@ class RouteController extends LoadableRoute implements IControllerRoute
/* Match global regular-expression for route */
$regexMatch = $this->matchRegex($request, $url);
if ($regexMatch === false || (stripos($url, $this->url) !== 0 && strtolower($url) !== strtolower($this->url))) {
if ($regexMatch === false || (stripos($url, $this->url) !== 0 && strtoupper($url) !== strtoupper($this->url))) {
return false;
}
@@ -177,9 +177,7 @@ class RouteController extends LoadableRoute implements IControllerRoute
$this->names = $values['names'];
}
parent::setSettings($values, $merge);
return $this;
return parent::setSettings($values, $merge);
}
}
+1 -3
View File
@@ -173,9 +173,7 @@ class RouteGroup extends Route implements IGroupRoute
$this->name = $name;
}
parent::setSettings($values, $merge);
return $this;
return parent::setSettings($values, $merge);
}
/**
@@ -92,7 +92,7 @@ class RouteResource extends LoadableRoute implements IControllerRoute
/* Match global regular-expression for route */
$regexMatch = $this->matchRegex($request, $url);
if ($regexMatch === false || (stripos($url, $this->url) !== 0 && strtolower($url) !== strtolower($this->url))) {
if ($regexMatch === false || (stripos($url, $this->url) !== 0 && strtoupper($url) !== strtoupper($this->url))) {
return false;
}
@@ -224,9 +224,7 @@ class RouteResource extends LoadableRoute implements IControllerRoute
$this->methodNames = $values['methods'];
}
parent::setSettings($values, $merge);
return $this;
return parent::setSettings($values, $merge);
}
}
+19 -24
View File
@@ -151,18 +151,20 @@ class Router
*/
public function addRoute(IRoute $route): IRoute
{
$this->fireEvents(EventHandler::EVENT_ADD_ROUTE, [
'route' => $route,
]);
/*
* If a route is currently being processed, that means that the route being added are rendered from the parent
* routes callback, so we add them to the stack instead.
*/
if ($this->isProcessingRoute === true) {
$this->routeStack[] = $route;
return $route;
} else {
$this->routes[] = $route;
}
$this->routes[] = $route;
return $route;
}
@@ -410,7 +412,7 @@ class Router
if ($methodNotAllowed === true) {
$message = sprintf('Route "%s" or method "%s" not allowed.', $this->request->getUrl()->getPath(), $this->request->getMethod());
$this->handleException(new HttpException($message, 403));
$this->handleException(new NotFoundHttpException($message, 403));
}
if (\count($this->request->getLoadedRoutes()) === 0) {
@@ -455,7 +457,9 @@ class Router
}
if ($this->request->getRewriteUrl() !== $url) {
unset($this->processedRoutes[$key]);
$this->request->setHasPendingRewrite(false);
$this->fireEvents(EventHandler::EVENT_REWRITE, [
@@ -504,12 +508,12 @@ class Router
}
try {
$this->debug('Start rendering exception handler');
$handler->handleError($this->request, $e);
$this->debug('Finished rendering exception-handler');
if (isset($this->loadedExceptionHandlers[$key]) === false && $this->request->hasPendingRewrite() === true) {
$this->loadedExceptionHandlers[$key] = $handler;
$this->debug('Exception handler contains rewrite, reloading routes');
@@ -519,6 +523,10 @@ class Router
'rewriteRoute' => $this->request->getRewriteRoute(),
]);
if ($this->request->getRewriteRoute() !== null) {
$this->processedRoutes[] = $this->request->getRewriteRoute();
}
return $this->routeRequest();
}
@@ -558,7 +566,7 @@ class Router
}
/* Direct match to controller */
if ($route instanceof IControllerRoute && strtolower($route->getController()) === strtolower($name)) {
if ($route instanceof IControllerRoute && strtoupper($route->getController()) === strtoupper($name)) {
$this->debug('Found route "%s" by controller "%s"', $route->getUrl(), $name);
return $route;
@@ -638,11 +646,7 @@ class Router
}
/* Only merge $_GET when all parameters are null */
if ($name === null && $parameters === null && $getParams === null) {
$getParams = $_GET;
} else {
$getParams = (array)$getParams;
}
$getParams = ($name === null && $parameters === null && $getParams === null) ? $_GET : (array)$getParams;
/* Return current route if no options has been specified */
if ($name === null && $parameters === null) {
@@ -798,26 +802,20 @@ class Router
* Set csrf verifier class
*
* @param BaseCsrfVerifier $csrfVerifier
* @return static
*/
public function setCsrfVerifier(BaseCsrfVerifier $csrfVerifier): self
public function setCsrfVerifier(BaseCsrfVerifier $csrfVerifier): void
{
$this->csrfVerifier = $csrfVerifier;
return $this;
}
/**
* Set class loader
*
* @param IClassLoader $loader
* @return static
*/
public function setClassLoader(IClassLoader $loader)
public function setClassLoader(IClassLoader $loader): void
{
$this->classLoader = $loader;
return $this;
}
/**
@@ -834,13 +832,10 @@ class Router
* Register event handler
*
* @param IEventHandler $handler
* @return static
*/
public function addEventHandler(IEventHandler $handler): self
public function addEventHandler(IEventHandler $handler): void
{
$this->eventHandlers[] = $handler;
return $this;
}
/**
+21 -15
View File
@@ -74,8 +74,7 @@ class SimpleRouter
try {
ob_start();
static::router()->setDebugEnabled(true);
static::start();
static::router()->setDebugEnabled(true)->start();
$routerOutput = ob_get_contents();
ob_end_clean();
} catch (\Exception $e) {
@@ -160,6 +159,21 @@ class SimpleRouter
static::router()->addBootManager($bootManager);
}
/**
* Redirect to when route matches.
*
* @param string $where
* @param string $to
* @param int $httpCode
* @return IRoute
*/
public static function redirect($where, $to, $httpCode = 301): IRoute
{
return static::get($where, function () use ($to, $httpCode) {
static::response()->redirect($to, $httpCode);
});
}
/**
* Route the given url to your callback on GET request method.
*
@@ -337,9 +351,7 @@ class SimpleRouter
$route->setSettings($settings);
}
static::router()->addRoute($route);
return $route;
return static::router()->addRoute($route);
}
/**
@@ -359,9 +371,7 @@ class SimpleRouter
$route->setSettings($settings);
}
static::router()->addRoute($route);
return $route;
return static::router()->addRoute($route);
}
/**
@@ -381,9 +391,7 @@ class SimpleRouter
$route->setSettings($settings);
}
static::router()->addRoute($route);
return $route;
return static::router()->addRoute($route);
}
/**
@@ -403,9 +411,7 @@ class SimpleRouter
$route->setSettings($settings);
}
static::router()->addRoute($route);
return $route;
return static::router()->addRoute($route);
}
/**
@@ -447,7 +453,7 @@ class SimpleRouter
* @param array|null $getParams
* @return Url
*/
public static function getUrl(?string $name = null, $parameters = null, $getParams = null): Url
public static function getUrl(?string $name = null, $parameters = null, ?array $getParams = null): Url
{
try {
return static::router()->getUrl($name, $parameters, $getParams);
+28 -2
View File
@@ -6,8 +6,8 @@ require_once 'Dummy/Handler/ExceptionHandler.php';
require_once 'Dummy/Security/SilentTokenProvider.php';
require_once 'Dummy/Managers/TestBootManager.php';
use \Pecee\SimpleRouter\Handlers\EventHandler;
use \Pecee\SimpleRouter\Event\EventArgument;
use Pecee\SimpleRouter\Event\EventArgument;
use Pecee\SimpleRouter\Handlers\EventHandler;
class EventHandlerTest extends \PHPUnit\Framework\TestCase
{
@@ -78,4 +78,30 @@ class EventHandlerTest extends \PHPUnit\Framework\TestCase
$this->assertEquals(true, $status);
}
public function testPrefixEvent()
{
$eventHandler = new EventHandler();
$eventHandler->register(EventHandler::EVENT_ADD_ROUTE, function (EventArgument $arg) use (&$status) {
if ($arg->route instanceof \Pecee\SimpleRouter\Route\LoadableRoute) {
$arg->route->prependUrl('/local-path');
}
});
TestRouter::addEventHandler($eventHandler);
$status = false;
TestRouter::get('/', function () use (&$status) {
$status = true;
});
TestRouter::debug('/local-path');
$this->assertTrue($status);
}
}
+96 -6
View File
@@ -7,14 +7,104 @@ require_once 'Dummy/Handler/ExceptionHandler.php';
class InputHandlerTest extends \PHPUnit\Framework\TestCase
{
public function testGet()
{
$this->assertEquals(true, true);
}
public function testPost()
{
$this->assertEquals(true, true);
global $_POST;
$names = [
'Lester',
'Michael',
'Franklin',
'Trevor',
];
$day = 'monday';
$_POST = [
'names' => $names,
'day' => $day,
];
$router = TestRouter::router();
$router->reset();
$router->getRequest()->setMethod('post');
$handler = TestRouter::request()->getInputHandler();
$this->assertEquals($names, $handler->value('names'));
$this->assertEquals($names, $handler->all(['names'])['names']);
$this->assertEquals($day, $handler->value('day'));
$this->assertInstanceOf(\Pecee\Http\Input\InputItem::class, $handler->find('day'));
$this->assertInstanceOf(\Pecee\Http\Input\InputItem::class, $handler->post('day'));
// Check non-existing and wrong request-type
$this->assertEmpty($handler->all(['non-existing']));
$this->assertNull($handler->value('non-existing'));
$this->assertNull($handler->find('non-existing'));
$this->assertNull($handler->value('names', null, 'get'));
$this->assertNull($handler->find('names', 'get'));
$objects = $handler->find('names');
$this->assertCount(4, $objects);
/* @var $object \Pecee\Http\Input\InputItem */
foreach($objects as $i => $object) {
$this->assertInstanceOf(\Pecee\Http\Input\InputItem::class, $object);
$this->assertEquals($names[$i], $object->getValue());
}
$_POST = [];
}
public function testGet()
{
global $_GET;
$names = [
'Lester',
'Michael',
'Franklin',
'Trevor',
];
$day = 'monday';
$_GET = [
'names' => $names,
'day' => $day,
];
$router = TestRouter::router();
$router->reset();
$router->getRequest()->setMethod('get');
$handler = TestRouter::request()->getInputHandler();
$this->assertEquals($names, $handler->value('names'));
$this->assertEquals($names, $handler->all(['names'])['names']);
$this->assertEquals($day, $handler->value('day'));
$this->assertInstanceOf(\Pecee\Http\Input\InputItem::class, $handler->find('day'));
$this->assertInstanceOf(\Pecee\Http\Input\InputItem::class, $handler->get('day'));
// Check non-existing and wrong request-type
$this->assertEmpty($handler->all(['non-existing']));
$this->assertNull($handler->value('non-existing'));
$this->assertNull($handler->find('non-existing'));
$this->assertNull($handler->value('names', null, 'post'));
$this->assertNull($handler->find('names', 'post'));
$objects = $handler->find('names');
$this->assertCount(4, $objects);
/* @var $object \Pecee\Http\Input\InputItem */
foreach($objects as $i => $object) {
$this->assertInstanceOf(\Pecee\Http\Input\InputItem::class, $object);
$this->assertEquals($names[$i], $object->getValue());
}
$_GET = [];
}
public function testFile()