Skip to content

Commit d12f22e

Browse files
authored
Fix issue with model::for() not actually creating a post/term for the post type/taxonomy (#637)
* Failing test * Switch to class created with eval * Remove unused classes * CHANGELOG typo * Ignore unset.possiblyHookedProperty
1 parent 50c9d8d commit d12f22e

File tree

5 files changed

+73
-65
lines changed

5 files changed

+73
-65
lines changed

CHANGELOG.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## v1.5.4 - 2025-03-06
9+
10+
### Fixed
11+
12+
- Fix the `Post::for()`/`Term::for()` methods to properly set the post
13+
type/taxonomy for the model when creating a new instance. Previously, the
14+
model would always be created with the default post type/taxonomy.
15+
816
## v1.5.3 - 2025-03-04
917

1018
### Changed
@@ -18,7 +26,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1826

1927
### Fixed
2028

21-
- Fixed bad configuration file caling `env()` vs `environment()`.
29+
- Fixed bad configuration file calling `env()` vs `environment()`.
2230

2331
## v1.5.1 - 2025-02-06
2432

phpstan.neon

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ parameters:
1818
identifier: require.fileNotFound
1919
-
2020
identifier: requireOnce.fileNotFound
21+
-
22+
identifier: unset.possiblyHookedProperty
2123
-
2224
identifier: function.alreadyNarrowedType
2325
paths:

src/mantle/database/model/class-post.php

Lines changed: 22 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@
88
namespace Mantle\Database\Model;
99

1010
use Carbon\Carbon;
11-
use DateTime;
1211
use DateTimeInterface;
1312
use Mantle\Contracts;
1413
use Mantle\Database\Model\Relations\Belongs_To;
15-
use Mantle\Database\Model\Relations\Has_One;
1614
use Mantle\Database\Query\Builder;
1715
use Mantle\Database\Query\Post_Query_Builder;
1816
use Mantle\Support\Helpers;
1917

18+
use function Mantle\Support\Helpers\stringable;
19+
2020
/**
2121
* Post Model
2222
*
@@ -182,43 +182,28 @@ public static function find( $object ) {
182182
*
183183
* @param string $post_type Post type to create the model for.
184184
*/
185-
public static function for( string $post_type ): self {
186-
$instance = new class() extends Post {
187-
/**
188-
* Constructor.
189-
*/
190-
public function __construct() {}
191-
192-
/**
193-
* Post type for the model.
194-
*/
195-
public static string $for_object_name = '';
196-
197-
/**
198-
* Retrieve the object name.
199-
*/
200-
public static function get_object_name(): string {
201-
return self::$for_object_name;
202-
}
203-
204-
/**
205-
* Boot the model if it has not been booted.
206-
*
207-
* Prevent booting the model unless the object name is set.
208-
*/
209-
public static function boot_if_not_booted(): void {
210-
if ( empty( self::$for_object_name ) ) {
211-
return;
212-
}
213-
214-
parent::boot_if_not_booted();
215-
}
216-
};
185+
public static function for( string $post_type ): Post {
186+
$post_type = sanitize_key( $post_type );
187+
$class_name = 'Post_' . stringable( $post_type )->studly()->replace( '-', '_' )->__toString();
188+
$namespace = __NAMESPACE__;
189+
190+
if ( ! class_exists( "{$namespace}\\{$class_name}" ) ) {
191+
// Similar to how Mockery creates classes on the fly for testing. No other
192+
// solution was found to create a class on the fly.
193+
eval( // phpcs:ignore Squiz.PHP.Eval.Discouraged
194+
<<<PHP
195+
namespace {$namespace} {
196+
class {$class_name} extends Post {
197+
public static \$object_name = '{$post_type}';
198+
}
199+
}
200+
PHP
201+
);
202+
}
217203

218-
$instance::$for_object_name = $post_type;
219-
$instance::boot_if_not_booted();
204+
$full_class_name = "{$namespace}\\{$class_name}";
220205

221-
return $instance;
206+
return new $full_class_name();
222207
}
223208

224209
/**

src/mantle/database/model/class-term.php

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
use Mantle\Database\Query\Term_Query_Builder;
1414
use Mantle\Support\Helpers;
1515

16+
use function Mantle\Support\Helpers\stringable;
17+
1618
/**
1719
* Term Model
1820
*
@@ -114,30 +116,27 @@ public static function find( $object ) {
114116
* @param string $taxonomy Taxonomy to create the model for.
115117
*/
116118
public static function for( string $taxonomy ): self {
117-
$instance = new class() extends Term {
118-
/**
119-
* Constructor.
120-
*/
121-
public function __construct() {}
122-
123-
/**
124-
* Boot the model if it has not been booted.
125-
*
126-
* Prevent booting the model unless the object name is set.
127-
*/
128-
public static function boot_if_not_booted(): void {
129-
if ( empty( self::$object_name ) ) {
130-
return;
131-
}
132-
133-
parent::boot_if_not_booted();
134-
}
135-
};
136-
137-
$instance::$object_name = $taxonomy;
138-
$instance::boot_if_not_booted();
139-
140-
return $instance;
119+
$taxonomy = sanitize_key( $taxonomy );
120+
$class_name = 'Term_' . stringable( $taxonomy )->studly()->replace( '-', '_' )->__toString();
121+
$namespace = __NAMESPACE__;
122+
123+
if ( ! class_exists( "{$namespace}\\{$class_name}" ) ) {
124+
// Similar to how Mockery creates classes on the fly for testing. No other
125+
// solution was found to create a class on the fly.
126+
eval( // phpcs:ignore Squiz.PHP.Eval.Discouraged
127+
<<<PHP
128+
namespace {$namespace} {
129+
class {$class_name} extends Term {
130+
public static \$object_name = '{$taxonomy}';
131+
}
132+
}
133+
PHP
134+
);
135+
}
136+
137+
$full_class_name = "{$namespace}\\{$class_name}";
138+
139+
return new $full_class_name();
141140
}
142141

143142
/**

tests/Database/Model/PostObjectTest.php

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -253,13 +253,27 @@ public function test_dynamic_model_instance() {
253253

254254
$this->assertEquals( 'foo_post_type', get_post_type( $post_id ) );
255255

256+
$dynamic_model = Post::for( 'foo_post_type' );
257+
256258
$this->assertEmpty( Post::find( $post_id ) );
257-
$this->assertInstanceOf( Post::class, Post::for( 'foo_post_type' ) );
258-
$this->assertEquals( $post_id, Post::for( 'foo_post_type' )->find( $post_id )->id() );
259+
$this->assertInstanceOf( Post::class, $dynamic_model );
260+
$this->assertEquals( $post_id, $dynamic_model->find( $post_id )->id() );
259261
$this->assertEquals(
260262
$post_two,
261-
Post::for( 'foo_post_type' )->where( 'title', 'Post Two' )->first()->id(),
263+
$dynamic_model->where( 'title', 'Post Two' )->first()->id(),
262264
);
265+
266+
// Test creating a post via the dynamic model.
267+
$new_post = $dynamic_model->create(
268+
[
269+
'post_title' => 'New Post',
270+
]
271+
);
272+
273+
$post = get_post( $new_post->id() );
274+
275+
$this->assertEquals( 'foo_post_type', $post->post_type );
276+
$this->assertEquals( 'New Post', $post->post_title );
263277
}
264278

265279
public function test_query_builder() {

0 commit comments

Comments
 (0)