<commit_before><?php

/*
 * This file is part of the Yosymfony\Spress.
 *
 * (c) YoSymfony <http://github.com/yosymfony>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Yosymfony\Spress\Core\ContentManager;

use Symfony\Component\EventDispatcher\EventDispatcher;
use Yosymfony\Spress\Core\ContentManager\Collection\CollectionManager;
use Yosymfony\Spress\Core\ContentManager\Collection\CollectionInterface;
use Yosymfony\Spress\Core\ContentManager\Converter\ConverterManager;
use Yosymfony\Spress\Core\ContentManager\Generator\GeneratorManager;
use Yosymfony\Spress\Core\ContentManager\Permalink\PermalinkGenerator;
use Yosymfony\Spress\Core\ContentManager\Renderizer\RenderizerInterface;
use Yosymfony\Spress\Core\ContentManager\SiteAttribute\SiteAttributeInterface;
use Yosymfony\Spress\Core\DataSource\DataSourceManager;
use Yosymfony\Spress\Core\DataWriter\DataWriterInterface;
use Yosymfony\Spress\Core\DataSource\ItemInterface;
use Yosymfony\Spress\Core\Exception\AttributeValueException;
use Yosymfony\Spress\Core\IO\IOInterface;
use Yosymfony\Spress\Core\Plugin\PluginManager;

/**
 * Content manager.
 *
 * @author <NAME> <<EMAIL>>
 */
class ContentManager
{
    private $dataSourceManager;
    private $dataWriter;
    private $generatorManager;
    private $converterManager;
    private $CollectionManager;
    private $permalinkGenerator;
    private $siteAttribute;
    private $renderizer;
    private $pluginManager;
    private $eventDispatcher;
    private $timezone;
    private $safe;
    private $processDraft;

    private $attributes;
    private $spressAttributes;
    private $parseResult;

    private $items;
    private $itemsGenerator;

    /**
     * Constructor.
     *
     * @param Yosymfony\Spress\Core\DataSource\DataSourceManager                        $dataSourceManager
     * @param Yosymfony\Spress\Core\DataWriter\DataWriterInterface                      $dataWriter
     * @param Yosymfony\Spress\Core\ContentManager\Converter\ConverterManager           $converterManager
     * @param Yosymfony\Spress\Core\ContentManager\Collection\CollectionManager         $CollectionManager
     * @param Yosymfony\Spress\Core\ContentManager\Permalink\PermalinkGenerator         $permalinkGenerator
     * @param Yosymfony\Spress\Core\ContentManager\Renderizer\RenderizerInterface       $renderizer
     * @param Yosymfony\Spress\Core\ContentManager\SiteAttribute\SiteAttributeInterface $siteAttribute
     * @param Yosymfony\Spress\Core\Plugin\PluginManager                                $pluginManager
     * @param Symfony\Component\EventDispatcher\EventDispatcher                         $eventDispatcher
     */
    public function __construct(
        DataSourceManager $dataSourceManager,
        DataWriterInterface $dataWriter,
        GeneratorManager $generatorManager,
        ConverterManager $converterManager,
        CollectionManager $CollectionManager,
        PermalinkGenerator $permalinkGenerator,
        RenderizerInterface $renderizer,
        SiteAttributeInterface $siteAttribute,
        PluginManager $pluginManager,
        EventDispatcher $eventDispatcher)
    {
        $this->dataSourceManager = $dataSourceManager;
        $this->dataWriter = $dataWriter;
        $this->generatorManager = $generatorManager;
        $this->converterManager = $converterManager;
        $this->CollectionManager = $CollectionManager;
        $this->permalinkGenerator = $permalinkGenerator;
        $this->renderizer = $renderizer;
        $this->siteAttribute = $siteAttribute;
        $this->pluginManager = $pluginManager;
        $this->eventDispatcher = $eventDispatcher;

        $this->attributes = [];
        $this->spressAttributes = [];

        $this->items = [];
        $this->itemsGenerator = [];

        $this->parseResult = [];
    }

