Skip to content

Updating 2 more articles for 4.0 #8798

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 28 additions & 25 deletions contributing/code/reproducer.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,20 +33,22 @@ Reproducing Complex Bugs
------------------------

If the bug is related to the Symfony Framework or if it's too complex to create
a PHP script, it's better to reproduce the bug by forking the Symfony Standard
edition. To do so:

#. Go to https://github.com/symfony/symfony-standard and click on the **Fork**
button to make a fork of that repository or go to your already forked copy.
#. Clone the forked repository into your computer:
``git clone git://github.com/YOUR-GITHUB-USERNAME/symfony-standard.git``
#. Browse the project and create a new branch (e.g. ``issue_23567``,
``reproduce_23657``, etc.)
#. Now you must add the minimum amount of code to reproduce the bug. This is the
a PHP script, it's better to reproduce the bug by creating a new project. To do so:

1. Create a new project:

.. code-block:: terminal

$ composer require symfony/skeleton bug_app

2. Now you must add the minimum amount of code to reproduce the bug. This is the
trickiest part and it's explained a bit more later.
#. Add, commit and push all your changes.
#. Add a comment in your original issue report to share the URL of your forked
project (e.g. ``https://github.com/YOUR-GITHUB-USERNAME/symfony-standard/tree/issue_23567``)
3. Add and commit your changes.
4. Create a `new repository`_ on GitHub (give it any name).
5. Follow the instructions on GitHub to add the ``origin`` remote to your local project
and push it.
6. Add a comment in your original issue report to share the URL of your forked
project (e.g. ``https://github.com/YOUR-GITHUB-USERNAME/symfony_issue_23567``)
and, if necessary, explain the steps to reproduce (e.g. "browse this URL",
"fill in this data in the form and submit it", etc.)

Expand All @@ -55,23 +57,24 @@ Adding the Minimum Amount of Code Possible

The key to create a bug reproducer is to solely focus on the feature that you
suspect is failing. For example, imagine that you suspect that the bug is related
to a route definition. Then, after forking the Symfony Standard Edition:
to a route definition. Then, after creating your project:

#. Don't edit any of the default Symfony configuration options.
#. Don't copy your original application code and don't use the same structure
of bundles, controllers, actions, etc. as in your original application.
#. Open the default controller class of the AppBundle and add your routing
definition using annotations.
of controllers, actions, etc. as in your original application.
#. Create a simple controller and add your routing definition that shows the bug.
#. Don't create or modify any other file.
#. Execute the ``server:run`` command and browse the previously defined route
to see if the bug appears or not.
#. Execute ``composer require server`` and use the ``server:run`` command to browse
to the new route and see if the bug appears or not.
#. If you can see the bug, you're done and you can already share the code with us.
#. If you can't see the bug, you must keep making small changes. For example, if
your original route was defined using XML, forget about the previous route
annotation and define the route using XML instead. Or maybe your application
uses bundle inheritance and that's where the real bug is. Then, forget about
AppBundle and quickly generate a new AppParentBundle, make AppBundle inherit
from it and test if the route is working.
and define the route using XML instead. Or maybe your application
registers some event listeners and that's where the real bug is. In that case,
add an event listener that's similar to your real app to see if you can find
the bug.

In short, the idea is to keep adding small and incremental changes to a new project
until you can reproduce the bug.

In short, the idea is to keep adding small and incremental changes to the default
Symfony Standard edition until you can reproduce the bug.
.. _`new repository`: https://github.com/new
112 changes: 30 additions & 82 deletions introduction/from_flat_php_to_symfony2.rst
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ content:

{
"require": {
"symfony/symfony": "3.1.*"
"symfony/http-foundation": "^4.0"
},
"autoload": {
"files": ["model.php","controllers.php"]
Expand Down Expand Up @@ -534,9 +534,8 @@ a simple application. Along the way, you've made a simple routing
system and a method using ``ob_start()`` and ``ob_get_clean()`` to render
templates. If, for some reason, you needed to continue building this "framework"
from scratch, you could at least use Symfony's standalone
:doc:`Routing </components/routing>` and
:doc:`Templating </components/templating>` components, which already
solve these problems.
:doc:`Routing </components/routing>` and component and :doc:`Twig </templating>`,
which already solve these problems.

Instead of re-solving common problems, you can let Symfony take care of
them for you. Here's the same sample application, now built in Symfony::
Expand All @@ -549,17 +548,16 @@ them for you. Here's the same sample application, now built in Symfony::

class BlogController extends Controller
{
public function listAction()
public function list()
{
$posts = $this->getDoctrine()
->getManager()
->createQuery('SELECT p FROM App:Post p')
->execute();
->getRepository(Post::class)
->findAll()

return $this->render('Blog/list.html.php', array('posts' => $posts));
return $this->render('blog/list.html.twig', ['posts' => $posts]);
}

public function showAction($id)
public function show($id)
{
$post = $this->getDoctrine()
->getRepository(Post::class)
Expand All @@ -570,7 +568,7 @@ them for you. Here's the same sample application, now built in Symfony::
throw $this->createNotFoundException();
}

return $this->render('Blog/show.html.php', array('post' => $post));
return $this->render('blog/show.html.php', ['post' => $post]);
}
}

Expand All @@ -581,51 +579,49 @@ nice way to group related pages. The controller functions are also sometimes cal
The two controllers (or actions) are still lightweight. Each uses the
:doc:`Doctrine ORM library </doctrine>` to retrieve objects from the
database and the Templating component to render a template and return a
``Response`` object. The list ``list.php`` template is now quite a bit simpler:
``Response`` object. The list ``list.html.twig`` template is now quite a bit simpler,
and uses Twig:

.. code-block:: html+php
.. code-block:: html+twig

<!-- templates/Blog/list.html.php -->
<?php $view->extend('layout.html.php') ?>
<!-- templates/blog/list.html.twig -->
{% extends 'base.html.twig' %}

<?php $view['slots']->set('title', 'List of Posts') ?>
{% block title %}List of Posts{% endblock %}

<h1>List of Posts</h1>
<ul>
<?php foreach ($posts as $post): ?>
{% for post in posts %}
<li>
<a href="<?php echo $view['router']->path(
'blog_show',
array('id' => $post->getId())
) ?>">
<?= $post->getTitle() ?>
<a href="{{ path('blog_show', { id: post.id }) }}">
{{ post.title }}
</a>
</li>
<?php endforeach ?>
{% endfor %}
</ul>

The ``layout.php`` file is nearly identical:

.. code-block:: html+php
.. code-block:: html+twig

<!-- templates/layout.html.php -->
<!-- templates/base.html.twig -->
<!DOCTYPE html>
<html>
<head>
<title><?= $view['slots']->output(
'title',
'Default title'
) ?></title>
<meta charset="UTF-8">
<title>{% block title %}Welcome!{% endblock %}</title>
{% block stylesheets %}{% endblock %}
</head>
<body>
<?= $view['slots']->output('_content') ?>
{% block body %}{% endblock %}
{% block javascripts %}{% endblock %}
</body>
</html>

.. note::

The show ``show.php`` template is left as an exercise: updating it should be
really similar to updating the ``list.php`` template.
The ``show.html.twig`` template is left as an exercise: updating it should be
really similar to updating the ``list.html.twig`` template.

When Symfony's engine (called the Kernel) boots up, it needs a map so
that it knows which controllers to execute based on the request information.
Expand All @@ -637,11 +633,11 @@ in a readable format:
# config/routes.yaml
blog_list:
path: /blog
defaults: { _controller: AppBundle:Blog:list }
controller: App\Controller\BlogController::list

blog_show:
path: /blog/show/{id}
defaults: { _controller: AppBundle:Blog:show }
controller: App\Controller\BlogController::show

Now that Symfony is handling all the mundane tasks, the front controller
``public/index.php`` is dead simple. And since it does so little, you'll never
Expand Down Expand Up @@ -671,54 +667,6 @@ It's a beautiful thing.
:align: center
:alt: Symfony request flow

Better Templates
~~~~~~~~~~~~~~~~

If you choose to use it, Symfony comes standard with a templating engine
called `Twig`_ that makes templates faster to write and easier to read.
It means that the sample application could contain even less code! Take,
for example, rewriting ``list.html.php`` template in Twig would look like
this:

.. code-block:: html+twig

{# templates/blog/list.html.twig #}
{% extends "layout.html.twig" %}

{% block title %}List of Posts{% endblock %}

{% block body %}
<h1>List of Posts</h1>
<ul>
{% for post in posts %}
<li>
<a href="{{ path('blog_show', {'id': post.id}) }}">
{{ post.title }}
</a>
</li>
{% endfor %}
</ul>
{% endblock %}

And rewriting ``layout.html.php`` template in Twig would look like this:

.. code-block:: html+twig

{# templates/layout.html.twig #}
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}Default title{% endblock %}</title>
</head>
<body>
{% block body %}{% endblock %}
</body>
</html>

Twig is well-supported in Symfony. And while PHP templates will always
be supported in Symfony, the many advantages of Twig will continue to
be discussed. For more information, see the :doc:`templating article </templating>`.

Where Symfony Delivers
----------------------

Expand Down