Artisan 在全局命名空间中看不到 WP_Query
Artisan Cant See WP_Query in Global Namespace
我正在 Laravel 中构建一个应用程序。该项目的一部分是一个前置网站,我公司的营销团队希望能够通过 WordPress 对其进行管理。为了允许他们这样做,并且为了轻松访问该数据,我将 WordPress 引导到 Laravel 以访问 WordPress classes 和功能。
WordPress 在 /public/index.php
中启动
<?php
/**
* Laravel - A PHP Framework For Web Artisans
*
* @package Laravel
* @author Taylor Otwell <taylorotwell@gmail.com>
*/
/*
|--------------------------------------------------------------------------
| Bootstrap Wordpress Inside Of Laravel
|--------------------------------------------------------------------------
|
| Brings in the wordpress functions for use inside of your laravel classes
| like your controllers and service providers. This makes true coupling
| inside of laravel possible.
|
*/
define('WP_USE_THEMES', false);
require __DIR__.'/hunchentoot/wp-blog-header.php';
/*
|--------------------------------------------------------------------------
| Register The Auto Loader
|--------------------------------------------------------------------------
|
| Composer provides a convenient, automatically generated class loader for
| our application. We just need to utilize it! We'll simply require it
| into the script here so that we don't have to worry about manual
| loading any of our classes later on. It feels nice to relax.
|
*/
require __DIR__.'/../bootstrap/autoload.php';
/*
|--------------------------------------------------------------------------
| Turn On The Lights
|--------------------------------------------------------------------------
|
| We need to illuminate PHP development, so let us turn on the lights.
| This bootstraps the framework and gets it ready for use, then it
| will load up this application so that we can run it and send
| the responses back to the browser and delight our users.
|
*/
$app = require_once __DIR__.'/../bootstrap/app.php';
/*
|--------------------------------------------------------------------------
| Run The Application
|--------------------------------------------------------------------------
|
| Once we have the application, we can handle the incoming request
| through the kernel, and send the associated response back to
| the client's browser allowing them to enjoy the creative
| and wonderful application we have prepared for them.
|
*/
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
$response = $kernel->handle(
$request = Illuminate\Http\Request::capture()
);
$response->send();
$kernel->terminate($request, $response);
不幸的是,Artisan 在服务提供商内部使用时无法看到这些 类。
有问题的服务提供商
<?php
namespace App\Providers;
use App\WPQuery\FooterLogosQuery;
use App\Formaters\FooterLogosFormater;
use Illuminate\Support\ServiceProvider;
class FooterLogosProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* @return void
*/
public function boot(FooterLogosQuery $footerLogosQuery, FooterLogosFormater $footerLogosFormater)
{
$logosQuery = $footerLogosQuery->createQuery();
$queriedLogos = $footerLogosQuery->get_posts();
$logos = $footerLogosFormater->formatFooterLogos($queriedLogos);
view()->share('footerLogos', $logos);
}
/**
* Register the application services.
*
* @return void
*/
public function register()
{
//
}
}
再次为了保持理智,我将 WP_Query class 提取到 Laravel 内部的可注射 classes 中,下面是服务提供商。
提供者"Query"
<?php
namespace App\WPQuery;
class FooterLogosQuery extends \WP_Query
{
/**
* Container for the arguements for the query
*
* @var Array
*/
protected $args;
/**
* Container for the query order
*
* @var String
*/
public $order;
/**
* Container for the query post total
*
* @var Integer
*/
public $totalPosts;
/**
* Constructs the object and sets the default args
*
* @return void
*/
public function __construct()
{
$this->order = 'ASC';
$this->totalPosts = 6;
$this->setArgs();
}
/**
* Sets the order for the query if called
*
* @param String $order Container for the query order
*/
public function setOrder($order)
{
$this->order = $order;
$this->setArgs();
}
/**
* Sets the total for the query if called
*
* @param Integer $total Container for the query post total
*/
public function setTotalPosts($total)
{
$this->totalPosts = $total;
$this->setArgs();
}
/**
* (Re)Sets the arguements for the query upon call
*
* @return void
*/
public function setArgs()
{
$this->args = [
'post_type' => 'footer_logos',
'posts_per_page' => $this->totalPosts,
'order' => $this->order,
];
}
/**
* Creates the query for manipulation inside of controller
*
* @return Object This is a WordPress Query Object
*/
public function createQuery()
{
parent::__construct($this->args);
}
/**
* Resets the query once the objects use is complete
*
* @return void
*/
public function __destruct()
{
wp_reset_query();
}
}
它们中的每一个都有一个数据格式化程序 class 这样它就可以在控制器和视图之间干净地传递。
"Query" 上述 class
的格式化程序
<?php
namespace App\Formaters;
class FooterLogosFormater {
/**
* Create a new formater instance.
*
* @return void
*/
public function __construct()
{
}
/**
* Formats the information from the wordpress object
*
* @param Object $queryObject This is the raw Query Object
* @return Array Returns useable data to controller
*/
public function formatFooterLogos($queryObject)
{
$logos = [];
foreach($queryObject as $key => $logo)
{
$logoId = get_post_meta($logo->ID, 'footer_logo', true);
$logos[$key] = [
'logo_link' => get_post_meta($logo->ID, 'footer_logo_link', true),
'logo_image' => wp_get_attachment_url($logoId),
];
}
return $logos;
}
}
我的这一切都运行良好,至少对于应用程序的前端而言。 Artisan 讨厌这一切,我不知道该怎么办。有没有把全局名称space暴露给artisan?还是我只是 SOL?
如有任何帮助,我们将不胜感激。
谢谢,
罗伯特
虽然这不是一个理想的答案,但我确实找到了解决方法。
新服务提供商
<?php
namespace App\Providers;
use App\WPQuery\FooterLogosQuery;
use App\Formaters\FooterLogosFormater;
use Illuminate\Support\ServiceProvider;
class FooterLogosProvider extends ServiceProvider
{
/**
* Loads the data for this service provider
*
* @return Array returns array of usable data
*/
public function loadData()
{
$footerLogosQuery = new FooterLogosQuery();
$footerLogosFormater = new FooterLogosFormater();
$logosQuery = $footerLogosQuery->createQuery();
$queriedLogos = $footerLogosQuery->get_posts();
$logos = $footerLogosFormater->formatFooterLogos($queriedLogos);
// Delets Objects From Memory
unset($footerLogosQuery, $footerLogosFormater);
return $logos;
}
/**
* Bootstrap the application services.
*
* @return void
*/
public function boot()
{
$logos = [];
// Stops false flag from being thrown in artisan
if (!$this->app->runningInConsole())
{
$logos = $this->loadData();
}
view()->share('footerLogos', $logos);
}
/**
* Register the application services.
*
* @return void
*/
public function register()
{
//
}
}
我没有使用依赖注入,而是手动实例化了对象的新实例以在辅助函数内部使用,然后限制该函数执行以在 CLI 上使用时使用。
我正在 Laravel 中构建一个应用程序。该项目的一部分是一个前置网站,我公司的营销团队希望能够通过 WordPress 对其进行管理。为了允许他们这样做,并且为了轻松访问该数据,我将 WordPress 引导到 Laravel 以访问 WordPress classes 和功能。
WordPress 在 /public/index.php
中启动<?php
/**
* Laravel - A PHP Framework For Web Artisans
*
* @package Laravel
* @author Taylor Otwell <taylorotwell@gmail.com>
*/
/*
|--------------------------------------------------------------------------
| Bootstrap Wordpress Inside Of Laravel
|--------------------------------------------------------------------------
|
| Brings in the wordpress functions for use inside of your laravel classes
| like your controllers and service providers. This makes true coupling
| inside of laravel possible.
|
*/
define('WP_USE_THEMES', false);
require __DIR__.'/hunchentoot/wp-blog-header.php';
/*
|--------------------------------------------------------------------------
| Register The Auto Loader
|--------------------------------------------------------------------------
|
| Composer provides a convenient, automatically generated class loader for
| our application. We just need to utilize it! We'll simply require it
| into the script here so that we don't have to worry about manual
| loading any of our classes later on. It feels nice to relax.
|
*/
require __DIR__.'/../bootstrap/autoload.php';
/*
|--------------------------------------------------------------------------
| Turn On The Lights
|--------------------------------------------------------------------------
|
| We need to illuminate PHP development, so let us turn on the lights.
| This bootstraps the framework and gets it ready for use, then it
| will load up this application so that we can run it and send
| the responses back to the browser and delight our users.
|
*/
$app = require_once __DIR__.'/../bootstrap/app.php';
/*
|--------------------------------------------------------------------------
| Run The Application
|--------------------------------------------------------------------------
|
| Once we have the application, we can handle the incoming request
| through the kernel, and send the associated response back to
| the client's browser allowing them to enjoy the creative
| and wonderful application we have prepared for them.
|
*/
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
$response = $kernel->handle(
$request = Illuminate\Http\Request::capture()
);
$response->send();
$kernel->terminate($request, $response);
不幸的是,Artisan 在服务提供商内部使用时无法看到这些 类。
有问题的服务提供商
<?php
namespace App\Providers;
use App\WPQuery\FooterLogosQuery;
use App\Formaters\FooterLogosFormater;
use Illuminate\Support\ServiceProvider;
class FooterLogosProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* @return void
*/
public function boot(FooterLogosQuery $footerLogosQuery, FooterLogosFormater $footerLogosFormater)
{
$logosQuery = $footerLogosQuery->createQuery();
$queriedLogos = $footerLogosQuery->get_posts();
$logos = $footerLogosFormater->formatFooterLogos($queriedLogos);
view()->share('footerLogos', $logos);
}
/**
* Register the application services.
*
* @return void
*/
public function register()
{
//
}
}
再次为了保持理智,我将 WP_Query class 提取到 Laravel 内部的可注射 classes 中,下面是服务提供商。
提供者"Query"
<?php
namespace App\WPQuery;
class FooterLogosQuery extends \WP_Query
{
/**
* Container for the arguements for the query
*
* @var Array
*/
protected $args;
/**
* Container for the query order
*
* @var String
*/
public $order;
/**
* Container for the query post total
*
* @var Integer
*/
public $totalPosts;
/**
* Constructs the object and sets the default args
*
* @return void
*/
public function __construct()
{
$this->order = 'ASC';
$this->totalPosts = 6;
$this->setArgs();
}
/**
* Sets the order for the query if called
*
* @param String $order Container for the query order
*/
public function setOrder($order)
{
$this->order = $order;
$this->setArgs();
}
/**
* Sets the total for the query if called
*
* @param Integer $total Container for the query post total
*/
public function setTotalPosts($total)
{
$this->totalPosts = $total;
$this->setArgs();
}
/**
* (Re)Sets the arguements for the query upon call
*
* @return void
*/
public function setArgs()
{
$this->args = [
'post_type' => 'footer_logos',
'posts_per_page' => $this->totalPosts,
'order' => $this->order,
];
}
/**
* Creates the query for manipulation inside of controller
*
* @return Object This is a WordPress Query Object
*/
public function createQuery()
{
parent::__construct($this->args);
}
/**
* Resets the query once the objects use is complete
*
* @return void
*/
public function __destruct()
{
wp_reset_query();
}
}
它们中的每一个都有一个数据格式化程序 class 这样它就可以在控制器和视图之间干净地传递。
"Query" 上述 class
的格式化程序<?php
namespace App\Formaters;
class FooterLogosFormater {
/**
* Create a new formater instance.
*
* @return void
*/
public function __construct()
{
}
/**
* Formats the information from the wordpress object
*
* @param Object $queryObject This is the raw Query Object
* @return Array Returns useable data to controller
*/
public function formatFooterLogos($queryObject)
{
$logos = [];
foreach($queryObject as $key => $logo)
{
$logoId = get_post_meta($logo->ID, 'footer_logo', true);
$logos[$key] = [
'logo_link' => get_post_meta($logo->ID, 'footer_logo_link', true),
'logo_image' => wp_get_attachment_url($logoId),
];
}
return $logos;
}
}
我的这一切都运行良好,至少对于应用程序的前端而言。 Artisan 讨厌这一切,我不知道该怎么办。有没有把全局名称space暴露给artisan?还是我只是 SOL?
如有任何帮助,我们将不胜感激。
谢谢, 罗伯特
虽然这不是一个理想的答案,但我确实找到了解决方法。
新服务提供商
<?php
namespace App\Providers;
use App\WPQuery\FooterLogosQuery;
use App\Formaters\FooterLogosFormater;
use Illuminate\Support\ServiceProvider;
class FooterLogosProvider extends ServiceProvider
{
/**
* Loads the data for this service provider
*
* @return Array returns array of usable data
*/
public function loadData()
{
$footerLogosQuery = new FooterLogosQuery();
$footerLogosFormater = new FooterLogosFormater();
$logosQuery = $footerLogosQuery->createQuery();
$queriedLogos = $footerLogosQuery->get_posts();
$logos = $footerLogosFormater->formatFooterLogos($queriedLogos);
// Delets Objects From Memory
unset($footerLogosQuery, $footerLogosFormater);
return $logos;
}
/**
* Bootstrap the application services.
*
* @return void
*/
public function boot()
{
$logos = [];
// Stops false flag from being thrown in artisan
if (!$this->app->runningInConsole())
{
$logos = $this->loadData();
}
view()->share('footerLogos', $logos);
}
/**
* Register the application services.
*
* @return void
*/
public function register()
{
//
}
}
我没有使用依赖注入,而是手动实例化了对象的新实例以在辅助函数内部使用,然后限制该函数执行以在 CLI 上使用时使用。