    /**
     * Parse a site.
     *
     * @param array  $attributes
     * @param array  $spressAttributes
     * @param bool   $draft            Include draft posts.
     * @param bool   $safe             True for disabling custom plugins.
     * @param string $timezone         Sets the time zone. @see http://php.net/manual/en/timezones.php More time zones.
     *
     * @return array Information about process
     */
    public function parseSite(array $attributes, array $spressAttributes, $draft = false, $safe = false, $timezone = 'UTC')
    {
        $this->attributes = $attributes;
        $this->spressAttributes = $spressAttributes;
        $this->safe = $safe;
        $this->timezone = $timezone;
        $this->processDraft = $draft;

        $this->reset();
        $this->setUp();
        $this->InitializePlugins();
        $this->process();
        $this->finish();

        return $this->parseResult;
    }

    private function reset()
    {
        $this->items = [];
        $this->itemsGenerator = [];
        $this->siteAttribute->initialize($this->attributes);
        $this->renderizer->clear();

        $this->parseResult = [
            'total_post' => 0,
            'processed_post' => 0,
            'drafts_post' => 0,
            'total_pages' => 0,
            'processed_pages' => 0,
            'other_resources' => 0,
        ];
    }

    private function setUp()
    {
        $this->configureTimezone($this->timezone);

        $this->siteAttribute->setAttribute('spress', $this->spressAttributes);
        $this->siteAttribute->setAttribute('site.safe', $this->safe);
        $this->siteAttribute->setAttribute('site.timezone', $this->timezone);

        $this->dataWriter->setUp();
    }

    private function InitializePlugins()
    {
        if ($this->safe === false) {
            $this->pluginManager->callInitialize();
        }
    }

    private function process()
    {
        $this->dataSourceManager->load();

        $items = $this->dataSourceManager->getItems();

        foreach ($items as $item) {
            if ($this->isGenerator($item)) {
                $this->itemsGenerator[$item->getId()] = $item;

                continue;
            }

            $this->processCollection($item);
            $this->processDraftIfPost($item);
            $this->processOutputAttribute($item);

            $this->items[$item->getId()] = $item;
        }

        foreach ($this->itemsGenerator as $item) {
            $this->processGenerator($item);
        }

        $this->prepareRenderizer();

        foreach ($this->items as $item) {
            $this->convertItem($item);
            $this->processPermalink($item);
            $this->renderBlocks($item);
        }

        foreach ($this->items as $item) {
            $this->renderPage($item);
            $this->dataWriter->write($item);
        }
    }

    private function finish()
    {
        $this->dataWriter->tearDown();
    }

    private function processCollection(ItemInterface $item)
    {
        $collection = $this->CollectionManager->getCollectionForItem($item);
        $collectionName = $collection->getName();
        $collectionNamePath = sprintf('site.collections.%s', $this->escapeDot($collectionName));

        $attributes = $item->getAttributes();
        $attributes['collection'] = $collectionName;

        $newAttributes = array_merge($collection->getAttributes(), $attributes);

        $item->setAttributes($newAttributes);

        $this->siteAttribute->setAttribute($collectionNamePath, $this->getCollectionAttributes($collection));
        $this->siteAttribute->setItem($item);
    }

