Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add EntityInterface #8325

Closed

Conversation

colethorsen
Copy link
Contributor

@colethorsen colethorsen commented Dec 12, 2023

The main CodeIgniter entity couldn't be replaced with a custom one because the database drivers checked to see if entities were extensions of the entity itself and not an interface. Creating an interface allows for a completely new entity to implement the interface instead of having to extend the Entity itself.

Checklist:

  • Securely signed commits
  • Component(s) with PHPDoc blocks, only if necessary or adds value
  • Unit testing, with >80% coverage
  • User guide updated
  • Conforms to style guide

@colethorsen colethorsen force-pushed the add-entity-interface branch 4 times, most recently from 53caa77 to c8647b3 Compare December 12, 2023 19:08
@lonnieezell
Copy link
Member

I'm all for this. I am not sure if all of the methods in the interface need to be in the interface, though, and will have to look over that later.

@colethorsen
Copy link
Contributor Author

They probably don't from a methods utilized within the framework itself standpoint, we'd need to identify which ones are being used though to include. This is just all the public methods which seemed like the safest place to start.

@kenjis
Copy link
Member

kenjis commented Dec 12, 2023

In this case, the interface needs only the injectRawData() method.
If you need other methods, it is better to add other interfaces.
See https://en.wikipedia.org/wiki/Interface_segregation_principle

@kenjis
Copy link
Member

kenjis commented Dec 12, 2023

Is this a bug fix? If not, please go to 4.5 branch.

@colethorsen
Copy link
Contributor Author

In this case, the interface needs only the injectRawData() method. If you need other methods, it is better to add other interfaces.

I think given that this is to align with how you'd build a replacement entity, you'd at minimum want to require the implementation of those methods used in the model such as toRawArray()

@lonnieezell
Copy link
Member

Here's my list of methods we would want in the interface:

  • fill - it's too much a part of how I use an entity to imagine it not being there. Especially dealing with data from forms.
  • toArray and toRawArray
  • hasChanged
  • injectRawData since that's how the database injects data.

To me, those 5 methods are what defines the core of the functionality if you were to create your own.

@kenjis
Copy link
Member

kenjis commented Dec 13, 2023

Indeed, injectRawData() and toRawArray() can be considered a set.

But there is an opinion that hasChanged() should be removed. It is not a must.
It is better to add as another interface, if we create interface for it.

@michalsn
Copy link
Member

I would be in favor of adding bare minimum methods to the interface, which will ensure that everything will work properly with our model. While we may be used to more methods, I feel the custom Entity implementation should not impose anything beyond what is required.

That being said I agree with @kenjis - we need only injectRawData() and toRawArray() since no other methods are required elsewhere.

This option would also require a little mention in the user guide.

@lonnieezell
Copy link
Member

If thinking of it purely as a "what does the framework need" to work with an Entity than I agree with both of you. I was thinking of it more from a user's perspective of what's the bare minimum functionality I would need to be able to reasonably swap out usage of Entity types.

@colethorsen
Copy link
Contributor Author

With the point of this interface being to allow for the safe creation of a custom entity, and assuming that the only items required by the framework are injectRawData() and toRawArray() it probably makes sense to just include those. The others are all convenience and really the point of being able to create your own entity is that you might want to handle data differently or create a much more minimal entity and therefore the others probably shouldn't be required.

Even hasChanged() while likely something that would be pretty common is not required by the other 2 toRawArray() alreaady takes care of the change state through arguments.

@michalsn
Copy link
Member

@colethorsen - out of curiosity, why are you implementing your own Entity class? Are you missing some functionality or just have a custom use case?

@kenjis kenjis added wrong branch PRs sent to wrong branch enhancement PRs that improve existing functionalities docs needed Pull requests needing documentation write-ups and/or revisions. labels Dec 14, 2023
@kenjis
Copy link
Member

kenjis commented Dec 14, 2023

Thank you for updating.

I think this is an enhancement, not a bug fix.
So please change the base branch to 4.5.
https://github.com/codeigniter4/CodeIgniter4/blob/develop/contributing/workflow.md#if-you-sent-to-the-wrong-branch

@kenjis kenjis added the tests needed Pull requests that need tests label Dec 14, 2023
@kenjis kenjis changed the base branch from develop to 4.5 December 21, 2023 21:35
@kenjis kenjis closed this Dec 21, 2023
@kenjis kenjis reopened this Dec 21, 2023
@kenjis kenjis added 4.5 and removed wrong branch PRs sent to wrong branch labels Dec 21, 2023
@MGatner
Copy link
Member

MGatner commented Dec 28, 2023

@colethorsen - out of curiosity, why are you implementing your own Entity class? Are you missing some functionality or just have a custom use case?

Cole is one of our resident NoSQL devs. In my work with Firebase I definitely had to hack up Entity to get things to work, and eventually ditched it altogether - so my guess is that he's doing the same.

