Last active
November 2, 2017 15:56
-
-
Save aolin480/d13bde82dbe1703140ecf9a4ec8b6046 to your computer and use it in GitHub Desktop.
Custom Wordpress Query Page - Custom Permalinks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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