Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
alexstandiford committed Feb 20, 2022
0 parents commit 2f15dd4
Show file tree
Hide file tree
Showing 8 changed files with 489 additions and 0 deletions.
11 changes: 11 additions & 0 deletions bootstrap.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

use Underpin\Abstracts\Underpin;
use Underpin\Factories\Observers\Loader;

if ( ! defined( 'ABSPATH' ) ) {
exit;
}

// Add this loader.
Underpin::attach( 'setup', new Loader( 'routes', [ 'class' => 'Underpin\Routes\Loaders\Routes' ] ) );
21 changes: 21 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "underpin/route-loader",
"description": "Custom route loader for Underpin",
"type": "library",
"license": "GPL-2.0-or-later",
"authors": [
{
"name": "Alex Standiford",
"email": "a@alexstandiford.com"
}
],
"require": {
"underpin/underpin": "^2.0"
},
"autoload": {
"psr-4": {"Underpin\\Routes\\": "lib/"},
"files": [
"bootstrap.php"
]
}
}
66 changes: 66 additions & 0 deletions lib/Abstracts/Route.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

namespace Underpin\Routes\Abstracts;

use Underpin\Traits\With_Middleware;

abstract class Route {

use With_Middleware;

protected $route = '';
protected $query_vars = [];
protected $is_current_route = null;
protected $priority = 'bottom';
protected $path = '';
protected $id = '';
private const FALSE_HASH = '11b3a8b654edbdec28dd944c3b44f3921';

protected function get_path() {
return add_query_arg( $this->query_vars, 'index.php' );
}

abstract public function get_id();

/**
* Determines if is route is the current route.
*
* @since 1.0.0
*
* @return bool True if this is the current route, otherwise false.
*/
protected function is_current_route() {
foreach ( array_keys( $this->query_vars ) as $query_var ) {
if ( get_query_var( $query_var, self::FALSE_HASH ) === self::FALSE_HASH ) {
return false;
}
}

return true;
}

public function __get( $key ) {

if ( 'path' === $key && empty( $this->path ) ) {
$this->path = $this->get_path();
return $this->path;
}

if ( 'id' === $key && empty( $this->id ) ) {
$this->id = $this->get_id();
return $this->id;
}

if ( 'is_current_route' === $key && empty ( $this->is_current_route ) ) {
$this->is_current_route = $this->is_current_route();
return $this->is_current_route;
}

if ( isset( $this->$key ) ) {
return $this->$key;
} else {
return new \WP_Error( 'route_param_not_set', 'The key ' . $key . ' could not be found.' );
}
}

}
26 changes: 26 additions & 0 deletions lib/Factories/Route.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace Underpin\Routes\Factories;

use Underpin\Traits\Instance_Setter;

if ( ! defined( 'ABSPATH' ) ) {
exit;
}


class Route extends \Underpin\Routes\Abstracts\Route {

use Instance_Setter;

protected $id_callback;

public function __construct( $args ) {
$this->set_values( $args );
}

public function get_id() {
return $this->set_callable( $this->id_callback, $this->query_vars );
}

}
116 changes: 116 additions & 0 deletions lib/Loaders/Routes.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
<?php
/**
* Script Loader
*
* @since 1.0.0
* @package Underpin\Registries\Loaders
*/


namespace Underpin\Routes\Loaders;

use Underpin\Abstracts\Registries\Object_Registry;
use Underpin\Routes\Abstracts\Route;
use Underpin\Routes\Factories;
use WP_Error;


if ( ! defined( 'ABSPATH' ) ) {
exit;
}

