HEX
Server: Apache
System: Linux wyse1.wyseservers.com 4.18.0-553.124.4.el8_10.x86_64 #1 SMP Fri May 15 04:14:14 EDT 2026 x86_64
User: kochikidswysewor (1061)
PHP: 8.3.33
Disabled: NONE
Upload Files
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;
    }
}