Humanize values that are readable only for developers.

Overview

PHP Humanizer

Tests Latest Stable Version Total Downloads Latest Unstable Version License

Tests

  • Build Status - 4.x

Readme for 4.x version

Humanize values to make them readable for regular people ;)

Installation

Run the following command:

composer require coduo/php-humanizer

Usage

Text

Humanize

use Coduo\PHPHumanizer\StringHumanizer;

StringHumanizer::humanize('field_name'); // "Field Name"
StringHumanizer::humanize('user_id'); // "User"
StringHumanizer::humanize('field_name', false); // "field name"

Truncate

Truncate string to word closest to a certain length

use Coduo\PHPHumanizer\StringHumanizer;

$text = 'Lorem ipsum dolorem si amet, lorem ipsum. Dolorem sic et nunc.';

StringHumanizer::truncate($text, 8); // "Lorem ipsum"
StringHumanizer::truncate($text, 8, '...'); // "Lorem ipsum..."
StringHumanizer::truncate($text, 2); // "Lorem"
StringHumanizer::truncate($text, strlen($text)); // "Lorem ipsum dolorem si amet, lorem ipsum. Dolorem sic et nunc."

Truncate HTML

Truncate and HTML string to word closest to a certain length

use Coduo\PHPHumanizer\StringHumanizer;

$text = '<p><b>HyperText Markup Language</b>, commonly referred to as <b>HTML</b>, is the standard <a href="/wiki/Markup_language" title="Markup language">markup language</a> used to create <a href="/wiki/Web_page" title="Web page">web pages</a>.<sup id="cite_ref-1" class="reference"><a href="#cite_note-1"><span>[</span>1<span>]</span></a></sup> <a href="/wiki/Web_browser" title="Web browser">Web browsers</a> can read HTML files and render them into visible or audible web pages. HTML describes the structure of a <a href="/wiki/Website" title="Website">website</a> <a href="/wiki/Semantic" title="Semantic" class="mw-redirect">semantically</a> along with cues for presentation, making it a markup language, rather than a <a href="/wiki/Programming_language" title="Programming language">programming language</a>.</p>';

StringHumanizer::truncateHtml($text, 3); // "<b>HyperText</b>"
StringHumanizer::truncateHtml($text, 12, ''); // "HyperText Markup"
StringHumanizer::truncateHtml($text, 50, '', '...'); // "HyperText Markup Language, commonly referred to as..."
StringHumanizer::truncateHtml($text, 75, '<b><i><u><em><strong><a><span>', '...'); // '<b>HyperText Markup Language</b>, commonly referred to as <b>HTML</b>, is the standard <a href="/wiki/Markup_language" title="Markup language">markup...</a>'

Remove shortcodes

$text = 'A text with [short]random[/short] [codes]words[/codes].';
StringHumanizer::removeShortcodes($text); // "A text with ."
StringHumanizer::removeShortcodeTags($text); // "A text with random words."

Number

Ordinalize

use Coduo\PHPHumanizer\NumberHumanizer;

NumberHumanizer::ordinalize(0); // "0th"
NumberHumanizer::ordinalize(1); // "1st"
NumberHumanizer::ordinalize(2); // "2nd"
NumberHumanizer::ordinalize(23); // "23rd"
NumberHumanizer::ordinalize(1002, 'nl'); // "1002e"
NumberHumanizer::ordinalize(-111); // "-111th"

Ordinal

use Coduo\PHPHumanizer\NumberHumanizer;

NumberHumanizer::ordinal(0); // "th"
NumberHumanizer::ordinal(1); // "st"
NumberHumanizer::ordinal(2); // "nd"
NumberHumanizer::ordinal(23); // "rd"
NumberHumanizer::ordinal(1002); // "nd"
NumberHumanizer::ordinal(-111, 'nl'); // "e"

Roman numbers

use Coduo\PHPHumanizer\NumberHumanizer;

NumberHumanizer::toRoman(1); // "I"
NumberHumanizer::toRoman(5); // "V"
NumberHumanizer::toRoman(1300); // "MCCC"

NumberHumanizer::fromRoman("MMMCMXCIX"); // 3999
NumberHumanizer::fromRoman("V"); // 5
NumberHumanizer::fromRoman("CXXV"); // 125

