Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Tests

on:
push:
pull_request:

permissions:
contents: read

jobs:
test:
name: phpunit (${{ matrix.php }}, ${{ matrix.composer }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- php: '7.0'
composer: v2.2
- php: '8.5'
composer: latest
steps:
- uses: actions/checkout@v4
- uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
tools: composer:${{ matrix.composer }}
coverage: none
- run: composer update --prefer-dist --no-interaction --no-progress
- run: vendor/bin/phpunit
30 changes: 18 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ composer require jord-jd/php-languages

## Usage

First, you need to get a `Language` object. You can get object by
language name or ISO code. You can also find all languages that belong
to a particular family.
Get a `Language` object by its English name, native name, or ISO code. You can
also find every language in a family. Lookups trim surrounding whitespace and
are case-insensitive.

```php
use \JordJD\Languages\Language;
use JordJD\Languages\Language;

$language = Language::getByName('German');
$language = Language::getByNativeName('Deutsch');
Expand All @@ -26,17 +26,23 @@ $language = Language::getByIso639_2_t('deu');
$language = Language::getByIso639_2_b('ger');
$language = Language::getByIso639_3('deu');
$languages = Language::getByFamily('Indo-European');
$languages = Language::all();
```

The ISO methods also have aliases without underscores, such as
`Language::getByIso6391('de')` and `Language::getByIso6393('deu')`. A single
language lookup returns `null` when there is no match; family lookups return an
empty array.

Once you have your `Language` object, you can access its various public
properties to yield information about the language.

```php
echo $language->family; // German
echo $language->name; // Deutsch
echo $language->nativeName; // de
echo $language->iso639_1; // deu
echo $language->iso639_2_t; // ger
echo $language->iso639_2_b; // deu
echo $language->iso639_3; // Indo-European
```
echo $language->family; // Indo-European
echo $language->name; // German
echo $language->nativeName; // Deutsch
echo $language->iso639_1; // de
echo $language->iso639_2_t; // deu
echo $language->iso639_2_b; // ger
echo $language->iso639_3; // deu
```
17 changes: 13 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,26 @@
],
"autoload": {
"psr-4": {
"JordJD\\Languages\\": "./src/"
"JordJD\\Languages\\": "src/"
}
},
"require": {},
"require": {
"php": ">=7.0"
},
"replace": {
"divineomega/php-languages": "self.version"
},
"extra": {
"branch-alias": {
"dev-master": "3.0-dev"
"dev-master": "3.1-dev"
}
},
"require-dev": {}
"require-dev": {
"phpunit/phpunit": "^6.5||^9.6||^10.5||^11.5||^12.5"
},
"config": {
"allow-plugins": {
"kylekatarnls/update-helper": false
}
}
}
8 changes: 8 additions & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="vendor/autoload.php" colors="true">
<testsuites>
<testsuite name="PHP Languages">
<directory>tests</directory>
</testsuite>
</testsuites>
</phpunit>
222 changes: 222 additions & 0 deletions src/Language.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
<?php

namespace JordJD\Languages;

class Language
{
/** @var string */
public $family;

/** @var string */
public $name;

/** @var string */
public $nativeName;

/** @var string */
public $iso639_1;

/** @var string */
public $iso639_2_t;

/** @var string */
public $iso639_2_b;

/** @var string */
public $iso639_3;

/** @var Language[]|null */
private static $languages;

/**
* Get every language in the bundled data set.
*
* Fresh objects are returned so callers cannot mutate future lookup results.
*
* @return Language[]
*/
public static function all()
{
return array_map(function (Language $language) {
return clone $language;
}, self::languages());
}

/**
* @return Language[]
*/
private static function languages()
{
if (self::$languages !== null) {
return self::$languages;
}

$filename = __DIR__.'/../resources/languages.csv';
$handle = @fopen($filename, 'r');

if ($handle === false) {
throw new \RuntimeException('Unable to read the bundled language data.');
}

self::$languages = [];
$rowNumber = 0;

try {
while (($row = fgetcsv($handle, 0, ',', '"', '\\')) !== false) {
++$rowNumber;

if ($rowNumber === 1) {
continue;
}

if (count($row) !== 7) {
throw new \RuntimeException('Invalid bundled language data on CSV row '.$rowNumber.'.');
}

$language = new self();
$language->family = trim($row[0]);
$language->name = trim($row[1]);
$language->nativeName = trim($row[2]);
$language->iso639_1 = trim($row[3]);
$language->iso639_2_t = trim($row[4]);
$language->iso639_2_b = trim($row[5]);
$language->iso639_3 = trim($row[6]);

self::$languages[] = $language;
}
} finally {
fclose($handle);
}

return self::$languages;
}

/**
* @param string $field
* @param string $value
*
* @return Language|null
*/
private static function getBy($field, $value)
{
$matches = self::getMultipleBy($field, $value);

return isset($matches[0]) ? $matches[0] : null;
}

/**
* @param string $field
* @param string $value
*
* @return Language[]
*/
private static function getMultipleBy($field, $value)
{
$matches = [];
$value = trim($value);

foreach (self::languages() as $language) {
if (strcasecmp($language->$field, $value) === 0) {
$matches[] = clone $language;
}
}

return $matches;
}

/**
* @return Language[]
*/
public static function getByFamily(string $family)
{
return self::getMultipleBy('family', $family);
}

/**
* @return Language|null
*/
public static function getByName(string $name)
{
return self::getBy('name', $name);
}

/**
* @return Language|null
*/
public static function getByNativeName(string $nativeName)
{
return self::getBy('nativeName', $nativeName);
}

/**
* @return Language|null
*/
public static function getByIso639_1(string $iso639_1)
{
return self::getBy('iso639_1', $iso639_1);
}

/**
* @return Language|null
*/
public static function getByIso639_2_t(string $iso639_2_t)
{
return self::getBy('iso639_2_t', $iso639_2_t);
}

/**
* @return Language|null
*/
public static function getByIso639_2_b(string $iso639_2_b)
{
return self::getBy('iso639_2_b', $iso639_2_b);
}

/**
* @return Language|null
*/
public static function getByIso639_3(string $iso639_3)
{
return self::getBy('iso639_3', $iso639_3);
}

/**
* Alias using a method name without underscores.
*
* @return Language|null
*/
public static function getByIso6391(string $iso639_1)
{
return self::getByIso639_1($iso639_1);
}

/**
* Alias using a method name without underscores.
*
* @return Language|null
*/
public static function getByIso6392T(string $iso639_2_t)
{
return self::getByIso639_2_t($iso639_2_t);
}

/**
* Alias using a method name without underscores.
*
* @return Language|null
*/
public static function getByIso6392B(string $iso639_2_b)
{
return self::getByIso639_2_b($iso639_2_b);
}

/**
* Alias using a method name without underscores.
*
* @return Language|null
*/
public static function getByIso6393(string $iso639_3)
{
return self::getByIso639_3($iso639_3);
}
}
Loading
Loading