├── .github └── workflows │ └── build.yml ├── .gitignore ├── .ncurc.json ├── .npmrc ├── .vscode └── launch.json ├── Dockerfile ├── Gruntfile.js ├── INSTALL.md ├── LICENSE ├── README.md ├── _config.yml ├── artifacts ├── config.ini ├── config.windows.ini ├── gitlist.patrikx3.com.conf ├── php-7.2-ubuntu.md ├── screenshots.md └── screenshots │ ├── p3x-gitlist-1.jpeg │ ├── p3x-gitlist-2.jpeg │ ├── p3x-gitlist-3.jpeg │ ├── p3x-gitlist-4.jpeg │ ├── p3x-gitlist-5.jpeg │ ├── p3x-gitlist-6.jpeg │ └── p3x-gitlist-7.jpeg ├── boot.php ├── change-break.md ├── change-log.md ├── composer.json ├── composer.lock ├── config.docker.ini ├── config.example.ini ├── docker-compose.yml ├── package.json ├── phpunit.xml ├── public ├── .htaccess ├── img │ ├── favicon.png │ └── gitlist.svg ├── index.php └── web.config ├── scripts ├── build.sh ├── init.cmd ├── init.sh ├── optimize.sh ├── release.sh ├── web.config └── www-git-optimize.sh ├── src ├── GitList │ ├── Application.php │ ├── Config.php │ ├── Controller │ │ ├── BlobController.php │ │ ├── CommitController.php │ │ ├── GitController.php │ │ ├── MainController.php │ │ ├── NetworkController.php │ │ ├── TreeController.php │ │ └── TreeGraphController.php │ ├── Escaper │ │ └── ArgumentEscaper.php │ ├── Exception │ │ ├── BlankDataException.php │ │ └── EmptyRepositoryException.php │ ├── Provider │ │ ├── GitServiceProvider.php │ │ ├── RepositoryUtilServiceProvider.php │ │ ├── RoutingUtilServiceProvider.php │ │ └── ViewUtilServiceProvider.php │ └── Util │ │ ├── Repository.php │ │ ├── Routing.php │ │ └── View.php ├── Gitter │ ├── Client.php │ ├── Model │ │ ├── AbstractModel.php │ │ ├── Blob.php │ │ ├── Branch.php │ │ ├── Commit │ │ │ ├── Author.php │ │ │ ├── Commit.php │ │ │ ├── Diff.php │ │ │ └── DiffLine.php │ │ ├── File.php │ │ ├── Item.php │ │ ├── Line.php │ │ ├── Module.php │ │ ├── Symlink.php │ │ ├── Tag.php │ │ └── Tree.php │ ├── PrettyFormat.php │ ├── Repository.php │ ├── Statistics │ │ ├── Contributors.php │ │ ├── Date.php │ │ ├── Day.php │ │ ├── Hour.php │ │ └── StatisticsInterface.php │ └── Util │ │ ├── Collection.php │ │ └── DateTime.php ├── Silex │ ├── .gitignore │ ├── .php_cs.dist │ ├── LICENSE │ ├── README.rst │ ├── composer.json │ ├── doc │ │ ├── changelog.rst │ │ ├── conf.py │ │ ├── contributing.rst │ │ ├── cookbook │ │ │ ├── error_handler.rst │ │ │ ├── form_no_csrf.rst │ │ │ ├── guard_authentication.rst │ │ │ ├── index.rst │ │ │ ├── json_request_body.rst │ │ │ ├── multiple_loggers.rst │ │ │ ├── session_storage.rst │ │ │ ├── sub_requests.rst │ │ │ └── validator_yaml.rst │ │ ├── index.rst │ │ ├── internals.rst │ │ ├── intro.rst │ │ ├── middlewares.rst │ │ ├── organizing_controllers.rst │ │ ├── providers.rst │ │ ├── providers │ │ │ ├── asset.rst │ │ │ ├── csrf.rst │ │ │ ├── doctrine.rst │ │ │ ├── form.rst │ │ │ ├── http_cache.rst │ │ │ ├── http_fragment.rst │ │ │ ├── index.rst │ │ │ ├── locale.rst │ │ │ ├── monolog.rst │ │ │ ├── remember_me.rst │ │ │ ├── routing.rst │ │ │ ├── security.rst │ │ │ ├── serializer.rst │ │ │ ├── service_controller.rst │ │ │ ├── session.rst │ │ │ ├── swiftmailer.rst │ │ │ ├── translation.rst │ │ │ ├── twig.rst │ │ │ ├── validator.rst │ │ │ └── var_dumper.rst │ │ ├── services.rst │ │ ├── testing.rst │ │ ├── usage.rst │ │ └── web_servers.rst │ ├── phpunit.xml.dist │ ├── src │ │ └── Silex │ │ │ ├── Api │ │ │ ├── BootableProviderInterface.php │ │ │ ├── ControllerProviderInterface.php │ │ │ ├── EventListenerProviderInterface.php │ │ │ ├── LICENSE │ │ │ └── composer.json │ │ │ ├── AppArgumentValueResolver.php │ │ │ ├── Application.php │ │ │ ├── Application │ │ │ ├── FormTrait.php │ │ │ ├── MonologTrait.php │ │ │ ├── SecurityTrait.php │ │ │ ├── SwiftmailerTrait.php │ │ │ ├── TranslationTrait.php │ │ │ ├── TwigTrait.php │ │ │ └── UrlGeneratorTrait.php │ │ │ ├── CallbackResolver.php │ │ │ ├── Controller.php │ │ │ ├── ControllerCollection.php │ │ │ ├── EventListener │ │ │ ├── ConverterListener.php │ │ │ ├── LogListener.php │ │ │ ├── MiddlewareListener.php │ │ │ └── StringToResponseListener.php │ │ │ ├── Exception │ │ │ └── ControllerFrozenException.php │ │ │ ├── ExceptionHandler.php │ │ │ ├── ExceptionListenerWrapper.php │ │ │ ├── Provider │ │ │ ├── AssetServiceProvider.php │ │ │ ├── CsrfServiceProvider.php │ │ │ ├── DoctrineServiceProvider.php │ │ │ ├── ExceptionHandlerServiceProvider.php │ │ │ ├── Form │ │ │ │ └── SilexFormExtension.php │ │ │ ├── FormServiceProvider.php │ │ │ ├── HttpCache │ │ │ │ └── HttpCache.php │ │ │ ├── HttpCacheServiceProvider.php │ │ │ ├── HttpFragmentServiceProvider.php │ │ │ ├── HttpKernelServiceProvider.php │ │ │ ├── LICENSE │ │ │ ├── Locale │ │ │ │ └── LocaleListener.php │ │ │ ├── LocaleServiceProvider.php │ │ │ ├── MonologServiceProvider.php │ │ │ ├── RememberMeServiceProvider.php │ │ │ ├── Routing │ │ │ │ ├── LazyRequestMatcher.php │ │ │ │ └── RedirectableUrlMatcher.php │ │ │ ├── RoutingServiceProvider.php │ │ │ ├── SecurityServiceProvider.php │ │ │ ├── SerializerServiceProvider.php │ │ │ ├── ServiceControllerServiceProvider.php │ │ │ ├── Session │ │ │ │ ├── SessionListener.php │ │ │ │ └── TestSessionListener.php │ │ │ ├── SessionServiceProvider.php │ │ │ ├── SwiftmailerServiceProvider.php │ │ │ ├── TranslationServiceProvider.php │ │ │ ├── Twig │ │ │ │ └── RuntimeLoader.php │ │ │ ├── TwigServiceProvider.php │ │ │ ├── Validator │ │ │ │ └── ConstraintValidatorFactory.php │ │ │ ├── ValidatorServiceProvider.php │ │ │ ├── VarDumperServiceProvider.php │ │ │ └── composer.json │ │ │ ├── Route.php │ │ │ ├── Route │ │ │ └── SecurityTrait.php │ │ │ ├── ServiceControllerResolver.php │ │ │ ├── ViewListenerWrapper.php │ │ │ └── WebTestCase.php │ └── tests │ │ └── Silex │ │ └── Tests │ │ ├── Application │ │ ├── FormApplication.php │ │ ├── FormTraitTest.php │ │ ├── MonologApplication.php │ │ ├── MonologTraitTest.php │ │ ├── SecurityApplication.php │ │ ├── SecurityTraitTest.php │ │ ├── SwiftmailerApplication.php │ │ ├── SwiftmailerTraitTest.php │ │ ├── TranslationApplication.php │ │ ├── TranslationTraitTest.php │ │ ├── TwigApplication.php │ │ ├── TwigTraitTest.php │ │ ├── UrlGeneratorApplication.php │ │ └── UrlGeneratorTraitTest.php │ │ ├── ApplicationTest.php │ │ ├── CallbackResolverTest.php │ │ ├── CallbackServicesTest.php │ │ ├── ControllerCollectionTest.php │ │ ├── ControllerTest.php │ │ ├── EventListener │ │ └── LogListenerTest.php │ │ ├── ExceptionHandlerTest.php │ │ ├── Fixtures │ │ ├── Php7Controller.php │ │ └── manifest.json │ │ ├── FunctionalTest.php │ │ ├── JsonTest.php │ │ ├── LazyDispatcherTest.php │ │ ├── LazyRequestMatcherTest.php │ │ ├── LocaleTest.php │ │ ├── MiddlewareTest.php │ │ ├── Provider │ │ ├── AssetServiceProviderTest.php │ │ ├── DoctrineServiceProviderTest.php │ │ ├── FormServiceProviderTest.php │ │ ├── FormServiceProviderTest │ │ │ └── DisableCsrfExtension.php │ │ ├── HttpCacheServiceProviderTest.php │ │ ├── HttpFragmentServiceProviderTest.php │ │ ├── MonologServiceProviderTest.php │ │ ├── RememberMeServiceProviderTest.php │ │ ├── RoutingServiceProviderTest.php │ │ ├── SecurityServiceProviderTest.php │ │ ├── SecurityServiceProviderTest │ │ │ └── TokenAuthenticator.php │ │ ├── SerializerServiceProviderTest.php │ │ ├── SessionServiceProviderTest.php │ │ ├── SpoolStub.php │ │ ├── SwiftmailerServiceProviderTest.php │ │ ├── TranslationServiceProviderTest.php │ │ ├── TwigServiceProviderTest.php │ │ ├── ValidatorServiceProviderTest.php │ │ └── ValidatorServiceProviderTest │ │ │ └── Constraint │ │ │ ├── Custom.php │ │ │ └── CustomValidator.php │ │ ├── Route │ │ ├── SecurityRoute.php │ │ └── SecurityTraitTest.php │ │ ├── RouterTest.php │ │ ├── ServiceControllerResolverRouterTest.php │ │ ├── ServiceControllerResolverTest.php │ │ ├── StreamTest.php │ │ └── WebTestCaseTest.php ├── browser │ ├── bundle.js │ ├── codemirror.js │ ├── grunt │ │ └── less.js │ ├── js │ │ ├── blame.js │ │ ├── breadcrumb.js │ │ ├── browser.js │ │ ├── change-log.js │ │ ├── clone-buttons.js │ │ ├── commit.js │ │ ├── commits-list.js │ │ ├── file-fragment.js │ │ ├── file.js │ │ ├── gitgraph.js │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── gitgraph.css │ │ │ └── gitgraph.js │ │ ├── global.js │ │ ├── global │ │ │ ├── ajax.js │ │ │ ├── cookie.js │ │ │ ├── git.js │ │ │ ├── hash.js │ │ │ ├── input.js │ │ │ ├── is-bot.js │ │ │ ├── location.js │ │ │ ├── path.js │ │ │ ├── scroll.js │ │ │ ├── snackbar.js │ │ │ └── theme.js │ │ ├── index.js │ │ ├── markdown.js │ │ ├── menu-responsive.js │ │ ├── network.js │ │ ├── paginate.js │ │ ├── settings.js │ │ ├── theme-switcher.js │ │ ├── themes.js │ │ ├── todo.js │ │ ├── tree.js │ │ ├── treegraph.js │ │ └── web-worker │ │ │ └── commit-diff.worker.js │ ├── layout.tpl.twig │ ├── less │ │ ├── blame.less │ │ ├── browser.less │ │ ├── clone-button.less │ │ ├── codemirror.less │ │ ├── commit.less │ │ ├── commits-lists.less │ │ ├── default.less │ │ ├── file-fragment.less │ │ ├── file.less │ │ ├── footer.less │ │ ├── index.less │ │ ├── list-group-striped.less │ │ ├── markdown.less │ │ ├── menu.less │ │ ├── navigation.less │ │ ├── network.less │ │ ├── overlay.less │ │ ├── pager.less │ │ ├── search.less │ │ ├── style.less │ │ ├── theme │ │ │ ├── cerulean.less │ │ │ ├── cosmo.less │ │ │ ├── cyborg.less │ │ │ ├── darkly.less │ │ │ ├── default.less │ │ │ ├── flatly.less │ │ │ ├── journal.less │ │ │ ├── lumen.less │ │ │ ├── paper.less │ │ │ ├── readable.less │ │ │ ├── sandstone.less │ │ │ ├── simplex.less │ │ │ ├── slate.less │ │ │ ├── solar.less │ │ │ ├── solar │ │ │ │ ├── bootswatch.less │ │ │ │ └── variables.less │ │ │ ├── spacelab.less │ │ │ ├── superhero.less │ │ │ ├── united.less │ │ │ └── yeti.less │ │ ├── tree.less │ │ └── treegraph.less │ ├── list.js │ ├── marked.js │ └── raphael.js ├── translation │ ├── en.json │ └── hu.json └── twig │ ├── blame.twig │ ├── breadcrumb.twig │ ├── browser.twig │ ├── commit.twig │ ├── commits-list.twig │ ├── commits.twig │ ├── error.twig │ ├── file.twig │ ├── footer.twig │ ├── index.twig │ ├── layout-page.twig │ ├── markdown.twig │ ├── menu.twig │ ├── modal │ └── modal-commit.twig │ ├── navigation.twig │ ├── network.twig │ ├── rss.twig │ ├── search.twig │ ├── searchcommits.twig │ ├── stats.twig │ ├── tree.twig │ └── treegraph.twig ├── tests ├── Gitlist │ └── RepositoryTest.php └── Gitter │ ├── ClientTest.php │ ├── Model │ └── Commit │ │ └── CommitTest.php │ ├── PrettyFormatTest.php │ ├── RepositoryTest.php │ └── Util │ └── DateTimeTest.php ├── todo.md ├── webpack.config.js └── yarn.lock /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | # This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions 3 | 4 | name: build 5 | 6 | on: 7 | schedule: 8 | - cron: '0 0 1 * *' 9 | push: 10 | branches: [ master ] 11 | pull_request: 12 | branches: [ master ] 13 | 14 | jobs: 15 | build: 16 | 17 | runs-on: ubuntu-latest 18 | 19 | strategy: 20 | matrix: 21 | node-version: ['lts/*'] 22 | #php-versions: ['8.0', '8.1'] 23 | php-versions: ['8.1'] 24 | # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ 25 | 26 | steps: 27 | - uses: actions/checkout@v2 28 | - name: Use Node.js ${{ matrix.node-version }} 29 | uses: actions/setup-node@v2 30 | with: 31 | node-version: ${{ matrix.node-version }} 32 | - run: npm i -g grunt-cli 33 | - run: yarn install 34 | - run: grunt 35 | 36 | - uses: shivammathur/setup-php@v2 37 | with: 38 | php-version: ${{ matrix.php-versions }} 39 | coverage: xdebug 40 | 41 | - name: tests 42 | run: | 43 | composer install --no-progress --ignore-platform-reqs 44 | XDEBUG_MODE=coverage ./vendor/bin/phpunit --coverage-text 45 | 46 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | cache/ 2 | vendor/ 3 | build/ 4 | *.diff 5 | *.err 6 | *.orig 7 | *.log 8 | *.rej 9 | *.swo 10 | *.swp 11 | *.zip 12 | *.vi 13 | *~ 14 | *.sass-cache 15 | .DS_Store 16 | ._* 17 | Thumbs.db 18 | .cache 19 | node_modules 20 | /config.ini 21 | /git-test 22 | /git-test2 23 | /bower_components 24 | .idea/workspace.xml 25 | .idea/tasks.xml 26 | .idea/profiles_settings.xml 27 | .idea/inspectionProfiles/Project_Default.xml 28 | .idea/inspectionProfiles/profiles_settings.xml 29 | 30 | node_modules/.yarn-integrity 31 | 32 | /public/prod 33 | /src/twig/layout.twig 34 | .phpunit.result.cache 35 | -------------------------------------------------------------------------------- /.ncurc.json: -------------------------------------------------------------------------------- 1 | { 2 | "reject": [ 3 | "jquery", 4 | "bootswatch", 5 | "bootstrap", 6 | "codemirror" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | https://registry.npmjs.org/= 2 | registry=https://registry.npmjs.org/ 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "outputCapture": "std", 9 | "type": "node", 10 | "request": "launch", 11 | "name": "npm run watch", 12 | "args": [ 13 | "run", 14 | "watch" 15 | ], 16 | "skipFiles": [ 17 | "/**" 18 | ], 19 | "cwd": "${workspaceRoot}", 20 | "program": "/usr/bin/npm" 21 | } 22 | ] 23 | } -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | #docker login 2 | #docker build -t patrikx3/p3x-gitlist . 3 | ##docker tag IMAGE_ID patrikx3/p3x-gitlist:latest 4 | #docker push patrikx3/p3x-gitlist:latest 5 | #docker tag IMAGE_ID patrikx3/p3x-gitlist:2019.10.525 6 | #docker push patrikx3/p3x-gitlist 7 | #docker images 8 | #docker rmi -f IMAGE_ID 9 | FROM ubuntu:latest 10 | MAINTAINER patrikx3/p3x-gitlist - Patrik Laszlo 11 | ENV COMPOSER_PROCESS_TIMEOUT=3600 12 | ENV DEBIAN_FRONTEND=noninteractive 13 | #ENV P3XRS_DOCKER_HOME=/settings 14 | 15 | RUN apt-get -y update 16 | RUN apt-get -y install git 17 | RUN apt-get -y install php --allow-unauthenticated 18 | RUN apt-get -y install php-fpm --allow-unauthenticated 19 | RUN apt-get -y install nginx 20 | RUN apt-get -y install curl 21 | RUN apt-get -y install git 22 | RUN apt-get -y install composer 23 | #RUN apt-get install -y build-essential 24 | 25 | # node 26 | RUN curl -sL https://deb.nodesource.com/setup_12.x | bash - 27 | RUN apt-get -y install nodejs 28 | RUN node -v 29 | 30 | 31 | ADD ./build/p3x-gitlist /gitlist 32 | 33 | 34 | RUN mkdir -p /run/php 35 | RUN echo "cgi.fix_pathinfo = 0;" >> /etc/php/7.4/fpm/php.ini 36 | RUN echo "max_input_vars = 10000;" >> /etc/php/7.4/fpm/php.ini 37 | RUN echo "max_execution_time = 10000;" >> /etc/php/7.4/fpm/php.ini 38 | RUN echo "date.timezone = Europe/Budapest;" >> /etc/php/7.4/fpm/php.ini 39 | RUN sed -i 's/;daemonize = yes/daemonize = no/g' /etc/php/7.4/fpm/php-fpm.conf 40 | 41 | RUN chown -R www-data:www-data /gitlist 42 | RUN chown -R www-data:www-data /var/git 43 | 44 | 45 | EXPOSE 12345 46 | #CMD p3x-redis 47 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-slate 2 | -------------------------------------------------------------------------------- /artifacts/screenshots/p3x-gitlist-1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrikx3/gitlist/d4fc4c225bae876675e5943adec352d3ab6b2f5f/artifacts/screenshots/p3x-gitlist-1.jpeg -------------------------------------------------------------------------------- /artifacts/screenshots/p3x-gitlist-2.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrikx3/gitlist/d4fc4c225bae876675e5943adec352d3ab6b2f5f/artifacts/screenshots/p3x-gitlist-2.jpeg -------------------------------------------------------------------------------- /artifacts/screenshots/p3x-gitlist-3.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrikx3/gitlist/d4fc4c225bae876675e5943adec352d3ab6b2f5f/artifacts/screenshots/p3x-gitlist-3.jpeg -------------------------------------------------------------------------------- /artifacts/screenshots/p3x-gitlist-4.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrikx3/gitlist/d4fc4c225bae876675e5943adec352d3ab6b2f5f/artifacts/screenshots/p3x-gitlist-4.jpeg -------------------------------------------------------------------------------- /artifacts/screenshots/p3x-gitlist-5.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrikx3/gitlist/d4fc4c225bae876675e5943adec352d3ab6b2f5f/artifacts/screenshots/p3x-gitlist-5.jpeg -------------------------------------------------------------------------------- /artifacts/screenshots/p3x-gitlist-6.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrikx3/gitlist/d4fc4c225bae876675e5943adec352d3ab6b2f5f/artifacts/screenshots/p3x-gitlist-6.jpeg -------------------------------------------------------------------------------- /artifacts/screenshots/p3x-gitlist-7.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrikx3/gitlist/d4fc4c225bae876675e5943adec352d3ab6b2f5f/artifacts/screenshots/p3x-gitlist-7.jpeg -------------------------------------------------------------------------------- /boot.php: -------------------------------------------------------------------------------- 1 | mount('', new GitList\Controller\MainController()); 9 | $app->mount('', new GitList\Controller\BlobController()); 10 | $app->mount('', new GitList\Controller\CommitController()); 11 | $app->mount('', new GitList\Controller\TreeController()); 12 | $app->mount('', new GitList\Controller\NetworkController()); 13 | $app->mount('', new GitList\Controller\TreeGraphController()); 14 | $app->mount('', new GitList\Controller\GitController()); 15 | 16 | return $app; 17 | 18 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "patrikx3/gitlist", 3 | "config": { 4 | "platform-check": false 5 | }, 6 | "description": "An elegant git repository viewer", 7 | "info": { 8 | "spatie/temporary-directory": "v2.0 only works on PHP 8 so deffered" 9 | }, 10 | "minimum-stability": "stable", 11 | "autoload": { 12 | "psr-4": { 13 | "GitList\\": "src/GitList", 14 | "Gitter\\": "src/Gitter", 15 | "Silex\\": "src/Silex/src/Silex" 16 | } 17 | }, 18 | "require": { 19 | "php": ">=7.1.0", 20 | "pimple/pimple": ">=3.4.0", 21 | "symfony/event-dispatcher": ">=5.3.7", 22 | "symfony/http-foundation": ">=5.3.7", 23 | "symfony/http-kernel": ">=5.3.7", 24 | "symfony/routing": ">=5.3.7", 25 | "symfony/filesystem": ">=5.3.4", 26 | "symfony/twig-bridge": ">=5.3.7", 27 | "twig/twig": ">=3.3.2", 28 | "danielstjules/stringy": ">=3.1.0", 29 | "symfony/mime": ">=5.3", 30 | "symfony/process": ">=5.3", 31 | "spatie/temporary-directory": "^1.3.0" 32 | }, 33 | "require-dev": { 34 | "symfony/filesystem": ">=4", 35 | "mockery/mockery": ">=1", 36 | "symfony/browser-kit": ">=4", 37 | "phpunit/phpunit": ">=7", 38 | "symfony/css-selector": ">=4", 39 | "phpspec/prophecy-phpunit": ">=2" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | # docker-compose up 2 | registry: 3 | image: patrikx3/p3x-gitlist:latest 4 | ports: 5 | - 12345:80 6 | volumes: 7 | # here you can set your own /home/user/p3x-gitlist/git folder 8 | - /home/user/p3x-gitlist/git:/var/git 9 | 10 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ./src/ 6 | 7 | 8 | 9 | 10 | ./tests/ 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /public/.htaccess: -------------------------------------------------------------------------------- 1 | 2 | Options -MultiViews +SymLinksIfOwnerMatch 3 | 4 | RewriteEngine On 5 | #RewriteBase /path/to/gitlist/ 6 | 7 | RewriteCond %{REQUEST_FILENAME} !-f 8 | RewriteCond %{REQUEST_FILENAME} !-d 9 | RewriteRule ^(.*)$ index.php/$1 [L,NC] 10 | 11 | 12 | order allow,deny 13 | deny from all 14 | 15 | -------------------------------------------------------------------------------- /public/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrikx3/gitlist/d4fc4c225bae876675e5943adec352d3ab6b2f5f/public/img/favicon.png -------------------------------------------------------------------------------- /public/index.php: -------------------------------------------------------------------------------- 1 | get('date', 'timezone')) { 28 | date_default_timezone_set($config->get('date', 'timezone')); 29 | } 30 | 31 | $app = require '../boot.php'; 32 | $app->run(); 33 | 34 | -------------------------------------------------------------------------------- /scripts/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 3 | TOP=$DIR/.. 4 | 5 | set -e 6 | 7 | version=$( node -e "console.log(require('$TOP/package.json').version)" ) 8 | pkg_name=$( node -e "console.log(require('$TOP/package.json').name)" ) 9 | name=$pkg_name 10 | repo=$TOP/build/$name 11 | 12 | pushd $TOP 13 | yarn install 14 | composer install --no-dev 15 | composer dump-autoload --optimize 16 | mkdir -p $TOP/cache 17 | #npm install 18 | npm run build 19 | 20 | rm -rf $repo || true 21 | mkdir -p $repo 22 | 23 | for item in "$TOP/cache" "$TOP/src" "$TOP/public" "$TOP/vendor" 24 | do 25 | echo $item 26 | cp -R $item $repo/ 27 | done 28 | 29 | for item in "$TOP/INSTALL.md" "$TOP/change-log.md" "$TOP/LICENSE" "$TOP/README.md" "$TOP/boot.php" "$TOP/config.example.ini" "$TOP/package.json" 30 | do 31 | echo $item 32 | cp $item $repo/ 33 | done 34 | 35 | rm -rf $repo/src/browser 36 | 37 | cp config.docker.ini $repo/config.ini 38 | 39 | pushd $repo 40 | 41 | popd 42 | 43 | popd 44 | -------------------------------------------------------------------------------- /scripts/init.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | set CACHE=cache 3 | set GIT_TEST=git-test 4 | 5 | del /s /q %CACHE% 6 | rmdir /s /q %CACHE% 7 | mkdir %CACHE% 8 | 9 | del /s /q %GIT_TEST% 10 | rmdir /s /q %GIT_TEST% 11 | mkdir %GIT_TEST% 12 | 13 | copy artifacts\config.windows.ini .\config.ini 14 | 15 | pushd %GIT_TEST% 16 | 17 | for %%r in ("https://github.com/patrikx3/angular-compile" "https://github.com/patrikx3/onenote" "https://github.com/patrikx3/aes-folder" "https://github.com/patrikx3/ramdisk" "https://github.com/patrikx3/openwrt-insomnia" "https://github.com/patrikx3/gitlist" "https://github.com/patrikx3/resume-web" "https://github.com/patrikx3/service-manager-tray-for-windows" "https://github.com/patrikx3/docker-debian-testing-mongodb-stable" ) do ( 18 | 19 | echo %%r 20 | git clone --bare %%r 21 | ) 22 | 23 | popd 24 | 25 | composer install 26 | yarn install 27 | -------------------------------------------------------------------------------- /scripts/init.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 3 | set -e 4 | sudo rm -rf ./cache 5 | mkdir -p ./cache 6 | touch ./cache/.gitkeep 7 | chmod 0770 ./cache 8 | 9 | sudo rm -rf ./git-test/ 10 | mkdir -p ./git-test/ 11 | 12 | pushd ./git-test 13 | 14 | for repo in "https://github.com/patrikx3/angular-compile" "https://github.com/patrikx3/onenote" "https://github.com/patrikx3/ramdisk" "https://github.com/patrikx3/openwrt-insomnia" "https://github.com/patrikx3/gitlist" "https://github.com/patrikx3/service-manager-tray-for-windows" 15 | do 16 | git clone --bare $repo 17 | done 18 | 19 | find . -name '*description*' | 20 | while read filename; 21 | do 22 | echo "$(dirname ${filename:2} | cut -f 1 -d '.') test repository." > $filename 23 | done 24 | 25 | popd 26 | 27 | sudo chmod 0777 ./git-test 28 | cp ./artifacts/config.ini ./ 29 | 30 | composer install 31 | 32 | chown $USER:$USER ./cache 33 | chown $USER:$USER ./git-test 34 | chown $USER:$USER ./config.ini 35 | 36 | 37 | -------------------------------------------------------------------------------- /scripts/optimize.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 3 | TOP=$DIR/.. 4 | set -e 5 | pushd $TOP 6 | sudo rm -rf ./cache 7 | mkdir -p ./cache 8 | touch ./cache/.gitkeep 9 | chmod 0770 ./cache 10 | composer install 11 | composer install --no-dev 12 | composer dump-autoload --optimize 13 | yarn install --unsafe-perm 14 | npm run build --verbose 15 | rm -rf ./node_modules 16 | popd 17 | -------------------------------------------------------------------------------- /scripts/release.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 3 | TOP=$DIR/.. 4 | 5 | set -e 6 | 7 | version=$( node -e "console.log(require('$TOP/package.json').version)" ) 8 | pkg_name=$( node -e "console.log(require('$TOP/package.json').name)" ) 9 | name=$pkg_name-v$version 10 | repo=$TOP/build/$name 11 | 12 | pushd $TOP 13 | yarn install 14 | 15 | if [ "$HOSTNAME" = "workstation" ]; 16 | then 17 | /usr/local/bin/composer install --no-dev 18 | /usr/local/bin/composer dump-autoload --optimize 19 | else 20 | composer install --no-dev 21 | composer dump-autoload --optimize 22 | fi 23 | mkdir -p $TOP/cache 24 | #npm install 25 | npm run build 26 | 27 | rm -rf $repo || true 28 | mkdir -p $repo 29 | 30 | for item in "$TOP/cache" "$TOP/src" "$TOP/public" "$TOP/vendor" 31 | do 32 | echo $item 33 | cp -R $item $repo/ 34 | done 35 | 36 | for item in "$TOP/INSTALL.md" "$TOP/change-log.md" "$TOP/LICENSE" "$TOP/README.md" "$TOP/boot.php" "$TOP/config.example.ini" "$TOP/package.json" 37 | do 38 | echo $item 39 | cp $item $repo/ 40 | done 41 | 42 | rm -rf $repo/src/browser 43 | 44 | zipname=$TOP/build/$name.zip 45 | rm -rf $zipname 46 | pushd $repo 47 | #sudo apt install -y zip 48 | 49 | zip -r $TOP/build/$name.zip . 50 | 51 | popd 52 | 53 | if [ $# -eq 0 ]; 54 | then 55 | rm -rf $repo 56 | else 57 | RELEASE=$TOP/build/release 58 | rm -rf $RELEASE || true 59 | mv $repo $RELEASE 60 | cp $TOP/config.ini $RELEASE || true 61 | cp -R $TOP/git-test $RELEASE/ || true 62 | fi 63 | 64 | popd 65 | -------------------------------------------------------------------------------- /scripts/www-git-optimize.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 3 | TOP=$DIR/.. 4 | set -e 5 | pushd $TOP 6 | git checkout -f . 7 | git pull 8 | chown git:www-data -R $PWD 9 | ./scripts/optimize.sh 10 | echo PWD: $PWD 11 | chown git:www-data -R $PWD 12 | popd 13 | -------------------------------------------------------------------------------- /src/GitList/Config.php: -------------------------------------------------------------------------------- 1 | data = $data; 12 | } 13 | 14 | public static function fromFile($file) 15 | { 16 | if (!file_exists($file)) { 17 | die(sprintf('Please, create the %1$s file.', $file)); 18 | } 19 | 20 | $data = parse_ini_file($file, true); 21 | $config = new static($data); 22 | $config->validateOptions(); 23 | 24 | return $config; 25 | } 26 | 27 | protected function validateOptions() 28 | { 29 | $repositories = $this->get('git', 'repositories'); 30 | 31 | $atLeastOneOk = false; 32 | $atLeastOneWrong = false; 33 | 34 | foreach ($repositories as $directory) { 35 | if (!$directory || !is_dir($directory)) { 36 | $atLeastOneWrong = true; 37 | } else { 38 | $atLeastOneOk = true; 39 | } 40 | } 41 | 42 | if (!$atLeastOneOk) { 43 | die("Please, edit the config file and provide your repositories directory"); 44 | } 45 | 46 | if ($atLeastOneWrong) { 47 | die("One or more of the supplied repository paths appears to be wrong. Please, check the config file"); 48 | } 49 | } 50 | 51 | public function get($section, $option) 52 | { 53 | if (!array_key_exists($section, $this->data)) { 54 | return false; 55 | } 56 | 57 | if (!array_key_exists($option, $this->data[$section])) { 58 | return false; 59 | } 60 | 61 | return $this->data[$section][$option]; 62 | } 63 | 64 | public function getSection($section) 65 | { 66 | if (!array_key_exists($section, $this->data)) { 67 | return false; 68 | } 69 | 70 | return $this->data[$section]; 71 | } 72 | 73 | public function set($section, $option, $value) 74 | { 75 | $this->data[$section][$option] = $value; 76 | } 77 | } 78 | 79 | -------------------------------------------------------------------------------- /src/GitList/Escaper/ArgumentEscaper.php: -------------------------------------------------------------------------------- 1 | factory(function () use ($app) { 19 | return new Repository($app); 20 | }); 21 | } 22 | 23 | public function boot(Container $app) 24 | { 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/GitList/Provider/RoutingUtilServiceProvider.php: -------------------------------------------------------------------------------- 1 | factory(function () use ($app) { 19 | return new Routing($app); 20 | }); 21 | } 22 | 23 | public function boot(Container $app) 24 | { 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/GitList/Provider/ViewUtilServiceProvider.php: -------------------------------------------------------------------------------- 1 | factory(function () { 19 | return new View; 20 | }); 21 | } 22 | 23 | public function boot(Container $app) 24 | { 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/GitList/Util/View.php: -------------------------------------------------------------------------------- 1 | $path) { 22 | $breadcrumbs[] = array( 23 | 'dir' => $path, 24 | 'path' => implode('/', array_slice($paths, 0, $i + 1)), 25 | ); 26 | } 27 | 28 | return $breadcrumbs; 29 | } 30 | 31 | public function getPager($pageNumber, $totalCommits) 32 | { 33 | $pageNumber = (empty($pageNumber)) ? 0 : $pageNumber; 34 | $lastPage = intval($totalCommits / 15); 35 | 36 | // If total commits are integral multiple of 15, the lastPage will be commits/15 - 1. 37 | $lastPage = ($lastPage * 15 == $totalCommits) ? $lastPage - 1 : $lastPage; 38 | $nextPage = $pageNumber + 1; 39 | $previousPage = $pageNumber - 1; 40 | 41 | return array('current' => $pageNumber, 42 | 'next' => $nextPage, 43 | 'previous' => $previousPage, 44 | 'last' => $lastPage, 45 | 'total' => $totalCommits, 46 | ); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Gitter/Model/AbstractModel.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Gitter\Model; 13 | 14 | use Gitter\Repository; 15 | 16 | abstract class AbstractModel 17 | { 18 | protected $repository; 19 | 20 | public function getRepository(): Repository 21 | { 22 | return $this->repository; 23 | } 24 | 25 | public function setRepository(Repository $repository) 26 | { 27 | $this->repository = $repository; 28 | 29 | return $this; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Gitter/Model/Blob.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Gitter\Model; 13 | 14 | use Gitter\Repository; 15 | 16 | class Blob extends Item 17 | { 18 | public function __construct($hash, Repository $repository) 19 | { 20 | $this->setHash($hash); 21 | $this->setRepository($repository); 22 | } 23 | 24 | public function output() 25 | { 26 | $data = $this->getRepository()->getClient()->run($this->getRepository(), 'show ' . $this->getHash()); 27 | 28 | return $data; 29 | } 30 | 31 | public function isBlob() 32 | { 33 | return true; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Gitter/Model/Branch.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Gitter\Model; 13 | 14 | class Branch extends AbstractModel 15 | { 16 | protected $name; 17 | 18 | public function getName() 19 | { 20 | return $this->name; 21 | } 22 | 23 | public function setName($name) 24 | { 25 | $this->name = $name; 26 | 27 | return $this; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Gitter/Model/Commit/Author.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Gitter\Model\Commit; 13 | 14 | use Gitter\Model\AbstractModel; 15 | 16 | class Author extends AbstractModel 17 | { 18 | protected $name; 19 | protected $email; 20 | 21 | public function __construct($name, $email) 22 | { 23 | $this->setName($name); 24 | $this->setEmail($email); 25 | } 26 | 27 | public function getName() 28 | { 29 | return $this->name; 30 | } 31 | 32 | public function setName($name) 33 | { 34 | $this->name = $name; 35 | } 36 | 37 | public function getEmail() 38 | { 39 | return $this->email; 40 | } 41 | 42 | public function setEmail($email) 43 | { 44 | $this->email = $email; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Gitter/Model/Commit/Diff.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Gitter\Model\Commit; 13 | 14 | use Gitter\Model\AbstractModel; 15 | 16 | class Diff extends AbstractModel 17 | { 18 | public $lineCount = 0; 19 | /** @var DiffLine[] */ 20 | protected $lines; 21 | protected $index; 22 | protected $old; 23 | protected $new; 24 | protected $file; 25 | protected $binary = false; 26 | 27 | public function addLine($line, $oldNo, $newNo) 28 | { 29 | $this->lines[] = new DiffLine($line, $oldNo, $newNo); 30 | } 31 | 32 | public function getLines() 33 | { 34 | return $this->lines; 35 | } 36 | 37 | public function getIndex() 38 | { 39 | return $this->index; 40 | } 41 | 42 | public function setIndex($index) 43 | { 44 | $this->index = $index; 45 | } 46 | 47 | public function getOld() 48 | { 49 | return $this->old; 50 | } 51 | 52 | public function setOld($old) 53 | { 54 | $this->old = $old; 55 | } 56 | 57 | public function getNew() 58 | { 59 | return $this->new; 60 | } 61 | 62 | public function setNew($new) 63 | { 64 | $this->new = $new; 65 | } 66 | 67 | public function getFile() 68 | { 69 | return $this->file; 70 | } 71 | 72 | public function setFile($file) 73 | { 74 | $this->file = $file; 75 | } 76 | 77 | public function getBinary() 78 | { 79 | return $this->binary; 80 | } 81 | 82 | public function setBinary($bool) 83 | { 84 | $this->binary = true; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/Gitter/Model/Commit/DiffLine.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Gitter\Model\Commit; 13 | 14 | use Gitter\Model\Line; 15 | 16 | class DiffLine extends Line 17 | { 18 | protected $numNew; 19 | protected $numOld; 20 | 21 | public function __construct($data, $numOld, $numNew) 22 | { 23 | parent::__construct($data); 24 | 25 | if (!empty($data)) { 26 | switch ($data[0]) { 27 | case '@': 28 | $this->numOld = '...'; 29 | $this->numNew = '...'; 30 | break; 31 | case '-': 32 | $this->numOld = $numOld; 33 | $this->numNew = ''; 34 | break; 35 | case '+': 36 | $this->numOld = ''; 37 | $this->numNew = $numNew; 38 | break; 39 | default: 40 | $this->numOld = $numOld; 41 | $this->numNew = $numNew; 42 | } 43 | } else { 44 | $this->numOld = $numOld; 45 | $this->numNew = $numNew; 46 | } 47 | } 48 | 49 | public function getNumOld() 50 | { 51 | return $this->numOld; 52 | } 53 | 54 | public function setNumOld($num) 55 | { 56 | $this->numOld = $num; 57 | } 58 | 59 | public function getNumNew() 60 | { 61 | return $this->numNew; 62 | } 63 | 64 | public function setNumNew($num) 65 | { 66 | $this->numNew = $num; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/Gitter/Model/File.php: -------------------------------------------------------------------------------- 1 | size; 20 | } 21 | 22 | public function setSize($size) 23 | { 24 | $this->size = $size; 25 | 26 | return $this; 27 | } 28 | 29 | public function getPath() 30 | { 31 | return $this->path; 32 | } 33 | 34 | public function setPath($path) 35 | { 36 | $this->path = $path; 37 | 38 | return $this; 39 | } 40 | 41 | public function getMode() 42 | { 43 | return $this->mode; 44 | } 45 | 46 | public function setMode($mode) 47 | { 48 | $this->mode = $mode; 49 | 50 | return $this; 51 | } 52 | 53 | public function getName() 54 | { 55 | return $this->name; 56 | } 57 | 58 | public function setName($name) 59 | { 60 | $this->name = $name; 61 | 62 | return $this; 63 | } 64 | 65 | public function getHash() 66 | { 67 | return $this->hash; 68 | } 69 | 70 | public function setHash($hash) 71 | { 72 | $this->hash = $hash; 73 | 74 | return $this; 75 | } 76 | 77 | 78 | public function getShortHash() 79 | { 80 | return $this->shortHash; 81 | } 82 | 83 | public function setShortHash($hash) 84 | { 85 | $this->shortHash = $hash; 86 | 87 | return $this; 88 | } 89 | 90 | public function getLastModified() 91 | { 92 | return $this->lastModified; 93 | } 94 | 95 | public function setLastModified($modified) 96 | { 97 | $this->lastModified = $modified; 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /src/Gitter/Model/Item.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Gitter\Model; 13 | 14 | class Item extends File 15 | { 16 | 17 | public function isBlob() 18 | { 19 | return false; 20 | } 21 | 22 | public function isTag() 23 | { 24 | return false; 25 | } 26 | 27 | public function isCommit() 28 | { 29 | return false; 30 | } 31 | 32 | public function isTree() 33 | { 34 | return false; 35 | } 36 | 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/Gitter/Model/Line.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Gitter\Model; 13 | 14 | class Line extends AbstractModel 15 | { 16 | protected $line; 17 | protected $type; 18 | 19 | public function __construct($data) 20 | { 21 | if (!empty($data)) { 22 | if ($data[0] == '@') { 23 | $this->setType('chunk'); 24 | } 25 | 26 | if ($data[0] == '-') { 27 | $this->setType('old'); 28 | } 29 | 30 | if ($data[0] == '+') { 31 | $this->setType('new'); 32 | } 33 | } 34 | 35 | $this->setLine($data); 36 | } 37 | 38 | public function getLine() 39 | { 40 | return $this->line; 41 | } 42 | 43 | public function setLine($line) 44 | { 45 | $this->line = $line; 46 | 47 | return $this; 48 | } 49 | 50 | public function getType() 51 | { 52 | return $this->type; 53 | } 54 | 55 | public function setType($type) 56 | { 57 | $this->type = $type; 58 | 59 | return $this; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/Gitter/Model/Module.php: -------------------------------------------------------------------------------- 1 | url; 12 | } 13 | 14 | public function setUrl($url) 15 | { 16 | $this->url = $url; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Gitter/Model/Symlink.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Gitter\Model; 13 | 14 | class Symlink extends File 15 | { 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/Gitter/Model/Tag.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Gitter\Model; 13 | 14 | class Tag extends Item 15 | { 16 | protected $name; 17 | 18 | public function getName() 19 | { 20 | return $this->name; 21 | } 22 | 23 | public function setName($name) 24 | { 25 | $this->name = $name; 26 | 27 | return $this; 28 | } 29 | 30 | public function isTag() 31 | { 32 | return true; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Gitter/PrettyFormat.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Gitter; 13 | 14 | class PrettyFormat 15 | { 16 | 17 | public function parse($output) 18 | { 19 | if (empty($output)) { 20 | throw new \RuntimeException('No data available'); 21 | } 22 | 23 | try { 24 | $xml = new \SimpleXmlIterator("$output"); 25 | } catch (\Exception $e) { 26 | $output = $this->escapeXml($output); 27 | $xml = new \SimpleXmlIterator("$output"); 28 | } 29 | $data = $this->iteratorToArray($xml); 30 | 31 | return $data['item']; 32 | } 33 | 34 | public function escapeXml($output) 35 | { 36 | return preg_replace('/[\x00-\x1f]/', '?', $output); 37 | } 38 | 39 | protected function iteratorToArray($iterator) 40 | { 41 | foreach ($iterator as $key => $item) { 42 | if ($iterator->hasChildren()) { 43 | $data[$key][] = $this->iteratorToArray($item); 44 | continue; 45 | } 46 | 47 | $data[$key] = trim(strval($item)); 48 | } 49 | 50 | return $data; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/Gitter/Statistics/Contributors.php: -------------------------------------------------------------------------------- 1 | getAuthor()->getEmail(); 19 | $commitDate = $commit->getCommiterDate()->format('Y-m-d'); 20 | 21 | if (!isset($this->items[$email])) { 22 | $this->items[$email] = new Collection; 23 | } 24 | 25 | $this->items[$email]->items[$commitDate][] = $commit; 26 | ksort($this->items[$email]->items); 27 | } 28 | 29 | public function sortCommits() 30 | { 31 | uasort($this->items, function ($sortA, $sortB) { 32 | if (count($sortA) === count($sortB)) { 33 | return 0; 34 | } 35 | 36 | return count($sortA) > count($sortB) ? -1 : 1; 37 | }); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Gitter/Statistics/Date.php: -------------------------------------------------------------------------------- 1 | getCommiterDate()->format('Y-m-d'); 19 | 20 | $this->items[$day][] = $commit; 21 | } 22 | 23 | public function sortCommits() 24 | { 25 | ksort($this->items); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Gitter/Statistics/Day.php: -------------------------------------------------------------------------------- 1 | getCommiterDate()->format('N'); 19 | 20 | $this->items[$day][] = $commit; 21 | } 22 | 23 | public function sortCommits() 24 | { 25 | ksort($this->items); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Gitter/Statistics/Hour.php: -------------------------------------------------------------------------------- 1 | getCommiterDate()->format('H'); 19 | 20 | $this->items[$hour][] = $commit; 21 | } 22 | 23 | public function sortCommits() 24 | { 25 | ksort($this->items); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Gitter/Statistics/StatisticsInterface.php: -------------------------------------------------------------------------------- 1 | items; 18 | } 19 | 20 | /** 21 | * @param array $items 22 | */ 23 | public function setItems($items) 24 | { 25 | $this->items = $items; 26 | } 27 | 28 | /** 29 | * {@inheritdoc} 30 | */ 31 | public function offsetExists($offset) 32 | { 33 | return isset($this->items[$offset]); 34 | } 35 | 36 | /** 37 | * {@inheritdoc} 38 | */ 39 | public function offsetGet($offset) 40 | { 41 | return isset($this->items[$offset]); 42 | } 43 | 44 | /** 45 | * {@inheritdoc} 46 | */ 47 | public function offsetSet($offset, $value) 48 | { 49 | if (is_null($offset)) { 50 | $this->items[] = $value; 51 | } else { 52 | $this->items[$offset] = $value; 53 | } 54 | } 55 | 56 | /** 57 | * {@inheritdoc} 58 | */ 59 | public function offsetUnset($offset) 60 | { 61 | unset($this->items[$offset]); 62 | } 63 | 64 | /** 65 | * {@inheritdoc} 66 | */ 67 | public function getIterator() 68 | { 69 | return new \ArrayIterator($this->items); 70 | } 71 | 72 | /** 73 | * {@inheritdoc} 74 | */ 75 | public function count() 76 | { 77 | return count($this->items); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/Gitter/Util/DateTime.php: -------------------------------------------------------------------------------- 1 | 8 | * 9 | * For the full copyright and license information, please view the LICENSE 10 | * file that was distributed with this source code. 11 | */ 12 | 13 | namespace Gitter\Util; 14 | 15 | /** 16 | * Fixes the issue that the $timezone parameter and the current timezone are ignored when 17 | * the $time parameter either is a UNIX timestamp (e.g. @946684800) or specifies a timezone 18 | * (e.g. 2010-01-28T15:00:00+02:00). 19 | * 20 | * @link https://github.com/klaussilveira/gitlist/issues/140 21 | */ 22 | class DateTime extends \DateTime 23 | { 24 | /** 25 | * @const The regular expression for an UNIX timestamp 26 | */ 27 | const UNIX_TIMESTAMP_PATTERN = '/^@\d+$/'; 28 | 29 | /** 30 | * @param string $time A date/time string. 31 | * @param DateTimeZone $timezone A DateTimeZone object representing the desired time zone. 32 | * @return DateTime A new DateTime instance. 33 | * @link http://php.net/manual/en/datetime.construct.php 34 | */ 35 | public function __construct($time = 'now', \DateTimeZone $timezone = null) 36 | { 37 | if ($timezone) { 38 | parent::__construct($time, $timezone); 39 | } else { 40 | parent::__construct($time); 41 | } 42 | 43 | if ($this->isUnixTimestamp($time)) { 44 | if (!$timezone) { 45 | $timezone = new \DateTimeZone(date_default_timezone_get()); 46 | } 47 | 48 | $this->setTimezone($timezone); 49 | } 50 | } 51 | 52 | /** 53 | * Checks if an UNIX timestamp is passed. 54 | * 55 | * @param string $time A date/time string. 56 | * @return bool Returns true if the $time parameter is a UNIX timestamp 57 | */ 58 | protected function isUnixTimestamp($time) 59 | { 60 | if (preg_match(self::UNIX_TIMESTAMP_PATTERN, $time)) { 61 | return true; 62 | } 63 | 64 | return false; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/Silex/.gitignore: -------------------------------------------------------------------------------- 1 | /phpunit.xml 2 | /vendor 3 | /build 4 | /composer.lock 5 | 6 | -------------------------------------------------------------------------------- /src/Silex/.php_cs.dist: -------------------------------------------------------------------------------- 1 | setRules(array( 5 | '@Symfony' => true, 6 | '@Symfony:risky' => true, 7 | '@PHPUnit48Migration:risky' => true, 8 | 'php_unit_no_expectation_annotation' => false, // part of `PHPUnitXYMigration:risky` ruleset, to be enabled when PHPUnit 4.x support will be dropped, as we don't want to rewrite exceptions handling twice 9 | 'array_syntax' => array('syntax' => 'short'), 10 | 'protected_to_private' => false, 11 | )) 12 | ->setRiskyAllowed(true) 13 | ->setFinder( 14 | PhpCsFixer\Finder::create() 15 | ->in(__DIR__.'/src/') 16 | ->in(__DIR__.'/tests/') 17 | ->name('*.php') 18 | ) 19 | ; 20 | -------------------------------------------------------------------------------- /src/Silex/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010-2017 Fabien Potencier 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is furnished 8 | to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /src/Silex/README.rst: -------------------------------------------------------------------------------- 1 | Silex, a simple Web Framework 2 | ============================= 3 | 4 | **WARNING**: Silex is in maintenance mode only. Ends of life is set to June 5 | 2018. Read more on `Symfony's blog `_. 6 | 7 | Silex is a PHP micro-framework to develop websites based on `Symfony 8 | components`_: 9 | 10 | .. code-block:: php 11 | 12 | get('/hello/{name}', function ($name) use ($app) { 19 | return 'Hello '.$app->escape($name); 20 | }); 21 | 22 | $app->run(); 23 | 24 | Silex works with PHP 7.1.3 or later. 25 | 26 | Installation 27 | ------------ 28 | 29 | The recommended way to install Silex is through `Composer`_: 30 | 31 | .. code-block:: bash 32 | 33 | composer require silex/silex "~2.0" 34 | 35 | Alternatively, you can download the `silex.zip`_ file and extract it. 36 | 37 | More Information 38 | ---------------- 39 | 40 | Read the `documentation`_ for more information and `changelog 41 | `_ for upgrading information. 42 | 43 | Tests 44 | ----- 45 | 46 | To run the test suite, you need `Composer`_ and `PHPUnit`_: 47 | 48 | .. code-block:: bash 49 | 50 | composer install 51 | phpunit 52 | 53 | Support 54 | ------- 55 | 56 | If you have a configuration problem use the `silex tag`_ on StackOverflow to ask a question. 57 | 58 | If you think there is an actual problem in Silex, please `open an issue`_ if there isn't one already created. 59 | 60 | License 61 | ------- 62 | 63 | Silex is licensed under the MIT license. 64 | 65 | .. _Symfony components: http://symfony.com 66 | .. _Composer: http://getcomposer.org 67 | .. _PHPUnit: https://phpunit.de 68 | .. _silex.zip: http://silex.sensiolabs.org/download 69 | .. _documentation: http://silex.sensiolabs.org/documentation 70 | .. _silex tag: https://stackoverflow.com/questions/tagged/silex 71 | .. _open an issue: https://github.com/silexphp/Silex/issues/new 72 | -------------------------------------------------------------------------------- /src/Silex/doc/conf.py: -------------------------------------------------------------------------------- 1 | import sys, os 2 | from sphinx.highlighting import lexers 3 | from pygments.lexers.web import PhpLexer 4 | 5 | sys.path.append(os.path.abspath('_exts')) 6 | 7 | extensions = [] 8 | master_doc = 'index' 9 | highlight_language = 'php' 10 | 11 | project = u'Silex' 12 | copyright = u'2010 Fabien Potencier' 13 | 14 | version = '0' 15 | release = '0.0.0' 16 | 17 | lexers['php'] = PhpLexer(startinline=True) 18 | -------------------------------------------------------------------------------- /src/Silex/doc/contributing.rst: -------------------------------------------------------------------------------- 1 | Contributing 2 | ============ 3 | 4 | We are open to contributions to the Silex code. If you find a bug or want to 5 | contribute a provider, just follow these steps: 6 | 7 | * Fork `the Silex repository `_; 8 | 9 | * Make your feature addition or bug fix; 10 | 11 | * Add tests for it; 12 | 13 | * Optionally, add some documentation; 14 | 15 | * `Send a pull request 16 | `_, to the correct 17 | target branch (1.3 for bug fixes, master for new features). 18 | 19 | .. note:: 20 | 21 | Any code you contribute must be licensed under the MIT 22 | License. 23 | 24 | Writing Documentation 25 | ===================== 26 | 27 | The documentation is written in `reStructuredText 28 | `_ and can be generated using `sphinx 29 | `_. 30 | 31 | .. code-block:: bash 32 | 33 | $ cd doc 34 | $ sphinx-build -b html . build 35 | -------------------------------------------------------------------------------- /src/Silex/doc/cookbook/error_handler.rst: -------------------------------------------------------------------------------- 1 | Converting Errors to Exceptions 2 | =============================== 3 | 4 | Silex catches exceptions that are thrown from within a request/response cycle. 5 | However, it does *not* catch PHP errors and notices. This recipe tells you how 6 | to catch them by converting them to exceptions. 7 | 8 | Registering the ErrorHandler 9 | ---------------------------- 10 | 11 | The ``Symfony/Debug`` package has an ``ErrorHandler`` class that solves this 12 | problem. It converts all errors to exceptions, and exceptions are then caught 13 | by Silex. 14 | 15 | Register it by calling the static ``register`` method:: 16 | 17 | use Symfony\Component\Debug\ErrorHandler; 18 | 19 | ErrorHandler::register(); 20 | 21 | It is recommended that you do this as early as possible. 22 | 23 | Handling fatal errors 24 | --------------------- 25 | 26 | To handle fatal errors, you can additionally register a global 27 | ``ExceptionHandler``:: 28 | 29 | use Symfony\Component\Debug\ExceptionHandler; 30 | 31 | ExceptionHandler::register(); 32 | 33 | In production you may want to disable the debug output by passing ``false`` as 34 | the ``$debug`` argument:: 35 | 36 | use Symfony\Component\Debug\ExceptionHandler; 37 | 38 | ExceptionHandler::register(false); 39 | 40 | .. note:: 41 | 42 | Important caveat when using Silex on a command-line interface: 43 | The ``ExceptionHandler`` should not be enabled as it would convert an error 44 | to HTML output and return a non-zero exit code:: 45 | 46 | use Symfony\Component\Debug\ExceptionHandler; 47 | 48 | if (!in_array(PHP_SAPI, ['cli', 'phpdbg'])) { 49 | ExceptionHandler::register(); 50 | } 51 | -------------------------------------------------------------------------------- /src/Silex/doc/cookbook/form_no_csrf.rst: -------------------------------------------------------------------------------- 1 | Disabling CSRF Protection on a Form using the FormExtension 2 | =========================================================== 3 | 4 | The *FormExtension* provides a service for building form in your application 5 | with the Symfony Form component. When the :doc:`CSRF Service Provider 6 | ` is registered, the *FormExtension* uses the CSRF Protection 7 | avoiding Cross-site request forgery, a method by which a malicious user 8 | attempts to make your legitimate users unknowingly submit data that they don't 9 | intend to submit. 10 | 11 | You can find more details about CSRF Protection and CSRF token in the 12 | `Symfony Book 13 | `_. 14 | 15 | In some cases (for example, when embedding a form in an html email) you might 16 | want not to use this protection. The easiest way to avoid this is to 17 | understand that it is possible to give specific options to your form builder 18 | through the ``createBuilder()`` function. 19 | 20 | Example 21 | ------- 22 | 23 | .. code-block:: php 24 | 25 | $form = $app['form.factory']->createBuilder('form', null, array('csrf_protection' => false)); 26 | 27 | That's it, your form could be submitted from everywhere without CSRF Protection. 28 | 29 | Going further 30 | ------------- 31 | 32 | This specific example showed how to change the ``csrf_protection`` in the 33 | ``$options`` parameter of the ``createBuilder()`` function. More of them could 34 | be passed through this parameter, it is as simple as using the Symfony 35 | ``getDefaultOptions()`` method in your form classes. `See more here 36 | `_. 37 | -------------------------------------------------------------------------------- /src/Silex/doc/cookbook/index.rst: -------------------------------------------------------------------------------- 1 | Cookbook 2 | ======== 3 | 4 | The cookbook section contains recipes for solving specific problems. 5 | 6 | .. toctree:: 7 | :maxdepth: 1 8 | :hidden: 9 | 10 | json_request_body 11 | session_storage 12 | form_no_csrf 13 | validator_yaml 14 | sub_requests 15 | error_handler 16 | multiple_loggers 17 | guard_authentication 18 | 19 | Recipes 20 | ------- 21 | 22 | * :doc:`Accepting a JSON Request Body ` A common need when 23 | building a restful API is the ability to accept a JSON encoded entity from 24 | the request body. 25 | 26 | * :doc:`Using PdoSessionStorage to store Sessions in the Database 27 | `. 28 | 29 | * :doc:`Disabling the CSRF Protection on a Form using the FormExtension 30 | `. 31 | 32 | * :doc:`Using YAML to configure Validation `. 33 | 34 | * :doc:`Making sub-Requests `. 35 | 36 | * :doc:`Converting Errors to Exceptions `. 37 | 38 | * :doc:`Using multiple Monolog Loggers `. 39 | 40 | * :doc:`How to Create a Custom Authentication System with Guard `. 41 | -------------------------------------------------------------------------------- /src/Silex/doc/cookbook/validator_yaml.rst: -------------------------------------------------------------------------------- 1 | Using YAML to configure Validation 2 | ================================== 3 | 4 | Simplicity is at the heart of Silex so there is no out of the box solution to 5 | use YAML files for validation. But this doesn't mean that this is not 6 | possible. Let's see how to do it. 7 | 8 | First, you need to install the YAML Component: 9 | 10 | .. code-block:: bash 11 | 12 | composer require symfony/yaml 13 | 14 | Next, you need to tell the Validation Service that you are not using 15 | ``StaticMethodLoader`` to load your class metadata but a YAML file:: 16 | 17 | $app->register(new ValidatorServiceProvider()); 18 | 19 | $app['validator.mapping.class_metadata_factory'] = new Symfony\Component\Validator\Mapping\Factory\LazyLoadingMetadataFactory( 20 | new Symfony\Component\Validator\Mapping\Loader\YamlFileLoader(__DIR__.'/validation.yml') 21 | ); 22 | 23 | Now, we can replace the usage of the static method and move all the validation 24 | rules to ``validation.yml``: 25 | 26 | .. code-block:: yaml 27 | 28 | # validation.yml 29 | Post: 30 | properties: 31 | title: 32 | - NotNull: ~ 33 | - NotBlank: ~ 34 | body: 35 | - Min: 100 36 | -------------------------------------------------------------------------------- /src/Silex/doc/index.rst: -------------------------------------------------------------------------------- 1 | The Book 2 | ======== 3 | 4 | .. toctree:: 5 | :maxdepth: 1 6 | 7 | intro 8 | usage 9 | middlewares 10 | organizing_controllers 11 | services 12 | providers 13 | testing 14 | cookbook/index 15 | internals 16 | contributing 17 | providers/index 18 | web_servers 19 | changelog 20 | -------------------------------------------------------------------------------- /src/Silex/doc/intro.rst: -------------------------------------------------------------------------------- 1 | Introduction 2 | ============ 3 | 4 | Silex is a PHP microframework. It is built on the shoulders of `Symfony`_ and 5 | `Pimple`_ and also inspired by `Sinatra`_. 6 | 7 | Silex aims to be: 8 | 9 | * *Concise*: Silex exposes an intuitive and concise API. 10 | 11 | * *Extensible*: Silex has an extension system based around the Pimple 12 | service-container that makes it easy to tie in third party libraries. 13 | 14 | * *Testable*: Silex uses Symfony's HttpKernel which abstracts request and 15 | response. This makes it very easy to test apps and the framework itself. It 16 | also respects the HTTP specification and encourages its proper use. 17 | 18 | In a nutshell, you define controllers and map them to routes, all in one step. 19 | 20 | Usage 21 | ----- 22 | 23 | .. code-block:: php 24 | 25 | get('/hello/{name}', function ($name) use ($app) { 33 | return 'Hello '.$app->escape($name); 34 | }); 35 | 36 | $app->run(); 37 | 38 | All that is needed to get access to the Framework is to include the 39 | autoloader. 40 | 41 | Next, a route for ``/hello/{name}`` that matches for ``GET`` requests is 42 | defined. When the route matches, the function is executed and the return value 43 | is sent back to the client. 44 | 45 | Finally, the app is run. Visit ``/hello/world`` to see the result. It's really 46 | that easy! 47 | 48 | .. _Symfony: http://symfony.com/ 49 | .. _Pimple: http://pimple.sensiolabs.org/ 50 | .. _Sinatra: http://www.sinatrarb.com/ 51 | -------------------------------------------------------------------------------- /src/Silex/doc/providers/csrf.rst: -------------------------------------------------------------------------------- 1 | CSRF 2 | ==== 3 | 4 | The *CsrfServiceProvider* provides a service for building forms in your 5 | application with the Symfony Form component. 6 | 7 | Parameters 8 | ---------- 9 | 10 | * **csrf.session_namespace** (optional): The namespace under which the token 11 | is stored in the session. Defaults to ``_csrf``. 12 | 13 | Services 14 | -------- 15 | 16 | * **csrf.token_manager**: An instance of an implementation of the 17 | `CsrfTokenManagerInterface 18 | `_, 19 | 20 | Registering 21 | ----------- 22 | 23 | .. code-block:: php 24 | 25 | use Silex\Provider\CsrfServiceProvider; 26 | 27 | $app->register(new CsrfServiceProvider()); 28 | 29 | .. note:: 30 | 31 | Add the Symfony's `Security CSRF Component 32 | `_ as a 33 | dependency: 34 | 35 | .. code-block:: bash 36 | 37 | composer require symfony/security-csrf 38 | 39 | Usage 40 | ----- 41 | 42 | When the CSRF Service Provider is registered, all forms created via the Form 43 | Service Provider are protected against CSRF by default. 44 | 45 | You can also use the CSRF protection without using the Symfony Form component. 46 | If, for example, you're doing a DELETE action, create a CSRF token to use in 47 | your code:: 48 | 49 | use Symfony\Component\Security\Csrf\CsrfToken; 50 | $csrfToken = $app['csrf.token_manager']->getToken('token_id'); //'TOKEN' 51 | 52 | Then check it:: 53 | 54 | $app['csrf.token_manager']->isTokenValid(new CsrfToken('token_id', 'TOKEN')); 55 | -------------------------------------------------------------------------------- /src/Silex/doc/providers/http_fragment.rst: -------------------------------------------------------------------------------- 1 | HTTP Fragment 2 | ============= 3 | 4 | The *HttpFragmentServiceProvider* provides support for the Symfony fragment 5 | sub-framework, which allows you to embed fragments of HTML in a template. 6 | 7 | Parameters 8 | ---------- 9 | 10 | * **fragment.path**: The path to use for the URL generated for ESI and 11 | HInclude URLs (``/_fragment`` by default). 12 | 13 | * **uri_signer.secret**: The secret to use for the URI signer service (used 14 | for the HInclude renderer). 15 | 16 | * **fragment.renderers.hinclude.global_template**: The content or Twig 17 | template to use for the default content when using the HInclude renderer. 18 | 19 | Services 20 | -------- 21 | 22 | * **fragment.handler**: An instance of `FragmentHandler 23 | `_. 24 | 25 | * **fragment.renderers**: An array of fragment renderers (by default, the 26 | inline, ESI, and HInclude renderers are pre-configured). 27 | 28 | Registering 29 | ----------- 30 | 31 | .. code-block:: php 32 | 33 | $app->register(new Silex\Provider\HttpFragmentServiceProvider()); 34 | 35 | Usage 36 | ----- 37 | 38 | .. note:: 39 | 40 | This section assumes that you are using Twig for your templates. 41 | 42 | Instead of building a page out of a single request/controller/template, the 43 | fragment framework allows you to build a page from several 44 | controllers/sub-requests/sub-templates by using **fragments**. 45 | 46 | Including "sub-pages" in the main page can be done with the Twig ``render()`` 47 | function: 48 | 49 | .. code-block:: jinja 50 | 51 | The main page content. 52 | 53 | {{ render('/foo') }} 54 | 55 | The main page content resumes here. 56 | 57 | The ``render()`` call is replaced by the content of the ``/foo`` URL 58 | (internally, a sub-request is handled by Silex to render the sub-page). 59 | 60 | Instead of making internal sub-requests, you can also use the ESI (the 61 | sub-request is handled by a reverse proxy) or the HInclude strategies (the 62 | sub-request is handled by a web browser): 63 | 64 | .. code-block:: jinja 65 | 66 | {{ render(url('route_name')) }} 67 | 68 | {{ render_esi(url('route_name')) }} 69 | 70 | {{ render_hinclude(url('route_name')) }} 71 | -------------------------------------------------------------------------------- /src/Silex/doc/providers/index.rst: -------------------------------------------------------------------------------- 1 | Built-in Service Providers 2 | ========================== 3 | 4 | .. toctree:: 5 | :maxdepth: 1 6 | 7 | twig 8 | asset 9 | monolog 10 | session 11 | swiftmailer 12 | locale 13 | translation 14 | validator 15 | form 16 | csrf 17 | http_cache 18 | http_fragment 19 | security 20 | remember_me 21 | serializer 22 | service_controller 23 | var_dumper 24 | doctrine 25 | routing 26 | -------------------------------------------------------------------------------- /src/Silex/doc/providers/locale.rst: -------------------------------------------------------------------------------- 1 | Locale 2 | ====== 3 | 4 | The *LocaleServiceProvider* manages the locale of an application. 5 | 6 | Parameters 7 | ---------- 8 | 9 | * **locale**: The locale of the user. When set before any request handling, it 10 | defines the default locale (``en`` by default). When a request is being 11 | handled, it is automatically set according to the ``_locale`` request 12 | attribute of the current route. 13 | 14 | Services 15 | -------- 16 | 17 | * n/a 18 | 19 | Registering 20 | ----------- 21 | 22 | .. code-block:: php 23 | 24 | $app->register(new Silex\Provider\LocaleServiceProvider()); 25 | -------------------------------------------------------------------------------- /src/Silex/doc/providers/remember_me.rst: -------------------------------------------------------------------------------- 1 | Remember Me 2 | =========== 3 | 4 | The *RememberMeServiceProvider* adds "Remember-Me" authentication to the 5 | *SecurityServiceProvider*. 6 | 7 | Parameters 8 | ---------- 9 | 10 | n/a 11 | 12 | Services 13 | -------- 14 | 15 | n/a 16 | 17 | .. note:: 18 | 19 | The service provider defines many other services that are used internally 20 | but rarely need to be customized. 21 | 22 | Registering 23 | ----------- 24 | 25 | Before registering this service provider, you must register the 26 | *SecurityServiceProvider*:: 27 | 28 | $app->register(new Silex\Provider\SecurityServiceProvider()); 29 | $app->register(new Silex\Provider\RememberMeServiceProvider()); 30 | 31 | $app['security.firewalls'] = array( 32 | 'my-firewall' => array( 33 | 'pattern' => '^/secure$', 34 | 'form' => true, 35 | 'logout' => true, 36 | 'remember_me' => array( 37 | 'key' => 'Choose_A_Unique_Random_Key', 38 | 'always_remember_me' => true, 39 | /* Other options */ 40 | ), 41 | 'users' => array( /* ... */ ), 42 | ), 43 | ); 44 | 45 | Options 46 | ------- 47 | 48 | * **key**: A secret key to generate tokens (you should generate a random 49 | string). 50 | 51 | * **name**: Cookie name (default: ``REMEMBERME``). 52 | 53 | * **lifetime**: Cookie lifetime (default: ``31536000`` ~ 1 year). 54 | 55 | * **path**: Cookie path (default: ``/``). 56 | 57 | * **domain**: Cookie domain (default: ``null`` = request domain). 58 | 59 | * **secure**: Cookie is secure (default: ``false``). 60 | 61 | * **httponly**: Cookie is HTTP only (default: ``true``). 62 | 63 | * **always_remember_me**: Enable remember me (default: ``false``). 64 | 65 | * **remember_me_parameter**: Name of the request parameter enabling remember_me 66 | on login. To add the checkbox to the login form. You can find more 67 | information in the `Symfony cookbook 68 | `_ 69 | (default: ``_remember_me``). 70 | -------------------------------------------------------------------------------- /src/Silex/doc/providers/var_dumper.rst: -------------------------------------------------------------------------------- 1 | Var Dumper 2 | ========== 3 | 4 | The *VarDumperServiceProvider* provides a mechanism that allows exploring then 5 | dumping any PHP variable. 6 | 7 | Parameters 8 | ---------- 9 | 10 | * **var_dumper.dump_destination**: A stream URL where dumps should be written 11 | to (defaults to ``null``). 12 | 13 | Services 14 | -------- 15 | 16 | * n/a 17 | 18 | Registering 19 | ----------- 20 | 21 | .. code-block:: php 22 | 23 | $app->register(new Silex\Provider\VarDumperServiceProvider()); 24 | 25 | .. note:: 26 | 27 | Add the Symfony VarDumper Component as a dependency: 28 | 29 | .. code-block:: bash 30 | 31 | composer require symfony/var-dumper 32 | 33 | Usage 34 | ----- 35 | 36 | Adding the VarDumper component as a Composer dependency gives you access to the 37 | ``dump()`` PHP function anywhere in your code. 38 | 39 | If you are using Twig, it also provides a ``dump()`` Twig function and a 40 | ``dump`` Twig tag. 41 | 42 | The VarDumperServiceProvider is also useful when used with the Silex 43 | WebProfiler as the dumps are made available in the web debug toolbar and in the 44 | web profiler. 45 | -------------------------------------------------------------------------------- /src/Silex/phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 14 | 15 | 16 | ./tests/Silex/ 17 | 18 | 19 | 20 | 21 | ./src 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/Silex/src/Silex/Api/BootableProviderInterface.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Silex\Api; 13 | 14 | use Silex\Application; 15 | 16 | /** 17 | * Interface for bootable service providers. 18 | * 19 | * @author Fabien Potencier 20 | */ 21 | interface BootableProviderInterface 22 | { 23 | /** 24 | * Bootstraps the application. 25 | * 26 | * This method is called after all services are registered 27 | * and should be used for "dynamic" configuration (whenever 28 | * a service must be requested). 29 | * 30 | * @param Application $app 31 | */ 32 | public function boot(Application $app); 33 | } 34 | -------------------------------------------------------------------------------- /src/Silex/src/Silex/Api/ControllerProviderInterface.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Silex\Api; 13 | 14 | use Silex\Application; 15 | use Silex\ControllerCollection; 16 | 17 | /** 18 | * Interface for controller providers. 19 | * 20 | * @author Fabien Potencier 21 | */ 22 | interface ControllerProviderInterface 23 | { 24 | /** 25 | * Returns routes to connect to the given application. 26 | * 27 | * @param Application $app An Application instance 28 | * 29 | * @return ControllerCollection A ControllerCollection instance 30 | */ 31 | public function connect(Application $app); 32 | } 33 | -------------------------------------------------------------------------------- /src/Silex/src/Silex/Api/EventListenerProviderInterface.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Silex\Api; 13 | 14 | use Symfony\Component\EventDispatcher\EventDispatcherInterface; 15 | use Pimple\Container; 16 | 17 | /** 18 | * Interface for event listener providers. 19 | * 20 | * @author Fabien Potencier 21 | */ 22 | interface EventListenerProviderInterface 23 | { 24 | public function subscribe(Container $app, EventDispatcherInterface $dispatcher); 25 | } 26 | -------------------------------------------------------------------------------- /src/Silex/src/Silex/Api/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010-2015 Fabien Potencier 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is furnished 8 | to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /src/Silex/src/Silex/Api/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "minimum-stability": "dev", 3 | "name": "silex/api", 4 | "description": "The Silex interfaces", 5 | "keywords": ["microframework"], 6 | "homepage": "http://silex.sensiolabs.org", 7 | "license": "MIT", 8 | "authors": [ 9 | { 10 | "name": "Fabien Potencier", 11 | "email": "fabien@symfony.com" 12 | }, 13 | { 14 | "name": "Igor Wiedler", 15 | "email": "igor@wiedler.ch" 16 | } 17 | ], 18 | "require": { 19 | "php": ">=5.5.9", 20 | "pimple/pimple": "~3.0" 21 | }, 22 | "suggest": { 23 | "symfony/event-dispatcher": "For EventListenerProviderInterface", 24 | "silex/silex": "For BootableProviderInterface and ControllerProviderInterface" 25 | }, 26 | "autoload": { 27 | "psr-4": { "Silex\\Api\\": "" } 28 | }, 29 | "extra": { 30 | "branch-alias": { 31 | "dev-master": "2.3.x-dev" 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Silex/src/Silex/AppArgumentValueResolver.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Silex; 13 | 14 | use Symfony\Component\HttpFoundation\Request; 15 | use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface; 16 | use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata; 17 | 18 | /** 19 | * HttpKernel Argument Resolver for Silex. 20 | * 21 | * @author Romain Neutron 22 | */ 23 | class AppArgumentValueResolver implements ArgumentValueResolverInterface 24 | { 25 | private $app; 26 | 27 | public function __construct(Application $app) 28 | { 29 | $this->app = $app; 30 | } 31 | 32 | /** 33 | * {@inheritdoc} 34 | */ 35 | public function supports(Request $request, ArgumentMetadata $argument) : bool 36 | { 37 | return null !== $argument->getType() && (Application::class === $argument->getType() || is_subclass_of($argument->getType(), Application::class)); 38 | } 39 | 40 | /** 41 | * {@inheritdoc} 42 | */ 43 | public function resolve(Request $request, ArgumentMetadata $argument) : iterable 44 | { 45 | yield $this->app; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Silex/src/Silex/Application/FormTrait.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Silex\Application; 13 | 14 | use Symfony\Component\Form\Extension\Core\Type\FormType; 15 | use Symfony\Component\Form\FormBuilder; 16 | use Symfony\Component\Form\FormTypeInterface; 17 | 18 | /** 19 | * Form trait. 20 | * 21 | * @author Fabien Potencier 22 | * @author David Berlioz 23 | */ 24 | trait FormTrait 25 | { 26 | /** 27 | * Creates and returns a form builder instance. 28 | * 29 | * @param mixed $data The initial data for the form 30 | * @param array $options Options for the form 31 | * @param string|FormTypeInterface $type Type of the form 32 | * 33 | * @return FormBuilder 34 | */ 35 | public function form($data = null, array $options = [], $type = null) 36 | { 37 | return $this['form.factory']->createBuilder($type ?: FormType::class, $data, $options); 38 | } 39 | 40 | /** 41 | * Creates and returns a named form builder instance. 42 | * 43 | * @param string $name 44 | * @param mixed $data The initial data for the form 45 | * @param array $options Options for the form 46 | * @param string|FormTypeInterface $type Type of the form 47 | * 48 | * @return FormBuilder 49 | */ 50 | public function namedForm($name, $data = null, array $options = [], $type = null) 51 | { 52 | return $this['form.factory']->createNamedBuilder($name, $type ?: FormType::class, $data, $options); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Silex/src/Silex/Application/MonologTrait.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Silex\Application; 13 | 14 | use Monolog\Logger; 15 | 16 | /** 17 | * Monolog trait. 18 | * 19 | * @author Fabien Potencier 20 | */ 21 | trait MonologTrait 22 | { 23 | /** 24 | * Adds a log record. 25 | * 26 | * @param string $message The log message 27 | * @param array $context The log context 28 | * @param int $level The logging level 29 | * 30 | * @return bool Whether the record has been processed 31 | */ 32 | public function log($message, array $context = [], $level = Logger::INFO) 33 | { 34 | return $this['monolog']->addRecord($level, $message, $context); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Silex/src/Silex/Application/SecurityTrait.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Silex\Application; 13 | 14 | use Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException; 15 | use Symfony\Component\Security\Core\User\UserInterface; 16 | 17 | /** 18 | * Security trait. 19 | * 20 | * @author Fabien Potencier 21 | */ 22 | trait SecurityTrait 23 | { 24 | /** 25 | * Encodes the raw password. 26 | * 27 | * @param UserInterface $user A UserInterface instance 28 | * @param string $password The password to encode 29 | * 30 | * @return string The encoded password 31 | * 32 | * @throws \RuntimeException when no password encoder could be found for the user 33 | */ 34 | public function encodePassword(UserInterface $user, $password) 35 | { 36 | return $this['security.encoder_factory']->getEncoder($user)->encodePassword($password, $user->getSalt()); 37 | } 38 | 39 | /** 40 | * Checks if the attributes are granted against the current authentication token and optionally supplied object. 41 | * 42 | * @param mixed $attributes 43 | * @param mixed $object 44 | * 45 | * @return bool 46 | * 47 | * @throws AuthenticationCredentialsNotFoundException when the token storage has no authentication token 48 | */ 49 | public function isGranted($attributes, $object = null) 50 | { 51 | return $this['security.authorization_checker']->isGranted($attributes, $object); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Silex/src/Silex/Application/SwiftmailerTrait.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Silex\Application; 13 | 14 | /** 15 | * Swiftmailer trait. 16 | * 17 | * @author Fabien Potencier 18 | */ 19 | trait SwiftmailerTrait 20 | { 21 | /** 22 | * Sends an email. 23 | * 24 | * @param \Swift_Message $message A \Swift_Message instance 25 | * @param array $failedRecipients An array of failures by-reference 26 | * 27 | * @return int The number of sent messages 28 | */ 29 | public function mail(\Swift_Message $message, &$failedRecipients = null) 30 | { 31 | return $this['mailer']->send($message, $failedRecipients); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Silex/src/Silex/Application/TranslationTrait.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Silex\Application; 13 | 14 | /** 15 | * Translation trait. 16 | * 17 | * @author Fabien Potencier 18 | */ 19 | trait TranslationTrait 20 | { 21 | /** 22 | * Translates the given message. 23 | * 24 | * @param string $id The message id 25 | * @param array $parameters An array of parameters for the message 26 | * @param string $domain The domain for the message 27 | * @param string $locale The locale 28 | * 29 | * @return string The translated string 30 | */ 31 | public function trans($id, array $parameters = [], $domain = 'messages', $locale = null) 32 | { 33 | return $this['translator']->trans($id, $parameters, $domain, $locale); 34 | } 35 | 36 | /** 37 | * Translates the given choice message by choosing a translation according to a number. 38 | * 39 | * @param string $id The message id 40 | * @param int $number The number to use to find the indice of the message 41 | * @param array $parameters An array of parameters for the message 42 | * @param string $domain The domain for the message 43 | * @param string $locale The locale 44 | * 45 | * @return string The translated string 46 | */ 47 | public function transChoice($id, $number, array $parameters = [], $domain = 'messages', $locale = null) 48 | { 49 | return $this['translator']->transChoice($id, $number, $parameters, $domain, $locale); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Silex/src/Silex/Application/TwigTrait.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Silex\Application; 13 | 14 | use Symfony\Component\HttpFoundation\Response; 15 | use Symfony\Component\HttpFoundation\StreamedResponse; 16 | 17 | /** 18 | * Twig trait. 19 | * 20 | * @author Fabien Potencier 21 | */ 22 | trait TwigTrait 23 | { 24 | /** 25 | * Renders a view and returns a Response. 26 | * 27 | * To stream a view, pass an instance of StreamedResponse as a third argument. 28 | * 29 | * @param string $view The view name 30 | * @param array $parameters An array of parameters to pass to the view 31 | * @param Response $response A Response instance 32 | * 33 | * @return Response A Response instance 34 | */ 35 | public function render($view, array $parameters = [], Response $response = null) 36 | { 37 | $twig = $this['twig']; 38 | 39 | if ($response instanceof StreamedResponse) { 40 | $response->setCallback(function () use ($twig, $view, $parameters) { 41 | $twig->display($view, $parameters); 42 | }); 43 | } else { 44 | if (null === $response) { 45 | $response = new Response(); 46 | } 47 | $response->setContent($twig->render($view, $parameters)); 48 | } 49 | 50 | return $response; 51 | } 52 | 53 | /** 54 | * Renders a view. 55 | * 56 | * @param string $view The view name 57 | * @param array $parameters An array of parameters to pass to the view 58 | * 59 | * @return string The rendered view 60 | */ 61 | public function renderView($view, array $parameters = []) 62 | { 63 | return $this['twig']->render($view, $parameters); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/Silex/src/Silex/Application/UrlGeneratorTrait.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Silex\Application; 13 | 14 | use Symfony\Component\Routing\Generator\UrlGeneratorInterface; 15 | 16 | /** 17 | * UrlGenerator trait. 18 | * 19 | * @author Fabien Potencier 20 | */ 21 | trait UrlGeneratorTrait 22 | { 23 | /** 24 | * Generates a path from the given parameters. 25 | * 26 | * @param string $route The name of the route 27 | * @param mixed $parameters An array of parameters 28 | * 29 | * @return string The generated path 30 | */ 31 | public function path($route, $parameters = []) 32 | { 33 | return $this['url_generator']->generate($route, $parameters, UrlGeneratorInterface::ABSOLUTE_PATH); 34 | } 35 | 36 | /** 37 | * Generates an absolute URL from the given parameters. 38 | * 39 | * @param string $route The name of the route 40 | * @param mixed $parameters An array of parameters 41 | * 42 | * @return string The generated URL 43 | */ 44 | public function url($route, $parameters = []) 45 | { 46 | return $this['url_generator']->generate($route, $parameters, UrlGeneratorInterface::ABSOLUTE_URL); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Silex/src/Silex/EventListener/ConverterListener.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Silex\EventListener; 13 | 14 | use Silex\CallbackResolver; 15 | use Symfony\Component\HttpKernel\KernelEvents; 16 | use Symfony\Component\HttpKernel\Event\ControllerEvent; 17 | use Symfony\Component\EventDispatcher\EventSubscriberInterface; 18 | use Symfony\Component\Routing\RouteCollection; 19 | 20 | /** 21 | * Handles converters. 22 | * 23 | * @author Fabien Potencier 24 | */ 25 | class ConverterListener implements EventSubscriberInterface 26 | { 27 | protected $routes; 28 | protected $callbackResolver; 29 | 30 | /** 31 | * Constructor. 32 | * 33 | * @param RouteCollection $routes A RouteCollection instance 34 | * @param CallbackResolver $callbackResolver A CallbackResolver instance 35 | */ 36 | public function __construct(RouteCollection $routes, CallbackResolver $callbackResolver) 37 | { 38 | $this->routes = $routes; 39 | $this->callbackResolver = $callbackResolver; 40 | } 41 | 42 | /** 43 | * Handles converters. 44 | * 45 | * @param ControllerEvent $event The event to handle 46 | */ 47 | public function onKernelController(ControllerEvent $event) 48 | { 49 | $request = $event->getRequest(); 50 | $route = $this->routes->get($request->attributes->get('_route')); 51 | if ($route && $converters = $route->getOption('_converters')) { 52 | foreach ($converters as $name => $callback) { 53 | $callback = $this->callbackResolver->resolveCallback($callback); 54 | 55 | $request->attributes->set($name, call_user_func($callback, $request->attributes->get($name), $request)); 56 | } 57 | } 58 | } 59 | 60 | public static function getSubscribedEvents() 61 | { 62 | return [ 63 | KernelEvents::CONTROLLER => 'onKernelController', 64 | ]; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/Silex/src/Silex/EventListener/StringToResponseListener.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Silex\EventListener; 13 | 14 | use Symfony\Component\HttpKernel\KernelEvents; 15 | use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent; 16 | use Symfony\Component\EventDispatcher\EventSubscriberInterface; 17 | use Symfony\Component\HttpFoundation\Response; 18 | 19 | /** 20 | * Converts string responses to proper Response instances. 21 | * 22 | * @author Fabien Potencier 23 | */ 24 | class StringToResponseListener implements EventSubscriberInterface 25 | { 26 | /** 27 | * Handles string responses. 28 | * 29 | * @param ViewEvent $event The event to handle 30 | */ 31 | public function onKernelView(\Symfony\Component\HttpKernel\Event\ViewEvent $event) 32 | { 33 | $response = $event->getControllerResult(); 34 | 35 | if (!( 36 | null === $response 37 | || is_array($response) 38 | || $response instanceof Response 39 | || (is_object($response) && !method_exists($response, '__toString')) 40 | )) { 41 | $event->setResponse(new Response((string) $response)); 42 | } 43 | } 44 | 45 | public static function getSubscribedEvents() 46 | { 47 | return [ 48 | KernelEvents::VIEW => ['onKernelView', -10], 49 | ]; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Silex/src/Silex/Exception/ControllerFrozenException.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Silex\Exception; 13 | 14 | /** 15 | * Exception, is thrown when a frozen controller is modified. 16 | * 17 | * @author Igor Wiedler 18 | */ 19 | class ControllerFrozenException extends \RuntimeException 20 | { 21 | } 22 | -------------------------------------------------------------------------------- /src/Silex/src/Silex/ExceptionHandler.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Silex; 13 | 14 | use Symfony\Component\Debug\ExceptionHandler as DebugExceptionHandler; 15 | use Symfony\Component\Debug\Exception\FlattenException; 16 | use Symfony\Component\EventDispatcher\EventSubscriberInterface; 17 | use Symfony\Component\HttpFoundation\Response; 18 | use Symfony\Component\HttpKernel\Event\ExceptionEvent; 19 | use Symfony\Component\HttpKernel\KernelEvents; 20 | 21 | /** 22 | * Default exception handler. 23 | * 24 | * @author Fabien Potencier 25 | */ 26 | class ExceptionHandler implements EventSubscriberInterface 27 | { 28 | protected $debug; 29 | 30 | public function __construct($debug) 31 | { 32 | $this->debug = $debug; 33 | } 34 | 35 | public function onSilexError(ExceptionEvent $event) 36 | { 37 | $handler = new DebugExceptionHandler($this->debug); 38 | 39 | $exception = $event->getException(); 40 | if (!$exception instanceof FlattenException) { 41 | $exception = FlattenException::create($exception); 42 | } 43 | 44 | $response = Response::create($handler->getHtml($exception), $exception->getStatusCode(), $exception->getHeaders())->setCharset(ini_get('default_charset')); 45 | 46 | $event->setResponse($response); 47 | } 48 | 49 | /** 50 | * {@inheritdoc} 51 | */ 52 | public static function getSubscribedEvents() 53 | { 54 | return [KernelEvents::EXCEPTION => ['onSilexError', -255]]; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/Silex/src/Silex/Provider/CsrfServiceProvider.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Silex\Provider; 13 | 14 | use Pimple\Container; 15 | use Pimple\ServiceProviderInterface; 16 | use Symfony\Component\Security\Csrf\CsrfTokenManager; 17 | use Symfony\Component\Security\Csrf\TokenGenerator\UriSafeTokenGenerator; 18 | use Symfony\Component\Security\Csrf\TokenStorage\SessionTokenStorage; 19 | use Symfony\Component\Security\Csrf\TokenStorage\NativeSessionTokenStorage; 20 | 21 | /** 22 | * Symfony CSRF Security component Provider. 23 | * 24 | * @author Fabien Potencier 25 | */ 26 | class CsrfServiceProvider implements ServiceProviderInterface 27 | { 28 | public function register(Container $app) 29 | { 30 | $app['csrf.token_manager'] = function ($app) { 31 | return new CsrfTokenManager($app['csrf.token_generator'], $app['csrf.token_storage']); 32 | }; 33 | 34 | $app['csrf.token_storage'] = function ($app) { 35 | if (isset($app['session'])) { 36 | return new SessionTokenStorage($app['session'], $app['csrf.session_namespace']); 37 | } 38 | 39 | return new NativeSessionTokenStorage($app['csrf.session_namespace']); 40 | }; 41 | 42 | $app['csrf.token_generator'] = function ($app) { 43 | return new UriSafeTokenGenerator(); 44 | }; 45 | 46 | $app['csrf.session_namespace'] = '_csrf'; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Silex/src/Silex/Provider/ExceptionHandlerServiceProvider.php: -------------------------------------------------------------------------------- 1 | addSubscriber($app['exception_handler']); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Silex/src/Silex/Provider/HttpCache/HttpCache.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Silex\Provider\HttpCache; 13 | 14 | use Symfony\Component\HttpKernel\HttpCache\HttpCache as BaseHttpCache; 15 | use Symfony\Component\HttpFoundation\Request; 16 | 17 | /** 18 | * HTTP Cache extension to allow using the run() shortcut. 19 | * 20 | * @author Fabien Potencier 21 | */ 22 | class HttpCache extends BaseHttpCache 23 | { 24 | /** 25 | * Handles the Request and delivers the Response. 26 | * 27 | * @param Request $request The Request object 28 | */ 29 | public function run(Request $request = null) 30 | { 31 | if (null === $request) { 32 | $request = Request::createFromGlobals(); 33 | } 34 | 35 | $response = $this->handle($request); 36 | $response->send(); 37 | $this->terminate($request, $response); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Silex/src/Silex/Provider/HttpCacheServiceProvider.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Silex\Provider; 13 | 14 | use Pimple\Container; 15 | use Pimple\ServiceProviderInterface; 16 | use Silex\Provider\HttpCache\HttpCache; 17 | use Silex\Api\EventListenerProviderInterface; 18 | use Symfony\Component\EventDispatcher\EventDispatcherInterface; 19 | use Symfony\Component\HttpKernel\HttpCache\Esi; 20 | use Symfony\Component\HttpKernel\HttpCache\Store; 21 | use Symfony\Component\HttpKernel\EventListener\SurrogateListener; 22 | 23 | /** 24 | * Symfony HttpKernel component Provider for HTTP cache. 25 | * 26 | * @author Fabien Potencier 27 | */ 28 | class HttpCacheServiceProvider implements ServiceProviderInterface, EventListenerProviderInterface 29 | { 30 | public function register(Container $app) 31 | { 32 | $app['http_cache'] = function ($app) { 33 | $app['http_cache.options'] = array_replace( 34 | [ 35 | 'debug' => $app['debug'], 36 | ], $app['http_cache.options'] 37 | ); 38 | 39 | return new HttpCache($app, $app['http_cache.store'], $app['http_cache.esi'], $app['http_cache.options']); 40 | }; 41 | 42 | $app['http_cache.esi'] = function ($app) { 43 | return new Esi(); 44 | }; 45 | 46 | $app['http_cache.store'] = function ($app) { 47 | return new Store($app['http_cache.cache_dir']); 48 | }; 49 | 50 | $app['http_cache.esi_listener'] = function ($app) { 51 | return new SurrogateListener($app['http_cache.esi']); 52 | }; 53 | 54 | $app['http_cache.options'] = []; 55 | } 56 | 57 | public function subscribe(Container $app, EventDispatcherInterface $dispatcher) 58 | { 59 | $dispatcher->addSubscriber($app['http_cache.esi_listener']); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/Silex/src/Silex/Provider/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010-2015 Fabien Potencier 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is furnished 8 | to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /src/Silex/src/Silex/Provider/LocaleServiceProvider.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Silex\Provider; 13 | 14 | use Pimple\Container; 15 | use Pimple\ServiceProviderInterface; 16 | use Silex\Api\EventListenerProviderInterface; 17 | use Silex\Provider\Locale\LocaleListener; 18 | use Symfony\Component\EventDispatcher\EventDispatcherInterface; 19 | 20 | /** 21 | * Locale Provider. 22 | * 23 | * @author Fabien Potencier 24 | */ 25 | class LocaleServiceProvider implements ServiceProviderInterface, EventListenerProviderInterface 26 | { 27 | public function register(Container $app) 28 | { 29 | $app['locale.listener'] = function ($app) { 30 | return new LocaleListener($app, $app['locale'], $app['request_stack'], isset($app['request_context']) ? $app['request_context'] : null); 31 | }; 32 | 33 | $app['locale'] = 'en'; 34 | } 35 | 36 | public function subscribe(Container $app, EventDispatcherInterface $dispatcher) 37 | { 38 | $dispatcher->addSubscriber($app['locale.listener']); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Silex/src/Silex/Provider/Routing/LazyRequestMatcher.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Silex\Provider\Routing; 13 | 14 | use Symfony\Component\HttpFoundation\Request; 15 | use Symfony\Component\Routing\Matcher\RequestMatcherInterface; 16 | use Symfony\Component\Routing\Matcher\UrlMatcherInterface; 17 | 18 | /** 19 | * Implements a lazy UrlMatcher. 20 | * 21 | * @author Igor Wiedler 22 | * @author Jérôme Tamarelle 23 | */ 24 | class LazyRequestMatcher implements RequestMatcherInterface 25 | { 26 | private $factory; 27 | 28 | public function __construct(\Closure $factory) 29 | { 30 | $this->factory = $factory; 31 | } 32 | 33 | /** 34 | * Returns the corresponding RequestMatcherInterface instance. 35 | * 36 | * @return UrlMatcherInterface 37 | */ 38 | public function getRequestMatcher() 39 | { 40 | $matcher = call_user_func($this->factory); 41 | if (!$matcher instanceof RequestMatcherInterface) { 42 | throw new \LogicException("Factory supplied to LazyRequestMatcher must return implementation of Symfony\Component\Routing\RequestMatcherInterface."); 43 | } 44 | 45 | return $matcher; 46 | } 47 | 48 | /** 49 | * {@inheritdoc} 50 | */ 51 | public function matchRequest(Request $request): array 52 | { 53 | return $this->getRequestMatcher()->matchRequest($request); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Silex/src/Silex/Provider/Routing/RedirectableUrlMatcher.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Silex\Provider\Routing; 13 | 14 | use Symfony\Component\HttpFoundation\RedirectResponse; 15 | use Symfony\Component\Routing\Matcher\RedirectableUrlMatcher as BaseRedirectableUrlMatcher; 16 | 17 | /** 18 | * Implements the RedirectableUrlMatcherInterface for Silex. 19 | * 20 | * @author Fabien Potencier 21 | */ 22 | class RedirectableUrlMatcher extends BaseRedirectableUrlMatcher 23 | { 24 | /** 25 | * {@inheritdoc} 26 | */ 27 | public function redirect(string $path, string $route, ?string $scheme = null) : array 28 | { 29 | $url = $this->context->getBaseUrl().$path; 30 | $query = $this->context->getQueryString() ?: ''; 31 | 32 | if ('' !== $query) { 33 | $url .= '?'.$query; 34 | } 35 | 36 | if ($this->context->getHost()) { 37 | if ($scheme) { 38 | $port = ''; 39 | if ('http' === $scheme && 80 != $this->context->getHttpPort()) { 40 | $port = ':'.$this->context->getHttpPort(); 41 | } elseif ('https' === $scheme && 443 != $this->context->getHttpsPort()) { 42 | $port = ':'.$this->context->getHttpsPort(); 43 | } 44 | 45 | $url = $scheme.'://'.$this->context->getHost().$port.$url; 46 | } 47 | } 48 | 49 | return [ 50 | '_controller' => function ($url) { return new RedirectResponse($url, 301); }, 51 | '_route' => $route, 52 | 'url' => $url, 53 | ]; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Silex/src/Silex/Provider/SerializerServiceProvider.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Silex\Provider; 13 | 14 | use Pimple\Container; 15 | use Pimple\ServiceProviderInterface; 16 | use Symfony\Component\Serializer\Serializer; 17 | use Symfony\Component\Serializer\Encoder\JsonEncoder; 18 | use Symfony\Component\Serializer\Encoder\XmlEncoder; 19 | use Symfony\Component\Serializer\Normalizer\CustomNormalizer; 20 | use Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer; 21 | 22 | /** 23 | * Symfony Serializer component Provider. 24 | * 25 | * @author Fabien Potencier 26 | * @author Marijn Huizendveld 27 | */ 28 | class SerializerServiceProvider implements ServiceProviderInterface 29 | { 30 | /** 31 | * {@inheritdoc} 32 | * 33 | * This method registers a serializer service. {@link http://api.symfony.com/master/Symfony/Component/Serializer/Serializer.html 34 | * The service is provided by the Symfony Serializer component}. 35 | */ 36 | public function register(Container $app) 37 | { 38 | $app['serializer'] = function ($app) { 39 | return new Serializer($app['serializer.normalizers'], $app['serializer.encoders']); 40 | }; 41 | 42 | $app['serializer.encoders'] = function () { 43 | return [new JsonEncoder(), new XmlEncoder()]; 44 | }; 45 | 46 | $app['serializer.normalizers'] = function () { 47 | return [new CustomNormalizer(), new GetSetMethodNormalizer()]; 48 | }; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Silex/src/Silex/Provider/ServiceControllerServiceProvider.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Silex\Provider; 13 | 14 | use Pimple\Container; 15 | use Pimple\ServiceProviderInterface; 16 | use Silex\ServiceControllerResolver; 17 | 18 | class ServiceControllerServiceProvider implements ServiceProviderInterface 19 | { 20 | public function register(Container $app) 21 | { 22 | $app->extend('resolver', function ($resolver, $app) { 23 | return new ServiceControllerResolver($resolver, $app['callback_resolver']); 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Silex/src/Silex/Provider/Session/SessionListener.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Silex\Provider\Session; 13 | 14 | use Pimple\Container; 15 | use Symfony\Component\HttpKernel\EventListener\SessionListener as BaseSessionListener; 16 | 17 | /** 18 | * Sets the session in the request. 19 | * 20 | * @author Fabien Potencier 21 | */ 22 | class SessionListener extends BaseSessionListener 23 | { 24 | private $app; 25 | 26 | public function __construct(Container $app) 27 | { 28 | $this->app = $app; 29 | } 30 | 31 | protected function getSession() 32 | { 33 | if (!isset($this->app['session'])) { 34 | return; 35 | } 36 | 37 | return $this->app['session']; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Silex/src/Silex/Provider/Session/TestSessionListener.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Silex\Provider\Session; 13 | 14 | use Pimple\Container; 15 | use Symfony\Component\HttpKernel\EventListener\TestSessionListener as BaseTestSessionListener; 16 | 17 | /** 18 | * Simulates sessions for testing purpose. 19 | * 20 | * @author Fabien Potencier 21 | */ 22 | class TestSessionListener extends BaseTestSessionListener 23 | { 24 | private $app; 25 | 26 | public function __construct(Container $app) 27 | { 28 | $this->app = $app; 29 | } 30 | 31 | protected function getSession() 32 | { 33 | if (!isset($this->app['session'])) { 34 | return; 35 | } 36 | 37 | return $this->app['session']; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Silex/src/Silex/Provider/Twig/RuntimeLoader.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Silex\Provider\Twig; 13 | 14 | use Pimple\Container; 15 | 16 | /** 17 | * Loads Twig extension runtimes via Pimple. 18 | * 19 | * @author Fabien Potencier 20 | */ 21 | class RuntimeLoader implements \Twig\RuntimeLoader\RuntimeLoaderInterface 22 | { 23 | private $container; 24 | private $mapping; 25 | 26 | public function __construct(Container $container, array $mapping) 27 | { 28 | $this->container = $container; 29 | $this->mapping = $mapping; 30 | } 31 | 32 | /** 33 | * {@inheritdoc} 34 | */ 35 | public function load($class) 36 | { 37 | if (isset($this->mapping[$class])) { 38 | return $this->container[$this->mapping[$class]]; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Silex/src/Silex/Provider/Validator/ConstraintValidatorFactory.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Silex\Provider\Validator; 13 | 14 | use Pimple\Container; 15 | use Symfony\Component\Validator\Constraint; 16 | use Symfony\Component\Validator\ConstraintValidatorFactory as BaseConstraintValidatorFactory; 17 | 18 | /** 19 | * Uses a service container to create constraint validators with dependencies. 20 | * 21 | * @author Kris Wallsmith 22 | * @author Alex Kalyvitis 23 | */ 24 | class ConstraintValidatorFactory extends BaseConstraintValidatorFactory 25 | { 26 | /** 27 | * @var Container 28 | */ 29 | protected $container; 30 | 31 | /** 32 | * @var array 33 | */ 34 | protected $serviceNames; 35 | 36 | /** 37 | * Constructor. 38 | * 39 | * @param Container $container DI container 40 | * @param array $serviceNames Validator service names 41 | */ 42 | public function __construct(Container $container, array $serviceNames = [], $propertyAccessor = null) 43 | { 44 | parent::__construct($propertyAccessor); 45 | 46 | $this->container = $container; 47 | $this->serviceNames = $serviceNames; 48 | } 49 | 50 | /** 51 | * {@inheritdoc} 52 | */ 53 | public function getInstance(Constraint $constraint) 54 | { 55 | $name = $constraint->validatedBy(); 56 | 57 | if (isset($this->serviceNames[$name])) { 58 | return $this->container[$this->serviceNames[$name]]; 59 | } 60 | 61 | return parent::getInstance($constraint); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/Silex/src/Silex/Provider/VarDumperServiceProvider.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Silex\Provider; 13 | 14 | use Pimple\Container; 15 | use Pimple\ServiceProviderInterface; 16 | use Silex\Application; 17 | use Silex\Api\BootableProviderInterface; 18 | use Symfony\Component\VarDumper\VarDumper; 19 | use Symfony\Component\VarDumper\Cloner\VarCloner; 20 | use Symfony\Component\VarDumper\Dumper\CliDumper; 21 | 22 | /** 23 | * Symfony Var Dumper component Provider. 24 | * 25 | * @author Fabien Potencier 26 | */ 27 | class VarDumperServiceProvider implements ServiceProviderInterface, BootableProviderInterface 28 | { 29 | public function register(Container $app) 30 | { 31 | $app['var_dumper.cli_dumper'] = function ($app) { 32 | return new CliDumper($app['var_dumper.dump_destination'], $app['charset']); 33 | }; 34 | 35 | $app['var_dumper.cloner'] = function ($app) { 36 | return new VarCloner(); 37 | }; 38 | 39 | $app['var_dumper.dump_destination'] = null; 40 | } 41 | 42 | public function boot(Application $app) 43 | { 44 | if (!$app['debug']) { 45 | return; 46 | } 47 | 48 | // This code is here to lazy load the dump stack. This default 49 | // configuration for CLI mode is overridden in HTTP mode on 50 | // 'kernel.request' event 51 | VarDumper::setHandler(function ($var) use ($app) { 52 | VarDumper::setHandler($handler = function ($var) use ($app) { 53 | $app['var_dumper.cli_dumper']->dump($app['var_dumper.cloner']->cloneVar($var)); 54 | }); 55 | $handler($var); 56 | }); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/Silex/src/Silex/Provider/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "minimum-stability": "dev", 3 | "name": "silex/providers", 4 | "description": "The Silex providers", 5 | "keywords": ["microframework"], 6 | "homepage": "http://silex.sensiolabs.org", 7 | "license": "MIT", 8 | "authors": [ 9 | { 10 | "name": "Fabien Potencier", 11 | "email": "fabien@symfony.com" 12 | }, 13 | { 14 | "name": "Igor Wiedler", 15 | "email": "igor@wiedler.ch" 16 | } 17 | ], 18 | "require": { 19 | "php": ">=5.5.9", 20 | "pimple/pimple": "~3.0", 21 | "silex/api": "~2.2" 22 | }, 23 | "autoload": { 24 | "psr-4": { "Silex\\Provider\\": "" } 25 | }, 26 | "extra": { 27 | "branch-alias": { 28 | "dev-master": "2.3.x-dev" 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Silex/src/Silex/Route/SecurityTrait.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Silex\Route; 13 | 14 | use Symfony\Component\Security\Core\Exception\AccessDeniedException; 15 | 16 | /** 17 | * Security trait. 18 | * 19 | * @author Fabien Potencier 20 | */ 21 | trait SecurityTrait 22 | { 23 | public function secure($roles) 24 | { 25 | $this->before(function ($request, $app) use ($roles) { 26 | if (!$app['security.authorization_checker']->isGranted($roles)) { 27 | throw new AccessDeniedException(); 28 | } 29 | }); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Silex/src/Silex/ServiceControllerResolver.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Silex; 13 | 14 | use Symfony\Component\HttpFoundation\Request; 15 | use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface; 16 | 17 | /** 18 | * Enables name_of_service:method_name syntax for declaring controllers. 19 | * 20 | * @see http://silex.sensiolabs.org/doc/providers/service_controller.html 21 | */ 22 | class ServiceControllerResolver implements ControllerResolverInterface 23 | { 24 | protected $controllerResolver; 25 | protected $callbackResolver; 26 | 27 | /** 28 | * Constructor. 29 | * 30 | * @param ControllerResolverInterface $controllerResolver A ControllerResolverInterface instance to delegate to 31 | * @param CallbackResolver $callbackResolver A service resolver instance 32 | */ 33 | public function __construct(ControllerResolverInterface $controllerResolver, CallbackResolver $callbackResolver) 34 | { 35 | $this->controllerResolver = $controllerResolver; 36 | $this->callbackResolver = $callbackResolver; 37 | } 38 | 39 | /** 40 | * {@inheritdoc} 41 | */ 42 | public function getController(Request $request) 43 | { 44 | $controller = $request->attributes->get('_controller', null); 45 | 46 | if (!$this->callbackResolver->isValid($controller)) { 47 | return $this->controllerResolver->getController($request); 48 | } 49 | 50 | return $this->callbackResolver->convertCallback($controller); 51 | } 52 | 53 | /** 54 | * {@inheritdoc} 55 | */ 56 | public function getArguments(Request $request, $controller) 57 | { 58 | return $this->controllerResolver->getArguments($request, $controller); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/Silex/src/Silex/WebTestCase.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Silex; 13 | 14 | use PHPUnit\Framework\TestCase; 15 | use Symfony\Component\HttpKernel\Client; 16 | use Symfony\Component\HttpKernel\HttpKernelInterface; 17 | 18 | /** 19 | * WebTestCase is the base class for functional tests. 20 | * 21 | * @author Igor Wiedler 22 | */ 23 | abstract class WebTestCase extends TestCase 24 | { 25 | /** 26 | * HttpKernelInterface instance. 27 | * 28 | * @var HttpKernelInterface 29 | */ 30 | protected $app; 31 | 32 | /** 33 | * PHPUnit setUp for setting up the application. 34 | * 35 | * Note: Child classes that define a setUp method must call 36 | * parent::setUp(). 37 | */ 38 | protected function setUp() 39 | { 40 | $this->app = $this->createApplication(); 41 | } 42 | 43 | /** 44 | * Creates the application. 45 | * 46 | * @return HttpKernelInterface 47 | */ 48 | abstract public function createApplication(); 49 | 50 | /** 51 | * Creates a Client. 52 | * 53 | * @param array $server Server parameters 54 | * 55 | * @return Client A Client instance 56 | */ 57 | public function createClient(array $server = []) 58 | { 59 | if (!class_exists('Symfony\Component\BrowserKit\Client')) { 60 | throw new \LogicException('Component "symfony/browser-kit" is required by WebTestCase.'.PHP_EOL.'Run composer require symfony/browser-kit'); 61 | } 62 | 63 | return new Client($this->app, $server); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/Silex/tests/Silex/Tests/Application/FormApplication.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Silex\Tests\Application; 13 | 14 | use Silex\Application; 15 | 16 | class FormApplication extends Application 17 | { 18 | use Application\FormTrait; 19 | } 20 | -------------------------------------------------------------------------------- /src/Silex/tests/Silex/Tests/Application/FormTraitTest.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Silex\Tests\Application; 13 | 14 | use PHPUnit\Framework\TestCase; 15 | use Silex\Provider\FormServiceProvider; 16 | use Symfony\Component\Form\FormBuilder; 17 | 18 | /** 19 | * FormTrait test cases. 20 | * 21 | * @author Fabien Potencier 22 | */ 23 | class FormTraitTest extends TestCase 24 | { 25 | public function testForm() 26 | { 27 | $this->assertInstanceOf(FormBuilder::class, $this->createApplication()->form()); 28 | } 29 | 30 | public function testNamedForm() 31 | { 32 | $builder = $this->createApplication()->namedForm('foo'); 33 | 34 | $this->assertInstanceOf(FormBuilder::class, $builder); 35 | $this->assertSame('foo', $builder->getName()); 36 | } 37 | 38 | public function createApplication() 39 | { 40 | $app = new FormApplication(); 41 | $app->register(new FormServiceProvider()); 42 | 43 | return $app; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Silex/tests/Silex/Tests/Application/MonologApplication.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Silex\Tests\Application; 13 | 14 | use Silex\Application; 15 | 16 | class MonologApplication extends Application 17 | { 18 | use Application\MonologTrait; 19 | } 20 | -------------------------------------------------------------------------------- /src/Silex/tests/Silex/Tests/Application/MonologTraitTest.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Silex\Tests\Application; 13 | 14 | use PHPUnit\Framework\TestCase; 15 | use Silex\Provider\MonologServiceProvider; 16 | use Monolog\Handler\TestHandler; 17 | use Monolog\Logger; 18 | 19 | /** 20 | * @author Fabien Potencier 21 | */ 22 | class MonologTraitTest extends TestCase 23 | { 24 | public function testLog() 25 | { 26 | $app = $this->createApplication(); 27 | 28 | $app->log('Foo'); 29 | $app->log('Bar', [], Logger::DEBUG); 30 | $this->assertTrue($app['monolog.handler']->hasInfo('Foo')); 31 | $this->assertTrue($app['monolog.handler']->hasDebug('Bar')); 32 | } 33 | 34 | public function createApplication() 35 | { 36 | $app = new MonologApplication(); 37 | $app->register(new MonologServiceProvider(), [ 38 | 'monolog.handler' => function () use ($app) { 39 | return new TestHandler($app['monolog.level']); 40 | }, 41 | 'monolog.logfile' => 'php://memory', 42 | ]); 43 | 44 | return $app; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Silex/tests/Silex/Tests/Application/SecurityApplication.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Silex\Tests\Application; 13 | 14 | use Silex\Application; 15 | 16 | class SecurityApplication extends Application 17 | { 18 | use Application\SecurityTrait; 19 | } 20 | -------------------------------------------------------------------------------- /src/Silex/tests/Silex/Tests/Application/SwiftmailerApplication.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Silex\Tests\Application; 13 | 14 | use Silex\Application; 15 | 16 | class SwiftmailerApplication extends Application 17 | { 18 | use Application\SwiftmailerTrait; 19 | } 20 | -------------------------------------------------------------------------------- /src/Silex/tests/Silex/Tests/Application/SwiftmailerTraitTest.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Silex\Tests\Application; 13 | 14 | use PHPUnit\Framework\TestCase; 15 | use Silex\Provider\SwiftmailerServiceProvider; 16 | 17 | /** 18 | * @author Fabien Potencier 19 | */ 20 | class SwiftmailerTraitTest extends TestCase 21 | { 22 | public function testMail() 23 | { 24 | $app = $this->createApplication(); 25 | 26 | $message = $this->getMockBuilder('Swift_Message')->disableOriginalConstructor()->getMock(); 27 | $app['mailer'] = $mailer = $this->getMockBuilder('Swift_Mailer')->disableOriginalConstructor()->getMock(); 28 | $mailer->expects($this->once()) 29 | ->method('send') 30 | ->with($message) 31 | ; 32 | 33 | $app->mail($message); 34 | } 35 | 36 | public function createApplication() 37 | { 38 | $app = new SwiftmailerApplication(); 39 | $app->register(new SwiftmailerServiceProvider()); 40 | 41 | return $app; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Silex/tests/Silex/Tests/Application/TranslationApplication.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Silex\Tests\Application; 13 | 14 | use Silex\Application; 15 | 16 | class TranslationApplication extends Application 17 | { 18 | use Application\TranslationTrait; 19 | } 20 | -------------------------------------------------------------------------------- /src/Silex/tests/Silex/Tests/Application/TranslationTraitTest.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Silex\Tests\Application; 13 | 14 | use PHPUnit\Framework\TestCase; 15 | use Silex\Provider\TranslationServiceProvider; 16 | 17 | /** 18 | * @author Fabien Potencier 19 | */ 20 | class TranslationTraitTest extends TestCase 21 | { 22 | public function testTrans() 23 | { 24 | $app = $this->createApplication(); 25 | $app['translator'] = $translator = $this->getMockBuilder('Symfony\Component\Translation\Translator')->disableOriginalConstructor()->getMock(); 26 | $translator->expects($this->once())->method('trans'); 27 | $app->trans('foo'); 28 | } 29 | 30 | public function testTransChoice() 31 | { 32 | $app = $this->createApplication(); 33 | $app['translator'] = $translator = $this->getMockBuilder('Symfony\Component\Translation\Translator')->disableOriginalConstructor()->getMock(); 34 | $translator->expects($this->once())->method('transChoice'); 35 | $app->transChoice('foo', 2); 36 | } 37 | 38 | public function createApplication() 39 | { 40 | $app = new TranslationApplication(); 41 | $app->register(new TranslationServiceProvider()); 42 | 43 | return $app; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Silex/tests/Silex/Tests/Application/TwigApplication.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Silex\Tests\Application; 13 | 14 | use Silex\Application; 15 | 16 | class TwigApplication extends Application 17 | { 18 | use Application\TwigTrait; 19 | } 20 | -------------------------------------------------------------------------------- /src/Silex/tests/Silex/Tests/Application/UrlGeneratorApplication.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Silex\Tests\Application; 13 | 14 | use Silex\Application; 15 | 16 | class UrlGeneratorApplication extends Application 17 | { 18 | use Application\UrlGeneratorTrait; 19 | } 20 | -------------------------------------------------------------------------------- /src/Silex/tests/Silex/Tests/Application/UrlGeneratorTraitTest.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Silex\Tests\Application; 13 | 14 | use PHPUnit\Framework\TestCase; 15 | use Symfony\Component\Routing\Generator\UrlGeneratorInterface; 16 | 17 | /** 18 | * UrlGeneratorTrait test cases. 19 | * 20 | * @author Fabien Potencier 21 | */ 22 | class UrlGeneratorTraitTest extends TestCase 23 | { 24 | public function testUrl() 25 | { 26 | $app = new UrlGeneratorApplication(); 27 | $app['url_generator'] = $this->getMockBuilder('Symfony\Component\Routing\Generator\UrlGeneratorInterface')->disableOriginalConstructor()->getMock(); 28 | $app['url_generator']->expects($this->once())->method('generate')->with('foo', [], UrlGeneratorInterface::ABSOLUTE_URL); 29 | $app->url('foo'); 30 | } 31 | 32 | public function testPath() 33 | { 34 | $app = new UrlGeneratorApplication(); 35 | $app['url_generator'] = $this->getMockBuilder('Symfony\Component\Routing\Generator\UrlGeneratorInterface')->disableOriginalConstructor()->getMock(); 36 | $app['url_generator']->expects($this->once())->method('generate')->with('foo', [], UrlGeneratorInterface::ABSOLUTE_PATH); 37 | $app->path('foo'); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Silex/tests/Silex/Tests/Fixtures/Php7Controller.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Silex\Tests\Fixtures; 13 | 14 | use Silex\Application; 15 | 16 | class Php7Controller 17 | { 18 | public function typehintedAction(Application $application, string $name) 19 | { 20 | return 'Hello '.$application->escape($name).' in '.get_class($application); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Silex/tests/Silex/Tests/Fixtures/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "app.js": "some-random-hash.js" 3 | } -------------------------------------------------------------------------------- /src/Silex/tests/Silex/Tests/FunctionalTest.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Silex\Tests; 13 | 14 | use PHPUnit\Framework\TestCase; 15 | use Silex\Application; 16 | use Silex\Route; 17 | use Silex\ControllerCollection; 18 | use Symfony\Component\HttpFoundation\Request; 19 | use Symfony\Component\HttpFoundation\Response; 20 | 21 | /** 22 | * Functional test cases. 23 | * 24 | * @author Igor Wiedler 25 | */ 26 | class FunctionalTest extends TestCase 27 | { 28 | public function testBind() 29 | { 30 | $app = new Application(); 31 | 32 | $app->get('/', function () { 33 | return 'hello'; 34 | }) 35 | ->bind('homepage'); 36 | 37 | $app->get('/foo', function () { 38 | return 'foo'; 39 | }) 40 | ->bind('foo_abc'); 41 | 42 | $app->flush(); 43 | $routes = $app['routes']; 44 | $this->assertInstanceOf('Symfony\Component\Routing\Route', $routes->get('homepage')); 45 | $this->assertInstanceOf('Symfony\Component\Routing\Route', $routes->get('foo_abc')); 46 | } 47 | 48 | public function testMount() 49 | { 50 | $mounted = new ControllerCollection(new Route()); 51 | $mounted->get('/{name}', function ($name) { return new Response($name); }); 52 | 53 | $app = new Application(); 54 | $app->mount('/hello', $mounted); 55 | 56 | $response = $app->handle(Request::create('/hello/Silex')); 57 | $this->assertEquals('Silex', $response->getContent()); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/Silex/tests/Silex/Tests/JsonTest.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Silex\Tests; 13 | 14 | use PHPUnit\Framework\TestCase; 15 | use Silex\Application; 16 | 17 | /** 18 | * JSON test cases. 19 | * 20 | * @author Igor Wiedler 21 | */ 22 | class JsonTest extends TestCase 23 | { 24 | public function testJsonReturnsJsonResponse() 25 | { 26 | $app = new Application(); 27 | 28 | $response = $app->json(); 29 | $this->assertInstanceOf('Symfony\Component\HttpFoundation\JsonResponse', $response); 30 | $response = json_decode($response->getContent(), true); 31 | $this->assertSame([], $response); 32 | } 33 | 34 | public function testJsonUsesData() 35 | { 36 | $app = new Application(); 37 | 38 | $response = $app->json(['foo' => 'bar']); 39 | $this->assertSame('{"foo":"bar"}', $response->getContent()); 40 | } 41 | 42 | public function testJsonUsesStatus() 43 | { 44 | $app = new Application(); 45 | 46 | $response = $app->json([], 202); 47 | $this->assertSame(202, $response->getStatusCode()); 48 | } 49 | 50 | public function testJsonUsesHeaders() 51 | { 52 | $app = new Application(); 53 | 54 | $response = $app->json([], 200, ['ETag' => 'foo']); 55 | $this->assertSame('foo', $response->headers->get('ETag')); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Silex/tests/Silex/Tests/LazyDispatcherTest.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Silex\Tests; 13 | 14 | use PHPUnit\Framework\TestCase; 15 | use Silex\Application; 16 | use Symfony\Component\HttpFoundation\Request; 17 | 18 | class LazyDispatcherTest extends TestCase 19 | { 20 | /** @test */ 21 | public function beforeMiddlewareShouldNotCreateDispatcherEarly() 22 | { 23 | $dispatcherCreated = false; 24 | 25 | $app = new Application(); 26 | $app->extend('dispatcher', function ($dispatcher, $app) use (&$dispatcherCreated) { 27 | $dispatcherCreated = true; 28 | 29 | return $dispatcher; 30 | }); 31 | 32 | $app->before(function () {}); 33 | 34 | $this->assertFalse($dispatcherCreated); 35 | 36 | $request = Request::create('/'); 37 | $app->handle($request); 38 | 39 | $this->assertTrue($dispatcherCreated); 40 | } 41 | 42 | /** @test */ 43 | public function eventHelpersShouldDirectlyAddListenersAfterBoot() 44 | { 45 | $app = new Application(); 46 | 47 | $fired = false; 48 | $app->get('/', function () use ($app, &$fired) { 49 | $app->finish(function () use (&$fired) { 50 | $fired = true; 51 | }); 52 | }); 53 | 54 | $request = Request::create('/'); 55 | $response = $app->handle($request); 56 | $app->terminate($request, $response); 57 | 58 | $this->assertTrue($fired, 'Event was not fired'); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/Silex/tests/Silex/Tests/Provider/AssetServiceProviderTest.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Silex\Tests\Provider; 13 | 14 | use PHPUnit\Framework\TestCase; 15 | use Silex\Application; 16 | use Silex\Provider\AssetServiceProvider; 17 | 18 | class AssetServiceProviderTest extends TestCase 19 | { 20 | public function testGenerateAssetUrl() 21 | { 22 | $app = new Application(); 23 | $app->register(new AssetServiceProvider(), [ 24 | 'assets.version' => 'v1', 25 | 'assets.version_format' => '%s?version=%s', 26 | 'assets.named_packages' => [ 27 | 'css' => ['version' => 'css2', 'base_path' => '/whatever-makes-sense'], 28 | 'images' => ['base_urls' => ['https://img.example.com']], 29 | ], 30 | ]); 31 | 32 | $this->assertEquals('/foo.png?version=v1', $app['assets.packages']->getUrl('/foo.png')); 33 | $this->assertEquals('/whatever-makes-sense/foo.css?css2', $app['assets.packages']->getUrl('foo.css', 'css')); 34 | $this->assertEquals('https://img.example.com/foo.png', $app['assets.packages']->getUrl('/foo.png', 'images')); 35 | } 36 | 37 | public function testJsonManifestVersionStrategy() 38 | { 39 | $app = new Application(); 40 | $app->register(new AssetServiceProvider(), [ 41 | 'assets.json_manifest_path' => __DIR__.'/../Fixtures/manifest.json', 42 | ]); 43 | 44 | $this->assertEquals('/some-random-hash.js', $app['assets.packages']->getUrl('app.js')); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Silex/tests/Silex/Tests/Provider/FormServiceProviderTest/DisableCsrfExtension.php: -------------------------------------------------------------------------------- 1 | setDefaults([ 14 | 'csrf_protection' => false, 15 | ]); 16 | } 17 | 18 | public function getExtendedType() 19 | { 20 | return FormType::class; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Silex/tests/Silex/Tests/Provider/HttpFragmentServiceProviderTest.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Silex\Tests\Provider; 13 | 14 | use PHPUnit\Framework\TestCase; 15 | use Silex\Application; 16 | use Silex\Provider\HttpCacheServiceProvider; 17 | use Silex\Provider\HttpFragmentServiceProvider; 18 | use Silex\Provider\TwigServiceProvider; 19 | use Symfony\Component\HttpFoundation\Request; 20 | 21 | class HttpFragmentServiceProviderTest extends TestCase 22 | { 23 | public function testRenderFunction() 24 | { 25 | $app = new Application(); 26 | unset($app['exception_handler']); 27 | 28 | $app->register(new HttpFragmentServiceProvider()); 29 | $app->register(new HttpCacheServiceProvider(), ['http_cache.cache_dir' => sys_get_temp_dir()]); 30 | $app->register(new TwigServiceProvider(), [ 31 | 'twig.templates' => [ 32 | 'hello' => '{{ render("/foo") }}{{ render_esi("/foo") }}{{ render_hinclude("/foo") }}', 33 | 'foo' => 'foo', 34 | ], 35 | ]); 36 | 37 | $app->get('/hello', function () use ($app) { 38 | return $app['twig']->render('hello'); 39 | }); 40 | 41 | $app->get('/foo', function () use ($app) { 42 | return $app['twig']->render('foo'); 43 | }); 44 | 45 | $response = $app['http_cache']->handle(Request::create('/hello')); 46 | 47 | $this->assertEquals('foofoo', $response->getContent()); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Silex/tests/Silex/Tests/Provider/SerializerServiceProviderTest.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Silex\Tests\Provider; 13 | 14 | use PHPUnit\Framework\TestCase; 15 | use Silex\Application; 16 | use Silex\Provider\SerializerServiceProvider; 17 | 18 | /** 19 | * SerializerServiceProvider test cases. 20 | * 21 | * @author Fabien Potencier 22 | */ 23 | class SerializerServiceProviderTest extends TestCase 24 | { 25 | public function testRegister() 26 | { 27 | $app = new Application(); 28 | 29 | $app->register(new SerializerServiceProvider()); 30 | 31 | $this->assertInstanceOf("Symfony\Component\Serializer\Serializer", $app['serializer']); 32 | $this->assertTrue($app['serializer']->supportsEncoding('xml')); 33 | $this->assertTrue($app['serializer']->supportsEncoding('json')); 34 | $this->assertTrue($app['serializer']->supportsDecoding('xml')); 35 | $this->assertTrue($app['serializer']->supportsDecoding('json')); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Silex/tests/Silex/Tests/Provider/SpoolStub.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Silex\Tests\Provider; 13 | 14 | class SpoolStub implements \Swift_Spool 15 | { 16 | private $messages = []; 17 | public $hasFlushed = false; 18 | 19 | public function getMessages() 20 | { 21 | return $this->messages; 22 | } 23 | 24 | public function start() 25 | { 26 | } 27 | 28 | public function stop() 29 | { 30 | } 31 | 32 | public function isStarted() 33 | { 34 | return count($this->messages) > 0; 35 | } 36 | 37 | public function queueMessage(\Swift_Mime_Message $message) 38 | { 39 | $this->messages[] = clone $message; 40 | } 41 | 42 | public function flushQueue(\Swift_Transport $transport, &$failedRecipients = null) 43 | { 44 | $this->hasFlushed = true; 45 | $this->messages = []; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Silex/tests/Silex/Tests/Provider/ValidatorServiceProviderTest/Constraint/Custom.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Silex\Tests\Provider\ValidatorServiceProviderTest\Constraint; 13 | 14 | use Symfony\Component\Validator\Constraint; 15 | 16 | /** 17 | * @author Alex Kalyvitis 18 | */ 19 | class Custom extends Constraint 20 | { 21 | public $message = 'This field must be ...'; 22 | public $table; 23 | public $field; 24 | 25 | public function validatedBy() 26 | { 27 | return 'test.custom.validator'; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Silex/tests/Silex/Tests/Provider/ValidatorServiceProviderTest/Constraint/CustomValidator.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Silex\Tests\Provider\ValidatorServiceProviderTest\Constraint; 13 | 14 | use Symfony\Component\Validator\Constraint; 15 | use Symfony\Component\Validator\ConstraintValidator; 16 | 17 | /** 18 | * @author Alex Kalyvitis 19 | */ 20 | class CustomValidator extends ConstraintValidator 21 | { 22 | public function isValid($value, Constraint $constraint) 23 | { 24 | // Validate... 25 | return true; 26 | } 27 | 28 | public function validate($value, Constraint $constraint) 29 | { 30 | return $this->isValid($value, $constraint); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Silex/tests/Silex/Tests/Route/SecurityRoute.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Silex\Tests\Route; 13 | 14 | use Silex\Route; 15 | 16 | class SecurityRoute extends Route 17 | { 18 | use Route\SecurityTrait; 19 | } 20 | -------------------------------------------------------------------------------- /src/Silex/tests/Silex/Tests/ServiceControllerResolverRouterTest.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Silex\Tests; 13 | 14 | use Silex\Application; 15 | use Silex\Provider\ServiceControllerServiceProvider; 16 | use Symfony\Component\HttpFoundation\Request; 17 | 18 | /** 19 | * Router test cases, using the ServiceControllerResolver. 20 | */ 21 | class ServiceControllerResolverRouterTest extends RouterTest 22 | { 23 | public function testServiceNameControllerSyntax() 24 | { 25 | $app = new Application(); 26 | $app->register(new ServiceControllerServiceProvider()); 27 | 28 | $app['service_name'] = function () { 29 | return new MyController(); 30 | }; 31 | 32 | $app->get('/bar', 'service_name:getBar'); 33 | 34 | $this->checkRouteResponse($app, '/bar', 'bar'); 35 | } 36 | 37 | protected function checkRouteResponse(Application $app, $path, $expectedContent, $method = 'get', $message = null) 38 | { 39 | $request = Request::create($path, $method); 40 | $response = $app->handle($request); 41 | $this->assertEquals($expectedContent, $response->getContent(), $message); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Silex/tests/Silex/Tests/StreamTest.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Silex\Tests; 13 | 14 | use PHPUnit\Framework\TestCase; 15 | use Silex\Application; 16 | use Symfony\Component\HttpFoundation\Request; 17 | 18 | /** 19 | * Stream test cases. 20 | * 21 | * @author Igor Wiedler 22 | */ 23 | class StreamTest extends TestCase 24 | { 25 | public function testStreamReturnsStreamingResponse() 26 | { 27 | $app = new Application(); 28 | 29 | $response = $app->stream(); 30 | $this->assertInstanceOf('Symfony\Component\HttpFoundation\StreamedResponse', $response); 31 | $this->assertFalse($response->getContent()); 32 | } 33 | 34 | public function testStreamActuallyStreams() 35 | { 36 | $i = 0; 37 | 38 | $stream = function () use (&$i) { 39 | ++$i; 40 | }; 41 | 42 | $app = new Application(); 43 | $response = $app->stream($stream); 44 | 45 | $this->assertEquals(0, $i); 46 | 47 | $request = Request::create('/stream'); 48 | $response->prepare($request); 49 | $response->sendContent(); 50 | 51 | $this->assertEquals(1, $i); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Silex/tests/Silex/Tests/WebTestCaseTest.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * This source file is subject to the MIT license that is bundled 9 | * with this source code in the file LICENSE. 10 | */ 11 | 12 | namespace Silex\Tests; 13 | 14 | use Silex\Application; 15 | use Silex\WebTestCase; 16 | use Symfony\Component\HttpFoundation\Request; 17 | 18 | /** 19 | * Functional test cases. 20 | * 21 | * @author Igor Wiedler 22 | */ 23 | class WebTestCaseTest extends WebTestCase 24 | { 25 | public function createApplication() 26 | { 27 | $app = new Application(); 28 | 29 | $app->match('/hello', function () { 30 | return 'world'; 31 | }); 32 | 33 | $app->match('/html', function () { 34 | return '

