<commit_before><?php
namespace Grav\Common\Page;

use Grav\Common\Filesystem\Folder;
use Grav\Common\Config\Config;
use Grav\Common\GravTrait;
use Grav\Common\Utils;
use Grav\Common\Cache;
use Grav\Common\Twig;
use Grav\Common\Uri;
use Grav\Common\Grav;
use Grav\Common\Taxonomy;
use Grav\Common\Markdown\Parsedown;
use Grav\Common\Markdown\ParsedownExtra;
use Grav\Common\Data\Blueprint;
use RocketTheme\Toolbox\Event\Event;
use RocketTheme\Toolbox\File\MarkdownFile;
use Symfony\Component\Yaml\Yaml;

/**
 * The Page object, or "Page" object is the main powerhouse of Grav.  It contains all the information
 * related to the nested pages structure that represents the content. Each page has several attributes that
 * can be retrieved via public functions. Also each page can potentially contain an array of sub-pages.
 * Recursively traversing the page structure allows Grav to create navigation systems.
 *
 * @author RocketTheme
 * @license MIT
 */
class Page
{
    use GravTrait;

    /**
     * @var string Filename. Leave as null if page is folder.
     */
    protected $name;

    /**
     * @var string Folder name.
     */
    protected $folder;

    /**
     * @var string Path to the folder. Add $this->folder to get full path.
     */
    protected $path;

    protected $parent;
    protected $template;
    protected $visible;
    protected $published;
    protected $publish_date;
    protected $unpublish_date;
    protected $slug;
    protected $route;
    protected $routable;
    protected $modified;
    protected $id;
    protected $items;
    protected $header;
    protected $frontmatter;
    protected $content;
    protected $raw_content;
    protected $pagination;
    protected $media;
    protected $metadata;
    protected $title;
    protected $max_count;
    protected $menu;
    protected $date;
    protected $taxonomy;
    protected $order_by;
    protected $order_dir;
    protected $order_manual;
    protected $modular;
    protected $modular_twig;
    protected $process;
    protected $summary_size;
    protected $markdown_extra;

    /**
     * @var Page Unmodified (original) version of the page. Used for copying and moving the page.
     */
    private $_original;

    /**
     * @var string Action
     */
    private $_action;

    /**
     * Page Object Constructor
     *
     * @param array $array An array of existing page objects
     */
    public function __construct($array = array())
    {
        /** @var Config $config */
        $config = self::getGrav()['config'];

        $this->routable = true;
        $this->taxonomy = array();
        $this->process = $config->get('system.pages.process');
        $this->published = true;
    }

    /**
     * Initializes the page instance variables based on a file
     *
     * @param  \SplFileInfo $file The file information for the .md file that the page represents
     * @return void
     */
    public function init($file)
    {
        $this->filePath($file->getPathName());
        $this->modified($file->getMTime());
        $this->id($this->modified().md5($this->filePath()));
        $this->header();
        $this->date();
        $this->metadata();
        $this->slug();
        $this->visible();
        $this->modularTwig($this->slug[0] == '_');

         // Handle publishing dates if no explict published option set
        if (self::getGrav()['config']->get('system.pages.publish_dates') && !isset($this->header->published)) {
            // unpublish if required, if not clear cache right before page should be unpublished
            if ($this->unpublishDate()) {
                if ($this->unpublishDate() < time()) {
                    $this->published(false);
                } else {
                    $this->published();
                    self::getGrav()['cache']->setLifeTime($this->unpublishDate());
                }
            }
            // publish if required, if not clear cache right before page is published
            if ($this->publishDate() != $this->modified() && $this->publishDate() > time()) {
                $this->published(false);
                self::getGrav()['cache']->setLifeTime($this->publishDate());
            }
        }
        $this->published();
    }

