A WordPress plugin and theme framework.
Read the full Radiate framework documentation.
composer require radiate/framework
A WordPress plugin and theme framework
Home Page: https://radiate-framework.github.io/
License: MIT License
A WordPress plugin and theme framework.
Read the full Radiate framework documentation.
composer require radiate/framework
Is your feature request related to a problem? Please describe.
Determining if a user has capabilities involves using the WordPress user_can
method.
Describe the solution you'd like
A Gate
or Policy
implementation like Laravel to create and check user capabilities.
Describe alternatives you've considered
user_can
, current_user_can
Additional context
https://wordpress.stackexchange.com/questions/345902/want-to-know-parameters-that-can-be-passed-to-user-can-for-access-control-by-u on mapping new capabilities
Is your feature request related to a problem? Please describe.
Getting multiple values from the cache involves lots of copy pasta.
Describe the solution you'd like
Methods to get/set multiple cache values Cache::many()
etc.
Describe alternatives you've considered
Loops are a bit ugly.
Additional context
Laravel has (poorly documented) multiple methods to handle many cache keys. many
, putMany
The ability to add a prefix to cache keys would also be cool:
Cache::prefix('users')->putMany([
'ben' => User::find(1), // users.ben
'jerry' => User::find(2), // users.jerry
]);
$ben = Cache::get('users.ben');
$jerry = Cache::prefix('users')->get('jerry');
Is your feature request related to a problem? Please describe.
When activating/deactivating a plugin, it would be great to set/delete multiple global options.
Describe the solution you'd like
Additional methods on the Option
facade to add and delete (and maybe get?) options.
Option::addMany([
'option_1' => 1,
'option_2' => 2,
]);
Option::deleteMany(['option_1', 'option_2']);
[$option_1, $option_2] = Option::getMany(['option_1', 'option_2']);
Describe alternatives you've considered
Manually looping over options.
Is your feature request related to a problem? Please describe.
I can't statically call the request object
Describe the solution you'd like
Additional facades for Request and any other bindings in the container
Additional context
Currently App, Arr, Event, Route, Str, View... Can add Auth, File, Request as these exist within the current framework
Add a boolean
method to the Request
class to determine if a value such as "remember me" is true or false.
Is your feature request related to a problem? Please describe.
I can't call other commands from a command
Describe the solution you'd like
I'd like a way to call other commands so I do things like generate a bunch of countrollers in one go
Describe alternatives you've considered
Manually calling each command
Additional context
WP_CLI::runcommand()
will allow this - a nice way to pass along arguments and handle errors will be needed.
Describe the bug
The event dispatch
method requires a second parameter to be passed.
To Reproduce
Steps to reproduce the behavior:
Expected behavior
The event to dispatch regardless of the presence of the second variable
Screenshots
Event::dispatch('wp_loaded');
Additional context
Unlike do_action
, apply_filters
requires this to be set. Setting the second value to null is a workaround.
Describe the bug
Auth:attempt()
method has "username" hardcoded. This could potentially come from the User model instead.
Is your feature request related to a problem? Please describe.
Auth login only accepts credentials
Describe the solution you'd like
The ability to login a user by the WP_User instance
Describe alternatives you've considered
extracting the credentials from the user but the password is already hashed so not possible
Additional context
<?php
use Radiate\Support\Facades\Auth;
use WP_User as User;
Auth::login(new User(1));
Describe the bug
The model has a __create
method. This looks to be a legacy/mistake method.
Additional context
The create
method is present on the query builder so it shouldn't be required on the model.
Describe the solution you'd like
Generate shortcodes make:shortcode
Is your feature request related to a problem? Please describe.
Restricted to what parameters are passed to controllers
Describe the solution you'd like
Add dependency injection to container
Additional context
Illuminate\Container is light on dependencies and should swap in quite easily
Is your feature request related to a problem? Please describe.
The WordPress pagination is limited and tricky to use consistently.
Describe the solution you'd like
A Laravel-esque paginator with useful methods and iterable for simple looping in a template file.
Describe alternatives you've considered
Using the WordPress pagination or manually outputting the pagination links.
Additional context
https://laravel.com/docs/8.x/pagination#introduction
Describe the bug
When running make:resource
command, the stub generated has the Request
object passed as the only method parameter. In reality, the JsonResource
doesn't actually get the request passed, so the method signature doesn't match the parent class.
To Reproduce
Steps to reproduce the behavior:
wp radiate make:resource TestResource
$request
parameterExpected behavior
The dumped $request
parameter to output a Radiate\Http\Request
instance
Additional context
The JsonResource::toArray
method doesn't get passed the Request
. It should in order to replicate the same functionality of Laravel, or the stub shouldn't include the parameter if the resource is deemed to not require it.
IMO the resource should get an instance of the request, or even have all dependencies resolved from the container. This would give great flexibility when building the resource.
Is your feature request related to a problem? Please describe.
Creating a REST route to return posts - the posts are returned as WP_Post
instances, which when encoded as JSON are ugly and full of superfluous data, increasing the response size.
Describe the solution you'd like
It would be nice to have a transformer like laravel's JsonResource
class to easily convert WP_Query
results into a tidy API response. It would also be simple to create API resources with the cli make:resource
. The resource class would have attribute accessors so you can write $post->title
instead of $post->post_title
. This would open up scope to apply filters to API responses in an OOP manner.
Define a resource:
class PostResource extends JsonResource
{
public function toArray()
{
return [
'id' => $this->ID,
'title' => $this->title,
'description' => $this->content,
'slug' => $this->slug,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
];
}
}
This would be used in a controller like so:
public function index()
{
$query = WP_Query(['post_type' => 'post']);
return PostResource::collection($query->posts);
}
This would also be usable in a non-api context, pretty much wherever WP_Query
might be used.
Describe alternatives you've considered
Manually looping through WP_Query
responses and passing them into a class. This pattern is highly repeatable and would be better suited in the framework to simplify dev.
Additional context
Until the framework has Eloquent or a similar, nice API for querying the database, specifically the posts table, using WP_Query is the most efficient way to retrieve data. Currently there is no way to change the underlying class used (WP_Post
) meaning accessing properties is ugly, and processing for an API response a hefty manual task.
Is your feature request related to a problem? Please describe.
Cpt is too abstract
Describe the solution you'd like
PostType is more declarative so easier for beginners to understand the link between wp and radiate
Describe alternatives you've considered
CustomPostType is too verbose, Type too generic
Additional context
Should taxonomies be in the post type directory?
Perhaps
.
Is your feature request related to a problem? Please describe.
The HasMeta
trait allows for the object meta to be fetched. Nice enough. But it would be cool if you could update/delete the meta data too.
Describe the solution you'd like
A method or getter/setter to update and delete the meta data attached to the particular post. E.g.
// new method to update multiple attributes
User::find(1)->meta->update([
'first_name' => 'changed',
]);
$meta = User::find(1)->meta;
$meta->first_name = 'changed'; // this already works, but doesn't persist in the db
$meta->save(); // new method to persist the entire Meta object
// new method to delete a single property
Post::find(1)->meta->delete('meta_description');
Describe alternatives you've considered
Using update_metadata
and delete_metadata
Additional context
The Meta
model already exists, additional methods would need to be added to use update_metadata
and delete_metadata
under the hood.
Is your feature request related to a problem? Please describe.
There's no easy way to reference API routes other than their URL which may not be simple to remember.
Describe the solution you'd like
Named routes and the ability to get the URL with the name.
Route::get('posts/{id}/categories', CategoryController::class)->name('post.categories');
echo route('post.categories', ['id' => 1234]); // https://example.com/wp-json/api/posts/1234/categories
Describe alternatives you've considered
Trying to remember API routes, and having to interpolate/concatenate URL parameters. hard-coding endpoints.
Additional context
Routes are stored in the Router
, it should be possible to assign names to each route, and then look these up from the router. There will also need to be a way to "build" a URL from the route and the given URL parameters.
Is your feature request related to a problem? Please describe.
generating/publishing multiple controllers for lost password, login, register etc takes time
Describe the solution you'd like
vendor:publish --tag=auth
would speed this up
Describe alternatives you've considered
make:auth
command but that isn't as descriptive of it's function and would re-implement vendor:publish
Additional context
It's a niche case to want generate as wp already has auth covered however, it would be nice for implementing custom login pages or an API signup
Is your feature request related to a problem? Please describe.
The AuthManager::user
method only returns a WP_User
. I want to return a custom class instead.
Describe the solution you'd like
Config to set the type of model returned by the AuthManager
like how Laravel works.
Additional context
Laravel let's you choose what model to return from the auth facade so the framework should have the option as the WP_User
model isn't great.
Is your feature request related to a problem? Please describe.
WordPress has many URL functions such as home_url
, rest_url
, wp_login_url
.
Describe the solution you'd like
It would be nice to have these accessible from a facade: Url::login()
. Bringing these functions under one class would make it easier to remember the functions. It could also be used in future to get named ajax and rest route URLs.
Describe alternatives you've considered
WordPress helper functions scattered through the code base
Additional context
Laravel has a Routing\UrlGenerator
class and facade. The class methods would be simple wrappers around core WordPress functions.
<?php
namespace Radiate\Routing;
use Radiate\Http\Request;
class UrlGenerator
{
/**
* The request instance
*
* @var \Radiate\Http\Request
*/
protected $request;
/**
* Assign the request object to the instance.
*
* @return void
*/
public function __construct(Request $request)
{
$this->request = $request;
}
/**
* Get the current URL without query parameters.
*
* @return string
*/
public function current(): string
{
return $this->request->url();
}
/**
* Get the current URL including query parameters.
*
* @return string
*/
public function full(): string
{
return $this->request->fullUrl();
}
/**
* Get the URL for the previous request.
*
* @param string|null $fallback The fallback URL
* @return string
*/
public function previous(?string $fallback = null): string
{
if ($previous = wp_get_referer()) {
return $previous;
}
if ($fallback) {
return $fallback;
}
return $this->home();
}
/**
* Return the registration URL
*
* @param string $redirect The Redirect URL
* @return string
*/
public function register(string $redirect = ''): string
{
if ($redirect) {
return add_query_arg('redirect_to', urlencode($redirect), wp_registration_url());
}
return wp_registration_url();
}
/**
* Return the login URL
*
* @param string $redirect The redirect URL
* @return string
*/
public function login(string $redirect = '/'): string
{
return wp_login_url($redirect);
}
/**
* Return the logout URL
*
* @param string $redirect The redirect URL
* @return string
*/
public function logout(string $redirect = '/'): string
{
return wp_logout_url($redirect);
}
/**
* Return the home URL
*
* @param string $path The path to append to the home URL
* @return string
*/
public function home(string $path = ''): string
{
return home_url($path);
}
/**
* Return the URL to the path specified
*
* @param string $path The path to append to the home URL
* @return string
*/
public function to(string $path): string
{
return $this->home($path);
}
/**
* Redirect to another page, with an optional status code
*
* @param string $url The URL to redirect to
* @param integer $status The status code to send
* @return void
*/
public function redirect(string $url, int $status = 302): void
{
die(wp_redirect($url, $status));
}
/**
* Return the admin URL
*
* @param string $path The path to append to the admin URL
* @return string
*/
public function admin(string $path = ''): string
{
return admin_url($path);
}
/**
* Return the ajax URL
*
* @param string $action The ajax action
* @return string
*/
public function ajax(string $action = ''): string
{
return $this->admin('admin-ajax.php' . ($action ? '?action=' . $action : ''));
}
/**
* Return the REST URL
*
* @param string $path The path to append to the admin URL
* @return string
*/
public function rest(string $path = ''): string
{
return rest_url($path);
}
/**
* Determine if the given path is a valid URL.
*
* @param string $path
* @return bool
*/
public function isValidUrl(string $path): bool
{
if (!preg_match('~^(#|//|https?://|(mailto|tel|sms):)~', $path)) {
return filter_var($path, FILTER_VALIDATE_URL) !== false;
}
return true;
}
}
Describe the bug
Using a Route::resource()
method doesn't return a Route
so there is no middleware
method available.
Is your feature request related to a problem? Please describe.
The ability to simply create scheduled tasks.
Describe the solution you'd like
A CRON-like scheduler to wrap wp_schedule_event
.
Describe alternatives you've considered
Native WP functions, custom CRON tasks
Additional context
wp_schedule_single_event
instead of the repeated schedule, so no need to filter schedule "intervals"hourly
, weekly
etc. https://github.com/laravel/framework/blob/8.x/src/Illuminate/Console/Scheduling/ManagesFrequencies.phpDescribe the bug
The collection
method only accepts an array
To Reproduce
Steps to reproduce the behavior:
Collection
Expected behavior
A collection should be able to be passed to the collection method
Additional context
https://laravel.com/docs/8.x/eloquent-resources#resource-collections
Describe the solution you'd like
Models such as a Post
or User
model that can be extended for CPTs and such. A Model
class would provide an expressive interface for interacting with the WordPress tables rather than using the fragmented and inconsistent APIs provided by core.
For example:
// current way
$post = get_post(1);
echo $post->post_title; // title
echo get_permalink($post->ID); // permalink
echo get_the_post_thumbnail_url($post->ID, 'post-thumbnail'); // featured image
// new way
$post = new Post(1);
echo $post->title; // title
echo $post->permalink; // permalink
echo $post->featuredImage('post-thumbnail'); // featured image
WP_User
, WP_Term
, WP_Post
could all be expanded on in some way to reduce the need for global helper functions. A better naming convention could also be utilized ($post->post_name
doesn't adequately describe "slug" for instance). Following from Laravel's Model
class, accessors, mutators, casts and more could be utilized for simple development.
Describe alternatives you've considered
Using the WP APIs has some cognitive load to remember the names of functions, the accepted parameters (WP functions quite often accept multiple types for one parameter), the error handling and other quirks such as using global $post
or requiring an ID to be passed. It is possible (obviously) to use the core functions but a Model
class would be nicer to write.
Additional context
Custom tables could also possibly also extend the Model
class. It may be required to have a base class and then WP "models" extending this so the underlying model is table-agnostic.
A DB query builder would be able to return results with the correct models, simplifying queries, result manipulation etc. For the sake of keeping the feature request a manageable size, I suggest building out the Model
first - WP_Query
can be piped through a transformer to hydrate the models in order to use the underlying models, and the a query builder can be implemented at a later date.
Extend WP_REST_Request
and WP_REST_Response
to improve integration with WP core
Describe the bug
The Radiate\Http\Client\Response::collect
method accepts a $key
but the json
method does not. One method is incorrect.
To Reproduce
Steps to reproduce the behaviour:
Radiate\Http\Client\Response
class methods.Expected behaviour
Either the collect
method doesn't have a $key
parameter, or the json
method does have a $key
parameter.
Describe the bug
Calling Auth::attempt()
results in aCall to undefined method Radiate\Auth\RadiateUserProvider::newUserInstance()
error.
To Reproduce
Steps to reproduce the behavior:
Auth::attempt()
with some credentials.Expected behavior
Either the attempt to return true for success, or false if the credentials are incorrect.
Additional context
The newUserInstance
method doesn't exist either on the provider, or the model.
Is your feature request related to a problem? Please describe.
The framework is heavily influenced by Laravel but doesn't use any Illuminate\Contracts
Describe the solution you'd like
Where implementations allow, use the available contracts. This will make it easier to extend/use custom services. An example would be using the UserProvider
interface for the WordPress/RadiateUserProvider classes.
Describe alternatives you've considered
¯_(ツ)_/¯
Additional context
There are other components of the framework that could implement contracts to make them easily swappable.
Is your feature request related to a problem? Please describe.
Currently I can only access the $request
and $id
parameter from the controller methods.
Describe the solution you'd like
I'd like the controller methods to be resolved from the container so I can type hint my dependencies.
Describe alternatives you've considered
Getting dependencies from within the controller using the facades but it would be neater to inject automatically.
Additional context
REST uri params should be type hinted by their name e.g.
// require params
Route::get('/create-file', function(Filesystem $files) {
//
});
// require params
Route::get('/user/{user_id}/create', function(int $user_id) {
//
});
// and optional params
Route::get('/user/{name?}', function(string $name = 'no name') {
//
});
Is your feature request related to a problem? Please describe.
Currently, the framework only throws HTTPResponseException
.
Describe the solution you'd like
It would be useful to throw Auth, PageNotFound, etc exceptions to cater for more use cases
Describe alternatives you've considered
Catching exceptions and checking the status codes
Additional context
Improvements to the exception handler would improve API responses
Describe the bug
Facades are missing doc-blocks
Describe the bug
the Request
class has no url
method.
To Reproduce
Steps to reproduce the behavior:
var_dump(Request::url());
Expected behavior
The Request
class to return the current URL.
Additional context
Bug discovered from UrlGenerator::current()
which calls the url
method on the underlying Request
class.
Is your feature request related to a problem? Please describe.
Using wp_remote_request
is clunky.
Describe the solution you'd like
A fluent way of making HTTP requests like Laravel's wrapper around Guzzle HTTP
Describe alternatives you've considered
Using wp_remote_request
or cURL
Additional context
Laravel's HTTP client is a wrapper around Guzzle HTTP library.
Is your feature request related to a problem? Please describe.
I want to authenticate with a JWT instead of the normal auth login
Describe the solution you'd like
A way to switch guards such as session/token
Describe alternatives you've considered
Custom middleware
Additional context
See Laravel
Is your feature request related to a problem? Please describe.
It's not easy to remember the functions to get the privacy and blog page links.
Describe the solution you'd like
Methods added to the UrlGenerator
class to make acessing these links simple. E.g. url()->privacyPolicy()
, url()->postsPage()
.
There are other links that could be added, such as archives, tag, category pages.
Describe alternatives you've considered
Using the built in functions get_post_type_archive_link
, get_privacy_policy_url
.
Additional context
The built in functions are difficult to remember and not always consistent. Adding the "special" pages to the UrlGenerator
class will solve these issues.
Describe the bug
Event listeners constructor method is not resolved from the container.
To Reproduce
Steps to reproduce the behavior:
Expected behavior
Dependencies to be resolved from the container.
Is your feature request related to a problem? Please describe.
Using get_option
and related functions is inconsistent with the Radiate
framework.
Describe the solution you'd like
A facade for the wp_options
table to give a consistent API for accessing.
Describe alternatives you've considered
Using the native functions.
Additional context
<?php
use Radiate\Support\Facades\Option;
$value = Option::get('key', 'default');
Option::set('value', 'updated_value');
if (Option::has('value')) {
//
}
Option::delete('value');
Is your feature request related to a problem? Please describe.
WordPress doesn't have a build in encrypt/decrypt function. This seems like a useful thing to have for application development.
Describe the solution you'd like
A facade like Laravel to encrypt/decrypt data: https://laravel.com/docs/8.x/encryption
Describe alternatives you've considered
custom implementation but this can lead to inconsistencies.
Additional context
Laravel uses openssl_encrypt/decrypt
. A secure key will also be needed. Could use one of the WordPress keys defined in wp-config.php
:https://api.wordpress.org/secret-key/1.1/salt/ or create a custom key. a CLI command would be nice
wp radiate key:generate
Describe the solution you'd like
Laravel provides a simple way to generate and validate signed routes. The Url::signedRoute()
method and Url::hasValidSignature()
method make it simple to have signed routes. There are also temporary signed routes.
This would make securing URLs simpler,
Describe alternatives you've considered
Manually adding the URL signature, but this will lead to inconsistencies in implementations.
Additional context
https://laravel.com/docs/8.x/urls#signed-urls
Is your feature request related to a problem? Please describe.
There is no easy way to make concurrent HTTP requests.
Describe the solution you'd like
A Http::pool()
method as in Laravel which returns concurrent HTTP requests.
Describe alternatives you've considered
Requests::request_multiple()
: https://developer.wordpress.org/reference/classes/requests/request_multiple/
Additional context
Laravel's pool
method: https://laravel.com/docs/8.x/http-client#concurrent-requests
Is your feature request related to a problem? Please describe.
Currently it's only possible to assign middleware to a group
Describe the solution you'd like
A method to add prefixed/middleware onto a single route without grouping. Also to have on a controller
Describe alternatives you've considered
grouping - it's excess code
Describe the bug
Nested JsonResource
's collection should be able to return any JSONable type, not just an array.
To Reproduce
Steps to reproduce the behavior:
// recipe resource
public function toArray()
{
return [
'ingredients' => IngredientResource::collection($this->ingredients),
];
}
// ingredient resource
public function toArray()
{
return $this->name;
}
{
"ingredients": [
["eggs"],
["milk"]
]
}
Expected behavior
The toArray method to return any JSONable type, string, int, bool, object, array E.g.
{
"ingredients": [
"eggs",
"milk"
]
}
Additional context
The toArray
method name implies the return will be an array but this seems restrictive in instances where the collection should return a simple array of strings.
Is your feature request related to a problem? Please describe.
Currently the REST/AJAX APIs only return raw data. REST responses are converted to JSON automatically.
Describe the solution you'd like
A consistent Response
object to be able to return raw arrays and have them automatically converted into JSON etc.
Describe alternatives you've considered
Writing json_encode
within the controllers
Additional context
Laravel returns a response object that automatically converts to JSON, HTML etc as required. Also a response
helper method with the ability to add additional headers.
Is your feature request related to a problem? Please describe.
It would be nice to be able to cache things for a certain time.
Describe the solution you'd like
Like Laravel's implementation: https://laravel.com/docs/8.x/cache, a cache facade to get/set items in the cache.
Describe alternatives you've considered
Transients: https://developer.wordpress.org/apis/handbook/transients/ or Object cache: https://developer.wordpress.org/reference/classes/wp_object_cache/
Additional context
transients aren't deleted until the transient is called, so perhaps a wp_cron
will need to be implemented to do this... Or just rely on the transient behaviour.
Is your feature request related to a problem? Please describe.
The illuminate package has few dependencies and will be better for supporting long term than radiate own collection class.
Describe the solution you'd like
Arr and collection classes to be replaced by illuminate package which is already present in framework as part of config
Describe alternatives you've considered
Improving collections and arr so full features can be carried. Ie. Arr::wrap
Additional context
Have Radiate\Support\Arr
extend Illuminate\Support\Arr
etc ... to prevent confusion when writing classes.
Is your feature request related to a problem? Please describe.
To get the post featured image requires adding boilerplate methods that could be used as a trait
Describe the solution you'd like
A trait for things such as the post featured image and author. HasFeaturedImage
Describe alternatives you've considered
Adding the methods to the base class
Additional context
Perhaps a trait for HasAuthor
, HasFeaturedImage
, HasAttachment
etc.
Is your feature request related to a problem? Please describe.
A user of the framework has no easy way to create their own commands
Describe the solution you'd like
The ability to create extra commands with the frameworks fluent builder
Describe alternatives you've considered
Writing custom commands with WP_CLI
Additional context
There will need to be a way of loading the commands on the fly or in a service provider. Laravel handles it with auto-discovery, possibly an option
Is your feature request related to a problem? Please describe.
The config directory adds complexity despite the likelyhood of changes being slim.
Describe the solution you'd like
Remove the config directory. Required configurations can be made in the functions file with $app->config()
like in lumen.
Additional context
Hard code the view and app configurations and remove the Auth driver for WordPress...
Is your feature request related to a problem? Please describe.
It's not easy to create custom tables.
Describe the solution you'd like
A schema builder and migration commands.
Describe alternatives you've considered
Writing raw SQL queries.
Additional context
Laravel has migrations.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.