title

'; 35 | }); 36 | 37 | $app->match('/server', function (Request $request) use ($app) { 38 | $user = $request->server->get('PHP_AUTH_USER'); 39 | $pass = $request->server->get('PHP_AUTH_PW'); 40 | 41 | return "

$user:$pass

"; 42 | }); 43 | 44 | return $app; 45 | } 46 | 47 | public function testGetHello() 48 | { 49 | $client = $this->createClient(); 50 | 51 | $client->request('GET', '/hello'); 52 | $response = $client->getResponse(); 53 | $this->assertTrue($response->isSuccessful()); 54 | $this->assertEquals('world', $response->getContent()); 55 | } 56 | 57 | public function testCrawlerFilter() 58 | { 59 | $client = $this->createClient(); 60 | 61 | $crawler = $client->request('GET', '/html'); 62 | $this->assertEquals('title', $crawler->filter('h1')->text()); 63 | } 64 | 65 | public function testServerVariables() 66 | { 67 | $user = 'klaus'; 68 | $pass = '123456'; 69 | 70 | $client = $this->createClient([ 71 | 'PHP_AUTH_USER' => $user, 72 | 'PHP_AUTH_PW' => $pass, 73 | ]); 74 | 75 | $crawler = $client->request('GET', '/server'); 76 | $this->assertEquals("$user:$pass", $crawler->filter('h1')->text()); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/browser/bundle.js: -------------------------------------------------------------------------------- 1 | window.gitlist.codemirrorTheme = { 2 | light: 'idea', 3 | dark: 'dracula', 4 | } 5 | 6 | require('@fortawesome/fontawesome-free/css/all.css') 7 | 8 | window.gitlist.snapckbarLongTimeout = 20000; 9 | global.jQuery = require('jquery') 10 | global.$ = global.jQuery; 11 | require('snackbarjs'); 12 | require('jquery.redirect'); 13 | require('bootstrap'); 14 | 15 | global.twemoji = require('twemoji').default 16 | const prodDir = require('../../package').corifeus["prod-dir"]; 17 | global.twemoji.base = `${prodDir}/twemoji/`; 18 | 19 | require('./js/network.js') 20 | 21 | require('./js/gitgraph.js/gitgraph.css') 22 | require('./js/gitgraph.js/gitgraph.js') 23 | 24 | require('./js/tree') 25 | require('./js/treegraph') 26 | require('./js/markdown') 27 | require('./js/clone-buttons') 28 | require('./js/paginate') 29 | require('./js/browser') 30 | require('./js/index.js') 31 | require('./js/file') 32 | require('./js/theme-switcher.js') 33 | require('./js/commit') 34 | require('./js/breadcrumb') 35 | require('./js/commits-list') 36 | require('./js/file-fragment') 37 | require('./js/change-log') 38 | require('./js/todo') 39 | require('./js/global') 40 | 41 | 42 | -------------------------------------------------------------------------------- /src/browser/codemirror.js: -------------------------------------------------------------------------------- 1 | require('codemirror/lib/codemirror.css') 2 | require(`codemirror/theme/idea.css`) 3 | require(`codemirror/theme/dracula.css`) 4 | 5 | global.CodeMirror = require('codemirror'); 6 | require('codemirror/addon/selection/active-line.js') 7 | require('codemirror/addon/mode/simple'); 8 | require('codemirror/addon/mode/multiplex'); 9 | require('codemirror/mode/cmake/cmake'); 10 | require('codemirror/mode/clike/clike'); 11 | require('codemirror/mode/css/css'); 12 | require('codemirror/mode/dockerfile/dockerfile'); 13 | require('codemirror/mode/go/go'); 14 | require('codemirror/mode/handlebars/handlebars'); 15 | require('codemirror/mode/htmlmixed/htmlmixed'); 16 | require('codemirror/mode/javascript/javascript'); 17 | require('codemirror/mode/jsx/jsx'); 18 | require('codemirror/mode/perl/perl'); 19 | require('codemirror/mode/php/php'); 20 | require('codemirror/mode/powershell/powershell'); 21 | require('codemirror/mode/python/python'); 22 | require('codemirror/mode/properties/properties'); 23 | require('codemirror/mode/ruby/ruby'); 24 | require('codemirror/mode/sass/sass'); 25 | require('codemirror/mode/shell/shell'); 26 | require('codemirror/mode/vbscript/vbscript'); 27 | require('codemirror/mode/groovy/groovy'); 28 | require('codemirror/mode/erlang/erlang'); 29 | require('codemirror/mode/ecl/ecl'); 30 | require('codemirror/mode/coffeescript/coffeescript'); 31 | require('codemirror/mode/clojure/clojure'); 32 | require('codemirror/mode/diff/diff'); 33 | require('codemirror/mode/smalltalk/smalltalk'); 34 | require('codemirror/mode/rust/rust'); 35 | require('codemirror/mode/lua/lua'); 36 | require('codemirror/mode/haskell/haskell'); 37 | require('codemirror/mode/markdown/markdown'); 38 | require('codemirror/mode/scheme/scheme'); 39 | require('codemirror/mode/r/r'); 40 | require('codemirror/mode/rst/rst'); 41 | require('codemirror/mode/ntriples/ntriples'); 42 | require('codemirror/mode/pascal/pascal'); 43 | require('codemirror/mode/sql/sql'); 44 | require('codemirror/mode/swift/swift'); 45 | require('codemirror/mode/twig/twig'); 46 | require('codemirror/mode/vue/vue'); 47 | require('codemirror/mode/xml/xml'); 48 | require('codemirror/mode/xquery/xquery'); 49 | require('codemirror/mode/yaml/yaml'); 50 | require('codemirror/mode/protobuf/protobuf'); -------------------------------------------------------------------------------- /src/browser/js/blame.js: -------------------------------------------------------------------------------- 1 | /* 2 | It uses the file-fragement 3 | */ -------------------------------------------------------------------------------- /src/browser/js/breadcrumb.js: -------------------------------------------------------------------------------- 1 | $(function () { 2 | const $gitActions = $('#p3x-gitlist-breadcrumb-git'); 3 | 4 | if ($gitActions.length === 0) { 5 | return; 6 | } 7 | 8 | const $gitActionFetch = $('#p3x-gitlist-breadcrumb-git-fetch') 9 | 10 | $gitActionFetch.on('click', async () => { 11 | const url = `${window.gitlist.basepath}/${window.gitlist.repo}/git-helper/${window.gitlist.branch}/fetch-origin` 12 | try { 13 | const request = $.ajax({ 14 | url: url, 15 | type: 'POST', 16 | }) 17 | 18 | const response = await request; 19 | const json = JSON.parse(response) 20 | 21 | if (json.error === true) { 22 | window.gitlist.ajaxErrorHandler(json); 23 | return; 24 | } 25 | 26 | $.snackbar({ 27 | htmlAllowed: true, 28 | content: json.message, 29 | }) 30 | } catch (e) { 31 | window.gitlist.ajaxErrorHandler(e); 32 | 33 | } 34 | }) 35 | 36 | }) 37 | -------------------------------------------------------------------------------- /src/browser/js/change-log.js: -------------------------------------------------------------------------------- 1 | let $changelogModal 2 | let changelogHtml; 3 | window.gitlist.changeLog = async () => { 4 | if (changelogHtml === undefined) { 5 | try { 6 | let response = await $.ajax('https://raw.githubusercontent.com/patrikx3/gitlist/master/change-log.md') 7 | const $changelogModalBody = $('#p3x-gitlist-modal-changelog-body') 8 | 9 | response = $('