    /**
     * Gets and Sets the raw data
     *
     * @param  string $var Raw content string
     * @return Object      Raw content string
     */
    public function raw($var = null)
    {
        $file = $this->file();

        if ($var) {
            // First update file object.
            if ($file) {
                $file->raw($var);
            }

            // Reset header and content.
            $this->modified = time();
            $this->id($this->modified().md5($this->filePath()));
            $this->header = null;
            $this->content = null;
        }
        return $file ? $file->raw() : '';
    }

    public function frontmatter($var = null)
    {

        if ($var) {
            $this->frontmatter = (string) $var;

            // Update also file object.
            $file = $this->file();
            if ($file) {
                $file->frontmatter((string) $var);
            }

            // Force content re-processing.
            $this->id(time().md5($this->filePath()));
        }
        if (!$this->frontmatter) {
            $this->header();
        }
        return $this->frontmatter;
    }

    /**
     * Gets and Sets the header based on the YAML configuration at the top of the .md file
     *
     * @param  object|array $var a YAML object representing the configuration for the file
     * @return object      the current YAML configuration
     */
    public function header($var = null)
    {
        if ($var) {
            $this->header = (object) $var;

            // Update also file object.
            $file = $this->file();
            if ($file) {
                $file->header((array) $var);
            }

            // Force content re-processing.
            $this->id(time().md5($this->filePath()));
        }
        if (!$this->header) {
            $file = $this->file();
            if ($file) {
                $this->raw_content = $file->markdown();
                $this->frontmatter = $file->frontmatter();
                $this->header = (object) $file->header();

                $var = true;
            }
        }

        if ($var) {
            if (isset($this->header->slug)) {
                $this->slug = trim($this->header->slug);
            }
            if (isset($this->header->title)) {
                $this->title = trim($this->header->title);
            }
            if (isset($this->header->template)) {
                $this->template = trim($this->header->template);
            }
            if (isset($this->header->menu)) {
                $this->menu = trim($this->header->menu);
            }
            if (isset($this->header->routable)) {
                $this->routable = $this->header->routable;
            }
            if (isset($this->header->visible)) {
                $this->visible = $this->header->visible;
            }
            if (isset($this->header->order_dir)) {
                $this->order_dir = trim($this->header->order_dir);
            }
            if (isset($this->header->order_by)) {
                $this->order_by = trim($this->header->order_by);
            }
            if (isset($this->header->order_manual)) {
                $this->order_manual = (array)$this->header->order_manual;
            }
            if (isset($this->header->date)) {
                $this->date = strtotime($this->header->date);
            }
            if (isset($this->header->markdown_extra)) {
                $this->markdown_extra = (bool)$this->header->markdown_extra;
            }
            if (isset($this->header->taxonomy)) {
                foreach ($this->header->taxonomy as $taxonomy => $taxitems) {
                    $this->taxonomy[$taxonomy] = (array)$taxitems;
                }
            }
            if (isset($this->header->max_count)) {
                $this->max_count = intval($this->header->max_count);
            }
            if (isset($this->header->process)) {
                foreach ($this->header->process as $process => $status) {
                    $this->process[$process] = $status;
                }
            }
            if (isset($this->header->published)) {
                $this->published = $this->header->published;
            }
            if (isset($this->header->publish_date)) {
                $this->publish_date = strtotime($this->header->publish_date);
            }
            if (isset($this->header->unpublish_date)) {
                $this->unpublish_date = strtotime($this->header->unpublish_date);
            }
        }

        return $this->header;
    }

    /**
     * Modify a header value directly
     *
     * @param $key
     * @param $value
     */
    public function modifyHeader($key, $value)
    {
        $this->header->$key = $value;
    }