Binary Suffix

Convert a number of bytes in to the highest applicable data unit

use Coduo\PHPHumanizer\NumberHumanizer;

NumberHumanizer::binarySuffix(0); // "0 bytes"
NumberHumanizer::binarySuffix(1); // "1 bytes"
NumberHumanizer::binarySuffix(1024); // "1 kB"
NumberHumanizer::binarySuffix(1025); // "1 kB"
NumberHumanizer::binarySuffix(1536); // "1.5 kB"
NumberHumanizer::binarySuffix(1048576 * 5); // "5 MB"
NumberHumanizer::binarySuffix(1073741824 * 2); // "2 GB"
NumberHumanizer::binarySuffix(1099511627776 * 3); // "3 TB"
NumberHumanizer::binarySuffix(1325899906842624); // "1.18 PB"

Number can be also formatted for specific locale

use Coduo\PHPHumanizer\NumberHumanizer;

NumberHumanizer::binarySuffix(1536, 'pl'); // "1,5 kB"

Number can also be humanized with a specific number of decimal places with preciseBinarySuffix($number, $precision, $locale = 'en') The precision parameter must be between 0 and 3.

use Coduo\PHPHumanizer\NumberHumanizer;

NumberHumanizer::preciseBinarySuffix(1024, 2); // "1.00 kB"
NumberHumanizer::preciseBinarySuffix(1325899906842624, 3); // "1.178 PB"

This function also supports locale

use Coduo\PHPHumanizer\NumberHumanizer;

NumberHumanizer::preciseBinarySuffix(1325899906842624, 3, 'pl'); // "1,178 PB"

Metric Suffix

use Coduo\PHPHumanizer\NumberHumanizer;

NumberHumanizer::metricSuffix(-1); // "-1"
NumberHumanizer::metricSuffix(0); // "0"
NumberHumanizer::metricSuffix(1); // "1"
NumberHumanizer::metricSuffix(101); // "101"
NumberHumanizer::metricSuffix(1000); // "1k"
NumberHumanizer::metricSuffix(1240); // "1.2k"
NumberHumanizer::metricSuffix(1240000); // "1.24M"
NumberHumanizer::metricSuffix(3500000); // "3.5M"

Number can be also formatted for specific locale

use Coduo\PHPHumanizer\NumberHumanizer;

NumberHumanizer::metricSuffix(1240000, 'pl'); // "1,24M"

Collections

Oxford

use Coduo\PHPHumanizer\CollectionHumanizer;

CollectionHumanizer::oxford(['Michal', 'Norbert', 'Lukasz', 'Pawel'], 2); // "Michal, Norbert, and 2 others"
CollectionHumanizer::oxford(['Michal', 'Norbert', 'Lukasz'], 2); // "Michal, Norbert, and 1 other"
CollectionHumanizer::oxford(['Michal', 'Norbert']); // "Michal and Norbert"

Oxford is using translator component, so you can use whatever string format you like.

Date time

Difference

use Coduo\PHPHumanizer\DateTimeHumanizer;

