Data Persister Decoration
…that object. Usually, this means that we're saving an entity
object to the database via Doctrine. But we could "save" an object anywhere, like
by sending the data to another API, or putting it into Redis or ElasticSearch.
ApiPlatform doesn't really care. These…
Completely Custom Resource
…really, an API resource can be any object that pulls data from... anywhere!
So instead of adding un-persisted $isMe and $isMvp fields to User:
We could have created a totally different non-entity class - like UserApiResource - with
exactly the fields in our API.
And…
Setting the UUID on POST
…be ignored.
How can I be so sure? Well, look at the User class: $uuid is not settable
anywhere. It's not an argument to the constructor and there's no setUuid()
method:
Time to change that!
Let's describe the behavior we want in…
Microservices Gone Wrong
…it.
How we built it. Where we ran into significant trouble, and where everything
worked well. And this is my puppy Adda who's going to help me on some of these
transitionary slides.
So let's jump into the background. I walked in to…
Bonus! LoggerTrait & Setter Injection
…take that code and move it into
its own service class.
Since this is such an important skill, let's do it: in the Service/ directory -
though we could put this anywhere - create a new class: SlackClient:
Give it a public function called, how about…
Symfony 4: Let's Launch!
…excited. Why? Because nothing
makes me happier than sitting down to work inside a framework where coding is actually
fun, and where I can build features fast, but without sacrificing quality. Well,
maybe I'd be even happier doing all of that on a beach..…
Clearing the Database
…In a Symfony 4 Flex application, you
should create a config/packages/test/doctrine.yaml file since this will contain
Doctrine configuration that you only want to use in the test environment.
Inside, anywhere, add doctrine, dbal then url set to
sqlite:///%kernel.project_dir…
Event Hooks
…
And this means that we can use standard Symfony event subscribers to totally kick
EasyAdminBundle's butt!
Create a new Event directory... though, this could live anywhere. Then, how about,
EasyAdminSubscriber. Event subscribers always implement EventSubscriberInterface:
I'll go to the "Code"->"Generate" menu…
Symfony Magic: Replace the _controller
…without borders
or boundaries. Let’s prove it.
We know that Symfony reads the _controller key in the request attributes
and executes that as the controller. This is set by the RouterListener
but it could be set anywhere.
Let’s go adventuring!. UserAgentSubscriber listens to…
Making an Argument Available to All Controllers
…it’s so important, that we want to be able to
have an $isMac argument in any controller function anywhere in the
system. This won’t come from a routing wildcard like normal - we’ll figure
this out by reading the User-Agent.
As an…
An Aside: Dependency Injection Parameters
…server can have their own. So we set parameters
here and use them anywhere else.
Adding More Parameters¶
But technically, we can add parameters to any configuration file. Go back
to config.yml and add a new parameters key anywhere in the file. Below
it…
Restricting Edit Access to Owners
…we’ll just deny access. And remember, you can deny
access anywhere in your app just by throwing the special AccessDeniedException.
Since we’ll need the same security logic in editAction, updateAction
and deleteAction, let’s create a private function called enforceOwnerSecurity
that holds it…
Functional Testing
…app/ directory.
And hey! There’s a phpunit.xml.dist file there already for it to read. This
tells phpunit how to bootstrap and where to find our tests.
But we see a few errors. If you look closely, you’ll see that it’s…
The QueryBuilder
…That is exactly what we wrote before! So, no surprise,
if we remove that dd() and refresh... we're back to working! It's just that easy.
Okay, we have the QueryBuilder basics down. Let's get more complex by adding
andWhere() and orWhere() next.
The Clever Criteria System
…this with a Criteria,
say addCriteria(self::createExpensiveCriteria()). Now that we're in a QueryBuilder,
we can do the normal stuff, like setMaxResults($limit). Want to do an orderBy
or an andWhere? Go for it. And of course, you can finish this with
getQuery()->getResult():…
Adding a Search + the Request Object
…QueryBuilder for now.
Now for the magic. If we have a search, add an andWhere() that checks if
the lower case name of our Starship part is like our search. I know it looks
a bit funky, but that's because PostgreSQL is case-sensitive…
DQL & The Query Builder
…the property... even though
the column in the table is asked_at. Now add ->orderBy() with
q.askedAt and DESC.
Oh, and notice that I'm using andWhere()... even though there are no WHERE
clauses before this! I'm doing this for 2 reasons. First..…
Filtering / Searching
…set the old return value to a new $qb variable. Then, if ($filter) has some value,
add a where clause: andWhere('programmer.nickname LIKE :filter OR programmer.tagLine LIKE filter').
Then use setParameter('filter' , '%'.$filter.'%'). Finish things by returning $qb
at the bottom:
If you…
SELECT the SUM (or COUNT)
…Keep the alias consistent for an entity, it'll
save you heartache later.
Next, we need an andWhere() because we need to only find FortuneCookie
results for this Category. So, fc.category - because category is the
name of the property on FortuneCookie for the relationship…
x
511