Buy

Ready to move a chunk of code out of the controller? Well good for you.

Step 1: create a new PHP class. In AppBundle, I'll create a new directory called Service - but that could be called anything. Inside, add a new PHP class called MarkdownTransformer:

12 lines src/AppBundle/Service/MarkdownTransformer.php
... lines 1 - 2
namespace AppBundle\Service;
class MarkdownTransformer
{
... lines 7 - 10
}

If you're keeping score at home, that could also be called anything.

Start this with one public function parse() with a $str argument:

12 lines src/AppBundle/Service/MarkdownTransformer.php
... lines 1 - 4
class MarkdownTransformer
{
public function parse($str)
{
return strtoupper($str);
}
}

Eventually, this will do all the dirty work of markdown parsing and caching. But for now... keep it simple and return strtoupper($str). But use your imagination - pretend like it totally is awesome and is parsing our markdown. In fact, it's so awesome that we want to use it in our controller. How?

Find GenusController. First, create a new object with $transformer = new MarkdownTransformer():

125 lines src/AppBundle/Controller/GenusController.php
... lines 1 - 13
class GenusController extends Controller
{
... lines 16 - 58
public function showAction($genusName)
{
$em = $this->getDoctrine()->getManager();
$genus = $em->getRepository('AppBundle:Genus')
->findOneBy(['name' => $genusName]);
if (!$genus) {
throw $this->createNotFoundException('genus not found');
}
$markdownParser = new MarkdownTransformer();
... lines 71 - 97
}
... lines 99 - 123
}

Noooothing special here: the new method is purposefully not static, and this means we need to instantiate the object first. Next, add $funFact = $transformer->parse() and pass $genus->getFunFact():

125 lines src/AppBundle/Controller/GenusController.php
... lines 1 - 69
$markdownParser = new MarkdownTransformer();
$funFact = $markdownParser->parse($genus->getFunFact());
... lines 72 - 125

And that's it! If you're feeling massively underwhelmed... you're right where I want you! I want this to be boring and easy - there are fireworks and exciting stuff later.

Finish this by passing $funFact into the template so we can render the parsed version:

125 lines src/AppBundle/Controller/GenusController.php
... lines 1 - 13
class GenusController extends Controller
{
... lines 16 - 58
public function showAction($genusName)
{
... lines 61 - 69
$markdownParser = new MarkdownTransformer();
$funFact = $markdownParser->parse($genus->getFunFact());
... lines 72 - 92
return $this->render('genus/show.html.twig', array(
... line 94
'funFact' => $funFact,
... line 96
));
}
... lines 99 - 123
}

Then, open the template and replace genus.funFact with just funFact:

42 lines app/Resources/views/genus/show.html.twig
... lines 1 - 4
{% block body %}
<h2 class="genus-name">{{ genus.name }}</h2>
<div class="sea-creature-container">
<div class="genus-photo"></div>
<div class="genus-details">
<dl class="genus-details-list">
... lines 12 - 15
<dt>Fun Fact:</dt>
<dd>{{ funFact }}</dd>
... lines 18 - 19
</dl>
</div>
</div>
<div id="js-notes-wrapper"></div>
{% endblock %}
... lines 25 - 42

Try it out: open up localhost:8000/genus - then click one of the genuses. Yes! The fun fact is screaming at us in upper case.

So believe it or not: you just saw one of the most important and commonly-confusing object-oriented strategies that exist anywhere... in any language! And it's this: you should take chunks of code that do things and move them into an outside function in an outside class. That's it.

Oh, and guess what? MarkdownTransform is a service. Because remember, a service is just a class that does work for us. And when you isolate a lot of your code into these service classes, you start to build what's called a "service-oriented architecture". OooOOoooOOOo. That basically means that instead of having all of your code in big controllers, you organize them into nice little services that each do one job.

Of course, the MarkdownTransformer service isn't actually transforming... any... markdown - so let's fix that.

Leave a comment!

  • 2016-08-25 Chmlls

    Day9? ;D

  • 2016-06-15 JLChafardet

    I know it gets old but weaverryan you sure are good at teaching and keeping ppl engaged in your lectures! kudos to you!
    for real you are the first caster{-that-teaches-something} that I've ever seen (outside a really few good starcraft2 casters) that really keeps me interested in what he/she is saying.

  • 2016-06-09 weaverryan

    Hi Konrad!

    Hmm, so your database was repopulated, but the page is still empty? Exactly which URL are you going to and what are you seeing? Did you download the code from this page? And if so, are you using the start or finish directory?

    Let me know - I'm sure we can figure out the issue :)

    Cheers!

  • 2016-06-06 Konrad Zając

    Hi I did the command it repopulated my databese, but it's still empty.In which project there's somthing done to the database?

  • 2016-05-31 weaverryan

    Hey Konrad!

    Ah yes, also run:


    php bin/console doctrine:fixtures:load

    This will populate your database. Btw, if you download the course code, we of the full setup details in the README.md file that's in both the start/ and finish/ directories. If you have any issues, let me know :).

    Cheers!

  • 2016-05-25 Konrad Zając

    I do see a page after runing that command( previously just an error) but still, no content. Should i add something?

  • 2016-05-25 weaverryan

    Hi Konrad!

    When you create a new class in PhpStorm, it *can* automatically add the "namespace" line for you (which is what you see in this tutorial). But, to get that, you need to mark your "src" directory as a "Sources Root" in PhpStorm. We show that at about 1:30 in this tutorial: http://knpuniversity.com/scree...

    About your error, you *do* have the database, but you don't yet have the database *tables* :). You can get them by running:


    php bin/console doctrine:migrations:migrate

    Let me know if that works! Cheers!

  • 2016-05-24 Luma

    Amazing tutorial! Thanks for your tips. It is helping me understand the fundamentals of symfony.

  • 2016-05-23 Konrad Zając

    HI,
    should the namespace generate automaticly?
    After all the steps I can display the localhost:8000
    but when I visit localhost:8000/genus ther's an error "SQLSTATE[42S02]: Base table or view not found: 1146 Table 'symfony.genus' doesn't exist"
    I did the db connection all right, so where's the problem???