    /**
     * Get the summary.
     *
     * @param int $size  Max summary size.
     * @return string
     */
    public function summary($size = null)
    {
        /** @var Config $config */
        $config = self::getGrav()['config'];
        $content = $this->content();

        // Return summary based on settings in site config file
        if (!$config->get('site.summary.enabled', true)) {
            return $content;
        }

        // Get summary size from site config's file
        if (is_null($size)) {
            $size = $config->get('site.summary.size', null);
        }

        // Return calculated summary based on summary divider's position
        $format = $config->get('site.summary.format', 'short');
        // Return entire page content on wrong/ unknown format
        if (!in_array($format, array('short', 'long'))) {
            return $content;
        } elseif (($format === 'short') && isset($this->summary_size)) {
            return substr($content, 0, $this->summary_size);
        }

        // If the size is zero, return the entire page content
        if ($size === 0) {
            return $content;
        // Return calculated summary based on defaults
        } elseif (!is_numeric($size) || ($size < 0)) {
            $size = 300;
        }

        return Utils::truncateHTML($content, $size);
    }

    /**
     * Gets and Sets the content based on content portion of the .md file
     *
     * @param  string $var Content
     * @return string      Content
     */
    public function content($var = null)
    {
        if ($var !== null) {
            $this->raw_content = $var;

            // Update file object.
            $file = $this->file();
            if ($file) {
                $file->markdown($var);
            }

            // Force re-processing.
            $this->id(time().md5($this->filePath()));
            $this->content = null;
        }

        // If no content, process it
        if ($this->content === null) {
            // Get media
            $this->media();

            // Load cached content
            /** @var Cache $cache */
            $cache = self::getGrav()['cache'];
            $cache_id = md5('page'.$this->id());
            $this->content = $cache->fetch($cache_id);

            $process_markdown = $this->shouldProcess('markdown');
            $process_twig = $this->shouldProcess('twig');
            $cache_twig = isset($this->header->cache_enable) ? $this->header->cache_enable : true;
            $twig_first = isset($this->header->twig_first) ? $this->header->twig_first : false;
            $twig_already_processed = false;

            // if no cached-content run everything
            if ($this->content == false) {
                $this->content = $this->raw_content;<commit_msg>strict boolean compare<commit_after><?php
namespace Grav\Common\Page;

use Grav\Common\Filesystem\Folder;
use Grav\Common\Config\Config;
use Grav\Common\GravTrait;
use Grav\Common\Utils;
use Grav\Common\Cache;
use Grav\Common\Twig;
use Grav\Common\Uri;
use Grav\Common\Grav;
use Grav\Common\Taxonomy;
use Grav\Common\Markdown\Parsedown;
use Grav\Common\Markdown\ParsedownExtra;
use Grav\Common\Data\Blueprint;
use RocketTheme\Toolbox\Event\Event;
use RocketTheme\Toolbox\File\MarkdownFile;
use Symfony\Component\Yaml\Yaml;

/**
 * The Page object, or "Page" object is the main powerhouse of Grav.  It contains all the information
 * related to the nested pages structure that represents the content. Each page has several attributes that
 * can be retrieved via public functions. Also each page can potentially contain an array of sub-pages.
 * Recursively traversing the page structure allows Grav to create navigation systems.
 *
 * @author RocketTheme
 * @license MIT
 */
class Page
{
    use GravTrait;

    /**
     * @var string Filename. Leave as null if page is folder.
     */
    protected $name;

    /**
     * @var string Folder name.
     */
    protected $folder;

    /**
     * @var string Path to the folder. Add $this->folder to get full path.
     */
    protected $path;

    protected $parent;
    protected $template;
    protected $visible;
    protected $published;
    protected $publish_date;
    protected $unpublish_date;
    protected $slug;
    protected $route;
    protected $routable;
    protected $modified;
    protected $id;
    protected $items;
    protected $header;
    protected $frontmatter;
    protected $content;
    protected $raw_content;
    protected $pagination;
    protected $media;
    protected $metadata;
    protected $title;
    protected $max_count;
    protected $menu;
    protected $date;
    protected $taxonomy;
    protected $order_by;
    protected $order_dir;
    protected $order_manual;
    protected $modular;
    protected $modular_twig;
    protected $process;
    protected $summary_size;
    protected $markdown_extra;

    /**
     * @var Page Unmodified (original) version of the page. Used for copying and moving the page.
     */
    private $_original;

    /**
     * @var string Action
     */
    private $_action;

    /**
     * Page Object Constructor
     *
     * @param array $array An array of existing page objects
     */
    public function __construct($array = array())
    {
        /** @var Config $config */
        $config = self::getGrav()['config'];

        $this->routable = true;
        $this->taxonomy = array();
        $this->process = $config->get('system.pages.process');
        $this->published = true;
    }

    /**
     * Initializes the page instance variables based on a file
     *
     * @param  \SplFileInfo $file The file information for the .md file that the page represents
     * @return void
     */
    public function init($file)
    {
        $this->filePath($file->getPathName());
        $this->modified($file->getMTime());
        $this->id($this->modified().md5($this->filePath()));
        $this->header();
        $this->date();
        $this->metadata();
        $this->slug();
        $this->visible();
        $this->modularTwig($this->slug[0] == '_');

         // Handle publishing dates if no explict published option set
        if (self::getGrav()['config']->get('system.pages.publish_dates') && !isset($this->header->published)) {
            // unpublish if required, if not clear cache right before page should be unpublished
            if ($this->unpublishDate()) {
                if ($this->unpublishDate() < time()) {
                    $this->published(false);
                } else {
                    $this->published();
                    self::getGrav()['cache']->setLifeTime($this->unpublishDate());
                }
            }
            // publish if required, if not clear cache right before page is published
            if ($this->publishDate() != $this->modified() && $this->publishDate() > time()) {
                $this->published(false);
                self::getGrav()['cache']->setLifeTime($this->publishDate());
            }
        }
        $this->published();
    }

    /**
     * Gets and Sets the raw data
     *
     * @param  string $var Raw content string
     * @return Object      Raw content string
     */
    public function raw($var = null)
    {
        $file = $this->file();

        if ($var) {
            // First update file object.
            if ($file) {
                $file->raw($var);
            }

            // Reset header and content.
            $this->modified = time();
            $this->id($this->modified().md5($this->filePath()));
            $this->header = null;
            $this->content = null;
        }
        return $file ? $file->raw() : '';
    }

    public function frontmatter($var = null)
    {

        if ($var) {
            $this->frontmatter = (string) $var;

            // Update also file object.
            $file = $this->file();
            if ($file) {
                $file->frontmatter((string) $var);
            }

            // Force content re-processing.
            $this->id(time().md5($this->filePath()));
        }
        if (!$this->frontmatter) {
            $this->header();
        }
        return $this->frontmatter;
    }

    /**
     * Gets and Sets the header based on the YAML configuration at the top of the .md file
     *
     * @param  object|array $var a YAML object representing the configuration for the file
     * @return object      the current YAML configuration
     */
    public function header($var = null)
    {
        if ($var) {
            $this->header = (object) $var;

            // Update also file object.
            $file = $this->file();
            if ($file) {
                $file->header((array) $var);
            }

            // Force content re-processing.
            $this->id(time().md5($this->filePath()));
        }
        if (!$this->header) {
            $file = $this->file();
            if ($file) {
                $this->raw_content = $file->markdown();
                $this->frontmatter = $file->frontmatter();
                $this->header = (object) $file->header();

                $var = true;
            }
        }

        if ($var) {
            if (isset($this->header->slug)) {
                $this->slug = trim($this->header->slug);
            }
            if (isset($this->header->title)) {
                $this->title = trim($this->header->title);
            }
            if (isset($this->header->template)) {
                $this->template = trim($this->header->template);
            }
            if (isset($this->header->menu)) {
                $this->menu = trim($this->header->menu);
            }
            if (isset($this->header->routable)) {
                $this->routable = $this->header->routable;
            }
            if (isset($this->header->visible)) {
                $this->visible = $this->header->visible;
            }
            if (isset($this->header->order_dir)) {
                $this->order_dir = trim($this->header->order_dir);
            }
            if (isset($this->header->order_by)) {
                $this->order_by = trim($this->header->order_by);
            }
            if (isset($this->header->order_manual)) {
                $this->order_manual = (array)$this->header->order_manual;
            }
            if (isset($this->header->date)) {
                $this->date = strtotime($this->header->date);
            }
            if (isset($this->header->markdown_extra)) {
                $this->markdown_extra = (bool)$this->header->markdown_extra;
            }
            if (isset($this->header->taxonomy)) {
                foreach ($this->header->taxonomy as $taxonomy => $taxitems) {
                    $this->taxonomy[$taxonomy] = (array)$taxitems;
                }
            }
            if (isset($this->header->max_count)) {
                $this->max_count = intval($this->header->max_count);
            }
            if (isset($this->header->process)) {
                foreach ($this->header->process as $process => $status) {
                    $this->process[$process] = $status;
                }
            }
            if (isset($this->header->published)) {
                $this->published = $this->header->published;
            }
            if (isset($this->header->publish_date)) {
                $this->publish_date = strtotime($this->header->publish_date);
            }
            if (isset($this->header->unpublish_date)) {
                $this->unpublish_date = strtotime($this->header->unpublish_date);
            }
        }

        return $this->header;
    }

    /**
     * Modify a header value directly
     *
     * @param $key
     * @param $value
     */
    public function modifyHeader($key, $value)
    {
        $this->header->$key = $value;
    }

    /**
     * Get the summary.
     *
     * @param int $size  Max summary size.
     * @return string
     */
    public function summary($size = null)
    {
        /** @var Config $config */
        $config = self::getGrav()['config'];
        $content = $this->content();

        // Return summary based on settings in site config file
        if (!$config->get('site.summary.enabled', true)) {
            return $content;
        }

        // Get summary size from site config's file
        if (is_null($size)) {
            $size = $config->get('site.summary.size', null);
        }

        // Return calculated summary based on summary divider's position
        $format = $config->get('site.summary.format', 'short');
        // Return entire page content on wrong/ unknown format
        if (!in_array($format, array('short', 'long'))) {
            return $content;
        } elseif (($format === 'short') && isset($this->summary_size)) {
            return substr($content, 0, $this->summary_size);
        }

        // If the size is zero, return the entire page content
        if ($size === 0) {
            return $content;
        // Return calculated summary based on defaults
        } elseif (!is_numeric($size) || ($size < 0)) {
            $size = 300;
        }

        return Utils::truncateHTML($content, $size);
    }

    /**
     * Gets and Sets the content based on content portion of the .md file
     *
     * @param  string $var Content
     * @return string      Content
     */
    public function content($var = null)
    {
        if ($var !== null) {
            $this->raw_content = $var;

            // Update file object.
            $file = $this->file();
            if ($file) {
                $file->markdown($var);
            }

            // Force re-processing.
            $this->id(time().md5($this->filePath()));
            $this->content = null;
        }

        // If no content, process it
        if ($this->content === null) {
            // Get media
            $this->media();

            // Load cached content
            /** @var Cache $cache */
            $cache = self::getGrav()['cache'];
            $cache_id = md5('page'.$this->id());
            $this->content = $cache->fetch($cache_id);

            $process_markdown = $this->shouldProcess('markdown');
            $process_twig = $this->shouldProcess('twig');
            $cache_twig = isset($this->header->cache_enable) ? $this->header->cache_enable : true;
            $twig_first = isset($this->header->twig_first) ? $this->header->twig_first : false;
            $twig_already_processed = false;

            // if no cached-content run everything
            if ($this->content === false) {
                $this->content = $this->raw_content;
{'fraction_non_alphanumeric': 0.14403833107191316, 'fraction_numerical': 0.0011024423337856173, 'mean_word_length': 1.7868368190948836, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 377, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5509145', 'n_tokens_mistral': 6603, 'n_tokens_neox': 6349, 'n_words': 1567}