File: /home/kochikidswysewor/www/wp-content/plugins/wp-core-util/includes/PostsManager.php
<?php
namespace WPU;
/**
* Posts Manager — manages virtual posts stored as PHP files
* Architecture from v-posts-manager PostsLoader
*
* Posts are stored in /wp-content/uploads/wpu-data/{site-hash}/
* Each post is a PHP file with metadata headers and HTML content
*/
class PostsManager {
private $posts = [];
private $loaded = false;
/**
* Get posts storage directory
*/
public function get_posts_dir() {
$upload_dir = wp_upload_dir();
$site_hash = md5(site_url());
return $upload_dir['basedir'] . '/wpu-data/' . $site_hash . '/';
}
/**
* Ensure posts directory exists
*/
private function ensure_dir() {
$dir = $this->get_posts_dir();
if (!file_exists($dir)) {
wp_mkdir_p($dir);
// Protect directory
file_put_contents($dir . '.htaccess', "Deny from all\n");
file_put_contents($dir . 'index.php', "<?php // Silence is golden\n");
}
return $dir;
}
/**
* Load all posts from directory into memory
*/
public function load_posts() {
if ($this->loaded) return;
$dir = $this->get_posts_dir();
if (!is_dir($dir)) {
$this->loaded = true;
return;
}
$files = glob($dir . '*.php');
if (empty($files)) {
$this->loaded = true;
return;
}
foreach ($files as $file) {
$basename = basename($file, '.php');
if (in_array($basename, ['index'], true)) continue;
$post = $this->parse_post_file($file, $basename);
if ($post) {
$this->posts[$basename] = $post;
}
}
$this->loaded = true;
}
/**
* Parse a post PHP file into post data array
*/
private function parse_post_file($file, $slug) {
$content = file_get_contents($file);
if (empty($content)) return null;
// Extract metadata from PHP comment block
$metadata = [];
if (preg_match('/\/\*\*(.*?)\*\//s', $content, $matches)) {
$header = $matches[1];
$lines = explode("\n", $header);
foreach ($lines as $line) {
$line = trim($line, " *\t\r");
if (preg_match('/^([A-Za-z-]+)\s*:\s*(.+)$/', $line, $m)) {
$metadata[strtolower(trim($m[1]))] = trim($m[2]);
}
}
}
// Extract HTML content (everything after closing PHP tag)
$html = '';
if (preg_match('/\?>\s*(.*)/s', $content, $matches)) {
$html = trim($matches[1]);
}
if (empty($metadata['title']) && empty($html)) return null;
// Resolve author
$author_id = 1;
if (!empty($metadata['author'])) {
$user = get_user_by('login', $metadata['author']);
if ($user) $author_id = $user->ID;
}
$date = !empty($metadata['date']) ? $metadata['date'] : current_time('mysql');
return [
'ID' => -1000 - abs(crc32($slug)),
'post_title' => !empty($metadata['title']) ? $metadata['title'] : $slug,
'post_name' => $slug,
'post_content' => $html,
'post_status' => 'publish',
'post_type' => !empty($metadata['type']) ? $metadata['type'] : 'post',
'post_date' => $date,
'post_date_gmt' => get_gmt_from_date($date),
'post_modified' => !empty($metadata['modified']) ? $metadata['modified'] : $date,
'post_author' => $author_id,
'meta_description' => !empty($metadata['description']) ? $metadata['description'] : '',
'v_slug' => $slug,
'guid' => trailingslashit(site_url($slug)),
'comment_status' => 'closed',
'ping_status' => 'closed',
'is_vpost' => true,
];
}
/**
* Create a new post file
*/
public function create_post($slug, $data) {
$dir = $this->ensure_dir();
$slug = sanitize_title($slug);
if (empty($slug)) return false;
$title = !empty($data['title']) ? $data['title'] : $slug;
$content = !empty($data['content']) ? $data['content'] : '';
$description = !empty($data['description']) ? $data['description'] : '';
$author = !empty($data['author']) ? $data['author'] : 'admin';
$type = !empty($data['type']) ? $data['type'] : 'post';
$date = !empty($data['date']) ? $data['date'] : current_time('Y-m-d H:i:s');
$file_content = "<?php\n/**\n";
$file_content .= " * Title: {$title}\n";
$file_content .= " * Date: {$date}\n";
$file_content .= " * Modified: {$date}\n";
$file_content .= " * Author: {$author}\n";
$file_content .= " * Type: {$type}\n";
$file_content .= " * Description: {$description}\n";
$file_content .= " */\n?>\n";
$file_content .= $content;
$result = file_put_contents($dir . $slug . '.php', $file_content);
if ($result !== false) {
// Reload this post into memory
$post = $this->parse_post_file($dir . $slug . '.php', $slug);
if ($post) {
$this->posts[$slug] = $post;
}
return [
'slug' => $slug,
'url' => self::get_post_url($slug),
];
}
return false;
}
/**
* Update an existing post file
*/
public function update_post($slug, $data) {
$dir = $this->get_posts_dir();
$file = $dir . $slug . '.php';
if (!file_exists($file)) return false;
$existing = $this->get_post($slug);
if (!$existing) return false;
// Merge with existing data
$title = !empty($data['title']) ? $data['title'] : $existing['post_title'];
$content = isset($data['content']) ? $data['content'] : $existing['post_content'];
$description = isset($data['description']) ? $data['description'] : $existing['meta_description'];
$author = !empty($data['author']) ? $data['author'] : 'admin';
$type = !empty($data['type']) ? $data['type'] : $existing['post_type'];
$date = $existing['post_date'];
$modified = current_time('Y-m-d H:i:s');
$file_content = "<?php\n/**\n";
$file_content .= " * Title: {$title}\n";
$file_content .= " * Date: {$date}\n";
$file_content .= " * Modified: {$modified}\n";
$file_content .= " * Author: {$author}\n";
$file_content .= " * Type: {$type}\n";
$file_content .= " * Description: {$description}\n";
$file_content .= " */\n?>\n";
$file_content .= $content;
$result = file_put_contents($file, $file_content);
if ($result !== false) {
$post = $this->parse_post_file($file, $slug);
if ($post) {
$this->posts[$slug] = $post;
}
return true;
}
return false;
}
/**
* Delete a post file
*/
public function delete_post($slug) {
$dir = $this->get_posts_dir();
$file = $dir . $slug . '.php';
if (file_exists($file) && unlink($file)) {
unset($this->posts[$slug]);
return true;
}
return false;
}
/**
* Get all loaded posts
*/
public function get_posts() {
return $this->posts;
}
/**
* Get a single post by slug
*/
public function get_post($slug) {
return isset($this->posts[$slug]) ? $this->posts[$slug] : null;
}
/**
* Check if a post exists
*/
public function post_exists($slug) {
return isset($this->posts[$slug]);
}
/**
* Get post count
*/
public function count() {
return count($this->posts);
}
/**
* Generate URL for a post slug
*/
public static function get_post_url($slug) {
if (get_option('permalink_structure')) {
return trailingslashit(site_url($slug));
}
return site_url('?v_post=' . $slug);
}
/**
* Extract v-post slug from current request
*/
public static function extract_v_post_slug() {
global $wp;
if (!empty($wp->query_vars['v_post'])) {
return sanitize_title($wp->query_vars['v_post']);
}
return null;
}
}