NotionCommotion
Members-
Posts
2,446 -
Joined
-
Last visited
-
Days Won
10
Everything posted by NotionCommotion
-
Alternatives to entity inheritance
NotionCommotion replied to NotionCommotion's topic in PHP Coding Help
What does model, view, controller, business model, service, presenter, action, domain, responder, router, mapper, entity, database model all have in common? They are all stuff! I definitely have a hard time keeping them all straight. Which is part of the problem. This API-Platform thing takes care of all the CRUD business logic as well as generating OpenAPI definitions, and then there are hooks to perform application specific business. I suppose I can find some other place to make the inheritance happen but then would be totally deviating from the intended approach. Well, actually maybe I could do it in the normalizers and denormalizers. Just seems that I should be doing it through composition. -
I'm having trouble listing the latest data.
NotionCommotion replied to maviyazilim's topic in PHP Coding Help
Please read the following, and tell me what it says in your own words. Fatal error: Uncaught ArgumentCountError: mysqli_query() expects at least 2 arguments, 1 given -
I'm having trouble listing the latest data.
NotionCommotion replied to maviyazilim's topic in PHP Coding Help
First look at what error message PHP send you. Then take a look at https://www.php.net/manual/en/mysqli.query.php You are doing the procedural (non OOP) version. mysqli_query ( mysqli $link , string $query , int $resultmode = MYSQLI_STORE_RESULT ) : mixed When you call a function or method, you need to provide something for all the arguments (i.e. inputs to the function) unless the input is followed by "=someDefaultValue". So, you don't send the just the query but first the mysqli link and then the query. -
Alternatives to entity inheritance
NotionCommotion replied to NotionCommotion's topic in PHP Coding Help
Where do you think all the Labadoodle cam from? Regardless, agree it is way to much. Was driving home last night and realized why some dislike too abstract of examples. Attempting to model life itself with a couple classes? Sure, we can extend a couple classes and have an academic run() and speak() method, but quickly breaks down. And for composition, suppose I would need to inject about a billion objects to even pretend to be doing so. Was hoping to add this before your response. Can't totally blame myself, however. Went online to look for examples and just about every one has to do with animals or vehicles. So, have Cat, Dog, Mouse, and Animal as entities, and Cat, Dog, Mouse, and Animal as real classes? What is the difference? I know you don't use Doctrine and probably not API Platform, and am not expecting any specific advice to those platforms (but, if someone else already uses them, please chime in!), however, do wish to model the entities so that I don't need to utilize inheritance. Not saying that there is anything wrong with inheritance but I am experience issues when used with Doctrine and API Platform (annotation on the parent does not extend to the child class, can't get serializer groups working as desired, likely other deficiencies which I haven't yet discovered, total lack of documentation on the subject, and suspect that they are known bugs). For the points (environmental data), Point is currently abstract and PhysicalPoint, VirtualPoint, and TransformedPoint all extend Point. While you can't tell by the below ERD, the same thing with Source and Datanode as they have the same super-subset inherited structure. Currently, if I request a collection of all Points, I would expect all to have the properties in Point as well as the properties of their specific sub-type. This works fine when I utilized all custom code, but doesn't work fine when using API-Platform with the standard Doctrine implementation (see above for definition of "not fine"). Also, I believe a RESTful API should have separate endpoints for resources that do not share the same structure. As an alternative structure, I am thinking that Point should be concrete (think that is the right word - not abstract with these child physical/etc concrete classes), but would be injected with some object (or objects) which would make it act like a physical, virtual, or transformed point. Then when serializing, Point would be serialized and and I would either also serialize this injected object or just provide its resource link. Maybe I am just not imaginative enough, but all I can think to call this injected object is something like PointType, and when I asked almost this exact same question, I realize it has been over two years and I still might not get it. Is it just what I am calling it where I am astray and I should call it what does (i.e. maybe DataSourceProvider) and not some generic PointType? Hopefully I do get it, but even so, seems like I still have the same issue not from a PHP perspective but from a SQL perspective. Point would need to have column data_source_provider_id which would reference some single table which would contain the data to create a PhysicalDataSourceProvider, VirtualDataSourceProvider, or TransformedDataSourceProvider. And that table would need to have both a reference to the class to be created and different data would likely (definitely for my case) be needed for each DataSourceProvider type. So, I am back to inheritance? Granted, I think I would be better off because each of these DataSourceProviders will be much more standalone. Still, think I am missing something because (I assume) many people utilize polymorphic objects with Doctrine and using Doctrine's inheritance options is rather rare (I believe). Ugg... -
Alternatives to entity inheritance
NotionCommotion replied to NotionCommotion's topic in PHP Coding Help
I was envisioning something like the following where $dog = new Animal(new DogDna());. I guess I still have the issue of inheritance at the DNA level as I would need a many-to-one relationship between animal and abstractDna, but hopefully less of an issue as it is a more isolated scope. class Animal { /** * @var DnaInterface */ private DnaInterface $dna; public function __construct(DnaInterface $dna) { $this->dna = $dna; } public function run() { $this->dna->run(); } } Humm, Initially, thought it looked off, but agree it basically does what inheritance does. How common is this approach? It might solve my immediate issues and will investigate, but am a little concerned if not often used for good reasons. What I have now is more classic inheritance where Mouse extends AbstractAnimal, BacnetGateway extends AbstractGateway, and PhysicalPoint extends AbstractPoint. Yes, Doctrine can do this, but as I said there appears to be shortcomings. I can consider your concept of inheritance but implemented using composition approach, but would like to first consider a more traditional composition approach. Is it possible with my Animal entity and if so how might it look? Thanks -
I am using API-Platform, Doctrine, and Symfony with entities that utilize class type inheritance to extend an abstract entity. I've been running into one issue after another primarily related to the serialization process (serialization groups, parent annotations not propagated to the child, etc), and while I am sure user error on my part is part of the culprit, it appears that API-Platform and potentially Symfony and Doctrine don't fully support entity inheritance. My reason for thinking so is the incredibly sparse amount of documentation on the subject and remarks on quite a few github issues posts and other blogs how it is "bad practice". For instance, say I have Mouse, Cat, and Dog which all extend AbstractAnimal, and each has a bunch of common properties such as birthday, weight, etc, and methods such as eats(), sleeps(), etc. Sorry in advance for using hypothetical entities but I don't think doing so distracts. I like how inheritance allows me to keep all common properties in a single table, but can let that go. More importantly, the subset mouse, cat, and dog table shares an ID from the animal table allowing me to associate all animals to some other table (i.e. many-to-one to person whether they are their pet or many-to-many to country whether they are native to a country), and to retrieve a list of animals and filter by some property or type as needed without a bunch of unions. To me, this sounds like inheritance, but if the products I am using don't support it very well, it doesn't matter. First question. Is entity inheritance considered bad practice? And even if not, is it common for frameworks to limit their level of support for them? If so, what can I do about it? Maybe favor composition over inheritance? Okay, great, I now have a single animal table which makes all my SQL concerns issues go away and I am pretty confident that my serialization issues will also go away. All I need to do is inject each animal with some "thing" to make them a mouse, cat, or dog. But what do I call this thing? I've struggled with this topic for a while and asked the same question regarding how to deal with BarCharts, PieCharts, GaugeCharts, LineCharts, etc all being charts but all acting slightly differently, and never really came to any conclusion. For a non-hypothetical scenario, I have BacnetGateway and ModbusGateway which extend AbstractGateway. Okay, this one is easy and I change to just having a Gateway and inject either BacnetProtocol or ModbusProtocol. For another non-hypothetical scenario, I have PhysicalPoint which represents some real environmental parameter, VirtualPoint which represents combining one or more PhysicalPoints or VirtualPoints, and TransformedPoint (feel free to provide a better name) which represents performing some time function such as integrating over a given time. Currently, they all extend AbstractPoint, but if I was trying to do so with composition, I could inject PointType but don't think doing so makes sense. For my hypothetical scenario, do I make a DNA interface and inject an Animal with DogDNA to get a dog? I really need to get my head around this once and for all. Thanks
-
reading fingerprint in php web base system (PDO)
NotionCommotion replied to naflinmoha's topic in PHP Coding Help
Or try this and that. -
Thanks kicken, Yeah, my memory is more fuzzy than I wish to admit. Gotcha on the other parts. I found that I would need to explicitly set some ORM monitored parameter such as updatedAt so that listeners actually listened to non-ORM monitored properties such as $newPasword. Appreciate and enjoy the rest of your weekend.
-
Hello again kicken, I struggled a little on using the correct interfaces and classes. First tried Symfony\Component\EventDispatcher\EventSubscriberInterface instead of your EventSubscriber, and found not only did it need to be static, also never called my post and pre load methods. Then tried Doctrine\Common\EventSubscriber and while it didn't need to be static, still never called the post/pre load methods. Only did Doctrine\Bundle\DoctrineBundle\EventSubscriber\EventSubscriberInterface work as desired. Using PHP 8 and Symfony 5.2.3. Look like I am doing things right but just a different version than you use? Also, I would have thought to use prePersist and preUpdate, but you used postLoad and preFlush. Do you mind expanding on this as well as your specific preFlush() code? Thanks! <?php namespace App\EventSubscriber; //use Doctrine\Common\EventSubscriber; //use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Doctrine\Bundle\DoctrineBundle\EventSubscriber\EventSubscriberInterface; use Doctrine\ORM\Events; use Doctrine\ORM\Event\LifecycleEventArgs; use Doctrine\ORM\Event\PreFlushEventArgs; use Doctrine\Common\Collections\ArrayCollection; use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface; use App\Entity\Account\EncodeOnPersistInterface; class EncodeOnPersist implements EventSubscriberInterface { private $encoderFactory; private $entityList; public function __construct(EncoderFactoryInterface $encoderFactory) { $this->encoderFactory = $encoderFactory; $this->entityList = new ArrayCollection(); } public function getSubscribedEvents():array { return [Events::postLoad, Events::preFlush]; } public function postLoad(LifecycleEventArgs $event):void { $entity = $event->getEntity(); $this->addEntity($entity); } public function preFlush(PreFlushEventArgs $event):void { $em = $event->getEntityManager(); foreach ($em->getUnitOfWork()->getScheduledEntityInsertions() as $entity){ $this->addEntity($entity); } foreach ($this->entityList as $entity){ $this->encodeEntity($entity); } $em->getUnitOfWork()->computeChangeSets(); } private function addEntity($entity):void { if ($entity instanceof EncodeOnPersistInterface && !$this->entityList->contains($entity)) { $this->entityList[] = $entity; } } private function encodeEntity(EncodeOnPersistInterface $entity):void { $entity->encodeOnPersist($this->encoderFactory); } }
-
Thanks kicken, Good information. I actually hate the magic. I waste so much time figuring out why something is happening that shouldn't and finally discover it is something I totally didn't expect. Regarding scanning files, Symfony 5.2.3 seems to scan all PHP files in src/* as you said. If I start some file but then don't finish it, I need to change the extension from .php to .php.tmp or I get errors (unless they are cached, sometimes). Didn't know about that single line service definition. Thanks.
-
Yes, I need to get over my class stinginess and create separate classes. At first putting a couple of tasks in a single class doesn't sting me, but eventually often does. I also like your approach of adding the EncodeOnPersistInterface to any entities that need it. Keeps things in one place. At first I thought it would be less code duplication to perform the encoding in EncodeOnPersist, but the more I think about it, the more I prefer your implementation. Thanks! Takes some of the magic away and makes me confident I can do this! One question I forgot to ask. Are there any "magic" directories that Symfony always/only scans and I need to know about or does it scan all directories without expectations and basis its action based on interfaces? And scans just for files with a .php extension, true?
-
Currently, I am using Doctrine events (prePersist or preUpdate as necessary) to do similar. For instance, new User is added but their password isn't yet hashed and they also need an account for another API so UserDoctrineEntityListner hashes their password and makes a cURL request to create their account and set's User's otherApiProperty using the response. On updating some user property which is shared with the other API, I do similarly but don't need the response to update the User entity. You "could have" done the same when you saved the approved timestamp. Was your primary reason why not to as your approach is more flexible should you want to do other things "when a committee is approved". Maybe use my approach only if these other tasks needed to also modify some Doctrine entity or use your approach and have it update the entity before persisting? Thanks! Takes some of the magic away and makes me confident I can do this! I didn't interpret the documentation that way but I think you are interpreting it correct. Entity listeners are defined as PHP classes that listen to a single Doctrine event on a single entity class. For example, suppose that you want to send some notifications whenever a User entity is modified in the database. To do so, define a listener for the postUpdate Doctrine event: For instance, I believe the following will work. App\EventListener\UserListner: tags: - name: 'doctrine.orm.entity_listener' event: 'prePersist' entity: 'App\Entity\Account\User' - name: 'doctrine.orm.entity_listener' event: 'preUpdate' entity: 'App\Entity\Account\User' - name: 'doctrine.orm.entity_listener' event: 'preRemove' entity: 'App\Entity\Account\User' As always, appreciate your advise.
-
I am a little confused with the difference between Symfony Events and Event Listners and Doctrine Events. The Doctrine events look pretty straight forward and are primary used for entity persistence, and I have outlined my understanding below: Doctrine Lifecycle Callbacks. Single entity and single Doctrine event. Method in class. Good performance. Don't have access to Symfony services (all others do) Doctrine Lifecycle Listeners. All entities and single Doctrine event. Separate class and configured in config.service.yaml. Doctrine Entity Listeners. Single entities and single Doctrine event. Separate class and configured in config.service.yaml. Doctrine Lifecycle Subscribers. All entities and multiple Doctrine event. Must implement EventSubscriber (or probably EventSubscriberInterface) Separate class and configured in config.service.yaml. I am more confused with the Symfony events and my interpretation as listed below is likely incorrect. Symfony Event Listeners. Single Symfony event. Separate class and configured in config.service.yaml. More flexible because bundles can enable or disable each of them conditionally depending on some configuration value. Symfony Event Subscribers. All specified Symfony events. Must implement EventSubscriberInterface Separate class but NOT configured in config.service.yaml but in class. Easier to reuse because the knowledge of the events is kept in the class rather than in the service definition. Are they used for totally different purposes or can one use Symfony events to also deal with entities? Where would one want to use these Symfony events? Is there a reason why Doctrine Lifecycle Subscribers are located in src/EventListener and not src/EventSubscriber Are Doctrine Lifecycle and Entity Listeners really only for a single event as I interpret the documentation states, or is it one method per Doctrine event such as the following? App\EventListener\SearchIndexer: tags: - name: 'doctrine.event_listener' event: 'postPersist' - name: 'doctrine.event_listener' event: 'postUpdate'
-
Reusable SELECT from any table and fields
NotionCommotion replied to aldo151's topic in PHP Coding Help
You mean this? $fields = array('id','type'); $fields[] = 'etc'; //$fields now is array('id','type', 'etc') -
No, but all apples are fruit but not all fruits are apples. The same goes for pears. Not sure about tomatoes... Can PHP "native" attributes be used to reflect all comment annotations? Not sure whether the word "native" is applicable... If someone knew the context of the attributes, couldn't one determine the equivalent annotations? For this use case, the use case is known, so why can't the equivalent annotations be derived? Or do I just need to upgrade to PHP8?
-
Per https://www.php.net/releases/8.0/en.php#attributes, it sure sounds like they are just a different way to do the same thing. What am I missing? Thanks PHP7 class PostsController { /** * @Route("/api/posts/{id}", methods={"GET"}) */ public function get($id) { /* ... */ } } PHP8 class PostsController { #[Route("/api/posts/{id}", methods: ["GET"])] public function get($id) { /* ... */ } }
-
The following script came from using-custom-paths. It appears that these are PHP 8's new attributes, correct? <?php // api/src/Entity/Question.php #[ApiResource( subresourceOperations: [ 'api_questions_answer_get_subresource' => [ 'method' => 'GET', 'path' => '/questions/{id}/all-answers', ], ], )] class Question { } I currently am using PHP7 and will need to convert them. Does the following look correct? Thanks /** * @ApiResource( * subresourceOperations = { * "api_questions_answer_get_subresource" = { * "method" = "GET", * "path" = "/questions/{id}/all-answers" * } * } * ) */
-
Retrieving a request parameter from Symfony's Request
NotionCommotion replied to NotionCommotion's topic in PHP Coding Help
Thanks kicken, I am surprised and was sure it was user error on my part. I think I am sending the correct content type header, but maybe symfony's request class isn't that sophisticated. Still hard to believe. -
Doing something wrong, but don't see it. How should one retrieve a POST parameter? My $request->toArray()['html'] works, but I am sure it is not the "right way". <?php namespace App\DataPersister; use ApiPlatform\Core\DataPersister\DataPersisterInterface; use Symfony\Component\HttpFoundation\RequestStack; class ArchivePersister implements DataPersisterInterface { public function __construct(RequestStack $requestStack) { $request = $requestStack->getCurrentRequest(); syslog(LOG_ERR, '$request->getMethod(): '.$request->getMethod()); syslog(LOG_ERR, '$request->getContent(): '.$request->getContent()); syslog(LOG_ERR, '$request->request->get(html): '.$request->request->get('html')); syslog(LOG_ERR, '$request->query->get(html): '.$request->query->get('html')); syslog(LOG_ERR, '$request->get(html): '.$request->get('html')); syslog(LOG_ERR, '$request->toArray(): '.json_encode($request->toArray())); syslog(LOG_ERR, '$request->toArray()[html]: '.$request->toArray()['html']); } } output $request->getMethod(): POST $request->getContent(): {"project":"/projects/1","description":"","html":"<p>{{ project_name }}</p>"} $request->request->get(html): $request->query->get(html): $request->get(html): $request->toArray(): {"project":"\/projects\/1","description":"","html":"<p>{{ project_name }}<\/p>"} $request->toArray()[html]: <p>{{ project_name }}</p>
-
Uploading a file with JSON to a REST API
NotionCommotion replied to NotionCommotion's topic in PHP Coding Help
Yeah, I would expect so even though there doesn't appear to be any definitive REST direction regarding sub-resources, the api-platform doesn't do so out of the box, and the previously mentioned youtube google reference doesn't appear to do it this way. Regardless, I will do it this way. Thanks -
Uploading a file with JSON to a REST API
NotionCommotion replied to NotionCommotion's topic in PHP Coding Help
Sorry, changing to create the entity first and then the file which resulted in a dilemma. When previously I sent the file first, I first performed a POST to /files with only the file in the body which returned {"url": "/media/somefile.ext", "foo": "bar"}. I then performed a POST to /documents with {"file": "/media/somefile.ext", "project": "/projects/321", name": "the name", "etc": "etc"} in the body which returned {"id": 123, "file": "/media/somefile.ext", "project": "/projects/321", name": "the name", "etc": "etc"}. For the new approach creating the entity first, I will still do the same POST request to /documents but without the file location and will get back {"id": 123, "file": null, "project": "/projects/321", name": "the name", "etc": "etc"} back. But now I can't do a POST to /files as it needs the documentID metadata (which obviously I don't want to mix with the file in the body). Would my two options be to post the file to either /documents/123/file or to /file?documentId=123? Is one approach considered more proper than the other? -
Uploading a file with JSON to a REST API
NotionCommotion replied to NotionCommotion's topic in PHP Coding Help
So much for bathing in my ignorance Okay, I see your point about not changing the flow based on whether there can be one or more files. My reasoning for uploading the file first when associated one-to-one with an entity was that then I could place a not null constraint on entity.file. Thank you for the update.