<commit_before><?php

/**
 * This file is part of the miBadger package.
 *
 * @author <NAME> <<EMAIL>>
 * @license http://opensource.org/licenses/Apache-2.0 Apache v2 License
 * @version 1.0.0
 */

namespace miBadger\ActiveRecord;

/**
 * The abstract active record search class.
 *
 * @since 1.0.0
 */
abstract class AbstractActiveRecordSearch extends AbstractActiveRecord
{
	/**
	 * {@inheritdoc}
	 */
	public function search($options = [])
	{
		try {
			$pdoStatement = $this->getPdo()->prepare($this->getSearchQuery($options));
			array_walk_recursive($options, function(&$value) use ($pdoStatement) {
				static $index = 1;

				$pdoStatement->bindParam($index++, $value);
			});

			$pdoStatement->execute();
			$result = [];

			while ($fetch = $pdoStatement->fetch()) {
				$new = new static($this->getPdo());

				$new->setId(intval($fetch['id']));
				$new->setActiveRecordData($fetch);

				$result[] = $new;
			}

			return $result;
		} catch (\PDOException $e) {
			throw new ActiveRecordException(sprintf('Can not search the record in the `%s` table.', $this->getActiveRecordName()), 0, $e);
		}
	}

	/**
	 * Returns the search query with the given options.
	 *
	 * @param array $options = []
	 * @return string the search query with the given options.
	 */
	private function getSearchQuery($options = [])
	{
		$columns = array_keys($this->getActiveRecordData());
		$columns[] = 'id';
		$values = [];

		foreach ($options as $key => $value) {
			if (!in_array($key, $columns)) {
				throw new ActiveRecordException(sprintf('Search option key `%s` does not exists.', $key));
			}

			if (is_numeric($value)) {
				$values[] = '`' . $key . '` = ?';
			} elseif (is_string($value)) {
				$values[] = '`' . $key . '` LIKE ?';
			} elseif (is_null($value)) {
				$values[] = '`' . $key . '` IS ?';
			} elseif (is_array($value) && !empty($value)) {
				$values[] = '`' . $key . '` IN(' . implode(',', array_fill(0, count($value), '?')) . ')';
			} else {
				throw new ActiveRecordException(sprintf('Search option value of key `%s` is not supported.', $this->getActiveRecordName()));
			}
		}

		return sprintf('SELECT * FROM `%s` %s', $this->getActiveRecordName(), empty($values) ? '' : 'WHERE ' . implode(' AND ', $values));
	}
}
<commit_msg>Fixed SQL injection by key<commit_after><?php

/**
 * This file is part of the miBadger package.
 *
 * @author <NAME> <<EMAIL>>
 * @license http://opensource.org/licenses/Apache-2.0 Apache v2 License
 * @version 1.0.0
 */

namespace miBadger\ActiveRecord;

/**
 * The abstract active record search class.
 *
 * @since 1.0.0
 */
abstract class AbstractActiveRecordSearch extends AbstractActiveRecord
{
	/**
	 * {@inheritdoc}
	 */
	public function search($options = [])
	{
		try {
			$pdoStatement = $this->getPdo()->prepare($this->getSearchQuery($options));
			array_walk_recursive($options, function(&$value) use ($pdoStatement) {
				static $index = 1;

				$pdoStatement->bindParam($index++, $value);
			});

			$pdoStatement->execute();
			$result = [];

			while ($fetch = $pdoStatement->fetch()) {
				$new = new static($this->getPdo());

				$new->setId(intval($fetch['id']));
				$new->setActiveRecordData($fetch);

				$result[] = $new;
			}

			return $result;
		} catch (\PDOException $e) {
			throw new ActiveRecordException(sprintf('Can not search the record in the `%s` table.', $this->getActiveRecordName()), 0, $e);
		}
	}

	/**
	 * Returns the search query with the given options.
	 *
	 * @param array $options = []
	 * @return string the search query with the given options.
	 */
	private function getSearchQuery($options = [])
	{
		$columns = array_keys($this->getActiveRecordData());
		$columns[] = 'id';
		$values = [];

		foreach ($options as $key => $value) {
			if (!in_array($key, $columns)) {
				throw new ActiveRecordException(sprintf('Search option key `%s` does not exists.', $key));
			}

			if (is_numeric($value)) {
				$values[] = sprintf('%s = ?', $this->getPdo()->quote($key));
			} elseif (is_string($value)) {
				$values[] = sprintf('%s LIKE ?', $this->getPdo()->quote($key));
			} elseif (is_null($value)) {
				$values[] = sprintf('%s IS ?', $this->getPdo()->quote($key));
			} elseif (is_array($value) && !empty($value)) {
				$values[] = sprintf('%s IN (%s)', $this->getPdo()->quote($key), implode(',', array_fill(0, count($value), '?')));
			} else {
				throw new ActiveRecordException(sprintf('Search option value of key `%s` is not supported.', $this->getActiveRecordName()));
			}
		}

		return sprintf('SELECT * FROM `%s` %s', $this->getActiveRecordName(), empty($values) ? '' : 'WHERE ' . implode(' AND ', $values));
	}
}

{'fraction_non_alphanumeric': 0.19982698961937717, 'fraction_numerical': 0.005190311418685121, 'mean_word_length': 3.7631307929969102, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 45, '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': '1346465', 'n_tokens_mistral': 1715, 'n_tokens_neox': 1526, 'n_words': 357}