/**
* Class Scripts
* Loader for scripts
*
* @since 1.0.0
* @package Underpin\Registries\Loaders
*/
class Routes extends Object_Registry {

protected $abstraction_class = Route::class;
protected $default_factory = Factories\Route::class;

public function __construct() {
parent::__construct();
$this->do_actions();
}

protected function do_actions() {
add_filter( 'init', [ $this, 'setup_rewrite_rules' ] );
add_filter( 'query_vars', [ $this, 'whitelist_rewrite_vars' ] );
}

function whitelist_rewrite_vars( $vars ) {
$items = [];
foreach ( (array) $this as $item ) {
$items = array_merge( $items, array_keys( $item->query_vars ) );
}
return array_merge( $vars, array_unique( $items ) );
}

/**
* Sets up rewrite rules for registered routes.
*
* @return void
*/
public function setup_rewrite_rules() {
/* @var Route $item */
foreach ( (array) $this as $item ) {
add_rewrite_rule( $item->route, $item->query_vars, $item->priority );
}
}

/**
* @param $key
*
* @return Route|WP_Error
*/
public function get( $key ) {
return parent::get( $key );
}

/**
* @param $route_id string The route ID
*
* @return boolean true if this is the current route, otherwise false.
*/
public function is_current_route( $route_id ) {

$route = $this->find( [ 'id' => $route_id ] );

if ( is_wp_error( $route ) ) {
return false;
}

/* @var Route $route */
return $route->is_current_route;
}

/**
* Attempts to retrieve the current route from routes registered against this plugin.
*
* @since 1.0.0
*
* @return Route|WP_Error The route if found, otherwise WP_Error
*/
public function current() {
return $this->find( [ 'is_current_route' => true ] );
}

/**
* Attempts to retrieve the current route from routes registered against this plugin.
*
* @since 1.0.0
*
* @return Route|WP_Error The route if found, otherwise WP_Error
*/
public function get_by_route( $route ) {
return $this->find( [ 'route' => $route ] );
}

protected function set_default_items() {
// TODO: Implement set_default_items() method.
}

}
53 changes: 53 additions & 0 deletions lib/Middlewares/Prevent_Main_Query.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

namespace Underpin\Routes\Middlewares;

use Underpin\Abstracts\Observer;
use Underpin\Abstracts\Storage;
use Underpin\Routes\Abstracts\Route;
use WP_Query;

if ( ! defined( 'ABSPATH' ) ) {
exit;
}


class Prevent_Main_Query extends Observer {

/**
* @var Route
*/
protected $route;

public function __construct() {
parent::__construct( 'prevent_main_query' );
}

public function update( $instance, Storage $args ) {
if ( $instance instanceof Route ) {
$this->route = $instance;
add_filter( 'posts_request', [ $this, 'prevent_main_query' ], 10, 2 );
}
}

/**
* @param $sql
* @param WP_Query $query
*
* @return string|false The current query if this route should not be prevented, otherwise false.
*/
public function prevent_main_query( $sql, WP_Query $query ) {

if ( $query->is_main_query() && true === $this->route->is_current_route ) {
// prevent SELECT FOUND_ROWS() query
$query->query_vars['no_found_rows'] = true;

// prevent post term and meta cache update queries
$query->query_vars['cache_results'] = false;

return false;
}
return $sql;
}

}
43 changes: 43 additions & 0 deletions lib/Middlewares/Use_Template.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

namespace Underpin\Routes\Middlewares;

use Underpin\Abstracts\Observer;
use Underpin\Abstracts\Storage;
use Underpin\Routes\Abstracts\Route;

if ( ! defined( 'ABSPATH' ) ) {
exit;
}


class Use_Template extends Observer {

/**
* @var Route
*/
protected $route;

protected $template = '';

public function __construct( $template ) {
$this->template = $template;
parent::__construct( 'use_template' );
}

public function update( $instance, Storage $args ) {
if ( $instance instanceof Route ) {
$this->route = $instance;
add_filter( 'template_include', [ $this, 'include_template' ], 10, 2 );
}
}

public function include_template( $template ) {
if ( $this->route->is_current_route ) {
return $this->template;
}

return $template;
}

}
Loading

0 comments on commit 2f15dd4

Please sign in to comment.