jgrossi / corcel
使用Laravel后端或任何PHP框架配合WordPress
Requires
- php: ^8.2
- bordoni/phpass: 0.3.*
- fakerphp/faker: ^1.19
- illuminate/database: ^11.0
- illuminate/filesystem: ^11.0
- illuminate/support: ^11.0
- thunderer/shortcode: ^0.7.3
Requires (Dev)
- dms/phpunit-arraysubset-asserts: ^0.5
- laravel/legacy-factories: ^1.0
- mockery/mockery: ^1.4.4
- orchestra/testbench: ^9.0
- symfony/thanks: ^1.0
Replaces
- juniorgrossi/corcel: v8.0.0
- 8.0.x-dev
- v8.0.0
- 7.0.x-dev
- v7.0.0
- 6.0.x-dev
- v6.0.0
- v5.1.1
- v5.1.0
- 5.0.x-dev
- v5.0.0
- v4.1.0
- 4.0.x-dev
- v4.0.1
- v4.0.0
- v3.4.0
- v3.3.0
- v3.2.0
- v3.1.0
- 3.0.x-dev
- v3.0.0
- 2.8.x-dev
- v2.8.1
- v2.8.0
- 2.7.x-dev
- v2.7.4
- v2.7.3
- v2.7.2
- v2.7.1
- v2.7.0
- 2.6.x-dev
- v2.6.4
- v2.6.3
- v2.6.2
- v2.6.1
- v2.6.0
- 2.5.x-dev
- v2.5.8
- v2.5.7
- v2.5.6
- v2.5.5
- v2.5.4
- v2.5.3
- v2.5.2
- v2.5.1
- v2.5.0
- 2.4.x-dev
- v2.4.1
- v2.4.0
- 2.3.x-dev
- v2.3.1
- v2.3.0
- 2.2.x-dev
- v2.2.1
- v2.2.0
- 2.1.x-dev
- v2.1.1
- v2.1.0
- v1.4.7
- v1.4.6
- v1.4.5
- v1.4.4
- v1.4.3
- v1.4.2
- v1.4.1
- v1.4.0
- v1.3.3
- v1.3.2
- v1.3.1
- v1.3.0
- v1.2.5
- v1.2.4
- v1.2.3
- v1.2.2
- v1.2.1
- v1.1.7
- v1.1.5
- v1.1.4
- v1.1.3
- v1.1.2
- v1.1.1
- v1.1.0
- v1.0.11
- v1.0.10
- v1.0.9
- v1.0.8
- v1.0.7
- v1.0.6
- v1.0.5
- v1.0.4
- v1.0.3
- v1.0.2
- v1.0.1
- v1.0.0
- dev-test-coverage
- dev-cleanup-tests
- dev-create-user
- dev-add-term-to-post
- dev-default-post-type
- dev-2.6-fix-themosis
- dev-corcel-helper
- dev-improve-testing
- dev-feature/role
- dev-feature/api
- dev-master
This package is auto-updated.
Last update: 2024-09-08 20:53:57 UTC
README
一组模型类,允许您直接从WordPress数据库中获取数据。
Corcel是在Eloquent ORM(来自Laravel框架)的基础上构建的PHP类集合,它提供了一个流畅的接口来连接并直接从WordPress数据库获取数据。
您可以将WordPress用作后端(管理面板)或CMS,用于插入帖子、自定义类型等,而另一侧的任何其他PHP应用程序则可以查询这些数据(作为模型层)。与Laravel一起使用Corcel更容易,但您也可以自由地将其用于任何使用Composer的PHP项目。
目录
安装Corcel
版本兼容性
安装Corcel
您需要使用Composer将Corcel安装到您的项目中
composer require jgrossi/corcel
配置(Laravel)
Laravel 5.5及更高版本
Corcel将使用Laravel的自动发现来注册自己。
Laravel 5.4及更早版本
您需要在您的config/app.php
中包含CorcelServiceProvider
。
'providers' => [ /* * Package Service Providers... */ Corcel\Laravel\CorcelServiceProvider::class, ]
发布配置文件
现在配置我们的配置文件以确保您的数据库设置正确,并允许您以非常简单的方式注册自定义帖子类型和短代码
在您的终端中运行以下Artisan命令
php artisan vendor:publish --provider="Corcel\Laravel\CorcelServiceProvider"
现在您有一个config/corcel.php
配置文件,您可以在其中设置与WordPress表关联的数据库连接等。
数据库设置
Laravel设置
只需在config/corcel.php
中设置Corcel将要使用的数据库连接
。
假设您在config/database.php
文件中有以下数据库连接
// File: /config/database.php 'connections' => [ 'mysql' => [ // for Laravel database 'driver' => 'mysql', 'host' => 'localhost', 'database' => 'mydatabase', 'username' => 'admin' 'password' => 'secret', 'charset' => 'utf8', 'collation' => 'utf8_unicode_ci', 'prefix' => '', 'strict' => false, 'engine' => null, ], 'wordpress' => [ // for WordPress database (used by Corcel) 'driver' => 'mysql', 'host' => 'localhost', 'database' => 'mydatabase', 'username' => 'admin', 'password' => 'secret', 'charset' => 'utf8', 'collation' => 'utf8_unicode_ci', 'prefix' => 'wp_', 'strict' => false, 'engine' => null, ], ],
在这种情况下,您可能希望为Corcel使用wordpress
连接,因此只需将其设置在Corcel配置文件config/corcel.php
中即可。
'connection' => 'wordpress',
其他PHP框架(非Laravel)设置
在这里,您需要根据Corcel的要求配置数据库。首先,如果尚未加载,您应包含Composer的autoload
文件。
require __DIR__ . '/vendor/autoload.php';
现在您必须设置您的WordPress数据库参数
$params = [ 'database' => 'database_name', 'username' => 'username', 'password' => 'pa$$word', 'prefix' => 'wp_' // default prefix is 'wp_', you can change to your own prefix ]; Corcel\Database::connect($params);
您可以指定所有Eloquent参数,但其中一些是默认的(但您可以覆盖它们)。
'driver' => 'mysql', 'host' => 'localhost', 'charset' => 'utf8', 'collation' => 'utf8_unicode_ci', 'prefix' => 'wp_', // Specify the prefix for WordPress tables, default prefix is 'wp_'
用法
帖子
每次您看到
Post::method()
,如果您正在使用自己的 Post 类(其中您设置了连接名称),例如App\Post
,则应使用App\Post::method()
而不是Post::method()
。所有示例都假定您已经知道这个区别。
在示例中,每次您看到
Post::method()
,假设它是Corcel\Model\Post::method()
。
// All published posts $posts = Post::published()->get(); $posts = Post::status('publish')->get(); // A specific post $post = Post::find(31); echo $post->post_title;
创建自己的模型类
可选地,您可以创建自己的 Post
模型(或页面,或任何其他内容),该模型扩展了 Corcel\Post
。然后设置您正在使用的连接名称(如果您想覆盖 Corcel 的默认连接名称),在这个例子中是 foo-bar
。
扩展
Corcel\Model\Post
类可以为您的项目增加灵活性,一旦您可以添加自定义方法和逻辑,就可以根据您从 WordPress 数据库中需要使用的内容来使用。
<?php // File: app/Post.php namespace App; use Corcel\Model\Post as Corcel; class Post extends Corcel { protected $connection = 'foo-bar'; public function customMethod() { // } }
因此,现在您可以使用自己的类获取 WP 数据库数据
$posts = App\Post::all(); // using the 'foo-bar' connection
请记住,您不必扩展我们的
Post
类,您可以无任何问题使用Corcel\Model\Post
和其他所有模型。
元数据(自定义字段)
注意:在 Corcel v1 中,您可以使用
Post::save()
方法保存元数据。现在不再允许这样做。请使用saveMeta()
或createMeta()
方法(见下文)来保存帖子元数据。
您也可以从帖子中检索元数据。
// Get a custom meta value (like 'link' or whatever) from a post (any type) $post = Post::find(31); echo $post->meta->link; // OR echo $post->fields->link; echo $post->link; // OR
要为用户创建或更新元数据,只需使用 saveMeta()
或 saveField()
方法。它们返回 bool
,就像 Eloquent 的 save()
方法一样。
$post = Post::find(1); $post->saveMeta('username', 'jgrossi');
您也可以同时保存多个元数据。
$post = Post::find(1); $post->saveMeta([ 'username' => 'jgrossi', 'url' => 'http://jgrossi.com', ]);
您还有 createMeta()
和 createField()
方法,它们的工作方式与 saveX()
方法类似,但它们仅用于创建,并返回创建的 PostMeta
实例,而不是 bool
。
$post = Post::find(1); $postMeta = $post->createMeta('foo', 'bar'); // instance of PostMeta class $trueOrFalse = $post->saveMeta('foo', 'baz'); // boolean
通过自定义字段(元数据)查询帖子
有多种方法可以通过在 Post
(或使用 HasMetaFields
特性的其他模型)类上使用作用域来通过自定义字段(元数据)查询帖子。
要检查元键是否存在,请使用 hasMeta()
作用域。
// Finds a published post with a meta flag.
$post = Post::published()->hasMeta('featured_article')->first();
如果您想精确匹配元字段,可以使用带值的 hasMeta()
作用域。
// Find a published post which matches both meta_key and meta_value. $post = Post::published()->hasMeta('username', 'jgrossi')->first();
如果您需要匹配多个元字段,也可以使用带数组作为参数的 hasMeta()
作用域。
$post = Post::hasMeta(['username' => 'jgrossi'])->first(); $post = Post::hasMeta(['username' => 'jgrossi', 'url' => 'jgrossi.com'])->first(); // Or just passing the keys $post = Post::hasMeta(['username', 'url'])->first();
如果您需要匹配不区分大小写的字符串或使用通配符匹配,可以使用带值的 hasMetaLike()
作用域。这使用 SQL 的 LIKE
操作符,所以使用 "%" 作为通配符。
// Will match: 'J Grossi', 'J GROSSI', and 'j grossi'. $post = Post::published()->hasMetaLike('author', 'J GROSSI')->first(); // Using % as a wildcard will match: 'J Grossi', 'J GROSSI', 'j grossi', 'Junior Grossi' etc. $post = Post::published()->hasMetaLike('author', 'J%GROSSI')->first();
字段别名
Post
类支持“别名”,因此如果您检查 Post
类,您应该注意静态 $aliases
数组中定义的一些别名,例如 title
对应于 post_title
,而 content
对应于 post_content
。
$post = Post::find(1); $post->title === $post->post_title; // true
如果您正在扩展 Post
类以创建自己的类,您也可以使用 $aliases
。只需在您的类中添加新别名到静态属性中,它将自动继承父 Post
类中的所有别名。
class A extends \Corcel\Post { protected static $aliases = [ 'foo' => 'post_foo', ]; } $a = A::find(1); echo $a->foo; echo $a->title; // from Post class
自定义作用域
要排序帖子,您可以使用 newest()
和 oldest()
作用域,适用于 Post
和 User
类。
$newest = Post::newest()->first(); $oldest = Post::oldest()->first();
分页
要排序帖子,只需使用 Eloquent 的 paginate()
方法。
$posts = Post::published()->paginate(5); foreach ($posts as $post) { // ... }
要显示分页链接,只需调用 links()
方法。
{{ $posts->links() }}
高级自定义字段(ACF)
如果您想检索由 高级自定义字段(ACF) 插件创建的自定义字段,您必须安装 corcel/acf
插件 - 点击此处获取更多信息 - 并像这样调用自定义字段
$post = Post::find(123); echo $post->acf->some_radio_field; $repeaterFields = $post->acf->my_repeater_name;
为了避免不必要的SQL查询,只需设置你请求的字段类型。通常需要两个SQL查询来获取字段类型,因此如果你想指定它,你将跳过那些额外的查询。
$post = Post::find(123); echo $post->acf->text('text_field_name'); echo $post->acf->boolean('boolean_field_name');
自定义文章类型
你还可以处理自定义文章类型。你可以使用type(string)
方法或创建自己的类。
// using type() method $videos = Post::type('video')->status('publish')->get(); // using your own class class Video extends Corcel\Post { protected $postType = 'video'; } $videos = Video::status('publish')->get();
使用type()
方法将使Corcel返回所有对象为Corcel\Post
。使用你的自定义类,你可以自定义类,包括自定义方法和属性,例如将所有对象返回为Video
。
自定义文章类型和元数据
// Get 3 posts with custom post type (store) and show its address $stores = Post::type('store')->status('publish')->take(3)->get(); foreach ($stores as $store) { $storeAddress = $store->address; // option 1 $storeAddress = $store->meta->address; // option 2 $storeAddress = $store->fields->address; // option 3 }
配置返回实例
每次你调用类似Post::type('video')->first()
或Video::first()
的操作时,你都会收到一个Corcel\Model\Post
实例。
如果你选择为你的自定义文章类型创建一个新的类,你可以让这个类为该文章类型的所有实例返回。
注册文章类型(简单方法)
而不是为所有想要注册的自定义文章类型调用Post::registerPostType()
方法,只需使用Corcel的配置文件并映射所有自定义文章及其类。它们将自动为你注册。
'post_types' => [ 'video' => App\Video::class, 'foo' => App\Foo::class, ]
因此,每次你查询自定义文章类型时,都会返回映射的实例。
当你打算获取不同类型文章的集合时(例如,当获取在菜单中定义的文章时),这尤其有用。
注册文章类型(困难方法)
//all objects in the $videos Collection will be instances of Post $videos = Post::type('video')->status('publish')->get(); // register the video custom post type and its particular class Post::registerPostType('video', '\App\Video') //now all objects in the $videos Collection will be instances of Video $videos = Post::type('video')->status('publish')->get();
你也可以为内置类,如页面或文章,这样做。只需将页面或文章类与其相关的文章类型字符串相关联,并将返回该对象而不是默认对象。
短代码
从配置(Laravel)
你可以在config/corcel.php
文件中的'shortcodes'
键下映射你想要的所有短代码。在这种情况下,你应该创建自己的类,该类实现Corcel\Shortcode
接口,该接口需要render()
方法。
'shortcodes' => [ 'foo' => App\Shortcodes\FooShortcode::class, 'bar' => App\Shortcodes\BarShortcode::class, ],
这是一个示例短代码类
class FakeShortcode implements \Corcel\Shortcode { /** * @param ShortcodeInterface $shortcode * @return string */ public function render(ShortcodeInterface $shortcode) { return sprintf( 'html-for-shortcode-%s-%s', $shortcode->getName(), $shortcode->getParameter('one') ); } }
在运行时
你可以通过在Post
模型上调用addShortcode
方法来添加短代码。
// [gallery id="1"] Post::addShortcode('gallery', function ($shortcode) { return $shortcode->getName() . '.' . $shortcode->getParameter('id'); }); $post = Post::find(1); echo $post->content;
Laravel 5.5使用包自动发现,因此不需要手动添加ServiceProvider。
如果你使用Laravel,我们建议在App\Providers\AppServiceProvider
中的boot
方法中添加你的短代码处理器。
短代码解析
短代码使用thunderer/shortcode库进行解析。
提供了几个不同的解析器。RegularParser
是最技术上正确的,默认提供。这适用于大多数情况。然而,如果你在短代码解析中遇到一些不规则性,你可能需要配置Corcel使用WordpressParser
,它更忠实地匹配WordPress的短代码正则表达式。为此,如果你使用Laravel,编辑config/corcel.php
文件,取消注释你首选的解析器。或者,你可以用你自己的解析器替换它。
'shortcode_parser' => Thunder\Shortcode\Parser\RegularParser::class, // 'shortcode_parser' => Thunder\Shortcode\Parser\WordpressParser::class,
如果你不使用Laravel,你可以在运行时这样做,通过从任何使用Shortcodes
特质的类(如Post
)中调用setShortcodeParser()
方法。
$post->setShortcodeParser(new WordpressParser()); echo $post->content; // content parsed with "WordpressParser" class
有关短代码包的更多信息,请点击此处。
分类法
你可以获取特定文章的分类法,如下所示:
$post = Post::find(1); $taxonomy = $post->taxonomies()->first(); echo $taxonomy->taxonomy;
或者,你可以通过其分类法搜索文章
$post = Post::taxonomy('category', 'php')->first();
文章格式
您还可以获取帖子格式,例如WordPress函数 get_post_format()
echo $post->getFormat(); // should return something like 'video', etc
页面
页面类似于自定义帖子类型。您可以使用 Post::type('page')
或 Corcel\Model\Page
类。
use Corcel\Model\Page; // Find a page by slug $page = Page::slug('about')->first(); // OR $page = Post::type('page')->slug('about')->first(); echo $page->post_title;
分类和税别
获取一个分类或税别或从特定分类加载帖子。有多种方法可以实现。
// all categories $cat = Taxonomy::category()->slug('uncategorized')->posts->first(); echo "<pre>"; print_r($cat->name); echo "</pre>"; // only all categories and posts connected with it $cat = Taxonomy::where('taxonomy', 'category')->with('posts')->get(); $cat->each(function($category) { echo $category->name; }); // clean and simple all posts from a category $cat = Category::slug('uncategorized')->posts->first(); $cat->posts->each(function($post) { echo $post->post_title; });
附件和修订版
从 Post
或 Page
获取附件和/或修订版。
$page = Page::slug('about')->with('attachment')->first(); // get feature image from page or post print_r($page->attachment); $post = Post::slug('test')->with('revision')->first(); // get all revisions from a post or page print_r($post->revision);
缩略图
获取 Post
或 Page
的缩略图。
$post = Post::find(1); // Retrieve an instance of Corcel\Model\Meta\ThumbnailMeta. print_r($post->thumbnail); // For convenience you may also echo the thumbnail instance to get the URL of the original image. echo $post->thumbnail;
要检索特定缩略图大小,您可以在缩略图对象上调用 ->size()
方法,并传入缩略图大小字符串参数(例如 thumbnail
或 medium
)。如果缩略图已生成,此方法返回图像元数据数组,否则将返回作为回退的原始图像URL。
if ($post->thumbnail !== null) { /** * [ * 'file' => 'filename-300x300.jpg', * 'width' => 300, * 'height' => 300, * 'mime-type' => 'image/jpeg', * 'url' => 'http://localhost/wp-content/uploads/filename-300x300.jpg', * ] */ print_r($post->thumbnail->size(Corcel\Model\Meta\ThumbnailMeta::SIZE_THUMBNAIL)); // http://localhost/wp-content/uploads/filename.jpg print_r($post->thumbnail->size('invalid_size')); }
选项
在Corcel的先前版本中,此类称为
Options
而不是Option
(单数)。因此,从v2.0.0
开始,请始终使用单数形式使用此类。
在Corcel 2+中删除了
Option::getAll()
方法,改为使用Option::asArray($keys [])
。
您可以使用 Option
类从 wp_options
表获取数据。
$siteUrl = Option::get('siteurl');
您还可以添加新选项
Option::add('foo', 'bar'); // stored as string Option::add('baz', ['one' => 'two']); // this will be serialized and saved
您可以将所有选项作为简单的数组获取
$options = Option::asArray(); echo $options['siteurl'];
或者,您还可以指定仅要获取的键
$options = Option::asArray(['siteurl', 'home', 'blogname']); echo $options['home'];
菜单
要按其别名获取菜单,请使用以下语法。菜单项将在 items
变量中加载(它是一个 Corcel\Model\MenuItem
对象的集合)。
当前支持的菜单项有:页面、帖子、自定义链接和分类。
一旦您有了 MenuItem
类的实例,如果您想使用原始实例(如原始页面或术语,例如),只需调用 MenuItem::instance()
方法。MenuItem
对象只是一个 post_type
等于 nav_menu_item
的帖子。
$menu = Menu::slug('primary')->first(); foreach ($menu->items as $item) { echo $item->instance()->title; // if it's a Post echo $item->instance()->name; // if it's a Term echo $item->instance()->link_text; // if it's a custom link }
instance()
方法将返回匹配的对象
Post
实例为post
菜单项;Page
实例为page
菜单项;CustomLink
实例为custom
菜单项;Term
实例为category
菜单项。
多级菜单
要处理多级菜单,遍历所有菜单项以将它们放在正确的级别上,例如。
您可以使用 MenuItem::parent()
方法检索该菜单项的父实例
$items = Menu::slug('foo')->first()->items; $parent = $items->first()->parent(); // Post, Page, CustomLink or Term (category)
要按父项分组菜单项,您可以在 $menu->items
集合中使用 ->groupBy()
方法,按 $item->parent()->ID
对菜单项进行分组。
有关 groupBy()
方法的更多信息,请参阅 Laravel 文档。
用户
您可以以与处理帖子相同的方式操作用户
// All users $users = User::get(); // A specific user $user = User::find(1); echo $user->user_login;
认证
使用Laravel
如果您正在使用Laravel 5.4或更早版本,请确保您已注册了 CorcelServiceProvider
提供程序。
然后,在 config/auth.php
中定义用户提供程序,以允许Laravel使用WordPress用户进行登录
'providers' => [ 'users' => [ 'driver' => 'corcel', 'model' => Corcel\Model\User::class, ], ],
现在您可以使用 Auth
门面来认证用户
Auth::validate([ 'email' => 'admin@example.com', // or using 'username' too 'password' => 'secret', ]);
为了使Laravel的密码重置功能与Corcel兼容,我们需要覆盖数据库中密码的存储方式。为此,您必须修改Auth/PasswordController.php
文件,将其从
use App\Http\Controllers\Controller; use Illuminate\Foundation\Auth\ResetsPasswords; class PasswordController extends Controller { use ResetsPasswords;
修改为
use App\Http\Controllers\Controller; use Illuminate\Foundation\Auth\ResetsPasswords; use Corcel\Laravel\Auth\ResetsPasswords as CorcelResetsPasswords; class PasswordController extends Controller { use ResetsPasswords, CorcelResetsPasswords { CorcelResetsPasswords::resetPassword insteadof ResetsPasswords; }
不使用Laravel
您可以使用AuthUserProvider
类手动验证用户。
$userProvider = new Corcel\Laravel\Auth\AuthUserProvider; $user = $userProvider->retrieveByCredentials(['username' => 'admin']); if(!is_null($user) && $userProvider->validateCredentials($user, ['password' => 'admin'])) { // successfully login }
请记住,您可以使用
username
和
运行测试
要运行phpunit测试,执行以下命令
./vendor/bin/phpunit
如果您已安装全局phpunit
命令,只需键入
phpunit
所有测试均使用Sqlite数据库的:memory
数据库编写,因此它在您的内存中运行。所有测试都使用factories
和migrations
。有关更多信息,请查看tests/database/factories
和tests/database/migrations
目录。
贡献
欢迎所有贡献帮助改进Corcel。
在您提交Pull Request (PR)之前,请考虑以下指南
-
在GitHub上Fork https://github.com/corcel/corcel;
-
在本地克隆您的Forked仓库(不是Corcel的)并创建自己的分支,基于您想要修复的版本(例如
2.1
、2.2
、2.3
、2.4
或2.5
):git checkout -b my-fix-branch 2.5
; -
进行所有代码更改。请记住,在此处为任何添加的功能或任何未测试的bugfix编写至少一个测试用例。我们的目标是让100%的代码由测试覆盖,因此请帮助我们编写更好的代码;-) 如果您没有测试经验,这是一个学习的好机会。只需查看我们的测试用例,您会发现它们多么简单。
-
在本地运行单元测试以确保您的更改没有破坏其他代码片段;
-
将您的分支推送到您的Forked仓库,通常
git push origin HEAD
应该可以工作; -
在GitHub上再次创建一个从您的自定义
my-fix-branch
分支(从您的Forked仓库)到相关分支的Pull Request (PR)(例如,corcel:2.5
,而不是corcel:master
,请); -
等待批准 :-)
许可证
MIT License © Junior Grossi