Creating a Service Class
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
:
// ... 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:
// ... 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()
:
// ... 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()
:
// ... 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:
// ... 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
:
// ... 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? MarkdownTransformer
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.
I know it gets old but there 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.