Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Amegatron committed Jun 22, 2014
0 parents commit b92149f
Show file tree
Hide file tree
Showing 16 changed files with 492 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/vendor
composer.phar
composer.lock
.DS_Store
14 changes: 14 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
language: php

php:
- 5.3
- 5.4
- 5.5
- 5.6
- hhvm

before_script:
- composer self-update
- composer install --prefer-source --no-interaction --dev

script: phpunit
98 changes: 98 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# Localized Carbon

+ [Introduction](#intro)
+ [Usage](#usage)
+ [Supported languages](#languages)
+ [Extending](#extending)
+ [Contributing](#contributing)

<a name="intro"></a>
## Introduction

Localized Carbon is an extension of a popular Carbon package, designed specially for Laravel framework. By localization I mean its `diffForHumans` function, which returns a human-readable string of time interval.

<a name="usage"></a>
## Usage

Imagine you have a `Comment` model which has default timestamp fields. You want to display, how much time has gone since its `create_at` in a human-readable format. You can achieve it this way in your Blade template:

```
{{ LocalizedCarbon::instance($comment->created_at)->diffForHumans() }}
```

In this case the class will output something like "5 minutes ago". Note that for just an English version of the string original Carbon would be enough. This `LocalizedCarbon` is used to display the message in the current application language. For example, for Russian language it will display "5 минут назад".

As in original Carbon, `diffForHumans` functions has an optional first argument (which is another Carbon instance). It specified the time to which difference should be calculated. By default (a missing or `null` value) current time is used.

Also `LocalizedCarbon` adds an optional second argument, in which you may specify the desired language, or directly a `formatter` class which is used to format the difference-string (see [extending Localized Carbon](#extending)). By default current application language is used.

<a name="languages"></a>
## Supported languages

Current version of Localized Carbon ships with two localizations:

+ English
+ Russian

But it is extendable, so you may write and use your own localization without altering the contents of the package. See [extending Localized Carbon](#extending).

## Installation

Add the following requirement to your `composer.json`: `"laravelrus/localized-carbon": "dev-master"`.

Next, add package's Service Provider to `app/config/app.php` in `providers` section:

```
'Laravelrus\LocalizedCarbon\LocalizedCarbonServiceProvider',
```

After that you may want to add some Aliases (`aliases` section of the same config):

```
'LocalizedCarbon' => 'Laravelrus\LocalizedCarbon\LocalizedCarbon',
'DiffFormatter' => 'Laravelrus\LocalizedCarbon\DiffFactoryFacade',
```

Note that `DiffFormatter` will only be used for extending default localizations. See [extending Localized Carbon](#extending).

<a name="extending"></a>
## Extending Localized Carbon

If needed localization is not shipped with this package, you may write your own and extend Localized Carbon with it, not even touching the vendor folder itself.

For this you should first write your `DiffFormatter` class, implementing `Laravelrus\LocalizedCarbon\DiffFormatters\DiffFormatterInterface`. This interface forces the class to have a single `format` method which looks like this:

```
public function format($isNow, $isFuture, $delta, $unit);
```

`$isNow` is a boolean, which is `true` when the time difference is calculated relevant to current time.
`$isFuture` is boolean, which is `true` if the DateTime object is in the future relevant to comparable time.
`$delta` is an integer, equals to number of units of difference.
`$unit` is a time-"unit". It can be either: `second`, `minute`, `hour`, `day`, `week`, `month` or `year`.

So, your `format` method should return a string based on this arguments. As an example see an existing DiffFormatters in `vendor\laravelrus\localized-carbon\src\Laravelrus\LocalizedCarbon\DiffFormatters` directory. You can also reference a lang-files, using `Lang::choice` as it is done in Russian localization for example.

When your class is ready, you must register it within the Localized Carbon. For this you must call `DiffFormatter::extend` method from within ane file which is loaded by the framework. For example, you can do it somewhere in `app/start/global.php`.

The `extend` method expects two parameters: first is the language you want to be supported (most often it would be `App::getLocale()` if you want just to use application's language). Next is the instance of your formatter, OR just a name of the class if it can be autoloaded. Consider these examples:

```
$formatter = new Acme\DiffFormatters\FrDiffFormatter;
DiffFormatter::extend('fr', $formatter);
// OR
DiffFormatter::extend('fr', 'Acme\\DiffFormatters\\FrDiffFormatter');
```

In the latter case the formatter will be autoloaded when it is needed using IoC. Also note that formatter is loaded only once during application life-cycle due to optimization considerations.

<a name="contributing"></a>
## Contributing

If you've written a formatter for the language which is not supported by current version of Localized Carbon out of the box - feel free to make a pull request with it, but be sure to adjust your formatter for been used by the package.

The formatter should lie in `src/Laravelrus/LocalizedCarbon/DiffFormatters` directory, following a simple naming convention: the class name should start with the desired language in lower-case, but the first letter in upper-case. The rest part of the name should be "DiffFormatter". The file name should correspond to the class name.

For example, the formatter for `fr` language would lie in `src/Laravelrus/LocalizedCarbon/DiffFormatters/FrDiffFormatter.php`, and the class name would be `FrDiffFormatter`.
21 changes: 21 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "laravelrus/localized-carbon",
"description": "A localizable version of Carbon",
"keywords": ["laravel", "carbon", "datetime", "date", "time"],
"authors": [
{
"name": "Aleksandr Egorov",
"email": "[email protected]"
}
],
"require": {
"php": ">=5.4.0",
"illuminate/support": "4.2.*"
},
"autoload": {
"psr-0": {
"Laravelrus\\LocalizedCarbon\\": "src/"
}
},
"minimum-stability": "stable"
}
98 changes: 98 additions & 0 deletions docs/README-ru.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# Localized Carbon

+ [Вступление](#intro)
+ [Использование](#usage)
+ [Поддерживаемые языки](#languages)
+ [Расширение пакета](#extending)
+ [Вклад в развитие пакета](#contributing)

<a name="intro"></a>
## Вступление

`Localized Carbon` - это расширение популярного пакета `Carbon`. Оно предназначено для использования исключительно во фреймворке Laravel. Под локализацией подразумевается локализация функции `diffForHumans` оригинального Carbon'а, предназначенная для вывода удобочитамой разницы в датах.

<a name="usage"></a>
## Использование

Представте, что у вас есть модель `Comment` (комментарий), в которой имеются временные поля по умолчанию (`created_at` и `updated_at`). И вам требуется вывести информацию о том, сколько времени прошло с момента создания комментария (поле `created_at`), в удобочитаемом формате. Это можно сделать следующим образом в Blade-шаблоне:

```
{{ LocalizedCarbon::instance($comment->created_at)->diffForHumans() }}
```

В этом случае класс выведет что-то вроде "5 минут назад" для русского языка.

Как и в исходном Carbon'е, метод `diffForHumans` имеет первый необязательный аргумент (который является другим экземпляром класса `Carbon`). Он указывает время, относительно которого вычислять разницу. По умолчанию (если этот параметр не задан, или равен `null`) используется текущее время.

В методе классе `LocalizedCarbon` имеется и второе необязательный аргумент, в котором вы можете указать желаемый язык, или напрямую класс-форматтер, используемый для формирования строки-разницы между временами (см. [расширение](#extending)). По умолчанию будет использоваться текущий язык приложения.

<a name="languages"></a>
## Поддерживаемые языки

Текущая версия Localized Carbon поставляетс со следующими локализациями:

+ Английский
+ Русский

Но пакет расширяем, то есть вы можете написать и использоваться свою собственную локализацию, не трогая само содержимое пакета. См. [расширение пакета](#extending).

## Установка

Добавте следующее определение в секуцию `require` файла `composer.json` вашего проекта: `"laravelrus/localized-carbon": "dev-master"`.

Далее нужно добавить сервис провайдер (Service Provider), поставляемый с пакетом, в раздел `providers` файла `app/config/app.php`:

```
'Laravelrus\LocalizedCarbon\LocalizedCarbonServiceProvider',
```

После этого рекомендуется добавить следующие алиасы (секция `aliases` того же конфига):

```
'LocalizedCarbon' => 'Laravelrus\LocalizedCarbon\LocalizedCarbon',
'DiffFormatter' => 'Laravelrus\LocalizedCarbon\DiffFactoryFacade',
```

Стоит отметить, что класс `DiffFormatter` будет использоваться только для расширения пакета дополнительными локализациями. См. [расширение пакета](#extending).

<a name="extending"></a>
## Расширение пакета

Если требуемая локализация не поствляется с пакетом, вы можете написать свою собственную и расширить пакет, не трогая его содержимое.

Для этого нужно сперва написать свой класс `DiffFormatter`, который реализует интерфейс `Laravelrus\LocalizedCarbon\DiffFormatters\DiffFormatterInterface`. Этот интерфейс требует от класса реализовать единственный метод `format`, который имеет следующий вид:

```
public function format($isNow, $isFuture, $delta, $unit);
```

+ `$isNow` - это флаг, который равен `true`, если разница во времени вычисляется относительно текущего времени.
+ `$isFuture` - это флаг, который равен `true`, если время находится в будущем относительно проверяемого времени.
+ `$delta` - это число, содержащее разницу во времени в единицах, указанных в `$unit`.
+ `$unit` - это единица измерения параметра `$delta`. Может принимать одно из следующих значений: `second` (секунды), `minute` (минуты), `hour` (часы), `day` (дни), `week` (недели), `month` (месяцы) или `year` (года).

Таким образом, ваш метод `format` должен возвращать строку, сформированную на основе этих аргументов. Для примера смотрите существующие форметтеры в директории `vendor\laravelrus\localized-carbon\src\Laravelrus\LocalizedCarbon\DiffFormatters`. Вы также можете например ссылаться на языковые файлы, посредством `Lang::choice`, как это сделано, например, в русской локализации.

Как только ваш класс будет готов, нужно зарегистрировать его в пакете. Для этого нужно вызвать `DiffFormatter::extend` из любого файла, который подключается фреймворком. Например, это можно сделать где-нибудь в файле `app/start/global.php`.

Этот метод `extend` принимает два аргумента. Первый - это язык, для которого написан этот форматтер (чаще всего это будет `App::getLocale()`, если вы пишете локализацию для текущего языка приложения). Следующий аргумент - это экземпляр вашего класса, ЛИБО просто полное имя вашего класса, принимая во внимание то, что он должен быть доступен для автозагрузки. Взгляните на примеры:

```
$formatter = new Acme\DiffFormatters\FrDiffFormatter;
DiffFormatter::extend('fr', $formatter);
// ИЛИ
DiffFormatter::extend('fr', 'Acme\\DiffFormatters\\FrDiffFormatter');
```

В последнем случае форматтер будет автоматически загружен, как только в нем будет необходимость (посредством IoC). Имейте также ввиду, что форматтер будет загружен только однажды за весь цикл приложениия из соображений оптимизации.

<a name="contributing"></a>
## Вклад в развитие пакета

Если вы написали локализацию для языка, которые не поставляется с текущей версией пакета, будет здорово, если вы сделаете pull request с ним, убедившись только, что вы "настроили" его для использования внутри пакета.

Форматтер должен находиться в директории `src/Laravelrus/LocalizedCarbon/DiffFormatters` и следовать следующим соглашениям: имя класса должно начинаться с языка, для которого он написан, в нижнем регистре, но первый символ - в верхнем. Осальная часть имени должна заканчиваться на `DiffFormatter`. Имя файла должно соответствовать имени класса.

Например, форматтер для языка `fr` (французский) будет находится в файле `src/Laravelrus/LocalizedCarbon/DiffFormatters/FrDiffFormatter.php`, а имя класса будет соответственно `FrDiffFormatter`.
18 changes: 18 additions & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="vendor/autoload.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false"
>
<testsuites>
<testsuite name="Package Test Suite">
<directory suffix=".php">./tests/</directory>
</testsuite>
</testsuites>
</phpunit>
15 changes: 15 additions & 0 deletions src/Laravelrus/LocalizedCarbon/DiffFactoryFacade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace Laravelrus\LocalizedCarbon;


use Illuminate\Support\Facades\Facade;

class DiffFactoryFacade extends Facade{
/**
* Get the registered name of the component.
*
* @return string
*/
protected static function getFacadeAccessor() { return 'difffactory'; }
}
55 changes: 55 additions & 0 deletions src/Laravelrus/LocalizedCarbon/DiffFormatterFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php namespace Laravelrus\LocalizedCarbon;

use Laravelrus\LocalizedCarbon\DiffFormatters\DiffFormatterInterface;

class DiffFormatterFactory {
protected $formatters = [];

public function extend($language, $formatter) {
$language = strtolower($language);
$this->formatters[$language] = $formatter;
}

public function get($language) {
$language = strtolower($language);

if (isset($this->formatters[$language])) {
$formatter = $this->formatters[$language];

if (is_string($formatter)) {
$formatter = \App::make($formatter);
}
} else {
$formatterClass = $this->getFormatterClassName($language);
try {
$formatter = \App::make($formatterClass);
} catch (\Exception $e) {
// In case desired formatter could not be loaded
// load a formatter for application's fallback locale
$language = $this->getFallbackLanguage();
$formatterClass = $this->getFormatterClassName($language);
$formatter = \App::make($formatterClass);
}
}

if (! $formatter instanceof DiffFormatterInterface) {
throw new \Exception('Formatter for language ' . $language . ' should implement DiffFormatterInterface.');
}

// Remember instance for further use
$this->extend($language, $formatter);

return $formatter;
}

protected function getFormatterClassName($language) {
$name = ucfirst(strtolower($language));
$name = 'Laravelrus\\LocalizedCarbon\\DiffFormatters\\' . $name . 'DiffFormatter';

return $name;
}

protected function getFallbackLanguage() {
return \Config::get('app.fallback_locale');
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php namespace Laravelrus\LocalizedCarbon\DiffFormatters;

interface DiffFormatterInterface {
public function format($isNow, $isFuture, $delta, $unit);
}
18 changes: 18 additions & 0 deletions src/Laravelrus/LocalizedCarbon/DiffFormatters/EnDiffFormatter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php namespace Laravelrus\LocalizedCarbon\DiffFormatters;


class EnDiffFormatter implements DiffFormatterInterface {

public function format($isNow, $isFuture, $delta, $unit) {
$txt = $delta . ' ' . $unit;
$txt .= $delta == 1 ? '' : 's';

if ($isNow) {
$txt .= ($isFuture) ? ' from now' : ' ago';
return $txt;
}

$txt .= ($isFuture) ? ' after' : ' before';
return $txt;
}
}
Loading

0 comments on commit b92149f

Please sign in to comment.