pluralizer.php 3.38 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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
<?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.
	 *
	 * @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
51
		// If the word is English, we'll just pass off the word to the automatic
52 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
		// 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
80
		// If the word is English, we'll just pass off the word to the automatic
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
		// 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.
102
		if (in_array(Str::lower($value), $this->config['uncountable']))
103 104 105 106
		{
			return $value;
		}

Chris Berthe committed
107
		// Next, we will check the "irregular" patterns, which contain words
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
		// 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);
			}
		}
	}

}