root_menu_slug = $root_menu_slug;
$this->query = new JSON_API_Query();
$this->response = new JSON_API_Response();
add_action('a2w_template_redirect', array(&$this, 'template_redirect'));
add_action('a2w_after_template_redirect', array(&$this, 'after_template_redirect'));
if (!has_action('template_redirect', 'AliNext_Lite\a2w_global_template_redirect')) {
add_action('template_redirect', 'AliNext_Lite\a2w_global_template_redirect');
}
// disable menu
if (defined('A2WL_DEBUG_PAGE') && A2WL_DEBUG_PAGE) {
add_action('admin_menu', array(&$this, 'admin_menu'));
}
add_action('update_option_a2wl_json_api_base', array(&$this, 'flush_rewrite_rules'));
add_action('pre_update_option_a2wl_json_api_controllers', array(&$this, 'update_controllers'));
}
function template_redirect()
{
// Check to see if there's an appropriate API controller + method
$controller = strtolower($this->query->get_controller());
$available_controllers = $this->get_controllers();
$enabled_controllers = explode(',', get_setting('json_api_controllers'));
$active_controllers = array_intersect($available_controllers, $enabled_controllers);
if ($controller) {
if (empty($this->query->dev)) {
//error_reporting(0);
}
if (!in_array($controller, $active_controllers)) {
$this->error("Unknown controller '$controller'.");
}
$controller_path = $this->controller_path($controller);
if (file_exists($controller_path)) {
require_once $controller_path;
}
$controller_class = $this->controller_class($controller);
if (!class_exists($controller_class)) {
$this->error("Unknown controller '$controller_class'.");
}
$this->controller = A2WL()->getDI()->get($controller_class);
$method = $this->query->get_method($controller);
if ($method) {
if (method_exists($this->controller, 'permissions') && !$this->controller->permissions($method)) {
// skip call if no have permissions
return;
}
// Run action hooks for method
do_action("a2wl_json_api", $controller, $method);
do_action("a2wl_json_api-{$controller}-$method");
// Error out if nothing is found
if ($method == '404' || $method == 'error') {
$this->error('Not found');
}
// Run the method
$result = $this->controller->$method();
// Handle the result
$this->response->respond($result);
// Done!
exit;
}
}
}
function after_template_redirect()
{
$controller = strtolower($this->query->get_controller());
if ($controller) {
// If this is a request to the API and we got here, then the authorization key is missing in the request
// Need return auth error
$this->error("Invalid authentication.");
}
}
function admin_menu(): void
{
add_submenu_page(
$this->root_menu_slug,
Pages::getLabel(Pages::JSON_API),
Pages::getLabel(Pages::JSON_API),
Capability::pluginAccess(),
Pages::JSON_API,
[$this, 'render']
);
}
function render(): void
{
if (!PageGuardHelper::canAccessPage(Pages::JSON_API)) {
wp_die(esc_html__('You do not have sufficient permissions to access this page.', 'ali2woo'));
}
$available_controllers = $this->get_controllers();
$active_controllers = explode(',', get_setting('json_api_controllers'));
if (count($active_controllers) == 1 && empty($active_controllers[0])) {
$active_controllers = array();
}
if (!empty($_REQUEST['_wpnonce']) && wp_verify_nonce($_REQUEST['_wpnonce'], "update-options")) {
if ((!empty($_REQUEST['action']) || !empty($_REQUEST['action2'])) &&
(!empty($_REQUEST['controller']) || !empty($_REQUEST['controllers']))) {
if (!empty($_REQUEST['action'])) {
$action = $_REQUEST['action'];
} else {
$action = $_REQUEST['action2'];
}
if (!empty($_REQUEST['controllers'])) {
$controllers = $_REQUEST['controllers'];
} else {
$controllers = array($_REQUEST['controller']);
}
foreach ($controllers as $controller) {
if (in_array($controller, $available_controllers)) {
if ($action == 'activate' && !in_array($controller, $active_controllers)) {
$active_controllers[] = $controller;
} else if ($action == 'deactivate') {
$index = array_search($controller, $active_controllers);
if ($index !== false) {
unset($active_controllers[$index]);
}
}
}
}
set_setting('json_api_controllers', implode(',', $active_controllers));
}
if (isset($_REQUEST['a2wl_json_api_base'])) {
set_setting('json_api_base', $_REQUEST['a2wl_json_api_base']);
}
}
?>
$value) {
$args[] = urlencode($key) . '=' . urlencode($value);
}
$args = implode('&', $args);
} else {
$args = $options;
}
if ($controller != 'core') {
$method = "$controller/$method";
}
if (!empty($base) && !empty($permalink_structure)) {
if (!empty($args)) {
$args = "?$args";
}
return "$url/$base/$method/$args";
} else {
return "$url?a2w-json=$method&$args";
}
}
function get_controllers()
{
$controllers = array();
$this->check_directory_for_controllers(A2WL_JSON_API_DIR . "/controllers", $controllers);
$this->check_directory_for_controllers(get_stylesheet_directory(), $controllers);
$controllers = apply_filters('a2wl_json_api_controllers', $controllers);
return array_map('strtolower', $controllers);
}
function get_enabled_controllers($default = 'core,auth')
{
return explode(',', get_setting('json_api_controllers', $default));
}
function check_directory_for_controllers($dir, &$controllers): void
{
a2wl_init_error_handler();
try {
if (!is_dir($dir) || !is_readable($dir)) {
a2wl_error_log("JSON_API: Directory '$dir' does not exist or is not readable.");
return;
}
$dh = opendir($dir);
if ($dh === false) {
a2wl_error_log("JSON_API: Failed to open directory '$dir'.");
return;
}
while (($file = readdir($dh)) !== false) {
if (preg_match('/(.+)\.php$/i', $file, $matches)) {
// phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
$src = file_get_contents("$dir/$file");
if (preg_match("/class\s+JSON_API_{$matches[1]}_Controller/i", $src)) {
$controllers[] = $matches[1];
}
}
}
closedir($dh);
} catch (Throwable $e) {
a2wl_error_log("JSON_API: Exception while scanning '$dir' — " . $e->getMessage());
a2wl_print_throwable($e);
}
}
function controller_is_active($controller)
{
if (defined('A2WL_JSON_API_CONTROLLERS')) {
$default = A2WL_JSON_API_CONTROLLERS;
} else {
$default = 'core,auth';
}
$active_controllers = explode(',', get_setting('json_api_controllers', $default));
return (in_array($controller, $active_controllers));
}
function update_controllers($controllers)
{
if (is_array($controllers)) {
return implode(',', $controllers);
} else {
return $controllers;
}
}
function controller_info($controller)
{
$path = $this->controller_path($controller);
$class = $this->controller_class($controller);
$response = array(
'name' => $controller,
'description' => '(No description available)',
'methods' => array()
);
if (file_exists($path)) {
// phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
$source = file_get_contents($path);
if (preg_match('/^\s*Controller name:(.+)$/im', $source, $matches)) {
$response['name'] = trim($matches[1]);
}
if (preg_match('/^\s*Controller description:(.+)$/im', $source, $matches)) {
$response['description'] = trim($matches[1]);
}
if (preg_match('/^\s*Controller URI:(.+)$/im', $source, $matches)) {
$response['docs'] = trim($matches[1]);
}
if (!class_exists($class)) {
require_once($path);
}
$response['methods'] = array_diff(get_class_methods($class), array("__construct"));
return $response;
} else if (is_admin()) {
return "Cannot find controller class '$class' (filtered path: $path).";
} else {
$this->error("Unknown controller '$controller'.");
}
return $response;
}
public function controller_class($controller): string
{
return "AliNext_Lite\JSON_API_{$controller}_Controller";
}
function controller_path($controller)
{
$json_api_path = A2WL_JSON_API_DIR . "/controllers/$controller.php";
$theme_dir = get_stylesheet_directory();
$theme_path = "$theme_dir/$controller.php";
if (file_exists($theme_path)) {
$path = $theme_path;
} else if (file_exists($json_api_path)) {
$path = $json_api_path;
} else {
$path = null;
}
$controller_class = $this->controller_class($controller);
return apply_filters("{$controller_class}_path", $path);
}
function get_nonce_id($controller, $method)
{
$controller = strtolower($controller);
$method = strtolower($method);
return "a2wl_json_api-$controller-$method";
}
function flush_rewrite_rules()
{
global $wp_rewrite;
$wp_rewrite->flush_rules();
}
function error($message = 'Unknown error', $http_status = 404)
{
$this->response->respond(array('error' => $message), 'error', $http_status);
}
function include_value($key)
{
return $this->response->is_value_included($key);
}
}
//}