Autodoc
  • Namespace
  • Class
  • Tree

Namespaces

  • BlueTihi
    • Context
  • Brickrouge
    • Element
      • Nodes
    • Renderer
    • Widget
  • ICanBoogie
    • ActiveRecord
    • AutoConfig
    • CLDR
    • Composer
    • Core
    • Event
    • Exception
    • HTTP
      • Dispatcher
      • Request
    • I18n
      • Translator
    • Mailer
    • Modules
      • Taxonomy
        • Support
      • Thumbnailer
        • Versions
    • Object
    • Operation
      • Dispatcher
    • Prototype
    • Routes
    • Routing
      • Dispatcher
    • Session
  • Icybee
    • ActiveRecord
      • Model
    • ConfigOperation
    • Document
    • EditBlock
    • Element
      • ActionbarContextual
      • ActionbarSearch
      • ActionbarToolbar
    • FormBlock
    • Installer
    • ManageBlock
    • Modules
      • Articles
      • Cache
        • Collection
        • ManageBlock
      • Comments
        • ManageBlock
      • Contents
        • ManageBlock
      • Dashboard
      • Editor
        • Collection
      • Files
        • File
        • ManageBlock
      • Forms
        • Form
        • ManageBlock
      • I18n
      • Images
        • ManageBlock
      • Members
      • Modules
        • ManageBlock
      • Nodes
        • ManageBlock
        • Module
      • Pages
        • BreadcrumbElement
        • LanguagesElement
        • ManageBlock
        • NavigationBranchElement
        • NavigationElement
        • Page
        • PageController
      • Registry
      • Search
      • Seo
      • Sites
        • ManageBlock
      • Taxonomy
        • Terms
          • ManageBlock
        • Vocabulary
          • ManageBlock
      • Users
        • ManageBlock
        • NonceLogin
        • Roles
      • Views
        • ActiveRecordProvider
        • Collection
        • View
    • Operation
      • ActiveRecord
      • Constructor
      • Module
      • Widget
    • Rendering
  • None
  • Patron
  • PHP

Classes

  • ActiveRecord
  • Cache
  • Configs
  • Core
  • DateTime
  • Debug
  • DeleteOperation
  • Errors
  • Event
  • EventHook
  • Events
  • FileCache
  • FormattedString
  • Helpers
  • I18n
  • Image
  • Inflections
  • Inflector
  • Models
  • Module
  • Modules
  • Object
  • Operation
  • PingOperation
  • Prototype
  • Route
  • Routes
  • SaveOperation
  • Session
  • TimeZone
  • TimeZoneLocation
  • Uploaded
  • Vars
  • VarsIterator

Interfaces

  • StorageInterface
  • ToArray
  • ToArrayRecursive

Traits

  • PrototypeTrait
  • ToArrayRecursiveTrait

Exceptions

  • AlreadyAuthenticated
  • AuthenticationRequired
  • Exception
  • ModuleConstructorMissing
  • ModuleIsDisabled
  • ModuleNotDefined
  • OffsetError
  • OffsetNotDefined
  • OffsetNotReadable
  • OffsetNotWritable
  • PermissionRequired
  • PropertyError
  • PropertyIsReserved
  • PropertyNotDefined
  • PropertyNotReadable
  • PropertyNotWritable
  • RouteNotDefined
  • SecurityException

Constants

  • TOKEN_ALPHA
  • TOKEN_ALPHA_UPCASE
  • TOKEN_NUMERIC
  • TOKEN_SYMBOL
  • TOKEN_SYMBOL_WIDE

