parent
0b08b2b932
commit
5ff1c4e187
@ -0,0 +1,13 @@ |
||||
<?php |
||||
|
||||
// autoload_files.php generated by Composer |
||||
|
||||
$vendorDir = dirname(dirname(__FILE__)); |
||||
$baseDir = dirname($vendorDir); |
||||
|
||||
return array( |
||||
$vendorDir . '/symfony/intl/Symfony/Component/Intl/Resources/stubs/functions.php', |
||||
$vendorDir . '/swiftmailer/swiftmailer/lib/swift_required.php', |
||||
$vendorDir . '/ezyang/htmlpurifier/library/HTMLPurifier.composer.php', |
||||
$vendorDir . '/kriswallsmith/assetic/src/functions.php', |
||||
); |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,77 @@ |
||||
1.4.0 / 2013-07-04 |
||||
================== |
||||
|
||||
* Configuration cache is now automatically bursted when debug is true and a file have changed. |
||||
* Introduce a ResourceCollection object that ConfigLoaders must add Resources to when loading. This |
||||
caused a BC break in the Configurator constructor arguments. |
||||
* Debug and cache dir is now setters on the Configurator instead of constructor arguments. |
||||
* Changed package name to `flint/flint`. |
||||
|
||||
1.3.1 / 2013-06-26 |
||||
================== |
||||
|
||||
* PHP Scalar values are now converted to its string counter part `true` will be `'true'` and so forth. |
||||
* Replacement for `%placeholder%` and `#PLACEHOLDER#` have been made more robust. Also `%placeholder%` only matches |
||||
lowercase characters and `#PLACEHOLDER#` only matches uppercase characters. |
||||
|
||||
1.3.0 / 2013-06-26 |
||||
================== |
||||
|
||||
* New documentation in Sphinx which is hosted on readthedocs.org |
||||
* Configuration with JSON files and caching. |
||||
|
||||
1.2.0 / 2013-05-06 |
||||
================== |
||||
|
||||
* `ApplicationAwareInterface` and `ApplicationAware` was renamed to `PimpleAwareInterface` and `PimpleAware`. This |
||||
means Controller must use `$this->pimple` instead of `$this->app` when accessing services. The base Controller have |
||||
been updated. |
||||
* Add a `Flint\Console\Application` base class that gives access to `pimple` through `PimpleAwareInterface`. It takes |
||||
a `Pimple` object as the first constructor argument. |
||||
|
||||
1.0.6 / 2013-03-03 |
||||
================== |
||||
|
||||
* Allow setting parameters in the constructor |
||||
* Just a small typo fix in README.md |
||||
* Reshare extended services |
||||
* allow 5.5 failures |
||||
* Add section about twig bridge |
||||
* test the priority of registered service providers |
||||
* rearrange service providers |
||||
|
||||
1.0.5 / 2013-02-08 |
||||
================== |
||||
|
||||
* Alias url_generator service to router to be compatible with application using UrlGeneratorServiceProvider |
||||
* New documentation |
||||
|
||||
1.0.4 / 2013-02-04 |
||||
================== |
||||
|
||||
* Add test for overriding exception controller |
||||
* Update documentation |
||||
* Allow to override the controller used for excetion handling |
||||
|
||||
1.0.3 / 2013-02-03 |
||||
================== |
||||
|
||||
* %root_dir%/config and %root_dir% are now registered as locations for config locator |
||||
* Ignore coverage directory |
||||
* Normalize visibility in Controller |
||||
* Ignore local phpunit.xml file |
||||
* Restructure composer file |
||||
* Add testcase for matcher and matcher_base_class |
||||
* Add .gitattributes file to make downloads slimmer |
||||
|
||||
1.0.2 / 2013-01-31 |
||||
================== |
||||
|
||||
* Fix typo in RoutingServiceProvider which previously would use an invalid class for matching. |
||||
* Add matcher_base_class as a default option for `routing.options` to make the cached matcher extend from the correct class. |
||||
|
||||
1.0.1 / 2013-01-31 |
||||
================== |
||||
|
||||
* Add .gitattributes file to make downloads slimmer |
||||
* Add CHANGELOG.md |
@ -0,0 +1,19 @@ |
||||
Copyright (c) 2013 Henrik Bjornskov |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
of this software and associated documentation files (the "Software"), to deal |
||||
in the Software without restriction, including without limitation the rights |
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
copies of the Software, and to permit persons to whom the Software is furnished |
||||
to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included in all |
||||
copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
||||
THE SOFTWARE. |
@ -0,0 +1,12 @@ |
||||
Flint |
||||
===== |
||||
|
||||
[![Build Status](https://travis-ci.org/henrikbjorn/Flint.png?branch=master)](https://travis-ci.org/henrikbjorn/Flint) |
||||
|
||||
Flint is a microframework build on top of Silex. It brings the full Router, conventions and structure to Silex. |
||||
|
||||
You can read more about [in it documentation](http://flint.rtfd.org). |
||||
|
||||
--- |
||||
|
||||
[![Peytz & Co](doc/_static/peytzco.jpg)](http://peytz.dk) |
@ -0,0 +1,37 @@ |
||||
{ |
||||
"name" : "flint/flint", |
||||
"description" : "Enhanced Silex", |
||||
"license" : "MIT", |
||||
|
||||
"authors" : [{ |
||||
"name" : "Henrik Bjornskov", |
||||
"email" : "henrik@bjrnskov.dk" |
||||
}], |
||||
|
||||
"autoload" : { |
||||
"psr-0" : { |
||||
"Flint" : "src" |
||||
} |
||||
}, |
||||
|
||||
"replace" : { |
||||
"henrikbjorn/flint" : "self.version" |
||||
}, |
||||
|
||||
"require" : { |
||||
"php" : ">=5.3.3", |
||||
"silex/silex" : "~1.0", |
||||
"twig/twig" : "~1.10", |
||||
"symfony/config" : "~2.2" |
||||
}, |
||||
|
||||
"require-dev" : { |
||||
"symfony/console" : "~2.2" |
||||
}, |
||||
|
||||
"extra" : { |
||||
"branch-alias" : { |
||||
"dev-master" : "1.4.x-dev" |
||||
} |
||||
} |
||||
} |
After Width: | Height: | Size: 2.8 KiB |
@ -0,0 +1,253 @@ |
||||
# -*- coding: utf-8 -*- |
||||
# |
||||
# Flint documentation build configuration file, created by |
||||
# sphinx-quickstart on Tue May 21 08:39:31 2013. |
||||
# |
||||
# This file is execfile()d with the current directory set to its containing dir. |
||||
# |
||||
# Note that not all possible configuration values are present in this |
||||
# autogenerated file. |
||||
# |
||||
# All configuration values have a default; values that are commented out |
||||
# serve to show the default. |
||||
|
||||
import sys, os |
||||
from subprocess import Popen, PIPE |
||||
|
||||
def get_version(): |
||||
""" Returns project version as string from 'git describe' command. """ |
||||
pipe = Popen('git describe --tags --always', stdout=PIPE, shell=True) |
||||
version = pipe.stdout.read() |
||||
|
||||
if version: |
||||
return version |
||||
else: |
||||
return 'latest' |
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory, |
||||
# add these directories to sys.path here. If the directory is relative to the |
||||
# documentation root, use os.path.abspath to make it absolute, like shown here. |
||||
#sys.path.insert(0, os.path.abspath('.')) |
||||
|
||||
# -- General configuration ----------------------------------------------------- |
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here. |
||||
#needs_sphinx = '1.0' |
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be extensions |
||||
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. |
||||
extensions = [] |
||||
|
||||
# Add any paths that contain templates here, relative to this directory. |
||||
templates_path = ['_templates'] |
||||
|
||||
# The suffix of source filenames. |
||||
source_suffix = '.rst' |
||||
|
||||
# The encoding of source files. |
||||
#source_encoding = 'utf-8-sig' |
||||
|
||||
# The master toctree document. |
||||
master_doc = 'index' |
||||
|
||||
# General information about the project. |
||||
project = u'Flint' |
||||
copyright = u'2013, Henrik Bjrnskov' |
||||
|
||||
# The version info for the project you're documenting, acts as replacement for |
||||
# |version| and |release|, also used in various other places throughout the |
||||
# built documents. |
||||
# |
||||
# The short X.Y version. |
||||
version = get_version().lstrip('v') |
||||
# The full version, including alpha/beta/rc tags. |
||||
release = version |
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation |
||||
# for a list of supported languages. |
||||
#language = None |
||||
|
||||
# There are two options for replacing |today|: either, you set today to some |
||||
# non-false value, then it is used: |
||||
#today = '' |
||||
# Else, today_fmt is used as the format for a strftime call. |
||||
#today_fmt = '%B %d, %Y' |
||||
|
||||
# List of patterns, relative to source directory, that match files and |
||||
# directories to ignore when looking for source files. |
||||
exclude_patterns = [] |
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all documents. |
||||
#default_role = None |
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text. |
||||
#add_function_parentheses = True |
||||
|
||||
# If true, the current module name will be prepended to all description |
||||
# unit titles (such as .. function::). |
||||
#add_module_names = True |
||||
|
||||
# If true, sectionauthor and moduleauthor directives will be shown in the |
||||
# output. They are ignored by default. |
||||
#show_authors = False |
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use. |
||||
pygments_style = 'sphinx' |
||||
|
||||
# A list of ignored prefixes for module index sorting. |
||||
#modindex_common_prefix = [] |
||||
|
||||
|
||||
# -- Options for HTML output --------------------------------------------------- |
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for |
||||
# a list of builtin themes. |
||||
html_theme = 'default' |
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme |
||||
# further. For a list of options available for each theme, see the |
||||
# documentation. |
||||
#html_theme_options = {} |
||||
|
||||
# Add any paths that contain custom themes here, relative to this directory. |
||||
#html_theme_path = [] |
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to |
||||
# "<project> v<release> documentation". |
||||
#html_title = None |
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title. |
||||
#html_short_title = None |
||||
|
||||
# The name of an image file (relative to this directory) to place at the top |
||||
# of the sidebar. |
||||
#html_logo = None |
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the |
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 |
||||
# pixels large. |
||||
#html_favicon = None |
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here, |
||||
# relative to this directory. They are copied after the builtin static files, |
||||
# so a file named "default.css" will overwrite the builtin "default.css". |
||||
html_static_path = ['_static'] |
||||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, |
||||
# using the given strftime format. |
||||
#html_last_updated_fmt = '%b %d, %Y' |
||||
|
||||
# If true, SmartyPants will be used to convert quotes and dashes to |
||||
# typographically correct entities. |
||||
#html_use_smartypants = True |
||||
|
||||
# Custom sidebar templates, maps document names to template names. |
||||
#html_sidebars = {} |
||||
|
||||
# Additional templates that should be rendered to pages, maps page names to |
||||
# template names. |
||||
#html_additional_pages = {} |
||||
|
||||
# If false, no module index is generated. |
||||
#html_domain_indices = True |
||||
|
||||
# If false, no index is generated. |
||||
#html_use_index = True |
||||
|
||||
# If true, the index is split into individual pages for each letter. |
||||
#html_split_index = False |
||||
|
||||
# If true, links to the reST sources are added to the pages. |
||||
#html_show_sourcelink = True |
||||
|
||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. |
||||
#html_show_sphinx = True |
||||
|
||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. |
||||
#html_show_copyright = True |
||||
|
||||
# If true, an OpenSearch description file will be output, and all pages will |
||||
# contain a <link> tag referring to it. The value of this option must be the |
||||
# base URL from which the finished HTML is served. |
||||
#html_use_opensearch = '' |
||||
|
||||
# This is the file name suffix for HTML files (e.g. ".xhtml"). |
||||
#html_file_suffix = None |
||||
|
||||
# Output file base name for HTML help builder. |
||||
htmlhelp_basename = 'Flintdoc' |
||||
|
||||
|
||||
# -- Options for LaTeX output -------------------------------------------------- |
||||
|
||||
latex_elements = { |
||||
# The paper size ('letterpaper' or 'a4paper'). |
||||
#'papersize': 'letterpaper', |
||||
|
||||
# The font size ('10pt', '11pt' or '12pt'). |
||||
#'pointsize': '10pt', |
||||
|
||||
# Additional stuff for the LaTeX preamble. |
||||
#'preamble': '', |
||||
} |
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples |
||||
# (source start file, target name, title, author, documentclass [howto/manual]). |
||||
latex_documents = [ |
||||
('index', 'Flint.tex', u'Flint Documentation', |
||||
u'Henrik Bjrnskov', 'manual'), |
||||
] |
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of |
||||
# the title page. |
||||
#latex_logo = None |
||||
|
||||
# For "manual" documents, if this is true, then toplevel headings are parts, |
||||
# not chapters. |
||||
#latex_use_parts = False |
||||
|
||||
# If true, show page references after internal links. |
||||
#latex_show_pagerefs = False |
||||
|
||||
# If true, show URL addresses after external links. |
||||
#latex_show_urls = False |
||||
|
||||
# Documents to append as an appendix to all manuals. |
||||
#latex_appendices = [] |
||||
|
||||
# If false, no module index is generated. |
||||
#latex_domain_indices = True |
||||
|
||||
|
||||
# -- Options for manual page output -------------------------------------------- |
||||
|
||||
# One entry per manual page. List of tuples |
||||
# (source start file, name, description, authors, manual section). |
||||
man_pages = [ |
||||
('index', 'flint', u'Flint Documentation', |
||||
[u'Henrik Bjrnskov'], 1) |
||||
] |
||||
|
||||
# If true, show URL addresses after external links. |
||||
#man_show_urls = False |
||||
|
||||
|
||||
# -- Options for Texinfo output ------------------------------------------------ |
||||
|
||||
# Grouping the document tree into Texinfo files. List of tuples |
||||
# (source start file, target name, title, author, |
||||
# dir menu entry, description, category) |
||||
texinfo_documents = [ |
||||
('index', 'Flint', u'Flint Documentation', |
||||
u'Henrik Bjrnskov', 'Flint', 'One line description of project.', |
||||
'Miscellaneous'), |
||||
] |
||||
|
||||
# Documents to append as an appendix to all manuals. |
||||
#texinfo_appendices = [] |
||||
|
||||
# If false, no module index is generated. |
||||
#texinfo_domain_indices = True |
||||
|
||||
# How to display URL addresses: 'footnote', 'no', or 'inline'. |
||||
#texinfo_show_urls = 'footnote' |
@ -0,0 +1,304 @@ |
||||
Flint |
||||
===== |
||||
|
||||
Flint is a microframework built on top of Silex. It tries to bridge the gap between Silex and |
||||
Symfony by bringing structure and conventions to Silex. |
||||
|
||||
Getting started |
||||
--------------- |
||||
|
||||
To start a new project with Flint the easiest way is to use |
||||
`Composer <http://getcomposer.org>`__ and |
||||
`Flint-Skeleton <http://github.com/henrikbjorn/flint-skeleton>`__. |
||||
|
||||
.. code-block:: bash |
||||
|
||||
$ php composer.phar create-project -s dev henrikbjorn/flint-skeleton my-flint-application |
||||
|
||||
Or if you are migrating from a Silex project you can change your |
||||
``composer.json`` file to require Flint and change the Application class |
||||
that is used. |
||||
|
||||
.. code-block:: bash |
||||
|
||||
$ php composer.phar require flint/flint:~1.0 |
||||
|
||||
.. code-block:: php |
||||
|
||||
<?php |
||||
|
||||
use Flint\Application; |
||||
|
||||
$application = new Application($rootDir, $debug); |
||||
|
||||
It is recommended to subclass ``Flint\Application`` instead of using the |
||||
application class directly. |
||||
|
||||
Controllers |
||||
----------- |
||||
|
||||
Flint tries to make Silex more like Symfony. And by using closures it is |
||||
hard to seperate controllers in a logic way when you have more than a |
||||
couple of them. To make it better it is recommended to use classes and |
||||
methods for controllers. The basics is `explained |
||||
here <http://silex.sensiolabs.org/doc/usage.html#controllers-in-classes>`__ |
||||
but Flint takes it further and allows the application to be injected |
||||
into a controller. |
||||
|
||||
The first way to accomplish this is by implementing |
||||
``PimpleAwareInterface`` or extending ``PimpleAware``. This works |
||||
exactly `as described in |
||||
Symfony <http://symfony.com/doc/2.0/book/controller.html#the-base-controller-class>`__. |
||||
With the only exception that the property is called ``$pimple`` instead |
||||
of ``$container``. |
||||
|
||||
.. code-block:: php |
||||
|
||||
<?php |
||||
|
||||
namespace Acme\Controller; |
||||
|
||||
use Flint\PimpleAware; |
||||
|
||||
class HelloController extends PimpleAware |
||||
{ |
||||
public function indexAction() |
||||
{ |
||||
return $this->pimple['twig']->render('Hello/index.html.twig'); |
||||
} |
||||
} |
||||
|
||||
Another way is to use a base controller which have convenience methods |
||||
for the most frequently used services. Theese methods can be seen in the |
||||
source code if you look at the implementation for |
||||
``Flint\Controller\Controller``. |
||||
|
||||
.. code-block:: php |
||||
|
||||
<?php |
||||
|
||||
namespace Acme\Controller; |
||||
|
||||
use Flint\Controller\Controller; |
||||
|
||||
class HelloController extends Controller |
||||
{ |
||||
public function indexAction() |
||||
{ |
||||
return $this->render('Hello/index.html.twig'); |
||||
} |
||||
} |
||||
|
||||
Routing |
||||
------- |
||||
|
||||
Because Flint replaces the url matcher used in Symfony with the full |
||||
router implementation a lot of new things is possible. |
||||
|
||||
Caching is one of thoose things. It makes your application faster as it |
||||
does not need to register routes on every request. Together with loading |
||||
your routes from a configuration file like Symfony it will also bring |
||||
more structure to your application. |
||||
|
||||
To enable caching you just need to point the router to the directory you |
||||
want to use and if it should cache or not. By default the ``debug`` |
||||
parameter will be used as to determaine if cache should be used or not. |
||||
|
||||
.. code-block:: php |
||||
|
||||
<?php |
||||
|
||||
// .. create a $app before this line |
||||
$app->inject(array( |
||||
'routing.options' => array( |
||||
'cache_dir' => '/my/cache/directory/routing', |
||||
), |
||||
)); |
||||
|
||||
Before it is possible to use the full power of caching it is needed to |
||||
use configuration files because Silex will always call add routes via |
||||
its convenience methods ``get|post|delete|put``. Furtunately this is |
||||
baked right in. |
||||
|
||||
.. code-block:: php |
||||
|
||||
<?php |
||||
|
||||
// .. create $app |
||||
$app->inject(array( |
||||
'routing.resource' => 'config/routing.xml', |
||||
)); |
||||
|
||||
.. code-block:: xml |
||||
|
||||
<!-- config/routing.xml --> |
||||
<?xml version="1.0" encoding="UTF-8" ?> |
||||
<routes xmlns="http://symfony.com/schema/routing" |
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd"> |
||||
|
||||
<route id="homepage" pattern="/"> |
||||
<default key="_controller">Acme\\Controller\\DefaultController::indexAction</default> |
||||
</route> |
||||
</routes> |
||||
|
||||
This will make the router load that resource by default. Here xml is |
||||
used as an example but ``php`` is also supported together with ``yml`` |
||||
if ``Symfony\Component\Yaml\Yaml`` is autoloadable. |
||||
|
||||
The benefit from doing it this way is of course they can be cached but |
||||
also it allows you to import routing files that are included in |
||||
libraries and even other Symfony bundles such as the |
||||
`WebProfilerBundle <https://github.com/symfony/webprofilerbundle>`__. |
||||
Also it will make it easier to generate routes from inside your views. |
||||
|
||||
.. code-block:: jinja |
||||
|
||||
<a href="{{ app.router.generate('homepage') }}">Homepage</a> |
||||
|
||||
This is also possible with Silex but with a more verbose syntax. The |
||||
syntax can be even more precise by using the twig functions that is |
||||
available in the Twig bridge for Symfony. To enable thoose add the twig |
||||
bridge to your composer file. |
||||
|
||||
.. code-block:: json |
||||
|
||||
{ |
||||
"require" : { |
||||
"symfony/twig-bridge" : "~2.0" |
||||
} |
||||
} |
||||
|
||||
Now it is possible to use the functions inside your Twig templates. |
||||
|
||||
.. code-block:: jinja |
||||
|
||||
<a href="{{ path('homepage') }}">Homepage</a> |
||||
<a href="{{ url('homepage') }}">Homepage</a> |
||||
|
||||
Default Parameters |
||||
------------------ |
||||
|
||||
The two contructor arguments ``$rootDir`` and ``$debug`` are also |
||||
registered on the application as parameters. This makes it easier for |
||||
services to add paths for caching, logs or other directories. |
||||
|
||||
.. code-block:: php |
||||
|
||||
<?php |
||||
|
||||
// .. create $app |
||||
$app->inject(array( |
||||
'twig.path' => $app['root_dir'] . '/views', |
||||
)); |
||||
|
||||
Custom Error Pages |
||||
------------------ |
||||
|
||||
When finished a project or application it is the small things that |
||||
matter the most. Such as having a custom error page instead of the one |
||||
Silex provides by default. Also it can help a lost user navigate back. |
||||
Flint makes this possible by using the exception handler from Symfony |
||||
and a dedicated controller. Both the views and the controller can be |
||||
overrriden. |
||||
|
||||
This will only work when debug is turned off. |
||||
|
||||
To override the error pages the same logic is used as inside Symfony. |
||||
The logic is very well described `in their |
||||
documentation <http://symfony.com/doc/master/cookbook/controller/error_pages.html>`__. |
||||
|
||||
Only difference from Symfony is the templates must be created inside |
||||
``views/Exception/`` directory. Inside the templates there is access to |
||||
``app`` which in turns gives you access to all of the services defined. |
||||
|
||||
To override the controller used by the exception handler change the |
||||
``exception_controller`` parameter. This parameter will by default be |
||||
set to ``Flint\\Controller\\ExceptionController::showAction``. |
||||
|
||||
.. code-block:: php |
||||
|
||||
<?php |
||||
|
||||
// .. create $app |
||||
$app->inject(array( |
||||
'exception_controller' => 'Acme\\Controller\\ExceptionController::showAction', |
||||
)); |
||||
|
||||
To see what parameter the controller action takes look at the one |
||||
provided by default. Normally it should not be overwritten as it already |
||||
gives a lot of flexibilty with the template lookup. |
||||
|
||||
Injecting Configuration Parameters |
||||
---------------------------------- |
||||
|
||||
Some times it is more useful to inject an array of parameters instead of |
||||
setting them on the application one-by-one. Flint have a method that |
||||
does this. It does the same thing as the second parameter of Silex |
||||
``register`` method. |
||||
|
||||
.. code-block:: php |
||||
|
||||
<?php |
||||
|
||||
// .. $app |
||||
$app->inject(array( |
||||
'twig.paths' => '/my/path/to/views', |
||||
)); |
||||
|
||||
Pimple Console |
||||
-------------- |
||||
|
||||
``Flint\Console\Application`` is an extension of the base console |
||||
application shipped with Symfony. It gives access to Pimple in commands. |
||||
|
||||
.. code-block:: php |
||||
|
||||
<?php |
||||
|
||||
namespace Application\Command; |
||||
|
||||
use Symfony\Component\Console\Input\InputInterface; |
||||
use Symfony\Component\Console\Output\OutputInterface; |
||||
|
||||
class MyCommand extends \Symfony\Component\Console\Command\Command |
||||
{ |
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output) |
||||
{ |
||||
$pimple = $this->getApplication()->getPimple(); |
||||
} |
||||
} |
||||
|
||||
Configuration |
||||
------------- |
||||
|
||||
Every application need to have some parameters configured based on environment or other parameters. |
||||
Flint comes with a ``Configurator`` which reads ``json`` files and sets them as parmeters on your application. |
||||
|
||||
It is very easy to use: |
||||
|
||||
.. code-block:: php |
||||
|
||||
<?php |
||||
|
||||
use Flint\Application; |
||||
|
||||
$app = new Application($rootDir, $debug); |
||||
$app->configure('config.json'); |
||||
|
||||
// Or use the service directly |
||||
$app['configurator']->configure($app, 'app/config/prod.json'); |
||||
|
||||
The Configurator will replace placeholders marked with ``%my_parameter%`` with the corresponding parameter in your |
||||
application which in this instance would be ``$app['my_parameter']``. It will also replace placeholders marked as |
||||
``#my_env#`` with environment variables. |
||||
|
||||
It is possible to inherit from a config file by using a special key ``@import`` and set its value to another file. The |
||||
loaded parameters from ``@import`` will have the lowest priority when merging the two files. |
||||
|
||||
.. warning:: |
||||
|
||||
When using Silex version 1.0.0 or earlier it is not possible to load configurations in the boot method. This is because |
||||
when adding a listener to the `dispatcher` service it will get the routes and a bunch of other services which means it |
||||
is too late. |
@ -0,0 +1,55 @@ |
||||
<?php |
||||
|
||||
namespace Flint; |
||||
|
||||
use Flint\Provider\ConfigServiceProvider; |
||||
use Flint\Provider\FlintServiceProvider; |
||||
use Flint\Provider\RoutingServiceProvider; |
||||
use Silex\Provider\TwigServiceProvider; |
||||
|
||||
/** |
||||
* @package Flint |
||||
*/ |
||||
class Application extends \Silex\Application |
||||
{ |
||||
/** |
||||
* Assigns rootDir and debug to the pimple container. Also replaces the |
||||
* normal resolver with a PimpleAware Resolver. |
||||
* |
||||
* @param string $rootDir |
||||
* @param boolean $debug |
||||
* @param array $parameters |
||||
*/ |
||||
public function __construct($rootDir, $debug = false, array $parameters = array()) |
||||
{ |
||||
parent::__construct($parameters); |
||||
|
||||
$this['root_dir'] = $rootDir; |
||||
$this['debug'] = $debug; |
||||
|
||||
$this->register(new ConfigServiceProvider); |
||||
$this->register(new RoutingServiceProvider); |
||||
$this->register(new TwigServiceProvider); |
||||
$this->register(new FlintServiceProvider); |
||||
} |
||||
|
||||
/** |
||||
* @see Flint\Config\Configurator::configure() |
||||
* @param string $resource |
||||
*/ |
||||
public function configure($resource) |
||||
{ |
||||
$this['configurator']->configure($this, $resource); |
||||
} |
||||
|
||||
/** |
||||
* @deprecated |
||||
* @param array $parameters |
||||
*/ |
||||
public function inject(array $parameters) |
||||
{ |
||||
foreach ($parameters as $k => $v) { |
||||
$this[$k] = $v; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,80 @@ |
||||
<?php |
||||
|
||||
namespace Flint\Config; |
||||
|
||||
use Pimple; |
||||
use Symfony\Component\Config\ConfigCache; |
||||
use Symfony\Component\Config\Loader\LoaderInterface; |
||||
|
||||
/** |
||||
* @package Flint |
||||
*/ |
||||
class Configurator |
||||
{ |
||||
protected $loader; |
||||
protected $resources; |
||||
protected $cacheDir; |
||||
protected $debug = true; |
||||
|
||||
/** |
||||
* @param LoaderInterface $resolver |
||||
* @param ResourceCollection $resources |
||||
* @param string $cacheDir |
||||
* @param boolean $debug |
||||
*/ |
||||
public function __construct(LoaderInterface $resolver, ResourceCollection $resources) |
||||
{ |
||||
$this->resources = $resources; |
||||
$this->loader = $resolver; |
||||
} |
||||
|
||||
/** |
||||
* @param boolean $debug |
||||
*/ |
||||
public function setDebug($debug) |
||||
{ |
||||
$this->debug = (boolean) $debug; |
||||
} |
||||
|
||||
/** |
||||
* @param string $cacheDir |
||||
*/ |
||||
public function setCacheDir($cacheDir) |
||||
{ |
||||
$this->cacheDir = $cacheDir; |
||||
} |
||||
|
||||
/** |
||||
* @param Pimple $pimple |
||||
* @param string $resource |
||||
*/ |
||||
public function configure(Pimple $pimple, $resource) |
||||
{ |
||||
$cache = new ConfigCache($this->cacheDir . '/' . crc32($resource) . '.php', $this->debug); |
||||
|
||||
if (!$cache->isFresh()) { |
||||
$parameters = $this->loader->load($resource); |
||||
} |
||||
|
||||
if ($this->cacheDir && isset($parameters)) { |
||||
$cache->write('<?php $parameters = ' . var_export($parameters, true) . ';', $this->resources->all()); |
||||
} |
||||
|
||||
if (!isset($parameters)) { |
||||
require (string) $cache; |
||||
} |
||||
|
||||
$this->build($pimple, $parameters); |
||||
} |
||||
|
||||
/** |
||||
* @param Pimple $pimple |
||||
* @param array $parameters |
||||
*/ |
||||
protected function build(Pimple $pimple, array $parameters) |
||||
{ |
||||
foreach ($parameters as $key => $value) { |
||||
$pimple[$key] = $value; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,77 @@ |
||||
<?php |
||||
|
||||
namespace Flint\Config\Loader; |
||||
|
||||
use Flint\Config\Normalizer\NormalizerInterface; |
||||
use Flint\Config\ResourceCollection; |
||||
use Symfony\Component\Config\FileLocatorInterface; |
||||
use Symfony\Component\Config\Resource\FileResource; |
||||
|
||||
/** |
||||
* @package Flint |
||||
*/ |
||||
class JsonFileLoader extends \Symfony\Component\Config\Loader\FileLoader |
||||
{ |
||||
protected $normalizer; |
||||
protected $resources; |
||||
|
||||
/** |
||||
* @param NormalizerInterface $normalizer |
||||
* @param FileLocatorInterface $locator |
||||
*/ |
||||
public function __construct( |
||||
NormalizerInterface $normalizer, |
||||
FileLocatorInterface $locator, |
||||
ResourceCollection $resources |
||||
) { |
||||
parent::__construct($locator); |
||||
|
||||
$this->normalizer = $normalizer; |
||||
$this->resources = $resources; |
||||
} |
||||
|
||||
/** |
||||
* {@inheritDoc} |
||||
*/ |
||||
public function load($resource, $type = null) |
||||
{ |
||||
$resource = $this->locator->locate($resource); |
||||
|
||||
$this->resources->add(new FileResource($resource)); |
||||
|
||||
return $this->parse($this->read($resource), $resource); |
||||
} |
||||
|
||||
/** |
||||
* @param array $parameters |
||||
* @param string $file |
||||
* @return array |
||||
*/ |
||||
protected function parse(array $parameters, $file) |
||||
{ |
||||
if (!isset($parameters['@import'])) { |
||||
return $parameters; |
||||
} |
||||
|
||||
$import = $parameters['@import']; |
||||
|
||||
unset($parameters['@import']); |
||||
|
||||
$this->setCurrentDir(dirname($import)); |
||||
|
||||
return array_replace($this->import($import, null, false, $file), $parameters); |
||||
} |
||||
|
||||
protected function read($resource) |
||||
{ |
||||
return json_decode($this->normalizer->normalize(file_get_contents($resource)), true); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritDoc} |
||||
*/ |
||||
public function supports($resource, $type = null) |
||||
{ |
||||
return is_string($resource) && 'json' === pathinfo($resource, PATHINFO_EXTENSION); |
||||
} |
||||
} |
@ -0,0 +1,39 @@ |
||||
<?php |
||||
|
||||
namespace Flint\Config\Normalizer; |
||||
|
||||
/** |
||||
* @package Flint |
||||
*/ |
||||
class ChainNormalizer implements NormalizerInterface |
||||
{ |
||||
protected $normalizers = array(); |
||||
|
||||
/** |
||||
* @param array $normalizers |
||||
*/ |
||||
public function __construct(array $normalizers = array()) |
||||
{ |
||||
array_map(array($this, 'add'), $normalizers); |
||||
} |
||||
|
||||
/** |
||||
* @param NormalizerInterface $normalizer |
||||
*/ |
||||
public function add(NormalizerInterface $normalizer) |
||||
{ |
||||
$this->normalizers[] = $normalizer; |
||||
} |
||||
|
||||
/** |
||||
* {@inheritDoc} |
||||
*/ |
||||
public function normalize($contents) |
||||
{ |
||||
foreach ($this->normalizers as $normalizer) { |
||||
$contents = $normalizer->normalize($contents); |
||||
} |
||||
|
||||
return $contents; |
||||
} |
||||
} |
@ -0,0 +1,33 @@ |
||||
<?php |
||||
|
||||
namespace Flint\Config\Normalizer; |
||||
|
||||
/** |
||||
* @package Flint |
||||
*/ |
||||
class EnvironmentNormalizer implements NormalizerInterface |
||||
{ |
||||
const PLACEHOLDER = '{##|#([A-Z0-9_]+)#}'; |
||||
|
||||
/** |
||||
* @param string $contents |
||||
* @return string |
||||
*/ |
||||
public function normalize($contents) |
||||
{ |
||||
return preg_replace_callback(static::PLACEHOLDER, array($this, 'callback'), $contents); |
||||
} |
||||
|
||||
/** |
||||
* @param array $matches |
||||
* @return mixed |
||||
*/ |
||||
protected function callback($matches) |
||||
{ |
||||
if (!isset($matches[1])) { |
||||
return '##'; |
||||
} |
||||
|
||||
return getenv($matches[1]); |
||||
} |
||||
} |
@ -0,0 +1,15 @@ |
||||
<?php |
||||
|
||||
namespace Flint\Config\Normalizer; |
||||
|
||||
/** |
||||
* @package Flint |
||||
*/ |
||||
interface NormalizerInterface |
||||
{ |
||||
/** |
||||
* @param string $contents |
||||
* @return string |
||||
*/ |
||||
public function normalize($contents); |
||||
} |
@ -0,0 +1,62 @@ |
||||
<?php |
||||
|
||||
namespace Flint\Config\Normalizer; |
||||
|
||||
use Pimple; |
||||
|
||||
/** |
||||
* @package Flint |
||||
*/ |
||||
class PimpleAwareNormalizer extends \Flint\PimpleAware implements NormalizerInterface |
||||
{ |
||||
const PLACEHOLDER = '{%%|%([a-z0-9_.]+)%}'; |
||||
|
||||
/** |
||||
* @param Pimple $pimple |
||||
*/ |
||||
public function __construct(Pimple $pimple = null) |
||||
{ |
||||
$this->setPimple($pimple); |
||||
} |
||||
|
||||
/** |
||||
* @param string $contents |
||||
* @return string |
||||
*/ |
||||
public function normalize($contents) |
||||
{ |
||||
return preg_replace_callback(static::PLACEHOLDER, array($this, 'callback'), $contents); |
||||
} |
||||
|
||||
/** |
||||
* @param array $matches |
||||
* @return mixed |
||||
*/ |
||||
protected function callback($matches) |
||||
{ |
||||
if (!isset($matches[1])) { |
||||
return '%%'; |
||||
} |
||||
|
||||
return $this->scarlarToString($this->pimple[$matches[1]]); |
||||
} |
||||
|
||||
/** |
||||
* @param mixed $value |
||||
* @return mixed |
||||
*/ |
||||
protected function scarlarToString($value) |
||||
{ |
||||
switch (gettype($value)) { |
||||
case 'resource': |
||||
case 'object': |
||||
throw new \RuntimeException('Unable to replace placeholder if its replacement is an object or resource.'); |
||||
case 'boolean': |
||||
return $value ? 'true' : 'false'; |
||||
case 'NULL': |
||||
return 'null'; |
||||
default: |
||||
return (string) $value; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,40 @@ |
||||
<?php |
||||
|
||||
namespace Flint\Config; |
||||
|
||||
use Symfony\Component\Config\Resource\ResourceInterface; |
||||
|
||||
/** |
||||
* Collection of Resources that is used to burst the cache for the configs |
||||
* when in debug. |
||||
* |
||||
* @package Flint |
||||
*/ |
||||
class ResourceCollection |
||||
{ |
||||
protected $resources = array(); |
||||
|
||||
/** |
||||
* @param array $resources |
||||
*/ |
||||
public function __construct(array $resources = array()) |
||||
{ |
||||
array_map(array($this, 'add'), $resources); |
||||
} |
||||
|
||||
/** |
||||
* @param ResourceInterface $resource |
||||
*/ |
||||
public function add(ResourceInterface $resource) |
||||
{ |
||||
$this->resources[] = $resource; |
||||
} |
||||
|
||||
/** |
||||
* @return ResourceInterface[] |
||||
*/ |
||||
public function all() |
||||
{ |
||||
return $this->resources; |
||||
} |
||||
} |
@ -0,0 +1,39 @@ |
||||
<?php |
||||
|
||||
namespace Flint\Console; |
||||
|
||||
use Flint\PimpleAwareInterface; |
||||
use Symfony\Component\Console\Application as BaseApplication; |
||||
|
||||
class Application extends BaseApplication implements PimpleAwareInterface |
||||
{ |
||||
protected $pimple; |
||||
|
||||
/** |
||||
* @param Pimple $pimple |
||||
* @param string $name |
||||
* @param string $version |
||||
*/ |
||||
public function __construct(\Pimple $pimple, $name = 'Flint', $version = 'UNKNOWN') |
||||
{ |
||||
parent::__construct($name, $version); |
||||
|
||||
$this->setPimple($pimple); |
||||
} |
||||
|
||||
/** |
||||
* @return Pimple |
||||
*/ |
||||
public function getPimple() |
||||
{ |
||||
return $this->pimple; |
||||
} |
||||
|
||||
/** |
||||
* {@inheritDoc} |
||||
*/ |
||||
public function setPimple(\Pimple $pimple = null) |
||||
{ |
||||
$this->pimple = $pimple; |
||||
} |
||||
} |
@ -0,0 +1,75 @@ |
||||
<?php |
||||
|
||||
namespace Flint\Controller; |
||||
|
||||
use Symfony\Component\HttpFoundation\Response; |
||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface; |
||||
|
||||
/** |
||||
* @package Flint |
||||
*/ |
||||
abstract class Controller extends \Flint\PimpleAware |
||||
{ |
||||
/** |
||||
* Creates a normal response with the given text and statusCode |
||||
* |
||||
* @param string $text |
||||
* @param integer $statusCode |
||||
* @param array $headers |
||||
* @return Response |
||||
*/ |
||||
public function text($text, $statusCode = 200, array $headers = array()) |
||||
{ |
||||
return new Response($text, $statusCode, $headers); |
||||
} |
||||
|
||||
/** |
||||
* @see Symfony\Component\Routing\RouterInterface::generate() |
||||
*/ |
||||
public function generateUrl($name, array $parameters = array(), $reference = UrlGeneratorInterface::ABSOLUTE_PATH) |
||||
{ |
||||
return $this->pimple['router']->generate($name, $parameters, $reference); |
||||
} |
||||
|
||||
/** |
||||
* @see Twig_Environment::render(); |
||||
*/ |
||||
public function render($name, array $context = array()) |
||||
{ |
||||
return $this->pimple['twig']->render($name, $context); |
||||
} |
||||
|
||||
/** |
||||
* @see Silex\Application::redirect() |
||||
*/ |
||||
public function redirect($url, $statusCode = 302) |
||||
{ |
||||
return $this->pimple->redirect($url, $statusCode); |
||||
} |
||||
|
||||
/** |
||||
* @see Silex\Application::abort() |
||||
*/ |
||||
public function abort($statusCode, $message = '', array $headers = array()) |
||||
{ |
||||
return $this->pimple->abort($statusCode, $message, $headers); |
||||
} |
||||
|
||||
/** |
||||
* @param string $id |
||||
* @return boolean |
||||
*/ |
||||
public function has($id) |
||||
{ |
||||
return isset($this->pimple[$id]); |
||||
} |
||||
|
||||
/** |
||||
* @param string $id |
||||
* @return mixed |
||||
*/ |
||||
public function get($id) |
||||
{ |
||||
return $this->pimple[$id]; |
||||
} |
||||
} |
@ -0,0 +1,56 @@ |
||||
<?php |
||||
|
||||
namespace Flint\Controller; |
||||
|
||||
use Flint\Application; |
||||
use Flint\PimpleAwareInterface; |
||||
use Symfony\Component\HttpFoundation\Request; |
||||
use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface; |
||||
|
||||
/** |
||||
* Injects the Application into the Controller if it implements the right interface |
||||
* otherwise it delegates to the composed resolver. |
||||
* |
||||
* @package Flint |
||||
*/ |
||||
class ControllerResolver implements ControllerResolverInterface |
||||
{ |
||||
protected $pimple; |
||||
protected $resolver; |
||||
|
||||
/** |
||||
* @param ControllerResolverInterface $resolver |
||||
* @param Pimple $pimple |
||||
*/ |
||||
public function __construct(ControllerResolverInterface $resolver, \Pimple $pimple) |
||||
{ |
||||
$this->resolver = $resolver; |
||||
$this->pimple = $pimple; |
||||
} |
||||
|
||||
/** |
||||
* {@inheritDoc} |
||||
*/ |
||||
public function getController(Request $request) |
||||
{ |
||||
$controller = $this->resolver->getController($request); |
||||
|
||||
if (false == is_array($controller)) { |
||||
return $controller; |
||||
} |
||||
|
||||
if ($controller[0] instanceof PimpleAwareInterface) { |
||||
$controller[0]->setPimple($this->pimple); |
||||
} |
||||
|
||||
return $controller; |
||||
} |
||||
|
||||
/** |
||||
* {@inheritDoc} |
||||
*/ |
||||
public function getArguments(Request $request, $controller) |
||||
{ |
||||
return $this->resolver->getArguments($request, $controller); |
||||
} |
||||
} |
@ -0,0 +1,74 @@ |
||||
<?php |
||||
|
||||
namespace Flint\Controller; |
||||
|
||||
use Symfony\Component\HttpKernel\Debug\ExceptionHandler; |
||||
use Symfony\Component\HttpKernel\Exception\FlattenException; |
||||
use Symfony\Component\HttpFoundation\Request; |
||||
use Symfony\Component\HttpFoundation\Response; |
||||
|
||||
/** |
||||
* @package Flint |
||||
*/ |
||||
class ExceptionController extends Controller |
||||
{ |
||||
/** |
||||
* @param Request $request |
||||
* @param FlattenException $exception |
||||
* @param string $format |
||||
*/ |
||||
public function showAction(Request $request, FlattenException $exception, $format) |
||||
{ |
||||
$handler = new ExceptionHandler($this->pimple['debug']); |
||||
|
||||
if ($this->pimple['debug']) { |
||||
return $handler->createResponse($exception); |
||||
} |
||||
|
||||
$code = $exception->getStatusCode(); |
||||
$template = $this->resolve($request, $code, $format); |
||||
|
||||
if ($template) { |
||||
$contents = $this->pimple['twig']->render($template, array( |
||||
'status_code' => $code, |
||||
'status_text' => isset(Response::$statusTexts[$code]) ? Response::$statusTexts[$code] : '', |
||||
'exception' => $exception, |
||||
)); |
||||
|
||||
return new Response($contents, $code); |
||||
} |
||||
|
||||
return $handler->createResponse($exception); |
||||
} |
||||
|
||||
/** |
||||
* @param Request $request |
||||
* @param integer $code |
||||
* @param string $format |
||||
* @return string|null |
||||
*/ |
||||
protected function resolve(Request $request, $code, $format) |
||||
{ |
||||
$loader = $this->pimple['twig.loader']; |
||||
|
||||
$templates = array( |
||||
'Exception/error' . $code . '.' . $format . '.twig', |
||||
'Exception/error.' . $format . '.twig', |
||||
'Exception/error.html.twig', |
||||
'@Flint/Exception/error.' . $format . '.twig', |
||||
'@Flint/Exception/error.html.twig', |
||||
); |
||||
|
||||
foreach ($templates as $template) { |
||||
if (false == $loader->exists($template)) { |
||||
continue; |
||||
} |
||||
|
||||
if (strpos($template, '.html.twig')) { |
||||
$request->setRequestFormat('html'); |
||||
} |
||||
|
||||
return $template; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,19 @@ |
||||
<?php |
||||
|
||||
namespace Flint; |
||||
|
||||
/** |
||||
* @package Flint |
||||
*/ |
||||
abstract class PimpleAware implements PimpleAwareInterface |
||||
{ |
||||
protected $pimple; |
||||
|
||||
/** |
||||
* {@inheritDoc} |
||||
*/ |
||||
public function setPimple(\Pimple $pimple = null) |
||||
{ |
||||
$this->pimple = $pimple; |
||||
} |
||||
} |
@ -0,0 +1,16 @@ |
||||
<?php |
||||
|
||||
namespace Flint; |
||||
|
||||
/** |
||||
* A Silex version of ContainerAwareInterface that is found in Symfony |
||||
* |
||||
* @package Flint |
||||
*/ |
||||
interface PimpleAwareInterface |
||||
{ |
||||
/** |
||||
* @param Pimple|null $flint |
||||
*/ |
||||
public function setPimple(\Pimple $pimple = null); |
||||
} |
@ -0,0 +1,75 @@ |
||||
<?php |
||||
|
||||
namespace Flint\Provider; |
||||
|
||||
use Flint\Config\Configurator; |
||||
use Flint\Config\ResourceCollection; |
||||
use Flint\Config\Loader\JsonFileLoader; |
||||
use Flint\Config\Normalizer\ChainNormalizer; |
||||
use Flint\Config\Normalizer\EnvironmentNormalizer; |
||||
use Flint\Config\Normalizer\PimpleAwareNormalizer; |
||||
use Silex\Application; |
||||
use Symfony\Component\Config\FileLocator; |
||||
use Symfony\Component\Config\Loader\DelegatingLoader; |
||||
use Symfony\Component\Config\Loader\LoaderResolver; |
||||
|
||||
/** |
||||
* @package Flint |
||||
*/ |
||||
class ConfigServiceProvider implements \Silex\ServiceProviderInterface |
||||
{ |
||||
/** |
||||
* {@inheritDoc} |
||||
*/ |
||||
public function register(Application $app) |
||||
{ |
||||
$app['config.paths'] = function (Application $app) { |
||||
return array($app['root_dir'] . '/config', $app['root_dir']); |
||||
}; |
||||
|
||||
$app['config.locator'] = $app->share(function (Application $app) { |
||||
return new FileLocator($app['config.paths']); |
||||
}); |
||||
|
||||
$app['config.resource_collection'] = $app->share(function (Application $app) { |
||||
return new ResourceCollection; |
||||
}); |
||||
|
||||
$app['config.normalizer'] = $app->share(function (Application $app) { |
||||
$normalizer = new ChainNormalizer; |
||||
$normalizer->add(new PimpleAwareNormalizer($app)); |
||||
$normalizer->add(new EnvironmentNormalizer); |
||||
|
||||
return $normalizer; |
||||
}); |
||||
|
||||
$app['config.loader'] = $app->share(function (Application $app) { |
||||
return new DelegatingLoader($app['config.loader_resolver']); |
||||
}); |
||||
|
||||
$app['config.loader_resolver'] = $app->share(function ($app) { |
||||
$loader = new JsonFileLoader($app['config.normalizer'], $app['config.locator'], $app['config.resource_collection']); |
||||
|
||||
return new LoaderResolver(array($loader)); |
||||
}); |
||||
|
||||
$app['configurator'] = $app->share(function (Application $app) { |
||||
$configurator = new Configurator($app['config.loader'], $app['config.resource_collection']); |
||||
$configurator->setCacheDir($app['config.cache_dir']); |
||||
$configurator->setDebug($app['debug']); |
||||
|
||||
return $configurator; |
||||
}); |
||||
|
||||
if (!isset($app['config.cache_dir'])) { |
||||
$app['config.cache_dir'] = null; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* {@inheritDoc} |
||||
*/ |
||||
public function boot(Application $app) |
||||
{ |
||||
} |
||||
} |
@ -0,0 +1,42 @@ |
||||
<?php |
||||
|
||||
namespace Flint\Provider; |
||||
|
||||
use Symfony\Component\HttpKernel\EventListener\ExceptionListener; |
||||
use Flint\Controller\ControllerResolver; |
||||
use Silex\Application; |
||||
|
||||
/** |
||||
* @package Flint |
||||
*/ |
||||
class FlintServiceProvider implements \Silex\ServiceProviderInterface |
||||
{ |
||||
/** |
||||
* {@inheritDoc} |
||||
*/ |
||||
public function register(Application $app) |
||||
{ |
||||
$app['exception_controller'] = 'Flint\\Controller\\ExceptionController::showAction'; |
||||
|
||||
$app['exception_handler'] = $app->share(function ($app) { |
||||
return new ExceptionListener($app['exception_controller'], $app['logger']); |
||||
}); |
||||
|
||||
$app['resolver'] = $app->share($app->extend('resolver', function ($resolver, $app) { |
||||
return new ControllerResolver($resolver, $app); |
||||
})); |
||||
|
||||
$app['twig.loader.filesystem'] = $app->share($app->extend('twig.loader.filesystem', function ($loader, $app) { |
||||
$loader->addPath(__DIR__ . '/../Resources/views', 'Flint'); |
||||
|
||||
return $loader; |
||||
})); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritDoc} |
||||
*/ |
||||
public function boot(Application $app) |
||||
{ |
||||
} |
||||
} |
@ -0,0 +1,87 @@ |
||||
<?php |
||||
|
||||
namespace Flint\Provider; |
||||
|
||||
use Silex\Application; |
||||
use Flint\Routing\Loader\NullLoader; |
||||
use Symfony\Component\Routing\Router; |
||||
use Symfony\Component\Routing\Loader\XmlFileLoader; |
||||
use Symfony\Component\Routing\Loader\PhpFileLoader; |
||||
use Symfony\Component\Routing\Loader\YamlFileLoader; |
||||
use Symfony\Component\Config\Loader\LoaderResolver; |
||||
use Symfony\Component\Config\Loader\DelegatingLoader; |
||||
|
||||
/** |
||||
* @package Flint |
||||
*/ |
||||
class RoutingServiceProvider implements \Silex\ServiceProviderInterface |
||||
{ |
||||
/** |
||||
* {@inheritDoc} |
||||
*/ |
||||
public function register(Application $app) |
||||
{ |
||||
$app['routing.resource'] = null; |
||||
$app['routing.options'] = array(); |
||||
|
||||
$app['routing.loader.xml'] = $app->share(function (Application $app) { |
||||
return new XmlFileLoader($app['config.locator']); |
||||
}); |
||||
|
||||
$app['routing.loader.php'] = $app->share(function (Application $app) { |
||||
return new PhpFileLoader($app['config.locator']); |
||||
}); |
||||
|
||||
$app['routing.loader.yml'] = $app->share(function (Application $app) { |
||||
return new YamlFileLoader($app['config.locator']); |
||||
}); |
||||
|
||||
$app['routing.loader.null'] = $app->share(function (Application $app) { |
||||
return new NullLoader; |
||||
}); |
||||
|
||||
$app['routing.loader.resolver'] = $app->share(function (Application $app) { |
||||
$loaders = array( |
||||
$app['routing.loader.xml'], |
||||
$app['routing.loader.php'], |
||||
$app['routing.loader.null'], |
||||
); |
||||
|
||||
if (class_exists('Symfony\\Component\\Yaml\\Yaml')) { |
||||
$loaders[] = $app['routing.loader.yml']; |
||||
} |
||||
|
||||
return new LoaderResolver($loaders); |
||||
}); |
||||
|
||||
$app['routing.loader'] = $app->share(function (Application $app) { |
||||
return new DelegatingLoader($app['routing.loader.resolver']); |
||||
}); |
||||
|
||||
$app['router'] = $app->share(function (Application $app) { |
||||
$defaults = array( |
||||
'debug' => $app['debug'], |
||||
'matcher_base_class' => 'Silex\\RedirectableUrlMatcher', |
||||
'matcher_class' => 'Silex\\RedirectableUrlMatcher', |
||||
); |
||||
|
||||
$options = array_replace($defaults, $app['routing.options']); |
||||
|
||||
return new Router($app['routing.loader'], $app['routing.resource'], $options, $app['request_context'], $app['logger']); |
||||
}); |
||||
|
||||
$app['routes'] = function (Application $app) { |
||||
return $app['router']->getRouteCollection(); |
||||
}; |
||||
|
||||
$app['url_matcher'] = $app->raw('router'); |
||||
$app['url_generator'] = $app->raw('router'); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritDoc} |
||||
*/ |
||||
public function boot(Application $app) |
||||
{ |
||||
} |
||||
} |
@ -0,0 +1 @@ |
||||
{% include 'Exception/error.xml.twig' with { 'exception': exception } %} |
@ -0,0 +1,4 @@ |
||||
/* |
||||
{{ status_code }} {{ status_text }} |
||||
|
||||
*/ |
@ -0,0 +1,17 @@ |
||||
<!DOCTYPE html> |
||||
<html> |
||||
<head> |
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> |
||||
<title>An Error Occurred: {{ status_text }}</title> |
||||
</head> |
||||
<body> |
||||
<h1>Oops! An Error Occurred</h1> |
||||
<h2>The server returned a "{{ status_code }} {{ status_text }}".</h2> |
||||
|
||||
<div> |
||||
Something is broken. Please e-mail us at [email] and let us know |
||||
what you were doing when this error occurred. We will fix it as soon |
||||
as possible. Sorry for any inconvenience caused. |
||||
</div> |
||||
</body> |
||||
</html> |
@ -0,0 +1,4 @@ |
||||
/* |
||||
{{ status_code }} {{ status_text }} |
||||
|
||||
*/ |
@ -0,0 +1 @@ |
||||
{{ { 'error': { 'code': status_code, 'message': status_text } }|json_encode|raw }} |
@ -0,0 +1 @@ |
||||
{% include 'Exception/error.xml.twig' with { 'exception': exception } %} |
@ -0,0 +1,8 @@ |
||||
Oops! An Error Occurred |
||||
======================= |
||||
|
||||
The server returned a "{{ status_code }} {{ status_text }}". |
||||
|
||||
Please e-mail us at [email] and let us know what you were doing when this |
||||
error occurred. We will fix it as soon as possible. Sorry for any |
||||
inconvenience caused. |
@ -0,0 +1,3 @@ |
||||
<?xml version="1.0" encoding="{{ _charset }}" ?> |
||||
|
||||
<error code="{{ status_code }}" message="{{ status_text }}" /> |
@ -0,0 +1,31 @@ |
||||
<?php |
||||
|
||||
namespace Flint\Routing\Loader; |
||||
|
||||
use Symfony\Component\Routing\RouteCollection; |
||||
|
||||
/** |
||||
* When `routing.resource` is null a loader needs to support that. |
||||
* This just returns an empty RouteCollection so an exception will |
||||
* not be raised and to keep BC with Silex. |
||||
* |
||||
* @package Flint |
||||
*/ |
||||
class NullLoader extends \Symfony\Component\Config\Loader\Loader |
||||
{ |
||||
/** |
||||
* {@inheritDoc} |
||||
*/ |
||||
public function load($resource, $type = null) |
||||
{ |
||||
return new RouteCollection; |
||||
} |
||||
|
||||
/** |
||||
* {@inheritDoc} |
||||
*/ |
||||
public function supports($resource, $type = null) |
||||
{ |
||||
return null === $resource; |
||||
} |
||||
} |
Loading…
Reference in new issue