Viewing file: SpdxLicenses.php (9.63 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php
/* * This file is part of composer/spdx-licenses. * * (c) Composer <https://github.com/composer> * * For the full copyright and license information, please view * the LICENSE file that was distributed with this source code. */
namespace Composer\Spdx;
class SpdxLicenses { /** @var string */ const LICENSES_FILE = 'spdx-licenses.json';
/** @var string */ const EXCEPTIONS_FILE = 'spdx-exceptions.json';
/** * Contains all the licenses. * * The array is indexed by license identifiers, which contain * a numerically indexed array with license details. * * [ lowercased license identifier => * [ 0 => identifier (string), 1 => full name (string), 2 => osi certified (bool), 3 => deprecated (bool) ] * , ... * ] * * @var array<string, array{0: string, 1: string, 2: bool, 3: bool}> */ private $licenses;
/** * @var string */ private $licensesExpression;
/** * Contains all the license exceptions. * * The array is indexed by license exception identifiers, which contain * a numerically indexed array with license exception details. * * [ lowercased exception identifier => * [ 0 => exception identifier (string), 1 => full name (string) ] * , ... * ] * * @var array<string, array{0: string, 1: string}> */ private $exceptions;
/** * @var string */ private $exceptionsExpression;
public function __construct() { $this->loadLicenses(); $this->loadExceptions(); }
/** * Returns license metadata by license identifier. * * This function adds a link to the full license text to the license metadata. * The array returned is in the form of: * * [ 0 => full name (string), 1 => osi certified, 2 => link to license text (string), 3 => deprecation status (bool) ] * * @param string $identifier * * @return array{0: string, 1: bool, 2: string, 3: bool}|null */ public function getLicenseByIdentifier($identifier) { $key = strtolower($identifier);
if (!isset($this->licenses[$key])) { return null; }
list($identifier, $name, $isOsiApproved, $isDeprecatedLicenseId) = $this->licenses[$key];
return array( $name, $isOsiApproved, 'https://spdx.org/licenses/' . $identifier . '.html#licenseText', $isDeprecatedLicenseId, ); }
/** * Returns all licenses information, keyed by the lowercased license identifier. * * @return array{0: string, 1: string, 2: bool, 3: bool}[] Each item is [ 0 => identifier (string), 1 => full name (string), 2 => osi certified (bool), 3 => deprecated (bool) ] */ public function getLicenses() { return $this->licenses; }
/** * Returns license exception metadata by license exception identifier. * * This function adds a link to the full license exception text to the license exception metadata. * The array returned is in the form of: * * [ 0 => full name (string), 1 => link to license text (string) ] * * @param string $identifier * * @return array{0: string, 1: string}|null */ public function getExceptionByIdentifier($identifier) { $key = strtolower($identifier);
if (!isset($this->exceptions[$key])) { return null; }
list($identifier, $name) = $this->exceptions[$key];
return array( $name, 'https://spdx.org/licenses/' . $identifier . '.html#licenseExceptionText', ); }
/** * Returns the short identifier of a license (or license exception) by full name. * * @param string $name * * @return string|null */ public function getIdentifierByName($name) { foreach ($this->licenses as $licenseData) { if ($licenseData[1] === $name) { return $licenseData[0]; } }
foreach ($this->exceptions as $licenseData) { if ($licenseData[1] === $name) { return $licenseData[0]; } }
return null; }
/** * Returns the OSI Approved status for a license by identifier. * * @param string $identifier * * @return bool */ public function isOsiApprovedByIdentifier($identifier) { return $this->licenses[strtolower($identifier)][2]; }
/** * Returns the deprecation status for a license by identifier. * * @param string $identifier * * @return bool */ public function isDeprecatedByIdentifier($identifier) { return $this->licenses[strtolower($identifier)][3]; }
/** * @param string[]|string $license * * @throws \InvalidArgumentException * * @return bool */ public function validate($license) { if (is_array($license)) { $count = count($license); if ($count !== count(array_filter($license, 'is_string'))) { throw new \InvalidArgumentException('Array of strings expected.'); } $license = $count > 1 ? '(' . implode(' OR ', $license) . ')' : (string) reset($license); }
if (!is_string($license)) { throw new \InvalidArgumentException(sprintf( 'Array or String expected, %s given.', gettype($license) )); }
return $this->isValidLicenseString($license); }
/** * @return string */ public static function getResourcesDir() { return dirname(__DIR__) . '/../data/Composer/res'; }
/** * @return void */ private function loadLicenses() { if (null !== $this->licenses) { return; }
$json = file_get_contents(self::getResourcesDir() . '/' . self::LICENSES_FILE); if (false === $json) { throw new \RuntimeException('Missing license file in ' . self::getResourcesDir() . '/' . self::LICENSES_FILE); } $this->licenses = array();
foreach (json_decode($json, true) as $identifier => $license) { $this->licenses[strtolower($identifier)] = array($identifier, $license[0], $license[1], $license[2]); } }
/** * @return void */ private function loadExceptions() { if (null !== $this->exceptions) { return; }
$json = file_get_contents(self::getResourcesDir() . '/' . self::EXCEPTIONS_FILE); if (false === $json) { throw new \RuntimeException('Missing exceptions file in ' . self::getResourcesDir() . '/' . self::EXCEPTIONS_FILE); } $this->exceptions = array();
foreach (json_decode($json, true) as $identifier => $exception) { $this->exceptions[strtolower($identifier)] = array($identifier, $exception[0]); } }
/** * @return string */ private function getLicensesExpression() { if (null === $this->licensesExpression) { $licenses = array_map('preg_quote', array_keys($this->licenses)); rsort($licenses); $licenses = implode('|', $licenses); $this->licensesExpression = $licenses; }
return $this->licensesExpression; }
/** * @return string */ private function getExceptionsExpression() { if (null === $this->exceptionsExpression) { $exceptions = array_map('preg_quote', array_keys($this->exceptions)); rsort($exceptions); $exceptions = implode('|', $exceptions); $this->exceptionsExpression = $exceptions; }
return $this->exceptionsExpression; }
/** * @param string $license * * @throws \RuntimeException * * @return bool */ private function isValidLicenseString($license) { if (isset($this->licenses[strtolower($license)])) { return true; }
$licenses = $this->getLicensesExpression(); $exceptions = $this->getExceptionsExpression();
$regex = <<<REGEX { (?(DEFINE) # idstring: 1*( ALPHA / DIGIT / - / . ) (?<idstring>[\pL\pN.-]{1,})
# license-id: taken from list (?<licenseid>${licenses})
# license-exception-id: taken from list (?<licenseexceptionid>${exceptions})
# license-ref: [DocumentRef-1*(idstring):]LicenseRef-1*(idstring) (?<licenseref>(?:DocumentRef-(?&idstring):)?LicenseRef-(?&idstring))
# simple-expresssion: license-id / license-id+ / license-ref (?<simple_expression>(?&licenseid)\+? | (?&licenseid) | (?&licenseref))
# compound-expression: 1*( # simple-expression / # simple-expression WITH license-exception-id / # compound-expression AND compound-expression / # compound-expression OR compound-expression # ) / ( compound-expression ) ) (?<compound_head> (?&simple_expression) ( \s+ WITH \s+ (?&licenseexceptionid))? | \( \s* (?&compound_expression) \s* \) ) (?<compound_expression> (?&compound_head) (?: \s+ (?:AND|OR) \s+ (?&compound_expression))? )
# license-expression: 1*1(simple-expression / compound-expression) (?<license_expression>(?&compound_expression) | (?&simple_expression)) ) # end of define
^(NONE | NOASSERTION | (?&license_expression))$ }xi REGEX;
$match = preg_match($regex, $license);
if (0 === $match) { return false; }
if (false === $match) { throw new \RuntimeException('Regex failed to compile/run.'); }
return true; } }
|