    private function processDraftIfPost(ItemInterface $item)
    {
        $attributes = array_replace(['draft' => false], $item->getAttributes());

        if (is_bool($attributes['draft']) === false) {
            throw new AttributeValueException('Invalid value. Expected boolean.', 'draft', $item->getPath(ItemInterface::SNAPSHOT_PATH_RELATIVE));
        }

        if ($attributes['collection'] === 'posts' &&  $attributes['draft'] === true) {
            if ($this->processDraft === false) {
                $attributes['output'] = false;

                $item->setAttributes($attributes);<commit_msg>Support for getCollection method of ItemInterface<commit_after><?php

/*
 * This file is part of the Yosymfony\Spress.
 *
 * (c) YoSymfony <http://github.com/yosymfony>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Yosymfony\Spress\Core\ContentManager;

use Symfony\Component\EventDispatcher\EventDispatcher;
use Yosymfony\Spress\Core\ContentManager\Collection\CollectionManager;
use Yosymfony\Spress\Core\ContentManager\Collection\CollectionInterface;
use Yosymfony\Spress\Core\ContentManager\Converter\ConverterManager;
use Yosymfony\Spress\Core\ContentManager\Generator\GeneratorManager;
use Yosymfony\Spress\Core\ContentManager\Permalink\PermalinkGenerator;
use Yosymfony\Spress\Core\ContentManager\Renderizer\RenderizerInterface;
use Yosymfony\Spress\Core\ContentManager\SiteAttribute\SiteAttributeInterface;
use Yosymfony\Spress\Core\DataSource\DataSourceManager;
use Yosymfony\Spress\Core\DataWriter\DataWriterInterface;
use Yosymfony\Spress\Core\DataSource\ItemInterface;
use Yosymfony\Spress\Core\Exception\AttributeValueException;
use Yosymfony\Spress\Core\Plugin\PluginManager;

/**
 * Content manager.
 *
 * @author <NAME> <<EMAIL>>
 */
class ContentManager
{
    private $dataSourceManager;
    private $dataWriter;
    private $generatorManager;
    private $converterManager;
    private $CollectionManager;
    private $permalinkGenerator;
    private $siteAttribute;
    private $renderizer;
    private $pluginManager;
    private $eventDispatcher;
    private $timezone;
    private $safe;
    private $processDraft;

    private $attributes;
    private $spressAttributes;
    private $parseResult;

    private $items;
    private $itemsGenerator;

    /**
     * Constructor.
     *
     * @param Yosymfony\Spress\Core\DataSource\DataSourceManager                        $dataSourceManager
     * @param Yosymfony\Spress\Core\DataWriter\DataWriterInterface                      $dataWriter
     * @param Yosymfony\Spress\Core\ContentManager\Converter\ConverterManager           $converterManager
     * @param Yosymfony\Spress\Core\ContentManager\Collection\CollectionManager         $CollectionManager
     * @param Yosymfony\Spress\Core\ContentManager\Permalink\PermalinkGenerator         $permalinkGenerator
     * @param Yosymfony\Spress\Core\ContentManager\Renderizer\RenderizerInterface       $renderizer
     * @param Yosymfony\Spress\Core\ContentManager\SiteAttribute\SiteAttributeInterface $siteAttribute
     * @param Yosymfony\Spress\Core\Plugin\PluginManager                                $pluginManager
     * @param Symfony\Component\EventDispatcher\EventDispatcher                         $eventDispatcher
     */
    public function __construct(
        DataSourceManager $dataSourceManager,
        DataWriterInterface $dataWriter,
        GeneratorManager $generatorManager,
        ConverterManager $converterManager,
        CollectionManager $CollectionManager,
        PermalinkGenerator $permalinkGenerator,
        RenderizerInterface $renderizer,
        SiteAttributeInterface $siteAttribute,
        PluginManager $pluginManager,
        EventDispatcher $eventDispatcher)
    {
        $this->dataSourceManager = $dataSourceManager;
        $this->dataWriter = $dataWriter;
        $this->generatorManager = $generatorManager;
        $this->converterManager = $converterManager;
        $this->CollectionManager = $CollectionManager;
        $this->permalinkGenerator = $permalinkGenerator;
        $this->renderizer = $renderizer;
        $this->siteAttribute = $siteAttribute;
        $this->pluginManager = $pluginManager;
        $this->eventDispatcher = $eventDispatcher;

        $this->attributes = [];
        $this->spressAttributes = [];

        $this->items = [];
        $this->itemsGenerator = [];

        $this->parseResult = [];
    }

    /**
     * Parse a site.
     *
     * @param array  $attributes
     * @param array  $spressAttributes
     * @param bool   $draft            Include draft posts.
     * @param bool   $safe             True for disabling custom plugins.
     * @param string $timezone         Sets the time zone. @see http://php.net/manual/en/timezones.php More time zones.
     *
     * @return array Information about process
     */
    public function parseSite(array $attributes, array $spressAttributes, $draft = false, $safe = false, $timezone = 'UTC')
    {
        $this->attributes = $attributes;
        $this->spressAttributes = $spressAttributes;
        $this->safe = $safe;
        $this->timezone = $timezone;
        $this->processDraft = $draft;

        $this->reset();
        $this->setUp();
        $this->InitializePlugins();
        $this->process();
        $this->finish();

        return $this->parseResult;
    }

    private function reset()
    {
        $this->items = [];
        $this->itemsGenerator = [];
        $this->siteAttribute->initialize($this->attributes);
        $this->renderizer->clear();

        $this->parseResult = [
            'total_post' => 0,
            'processed_post' => 0,
            'drafts_post' => 0,
            'total_pages' => 0,
            'processed_pages' => 0,
            'other_resources' => 0,
        ];
    }

    private function setUp()
    {
        $this->configureTimezone($this->timezone);

        $this->siteAttribute->setAttribute('spress', $this->spressAttributes);
        $this->siteAttribute->setAttribute('site.safe', $this->safe);
        $this->siteAttribute->setAttribute('site.timezone', $this->timezone);

        $this->dataWriter->setUp();
    }

    private function InitializePlugins()
    {
        if ($this->safe === false) {
            $this->pluginManager->callInitialize();
        }
    }

    private function process()
    {
        $this->dataSourceManager->load();

        $items = $this->dataSourceManager->getItems();

        foreach ($items as $item) {
            if ($this->isGenerator($item)) {
                $this->itemsGenerator[$item->getId()] = $item;

                continue;
            }

            $this->processCollection($item);
            $this->processDraftIfPost($item);
            $this->processOutputAttribute($item);

            $this->items[$item->getId()] = $item;
        }

        foreach ($this->itemsGenerator as $item) {
            $this->processGenerator($item);
        }

        $this->prepareRenderizer();

        foreach ($this->items as $item) {
            $this->convertItem($item);
            $this->processPermalink($item);
            $this->renderBlocks($item);
        }

        foreach ($this->items as $item) {
            $this->renderPage($item);
            $this->dataWriter->write($item);
        }
    }

    private function finish()
    {
        $this->dataWriter->tearDown();
    }

    private function processCollection(ItemInterface $item)
    {
        $collection = $this->CollectionManager->getCollectionForItem($item);
        $collectionName = $collection->getName();
        $collectionNamePath = sprintf('site.collections.%s', $this->escapeDot($collectionName));

        $attributes = $item->getAttributes();
        $attributes['collection'] = $collectionName;

        $newAttributes = array_merge($collection->getAttributes(), $attributes);

        $item->setAttributes($newAttributes);
        $item->setCollection($collectionName);

        $this->siteAttribute->setAttribute($collectionNamePath, $this->getCollectionAttributes($collection));
        $this->siteAttribute->setItem($item);
    }

    private function processDraftIfPost(ItemInterface $item)
    {
        $attributes = array_replace(['draft' => false], $item->getAttributes());

        if (is_bool($attributes['draft']) === false) {
            throw new AttributeValueException('Invalid value. Expected boolean.', 'draft', $item->getPath(ItemInterface::SNAPSHOT_PATH_RELATIVE));
        }

        if ($item->getCollection() === 'posts' &&  $attributes['draft'] === true) {
            if ($this->processDraft === false) {
                $attributes['output'] = false;

                $item->setAttributes($attributes);
{'fraction_non_alphanumeric': 0.12359137677609015, 'fraction_numerical': 0.0007349338559529642, 'mean_word_length': 2.7667820069204154, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 209, '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': '121626', 'n_tokens_mistral': 4447, 'n_tokens_neox': 4332, 'n_words': 765}