DateTimeHumanizer::difference(new \DateTime("2014-04-26 13:00:00"), new \DateTime("2014-04-26 13:00:00")); // just now
DateTimeHumanizer::difference(new \DateTime("2014-04-26 13:00:00"), new \DateTime("2014-04-26 13:00:05")); // 5 seconds from now
DateTimeHumanizer::difference(new \DateTime("2014-04-26 13:00:00"), new \DateTime("2014-04-26 12:59:00")); // 1 minute ago
DateTimeHumanizer::difference(new \DateTime("2014-04-26 13:00:00"), new \DateTime("2014-04-26 12:45:00")); // 15 minutes ago
DateTimeHumanizer::difference(new \DateTime("2014-04-26 13:00:00"), new \DateTime("2014-04-26 13:15:00")); // 15 minutes from now
DateTimeHumanizer::difference(new \DateTime("2014-04-26 13:00:00"), new \DateTime("2014-04-26 14:00:00")); // 1 hour from now
DateTimeHumanizer::difference(new \DateTime("2014-04-26 13:00:00"), new \DateTime("2014-04-26 15:00:00")); // 2 hours from now
DateTimeHumanizer::difference(new \DateTime("2014-04-26 13:00:00"), new \DateTime("2014-04-26 12:00:00")); // 1 hour ago
DateTimeHumanizer::difference(new \DateTime("2014-04-26"), new \DateTime("2014-04-25")); // 1 day ago
DateTimeHumanizer::difference(new \DateTime("2014-04-26"), new \DateTime("2014-04-24")); // 2 days ago
DateTimeHumanizer::difference(new \DateTime("2014-04-26"), new \DateTime("2014-04-28")); // 2 days from now
DateTimeHumanizer::difference(new \DateTime("2014-04-01"), new \DateTime("2014-04-15")); // 2 weeks from now
DateTimeHumanizer::difference(new \DateTime("2014-04-15"), new \DateTime("2014-04-07")); // 1 week ago
DateTimeHumanizer::difference(new \DateTime("2014-01-01"), new \DateTime("2014-04-01")); // 3 months from now
DateTimeHumanizer::difference(new \DateTime("2014-05-01"), new \DateTime("2014-04-01")); // 1 month ago
DateTimeHumanizer::difference(new \DateTime("2015-05-01"), new \DateTime("2014-04-01")); // 1 year ago
DateTimeHumanizer::difference(new \DateTime("2014-05-01"), new \DateTime("2016-04-01")); // 2 years from now

Precise difference

use Coduo\PHPHumanizer\DateTimeHumanizer;

DateTimeHumanizer::preciseDifference(new \DateTime("2014-04-26 13:00:00"), new \DateTime("2014-04-25 11:20:00")); // 1 day, 1 hour, 40 minutes ago
DateTimeHumanizer::preciseDifference(new \DateTime("2014-04-26 13:00:00"), new \DateTime("2015-04-28 17:00:00")); // 1 year, 2 days, 4 hours from now
DateTimeHumanizer::preciseDifference(new \DateTime("2014-04-26 13:00:00"), new \DateTime("2016-04-27 13:00:00")); // 2 years, 1 day from now

Aeon Calendar

Aeon PHP is a date&time oriented set of libraries.

use Coduo\PHPHumanizer\DateTimeHumanizer;

$timeUnit = TimeUnit::days(2)
                ->add(TimeUnit::hours(3))
                ->add(TimeUnit::minutes(25))
                ->add(TimeUnit::seconds(30))
                ->add(TimeUnit::milliseconds(200));
            
DateTimeHumanizer::timeUnit($timeUnit); // 2 days, 3 hours, 25 minutes, and 30.2 seconds

Currently we support following languages:

Development

After downloading library update dependencies:

composer update

In order to check lowest possible versions of dependencies add

composer update --prefer-lowest

Execute test suite:

composer run test

Run CS Fixer

composer run cs:php:fix

Credits

This lib was inspired by Java Humanize Lib && Rails Active Support

