Skip to content

Commit e3c66a1

Browse files
committed
Fix up Reflection.
1 parent a96c5f2 commit e3c66a1

File tree

5 files changed

+54
-9
lines changed

5 files changed

+54
-9
lines changed

src/Method/AssociationTableMixinClassReflectionExtension.php

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,17 +48,23 @@ protected function getTableReflection(): ClassReflection
4848
*/
4949
public function hasMethod(ClassReflection $classReflection, string $methodName): bool
5050
{
51-
// magic findBy* method
52-
if ($classReflection->is(Table::class) && preg_match('/^find(?:\w+)?By/', $methodName) > 0) {
53-
return true;
51+
// Check if it's a native method first, before treating as magic
52+
if ($classReflection->is(Table::class)) {
53+
if ($classReflection->hasNativeMethod($methodName)) {
54+
return false; // Let the native method be used
55+
}
56+
// magic findBy* method
57+
if (preg_match('/^find\w*By/', $methodName) > 0) {
58+
return true;
59+
}
5460
}
5561

5662
if (!$classReflection->is(Association::class)) {
5763
return false;
5864
}
5965

6066
// magic findBy* method on Association
61-
if (preg_match('/^find(?:\w+)?By/', $methodName) > 0) {
67+
if (preg_match('/^find\w*By/', $methodName) > 0) {
6268
return true;
6369
}
6470

@@ -72,16 +78,22 @@ public function hasMethod(ClassReflection $classReflection, string $methodName):
7278
*/
7379
public function getMethod(ClassReflection $classReflection, string $methodName): MethodReflection
7480
{
75-
// magic findBy* method
76-
if ($classReflection->is(Table::class) && preg_match('/^find(?:\w+)?By/', $methodName) > 0) {
77-
return new TableFindByPropertyMethodReflection($methodName, $classReflection);
81+
// Check if it's a native method first, before treating as magic
82+
if ($classReflection->is(Table::class)) {
83+
if ($classReflection->hasNativeMethod($methodName)) {
84+
return $classReflection->getNativeMethod($methodName);
85+
}
86+
// magic findBy* method
87+
if (preg_match('/^find\w*By/', $methodName) > 0) {
88+
return new TableFindByPropertyMethodReflection($methodName, $classReflection);
89+
}
7890
}
7991

8092
// magic findBy* method on Association
8193
$associationReflection = $this->reflectionProvider->getClass(Association::class);
8294
if (
8395
$classReflection->isSubclassOfClass($associationReflection)
84-
&& preg_match('/^find(?:\w+)?By/', $methodName) > 0
96+
&& preg_match('/^find\w*By/', $methodName) > 0
8597
) {
8698
return new TableFindByPropertyMethodReflection($methodName, $this->getTableReflection());
8799
}

src/Method/TableFindByPropertyMethodReflection.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,15 @@ public function hasSideEffects(): TrinaryLogic
210210
protected function getParams(string $method): array
211211
{
212212
$method = Inflector::underscore($method);
213-
$fields = substr($method, 8);
213+
// Extract the part after "find" and before "_by"
214+
// Handles: findBy, findAllBy, findOrCreateBy, etc.
215+
if (preg_match('/^find(?:_\w+)?_by_(.+)$/', $method, $matches) === 1) {
216+
$fields = $matches[1];
217+
} else {
218+
// Fallback for simple cases
219+
$fields = substr($method, 8);
220+
}
221+
214222
if (str_contains($fields, '_and_')) {
215223
return explode('_and_', $fields);
216224
}

tests/test_app/Model/Table/NotesTable.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ public function warning(): array
5959
$this->MyUsers->Articles->findByTitleAndActive('Test', true)->first();
6060
// Test findBy with Or operator
6161
$this->MyUsers->Articles->findByTitleOrActive('Test', true)->first();
62+
// Test magic findOrCreateBy methods on Table (issue #55)
63+
$noteQuery = $this->findOrCreateByNote('Test Note');
64+
$noteQuery->first();
6265
$entity = $this->get(10, cache: 'my_cache');
6366
if ($entity->note === 'Test') {
6467
$entity = $this->newEmptyEntity();

tests/test_app/Model/Table/UsersTable.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,5 +48,9 @@ public function blockOld(): void
4848
// Test magic findBy methods on association (issue #51)
4949
$articleQuery = $this->Articles->findByTitle('Test');
5050
$articleQuery->first();
51+
// Test actual (non-magic) findOrCreateBySku method with specific signature (issue #55)
52+
// This should use the native method, not the magic method reflection
53+
$article = $this->Articles->findOrCreateBySku('TEST-SKU', 'Test Article');
54+
$article->set('title', 'Updated Title');
5155
}
5256
}

tests/test_app/Model/Table/VeryCustomize00009ArticlesTable.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,22 @@ public function newSample()
6969
],
7070
);
7171
}
72+
73+
/**
74+
* Custom non-magic findOrCreateBySku method with specific signature
75+
*
76+
* @param string $sku
77+
* @param string $foo
78+
* @return \Cake\ORM\Entity
79+
*/
80+
public function findOrCreateBySku(string $sku, string $foo): Entity
81+
{
82+
$entity = $this->findBySku($sku)->first();
83+
if ($entity === null) {
84+
$entity = $this->newEntity(['sku' => $sku] + ['foo' => $foo]);
85+
$this->saveOrFail($entity);
86+
}
87+
88+
return $entity;
89+
}
7290
}

0 commit comments

Comments
 (0)