@kenjis
Copy link
Member

kenjis commented Jan 28, 2024

Please fix the code, and re-run composer cs-fix.

1 file with changes
===================

1) system/Entity/EntityInterface.php:0

    ---------- begin diff ----------
@@ @@
 <?php

+declare(strict_types=1);
+
 /**
  * This file is part of CodeIgniter 4 framework.
  *
@@ @@
  * For the full copyright and license information, please view
  * the LICENSE file that was distributed with this source code.
  */
-
 namespace CodeIgniter\Entity;

 /**
    ----------- end diff -----------

@kenjis kenjis changed the title add entity interface feat: add EntityInterface Jan 28, 2024
@kenjis kenjis removed the abandoned? Activity on a pull request is almost none since the last interaction with the author label Mar 12, 2024
@colethorsen colethorsen force-pushed the add-entity-interface branch from d19ee9c to f4eda59 Compare March 12, 2024 18:46
CHANGELOG.md Outdated Show resolved Hide resolved
@@ -143,7 +143,7 @@ protected function fetchObject(string $className = 'stdClass')

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update @return.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

--- a/system/Database/SQLite3/Result.php
+++ b/system/Database/SQLite3/Result.php
@@ -128,7 +128,7 @@ class Result extends BaseResult
      *
      * Overridden by child classes.
      *
-     * @return Entity|false|object|stdClass
+     * @return EntityInterface|false|object|stdClass
      */
     protected function fetchObject(string $className = 'stdClass')
     {

@kenjis
Copy link
Member

kenjis commented Mar 22, 2024

BaseResult still depends on Entity.
Replace it with the interface.

use CodeIgniter\Entity\Entity;

if (! is_subclass_of($row, Entity::class) && method_exists($row, 'syncOriginal')) {

if (! is_subclass_of($row, Entity::class) && method_exists($row, 'syncOriginal')) {

* @return Entity|false|object|stdClass

@colethorsen colethorsen force-pushed the add-entity-interface branch from fb94958 to 557e2b4 Compare March 22, 2024 17:05
@kenjis
Copy link
Member

kenjis commented Mar 26, 2024

Fix the PHPStan errors. Remove the following Ignored error pattern in phpstan-baseline.php.

Error: Ignored error pattern #^Method CodeIgniter\\Entity\\Entity\:\:injectRawData\(\) has parameter \$data with no value type specified in iterable type array\.$# in path /home/runner/work/CodeIgniter4/CodeIgniter4/system/Entity/Entity.php was not matched in reported errors.
Error: Ignored error pattern #^Method CodeIgniter\\Entity\\Entity\:\:toRawArray\(\) return type has no value type specified in iterable type array\.$# in path /home/runner/work/CodeIgniter4/CodeIgniter4/system/Entity/Entity.php was not matched in reported errors.
 ------ ----------------------------------------------------------------------- 
  Line   system/Entity/Entity.php                                               
 ------ ----------------------------------------------------------------------- 
         Ignored error pattern #^Method                                         
         CodeIgniter\\Entity\\Entity\:\:injectRawData\(\) has parameter \$data  
         with no value type specified in iterable type array\.$# in path        
         /home/runner/work/CodeIgniter4/CodeIgniter4/system/Entity/Entity.php   
         was not matched in reported errors.                                    
         Ignored error pattern #^Method                                         
         CodeIgniter\\Entity\\Entity\:\:toRawArray\(\) return type has no       
         value type specified in iterable type array\.$# in path                
         /home/runner/work/CodeIgniter4/CodeIgniter4/system/Entity/Entity.php   
         was not matched in reported errors.                                    
 ------ ----------------------------------------------------------------------- 


Error:  [ERROR] Found 2 errors  

https://github.com/codeigniter4/CodeIgniter4/actions/runs/8423534292/job/23065390399?pr=8325

Copy link

👋 Hi, @colethorsen!

We detected conflicts in your PR against the base branch 🙊
You may want to sync 🔄 your branch with upstream!

Ref: Syncing Your Branch

@github-actions github-actions bot added the stale Pull requests with conflicts label Mar 28, 2024
@colethorsen colethorsen force-pushed the add-entity-interface branch from db4fed1 to c43c429 Compare March 28, 2024 16:38
@kenjis
Copy link
Member

kenjis commented Mar 28, 2024

Resolve conflicts, please.

@kenjis
Copy link
Member

kenjis commented Apr 2, 2024

We will release v4.5.0 soon.
If you want this to be included, fix the issue.

@kenjis kenjis deleted the branch codeigniter4:4.5 April 7, 2024 04:47
@kenjis kenjis closed this Apr 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
4.5 docs needed Pull requests needing documentation write-ups and/or revisions. enhancement PRs that improve existing functionalities stale Pull requests with conflicts tests needed Pull requests that need tests
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants