mirror of
https://github.com/skipperbent/simple-php-router.git
synced 2026-06-15 18:23:26 +03:00
@@ -1,22 +0,0 @@
|
||||
engines:
|
||||
phpmd:
|
||||
enabled: true
|
||||
checks:
|
||||
Design/TooManyPublicMethods:
|
||||
enabled: true
|
||||
Naming/ShortVariable:
|
||||
enabled: true
|
||||
CleanCode/StaticAccess:
|
||||
enabled: true
|
||||
Controversial/CamelCaseMethodName:
|
||||
enabled: true
|
||||
fixme:
|
||||
enabled: true
|
||||
duplication:
|
||||
enabled: true
|
||||
config:
|
||||
languages:
|
||||
- php:
|
||||
ratings:
|
||||
paths:
|
||||
- src/**
|
||||
59
.github/workflows/ci.yml
vendored
Normal file
59
.github/workflows/ci.yml
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
name: CI
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build-test:
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
env:
|
||||
PHP_EXTENSIONS: json
|
||||
PHP_INI_VALUES: assert.exception=1, zend.assertions=1
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os:
|
||||
- ubuntu-latest
|
||||
- windows-latest
|
||||
php-version:
|
||||
- 7.1
|
||||
- 7.4
|
||||
phpunit-version:
|
||||
- 7.5.20
|
||||
dependencies:
|
||||
- lowest
|
||||
- highest
|
||||
name: PHPUnit Tests
|
||||
steps:
|
||||
- name: Configure git to avoid issues with line endings
|
||||
if: matrix.os == 'windows-latest'
|
||||
run: git config --global core.autocrlf false
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php-version }}
|
||||
tools: composer:v5, phpunit:${{ matrix.phpunit-versions }}
|
||||
coverage: xdebug
|
||||
extensions: ${{ env.PHP_EXTENSIONS }}
|
||||
ini-values: ${{ env.PHP_INI_VALUES }}
|
||||
- name: Get composer cache directory
|
||||
id: composer-cache
|
||||
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
|
||||
- name: Cache dependencies
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ${{ steps.composer-cache.outputs.dir }}
|
||||
key: php${{ matrix.php-version }}-composer-${{ matrix.dependencies }}-${{ hashFiles('**/composer.json') }}
|
||||
restore-keys: |
|
||||
php${{ matrix.php-version }}-composer-${{ matrix.dependencies }}-
|
||||
- name: Install lowest dependencies with composer
|
||||
if: matrix.dependencies == 'lowest'
|
||||
run: composer update --no-ansi --no-interaction --no-progress --prefer-lowest
|
||||
- name: Install highest dependencies with composer
|
||||
if: matrix.dependencies == 'highest'
|
||||
run: composer update --no-ansi --no-interaction --no-progress
|
||||
- name: Run tests with phpunit
|
||||
run: composer test
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,3 +1,4 @@
|
||||
composer.lock
|
||||
vendor/
|
||||
tests/tmp/*
|
||||
.idea/
|
||||
.phpunit.result.cache
|
||||
5
.idea/codeStyles/codeStyleConfig.xml
generated
5
.idea/codeStyles/codeStyleConfig.xml
generated
@@ -1,5 +0,0 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<state>
|
||||
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Simon" />
|
||||
</state>
|
||||
</component>
|
||||
12
.idea/dictionaries/simon.xml
generated
12
.idea/dictionaries/simon.xml
generated
@@ -1,12 +0,0 @@
|
||||
<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>
|
||||
4
.idea/encodings.xml
generated
4
.idea/encodings.xml
generated
@@ -1,4 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding" addBOMForNewFiles="with NO BOM" />
|
||||
</project>
|
||||
72
.idea/markdown-navigator.xml
generated
72
.idea/markdown-navigator.xml
generated
@@ -1,72 +0,0 @@
|
||||
<?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
.idea/markdown-navigator/profiles_settings.xml
generated
3
.idea/markdown-navigator/profiles_settings.xml
generated
@@ -1,3 +0,0 @@
|
||||
<component name="MarkdownNavigator.ProfileManager">
|
||||
<settings default="" pdf-export="" />
|
||||
</component>
|
||||
8
.idea/modules.xml
generated
8
.idea/modules.xml
generated
@@ -1,8 +0,0 @@
|
||||
<?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
.idea/php-test-framework.xml
generated
14
.idea/php-test-framework.xml
generated
@@ -1,14 +0,0 @@
|
||||
<?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>
|
||||
53
.idea/php.xml
generated
53
.idea/php.xml
generated
@@ -1,53 +0,0 @@
|
||||
<?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/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" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/yaml" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php56" />
|
||||
</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>
|
||||
50
.idea/simple-php-router.iml
generated
50
.idea/simple-php-router.iml
generated
@@ -1,50 +0,0 @@
|
||||
<?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/symfony/yaml" />
|
||||
<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>
|
||||
6
.idea/vcs.xml
generated
6
.idea/vcs.xml
generated
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
939
.idea/workspace.xml
generated
939
.idea/workspace.xml
generated
@@ -1,939 +0,0 @@
|
||||
<?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 afterPath="$PROJECT_DIR$/.idea/encodings.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/php.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/php.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/Pecee/Http/Middleware/BaseCsrfVerifier.php" beforeDir="false" afterPath="$PROJECT_DIR$/src/Pecee/Http/Middleware/BaseCsrfVerifier.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" />
|
||||
</list>
|
||||
<option name="EXCLUDED_CONVERTED_TO_IGNORED" 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>
|
||||
<file 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="363">
|
||||
<caret line="19" column="36" selection-start-line="19" selection-start-column="36" selection-end-line="19" selection-end-column="36" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file 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="396">
|
||||
<caret line="190" column="12" selection-start-line="190" selection-start-column="12" selection-end-line="190" selection-end-column="12" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file 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="294">
|
||||
<caret line="32" column="7" selection-start-line="32" selection-start-column="7" selection-end-line="32" selection-end-column="7" />
|
||||
<folding>
|
||||
<element signature="e#36#82#0#PHP" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/src/Pecee/Http/Request.php">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="265">
|
||||
<caret line="87" column="24" selection-start-line="87" selection-start-column="24" selection-end-line="87" selection-end-column="24" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file 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="172">
|
||||
<caret line="94" column="49" selection-start-line="94" selection-start-column="49" selection-end-line="94" selection-end-column="49" />
|
||||
<folding>
|
||||
<element signature="e#44#82#0#PHP" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/src/Pecee/Http/Middleware/BaseCsrfVerifier.php">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="357">
|
||||
<caret line="20" column="7" selection-start-line="20" selection-start-column="7" selection-end-line="20" selection-end-column="7" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file pinned="false" current-in-tab="true">
|
||||
<entry file="file://$PROJECT_DIR$/.gitignore">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="42">
|
||||
<caret line="2" column="11" selection-start-line="2" selection-start-column="11" selection-end-line="2" selection-end-column="11" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/README.md">
|
||||
<provider selected="true" editor-type-id="split-provider[text-editor;MarkdownPreviewEditor]">
|
||||
<state split_layout="SPLIT">
|
||||
<first_editor relative-caret-position="206">
|
||||
<caret line="849" column="50" selection-start-line="849" selection-start-column="50" selection-end-line="849" selection-end-column="50" />
|
||||
</first_editor>
|
||||
<second_editor>
|
||||
<markdownNavigatorState />
|
||||
</second_editor>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file 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="168">
|
||||
<caret line="8" column="14" selection-start-line="8" selection-start-column="14" selection-end-line="8" selection-end-column="14" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
</leaf>
|
||||
</component>
|
||||
<component name="FindInProjectRecents">
|
||||
<findStrings>
|
||||
<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>->getValue</find>
|
||||
<find>->find</find>
|
||||
<find>function find</find>
|
||||
<find>Req</find>
|
||||
<find>value(</find>
|
||||
<find>file(</find>
|
||||
<find>setUrl</find>
|
||||
<find>TODO</find>
|
||||
<find>input()->get</find>
|
||||
<find>function get</find>
|
||||
<find>REQUEST_TYPE_</find>
|
||||
<find>or method</find>
|
||||
<find>setDebugEnabled</find>
|
||||
<find>debugEnabled</find>
|
||||
<find>optiona</find>
|
||||
<find>\/</find>
|
||||
<find>requirements</find>
|
||||
<find>ler = new I</find>
|
||||
<find>csrf_token</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/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$/tests/Pecee/SimpleRouter/GroupTest.php" />
|
||||
<option value="$PROJECT_DIR$/tests/Pecee/SimpleRouter/DependencyInjectionTest.php" />
|
||||
<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/Request.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$/tests/Pecee/SimpleRouter/RouterRouteTest.php" />
|
||||
<option value="$PROJECT_DIR$/src/Pecee/SimpleRouter/Route/LoadableRoute.php" />
|
||||
<option value="$PROJECT_DIR$/src/Pecee/Http/Security/CookieTokenProvider.php" />
|
||||
<option value="$PROJECT_DIR$/composer.json" />
|
||||
<option value="$PROJECT_DIR$/src/Pecee/SimpleRouter/SimpleRouter.php" />
|
||||
<option value="$PROJECT_DIR$/src/Pecee/SimpleRouter/Router.php" />
|
||||
<option value="$PROJECT_DIR$/src/Pecee/SimpleRouter/Route/Route.php" />
|
||||
<option value="$PROJECT_DIR$/README.md" />
|
||||
<option value="$PROJECT_DIR$/src/Pecee/Http/Middleware/BaseCsrfVerifier.php" />
|
||||
<option value="$PROJECT_DIR$/.gitignore" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<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="PhpWorkspaceProjectConfiguration" interpreter_name="PHP 7.1">
|
||||
<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/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" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/yaml" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php56" />
|
||||
</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="Scope" />
|
||||
<pane id="ProjectPane">
|
||||
<subPane>
|
||||
<expand>
|
||||
<path>
|
||||
<item name="simple-php-router" type="b2602c69:ProjectViewProjectNode" />
|
||||
<item name="simple-php-router" type="462c0819:PsiDirectoryNode" />
|
||||
</path>
|
||||
<path>
|
||||
<item name="simple-php-router" type="b2602c69:ProjectViewProjectNode" />
|
||||
<item name="simple-php-router" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="src" type="462c0819:PsiDirectoryNode" />
|
||||
</path>
|
||||
<path>
|
||||
<item name="simple-php-router" type="b2602c69:ProjectViewProjectNode" />
|
||||
<item name="simple-php-router" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="src" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="Pecee" type="462c0819:PsiDirectoryNode" />
|
||||
</path>
|
||||
<path>
|
||||
<item name="simple-php-router" type="b2602c69:ProjectViewProjectNode" />
|
||||
<item name="simple-php-router" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="src" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="Pecee" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="Http" type="462c0819:PsiDirectoryNode" />
|
||||
</path>
|
||||
<path>
|
||||
<item name="simple-php-router" type="b2602c69:ProjectViewProjectNode" />
|
||||
<item name="simple-php-router" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="src" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="Pecee" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="SimpleRouter" type="462c0819:PsiDirectoryNode" />
|
||||
</path>
|
||||
<path>
|
||||
<item name="simple-php-router" type="b2602c69:ProjectViewProjectNode" />
|
||||
<item name="simple-php-router" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="src" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="Pecee" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="SimpleRouter" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="Route" type="462c0819:PsiDirectoryNode" />
|
||||
</path>
|
||||
<path>
|
||||
<item name="simple-php-router" type="b2602c69:ProjectViewProjectNode" />
|
||||
<item name="simple-php-router" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="tests" type="462c0819:PsiDirectoryNode" />
|
||||
</path>
|
||||
<path>
|
||||
<item name="simple-php-router" type="b2602c69:ProjectViewProjectNode" />
|
||||
<item name="simple-php-router" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="tests" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="Pecee" type="462c0819:PsiDirectoryNode" />
|
||||
</path>
|
||||
<path>
|
||||
<item name="simple-php-router" type="b2602c69:ProjectViewProjectNode" />
|
||||
<item name="simple-php-router" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="tests" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="Pecee" type="462c0819:PsiDirectoryNode" />
|
||||
<item name="SimpleRouter" type="462c0819:PsiDirectoryNode" />
|
||||
</path>
|
||||
</expand>
|
||||
<select />
|
||||
</subPane>
|
||||
</pane>
|
||||
</panes>
|
||||
</component>
|
||||
<component name="PropertiesComponent">
|
||||
<property name="WebServerToolWindowFactoryState" value="false" />
|
||||
<property name="last_opened_file_path" value="$PROJECT_DIR$/../pecee-pixie" />
|
||||
<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.tests">
|
||||
<configuration name="EventHandlerTest" type="PHPUnitRunConfigurationType" factoryName="PHPUnit" temporary="true">
|
||||
<TestRunner class="EventHandlerTest" file="$PROJECT_DIR$/tests/Pecee/SimpleRouter/EventHandlerTest.php" scope="Class" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<configuration name="RouterRouteTest" type="PHPUnitRunConfigurationType" factoryName="PHPUnit" temporary="true">
|
||||
<TestRunner class="RouterRouteTest" file="$PROJECT_DIR$/tests/Pecee/SimpleRouter/RouterRouteTest.php" scope="Class" />
|
||||
<method v="2" />
|
||||
</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" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<configuration name="tests" type="PHPUnitRunConfigurationType" factoryName="PHPUnit" temporary="true">
|
||||
<TestRunner directory="$PROJECT_DIR$/tests" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<configuration name="debug.php" type="PhpLocalRunConfigurationType" factoryName="PHP Console" temporary="true" path="$PROJECT_DIR$/tests/debug.php">
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<list>
|
||||
<item itemvalue="PHP Script.debug.php" />
|
||||
<item itemvalue="PHPUnit.tests" />
|
||||
<item itemvalue="PHPUnit.phpunit.xml" />
|
||||
<item itemvalue="PHPUnit.EventHandlerTest" />
|
||||
<item itemvalue="PHPUnit.RouterRouteTest" />
|
||||
</list>
|
||||
<recent_temporary>
|
||||
<list>
|
||||
<item itemvalue="PHPUnit.tests" />
|
||||
<item itemvalue="PHPUnit.RouterRouteTest" />
|
||||
<item itemvalue="PHPUnit.phpunit.xml" />
|
||||
<item itemvalue="PHP Script.debug.php" />
|
||||
<item itemvalue="PHPUnit.EventHandlerTest" />
|
||||
</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="1022000" />
|
||||
<workItem from="1523038029219" duration="56000" />
|
||||
<workItem from="1535121332253" duration="2346000" />
|
||||
<workItem from="1535671881115" duration="506000" />
|
||||
<workItem from="1535806837271" duration="204000" />
|
||||
<workItem from="1543101575756" duration="1207000" />
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
<component name="TestHistory">
|
||||
<history-entry file="tests - 2018.08.24 at 17h 12m 28s.xml">
|
||||
<configuration name="tests" configurationId="PHPUnitRunConfigurationType" />
|
||||
</history-entry>
|
||||
<history-entry file="tests - 2018.08.24 at 17h 12m 29s.xml">
|
||||
<configuration name="tests" configurationId="PHPUnitRunConfigurationType" />
|
||||
</history-entry>
|
||||
<history-entry file="tests - 2018.08.24 at 17h 12m 31s.xml">
|
||||
<configuration name="tests" configurationId="PHPUnitRunConfigurationType" />
|
||||
</history-entry>
|
||||
<history-entry file="tests - 2018.08.24 at 17h 12m 32s.xml">
|
||||
<configuration name="tests" configurationId="PHPUnitRunConfigurationType" />
|
||||
</history-entry>
|
||||
<history-entry file="tests - 2018.08.24 at 17h 12m 33s.xml">
|
||||
<configuration name="tests" configurationId="PHPUnitRunConfigurationType" />
|
||||
</history-entry>
|
||||
<history-entry file="tests - 2018.08.24 at 17h 13m 32s.xml">
|
||||
<configuration name="tests" configurationId="PHPUnitRunConfigurationType" />
|
||||
</history-entry>
|
||||
<history-entry file="tests - 2018.08.31 at 01h 36m 24s.xml">
|
||||
<configuration name="tests" configurationId="PHPUnitRunConfigurationType" />
|
||||
</history-entry>
|
||||
<history-entry file="tests - 2018.08.31 at 01h 36m 28s.xml">
|
||||
<configuration name="tests" configurationId="PHPUnitRunConfigurationType" />
|
||||
</history-entry>
|
||||
<history-entry file="tests - 2018.08.31 at 01h 36m 29s.xml">
|
||||
<configuration name="tests" configurationId="PHPUnitRunConfigurationType" />
|
||||
</history-entry>
|
||||
<history-entry file="tests - 2018.11.25 at 00h 37m 03s.xml">
|
||||
<configuration name="tests" configurationId="PHPUnitRunConfigurationType" />
|
||||
</history-entry>
|
||||
</component>
|
||||
<component name="TimeTrackingManager">
|
||||
<option name="totallyTimeSpent" value="171000000" />
|
||||
</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 active="true" content_ui="combo" id="Project" order="0" visible="true" weight="0.21878122" />
|
||||
<window_info id="Structure" order="1" weight="0.24975026" />
|
||||
<window_info id="Favorites" order="2" weight="0.32967034" />
|
||||
<window_info anchor="bottom" id="Message" order="0" />
|
||||
<window_info anchor="bottom" id="Find" order="1" sideWeight="0.48880896" weight="0.32696176" />
|
||||
<window_info anchor="bottom" id="Terminal" order="2" sideWeight="0.4935065" visible="true" weight="0.28169015" />
|
||||
<window_info anchor="bottom" id="Run" order="3" sideWeight="0.49080735" weight="0.32595575" />
|
||||
<window_info anchor="bottom" id="Debug" order="4" weight="0.4" />
|
||||
<window_info anchor="bottom" id="Cvs" order="5" weight="0.25" />
|
||||
<window_info anchor="bottom" id="REST Client" order="6" weight="0.32929292" />
|
||||
<window_info anchor="bottom" id="Inspection" order="7" weight="0.4" />
|
||||
<window_info anchor="bottom" id="Docker" order="8" show_stripe_button="false" />
|
||||
<window_info anchor="bottom" id="Command Line Tools Console" order="9" weight="0.32928804" />
|
||||
<window_info anchor="bottom" id="PHP-CGI Server" order="10" />
|
||||
<window_info anchor="bottom" id="TODO" order="11" weight="0.32897383" />
|
||||
<window_info anchor="bottom" id="Database Changes" order="12" show_stripe_button="false" />
|
||||
<window_info anchor="bottom" id="Version Control" order="13" weight="0.3279678" />
|
||||
<window_info anchor="bottom" id="Inspection Results" order="14" weight="0.32696176" />
|
||||
<window_info anchor="bottom" id="Event Log" order="15" sideWeight="0.5064935" weight="0.28169015" />
|
||||
<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="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" />
|
||||
<window_info anchor="right" id="Database" order="3" />
|
||||
</layout>
|
||||
</component>
|
||||
<component name="TypeScriptGeneratedFilesManager">
|
||||
<option name="version" value="1" />
|
||||
</component>
|
||||
<component name="editorHistoryManager">
|
||||
<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$/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/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" />
|
||||
</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$/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="1640">
|
||||
<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" />
|
||||
</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$/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/SimpleRouter/Route/RouteUrl.php">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="120">
|
||||
<caret line="6" column="28" selection-start-line="6" selection-start-column="28" selection-end-line="6" selection-end-column="28" />
|
||||
</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="280">
|
||||
<caret line="14" lean-forward="true" selection-start-line="14" selection-end-line="14" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/Pecee/Http/Security/CookieTokenProvider.php">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="206">
|
||||
<caret line="65" column="87" selection-start-line="65" selection-start-column="87" selection-end-line="65" selection-end-column="87" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/composer.json">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="538">
|
||||
<caret line="30" column="20" selection-start-line="30" selection-start-column="20" selection-end-line="30" selection-end-column="20" />
|
||||
</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="243">
|
||||
<caret line="263" column="48" lean-forward="true" selection-start-line="263" selection-start-column="48" selection-end-line="263" selection-end-column="48" />
|
||||
</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="120">
|
||||
<caret line="9" column="38" selection-start-line="9" selection-start-column="38" selection-end-line="9" selection-end-column="38" />
|
||||
</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="363">
|
||||
<caret line="19" column="36" selection-start-line="19" selection-start-column="36" selection-end-line="19" selection-end-column="36" />
|
||||
</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="168">
|
||||
<caret line="8" column="14" selection-start-line="8" selection-start-column="14" selection-end-line="8" selection-end-column="14" />
|
||||
</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="396">
|
||||
<caret line="190" column="12" selection-start-line="190" selection-start-column="12" selection-end-line="190" selection-end-column="12" />
|
||||
</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="294">
|
||||
<caret line="32" column="7" selection-start-line="32" selection-start-column="7" selection-end-line="32" selection-end-column="7" />
|
||||
<folding>
|
||||
<element signature="e#36#82#0#PHP" expanded="true" />
|
||||
</folding>
|
||||
</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="265">
|
||||
<caret line="87" column="24" selection-start-line="87" selection-start-column="24" selection-end-line="87" selection-end-column="24" />
|
||||
</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="172">
|
||||
<caret line="94" column="49" selection-start-line="94" selection-start-column="49" selection-end-line="94" selection-end-column="49" />
|
||||
<folding>
|
||||
<element signature="e#44#82#0#PHP" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/README.md">
|
||||
<provider selected="true" editor-type-id="split-provider[text-editor;MarkdownPreviewEditor]">
|
||||
<state split_layout="SPLIT">
|
||||
<first_editor relative-caret-position="206">
|
||||
<caret line="849" column="50" selection-start-line="849" selection-start-column="50" selection-end-line="849" selection-end-column="50" />
|
||||
</first_editor>
|
||||
<second_editor>
|
||||
<markdownNavigatorState />
|
||||
</second_editor>
|
||||
</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="357">
|
||||
<caret line="20" column="7" selection-start-line="20" selection-start-column="7" selection-end-line="20" selection-end-column="7" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/.gitignore">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="42">
|
||||
<caret line="2" column="11" selection-start-line="2" selection-start-column="11" selection-end-line="2" selection-end-column="11" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</component>
|
||||
</project>
|
||||
@@ -1,13 +0,0 @@
|
||||
build:
|
||||
tests:
|
||||
override:
|
||||
-
|
||||
command: './vendor/bin/phpunit --coverage-clover=coverage.clover'
|
||||
coverage:
|
||||
file: 'coverage.clover'
|
||||
format: 'clover'
|
||||
checks:
|
||||
php:
|
||||
code_rating: true
|
||||
duplication: true
|
||||
|
||||
13
.travis.yml
13
.travis.yml
@@ -1,13 +0,0 @@
|
||||
sudo: false
|
||||
|
||||
language: php
|
||||
|
||||
php:
|
||||
- 7.1
|
||||
|
||||
before_script:
|
||||
- curl -sS http://getcomposer.org/installer | php
|
||||
- php composer.phar install --prefer-source --no-interaction
|
||||
|
||||
script:
|
||||
- ./vendor/bin/phpunit
|
||||
262
README.md
262
README.md
@@ -14,8 +14,7 @@ SimpleRouter::get('/', function() {
|
||||
|
||||
### Support the project
|
||||
|
||||
If you like simple-router and wish to see the continued development and maintenance of the project,
|
||||
please consider showing your support by buying me a coffee. Supporters will be listed under the credits section of this documentation.
|
||||
If you like simple-router and wish to see the continued development and maintenance of the project, please consider showing your support by buying me a coffee. Supporters will be listed under the credits section of this documentation.
|
||||
|
||||
You can donate any amount of your choice by [clicking here](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=NNX4D2RUSALCN).
|
||||
|
||||
@@ -33,6 +32,7 @@ You can donate any amount of your choice by [clicking here](https://www.paypal.c
|
||||
- [Helper functions](#helper-functions)
|
||||
- [Routes](#routes)
|
||||
- [Basic routing](#basic-routing)
|
||||
- [Class hinting](#class-hinting)
|
||||
- [Available methods](#available-methods)
|
||||
- [Multiple HTTP-verbs](#multiple-http-verbs)
|
||||
- [Route parameters](#route-parameters)
|
||||
@@ -51,9 +51,6 @@ You can donate any amount of your choice by [clicking here](https://www.paypal.c
|
||||
- [Partial groups](#partial-groups)
|
||||
- [Form Method Spoofing](#form-method-spoofing)
|
||||
- [Accessing The Current Route](#accessing-the-current-route)
|
||||
- [Dependency injection](#dependency-injection)
|
||||
- [Enabling dependency injection](#enabling-dependency-injection)
|
||||
- [More reading](#more-reading)
|
||||
- [Other examples](#other-examples)
|
||||
- [CSRF-protection](#csrf-protection)
|
||||
- [Adding CSRF-verifier](#adding-csrf-verifier)
|
||||
@@ -85,10 +82,13 @@ You can donate any amount of your choice by [clicking here](https://www.paypal.c
|
||||
- [Registering new event](#registering-new-event)
|
||||
- [Custom EventHandlers](#custom-eventhandlers)
|
||||
- [Advanced](#advanced)
|
||||
- [Disable multiple route rendering](#disable-multiple-route-rendering)
|
||||
- [Url rewriting](#url-rewriting)
|
||||
- [Changing current route](#changing-current-route)
|
||||
- [Bootmanager: loading routes dynamically](#bootmanager-loading-routes-dynamically)
|
||||
- [Adding routes manually](#adding-routes-manually)
|
||||
- [Custom class-loader](#custom-class-loader)
|
||||
- [Integrating with php-di](#Integrating-with-php-di)
|
||||
- [Parameters](#parameters)
|
||||
- [Extending](#extending)
|
||||
- [Help and support](#help-and-support)
|
||||
@@ -123,7 +123,7 @@ composer require pecee/simple-router
|
||||
|
||||
The goal of this project is to create a router that is more or less 100% compatible with the Laravel documentation, while remaining as simple as possible, and as easy to integrate and change without compromising either speed or complexity. Being lightweight is the #1 priority.
|
||||
|
||||
We've included a simple demo project for the router which can be found in the `demo-project` folder. This project should give you a basic understanding of how to setup and use simple-php-router project.
|
||||
We've included a simple demo project for the router which can be found [here](https://github.com/skipperbent/simple-router-demo). This project should give you a basic understanding of how to setup and use simple-php-router project.
|
||||
|
||||
Please note that the demo-project only covers how to integrate the `simple-php-router` in a project without an existing framework. If you are using a framework in your project, the implementation might vary.
|
||||
|
||||
@@ -250,6 +250,7 @@ To add `favicon.ico` to the IIS ignore-list, add the following line to the `<con
|
||||
```
|
||||
|
||||
You can also make one exception for files with some extensions:
|
||||
|
||||
```
|
||||
<add input="{REQUEST_FILENAME}" pattern="\.ico|\.png|\.css|\.jpg" negate="true" ignoreCase="true" />
|
||||
```
|
||||
@@ -257,6 +258,7 @@ You can also make one exception for files with some extensions:
|
||||
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
|
||||
```
|
||||
@@ -298,8 +300,6 @@ We recommend that you add these helper functions to your project. These will all
|
||||
To implement the functions below, simply copy the code to a new file and require the file before initializing the router or copy the `helpers.php` we've included in this library.
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use Pecee\SimpleRouter\SimpleRouter as Router;
|
||||
use Pecee\Http\Url;
|
||||
use Pecee\Http\Response;
|
||||
@@ -347,7 +347,7 @@ function request(): Request
|
||||
/**
|
||||
* Get input class
|
||||
* @param string|null $index Parameter index name
|
||||
* @param string|null $defaultValue Default return value
|
||||
* @param string|mixed|null $defaultValue Default return value
|
||||
* @param array ...$methods Default methods
|
||||
* @return \Pecee\Http\Input\InputHandler|array|string|null
|
||||
*/
|
||||
@@ -404,6 +404,14 @@ SimpleRouter::get('/', function() {
|
||||
});
|
||||
```
|
||||
|
||||
### Class hinting
|
||||
|
||||
You can use class hinting to load a class & method like this:
|
||||
|
||||
```php
|
||||
SimpleRouter::get('/', [MyClass::class, 'myMethod']);
|
||||
```
|
||||
|
||||
### Available methods
|
||||
|
||||
Here you can see a list over all available routes:
|
||||
@@ -484,13 +492,13 @@ SimpleRouter::get('/user/{name}', function ($name) {
|
||||
|
||||
// ... do stuff
|
||||
|
||||
})->where('name', '[A-Za-z]+');
|
||||
})->where([ 'name' => '[A-Za-z]+' ]);
|
||||
|
||||
SimpleRouter::get('/user/{id}', function ($id) {
|
||||
|
||||
// ... do stuff
|
||||
|
||||
})->where('id', '[0-9]+');
|
||||
})->where([ 'id' => '[0-9]+' ]);
|
||||
|
||||
SimpleRouter::get('/user/{id}/{name}', function ($id, $name) {
|
||||
|
||||
@@ -522,10 +530,12 @@ SimpleRouter::all('/ajax/abc/123', function($param1, $param2) {
|
||||
|
||||
### Custom regex for matching parameters
|
||||
|
||||
By default simple-php-router uses the `\w` regular expression when matching parameters.
|
||||
By default simple-php-router uses the `[\w\-]+` regular expression. It will match `A-Z`, `a-z`, `0-9`, `-` and `_` characters in parameters.
|
||||
This decision was made with speed and reliability in mind, as this match will match both letters, number and most of the used symbols on the internet.
|
||||
|
||||
However, sometimes it can be necessary to add a custom regular expression to match more advanced characters like `-` etc.
|
||||
However, sometimes it can be necessary to add a custom regular expression to match more advanced characters like foreign letters `æ ø å` etc.
|
||||
|
||||
You can test your custom regular expression by using on the site [Regex101.com](https://www.regex101.com).
|
||||
|
||||
Instead of adding a custom regular expression to all your parameters, you can simply add a global regular expression which will be used on all the parameters on the route.
|
||||
|
||||
@@ -533,16 +543,16 @@ Instead of adding a custom regular expression to all your parameters, you can si
|
||||
|
||||
#### Example
|
||||
|
||||
This example will ensure that all parameters use the `[\w\-]+` regular expression when parsing.
|
||||
This example will ensure that all parameters use the `[\w\-\æ\ø\å]+` (`a-z`, `A-Z`, `-`, `_`, `0-9`, `æ`, `ø`, `å`) regular expression when parsing.
|
||||
|
||||
```php
|
||||
SimpleRouter::get('/path/{parameter}', 'VideoController@home', ['defaultParameterRegex' => '[\w\-]+']);
|
||||
SimpleRouter::get('/path/{parameter}', 'VideoController@home', ['defaultParameterRegex' => '[\w\-\æ\ø\å]+']);
|
||||
```
|
||||
|
||||
You can also apply this setting to a group if you need multiple routes to use your custom regular expression when parsing parameters.
|
||||
|
||||
```php
|
||||
SimpleRouter::group(['defaultParameterRegex' => '[\w\-]+'], function() {
|
||||
SimpleRouter::group(['defaultParameterRegex' => '[\w\-\æ\ø\å]+'], function() {
|
||||
|
||||
SimpleRouter::get('/path/{parameter}', 'VideoController@home');
|
||||
|
||||
@@ -648,6 +658,7 @@ SimpleRouter::group(['prefix' => '/admin'], function () {
|
||||
## Partial groups
|
||||
|
||||
Partial router groups has the same benefits as a normal group, but supports parameters and are only rendered once the url has matched.
|
||||
Partial groups will render once a part of the url has matched.
|
||||
|
||||
This can be extremely useful in situations, where you only want special routes to be added, when a certain criteria or logic has been met.
|
||||
|
||||
@@ -656,11 +667,11 @@ This can be extremely useful in situations, where you only want special routes t
|
||||
**Example:**
|
||||
|
||||
```php
|
||||
SimpleRouter::partialGroup('/admin/{applicationId}', function ($applicationId) {
|
||||
SimpleRouter::partialGroup('/lang/{language}', function ($language) {
|
||||
|
||||
SimpleRouter::get('/', function($applicationId) {
|
||||
SimpleRouter::get('/', function($language) {
|
||||
|
||||
// Matches The "/admin/applicationId" URL
|
||||
// Matches The "/lang/da" URL
|
||||
|
||||
});
|
||||
|
||||
@@ -685,88 +696,6 @@ SimpleRouter::request()->getLoadedRoute();
|
||||
request()->getLoadedRoute();
|
||||
```
|
||||
|
||||
## Dependency injection
|
||||
|
||||
simple-router supports dependency injection using the [`php-di`](http://php-di.org/) library.
|
||||
|
||||
Dependency injection allows the framework to automatically "inject" (load) classes added as parameters. This can simplify your code, as you can avoid creating new instances of objects you are using often in your `Controllers` etc.
|
||||
|
||||
Here's a basic example of a controller class using dependency injection:
|
||||
|
||||
```php
|
||||
namespace Demo\Controllers;
|
||||
|
||||
class DefaultController {
|
||||
|
||||
public function login(User $user): string
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
The example above will automatically create a new instance of the `User` from the `$user` parameter. This means that the `$user` class contains a new instance of the `User` class and we won't need to create a new instance our self.
|
||||
|
||||
**WARNING:** dependency injection can have some negative impact in performance. If you experience any performance issues, we recommend disabling this functionality.
|
||||
|
||||
### Enabling dependency injection
|
||||
|
||||
Dependency injection is disabled per default to avoid any performance issues.
|
||||
|
||||
Before enabling dependency injection, we recommend that you read the [Container configuration](http://php-di.org/doc/container-configuration.html) section of the php-di documentation. This section covers how to configure php-di to different environments and speed-up the performance.
|
||||
|
||||
#### Enabling for development environment
|
||||
|
||||
The example below should ONLY be used on a development environment.
|
||||
|
||||
```php
|
||||
// Create our new php-di container
|
||||
$container = (new \DI\ContainerBuilder())
|
||||
->useAutowiring(true)
|
||||
->build();
|
||||
|
||||
// Add our container to simple-router and enable dependency injection
|
||||
SimpleRouter::enableDependencyInjection($container);
|
||||
```
|
||||
|
||||
Please check the [More reading](#more-reading) section of the documentation for useful php-di links and tutorials.
|
||||
|
||||
#### Enabling for production environment
|
||||
|
||||
The example below compiles the injections, which can help speed up performance.
|
||||
|
||||
**Note:** You should change the `$cacheDir` to a cache-storage within your project.
|
||||
|
||||
```php
|
||||
// Cache directory
|
||||
$cacheDir = sys_get_temp_dir('simple-router');
|
||||
|
||||
// Create our new php-di container
|
||||
$container = (new \DI\ContainerBuilder())
|
||||
->enableCompilation($cacheDir)
|
||||
->writeProxiesToFile(true, $cacheDir . '/proxies')
|
||||
->useAutowiring(true)
|
||||
->build();
|
||||
|
||||
// Add our container to simple-router and enable dependency injection
|
||||
SimpleRouter::enableDependencyInjection($container);
|
||||
```
|
||||
|
||||
Please check the [More reading](#more-reading) section of the documentation for useful php-di links and tutorials.
|
||||
|
||||
### More reading
|
||||
|
||||
For more information about dependency injection, configuration and settings - we recommend that you check the php-di documentation or some of the useful links we've gathered below.
|
||||
|
||||
#### Useful links
|
||||
|
||||
- [php-di documentation](http://php-di.org/doc/)
|
||||
- [Understanding dependency injection](http://php-di.org/doc/understanding-di.html)
|
||||
- [Best practices guide](http://php-di.org/doc/best-practices.html)
|
||||
- [Configuring the container](http://php-di.org/doc/container-configuration.html)
|
||||
- [Definitions](http://php-di.org/doc/definition.html)
|
||||
|
||||
## Other examples
|
||||
|
||||
You can find many more examples in the `routes.php` example-file below:
|
||||
@@ -783,12 +712,17 @@ SimpleRouter::group(['middleware' => \Demo\Middlewares\Site::class, 'exceptionHa
|
||||
|
||||
SimpleRouter::get('/answers/{id}', 'ControllerAnswers@show', ['where' => ['id' => '[0-9]+']]);
|
||||
|
||||
/**
|
||||
* Class hinting is supported too
|
||||
*/
|
||||
|
||||
SimpleRouter::get('/answers/{id}', [ControllerAnswers::class, 'show'], ['where' => ['id' => '[0-9]+']]);
|
||||
|
||||
/**
|
||||
* Restful resource (see IRestController interface for available methods)
|
||||
*/
|
||||
|
||||
SimpleRouter::resource('/rest', ControllerRessource::class);
|
||||
SimpleRouter::resource('/rest', ControllerResource::class);
|
||||
|
||||
|
||||
/**
|
||||
@@ -809,7 +743,6 @@ SimpleRouter::group(['middleware' => \Demo\Middlewares\Site::class, 'exceptionHa
|
||||
});
|
||||
|
||||
SimpleRouter::get('/page/404', 'ControllerPage@notFound', ['as' => 'page.notfound']);
|
||||
|
||||
```
|
||||
|
||||
---
|
||||
@@ -1429,6 +1362,12 @@ class DatabaseDebugHandler implements IEventHandler
|
||||
|
||||
# Advanced
|
||||
|
||||
## Disable multiple route rendering
|
||||
|
||||
By default the router will try to execute all routes that matches a given url. To stop the router from executing any further routes any method can return a value.
|
||||
|
||||
This behavior can be easily disabled by setting `SimpleRouter::enableMultiRouteRendering(false)` in your `routes.php` file. This is the same behavior as version 3 and below.
|
||||
|
||||
## Url rewriting
|
||||
|
||||
### Changing current route
|
||||
@@ -1480,7 +1419,7 @@ class CustomRouterRules implement IRouterBootManager
|
||||
|
||||
// If the current url matches the rewrite url, we use our custom route
|
||||
|
||||
if($request->getUrl()->getPath() === $url) {
|
||||
if($request->getUrl()->contains($url)) {
|
||||
$request->setRewriteUrl($rule);
|
||||
}
|
||||
}
|
||||
@@ -1528,6 +1467,119 @@ $route->setPrefix('v1');
|
||||
$router->addRoute($route);
|
||||
```
|
||||
|
||||
## Custom class loader
|
||||
|
||||
You can easily extend simple-router to support custom injection frameworks like php-di by taking advantage of the ability to add your custom class-loader.
|
||||
|
||||
Class-loaders must inherit the `IClassLoader` interface.
|
||||
|
||||
**Example:**
|
||||
|
||||
```php
|
||||
class MyCustomClassLoader implements IClassLoader
|
||||
{
|
||||
/**
|
||||
* Load class
|
||||
*
|
||||
* @param string $class
|
||||
* @return object
|
||||
* @throws NotFoundHttpException
|
||||
*/
|
||||
public function loadClass(string $class)
|
||||
{
|
||||
if (\class_exists($class) === false) {
|
||||
throw new NotFoundHttpException(sprintf('Class "%s" does not exist', $class), 404);
|
||||
}
|
||||
|
||||
return new $class();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load closure
|
||||
*
|
||||
* @param Callable $closure
|
||||
* @param array $parameters
|
||||
* @return mixed
|
||||
*/
|
||||
public function loadClosure(Callable $closure, array $parameters)
|
||||
{
|
||||
return \call_user_func_array($closure, $parameters);
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
Next, we need to configure our `routes.php` so the router uses our `MyCustomClassLoader` class for loading classes. This can be done by adding the following line to your `routes.php` file.
|
||||
|
||||
```php
|
||||
SimpleRouter::setCustomClassLoader(new MyCustomClassLoader());
|
||||
```
|
||||
|
||||
### Integrating with php-di
|
||||
|
||||
php-di support was discontinued by version 4.3, however you can easily add it again by creating your own class-loader like the example below:
|
||||
|
||||
```php
|
||||
class MyCustomClassLoader implements IClassLoader
|
||||
{
|
||||
|
||||
protected $container;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
// Create our new php-di container
|
||||
$container = (new \DI\ContainerBuilder())
|
||||
->useAutowiring(true)
|
||||
->build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load class
|
||||
*
|
||||
* @param string $class
|
||||
* @return object
|
||||
* @throws NotFoundHttpException
|
||||
*/
|
||||
public function loadClass(string $class)
|
||||
{
|
||||
if (class_exists($class) === false) {
|
||||
throw new NotFoundHttpException(sprintf('Class "%s" does not exist', $class), 404);
|
||||
}
|
||||
|
||||
if ($this->container !== null) {
|
||||
try {
|
||||
return $this->container->get($class);
|
||||
} catch (\Exception $e) {
|
||||
throw new NotFoundHttpException($e->getMessage(), (int)$e->getCode(), $e->getPrevious());
|
||||
}
|
||||
}
|
||||
|
||||
return new $class();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load closure
|
||||
*
|
||||
* @param Callable $closure
|
||||
* @param array $parameters
|
||||
* @return mixed
|
||||
*/
|
||||
public function loadClosure(Callable $closure, array $parameters)
|
||||
{
|
||||
if ($this->container !== null) {
|
||||
try {
|
||||
return $this->container->call($closure, $parameters);
|
||||
} catch (\Exception $e) {
|
||||
throw new NotFoundHttpException($e->getMessage(), (int)$e->getCode(), $e->getPrevious());
|
||||
}
|
||||
}
|
||||
|
||||
return \call_user_func_array($closure, $parameters);
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
This section contains advanced tips & tricks on extending the usage for parameters.
|
||||
@@ -1854,4 +1906,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
SOFTWARE.
|
||||
@@ -28,13 +28,17 @@
|
||||
],
|
||||
"require": {
|
||||
"php": ">=7.1",
|
||||
"ext-json": "*",
|
||||
"php-di/php-di": "^6.0"
|
||||
"ext-json": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^6.0",
|
||||
"phpunit/phpunit": "^7",
|
||||
"mockery/mockery": "^1"
|
||||
},
|
||||
"scripts": {
|
||||
"test": [
|
||||
"phpunit tests"
|
||||
]
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Pecee\\": "src/Pecee/"
|
||||
|
||||
@@ -47,7 +47,7 @@ function request(): Request
|
||||
/**
|
||||
* Get input class
|
||||
* @param string|null $index Parameter index name
|
||||
* @param string|null $defaultValue Default return value
|
||||
* @param string|mixed|null $defaultValue Default return value
|
||||
* @param array ...$methods Default methods
|
||||
* @return \Pecee\Http\Input\InputHandler|array|string|null
|
||||
*/
|
||||
|
||||
@@ -9,15 +9,15 @@
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
processIsolation="false"
|
||||
stopOnFailure="false"
|
||||
syntaxCheck="false">
|
||||
stopOnFailure="false">
|
||||
<testsuites>
|
||||
<testsuite name="SimpleRouter Test Suite">
|
||||
<directory>tests/Pecee/SimpleRouter/</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<filter>
|
||||
<whitelist processUncoveredFilesFromWhitelist="true">
|
||||
<whitelist addUncoveredFilesFromWhitelist="true"
|
||||
processUncoveredFilesFromWhitelist="true">
|
||||
<directory suffix=".php">src</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
|
||||
@@ -13,9 +13,9 @@ interface IInputItem
|
||||
|
||||
public function setName(string $name): self;
|
||||
|
||||
public function getValue(): ?string;
|
||||
public function getValue();
|
||||
|
||||
public function setValue(string $value): self;
|
||||
public function setValue($value): self;
|
||||
|
||||
public function __toString(): string;
|
||||
|
||||
|
||||
@@ -261,16 +261,16 @@ class InputFile implements IInputItem
|
||||
return $this->getTmpName();
|
||||
}
|
||||
|
||||
public function getValue(): ?string
|
||||
public function getValue()
|
||||
{
|
||||
return $this->getFilename();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
* @param mixed $value
|
||||
* @return static
|
||||
*/
|
||||
public function setValue(string $value): IInputItem
|
||||
public function setValue($value): IInputItem
|
||||
{
|
||||
$this->filename = $value;
|
||||
|
||||
|
||||
@@ -27,6 +27,24 @@ class InputHandler
|
||||
*/
|
||||
protected $request;
|
||||
|
||||
/**
|
||||
* Original post variables
|
||||
* @var array
|
||||
*/
|
||||
protected $originalPost = [];
|
||||
|
||||
/**
|
||||
* Original get/params variables
|
||||
* @var array
|
||||
*/
|
||||
protected $originalParams = [];
|
||||
|
||||
/**
|
||||
* Get original file variables
|
||||
* @var array
|
||||
*/
|
||||
protected $originalFile = [];
|
||||
|
||||
/**
|
||||
* Input constructor.
|
||||
* @param Request $request
|
||||
@@ -46,38 +64,59 @@ class InputHandler
|
||||
{
|
||||
/* Parse get requests */
|
||||
if (\count($_GET) !== 0) {
|
||||
$this->get = $this->parseInputItem($_GET);
|
||||
$this->originalParams = $_GET;
|
||||
$this->get = $this->parseInputItem($this->originalParams);
|
||||
}
|
||||
|
||||
/* Parse post requests */
|
||||
$postVars = $_POST;
|
||||
$this->originalPost = $_POST;
|
||||
|
||||
if (\in_array($this->request->getMethod(), ['put', 'patch', 'delete'], false) === true) {
|
||||
parse_str(file_get_contents('php://input'), $postVars);
|
||||
if ($this->request->isPostBack() === true) {
|
||||
|
||||
$contents = file_get_contents('php://input');
|
||||
|
||||
// Append any PHP-input json
|
||||
if (strpos(trim($contents), '{') === 0) {
|
||||
$post = json_decode($contents, true);
|
||||
|
||||
if ($post !== false) {
|
||||
$this->originalPost += $post;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (\count($postVars) !== 0) {
|
||||
$this->post = $this->parseInputItem($postVars);
|
||||
if (\count($this->originalPost) !== 0) {
|
||||
$this->post = $this->parseInputItem($this->originalPost);
|
||||
}
|
||||
|
||||
/* Parse get requests */
|
||||
if (\count($_FILES) !== 0) {
|
||||
$this->file = $this->parseFiles();
|
||||
$this->originalFile = $_FILES;
|
||||
$this->file = $this->parseFiles($this->originalFile);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $files Array with files to parse
|
||||
* @param string|null $parentKey Key from parent (used when parsing nested array).
|
||||
* @return array
|
||||
*/
|
||||
public function parseFiles(): array
|
||||
public function parseFiles(array $files, ?string $parentKey = null): array
|
||||
{
|
||||
$list = [];
|
||||
|
||||
foreach ((array)$_FILES as $key => $value) {
|
||||
foreach ($files as $key => $value) {
|
||||
|
||||
// Parse multi dept file array
|
||||
if(isset($value['name']) === false && \is_array($value) === true) {
|
||||
$list[$key] = $this->parseFiles($value, $key);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle array input
|
||||
if (\is_array($value['name']) === false) {
|
||||
$values['index'] = $key;
|
||||
$values['index'] = $parentKey ?? $key;
|
||||
|
||||
try {
|
||||
$list[$key] = InputFile::createFromArray($values + $value);
|
||||
} catch (InvalidArgumentException $e) {
|
||||
@@ -171,14 +210,11 @@ class InputHandler
|
||||
foreach ($array as $key => $value) {
|
||||
|
||||
// Handle array input
|
||||
if (\is_array($value) === false) {
|
||||
$list[$key] = new InputItem($key, $value);
|
||||
continue;
|
||||
if (\is_array($value) === true) {
|
||||
$value = $this->parseInputItem($value);
|
||||
}
|
||||
|
||||
$output = $this->parseInputItem($value);
|
||||
|
||||
$list[$key] = $output;
|
||||
$list[$key] = new InputItem($key, $value);
|
||||
}
|
||||
|
||||
return $list;
|
||||
@@ -195,11 +231,11 @@ class InputHandler
|
||||
{
|
||||
$element = null;
|
||||
|
||||
if (\count($methods) === 0 || \in_array('get', $methods, true) === true) {
|
||||
if (\count($methods) === 0 || \in_array(Request::REQUEST_TYPE_GET, $methods, true) === true) {
|
||||
$element = $this->get($index);
|
||||
}
|
||||
|
||||
if (($element === null && \count($methods) === 0) || (\count($methods) !== 0 && \in_array('post', $methods, true) === true)) {
|
||||
if (($element === null && \count($methods) === 0) || (\count($methods) !== 0 && \in_array(Request::REQUEST_TYPE_POST, $methods, true) === true)) {
|
||||
$element = $this->post($index);
|
||||
}
|
||||
|
||||
@@ -210,31 +246,46 @@ class InputHandler
|
||||
return $element;
|
||||
}
|
||||
|
||||
protected function getValueFromArray(array $array): array
|
||||
{
|
||||
$output = [];
|
||||
/* @var $item InputItem */
|
||||
foreach ($array as $key => $item) {
|
||||
|
||||
if ($item instanceof IInputItem) {
|
||||
$item = $item->getValue();
|
||||
}
|
||||
|
||||
$output[$key] = \is_array($item) ? $this->getValueFromArray($item) : $item;
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get input element value matching index
|
||||
*
|
||||
* @param string $index
|
||||
* @param string|null $defaultValue
|
||||
* @param string|mixed|null $defaultValue
|
||||
* @param array ...$methods
|
||||
* @return string|array
|
||||
*/
|
||||
public function value(string $index, ?string $defaultValue = null, ...$methods)
|
||||
public function value(string $index, $defaultValue = null, ...$methods)
|
||||
{
|
||||
$input = $this->find($index, ...$methods);
|
||||
|
||||
$output = [];
|
||||
if ($input instanceof IInputItem) {
|
||||
$input = $input->getValue();
|
||||
}
|
||||
|
||||
/* Handle collection */
|
||||
if (\is_array($input) === true) {
|
||||
/* @var $item InputItem */
|
||||
foreach ($input as $item) {
|
||||
$output[] = $item->getValue();
|
||||
}
|
||||
$output = $this->getValueFromArray($input);
|
||||
|
||||
return (\count($output) === 0) ? $defaultValue : $output;
|
||||
}
|
||||
|
||||
return ($input === null || ($input !== null && trim($input->getValue()) === '')) ? $defaultValue : $input->getValue();
|
||||
return ($input === null || (\is_string($input) && trim($input) === '')) ? $defaultValue : $input;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -292,24 +343,16 @@ class InputHandler
|
||||
*/
|
||||
public function all(array $filter = []): array
|
||||
{
|
||||
$output = $_GET;
|
||||
$output = $this->originalParams + $this->originalPost + $this->originalFile;
|
||||
$output = (\count($filter) > 0) ? \array_intersect_key($output, \array_flip($filter)) : $output;
|
||||
|
||||
if ($this->request->getMethod() === 'post') {
|
||||
|
||||
// Append POST data
|
||||
$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;
|
||||
}
|
||||
foreach ($filter as $filterKey) {
|
||||
if (array_key_exists($filterKey, $output) === false) {
|
||||
$output[$filterKey] = null;
|
||||
}
|
||||
}
|
||||
|
||||
return (\count($filter) > 0) ? array_intersect_key($output, array_flip($filter)) : $output;
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -345,4 +388,67 @@ class InputHandler
|
||||
$this->file[$key] = $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get original post variables
|
||||
* @return array
|
||||
*/
|
||||
public function getOriginalPost(): array
|
||||
{
|
||||
return $this->originalPost;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set original post variables
|
||||
* @param array $post
|
||||
* @return static $this
|
||||
*/
|
||||
public function setOriginalPost(array $post): self
|
||||
{
|
||||
$this->originalPost = $post;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get original get variables
|
||||
* @return array
|
||||
*/
|
||||
public function getOriginalParams(): array
|
||||
{
|
||||
return $this->originalParams;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set original get-variables
|
||||
* @param array $params
|
||||
* @return static $this
|
||||
*/
|
||||
public function setOriginalParams(array $params): self
|
||||
{
|
||||
$this->originalParams = $params;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get original file variables
|
||||
* @return array
|
||||
*/
|
||||
public function getOriginalFile(): array
|
||||
{
|
||||
return $this->originalFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set original file posts variables
|
||||
* @param array $file
|
||||
* @return static $this
|
||||
*/
|
||||
public function setOriginalFile(array $file): self
|
||||
{
|
||||
$this->originalFile = $file;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,13 +2,13 @@
|
||||
|
||||
namespace Pecee\Http\Input;
|
||||
|
||||
class InputItem implements IInputItem
|
||||
class InputItem implements IInputItem, \IteratorAggregate
|
||||
{
|
||||
public $index;
|
||||
public $name;
|
||||
public $value;
|
||||
|
||||
public function __construct(string $index, ?string $value = null)
|
||||
public function __construct(string $index, $value = null)
|
||||
{
|
||||
$this->index = $index;
|
||||
$this->value = $value;
|
||||
@@ -53,19 +53,19 @@ class InputItem implements IInputItem
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @return mixed
|
||||
*/
|
||||
public function getValue(): ?string
|
||||
public function getValue()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set input value
|
||||
* @param string $value
|
||||
* @param mixed $value
|
||||
* @return static
|
||||
*/
|
||||
public function setValue(string $value): IInputItem
|
||||
public function setValue($value): IInputItem
|
||||
{
|
||||
$this->value = $value;
|
||||
|
||||
@@ -74,7 +74,12 @@ class InputItem implements IInputItem
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return (string)$this->value;
|
||||
$value = $this->getValue();
|
||||
return (\is_array($value) === true) ? json_encode($value) : $value;
|
||||
}
|
||||
|
||||
public function getIterator(): \ArrayIterator
|
||||
{
|
||||
return new \ArrayIterator($this->getValue());
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,6 @@ class BaseCsrfVerifier implements IMiddleware
|
||||
|
||||
/**
|
||||
* BaseCsrfVerifier constructor.
|
||||
* @throws \Pecee\Http\Security\Exceptions\SecurityException
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
@@ -64,13 +63,12 @@ class BaseCsrfVerifier implements IMiddleware
|
||||
*/
|
||||
public function handle(Request $request): void
|
||||
{
|
||||
|
||||
if ($this->skip($request) === false && \in_array($request->getMethod(), ['post', 'put', 'delete'], true) === true) {
|
||||
if ($this->skip($request) === false && $request->isPostBack() === true) {
|
||||
|
||||
$token = $request->getInputHandler()->value(
|
||||
static::POST_KEY,
|
||||
$request->getHeader(static::HEADER_KEY),
|
||||
'post'
|
||||
Request::$requestTypesPost
|
||||
);
|
||||
|
||||
if ($this->tokenProvider->validate((string)$token) === false) {
|
||||
@@ -81,7 +79,6 @@ class BaseCsrfVerifier implements IMiddleware
|
||||
|
||||
// Refresh existing token
|
||||
$this->tokenProvider->refresh();
|
||||
|
||||
}
|
||||
|
||||
public function getTokenProvider(): ITokenProvider
|
||||
|
||||
@@ -4,12 +4,52 @@ namespace Pecee\Http;
|
||||
|
||||
use Pecee\Http\Exceptions\MalformedUrlException;
|
||||
use Pecee\Http\Input\InputHandler;
|
||||
use Pecee\Http\Middleware\BaseCsrfVerifier;
|
||||
use Pecee\SimpleRouter\Route\ILoadableRoute;
|
||||
use Pecee\SimpleRouter\Route\RouteUrl;
|
||||
use Pecee\SimpleRouter\SimpleRouter;
|
||||
|
||||
class Request
|
||||
{
|
||||
public const REQUEST_TYPE_GET = 'get';
|
||||
public const REQUEST_TYPE_POST = 'post';
|
||||
public const REQUEST_TYPE_PUT = 'put';
|
||||
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 const CONTENT_TYPE_JSON = 'application/json';
|
||||
public const CONTENT_TYPE_FORM_DATA = 'multipart/form-data';
|
||||
public const CONTENT_TYPE_X_FORM_ENCODED = 'application/x-www-form-urlencoded';
|
||||
|
||||
public const FORCE_METHOD_KEY = '_method';
|
||||
|
||||
/**
|
||||
* All request-types
|
||||
* @var string[]
|
||||
*/
|
||||
public static $requestTypes = [
|
||||
self::REQUEST_TYPE_GET,
|
||||
self::REQUEST_TYPE_POST,
|
||||
self::REQUEST_TYPE_PUT,
|
||||
self::REQUEST_TYPE_PATCH,
|
||||
self::REQUEST_TYPE_OPTIONS,
|
||||
self::REQUEST_TYPE_DELETE,
|
||||
self::REQUEST_TYPE_HEAD,
|
||||
];
|
||||
|
||||
/**
|
||||
* Post request-types.
|
||||
* @var string[]
|
||||
*/
|
||||
public static $requestTypesPost = [
|
||||
self::REQUEST_TYPE_POST,
|
||||
self::REQUEST_TYPE_PUT,
|
||||
self::REQUEST_TYPE_PATCH,
|
||||
self::REQUEST_TYPE_DELETE,
|
||||
];
|
||||
|
||||
/**
|
||||
* Additional data
|
||||
*
|
||||
@@ -23,6 +63,12 @@ class Request
|
||||
*/
|
||||
protected $headers = [];
|
||||
|
||||
/**
|
||||
* Request ContentType
|
||||
* @var string
|
||||
*/
|
||||
protected $contentType;
|
||||
|
||||
/**
|
||||
* Request host
|
||||
* @var string
|
||||
@@ -77,17 +123,16 @@ class Request
|
||||
{
|
||||
foreach ($_SERVER as $key => $value) {
|
||||
$this->headers[strtolower($key)] = $value;
|
||||
$this->headers[strtolower(str_replace('_', '-', $key))] = $value;
|
||||
$this->headers[str_replace('_', '-', strtolower($key))] = $value;
|
||||
}
|
||||
|
||||
$this->setHost($this->getHeader('http-host'));
|
||||
|
||||
// Check if special IIS header exist, otherwise use default.
|
||||
$this->setUrl(new Url($this->getHeader('unencoded-url', $this->getHeader('request-uri'))));
|
||||
|
||||
$this->method = strtolower($this->getHeader('request-method'));
|
||||
$this->setUrl(new Url($this->getFirstHeader(['unencoded-url', 'request-uri'])));
|
||||
$this->setContentType((string)$this->getHeader('content-type'));
|
||||
$this->setMethod((string)($_POST[static::FORCE_METHOD_KEY] ?? $this->getHeader('request-method')));
|
||||
$this->inputHandler = new InputHandler($this);
|
||||
$this->method = strtolower($this->inputHandler->value('_method', $this->getHeader('request-method')));
|
||||
}
|
||||
|
||||
public function isSecure(): bool
|
||||
@@ -147,6 +192,15 @@ class Request
|
||||
return $this->getHeader('php-auth-pw');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the csrf token
|
||||
* @return string|null
|
||||
*/
|
||||
public function getCsrfToken(): ?string
|
||||
{
|
||||
return $this->getHeader(BaseCsrfVerifier::HEADER_KEY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all headers
|
||||
* @return array
|
||||
@@ -158,19 +212,23 @@ class Request
|
||||
|
||||
/**
|
||||
* Get id address
|
||||
* If $safe is false, this function will detect Proxys. But the user can edit this header to whatever he wants!
|
||||
* https://stackoverflow.com/questions/3003145/how-to-get-the-client-ip-address-in-php#comment-25086804
|
||||
* @param bool $safeMode When enabled, only safe non-spoofable headers will be returned. Note this can cause issues when using proxy.
|
||||
* @return string|null
|
||||
*/
|
||||
public function getIp(): ?string
|
||||
public function getIp(bool $safeMode = false): ?string
|
||||
{
|
||||
if ($this->getHeader('http-cf-connecting-ip') !== null) {
|
||||
return $this->getHeader('http-cf-connecting-ip');
|
||||
$headers = ['remote-addr'];
|
||||
if($safeMode === false) {
|
||||
$headers = array_merge($headers, [
|
||||
'http-cf-connecting-ip',
|
||||
'http-client-ip',
|
||||
'http-x-forwarded-for',
|
||||
]);
|
||||
}
|
||||
|
||||
if ($this->getHeader('http-x-forwarded-for') !== null) {
|
||||
return $this->getHeader('http-x-forwarded_for');
|
||||
}
|
||||
|
||||
return $this->getHeader('remote-addr');
|
||||
return $this->getFirstHeader($headers);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -205,14 +263,72 @@ class Request
|
||||
/**
|
||||
* Get header value by name
|
||||
*
|
||||
* @param string $name
|
||||
* @param string|null $defaultValue
|
||||
* @param string $name Name of the header.
|
||||
* @param string|null $defaultValue Value to be returned if header is not found.
|
||||
* @param bool $tryParse When enabled the method will try to find the header from both from client (http) and server-side variants, if the header is not found.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getHeader($name, $defaultValue = null): ?string
|
||||
public function getHeader(string $name, $defaultValue = null, $tryParse = true): ?string
|
||||
{
|
||||
return $this->headers[strtolower($name)] ?? $defaultValue;
|
||||
$name = strtolower($name);
|
||||
$header = $this->headers[$name] ?? null;
|
||||
|
||||
if ($tryParse === true && $header === null) {
|
||||
if (strpos($name, 'http-') === 0) {
|
||||
// Trying to find client header variant which was not found, searching for header variant without http- prefix.
|
||||
$header = $this->headers[str_replace('http-', '', $name)] ?? null;
|
||||
} else {
|
||||
// Trying to find server variant which was not found, searching for client variant with http- prefix.
|
||||
$header = $this->headers['http-' . $name] ?? null;
|
||||
}
|
||||
}
|
||||
|
||||
return $header ?? $defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Will try to find first header from list of headers.
|
||||
*
|
||||
* @param array $headers
|
||||
* @param mixed|null $defaultValue
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function getFirstHeader(array $headers, $defaultValue = null)
|
||||
{
|
||||
foreach($headers as $header) {
|
||||
$header = $this->getHeader($header);
|
||||
if($header !== null) {
|
||||
return $header;
|
||||
}
|
||||
}
|
||||
|
||||
return $defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get request content-type
|
||||
* @return string|null
|
||||
*/
|
||||
public function getContentType(): ?string
|
||||
{
|
||||
return $this->contentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set request content-type
|
||||
* @param string $contentType
|
||||
* @return $this
|
||||
*/
|
||||
protected function setContentType(string $contentType): self
|
||||
{
|
||||
if(strpos($contentType, ';') > 0) {
|
||||
$this->contentType = strtolower(substr($contentType, 0, strpos($contentType, ';')));
|
||||
} else {
|
||||
$this->contentType = strtolower($contentType);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -231,7 +347,7 @@ class Request
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isFormatAccepted($format): bool
|
||||
public function isFormatAccepted(string $format): bool
|
||||
{
|
||||
return ($this->getHeader('http-accept') !== null && stripos($this->getHeader('http-accept'), $format) !== false);
|
||||
}
|
||||
@@ -246,6 +362,16 @@ class Request
|
||||
return (strtolower($this->getHeader('http-x-requested-with')) === 'xmlhttprequest');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true when request-method is type that could contain data in the page body.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isPostBack(): bool
|
||||
{
|
||||
return \in_array($this->getMethod(), static::$requestTypesPost, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get accept formats
|
||||
* @return array
|
||||
@@ -371,7 +497,6 @@ class Request
|
||||
public function setLoadedRoutes(array $routes): self
|
||||
{
|
||||
$this->loadedRoutes = $routes;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -384,7 +509,6 @@ class Request
|
||||
public function addLoadedRoute(ILoadableRoute $route): self
|
||||
{
|
||||
$this->loadedRoutes[] = $route;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -407,11 +531,10 @@ class Request
|
||||
public function setHasPendingRewrite(bool $boolean): self
|
||||
{
|
||||
$this->hasPendingRewrite = $boolean;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function __isset($name)
|
||||
public function __isset($name): bool
|
||||
{
|
||||
return array_key_exists($name, $this->data) === true;
|
||||
}
|
||||
@@ -426,4 +549,4 @@ class Request
|
||||
return $this->data[$name] ?? null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,7 @@ class Response
|
||||
* Redirect the response
|
||||
*
|
||||
* @param string $url
|
||||
* @param int $httpCode
|
||||
* @param ?int $httpCode
|
||||
*/
|
||||
public function redirect(string $url, ?int $httpCode = null): void
|
||||
{
|
||||
@@ -86,7 +86,7 @@ class Response
|
||||
/**
|
||||
* Json encode
|
||||
* @param array|\JsonSerializable $value
|
||||
* @param int $options JSON options Bitmask consisting of JSON_HEX_QUOT, JSON_HEX_TAG, JSON_HEX_AMP, JSON_HEX_APOS, JSON_NUMERIC_CHECK, JSON_PRETTY_PRINT, JSON_UNESCAPED_SLASHES, JSON_FORCE_OBJECT, JSON_PRESERVE_ZERO_FRACTION, JSON_UNESCAPED_UNICODE, JSON_PARTIAL_OUTPUT_ON_ERROR.
|
||||
* @param ?int $options JSON options Bitmask consisting of JSON_HEX_QUOT, JSON_HEX_TAG, JSON_HEX_AMP, JSON_HEX_APOS, JSON_NUMERIC_CHECK, JSON_PRETTY_PRINT, JSON_UNESCAPED_SLASHES, JSON_FORCE_OBJECT, JSON_PRESERVE_ZERO_FRACTION, JSON_UNESCAPED_UNICODE, JSON_PARTIAL_OUTPUT_ON_ERROR.
|
||||
* @param int $dept JSON debt.
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
|
||||
@@ -17,7 +17,7 @@ class CookieTokenProvider implements ITokenProvider
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->token = $this->getToken();
|
||||
$this->token = ($this->hasToken() === true) ? $_COOKIE[static::CSRF_KEY] : null;
|
||||
|
||||
if ($this->token === null) {
|
||||
$this->token = $this->generateToken();
|
||||
@@ -63,7 +63,7 @@ class CookieTokenProvider implements ITokenProvider
|
||||
public function setToken(string $token): void
|
||||
{
|
||||
$this->token = $token;
|
||||
setcookie(static::CSRF_KEY, $token, (time() + 60) * $this->cookieTimeoutMinutes, '/', ini_get('session.cookie_domain'), ini_get('session.cookie_secure'), ini_get('session.cookie_httponly'));
|
||||
setcookie(static::CSRF_KEY, $token, time() + (60 * $this->cookieTimeoutMinutes), '/', ini_get('session.cookie_domain'), ini_get('session.cookie_secure'), ini_get('session.cookie_httponly'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,8 +73,6 @@ class CookieTokenProvider implements ITokenProvider
|
||||
*/
|
||||
public function getToken(?string $defaultValue = null): ?string
|
||||
{
|
||||
$this->token = ($this->hasToken() === true) ? $_COOKIE[static::CSRF_KEY] : null;
|
||||
|
||||
return $this->token ?? $defaultValue;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ class Url implements \JsonSerializable
|
||||
/**
|
||||
* Url constructor.
|
||||
*
|
||||
* @param string $url
|
||||
* @param ?string $url
|
||||
* @throws MalformedUrlException
|
||||
*/
|
||||
public function __construct(?string $url)
|
||||
@@ -371,7 +371,7 @@ class Url implements \JsonSerializable
|
||||
*/
|
||||
public function getParam(string $name, ?string $defaultValue = null): ?string
|
||||
{
|
||||
return isset($this->getParams()[$name]) ?? $defaultValue;
|
||||
return (isset($this->getParams()[$name]) === true) ? $this->getParams()[$name] : $defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -385,7 +385,7 @@ class Url implements \JsonSerializable
|
||||
{
|
||||
$encodedUrl = preg_replace_callback(
|
||||
'/[^:\/@?&=#]+/u',
|
||||
function ($matches) {
|
||||
static function ($matches) {
|
||||
return urlencode($matches[0]);
|
||||
},
|
||||
$url
|
||||
@@ -412,7 +412,7 @@ class Url implements \JsonSerializable
|
||||
if (\count($getParams) !== 0) {
|
||||
|
||||
if ($includeEmpty === false) {
|
||||
$getParams = array_filter($getParams, function ($item) {
|
||||
$getParams = array_filter($getParams, static function ($item) {
|
||||
return (trim($item) !== '');
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2,44 +2,21 @@
|
||||
|
||||
namespace Pecee\SimpleRouter\ClassLoader;
|
||||
|
||||
use DI\Container;
|
||||
use Pecee\SimpleRouter\Exceptions\NotFoundHttpException;
|
||||
use Pecee\SimpleRouter\Exceptions\ClassNotFoundHttpException;
|
||||
|
||||
class ClassLoader implements IClassLoader
|
||||
{
|
||||
/**
|
||||
* Dependency injection enabled
|
||||
* @var bool
|
||||
*/
|
||||
protected $useDependencyInjection = false;
|
||||
|
||||
/**
|
||||
* @var Container|null
|
||||
*/
|
||||
protected $container;
|
||||
|
||||
/**
|
||||
* Load class
|
||||
*
|
||||
* @param string $class
|
||||
* @return mixed
|
||||
* @throws NotFoundHttpException
|
||||
* @return object
|
||||
* @throws ClassNotFoundHttpException
|
||||
*/
|
||||
public function loadClass(string $class)
|
||||
{
|
||||
if (class_exists($class) === false) {
|
||||
throw new NotFoundHttpException(sprintf('Class "%s" does not exist', $class), 404);
|
||||
}
|
||||
|
||||
if ($this->useDependencyInjection === true) {
|
||||
$container = $this->getContainer();
|
||||
if ($container !== null) {
|
||||
try {
|
||||
return $container->get($class);
|
||||
} catch (\Exception $e) {
|
||||
throw new NotFoundHttpException($e->getMessage(), (int)$e->getCode(), $e->getPrevious());
|
||||
}
|
||||
}
|
||||
throw new ClassNotFoundHttpException($class, null, sprintf('Class "%s" does not exist', $class), 404, null);
|
||||
}
|
||||
|
||||
return new $class();
|
||||
@@ -48,71 +25,13 @@ class ClassLoader implements IClassLoader
|
||||
/**
|
||||
* Load closure
|
||||
*
|
||||
* @param \Closure $closure
|
||||
* @param Callable $closure
|
||||
* @param array $parameters
|
||||
* @return mixed
|
||||
* @throws NotFoundHttpException
|
||||
*/
|
||||
public function loadClosure(\Closure $closure, array $parameters)
|
||||
public function loadClosure(Callable $closure, array $parameters)
|
||||
{
|
||||
if ($this->useDependencyInjection === true) {
|
||||
$container = $this->getContainer();
|
||||
if ($container !== null) {
|
||||
try {
|
||||
return $container->call($closure, $parameters);
|
||||
} catch (\Exception $e) {
|
||||
throw new NotFoundHttpException($e->getMessage(), (int)$e->getCode(), $e->getPrevious());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return \call_user_func_array($closure, $parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get dependency injector container.
|
||||
*
|
||||
* @return Container|null
|
||||
*/
|
||||
public function getContainer(): ?Container
|
||||
{
|
||||
return $this->container;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the dependency-injector container.
|
||||
*
|
||||
* @param Container $container
|
||||
* @return ClassLoader
|
||||
*/
|
||||
public function setContainer(Container $container): self
|
||||
{
|
||||
$this->container = $container;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable or disable dependency injection.
|
||||
*
|
||||
* @param bool $enabled
|
||||
* @return static
|
||||
*/
|
||||
public function useDependencyInjection(bool $enabled): self
|
||||
{
|
||||
$this->useDependencyInjection = $enabled;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if dependency injection is enabled.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isDependencyInjectionEnabled(): bool
|
||||
{
|
||||
return $this->useDependencyInjection;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,8 +5,20 @@ namespace Pecee\SimpleRouter\ClassLoader;
|
||||
interface IClassLoader
|
||||
{
|
||||
|
||||
/**
|
||||
* Called when loading class
|
||||
* @param string $class
|
||||
* @return object
|
||||
*/
|
||||
public function loadClass(string $class);
|
||||
|
||||
public function loadClosure(\Closure $closure, array $parameters);
|
||||
/**
|
||||
* Called when loading method
|
||||
*
|
||||
* @param callable $closure
|
||||
* @param array $parameters
|
||||
* @return mixed
|
||||
*/
|
||||
public function loadClosure(Callable $closure, array $parameters);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ class EventArgument implements IEventArgument
|
||||
* @param string $name
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get($name)
|
||||
public function __get(string $name)
|
||||
{
|
||||
return $this->arguments[$name] ?? null;
|
||||
}
|
||||
@@ -83,7 +83,7 @@ class EventArgument implements IEventArgument
|
||||
* @param string $name
|
||||
* @return bool
|
||||
*/
|
||||
public function __isset($name)
|
||||
public function __isset(string $name): bool
|
||||
{
|
||||
return array_key_exists($name, $this->arguments);
|
||||
}
|
||||
@@ -93,7 +93,7 @@ class EventArgument implements IEventArgument
|
||||
* @param mixed $value
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __set($name, $value)
|
||||
public function __set(string $name, $value)
|
||||
{
|
||||
throw new \InvalidArgumentException('Not supported');
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace Pecee\SimpleRouter\Exceptions;
|
||||
|
||||
use Throwable;
|
||||
|
||||
class ClassNotFoundHttpException extends NotFoundHttpException
|
||||
{
|
||||
protected $class;
|
||||
protected $method;
|
||||
|
||||
public function __construct(string $class, ?string $method = null, $message = "", $code = 0, Throwable $previous = null)
|
||||
{
|
||||
parent::__construct($message, $code, $previous);
|
||||
|
||||
$this->class = $class;
|
||||
$this->method = $method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get class name
|
||||
* @return string
|
||||
*/
|
||||
public function getClass(): string
|
||||
{
|
||||
return $this->class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get method
|
||||
* @return string|null
|
||||
*/
|
||||
public function getMethod(): ?string
|
||||
{
|
||||
return $this->method;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,7 +16,7 @@ class DebugEventHandler implements IEventHandler
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->callback = function (EventArgument $argument) {
|
||||
$this->callback = static function (EventArgument $argument) {
|
||||
// todo: log in database
|
||||
};
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@ class EventHandler implements IEventHandler
|
||||
* Get events.
|
||||
*
|
||||
* @param string|null $name Filter events by name.
|
||||
* @param array ...$names Add multiple names...
|
||||
* @param array|string ...$names Add multiple names...
|
||||
* @return array
|
||||
*/
|
||||
public function getEvents(?string $name, ...$names): array
|
||||
|
||||
@@ -29,7 +29,7 @@ interface IGroupRoute extends IRoute
|
||||
* @param array $handlers
|
||||
* @return static
|
||||
*/
|
||||
public function setExceptionHandlers(array $handlers);
|
||||
public function setExceptionHandlers(array $handlers): self;
|
||||
|
||||
/**
|
||||
* Get exception-handlers for group
|
||||
@@ -59,7 +59,7 @@ interface IGroupRoute extends IRoute
|
||||
* @param string $prefix
|
||||
* @return static
|
||||
*/
|
||||
public function setPrefix($prefix): self;
|
||||
public function setPrefix(string $prefix): self;
|
||||
|
||||
/**
|
||||
* Get prefix.
|
||||
|
||||
@@ -82,6 +82,6 @@ interface ILoadableRoute extends IRoute
|
||||
* @param string $regex
|
||||
* @return static
|
||||
*/
|
||||
public function setMatch($regex): self;
|
||||
public function setMatch(string $regex): self;
|
||||
|
||||
}
|
||||
@@ -10,11 +10,11 @@ interface IRoute
|
||||
/**
|
||||
* Method called to check if a domain matches
|
||||
*
|
||||
* @param string $route
|
||||
* @param string $url
|
||||
* @param Request $request
|
||||
* @return bool
|
||||
*/
|
||||
public function matchRoute($route, Request $request): bool;
|
||||
public function matchRoute(string $url, Request $request): bool;
|
||||
|
||||
/**
|
||||
* Called when route is matched.
|
||||
@@ -22,8 +22,8 @@ interface IRoute
|
||||
*
|
||||
* @param Request $request
|
||||
* @param Router $router
|
||||
* @throws \Pecee\SimpleRouter\Exceptions\NotFoundHttpException
|
||||
* @return string
|
||||
* @throws \Pecee\SimpleRouter\Exceptions\NotFoundHttpException
|
||||
*/
|
||||
public function renderRoute(Request $request, Router $router): ?string;
|
||||
|
||||
@@ -82,7 +82,7 @@ interface IRoute
|
||||
/**
|
||||
* Set callback
|
||||
*
|
||||
* @param string $callback
|
||||
* @param string|array|\Closure $callback
|
||||
* @return static
|
||||
*/
|
||||
public function setCallback($callback): self;
|
||||
@@ -129,7 +129,7 @@ interface IRoute
|
||||
* @param string $namespace
|
||||
* @return static
|
||||
*/
|
||||
public function setDefaultNamespace($namespace): IRoute;
|
||||
public function setDefaultNamespace(string $namespace): IRoute;
|
||||
|
||||
/**
|
||||
* Get default namespace
|
||||
@@ -196,7 +196,7 @@ interface IRoute
|
||||
* @param string $middleware
|
||||
* @return static
|
||||
*/
|
||||
public function addMiddleware($middleware): self;
|
||||
public function addMiddleware(string $middleware): self;
|
||||
|
||||
/**
|
||||
* Set middlewares array
|
||||
@@ -206,4 +206,18 @@ interface IRoute
|
||||
*/
|
||||
public function setMiddlewares(array $middlewares): self;
|
||||
|
||||
/**
|
||||
* If enabled parameters containing null-value will not be passed along to the callback.
|
||||
*
|
||||
* @param bool $enabled
|
||||
* @return static $this
|
||||
*/
|
||||
public function setFilterEmptyParams(bool $enabled): self;
|
||||
|
||||
/**
|
||||
* Status if filtering of empty params is enabled or disabled
|
||||
* @return bool
|
||||
*/
|
||||
public function getFilterEmptyParams(): bool;
|
||||
|
||||
}
|
||||
@@ -60,7 +60,7 @@ abstract class LoadableRoute extends Route implements ILoadableRoute
|
||||
return null;
|
||||
}
|
||||
|
||||
return ((bool)preg_match($this->regex, $request->getHost() . $url) !== false);
|
||||
return ((bool)preg_match($this->regex, $url) !== false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -183,7 +183,7 @@ abstract class LoadableRoute extends Route implements ILoadableRoute
|
||||
* @param string $regex
|
||||
* @return static
|
||||
*/
|
||||
public function setMatch($regex): ILoadableRoute
|
||||
public function setMatch(string $regex): ILoadableRoute
|
||||
{
|
||||
$this->regex = $regex;
|
||||
|
||||
@@ -229,15 +229,15 @@ abstract class LoadableRoute extends Route implements ILoadableRoute
|
||||
/**
|
||||
* Merge with information from another route.
|
||||
*
|
||||
* @param array $values
|
||||
* @param array $settings
|
||||
* @param bool $merge
|
||||
* @return static
|
||||
*/
|
||||
public function setSettings(array $values, bool $merge = false): IRoute
|
||||
public function setSettings(array $settings, bool $merge = false): IRoute
|
||||
{
|
||||
if (isset($values['as']) === true) {
|
||||
if (isset($settings['as']) === true) {
|
||||
|
||||
$name = $values['as'];
|
||||
$name = $settings['as'];
|
||||
|
||||
if ($this->name !== null && $merge !== false) {
|
||||
$name .= '.' . $this->name;
|
||||
@@ -246,11 +246,11 @@ abstract class LoadableRoute extends Route implements ILoadableRoute
|
||||
$this->setName($name);
|
||||
}
|
||||
|
||||
if (isset($values['prefix']) === true) {
|
||||
$this->prependUrl($values['prefix']);
|
||||
if (isset($settings['prefix']) === true) {
|
||||
$this->prependUrl($settings['prefix']);
|
||||
}
|
||||
|
||||
return parent::setSettings($values, $merge);
|
||||
return parent::setSettings($settings, $merge);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,31 +4,14 @@ namespace Pecee\SimpleRouter\Route;
|
||||
|
||||
use Pecee\Http\Middleware\IMiddleware;
|
||||
use Pecee\Http\Request;
|
||||
use Pecee\SimpleRouter\Exceptions\ClassNotFoundHttpException;
|
||||
use Pecee\SimpleRouter\Exceptions\NotFoundHttpException;
|
||||
use Pecee\SimpleRouter\Router;
|
||||
|
||||
abstract class Route implements IRoute
|
||||
{
|
||||
protected const PARAMETERS_REGEX_FORMAT = '%s([\w]+)(\%s?)%s';
|
||||
protected const PARAMETERS_DEFAULT_REGEX = '[\w]+';
|
||||
|
||||
public const REQUEST_TYPE_GET = 'get';
|
||||
public const REQUEST_TYPE_POST = 'post';
|
||||
public const REQUEST_TYPE_PUT = 'put';
|
||||
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,
|
||||
self::REQUEST_TYPE_POST,
|
||||
self::REQUEST_TYPE_PUT,
|
||||
self::REQUEST_TYPE_PATCH,
|
||||
self::REQUEST_TYPE_OPTIONS,
|
||||
self::REQUEST_TYPE_DELETE,
|
||||
self::REQUEST_TYPE_HEAD,
|
||||
];
|
||||
protected const PARAMETERS_DEFAULT_REGEX = '[\w-]+';
|
||||
|
||||
/**
|
||||
* If enabled parameters containing null-value
|
||||
@@ -85,7 +68,7 @@ abstract class Route implements IRoute
|
||||
|
||||
/* Filter parameters with null-value */
|
||||
if ($this->filterEmptyParams === true) {
|
||||
$parameters = array_filter($parameters, function ($var) {
|
||||
$parameters = array_filter($parameters, static function ($var) {
|
||||
return ($var !== null);
|
||||
});
|
||||
}
|
||||
@@ -95,28 +78,24 @@ abstract class Route implements IRoute
|
||||
$router->debug('Executing callback');
|
||||
|
||||
/* When the callback is a function */
|
||||
|
||||
return $router->getClassLoader()->loadClosure($callback, $parameters);
|
||||
}
|
||||
|
||||
/* When the callback is a class + method */
|
||||
$controller = explode('@', $callback);
|
||||
$controller = $this->getClass();
|
||||
$method = $this->getMethod();
|
||||
|
||||
$namespace = $this->getNamespace();
|
||||
|
||||
$className = ($namespace !== null && $controller[0][0] !== '\\') ? $namespace . '\\' . $controller[0] : $controller[0];
|
||||
$className = ($namespace !== null && $controller[0] !== '\\') ? $namespace . '\\' . $controller : $controller;
|
||||
|
||||
$router->debug('Loading class %s', $className);
|
||||
$class = $router->getClassLoader()->loadClass($className);
|
||||
|
||||
if (\count($controller) === 1) {
|
||||
if ($method === null) {
|
||||
$controller[1] = '__invoke';
|
||||
}
|
||||
|
||||
$method = $controller[1];
|
||||
|
||||
if (method_exists($class, $method) === false) {
|
||||
throw new NotFoundHttpException(sprintf('Method "%s" does not exist in class "%s"', $method, $className), 404);
|
||||
throw new ClassNotFoundHttpException($className, $method, sprintf('Method "%s" does not exist in class "%s"', $method, $className), 404, null);
|
||||
}
|
||||
|
||||
$router->debug('Executing callback');
|
||||
@@ -124,7 +103,7 @@ abstract class Route implements IRoute
|
||||
return \call_user_func_array([$class, $method], $parameters);
|
||||
}
|
||||
|
||||
protected function parseParameters($route, $url, $parameterRegex = null)
|
||||
protected function parseParameters($route, $url, $parameterRegex = null): ?array
|
||||
{
|
||||
$regex = (strpos($route, $this->paramModifiers[0]) === false) ? null :
|
||||
sprintf
|
||||
@@ -144,7 +123,7 @@ abstract class Route implements IRoute
|
||||
$urlRegex = preg_quote($route, '/');
|
||||
} else {
|
||||
|
||||
foreach (preg_split('/((\-?\/?)\{[^}]+\})/', $route) as $key => $t) {
|
||||
foreach (preg_split('/((-?\/?){[^}]+})/', $route) as $key => $t) {
|
||||
|
||||
$regex = '';
|
||||
|
||||
@@ -155,13 +134,11 @@ abstract class Route implements IRoute
|
||||
/* If custom regex is defined, use that */
|
||||
if (isset($this->where[$name]) === true) {
|
||||
$regex = $this->where[$name];
|
||||
} else if ($parameterRegex !== null) {
|
||||
$regex = $parameterRegex;
|
||||
} else {
|
||||
$regex = $this->defaultParameterRegex ?? static::PARAMETERS_DEFAULT_REGEX;
|
||||
$regex = $parameterRegex ?? $this->defaultParameterRegex ?? static::PARAMETERS_DEFAULT_REGEX;
|
||||
}
|
||||
|
||||
$regex = sprintf('((\/|\-)(?P<%2$s>%3$s))%1$s', $parameters[2][$key], $name, $regex);
|
||||
$regex = sprintf('((\/|-)(?P<%2$s>%3$s))%1$s', $parameters[2][$key], $name, $regex);
|
||||
}
|
||||
|
||||
$urlRegex .= preg_quote($t, '/') . $regex;
|
||||
@@ -273,7 +250,7 @@ abstract class Route implements IRoute
|
||||
/**
|
||||
* Set callback
|
||||
*
|
||||
* @param string $callback
|
||||
* @param string|array|\Closure $callback
|
||||
* @return static
|
||||
*/
|
||||
public function setCallback($callback): IRoute
|
||||
@@ -293,6 +270,10 @@ abstract class Route implements IRoute
|
||||
|
||||
public function getMethod(): ?string
|
||||
{
|
||||
if (\is_array($this->callback) === true && \count($this->callback) > 1) {
|
||||
return $this->callback[1];
|
||||
}
|
||||
|
||||
if (\is_string($this->callback) === true && strpos($this->callback, '@') !== false) {
|
||||
$tmp = explode('@', $this->callback);
|
||||
|
||||
@@ -304,6 +285,10 @@ abstract class Route implements IRoute
|
||||
|
||||
public function getClass(): ?string
|
||||
{
|
||||
if (\is_array($this->callback) === true && \count($this->callback) > 0) {
|
||||
return $this->callback[0];
|
||||
}
|
||||
|
||||
if (\is_string($this->callback) === true && strpos($this->callback, '@') !== false) {
|
||||
$tmp = explode('@', $this->callback);
|
||||
|
||||
@@ -315,14 +300,14 @@ abstract class Route implements IRoute
|
||||
|
||||
public function setMethod(string $method): IRoute
|
||||
{
|
||||
$this->callback = sprintf('%s@%s', $this->getClass(), $method);
|
||||
$this->callback = [$this->getClass(), $method];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setClass(string $class): IRoute
|
||||
{
|
||||
$this->callback = sprintf('%s@%s', $class, $this->getMethod());
|
||||
$this->callback = [$class, $this->getMethod()];
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -342,7 +327,7 @@ abstract class Route implements IRoute
|
||||
* @param string $namespace
|
||||
* @return static
|
||||
*/
|
||||
public function setDefaultNamespace($namespace): IRoute
|
||||
public function setDefaultNamespace(string $namespace): IRoute
|
||||
{
|
||||
$this->defaultNamespace = $namespace;
|
||||
|
||||
@@ -397,35 +382,35 @@ abstract class Route implements IRoute
|
||||
/**
|
||||
* Merge with information from another route.
|
||||
*
|
||||
* @param array $values
|
||||
* @param array $settings
|
||||
* @param bool $merge
|
||||
* @return static
|
||||
*/
|
||||
public function setSettings(array $values, bool $merge = false): IRoute
|
||||
public function setSettings(array $settings, bool $merge = false): IRoute
|
||||
{
|
||||
if ($this->namespace === null && isset($values['namespace']) === true) {
|
||||
$this->setNamespace($values['namespace']);
|
||||
if ($this->namespace === null && isset($settings['namespace']) === true) {
|
||||
$this->setNamespace($settings['namespace']);
|
||||
}
|
||||
|
||||
if (isset($values['method']) === true) {
|
||||
$this->setRequestMethods(array_merge($this->requestMethods, (array)$values['method']));
|
||||
if (isset($settings['method']) === true) {
|
||||
$this->setRequestMethods(array_merge($this->requestMethods, (array)$settings['method']));
|
||||
}
|
||||
|
||||
if (isset($values['where']) === true) {
|
||||
$this->setWhere(array_merge($this->where, (array)$values['where']));
|
||||
if (isset($settings['where']) === true) {
|
||||
$this->setWhere(array_merge($this->where, (array)$settings['where']));
|
||||
}
|
||||
|
||||
if (isset($values['parameters']) === true) {
|
||||
$this->setParameters(array_merge($this->parameters, (array)$values['parameters']));
|
||||
if (isset($settings['parameters']) === true) {
|
||||
$this->setParameters(array_merge($this->parameters, (array)$settings['parameters']));
|
||||
}
|
||||
|
||||
// Push middleware if multiple
|
||||
if (isset($values['middleware']) === true) {
|
||||
$this->setMiddlewares(array_merge((array)$values['middleware'], $this->middlewares));
|
||||
if (isset($settings['middleware']) === true) {
|
||||
$this->setMiddlewares(array_merge((array)$settings['middleware'], $this->middlewares));
|
||||
}
|
||||
|
||||
if (isset($values['defaultParameterRegex']) === true) {
|
||||
$this->setDefaultParameterRegex($values['defaultParameterRegex']);
|
||||
if (isset($settings['defaultParameterRegex']) === true) {
|
||||
$this->setDefaultParameterRegex($settings['defaultParameterRegex']);
|
||||
}
|
||||
|
||||
return $this;
|
||||
@@ -458,9 +443,9 @@ abstract class Route implements IRoute
|
||||
* Add regular expression parameter match.
|
||||
* Alias for LoadableRoute::where()
|
||||
*
|
||||
* @see LoadableRoute::where()
|
||||
* @param array $options
|
||||
* @return static
|
||||
* @see LoadableRoute::where()
|
||||
*/
|
||||
public function where(array $options)
|
||||
{
|
||||
@@ -508,11 +493,11 @@ abstract class Route implements IRoute
|
||||
/**
|
||||
* Add middleware class-name
|
||||
*
|
||||
* @deprecated This method is deprecated and will be removed in the near future.
|
||||
* @param IMiddleware|string $middleware
|
||||
* @param string $middleware
|
||||
* @return static
|
||||
* @deprecated This method is deprecated and will be removed in the near future.
|
||||
*/
|
||||
public function setMiddleware($middleware)
|
||||
public function setMiddleware(string $middleware): self
|
||||
{
|
||||
$this->middlewares[] = $middleware;
|
||||
|
||||
@@ -522,10 +507,10 @@ abstract class Route implements IRoute
|
||||
/**
|
||||
* Add middleware class-name
|
||||
*
|
||||
* @param IMiddleware|string $middleware
|
||||
* @param string $middleware
|
||||
* @return static
|
||||
*/
|
||||
public function addMiddleware($middleware): IRoute
|
||||
public function addMiddleware(string $middleware): IRoute
|
||||
{
|
||||
$this->middlewares[] = $middleware;
|
||||
|
||||
@@ -560,7 +545,7 @@ abstract class Route implements IRoute
|
||||
* @param string $regex
|
||||
* @return static
|
||||
*/
|
||||
public function setDefaultParameterRegex($regex)
|
||||
public function setDefaultParameterRegex(string $regex): self
|
||||
{
|
||||
$this->defaultParameterRegex = $regex;
|
||||
|
||||
@@ -577,4 +562,25 @@ abstract class Route implements IRoute
|
||||
return $this->defaultParameterRegex;
|
||||
}
|
||||
|
||||
/**
|
||||
* If enabled parameters containing null-value will not be passed along to the callback.
|
||||
*
|
||||
* @param bool $enabled
|
||||
* @return static $this
|
||||
*/
|
||||
public function setFilterEmptyParams(bool $enabled): IRoute
|
||||
{
|
||||
$this->filterEmptyParams = $enabled;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Status if filtering of empty params is enabled or disabled
|
||||
* @return bool
|
||||
*/
|
||||
public function getFilterEmptyParams(): bool
|
||||
{
|
||||
return $this->filterEmptyParams;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -64,7 +64,7 @@ class RouteController extends LoadableRoute implements IControllerRoute
|
||||
if ($method !== null) {
|
||||
|
||||
/* Remove requestType from method-name, if it exists */
|
||||
foreach (static::$requestTypes as $requestType) {
|
||||
foreach (Request::$requestTypes as $requestType) {
|
||||
|
||||
if (stripos($method, $requestType) === 0) {
|
||||
$method = (string)substr($method, \strlen($requestType));
|
||||
@@ -86,7 +86,7 @@ class RouteController extends LoadableRoute implements IControllerRoute
|
||||
return '/' . trim($url, '/') . '/';
|
||||
}
|
||||
|
||||
public function matchRoute($url, Request $request): bool
|
||||
public function matchRoute(string $url, Request $request): bool
|
||||
{
|
||||
if ($this->getGroup() !== null && $this->getGroup()->matchRoute($url, $request) === false) {
|
||||
return false;
|
||||
@@ -110,7 +110,7 @@ class RouteController extends LoadableRoute implements IControllerRoute
|
||||
$this->parameters = \array_slice($path, 1);
|
||||
|
||||
// Set callback
|
||||
$this->setCallback($this->controller . '@' . $this->method);
|
||||
$this->setCallback([$this->controller, $this->method]);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -167,17 +167,17 @@ class RouteController extends LoadableRoute implements IControllerRoute
|
||||
/**
|
||||
* Merge with information from another route.
|
||||
*
|
||||
* @param array $values
|
||||
* @param array $settings
|
||||
* @param bool $merge
|
||||
* @return static
|
||||
*/
|
||||
public function setSettings(array $values, bool $merge = false): IRoute
|
||||
public function setSettings(array $settings, bool $merge = false): IRoute
|
||||
{
|
||||
if (isset($values['names']) === true) {
|
||||
$this->names = $values['names'];
|
||||
if (isset($settings['names']) === true) {
|
||||
$this->names = $settings['names'];
|
||||
}
|
||||
|
||||
return parent::setSettings($values, $merge);
|
||||
return parent::setSettings($settings, $merge);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -26,12 +26,15 @@ class RouteGroup extends Route implements IGroupRoute
|
||||
|
||||
foreach ($this->domains as $domain) {
|
||||
|
||||
// If domain has no parameters but matches
|
||||
if ($domain === $request->getHost()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$parameters = $this->parseParameters($domain, $request->getHost(), '.*');
|
||||
|
||||
if ($parameters !== null && \count($parameters) !== 0) {
|
||||
|
||||
$this->parameters = $parameters;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -46,14 +49,22 @@ class RouteGroup extends Route implements IGroupRoute
|
||||
* @param Request $request
|
||||
* @return bool
|
||||
*/
|
||||
public function matchRoute($url, Request $request): bool
|
||||
public function matchRoute(string $url, Request $request): bool
|
||||
{
|
||||
if ($this->getGroup() !== null && $this->getGroup()->matchRoute($url, $request) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Parse parameter
|
||||
|
||||
$prefix = $this->prefix;
|
||||
|
||||
foreach ($this->getParameters() as $parameter => $value) {
|
||||
$prefix = str_ireplace('{' . $parameter . '}', $value, $prefix);
|
||||
}
|
||||
|
||||
/* Skip if prefix doesn't match */
|
||||
if ($this->prefix !== null && stripos($url, $this->prefix) === false) {
|
||||
if ($this->prefix !== null && stripos($url, $prefix) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -123,7 +134,7 @@ class RouteGroup extends Route implements IGroupRoute
|
||||
* @param string $prefix
|
||||
* @return static
|
||||
*/
|
||||
public function setPrefix($prefix): IGroupRoute
|
||||
public function setPrefix(string $prefix): IGroupRoute
|
||||
{
|
||||
$this->prefix = '/' . trim($prefix, '/');
|
||||
|
||||
@@ -143,28 +154,28 @@ class RouteGroup extends Route implements IGroupRoute
|
||||
/**
|
||||
* Merge with information from another route.
|
||||
*
|
||||
* @param array $values
|
||||
* @param array $settings
|
||||
* @param bool $merge
|
||||
* @return static
|
||||
*/
|
||||
public function setSettings(array $values, bool $merge = false): IRoute
|
||||
public function setSettings(array $settings, bool $merge = false): IRoute
|
||||
{
|
||||
|
||||
if (isset($values['prefix']) === true) {
|
||||
$this->setPrefix($values['prefix'] . $this->prefix);
|
||||
if (isset($settings['prefix']) === true) {
|
||||
$this->setPrefix($settings['prefix'] . $this->prefix);
|
||||
}
|
||||
|
||||
if ($merge === false && isset($values['exceptionHandler']) === true) {
|
||||
$this->setExceptionHandlers((array)$values['exceptionHandler']);
|
||||
if ($merge === false && isset($settings['exceptionHandler']) === true) {
|
||||
$this->setExceptionHandlers((array)$settings['exceptionHandler']);
|
||||
}
|
||||
|
||||
if ($merge === false && isset($values['domain']) === true) {
|
||||
$this->setDomains((array)$values['domain']);
|
||||
if ($merge === false && isset($settings['domain']) === true) {
|
||||
$this->setDomains((array)$settings['domain']);
|
||||
}
|
||||
|
||||
if (isset($values['as']) === true) {
|
||||
if (isset($settings['as']) === true) {
|
||||
|
||||
$name = $values['as'];
|
||||
$name = $settings['as'];
|
||||
|
||||
if ($this->name !== null && $merge !== false) {
|
||||
$name .= '.' . $this->name;
|
||||
@@ -173,7 +184,7 @@ class RouteGroup extends Route implements IGroupRoute
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
return parent::setSettings($values, $merge);
|
||||
return parent::setSettings($settings, $merge);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -22,7 +22,7 @@ class RoutePartialGroup extends RouteGroup implements IPartialGroupRoute
|
||||
* @param Request $request
|
||||
* @return bool
|
||||
*/
|
||||
public function matchRoute($url, Request $request): bool
|
||||
public function matchRoute(string $url, Request $request): bool
|
||||
{
|
||||
if ($this->getGroup() !== null && $this->getGroup()->matchRoute($url, $request) === false) {
|
||||
return false;
|
||||
@@ -38,7 +38,7 @@ class RoutePartialGroup extends RouteGroup implements IPartialGroupRoute
|
||||
}
|
||||
|
||||
/* Set the parameters */
|
||||
$this->setParameters((array)$parameters);
|
||||
$this->setParameters($parameters);
|
||||
}
|
||||
|
||||
return $this->matchDomain($request);
|
||||
|
||||
@@ -76,14 +76,14 @@ class RouteResource extends LoadableRoute implements IControllerRoute
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
protected function call($method)
|
||||
protected function call($method): bool
|
||||
{
|
||||
$this->setCallback($this->controller . '@' . $method);
|
||||
$this->setCallback([$this->controller, $method]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function matchRoute($url, Request $request): bool
|
||||
public function matchRoute(string $url, Request $request): bool
|
||||
{
|
||||
if ($this->getGroup() !== null && $this->getGroup()->matchRoute($url, $request) === false) {
|
||||
return false;
|
||||
@@ -115,32 +115,32 @@ class RouteResource extends LoadableRoute implements IControllerRoute
|
||||
$method = $request->getMethod();
|
||||
|
||||
// Delete
|
||||
if ($method === static::REQUEST_TYPE_DELETE && $id !== null) {
|
||||
if ($method === Request::REQUEST_TYPE_DELETE && $id !== null) {
|
||||
return $this->call($this->methodNames['destroy']);
|
||||
}
|
||||
|
||||
// Update
|
||||
if ($id !== null && \in_array($method, [static::REQUEST_TYPE_PATCH, static::REQUEST_TYPE_PUT], true) === true) {
|
||||
if ($id !== null && \in_array($method, [Request::REQUEST_TYPE_PATCH, Request::REQUEST_TYPE_PUT], true) === true) {
|
||||
return $this->call($this->methodNames['update']);
|
||||
}
|
||||
|
||||
// Edit
|
||||
if ($method === static::REQUEST_TYPE_GET && $id !== null && $action === 'edit') {
|
||||
if ($method === Request::REQUEST_TYPE_GET && $id !== null && $action === 'edit') {
|
||||
return $this->call($this->methodNames['edit']);
|
||||
}
|
||||
|
||||
// Create
|
||||
if ($method === static::REQUEST_TYPE_GET && $id === 'create') {
|
||||
if ($method === Request::REQUEST_TYPE_GET && $id === 'create') {
|
||||
return $this->call($this->methodNames['create']);
|
||||
}
|
||||
|
||||
// Save
|
||||
if ($method === static::REQUEST_TYPE_POST) {
|
||||
if ($method === Request::REQUEST_TYPE_POST) {
|
||||
return $this->call($this->methodNames['store']);
|
||||
}
|
||||
|
||||
// Show
|
||||
if ($method === static::REQUEST_TYPE_GET && $id !== null) {
|
||||
if ($method === Request::REQUEST_TYPE_GET && $id !== null) {
|
||||
return $this->call($this->methodNames['show']);
|
||||
}
|
||||
|
||||
@@ -190,7 +190,7 @@ class RouteResource extends LoadableRoute implements IControllerRoute
|
||||
* @param array $names
|
||||
* @return static $this
|
||||
*/
|
||||
public function setMethodNames(array $names)
|
||||
public function setMethodNames(array $names): RouteResource
|
||||
{
|
||||
$this->methodNames = $names;
|
||||
|
||||
@@ -210,21 +210,21 @@ class RouteResource extends LoadableRoute implements IControllerRoute
|
||||
/**
|
||||
* Merge with information from another route.
|
||||
*
|
||||
* @param array $values
|
||||
* @param array $settings
|
||||
* @param bool $merge
|
||||
* @return static
|
||||
*/
|
||||
public function setSettings(array $values, bool $merge = false): IRoute
|
||||
public function setSettings(array $settings, bool $merge = false): IRoute
|
||||
{
|
||||
if (isset($values['names']) === true) {
|
||||
$this->names = $values['names'];
|
||||
if (isset($settings['names']) === true) {
|
||||
$this->names = $settings['names'];
|
||||
}
|
||||
|
||||
if (isset($values['methods']) === true) {
|
||||
$this->methodNames = $values['methods'];
|
||||
if (isset($settings['methods']) === true) {
|
||||
$this->methodNames = $settings['methods'];
|
||||
}
|
||||
|
||||
return parent::setSettings($values, $merge);
|
||||
return parent::setSettings($settings, $merge);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -12,7 +12,7 @@ class RouteUrl extends LoadableRoute
|
||||
$this->setCallback($callback);
|
||||
}
|
||||
|
||||
public function matchRoute($url, Request $request): bool
|
||||
public function matchRoute(string $url, Request $request): bool
|
||||
{
|
||||
if ($this->getGroup() !== null && $this->getGroup()->matchRoute($url, $request) === false) {
|
||||
return false;
|
||||
|
||||
@@ -110,6 +110,13 @@ class Router
|
||||
*/
|
||||
protected $classLoader;
|
||||
|
||||
/**
|
||||
* When enabled the router will render all routes that matches.
|
||||
* When disabled the router will stop execution when first route is found.
|
||||
* @var bool
|
||||
*/
|
||||
protected $renderMultipleRoutes = true;
|
||||
|
||||
/**
|
||||
* Router constructor.
|
||||
*/
|
||||
@@ -262,13 +269,20 @@ class Router
|
||||
|
||||
/**
|
||||
* Load routes
|
||||
* @throws NotFoundHttpException
|
||||
* @return void
|
||||
* @throws NotFoundHttpException
|
||||
*/
|
||||
public function loadRoutes(): void
|
||||
{
|
||||
$this->debug('Loading routes');
|
||||
|
||||
$this->fireEvents(EventHandler::EVENT_LOAD_ROUTES, [
|
||||
'routes' => $this->routes,
|
||||
]);
|
||||
|
||||
/* Loop through each route-request */
|
||||
$this->processRoutes($this->routes);
|
||||
|
||||
$this->fireEvents(EventHandler::EVENT_BOOT, [
|
||||
'bootmanagers' => $this->bootManagers,
|
||||
]);
|
||||
@@ -291,13 +305,6 @@ class Router
|
||||
$this->debug('Finished rendering bootmanager "%s"', $className);
|
||||
}
|
||||
|
||||
$this->fireEvents(EventHandler::EVENT_LOAD_ROUTES, [
|
||||
'routes' => $this->routes,
|
||||
]);
|
||||
|
||||
/* Loop through each route-request */
|
||||
$this->processRoutes($this->routes);
|
||||
|
||||
$this->debug('Finished loading routes');
|
||||
}
|
||||
|
||||
@@ -305,7 +312,7 @@ class Router
|
||||
* Start the routing
|
||||
*
|
||||
* @return string|null
|
||||
* @throws \Pecee\SimpleRouter\Exceptions\NotFoundHttpException
|
||||
* @throws NotFoundHttpException
|
||||
* @throws \Pecee\Http\Middleware\Exceptions\TokenMismatchException
|
||||
* @throws HttpException
|
||||
* @throws \Exception
|
||||
@@ -350,7 +357,7 @@ class Router
|
||||
{
|
||||
$this->debug('Routing request');
|
||||
|
||||
$methodNotAllowed = false;
|
||||
$methodNotAllowed = null;
|
||||
|
||||
try {
|
||||
$url = $this->request->getRewriteUrl() ?? $this->request->getUrl()->getPath();
|
||||
@@ -370,7 +377,12 @@ class Router
|
||||
/* Check if request method matches */
|
||||
if (\count($route->getRequestMethods()) !== 0 && \in_array($this->request->getMethod(), $route->getRequestMethods(), true) === false) {
|
||||
$this->debug('Method "%s" not allowed', $this->request->getMethod());
|
||||
$methodNotAllowed = true;
|
||||
|
||||
// Only set method not allowed is not already set
|
||||
if ($methodNotAllowed === null) {
|
||||
$methodNotAllowed = true;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -394,14 +406,21 @@ class Router
|
||||
'route' => $route,
|
||||
]);
|
||||
|
||||
$output = $route->renderRoute($this->request, $this);
|
||||
if ($output !== null) {
|
||||
return $output;
|
||||
}
|
||||
$routeOutput = $route->renderRoute($this->request, $this);
|
||||
|
||||
$output = $this->handleRouteRewrite($key, $url);
|
||||
if ($output !== null) {
|
||||
return $output;
|
||||
if ($this->renderMultipleRoutes === true) {
|
||||
if ($routeOutput !== null) {
|
||||
return $routeOutput;
|
||||
}
|
||||
|
||||
$output = $this->handleRouteRewrite($key, $url);
|
||||
if ($output !== null) {
|
||||
return $output;
|
||||
}
|
||||
} else {
|
||||
$output = $this->handleRouteRewrite($key, $url);
|
||||
|
||||
return $output ?? $routeOutput;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -442,7 +461,7 @@ class Router
|
||||
* @throws HttpException
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function handleRouteRewrite($key, string $url): ?string
|
||||
protected function handleRouteRewrite(string $key, string $url): ?string
|
||||
{
|
||||
/* If the request has changed */
|
||||
if ($this->request->hasPendingRewrite() === false) {
|
||||
@@ -475,9 +494,9 @@ class Router
|
||||
|
||||
/**
|
||||
* @param \Exception $e
|
||||
* @throws HttpException
|
||||
* @throws \Exception
|
||||
* @return string|null
|
||||
* @throws \Exception
|
||||
* @throws HttpException
|
||||
*/
|
||||
protected function handleException(\Exception $e): ?string
|
||||
{
|
||||
@@ -585,7 +604,7 @@ class Router
|
||||
|
||||
/* Check if callback matches (if it's not a function) */
|
||||
$callback = $route->getCallback();
|
||||
if (\is_string($name) === true && \is_string($callback) === true && strpos($name, '@') !== false && strpos($callback, '@') !== false && \is_callable($callback) === false) {
|
||||
if (\is_string($name) === true && \is_string($callback) === true && \is_callable($callback) === false && strpos($name, '@') !== false && strpos($callback, '@') !== false) {
|
||||
|
||||
/* Check if the entire callback is matching */
|
||||
if (strpos($callback, $name) === 0 || strtolower($callback) === strtolower($name)) {
|
||||
@@ -625,7 +644,6 @@ class Router
|
||||
* @param array|null $getParams
|
||||
* @return Url
|
||||
* @throws InvalidArgumentException
|
||||
* @throws \Pecee\Http\Exceptions\MalformedUrlException
|
||||
*/
|
||||
public function getUrl(?string $name = null, $parameters = null, ?array $getParams = null): Url
|
||||
{
|
||||
@@ -665,14 +683,16 @@ class Router
|
||||
->setParams($getParams);
|
||||
}
|
||||
|
||||
/* We try to find a match on the given name */
|
||||
$route = $this->findRoute($name);
|
||||
if($name !== null) {
|
||||
/* We try to find a match on the given name */
|
||||
$route = $this->findRoute($name);
|
||||
|
||||
if ($route !== null) {
|
||||
return $this->request
|
||||
->getUrlCopy()
|
||||
->setPath($route->findUrl($route->getMethod(), $parameters, $name))
|
||||
->setParams($getParams);
|
||||
if ($route !== null) {
|
||||
return $this->request
|
||||
->getUrlCopy()
|
||||
->setPath($route->findUrl($route->getMethod(), $parameters, $name))
|
||||
->setParams($getParams);
|
||||
}
|
||||
}
|
||||
|
||||
/* Using @ is most definitely a controller@method or alias@method */
|
||||
@@ -854,7 +874,7 @@ class Router
|
||||
* @param string $name
|
||||
* @param array $arguments
|
||||
*/
|
||||
protected function fireEvents($name, array $arguments = []): void
|
||||
protected function fireEvents(string $name, array $arguments = []): void
|
||||
{
|
||||
if (\count($this->eventHandlers) === 0) {
|
||||
return;
|
||||
@@ -908,4 +928,19 @@ class Router
|
||||
return $this->debugList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the rendering behavior of the router.
|
||||
* When enabled the router will render all routes that matches.
|
||||
* When disabled the router will stop rendering at the first route that matches.
|
||||
*
|
||||
* @param bool $bool
|
||||
* @return $this
|
||||
*/
|
||||
public function setRenderMultipleRoutes(bool $bool): self
|
||||
{
|
||||
$this->renderMultipleRoutes = $bool;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,9 +10,7 @@
|
||||
|
||||
namespace Pecee\SimpleRouter;
|
||||
|
||||
use DI\Container;
|
||||
use Pecee\Exceptions\InvalidArgumentException;
|
||||
use Pecee\Http\Exceptions\MalformedUrlException;
|
||||
use Pecee\Http\Middleware\BaseCsrfVerifier;
|
||||
use Pecee\Http\Request;
|
||||
use Pecee\Http\Response;
|
||||
@@ -60,6 +58,11 @@ class SimpleRouter
|
||||
*/
|
||||
public static function start(): void
|
||||
{
|
||||
// Set default namespaces
|
||||
foreach (static::router()->getRoutes() as $route) {
|
||||
static::addDefaultNamespace($route);
|
||||
}
|
||||
|
||||
echo static::router()->start();
|
||||
}
|
||||
|
||||
@@ -75,8 +78,7 @@ class SimpleRouter
|
||||
try {
|
||||
ob_start();
|
||||
static::router()->setDebugEnabled(true)->start();
|
||||
$routerOutput = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$routerOutput = ob_get_clean();
|
||||
} catch (\Exception $e) {
|
||||
|
||||
}
|
||||
@@ -167,7 +169,7 @@ class SimpleRouter
|
||||
* @param int $httpCode
|
||||
* @return IRoute
|
||||
*/
|
||||
public static function redirect($where, $to, $httpCode = 301): IRoute
|
||||
public static function redirect(string $where, string $to, int $httpCode = 301): IRoute
|
||||
{
|
||||
return static::get($where, function () use ($to, $httpCode) {
|
||||
static::response()->redirect($to, $httpCode);
|
||||
@@ -178,79 +180,79 @@ class SimpleRouter
|
||||
* Route the given url to your callback on GET request method.
|
||||
*
|
||||
* @param string $url
|
||||
* @param string|\Closure $callback
|
||||
* @param string|array|\Closure $callback
|
||||
* @param array|null $settings
|
||||
*
|
||||
* @return RouteUrl
|
||||
*/
|
||||
public static function get(string $url, $callback, array $settings = null): IRoute
|
||||
{
|
||||
return static::match(['get'], $url, $callback, $settings);
|
||||
return static::match([Request::REQUEST_TYPE_GET], $url, $callback, $settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Route the given url to your callback on POST request method.
|
||||
*
|
||||
* @param string $url
|
||||
* @param string|\Closure $callback
|
||||
* @param string|array|\Closure $callback
|
||||
* @param array|null $settings
|
||||
* @return RouteUrl
|
||||
*/
|
||||
public static function post(string $url, $callback, array $settings = null): IRoute
|
||||
{
|
||||
return static::match(['post'], $url, $callback, $settings);
|
||||
return static::match([Request::REQUEST_TYPE_POST], $url, $callback, $settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Route the given url to your callback on PUT request method.
|
||||
*
|
||||
* @param string $url
|
||||
* @param string|\Closure $callback
|
||||
* @param string|array|\Closure $callback
|
||||
* @param array|null $settings
|
||||
* @return RouteUrl
|
||||
*/
|
||||
public static function put(string $url, $callback, array $settings = null): IRoute
|
||||
{
|
||||
return static::match(['put'], $url, $callback, $settings);
|
||||
return static::match([Request::REQUEST_TYPE_PUT], $url, $callback, $settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Route the given url to your callback on PATCH request method.
|
||||
*
|
||||
* @param string $url
|
||||
* @param string|\Closure $callback
|
||||
* @param string|array|\Closure $callback
|
||||
* @param array|null $settings
|
||||
* @return RouteUrl
|
||||
*/
|
||||
public static function patch(string $url, $callback, array $settings = null): IRoute
|
||||
{
|
||||
return static::match(['patch'], $url, $callback, $settings);
|
||||
return static::match([Request::REQUEST_TYPE_PATCH], $url, $callback, $settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Route the given url to your callback on OPTIONS request method.
|
||||
*
|
||||
* @param string $url
|
||||
* @param string|\Closure $callback
|
||||
* @param string|array|\Closure $callback
|
||||
* @param array|null $settings
|
||||
* @return RouteUrl
|
||||
*/
|
||||
public static function options(string $url, $callback, array $settings = null): IRoute
|
||||
{
|
||||
return static::match(['options'], $url, $callback, $settings);
|
||||
return static::match([Request::REQUEST_TYPE_OPTIONS], $url, $callback, $settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Route the given url to your callback on DELETE request method.
|
||||
*
|
||||
* @param string $url
|
||||
* @param string|\Closure $callback
|
||||
* @param string|array|\Closure $callback
|
||||
* @param array|null $settings
|
||||
* @return RouteUrl
|
||||
*/
|
||||
public static function delete(string $url, $callback, array $settings = null): IRoute
|
||||
{
|
||||
return static::match(['delete'], $url, $callback, $settings);
|
||||
return static::match([Request::REQUEST_TYPE_DELETE], $url, $callback, $settings);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -307,14 +309,14 @@ class SimpleRouter
|
||||
* Alias for the form method
|
||||
*
|
||||
* @param string $url
|
||||
* @param callable $callback
|
||||
* @param string|array|\Closure $callback
|
||||
* @param array|null $settings
|
||||
* @see SimpleRouter::form
|
||||
* @return RouteUrl
|
||||
* @see SimpleRouter::form
|
||||
*/
|
||||
public static function basic(string $url, $callback, array $settings = null): IRoute
|
||||
{
|
||||
return static::match(['get', 'post'], $url, $callback, $settings);
|
||||
return static::form($url, $callback, $settings);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -322,14 +324,17 @@ class SimpleRouter
|
||||
* Route the given url to your callback on POST and GET request method.
|
||||
*
|
||||
* @param string $url
|
||||
* @param string|\Closure $callback
|
||||
* @param string|array|\Closure $callback
|
||||
* @param array|null $settings
|
||||
* @see SimpleRouter::form
|
||||
* @return RouteUrl
|
||||
* @see SimpleRouter::form
|
||||
*/
|
||||
public static function form(string $url, $callback, array $settings = null): IRoute
|
||||
{
|
||||
return static::match(['get', 'post'], $url, $callback, $settings);
|
||||
return static::match([
|
||||
Request::REQUEST_TYPE_GET,
|
||||
Request::REQUEST_TYPE_POST,
|
||||
], $url, $callback, $settings);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -337,7 +342,7 @@ class SimpleRouter
|
||||
*
|
||||
* @param array $requestMethods
|
||||
* @param string $url
|
||||
* @param string|\Closure $callback
|
||||
* @param string|array|\Closure $callback
|
||||
* @param array|null $settings
|
||||
* @return RouteUrl|IRoute
|
||||
*/
|
||||
@@ -345,7 +350,6 @@ class SimpleRouter
|
||||
{
|
||||
$route = new RouteUrl($url, $callback);
|
||||
$route->setRequestMethods($requestMethods);
|
||||
$route = static::addDefaultNamespace($route);
|
||||
|
||||
if ($settings !== null) {
|
||||
$route->setSettings($settings);
|
||||
@@ -358,14 +362,13 @@ class SimpleRouter
|
||||
* This type will route the given url to your callback and allow any type of request method
|
||||
*
|
||||
* @param string $url
|
||||
* @param string|\Closure $callback
|
||||
* @param string|array|\Closure $callback
|
||||
* @param array|null $settings
|
||||
* @return RouteUrl|IRoute
|
||||
*/
|
||||
public static function all(string $url, $callback, array $settings = null)
|
||||
{
|
||||
$route = new RouteUrl($url, $callback);
|
||||
$route = static::addDefaultNamespace($route);
|
||||
|
||||
if ($settings !== null) {
|
||||
$route->setSettings($settings);
|
||||
@@ -382,10 +385,9 @@ class SimpleRouter
|
||||
* @param array|null $settings
|
||||
* @return RouteController|IRoute
|
||||
*/
|
||||
public static function controller(string $url, $controller, array $settings = null)
|
||||
public static function controller(string $url, string $controller, array $settings = null)
|
||||
{
|
||||
$route = new RouteController($url, $controller);
|
||||
$route = static::addDefaultNamespace($route);
|
||||
|
||||
if ($settings !== null) {
|
||||
$route->setSettings($settings);
|
||||
@@ -402,10 +404,9 @@ class SimpleRouter
|
||||
* @param array|null $settings
|
||||
* @return RouteResource|IRoute
|
||||
*/
|
||||
public static function resource(string $url, $controller, array $settings = null)
|
||||
public static function resource(string $url, string $controller, array $settings = null)
|
||||
{
|
||||
$route = new RouteResource($url, $controller);
|
||||
$route = static::addDefaultNamespace($route);
|
||||
|
||||
if ($settings !== null) {
|
||||
$route->setSettings($settings);
|
||||
@@ -458,21 +459,14 @@ class SimpleRouter
|
||||
try {
|
||||
return static::router()->getUrl($name, $parameters, $getParams);
|
||||
} catch (\Exception $e) {
|
||||
try {
|
||||
return new Url('/');
|
||||
} catch (MalformedUrlException $e) {
|
||||
|
||||
}
|
||||
return new Url('/');
|
||||
}
|
||||
|
||||
// This will never happen...
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the request
|
||||
*
|
||||
* @return \Pecee\Http\Request
|
||||
* @return Request
|
||||
*/
|
||||
public static function request(): Request
|
||||
{
|
||||
@@ -517,39 +511,43 @@ class SimpleRouter
|
||||
{
|
||||
if (static::$defaultNamespace !== null) {
|
||||
|
||||
$callback = $route->getCallback();
|
||||
$ns = static::$defaultNamespace;
|
||||
$namespace = $route->getNamespace();
|
||||
|
||||
/* Only add default namespace on relative callbacks */
|
||||
if ($callback === null || (\is_string($callback) === true && $callback[0] !== '\\')) {
|
||||
|
||||
$namespace = static::$defaultNamespace;
|
||||
|
||||
$currentNamespace = $route->getNamespace();
|
||||
|
||||
if ($currentNamespace !== null) {
|
||||
$namespace .= '\\' . $currentNamespace;
|
||||
if ($namespace !== null) {
|
||||
// Don't overwrite namespaces that starts with \
|
||||
if ($namespace[0] !== '\\') {
|
||||
$ns .= '\\' . $namespace;
|
||||
} else {
|
||||
$ns = $namespace;
|
||||
}
|
||||
|
||||
$route->setDefaultNamespace($namespace);
|
||||
|
||||
}
|
||||
|
||||
$route->setNamespace($ns);
|
||||
}
|
||||
|
||||
return $route;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable or disable dependency injection
|
||||
* Changes the rendering behavior of the router.
|
||||
* When enabled the router will render all routes that matches.
|
||||
* When disabled the router will stop rendering at the first route that matches.
|
||||
*
|
||||
* @param Container $container
|
||||
* @return IClassLoader
|
||||
* @param bool $bool
|
||||
*/
|
||||
public static function enableDependencyInjection(Container $container): IClassLoader
|
||||
public static function enableMultiRouteRendering(bool $bool): void
|
||||
{
|
||||
return static::router()
|
||||
->getClassLoader()
|
||||
->useDependencyInjection(true)
|
||||
->setContainer($container);
|
||||
static::router()->setRenderMultipleRoutes($bool);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set custom class-loader class used.
|
||||
* @param IClassLoader $classLoader
|
||||
*/
|
||||
public static function setCustomClassLoader(IClassLoader $classLoader): void
|
||||
{
|
||||
static::router()->setClassLoader($classLoader);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
49
tests/Pecee/SimpleRouter/BootManagerTest.php
Normal file
49
tests/Pecee/SimpleRouter/BootManagerTest.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
require_once 'Dummy/DummyMiddleware.php';
|
||||
require_once 'Dummy/DummyController.php';
|
||||
require_once 'Dummy/Handler/ExceptionHandler.php';
|
||||
require_once 'Dummy/Managers/TestBootManager.php';
|
||||
require_once 'Dummy/Managers/FindUrlBootManager.php';
|
||||
|
||||
class BootManagerTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
|
||||
public function testBootManagerRoutes()
|
||||
{
|
||||
$result = false;
|
||||
|
||||
TestRouter::get('/', function () use (&$result) {
|
||||
$result = true;
|
||||
});
|
||||
TestRouter::get('/about', 'DummyController@method2');
|
||||
TestRouter::get('/contact', 'DummyController@method3');
|
||||
|
||||
// Add boot-manager
|
||||
TestRouter::addBootManager(new TestBootManager([
|
||||
'/con' => '/about',
|
||||
'/contact' => '/',
|
||||
]));
|
||||
|
||||
TestRouter::debug('/contact');
|
||||
|
||||
$this->assertTrue($result);
|
||||
}
|
||||
|
||||
public function testFindUrlFromBootManager()
|
||||
{
|
||||
TestRouter::get('/', 'DummyController@method1');
|
||||
TestRouter::get('/about', 'DummyController@method2')->name('about');
|
||||
TestRouter::get('/contact', 'DummyController@method3')->name('contact');
|
||||
|
||||
$result = false;
|
||||
|
||||
// Add boot-manager
|
||||
TestRouter::addBootManager(new FindUrlBootManager($result));
|
||||
|
||||
TestRouter::debug('/');
|
||||
|
||||
$this->assertTrue($result);
|
||||
}
|
||||
|
||||
}
|
||||
30
tests/Pecee/SimpleRouter/ClassLoaderTest.php
Normal file
30
tests/Pecee/SimpleRouter/ClassLoaderTest.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
require_once 'Dummy/DummyMiddleware.php';
|
||||
require_once 'Dummy/DummyController.php';
|
||||
require_once 'Dummy/ClassLoader/CustomClassLoader.php';
|
||||
|
||||
class ClassLoaderTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
|
||||
public function testCustomClassLoader()
|
||||
{
|
||||
$result = false;
|
||||
|
||||
TestRouter::setCustomClassLoader(new CustomClassLoader());
|
||||
|
||||
TestRouter::get('/', 'NonExistingClass@method3');
|
||||
TestRouter::get('/test-closure', function($status) use(&$result) {
|
||||
$result = $status;
|
||||
});
|
||||
|
||||
$classLoaderClass = TestRouter::debugOutput('/', 'get', false);
|
||||
TestRouter::debugOutput('/test-closure');
|
||||
|
||||
$this->assertEquals('method3', $classLoaderClass);
|
||||
$this->assertTrue($result);
|
||||
|
||||
TestRouter::router()->reset();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
<?php
|
||||
|
||||
require_once 'Dummy/DummyMiddleware.php';
|
||||
|
||||
class DependencyInjectionTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function testDependencyInjectionDevelopment()
|
||||
{
|
||||
$builder = new \DI\ContainerBuilder();
|
||||
$container = $builder
|
||||
->useAutowiring(true)
|
||||
->ignorePhpDocErrors(true)
|
||||
->build();
|
||||
|
||||
TestRouter::enableDependencyInjection($container);
|
||||
|
||||
$className = null;
|
||||
|
||||
TestRouter::get('/', function (DummyMiddleware $url) use (&$className) {
|
||||
$className = \get_class($url);
|
||||
});
|
||||
|
||||
TestRouter::debug('/');
|
||||
|
||||
$this->assertEquals(DummyMiddleware::class, $className);
|
||||
}
|
||||
|
||||
public function testDependencyInjectionProduction()
|
||||
{
|
||||
$cacheDir = dirname(__DIR__, 2) . '/tmp';
|
||||
|
||||
$builder = new \DI\ContainerBuilder();
|
||||
$builder
|
||||
->enableCompilation($cacheDir)
|
||||
->writeProxiesToFile(true, $cacheDir . '/proxies')
|
||||
->ignorePhpDocErrors(true)
|
||||
->useAutowiring(true);
|
||||
|
||||
$container = $builder->build();
|
||||
|
||||
TestRouter::enableDependencyInjection($container);
|
||||
|
||||
$className = null;
|
||||
|
||||
TestRouter::get('/', function (DummyMiddleware $url) use (&$className) {
|
||||
$className = \get_class($url);
|
||||
});
|
||||
|
||||
TestRouter::debug('/');
|
||||
|
||||
$this->assertEquals(DummyMiddleware::class, $className);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
class CustomClassLoader implements \Pecee\SimpleRouter\ClassLoader\IClassLoader
|
||||
{
|
||||
public function loadClass(string $class)
|
||||
{
|
||||
return new DummyController();
|
||||
}
|
||||
|
||||
public function loadClosure(callable $closure, array $parameters)
|
||||
{
|
||||
return \call_user_func_array($closure, ['result' => true]);
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,12 @@
|
||||
|
||||
class DummyController
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function method1()
|
||||
{
|
||||
|
||||
@@ -10,6 +16,11 @@ class DummyController
|
||||
public function method2()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function method3()
|
||||
{
|
||||
return 'method3';
|
||||
}
|
||||
|
||||
public function param($params = null)
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
class FindUrlBootManager implements \Pecee\SimpleRouter\IRouterBootManager
|
||||
{
|
||||
protected $result;
|
||||
|
||||
public function __construct(&$result)
|
||||
{
|
||||
$this->result = &$result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when router loads it's routes
|
||||
*
|
||||
* @param \Pecee\SimpleRouter\Router $router
|
||||
* @param \Pecee\Http\Request $request
|
||||
*/
|
||||
public function boot(\Pecee\SimpleRouter\Router $router, \Pecee\Http\Request $request): void
|
||||
{
|
||||
$contact = $router->findRoute('contact');
|
||||
|
||||
if($contact !== null) {
|
||||
$this->result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,13 +3,11 @@
|
||||
class TestBootManager implements \Pecee\SimpleRouter\IRouterBootManager
|
||||
{
|
||||
|
||||
protected $routes;
|
||||
protected $aliasUrl;
|
||||
protected $rewrite;
|
||||
|
||||
public function __construct(array $routes, string $aliasUrl)
|
||||
public function __construct(array $rewrite)
|
||||
{
|
||||
$this->routes = $routes;
|
||||
$this->aliasUrl = $aliasUrl;
|
||||
$this->rewrite = $rewrite;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -20,11 +18,11 @@ class TestBootManager implements \Pecee\SimpleRouter\IRouterBootManager
|
||||
*/
|
||||
public function boot(\Pecee\SimpleRouter\Router $router, \Pecee\Http\Request $request): void
|
||||
{
|
||||
foreach ($this->routes as $url) {
|
||||
foreach ($this->rewrite as $url => $rewrite) {
|
||||
// If the current url matches the rewrite url, we use our custom route
|
||||
|
||||
if ($request->getUrl()->contains($url) === true) {
|
||||
$request->setRewriteUrl($this->aliasUrl);
|
||||
$request->setRewriteUrl($rewrite);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,43 +4,36 @@ class ResourceController implements \Pecee\Controllers\IResourceController
|
||||
|
||||
public function index() : ?string
|
||||
{
|
||||
echo 'index';
|
||||
return null;
|
||||
return 'index';
|
||||
}
|
||||
|
||||
public function show($id) : ?string
|
||||
{
|
||||
echo 'show ' . $id;
|
||||
return null;
|
||||
return 'show ' . $id;
|
||||
}
|
||||
|
||||
public function store() : ?string
|
||||
{
|
||||
echo 'store';
|
||||
return null;
|
||||
return 'store';
|
||||
}
|
||||
|
||||
public function create() : ?string
|
||||
{
|
||||
echo 'create';
|
||||
return null;
|
||||
return 'create';
|
||||
}
|
||||
|
||||
public function edit($id) : ?string
|
||||
{
|
||||
echo 'edit ' . $id;
|
||||
return null;
|
||||
return 'edit ' . $id;
|
||||
}
|
||||
|
||||
public function update($id) : ?string
|
||||
{
|
||||
echo 'update ' . $id;
|
||||
return null;
|
||||
return 'update ' . $id;
|
||||
}
|
||||
|
||||
public function destroy($id) : ?string
|
||||
{
|
||||
echo 'destroy ' . $id;
|
||||
return null;
|
||||
return 'destroy ' . $id;
|
||||
}
|
||||
}
|
||||
@@ -50,8 +50,8 @@ class EventHandlerTest extends \PHPUnit\Framework\TestCase
|
||||
|
||||
// Add boot-manager
|
||||
TestRouter::addBootManager(new TestBootManager([
|
||||
'/test',
|
||||
], '/'));
|
||||
'/test' => '/',
|
||||
]));
|
||||
|
||||
// Start router
|
||||
TestRouter::debug('/non-existing');
|
||||
@@ -61,7 +61,6 @@ class EventHandlerTest extends \PHPUnit\Framework\TestCase
|
||||
|
||||
public function testAllEvent()
|
||||
{
|
||||
|
||||
$status = false;
|
||||
|
||||
$eventHandler = new EventHandler();
|
||||
|
||||
@@ -1,28 +1,44 @@
|
||||
<?php
|
||||
|
||||
use Pecee\Http\Input\InputFile;
|
||||
|
||||
require_once 'Dummy/DummyMiddleware.php';
|
||||
require_once 'Dummy/DummyController.php';
|
||||
require_once 'Dummy/Handler/ExceptionHandler.php';
|
||||
|
||||
class InputHandlerTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
protected $names = [
|
||||
'Lester',
|
||||
'Michael',
|
||||
'Franklin',
|
||||
'Trevor',
|
||||
];
|
||||
|
||||
protected $brands = [
|
||||
'Samsung',
|
||||
'Apple',
|
||||
'HP',
|
||||
'Canon',
|
||||
];
|
||||
|
||||
protected $sodas = [
|
||||
0 => 'Pepsi',
|
||||
1 => 'Coca Cola',
|
||||
2 => 'Harboe',
|
||||
3 => 'Mountain Dew',
|
||||
];
|
||||
|
||||
protected $day = 'monday';
|
||||
|
||||
public function testPost()
|
||||
{
|
||||
global $_POST;
|
||||
|
||||
$names = [
|
||||
'Lester',
|
||||
'Michael',
|
||||
'Franklin',
|
||||
'Trevor',
|
||||
];
|
||||
|
||||
$day = 'monday';
|
||||
|
||||
$_POST = [
|
||||
'names' => $names,
|
||||
'day' => $day,
|
||||
'names' => $this->names,
|
||||
'day' => $this->day,
|
||||
'sodas' => $this->sodas,
|
||||
];
|
||||
|
||||
$router = TestRouter::router();
|
||||
@@ -31,29 +47,34 @@ class InputHandlerTest extends \PHPUnit\Framework\TestCase
|
||||
|
||||
$handler = TestRouter::request()->getInputHandler();
|
||||
|
||||
$this->assertEquals($names, $handler->value('names'));
|
||||
$this->assertEquals($names, $handler->all(['names'])['names']);
|
||||
$this->assertEquals($day, $handler->value('day'));
|
||||
$this->assertEquals($this->names, $handler->value('names'));
|
||||
$this->assertEquals($this->names, $handler->all(['names'])['names']);
|
||||
$this->assertEquals($this->day, $handler->value('day'));
|
||||
$this->assertInstanceOf(\Pecee\Http\Input\InputItem::class, $handler->find('day'));
|
||||
$this->assertInstanceOf(\Pecee\Http\Input\InputItem::class, $handler->post('day'));
|
||||
$this->assertInstanceOf(\Pecee\Http\Input\InputItem::class, $handler->find('day', 'post'));
|
||||
|
||||
// Check non-existing and wrong request-type
|
||||
$this->assertEmpty($handler->all(['non-existing']));
|
||||
$this->assertCount(1, $handler->all(['non-existing']));
|
||||
$this->assertEmpty($handler->all(['non-existing'])['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'));
|
||||
$this->assertEquals($this->sodas, $handler->value('sodas'));
|
||||
|
||||
$objects = $handler->find('names');
|
||||
|
||||
$this->assertInstanceOf(\Pecee\Http\Input\InputItem::class, $objects);
|
||||
$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());
|
||||
$this->assertEquals($this->names[$i], $object->getValue());
|
||||
}
|
||||
|
||||
// Reset
|
||||
$_POST = [];
|
||||
}
|
||||
|
||||
@@ -61,18 +82,9 @@ class InputHandlerTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
global $_GET;
|
||||
|
||||
$names = [
|
||||
'Lester',
|
||||
'Michael',
|
||||
'Franklin',
|
||||
'Trevor',
|
||||
];
|
||||
|
||||
$day = 'monday';
|
||||
|
||||
$_GET = [
|
||||
'names' => $names,
|
||||
'day' => $day,
|
||||
'names' => $this->names,
|
||||
'day' => $this->day,
|
||||
];
|
||||
|
||||
$router = TestRouter::router();
|
||||
@@ -81,14 +93,15 @@ class InputHandlerTest extends \PHPUnit\Framework\TestCase
|
||||
|
||||
$handler = TestRouter::request()->getInputHandler();
|
||||
|
||||
$this->assertEquals($names, $handler->value('names'));
|
||||
$this->assertEquals($names, $handler->all(['names'])['names']);
|
||||
$this->assertEquals($day, $handler->value('day'));
|
||||
$this->assertEquals($this->names, $handler->value('names'));
|
||||
$this->assertEquals($this->names, $handler->all(['names'])['names']);
|
||||
$this->assertEquals($this->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->assertCount(1, $handler->all(['non-existing']));
|
||||
$this->assertEmpty($handler->all(['non-existing'])['non-existing']);
|
||||
$this->assertNull($handler->value('non-existing'));
|
||||
$this->assertNull($handler->find('non-existing'));
|
||||
$this->assertNull($handler->value('names', null, 'post'));
|
||||
@@ -96,30 +109,166 @@ class InputHandlerTest extends \PHPUnit\Framework\TestCase
|
||||
|
||||
$objects = $handler->find('names');
|
||||
|
||||
$this->assertInstanceOf(\Pecee\Http\Input\InputItem::class, $objects);
|
||||
$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());
|
||||
$this->assertEquals($this->names[$i], $object->getValue());
|
||||
}
|
||||
|
||||
// Reset
|
||||
$_GET = [];
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function testFile()
|
||||
{
|
||||
$this->assertEquals(true, true);
|
||||
global $_FILES;
|
||||
|
||||
$testFile = $this->generateFile();
|
||||
|
||||
$_FILES = [
|
||||
'test_input' => $testFile,
|
||||
];
|
||||
|
||||
$router = TestRouter::router();
|
||||
$router->reset();
|
||||
$router->getRequest()->setMethod('post');
|
||||
$inputHandler = TestRouter::request()->getInputHandler();
|
||||
|
||||
$testFileContent = md5(uniqid('test', false));
|
||||
|
||||
$file = $inputHandler->file('test_input');
|
||||
|
||||
$this->assertInstanceOf(InputFile::class, $file);
|
||||
$this->assertEquals($testFile['name'], $file->getFilename());
|
||||
$this->assertEquals($testFile['type'], $file->getType());
|
||||
$this->assertEquals($testFile['tmp_name'], $file->getTmpName());
|
||||
$this->assertEquals($testFile['error'], $file->getError());
|
||||
$this->assertEquals($testFile['size'], $file->getSize());
|
||||
$this->assertEquals(pathinfo($testFile['name'], PATHINFO_EXTENSION), $file->getExtension());
|
||||
|
||||
file_put_contents($testFile['tmp_name'], $testFileContent);
|
||||
$this->assertEquals($testFileContent, $file->getContents());
|
||||
|
||||
// Cleanup
|
||||
unlink($testFile['tmp_name']);
|
||||
}
|
||||
|
||||
public function testFiles()
|
||||
public function testFilesArray()
|
||||
{
|
||||
$this->assertEquals(true, true);
|
||||
global $_FILES;
|
||||
|
||||
$testFiles = [
|
||||
$file = $this->generateFile(),
|
||||
$file = $this->generateFile(),
|
||||
$file = $this->generateFile(),
|
||||
$file = $this->generateFile(),
|
||||
$file = $this->generateFile(),
|
||||
];
|
||||
|
||||
$_FILES = [
|
||||
'my_files' => $testFiles,
|
||||
];
|
||||
|
||||
$router = TestRouter::router();
|
||||
$router->reset();
|
||||
$router->getRequest()->setMethod('post');
|
||||
$inputHandler = TestRouter::request()->getInputHandler();
|
||||
|
||||
$files = $inputHandler->file('my_files');
|
||||
$this->assertCount(5, $files);
|
||||
|
||||
/* @var $file InputFile */
|
||||
foreach ($files as $key => $file) {
|
||||
|
||||
$testFileContent = md5(uniqid('test', false));
|
||||
|
||||
$this->assertInstanceOf(InputFile::class, $file);
|
||||
$this->assertEquals($testFiles[$key]['name'], $file->getFilename());
|
||||
$this->assertEquals($testFiles[$key]['type'], $file->getType());
|
||||
$this->assertEquals($testFiles[$key]['tmp_name'], $file->getTmpName());
|
||||
$this->assertEquals($testFiles[$key]['error'], $file->getError());
|
||||
$this->assertEquals($testFiles[$key]['size'], $file->getSize());
|
||||
$this->assertEquals(pathinfo($testFiles[$key]['name'], PATHINFO_EXTENSION), $file->getExtension());
|
||||
|
||||
file_put_contents($testFiles[$key]['tmp_name'], $testFileContent);
|
||||
|
||||
$this->assertEquals($testFileContent, $file->getContents());
|
||||
|
||||
// Cleanup
|
||||
unlink($testFiles[$key]['tmp_name']);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function testAll()
|
||||
{
|
||||
$this->assertEquals(true, true);
|
||||
global $_POST;
|
||||
global $_GET;
|
||||
|
||||
$_POST = [
|
||||
'names' => $this->names,
|
||||
'is_sad' => true,
|
||||
];
|
||||
|
||||
$_GET = [
|
||||
'brands' => $this->brands,
|
||||
'is_happy' => true,
|
||||
];
|
||||
|
||||
$router = TestRouter::router();
|
||||
$router->reset();
|
||||
$router->getRequest()->setMethod('post');
|
||||
|
||||
$handler = TestRouter::request()->getInputHandler();
|
||||
|
||||
// GET
|
||||
$brandsFound = $handler->all(['brands', 'nothing']);
|
||||
|
||||
$this->assertArrayHasKey('brands', $brandsFound);
|
||||
$this->assertArrayHasKey('nothing', $brandsFound);
|
||||
$this->assertEquals($this->brands, $brandsFound['brands']);
|
||||
$this->assertNull($brandsFound['nothing']);
|
||||
|
||||
// POST
|
||||
$namesFound = $handler->all(['names', 'nothing']);
|
||||
|
||||
$this->assertArrayHasKey('names', $namesFound);
|
||||
$this->assertArrayHasKey('nothing', $namesFound);
|
||||
$this->assertEquals($this->names, $namesFound['names']);
|
||||
$this->assertNull($namesFound['nothing']);
|
||||
|
||||
// DEFAULT VALUE
|
||||
$nonExisting = $handler->all([
|
||||
'non-existing'
|
||||
]);
|
||||
|
||||
$this->assertArrayHasKey('non-existing', $nonExisting);
|
||||
$this->assertNull($nonExisting['non-existing']);
|
||||
|
||||
// Reset
|
||||
$_GET = [];
|
||||
$_POST = [];
|
||||
}
|
||||
|
||||
protected function generateFile()
|
||||
{
|
||||
return [
|
||||
'name' => uniqid('', false) . '.txt',
|
||||
'type' => 'text/plain',
|
||||
'tmp_name' => sys_get_temp_dir() . '/phpYfWUiw',
|
||||
'error' => 0,
|
||||
'size' => rand(3, 40),
|
||||
];
|
||||
}
|
||||
|
||||
protected function generateFileContent()
|
||||
{
|
||||
return md5(uniqid('', false));
|
||||
}
|
||||
|
||||
}
|
||||
84
tests/Pecee/SimpleRouter/RequestTest.php
Normal file
84
tests/Pecee/SimpleRouter/RequestTest.php
Normal file
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
use Pecee\Http\Input\InputFile;
|
||||
|
||||
require_once 'Dummy/DummyMiddleware.php';
|
||||
require_once 'Dummy/DummyController.php';
|
||||
require_once 'Dummy/Handler/ExceptionHandler.php';
|
||||
|
||||
class RequestTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
|
||||
protected function processHeader($name, $value, callable $callback)
|
||||
{
|
||||
global $_SERVER;
|
||||
|
||||
$_SERVER[$name] = $value;
|
||||
|
||||
$router = TestRouter::router();
|
||||
$router->reset();
|
||||
|
||||
$request = $router->getRequest();
|
||||
|
||||
$callback($request);
|
||||
|
||||
// Reset everything
|
||||
$_SERVER[$name] = null;
|
||||
$router->reset();
|
||||
}
|
||||
|
||||
public function testContentTypeParse()
|
||||
{
|
||||
global $_SERVER;
|
||||
|
||||
// Test normal content-type
|
||||
|
||||
$contentType = 'application/x-www-form-urlencoded';
|
||||
|
||||
$this->processHeader('content_type', $contentType, function(\Pecee\Http\Request $request) use($contentType) {
|
||||
$this->assertEquals($contentType, $request->getContentType());
|
||||
});
|
||||
|
||||
// Test special content-type with encoding
|
||||
|
||||
$contentTypeWithEncoding = 'application/x-www-form-urlencoded; charset=UTF-8';
|
||||
|
||||
$this->processHeader('content_type', $contentTypeWithEncoding, function(\Pecee\Http\Request $request) use($contentType) {
|
||||
$this->assertEquals($contentType, $request->getContentType());
|
||||
});
|
||||
}
|
||||
|
||||
public function testGetIp()
|
||||
{
|
||||
$ip = '1.1.1.1';
|
||||
$this->processHeader('remote_addr', $ip, function(\Pecee\Http\Request $request) use($ip) {
|
||||
$this->assertEquals($ip, $request->getIp());
|
||||
});
|
||||
|
||||
$ip = '2.2.2.2';
|
||||
$this->processHeader('http-cf-connecting-ip', $ip, function(\Pecee\Http\Request $request) use($ip) {
|
||||
$this->assertEquals($ip, $request->getIp());
|
||||
});
|
||||
|
||||
$ip = '3.3.3.3';
|
||||
$this->processHeader('http-client-ip', $ip, function(\Pecee\Http\Request $request) use($ip) {
|
||||
$this->assertEquals($ip, $request->getIp());
|
||||
});
|
||||
|
||||
$ip = '4.4.4.4';
|
||||
$this->processHeader('http-x-forwarded-for', $ip, function(\Pecee\Http\Request $request) use($ip) {
|
||||
$this->assertEquals($ip, $request->getIp());
|
||||
});
|
||||
|
||||
// Test safe
|
||||
|
||||
$ip = '5.5.5.5';
|
||||
$this->processHeader('http-x-forwarded-for', $ip, function(\Pecee\Http\Request $request) {
|
||||
$this->assertEquals(null, $request->getIp(true));
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// TODO: implement more test-cases
|
||||
|
||||
}
|
||||
@@ -25,4 +25,49 @@ class RouterPartialGroupTest extends \PHPUnit\Framework\TestCase
|
||||
$this->assertEquals('param2', $result2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fixed issue with partial routes not loading child groups.
|
||||
* Reported in issue: #456
|
||||
*/
|
||||
public function testPartialGroupWithGroup() {
|
||||
|
||||
$lang = null;
|
||||
|
||||
$route1 = '/lang/da/test/';
|
||||
$route2 = '/lang/da/auth';
|
||||
$route3 = '/lang/da/auth/test';
|
||||
|
||||
TestRouter::partialGroup(
|
||||
'/lang/{test}/',
|
||||
function ($lang = 'en') use($route1, $route2, $route3) {
|
||||
|
||||
TestRouter::get('/test/', function () use($route1) {
|
||||
return $route1;
|
||||
});
|
||||
|
||||
TestRouter::group(['prefix' => '/auth/'], function () use($route2, $route3) {
|
||||
|
||||
TestRouter::get('/', function() use($route2) {
|
||||
return $route2;
|
||||
});
|
||||
|
||||
TestRouter::get('/test', function () use($route3){
|
||||
return $route3;
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
$test1 = TestRouter::debugOutput('/lang/da/test', 'get', false);
|
||||
$test2 = TestRouter::debugOutput('/lang/da/auth', 'get', false);
|
||||
$test3 = TestRouter::debugOutput('/lang/da/auth/test', 'get', false);
|
||||
|
||||
$this->assertEquals($test1, $route1);
|
||||
$this->assertEquals($test2, $route2);
|
||||
$this->assertEquals($test3, $route3);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,7 +6,7 @@ require_once 'Dummy/Handler/ExceptionHandlerSecond.php';
|
||||
require_once 'Dummy/Handler/ExceptionHandlerThird.php';
|
||||
require_once 'Dummy/Middleware/RewriteMiddleware.php';
|
||||
|
||||
class RouteRewriteTest extends \PHPUnit\Framework\TestCase
|
||||
class RouterRewriteTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
|
||||
/**
|
||||
|
||||
@@ -101,12 +101,48 @@ class RouterRouteTest extends \PHPUnit\Framework\TestCase
|
||||
|
||||
public function testPathParamRegex()
|
||||
{
|
||||
TestRouter::get('/{lang}/productscategories/{name}', 'DummyController@param', ['where' => ['lang' => '[a-z]+', 'name' => '[A-Za-z0-9\-]+']]);
|
||||
TestRouter::get('/{lang}/productscategories/{name}', 'DummyController@param', ['where' => ['lang' => '[a-z]+', 'name' => '[A-Za-z0-9-]+']]);
|
||||
$response = TestRouter::debugOutput('/it/productscategories/system', 'get');
|
||||
|
||||
$this->assertEquals('it, system', $response);
|
||||
}
|
||||
|
||||
public function testFixedDomain()
|
||||
{
|
||||
$result = false;
|
||||
TestRouter::request()->setHost('admin.world.com');
|
||||
|
||||
TestRouter::group(['domain' => 'admin.world.com'], function () use (&$result) {
|
||||
TestRouter::get('/test', function ($subdomain = null) use (&$result) {
|
||||
$result = true;
|
||||
});
|
||||
});
|
||||
|
||||
TestRouter::debug('/test', 'get');
|
||||
|
||||
$this->assertTrue($result);
|
||||
}
|
||||
|
||||
public function testFixedNotAllowedDomain()
|
||||
{
|
||||
$result = false;
|
||||
TestRouter::request()->setHost('other.world.com');
|
||||
|
||||
TestRouter::group(['domain' => 'admin.world.com'], function () use (&$result) {
|
||||
TestRouter::get('/', function ($subdomain = null) use (&$result) {
|
||||
$result = true;
|
||||
});
|
||||
});
|
||||
|
||||
try {
|
||||
TestRouter::debug('/', 'get');
|
||||
} catch(\Exception $e) {
|
||||
|
||||
}
|
||||
|
||||
$this->assertFalse($result);
|
||||
}
|
||||
|
||||
public function testDomainAllowedRoute()
|
||||
{
|
||||
$result = false;
|
||||
@@ -144,12 +180,27 @@ class RouterRouteTest extends \PHPUnit\Framework\TestCase
|
||||
|
||||
public function testRegEx()
|
||||
{
|
||||
TestRouter::get('/my/{path}', 'DummyController@method1')->where(['path' => '[a-zA-Z\-]+']);
|
||||
TestRouter::get('/my/{path}', 'DummyController@method1')->where(['path' => '[a-zA-Z-]+']);
|
||||
TestRouter::debug('/my/custom-path', 'get');
|
||||
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
|
||||
public function testParametersWithDashes()
|
||||
{
|
||||
|
||||
$defaultVariable = null;
|
||||
|
||||
TestRouter::get('/my/{path}', function ($path = 'working') use (&$defaultVariable) {
|
||||
$defaultVariable = $path;
|
||||
});
|
||||
|
||||
TestRouter::debug('/my/hello-motto-man');
|
||||
|
||||
$this->assertEquals('hello-motto-man', $defaultVariable);
|
||||
|
||||
}
|
||||
|
||||
public function testParameterDefaultValue()
|
||||
{
|
||||
|
||||
@@ -167,7 +218,7 @@ class RouterRouteTest extends \PHPUnit\Framework\TestCase
|
||||
|
||||
public function testDefaultParameterRegex()
|
||||
{
|
||||
TestRouter::get('/my/{path}', 'DummyController@param', ['defaultParameterRegex' => '[\w\-]+']);
|
||||
TestRouter::get('/my/{path}', 'DummyController@param', ['defaultParameterRegex' => '[\w-]+']);
|
||||
$output = TestRouter::debugOutput('/my/custom-regex', 'get');
|
||||
|
||||
$this->assertEquals('custom-regex', $output);
|
||||
@@ -175,7 +226,7 @@ class RouterRouteTest extends \PHPUnit\Framework\TestCase
|
||||
|
||||
public function testDefaultParameterRegexGroup()
|
||||
{
|
||||
TestRouter::group(['defaultParameterRegex' => '[\w\-]+'], function () {
|
||||
TestRouter::group(['defaultParameterRegex' => '[\w-]+'], function () {
|
||||
TestRouter::get('/my/{path}', 'DummyController@param');
|
||||
});
|
||||
|
||||
@@ -184,4 +235,26 @@ class RouterRouteTest extends \PHPUnit\Framework\TestCase
|
||||
$this->assertEquals('custom-regex', $output);
|
||||
}
|
||||
|
||||
public function testClassHint()
|
||||
{
|
||||
TestRouter::get('/my/test/url', ['DummyController', 'method1']);
|
||||
TestRouter::all('/my/test/url', ['DummyController', 'method1']);
|
||||
TestRouter::match(['put', 'get', 'post'], '/my/test/url', ['DummyController', 'method1']);
|
||||
|
||||
TestRouter::debug('/my/test/url', 'get');
|
||||
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
|
||||
public function testSameRoutes()
|
||||
{
|
||||
TestRouter::get('/recipe', 'DummyController@method1')->name('add');
|
||||
TestRouter::post('/recipe', 'DummyController@method2')->name('edit');
|
||||
|
||||
TestRouter::debugNoReset('/recipe', 'post');
|
||||
TestRouter::debug('/recipe', 'get');
|
||||
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,7 +11,7 @@ class RouterUrlTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
TestRouter::get('/', 'DummyController@method1');
|
||||
TestRouter::get('/page/{id?}', 'DummyController@method1');
|
||||
TestRouter::get('/test-output', function() {
|
||||
TestRouter::get('/test-output', function () {
|
||||
return 'return value';
|
||||
});
|
||||
|
||||
@@ -30,8 +30,8 @@ class RouterUrlTest extends \PHPUnit\Framework\TestCase
|
||||
public function testUnicodeCharacters()
|
||||
{
|
||||
// Test spanish characters
|
||||
TestRouter::get('/cursos/listado/{listado?}/{category?}', 'DummyController@method1', ['defaultParameterRegex' => '[\w\p{L}\s-]+']);
|
||||
TestRouter::get('/test/{param}', 'DummyController@method1', ['defaultParameterRegex' => '[\w\p{L}\s-\í]+']);
|
||||
TestRouter::get('/cursos/listado/{listado?}/{category?}', 'DummyController@method1', ['defaultParameterRegex' => '[\w\p{L}\s\-]+']);
|
||||
TestRouter::get('/test/{param}', 'DummyController@method1', ['defaultParameterRegex' => '[\w\p{L}\s\-\í]+']);
|
||||
TestRouter::debugNoReset('/cursos/listado/especialidad/cirugía local', 'get');
|
||||
|
||||
$this->assertEquals('/cursos/listado/{listado?}/{category?}/', TestRouter::router()->getRequest()->getLoadedRoute()->getUrl());
|
||||
@@ -78,10 +78,11 @@ class RouterUrlTest extends \PHPUnit\Framework\TestCase
|
||||
public function testSimilarUrls()
|
||||
{
|
||||
// Match normal route on alias
|
||||
TestRouter::resource('/url11', 'DummyController@method1');
|
||||
TestRouter::resource('/url1', 'DummyController@method1', ['as' => 'match']);
|
||||
TestRouter::get('/url11', 'DummyController@method1');
|
||||
TestRouter::get('/url22', 'DummyController@method2');
|
||||
TestRouter::get('/url33', 'DummyController@method2')->name('match');
|
||||
|
||||
TestRouter::debugNoReset('/url1', 'get');
|
||||
TestRouter::debugNoReset('/url33', 'get');
|
||||
|
||||
$this->assertEquals(TestRouter::getUrl('match'), TestRouter::getUrl());
|
||||
|
||||
@@ -170,4 +171,104 @@ class RouterUrlTest extends \PHPUnit\Framework\TestCase
|
||||
|
||||
}
|
||||
|
||||
public function testCustomRegex()
|
||||
{
|
||||
TestRouter::request()->setHost('google.com');
|
||||
|
||||
TestRouter::get('/admin/', function () {
|
||||
return 'match';
|
||||
})->setMatch('/^\/admin\/?(.*)/i');
|
||||
|
||||
$output = TestRouter::debugOutput('/admin/asd/bec/123', 'get');
|
||||
$this->assertEquals('match', $output);
|
||||
}
|
||||
|
||||
public function testRenderMultipleRoutesDisabled()
|
||||
{
|
||||
TestRouter::router()->setRenderMultipleRoutes(false);
|
||||
|
||||
$result = false;
|
||||
|
||||
TestRouter::get('/', function () use (&$result) {
|
||||
$result = true;
|
||||
});
|
||||
|
||||
TestRouter::get('/', function () use (&$result) {
|
||||
$result = false;
|
||||
});
|
||||
|
||||
TestRouter::debug('/');
|
||||
|
||||
$this->assertTrue($result);
|
||||
}
|
||||
|
||||
public function testRenderMultipleRoutesEnabled()
|
||||
{
|
||||
TestRouter::router()->setRenderMultipleRoutes(true);
|
||||
|
||||
$result = [];
|
||||
|
||||
TestRouter::get('/', function () use (&$result) {
|
||||
$result[] = 'route1';
|
||||
});
|
||||
|
||||
TestRouter::get('/', function () use (&$result) {
|
||||
$result[] = 'route2';
|
||||
});
|
||||
|
||||
TestRouter::debug('/');
|
||||
|
||||
$this->assertCount(2, $result);
|
||||
}
|
||||
|
||||
public function testDefaultNamespace()
|
||||
{
|
||||
TestRouter::setDefaultNamespace('\\Default\\Namespace');
|
||||
|
||||
TestRouter::get('/', 'DummyController@method1', ['as' => 'home']);
|
||||
|
||||
TestRouter::group([
|
||||
'namespace' => 'Appended\Namespace',
|
||||
'prefix' => '/horses',
|
||||
], function () {
|
||||
|
||||
TestRouter::get('/', 'DummyController@method1');
|
||||
|
||||
TestRouter::group([
|
||||
'namespace' => '\\New\\Namespace',
|
||||
'prefix' => '/race',
|
||||
], function () {
|
||||
|
||||
TestRouter::get('/', 'DummyController@method1');
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
// Test appended namespace
|
||||
|
||||
$class = null;
|
||||
|
||||
try {
|
||||
TestRouter::debugNoReset('/horses/');
|
||||
} catch (\Pecee\SimpleRouter\Exceptions\ClassNotFoundHttpException $e) {
|
||||
$class = $e->getClass();
|
||||
}
|
||||
|
||||
$this->assertEquals('\\Default\\Namespace\\Appended\Namespace\\DummyController', $class);
|
||||
|
||||
// Test overwritten namespace
|
||||
|
||||
$class = null;
|
||||
|
||||
try {
|
||||
TestRouter::debugNoReset('/horses/race');
|
||||
} catch (\Pecee\SimpleRouter\Exceptions\ClassNotFoundHttpException $e) {
|
||||
$class = $e->getClass();
|
||||
}
|
||||
|
||||
$this->assertEquals('\\New\\Namespace\\DummyController', $class);
|
||||
|
||||
TestRouter::router()->reset();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,6 +3,11 @@
|
||||
class TestRouter extends \Pecee\SimpleRouter\SimpleRouter
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
static::request()->setHost('testhost.com');
|
||||
}
|
||||
|
||||
public static function debugNoReset($testUrl, $testMethod = 'get')
|
||||
{
|
||||
$request = static::request();
|
||||
@@ -13,7 +18,7 @@ class TestRouter extends \Pecee\SimpleRouter\SimpleRouter
|
||||
static::start();
|
||||
}
|
||||
|
||||
public static function debug($testUrl, $testMethod = 'get')
|
||||
public static function debug($testUrl, $testMethod = 'get', bool $reset = true)
|
||||
{
|
||||
try {
|
||||
static::debugNoReset($testUrl, $testMethod);
|
||||
@@ -22,19 +27,20 @@ class TestRouter extends \Pecee\SimpleRouter\SimpleRouter
|
||||
throw $e;
|
||||
}
|
||||
|
||||
static::router()->reset();
|
||||
if($reset === true) {
|
||||
static::router()->reset();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static function debugOutput($testUrl, $testMethod = 'get')
|
||||
public static function debugOutput($testUrl, $testMethod = 'get', bool $reset = true)
|
||||
{
|
||||
$response = null;
|
||||
|
||||
// Route request
|
||||
ob_start();
|
||||
static::debug($testUrl, $testMethod);
|
||||
$response = ob_get_contents();
|
||||
ob_end_clean();
|
||||
static::debug($testUrl, $testMethod, $reset);
|
||||
$response = ob_get_clean();
|
||||
|
||||
// Return response
|
||||
return $response;
|
||||
|
||||
Reference in New Issue
Block a user