Comments
  • TruncateHtml

    TruncateHtml

    I've implemented a html truncate based FuelPHP truncate function, with breakpoint management. I'm not exactly sure of the code style and hope it's okay.

    Changes

    This PR add a TruncateHTML class which extends from Truncate, it has the capability to truncate HTML by keeping some tags or removing them all together. It supports the breakpoints and append.

    This PR changes the Truncate class by changing the visibility of the properties are refactoring the breakpoint mechanism in order for it to be reusable.

    Code example

    use Coduo\PHPHumanizer\String;
    
    $text = '<p><b>HyperText Markup Language</b>, commonly referred to as <b>HTML</b>, is the standard <a href="/wiki/Markup_language" title="Markup language">markup language</a> used to create <a href="/wiki/Web_page" title="Web page">web pages</a>.<sup id="cite_ref-1" class="reference"><a href="#cite_note-1"><span>[</span>1<span>]</span></a></sup> <a href="/wiki/Web_browser" title="Web browser">Web browsers</a> can read HTML files and render them into visible or audible web pages. HTML describes the structure of a <a href="/wiki/Website" title="Website">website</a> <a href="/wiki/Semantic" title="Semantic" class="mw-redirect">semantically</a> along with cues for presentation, making it a markup language, rather than a <a href="/wiki/Programming_language" title="Programming language">programming language</a>.</p>';
    
    echo String::truncateHtml($text, 3); // "<b>HyperText</b>"
    echo String::truncateHtml($text, 12, ''); // "HyperText Markup"
    echo String::truncateHtml($text, 50, '', '...'); // "HyperText Markup Language, commonly referred to as..."
    echo String::truncateHtml($text, 75, '<b><i><u><em><strong><a><span>', '...'); // '<b>HyperText Markup Language</b>, commonly referred to as <b>HTML</b>, is the standard <a href="/wiki/Markup_language" title="Markup language">markup...</a>'
    
    
    opened by smeeckaert 20
  • Number::spell() - spell numbers as words

    Number::spell() - spell numbers as words

    Firstly, thanks for the project. It's nice idea to package this functionality up together in a lib. Definitely much nicer than the ball of utility functions I normally use.

    Would you be interested in adding this Number::toWords() function to the lib?

    Summary:

    • Convert '123' to 'one hundred and twenty-three'
    • Includes support for decimals and negatives
    • Includes tests
    • Credit to Karl Rixon for the original function (http://www.karlrixon.co.uk/writing/convert-numbers-to-words-with-php/)

    If you're interested in adding this function to php-humanizer would you prefer to see toWords as a function of String like BinarySuffix and MetricSuffix?

    Presumably this would also benefit from localisation, although I guess that could be problematic if other languages construct large numbers differently to English? I imagine the ordinalization could also face similar challenges. Again, if you're interested in adding this function I'm happy to add base support for the localisation, if you want it.

    feature request 
    opened by tommarshall 15
  • Add basic Russian support

    Add basic Russian support

    This commit adds basic Russian support to DateTimeDifference.

    However, fixes are required. The compound items are supposed to be different for "past" and "future" dates. For now they're translated as "past". Also, the "future" prefix (from_now) goes before the text:

    second:
      past: "%count% секунда назад|%count% секунды назад|%count% секунд назад"
      future: "через %count% секунду|через %count% секунды|через %count% секунд"
    

    The translation format is taken from Symfony/Component/Translation/PluralizationRules.php and has to be tested.

    opened by Forst 12
  • added phpunit tests and found a bug

    added phpunit tests and found a bug

    First I wanted to change the library to make it possible to call the methods non-statically, after doing so I could not figure out why phpspec was not throwing any errors as it should, so I rewrote all the specs in phpunit.

    Then I found out PHP allows you to call static methods non-statically so all my work was for nothing, or so I thought!

    phpunit found that the fromRoman method in the Number class was not static and so not allowed to be called statically.

    So, this pull request adds a lot of phpunit tests that found a bug that phpspec somehow missed and fixes a very tiny bug!

    opened by Zae 10
  • Add Spanish translation.

    Add Spanish translation.

    Initial work on a Spanish translation. There might be a problem with the way you generate the compound past/future in PreciseFormatter, which is always a suffix. In Spanish, we actually use a prefix. When I figure out a way of implementing it I'll send in another pull request.

    opened by orestes 8
  • Addition of Portuguese (pt) language translation (with spec tests)

    Addition of Portuguese (pt) language translation (with spec tests)

    Hi,

    In terms of context of the translations when you have the text:

    %count% seconds from now

    you mean the same as:

    in about %count% seconds

    or

    in %count% seconds

    Because the translation of the second sentence makes more sense to me in Portuguese and if it's the same for you I will change the texts.

    PS: I'm also getting some errors in the tests for Numbers in my machine but I will look into that later.

    opened by lightglitch 7
  • Division by zero

    Division by zero

    Hi,

    I'm facing an issue on PHP 5.5.9-1ubuntu4.19 (cli) when using NumberHumanizer::binarySuffix as I'm having a PHP warning saying Division by zero.

    I digged by myself and found that the array

    private $binaryPrefixes = array(
            1125899906842624 => '#.## PB',
            1099511627776 => '#.## TB',
            1073741824 => '#.## GB',
            1048576 => '#.## MB',
            1024 => '#.# kB',
            0 => '# bytes',
        );
    

    is actually returned such as

    Array
    (
        [0] => # bytes
        [1073741824] => #.## GB
        [1048576] => #.## MB
        [1024] => #.# kB
    )
    

    Did anyone faced this issue already?

    Thanks by the way

    require investigation 
    opened by mikaelcom 6
  • PHP 7 release

    PHP 7 release

    Is there a reason why still not exists 2.0 release? it will allow require this package recursively without downgrading stability settings, thanks. for ex.: my package A uses your package as a dependency (dev-master). when I try to require my package A with default minimum-stability "stable" it fails and I need to downgrade it up to "@dev".

    opened by endihunter 6
  • Support for IEC standard prefixes and suffix translation

    Support for IEC standard prefixes and suffix translation

    I would also being able to use the standard IEC binary prefixes such as "Mi" and "Gi" instead of "M" and "G" in BinarySuffix functions and to use a localized suffix as in french we commonly use "o" instead of "B" (we use "octet(s)" instead of "byte(s)"). I can understand that replacing "GB" by "GiB" by default is counterintuitive as it's not the most commonly used spelling so it could be achieved adding another parameter or usng a "tweaked" locale. The result could be something like this:

    echo Number::binarySuffix(1073741824 * 2); // "2 GiB"
    echo Number::binarySuffix(1073741824 * 2, 'en-iec'); // "2 GiB"
    echo Number::binarySuffix(1073741824 * 2, 'fr'); // "2 Go"
    echo Number::binarySuffix(1073741824 * 2, 'fr-iec'); // "2 Gio"
    
    feature request 
    opened by zebratrois 5
  • Support for optional explicit BinarySuffix precision

    Support for optional explicit BinarySuffix precision

    When humanizing a number of bytes into the largest possible unit (as the BinarySuffix humanizer already does) you may have differing requirements in the number of decimal places you wish to show.

    For example, you may which to truncate the result to a natural number if displaying the value within a paragraph or you may wish to show three decimal places if you want to still maintain information about the next largest unit.

    My change gives this functionality via an optional third precision parameter to Number::binarySuffix(). The parameter being optional means that the change is non-breaking.

    I have attempted to make the change in such as way that it will also be compatible with future updates to the existing hard-coded ICU 56.1 decimal formats used by BinarySuffix

    Lastly, I have also updated the README to include this new functionality and provided a similar test coverage to the existing functionality.

    opened by mostertb 5
  • Refactor Number into separate languages

    Refactor Number into separate languages

    The old Number\Ordinal is no longer directly responsible for the ordinal string generation. Instead, it'll use a dynamically included closure for that. Closures for English and Dutch are included.

    Intended as Proof of Concept, but I can see this working.

    Relates to #39

    opened by doenietzomoeilijk 5
  • Make the CollectionHumanizer::oxford to accept an \Iterator interface

    Make the CollectionHumanizer::oxford to accept an \Iterator interface

    What is the Idea?

    The idea is to improve the make Coduo\PHPHumanizer\CollectionHumanizer::oxford() accept an \Iterator interface instead of an array always. With this, We could send real collections, arrays, etc. To make it work, all We will need is to iterate it (call the array_map as it's being done) and rely on a possible toString implementation, in case it doesn't have OR the result of each iteration is not a string eligible/parseable, so, We just throw an exception.

    I can submit a PR with the idea if you guys agree with the improvement.

    opened by gabrielanhaia 4
Releases(4.0.3)
Owner
Coduo
Coduo
[ONLY Magento 2.0.x Compatible] Code samples for Magento developers

Synopsis This project is a collection of samples to demonstrate technologies introduced in Magento 2. You will find the most simple extension along wi

Magento 58 Dec 26, 2022
The easiest way to match data structures like JSON/PlainText/XML against readable patterns. Sandbox:

PHP Matcher Library created for testing all kinds of JSON/XML/TXT/Scalar values against patterns. API: PHPMatcher::match($value = '{"foo": "bar"}', $p

Coduo 774 Dec 31, 2022
🦉 human-readable regular expressions for PHP

RegExpBuilder integrates regular expressions into the programming language, thereby making them easy to read and maintain. Regular Expressions are created by using chained methods and variables such as arrays or strings.

Max Girkens 907 Dec 30, 2022
Clean Code concepts adapted for PHP - A guide for producing readable, reusable, and refactorable PHP software

Clean Code concepts adapted for PHP - A guide for producing readable, reusable, and refactorable PHP software

Fabio Soares 172 Dec 25, 2022
This component, based on the Symfony serializer and async-aws, is a human-readable and quick abstraction to easily store serialized objects in DynamoDB 🚀.

DynamoDB Storable This component, based on the Symfony serializer and async-aws, is a human-readable and quick abstraction to easily store serialized

Matthieu W. 2 Jun 19, 2022
A PHP package for MRZ (Machine Readable Zones) code parser for Passport, Visa & Travel Document (TD1 & TD2).

MRZ (Machine Readable Zones) Parser for PHP A PHP package for MRZ (Machine Readable Zones) code parser for Passport, Visa & Travel Document (TD1 & TD2

Md. Rakibul Islam 25 Aug 24, 2022
A wrapper around symplify/config-transformer used to update recipes and using easy coding standard for generating readable config files.

Symfony Recipes Yaml to PHP Converter This is a wrapper around the symplify/config-transformer used to convert Symfony core recipes which uses .yaml c

Alexander Schranz 3 Nov 24, 2022
Provides the functionality to compare PHP values for equality.

sebastian/comparator This component provides the functionality to compare PHP values for equality. Installation You can add this library as a local, p

Sebastian Bergmann 6.7k Jan 1, 2023
A PHP library to write values to .env (DotEnv) files

DotEnvWriter A PHP library to write values to .env (DotEnv) files Installation DotEnvWriter can be installed with Composer. composer require mirazmac/

Miraz Mac 9 May 24, 2022
Google-like values converter

Google-like values converter. Support for different types of conversions, for examples: 1 kilometer -> meters 1 dollar -> THB 1 kilogram -> meters ...

Pavinthan 1 Nov 4, 2021
Sanitize and escape every values in your PHP Application

PHP Sanitizer Sanitize and escape every values in your PHP Application. This solution will make PHP developer life easy, very easy and developers woul

Maniruzzaman Akash 10 Oct 2, 2022
Deeper is a easy way to compare if 2 objects is equal based on values in these objects. This library is heavily inspired in Golang's reflect.DeepEqual().

Deeper Deeper is a easy way to compare if 2 objects is equal based on values in these objects. This library is heavily inspired in Golang's reflect.De

Joubert RedRat 4 Feb 12, 2022
Composer plugin replacing placeholders in the scripts section by dynamic values

Composer Substitution Plugin The Composer Substitution plugin replaces placeholders in the scripts section by dynamic values. It also permits to cache

Fabien Villepinte 49 Jan 8, 2022
Read and show values from form valid

read-and-show-values-from-form-valid Escribe un programa PHP que permita al usuario rellenar un formulario de registro con los datos de nombre, contra

ManuMT 1 Jan 21, 2022
JSONFinder - a library that can find json values in a mixed text or html documents, can filter and search the json tree, and converts php objects to json without 'ext-json' extension.

JSONFinder - a library that can find json values in a mixed text or html documents, can filter and search the json tree, and converts php objects to json without 'ext-json' extension.

Eboubaker Eboubaker 2 Jul 31, 2022
Miniset allows you to create compact sets of fields that either combine into a string of classes, or return a simple array of values

Miniset allows you to create compact sets of fields that either combine into a string of classes, or return a simple array of values. Miniset

Jack Sleight 5 Jun 13, 2022
[READ-ONLY] CakePHP Utility classes such as Inflector, Text, Hash, Security and Xml. This repo is a split of the main code that can be found in https://github.com/cakephp/cakephp

CakePHP Utility Classes This library provides a range of utility classes that are used throughout the CakePHP framework What's in the toolbox? Hash A

CakePHP 112 Feb 15, 2022
The only way to implement the pipe operator in PHP.

Pipe Operator in PHP Introduction This package is based on the pipe operator RFC by Sara Golemon and Marcelo Camargo (2016), who explains the problem

BoostPHP 21 Nov 12, 2022
Enforce that your classes get only instantiated by the factories you define!

Enforce that your classes get only instantiated by the factories you define!

null 3 Nov 15, 2021