1000 search results

// ... lines 1 - 11
class CheeseListingIsPublishedExtension implements QueryCollectionExtensionInterface, QueryItemExtensionInterface
{
// ... lines 14 - 20
public function applyToCollection(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, string $operationName = null)
{
$this->addWhere($queryBuilder, $resourceClass);
}
// ... lines 25 - 30
private function addWhere(QueryBuilder $queryBuilder, string $resourceClass): void
{
if ($resourceClass !== CheeseListing::class) {
return;
}
if ($this->security->isGranted('ROLE_ADMIN')) {
return;
}
$rootAlias = $queryBuilder->getRootAliases()[0];
$queryBuilder->andWhere(sprintf('%s.isPublished = :isPublished', $rootAlias))
->setParameter('isPublished', true);
}
}
See Code Block in Script
// ... lines 1 - 25
public function applyToItem(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, array $identifiers, string $operationName = null, array $context = [])
{
$this->addWhere($queryBuilder, $resourceClass);
}
// ... lines 30 - 45
See Code Block in Script
// ... lines 1 - 2
namespace App\ApiPlatform;
// ... line 4
use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
// ... lines 6 - 7
class AutoGroupResourceMetadataFactory implements ResourceMetadataFactoryInterface
{
// ... lines 10 - 22
}
See Code Block in Script
// ... lines 1 - 5
use ApiPlatform\Core\Metadata\Resource\ResourceMetadata;
// ... line 7
class AutoGroupResourceMetadataFactory implements ResourceMetadataFactoryInterface
{
// ... lines 10 - 16
public function create(string $resourceClass): ResourceMetadata
{
// ... lines 19 - 21
}
}
See Code Block in Script
// ... lines 1 - 7
class AutoGroupResourceMetadataFactory implements ResourceMetadataFactoryInterface
{
private $decorated;
// ... line 11
public function __construct(ResourceMetadataFactoryInterface $decorated)
{
$this->decorated = $decorated;
}
// ... lines 16 - 22
}
See Code Block in Script
// ... lines 1 - 16
public function create(string $resourceClass): ResourceMetadata
{
$resourceMetadata = $this->decorated->create($resourceClass);
return $resourceMetadata;
}
// ... lines 23 - 24
See Code Block in Script
// ... lines 1 - 7
class AutoGroupResourceMetadataFactory implements ResourceMetadataFactoryInterface
{
// ... lines 10 - 33
private function updateContextOnOperations(array $operations, string $shortName, bool $isItem)
{
foreach ($operations as $operationName => $operationOptions) {
$operationOptions['normalization_context'] = $operationOptions['normalization_context'] ?? [];
$operationOptions['normalization_context']['groups'] = $operationOptions['normalization_context']['groups'] ?? [];
$operationOptions['normalization_context']['groups'] = array_unique(array_merge(
$operationOptions['normalization_context']['groups'],
$this->getDefaultGroups($shortName, true, $isItem, $operationName)
));
$operationOptions['denormalization_context'] = $operationOptions['denormalization_context'] ?? [];
$operationOptions['denormalization_context']['groups'] = $operationOptions['denormalization_context']['groups'] ?? [];
$operationOptions['denormalization_context']['groups'] = array_unique(array_merge(
$operationOptions['denormalization_context']['groups'],
$this->getDefaultGroups($shortName, false, $isItem, $operationName)
));
$operations[$operationName] = $operationOptions;
}
return $operations;
}
private function getDefaultGroups(string $shortName, bool $normalization, bool $isItem, string $operationName)
{
$shortName = strtolower($shortName);
$readOrWrite = $normalization ? 'read' : 'write';
$itemOrCollection = $isItem ? 'item' : 'collection';
return [
// {shortName}:{read/write}
// e.g. user:read
sprintf('%s:%s', $shortName, $readOrWrite),
// {shortName}:{item/collection}:{read/write}
// e.g. user:collection:read
sprintf('%s:%s:%s', $shortName, $itemOrCollection, $readOrWrite),
// {shortName}:{item/collection}:{operationName}
// e.g. user:collection:get
sprintf('%s:%s:%s', $shortName, $itemOrCollection, $operationName),
];
}
}
See Code Block in Script
// ... lines 1 - 16
public function create(string $resourceClass): ResourceMetadata
{
// ... lines 19 - 20
$itemOperations = $resourceMetadata->getItemOperations();
$resourceMetadata = $resourceMetadata->withItemOperations(
$this->updateContextOnOperations($itemOperations, $resourceMetadata->getShortName(), true)
);
$collectionOperations = $resourceMetadata->getCollectionOperations();
$resourceMetadata = $resourceMetadata->withCollectionOperations(
$this->updateContextOnOperations($collectionOperations, $resourceMetadata->getShortName(), false)
);
// ... lines 30 - 31
}
// ... lines 33 - 77
See Code Block in Script
Checkout API Request

…type' => 'checkouts']]. We can leave the rest of the options empty for now. LemonSqueezy's API docs don't really clarify which option is required, so we'll just have to figure it out for ourselves. Down here, since we have a JSON response…

7:17
Enhancing API Error Handling

… The generic error message is now a custom message: LS API Error: 422 Unprocessable entity "The {0} field must be a string" (at path "data/attributes/checkout_data/custom/user_id"). That was much easier to understand. All we need to do now is return…

4:45
Serializer & API Endpoint

…every method requires authentication. Then, to transform the User object into JSON - this is pretty cool - return $this->json() and pass $user: Let's try it! In your browser, head over to /api/account. And! Oh! That's not what I expected! It's JSON…

5:29
99 api/problem+json(s)

…JSON API returned the same format when things went wrong: always with these keys. That'd be pretty awesome. As API client, we'd always know what to expect and what things mean. That's a beautiful fairy tale. In the real world, every API

3:21
JSON API Endpoint

…to the server that will, eventually, update something in a database to show that the we liked this article. That API endpoint also needs to return the new number of hearts to show on the page... ya know... in case 10 other people liked it…

6:29
Generating the API Token & Fixtures

…be nullable anymore. It will always be a string. Ok! This is set up! So let's add some API tokens to the database. At your terminal, run php ./bin/console make:factory so we can generate a Foundry factory for ApiToken. Go check out…

5:58
The Values API

…your server into your Stimulus controller - that stimulus gives us a special system for handling this... with a couple of really nice advantages. It's called the values API. Here's how it works. Step 1, add a static values property set to an object…

7:03
The REST API Tutorial

…won’t make it through chapter 2. The same goes for “representations”. Pay special attention to the links on each page and how resources interact. Our API will feel a lot like the web interface. With a programmer, you can take an action on her…

3:07
To use API Token Authentication or Not?

…my user data! The Ajax request sends the session cookie and so... authentication just works. So if the only thing that needs to use your API is your own JavaScript, save yourself a lot of trouble and just use a login form. And if you…

4:09
Proper JSON API Endpoint Setup

…you, awesome, use Symfony forms. We need to make two adjustments. First, get rid of the CSRF _token field. Protecting your API against CSRF attacks is a little more complicated, and a topic for another time. Second, when you use the Symfony form component, it…

4:46
POSTing to the API Endpoint

Before we keep going, I want to go back and look at what it used to look like when we submitted the form. I have not refreshed yet, and this AJAX call is an example of what the POST request looked like using our old…

3:59
Logout & Passing API Data to JS on Page Load

…see that we're currently logged in. And now... gone! We are anonymous. Before we keep going with all this API & security goodness, our app has a bug. If we log in... as soon as the AJAX call finishes, we've made our Vue.js…

8:49