Pressroom template verwijderd, website naar root van repo

This commit is contained in:
2020-03-22 15:30:52 +01:00
parent 2cb6a77425
commit f3d1c41e91
7620 changed files with 0 additions and 186900 deletions

7
vendor/autoload.php vendored Normal file
View File

@@ -0,0 +1,7 @@
<?php
// autoload.php @generated by Composer
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInit5216a35d72a5119d2f4646cd700f802d::getLoader();

1
vendor/bin/php-parse vendored Symbolic link
View File

@@ -0,0 +1 @@
../nikic/php-parser/bin/php-parse

1
vendor/bin/phpunit vendored Symbolic link
View File

@@ -0,0 +1 @@
../phpunit/phpunit/phpunit

1
vendor/bin/psysh vendored Symbolic link
View File

@@ -0,0 +1 @@
../psy/psysh/bin/psysh

445
vendor/composer/ClassLoader.php vendored Normal file
View File

@@ -0,0 +1,445 @@
<?php
/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Composer\Autoload;
/**
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
*
* $loader = new \Composer\Autoload\ClassLoader();
*
* // register classes with namespaces
* $loader->add('Symfony\Component', __DIR__.'/component');
* $loader->add('Symfony', __DIR__.'/framework');
*
* // activate the autoloader
* $loader->register();
*
* // to enable searching the include path (eg. for PEAR packages)
* $loader->setUseIncludePath(true);
*
* In this example, if you try to use a class in the Symfony\Component
* namespace or one of its children (Symfony\Component\Console for instance),
* the autoloader will first look for the class under the component/
* directory, and it will then fallback to the framework/ directory if not
* found before giving up.
*
* This class is loosely based on the Symfony UniversalClassLoader.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Jordi Boggiano <j.boggiano@seld.be>
* @see http://www.php-fig.org/psr/psr-0/
* @see http://www.php-fig.org/psr/psr-4/
*/
class ClassLoader
{
// PSR-4
private $prefixLengthsPsr4 = array();
private $prefixDirsPsr4 = array();
private $fallbackDirsPsr4 = array();
// PSR-0
private $prefixesPsr0 = array();
private $fallbackDirsPsr0 = array();
private $useIncludePath = false;
private $classMap = array();
private $classMapAuthoritative = false;
private $missingClasses = array();
private $apcuPrefix;
public function getPrefixes()
{
if (!empty($this->prefixesPsr0)) {
return call_user_func_array('array_merge', $this->prefixesPsr0);
}
return array();
}
public function getPrefixesPsr4()
{
return $this->prefixDirsPsr4;
}
public function getFallbackDirs()
{
return $this->fallbackDirsPsr0;
}
public function getFallbackDirsPsr4()
{
return $this->fallbackDirsPsr4;
}
public function getClassMap()
{
return $this->classMap;
}
/**
* @param array $classMap Class to filename map
*/
public function addClassMap(array $classMap)
{
if ($this->classMap) {
$this->classMap = array_merge($this->classMap, $classMap);
} else {
$this->classMap = $classMap;
}
}
/**
* Registers a set of PSR-0 directories for a given prefix, either
* appending or prepending to the ones previously set for this prefix.
*
* @param string $prefix The prefix
* @param array|string $paths The PSR-0 root directories
* @param bool $prepend Whether to prepend the directories
*/
public function add($prefix, $paths, $prepend = false)
{
if (!$prefix) {
if ($prepend) {
$this->fallbackDirsPsr0 = array_merge(
(array) $paths,
$this->fallbackDirsPsr0
);
} else {
$this->fallbackDirsPsr0 = array_merge(
$this->fallbackDirsPsr0,
(array) $paths
);
}
return;
}
$first = $prefix[0];
if (!isset($this->prefixesPsr0[$first][$prefix])) {
$this->prefixesPsr0[$first][$prefix] = (array) $paths;
return;
}
if ($prepend) {
$this->prefixesPsr0[$first][$prefix] = array_merge(
(array) $paths,
$this->prefixesPsr0[$first][$prefix]
);
} else {
$this->prefixesPsr0[$first][$prefix] = array_merge(
$this->prefixesPsr0[$first][$prefix],
(array) $paths
);
}
}
/**
* Registers a set of PSR-4 directories for a given namespace, either
* appending or prepending to the ones previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param array|string $paths The PSR-4 base directories
* @param bool $prepend Whether to prepend the directories
*
* @throws \InvalidArgumentException
*/
public function addPsr4($prefix, $paths, $prepend = false)
{
if (!$prefix) {
// Register directories for the root namespace.
if ($prepend) {
$this->fallbackDirsPsr4 = array_merge(
(array) $paths,
$this->fallbackDirsPsr4
);
} else {
$this->fallbackDirsPsr4 = array_merge(
$this->fallbackDirsPsr4,
(array) $paths
);
}
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
// Register directories for a new namespace.
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
} elseif ($prepend) {
// Prepend directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
(array) $paths,
$this->prefixDirsPsr4[$prefix]
);
} else {
// Append directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
$this->prefixDirsPsr4[$prefix],
(array) $paths
);
}
}
/**
* Registers a set of PSR-0 directories for a given prefix,
* replacing any others previously set for this prefix.
*
* @param string $prefix The prefix
* @param array|string $paths The PSR-0 base directories
*/
public function set($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr0 = (array) $paths;
} else {
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
}
}
/**
* Registers a set of PSR-4 directories for a given namespace,
* replacing any others previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param array|string $paths The PSR-4 base directories
*
* @throws \InvalidArgumentException
*/
public function setPsr4($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr4 = (array) $paths;
} else {
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
}
}
/**
* Turns on searching the include path for class files.
*
* @param bool $useIncludePath
*/
public function setUseIncludePath($useIncludePath)
{
$this->useIncludePath = $useIncludePath;
}
/**
* Can be used to check if the autoloader uses the include path to check
* for classes.
*
* @return bool
*/
public function getUseIncludePath()
{
return $this->useIncludePath;
}
/**
* Turns off searching the prefix and fallback directories for classes
* that have not been registered with the class map.
*
* @param bool $classMapAuthoritative
*/
public function setClassMapAuthoritative($classMapAuthoritative)
{
$this->classMapAuthoritative = $classMapAuthoritative;
}
/**
* Should class lookup fail if not found in the current class map?
*
* @return bool
*/
public function isClassMapAuthoritative()
{
return $this->classMapAuthoritative;
}
/**
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
*
* @param string|null $apcuPrefix
*/
public function setApcuPrefix($apcuPrefix)
{
$this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null;
}
/**
* The APCu prefix in use, or null if APCu caching is not enabled.
*
* @return string|null
*/
public function getApcuPrefix()
{
return $this->apcuPrefix;
}
/**
* Registers this instance as an autoloader.
*
* @param bool $prepend Whether to prepend the autoloader or not
*/
public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
}
/**
* Unregisters this instance as an autoloader.
*/
public function unregister()
{
spl_autoload_unregister(array($this, 'loadClass'));
}
/**
* Loads the given class or interface.
*
* @param string $class The name of the class
* @return bool|null True if loaded, null otherwise
*/
public function loadClass($class)
{
if ($file = $this->findFile($class)) {
includeFile($file);
return true;
}
}
/**
* Finds the path to the file where the class is defined.
*
* @param string $class The name of the class
*
* @return string|false The path if found, false otherwise
*/
public function findFile($class)
{
// class map lookup
if (isset($this->classMap[$class])) {
return $this->classMap[$class];
}
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
return false;
}
if (null !== $this->apcuPrefix) {
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
if ($hit) {
return $file;
}
}
$file = $this->findFileWithExtension($class, '.php');
// Search for Hack files if we are running on HHVM
if (false === $file && defined('HHVM_VERSION')) {
$file = $this->findFileWithExtension($class, '.hh');
}
if (null !== $this->apcuPrefix) {
apcu_add($this->apcuPrefix.$class, $file);
}
if (false === $file) {
// Remember that this class does not exist.
$this->missingClasses[$class] = true;
}
return $file;
}
private function findFileWithExtension($class, $ext)
{
// PSR-4 lookup
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
$first = $class[0];
if (isset($this->prefixLengthsPsr4[$first])) {
$subPath = $class;
while (false !== $lastPos = strrpos($subPath, '\\')) {
$subPath = substr($subPath, 0, $lastPos);
$search = $subPath.'\\';
if (isset($this->prefixDirsPsr4[$search])) {
foreach ($this->prefixDirsPsr4[$search] as $dir) {
$length = $this->prefixLengthsPsr4[$first][$search];
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
return $file;
}
}
}
}
}
// PSR-4 fallback dirs
foreach ($this->fallbackDirsPsr4 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
return $file;
}
}
// PSR-0 lookup
if (false !== $pos = strrpos($class, '\\')) {
// namespaced class name
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
} else {
// PEAR-like class name
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
}
if (isset($this->prefixesPsr0[$first])) {
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
if (0 === strpos($class, $prefix)) {
foreach ($dirs as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
}
}
}
// PSR-0 fallback dirs
foreach ($this->fallbackDirsPsr0 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
// PSR-0 include paths.
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
return $file;
}
return false;
}
}
/**
* Scope isolated include.
*
* Prevents access to $this/self from included files.
*/
function includeFile($file)
{
include $file;
}

21
vendor/composer/LICENSE vendored Normal file
View File

@@ -0,0 +1,21 @@
Copyright (c) Nils Adermann, Jordi Boggiano
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

3019
vendor/composer/autoload_classmap.php vendored Normal file

File diff suppressed because it is too large Load Diff

18
vendor/composer/autoload_files.php vendored Normal file
View File

@@ -0,0 +1,18 @@
<?php
// autoload_files.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
'667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php',
'1d1b89d124cc9cb8219922c9d5569199' => $vendorDir . '/hamcrest/hamcrest-php/hamcrest/Hamcrest.php',
'2c102faa651ef8ea5874edb585946bce' => $vendorDir . '/swiftmailer/swiftmailer/lib/swift_required.php',
'5255c38a0faeba867671b61dfda6d864' => $vendorDir . '/paragonie/random_compat/lib/random.php',
'e7223560d890eab89cda23685e711e2c' => $vendorDir . '/psy/psysh/src/Psy/functions.php',
'f0906e6318348a765ffb6eb24e0d0938' => $vendorDir . '/laravel/framework/src/Illuminate/Foundation/helpers.php',
'58571171fd5812e6e447dce228f52f4d' => $vendorDir . '/laravel/framework/src/Illuminate/Support/helpers.php',
'f18cc91337d49233e5754e93f3ed9ec3' => $vendorDir . '/laravelcollective/html/src/helpers.php',
);

15
vendor/composer/autoload_namespaces.php vendored Normal file
View File

@@ -0,0 +1,15 @@
<?php
// autoload_namespaces.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'Prophecy\\' => array($vendorDir . '/phpspec/prophecy/src'),
'Parsedown' => array($vendorDir . '/erusev/parsedown'),
'Mockery' => array($vendorDir . '/mockery/mockery/library'),
'JakubOnderka\\PhpConsoleHighlighter' => array($vendorDir . '/jakub-onderka/php-console-highlighter/src'),
'JakubOnderka\\PhpConsoleColor' => array($vendorDir . '/jakub-onderka/php-console-color/src'),
'Doctrine\\Common\\Inflector\\' => array($vendorDir . '/doctrine/inflector/lib'),
);

45
vendor/composer/autoload_psr4.php vendored Normal file
View File

@@ -0,0 +1,45 @@
<?php
// autoload_psr4.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'phpDocumentor\\Reflection\\' => array($vendorDir . '/phpdocumentor/reflection-common/src', $vendorDir . '/phpdocumentor/type-resolver/src', $vendorDir . '/phpdocumentor/reflection-docblock/src'),
'XdgBaseDir\\' => array($vendorDir . '/dnoegel/php-xdg-base-dir/src'),
'Webmozart\\Assert\\' => array($vendorDir . '/webmozart/assert/src'),
'TijsVerkoyen\\CssToInlineStyles\\' => array($vendorDir . '/tijsverkoyen/css-to-inline-styles/src'),
'Tests\\' => array($baseDir . '/tests'),
'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'),
'Symfony\\Component\\Yaml\\' => array($vendorDir . '/symfony/yaml'),
'Symfony\\Component\\VarDumper\\' => array($vendorDir . '/symfony/var-dumper'),
'Symfony\\Component\\Translation\\' => array($vendorDir . '/symfony/translation'),
'Symfony\\Component\\Routing\\' => array($vendorDir . '/symfony/routing'),
'Symfony\\Component\\Process\\' => array($vendorDir . '/symfony/process'),
'Symfony\\Component\\HttpKernel\\' => array($vendorDir . '/symfony/http-kernel'),
'Symfony\\Component\\HttpFoundation\\' => array($vendorDir . '/symfony/http-foundation'),
'Symfony\\Component\\Finder\\' => array($vendorDir . '/symfony/finder'),
'Symfony\\Component\\EventDispatcher\\' => array($vendorDir . '/symfony/event-dispatcher'),
'Symfony\\Component\\Debug\\' => array($vendorDir . '/symfony/debug'),
'Symfony\\Component\\CssSelector\\' => array($vendorDir . '/symfony/css-selector'),
'Symfony\\Component\\Console\\' => array($vendorDir . '/symfony/console'),
'Ramsey\\Uuid\\' => array($vendorDir . '/ramsey/uuid/src'),
'Psy\\' => array($vendorDir . '/psy/psysh/src/Psy'),
'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),
'PhpParser\\' => array($vendorDir . '/nikic/php-parser/lib/PhpParser'),
'Monolog\\' => array($vendorDir . '/monolog/monolog/src/Monolog'),
'Model\\' => array($baseDir . '/../api-dev/common/classes'),
'League\\Flysystem\\' => array($vendorDir . '/league/flysystem/src'),
'Laravel\\Tinker\\' => array($vendorDir . '/laravel/tinker/src'),
'Illuminate\\' => array($vendorDir . '/laravel/framework/src/Illuminate'),
'Helpers\\' => array($baseDir . '/app/Helpers'),
'Faker\\' => array($vendorDir . '/fzaninotto/faker/src/Faker'),
'Dotenv\\' => array($vendorDir . '/vlucas/phpdotenv/src'),
'Doctrine\\Instantiator\\' => array($vendorDir . '/doctrine/instantiator/src/Doctrine/Instantiator'),
'DeepCopy\\' => array($vendorDir . '/myclabs/deep-copy/src/DeepCopy'),
'Cron\\' => array($vendorDir . '/mtdowling/cron-expression/src/Cron'),
'Collective\\Html\\' => array($vendorDir . '/laravelcollective/html/src'),
'Carbon\\' => array($vendorDir . '/nesbot/carbon/src/Carbon'),
'App\\' => array($baseDir . '/app'),
);

70
vendor/composer/autoload_real.php vendored Normal file
View File

@@ -0,0 +1,70 @@
<?php
// autoload_real.php @generated by Composer
class ComposerAutoloaderInit5216a35d72a5119d2f4646cd700f802d
{
private static $loader;
public static function loadClassLoader($class)
{
if ('Composer\Autoload\ClassLoader' === $class) {
require __DIR__ . '/ClassLoader.php';
}
}
public static function getLoader()
{
if (null !== self::$loader) {
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInit5216a35d72a5119d2f4646cd700f802d', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
spl_autoload_unregister(array('ComposerAutoloaderInit5216a35d72a5119d2f4646cd700f802d', 'loadClassLoader'));
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
if ($useStaticLoader) {
require_once __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInit5216a35d72a5119d2f4646cd700f802d::getInitializer($loader));
} else {
$map = require __DIR__ . '/autoload_namespaces.php';
foreach ($map as $namespace => $path) {
$loader->set($namespace, $path);
}
$map = require __DIR__ . '/autoload_psr4.php';
foreach ($map as $namespace => $path) {
$loader->setPsr4($namespace, $path);
}
$classMap = require __DIR__ . '/autoload_classmap.php';
if ($classMap) {
$loader->addClassMap($classMap);
}
}
$loader->register(true);
if ($useStaticLoader) {
$includeFiles = Composer\Autoload\ComposerStaticInit5216a35d72a5119d2f4646cd700f802d::$files;
} else {
$includeFiles = require __DIR__ . '/autoload_files.php';
}
foreach ($includeFiles as $fileIdentifier => $file) {
composerRequire5216a35d72a5119d2f4646cd700f802d($fileIdentifier, $file);
}
return $loader;
}
}
function composerRequire5216a35d72a5119d2f4646cd700f802d($fileIdentifier, $file)
{
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
require $file;
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
}
}

3316
vendor/composer/autoload_static.php vendored Normal file

File diff suppressed because it is too large Load Diff

3526
vendor/composer/installed.json vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@
/vendor/

19
vendor/dnoegel/php-xdg-base-dir/LICENSE vendored Normal file
View File

