From 00200eb95e3b0cc930dcd6d7dcd2e20418f59eb3 Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Mon, 25 Sep 2023 22:15:55 +0200 Subject: [PATCH 01/67] #6 Add php-cs-fixer, update php and illuminate/database versions, start clean code --- .gitignore | 4 +- .php-cs-fixer.php | 47 +++++++++++++++ Makefile | 5 ++ composer.json | 9 ++- src/Builders/AbstractBuilder.php | 13 +++-- src/Builders/CommentBuilder.php | 13 +++-- src/Builders/OptionBuilder.php | 11 ++-- src/Builders/PostBuilder.php | 11 ++-- src/Builders/TermBuilder.php | 15 ++--- src/Builders/Traits/WithMeta.php | 19 ++++--- src/Builders/UserBuilder.php | 11 ++-- src/Exceptions/MetaNotSupportedException.php | 13 +++-- src/Exceptions/NotAllowedException.php | 11 ++-- src/Migration/Config.php | 15 ++--- src/Models/Article.php | 15 ++--- src/Models/Attachment.php | 15 ++--- src/Models/Comment.php | 46 ++++++++------- src/Models/CustomComment.php | 16 +++--- src/Models/CustomPost.php | 13 +++-- src/Models/Meta/AbstractMeta.php | 17 +++--- src/Models/Meta/MetaInterface.php | 13 +++-- src/Models/Meta/PostMeta.php | 14 +++-- src/Models/Meta/UserMeta.php | 14 +++-- src/Models/Meta/WithMeta.php | 19 ++++--- src/Models/Option.php | 18 +++--- src/Models/Page.php | 11 ++-- src/Models/Post.php | 60 ++++++++++---------- src/Models/Term.php | 20 ++++--- src/Models/TermRelationship.php | 18 +++--- src/Models/TermTaxonomy.php | 26 +++++---- src/Models/Traits/HasCustomType.php | 15 ++--- src/Models/User.php | 34 +++++------ src/Orm/AbstractModel.php | 17 +++--- src/Orm/Builder.php | 20 ++++--- src/Orm/Database.php | 56 ++++++++++-------- src/Orm/Resolver.php | 21 +++---- src/Scopes/CustomPostAddTypeScope.php | 14 ++--- src/includes/migrations.php | 8 ++- 38 files changed, 415 insertions(+), 302 deletions(-) create mode 100644 .php-cs-fixer.php create mode 100644 Makefile diff --git a/.gitignore b/.gitignore index 3051de5..727390c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ - vendor/ .idea/ - +composer.lock +.php-cs-fixer.cache \ No newline at end of file diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php new file mode 100644 index 0000000..0981160 --- /dev/null +++ b/.php-cs-fixer.php @@ -0,0 +1,47 @@ + + */ + +$finder = \PhpCsFixer\Finder::create() + ->name('*.php') + ->in([ + 'src', + ]) +; + +$header = << + EOF; + +$config = new \PhpCsFixer\Config(); +return $config + ->setFinder($finder) + ->setRiskyAllowed(true) + ->setRules([ + '@PSR12' => true, + '@PHP81Migration' => true, + 'strict_param' => true, + 'array_syntax' => ['syntax' => 'short'], + 'octal_notation' => false, + 'trim_array_spaces' => true, + 'phpdoc_order' => true, + 'ordered_imports' => true, + 'new_with_braces' => true, + 'method_chaining_indentation' => true, + 'no_unused_imports' => true, + 'align_multiline_comment' => true, + 'array_indentation' => true, + 'header_comment' => [ + 'header' => $header, + 'comment_type' => 'PHPDoc', + 'location' => 'after_open', + 'separate' => 'bottom', + ], + ]); diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..2583a87 --- /dev/null +++ b/Makefile @@ -0,0 +1,5 @@ +.PHONY: csFixer + +# Fix CS fixer +csFixer: + php vendor/bin/php-cs-fixer fix \ No newline at end of file diff --git a/composer.json b/composer.json index 59b324d..7ef9f18 100644 --- a/composer.json +++ b/composer.json @@ -19,9 +19,9 @@ "minimum-stability": "dev", "prefer-stable": true, "require": { - "php": "^7.4|^8.0", - "illuminate/database": "^8.0", - "robmorgan/phinx": "^0.12.5" + "php": ">=8.1", + "robmorgan/phinx": "^0.12.5", + "illuminate/database": "^10.0" }, "suggest": { "illuminate/events": "Add events to your models" @@ -33,5 +33,8 @@ "psr-4": { "Dbout\\WpOrm\\": "src/" } + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.28" } } diff --git a/src/Builders/AbstractBuilder.php b/src/Builders/AbstractBuilder.php index 81de640..1e6fc12 100644 --- a/src/Builders/AbstractBuilder.php +++ b/src/Builders/AbstractBuilder.php @@ -1,4 +1,10 @@ + */ namespace Dbout\WpOrm\Builders; @@ -6,13 +12,8 @@ use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; -/** - * Class AbstractBuilder - * @package Dbout\WpOrm\Builders - */ abstract class AbstractBuilder extends Builder { - /** * @inheritDoc */ @@ -34,7 +35,7 @@ protected function _whereOrIn(string $columns, array $value): self $first = reset($value); if(is_array($first)) { $this->whereIn($columns, $first); - } else if(count($value) == 1) { + } elseif(count($value) == 1) { $this->where($columns, reset($value)); } else { $this->whereIn($columns, $value); diff --git a/src/Builders/CommentBuilder.php b/src/Builders/CommentBuilder.php index a43cef0..b819480 100644 --- a/src/Builders/CommentBuilder.php +++ b/src/Builders/CommentBuilder.php @@ -1,17 +1,18 @@ + */ namespace Dbout\WpOrm\Builders; use Dbout\WpOrm\Models\Comment; use Illuminate\Database\Eloquent\Collection; -/** - * Class CommentBuilder - * @package Dbout\WpOrm\Builders - */ class CommentBuilder extends AbstractBuilder { - /** * @param string $type * @return Collection @@ -31,4 +32,4 @@ public function whereTypes(...$types): self { return $this->_whereOrIn(Comment::TYPE, $types); } -} \ No newline at end of file +} diff --git a/src/Builders/OptionBuilder.php b/src/Builders/OptionBuilder.php index 8c67f6a..6fe0384 100644 --- a/src/Builders/OptionBuilder.php +++ b/src/Builders/OptionBuilder.php @@ -1,16 +1,17 @@ + */ namespace Dbout\WpOrm\Builders; use Dbout\WpOrm\Models\Option; -/** - * Class OptionBuilder - * @package Dbout\WpOrm\Builders - */ class OptionBuilder extends AbstractBuilder { - /** * @param string $optionName * @return Option|null diff --git a/src/Builders/PostBuilder.php b/src/Builders/PostBuilder.php index 64a6e09..e3b25c8 100644 --- a/src/Builders/PostBuilder.php +++ b/src/Builders/PostBuilder.php @@ -1,4 +1,10 @@ + */ namespace Dbout\WpOrm\Builders; @@ -6,13 +12,8 @@ use Dbout\WpOrm\Models\Post; use Illuminate\Database\Eloquent\Collection; -/** - * Class PostBuilder - * @package Dbout\WpOrm\Builders - */ class PostBuilder extends AbstractBuilder { - use WithMeta; /** diff --git a/src/Builders/TermBuilder.php b/src/Builders/TermBuilder.php index c2a806b..6ab8eff 100644 --- a/src/Builders/TermBuilder.php +++ b/src/Builders/TermBuilder.php @@ -1,25 +1,26 @@ + */ namespace Dbout\WpOrm\Builders; use Dbout\WpOrm\Models\TermTaxonomy; use Illuminate\Database\Eloquent\Collection; -/** - * Class TermBuilder - * @package Dbout\WpOrm\Builders - */ class TermBuilder extends AbstractBuilder { - /** * @param string $taxonomy * @return Collection */ public function findAllByTaxonomy(string $taxonomy): Collection { - return $this->whereHas('termTaxonomy', function ($query) use($taxonomy) { + return $this->whereHas('termTaxonomy', function ($query) use ($taxonomy) { return $query->where(TermTaxonomy::TAXONOMY, $taxonomy); })->get(); } -} \ No newline at end of file +} diff --git a/src/Builders/Traits/WithMeta.php b/src/Builders/Traits/WithMeta.php index 5bb19f7..0e5712f 100644 --- a/src/Builders/Traits/WithMeta.php +++ b/src/Builders/Traits/WithMeta.php @@ -1,4 +1,10 @@ + */ namespace Dbout\WpOrm\Builders\Traits; @@ -7,13 +13,8 @@ use Dbout\WpOrm\Orm\AbstractModel; use Illuminate\Database\Eloquent\Model; -/** - * Trait WithMeta - * @package Dbout\WpOrm\Builders\Traits - */ trait WithMeta { - /** * @var array|string[] */ @@ -61,7 +62,7 @@ public function addMetasToSelect(array $metas): self $this->addMetaToSelect($metaName, $alias); } - + return $this; } @@ -88,7 +89,7 @@ public function addMetaToFilter(string $metaKey, $value, string $operator = '=') public function setModel(Model $model) { $traits = class_uses_recursive(get_class($model)); - if (!in_array(\Dbout\WpOrm\Models\Meta\WithMeta::class, $traits)) { + if (!in_array(\Dbout\WpOrm\Models\Meta\WithMeta::class, $traits, true)) { throw new MetaNotSupportedException(sprintf( "Model %s must be use trait %s", get_class($model), @@ -123,11 +124,11 @@ public function joinToMeta(string $metaKey, string $joinType = 'inner'): self /** @var \Illuminate\Database\Query\JoinClause $join */ $join->on( sprintf('%s.%s', $metaKey, $this->metaModel->getKeyColumn()), - '=', + '=', $join->raw(sprintf("'%s'", $metaKey)) )->on( $join->raw(sprintf("%s.%s", $metaKey, $this->metaModel->getFkColumn())), - '=', + '=', sprintf('%s.%s', $model->getTable(), $model->getKeyName()), ); }); diff --git a/src/Builders/UserBuilder.php b/src/Builders/UserBuilder.php index 8d0ab7e..4a417d4 100644 --- a/src/Builders/UserBuilder.php +++ b/src/Builders/UserBuilder.php @@ -1,17 +1,18 @@ + */ namespace Dbout\WpOrm\Builders; use Dbout\WpOrm\Builders\Traits\WithMeta; use Dbout\WpOrm\Models\User; -/** - * Class UserBuilder - * @package Dbout\WpOrm\Builders - */ class UserBuilder extends AbstractBuilder { - use WithMeta; /** diff --git a/src/Exceptions/MetaNotSupportedException.php b/src/Exceptions/MetaNotSupportedException.php index cc0c3eb..352ff71 100644 --- a/src/Exceptions/MetaNotSupportedException.php +++ b/src/Exceptions/MetaNotSupportedException.php @@ -1,12 +1,13 @@ + */ namespace Dbout\WpOrm\Exceptions; -/** - * Class MetaNotSupportedException - * @package Dbout\WpOrm\Exceptions - */ class MetaNotSupportedException extends \Exception { - -} \ No newline at end of file +} diff --git a/src/Exceptions/NotAllowedException.php b/src/Exceptions/NotAllowedException.php index 64be9c2..e659a2f 100644 --- a/src/Exceptions/NotAllowedException.php +++ b/src/Exceptions/NotAllowedException.php @@ -1,12 +1,13 @@ + */ namespace Dbout\WpOrm\Exceptions; -/** - * Class NotAllowedException - * @package Dbout\WpOrm\Exceptions - */ class NotAllowedException extends \Exception { - } diff --git a/src/Migration/Config.php b/src/Migration/Config.php index 8c4119d..a76108c 100644 --- a/src/Migration/Config.php +++ b/src/Migration/Config.php @@ -1,14 +1,15 @@ + */ namespace Dbout\WpOrm\Migration; -/** - * Class Config - * @package Dbout\WpOrm\Migration - */ class Config { - /** * @param array $userConfig * @return array @@ -30,8 +31,8 @@ public static function createPhinxConfig(array $userConfig = []): array 'user' => $userConfig['db_user'] ?? '', 'pass' => $userConfig['db_password'] ?? '', 'table_prefix' => $userConfig['table_prefix'] ?? '', - ] + ], ], ]; } -} \ No newline at end of file +} diff --git a/src/Models/Article.php b/src/Models/Article.php index ee16284..05f932e 100644 --- a/src/Models/Article.php +++ b/src/Models/Article.php @@ -1,16 +1,17 @@ + */ namespace Dbout\WpOrm\Models; -/** - * Class Article - * @package Dbout\WpOrm\Models - */ class Article extends CustomPost { - /** - * @var string + * @inheritDoc */ protected string $_type = 'post'; -} \ No newline at end of file +} diff --git a/src/Models/Attachment.php b/src/Models/Attachment.php index a69fb6b..60420ee 100644 --- a/src/Models/Attachment.php +++ b/src/Models/Attachment.php @@ -1,16 +1,17 @@ + */ namespace Dbout\WpOrm\Models; -/** - * Class Attachment - * @package Dbout\WpOrm\Models - */ class Attachment extends CustomPost { - /** - * @var string + * @inheritDoc */ protected string $_type = 'attachment'; -} \ No newline at end of file +} diff --git a/src/Models/Comment.php b/src/Models/Comment.php index ed9d50c..e34e2c1 100644 --- a/src/Models/Comment.php +++ b/src/Models/Comment.php @@ -1,4 +1,10 @@ + */ namespace Dbout\WpOrm\Models; @@ -8,9 +14,6 @@ use Illuminate\Database\Eloquent\Relations\HasOne; /** - * Class Comment - * @package Dbout\WpOrm\Models - * * @method static Comment|null find(int $commentId) * @method static CommentBuilder query() * @property User|null $user @@ -19,24 +22,23 @@ */ class Comment extends AbstractModel { - - const COMMENT_ID = 'comment_ID'; - const POST_ID = 'comment_post_ID'; - const AUTHOR = 'comment_author'; - const AUTHOR_EMAIL = 'comment_author_email'; - const AUTHOR_URL = 'comment_author_url'; - const AUTHOR_IP = 'comment_author_IP'; - const DATE = 'comment_date'; - const DATE_GMT = 'comment_date_gmt'; - const CONTENT = 'comment_content'; - const KARMA = 'comment_karma'; - const APPROVED = 'comment_approved'; - const AGENT = 'comment_agent'; - const TYPE = 'comment_type'; - const PARENT = 'comment_parent'; - const USER_ID = 'user_id'; - const CREATED_AT = self::DATE; - const UPDATED_AT = null; + public const COMMENT_ID = 'comment_ID'; + public const POST_ID = 'comment_post_ID'; + public const AUTHOR = 'comment_author'; + public const AUTHOR_EMAIL = 'comment_author_email'; + public const AUTHOR_URL = 'comment_author_url'; + public const AUTHOR_IP = 'comment_author_IP'; + public const DATE = 'comment_date'; + public const DATE_GMT = 'comment_date_gmt'; + public const CONTENT = 'comment_content'; + public const KARMA = 'comment_karma'; + public const APPROVED = 'comment_approved'; + public const AGENT = 'comment_agent'; + public const TYPE = 'comment_type'; + public const PARENT = 'comment_parent'; + public const USER_ID = 'user_id'; + public const CREATED_AT = self::DATE; + public const UPDATED_AT = null; /** * @var string @@ -277,4 +279,4 @@ public function newEloquentBuilder($query): CommentBuilder { return new CommentBuilder($query); } -} \ No newline at end of file +} diff --git a/src/Models/CustomComment.php b/src/Models/CustomComment.php index 570d18c..348067c 100644 --- a/src/Models/CustomComment.php +++ b/src/Models/CustomComment.php @@ -1,20 +1,18 @@ + */ namespace Dbout\WpOrm\Models; use Dbout\WpOrm\Models\Traits\HasCustomType; use Dbout\WpOrm\Scopes\CustomPostAddTypeScope; -/** - * Class CustomComment - * @package Dbout\WpOrm\Models - * - * @author Dimitri BOUTEILLE - * @copyright Copyright (c) 2021 - */ abstract class CustomComment extends Comment { - use HasCustomType; /** @@ -37,4 +35,4 @@ protected static function booted() { static::addGlobalScope(new CustomPostAddTypeScope()); } -} \ No newline at end of file +} diff --git a/src/Models/CustomPost.php b/src/Models/CustomPost.php index aea4b8e..0e4cca5 100644 --- a/src/Models/CustomPost.php +++ b/src/Models/CustomPost.php @@ -1,17 +1,18 @@ + */ namespace Dbout\WpOrm\Models; use Dbout\WpOrm\Models\Traits\HasCustomType; use Dbout\WpOrm\Scopes\CustomPostAddTypeScope; -/** - * Class CustomPost - * @package Dbout\WpOrm\Models - */ abstract class CustomPost extends Post { - use HasCustomType; /** @@ -34,4 +35,4 @@ protected static function booted() { static::addGlobalScope(new CustomPostAddTypeScope()); } -} \ No newline at end of file +} diff --git a/src/Models/Meta/AbstractMeta.php b/src/Models/Meta/AbstractMeta.php index 47cf012..85979b1 100644 --- a/src/Models/Meta/AbstractMeta.php +++ b/src/Models/Meta/AbstractMeta.php @@ -1,18 +1,19 @@ + */ namespace Dbout\WpOrm\Models\Meta; use Dbout\WpOrm\Orm\AbstractModel; -/** - * Class AbstractMeta - * @package Dbout\WpOrm\Models\Meta - */ abstract class AbstractMeta extends AbstractModel implements MetaInterface { - - const META_KEY = 'meta_key'; - const META_VALUE = 'meta_value'; + public const META_KEY = 'meta_key'; + public const META_VALUE = 'meta_value'; /** * Disable created_at and updated_at @@ -24,7 +25,7 @@ abstract class AbstractMeta extends AbstractModel implements MetaInterface * @var array */ protected $fillable = [ - self::META_VALUE, self::META_KEY + self::META_VALUE, self::META_KEY, ]; /** diff --git a/src/Models/Meta/MetaInterface.php b/src/Models/Meta/MetaInterface.php index 81cbee6..764e299 100644 --- a/src/Models/Meta/MetaInterface.php +++ b/src/Models/Meta/MetaInterface.php @@ -1,14 +1,15 @@ + */ namespace Dbout\WpOrm\Models\Meta; -/** - * Interface MetaInterface - * @package Dbout\WpOrm\Models\Meta - */ interface MetaInterface { - /** * @return string */ @@ -24,4 +25,4 @@ public function getKeyColumn(): string; * @return string */ public function getValueColumn(): string; -} \ No newline at end of file +} diff --git a/src/Models/Meta/PostMeta.php b/src/Models/Meta/PostMeta.php index e568e38..a5edcfa 100644 --- a/src/Models/Meta/PostMeta.php +++ b/src/Models/Meta/PostMeta.php @@ -1,4 +1,10 @@ + */ namespace Dbout\WpOrm\Models\Meta; @@ -6,17 +12,13 @@ use Illuminate\Database\Eloquent\Relations\HasOne; /** - * Class PostMeta - * @package Dbout\WpOrm\Models\Meta - * * @method static PostMeta find(int $metaId); * @property Post|null $post */ class PostMeta extends AbstractMeta { - - const META_ID = 'meta_id'; - const POST_ID = 'post_id'; + public const META_ID = 'meta_id'; + public const POST_ID = 'post_id'; /** * @var string diff --git a/src/Models/Meta/UserMeta.php b/src/Models/Meta/UserMeta.php index 5a803aa..d20e046 100644 --- a/src/Models/Meta/UserMeta.php +++ b/src/Models/Meta/UserMeta.php @@ -1,4 +1,10 @@ + */ namespace Dbout\WpOrm\Models\Meta; @@ -6,17 +12,13 @@ use Illuminate\Database\Eloquent\Relations\HasOne; /** - * Class UserMeta - * @package Dbout\WpOrm\Models\Meta - * * @method static UserMeta find(int $metaId); * @property User|null $user */ class UserMeta extends AbstractMeta { - - const META_ID = 'umeta_id'; - const USER_ID = 'user_id'; + public const META_ID = 'umeta_id'; + public const USER_ID = 'user_id'; /** * @var string diff --git a/src/Models/Meta/WithMeta.php b/src/Models/Meta/WithMeta.php index 2aa9ed1..a637e06 100644 --- a/src/Models/Meta/WithMeta.php +++ b/src/Models/Meta/WithMeta.php @@ -1,17 +1,18 @@ + */ namespace Dbout\WpOrm\Models\Meta; use Dbout\WpOrm\Exceptions\MetaNotSupportedException; use Illuminate\Database\Eloquent\Relations\HasMany; -/** - * Trait WithMeta - * @package Dbout\WpOrm\Models\Meta - */ trait WithMeta { - /** * @var AbstractMeta|null */ @@ -27,7 +28,7 @@ trait WithMeta */ protected static function bootWithMeta() { - static::saved(function($model) { + static::saved(function ($model) { $model->saveTmpMetas(); }); } @@ -112,11 +113,11 @@ public function setMeta(string $metaKey, $value): ?AbstractMeta $instance = $this->metas() ->firstOrNew([ - $this->metaModel->getKeyColumn() => $metaKey + $this->metaModel->getKeyColumn() => $metaKey, ]); $instance->fill([ - $this->metaModel->getValueColumn() => $value + $this->metaModel->getValueColumn() => $value, ])->save(); return $instance; @@ -154,4 +155,4 @@ protected function saveTmpMetas(): void $this->_tmpMetas = []; } -} \ No newline at end of file +} diff --git a/src/Models/Option.php b/src/Models/Option.php index f3c3b78..ebbfe3c 100644 --- a/src/Models/Option.php +++ b/src/Models/Option.php @@ -1,4 +1,10 @@ + */ namespace Dbout\WpOrm\Models; @@ -6,9 +12,6 @@ use Dbout\WpOrm\Orm\AbstractModel; /** - * Class Option - * @package Dbout\WpOrm\Models - * * @method static Option|null find($optionId) * @method static OptionBuilder query() * @@ -21,11 +24,10 @@ */ class Option extends AbstractModel { - - const OPTION_ID = 'option_id'; - const NAME = 'option_name'; - const VALUE = 'option_value'; - const AUTOLOAD = 'autoload'; + public const OPTION_ID = 'option_id'; + public const NAME = 'option_name'; + public const VALUE = 'option_value'; + public const AUTOLOAD = 'autoload'; /** * @var string diff --git a/src/Models/Page.php b/src/Models/Page.php index 1733e76..72a32f9 100644 --- a/src/Models/Page.php +++ b/src/Models/Page.php @@ -1,14 +1,15 @@ + */ namespace Dbout\WpOrm\Models; -/** - * Class Page - * @package Dbout\WpOrm\Models - */ class Page extends CustomPost { - /** * @var string */ diff --git a/src/Models/Post.php b/src/Models/Post.php index 0bec797..6a3de22 100644 --- a/src/Models/Post.php +++ b/src/Models/Post.php @@ -1,4 +1,10 @@ + */ namespace Dbout\WpOrm\Models; @@ -11,9 +17,6 @@ use Illuminate\Database\Eloquent\Relations\HasOne; /** - * Class Post - * @package Dbout\WpOrm\Models - * * @method static Post find(int $postId) * @method static PostBuilder query() * @property User|null $author @@ -61,34 +64,33 @@ */ class Post extends AbstractModel { - use WithMeta; - const CREATED_AT = 'post_date'; - const UPDATED_AT = 'post_modified'; - const POST_ID = 'ID'; - const AUTHOR = 'post_author'; - const DATE = 'post_date'; - const DATE_GMT = 'post_date_gmt'; - const CONTENT = 'post_content'; - const TITLE = 'post_title'; - const EXCERPT = 'post_excerpt'; - const COMMENT_STATUS = 'comment_status'; - const STATUS = 'post_status'; - const PING_STATUS = 'ping_status'; - const PASSWORD = 'post_password'; - const POST_NAME = 'post_name'; - const TO_PING = 'to_ping'; - const PINGED = 'pinged'; - const MODIFIED = 'post_modified'; - const MODIFIED_GMT = 'post_modified_gmt'; - const CONTENT_FILTERED = 'post_content_filtered'; - const PARENT = 'post_parent'; - const GUID = 'guid'; - const MENU_ORDER = 'menu_order'; - const TYPE = 'post_type'; - const MIME_TYPE = 'post_mime_type'; - const COMMENT_COUNT = 'comment_count'; + public const CREATED_AT = 'post_date'; + public const UPDATED_AT = 'post_modified'; + public const POST_ID = 'ID'; + public const AUTHOR = 'post_author'; + public const DATE = 'post_date'; + public const DATE_GMT = 'post_date_gmt'; + public const CONTENT = 'post_content'; + public const TITLE = 'post_title'; + public const EXCERPT = 'post_excerpt'; + public const COMMENT_STATUS = 'comment_status'; + public const STATUS = 'post_status'; + public const PING_STATUS = 'ping_status'; + public const PASSWORD = 'post_password'; + public const POST_NAME = 'post_name'; + public const TO_PING = 'to_ping'; + public const PINGED = 'pinged'; + public const MODIFIED = 'post_modified'; + public const MODIFIED_GMT = 'post_modified_gmt'; + public const CONTENT_FILTERED = 'post_content_filtered'; + public const PARENT = 'post_parent'; + public const GUID = 'guid'; + public const MENU_ORDER = 'menu_order'; + public const TYPE = 'post_type'; + public const MIME_TYPE = 'post_mime_type'; + public const COMMENT_COUNT = 'comment_count'; /** * @var string diff --git a/src/Models/Term.php b/src/Models/Term.php index c140c48..8d4ca82 100644 --- a/src/Models/Term.php +++ b/src/Models/Term.php @@ -1,4 +1,10 @@ + */ namespace Dbout\WpOrm\Models; @@ -7,9 +13,6 @@ use Illuminate\Database\Eloquent\Relations\HasOne; /** - * Class Term - * @package Dbout\WpOrm\Models - * * @method static self find(int $termId) * @method static TermBuilder query() * @@ -24,11 +27,10 @@ */ class Term extends AbstractModel { - - const TERM_ID = 'term_id'; - const NAME = 'name'; - const SLUG = 'slug'; - const TERM_GROUP = 'term_group'; + public const TERM_ID = 'term_id'; + public const NAME = 'name'; + public const SLUG = 'slug'; + public const TERM_GROUP = 'term_group'; /** * @var string @@ -75,4 +77,4 @@ public function newEloquentBuilder($query): TermBuilder { return new TermBuilder($query); } -} \ No newline at end of file +} diff --git a/src/Models/TermRelationship.php b/src/Models/TermRelationship.php index 0bd6e31..46d437d 100644 --- a/src/Models/TermRelationship.php +++ b/src/Models/TermRelationship.php @@ -1,13 +1,16 @@ + */ namespace Dbout\WpOrm\Models; use Dbout\WpOrm\Orm\AbstractModel; /** - * Class TermRelationship - * @package Dbout\WpOrm\Models - * * @method int|null getTermOrder() * @method self setTermOrder(?int $order) * @method int|null getTermTaxonomyId() @@ -17,10 +20,9 @@ */ class TermRelationship extends AbstractModel { - - const OBJECT_ID = 'object_id'; - const TERM_TAXONOMY_ID = 'term_taxonomy_id'; - const TERM_ORDER = 'term_order'; + public const OBJECT_ID = 'object_id'; + public const TERM_TAXONOMY_ID = 'term_taxonomy_id'; + public const TERM_ORDER = 'term_order'; /** * @var string @@ -39,4 +41,4 @@ class TermRelationship extends AbstractModel self::TERM_ORDER => 'integer', self::TERM_TAXONOMY_ID => 'integer', ]; -} \ No newline at end of file +} diff --git a/src/Models/TermTaxonomy.php b/src/Models/TermTaxonomy.php index 21b6ee8..fd9b3f1 100644 --- a/src/Models/TermTaxonomy.php +++ b/src/Models/TermTaxonomy.php @@ -1,13 +1,16 @@ + */ namespace Dbout\WpOrm\Models; use Dbout\WpOrm\Orm\AbstractModel; /** - * Class TermTaxonomy - * @package Dbout\WpOrm\Models - * * @method static TermTaxonomy|null find(int $id) * @method int|null getTermId() * @method self setTermId(int $id) @@ -22,13 +25,12 @@ */ class TermTaxonomy extends AbstractModel { - - const TERM_TAXONOMY_ID = 'term_taxonomy_id'; - const TERM_ID = 'term_id'; - const TAXONOMY = 'taxonomy'; - const DESCRIPTION = 'description'; - const PARENT = 'parent'; - const COUNT = 'count'; + public const TERM_TAXONOMY_ID = 'term_taxonomy_id'; + public const TERM_ID = 'term_id'; + public const TAXONOMY = 'taxonomy'; + public const DESCRIPTION = 'description'; + public const PARENT = 'parent'; + public const COUNT = 'count'; /** * @var bool @@ -56,6 +58,6 @@ class TermTaxonomy extends AbstractModel * @var string[] */ protected $fillable = [ - self::TERM_TAXONOMY_ID, self::TERM_ID, self::TAXONOMY, self::DESCRIPTION, self::PARENT, self::COUNT + self::TERM_TAXONOMY_ID, self::TERM_ID, self::TAXONOMY, self::DESCRIPTION, self::PARENT, self::COUNT, ]; -} \ No newline at end of file +} diff --git a/src/Models/Traits/HasCustomType.php b/src/Models/Traits/HasCustomType.php index 57e5e4f..c99a590 100644 --- a/src/Models/Traits/HasCustomType.php +++ b/src/Models/Traits/HasCustomType.php @@ -1,16 +1,17 @@ + */ namespace Dbout\WpOrm\Models\Traits; use Dbout\WpOrm\Exceptions\NotAllowedException; -/** - * Trait HasCustomType - * @package Dbout\WpOrm\Models\Traits - */ trait HasCustomType { - /** * @var string */ @@ -28,10 +29,10 @@ public function getPostType(): ?string * @param string $postType * @throws NotAllowedException */ - public final function setPostType(string $postType): void + final public function setPostType(string $postType): void { throw new NotAllowedException(sprintf( - "You cannot set a type for this object. Current type [%s]", + 'You cannot set a type for this object. Current type [%s]', $this->_type )); } diff --git a/src/Models/User.php b/src/Models/User.php index d6ddfbf..06b7073 100644 --- a/src/Models/User.php +++ b/src/Models/User.php @@ -1,4 +1,10 @@ + */ namespace Dbout\WpOrm\Models; @@ -10,9 +16,6 @@ use Illuminate\Database\Eloquent\Relations\HasMany; /** - * Class User - * @package Dbout\WpOrm\Models - * * @method static User|null find($userId) * @method static UserBuilder query() * @property UserMeta[] $metas @@ -41,21 +44,20 @@ */ class User extends AbstractModel { - use WithMeta; - const USER_ID = 'ID'; - const LOGIN = 'user_login'; - const PASSWORD = 'user_pass'; - const NICE_NAME = 'user_nicename'; - const EMAIL = 'user_email'; - const URL = 'user_url'; - const REGISTERED = 'user_registered'; - const ACTIVATION_KEY = 'user_activation_key'; - const DISPLAY_NAME = 'display_name'; - const STATUS = 'user_status'; - const CREATED_AT = 'user_registered'; - const UPDATED_AT = null; + public const USER_ID = 'ID'; + public const LOGIN = 'user_login'; + public const PASSWORD = 'user_pass'; + public const NICE_NAME = 'user_nicename'; + public const EMAIL = 'user_email'; + public const URL = 'user_url'; + public const REGISTERED = 'user_registered'; + public const ACTIVATION_KEY = 'user_activation_key'; + public const DISPLAY_NAME = 'display_name'; + public const STATUS = 'user_status'; + public const CREATED_AT = 'user_registered'; + public const UPDATED_AT = null; /** * @var string diff --git a/src/Orm/AbstractModel.php b/src/Orm/AbstractModel.php index 23b18d6..fda4b75 100644 --- a/src/Orm/AbstractModel.php +++ b/src/Orm/AbstractModel.php @@ -1,17 +1,18 @@ + */ namespace Dbout\WpOrm\Orm; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Str; -/** - * Class AbstractModel - * @package Dbout\WpOrm\Orm - */ abstract class AbstractModel extends Model { - /** * AbstractModel constructor. * @param array $attributes @@ -29,7 +30,9 @@ protected function newBaseQueryBuilder() { $connection = $this->getConnection(); return new Builder( - $connection, $connection->getQueryGrammar(), $connection->getPostProcessor() + $connection, + $connection->getQueryGrammar(), + $connection->getPostProcessor() ); } @@ -50,7 +53,7 @@ public function getConnection() public function getTable(): string { $prefix = $this->getConnection()->getTablePrefix(); - + if (!empty($this->table)) { // Ajoute plusieurs fois le suffix, va savoir pourquoi ... // @todo Corriger le bug ci dessus diff --git a/src/Orm/Builder.php b/src/Orm/Builder.php index b77d726..c8f41c5 100644 --- a/src/Orm/Builder.php +++ b/src/Orm/Builder.php @@ -1,14 +1,17 @@ + */ + namespace Dbout\WpOrm\Orm; use Illuminate\Database\Query\Builder as EloquentBuilder; -/** - * Class Builder - * @package Dbout\WpOrm\Orm - */ -class Builder extends EloquentBuilder { - +class Builder extends EloquentBuilder +{ /** * Add an exists clause to the query. * @@ -17,8 +20,9 @@ class Builder extends EloquentBuilder { * @param bool $not * @return $this */ - public function addWhereExistsQuery(EloquentBuilder $query, $boolean = 'and', $not = false) { - + public function addWhereExistsQuery(EloquentBuilder $query, $boolean = 'and', $not = false) + { + $type = $not ? 'NotExists' : 'Exists'; $this->wheres[] = compact('type', 'query', 'boolean'); diff --git a/src/Orm/Database.php b/src/Orm/Database.php index 3ad9540..3660dfe 100644 --- a/src/Orm/Database.php +++ b/src/Orm/Database.php @@ -1,10 +1,17 @@ + */ + namespace Dbout\WpOrm\Orm; use Illuminate\Database\ConnectionInterface; +use Illuminate\Database\Query\Expression; use Illuminate\Database\Query\Grammars\Grammar; use Illuminate\Database\Query\Processors\Processor; -use Illuminate\Database\Query\Expression; use Illuminate\Database\QueryException; use Illuminate\Support\Arr; @@ -14,7 +21,6 @@ */ class Database implements ConnectionInterface { - /** * @var \wpdb */ @@ -125,17 +131,19 @@ public function raw($value) return new Expression($value); } - /** - * Get a new query builder instance. - * - * @return \Illuminate\Database\Query\Builder - */ - public function query() - { - return new Builder( - $this, $this->getQueryGrammar(), $this->getPostProcessor() - ); - } + /** + * Get a new query builder instance. + * + * @return \Illuminate\Database\Query\Builder + */ + public function query() + { + return new Builder( + $this, + $this->getQueryGrammar(), + $this->getPostProcessor() + ); + } /** * Run a select statement and return a single result @@ -149,8 +157,9 @@ public function selectOne($query, $bindings = [], $useReadPdo = true) { $query = $this->bind_params($query, $bindings); $result = $this->db->get_row($query); - if ($result === false || $this->db->last_error) + if ($result === false || $this->db->last_error) { throw new QueryException($query, $bindings, new \Exception($this->db->last_error)); + } return $result; } @@ -215,7 +224,7 @@ private function bind_params($query, $bindings, $update = false) return $replace; }, $bindings); - $query = \str_replace(array('%', '?'), array('%%', '%s'), $query); + $query = \str_replace(['%', '?'], ['%%', '%s'], $query); $query = \vsprintf($query, $bindings); return $query; @@ -230,7 +239,7 @@ private function bind_params($query, $bindings, $update = false) * * @return array */ - public function bind_and_run($query, $bindings = array()) + public function bind_and_run($query, $bindings = []) { $new_query = $this->bind_params($query, $bindings); $result = $this->db->query($new_query); @@ -256,7 +265,7 @@ public function insert($query, $bindings = []) * @param array $bindings * @return int */ - public function update($query, $bindings = array()) + public function update($query, $bindings = []) { return $this->affectingStatement($query, $bindings); } @@ -266,7 +275,7 @@ public function update($query, $bindings = array()) * @param array $bindings * @return int */ - public function delete($query, $bindings = array()) + public function delete($query, $bindings = []) { return $this->affectingStatement($query, $bindings); } @@ -276,7 +285,7 @@ public function delete($query, $bindings = array()) * @param array $bindings * @return bool */ - public function statement($query, $bindings = array()) + public function statement($query, $bindings = []) { $newQuery = $this->bind_params($query, $bindings, true); return $this->unprepared($newQuery); @@ -287,13 +296,14 @@ public function statement($query, $bindings = array()) * @param array $bindings * @return int */ - public function affectingStatement($query, $bindings = array()) + public function affectingStatement($query, $bindings = []) { $new_query = $this->bind_params($query, $bindings, true); $result = $this->db->query($new_query); - if ($result === false || $this->db->last_error) + if ($result === false || $this->db->last_error) { throw new QueryException($new_query, $bindings, new \Exception($this->db->last_error)); + } return \intval($result); } @@ -336,8 +346,8 @@ public function prepareBindings(array $bindings) /** * @param \Closure $callback * @param int $attempts - * @return mixed * @throws \Exception + * @return mixed */ public function transaction(\Closure $callback, $attempts = 1) { @@ -346,7 +356,7 @@ public function transaction(\Closure $callback, $attempts = 1) $data = $callback(); $this->commit(); return $data; - } catch (\Exception $e){ + } catch (\Exception $e) { $this->rollBack(); throw $e; } diff --git a/src/Orm/Resolver.php b/src/Orm/Resolver.php index e195d2b..9107bf4 100644 --- a/src/Orm/Resolver.php +++ b/src/Orm/Resolver.php @@ -1,18 +1,19 @@ + */ + namespace Dbout\WpOrm\Orm; use Illuminate\Database\ConnectionResolverInterface; -/** - * Class Resolver - * @package Dbout\WpOrm\Orm - */ class Resolver implements ConnectionResolverInterface { - /** - * @param null $name - * @return Database|\Illuminate\Database\ConnectionInterface|null + * @inheritDoc */ public function connection($name = null) { @@ -20,16 +21,16 @@ public function connection($name = null) } /** - * @return string|void + * @inheritDoc */ public function getDefaultConnection() { } /** - * @param string $name + * @inheritDoc */ public function setDefaultConnection($name) { } -} \ No newline at end of file +} diff --git a/src/Scopes/CustomPostAddTypeScope.php b/src/Scopes/CustomPostAddTypeScope.php index 985f16a..15017c1 100644 --- a/src/Scopes/CustomPostAddTypeScope.php +++ b/src/Scopes/CustomPostAddTypeScope.php @@ -1,4 +1,10 @@ + */ namespace Dbout\WpOrm\Scopes; @@ -7,16 +13,10 @@ use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Scope; -/** - * Class CustomPostAddTypeScope - * @package Dbout\WpOrm\Scopes - */ class CustomPostAddTypeScope implements Scope { - /** - * @param Builder $builder - * @param Model $model + * @inheritDoc */ public function apply(Builder $builder, Model $model) { diff --git a/src/includes/migrations.php b/src/includes/migrations.php index b8be2b0..8fa589b 100644 --- a/src/includes/migrations.php +++ b/src/includes/migrations.php @@ -1,4 +1,10 @@ + */ if (!function_exists('wp_orm_get_phinx_config')) { @@ -10,4 +16,4 @@ function wp_orm_get_phinx_config(array $config = []): array { return \Dbout\WpOrm\Migration\Config::createPhinxConfig($config); } -} \ No newline at end of file +} From 799de0ab5871893e563ed5ce37f67dfe1044f464 Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Mon, 25 Sep 2023 22:24:20 +0200 Subject: [PATCH 02/67] #6 Add PingStatus & PostStatus --- src/Providers/PingStatus.php | 15 +++++++++++++++ src/Providers/PostStatus.php | 24 ++++++++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 src/Providers/PingStatus.php create mode 100644 src/Providers/PostStatus.php diff --git a/src/Providers/PingStatus.php b/src/Providers/PingStatus.php new file mode 100644 index 0000000..0790c2d --- /dev/null +++ b/src/Providers/PingStatus.php @@ -0,0 +1,15 @@ + + */ + +namespace Dbout\WpOrm\Providers; + +enum PingStatus: string +{ + case Closed = 'closed'; + case Open = 'open'; +} diff --git a/src/Providers/PostStatus.php b/src/Providers/PostStatus.php new file mode 100644 index 0000000..91672b8 --- /dev/null +++ b/src/Providers/PostStatus.php @@ -0,0 +1,24 @@ + + */ + +namespace Dbout\WpOrm\Providers; + +/** + * @see https://wordpress.org/documentation/article/post-status/ + */ +enum PostStatus: string +{ + case Publish = 'publish'; + case Future = 'future'; + case Draft = 'draft'; + case Pending = 'pending'; + case Private = 'private'; + case Trash = 'trash'; + case AutoDraft = 'auto-draft'; + case Inherit = 'inherit'; +} From e4aeda33bbbb8bc2a90dba5de0cc1f465f750078 Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Tue, 26 Sep 2023 22:10:24 +0200 Subject: [PATCH 03/67] #6 Add phpStan --- LICENSE | 2 +- Makefile | 7 +++++-- composer.json | 4 +++- phpstan.neon | 6 ++++++ src/Builders/Traits/WithMeta.php | 3 ++- src/Orm/AbstractModel.php | 14 +++++--------- src/Orm/Database.php | 4 ---- src/Orm/Resolver.php | 12 ++++++++++-- src/Scopes/CustomPostAddTypeScope.php | 2 ++ 9 files changed, 34 insertions(+), 20 deletions(-) create mode 100644 phpstan.neon diff --git a/LICENSE b/LICENSE index 9d191cb..1b50134 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2020 Dimitri BOUTEILLE +Copyright (c) 2023 Dimitri BOUTEILLE Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Makefile b/Makefile index 2583a87..f33cad9 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,8 @@ -.PHONY: csFixer +.PHONY: csFixer runPHPStan # Fix CS fixer csFixer: - php vendor/bin/php-cs-fixer fix \ No newline at end of file + php vendor/bin/php-cs-fixer fix + +runPHPStan: + vendor/bin/phpstan analyse -c phpstan.neon \ No newline at end of file diff --git a/composer.json b/composer.json index 7ef9f18..3f379f0 100644 --- a/composer.json +++ b/composer.json @@ -3,6 +3,7 @@ "description": "Wordpress ORM with Eloquent and Phinx", "type": "package", "license": "GPL-2.0-or-later", + "version": "3.0.0", "authors": [ { "name": "Dimitri BOUTEILLE", @@ -35,6 +36,7 @@ } }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.28" + "friendsofphp/php-cs-fixer": "^3.28", + "phpstan/phpstan": "^1.10" } } diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..1580cc6 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,6 @@ +parameters: + level: 2 + paths: + - src + excludePaths: + - src/Orm/Database.php diff --git a/src/Builders/Traits/WithMeta.php b/src/Builders/Traits/WithMeta.php index 0e5712f..2d9b612 100644 --- a/src/Builders/Traits/WithMeta.php +++ b/src/Builders/Traits/WithMeta.php @@ -91,12 +91,13 @@ public function setModel(Model $model) $traits = class_uses_recursive(get_class($model)); if (!in_array(\Dbout\WpOrm\Models\Meta\WithMeta::class, $traits, true)) { throw new MetaNotSupportedException(sprintf( - "Model %s must be use trait %s", + 'Model %s must be use trait %s', get_class($model), \Dbout\WpOrm\Models\Meta\WithMeta::class )); } + /** @var \Dbout\WpOrm\Models\Meta\WithMeta $model */ $metaClass = $model->getMetaClass(); $object = (new \ReflectionClass($metaClass)); $this->metaModel = $object->newInstanceWithoutConstructor(); diff --git a/src/Orm/AbstractModel.php b/src/Orm/AbstractModel.php index fda4b75..94e5e3d 100644 --- a/src/Orm/AbstractModel.php +++ b/src/Orm/AbstractModel.php @@ -37,7 +37,7 @@ protected function newBaseQueryBuilder() } /** - * @return Database|null + * @inheritDoc */ public function getConnection() { @@ -46,7 +46,7 @@ public function getConnection() /** * Get table name associated with the model - * Add wordpress table prefix + * Add WordPress table prefix * * @return string */ @@ -57,13 +57,13 @@ public function getTable(): string if (!empty($this->table)) { // Ajoute plusieurs fois le suffix, va savoir pourquoi ... // @todo Corriger le bug ci dessus - return \substr($this->table, 0, strlen($prefix)) === $prefix ? $this->table : $prefix . $this->table; + return str_starts_with($this->table, $prefix) ? $this->table : $prefix . $this->table; } $table = \substr(\strrchr(\get_class($this), "\\"), 1); $table = Str::snake(Str::plural($table)); - // Add wordpress table prefix + // Add WordPress table prefix return $prefix . $table; } @@ -86,9 +86,7 @@ public static function table(): string } /** - * @param string $method - * @param array $parameters - * @return $this|mixed + * @inheritDoc */ public function __call($method, $parameters) { @@ -99,8 +97,6 @@ public function __call($method, $parameters) $type = $matchGetter[1]; $attribute = $matchGetter[2]; - - // to pascal case $attribute = strtolower(preg_replace('/(?default ?? ''; } /** * @inheritDoc */ - public function setDefaultConnection($name) + public function setDefaultConnection($name): void { + $this->default = $name; } } diff --git a/src/Scopes/CustomPostAddTypeScope.php b/src/Scopes/CustomPostAddTypeScope.php index 15017c1..07135f8 100644 --- a/src/Scopes/CustomPostAddTypeScope.php +++ b/src/Scopes/CustomPostAddTypeScope.php @@ -8,6 +8,7 @@ namespace Dbout\WpOrm\Scopes; +use Dbout\WpOrm\Builders\PostBuilder; use Dbout\WpOrm\Models\CustomPost; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; @@ -16,6 +17,7 @@ class CustomPostAddTypeScope implements Scope { /** + * @param PostBuilder $builder * @inheritDoc */ public function apply(Builder $builder, Model $model) From 7988eda08a66676c93b1fedd9777a2e918cf48ff Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Tue, 26 Sep 2023 22:32:35 +0200 Subject: [PATCH 04/67] #6 Add rector, start API models support --- Makefile | 1 + composer.json | 3 +- src/Api/CommentInterface.php | 28 +++++++++++ src/Api/OptionInterface.php | 25 ++++++++++ src/Api/PostInterface.php | 80 +++++++++++++++++++++++++++++++ src/Api/UserInterface.php | 48 +++++++++++++++++++ src/Builders/OptionBuilder.php | 7 ++- src/Models/Comment.php | 22 ++------- src/Models/Option.php | 27 ++++------- src/Models/Post.php | 88 +++++----------------------------- src/Models/User.php | 56 ++++------------------ src/Orm/Builder.php | 2 - 12 files changed, 223 insertions(+), 164 deletions(-) create mode 100644 src/Api/CommentInterface.php create mode 100644 src/Api/OptionInterface.php create mode 100644 src/Api/PostInterface.php create mode 100644 src/Api/UserInterface.php diff --git a/Makefile b/Makefile index f33cad9..4f4d14b 100644 --- a/Makefile +++ b/Makefile @@ -4,5 +4,6 @@ csFixer: php vendor/bin/php-cs-fixer fix +# Run phpStan check runPHPStan: vendor/bin/phpstan analyse -c phpstan.neon \ No newline at end of file diff --git a/composer.json b/composer.json index 3f379f0..4506817 100644 --- a/composer.json +++ b/composer.json @@ -37,6 +37,7 @@ }, "require-dev": { "friendsofphp/php-cs-fixer": "^3.28", - "phpstan/phpstan": "^1.10" + "phpstan/phpstan": "^1.10", + "rector/rector": "^0.18.4" } } diff --git a/src/Api/CommentInterface.php b/src/Api/CommentInterface.php new file mode 100644 index 0000000..8e610f5 --- /dev/null +++ b/src/Api/CommentInterface.php @@ -0,0 +1,28 @@ + + */ + +namespace Dbout\WpOrm\Api; + +interface CommentInterface +{ + public const COMMENT_ID = 'comment_ID'; + public const POST_ID = 'comment_post_ID'; + public const AUTHOR = 'comment_author'; + public const AUTHOR_EMAIL = 'comment_author_email'; + public const AUTHOR_URL = 'comment_author_url'; + public const AUTHOR_IP = 'comment_author_IP'; + public const DATE = 'comment_date'; + public const DATE_GMT = 'comment_date_gmt'; + public const CONTENT = 'comment_content'; + public const KARMA = 'comment_karma'; + public const APPROVED = 'comment_approved'; + public const AGENT = 'comment_agent'; + public const TYPE = 'comment_type'; + public const PARENT = 'comment_parent'; + public const USER_ID = 'user_id'; +} diff --git a/src/Api/OptionInterface.php b/src/Api/OptionInterface.php new file mode 100644 index 0000000..4dbeba0 --- /dev/null +++ b/src/Api/OptionInterface.php @@ -0,0 +1,25 @@ + + */ + +namespace Dbout\WpOrm\Api; + +/** + * @method self setOptionName(string $name) + * @method string getOptionName() + * @method self setOptionValue($value) + * @method mixed getOptionValue() + * @method self setAutoload(string $autoload) + * @method string getAutoload() + */ +interface OptionInterface +{ + public const OPTION_ID = 'option_id'; + public const NAME = 'option_name'; + public const VALUE = 'option_value'; + public const AUTOLOAD = 'autoload'; +} diff --git a/src/Api/PostInterface.php b/src/Api/PostInterface.php new file mode 100644 index 0000000..307af88 --- /dev/null +++ b/src/Api/PostInterface.php @@ -0,0 +1,80 @@ + + */ + +namespace Dbout\WpOrm\Api; + +use Carbon\Carbon; + +/** + * @method self setPostDate($date) + * @method Carbon|null getPostDate() + * @method self setPostDateGMT($date) + * @method Carbon|null getPostDateGMT() + * @method self setPostContent(?string $content) + * @method string|null getPostContent() + * @method self setPostType(string $type) + * @method string|null getPostType() + * @method self setGuid(?string $guid) + * @method string|null getGuid() + * @method self setPostTitle(?string $title) + * @method string|null getPostTitle() + * @method self setPostExcerpt(?string $excerpt) + * @method string|null getPostExcerpt() + * @method self setPostStatus(?string $status) + * @method string|null getPostStatus() + * @method self setCommentStatus(string $status) + * @method string|null getCommentStatus() + * @method self setPingStatus(string $status) + * @method string|null getPingStatus() + * @method self setPostPassword(?string $password) + * @method string|null getPostPassword() + * @method self setPostName(?string $name) + * @method string|null getPostName() + * @method self setToPing(?string $toPing) + * @method string|null getToPing() + * @method self setPinged(?string $pinged) + * @method string|null getPinged() + * @method self setPostModified($modified) + * @method Carbon|null getPostModified() + * @method self setPostModifiedGMT($modified) + * @method Carbon|null getPostModifiedGMT() + * @method setPostMimeType(?string $mimeType) + * @method string|null getPostMimeType() + * @method self setMenuOrder(?int $order) + * @method int|null getMenuOrder() + * @method self setPostContentFiltered($content) + * @method string|null getPostContentFiltered() + */ +interface PostInterface +{ + public const CREATED_AT = 'post_date'; + public const UPDATED_AT = 'post_modified'; + public const POST_ID = 'ID'; + public const AUTHOR = 'post_author'; + public const DATE = 'post_date'; + public const DATE_GMT = 'post_date_gmt'; + public const CONTENT = 'post_content'; + public const TITLE = 'post_title'; + public const EXCERPT = 'post_excerpt'; + public const COMMENT_STATUS = 'comment_status'; + public const STATUS = 'post_status'; + public const PING_STATUS = 'ping_status'; + public const PASSWORD = 'post_password'; + public const POST_NAME = 'post_name'; + public const TO_PING = 'to_ping'; + public const PINGED = 'pinged'; + public const MODIFIED = 'post_modified'; + public const MODIFIED_GMT = 'post_modified_gmt'; + public const CONTENT_FILTERED = 'post_content_filtered'; + public const PARENT = 'post_parent'; + public const GUID = 'guid'; + public const MENU_ORDER = 'menu_order'; + public const TYPE = 'post_type'; + public const MIME_TYPE = 'post_mime_type'; + public const COMMENT_COUNT = 'comment_count'; +} diff --git a/src/Api/UserInterface.php b/src/Api/UserInterface.php new file mode 100644 index 0000000..8ed2eb3 --- /dev/null +++ b/src/Api/UserInterface.php @@ -0,0 +1,48 @@ + + */ + +namespace Dbout\WpOrm\Api; + +use Carbon\Carbon; + +/** + * @method string|null getUserLogin() + * @method self setUserLogin(string $login) + * @method string|null getUserPass() + * @method self setUserPass(string $password) + * @method string|null getUserNicename() + * @method self setUserNicename(string $nicename) + * @method string|null getUserEmail() + * @method self setUserEmail(string $email) + * @method string|null getUserUrl() + * @method self setUserUrl(?string $url) + * @method Carbon|null getUserRegistered() + * @method self setUserRegistered($date) + * @method string|null getUserActivationKey() + * @method self setUserActivationKey(?string $key) + * @method int getUserStatus() + * @method self setUserStatus(int $status) + * @method string|null getDisplayName() + * @method self setDisplayName(?string $name) + */ +interface UserInterface +{ + public const USER_ID = 'ID'; + public const LOGIN = 'user_login'; + public const PASSWORD = 'user_pass'; + public const NICE_NAME = 'user_nicename'; + public const EMAIL = 'user_email'; + public const URL = 'user_url'; + public const REGISTERED = 'user_registered'; + public const ACTIVATION_KEY = 'user_activation_key'; + public const DISPLAY_NAME = 'display_name'; + public const STATUS = 'user_status'; + public const CREATED_AT = 'user_registered'; + public const UPDATED_AT = null; + +} diff --git a/src/Builders/OptionBuilder.php b/src/Builders/OptionBuilder.php index 6fe0384..2c2d1e0 100644 --- a/src/Builders/OptionBuilder.php +++ b/src/Builders/OptionBuilder.php @@ -8,6 +8,7 @@ namespace Dbout\WpOrm\Builders; +use Dbout\WpOrm\Api\OptionInterface; use Dbout\WpOrm\Models\Option; class OptionBuilder extends AbstractBuilder @@ -18,7 +19,9 @@ class OptionBuilder extends AbstractBuilder */ public function findOneByName(string $optionName): ?Option { - return $this->firstWhere(Option::NAME, $optionName); + /** @var Option|null $model */ + $model = $this->firstWhere(OptionInterface::NAME, $optionName); + return $model; } /** @@ -27,6 +30,6 @@ public function findOneByName(string $optionName): ?Option */ public function whereName(string $optionName): self { - return $this->where(Option::NAME, $optionName); + return $this->where(OptionInterface::NAME, $optionName); } } diff --git a/src/Models/Comment.php b/src/Models/Comment.php index e34e2c1..79f523e 100644 --- a/src/Models/Comment.php +++ b/src/Models/Comment.php @@ -9,6 +9,7 @@ namespace Dbout\WpOrm\Models; use Carbon\Carbon; +use Dbout\WpOrm\Api\CommentInterface; use Dbout\WpOrm\Builders\CommentBuilder; use Dbout\WpOrm\Orm\AbstractModel; use Illuminate\Database\Eloquent\Relations\HasOne; @@ -20,33 +21,18 @@ * @property Post|null $post * @property Comment|null $parent */ -class Comment extends AbstractModel +class Comment extends AbstractModel implements CommentInterface { - public const COMMENT_ID = 'comment_ID'; - public const POST_ID = 'comment_post_ID'; - public const AUTHOR = 'comment_author'; - public const AUTHOR_EMAIL = 'comment_author_email'; - public const AUTHOR_URL = 'comment_author_url'; - public const AUTHOR_IP = 'comment_author_IP'; - public const DATE = 'comment_date'; - public const DATE_GMT = 'comment_date_gmt'; - public const CONTENT = 'comment_content'; - public const KARMA = 'comment_karma'; - public const APPROVED = 'comment_approved'; - public const AGENT = 'comment_agent'; - public const TYPE = 'comment_type'; - public const PARENT = 'comment_parent'; - public const USER_ID = 'user_id'; public const CREATED_AT = self::DATE; public const UPDATED_AT = null; /** - * @var string + * @inheritDoc */ protected $primaryKey = self::COMMENT_ID; /** - * @var string + * @inheritDoc */ protected $table = 'comments'; diff --git a/src/Models/Option.php b/src/Models/Option.php index ebbfe3c..0f973f2 100644 --- a/src/Models/Option.php +++ b/src/Models/Option.php @@ -8,44 +8,37 @@ namespace Dbout\WpOrm\Models; +use Dbout\WpOrm\Api\OptionInterface; use Dbout\WpOrm\Builders\OptionBuilder; use Dbout\WpOrm\Orm\AbstractModel; /** * @method static Option|null find($optionId) * @method static OptionBuilder query() - * - * @method self setOptionName(string $name) - * @method string getOptionName() - * @method self setOptionValue($value) - * @method mixed getOptionValue() - * @method self setAutoload(string $autoload) - * @method string getAutoload() */ -class Option extends AbstractModel +class Option extends AbstractModel implements OptionInterface { - public const OPTION_ID = 'option_id'; - public const NAME = 'option_name'; - public const VALUE = 'option_value'; - public const AUTOLOAD = 'autoload'; - /** - * @var string + * @inheritDoc */ protected $primaryKey = self::OPTION_ID; + protected $casts = [ + self::AUTOLOAD => 'boolean', + ]; + /** - * @var string + * @inheritDoc */ protected $table = 'options'; /** - * @var bool + * @inheritDoc */ public $timestamps = false; /** - * @var string[] + * @inheritDoc */ protected $fillable = [ self::OPTION_ID, self::NAME, self::VALUE, self::AUTOLOAD, diff --git a/src/Models/Post.php b/src/Models/Post.php index 6a3de22..09db5f7 100644 --- a/src/Models/Post.php +++ b/src/Models/Post.php @@ -8,7 +8,8 @@ namespace Dbout\WpOrm\Models; -use Carbon\Carbon; +use Dbout\WpOrm\Api\PostInterface; +use Dbout\WpOrm\Api\UserInterface; use Dbout\WpOrm\Builders\PostBuilder; use Dbout\WpOrm\Models\Meta\PostMeta; use Dbout\WpOrm\Models\Meta\WithMeta; @@ -22,88 +23,17 @@ * @property User|null $author * @property PostMeta[] $metas * @property Post|null $parent - * - * @method self setPostDate($date) - * @method Carbon|null getPostDate() - * @method self setPostDateGMT($date) - * @method Carbon|null getPostDateGMT() - * @method self setPostContent(?string $content) - * @method string|null getPostContent() - * @method self setPostType(string $type) - * @method string|null getPostType() - * @method self setGuid(?string $guid) - * @method string|null getGuid() - * @method self setPostTitle(?string $title) - * @method string|null getPostTitle() - * @method self setPostExcerpt(?string $excerpt) - * @method string|null getPostExcerpt() - * @method self setPostStatus(?string $status) - * @method string|null getPostStatus() - * @method self setCommentStatus(string $status) - * @method string|null getCommentStatus() - * @method self setPingStatus(string $status) - * @method string|null getPingStatus() - * @method self setPostPassword(?string $password) - * @method string|null getPostPassword() - * @method self setPostName(?string $name) - * @method string|null getPostName() - * @method self setToPing(?string $toPing) - * @method string|null getToPing() - * @method self setPinged(?string $pinged) - * @method string|null getPinged() - * @method self setPostModified($modified) - * @method Carbon|null getPostModified() - * @method self setPostModifiedGMT($modified) - * @method Carbon|null getPostModifiedGMT() - * @method setPostMimeType(?string $mimeType) - * @method string|null getPostMimeType() - * @method self setMenuOrder(?int $order) - * @method int|null getMenuOrder() - * @method self setPostContentFiltered($content) - * @method string|null getPostContentFiltered() + * @property Comment[] $comments */ -class Post extends AbstractModel +class Post extends AbstractModel implements PostInterface { use WithMeta; - public const CREATED_AT = 'post_date'; - public const UPDATED_AT = 'post_modified'; - public const POST_ID = 'ID'; - public const AUTHOR = 'post_author'; - public const DATE = 'post_date'; - public const DATE_GMT = 'post_date_gmt'; - public const CONTENT = 'post_content'; - public const TITLE = 'post_title'; - public const EXCERPT = 'post_excerpt'; - public const COMMENT_STATUS = 'comment_status'; - public const STATUS = 'post_status'; - public const PING_STATUS = 'ping_status'; - public const PASSWORD = 'post_password'; - public const POST_NAME = 'post_name'; - public const TO_PING = 'to_ping'; - public const PINGED = 'pinged'; - public const MODIFIED = 'post_modified'; - public const MODIFIED_GMT = 'post_modified_gmt'; - public const CONTENT_FILTERED = 'post_content_filtered'; - public const PARENT = 'post_parent'; - public const GUID = 'guid'; - public const MENU_ORDER = 'menu_order'; - public const TYPE = 'post_type'; - public const MIME_TYPE = 'post_mime_type'; - public const COMMENT_COUNT = 'comment_count'; - /** * @var string */ protected $primaryKey = self::POST_ID; - /** - * @var string[] - */ - protected $dates = [ - self::DATE, self::MODIFIED, self::DATE_GMT, self::MODIFIED_GMT, - ]; - /** * @var string[] */ @@ -115,11 +45,15 @@ class Post extends AbstractModel ]; /** - * @var string[] + * @inheritDoc */ protected $casts = [ self::MENU_ORDER => 'integer', self::COMMENT_COUNT => 'integer', + self::DATE => 'date', + self::MODIFIED => 'date', + self::DATE_GMT => 'date', + self::MODIFIED_GMT => 'date', ]; /** @@ -132,7 +66,7 @@ class Post extends AbstractModel */ public function author(): HasOne { - return $this->hasOne(User::class, User::USER_ID, self::AUTHOR); + return $this->hasOne(User::class, UserInterface::USER_ID, self::AUTHOR); } /** @@ -148,7 +82,7 @@ public function comments(): HasMany */ public function parent(): HasOne { - return $this->hasOne(Post::class, Post::POST_ID, self::PARENT); + return $this->hasOne(Post::class, PostInterface::POST_ID, self::PARENT); } /** diff --git a/src/Models/User.php b/src/Models/User.php index 06b7073..d02df6a 100644 --- a/src/Models/User.php +++ b/src/Models/User.php @@ -8,7 +8,8 @@ namespace Dbout\WpOrm\Models; -use Carbon\Carbon; +use Dbout\WpOrm\Api\PostInterface; +use Dbout\WpOrm\Api\UserInterface; use Dbout\WpOrm\Builders\UserBuilder; use Dbout\WpOrm\Models\Meta\UserMeta; use Dbout\WpOrm\Models\Meta\WithMeta; @@ -21,70 +22,31 @@ * @property UserMeta[] $metas * @property Comment $comments * @property Post[] $posts - * - * @method string|null getUserLogin() - * @method self setUserLogin(string $login) - * @method string|null getUserPass() - * @method self setUserPass(string $password) - * @method string|null getUserNicename() - * @method self setUserNicename(string $nicename) - * @method string|null getUserEmail() - * @method self setUserEmail(string $email) - * @method string|null getUserUrl() - * @method self setUserUrl(?string $url) - * @method Carbon|null getUserRegistered() - * @method self setUserRegistered($date) - * @method string|null getUserActivationKey() - * @method self setUserActivationKey(?string $key) - * @method int getUserStatus() - * @method self setUserStatus(int $status) - * @method string|null getDisplayName() - * @method self setDisplayName(?string $name) - * */ -class User extends AbstractModel +class User extends AbstractModel implements UserInterface { use WithMeta; - public const USER_ID = 'ID'; - public const LOGIN = 'user_login'; - public const PASSWORD = 'user_pass'; - public const NICE_NAME = 'user_nicename'; - public const EMAIL = 'user_email'; - public const URL = 'user_url'; - public const REGISTERED = 'user_registered'; - public const ACTIVATION_KEY = 'user_activation_key'; - public const DISPLAY_NAME = 'display_name'; - public const STATUS = 'user_status'; - public const CREATED_AT = 'user_registered'; - public const UPDATED_AT = null; - /** - * @var string + * @inheritDoc */ protected $table = 'users'; /** - * @var string[] - */ - protected $dates = [ - self::REGISTERED, - ]; - - /** - * @var array + * @inheritDoc */ protected $casts = [ self::STATUS => 'integer', + self::REGISTERED => 'date', ]; /** - * @var string + * @inheritDoc */ protected $primaryKey = self::USER_ID; /** - * @var string[] + * @inheritDoc */ protected $fillable = [ self::LOGIN, self::PASSWORD, self::NICE_NAME, self::EMAIL, self::URL, self::REGISTERED, self::ACTIVATION_KEY, @@ -104,7 +66,7 @@ public function comments(): HasMany */ public function posts(): HasMany { - return $this->hasMany(Post::class, Post::AUTHOR); + return $this->hasMany(Post::class, PostInterface::AUTHOR); } /** diff --git a/src/Orm/Builder.php b/src/Orm/Builder.php index c8f41c5..34e5262 100644 --- a/src/Orm/Builder.php +++ b/src/Orm/Builder.php @@ -22,9 +22,7 @@ class Builder extends EloquentBuilder */ public function addWhereExistsQuery(EloquentBuilder $query, $boolean = 'and', $not = false) { - $type = $not ? 'NotExists' : 'Exists'; - $this->wheres[] = compact('type', 'query', 'boolean'); $this->addBinding($query->getBindings(), 'where'); From d4a84c2a4818dac78407dcc6904ef28c26aeb136 Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Tue, 26 Sep 2023 22:40:06 +0200 Subject: [PATCH 05/67] #6 CS --- src/Builders/AbstractBuilder.php | 4 ++-- src/Builders/CommentBuilder.php | 4 ++-- src/Builders/PostBuilder.php | 13 +++++++------ src/Builders/Traits/WithMeta.php | 2 +- src/Builders/UserBuilder.php | 17 +++++++++++------ src/Models/Option.php | 4 ---- 6 files changed, 23 insertions(+), 21 deletions(-) diff --git a/src/Builders/AbstractBuilder.php b/src/Builders/AbstractBuilder.php index 1e6fc12..57b8de9 100644 --- a/src/Builders/AbstractBuilder.php +++ b/src/Builders/AbstractBuilder.php @@ -8,7 +8,7 @@ namespace Dbout\WpOrm\Builders; -use Dbout\WpOrm\Models\Post; +use Dbout\WpOrm\Api\PostInterface; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; @@ -70,7 +70,7 @@ protected function joined($query, $table): bool * @param string $key * @return array */ - public function toArrayOptions(string $label = Post::TITLE, string $key = Post::POST_ID): array + public function toArrayOptions(string $label = PostInterface::TITLE, string $key = PostInterface::POST_ID): array { return $this->pluck($label, $key)->toArray(); } diff --git a/src/Builders/CommentBuilder.php b/src/Builders/CommentBuilder.php index b819480..902698d 100644 --- a/src/Builders/CommentBuilder.php +++ b/src/Builders/CommentBuilder.php @@ -8,7 +8,7 @@ namespace Dbout\WpOrm\Builders; -use Dbout\WpOrm\Models\Comment; +use Dbout\WpOrm\Api\CommentInterface; use Illuminate\Database\Eloquent\Collection; class CommentBuilder extends AbstractBuilder @@ -30,6 +30,6 @@ public function findAllByType(string $type): Collection */ public function whereTypes(...$types): self { - return $this->_whereOrIn(Comment::TYPE, $types); + return $this->_whereOrIn(CommentInterface::TYPE, $types); } } diff --git a/src/Builders/PostBuilder.php b/src/Builders/PostBuilder.php index e3b25c8..8061350 100644 --- a/src/Builders/PostBuilder.php +++ b/src/Builders/PostBuilder.php @@ -8,6 +8,7 @@ namespace Dbout\WpOrm\Builders; +use Dbout\WpOrm\Api\PostInterface; use Dbout\WpOrm\Builders\Traits\WithMeta; use Dbout\WpOrm\Models\Post; use Illuminate\Database\Eloquent\Collection; @@ -26,9 +27,9 @@ public function findOneByName(?string $name): ?Post return null; } - return $this - ->where(Post::POST_NAME, $name) - ->first(); + /** @var Post|null $model */ + $model = $this->firstWhere(PostInterface::POST_NAME, $name); + return $model; } /** @@ -48,7 +49,7 @@ public function findAllByType(string $type): Collection */ public function whereTypes(...$types): self { - return $this->_whereOrIn(Post::TYPE, $types); + return $this->_whereOrIn(PostInterface::TYPE, $types); } /** @@ -57,7 +58,7 @@ public function whereTypes(...$types): self */ public function whereAuthor($author): self { - $this->where(Post::AUTHOR, $author); + $this->where(PostInterface::AUTHOR, $author); return $this; } @@ -67,6 +68,6 @@ public function whereAuthor($author): self */ public function whereStatus(...$status): self { - return $this->_whereOrIn(Post::STATUS, $status); + return $this->_whereOrIn(PostInterface::STATUS, $status); } } diff --git a/src/Builders/Traits/WithMeta.php b/src/Builders/Traits/WithMeta.php index 2d9b612..17301ce 100644 --- a/src/Builders/Traits/WithMeta.php +++ b/src/Builders/Traits/WithMeta.php @@ -128,7 +128,7 @@ public function joinToMeta(string $metaKey, string $joinType = 'inner'): self '=', $join->raw(sprintf("'%s'", $metaKey)) )->on( - $join->raw(sprintf("%s.%s", $metaKey, $this->metaModel->getFkColumn())), + $join->raw(sprintf('%s.%s', $metaKey, $this->metaModel->getFkColumn())), '=', sprintf('%s.%s', $model->getTable(), $model->getKeyName()), ); diff --git a/src/Builders/UserBuilder.php b/src/Builders/UserBuilder.php index 4a417d4..f9bb3b8 100644 --- a/src/Builders/UserBuilder.php +++ b/src/Builders/UserBuilder.php @@ -8,6 +8,7 @@ namespace Dbout\WpOrm\Builders; +use Dbout\WpOrm\Api\UserInterface; use Dbout\WpOrm\Builders\Traits\WithMeta; use Dbout\WpOrm\Models\User; @@ -21,7 +22,9 @@ class UserBuilder extends AbstractBuilder */ public function findOneByEmail(string $email): ?User { - return $this->firstWhere(User::EMAIL, $email); + /** @var User|null $model */ + $model = $this->firstWhere(UserInterface::EMAIL, $email); + return $model; } /** @@ -30,7 +33,9 @@ public function findOneByEmail(string $email): ?User */ public function findOneByLogin(string $login): ?User { - return $this->firstWhere(User::LOGIN, $login); + /** @var User|null $model */ + $model = $this->firstWhere(UserInterface::LOGIN, $login); + return $model; } /** @@ -39,7 +44,7 @@ public function findOneByLogin(string $login): ?User */ public function whereEmail(string $email): self { - return $this->where(User::EMAIL, $email); + return $this->where(UserInterface::EMAIL, $email); } /** @@ -48,7 +53,7 @@ public function whereEmail(string $email): self */ public function whereLogin(string $login): self { - return $this->where(User::LOGIN, $login); + return $this->where(UserInterface::LOGIN, $login); } /** @@ -57,7 +62,7 @@ public function whereLogin(string $login): self */ public function whereEmails(... $emails): self { - return $this->_whereOrIn(User::EMAIL, $emails); + return $this->_whereOrIn(UserInterface::EMAIL, $emails); } /** @@ -66,6 +71,6 @@ public function whereEmails(... $emails): self */ public function whereLogins(... $logins): self { - return $this->_whereOrIn(User::LOGIN, $logins); + return $this->_whereOrIn(UserInterface::LOGIN, $logins); } } diff --git a/src/Models/Option.php b/src/Models/Option.php index 0f973f2..a9e8690 100644 --- a/src/Models/Option.php +++ b/src/Models/Option.php @@ -23,10 +23,6 @@ class Option extends AbstractModel implements OptionInterface */ protected $primaryKey = self::OPTION_ID; - protected $casts = [ - self::AUTOLOAD => 'boolean', - ]; - /** * @inheritDoc */ From 29d86d8687abb5f2fadbfaa41afeb4fdfc0e284d Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Wed, 27 Sep 2023 22:25:16 +0200 Subject: [PATCH 06/67] #6 WIP api --- src/Api/CommentInterface.php | 27 ++++ src/Api/TermInterface.php | 25 +++ src/Api/TermRelationshipInterface.php | 24 +++ src/Api/TermTaxonomyInterface.php | 31 ++++ src/Models/Comment.php | 210 ++------------------------ src/Models/Page.php | 2 +- src/Models/Post.php | 3 +- src/Models/Term.php | 38 ++--- src/Models/TermRelationship.php | 21 +-- src/Models/TermTaxonomy.php | 28 +--- src/Models/User.php | 3 +- 11 files changed, 149 insertions(+), 263 deletions(-) create mode 100644 src/Api/TermInterface.php create mode 100644 src/Api/TermRelationshipInterface.php create mode 100644 src/Api/TermTaxonomyInterface.php diff --git a/src/Api/CommentInterface.php b/src/Api/CommentInterface.php index 8e610f5..0213ec4 100644 --- a/src/Api/CommentInterface.php +++ b/src/Api/CommentInterface.php @@ -8,6 +8,33 @@ namespace Dbout\WpOrm\Api; +use Carbon\Carbon; +use Dbout\WpOrm\Models\Comment; + +/** + * @method Comment setAuthor(string $author) + * @method string|null getAuthor() + * @method Comment setAuthorEmail(string $email) + * @method string|null getAuthorEmail() + * @method Comment setAuthorUrl(?string $url) + * @method string|null getAuthorUrl() + * @method Comment setAuthorIp(?string $ip) + * @method string|null getAuthorIp() + * @method Comment setDate($date) + * @method Carbon|null getDate() + * @method Comment setDateGMT($date) + * @method Carbon|null getDateGMT() + * @method Comment setContent(string $content) + * @method string|null getContent() + * @method Comment setKarma(int $karma) + * @method int|null getKarma() + * @method Comment setAgent(string $agent) + * @method string|null getAgent() + * @method Comment setType(?string $type) + * @method string|null getType() + * @method Comment setApproved(string $approved) + * @method string|null getApproved() + */ interface CommentInterface { public const COMMENT_ID = 'comment_ID'; diff --git a/src/Api/TermInterface.php b/src/Api/TermInterface.php new file mode 100644 index 0000000..5fe0706 --- /dev/null +++ b/src/Api/TermInterface.php @@ -0,0 +1,25 @@ + + */ + +namespace Dbout\WpOrm\Api; + +/** + * @method string|null getName() + * @method self setName(?string $name); + * @method string|null getSlug() + * @method self setSlug(?string $slug) + * @method int|null getTermGroup() + * @method self setTermGroup(?int $group) + */ +interface TermInterface +{ + public const TERM_ID = 'term_id'; + public const NAME = 'name'; + public const SLUG = 'slug'; + public const TERM_GROUP = 'term_group'; +} diff --git a/src/Api/TermRelationshipInterface.php b/src/Api/TermRelationshipInterface.php new file mode 100644 index 0000000..589efbf --- /dev/null +++ b/src/Api/TermRelationshipInterface.php @@ -0,0 +1,24 @@ + + */ + +namespace Dbout\WpOrm\Api; + +/** + * @method int|null getTermOrder() + * @method self setTermOrder(?int $order) + * @method int|null getTermTaxonomyId() + * @method self setTermTaxonomyId(?int $id) + * @method int|null getObjectId() + * @method self setObjectId(?int $id) + */ +interface TermRelationshipInterface +{ + public const OBJECT_ID = 'object_id'; + public const TERM_TAXONOMY_ID = 'term_taxonomy_id'; + public const TERM_ORDER = 'term_order'; +} diff --git a/src/Api/TermTaxonomyInterface.php b/src/Api/TermTaxonomyInterface.php new file mode 100644 index 0000000..b005bba --- /dev/null +++ b/src/Api/TermTaxonomyInterface.php @@ -0,0 +1,31 @@ + + */ + +namespace Dbout\WpOrm\Api; + +/** + * @method int|null getTermId() + * @method self setTermId(int $id) + * @method string getTaxonomy() + * @method self setTaxonomy(string $taxonomy) + * @method string|null getDescription() + * @method self setDescription(?string $description) + * @method int|null getParent() + * @method self setParent($parent) + * @method int|null getCount() + * @method self setCount(int $count) + */ +interface TermTaxonomyInterface +{ + public const TERM_TAXONOMY_ID = 'term_taxonomy_id'; + public const TERM_ID = 'term_id'; + public const TAXONOMY = 'taxonomy'; + public const DESCRIPTION = 'description'; + public const PARENT = 'parent'; + public const COUNT = 'count'; +} diff --git a/src/Models/Comment.php b/src/Models/Comment.php index 79f523e..9616c3a 100644 --- a/src/Models/Comment.php +++ b/src/Models/Comment.php @@ -8,8 +8,9 @@ namespace Dbout\WpOrm\Models; -use Carbon\Carbon; use Dbout\WpOrm\Api\CommentInterface; +use Dbout\WpOrm\Api\PostInterface; +use Dbout\WpOrm\Api\UserInterface; use Dbout\WpOrm\Builders\CommentBuilder; use Dbout\WpOrm\Orm\AbstractModel; use Illuminate\Database\Eloquent\Relations\HasOne; @@ -37,209 +38,20 @@ class Comment extends AbstractModel implements CommentInterface protected $table = 'comments'; /** - * @param string $author - * @return $this - */ - public function setAuthor(string $author): self - { - $this->setAttribute(self::AUTHOR, $author); - return $this; - } - - /** - * @return string - */ - public function getAuthor(): string - { - return $this->getAttribute(self::AUTHOR); - } - - /** - * @param string $email - * @return $this - */ - public function setAuthorEmail(string $email): self - { - $this->setAttribute(self::AUTHOR_EMAIL, $email); - return $this; - } - - /** - * @return string - */ - public function getAuthorEmail(): string - { - return $this->getAttribute(self::AUTHOR_EMAIL); - } - - /** - * @param string|null $url - * @return $this - */ - public function setAuthorUrl(?string $url): self - { - $this->setAttribute(self::AUTHOR_URL, $url); - return $this; - } - - /** - * @return string|null - */ - public function getAuthorUrl(): ?string - { - return $this->getAttribute(self::AUTHOR_URL); - } - - /** - * @param string|null $ip - * @return $this - */ - public function setAuthorIp(?string $ip): self - { - $this->setAttribute(self::AUTHOR_IP, $ip); - return $this; - } - - /** - * @return string|null - */ - public function getAuthorIp(): ?string - { - return $this->getAttribute(self::AUTHOR_IP); - } - - /** - * @param $date - * @return $this - */ - public function setDate($date): self - { - $this->setAttribute(self::DATE, $date); - return $this; - } - - /** - * @return Carbon|null - */ - public function getDate(): ?Carbon - { - return $this->getAttribute(self::DATE); - } - - /** - * @param $date - * @return $this - */ - public function setDateGMT($date): self - { - $this->setAttribute(self::DATE_GMT, $date); - return $this; - } - - /** - * @return mixed - */ - public function getDateGMT() - { - return $this->getAttribute(self::DATE_GMT); - } - - /** - * @param string $content - * @return $this - */ - public function setContent(string $content): self - { - $this->setAttribute(self::CONTENT, $content); - return $this; - } - - /** - * @return string|null - */ - public function getContent(): ?string - { - return $this->getAttribute(self::CONTENT); - } - - /** - * @param int $karma - * @return $this - */ - public function setKarma(int $karma): self - { - $this->setAttribute(self::KARMA, $karma); - return $this; - } - - /** - * @return int - */ - public function getKarma(): int - { - return $this->getAttribute(self::KARMA); - } - - /** - * @param string $approved - * @return $this - */ - public function setApproved(string $approved): self - { - $this->setAttribute(self::APPROVED, $approved); - return $this; - } - - /** - * @return mixed - */ - public function getApproved() - { - return $this->getAttribute(self::APPROVED); - } - - /** - * @param string $agent - * @return $this - */ - public function setAgent(string $agent): self - { - $this->setAttribute(self::AGENT, $agent); - return $this; - } - - /** - * @return string|null - */ - public function getAgent(): ?string - { - return $this->getAttribute(self::AGENT); - } - - /** - * @param string|null $type - * @return $this - */ - public function setType(?string $type): self - { - $this->setAttribute(self::TYPE, $type); - return $this; - } - - /** - * @return string|null + * @inheritDoc */ - public function getType(): ?string - { - return $this->getAttribute(self::TYPE); - } + protected $casts = [ + self::KARMA => 'integer', + self::DATE_GMT => 'date', + self::DATE => 'date', + ]; /** * @return HasOne */ public function user(): HasOne { - return $this->hasOne(User::class, User::USER_ID, self::USER_ID); + return $this->hasOne(User::class, UserInterface::USER_ID, self::USER_ID); } /** @@ -247,7 +59,7 @@ public function user(): HasOne */ public function post(): HasOne { - return $this->hasOne(Post::class, Post::POST_ID, self::POST_ID); + return $this->hasOne(Post::class, PostInterface::POST_ID, self::POST_ID); } /** @@ -255,7 +67,7 @@ public function post(): HasOne */ public function parent(): HasOne { - return $this->hasOne(Comment::class, Comment::COMMENT_ID, self::PARENT); + return $this->hasOne(Comment::class, CommentInterface::COMMENT_ID, self::PARENT); } /** diff --git a/src/Models/Page.php b/src/Models/Page.php index 72a32f9..df2476d 100644 --- a/src/Models/Page.php +++ b/src/Models/Page.php @@ -11,7 +11,7 @@ class Page extends CustomPost { /** - * @var string + * @inheritDoc */ protected string $_type = 'page'; } diff --git a/src/Models/Post.php b/src/Models/Post.php index 09db5f7..0621d95 100644 --- a/src/Models/Post.php +++ b/src/Models/Post.php @@ -8,6 +8,7 @@ namespace Dbout\WpOrm\Models; +use Dbout\WpOrm\Api\CommentInterface; use Dbout\WpOrm\Api\PostInterface; use Dbout\WpOrm\Api\UserInterface; use Dbout\WpOrm\Builders\PostBuilder; @@ -74,7 +75,7 @@ public function author(): HasOne */ public function comments(): HasMany { - return $this->hasMany(Comment::class, Comment::POST_ID); + return $this->hasMany(Comment::class, CommentInterface::POST_ID); } /** diff --git a/src/Models/Term.php b/src/Models/Term.php index 8d4ca82..ab8afe5 100644 --- a/src/Models/Term.php +++ b/src/Models/Term.php @@ -8,54 +8,43 @@ namespace Dbout\WpOrm\Models; +use Dbout\WpOrm\Api\TermInterface; +use Dbout\WpOrm\Api\TermTaxonomyInterface; use Dbout\WpOrm\Builders\TermBuilder; use Dbout\WpOrm\Orm\AbstractModel; use Illuminate\Database\Eloquent\Relations\HasOne; /** - * @method static self find(int $termId) + * @method static Term|null find(int $termId) * @method static TermBuilder query() - * - * @method string|null getName() - * @method self setName(?string $name); - * @method string|null getSlug() - * @method self setSlug(?string $slug) - * @method int|null getTermGroup() - * @method self setTermGroup(?int $group) - * * @property TermTaxonomy|null $termTaxonomy */ -class Term extends AbstractModel +class Term extends AbstractModel implements TermInterface { - public const TERM_ID = 'term_id'; - public const NAME = 'name'; - public const SLUG = 'slug'; - public const TERM_GROUP = 'term_group'; - /** - * @var string + * @inheritDoc */ protected $table = 'terms'; /** - * @var string + * @inheritDoc */ protected $primaryKey = self::TERM_ID; /** - * @var bool + * @inheritDoc */ public $timestamps = false; /** - * @var string[] + * @inheritDoc */ protected $casts = [ self::TERM_GROUP => 'integer', ]; /** - * @var string[] + * @inheritDoc */ protected $fillable = [ self::SLUG, self::TERM_ID, self::TERM_GROUP, self::NAME, @@ -66,12 +55,15 @@ class Term extends AbstractModel */ public function termTaxonomy(): HasOne { - return $this->hasOne(TermTaxonomy::class, TermTaxonomy::TERM_ID, self::TERM_ID); + return $this->hasOne( + TermTaxonomy::class, + TermTaxonomyInterface::TERM_ID, + self::TERM_ID + ); } /** - * @param \Illuminate\Database\Query\Builder $query - * @return TermBuilder + * @inheritDoc */ public function newEloquentBuilder($query): TermBuilder { diff --git a/src/Models/TermRelationship.php b/src/Models/TermRelationship.php index 46d437d..a6f55f9 100644 --- a/src/Models/TermRelationship.php +++ b/src/Models/TermRelationship.php @@ -8,34 +8,23 @@ namespace Dbout\WpOrm\Models; +use Dbout\WpOrm\Api\TermRelationshipInterface; use Dbout\WpOrm\Orm\AbstractModel; -/** - * @method int|null getTermOrder() - * @method self setTermOrder(?int $order) - * @method int|null getTermTaxonomyId() - * @method self setTermTaxonomyId(?int $id) - * @method int|null getObjectId() - * @method self setObjectId(?int $id) - */ -class TermRelationship extends AbstractModel +class TermRelationship extends AbstractModel implements TermRelationshipInterface { - public const OBJECT_ID = 'object_id'; - public const TERM_TAXONOMY_ID = 'term_taxonomy_id'; - public const TERM_ORDER = 'term_order'; - /** - * @var string + * @inheritDoc */ protected $primaryKey = self::OBJECT_ID; /** - * @var bool + * @inheritDoc */ public $timestamps = false; /** - * @var string[] + * @inheritDoc */ protected $casts = [ self::TERM_ORDER => 'integer', diff --git a/src/Models/TermTaxonomy.php b/src/Models/TermTaxonomy.php index fd9b3f1..47f485e 100644 --- a/src/Models/TermTaxonomy.php +++ b/src/Models/TermTaxonomy.php @@ -8,47 +8,31 @@ namespace Dbout\WpOrm\Models; +use Dbout\WpOrm\Api\TermTaxonomyInterface; use Dbout\WpOrm\Orm\AbstractModel; /** * @method static TermTaxonomy|null find(int $id) - * @method int|null getTermId() - * @method self setTermId(int $id) - * @method string getTaxonomy() - * @method self setTaxonomy(string $taxonomy) - * @method string|null getDescription() - * @method self setDescription(?string $description) - * @method int|null getParent() - * @method self setParent($parent) - * @method int|null getCount() - * @method self setCount(int $count) */ -class TermTaxonomy extends AbstractModel +class TermTaxonomy extends AbstractModel implements TermTaxonomyInterface { - public const TERM_TAXONOMY_ID = 'term_taxonomy_id'; - public const TERM_ID = 'term_id'; - public const TAXONOMY = 'taxonomy'; - public const DESCRIPTION = 'description'; - public const PARENT = 'parent'; - public const COUNT = 'count'; - /** - * @var bool + * @inheritDoc */ public $timestamps = false; /** - * @var string + * @inheritDoc */ protected $table = 'term_taxonomy'; /** - * @var string + * @inheritDoc */ protected $primaryKey = self::TERM_TAXONOMY_ID; /** - * @var string[] + * @inheritDoc */ protected $casts = [ self::COUNT => 'integer', diff --git a/src/Models/User.php b/src/Models/User.php index d02df6a..23f4eae 100644 --- a/src/Models/User.php +++ b/src/Models/User.php @@ -8,6 +8,7 @@ namespace Dbout\WpOrm\Models; +use Dbout\WpOrm\Api\CommentInterface; use Dbout\WpOrm\Api\PostInterface; use Dbout\WpOrm\Api\UserInterface; use Dbout\WpOrm\Builders\UserBuilder; @@ -58,7 +59,7 @@ class User extends AbstractModel implements UserInterface */ public function comments(): HasMany { - return $this->hasMany(Comment::class, Comment::USER_ID); + return $this->hasMany(Comment::class, CommentInterface::USER_ID); } /** From 88a2d83e24f1a5b293f5d5501ec1c644e45fccd6 Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Wed, 27 Sep 2023 22:31:43 +0200 Subject: [PATCH 07/67] #6 Run rector --- Makefile | 6 +++++- rector.php | 23 ++++++++++++++++++++++ src/Models/Comment.php | 4 ++-- src/Models/Meta/AbstractMeta.php | 4 ++-- src/Models/Meta/PostMeta.php | 4 ++-- src/Models/Meta/UserMeta.php | 4 ++-- src/Models/Traits/HasCustomType.php | 2 +- src/Orm/AbstractModel.php | 2 +- src/Orm/Builder.php | 2 +- src/Orm/Database.php | 30 +++++++++++++++-------------- 10 files changed, 55 insertions(+), 26 deletions(-) create mode 100644 rector.php diff --git a/Makefile b/Makefile index 4f4d14b..f2cccaa 100644 --- a/Makefile +++ b/Makefile @@ -6,4 +6,8 @@ csFixer: # Run phpStan check runPHPStan: - vendor/bin/phpstan analyse -c phpstan.neon \ No newline at end of file + vendor/bin/phpstan analyse -c phpstan.neon + +# Run rector +runRector: + vendor/bin/rector process src --dry-run \ No newline at end of file diff --git a/rector.php b/rector.php new file mode 100644 index 0000000..876d6fe --- /dev/null +++ b/rector.php @@ -0,0 +1,23 @@ + + */ + +use Rector\Config\RectorConfig; +use Rector\Set\ValueObject\SetList; +use Rector\TypeDeclaration\Rector\Property\TypedPropertyFromStrictConstructorRector; + +return static function (RectorConfig $rectorConfig): void { + // register single rule + $rectorConfig->rule(TypedPropertyFromStrictConstructorRector::class); + + // here we can define, what sets of rules will be applied + // tip: use "SetList" class to autocomplete sets with your IDE + $rectorConfig->sets([ + SetList::CODE_QUALITY, + SetList::PHP_81, + ]); +}; diff --git a/src/Models/Comment.php b/src/Models/Comment.php index 9616c3a..abf210d 100644 --- a/src/Models/Comment.php +++ b/src/Models/Comment.php @@ -24,8 +24,8 @@ */ class Comment extends AbstractModel implements CommentInterface { - public const CREATED_AT = self::DATE; - public const UPDATED_AT = null; + final public const CREATED_AT = self::DATE; + final public const UPDATED_AT = null; /** * @inheritDoc diff --git a/src/Models/Meta/AbstractMeta.php b/src/Models/Meta/AbstractMeta.php index 85979b1..ccf8014 100644 --- a/src/Models/Meta/AbstractMeta.php +++ b/src/Models/Meta/AbstractMeta.php @@ -12,8 +12,8 @@ abstract class AbstractMeta extends AbstractModel implements MetaInterface { - public const META_KEY = 'meta_key'; - public const META_VALUE = 'meta_value'; + final public const META_KEY = 'meta_key'; + final public const META_VALUE = 'meta_value'; /** * Disable created_at and updated_at diff --git a/src/Models/Meta/PostMeta.php b/src/Models/Meta/PostMeta.php index a5edcfa..ceff27c 100644 --- a/src/Models/Meta/PostMeta.php +++ b/src/Models/Meta/PostMeta.php @@ -17,8 +17,8 @@ */ class PostMeta extends AbstractMeta { - public const META_ID = 'meta_id'; - public const POST_ID = 'post_id'; + final public const META_ID = 'meta_id'; + final public const POST_ID = 'post_id'; /** * @var string diff --git a/src/Models/Meta/UserMeta.php b/src/Models/Meta/UserMeta.php index d20e046..5eb3c81 100644 --- a/src/Models/Meta/UserMeta.php +++ b/src/Models/Meta/UserMeta.php @@ -17,8 +17,8 @@ */ class UserMeta extends AbstractMeta { - public const META_ID = 'umeta_id'; - public const USER_ID = 'user_id'; + final public const META_ID = 'umeta_id'; + final public const USER_ID = 'user_id'; /** * @var string diff --git a/src/Models/Traits/HasCustomType.php b/src/Models/Traits/HasCustomType.php index c99a590..f20ed95 100644 --- a/src/Models/Traits/HasCustomType.php +++ b/src/Models/Traits/HasCustomType.php @@ -29,7 +29,7 @@ public function getPostType(): ?string * @param string $postType * @throws NotAllowedException */ - final public function setPostType(string $postType): void + final public function setPostType(string $postType): never { throw new NotAllowedException(sprintf( 'You cannot set a type for this object. Current type [%s]', diff --git a/src/Orm/AbstractModel.php b/src/Orm/AbstractModel.php index 94e5e3d..f9471f4 100644 --- a/src/Orm/AbstractModel.php +++ b/src/Orm/AbstractModel.php @@ -91,7 +91,7 @@ public static function table(): string public function __call($method, $parameters) { preg_match('#^(get|set)(.*)#', $method, $matchGetter); - if (!$matchGetter) { + if ($matchGetter === []) { return parent::__call($method, $parameters); } diff --git a/src/Orm/Builder.php b/src/Orm/Builder.php index 34e5262..41b65b4 100644 --- a/src/Orm/Builder.php +++ b/src/Orm/Builder.php @@ -23,7 +23,7 @@ class Builder extends EloquentBuilder public function addWhereExistsQuery(EloquentBuilder $query, $boolean = 'and', $not = false) { $type = $not ? 'NotExists' : 'Exists'; - $this->wheres[] = compact('type', 'query', 'boolean'); + $this->wheres[] = ['type' => $type, 'query' => $query, 'boolean' => $boolean]; $this->addBinding($query->getBindings(), 'where'); diff --git a/src/Orm/Database.php b/src/Orm/Database.php index 8c43525..ff074ce 100644 --- a/src/Orm/Database.php +++ b/src/Orm/Database.php @@ -17,6 +17,10 @@ class Database implements ConnectionInterface { + /** + * @var bool + */ + public $loggingQueries; /** * @var \wpdb */ @@ -32,7 +36,9 @@ class Database implements ConnectionInterface * The database connection configuration options. * @var array */ - protected array $config = []; + protected array $config = [ + 'name' => 'wp-eloquent-mysql2', + ]; /** * @var string|null @@ -49,7 +55,7 @@ class Database implements ConnectionInterface */ public static function getInstance(): Database { - if (!self::$instance) { + if (!self::$instance instanceof \Dbout\WpOrm\Orm\Database) { self::$instance = new self(); } @@ -62,9 +68,6 @@ public static function getInstance(): Database public function __construct() { global $wpdb; - $this->config = [ - 'name' => 'wp-eloquent-mysql2', - ]; if ($wpdb) { $this->tablePrefix = $wpdb->prefix; @@ -203,10 +206,10 @@ public function cursor($query, $bindings = [], $useReadPdo = true) */ private function bind_params($query, $bindings, $update = false) { - $query = \str_replace('"', '`', $query); + $query = \str_replace('"', '`', (string) $query); $bindings = $this->prepareBindings($bindings); - if (!$bindings) { + if ($bindings === []) { return $query; } @@ -221,9 +224,8 @@ private function bind_params($query, $bindings, $update = false) }, $bindings); $query = \str_replace(['%', '?'], ['%%', '%s'], $query); - $query = \vsprintf($query, $bindings); - return $query; + return \vsprintf($query, $bindings); } /** @@ -301,7 +303,7 @@ public function affectingStatement($query, $bindings = []) throw new QueryException($new_query, $bindings, new \Exception($this->db->last_error)); } - return \intval($result); + return (int) $result; } /** @@ -325,7 +327,7 @@ public function prepareBindings(array $bindings) // Micro-optimization: check for scalar values before instances if (\is_bool($value)) { - $bindings[$key] = \intval($value); + $bindings[$key] = (int) $value; } elseif (is_scalar($value)) { continue; } elseif ($value instanceof \DateTime) { @@ -366,7 +368,7 @@ public function transaction(\Closure $callback, $attempts = 1) public function beginTransaction() { $transaction = $this->unprepared("START TRANSACTION;"); - if (false !== $transaction) { + if ($transaction) { $this->transactionCount++; } } @@ -382,7 +384,7 @@ public function commit() return; } $transaction = $this->unprepared("COMMIT;"); - if (false !== $transaction) { + if ($transaction) { $this->transactionCount--; } } @@ -398,7 +400,7 @@ public function rollBack() return; } $transaction = $this->unprepared("ROLLBACK;"); - if (false !== $transaction) { + if ($transaction) { $this->transactionCount--; } } From 01ca64194e8e04dbe9ad7a4bfe176443dd82f1af Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Wed, 27 Sep 2023 22:43:33 +0200 Subject: [PATCH 08/67] #6 Some fix --- src/Api/OptionInterface.php | 9 ++++--- src/Api/PostInterface.php | 37 ++++++++++++++------------- src/Api/TermInterface.php | 8 +++--- src/Api/TermRelationshipInterface.php | 8 +++--- src/Api/TermTaxonomyInterface.php | 12 +++++---- src/Api/UserInterface.php | 19 +++++++------- src/Orm/AbstractModel.php | 9 ++----- src/Orm/Database.php | 1 + src/Providers/YesNo.php | 15 +++++++++++ 9 files changed, 70 insertions(+), 48 deletions(-) create mode 100644 src/Providers/YesNo.php diff --git a/src/Api/OptionInterface.php b/src/Api/OptionInterface.php index 4dbeba0..25f768f 100644 --- a/src/Api/OptionInterface.php +++ b/src/Api/OptionInterface.php @@ -8,12 +8,15 @@ namespace Dbout\WpOrm\Api; +use Dbout\WpOrm\Models\Option; +use Dbout\WpOrm\Providers\YesNo; + /** - * @method self setOptionName(string $name) + * @method Option setOptionName(string $name) * @method string getOptionName() - * @method self setOptionValue($value) + * @method Option setOptionValue($value) * @method mixed getOptionValue() - * @method self setAutoload(string $autoload) + * @method Option setAutoload(string|YesNo $autoload) * @method string getAutoload() */ interface OptionInterface diff --git a/src/Api/PostInterface.php b/src/Api/PostInterface.php index 307af88..70a4f7b 100644 --- a/src/Api/PostInterface.php +++ b/src/Api/PostInterface.php @@ -9,45 +9,46 @@ namespace Dbout\WpOrm\Api; use Carbon\Carbon; +use Dbout\WpOrm\Models\Post; /** - * @method self setPostDate($date) + * @method Post setPostDate($date) * @method Carbon|null getPostDate() - * @method self setPostDateGMT($date) + * @method Post setPostDateGMT($date) * @method Carbon|null getPostDateGMT() - * @method self setPostContent(?string $content) + * @method Post setPostContent(?string $content) * @method string|null getPostContent() - * @method self setPostType(string $type) + * @method Post setPostType(string $type) * @method string|null getPostType() - * @method self setGuid(?string $guid) + * @method Post setGuid(?string $guid) * @method string|null getGuid() - * @method self setPostTitle(?string $title) + * @method Post setPostTitle(?string $title) * @method string|null getPostTitle() - * @method self setPostExcerpt(?string $excerpt) + * @method Post setPostExcerpt(?string $excerpt) * @method string|null getPostExcerpt() - * @method self setPostStatus(?string $status) + * @method Post setPostStatus(?string $status) * @method string|null getPostStatus() - * @method self setCommentStatus(string $status) + * @method Post setCommentStatus(string $status) * @method string|null getCommentStatus() - * @method self setPingStatus(string $status) + * @method Post setPingStatus(string $status) * @method string|null getPingStatus() - * @method self setPostPassword(?string $password) + * @method Post setPostPassword(?string $password) * @method string|null getPostPassword() - * @method self setPostName(?string $name) + * @method Post setPostName(?string $name) * @method string|null getPostName() - * @method self setToPing(?string $toPing) + * @method Post setToPing(?string $toPing) * @method string|null getToPing() - * @method self setPinged(?string $pinged) + * @method Post setPinged(?string $pinged) * @method string|null getPinged() - * @method self setPostModified($modified) + * @method Post setPostModified($modified) * @method Carbon|null getPostModified() - * @method self setPostModifiedGMT($modified) + * @method Post setPostModifiedGMT($modified) * @method Carbon|null getPostModifiedGMT() * @method setPostMimeType(?string $mimeType) * @method string|null getPostMimeType() - * @method self setMenuOrder(?int $order) + * @method Post setMenuOrder(?int $order) * @method int|null getMenuOrder() - * @method self setPostContentFiltered($content) + * @method Post setPostContentFiltered($content) * @method string|null getPostContentFiltered() */ interface PostInterface diff --git a/src/Api/TermInterface.php b/src/Api/TermInterface.php index 5fe0706..db72d94 100644 --- a/src/Api/TermInterface.php +++ b/src/Api/TermInterface.php @@ -8,13 +8,15 @@ namespace Dbout\WpOrm\Api; +use Dbout\WpOrm\Models\Term; + /** * @method string|null getName() - * @method self setName(?string $name); + * @method Term setName(?string $name); * @method string|null getSlug() - * @method self setSlug(?string $slug) + * @method Term setSlug(?string $slug) * @method int|null getTermGroup() - * @method self setTermGroup(?int $group) + * @method Term setTermGroup(?int $group) */ interface TermInterface { diff --git a/src/Api/TermRelationshipInterface.php b/src/Api/TermRelationshipInterface.php index 589efbf..b95a2f1 100644 --- a/src/Api/TermRelationshipInterface.php +++ b/src/Api/TermRelationshipInterface.php @@ -8,13 +8,15 @@ namespace Dbout\WpOrm\Api; +use Dbout\WpOrm\Models\TermRelationship; + /** * @method int|null getTermOrder() - * @method self setTermOrder(?int $order) + * @method TermRelationship setTermOrder(?int $order) * @method int|null getTermTaxonomyId() - * @method self setTermTaxonomyId(?int $id) + * @method TermRelationship setTermTaxonomyId(?int $id) * @method int|null getObjectId() - * @method self setObjectId(?int $id) + * @method TermRelationship setObjectId(?int $id) */ interface TermRelationshipInterface { diff --git a/src/Api/TermTaxonomyInterface.php b/src/Api/TermTaxonomyInterface.php index b005bba..2f5d8bd 100644 --- a/src/Api/TermTaxonomyInterface.php +++ b/src/Api/TermTaxonomyInterface.php @@ -8,17 +8,19 @@ namespace Dbout\WpOrm\Api; +use Dbout\WpOrm\Models\TermTaxonomy; + /** * @method int|null getTermId() - * @method self setTermId(int $id) + * @method TermTaxonomy setTermId(int $id) * @method string getTaxonomy() - * @method self setTaxonomy(string $taxonomy) + * @method TermTaxonomy setTaxonomy(string $taxonomy) * @method string|null getDescription() - * @method self setDescription(?string $description) + * @method TermTaxonomy setDescription(?string $description) * @method int|null getParent() - * @method self setParent($parent) + * @method TermTaxonomy setParent($parent) * @method int|null getCount() - * @method self setCount(int $count) + * @method TermTaxonomy setCount(int $count) */ interface TermTaxonomyInterface { diff --git a/src/Api/UserInterface.php b/src/Api/UserInterface.php index 8ed2eb3..cd55a39 100644 --- a/src/Api/UserInterface.php +++ b/src/Api/UserInterface.php @@ -9,26 +9,27 @@ namespace Dbout\WpOrm\Api; use Carbon\Carbon; +use Dbout\WpOrm\Models\User; /** * @method string|null getUserLogin() - * @method self setUserLogin(string $login) + * @method User setUserLogin(string $login) * @method string|null getUserPass() - * @method self setUserPass(string $password) + * @method User setUserPass(string $password) * @method string|null getUserNicename() - * @method self setUserNicename(string $nicename) + * @method User setUserNicename(string $nicename) * @method string|null getUserEmail() - * @method self setUserEmail(string $email) + * @method User setUserEmail(string $email) * @method string|null getUserUrl() - * @method self setUserUrl(?string $url) + * @method User setUserUrl(?string $url) * @method Carbon|null getUserRegistered() - * @method self setUserRegistered($date) + * @method User setUserRegistered($date) * @method string|null getUserActivationKey() - * @method self setUserActivationKey(?string $key) + * @method User setUserActivationKey(?string $key) * @method int getUserStatus() - * @method self setUserStatus(int $status) + * @method User setUserStatus(int $status) * @method string|null getDisplayName() - * @method self setDisplayName(?string $name) + * @method User setDisplayName(?string $name) */ interface UserInterface { diff --git a/src/Orm/AbstractModel.php b/src/Orm/AbstractModel.php index f9471f4..0dd58a8 100644 --- a/src/Orm/AbstractModel.php +++ b/src/Orm/AbstractModel.php @@ -24,7 +24,7 @@ public function __construct(array $attributes = []) } /** - * @return Builder|\Illuminate\Database\Query\Builder + * @inheritDoc */ protected function newBaseQueryBuilder() { @@ -45,18 +45,13 @@ public function getConnection() } /** - * Get table name associated with the model - * Add WordPress table prefix - * - * @return string + * @inheritDoc */ public function getTable(): string { $prefix = $this->getConnection()->getTablePrefix(); if (!empty($this->table)) { - // Ajoute plusieurs fois le suffix, va savoir pourquoi ... - // @todo Corriger le bug ci dessus return str_starts_with($this->table, $prefix) ? $this->table : $prefix . $this->table; } diff --git a/src/Orm/Database.php b/src/Orm/Database.php index ff074ce..48eaf4b 100644 --- a/src/Orm/Database.php +++ b/src/Orm/Database.php @@ -21,6 +21,7 @@ class Database implements ConnectionInterface * @var bool */ public $loggingQueries; + /** * @var \wpdb */ diff --git a/src/Providers/YesNo.php b/src/Providers/YesNo.php new file mode 100644 index 0000000..fb7dde4 --- /dev/null +++ b/src/Providers/YesNo.php @@ -0,0 +1,15 @@ + + */ + +namespace Dbout\WpOrm\Providers; + +enum YesNo: string +{ + case Yes = 'yes'; + case No = 'no'; +} From 57fcf36a0301dbb7c8f6998bd85fbe59064f22d8 Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Mon, 2 Oct 2023 16:40:06 +0200 Subject: [PATCH 09/67] #6 Fix UPDATED_AT & CREATED_AT Post constants --- src/Api/PostInterface.php | 2 -- src/Models/Post.php | 4 ++++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Api/PostInterface.php b/src/Api/PostInterface.php index 70a4f7b..ae0fcbc 100644 --- a/src/Api/PostInterface.php +++ b/src/Api/PostInterface.php @@ -53,8 +53,6 @@ */ interface PostInterface { - public const CREATED_AT = 'post_date'; - public const UPDATED_AT = 'post_modified'; public const POST_ID = 'ID'; public const AUTHOR = 'post_author'; public const DATE = 'post_date'; diff --git a/src/Models/Post.php b/src/Models/Post.php index 0621d95..2307eaa 100644 --- a/src/Models/Post.php +++ b/src/Models/Post.php @@ -30,6 +30,10 @@ class Post extends AbstractModel implements PostInterface { use WithMeta; + public const UPDATED_AT = self::MODIFIED; + + public const CREATED_AT = self::DATE; + /** * @var string */ From 2cc1a56700063c1e6f5f86c29e9218e7e28c0f15 Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Mon, 2 Oct 2023 16:41:19 +0200 Subject: [PATCH 10/67] #6 Fix UPDATED_AT & CREATED_AT User constants --- src/Api/UserInterface.php | 3 --- src/Models/User.php | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Api/UserInterface.php b/src/Api/UserInterface.php index cd55a39..d93784c 100644 --- a/src/Api/UserInterface.php +++ b/src/Api/UserInterface.php @@ -43,7 +43,4 @@ interface UserInterface public const ACTIVATION_KEY = 'user_activation_key'; public const DISPLAY_NAME = 'display_name'; public const STATUS = 'user_status'; - public const CREATED_AT = 'user_registered'; - public const UPDATED_AT = null; - } diff --git a/src/Models/User.php b/src/Models/User.php index 23f4eae..cf0c06d 100644 --- a/src/Models/User.php +++ b/src/Models/User.php @@ -28,6 +28,9 @@ class User extends AbstractModel implements UserInterface { use WithMeta; + public const CREATED_AT = self::REGISTERED; + public const UPDATED_AT = null; + /** * @inheritDoc */ From 7baab1fa60fc4b0c1e0b50f48c19c1ca4c244f7b Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Wed, 4 Oct 2023 22:18:23 +0200 Subject: [PATCH 11/67] Test github workflows --- .github/workflows/php.yml | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 .github/workflows/php.yml diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml new file mode 100644 index 0000000..c83c22b --- /dev/null +++ b/.github/workflows/php.yml @@ -0,0 +1,39 @@ +name: PHP Composer + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + +permissions: + contents: read + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + - name: Validate composer.json and composer.lock + run: composer validate --strict + + - name: Cache Composer packages + id: composer-cache + uses: actions/cache@v3 + with: + path: vendor + key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-php- + + - name: Install dependencies + run: composer install --prefer-dist --no-progress + + # Add a test script to composer.json, for instance: "test": "vendor/bin/phpunit" + # Docs: https://getcomposer.org/doc/articles/scripts.md + + # - name: Run test suite + # run: composer run-script test From 42cabda7c1368cca2b639db50ef979964c1c1a7f Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Sat, 21 Oct 2023 12:43:35 +0200 Subject: [PATCH 12/67] #10 Start fix comment issue --- src/Api/CommentInterface.php | 217 +++++++++++++++++++++++++++++++---- src/Models/Comment.php | 3 - 2 files changed, 195 insertions(+), 25 deletions(-) diff --git a/src/Api/CommentInterface.php b/src/Api/CommentInterface.php index 0213ec4..5be62c7 100644 --- a/src/Api/CommentInterface.php +++ b/src/Api/CommentInterface.php @@ -10,30 +10,38 @@ use Carbon\Carbon; use Dbout\WpOrm\Models\Comment; +use Dbout\WpOrm\Models\Post; +use Dbout\WpOrm\Models\User; /** - * @method Comment setAuthor(string $author) - * @method string|null getAuthor() - * @method Comment setAuthorEmail(string $email) - * @method string|null getAuthorEmail() - * @method Comment setAuthorUrl(?string $url) - * @method string|null getAuthorUrl() - * @method Comment setAuthorIp(?string $ip) - * @method string|null getAuthorIp() - * @method Comment setDate($date) - * @method Carbon|null getDate() - * @method Comment setDateGMT($date) - * @method Carbon|null getDateGMT() - * @method Comment setContent(string $content) - * @method string|null getContent() - * @method Comment setKarma(int $karma) - * @method int|null getKarma() - * @method Comment setAgent(string $agent) - * @method string|null getAgent() - * @method Comment setType(?string $type) - * @method string|null getType() - * @method Comment setApproved(string $approved) - * @method string|null getApproved() + * @method Comment setCommentAuthor(?string $author) + * @method string|null getCommentAuthor() + * @method Comment setCommentAuthorEmail(?string $email) + * @method string|null getCommentAuthorEmail() + * @method Comment setCommentAuthorUrl(?string $url) + * @method string|null getCommentAuthorUrl() + * @method Comment setCommentAuthorIP(?string $ip) + * @method string|null getCommentAuthorIP() + * @method Comment setCommentContent(?string $content) + * @method string|null getCommentContent() + * @method Comment setCommentKarma(?int $karma) + * @method int|null getCommentKarma() + * @method Comment setCommentApproved(string $approved) + * @method string getCommentApproved() + * @method Comment setCommentAgent(?string $agent) + * @method string|null getCommentAgent() + * @method Comment setCommentType(?string $type) + * @method string|null getCommentType() + * @method Comment setUserId(?int $userId) + * @method int|null getUserId() + * @method Comment setCommentDate(mixed $date) + * @method Carbon|null getCommentDate() + * @method Comment setCommentDateGmt(mixed $date) + * @method Carbon|null getCommentDateGmt() + * + * @property User|null $user + * @property Post|null $post + * @property Comment|null $parent */ interface CommentInterface { @@ -52,4 +60,169 @@ interface CommentInterface public const TYPE = 'comment_type'; public const PARENT = 'comment_parent'; public const USER_ID = 'user_id'; + + /** + * @param string $author + * @return self + * @deprecated Remove in next version + * @see setCommentAuthor() + */ + public function setAuthor(string $author): self; + + /** + * @return string|null + * @deprecated Remove in next version + * @see getCommentAuthor() + */ + public function getAuthor(): ?string; + + /** + * @param string|null $email + * @return self + * @deprecated Remove in next version + * @see setCommentAuthorEmail() + */ + public function setAuthorEmail(?string $email): self; + + /** + * @return string|null + * @deprecated Remove in next version + * @see getCommentAuthorEmail() + */ + public function getAuthorEmail(): ?string; + + /** + * @param string|null $url + * @return self + * @deprecated Remove in next version + * @see setCommentAuthorUrl() + */ + public function setAuthorUrl(?string $url): self; + + /** + * @return string|null + * @deprecated Remove in next version + * @see getCommentAuthorUrl() + */ + public function getAuthorUrl(): ?string; + + /** + * @param string|null $ip + * @return self + * @deprecated Remove in next version + * @see setCommentAuthorIP() + */ + public function setAuthorIp(?string $ip): self; + + /** + * @return string|null + * @deprecated Remove in next version + * @see getCommentAuthorIP() + */ + public function getAuthorIp(): ?string; + + /** + * @param string|null $content + * @return self + * @deprecated Remove in next version + * @see setCommentContent() + */ + public function setContent(?string $content): self; + + /** + * @return string|null + * @deprecated Remove in next version + * @see gsetCommentContent() + */ + public function getContent(): ?string; + + /** + * @param int|null $karma + * @return self + * @deprecated Remove in next version + * @see setCommentKarma() + */ + public function setKarma(?int $karma): self; + + /** + * @return int|null + * @deprecated Remove in next version + * @see getCommentKarma() + */ + public function getKarma(): ?int; + + /** + * @param string|null $agent + * @return self + * @deprecated Remove in next version + * @see setCommentAgent() + */ + public function setAgent(?string $agent): self; + + /** + * @return string|null + * @deprecated Remove in next version + * @see getCommentAgent() + */ + public function getAgent(): ?string; + + /** + * @param string|null $type + * @return self + * @deprecated Remove in next version + * @see setCommentType() + */ + public function setType(?string $type): self; + + /** + * @return string|null + * @deprecated Remove in next version + * @see getCommentType() + */ + public function getType(): ?string; + + /** + * @param string|null $approved + * @return self + * @deprecated Remove in next version + * @see setCommentApproved() + */ + public function setApproved(?string $approved): self; + + /** + * @return string|null + * @deprecated Remove in next version + * @see getCommentApproved() + */ + public function getApproved(): ?string; + + /** + * @param mixed $date + * @return self + * @deprecated Remove in next version + * @see setCommentDate() + */ + public function setDate(mixed $date): self; + + /** + * @return Carbon|null + * @deprecated Remove in next version + * @see getCommentDate() + */ + public function getDate(): ?Carbon; + + /** + * @param mixed $date + * @return self + * @deprecated Remove in next version + * @see setCommentDateGmt() + */ + public function setDateGMT(mixed $date): self; + + /** + * @return Carbon|null + * @deprecated Remove in next version + * @see getCommentDateGmt() + */ + public function getDateGMT(): ?Carbon; } diff --git a/src/Models/Comment.php b/src/Models/Comment.php index abf210d..3affde6 100644 --- a/src/Models/Comment.php +++ b/src/Models/Comment.php @@ -18,9 +18,6 @@ /** * @method static Comment|null find(int $commentId) * @method static CommentBuilder query() - * @property User|null $user - * @property Post|null $post - * @property Comment|null $parent */ class Comment extends AbstractModel implements CommentInterface { From 9fbe26aeb61fd2d4a963a81822362c853adf0d38 Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Sat, 21 Oct 2023 20:13:16 +0200 Subject: [PATCH 13/67] #10 Implement comment deprecated functions --- src/Models/Comment.php | 177 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) diff --git a/src/Models/Comment.php b/src/Models/Comment.php index 3affde6..f734f49 100644 --- a/src/Models/Comment.php +++ b/src/Models/Comment.php @@ -8,6 +8,7 @@ namespace Dbout\WpOrm\Models; +use Carbon\Carbon; use Dbout\WpOrm\Api\CommentInterface; use Dbout\WpOrm\Api\PostInterface; use Dbout\WpOrm\Api\UserInterface; @@ -74,4 +75,180 @@ public function newEloquentBuilder($query): CommentBuilder { return new CommentBuilder($query); } + + /** + * @inheritDoc + */ + public function setAuthor(string $author): CommentInterface + { + return $this->setCommentAuthor($author); + } + + /** + * @inheritDoc + */ + public function getAuthor(): ?string + { + return $this->getCommentAuthor(); + } + + /** + * @inheritDoc + */ + public function setAuthorEmail(?string $email): CommentInterface + { + return $this->setCommentAuthorEmail($email); + } + + /** + * @inheritDoc + */ + public function getAuthorEmail(): ?string + { + return $this->getCommentAuthorEmail(); + } + + /** + * @inheritDoc + */ + public function setAuthorUrl(?string $url): CommentInterface + { + return $this->setCommentAuthorUrl($url); + } + + /** + * @inheritDoc + */ + public function getAuthorUrl(): ?string + { + return $this->getCommentAuthorUrl(); + } + + /** + * @inheritDoc + */ + public function setAuthorIp(?string $ip): CommentInterface + { + return $this->setCommentAuthorIP($ip); + } + + /** + * @inheritDoc + */ + public function getAuthorIp(): ?string + { + return $this->getCommentAuthorIP(); + } + + /** + * @inheritDoc + */ + public function setContent(?string $content): CommentInterface + { + return $this->setCommentContent($content); + } + + /** + * @inheritDoc + */ + public function getContent(): ?string + { + return $this->getCommentContent(); + } + + /** + * @inheritDoc + */ + public function setKarma(?int $karma): CommentInterface + { + return $this->setCommentKarma($karma); + } + + /** + * @inheritDoc + */ + public function getKarma(): ?int + { + return $this->getCommentKarma(); + } + + /** + * @inheritDoc + */ + public function setAgent(?string $agent): CommentInterface + { + return $this->setCommentAgent($agent); + } + + /** + * @inheritDoc + */ + public function getAgent(): ?string + { + return $this->getCommentAgent(); + } + + /** + * @inheritDoc + */ + public function setType(?string $type): CommentInterface + { + return $this->setCommentType($type); + } + + /** + * @inheritDoc + */ + public function getType(): ?string + { + return $this->getCommentType(); + } + + /** + * @inheritDoc + */ + public function setApproved(?string $approved): CommentInterface + { + return $this->setCommentApproved($approved); + } + + /** + * @inheritDoc + */ + public function getApproved(): ?string + { + return $this->getCommentApproved(); + } + + /** + * @inheritDoc + */ + public function setDate(mixed $date): CommentInterface + { + return $this->setCommentDate($date); + } + + /** + * @inheritDoc + */ + public function getDate(): ?Carbon + { + return $this->getCommentDate(); + } + + /** + * @inheritDoc + */ + public function setDateGMT(mixed $date): CommentInterface + { + return $this->setCommentDateGmt($date); + } + + /** + * @inheritDoc + */ + public function getDateGMT(): ?Carbon + { + return $this->getCommentDateGmt(); + } } From 9b3bf90f7ae56a6c716aca84bb3e45dc541e8fe1 Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Sat, 28 Oct 2023 12:08:04 +0200 Subject: [PATCH 14/67] #11 Replace $cast date by datetime in Comment, Post and User models --- src/Models/Comment.php | 4 ++-- src/Models/Post.php | 8 ++++---- src/Models/User.php | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Models/Comment.php b/src/Models/Comment.php index f734f49..05b932d 100644 --- a/src/Models/Comment.php +++ b/src/Models/Comment.php @@ -40,8 +40,8 @@ class Comment extends AbstractModel implements CommentInterface */ protected $casts = [ self::KARMA => 'integer', - self::DATE_GMT => 'date', - self::DATE => 'date', + self::DATE_GMT => 'datetime', + self::DATE => 'datetime', ]; /** diff --git a/src/Models/Post.php b/src/Models/Post.php index 2307eaa..94b676d 100644 --- a/src/Models/Post.php +++ b/src/Models/Post.php @@ -55,10 +55,10 @@ class Post extends AbstractModel implements PostInterface protected $casts = [ self::MENU_ORDER => 'integer', self::COMMENT_COUNT => 'integer', - self::DATE => 'date', - self::MODIFIED => 'date', - self::DATE_GMT => 'date', - self::MODIFIED_GMT => 'date', + self::DATE => 'datetime', + self::MODIFIED => 'datetime', + self::DATE_GMT => 'datetime', + self::MODIFIED_GMT => 'datetime', ]; /** diff --git a/src/Models/User.php b/src/Models/User.php index cf0c06d..be60399 100644 --- a/src/Models/User.php +++ b/src/Models/User.php @@ -41,7 +41,7 @@ class User extends AbstractModel implements UserInterface */ protected $casts = [ self::STATUS => 'integer', - self::REGISTERED => 'date', + self::REGISTERED => 'datetime', ]; /** From a10b6e71feaca07f3c56137848c35aefafb1b482 Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Sun, 5 Nov 2023 18:39:37 +0100 Subject: [PATCH 15/67] #12 Add User helpers --- src/Api/UserInterface.php | 16 ++++++++++++++++ src/Models/User.php | 18 +++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/Api/UserInterface.php b/src/Api/UserInterface.php index d93784c..3bd4949 100644 --- a/src/Api/UserInterface.php +++ b/src/Api/UserInterface.php @@ -43,4 +43,20 @@ interface UserInterface public const ACTIVATION_KEY = 'user_activation_key'; public const DISPLAY_NAME = 'display_name'; public const STATUS = 'user_status'; + + /** + * Find user by email + * + * @param string $email + * @return self|null + */ + public static function findByEmail(string $email): ?self; + + /** + * Find user by login + * + * @param string $login + * @return self|null + */ + public static function findByLogin(string $login): ?self; } diff --git a/src/Models/User.php b/src/Models/User.php index be60399..3e7a8eb 100644 --- a/src/Models/User.php +++ b/src/Models/User.php @@ -21,7 +21,7 @@ * @method static User|null find($userId) * @method static UserBuilder query() * @property UserMeta[] $metas - * @property Comment $comments + * @property Comment[] $comments * @property Post[] $posts */ class User extends AbstractModel implements UserInterface @@ -88,4 +88,20 @@ public function getMetaClass(): string { return \Dbout\WpOrm\Models\Meta\UserMeta::class; } + + /** + * @inheritDoc + */ + public static function findByEmail(string $email): ?self + { + return self::query()->firstWhere(self::EMAIL, $email); + } + + /** + * @inheritDoc + */ + public static function findByLogin(string $login): ?self + { + return self::query()->firstWhere(self::LOGIN, $login); + } } From 6bb69354eeae302f8bf79febd2edf7503633b992 Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Sun, 5 Nov 2023 18:50:11 +0100 Subject: [PATCH 16/67] #12 Add Option helpers --- src/Api/OptionInterface.php | 8 ++++++++ src/Models/Option.php | 25 +++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/src/Api/OptionInterface.php b/src/Api/OptionInterface.php index 25f768f..4090299 100644 --- a/src/Api/OptionInterface.php +++ b/src/Api/OptionInterface.php @@ -25,4 +25,12 @@ interface OptionInterface public const NAME = 'option_name'; public const VALUE = 'option_value'; public const AUTOLOAD = 'autoload'; + + /** + * Find option by name + * + * @param string $optionName + * @return self|null + */ + public static function findByName(string $optionName): ?self; } diff --git a/src/Models/Option.php b/src/Models/Option.php index a9e8690..76b5d8d 100644 --- a/src/Models/Option.php +++ b/src/Models/Option.php @@ -11,10 +11,13 @@ use Dbout\WpOrm\Api\OptionInterface; use Dbout\WpOrm\Builders\OptionBuilder; use Dbout\WpOrm\Orm\AbstractModel; +use Dbout\WpOrm\Providers\YesNo; /** * @method static Option|null find($optionId) * @method static OptionBuilder query() + * @method static OptionBuilder autoload(bool|YesNo $autoload = YesNo::Yes) + * @method OptionBuilder autoload(bool|YesNo $autoload = YesNo::Yes) */ class Option extends AbstractModel implements OptionInterface { @@ -47,4 +50,26 @@ public function newEloquentBuilder($query): OptionBuilder { return new OptionBuilder($query); } + + /** + * @inheritDoc + */ + public static function findByName(string $optionName): ?self + { + return self::query()->firstWhere(self::NAME, $optionName); + } + + /** + * @param OptionBuilder $builder + * @param bool|YesNo $autoload + * @return void + */ + public function scopeAutoload(OptionBuilder $builder, bool|YesNo $autoload = YesNo::Yes): void + { + if (is_bool($autoload)) { + $autoload = $autoload ? YesNo::Yes : YesNo::No; + } + + $builder->where(self::AUTOLOAD, $autoload->value); + } } From d9eca33213fb1676cca03658a00344639a644f0a Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Sun, 5 Nov 2023 19:01:56 +0100 Subject: [PATCH 17/67] #12 Add Attachment helpers --- src/Models/Attachment.php | 20 ++++++++++++++++++++ src/Models/Option.php | 5 ++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/Models/Attachment.php b/src/Models/Attachment.php index 60420ee..43d0366 100644 --- a/src/Models/Attachment.php +++ b/src/Models/Attachment.php @@ -8,10 +8,30 @@ namespace Dbout\WpOrm\Models; +use Dbout\WpOrm\Builders\PostBuilder; + +/** + * @method static|PostBuilder mimeType(string|array $type) + */ class Attachment extends CustomPost { /** * @inheritDoc */ protected string $_type = 'attachment'; + + /** + * @param PostBuilder $builder + * @param ...$types + * @return void + */ + protected function scopeMimeType(PostBuilder $builder, ...$types): void + { + $firstValue = reset($types); + if (is_array($firstValue)) { + $builder->whereIn(self::MIME_TYPE, $firstValue); + } else { + $builder->where(self::MIME_TYPE, $firstValue); + } + } } diff --git a/src/Models/Option.php b/src/Models/Option.php index 76b5d8d..864d311 100644 --- a/src/Models/Option.php +++ b/src/Models/Option.php @@ -16,8 +16,7 @@ /** * @method static Option|null find($optionId) * @method static OptionBuilder query() - * @method static OptionBuilder autoload(bool|YesNo $autoload = YesNo::Yes) - * @method OptionBuilder autoload(bool|YesNo $autoload = YesNo::Yes) + * @method static|OptionBuilder autoload(bool|YesNo $autoload = YesNo::Yes) */ class Option extends AbstractModel implements OptionInterface { @@ -64,7 +63,7 @@ public static function findByName(string $optionName): ?self * @param bool|YesNo $autoload * @return void */ - public function scopeAutoload(OptionBuilder $builder, bool|YesNo $autoload = YesNo::Yes): void + protected function scopeAutoload(OptionBuilder $builder, bool|YesNo $autoload = YesNo::Yes): void { if (is_bool($autoload)) { $autoload = $autoload ? YesNo::Yes : YesNo::No; From f295ecfcf96ca391236c523e945b6175616163a4 Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Sun, 5 Nov 2023 19:19:21 +0100 Subject: [PATCH 18/67] #12 CS --- src/Models/Post.php | 2 +- src/Models/User.php | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/Models/Post.php b/src/Models/Post.php index 94b676d..2c540c6 100644 --- a/src/Models/Post.php +++ b/src/Models/Post.php @@ -99,7 +99,7 @@ public function newEloquentBuilder($query): PostBuilder } /** - * @inerhitDoc + * @inheritDoc */ public function getMetaClass(): string { diff --git a/src/Models/User.php b/src/Models/User.php index 3e7a8eb..7291529 100644 --- a/src/Models/User.php +++ b/src/Models/User.php @@ -53,8 +53,15 @@ class User extends AbstractModel implements UserInterface * @inheritDoc */ protected $fillable = [ - self::LOGIN, self::PASSWORD, self::NICE_NAME, self::EMAIL, self::URL, self::REGISTERED, self::ACTIVATION_KEY, - self::DISPLAY_NAME, self::STATUS, + self::LOGIN, + self::PASSWORD, + self::NICE_NAME, + self::EMAIL, + self::URL, + self::REGISTERED, + self::ACTIVATION_KEY, + self::DISPLAY_NAME, + self::STATUS, ]; /** @@ -82,7 +89,7 @@ public function newEloquentBuilder($query): UserBuilder } /** - * @inerhitDoc + * @inheritDoc */ public function getMetaClass(): string { From acd66c3131b019e316a56a0b4c6cacd71f04e849 Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Sun, 5 Nov 2023 19:52:08 +0100 Subject: [PATCH 19/67] Update Doc --- README.md | 62 +++++++++++++++++------------------ doc/migration-with-bedrock.md | 35 -------------------- doc/migration.md | 55 +++++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+), 67 deletions(-) delete mode 100644 doc/migration-with-bedrock.md create mode 100644 doc/migration.md diff --git a/README.md b/README.md index 67f2a6c..1ec8ceb 100644 --- a/README.md +++ b/README.md @@ -5,25 +5,44 @@ The ORM is based on [Eloquent ORM](https://laravel.com/docs/8.x/eloquent) and us The ORM also offers a system to simply manage database migrations based on [Phinx](https://phinx.org/). -Requirements --------- +💡 To simplify the integration of this library, we recommend using Wordpress with one of the following tools: [Bedrock](https://roots.io/bedrock/), [Themosis](https://framework.themosis.com/) or [Wordplate](https://github.com/wordplate/wordplate#readme). -The server requirements are basically the same as for [WordPress](https://wordpress.org/about/requirements/) with the addition of a few ones : +### Features : -- PHP >= 7.4 -- [Composer](https://getcomposer.org/) ❤️ +- ✅ Support core WordPress models: `Comment`, `Option`, `Post`, `TermTaxonomy`, `Term`, `User`, `PostMeta` and `UserMeta`. +- ✅ Support core WordPress post type: `Article`, `Attachment` and `Page`. +- ✅ Based on core Wordpress database connection (`wpdb` class) +- ✅ Migration with `Phinx` library. +- ❤️ Easy integration of a custom post type and comment. +- ❤️ Easy model creation for projects with custom tables -> To simplify the integration of this library, we recommend using Wordpress with one of the following tools: [Bedrock](https://roots.io/bedrock/), [Themosis](https://framework.themosis.com/) or [Wordplate](https://github.com/wordplate/wordplate#readme). +### Documentations : -Installation --------- +- [Requirements](#requirements) +- [Installation](#installation) +- [Migrations](doc/migration.md) + +## Requirements + +The server requirements are basically the same as for [WordPress](https://wordpress.org/about/requirements/) with the addition of a few ones : + +- PHP >= 8.1 +- [Composer](https://getcomposer.org/) +## Installation -Install with composer, in the root of the Wordpress project run: +You can use [Composer](https://getcomposer.org/). Follow the [installation instructions](https://getcomposer.org/doc/00-intro.md) if you do not already have composer installed. -```bash +~~~bash composer require dbout/wp-orm -``` +~~~ + +In your PHP script, make sure you include the autoloader: + +~~~php +require __DIR__ . '/vendor/autoload.php'; +~~~ + Basic usage with core Wordpress models -------- @@ -48,25 +67,4 @@ $pages = \Dbout\WpOrm\Models\Page::query() $pages = \Dbout\WpOrm\Models\Page::query() ->whereStatus('publish') ->get(); -``` - - -### Migration - -To use phinx, you must create a configuration file named `config-phinx.php` at the root of your project. To create this file, please see one of the following documentation: - -- [Create config-phinx.php file for Bedrock Framework](doc/migration-with-bedrock.md) - -If you would like to learn more about the configuration file, please visit [Phinx - Configuration](https://phinx.readthedocs.io/en/latest/configuration.html). - -#### Create new migration : - -```bash -php vendor/bin/phinx create -c config-phinx.php -``` - -#### Run migration : - -```bash -php vendor/bin/phinx migrate -c config-phinx.php ``` \ No newline at end of file diff --git a/doc/migration-with-bedrock.md b/doc/migration-with-bedrock.md deleted file mode 100644 index 689807f..0000000 --- a/doc/migration-with-bedrock.md +++ /dev/null @@ -1,35 +0,0 @@ -# Migration with Bedrock : - -If you are using the [Bedrock](https://roots.io/bedrock/) framework, please create a file named `config-phinx.php` at the root of your project and copy the following content. Remember to replace the following values : - -- {YOUR_WP_DIR} : Wordpress directory -- {YOUR_MIGRATIONS_DIR} : Folder where migrations are saved - -```php - '{YOUR_MIGRATIONS_DIR}', - 'db_user' => DB_USER, - 'db_password' => DB_PASSWORD, - 'db_name' => DB_NAME, - 'db_host' => DB_HOST, -]); -`` \ No newline at end of file diff --git a/doc/migration.md b/doc/migration.md new file mode 100644 index 0000000..f87c59d --- /dev/null +++ b/doc/migration.md @@ -0,0 +1,55 @@ +# Migration + +To use phinx, you must create a configuration file named `config-phinx.php` at the root of your project. To create this file, please see one of the following documentation: + +- [Create config-phinx.php file for Bedrock Framework](#bedrock-support) + +If you would like to learn more about the configuration file, please visit [Phinx - Configuration](https://phinx.readthedocs.io/en/latest/configuration.html). + +#### Create new migration : + +~~~bash +php vendor/bin/phinx create -c config-phinx.php +~~~ + +#### Run migration : + +~~~bash +php vendor/bin/phinx migrate -c config-phinx.php +~~~ + +## Bedrock support + +If you are using the [Bedrock](https://roots.io/bedrock/) framework, please create a file named `config-phinx.php` at the root of your project and copy the following content. + +~~~php + 'YOUR_MIGRATIONS_DIR', + 'db_user' => DB_USER, + 'db_password' => DB_PASSWORD, + 'db_name' => DB_NAME, + 'db_host' => DB_HOST, +]); +~~~ \ No newline at end of file From c8df7f1bb26a9921cf00e983d0d6a40a9788c54c Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Sat, 13 Jan 2024 22:38:44 +0100 Subject: [PATCH 20/67] Add some scopes, CS --- .php-cs-fixer.php | 2 +- src/Api/CommentInterface.php | 2 +- src/Api/OptionInterface.php | 8 +- src/Api/PostInterface.php | 2 +- src/Api/TermInterface.php | 2 +- src/Api/TermRelationshipInterface.php | 2 +- src/Api/TermTaxonomyInterface.php | 2 +- src/Api/UserInterface.php | 2 +- src/Builders/AbstractBuilder.php | 2 +- src/Builders/CommentBuilder.php | 2 +- src/Builders/OptionBuilder.php | 2 +- src/Builders/PostBuilder.php | 2 +- src/Builders/TermBuilder.php | 2 +- src/Builders/Traits/WithMeta.php | 2 +- src/Builders/UserBuilder.php | 2 +- src/{Providers => Enums}/PingStatus.php | 4 +- src/{Providers => Enums}/PostStatus.php | 4 +- src/{Providers => Enums}/YesNo.php | 4 +- src/Exceptions/MetaNotSupportedException.php | 2 +- src/Exceptions/NotAllowedException.php | 2 +- src/Migration/Config.php | 2 +- src/Models/Article.php | 2 +- src/Models/Attachment.php | 2 +- src/Models/Comment.php | 17 +++- src/Models/CustomComment.php | 2 +- src/Models/CustomPost.php | 5 +- src/Models/Meta/AbstractMeta.php | 2 +- src/Models/Meta/MetaInterface.php | 2 +- src/Models/Meta/PostMeta.php | 2 +- src/Models/Meta/UserMeta.php | 2 +- src/Models/Meta/WithMeta.php | 2 +- src/Models/Option.php | 15 ++-- src/Models/Page.php | 2 +- src/Models/Post.php | 86 ++++++++++++++++++-- src/Models/Term.php | 7 +- src/Models/TermRelationship.php | 2 +- src/Models/TermTaxonomy.php | 9 +- src/Models/Traits/HasCustomType.php | 2 +- src/Models/User.php | 10 ++- src/Orm/AbstractModel.php | 2 +- src/Orm/Builder.php | 2 +- src/Orm/Database.php | 2 +- src/Orm/Resolver.php | 2 +- src/Scopes/CustomPostAddTypeScope.php | 2 +- src/includes/migrations.php | 2 +- 45 files changed, 169 insertions(+), 68 deletions(-) rename src/{Providers => Enums}/PingStatus.php (68%) rename src/{Providers => Enums}/PostStatus.php (82%) rename src/{Providers => Enums}/YesNo.php (67%) diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php index 0981160..87a7e94 100644 --- a/.php-cs-fixer.php +++ b/.php-cs-fixer.php @@ -14,7 +14,7 @@ ; $header = << diff --git a/src/Api/CommentInterface.php b/src/Api/CommentInterface.php index 5be62c7..3451b1c 100644 --- a/src/Api/CommentInterface.php +++ b/src/Api/CommentInterface.php @@ -1,6 +1,6 @@ diff --git a/src/Api/OptionInterface.php b/src/Api/OptionInterface.php index 4090299..7d0e714 100644 --- a/src/Api/OptionInterface.php +++ b/src/Api/OptionInterface.php @@ -1,6 +1,6 @@ @@ -8,8 +8,8 @@ namespace Dbout\WpOrm\Api; +use Dbout\WpOrm\Enums\YesNo; use Dbout\WpOrm\Models\Option; -use Dbout\WpOrm\Providers\YesNo; /** * @method Option setOptionName(string $name) @@ -27,10 +27,10 @@ interface OptionInterface public const AUTOLOAD = 'autoload'; /** - * Find option by name + * Find one option by name * * @param string $optionName * @return self|null */ - public static function findByName(string $optionName): ?self; + public static function findOneByName(string $optionName): ?self; } diff --git a/src/Api/PostInterface.php b/src/Api/PostInterface.php index ae0fcbc..9af1ce3 100644 --- a/src/Api/PostInterface.php +++ b/src/Api/PostInterface.php @@ -1,6 +1,6 @@ diff --git a/src/Api/TermInterface.php b/src/Api/TermInterface.php index db72d94..d71d770 100644 --- a/src/Api/TermInterface.php +++ b/src/Api/TermInterface.php @@ -1,6 +1,6 @@ diff --git a/src/Api/TermRelationshipInterface.php b/src/Api/TermRelationshipInterface.php index b95a2f1..d2e09c5 100644 --- a/src/Api/TermRelationshipInterface.php +++ b/src/Api/TermRelationshipInterface.php @@ -1,6 +1,6 @@ diff --git a/src/Api/TermTaxonomyInterface.php b/src/Api/TermTaxonomyInterface.php index 2f5d8bd..3994f0e 100644 --- a/src/Api/TermTaxonomyInterface.php +++ b/src/Api/TermTaxonomyInterface.php @@ -1,6 +1,6 @@ diff --git a/src/Api/UserInterface.php b/src/Api/UserInterface.php index 3bd4949..3c4a561 100644 --- a/src/Api/UserInterface.php +++ b/src/Api/UserInterface.php @@ -1,6 +1,6 @@ diff --git a/src/Builders/AbstractBuilder.php b/src/Builders/AbstractBuilder.php index 57b8de9..acb0145 100644 --- a/src/Builders/AbstractBuilder.php +++ b/src/Builders/AbstractBuilder.php @@ -1,6 +1,6 @@ diff --git a/src/Builders/CommentBuilder.php b/src/Builders/CommentBuilder.php index 902698d..0e75466 100644 --- a/src/Builders/CommentBuilder.php +++ b/src/Builders/CommentBuilder.php @@ -1,6 +1,6 @@ diff --git a/src/Builders/OptionBuilder.php b/src/Builders/OptionBuilder.php index 2c2d1e0..879bed2 100644 --- a/src/Builders/OptionBuilder.php +++ b/src/Builders/OptionBuilder.php @@ -1,6 +1,6 @@ diff --git a/src/Builders/PostBuilder.php b/src/Builders/PostBuilder.php index 8061350..8e4981d 100644 --- a/src/Builders/PostBuilder.php +++ b/src/Builders/PostBuilder.php @@ -1,6 +1,6 @@ diff --git a/src/Builders/TermBuilder.php b/src/Builders/TermBuilder.php index 6ab8eff..2925ebd 100644 --- a/src/Builders/TermBuilder.php +++ b/src/Builders/TermBuilder.php @@ -1,6 +1,6 @@ diff --git a/src/Builders/Traits/WithMeta.php b/src/Builders/Traits/WithMeta.php index 17301ce..bc2b9dd 100644 --- a/src/Builders/Traits/WithMeta.php +++ b/src/Builders/Traits/WithMeta.php @@ -1,6 +1,6 @@ diff --git a/src/Builders/UserBuilder.php b/src/Builders/UserBuilder.php index f9bb3b8..f290930 100644 --- a/src/Builders/UserBuilder.php +++ b/src/Builders/UserBuilder.php @@ -1,6 +1,6 @@ diff --git a/src/Providers/PingStatus.php b/src/Enums/PingStatus.php similarity index 68% rename from src/Providers/PingStatus.php rename to src/Enums/PingStatus.php index 0790c2d..f11cb95 100644 --- a/src/Providers/PingStatus.php +++ b/src/Enums/PingStatus.php @@ -1,12 +1,12 @@ */ -namespace Dbout\WpOrm\Providers; +namespace Dbout\WpOrm\Enums; enum PingStatus: string { diff --git a/src/Providers/PostStatus.php b/src/Enums/PostStatus.php similarity index 82% rename from src/Providers/PostStatus.php rename to src/Enums/PostStatus.php index 91672b8..1da17b9 100644 --- a/src/Providers/PostStatus.php +++ b/src/Enums/PostStatus.php @@ -1,12 +1,12 @@ */ -namespace Dbout\WpOrm\Providers; +namespace Dbout\WpOrm\Enums; /** * @see https://wordpress.org/documentation/article/post-status/ diff --git a/src/Providers/YesNo.php b/src/Enums/YesNo.php similarity index 67% rename from src/Providers/YesNo.php rename to src/Enums/YesNo.php index fb7dde4..d13a84e 100644 --- a/src/Providers/YesNo.php +++ b/src/Enums/YesNo.php @@ -1,12 +1,12 @@ */ -namespace Dbout\WpOrm\Providers; +namespace Dbout\WpOrm\Enums; enum YesNo: string { diff --git a/src/Exceptions/MetaNotSupportedException.php b/src/Exceptions/MetaNotSupportedException.php index 352ff71..71aff67 100644 --- a/src/Exceptions/MetaNotSupportedException.php +++ b/src/Exceptions/MetaNotSupportedException.php @@ -1,6 +1,6 @@ diff --git a/src/Exceptions/NotAllowedException.php b/src/Exceptions/NotAllowedException.php index e659a2f..3d4d07e 100644 --- a/src/Exceptions/NotAllowedException.php +++ b/src/Exceptions/NotAllowedException.php @@ -1,6 +1,6 @@ diff --git a/src/Migration/Config.php b/src/Migration/Config.php index a76108c..1ef8c27 100644 --- a/src/Migration/Config.php +++ b/src/Migration/Config.php @@ -1,6 +1,6 @@ diff --git a/src/Models/Article.php b/src/Models/Article.php index 05f932e..d77d1de 100644 --- a/src/Models/Article.php +++ b/src/Models/Article.php @@ -1,6 +1,6 @@ diff --git a/src/Models/Attachment.php b/src/Models/Attachment.php index 43d0366..5785bfb 100644 --- a/src/Models/Attachment.php +++ b/src/Models/Attachment.php @@ -1,6 +1,6 @@ diff --git a/src/Models/Comment.php b/src/Models/Comment.php index 05b932d..6c5ad8e 100644 --- a/src/Models/Comment.php +++ b/src/Models/Comment.php @@ -1,6 +1,6 @@ @@ -19,6 +19,7 @@ /** * @method static Comment|null find(int $commentId) * @method static CommentBuilder query() + * @method static|CommentBuilder user(int|User $user) */ class Comment extends AbstractModel implements CommentInterface { @@ -251,4 +252,18 @@ public function getDateGMT(): ?Carbon { return $this->getCommentDateGmt(); } + + /** + * @param CommentBuilder $builder + * @param int|User $user + * @return void + */ + public function scopeUser(CommentBuilder $builder, int|User $user): void + { + if ($user instanceof User) { + $user = $user->getId(); + } + + $builder->where(self::USER_ID, $user); + } } diff --git a/src/Models/CustomComment.php b/src/Models/CustomComment.php index 348067c..6c9f684 100644 --- a/src/Models/CustomComment.php +++ b/src/Models/CustomComment.php @@ -1,6 +1,6 @@ diff --git a/src/Models/CustomPost.php b/src/Models/CustomPost.php index 0e4cca5..b1a87b8 100644 --- a/src/Models/CustomPost.php +++ b/src/Models/CustomPost.php @@ -1,6 +1,6 @@ @@ -16,7 +16,6 @@ abstract class CustomPost extends Post use HasCustomType; /** - * CustomPost constructor. * @param array $attributes */ public function __construct(array $attributes = []) @@ -29,7 +28,7 @@ public function __construct(array $attributes = []) } /** - * @return void + * @inheritDoc */ protected static function booted() { diff --git a/src/Models/Meta/AbstractMeta.php b/src/Models/Meta/AbstractMeta.php index ccf8014..457e454 100644 --- a/src/Models/Meta/AbstractMeta.php +++ b/src/Models/Meta/AbstractMeta.php @@ -1,6 +1,6 @@ diff --git a/src/Models/Meta/MetaInterface.php b/src/Models/Meta/MetaInterface.php index 764e299..52cd399 100644 --- a/src/Models/Meta/MetaInterface.php +++ b/src/Models/Meta/MetaInterface.php @@ -1,6 +1,6 @@ diff --git a/src/Models/Meta/PostMeta.php b/src/Models/Meta/PostMeta.php index ceff27c..500421b 100644 --- a/src/Models/Meta/PostMeta.php +++ b/src/Models/Meta/PostMeta.php @@ -1,6 +1,6 @@ diff --git a/src/Models/Meta/UserMeta.php b/src/Models/Meta/UserMeta.php index 5eb3c81..2d032e9 100644 --- a/src/Models/Meta/UserMeta.php +++ b/src/Models/Meta/UserMeta.php @@ -1,6 +1,6 @@ diff --git a/src/Models/Meta/WithMeta.php b/src/Models/Meta/WithMeta.php index a637e06..b2c6581 100644 --- a/src/Models/Meta/WithMeta.php +++ b/src/Models/Meta/WithMeta.php @@ -1,6 +1,6 @@ diff --git a/src/Models/Option.php b/src/Models/Option.php index 864d311..4b0d48f 100644 --- a/src/Models/Option.php +++ b/src/Models/Option.php @@ -1,6 +1,6 @@ @@ -10,8 +10,8 @@ use Dbout\WpOrm\Api\OptionInterface; use Dbout\WpOrm\Builders\OptionBuilder; +use Dbout\WpOrm\Enums\YesNo; use Dbout\WpOrm\Orm\AbstractModel; -use Dbout\WpOrm\Providers\YesNo; /** * @method static Option|null find($optionId) @@ -39,7 +39,10 @@ class Option extends AbstractModel implements OptionInterface * @inheritDoc */ protected $fillable = [ - self::OPTION_ID, self::NAME, self::VALUE, self::AUTOLOAD, + self::OPTION_ID, + self::NAME, + self::VALUE, + self::AUTOLOAD, ]; /** @@ -53,9 +56,11 @@ public function newEloquentBuilder($query): OptionBuilder /** * @inheritDoc */ - public static function findByName(string $optionName): ?self + public static function findOneByName(string $optionName): ?self { - return self::query()->firstWhere(self::NAME, $optionName); + /** @var self|null $result */ + $result = self::query()->firstWhere(self::NAME, $optionName); + return $result; } /** diff --git a/src/Models/Page.php b/src/Models/Page.php index df2476d..f82493a 100644 --- a/src/Models/Page.php +++ b/src/Models/Page.php @@ -1,6 +1,6 @@ diff --git a/src/Models/Post.php b/src/Models/Post.php index 2c540c6..3f725f4 100644 --- a/src/Models/Post.php +++ b/src/Models/Post.php @@ -1,6 +1,6 @@ @@ -12,6 +12,8 @@ use Dbout\WpOrm\Api\PostInterface; use Dbout\WpOrm\Api\UserInterface; use Dbout\WpOrm\Builders\PostBuilder; +use Dbout\WpOrm\Enums\PingStatus; +use Dbout\WpOrm\Enums\PostStatus; use Dbout\WpOrm\Models\Meta\PostMeta; use Dbout\WpOrm\Models\Meta\WithMeta; use Dbout\WpOrm\Orm\AbstractModel; @@ -25,28 +27,44 @@ * @property PostMeta[] $metas * @property Post|null $parent * @property Comment[] $comments + * @method static|PostBuilder author(int|User $user) + * @method static|PostBuilder status(string|PostStatus $status) + * @method static|PostBuilder pingStatus(string|PingStatus $status) + * @method static|PostBuilder postType(string $type) */ class Post extends AbstractModel implements PostInterface { use WithMeta; public const UPDATED_AT = self::MODIFIED; - public const CREATED_AT = self::DATE; /** - * @var string + * @inheritDoc */ protected $primaryKey = self::POST_ID; /** - * @var string[] + * @inheritDoc */ protected $fillable = [ - self::CONTENT, self::TITLE, self::EXCERPT, self::COMMENT_STATUS, self::STATUS, - self::PING_STATUS, self::PASSWORD, self::POST_NAME, self::TO_PING, self::PINGED, - self::CONTENT_FILTERED, self::PARENT, self::GUID, self::MENU_ORDER, self::TYPE, - self::MIME_TYPE, self::COMMENT_COUNT, + self::CONTENT, + self::TITLE, + self::EXCERPT, + self::COMMENT_STATUS, + self::STATUS, + self::PING_STATUS, + self::PASSWORD, + self::POST_NAME, + self::TO_PING, + self::PINGED, + self::CONTENT_FILTERED, + self::PARENT, + self::GUID, + self::MENU_ORDER, + self::TYPE, + self::MIME_TYPE, + self::COMMENT_COUNT, ]; /** @@ -105,4 +123,56 @@ public function getMetaClass(): string { return \Dbout\WpOrm\Models\Meta\PostMeta::class; } + + /** + * @param PostBuilder $builder + * @param int|User $user + * @return void + */ + public function scopeAuthor(PostBuilder $builder, int|User $user): void + { + if ($user instanceof User) { + $user = $user->getId(); + } + + $builder->where(self::AUTHOR, $user); + } + + /** + * @param PostBuilder $builder + * @param string|PostStatus $status + * @return void + */ + public function scopeStatus(PostBuilder $builder, string|PostStatus $status): void + { + if ($status instanceof PostStatus) { + $status = $status->value; + } + + $builder->where(self::STATUS, $status); + } + + /** + * @param PostBuilder $builder + * @param string|PingStatus $status + * @return void + */ + public function scopePingStatus(PostBuilder $builder, string|PingStatus $status): void + { + if ($status instanceof PingStatus) { + $status = $status->value; + } + + $builder->where(self::PING_STATUS, $status); + } + + /** + * @param PostBuilder $builder + * @param string $postType + * @return void + */ + public function scopePostType(PostBuilder $builder, string $postType): void + { + $builder->where(self::TYPE, $postType); + } } diff --git a/src/Models/Term.php b/src/Models/Term.php index ab8afe5..6856926 100644 --- a/src/Models/Term.php +++ b/src/Models/Term.php @@ -1,6 +1,6 @@ @@ -47,7 +47,10 @@ class Term extends AbstractModel implements TermInterface * @inheritDoc */ protected $fillable = [ - self::SLUG, self::TERM_ID, self::TERM_GROUP, self::NAME, + self::SLUG, + self::TERM_ID, + self::TERM_GROUP, + self::NAME, ]; /** diff --git a/src/Models/TermRelationship.php b/src/Models/TermRelationship.php index a6f55f9..d38af12 100644 --- a/src/Models/TermRelationship.php +++ b/src/Models/TermRelationship.php @@ -1,6 +1,6 @@ diff --git a/src/Models/TermTaxonomy.php b/src/Models/TermTaxonomy.php index 47f485e..bd42562 100644 --- a/src/Models/TermTaxonomy.php +++ b/src/Models/TermTaxonomy.php @@ -1,6 +1,6 @@ @@ -42,6 +42,11 @@ class TermTaxonomy extends AbstractModel implements TermTaxonomyInterface * @var string[] */ protected $fillable = [ - self::TERM_TAXONOMY_ID, self::TERM_ID, self::TAXONOMY, self::DESCRIPTION, self::PARENT, self::COUNT, + self::TERM_TAXONOMY_ID, + self::TERM_ID, + self::TAXONOMY, + self::DESCRIPTION, + self::PARENT, + self::COUNT, ]; } diff --git a/src/Models/Traits/HasCustomType.php b/src/Models/Traits/HasCustomType.php index f20ed95..8c9f1f1 100644 --- a/src/Models/Traits/HasCustomType.php +++ b/src/Models/Traits/HasCustomType.php @@ -1,6 +1,6 @@ diff --git a/src/Models/User.php b/src/Models/User.php index 7291529..b617906 100644 --- a/src/Models/User.php +++ b/src/Models/User.php @@ -1,6 +1,6 @@ @@ -101,7 +101,9 @@ public function getMetaClass(): string */ public static function findByEmail(string $email): ?self { - return self::query()->firstWhere(self::EMAIL, $email); + /** @var self|null $result */ + $result = self::query()->firstWhere(self::EMAIL, $email); + return $result; } /** @@ -109,6 +111,8 @@ public static function findByEmail(string $email): ?self */ public static function findByLogin(string $login): ?self { - return self::query()->firstWhere(self::LOGIN, $login); + /** @var self|null $result */ + $result = self::query()->firstWhere(self::LOGIN, $login); + return $result; } } diff --git a/src/Orm/AbstractModel.php b/src/Orm/AbstractModel.php index 0dd58a8..cda4287 100644 --- a/src/Orm/AbstractModel.php +++ b/src/Orm/AbstractModel.php @@ -1,6 +1,6 @@ diff --git a/src/Orm/Builder.php b/src/Orm/Builder.php index 41b65b4..673b465 100644 --- a/src/Orm/Builder.php +++ b/src/Orm/Builder.php @@ -1,6 +1,6 @@ diff --git a/src/Orm/Database.php b/src/Orm/Database.php index 48eaf4b..f5dec80 100644 --- a/src/Orm/Database.php +++ b/src/Orm/Database.php @@ -1,6 +1,6 @@ diff --git a/src/Orm/Resolver.php b/src/Orm/Resolver.php index ac0219f..c47b31c 100644 --- a/src/Orm/Resolver.php +++ b/src/Orm/Resolver.php @@ -1,6 +1,6 @@ diff --git a/src/Scopes/CustomPostAddTypeScope.php b/src/Scopes/CustomPostAddTypeScope.php index 07135f8..fbbe900 100644 --- a/src/Scopes/CustomPostAddTypeScope.php +++ b/src/Scopes/CustomPostAddTypeScope.php @@ -1,6 +1,6 @@ diff --git a/src/includes/migrations.php b/src/includes/migrations.php index 8fa589b..a9a2bf4 100644 --- a/src/includes/migrations.php +++ b/src/includes/migrations.php @@ -1,6 +1,6 @@ From e47cdf3c50f1e0ebddd825c4076c2238293a952a Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Sat, 13 Jan 2024 22:45:59 +0100 Subject: [PATCH 21/67] Support migration options config --- src/Migration/Config.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Migration/Config.php b/src/Migration/Config.php index 1ef8c27..83a1e84 100644 --- a/src/Migration/Config.php +++ b/src/Migration/Config.php @@ -20,12 +20,13 @@ public static function createPhinxConfig(array $userConfig = []): array 'migration_base_class' => \Phinx\Migration\AbstractMigration::class, 'paths' => [ 'migrations' => $userConfig['migrations_path'], + 'seeds' => $userConfig['seeds_path'] ?? null, ], 'environments' => [ - 'default_migration_table' => 'phinxlog', - 'default_database' => 'default', + 'default_migration_table' => $userConfig['migration_table'] ?? 'phinxlog', + 'default_database' => $userConfig['default_database'] ?? 'default', 'default' => [ - 'adapter' => 'mysql', + 'adapter' => $userConfig['adapter'] ?? 'mysql', 'host' => $userConfig['db_host'] ?? '', 'name' => $userConfig['db_name'] ?? '', 'user' => $userConfig['db_user'] ?? '', From 1bfee5dbc488ec4bc7e58a44039d1ab4f6044f04 Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Sat, 13 Jan 2024 22:48:29 +0100 Subject: [PATCH 22/67] Use findOneBy* --- src/Api/UserInterface.php | 4 ++-- src/Models/User.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Api/UserInterface.php b/src/Api/UserInterface.php index 3c4a561..3c19e3c 100644 --- a/src/Api/UserInterface.php +++ b/src/Api/UserInterface.php @@ -50,7 +50,7 @@ interface UserInterface * @param string $email * @return self|null */ - public static function findByEmail(string $email): ?self; + public static function findOneByEmail(string $email): ?self; /** * Find user by login @@ -58,5 +58,5 @@ public static function findByEmail(string $email): ?self; * @param string $login * @return self|null */ - public static function findByLogin(string $login): ?self; + public static function findOneByLogin(string $login): ?self; } diff --git a/src/Models/User.php b/src/Models/User.php index b617906..40323e2 100644 --- a/src/Models/User.php +++ b/src/Models/User.php @@ -99,7 +99,7 @@ public function getMetaClass(): string /** * @inheritDoc */ - public static function findByEmail(string $email): ?self + public static function findOneByEmail(string $email): ?self { /** @var self|null $result */ $result = self::query()->firstWhere(self::EMAIL, $email); @@ -109,7 +109,7 @@ public static function findByEmail(string $email): ?self /** * @inheritDoc */ - public static function findByLogin(string $login): ?self + public static function findOneByLogin(string $login): ?self { /** @var self|null $result */ $result = self::query()->firstWhere(self::LOGIN, $login); From f78781486b3f1ee5e71b70045dec708bea714a64 Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Sat, 13 Jan 2024 23:03:44 +0100 Subject: [PATCH 23/67] Update Readme --- README.md | 36 +++++++++--------------------------- 1 file changed, 9 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 1ec8ceb..3bed26b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Wordpress ORM with Eloquent +![GitHub Release](https://img.shields.io/github/v/release/dimitriBouteille/wp-orm) ![Packagist Downloads](https://img.shields.io/packagist/dt/dbout/wp-orm) + WordPress ORM wih Eloquent is a small library that adds a basic ORM into WordPress, which is easily extendable and includes models for core WordPress models such as posts, post metas, users, comments and more. The ORM is based on [Eloquent ORM](https://laravel.com/docs/8.x/eloquent) and uses the Wordpress connection (`wpdb` class). @@ -16,11 +18,15 @@ The ORM also offers a system to simply manage database migrations based on [Phin - ❤️ Easy integration of a custom post type and comment. - ❤️ Easy model creation for projects with custom tables -### Documentations : +### Documentation : - [Requirements](#requirements) - [Installation](#installation) -- [Migrations](doc/migration.md) +- [Introduction]() +- [Use the Wordpress models]() +- [Create custom Model]() +- [Create custom PostType/CommentType model]() +- [Migration with Phinx](doc/migration.md) ## Requirements @@ -43,28 +49,4 @@ In your PHP script, make sure you include the autoloader: require __DIR__ . '/vendor/autoload.php'; ~~~ - -Basic usage with core Wordpress models --------- - -### Page model - -#### Queries - -```php -# Get all pages -$pages = \Dbout\WpOrm\Models\Page::all(); - -# Get one page by ID -$page = \Dbout\WpOrm\Models\Page::find(15); - -# Get all pages by author -$pages = \Dbout\WpOrm\Models\Page::query() - ->whereAuthor(1) - ->get(); - -# Get all publish pages -$pages = \Dbout\WpOrm\Models\Page::query() - ->whereStatus('publish') - ->get(); -``` \ No newline at end of file +## Introduction \ No newline at end of file From 816a5561194feff0b17acd0cce51243b6e6ccbcb Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Sat, 13 Jan 2024 23:05:20 +0100 Subject: [PATCH 24/67] Update Readme installation --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 3bed26b..887703f 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,6 @@ The ORM also offers a system to simply manage database migrations based on [Phin ### Documentation : -- [Requirements](#requirements) - [Installation](#installation) - [Introduction]() - [Use the Wordpress models]() @@ -28,14 +27,17 @@ The ORM also offers a system to simply manage database migrations based on [Phin - [Create custom PostType/CommentType model]() - [Migration with Phinx](doc/migration.md) -## Requirements + +## Installation + +**Requirements** The server requirements are basically the same as for [WordPress](https://wordpress.org/about/requirements/) with the addition of a few ones : - PHP >= 8.1 - [Composer](https://getcomposer.org/) -## Installation +**Installation** You can use [Composer](https://getcomposer.org/). Follow the [installation instructions](https://getcomposer.org/doc/00-intro.md) if you do not already have composer installed. From 70c5f86ab11e6ffff0cf85cc14011a3199b03e8c Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Sun, 14 Jan 2024 12:07:04 +0100 Subject: [PATCH 25/67] #12 Update custom post feature, rollback customModelPost to CustomPost, add WpOrmException --- src/Api/CustomModelTypeInterface.php | 22 ++++++++ src/Exceptions/MetaNotSupportedException.php | 2 +- src/Exceptions/NotAllowedException.php | 2 +- src/Exceptions/WpOrmException.php | 13 +++++ src/Models/CustomComment.php | 38 ------------- src/Models/CustomPost.php | 59 ++++++++++++++++++-- src/Models/Page.php | 2 +- src/Models/Traits/HasCustomType.php | 47 ---------------- src/Scopes/CustomModelTypeScope.php | 35 ++++++++++++ src/Scopes/CustomPostAddTypeScope.php | 29 ---------- 10 files changed, 127 insertions(+), 122 deletions(-) create mode 100644 src/Api/CustomModelTypeInterface.php create mode 100644 src/Exceptions/WpOrmException.php delete mode 100644 src/Models/CustomComment.php delete mode 100644 src/Models/Traits/HasCustomType.php create mode 100644 src/Scopes/CustomModelTypeScope.php delete mode 100644 src/Scopes/CustomPostAddTypeScope.php diff --git a/src/Api/CustomModelTypeInterface.php b/src/Api/CustomModelTypeInterface.php new file mode 100644 index 0000000..a495814 --- /dev/null +++ b/src/Api/CustomModelTypeInterface.php @@ -0,0 +1,22 @@ + + */ + +namespace Dbout\WpOrm\Api; + +interface CustomModelTypeInterface +{ + /** + * @return string + */ + public function getCustomTypeCode(): string; + + /** + * @return string + */ + public function getCustomTypeColumn(): string; +} diff --git a/src/Exceptions/MetaNotSupportedException.php b/src/Exceptions/MetaNotSupportedException.php index 71aff67..cec6f42 100644 --- a/src/Exceptions/MetaNotSupportedException.php +++ b/src/Exceptions/MetaNotSupportedException.php @@ -8,6 +8,6 @@ namespace Dbout\WpOrm\Exceptions; -class MetaNotSupportedException extends \Exception +class MetaNotSupportedException extends WpOrmException { } diff --git a/src/Exceptions/NotAllowedException.php b/src/Exceptions/NotAllowedException.php index 3d4d07e..35db87e 100644 --- a/src/Exceptions/NotAllowedException.php +++ b/src/Exceptions/NotAllowedException.php @@ -8,6 +8,6 @@ namespace Dbout\WpOrm\Exceptions; -class NotAllowedException extends \Exception +class NotAllowedException extends WpOrmException { } diff --git a/src/Exceptions/WpOrmException.php b/src/Exceptions/WpOrmException.php new file mode 100644 index 0000000..3455a73 --- /dev/null +++ b/src/Exceptions/WpOrmException.php @@ -0,0 +1,13 @@ + + */ + +namespace Dbout\WpOrm\Exceptions; + +class WpOrmException extends \Exception +{ +} diff --git a/src/Models/CustomComment.php b/src/Models/CustomComment.php deleted file mode 100644 index 6c9f684..0000000 --- a/src/Models/CustomComment.php +++ /dev/null @@ -1,38 +0,0 @@ - - */ - -namespace Dbout\WpOrm\Models; - -use Dbout\WpOrm\Models\Traits\HasCustomType; -use Dbout\WpOrm\Scopes\CustomPostAddTypeScope; - -abstract class CustomComment extends Comment -{ - use HasCustomType; - - /** - * CustomPost constructor. - * @param array $attributes - */ - public function __construct(array $attributes = []) - { - $this->attributes = [ - self::TYPE => $this->_type, - ]; - - parent::__construct($attributes); - } - - /** - * @return void - */ - protected static function booted() - { - static::addGlobalScope(new CustomPostAddTypeScope()); - } -} diff --git a/src/Models/CustomPost.php b/src/Models/CustomPost.php index b1a87b8..376595c 100644 --- a/src/Models/CustomPost.php +++ b/src/Models/CustomPost.php @@ -8,12 +8,16 @@ namespace Dbout\WpOrm\Models; -use Dbout\WpOrm\Models\Traits\HasCustomType; -use Dbout\WpOrm\Scopes\CustomPostAddTypeScope; +use Dbout\WpOrm\Api\CustomModelTypeInterface; +use Dbout\WpOrm\Exceptions\NotAllowedException; +use Dbout\WpOrm\Scopes\CustomModelTypeScope; -abstract class CustomPost extends Post +abstract class CustomPost extends Post implements CustomModelTypeInterface { - use HasCustomType; + /** + * @var string + */ + protected string $_type; /** * @param array $attributes @@ -27,11 +31,56 @@ public function __construct(array $attributes = []) parent::__construct($attributes); } + /** + * @inheritDoc + */ + public function getPostType(): ?string + { + return $this->_type; + } + + /** + * @inheritDoc + */ + public function getCustomTypeCode(): string + { + return $this->getPostType(); + } + + /** + * @inheritDoc + */ + public function getCustomTypeColumn(): string + { + return self::TYPE; + } + + /** + * @param string $type + * @throws NotAllowedException + * @return never + */ + final public function setPostType(string $type): never + { + throw new NotAllowedException(sprintf( + 'You cannot set a type for this object. Current type [%s]', + $this->_type + )); + } + + /** + * @return string|null + */ + public static function type(): ?string + { + return (new static())->getPostType(); + } + /** * @inheritDoc */ protected static function booted() { - static::addGlobalScope(new CustomPostAddTypeScope()); + static::addGlobalScope(new CustomModelTypeScope()); } } diff --git a/src/Models/Page.php b/src/Models/Page.php index f82493a..18f0888 100644 --- a/src/Models/Page.php +++ b/src/Models/Page.php @@ -8,7 +8,7 @@ namespace Dbout\WpOrm\Models; -class Page extends CustomPost +class Page extends CustomModelPost { /** * @inheritDoc diff --git a/src/Models/Traits/HasCustomType.php b/src/Models/Traits/HasCustomType.php deleted file mode 100644 index 8c9f1f1..0000000 --- a/src/Models/Traits/HasCustomType.php +++ /dev/null @@ -1,47 +0,0 @@ - - */ - -namespace Dbout\WpOrm\Models\Traits; - -use Dbout\WpOrm\Exceptions\NotAllowedException; - -trait HasCustomType -{ - /** - * @var string - */ - protected string $_type; - - /** - * @return string|null - */ - public function getPostType(): ?string - { - return $this->_type; - } - - /** - * @param string $postType - * @throws NotAllowedException - */ - final public function setPostType(string $postType): never - { - throw new NotAllowedException(sprintf( - 'You cannot set a type for this object. Current type [%s]', - $this->_type - )); - } - - /** - * @return string|null - */ - public static function type(): ?string - { - return (new static())->getPostType(); - } -} diff --git a/src/Scopes/CustomModelTypeScope.php b/src/Scopes/CustomModelTypeScope.php new file mode 100644 index 0000000..2cc93ba --- /dev/null +++ b/src/Scopes/CustomModelTypeScope.php @@ -0,0 +1,35 @@ + + */ + +namespace Dbout\WpOrm\Scopes; + +use Dbout\WpOrm\Api\CustomModelTypeInterface; +use Dbout\WpOrm\Exceptions\WpOrmException; +use Illuminate\Database\Eloquent\Builder; +use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Scope; + +class CustomModelTypeScope implements Scope +{ + /** + * @inheritDoc + * @throws WpOrmException + */ + public function apply(Builder $builder, Model $model) + { + if (!$model instanceof CustomModelTypeInterface) { + throw new WpOrmException(sprintf( + 'The object %s must be implement %s.', + get_class($model), + CustomModelTypeInterface::class + )); + } + + $builder->where($model->getCustomTypeColumn(), $model->getCustomTypeCode()); + } +} diff --git a/src/Scopes/CustomPostAddTypeScope.php b/src/Scopes/CustomPostAddTypeScope.php deleted file mode 100644 index fbbe900..0000000 --- a/src/Scopes/CustomPostAddTypeScope.php +++ /dev/null @@ -1,29 +0,0 @@ - - */ - -namespace Dbout\WpOrm\Scopes; - -use Dbout\WpOrm\Builders\PostBuilder; -use Dbout\WpOrm\Models\CustomPost; -use Illuminate\Database\Eloquent\Builder; -use Illuminate\Database\Eloquent\Model; -use Illuminate\Database\Eloquent\Scope; - -class CustomPostAddTypeScope implements Scope -{ - /** - * @param PostBuilder $builder - * @inheritDoc - */ - public function apply(Builder $builder, Model $model) - { - /** @var CustomPost $model */ - $type = $model->getPostType(); - $builder->whereTypes($type); - } -} From 89fcfaf2ca81ed433d1a4f11ebb0e6d27dcb59c6 Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Sun, 14 Jan 2024 12:24:05 +0100 Subject: [PATCH 26/67] #12 Update phpdoc, set deprecated findOne* in builder, fix Models\Page extend CUstomPost --- src/Api/CommentInterface.php | 2 ++ src/Api/CustomModelTypeInterface.php | 3 +++ src/Api/OptionInterface.php | 2 ++ src/Api/PostInterface.php | 10 ++++++++ src/Api/TermInterface.php | 2 ++ src/Api/TermRelationshipInterface.php | 2 ++ src/Api/TermTaxonomyInterface.php | 2 ++ src/Api/UserInterface.php | 2 ++ src/Builders/OptionBuilder.php | 2 ++ src/Builders/PostBuilder.php | 2 ++ src/Builders/UserBuilder.php | 4 ++++ src/Enums/PingStatus.php | 3 +++ src/Enums/PostStatus.php | 1 + src/Enums/YesNo.php | 3 +++ .../CannotOverrideCustomTypeException.php | 24 +++++++++++++++++++ src/Exceptions/WpOrmException.php | 3 +++ src/Models/Attachment.php | 13 ++++------ src/Models/CustomPost.php | 6 ++--- src/Models/Page.php | 2 +- src/Models/Post.php | 10 ++++++++ src/Scopes/CustomModelTypeScope.php | 3 +++ 21 files changed, 87 insertions(+), 14 deletions(-) create mode 100644 src/Exceptions/CannotOverrideCustomTypeException.php diff --git a/src/Api/CommentInterface.php b/src/Api/CommentInterface.php index 3451b1c..9003e33 100644 --- a/src/Api/CommentInterface.php +++ b/src/Api/CommentInterface.php @@ -42,6 +42,8 @@ * @property User|null $user * @property Post|null $post * @property Comment|null $parent + * + * @since 3.0.0 */ interface CommentInterface { diff --git a/src/Api/CustomModelTypeInterface.php b/src/Api/CustomModelTypeInterface.php index a495814..a87a1e3 100644 --- a/src/Api/CustomModelTypeInterface.php +++ b/src/Api/CustomModelTypeInterface.php @@ -8,6 +8,9 @@ namespace Dbout\WpOrm\Api; +/** + * @since 3.0.0 + */ interface CustomModelTypeInterface { /** diff --git a/src/Api/OptionInterface.php b/src/Api/OptionInterface.php index 7d0e714..f08bfad 100644 --- a/src/Api/OptionInterface.php +++ b/src/Api/OptionInterface.php @@ -18,6 +18,8 @@ * @method mixed getOptionValue() * @method Option setAutoload(string|YesNo $autoload) * @method string getAutoload() + * + * @since 3.0.0 */ interface OptionInterface { diff --git a/src/Api/PostInterface.php b/src/Api/PostInterface.php index 9af1ce3..15dcd18 100644 --- a/src/Api/PostInterface.php +++ b/src/Api/PostInterface.php @@ -50,6 +50,8 @@ * @method int|null getMenuOrder() * @method Post setPostContentFiltered($content) * @method string|null getPostContentFiltered() + * + * @since 3.0.0 */ interface PostInterface { @@ -76,4 +78,12 @@ interface PostInterface public const TYPE = 'post_type'; public const MIME_TYPE = 'post_mime_type'; public const COMMENT_COUNT = 'comment_count'; + + /** + * Find post by name + * + * @param string|null $name + * @return Post|null + */ + public function findOneByName(?string $name): ?Post; } diff --git a/src/Api/TermInterface.php b/src/Api/TermInterface.php index d71d770..f8374a4 100644 --- a/src/Api/TermInterface.php +++ b/src/Api/TermInterface.php @@ -17,6 +17,8 @@ * @method Term setSlug(?string $slug) * @method int|null getTermGroup() * @method Term setTermGroup(?int $group) + * + * @since 3.0.0 */ interface TermInterface { diff --git a/src/Api/TermRelationshipInterface.php b/src/Api/TermRelationshipInterface.php index d2e09c5..8162d3e 100644 --- a/src/Api/TermRelationshipInterface.php +++ b/src/Api/TermRelationshipInterface.php @@ -17,6 +17,8 @@ * @method TermRelationship setTermTaxonomyId(?int $id) * @method int|null getObjectId() * @method TermRelationship setObjectId(?int $id) + * + * @since 3.0.0 */ interface TermRelationshipInterface { diff --git a/src/Api/TermTaxonomyInterface.php b/src/Api/TermTaxonomyInterface.php index 3994f0e..731bae8 100644 --- a/src/Api/TermTaxonomyInterface.php +++ b/src/Api/TermTaxonomyInterface.php @@ -21,6 +21,8 @@ * @method TermTaxonomy setParent($parent) * @method int|null getCount() * @method TermTaxonomy setCount(int $count) + * + * @since 3.0.0 */ interface TermTaxonomyInterface { diff --git a/src/Api/UserInterface.php b/src/Api/UserInterface.php index 3c19e3c..9c00541 100644 --- a/src/Api/UserInterface.php +++ b/src/Api/UserInterface.php @@ -30,6 +30,8 @@ * @method User setUserStatus(int $status) * @method string|null getDisplayName() * @method User setDisplayName(?string $name) + * + * @since 3.0.0 */ interface UserInterface { diff --git a/src/Builders/OptionBuilder.php b/src/Builders/OptionBuilder.php index 879bed2..6e516bc 100644 --- a/src/Builders/OptionBuilder.php +++ b/src/Builders/OptionBuilder.php @@ -16,6 +16,8 @@ class OptionBuilder extends AbstractBuilder /** * @param string $optionName * @return Option|null + * @deprecated Remove in next version + * @see Option::findOneByName() */ public function findOneByName(string $optionName): ?Option { diff --git a/src/Builders/PostBuilder.php b/src/Builders/PostBuilder.php index 8e4981d..9b28fb0 100644 --- a/src/Builders/PostBuilder.php +++ b/src/Builders/PostBuilder.php @@ -20,6 +20,8 @@ class PostBuilder extends AbstractBuilder /** * @param string|null $name * @return Post|null + * @deprecated Remove in next version + * @see Post::findOneByName() */ public function findOneByName(?string $name): ?Post { diff --git a/src/Builders/UserBuilder.php b/src/Builders/UserBuilder.php index f290930..42ca0b2 100644 --- a/src/Builders/UserBuilder.php +++ b/src/Builders/UserBuilder.php @@ -19,6 +19,8 @@ class UserBuilder extends AbstractBuilder /** * @param string $email * @return User|null + * @deprecated Remove in next version + * @see User::findOneByEmail() */ public function findOneByEmail(string $email): ?User { @@ -30,6 +32,8 @@ public function findOneByEmail(string $email): ?User /** * @param string $login * @return User|null + * @deprecated Remove in next version + * @see User::findOneByLogin() */ public function findOneByLogin(string $login): ?User { diff --git a/src/Enums/PingStatus.php b/src/Enums/PingStatus.php index f11cb95..c5d871c 100644 --- a/src/Enums/PingStatus.php +++ b/src/Enums/PingStatus.php @@ -8,6 +8,9 @@ namespace Dbout\WpOrm\Enums; +/** + * @since 3.0.0 + */ enum PingStatus: string { case Closed = 'closed'; diff --git a/src/Enums/PostStatus.php b/src/Enums/PostStatus.php index 1da17b9..07c4b16 100644 --- a/src/Enums/PostStatus.php +++ b/src/Enums/PostStatus.php @@ -10,6 +10,7 @@ /** * @see https://wordpress.org/documentation/article/post-status/ + * @since 3.0.0 */ enum PostStatus: string { diff --git a/src/Enums/YesNo.php b/src/Enums/YesNo.php index d13a84e..f9fce5e 100644 --- a/src/Enums/YesNo.php +++ b/src/Enums/YesNo.php @@ -8,6 +8,9 @@ namespace Dbout\WpOrm\Enums; +/** + * @since 3.0.0 + */ enum YesNo: string { case Yes = 'yes'; diff --git a/src/Exceptions/CannotOverrideCustomTypeException.php b/src/Exceptions/CannotOverrideCustomTypeException.php new file mode 100644 index 0000000..c52dde3 --- /dev/null +++ b/src/Exceptions/CannotOverrideCustomTypeException.php @@ -0,0 +1,24 @@ +whereIn(self::MIME_TYPE, $firstValue); - } else { - $builder->where(self::MIME_TYPE, $firstValue); - } + $builder->where(self::MIME_TYPE, $type); } } diff --git a/src/Models/CustomPost.php b/src/Models/CustomPost.php index 376595c..979f519 100644 --- a/src/Models/CustomPost.php +++ b/src/Models/CustomPost.php @@ -9,6 +9,7 @@ namespace Dbout\WpOrm\Models; use Dbout\WpOrm\Api\CustomModelTypeInterface; +use Dbout\WpOrm\Exceptions\CannotOverrideCustomTypeException; use Dbout\WpOrm\Exceptions\NotAllowedException; use Dbout\WpOrm\Scopes\CustomModelTypeScope; @@ -62,10 +63,7 @@ public function getCustomTypeColumn(): string */ final public function setPostType(string $type): never { - throw new NotAllowedException(sprintf( - 'You cannot set a type for this object. Current type [%s]', - $this->_type - )); + throw new CannotOverrideCustomTypeException($this->_type); } /** diff --git a/src/Models/Page.php b/src/Models/Page.php index 18f0888..f82493a 100644 --- a/src/Models/Page.php +++ b/src/Models/Page.php @@ -8,7 +8,7 @@ namespace Dbout\WpOrm\Models; -class Page extends CustomModelPost +class Page extends CustomPost { /** * @inheritDoc diff --git a/src/Models/Post.php b/src/Models/Post.php index 3f725f4..f9a2945 100644 --- a/src/Models/Post.php +++ b/src/Models/Post.php @@ -175,4 +175,14 @@ public function scopePostType(PostBuilder $builder, string $postType): void { $builder->where(self::TYPE, $postType); } + + /** + * @inheritDoc + */ + public function findOneByName(?string $name): ?Post + { + /** @var Post|null $model */ + $model = self::query()->firstWhere(self::POST_NAME, $name); + return $model; + } } diff --git a/src/Scopes/CustomModelTypeScope.php b/src/Scopes/CustomModelTypeScope.php index 2cc93ba..8fac89a 100644 --- a/src/Scopes/CustomModelTypeScope.php +++ b/src/Scopes/CustomModelTypeScope.php @@ -14,6 +14,9 @@ use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Scope; +/** + * @since 3.0.0 + */ class CustomModelTypeScope implements Scope { /** From 532899cd3d63d022e18b86d18ddb0a865abd0c2a Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Sun, 14 Jan 2024 12:28:44 +0100 Subject: [PATCH 27/67] #12 Update README.md --- README.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 887703f..1323355 100644 --- a/README.md +++ b/README.md @@ -9,25 +9,28 @@ The ORM also offers a system to simply manage database migrations based on [Phin 💡 To simplify the integration of this library, we recommend using Wordpress with one of the following tools: [Bedrock](https://roots.io/bedrock/), [Themosis](https://framework.themosis.com/) or [Wordplate](https://github.com/wordplate/wordplate#readme). -### Features : +### Features - ✅ Support core WordPress models: `Comment`, `Option`, `Post`, `TermTaxonomy`, `Term`, `User`, `PostMeta` and `UserMeta`. - ✅ Support core WordPress post type: `Article`, `Attachment` and `Page`. - ✅ Based on core Wordpress database connection (`wpdb` class) - ✅ Migration with `Phinx` library. -- ❤️ Easy integration of a custom post type and comment. -- ❤️ Easy model creation for projects with custom tables +- ❤️ Easy integration of a custom post type. +- ❤️ Easy model creation for projects with custom tables. -### Documentation : +**Not yet developed but planned in a future version:** + +- 💡 Create custom comment type +- 💡 Meta casting (ie [Attribute Casting](https://laravel.com/docs/10.x/eloquent-mutators#attribute-casting)) + +### Documentation - [Installation](#installation) - [Introduction]() - [Use the Wordpress models]() - [Create custom Model]() -- [Create custom PostType/CommentType model]() - [Migration with Phinx](doc/migration.md) - ## Installation **Requirements** From 067a1c9de25bc06ee15d73c8b2382b6fc887f259 Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Sun, 14 Jan 2024 12:34:31 +0100 Subject: [PATCH 28/67] #12 Add CONTRIBUTING.md --- CONTRIBUTING.md | 19 +++++++++++++++++++ README.md | 6 +++++- 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..d4d72c1 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,19 @@ +# Contribution guidelines + +## How to contribute step-by-step + +1. Fork the `dbout/wp-orm` repository. +2. Create a new branch from `main` in your fork. This makes it easier for you to keep track of your changes. +3. Make the desired changes to the code. + * If you are adding new functionality or fixing a bug, we recommend you add unit tests that cover it. +4. Push the changes to your fork. +5. Create a pull request to the `dbout/wp-orm` repository. +6. In your pull request, please describe in detail: + * What problem you’re solving + * Your approach to fixing the problem + * Any tests you wrote +7. Check Allow edits from maintainers. +8. Create the pull request. +9. Ensure that all checks have passed. + +After you create your pull request, one of the code owners will review your code. diff --git a/README.md b/README.md index 1323355..e58ce55 100644 --- a/README.md +++ b/README.md @@ -54,4 +54,8 @@ In your PHP script, make sure you include the autoloader: require __DIR__ . '/vendor/autoload.php'; ~~~ -## Introduction \ No newline at end of file +## Introduction + +## Contributing + +We encourage you to contribute to this repository, so everyone can benefit from new features, bug fixes, and any other improvements. Have a look at our [contributing guidelines](CONTRIBUTING.md) to find out how to raise a pull request. \ No newline at end of file From ddf742358de7de79f66f9643e472f3a870ac0faa Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Sun, 14 Jan 2024 12:47:44 +0100 Subject: [PATCH 29/67] #12 Add issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 31 +++++++++++++++++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 28 ++++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..bf801d7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,31 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '[BUG]: ' +labels: ["bug"] +assignees: + - dimitriBouteille + +--- + +### Describe the bug + +A clear and concise description of what the bug is. + +### Steps to reproduce the issue + +A clear and concise description to reproduce the bug. + +### Expected behavior + +A clear and concise description of what you expected to happen. + +### Your setup + +- Wordpress Version: [e.g. 6.4.2] +- Module version: [e.g. 3.0.0] +- Are you using framework ?: [e.g. Bedrock, Wordplate, ... - If yes, Please specify the framework and version] + +### Additional context + +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..c768a71 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,28 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '[FEATURE]: ' +labels: ["enhancement"] +assignees: + - dimitriBouteille + +--- + +### Introduction + +Making your own contribution is easy, encouraged and greatly appreciated! We will put effort into reviewing and merging your PR quickly. For more info, please refer to the [contribution guidelines](https://github.com/dbout/wp-orm/blob/develop/CONTRIBUTING.md). + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +### Describe the solution you'd like + +A clear and concise description of what you want to happen. + +### Describe alternatives you've considered + +A clear and concise description of any alternative solutions or features you've considered. + +### Additional context + +Add any other context or screenshots about the feature request here. From 3a13e816729422c668b6f325c492859fececda9d Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Sun, 14 Jan 2024 12:50:38 +0100 Subject: [PATCH 30/67] #12 Add config.yml --- .github/ISSUE_TEMPLATE/config.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 .github/ISSUE_TEMPLATE/config.yml diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..ec4bb38 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1 @@ +blank_issues_enabled: false \ No newline at end of file From 4f35535c42d46bfec9fe29b5fee91a72f3aa2a1f Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Sun, 14 Jan 2024 17:21:24 +0100 Subject: [PATCH 31/67] #12 Replace scope by taps, update blank_issues_enabled, change php-cs-fixer cache path, replace @property by @property-read --- .github/ISSUE_TEMPLATE/config.yml | 2 +- .gitignore | 1 + .php-cs-fixer.php | 1 + index.php | 3 + src/Api/CommentInterface.php | 6 +- .../CannotOverrideCustomTypeException.php | 8 ++- src/Models/Attachment.php | 15 ---- src/Models/Comment.php | 17 +---- src/Models/Meta/PostMeta.php | 2 +- src/Models/Meta/UserMeta.php | 2 +- src/Models/Option.php | 18 +---- src/Models/Post.php | 68 ++----------------- src/Models/Term.php | 4 +- src/Models/TermTaxonomy.php | 2 +- src/Models/User.php | 8 +-- src/Taps/Attachment/IsMimeTypeTap.php | 35 ++++++++++ src/Taps/Comment/IsApprovedTap.php | 35 ++++++++++ src/Taps/Comment/IsUserTap.php | 41 +++++++++++ src/Taps/Option/IsAutoloadTap.php | 38 +++++++++++ src/Taps/Post/IsAuthorTap.php | 41 +++++++++++ src/Taps/Post/IsPingStatusTap.php | 41 +++++++++++ src/Taps/Post/IsPostTypeTap.php | 35 ++++++++++ src/Taps/Post/IsStatusTap.php | 41 +++++++++++ 23 files changed, 339 insertions(+), 125 deletions(-) create mode 100644 index.php create mode 100644 src/Taps/Attachment/IsMimeTypeTap.php create mode 100644 src/Taps/Comment/IsApprovedTap.php create mode 100644 src/Taps/Comment/IsUserTap.php create mode 100644 src/Taps/Option/IsAutoloadTap.php create mode 100644 src/Taps/Post/IsAuthorTap.php create mode 100644 src/Taps/Post/IsPingStatusTap.php create mode 100644 src/Taps/Post/IsPostTypeTap.php create mode 100644 src/Taps/Post/IsStatusTap.php diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index ec4bb38..a49eab2 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1 +1 @@ -blank_issues_enabled: false \ No newline at end of file +blank_issues_enabled: true \ No newline at end of file diff --git a/.gitignore b/.gitignore index 727390c..a7892c5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ vendor/ +var/ .idea/ composer.lock .php-cs-fixer.cache \ No newline at end of file diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php index 87a7e94..00be7ce 100644 --- a/.php-cs-fixer.php +++ b/.php-cs-fixer.php @@ -23,6 +23,7 @@ $config = new \PhpCsFixer\Config(); return $config ->setFinder($finder) + ->setCacheFile(__DIR__ . '/var/.php-cs-fixer.cache') ->setRiskyAllowed(true) ->setRules([ '@PSR12' => true, diff --git a/index.php b/index.php new file mode 100644 index 0000000..f5c264d --- /dev/null +++ b/index.php @@ -0,0 +1,3 @@ +author(15)->postType('tr'); diff --git a/src/Api/CommentInterface.php b/src/Api/CommentInterface.php index 9003e33..1d3ae28 100644 --- a/src/Api/CommentInterface.php +++ b/src/Api/CommentInterface.php @@ -39,9 +39,9 @@ * @method Comment setCommentDateGmt(mixed $date) * @method Carbon|null getCommentDateGmt() * - * @property User|null $user - * @property Post|null $post - * @property Comment|null $parent + * @property-read User|null $user + * @property-read Post|null $post + * @property-read Comment|null $parent * * @since 3.0.0 */ diff --git a/src/Exceptions/CannotOverrideCustomTypeException.php b/src/Exceptions/CannotOverrideCustomTypeException.php index c52dde3..fc27dff 100644 --- a/src/Exceptions/CannotOverrideCustomTypeException.php +++ b/src/Exceptions/CannotOverrideCustomTypeException.php @@ -1,4 +1,10 @@ + */ namespace Dbout\WpOrm\Exceptions; @@ -21,4 +27,4 @@ public function __construct(string $type, int $code = 0, ?\Throwable $previous = parent::__construct($message, $code, $previous); } -} \ No newline at end of file +} diff --git a/src/Models/Attachment.php b/src/Models/Attachment.php index 9a74a19..d380774 100644 --- a/src/Models/Attachment.php +++ b/src/Models/Attachment.php @@ -8,25 +8,10 @@ namespace Dbout\WpOrm\Models; -use Dbout\WpOrm\Builders\PostBuilder; - -/** - * @method static|PostBuilder mimeType(string $type) - */ class Attachment extends CustomPost { /** * @inheritDoc */ protected string $_type = 'attachment'; - - /** - * @param PostBuilder $builder - * @param string $type - * @return void - */ - protected function scopeMimeType(PostBuilder $builder, string $type): void - { - $builder->where(self::MIME_TYPE, $type); - } } diff --git a/src/Models/Comment.php b/src/Models/Comment.php index 6c5ad8e..f0a67a5 100644 --- a/src/Models/Comment.php +++ b/src/Models/Comment.php @@ -17,9 +17,8 @@ use Illuminate\Database\Eloquent\Relations\HasOne; /** - * @method static Comment|null find(int $commentId) + * @method static static|null find(int $commentId) * @method static CommentBuilder query() - * @method static|CommentBuilder user(int|User $user) */ class Comment extends AbstractModel implements CommentInterface { @@ -252,18 +251,4 @@ public function getDateGMT(): ?Carbon { return $this->getCommentDateGmt(); } - - /** - * @param CommentBuilder $builder - * @param int|User $user - * @return void - */ - public function scopeUser(CommentBuilder $builder, int|User $user): void - { - if ($user instanceof User) { - $user = $user->getId(); - } - - $builder->where(self::USER_ID, $user); - } } diff --git a/src/Models/Meta/PostMeta.php b/src/Models/Meta/PostMeta.php index 500421b..1a7c4b8 100644 --- a/src/Models/Meta/PostMeta.php +++ b/src/Models/Meta/PostMeta.php @@ -13,7 +13,7 @@ /** * @method static PostMeta find(int $metaId); - * @property Post|null $post + * @property-read Post|null $post */ class PostMeta extends AbstractMeta { diff --git a/src/Models/Meta/UserMeta.php b/src/Models/Meta/UserMeta.php index 2d032e9..74c450f 100644 --- a/src/Models/Meta/UserMeta.php +++ b/src/Models/Meta/UserMeta.php @@ -13,7 +13,7 @@ /** * @method static UserMeta find(int $metaId); - * @property User|null $user + * @property-read User|null $user */ class UserMeta extends AbstractMeta { diff --git a/src/Models/Option.php b/src/Models/Option.php index 4b0d48f..04efc38 100644 --- a/src/Models/Option.php +++ b/src/Models/Option.php @@ -10,13 +10,11 @@ use Dbout\WpOrm\Api\OptionInterface; use Dbout\WpOrm\Builders\OptionBuilder; -use Dbout\WpOrm\Enums\YesNo; use Dbout\WpOrm\Orm\AbstractModel; /** - * @method static Option|null find($optionId) + * @method static static|null find($optionId) * @method static OptionBuilder query() - * @method static|OptionBuilder autoload(bool|YesNo $autoload = YesNo::Yes) */ class Option extends AbstractModel implements OptionInterface { @@ -62,18 +60,4 @@ public static function findOneByName(string $optionName): ?self $result = self::query()->firstWhere(self::NAME, $optionName); return $result; } - - /** - * @param OptionBuilder $builder - * @param bool|YesNo $autoload - * @return void - */ - protected function scopeAutoload(OptionBuilder $builder, bool|YesNo $autoload = YesNo::Yes): void - { - if (is_bool($autoload)) { - $autoload = $autoload ? YesNo::Yes : YesNo::No; - } - - $builder->where(self::AUTOLOAD, $autoload->value); - } } diff --git a/src/Models/Post.php b/src/Models/Post.php index f9a2945..222169c 100644 --- a/src/Models/Post.php +++ b/src/Models/Post.php @@ -12,8 +12,6 @@ use Dbout\WpOrm\Api\PostInterface; use Dbout\WpOrm\Api\UserInterface; use Dbout\WpOrm\Builders\PostBuilder; -use Dbout\WpOrm\Enums\PingStatus; -use Dbout\WpOrm\Enums\PostStatus; use Dbout\WpOrm\Models\Meta\PostMeta; use Dbout\WpOrm\Models\Meta\WithMeta; use Dbout\WpOrm\Orm\AbstractModel; @@ -21,16 +19,12 @@ use Illuminate\Database\Eloquent\Relations\HasOne; /** - * @method static Post find(int $postId) + * @method static static find(int $postId) * @method static PostBuilder query() - * @property User|null $author - * @property PostMeta[] $metas - * @property Post|null $parent - * @property Comment[] $comments - * @method static|PostBuilder author(int|User $user) - * @method static|PostBuilder status(string|PostStatus $status) - * @method static|PostBuilder pingStatus(string|PingStatus $status) - * @method static|PostBuilder postType(string $type) + * @property-read User|null $author + * @property-read PostMeta[] $metas + * @property-read static|null $parent + * @property-read Comment[] $comments */ class Post extends AbstractModel implements PostInterface { @@ -124,58 +118,6 @@ public function getMetaClass(): string return \Dbout\WpOrm\Models\Meta\PostMeta::class; } - /** - * @param PostBuilder $builder - * @param int|User $user - * @return void - */ - public function scopeAuthor(PostBuilder $builder, int|User $user): void - { - if ($user instanceof User) { - $user = $user->getId(); - } - - $builder->where(self::AUTHOR, $user); - } - - /** - * @param PostBuilder $builder - * @param string|PostStatus $status - * @return void - */ - public function scopeStatus(PostBuilder $builder, string|PostStatus $status): void - { - if ($status instanceof PostStatus) { - $status = $status->value; - } - - $builder->where(self::STATUS, $status); - } - - /** - * @param PostBuilder $builder - * @param string|PingStatus $status - * @return void - */ - public function scopePingStatus(PostBuilder $builder, string|PingStatus $status): void - { - if ($status instanceof PingStatus) { - $status = $status->value; - } - - $builder->where(self::PING_STATUS, $status); - } - - /** - * @param PostBuilder $builder - * @param string $postType - * @return void - */ - public function scopePostType(PostBuilder $builder, string $postType): void - { - $builder->where(self::TYPE, $postType); - } - /** * @inheritDoc */ diff --git a/src/Models/Term.php b/src/Models/Term.php index 6856926..b2cbda8 100644 --- a/src/Models/Term.php +++ b/src/Models/Term.php @@ -15,9 +15,9 @@ use Illuminate\Database\Eloquent\Relations\HasOne; /** - * @method static Term|null find(int $termId) + * @method static static|null find(int $termId) * @method static TermBuilder query() - * @property TermTaxonomy|null $termTaxonomy + * @property-read TermTaxonomy|null $termTaxonomy */ class Term extends AbstractModel implements TermInterface { diff --git a/src/Models/TermTaxonomy.php b/src/Models/TermTaxonomy.php index bd42562..365d9d0 100644 --- a/src/Models/TermTaxonomy.php +++ b/src/Models/TermTaxonomy.php @@ -12,7 +12,7 @@ use Dbout\WpOrm\Orm\AbstractModel; /** - * @method static TermTaxonomy|null find(int $id) + * @method static static|null find(int $id) */ class TermTaxonomy extends AbstractModel implements TermTaxonomyInterface { diff --git a/src/Models/User.php b/src/Models/User.php index 40323e2..596fa06 100644 --- a/src/Models/User.php +++ b/src/Models/User.php @@ -18,11 +18,11 @@ use Illuminate\Database\Eloquent\Relations\HasMany; /** - * @method static User|null find($userId) + * @method static static|null find($userId) * @method static UserBuilder query() - * @property UserMeta[] $metas - * @property Comment[] $comments - * @property Post[] $posts + * @property-read UserMeta[] $metas + * @property-read Comment[] $comments + * @property-read Post[] $posts */ class User extends AbstractModel implements UserInterface { diff --git a/src/Taps/Attachment/IsMimeTypeTap.php b/src/Taps/Attachment/IsMimeTypeTap.php new file mode 100644 index 0000000..89e3760 --- /dev/null +++ b/src/Taps/Attachment/IsMimeTypeTap.php @@ -0,0 +1,35 @@ + + */ + +namespace Dbout\WpOrm\Taps\Attachment; + +use Dbout\WpOrm\Api\PostInterface; +use Dbout\WpOrm\Builders\PostBuilder; + +/** + * @since 3.0.0 + */ +class IsMimeTypeTap +{ + /** + * @param string $mimeType + */ + public function __construct( + protected readonly string $mimeType + ) { + } + + /** + * @param PostBuilder $builder + * @return void + */ + public function __invoke(PostBuilder $builder): void + { + $builder->where(PostInterface::MIME_TYPE, $this->mimeType); + } +} diff --git a/src/Taps/Comment/IsApprovedTap.php b/src/Taps/Comment/IsApprovedTap.php new file mode 100644 index 0000000..534fb99 --- /dev/null +++ b/src/Taps/Comment/IsApprovedTap.php @@ -0,0 +1,35 @@ + + */ + +namespace Dbout\WpOrm\Taps\Comment; + +use Dbout\WpOrm\Api\CommentInterface; +use Dbout\WpOrm\Builders\CommentBuilder; + +/** + * @since 3.0.0 + */ +class IsApprovedTap +{ + /** + * @param bool $isApproved + */ + public function __construct( + protected readonly bool $isApproved = true + ) { + } + + /** + * @param CommentBuilder $builder + * @return void + */ + public function __invoke(CommentBuilder $builder): void + { + $builder->where(CommentInterface::APPROVED, $this->isApproved); + } +} diff --git a/src/Taps/Comment/IsUserTap.php b/src/Taps/Comment/IsUserTap.php new file mode 100644 index 0000000..cfee667 --- /dev/null +++ b/src/Taps/Comment/IsUserTap.php @@ -0,0 +1,41 @@ + + */ + +namespace Dbout\WpOrm\Taps\Comment; + +use Dbout\WpOrm\Api\CommentInterface; +use Dbout\WpOrm\Builders\CommentBuilder; +use Dbout\WpOrm\Models\User; + +/** + * @since 3.0.0 + */ +class IsUserTap +{ + /** + * @param int|User $user + */ + public function __construct( + protected readonly int|User $user + ) { + } + + /** + * @param CommentBuilder $builder + * @return void + */ + public function __invoke(CommentBuilder $builder): void + { + $user = $this->user; + if ($user instanceof User) { + $user = $user->getId(); + } + + $builder->where(CommentInterface::USER_ID, $user); + } +} diff --git a/src/Taps/Option/IsAutoloadTap.php b/src/Taps/Option/IsAutoloadTap.php new file mode 100644 index 0000000..b9191ec --- /dev/null +++ b/src/Taps/Option/IsAutoloadTap.php @@ -0,0 +1,38 @@ + + */ + +namespace Dbout\WpOrm\Taps\Option; + +use Dbout\WpOrm\Api\OptionInterface; +use Dbout\WpOrm\Builders\OptionBuilder; +use Dbout\WpOrm\Enums\YesNo; + +/** + * @since 3.0.0 + */ +class IsAutoloadTap +{ + public function __construct( + protected readonly bool|YesNo $autoload = YesNo::Yes + ) { + } + + /** + * @param OptionBuilder $builder + * @return void + */ + public function __invoke(OptionBuilder $builder): void + { + $autoload = $this->autoload; + if (is_bool($autoload)) { + $autoload = $autoload ? YesNo::Yes : YesNo::No; + } + + $builder->where(OptionInterface::AUTOLOAD, $autoload->value); + } +} diff --git a/src/Taps/Post/IsAuthorTap.php b/src/Taps/Post/IsAuthorTap.php new file mode 100644 index 0000000..afea7ca --- /dev/null +++ b/src/Taps/Post/IsAuthorTap.php @@ -0,0 +1,41 @@ + + */ + +namespace Dbout\WpOrm\Taps\Post; + +use Dbout\WpOrm\Api\PostInterface; +use Dbout\WpOrm\Builders\PostBuilder; +use Dbout\WpOrm\Models\User; + +/** + * @since 3.0.0 + */ +class IsAuthorTap +{ + /** + * @param int|User $author + */ + public function __construct( + protected int|User $author + ) { + } + + /** + * @param PostBuilder $builder + * @return void + */ + public function __invoke(PostBuilder $builder): void + { + $author = $this->author; + if ($author instanceof User) { + $author = $author->getId(); + } + + $builder->where(PostInterface::AUTHOR, $author); + } +} diff --git a/src/Taps/Post/IsPingStatusTap.php b/src/Taps/Post/IsPingStatusTap.php new file mode 100644 index 0000000..d1034ac --- /dev/null +++ b/src/Taps/Post/IsPingStatusTap.php @@ -0,0 +1,41 @@ + + */ + +namespace Dbout\WpOrm\Taps\Post; + +use Dbout\WpOrm\Api\PostInterface; +use Dbout\WpOrm\Builders\PostBuilder; +use Dbout\WpOrm\Enums\PingStatus; + +/** + * @since 3.0.0 + */ +class IsPingStatusTap +{ + /** + * @param string|PingStatus $status + */ + public function __construct( + protected readonly string|PingStatus $status + ) { + } + + /** + * @param PostBuilder $builder + * @return void + */ + public function __invoke(PostBuilder $builder): void + { + $status = $this->status; + if ($status instanceof PingStatus) { + $status = $status->value; + } + + $builder->where(PostInterface::PING_STATUS, $status); + } +} diff --git a/src/Taps/Post/IsPostTypeTap.php b/src/Taps/Post/IsPostTypeTap.php new file mode 100644 index 0000000..5bb7586 --- /dev/null +++ b/src/Taps/Post/IsPostTypeTap.php @@ -0,0 +1,35 @@ + + */ + +namespace Dbout\WpOrm\Taps\Post; + +use Dbout\WpOrm\Api\PostInterface; +use Dbout\WpOrm\Builders\PostBuilder; + +/** + * @since 3.0.0 + */ +class IsPostTypeTap +{ + /** + * @param string $postType + */ + public function __construct( + protected readonly string $postType + ) { + } + + /** + * @param PostBuilder $builder + * @return void + */ + public function __invoke(PostBuilder $builder): void + { + $builder->where(PostInterface::TYPE, $this->postType); + } +} diff --git a/src/Taps/Post/IsStatusTap.php b/src/Taps/Post/IsStatusTap.php new file mode 100644 index 0000000..ad1164a --- /dev/null +++ b/src/Taps/Post/IsStatusTap.php @@ -0,0 +1,41 @@ + + */ + +namespace Dbout\WpOrm\Taps\Post; + +use Dbout\WpOrm\Api\PostInterface; +use Dbout\WpOrm\Builders\PostBuilder; +use Dbout\WpOrm\Enums\PostStatus; + +/** + * @since 3.0.0 + */ +class IsStatusTap +{ + /** + * @param string|PostStatus $status + */ + public function __construct( + protected readonly string|PostStatus $status + ) { + } + + /** + * @param PostBuilder $builder + * @return void + */ + public function __invoke(PostBuilder $builder): void + { + $status = $this->status; + if ($status instanceof PostStatus) { + $status = $status->value; + } + + $builder->where(PostInterface::STATUS, $status); + } +} From 35f6c4ecaa0427e74344822bf2fb13673f10dc30 Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Sun, 14 Jan 2024 17:56:04 +0100 Subject: [PATCH 32/67] #12 WIP doc --- README.md | 20 +++++++++++++++++--- doc/comment-functions.md | 14 -------------- doc/documentation.md | 11 +++++++++++ doc/post-functions.md | 22 ---------------------- doc/user-functions.md | 14 -------------- 5 files changed, 28 insertions(+), 53 deletions(-) delete mode 100644 doc/comment-functions.md create mode 100644 doc/documentation.md delete mode 100644 doc/post-functions.md delete mode 100644 doc/user-functions.md diff --git a/README.md b/README.md index e58ce55..19140dc 100644 --- a/README.md +++ b/README.md @@ -26,9 +26,9 @@ The ORM also offers a system to simply manage database migrations based on [Phin ### Documentation - [Installation](#installation) -- [Introduction]() -- [Use the Wordpress models]() -- [Create custom Model]() +- [Introduction](#introduction) +- [Use WordPress models](doc/documentation.md#use-wordpress-models) +- [Create custom Model](doc/documentation.md#create-model) - [Migration with Phinx](doc/migration.md) ## Installation @@ -56,6 +56,20 @@ require __DIR__ . '/vendor/autoload.php'; ## Introduction +Simply put, wp-orm is a library that makes it easy to manipulate a Wordpress database via the Eloquent ORM. The objective of this library is to **simplify the manipulation of the Wordpress database** on large projects - you can also use it for small projects:p + +> Eloquent is an object-relational mapper (ORM) that makes it enjoyable to interact with your database. When using Eloquent, each database table has a corresponding "Model" that is used to interact with that table. In addition to retrieving records from the database table, Eloquent models allow you to insert, update, and delete records from the table as well. + +**Here is a list of available features :** + +- The `wpdb` connection is used so **no configuration is needed to use**. +- Ability to [create models](doc/documentation.md#model) simply +- WordPress works with custom content types, you can simply [use the default types of WordPress](doc/documentation.md#use-wordpress-models) (page, attachment, ...) and create [custom models for your types](doc/documentation.md#custom-post-type-model). +- Ability to [filter data](doc/documentation.md#filter-data) easily via taps. +- All the features available in Eloquent, are usable with this library. + +> 📘 If you want to know more about how Eloquent works, the easiest way is to [read the documentation](https://laravel.com/docs/10.x/eloquent). + ## Contributing We encourage you to contribute to this repository, so everyone can benefit from new features, bug fixes, and any other improvements. Have a look at our [contributing guidelines](CONTRIBUTING.md) to find out how to raise a pull request. \ No newline at end of file diff --git a/doc/comment-functions.md b/doc/comment-functions.md deleted file mode 100644 index 42b3e58..0000000 --- a/doc/comment-functions.md +++ /dev/null @@ -1,14 +0,0 @@ -```php -$comment->getId(); -$comment->getAuthor(); -$comment->getAuthorEmail(); -$comment->getAuthorIp(); -$comment->getAuthorUrl(); -$comment->getDate(); -$comment->getDateGMT(); -$comment->getContent(); -$comment->getKarma(); -$comment->getApproved(); -$comment->getAgent(); -$comment->getType(); -``` \ No newline at end of file diff --git a/doc/documentation.md b/doc/documentation.md new file mode 100644 index 0000000..4e6a01f --- /dev/null +++ b/doc/documentation.md @@ -0,0 +1,11 @@ +# Documentation + +## Use Wordpress Models + +## Filter data + +## Create Model + +### Model + +### Custom post type model \ No newline at end of file diff --git a/doc/post-functions.md b/doc/post-functions.md deleted file mode 100644 index 07a6c1e..0000000 --- a/doc/post-functions.md +++ /dev/null @@ -1,22 +0,0 @@ -```php -$post->getId(); -$post->getDate(); -$post->getContent(); -$post->getTitle(); -$post->getExcerpt(); -$post->getStatus(); -$post->getCommentStatus(); -$post->getPingStatus(); -$post->getPassword(); -$post->getName(); -$post->getToPing(); -$post->getModified(); -$post->getGuid(); -$post->getMenuOrder(); -$post->getPostType(); -$post->getMimeType(); -$post->author; -$post->comments; -$post->metas; -$post->parent; -``` \ No newline at end of file diff --git a/doc/user-functions.md b/doc/user-functions.md deleted file mode 100644 index 9f6e37b..0000000 --- a/doc/user-functions.md +++ /dev/null @@ -1,14 +0,0 @@ -```php -$user->getId(); -$user->getLogin(); -$user->getPassword(); -$user->getNiceName(); -$user->getEmail(); -$user->getUrl(); -$user->getRegistered(); -$user->getActivationKey(); -$user->getDisplayName(); -$user->comments; -$user->metas; -$user->posts; -``` \ No newline at end of file From dfa984a44b9c44c7ddaff7c3b3c93a56dd9c24d4 Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Sun, 14 Jan 2024 18:10:10 +0100 Subject: [PATCH 33/67] #12 Add eloquent version --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 19140dc..55f5baf 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,19 @@ # Wordpress ORM with Eloquent -![GitHub Release](https://img.shields.io/github/v/release/dimitriBouteille/wp-orm) ![Packagist Downloads](https://img.shields.io/packagist/dt/dbout/wp-orm) +![GitHub Release](https://img.shields.io/github/v/release/dimitriBouteille/wp-orm) ![Packagist Downloads](https://img.shields.io/packagist/dt/dbout/wp-orm) ![Eloquent version](https://img.shields.io/packagist/dependency-v/dbout/wp-orm/illuminate%2Fdatabase?color=orange) WordPress ORM wih Eloquent is a small library that adds a basic ORM into WordPress, which is easily extendable and includes models for core WordPress models such as posts, post metas, users, comments and more. -The ORM is based on [Eloquent ORM](https://laravel.com/docs/8.x/eloquent) and uses the Wordpress connection (`wpdb` class). +The ORM is based on [Eloquent ORM](https://laravel.com/docs/8.x/eloquent) and uses the WordPress connection (`wpdb` class). The ORM also offers a system to simply manage database migrations based on [Phinx](https://phinx.org/). -💡 To simplify the integration of this library, we recommend using Wordpress with one of the following tools: [Bedrock](https://roots.io/bedrock/), [Themosis](https://framework.themosis.com/) or [Wordplate](https://github.com/wordplate/wordplate#readme). +💡 To simplify the integration of this library, we recommend using WordPress with one of the following tools: [Bedrock](https://roots.io/bedrock/), [Themosis](https://framework.themosis.com/) or [Wordplate](https://github.com/wordplate/wordplate#readme). ### Features - ✅ Support core WordPress models: `Comment`, `Option`, `Post`, `TermTaxonomy`, `Term`, `User`, `PostMeta` and `UserMeta`. - ✅ Support core WordPress post type: `Article`, `Attachment` and `Page`. -- ✅ Based on core Wordpress database connection (`wpdb` class) +- ✅ Based on core WordPress database connection (`wpdb` class) - ✅ Migration with `Phinx` library. - ❤️ Easy integration of a custom post type. - ❤️ Easy model creation for projects with custom tables. @@ -56,7 +56,7 @@ require __DIR__ . '/vendor/autoload.php'; ## Introduction -Simply put, wp-orm is a library that makes it easy to manipulate a Wordpress database via the Eloquent ORM. The objective of this library is to **simplify the manipulation of the Wordpress database** on large projects - you can also use it for small projects:p +Simply put, wp-orm is a library that makes it easy to manipulate a WordPress database via the Eloquent ORM. The objective of this library is to **simplify the manipulation of the WordPress database** on large projects - you can also use it for small projects. > Eloquent is an object-relational mapper (ORM) that makes it enjoyable to interact with your database. When using Eloquent, each database table has a corresponding "Model" that is used to interact with that table. In addition to retrieving records from the database table, Eloquent models allow you to insert, update, and delete records from the table as well. From 0bbd718815b00cc5ee44168a0ba68ec0fba811f4 Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Thu, 18 Jan 2024 21:33:30 +0100 Subject: [PATCH 34/67] Update CI --- .github/workflows/ci.yml | 26 ++++++++++++++++++++++++++ .github/workflows/php.yml | 39 --------------------------------------- 2 files changed, 26 insertions(+), 39 deletions(-) create mode 100644 .github/workflows/ci.yml delete mode 100644 .github/workflows/php.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..55ad488 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,26 @@ +name: ci + +on: + pull_request: + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + steps: + - name: Checkout repo + uses: actions/checkout@v3 + + - name: Configure PHP + uses: shivammathur/setup-php@v2 + with: + php-version: 8.1 + tools: composer:v2 + + - name: Install dependencies + run: composer install --prefer-dist --no-progress diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml deleted file mode 100644 index c83c22b..0000000 --- a/.github/workflows/php.yml +++ /dev/null @@ -1,39 +0,0 @@ -name: PHP Composer - -on: - push: - branches: [ "master" ] - pull_request: - branches: [ "master" ] - -permissions: - contents: read - -jobs: - build: - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - - - name: Validate composer.json and composer.lock - run: composer validate --strict - - - name: Cache Composer packages - id: composer-cache - uses: actions/cache@v3 - with: - path: vendor - key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }} - restore-keys: | - ${{ runner.os }}-php- - - - name: Install dependencies - run: composer install --prefer-dist --no-progress - - # Add a test script to composer.json, for instance: "test": "vendor/bin/phpunit" - # Docs: https://getcomposer.org/doc/articles/scripts.md - - # - name: Run test suite - # run: composer run-script test From 1c1c2f581c00b2530ceb69f3040d70988e8c5573 Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Thu, 18 Jan 2024 21:57:24 +0100 Subject: [PATCH 35/67] Update CI --- .github/workflows/ci.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 55ad488..fcfa463 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,3 +24,9 @@ jobs: - name: Install dependencies run: composer install --prefer-dist --no-progress + + - name: PHPCsFixer + run: vendor/bin/php-cs-fixer fix --verbose --diff --dry-run + + - name: PHPStan + run: vendor/bin/phpstan analyse -c phpstan.neon \ No newline at end of file From 285d9c2328e02beca98a176b9ca7aea0b56dc053 Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Thu, 18 Jan 2024 22:07:24 +0100 Subject: [PATCH 36/67] Update CI --- .github/workflows/ci.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fcfa463..2aa9321 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,4 +29,7 @@ jobs: run: vendor/bin/php-cs-fixer fix --verbose --diff --dry-run - name: PHPStan - run: vendor/bin/phpstan analyse -c phpstan.neon \ No newline at end of file + run: vendor/bin/phpstan analyse -c phpstan.neon + + - name: Rector + run: vendor/bin/rector process src --dry-run \ No newline at end of file From c3a94c31e4ddbe9d92d09982edc5d58bbef84492 Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Fri, 19 Jan 2024 18:09:14 +0100 Subject: [PATCH 37/67] Start clean Meta feature --- src/Models/Comment.php | 5 ++ src/Models/CustomPost.php | 6 ++- src/Models/Meta/AbstractMeta.php | 23 ++------ src/Models/Meta/MetaInterface.php | 7 ++- src/Models/Meta/PostMeta.php | 11 +--- src/Models/Meta/UserMeta.php | 11 +--- src/Models/Meta/WithMeta.php | 88 ++++++++++++++++++------------- src/Models/Option.php | 7 +-- src/Models/Post.php | 39 +++++--------- src/Models/Term.php | 7 +-- src/Models/User.php | 28 ++++------ src/Orm/AbstractModel.php | 4 ++ 12 files changed, 98 insertions(+), 138 deletions(-) diff --git a/src/Models/Comment.php b/src/Models/Comment.php index f0a67a5..995dd5b 100644 --- a/src/Models/Comment.php +++ b/src/Models/Comment.php @@ -35,6 +35,11 @@ class Comment extends AbstractModel implements CommentInterface */ protected $table = 'comments'; + /** + * @inheritDoc + */ + protected $guarded = []; + /** * @inheritDoc */ diff --git a/src/Models/CustomPost.php b/src/Models/CustomPost.php index 979f519..12ea6d8 100644 --- a/src/Models/CustomPost.php +++ b/src/Models/CustomPost.php @@ -25,9 +25,9 @@ abstract class CustomPost extends Post implements CustomModelTypeInterface */ public function __construct(array $attributes = []) { - $this->attributes = [ + $this->setRawAttributes([ self::TYPE => $this->_type, - ]; + ]); parent::__construct($attributes); } @@ -68,9 +68,11 @@ final public function setPostType(string $type): never /** * @return string|null + * @deprecated Remove in next version - Use constant */ public static function type(): ?string { + // @phpstan-ignore-next-line return (new static())->getPostType(); } diff --git a/src/Models/Meta/AbstractMeta.php b/src/Models/Meta/AbstractMeta.php index 457e454..1c3a9e1 100644 --- a/src/Models/Meta/AbstractMeta.php +++ b/src/Models/Meta/AbstractMeta.php @@ -10,7 +10,7 @@ use Dbout\WpOrm\Orm\AbstractModel; -abstract class AbstractMeta extends AbstractModel implements MetaInterface +abstract class AbstractMeta extends AbstractModel { final public const META_KEY = 'meta_key'; final public const META_VALUE = 'meta_value'; @@ -22,10 +22,11 @@ abstract class AbstractMeta extends AbstractModel implements MetaInterface public $timestamps = false; /** - * @var array + * @inheritDoc */ protected $fillable = [ - self::META_VALUE, self::META_KEY, + self::META_VALUE, + self::META_KEY, ]; /** @@ -63,20 +64,4 @@ public function setValue(string $value): self $this->setAttribute(self::META_VALUE, $value); return $this; } - - /** - * @return string - */ - public function getKeyColumn(): string - { - return self::META_KEY; - } - - /** - * @return string - */ - public function getValueColumn(): string - { - return self::META_VALUE; - } } diff --git a/src/Models/Meta/MetaInterface.php b/src/Models/Meta/MetaInterface.php index 52cd399..bb553fb 100644 --- a/src/Models/Meta/MetaInterface.php +++ b/src/Models/Meta/MetaInterface.php @@ -13,16 +13,15 @@ interface MetaInterface /** * @return string */ - public function getFkColumn(): string; - + public static function getMetaFkColumn(): string; /** * @return string */ - public function getKeyColumn(): string; + public static function getMetaKeyColumn(): string; /** * @return string */ - public function getValueColumn(): string; + public static function getMetaValueColumn(): string; } diff --git a/src/Models/Meta/PostMeta.php b/src/Models/Meta/PostMeta.php index 1a7c4b8..4eccb2b 100644 --- a/src/Models/Meta/PostMeta.php +++ b/src/Models/Meta/PostMeta.php @@ -8,6 +8,7 @@ namespace Dbout\WpOrm\Models\Meta; +use Dbout\WpOrm\Api\PostInterface; use Dbout\WpOrm\Models\Post; use Illuminate\Database\Eloquent\Relations\HasOne; @@ -35,14 +36,6 @@ class PostMeta extends AbstractMeta */ public function post(): HasOne { - return $this->hasOne(Post::class, Post::POST_ID, self::POST_ID); - } - - /** - * @inheritDoc - */ - public function getFkColumn(): string - { - return self::POST_ID; + return $this->hasOne(Post::class, PostInterface::POST_ID, self::POST_ID); } } diff --git a/src/Models/Meta/UserMeta.php b/src/Models/Meta/UserMeta.php index 74c450f..1151b66 100644 --- a/src/Models/Meta/UserMeta.php +++ b/src/Models/Meta/UserMeta.php @@ -8,6 +8,7 @@ namespace Dbout\WpOrm\Models\Meta; +use Dbout\WpOrm\Api\UserInterface; use Dbout\WpOrm\Models\User; use Illuminate\Database\Eloquent\Relations\HasOne; @@ -35,14 +36,6 @@ class UserMeta extends AbstractMeta */ public function user(): HasOne { - return $this->hasOne(User::class, User::USER_ID, self::USER_ID); - } - - /** - * @return string - */ - public function getFkColumn(): string - { - return self::USER_ID; + return $this->hasOne(User::class, UserInterface::USER_ID, self::USER_ID); } } diff --git a/src/Models/Meta/WithMeta.php b/src/Models/Meta/WithMeta.php index b2c6581..cf79324 100644 --- a/src/Models/Meta/WithMeta.php +++ b/src/Models/Meta/WithMeta.php @@ -8,15 +8,17 @@ namespace Dbout\WpOrm\Models\Meta; -use Dbout\WpOrm\Exceptions\MetaNotSupportedException; +use Dbout\WpOrm\Exceptions\WpOrmException; use Illuminate\Database\Eloquent\Relations\HasMany; trait WithMeta { - /** - * @var AbstractMeta|null - */ - protected ?AbstractMeta $metaModel = null; + protected array $metaConfig = [ + 'class' => '', + 'columnKey' => '', + 'columnValue' => '', + 'foreignKey' => '', + ]; /** * @var array @@ -26,7 +28,7 @@ trait WithMeta /** * @return void */ - protected static function bootWithMeta() + protected static function bootWithMeta(): void { static::saved(function ($model) { $model->saveTmpMetas(); @@ -34,22 +36,16 @@ protected static function bootWithMeta() } /** - * @throws MetaNotSupportedException - * @throws \ReflectionException + * @throws WpOrmException + * @return void */ public function initializeWithMeta(): void { - $metaClass = $this->getMetaClass(); - $object = (new \ReflectionClass($metaClass)); - if (!$object->implementsInterface(MetaInterface::class)) { - throw new MetaNotSupportedException(sprintf( - "Model %s must be implement %s", - $metaClass, - MetaInterface::class - )); + foreach ($this->metaConfig as $optionKey => $optionValue) { + if ($optionValue === null || $optionValue === '') { + throw new WpOrmException(sprintf('Please define %s key in metaConfig property.', $optionKey)); + } } - - $this->metaModel = $object->newInstanceWithoutConstructor(); } /** @@ -57,7 +53,7 @@ public function initializeWithMeta(): void */ public function metas(): HasMany { - return $this->hasMany(get_class($this->metaModel), $this->metaModel->getFkColumn()); + return $this->hasMany($this->metaConfig['class'], $this->getMetaForeignKey()); } /** @@ -66,26 +62,24 @@ public function metas(): HasMany */ public function getMeta(string $metaKey): ?AbstractMeta { - return $this->metas() - ->firstWhere($this->metaModel->getKeyColumn(), $metaKey); + /** @var ?AbstractMeta $value */ + $value = $this->metas()->firstWhere($this->getMetaColumnKey(), $metaKey); + return $value; } /** * @param string $metaKey * @return mixed|null */ - public function getMetaValue(string $metaKey) + public function getMetaValue(string $metaKey): mixed { if (!$this->exists) { return $this->_tmpMetas[$metaKey] ?? null; } $meta = $this->getMeta($metaKey); - if (!$meta) { - return null; - } + return $meta?->getValue(); - return $meta->getValue(); } /** @@ -95,29 +89,30 @@ public function getMetaValue(string $metaKey) public function hasMeta(string $metaKey): bool { return $this->metas() - ->where($this->metaModel->getKeyColumn(), $metaKey) + ->where($this->getMetaColumnKey(), $metaKey) ->exists(); } /** * @param string $metaKey - * @param $value + * @param mixed $value * @return AbstractMeta|null */ - public function setMeta(string $metaKey, $value): ?AbstractMeta + public function setMeta(string $metaKey, mixed $value): ?AbstractMeta { if (!$this->exists) { $this->_tmpMetas[$metaKey] = $value; return null; } + /** @var AbstractMeta $instance */ $instance = $this->metas() ->firstOrNew([ - $this->metaModel->getKeyColumn() => $metaKey, + $this->getMetaForeignKey() => $metaKey, ]); $instance->fill([ - $this->metaModel->getValueColumn() => $value, + $this->getMetaColumnValue() => $value, ])->save(); return $instance; @@ -135,15 +130,10 @@ public function deleteMeta(string $metaKey): bool } return $this->metas() - ->where($this->metaModel->getKeyColumn(), $metaKey) + ->where($this->getMetaColumnKey(), $metaKey) ->forceDelete(); } - /** - * @return string - */ - abstract public function getMetaClass(): string; - /** * @return void */ @@ -155,4 +145,28 @@ protected function saveTmpMetas(): void $this->_tmpMetas = []; } + + /** + * @return string + */ + protected function getMetaColumnKey(): string + { + return $this->metaConfig['columnKey'] ?? ''; + } + + /** + * @return string + */ + protected function getMetaColumnValue(): string + { + return $this->metaConfig['columnValue'] ?? ''; + } + + /** + * @return string + */ + protected function getMetaForeignKey(): string + { + return $this->metaConfig['foreignKey'] ?? ''; + } } diff --git a/src/Models/Option.php b/src/Models/Option.php index 04efc38..be2ba8a 100644 --- a/src/Models/Option.php +++ b/src/Models/Option.php @@ -36,12 +36,7 @@ class Option extends AbstractModel implements OptionInterface /** * @inheritDoc */ - protected $fillable = [ - self::OPTION_ID, - self::NAME, - self::VALUE, - self::AUTOLOAD, - ]; + protected $guarded = []; /** * @inheritDoc diff --git a/src/Models/Post.php b/src/Models/Post.php index 222169c..3e1c31d 100644 --- a/src/Models/Post.php +++ b/src/Models/Post.php @@ -12,6 +12,7 @@ use Dbout\WpOrm\Api\PostInterface; use Dbout\WpOrm\Api\UserInterface; use Dbout\WpOrm\Builders\PostBuilder; +use Dbout\WpOrm\Models\Meta\AbstractMeta; use Dbout\WpOrm\Models\Meta\PostMeta; use Dbout\WpOrm\Models\Meta\WithMeta; use Dbout\WpOrm\Orm\AbstractModel; @@ -41,25 +42,7 @@ class Post extends AbstractModel implements PostInterface /** * @inheritDoc */ - protected $fillable = [ - self::CONTENT, - self::TITLE, - self::EXCERPT, - self::COMMENT_STATUS, - self::STATUS, - self::PING_STATUS, - self::PASSWORD, - self::POST_NAME, - self::TO_PING, - self::PINGED, - self::CONTENT_FILTERED, - self::PARENT, - self::GUID, - self::MENU_ORDER, - self::TYPE, - self::MIME_TYPE, - self::COMMENT_COUNT, - ]; + protected $guarded = []; /** * @inheritDoc @@ -73,6 +56,16 @@ class Post extends AbstractModel implements PostInterface self::MODIFIED_GMT => 'datetime', ]; + /** + * @var array + */ + protected array $metaConfig = [ + 'class' => PostMeta::class, + 'columnKey' => Meta\AbstractMeta::META_KEY, + 'columnValue' => AbstractMeta::META_VALUE, + 'foreignKey' => PostMeta::POST_ID, + ]; + /** * @var string */ @@ -110,14 +103,6 @@ public function newEloquentBuilder($query): PostBuilder return new PostBuilder($query); } - /** - * @inheritDoc - */ - public function getMetaClass(): string - { - return \Dbout\WpOrm\Models\Meta\PostMeta::class; - } - /** * @inheritDoc */ diff --git a/src/Models/Term.php b/src/Models/Term.php index b2cbda8..a9a2f01 100644 --- a/src/Models/Term.php +++ b/src/Models/Term.php @@ -46,12 +46,7 @@ class Term extends AbstractModel implements TermInterface /** * @inheritDoc */ - protected $fillable = [ - self::SLUG, - self::TERM_ID, - self::TERM_GROUP, - self::NAME, - ]; + protected $guarded = []; /** * @return HasOne diff --git a/src/Models/User.php b/src/Models/User.php index 596fa06..3fd2e9f 100644 --- a/src/Models/User.php +++ b/src/Models/User.php @@ -12,6 +12,7 @@ use Dbout\WpOrm\Api\PostInterface; use Dbout\WpOrm\Api\UserInterface; use Dbout\WpOrm\Builders\UserBuilder; +use Dbout\WpOrm\Models\Meta\AbstractMeta; use Dbout\WpOrm\Models\Meta\UserMeta; use Dbout\WpOrm\Models\Meta\WithMeta; use Dbout\WpOrm\Orm\AbstractModel; @@ -44,6 +45,13 @@ class User extends AbstractModel implements UserInterface self::REGISTERED => 'datetime', ]; + protected array $metaConfig = [ + 'class' => UserMeta::class, + 'columnKey' => AbstractMeta::META_KEY, + 'columnValue' => AbstractMeta::META_VALUE, + 'foreignKey' => UserMeta::USER_ID, + ]; + /** * @inheritDoc */ @@ -52,17 +60,7 @@ class User extends AbstractModel implements UserInterface /** * @inheritDoc */ - protected $fillable = [ - self::LOGIN, - self::PASSWORD, - self::NICE_NAME, - self::EMAIL, - self::URL, - self::REGISTERED, - self::ACTIVATION_KEY, - self::DISPLAY_NAME, - self::STATUS, - ]; + protected $guarded = []; /** * @return HasMany @@ -88,14 +86,6 @@ public function newEloquentBuilder($query): UserBuilder return new UserBuilder($query); } - /** - * @inheritDoc - */ - public function getMetaClass(): string - { - return \Dbout\WpOrm\Models\Meta\UserMeta::class; - } - /** * @inheritDoc */ diff --git a/src/Orm/AbstractModel.php b/src/Orm/AbstractModel.php index cda4287..eaa47ec 100644 --- a/src/Orm/AbstractModel.php +++ b/src/Orm/AbstractModel.php @@ -74,9 +74,13 @@ public function getId(): ?int * Returns model table name * * @return string + * @deprecated Remove in next version + * @see self::getTable() + * @see https://stackoverflow.com/a/20812314 */ public static function table(): string { + // @phpstan-ignore-next-line return (new static())->getTable(); } From 02a9a634fb8f1dde6812bc04ca7b4ed75e82bd84 Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Fri, 19 Jan 2024 19:57:18 +0100 Subject: [PATCH 38/67] WIP clean Meta feature --- src/Attributes/MetaConfigAttribute.php | 30 +++++++++++++ src/Models/Meta/WithMeta.php | 62 +++++++++----------------- src/Models/Post.php | 12 +---- src/Models/User.php | 9 +--- 4 files changed, 54 insertions(+), 59 deletions(-) create mode 100644 src/Attributes/MetaConfigAttribute.php diff --git a/src/Attributes/MetaConfigAttribute.php b/src/Attributes/MetaConfigAttribute.php new file mode 100644 index 0000000..e59a1c6 --- /dev/null +++ b/src/Attributes/MetaConfigAttribute.php @@ -0,0 +1,30 @@ + + */ + +namespace Dbout\WpOrm\Attributes; + +/** + * @since 3.0.0 + */ +#[\Attribute(\Attribute::TARGET_CLASS)] +class MetaConfigAttribute +{ + /** + * @param string $metaClass Meta className + * @param string $foreignKey + * @param string $columnKey Column contains the meta key + * @param string $columnValue Column contains the meta value + */ + public function __construct( + public readonly string $metaClass, + public readonly string $foreignKey, + public readonly string $columnKey = 'meta_key', + public readonly string $columnValue = 'meta_value', + ) { + } +} diff --git a/src/Models/Meta/WithMeta.php b/src/Models/Meta/WithMeta.php index cf79324..02e92a6 100644 --- a/src/Models/Meta/WithMeta.php +++ b/src/Models/Meta/WithMeta.php @@ -8,17 +8,16 @@ namespace Dbout\WpOrm\Models\Meta; +use Dbout\WpOrm\Attributes\MetaConfigAttribute; use Dbout\WpOrm\Exceptions\WpOrmException; use Illuminate\Database\Eloquent\Relations\HasMany; trait WithMeta { - protected array $metaConfig = [ - 'class' => '', - 'columnKey' => '', - 'columnValue' => '', - 'foreignKey' => '', - ]; + /** + * @var MetaConfigAttribute + */ + protected MetaConfigAttribute $metaConfig; /** * @var array @@ -41,11 +40,15 @@ protected static function bootWithMeta(): void */ public function initializeWithMeta(): void { - foreach ($this->metaConfig as $optionKey => $optionValue) { - if ($optionValue === null || $optionValue === '') { - throw new WpOrmException(sprintf('Please define %s key in metaConfig property.', $optionKey)); - } + $reflection = new \ReflectionClass(static::class); + $configs = $reflection->getAttributes(MetaConfigAttribute::class); + if ($configs === []) { + throw new WpOrmException(sprintf('Please define attribute %s.', MetaConfigAttribute::class)); } + + /** @var MetaConfigAttribute $config */ + $config = $configs[0]; + $this->metaConfig = $config; } /** @@ -53,7 +56,7 @@ public function initializeWithMeta(): void */ public function metas(): HasMany { - return $this->hasMany($this->metaConfig['class'], $this->getMetaForeignKey()); + return $this->hasMany($this->metaConfig->metaClass, $this->metaConfig->foreignKey); } /** @@ -63,7 +66,8 @@ public function metas(): HasMany public function getMeta(string $metaKey): ?AbstractMeta { /** @var ?AbstractMeta $value */ - $value = $this->metas()->firstWhere($this->getMetaColumnKey(), $metaKey); + // @phpstan-ignore-next-line + $value = $this->metas()->firstWhere($this->metaConfig->columnKey, $metaKey); return $value; } @@ -88,8 +92,9 @@ public function getMetaValue(string $metaKey): mixed */ public function hasMeta(string $metaKey): bool { + // @phpstan-ignore-next-line return $this->metas() - ->where($this->getMetaColumnKey(), $metaKey) + ->where($this->metaConfig->columnKey, $metaKey) ->exists(); } @@ -108,11 +113,11 @@ public function setMeta(string $metaKey, mixed $value): ?AbstractMeta /** @var AbstractMeta $instance */ $instance = $this->metas() ->firstOrNew([ - $this->getMetaForeignKey() => $metaKey, + $this->metaConfig->foreignKey => $metaKey, ]); $instance->fill([ - $this->getMetaColumnValue() => $value, + $this->metaConfig->columnValue => $value, ])->save(); return $instance; @@ -129,8 +134,9 @@ public function deleteMeta(string $metaKey): bool return true; } + // @phpstan-ignore-next-line return $this->metas() - ->where($this->getMetaColumnKey(), $metaKey) + ->where($this->metaConfig->columnKey, $metaKey) ->forceDelete(); } @@ -145,28 +151,4 @@ protected function saveTmpMetas(): void $this->_tmpMetas = []; } - - /** - * @return string - */ - protected function getMetaColumnKey(): string - { - return $this->metaConfig['columnKey'] ?? ''; - } - - /** - * @return string - */ - protected function getMetaColumnValue(): string - { - return $this->metaConfig['columnValue'] ?? ''; - } - - /** - * @return string - */ - protected function getMetaForeignKey(): string - { - return $this->metaConfig['foreignKey'] ?? ''; - } } diff --git a/src/Models/Post.php b/src/Models/Post.php index 3e1c31d..d343465 100644 --- a/src/Models/Post.php +++ b/src/Models/Post.php @@ -12,7 +12,6 @@ use Dbout\WpOrm\Api\PostInterface; use Dbout\WpOrm\Api\UserInterface; use Dbout\WpOrm\Builders\PostBuilder; -use Dbout\WpOrm\Models\Meta\AbstractMeta; use Dbout\WpOrm\Models\Meta\PostMeta; use Dbout\WpOrm\Models\Meta\WithMeta; use Dbout\WpOrm\Orm\AbstractModel; @@ -27,6 +26,7 @@ * @property-read static|null $parent * @property-read Comment[] $comments */ +#[\Dbout\WpOrm\Attributes\MetaConfigAttribute(PostMeta::class, PostMeta::POST_ID)] class Post extends AbstractModel implements PostInterface { use WithMeta; @@ -56,16 +56,6 @@ class Post extends AbstractModel implements PostInterface self::MODIFIED_GMT => 'datetime', ]; - /** - * @var array - */ - protected array $metaConfig = [ - 'class' => PostMeta::class, - 'columnKey' => Meta\AbstractMeta::META_KEY, - 'columnValue' => AbstractMeta::META_VALUE, - 'foreignKey' => PostMeta::POST_ID, - ]; - /** * @var string */ diff --git a/src/Models/User.php b/src/Models/User.php index 3fd2e9f..1c71360 100644 --- a/src/Models/User.php +++ b/src/Models/User.php @@ -12,7 +12,6 @@ use Dbout\WpOrm\Api\PostInterface; use Dbout\WpOrm\Api\UserInterface; use Dbout\WpOrm\Builders\UserBuilder; -use Dbout\WpOrm\Models\Meta\AbstractMeta; use Dbout\WpOrm\Models\Meta\UserMeta; use Dbout\WpOrm\Models\Meta\WithMeta; use Dbout\WpOrm\Orm\AbstractModel; @@ -25,6 +24,7 @@ * @property-read Comment[] $comments * @property-read Post[] $posts */ +#[\Dbout\WpOrm\Attributes\MetaConfigAttribute(UserMeta::class, UserMeta::USER_ID)] class User extends AbstractModel implements UserInterface { use WithMeta; @@ -45,13 +45,6 @@ class User extends AbstractModel implements UserInterface self::REGISTERED => 'datetime', ]; - protected array $metaConfig = [ - 'class' => UserMeta::class, - 'columnKey' => AbstractMeta::META_KEY, - 'columnValue' => AbstractMeta::META_VALUE, - 'foreignKey' => UserMeta::USER_ID, - ]; - /** * @inheritDoc */ From eb5574fb63127d205db7a4a21794274aa5ac1e4b Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Fri, 19 Jan 2024 22:05:03 +0100 Subject: [PATCH 39/67] Finish clean Meta builder, CS, PHPStan level 5, clean Api models --- phpstan.neon | 2 +- src/Api/CommentInterface.php | 199 ------------------ src/Api/OptionInterface.php | 18 -- src/Api/PostInterface.php | 50 ----- src/Api/TermInterface.php | 9 - src/Api/TermRelationshipInterface.php | 9 - src/Api/TermTaxonomyInterface.php | 13 -- src/Api/UserInterface.php | 38 ---- src/Builders/AbstractBuilder.php | 11 - src/Builders/AbstractWithMetaBuilder.php | 174 +++++++++++++++ src/Builders/PostBuilder.php | 5 +- src/Builders/TermBuilder.php | 4 +- src/Builders/Traits/WithMeta.php | 139 ------------ src/Builders/UserBuilder.php | 5 +- .../WithMeta.php => Concerns/HasMeta.php} | 19 +- src/Models/Comment.php | 152 +++++++++---- src/Models/Option.php | 15 +- src/Models/Post.php | 52 ++++- src/Models/Term.php | 12 +- src/Models/TermRelationship.php | 8 + src/Models/TermTaxonomy.php | 10 + src/Models/User.php | 39 +++- src/Orm/AbstractModel.php | 7 +- src/Orm/Database.php | 69 ++---- src/Taps/Comment/IsCommentTypeTap.php | 35 +++ 25 files changed, 473 insertions(+), 621 deletions(-) create mode 100644 src/Builders/AbstractWithMetaBuilder.php delete mode 100644 src/Builders/Traits/WithMeta.php rename src/{Models/Meta/WithMeta.php => Concerns/HasMeta.php} (90%) create mode 100644 src/Taps/Comment/IsCommentTypeTap.php diff --git a/phpstan.neon b/phpstan.neon index 1580cc6..3dfb599 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,5 +1,5 @@ parameters: - level: 2 + level: 5 paths: - src excludePaths: diff --git a/src/Api/CommentInterface.php b/src/Api/CommentInterface.php index 1d3ae28..57b306b 100644 --- a/src/Api/CommentInterface.php +++ b/src/Api/CommentInterface.php @@ -8,41 +8,7 @@ namespace Dbout\WpOrm\Api; -use Carbon\Carbon; -use Dbout\WpOrm\Models\Comment; -use Dbout\WpOrm\Models\Post; -use Dbout\WpOrm\Models\User; - /** - * @method Comment setCommentAuthor(?string $author) - * @method string|null getCommentAuthor() - * @method Comment setCommentAuthorEmail(?string $email) - * @method string|null getCommentAuthorEmail() - * @method Comment setCommentAuthorUrl(?string $url) - * @method string|null getCommentAuthorUrl() - * @method Comment setCommentAuthorIP(?string $ip) - * @method string|null getCommentAuthorIP() - * @method Comment setCommentContent(?string $content) - * @method string|null getCommentContent() - * @method Comment setCommentKarma(?int $karma) - * @method int|null getCommentKarma() - * @method Comment setCommentApproved(string $approved) - * @method string getCommentApproved() - * @method Comment setCommentAgent(?string $agent) - * @method string|null getCommentAgent() - * @method Comment setCommentType(?string $type) - * @method string|null getCommentType() - * @method Comment setUserId(?int $userId) - * @method int|null getUserId() - * @method Comment setCommentDate(mixed $date) - * @method Carbon|null getCommentDate() - * @method Comment setCommentDateGmt(mixed $date) - * @method Carbon|null getCommentDateGmt() - * - * @property-read User|null $user - * @property-read Post|null $post - * @property-read Comment|null $parent - * * @since 3.0.0 */ interface CommentInterface @@ -62,169 +28,4 @@ interface CommentInterface public const TYPE = 'comment_type'; public const PARENT = 'comment_parent'; public const USER_ID = 'user_id'; - - /** - * @param string $author - * @return self - * @deprecated Remove in next version - * @see setCommentAuthor() - */ - public function setAuthor(string $author): self; - - /** - * @return string|null - * @deprecated Remove in next version - * @see getCommentAuthor() - */ - public function getAuthor(): ?string; - - /** - * @param string|null $email - * @return self - * @deprecated Remove in next version - * @see setCommentAuthorEmail() - */ - public function setAuthorEmail(?string $email): self; - - /** - * @return string|null - * @deprecated Remove in next version - * @see getCommentAuthorEmail() - */ - public function getAuthorEmail(): ?string; - - /** - * @param string|null $url - * @return self - * @deprecated Remove in next version - * @see setCommentAuthorUrl() - */ - public function setAuthorUrl(?string $url): self; - - /** - * @return string|null - * @deprecated Remove in next version - * @see getCommentAuthorUrl() - */ - public function getAuthorUrl(): ?string; - - /** - * @param string|null $ip - * @return self - * @deprecated Remove in next version - * @see setCommentAuthorIP() - */ - public function setAuthorIp(?string $ip): self; - - /** - * @return string|null - * @deprecated Remove in next version - * @see getCommentAuthorIP() - */ - public function getAuthorIp(): ?string; - - /** - * @param string|null $content - * @return self - * @deprecated Remove in next version - * @see setCommentContent() - */ - public function setContent(?string $content): self; - - /** - * @return string|null - * @deprecated Remove in next version - * @see gsetCommentContent() - */ - public function getContent(): ?string; - - /** - * @param int|null $karma - * @return self - * @deprecated Remove in next version - * @see setCommentKarma() - */ - public function setKarma(?int $karma): self; - - /** - * @return int|null - * @deprecated Remove in next version - * @see getCommentKarma() - */ - public function getKarma(): ?int; - - /** - * @param string|null $agent - * @return self - * @deprecated Remove in next version - * @see setCommentAgent() - */ - public function setAgent(?string $agent): self; - - /** - * @return string|null - * @deprecated Remove in next version - * @see getCommentAgent() - */ - public function getAgent(): ?string; - - /** - * @param string|null $type - * @return self - * @deprecated Remove in next version - * @see setCommentType() - */ - public function setType(?string $type): self; - - /** - * @return string|null - * @deprecated Remove in next version - * @see getCommentType() - */ - public function getType(): ?string; - - /** - * @param string|null $approved - * @return self - * @deprecated Remove in next version - * @see setCommentApproved() - */ - public function setApproved(?string $approved): self; - - /** - * @return string|null - * @deprecated Remove in next version - * @see getCommentApproved() - */ - public function getApproved(): ?string; - - /** - * @param mixed $date - * @return self - * @deprecated Remove in next version - * @see setCommentDate() - */ - public function setDate(mixed $date): self; - - /** - * @return Carbon|null - * @deprecated Remove in next version - * @see getCommentDate() - */ - public function getDate(): ?Carbon; - - /** - * @param mixed $date - * @return self - * @deprecated Remove in next version - * @see setCommentDateGmt() - */ - public function setDateGMT(mixed $date): self; - - /** - * @return Carbon|null - * @deprecated Remove in next version - * @see getCommentDateGmt() - */ - public function getDateGMT(): ?Carbon; } diff --git a/src/Api/OptionInterface.php b/src/Api/OptionInterface.php index f08bfad..20593db 100644 --- a/src/Api/OptionInterface.php +++ b/src/Api/OptionInterface.php @@ -8,17 +8,7 @@ namespace Dbout\WpOrm\Api; -use Dbout\WpOrm\Enums\YesNo; -use Dbout\WpOrm\Models\Option; - /** - * @method Option setOptionName(string $name) - * @method string getOptionName() - * @method Option setOptionValue($value) - * @method mixed getOptionValue() - * @method Option setAutoload(string|YesNo $autoload) - * @method string getAutoload() - * * @since 3.0.0 */ interface OptionInterface @@ -27,12 +17,4 @@ interface OptionInterface public const NAME = 'option_name'; public const VALUE = 'option_value'; public const AUTOLOAD = 'autoload'; - - /** - * Find one option by name - * - * @param string $optionName - * @return self|null - */ - public static function findOneByName(string $optionName): ?self; } diff --git a/src/Api/PostInterface.php b/src/Api/PostInterface.php index 15dcd18..4dce846 100644 --- a/src/Api/PostInterface.php +++ b/src/Api/PostInterface.php @@ -8,49 +8,7 @@ namespace Dbout\WpOrm\Api; -use Carbon\Carbon; -use Dbout\WpOrm\Models\Post; - /** - * @method Post setPostDate($date) - * @method Carbon|null getPostDate() - * @method Post setPostDateGMT($date) - * @method Carbon|null getPostDateGMT() - * @method Post setPostContent(?string $content) - * @method string|null getPostContent() - * @method Post setPostType(string $type) - * @method string|null getPostType() - * @method Post setGuid(?string $guid) - * @method string|null getGuid() - * @method Post setPostTitle(?string $title) - * @method string|null getPostTitle() - * @method Post setPostExcerpt(?string $excerpt) - * @method string|null getPostExcerpt() - * @method Post setPostStatus(?string $status) - * @method string|null getPostStatus() - * @method Post setCommentStatus(string $status) - * @method string|null getCommentStatus() - * @method Post setPingStatus(string $status) - * @method string|null getPingStatus() - * @method Post setPostPassword(?string $password) - * @method string|null getPostPassword() - * @method Post setPostName(?string $name) - * @method string|null getPostName() - * @method Post setToPing(?string $toPing) - * @method string|null getToPing() - * @method Post setPinged(?string $pinged) - * @method string|null getPinged() - * @method Post setPostModified($modified) - * @method Carbon|null getPostModified() - * @method Post setPostModifiedGMT($modified) - * @method Carbon|null getPostModifiedGMT() - * @method setPostMimeType(?string $mimeType) - * @method string|null getPostMimeType() - * @method Post setMenuOrder(?int $order) - * @method int|null getMenuOrder() - * @method Post setPostContentFiltered($content) - * @method string|null getPostContentFiltered() - * * @since 3.0.0 */ interface PostInterface @@ -78,12 +36,4 @@ interface PostInterface public const TYPE = 'post_type'; public const MIME_TYPE = 'post_mime_type'; public const COMMENT_COUNT = 'comment_count'; - - /** - * Find post by name - * - * @param string|null $name - * @return Post|null - */ - public function findOneByName(?string $name): ?Post; } diff --git a/src/Api/TermInterface.php b/src/Api/TermInterface.php index f8374a4..a3b31dd 100644 --- a/src/Api/TermInterface.php +++ b/src/Api/TermInterface.php @@ -8,16 +8,7 @@ namespace Dbout\WpOrm\Api; -use Dbout\WpOrm\Models\Term; - /** - * @method string|null getName() - * @method Term setName(?string $name); - * @method string|null getSlug() - * @method Term setSlug(?string $slug) - * @method int|null getTermGroup() - * @method Term setTermGroup(?int $group) - * * @since 3.0.0 */ interface TermInterface diff --git a/src/Api/TermRelationshipInterface.php b/src/Api/TermRelationshipInterface.php index 8162d3e..451610c 100644 --- a/src/Api/TermRelationshipInterface.php +++ b/src/Api/TermRelationshipInterface.php @@ -8,16 +8,7 @@ namespace Dbout\WpOrm\Api; -use Dbout\WpOrm\Models\TermRelationship; - /** - * @method int|null getTermOrder() - * @method TermRelationship setTermOrder(?int $order) - * @method int|null getTermTaxonomyId() - * @method TermRelationship setTermTaxonomyId(?int $id) - * @method int|null getObjectId() - * @method TermRelationship setObjectId(?int $id) - * * @since 3.0.0 */ interface TermRelationshipInterface diff --git a/src/Api/TermTaxonomyInterface.php b/src/Api/TermTaxonomyInterface.php index 731bae8..d66446b 100644 --- a/src/Api/TermTaxonomyInterface.php +++ b/src/Api/TermTaxonomyInterface.php @@ -8,20 +8,7 @@ namespace Dbout\WpOrm\Api; -use Dbout\WpOrm\Models\TermTaxonomy; - /** - * @method int|null getTermId() - * @method TermTaxonomy setTermId(int $id) - * @method string getTaxonomy() - * @method TermTaxonomy setTaxonomy(string $taxonomy) - * @method string|null getDescription() - * @method TermTaxonomy setDescription(?string $description) - * @method int|null getParent() - * @method TermTaxonomy setParent($parent) - * @method int|null getCount() - * @method TermTaxonomy setCount(int $count) - * * @since 3.0.0 */ interface TermTaxonomyInterface diff --git a/src/Api/UserInterface.php b/src/Api/UserInterface.php index 9c00541..1029673 100644 --- a/src/Api/UserInterface.php +++ b/src/Api/UserInterface.php @@ -8,29 +8,7 @@ namespace Dbout\WpOrm\Api; -use Carbon\Carbon; -use Dbout\WpOrm\Models\User; - /** - * @method string|null getUserLogin() - * @method User setUserLogin(string $login) - * @method string|null getUserPass() - * @method User setUserPass(string $password) - * @method string|null getUserNicename() - * @method User setUserNicename(string $nicename) - * @method string|null getUserEmail() - * @method User setUserEmail(string $email) - * @method string|null getUserUrl() - * @method User setUserUrl(?string $url) - * @method Carbon|null getUserRegistered() - * @method User setUserRegistered($date) - * @method string|null getUserActivationKey() - * @method User setUserActivationKey(?string $key) - * @method int getUserStatus() - * @method User setUserStatus(int $status) - * @method string|null getDisplayName() - * @method User setDisplayName(?string $name) - * * @since 3.0.0 */ interface UserInterface @@ -45,20 +23,4 @@ interface UserInterface public const ACTIVATION_KEY = 'user_activation_key'; public const DISPLAY_NAME = 'display_name'; public const STATUS = 'user_status'; - - /** - * Find user by email - * - * @param string $email - * @return self|null - */ - public static function findOneByEmail(string $email): ?self; - - /** - * Find user by login - * - * @param string $login - * @return self|null - */ - public static function findOneByLogin(string $login): ?self; } diff --git a/src/Builders/AbstractBuilder.php b/src/Builders/AbstractBuilder.php index acb0145..5ce4c22 100644 --- a/src/Builders/AbstractBuilder.php +++ b/src/Builders/AbstractBuilder.php @@ -8,7 +8,6 @@ namespace Dbout\WpOrm\Builders; -use Dbout\WpOrm\Api\PostInterface; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; @@ -64,14 +63,4 @@ protected function joined($query, $table): bool return false; } - - /** - * @param string $label - * @param string $key - * @return array - */ - public function toArrayOptions(string $label = PostInterface::TITLE, string $key = PostInterface::POST_ID): array - { - return $this->pluck($label, $key)->toArray(); - } } diff --git a/src/Builders/AbstractWithMetaBuilder.php b/src/Builders/AbstractWithMetaBuilder.php new file mode 100644 index 0000000..6c35490 --- /dev/null +++ b/src/Builders/AbstractWithMetaBuilder.php @@ -0,0 +1,174 @@ + + */ + +namespace Dbout\WpOrm\Builders; + +use Dbout\WpOrm\Attributes\MetaConfigAttribute; +use Dbout\WpOrm\Exceptions\MetaNotSupportedException; +use Dbout\WpOrm\Exceptions\WpOrmException; +use Dbout\WpOrm\Orm\AbstractModel; +use Illuminate\Database\Eloquent\Model; + +/** + * @since 3.0.0 + */ +abstract class AbstractWithMetaBuilder extends AbstractBuilder +{ + /** + * @var array + */ + protected array $joinCallback = [ + 'inner' => 'join', + 'left' => 'leftJoin', + 'right' => 'rightJoin', + ]; + + /** + * @var MetaConfigAttribute|null + */ + protected ?MetaConfigAttribute $metaConfig = null; + + /** + * @var string|null + */ + protected ?string $metaTable = null; + + /** + * @inheritDoc + * @throws \Exception + */ + public function setModel(Model $model): self + { + parent::setModel($model); + $this->initMeta(); + return $this; + } + + /** + * @param string $metaKey + * @param string|null $alias + * @throws WpOrmException + * @return $this + */ + public function addMetaToSelect(string $metaKey, ?string $alias = null): self + { + $this->joinToMeta($metaKey); + if ($alias === null || $alias === '') { + $alias = $metaKey; + } + + $column = sprintf('%s.%s AS %s', $metaKey, $this->metaConfig?->columnValue, $alias); + $this->addSelect($column); + return $this; + } + + /** + * @param array|array $metas + * @throws WpOrmException + * @return $this + */ + public function addMetasToSelect(array $metas): self + { + foreach ($metas as $key => $metaName) { + $alias = null; + if (is_string($key)) { + $alias = $key; + } + + $this->addMetaToSelect($metaName, $alias); + } + + return $this; + } + + /** + * @param string $metaKey + * @param mixed $value + * @param string $operator + * @throws WpOrmException + * @return $this + */ + public function addMetaToFilter(string $metaKey, mixed $value, string $operator = '='): self + { + $this + ->joinToMeta($metaKey) + ->where(sprintf('%s.%s', $metaKey, $this->metaConfig->columnValue), $operator, $value); + + return $this; + } + + /** + * @param string $metaKey + * @param string $joinType + * @throws WpOrmException + * @return $this + */ + public function joinToMeta(string $metaKey, string $joinType = 'inner'): self + { + $model = $this->model; + $joinTable = sprintf('%s AS %s', $this->metaTable, $metaKey); + + if ($this->joined($this, $joinTable)) { + return $this; + } + + $join = $this->joinCallback[$joinType] ?? null; + if ($join === null) { + throw new WpOrmException('Invalid join type.'); + } + + $this->$join($joinTable, function ($join) use ($metaKey, $model) { + /** @var \Illuminate\Database\Query\JoinClause $join */ + $join->on( + sprintf('%s.%s', $metaKey, $this->metaConfig?->columnKey), + '=', + $join->raw(sprintf("'%s'", $metaKey)) + )->on( + sprintf('%s.%s', $metaKey, $this->metaConfig?->foreignKey), + '=', + sprintf('%s.%s', $model->getTable(), $model->getKeyName()), + ); + }); + + return $this; + } + + /** + * @throws \ReflectionException + * @throws MetaNotSupportedException + * @throws WpOrmException + */ + protected function initMeta(): void + { + $traits = class_uses_recursive(get_class($this->model)); + if (!in_array(\Dbout\WpOrm\Concerns\HasMeta::class, $traits, true)) { + throw new MetaNotSupportedException(sprintf( + 'Model %s must be use trait %s', + get_class($this->model), + \Dbout\WpOrm\Concerns\HasMeta::class + )); + } + + // @phpstan-ignore-next-line + $config = $this->model->getMetaConfig(); + $reflection = new \ReflectionClass($config->metaClass); + if (!$reflection->isSubclassOf(AbstractModel::class)) { + throw new WpOrmException(sprintf( + 'Class %s must extend from %s.', + $config->metaClass, + AbstractModel::class + )); + } + + /** @var AbstractModel $metaModel */ + $metaModel = $reflection->newInstanceWithoutConstructor(); + + $this->metaTable = $metaModel->getTable(); + $this->metaConfig = $config; + } +} diff --git a/src/Builders/PostBuilder.php b/src/Builders/PostBuilder.php index 9b28fb0..4435995 100644 --- a/src/Builders/PostBuilder.php +++ b/src/Builders/PostBuilder.php @@ -9,14 +9,11 @@ namespace Dbout\WpOrm\Builders; use Dbout\WpOrm\Api\PostInterface; -use Dbout\WpOrm\Builders\Traits\WithMeta; use Dbout\WpOrm\Models\Post; use Illuminate\Database\Eloquent\Collection; -class PostBuilder extends AbstractBuilder +class PostBuilder extends AbstractWithMetaBuilder { - use WithMeta; - /** * @param string|null $name * @return Post|null diff --git a/src/Builders/TermBuilder.php b/src/Builders/TermBuilder.php index 2925ebd..6dbc988 100644 --- a/src/Builders/TermBuilder.php +++ b/src/Builders/TermBuilder.php @@ -8,7 +8,7 @@ namespace Dbout\WpOrm\Builders; -use Dbout\WpOrm\Models\TermTaxonomy; +use Dbout\WpOrm\Api\TermTaxonomyInterface; use Illuminate\Database\Eloquent\Collection; class TermBuilder extends AbstractBuilder @@ -20,7 +20,7 @@ class TermBuilder extends AbstractBuilder public function findAllByTaxonomy(string $taxonomy): Collection { return $this->whereHas('termTaxonomy', function ($query) use ($taxonomy) { - return $query->where(TermTaxonomy::TAXONOMY, $taxonomy); + return $query->where(TermTaxonomyInterface::TAXONOMY, $taxonomy); })->get(); } } diff --git a/src/Builders/Traits/WithMeta.php b/src/Builders/Traits/WithMeta.php deleted file mode 100644 index bc2b9dd..0000000 --- a/src/Builders/Traits/WithMeta.php +++ /dev/null @@ -1,139 +0,0 @@ - - */ - -namespace Dbout\WpOrm\Builders\Traits; - -use Dbout\WpOrm\Exceptions\MetaNotSupportedException; -use Dbout\WpOrm\Models\Meta\AbstractMeta; -use Dbout\WpOrm\Orm\AbstractModel; -use Illuminate\Database\Eloquent\Model; - -trait WithMeta -{ - /** - * @var array|string[] - */ - protected array $joinCallback = [ - 'inner' => 'join', - 'left' => 'leftJoin', - 'right' => 'rightJoin', - ]; - - /** - * @var AbstractMeta|null - */ - protected ?AbstractMeta $metaModel = null; - - /** - * @param string $metaKey - * @param string|null $alias - * @return $this - */ - public function addMetaToSelect(string $metaKey, ?string $alias = null): self - { - $this - ->joinToMeta($metaKey); - - if (!$alias) { - $alias = $metaKey; - } - - $column = sprintf('%s.%s AS %s', $metaKey, $this->metaModel->getValueColumn(), $alias); - $this->addSelect($column); - return $this; - } - - /** - * @param array $metas - * @return $this - */ - public function addMetasToSelect(array $metas): self - { - foreach ($metas as $key => $metaName) { - $alias = null; - if (is_string($key)) { - $alias = $key; - } - - $this->addMetaToSelect($metaName, $alias); - } - - return $this; - } - - /** - * @param string $metaKey - * @param $value - * @param string $operator - * @return $this - */ - public function addMetaToFilter(string $metaKey, $value, string $operator = '='): self - { - $this - ->joinToMeta($metaKey) - ->where(sprintf('%s.%s', $metaKey, $this->metaModel->getValueColumn()), $operator, $value); - - return $this; - } - - /** - * @inheritDoc - * @throws MetaNotSupportedException - * @throws \ReflectionException - */ - public function setModel(Model $model) - { - $traits = class_uses_recursive(get_class($model)); - if (!in_array(\Dbout\WpOrm\Models\Meta\WithMeta::class, $traits, true)) { - throw new MetaNotSupportedException(sprintf( - 'Model %s must be use trait %s', - get_class($model), - \Dbout\WpOrm\Models\Meta\WithMeta::class - )); - } - - /** @var \Dbout\WpOrm\Models\Meta\WithMeta $model */ - $metaClass = $model->getMetaClass(); - $object = (new \ReflectionClass($metaClass)); - $this->metaModel = $object->newInstanceWithoutConstructor(); - - return parent::setModel($model); - } - - /** - * @param string $metaKey - * @param string $joinType - * @return $this - */ - public function joinToMeta(string $metaKey, string $joinType = 'inner'): self - { - /** @var AbstractModel $model */ - $model = $this->model; - $joinTable = sprintf('%s AS %s', $this->metaModel->getTable(), $metaKey); - - if ($this->joined($this, $joinTable)) { - return $this; - } - - $join = $this->joinCallback[$joinType]; - $this->$join($joinTable, function ($join) use ($metaKey, $model) { - /** @var \Illuminate\Database\Query\JoinClause $join */ - $join->on( - sprintf('%s.%s', $metaKey, $this->metaModel->getKeyColumn()), - '=', - $join->raw(sprintf("'%s'", $metaKey)) - )->on( - $join->raw(sprintf('%s.%s', $metaKey, $this->metaModel->getFkColumn())), - '=', - sprintf('%s.%s', $model->getTable(), $model->getKeyName()), - ); - }); - - return $this; - } -} diff --git a/src/Builders/UserBuilder.php b/src/Builders/UserBuilder.php index 42ca0b2..8a650ad 100644 --- a/src/Builders/UserBuilder.php +++ b/src/Builders/UserBuilder.php @@ -9,13 +9,10 @@ namespace Dbout\WpOrm\Builders; use Dbout\WpOrm\Api\UserInterface; -use Dbout\WpOrm\Builders\Traits\WithMeta; use Dbout\WpOrm\Models\User; -class UserBuilder extends AbstractBuilder +class UserBuilder extends AbstractWithMetaBuilder { - use WithMeta; - /** * @param string $email * @return User|null diff --git a/src/Models/Meta/WithMeta.php b/src/Concerns/HasMeta.php similarity index 90% rename from src/Models/Meta/WithMeta.php rename to src/Concerns/HasMeta.php index 02e92a6..50ea2dd 100644 --- a/src/Models/Meta/WithMeta.php +++ b/src/Concerns/HasMeta.php @@ -6,13 +6,14 @@ * Author: Dimitri BOUTEILLE */ -namespace Dbout\WpOrm\Models\Meta; +namespace Dbout\WpOrm\Concerns; use Dbout\WpOrm\Attributes\MetaConfigAttribute; use Dbout\WpOrm\Exceptions\WpOrmException; +use Dbout\WpOrm\Models\Meta\AbstractMeta; use Illuminate\Database\Eloquent\Relations\HasMany; -trait WithMeta +trait HasMeta { /** * @var MetaConfigAttribute @@ -27,7 +28,7 @@ trait WithMeta /** * @return void */ - protected static function bootWithMeta(): void + protected static function bootHasMeta(): void { static::saved(function ($model) { $model->saveTmpMetas(); @@ -38,7 +39,7 @@ protected static function bootWithMeta(): void * @throws WpOrmException * @return void */ - public function initializeWithMeta(): void + public function initializeHasMeta(): void { $reflection = new \ReflectionClass(static::class); $configs = $reflection->getAttributes(MetaConfigAttribute::class); @@ -47,7 +48,7 @@ public function initializeWithMeta(): void } /** @var MetaConfigAttribute $config */ - $config = $configs[0]; + $config = $configs[0]; $this->metaConfig = $config; } @@ -151,4 +152,12 @@ protected function saveTmpMetas(): void $this->_tmpMetas = []; } + + /** + * @return MetaConfigAttribute|null + */ + public function getMetaConfig(): ?MetaConfigAttribute + { + return $this->metaConfig; + } } diff --git a/src/Models/Comment.php b/src/Models/Comment.php index 995dd5b..5e0707f 100644 --- a/src/Models/Comment.php +++ b/src/Models/Comment.php @@ -17,8 +17,36 @@ use Illuminate\Database\Eloquent\Relations\HasOne; /** + * @method Comment setCommentAuthor(?string $author) + * @method string|null getCommentAuthor() + * @method Comment setCommentAuthorEmail(?string $email) + * @method string|null getCommentAuthorEmail() + * @method Comment setCommentAuthorUrl(?string $url) + * @method string|null getCommentAuthorUrl() + * @method Comment setCommentAuthorIP(?string $ip) + * @method string|null getCommentAuthorIP() + * @method Comment setCommentContent(?string $content) + * @method string|null getCommentContent() + * @method Comment setCommentKarma(?int $karma) + * @method int|null getCommentKarma() + * @method Comment setCommentApproved(string $approved) + * @method string getCommentApproved() + * @method Comment setCommentAgent(?string $agent) + * @method string|null getCommentAgent() + * @method Comment setCommentType(?string $type) + * @method string|null getCommentType() + * @method Comment setUserId(?int $userId) + * @method int|null getUserId() + * @method Comment setCommentDate(mixed $date) + * @method Carbon|null getCommentDate() + * @method Comment setCommentDateGmt(mixed $date) + * @method Carbon|null getCommentDateGmt() * @method static static|null find(int $commentId) * @method static CommentBuilder query() + * + * @property-read User|null $user + * @property-read Post|null $post + * @property-read Comment|null $parent */ class Comment extends AbstractModel implements CommentInterface { @@ -35,11 +63,6 @@ class Comment extends AbstractModel implements CommentInterface */ protected $table = 'comments'; - /** - * @inheritDoc - */ - protected $guarded = []; - /** * @inheritDoc */ @@ -82,15 +105,20 @@ public function newEloquentBuilder($query): CommentBuilder } /** - * @inheritDoc + * @param string $author + * @return self + * @deprecated Remove in next version + * @see setCommentAuthor() */ - public function setAuthor(string $author): CommentInterface + public function setAuthor(string $author): self { return $this->setCommentAuthor($author); } /** - * @inheritDoc + * @return string|null + * @deprecated Remove in next version + * @see getCommentAuthor() */ public function getAuthor(): ?string { @@ -98,15 +126,20 @@ public function getAuthor(): ?string } /** - * @inheritDoc + * @param string|null $email + * @return self + * @deprecated Remove in next version + * @see setCommentAuthorEmail() */ - public function setAuthorEmail(?string $email): CommentInterface + public function setAuthorEmail(?string $email): self { return $this->setCommentAuthorEmail($email); } /** - * @inheritDoc + * @return string|null + * @deprecated Remove in next version + * @see getCommentAuthorEmail() */ public function getAuthorEmail(): ?string { @@ -114,15 +147,20 @@ public function getAuthorEmail(): ?string } /** - * @inheritDoc + * @param string|null $url + * @return self + * @deprecated Remove in next version + * @see setCommentAuthorUrl() */ - public function setAuthorUrl(?string $url): CommentInterface + public function setAuthorUrl(?string $url): self { return $this->setCommentAuthorUrl($url); } /** - * @inheritDoc + * @return string|null + * @deprecated Remove in next version + * @see getCommentAuthorUrl() */ public function getAuthorUrl(): ?string { @@ -130,15 +168,20 @@ public function getAuthorUrl(): ?string } /** - * @inheritDoc + * @param string|null $ip + * @return self + * @deprecated Remove in next version + * @see setCommentAuthorIP() */ - public function setAuthorIp(?string $ip): CommentInterface + public function setAuthorIp(?string $ip): self { return $this->setCommentAuthorIP($ip); } /** - * @inheritDoc + * @return string|null + * @deprecated Remove in next version + * @see getCommentAuthorIP() */ public function getAuthorIp(): ?string { @@ -146,15 +189,20 @@ public function getAuthorIp(): ?string } /** - * @inheritDoc + * @param string|null $content + * @return self + * @deprecated Remove in next version + * @see setCommentContent() */ - public function setContent(?string $content): CommentInterface + public function setContent(?string $content): self { return $this->setCommentContent($content); } /** - * @inheritDoc + * @return string|null + * @deprecated Remove in next version + * @see gsetCommentContent() */ public function getContent(): ?string { @@ -162,15 +210,20 @@ public function getContent(): ?string } /** - * @inheritDoc + * @param int|null $karma + * @return self + * @deprecated Remove in next version + * @see setCommentKarma() */ - public function setKarma(?int $karma): CommentInterface + public function setKarma(?int $karma): self { return $this->setCommentKarma($karma); } /** * @inheritDoc + * @deprecated Remove in next version + * @see getCommentKarma() */ public function getKarma(): ?int { @@ -178,15 +231,20 @@ public function getKarma(): ?int } /** - * @inheritDoc + * @param string|null $agent + * @return self + * @deprecated Remove in next version + * @see setCommentAgent() */ - public function setAgent(?string $agent): CommentInterface + public function setAgent(?string $agent): self { return $this->setCommentAgent($agent); } /** - * @inheritDoc + * @return string|null + * @deprecated Remove in next version + * @see getCommentAgent() */ public function getAgent(): ?string { @@ -194,15 +252,20 @@ public function getAgent(): ?string } /** - * @inheritDoc + * @param string|null $type + * @return self + * @deprecated Remove in next version + * @see setCommentType() */ - public function setType(?string $type): CommentInterface + public function setType(?string $type): self { return $this->setCommentType($type); } /** - * @inheritDoc + * @return string|null + * @deprecated Remove in next version + * @see getCommentType() */ public function getType(): ?string { @@ -210,15 +273,20 @@ public function getType(): ?string } /** - * @inheritDoc + * @param string|null $approved + * @return self + * @deprecated Remove in next version + * @see setCommentApproved() */ - public function setApproved(?string $approved): CommentInterface + public function setApproved(?string $approved): self { return $this->setCommentApproved($approved); } /** - * @inheritDoc + * @return string|null + * @deprecated Remove in next version + * @see getCommentApproved() */ public function getApproved(): ?string { @@ -226,15 +294,20 @@ public function getApproved(): ?string } /** - * @inheritDoc + * @param mixed $date + * @return self + * @deprecated Remove in next version + * @see setCommentDate() */ - public function setDate(mixed $date): CommentInterface + public function setDate(mixed $date): self { return $this->setCommentDate($date); } /** - * @inheritDoc + * @return Carbon|null + * @deprecated Remove in next version + * @see getCommentDate() */ public function getDate(): ?Carbon { @@ -242,15 +315,20 @@ public function getDate(): ?Carbon } /** - * @inheritDoc + * @param mixed $date + * @return self + * @deprecated Remove in next version + * @see setCommentDateGmt() */ - public function setDateGMT(mixed $date): CommentInterface + public function setDateGMT(mixed $date): self { return $this->setCommentDateGmt($date); } /** - * @inheritDoc + * @return Carbon|null + * @deprecated Remove in next version + * @see getCommentDateGmt() */ public function getDateGMT(): ?Carbon { diff --git a/src/Models/Option.php b/src/Models/Option.php index be2ba8a..efaf4bb 100644 --- a/src/Models/Option.php +++ b/src/Models/Option.php @@ -10,9 +10,16 @@ use Dbout\WpOrm\Api\OptionInterface; use Dbout\WpOrm\Builders\OptionBuilder; +use Dbout\WpOrm\Enums\YesNo; use Dbout\WpOrm\Orm\AbstractModel; /** + * @method Option setOptionName(string $name) + * @method string getOptionName() + * @method Option setOptionValue($value) + * @method mixed getOptionValue() + * @method Option setAutoload(string|YesNo $autoload) + * @method string getAutoload() * @method static static|null find($optionId) * @method static OptionBuilder query() */ @@ -33,11 +40,6 @@ class Option extends AbstractModel implements OptionInterface */ public $timestamps = false; - /** - * @inheritDoc - */ - protected $guarded = []; - /** * @inheritDoc */ @@ -47,7 +49,8 @@ public function newEloquentBuilder($query): OptionBuilder } /** - * @inheritDoc + * @param string $optionName + * @return self|null */ public static function findOneByName(string $optionName): ?self { diff --git a/src/Models/Post.php b/src/Models/Post.php index d343465..7e88a66 100644 --- a/src/Models/Post.php +++ b/src/Models/Post.php @@ -8,19 +8,59 @@ namespace Dbout\WpOrm\Models; +use Carbon\Carbon; use Dbout\WpOrm\Api\CommentInterface; use Dbout\WpOrm\Api\PostInterface; use Dbout\WpOrm\Api\UserInterface; use Dbout\WpOrm\Builders\PostBuilder; +use Dbout\WpOrm\Concerns\HasMeta; use Dbout\WpOrm\Models\Meta\PostMeta; -use Dbout\WpOrm\Models\Meta\WithMeta; use Dbout\WpOrm\Orm\AbstractModel; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\HasOne; /** + * @method Post setPostDate($date) + * @method Carbon|null getPostDate() + * @method Post setPostDateGMT($date) + * @method Carbon|null getPostDateGMT() + * @method Post setPostContent(?string $content) + * @method string|null getPostContent() + * @method Post setPostType(string $type) + * @method string|null getPostType() + * @method Post setGuid(?string $guid) + * @method string|null getGuid() + * @method Post setPostTitle(?string $title) + * @method string|null getPostTitle() + * @method Post setPostExcerpt(?string $excerpt) + * @method string|null getPostExcerpt() + * @method Post setPostStatus(?string $status) + * @method string|null getPostStatus() + * @method Post setCommentStatus(string $status) + * @method string|null getCommentStatus() + * @method Post setPingStatus(string $status) + * @method string|null getPingStatus() + * @method Post setPostPassword(?string $password) + * @method string|null getPostPassword() + * @method Post setPostName(?string $name) + * @method string|null getPostName() + * @method Post setToPing(?string $toPing) + * @method string|null getToPing() + * @method Post setPinged(?string $pinged) + * @method string|null getPinged() + * @method Post setPostModified($modified) + * @method Carbon|null getPostModified() + * @method Post setPostModifiedGMT($modified) + * @method Carbon|null getPostModifiedGMT() + * @method setPostMimeType(?string $mimeType) + * @method string|null getPostMimeType() + * @method Post setMenuOrder(?int $order) + * @method int|null getMenuOrder() + * @method Post setPostContentFiltered($content) + * @method string|null getPostContentFiltered() * @method static static find(int $postId) * @method static PostBuilder query() + * * @property-read User|null $author * @property-read PostMeta[] $metas * @property-read static|null $parent @@ -29,7 +69,7 @@ #[\Dbout\WpOrm\Attributes\MetaConfigAttribute(PostMeta::class, PostMeta::POST_ID)] class Post extends AbstractModel implements PostInterface { - use WithMeta; + use HasMeta; public const UPDATED_AT = self::MODIFIED; public const CREATED_AT = self::DATE; @@ -39,11 +79,6 @@ class Post extends AbstractModel implements PostInterface */ protected $primaryKey = self::POST_ID; - /** - * @inheritDoc - */ - protected $guarded = []; - /** * @inheritDoc */ @@ -94,7 +129,8 @@ public function newEloquentBuilder($query): PostBuilder } /** - * @inheritDoc + * @param string|null $name + * @return Post|null */ public function findOneByName(?string $name): ?Post { diff --git a/src/Models/Term.php b/src/Models/Term.php index a9a2f01..7801ecb 100644 --- a/src/Models/Term.php +++ b/src/Models/Term.php @@ -15,8 +15,15 @@ use Illuminate\Database\Eloquent\Relations\HasOne; /** + * @method string|null getName() + * @method Term setName(?string $name); + * @method string|null getSlug() + * @method Term setSlug(?string $slug) + * @method int|null getTermGroup() + * @method Term setTermGroup(?int $group) * @method static static|null find(int $termId) * @method static TermBuilder query() + * * @property-read TermTaxonomy|null $termTaxonomy */ class Term extends AbstractModel implements TermInterface @@ -43,11 +50,6 @@ class Term extends AbstractModel implements TermInterface self::TERM_GROUP => 'integer', ]; - /** - * @inheritDoc - */ - protected $guarded = []; - /** * @return HasOne */ diff --git a/src/Models/TermRelationship.php b/src/Models/TermRelationship.php index d38af12..63f8b84 100644 --- a/src/Models/TermRelationship.php +++ b/src/Models/TermRelationship.php @@ -11,6 +11,14 @@ use Dbout\WpOrm\Api\TermRelationshipInterface; use Dbout\WpOrm\Orm\AbstractModel; +/** + * @method int|null getTermOrder() + * @method TermRelationship setTermOrder(?int $order) + * @method int|null getTermTaxonomyId() + * @method TermRelationship setTermTaxonomyId(?int $id) + * @method int|null getObjectId() + * @method TermRelationship setObjectId(?int $id) + */ class TermRelationship extends AbstractModel implements TermRelationshipInterface { /** diff --git a/src/Models/TermTaxonomy.php b/src/Models/TermTaxonomy.php index 365d9d0..6bb7668 100644 --- a/src/Models/TermTaxonomy.php +++ b/src/Models/TermTaxonomy.php @@ -12,6 +12,16 @@ use Dbout\WpOrm\Orm\AbstractModel; /** + * @method int|null getTermId() + * @method TermTaxonomy setTermId(int $id) + * @method string getTaxonomy() + * @method TermTaxonomy setTaxonomy(string $taxonomy) + * @method string|null getDescription() + * @method TermTaxonomy setDescription(?string $description) + * @method int|null getParent() + * @method TermTaxonomy setParent($parent) + * @method int|null getCount() + * @method TermTaxonomy setCount(int $count) * @method static static|null find(int $id) */ class TermTaxonomy extends AbstractModel implements TermTaxonomyInterface diff --git a/src/Models/User.php b/src/Models/User.php index 1c71360..5871da3 100644 --- a/src/Models/User.php +++ b/src/Models/User.php @@ -8,18 +8,38 @@ namespace Dbout\WpOrm\Models; +use Carbon\Carbon; use Dbout\WpOrm\Api\CommentInterface; use Dbout\WpOrm\Api\PostInterface; use Dbout\WpOrm\Api\UserInterface; use Dbout\WpOrm\Builders\UserBuilder; +use Dbout\WpOrm\Concerns\HasMeta; use Dbout\WpOrm\Models\Meta\UserMeta; -use Dbout\WpOrm\Models\Meta\WithMeta; use Dbout\WpOrm\Orm\AbstractModel; use Illuminate\Database\Eloquent\Relations\HasMany; /** + * @method string|null getUserLogin() + * @method User setUserLogin(string $login) + * @method string|null getUserPass() + * @method User setUserPass(string $password) + * @method string|null getUserNicename() + * @method User setUserNicename(string $nicename) + * @method string|null getUserEmail() + * @method User setUserEmail(string $email) + * @method string|null getUserUrl() + * @method User setUserUrl(?string $url) + * @method Carbon|null getUserRegistered() + * @method User setUserRegistered($date) + * @method string|null getUserActivationKey() + * @method User setUserActivationKey(?string $key) + * @method int getUserStatus() + * @method User setUserStatus(int $status) + * @method string|null getDisplayName() + * @method User setDisplayName(?string $name) * @method static static|null find($userId) * @method static UserBuilder query() + * * @property-read UserMeta[] $metas * @property-read Comment[] $comments * @property-read Post[] $posts @@ -27,10 +47,10 @@ #[\Dbout\WpOrm\Attributes\MetaConfigAttribute(UserMeta::class, UserMeta::USER_ID)] class User extends AbstractModel implements UserInterface { - use WithMeta; + use HasMeta; - public const CREATED_AT = self::REGISTERED; - public const UPDATED_AT = null; + final public const CREATED_AT = self::REGISTERED; + final public const UPDATED_AT = null; /** * @inheritDoc @@ -50,11 +70,6 @@ class User extends AbstractModel implements UserInterface */ protected $primaryKey = self::USER_ID; - /** - * @inheritDoc - */ - protected $guarded = []; - /** * @return HasMany */ @@ -80,7 +95,8 @@ public function newEloquentBuilder($query): UserBuilder } /** - * @inheritDoc + * @param string $email + * @return self|null */ public static function findOneByEmail(string $email): ?self { @@ -90,7 +106,8 @@ public static function findOneByEmail(string $email): ?self } /** - * @inheritDoc + * @param string $login + * @return self|null */ public static function findOneByLogin(string $login): ?self { diff --git a/src/Orm/AbstractModel.php b/src/Orm/AbstractModel.php index eaa47ec..62bcf1d 100644 --- a/src/Orm/AbstractModel.php +++ b/src/Orm/AbstractModel.php @@ -14,7 +14,11 @@ abstract class AbstractModel extends Model { /** - * AbstractModel constructor. + * @inheritDoc + */ + protected $guarded = []; + + /** * @param array $attributes */ public function __construct(array $attributes = []) @@ -41,6 +45,7 @@ protected function newBaseQueryBuilder() */ public function getConnection() { + // @phpstan-ignore-next-line return Database::getInstance(); } diff --git a/src/Orm/Database.php b/src/Orm/Database.php index f5dec80..6b685f4 100644 --- a/src/Orm/Database.php +++ b/src/Orm/Database.php @@ -82,7 +82,7 @@ public function __construct() } /** - * @return mixed|string + * @inheritDoc */ public function getDatabaseName() { @@ -106,9 +106,7 @@ public function getTablePrefix(): ?string } /** - * @param \Closure|\Illuminate\Database\Query\Builder|string $table - * @param null $as - * @return Builder|\Illuminate\Database\Query\Builder + * @inheritDoc */ public function table($table, $as = null) { @@ -120,11 +118,7 @@ public function table($table, $as = null) } /** - * Get a new raw query expression. - * - * @param mixed $value - * - * @return \Illuminate\Database\Query\Expression + * @inheritDoc */ public function raw($value) { @@ -146,38 +140,28 @@ public function query() } /** - * Run a select statement and return a single result - * - * @param string $query - * @param array $bindings - * @param bool $useReadPdo - * @return array|mixed|object|void|null + * @inheritDoc */ public function selectOne($query, $bindings = [], $useReadPdo = true) { $query = $this->bind_params($query, $bindings); $result = $this->db->get_row($query); if ($result === false || $this->db->last_error) { - throw new QueryException($query, $bindings, new \Exception($this->db->last_error)); + throw new QueryException($this->getName(), $query, $bindings, new \Exception($this->db->last_error)); } return $result; } /** - * Run a select statement - * - * @param string $query - * @param array $bindings - * @param bool $useReadPdo - * @return array|object|null + * @inheritDoc */ public function select($query, $bindings = [], $useReadPdo = true) { $query = $this->bind_params($query, $bindings); $result = $this->db->get_results($query); if ($result === false || $this->db->last_error) { - throw new QueryException($query, $bindings, new \Exception($this->db->last_error)); + throw new QueryException($this->getName(), $query, $bindings, new \Exception($this->db->last_error)); } return $result; @@ -297,19 +281,18 @@ public function statement($query, $bindings = []) */ public function affectingStatement($query, $bindings = []) { - $new_query = $this->bind_params($query, $bindings, true); - $result = $this->db->query($new_query); + $newQuery = $this->bind_params($query, $bindings, true); + $result = $this->db->query($newQuery); if ($result === false || $this->db->last_error) { - throw new QueryException($new_query, $bindings, new \Exception($this->db->last_error)); + throw new QueryException($this->getName(), $newQuery, $bindings, new \Exception($this->db->last_error)); } return (int) $result; } /** - * @param string $query - * @return bool + * @inheritDoc */ public function unprepared($query) { @@ -318,8 +301,7 @@ public function unprepared($query) } /** - * @param array $bindings - * @return array + * @inheritDoc */ public function prepareBindings(array $bindings) { @@ -343,10 +325,7 @@ public function prepareBindings(array $bindings) } /** - * @param \Closure $callback - * @param int $attempts - * @throws \Exception - * @return mixed + * @inheritDoc */ public function transaction(\Closure $callback, $attempts = 1) { @@ -362,9 +341,7 @@ public function transaction(\Closure $callback, $attempts = 1) } /** - * Start a new database transaction. - * - * @return void + * @inheritDoc */ public function beginTransaction() { @@ -375,9 +352,7 @@ public function beginTransaction() } /** - * Commit the active database transaction. - * - * @return void + * @inheritDoc */ public function commit() { @@ -391,9 +366,7 @@ public function commit() } /** - * Rollback the active database transaction. - * - * @return void + * @inheritDoc */ public function rollBack() { @@ -407,9 +380,7 @@ public function rollBack() } /** - * Get the number of active transactions. - * - * @return int + * @inheritDoc */ public function transactionLevel() { @@ -417,11 +388,7 @@ public function transactionLevel() } /** - * Execute the given callback in "dry run" mode. - * - * @param \Closure $callback - * - * @return array + * @inheritDoc */ public function pretend(\Closure $callback) { diff --git a/src/Taps/Comment/IsCommentTypeTap.php b/src/Taps/Comment/IsCommentTypeTap.php new file mode 100644 index 0000000..d55af95 --- /dev/null +++ b/src/Taps/Comment/IsCommentTypeTap.php @@ -0,0 +1,35 @@ + + */ + +namespace Dbout\WpOrm\Taps\Comment; + +use Dbout\WpOrm\Api\CommentInterface; +use Dbout\WpOrm\Builders\CommentBuilder; + +/** + * @since 3.0.0 + */ +class IsCommentTypeTap +{ + /** + * @param string $commentType + */ + public function __construct( + protected readonly string $commentType + ) { + } + + /** + * @param CommentBuilder $builder + * @return void + */ + public function __invoke(CommentBuilder $builder): void + { + $builder->where(CommentInterface::TYPE, $this->commentType); + } +} From 26c75df6c64d43e16921c95a6d0ea62b4f3b37a2 Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Fri, 19 Jan 2024 22:09:29 +0100 Subject: [PATCH 40/67] Update CI (remove rector) --- .github/workflows/ci.yml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2aa9321..952f7a9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,8 +28,5 @@ jobs: - name: PHPCsFixer run: vendor/bin/php-cs-fixer fix --verbose --diff --dry-run - - name: PHPStan - run: vendor/bin/phpstan analyse -c phpstan.neon - - - name: Rector - run: vendor/bin/rector process src --dry-run \ No newline at end of file + - name: PHPStan Analyse + run: vendor/bin/phpstan analyse -c phpstan.neon \ No newline at end of file From 807f44538cba3910e1267cfd8b2de71a71997e91 Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Fri, 19 Jan 2024 22:54:28 +0100 Subject: [PATCH 41/67] Remove index.php, update doc --- LICENSE | 2 +- README.md | 2 +- index.php | 3 --- 3 files changed, 2 insertions(+), 5 deletions(-) delete mode 100644 index.php diff --git a/LICENSE b/LICENSE index 1b50134..711843d 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2023 Dimitri BOUTEILLE +Copyright (c) 2024 Dimitri BOUTEILLE Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 55f5baf..b71f0a0 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ The ORM also offers a system to simply manage database migrations based on [Phin **Not yet developed but planned in a future version:** - 💡 Create custom comment type -- 💡 Meta casting (ie [Attribute Casting](https://laravel.com/docs/10.x/eloquent-mutators#attribute-casting)) +- 💡 Meta casting (e.g. [Attribute Casting](https://laravel.com/docs/10.x/eloquent-mutators#attribute-casting)) ### Documentation diff --git a/index.php b/index.php deleted file mode 100644 index f5c264d..0000000 --- a/index.php +++ /dev/null @@ -1,3 +0,0 @@ -author(15)->postType('tr'); From a23e7c67a00b887ea036586a2f83554f5d836fc9 Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Sat, 20 Jan 2024 11:04:20 +0100 Subject: [PATCH 42/67] Remove Api model interface --- src/Api/CommentInterface.php | 31 --------------------- src/Api/OptionInterface.php | 20 -------------- src/Api/PostInterface.php | 39 --------------------------- src/Api/TermInterface.php | 20 -------------- src/Api/TermRelationshipInterface.php | 19 ------------- src/Api/TermTaxonomyInterface.php | 22 --------------- src/Api/UserInterface.php | 26 ------------------ src/Builders/CommentBuilder.php | 4 +-- src/Builders/OptionBuilder.php | 5 ++-- src/Builders/PostBuilder.php | 9 +++---- src/Builders/TermBuilder.php | 4 +-- src/Builders/UserBuilder.php | 13 +++++---- src/Models/Comment.php | 26 +++++++++++++----- src/Models/Meta/PostMeta.php | 3 +-- src/Models/Meta/UserMeta.php | 3 +-- src/Models/Option.php | 8 ++++-- src/Models/Post.php | 34 ++++++++++++++++++----- src/Models/Term.php | 11 +++++--- src/Models/TermRelationship.php | 7 +++-- src/Models/TermTaxonomy.php | 10 +++++-- src/Models/User.php | 20 +++++++++----- src/Taps/Attachment/IsMimeTypeTap.php | 4 +-- src/Taps/Comment/IsApprovedTap.php | 4 +-- src/Taps/Comment/IsCommentTypeTap.php | 4 +-- src/Taps/Comment/IsUserTap.php | 4 +-- src/Taps/Option/IsAutoloadTap.php | 4 +-- src/Taps/Post/IsAuthorTap.php | 4 +-- src/Taps/Post/IsPingStatusTap.php | 4 +-- src/Taps/Post/IsPostTypeTap.php | 4 +-- src/Taps/Post/IsStatusTap.php | 4 +-- 30 files changed, 122 insertions(+), 248 deletions(-) delete mode 100644 src/Api/CommentInterface.php delete mode 100644 src/Api/OptionInterface.php delete mode 100644 src/Api/PostInterface.php delete mode 100644 src/Api/TermInterface.php delete mode 100644 src/Api/TermRelationshipInterface.php delete mode 100644 src/Api/TermTaxonomyInterface.php delete mode 100644 src/Api/UserInterface.php diff --git a/src/Api/CommentInterface.php b/src/Api/CommentInterface.php deleted file mode 100644 index 57b306b..0000000 --- a/src/Api/CommentInterface.php +++ /dev/null @@ -1,31 +0,0 @@ - - */ - -namespace Dbout\WpOrm\Api; - -/** - * @since 3.0.0 - */ -interface CommentInterface -{ - public const COMMENT_ID = 'comment_ID'; - public const POST_ID = 'comment_post_ID'; - public const AUTHOR = 'comment_author'; - public const AUTHOR_EMAIL = 'comment_author_email'; - public const AUTHOR_URL = 'comment_author_url'; - public const AUTHOR_IP = 'comment_author_IP'; - public const DATE = 'comment_date'; - public const DATE_GMT = 'comment_date_gmt'; - public const CONTENT = 'comment_content'; - public const KARMA = 'comment_karma'; - public const APPROVED = 'comment_approved'; - public const AGENT = 'comment_agent'; - public const TYPE = 'comment_type'; - public const PARENT = 'comment_parent'; - public const USER_ID = 'user_id'; -} diff --git a/src/Api/OptionInterface.php b/src/Api/OptionInterface.php deleted file mode 100644 index 20593db..0000000 --- a/src/Api/OptionInterface.php +++ /dev/null @@ -1,20 +0,0 @@ - - */ - -namespace Dbout\WpOrm\Api; - -/** - * @since 3.0.0 - */ -interface OptionInterface -{ - public const OPTION_ID = 'option_id'; - public const NAME = 'option_name'; - public const VALUE = 'option_value'; - public const AUTOLOAD = 'autoload'; -} diff --git a/src/Api/PostInterface.php b/src/Api/PostInterface.php deleted file mode 100644 index 4dce846..0000000 --- a/src/Api/PostInterface.php +++ /dev/null @@ -1,39 +0,0 @@ - - */ - -namespace Dbout\WpOrm\Api; - -/** - * @since 3.0.0 - */ -interface PostInterface -{ - public const POST_ID = 'ID'; - public const AUTHOR = 'post_author'; - public const DATE = 'post_date'; - public const DATE_GMT = 'post_date_gmt'; - public const CONTENT = 'post_content'; - public const TITLE = 'post_title'; - public const EXCERPT = 'post_excerpt'; - public const COMMENT_STATUS = 'comment_status'; - public const STATUS = 'post_status'; - public const PING_STATUS = 'ping_status'; - public const PASSWORD = 'post_password'; - public const POST_NAME = 'post_name'; - public const TO_PING = 'to_ping'; - public const PINGED = 'pinged'; - public const MODIFIED = 'post_modified'; - public const MODIFIED_GMT = 'post_modified_gmt'; - public const CONTENT_FILTERED = 'post_content_filtered'; - public const PARENT = 'post_parent'; - public const GUID = 'guid'; - public const MENU_ORDER = 'menu_order'; - public const TYPE = 'post_type'; - public const MIME_TYPE = 'post_mime_type'; - public const COMMENT_COUNT = 'comment_count'; -} diff --git a/src/Api/TermInterface.php b/src/Api/TermInterface.php deleted file mode 100644 index a3b31dd..0000000 --- a/src/Api/TermInterface.php +++ /dev/null @@ -1,20 +0,0 @@ - - */ - -namespace Dbout\WpOrm\Api; - -/** - * @since 3.0.0 - */ -interface TermInterface -{ - public const TERM_ID = 'term_id'; - public const NAME = 'name'; - public const SLUG = 'slug'; - public const TERM_GROUP = 'term_group'; -} diff --git a/src/Api/TermRelationshipInterface.php b/src/Api/TermRelationshipInterface.php deleted file mode 100644 index 451610c..0000000 --- a/src/Api/TermRelationshipInterface.php +++ /dev/null @@ -1,19 +0,0 @@ - - */ - -namespace Dbout\WpOrm\Api; - -/** - * @since 3.0.0 - */ -interface TermRelationshipInterface -{ - public const OBJECT_ID = 'object_id'; - public const TERM_TAXONOMY_ID = 'term_taxonomy_id'; - public const TERM_ORDER = 'term_order'; -} diff --git a/src/Api/TermTaxonomyInterface.php b/src/Api/TermTaxonomyInterface.php deleted file mode 100644 index d66446b..0000000 --- a/src/Api/TermTaxonomyInterface.php +++ /dev/null @@ -1,22 +0,0 @@ - - */ - -namespace Dbout\WpOrm\Api; - -/** - * @since 3.0.0 - */ -interface TermTaxonomyInterface -{ - public const TERM_TAXONOMY_ID = 'term_taxonomy_id'; - public const TERM_ID = 'term_id'; - public const TAXONOMY = 'taxonomy'; - public const DESCRIPTION = 'description'; - public const PARENT = 'parent'; - public const COUNT = 'count'; -} diff --git a/src/Api/UserInterface.php b/src/Api/UserInterface.php deleted file mode 100644 index 1029673..0000000 --- a/src/Api/UserInterface.php +++ /dev/null @@ -1,26 +0,0 @@ - - */ - -namespace Dbout\WpOrm\Api; - -/** - * @since 3.0.0 - */ -interface UserInterface -{ - public const USER_ID = 'ID'; - public const LOGIN = 'user_login'; - public const PASSWORD = 'user_pass'; - public const NICE_NAME = 'user_nicename'; - public const EMAIL = 'user_email'; - public const URL = 'user_url'; - public const REGISTERED = 'user_registered'; - public const ACTIVATION_KEY = 'user_activation_key'; - public const DISPLAY_NAME = 'display_name'; - public const STATUS = 'user_status'; -} diff --git a/src/Builders/CommentBuilder.php b/src/Builders/CommentBuilder.php index 0e75466..0684858 100644 --- a/src/Builders/CommentBuilder.php +++ b/src/Builders/CommentBuilder.php @@ -8,7 +8,7 @@ namespace Dbout\WpOrm\Builders; -use Dbout\WpOrm\Api\CommentInterface; +use Dbout\WpOrm\Models\Comment; use Illuminate\Database\Eloquent\Collection; class CommentBuilder extends AbstractBuilder @@ -30,6 +30,6 @@ public function findAllByType(string $type): Collection */ public function whereTypes(...$types): self { - return $this->_whereOrIn(CommentInterface::TYPE, $types); + return $this->_whereOrIn(Comment::TYPE, $types); } } diff --git a/src/Builders/OptionBuilder.php b/src/Builders/OptionBuilder.php index 6e516bc..e546a8d 100644 --- a/src/Builders/OptionBuilder.php +++ b/src/Builders/OptionBuilder.php @@ -8,7 +8,6 @@ namespace Dbout\WpOrm\Builders; -use Dbout\WpOrm\Api\OptionInterface; use Dbout\WpOrm\Models\Option; class OptionBuilder extends AbstractBuilder @@ -22,7 +21,7 @@ class OptionBuilder extends AbstractBuilder public function findOneByName(string $optionName): ?Option { /** @var Option|null $model */ - $model = $this->firstWhere(OptionInterface::NAME, $optionName); + $model = $this->firstWhere(Option::NAME, $optionName); return $model; } @@ -32,6 +31,6 @@ public function findOneByName(string $optionName): ?Option */ public function whereName(string $optionName): self { - return $this->where(OptionInterface::NAME, $optionName); + return $this->where(Option::NAME, $optionName); } } diff --git a/src/Builders/PostBuilder.php b/src/Builders/PostBuilder.php index 4435995..4571746 100644 --- a/src/Builders/PostBuilder.php +++ b/src/Builders/PostBuilder.php @@ -8,7 +8,6 @@ namespace Dbout\WpOrm\Builders; -use Dbout\WpOrm\Api\PostInterface; use Dbout\WpOrm\Models\Post; use Illuminate\Database\Eloquent\Collection; @@ -27,7 +26,7 @@ public function findOneByName(?string $name): ?Post } /** @var Post|null $model */ - $model = $this->firstWhere(PostInterface::POST_NAME, $name); + $model = $this->firstWhere(Post::POST_NAME, $name); return $model; } @@ -48,7 +47,7 @@ public function findAllByType(string $type): Collection */ public function whereTypes(...$types): self { - return $this->_whereOrIn(PostInterface::TYPE, $types); + return $this->_whereOrIn(Post::TYPE, $types); } /** @@ -57,7 +56,7 @@ public function whereTypes(...$types): self */ public function whereAuthor($author): self { - $this->where(PostInterface::AUTHOR, $author); + $this->where(Post::AUTHOR, $author); return $this; } @@ -67,6 +66,6 @@ public function whereAuthor($author): self */ public function whereStatus(...$status): self { - return $this->_whereOrIn(PostInterface::STATUS, $status); + return $this->_whereOrIn(Post::STATUS, $status); } } diff --git a/src/Builders/TermBuilder.php b/src/Builders/TermBuilder.php index 6dbc988..2925ebd 100644 --- a/src/Builders/TermBuilder.php +++ b/src/Builders/TermBuilder.php @@ -8,7 +8,7 @@ namespace Dbout\WpOrm\Builders; -use Dbout\WpOrm\Api\TermTaxonomyInterface; +use Dbout\WpOrm\Models\TermTaxonomy; use Illuminate\Database\Eloquent\Collection; class TermBuilder extends AbstractBuilder @@ -20,7 +20,7 @@ class TermBuilder extends AbstractBuilder public function findAllByTaxonomy(string $taxonomy): Collection { return $this->whereHas('termTaxonomy', function ($query) use ($taxonomy) { - return $query->where(TermTaxonomyInterface::TAXONOMY, $taxonomy); + return $query->where(TermTaxonomy::TAXONOMY, $taxonomy); })->get(); } } diff --git a/src/Builders/UserBuilder.php b/src/Builders/UserBuilder.php index 8a650ad..cd192f4 100644 --- a/src/Builders/UserBuilder.php +++ b/src/Builders/UserBuilder.php @@ -8,7 +8,6 @@ namespace Dbout\WpOrm\Builders; -use Dbout\WpOrm\Api\UserInterface; use Dbout\WpOrm\Models\User; class UserBuilder extends AbstractWithMetaBuilder @@ -22,7 +21,7 @@ class UserBuilder extends AbstractWithMetaBuilder public function findOneByEmail(string $email): ?User { /** @var User|null $model */ - $model = $this->firstWhere(UserInterface::EMAIL, $email); + $model = $this->firstWhere(User::EMAIL, $email); return $model; } @@ -35,7 +34,7 @@ public function findOneByEmail(string $email): ?User public function findOneByLogin(string $login): ?User { /** @var User|null $model */ - $model = $this->firstWhere(UserInterface::LOGIN, $login); + $model = $this->firstWhere(User::LOGIN, $login); return $model; } @@ -45,7 +44,7 @@ public function findOneByLogin(string $login): ?User */ public function whereEmail(string $email): self { - return $this->where(UserInterface::EMAIL, $email); + return $this->where(User::EMAIL, $email); } /** @@ -54,7 +53,7 @@ public function whereEmail(string $email): self */ public function whereLogin(string $login): self { - return $this->where(UserInterface::LOGIN, $login); + return $this->where(User::LOGIN, $login); } /** @@ -63,7 +62,7 @@ public function whereLogin(string $login): self */ public function whereEmails(... $emails): self { - return $this->_whereOrIn(UserInterface::EMAIL, $emails); + return $this->_whereOrIn(User::EMAIL, $emails); } /** @@ -72,6 +71,6 @@ public function whereEmails(... $emails): self */ public function whereLogins(... $logins): self { - return $this->_whereOrIn(UserInterface::LOGIN, $logins); + return $this->_whereOrIn(User::LOGIN, $logins); } } diff --git a/src/Models/Comment.php b/src/Models/Comment.php index 5e0707f..7828ec0 100644 --- a/src/Models/Comment.php +++ b/src/Models/Comment.php @@ -9,9 +9,6 @@ namespace Dbout\WpOrm\Models; use Carbon\Carbon; -use Dbout\WpOrm\Api\CommentInterface; -use Dbout\WpOrm\Api\PostInterface; -use Dbout\WpOrm\Api\UserInterface; use Dbout\WpOrm\Builders\CommentBuilder; use Dbout\WpOrm\Orm\AbstractModel; use Illuminate\Database\Eloquent\Relations\HasOne; @@ -48,10 +45,25 @@ * @property-read Post|null $post * @property-read Comment|null $parent */ -class Comment extends AbstractModel implements CommentInterface +class Comment extends AbstractModel { final public const CREATED_AT = self::DATE; final public const UPDATED_AT = null; + final public const COMMENT_ID = 'comment_ID'; + final public const POST_ID = 'comment_post_ID'; + final public const AUTHOR = 'comment_author'; + final public const AUTHOR_EMAIL = 'comment_author_email'; + final public const AUTHOR_URL = 'comment_author_url'; + final public const AUTHOR_IP = 'comment_author_IP'; + final public const DATE = 'comment_date'; + final public const DATE_GMT = 'comment_date_gmt'; + final public const CONTENT = 'comment_content'; + final public const KARMA = 'comment_karma'; + final public const APPROVED = 'comment_approved'; + final public const AGENT = 'comment_agent'; + final public const TYPE = 'comment_type'; + final public const PARENT = 'comment_parent'; + final public const USER_ID = 'user_id'; /** * @inheritDoc @@ -77,7 +89,7 @@ class Comment extends AbstractModel implements CommentInterface */ public function user(): HasOne { - return $this->hasOne(User::class, UserInterface::USER_ID, self::USER_ID); + return $this->hasOne(User::class, User::USER_ID, self::USER_ID); } /** @@ -85,7 +97,7 @@ public function user(): HasOne */ public function post(): HasOne { - return $this->hasOne(Post::class, PostInterface::POST_ID, self::POST_ID); + return $this->hasOne(Post::class, Post::POST_ID, self::POST_ID); } /** @@ -93,7 +105,7 @@ public function post(): HasOne */ public function parent(): HasOne { - return $this->hasOne(Comment::class, CommentInterface::COMMENT_ID, self::PARENT); + return $this->hasOne(Comment::class, Comment::COMMENT_ID, self::PARENT); } /** diff --git a/src/Models/Meta/PostMeta.php b/src/Models/Meta/PostMeta.php index 4eccb2b..c868312 100644 --- a/src/Models/Meta/PostMeta.php +++ b/src/Models/Meta/PostMeta.php @@ -8,7 +8,6 @@ namespace Dbout\WpOrm\Models\Meta; -use Dbout\WpOrm\Api\PostInterface; use Dbout\WpOrm\Models\Post; use Illuminate\Database\Eloquent\Relations\HasOne; @@ -36,6 +35,6 @@ class PostMeta extends AbstractMeta */ public function post(): HasOne { - return $this->hasOne(Post::class, PostInterface::POST_ID, self::POST_ID); + return $this->hasOne(Post::class, Post::POST_ID, self::POST_ID); } } diff --git a/src/Models/Meta/UserMeta.php b/src/Models/Meta/UserMeta.php index 1151b66..ca09124 100644 --- a/src/Models/Meta/UserMeta.php +++ b/src/Models/Meta/UserMeta.php @@ -8,7 +8,6 @@ namespace Dbout\WpOrm\Models\Meta; -use Dbout\WpOrm\Api\UserInterface; use Dbout\WpOrm\Models\User; use Illuminate\Database\Eloquent\Relations\HasOne; @@ -36,6 +35,6 @@ class UserMeta extends AbstractMeta */ public function user(): HasOne { - return $this->hasOne(User::class, UserInterface::USER_ID, self::USER_ID); + return $this->hasOne(User::class, User::USER_ID, self::USER_ID); } } diff --git a/src/Models/Option.php b/src/Models/Option.php index efaf4bb..3bdb356 100644 --- a/src/Models/Option.php +++ b/src/Models/Option.php @@ -8,7 +8,6 @@ namespace Dbout\WpOrm\Models; -use Dbout\WpOrm\Api\OptionInterface; use Dbout\WpOrm\Builders\OptionBuilder; use Dbout\WpOrm\Enums\YesNo; use Dbout\WpOrm\Orm\AbstractModel; @@ -23,8 +22,13 @@ * @method static static|null find($optionId) * @method static OptionBuilder query() */ -class Option extends AbstractModel implements OptionInterface +class Option extends AbstractModel { + final public const OPTION_ID = 'option_id'; + final public const NAME = 'option_name'; + final public const VALUE = 'option_value'; + final public const AUTOLOAD = 'autoload'; + /** * @inheritDoc */ diff --git a/src/Models/Post.php b/src/Models/Post.php index 7e88a66..b2904da 100644 --- a/src/Models/Post.php +++ b/src/Models/Post.php @@ -9,9 +9,6 @@ namespace Dbout\WpOrm\Models; use Carbon\Carbon; -use Dbout\WpOrm\Api\CommentInterface; -use Dbout\WpOrm\Api\PostInterface; -use Dbout\WpOrm\Api\UserInterface; use Dbout\WpOrm\Builders\PostBuilder; use Dbout\WpOrm\Concerns\HasMeta; use Dbout\WpOrm\Models\Meta\PostMeta; @@ -67,12 +64,35 @@ * @property-read Comment[] $comments */ #[\Dbout\WpOrm\Attributes\MetaConfigAttribute(PostMeta::class, PostMeta::POST_ID)] -class Post extends AbstractModel implements PostInterface +class Post extends AbstractModel { use HasMeta; public const UPDATED_AT = self::MODIFIED; public const CREATED_AT = self::DATE; + final public const POST_ID = 'ID'; + final public const AUTHOR = 'post_author'; + final public const DATE = 'post_date'; + final public const DATE_GMT = 'post_date_gmt'; + final public const CONTENT = 'post_content'; + final public const TITLE = 'post_title'; + final public const EXCERPT = 'post_excerpt'; + final public const COMMENT_STATUS = 'comment_status'; + final public const STATUS = 'post_status'; + final public const PING_STATUS = 'ping_status'; + final public const PASSWORD = 'post_password'; + final public const POST_NAME = 'post_name'; + final public const TO_PING = 'to_ping'; + final public const PINGED = 'pinged'; + final public const MODIFIED = 'post_modified'; + final public const MODIFIED_GMT = 'post_modified_gmt'; + final public const CONTENT_FILTERED = 'post_content_filtered'; + final public const PARENT = 'post_parent'; + final public const GUID = 'guid'; + final public const MENU_ORDER = 'menu_order'; + final public const TYPE = 'post_type'; + final public const MIME_TYPE = 'post_mime_type'; + final public const COMMENT_COUNT = 'comment_count'; /** * @inheritDoc @@ -101,7 +121,7 @@ class Post extends AbstractModel implements PostInterface */ public function author(): HasOne { - return $this->hasOne(User::class, UserInterface::USER_ID, self::AUTHOR); + return $this->hasOne(User::class, User::USER_ID, self::AUTHOR); } /** @@ -109,7 +129,7 @@ public function author(): HasOne */ public function comments(): HasMany { - return $this->hasMany(Comment::class, CommentInterface::POST_ID); + return $this->hasMany(Comment::class, Comment::POST_ID); } /** @@ -117,7 +137,7 @@ public function comments(): HasMany */ public function parent(): HasOne { - return $this->hasOne(Post::class, PostInterface::POST_ID, self::PARENT); + return $this->hasOne(Post::class, Post::POST_ID, self::PARENT); } /** diff --git a/src/Models/Term.php b/src/Models/Term.php index 7801ecb..9ea8546 100644 --- a/src/Models/Term.php +++ b/src/Models/Term.php @@ -8,8 +8,6 @@ namespace Dbout\WpOrm\Models; -use Dbout\WpOrm\Api\TermInterface; -use Dbout\WpOrm\Api\TermTaxonomyInterface; use Dbout\WpOrm\Builders\TermBuilder; use Dbout\WpOrm\Orm\AbstractModel; use Illuminate\Database\Eloquent\Relations\HasOne; @@ -26,8 +24,13 @@ * * @property-read TermTaxonomy|null $termTaxonomy */ -class Term extends AbstractModel implements TermInterface +class Term extends AbstractModel { + final public const TERM_ID = 'term_id'; + final public const NAME = 'name'; + final public const SLUG = 'slug'; + final public const TERM_GROUP = 'term_group'; + /** * @inheritDoc */ @@ -57,7 +60,7 @@ public function termTaxonomy(): HasOne { return $this->hasOne( TermTaxonomy::class, - TermTaxonomyInterface::TERM_ID, + TermTaxonomy::TERM_ID, self::TERM_ID ); } diff --git a/src/Models/TermRelationship.php b/src/Models/TermRelationship.php index 63f8b84..e8447c4 100644 --- a/src/Models/TermRelationship.php +++ b/src/Models/TermRelationship.php @@ -8,7 +8,6 @@ namespace Dbout\WpOrm\Models; -use Dbout\WpOrm\Api\TermRelationshipInterface; use Dbout\WpOrm\Orm\AbstractModel; /** @@ -19,8 +18,12 @@ * @method int|null getObjectId() * @method TermRelationship setObjectId(?int $id) */ -class TermRelationship extends AbstractModel implements TermRelationshipInterface +class TermRelationship extends AbstractModel { + final public const OBJECT_ID = 'object_id'; + final public const TERM_TAXONOMY_ID = 'term_taxonomy_id'; + final public const TERM_ORDER = 'term_order'; + /** * @inheritDoc */ diff --git a/src/Models/TermTaxonomy.php b/src/Models/TermTaxonomy.php index 6bb7668..5137eb2 100644 --- a/src/Models/TermTaxonomy.php +++ b/src/Models/TermTaxonomy.php @@ -8,7 +8,6 @@ namespace Dbout\WpOrm\Models; -use Dbout\WpOrm\Api\TermTaxonomyInterface; use Dbout\WpOrm\Orm\AbstractModel; /** @@ -24,8 +23,15 @@ * @method TermTaxonomy setCount(int $count) * @method static static|null find(int $id) */ -class TermTaxonomy extends AbstractModel implements TermTaxonomyInterface +class TermTaxonomy extends AbstractModel { + final public const TERM_TAXONOMY_ID = 'term_taxonomy_id'; + final public const TERM_ID = 'term_id'; + final public const TAXONOMY = 'taxonomy'; + final public const DESCRIPTION = 'description'; + final public const PARENT = 'parent'; + final public const COUNT = 'count'; + /** * @inheritDoc */ diff --git a/src/Models/User.php b/src/Models/User.php index 5871da3..7ced1f1 100644 --- a/src/Models/User.php +++ b/src/Models/User.php @@ -9,9 +9,6 @@ namespace Dbout\WpOrm\Models; use Carbon\Carbon; -use Dbout\WpOrm\Api\CommentInterface; -use Dbout\WpOrm\Api\PostInterface; -use Dbout\WpOrm\Api\UserInterface; use Dbout\WpOrm\Builders\UserBuilder; use Dbout\WpOrm\Concerns\HasMeta; use Dbout\WpOrm\Models\Meta\UserMeta; @@ -45,13 +42,24 @@ * @property-read Post[] $posts */ #[\Dbout\WpOrm\Attributes\MetaConfigAttribute(UserMeta::class, UserMeta::USER_ID)] -class User extends AbstractModel implements UserInterface +class User extends AbstractModel { use HasMeta; final public const CREATED_AT = self::REGISTERED; final public const UPDATED_AT = null; + final public const USER_ID = 'ID'; + final public const LOGIN = 'user_login'; + final public const PASSWORD = 'user_pass'; + final public const NICE_NAME = 'user_nicename'; + final public const EMAIL = 'user_email'; + final public const URL = 'user_url'; + final public const REGISTERED = 'user_registered'; + final public const ACTIVATION_KEY = 'user_activation_key'; + final public const DISPLAY_NAME = 'display_name'; + final public const STATUS = 'user_status'; + /** * @inheritDoc */ @@ -75,7 +83,7 @@ class User extends AbstractModel implements UserInterface */ public function comments(): HasMany { - return $this->hasMany(Comment::class, CommentInterface::USER_ID); + return $this->hasMany(Comment::class, Comment::USER_ID); } /** @@ -83,7 +91,7 @@ public function comments(): HasMany */ public function posts(): HasMany { - return $this->hasMany(Post::class, PostInterface::AUTHOR); + return $this->hasMany(Post::class, Post::AUTHOR); } /** diff --git a/src/Taps/Attachment/IsMimeTypeTap.php b/src/Taps/Attachment/IsMimeTypeTap.php index 89e3760..9023fc0 100644 --- a/src/Taps/Attachment/IsMimeTypeTap.php +++ b/src/Taps/Attachment/IsMimeTypeTap.php @@ -8,8 +8,8 @@ namespace Dbout\WpOrm\Taps\Attachment; -use Dbout\WpOrm\Api\PostInterface; use Dbout\WpOrm\Builders\PostBuilder; +use Dbout\WpOrm\Models\Post; /** * @since 3.0.0 @@ -30,6 +30,6 @@ public function __construct( */ public function __invoke(PostBuilder $builder): void { - $builder->where(PostInterface::MIME_TYPE, $this->mimeType); + $builder->where(Post::MIME_TYPE, $this->mimeType); } } diff --git a/src/Taps/Comment/IsApprovedTap.php b/src/Taps/Comment/IsApprovedTap.php index 534fb99..217b2bc 100644 --- a/src/Taps/Comment/IsApprovedTap.php +++ b/src/Taps/Comment/IsApprovedTap.php @@ -8,8 +8,8 @@ namespace Dbout\WpOrm\Taps\Comment; -use Dbout\WpOrm\Api\CommentInterface; use Dbout\WpOrm\Builders\CommentBuilder; +use Dbout\WpOrm\Models\Comment; /** * @since 3.0.0 @@ -30,6 +30,6 @@ public function __construct( */ public function __invoke(CommentBuilder $builder): void { - $builder->where(CommentInterface::APPROVED, $this->isApproved); + $builder->where(Comment::APPROVED, $this->isApproved); } } diff --git a/src/Taps/Comment/IsCommentTypeTap.php b/src/Taps/Comment/IsCommentTypeTap.php index d55af95..1d7c72b 100644 --- a/src/Taps/Comment/IsCommentTypeTap.php +++ b/src/Taps/Comment/IsCommentTypeTap.php @@ -8,8 +8,8 @@ namespace Dbout\WpOrm\Taps\Comment; -use Dbout\WpOrm\Api\CommentInterface; use Dbout\WpOrm\Builders\CommentBuilder; +use Dbout\WpOrm\Models\Comment; /** * @since 3.0.0 @@ -30,6 +30,6 @@ public function __construct( */ public function __invoke(CommentBuilder $builder): void { - $builder->where(CommentInterface::TYPE, $this->commentType); + $builder->where(Comment::TYPE, $this->commentType); } } diff --git a/src/Taps/Comment/IsUserTap.php b/src/Taps/Comment/IsUserTap.php index cfee667..cd827e5 100644 --- a/src/Taps/Comment/IsUserTap.php +++ b/src/Taps/Comment/IsUserTap.php @@ -8,8 +8,8 @@ namespace Dbout\WpOrm\Taps\Comment; -use Dbout\WpOrm\Api\CommentInterface; use Dbout\WpOrm\Builders\CommentBuilder; +use Dbout\WpOrm\Models\Comment; use Dbout\WpOrm\Models\User; /** @@ -36,6 +36,6 @@ public function __invoke(CommentBuilder $builder): void $user = $user->getId(); } - $builder->where(CommentInterface::USER_ID, $user); + $builder->where(Comment::USER_ID, $user); } } diff --git a/src/Taps/Option/IsAutoloadTap.php b/src/Taps/Option/IsAutoloadTap.php index b9191ec..fb30c70 100644 --- a/src/Taps/Option/IsAutoloadTap.php +++ b/src/Taps/Option/IsAutoloadTap.php @@ -8,9 +8,9 @@ namespace Dbout\WpOrm\Taps\Option; -use Dbout\WpOrm\Api\OptionInterface; use Dbout\WpOrm\Builders\OptionBuilder; use Dbout\WpOrm\Enums\YesNo; +use Dbout\WpOrm\Models\Option; /** * @since 3.0.0 @@ -33,6 +33,6 @@ public function __invoke(OptionBuilder $builder): void $autoload = $autoload ? YesNo::Yes : YesNo::No; } - $builder->where(OptionInterface::AUTOLOAD, $autoload->value); + $builder->where(Option::AUTOLOAD, $autoload->value); } } diff --git a/src/Taps/Post/IsAuthorTap.php b/src/Taps/Post/IsAuthorTap.php index afea7ca..8fe9a48 100644 --- a/src/Taps/Post/IsAuthorTap.php +++ b/src/Taps/Post/IsAuthorTap.php @@ -8,8 +8,8 @@ namespace Dbout\WpOrm\Taps\Post; -use Dbout\WpOrm\Api\PostInterface; use Dbout\WpOrm\Builders\PostBuilder; +use Dbout\WpOrm\Models\Post; use Dbout\WpOrm\Models\User; /** @@ -36,6 +36,6 @@ public function __invoke(PostBuilder $builder): void $author = $author->getId(); } - $builder->where(PostInterface::AUTHOR, $author); + $builder->where(Post::AUTHOR, $author); } } diff --git a/src/Taps/Post/IsPingStatusTap.php b/src/Taps/Post/IsPingStatusTap.php index d1034ac..2eb9c1e 100644 --- a/src/Taps/Post/IsPingStatusTap.php +++ b/src/Taps/Post/IsPingStatusTap.php @@ -8,9 +8,9 @@ namespace Dbout\WpOrm\Taps\Post; -use Dbout\WpOrm\Api\PostInterface; use Dbout\WpOrm\Builders\PostBuilder; use Dbout\WpOrm\Enums\PingStatus; +use Dbout\WpOrm\Models\Post; /** * @since 3.0.0 @@ -36,6 +36,6 @@ public function __invoke(PostBuilder $builder): void $status = $status->value; } - $builder->where(PostInterface::PING_STATUS, $status); + $builder->where(Post::PING_STATUS, $status); } } diff --git a/src/Taps/Post/IsPostTypeTap.php b/src/Taps/Post/IsPostTypeTap.php index 5bb7586..69668c9 100644 --- a/src/Taps/Post/IsPostTypeTap.php +++ b/src/Taps/Post/IsPostTypeTap.php @@ -8,8 +8,8 @@ namespace Dbout\WpOrm\Taps\Post; -use Dbout\WpOrm\Api\PostInterface; use Dbout\WpOrm\Builders\PostBuilder; +use Dbout\WpOrm\Models\Post; /** * @since 3.0.0 @@ -30,6 +30,6 @@ public function __construct( */ public function __invoke(PostBuilder $builder): void { - $builder->where(PostInterface::TYPE, $this->postType); + $builder->where(Post::TYPE, $this->postType); } } diff --git a/src/Taps/Post/IsStatusTap.php b/src/Taps/Post/IsStatusTap.php index ad1164a..c6889cb 100644 --- a/src/Taps/Post/IsStatusTap.php +++ b/src/Taps/Post/IsStatusTap.php @@ -8,9 +8,9 @@ namespace Dbout\WpOrm\Taps\Post; -use Dbout\WpOrm\Api\PostInterface; use Dbout\WpOrm\Builders\PostBuilder; use Dbout\WpOrm\Enums\PostStatus; +use Dbout\WpOrm\Models\Post; /** * @since 3.0.0 @@ -36,6 +36,6 @@ public function __invoke(PostBuilder $builder): void $status = $status->value; } - $builder->where(PostInterface::STATUS, $status); + $builder->where(Post::STATUS, $status); } } From 21c22ce3a1228ee7158825b6956214de5c53dd21 Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Sat, 20 Jan 2024 11:40:49 +0100 Subject: [PATCH 43/67] #7 Update doc --- README.md | 9 ++++---- doc/documentation.md | 49 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 53 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index b71f0a0..ef22a16 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ The ORM also offers a system to simply manage database migrations based on [Phin - [Installation](#installation) - [Introduction](#introduction) - [Use WordPress models](doc/documentation.md#use-wordpress-models) +- [Filter data](/doc/documentation.md#filter-data) - [Create custom Model](doc/documentation.md#create-model) - [Migration with Phinx](doc/migration.md) @@ -62,11 +63,11 @@ Simply put, wp-orm is a library that makes it easy to manipulate a WordPress dat **Here is a list of available features :** -- The `wpdb` connection is used so **no configuration is needed to use**. +- The `wpdb` connection is used so **no configuration is needed to use** - Ability to [create models](doc/documentation.md#model) simply -- WordPress works with custom content types, you can simply [use the default types of WordPress](doc/documentation.md#use-wordpress-models) (page, attachment, ...) and create [custom models for your types](doc/documentation.md#custom-post-type-model). -- Ability to [filter data](doc/documentation.md#filter-data) easily via taps. -- All the features available in Eloquent, are usable with this library. +- WordPress works with custom content types, you can simply [use the default types of WordPress](doc/documentation.md#use-wordpress-models) (page, attachment, ...) and create [custom models](doc/documentation.md#create-model) +- Ability to [filter data](doc/documentation.md#filter-data) easily via taps +- All the features available in Eloquent, are usable with this library > 📘 If you want to know more about how Eloquent works, the easiest way is to [read the documentation](https://laravel.com/docs/10.x/eloquent). diff --git a/doc/documentation.md b/doc/documentation.md index 4e6a01f..fca99ab 100644 --- a/doc/documentation.md +++ b/doc/documentation.md @@ -8,4 +8,51 @@ ### Model -### Custom post type model \ No newline at end of file +Creating a model is very simple, just create a class that extends from `Dbout\WpOrm\Orm\AbstractModel`. + +```php +use Dbout\WpOrm\Orm\AbstractModel; + +class MyModel extends AbstractModel +{ + +} +``` + +Note that we did not tell Eloquent which table to use for our `MyModel` model. The "snake case", plural name of the class will be used as the table name unless another name is explicitly specified. So, in this case, Eloquent will assume the `MyModel` model stores records in the myModels table. You may specify a custom table by defining a table property on your model: + +```php +use Dbout\WpOrm\Orm\AbstractModel; + +class MyModel extends AbstractModel +{ + + protected $table = 'my_table'; +} +``` + +**Note:** Eloquent will also assume that each table has a primary key column named id. You may define a primaryKey property to override this convention. Likewise, you may define a connection property to override the name of the database connection that should be used when utilizing the model. + +Once a model is defined, you are ready to start retrieving and creating records in your table. Note that you will need to place `updated_at` and `created_at` columns on your table by default. If you do not wish to have these columns automatically maintained, set the `$timestamps` property on your model to false. + +> 📘 If you want to know more about creating a model you can look the [Eloquent documentation](https://laravel.com/docs/5.0/eloquent#basic-usage). + +### Custom Post Type Model + +All Custom Post Type (CPT) models extend `Dbout\WpOrm\Models\MyCustomType`. + +```php +use Dbout\WpOrm\Models\CustomPost; + +class MyCustomType extends CustomPost +{ + /** + * @inheritDoc + */ + protected string $_type = 'my_customm_type'; +} +``` + +When retrieving a model `MyCustomType`, the `posts.post_type = my_customm_type` filter will be automatically added to the query. + +**Note:** You cannot use `setPostType` function on CPT models. \ No newline at end of file From fa6987565a486779e5008c5bfd922de75141a016 Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Sat, 20 Jan 2024 12:00:10 +0100 Subject: [PATCH 44/67] #7 WIP doc --- README.md | 2 +- doc/available-filters.md | 25 +++++++++++++++++++++++++ doc/documentation.md | 31 +++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 doc/available-filters.md diff --git a/README.md b/README.md index ef22a16..a74fec4 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ Simply put, wp-orm is a library that makes it easy to manipulate a WordPress dat - The `wpdb` connection is used so **no configuration is needed to use** - Ability to [create models](doc/documentation.md#model) simply -- WordPress works with custom content types, you can simply [use the default types of WordPress](doc/documentation.md#use-wordpress-models) (page, attachment, ...) and create [custom models](doc/documentation.md#create-model) +- WordPress works with custom content types, you can simply [use the default types of WordPress](doc/documentation.md#use-wordpress-models) (page, attachment, ...) and create [custom models for your types](doc/documentation.md#custom-post-type-model) or create [custom model](doc/documentation.md) - Ability to [filter data](doc/documentation.md#filter-data) easily via taps - All the features available in Eloquent, are usable with this library diff --git a/doc/available-filters.md b/doc/available-filters.md new file mode 100644 index 0000000..5a2ceb1 --- /dev/null +++ b/doc/available-filters.md @@ -0,0 +1,25 @@ +# Available filters + +## Post + +**Available for all post models** + +- `Dbout\WpOrm\Taps\Post\IsAuthorTap` +- `Dbout\WpOrm\Taps\Post\IsPingStatusTap` +- `Dbout\WpOrm\Taps\Post\IsPostTypeTap` +- `Dbout\WpOrm\Taps\Post\IsStatusTap` + +**Attachment CPT** + +- `Dbout\WpOrm\Taps\Attachment\IsMimeTypeTap` + +## Comment + +- `Dbout\WpOrm\Taps\Comment\IsApprovedTap` +- `Dbout\WpOrm\Taps\Comment\IsCommentTypeTap` +- `Dbout\WpOrm\Taps\Comment\IsUserTap` + +## Option + +- `Dbout\WpOrm\Taps\Option\IsAutoloadTap` + diff --git a/doc/documentation.md b/doc/documentation.md index fca99ab..58f76e1 100644 --- a/doc/documentation.md +++ b/doc/documentation.md @@ -4,6 +4,37 @@ ## Filter data +You can easily filter data via the `tap` function : + +```php +use Dbout\WpOrm\Taps\Post\IsAuthorTap; +use Dbout\WpOrm\Taps\Post\IsStatusTap; +use Dbout\WpOrm\Enums\PostStatus; +use Dbout\WpOrm\Models\Post; + +$posts = Post::query() + ->tap(new IsAuthorTap(1)) + ->get(); +``` + +This query, returns all user posts with ID 1. + +If you want to apply multiple filters, nothing complicated : + +```php +use Dbout\WpOrm\Taps\Post\IsAuthorTap; +use Dbout\WpOrm\Taps\Post\IsStatusTap; +use Dbout\WpOrm\Enums\PostStatus; +use Dbout\WpOrm\Models\Post; + +$posts = Post::query() + ->tap(new IsAuthorTap(1)) + ->tap(new IsStatusTap(PostStatus::Publish)) + ->get(); +``` + +You can find all the available filters here: [Available filters](available-filters.md). + ## Create Model ### Model From a508fab2a2a722bc3e70bb97bdbb9d139aa4da58 Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Sat, 20 Jan 2024 12:10:49 +0100 Subject: [PATCH 45/67] #7 WIP doc --- README.md | 2 +- doc/create-model.md | 61 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 doc/create-model.md diff --git a/README.md b/README.md index a74fec4..6d92d04 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ The ORM also offers a system to simply manage database migrations based on [Phin - [Introduction](#introduction) - [Use WordPress models](doc/documentation.md#use-wordpress-models) - [Filter data](/doc/documentation.md#filter-data) -- [Create custom Model](doc/documentation.md#create-model) +- [Create custom Model](doc/create-model.md) - [Migration with Phinx](doc/migration.md) ## Installation diff --git a/doc/create-model.md b/doc/create-model.md new file mode 100644 index 0000000..6511b46 --- /dev/null +++ b/doc/create-model.md @@ -0,0 +1,61 @@ +# Create Model + +You can create two model types: + +- A model that corresponds to a custom table (e.g. `User`, `Option`, ... tables) +- A model that corresponds to a Custom Post Type (e.g `Page`, `Attachment`, `Article`, ...) + +## Generic Model + +Creating a model is very simple, just create a class that extends from `Dbout\WpOrm\Orm\AbstractModel`. + +```php +use Dbout\WpOrm\Orm\AbstractModel; + +class MyModel extends AbstractModel +{ + +} +``` + +Note that we did not tell Eloquent which table to use for our `MyModel` model. The "snake case", plural name of the class will be used as the table name unless another name is explicitly specified. So, in this case, Eloquent will assume the `MyModel` model stores records in the myModels table. You may specify a custom table by defining a table property on your model: + +```php +use Dbout\WpOrm\Orm\AbstractModel; + +class MyModel extends AbstractModel +{ + + protected $table = 'my_table'; +} +``` + +**Note:** Eloquent will also assume that each table has a primary key column named id. You may define a primaryKey property to override this convention. Likewise, you may define a connection property to override the name of the database connection that should be used when utilizing the model. + +Once a model is defined, you are ready to start retrieving and creating records in your table. Note that you will need to place `updated_at` and `created_at` columns on your table by default. If you do not wish to have these columns automatically maintained, set the `$timestamps` property on your model to false. + +> 💡 If your model may have metas, you can easily link metas to your model. You can look `Dbout\WpOrm\Models\Post` to understand how it works. + +> 📘 If you want to know more about creating a model you can look the [Eloquent documentation](https://laravel.com/docs/5.0/eloquent#basic-usage). + +## Custom Post Type Model + +All Custom Post Type (CPT) models extend `Dbout\WpOrm\Models\MyCustomType`. + +```php +use Dbout\WpOrm\Models\CustomPost; + +class MyCustomType extends CustomPost +{ + /** + * @inheritDoc + */ + protected string $_type = 'my_customm_type'; +} +``` + +When retrieving a model `MyCustomType`, the `posts.post_type = my_customm_type` filter will be automatically added to the query. + +When creating the model, the `post_type` property is automatically filled in with the value `my_customm_type`. + +**Note:** You cannot use `setPostType` function on CPT models. \ No newline at end of file From 2d39ee47f63831e69a8274672b5fecc5f7f87622 Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Sun, 21 Jan 2024 11:28:25 +0100 Subject: [PATCH 46/67] Fix Post::findOneByName, Refactor meta management --- doc/create-model.md | 4 +- src/Api/WithMetaModelInterface.php | 22 ++++++++++ src/Builders/AbstractWithMetaBuilder.php | 17 ++++--- src/Concerns/HasMeta.php | 44 ++++--------------- ...figAttribute.php => MetaMappingConfig.php} | 5 +-- src/Models/Post.php | 15 +++++-- src/Models/User.php | 13 +++++- 7 files changed, 66 insertions(+), 54 deletions(-) create mode 100644 src/Api/WithMetaModelInterface.php rename src/{Attributes/MetaConfigAttribute.php => MetaMappingConfig.php} (87%) diff --git a/doc/create-model.md b/doc/create-model.md index 6511b46..e3f6ab4 100644 --- a/doc/create-model.md +++ b/doc/create-model.md @@ -2,7 +2,7 @@ You can create two model types: -- A model that corresponds to a custom table (e.g. `User`, `Option`, ... tables) +- A model that corresponds to a custom table (e.g. `User`, `Option`, ...) - A model that corresponds to a Custom Post Type (e.g `Page`, `Attachment`, `Article`, ...) ## Generic Model @@ -40,7 +40,7 @@ Once a model is defined, you are ready to start retrieving and creating records ## Custom Post Type Model -All Custom Post Type (CPT) models extend `Dbout\WpOrm\Models\MyCustomType`. +All Custom Post Type (CPT) models extend `Dbout\WpOrm\Models\CustomPost`. ```php use Dbout\WpOrm\Models\CustomPost; diff --git a/src/Api/WithMetaModelInterface.php b/src/Api/WithMetaModelInterface.php new file mode 100644 index 0000000..2e2df63 --- /dev/null +++ b/src/Api/WithMetaModelInterface.php @@ -0,0 +1,22 @@ + + */ + +namespace Dbout\WpOrm\Api; + +use Dbout\WpOrm\MetaMappingConfig; + +/** + * @since 3.0.0 + */ +interface WithMetaModelInterface +{ + /** + * @return MetaMappingConfig + */ + public function getMetaConfigMapping(): MetaMappingConfig; +} diff --git a/src/Builders/AbstractWithMetaBuilder.php b/src/Builders/AbstractWithMetaBuilder.php index 6c35490..cc41760 100644 --- a/src/Builders/AbstractWithMetaBuilder.php +++ b/src/Builders/AbstractWithMetaBuilder.php @@ -8,9 +8,10 @@ namespace Dbout\WpOrm\Builders; -use Dbout\WpOrm\Attributes\MetaConfigAttribute; +use Dbout\WpOrm\Api\WithMetaModelInterface; use Dbout\WpOrm\Exceptions\MetaNotSupportedException; use Dbout\WpOrm\Exceptions\WpOrmException; +use Dbout\WpOrm\MetaMappingConfig; use Dbout\WpOrm\Orm\AbstractModel; use Illuminate\Database\Eloquent\Model; @@ -29,9 +30,9 @@ abstract class AbstractWithMetaBuilder extends AbstractBuilder ]; /** - * @var MetaConfigAttribute|null + * @var MetaMappingConfig|null */ - protected ?MetaConfigAttribute $metaConfig = null; + protected ?MetaMappingConfig $metaConfig = null; /** * @var string|null @@ -145,17 +146,15 @@ public function joinToMeta(string $metaKey, string $joinType = 'inner'): self */ protected function initMeta(): void { - $traits = class_uses_recursive(get_class($this->model)); - if (!in_array(\Dbout\WpOrm\Concerns\HasMeta::class, $traits, true)) { + if (!$this->model instanceof WithMetaModelInterface) { throw new MetaNotSupportedException(sprintf( - 'Model %s must be use trait %s', + 'Model %s must be implement %s', get_class($this->model), - \Dbout\WpOrm\Concerns\HasMeta::class + WithMetaModelInterface::class )); } - // @phpstan-ignore-next-line - $config = $this->model->getMetaConfig(); + $config = $this->model->getMetaConfigMapping(); $reflection = new \ReflectionClass($config->metaClass); if (!$reflection->isSubclassOf(AbstractModel::class)) { throw new WpOrmException(sprintf( diff --git a/src/Concerns/HasMeta.php b/src/Concerns/HasMeta.php index 50ea2dd..0787feb 100644 --- a/src/Concerns/HasMeta.php +++ b/src/Concerns/HasMeta.php @@ -8,18 +8,12 @@ namespace Dbout\WpOrm\Concerns; -use Dbout\WpOrm\Attributes\MetaConfigAttribute; -use Dbout\WpOrm\Exceptions\WpOrmException; +use Dbout\WpOrm\MetaMappingConfig; use Dbout\WpOrm\Models\Meta\AbstractMeta; use Illuminate\Database\Eloquent\Relations\HasMany; trait HasMeta { - /** - * @var MetaConfigAttribute - */ - protected MetaConfigAttribute $metaConfig; - /** * @var array */ @@ -35,29 +29,12 @@ protected static function bootHasMeta(): void }); } - /** - * @throws WpOrmException - * @return void - */ - public function initializeHasMeta(): void - { - $reflection = new \ReflectionClass(static::class); - $configs = $reflection->getAttributes(MetaConfigAttribute::class); - if ($configs === []) { - throw new WpOrmException(sprintf('Please define attribute %s.', MetaConfigAttribute::class)); - } - - /** @var MetaConfigAttribute $config */ - $config = $configs[0]; - $this->metaConfig = $config; - } - /** * @return HasMany */ public function metas(): HasMany { - return $this->hasMany($this->metaConfig->metaClass, $this->metaConfig->foreignKey); + return $this->hasMany($this->getMetaConfigMapping()->metaClass, $this->getMetaConfigMapping()->foreignKey); } /** @@ -68,7 +45,7 @@ public function getMeta(string $metaKey): ?AbstractMeta { /** @var ?AbstractMeta $value */ // @phpstan-ignore-next-line - $value = $this->metas()->firstWhere($this->metaConfig->columnKey, $metaKey); + $value = $this->metas()->firstWhere($this->getMetaConfigMapping()->columnKey, $metaKey); return $value; } @@ -95,7 +72,7 @@ public function hasMeta(string $metaKey): bool { // @phpstan-ignore-next-line return $this->metas() - ->where($this->metaConfig->columnKey, $metaKey) + ->where($this->getMetaConfigMapping()->columnKey, $metaKey) ->exists(); } @@ -114,11 +91,11 @@ public function setMeta(string $metaKey, mixed $value): ?AbstractMeta /** @var AbstractMeta $instance */ $instance = $this->metas() ->firstOrNew([ - $this->metaConfig->foreignKey => $metaKey, + $this->getMetaConfigMapping()->foreignKey => $metaKey, ]); $instance->fill([ - $this->metaConfig->columnValue => $value, + $this->getMetaConfigMapping()->columnValue => $value, ])->save(); return $instance; @@ -137,7 +114,7 @@ public function deleteMeta(string $metaKey): bool // @phpstan-ignore-next-line return $this->metas() - ->where($this->metaConfig->columnKey, $metaKey) + ->where($this->getMetaConfigMapping()->columnKey, $metaKey) ->forceDelete(); } @@ -154,10 +131,7 @@ protected function saveTmpMetas(): void } /** - * @return MetaConfigAttribute|null + * @return MetaMappingConfig */ - public function getMetaConfig(): ?MetaConfigAttribute - { - return $this->metaConfig; - } + abstract public function getMetaConfigMapping(): MetaMappingConfig; } diff --git a/src/Attributes/MetaConfigAttribute.php b/src/MetaMappingConfig.php similarity index 87% rename from src/Attributes/MetaConfigAttribute.php rename to src/MetaMappingConfig.php index e59a1c6..8a38721 100644 --- a/src/Attributes/MetaConfigAttribute.php +++ b/src/MetaMappingConfig.php @@ -6,13 +6,12 @@ * Author: Dimitri BOUTEILLE */ -namespace Dbout\WpOrm\Attributes; +namespace Dbout\WpOrm; /** * @since 3.0.0 */ -#[\Attribute(\Attribute::TARGET_CLASS)] -class MetaConfigAttribute +class MetaMappingConfig { /** * @param string $metaClass Meta className diff --git a/src/Models/Post.php b/src/Models/Post.php index b2904da..cdcc4f4 100644 --- a/src/Models/Post.php +++ b/src/Models/Post.php @@ -9,8 +9,10 @@ namespace Dbout\WpOrm\Models; use Carbon\Carbon; +use Dbout\WpOrm\Api\WithMetaModelInterface; use Dbout\WpOrm\Builders\PostBuilder; use Dbout\WpOrm\Concerns\HasMeta; +use Dbout\WpOrm\MetaMappingConfig; use Dbout\WpOrm\Models\Meta\PostMeta; use Dbout\WpOrm\Orm\AbstractModel; use Illuminate\Database\Eloquent\Relations\HasMany; @@ -63,8 +65,7 @@ * @property-read static|null $parent * @property-read Comment[] $comments */ -#[\Dbout\WpOrm\Attributes\MetaConfigAttribute(PostMeta::class, PostMeta::POST_ID)] -class Post extends AbstractModel +class Post extends AbstractModel implements WithMetaModelInterface { use HasMeta; @@ -152,10 +153,18 @@ public function newEloquentBuilder($query): PostBuilder * @param string|null $name * @return Post|null */ - public function findOneByName(?string $name): ?Post + public static function findOneByName(?string $name): ?Post { /** @var Post|null $model */ $model = self::query()->firstWhere(self::POST_NAME, $name); return $model; } + + /** + * @return MetaMappingConfig + */ + public function getMetaConfigMapping(): MetaMappingConfig + { + return new MetaMappingConfig(PostMeta::class, PostMeta::POST_ID); + } } diff --git a/src/Models/User.php b/src/Models/User.php index 7ced1f1..22f24e4 100644 --- a/src/Models/User.php +++ b/src/Models/User.php @@ -9,8 +9,10 @@ namespace Dbout\WpOrm\Models; use Carbon\Carbon; +use Dbout\WpOrm\Api\WithMetaModelInterface; use Dbout\WpOrm\Builders\UserBuilder; use Dbout\WpOrm\Concerns\HasMeta; +use Dbout\WpOrm\MetaMappingConfig; use Dbout\WpOrm\Models\Meta\UserMeta; use Dbout\WpOrm\Orm\AbstractModel; use Illuminate\Database\Eloquent\Relations\HasMany; @@ -41,8 +43,7 @@ * @property-read Comment[] $comments * @property-read Post[] $posts */ -#[\Dbout\WpOrm\Attributes\MetaConfigAttribute(UserMeta::class, UserMeta::USER_ID)] -class User extends AbstractModel +class User extends AbstractModel implements WithMetaModelInterface { use HasMeta; @@ -123,4 +124,12 @@ public static function findOneByLogin(string $login): ?self $result = self::query()->firstWhere(self::LOGIN, $login); return $result; } + + /** + * @return MetaMappingConfig + */ + public function getMetaConfigMapping(): MetaMappingConfig + { + return new MetaMappingConfig(UserMeta::class, UserMeta::USER_ID); + } } From 1212d330f50ab2a87699a3a0acf124264406d3c4 Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Sun, 21 Jan 2024 11:57:07 +0100 Subject: [PATCH 47/67] Fix CPT post_type in constructor args, add phpunit tests --- .github/workflows/ci.yml | 8 ++++- Makefile | 6 +++- composer.json | 3 +- src/Models/CustomPost.php | 6 ++-- src/Test/Unit/Models/CustomPostTypeTest.php | 37 +++++++++++++++++++++ 5 files changed, 53 insertions(+), 7 deletions(-) create mode 100644 src/Test/Unit/Models/CustomPostTypeTest.php diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 952f7a9..80f9485 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,4 +29,10 @@ jobs: run: vendor/bin/php-cs-fixer fix --verbose --diff --dry-run - name: PHPStan Analyse - run: vendor/bin/phpstan analyse -c phpstan.neon \ No newline at end of file + run: vendor/bin/phpstan analyse -c phpstan.neon + + - name: Running unit test + uses: php-actions/phpunit@v3 + with: + version: 10.5.8 + php_version: 8.1 \ No newline at end of file diff --git a/Makefile b/Makefile index f2cccaa..ee3b803 100644 --- a/Makefile +++ b/Makefile @@ -10,4 +10,8 @@ runPHPStan: # Run rector runRector: - vendor/bin/rector process src --dry-run \ No newline at end of file + vendor/bin/rector process src --dry-run + +# Run PHPUnit +runPHPUnit: + vendor/bin/phpunit --verbose diff --git a/composer.json b/composer.json index 4506817..3e2a56a 100644 --- a/composer.json +++ b/composer.json @@ -38,6 +38,7 @@ "require-dev": { "friendsofphp/php-cs-fixer": "^3.28", "phpstan/phpstan": "^1.10", - "rector/rector": "^0.18.4" + "rector/rector": "^0.18.4", + "phpunit/phpunit": "^10.5" } } diff --git a/src/Models/CustomPost.php b/src/Models/CustomPost.php index 12ea6d8..6f40cbf 100644 --- a/src/Models/CustomPost.php +++ b/src/Models/CustomPost.php @@ -25,11 +25,9 @@ abstract class CustomPost extends Post implements CustomModelTypeInterface */ public function __construct(array $attributes = []) { - $this->setRawAttributes([ + parent::__construct(array_merge($attributes, [ self::TYPE => $this->_type, - ]); - - parent::__construct($attributes); + ])); } /** diff --git a/src/Test/Unit/Models/CustomPostTypeTest.php b/src/Test/Unit/Models/CustomPostTypeTest.php new file mode 100644 index 0000000..e85a629 --- /dev/null +++ b/src/Test/Unit/Models/CustomPostTypeTest.php @@ -0,0 +1,37 @@ +expectException(CannotOverrideCustomTypeException::class); + $this->expectExceptionMessage('You cannot override type for this object. Current type [attachment]'); + $model->setPostType('my_type'); + } + + /** + * @return void + */ + public function testSetPostTypeInConstructor(): void + { + $model = new Attachment([ + 'post_type' => 'my_type', + ]); + + $this->assertEquals('attachment', $model->getPostType()); + } +} From edf35be7784d0120833724a53472c3d646445ff8 Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Sun, 21 Jan 2024 11:57:55 +0100 Subject: [PATCH 48/67] CS --- src/Test/Unit/Models/CustomPostTypeTest.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Test/Unit/Models/CustomPostTypeTest.php b/src/Test/Unit/Models/CustomPostTypeTest.php index e85a629..3d289c6 100644 --- a/src/Test/Unit/Models/CustomPostTypeTest.php +++ b/src/Test/Unit/Models/CustomPostTypeTest.php @@ -1,4 +1,10 @@ + */ namespace Dbout\WpOrm\Test\Unit\Models; @@ -12,8 +18,8 @@ class CustomPostTypeTest extends TestCase { /** - * @return void * @throws \Dbout\WpOrm\Exceptions\NotAllowedException + * @return void */ public function testSetPostTypeException(): void { From 5a2459fffa177423a0eb18c6bf109718cded7012 Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Sun, 21 Jan 2024 11:59:57 +0100 Subject: [PATCH 49/67] Update CI PHPUnit --- .github/workflows/ci.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 80f9485..30107d1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,7 +32,4 @@ jobs: run: vendor/bin/phpstan analyse -c phpstan.neon - name: Running unit test - uses: php-actions/phpunit@v3 - with: - version: 10.5.8 - php_version: 8.1 \ No newline at end of file + run: vendor/bin/phpunit \ No newline at end of file From 59b9e7904b7fce3fcf93bebc6116ba160b79502b Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Sun, 21 Jan 2024 12:06:43 +0100 Subject: [PATCH 50/67] Update PHPUnit config --- Makefile | 2 +- phpunit.xml | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 phpunit.xml diff --git a/Makefile b/Makefile index ee3b803..2c7981d 100644 --- a/Makefile +++ b/Makefile @@ -14,4 +14,4 @@ runRector: # Run PHPUnit runPHPUnit: - vendor/bin/phpunit --verbose + ./vendor/bin/phpunit diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..5c4a3d3 --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,8 @@ + + + + + src/ + + + \ No newline at end of file From 041871638ae1d31050da0fabe67d66237676a8c6 Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Sun, 21 Jan 2024 12:29:55 +0100 Subject: [PATCH 51/67] Add tests --- src/Test/Unit/Models/CustomPostTypeTest.php | 3 + .../Unit/Scopes/CustomModelTypeScopeTest.php | 71 +++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 src/Test/Unit/Scopes/CustomModelTypeScopeTest.php diff --git a/src/Test/Unit/Models/CustomPostTypeTest.php b/src/Test/Unit/Models/CustomPostTypeTest.php index 3d289c6..d2eac45 100644 --- a/src/Test/Unit/Models/CustomPostTypeTest.php +++ b/src/Test/Unit/Models/CustomPostTypeTest.php @@ -14,12 +14,14 @@ /** * @since 3.0.0 + * @coversDefaultClass \Dbout\WpOrm\Models\Attachment */ class CustomPostTypeTest extends TestCase { /** * @throws \Dbout\WpOrm\Exceptions\NotAllowedException * @return void + * @covers ::setPostType */ public function testSetPostTypeException(): void { @@ -31,6 +33,7 @@ public function testSetPostTypeException(): void /** * @return void + * @covers ::setPostType */ public function testSetPostTypeInConstructor(): void { diff --git a/src/Test/Unit/Scopes/CustomModelTypeScopeTest.php b/src/Test/Unit/Scopes/CustomModelTypeScopeTest.php new file mode 100644 index 0000000..f58421e --- /dev/null +++ b/src/Test/Unit/Scopes/CustomModelTypeScopeTest.php @@ -0,0 +1,71 @@ + + */ + +namespace Dbout\WpOrm\Test\Unit\Scopes; + +use Dbout\WpOrm\Builders\OptionBuilder; +use Dbout\WpOrm\Builders\PostBuilder; +use Dbout\WpOrm\Exceptions\WpOrmException; +use Dbout\WpOrm\Models\Attachment; +use Dbout\WpOrm\Models\Option; +use Dbout\WpOrm\Scopes\CustomModelTypeScope; +use PHPUnit\Framework\TestCase; + +/** + * @since 3.0.0 + * @coversDefaultClass \Dbout\WpOrm\Scopes\CustomModelTypeScope + */ +class CustomModelTypeScopeTest extends TestCase +{ + private CustomModelTypeScope $subject; + + /** + * @inheritDoc + */ + protected function setUp(): void + { + $this->subject = new CustomModelTypeScope(); + } + + /** + * @throws WpOrmException + * @throws \PHPUnit\Framework\MockObject\Exception + * @return void + * @covers ::apply + */ + public function testWithInvalidModel(): void + { + $model = new Option(); + $builder = $this->createMock(OptionBuilder::class); + $this->expectException(WpOrmException::class); + $this->subject->apply($builder, $model); + } + + /** + * @throws WpOrmException + * @throws \PHPUnit\Framework\MockObject\Exception + * @return void + * @covers ::apply + */ + public function testBuilderContainFilter(): void + { + $model = new Attachment(); + $query = new \Illuminate\Database\Query\Builder( + $this->createMock(\Illuminate\Database\MySqlConnection::class), + new \Illuminate\Database\Query\Grammars\Grammar(), + new \Illuminate\Database\Query\Processors\Processor() + ); + $builder = new PostBuilder($query); + $this->subject->apply($builder, $model); + + $this->assertEquals('select * where "post_type" = ?', $builder->toSql()); + $this->assertEquals([ + 'attachment', + ], $builder->getBindings()); + } +} From 335dcc2fefeb2fa95fddf988716b6465a1f09221 Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Sun, 21 Jan 2024 12:39:13 +0100 Subject: [PATCH 52/67] Update CI --- .github/workflows/ci.yml | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 30107d1..247a8ed 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,16 +1,12 @@ -name: ci +name: Coding Style & Tests on: pull_request: jobs: - analyze: - name: Analyze + codingStyle: + name: Coding Style runs-on: ubuntu-latest - permissions: - actions: read - contents: read - security-events: write steps: - name: Checkout repo @@ -29,7 +25,23 @@ jobs: run: vendor/bin/php-cs-fixer fix --verbose --diff --dry-run - name: PHPStan Analyse - run: vendor/bin/phpstan analyse -c phpstan.neon + run: php -d memory_limit=-1 vendor/bin/phpstan analyse -c phpstan.neon + + tests: + name: Tests + runs-on: ubuntu-latest + permissions: + contents: write + + steps: + - name: Checkout repo + uses: actions/checkout@v3 + + - name: Configure PHP + uses: shivammathur/setup-php@v2 + with: + php-version: 8.1 + tools: composer:v2 - name: Running unit test run: vendor/bin/phpunit \ No newline at end of file From 578d57c4e636bb81a8277e326450e1870d758784 Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Sun, 21 Jan 2024 12:40:52 +0100 Subject: [PATCH 53/67] Update CI --- .github/workflows/ci.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 247a8ed..8f7e29b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,4 +1,4 @@ -name: Coding Style & Tests +name: CI on: pull_request: @@ -43,5 +43,8 @@ jobs: php-version: 8.1 tools: composer:v2 + - name: Install dependencies + run: composer install --prefer-dist --no-progress + - name: Running unit test run: vendor/bin/phpunit \ No newline at end of file From acc0aab64e2a198921a44c7a2a448f8e3d429d85 Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Sun, 21 Jan 2024 16:15:53 +0100 Subject: [PATCH 54/67] Split CI --- .github/workflows/{ci.yml => styles.yml} | 24 +---------------------- .github/workflows/tests.yml | 25 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 23 deletions(-) rename .github/workflows/{ci.yml => styles.yml} (56%) create mode 100644 .github/workflows/tests.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/styles.yml similarity index 56% rename from .github/workflows/ci.yml rename to .github/workflows/styles.yml index 8f7e29b..d3581c6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/styles.yml @@ -1,4 +1,4 @@ -name: CI +name: Coding Styles on: pull_request: @@ -26,25 +26,3 @@ jobs: - name: PHPStan Analyse run: php -d memory_limit=-1 vendor/bin/phpstan analyse -c phpstan.neon - - tests: - name: Tests - runs-on: ubuntu-latest - permissions: - contents: write - - steps: - - name: Checkout repo - uses: actions/checkout@v3 - - - name: Configure PHP - uses: shivammathur/setup-php@v2 - with: - php-version: 8.1 - tools: composer:v2 - - - name: Install dependencies - run: composer install --prefer-dist --no-progress - - - name: Running unit test - run: vendor/bin/phpunit \ No newline at end of file diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..8b1d6b6 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,25 @@ +name: Tests + +on: + pull_request: + +jobs: + test: + name: Tests + runs-on: ubuntu-latest + + steps: + - name: Checkout repo + uses: actions/checkout@v3 + + - name: Configure PHP + uses: shivammathur/setup-php@v2 + with: + php-version: 8.1 + tools: composer:v2 + + - name: Install dependencies + run: composer install --prefer-dist --no-progress + + - name: Running unit test + run: vendor/bin/phpunit \ No newline at end of file From 49c31c0c9f215c7be9328efbdc98cd2f6caaa79d Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Sun, 21 Jan 2024 16:21:48 +0100 Subject: [PATCH 55/67] Add test badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6d92d04..3a646bb 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Wordpress ORM with Eloquent -![GitHub Release](https://img.shields.io/github/v/release/dimitriBouteille/wp-orm) ![Packagist Downloads](https://img.shields.io/packagist/dt/dbout/wp-orm) ![Eloquent version](https://img.shields.io/packagist/dependency-v/dbout/wp-orm/illuminate%2Fdatabase?color=orange) +![GitHub Release](https://img.shields.io/github/v/release/dimitriBouteille/wp-orm) ![tests](https://img.shields.io/github/actions/workflow/status/dimitriBouteille/wp-orm/tests.yml?label=tests) ![Packagist Downloads](https://img.shields.io/packagist/dt/dbout/wp-orm?color=yellow) ![Eloquent version](https://img.shields.io/packagist/dependency-v/dbout/wp-orm/illuminate%2Fdatabase?color=orange) WordPress ORM wih Eloquent is a small library that adds a basic ORM into WordPress, which is easily extendable and includes models for core WordPress models such as posts, post metas, users, comments and more. The ORM is based on [Eloquent ORM](https://laravel.com/docs/8.x/eloquent) and uses the WordPress connection (`wpdb` class). From 1c0a2208976d7bf4abf7c2005c6b0b41863d98fd Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Sun, 21 Jan 2024 16:25:18 +0100 Subject: [PATCH 56/67] Update composer.json, add badge links --- README.md | 2 +- composer.json | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 3a646bb..2bd5752 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Wordpress ORM with Eloquent -![GitHub Release](https://img.shields.io/github/v/release/dimitriBouteille/wp-orm) ![tests](https://img.shields.io/github/actions/workflow/status/dimitriBouteille/wp-orm/tests.yml?label=tests) ![Packagist Downloads](https://img.shields.io/packagist/dt/dbout/wp-orm?color=yellow) ![Eloquent version](https://img.shields.io/packagist/dependency-v/dbout/wp-orm/illuminate%2Fdatabase?color=orange) +![GitHub Release](https://img.shields.io/github/v/release/dimitriBouteille/wp-orm) [![tests](https://img.shields.io/github/actions/workflow/status/dimitriBouteille/wp-orm/tests.yml?label=tests)](https://github.com/dimitriBouteille/wp-orm/actions/workflows/tests.yml) [![Packagist Downloads](https://img.shields.io/packagist/dt/dbout/wp-orm?color=yellow)](https://packagist.org/packages/dbout/wp-orm) ![Eloquent version](https://img.shields.io/packagist/dependency-v/dbout/wp-orm/illuminate%2Fdatabase?color=orange) WordPress ORM wih Eloquent is a small library that adds a basic ORM into WordPress, which is easily extendable and includes models for core WordPress models such as posts, post metas, users, comments and more. The ORM is based on [Eloquent ORM](https://laravel.com/docs/8.x/eloquent) and uses the WordPress connection (`wpdb` class). diff --git a/composer.json b/composer.json index 3e2a56a..17204df 100644 --- a/composer.json +++ b/composer.json @@ -1,8 +1,8 @@ { "name": "dbout/wp-orm", - "description": "Wordpress ORM with Eloquent and Phinx", + "description": "Wordpress ORM with Eloquent and Phinx.", "type": "package", - "license": "GPL-2.0-or-later", + "license": "MIT", "version": "3.0.0", "authors": [ { @@ -13,9 +13,10 @@ } ], "keywords": ["wordpress", "wp", "orm", "database", "eloquent", "db", "sql", "migration", "phinx"], - "homepage": "https://github.com/dimitriBouteille/wp-orm/", + "homepage": "https://github.com/dimitriBouteille/wp-orm", "support": { - "issues": "https://github.com/dimitriBouteille/wp-orm/issues" + "issues": "https://github.com/dimitriBouteille/wp-orm/issues", + "source": "https://github.com/dimitriBouteille/wp-orm/" }, "minimum-stability": "dev", "prefer-stable": true, From affdd859a868b1773f416c91a0d1e8a92b1afdcd Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Mon, 22 Jan 2024 15:17:10 +0100 Subject: [PATCH 57/67] #7 WIP documentation --- README.md | 9 +++++---- doc/create-model.md | 2 +- doc/wordpress-core-models.md | 19 +++++++++++++++++++ 3 files changed, 25 insertions(+), 5 deletions(-) create mode 100644 doc/wordpress-core-models.md diff --git a/README.md b/README.md index 2bd5752..3a99684 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,9 @@ The ORM is based on [Eloquent ORM](https://laravel.com/docs/8.x/eloquent) and us The ORM also offers a system to simply manage database migrations based on [Phinx](https://phinx.org/). -💡 To simplify the integration of this library, we recommend using WordPress with one of the following tools: [Bedrock](https://roots.io/bedrock/), [Themosis](https://framework.themosis.com/) or [Wordplate](https://github.com/wordplate/wordplate#readme). +> 📘 This is documentation for additional functionality on top of Eloquent. For documentation on all of Eloquent's features you visit the documentation. + +> 💡 To simplify the integration of this library, we recommend using WordPress with one of the following tools: [Bedrock](https://roots.io/bedrock/), [Themosis](https://framework.themosis.com/) or [Wordplate](https://github.com/wordplate/wordplate#readme). ### Features @@ -26,10 +28,9 @@ The ORM also offers a system to simply manage database migrations based on [Phin ### Documentation - [Installation](#installation) -- [Introduction](#introduction) -- [Use WordPress models](doc/documentation.md#use-wordpress-models) +- [Use WordPress core models](doc/wordpress-core-models.md) +- [Create custom model](doc/create-model.md) - [Filter data](/doc/documentation.md#filter-data) -- [Create custom Model](doc/create-model.md) - [Migration with Phinx](doc/migration.md) ## Installation diff --git a/doc/create-model.md b/doc/create-model.md index e3f6ab4..ade2800 100644 --- a/doc/create-model.md +++ b/doc/create-model.md @@ -34,7 +34,7 @@ class MyModel extends AbstractModel Once a model is defined, you are ready to start retrieving and creating records in your table. Note that you will need to place `updated_at` and `created_at` columns on your table by default. If you do not wish to have these columns automatically maintained, set the `$timestamps` property on your model to false. -> 💡 If your model may have metas, you can easily link metas to your model. You can look `Dbout\WpOrm\Models\Post` to understand how it works. +> 💡 If your model have metas, you can easily link metas to your model and use custom functions (e.g. `getMeta`, `getMetaValue`, ...). You can look `Dbout\WpOrm\Models\Post` to understand how it works. > 📘 If you want to know more about creating a model you can look the [Eloquent documentation](https://laravel.com/docs/5.0/eloquent#basic-usage). diff --git a/doc/wordpress-core-models.md b/doc/wordpress-core-models.md new file mode 100644 index 0000000..587f794 --- /dev/null +++ b/doc/wordpress-core-models.md @@ -0,0 +1,19 @@ +# WordPress Core Models + +## Models + +- Comment +- Option +- Post +- PostMeta +- Term +- TermRelationship +- TermTaxonomy +- User +- UserMeta + +## Custom post type + +- Attachment +- Article +- Page \ No newline at end of file From 72eb1ffd791d6261d2e2d2f74acd0d4f99632d1a Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Mon, 22 Jan 2024 15:22:25 +0100 Subject: [PATCH 58/67] Test to Tests directory --- src/{Test => Tests}/Unit/Models/CustomPostTypeTest.php | 2 +- src/{Test => Tests}/Unit/Scopes/CustomModelTypeScopeTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename src/{Test => Tests}/Unit/Models/CustomPostTypeTest.php (96%) rename src/{Test => Tests}/Unit/Scopes/CustomModelTypeScopeTest.php (97%) diff --git a/src/Test/Unit/Models/CustomPostTypeTest.php b/src/Tests/Unit/Models/CustomPostTypeTest.php similarity index 96% rename from src/Test/Unit/Models/CustomPostTypeTest.php rename to src/Tests/Unit/Models/CustomPostTypeTest.php index d2eac45..95932f4 100644 --- a/src/Test/Unit/Models/CustomPostTypeTest.php +++ b/src/Tests/Unit/Models/CustomPostTypeTest.php @@ -6,7 +6,7 @@ * Author: Dimitri BOUTEILLE */ -namespace Dbout\WpOrm\Test\Unit\Models; +namespace Dbout\WpOrm\Tests\Unit\Models; use Dbout\WpOrm\Exceptions\CannotOverrideCustomTypeException; use Dbout\WpOrm\Models\Attachment; diff --git a/src/Test/Unit/Scopes/CustomModelTypeScopeTest.php b/src/Tests/Unit/Scopes/CustomModelTypeScopeTest.php similarity index 97% rename from src/Test/Unit/Scopes/CustomModelTypeScopeTest.php rename to src/Tests/Unit/Scopes/CustomModelTypeScopeTest.php index f58421e..c704453 100644 --- a/src/Test/Unit/Scopes/CustomModelTypeScopeTest.php +++ b/src/Tests/Unit/Scopes/CustomModelTypeScopeTest.php @@ -6,7 +6,7 @@ * Author: Dimitri BOUTEILLE */ -namespace Dbout\WpOrm\Test\Unit\Scopes; +namespace Dbout\WpOrm\Tests\Unit\Scopes; use Dbout\WpOrm\Builders\OptionBuilder; use Dbout\WpOrm\Builders\PostBuilder; From 02869dfa5327b665d2ed5f7f14610a9031e6f861 Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Mon, 29 Jan 2024 20:36:49 +0100 Subject: [PATCH 59/67] Add WithMetaBuilderTest, fix join meta value --- composer.json | 16 +- src/Builders/AbstractWithMetaBuilder.php | 4 +- .../Unit/Builders/WithMetaBuilderTest.php | 166 ++++++++++++++++++ 3 files changed, 183 insertions(+), 3 deletions(-) create mode 100644 src/Tests/Unit/Builders/WithMetaBuilderTest.php diff --git a/composer.json b/composer.json index 17204df..306697d 100644 --- a/composer.json +++ b/composer.json @@ -40,6 +40,20 @@ "friendsofphp/php-cs-fixer": "^3.28", "phpstan/phpstan": "^1.10", "rector/rector": "^0.18.4", - "phpunit/phpunit": "^10.5" + "phpunit/phpunit": "^10.5", + "phpstan/phpstan-phpunit": "^1.3", + "phpstan/extension-installer": "^1.3" + }, + "config": { + "allow-plugins": { + "phpstan/extension-installer": true + } + }, + "extra": { + "phpstan": { + "includes": [ + "extension.neon" + ] + } } } diff --git a/src/Builders/AbstractWithMetaBuilder.php b/src/Builders/AbstractWithMetaBuilder.php index cc41760..3463071 100644 --- a/src/Builders/AbstractWithMetaBuilder.php +++ b/src/Builders/AbstractWithMetaBuilder.php @@ -60,7 +60,7 @@ public function addMetaToSelect(string $metaKey, ?string $alias = null): self { $this->joinToMeta($metaKey); if ($alias === null || $alias === '') { - $alias = $metaKey; + $alias = sprintf('%s_value', $metaKey); } $column = sprintf('%s.%s AS %s', $metaKey, $this->metaConfig?->columnValue, $alias); @@ -128,7 +128,7 @@ public function joinToMeta(string $metaKey, string $joinType = 'inner'): self $join->on( sprintf('%s.%s', $metaKey, $this->metaConfig?->columnKey), '=', - $join->raw(sprintf("'%s'", $metaKey)) + "$metaKey" )->on( sprintf('%s.%s', $metaKey, $this->metaConfig?->foreignKey), '=', diff --git a/src/Tests/Unit/Builders/WithMetaBuilderTest.php b/src/Tests/Unit/Builders/WithMetaBuilderTest.php new file mode 100644 index 0000000..d7230b8 --- /dev/null +++ b/src/Tests/Unit/Builders/WithMetaBuilderTest.php @@ -0,0 +1,166 @@ + + */ + +namespace Dbout\WpOrm\Tests\Unit\Builders; + +use Dbout\WpOrm\Builders\PostBuilder; +use Dbout\WpOrm\Exceptions\WpOrmException; +use Dbout\WpOrm\Models\Post; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; + +/** + * @since 3.0.0 + * @coversDefaultClass \Dbout\WpOrm\Builders\AbstractWithMetaBuilder + */ +class WithMetaBuilderTest extends TestCase +{ + private PostBuilder $builder; + + private Post&MockObject $post; + + /** + * @inheritDoc + * @throws \PHPUnit\Framework\MockObject\Exception + * @throws \Exception + */ + protected function setUp(): void + { + $queryBuilder = new \Illuminate\Database\Query\Builder( + $this->createMock(\Illuminate\Database\MySqlConnection::class), + new \Illuminate\Database\Query\Grammars\Grammar(), + new \Illuminate\Database\Query\Processors\Processor() + ); + + $post = $this->createPartialMock(Post::class, ['getTable']); + $post->method('getTable')->willReturn('posts'); + $this->post = $post; + $builder = new PostBuilder($queryBuilder); + $builder->setModel($this->post); + $this->builder = $builder; + } + + /** + * @param string $metaKey + * @param string|null $alias + * @param string $expectedQuery + * @throws WpOrmException + * @return void + * @covers ::addMetaToSelect + * @dataProvider providerTestAddMetaToSelect + */ + public function testAddMetaToSelect(string $metaKey, ?string $alias, string $expectedQuery): void + { + $this->builder->addMetaToSelect($metaKey, $alias); + $query = $this->builder->toSql(); + $this->assertEquals($expectedQuery, $query); + } + + /** + * @return array + */ + public static function providerTestAddMetaToSelect(): array + { + return [ + 'Without alias' => [ + 'my_meta', + null, + 'select "posts".*, "my_meta"."meta_value" as "my_meta_value" from "posts" inner join "postmeta" as "my_meta" on "my_meta"."meta_key" = "my_meta" and "my_meta"."post_id" = "posts"."ID"', + ], + 'With alias' => [ + 'first_name', + 'my_custom_alias', + 'select "posts".*, "first_name"."meta_value" as "my_custom_alias" from "posts" inner join "postmeta" as "first_name" on "first_name"."meta_key" = "first_name" and "first_name"."post_id" = "posts"."ID"', + ], + ]; + } + + /** + * @param array $metas + * @param string $expectedQuery + * @throws WpOrmException + * @return void + * @covers ::addMetasToSelect + * @dataProvider providerTestAddMetasToSelect + */ + public function testAddMetasToSelect(array $metas, string $expectedQuery): void + { + $this->builder->addMetasToSelect($metas); + $query = $this->builder->toSql(); + $this->assertEquals($expectedQuery, $query); + } + + /** + * @return array + */ + public static function providerTestAddMetasToSelect(): array + { + return [ + 'Without alias' => [ + [ + 'firstname', + 'lastname', + ], + 'select "posts".*, "firstname"."meta_value" as "firstname_value", "lastname"."meta_value" as "lastname_value" from "posts" inner join "postmeta" as "firstname" on "firstname"."meta_key" = "firstname" and "firstname"."post_id" = "posts"."ID" inner join "postmeta" as "lastname" on "lastname"."meta_key" = "lastname" and "lastname"."post_id" = "posts"."ID"', + ], + 'With alias' => [ + [ + 'my_meta' => 'firstname', + 'second_meta' => 'lastname', + ], + 'select "posts".*, "firstname"."meta_value" as "my_meta", "lastname"."meta_value" as "second_meta" from "posts" inner join "postmeta" as "firstname" on "firstname"."meta_key" = "firstname" and "firstname"."post_id" = "posts"."ID" inner join "postmeta" as "lastname" on "lastname"."meta_key" = "lastname" and "lastname"."post_id" = "posts"."ID"', + ], + 'On meta with alias on another one without alias' => [ + [ + 'my_meta' => 'street_1', + 'lastname', + ], + 'select "posts".*, "street_1"."meta_value" as "my_meta", "lastname"."meta_value" as "lastname_value" from "posts" inner join "postmeta" as "street_1" on "street_1"."meta_key" = "street_1" and "street_1"."post_id" = "posts"."ID" inner join "postmeta" as "lastname" on "lastname"."meta_key" = "lastname" and "lastname"."post_id" = "posts"."ID"', + ], + ]; + } + + /** + * @throws WpOrmException + * @return void + * @covers ::joinToMeta + */ + public function testJoinToMeta(): void + { + $this->post->expects($this->once())->method('getTable'); + $this->builder->joinToMeta('my_meta'); + $query = $this->builder->toSql(); + $this->assertEquals( + 'select "posts".* from "posts" inner join "postmeta" as "my_meta" on "my_meta"."meta_key" = "my_meta" and "my_meta"."post_id" = "posts"."ID"', + $query + ); + } + + /** + * @throws WpOrmException + * @return void + * @covers ::addMetaToFilter + */ + public function testAddMetaToFilter(): void + { + $this->builder->addMetaToFilter('firstname', 'Dimitri'); + $query = $this->builder->toSql(); + + $this->assertEquals( + 'select "posts".* from "posts" inner join "postmeta" as "firstname" on "firstname"."meta_key" = "firstname" and "firstname"."post_id" = "posts"."ID" where "firstname"."meta_value" = ?', + $query, + ); + + $this->assertEquals( + [ + 'Dimitri', + ], + $this->builder->getBindings(), + ); + } +} From a14ac664614b19fda325d81607c1e7d5743a39a4 Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Mon, 29 Jan 2024 20:42:30 +0100 Subject: [PATCH 60/67] Add Post::findOneByGuid() --- src/Models/Post.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/Models/Post.php b/src/Models/Post.php index cdcc4f4..2822c0e 100644 --- a/src/Models/Post.php +++ b/src/Models/Post.php @@ -160,6 +160,17 @@ public static function findOneByName(?string $name): ?Post return $model; } + /** + * @param string $guid + * @return Post|null + */ + public static function findOneByGuid(string $guid): ?Post + { + /** @var Post|null $model */ + $model = self::query()->firstWhere(self::GUID, $guid); + return $model; + } + /** * @return MetaMappingConfig */ From b1e6500103118803fa78dcabb0137344ce9754a3 Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Mon, 29 Jan 2024 22:02:06 +0100 Subject: [PATCH 61/67] Remove composer.json version --- composer.json | 1 - 1 file changed, 1 deletion(-) diff --git a/composer.json b/composer.json index 306697d..aab68d8 100644 --- a/composer.json +++ b/composer.json @@ -3,7 +3,6 @@ "description": "Wordpress ORM with Eloquent and Phinx.", "type": "package", "license": "MIT", - "version": "3.0.0", "authors": [ { "name": "Dimitri BOUTEILLE", From 4d6f7b23adac4a93bdcb812b37e20798b97b31d3 Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Tue, 30 Jan 2024 19:13:48 +0100 Subject: [PATCH 62/67] Some update --- README.md | 4 +--- composer.json | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 3a99684..8923f2b 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Wordpress ORM with Eloquent +# WordPress ORM with Eloquent ![GitHub Release](https://img.shields.io/github/v/release/dimitriBouteille/wp-orm) [![tests](https://img.shields.io/github/actions/workflow/status/dimitriBouteille/wp-orm/tests.yml?label=tests)](https://github.com/dimitriBouteille/wp-orm/actions/workflows/tests.yml) [![Packagist Downloads](https://img.shields.io/packagist/dt/dbout/wp-orm?color=yellow)](https://packagist.org/packages/dbout/wp-orm) ![Eloquent version](https://img.shields.io/packagist/dependency-v/dbout/wp-orm/illuminate%2Fdatabase?color=orange) @@ -7,8 +7,6 @@ The ORM is based on [Eloquent ORM](https://laravel.com/docs/8.x/eloquent) and us The ORM also offers a system to simply manage database migrations based on [Phinx](https://phinx.org/). -> 📘 This is documentation for additional functionality on top of Eloquent. For documentation on all of Eloquent's features you visit the documentation. - > 💡 To simplify the integration of this library, we recommend using WordPress with one of the following tools: [Bedrock](https://roots.io/bedrock/), [Themosis](https://framework.themosis.com/) or [Wordplate](https://github.com/wordplate/wordplate#readme). ### Features diff --git a/composer.json b/composer.json index aab68d8..c1d1b06 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "dbout/wp-orm", - "description": "Wordpress ORM with Eloquent and Phinx.", + "description": "WordPress ORM with Eloquent and Phinx.", "type": "package", "license": "MIT", "authors": [ From 145d3fc017417829be972f8fd1fe02f05ce0da9d Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Tue, 30 Jan 2024 19:55:43 +0100 Subject: [PATCH 63/67] #7 Update documentation --- README.md | 43 ++++++++++----------- doc/documentation.md | 89 -------------------------------------------- doc/filter-data.md | 60 +++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+), 113 deletions(-) delete mode 100644 doc/documentation.md create mode 100644 doc/filter-data.md diff --git a/README.md b/README.md index 8923f2b..f2c0f4b 100644 --- a/README.md +++ b/README.md @@ -11,24 +11,33 @@ The ORM also offers a system to simply manage database migrations based on [Phin ### Features -- ✅ Support core WordPress models: `Comment`, `Option`, `Post`, `TermTaxonomy`, `Term`, `User`, `PostMeta` and `UserMeta`. -- ✅ Support core WordPress post type: `Article`, `Attachment` and `Page`. -- ✅ Based on core WordPress database connection (`wpdb` class) -- ✅ Migration with `Phinx` library. -- ❤️ Easy integration of a custom post type. -- ❤️ Easy model creation for projects with custom tables. +- ✅ Support core WordPress models: `Comment`, `Option`, `Post`, `TermTaxonomy`, `Term`, `User`, `PostMeta` and `UserMeta` +- ✅ Support core WordPress post type: `Article`, `Attachment` and `Page` +- ✅ Based on core WordPress database connection (`wpdb` class), no configuration required ! +- ✅ Migration with `Phinx` +- ✅ Custom functions to filter models with meta +- ❤️ Easy integration of a custom post type +- ❤️ Easy model creation for projects with custom tables +- ❤️ All the features available in Eloquent, are usable with this library ! **Not yet developed but planned in a future version:** -- 💡 Create custom comment type -- 💡 Meta casting (e.g. [Attribute Casting](https://laravel.com/docs/10.x/eloquent-mutators#attribute-casting)) +- 🗓️ Create custom comment type +- 🗓️ Meta casting (e.g. [Attribute Casting](https://laravel.com/docs/10.x/eloquent-mutators#attribute-casting)) ### Documentation +This documentation only covers the specific points of this library, if you want to know more about Eloquent, the easiest is to look at [the documentation of Eloquent](https://laravel.com/docs/10.x/eloquent) :) + - [Installation](#installation) - [Use WordPress core models](doc/wordpress-core-models.md) +- [Filter data](/doc/filter-data.md) + - [With findOneBy*](/doc/filter-data.md#with-findoneby) + - [With predefined taps](/doc/filter-data.md#with-taps) + - [With query builder](/doc/filter-data.md#with-query-builder) - [Create custom model](doc/create-model.md) -- [Filter data](/doc/documentation.md#filter-data) + - [Generic Model](doc/create-model.md#generic-model) + - [Custom Post Type Model](doc/create-model.md#custom-post-type-model) - [Migration with Phinx](doc/migration.md) ## Installation @@ -54,21 +63,7 @@ In your PHP script, make sure you include the autoloader: require __DIR__ . '/vendor/autoload.php'; ~~~ -## Introduction - -Simply put, wp-orm is a library that makes it easy to manipulate a WordPress database via the Eloquent ORM. The objective of this library is to **simplify the manipulation of the WordPress database** on large projects - you can also use it for small projects. - -> Eloquent is an object-relational mapper (ORM) that makes it enjoyable to interact with your database. When using Eloquent, each database table has a corresponding "Model" that is used to interact with that table. In addition to retrieving records from the database table, Eloquent models allow you to insert, update, and delete records from the table as well. - -**Here is a list of available features :** - -- The `wpdb` connection is used so **no configuration is needed to use** -- Ability to [create models](doc/documentation.md#model) simply -- WordPress works with custom content types, you can simply [use the default types of WordPress](doc/documentation.md#use-wordpress-models) (page, attachment, ...) and create [custom models for your types](doc/documentation.md#custom-post-type-model) or create [custom model](doc/documentation.md) -- Ability to [filter data](doc/documentation.md#filter-data) easily via taps -- All the features available in Eloquent, are usable with this library - -> 📘 If you want to know more about how Eloquent works, the easiest way is to [read the documentation](https://laravel.com/docs/10.x/eloquent). +🎉 You have nothing more to do, you can use the library now! Not even need to configure database accesses because it's the `wpdb` connection that is used. ## Contributing diff --git a/doc/documentation.md b/doc/documentation.md deleted file mode 100644 index 58f76e1..0000000 --- a/doc/documentation.md +++ /dev/null @@ -1,89 +0,0 @@ -# Documentation - -## Use Wordpress Models - -## Filter data - -You can easily filter data via the `tap` function : - -```php -use Dbout\WpOrm\Taps\Post\IsAuthorTap; -use Dbout\WpOrm\Taps\Post\IsStatusTap; -use Dbout\WpOrm\Enums\PostStatus; -use Dbout\WpOrm\Models\Post; - -$posts = Post::query() - ->tap(new IsAuthorTap(1)) - ->get(); -``` - -This query, returns all user posts with ID 1. - -If you want to apply multiple filters, nothing complicated : - -```php -use Dbout\WpOrm\Taps\Post\IsAuthorTap; -use Dbout\WpOrm\Taps\Post\IsStatusTap; -use Dbout\WpOrm\Enums\PostStatus; -use Dbout\WpOrm\Models\Post; - -$posts = Post::query() - ->tap(new IsAuthorTap(1)) - ->tap(new IsStatusTap(PostStatus::Publish)) - ->get(); -``` - -You can find all the available filters here: [Available filters](available-filters.md). - -## Create Model - -### Model - -Creating a model is very simple, just create a class that extends from `Dbout\WpOrm\Orm\AbstractModel`. - -```php -use Dbout\WpOrm\Orm\AbstractModel; - -class MyModel extends AbstractModel -{ - -} -``` - -Note that we did not tell Eloquent which table to use for our `MyModel` model. The "snake case", plural name of the class will be used as the table name unless another name is explicitly specified. So, in this case, Eloquent will assume the `MyModel` model stores records in the myModels table. You may specify a custom table by defining a table property on your model: - -```php -use Dbout\WpOrm\Orm\AbstractModel; - -class MyModel extends AbstractModel -{ - - protected $table = 'my_table'; -} -``` - -**Note:** Eloquent will also assume that each table has a primary key column named id. You may define a primaryKey property to override this convention. Likewise, you may define a connection property to override the name of the database connection that should be used when utilizing the model. - -Once a model is defined, you are ready to start retrieving and creating records in your table. Note that you will need to place `updated_at` and `created_at` columns on your table by default. If you do not wish to have these columns automatically maintained, set the `$timestamps` property on your model to false. - -> 📘 If you want to know more about creating a model you can look the [Eloquent documentation](https://laravel.com/docs/5.0/eloquent#basic-usage). - -### Custom Post Type Model - -All Custom Post Type (CPT) models extend `Dbout\WpOrm\Models\MyCustomType`. - -```php -use Dbout\WpOrm\Models\CustomPost; - -class MyCustomType extends CustomPost -{ - /** - * @inheritDoc - */ - protected string $_type = 'my_customm_type'; -} -``` - -When retrieving a model `MyCustomType`, the `posts.post_type = my_customm_type` filter will be automatically added to the query. - -**Note:** You cannot use `setPostType` function on CPT models. \ No newline at end of file diff --git a/doc/filter-data.md b/doc/filter-data.md new file mode 100644 index 0000000..584ca4e --- /dev/null +++ b/doc/filter-data.md @@ -0,0 +1,60 @@ +# Filter data + +You can filter data in several ways: + +- With predefined `findOneBy` functions in place on some models +- With predefined taps +- With Eloquent query builder. If your model has metas, you can use custom filter methods. + +## With findOneBy + +## With taps + +You can easily filter data via the `tap` function : + +```php +use Dbout\WpOrm\Taps\Post\IsAuthorTap; +use Dbout\WpOrm\Taps\Post\IsStatusTap; +use Dbout\WpOrm\Enums\PostStatus; +use Dbout\WpOrm\Models\Post; + +$posts = Post::query() + ->tap(new IsAuthorTap(1)) + ->get(); +``` + +This query, returns all user posts with ID 1. + +If you want to apply multiple filters, nothing complicated : + +```php +use Dbout\WpOrm\Taps\Post\IsAuthorTap; +use Dbout\WpOrm\Taps\Post\IsStatusTap; +use Dbout\WpOrm\Enums\PostStatus; +use Dbout\WpOrm\Models\Post; + +$posts = Post::query() + ->tap(new IsAuthorTap(1)) + ->tap(new IsStatusTap(PostStatus::Publish)) + ->get(); +``` + +You can find all the available filters here: [Available filters](available-filters.md). + +## With query builder + +### Generic + +The Eloquent `all` method will return all of the results in the model's table. However, since each Eloquent model serves as a [query builder](https://laravel.com/docs/10.x/queries), you may add additional constraints to queries and then invoke the `get` method to retrieve the results: + +```php +use Dbout\WpOrm\Models\Post; + +$posts = Post::query() + ->where('ping_status', 'closed') + ->get(); +``` + +> 📘 More information here: [Eloquent query builder](https://laravel.com/docs/10.x/queries). + +### Model with meta relation \ No newline at end of file From 55b71e9d424f31cf227f4ac511084e7a45b61407 Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Sun, 11 Feb 2024 18:17:41 +0100 Subject: [PATCH 64/67] Update CI, WIP doc --- .github/workflows/styles.yml | 7 +++++-- .github/workflows/tests.yml | 2 +- Makefile | 17 ----------------- README.md | 2 +- composer.json | 7 +++++++ doc/create-model.md | 8 +++++--- doc/filter-data.md | 32 +++++++++++++++++++++++++++++--- 7 files changed, 48 insertions(+), 27 deletions(-) delete mode 100644 Makefile diff --git a/.github/workflows/styles.yml b/.github/workflows/styles.yml index d3581c6..249486c 100644 --- a/.github/workflows/styles.yml +++ b/.github/workflows/styles.yml @@ -22,7 +22,10 @@ jobs: run: composer install --prefer-dist --no-progress - name: PHPCsFixer - run: vendor/bin/php-cs-fixer fix --verbose --diff --dry-run + run: composer csFixer - name: PHPStan Analyse - run: php -d memory_limit=-1 vendor/bin/phpstan analyse -c phpstan.neon + run: composer phpstan + + - name: Rector + run: composer rector diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 8b1d6b6..5c0aa79 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -22,4 +22,4 @@ jobs: run: composer install --prefer-dist --no-progress - name: Running unit test - run: vendor/bin/phpunit \ No newline at end of file + run: composer phpunit \ No newline at end of file diff --git a/Makefile b/Makefile deleted file mode 100644 index 2c7981d..0000000 --- a/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -.PHONY: csFixer runPHPStan - -# Fix CS fixer -csFixer: - php vendor/bin/php-cs-fixer fix - -# Run phpStan check -runPHPStan: - vendor/bin/phpstan analyse -c phpstan.neon - -# Run rector -runRector: - vendor/bin/rector process src --dry-run - -# Run PHPUnit -runPHPUnit: - ./vendor/bin/phpunit diff --git a/README.md b/README.md index f2c0f4b..3114ce2 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ This documentation only covers the specific points of this library, if you want - [Use WordPress core models](doc/wordpress-core-models.md) - [Filter data](/doc/filter-data.md) - [With findOneBy*](/doc/filter-data.md#with-findoneby) - - [With predefined taps](/doc/filter-data.md#with-taps) + - [With taps](/doc/filter-data.md#with-taps) - [With query builder](/doc/filter-data.md#with-query-builder) - [Create custom model](doc/create-model.md) - [Generic Model](doc/create-model.md#generic-model) diff --git a/composer.json b/composer.json index c1d1b06..37873b8 100644 --- a/composer.json +++ b/composer.json @@ -54,5 +54,12 @@ "extension.neon" ] } + }, + "scripts": { + "rector": "vendor/bin/rector process src --dry-run", + "phpstan": "vendor/bin/phpstan analyse -c phpstan.neon", + "phpunit": "vendor/bin/phpunit", + "csFixer": "vendor/bin/php-cs-fixer fix --verbose --diff --dry-run", + "fix:csFixer": "vendor/bin/php-cs-fixer fix" } } diff --git a/doc/create-model.md b/doc/create-model.md index ade2800..5a49fa3 100644 --- a/doc/create-model.md +++ b/doc/create-model.md @@ -34,10 +34,12 @@ class MyModel extends AbstractModel Once a model is defined, you are ready to start retrieving and creating records in your table. Note that you will need to place `updated_at` and `created_at` columns on your table by default. If you do not wish to have these columns automatically maintained, set the `$timestamps` property on your model to false. -> 💡 If your model have metas, you can easily link metas to your model and use custom functions (e.g. `getMeta`, `getMetaValue`, ...). You can look `Dbout\WpOrm\Models\Post` to understand how it works. - > 📘 If you want to know more about creating a model you can look the [Eloquent documentation](https://laravel.com/docs/5.0/eloquent#basic-usage). +### Add meta relation + +If your model have metas, you can easily link metas to your model and use custom functions (e.g. `getMeta`, `getMetaValue`, ...). You can look `Dbout\WpOrm\Models\Post` to understand how it works. + ## Custom Post Type Model All Custom Post Type (CPT) models extend `Dbout\WpOrm\Models\CustomPost`. @@ -58,4 +60,4 @@ When retrieving a model `MyCustomType`, the `posts.post_type = my_customm_type` When creating the model, the `post_type` property is automatically filled in with the value `my_customm_type`. -**Note:** You cannot use `setPostType` function on CPT models. \ No newline at end of file +**Note:** You cannot use `setPostType` function on CPT models. diff --git a/doc/filter-data.md b/doc/filter-data.md index 584ca4e..4b56a05 100644 --- a/doc/filter-data.md +++ b/doc/filter-data.md @@ -2,12 +2,28 @@ You can filter data in several ways: -- With predefined `findOneBy` functions in place on some models -- With predefined taps +- With `findOneBy` functions in place on some models +- With taps - With Eloquent query builder. If your model has metas, you can use custom filter methods. ## With findOneBy +By default, Eloquent does not offer a magic feature [findOneBy*](https://github.com/laravel/ideas/issues/107), however you can use this feature on some models : + +**User :** + +- `User::findOneByEmail()` +- `User::findOneByLogin()` + +**Option :** + +- `Option::findOneByName()` + +**Post :** + +- `Post::findOneByName()` +- `Post::findOneByGuid()` + ## With taps You can easily filter data via the `tap` function : @@ -57,4 +73,14 @@ $posts = Post::query() > 📘 More information here: [Eloquent query builder](https://laravel.com/docs/10.x/queries). -### Model with meta relation \ No newline at end of file +### Model with meta relation + +For models that may have metas (e.g. `Post`, `User`, ...), you can filter with `addMetaToFilter`, here is an example that speaks for itself:) + +```php +$products = Post::query() + ->addMetaToFilter('product_type', 'simple') + ->get(); +``` + +> 📘 You can find all functions usable on models with metas here: \ No newline at end of file From 8f17795e9b702636488a0d4f5fa8127062808deb Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Sun, 11 Feb 2024 18:20:02 +0100 Subject: [PATCH 65/67] Fix rector CI --- .github/workflows/styles.yml | 6 +++--- src/Tests/Unit/Models/CustomPostTypeTest.php | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/styles.yml b/.github/workflows/styles.yml index 249486c..a196720 100644 --- a/.github/workflows/styles.yml +++ b/.github/workflows/styles.yml @@ -24,8 +24,8 @@ jobs: - name: PHPCsFixer run: composer csFixer - - name: PHPStan Analyse - run: composer phpstan - - name: Rector run: composer rector + + - name: PHPStan Analyse + run: composer phpstan diff --git a/src/Tests/Unit/Models/CustomPostTypeTest.php b/src/Tests/Unit/Models/CustomPostTypeTest.php index 95932f4..ec158be 100644 --- a/src/Tests/Unit/Models/CustomPostTypeTest.php +++ b/src/Tests/Unit/Models/CustomPostTypeTest.php @@ -20,10 +20,10 @@ class CustomPostTypeTest extends TestCase { /** * @throws \Dbout\WpOrm\Exceptions\NotAllowedException - * @return void + * @return never * @covers ::setPostType */ - public function testSetPostTypeException(): void + public function testSetPostTypeException(): never { $model = new Attachment(); $this->expectException(CannotOverrideCustomTypeException::class); From effa1244675a318537dfb28763cbf92c4638ddff Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Sun, 11 Feb 2024 18:21:44 +0100 Subject: [PATCH 66/67] Disable rector CI --- .github/workflows/styles.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/styles.yml b/.github/workflows/styles.yml index a196720..6a6768b 100644 --- a/.github/workflows/styles.yml +++ b/.github/workflows/styles.yml @@ -24,8 +24,8 @@ jobs: - name: PHPCsFixer run: composer csFixer - - name: Rector - run: composer rector + #- name: Rector + # run: composer rector - name: PHPStan Analyse run: composer phpstan From b96161ebbb551af926dda407dd127bc8e26abfc9 Mon Sep 17 00:00:00 2001 From: dimitri-bouteille Date: Sun, 11 Feb 2024 18:30:10 +0100 Subject: [PATCH 67/67] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3114ce2..16069d1 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ ![GitHub Release](https://img.shields.io/github/v/release/dimitriBouteille/wp-orm) [![tests](https://img.shields.io/github/actions/workflow/status/dimitriBouteille/wp-orm/tests.yml?label=tests)](https://github.com/dimitriBouteille/wp-orm/actions/workflows/tests.yml) [![Packagist Downloads](https://img.shields.io/packagist/dt/dbout/wp-orm?color=yellow)](https://packagist.org/packages/dbout/wp-orm) ![Eloquent version](https://img.shields.io/packagist/dependency-v/dbout/wp-orm/illuminate%2Fdatabase?color=orange) WordPress ORM wih Eloquent is a small library that adds a basic ORM into WordPress, which is easily extendable and includes models for core WordPress models such as posts, post metas, users, comments and more. -The ORM is based on [Eloquent ORM](https://laravel.com/docs/8.x/eloquent) and uses the WordPress connection (`wpdb` class). +The ORM is based on [Eloquent ORM](https://laravel.com/docs/eloquent) and uses the WordPress connection (`wpdb` class). The ORM also offers a system to simply manage database migrations based on [Phinx](https://phinx.org/).