Files
deskhub/wordpress-plugin/tests/wp-stub.php
T
2026-11-08 20:09:19 +00:00

157 lines
9.1 KiB
PHP

<?php
/**
* Minimaler Nachbau der WordPress-Funktionen, die das Plugin benutzt. Nur für die Tests (es gibt hier kein echtes WordPress).
* Die Nachbauten folgen dem Verhalten von WordPress (zum Beispiel: add_query_arg codiert Werte nicht selbst).
*/
define('ABSPATH', __DIR__ . '/');
define('HOUR_IN_SECONDS', 3600);
define('MINUTE_IN_SECONDS', 60);
$GLOBALS['wp_options'] = [];
$GLOBALS['wp_transients'] = [];
$GLOBALS['wp_actions'] = [];
$GLOBALS['wp_filters'] = [];
$GLOBALS['wp_shortcodes'] = [];
$GLOBALS['wp_http_log'] = [];
$GLOBALS['wp_http_handler'] = null; // function(string $url, array $args): array|WP_Error
$GLOBALS['wp_user'] = ['id' => 0, 'caps' => [], 'name' => '', 'email' => ''];
$GLOBALS['wp_settings_errors'] = [];
$GLOBALS['wp_enqueued'] = [];
class WP_Error
{
public $code;
public $message;
public $data;
public function __construct($code = '', $message = '', $data = '') { $this->code = $code; $this->message = $message; $this->data = $data; }
public function get_error_message() { return $this->message; }
public function get_error_code() { return $this->code; }
public function get_error_data() { return $this->data; }
}
class WpRedirect extends Exception
{
public $location;
public function __construct(string $location) { parent::__construct('redirect'); $this->location = $location; }
}
function is_wp_error($v) { return $v instanceof WP_Error; }
function plugin_dir_path($file) { return rtrim(dirname($file), '/\\') . '/'; }
function plugin_dir_url($file) { return 'https://wp.test/wp-content/plugins/deskhub-tickets/'; }
function plugin_basename($file) { return 'deskhub-tickets/' . basename($file); }
function load_plugin_textdomain() { return true; }
function add_action($tag, $fn, $prio = 10, $args = 1) { $GLOBALS['wp_actions'][$tag][] = $fn; }
function add_filter($tag, $fn, $prio = 10, $args = 1) { $GLOBALS['wp_filters'][$tag][] = $fn; }
function add_shortcode($tag, $fn) { $GLOBALS['wp_shortcodes'][$tag] = $fn; }
function apply_filters($tag, $value, ...$rest) { foreach ($GLOBALS['wp_filters'][$tag] ?? [] as $fn) $value = $fn($value, ...$rest); return $value; }
function do_action($tag, ...$args) { foreach ($GLOBALS['wp_actions'][$tag] ?? [] as $fn) $fn(...$args); }
function get_option($k, $default = false) { return $GLOBALS['wp_options'][$k] ?? $default; }
function update_option($k, $v) { $GLOBALS['wp_options'][$k] = $v; return true; }
function delete_option($k) { unset($GLOBALS['wp_options'][$k]); return true; }
function get_transient($k) { $t = $GLOBALS['wp_transients'][$k] ?? null; if (!$t) return false; if ($t[1] < time()) { unset($GLOBALS['wp_transients'][$k]); return false; } return $t[0]; }
function set_transient($k, $v, $ttl = 0) { $GLOBALS['wp_transients'][$k] = [$v, time() + ($ttl ?: 86400 * 365)]; return true; }
function delete_transient($k) { unset($GLOBALS['wp_transients'][$k]); return true; }
function wp_salt($scheme = 'auth') { return 'test-salt-' . $scheme; }
function __($s, $d = null) { return $s; }
function esc_html__($s, $d = null) { return esc_html($s); }
function esc_attr__($s, $d = null) { return esc_attr($s); }
function esc_html($s) { return htmlspecialchars((string) $s, ENT_QUOTES, 'UTF-8'); }
function esc_attr($s) { return htmlspecialchars((string) $s, ENT_QUOTES, 'UTF-8'); }
function esc_textarea($s) { return htmlspecialchars((string) $s, ENT_QUOTES, 'UTF-8'); }
function esc_url($s) { $s = (string) $s; return preg_match('#^(https?://|/)#i', $s) ? htmlspecialchars($s, ENT_QUOTES, 'UTF-8') : ''; }
function esc_url_raw($s) { $s = (string) $s; return preg_match('#^https?://#i', $s) ? $s : ''; }
function wp_kses($s, $allowed) {
// vereinfacht: erlaubte Tags behalten (ohne Attribute zu prüfen außer href), alle anderen Tags entfernen
$tags = array_keys($allowed);
return preg_replace_callback('#<(/?)([a-z0-9]+)([^>]*)>#i', function ($m) use ($allowed, $tags) {
$name = strtolower($m[2]);
if (!in_array($name, $tags, true)) return '';
if ($m[1] === '/') return '</' . $name . '>';
$attrs = '';
if (preg_match_all('#\s([a-z-]+)="([^"]*)"#i', $m[3], $am, PREG_SET_ORDER)) {
foreach ($am as $a) {
if (isset($allowed[$name][strtolower($a[1])]) && !preg_match('#^\s*javascript:#i', $a[2])) $attrs .= ' ' . strtolower($a[1]) . '="' . $a[2] . '"';
}
}
return '<' . $name . $attrs . '>';
}, (string) $s);
}
function wp_parse_url($url, $component = -1) { return parse_url($url, $component); }
function add_query_arg($key, $value = null, $url = null) {
if (is_array($key)) { $args = $key; $url = $value; } else { $args = [$key => $value]; }
$parts = explode('#', (string) $url, 2);
$base = $parts[0];
$frag = isset($parts[1]) ? '#' . $parts[1] : '';
$q = '';
if (strpos($base, '?') !== false) { [$base, $q] = explode('?', $base, 2); }
parse_str($q, $existing);
foreach ($args as $k => $v) { $existing[$k] = $v; } // Werte werden NICHT codiert (wie in WordPress)
$pairs = [];
foreach ($existing as $k => $v) { $pairs[] = $k . '=' . $v; }
return $base . ($pairs ? '?' . implode('&', $pairs) : '') . $frag;
}
function remove_query_arg($key, $url = null) {
$parts = explode('?', (string) $url, 2);
if (count($parts) < 2) return $parts[0];
parse_str($parts[1], $q);
foreach ((array) $key as $k) unset($q[$k]);
return $parts[0] . ($q ? '?' . http_build_query($q) : '');
}
function wp_json_encode($v, $flags = 0) { return json_encode($v, $flags | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); }
function wp_remote_retrieve_response_code($r) { return is_array($r) ? ($r['response']['code'] ?? 0) : 0; }
function wp_remote_retrieve_body($r) { return is_array($r) ? ($r['body'] ?? '') : ''; }
function wp_remote_request($url, $args = []) {
$GLOBALS['wp_http_log'][] = ['url' => $url, 'args' => $args];
$h = $GLOBALS['wp_http_handler'];
if (!$h) return new WP_Error('http_no_handler', 'kein Server');
return $h($url, $args);
}
function wp_remote_post($url, $args = []) { $args['method'] = 'POST'; return wp_remote_request($url, $args); }
function shortcode_atts($pairs, $atts, $shortcode = '') { $out = []; foreach ($pairs as $k => $d) $out[$k] = array_key_exists($k, $atts) ? $atts[$k] : $d; return $out; }
function wp_register_style() {}
function wp_enqueue_style($h) { $GLOBALS['wp_enqueued'][] = $h; }
function wp_enqueue_script($h) { $GLOBALS['wp_enqueued'][] = $h; }
function current_user_can($cap) { return in_array($cap, $GLOBALS['wp_user']['caps'], true); }
function is_user_logged_in() { return $GLOBALS['wp_user']['id'] > 0; }
function wp_get_current_user() { return (object) ['display_name' => $GLOBALS['wp_user']['name'], 'user_email' => $GLOBALS['wp_user']['email']]; }
function get_current_user_id() { return $GLOBALS['wp_user']['id']; }
function admin_url($p = '') { return 'https://wp.test/wp-admin/' . ltrim($p, '/'); }
function home_url($p = '') { return 'https://wp.test' . ($p === '' ? '' : '/' . ltrim($p, '/')); }
function get_permalink() { return $GLOBALS['wp_permalink'] ?? 'https://wp.test/kontakt/'; }
function wp_validate_redirect($url, $default = '') { $h = parse_url((string) $url, PHP_URL_HOST); return ($h === 'wp.test') ? $url : $default; }
function wp_safe_redirect($url) { throw new WpRedirect((string) $url); }
function sanitize_text_field($s) { $s = strip_tags((string) $s); $s = preg_replace('/[\r\n\t ]+/', ' ', $s); return trim($s); }
function sanitize_textarea_field($s) { $s = strip_tags((string) $s); return trim(str_replace("\r\n", "\n", $s)); }
function sanitize_email($s) { return preg_replace('/[^a-zA-Z0-9.!#$%&\'*+\/=?^_`{|}~@-]/', '', (string) $s); }
function is_email($s) { return (bool) filter_var($s, FILTER_VALIDATE_EMAIL); }
function wp_unslash($v) { return $v; }
function absint($v) { return abs((int) $v); }
function selected($a, $b) { if ((string) $a === (string) $b) echo ' selected="selected"'; }
function date_i18n($fmt, $ts) { return date($fmt, $ts); }
function register_setting() {}
function settings_fields() {}
function settings_errors() {}
function add_settings_error($setting, $code, $message) { $GLOBALS['wp_settings_errors'][] = [$code, $message]; }
function add_options_page() {}
function submit_button() {}
function wp_nonce_field() {}
function check_admin_referer() { return true; }
function wp_die($m = '') { throw new RuntimeException('wp_die: ' . $m); }
function wp_kses_post($s) { return $s; }
/** Antwort für wp_remote_request nachbauen. */
function wp_stub_response(int $code, $body): array
{
return ['response' => ['code' => $code], 'body' => is_string($body) ? $body : json_encode($body, JSON_UNESCAPED_UNICODE)];
}
if (!function_exists('sanitize_hex_color')) {
function sanitize_hex_color($c) { return preg_match('/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/', (string) $c) ? $c : ''; }
}
if (!function_exists('checked')) {
function checked($a, $b = true, $echo = true) { $r = (string) $a === (string) $b ? " checked='checked'" : ''; if ($echo) echo $r; return $r; }
}
if (!function_exists('sanitize_file_name')) {
function sanitize_file_name($f) { $f = basename(str_replace(chr(92), '/', (string) $f)); $f = preg_replace('/[^A-Za-z0-9._ -]+/', '-', $f); return trim((string) $f, '.- ') === '' ? '' : (string) $f; }
}