@@ -0,0 +1,19 @@
Copyright (c) 2014 Daniel Nögel
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -0,0 +1,38 @@
# XDG Base Directory
[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE.md)
Implementation of XDG Base Directory specification for php
## Install
Via Composer
``` bash
$ composer require dnoegel/php-xdg-base-dir
```
## Usage
``` php
$xdg = \XdgBaseDir\Xdg();
echo $xdg->getHomeDir();
echo $xdg->getHomeConfigDir()
echo $xdg->getHomeDataDir()
echo $xdg->getHomeCacheDir()
echo $xdg->getRuntimeDir()
$xdg->getDataDirs() // returns array
$xdg->getConfigDirs() // returns array
```
## Testing
``` bash
$ phpunit
```
## License
The MIT License (MIT). Please see [License File](https://github.com/dnoegel/php-xdg-base-dir/blob/master/LICENSE) for more information.

View File

@@ -0,0 +1,17 @@
{
"name": "dnoegel/php-xdg-base-dir",
"description": "implementation of xdg base directory specification for php",
"type": "project",
"license": "MIT",
"require": {
"php": ">=5.3.2"
},
"require-dev": {
"phpunit/phpunit": "@stable"
},
"autoload": {
"psr-4": {
"XdgBaseDir\\": "src/"
}
}
}

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false"
bootstrap="vendor/autoload.php"
>
<testsuites>
<testsuite name="php-xdg-base-dir unit tests">
<directory>./tests/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory>./src/</directory>
</whitelist>
</filter>
</phpunit>

View File

@@ -0,0 +1,121 @@
<?php
namespace XdgBaseDir;
/**
* Simple implementation of the XDG standard http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
*
* Based on the python implementation https://github.com/takluyver/pyxdg/blob/master/xdg/BaseDirectory.py
*
* Class Xdg
* @package ShopwareCli\Application
*/
class Xdg
{
const S_IFDIR = 040000; // directory
const S_IRWXO = 00007; // rwx other
const S_IRWXG = 00056; // rwx group
const RUNTIME_DIR_FALLBACK = 'php-xdg-runtime-dir-fallback-';
/**
* @return string
*/
public function getHomeDir()
{
return getenv('HOME') ?: (getenv('HOMEDRIVE') . DIRECTORY_SEPARATOR . getenv('HOMEPATH'));
}
/**
* @return string
*/
public function getHomeConfigDir()
{
$path = getenv('XDG_CONFIG_HOME') ?: $this->getHomeDir() . DIRECTORY_SEPARATOR . '.config';
return $path;
}
/**
* @return string
*/
public function getHomeDataDir()
{
$path = getenv('XDG_DATA_HOME') ?: $this->getHomeDir() . DIRECTORY_SEPARATOR . '.local' . DIRECTORY_SEPARATOR . 'share';
return $path;
}
/**
* @return array
*/
public function getConfigDirs()
{
$configDirs = getenv('XDG_CONFIG_DIRS') ? explode(':', getenv('XDG_CONFIG_DIRS')) : array('/etc/xdg');
$paths = array_merge(array($this->getHomeConfigDir()), $configDirs);
return $paths;
}
/**
* @return array
*/
public function getDataDirs()
{
$dataDirs = getenv('XDG_DATA_DIRS') ? explode(':', getenv('XDG_DATA_DIRS')) : array('/usr/local/share', '/usr/share');
$paths = array_merge(array($this->getHomeDataDir()), $dataDirs);
return $paths;
}
/**
* @return string
*/
public function getHomeCacheDir()
{
$path = getenv('XDG_CACHE_HOME') ?: $this->getHomeDir() . DIRECTORY_SEPARATOR . '.cache';
return $path;
}
public function getRuntimeDir($strict=true)
{
if ($runtimeDir = getenv('XDG_RUNTIME_DIR')) {
return $runtimeDir;
}
if ($strict) {
throw new \RuntimeException('XDG_RUNTIME_DIR was not set');
}
$fallback = sys_get_temp_dir() . DIRECTORY_SEPARATOR . self::RUNTIME_DIR_FALLBACK . getenv('USER');
$create = false;
if (!is_dir($fallback)) {
mkdir($fallback, 0700, true);
}
$st = lstat($fallback);
# The fallback must be a directory
if (!$st['mode'] & self::S_IFDIR) {
rmdir($fallback);
$create = true;
} elseif ($st['uid'] != getmyuid() ||
$st['mode'] & (self::S_IRWXG | self::S_IRWXO)
) {
rmdir($fallback);
$create = true;
}
if ($create) {
mkdir($fallback, 0700, true);
}
return $fallback;
}
}

View File

@@ -0,0 +1,116 @@
<?php
class XdgTest extends PHPUnit_Framework_TestCase
{
/**
* @return \XdgBaseDir\Xdg
*/
public function getXdg()
{
return new \XdgBaseDir\Xdg();
}
public function testGetHomeDir()
{
putenv('HOME=/fake-dir');
$this->assertEquals('/fake-dir', $this->getXdg()->getHomeDir());
}
public function testGetFallbackHomeDir()
{
putenv('HOME=');
putenv('HOMEDRIVE=C:');
putenv('HOMEPATH=fake-dir');
$this->assertEquals('C:/fake-dir', $this->getXdg()->getHomeDir());
}
public function testXdgPutCache()
{
putenv('XDG_DATA_HOME=tmp/');
putenv('XDG_CONFIG_HOME=tmp/');
putenv('XDG_CACHE_HOME=tmp/');
$this->assertEquals('tmp/', $this->getXdg()->getHomeCacheDir());
}
public function testXdgPutData()
{
putenv('XDG_DATA_HOME=tmp/');
$this->assertEquals('tmp/', $this->getXdg()->getHomeDataDir());
}
public function testXdgPutConfig()
{
putenv('XDG_CONFIG_HOME=tmp/');
$this->assertEquals('tmp/', $this->getXdg()->getHomeConfigDir());
}
public function testXdgDataDirsShouldIncludeHomeDataDir()
{
putenv('XDG_DATA_HOME=tmp/');
putenv('XDG_CONFIG_HOME=tmp/');
$this->assertArrayHasKey('tmp/', array_flip($this->getXdg()->getDataDirs()));
}
public function testXdgConfigDirsShouldIncludeHomeConfigDir()
{
putenv('XDG_CONFIG_HOME=tmp/');
$this->assertArrayHasKey('tmp/', array_flip($this->getXdg()->getConfigDirs()));
}
/**
* If XDG_RUNTIME_DIR is set, it should be returned
*/
public function testGetRuntimeDir()
{
putenv('XDG_RUNTIME_DIR=/tmp/');
$runtimeDir = $this->getXdg()->getRuntimeDir();
$this->assertEquals(is_dir($runtimeDir), true);
}
/**
* In strict mode, an exception should be shown if XDG_RUNTIME_DIR does not exist
*
* @expectedException \RuntimeException
*/
public function testGetRuntimeDirShouldThrowException()
{
putenv('XDG_RUNTIME_DIR=');
$this->getXdg()->getRuntimeDir(true);
}
/**
* In fallback mode a directory should be created
*/
public function testGetRuntimeDirShouldCreateDirectory()
{
putenv('XDG_RUNTIME_DIR=');
$dir = $this->getXdg()->getRuntimeDir(false);
$permission = decoct(fileperms($dir) & 0777);
$this->assertEquals(700, $permission);
}
/**
* Ensure, that the fallback directories are created with correct permission
*/
public function testGetRuntimeShouldDeleteDirsWithWrongPermission()
{
$runtimeDir = sys_get_temp_dir() . DIRECTORY_SEPARATOR . XdgBaseDir\Xdg::RUNTIME_DIR_FALLBACK . getenv('USER');
rmdir($runtimeDir);
mkdir($runtimeDir, 0764, true);
// Permission should be wrong now
$permission = decoct(fileperms($runtimeDir) & 0777);
$this->assertEquals(764, $permission);
putenv('XDG_RUNTIME_DIR=');
$dir = $this->getXdg()->getRuntimeDir(false);
// Permission should be fixed
$permission = decoct(fileperms($dir) & 0777);
$this->assertEquals(700, $permission);
}
}

4
vendor/doctrine/inflector/.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
vendor/
composer.lock
composer.phar
phpunit.xml

21
vendor/doctrine/inflector/.travis.yml vendored Normal file
View File

@@ -0,0 +1,21 @@
language: php
sudo: false
cache:
directory:
- $HOME/.composer/cache
php:
- 5.3
- 5.4
- 5.5
- 5.6
- 7.0
- hhvm
install:
- composer install -n
script:
- phpunit

19
vendor/doctrine/inflector/LICENSE vendored Normal file
View File

@@ -0,0 +1,19 @@
Copyright (c) 2006-2015 Doctrine Project
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

6
vendor/doctrine/inflector/README.md vendored Normal file
View File

@@ -0,0 +1,6 @@
# Doctrine Inflector
Doctrine Inflector is a small library that can perform string manipulations
with regard to upper-/lowercase and singular/plural forms of words.
[![Build Status](https://travis-ci.org/doctrine/inflector.svg?branch=master)](https://travis-ci.org/doctrine/inflector)

29
vendor/doctrine/inflector/composer.json vendored Normal file
View File

@@ -0,0 +1,29 @@
{
"name": "doctrine/inflector",
"type": "library",
"description": "Common String Manipulations with regard to casing and singular/plural rules.",
"keywords": ["string", "inflection", "singularize", "pluralize"],
"homepage": "http://www.doctrine-project.org",
"license": "MIT",
"authors": [
{"name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com"},
{"name": "Roman Borschel", "email": "roman@code-factory.org"},
{"name": "Benjamin Eberlei", "email": "kontakt@beberlei.de"},
{"name": "Jonathan Wage", "email": "jonwage@gmail.com"},
{"name": "Johannes Schmitt", "email": "schmittjoh@gmail.com"}
],
"require": {
"php": ">=5.3.2"
},
"require-dev": {
"phpunit/phpunit": "4.*"
},
"autoload": {
"psr-0": { "Doctrine\\Common\\Inflector\\": "lib/" }
},
"extra": {
"branch-alias": {
"dev-master": "1.1.x-dev"
}
}
}

View File

@@ -0,0 +1,482 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Inflector;
/**
* Doctrine inflector has static methods for inflecting text.
*
* The methods in these classes are from several different sources collected
* across several different php projects and several different authors. The
* original author names and emails are not known.
*
* Pluralize & Singularize implementation are borrowed from CakePHP with some modifications.
*
* @link www.doctrine-project.org
* @since 1.0
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
* @author Jonathan H. Wage <jonwage@gmail.com>
*/
class Inflector
{
/**
* Plural inflector rules.
*
* @var array
*/
private static $plural = array(
'rules' => array(
'/(s)tatus$/i' => '\1\2tatuses',
'/(quiz)$/i' => '\1zes',
'/^(ox)$/i' => '\1\2en',
'/([m|l])ouse$/i' => '\1ice',
'/(matr|vert|ind)(ix|ex)$/i' => '\1ices',
'/(x|ch|ss|sh)$/i' => '\1es',
'/([^aeiouy]|qu)y$/i' => '\1ies',
'/(hive)$/i' => '\1s',
'/(?:([^f])fe|([lr])f)$/i' => '\1\2ves',
'/sis$/i' => 'ses',
'/([ti])um$/i' => '\1a',
'/(p)erson$/i' => '\1eople',
'/(m)an$/i' => '\1en',
'/(c)hild$/i' => '\1hildren',
'/(f)oot$/i' => '\1eet',
'/(buffal|her|potat|tomat|volcan)o$/i' => '\1\2oes',
'/(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|vir)us$/i' => '\1i',
'/us$/i' => 'uses',
'/(alias)$/i' => '\1es',
'/(analys|ax|cris|test|thes)is$/i' => '\1es',
'/s$/' => 's',
'/^$/' => '',
'/$/' => 's',
),
'uninflected' => array(
'.*[nrlm]ese', '.*deer', '.*fish', '.*measles', '.*ois', '.*pox', '.*sheep', 'people', 'cookie'
),
'irregular' => array(
'atlas' => 'atlases',
'axe' => 'axes',
'beef' => 'beefs',
'brother' => 'brothers',
'cafe' => 'cafes',
'chateau' => 'chateaux',
'child' => 'children',
'cookie' => 'cookies',
'corpus' => 'corpuses',
'cow' => 'cows',
'criterion' => 'criteria',
'curriculum' => 'curricula',
'demo' => 'demos',
'domino' => 'dominoes',
'echo' => 'echoes',
'foot' => 'feet',
'fungus' => 'fungi',
'ganglion' => 'ganglions',
'genie' => 'genies',
'genus' => 'genera',
'graffito' => 'graffiti',
'hippopotamus' => 'hippopotami',
'hoof' => 'hoofs',
'human' => 'humans',
'iris' => 'irises',
'leaf' => 'leaves',
'loaf' => 'loaves',
'man' => 'men',
'medium' => 'media',
'memorandum' => 'memoranda',
'money' => 'monies',
'mongoose' => 'mongooses',
'motto' => 'mottoes',
'move' => 'moves',
'mythos' => 'mythoi',
'niche' => 'niches',
'nucleus' => 'nuclei',
'numen' => 'numina',
'occiput' => 'occiputs',
'octopus' => 'octopuses',
'opus' => 'opuses',
'ox' => 'oxen',
'penis' => 'penises',
'person' => 'people',
'plateau' => 'plateaux',
'runner-up' => 'runners-up',
'sex' => 'sexes',
'soliloquy' => 'soliloquies',
'son-in-law' => 'sons-in-law',
'syllabus' => 'syllabi',
'testis' => 'testes',
'thief' => 'thieves',
'tooth' => 'teeth',
'tornado' => 'tornadoes',
'trilby' => 'trilbys',
'turf' => 'turfs',
'volcano' => 'volcanoes',
)
);
/**
* Singular inflector rules.
*
* @var array
*/
private static $singular = array(
'rules' => array(
'/(s)tatuses$/i' => '\1\2tatus',
'/^(.*)(menu)s$/i' => '\1\2',
'/(quiz)zes$/i' => '\\1',
'/(matr)ices$/i' => '\1ix',
'/(vert|ind)ices$/i' => '\1ex',
'/^(ox)en/i' => '\1',
'/(alias)(es)*$/i' => '\1',
'/(buffal|her|potat|tomat|volcan)oes$/i' => '\1o',
'/(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|viri?)i$/i' => '\1us',
'/([ftw]ax)es/i' => '\1',
'/(analys|ax|cris|test|thes)es$/i' => '\1is',
'/(shoe|slave)s$/i' => '\1',
'/(o)es$/i' => '\1',
'/ouses$/' => 'ouse',
'/([^a])uses$/' => '\1us',
'/([m|l])ice$/i' => '\1ouse',
'/(x|ch|ss|sh)es$/i' => '\1',
'/(m)ovies$/i' => '\1\2ovie',
'/(s)eries$/i' => '\1\2eries',
'/([^aeiouy]|qu)ies$/i' => '\1y',
'/([lr])ves$/i' => '\1f',
'/(tive)s$/i' => '\1',
'/(hive)s$/i' => '\1',
'/(drive)s$/i' => '\1',
'/([^fo])ves$/i' => '\1fe',
'/(^analy)ses$/i' => '\1sis',
'/(analy|diagno|^ba|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i' => '\1\2sis',
'/([ti])a$/i' => '\1um',
'/(p)eople$/i' => '\1\2erson',
'/(m)en$/i' => '\1an',
'/(c)hildren$/i' => '\1\2hild',
'/(f)eet$/i' => '\1oot',
'/(n)ews$/i' => '\1\2ews',
'/eaus$/' => 'eau',
'/^(.*us)$/' => '\\1',
'/s$/i' => '',
),
'uninflected' => array(
'.*[nrlm]ese',
'.*deer',
'.*fish',
'.*measles',
'.*ois',
'.*pox',
'.*sheep',
'.*ss',
),
'irregular' => array(
'criteria' => 'criterion',
'curves' => 'curve',
'emphases' => 'emphasis',
'foes' => 'foe',
'hoaxes' => 'hoax',
'media' => 'medium',
'neuroses' => 'neurosis',
'waves' => 'wave',
'oases' => 'oasis',
)
);
/**
* Words that should not be inflected.
*
* @var array
*/
private static $uninflected = array(
'Amoyese', 'bison', 'Borghese', 'bream', 'breeches', 'britches', 'buffalo', 'cantus',
'carp', 'chassis', 'clippers', 'cod', 'coitus', 'Congoese', 'contretemps', 'corps',
'debris', 'diabetes', 'djinn', 'eland', 'elk', 'equipment', 'Faroese', 'flounder',
'Foochowese', 'gallows', 'Genevese', 'Genoese', 'Gilbertese', 'graffiti',
'headquarters', 'herpes', 'hijinks', 'Hottentotese', 'information', 'innings',
'jackanapes', 'Kiplingese', 'Kongoese', 'Lucchese', 'mackerel', 'Maltese', '.*?media',
'mews', 'moose', 'mumps', 'Nankingese', 'news', 'nexus', 'Niasese',
'Pekingese', 'Piedmontese', 'pincers', 'Pistoiese', 'pliers', 'Portuguese',
'proceedings', 'rabies', 'rice', 'rhinoceros', 'salmon', 'Sarawakese', 'scissors',
'sea[- ]bass', 'series', 'Shavese', 'shears', 'siemens', 'species', 'staff', 'swine',
'testes', 'trousers', 'trout', 'tuna', 'Vermontese', 'Wenchowese', 'whiting',
'wildebeest', 'Yengeese'
);
/**
* Method cache array.
*
* @var array
*/
private static $cache = array();
/**
* The initial state of Inflector so reset() works.
*
* @var array
*/
private static $initialState = array();
/**
* Converts a word into the format for a Doctrine table name. Converts 'ModelName' to 'model_name'.
*
* @param string $word The word to tableize.
*
* @return string The tableized word.
*/
public static function tableize($word)
{
return strtolower(preg_replace('~(?<=\\w)([A-Z])~', '_$1', $word));
}
/**
* Converts a word into the format for a Doctrine class name. Converts 'table_name' to 'TableName'.
*
* @param string $word The word to classify.
*
* @return string The classified word.
*/
public static function classify($word)
{
return str_replace(" ", "", ucwords(strtr($word, "_-", " ")));
}
/**
* Camelizes a word. This uses the classify() method and turns the first character to lowercase.
*
* @param string $word The word to camelize.
*
* @return string The camelized word.
*/
public static function camelize($word)
{
return lcfirst(self::classify($word));
}
/**
* Uppercases words with configurable delimeters between words.
*
* Takes a string and capitalizes all of the words, like PHP's built-in
* ucwords function. This extends that behavior, however, by allowing the
* word delimeters to be configured, rather than only separating on
* whitespace.
*
* Here is an example:
* <code>
* <?php
* $string = 'top-o-the-morning to all_of_you!';
* echo \Doctrine\Common\Inflector\Inflector::ucwords($string);
* // Top-O-The-Morning To All_of_you!
*
* echo \Doctrine\Common\Inflector\Inflector::ucwords($string, '-_ ');
* // Top-O-The-Morning To All_Of_You!
* ?>
* </code>
*
* @param string $string The string to operate on.
* @param string $delimiters A list of word separators.
*
* @return string The string with all delimeter-separated words capitalized.
*/
public static function ucwords($string, $delimiters = " \n\t\r\0\x0B-")
{
return preg_replace_callback(
'/[^' . preg_quote($delimiters, '/') . ']+/',
function($matches) {
return ucfirst($matches[0]);
},
$string
);
}
/**
* Clears Inflectors inflected value caches, and resets the inflection
* rules to the initial values.
*
* @return void
*/
public static function reset()
{
if (empty(self::$initialState)) {
self::$initialState = get_class_vars('Inflector');
return;
}
foreach (self::$initialState as $key => $val) {
if ($key != 'initialState') {
self::${$key} = $val;
}
}
}
/**
* Adds custom inflection $rules, of either 'plural' or 'singular' $type.
*
* ### Usage:
*
* {{{
* Inflector::rules('plural', array('/^(inflect)or$/i' => '\1ables'));
* Inflector::rules('plural', array(
* 'rules' => array('/^(inflect)ors$/i' => '\1ables'),
* 'uninflected' => array('dontinflectme'),
* 'irregular' => array('red' => 'redlings')
* ));
* }}}
*
* @param string $type The type of inflection, either 'plural' or 'singular'
* @param array $rules An array of rules to be added.
* @param boolean $reset If true, will unset default inflections for all
* new rules that are being defined in $rules.
*
* @return void
*/
public static function rules($type, $rules, $reset = false)
{
foreach ($rules as $rule => $pattern) {
if ( ! is_array($pattern)) {
continue;
}
if ($reset) {
self::${$type}[$rule] = $pattern;
} else {
self::${$type}[$rule] = ($rule === 'uninflected')
? array_merge($pattern, self::${$type}[$rule])
: $pattern + self::${$type}[$rule];
}
unset($rules[$rule], self::${$type}['cache' . ucfirst($rule)]);
if (isset(self::${$type}['merged'][$rule])) {
unset(self::${$type}['merged'][$rule]);
}
if ($type === 'plural') {
self::$cache['pluralize'] = self::$cache['tableize'] = array();
} elseif ($type === 'singular') {
self::$cache['singularize'] = array();
}
}
self::${$type}['rules'] = $rules + self::${$type}['rules'];
}
/**
* Returns a word in plural form.
*
* @param string $word The word in singular form.
*
* @return string The word in plural form.
*/
public static function pluralize($word)
{
if (isset(self::$cache['pluralize'][$word])) {
return self::$cache['pluralize'][$word];
}
if (!isset(self::$plural['merged']['irregular'])) {
self::$plural['merged']['irregular'] = self::$plural['irregular'];
}
if (!isset(self::$plural['merged']['uninflected'])) {
self::$plural['merged']['uninflected'] = array_merge(self::$plural['uninflected'], self::$uninflected);
}
if (!isset(self::$plural['cacheUninflected']) || !isset(self::$plural['cacheIrregular'])) {
self::$plural['cacheUninflected'] = '(?:' . implode('|', self::$plural['merged']['uninflected']) . ')';
self::$plural['cacheIrregular'] = '(?:' . implode('|', array_keys(self::$plural['merged']['irregular'])) . ')';
}
if (preg_match('/(.*)\\b(' . self::$plural['cacheIrregular'] . ')$/i', $word, $regs)) {
self::$cache['pluralize'][$word] = $regs[1] . substr($word, 0, 1) . substr(self::$plural['merged']['irregular'][strtolower($regs[2])], 1);
return self::$cache['pluralize'][$word];
}
if (preg_match('/^(' . self::$plural['cacheUninflected'] . ')$/i', $word, $regs)) {
self::$cache['pluralize'][$word] = $word;
return $word;
}
foreach (self::$plural['rules'] as $rule => $replacement) {
if (preg_match($rule, $word)) {
self::$cache['pluralize'][$word] = preg_replace($rule, $replacement, $word);
return self::$cache['pluralize'][$word];
}
}
}
/**
* Returns a word in singular form.
*
* @param string $word The word in plural form.
*
* @return string The word in singular form.
*/
public static function singularize($word)
{
if (isset(self::$cache['singularize'][$word])) {
return self::$cache['singularize'][$word];
}
if (!isset(self::$singular['merged']['uninflected'])) {
self::$singular['merged']['uninflected'] = array_merge(
self::$singular['uninflected'],
self::$uninflected
);
}
if (!isset(self::$singular['merged']['irregular'])) {
self::$singular['merged']['irregular'] = array_merge(
self::$singular['irregular'],
array_flip(self::$plural['irregular'])
);
}
if (!isset(self::$singular['cacheUninflected']) || !isset(self::$singular['cacheIrregular'])) {
self::$singular['cacheUninflected'] = '(?:' . join('|', self::$singular['merged']['uninflected']) . ')';
self::$singular['cacheIrregular'] = '(?:' . join('|', array_keys(self::$singular['merged']['irregular'])) . ')';
}
if (preg_match('/(.*)\\b(' . self::$singular['cacheIrregular'] . ')$/i', $word, $regs)) {
self::$cache['singularize'][$word] = $regs[1] . substr($word, 0, 1) . substr(self::$singular['merged']['irregular'][strtolower($regs[2])], 1);
return self::$cache['singularize'][$word];
}
if (preg_match('/^(' . self::$singular['cacheUninflected'] . ')$/i', $word, $regs)) {
self::$cache['singularize'][$word] = $word;
return $word;
}
foreach (self::$singular['rules'] as $rule => $replacement) {
if (preg_match($rule, $word)) {
self::$cache['singularize'][$word] = preg_replace($rule, $replacement, $word);
return self::$cache['singularize'][$word];
}
}
self::$cache['singularize'][$word] = $word;
return $word;
}
}

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false"
bootstrap="./tests/Doctrine/Tests/TestInit.php"
>
<testsuites>
<testsuite name="Doctrine Inflector Test Suite">
<directory>./tests/Doctrine/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory>./lib/Doctrine/</directory>
</whitelist>
</filter>
<groups>
<exclude>
<group>performance</group>
</exclude>
</groups>
</phpunit>

View File

@@ -0,0 +1,309 @@
<?php
namespace Doctrine\Tests\Common\Inflector;
use Doctrine\Tests\DoctrineTestCase;
use Doctrine\Common\Inflector\Inflector;
class InflectorTest extends DoctrineTestCase
{
/**
* Singular & Plural test data. Returns an array of sample words.
*
* @return array
*/
public function dataSampleWords()
{
Inflector::reset();
// In the format array('singular', 'plural')
return array(
array('', ''),
array('Alias', 'Aliases'),
array('alumnus', 'alumni'),
array('analysis', 'analyses'),
array('aquarium', 'aquaria'),
array('arch', 'arches'),
array('atlas', 'atlases'),
array('axe', 'axes'),
array('baby', 'babies'),
array('bacillus', 'bacilli'),
array('bacterium', 'bacteria'),
array('bureau', 'bureaus'),
array('bus', 'buses'),
array('Bus', 'Buses'),
array('cactus', 'cacti'),
array('cafe', 'cafes'),
array('calf', 'calves'),
array('categoria', 'categorias'),
array('chateau', 'chateaux'),
array('cherry', 'cherries'),
array('child', 'children'),
array('church', 'churches'),
array('circus', 'circuses'),
array('city', 'cities'),
array('cod', 'cod'),
array('cookie', 'cookies'),
array('copy', 'copies'),
array('crisis', 'crises'),
array('criterion', 'criteria'),
array('curriculum', 'curricula'),
array('curve', 'curves'),
array('deer', 'deer'),
array('demo', 'demos'),
array('dictionary', 'dictionaries'),
array('domino', 'dominoes'),
array('dwarf', 'dwarves'),
array('echo', 'echoes'),
array('elf', 'elves'),
array('emphasis', 'emphases'),
array('family', 'families'),
array('fax', 'faxes'),
array('fish', 'fish'),
array('flush', 'flushes'),
array('fly', 'flies'),
array('focus', 'foci'),
array('foe', 'foes'),
array('food_menu', 'food_menus'),
array('FoodMenu', 'FoodMenus'),
array('foot', 'feet'),
array('fungus', 'fungi'),
array('glove', 'gloves'),
array('half', 'halves'),
array('hero', 'heroes'),
array('hippopotamus', 'hippopotami'),
array('hoax', 'hoaxes'),
array('house', 'houses'),
array('human', 'humans'),
array('identity', 'identities'),
array('index', 'indices'),
array('iris', 'irises'),
array('kiss', 'kisses'),
array('knife', 'knives'),
array('leaf', 'leaves'),
array('life', 'lives'),
array('loaf', 'loaves'),
array('man', 'men'),
array('matrix', 'matrices'),
array('matrix_row', 'matrix_rows'),
array('medium', 'media'),
array('memorandum', 'memoranda'),
array('menu', 'menus'),
array('Menu', 'Menus'),
array('mess', 'messes'),
array('moose', 'moose'),
array('motto', 'mottoes'),
array('mouse', 'mice'),
array('neurosis', 'neuroses'),
array('news', 'news'),
array('NodeMedia', 'NodeMedia'),
array('nucleus', 'nuclei'),
array('oasis', 'oases'),
array('octopus', 'octopuses'),
array('pass', 'passes'),
array('person', 'people'),
array('plateau', 'plateaux'),
array('potato', 'potatoes'),
array('powerhouse', 'powerhouses'),
array('quiz', 'quizzes'),
array('radius', 'radii'),
array('reflex', 'reflexes'),
array('roof', 'roofs'),
array('runner-up', 'runners-up'),
array('scarf', 'scarves'),
array('scratch', 'scratches'),
array('series', 'series'),
array('sheep', 'sheep'),
array('shelf', 'shelves'),
array('shoe', 'shoes'),
array('son-in-law', 'sons-in-law'),
array('species', 'species'),
array('splash', 'splashes'),
array('spy', 'spies'),
array('stimulus', 'stimuli'),
array('stitch', 'stitches'),
array('story', 'stories'),
array('syllabus', 'syllabi'),
array('tax', 'taxes'),
array('terminus', 'termini'),
array('thesis', 'theses'),
array('thief', 'thieves'),
array('tomato', 'tomatoes'),
array('tooth', 'teeth'),
array('tornado', 'tornadoes'),
array('try', 'tries'),
array('vertex', 'vertices'),
array('virus', 'viri'),
array('volcano', 'volcanoes'),
array('wash', 'washes'),
array('watch', 'watches'),
array('wave', 'waves'),
array('wharf', 'wharves'),
array('wife', 'wives'),
array('woman', 'women'),
);
}
/**
* testInflectingSingulars method
*
* @dataProvider dataSampleWords
* @return void
*/
public function testInflectingSingulars($singular, $plural)
{
$this->assertEquals(
$singular,
Inflector::singularize($plural),
"'$plural' should be singularized to '$singular'"
);
}
/**
* testInflectingPlurals method
*
* @dataProvider dataSampleWords
* @return void
*/
public function testInflectingPlurals($singular, $plural)
{
$this->assertEquals(
$plural,
Inflector::pluralize($singular),
"'$singular' should be pluralized to '$plural'"
);
}
/**
* testCustomPluralRule method
*
* @return void
*/
public function testCustomPluralRule()
{
Inflector::reset();
Inflector::rules('plural', array('/^(custom)$/i' => '\1izables'));
$this->assertEquals(Inflector::pluralize('custom'), 'customizables');
Inflector::rules('plural', array('uninflected' => array('uninflectable')));
$this->assertEquals(Inflector::pluralize('uninflectable'), 'uninflectable');
Inflector::rules('plural', array(
'rules' => array('/^(alert)$/i' => '\1ables'),
'uninflected' => array('noflect', 'abtuse'),
'irregular' => array('amaze' => 'amazable', 'phone' => 'phonezes')
));
$this->assertEquals(Inflector::pluralize('noflect'), 'noflect');
$this->assertEquals(Inflector::pluralize('abtuse'), 'abtuse');
$this->assertEquals(Inflector::pluralize('alert'), 'alertables');
$this->assertEquals(Inflector::pluralize('amaze'), 'amazable');
$this->assertEquals(Inflector::pluralize('phone'), 'phonezes');
}
/**
* testCustomSingularRule method
*
* @return void
*/
public function testCustomSingularRule()
{
Inflector::reset();
Inflector::rules('singular', array('/(eple)r$/i' => '\1', '/(jente)r$/i' => '\1'));
$this->assertEquals(Inflector::singularize('epler'), 'eple');
$this->assertEquals(Inflector::singularize('jenter'), 'jente');
Inflector::rules('singular', array(
'rules' => array('/^(bil)er$/i' => '\1', '/^(inflec|contribu)tors$/i' => '\1ta'),
'uninflected' => array('singulars'),
'irregular' => array('spins' => 'spinor')
));
$this->assertEquals(Inflector::singularize('inflectors'), 'inflecta');
$this->assertEquals(Inflector::singularize('contributors'), 'contributa');
$this->assertEquals(Inflector::singularize('spins'), 'spinor');
$this->assertEquals(Inflector::singularize('singulars'), 'singulars');
}
/**
* test that setting new rules clears the inflector caches.
*
* @return void
*/
public function testRulesClearsCaches()
{
Inflector::reset();
$this->assertEquals(Inflector::singularize('Bananas'), 'Banana');
$this->assertEquals(Inflector::pluralize('Banana'), 'Bananas');
Inflector::rules('singular', array(
'rules' => array('/(.*)nas$/i' => '\1zzz')
));
$this->assertEquals('Banazzz', Inflector::singularize('Bananas'), 'Was inflected with old rules.');
Inflector::rules('plural', array(
'rules' => array('/(.*)na$/i' => '\1zzz'),
'irregular' => array('corpus' => 'corpora')
));
$this->assertEquals(Inflector::pluralize('Banana'), 'Banazzz', 'Was inflected with old rules.');
$this->assertEquals(Inflector::pluralize('corpus'), 'corpora', 'Was inflected with old irregular form.');
}
/**
* Test resetting inflection rules.
*
* @return void
*/
public function testCustomRuleWithReset()
{
Inflector::reset();
$uninflected = array('atlas', 'lapis', 'onibus', 'pires', 'virus', '.*x');
$pluralIrregular = array('as' => 'ases');
Inflector::rules('singular', array(
'rules' => array('/^(.*)(a|e|o|u)is$/i' => '\1\2l'),
'uninflected' => $uninflected,
), true);
Inflector::rules('plural', array(
'rules' => array(
'/^(.*)(a|e|o|u)l$/i' => '\1\2is',
),
'uninflected' => $uninflected,
'irregular' => $pluralIrregular
), true);
$this->assertEquals(Inflector::pluralize('Alcool'), 'Alcoois');
$this->assertEquals(Inflector::pluralize('Atlas'), 'Atlas');
$this->assertEquals(Inflector::singularize('Alcoois'), 'Alcool');
$this->assertEquals(Inflector::singularize('Atlas'), 'Atlas');
}
/**
* Test basic ucwords functionality.
*
* @return void
*/
public function testUcwords()
{
$this->assertSame('Top-O-The-Morning To All_of_you!', Inflector::ucwords( 'top-o-the-morning to all_of_you!'));
}
/**
* Test ucwords functionality with custom delimeters.
*
* @return void
*/
public function testUcwordsWithCustomDelimeters()
{
$this->assertSame('Top-O-The-Morning To All_Of_You!', Inflector::ucwords( 'top-o-the-morning to all_of_you!', '-_ '));
}
}

View File

@@ -0,0 +1,10 @@
<?php
namespace Doctrine\Tests;
/**
* Base testcase class for all Doctrine testcases.
*/
abstract class DoctrineTestCase extends \PHPUnit_Framework_TestCase
{
}

View File

@@ -0,0 +1,27 @@
<?php
/*
* This file bootstraps the test environment.
*/
namespace Doctrine\Tests;
error_reporting(E_ALL | E_STRICT);
// register silently failing autoloader
spl_autoload_register(function($class)
{
if (0 === strpos($class, 'Doctrine\Tests\\')) {
$path = __DIR__.'/../../'.strtr($class, '\\', '/').'.php';
if (is_file($path) && is_readable($path)) {
require_once $path;
return true;
}
} else if (0 === strpos($class, 'Doctrine\Common\\')) {
$path = __DIR__.'/../../../lib/'.($class = strtr($class, '\\', '/')).'.php';
if (is_file($path) && is_readable($path)) {
require_once $path;
return true;
}
}
});

View File

@@ -0,0 +1,5 @@
phpunit.xml
composer.lock
build
vendor
coverage.clover

View File

@@ -0,0 +1,46 @@
before_commands:
- "composer install --prefer-source"
tools:
external_code_coverage:
timeout: 600
php_code_coverage:
enabled: true
test_command: ./vendor/bin/phpunit
php_code_sniffer:
enabled: true
config:
standard: PSR2
filter:
paths: ["src/*", "tests/*"]
php_cpd:
enabled: true
excluded_dirs: ["build/*", "tests", "vendor"]
php_cs_fixer:
enabled: true
config:
level: all
filter:
paths: ["src/*", "tests/*"]
php_loc:
enabled: true
excluded_dirs: ["build", "tests", "vendor"]
php_mess_detector:
enabled: true
config:
ruleset: phpmd.xml.dist
design_rules: { eval_expression: false }
filter:
paths: ["src/*"]
php_pdepend:
enabled: true
excluded_dirs: ["build", "tests", "vendor"]
php_analyzer:
enabled: true
filter:
paths: ["src/*", "tests/*"]
php_hhvm:
enabled: true
filter:
paths: ["src/*", "tests/*"]
sensiolabs_security_checker: true

View File

@@ -0,0 +1,14 @@
#!/bin/sh
set -x
if [ "$TRAVIS_PHP_VERSION" = 'hhvm' ] || [ "$TRAVIS_PHP_VERSION" = 'hhvm-nightly' ] ; then
curl -sS https://getcomposer.org/installer > composer-installer.php
hhvm composer-installer.php
hhvm -v ResourceLimit.SocketDefaultTimeout=30 -v Http.SlowQueryThreshold=30000 composer.phar update --prefer-source
elif [ "$TRAVIS_PHP_VERSION" = '5.3.3' ] ; then
composer self-update
composer update --prefer-source --no-dev
composer dump-autoload
else
composer self-update
composer update --prefer-source
fi

View File

@@ -0,0 +1,22 @@
language: php
php:
- 5.3.3
- 5.3
- 5.4
- 5.5
- 5.6
- hhvm
before_script:
- ./.travis.install.sh
- if [ $TRAVIS_PHP_VERSION = '5.6' ]; then PHPUNIT_FLAGS="--coverage-clover coverage.clover"; else PHPUNIT_FLAGS=""; fi
script:
- if [ $TRAVIS_PHP_VERSION = '5.3.3' ]; then phpunit; fi
- if [ $TRAVIS_PHP_VERSION != '5.3.3' ]; then ./vendor/bin/phpunit $PHPUNIT_FLAGS; fi
- if [ $TRAVIS_PHP_VERSION != '5.3.3' ]; then ./vendor/bin/phpcs --standard=PSR2 ./src/ ./tests/; fi
- if [[ $TRAVIS_PHP_VERSION != '5.3.3' && $TRAVIS_PHP_VERSION != '5.4.29' && $TRAVIS_PHP_VERSION != '5.5.13' ]]; then php -n ./vendor/bin/athletic -p ./tests/DoctrineTest/InstantiatorPerformance/ -f GroupedFormatter; fi
after_script:
- if [ $TRAVIS_PHP_VERSION = '5.6' ]; then wget https://scrutinizer-ci.com/ocular.phar; php ocular.phar code-coverage:upload --format=php-clover coverage.clover; fi

View File

@@ -0,0 +1,35 @@
# Contributing
* Coding standard for the project is [PSR-2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)
* The project will follow strict [object calisthenics](http://www.slideshare.net/guilhermeblanco/object-calisthenics-applied-to-php)
* Any contribution must provide tests for additional introduced conditions
* Any un-confirmed issue needs a failing test case before being accepted
* Pull requests must be sent from a new hotfix/feature branch, not from `master`.
## Installation
To install the project and run the tests, you need to clone it first:
```sh
$ git clone git://github.com/doctrine/instantiator.git
```
You will then need to run a composer installation:
```sh
$ cd Instantiator
$ curl -s https://getcomposer.org/installer | php
$ php composer.phar update
```
## Testing
The PHPUnit version to be used is the one installed as a dev- dependency via composer:
```sh
$ ./vendor/bin/phpunit
```
Accepted coverage for new contributions is 80%. Any contribution not satisfying this requirement
won't be merged.

19
vendor/doctrine/instantiator/LICENSE vendored Normal file
View File

@@ -0,0 +1,19 @@
Copyright (c) 2014 Doctrine Project
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

40
vendor/doctrine/instantiator/README.md vendored Normal file
View File

@@ -0,0 +1,40 @@
# Instantiator
This library provides a way of avoiding usage of constructors when instantiating PHP classes.
[![Build Status](https://travis-ci.org/doctrine/instantiator.svg?branch=master)](https://travis-ci.org/doctrine/instantiator)
[![Code Coverage](https://scrutinizer-ci.com/g/doctrine/instantiator/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/doctrine/instantiator/?branch=master)
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/doctrine/instantiator/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/doctrine/instantiator/?branch=master)
[![Dependency Status](https://www.versioneye.com/package/php--doctrine--instantiator/badge.svg)](https://www.versioneye.com/package/php--doctrine--instantiator)
[![HHVM Status](http://hhvm.h4cc.de/badge/doctrine/instantiator.png)](http://hhvm.h4cc.de/package/doctrine/instantiator)
[![Latest Stable Version](https://poser.pugx.org/doctrine/instantiator/v/stable.png)](https://packagist.org/packages/doctrine/instantiator)
[![Latest Unstable Version](https://poser.pugx.org/doctrine/instantiator/v/unstable.png)](https://packagist.org/packages/doctrine/instantiator)
## Installation
The suggested installation method is via [composer](https://getcomposer.org/):
```sh
php composer.phar require "doctrine/instantiator:~1.0.3"
```
## Usage
The instantiator is able to create new instances of any class without using the constructor or any API of the class
itself:
```php
$instantiator = new \Doctrine\Instantiator\Instantiator();
$instance = $instantiator->instantiate('My\\ClassName\\Here');
```
## Contributing
Please read the [CONTRIBUTING.md](CONTRIBUTING.md) contents if you wish to help out!
## Credits
This library was migrated from [ocramius/instantiator](https://github.com/Ocramius/Instantiator), which
has been donated to the doctrine organization, and which is now deprecated in favour of this package.

View File

@@ -0,0 +1,45 @@
{
"name": "doctrine/instantiator",
"description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
"type": "library",
"license": "MIT",
"homepage": "https://github.com/doctrine/instantiator",
"keywords": [
"instantiate",
"constructor"
],
"authors": [
{
"name": "Marco Pivetta",
"email": "ocramius@gmail.com",
"homepage": "http://ocramius.github.com/"
}
],
"require": {
"php": ">=5.3,<8.0-DEV"
},
"require-dev": {
"ext-phar": "*",
"ext-pdo": "*",
"phpunit/phpunit": "~4.0",
"squizlabs/php_codesniffer": "~2.0",
"athletic/athletic": "~0.1.8"
},
"autoload": {
"psr-4": {
"Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
}
},
"autoload-dev": {
"psr-0": {
"DoctrineTest\\InstantiatorPerformance\\": "tests",
"DoctrineTest\\InstantiatorTest\\": "tests",
"DoctrineTest\\InstantiatorTestAsset\\": "tests"
}
},
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
}
}

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8" ?>
<ruleset
name="Instantiator rules"
xmlns="http://pmd.sf.net/ruleset/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd"
xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd"
>
<rule ref="rulesets/cleancode.xml">
<!-- static access is used for caching purposes -->
<exclude name="StaticAccess"/>
</rule>
<rule ref="rulesets/codesize.xml"/>
<rule ref="rulesets/controversial.xml"/>
<rule ref="rulesets/design.xml"/>
<rule ref="rulesets/naming.xml"/>
<rule ref="rulesets/unusedcode.xml"/>
<rule
name="NPathComplexity"
message="The {0} {1}() has an NPath complexity of {2}. The configured NPath complexity threshold is {3}."
class="PHP_PMD_Rule_Design_NpathComplexity"
>
<properties>
<property name="minimum" description="The npath reporting threshold" value="10"/>
</properties>
</rule>
</ruleset>

View File

@@ -0,0 +1,22 @@
<?xml version="1.0"?>
<phpunit
bootstrap="./vendor/autoload.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
verbose="true"
stopOnFailure="false"
processIsolation="false"
backupGlobals="false"
syntaxCheck="true"
>
<testsuite name="Doctrine\Instantiator tests">
<directory>./tests/DoctrineTest/InstantiatorTest</directory>
</testsuite>
<filter>
<whitelist addUncoveredFilesFromWhitelist="true">
<directory suffix=".php">./src</directory>
</whitelist>
</filter>
</phpunit>

View File

@@ -0,0 +1,29 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Instantiator\Exception;
/**
* Base exception marker interface for the instantiator component
*
* @author Marco Pivetta <ocramius@gmail.com>
*/
interface ExceptionInterface
{
}

View File

@@ -0,0 +1,62 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Instantiator\Exception;
use InvalidArgumentException as BaseInvalidArgumentException;
use ReflectionClass;
/**
* Exception for invalid arguments provided to the instantiator
*
* @author Marco Pivetta <ocramius@gmail.com>
*/
class InvalidArgumentException extends BaseInvalidArgumentException implements ExceptionInterface
{
/**
* @param string $className
*
* @return self
*/
public static function fromNonExistingClass($className)
{
if (interface_exists($className)) {
return new self(sprintf('The provided type "%s" is an interface, and can not be instantiated', $className));
}
if (PHP_VERSION_ID >= 50400 && trait_exists($className)) {
return new self(sprintf('The provided type "%s" is a trait, and can not be instantiated', $className));
}
return new self(sprintf('The provided class "%s" does not exist', $className));
}
/**
* @param ReflectionClass $reflectionClass
*
* @return self
*/
public static function fromAbstractClass(ReflectionClass $reflectionClass)
{
return new self(sprintf(
'The provided class "%s" is abstract, and can not be instantiated',
$reflectionClass->getName()
));
}
}

View File

@@ -0,0 +1,79 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Instantiator\Exception;
use Exception;
use ReflectionClass;
use UnexpectedValueException as BaseUnexpectedValueException;
/**
* Exception for given parameters causing invalid/unexpected state on instantiation
*
* @author Marco Pivetta <ocramius@gmail.com>
*/
class UnexpectedValueException extends BaseUnexpectedValueException implements ExceptionInterface
{
/**
* @param ReflectionClass $reflectionClass
* @param Exception $exception
*
* @return self
*/
public static function fromSerializationTriggeredException(ReflectionClass $reflectionClass, Exception $exception)
{
return new self(
sprintf(
'An exception was raised while trying to instantiate an instance of "%s" via un-serialization',
$reflectionClass->getName()
),
0,
$exception
);
}
/**
* @param ReflectionClass $reflectionClass
* @param string $errorString
* @param int $errorCode
* @param string $errorFile
* @param int $errorLine
*
* @return UnexpectedValueException
*/
public static function fromUncleanUnSerialization(
ReflectionClass $reflectionClass,
$errorString,
$errorCode,
$errorFile,
$errorLine
) {
return new self(
sprintf(
'Could not produce an instance of "%s" via un-serialization, since an error was triggered '
. 'in file "%s" at line "%d"',
$reflectionClass->getName(),
$errorFile,
$errorLine
),
0,
new Exception($errorString, $errorCode)
);
}
}

View File

@@ -0,0 +1,273 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Instantiator;
use Closure;
use Doctrine\Instantiator\Exception\InvalidArgumentException;
use Doctrine\Instantiator\Exception\UnexpectedValueException;
use Exception;
use ReflectionClass;
/**
* {@inheritDoc}
*
* @author Marco Pivetta <ocramius@gmail.com>
*/
final class Instantiator implements InstantiatorInterface
{
/**
* Markers used internally by PHP to define whether {@see \unserialize} should invoke
* the method {@see \Serializable::unserialize()} when dealing with classes implementing
* the {@see \Serializable} interface.
*/
const SERIALIZATION_FORMAT_USE_UNSERIALIZER = 'C';
const SERIALIZATION_FORMAT_AVOID_UNSERIALIZER = 'O';
/**
* @var \Closure[] of {@see \Closure} instances used to instantiate specific classes
*/
private static $cachedInstantiators = array();
/**
* @var object[] of objects that can directly be cloned
*/
private static $cachedCloneables = array();
/**
* {@inheritDoc}
*/
public function instantiate($className)
{
if (isset(self::$cachedCloneables[$className])) {
return clone self::$cachedCloneables[$className];
}
if (isset(self::$cachedInstantiators[$className])) {
$factory = self::$cachedInstantiators[$className];
return $factory();
}
return $this->buildAndCacheFromFactory($className);
}
/**
* Builds the requested object and caches it in static properties for performance
*
* @param string $className
*
* @return object
*/
private function buildAndCacheFromFactory($className)
{
$factory = self::$cachedInstantiators[$className] = $this->buildFactory($className);
$instance = $factory();
if ($this->isSafeToClone(new ReflectionClass($instance))) {
self::$cachedCloneables[$className] = clone $instance;
}
return $instance;
}
/**
* Builds a {@see \Closure} capable of instantiating the given $className without
* invoking its constructor.
*
* @param string $className
*
* @return Closure
*/
private function buildFactory($className)
{
$reflectionClass = $this->getReflectionClass($className);
if ($this->isInstantiableViaReflection($reflectionClass)) {
return function () use ($reflectionClass) {
return $reflectionClass->newInstanceWithoutConstructor();
};
}
$serializedString = sprintf(
'%s:%d:"%s":0:{}',
$this->getSerializationFormat($reflectionClass),
strlen($className),
$className
);
$this->checkIfUnSerializationIsSupported($reflectionClass, $serializedString);
return function () use ($serializedString) {
return unserialize($serializedString);
};
}
/**
* @param string $className
*
* @return ReflectionClass
*
* @throws InvalidArgumentException
*/
private function getReflectionClass($className)
{
if (! class_exists($className)) {
throw InvalidArgumentException::fromNonExistingClass($className);
}
$reflection = new ReflectionClass($className);
if ($reflection->isAbstract()) {
throw InvalidArgumentException::fromAbstractClass($reflection);
}
return $reflection;
}
/**
* @param ReflectionClass $reflectionClass
* @param string $serializedString
*
* @throws UnexpectedValueException
*
* @return void
*/
private function checkIfUnSerializationIsSupported(ReflectionClass $reflectionClass, $serializedString)
{
set_error_handler(function ($code, $message, $file, $line) use ($reflectionClass, & $error) {
$error = UnexpectedValueException::fromUncleanUnSerialization(
$reflectionClass,
$message,
$code,
$file,
$line
);
});
$this->attemptInstantiationViaUnSerialization($reflectionClass, $serializedString);
restore_error_handler();
if ($error) {
throw $error;
}
}
/**
* @param ReflectionClass $reflectionClass
* @param string $serializedString
*
* @throws UnexpectedValueException
*
* @return void
*/
private function attemptInstantiationViaUnSerialization(ReflectionClass $reflectionClass, $serializedString)
{
try {
unserialize($serializedString);
} catch (Exception $exception) {
restore_error_handler();
throw UnexpectedValueException::fromSerializationTriggeredException($reflectionClass, $exception);
}
}
/**
* @param ReflectionClass $reflectionClass
*
* @return bool
*/
private function isInstantiableViaReflection(ReflectionClass $reflectionClass)
{
if (\PHP_VERSION_ID >= 50600) {
return ! ($this->hasInternalAncestors($reflectionClass) && $reflectionClass->isFinal());
}
return \PHP_VERSION_ID >= 50400 && ! $this->hasInternalAncestors($reflectionClass);
}
/**
* Verifies whether the given class is to be considered internal
*
* @param ReflectionClass $reflectionClass
*
* @return bool
*/
private function hasInternalAncestors(ReflectionClass $reflectionClass)
{
do {
if ($reflectionClass->isInternal()) {
return true;
}
} while ($reflectionClass = $reflectionClass->getParentClass());
return false;
}
/**
* Verifies if the given PHP version implements the `Serializable` interface serialization
* with an incompatible serialization format. If that's the case, use serialization marker
* "C" instead of "O".
*
* @link http://news.php.net/php.internals/74654
*
* @param ReflectionClass $reflectionClass
*
* @return string the serialization format marker, either self::SERIALIZATION_FORMAT_USE_UNSERIALIZER
* or self::SERIALIZATION_FORMAT_AVOID_UNSERIALIZER
*/
private function getSerializationFormat(ReflectionClass $reflectionClass)
{
if ($this->isPhpVersionWithBrokenSerializationFormat()
&& $reflectionClass->implementsInterface('Serializable')
) {
return self::SERIALIZATION_FORMAT_USE_UNSERIALIZER;
}
return self::SERIALIZATION_FORMAT_AVOID_UNSERIALIZER;
}
/**
* Checks whether the current PHP runtime uses an incompatible serialization format
*
* @return bool
*/
private function isPhpVersionWithBrokenSerializationFormat()
{
return PHP_VERSION_ID === 50429 || PHP_VERSION_ID === 50513;
}
/**
* Checks if a class is cloneable
*
* @param ReflectionClass $reflection
*
* @return bool
*/
private function isSafeToClone(ReflectionClass $reflection)
{
if (method_exists($reflection, 'isCloneable') && ! $reflection->isCloneable()) {
return false;
}
// not cloneable if it implements `__clone`, as we want to avoid calling it
return ! $reflection->hasMethod('__clone');
}
}

View File

@@ -0,0 +1,37 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Instantiator;
/**
* Instantiator provides utility methods to build objects without invoking their constructors
*
* @author Marco Pivetta <ocramius@gmail.com>
*/
interface InstantiatorInterface
{
/**
* @param string $className
*
* @return object
*
* @throws \Doctrine\Instantiator\Exception\ExceptionInterface
*/
public function instantiate($className);
}

View File

@@ -0,0 +1,96 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace DoctrineTest\InstantiatorPerformance;
use Athletic\AthleticEvent;
use Doctrine\Instantiator\Instantiator;
/**
* Performance tests for {@see \Doctrine\Instantiator\Instantiator}
*
* @author Marco Pivetta <ocramius@gmail.com>
*/
class InstantiatorPerformanceEvent extends AthleticEvent
{
/**
* @var \Doctrine\Instantiator\Instantiator
*/
private $instantiator;
/**
* {@inheritDoc}
*/
protected function setUp()
{
$this->instantiator = new Instantiator();
$this->instantiator->instantiate(__CLASS__);
$this->instantiator->instantiate('ArrayObject');
$this->instantiator->instantiate('DoctrineTest\\InstantiatorTestAsset\\SimpleSerializableAsset');
$this->instantiator->instantiate('DoctrineTest\\InstantiatorTestAsset\\SerializableArrayObjectAsset');
$this->instantiator->instantiate('DoctrineTest\\InstantiatorTestAsset\\UnCloneableAsset');
}
/**
* @iterations 20000
* @baseline
* @group instantiation
*/
public function testInstantiateSelf()
{
$this->instantiator->instantiate(__CLASS__);
}
/**
* @iterations 20000
* @group instantiation
*/
public function testInstantiateInternalClass()
{
$this->instantiator->instantiate('ArrayObject');
}
/**
* @iterations 20000
* @group instantiation
*/
public function testInstantiateSimpleSerializableAssetClass()
{
$this->instantiator->instantiate('DoctrineTest\\InstantiatorTestAsset\\SimpleSerializableAsset');
}
/**
* @iterations 20000
* @group instantiation
*/
public function testInstantiateSerializableArrayObjectAsset()
{
$this->instantiator->instantiate('DoctrineTest\\InstantiatorTestAsset\\SerializableArrayObjectAsset');
}
/**
* @iterations 20000
* @group instantiation
*/
public function testInstantiateUnCloneableAsset()
{
$this->instantiator->instantiate('DoctrineTest\\InstantiatorTestAsset\\UnCloneableAsset');
}
}

View File

@@ -0,0 +1,83 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace DoctrineTest\InstantiatorTest\Exception;
use Doctrine\Instantiator\Exception\InvalidArgumentException;
use PHPUnit_Framework_TestCase;
use ReflectionClass;
/**
* Tests for {@see \Doctrine\Instantiator\Exception\InvalidArgumentException}
*
* @author Marco Pivetta <ocramius@gmail.com>
*
* @covers \Doctrine\Instantiator\Exception\InvalidArgumentException
*/
class InvalidArgumentExceptionTest extends PHPUnit_Framework_TestCase
{
public function testFromNonExistingTypeWithNonExistingClass()
{
$className = __CLASS__ . uniqid();
$exception = InvalidArgumentException::fromNonExistingClass($className);
$this->assertInstanceOf('Doctrine\\Instantiator\\Exception\\InvalidArgumentException', $exception);
$this->assertSame('The provided class "' . $className . '" does not exist', $exception->getMessage());
}
public function testFromNonExistingTypeWithTrait()
{
if (PHP_VERSION_ID < 50400) {
$this->markTestSkipped('Need at least PHP 5.4.0, as this test requires traits support to run');
}
$exception = InvalidArgumentException::fromNonExistingClass(
'DoctrineTest\\InstantiatorTestAsset\\SimpleTraitAsset'
);
$this->assertSame(
'The provided type "DoctrineTest\\InstantiatorTestAsset\\SimpleTraitAsset" is a trait, '
. 'and can not be instantiated',
$exception->getMessage()
);
}
public function testFromNonExistingTypeWithInterface()
{
$exception = InvalidArgumentException::fromNonExistingClass('Doctrine\\Instantiator\\InstantiatorInterface');
$this->assertSame(
'The provided type "Doctrine\\Instantiator\\InstantiatorInterface" is an interface, '
. 'and can not be instantiated',
$exception->getMessage()
);
}
public function testFromAbstractClass()
{
$reflection = new ReflectionClass('DoctrineTest\\InstantiatorTestAsset\\AbstractClassAsset');
$exception = InvalidArgumentException::fromAbstractClass($reflection);
$this->assertSame(
'The provided class "DoctrineTest\\InstantiatorTestAsset\\AbstractClassAsset" is abstract, '
. 'and can not be instantiated',
$exception->getMessage()
);
}
}

View File

@@ -0,0 +1,69 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace DoctrineTest\InstantiatorTest\Exception;
use Doctrine\Instantiator\Exception\UnexpectedValueException;
use Exception;
use PHPUnit_Framework_TestCase;
use ReflectionClass;
/**
* Tests for {@see \Doctrine\Instantiator\Exception\UnexpectedValueException}
*
* @author Marco Pivetta <ocramius@gmail.com>
*
* @covers \Doctrine\Instantiator\Exception\UnexpectedValueException
*/
class UnexpectedValueExceptionTest extends PHPUnit_Framework_TestCase
{
public function testFromSerializationTriggeredException()
{
$reflectionClass = new ReflectionClass($this);
$previous = new Exception();
$exception = UnexpectedValueException::fromSerializationTriggeredException($reflectionClass, $previous);
$this->assertInstanceOf('Doctrine\\Instantiator\\Exception\\UnexpectedValueException', $exception);
$this->assertSame($previous, $exception->getPrevious());
$this->assertSame(
'An exception was raised while trying to instantiate an instance of "'
. __CLASS__ . '" via un-serialization',
$exception->getMessage()
);
}
public function testFromUncleanUnSerialization()
{
$reflection = new ReflectionClass('DoctrineTest\\InstantiatorTestAsset\\AbstractClassAsset');
$exception = UnexpectedValueException::fromUncleanUnSerialization($reflection, 'foo', 123, 'bar', 456);
$this->assertInstanceOf('Doctrine\\Instantiator\\Exception\\UnexpectedValueException', $exception);
$this->assertSame(
'Could not produce an instance of "DoctrineTest\\InstantiatorTestAsset\\AbstractClassAsset" '
. 'via un-serialization, since an error was triggered in file "bar" at line "456"',
$exception->getMessage()
);
$previous = $exception->getPrevious();
$this->assertInstanceOf('Exception', $previous);
$this->assertSame('foo', $previous->getMessage());
$this->assertSame(123, $previous->getCode());
}
}

View File

@@ -0,0 +1,219 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace DoctrineTest\InstantiatorTest;
use Doctrine\Instantiator\Exception\UnexpectedValueException;
use Doctrine\Instantiator\Instantiator;
use PHPUnit_Framework_TestCase;
use ReflectionClass;
/**
* Tests for {@see \Doctrine\Instantiator\Instantiator}
*
* @author Marco Pivetta <ocramius@gmail.com>
*
* @covers \Doctrine\Instantiator\Instantiator
*/
class InstantiatorTest extends PHPUnit_Framework_TestCase
{
/**
* @var Instantiator
*/
private $instantiator;
/**
* {@inheritDoc}
*/
protected function setUp()
{
$this->instantiator = new Instantiator();
}
/**
* @param string $className
*
* @dataProvider getInstantiableClasses
*/
public function testCanInstantiate($className)
{
$this->assertInstanceOf($className, $this->instantiator->instantiate($className));
}
/**
* @param string $className
*
* @dataProvider getInstantiableClasses
*/
public function testInstantiatesSeparateInstances($className)
{
$instance1 = $this->instantiator->instantiate($className);
$instance2 = $this->instantiator->instantiate($className);
$this->assertEquals($instance1, $instance2);
$this->assertNotSame($instance1, $instance2);
}
public function testExceptionOnUnSerializationException()
{
if (defined('HHVM_VERSION')) {
$this->markTestSkipped(
'As of facebook/hhvm#3432, HHVM has no PDORow, and therefore '
. ' no internal final classes that cannot be instantiated'
);
}
$className = 'DoctrineTest\\InstantiatorTestAsset\\UnserializeExceptionArrayObjectAsset';
if (\PHP_VERSION_ID >= 50600) {
$className = 'PDORow';
}
if (\PHP_VERSION_ID === 50429 || \PHP_VERSION_ID === 50513) {
$className = 'DoctrineTest\\InstantiatorTestAsset\\SerializableArrayObjectAsset';
}
$this->setExpectedException('Doctrine\\Instantiator\\Exception\\UnexpectedValueException');
$this->instantiator->instantiate($className);
}
public function testNoticeOnUnSerializationException()
{
if (\PHP_VERSION_ID >= 50600) {
$this->markTestSkipped(
'PHP 5.6 supports `ReflectionClass#newInstanceWithoutConstructor()` for some internal classes'
);
}
try {
$this->instantiator->instantiate('DoctrineTest\\InstantiatorTestAsset\\WakeUpNoticesAsset');
$this->fail('No exception was raised');
} catch (UnexpectedValueException $exception) {
$wakeUpNoticesReflection = new ReflectionClass('DoctrineTest\\InstantiatorTestAsset\\WakeUpNoticesAsset');
$previous = $exception->getPrevious();
$this->assertInstanceOf('Exception', $previous);
// in PHP 5.4.29 and PHP 5.5.13, this case is not a notice, but an exception being thrown
if (! (\PHP_VERSION_ID === 50429 || \PHP_VERSION_ID === 50513)) {
$this->assertSame(
'Could not produce an instance of "DoctrineTest\\InstantiatorTestAsset\WakeUpNoticesAsset" '
. 'via un-serialization, since an error was triggered in file "'
. $wakeUpNoticesReflection->getFileName() . '" at line "36"',
$exception->getMessage()
);
$this->assertSame('Something went bananas while un-serializing this instance', $previous->getMessage());
$this->assertSame(\E_USER_NOTICE, $previous->getCode());
}
}
}
/**
* @param string $invalidClassName
*
* @dataProvider getInvalidClassNames
*/
public function testInstantiationFromNonExistingClass($invalidClassName)
{
$this->setExpectedException('Doctrine\\Instantiator\\Exception\\InvalidArgumentException');
$this->instantiator->instantiate($invalidClassName);
}
public function testInstancesAreNotCloned()
{
$className = 'TemporaryClass' . uniqid();
eval('namespace ' . __NAMESPACE__ . '; class ' . $className . '{}');
$instance = $this->instantiator->instantiate(__NAMESPACE__ . '\\' . $className);
$instance->foo = 'bar';
$instance2 = $this->instantiator->instantiate(__NAMESPACE__ . '\\' . $className);
$this->assertObjectNotHasAttribute('foo', $instance2);
}
/**
* Provides a list of instantiable classes (existing)
*
* @return string[][]
*/
public function getInstantiableClasses()
{
$classes = array(
array('stdClass'),
array(__CLASS__),
array('Doctrine\\Instantiator\\Instantiator'),
array('Exception'),
array('PharException'),
array('DoctrineTest\\InstantiatorTestAsset\\SimpleSerializableAsset'),
array('DoctrineTest\\InstantiatorTestAsset\\ExceptionAsset'),
array('DoctrineTest\\InstantiatorTestAsset\\FinalExceptionAsset'),
array('DoctrineTest\\InstantiatorTestAsset\\PharExceptionAsset'),
array('DoctrineTest\\InstantiatorTestAsset\\UnCloneableAsset'),
array('DoctrineTest\\InstantiatorTestAsset\\XMLReaderAsset'),
);
if (\PHP_VERSION_ID === 50429 || \PHP_VERSION_ID === 50513) {
return $classes;
}
$classes = array_merge(
$classes,
array(
array('PharException'),
array('ArrayObject'),
array('DoctrineTest\\InstantiatorTestAsset\\ArrayObjectAsset'),
array('DoctrineTest\\InstantiatorTestAsset\\SerializableArrayObjectAsset'),
)
);
if (\PHP_VERSION_ID >= 50600) {
$classes[] = array('DoctrineTest\\InstantiatorTestAsset\\WakeUpNoticesAsset');
$classes[] = array('DoctrineTest\\InstantiatorTestAsset\\UnserializeExceptionArrayObjectAsset');
}
return $classes;
}
/**
* Provides a list of instantiable classes (existing)
*
* @return string[][]
*/
public function getInvalidClassNames()
{
$classNames = array(
array(__CLASS__ . uniqid()),
array('Doctrine\\Instantiator\\InstantiatorInterface'),
array('DoctrineTest\\InstantiatorTestAsset\\AbstractClassAsset'),
);
if (\PHP_VERSION_ID >= 50400) {
$classNames[] = array('DoctrineTest\\InstantiatorTestAsset\\SimpleTraitAsset');
}
return $classNames;
}
}

View File

@@ -0,0 +1,29 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace DoctrineTest\InstantiatorTestAsset;
/**
* A simple asset for an abstract class
*
* @author Marco Pivetta <ocramius@gmail.com>
*/
abstract class AbstractClassAsset
{
}

View File

@@ -0,0 +1,41 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace DoctrineTest\InstantiatorTestAsset;
use ArrayObject;
use BadMethodCallException;
/**
* Test asset that extends an internal PHP class
*
* @author Marco Pivetta <ocramius@gmail.com>
*/
class ArrayObjectAsset extends ArrayObject
{
/**
* Constructor - should not be called
*
* @throws BadMethodCallException
*/
public function __construct()
{
throw new BadMethodCallException('Not supposed to be called!');
}
}

View File

@@ -0,0 +1,41 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace DoctrineTest\InstantiatorTestAsset;
use BadMethodCallException;
use Exception;
/**
* Test asset that extends an internal PHP base exception
*
* @author Marco Pivetta <ocramius@gmail.com>
*/
class ExceptionAsset extends Exception
{
/**
* Constructor - should not be called
*
* @throws BadMethodCallException
*/
public function __construct()
{
throw new BadMethodCallException('Not supposed to be called!');
}
}

View File

@@ -0,0 +1,41 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace DoctrineTest\InstantiatorTestAsset;
use BadMethodCallException;
use Exception;
/**
* Test asset that extends an internal PHP base exception
*
* @author Marco Pivetta <ocramius@gmail.com>
*/
final class FinalExceptionAsset extends Exception
{
/**
* Constructor - should not be called
*
* @throws BadMethodCallException
*/
public function __construct()
{
throw new BadMethodCallException('Not supposed to be called!');
}
}

View File

@@ -0,0 +1,41 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace DoctrineTest\InstantiatorTestAsset;
use BadMethodCallException;
use Phar;
/**
* Test asset that extends an internal PHP class
*
* @author Marco Pivetta <ocramius@gmail.com>
*/
class PharAsset extends Phar
{
/**
* Constructor - should not be called
*
* @throws BadMethodCallException
*/
public function __construct()
{
throw new BadMethodCallException('Not supposed to be called!');
}
}

View File

@@ -0,0 +1,44 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace DoctrineTest\InstantiatorTestAsset;
use BadMethodCallException;
use PharException;
/**
* Test asset that extends an internal PHP class
* This class should be serializable without problems
* and without getting the "Erroneous data format for unserializing"
* error
*
* @author Marco Pivetta <ocramius@gmail.com>
*/
class PharExceptionAsset extends PharException
{
/**
* Constructor - should not be called
*
* @throws BadMethodCallException
*/
public function __construct()
{
throw new BadMethodCallException('Not supposed to be called!');
}
}

View File

@@ -0,0 +1,62 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace DoctrineTest\InstantiatorTestAsset;
use ArrayObject;
use BadMethodCallException;
use Serializable;
/**
* Serializable test asset that also extends an internal class
*
* @author Marco Pivetta <ocramius@gmail.com>
*/
class SerializableArrayObjectAsset extends ArrayObject implements Serializable
{
/**
* Constructor - should not be called
*
* @throws BadMethodCallException
*/
public function __construct()
{
throw new BadMethodCallException('Not supposed to be called!');
}
/**
* {@inheritDoc}
*/
public function serialize()
{
return '';
}
/**
* {@inheritDoc}
*
* Should not be called
*
* @throws BadMethodCallException
*/
public function unserialize($serialized)
{
throw new BadMethodCallException('Not supposed to be called!');
}
}

View File

@@ -0,0 +1,61 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace DoctrineTest\InstantiatorTestAsset;
use BadMethodCallException;
use Serializable;
/**
* Base serializable test asset
*
* @author Marco Pivetta <ocramius@gmail.com>
*/
class SimpleSerializableAsset implements Serializable
{
/**
* Constructor - should not be called
*
* @throws BadMethodCallException
*/
public function __construct()
{
throw new BadMethodCallException('Not supposed to be called!');
}
/**
* {@inheritDoc}
*/
public function serialize()
{
return '';
}
/**
* {@inheritDoc}
*
* Should not be called
*
* @throws BadMethodCallException
*/
public function unserialize($serialized)
{
throw new BadMethodCallException('Not supposed to be called!');
}
}

View File

@@ -0,0 +1,29 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace DoctrineTest\InstantiatorTestAsset;
/**
* A simple trait with no attached logic
*
* @author Marco Pivetta <ocramius@gmail.com>
*/
trait SimpleTraitAsset
{
}

View File

@@ -0,0 +1,50 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace DoctrineTest\InstantiatorTestAsset;
use BadMethodCallException;
/**
* Base un-cloneable asset
*
* @author Marco Pivetta <ocramius@gmail.com>
*/
class UnCloneableAsset
{
/**
* Constructor - should not be called
*
* @throws BadMethodCallException
*/
public function __construct()
{
throw new BadMethodCallException('Not supposed to be called!');
}
/**
* Magic `__clone` - should not be invoked
*
* @throws BadMethodCallException
*/
public function __clone()
{
throw new BadMethodCallException('Not supposed to be called!');
}
}

View File

@@ -0,0 +1,39 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace DoctrineTest\InstantiatorTestAsset;
use ArrayObject;
use BadMethodCallException;
/**
* A simple asset for an abstract class
*
* @author Marco Pivetta <ocramius@gmail.com>
*/
class UnserializeExceptionArrayObjectAsset extends ArrayObject
{
/**
* {@inheritDoc}
*/
public function __wakeup()
{
throw new BadMethodCallException();
}
}

View File

@@ -0,0 +1,38 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace DoctrineTest\InstantiatorTestAsset;
use ArrayObject;
/**
* A simple asset for an abstract class
*
* @author Marco Pivetta <ocramius@gmail.com>
*/
class WakeUpNoticesAsset extends ArrayObject
{
/**
* Wakeup method called after un-serialization
*/
public function __wakeup()
{
trigger_error('Something went bananas while un-serializing this instance');
}
}

View File

@@ -0,0 +1,41 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace DoctrineTest\InstantiatorTestAsset;
use BadMethodCallException;
use XMLReader;
/**
* Test asset that extends an internal PHP class
*
* @author Dave Marshall <dave@atst.io>
*/
class XMLReaderAsset extends XMLReader
{
/**
* Constructor - should not be called
*
* @throws BadMethodCallException
*/
public function __construct()
{
throw new BadMethodCallException('Not supposed to be called!');
}
}

20
vendor/erusev/parsedown/LICENSE.txt vendored Normal file
View File

@@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2013 Emanuil Rusev, erusev.com
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

1548
vendor/erusev/parsedown/Parsedown.php vendored Normal file

File diff suppressed because it is too large Load Diff

56
vendor/erusev/parsedown/README.md vendored Normal file
View File

@@ -0,0 +1,56 @@
> You might also like [Caret](https://caret.io?ref=parsedown) - our Markdown editor for Mac / Windows / Linux.
## Parsedown
[![Build Status](https://img.shields.io/travis/erusev/parsedown/master.svg?style=flat-square)](https://travis-ci.org/erusev/parsedown)
<!--[![Total Downloads](http://img.shields.io/packagist/dt/erusev/parsedown.svg?style=flat-square)](https://packagist.org/packages/erusev/parsedown)-->
Better Markdown Parser in PHP
[Demo](http://parsedown.org/demo) |
[Benchmarks](http://parsedown.org/speed) |
[Tests](http://parsedown.org/tests/) |
[Documentation](https://github.com/erusev/parsedown/wiki/)
### Features
* One File
* Super Fast
* Extensible
* [GitHub flavored](https://help.github.com/articles/github-flavored-markdown)
* Tested in 5.3 to 7.1 and in HHVM
* [Markdown Extra extension](https://github.com/erusev/parsedown-extra)
### Installation
Include `Parsedown.php` or install [the composer package](https://packagist.org/packages/erusev/parsedown).
### Example
``` php
$Parsedown = new Parsedown();
echo $Parsedown->text('Hello _Parsedown_!'); # prints: <p>Hello <em>Parsedown</em>!</p>
```
More examples in [the wiki](https://github.com/erusev/parsedown/wiki/) and in [this video tutorial](http://youtu.be/wYZBY8DEikI).
### Questions
**How does Parsedown work?**
It tries to read Markdown like a human. First, it looks at the lines. Its interested in how the lines start. This helps it recognise blocks. It knows, for example, that if a line starts with a `-` then perhaps it belongs to a list. Once it recognises the blocks, it continues to the content. As it reads, it watches out for special characters. This helps it recognise inline elements (or inlines).
We call this approach "line based". We believe that Parsedown is the first Markdown parser to use it. Since the release of Parsedown, other developers have used the same approach to develop other Markdown parsers in PHP and in other languages.
**Is it compliant with CommonMark?**
It passes most of the CommonMark tests. Most of the tests that don't pass deal with cases that are quite uncommon. Still, as CommonMark matures, compliance should improve.
**Who uses it?**
[phpDocumentor](http://www.phpdoc.org/), [October CMS](http://octobercms.com/), [Bolt CMS](http://bolt.cm/), [Kirby CMS](http://getkirby.com/), [Grav CMS](http://getgrav.org/), [Statamic CMS](http://www.statamic.com/), [Herbie CMS](http://www.getherbie.org/), [RaspberryPi.org](http://www.raspberrypi.org/), [Symfony demo](https://github.com/symfony/symfony-demo) and [more](https://packagist.org/packages/erusev/parsedown/dependents).
**How can I help?**
Use it, star it, share it and if you feel generous, [donate](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=528P3NZQMP8N2).

21
vendor/erusev/parsedown/composer.json vendored Normal file
View File

@@ -0,0 +1,21 @@
{
"name": "erusev/parsedown",
"description": "Parser for Markdown.",
"keywords": ["markdown", "parser"],
"homepage": "http://parsedown.org",
"type": "library",
"license": "MIT",
"authors": [
{
"name": "Emanuil Rusev",
"email": "hello@erusev.com",
"homepage": "http://erusev.com"
}
],
"require": {
"php": ">=5.3.0"
},
"autoload": {
"psr-0": {"Parsedown": ""}
}
}

2
vendor/fzaninotto/faker/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
vendor
composer.lock

21
vendor/fzaninotto/faker/.travis.yml vendored Normal file
View File

@@ -0,0 +1,21 @@
language: php
php:
- 5.3
- 5.4
- 5.5
- 5.6
- 7.0
- hhvm
sudo: false
cache:
directories:
- $HOME/.composer/cache
before_script:
- travis_retry composer self-update
- travis_retry composer install --no-interaction --prefer-dist
script: make sniff test

295
vendor/fzaninotto/faker/CHANGELOG.md vendored Normal file
View File

@@ -0,0 +1,295 @@
CHANGELOG
=========
2015-05-29, v1.5.0
------------------
* Added ability to print custom text on the images fetched by the Image provider [\#583](https://github.com/fzaninotto/Faker/pull/583) ([fzaninotto](https://github.com/fzaninotto))
* Fixed typos in Preuvian (es\_PE) Person provider [\#581](https://github.com/fzaninotto/Faker/pull/581) [\#580](https://github.com/fzaninotto/Faker/pull/580) ([ysramirez](https://github.com/ysramirez))
* Added instructions for installing with composer to readme.md [\#572](https://github.com/fzaninotto/Faker/pull/572) ([totophe](https://github.com/totophe))
* Added Kazakh (kk\_KZ) locale [\#569](https://github.com/fzaninotto/Faker/pull/569) ([YerlenZhubangaliyev](https://github.com/YerlenZhubangaliyev))
* Added Korean (ko\_KR) locale [\#566](https://github.com/fzaninotto/Faker/pull/566) ([pearlc](https://github.com/pearlc))
* Fixed file provider to ignore unreadable and special files [\#565](https://github.com/fzaninotto/Faker/pull/565) ([svrnm](https://github.com/svrnm))
* Fixed Dutch (nl\_NL) Address and Person providers [\#560](https://github.com/fzaninotto/Faker/pull/560) ([killerog](https://github.com/killerog))
* Fixed Dutch (nl\_NL) Person provider [\#559](https://github.com/fzaninotto/Faker/pull/559) ([pauledenburg](https://github.com/pauledenburg))
* Added Russian (ru\_RU) Bank names provider [\#553](https://github.com/fzaninotto/Faker/pull/553) ([wizardjedi](https://github.com/wizardjedi))
* Added mobile phone function in French (fr\_FR) provider [\#552](https://github.com/fzaninotto/Faker/pull/552) ([kletellier](https://github.com/kletellier))
* Added phpdoc for new magic methods in Generator to help IntelliSense completion [\#550](https://github.com/fzaninotto/Faker/pull/550) ([stof](https://github.com/stof))
* Fixed File provider bug 'The first argument to copy() function cannot be a directory' [\#547](https://github.com/fzaninotto/Faker/pull/547) ([svrnm](https://github.com/svrnm))
* Added new Brazilian (pt\_BR) Providers [\#545](https://github.com/fzaninotto/Faker/pull/545) ([igorsantos07](https://github.com/igorsantos07))
* Fixed ability to seed the generator [\#543](https://github.com/fzaninotto/Faker/pull/543) ([schmengler](https://github.com/schmengler))
* Added streetAddress formatter to Russian (ru\_RU) provider [\#542](https://github.com/fzaninotto/Faker/pull/542) ([ZAYEC77](https://github.com/ZAYEC77))
* Fixed Internet provider warning "Could not create transliterator"* [\#541](https://github.com/fzaninotto/Faker/pull/541) ([fonsecas72](https://github.com/fonsecas72))
* Fixed Spanish for Argentina (es\_AR) Address provider [\#540](https://github.com/fzaninotto/Faker/pull/540) ([ivanmirson](https://github.com/ivanmirson))
* Fixed region names in French for Belgium (fr\_BE) address provider [\#536](https://github.com/fzaninotto/Faker/pull/536) ([miclf](https://github.com/miclf))
* Fixed broken Doctrine2 link in README [\#534](https://github.com/fzaninotto/Faker/pull/534) ([JonathanKryza](https://github.com/JonathanKryza))
* Added link to faker-context Behat extension in readme [\#532](https://github.com/fzaninotto/Faker/pull/532) ([denheck](https://github.com/denheck))
* Added PHP 7.0 nightly to Travis build targets [\#525](https://github.com/fzaninotto/Faker/pull/525) ([TomasVotruba](https://github.com/TomasVotruba))
* Added Dutch (nl\_NL) color names [\#523](https://github.com/fzaninotto/Faker/pull/523) ([belendel](https://github.com/belendel))
* Fixed Chinese (zh\_CN) Address provider (remove Taipei) [\#522](https://github.com/fzaninotto/Faker/pull/522) ([asika32764](https://github.com/asika32764))
* Fixed phonenumber formats in Dutch (nl\_NL) PhoneNumber provider [\#521](https://github.com/fzaninotto/Faker/pull/521) ([SpaceK33z](https://github.com/SpaceK33z))
* Fixed Russian (ru\_RU) Address provider [\#518](https://github.com/fzaninotto/Faker/pull/518) ([glagola](https://github.com/glagola))
* Added Italian (it\_IT) Text provider [\#517](https://github.com/fzaninotto/Faker/pull/517) ([endelwar](https://github.com/endelwar))
* Added Norwegian (no\_NO) locale [\#515](https://github.com/fzaninotto/Faker/pull/515) ([phaza](https://github.com/phaza))
* Added VAT number to Bulgarian (bg\_BG) Payment provider [\#512](https://github.com/fzaninotto/Faker/pull/512) ([ronanguilloux](https://github.com/ronanguilloux))
* Fixed UserAgent provider outdated user agents [\#511](https://github.com/fzaninotto/Faker/pull/511) ([ajbdev](https://github.com/ajbdev))
* Fixed `image()` formatter to make it work with temp dir of any (decent) OS [\#507](https://github.com/fzaninotto/Faker/pull/507) ([ronanguilloux](https://github.com/ronanguilloux))
* Added Persian (fa\_IR) locale [\#500](https://github.com/fzaninotto/Faker/pull/500) ([zoli](https://github.com/zoli))
* Added Currency Code formatter [\#497](https://github.com/fzaninotto/Faker/pull/497) ([stelgenhof](https://github.com/stelgenhof))
* Added VAT number to Belgium (be_BE) Payment provider [\#495](https://github.com/fzaninotto/Faker/pull/495) ([ronanguilloux](https://github.com/ronanguilloux))
* Fixed `imageUrl` formatter bug where it would always return the same image [\#494](https://github.com/fzaninotto/Faker/pull/494) ([fzaninotto](https://github.com/fzaninotto))
* Added more Indonesian (id\_ID) providers [\#493](https://github.com/fzaninotto/Faker/pull/493) ([deerawan](https://github.com/deerawan))
* Added Indonesian (id\_ID) locale [\#492](https://github.com/fzaninotto/Faker/pull/492) ([stoutZero](https://github.com/stoutZero))
* Fixed unique generator performance [\#491](https://github.com/fzaninotto/Faker/pull/491) ([ikwattro](https://github.com/ikwattro))
* Added transliterator to `email` and `username` [\#490](https://github.com/fzaninotto/Faker/pull/490) ([fzaninotto](https://github.com/fzaninotto))
* Added Hungarian (hu\_HU) Text provider [\#486](https://github.com/fzaninotto/Faker/pull/486) ([lintaba](https://github.com/lintaba))
* Fixed CakePHP Entity Popolator (some cases where no entities prev. inserted) [\#483](https://github.com/fzaninotto/Faker/pull/483) ([jadb](https://github.com/jadb))
* Added Color and DateTime Turkish (tr\_TR) Providers [\#481](https://github.com/fzaninotto/Faker/pull/481) ([behramcelen](https://github.com/behramcelen))
* Added Latvian (lv\_LV) `personalIdentityNumber` formatter [\#472](https://github.com/fzaninotto/Faker/pull/472) ([MatissJanis](https://github.com/MatissJanis))
* Added VAT number to Austrian (at_AT) Payment provider [\#470](https://github.com/fzaninotto/Faker/pull/470) ([ronanguilloux](https://github.com/ronanguilloux))
* Fixed missing @return phpDoc in Payment provider [\#469](https://github.com/fzaninotto/Faker/pull/469) ([ronanguilloux](https://github.com/ronanguilloux))
* Added SWIFT/BIC payment type formatter to the Payment provider [\#465](https://github.com/fzaninotto/Faker/pull/465) ([ronanguilloux](https://github.com/ronanguilloux))
* Fixed small typo in Base provider exception [\#460](https://github.com/fzaninotto/Faker/pull/460) ([miclf](https://github.com/miclf))
* Added Georgian (ka\_Ge) locale [\#457](https://github.com/fzaninotto/Faker/pull/457) ([lperto](https://github.com/lperto))
* Added PSR-4 Autoloading [\#455](https://github.com/fzaninotto/Faker/pull/455) ([GrahamCampbell](https://github.com/GrahamCampbell))
* Added Uganda (en_UG) locale [\#454](https://github.com/fzaninotto/Faker/pull/454) ([tharoldD](https://github.com/tharoldD))
* Added `regexify` formatter, generating a random string based on a regular expression [\#453](https://github.com/fzaninotto/Faker/pull/453) ([fzaninotto](https://github.com/fzaninotto))
* Added shuffle formatter, to shuffle an array or a string [\#452](https://github.com/fzaninotto/Faker/pull/452) ([fzaninotto](https://github.com/fzaninotto))
* Added ISBN-10 & ISBN-13 codes formatters to Barcode provider [\#451](https://github.com/fzaninotto/Faker/pull/451) ([gietos](https://github.com/gietos))
* Fixed Russian (ru\_RU) middle names (different for different genders) [\#450](https://github.com/fzaninotto/Faker/pull/450) ([gietos](https://github.com/gietos))
* Fixed Ukranian (uk\_UA) Person provider [\#448](https://github.com/fzaninotto/Faker/pull/448) ([aivus](https://github.com/aivus))
* Added Vietnamese (vi\_VN) locale [\#447](https://github.com/fzaninotto/Faker/pull/447) ([huy95](https://github.com/huy95))
* Added type hint to the Documentor constructor [\#446](https://github.com/fzaninotto/Faker/pull/446) ([JeroenDeDauw](https://github.com/JeroenDeDauw))
* Fixed Russian (ru\_RU) Person provider (joined names) [\#445](https://github.com/fzaninotto/Faker/pull/445) ([aivus](https://github.com/aivus))
* Added English (en\_GB) `mobileNumber` methods [\#438](https://github.com/fzaninotto/Faker/pull/438) ([daveblake](https://github.com/daveblake))
* Added Traditional Chinese (zh\_TW) Realtext provider [\#434](https://github.com/fzaninotto/Faker/pull/434) ([tzhuan](https://github.com/tzhuan))
* Fixed first name in Spanish for Argentina (es\_AR) Person provider [\#433](https://github.com/fzaninotto/Faker/pull/433) ([fzaninotto](https://github.com/fzaninotto))
* Fixed Canadian (en_CA) state abbreviation for Nunavut [\#430](https://github.com/fzaninotto/Faker/pull/430) ([julien-c](https://github.com/julien-c))
* Added CakePHP ORM entity populator [\#428](https://github.com/fzaninotto/Faker/pull/428) ([jadb](https://github.com/jadb))
* Added Traditional Chinese (zh\_TW) locale [\#427](https://github.com/fzaninotto/Faker/pull/427) ([tzhuan](https://github.com/tzhuan))
* Fixed typo in Doctrine Populator phpDoc [\#425](https://github.com/fzaninotto/Faker/pull/425) ([ihsanudin](https://github.com/ihsanudin))
* Added Chinese (zh_CN) Internet provider [\#424](https://github.com/fzaninotto/Faker/pull/424) ([Lisso-Me](https://github.com/Lisso-Me))
* Added Country ISO 3166-1 alpha-3 code to the Miscellaneous provider[\#422](https://github.com/fzaninotto/Faker/pull/422) ([gido](https://github.com/gido))
* Added English (en\_GB) Person provider [\#421](https://github.com/fzaninotto/Faker/pull/421) ([AlexCutts](https://github.com/AlexCutts))
* Added missing tests for the Color Provider [\#420](https://github.com/fzaninotto/Faker/pull/420) ([bessl](https://github.com/bessl))
* Added Nepali (ne\_NP) locale [\#419](https://github.com/fzaninotto/Faker/pull/419) ([ankitpokhrel](https://github.com/ankitpokhrel))
* Fixed latitude and longitude formatters bug (numeric value out of range for 32bits) [\#416](https://github.com/fzaninotto/Faker/pull/416) ([fzaninotto](https://github.com/fzaninotto))
* Added a dedicated calculator Luhn calculator service [\#414](https://github.com/fzaninotto/Faker/pull/414) ([fzaninotto](https://github.com/fzaninotto))
* Fixed Russian (ru_RU) Person provider (removed lowercase duplications) [\#413](https://github.com/fzaninotto/Faker/pull/413) ([Ragazzo](https://github.com/Ragazzo))
* Fixed barcode formatter (improved speed, added tests) [\#412](https://github.com/fzaninotto/Faker/pull/412) ([fzaninotto](https://github.com/fzaninotto))
* Added ipv4 and barcode formatters tests [\#410](https://github.com/fzaninotto/Faker/pull/410) ([bessl](https://github.com/bessl))
* Fixed typos in various comments blocks [\#409](https://github.com/fzaninotto/Faker/pull/409) ([bessl](https://github.com/bessl))
* Fixed InternetTest (replaced regex with PHP filter) [\#406](https://github.com/fzaninotto/Faker/pull/406) ([bessl](https://github.com/bessl))
* Added password formatter to the Internet provider[\#402](https://github.com/fzaninotto/Faker/pull/402) ([fzaninotto](https://github.com/fzaninotto))
* Added Company and Internet Austrian (de\_AT) Providers [\#400](https://github.com/fzaninotto/Faker/pull/400) ([bessl](https://github.com/bessl))
* Added third-party libraries section in README [\#399](https://github.com/fzaninotto/Faker/pull/399) ([fzaninotto](https://github.com/fzaninotto))
* Added Spanish for Venezuela (es\_VE) locale [\#398](https://github.com/fzaninotto/Faker/pull/398) ([DIOHz0r](https://github.com/DIOHz0r))
* Added PhoneNumber Autrian (de\_AT) Provider, and missing test for the 'locale' method. [\#395](https://github.com/fzaninotto/Faker/pull/395) ([bessl](https://github.com/bessl))
* Removed wrongly localized Lorem provider [\#394](https://github.com/fzaninotto/Faker/pull/394) ([fzaninotto](https://github.com/fzaninotto))
* Fixed Miscellaneous provider (made the `locale` formatter static) [\#390](https://github.com/fzaninotto/Faker/pull/390) ([bessl](https://github.com/bessl))
* Added a unit test file for the Miscellaneous Provider [\#389](https://github.com/fzaninotto/Faker/pull/389) ([bessl](https://github.com/bessl))
* Added warning in README about using `rand()`` and the seed functions [\#386](https://github.com/fzaninotto/Faker/pull/386) ([paulvalla](https://github.com/paulvalla))
* Fixed French (fr\_FR) Person provider (Uppercased a first name) [\#385](https://github.com/fzaninotto/Faker/pull/385) ([netcarver](https://github.com/netcarver))
* Added Russian (ru\_RU) and Ukrainian (uk\_UA) Text providers [\#383](https://github.com/fzaninotto/Faker/pull/383) ([terion-name](https://github.com/terion-name))
* Added more street prefixes to French (fr\_FR) Address provider [\#381](https://github.com/fzaninotto/Faker/pull/381) ([ronanguilloux](https://github.com/ronanguilloux))
* Added PHP 5.6 to CI targets [\#378](https://github.com/fzaninotto/Faker/pull/378) ([GrahamCampbell](https://github.com/GrahamCampbell))
* Fixed spaces remaining at the end of liine in various files [\#377](https://github.com/fzaninotto/Faker/pull/377) ([GrahamCampbell](https://github.com/GrahamCampbell))
* Fixed UserAgent provider (added space before processor on linux platform) [\#374](https://github.com/fzaninotto/Faker/pull/374) ([TomK](https://github.com/TomK))
* Added Company generator for Russian (ru\_RU) locale [\#371](https://github.com/fzaninotto/Faker/pull/371) ([kix](https://github.com/kix))
* Fixed Russian (ru\_RU) Color provider (uppercase letters) [\#370](https://github.com/fzaninotto/Faker/pull/370) ([semanser](https://github.com/semanser))
* Added more Polish (pl\_PL) phone numbers [\#369](https://github.com/fzaninotto/Faker/pull/369) ([piotrantosik](https://github.com/piotrantosik))
* Fixed Ruby Faker link in readme [\#368](https://github.com/fzaninotto/Faker/pull/368) ([philsturgeon](https://github.com/philsturgeon))
* Added more Japanese (ja\_JP) names in Person provider [\#366](https://github.com/fzaninotto/Faker/pull/366) ([kumamidori](https://github.com/kumamidori))
* Added Slovenian (sl\_SL) locale [\#363](https://github.com/fzaninotto/Faker/pull/363) ([alesf](https://github.com/alesf))
* Fixed German (de\_DE) Person provider (first names) [\#362](https://github.com/fzaninotto/Faker/pull/362) ([mikehaertl](https://github.com/mikehaertl))
* Fixed Ukrainian (uk\_UA) Person providr (there is no such letter "ы" in Ukrainian) [\#359](https://github.com/fzaninotto/Faker/pull/359) ([nazar-pc](https://github.com/nazar-pc))
* Fixed Chinese (zh\_CN) PhoneNumber provider (the length of mobile phone number is 11) [\#358](https://github.com/fzaninotto/Faker/pull/358) ([byan](https://github.com/byan))
* Added Arabic (ar_\JO) Locale [\#357](https://github.com/fzaninotto/Faker/pull/357) ([zrashwani](https://github.com/zrashwani))
* Fixed Czech (cs\_CZ) Person provider (missing lowercase in last name) [\#355](https://github.com/fzaninotto/Faker/pull/355) ([halaxa](https://github.com/halaxa))
* Fixed French for Belgium (fr\_BE) Address Provider (doubled city names) [\#354](https://github.com/fzaninotto/Faker/pull/354) ([miclf](https://github.com/miclf))
* Added Biased Integer Provider [\#332](https://github.com/fzaninotto/Faker/pull/332) ([TimWolla](https://github.com/TimWolla))
* Added Swedish (sv\_SE) locale [\#316](https://github.com/fzaninotto/Faker/pull/316) ([ulrikjohansson](https://github.com/ulrikjohansson))
* Added English for New Zealand (en\_NZ) locale [\#283](https://github.com/fzaninotto/Faker/pull/283) ([JasonMortonNZ](https://github.com/JasonMortonNZ))
* Added mention of external Provider for cron expressions to readme[\#498](https://github.com/fzaninotto/Faker/pull/498) ([swekaj](https://github.com/swekaj))
2014-06-04, v1.4.0
------------------
* Fixed typo in Slovak person names (cinan)
* Added tests for uk_UA providers (serge-kuharev)
* Fixed numerify() performance by making it 30% faster (fzaninotto)
* Added strict option to randomNumber to force number of digits (fzaninotto)
* Fixed randomNumber usage duplicating numberBetween (fzaninotto)
* Fixed address provider for latvian language (MatissJA)
* Added Czech Republic (cs_CZ) address, company, datetime and text providers (Mikulas)
* Fixed da_DK Person provider data containing an 'unnamed' person (tolnem)
* Added slug provider (fzaninotto)
* Fixed IDE insights for new local IP and MAC address providers (hugofonseca)
* Added firstname gender method to all Person providers (csanquer)
* Fixed tr_TR email service, city name, person, and phone number formats (ogunkarakus)
* Fixed US_en state list (fzaninotto)
* Fixed en_US address provider so state abbr are ISO 3166 codes (Garbee)
* Added local IP and MAC address providers (kielabokkie)
* Fixed typo in century list affecting the century provider (fzaninotto)
* Added default value to optional modifier (joshuajabbour)
* Fixed Portuguese phonenumbers have 9 digits (hugofonseca)
* Added fileCopy to File provider to simulate file upload (stefanosala)
* Added pt_PT providers (hugofonseca)
* Fixed dead code in text provider (hugofonseca)
* Fixed IDE insights for magic properties (hugofonseca)
* Added tin (NIF) generator for pt_PT provider (hugofonseca)
* Fixed numberBetween max default value handling (fzaninotto)
* Added pt_PT phone number provider (hugofonseca)
* Fixed PSR-2 standards and add make task to force it on Travis (terite)
* Added new ro_RO Personal Numerical Code (CNP) and phone number providers (avataru)
* Fixed Internet provider for sk_SK locale (cinan)
* Fixed typo in en_ZA Internet provider (bjorntheart)
* Fixed phpdoc for DateTime magic methods (stof)
* Added doc about seeding with maximum timestamp using dateTime formatters (fzaninotto)
* Added Maximum Timestamp option to get always same unix timestamp when using a fixed seed (csanquer)
* Added Montenegrian (me_ME) providers (ognjenm)
* Added ean barcode provider (nineinchnick)
* Added fullPath parameter to Image provider (stefanosala)
* Added more Polish company formats (nineinchnick)
* Added Polish realText provider (nineinchnick)
* Fixed remaining non-seedable random generators (terite)
* Added randomElements provider (terite)
* Added French realText provider (fzaninotto)
* Fixed realText provider bootstrap slowness (fzaninotto)
* Added realText provider for English and German, based on Markov Chains Generator (TimWolla)
* Fixed address format in nl_NL provider (doenietzomoeilijk)
* Fixed potentially offensive word from last name list (joshuajabbour)
* Fixed reamde documentation about the optional modifier (cryode)
* Fixed Image provider and documentor routine (fzaninotto)
* Fixed IDE insights for methods (PedroTroller)
* Fixed missing data in en_US Address provider (Garbee)
* Added Bengali (bn_BD) providers (masnun)
* Fixed warning on test file when short tags are on (bateller)
* Fixed Doctrine populator undefined index warning (dbojdo)
* Added French Canadian (fr_CA) Address and Person providers (marcaube)
* Fixed typo in NullGenerator (mhanson01)
* Fixed Doctrine populator issue with one-to-one nullable relationship (jpetitcolas)
* Added Canadian English (en_CA) address and phone number providers (cviebrock)
* Fixed duplicated Payment example in readme (Garbee)
* Fixed Polish (pl_PL) Person provider data (czogori)
* Added Hungarian (hu_HU) providers (sagikazarmark)
* Added 'kana' (ja_JP) name formatters (kzykhys)
* Added allow_failure for hhvm to travis-ci and test against php 5.5 (toin0u)
2013-12-16, v1.3.0
------------------
* Fixed state generator in Australian (en_AU) provider (sebklaus)
* Fixed IDE insights for locale specific providers (ulrikjohansson)
* Added English (South Africa) (en_ZA) person, address, Internet and phone number providers (dmfaux)
* Fixed integer values overflowing on signed INTEGER columns on Doctrine populator (Thinkscape)
* Fixed spelling error in French (fr_FR) address provider (leihog)
* Added improvements based on SensioLabsInsights analysis
* Fixed Italian (it_IT) email provider (garak)
* Added Spanish (es_ES) Internet provider (eusonlito)
* Added English Philippines (en_PH) address provider (kamote)
* Added Brazilian (pt_BR) email provider data (KennedyTedesco)
* Fixed UK country code (pgscandeias)
* Added Peruvian (es_PE) person, address, phone number, and company providers (cslucano)
* Added Ukrainian (uk_UA) color provider (ruden)
* Fixed Ukrainian (uk_UA) namespace and email translitteration (ruden)
* Added Romanian (Moldova) (ro_MD) person, address, and phone number providers (AlexanderC)
* Added IBAN generator for every currently known locale that uses it (nineinchnick)
* Added Image generation powered by LoremPixel (weotch)
* Fixed missing timezone with dateTimeBetween (baldurrensch)
* Fixed call to undefined method cardType in Payment (WMeldon)
* Added Romanian (ro_RO) address and person providers (calina-c)
* Fixed Doctrine populator to use ObjectManager instead of EntityManagerInterface (mgiustiniani)
* Fixed docblock for Provider\Base::unique() (pschultz)
* Added Payment providers (creditCardType, creditCardNumber, creditCardExpirationDate, creditCardExpirationDateString) (pomaxa)
* Added unique() modifier
* Added IDE insights to allow better intellisense/phpStorm autocompletion (thallisphp)
* Added Polish (pl_PL) address provider, personal identity number and pesel number generator (nineinchnick)
* Added Turkish (tr_TR) address provider, and improved internet provider (hasandz)
* Fixed Propel column number guesser to use signed range of values (gunnarlium)
* Added Greek (el_GR) person, address, and phone number providers (georgeharito)
* Added Austrian (en_AU) address, Internet, and phone number providers (rcuddy)
* Fixed phpDoc in Doctrine Entity populator (rogamoore)
* Added French (fr_FR) phone number formats (vchabot)
* Added optional() modifier (weotch)
* Fixed typo in the Person provider documentation (jtreminio)
* Fixed Russian (ru_RU) person format (alexshadow007)
* Added Japanese (ja_JP) person, address, Internet, phone number, and company providers (kumamidori)
* Added color providers, driver license and passport number formats for the ru_RU locale (pomaxa)
* Added Latvian (lv_LV) person, address, Internet, and phone number providers (pomaxa)
* Added Brazilian (pt_BR) Internet provider (vjnrv)
* Added more Czech (cs_CZ) lastnames (petrkle)
* Added Chinese Simplified (zh_CN) person, address, Internet, and phone number providers (tlikai)
* Fixed Typos (pborelli)
* Added Color provider with hexColor, rgbColor, rgbColorAsArray, rgbCssColor, safeColorName, and colorName formatters (lsv)
* Added support for associative arrays in `randomElement` (aRn0D)
2013-06-09, v1.2.0
------------------
* Added new provider for fr_BE locale (jflefebvre)
* Updated locale provider to use a static locale list (spawn-guy)
* Fixed invalid UTF-8 sequence in domain provider with the Bulgarian provider (Dynom)
* Fixed the nl_NL Person provider (Dynom)
* Removed all requires and added the autoload definition to composer (Dynom)
* Fixed encoding problems in nl_NL Address provider (Dynom)
* Added icelandic provider (is_IS) (birkir)
* Added en_CA address and phone numbers (cviebrock)
* Updated safeEmail provider to be really safe (TimWolla)
* Documented alternative randomNumber usage (Seldaek)
* Added basic file provider (anroots)
* Fixed use of fourth argument on Doctrine addEntity (ecentinela)
* Added nl_BE provider (wimvds)
* Added Random Float provider (csanquer)
* Fixed bug in Faker\ORM\Doctrine\Populator (mmf-amarcos)
* Updated ru_RU provider (rmrevin)
* Added safe email domain provider (csanquer)
* Fixed latitude provider (rumpl)
* Fixed unpredictability of fake data generated by Faker\Provider\Base::numberBetween() (goatherd)
* Added uuid provider (goatherd)
* Added possibility to call methods on Doctrine entities, possibility to generate unique id (nenadalm)
* Fixed prefixes typos in 'pl_PL' Person provider (krymen)
* Added more fake data to the Ukraininan providers (lysenkobv)
* Added more fake data to the Italian providers (EmanueleMinotto)
* Fixed spaces appearing in generated emails (alchy58)
* Added Armenian (hy_AM) provider (artash)
* Added Generation of valid SIREN & SIRET codes to French providers (alexsegura)
* Added Dutch (nl_NL) provider (WouterJ)
* Fixed missing typehint in Base::__construct() (benja-M-1)
* Fixed typo in README (benja-M-1)
* Added Ukrainian (ua_UA) provider (rsvasilyev)
* Added Turkish (tr_TR) Provider (faridmovsumov)
* Fixed executable bit in some PHP files (siwinski)
* Added Brazilian Portuguese (pt_BR) provider (oliveiraev)
* Added Spanish (es_ES) provider (ivannis)
* Fixed Doctrine populator to allow for the population of entity data that has associations to other entities (afishnamedsquish)
* Added Danish (da_DK) providers (toin0u)
* Cleaned up whitespaces (toin0u)
* Fixed utf-8 bug with lowercase generators (toin0u)
* Fixed composer.json (Seldaek)
* Fixed bug in Doctrine EntityPopulator (beberlei)
* Added Finnish (fi_FI) provider (drodil)
2012-10-29, v1.1.0
------------------
* Updated text provider to return paragraphs as a string instead of array. Great for populating markdown textarea fields (Seldaek)
* Updated dateTimeBetween to accept DateTime instances (Seldaek)
* Added random number generator between a and b, simply like rand() (Seldaek)
* Fixed spaces in generated emails (blaugueux)
* Fixed Person provider in Russian locale (Isamashii)
* Added new UserAgent provider (blaugueux)
* Added locale generator to Miscellaneous provider (blaugueux)
* Added timezone generator to DateTime provider (blaugueux)
* Added new generators to French Address providers (departments, regions) (geoffrey-brier)
* Added new generators to French Company provider (catch phrase, SIREN, and SIRET numbers) (geoffrey-brier)
* Added state generator to German Address provider (Powerhamster)
* Added Slovak provider (bazo)
* Added latitude and longitude formatters to Address provider (fixe)
* Added Serbian provider (umpirsky)
2012-07-10, v1.0.0
-----------------
* Initial Version

22
vendor/fzaninotto/faker/CONTRIBUTING.md vendored Normal file
View File

@@ -0,0 +1,22 @@
Contributing
============
If you've written a new formatter, adapted Faker to a new locale, or fixed a bug, your contribution is welcome!
Before proposing a pull request, check the following:
* Your code should follow the [PSR-2 coding standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md). Run `make sniff` to check that the coding standards are followed, and use [php-cs-fixer](https://github.com/fabpot/PHP-CS-Fixer) to fix inconsistencies.
* Unit tests should still pass after your patch. Run the tests on your dev server (with `make test`) or check the continuous integration status for your pull request.
* As much as possible, add unit tests for your code
* Never use `rand()` in your providers. Faker uses the Mersenne Twister Randomizer, so use `mt_rand()` or any of the base generators (`randomNumber`, `randomElement`, etc.) instead.
* If you add new providers (or new locales) and that they embed a lot of data for random generation (e.g. first names in a new language), please add a `@link` to the reference you used for this list (example [in the ru_RU locale](https://github.com/fzaninotto/Faker/blob/master/src/Faker/Provider/ru_RU/Person.php#L13)). This will ease future updates of the list and debates about the most relevant data for this provider.
* If you add long list of random data, please split the list into several lines. This makes diffs easier to read, and facilitates core review.
* If you add new formatters, please include documentation for it in the README. Don't forget to add a line about new formatters in the `@property` or `@method` phpDoc entries in [Generator.php](https://github.com/fzaninotto/Faker/blob/master/src/Faker/Generator.php#L6-L118) to help IDEs auto-complete your formatters.
* If your new formatters are specific to a certain locale, document them in the [Language-specific formatters](https://github.com/fzaninotto/Faker#language-specific-formatters) list instead.
* Avoid changing existing sets of data. Some developers use Faker with seeding for unit tests ; changing the data makes their tests fail.
* Speed is important in all Faker usages. Make sure your code is optimized to generate thousands of fake items in no time, without consuming too much memory or CPU.
* If you commit a new feature, be prepared to help maintaining it. Watch the project on GitHub, and please comment on issues or PRs regarding the feature you contributed.
Once your code is merged, it is available for free to everybody under the MIT License. Publishing your Pull Request on the Faker GitHub repository means that you agree with this license for your contribution.
Thank you for your contribution! Faker wouldn't be so great without you.

22
vendor/fzaninotto/faker/LICENSE vendored Normal file
View File

@@ -0,0 +1,22 @@
Copyright (c) 2011 François Zaninotto
Portions Copyright (c) 2008 Caius Durling
Portions Copyright (c) 2008 Adam Royle
Portions Copyright (c) 2008 Fiona Burrows
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

10
vendor/fzaninotto/faker/Makefile vendored Normal file
View File

@@ -0,0 +1,10 @@
vendor/autoload.php:
composer install --no-interaction --prefer-source
.PHONY: sniff
sniff: vendor/autoload.php
vendor/bin/phpcs --standard=PSR2 src -n
.PHONY: test
test: vendor/autoload.php
vendor/bin/phpunit --verbose

35
vendor/fzaninotto/faker/composer.json vendored Normal file
View File

@@ -0,0 +1,35 @@
{
"name": "fzaninotto/faker",
"type": "library",
"description": "Faker is a PHP library that generates fake data for you.",
"keywords": ["faker", "fixtures", "data"],
"license": "MIT",
"authors": [
{
"name": "François Zaninotto"
}
],
"require": {
"php": "^5.3.3|^7.0"
},
"require-dev": {
"phpunit/phpunit": "~4.0",
"squizlabs/php_codesniffer": "~1.5",
"ext-intl": "*"
},
"autoload": {
"psr-4": {
"Faker\\": "src/Faker/"
}
},
"autoload-dev": {
"psr-4": {
"Faker\\Test\\": "test/Faker/"
}
},
"extra": {
"branch-alias": {
"dev-master": "1.6.0"
}
}
}

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
bootstrap="vendor/autoload.php"
colors="true"
>
<testsuites>
<testsuite name="Faker Test Suite">
<directory>./test/Faker/</directory>
</testsuite>
</testsuites>
</phpunit>

1287
vendor/fzaninotto/faker/readme.md vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,71 @@
<?php
namespace Faker\Calculator;
class Iban
{
/**
* Generates IBAN Checksum
*
* @param string $iban
* @return string Checksum (numeric string)
*/
public static function checksum($iban)
{
// Move first four digits to end and set checksum to '00'
$checkString = substr($iban, 4) . substr($iban, 0, 2) . '00';
// Replace all letters with their number equivalents
$checkString = preg_replace_callback('/[A-Z]/', array('self','alphaToNumberCallback'), $checkString);
// Perform mod 97 and subtract from 98
$checksum = 98 - self::mod97($checkString);
return str_pad($checksum, 2, '0', STR_PAD_LEFT);
}
/**
* @return int
*/
private static function alphaToNumberCallback($match)
{
return self::alphaToNumber($match[0]);
}
/**
* Converts letter to number
*
* @param string $char
* @return int
*/
public static function alphaToNumber($char)
{
return ord($char) - 55;
}
/**
* Calculates mod97 on a numeric string
*
* @param string $number Numeric string
* @return int
*/
public static function mod97($number)
{
$checksum = (int)$number[0];
for ($i = 1, $size = strlen($number); $i < $size; $i++) {
$checksum = (10 * $checksum + (int) $number[$i]) % 97;
}
return $checksum;
}
/**
* Checks whether an IBAN has a valid checksum
*
* @param string $iban
* @return boolean
*/
public static function isValid($iban)
{
return self::checksum($iban) === substr($iban, 2, 2);
}
}

View File

@@ -0,0 +1,58 @@
<?php
namespace Faker\Calculator;
/**
* Utility class for generating Luhn checksum and validating a number
*
* Luhn algorithm is used to validate credit card numbers, IMEI numbers, and
* National Provider Identifier numbers.
*
* @see http://en.wikipedia.org/wiki/Luhn_algorithm
*/
class Luhn
{
/**
* @param string $number
* @return int
*/
private static function checksum($number)
{
$number = (string) $number;
$length = strlen($number);
$sum = 0;
for ($i = $length - 1; $i >= 0; $i -= 2) {
$sum += $number{$i};
}
for ($i = $length - 2; $i >= 0; $i -= 2) {
$sum += array_sum(str_split($number{$i} * 2));
}
return $sum % 10;
}
/**
* @param $partialNumber
* @return string
*/
public static function computeCheckDigit($partialNumber)
{
$checkDigit = self::checksum($partialNumber . '0');
if ($checkDigit === 0) {
return 0;
}
return (string) (10 - $checkDigit);
}
/**
* Checks whether a number (partial number + check digit) is Luhn compliant
*
* @param string $number
* @return bool
*/
public static function isValid($number)
{
return self::checksum($number) === 0;
}
}

View File

@@ -0,0 +1,34 @@
<?php
namespace Faker;
/**
* This generator returns a default value for all called properties
* and methods. It works with Faker\Generator\Base->optional().
*/
class DefaultGenerator
{
protected $default;
public function __construct($default = null)
{
$this->default = $default;
}
/**
* @param string $attribute
*/
public function __get($attribute)
{
return $this->default;
}
/**
* @param string $method
* @param array $attributes
*/
public function __call($method, $attributes)
{
return $this->default;
}
}

View File

@@ -0,0 +1,66 @@
<?php
namespace Faker;
class Documentor
{
protected $generator;
/**
* @param Generator $generator
*/
public function __construct(Generator $generator)
{
$this->generator = $generator;
}
/**
* @return array
*/
public function getFormatters()
{
$formatters = array();
$providers = array_reverse($this->generator->getProviders());
$providers[]= new Provider\Base($this->generator);
foreach ($providers as $provider) {
$providerClass = get_class($provider);
$formatters[$providerClass] = array();
$refl = new \ReflectionObject($provider);
foreach ($refl->getMethods(\ReflectionMethod::IS_PUBLIC) as $reflmethod) {
if ($reflmethod->getDeclaringClass()->getName() == 'Faker\Provider\Base' && $providerClass != 'Faker\Provider\Base') {
continue;
}
$methodName = $reflmethod->name;
if ($reflmethod->isConstructor()) {
continue;
}
$parameters = array();
foreach ($reflmethod->getParameters() as $reflparameter) {
$parameter = '$'. $reflparameter->getName();
if ($reflparameter->isDefaultValueAvailable()) {
$parameter .= ' = ' . var_export($reflparameter->getDefaultValue(), true);
}
$parameters []= $parameter;
}
$parameters = $parameters ? '('. join(', ', $parameters) . ')' : '';
try {
$example = $this->generator->format($methodName);
} catch (\InvalidArgumentException $e) {
$example = '';
}
if (is_array($example)) {
$example = "array('". join("', '", $example) . "')";
} elseif ($example instanceof \DateTime) {
$example = "DateTime('" . $example->format('Y-m-d H:i:s') . "')";
} elseif ($example instanceof Generator || $example instanceof UniqueGenerator) { // modifier
$example = '';
} else {
$example = var_export($example, true);
}
$formatters[$providerClass][$methodName . $parameters] = $example;
}
}
return $formatters;
}
}

View File

@@ -0,0 +1,61 @@
<?php
namespace Faker;
class Factory
{
const DEFAULT_LOCALE = 'en_US';
protected static $defaultProviders = array('Address', 'Barcode', 'Biased', 'Color', 'Company', 'DateTime', 'File', 'Image', 'Internet', 'Lorem', 'Miscellaneous', 'Payment', 'Person', 'PhoneNumber', 'Text', 'UserAgent', 'Uuid');
/**
* Create a new generator
*
* @param string $locale
* @return Generator
*/
public static function create($locale = self::DEFAULT_LOCALE)
{
$generator = new Generator();
foreach (static::$defaultProviders as $provider) {
$providerClassName = self::getProviderClassname($provider, $locale);
$generator->addProvider(new $providerClassName($generator));
}
return $generator;
}
/**
* @param string $provider
* @param string $locale
* @return string
*/
protected static function getProviderClassname($provider, $locale = '')
{
if ($providerClass = self::findProviderClassname($provider, $locale)) {
return $providerClass;
}
// fallback to default locale
if ($providerClass = self::findProviderClassname($provider, static::DEFAULT_LOCALE)) {
return $providerClass;
}
// fallback to no locale
if ($providerClass = self::findProviderClassname($provider)) {
return $providerClass;
}
throw new \InvalidArgumentException(sprintf('Unable to find provider "%s" with locale "%s"', $provider, $locale));
}
/**
* @param string $provider
* @param string $locale
* @return string
*/
protected static function findProviderClassname($provider, $locale = '')
{
$providerClass = 'Faker\\' . ($locale ? sprintf('Provider\%s\%s', $locale, $provider) : sprintf('Provider\%s', $provider));
if (class_exists($providerClass, true)) {
return $providerClass;
}
}
}

View File

@@ -0,0 +1,249 @@
<?php
namespace Faker;
/**
* @property string $name
* @property string $firstName
* @property string $firstNameMale
* @property string $firstNameFemale
* @property string $lastName
* @property string $title
* @property string $titleMale
* @property string $titleFemale
*
* @property string $citySuffix
* @property string $streetSuffix
* @property string $buildingNumber
* @property string $city
* @property string $streetName
* @property string $streetAddress
* @property string $postcode
* @property string $address
* @property string $country
* @property float $latitude
* @property float $longitude
*
* @property string $ean13
* @property string $ean8
* @property string $isbn13
* @property string $isbn10
*
* @property string $phoneNumber
*
* @property string $company
* @property string $companySuffix
* @property string $jobTitle
*
* @property string $creditCardType
* @property string $creditCardNumber
* @method string creditCardNumber($type = null, $formatted = false, $separator = '-')
* @property \DateTime $creditCardExpirationDate
* @property string $creditCardExpirationDateString
* @property string $creditCardDetails
* @property string $bankAccountNumber
* @method string iban($countryCode = null, $prefix = '', $length = null)
* @property string $swiftBicNumber
* @property string $vat
*
* @property string $word
* @property string|array $words
* @method string|array words($nb = 3, $asText = false)
* @property string $sentence
* @method string sentence($nbWords = 6, $variableNbWords = true)
* @property string|array $sentences
* @method string|array sentences($nb = 3, $asText = false)
* @property string $paragraph
* @method string paragraph($nbSentences = 3, $variableNbSentences = true)
* @property string|array $paragraphs
* @method string|array paragraphs($nb = 3, $asText = false)
* @property string $text
* @method string text($maxNbChars = 200)
*
* @method string realText($maxNbChars = 200, $indexSize = 2)
*
* @property string $email
* @property string $safeEmail
* @property string $freeEmail
* @property string $companyEmail
* @property string $freeEmailDomain
* @property string $safeEmailDomain
* @property string $userName
* @property string $password
* @method string password($minLength = 6, $maxLength = 20)
* @property string $domainName
* @property string $domainWord
* @property string $tld
* @property string $url
* @property string $slug
* @method string slug($nbWords = 6, $variableNbWords = true)
* @property string $ipv4
* @property string $ipv6
* @property string $localIpv4
* @property string $macAddress
*
* @property int $unixTime
* @property \DateTime $dateTime
* @property \DateTime $dateTimeAD
* @property string $iso8601
* @property \DateTime $dateTimeThisCentury
* @property \DateTime $dateTimeThisDecade
* @property \DateTime $dateTimeThisYear
* @property \DateTime $dateTimeThisMonth
* @property string $amPm
* @property int $dayOfMonth
* @property int $dayOfWeek
* @property int $month
* @property string $monthName
* @property int $year
* @property int $century
* @property string $timezone
* @method string date($format = 'Y-m-d', $max = 'now')
* @method string time($format = 'H:i:s', $max = 'now')
* @method \DateTime dateTimeBetween($startDate = '-30 years', $endDate = 'now')
*
* @property string $md5
* @property string $sha1
* @property string $sha256
* @property string $locale
* @property string $countryCode
* @property string $countryISOAlpha3
* @property string $languageCode
* @property string $currencyCode
* @property boolean boolean
* @method boolean boolean($chanceOfGettingTrue = 50)
*
* @property int $randomDigit
* @property int $randomDigitNotNull
* @property string $randomLetter
* @property string $randomAscii
* @method int randomNumber($nbDigits = null, $strict = false)
* @method int|string|null randomKey(array $array = array())
* @method int numberBetween($min = 0, $max = 2147483647)
* @method float randomFloat($nbMaxDecimals = null, $min = 0, $max = null)
* @method mixed randomElement(array $array = array('a', 'b', 'c'))
* @method array randomElements(array $array = array('a', 'b', 'c'), $count = 1)
* @method array|string shuffle($arg = '')
* @method array shuffleArray(array $array = array())
* @method string shuffleString($string = '', $encoding = 'UTF-8')
* @method string numerify($string = '###')
* @method string lexify($string = '????')
* @method string bothify($string = '## ??')
* @method string asciify($string = '****')
* @method string regexify($regex = '')
* @method string toLower($string = '')
* @method string toUpper($string = '')
* @method Generator optional($weight = 0.5, $default = null)
* @method Generator unique($reset = false, $maxRetries = 10000)
*
* @method integer biasedNumberBetween($min = 0, $max = 100, $function = 'sqrt')
*
* @property string $macProcessor
* @property string $linuxProcessor
* @property string $userAgent
* @property string $chrome
* @property string $firefox
* @property string $safari
* @property string $opera
* @property string $internetExplorer
* @property string $windowsPlatformToken
* @property string $macPlatformToken
* @property string $linuxPlatformToken
*
* @property string $uuid
*
* @property string $mimeType
* @property string $fileExtension
* @method string file($sourceDirectory = '/tmp', $targetDirectory = '/tmp', $fullPath = true)
*
* @method string imageUrl($width = 640, $height = 480, $category = null, $randomize = true, $word = null)
* @method string image($dir = null, $width = 640, $height = 480, $category = null, $fullPath = true)
*
* @property string $hexColor
* @property string $safeHexColor
* @property string $rgbColor
* @property array $rgbColorAsArray
* @property string $rgbCssColor
* @property string $safeColorName
* @property string $colorName
*/
class Generator
{
protected $providers = array();
protected $formatters = array();
public function addProvider($provider)
{
array_unshift($this->providers, $provider);
}
public function getProviders()
{
return $this->providers;
}
public function seed($seed = null)
{
if ($seed === null) {
mt_srand();
} else {
mt_srand((int) $seed);
}
}
public function format($formatter, $arguments = array())
{
return call_user_func_array($this->getFormatter($formatter), $arguments);
}
/**
* @return Callable
*/
public function getFormatter($formatter)
{
if (isset($this->formatters[$formatter])) {
return $this->formatters[$formatter];
}
foreach ($this->providers as $provider) {
if (method_exists($provider, $formatter)) {
$this->formatters[$formatter] = array($provider, $formatter);
return $this->formatters[$formatter];
}
}
throw new \InvalidArgumentException(sprintf('Unknown formatter "%s"', $formatter));
}
/**
* Replaces tokens ('{{ tokenName }}') with the result from the token method call
*
* @param string $string String that needs to bet parsed
* @return string
*/
public function parse($string)
{
return preg_replace_callback('/\{\{\s?(\w+)\s?\}\}/u', array($this, 'callFormatWithMatches'), $string);
}
protected function callFormatWithMatches($matches)
{
return $this->format($matches[1]);
}
/**
* @param string $attribute
*/
public function __get($attribute)
{
return $this->format($attribute);
}
/**
* @param string $method
* @param array $attributes
*/
public function __call($method, $attributes)
{
return $this->format($method, $attributes);
}
}

View File

@@ -0,0 +1,156 @@
<?php
namespace Faker\Guesser;
use \Faker\Provider\Base;
class Name
{
protected $generator;
/**
* @param \Faker\Generator $generator
*/
public function __construct(\Faker\Generator $generator)
{
$this->generator = $generator;
}
/**
* @param string $name
* @param int|null $size Length of field, if known
* @return callable
*/
public function guessFormat($name, $size = null)
{
$name = Base::toLower($name);
$generator = $this->generator;
if (preg_match('/^is[_A-Z]/', $name)) {
return function () use ($generator) {
return $generator->boolean;
};
}
if (preg_match('/(_a|A)t$/', $name)) {
return function () use ($generator) {
return $generator->dateTime;
};
}
switch (str_replace('_', '', $name)) {
case 'firstname':
return function () use ($generator) {
return $generator->firstName;
};
case 'lastname':
return function () use ($generator) {
return $generator->lastName;
};
case 'username':
case 'login':
return function () use ($generator) {
return $generator->userName;
};
case 'email':
case 'emailaddress':
return function () use ($generator) {
return $generator->email;
};
case 'phonenumber':
case 'phone':
case 'telephone':
case 'telnumber':
return function () use ($generator) {
return $generator->phoneNumber;
};
case 'address':
return function () use ($generator) {
return $generator->address;
};
case 'city':
case 'town':
return function () use ($generator) {
return $generator->city;
};
case 'streetaddress':
return function () use ($generator) {
return $generator->streetAddress;
};
case 'postcode':
case 'zipcode':
return function () use ($generator) {
return $generator->postcode;
};
case 'state':
return function () use ($generator) {
return $generator->state;
};
case 'county':
if ($this->generator->locale == 'en_US') {
return function () use ($generator) {
return sprintf('%s County', $generator->city);
};
}
return function () use ($generator) {
return $generator->state;
};
case 'country':
switch ($size) {
case 2:
return function () use ($generator) {
return $generator->countryCode;
};
case 3:
return function () use ($generator) {
return $generator->countryISOAlpha3;
};
case 5:
case 6:
return function () use ($generator) {
return $generator->locale;
};
default:
return function () use ($generator) {
return $generator->country;
};
}
break;
case 'locale':
return function () use ($generator) {
return $generator->locale;
};
case 'currency':
case 'currencycode':
return function () use ($generator) {
return $generator->currencyCode;
};
case 'url':
case 'website':
return function () use ($generator) {
return $generator->url;
};
case 'company':
case 'companyname':
case 'employer':
return function () use ($generator) {
return $generator->company;
};
case 'title':
if ($size !== null && $size <= 10) {
return function () use ($generator) {
return $generator->title;
};
}
return function () use ($generator) {
return $generator->sentence;
};
case 'body':
case 'summary':
case 'article':
case 'description':
return function () use ($generator) {
return $generator->text;
};
}
}
}

View File

@@ -0,0 +1,67 @@
<?php
namespace Faker\ORM\CakePHP;
class ColumnTypeGuesser
{
protected $generator;
public function __construct(\Faker\Generator $generator)
{
$this->generator = $generator;
}
/**
* @return \Closure|null
*/
public function guessFormat($column, $table)
{
$generator = $this->generator;
$schema = $table->schema();
switch ($schema->columnType($column)) {
case 'boolean':
return function () use ($generator) {
return $generator->boolean;
};
case 'integer':
return function () {
return mt_rand(0, intval('2147483647'));
};
case 'biginteger':
return function () {
return mt_rand(0, intval('9223372036854775807'));
};
case 'decimal':
case 'float':
return function () use ($generator) {
return $generator->randomFloat();
};
case 'uuid':
return function () use ($generator) {
return $generator->uuid();
};
case 'string':
$columnData = $schema->column($column);
$length = $columnData['length'];
return function () use ($generator, $length) {
return $generator->text($length);
};
case 'text':
return function () use ($generator) {
return $generator->text();
};
case 'date':
case 'datetime':
case 'timestamp':
case 'time':
return function () use ($generator) {
return $generator->datetime();
};
case 'binary':
default:
return null;
}
}
}

View File

@@ -0,0 +1,166 @@
<?php
namespace Faker\ORM\CakePHP;
use Cake\ORM\TableRegistry;
class EntityPopulator
{
protected $class;
protected $connectionName;
protected $columnFormatters = [];
protected $modifiers = [];
public function __construct($class)
{
$this->class = $class;
}
/**
* @param string $name
*/
public function __get($name)
{
return $this->{$name};
}
/**
* @param string $name
*/
public function __set($name, $value)
{
$this->{$name} = $value;
}
public function mergeColumnFormattersWith($columnFormatters)
{
$this->columnFormatters = array_merge($this->columnFormatters, $columnFormatters);
}
public function mergeModifiersWith($modifiers)
{
$this->modifiers = array_merge($this->modifiers, $modifiers);
}
/**
* @return array
*/
public function guessColumnFormatters($populator)
{
$formatters = [];
$class = $this->class;
$table = $this->getTable($class);
$schema = $table->schema();
$pk = $schema->primaryKey();
$guessers = $populator->getGuessers() + ['ColumnTypeGuesser' => new ColumnTypeGuesser($populator->getGenerator())];
$isForeignKey = function ($column) use ($table) {
foreach ($table->associations()->type('BelongsTo') as $assoc) {
if ($column == $assoc->foreignKey()) {
return true;
}
}
return false;
};
foreach ($schema->columns() as $column) {
if ($column == $pk[0] || $isForeignKey($column)) {
continue;
}
foreach ($guessers as $guesser) {
if ($formatter = $guesser->guessFormat($column, $table)) {
$formatters[$column] = $formatter;
break;
}
}
}
return $formatters;
}
/**
* @return array
*/
public function guessModifiers()
{
$modifiers = [];
$table = $this->getTable($this->class);
$belongsTo = $table->associations()->type('BelongsTo');
foreach ($belongsTo as $assoc) {
$modifiers['belongsTo' . $assoc->name()] = function ($data, $insertedEntities) use ($assoc) {
$table = $assoc->target();
$foreignModel = $table->alias();
$foreignKeys = [];
if (!empty($insertedEntities[$foreignModel])) {
$foreignKeys = $insertedEntities[$foreignModel];
} else {
$foreignKeys = $table->find('all')
->select(['id'])
->map(function ($row) {
return $row->id;
})
->toArray();
}
if (empty($foreignKeys)) {
throw new \Exception(sprintf('%s belongsTo %s, which seems empty at this point.', $this->getTable($this->class)->table(), $assoc->table()));
}
$foreignKey = $foreignKeys[array_rand($foreignKeys)];
$data[$assoc->foreignKey()] = $foreignKey;
return $data;
};
}
// TODO check if TreeBehavior attached to modify lft/rgt cols
return $modifiers;
}
/**
* @param array $options
*/
public function execute($class, $insertedEntities, $options = [])
{
$table = $this->getTable($class);
$entity = $table->newEntity();
foreach ($this->columnFormatters as $column => $format) {
if (!is_null($format)) {
$entity->{$column} = is_callable($format) ? $format($insertedEntities, $table) : $format;
}
}
foreach ($this->modifiers as $modifier) {
$entity = $modifier($entity, $insertedEntities);
}
if (!$entity = $table->save($entity, $options)) {
throw new \RuntimeException("Failed saving $class record");
}
$pk = $table->primaryKey();
if (is_string($pk)) {
return $entity->{$pk};
}
return $entity->{$pk[0]};
}
public function setConnection($name)
{
$this->connectionName = $name;
}
protected function getTable($class)
{
$options = [];
if (!empty($this->connectionName)) {
$options['connection'] = $this->connectionName;
}
return TableRegistry::get($class, $options);
}
}

View File

@@ -0,0 +1,109 @@
<?php
namespace Faker\ORM\CakePHP;
class Populator
{
protected $generator;
protected $entities = [];
protected $quantities = [];
protected $guessers = [];
/**
* @param \Faker\Generator $generator
*/
public function __construct(\Faker\Generator $generator)
{
$this->generator = $generator;
}
/**
* @return \Faker\Generator
*/
public function getGenerator()
{
return $this->generator;
}
/**
* @return array
*/
public function getGuessers()
{
return $this->guessers;
}
/**
* @return $this
*/
public function removeGuesser($name)
{
if ($this->guessers[$name]) {
unset($this->guessers[$name]);
}
return $this;
}
/**
* @return $this
* @throws \Exception
*/
public function addGuesser($class)
{
if (!is_object($class)) {
$class = new $class($this->generator);
}
if (!method_exists($class, 'guessFormat')) {
throw new \Exception('Missing required custom guesser method: ' . get_class($class) . '::guessFormat()');
}
$this->guessers[get_class($class)] = $class;
return $this;
}
/**
* @param array $customColumnFormatters
* @param array $customModifiers
* @return $this
*/
public function addEntity($entity, $number, $customColumnFormatters = [], $customModifiers = [])
{
if (!$entity instanceof EntityPopulator) {
$entity = new EntityPopulator($entity);
}
$entity->columnFormatters = $entity->guessColumnFormatters($this);
if ($customColumnFormatters) {
$entity->mergeColumnFormattersWith($customColumnFormatters);
}
$entity->modifiers = $entity->guessModifiers($this);
if ($customModifiers) {
$entity->mergeModifiersWith($customModifiers);
}
$class = $entity->class;
$this->entities[$class] = $entity;
$this->quantities[$class] = $number;
return $this;
}
/**
* @param array $options
* @return array
*/
public function execute($options = [])
{
$insertedEntities = [];
foreach ($this->quantities as $class => $number) {
for ($i = 0; $i < $number; $i++) {
$insertedEntities[$class][] = $this->entities[$class]->execute($class, $insertedEntities, $options);
}
}
return $insertedEntities;
}
}

View File

@@ -0,0 +1,75 @@
<?php
namespace Faker\ORM\Doctrine;
use Doctrine\Common\Persistence\Mapping\ClassMetadata;
class ColumnTypeGuesser
{
protected $generator;
/**
* @param \Faker\Generator $generator
*/
public function __construct(\Faker\Generator $generator)
{
$this->generator = $generator;
}
/**
* @param ClassMetadata $class
* @return \Closure|null
*/
public function guessFormat($fieldName, ClassMetadata $class)
{
$generator = $this->generator;
$type = $class->getTypeOfField($fieldName);
switch ($type) {
case 'boolean':
return function () use ($generator) {
return $generator->boolean;
};
case 'decimal':
$size = isset($class->fieldMappings[$fieldName]['precision']) ? $class->fieldMappings[$fieldName]['precision'] : 2;
return function () use ($generator, $size) {
return $generator->randomNumber($size + 2) / 100;
};
case 'smallint':
return function () {
return mt_rand(0, 65535);
};
case 'integer':
return function () {
return mt_rand(0, intval('2147483647'));
};
case 'bigint':
return function () {
return mt_rand(0, intval('18446744073709551615'));
};
case 'float':
return function () {
return mt_rand(0, intval('4294967295'))/mt_rand(1, intval('4294967295'));
};
case 'string':
$size = isset($class->fieldMappings[$fieldName]['length']) ? $class->fieldMappings[$fieldName]['length'] : 255;
return function () use ($generator, $size) {
return $generator->text($size);
};
case 'text':
return function () use ($generator) {
return $generator->text;
};
case 'datetime':
case 'date':
case 'time':
return function () use ($generator) {
return $generator->datetime;
};
default:
// no smart way to guess what the user expects here
return null;
}
}
}

View File

@@ -0,0 +1,239 @@
<?php
namespace Faker\ORM\Doctrine;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Mapping\ClassMetadata;
/**
* Service class for populating a table through a Doctrine Entity class.
*/
class EntityPopulator
{
/**
* @var ClassMetadata
*/
protected $class;
/**
* @var array
*/
protected $columnFormatters = array();
/**
* @var array
*/
protected $modifiers = array();
/**
* Class constructor.
*
* @param ClassMetadata $class
*/
public function __construct(ClassMetadata $class)
{
$this->class = $class;
}
/**
* @return string
*/
public function getClass()
{
return $this->class->getName();
}
/**
* @param $columnFormatters
*/
public function setColumnFormatters($columnFormatters)
{
$this->columnFormatters = $columnFormatters;
}
/**
* @return array
*/
public function getColumnFormatters()
{
return $this->columnFormatters;
}
public function mergeColumnFormattersWith($columnFormatters)
{
$this->columnFormatters = array_merge($this->columnFormatters, $columnFormatters);
}
/**
* @param array $modifiers
*/
public function setModifiers(array $modifiers)
{
$this->modifiers = $modifiers;
}
/**
* @return array
*/
public function getModifiers()
{
return $this->modifiers;
}
/**
* @param array $modifiers
*/
public function mergeModifiersWith(array $modifiers)
{
$this->modifiers = array_merge($this->modifiers, $modifiers);
}
/**
* @param \Faker\Generator $generator
* @return array
*/
public function guessColumnFormatters(\Faker\Generator $generator)
{
$formatters = array();
$nameGuesser = new \Faker\Guesser\Name($generator);
$columnTypeGuesser = new ColumnTypeGuesser($generator);
foreach ($this->class->getFieldNames() as $fieldName) {
if ($this->class->isIdentifier($fieldName) || !$this->class->hasField($fieldName)) {
continue;
}
$size = isset($this->class->fieldMappings[$fieldName]['length']) ? $this->class->fieldMappings[$fieldName]['length'] : null;
if ($formatter = $nameGuesser->guessFormat($fieldName, $size)) {
$formatters[$fieldName] = $formatter;
continue;
}
if ($formatter = $columnTypeGuesser->guessFormat($fieldName, $this->class)) {
$formatters[$fieldName] = $formatter;
continue;
}
}
foreach ($this->class->getAssociationNames() as $assocName) {
if ($this->class->isCollectionValuedAssociation($assocName)) {
continue;
}
$relatedClass = $this->class->getAssociationTargetClass($assocName);
$unique = $optional = false;
$mappings = $this->class->getAssociationMappings();
foreach ($mappings as $mapping) {
if ($mapping['targetEntity'] == $relatedClass) {
if ($mapping['type'] == ClassMetadata::ONE_TO_ONE) {
$unique = true;
$optional = isset($mapping['joinColumns'][0]['nullable']) ? $mapping['joinColumns'][0]['nullable'] : false;
break;
}
}
}
$index = 0;
$formatters[$assocName] = function ($inserted) use ($relatedClass, &$index, $unique, $optional) {
if (isset($inserted[$relatedClass])) {
if ($unique) {
$related = null;
if (isset($inserted[$relatedClass][$index]) || !$optional) {
$related = $inserted[$relatedClass][$index];
}
$index++;
return $related;
}
return $inserted[$relatedClass][mt_rand(0, count($inserted[$relatedClass]) - 1)];
}
return null;
};
}
return $formatters;
}
/**
* Insert one new record using the Entity class.
* @param ObjectManager $manager
* @param bool $generateId
* @return EntityPopulator
*/
public function execute(ObjectManager $manager, $insertedEntities, $generateId = false)
{
$obj = $this->class->newInstance();
$this->fillColumns($obj, $insertedEntities);
$this->callMethods($obj, $insertedEntities);
if ($generateId) {
$idsName = $this->class->getIdentifier();
foreach ($idsName as $idName) {
$id = $this->generateId($obj, $idName, $manager);
$this->class->reflFields[$idName]->setValue($obj, $id);
}
}
$manager->persist($obj);
return $obj;
}
private function fillColumns($obj, $insertedEntities)
{
foreach ($this->columnFormatters as $field => $format) {
if (null !== $format) {
// Add some extended debugging information to any errors thrown by the formatter
try {
$value = is_callable($format) ? $format($insertedEntities, $obj) : $format;
} catch (\InvalidArgumentException $ex) {
throw new \InvalidArgumentException(sprintf(
"Failed to generate a value for %s::%s: %s",
get_class($obj),
$field,
$ex->getMessage()
));
}
// Try a standard setter if it's available, otherwise fall back on reflection
$setter = sprintf("set%s", ucfirst($field));
if (method_exists($obj, $setter)) {
$obj->$setter($value);
} else {
$this->class->reflFields[$field]->setValue($obj, $value);
}
}
}
}
private function callMethods($obj, $insertedEntities)
{
foreach ($this->getModifiers() as $modifier) {
$modifier($obj, $insertedEntities);
}
}
/**
* @param EntityManagerInterface $manager
* @return int|null
*/
private function generateId($obj, $column, EntityManagerInterface $manager)
{
/* @var $repository \Doctrine\ORM\EntityRepository */
$repository = $manager->getRepository(get_class($obj));
$result = $repository->createQueryBuilder('e')
->select(sprintf('e.%s', $column))
->getQuery()
->getResult();
$ids = array_map('current', $result);
$id = null;
do {
$id = mt_rand();
} while (in_array($id, $ids));
return $id;
}
}

View File

@@ -0,0 +1,82 @@
<?php
namespace Faker\ORM\Doctrine;
use Doctrine\Common\Persistence\ObjectManager;
/**
* Service class for populating a database using the Doctrine ORM or ODM.
* A Populator can populate several tables using ActiveRecord classes.
*/
class Populator
{
protected $generator;
protected $manager;
protected $entities = array();
protected $quantities = array();
protected $generateId = array();
/**
* @param \Faker\Generator $generator
* @param ObjectManager|null $manager
*/
public function __construct(\Faker\Generator $generator, ObjectManager $manager = null)
{
$this->generator = $generator;
$this->manager = $manager;
}
/**
* Add an order for the generation of $number records for $entity.
*
* @param mixed $entity A Doctrine classname, or a \Faker\ORM\Doctrine\EntityPopulator instance
* @param int $number The number of entities to populate
*/
public function addEntity($entity, $number, $customColumnFormatters = array(), $customModifiers = array(), $generateId = false)
{
if (!$entity instanceof \Faker\ORM\Doctrine\EntityPopulator) {
if (null === $this->manager) {
throw new \InvalidArgumentException("No entity manager passed to Doctrine Populator.");
}
$entity = new \Faker\ORM\Doctrine\EntityPopulator($this->manager->getClassMetadata($entity));
}
$entity->setColumnFormatters($entity->guessColumnFormatters($this->generator));
if ($customColumnFormatters) {
$entity->mergeColumnFormattersWith($customColumnFormatters);
}
$entity->mergeModifiersWith($customModifiers);
$this->generateId[$entity->getClass()] = $generateId;
$class = $entity->getClass();
$this->entities[$class] = $entity;
$this->quantities[$class] = $number;
}
/**
* Populate the database using all the Entity classes previously added.
*
* @param null|EntityManager $entityManager A Doctrine connection object
*
* @return array A list of the inserted PKs
*/
public function execute($entityManager = null)
{
if (null === $entityManager) {
$entityManager = $this->manager;
}
if (null === $entityManager) {
throw new \InvalidArgumentException("No entity manager passed to Doctrine Populator.");
}
$insertedEntities = array();
foreach ($this->quantities as $class => $number) {
$generateId = $this->generateId[$class];
for ($i=0; $i < $number; $i++) {
$insertedEntities[$class][]= $this->entities[$class]->execute($entityManager, $insertedEntities, $generateId);
}
$entityManager->flush();
}
return $insertedEntities;
}
}

View File

@@ -0,0 +1,49 @@
<?php
namespace Faker\ORM\Mandango;
class ColumnTypeGuesser
{
protected $generator;
/**
* @param \Faker\Generator $generator
*/
public function __construct(\Faker\Generator $generator)
{
$this->generator = $generator;
}
/**
* @return \Closure|null
*/
public function guessFormat($field)
{
$generator = $this->generator;
switch ($field['type']) {
case 'boolean':
return function () use ($generator) {
return $generator->boolean;
};
case 'integer':
return function () {
return mt_rand(0, intval('4294967295'));
};
case 'float':
return function () {
return mt_rand(0, intval('4294967295'))/mt_rand(1, intval('4294967295'));
};
case 'string':
return function () use ($generator) {
return $generator->text(255);
};
case 'date':
return function () use ($generator) {
return $generator->datetime;
};
default:
// no smart way to guess what the user expects here
return null;
}
}
}

View File

@@ -0,0 +1,122 @@
<?php
namespace Faker\ORM\Mandango;
use Mandango\Mandango;
use Faker\Provider\Base;
/**
* Service class for populating a table through a Mandango ActiveRecord class.
*/
class EntityPopulator
{
protected $class;
protected $columnFormatters = array();
/**
* Class constructor.
*
* @param string $class A Mandango ActiveRecord classname
*/
public function __construct($class)
{
$this->class = $class;
}
/**
* @return string
*/
public function getClass()
{
return $this->class;
}
public function setColumnFormatters($columnFormatters)
{
$this->columnFormatters = $columnFormatters;
}
/**
* @return array
*/
public function getColumnFormatters()
{
return $this->columnFormatters;
}
public function mergeColumnFormattersWith($columnFormatters)
{
$this->columnFormatters = array_merge($this->columnFormatters, $columnFormatters);
}
/**
* @param \Faker\Generator $generator
* @param Mandango $mandango
* @return array
*/
public function guessColumnFormatters(\Faker\Generator $generator, Mandango $mandango)
{
$formatters = array();
$nameGuesser = new \Faker\Guesser\Name($generator);
$columnTypeGuesser = new \Faker\ORM\Mandango\ColumnTypeGuesser($generator);
$metadata = $mandango->getMetadata($this->class);
// fields
foreach ($metadata['fields'] as $fieldName => $field) {
if ($formatter = $nameGuesser->guessFormat($fieldName)) {
$formatters[$fieldName] = $formatter;
continue;
}
if ($formatter = $columnTypeGuesser->guessFormat($field)) {
$formatters[$fieldName] = $formatter;
continue;
}
}
// references
foreach (array_merge($metadata['referencesOne'], $metadata['referencesMany']) as $referenceName => $reference) {
if (!isset($reference['class'])) {
continue;
}
$referenceClass = $reference['class'];
$formatters[$referenceName] = function ($insertedEntities) use ($referenceClass) {
if (isset($insertedEntities[$referenceClass])) {
return Base::randomElement($insertedEntities[$referenceClass]);
}
};
}
return $formatters;
}
/**
* Insert one new record using the Entity class.
* @param Mandango $mandango
*/
public function execute(Mandango $mandango, $insertedEntities)
{
$metadata = $mandango->getMetadata($this->class);
$obj = $mandango->create($this->class);
foreach ($this->columnFormatters as $column => $format) {
if (null !== $format) {
$value = is_callable($format) ? $format($insertedEntities, $obj) : $format;
if (isset($metadata['fields'][$column]) ||
isset($metadata['referencesOne'][$column])) {
$obj->set($column, $value);
}
if (isset($metadata['referencesMany'][$column])) {
$adder = 'add'.ucfirst($column);
$obj->$adder($value);
}
}
}
$mandango->persist($obj);
return $obj;
}
}

View File

@@ -0,0 +1,65 @@
<?php
namespace Faker\ORM\Mandango;
use Mandango\Mandango;
/**
* Service class for populating a database using Mandango.
* A Populator can populate several tables using ActiveRecord classes.
*/
class Populator
{
protected $generator;
protected $mandango;
protected $entities = array();
protected $quantities = array();
/**
* @param \Faker\Generator $generator
* @param Mandango $mandango
*/
public function __construct(\Faker\Generator $generator, Mandango $mandango)
{
$this->generator = $generator;
$this->mandango = $mandango;
}
/**
* Add an order for the generation of $number records for $entity.
*
* @param mixed $entity A Propel ActiveRecord classname, or a \Faker\ORM\Propel\EntityPopulator instance
* @param int $number The number of entities to populate
*/
public function addEntity($entity, $number, $customColumnFormatters = array())
{
if (!$entity instanceof \Faker\ORM\Mandango\EntityPopulator) {
$entity = new \Faker\ORM\Mandango\EntityPopulator($entity);
}
$entity->setColumnFormatters($entity->guessColumnFormatters($this->generator, $this->mandango));
if ($customColumnFormatters) {
$entity->mergeColumnFormattersWith($customColumnFormatters);
}
$class = $entity->getClass();
$this->entities[$class] = $entity;
$this->quantities[$class] = $number;
}
/**
* Populate the database using all the Entity classes previously added.
*
* @return array A list of the inserted entities.
*/
public function execute()
{
$insertedEntities = array();
foreach ($this->quantities as $class => $number) {
for ($i=0; $i < $number; $i++) {
$insertedEntities[$class][]= $this->entities[$class]->execute($this->mandango, $insertedEntities);
}
}
$this->mandango->flush();
return $insertedEntities;
}
}

View File

@@ -0,0 +1,107 @@
<?php
namespace Faker\ORM\Propel;
use \PropelColumnTypes;
use \ColumnMap;
class ColumnTypeGuesser
{
protected $generator;
/**
* @param \Faker\Generator $generator
*/
public function __construct(\Faker\Generator $generator)
{
$this->generator = $generator;
}
/**
* @param ColumnMap $column
* @return \Closure|null
*/
public function guessFormat(ColumnMap $column)
{
$generator = $this->generator;
if ($column->isTemporal()) {
if ($column->isEpochTemporal()) {
return function () use ($generator) {
return $generator->dateTime;
};
} else {
return function () use ($generator) {
return $generator->dateTimeAD;
};
}
}
$type = $column->getType();
switch ($type) {
case PropelColumnTypes::BOOLEAN:
case PropelColumnTypes::BOOLEAN_EMU:
return function () use ($generator) {
return $generator->boolean;
};
case PropelColumnTypes::NUMERIC:
case PropelColumnTypes::DECIMAL:
$size = $column->getSize();
return function () use ($generator, $size) {
return $generator->randomNumber($size + 2) / 100;
};
case PropelColumnTypes::TINYINT:
return function () {
return mt_rand(0, 127);
};
case PropelColumnTypes::SMALLINT:
return function () {
return mt_rand(0, 32767);
};
case PropelColumnTypes::INTEGER:
return function () {
return mt_rand(0, intval('2147483647'));
};
case PropelColumnTypes::BIGINT:
return function () {
return mt_rand(0, intval('9223372036854775807'));
};
case PropelColumnTypes::FLOAT:
return function () {
return mt_rand(0, intval('2147483647'))/mt_rand(1, intval('2147483647'));
};
case PropelColumnTypes::DOUBLE:
case PropelColumnTypes::REAL:
return function () {
return mt_rand(0, intval('9223372036854775807'))/mt_rand(1, intval('9223372036854775807'));
};
case PropelColumnTypes::CHAR:
case PropelColumnTypes::VARCHAR:
case PropelColumnTypes::BINARY:
case PropelColumnTypes::VARBINARY:
$size = $column->getSize();
return function () use ($generator, $size) {
return $generator->text($size);
};
case PropelColumnTypes::LONGVARCHAR:
case PropelColumnTypes::LONGVARBINARY:
case PropelColumnTypes::CLOB:
case PropelColumnTypes::CLOB_EMU:
case PropelColumnTypes::BLOB:
return function () use ($generator) {
return $generator->text;
};
case PropelColumnTypes::ENUM:
$valueSet = $column->getValueSet();
return function () use ($generator, $valueSet) {
return $generator->randomElement($valueSet);
};
case PropelColumnTypes::OBJECT:
case PropelColumnTypes::PHP_ARRAY:
default:
// no smart way to guess what the user expects here
return null;
}
}
}

View File

@@ -0,0 +1,191 @@
<?php
namespace Faker\ORM\Propel;
use \Faker\Provider\Base;
use \ColumnMap;
/**
* Service class for populating a table through a Propel ActiveRecord class.
*/
class EntityPopulator
{
protected $class;
protected $columnFormatters = array();
protected $modifiers = array();
/**
* Class constructor.
*
* @param string $class A Propel ActiveRecord classname
*/
public function __construct($class)
{
$this->class = $class;
}
/**
* @return string
*/
public function getClass()
{
return $this->class;
}
public function setColumnFormatters($columnFormatters)
{
$this->columnFormatters = $columnFormatters;
}
/**
* @return array
*/
public function getColumnFormatters()
{
return $this->columnFormatters;
}
public function mergeColumnFormattersWith($columnFormatters)
{
$this->columnFormatters = array_merge($this->columnFormatters, $columnFormatters);
}
/**
* @param \Faker\Generator $generator
* @return array
*/
public function guessColumnFormatters(\Faker\Generator $generator)
{
$formatters = array();
$class = $this->class;
$peerClass = $class::PEER;
$tableMap = $peerClass::getTableMap();
$nameGuesser = new \Faker\Guesser\Name($generator);
$columnTypeGuesser = new \Faker\ORM\Propel\ColumnTypeGuesser($generator);
foreach ($tableMap->getColumns() as $columnMap) {
// skip behavior columns, handled by modifiers
if ($this->isColumnBehavior($columnMap)) {
continue;
}
if ($columnMap->isForeignKey()) {
$relatedClass = $columnMap->getRelation()->getForeignTable()->getClassname();
$formatters[$columnMap->getPhpName()] = function ($inserted) use ($relatedClass) {
return isset($inserted[$relatedClass]) ? $inserted[$relatedClass][mt_rand(0, count($inserted[$relatedClass]) - 1)] : null;
};
continue;
}
if ($columnMap->isPrimaryKey()) {
continue;
}
if ($formatter = $nameGuesser->guessFormat($columnMap->getPhpName(), $columnMap->getSize())) {
$formatters[$columnMap->getPhpName()] = $formatter;
continue;
}
if ($formatter = $columnTypeGuesser->guessFormat($columnMap)) {
$formatters[$columnMap->getPhpName()] = $formatter;
continue;
}
}
return $formatters;
}
/**
* @param ColumnMap $columnMap
* @return bool
*/
protected function isColumnBehavior(ColumnMap $columnMap)
{
foreach ($columnMap->getTable()->getBehaviors() as $name => $params) {
$columnName = Base::toLower($columnMap->getName());
switch ($name) {
case 'nested_set':
$columnNames = array($params['left_column'], $params['right_column'], $params['level_column']);
if (in_array($columnName, $columnNames)) {
return true;
}
break;
case 'timestampable':
$columnNames = array($params['create_column'], $params['update_column']);
if (in_array($columnName, $columnNames)) {
return true;
}
break;
}
}
return false;
}
public function setModifiers($modifiers)
{
$this->modifiers = $modifiers;
}
/**
* @return array
*/
public function getModifiers()
{
return $this->modifiers;
}
public function mergeModifiersWith($modifiers)
{
$this->modifiers = array_merge($this->modifiers, $modifiers);
}
/**
* @param \Faker\Generator $generator
* @return array
*/
public function guessModifiers(\Faker\Generator $generator)
{
$modifiers = array();
$class = $this->class;
$peerClass = $class::PEER;
$tableMap = $peerClass::getTableMap();
foreach ($tableMap->getBehaviors() as $name => $params) {
switch ($name) {
case 'nested_set':
$modifiers['nested_set'] = function ($obj, $inserted) use ($class, $generator) {
if (isset($inserted[$class])) {
$queryClass = $class . 'Query';
$parent = $queryClass::create()->findPk($generator->randomElement($inserted[$class]));
$obj->insertAsLastChildOf($parent);
} else {
$obj->makeRoot();
}
};
break;
case 'sortable':
$modifiers['sortable'] = function ($obj, $inserted) use ($class) {
$maxRank = isset($inserted[$class]) ? count($inserted[$class]) : 0;
$obj->insertAtRank(mt_rand(1, $maxRank + 1));
};
break;
}
}
return $modifiers;
}
/**
* Insert one new record using the Entity class.
*/
public function execute($con, $insertedEntities)
{
$obj = new $this->class();
foreach ($this->getColumnFormatters() as $column => $format) {
if (null !== $format) {
$obj->setByName($column, is_callable($format) ? $format($insertedEntities, $obj) : $format);
}
}
foreach ($this->getModifiers() as $modifier) {
$modifier($obj, $insertedEntities);
}
$obj->save($con);
return $obj->getPrimaryKey();
}
}

View File

@@ -0,0 +1,89 @@
<?php
namespace Faker\ORM\Propel;
/**
* Service class for populating a database using the Propel ORM.
* A Populator can populate several tables using ActiveRecord classes.
*/
class Populator
{
protected $generator;
protected $entities = array();
protected $quantities = array();
/**
* @param \Faker\Generator $generator
*/
public function __construct(\Faker\Generator $generator)
{
$this->generator = $generator;
}
/**
* Add an order for the generation of $number records for $entity.
*
* @param mixed $entity A Propel ActiveRecord classname, or a \Faker\ORM\Propel\EntityPopulator instance
* @param int $number The number of entities to populate
*/
public function addEntity($entity, $number, $customColumnFormatters = array(), $customModifiers = array())
{
if (!$entity instanceof \Faker\ORM\Propel\EntityPopulator) {
$entity = new \Faker\ORM\Propel\EntityPopulator($entity);
}
$entity->setColumnFormatters($entity->guessColumnFormatters($this->generator));
if ($customColumnFormatters) {
$entity->mergeColumnFormattersWith($customColumnFormatters);
}
$entity->setModifiers($entity->guessModifiers($this->generator));
if ($customModifiers) {
$entity->mergeModifiersWith($customModifiers);
}
$class = $entity->getClass();
$this->entities[$class] = $entity;
$this->quantities[$class] = $number;
}
/**
* Populate the database using all the Entity classes previously added.
*
* @param PropelPDO $con A Propel connection object
*
* @return array A list of the inserted PKs
*/
public function execute($con = null)
{
if (null === $con) {
$con = $this->getConnection();
}
$isInstancePoolingEnabled = \Propel::isInstancePoolingEnabled();
\Propel::disableInstancePooling();
$insertedEntities = array();
$con->beginTransaction();
foreach ($this->quantities as $class => $number) {
for ($i=0; $i < $number; $i++) {
$insertedEntities[$class][]= $this->entities[$class]->execute($con, $insertedEntities);
}
}
$con->commit();
if ($isInstancePoolingEnabled) {
\Propel::enableInstancePooling();
}
return $insertedEntities;
}
protected function getConnection()
{
// use the first connection available
$class = key($this->entities);
if (!$class) {
throw new \RuntimeException('No class found from entities. Did you add entities to the Populator ?');
}
$peer = $class::PEER;
return \Propel::getConnection($peer::DATABASE_NAME, \Propel::CONNECTION_WRITE);
}
}

View File

@@ -0,0 +1,107 @@
<?php
namespace Faker\ORM\Propel2;
use \Propel\Generator\Model\PropelTypes;
use \Propel\Runtime\Map\ColumnMap;
class ColumnTypeGuesser
{
protected $generator;
/**
* @param \Faker\Generator $generator
*/
public function __construct(\Faker\Generator $generator)
{
$this->generator = $generator;
}
/**
* @param ColumnMap $column
* @return \Closure|null
*/
public function guessFormat(ColumnMap $column)
{
$generator = $this->generator;
if ($column->isTemporal()) {
if ($column->getType() == PropelTypes::BU_DATE || $column->getType() == PropelTypes::BU_TIMESTAMP) {
return function () use ($generator) {
return $generator->dateTime;
};
} else {
return function () use ($generator) {
return $generator->dateTimeAD;
};
}
}
$type = $column->getType();
switch ($type) {
case PropelTypes::BOOLEAN:
case PropelTypes::BOOLEAN_EMU:
return function () use ($generator) {
return $generator->boolean;
};
case PropelTypes::NUMERIC:
case PropelTypes::DECIMAL:
$size = $column->getSize();
return function () use ($generator, $size) {
return $generator->randomNumber($size + 2) / 100;
};
case PropelTypes::TINYINT:
return function () {
return mt_rand(0, 127);
};
case PropelTypes::SMALLINT:
return function () {
return mt_rand(0, 32767);
};
case PropelTypes::INTEGER:
return function () {
return mt_rand(0, intval('2147483647'));
};
case PropelTypes::BIGINT:
return function () {
return mt_rand(0, intval('9223372036854775807'));
};
case PropelTypes::FLOAT:
return function () {
return mt_rand(0, intval('2147483647'))/mt_rand(1, intval('2147483647'));
};
case PropelTypes::DOUBLE:
case PropelTypes::REAL:
return function () {
return mt_rand(0, intval('9223372036854775807'))/mt_rand(1, intval('9223372036854775807'));
};
case PropelTypes::CHAR:
case PropelTypes::VARCHAR:
case PropelTypes::BINARY:
case PropelTypes::VARBINARY:
$size = $column->getSize();
return function () use ($generator, $size) {
return $generator->text($size);
};
case PropelTypes::LONGVARCHAR:
case PropelTypes::LONGVARBINARY:
case PropelTypes::CLOB:
case PropelTypes::CLOB_EMU:
case PropelTypes::BLOB:
return function () use ($generator) {
return $generator->text;
};
case PropelTypes::ENUM:
$valueSet = $column->getValueSet();
return function () use ($generator, $valueSet) {
return $generator->randomElement($valueSet);
};
case PropelTypes::OBJECT:
case PropelTypes::PHP_ARRAY:
default:
// no smart way to guess what the user expects here
return null;
}
}
}

View File

@@ -0,0 +1,192 @@
<?php
namespace Faker\ORM\Propel2;
use \Faker\Provider\Base;
use \Propel\Runtime\Map\ColumnMap;
/**
* Service class for populating a table through a Propel ActiveRecord class.
*/
class EntityPopulator
{
protected $class;
protected $columnFormatters = array();
protected $modifiers = array();
/**
* Class constructor.
*
* @param string $class A Propel ActiveRecord classname
*/
public function __construct($class)
{
$this->class = $class;
}
/**
* @return string
*/
public function getClass()
{
return $this->class;
}
public function setColumnFormatters($columnFormatters)
{
$this->columnFormatters = $columnFormatters;
}
/**
* @return array
*/
public function getColumnFormatters()
{
return $this->columnFormatters;
}
public function mergeColumnFormattersWith($columnFormatters)
{
$this->columnFormatters = array_merge($this->columnFormatters, $columnFormatters);
}
/**
* @param \Faker\Generator $generator
* @return array
*/
public function guessColumnFormatters(\Faker\Generator $generator)
{
$formatters = array();
$class = $this->class;
$peerClass = $class::TABLE_MAP;
$tableMap = $peerClass::getTableMap();
$nameGuesser = new \Faker\Guesser\Name($generator);
$columnTypeGuesser = new \Faker\ORM\Propel2\ColumnTypeGuesser($generator);
foreach ($tableMap->getColumns() as $columnMap) {
// skip behavior columns, handled by modifiers
if ($this->isColumnBehavior($columnMap)) {
continue;
}
if ($columnMap->isForeignKey()) {
$relatedClass = $columnMap->getRelation()->getForeignTable()->getClassname();
$formatters[$columnMap->getPhpName()] = function ($inserted) use ($relatedClass) {
$relatedClass = trim($relatedClass, "\\");
return isset($inserted[$relatedClass]) ? $inserted[$relatedClass][mt_rand(0, count($inserted[$relatedClass]) - 1)] : null;
};
continue;
}
if ($columnMap->isPrimaryKey()) {
continue;
}
if ($formatter = $nameGuesser->guessFormat($columnMap->getPhpName(), $columnMap->getSize())) {
$formatters[$columnMap->getPhpName()] = $formatter;
continue;
}
if ($formatter = $columnTypeGuesser->guessFormat($columnMap)) {
$formatters[$columnMap->getPhpName()] = $formatter;
continue;
}
}
return $formatters;
}
/**
* @param ColumnMap $columnMap
* @return bool
*/
protected function isColumnBehavior(ColumnMap $columnMap)
{
foreach ($columnMap->getTable()->getBehaviors() as $name => $params) {
$columnName = Base::toLower($columnMap->getName());
switch ($name) {
case 'nested_set':
$columnNames = array($params['left_column'], $params['right_column'], $params['level_column']);
if (in_array($columnName, $columnNames)) {
return true;
}
break;
case 'timestampable':
$columnNames = array($params['create_column'], $params['update_column']);
if (in_array($columnName, $columnNames)) {
return true;
}
break;
}
}
return false;
}
public function setModifiers($modifiers)
{
$this->modifiers = $modifiers;
}
/**
* @return array
*/
public function getModifiers()
{
return $this->modifiers;
}
public function mergeModifiersWith($modifiers)
{
$this->modifiers = array_merge($this->modifiers, $modifiers);
}
/**
* @param \Faker\Generator $generator
* @return array
*/
public function guessModifiers(\Faker\Generator $generator)
{
$modifiers = array();
$class = $this->class;
$peerClass = $class::TABLE_MAP;
$tableMap = $peerClass::getTableMap();
foreach ($tableMap->getBehaviors() as $name => $params) {
switch ($name) {
case 'nested_set':
$modifiers['nested_set'] = function ($obj, $inserted) use ($class, $generator) {
if (isset($inserted[$class])) {
$queryClass = $class . 'Query';
$parent = $queryClass::create()->findPk($generator->randomElement($inserted[$class]));
$obj->insertAsLastChildOf($parent);
} else {
$obj->makeRoot();
}
};
break;
case 'sortable':
$modifiers['sortable'] = function ($obj, $inserted) use ($class) {
$maxRank = isset($inserted[$class]) ? count($inserted[$class]) : 0;
$obj->insertAtRank(mt_rand(1, $maxRank + 1));
};
break;
}
}
return $modifiers;
}
/**
* Insert one new record using the Entity class.
*/
public function execute($con, $insertedEntities)
{
$obj = new $this->class();
foreach ($this->getColumnFormatters() as $column => $format) {
if (null !== $format) {
$obj->setByName($column, is_callable($format) ? $format($insertedEntities, $obj) : $format);
}
}
foreach ($this->getModifiers() as $modifier) {
$modifier($obj, $insertedEntities);
}
$obj->save($con);
return $obj->getPrimaryKey();
}
}

View File

@@ -0,0 +1,92 @@
<?php
namespace Faker\ORM\Propel2;
use Propel\Runtime\Propel;
use Propel\Runtime\ServiceContainer\ServiceContainerInterface;
/**
* Service class for populating a database using the Propel ORM.
* A Populator can populate several tables using ActiveRecord classes.
*/
class Populator
{
protected $generator;
protected $entities = array();
protected $quantities = array();
/**
* @param \Faker\Generator $generator
*/
public function __construct(\Faker\Generator $generator)
{
$this->generator = $generator;
}
/**
* Add an order for the generation of $number records for $entity.
*
* @param mixed $entity A Propel ActiveRecord classname, or a \Faker\ORM\Propel2\EntityPopulator instance
* @param int $number The number of entities to populate
*/
public function addEntity($entity, $number, $customColumnFormatters = array(), $customModifiers = array())
{
if (!$entity instanceof \Faker\ORM\Propel2\EntityPopulator) {
$entity = new \Faker\ORM\Propel2\EntityPopulator($entity);
}
$entity->setColumnFormatters($entity->guessColumnFormatters($this->generator));
if ($customColumnFormatters) {
$entity->mergeColumnFormattersWith($customColumnFormatters);
}
$entity->setModifiers($entity->guessModifiers($this->generator));
if ($customModifiers) {
$entity->mergeModifiersWith($customModifiers);
}
$class = $entity->getClass();
$this->entities[$class] = $entity;
$this->quantities[$class] = $number;
}
/**
* Populate the database using all the Entity classes previously added.
*
* @param PropelPDO $con A Propel connection object
*
* @return array A list of the inserted PKs
*/
public function execute($con = null)
{
if (null === $con) {
$con = $this->getConnection();
}
$isInstancePoolingEnabled = Propel::isInstancePoolingEnabled();
Propel::disableInstancePooling();
$insertedEntities = array();
$con->beginTransaction();
foreach ($this->quantities as $class => $number) {
for ($i=0; $i < $number; $i++) {
$insertedEntities[$class][]= $this->entities[$class]->execute($con, $insertedEntities);
}
}
$con->commit();
if ($isInstancePoolingEnabled) {
Propel::enableInstancePooling();
}
return $insertedEntities;
}
protected function getConnection()
{
// use the first connection available
$class = key($this->entities);
if (!$class) {
throw new \RuntimeException('No class found from entities. Did you add entities to the Populator ?');
}
$peer = $class::TABLE_MAP;
return Propel::getConnection($peer::DATABASE_NAME, ServiceContainerInterface::CONNECTION_WRITE);
}
}

View File

@@ -0,0 +1,77 @@
<?php
namespace Faker\ORM\Spot;
use Faker\Generator;
class ColumnTypeGuesser
{
protected $generator;
/**
* ColumnTypeGuesser constructor.
* @param Generator $generator
*/
public function __construct(Generator $generator)
{
$this->generator = $generator;
}
/**
* @param array $field
* @return \Closure|null
*/
public function guessFormat(array $field)
{
$generator = $this->generator;
$type = $field['type'];
switch ($type) {
case 'boolean':
return function () use ($generator) {
return $generator->boolean;
};
case 'decimal':
$size = isset($field['precision']) ? $field['precision'] : 2;
return function () use ($generator, $size) {
return $generator->randomNumber($size + 2) / 100;
};
case 'smallint':
return function () use ($generator) {
return $generator->numberBetween(0, 65535);
};
case 'integer':
return function () use ($generator) {
return $generator->numberBetween(0, intval('2147483647'));
};
case 'bigint':
return function () use ($generator) {
return $generator->numberBetween(0, intval('18446744073709551615'));
};
case 'float':
return function () use ($generator) {
return $generator->randomFloat(null, 0, intval('4294967295'));
};
case 'string':
$size = isset($field['length']) ? $field['length'] : 255;
return function () use ($generator, $size) {
return $generator->text($size);
};
case 'text':
return function () use ($generator) {
return $generator->text;
};
case 'datetime':
case 'date':
case 'time':
return function () use ($generator) {
return $generator->datetime;
};
default:
// no smart way to guess what the user expects here
return null;
}
}
}

View File

@@ -0,0 +1,222 @@
<?php
namespace Faker\ORM\Spot;
use Faker\Generator;
use Faker\Guesser\Name;
use Spot\Locator;
use Spot\Mapper;
use Spot\Relation\BelongsTo;
/**
* Service class for populating a table through a Spot Entity class.
*/
class EntityPopulator
{
/**
* When fetching existing data - fetch only few first rows.
*/
const RELATED_FETCH_COUNT = 10;
/**
* @var Mapper
*/
protected $mapper;
/**
* @var Locator
*/
protected $locator;
/**
* @var array
*/
protected $columnFormatters = array();
/**
* @var array
*/
protected $modifiers = array();
/**
* @var bool
*/
protected $useExistingData = false;
/**
* Class constructor.
*
* @param Mapper $mapper
* @param Locator $locator
* @param $useExistingData
*/
public function __construct(Mapper $mapper, Locator $locator, $useExistingData = false)
{
$this->mapper = $mapper;
$this->locator = $locator;
$this->useExistingData = $useExistingData;
}
/**
* @return string
*/
public function getMapper()
{
return $this->mapper;
}
/**
* @param $columnFormatters
*/
public function setColumnFormatters($columnFormatters)
{
$this->columnFormatters = $columnFormatters;
}
/**
* @return array
*/
public function getColumnFormatters()
{
return $this->columnFormatters;
}
/**
* @param $columnFormatters
*/
public function mergeColumnFormattersWith($columnFormatters)
{
$this->columnFormatters = array_merge($this->columnFormatters, $columnFormatters);
}
/**
* @param array $modifiers
*/
public function setModifiers(array $modifiers)
{
$this->modifiers = $modifiers;
}
/**
* @return array
*/
public function getModifiers()
{
return $this->modifiers;
}
/**
* @param array $modifiers
*/
public function mergeModifiersWith(array $modifiers)
{
$this->modifiers = array_merge($this->modifiers, $modifiers);
}
/**
* @param Generator $generator
* @return array
*/
public function guessColumnFormatters(Generator $generator)
{
$formatters = array();
$nameGuesser = new Name($generator);
$columnTypeGuesser = new ColumnTypeGuesser($generator);
$fields = $this->mapper->fields();
foreach ($fields as $fieldName => $field) {
if ($field['primary'] === true) {
continue;
}
if ($formatter = $nameGuesser->guessFormat($fieldName)) {
$formatters[$fieldName] = $formatter;
continue;
}
if ($formatter = $columnTypeGuesser->guessFormat($field)) {
$formatters[$fieldName] = $formatter;
continue;
}
}
$entityName = $this->mapper->entity();
$entity = $this->mapper->build([]);
$relations = $entityName::relations($this->mapper, $entity);
foreach ($relations as $relation) {
// We don't need any other relation here.
if ($relation instanceof BelongsTo) {
$fieldName = $relation->localKey();
$entityName = $relation->entityName();
$field = $fields[$fieldName];
$required = $field['required'];
$locator = $this->locator;
$formatters[$fieldName] = function ($inserted) use ($required, $entityName, $locator) {
if (!empty($inserted[$entityName])) {
return $inserted[$entityName][mt_rand(0, count($inserted[$entityName]) - 1)]->getId();
} else {
if ($required && $this->useExistingData) {
// We did not add anything like this, but it's required,
// So let's find something existing in DB.
$mapper = $this->locator->mapper($entityName);
$records = $mapper->all()->limit(self::RELATED_FETCH_COUNT)->toArray();
if (empty($records)) {
return null;
}
$id = $records[mt_rand(0, count($records) - 1)]['id'];
return $id;
} else {
return null;
}
}
};
}
}
return $formatters;
}
/**
* Insert one new record using the Entity class.
*
* @param $insertedEntities
* @return string
*/
public function execute($insertedEntities)
{
$obj = $this->mapper->build([]);
$this->fillColumns($obj, $insertedEntities);
$this->callMethods($obj, $insertedEntities);
$this->mapper->insert($obj);
return $obj;
}
/**
* @param $obj
* @param $insertedEntities
*/
private function fillColumns($obj, $insertedEntities)
{
foreach ($this->columnFormatters as $field => $format) {
if (null !== $format) {
$value = is_callable($format) ? $format($insertedEntities, $obj) : $format;
$obj->set($field, $value);
}
}
}
/**
* @param $obj
* @param $insertedEntities
*/
private function callMethods($obj, $insertedEntities)
{
foreach ($this->getModifiers() as $modifier) {
$modifier($obj, $insertedEntities);
}
}
}

View File

@@ -0,0 +1,88 @@
<?php
namespace Faker\ORM\Spot;
use Spot\Locator;
/**
* Service class for populating a database using the Spot ORM.
*/
class Populator
{
protected $generator;
protected $locator;
protected $entities = array();
protected $quantities = array();
/**
* Populator constructor.
* @param \Faker\Generator $generator
* @param Locator|null $locator
*/
public function __construct(\Faker\Generator $generator, Locator $locator = null)
{
$this->generator = $generator;
$this->locator = $locator;
}
/**
* Add an order for the generation of $number records for $entity.
*
* @param $entityName string Name of Entity object to generate
* @param $number int The number of entities to populate
* @param $customColumnFormatters array
* @param $customModifiers array
* @param $useExistingData bool Should we use existing rows (e.g. roles) to populate relations?
*/
public function addEntity(
$entityName,
$number,
$customColumnFormatters = array(),
$customModifiers = array(),
$useExistingData = false
) {
$mapper = $this->locator->mapper($entityName);
if (null === $mapper) {
throw new \InvalidArgumentException("No mapper can be found for entity " . $entityName);
}
$entity = new EntityPopulator($mapper, $this->locator, $useExistingData);
$entity->setColumnFormatters($entity->guessColumnFormatters($this->generator));
if ($customColumnFormatters) {
$entity->mergeColumnFormattersWith($customColumnFormatters);
}
$entity->mergeModifiersWith($customModifiers);
$this->entities[$entityName] = $entity;
$this->quantities[$entityName] = $number;
}
/**
* Populate the database using all the Entity classes previously added.
*
* @param Locator $locator A Spot locator
*
* @return array A list of the inserted PKs
*/
public function execute($locator = null)
{
if (null === $locator) {
$locator = $this->locator;
}
if (null === $locator) {
throw new \InvalidArgumentException("No entity manager passed to Spot Populator.");
}
$insertedEntities = array();
foreach ($this->quantities as $entityName => $number) {
for ($i = 0; $i < $number; $i++) {
$insertedEntities[$entityName][] = $this->entities[$entityName]->execute(
$insertedEntities
);
}
}
return $insertedEntities;
}
}

Some files were not shown because too many files have changed in this diff Show More