API won't stop eager loading - doctrine

I'm reading the docs here:
https://api-platform.com/docs/core/performance/#eager-loading
No matter what config I try, my API always eager loads relations in my payload.
Why is the API Platform ignoring these settings?
I've tried this to no avail
# api/config/packages/api_platform.yaml
api_platform:
eager_loading:
force_eager: false
# also tried this
api_platform:
eager_loading:
enabled: false
I've also tried annotations on my entity & relationship
/**
* #ApiResource(attributes={"force_eager"=false})
* #ORM\Entity
*/
class User
{
/**
* #var Address
*
* #ORM\ManyToOne(targetEntity="Address", fetch="LAZY")
*/
public $address;```

Related

How can I "validate" DELETE request in api-platform

I want to check the entity variable and check if it is allowed to delete the entity. For example if the owner entity of the association is linked to another entity, I want to make the deletion impossible.
I've looked in the documentation of api-platform bu I could not find any help regarding my problems. Either you give the right to delete or not. I could not find how to control it (equivalent to validation for POST, PUT and PATCH).
You can use the access control feature of Api-Platform and Symfony Expression Language to achieve what you want. This way you can write pretty complex expressions.
I hope this example makes it clear.
user is the currently logged in user.
object is the resource user is trying to delete.
/**
* #ApiResource(
* itemOperations={
* "delete"={
* "access_control"="is_granted('ROLE_USER') and object.getUsers().contains(user),
* }
* }
* )
*/
class Entity
{
/**
* #var ArrayCollection
*
* #ORM\OneToMany(targetEntity="User", inversedBy="entities")
* #ORM\JoinTable(name="entity_users")
*/
private $users;
/**
* #return ArrayCollection
*/
public function getUsers(): ArrayCollection
{
return $this->users;
}
}
In this case only users who are stored in users Array of Entity can delete this resource.

Overriding property name in Api Platform

Oke, so I have the following use case. On some of my entities I use a file entity for example with the organization logo.
Now I want users to post either a link (I will then async get the file) or a base64 has of the file. But when the user does a get I want to present an JSON representation of the file entity (that also includes size, a thumbnail link etc).
The current setup that I have is two different properties on my entity, one for reading and one for posting with different logic. And then an event listener that handels the logic. That’s all fine and all but it causes the user to post a postLogo property in their json file, I would hower like them to post to a logo property in their json file.
Is there an annotation that I can use (for example name on ApiProperty) to achieve this or do I need to override the serializer?
/**
* #var File The logo of this organisation
*
* #ORM\ManyToOne(targetEntity="File")
* #ApiProperty(
* attributes={
* "openapi_context"={
* "type"="#/components/schemas/File"
* }
* }
* )
* #Groups({"read"})
*/
public $logo;
/**
* #var string The logo of this organisation, a logo can iether be posted as a valid url to that logo or a base64 reprecentation of that logo.
*
* #ApiProperty(
* attributes={
* "openapi_context"={
* "type"="url or base64"
* }
* }
* )
* #Groups({"write"})
*/
public $postLogo;
You can add a setter with a SerializedName annotation. Something like this should work
/**
* #Groups({"write"})
* #SerializedName("logo")
*
*/
public function setPostLogo($value)
{
$this->postLogo = $value;
}

owner check not working with JWT auth

I'm following the example / documentation closely trying to set up a resource that only its owner can access, and I get this error:
"hydra:description": "Notice: Undefined property:
ApiPlatform\Core\Bridge\Doctrine\Orm\Paginator::$owner",
JWT authentication per se seems to work fine.
my resource is defined like this:
/**
* #ORM\Entity
* #ApiResource(
* attributes={"access_control"="is_granted('ROLE_USER') and object.owner == user"},
* collectionOperations={"get"},
* itemOperations={"get"},
* )
*/
Security and user provider and everything is set up exactly as in the api-platform or Symfony documentation.
The property owner is defined as:
/**
* #var User The owner
*
* #ORM\ManyToOne(targetEntity=User::class)
*/
public $owner;
What am I doing wrong?
I think this would work on your itemOperation GET, but not on your collectionOperation. The reason is that "object" in this case will the the collection of User objects, which is represented as the Paginator class.
#ahaaje is correct.
But you can still achieve what you're looking for by implementing an "extension". This would allow you to filter the collection with only items that belong to your user.
Official documentation is here.

FreeSwitch - It doesn't connect MySQL database using xml_mod_curl

After install FreeSwitch, I tried to connect user account using xml_mod_curl. I followed below instruction to connect MySQL database.
http://saevolgo.blogspot.kr/2012/07/freeswitch-with-sip-users-in-mysql-mod.html
I could see that it actually read XML to sign in SIP account with 1000-1019 username. However, it doesn't look like it connects MySQL database. I failed to sign in new user and new password that is saved in MySQL column.
here is global_defines.php
if (basename($_SERVER['PHP_SELF']) == basename(__FILE__)) {
header('Location: index.php');
}
/**
* Defines the default dsn for the FS_PDO class
*/
define('DEFAULT_DSN', 'mysql:dbname=FS_DB;host=127.0.0.1');
/**
* Defines the default dsn login for the PDO class
*/
define('DEFAULT_DSN_LOGIN', 'root');
/**
* Defines the default dsn password for the PDOclass
*/
define('DEFAULT_DSN_PASSWORD', 'mypassword');
/**
* Generic return success
*/
define('FS_CURL_SUCCESS', 0);
/**
* Generic return success
*/
define('FS_SQL_SUCCESS', '00000');
/**
* Generic return warning
*/
define('FS_CURL_WARNING', 1);
/**
* Generic return critical
*/
define('FS_CURL_CRITICAL', 2);
/**
* determines how the error handler handles warnings
*/
define('RETURN_ON_WARN', true);
/**
* Determines whether or not users should be domain specific
* If GLOBAL_USERS is true, user info will be returned for whatever
* domain is passed.....
* NOTE: using a1 hashes will NOT work with this setting
*/
define('GLOBAL_USERS', false);
The instruction article was written 2 years ago. It seems like there should be one more option to turn on My-SQL connection. Did I missing something?

how to reset symfony2 cached routes inside controller?

I want to add routes dynamically. I am storing tree of documents in database. Based on document's position in that tree i can generate url for specific document. Problem is, whenever I add document to that tree, I have to clean cache because url matcher is precached. But if I clean cache inside controller by deleting of content of cache directory error is thrown. Is there any way, how to solve it?
more problem specification:
I need more routes to create, because based on documents type, its called specific controller and action (even with specific parameters). In tree item entity i store url_part and some parameters to create particular route (like controller and action), then parameters, which are passed to that controller. Entity has method getRoute() which knows how to build route from its data. Then i have for example page document, it is entity called page and it has relation to tree item (i did not wanted to mess with inheritance). When i create page, it knows how to fill data for related tree item. Problem is, when i create page, its not unvalidated cache with existing routes. I wanna have routes cached, so after creating page i wanna reset cached routes.
Why do you want to generate routes dynamically? Can't you create a single route with a pattern which allows slashes?
I've made a similar CMS using Symfony2 before, and I used StofDoctrineExtensionsBundle (have a look at Tree and Sluggable).
My Document entity had the following fields to support tree structure:
/**
* #Gedmo\TreeLeft
* #ORM\Column(name="`left`", type="integer")
*/
private $left;
/**
* #Gedmo\TreeLevel
* #ORM\Column(name="level", type="integer")
*/
private $level;
/**
* #Gedmo\TreeRight
* #ORM\Column(name="`right`", type="integer")
*/
private $right;
/**
* #Gedmo\TreeRoot
* #ORM\Column(name="root", type="integer", nullable=true)
*/
private $root;
/**
* #Gedmo\TreeParent
* #ORM\ManyToOne(targetEntity="Page", inversedBy="children")
* #ORM\JoinColumn(name="parent_id", referencedColumnName="id", onDelete="SET NULL")
*/
private $parent;
/**
* #ORM\OneToMany(targetEntity="Page", mappedBy="parent")
* #ORM\OrderBy({"left" = "ASC"})
*/
private $children;
And a slug field which reflected the hierarchy:
/**
* #var string $slug
*
* #ORM\Column(name="slug", type="string", length=255, unique=true)
* #Gedmo\Slug(handlers={
* #Gedmo\SlugHandler(class="Gedmo\Sluggable\Handler\TreeSlugHandler", options={
* #Gedmo\SlugHandlerOption(name="parentRelationField", value="parent"),
* #Gedmo\SlugHandlerOption(name="separator", value="/")
* })
* }, fields={"title"})
*/
private $slug;
Isn't this what you're looking for?

Resources