<commit_before><?php

namespace Parvula\Collections;

use IteratorAggregate;
use MongoDB\Collection as MongoCollectionBase;
use Parvula\ArrayableInterface;
use Parvula\Models\Model;
use Parvula\Models\Page;

class MongoCollection extends Collection {

	/**
	 * @var \MongoDB\Collection
	 */
	protected $collection;

	/**
	 * @var array
	 */
	protected $options;

	/**
	 * @var array
	 */
	protected $filter;

	public function __construct(MongoCollectionBase $collection, $model, $filter = [], $options = []) {
		$this->collection = $collection;
		$this->model = $model;
		$this->filter = $filter;
		$this->options = $options;
	}

	/**
	 * {@inheritDoc}
	 * @return \Parvula\Collections\MongoCollection
	 */
	public function sortBy($field, $ascending = true) {
		if (!isset($this->options['sort'])) {
			$this->options['sort'] = [];
		}

		$this->options['sort'][$field] = $ascending ? 1 : -1;

		return $this->cloneCollection();
	}

	/**
	 * {@inheritDoc}
	 * @return \Parvula\Collections\MongoCollection
	 */
	public function filter($field, array $values = [true]) {
		$this->filter[$field] = ['$in' => $values];

		return $this->cloneCollection();
	}

	/**
	 * @return \MongoDB\Driver\Cursor
	 */
	protected function all() {
		// Possibility to use aggregation
		if (isset($this->filter['$$aggregate'])) {
			$aggregate = $this->filter['$$aggregate'];
			unset($this->filter['$$aggregate']);

			// Use the filter as a $match for aggregation
			$aggregate[] = ['$match' => $this->filter];

			// Use projection in option if exists
			if (isset($this->options['projection'])) {
				$aggregate[] = ['$project' => $this->options['projection']];
			}

			return $this->collection->aggregate($aggregate, $this->options);
		}
		return $this->collection->find($this->filter, $this->options);
	}

	/**
	 * {@inheritDoc}
	 */
	public function count() {
		return count($this->collection->count());
	}

	/**
	 * {@inheritDoc}
	 */
	protected function cloneCollection() {
		return new static($this->collection, $this->model, $this->filter, $this->options);
	}
}<commit_msg>Fix aggregate with options (like sort)<commit_after><?php

namespace Parvula\Collections;

use IteratorAggregate;
use MongoDB\Collection as MongoCollectionBase;
use Parvula\ArrayableInterface;
use Parvula\Models\Model;
use Parvula\Models\Page;

class MongoCollection extends Collection {

	/**
	 * @var \MongoDB\Collection
	 */
	protected $collection;

	/**
	 * @var array
	 */
	protected $options;

	/**
	 * @var array
	 */
	protected $filter;

	public function __construct(MongoCollectionBase $collection, $model, $filter = [], $options = []) {
		$this->collection = $collection;
		$this->model = $model;
		$this->filter = $filter;
		$this->options = $options;
	}

	/**
	 * {@inheritDoc}
	 * @return static
	 */
	public function sortBy($field, $ascending = true) {
		$options = $this->options;

		if (!isset($options['sort'])) {
			$options['sort'] = [];
		}

		$options['sort'][$field] = $ascending ? 1 : -1;

		return new static($this->collection, $this->model, $this->filter, $options);
	}

	/**
	 * {@inheritDoc}
	 * @return static
	 */
	public function filter($field, array $values = [true]) {
		$filter = $this->filter;
		$filter[$field] = ['$in' => $values];

		return new static($this->collection, $this->model, $filter, $this->options);
	}

	/**
	 * @return \MongoDB\Driver\Cursor
	 */
	protected function all() {
		// Possibility to use aggregation
		if (isset($this->filter['$$aggregate'])) {
			$aggregate = $this->filter['$$aggregate'];
			unset($this->filter['$$aggregate']);

			// Use the filter as a $match for aggregation
			$aggregate[] = ['$match' => $this->filter];

			// Transform options and append a `$`
			foreach ($this->options as $key => $option) {
				if ($key === 'projection') {
					$key = 'project';
				}
				$aggregate[] = ['$' . $key => $option];
			}

			return $this->collection->aggregate($aggregate, $this->options);
		}
		return $this->collection->find($this->filter, $this->options);
	}

	/**
	 * {@inheritDoc}
	 */
	public function count() {
		return count($this->collection->count());
	}

	/**
	 * {@inheritDoc}
	 */
	protected function cloneCollection() {
		return new static($this->collection, $this->model, $this->filter, $this->options);
	}
}
{'fraction_non_alphanumeric': 0.19266917293233082, 'fraction_numerical': 0.0009398496240601503, 'mean_word_length': 3.843003412969283, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 69, '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': '4245440', 'n_tokens_mistral': 1527, 'n_tokens_neox': 1346, 'n_words': 294}