Functions

  • array_flatten
  • array_insert
  • array_merge_recursive
  • camelize
  • capitalize
  • downcase
  • dump
  • escape
  • escape_all
  • exact_array_merge_recursive
  • excerpt
  • format
  • generate_token
  • generate_token_wide
  • generate_v4_uuid
  • get_autoconfig
  • humanize
  • hyphenate
  • log
  • log_error
  • log_info
  • log_success
  • log_time
  • normalize
  • normalize_namespace_part
  • normalize_url_path
  • pbkdf2
  • pluralize
  • remove_accents
  • shorten
  • singularize
  • sort_by_weight
  • stable_sort
  • strip_root
  • titleize
  • unaccent_compare
  • unaccent_compare_ci
  • underscore
  • upcase
  1 <?php
  2 
  3 /*
  4  * This file is part of the ICanBoogie package.
  5  *
  6  * (c) Olivier Laviale <olivier.laviale@gmail.com>
  7  *
  8  * For the full copyright and license information, please view the LICENSE
  9  * file that was distributed with this source code.
 10  */
 11 
 12 namespace ICanBoogie;
 13 
 14 /**
 15  * The Inflector transforms words from singular to plural, class names to table names, modularized
 16  * class names to ones without, and class names to foreign keys. Inflections can be localized, the
 17  * default english inflections for pluralization, singularization, and uncountable words are
 18  * kept in `lib/inflections/en.php`.
 19  *
 20  * @property-read Inflections $inflections Inflections used by the inflector.
 21  */
 22 class Inflector
 23 {
 24     static private $inflectors = array();
 25 
 26     /**
 27      * Returns an inflector for the specified locale.
 28      *
 29      * Note: Inflectors are shared for the same locale. If you need to alter an inflector you
 30      * MUST clone it first.
 31      *
 32      * @param string $locale
 33      *
 34      * @return \ICanBoogie\Inflector
 35      */
 36     static public function get($locale='en')
 37     {
 38         if (isset(self::$inflectors[$locale]))
 39         {
 40             return self::$inflectors[$locale];
 41         }
 42 
 43         return self::$inflectors[$locale] = new static(Inflections::get($locale));
 44     }
 45 
 46     /**
 47      * Inflections used by the inflector.
 48      *
 49      * @var Inflections
 50      */
 51     protected $inflections;
 52 
 53     /**
 54      * Initializes the {@link $inflections} property.
 55      *
 56      * @param Inflections $inflections
 57      */
 58     protected function __construct(Inflections $inflections=null)
 59     {
 60         $this->inflections = $inflections ?: new Inflections;
 61     }
 62 
 63     /**
 64      * Returns the {@link $inflections} property.
 65      *
 66      * @param string $property
 67      *
 68      * @throws PropertyNotDefined in attempt to read an unaccessible property. If the {@link PropertyNotDefined}
 69      * class is not available a {@link \InvalidArgumentException} is thrown instead.
 70      */
 71     public function __get($property)
 72     {
 73         static $readers = array('inflections');
 74 
 75         if (in_array($property, $readers))
 76         {
 77             return $this->$property;
 78         }
 79 
 80         if (class_exists('ICanBoogie\PropertyNotDefined'))
 81         {
 82             throw new PropertyNotDefined(array($property, $this));
 83         }
 84         else
 85         {
 86             throw new \InvalidArgumentException("Property not defined: $property");
 87         }
 88     }
 89 
 90     /**
 91      * Clone inflections.
 92      */
 93     public function __clone()
 94     {
 95         $this->inflections = clone $this->inflections;
 96     }
 97 
 98     /**
 99      * Applies inflection rules for {@link singularize} and {@link pluralize}.
100      *
101      * <pre>
102      * $this->apply_inflections('post', $this->plurals);    // "posts"
103      * $this->apply_inflections('posts', $this->singulars); // "post"
104      * </pre>
105      *
106      * @param string $word
107      * @param array $rules
108      *
109      * @return string
110      */
111     private function apply_inflections($word, array $rules)
112     {
113         $rc = (string) $word;
114 
115         if (!$rc)
116         {
117             return $rc;
118         }
119 
120         if (preg_match('/\b\w+\Z/', downcase($rc), $matches))
121         {
122             if (isset($this->inflections->uncountables[$matches[0]]))
123             {
124                 return $rc;
125             }
126         }
127 
128         foreach ($rules as $rule => $replacement)
129         {
130             $rc = preg_replace($rule, $replacement, $rc, -1, $count);
131 
132             if ($count) break;
133         }
134 
135         return $rc;
136     }
137 
138     /**
139      * Returns the plural form of the word in the string.
140      *
141      * <pre>
142      * $this->pluralize('post');       // "posts"
143      * $this->pluralize('children');   // "child"
144      * $this->pluralize('sheep');      // "sheep"
145      * $this->pluralize('words');      // "words"
146      * $this->pluralize('CamelChild'); // "CamelChild"
147      * </pre>
148      *
149      * @param string $word
150      *
151      * @return string
152      */
153     public function pluralize($word)
154     {
155         return $this->apply_inflections($word, $this->inflections->plurals);
156     }
157 
158     /**
159      * The reverse of {@link pluralize}, returns the singular form of a word in a string.
160      *
161      * <pre>
162      * $this->singularize('posts');         // "post"
163      * $this->singularize('childred');      // "child"
164      * $this->singularize('sheep');         // "sheep"
165      * $this->singularize('word');          // "word"
166      * $this->singularize('CamelChildren'); // "CamelChild"
167      * </pre>
168      *
169      * @param string $word
170      *
171      * @return string
172      */
173     public function singularize($word)
174     {
175         return $this->apply_inflections($word, $this->inflections->singulars);
176     }
177 
178     /**
179      * By default, {@link camelize} converts strings to UpperCamelCase.
180      *
181      * {@link camelize} will also convert "/" to "\" which is useful for converting paths to
182      * namespaces.
183      *
184      * <pre>
185      * $this->camelize('active_model');                // 'ActiveModel'
186      * $this->camelize('active_model', true);          // 'activeModel'
187      * $this->camelize('active_model/errors');         // 'ActiveModel\Errors'
188      * $this->camelize('active_model/errors', true);   // 'activeModel\Errors'
189      * </pre>
190      *
191      * As a rule of thumb you can think of {@link camelize} as the inverse of {@link underscore},
192      * though there are cases where that does not hold:
193      *
194      * <pre>
195      * $this->camelize($this->underscore('SSLError')); // "SslError"
196      * </pre>
197      *
198      * @param string $term
199      * @param bool $downcase_first_letter If `false` then {@link camelize} produces
200      * lowerCamelCase.
201      *
202      * @return string
203      */
204     public function camelize($term, $downcase_first_letter=false)
205     {
206         $string = (string) $term;
207         $acronyms = $this->inflections->acronyms;
208 
209         if ($downcase_first_letter)
210         {
211             $string = preg_replace_callback('/^(?:' . trim($this->inflections->acronym_regex, '/') . '(?=\b|[A-Z_])|\w)/', function($matches) {
212 
213                 return downcase($matches[0]);
214 
215             }, $string, 1);
216         }
217         else
218         {
219             $string = preg_replace_callback('/^[a-z\d]*/', function($matches) use($acronyms) {
220 
221                 $m = $matches[0];
222 
223                 return !empty($acronyms[$m]) ? $acronyms[$m] : capitalize($m);
224 
225             }, $string, 1);
226         }
227 
228         $string = preg_replace_callback('/(?:_|-|(\/))([a-z\d]*)/i', function($matches) use($acronyms) {
229 
230             list(, $m1, $m2) = $matches;
231 
232             return $m1 . (isset($acronyms[$m2]) ? $acronyms[$m2] : capitalize($m2));
233 
234         }, $string);
235 
236         $string = str_replace('/', '\\', $string);
237 
238         return $string;
239     }
240 
241     /**
242      * Makes an underscored, lowercase form from the expression in the string.
243      *
244      * Changes "\" to "/" to convert namespaces to paths.
245      *
246      * <pre>
247      * $this->underscore('ActiveModel');        // 'active_model'
248      * $this->underscore('ActiveModel\Errors'); // 'active_model/errors'
249      * </pre>
250      *
251      * As a rule of thumb you can think of {@link underscore} as the inverse of {@link camelize()},
252      * though there are cases where that does not hold:
253      *
254      * <pre>
255      * $this->camelize($this->underscore('SSLError')); // "SslError"
256      * </pre>
257      *
258      * @param string $camel_cased_word
259      *
260      * @return string
261      */
262     public function underscore($camel_cased_word)
263     {
264         $word = (string) $camel_cased_word;
265         $word = str_replace('\\', '/', $word);
266         $word = preg_replace_callback('/(?:([A-Za-z\d])|^)(' . trim($this->inflections->acronym_regex, '/') . ')(?=\b|[^a-z])/', function($matches) {
267 
268             list(, $m1, $m2) = $matches;
269 
270             return $m1 . ($m1 ? '_' : '') . downcase($m2);
271 
272         }, $word);
273 
274         $word = preg_replace('/([A-Z\d]+)([A-Z][a-z])/', '\1_\2', $word);
275         $word = preg_replace('/([a-z\d])([A-Z])/','\1_\2', $word);
276         $word = strtr($word, "-", "_");
277         $word = downcase($word);
278 
279         return $word;
280     }
281 
282     /**
283      * Capitalizes the first word and turns underscores into spaces and strips a trailing "_id",
284      * if any. Like {@link titleize()}, this is meant for creating pretty output.
285      *
286      * <pre>
287      * $this->humanize('employee_salary'); // "Employee salary"
288      * $this->humanize('author_id');       // "Author"
289      * </pre>
290      *
291      * @param string $lower_case_and_underscored_word
292      *
293      * @return string
294      */
295     public function humanize($lower_case_and_underscored_word)
296     {
297         $result = (string) $lower_case_and_underscored_word;
298 
299         foreach ($this->inflections->humans as $rule => $replacement)
300         {
301             $result = preg_replace($rule, $replacement, $result, 1, $count);
302 
303             if ($count) break;
304         }
305 
306         $acronyms = $this->inflections->acronyms;
307 
308         $result = preg_replace('/_id$/', "", $result);
309         $result = strtr($result, '_', ' ');
310         $result = preg_replace_callback('/([a-z\d]*)/i', function($matches) use($acronyms) {
311 
312             list($m) = $matches;
313 
314             return !empty($acronyms[$m]) ? $acronyms[$m] : downcase($m);
315         }, $result);
316 
317         $result = preg_replace_callback('/^\w/', function($matches) {
318 
319             return upcase($matches[0]);
320 
321         }, $result);
322 
323         return $result;
324     }
325 
326     /**
327      * Capitalizes all the words and replaces some characters in the string to create a nicer
328      * looking title. {@link titleize()} is meant for creating pretty output. It is not used in
329      * the Rails internals.
330      *
331      * <pre>
332      * $this->titleize('man from the boondocks');  // "Man From The Boondocks"
333      * $this->titleize('x-men: the last stand');   // "X Men: The Last Stand"
334      * $this->titleize('TheManWithoutAPast');      // "The Man Without A Past"
335      * $this->titleize('raiders_of_the_lost_ark'); // "Raiders Of The Lost Ark"
336      * </pre>
337      *
338      * @param string $str
339      *
340      * @return string
341      */
342     public function titleize($str)
343     {
344         $str = $this->underscore($str);
345         $str = $this->humanize($str);
346         $str = preg_replace_callback('/\b(?<![\'’`])[a-z]/', function($matches) {
347 
348             return capitalize($matches[0]);
349 
350         }, $str);
351 
352         return $str;
353     }
354 
355     /**
356      * Replaces underscores with dashes in the string.
357      *
358      * <pre>
359      * $this->dasherize('puni_puni'); // "puni-puni"
360      * </pre>
361      *
362      * @param string $underscored_word
363      *
364      * @return string
365      */
366     public function dasherize($underscored_word)
367     {
368         return strtr($underscored_word, '_', '-');
369     }
370 
371     /**
372      * Makes an hyphenated, lowercase form from the expression in the string.
373      *
374      * This is a combination of {@link underscore} and {@link dasherize}.
375      *
376      * @param string $str
377      *
378      * @return string
379      */
380     public function hyphenate($str)
381     {
382         return $this->dasherize($this->underscore($str));
383     }
384 
385     /**
386      * Returns the suffix that should be added to a number to denote the position in an ordered
387      * sequence such as 1st, 2nd, 3rd, 4th.
388      *
389      * <pre>
390      * $this->ordinal(1);     // "st"
391      * $this->ordinal(2);     // "nd"
392      * $this->ordinal(1002);  // "nd"
393      * $this->ordinal(1003);  // "rd"
394      * $this->ordinal(-11);   // "th"
395      * $this->ordinal(-1021); // "st"
396      * </pre>
397      */
398     public function ordinal($number)
399     {
400         $abs_number = abs($number);
401 
402         if (($abs_number % 100) > 10 && ($abs_number % 100) < 14)
403         {
404             return 'th';
405         }
406 
407         switch ($abs_number % 10)
408         {
409             case 1; return "st";
410             case 2; return "nd";
411             case 3; return "rd";
412             default: return "th";
413         }
414     }
415 
416     /**
417      * Turns a number into an ordinal string used to denote the position in an ordered sequence
418      * such as 1st, 2nd, 3rd, 4th.
419      *
420      * <pre>
421      * $this->ordinalize(1);     // "1st"
422      * $this->ordinalize(2);     // "2nd"
423      * $this->ordinalize(1002);  // "1002nd"
424      * $this->ordinalize(1003);  // "1003rd"
425      * $this->ordinalize(-11);   // "-11th"
426      * $this->ordinalize(-1021); // "-1021st"
427      * </pre>
428      */
429     public function ordinalize($number)
430     {
431         return $number . $this->ordinal($number);
432     }
433 }
Autodoc API documentation generated by ApiGen 2.8.0