Skip to content

Instantly share code, notes, and snippets.

@aolin480
Last active November 2, 2017 15:56
Show Gist options
  • Save aolin480/d13bde82dbe1703140ecf9a4ec8b6046 to your computer and use it in GitHub Desktop.
Save aolin480/d13bde82dbe1703140ecf9a4ec8b6046 to your computer and use it in GitHub Desktop.
Custom Wordpress Query Page - Custom Permalinks
<?php
/**
* Custom Wordpress Query Page - Custom Permalinks
* @author Aaron Olin
*/
if (! class_exists('CustomEndpoint')) {
class CustomEndpoint {
protected static $_instance = null;
protected $templateFile;
protected $endpointRoot;
protected $apiRewritePermalink;
protected $apiRewriteRule;
protected $rewriteRules = [];
public function __construct($templateFile, $endpointRoot, $rewriteRules = [])
{
$this->templateFile = $templateFile;
$this->endpointRoot = $endpointRoot;
$this->rewriteRules = $rewriteRules;
$this->setApiRewritePermalink();
$this->setApiRewriteRule();
// b/o: API Endpoint
add_action('init', [$this, 'addApiEndPoint']);
add_filter('query_vars', [$this, 'validQueryVars']);
add_filter('template_include', [$this, 'handleApiRequest']);
// e/o: API Endpoint
}
public function setApiRewritePermalink()
{
$this->apiRewritePermalink = $this->endpointRoot . '/';
$ruleCount = count($this->rewriteRules);
for($i=0; $i<= $ruleCount; $i++) {
$this->apiRewritePermalink .= '([^\\/]*)/?';
}
}
public function apiParameterRulesBuilt()
{
$rules = '';
$i = 1;
foreach ($this->rewriteRules as $rule) {
if ($i == 1) {
$rules .= "$rule=\$matches[$i]";
} else {
$rules .= "&$rule=\$matches[$i]";
}
$i++;
}
return $rules;
}
public function setApiRewriteRule()
{
$this->apiRewriteRule = 'index.php?';
$this->apiRewriteRule .= $this->apiParameterRulesBuilt();
}
/**
* Set the endpoint URL for concatenated CSS link
*/
public function addApiEndPoint()
{
$this->maybeFlushRewriteRules($this->apiRewritePermalink, $this->apiRewriteRule);
$regex = $this->apiRewritePermalink;
$location = $this->apiRewriteRule;
$priority = 'top'; // use 'top' here or WP will send you to the page if 'bottom' is used;
add_rewrite_rule($regex, $location, $priority);
}
/**
* Specify safe variables to use with the endpoint. If a variable is not specified, it will not be available to $this->add_api_endpoint()
*
* @param array $vars an array of query vars
* @return array an array of query vars
*/
public function validQueryVars($vars)
{
foreach ($this->rewriteRules as $_var) {
$vars[] = $_var;
}
return $vars;
}
/**
* Handle the API requests and route where necessary
*
* @return string wp template URL which should always be returned for non-api calls
*/
public function handleApiRequest($template)
{
$firstVar = get_query_var('firstvar', null);
// $secondVar = get_query_var('secondvar', null);
// $thirdVar = get_query_var('thirdvar', null);
if ($firstVar) {
$template = get_stylesheet_directory() . '/' . $this->templateFile;
}
return $template; // must be returned, always!
}
/**
* Check if specific rewrite rule exists, if not, then we'll flush the permalinks to add it
*
* @param string $rewriteKey the rewrite array key value to check for
* @param boolean $force skip checking for rewrite key and force the flush
* @return null
*/
public function maybeFlushRewriteRules($rewriteKey, $rewriteRule, $force = false)
{
if ($force) {
flush_rewrite_rules(true);
return;
}
$registeredRewriteRules = get_option('rewrite_rules');
if (! array_key_exists($rewriteKey, $registeredRewriteRules) || ! $this->in_array_r($rewriteRule, $registeredRewriteRules)) {
flush_rewrite_rules(true);
}
}
/**
* a multidimensional version of PHP's in_array()
* https://gist.github.com/Billy-/bc6865066981e80e097f
*
* @param string $needle [description]
* @param array $haystack [description]
* @param boolean $strict [description]
* @return boolean [description]
* usage: $multi_array = [ ["foo", "bar"], ["baz", "qux"] ];
* echo in_array_r("baz", $multi_array) ? 'found' : 'not found';
*/
public function in_array_r($needle, $haystack, $strict = false) {
foreach ($haystack as $item) {
if (($strict ? $item === $needle : $item == $needle) || (is_array($item) && $this->in_array_r($needle, $item, $strict))) {
return true;
}
}
return false;
}
public static function instance($templateFile, $endpoint, $rewriteRules = [])
{
if (is_null(self::$_instance)) {
self::$_instance = new self($templateFile, $endpoint, $rewriteRules);
}
return self::$_instance;
}
}
function endpointRedirect($templateFile, $endpoint, $rewriteRules) {
return CustomEndpoint::instance($templateFile, $endpoint, $rewriteRules);
}
} // e/o: if class_exists
/**
* register the custom endpoint with these properties
* Example: You can access the following page: http://domain.dev/myendpoint/firstvar_value/secondvar_value/thirdvar_value
* Tip 1: Use the handleApiRequest method to handle the custom query vars (firstvar,secondvar, thirdvar)
*/
if (function_exists('endpointRedirect')) {
endpointRedirect(
'redirect-myendpoint.php', // uses the template file redirect-myendpoint.php located in root of Wordpress theme
'myendpoint', // the custom endpoint permalink slug
['firstvar', 'secondvar', 'thirdvar'] // rewrite rules
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment