pluralizer.php 3.41 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
<?php namespace Laravel;

class Pluralizer {

	/**
	 * The "strings" configuration array.
	 *
	 * @var array
	 */
	protected $config;

	/**
	 * The cached copies of the plural inflections.
	 */
	protected $plural = array();

	/**
	 * The cached copies of the singular inflections.
	 *
	 * @var array
	 */
	protected $singular = array();

	/**
	 * Create a new pluralizer instance.
	 *
Sergii Grebeniuk committed
27
	 * @param  array  $config
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
	 * @return void
	 */
	public function __construct($config)
	{
		$this->config = $config;
	}

	/**
	 * Get the singular form of the given word.
	 *
	 * @param  string  $value
	 * @return string
	 */
	public function singular($value)
	{
		// First we'll check the cache of inflected values. We cache each word that
		// is inflected so we don't have to spin through the regular expressions
		// each time we need to inflect a given value for the developer.
		if (isset($this->singular[$value]))
		{
			return $this->singular[$value];
		}

		// English words may be automatically inflected using regular expressions.
Chris Berthe committed
52
		// If the word is English, we'll just pass off the word to the automatic
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
		// inflection method and return the result, which is cached.
		$irregular = $this->config['irregular'];

		$result = $this->auto($value, $this->config['singular'], $irregular);

		return $this->singular[$value] = $result ?: $value;
	}

	/**
	 * Get the plural form of the given word.
	 *
	 * @param  string  $value
	 * @param  int     $count
	 * @return string
	 */
	public function plural($value, $count = 2)
	{
		if ((int) $count == 1) return $value;

		// First we'll check the cache of inflected values. We cache each word that
		// is inflected so we don't have to spin through the regular expressions
		// each time we need to inflect a given value for the developer.
		if (isset($this->plural[$value]))
		{
			return $this->plural[$value];
		}

		// English words may be automatically inflected using regular expressions.
Chris Berthe committed
81
		// If the word is English, we'll just pass off the word to the automatic
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
		// inflection method and return the result, which is cached.
		$irregular = array_flip($this->config['irregular']);

		$result = $this->auto($value, $this->config['plural'], $irregular);

		return $this->plural[$value] = $result;
	}

	/**
	 * Perform auto inflection on an English word.
	 *
	 * @param  string  $value
	 * @param  array   $source
	 * @param  array   $irregular
	 * @return string
	 */
	protected function auto($value, $source, $irregular)
	{
		// If the word hasn't been cached, we'll check the list of words that
		// that are "uncountable". This should be a quick look up since we
		// can just hit the array directly for the value.
103
		if (in_array(Str::lower($value), $this->config['uncountable']))
104 105 106 107
		{
			return $value;
		}

Chris Berthe committed
108
		// Next, we will check the "irregular" patterns, which contain words
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
		// like "children" and "teeth" which can not be inflected using the
		// typically used regular expression matching approach.
		foreach ($irregular as $irregular => $pattern)
		{
			if (preg_match($pattern = '/'.$pattern.'$/i', $value))
			{
				return preg_replace($pattern, $irregular, $value);
			}
		}

		// Finally we'll spin through the array of regular expressions and
		// and look for matches for the word. If we find a match we will
		// cache and return the inflected value for quick look up.
		foreach ($source as $pattern => $inflected)
		{
			if (preg_match($pattern, $value))
			{
				return preg_replace($pattern, $inflected, $value);
			}
		}
	}

}