[Ivan Diaz] - Delete vendor
This commit is contained in:
parent
fb1475957e
commit
10e3fd5b4f
File diff suppressed because it is too large
Load Diff
|
@ -1,7 +0,0 @@
|
|||
<?php
|
||||
|
||||
// autoload.php @generated by Composer
|
||||
|
||||
require_once __DIR__ . '/composer' . '/autoload_real.php';
|
||||
|
||||
return ComposerAutoloaderInitc1131bbfb8e9acff5fc8b79d0d7d1f64::getLoader();
|
|
@ -1 +0,0 @@
|
|||
../phpunit/phpunit/phpunit
|
|
@ -1,413 +0,0 @@
|
|||
<?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 class loader
|
||||
*
|
||||
* See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md
|
||||
*
|
||||
* $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>
|
||||
*/
|
||||
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;
|
||||
|
||||
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-0 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
// work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731
|
||||
if ('\\' == $class[0]) {
|
||||
$class = substr($class, 1);
|
||||
}
|
||||
|
||||
// class map lookup
|
||||
if (isset($this->classMap[$class])) {
|
||||
return $this->classMap[$class];
|
||||
}
|
||||
if ($this->classMapAuthoritative) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$file = $this->findFileWithExtension($class, '.php');
|
||||
|
||||
// Search for Hack files if we are running on HHVM
|
||||
if ($file === null && defined('HHVM_VERSION')) {
|
||||
$file = $this->findFileWithExtension($class, '.hh');
|
||||
}
|
||||
|
||||
if ($file === null) {
|
||||
// Remember that this class does not exist.
|
||||
return $this->classMap[$class] = false;
|
||||
}
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
private function findFileWithExtension($class, $ext)
|
||||
{
|
||||
// PSR-4 lookup
|
||||
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
|
||||
|
||||
$first = $class[0];
|
||||
if (isset($this->prefixLengthsPsr4[$first])) {
|
||||
foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) {
|
||||
if (0 === strpos($class, $prefix)) {
|
||||
foreach ($this->prefixDirsPsr4[$prefix] as $dir) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope isolated include.
|
||||
*
|
||||
* Prevents access to $this/self from included files.
|
||||
*/
|
||||
function includeFile($file)
|
||||
{
|
||||
include $file;
|
||||
}
|
|
@ -1,450 +0,0 @@
|
|||
<?php
|
||||
|
||||
// autoload_classmap.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'File_Iterator' => $vendorDir . '/phpunit/php-file-iterator/src/Iterator.php',
|
||||
'File_Iterator_Facade' => $vendorDir . '/phpunit/php-file-iterator/src/Facade.php',
|
||||
'File_Iterator_Factory' => $vendorDir . '/phpunit/php-file-iterator/src/Factory.php',
|
||||
'PHPUnit_Exception' => $vendorDir . '/phpunit/phpunit/src/Exception.php',
|
||||
'PHPUnit_Extensions_GroupTestSuite' => $vendorDir . '/phpunit/phpunit/src/Extensions/GroupTestSuite.php',
|
||||
'PHPUnit_Extensions_PhptTestCase' => $vendorDir . '/phpunit/phpunit/src/Extensions/PhptTestCase.php',
|
||||
'PHPUnit_Extensions_PhptTestSuite' => $vendorDir . '/phpunit/phpunit/src/Extensions/PhptTestSuite.php',
|
||||
'PHPUnit_Extensions_RepeatedTest' => $vendorDir . '/phpunit/phpunit/src/Extensions/RepeatedTest.php',
|
||||
'PHPUnit_Extensions_TestDecorator' => $vendorDir . '/phpunit/phpunit/src/Extensions/TestDecorator.php',
|
||||
'PHPUnit_Extensions_TicketListener' => $vendorDir . '/phpunit/phpunit/src/Extensions/TicketListener.php',
|
||||
'PHPUnit_Framework_Assert' => $vendorDir . '/phpunit/phpunit/src/Framework/Assert.php',
|
||||
'PHPUnit_Framework_AssertionFailedError' => $vendorDir . '/phpunit/phpunit/src/Framework/AssertionFailedError.php',
|
||||
'PHPUnit_Framework_BaseTestListener' => $vendorDir . '/phpunit/phpunit/src/Framework/BaseTestListener.php',
|
||||
'PHPUnit_Framework_CodeCoverageException' => $vendorDir . '/phpunit/phpunit/src/Framework/CodeCoverageException.php',
|
||||
'PHPUnit_Framework_Constraint' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint.php',
|
||||
'PHPUnit_Framework_Constraint_And' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/And.php',
|
||||
'PHPUnit_Framework_Constraint_ArrayHasKey' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ArrayHasKey.php',
|
||||
'PHPUnit_Framework_Constraint_ArraySubset' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ArraySubset.php',
|
||||
'PHPUnit_Framework_Constraint_Attribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Attribute.php',
|
||||
'PHPUnit_Framework_Constraint_Callback' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Callback.php',
|
||||
'PHPUnit_Framework_Constraint_ClassHasAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ClassHasAttribute.php',
|
||||
'PHPUnit_Framework_Constraint_ClassHasStaticAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ClassHasStaticAttribute.php',
|
||||
'PHPUnit_Framework_Constraint_Composite' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Composite.php',
|
||||
'PHPUnit_Framework_Constraint_Count' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Count.php',
|
||||
'PHPUnit_Framework_Constraint_Exception' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Exception.php',
|
||||
'PHPUnit_Framework_Constraint_ExceptionCode' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionCode.php',
|
||||
'PHPUnit_Framework_Constraint_ExceptionMessage' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessage.php',
|
||||
'PHPUnit_Framework_Constraint_ExceptionMessageRegExp' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessageRegExp.php',
|
||||
'PHPUnit_Framework_Constraint_FileExists' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/FileExists.php',
|
||||
'PHPUnit_Framework_Constraint_GreaterThan' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/GreaterThan.php',
|
||||
'PHPUnit_Framework_Constraint_IsAnything' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsAnything.php',
|
||||
'PHPUnit_Framework_Constraint_IsEmpty' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsEmpty.php',
|
||||
'PHPUnit_Framework_Constraint_IsEqual' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsEqual.php',
|
||||
'PHPUnit_Framework_Constraint_IsFalse' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsFalse.php',
|
||||
'PHPUnit_Framework_Constraint_IsFinite' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsFinite.php',
|
||||
'PHPUnit_Framework_Constraint_IsIdentical' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsIdentical.php',
|
||||
'PHPUnit_Framework_Constraint_IsInfinite' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsInfinite.php',
|
||||
'PHPUnit_Framework_Constraint_IsInstanceOf' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsInstanceOf.php',
|
||||
'PHPUnit_Framework_Constraint_IsJson' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsJson.php',
|
||||
'PHPUnit_Framework_Constraint_IsNan' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsNan.php',
|
||||
'PHPUnit_Framework_Constraint_IsNull' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsNull.php',
|
||||
'PHPUnit_Framework_Constraint_IsTrue' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsTrue.php',
|
||||
'PHPUnit_Framework_Constraint_IsType' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsType.php',
|
||||
'PHPUnit_Framework_Constraint_JsonMatches' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/JsonMatches.php',
|
||||
'PHPUnit_Framework_Constraint_JsonMatches_ErrorMessageProvider' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/JsonMatches/ErrorMessageProvider.php',
|
||||
'PHPUnit_Framework_Constraint_LessThan' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LessThan.php',
|
||||
'PHPUnit_Framework_Constraint_Not' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Not.php',
|
||||
'PHPUnit_Framework_Constraint_ObjectHasAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ObjectHasAttribute.php',
|
||||
'PHPUnit_Framework_Constraint_Or' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Or.php',
|
||||
'PHPUnit_Framework_Constraint_PCREMatch' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/PCREMatch.php',
|
||||
'PHPUnit_Framework_Constraint_SameSize' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/SameSize.php',
|
||||
'PHPUnit_Framework_Constraint_StringContains' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringContains.php',
|
||||
'PHPUnit_Framework_Constraint_StringEndsWith' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringEndsWith.php',
|
||||
'PHPUnit_Framework_Constraint_StringMatches' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringMatches.php',
|
||||
'PHPUnit_Framework_Constraint_StringStartsWith' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringStartsWith.php',
|
||||
'PHPUnit_Framework_Constraint_TraversableContains' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/TraversableContains.php',
|
||||
'PHPUnit_Framework_Constraint_TraversableContainsOnly' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/TraversableContainsOnly.php',
|
||||
'PHPUnit_Framework_Constraint_Xor' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Xor.php',
|
||||
'PHPUnit_Framework_Error' => $vendorDir . '/phpunit/phpunit/src/Framework/Error.php',
|
||||
'PHPUnit_Framework_Error_Deprecated' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Deprecated.php',
|
||||
'PHPUnit_Framework_Error_Notice' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Notice.php',
|
||||
'PHPUnit_Framework_Error_Warning' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Warning.php',
|
||||
'PHPUnit_Framework_Exception' => $vendorDir . '/phpunit/phpunit/src/Framework/Exception.php',
|
||||
'PHPUnit_Framework_ExceptionWrapper' => $vendorDir . '/phpunit/phpunit/src/Framework/ExceptionWrapper.php',
|
||||
'PHPUnit_Framework_ExpectationFailedException' => $vendorDir . '/phpunit/phpunit/src/Framework/ExpectationFailedException.php',
|
||||
'PHPUnit_Framework_IncompleteTest' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTest.php',
|
||||
'PHPUnit_Framework_IncompleteTestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTestCase.php',
|
||||
'PHPUnit_Framework_IncompleteTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTestError.php',
|
||||
'PHPUnit_Framework_InvalidCoversTargetError' => $vendorDir . '/phpunit/phpunit/src/Framework/InvalidCoversTargetError.php',
|
||||
'PHPUnit_Framework_InvalidCoversTargetException' => $vendorDir . '/phpunit/phpunit/src/Framework/InvalidCoversTargetException.php',
|
||||
'PHPUnit_Framework_MockObject_BadMethodCallException' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/BadMethodCallException.php',
|
||||
'PHPUnit_Framework_MockObject_Builder_Identity' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Identity.php',
|
||||
'PHPUnit_Framework_MockObject_Builder_InvocationMocker' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/InvocationMocker.php',
|
||||
'PHPUnit_Framework_MockObject_Builder_Match' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Match.php',
|
||||
'PHPUnit_Framework_MockObject_Builder_MethodNameMatch' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/MethodNameMatch.php',
|
||||
'PHPUnit_Framework_MockObject_Builder_Namespace' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Namespace.php',
|
||||
'PHPUnit_Framework_MockObject_Builder_ParametersMatch' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/ParametersMatch.php',
|
||||
'PHPUnit_Framework_MockObject_Builder_Stub' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Stub.php',
|
||||
'PHPUnit_Framework_MockObject_Exception' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/Exception.php',
|
||||
'PHPUnit_Framework_MockObject_Generator' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator.php',
|
||||
'PHPUnit_Framework_MockObject_Invocation' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation.php',
|
||||
'PHPUnit_Framework_MockObject_InvocationMocker' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/InvocationMocker.php',
|
||||
'PHPUnit_Framework_MockObject_Invocation_Object' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation/Object.php',
|
||||
'PHPUnit_Framework_MockObject_Invocation_Static' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation/Static.php',
|
||||
'PHPUnit_Framework_MockObject_Invokable' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invokable.php',
|
||||
'PHPUnit_Framework_MockObject_Matcher' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher.php',
|
||||
'PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/AnyInvokedCount.php',
|
||||
'PHPUnit_Framework_MockObject_Matcher_AnyParameters' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/AnyParameters.php',
|
||||
'PHPUnit_Framework_MockObject_Matcher_ConsecutiveParameters' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/ConsecutiveParameters.php',
|
||||
'PHPUnit_Framework_MockObject_Matcher_Invocation' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/Invocation.php',
|
||||
'PHPUnit_Framework_MockObject_Matcher_InvokedAtIndex' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtIndex.php',
|
||||
'PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtLeastCount.php',
|
||||
'PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastOnce' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtLeastOnce.php',
|
||||
'PHPUnit_Framework_MockObject_Matcher_InvokedAtMostCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtMostCount.php',
|
||||
'PHPUnit_Framework_MockObject_Matcher_InvokedCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedCount.php',
|
||||
'PHPUnit_Framework_MockObject_Matcher_InvokedRecorder' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedRecorder.php',
|
||||
'PHPUnit_Framework_MockObject_Matcher_MethodName' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/MethodName.php',
|
||||
'PHPUnit_Framework_MockObject_Matcher_Parameters' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/Parameters.php',
|
||||
'PHPUnit_Framework_MockObject_Matcher_StatelessInvocation' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/StatelessInvocation.php',
|
||||
'PHPUnit_Framework_MockObject_MockBuilder' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/MockBuilder.php',
|
||||
'PHPUnit_Framework_MockObject_MockObject' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/MockObject.php',
|
||||
'PHPUnit_Framework_MockObject_RuntimeException' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/RuntimeException.php',
|
||||
'PHPUnit_Framework_MockObject_Stub' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub.php',
|
||||
'PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ConsecutiveCalls.php',
|
||||
'PHPUnit_Framework_MockObject_Stub_Exception' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/Exception.php',
|
||||
'PHPUnit_Framework_MockObject_Stub_MatcherCollection' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/MatcherCollection.php',
|
||||
'PHPUnit_Framework_MockObject_Stub_Return' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/Return.php',
|
||||
'PHPUnit_Framework_MockObject_Stub_ReturnArgument' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnArgument.php',
|
||||
'PHPUnit_Framework_MockObject_Stub_ReturnCallback' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnCallback.php',
|
||||
'PHPUnit_Framework_MockObject_Stub_ReturnSelf' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnSelf.php',
|
||||
'PHPUnit_Framework_MockObject_Stub_ReturnValueMap' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnValueMap.php',
|
||||
'PHPUnit_Framework_MockObject_Verifiable' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Verifiable.php',
|
||||
'PHPUnit_Framework_OutputError' => $vendorDir . '/phpunit/phpunit/src/Framework/OutputError.php',
|
||||
'PHPUnit_Framework_RiskyTest' => $vendorDir . '/phpunit/phpunit/src/Framework/RiskyTest.php',
|
||||
'PHPUnit_Framework_RiskyTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/RiskyTestError.php',
|
||||
'PHPUnit_Framework_SelfDescribing' => $vendorDir . '/phpunit/phpunit/src/Framework/SelfDescribing.php',
|
||||
'PHPUnit_Framework_SkippedTest' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTest.php',
|
||||
'PHPUnit_Framework_SkippedTestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTestCase.php',
|
||||
'PHPUnit_Framework_SkippedTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTestError.php',
|
||||
'PHPUnit_Framework_SkippedTestSuiteError' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTestSuiteError.php',
|
||||
'PHPUnit_Framework_SyntheticError' => $vendorDir . '/phpunit/phpunit/src/Framework/SyntheticError.php',
|
||||
'PHPUnit_Framework_Test' => $vendorDir . '/phpunit/phpunit/src/Framework/Test.php',
|
||||
'PHPUnit_Framework_TestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/TestCase.php',
|
||||
'PHPUnit_Framework_TestFailure' => $vendorDir . '/phpunit/phpunit/src/Framework/TestFailure.php',
|
||||
'PHPUnit_Framework_TestListener' => $vendorDir . '/phpunit/phpunit/src/Framework/TestListener.php',
|
||||
'PHPUnit_Framework_TestResult' => $vendorDir . '/phpunit/phpunit/src/Framework/TestResult.php',
|
||||
'PHPUnit_Framework_TestSuite' => $vendorDir . '/phpunit/phpunit/src/Framework/TestSuite.php',
|
||||
'PHPUnit_Framework_TestSuite_DataProvider' => $vendorDir . '/phpunit/phpunit/src/Framework/TestSuite/DataProvider.php',
|
||||
'PHPUnit_Framework_UnintentionallyCoveredCodeError' => $vendorDir . '/phpunit/phpunit/src/Framework/UnintentionallyCoveredCodeError.php',
|
||||
'PHPUnit_Framework_Warning' => $vendorDir . '/phpunit/phpunit/src/Framework/Warning.php',
|
||||
'PHPUnit_Runner_BaseTestRunner' => $vendorDir . '/phpunit/phpunit/src/Runner/BaseTestRunner.php',
|
||||
'PHPUnit_Runner_Exception' => $vendorDir . '/phpunit/phpunit/src/Runner/Exception.php',
|
||||
'PHPUnit_Runner_Filter_Factory' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Factory.php',
|
||||
'PHPUnit_Runner_Filter_GroupFilterIterator' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Group.php',
|
||||
'PHPUnit_Runner_Filter_Group_Exclude' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Group/Exclude.php',
|
||||
'PHPUnit_Runner_Filter_Group_Include' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Group/Include.php',
|
||||
'PHPUnit_Runner_Filter_Test' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Test.php',
|
||||
'PHPUnit_Runner_StandardTestSuiteLoader' => $vendorDir . '/phpunit/phpunit/src/Runner/StandardTestSuiteLoader.php',
|
||||
'PHPUnit_Runner_TestSuiteLoader' => $vendorDir . '/phpunit/phpunit/src/Runner/TestSuiteLoader.php',
|
||||
'PHPUnit_Runner_Version' => $vendorDir . '/phpunit/phpunit/src/Runner/Version.php',
|
||||
'PHPUnit_TextUI_Command' => $vendorDir . '/phpunit/phpunit/src/TextUI/Command.php',
|
||||
'PHPUnit_TextUI_ResultPrinter' => $vendorDir . '/phpunit/phpunit/src/TextUI/ResultPrinter.php',
|
||||
'PHPUnit_TextUI_TestRunner' => $vendorDir . '/phpunit/phpunit/src/TextUI/TestRunner.php',
|
||||
'PHPUnit_Util_Blacklist' => $vendorDir . '/phpunit/phpunit/src/Util/Blacklist.php',
|
||||
'PHPUnit_Util_Configuration' => $vendorDir . '/phpunit/phpunit/src/Util/Configuration.php',
|
||||
'PHPUnit_Util_ErrorHandler' => $vendorDir . '/phpunit/phpunit/src/Util/ErrorHandler.php',
|
||||
'PHPUnit_Util_Fileloader' => $vendorDir . '/phpunit/phpunit/src/Util/Fileloader.php',
|
||||
'PHPUnit_Util_Filesystem' => $vendorDir . '/phpunit/phpunit/src/Util/Filesystem.php',
|
||||
'PHPUnit_Util_Filter' => $vendorDir . '/phpunit/phpunit/src/Util/Filter.php',
|
||||
'PHPUnit_Util_Getopt' => $vendorDir . '/phpunit/phpunit/src/Util/Getopt.php',
|
||||
'PHPUnit_Util_GlobalState' => $vendorDir . '/phpunit/phpunit/src/Util/GlobalState.php',
|
||||
'PHPUnit_Util_InvalidArgumentHelper' => $vendorDir . '/phpunit/phpunit/src/Util/InvalidArgumentHelper.php',
|
||||
'PHPUnit_Util_Log_JSON' => $vendorDir . '/phpunit/phpunit/src/Util/Log/JSON.php',
|
||||
'PHPUnit_Util_Log_JUnit' => $vendorDir . '/phpunit/phpunit/src/Util/Log/JUnit.php',
|
||||
'PHPUnit_Util_Log_TAP' => $vendorDir . '/phpunit/phpunit/src/Util/Log/TAP.php',
|
||||
'PHPUnit_Util_Log_TeamCity' => $vendorDir . '/phpunit/phpunit/src/Util/Log/TeamCity.php',
|
||||
'PHPUnit_Util_PHP' => $vendorDir . '/phpunit/phpunit/src/Util/PHP.php',
|
||||
'PHPUnit_Util_PHP_Default' => $vendorDir . '/phpunit/phpunit/src/Util/PHP/Default.php',
|
||||
'PHPUnit_Util_PHP_Windows' => $vendorDir . '/phpunit/phpunit/src/Util/PHP/Windows.php',
|
||||
'PHPUnit_Util_Printer' => $vendorDir . '/phpunit/phpunit/src/Util/Printer.php',
|
||||
'PHPUnit_Util_Regex' => $vendorDir . '/phpunit/phpunit/src/Util/Regex.php',
|
||||
'PHPUnit_Util_String' => $vendorDir . '/phpunit/phpunit/src/Util/String.php',
|
||||
'PHPUnit_Util_Test' => $vendorDir . '/phpunit/phpunit/src/Util/Test.php',
|
||||
'PHPUnit_Util_TestDox_NamePrettifier' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/NamePrettifier.php',
|
||||
'PHPUnit_Util_TestDox_ResultPrinter' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter.php',
|
||||
'PHPUnit_Util_TestDox_ResultPrinter_HTML' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter/HTML.php',
|
||||
'PHPUnit_Util_TestDox_ResultPrinter_Text' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter/Text.php',
|
||||
'PHPUnit_Util_TestSuiteIterator' => $vendorDir . '/phpunit/phpunit/src/Util/TestSuiteIterator.php',
|
||||
'PHPUnit_Util_Type' => $vendorDir . '/phpunit/phpunit/src/Util/Type.php',
|
||||
'PHPUnit_Util_XML' => $vendorDir . '/phpunit/phpunit/src/Util/XML.php',
|
||||
'PHP_CodeCoverage' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage.php',
|
||||
'PHP_CodeCoverage_Driver' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Driver.php',
|
||||
'PHP_CodeCoverage_Driver_HHVM' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Driver/HHVM.php',
|
||||
'PHP_CodeCoverage_Driver_PHPDBG' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Driver/PHPDBG.php',
|
||||
'PHP_CodeCoverage_Driver_Xdebug' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Driver/Xdebug.php',
|
||||
'PHP_CodeCoverage_Exception' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Exception/Exception.php',
|
||||
'PHP_CodeCoverage_Filter' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Filter.php',
|
||||
'PHP_CodeCoverage_InvalidArgumentException' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Exception/InvalidArgumentException.php',
|
||||
'PHP_CodeCoverage_Report_Clover' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/Clover.php',
|
||||
'PHP_CodeCoverage_Report_Crap4j' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/Crap4j.php',
|
||||
'PHP_CodeCoverage_Report_Factory' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/Factory.php',
|
||||
'PHP_CodeCoverage_Report_HTML' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML.php',
|
||||
'PHP_CodeCoverage_Report_HTML_Renderer' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer.php',
|
||||
'PHP_CodeCoverage_Report_HTML_Renderer_Dashboard' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Dashboard.php',
|
||||
'PHP_CodeCoverage_Report_HTML_Renderer_Directory' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Directory.php',
|
||||
'PHP_CodeCoverage_Report_HTML_Renderer_File' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/File.php',
|
||||
'PHP_CodeCoverage_Report_Node' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/Node.php',
|
||||
'PHP_CodeCoverage_Report_Node_Directory' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/Node/Directory.php',
|
||||
'PHP_CodeCoverage_Report_Node_File' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/Node/File.php',
|
||||
'PHP_CodeCoverage_Report_Node_Iterator' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/Node/Iterator.php',
|
||||
'PHP_CodeCoverage_Report_PHP' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/PHP.php',
|
||||
'PHP_CodeCoverage_Report_Text' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/Text.php',
|
||||
'PHP_CodeCoverage_Report_XML' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML.php',
|
||||
'PHP_CodeCoverage_Report_XML_Directory' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/Directory.php',
|
||||
'PHP_CodeCoverage_Report_XML_File' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/File.php',
|
||||
'PHP_CodeCoverage_Report_XML_File_Coverage' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/File/Coverage.php',
|
||||
'PHP_CodeCoverage_Report_XML_File_Method' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/File/Method.php',
|
||||
'PHP_CodeCoverage_Report_XML_File_Report' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/File/Report.php',
|
||||
'PHP_CodeCoverage_Report_XML_File_Unit' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/File/Unit.php',
|
||||
'PHP_CodeCoverage_Report_XML_Node' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/Node.php',
|
||||
'PHP_CodeCoverage_Report_XML_Project' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/Project.php',
|
||||
'PHP_CodeCoverage_Report_XML_Tests' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/Tests.php',
|
||||
'PHP_CodeCoverage_Report_XML_Totals' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/Totals.php',
|
||||
'PHP_CodeCoverage_RuntimeException' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Exception/RuntimeException.php',
|
||||
'PHP_CodeCoverage_UnintentionallyCoveredCodeException' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Exception/UnintentionallyCoveredCodeException.php',
|
||||
'PHP_CodeCoverage_Util' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Util.php',
|
||||
'PHP_Timer' => $vendorDir . '/phpunit/php-timer/src/Timer.php',
|
||||
'PHP_Token' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_TokenWithScope' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_TokenWithScopeAndVisibility' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_ABSTRACT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_AMPERSAND' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_AND_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_ARRAY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_ARRAY_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_AS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_ASYNC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_AT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_AWAIT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_BACKTICK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_BAD_CHARACTER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_BOOLEAN_AND' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_BOOLEAN_OR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_BOOL_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_BREAK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_CALLABLE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_CARET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_CASE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_CATCH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_CHARACTER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_CLASS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_CLASS_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_CLASS_NAME_CONSTANT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_CLONE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_CLOSE_BRACKET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_CLOSE_CURLY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_CLOSE_SQUARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_CLOSE_TAG' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_COALESCE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_COLON' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_COMMA' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_COMMENT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_COMPILER_HALT_OFFSET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_CONCAT_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_CONST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_CONSTANT_ENCAPSED_STRING' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_CONTINUE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_CURLY_OPEN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_DEC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_DECLARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_DEFAULT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_DIR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_DIV' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_DIV_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_DNUMBER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_DO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_DOC_COMMENT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_DOLLAR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_DOLLAR_OPEN_CURLY_BRACES' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_DOT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_DOUBLE_ARROW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_DOUBLE_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_DOUBLE_COLON' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_DOUBLE_QUOTES' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_ECHO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_ELLIPSIS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_ELSE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_ELSEIF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_EMPTY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_ENCAPSED_AND_WHITESPACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_ENDDECLARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_ENDFOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_ENDFOREACH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_ENDIF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_ENDSWITCH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_ENDWHILE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_END_HEREDOC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_ENUM' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_EQUALS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_EVAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_EXCLAMATION_MARK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_EXIT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_EXTENDS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_FILE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_FINAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_FINALLY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_FOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_FOREACH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_FUNCTION' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_FUNC_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_GLOBAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_GOTO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_GT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_HALT_COMPILER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_IF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_IMPLEMENTS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_IN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_INC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_INCLUDE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_INCLUDE_ONCE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_INLINE_HTML' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_INSTANCEOF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_INSTEADOF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_INTERFACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_INT_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_ISSET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_IS_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_IS_GREATER_OR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_IS_IDENTICAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_IS_NOT_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_IS_NOT_IDENTICAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_IS_SMALLER_OR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_Includes' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_JOIN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_LAMBDA_ARROW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_LAMBDA_CP' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_LAMBDA_OP' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_LINE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_LIST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_LNUMBER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_LOGICAL_AND' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_LOGICAL_OR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_LOGICAL_XOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_LT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_METHOD_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_MINUS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_MINUS_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_MOD_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_MULT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_MUL_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_NAMESPACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_NEW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_NS_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_NS_SEPARATOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_NUM_STRING' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_OBJECT_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_OBJECT_OPERATOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_ONUMBER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_OPEN_BRACKET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_OPEN_CURLY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_OPEN_SQUARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_OPEN_TAG' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_OPEN_TAG_WITH_ECHO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_OR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_PAAMAYIM_NEKUDOTAYIM' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_PERCENT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_PIPE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_PLUS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_PLUS_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_POW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_POW_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_PRINT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_PRIVATE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_PROTECTED' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_PUBLIC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_QUESTION_MARK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_REQUIRE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_REQUIRE_ONCE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_RETURN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_SEMICOLON' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_SHAPE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_SL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_SL_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_SPACESHIP' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_SR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_SR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_START_HEREDOC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_STATIC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_STRING' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_STRING_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_STRING_VARNAME' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_SWITCH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_Stream' => $vendorDir . '/phpunit/php-token-stream/src/Token/Stream.php',
|
||||
'PHP_Token_Stream_CachingFactory' => $vendorDir . '/phpunit/php-token-stream/src/Token/Stream/CachingFactory.php',
|
||||
'PHP_Token_THROW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_TILDE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_TRAIT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_TRAIT_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_TRY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_TYPE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_TYPELIST_GT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_TYPELIST_LT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_UNSET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_UNSET_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_USE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_VAR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_VARIABLE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_WHERE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_WHILE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_WHITESPACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_XHP_ATTRIBUTE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_XHP_CATEGORY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_XHP_CATEGORY_LABEL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_XHP_CHILDREN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_XHP_LABEL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_XHP_REQUIRED' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_XHP_TAG_GT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_XHP_TAG_LT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_XHP_TEXT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_XOR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_YIELD' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'PHP_Token_YIELD_FROM' => $vendorDir . '/phpunit/php-token-stream/src/Token.php',
|
||||
'SebastianBergmann\\Comparator\\ArrayComparator' => $vendorDir . '/sebastian/comparator/src/ArrayComparator.php',
|
||||
'SebastianBergmann\\Comparator\\Comparator' => $vendorDir . '/sebastian/comparator/src/Comparator.php',
|
||||
'SebastianBergmann\\Comparator\\ComparisonFailure' => $vendorDir . '/sebastian/comparator/src/ComparisonFailure.php',
|
||||
'SebastianBergmann\\Comparator\\DOMNodeComparator' => $vendorDir . '/sebastian/comparator/src/DOMNodeComparator.php',
|
||||
'SebastianBergmann\\Comparator\\DateTimeComparator' => $vendorDir . '/sebastian/comparator/src/DateTimeComparator.php',
|
||||
'SebastianBergmann\\Comparator\\DoubleComparator' => $vendorDir . '/sebastian/comparator/src/DoubleComparator.php',
|
||||
'SebastianBergmann\\Comparator\\ExceptionComparator' => $vendorDir . '/sebastian/comparator/src/ExceptionComparator.php',
|
||||
'SebastianBergmann\\Comparator\\Factory' => $vendorDir . '/sebastian/comparator/src/Factory.php',
|
||||
'SebastianBergmann\\Comparator\\MockObjectComparator' => $vendorDir . '/sebastian/comparator/src/MockObjectComparator.php',
|
||||
'SebastianBergmann\\Comparator\\NumericComparator' => $vendorDir . '/sebastian/comparator/src/NumericComparator.php',
|
||||
'SebastianBergmann\\Comparator\\ObjectComparator' => $vendorDir . '/sebastian/comparator/src/ObjectComparator.php',
|
||||
'SebastianBergmann\\Comparator\\ResourceComparator' => $vendorDir . '/sebastian/comparator/src/ResourceComparator.php',
|
||||
'SebastianBergmann\\Comparator\\ScalarComparator' => $vendorDir . '/sebastian/comparator/src/ScalarComparator.php',
|
||||
'SebastianBergmann\\Comparator\\SplObjectStorageComparator' => $vendorDir . '/sebastian/comparator/src/SplObjectStorageComparator.php',
|
||||
'SebastianBergmann\\Comparator\\TypeComparator' => $vendorDir . '/sebastian/comparator/src/TypeComparator.php',
|
||||
'SebastianBergmann\\Diff\\Chunk' => $vendorDir . '/sebastian/diff/src/Chunk.php',
|
||||
'SebastianBergmann\\Diff\\Diff' => $vendorDir . '/sebastian/diff/src/Diff.php',
|
||||
'SebastianBergmann\\Diff\\Differ' => $vendorDir . '/sebastian/diff/src/Differ.php',
|
||||
'SebastianBergmann\\Diff\\LCS\\LongestCommonSubsequence' => $vendorDir . '/sebastian/diff/src/LCS/LongestCommonSubsequence.php',
|
||||
'SebastianBergmann\\Diff\\LCS\\MemoryEfficientImplementation' => $vendorDir . '/sebastian/diff/src/LCS/MemoryEfficientLongestCommonSubsequenceImplementation.php',
|
||||
'SebastianBergmann\\Diff\\LCS\\TimeEfficientImplementation' => $vendorDir . '/sebastian/diff/src/LCS/TimeEfficientLongestCommonSubsequenceImplementation.php',
|
||||
'SebastianBergmann\\Diff\\Line' => $vendorDir . '/sebastian/diff/src/Line.php',
|
||||
'SebastianBergmann\\Diff\\Parser' => $vendorDir . '/sebastian/diff/src/Parser.php',
|
||||
'SebastianBergmann\\Environment\\Console' => $vendorDir . '/sebastian/environment/src/Console.php',
|
||||
'SebastianBergmann\\Environment\\Runtime' => $vendorDir . '/sebastian/environment/src/Runtime.php',
|
||||
'SebastianBergmann\\Exporter\\Exporter' => $vendorDir . '/sebastian/exporter/src/Exporter.php',
|
||||
'SebastianBergmann\\GlobalState\\Blacklist' => $vendorDir . '/sebastian/global-state/src/Blacklist.php',
|
||||
'SebastianBergmann\\GlobalState\\CodeExporter' => $vendorDir . '/sebastian/global-state/src/CodeExporter.php',
|
||||
'SebastianBergmann\\GlobalState\\Exception' => $vendorDir . '/sebastian/global-state/src/Exception.php',
|
||||
'SebastianBergmann\\GlobalState\\Restorer' => $vendorDir . '/sebastian/global-state/src/Restorer.php',
|
||||
'SebastianBergmann\\GlobalState\\RuntimeException' => $vendorDir . '/sebastian/global-state/src/RuntimeException.php',
|
||||
'SebastianBergmann\\GlobalState\\Snapshot' => $vendorDir . '/sebastian/global-state/src/Snapshot.php',
|
||||
'SebastianBergmann\\RecursionContext\\Context' => $vendorDir . '/sebastian/recursion-context/src/Context.php',
|
||||
'SebastianBergmann\\RecursionContext\\Exception' => $vendorDir . '/sebastian/recursion-context/src/Exception.php',
|
||||
'SebastianBergmann\\RecursionContext\\InvalidArgumentException' => $vendorDir . '/sebastian/recursion-context/src/InvalidArgumentException.php',
|
||||
'SebastianBergmann\\ResourceOperations\\ResourceOperations' => $vendorDir . '/sebastian/resource-operations/src/ResourceOperations.php',
|
||||
'SebastianBergmann\\Version' => $vendorDir . '/sebastian/version/src/Version.php',
|
||||
'Text_Template' => $vendorDir . '/phpunit/php-text-template/src/Template.php',
|
||||
);
|
|
@ -1,12 +0,0 @@
|
|||
<?php
|
||||
|
||||
// autoload_namespaces.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'phpDocumentor' => array($vendorDir . '/phpdocumentor/reflection-docblock/src'),
|
||||
'Slim' => array($vendorDir . '/slim/slim'),
|
||||
'Prophecy\\' => array($vendorDir . '/phpspec/prophecy/src'),
|
||||
);
|
|
@ -1,13 +0,0 @@
|
|||
<?php
|
||||
|
||||
// autoload_psr4.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'Symfony\\Component\\Yaml\\' => array($vendorDir . '/symfony/yaml'),
|
||||
'RedBeanPHP\\' => array($vendorDir . '/gabordemooij/redbean/RedBeanPHP'),
|
||||
'Doctrine\\Instantiator\\' => array($vendorDir . '/doctrine/instantiator/src/Doctrine/Instantiator'),
|
||||
'DeepCopy\\' => array($vendorDir . '/myclabs/deep-copy/src/DeepCopy'),
|
||||
);
|
|
@ -1,50 +0,0 @@
|
|||
<?php
|
||||
|
||||
// autoload_real.php @generated by Composer
|
||||
|
||||
class ComposerAutoloaderInitc1131bbfb8e9acff5fc8b79d0d7d1f64
|
||||
{
|
||||
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('ComposerAutoloaderInitc1131bbfb8e9acff5fc8b79d0d7d1f64', 'loadClassLoader'), true, true);
|
||||
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInitc1131bbfb8e9acff5fc8b79d0d7d1f64', 'loadClassLoader'));
|
||||
|
||||
$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);
|
||||
|
||||
return $loader;
|
||||
}
|
||||
}
|
||||
|
||||
function composerRequirec1131bbfb8e9acff5fc8b79d0d7d1f64($file)
|
||||
{
|
||||
require $file;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +0,0 @@
|
|||
phpunit.xml
|
||||
composer.lock
|
||||
build
|
||||
vendor
|
||||
coverage.clover
|
|
@ -1,46 +0,0 @@
|
|||
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
|
|
@ -1,14 +0,0 @@
|
|||
#!/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
|
|
@ -1,22 +0,0 @@
|
|||
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
|
|
@ -1,35 +0,0 @@
|
|||
# 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.
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
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.
|
|
@ -1,40 +0,0 @@
|
|||
# Instantiator
|
||||
|
||||
This library provides a way of avoiding usage of constructors when instantiating PHP classes.
|
||||
|
||||
[](https://travis-ci.org/doctrine/instantiator)
|
||||
[](https://scrutinizer-ci.com/g/doctrine/instantiator/?branch=master)
|
||||
[](https://scrutinizer-ci.com/g/doctrine/instantiator/?branch=master)
|
||||
[](https://www.versioneye.com/package/php--doctrine--instantiator)
|
||||
[](http://hhvm.h4cc.de/package/doctrine/instantiator)
|
||||
|
||||
[](https://packagist.org/packages/doctrine/instantiator)
|
||||
[](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.
|
|
@ -1,45 +0,0 @@
|
|||
{
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
<?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>
|
|
@ -1,22 +0,0 @@
|
|||
<?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>
|
|
@ -1,29 +0,0 @@
|
|||
<?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
|
||||
{
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
<?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()
|
||||
));
|
||||
}
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
<?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)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,273 +0,0 @@
|
|||
<?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');
|
||||
}
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
<?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);
|
||||
}
|
|
@ -1,96 +0,0 @@
|
|||
<?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');
|
||||
}
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
<?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()
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
<?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());
|
||||
}
|
||||
}
|
|
@ -1,219 +0,0 @@
|
|||
<?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;
|
||||
}
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
<?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
|
||||
{
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
<?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!');
|
||||
}
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
<?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!');
|
||||
}
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
<?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!');
|
||||
}
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
<?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!');
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
<?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!');
|
||||
}
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
<?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!');
|
||||
}
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
<?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!');
|
||||
}
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
<?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
|
||||
{
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
<?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!');
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
<?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();
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
<?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');
|
||||
}
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
<?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!');
|
||||
}
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
# Compiled source #
|
||||
###################
|
||||
*.com
|
||||
*.class
|
||||
*.dll
|
||||
*.exe
|
||||
*.o
|
||||
*.so
|
||||
*.pyc
|
||||
|
||||
# Logs and databases #
|
||||
######################
|
||||
*.log
|
||||
|
||||
# OS generated files #
|
||||
######################
|
||||
.DS_Store*
|
||||
ehthumbs.db
|
||||
Icon?
|
||||
Thumbs.db
|
||||
/.project
|
||||
/.settings/org.eclipse.php.core.prefs
|
||||
/.settings/org.eclipse.php.debug.core.Debug_Process_Preferences.prefs
|
||||
/rb.phar
|
||||
/rb.php
|
||||
build/
|
|
@ -1,20 +0,0 @@
|
|||
language: php
|
||||
php:
|
||||
- 5.3
|
||||
- 5.4
|
||||
- 5.5
|
||||
- 5.6
|
||||
- 7.0
|
||||
- hhvm
|
||||
|
||||
before_script:
|
||||
- touch /tmp/oodb.db
|
||||
- mysql -e 'create database oodb;'
|
||||
- psql template1 -c 'CREATE EXTENSION "uuid-ossp";' -U postgres
|
||||
- psql -c 'create database oodb;' -U postgres
|
||||
- php replica2.php onlyphp
|
||||
- cp rb.php testing/cli/testcontainer/rb.php
|
||||
- cd testing/cli
|
||||
|
||||
|
||||
script: php runtests.php
|
|
@ -1,48 +0,0 @@
|
|||
RedBeanPHP 4
|
||||
============
|
||||
|
||||

|
||||
|
||||
RedBeanPHP is an easy to use ORM tool for PHP.
|
||||
|
||||
* Automatically creates tables and columns as you go
|
||||
* No configuration, just fire and forget
|
||||
* No complicated package tools, no autoloaders, just ONE file
|
||||
|
||||
Installation via Composer
|
||||
-------------------------
|
||||
|
||||
Just open your composer.json file and add the package name ```(e.g. "gabordemooij/redbean": "dev-master")``` in your require list.
|
||||
|
||||
```json
|
||||
{
|
||||
"require": {
|
||||
"gabordemooij/redbean": "dev-master"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If you not using composer then [try it.](http://redbeanphp.com/install)
|
||||
|
||||
|
||||
Quick Example
|
||||
-------------
|
||||
|
||||
How we store a book object with RedBeanPHP:
|
||||
```php
|
||||
$book = R::dispense("book");
|
||||
$book->author = "Santa Claus";
|
||||
$book->title = "Secrets of Christmas";
|
||||
$id = R::store( $book );
|
||||
```
|
||||
|
||||
Yep, it's that simple.
|
||||
|
||||
|
||||
More information
|
||||
----------------
|
||||
|
||||
For more information about RedBeanPHP please consult
|
||||
the RedBeanPHP website:
|
||||
|
||||
http://www.redbeanphp.com/
|
|
@ -1,189 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RedBeanPHP;
|
||||
|
||||
/**
|
||||
* Adapter Interface.
|
||||
* Describes the API for a RedBeanPHP Database Adapter.
|
||||
* This interface defines the API contract for
|
||||
* a RedBeanPHP Database Adapter.
|
||||
*
|
||||
* @file RedBeanPHP/Adapter.php
|
||||
* @author Gabor de Mooij and the RedBeanPHP Community
|
||||
* @license BSD/GPLv2
|
||||
*
|
||||
* @copyright
|
||||
* (c) G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community.
|
||||
* This source file is subject to the BSD/GPLv2 License that is bundled
|
||||
* with this source code in the file license.txt.
|
||||
*/
|
||||
interface Adapter
|
||||
{
|
||||
/**
|
||||
* Returns the latest SQL statement.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSQL();
|
||||
|
||||
/**
|
||||
* Executes an SQL Statement using an array of values to bind
|
||||
* If $noevent is TRUE then this function will not signal its
|
||||
* observers to notify about the SQL execution; this to prevent
|
||||
* infinite recursion when using observers.
|
||||
*
|
||||
* @param string $sql string containing SQL code for database
|
||||
* @param array $bindings array of values to bind to parameters in query string
|
||||
* @param boolean $noevent no event firing
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function exec( $sql, $bindings = array(), $noevent = FALSE );
|
||||
|
||||
/**
|
||||
* Executes an SQL Query and returns a resultset.
|
||||
* This method returns a multi dimensional resultset similar to getAll
|
||||
* The values array can be used to bind values to the place holders in the
|
||||
* SQL query.
|
||||
*
|
||||
* @param string $sql string containing SQL code for database
|
||||
* @param array $bindings array of values to bind to parameters in query string
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get( $sql, $bindings = array() );
|
||||
|
||||
/**
|
||||
* Executes an SQL Query and returns a resultset.
|
||||
* This method returns a single row (one array) resultset.
|
||||
* The values array can be used to bind values to the place holders in the
|
||||
* SQL query.
|
||||
*
|
||||
* @param string $sql string containing SQL code for database
|
||||
* @param array $bindings array of values to bind to parameters in query string
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getRow( $sql, $bindings = array() );
|
||||
|
||||
/**
|
||||
* Executes an SQL Query and returns a resultset.
|
||||
* This method returns a single column (one array) resultset.
|
||||
* The values array can be used to bind values to the place holders in the
|
||||
* SQL query.
|
||||
*
|
||||
* @param string $sql string containing SQL code for database
|
||||
* @param array $bindings array of values to bind to parameters in query string
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getCol( $sql, $bindings = array() );
|
||||
|
||||
/**
|
||||
* Executes an SQL Query and returns a resultset.
|
||||
* This method returns a single cell, a scalar value as the resultset.
|
||||
* The values array can be used to bind values to the place holders in the
|
||||
* SQL query.
|
||||
*
|
||||
* @param string $sql string containing SQL code for database
|
||||
* @param array $bindings array of values to bind to parameters in query string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCell( $sql, $bindings = array() );
|
||||
|
||||
/**
|
||||
* Executes the SQL query specified in $sql and takes
|
||||
* the first two columns of the resultset. This function transforms the
|
||||
* resultset into an associative array. Values from the the first column will
|
||||
* serve as keys while the values of the second column will be used as values.
|
||||
* The values array can be used to bind values to the place holders in the
|
||||
* SQL query.
|
||||
*
|
||||
* @param string $sql string containing SQL code for database
|
||||
* @param array $bindings array of values to bind to parameters in query string
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAssoc( $sql, $bindings = array() );
|
||||
|
||||
/**
|
||||
* Executes the SQL query specified in $sql and indexes
|
||||
* the row by the first column.
|
||||
*
|
||||
* @param string $sql Sstring containing SQL code for databaseQL
|
||||
* @param array $bindings values to bind
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAssocRow( $sql, $bindings = array() );
|
||||
|
||||
/**
|
||||
* Returns the latest insert ID.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getInsertID();
|
||||
|
||||
/**
|
||||
* Returns the number of rows that have been
|
||||
* affected by the last update statement.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getAffectedRows();
|
||||
|
||||
/**
|
||||
* Returns a database agnostic Cursor object.
|
||||
*
|
||||
* @param string $sql string containing SQL code for database
|
||||
* @param array $bindings array of values to bind to parameters in query string
|
||||
*
|
||||
* @return Cursor
|
||||
*/
|
||||
public function getCursor( $sql, $bindings = array() );
|
||||
|
||||
/**
|
||||
* Returns the original database resource. This is useful if you want to
|
||||
* perform operations on the driver directly instead of working with the
|
||||
* adapter. RedBean will only access the adapter and never to talk
|
||||
* directly to the driver though.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getDatabase();
|
||||
|
||||
/**
|
||||
* This method is part of the RedBean Transaction Management
|
||||
* mechanisms.
|
||||
* Starts a transaction.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function startTransaction();
|
||||
|
||||
/**
|
||||
* This method is part of the RedBean Transaction Management
|
||||
* mechanisms.
|
||||
* Commits the transaction.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function commit();
|
||||
|
||||
/**
|
||||
* This method is part of the RedBean Transaction Management
|
||||
* mechanisms.
|
||||
* Rolls back the transaction.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function rollback();
|
||||
|
||||
/**
|
||||
* Closes database connection.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function close();
|
||||
}
|
|
@ -1,230 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RedBeanPHP\Adapter;
|
||||
|
||||
use RedBeanPHP\Observable as Observable;
|
||||
use RedBeanPHP\Adapter as Adapter;
|
||||
use RedBeanPHP\Driver as Driver;
|
||||
|
||||
/**
|
||||
* DBAdapter (Database Adapter)
|
||||
*
|
||||
* An adapter class to connect various database systems to RedBean
|
||||
* Database Adapter Class. The task of the database adapter class is to
|
||||
* communicate with the database driver. You can use all sorts of database
|
||||
* drivers with RedBeanPHP. The default database drivers that ships with
|
||||
* the RedBeanPHP library is the RPDO driver ( which uses the PHP Data Objects
|
||||
* Architecture aka PDO ).
|
||||
*
|
||||
* @file RedBeanPHP/Adapter/DBAdapter.php
|
||||
* @author Gabor de Mooij and the RedBeanPHP Community.
|
||||
* @license BSD/GPLv2
|
||||
*
|
||||
* @copyright
|
||||
* (c) copyright G.J.G.T. (Gabor) de Mooij and the RedBeanPHP community.
|
||||
* This source file is subject to the BSD/GPLv2 License that is bundled
|
||||
* with this source code in the file license.txt.
|
||||
*/
|
||||
class DBAdapter extends Observable implements Adapter
|
||||
{
|
||||
/**
|
||||
* @var Driver
|
||||
*/
|
||||
private $db = NULL;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sql = '';
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Creates an instance of the RedBean Adapter Class.
|
||||
* This class provides an interface for RedBean to work
|
||||
* with ADO compatible DB instances.
|
||||
*
|
||||
* @param Driver $database ADO Compatible DB Instance
|
||||
*/
|
||||
public function __construct( $database )
|
||||
{
|
||||
$this->db = $database;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Adapter::getSQL
|
||||
*/
|
||||
public function getSQL()
|
||||
{
|
||||
return $this->sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Adapter::exec
|
||||
*/
|
||||
public function exec( $sql, $bindings = array(), $noevent = FALSE )
|
||||
{
|
||||
if ( !$noevent ) {
|
||||
$this->sql = $sql;
|
||||
$this->signal( 'sql_exec', $this );
|
||||
}
|
||||
|
||||
return $this->db->Execute( $sql, $bindings );
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Adapter::get
|
||||
*/
|
||||
public function get( $sql, $bindings = array() )
|
||||
{
|
||||
$this->sql = $sql;
|
||||
$this->signal( 'sql_exec', $this );
|
||||
|
||||
return $this->db->GetAll( $sql, $bindings );
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Adapter::getRow
|
||||
*/
|
||||
public function getRow( $sql, $bindings = array() )
|
||||
{
|
||||
$this->sql = $sql;
|
||||
$this->signal( 'sql_exec', $this );
|
||||
|
||||
return $this->db->GetRow( $sql, $bindings );
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Adapter::getCol
|
||||
*/
|
||||
public function getCol( $sql, $bindings = array() )
|
||||
{
|
||||
$this->sql = $sql;
|
||||
$this->signal( 'sql_exec', $this );
|
||||
|
||||
return $this->db->GetCol( $sql, $bindings );
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Adapter::getAssoc
|
||||
*/
|
||||
public function getAssoc( $sql, $bindings = array() )
|
||||
{
|
||||
$this->sql = $sql;
|
||||
|
||||
$this->signal( 'sql_exec', $this );
|
||||
|
||||
$rows = $this->db->GetAll( $sql, $bindings );
|
||||
|
||||
$assoc = array();
|
||||
if ( !$rows ) {
|
||||
return $assoc;
|
||||
}
|
||||
|
||||
foreach ( $rows as $row ) {
|
||||
if ( empty( $row ) ) continue;
|
||||
|
||||
if ( count( $row ) > 2 ) {
|
||||
$key = array_shift( $row );
|
||||
$value = $row;
|
||||
} elseif ( count( $row ) > 1 ) {
|
||||
$key = array_shift( $row );
|
||||
$value = array_shift( $row );
|
||||
} else {
|
||||
$key = array_shift( $row );
|
||||
$value = $key;
|
||||
}
|
||||
|
||||
$assoc[$key] = $value;
|
||||
}
|
||||
|
||||
return $assoc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Adapter::getAssocRow
|
||||
*/
|
||||
public function getAssocRow($sql, $bindings = array())
|
||||
{
|
||||
$this->sql = $sql;
|
||||
$this->signal( 'sql_exec', $this );
|
||||
|
||||
return $this->db->GetAssocRow( $sql, $bindings );
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Adapter::getCell
|
||||
*/
|
||||
public function getCell( $sql, $bindings = array(), $noSignal = NULL )
|
||||
{
|
||||
$this->sql = $sql;
|
||||
|
||||
if ( !$noSignal ) $this->signal( 'sql_exec', $this );
|
||||
|
||||
return $this->db->GetOne( $sql, $bindings );
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Adapter::getCursor
|
||||
*/
|
||||
public function getCursor( $sql, $bindings = array() )
|
||||
{
|
||||
return $this->db->GetCursor( $sql, $bindings );
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Adapter::getInsertID
|
||||
*/
|
||||
public function getInsertID()
|
||||
{
|
||||
return $this->db->getInsertID();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Adapter::getAffectedRows
|
||||
*/
|
||||
public function getAffectedRows()
|
||||
{
|
||||
return $this->db->Affected_Rows();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Adapter::getDatabase
|
||||
*/
|
||||
public function getDatabase()
|
||||
{
|
||||
return $this->db;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Adapter::startTransaction
|
||||
*/
|
||||
public function startTransaction()
|
||||
{
|
||||
$this->db->StartTrans();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Adapter::commit
|
||||
*/
|
||||
public function commit()
|
||||
{
|
||||
$this->db->CommitTrans();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Adapter::rollback
|
||||
*/
|
||||
public function rollback()
|
||||
{
|
||||
$this->db->FailTrans();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Adapter::close.
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
$this->db->close();
|
||||
}
|
||||
}
|
|
@ -1,341 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RedBeanPHP;
|
||||
|
||||
use RedBeanPHP\Adapter\DBAdapter as DBAdapter;
|
||||
use RedBeanPHP\QueryWriter as QueryWriter;
|
||||
use RedBeanPHP\RedException as RedException;
|
||||
use RedBeanPHP\RedException\SQL as SQLException;
|
||||
|
||||
/**
|
||||
* Association Manager.
|
||||
* Manages simple bean associations.
|
||||
*
|
||||
* @file RedBeanPHP/AssociationManager.php
|
||||
* @author Gabor de Mooij and the RedBeanPHP Community
|
||||
* @license BSD/GPLv2
|
||||
*
|
||||
* @copyright
|
||||
* (c) G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community.
|
||||
* This source file is subject to the BSD/GPLv2 License that is bundled
|
||||
* with this source code in the file license.txt.
|
||||
*/
|
||||
class AssociationManager extends Observable
|
||||
{
|
||||
/**
|
||||
* @var OODB
|
||||
*/
|
||||
protected $oodb;
|
||||
|
||||
/**
|
||||
* @var DBAdapter
|
||||
*/
|
||||
protected $adapter;
|
||||
|
||||
/**
|
||||
* @var QueryWriter
|
||||
*/
|
||||
protected $writer;
|
||||
|
||||
/**
|
||||
* Handles exceptions. Suppresses exceptions caused by missing structures.
|
||||
*
|
||||
* @param Exception $exception exception to handle
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function handleException( \Exception $exception )
|
||||
{
|
||||
if ( $this->oodb->isFrozen() || !$this->writer->sqlStateIn( $exception->getSQLState(),
|
||||
array(
|
||||
QueryWriter::C_SQLSTATE_NO_SUCH_TABLE,
|
||||
QueryWriter::C_SQLSTATE_NO_SUCH_COLUMN )
|
||||
)
|
||||
) {
|
||||
throw $exception;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method.
|
||||
* Returns the many-to-many related rows of table $type for bean $bean using additional SQL in $sql and
|
||||
* $bindings bindings. If $getLinks is TRUE, link rows are returned instead.
|
||||
*
|
||||
* @param OODBBean $bean reference bean instance
|
||||
* @param string $type target bean type
|
||||
* @param string $sql additional SQL snippet
|
||||
* @param array $bindings bindings for query
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function relatedRows( $bean, $type, $sql = '', $bindings = array() )
|
||||
{
|
||||
$ids = array( $bean->id );
|
||||
$sourceType = $bean->getMeta( 'type' );
|
||||
try {
|
||||
return $this->writer->queryRecordRelated( $sourceType, $type, $ids, $sql, $bindings );
|
||||
} catch ( SQLException $exception ) {
|
||||
$this->handleException( $exception );
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Associates a pair of beans. This method associates two beans, no matter
|
||||
* what types. Accepts a base bean that contains data for the linking record.
|
||||
* This method is used by associate. This method also accepts a base bean to be used
|
||||
* as the template for the link record in the database.
|
||||
*
|
||||
* @param OODBBean $bean1 first bean
|
||||
* @param OODBBean $bean2 second bean
|
||||
* @param OODBBean $bean base bean (association record)
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
protected function associateBeans( OODBBean $bean1, OODBBean $bean2, OODBBean $bean )
|
||||
{
|
||||
$type = $bean->getMeta( 'type' );
|
||||
$property1 = $bean1->getMeta( 'type' ) . '_id';
|
||||
$property2 = $bean2->getMeta( 'type' ) . '_id';
|
||||
|
||||
if ( $property1 == $property2 ) {
|
||||
$property2 = $bean2->getMeta( 'type' ) . '2_id';
|
||||
}
|
||||
|
||||
$this->oodb->store( $bean1 );
|
||||
$this->oodb->store( $bean2 );
|
||||
|
||||
$bean->setMeta( "cast.$property1", "id" );
|
||||
$bean->setMeta( "cast.$property2", "id" );
|
||||
$bean->setMeta( 'sys.buildcommand.unique', array( $property1, $property2 ) );
|
||||
|
||||
$bean->$property1 = $bean1->id;
|
||||
$bean->$property2 = $bean2->id;
|
||||
|
||||
$results = array();
|
||||
|
||||
try {
|
||||
$id = $this->oodb->store( $bean );
|
||||
$results[] = $id;
|
||||
} catch ( SQLException $exception ) {
|
||||
if ( !$this->writer->sqlStateIn( $exception->getSQLState(),
|
||||
array( QueryWriter::C_SQLSTATE_INTEGRITY_CONSTRAINT_VIOLATION ) )
|
||||
) {
|
||||
throw $exception;
|
||||
}
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param ToolBox $tools toolbox
|
||||
*/
|
||||
public function __construct( ToolBox $tools )
|
||||
{
|
||||
$this->oodb = $tools->getRedBean();
|
||||
$this->adapter = $tools->getDatabaseAdapter();
|
||||
$this->writer = $tools->getWriter();
|
||||
$this->toolbox = $tools;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a table name based on a types array.
|
||||
* Manages the get the correct name for the linking table for the
|
||||
* types provided.
|
||||
*
|
||||
* @todo find a nice way to decouple this class from QueryWriter?
|
||||
*
|
||||
* @param array $types 2 types as strings
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTable( $types )
|
||||
{
|
||||
return $this->writer->getAssocTable( $types );
|
||||
}
|
||||
|
||||
/**
|
||||
* Associates two beans in a many-to-many relation.
|
||||
* This method will associate two beans and store the connection between the
|
||||
* two in a link table. Instead of two single beans this method also accepts
|
||||
* two sets of beans. Returns the ID or the IDs of the linking beans.
|
||||
*
|
||||
* @param OODBBean|array $beans1 one or more beans to form the association
|
||||
* @param OODBBean|array $beans2 one or more beans to form the association
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function associate( $beans1, $beans2 )
|
||||
{
|
||||
if ( !is_array( $beans1 ) ) {
|
||||
$beans1 = array( $beans1 );
|
||||
}
|
||||
|
||||
if ( !is_array( $beans2 ) ) {
|
||||
$beans2 = array( $beans2 );
|
||||
}
|
||||
|
||||
$results = array();
|
||||
foreach ( $beans1 as $bean1 ) {
|
||||
foreach ( $beans2 as $bean2 ) {
|
||||
$table = $this->getTable( array( $bean1->getMeta( 'type' ), $bean2->getMeta( 'type' ) ) );
|
||||
$bean = $this->oodb->dispense( $table );
|
||||
$results[] = $this->associateBeans( $bean1, $bean2, $bean );
|
||||
}
|
||||
}
|
||||
|
||||
return ( count( $results ) > 1 ) ? $results : reset( $results );
|
||||
}
|
||||
|
||||
/**
|
||||
* Counts the number of related beans in an N-M relation.
|
||||
* This method returns the number of beans of type $type associated
|
||||
* with reference bean(s) $bean. The query can be tuned using an
|
||||
* SQL snippet for additional filtering.
|
||||
*
|
||||
* @param OODBBean|array $bean a bean object or an array of beans
|
||||
* @param string $type type of bean you're interested in
|
||||
* @param string $sql SQL snippet (optional)
|
||||
* @param array $bindings bindings for your SQL string
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function relatedCount( $bean, $type, $sql = NULL, $bindings = array() )
|
||||
{
|
||||
if ( !( $bean instanceof OODBBean ) ) {
|
||||
throw new RedException(
|
||||
'Expected array or OODBBean but got:' . gettype( $bean )
|
||||
);
|
||||
}
|
||||
|
||||
if ( !$bean->id ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$beanType = $bean->getMeta( 'type' );
|
||||
|
||||
try {
|
||||
return $this->writer->queryRecordCountRelated( $beanType, $type, $bean->id, $sql, $bindings );
|
||||
} catch ( SQLException $exception ) {
|
||||
$this->handleException( $exception );
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Breaks the association between two beans. This method unassociates two beans. If the
|
||||
* method succeeds the beans will no longer form an association. In the database
|
||||
* this means that the association record will be removed. This method uses the
|
||||
* OODB trash() method to remove the association links, thus giving FUSE models the
|
||||
* opportunity to hook-in additional business logic. If the $fast parameter is
|
||||
* set to boolean TRUE this method will remove the beans without their consent,
|
||||
* bypassing FUSE. This can be used to improve performance.
|
||||
*
|
||||
* @param OODBBean $bean1 first bean in target association
|
||||
* @param OODBBean $bean2 second bean in target association
|
||||
* @param boolean $fast if TRUE, removes the entries by query without FUSE
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function unassociate( $beans1, $beans2, $fast = NULL )
|
||||
{
|
||||
$beans1 = ( !is_array( $beans1 ) ) ? array( $beans1 ) : $beans1;
|
||||
$beans2 = ( !is_array( $beans2 ) ) ? array( $beans2 ) : $beans2;
|
||||
|
||||
foreach ( $beans1 as $bean1 ) {
|
||||
foreach ( $beans2 as $bean2 ) {
|
||||
try {
|
||||
$this->oodb->store( $bean1 );
|
||||
$this->oodb->store( $bean2 );
|
||||
|
||||
$type1 = $bean1->getMeta( 'type' );
|
||||
$type2 = $bean2->getMeta( 'type' );
|
||||
|
||||
$row = $this->writer->queryRecordLink( $type1, $type2, $bean1->id, $bean2->id );
|
||||
$linkType = $this->getTable( array( $type1, $type2 ) );
|
||||
|
||||
if ( $fast ) {
|
||||
$this->writer->deleteRecord( $linkType, array( 'id' => $row['id'] ) );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$beans = $this->oodb->convertToBeans( $linkType, array( $row ) );
|
||||
|
||||
if ( count( $beans ) > 0 ) {
|
||||
$bean = reset( $beans );
|
||||
$this->oodb->trash( $bean );
|
||||
}
|
||||
} catch ( SQLException $exception ) {
|
||||
$this->handleException( $exception );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all relations for a bean. This method breaks every connection between
|
||||
* a certain bean $bean and every other bean of type $type. Warning: this method
|
||||
* is really fast because it uses a direct SQL query however it does not inform the
|
||||
* models about this. If you want to notify FUSE models about deletion use a foreach-loop
|
||||
* with unassociate() instead. (that might be slower though)
|
||||
*
|
||||
* @param OODBBean $bean reference bean
|
||||
* @param string $type type of beans that need to be unassociated
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function clearRelations( OODBBean $bean, $type )
|
||||
{
|
||||
$this->oodb->store( $bean );
|
||||
try {
|
||||
$this->writer->deleteRelations( $bean->getMeta( 'type' ), $type, $bean->id );
|
||||
} catch ( SQLException $exception ) {
|
||||
$this->handleException( $exception );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the beans associated with $bean.
|
||||
* This method will return an array containing all the beans that have
|
||||
* been associated once with the associate() function and are still
|
||||
* associated with the bean specified. The type parameter indicates the
|
||||
* type of beans you are looking for. You can also pass some extra SQL and
|
||||
* values for that SQL to filter your results after fetching the
|
||||
* related beans.
|
||||
*
|
||||
* Don't try to make use of subqueries, a subquery using IN() seems to
|
||||
* be slower than two queries!
|
||||
*
|
||||
* Since 3.2, you can now also pass an array of beans instead just one
|
||||
* bean as the first parameter.
|
||||
*
|
||||
* @param OODBBean|array $bean the bean you have
|
||||
* @param string $type the type of beans you want
|
||||
* @param string $sql SQL snippet for extra filtering
|
||||
* @param array $bindings values to be inserted in SQL slots
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function related( $bean, $type, $sql = '', $bindings = array() )
|
||||
{
|
||||
$sql = $this->writer->glueSQLCondition( $sql );
|
||||
$rows = $this->relatedRows( $bean, $type, $sql, $bindings );
|
||||
$links = array();
|
||||
|
||||
foreach ( $rows as $key => $row ) {
|
||||
if ( !isset( $links[$row['id']] ) ) $links[$row['id']] = array();
|
||||
$links[$row['id']][] = $row['linked_by'];
|
||||
unset( $rows[$key]['linked_by'] );
|
||||
}
|
||||
|
||||
$beans = $this->oodb->convertToBeans( $type, $rows );
|
||||
foreach ( $beans as $bean ) $bean->setMeta( 'sys.belongs-to', $links[$bean->id] );
|
||||
|
||||
return $beans;
|
||||
}
|
||||
}
|
|
@ -1,92 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RedBeanPHP;
|
||||
|
||||
use RedBeanPHP\Cursor as Cursor;
|
||||
use RedBeanPHP\Repository as Repository;
|
||||
|
||||
/**
|
||||
* BeanCollection.
|
||||
*
|
||||
* The BeanCollection represents a collection of beans and
|
||||
* makes it possible to use database cursors. The BeanCollection
|
||||
* has a method next() to obtain the first, next and last bean
|
||||
* in the collection. The BeanCollection does not implement the array
|
||||
* interface nor does it try to act like an array because it cannot go
|
||||
* backward or rewind itself.
|
||||
*
|
||||
* Use the BeanCollection for large datasets where skip/limit is not an
|
||||
* option. Keep in mind that ID-marking (querying a start ID) is a decent
|
||||
* alternative though.
|
||||
*
|
||||
* @file RedBeanPHP/BeanCollection.php
|
||||
* @author Gabor de Mooij and the RedBeanPHP community
|
||||
* @license BSD/GPLv2
|
||||
*
|
||||
* @copyright
|
||||
* copyright (c) G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community
|
||||
* This source file is subject to the BSD/GPLv2 License that is bundled
|
||||
* with this source code in the file license.txt.
|
||||
*/
|
||||
class BeanCollection
|
||||
{
|
||||
/**
|
||||
* @var Cursor
|
||||
*/
|
||||
protected $cursor = NULL;
|
||||
|
||||
/**
|
||||
* @var Repository
|
||||
*/
|
||||
protected $repository = NULL;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $type = NULL;
|
||||
|
||||
/**
|
||||
* Constructor, creates a new instance of the BeanCollection.
|
||||
*
|
||||
* @param string $type type of beans in this collection
|
||||
* @param Repository $repository repository to use to generate bean objects
|
||||
* @param Cursor $cursor cursor object to use
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct( $type, Repository $repository, Cursor $cursor )
|
||||
{
|
||||
$this->type = $type;
|
||||
$this->cursor = $cursor;
|
||||
$this->repository = $repository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next bean in the collection.
|
||||
* If called the first time, this will return the first bean in the collection.
|
||||
* If there are no more beans left in the collection, this method
|
||||
* will return NULL.
|
||||
*
|
||||
* @return OODBBean|NULL
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
$row = $this->cursor->getNextItem();
|
||||
if ( $row ) {
|
||||
$beans = $this->repository->convertToBeans( $this->type, array( $row ) );
|
||||
$bean = array_shift( $beans );
|
||||
return $bean;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the underlying cursor (needed for some databases).
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
$this->cursor->close();
|
||||
}
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RedBeanPHP;
|
||||
|
||||
use RedBeanPHP\ToolBox as ToolBox;
|
||||
use RedBeanPHP\OODBBean as OODBBean;
|
||||
|
||||
/**
|
||||
* Bean Helper Interface.
|
||||
*
|
||||
* Interface for Bean Helper.
|
||||
* A little bolt that glues the whole machinery together.
|
||||
*
|
||||
* @file RedBeanPHP/IBeanHelper.php
|
||||
* @author Gabor de Mooij and the RedBeanPHP Community
|
||||
* @license BSD/GPLv2
|
||||
*
|
||||
* @copyright
|
||||
* copyright (c) G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community
|
||||
* This source file is subject to the BSD/GPLv2 License that is bundled
|
||||
* with this source code in the file license.txt.
|
||||
*/
|
||||
interface BeanHelper
|
||||
{
|
||||
/**
|
||||
* Returns a toolbox to empower the bean.
|
||||
* This allows beans to perform OODB operations by themselves,
|
||||
* as such the bean is a proxy for OODB. This allows beans to implement
|
||||
* their magic getters and setters and return lists.
|
||||
*
|
||||
* @return ToolBox
|
||||
*/
|
||||
public function getToolbox();
|
||||
|
||||
/**
|
||||
* Does approximately the same as getToolbox but also extracts the
|
||||
* toolbox for you.
|
||||
* This method returns a list with all toolbox items in Toolbox Constructor order:
|
||||
* OODB, adapter, writer and finally the toolbox itself!.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getExtractedToolbox();
|
||||
|
||||
/**
|
||||
* Given a certain bean this method will
|
||||
* return the corresponding model.
|
||||
*
|
||||
* @param OODBBean $bean bean to obtain the corresponding model of
|
||||
*
|
||||
* @return SimpleModel|CustomModel
|
||||
*/
|
||||
public function getModelForBean( OODBBean $bean );
|
||||
}
|
|
@ -1,115 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RedBeanPHP\BeanHelper;
|
||||
|
||||
use RedBeanPHP\BeanHelper as BeanHelper;
|
||||
use RedBeanPHP\Facade as Facade;
|
||||
use RedBeanPHP\OODBBean as OODBBean;
|
||||
use RedBeanPHP\SimpleModelHelper as SimpleModelHelper;
|
||||
|
||||
/**
|
||||
* Bean Helper.
|
||||
*
|
||||
* The Bean helper helps beans to access access the toolbox and
|
||||
* FUSE models. This Bean Helper makes use of the facade to obtain a
|
||||
* reference to the toolbox.
|
||||
*
|
||||
* @file RedBeanPHP/BeanHelperFacade.php
|
||||
* @author Gabor de Mooij and the RedBeanPHP Community
|
||||
* @license BSD/GPLv2
|
||||
*
|
||||
* @copyright
|
||||
* (c) copyright G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community
|
||||
* This source file is subject to the BSD/GPLv2 License that is bundled
|
||||
* with this source code in the file license.txt.
|
||||
*/
|
||||
class SimpleFacadeBeanHelper implements BeanHelper
|
||||
{
|
||||
/**
|
||||
* Factory function to create instance of Simple Model, if any.
|
||||
*
|
||||
* @var closure
|
||||
*/
|
||||
private static $factory = null;
|
||||
|
||||
/**
|
||||
* Factory method using a customizable factory function to create
|
||||
* the instance of the Simple Model.
|
||||
*
|
||||
* @param string $modelClassName name of the class
|
||||
*
|
||||
* @return SimpleModel
|
||||
*/
|
||||
public static function factory( $modelClassName )
|
||||
{
|
||||
$factory = self::$factory;
|
||||
return ( $factory ) ? $factory( $modelClassName ) : new $modelClassName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the factory function to create the model when using FUSE
|
||||
* to connect a bean to a model.
|
||||
*
|
||||
* @param closure $factory factory function
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function setFactoryFunction( $factory )
|
||||
{
|
||||
self::$factory = $factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see BeanHelper::getToolbox
|
||||
*/
|
||||
public function getToolbox()
|
||||
{
|
||||
return Facade::getToolBox();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see BeanHelper::getModelForBean
|
||||
*/
|
||||
public function getModelForBean( OODBBean $bean )
|
||||
{
|
||||
$model = $bean->getMeta( 'type' );
|
||||
$prefix = defined( 'REDBEAN_MODEL_PREFIX' ) ? REDBEAN_MODEL_PREFIX : '\\Model_';
|
||||
|
||||
if ( strpos( $model, '_' ) !== FALSE ) {
|
||||
$modelParts = explode( '_', $model );
|
||||
$modelName = '';
|
||||
foreach( $modelParts as $part ) {
|
||||
$modelName .= ucfirst( $part );
|
||||
}
|
||||
$modelName = $prefix . $modelName;
|
||||
|
||||
if ( !class_exists( $modelName ) ) {
|
||||
//second try
|
||||
$modelName = $prefix . ucfirst( $model );
|
||||
|
||||
if ( !class_exists( $modelName ) ) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
$modelName = $prefix . ucfirst( $model );
|
||||
if ( !class_exists( $modelName ) ) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
$obj = self::factory( $modelName );
|
||||
$obj->loadBean( $bean );
|
||||
|
||||
return $obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see BeanHelper::getExtractedToolbox
|
||||
*/
|
||||
public function getExtractedToolbox()
|
||||
{
|
||||
return Facade::getExtractedToolbox();
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RedBeanPHP;
|
||||
|
||||
/**
|
||||
* Database Cursor Interface.
|
||||
* Represents a simple database cursor.
|
||||
* Cursors make it possible to create lightweight BeanCollections.
|
||||
*
|
||||
* @file RedBeanPHP/Cursor.php
|
||||
* @author Gabor de Mooij and the RedBeanPHP Community
|
||||
* @license BSD/GPLv2
|
||||
*
|
||||
* @copyright
|
||||
* copyright (c) G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community
|
||||
* This source file is subject to the BSD/GPLv2 License that is bundled
|
||||
* with this source code in the file license.txt.
|
||||
*/
|
||||
interface Cursor
|
||||
{
|
||||
/**
|
||||
* Retrieves the next row from the result set.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getNextItem();
|
||||
|
||||
/**
|
||||
* Closes the database cursor.
|
||||
* Some databases require a cursor to be closed before executing
|
||||
* another statement/opening a new cursor.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function close();
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RedBeanPHP\Cursor;
|
||||
|
||||
use RedBeanPHP\Cursor as Cursor;
|
||||
|
||||
/**
|
||||
* NULL Database Cursor
|
||||
* Implementation of the NULL Cursor.
|
||||
* Used for an empty BeanCollection.
|
||||
*
|
||||
* @file RedBeanPHP/Cursor/NULLCursor.php
|
||||
* @author Gabor de Mooij and the RedBeanPHP Community
|
||||
* @license BSD/GPLv2
|
||||
*
|
||||
* @copyright
|
||||
* (c) G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community.
|
||||
* This source file is subject to the BSD/GPLv2 License that is bundled
|
||||
* with this source code in the file license.txt.
|
||||
*/
|
||||
class NullCursor implements Cursor
|
||||
{
|
||||
/**
|
||||
* @see Cursor::getNextItem
|
||||
*/
|
||||
public function getNextItem()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Cursor::close
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RedBeanPHP\Cursor;
|
||||
|
||||
use RedBeanPHP\Cursor as Cursor;
|
||||
|
||||
/**
|
||||
* PDO Database Cursor
|
||||
* Implementation of PDO Database Cursor.
|
||||
* Used by the BeanCollection to fetch one bean at a time.
|
||||
*
|
||||
* @file RedBeanPHP/Cursor/PDOCursor.php
|
||||
* @author Gabor de Mooij and the RedBeanPHP Community
|
||||
* @license BSD/GPLv2
|
||||
*
|
||||
* @copyright
|
||||
* (c) G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community.
|
||||
* This source file is subject to the BSD/GPLv2 License that is bundled
|
||||
* with this source code in the file license.txt.
|
||||
*/
|
||||
class PDOCursor implements Cursor
|
||||
{
|
||||
/**
|
||||
* @var PDOStatement
|
||||
*/
|
||||
protected $res;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $fetchStyle;
|
||||
|
||||
/**
|
||||
* Constructor, creates a new instance of a PDO Database Cursor.
|
||||
*
|
||||
* @param PDOStatement $res the PDO statement
|
||||
* @param string $fetchStyle fetch style constant to use
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct( \PDOStatement $res, $fetchStyle )
|
||||
{
|
||||
$this->res = $res;
|
||||
$this->fetchStyle = $fetchStyle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Cursor::getNextItem
|
||||
*/
|
||||
public function getNextItem()
|
||||
{
|
||||
return $this->res->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Cursor::close
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
$this->res->closeCursor();
|
||||
}
|
||||
}
|
|
@ -1,164 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RedBeanPHP;
|
||||
|
||||
/**
|
||||
* Interface for database drivers.
|
||||
* The Driver API conforms to the ADODB pseudo standard
|
||||
* for database drivers.
|
||||
*
|
||||
* @file RedBeanPHP/Driver.php
|
||||
* @author Gabor de Mooij and the RedBeanPHP Community
|
||||
* @license BSD/GPLv2
|
||||
*
|
||||
* @copyright
|
||||
* copyright (c) G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community
|
||||
* This source file is subject to the BSD/GPLv2 License that is bundled
|
||||
* with this source code in the file license.txt.
|
||||
*/
|
||||
interface Driver
|
||||
{
|
||||
/**
|
||||
* Runs a query and fetches results as a multi dimensional array.
|
||||
*
|
||||
* @param string $sql SQL query to execute
|
||||
* @param array $bindings list of values to bind to SQL snippet
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetAll( $sql, $bindings = array() );
|
||||
|
||||
/**
|
||||
* Runs a query and fetches results as a column.
|
||||
*
|
||||
* @param string $sql SQL query to execute
|
||||
* @param array $bindings list of values to bind to SQL snippet
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetCol( $sql, $bindings = array() );
|
||||
|
||||
/**
|
||||
* Runs a query and returns results as a single cell.
|
||||
*
|
||||
* @param string $sql SQL query to execute
|
||||
* @param array $bindings list of values to bind to SQL snippet
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function GetOne( $sql, $bindings = array() );
|
||||
|
||||
/**
|
||||
* Runs a query and returns results as an associative array
|
||||
* indexed by the first column.
|
||||
*
|
||||
* @param string $sql SQL query to execute
|
||||
* @param array $bindings list of values to bind to SQL snippet
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function GetAssocRow( $sql, $bindings = array() );
|
||||
|
||||
/**
|
||||
* Runs a query and returns a flat array containing the values of
|
||||
* one row.
|
||||
*
|
||||
* @param string $sql SQL query to execute
|
||||
* @param array $bindings list of values to bind to SQL snippet
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetRow( $sql, $bindings = array() );
|
||||
|
||||
/**
|
||||
* Executes SQL code and allows key-value binding.
|
||||
* This function allows you to provide an array with values to bind
|
||||
* to query parameters. For instance you can bind values to question
|
||||
* marks in the query. Each value in the array corresponds to the
|
||||
* question mark in the query that matches the position of the value in the
|
||||
* array. You can also bind values using explicit keys, for instance
|
||||
* array(":key"=>123) will bind the integer 123 to the key :key in the
|
||||
* SQL. This method has no return value.
|
||||
*
|
||||
* @param string $sql SQL query to execute
|
||||
* @param array $bindings list of values to bind to SQL snippet
|
||||
*
|
||||
* @return array Affected Rows
|
||||
*/
|
||||
public function Execute( $sql, $bindings = array() );
|
||||
|
||||
/**
|
||||
* Returns the latest insert ID if driver does support this
|
||||
* feature.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function GetInsertID();
|
||||
|
||||
/**
|
||||
* Returns the number of rows affected by the most recent query
|
||||
* if the currently selected driver driver supports this feature.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function Affected_Rows();
|
||||
|
||||
/**
|
||||
* Returns a cursor-like object from the database.
|
||||
*
|
||||
* @param string $sql SQL query to execute
|
||||
* @param array $bindings list of values to bind to SQL snippet
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function GetCursor( $sql, $bindings = array() );
|
||||
|
||||
/**
|
||||
* Toggles debug mode. In debug mode the driver will print all
|
||||
* SQL to the screen together with some information about the
|
||||
* results. All SQL code that passes through the driver will be
|
||||
* passes on to the screen for inspection.
|
||||
* This method has no return value.
|
||||
*
|
||||
* @param boolean $tf TRUE = debug mode ON
|
||||
* @param Logger $customLogger
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setDebugMode( $tf, $customLogger );
|
||||
|
||||
/**
|
||||
* Starts a transaction.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function CommitTrans();
|
||||
|
||||
/**
|
||||
* Commits a transaction.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function StartTrans();
|
||||
|
||||
/**
|
||||
* Rolls back a transaction.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function FailTrans();
|
||||
|
||||
/**
|
||||
* Resets the internal Query Counter.
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function resetCounter();
|
||||
|
||||
/**
|
||||
* Returns the number of SQL queries processed.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getQueryCount();
|
||||
}
|
|
@ -1,621 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RedBeanPHP\Driver;
|
||||
|
||||
use RedBeanPHP\Driver as Driver;
|
||||
use RedBeanPHP\Logger as Logger;
|
||||
use RedBeanPHP\QueryWriter\AQueryWriter as AQueryWriter;
|
||||
use RedBeanPHP\RedException as RedException;
|
||||
use RedBeanPHP\RedException\SQL as SQL;
|
||||
use RedBeanPHP\Logger\RDefault as RDefault;
|
||||
use RedBeanPHP\PDOCompatible as PDOCompatible;
|
||||
use RedBeanPHP\Cursor\PDOCursor as PDOCursor;
|
||||
|
||||
/**
|
||||
* PDO Driver
|
||||
* This Driver implements the RedBean Driver API.
|
||||
* for RedBeanPHP. This is the standard / default database driver
|
||||
* for RedBeanPHP.
|
||||
*
|
||||
* @file RedBeanPHP/PDO.php
|
||||
* @author Gabor de Mooij and the RedBeanPHP Community, Desfrenes
|
||||
* @license BSD/GPLv2
|
||||
*
|
||||
* @copyright
|
||||
* copyright (c) Desfrenes & Gabor de Mooij and the RedBeanPHP community
|
||||
* This source file is subject to the BSD/GPLv2 License that is bundled
|
||||
* with this source code in the file license.txt.
|
||||
*/
|
||||
class RPDO implements Driver
|
||||
{
|
||||
/**
|
||||
* @var integer
|
||||
*/
|
||||
protected $max;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $dsn;
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
*/
|
||||
protected $loggingEnabled = FALSE;
|
||||
|
||||
/**
|
||||
* @var Logger
|
||||
*/
|
||||
protected $logger = NULL;
|
||||
|
||||
/**
|
||||
* @var PDO
|
||||
*/
|
||||
protected $pdo;
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*/
|
||||
protected $affectedRows;
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*/
|
||||
protected $resultArray;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $connectInfo = array();
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
*/
|
||||
protected $isConnected = FALSE;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $flagUseStringOnlyBinding = FALSE;
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*/
|
||||
protected $queryCounter = 0;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $mysqlEncoding = '';
|
||||
|
||||
/**
|
||||
* Binds parameters. This method binds parameters to a PDOStatement for
|
||||
* Query Execution. This method binds parameters as NULL, INTEGER or STRING
|
||||
* and supports both named keys and question mark keys.
|
||||
*
|
||||
* @param PDOStatement $statement PDO Statement instance
|
||||
* @param array $bindings values that need to get bound to the statement
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function bindParams( $statement, $bindings )
|
||||
{
|
||||
foreach ( $bindings as $key => &$value ) {
|
||||
if ( is_integer( $key ) ) {
|
||||
if ( is_null( $value ) ) {
|
||||
$statement->bindValue( $key + 1, NULL, \PDO::PARAM_NULL );
|
||||
} elseif ( !$this->flagUseStringOnlyBinding && AQueryWriter::canBeTreatedAsInt( $value ) && abs( $value ) <= $this->max ) {
|
||||
$statement->bindParam( $key + 1, $value, \PDO::PARAM_INT );
|
||||
} else {
|
||||
$statement->bindParam( $key + 1, $value, \PDO::PARAM_STR );
|
||||
}
|
||||
} else {
|
||||
if ( is_null( $value ) ) {
|
||||
$statement->bindValue( $key, NULL, \PDO::PARAM_NULL );
|
||||
} elseif ( !$this->flagUseStringOnlyBinding && AQueryWriter::canBeTreatedAsInt( $value ) && abs( $value ) <= $this->max ) {
|
||||
$statement->bindParam( $key, $value, \PDO::PARAM_INT );
|
||||
} else {
|
||||
$statement->bindParam( $key, $value, \PDO::PARAM_STR );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method runs the actual SQL query and binds a list of parameters to the query.
|
||||
* slots. The result of the query will be stored in the protected property
|
||||
* $rs (always array). The number of rows affected (result of rowcount, if supported by database)
|
||||
* is stored in protected property $affectedRows. If the debug flag is set
|
||||
* this function will send debugging output to screen buffer.
|
||||
*
|
||||
* @param string $sql the SQL string to be send to database server
|
||||
* @param array $bindings the values that need to get bound to the query slots
|
||||
* @param array $options
|
||||
*
|
||||
* @return mixed
|
||||
* @throws SQL
|
||||
*/
|
||||
protected function runQuery( $sql, $bindings, $options = array() )
|
||||
{
|
||||
$this->connect();
|
||||
if ( $this->loggingEnabled && $this->logger ) {
|
||||
$this->logger->log( $sql, $bindings );
|
||||
}
|
||||
try {
|
||||
if ( strpos( 'pgsql', $this->dsn ) === 0 ) {
|
||||
if ( defined( '\PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT' ) ) {
|
||||
$statement = $this->pdo->prepare( $sql, array( \PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT => TRUE ) );
|
||||
} else {
|
||||
$statement = $this->pdo->prepare( $sql );
|
||||
}
|
||||
} else {
|
||||
$statement = $this->pdo->prepare( $sql );
|
||||
}
|
||||
$this->bindParams( $statement, $bindings );
|
||||
$statement->execute();
|
||||
$this->queryCounter ++;
|
||||
$this->affectedRows = $statement->rowCount();
|
||||
if ( $statement->columnCount() ) {
|
||||
$fetchStyle = ( isset( $options['fetchStyle'] ) ) ? $options['fetchStyle'] : NULL;
|
||||
if ( isset( $options['noFetch'] ) && $options['noFetch'] ) {
|
||||
$this->resultArray = array();
|
||||
return $statement;
|
||||
}
|
||||
$this->resultArray = $statement->fetchAll( $fetchStyle );
|
||||
if ( $this->loggingEnabled && $this->logger ) {
|
||||
$this->logger->log( 'resultset: ' . count( $this->resultArray ) . ' rows' );
|
||||
}
|
||||
} else {
|
||||
$this->resultArray = array();
|
||||
}
|
||||
} catch ( \PDOException $e ) {
|
||||
//Unfortunately the code field is supposed to be int by default (php)
|
||||
//So we need a property to convey the SQL State code.
|
||||
$err = $e->getMessage();
|
||||
if ( $this->loggingEnabled && $this->logger ) $this->logger->log( 'An error occurred: ' . $err );
|
||||
$exception = new SQL( $err, 0 );
|
||||
$exception->setSQLState( $e->getCode() );
|
||||
throw $exception;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to fix MySQL character encoding problems.
|
||||
* MySQL < 5.5 does not support proper 4 byte unicode but they
|
||||
* seem to have added it with version 5.5 under a different label: utf8mb4.
|
||||
* We try to select the best possible charset based on your version data.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function setEncoding()
|
||||
{
|
||||
$driver = $this->pdo->getAttribute( \PDO::ATTR_DRIVER_NAME );
|
||||
$version = floatval( $this->pdo->getAttribute( \PDO::ATTR_SERVER_VERSION ) );
|
||||
if ($driver === 'mysql') {
|
||||
$encoding = ($version >= 5.5) ? 'utf8mb4' : 'utf8';
|
||||
$this->pdo->setAttribute(\PDO::MYSQL_ATTR_INIT_COMMAND, 'SET NAMES '.$encoding ); //on every re-connect
|
||||
$this->pdo->exec(' SET NAMES '. $encoding); //also for current connection
|
||||
$this->mysqlEncoding = $encoding;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor. You may either specify dsn, user and password or
|
||||
* just give an existing PDO connection.
|
||||
*
|
||||
* Examples:
|
||||
* $driver = new RPDO($dsn, $user, $password);
|
||||
* $driver = new RPDO($existingConnection);
|
||||
*
|
||||
* @param string|object $dsn database connection string
|
||||
* @param string $user optional, usename to sign in
|
||||
* @param string $pass optional, password for connection login
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct( $dsn, $user = NULL, $pass = NULL )
|
||||
{
|
||||
if ( is_object( $dsn ) ) {
|
||||
$this->pdo = $dsn;
|
||||
$this->isConnected = TRUE;
|
||||
$this->setEncoding();
|
||||
$this->pdo->setAttribute( \PDO::ATTR_ERRMODE,\PDO::ERRMODE_EXCEPTION );
|
||||
$this->pdo->setAttribute( \PDO::ATTR_DEFAULT_FETCH_MODE,\PDO::FETCH_ASSOC );
|
||||
// make sure that the dsn at least contains the type
|
||||
$this->dsn = $this->getDatabaseType();
|
||||
} else {
|
||||
$this->dsn = $dsn;
|
||||
$this->connectInfo = array( 'pass' => $pass, 'user' => $user );
|
||||
}
|
||||
|
||||
//PHP 5.3 PDO SQLite has a bug with large numbers:
|
||||
if ( ( strpos( $this->dsn, 'sqlite' ) === 0 && PHP_MAJOR_VERSION === 5 && PHP_MINOR_VERSION === 3 ) || defined('HHVM_VERSION') || $this->dsn === 'test-sqlite-53' ) {
|
||||
$this->max = 2147483647; //otherwise you get -2147483648 ?! demonstrated in build #603 on Travis.
|
||||
} elseif ( strpos( $this->dsn, 'cubrid' ) === 0 ) {
|
||||
$this->max = 2147483647; //bindParam in pdo_cubrid also fails...
|
||||
} else {
|
||||
$this->max = PHP_INT_MAX; //the normal value of course (makes it possible to use large numbers in LIMIT clause)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the best possible encoding for MySQL based on version data.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getMysqlEncoding()
|
||||
{
|
||||
return $this->mysqlEncoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to bind all parameters as strings.
|
||||
* If set to TRUE this will cause all integers to be bound as STRINGS.
|
||||
* This will NOT affect NULL values.
|
||||
*
|
||||
* @param boolean $yesNo pass TRUE to bind all parameters as strings.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setUseStringOnlyBinding( $yesNo )
|
||||
{
|
||||
$this->flagUseStringOnlyBinding = (boolean) $yesNo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maximum value to be bound as integer, normally
|
||||
* this value equals PHP's MAX INT constant, however sometimes
|
||||
* PDO driver bindings cannot bind large integers as integers.
|
||||
* This method allows you to manually set the max integer binding
|
||||
* value to manage portability/compatibility issues among different
|
||||
* PHP builds. This method will return the old value.
|
||||
*
|
||||
* @param integer $max maximum value for integer bindings
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function setMaxIntBind( $max )
|
||||
{
|
||||
if ( !is_integer( $max ) ) throw new RedException( 'Parameter has to be integer.' );
|
||||
$oldMax = $this->max;
|
||||
$this->max = $max;
|
||||
return $oldMax;
|
||||
}
|
||||
|
||||
/**
|
||||
* Establishes a connection to the database using PHP\PDO
|
||||
* functionality. If a connection has already been established this
|
||||
* method will simply return directly. This method also turns on
|
||||
* UTF8 for the database and PDO-ERRMODE-EXCEPTION as well as
|
||||
* PDO-FETCH-ASSOC.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function connect()
|
||||
{
|
||||
if ( $this->isConnected ) return;
|
||||
try {
|
||||
$user = $this->connectInfo['user'];
|
||||
$pass = $this->connectInfo['pass'];
|
||||
$this->pdo = new \PDO(
|
||||
$this->dsn,
|
||||
$user,
|
||||
$pass
|
||||
);
|
||||
$this->setEncoding();
|
||||
$this->pdo->setAttribute( \PDO::ATTR_STRINGIFY_FETCHES, TRUE );
|
||||
//cant pass these as argument to constructor, CUBRID driver does not understand...
|
||||
$this->pdo->setAttribute( \PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION );
|
||||
$this->pdo->setAttribute( \PDO::ATTR_DEFAULT_FETCH_MODE, \PDO::FETCH_ASSOC );
|
||||
$this->isConnected = TRUE;
|
||||
} catch ( \PDOException $exception ) {
|
||||
$matches = array();
|
||||
$dbname = ( preg_match( '/dbname=(\w+)/', $this->dsn, $matches ) ) ? $matches[1] : '?';
|
||||
throw new \PDOException( 'Could not connect to database (' . $dbname . ').', $exception->getCode() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Directly sets PDO instance into driver.
|
||||
* This method might improve performance, however since the driver does
|
||||
* not configure this instance terrible things may happen... only use
|
||||
* this method if you are an expert on RedBeanPHP, PDO and UTF8 connections and
|
||||
* you know your database server VERY WELL.
|
||||
*
|
||||
* @param PDO $pdo PDO instance
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setPDO( \PDO $pdo ) {
|
||||
$this->pdo = $pdo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Driver::GetAll
|
||||
*/
|
||||
public function GetAll( $sql, $bindings = array() )
|
||||
{
|
||||
$this->runQuery( $sql, $bindings );
|
||||
return $this->resultArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Driver::GetAssocRow
|
||||
*/
|
||||
public function GetAssocRow( $sql, $bindings = array() )
|
||||
{
|
||||
$this->runQuery( $sql, $bindings, array(
|
||||
'fetchStyle' => \PDO::FETCH_ASSOC
|
||||
)
|
||||
);
|
||||
return $this->resultArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Driver::GetCol
|
||||
*/
|
||||
public function GetCol( $sql, $bindings = array() )
|
||||
{
|
||||
$rows = $this->GetAll( $sql, $bindings );
|
||||
$cols = array();
|
||||
if ( $rows && is_array( $rows ) && count( $rows ) > 0 ) {
|
||||
foreach ( $rows as $row ) {
|
||||
$cols[] = array_shift( $row );
|
||||
}
|
||||
}
|
||||
|
||||
return $cols;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Driver::GetOne
|
||||
*/
|
||||
public function GetOne( $sql, $bindings = array() )
|
||||
{
|
||||
$arr = $this->GetAll( $sql, $bindings );
|
||||
$res = NULL;
|
||||
if ( !is_array( $arr ) ) return NULL;
|
||||
if ( count( $arr ) === 0 ) return NULL;
|
||||
$row1 = array_shift( $arr );
|
||||
if ( !is_array( $row1 ) ) return NULL;
|
||||
if ( count( $row1 ) === 0 ) return NULL;
|
||||
$col1 = array_shift( $row1 );
|
||||
return $col1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias for getOne().
|
||||
* Backward compatibility.
|
||||
*
|
||||
* @param string $sql SQL
|
||||
* @param array $bindings bindings
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function GetCell( $sql, $bindings = array() )
|
||||
{
|
||||
return $this->GetOne( $sql, $bindings );
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Driver::GetRow
|
||||
*/
|
||||
public function GetRow( $sql, $bindings = array() )
|
||||
{
|
||||
$arr = $this->GetAll( $sql, $bindings );
|
||||
return array_shift( $arr );
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Driver::Excecute
|
||||
*/
|
||||
public function Execute( $sql, $bindings = array() )
|
||||
{
|
||||
$this->runQuery( $sql, $bindings );
|
||||
return $this->affectedRows;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Driver::GetInsertID
|
||||
*/
|
||||
public function GetInsertID()
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
return (int) $this->pdo->lastInsertId();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Driver::GetCursor
|
||||
*/
|
||||
public function GetCursor( $sql, $bindings = array() )
|
||||
{
|
||||
$statement = $this->runQuery( $sql, $bindings, array( 'noFetch' => TRUE ) );
|
||||
$cursor = new PDOCursor( $statement, \PDO::FETCH_ASSOC );
|
||||
return $cursor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Driver::Affected_Rows
|
||||
*/
|
||||
public function Affected_Rows()
|
||||
{
|
||||
$this->connect();
|
||||
return (int) $this->affectedRows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles debug mode. In debug mode the driver will print all
|
||||
* SQL to the screen together with some information about the
|
||||
* results.
|
||||
*
|
||||
* @param boolean $trueFalse turn on/off
|
||||
* @param Logger $logger logger instance
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setDebugMode( $tf, $logger = NULL )
|
||||
{
|
||||
$this->connect();
|
||||
$this->loggingEnabled = (bool) $tf;
|
||||
if ( $this->loggingEnabled and !$logger ) {
|
||||
$logger = new RDefault();
|
||||
}
|
||||
$this->setLogger( $logger );
|
||||
}
|
||||
|
||||
/**
|
||||
* Injects Logger object.
|
||||
* Sets the logger instance you wish to use.
|
||||
*
|
||||
* @param Logger $logger the logger instance to be used for logging
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setLogger( Logger $logger )
|
||||
{
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets Logger object.
|
||||
* Returns the currently active Logger instance.
|
||||
*
|
||||
* @return Logger
|
||||
*/
|
||||
public function getLogger()
|
||||
{
|
||||
return $this->logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Driver::StartTrans
|
||||
*/
|
||||
public function StartTrans()
|
||||
{
|
||||
$this->connect();
|
||||
$this->pdo->beginTransaction();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Driver::CommitTrans
|
||||
*/
|
||||
public function CommitTrans()
|
||||
{
|
||||
$this->connect();
|
||||
$this->pdo->commit();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Driver::FailTrans
|
||||
*/
|
||||
public function FailTrans()
|
||||
{
|
||||
$this->connect();
|
||||
$this->pdo->rollback();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of database driver for PDO.
|
||||
* Uses the PDO attribute DRIVER NAME to obtain the name of the
|
||||
* PDO driver.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDatabaseType()
|
||||
{
|
||||
$this->connect();
|
||||
|
||||
return $this->pdo->getAttribute(\PDO::ATTR_DRIVER_NAME );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the version number of the database.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getDatabaseVersion()
|
||||
{
|
||||
$this->connect();
|
||||
return $this->pdo->getAttribute(\PDO::ATTR_CLIENT_VERSION );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the underlying PHP PDO instance.
|
||||
*
|
||||
* @return PDO
|
||||
*/
|
||||
public function getPDO()
|
||||
{
|
||||
$this->connect();
|
||||
return $this->pdo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes database connection by destructing PDO.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
$this->pdo = NULL;
|
||||
$this->isConnected = FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns TRUE if the current PDO instance is connected.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isConnected()
|
||||
{
|
||||
return $this->isConnected && $this->pdo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles logging, enables or disables logging.
|
||||
*
|
||||
* @param boolean $enable TRUE to enable logging
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setEnableLogging( $enable )
|
||||
{
|
||||
$this->loggingEnabled = (boolean) $enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the internal Query Counter.
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function resetCounter()
|
||||
{
|
||||
$this->queryCounter = 0;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of SQL queries processed.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getQueryCount()
|
||||
{
|
||||
return $this->queryCounter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum value treated as integer parameter
|
||||
* binding.
|
||||
*
|
||||
* This method is mainly for testing purposes but it can help
|
||||
* you solve some issues relating to integer bindings.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getIntegerBindingMax()
|
||||
{
|
||||
return $this->max;
|
||||
}
|
||||
}
|
|
@ -1,455 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RedBeanPHP;
|
||||
|
||||
use RedBeanPHP\ToolBox as ToolBox;
|
||||
use RedBeanPHP\AssociationManager as AssociationManager;
|
||||
use RedBeanPHP\OODB as OODB;
|
||||
use RedBeanPHP\OODBBean as OODBBean;
|
||||
use RedBeanPHP\QueryWriter\AQueryWriter as AQueryWriter;
|
||||
|
||||
/**
|
||||
* Duplication Manager.
|
||||
* Creates deep copies of beans.
|
||||
*
|
||||
* @file RedBeanPHP/DuplicationManager.php
|
||||
* @author Gabor de Mooij and the RedBeanPHP Community
|
||||
* @license BSD/GPLv2
|
||||
*
|
||||
* @copyright
|
||||
* copyright (c) G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community
|
||||
* This source file is subject to the BSD/GPLv2 License that is bundled
|
||||
* with this source code in the file license.txt.
|
||||
*/
|
||||
class DuplicationManager
|
||||
{
|
||||
/**
|
||||
* @var ToolBox
|
||||
*/
|
||||
protected $toolbox;
|
||||
|
||||
/**
|
||||
* @var AssociationManager
|
||||
*/
|
||||
protected $associationManager;
|
||||
|
||||
/**
|
||||
* @var OODB
|
||||
*/
|
||||
protected $redbean;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $tables = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $columns = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $filters = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $cacheTables = FALSE;
|
||||
|
||||
/**
|
||||
* Copies the shared beans in a bean, i.e. all the sharedBean-lists.
|
||||
*
|
||||
* @param OODBBean $copy target bean to copy lists to
|
||||
* @param string $shared name of the shared list
|
||||
* @param array $beans array with shared beans to copy
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function copySharedBeans( OODBBean $copy, $shared, $beans )
|
||||
{
|
||||
$copy->$shared = array();
|
||||
|
||||
foreach ( $beans as $subBean ) {
|
||||
array_push( $copy->$shared, $subBean );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the own beans in a bean, i.e. all the ownBean-lists.
|
||||
* Each bean in the own-list belongs exclusively to its owner so
|
||||
* we need to invoke the duplicate method again to duplicate each bean here.
|
||||
*
|
||||
* @param OODBBean $copy target bean to copy lists to
|
||||
* @param string $owned name of the own list
|
||||
* @param array $beans array with shared beans to copy
|
||||
* @param array $trail array with former beans to detect recursion
|
||||
* @param boolean $preserveIDs TRUE means preserve IDs, for export only
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function copyOwnBeans( OODBBean $copy, $owned, $beans, $trail, $preserveIDs )
|
||||
{
|
||||
$copy->$owned = array();
|
||||
foreach ( $beans as $subBean ) {
|
||||
array_push( $copy->$owned, $this->duplicate( $subBean, $trail, $preserveIDs ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of bean $bean and copies all primitive properties (not lists)
|
||||
* and the parents beans to the newly created bean. Also sets the ID of the bean
|
||||
* to 0.
|
||||
*
|
||||
* @param OODBBean $bean bean to copy
|
||||
*
|
||||
* @return OODBBean
|
||||
*/
|
||||
private function createCopy( OODBBean $bean )
|
||||
{
|
||||
$type = $bean->getMeta( 'type' );
|
||||
|
||||
$copy = $this->redbean->dispense( $type );
|
||||
$copy->setMeta( 'sys.dup-from-id', $bean->id );
|
||||
$copy->setMeta( 'sys.old-id', $bean->id );
|
||||
$copy->importFrom( $bean );
|
||||
$copy->id = 0;
|
||||
|
||||
return $copy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a key from the bean type and its ID and determines if the bean
|
||||
* occurs in the trail, if not the bean will be added to the trail.
|
||||
* Returns TRUE if the bean occurs in the trail and FALSE otherwise.
|
||||
*
|
||||
* @param array $trail list of former beans
|
||||
* @param OODBBean $bean currently selected bean
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
private function inTrailOrAdd( &$trail, OODBBean $bean )
|
||||
{
|
||||
$type = $bean->getMeta( 'type' );
|
||||
$key = $type . $bean->getID();
|
||||
|
||||
if ( isset( $trail[$key] ) ) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
$trail[$key] = $bean;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given the type name of a bean this method returns the canonical names
|
||||
* of the own-list and the shared-list properties respectively.
|
||||
* Returns a list with two elements: name of the own-list, and name
|
||||
* of the shared list.
|
||||
*
|
||||
* @param string $typeName bean type name
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getListNames( $typeName )
|
||||
{
|
||||
$owned = 'own' . ucfirst( $typeName );
|
||||
$shared = 'shared' . ucfirst( $typeName );
|
||||
|
||||
return array( $owned, $shared );
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the bean has an own list based on
|
||||
* schema inspection from realtime schema or cache.
|
||||
*
|
||||
* @param string $type bean type to get list for
|
||||
* @param string $target type of list you want to detect
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
protected function hasOwnList( $type, $target )
|
||||
{
|
||||
return isset( $this->columns[$target][$type . '_id'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the bea has a shared list based on
|
||||
* schema inspection from realtime schema or cache.
|
||||
*
|
||||
* @param string $type bean type to get list for
|
||||
* @param string $target type of list you are looking for
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
protected function hasSharedList( $type, $target )
|
||||
{
|
||||
return in_array( AQueryWriter::getAssocTableFormat( array( $type, $target ) ), $this->tables );
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DuplicationManager::dup
|
||||
*
|
||||
* @param OODBBean $bean bean to be copied
|
||||
* @param array $trail trail to prevent infinite loops
|
||||
* @param boolean $preserveIDs preserve IDs
|
||||
*
|
||||
* @return OODBBean
|
||||
*/
|
||||
protected function duplicate( OODBBean $bean, $trail = array(), $preserveIDs = FALSE )
|
||||
{
|
||||
if ( $this->inTrailOrAdd( $trail, $bean ) ) return $bean;
|
||||
|
||||
$type = $bean->getMeta( 'type' );
|
||||
|
||||
$copy = $this->createCopy( $bean );
|
||||
foreach ( $this->tables as $table ) {
|
||||
|
||||
if ( !empty( $this->filters ) ) {
|
||||
if ( !in_array( $table, $this->filters ) ) continue;
|
||||
}
|
||||
|
||||
list( $owned, $shared ) = $this->getListNames( $table );
|
||||
|
||||
if ( $this->hasSharedList( $type, $table ) ) {
|
||||
if ( $beans = $bean->$shared ) {
|
||||
$this->copySharedBeans( $copy, $shared, $beans );
|
||||
}
|
||||
} elseif ( $this->hasOwnList( $type, $table ) ) {
|
||||
if ( $beans = $bean->$owned ) {
|
||||
$this->copyOwnBeans( $copy, $owned, $beans, $trail, $preserveIDs );
|
||||
}
|
||||
|
||||
$copy->setMeta( 'sys.shadow.' . $owned, NULL );
|
||||
}
|
||||
|
||||
$copy->setMeta( 'sys.shadow.' . $shared, NULL );
|
||||
}
|
||||
|
||||
$copy->id = ( $preserveIDs ) ? $bean->id : $copy->id;
|
||||
|
||||
return $copy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor,
|
||||
* creates a new instance of DupManager.
|
||||
*
|
||||
* @param ToolBox $toolbox
|
||||
*/
|
||||
public function __construct( ToolBox $toolbox )
|
||||
{
|
||||
$this->toolbox = $toolbox;
|
||||
$this->redbean = $toolbox->getRedBean();
|
||||
$this->associationManager = $this->redbean->getAssociationManager();
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively turns the keys of an array into
|
||||
* camelCase.
|
||||
*
|
||||
* @param array $array array to camelize
|
||||
* @param boolean $dolphinMode whether you want the exception for IDs.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function camelfy( $array, $dolphinMode = false ) {
|
||||
$newArray = array();
|
||||
foreach( $array as $key => $element ) {
|
||||
$newKey = preg_replace_callback( '/_(\w)/', function( &$matches ){
|
||||
return strtoupper( $matches[1] );
|
||||
}, $key);
|
||||
|
||||
if ( $dolphinMode ) {
|
||||
$newKey = preg_replace( '/(\w)Id$/', '$1ID', $newKey );
|
||||
}
|
||||
|
||||
$newArray[$newKey] = ( is_array($element) ) ? $this->camelfy( $element, $dolphinMode ) : $element;
|
||||
}
|
||||
return $newArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* For better performance you can pass the tables in an array to this method.
|
||||
* If the tables are available the duplication manager will not query them so
|
||||
* this might be beneficial for performance.
|
||||
*
|
||||
* This method allows two array formats:
|
||||
*
|
||||
* <code>
|
||||
* array( TABLE1, TABLE2 ... )
|
||||
* </code>
|
||||
*
|
||||
* or
|
||||
*
|
||||
* <code>
|
||||
* array( TABLE1 => array( COLUMN1, COLUMN2 ... ) ... )
|
||||
* </code>
|
||||
*
|
||||
* @param array $tables a table cache array
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setTables( $tables )
|
||||
{
|
||||
foreach ( $tables as $key => $value ) {
|
||||
if ( is_numeric( $key ) ) {
|
||||
$this->tables[] = $value;
|
||||
} else {
|
||||
$this->tables[] = $key;
|
||||
$this->columns[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
$this->cacheTables = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a schema array for cache.
|
||||
* You can use the return value of this method as a cache,
|
||||
* store it in RAM or on disk and pass it to setTables later.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getSchema()
|
||||
{
|
||||
return $this->columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether you want the duplication manager to cache the database schema.
|
||||
* If this flag is set to TRUE the duplication manager will query the database schema
|
||||
* only once. Otherwise the duplicationmanager will, by default, query the schema
|
||||
* every time a duplication action is performed (dup()).
|
||||
*
|
||||
* @param boolean $yesNo TRUE to use caching, FALSE otherwise
|
||||
*/
|
||||
public function setCacheTables( $yesNo )
|
||||
{
|
||||
$this->cacheTables = $yesNo;
|
||||
}
|
||||
|
||||
/**
|
||||
* A filter array is an array with table names.
|
||||
* By setting a table filter you can make the duplication manager only take into account
|
||||
* certain bean types. Other bean types will be ignored when exporting or making a
|
||||
* deep copy. If no filters are set all types will be taking into account, this is
|
||||
* the default behavior.
|
||||
*
|
||||
* @param array $filters list of tables to be filtered
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setFilters( $filters )
|
||||
{
|
||||
if ( !is_array( $filters ) ) {
|
||||
$filters = array( $filters );
|
||||
}
|
||||
|
||||
$this->filters = $filters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a copy of a bean. This method makes a deep copy
|
||||
* of the bean.The copy will have the following features.
|
||||
* - All beans in own-lists will be duplicated as well
|
||||
* - All references to shared beans will be copied but not the shared beans themselves
|
||||
* - All references to parent objects (_id fields) will be copied but not the parents themselves
|
||||
* In most cases this is the desired scenario for copying beans.
|
||||
* This function uses a trail-array to prevent infinite recursion, if a recursive bean is found
|
||||
* (i.e. one that already has been processed) the ID of the bean will be returned.
|
||||
* This should not happen though.
|
||||
*
|
||||
* Note:
|
||||
* This function does a reflectional database query so it may be slow.
|
||||
*
|
||||
* Note:
|
||||
* this function actually passes the arguments to a protected function called
|
||||
* duplicate() that does all the work. This method takes care of creating a clone
|
||||
* of the bean to avoid the bean getting tainted (triggering saving when storing it).
|
||||
*
|
||||
* @param OODBBean $bean bean to be copied
|
||||
* @param array $trail for internal usage, pass array()
|
||||
* @param boolean $preserveIDs for internal usage
|
||||
*
|
||||
* @return OODBBean
|
||||
*/
|
||||
public function dup( OODBBean $bean, $trail = array(), $preserveIDs = FALSE )
|
||||
{
|
||||
if ( !count( $this->tables ) ) {
|
||||
$this->tables = $this->toolbox->getWriter()->getTables();
|
||||
}
|
||||
|
||||
if ( !count( $this->columns ) ) {
|
||||
foreach ( $this->tables as $table ) {
|
||||
$this->columns[$table] = $this->toolbox->getWriter()->getColumns( $table );
|
||||
}
|
||||
}
|
||||
|
||||
$rs = $this->duplicate( ( clone $bean ), $trail, $preserveIDs );
|
||||
|
||||
if ( !$this->cacheTables ) {
|
||||
$this->tables = array();
|
||||
$this->columns = array();
|
||||
}
|
||||
|
||||
return $rs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exports a collection of beans recursively.
|
||||
* This method will export an array of beans in the first argument to a
|
||||
* set of arrays. This can be used to send JSON or XML representations
|
||||
* of bean hierarchies to the client.
|
||||
*
|
||||
* For every bean in the array this method will export:
|
||||
*
|
||||
* - contents of the bean
|
||||
* - all own bean lists (recursively)
|
||||
* - all shared beans (but not THEIR own lists)
|
||||
*
|
||||
* If the second parameter is set to TRUE the parents of the beans in the
|
||||
* array will be exported as well (but not THEIR parents).
|
||||
*
|
||||
* The third parameter can be used to provide a white-list array
|
||||
* for filtering. This is an array of strings representing type names,
|
||||
* only the type names in the filter list will be exported.
|
||||
*
|
||||
* The fourth parameter can be used to change the keys of the resulting
|
||||
* export arrays. The default mode is 'snake case' but this leaves the
|
||||
* keys as-is, because 'snake' is the default case style used by
|
||||
* RedBeanPHP in the database. You can set this to 'camel' for
|
||||
* camel cased keys or 'dolphin' (same as camelcase but id will be
|
||||
* converted to ID instead of Id).
|
||||
*
|
||||
* @param array|OODBBean $beans beans to be exported
|
||||
* @param boolean $parents also export parents
|
||||
* @param array $filters only these types (whitelist)
|
||||
* @param string $caseStyle case style identifier
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function exportAll( $beans, $parents = FALSE, $filters = array(), $caseStyle = 'snake')
|
||||
{
|
||||
$array = array();
|
||||
|
||||
if ( !is_array( $beans ) ) {
|
||||
$beans = array( $beans );
|
||||
}
|
||||
|
||||
foreach ( $beans as $bean ) {
|
||||
$this->setFilters( $filters );
|
||||
|
||||
$duplicate = $this->dup( $bean, array(), TRUE );
|
||||
|
||||
$array[] = $duplicate->export( FALSE, $parents, FALSE, $filters );
|
||||
}
|
||||
|
||||
if ( $caseStyle === 'camel' ) $array = $this->camelfy( $array );
|
||||
if ( $caseStyle === 'dolphin' ) $array = $this->camelfy( $array, true );
|
||||
|
||||
return $array;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,386 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RedBeanPHP;
|
||||
|
||||
|
||||
/**
|
||||
* RedBeanPHP Finder.
|
||||
* Service class to find beans. For the most part this class
|
||||
* offers user friendly utility methods for interacting with the
|
||||
* OODB::find() method, which is rather complex. This class can be
|
||||
* used to find beans using plain old SQL queries.
|
||||
*
|
||||
* @file RedBeanPHP/Finder.php
|
||||
* @author Gabor de Mooij and the RedBeanPHP Community
|
||||
* @license BSD/GPLv2
|
||||
*
|
||||
* @copyright
|
||||
* copyright (c) G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community
|
||||
* This source file is subject to the BSD/GPLv2 License that is bundled
|
||||
* with this source code in the file license.txt.
|
||||
*/
|
||||
class Finder
|
||||
{
|
||||
/**
|
||||
* @var ToolBox
|
||||
*/
|
||||
protected $toolbox;
|
||||
|
||||
/**
|
||||
* @var OODB
|
||||
*/
|
||||
protected $redbean;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* The Finder requires a toolbox.
|
||||
*
|
||||
* @param ToolBox $toolbox
|
||||
*/
|
||||
public function __construct( ToolBox $toolbox )
|
||||
{
|
||||
$this->toolbox = $toolbox;
|
||||
$this->redbean = $toolbox->getRedBean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a bean using a type and a where clause (SQL).
|
||||
* As with most Query tools in RedBean you can provide values to
|
||||
* be inserted in the SQL statement by populating the value
|
||||
* array parameter; you can either use the question mark notation
|
||||
* or the slot-notation (:keyname).
|
||||
*
|
||||
* @param string $type type the type of bean you are looking for
|
||||
* @param string $sql sql SQL query to find the desired bean, starting right after WHERE clause
|
||||
* @param array $bindings values array of values to be bound to parameters in query
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function find( $type, $sql = NULL, $bindings = array() )
|
||||
{
|
||||
if ( !is_array( $bindings ) ) {
|
||||
throw new RedException(
|
||||
'Expected array, ' . gettype( $bindings ) . ' given.'
|
||||
);
|
||||
}
|
||||
|
||||
return $this->redbean->find( $type, array(), $sql, $bindings );
|
||||
}
|
||||
|
||||
/**
|
||||
* Like find() but also exports the beans as an array.
|
||||
* This method will perform a find-operation. For every bean
|
||||
* in the result collection this method will call the export() method.
|
||||
* This method returns an array containing the array representations
|
||||
* of every bean in the result set.
|
||||
*
|
||||
* @see Finder::find
|
||||
*
|
||||
* @param string $type type the type of bean you are looking for
|
||||
* @param string $sql sql SQL query to find the desired bean, starting right after WHERE clause
|
||||
* @param array $bindings values array of values to be bound to parameters in query
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function findAndExport( $type, $sql = NULL, $bindings = array() )
|
||||
{
|
||||
$arr = array();
|
||||
foreach ( $this->find( $type, $sql, $bindings ) as $key => $item ) {
|
||||
$arr[] = $item->export();
|
||||
}
|
||||
|
||||
return $arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Like find() but returns just one bean instead of an array of beans.
|
||||
* This method will return only the first bean of the array.
|
||||
* If no beans are found, this method will return NULL.
|
||||
*
|
||||
* @see Finder::find
|
||||
*
|
||||
* @param string $type type the type of bean you are looking for
|
||||
* @param string $sql sql SQL query to find the desired bean, starting right after WHERE clause
|
||||
* @param array $bindings values array of values to be bound to parameters in query
|
||||
*
|
||||
* @return OODBBean
|
||||
*/
|
||||
public function findOne( $type, $sql = NULL, $bindings = array() )
|
||||
{
|
||||
$sql = $this->toolbox->getWriter()->glueLimitOne( $sql );
|
||||
|
||||
$items = $this->find( $type, $sql, $bindings );
|
||||
|
||||
if ( empty($items) ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return reset( $items );
|
||||
}
|
||||
|
||||
/**
|
||||
* Like find() but returns the last bean of the result array.
|
||||
* Opposite of Finder::findLast().
|
||||
* If no beans are found, this method will return NULL.
|
||||
*
|
||||
* @see Finder::find
|
||||
*
|
||||
* @param string $type the type of bean you are looking for
|
||||
* @param string $sql SQL query to find the desired bean, starting right after WHERE clause
|
||||
* @param array $bindings values array of values to be bound to parameters in query
|
||||
*
|
||||
* @return OODBBean
|
||||
*/
|
||||
public function findLast( $type, $sql = NULL, $bindings = array() )
|
||||
{
|
||||
$items = $this->find( $type, $sql, $bindings );
|
||||
|
||||
if ( empty($items) ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return end( $items );
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to find beans of a certain type,
|
||||
* if no beans are found, it dispenses a bean of that type.
|
||||
*
|
||||
* @see Finder::find
|
||||
*
|
||||
* @param string $type the type of bean you are looking for
|
||||
* @param string $sql SQL query to find the desired bean, starting right after WHERE clause
|
||||
* @param array $bindings values array of values to be bound to parameters in query
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function findOrDispense( $type, $sql = NULL, $bindings = array() )
|
||||
{
|
||||
$foundBeans = $this->find( $type, $sql, $bindings );
|
||||
|
||||
if ( empty( $foundBeans ) ) {
|
||||
return array( $this->redbean->dispense( $type ) );
|
||||
} else {
|
||||
return $foundBeans;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a BeanCollection using the repository.
|
||||
* A bean collection can be used to retrieve one bean at a time using
|
||||
* cursors - this is useful for processing large datasets. A bean collection
|
||||
* will not load all beans into memory all at once, just one at a time.
|
||||
*
|
||||
* @param string $type the type of bean you are looking for
|
||||
* @param string $sql SQL query to find the desired bean, starting right after WHERE clause
|
||||
* @param array $bindings values array of values to be bound to parameters in query
|
||||
*
|
||||
* @return BeanCollection
|
||||
*/
|
||||
public function findCollection( $type, $sql, $bindings = array() )
|
||||
{
|
||||
return $this->redbean->findCollection( $type, $sql, $bindings );
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds or creates a bean.
|
||||
* Tries to find a bean with certain properties specified in the second
|
||||
* parameter ($like). If the bean is found, it will be returned.
|
||||
* If multiple beans are found, only the first will be returned.
|
||||
* If no beans match the criteria, a new bean will be dispensed,
|
||||
* the criteria will be imported as properties and this new bean
|
||||
* will be stored and returned.
|
||||
*
|
||||
* Format of criteria set: property => value
|
||||
* The criteria set also supports OR-conditions: property => array( value1, orValue2 )
|
||||
*
|
||||
* @param string $type type of bean to search for
|
||||
* @param array $like criteria set describing bean to search for
|
||||
*
|
||||
* @return OODBBean
|
||||
*/
|
||||
public function findOrCreate( $type, $like = array() )
|
||||
{
|
||||
$beans = $this->findLike( $type, $like );
|
||||
if ( count( $beans ) ) {
|
||||
$bean = reset( $beans );
|
||||
return $bean;
|
||||
}
|
||||
|
||||
$bean = $this->redbean->dispense( $type );
|
||||
$bean->import( $like );
|
||||
$this->redbean->store( $bean );
|
||||
return $bean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds beans by its type and a certain criteria set.
|
||||
*
|
||||
* Format of criteria set: property => value
|
||||
* The criteria set also supports OR-conditions: property => array( value1, orValue2 )
|
||||
*
|
||||
* If the additional SQL is a condition, this condition will be glued to the rest
|
||||
* of the query using an AND operator. Note that this is as far as this method
|
||||
* can go, there is no way to glue additional SQL using an OR-condition.
|
||||
* This method provides access to an underlying mechanism in the RedBeanPHP architecture
|
||||
* to find beans using criteria sets. However, please do not use this method
|
||||
* for complex queries, use plain SQL instead ( the regular find method ) as it is
|
||||
* more suitable for the job. This method is
|
||||
* meant for basic search-by-example operations.
|
||||
*
|
||||
* @param string $type type of bean to search for
|
||||
* @param array $conditions criteria set describing the bean to search for
|
||||
* @param string $sql additional SQL (for sorting)
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function findLike( $type, $conditions = array(), $sql = '' )
|
||||
{
|
||||
if ( count( $conditions ) > 0 ) {
|
||||
foreach( $conditions as $key => $condition ) {
|
||||
if ( !count( $condition ) ) unset( $conditions[$key] );
|
||||
}
|
||||
}
|
||||
|
||||
return $this->redbean->find( $type, $conditions, $sql );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hashmap with bean arrays keyed by type using an SQL
|
||||
* query as its resource. Given an SQL query like 'SELECT movie.*, review.* FROM movie... JOIN review'
|
||||
* this method will return movie and review beans.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* <code>
|
||||
* $stuff = $finder->findMulti('movie,review', '
|
||||
* SELECT movie.*, review.* FROM movie
|
||||
* LEFT JOIN review ON review.movie_id = movie.id');
|
||||
* </code>
|
||||
*
|
||||
* After this operation, $stuff will contain an entry 'movie' containing all
|
||||
* movies and an entry named 'review' containing all reviews (all beans).
|
||||
* You can also pass bindings.
|
||||
*
|
||||
* If you want to re-map your beans, so you can use $movie->ownReviewList without
|
||||
* having RedBeanPHP executing an SQL query you can use the fourth parameter to
|
||||
* define a selection of remapping closures.
|
||||
*
|
||||
* The remapping argument (optional) should contain an array of arrays.
|
||||
* Each array in the remapping array should contain the following entries:
|
||||
*
|
||||
* <code>
|
||||
* array(
|
||||
* 'a' => TYPE A
|
||||
* 'b' => TYPE B
|
||||
* 'matcher' => MATCHING FUNCTION ACCEPTING A, B and ALL BEANS
|
||||
* 'do' => OPERATION FUNCTION ACCEPTING A, B, ALL BEANS, ALL REMAPPINGS
|
||||
* )
|
||||
* </code>
|
||||
*
|
||||
* Using this mechanism you can build your own 'preloader' with tiny function
|
||||
* snippets (and those can be re-used and shared online of course).
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* <code>
|
||||
* array(
|
||||
* 'a' => 'movie' //define A as movie
|
||||
* 'b' => 'review' //define B as review
|
||||
* 'matcher' => function( $a, $b ) {
|
||||
* return ( $b->movie_id == $a->id ); //Perform action if review.movie_id equals movie.id
|
||||
* }
|
||||
* 'do' => function( $a, $b ) {
|
||||
* $a->noLoad()->ownReviewList[] = $b; //Add the review to the movie
|
||||
* $a->clearHistory(); //optional, act 'as if these beans have been loaded through ownReviewList'.
|
||||
* }
|
||||
* )
|
||||
* </code>
|
||||
*
|
||||
* The Query Template parameter is optional as well but can be used to
|
||||
* set a different SQL template (sprintf-style) for processing the original query.
|
||||
*
|
||||
* @note the SQL query provided IS NOT THE ONE used internally by this function,
|
||||
* this function will pre-process the query to get all the data required to find the beans.
|
||||
*
|
||||
* @note if you use the 'book.*' notation make SURE you're
|
||||
* selector starts with a SPACE. ' book.*' NOT ',book.*'. This is because
|
||||
* it's actually an SQL-like template SLOT, not real SQL.
|
||||
*
|
||||
* @note instead of an SQL query you can pass a result array as well.
|
||||
*
|
||||
* @param string|array $types a list of types (either array or comma separated string)
|
||||
* @param string|array $sqlOrArr an SQL query or an array of prefetched records
|
||||
* @param array $bindings optional, bindings for SQL query
|
||||
* @param array $remappings optional, an array of remapping arrays
|
||||
* @param string $queryTemplate optional, query template
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function findMulti( $types, $sql, $bindings = array(), $remappings = array(), $queryTemplate = ' %s.%s AS %s__%s' )
|
||||
{
|
||||
if ( !is_array( $types ) ) $types = explode( ',', $types );
|
||||
if ( !is_array( $sql ) ) {
|
||||
$writer = $this->toolbox->getWriter();
|
||||
$adapter = $this->toolbox->getDatabaseAdapter();
|
||||
|
||||
//Repair the query, replace book.* with book.id AS book_id etc..
|
||||
foreach( $types as $type ) {
|
||||
$pattern = " {$type}.*";
|
||||
if ( strpos( $sql, $pattern ) !== FALSE ) {
|
||||
$newSelectorArray = array();
|
||||
$columns = $writer->getColumns( $type );
|
||||
foreach( $columns as $column => $definition ) {
|
||||
$newSelectorArray[] = sprintf( $queryTemplate, $type, $column, $type, $column );
|
||||
}
|
||||
$newSelector = implode( ',', $newSelectorArray );
|
||||
$sql = str_replace( $pattern, $newSelector, $sql );
|
||||
}
|
||||
}
|
||||
|
||||
$rows = $adapter->get( $sql, $bindings );
|
||||
} else {
|
||||
$rows = $sql;
|
||||
}
|
||||
|
||||
//Gather the bean data from the query results using the prefix
|
||||
$wannaBeans = array();
|
||||
foreach( $types as $type ) {
|
||||
$wannaBeans[$type] = array();
|
||||
$prefix = "{$type}__";
|
||||
foreach( $rows as $rowkey=>$row ) {
|
||||
$wannaBean = array();
|
||||
foreach( $row as $cell => $value ) {
|
||||
if ( strpos( $cell, $prefix ) === 0 ) {
|
||||
$property = substr( $cell, strlen( $prefix ) );
|
||||
unset( $rows[$rowkey][$cell] );
|
||||
$wannaBean[$property] = $value;
|
||||
}
|
||||
}
|
||||
if ( !isset( $wannaBean['id'] ) ) continue;
|
||||
if ( is_null( $wannaBean['id'] ) ) continue;
|
||||
$wannaBeans[$type][$wannaBean['id']] = $wannaBean;
|
||||
}
|
||||
}
|
||||
|
||||
//Turn the rows into beans
|
||||
$beans = array();
|
||||
foreach( $wannaBeans as $type => $wannabees ) {
|
||||
$beans[$type] = $this->redbean->convertToBeans( $type, $wannabees );
|
||||
}
|
||||
|
||||
//Apply additional re-mappings
|
||||
foreach($remappings as $remapping) {
|
||||
$a = $remapping['a'];
|
||||
$b = $remapping['b'];
|
||||
$matcher = $remapping['matcher'];
|
||||
$do = $remapping['do'];
|
||||
foreach( $beans[$a] as $bean ) {
|
||||
foreach( $beans[$b] as $putBean ) {
|
||||
if ( $matcher( $bean, $putBean, $beans ) ) $do( $bean, $putBean, $beans, $remapping );
|
||||
}
|
||||
}
|
||||
}
|
||||
return $beans;
|
||||
}
|
||||
}
|
|
@ -1,78 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Support functions for RedBeanPHP.
|
||||
* Additional convenience shortcut functions for RedBeanPHP.
|
||||
*
|
||||
* @file RedBeanPHP/Functions.php
|
||||
* @author Gabor de Mooij and the RedBeanPHP community
|
||||
* @license BSD/GPLv2
|
||||
*
|
||||
* @copyright
|
||||
* copyright (c) G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community.
|
||||
* This source file is subject to the BSD/GPLv2 License that is bundled
|
||||
* with this source code in the file license.txt.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Convenience function for ENUM short syntax in queries.
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* <code>
|
||||
* R::find( 'paint', ' color_id = ? ', [ EID('color:yellow') ] );
|
||||
* </code>
|
||||
*
|
||||
* If a function called EID() already exists you'll have to write this
|
||||
* wrapper yourself ;)
|
||||
*
|
||||
* @param string $enumName enum code as you would pass to R::enum()
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
if (!function_exists('EID')) {
|
||||
|
||||
function EID($enumName)
|
||||
{
|
||||
return \RedBeanPHP\Facade::enum( $enumName )->id;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the result of R::dump() to the screen using
|
||||
* print_r.
|
||||
*
|
||||
* @param mixed $data data to dump
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
if ( !function_exists( 'dump' ) ) {
|
||||
|
||||
function dmp( $list )
|
||||
{
|
||||
print_r( \RedBeanPHP\Facade::dump( $list ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function alias for R::genSlots().
|
||||
*/
|
||||
if ( !function_exists( 'genslots' ) ) {
|
||||
|
||||
function genslots( $slots, $tpl = NULL )
|
||||
{
|
||||
return \RedBeanPHP\Facade::genSlots( $slots, $tpl );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function alias for R::flat().
|
||||
*/
|
||||
if ( !function_exists( 'array_flatten' ) ) {
|
||||
|
||||
function array_flatten( $array )
|
||||
{
|
||||
return \RedBeanPHP\Facade::flat( $array );
|
||||
}
|
||||
}
|
|
@ -1,182 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RedBeanPHP;
|
||||
|
||||
use RedBeanPHP\ToolBox as ToolBox;
|
||||
use RedBeanPHP\OODBBean as OODBBean;
|
||||
|
||||
/**
|
||||
* Label Maker.
|
||||
* Makes so-called label beans.
|
||||
* A label is a bean with only an id, type and name property.
|
||||
* Labels can be used to create simple entities like categories, tags or enums.
|
||||
* This service class provides convenience methods to deal with this kind of
|
||||
* beans.
|
||||
*
|
||||
* @file RedBeanPHP/LabelMaker.php
|
||||
* @author Gabor de Mooij and the RedBeanPHP Community
|
||||
* @license BSD/GPLv2
|
||||
*
|
||||
* @copyright
|
||||
* copyright (c) G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community
|
||||
* This source file is subject to the BSD/GPLv2 License that is bundled
|
||||
* with this source code in the file license.txt.
|
||||
*/
|
||||
class LabelMaker
|
||||
{
|
||||
/**
|
||||
* @var ToolBox
|
||||
*/
|
||||
protected $toolbox;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param ToolBox $toolbox
|
||||
*/
|
||||
public function __construct( ToolBox $toolbox )
|
||||
{
|
||||
$this->toolbox = $toolbox;
|
||||
}
|
||||
|
||||
/**
|
||||
* A label is a bean with only an id, type and name property.
|
||||
* This function will dispense beans for all entries in the array. The
|
||||
* values of the array will be assigned to the name property of each
|
||||
* individual bean.
|
||||
*
|
||||
* <code>
|
||||
* $people = R::dispenseLabels( 'person', [ 'Santa', 'Claus' ] );
|
||||
* </code>
|
||||
*
|
||||
* @param string $type type of beans you would like to have
|
||||
* @param array $labels list of labels, names for each bean
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function dispenseLabels( $type, $labels )
|
||||
{
|
||||
$labelBeans = array();
|
||||
foreach ( $labels as $label ) {
|
||||
$labelBean = $this->toolbox->getRedBean()->dispense( $type );
|
||||
$labelBean->name = $label;
|
||||
$labelBeans[] = $labelBean;
|
||||
}
|
||||
|
||||
return $labelBeans;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gathers labels from beans. This function loops through the beans,
|
||||
* collects the value of the name property for each individual bean
|
||||
* and stores the names in a new array. The array then gets sorted using the
|
||||
* default sort function of PHP (sort).
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* <code>
|
||||
* $o1->name = 'hamburger';
|
||||
* $o2->name = 'pizza';
|
||||
* implode( ',', R::gatherLabels( [ $o1, $o2 ] ) ); //hamburger,pizza
|
||||
* </code>
|
||||
*
|
||||
* Note that the return value is an array of strings, not beans.
|
||||
*
|
||||
* @param array $beans list of beans to loop through
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function gatherLabels( $beans )
|
||||
{
|
||||
$labels = array();
|
||||
|
||||
foreach ( $beans as $bean ) {
|
||||
$labels[] = $bean->name;
|
||||
}
|
||||
|
||||
sort( $labels );
|
||||
|
||||
return $labels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches an ENUM from the database and creates it if necessary.
|
||||
* An ENUM has the following format:
|
||||
*
|
||||
* <code>
|
||||
* ENUM:VALUE
|
||||
* </code>
|
||||
*
|
||||
* If you pass 'ENUM' only, this method will return an array of its
|
||||
* values:
|
||||
*
|
||||
* <code>
|
||||
* implode( ',', R::gatherLabels( R::enum( 'flavour' ) ) ) //'BANANA,MOCCA'
|
||||
* </code>
|
||||
*
|
||||
* If you pass 'ENUM:VALUE' this method will return the specified enum bean
|
||||
* and create it in the database if it does not exist yet:
|
||||
*
|
||||
* <code>
|
||||
* $bananaFlavour = R::enum( 'flavour:banana' );
|
||||
* $bananaFlavour->name;
|
||||
* </code>
|
||||
*
|
||||
* So you can use this method to set an ENUM value in a bean:
|
||||
*
|
||||
* <code>
|
||||
* $shake->flavour = R::enum( 'flavour:banana' );
|
||||
* </code>
|
||||
*
|
||||
* the property flavour now contains the enum bean, a parent bean.
|
||||
* In the database, flavour_id will point to the flavour record with name 'banana'.
|
||||
*
|
||||
* @param string $enum ENUM specification for label
|
||||
*
|
||||
* @return array|OODBBean
|
||||
*/
|
||||
public function enum( $enum )
|
||||
{
|
||||
$oodb = $this->toolbox->getRedBean();
|
||||
|
||||
if ( strpos( $enum, ':' ) === FALSE ) {
|
||||
$type = $enum;
|
||||
$value = FALSE;
|
||||
} else {
|
||||
list( $type, $value ) = explode( ':', $enum );
|
||||
$value = preg_replace( '/\W+/', '_', strtoupper( trim( $value ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* We use simply find here, we could use inspect() in fluid mode etc,
|
||||
* but this would be useless. At first sight it looks clean, you could even
|
||||
* bake this into find(), however, find not only has to deal with the primary
|
||||
* search type, people can also include references in the SQL part, so avoiding
|
||||
* find failures does not matter, this is still the quickest way making use
|
||||
* of existing functionality.
|
||||
*
|
||||
* @note There seems to be a bug in XDebug v2.3.2 causing suppressed
|
||||
* exceptions like these to surface anyway, to prevent this use:
|
||||
*
|
||||
* "xdebug.default_enable = 0"
|
||||
*
|
||||
* Also see Github Issue #464
|
||||
*/
|
||||
$values = $oodb->find( $type );
|
||||
|
||||
if ( $value === FALSE ) {
|
||||
return $values;
|
||||
}
|
||||
|
||||
foreach( $values as $enumItem ) {
|
||||
if ( $enumItem->name === $value ) return $enumItem;
|
||||
}
|
||||
|
||||
$newEnumItems = $this->dispenseLabels( $type, array( $value ) );
|
||||
$newEnumItem = reset( $newEnumItems );
|
||||
|
||||
$oodb->store( $newEnumItem );
|
||||
|
||||
return $newEnumItem;
|
||||
}
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RedBeanPHP;
|
||||
|
||||
/**
|
||||
* RedBean Logging interface.
|
||||
* Provides a uniform and convenient logging
|
||||
* interface throughout RedBeanPHP.
|
||||
*
|
||||
* @file RedBean/Logging.php
|
||||
* @author Gabor de Mooij and the RedBeanPHP Community
|
||||
* @license BSD/GPLv2
|
||||
*
|
||||
* @copyright
|
||||
* copyright (c) G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community
|
||||
* This source file is subject to the BSD/GPLv2 License that is bundled
|
||||
* with this source code in the file license.txt.
|
||||
*/
|
||||
interface Logger
|
||||
{
|
||||
/**
|
||||
* A logger (for PDO or OCI driver) needs to implement the log method.
|
||||
* The log method will receive logging data. Note that the number of parameters is 0, this means
|
||||
* all parameters are optional and the number may vary. This way the logger can be used in a very
|
||||
* flexible way. Sometimes the logger is used to log a simple error message and in other
|
||||
* situations sql and bindings are passed.
|
||||
* The log method should be able to accept all kinds of parameters and data by using
|
||||
* functions like func_num_args/func_get_args.
|
||||
*
|
||||
* @param string $message, ...
|
||||
* @return void
|
||||
*/
|
||||
public function log();
|
||||
}
|
|
@ -1,133 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RedBeanPHP\Logger;
|
||||
|
||||
use RedBeanPHP\Logger as Logger;
|
||||
use RedBeanPHP\RedException as RedException;
|
||||
|
||||
/**
|
||||
* Logger. Provides a basic logging function for RedBeanPHP.
|
||||
*
|
||||
* @file RedBeanPHP/Logger.php
|
||||
* @author Gabor de Mooij and the RedBeanPHP Community
|
||||
* @license BSD/GPLv2
|
||||
*
|
||||
* @copyright
|
||||
* copyright (c) G.J.G.T. (Gabor) de Mooij
|
||||
* This source file is subject to the BSD/GPLv2 License that is bundled
|
||||
* with this source code in the file license.txt.
|
||||
*/
|
||||
class RDefault implements Logger
|
||||
{
|
||||
/**
|
||||
* Logger modes
|
||||
*/
|
||||
const C_LOGGER_ECHO = 0;
|
||||
const C_LOGGER_ARRAY = 1;
|
||||
|
||||
/**
|
||||
* @var integer
|
||||
*/
|
||||
protected $mode = 0;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $logs = array();
|
||||
|
||||
/**
|
||||
* Default logger method logging to STDOUT.
|
||||
* This is the default/reference implementation of a logger.
|
||||
* This method will write the message value to STDOUT (screen) unless
|
||||
* you have changed the mode of operation to C_LOGGER_ARRAY.
|
||||
*
|
||||
* @param $message (optional) message to log (might also be data or output)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function log()
|
||||
{
|
||||
if ( func_num_args() < 1 ) return;
|
||||
|
||||
foreach ( func_get_args() as $argument ) {
|
||||
if ( is_array( $argument ) ) {
|
||||
$log = print_r( $argument, TRUE );
|
||||
if ( $this->mode === self::C_LOGGER_ECHO ) {
|
||||
echo $log;
|
||||
} else {
|
||||
$this->logs[] = $log;
|
||||
}
|
||||
} else {
|
||||
if ( $this->mode === self::C_LOGGER_ECHO ) {
|
||||
echo $argument;
|
||||
} else {
|
||||
$this->logs[] = $argument;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $this->mode === self::C_LOGGER_ECHO ) echo "<br>" . PHP_EOL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the internal log array.
|
||||
* The internal log array is where all log messages are stored.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getLogs()
|
||||
{
|
||||
return $this->logs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the internal log array, removing all
|
||||
* previously stored entries.
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
$this->logs = array();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Selects a logging mode.
|
||||
* There are several options available.
|
||||
*
|
||||
* * C_LOGGER_ARRAY - log silently, stores entries in internal log array only
|
||||
* * C_LOGGER_ECHO - also forward log messages directly to STDOUT
|
||||
*
|
||||
* @param integer $mode mode of operation for logging object
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setMode( $mode )
|
||||
{
|
||||
if ($mode !== self::C_LOGGER_ARRAY && $mode !== self::C_LOGGER_ECHO ) {
|
||||
throw new RedException( 'Invalid mode selected for logger, use C_LOGGER_ARRAY or C_LOGGER_ECHO.' );
|
||||
}
|
||||
$this->mode = $mode;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for all log entries in internal log array
|
||||
* for $needle and returns those entries.
|
||||
* This method will return an array containing all matches for your
|
||||
* search query.
|
||||
*
|
||||
* @param string $needle phrase to look for in internal log array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function grep( $needle )
|
||||
{
|
||||
$found = array();
|
||||
foreach( $this->logs as $logEntry ) {
|
||||
if ( strpos( $logEntry, $needle ) !== FALSE ) $found[] = $logEntry;
|
||||
}
|
||||
return $found;
|
||||
}
|
||||
}
|
|
@ -1,185 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RedBeanPHP\Logger\RDefault;
|
||||
|
||||
use RedBeanPHP\Logger as Logger;
|
||||
use RedBeanPHP\Logger\RDefault as RDefault;
|
||||
use RedBeanPHP\RedException as RedException;
|
||||
|
||||
/**
|
||||
* Debug logger.
|
||||
* A special logger for debugging purposes.
|
||||
* Provides debugging logging functions for RedBeanPHP.
|
||||
*
|
||||
* @file RedBeanPHP/Logger/RDefault/Debug.php
|
||||
* @author Gabor de Mooij and the RedBeanPHP Community
|
||||
* @license BSD/GPLv2
|
||||
*
|
||||
* @copyright
|
||||
* copyright (c) G.J.G.T. (Gabor) de Mooij
|
||||
* This source file is subject to the BSD/GPLv2 License that is bundled
|
||||
* with this source code in the file license.txt.
|
||||
*/
|
||||
class Debug extends RDefault implements Logger
|
||||
{
|
||||
/**
|
||||
* @var integer
|
||||
*/
|
||||
private $strLen = 40;
|
||||
|
||||
/**
|
||||
* Writes a query for logging with all bindings / params filled
|
||||
* in.
|
||||
*
|
||||
* @param string $newSql the query
|
||||
* @param array $bindings the bindings to process (key-value pairs)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function writeQuery( $newSql, $newBindings )
|
||||
{
|
||||
//avoid str_replace collisions: slot1 and slot10 (issue 407).
|
||||
uksort( $newBindings, function( $a, $b ) {
|
||||
return ( strlen( $b ) - strlen( $a ) );
|
||||
} );
|
||||
|
||||
$newStr = $newSql;
|
||||
foreach( $newBindings as $slot => $value ) {
|
||||
if ( strpos( $slot, ':' ) === 0 ) {
|
||||
$newStr = str_replace( $slot, $this->fillInValue( $value ), $newStr );
|
||||
}
|
||||
}
|
||||
return $newStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills in a value of a binding and truncates the
|
||||
* resulting string if necessary.
|
||||
*
|
||||
* @param mixed $value bound value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function fillInValue( $value )
|
||||
{
|
||||
if ( is_null( $value ) ) $value = 'NULL';
|
||||
|
||||
$value = strval( $value );
|
||||
if ( strlen( $value ) > ( $this->strLen ) ) {
|
||||
$value = substr( $value, 0, ( $this->strLen ) ).'... ';
|
||||
}
|
||||
|
||||
if ( !is_numeric( $value ) && $value !== 'NULL') {
|
||||
$value = '\''.$value.'\'';
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dependending on the current mode of operation,
|
||||
* this method will either log and output to STDIN or
|
||||
* just log.
|
||||
*
|
||||
* @param string $str string to log or output and log
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function output( $str )
|
||||
{
|
||||
$this->logs[] = $str;
|
||||
if ( !$this->mode ) echo $str ,'<br />';
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes the slots in an SQL string.
|
||||
* Replaces question mark slots with :slot1 :slot2 etc.
|
||||
*
|
||||
* @param string $sql sql to normalize
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function normalizeSlots( $sql )
|
||||
{
|
||||
$i = 0;
|
||||
$newSql = $sql;
|
||||
while($i < 20 && strpos($newSql, '?') !== FALSE ){
|
||||
$pos = strpos( $newSql, '?' );
|
||||
$slot = ':slot'.$i;
|
||||
$begin = substr( $newSql, 0, $pos );
|
||||
$end = substr( $newSql, $pos+1 );
|
||||
$newSql = $begin . $slot . $end;
|
||||
$i++;
|
||||
}
|
||||
return $newSql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes the bindings.
|
||||
* Replaces numeric binding keys with :slot1 :slot2 etc.
|
||||
*
|
||||
* @param array $bindings bindings to normalize
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function normalizeBindings( $bindings )
|
||||
{
|
||||
$i = 0;
|
||||
$newBindings = array();
|
||||
foreach( $bindings as $key => $value ) {
|
||||
if ( is_numeric($key) ) {
|
||||
$newKey = ':slot'.$i;
|
||||
$newBindings[$newKey] = $value;
|
||||
$i++;
|
||||
} else {
|
||||
$newBindings[$key] = $value;
|
||||
}
|
||||
}
|
||||
return $newBindings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Logger method.
|
||||
*
|
||||
* Takes a number of arguments tries to create
|
||||
* a proper debug log based on the available data.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function log()
|
||||
{
|
||||
if ( func_num_args() < 1 ) return;
|
||||
|
||||
$sql = func_get_arg( 0 );
|
||||
|
||||
if ( func_num_args() < 2) {
|
||||
$bindings = array();
|
||||
} else {
|
||||
$bindings = func_get_arg( 1 );
|
||||
}
|
||||
|
||||
if ( !is_array( $bindings ) ) {
|
||||
return $this->output( $sql );
|
||||
}
|
||||
|
||||
$newSql = $this->normalizeSlots( $sql );
|
||||
$newBindings = $this->normalizeBindings( $bindings );
|
||||
$newStr = $this->writeQuery( $newSql, $newBindings );
|
||||
$this->output( $newStr );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the max string length for the parameter output in
|
||||
* SQL queries. Set this value to a reasonable number to
|
||||
* keep you SQL queries readable.
|
||||
*
|
||||
* @param integer $len string length
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setParamStringLength( $len = 20 )
|
||||
{
|
||||
$this->strLen = max(0, $len);
|
||||
return $this;
|
||||
}
|
||||
}
|
|
@ -1,545 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RedBeanPHP;
|
||||
|
||||
use RedBeanPHP\Adapter\DBAdapter as DBAdapter;
|
||||
use RedBeanPHP\QueryWriter as QueryWriter;
|
||||
use RedBeanPHP\BeanHelper as BeanHelper;
|
||||
use RedBeanPHP\QueryWriter\AQueryWriter as AQueryWriter;
|
||||
use RedBeanPHP\Repository as Repository;
|
||||
use RedBeanPHP\Repository\Fluid as FluidRepo;
|
||||
use RedBeanPHP\Repository\Frozen as FrozenRepo;
|
||||
|
||||
/**
|
||||
* RedBean Object Oriented DataBase.
|
||||
*
|
||||
* The RedBean OODB Class is the main class of RedBeanPHP.
|
||||
* It takes OODBBean objects and stores them to and loads them from the
|
||||
* database as well as providing other CRUD functions. This class acts as a
|
||||
* object database.
|
||||
*
|
||||
* @file RedBeanPHP/OODB.php
|
||||
* @author Gabor de Mooij and the RedBeanPHP community
|
||||
* @license BSD/GPLv2
|
||||
*
|
||||
* @copyright
|
||||
* copyright (c) G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community
|
||||
* This source file is subject to the BSD/GPLv2 License that is bundled
|
||||
* with this source code in the file license.txt.
|
||||
*/
|
||||
class OODB extends Observable
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private static $sqlFilters = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $chillList = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $stash = NULL;
|
||||
|
||||
/*
|
||||
* @var integer
|
||||
*/
|
||||
protected $nesting = 0;
|
||||
|
||||
/**
|
||||
* @var DBAdapter
|
||||
*/
|
||||
protected $writer;
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
*/
|
||||
protected $isFrozen = FALSE;
|
||||
|
||||
/**
|
||||
* @var FacadeBeanHelper
|
||||
*/
|
||||
protected $beanhelper = NULL;
|
||||
|
||||
/**
|
||||
* @var AssociationManager
|
||||
*/
|
||||
protected $assocManager = NULL;
|
||||
|
||||
/**
|
||||
* @var Repository
|
||||
*/
|
||||
protected $repository = NULL;
|
||||
|
||||
/**
|
||||
* @var FrozenRepo
|
||||
*/
|
||||
protected $frozenRepository = NULL;
|
||||
|
||||
/**
|
||||
* @var FluidRepo
|
||||
*/
|
||||
protected $fluidRepository = NULL;
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
*/
|
||||
protected static $autoClearHistoryAfterStore = FALSE;
|
||||
|
||||
/**
|
||||
* If set to TRUE, this method will call clearHistory every time
|
||||
* the bean gets stored.
|
||||
*
|
||||
* @param boolean $autoClear auto clear option
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function autoClearHistoryAfterStore( $autoClear = TRUE )
|
||||
{
|
||||
self::$autoClearHistoryAfterStore = (boolean) $autoClear;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unboxes a bean from a FUSE model if needed and checks whether the bean is
|
||||
* an instance of OODBBean.
|
||||
*
|
||||
* @param OODBBean $bean bean you wish to unbox
|
||||
*
|
||||
* @return OODBBean
|
||||
*/
|
||||
protected function unboxIfNeeded( $bean )
|
||||
{
|
||||
if ( $bean instanceof SimpleModel ) {
|
||||
$bean = $bean->unbox();
|
||||
}
|
||||
if ( !( $bean instanceof OODBBean ) ) {
|
||||
throw new RedException( 'OODB Store requires a bean, got: ' . gettype( $bean ) );
|
||||
}
|
||||
|
||||
return $bean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor, requires a query writer.
|
||||
*
|
||||
* @param QueryWriter $writer writer
|
||||
* @param array|boolean $frozen mode of operation: TRUE (frozen), FALSE (default, fluid) or ARRAY (chilled)
|
||||
*/
|
||||
public function __construct( QueryWriter $writer, $frozen = FALSE )
|
||||
{
|
||||
if ( $writer instanceof QueryWriter ) {
|
||||
$this->writer = $writer;
|
||||
}
|
||||
|
||||
$this->freeze( $frozen );
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles fluid or frozen mode. In fluid mode the database
|
||||
* structure is adjusted to accomodate your objects. In frozen mode
|
||||
* this is not the case.
|
||||
*
|
||||
* You can also pass an array containing a selection of frozen types.
|
||||
* Let's call this chilly mode, it's just like fluid mode except that
|
||||
* certain types (i.e. tables) aren't touched.
|
||||
*
|
||||
* @param boolean|array $toggle TRUE if you want to use OODB instance in frozen mode
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function freeze( $toggle )
|
||||
{
|
||||
if ( is_array( $toggle ) ) {
|
||||
$this->chillList = $toggle;
|
||||
$this->isFrozen = FALSE;
|
||||
} else {
|
||||
$this->isFrozen = (boolean) $toggle;
|
||||
}
|
||||
|
||||
if ( $this->isFrozen ) {
|
||||
if ( !$this->frozenRepository ) {
|
||||
$this->frozenRepository = new FrozenRepo( $this, $this->writer );
|
||||
}
|
||||
|
||||
$this->repository = $this->frozenRepository;
|
||||
|
||||
} else {
|
||||
if ( !$this->fluidRepository ) {
|
||||
$this->fluidRepository = new FluidRepo( $this, $this->writer );
|
||||
}
|
||||
|
||||
$this->repository = $this->fluidRepository;
|
||||
}
|
||||
|
||||
if ( count( self::$sqlFilters ) ) {
|
||||
AQueryWriter::setSQLFilters( self::$sqlFilters, ( !$this->isFrozen ) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current mode of operation of RedBean.
|
||||
* In fluid mode the database
|
||||
* structure is adjusted to accomodate your objects.
|
||||
* In frozen mode
|
||||
* this is not the case.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isFrozen()
|
||||
{
|
||||
return (bool) $this->isFrozen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether a type is in the chill list.
|
||||
* If a type is 'chilled' it's frozen, so its schema cannot be
|
||||
* changed anymore. However other bean types may still be modified.
|
||||
* This method is a convenience method for other objects to check if
|
||||
* the schema of a certain type is locked for modification.
|
||||
*
|
||||
* @param string $type the type you wish to check
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isChilled( $type )
|
||||
{
|
||||
return (boolean) ( in_array( $type, $this->chillList ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispenses a new bean (a OODBBean Bean Object)
|
||||
* of the specified type. Always
|
||||
* use this function to get an empty bean object. Never
|
||||
* instantiate a OODBBean yourself because it needs
|
||||
* to be configured before you can use it with RedBean. This
|
||||
* function applies the appropriate initialization /
|
||||
* configuration for you.
|
||||
*
|
||||
* @param string $type type of bean you want to dispense
|
||||
* @param string $number number of beans you would like to get
|
||||
* @param boolean $alwaysReturnArray if TRUE always returns the result as an array
|
||||
*
|
||||
* @return OODBBean
|
||||
*/
|
||||
public function dispense( $type, $number = 1, $alwaysReturnArray = FALSE )
|
||||
{
|
||||
if ( $number < 1 ) {
|
||||
if ( $alwaysReturnArray ) return array();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return $this->repository->dispense( $type, $number, $alwaysReturnArray );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets bean helper to be given to beans.
|
||||
* Bean helpers assist beans in getting a reference to a toolbox.
|
||||
*
|
||||
* @param BeanHelper $beanhelper helper
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setBeanHelper( BeanHelper $beanhelper )
|
||||
{
|
||||
$this->beanhelper = $beanhelper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current bean helper.
|
||||
* Bean helpers assist beans in getting a reference to a toolbox.
|
||||
*
|
||||
* @return BeanHelper
|
||||
*/
|
||||
public function getBeanHelper()
|
||||
{
|
||||
return $this->beanhelper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a OODBBean bean is valid.
|
||||
* If the type is not valid or the ID is not valid it will
|
||||
* throw an exception: Security.
|
||||
*
|
||||
* @param OODBBean $bean the bean that needs to be checked
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function check( OODBBean $bean )
|
||||
{
|
||||
$this->repository->check( $bean );
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches the database for a bean that matches conditions $conditions and sql $addSQL
|
||||
* and returns an array containing all the beans that have been found.
|
||||
*
|
||||
* Conditions need to take form:
|
||||
*
|
||||
* <code>
|
||||
* array(
|
||||
* 'PROPERTY' => array( POSSIBLE VALUES... 'John', 'Steve' )
|
||||
* 'PROPERTY' => array( POSSIBLE VALUES... )
|
||||
* );
|
||||
* </code>
|
||||
*
|
||||
* All conditions are glued together using the AND-operator, while all value lists
|
||||
* are glued using IN-operators thus acting as OR-conditions.
|
||||
*
|
||||
* Note that you can use property names; the columns will be extracted using the
|
||||
* appropriate bean formatter.
|
||||
*
|
||||
* @param string $type type of beans you are looking for
|
||||
* @param array $conditions list of conditions
|
||||
* @param string $addSQL SQL to be used in query
|
||||
* @param array $bindings a list of values to bind to query parameters
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function find( $type, $conditions = array(), $sql = NULL, $bindings = array() )
|
||||
{
|
||||
return $this->repository->find( $type, $conditions, $sql, $bindings );
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as find() but returns a BeanCollection.
|
||||
*
|
||||
* @param string $type type of beans you are looking for
|
||||
* @param string $addSQL SQL to be used in query
|
||||
* @param array $bindings a list of values to bind to query parameters
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function findCollection( $type, $sql = NULL, $bindings = array() )
|
||||
{
|
||||
return $this->repository->findCollection( $type, $sql, $bindings );
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the specified table already exists in the database.
|
||||
* Not part of the Object Database interface!
|
||||
*
|
||||
* @deprecated Use AQueryWriter::typeExists() instead.
|
||||
*
|
||||
* @param string $table table name
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function tableExists( $table )
|
||||
{
|
||||
return $this->repository->tableExists( $table );
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a bean in the database. This method takes a
|
||||
* OODBBean Bean Object $bean and stores it
|
||||
* in the database. If the database schema is not compatible
|
||||
* with this bean and RedBean runs in fluid mode the schema
|
||||
* will be altered to store the bean correctly.
|
||||
* If the database schema is not compatible with this bean and
|
||||
* RedBean runs in frozen mode it will throw an exception.
|
||||
* This function returns the primary key ID of the inserted
|
||||
* bean.
|
||||
*
|
||||
* The return value is an integer if possible. If it is not possible to
|
||||
* represent the value as an integer a string will be returned. We use
|
||||
* explicit casts instead of functions to preserve performance
|
||||
* (0.13 vs 0.28 for 10000 iterations on Core i3).
|
||||
*
|
||||
* @param OODBBean|SimpleModel $bean bean to store
|
||||
*
|
||||
* @return integer|string
|
||||
*/
|
||||
public function store( $bean )
|
||||
{
|
||||
$bean = $this->unboxIfNeeded( $bean );
|
||||
$id = $this->repository->store( $bean );
|
||||
if ( self::$autoClearHistoryAfterStore ) {
|
||||
$bean->clearHistory();
|
||||
}
|
||||
return $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a bean from the object database.
|
||||
* It searches for a OODBBean Bean Object in the
|
||||
* database. It does not matter how this bean has been stored.
|
||||
* RedBean uses the primary key ID $id and the string $type
|
||||
* to find the bean. The $type specifies what kind of bean you
|
||||
* are looking for; this is the same type as used with the
|
||||
* dispense() function. If RedBean finds the bean it will return
|
||||
* the OODB Bean object; if it cannot find the bean
|
||||
* RedBean will return a new bean of type $type and with
|
||||
* primary key ID 0. In the latter case it acts basically the
|
||||
* same as dispense().
|
||||
*
|
||||
* Important note:
|
||||
* If the bean cannot be found in the database a new bean of
|
||||
* the specified type will be generated and returned.
|
||||
*
|
||||
* @param string $type type of bean you want to load
|
||||
* @param integer $id ID of the bean you want to load
|
||||
*
|
||||
* @return OODBBean
|
||||
*/
|
||||
public function load( $type, $id )
|
||||
{
|
||||
return $this->repository->load( $type, $id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a bean from the database.
|
||||
* This function will remove the specified OODBBean
|
||||
* Bean Object from the database.
|
||||
*
|
||||
* @param OODBBean|SimpleModel $bean bean you want to remove from database
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function trash( $bean )
|
||||
{
|
||||
$bean = $this->unboxIfNeeded( $bean );
|
||||
return $this->repository->trash( $bean );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of beans. Pass a type and a series of ids and
|
||||
* this method will bring you the corresponding beans.
|
||||
*
|
||||
* important note: Because this method loads beans using the load()
|
||||
* function (but faster) it will return empty beans with ID 0 for
|
||||
* every bean that could not be located. The resulting beans will have the
|
||||
* passed IDs as their keys.
|
||||
*
|
||||
* @param string $type type of beans
|
||||
* @param array $ids ids to load
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function batch( $type, $ids )
|
||||
{
|
||||
return $this->repository->batch( $type, $ids );
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a convenience method; it converts database rows
|
||||
* (arrays) into beans. Given a type and a set of rows this method
|
||||
* will return an array of beans of the specified type loaded with
|
||||
* the data fields provided by the result set from the database.
|
||||
*
|
||||
* @param string $type type of beans you would like to have
|
||||
* @param array $rows rows from the database result
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function convertToBeans( $type, $rows )
|
||||
{
|
||||
return $this->repository->convertToBeans( $type, $rows );
|
||||
}
|
||||
|
||||
/**
|
||||
* Counts the number of beans of type $type.
|
||||
* This method accepts a second argument to modify the count-query.
|
||||
* A third argument can be used to provide bindings for the SQL snippet.
|
||||
*
|
||||
* @param string $type type of bean we are looking for
|
||||
* @param string $addSQL additional SQL snippet
|
||||
* @param array $bindings parameters to bind to SQL
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function count( $type, $addSQL = '', $bindings = array() )
|
||||
{
|
||||
return $this->repository->count( $type, $addSQL, $bindings );
|
||||
}
|
||||
|
||||
/**
|
||||
* Trash all beans of a given type. Wipes an entire type of bean.
|
||||
*
|
||||
* @param string $type type of bean you wish to delete all instances of
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function wipe( $type )
|
||||
{
|
||||
return $this->repository->wipe( $type );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an Association Manager for use with OODB.
|
||||
* A simple getter function to obtain a reference to the association manager used for
|
||||
* storage and more.
|
||||
*
|
||||
* @return AssociationManager
|
||||
*/
|
||||
public function getAssociationManager()
|
||||
{
|
||||
if ( !isset( $this->assocManager ) ) {
|
||||
throw new RedException( 'No association manager available.' );
|
||||
}
|
||||
|
||||
return $this->assocManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the association manager instance to be used by this OODB.
|
||||
* A simple setter function to set the association manager to be used for storage and
|
||||
* more.
|
||||
*
|
||||
* @param AssociationManager $assoc sets the association manager to be used
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setAssociationManager( AssociationManager $assocManager )
|
||||
{
|
||||
$this->assocManager = $assocManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the currently used repository instance.
|
||||
* For testing purposes only.
|
||||
*
|
||||
* @return Repository
|
||||
*/
|
||||
public function getCurrentRepository()
|
||||
{
|
||||
return $this->repository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds an SQL function to a column.
|
||||
* This method can be used to setup a decode/encode scheme or
|
||||
* perform UUID insertion. This method is especially useful for handling
|
||||
* MySQL spatial columns, because they need to be processed first using
|
||||
* the asText/GeomFromText functions.
|
||||
*
|
||||
* @param string $mode mode to set function for, i.e. read or write
|
||||
* @param string $field field (table.column) to bind SQL function to
|
||||
* @param string $function SQL function to bind to field
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function bindFunc( $mode, $field, $function )
|
||||
{
|
||||
list( $type, $property ) = explode( '.', $field );
|
||||
$mode = ($mode === 'write') ? QueryWriter::C_SQLFILTER_WRITE : QueryWriter::C_SQLFILTER_READ;
|
||||
|
||||
if ( !isset( self::$sqlFilters[$mode] ) ) self::$sqlFilters[$mode] = array();
|
||||
if ( !isset( self::$sqlFilters[$mode][$type] ) ) self::$sqlFilters[$mode][$type] = array();
|
||||
|
||||
if ( is_null( $function ) ) {
|
||||
unset( self::$sqlFilters[$mode][$type][$property] );
|
||||
} else {
|
||||
if ($mode === QueryWriter::C_SQLFILTER_WRITE) {
|
||||
self::$sqlFilters[$mode][$type][$property] = $function.'(?)';
|
||||
} else {
|
||||
self::$sqlFilters[$mode][$type][$property] = $function."($field)";
|
||||
}
|
||||
}
|
||||
|
||||
AQueryWriter::setSQLFilters( self::$sqlFilters, ( !$this->isFrozen ) );
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,75 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RedBeanPHP;
|
||||
|
||||
use RedBeanPHP\Observer as Observer;
|
||||
|
||||
/**
|
||||
* Observable
|
||||
* Base class for Observables
|
||||
*
|
||||
* @file RedBeanPHP/Observable.php
|
||||
* @author Gabor de Mooij and the RedBeanPHP community
|
||||
* @license BSD/GPLv2
|
||||
*
|
||||
* @copyright
|
||||
* copyright (c) G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community.
|
||||
* This source file is subject to the BSD/GPLv2 License that is bundled
|
||||
* with this source code in the file license.txt.
|
||||
*/
|
||||
abstract class Observable { //bracket must be here - otherwise coverage software does not understand.
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $observers = array();
|
||||
|
||||
/**
|
||||
* Implementation of the Observer Pattern.
|
||||
* Adds an event listener to the observable object.
|
||||
* First argument should be the name of the event you wish to listen for.
|
||||
* Second argument should be the object that wants to be notified in case
|
||||
* the event occurs.
|
||||
*
|
||||
* @param string $eventname event identifier
|
||||
* @param Observer $observer observer instance
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addEventListener( $eventname, Observer $observer )
|
||||
{
|
||||
if ( !isset( $this->observers[$eventname] ) ) {
|
||||
$this->observers[$eventname] = array();
|
||||
}
|
||||
|
||||
foreach ( $this->observers[$eventname] as $o ) {
|
||||
if ( $o == $observer ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$this->observers[$eventname][] = $observer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies listeners.
|
||||
* Sends the signal $eventname, the event identifier and a message object
|
||||
* to all observers that have been registered to receive notification for
|
||||
* this event. Part of the observer pattern implementation in RedBeanPHP.
|
||||
*
|
||||
* @param string $eventname event you want signal
|
||||
* @param mixed $info message object to send along
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function signal( $eventname, $info )
|
||||
{
|
||||
if ( !isset( $this->observers[$eventname] ) ) {
|
||||
$this->observers[$eventname] = array();
|
||||
}
|
||||
|
||||
foreach ( $this->observers[$eventname] as $observer ) {
|
||||
$observer->onEvent( $eventname, $info );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RedBeanPHP;
|
||||
|
||||
/**
|
||||
* Observer.
|
||||
*
|
||||
* Interface for Observer object. Implementation of the
|
||||
* observer pattern.
|
||||
*
|
||||
* @file RedBeanPHP/Observer.php
|
||||
* @author Gabor de Mooij and the RedBeanPHP community
|
||||
* @license BSD/GPLv2
|
||||
* @desc Part of the observer pattern in RedBean
|
||||
*
|
||||
* @copyright
|
||||
* copyright (c) G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community.
|
||||
* This source file is subject to the BSD/GPLv2 License that is bundled
|
||||
* with this source code in the file license.txt.
|
||||
*/
|
||||
interface Observer
|
||||
{
|
||||
/**
|
||||
* An observer object needs to be capable of receiving
|
||||
* notifications. Therefore the observer needs to implement the
|
||||
* onEvent method with two parameters: the event identifier specifying the
|
||||
* current event and a message object (in RedBeanPHP this can also be a bean).
|
||||
*
|
||||
* @param string $eventname event identifier
|
||||
* @param mixed $bean a message sent along with the notification
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function onEvent( $eventname, $bean );
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RedBeanPHP;
|
||||
|
||||
/**
|
||||
* RedBean Plugin.
|
||||
* Marker interface for plugins.
|
||||
*
|
||||
* @file RedBean/Plugin.php
|
||||
* @author Gabor de Mooij and the RedBeanPHP Community
|
||||
* @license BSD/GPLv2
|
||||
*
|
||||
* @copyright
|
||||
* copyright (c) G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community
|
||||
* This source file is subject to the BSD/GPLv2 License that is bundled
|
||||
* with this source code in the file license.txt.
|
||||
*/
|
||||
interface Plugin
|
||||
{
|
||||
}
|
||||
|
||||
;
|
|
@ -1,494 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RedBeanPHP;
|
||||
|
||||
/**
|
||||
* QueryWriter
|
||||
* Interface for QueryWriters.
|
||||
* Describes the API for a QueryWriter.
|
||||
*
|
||||
* Terminology:
|
||||
*
|
||||
* - beautified property (a camelCased property, has to be converted first)
|
||||
* - beautified type (a camelCased type, has to be converted first)
|
||||
* - type (a bean type, corresponds directly to a table)
|
||||
* - property (a bean property, corresponds directly to a column)
|
||||
* - table (a checked and quoted type, ready for use in a query)
|
||||
* - column (a checked and quoted property, ready for use in query)
|
||||
* - tableNoQ (same as type, but in context of a database operation)
|
||||
* - columnNoQ (same as property, but in context of a database operation)
|
||||
*
|
||||
* @file RedBeanPHP/QueryWriter.php
|
||||
* @author Gabor de Mooij and the RedBeanPHP community
|
||||
* @license BSD/GPLv2
|
||||
*
|
||||
* @copyright
|
||||
* copyright (c) G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community.
|
||||
* This source file is subject to the BSD/GPLv2 License that is bundled
|
||||
* with this source code in the file license.txt.
|
||||
*/
|
||||
interface QueryWriter
|
||||
{
|
||||
/**
|
||||
* SQL filter constants
|
||||
*/
|
||||
const C_SQLFILTER_READ = 'r';
|
||||
const C_SQLFILTER_WRITE = 'w';
|
||||
|
||||
/**
|
||||
* Query Writer constants.
|
||||
*/
|
||||
const C_SQLSTATE_NO_SUCH_TABLE = 1;
|
||||
const C_SQLSTATE_NO_SUCH_COLUMN = 2;
|
||||
const C_SQLSTATE_INTEGRITY_CONSTRAINT_VIOLATION = 3;
|
||||
|
||||
/**
|
||||
* Define data type regions
|
||||
*
|
||||
* 00 - 80: normal data types
|
||||
* 80 - 99: special data types, only scan/code if requested
|
||||
* 99 : specified by user, don't change
|
||||
*/
|
||||
const C_DATATYPE_RANGE_SPECIAL = 80;
|
||||
const C_DATATYPE_RANGE_SPECIFIED = 99;
|
||||
|
||||
/**
|
||||
* Define GLUE types for use with glueSQLCondition methods.
|
||||
* Determines how to prefix a snippet of SQL before appending it
|
||||
* to other SQL (or integrating it, mixing it otherwise).
|
||||
*
|
||||
* WHERE - glue as WHERE condition
|
||||
* AND - glue as AND condition
|
||||
*/
|
||||
const C_GLUE_WHERE = 1;
|
||||
const C_GLUE_AND = 2;
|
||||
|
||||
/**
|
||||
* Writes an SQL Snippet for a JOIN, returns the
|
||||
* SQL snippet string.
|
||||
*
|
||||
* @note A default implementation is available in AQueryWriter
|
||||
* unless a database uses very different SQL this should suffice.
|
||||
*
|
||||
* @param string $type source type
|
||||
* @param string $targetType target type (type to join)
|
||||
* @param string $leftRight type of join (possible: 'LEFT', 'RIGHT' or 'INNER').
|
||||
*
|
||||
* @return string $joinSQLSnippet
|
||||
*/
|
||||
public function writeJoin( $type, $targetType, $joinType );
|
||||
|
||||
/**
|
||||
* Glues an SQL snippet to the beginning of a WHERE clause.
|
||||
* This ensures users don't have to add WHERE to their query snippets.
|
||||
*
|
||||
* The snippet gets prefixed with WHERE or AND
|
||||
* if it starts with a condition.
|
||||
*
|
||||
* If the snippet does NOT start with a condition (or this function thinks so)
|
||||
* the snippet is returned as-is.
|
||||
*
|
||||
* The GLUE type determines the prefix:
|
||||
*
|
||||
* * NONE prefixes with WHERE
|
||||
* * WHERE prefixes with WHERE and replaces AND if snippets starts with AND
|
||||
* * AND prefixes with AND
|
||||
*
|
||||
* This method will never replace WHERE with AND since a snippet should never
|
||||
* begin with WHERE in the first place. OR is not supported.
|
||||
*
|
||||
* Only a limited set of clauses will be recognized as non-conditions.
|
||||
* For instance beginning a snippet with complex statements like JOIN or UNION
|
||||
* will not work. This is too complex for use in a snippet.
|
||||
*
|
||||
* @note A default implementation is available in AQueryWriter
|
||||
* unless a database uses very different SQL this should suffice.
|
||||
*
|
||||
* @param string $sql SQL Snippet
|
||||
* @param integer $glue the GLUE type - how to glue (C_GLUE_WHERE or C_GLUE_AND)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function glueSQLCondition( $sql, $glue = NULL );
|
||||
|
||||
/**
|
||||
* Determines if there is a LIMIT 1 clause in the SQL.
|
||||
* If not, it will add a LIMIT 1. (used for findOne).
|
||||
*
|
||||
* @note A default implementation is available in AQueryWriter
|
||||
* unless a database uses very different SQL this should suffice.
|
||||
*
|
||||
* @param string $sql query to scan and adjust
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function glueLimitOne( $sql );
|
||||
|
||||
/**
|
||||
* Returns the tables that are in the database.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getTables();
|
||||
|
||||
/**
|
||||
* This method will create a table for the bean.
|
||||
* This methods accepts a type and infers the corresponding table name.
|
||||
*
|
||||
* @param string $type type of bean you want to create a table for
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function createTable( $type );
|
||||
|
||||
/**
|
||||
* Returns an array containing all the columns of the specified type.
|
||||
* The format of the return array looks like this:
|
||||
* $field => $type where $field is the name of the column and $type
|
||||
* is a database specific description of the datatype.
|
||||
*
|
||||
* This methods accepts a type and infers the corresponding table name.
|
||||
*
|
||||
* @param string $type type of bean you want to obtain a column list of
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getColumns( $type );
|
||||
|
||||
/**
|
||||
* Returns the Column Type Code (integer) that corresponds
|
||||
* to the given value type. This method is used to determine the minimum
|
||||
* column type required to represent the given value.
|
||||
*
|
||||
* @param string $value value
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function scanType( $value, $alsoScanSpecialForTypes = FALSE );
|
||||
|
||||
/**
|
||||
* This method will add a column to a table.
|
||||
* This methods accepts a type and infers the corresponding table name.
|
||||
*
|
||||
* @param string $type name of the table
|
||||
* @param string $column name of the column
|
||||
* @param integer $field data type for field
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addColumn( $type, $column, $field );
|
||||
|
||||
/**
|
||||
* Returns the Type Code for a Column Description.
|
||||
* Given an SQL column description this method will return the corresponding
|
||||
* code for the writer. If the include specials flag is set it will also
|
||||
* return codes for special columns. Otherwise special columns will be identified
|
||||
* as specified columns.
|
||||
*
|
||||
* @param string $typedescription description
|
||||
* @param boolean $includeSpecials whether you want to get codes for special columns as well
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function code( $typedescription, $includeSpecials = FALSE );
|
||||
|
||||
/**
|
||||
* This method will widen the column to the specified data type.
|
||||
* This methods accepts a type and infers the corresponding table name.
|
||||
*
|
||||
* @param string $type type / table that needs to be adjusted
|
||||
* @param string $column column that needs to be altered
|
||||
* @param integer $datatype target data type
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function widenColumn( $type, $column, $datatype );
|
||||
|
||||
/**
|
||||
* Selects records from the database.
|
||||
* This methods selects the records from the database that match the specified
|
||||
* type, conditions (optional) and additional SQL snippet (optional).
|
||||
*
|
||||
* @param string $type name of the table you want to query
|
||||
* @param array $conditions criteria ( $column => array( $values ) )
|
||||
* @param string $addSQL additional SQL snippet
|
||||
* @param array $bindings bindings for SQL snippet
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function queryRecord( $type, $conditions = array(), $addSql = NULL, $bindings = array() );
|
||||
|
||||
/**
|
||||
* Selects records from the database and returns a cursor.
|
||||
* This methods selects the records from the database that match the specified
|
||||
* type, conditions (optional) and additional SQL snippet (optional).
|
||||
*
|
||||
* @param string $type name of the table you want to query
|
||||
* @param array $conditions criteria ( $column => array( $values ) )
|
||||
* @param string $addSQL additional SQL snippet
|
||||
* @param array $bindings bindings for SQL snippet
|
||||
*
|
||||
* @return Cursor
|
||||
*/
|
||||
public function queryRecordWithCursor( $type, $addSql = NULL, $bindings = array() );
|
||||
|
||||
/**
|
||||
* Returns records through an intermediate type. This method is used to obtain records using a link table and
|
||||
* allows the SQL snippets to reference columns in the link table for additional filtering or ordering.
|
||||
*
|
||||
* @param string $sourceType source type, the reference type you want to use to fetch related items on the other side
|
||||
* @param string $destType destination type, the target type you want to get beans of
|
||||
* @param mixed $linkID ID to use for the link table
|
||||
* @param string $addSql Additional SQL snippet
|
||||
* @param array $bindings Bindings for SQL snippet
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function queryRecordRelated( $sourceType, $destType, $linkID, $addSql = '', $bindings = array() );
|
||||
|
||||
/**
|
||||
* Returns the row that links $sourceType $sourcID to $destType $destID in an N-M relation.
|
||||
*
|
||||
* @param string $sourceType source type, the first part of the link you're looking for
|
||||
* @param string $destType destination type, the second part of the link you're looking for
|
||||
* @param string $sourceID ID for the source
|
||||
* @param string $destID ID for the destination
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public function queryRecordLink( $sourceType, $destType, $sourceID, $destID );
|
||||
|
||||
/**
|
||||
* Counts the number of records in the database that match the
|
||||
* conditions and additional SQL.
|
||||
*
|
||||
* @param string $type name of the table you want to query
|
||||
* @param array $conditions criteria ( $column => array( $values ) )
|
||||
* @param string $addSQL additional SQL snippet
|
||||
* @param array $bindings bindings for SQL snippet
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function queryRecordCount( $type, $conditions = array(), $addSql = NULL, $bindings = array() );
|
||||
|
||||
/**
|
||||
* Returns the number of records linked through $linkType and satisfying the SQL in $addSQL/$bindings.
|
||||
*
|
||||
* @param string $sourceType source type
|
||||
* @param string $targetType the thing you want to count
|
||||
* @param mixed $linkID the of the source type
|
||||
* @param string $addSQL additional SQL snippet
|
||||
* @param array $bindings bindings for SQL snippet
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function queryRecordCountRelated( $sourceType, $targetType, $linkID, $addSQL = '', $bindings = array() );
|
||||
|
||||
/**
|
||||
* Returns all rows of specified type that have been tagged with one of the
|
||||
* strings in the specified tag list array.
|
||||
*
|
||||
* Note that the additional SQL snippet can only be used for pagination,
|
||||
* the SQL snippet will be appended to the end of the query.
|
||||
*
|
||||
* @param string $type the bean type you want to query
|
||||
* @param array $tagList an array of strings, each string containing a tag title
|
||||
* @param boolean $all if TRUE only return records that have been associated with ALL the tags in the list
|
||||
* @param string $addSql addition SQL snippet, for pagination
|
||||
* @param array $bindings parameter bindings for additional SQL snippet
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function queryTagged( $type, $tagList, $all = FALSE, $addSql = '', $bindings = array() );
|
||||
|
||||
/**
|
||||
* This method should update (or insert a record), it takes
|
||||
* a table name, a list of update values ( $field => $value ) and an
|
||||
* primary key ID (optional). If no primary key ID is provided, an
|
||||
* INSERT will take place.
|
||||
* Returns the new ID.
|
||||
* This methods accepts a type and infers the corresponding table name.
|
||||
*
|
||||
* @param string $type name of the table to update
|
||||
* @param array $updatevalues list of update values
|
||||
* @param integer $id optional primary key ID value
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function updateRecord( $type, $updatevalues, $id = NULL );
|
||||
|
||||
/**
|
||||
* Deletes records from the database.
|
||||
* @note $addSql is always prefixed with ' WHERE ' or ' AND .'
|
||||
*
|
||||
* @param string $type name of the table you want to query
|
||||
* @param array $conditions criteria ( $column => array( $values ) )
|
||||
* @param string $sql additional SQL
|
||||
* @param array $bindings bindings
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function deleteRecord( $type, $conditions = array(), $addSql = '', $bindings = array() );
|
||||
|
||||
/**
|
||||
* Deletes all links between $sourceType and $destType in an N-M relation.
|
||||
*
|
||||
* @param string $sourceType source type
|
||||
* @param string $destType destination type
|
||||
* @param string $sourceID source ID
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function deleteRelations( $sourceType, $destType, $sourceID );
|
||||
|
||||
/**
|
||||
* @see QueryWriter::addUniqueConstaint
|
||||
*/
|
||||
public function addUniqueIndex( $type, $columns );
|
||||
|
||||
/**
|
||||
* This method will add a UNIQUE constraint index to a table on columns $columns.
|
||||
* This methods accepts a type and infers the corresponding table name.
|
||||
*
|
||||
* @param string $type target bean type
|
||||
* @param array $columnsPartOfIndex columns to include in index
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addUniqueConstraint( $type, $columns );
|
||||
|
||||
/**
|
||||
* This method will check whether the SQL state is in the list of specified states
|
||||
* and returns TRUE if it does appear in this list or FALSE if it
|
||||
* does not. The purpose of this method is to translate the database specific state to
|
||||
* a one of the constants defined in this class and then check whether it is in the list
|
||||
* of standard states provided.
|
||||
*
|
||||
* @param string $state SQL state to consider
|
||||
* @param array $list list of standardized SQL state constants to check against
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function sqlStateIn( $state, $list );
|
||||
|
||||
/**
|
||||
* This method will remove all beans of a certain type.
|
||||
* This methods accepts a type and infers the corresponding table name.
|
||||
*
|
||||
* @param string $type bean type
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function wipe( $type );
|
||||
|
||||
/**
|
||||
* This method will add a foreign key from type and field to
|
||||
* target type and target field.
|
||||
* The foreign key is created without an action. On delete/update
|
||||
* no action will be triggered. The FK is only used to allow database
|
||||
* tools to generate pretty diagrams and to make it easy to add actions
|
||||
* later on.
|
||||
* This methods accepts a type and infers the corresponding table name.
|
||||
*
|
||||
*
|
||||
* @param string $type type that will have a foreign key field
|
||||
* @param string $targetType points to this type
|
||||
* @param string $property field that contains the foreign key value
|
||||
* @param string $targetProperty field where the fk points to
|
||||
* @param string $isDep whether target is dependent and should cascade on update/delete
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addFK( $type, $targetType, $property, $targetProperty, $isDep = false );
|
||||
|
||||
/**
|
||||
* This method will add an index to a type and field with name
|
||||
* $name.
|
||||
* This methods accepts a type and infers the corresponding table name.
|
||||
*
|
||||
* @param string $type type to add index to
|
||||
* @param string $name name of the new index
|
||||
* @param string $property field to index
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addIndex( $type, $name, $property );
|
||||
|
||||
/**
|
||||
* Checks and filters a database structure element like a table of column
|
||||
* for safe use in a query. A database structure has to conform to the
|
||||
* RedBeanPHP DB security policy which basically means only alphanumeric
|
||||
* symbols are allowed. This security policy is more strict than conventional
|
||||
* SQL policies and does therefore not require database specific escaping rules.
|
||||
*
|
||||
* @param string $databaseStructure name of the column/table to check
|
||||
* @param boolean $noQuotes TRUE to NOT put backticks or quotes around the string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function esc( $databaseStructure, $dontQuote = FALSE );
|
||||
|
||||
/**
|
||||
* Removes all tables and views from the database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function wipeAll();
|
||||
|
||||
/**
|
||||
* Renames an association. For instance if you would like to refer to
|
||||
* album_song as: track you can specify this by calling this method like:
|
||||
*
|
||||
* <code>
|
||||
* renameAssociation('album_song','track')
|
||||
* </code>
|
||||
*
|
||||
* This allows:
|
||||
*
|
||||
* <code>
|
||||
* $album->sharedSong
|
||||
* </code>
|
||||
*
|
||||
* to add/retrieve beans from track instead of album_song.
|
||||
* Also works for exportAll().
|
||||
*
|
||||
* This method also accepts a single associative array as
|
||||
* its first argument.
|
||||
*
|
||||
* @param string|array $fromType original type name, or array
|
||||
* @param string $toType new type name (only if 1st argument is string)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function renameAssocTable( $fromType, $toType = NULL );
|
||||
|
||||
/**
|
||||
* Returns the format for link tables.
|
||||
* Given an array containing two type names this method returns the
|
||||
* name of the link table to be used to store and retrieve
|
||||
* association records. For instance, given two types: person and
|
||||
* project, the corresponding link table might be: 'person_project'.
|
||||
*
|
||||
* @param array $types two types array($type1, $type2)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAssocTable( $types );
|
||||
|
||||
/**
|
||||
* Given a bean type and a property, this method
|
||||
* tries to infer the fetch type using the foreign key
|
||||
* definitions in the database.
|
||||
* For instance: project, student -> person.
|
||||
* If no fetchType can be inferred, this method will return NULL.
|
||||
*
|
||||
* @note QueryWriters do not have to implement this method,
|
||||
* it's optional. A default version is available in AQueryWriter.
|
||||
*
|
||||
* @param $type the source type to fetch a target type for
|
||||
* @param $property the property to fetch the type of
|
||||
*
|
||||
* @return string|NULL
|
||||
*/
|
||||
public function inferFetchType( $type, $property );
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,351 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RedBeanPHP\QueryWriter;
|
||||
use RedBeanPHP\QueryWriter\AQueryWriter as AQueryWriter;
|
||||
use RedBeanPHP\QueryWriter as QueryWriter;
|
||||
use RedBeanPHP\Adapter\DBAdapter as DBAdapter;
|
||||
use RedBeanPHP\Adapter as Adapter;
|
||||
use RedBeanPHP\RedException\SQL as SQLException;
|
||||
|
||||
/**
|
||||
* RedBeanPHP CUBRID Writer.
|
||||
* This is a QueryWriter class for RedBeanPHP.
|
||||
* This QueryWriter provides support for the CUBRID database platform.
|
||||
*
|
||||
* @file RedBeanPHP/QueryWriter/CUBRID.php
|
||||
* @author Gabor de Mooij and the RedBeanPHP Community
|
||||
* @license BSD/GPLv2
|
||||
*
|
||||
* @copyright
|
||||
* (c) copyright G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community.
|
||||
* This source file is subject to the BSD/GPLv2 License that is bundled
|
||||
* with this source code in the file license.txt.
|
||||
*/
|
||||
class CUBRID extends AQueryWriter implements QueryWriter
|
||||
{
|
||||
/**
|
||||
* Data types
|
||||
*/
|
||||
const C_DATATYPE_INTEGER = 0;
|
||||
const C_DATATYPE_DOUBLE = 1;
|
||||
const C_DATATYPE_STRING = 2;
|
||||
const C_DATATYPE_SPECIAL_DATE = 80;
|
||||
const C_DATATYPE_SPECIAL_DATETIME = 81;
|
||||
const C_DATATYPE_SPECIFIED = 99;
|
||||
|
||||
/**
|
||||
* @var DBAdapter
|
||||
*/
|
||||
protected $adapter;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $quoteCharacter = '`';
|
||||
|
||||
/**
|
||||
* This method adds a foreign key from type and field to
|
||||
* target type and target field.
|
||||
* The foreign key is created without an action. On delete/update
|
||||
* no action will be triggered. The FK is only used to allow database
|
||||
* tools to generate pretty diagrams and to make it easy to add actions
|
||||
* later on.
|
||||
* This methods accepts a type and infers the corresponding table name.
|
||||
*
|
||||
* @param string $type type that will have a foreign key field
|
||||
* @param string $targetType points to this type
|
||||
* @param string $property field that contains the foreign key value
|
||||
* @param string $targetProperty field where the fk points to
|
||||
* @param bool $isDep
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function buildFK( $type, $targetType, $property, $targetProperty, $isDep = FALSE )
|
||||
{
|
||||
$table = $this->esc( $type );
|
||||
$tableNoQ = $this->esc( $type, TRUE );
|
||||
$targetTable = $this->esc( $targetType );
|
||||
$targetTableNoQ = $this->esc( $targetType, TRUE );
|
||||
$column = $this->esc( $property );
|
||||
$columnNoQ = $this->esc( $property, TRUE );
|
||||
$targetColumn = $this->esc( $targetProperty );
|
||||
if ( !is_null( $this->getForeignKeyForTypeProperty( $tableNoQ, $columnNoQ ) ) ) return FALSE;
|
||||
$needsToDropFK = FALSE;
|
||||
$casc = ( $isDep ? 'CASCADE' : 'SET NULL' );
|
||||
$sql = "ALTER TABLE $table ADD CONSTRAINT FOREIGN KEY($column) REFERENCES $targetTable($targetColumn) ON DELETE $casc ";
|
||||
try {
|
||||
$this->adapter->exec( $sql );
|
||||
} catch( SQLException $e ) {
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see AQueryWriter::getKeyMapForType
|
||||
*/
|
||||
protected function getKeyMapForType( $type )
|
||||
{
|
||||
$sqlCode = $this->adapter->get("SHOW CREATE TABLE `{$type}`");
|
||||
if (!isset($sqlCode[0])) return array();
|
||||
$matches = array();
|
||||
preg_match_all( '/CONSTRAINT\s+\[([\w_]+)\]\s+FOREIGN\s+KEY\s+\(\[([\w_]+)\]\)\s+REFERENCES\s+\[([\w_]+)\](\s+ON\s+DELETE\s+(CASCADE|SET\sNULL|RESTRICT|NO\sACTION)\s+ON\s+UPDATE\s+(SET\sNULL|RESTRICT|NO\sACTION))?/', $sqlCode[0]['CREATE TABLE'], $matches );
|
||||
$list = array();
|
||||
if (!isset($matches[0])) return $list;
|
||||
$max = count($matches[0]);
|
||||
for($i = 0; $i < $max; $i++) {
|
||||
$label = $this->makeFKLabel( $matches[2][$i], $matches[3][$i], 'id' );
|
||||
$list[ $label ] = array(
|
||||
'name' => $matches[1][$i],
|
||||
'from' => $matches[2][$i],
|
||||
'table' => $matches[3][$i],
|
||||
'to' => 'id',
|
||||
'on_update' => $matches[6][$i],
|
||||
'on_delete' => $matches[5][$i]
|
||||
);
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param Adapter $adapter Database Adapter
|
||||
*/
|
||||
public function __construct( Adapter $adapter )
|
||||
{
|
||||
$this->typeno_sqltype = array(
|
||||
CUBRID::C_DATATYPE_INTEGER => ' INTEGER ',
|
||||
CUBRID::C_DATATYPE_DOUBLE => ' DOUBLE ',
|
||||
CUBRID::C_DATATYPE_STRING => ' STRING ',
|
||||
CUBRID::C_DATATYPE_SPECIAL_DATE => ' DATE ',
|
||||
CUBRID::C_DATATYPE_SPECIAL_DATETIME => ' DATETIME ',
|
||||
);
|
||||
|
||||
$this->sqltype_typeno = array();
|
||||
|
||||
foreach ( $this->typeno_sqltype as $k => $v ) {
|
||||
$this->sqltype_typeno[trim( ( $v ) )] = $k;
|
||||
}
|
||||
|
||||
$this->sqltype_typeno['STRING(1073741823)'] = self::C_DATATYPE_STRING;
|
||||
|
||||
$this->adapter = $adapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the datatype to be used for primary key IDS and
|
||||
* foreign keys. Returns one if the data type constants.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getTypeForID()
|
||||
{
|
||||
return self::C_DATATYPE_INTEGER;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::getTables
|
||||
*/
|
||||
public function getTables()
|
||||
{
|
||||
$rows = $this->adapter->getCol( "SELECT class_name FROM db_class WHERE is_system_class = 'NO';" );
|
||||
|
||||
return $rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::createTable
|
||||
*/
|
||||
public function createTable( $table )
|
||||
{
|
||||
$sql = 'CREATE TABLE '
|
||||
. $this->esc( $table )
|
||||
. ' ("id" integer AUTO_INCREMENT, CONSTRAINT "pk_'
|
||||
. $this->esc( $table, TRUE )
|
||||
. '_id" PRIMARY KEY("id"))';
|
||||
|
||||
$this->adapter->exec( $sql );
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::getColumns
|
||||
*/
|
||||
public function getColumns( $table )
|
||||
{
|
||||
$table = $this->esc( $table );
|
||||
|
||||
$columnsRaw = $this->adapter->get( "SHOW COLUMNS FROM $table" );
|
||||
|
||||
$columns = array();
|
||||
foreach ( $columnsRaw as $r ) {
|
||||
$columns[$r['Field']] = $r['Type'];
|
||||
}
|
||||
|
||||
return $columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::scanType
|
||||
*/
|
||||
public function scanType( $value, $flagSpecial = FALSE )
|
||||
{
|
||||
$this->svalue = $value;
|
||||
|
||||
if ( is_null( $value ) ) {
|
||||
return self::C_DATATYPE_INTEGER;
|
||||
}
|
||||
|
||||
if ( $flagSpecial ) {
|
||||
if ( preg_match( '/^\d{4}\-\d\d-\d\d$/', $value ) ) {
|
||||
return self::C_DATATYPE_SPECIAL_DATE;
|
||||
}
|
||||
if ( preg_match( '/^\d{4}\-\d\d-\d\d\s\d\d:\d\d:\d\d$/', $value ) ) {
|
||||
return self::C_DATATYPE_SPECIAL_DATETIME;
|
||||
}
|
||||
}
|
||||
|
||||
$value = strval( $value );
|
||||
|
||||
if ( !$this->startsWithZeros( $value ) ) {
|
||||
if ( is_numeric( $value ) && ( floor( $value ) == $value ) && $value >= -2147483647 && $value <= 2147483647 ) {
|
||||
return self::C_DATATYPE_INTEGER;
|
||||
}
|
||||
if ( is_numeric( $value ) ) {
|
||||
return self::C_DATATYPE_DOUBLE;
|
||||
}
|
||||
}
|
||||
|
||||
return self::C_DATATYPE_STRING;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::code
|
||||
*/
|
||||
public function code( $typedescription, $includeSpecials = FALSE )
|
||||
{
|
||||
$r = ( ( isset( $this->sqltype_typeno[$typedescription] ) ) ? $this->sqltype_typeno[$typedescription] : self::C_DATATYPE_SPECIFIED );
|
||||
|
||||
if ( $includeSpecials ) {
|
||||
return $r;
|
||||
}
|
||||
|
||||
if ( $r >= QueryWriter::C_DATATYPE_RANGE_SPECIAL ) {
|
||||
return self::C_DATATYPE_SPECIFIED;
|
||||
}
|
||||
|
||||
return $r;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::addColumn
|
||||
*/
|
||||
public function addColumn( $type, $column, $field )
|
||||
{
|
||||
$table = $type;
|
||||
$type = $field;
|
||||
|
||||
$table = $this->esc( $table );
|
||||
$column = $this->esc( $column );
|
||||
|
||||
$type = array_key_exists( $type, $this->typeno_sqltype ) ? $this->typeno_sqltype[$type] : '';
|
||||
|
||||
$this->adapter->exec( "ALTER TABLE $table ADD COLUMN $column $type " );
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::addUniqueIndex
|
||||
*/
|
||||
public function addUniqueConstraint( $type, $properties )
|
||||
{
|
||||
$tableNoQ = $this->esc( $type, TRUE );
|
||||
$columns = array();
|
||||
foreach( $properties as $key => $column ) $columns[$key] = $this->esc( $column );
|
||||
$table = $this->esc( $type );
|
||||
sort( $columns ); // else we get multiple indexes due to order-effects
|
||||
$name = 'UQ_' . sha1( implode( ',', $columns ) );
|
||||
$sql = "ALTER TABLE $table ADD CONSTRAINT UNIQUE $name (" . implode( ',', $columns ) . ")";
|
||||
try {
|
||||
$this->adapter->exec( $sql );
|
||||
} catch( SQLException $e ) {
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::sqlStateIn
|
||||
*/
|
||||
public function sqlStateIn( $state, $list )
|
||||
{
|
||||
return ( $state == 'HY000' ) ? ( count( array_diff( array(
|
||||
QueryWriter::C_SQLSTATE_INTEGRITY_CONSTRAINT_VIOLATION,
|
||||
QueryWriter::C_SQLSTATE_NO_SUCH_COLUMN,
|
||||
QueryWriter::C_SQLSTATE_NO_SUCH_TABLE
|
||||
), $list ) ) !== 3 ) : FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::addIndex
|
||||
*/
|
||||
public function addIndex( $type, $name, $column )
|
||||
{
|
||||
try {
|
||||
$table = $this->esc( $type );
|
||||
$name = preg_replace( '/\W/', '', $name );
|
||||
$column = $this->esc( $column );
|
||||
$this->adapter->exec( "CREATE INDEX $name ON $table ($column) " );
|
||||
return TRUE;
|
||||
} catch ( SQLException $e ) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::addFK
|
||||
*/
|
||||
public function addFK( $type, $targetType, $property, $targetProperty, $isDependent = FALSE )
|
||||
{
|
||||
return $this->buildFK( $type, $targetType, $property, $targetProperty, $isDependent );
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::wipeAll
|
||||
*/
|
||||
public function wipeAll()
|
||||
{
|
||||
foreach ( $this->getTables() as $t ) {
|
||||
foreach ( $this->getKeyMapForType( $t ) as $k ) {
|
||||
$this->adapter->exec( "ALTER TABLE \"$t\" DROP FOREIGN KEY \"{$k['name']}\"" );
|
||||
}
|
||||
}
|
||||
foreach ( $this->getTables() as $t ) {
|
||||
$this->adapter->exec( "DROP TABLE \"$t\"" );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::esc
|
||||
*/
|
||||
public function esc( $dbStructure, $noQuotes = FALSE )
|
||||
{
|
||||
return parent::esc( strtolower( $dbStructure ), $noQuotes );
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::inferFetchType
|
||||
*/
|
||||
public function inferFetchType( $type, $property )
|
||||
{
|
||||
$table = $this->esc( $type, TRUE );
|
||||
$field = $this->esc( $property, TRUE ) . '_id';
|
||||
$keys = $this->getKeyMapForType( $table );
|
||||
|
||||
foreach( $keys as $key ) {
|
||||
if (
|
||||
$key['from'] === $field
|
||||
) return $key['table'];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
}
|
|
@ -1,375 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RedBeanPHP\QueryWriter;
|
||||
|
||||
use RedBeanPHP\QueryWriter\AQueryWriter as AQueryWriter;
|
||||
use RedBeanPHP\QueryWriter as QueryWriter;
|
||||
use RedBeanPHP\Adapter\DBAdapter as DBAdapter;
|
||||
use RedBeanPHP\Adapter as Adapter;
|
||||
use RedBeanPHP\RedException\SQL as SQLException;
|
||||
|
||||
/**
|
||||
* RedBeanPHP MySQLWriter.
|
||||
* This is a QueryWriter class for RedBeanPHP.
|
||||
* This QueryWriter provides support for the MySQL/MariaDB database platform.
|
||||
*
|
||||
* @file RedBeanPHP/QueryWriter/MySQL.php
|
||||
* @author Gabor de Mooij and the RedBeanPHP Community
|
||||
* @license BSD/GPLv2
|
||||
*
|
||||
* @copyright
|
||||
* (c) G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community.
|
||||
* This source file is subject to the BSD/GPLv2 License that is bundled
|
||||
* with this source code in the file license.txt.
|
||||
*/
|
||||
class MySQL extends AQueryWriter implements QueryWriter
|
||||
{
|
||||
/**
|
||||
* Data types
|
||||
*/
|
||||
const C_DATATYPE_BOOL = 0;
|
||||
const C_DATATYPE_UINT32 = 2;
|
||||
const C_DATATYPE_DOUBLE = 3;
|
||||
const C_DATATYPE_TEXT7 = 4; //InnoDB cant index varchar(255) utf8mb4 - so keep 191 as long as possible
|
||||
const C_DATATYPE_TEXT8 = 5;
|
||||
const C_DATATYPE_TEXT16 = 6;
|
||||
const C_DATATYPE_TEXT32 = 7;
|
||||
const C_DATATYPE_SPECIAL_DATE = 80;
|
||||
const C_DATATYPE_SPECIAL_DATETIME = 81;
|
||||
const C_DATATYPE_SPECIAL_POINT = 90;
|
||||
const C_DATATYPE_SPECIAL_LINESTRING = 91;
|
||||
const C_DATATYPE_SPECIAL_POLYGON = 92;
|
||||
const C_DATATYPE_SPECIAL_MONEY = 93;
|
||||
|
||||
const C_DATATYPE_SPECIFIED = 99;
|
||||
|
||||
/**
|
||||
* @var DBAdapter
|
||||
*/
|
||||
protected $adapter;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $quoteCharacter = '`';
|
||||
|
||||
/**
|
||||
* @see AQueryWriter::getKeyMapForType
|
||||
*/
|
||||
protected function getKeyMapForType( $type )
|
||||
{
|
||||
$databaseName = $this->adapter->getCell('SELECT DATABASE()');
|
||||
$table = $this->esc( $type, TRUE );
|
||||
$keys = $this->adapter->get('
|
||||
SELECT
|
||||
information_schema.key_column_usage.constraint_name AS `name`,
|
||||
information_schema.key_column_usage.referenced_table_name AS `table`,
|
||||
information_schema.key_column_usage.column_name AS `from`,
|
||||
information_schema.key_column_usage.referenced_column_name AS `to`,
|
||||
information_schema.referential_constraints.update_rule AS `on_update`,
|
||||
information_schema.referential_constraints.delete_rule AS `on_delete`
|
||||
FROM information_schema.key_column_usage
|
||||
INNER JOIN information_schema.referential_constraints
|
||||
ON information_schema.referential_constraints.constraint_name = information_schema.key_column_usage.constraint_name
|
||||
WHERE
|
||||
information_schema.key_column_usage.table_schema = :database
|
||||
AND information_schema.referential_constraints.constraint_schema = :database
|
||||
AND information_schema.key_column_usage.constraint_schema = :database
|
||||
AND information_schema.key_column_usage.table_name = :table
|
||||
AND information_schema.key_column_usage.constraint_name != \'PRIMARY\'
|
||||
AND information_schema.key_column_usage.referenced_table_name IS NOT NULL
|
||||
', array( ':database' => $databaseName, ':table' => $table ) );
|
||||
$keyInfoList = array();
|
||||
foreach ( $keys as $k ) {
|
||||
$label = $this->makeFKLabel( $k['from'], $k['table'], $k['to'] );
|
||||
$keyInfoList[$label] = array(
|
||||
'name' => $k['name'],
|
||||
'from' => $k['from'],
|
||||
'table' => $k['table'],
|
||||
'to' => $k['to'],
|
||||
'on_update' => $k['on_update'],
|
||||
'on_delete' => $k['on_delete']
|
||||
);
|
||||
}
|
||||
return $keyInfoList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param Adapter $adapter Database Adapter
|
||||
*/
|
||||
public function __construct( Adapter $adapter )
|
||||
{
|
||||
$this->typeno_sqltype = array(
|
||||
MySQL::C_DATATYPE_BOOL => ' TINYINT(1) UNSIGNED ',
|
||||
MySQL::C_DATATYPE_UINT32 => ' INT(11) UNSIGNED ',
|
||||
MySQL::C_DATATYPE_DOUBLE => ' DOUBLE ',
|
||||
MySQL::C_DATATYPE_TEXT7 => ' VARCHAR(191) ',
|
||||
MYSQL::C_DATATYPE_TEXT8 => ' VARCHAR(255) ',
|
||||
MySQL::C_DATATYPE_TEXT16 => ' TEXT ',
|
||||
MySQL::C_DATATYPE_TEXT32 => ' LONGTEXT ',
|
||||
MySQL::C_DATATYPE_SPECIAL_DATE => ' DATE ',
|
||||
MySQL::C_DATATYPE_SPECIAL_DATETIME => ' DATETIME ',
|
||||
MySQL::C_DATATYPE_SPECIAL_POINT => ' POINT ',
|
||||
MySQL::C_DATATYPE_SPECIAL_LINESTRING => ' LINESTRING ',
|
||||
MySQL::C_DATATYPE_SPECIAL_POLYGON => ' POLYGON ',
|
||||
MySQL::C_DATATYPE_SPECIAL_MONEY => ' DECIMAL(10,2) '
|
||||
);
|
||||
|
||||
$this->sqltype_typeno = array();
|
||||
|
||||
foreach ( $this->typeno_sqltype as $k => $v ) {
|
||||
$this->sqltype_typeno[trim( strtolower( $v ) )] = $k;
|
||||
}
|
||||
|
||||
$this->adapter = $adapter;
|
||||
|
||||
$this->encoding = $this->adapter->getDatabase()->getMysqlEncoding();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the datatype to be used for primary key IDS and
|
||||
* foreign keys. Returns one if the data type constants.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getTypeForID()
|
||||
{
|
||||
return self::C_DATATYPE_UINT32;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::getTables
|
||||
*/
|
||||
public function getTables()
|
||||
{
|
||||
return $this->adapter->getCol( 'show tables' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::createTable
|
||||
*/
|
||||
public function createTable( $table )
|
||||
{
|
||||
$table = $this->esc( $table );
|
||||
|
||||
$encoding = $this->adapter->getDatabase()->getMysqlEncoding();
|
||||
$sql = "CREATE TABLE $table (id INT( 11 ) UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARY KEY ( id )) ENGINE = InnoDB DEFAULT CHARSET={$encoding} COLLATE={$encoding}_unicode_ci ";
|
||||
|
||||
$this->adapter->exec( $sql );
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::getColumns
|
||||
*/
|
||||
public function getColumns( $table )
|
||||
{
|
||||
$columnsRaw = $this->adapter->get( "DESCRIBE " . $this->esc( $table ) );
|
||||
|
||||
$columns = array();
|
||||
foreach ( $columnsRaw as $r ) {
|
||||
$columns[$r['Field']] = $r['Type'];
|
||||
}
|
||||
|
||||
return $columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::scanType
|
||||
*/
|
||||
public function scanType( $value, $flagSpecial = FALSE )
|
||||
{
|
||||
$this->svalue = $value;
|
||||
|
||||
if ( is_null( $value ) ) return MySQL::C_DATATYPE_BOOL;
|
||||
if ( $value === INF ) return MySQL::C_DATATYPE_TEXT7;
|
||||
|
||||
if ( $flagSpecial ) {
|
||||
if ( preg_match( '/^-?\d+\.\d{2}$/', $value ) ) {
|
||||
return MySQL::C_DATATYPE_SPECIAL_MONEY;
|
||||
}
|
||||
if ( preg_match( '/^\d{4}\-\d\d-\d\d$/', $value ) ) {
|
||||
return MySQL::C_DATATYPE_SPECIAL_DATE;
|
||||
}
|
||||
if ( preg_match( '/^\d{4}\-\d\d-\d\d\s\d\d:\d\d:\d\d$/', $value ) ) {
|
||||
return MySQL::C_DATATYPE_SPECIAL_DATETIME;
|
||||
}
|
||||
if ( preg_match( '/^POINT\(/', $value ) ) {
|
||||
return MySQL::C_DATATYPE_SPECIAL_POINT;
|
||||
}
|
||||
if ( preg_match( '/^LINESTRING\(/', $value ) ) {
|
||||
return MySQL::C_DATATYPE_SPECIAL_LINESTRING;
|
||||
}
|
||||
if ( preg_match( '/^POLYGON\(/', $value ) ) {
|
||||
return MySQL::C_DATATYPE_SPECIAL_POLYGON;
|
||||
}
|
||||
}
|
||||
|
||||
//setter turns TRUE FALSE into 0 and 1 because database has no real bools (TRUE and FALSE only for test?).
|
||||
if ( $value === FALSE || $value === TRUE || $value === '0' || $value === '1' ) {
|
||||
return MySQL::C_DATATYPE_BOOL;
|
||||
}
|
||||
|
||||
if ( is_float( $value ) ) return self::C_DATATYPE_DOUBLE;
|
||||
|
||||
if ( !$this->startsWithZeros( $value ) ) {
|
||||
|
||||
if ( is_numeric( $value ) && ( floor( $value ) == $value ) && $value >= 0 && $value <= 4294967295 ) {
|
||||
return MySQL::C_DATATYPE_UINT32;
|
||||
}
|
||||
|
||||
if ( is_numeric( $value ) ) {
|
||||
return MySQL::C_DATATYPE_DOUBLE;
|
||||
}
|
||||
}
|
||||
|
||||
if ( mb_strlen( $value, 'UTF-8' ) <= 191 ) {
|
||||
return MySQL::C_DATATYPE_TEXT7;
|
||||
}
|
||||
|
||||
if ( mb_strlen( $value, 'UTF-8' ) <= 255 ) {
|
||||
return MySQL::C_DATATYPE_TEXT8;
|
||||
}
|
||||
|
||||
if ( mb_strlen( $value, 'UTF-8' ) <= 65535 ) {
|
||||
return MySQL::C_DATATYPE_TEXT16;
|
||||
}
|
||||
|
||||
return MySQL::C_DATATYPE_TEXT32;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::code
|
||||
*/
|
||||
public function code( $typedescription, $includeSpecials = FALSE )
|
||||
{
|
||||
if ( isset( $this->sqltype_typeno[$typedescription] ) ) {
|
||||
$r = $this->sqltype_typeno[$typedescription];
|
||||
} else {
|
||||
$r = self::C_DATATYPE_SPECIFIED;
|
||||
}
|
||||
|
||||
if ( $includeSpecials ) {
|
||||
return $r;
|
||||
}
|
||||
|
||||
if ( $r >= QueryWriter::C_DATATYPE_RANGE_SPECIAL ) {
|
||||
return self::C_DATATYPE_SPECIFIED;
|
||||
}
|
||||
|
||||
return $r;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::addUniqueIndex
|
||||
*/
|
||||
public function addUniqueConstraint( $type, $properties )
|
||||
{
|
||||
$tableNoQ = $this->esc( $type, TRUE );
|
||||
$columns = array();
|
||||
foreach( $properties as $key => $column ) $columns[$key] = $this->esc( $column );
|
||||
$table = $this->esc( $type );
|
||||
sort( $columns ); // Else we get multiple indexes due to order-effects
|
||||
$name = 'UQ_' . sha1( implode( ',', $columns ) );
|
||||
try {
|
||||
$sql = "ALTER TABLE $table
|
||||
ADD UNIQUE INDEX $name (" . implode( ',', $columns ) . ")";
|
||||
$this->adapter->exec( $sql );
|
||||
} catch ( SQLException $e ) {
|
||||
//do nothing, dont use alter table ignore, this will delete duplicate records in 3-ways!
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::addIndex
|
||||
*/
|
||||
public function addIndex( $type, $name, $property )
|
||||
{
|
||||
try {
|
||||
$table = $this->esc( $type );
|
||||
$name = preg_replace( '/\W/', '', $name );
|
||||
$column = $this->esc( $property );
|
||||
$this->adapter->exec( "CREATE INDEX $name ON $table ($column) " );
|
||||
return TRUE;
|
||||
} catch ( SQLException $e ) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::addFK
|
||||
* @return bool
|
||||
*/
|
||||
public function addFK( $type, $targetType, $property, $targetProperty, $isDependent = FALSE )
|
||||
{
|
||||
$table = $this->esc( $type );
|
||||
$targetTable = $this->esc( $targetType );
|
||||
$targetTableNoQ = $this->esc( $targetType, TRUE );
|
||||
$field = $this->esc( $property );
|
||||
$fieldNoQ = $this->esc( $property, TRUE );
|
||||
$targetField = $this->esc( $targetProperty );
|
||||
$targetFieldNoQ = $this->esc( $targetProperty, TRUE );
|
||||
$tableNoQ = $this->esc( $type, TRUE );
|
||||
$fieldNoQ = $this->esc( $property, TRUE );
|
||||
if ( !is_null( $this->getForeignKeyForTypeProperty( $tableNoQ, $fieldNoQ ) ) ) return FALSE;
|
||||
|
||||
//Widen the column if it's incapable of representing a foreign key (at least INT).
|
||||
$columns = $this->getColumns( $tableNoQ );
|
||||
$idType = $this->getTypeForID();
|
||||
if ( $this->code( $columns[$fieldNoQ] ) !== $idType ) {
|
||||
$this->widenColumn( $type, $property, $idType );
|
||||
}
|
||||
|
||||
$fkName = 'fk_'.($tableNoQ.'_'.$fieldNoQ);
|
||||
$cName = 'c_'.$fkName;
|
||||
try {
|
||||
$this->adapter->exec( "
|
||||
ALTER TABLE {$table}
|
||||
ADD CONSTRAINT $cName
|
||||
FOREIGN KEY $fkName ( {$fieldNoQ} ) REFERENCES {$targetTableNoQ}
|
||||
({$targetFieldNoQ}) ON DELETE " . ( $isDependent ? 'CASCADE' : 'SET NULL' ) . ' ON UPDATE '.( $isDependent ? 'CASCADE' : 'SET NULL' ).';');
|
||||
} catch ( SQLException $e ) {
|
||||
// Failure of fk-constraints is not a problem
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::sqlStateIn
|
||||
*/
|
||||
public function sqlStateIn( $state, $list )
|
||||
{
|
||||
$stateMap = array(
|
||||
'42S02' => QueryWriter::C_SQLSTATE_NO_SUCH_TABLE,
|
||||
'42S22' => QueryWriter::C_SQLSTATE_NO_SUCH_COLUMN,
|
||||
'23000' => QueryWriter::C_SQLSTATE_INTEGRITY_CONSTRAINT_VIOLATION
|
||||
);
|
||||
|
||||
return in_array( ( isset( $stateMap[$state] ) ? $stateMap[$state] : '0' ), $list );
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::wipeAll
|
||||
*/
|
||||
public function wipeAll()
|
||||
{
|
||||
$this->adapter->exec( 'SET FOREIGN_KEY_CHECKS = 0;' );
|
||||
|
||||
foreach ( $this->getTables() as $t ) {
|
||||
try {
|
||||
$this->adapter->exec( "DROP TABLE IF EXISTS `$t`" );
|
||||
} catch ( SQLException $e ) {
|
||||
}
|
||||
|
||||
try {
|
||||
$this->adapter->exec( "DROP VIEW IF EXISTS `$t`" );
|
||||
} catch ( SQLException $e ) {
|
||||
}
|
||||
}
|
||||
|
||||
$this->adapter->exec( 'SET FOREIGN_KEY_CHECKS = 1;' );
|
||||
}
|
||||
}
|
|
@ -1,381 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RedBeanPHP\QueryWriter;
|
||||
|
||||
use RedBeanPHP\QueryWriter\AQueryWriter as AQueryWriter;
|
||||
use RedBeanPHP\QueryWriter as QueryWriter;
|
||||
use RedBeanPHP\Adapter\DBAdapter as DBAdapter;
|
||||
use RedBeanPHP\Adapter as Adapter;
|
||||
use RedBeanPHP\RedException\SQL as SQLException;
|
||||
|
||||
/**
|
||||
* RedBeanPHP PostgreSQL Query Writer.
|
||||
* This is a QueryWriter class for RedBeanPHP.
|
||||
* This QueryWriter provides support for the PostgreSQL database platform.
|
||||
*
|
||||
* @file RedBeanPHP/QueryWriter/PostgreSQL.php
|
||||
* @author Gabor de Mooij and the RedBeanPHP Community
|
||||
* @license BSD/GPLv2
|
||||
*
|
||||
* @copyright
|
||||
* (c) copyright G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community.
|
||||
* This source file is subject to the BSD/GPLv2 License that is bundled
|
||||
* with this source code in the file license.txt.
|
||||
*/
|
||||
class PostgreSQL extends AQueryWriter implements QueryWriter
|
||||
{
|
||||
/**
|
||||
* Data types
|
||||
*/
|
||||
const C_DATATYPE_INTEGER = 0;
|
||||
const C_DATATYPE_DOUBLE = 1;
|
||||
const C_DATATYPE_TEXT = 3;
|
||||
const C_DATATYPE_SPECIAL_DATE = 80;
|
||||
const C_DATATYPE_SPECIAL_DATETIME = 81;
|
||||
const C_DATATYPE_SPECIAL_POINT = 90;
|
||||
const C_DATATYPE_SPECIAL_LSEG = 91;
|
||||
const C_DATATYPE_SPECIAL_CIRCLE = 92;
|
||||
const C_DATATYPE_SPECIAL_MONEY = 93;
|
||||
const C_DATATYPE_SPECIAL_POLYGON = 94;
|
||||
const C_DATATYPE_SPECIAL_MONEY2 = 95; //Numbers only money, i.e. fixed point numeric
|
||||
const C_DATATYPE_SPECIFIED = 99;
|
||||
|
||||
/**
|
||||
* @var DBAdapter
|
||||
*/
|
||||
protected $adapter;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $quoteCharacter = '"';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $defaultValue = 'DEFAULT';
|
||||
|
||||
/**
|
||||
* Returns the insert suffix SQL Snippet
|
||||
*
|
||||
* @param string $table table
|
||||
*
|
||||
* @return string $sql SQL Snippet
|
||||
*/
|
||||
protected function getInsertSuffix( $table )
|
||||
{
|
||||
return 'RETURNING id ';
|
||||
}
|
||||
|
||||
/**
|
||||
* @see AQueryWriter::getKeyMapForType
|
||||
*/
|
||||
protected function getKeyMapForType( $type )
|
||||
{
|
||||
$table = $this->esc( $type, TRUE );
|
||||
$keys = $this->adapter->get( '
|
||||
SELECT
|
||||
information_schema.key_column_usage.constraint_name AS "name",
|
||||
information_schema.key_column_usage.column_name AS "from",
|
||||
information_schema.constraint_table_usage.table_name AS "table",
|
||||
information_schema.constraint_column_usage.column_name AS "to",
|
||||
information_schema.referential_constraints.update_rule AS "on_update",
|
||||
information_schema.referential_constraints.delete_rule AS "on_delete"
|
||||
FROM information_schema.key_column_usage
|
||||
INNER JOIN information_schema.constraint_table_usage
|
||||
ON (
|
||||
information_schema.key_column_usage.constraint_name = information_schema.constraint_table_usage.constraint_name
|
||||
AND information_schema.key_column_usage.constraint_schema = information_schema.constraint_table_usage.constraint_schema
|
||||
AND information_schema.key_column_usage.constraint_catalog = information_schema.constraint_table_usage.constraint_catalog
|
||||
)
|
||||
INNER JOIN information_schema.constraint_column_usage
|
||||
ON (
|
||||
information_schema.key_column_usage.constraint_name = information_schema.constraint_column_usage.constraint_name
|
||||
AND information_schema.key_column_usage.constraint_schema = information_schema.constraint_column_usage.constraint_schema
|
||||
AND information_schema.key_column_usage.constraint_catalog = information_schema.constraint_column_usage.constraint_catalog
|
||||
)
|
||||
INNER JOIN information_schema.referential_constraints
|
||||
ON (
|
||||
information_schema.key_column_usage.constraint_name = information_schema.referential_constraints.constraint_name
|
||||
AND information_schema.key_column_usage.constraint_schema = information_schema.referential_constraints.constraint_schema
|
||||
AND information_schema.key_column_usage.constraint_catalog = information_schema.referential_constraints.constraint_catalog
|
||||
)
|
||||
WHERE
|
||||
information_schema.key_column_usage.table_catalog = current_database()
|
||||
AND information_schema.key_column_usage.table_schema = ANY( current_schemas( FALSE ) )
|
||||
AND information_schema.key_column_usage.table_name = ?
|
||||
', array( $type ) );
|
||||
$keyInfoList = array();
|
||||
foreach ( $keys as $k ) {
|
||||
$label = $this->makeFKLabel( $k['from'], $k['table'], $k['to'] );
|
||||
$keyInfoList[$label] = array(
|
||||
'name' => $k['name'],
|
||||
'from' => $k['from'],
|
||||
'table' => $k['table'],
|
||||
'to' => $k['to'],
|
||||
'on_update' => $k['on_update'],
|
||||
'on_delete' => $k['on_delete']
|
||||
);
|
||||
}
|
||||
return $keyInfoList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param Adapter $adapter Database Adapter
|
||||
*/
|
||||
public function __construct( Adapter $adapter )
|
||||
{
|
||||
$this->typeno_sqltype = array(
|
||||
self::C_DATATYPE_INTEGER => ' integer ',
|
||||
self::C_DATATYPE_DOUBLE => ' double precision ',
|
||||
self::C_DATATYPE_TEXT => ' text ',
|
||||
self::C_DATATYPE_SPECIAL_DATE => ' date ',
|
||||
self::C_DATATYPE_SPECIAL_DATETIME => ' timestamp without time zone ',
|
||||
self::C_DATATYPE_SPECIAL_POINT => ' point ',
|
||||
self::C_DATATYPE_SPECIAL_LSEG => ' lseg ',
|
||||
self::C_DATATYPE_SPECIAL_CIRCLE => ' circle ',
|
||||
self::C_DATATYPE_SPECIAL_MONEY => ' money ',
|
||||
self::C_DATATYPE_SPECIAL_MONEY2 => ' numeric(10,2) ',
|
||||
self::C_DATATYPE_SPECIAL_POLYGON => ' polygon ',
|
||||
);
|
||||
|
||||
$this->sqltype_typeno = array();
|
||||
|
||||
foreach ( $this->typeno_sqltype as $k => $v ) {
|
||||
$this->sqltype_typeno[trim( strtolower( $v ) )] = $k;
|
||||
}
|
||||
|
||||
$this->adapter = $adapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the datatype to be used for primary key IDS and
|
||||
* foreign keys. Returns one if the data type constants.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getTypeForID()
|
||||
{
|
||||
return self::C_DATATYPE_INTEGER;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::getTables
|
||||
*/
|
||||
public function getTables()
|
||||
{
|
||||
return $this->adapter->getCol( 'SELECT table_name FROM information_schema.tables WHERE table_schema = ANY( current_schemas( FALSE ) )' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::createTable
|
||||
*/
|
||||
public function createTable( $table )
|
||||
{
|
||||
$table = $this->esc( $table );
|
||||
|
||||
$this->adapter->exec( " CREATE TABLE $table (id SERIAL PRIMARY KEY); " );
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::getColumns
|
||||
*/
|
||||
public function getColumns( $table )
|
||||
{
|
||||
$table = $this->esc( $table, TRUE );
|
||||
|
||||
$columnsRaw = $this->adapter->get( "SELECT column_name, data_type FROM information_schema.columns WHERE table_name='$table' AND table_schema = ANY( current_schemas( FALSE ) )" );
|
||||
|
||||
$columns = array();
|
||||
foreach ( $columnsRaw as $r ) {
|
||||
$columns[$r['column_name']] = $r['data_type'];
|
||||
}
|
||||
|
||||
return $columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::scanType
|
||||
*/
|
||||
public function scanType( $value, $flagSpecial = FALSE )
|
||||
{
|
||||
$this->svalue = $value;
|
||||
|
||||
if ( $value === INF ) return self::C_DATATYPE_TEXT;
|
||||
|
||||
if ( $flagSpecial && $value ) {
|
||||
if ( preg_match( '/^\d{4}\-\d\d-\d\d$/', $value ) ) {
|
||||
return PostgreSQL::C_DATATYPE_SPECIAL_DATE;
|
||||
}
|
||||
|
||||
if ( preg_match( '/^\d{4}\-\d\d-\d\d\s\d\d:\d\d:\d\d(\.\d{1,6})?$/', $value ) ) {
|
||||
return PostgreSQL::C_DATATYPE_SPECIAL_DATETIME;
|
||||
}
|
||||
|
||||
if ( preg_match( '/^\([\d\.]+,[\d\.]+\)$/', $value ) ) {
|
||||
return PostgreSQL::C_DATATYPE_SPECIAL_POINT;
|
||||
}
|
||||
|
||||
if ( preg_match( '/^\[\([\d\.]+,[\d\.]+\),\([\d\.]+,[\d\.]+\)\]$/', $value ) ) {
|
||||
return PostgreSQL::C_DATATYPE_SPECIAL_LSEG;
|
||||
}
|
||||
|
||||
if ( preg_match( '/^\<\([\d\.]+,[\d\.]+\),[\d\.]+\>$/', $value ) ) {
|
||||
return PostgreSQL::C_DATATYPE_SPECIAL_CIRCLE;
|
||||
}
|
||||
|
||||
if ( preg_match( '/^\((\([\d\.]+,[\d\.]+\),?)+\)$/', $value ) ) {
|
||||
return PostgreSQL::C_DATATYPE_SPECIAL_POLYGON;
|
||||
}
|
||||
|
||||
if ( preg_match( '/^\-?(\$|€|¥|£)[\d,\.]+$/', $value ) ) {
|
||||
return PostgreSQL::C_DATATYPE_SPECIAL_MONEY;
|
||||
}
|
||||
|
||||
if ( preg_match( '/^-?\d+\.\d{2}$/', $value ) ) {
|
||||
return PostgreSQL::C_DATATYPE_SPECIAL_MONEY2;
|
||||
}
|
||||
}
|
||||
|
||||
if ( is_float( $value ) ) return self::C_DATATYPE_DOUBLE;
|
||||
|
||||
if ( $this->startsWithZeros( $value ) ) return self::C_DATATYPE_TEXT;
|
||||
|
||||
if ( $value === FALSE || $value === TRUE || $value === NULL || ( is_numeric( $value )
|
||||
&& AQueryWriter::canBeTreatedAsInt( $value )
|
||||
&& $value < 2147483648
|
||||
&& $value > -2147483648 )
|
||||
) {
|
||||
return self::C_DATATYPE_INTEGER;
|
||||
} elseif ( is_numeric( $value ) ) {
|
||||
return self::C_DATATYPE_DOUBLE;
|
||||
} else {
|
||||
return self::C_DATATYPE_TEXT;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::code
|
||||
*/
|
||||
public function code( $typedescription, $includeSpecials = FALSE )
|
||||
{
|
||||
$r = ( isset( $this->sqltype_typeno[$typedescription] ) ) ? $this->sqltype_typeno[$typedescription] : 99;
|
||||
|
||||
if ( $includeSpecials ) return $r;
|
||||
|
||||
if ( $r >= QueryWriter::C_DATATYPE_RANGE_SPECIAL ) {
|
||||
return self::C_DATATYPE_SPECIFIED;
|
||||
}
|
||||
|
||||
return $r;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::widenColumn
|
||||
*/
|
||||
public function widenColumn( $type, $column, $datatype )
|
||||
{
|
||||
$table = $type;
|
||||
$type = $datatype;
|
||||
|
||||
$table = $this->esc( $table );
|
||||
$column = $this->esc( $column );
|
||||
|
||||
$newtype = $this->typeno_sqltype[$type];
|
||||
|
||||
$this->adapter->exec( "ALTER TABLE $table \n\t ALTER COLUMN $column TYPE $newtype " );
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::addUniqueIndex
|
||||
*/
|
||||
public function addUniqueConstraint( $type, $properties )
|
||||
{
|
||||
$tableNoQ = $this->esc( $type, TRUE );
|
||||
$columns = array();
|
||||
foreach( $properties as $key => $column ) $columns[$key] = $this->esc( $column );
|
||||
$table = $this->esc( $type );
|
||||
sort( $columns ); //else we get multiple indexes due to order-effects
|
||||
$name = "UQ_" . sha1( $table . implode( ',', $columns ) );
|
||||
$sql = "ALTER TABLE {$table}
|
||||
ADD CONSTRAINT $name UNIQUE (" . implode( ',', $columns ) . ")";
|
||||
try {
|
||||
$this->adapter->exec( $sql );
|
||||
} catch( SQLException $e ) {
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::sqlStateIn
|
||||
*/
|
||||
public function sqlStateIn( $state, $list )
|
||||
{
|
||||
$stateMap = array(
|
||||
'42P01' => QueryWriter::C_SQLSTATE_NO_SUCH_TABLE,
|
||||
'42703' => QueryWriter::C_SQLSTATE_NO_SUCH_COLUMN,
|
||||
'23505' => QueryWriter::C_SQLSTATE_INTEGRITY_CONSTRAINT_VIOLATION
|
||||
);
|
||||
|
||||
return in_array( ( isset( $stateMap[$state] ) ? $stateMap[$state] : '0' ), $list );
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::addIndex
|
||||
*/
|
||||
public function addIndex( $type, $name, $property )
|
||||
{
|
||||
$table = $this->esc( $type );
|
||||
$name = preg_replace( '/\W/', '', $name );
|
||||
$column = $this->esc( $property );
|
||||
|
||||
try {
|
||||
$this->adapter->exec( "CREATE INDEX {$name} ON $table ({$column}) " );
|
||||
return TRUE;
|
||||
} catch ( SQLException $e ) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::addFK
|
||||
*/
|
||||
public function addFK( $type, $targetType, $property, $targetProperty, $isDep = FALSE )
|
||||
{
|
||||
$table = $this->esc( $type );
|
||||
$targetTable = $this->esc( $targetType );
|
||||
$field = $this->esc( $property );
|
||||
$targetField = $this->esc( $targetProperty );
|
||||
$tableNoQ = $this->esc( $type, TRUE );
|
||||
$fieldNoQ = $this->esc( $property, TRUE );
|
||||
if ( !is_null( $this->getForeignKeyForTypeProperty( $tableNoQ, $fieldNoQ ) ) ) return FALSE;
|
||||
try{
|
||||
$delRule = ( $isDep ? 'CASCADE' : 'SET NULL' );
|
||||
$this->adapter->exec( "ALTER TABLE {$table}
|
||||
ADD FOREIGN KEY ( {$field} ) REFERENCES {$targetTable}
|
||||
({$targetField}) ON DELETE {$delRule} ON UPDATE {$delRule} DEFERRABLE ;" );
|
||||
return TRUE;
|
||||
} catch ( SQLException $e ) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::wipeAll
|
||||
*/
|
||||
public function wipeAll()
|
||||
{
|
||||
$this->adapter->exec( 'SET CONSTRAINTS ALL DEFERRED' );
|
||||
|
||||
foreach ( $this->getTables() as $t ) {
|
||||
$t = $this->esc( $t );
|
||||
|
||||
$this->adapter->exec( "DROP TABLE IF EXISTS $t CASCADE " );
|
||||
}
|
||||
|
||||
$this->adapter->exec( 'SET CONSTRAINTS ALL IMMEDIATE' );
|
||||
}
|
||||
}
|
|
@ -1,437 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RedBeanPHP\QueryWriter;
|
||||
|
||||
use RedBeanPHP\QueryWriter\AQueryWriter as AQueryWriter;
|
||||
use RedBeanPHP\QueryWriter as QueryWriter;
|
||||
use RedBeanPHP\Adapter\DBAdapter as DBAdapter;
|
||||
use RedBeanPHP\Adapter as Adapter;
|
||||
use RedBeanPHP\RedException\SQL as SQLException;
|
||||
|
||||
/**
|
||||
* RedBeanPHP SQLiteWriter with support for SQLite types
|
||||
* This is a QueryWriter class for RedBeanPHP.
|
||||
* This QueryWriter provides support for the SQLite database platform.
|
||||
*
|
||||
* @file RedBeanPHP/QueryWriter/SQLiteT.php
|
||||
* @author Gabor de Mooij and the RedBeanPHP Community
|
||||
* @license BSD/GPLv2
|
||||
*
|
||||
* @copyright
|
||||
* (c) copyright G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community.
|
||||
* This source file is subject to the BSD/GPLv2 License that is bundled
|
||||
* with this source code in the file license.txt.
|
||||
*/
|
||||
class SQLiteT extends AQueryWriter implements QueryWriter
|
||||
{
|
||||
/**
|
||||
* Data types
|
||||
*/
|
||||
const C_DATATYPE_INTEGER = 0;
|
||||
const C_DATATYPE_NUMERIC = 1;
|
||||
const C_DATATYPE_TEXT = 2;
|
||||
const C_DATATYPE_SPECIFIED = 99;
|
||||
|
||||
/**
|
||||
* @var DBAdapter
|
||||
*/
|
||||
protected $adapter;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $quoteCharacter = '`';
|
||||
|
||||
/**
|
||||
* Gets all information about a table (from a type).
|
||||
*
|
||||
* Format:
|
||||
* array(
|
||||
* name => name of the table
|
||||
* columns => array( name => datatype )
|
||||
* indexes => array() raw index information rows from PRAGMA query
|
||||
* keys => array() raw key information rows from PRAGMA query
|
||||
* )
|
||||
*
|
||||
* @param string $type type you want to get info of
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getTable( $type )
|
||||
{
|
||||
$tableName = $this->esc( $type, TRUE );
|
||||
$columns = $this->getColumns( $type );
|
||||
$indexes = $this->getIndexes( $type );
|
||||
$keys = $this->getKeyMapForType( $type );
|
||||
|
||||
$table = array(
|
||||
'columns' => $columns,
|
||||
'indexes' => $indexes,
|
||||
'keys' => $keys,
|
||||
'name' => $tableName
|
||||
);
|
||||
|
||||
$this->tableArchive[$tableName] = $table;
|
||||
|
||||
return $table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts a table. Updates the table structure.
|
||||
* In SQLite we can't change columns, drop columns, change or add foreign keys so we
|
||||
* have a table-rebuild function. You simply load your table with getTable(), modify it and
|
||||
* then store it with putTable()...
|
||||
*
|
||||
* @param array $tableMap information array
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function putTable( $tableMap )
|
||||
{
|
||||
$table = $tableMap['name'];
|
||||
$q = array();
|
||||
$q[] = "DROP TABLE IF EXISTS tmp_backup;";
|
||||
|
||||
$oldColumnNames = array_keys( $this->getColumns( $table ) );
|
||||
|
||||
foreach ( $oldColumnNames as $k => $v ) $oldColumnNames[$k] = "`$v`";
|
||||
|
||||
$q[] = "CREATE TEMPORARY TABLE tmp_backup(" . implode( ",", $oldColumnNames ) . ");";
|
||||
$q[] = "INSERT INTO tmp_backup SELECT * FROM `$table`;";
|
||||
$q[] = "PRAGMA foreign_keys = 0 ";
|
||||
$q[] = "DROP TABLE `$table`;";
|
||||
|
||||
$newTableDefStr = '';
|
||||
foreach ( $tableMap['columns'] as $column => $type ) {
|
||||
if ( $column != 'id' ) {
|
||||
$newTableDefStr .= ",`$column` $type";
|
||||
}
|
||||
}
|
||||
|
||||
$fkDef = '';
|
||||
foreach ( $tableMap['keys'] as $key ) {
|
||||
$fkDef .= ", FOREIGN KEY(`{$key['from']}`)
|
||||
REFERENCES `{$key['table']}`(`{$key['to']}`)
|
||||
ON DELETE {$key['on_delete']} ON UPDATE {$key['on_update']}";
|
||||
}
|
||||
|
||||
$q[] = "CREATE TABLE `$table` ( `id` INTEGER PRIMARY KEY AUTOINCREMENT $newTableDefStr $fkDef );";
|
||||
|
||||
foreach ( $tableMap['indexes'] as $name => $index ) {
|
||||
if ( strpos( $name, 'UQ_' ) === 0 ) {
|
||||
$cols = explode( '__', substr( $name, strlen( 'UQ_' . $table ) ) );
|
||||
foreach ( $cols as $k => $v ) $cols[$k] = "`$v`";
|
||||
$q[] = "CREATE UNIQUE INDEX $name ON `$table` (" . implode( ',', $cols ) . ")";
|
||||
} else $q[] = "CREATE INDEX $name ON `$table` ({$index['name']}) ";
|
||||
}
|
||||
|
||||
$q[] = "INSERT INTO `$table` SELECT * FROM tmp_backup;";
|
||||
$q[] = "DROP TABLE tmp_backup;";
|
||||
$q[] = "PRAGMA foreign_keys = 1 ";
|
||||
|
||||
foreach ( $q as $sq ) $this->adapter->exec( $sq );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the an array describing the indexes for type $type.
|
||||
*
|
||||
* @param string $type type to describe indexes of
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getIndexes( $type )
|
||||
{
|
||||
$table = $this->esc( $type, TRUE );
|
||||
$indexes = $this->adapter->get( "PRAGMA index_list('$table')" );
|
||||
|
||||
$indexInfoList = array();
|
||||
foreach ( $indexes as $i ) {
|
||||
$indexInfoList[$i['name']] = $this->adapter->getRow( "PRAGMA index_info('{$i['name']}') " );
|
||||
|
||||
$indexInfoList[$i['name']]['unique'] = $i['unique'];
|
||||
}
|
||||
|
||||
return $indexInfoList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a foreign key to a type.
|
||||
* Note: cant put this in try-catch because that can hide the fact
|
||||
* that database has been damaged.
|
||||
*
|
||||
* @param string $type type you want to modify table of
|
||||
* @param string $targetType target type
|
||||
* @param string $field field of the type that needs to get the fk
|
||||
* @param string $targetField field where the fk needs to point to
|
||||
* @param integer $buildopt 0 = NO ACTION, 1 = ON DELETE CASCADE
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
protected function buildFK( $type, $targetType, $property, $targetProperty, $constraint = FALSE )
|
||||
{
|
||||
$table = $this->esc( $type, TRUE );
|
||||
$targetTable = $this->esc( $targetType, TRUE );
|
||||
$column = $this->esc( $property, TRUE );
|
||||
$targetColumn = $this->esc( $targetProperty, TRUE );
|
||||
|
||||
$tables = $this->getTables();
|
||||
if ( !in_array( $targetTable, $tables ) ) return FALSE;
|
||||
|
||||
if ( !is_null( $this->getForeignKeyForTypeProperty( $table, $column ) ) ) return FALSE;
|
||||
$t = $this->getTable( $table );
|
||||
$consSQL = ( $constraint ? 'CASCADE' : 'SET NULL' );
|
||||
$label = 'from_' . $column . '_to_table_' . $targetTable . '_col_' . $targetColumn;
|
||||
$t['keys'][$label] = array(
|
||||
'table' => $targetTable,
|
||||
'from' => $column,
|
||||
'to' => $targetColumn,
|
||||
'on_update' => $consSQL,
|
||||
'on_delete' => $consSQL
|
||||
);
|
||||
$this->putTable( $t );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see AQueryWriter::getKeyMapForType
|
||||
*/
|
||||
protected function getKeyMapForType( $type )
|
||||
{
|
||||
$table = $this->esc( $type, TRUE );
|
||||
$keys = $this->adapter->get( "PRAGMA foreign_key_list('$table')" );
|
||||
$keyInfoList = array();
|
||||
foreach ( $keys as $k ) {
|
||||
$label = $this->makeFKLabel( $k['from'], $k['table'], $k['to'] );
|
||||
$keyInfoList[$label] = array(
|
||||
'name' => $label,
|
||||
'from' => $k['from'],
|
||||
'table' => $k['table'],
|
||||
'to' => $k['to'],
|
||||
'on_update' => $k['on_update'],
|
||||
'on_delete' => $k['on_delete']
|
||||
);
|
||||
}
|
||||
return $keyInfoList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param Adapter $adapter Database Adapter
|
||||
*/
|
||||
public function __construct( Adapter $adapter )
|
||||
{
|
||||
$this->typeno_sqltype = array(
|
||||
SQLiteT::C_DATATYPE_INTEGER => 'INTEGER',
|
||||
SQLiteT::C_DATATYPE_NUMERIC => 'NUMERIC',
|
||||
SQLiteT::C_DATATYPE_TEXT => 'TEXT',
|
||||
);
|
||||
|
||||
$this->sqltype_typeno = array();
|
||||
|
||||
foreach ( $this->typeno_sqltype as $k => $v ) {
|
||||
$this->sqltype_typeno[$v] = $k;
|
||||
}
|
||||
|
||||
$this->adapter = $adapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the datatype to be used for primary key IDS and
|
||||
* foreign keys. Returns one if the data type constants.
|
||||
*
|
||||
* @return integer $const data type to be used for IDS.
|
||||
*/
|
||||
public function getTypeForID()
|
||||
{
|
||||
return self::C_DATATYPE_INTEGER;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::scanType
|
||||
*/
|
||||
public function scanType( $value, $flagSpecial = FALSE )
|
||||
{
|
||||
$this->svalue = $value;
|
||||
|
||||
if ( $value === NULL ) return self::C_DATATYPE_INTEGER;
|
||||
if ( $value === INF ) return self::C_DATATYPE_TEXT;
|
||||
|
||||
if ( $this->startsWithZeros( $value ) ) return self::C_DATATYPE_TEXT;
|
||||
|
||||
if ( $value === TRUE || $value === FALSE ) return self::C_DATATYPE_INTEGER;
|
||||
|
||||
if ( is_numeric( $value ) && ( intval( $value ) == $value ) && $value < 2147483648 && $value > -2147483648 ) return self::C_DATATYPE_INTEGER;
|
||||
|
||||
if ( ( is_numeric( $value ) && $value < 2147483648 && $value > -2147483648)
|
||||
|| preg_match( '/\d{4}\-\d\d\-\d\d/', $value )
|
||||
|| preg_match( '/\d{4}\-\d\d\-\d\d\s\d\d:\d\d:\d\d/', $value )
|
||||
) {
|
||||
return self::C_DATATYPE_NUMERIC;
|
||||
}
|
||||
|
||||
return self::C_DATATYPE_TEXT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::addColumn
|
||||
*/
|
||||
public function addColumn( $table, $column, $type )
|
||||
{
|
||||
$column = $this->check( $column );
|
||||
$table = $this->check( $table );
|
||||
$type = $this->typeno_sqltype[$type];
|
||||
|
||||
$this->adapter->exec( "ALTER TABLE `$table` ADD `$column` $type " );
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::code
|
||||
*/
|
||||
public function code( $typedescription, $includeSpecials = FALSE )
|
||||
{
|
||||
$r = ( ( isset( $this->sqltype_typeno[$typedescription] ) ) ? $this->sqltype_typeno[$typedescription] : 99 );
|
||||
|
||||
return $r;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::widenColumn
|
||||
*/
|
||||
public function widenColumn( $type, $column, $datatype )
|
||||
{
|
||||
$t = $this->getTable( $type );
|
||||
|
||||
$t['columns'][$column] = $this->typeno_sqltype[$datatype];
|
||||
|
||||
$this->putTable( $t );
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::getTables();
|
||||
*/
|
||||
public function getTables()
|
||||
{
|
||||
return $this->adapter->getCol( "SELECT name FROM sqlite_master
|
||||
WHERE type='table' AND name!='sqlite_sequence';" );
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::createTable
|
||||
*/
|
||||
public function createTable( $table )
|
||||
{
|
||||
$table = $this->esc( $table );
|
||||
|
||||
$sql = "CREATE TABLE $table ( id INTEGER PRIMARY KEY AUTOINCREMENT ) ";
|
||||
|
||||
$this->adapter->exec( $sql );
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::getColumns
|
||||
*/
|
||||
public function getColumns( $table )
|
||||
{
|
||||
$table = $this->esc( $table, TRUE );
|
||||
|
||||
$columnsRaw = $this->adapter->get( "PRAGMA table_info('$table')" );
|
||||
|
||||
$columns = array();
|
||||
foreach ( $columnsRaw as $r ) $columns[$r['name']] = $r['type'];
|
||||
|
||||
return $columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::addUniqueIndex
|
||||
*/
|
||||
public function addUniqueConstraint( $type, $properties )
|
||||
{
|
||||
$tableNoQ = $this->esc( $type, TRUE );
|
||||
$name = 'UQ_' . $this->esc( $type, TRUE ) . implode( '__', $properties );
|
||||
$t = $this->getTable( $type );
|
||||
$t['indexes'][$name] = array( 'name' => $name );
|
||||
try {
|
||||
$this->putTable( $t );
|
||||
} catch( SQLException $e ) {
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::sqlStateIn
|
||||
*/
|
||||
public function sqlStateIn( $state, $list )
|
||||
{
|
||||
$stateMap = array(
|
||||
'HY000' => QueryWriter::C_SQLSTATE_NO_SUCH_TABLE,
|
||||
'23000' => QueryWriter::C_SQLSTATE_INTEGRITY_CONSTRAINT_VIOLATION
|
||||
);
|
||||
|
||||
return in_array( ( isset( $stateMap[$state] ) ? $stateMap[$state] : '0' ), $list );
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::addIndex
|
||||
*/
|
||||
public function addIndex( $type, $name, $column )
|
||||
{
|
||||
$columns = $this->getColumns( $type );
|
||||
if ( !isset( $columns[$column] ) ) return FALSE;
|
||||
|
||||
$table = $this->esc( $type );
|
||||
$name = preg_replace( '/\W/', '', $name );
|
||||
$column = $this->esc( $column, TRUE );
|
||||
|
||||
try {
|
||||
$t = $this->getTable( $type );
|
||||
$t['indexes'][$name] = array( 'name' => $column );
|
||||
$this->putTable( $t );
|
||||
return TRUE;
|
||||
} catch( SQLException $exception ) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::wipe
|
||||
*/
|
||||
public function wipe( $type )
|
||||
{
|
||||
$table = $this->esc( $type );
|
||||
|
||||
$this->adapter->exec( "DELETE FROM $table " );
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::addFK
|
||||
*/
|
||||
public function addFK( $type, $targetType, $property, $targetProperty, $isDep = FALSE )
|
||||
{
|
||||
return $this->buildFK( $type, $targetType, $property, $targetProperty, $isDep );
|
||||
}
|
||||
|
||||
/**
|
||||
* @see QueryWriter::wipeAll
|
||||
*/
|
||||
public function wipeAll()
|
||||
{
|
||||
$this->adapter->exec( 'PRAGMA foreign_keys = 0 ' );
|
||||
|
||||
foreach ( $this->getTables() as $t ) {
|
||||
try {
|
||||
$this->adapter->exec( "DROP TABLE IF EXISTS `$t`" );
|
||||
} catch ( SQLException $e ) {
|
||||
}
|
||||
|
||||
try {
|
||||
$this->adapter->exec( "DROP TABLE IF EXISTS `$t`" );
|
||||
} catch ( SQLException $e ) {
|
||||
}
|
||||
}
|
||||
|
||||
$this->adapter->exec( 'PRAGMA foreign_keys = 1 ' );
|
||||
}
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RedBeanPHP;
|
||||
|
||||
/**
|
||||
* R-Facade (for Composer)
|
||||
*
|
||||
* If you use Composer you don't use the rb.php file which
|
||||
* has the R-facade, so here is a separate, namespaced R-facade for
|
||||
* those that prefer this.
|
||||
*
|
||||
* An alternative option might be to alias RedBeanPHP/Facade.
|
||||
*
|
||||
* @file RedBeanPHP/R.php
|
||||
* @author Simirimia
|
||||
* @license BSD/GPLv2
|
||||
*
|
||||
*/
|
||||
class R extends Facade
|
||||
{
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RedBeanPHP;
|
||||
|
||||
/**
|
||||
* RedBean\Exception Base.
|
||||
* Represents the base class for RedBeanPHP\Exceptions.
|
||||
*
|
||||
* @file RedBeanPHP/Exception.php
|
||||
* @author Gabor de Mooij and the RedBeanPHP Community
|
||||
* @license BSD/GPLv2
|
||||
*
|
||||
* @copyright
|
||||
* copyright (c) G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community
|
||||
* This source file is subject to the BSD/GPLv2 License that is bundled
|
||||
* with this source code in the file license.txt.
|
||||
*/
|
||||
class RedException extends \Exception
|
||||
{
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RedBeanPHP\RedException;
|
||||
|
||||
use RedBeanPHP\RedException as RedException;
|
||||
|
||||
/**
|
||||
* SQL Exception.
|
||||
* Represents a generic database exception independent of the underlying driver.
|
||||
*
|
||||
* @file RedBeanPHP/RedException/SQL.php
|
||||
* @author Gabor de Mooij and the RedBeanPHP Community
|
||||
* @license BSD/GPLv2
|
||||
*
|
||||
* @copyright
|
||||
* (c) copyright G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community.
|
||||
* This source file is subject to the BSD/GPLv2 License that is bundled
|
||||
* with this source code in the file license.txt.
|
||||
*/
|
||||
class SQL extends RedException
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sqlState;
|
||||
|
||||
/**
|
||||
* Returns an ANSI-92 compliant SQL state.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSQLState()
|
||||
{
|
||||
return $this->sqlState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw SQL STATE, possibly compliant with
|
||||
* ANSI SQL error codes - but this depends on database driver.
|
||||
*
|
||||
* @param string $sqlState SQL state error code
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setSQLState( $sqlState )
|
||||
{
|
||||
$this->sqlState = $sqlState;
|
||||
}
|
||||
|
||||
/**
|
||||
* To String prints both code and SQL state.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return '[' . $this->getSQLState() . '] - ' . $this->getMessage()."\n".
|
||||
'trace: ' . $this->getTraceAsString();
|
||||
}
|
||||
}
|
|
@ -1,598 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RedBeanPHP;
|
||||
|
||||
use RedBeanPHP\Adapter\DBAdapter as DBAdapter;
|
||||
use RedBeanPHP\QueryWriter as QueryWriter;
|
||||
use RedBeanPHP\BeanHelper as BeanHelper;
|
||||
use RedBeanPHP\RedException\SQL as SQLException;
|
||||
use RedBeanPHP\QueryWriter\AQueryWriter as AQueryWriter;
|
||||
use RedBeanPHP\Cursor as Cursor;
|
||||
use RedBeanPHP\Cursor\NullCursor as NullCursor;
|
||||
|
||||
/**
|
||||
* Abstract Repository.
|
||||
*
|
||||
* OODB manages two repositories, a fluid one that
|
||||
* adjust the database schema on-the-fly to accomodate for
|
||||
* new bean types (tables) and new properties (columns) and
|
||||
* a frozen one for use in a production environment. OODB
|
||||
* allows you to swap the repository instances using the freeze()
|
||||
* method.
|
||||
*
|
||||
* @file RedBeanPHP/Repository.php
|
||||
* @author Gabor de Mooij and the RedBeanPHP community
|
||||
* @license BSD/GPLv2
|
||||
*
|
||||
* @copyright
|
||||
* copyright (c) G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community
|
||||
* This source file is subject to the BSD/GPLv2 License that is bundled
|
||||
* with this source code in the file license.txt.
|
||||
*/
|
||||
abstract class Repository
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $stash = NULL;
|
||||
|
||||
/*
|
||||
* @var integer
|
||||
*/
|
||||
protected $nesting = 0;
|
||||
|
||||
/**
|
||||
* @var DBAdapter
|
||||
*/
|
||||
protected $writer;
|
||||
|
||||
/**
|
||||
* Stores a bean and its lists in one run.
|
||||
*
|
||||
* @param OODBBean $bean bean to process
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function storeBeanWithLists( OODBBean $bean )
|
||||
{
|
||||
$sharedAdditions = $sharedTrashcan = $sharedresidue = $sharedItems = $ownAdditions = $ownTrashcan = $ownresidue = $embeddedBeans = array(); //Define groups
|
||||
foreach ( $bean as $property => $value ) {
|
||||
$value = ( $value instanceof SimpleModel ) ? $value->unbox() : $value;
|
||||
if ( $value instanceof OODBBean ) {
|
||||
$this->processEmbeddedBean( $embeddedBeans, $bean, $property, $value );
|
||||
$bean->setMeta("sys.typeof.{$property}", $value->getMeta('type'));
|
||||
} elseif ( is_array( $value ) ) {
|
||||
$originals = $bean->moveMeta( 'sys.shadow.' . $property, array() );
|
||||
if ( strpos( $property, 'own' ) === 0 ) {
|
||||
list( $ownAdditions, $ownTrashcan, $ownresidue ) = $this->processGroups( $originals, $value, $ownAdditions, $ownTrashcan, $ownresidue );
|
||||
$listName = lcfirst( substr( $property, 3 ) );
|
||||
if ($bean->moveMeta( 'sys.exclusive-'. $listName ) ) {
|
||||
OODBBean::setMetaAll( $ownTrashcan, 'sys.garbage', TRUE );
|
||||
OODBBean::setMetaAll( $ownAdditions, 'sys.buildcommand.fkdependson', $bean->getMeta( 'type' ) );
|
||||
}
|
||||
unset( $bean->$property );
|
||||
} elseif ( strpos( $property, 'shared' ) === 0 ) {
|
||||
list( $sharedAdditions, $sharedTrashcan, $sharedresidue ) = $this->processGroups( $originals, $value, $sharedAdditions, $sharedTrashcan, $sharedresidue );
|
||||
unset( $bean->$property );
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->storeBean( $bean );
|
||||
$this->processTrashcan( $bean, $ownTrashcan );
|
||||
$this->processAdditions( $bean, $ownAdditions );
|
||||
$this->processResidue( $ownresidue );
|
||||
$this->processSharedTrashcan( $bean, $sharedTrashcan );
|
||||
$this->processSharedAdditions( $bean, $sharedAdditions );
|
||||
$this->processSharedResidue( $bean, $sharedresidue );
|
||||
}
|
||||
|
||||
/**
|
||||
* Process groups. Internal function. Processes different kind of groups for
|
||||
* storage function. Given a list of original beans and a list of current beans,
|
||||
* this function calculates which beans remain in the list (residue), which
|
||||
* have been deleted (are in the trashcan) and which beans have been added
|
||||
* (additions).
|
||||
*
|
||||
* @param array $originals originals
|
||||
* @param array $current the current beans
|
||||
* @param array $additions beans that have been added
|
||||
* @param array $trashcan beans that have been deleted
|
||||
* @param array $residue beans that have been left untouched
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function processGroups( $originals, $current, $additions, $trashcan, $residue )
|
||||
{
|
||||
return array(
|
||||
array_merge( $additions, array_diff( $current, $originals ) ),
|
||||
array_merge( $trashcan, array_diff( $originals, $current ) ),
|
||||
array_merge( $residue, array_intersect( $current, $originals ) )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes an embedded bean.
|
||||
*
|
||||
* @param OODBBean|SimpleModel $embeddedBean the bean or model
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
protected function prepareEmbeddedBean( $embeddedBean )
|
||||
{
|
||||
if ( !$embeddedBean->id || $embeddedBean->getMeta( 'tainted' ) ) {
|
||||
$this->store( $embeddedBean );
|
||||
}
|
||||
|
||||
return $embeddedBean->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a list of beans from a bean. A bean may contain lists. This
|
||||
* method handles shared addition lists; i.e. the $bean->sharedObject properties.
|
||||
*
|
||||
* @param OODBBean $bean the bean
|
||||
* @param array $sharedAdditions list with shared additions
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function processSharedAdditions( $bean, $sharedAdditions )
|
||||
{
|
||||
foreach ( $sharedAdditions as $addition ) {
|
||||
if ( $addition instanceof OODBBean ) {
|
||||
$this->oodb->getAssociationManager()->associate( $addition, $bean );
|
||||
} else {
|
||||
throw new RedException( 'Array may only contain OODBBeans' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a list of beans from a bean. A bean may contain lists. This
|
||||
* method handles own lists; i.e. the $bean->ownObject properties.
|
||||
* A residue is a bean in an own-list that stays where it is. This method
|
||||
* checks if there have been any modification to this bean, in that case
|
||||
* the bean is stored once again, otherwise the bean will be left untouched.
|
||||
*
|
||||
* @param OODBBean $bean bean tor process
|
||||
* @param array $ownresidue list to process
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function processResidue( $ownresidue )
|
||||
{
|
||||
foreach ( $ownresidue as $residue ) {
|
||||
if ( $residue->getMeta( 'tainted' ) ) {
|
||||
$this->store( $residue );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a list of beans from a bean. A bean may contain lists. This
|
||||
* method handles own lists; i.e. the $bean->ownObject properties.
|
||||
* A trash can bean is a bean in an own-list that has been removed
|
||||
* (when checked with the shadow). This method
|
||||
* checks if the bean is also in the dependency list. If it is the bean will be removed.
|
||||
* If not, the connection between the bean and the owner bean will be broken by
|
||||
* setting the ID to NULL.
|
||||
*
|
||||
* @param OODBBean $bean bean to process
|
||||
* @param array $ownTrashcan list to process
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function processTrashcan( $bean, $ownTrashcan )
|
||||
{
|
||||
foreach ( $ownTrashcan as $trash ) {
|
||||
|
||||
$myFieldLink = $bean->getMeta( 'type' ) . '_id';
|
||||
$alias = $bean->getMeta( 'sys.alias.' . $trash->getMeta( 'type' ) );
|
||||
if ( $alias ) $myFieldLink = $alias . '_id';
|
||||
|
||||
if ( $trash->getMeta( 'sys.garbage' ) === true ) {
|
||||
$this->trash( $trash );
|
||||
} else {
|
||||
$trash->$myFieldLink = NULL;
|
||||
$this->store( $trash );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unassociates the list items in the trashcan.
|
||||
*
|
||||
* @param OODBBean $bean bean to process
|
||||
* @param array $sharedTrashcan list to process
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function processSharedTrashcan( $bean, $sharedTrashcan )
|
||||
{
|
||||
foreach ( $sharedTrashcan as $trash ) {
|
||||
$this->oodb->getAssociationManager()->unassociate( $trash, $bean );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores all the beans in the residue group.
|
||||
*
|
||||
* @param OODBBean $bean bean to process
|
||||
* @param array $sharedresidue list to process
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function processSharedResidue( $bean, $sharedresidue )
|
||||
{
|
||||
foreach ( $sharedresidue as $residue ) {
|
||||
$this->store( $residue );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the bean has 'loaded lists' or
|
||||
* 'loaded embedded beans' that need to be processed
|
||||
* by the store() method.
|
||||
*
|
||||
* @param OODBBean $bean bean to be examined
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
protected function hasListsOrObjects( OODBBean $bean )
|
||||
{
|
||||
$processLists = FALSE;
|
||||
foreach ( $bean as $value ) {
|
||||
if ( is_array( $value ) || is_object( $value ) ) {
|
||||
$processLists = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $processLists;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an embedded bean to an ID, removed the bean property and
|
||||
* stores the bean in the embedded beans array.
|
||||
*
|
||||
* @param array $embeddedBeans destination array for embedded bean
|
||||
* @param OODBBean $bean target bean to process
|
||||
* @param string $property property that contains the embedded bean
|
||||
* @param OODBBean $value embedded bean itself
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function processEmbeddedBean( &$embeddedBeans, $bean, $property, OODBBean $value )
|
||||
{
|
||||
$linkField = $property . '_id';
|
||||
$id = $this->prepareEmbeddedBean( $value );
|
||||
if ($bean->$linkField != $id) $bean->$linkField = $id;
|
||||
$bean->setMeta( 'cast.' . $linkField, 'id' );
|
||||
$embeddedBeans[$linkField] = $value;
|
||||
unset( $bean->$property );
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor, requires a query writer.
|
||||
* Creates a new instance of the bean respository class.
|
||||
*
|
||||
* @param QueryWriter $writer the Query Writer to use for this repository
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct( OODB $oodb, QueryWriter $writer )
|
||||
{
|
||||
$this->writer = $writer;
|
||||
$this->oodb = $oodb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a OODBBean bean is valid.
|
||||
* If the type is not valid or the ID is not valid it will
|
||||
* throw an exception: Security.
|
||||
*
|
||||
* @param OODBBean $bean the bean that needs to be checked
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function check( OODBBean $bean )
|
||||
{
|
||||
//Is all meta information present?
|
||||
if ( !isset( $bean->id ) ) {
|
||||
throw new RedException( 'Bean has incomplete Meta Information id ' );
|
||||
}
|
||||
if ( !( $bean->getMeta( 'type' ) ) ) {
|
||||
throw new RedException( 'Bean has incomplete Meta Information II' );
|
||||
}
|
||||
//Pattern of allowed characters
|
||||
$pattern = '/[^a-z0-9_]/i';
|
||||
//Does the type contain invalid characters?
|
||||
if ( preg_match( $pattern, $bean->getMeta( 'type' ) ) ) {
|
||||
throw new RedException( 'Bean Type is invalid' );
|
||||
}
|
||||
//Are the properties and values valid?
|
||||
foreach ( $bean as $prop => $value ) {
|
||||
if (
|
||||
is_array( $value )
|
||||
|| ( is_object( $value ) )
|
||||
) {
|
||||
throw new RedException( "Invalid Bean value: property $prop" );
|
||||
} else if (
|
||||
strlen( $prop ) < 1
|
||||
|| preg_match( $pattern, $prop )
|
||||
) {
|
||||
throw new RedException( "Invalid Bean property: property $prop" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches the database for a bean that matches conditions $conditions and sql $addSQL
|
||||
* and returns an array containing all the beans that have been found.
|
||||
*
|
||||
* Conditions need to take form:
|
||||
*
|
||||
* <code>
|
||||
* array(
|
||||
* 'PROPERTY' => array( POSSIBLE VALUES... 'John', 'Steve' )
|
||||
* 'PROPERTY' => array( POSSIBLE VALUES... )
|
||||
* );
|
||||
* </code>
|
||||
*
|
||||
* All conditions are glued together using the AND-operator, while all value lists
|
||||
* are glued using IN-operators thus acting as OR-conditions.
|
||||
*
|
||||
* Note that you can use property names; the columns will be extracted using the
|
||||
* appropriate bean formatter.
|
||||
*
|
||||
* @param string $type type of beans you are looking for
|
||||
* @param array $conditions list of conditions
|
||||
* @param string $addSQL SQL to be used in query
|
||||
* @param array $bindings whether you prefer to use a WHERE clause or not (TRUE = not)
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function find( $type, $conditions = array(), $sql = NULL, $bindings = array() )
|
||||
{
|
||||
//for backward compatibility, allow mismatch arguments:
|
||||
if ( is_array( $sql ) ) {
|
||||
if ( isset( $sql[1] ) ) {
|
||||
$bindings = $sql[1];
|
||||
}
|
||||
$sql = $sql[0];
|
||||
}
|
||||
try {
|
||||
$beans = $this->convertToBeans( $type, $this->writer->queryRecord( $type, $conditions, $sql, $bindings ) );
|
||||
|
||||
return $beans;
|
||||
} catch ( SQLException $exception ) {
|
||||
$this->handleException( $exception );
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a BeanCollection.
|
||||
*
|
||||
* @param string $type type of beans you are looking for
|
||||
* @param string $sql SQL to be used in query
|
||||
* @param array $bindings whether you prefer to use a WHERE clause or not (TRUE = not)
|
||||
*
|
||||
* @return BeanCollection
|
||||
*/
|
||||
public function findCollection( $type, $sql, $bindings = array() )
|
||||
{
|
||||
try {
|
||||
$cursor = $this->writer->queryRecordWithCursor( $type, $sql, $bindings );
|
||||
return new BeanCollection( $type, $this, $cursor );
|
||||
} catch ( SQLException $exception ) {
|
||||
$this->handleException( $exception );
|
||||
}
|
||||
return new BeanCollection( $type, $this, new NullCursor );
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a bean in the database. This method takes a
|
||||
* OODBBean Bean Object $bean and stores it
|
||||
* in the database. If the database schema is not compatible
|
||||
* with this bean and RedBean runs in fluid mode the schema
|
||||
* will be altered to store the bean correctly.
|
||||
* If the database schema is not compatible with this bean and
|
||||
* RedBean runs in frozen mode it will throw an exception.
|
||||
* This function returns the primary key ID of the inserted
|
||||
* bean.
|
||||
*
|
||||
* The return value is an integer if possible. If it is not possible to
|
||||
* represent the value as an integer a string will be returned. We use
|
||||
* explicit casts instead of functions to preserve performance
|
||||
* (0.13 vs 0.28 for 10000 iterations on Core i3).
|
||||
*
|
||||
* @param OODBBean|SimpleModel $bean bean to store
|
||||
*
|
||||
* @return integer|string
|
||||
*/
|
||||
public function store( $bean )
|
||||
{
|
||||
$processLists = $this->hasListsOrObjects( $bean );
|
||||
if ( !$processLists && !$bean->getMeta( 'tainted' ) ) {
|
||||
return $bean->getID(); //bail out!
|
||||
}
|
||||
$this->oodb->signal( 'update', $bean );
|
||||
$processLists = $this->hasListsOrObjects( $bean ); //check again, might have changed by model!
|
||||
if ( $processLists ) {
|
||||
$this->storeBeanWithLists( $bean );
|
||||
} else {
|
||||
$this->storeBean( $bean );
|
||||
}
|
||||
$this->oodb->signal( 'after_update', $bean );
|
||||
|
||||
return ( (string) $bean->id === (string) (int) $bean->id ) ? (int) $bean->id : (string) $bean->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of beans. Pass a type and a series of ids and
|
||||
* this method will bring you the corresponding beans.
|
||||
*
|
||||
* important note: Because this method loads beans using the load()
|
||||
* function (but faster) it will return empty beans with ID 0 for
|
||||
* every bean that could not be located. The resulting beans will have the
|
||||
* passed IDs as their keys.
|
||||
*
|
||||
* @param string $type type of beans
|
||||
* @param array $ids ids to load
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function batch( $type, $ids )
|
||||
{
|
||||
if ( !$ids ) {
|
||||
return array();
|
||||
}
|
||||
$collection = array();
|
||||
try {
|
||||
$rows = $this->writer->queryRecord( $type, array( 'id' => $ids ) );
|
||||
} catch ( SQLException $e ) {
|
||||
$this->handleException( $e );
|
||||
$rows = FALSE;
|
||||
}
|
||||
$this->stash[$this->nesting] = array();
|
||||
if ( !$rows ) {
|
||||
return array();
|
||||
}
|
||||
foreach ( $rows as $row ) {
|
||||
$this->stash[$this->nesting][$row['id']] = $row;
|
||||
}
|
||||
foreach ( $ids as $id ) {
|
||||
$collection[$id] = $this->load( $type, $id );
|
||||
}
|
||||
$this->stash[$this->nesting] = NULL;
|
||||
|
||||
return $collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a convenience method; it converts database rows
|
||||
* (arrays) into beans. Given a type and a set of rows this method
|
||||
* will return an array of beans of the specified type loaded with
|
||||
* the data fields provided by the result set from the database.
|
||||
*
|
||||
* @param string $type type of beans you would like to have
|
||||
* @param array $rows rows from the database result
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function convertToBeans( $type, $rows )
|
||||
{
|
||||
$collection = array();
|
||||
$this->stash[$this->nesting] = array();
|
||||
foreach ( $rows as $row ) {
|
||||
$id = $row['id'];
|
||||
$this->stash[$this->nesting][$id] = $row;
|
||||
$collection[$id] = $this->load( $type, $id );
|
||||
}
|
||||
$this->stash[$this->nesting] = NULL;
|
||||
|
||||
return $collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Counts the number of beans of type $type.
|
||||
* This method accepts a second argument to modify the count-query.
|
||||
* A third argument can be used to provide bindings for the SQL snippet.
|
||||
*
|
||||
* @param string $type type of bean we are looking for
|
||||
* @param string $addSQL additional SQL snippet
|
||||
* @param array $bindings parameters to bind to SQL
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function count( $type, $addSQL = '', $bindings = array() )
|
||||
{
|
||||
$type = AQueryWriter::camelsSnake( $type );
|
||||
if ( count( explode( '_', $type ) ) > 2 ) {
|
||||
throw new RedException( 'Invalid type for count.' );
|
||||
}
|
||||
|
||||
try {
|
||||
return (int) $this->writer->queryRecordCount( $type, array(), $addSQL, $bindings );
|
||||
} catch ( SQLException $exception ) {
|
||||
if ( !$this->writer->sqlStateIn( $exception->getSQLState(), array(
|
||||
QueryWriter::C_SQLSTATE_NO_SUCH_TABLE,
|
||||
QueryWriter::C_SQLSTATE_NO_SUCH_COLUMN ) ) ) {
|
||||
throw $exception;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a bean from the database.
|
||||
* This function will remove the specified OODBBean
|
||||
* Bean Object from the database.
|
||||
*
|
||||
* @param OODBBean|SimpleModel $bean bean you want to remove from database
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function trash( $bean )
|
||||
{
|
||||
$this->oodb->signal( 'delete', $bean );
|
||||
foreach ( $bean as $property => $value ) {
|
||||
if ( $value instanceof OODBBean ) {
|
||||
unset( $bean->$property );
|
||||
}
|
||||
if ( is_array( $value ) ) {
|
||||
if ( strpos( $property, 'own' ) === 0 ) {
|
||||
unset( $bean->$property );
|
||||
} elseif ( strpos( $property, 'shared' ) === 0 ) {
|
||||
unset( $bean->$property );
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
$this->writer->deleteRecord( $bean->getMeta( 'type' ), array( 'id' => array( $bean->id ) ), NULL );
|
||||
} catch ( SQLException $exception ) {
|
||||
$this->handleException( $exception );
|
||||
}
|
||||
$bean->id = 0;
|
||||
$this->oodb->signal( 'after_delete', $bean );
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the specified table already exists in the database.
|
||||
* Not part of the Object Database interface!
|
||||
*
|
||||
* @deprecated Use AQueryWriter::typeExists() instead.
|
||||
*
|
||||
* @param string $table table name
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function tableExists( $table )
|
||||
{
|
||||
return $this->writer->tableExists( $table );
|
||||
}
|
||||
|
||||
/**
|
||||
* Trash all beans of a given type. Wipes an entire type of bean.
|
||||
*
|
||||
* @param string $type type of bean you wish to delete all instances of
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function wipe( $type )
|
||||
{
|
||||
try {
|
||||
$this->writer->wipe( $type );
|
||||
|
||||
return TRUE;
|
||||
} catch ( SQLException $exception ) {
|
||||
if ( !$this->writer->sqlStateIn( $exception->getSQLState(), array( QueryWriter::C_SQLSTATE_NO_SUCH_TABLE ) ) ) {
|
||||
throw $exception;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,314 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RedBeanPHP\Repository;
|
||||
|
||||
use RedBeanPHP\OODBBean as OODBBean;
|
||||
use RedBeanPHP\QueryWriter as QueryWriter;
|
||||
use RedBeanPHP\RedException as RedException;
|
||||
use RedBeanPHP\BeanHelper as BeanHelper;
|
||||
use RedBeanPHP\RedException\SQL as SQLException;
|
||||
use RedBeanPHP\Repository as Repository;
|
||||
|
||||
/**
|
||||
* Fluid Repository.
|
||||
* OODB manages two repositories, a fluid one that
|
||||
* adjust the database schema on-the-fly to accomodate for
|
||||
* new bean types (tables) and new properties (columns) and
|
||||
* a frozen one for use in a production environment. OODB
|
||||
* allows you to swap the repository instances using the freeze()
|
||||
* method.
|
||||
*
|
||||
* @file RedBeanPHP/Repository/Fluid.php
|
||||
* @author Gabor de Mooij and the RedBeanPHP community
|
||||
* @license BSD/GPLv2
|
||||
*
|
||||
* @copyright
|
||||
* copyright (c) G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community
|
||||
* This source file is subject to the BSD/GPLv2 License that is bundled
|
||||
* with this source code in the file license.txt.
|
||||
*/
|
||||
class Fluid extends Repository
|
||||
{
|
||||
/**
|
||||
* Figures out the desired type given the cast string ID.
|
||||
*
|
||||
* @param string $cast cast identifier
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
private function getTypeFromCast( $cast )
|
||||
{
|
||||
if ( $cast == 'string' ) {
|
||||
$typeno = $this->writer->scanType( 'STRING' );
|
||||
} elseif ( $cast == 'id' ) {
|
||||
$typeno = $this->writer->getTypeForID();
|
||||
} elseif ( isset( $this->writer->sqltype_typeno[$cast] ) ) {
|
||||
$typeno = $this->writer->sqltype_typeno[$cast];
|
||||
} else {
|
||||
throw new RedException( 'Invalid Cast' );
|
||||
}
|
||||
|
||||
return $typeno;
|
||||
}
|
||||
|
||||
/**
|
||||
* Orders the Query Writer to create a table if it does not exist already and
|
||||
* adds a note in the build report about the creation.
|
||||
*
|
||||
* @param OODBBean $bean bean to update report of
|
||||
* @param string $table table to check and create if not exists
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function createTableIfNotExists( OODBBean $bean, $table )
|
||||
{
|
||||
//Does table exist? If not, create
|
||||
if ( !$this->tableExists( $this->writer->esc( $table, TRUE ) ) ) {
|
||||
$this->writer->createTable( $table );
|
||||
$bean->setMeta( 'buildreport.flags.created', TRUE );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies the table to fit the bean data.
|
||||
* Given a property and a value and the bean, this method will
|
||||
* adjust the table structure to fit the requirements of the property and value.
|
||||
* This may include adding a new column or widening an existing column to hold a larger
|
||||
* or different kind of value. This method employs the writer to adjust the table
|
||||
* structure in the database. Schema updates are recorded in meta properties of the bean.
|
||||
*
|
||||
* This method will also apply indexes, unique constraints and foreign keys.
|
||||
*
|
||||
* @param OODBBean $bean bean to get cast data from and store meta in
|
||||
* @param string $property property to store
|
||||
* @param mixed $value value to store
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function modifySchema( OODBBean $bean, $property, $value )
|
||||
{
|
||||
$doFKStuff = FALSE;
|
||||
$table = $bean->getMeta( 'type' );
|
||||
$columns = $this->writer->getColumns( $table );
|
||||
$columnNoQ = $this->writer->esc( $property, TRUE );
|
||||
if ( !$this->oodb->isChilled( $bean->getMeta( 'type' ) ) ) {
|
||||
if ( $bean->getMeta( "cast.$property", -1 ) !== -1 ) { //check for explicitly specified types
|
||||
$cast = $bean->getMeta( "cast.$property" );
|
||||
$typeno = $this->getTypeFromCast( $cast );
|
||||
} else {
|
||||
$cast = FALSE;
|
||||
$typeno = $this->writer->scanType( $value, TRUE );
|
||||
}
|
||||
if ( isset( $columns[$this->writer->esc( $property, TRUE )] ) ) { //Is this property represented in the table ?
|
||||
if ( !$cast ) { //rescan without taking into account special types >80
|
||||
$typeno = $this->writer->scanType( $value, FALSE );
|
||||
}
|
||||
$sqlt = $this->writer->code( $columns[$this->writer->esc( $property, TRUE )] );
|
||||
if ( $typeno > $sqlt ) { //no, we have to widen the database column type
|
||||
$this->writer->widenColumn( $table, $property, $typeno );
|
||||
$bean->setMeta( 'buildreport.flags.widen', TRUE );
|
||||
$doFKStuff = TRUE;
|
||||
}
|
||||
} else {
|
||||
$this->writer->addColumn( $table, $property, $typeno );
|
||||
$bean->setMeta( 'buildreport.flags.addcolumn', TRUE );
|
||||
$doFKStuff = TRUE;
|
||||
}
|
||||
if ($doFKStuff) {
|
||||
if (strrpos($columnNoQ, '_id')===(strlen($columnNoQ)-3)) {
|
||||
$destinationColumnNoQ = substr($columnNoQ, 0, strlen($columnNoQ)-3);
|
||||
$indexName = "index_foreignkey_{$table}_{$destinationColumnNoQ}";
|
||||
$this->writer->addIndex($table, $indexName, $columnNoQ);
|
||||
$typeof = $bean->getMeta("sys.typeof.{$destinationColumnNoQ}", $destinationColumnNoQ);
|
||||
$isLink = $bean->getMeta( 'sys.buildcommand.unique', FALSE );
|
||||
//Make FK CASCADING if part of exclusive list (dependson=typeof) or if link bean
|
||||
$isDep = ( $bean->moveMeta( 'sys.buildcommand.fkdependson' ) === $typeof || is_array( $isLink ) );
|
||||
$result = $this->writer->addFK( $table, $typeof, $columnNoQ, 'id', $isDep );
|
||||
//If this is a link bean and all unique columns have been added already, then apply unique constraint
|
||||
if ( is_array( $isLink ) && !count( array_diff( $isLink, array_keys( $this->writer->getColumns( $table ) ) ) ) ) {
|
||||
$this->writer->addUniqueConstraint( $table, $bean->moveMeta('sys.buildcommand.unique') );
|
||||
$bean->setMeta("sys.typeof.{$destinationColumnNoQ}", NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Part of the store() functionality.
|
||||
* Handles all new additions after the bean has been saved.
|
||||
* Stores addition bean in own-list, extracts the id and
|
||||
* adds a foreign key. Also adds a constraint in case the type is
|
||||
* in the dependent list.
|
||||
*
|
||||
* Note that this method raises a custom exception if the bean
|
||||
* is not an instance of OODBBean. Therefore it does not use
|
||||
* a type hint. This allows the user to take action in case
|
||||
* invalid objects are passed in the list.
|
||||
*
|
||||
* @param OODBBean $bean bean to process
|
||||
* @param array $ownAdditions list of addition beans in own-list
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function processAdditions( $bean, $ownAdditions )
|
||||
{
|
||||
$beanType = $bean->getMeta( 'type' );
|
||||
|
||||
foreach ( $ownAdditions as $addition ) {
|
||||
if ( $addition instanceof OODBBean ) {
|
||||
|
||||
$myFieldLink = $beanType . '_id';
|
||||
$alias = $bean->getMeta( 'sys.alias.' . $addition->getMeta( 'type' ) );
|
||||
if ( $alias ) $myFieldLink = $alias . '_id';
|
||||
|
||||
$addition->$myFieldLink = $bean->id;
|
||||
$addition->setMeta( 'cast.' . $myFieldLink, 'id' );
|
||||
|
||||
if ($alias) {
|
||||
$addition->setMeta( "sys.typeof.{$alias}", $beanType );
|
||||
} else {
|
||||
$addition->setMeta( "sys.typeof.{$beanType}", $beanType );
|
||||
}
|
||||
|
||||
$this->store( $addition );
|
||||
} else {
|
||||
throw new RedException( 'Array may only contain OODBBeans' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a cleaned bean; i.e. only scalar values. This is the core of the store()
|
||||
* method. When all lists and embedded beans (parent objects) have been processed and
|
||||
* removed from the original bean the bean is passed to this method to be stored
|
||||
* in the database.
|
||||
*
|
||||
* @param OODBBean $bean the clean bean
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function storeBean( OODBBean $bean )
|
||||
{
|
||||
if ( $bean->getMeta( 'changed' ) ) {
|
||||
$this->check( $bean );
|
||||
$table = $bean->getMeta( 'type' );
|
||||
$this->createTableIfNotExists( $bean, $table );
|
||||
|
||||
$updateValues = array();
|
||||
foreach ( $bean as $property => $value ) {
|
||||
if ( $property !== 'id' ) {
|
||||
$this->modifySchema( $bean, $property, $value );
|
||||
}
|
||||
if ( $property !== 'id' ) {
|
||||
$updateValues[] = array( 'property' => $property, 'value' => $value );
|
||||
}
|
||||
}
|
||||
|
||||
$bean->id = $this->writer->updateRecord( $table, $updateValues, $bean->id );
|
||||
$bean->setMeta( 'changed', FALSE );
|
||||
}
|
||||
$bean->setMeta( 'tainted', FALSE );
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles exceptions. Suppresses exceptions caused by missing structures.
|
||||
*
|
||||
* @param Exception $exception exception
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function handleException( \Exception $exception )
|
||||
{
|
||||
if ( !$this->writer->sqlStateIn( $exception->getSQLState(),
|
||||
array(
|
||||
QueryWriter::C_SQLSTATE_NO_SUCH_TABLE,
|
||||
QueryWriter::C_SQLSTATE_NO_SUCH_COLUMN ) )
|
||||
) {
|
||||
throw $exception;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispenses a new bean (a OODBBean Bean Object)
|
||||
* of the specified type. Always
|
||||
* use this function to get an empty bean object. Never
|
||||
* instantiate a OODBBean yourself because it needs
|
||||
* to be configured before you can use it with RedBean. This
|
||||
* function applies the appropriate initialization /
|
||||
* configuration for you.
|
||||
*
|
||||
* @param string $type type of bean you want to dispense
|
||||
* @param string $number number of beans you would like to get
|
||||
* @param boolean $alwaysReturnArray if TRUE always returns the result as an array
|
||||
*
|
||||
* @return OODBBean
|
||||
*/
|
||||
public function dispense( $type, $number = 1, $alwaysReturnArray = FALSE )
|
||||
{
|
||||
$OODBBEAN = defined( 'REDBEAN_OODBBEAN_CLASS' ) ? REDBEAN_OODBBEAN_CLASS : '\RedBeanPHP\OODBBean';
|
||||
$beans = array();
|
||||
for ( $i = 0; $i < $number; $i++ ) {
|
||||
$bean = new $OODBBEAN;
|
||||
$bean->initializeForDispense( $type, $this->oodb->getBeanHelper() );
|
||||
$this->check( $bean );
|
||||
$this->oodb->signal( 'dispense', $bean );
|
||||
$beans[] = $bean;
|
||||
}
|
||||
|
||||
return ( count( $beans ) === 1 && !$alwaysReturnArray ) ? array_pop( $beans ) : $beans;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a bean from the object database.
|
||||
* It searches for a OODBBean Bean Object in the
|
||||
* database. It does not matter how this bean has been stored.
|
||||
* RedBean uses the primary key ID $id and the string $type
|
||||
* to find the bean. The $type specifies what kind of bean you
|
||||
* are looking for; this is the same type as used with the
|
||||
* dispense() function. If RedBean finds the bean it will return
|
||||
* the OODB Bean object; if it cannot find the bean
|
||||
* RedBean will return a new bean of type $type and with
|
||||
* primary key ID 0. In the latter case it acts basically the
|
||||
* same as dispense().
|
||||
*
|
||||
* Important note:
|
||||
* If the bean cannot be found in the database a new bean of
|
||||
* the specified type will be generated and returned.
|
||||
*
|
||||
* @param string $type type of bean you want to load
|
||||
* @param integer $id ID of the bean you want to load
|
||||
*
|
||||
* @return OODBBean
|
||||
*/
|
||||
public function load( $type, $id )
|
||||
{
|
||||
$bean = $this->dispense( $type );
|
||||
if ( isset( $this->stash[$this->nesting][$id] ) ) {
|
||||
$row = $this->stash[$this->nesting][$id];
|
||||
} else {
|
||||
try {
|
||||
$rows = $this->writer->queryRecord( $type, array( 'id' => array( $id ) ) );
|
||||
} catch ( SQLException $exception ) {
|
||||
if ( $this->writer->sqlStateIn( $exception->getSQLState(),
|
||||
array(
|
||||
QueryWriter::C_SQLSTATE_NO_SUCH_COLUMN,
|
||||
QueryWriter::C_SQLSTATE_NO_SUCH_TABLE )
|
||||
)
|
||||
) {
|
||||
$rows = 0;
|
||||
}
|
||||
}
|
||||
if ( empty( $rows ) ) {
|
||||
return $bean;
|
||||
}
|
||||
$row = array_pop( $rows );
|
||||
}
|
||||
$bean->importRow( $row );
|
||||
$this->nesting++;
|
||||
$this->oodb->signal( 'open', $bean );
|
||||
$this->nesting--;
|
||||
|
||||
return $bean->setMeta( 'tainted', FALSE );
|
||||
}
|
||||
}
|
|
@ -1,197 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RedBeanPHP\Repository;
|
||||
|
||||
use RedBeanPHP\OODBBean as OODBBean;
|
||||
use RedBeanPHP\QueryWriter as QueryWriter;
|
||||
use RedBeanPHP\RedException as RedException;
|
||||
use RedBeanPHP\BeanHelper as BeanHelper;
|
||||
use RedBeanPHP\RedException\SQL as SQLException;
|
||||
use RedBeanPHP\Repository as Repository;
|
||||
|
||||
/**
|
||||
* Frozen Repository.
|
||||
* OODB manages two repositories, a fluid one that
|
||||
* adjust the database schema on-the-fly to accomodate for
|
||||
* new bean types (tables) and new properties (columns) and
|
||||
* a frozen one for use in a production environment. OODB
|
||||
* allows you to swap the repository instances using the freeze()
|
||||
* method.
|
||||
*
|
||||
* @file RedBeanPHP/Repository/Frozen.php
|
||||
* @author Gabor de Mooij and the RedBeanPHP community
|
||||
* @license BSD/GPLv2
|
||||
*
|
||||
* @copyright
|
||||
* copyright (c) G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community
|
||||
* This source file is subject to the BSD/GPLv2 License that is bundled
|
||||
* with this source code in the file license.txt.
|
||||
*/
|
||||
class Frozen extends Repository
|
||||
{
|
||||
/**
|
||||
* Handles exceptions. Suppresses exceptions caused by missing structures.
|
||||
*
|
||||
* @param \Exception $exception exception to handle
|
||||
*
|
||||
* @return void
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function handleException( \Exception $exception )
|
||||
{
|
||||
throw $exception;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a cleaned bean; i.e. only scalar values. This is the core of the store()
|
||||
* method. When all lists and embedded beans (parent objects) have been processed and
|
||||
* removed from the original bean the bean is passed to this method to be stored
|
||||
* in the database.
|
||||
*
|
||||
* @param OODBBean $bean the clean bean
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function storeBean( OODBBean $bean )
|
||||
{
|
||||
if ( $bean->getMeta( 'changed' ) ) {
|
||||
|
||||
list( $properties, $table ) = $bean->getPropertiesAndType();
|
||||
$id = $properties['id'];
|
||||
unset($properties['id']);
|
||||
$updateValues = array();
|
||||
$k1 = 'property';
|
||||
$k2 = 'value';
|
||||
foreach( $properties as $key => $value ) {
|
||||
$updateValues[] = array( $k1 => $key, $k2 => $value );
|
||||
}
|
||||
$bean->id = $this->writer->updateRecord( $table, $updateValues, $id );
|
||||
$bean->setMeta( 'changed', FALSE );
|
||||
}
|
||||
$bean->setMeta( 'tainted', FALSE );
|
||||
}
|
||||
|
||||
/**
|
||||
* Part of the store() functionality.
|
||||
* Handles all new additions after the bean has been saved.
|
||||
* Stores addition bean in own-list, extracts the id and
|
||||
* adds a foreign key. Also adds a constraint in case the type is
|
||||
* in the dependent list.
|
||||
*
|
||||
* Note that this method raises a custom exception if the bean
|
||||
* is not an instance of OODBBean. Therefore it does not use
|
||||
* a type hint. This allows the user to take action in case
|
||||
* invalid objects are passed in the list.
|
||||
*
|
||||
* @param OODBBean $bean bean to process
|
||||
* @param array $ownAdditions list of addition beans in own-list
|
||||
*
|
||||
* @return void
|
||||
* @throws RedException
|
||||
*/
|
||||
protected function processAdditions( $bean, $ownAdditions )
|
||||
{
|
||||
$beanType = $bean->getMeta( 'type' );
|
||||
|
||||
$cachedIndex = array();
|
||||
foreach ( $ownAdditions as $addition ) {
|
||||
if ( $addition instanceof OODBBean ) {
|
||||
|
||||
$myFieldLink = $beanType . '_id';
|
||||
$alias = $bean->getMeta( 'sys.alias.' . $addition->getMeta( 'type' ) );
|
||||
if ( $alias ) $myFieldLink = $alias . '_id';
|
||||
|
||||
$addition->$myFieldLink = $bean->id;
|
||||
$addition->setMeta( 'cast.' . $myFieldLink, 'id' );
|
||||
$this->store( $addition );
|
||||
|
||||
} else {
|
||||
throw new RedException( 'Array may only contain OODBBeans' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispenses a new bean (a OODBBean Bean Object)
|
||||
* of the specified type. Always
|
||||
* use this function to get an empty bean object. Never
|
||||
* instantiate a OODBBean yourself because it needs
|
||||
* to be configured before you can use it with RedBean. This
|
||||
* function applies the appropriate initialization /
|
||||
* configuration for you.
|
||||
*
|
||||
* @param string $type type of bean you want to dispense
|
||||
* @param int $number number of beans you would like to get
|
||||
* @param boolean $alwaysReturnArray if TRUE always returns the result as an array
|
||||
*
|
||||
* @return OODBBean
|
||||
*/
|
||||
public function dispense( $type, $number = 1, $alwaysReturnArray = FALSE )
|
||||
{
|
||||
$OODBBEAN = defined( 'REDBEAN_OODBBEAN_CLASS' ) ? REDBEAN_OODBBEAN_CLASS : '\RedBeanPHP\OODBBean';
|
||||
$beans = array();
|
||||
for ( $i = 0; $i < $number; $i++ ) {
|
||||
/** @var \RedBeanPHP\OODBBean $bean */
|
||||
$bean = new $OODBBEAN;
|
||||
$bean->initializeForDispense( $type, $this->oodb->getBeanHelper() );
|
||||
$this->oodb->signal( 'dispense', $bean );
|
||||
$beans[] = $bean;
|
||||
}
|
||||
|
||||
return ( count( $beans ) === 1 && !$alwaysReturnArray ) ? array_pop( $beans ) : $beans;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a bean from the object database.
|
||||
* It searches for a OODBBean Bean Object in the
|
||||
* database. It does not matter how this bean has been stored.
|
||||
* RedBean uses the primary key ID $id and the string $type
|
||||
* to find the bean. The $type specifies what kind of bean you
|
||||
* are looking for; this is the same type as used with the
|
||||
* dispense() function. If RedBean finds the bean it will return
|
||||
* the OODB Bean object; if it cannot find the bean
|
||||
* RedBean will return a new bean of type $type and with
|
||||
* primary key ID 0. In the latter case it acts basically the
|
||||
* same as dispense().
|
||||
*
|
||||
* Important note:
|
||||
* If the bean cannot be found in the database a new bean of
|
||||
* the specified type will be generated and returned.
|
||||
*
|
||||
* @param string $type type of bean you want to load
|
||||
* @param integer $id ID of the bean you want to load
|
||||
*
|
||||
* @return OODBBean
|
||||
* @throws SQLException
|
||||
*/
|
||||
public function load( $type, $id )
|
||||
{
|
||||
$bean = $this->dispense( $type );
|
||||
if ( isset( $this->stash[$this->nesting][$id] ) ) {
|
||||
$row = $this->stash[$this->nesting][$id];
|
||||
} else {
|
||||
try {
|
||||
$rows = $this->writer->queryRecord( $type, array( 'id' => array( $id ) ) );
|
||||
} catch ( SQLException $exception ) {
|
||||
if ( $this->writer->sqlStateIn( $exception->getSQLState(),
|
||||
array(
|
||||
QueryWriter::C_SQLSTATE_NO_SUCH_COLUMN,
|
||||
QueryWriter::C_SQLSTATE_NO_SUCH_TABLE )
|
||||
)
|
||||
) {
|
||||
throw $exception; //only throw if frozen
|
||||
}
|
||||
}
|
||||
if ( empty( $rows ) ) {
|
||||
return $bean;
|
||||
}
|
||||
$row = array_pop( $rows );
|
||||
}
|
||||
$bean->importRow( $row );
|
||||
$this->nesting++;
|
||||
$this->oodb->signal( 'open', $bean );
|
||||
$this->nesting--;
|
||||
|
||||
return $bean->setMeta( 'tainted', FALSE );
|
||||
}
|
||||
}
|
|
@ -1,113 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RedBeanPHP;
|
||||
|
||||
use RedBeanPHP\OODBBean as OODBBean;
|
||||
|
||||
/**
|
||||
* SimpleModel
|
||||
* Base Model For All RedBeanPHP Models using FUSE.
|
||||
*
|
||||
* RedBeanPHP FUSE is a mechanism to connect beans to posthoc
|
||||
* models. Models are connected to beans by naming conventions.
|
||||
* Actions on beans will result in actions on models.
|
||||
*
|
||||
* @file RedBeanPHP/SimpleModel.php
|
||||
* @author Gabor de Mooij and the RedBeanPHP Team
|
||||
* @license BSD/GPLv2
|
||||
*
|
||||
* @copyright
|
||||
* copyright (c) G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community
|
||||
* This source file is subject to the BSD/GPLv2 License that is bundled
|
||||
* with this source code in the file license.txt.
|
||||
*/
|
||||
class SimpleModel
|
||||
{
|
||||
/**
|
||||
* @var OODBBean
|
||||
*/
|
||||
protected $bean;
|
||||
|
||||
/**
|
||||
* Used by FUSE: the ModelHelper class to connect a bean to a model.
|
||||
* This method loads a bean in the model.
|
||||
*
|
||||
* @param OODBBean $bean bean to load
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function loadBean( OODBBean $bean )
|
||||
{
|
||||
$this->bean = $bean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic Getter to make the bean properties available from
|
||||
* the $this-scope.
|
||||
*
|
||||
* @note this method returns a value, not a reference!
|
||||
* To obtain a reference unbox the bean first!
|
||||
*
|
||||
* @param string $prop property to get
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get( $prop )
|
||||
{
|
||||
return $this->bean->$prop;
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic Setter.
|
||||
* Sets the value directly as a bean property.
|
||||
*
|
||||
* @param string $prop property to set value of
|
||||
* @param mixed $value value to set
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __set( $prop, $value )
|
||||
{
|
||||
$this->bean->$prop = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Isset implementation.
|
||||
* Implements the isset function for array-like access.
|
||||
*
|
||||
* @param string $key key to check
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function __isset( $key )
|
||||
{
|
||||
return isset( $this->bean->$key );
|
||||
}
|
||||
|
||||
/**
|
||||
* Box the bean using the current model.
|
||||
* This method wraps the current bean in this model.
|
||||
* This method can be reached using FUSE through a simple
|
||||
* OODBBean. The method returns a RedBeanPHP Simple Model.
|
||||
* This is useful if you would like to rely on PHP type hinting.
|
||||
* You can box your beans before passing them to functions or methods
|
||||
* with typed parameters.
|
||||
*
|
||||
* @return SimpleModel
|
||||
*/
|
||||
public function box()
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unbox the bean from the model.
|
||||
* This method returns the bean inside the model.
|
||||
*
|
||||
* @return OODBBean
|
||||
*/
|
||||
public function unbox()
|
||||
{
|
||||
return $this->bean;
|
||||
}
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RedBeanPHP;
|
||||
|
||||
use RedBeanPHP\Observer as Observer;
|
||||
use RedBeanPHP\OODBBean as OODBBean;
|
||||
use RedBeanPHP\Observable as Observable;
|
||||
|
||||
/**
|
||||
* RedBean Model Helper.
|
||||
*
|
||||
* Connects beans to models.
|
||||
* This is the core of so-called FUSE.
|
||||
*
|
||||
* @file RedBeanPHP/ModelHelper.php
|
||||
* @author Gabor de Mooij and the RedBeanPHP Community
|
||||
* @license BSD/GPLv2
|
||||
*
|
||||
* @copyright
|
||||
* copyright (c) G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community
|
||||
* This source file is subject to the BSD/GPLv2 License that is bundled
|
||||
* with this source code in the file license.txt.
|
||||
*/
|
||||
class SimpleModelHelper implements Observer
|
||||
{
|
||||
|
||||
/**
|
||||
* @see Observer::onEvent
|
||||
*/
|
||||
public function onEvent( $eventName, $bean )
|
||||
{
|
||||
$bean->$eventName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches the FUSE event listeners. Now the Model Helper will listen for
|
||||
* CRUD events. If a CRUD event occurs it will send a signal to the model
|
||||
* that belongs to the CRUD bean and this model will take over control from
|
||||
* there.
|
||||
*
|
||||
* @param Observable $observable object to observe
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function attachEventListeners( Observable $observable )
|
||||
{
|
||||
foreach ( array( 'update', 'open', 'delete', 'after_delete', 'after_update', 'dispense' ) as $e ) {
|
||||
$observable->addEventListener( $e, $this );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,265 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RedBeanPHP;
|
||||
|
||||
use RedBeanPHP\ToolBox as ToolBox;
|
||||
use RedBeanPHP\AssociationManager as AssociationManager;
|
||||
use RedBeanPHP\OODBBean as OODBBean;
|
||||
|
||||
/**
|
||||
* RedBeanPHP Tag Manager.
|
||||
*
|
||||
* The tag manager offers an easy way to quickly implement basic tagging
|
||||
* functionality.
|
||||
*
|
||||
* Provides methods to tag beans and perform tag-based searches in the
|
||||
* bean database.
|
||||
*
|
||||
* @file RedBeanPHP/TagManager.php
|
||||
* @author Gabor de Mooij and the RedBeanPHP community
|
||||
* @license BSD/GPLv2
|
||||
*
|
||||
* @copyright
|
||||
* copyright (c) G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community
|
||||
* This source file is subject to the BSD/GPLv2 License that is bundled
|
||||
* with this source code in the file license.txt.
|
||||
*/
|
||||
class TagManager
|
||||
{
|
||||
/**
|
||||
* @var ToolBox
|
||||
*/
|
||||
protected $toolbox;
|
||||
|
||||
/**
|
||||
* @var AssociationManager
|
||||
*/
|
||||
protected $associationManager;
|
||||
|
||||
/**
|
||||
* @var OODBBean
|
||||
*/
|
||||
protected $redbean;
|
||||
|
||||
/**
|
||||
* Checks if the argument is a comma separated string, in this case
|
||||
* it will split the string into words and return an array instead.
|
||||
* In case of an array the argument will be returned 'as is'.
|
||||
*
|
||||
* @param array|string $tagList list of tags
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function extractTagsIfNeeded( $tagList )
|
||||
{
|
||||
if ( $tagList !== FALSE && !is_array( $tagList ) ) {
|
||||
$tags = explode( ',', (string) $tagList );
|
||||
} else {
|
||||
$tags = $tagList;
|
||||
}
|
||||
|
||||
return $tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a tag bean by it's title.
|
||||
* Internal method.
|
||||
*
|
||||
* @param string $title title to search for
|
||||
*
|
||||
* @return OODBBean
|
||||
*/
|
||||
protected function findTagByTitle( $title )
|
||||
{
|
||||
$beans = $this->redbean->find( 'tag', array( 'title' => array( $title ) ) );
|
||||
|
||||
if ( $beans ) {
|
||||
$bean = reset( $beans );
|
||||
|
||||
return $bean;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* The tag manager offers an easy way to quickly implement basic tagging
|
||||
* functionality.
|
||||
*
|
||||
* @param ToolBox $toolbox toolbox object
|
||||
*/
|
||||
public function __construct( ToolBox $toolbox )
|
||||
{
|
||||
$this->toolbox = $toolbox;
|
||||
$this->redbean = $toolbox->getRedBean();
|
||||
|
||||
$this->associationManager = $this->redbean->getAssociationManager();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether a bean has been associated with one ore more
|
||||
* of the listed tags. If the third parameter is TRUE this method
|
||||
* will return TRUE only if all tags that have been specified are indeed
|
||||
* associated with the given bean, otherwise FALSE.
|
||||
* If the third parameter is FALSE this
|
||||
* method will return TRUE if one of the tags matches, FALSE if none
|
||||
* match.
|
||||
*
|
||||
* Tag list can be either an array with tag names or a comma separated list
|
||||
* of tag names.
|
||||
*
|
||||
* @param OODBBean $bean bean to check for tags
|
||||
* @param array|string $tags list of tags
|
||||
* @param boolean $all whether they must all match or just some
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasTag( $bean, $tags, $all = FALSE )
|
||||
{
|
||||
$foundtags = $this->tag( $bean );
|
||||
|
||||
$tags = $this->extractTagsIfNeeded( $tags );
|
||||
$same = array_intersect( $tags, $foundtags );
|
||||
|
||||
if ( $all ) {
|
||||
return ( implode( ',', $same ) === implode( ',', $tags ) );
|
||||
}
|
||||
|
||||
return (bool) ( count( $same ) > 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all sepcified tags from the bean. The tags specified in
|
||||
* the second parameter will no longer be associated with the bean.
|
||||
*
|
||||
* Tag list can be either an array with tag names or a comma separated list
|
||||
* of tag names.
|
||||
*
|
||||
* @param OODBBean $bean tagged bean
|
||||
* @param array|string $tagList list of tags (names)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function untag( $bean, $tagList )
|
||||
{
|
||||
$tags = $this->extractTagsIfNeeded( $tagList );
|
||||
|
||||
foreach ( $tags as $tag ) {
|
||||
if ( $t = $this->findTagByTitle( $tag ) ) {
|
||||
$this->associationManager->unassociate( $bean, $t );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tags a bean or returns tags associated with a bean.
|
||||
* If $tagList is NULL or omitted this method will return a
|
||||
* comma separated list of tags associated with the bean provided.
|
||||
* If $tagList is a comma separated list (string) of tags all tags will
|
||||
* be associated with the bean.
|
||||
* You may also pass an array instead of a string.
|
||||
*
|
||||
* Tag list can be either an array with tag names or a comma separated list
|
||||
* of tag names.
|
||||
*
|
||||
* @param OODBBean $bean bean to be tagged
|
||||
* @param array|string $tagList a list of tags
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function tag( OODBBean $bean, $tagList = NULL )
|
||||
{
|
||||
if ( is_null( $tagList ) ) {
|
||||
|
||||
$tags = $bean->sharedTag;
|
||||
$foundTags = array();
|
||||
|
||||
foreach ( $tags as $tag ) {
|
||||
$foundTags[] = $tag->title;
|
||||
}
|
||||
|
||||
return $foundTags;
|
||||
}
|
||||
|
||||
$this->associationManager->clearRelations( $bean, 'tag' );
|
||||
$this->addTags( $bean, $tagList );
|
||||
|
||||
return $tagList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds tags to a bean.
|
||||
* If $tagList is a comma separated list of tags all tags will
|
||||
* be associated with the bean.
|
||||
* You may also pass an array instead of a string.
|
||||
*
|
||||
* Tag list can be either an array with tag names or a comma separated list
|
||||
* of tag names.
|
||||
*
|
||||
* @param OODBBean $bean bean to add tags to
|
||||
* @param array|string $tagList list of tags to add to bean
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addTags( OODBBean $bean, $tagList )
|
||||
{
|
||||
$tags = $this->extractTagsIfNeeded( $tagList );
|
||||
|
||||
if ( $tagList === FALSE ) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ( $tags as $tag ) {
|
||||
if ( !$t = $this->findTagByTitle( $tag ) ) {
|
||||
$t = $this->redbean->dispense( 'tag' );
|
||||
$t->title = $tag;
|
||||
|
||||
$this->redbean->store( $t );
|
||||
}
|
||||
|
||||
$this->associationManager->associate( $bean, $t );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all beans that have been tagged with one or more
|
||||
* of the specified tags.
|
||||
*
|
||||
* Tag list can be either an array with tag names or a comma separated list
|
||||
* of tag names.
|
||||
*
|
||||
* @param string $beanType type of bean you are looking for
|
||||
* @param array|string $tagList list of tags to match
|
||||
* @param string $sql additional SQL (use only for pagination)
|
||||
* @param array $bindings bindings
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function tagged( $beanType, $tagList, $sql = '', $bindings = array() )
|
||||
{
|
||||
$tags = $this->extractTagsIfNeeded( $tagList );
|
||||
$records = $this->toolbox->getWriter()->queryTagged( $beanType, $tags, FALSE, $sql, $bindings );
|
||||
|
||||
return $this->redbean->convertToBeans( $beanType, $records );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all beans that have been tagged with ALL of the tags given.
|
||||
*
|
||||
* Tag list can be either an array with tag names or a comma separated list
|
||||
* of tag names.
|
||||
*
|
||||
* @param string $beanType type of bean you are looking for
|
||||
* @param array|string $tagList list of tags to match
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function taggedAll( $beanType, $tagList, $sql = '', $bindings = array() )
|
||||
{
|
||||
$tags = $this->extractTagsIfNeeded( $tagList );
|
||||
$records = $this->toolbox->getWriter()->queryTagged( $beanType, $tags, TRUE, $sql, $bindings );
|
||||
|
||||
return $this->redbean->convertToBeans( $beanType, $records );
|
||||
}
|
||||
}
|
|
@ -1,103 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RedBeanPHP;
|
||||
|
||||
use RedBeanPHP\OODB as OODB;
|
||||
use RedBeanPHP\QueryWriter as QueryWriter;
|
||||
use RedBeanPHP\Adapter\DBAdapter as DBAdapter;
|
||||
use RedBeanPHP\Adapter as Adapter;
|
||||
|
||||
/**
|
||||
* ToolBox.
|
||||
*
|
||||
* The toolbox is an integral part of RedBeanPHP providing the basic
|
||||
* architectural building blocks to manager objects, helpers and additional tools
|
||||
* like plugins. A toolbox contains the three core components of RedBeanPHP:
|
||||
* the adapter, the query writer and the core functionality of RedBeanPHP in
|
||||
* OODB.
|
||||
*
|
||||
* @file RedBeanPHP/ToolBox.php
|
||||
* @author Gabor de Mooij and the RedBeanPHP community
|
||||
* @license BSD/GPLv2
|
||||
*
|
||||
* @copyright
|
||||
* copyright (c) G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community.
|
||||
* This source file is subject to the BSD/GPLv2 License that is bundled
|
||||
* with this source code in the file license.txt.
|
||||
*/
|
||||
class ToolBox
|
||||
{
|
||||
|
||||
/**
|
||||
* @var OODB
|
||||
*/
|
||||
protected $oodb;
|
||||
|
||||
/**
|
||||
* @var QueryWriter
|
||||
*/
|
||||
protected $writer;
|
||||
|
||||
/**
|
||||
* @var DBAdapter
|
||||
*/
|
||||
protected $adapter;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* The toolbox is an integral part of RedBeanPHP providing the basic
|
||||
* architectural building blocks to manager objects, helpers and additional tools
|
||||
* like plugins. A toolbox contains the three core components of RedBeanPHP:
|
||||
* the adapter, the query writer and the core functionality of RedBeanPHP in
|
||||
* OODB.
|
||||
*
|
||||
* @param OODB $oodb Object Database, OODB
|
||||
* @param DBAdapter $adapter Database Adapter
|
||||
* @param QueryWriter $writer Query Writer
|
||||
*/
|
||||
public function __construct( OODB $oodb, Adapter $adapter, QueryWriter $writer )
|
||||
{
|
||||
$this->oodb = $oodb;
|
||||
$this->adapter = $adapter;
|
||||
$this->writer = $writer;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the query writer in this toolbox.
|
||||
* The Query Writer is responsible for building the queries for a
|
||||
* specific database and executing them through the adapter.
|
||||
*
|
||||
* @return QueryWriter
|
||||
*/
|
||||
public function getWriter()
|
||||
{
|
||||
return $this->writer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the OODB instance in this toolbox.
|
||||
* OODB is responsible for creating, storing, retrieving and deleting
|
||||
* single beans. Other components rely
|
||||
* on OODB for their basic functionality.
|
||||
*
|
||||
* @return OODB
|
||||
*/
|
||||
public function getRedBean()
|
||||
{
|
||||
return $this->oodb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the database adapter in this toolbox.
|
||||
* The adapter is responsible for executing the query and binding the values.
|
||||
* The adapter also takes care of transaction handling.
|
||||
*
|
||||
* @return DBAdapter
|
||||
*/
|
||||
public function getDatabaseAdapter()
|
||||
{
|
||||
return $this->adapter;
|
||||
}
|
||||
}
|
|
@ -1,316 +0,0 @@
|
|||
|
||||
RedBeanPHP
|
||||
Written by Gabor de Mooij
|
||||
|
||||
RedBean is DUAL Licensed New BSD and GPLv2. You may choose the license that fits
|
||||
best for your project.
|
||||
|
||||
New BSD License
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of RedBeanPHP nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY GABOR DE MOOIJ ''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 GABOR DE MOOIJ 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.
|
||||
|
||||
RedBeanPHP is Written by Gabor de Mooij (G.J.G.T de Mooij) Copyright (c) 2015.
|
||||
|
||||
|
||||
GPLv2 LICENSE
|
||||
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
|
@ -1,79 +0,0 @@
|
|||
<?php
|
||||
|
||||
//Set the directory path
|
||||
define('REDBEANPHP_MAIN_DIR', 'phar://rb.phar/RedBeanPHP/');
|
||||
|
||||
//Load Database drivers
|
||||
require( REDBEANPHP_MAIN_DIR . 'Logger.php' );
|
||||
require( REDBEANPHP_MAIN_DIR . 'Logger/RDefault.php' );
|
||||
require( REDBEANPHP_MAIN_DIR . 'Logger/RDefault/Debug.php' );
|
||||
require( REDBEANPHP_MAIN_DIR . 'Driver.php' );
|
||||
require( REDBEANPHP_MAIN_DIR . 'Driver/RPDO.php' );
|
||||
|
||||
//Load Infrastructure
|
||||
require( REDBEANPHP_MAIN_DIR . 'OODBBean.php' );
|
||||
require( REDBEANPHP_MAIN_DIR . 'Observable.php' );
|
||||
require( REDBEANPHP_MAIN_DIR . 'Observer.php' );
|
||||
|
||||
//Load Database Adapters
|
||||
require( REDBEANPHP_MAIN_DIR . 'Adapter.php' );
|
||||
require( REDBEANPHP_MAIN_DIR . 'Adapter/DBAdapter.php' );
|
||||
require( REDBEANPHP_MAIN_DIR . 'Cursor.php');
|
||||
require( REDBEANPHP_MAIN_DIR . 'Cursor/PDOCursor.php');
|
||||
require( REDBEANPHP_MAIN_DIR . 'Cursor/NullCursor.php');
|
||||
require( REDBEANPHP_MAIN_DIR . 'BeanCollection.php' );
|
||||
|
||||
//Load SQL drivers
|
||||
require( REDBEANPHP_MAIN_DIR . 'QueryWriter.php' );
|
||||
require( REDBEANPHP_MAIN_DIR . 'QueryWriter/AQueryWriter.php' );
|
||||
require( REDBEANPHP_MAIN_DIR . 'QueryWriter/MySQL.php' );
|
||||
require( REDBEANPHP_MAIN_DIR . 'QueryWriter/SQLiteT.php' );
|
||||
require( REDBEANPHP_MAIN_DIR . 'QueryWriter/PostgreSQL.php' );
|
||||
|
||||
//Load required Exceptions
|
||||
require( REDBEANPHP_MAIN_DIR . 'RedException.php' );
|
||||
require( REDBEANPHP_MAIN_DIR . 'RedException/SQL.php' );
|
||||
|
||||
//Load Repository Classes
|
||||
require( REDBEANPHP_MAIN_DIR . 'Repository.php' );
|
||||
require( REDBEANPHP_MAIN_DIR . 'Repository/Fluid.php' );
|
||||
require( REDBEANPHP_MAIN_DIR . 'Repository/Frozen.php' );
|
||||
|
||||
//Load Core functionality
|
||||
require( REDBEANPHP_MAIN_DIR . 'OODB.php' );
|
||||
require( REDBEANPHP_MAIN_DIR . 'ToolBox.php' );
|
||||
require( REDBEANPHP_MAIN_DIR . 'Finder.php' );
|
||||
|
||||
//Load extended functionality
|
||||
require( REDBEANPHP_MAIN_DIR . 'AssociationManager.php' );
|
||||
require( REDBEANPHP_MAIN_DIR . 'BeanHelper.php' );
|
||||
require( REDBEANPHP_MAIN_DIR . 'BeanHelper/SimpleFacadeBeanHelper.php' );
|
||||
|
||||
/* Developer Comfort */
|
||||
require( REDBEANPHP_MAIN_DIR . 'SimpleModel.php' );
|
||||
require( REDBEANPHP_MAIN_DIR . 'SimpleModelHelper.php' );
|
||||
require( REDBEANPHP_MAIN_DIR . 'TagManager.php' );
|
||||
require( REDBEANPHP_MAIN_DIR . 'LabelMaker.php' );
|
||||
require( REDBEANPHP_MAIN_DIR . 'Facade.php' );
|
||||
require( REDBEANPHP_MAIN_DIR . 'DuplicationManager.php' );
|
||||
require( REDBEANPHP_MAIN_DIR . 'Plugin.php' );
|
||||
require( REDBEANPHP_MAIN_DIR . 'Functions.php' );
|
||||
|
||||
/* Facade Utilities */
|
||||
require( REDBEANPHP_MAIN_DIR . 'Util/ArrayTool.php' );
|
||||
require( REDBEANPHP_MAIN_DIR . 'Util/DispenseHelper.php' );
|
||||
require( REDBEANPHP_MAIN_DIR . 'Util/Dump.php' );
|
||||
require( REDBEANPHP_MAIN_DIR . 'Util/MultiLoader.php' );
|
||||
require( REDBEANPHP_MAIN_DIR . 'Util/Transaction.php' );
|
||||
|
||||
//Allow users to mount the plugin folder.
|
||||
if ( defined( 'REDBEANPHP_PLUGINS' ) ) {
|
||||
Phar::mount( 'RedBeanPHP/Plugin', REDBEANPHP_PLUGINS );
|
||||
}
|
||||
|
||||
//make some classes available for backward compatibility
|
||||
class RedBean_SimpleModel extends \RedBeanPHP\SimpleModel {};
|
||||
|
||||
if (!class_exists('R')) {
|
||||
class R extends \RedBeanPHP\Facade{};
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
{
|
||||
"name": "gabordemooij/redbean",
|
||||
"description": "RedBeanPHP ORM",
|
||||
"keywords": ["orm"],
|
||||
"homepage": "http://redbeanphp.com/",
|
||||
"license": "New BSD and GPLv2",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Gabor de Mooij",
|
||||
"email": "gabor@redbeanphp.com",
|
||||
"homepage": "http://redbeanphp.com"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.3.4"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"RedBeanPHP\\" : "RedBeanPHP"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Strips out all fluid functions (experimental)
|
||||
*/
|
||||
$functions = array(
|
||||
'addFK','addIndex','addUniqueConstraint','createTable',
|
||||
'widenColumn','buildFK','addColumn','wipeAll'
|
||||
);
|
||||
$code = file_get_contents('rb.php');
|
||||
$functionDefs = array();
|
||||
foreach($functions as $function) {
|
||||
$functionDefs[] = "public function $function";
|
||||
$functionDefs[] = "private function $function";
|
||||
$functionDefs[] = "protected function $function";
|
||||
$functionDefs[] = "public static function $function";
|
||||
$functionDefs[] = "private static function $function";
|
||||
$functionDefs[] = "protected static function $function";
|
||||
}
|
||||
$functionDefs[] = 'class Fluid extends Repository';
|
||||
foreach( $functionDefs as $function ) {
|
||||
while( strpos( $code, $function ) !== FALSE ) {
|
||||
$begin = strpos( $code, $function );
|
||||
$pointer = $begin;
|
||||
$char = '';
|
||||
while( $char !== '{' && $char !== ';' ) {
|
||||
echo $char;
|
||||
$char = substr( $code, $pointer, 1);
|
||||
$pointer ++;
|
||||
}
|
||||
if ($char === ';') {
|
||||
$code = substr( $code, 0, $begin-1 ) . substr( $code, $pointer );
|
||||
continue;
|
||||
}
|
||||
if ($char === '{') {
|
||||
$nesting = 1;
|
||||
$pointer ++;
|
||||
$beginOfFunction = $pointer;
|
||||
while( !( $char === '}' && $nesting === 0 ) ) {
|
||||
$char = substr( $code, $pointer, 1);
|
||||
if ($char === '{') { $nesting ++; echo "($nesting)"; }
|
||||
if ($char === '}') { $nesting --; echo "($nesting)"; }
|
||||
$pointer ++;
|
||||
}
|
||||
$code = substr( $code, 0, $begin-1 ) . substr( $code, $pointer );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
file_put_contents('rbf.php', $code);
|
|
@ -1,19 +0,0 @@
|
|||
<?php
|
||||
|
||||
echo "Running Patch P533...";
|
||||
echo PHP_EOL;
|
||||
|
||||
$code = file_get_contents('rb.php');
|
||||
$code = str_replace('&offsetGet', 'offsetGet', $code);
|
||||
|
||||
$bytes = file_put_contents('rb-p533.php', $code);
|
||||
|
||||
if ($bytes > 0) {
|
||||
echo 'Applied patch for PHP < 5.3.3';
|
||||
echo PHP_EOL;
|
||||
exit;
|
||||
} else {
|
||||
echo 'Somthing went wrong.';
|
||||
echo PHP_EOL;
|
||||
exit;
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
<?php
|
||||
|
||||
echo "Welcome to Replica 2 Build Script for RedBeanPHP\n";
|
||||
echo "Now building your beans!\n";
|
||||
echo "-------------------------------------------\n";
|
||||
|
||||
echo "Cleaning up... ";
|
||||
@exec('del /q rb.phar');
|
||||
@exec('del /q build');
|
||||
echo "Done.\n";
|
||||
|
||||
echo "Trying to create a directory called build to build the PHAR... ";
|
||||
@mkdir('build');
|
||||
@mkdir('build\RedBeanPHP');
|
||||
echo "Done.\n";
|
||||
|
||||
echo "Trying to copy RedBeanPHP to build/RedBeanPHP... ";
|
||||
@exec('xcopy .\RedBeanPHP .\build\RedBeanPHP /e /y');
|
||||
echo "Done.\n";
|
||||
|
||||
echo "Moving loader to build folder... ";
|
||||
@exec('move .\build\RedBeanPHP\loader.php .\build\loader.php');
|
||||
echo "Done.\n";
|
||||
|
||||
echo "Creating PHAR archive... ";
|
||||
$phar = new Phar("rb.phar", 0, "rb.phar");
|
||||
$phar->buildFromDirectory('./build');
|
||||
echo "Done.\n";
|
||||
|
||||
echo "Adding stub... ";
|
||||
$phar->setStub($phar->createDefaultStub("loader.php"));
|
||||
echo "Done.\n";
|
||||
|
||||
echo "Your PHAR file has been generated.\n";
|
|
@ -1,128 +0,0 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
$mode = 'default';
|
||||
if ($_SERVER['argc']>1) $mode = $_SERVER['argv'][1];
|
||||
|
||||
echo "Welcome to Replica 2 Build Script for RedBeanPHP\n";
|
||||
echo "Now building your beans!\n";
|
||||
echo "-------------------------------------------\n";
|
||||
|
||||
if ($mode !== 'onlyphp') {
|
||||
echo "Cleaning up... ";
|
||||
@exec('rm rb.phar; rm -Rf build');
|
||||
echo "Done.\n";
|
||||
echo "Trying to create a directory called build to build the PHAR... ";
|
||||
@mkdir('build');
|
||||
echo "Done.\n";
|
||||
echo "Trying to copy RedBeanPHP to build/RedBeanPHP... ";
|
||||
@exec('cp -R RedBeanPHP build/RedBeanPHP');
|
||||
echo "Done.\n";
|
||||
echo "Moving loader to build folder... ";
|
||||
@exec('mv build/RedBeanPHP/loader.php build/');
|
||||
echo "Done.\n";
|
||||
echo "Creating PHAR archive... ";
|
||||
$phar = new Phar("rb.phar", 0, "rb.phar");
|
||||
$phar->buildFromDirectory('./build', '/^((?!loader\.php).)*$/');
|
||||
echo "Done.\n";
|
||||
echo "Adding stub... ";
|
||||
$stub = "<"."?php Phar::mapPhar();\n";
|
||||
$stub .= str_replace('<'.'?php','',file_get_contents('build/loader.php'));
|
||||
$stub .= "__HALT_COMPILER();\n";
|
||||
$phar->setStub($stub);
|
||||
echo "Done.\n";
|
||||
echo "Your PHAR file has been generated.\n";
|
||||
}
|
||||
|
||||
if ($mode !== 'onlyphar') {
|
||||
|
||||
$code = '';
|
||||
|
||||
function addFile($file) {
|
||||
global $code;
|
||||
echo 'Added ', $file , ' to package... ',PHP_EOL;
|
||||
$raw = file_get_contents($file);
|
||||
$raw = preg_replace('/namespace\s+([a-zA-Z0-9\\\;]+);/m', 'namespace $1 {', $raw);
|
||||
$raw .= '}';
|
||||
$code .= $raw;
|
||||
}
|
||||
|
||||
define('DIR', 'RedBeanPHP/');
|
||||
|
||||
addFile( DIR . 'Logger.php' );
|
||||
addFile( DIR . 'Logger/RDefault.php' );
|
||||
addFile( DIR . 'Logger/RDefault/Debug.php' );
|
||||
addFile( DIR . 'Driver.php' );
|
||||
addFile( DIR . 'Driver/RPDO.php' );
|
||||
addFile( DIR . 'OODBBean.php' );
|
||||
addFile( DIR . 'Observable.php' );
|
||||
addFile( DIR . 'Observer.php' );
|
||||
addFile( DIR . 'Adapter.php' );
|
||||
addFile( DIR . 'Adapter/DBAdapter.php' );
|
||||
addFile( DIR . 'Cursor.php');
|
||||
addFile( DIR . 'Cursor/PDOCursor.php');
|
||||
addFile( DIR . 'Cursor/NullCursor.php');
|
||||
addFile( DIR . 'BeanCollection.php' );
|
||||
addFile( DIR . 'QueryWriter.php' );
|
||||
addFile( DIR . 'QueryWriter/AQueryWriter.php' );
|
||||
addFile( DIR . 'QueryWriter/MySQL.php' );
|
||||
addFile( DIR . 'QueryWriter/SQLiteT.php' );
|
||||
addFile( DIR . 'QueryWriter/PostgreSQL.php' );
|
||||
addFile( DIR . 'RedException.php' );
|
||||
addFile( DIR . 'RedException/SQL.php' );
|
||||
addFile( DIR . 'Repository.php' );
|
||||
addFile( DIR . 'Repository/Fluid.php' );
|
||||
addFile( DIR . 'Repository/Frozen.php' );
|
||||
addFile( DIR . 'OODB.php' );
|
||||
addFile( DIR . 'ToolBox.php' );
|
||||
addFile( DIR . 'Finder.php' );
|
||||
addFile( DIR . 'AssociationManager.php' );
|
||||
addFile( DIR . 'BeanHelper.php' );
|
||||
addFile( DIR . 'BeanHelper/SimpleFacadeBeanHelper.php' );
|
||||
addFile( DIR . 'SimpleModel.php' );
|
||||
addFile( DIR . 'SimpleModelHelper.php' );
|
||||
addFile( DIR . 'TagManager.php' );
|
||||
addFile( DIR . 'LabelMaker.php' );
|
||||
addFile( DIR . 'Facade.php' );
|
||||
addFile( DIR . 'DuplicationManager.php' );
|
||||
addFile( DIR . 'Util/ArrayTool.php' );
|
||||
addFile( DIR . 'Util/DispenseHelper.php' );
|
||||
addFile( DIR . 'Util/Dump.php' );
|
||||
addFile( DIR . 'Util/MultiLoader.php' );
|
||||
addFile( DIR . 'Util/Transaction.php' );
|
||||
addFile( DIR . 'Plugin.php' );
|
||||
|
||||
$func = file_get_contents(DIR . 'Functions.php');
|
||||
|
||||
$code .= "
|
||||
namespace {
|
||||
|
||||
//make some classes available for backward compatibility
|
||||
class RedBean_SimpleModel extends \RedBeanPHP\SimpleModel {};
|
||||
|
||||
if (!class_exists('R')) {
|
||||
class R extends \RedBeanPHP\Facade{};
|
||||
}
|
||||
|
||||
$func
|
||||
|
||||
}
|
||||
";
|
||||
|
||||
$code = '<?php'.str_replace('<?php', '', $code);
|
||||
|
||||
echo 'Okay, seems we have all the code.. now writing file: rb.php' ,PHP_EOL;
|
||||
|
||||
$b = file_put_contents('rb.php', $code);
|
||||
|
||||
echo 'Written: ',$b,' bytes.',PHP_EOL;
|
||||
|
||||
if ($b > 0) {
|
||||
echo 'Done!' ,PHP_EOL;
|
||||
} else {
|
||||
echo 'Hm, something seems to have gone wrong... ',PHP_EOL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
; Test suite database config
|
||||
; Rename this file to test.ini if you are done
|
||||
|
||||
[mysql]
|
||||
host = "localhost"
|
||||
schema = "oodb"
|
||||
user = "root"
|
||||
pass = "password"
|
||||
|
||||
[pgsql]
|
||||
host = "localhost"
|
||||
schema = "oodb"
|
||||
user = "postgres"
|
||||
pass = "password"
|
||||
|
||||
[sqlite]
|
||||
file = "/tmp/database.db"
|
|
@ -1,124 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RedUNIT;
|
||||
use RedBeanPHP\Facade as R;
|
||||
|
||||
/**
|
||||
* RedUNIT
|
||||
* Base class for RedUNIT, the micro unit test suite for RedBeanPHP
|
||||
*
|
||||
* @file RedUNIT/RedUNIT.php
|
||||
* @description Provides the basic logic for any unit test in RedUNIT.
|
||||
* @author Gabor de Mooij
|
||||
* @license BSD
|
||||
*
|
||||
*
|
||||
* (c) G.J.G.T. (Gabor) de Mooij
|
||||
* This source file is subject to the BSD/GPLv2 License that is bundled
|
||||
* with this source code in the file license.txt.
|
||||
*/
|
||||
abstract class RedUNIT
|
||||
{
|
||||
/**
|
||||
* @var integer
|
||||
*/
|
||||
protected $round;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $currentlyActiveDriverID = 'unknown';
|
||||
|
||||
/**
|
||||
* What drivers should be loaded for this test pack?
|
||||
*/
|
||||
abstract public function getTargetDrivers();
|
||||
|
||||
/**
|
||||
* Prepare test pack (mostly: nuke the entire database)
|
||||
*/
|
||||
public function prepare()
|
||||
{
|
||||
R::freeze( FALSE );
|
||||
|
||||
R::debug( FALSE );
|
||||
|
||||
R::nuke();
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the actual test
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$class = new \ReflectionClass( $this );
|
||||
|
||||
$skip = array( 'run', 'getTargetDrivers', 'onEvent');
|
||||
// Call all methods except run automatically
|
||||
foreach ( $class->getMethods( \ReflectionMethod::IS_PUBLIC ) as $method ) {
|
||||
// Skip methods inherited from parent class
|
||||
if ( $method->class != $class->getName() ) continue;
|
||||
|
||||
if ( in_array( $method->name, $skip ) ) continue;
|
||||
|
||||
$classname = str_replace( $class->getParentClass()->getName().'_', '', $method->class );
|
||||
|
||||
printtext( "\n\t" . $classname."->".$method->name." [".$method->class."->".$method->name."]" . " \n\t" );
|
||||
|
||||
$call = $method->name;
|
||||
|
||||
$this->$call();
|
||||
|
||||
try {
|
||||
R::nuke();
|
||||
} catch( \PDOException $e ) {
|
||||
// Some tests use a broken database on purpose, so an exception is ok
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Do some cleanup (if necessary..)
|
||||
*/
|
||||
public function cleanUp()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current driver.
|
||||
*/
|
||||
public function setCurrentDriver( $driver )
|
||||
{
|
||||
$this->currentlyActiveDriverID = $driver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the round number.
|
||||
*
|
||||
* @param integer $roundNumber round
|
||||
*/
|
||||
public function setRound( $roundNumber )
|
||||
{
|
||||
$this->round = (int) $roundNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current round number
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getRound()
|
||||
{
|
||||
return $this->round;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns TRUE if the current round is the first round.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isFirstRound()
|
||||
{
|
||||
return ( $this->round === 0 );
|
||||
}
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RedUNIT;
|
||||
|
||||
/**
|
||||
* Base
|
||||
*
|
||||
* @file RedUNIT/Base.php
|
||||
* @desc Base class for all drivers that support all database systems.
|
||||
* @author Gabor de Mooij and the RedBeanPHP Community
|
||||
* @license New BSD/GPLv2
|
||||
*
|
||||
* (c) G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community.
|
||||
* This source file is subject to the New BSD/GPLv2 License that is bundled
|
||||
* with this source code in the file license.txt.
|
||||
*/
|
||||
class Base extends RedUNIT
|
||||
{
|
||||
|
||||
/**
|
||||
* List of DB drivers
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $driverList = array( 'mysql', 'pgsql', 'sqlite', 'CUBRID', 'oracle' );
|
||||
|
||||
/**
|
||||
* Adds a driver to the list.
|
||||
*
|
||||
* @param string $driverID
|
||||
*/
|
||||
public static function addToDriverList( $driverID )
|
||||
{
|
||||
self::$driverList[] = $driverID;
|
||||
}
|
||||
|
||||
/**
|
||||
* What drivers should be loaded for this test pack?
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getTargetDrivers()
|
||||
{
|
||||
return self::$driverList;
|
||||
}
|
||||
}
|
|
@ -1,545 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RedUNIT\Base;
|
||||
|
||||
use RedUNIT\Base as Base;
|
||||
use RedBeanPHP\Facade as R;
|
||||
use RedBeanPHP\RedException as RedException;
|
||||
use RedBeanPHP\OODBBean as OODBBean;
|
||||
|
||||
/**
|
||||
* Aliasing
|
||||
*
|
||||
* @file RedUNIT/Base/Aliasing.php
|
||||
* @desc Tests for nested beans with aliases, i.e. teacher alias for person etc.
|
||||
* @author Gabor de Mooij and the RedBeanPHP Community
|
||||
* @license New BSD/GPLv2
|
||||
*
|
||||
* (c) G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community.
|
||||
* This source file is subject to the New BSD/GPLv2 License that is bundled
|
||||
* with this source code in the file license.txt.
|
||||
*/
|
||||
class Aliasing extends Base
|
||||
{
|
||||
/**
|
||||
* Tests automatic resolvement of parent beans
|
||||
* without fetchAs() using inferFetchType (foreign keys).
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testAutoResolver()
|
||||
{
|
||||
R::nuke();
|
||||
list( $project, $teacher, $student ) = R::dispenseAll( 'project,person,person' );
|
||||
$teacher->name = 'teacher';
|
||||
$student->name = 'student';
|
||||
$project->teacher = $teacher;
|
||||
$project->student = $student;
|
||||
R::store( $project );
|
||||
$project = $project->fresh();
|
||||
asrt( ( $project->teacher instanceof OODBBean), TRUE );
|
||||
asrt( ( $project->student instanceof OODBBean), TRUE );
|
||||
asrt( $project->teacher->name, 'teacher' );
|
||||
asrt( $project->student->name, 'student' );
|
||||
$project2 = R::dispense( 'project' );
|
||||
$teacher2 = R::dispense( 'person' );
|
||||
$teacher2->name = 'teacher2';
|
||||
$project2->teacher = $teacher2;
|
||||
R::store( $project2 );
|
||||
$project2 = $project2->fresh();
|
||||
asrt( ( $project2->teacher instanceof OODBBean), TRUE );
|
||||
asrt( $project2->teacher->name, 'teacher2' );
|
||||
asrt( is_null( $project2->student ), TRUE );
|
||||
$project = $project->fresh();
|
||||
asrt( ( $project->fetchAs('person')->teacher instanceof OODBBean), TRUE );
|
||||
asrt( ( $project->fetchAs('person')->student instanceof OODBBean), TRUE );
|
||||
asrt( $project->fetchAs('person')->teacher->name, 'teacher' );
|
||||
asrt( $project->fetchAs('person')->student->name, 'student' );
|
||||
$project = $project->fresh();
|
||||
$export = R::exportAll( array( $project ), TRUE );
|
||||
asrt( isset( $export[0]['teacher']['name'] ), TRUE );
|
||||
asrt( isset( $export[0]['student']['name'] ), TRUE );
|
||||
asrt( $export[0]['teacher']['name'], 'teacher' );
|
||||
asrt( $export[0]['student']['name'], 'student' );
|
||||
//Also test the default implementation...
|
||||
$nullWriter = new \NullWriter( R::getDatabaseAdapter() );
|
||||
asrt( is_null( $nullWriter->inferFetchType( 'test', 'test' ) ), TRUE );
|
||||
//Realteacher should take precedence over fetchAs-teacher, name conventions first!
|
||||
//also: ensure we do not use autoresolv for anything except when truly necessary! (performance)
|
||||
$realTeacher = R::dispense( 'teacher' );
|
||||
$realTeacher->name = 'real';
|
||||
R::store( $realTeacher );
|
||||
//ID must be same
|
||||
asrt( $realTeacher->id, $teacher->id );
|
||||
$project = $project->fresh();
|
||||
asrt( $project->teacher->name, 'real' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for aliasing issue for LTS version.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testIssueAliasingForLTSVersion() {
|
||||
$person = R::dispense('person');
|
||||
$pro = R::dispense('project');
|
||||
$c = R::dispense('course');
|
||||
$person->name = 'x';
|
||||
$person->alias('teacher')->ownProject[] = $pro;
|
||||
$person->alias('student')->ownCourse[] = $c;
|
||||
R::store($person);
|
||||
asrt($c->fresh()->fetchAs('person')->student->name, 'x');
|
||||
asrt($pro->fresh()->fetchAs('person')->teacher->name, 'x');
|
||||
$person = $person->fresh();
|
||||
$person->alias('teacher')->ownProject = array();
|
||||
$person->alias('student')->ownCourse = array();
|
||||
R::store($person);
|
||||
asrt($c->fresh()->fetchAs('person')->student, NULL);
|
||||
asrt($pro->fresh()->fetchAs('person')->teacher, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Describing how clearing state of bean works.
|
||||
* Every method returning somthing (except getID)
|
||||
* clears prefix-method-state (anything set by withCond,with,alias,fetchAs).
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function clearStateAdditionalTests()
|
||||
{
|
||||
list( $project1, $project2 ) = R::dispense( 'project', 2 );
|
||||
list( $irene, $ilse ) = R::dispense('person', 2);
|
||||
|
||||
$project1->developer = $ilse;
|
||||
$project1->designer = $irene;
|
||||
|
||||
$ilse->name = 'Ilse';
|
||||
$irene->name = 'Irene';
|
||||
|
||||
$project2->developer = $ilse;
|
||||
|
||||
R::storeAll( array( $project1, $project2 ) );
|
||||
|
||||
$ilse = R::load( 'person', $ilse->id );
|
||||
|
||||
asrt( count( $ilse->alias( 'developer' )->ownProject ), 2);
|
||||
|
||||
//cached - same list
|
||||
asrt( count( $ilse->ownProject ), 2);
|
||||
|
||||
asrt( count( $ilse->alias( 'designer' )->ownProject ), 0);
|
||||
|
||||
//cached - same list
|
||||
asrt( count( $ilse->ownProject ), 0);
|
||||
|
||||
//now test state
|
||||
asrt( count( $ilse->setAttr( 'a', 'b' )->alias( 'developer' )->ownProject ), 2);
|
||||
|
||||
//now test state
|
||||
$ilse = $ilse->fresh();
|
||||
|
||||
//attr clears state...
|
||||
asrt( count( $ilse->alias( 'developer' )->setAttr( 'a', 'b' )->ownProject ), 0);
|
||||
|
||||
//but getID() does not!
|
||||
$ilse = $ilse->fresh();
|
||||
$ilse->alias('developer');
|
||||
$ilse->getID();
|
||||
asrt( count( $ilse->ownProject ), 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Can switch fetchAs().
|
||||
* Also checks shadow by storing.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function canSwitchParentBean()
|
||||
{
|
||||
|
||||
list( $project1, $project2 ) = R::dispense( 'project', 2 );
|
||||
list( $irene, $ilse ) = R::dispense('person', 2);
|
||||
|
||||
$project1->developer = $ilse;
|
||||
$project1->designer = $irene;
|
||||
|
||||
$ilse->name = 'Ilse';
|
||||
$irene->name = 'Irene';
|
||||
|
||||
$project2->developer = $ilse;
|
||||
|
||||
R::storeAll( array( $project1, $project2 ) );
|
||||
|
||||
$project1 = R::load( 'project', $project1->id );
|
||||
|
||||
asrt( $project1->fetchAs('person')->developer->name, 'Ilse' );
|
||||
asrt( $project1->fetchAs('person')->designer->name, 'Irene' );
|
||||
|
||||
R::store( $project1 );
|
||||
|
||||
$project1 = R::load( 'project', $project1->id );
|
||||
|
||||
asrt( $project1->fetchAs('person')->designer->name, 'Irene' );
|
||||
asrt( $project1->fetchAs('person')->developer->name, 'Ilse' );
|
||||
|
||||
R::store( $project1 );
|
||||
|
||||
asrt( $project1->fetchAs('person')->developer->name, 'Ilse' );
|
||||
asrt( $project1->fetchAs('person')->designer->name, 'Irene' );
|
||||
asrt( $project1->fetchAs('person')->developer->name, 'Ilse' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Switching aliases (->alias) should not change other list during
|
||||
* storage.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testShadow()
|
||||
{
|
||||
list( $project1, $project2 ) = R::dispense( 'project', 2 );
|
||||
list( $irene, $ilse ) = R::dispense('person', 2);
|
||||
|
||||
$project1->developer = $ilse;
|
||||
$project1->designer = $irene;
|
||||
|
||||
$project2->developer = $ilse;
|
||||
|
||||
R::storeAll( array( $project1, $project2 ) );
|
||||
|
||||
$ilse = R::load( 'person', $ilse->id );
|
||||
$irene = R::load( 'person', $irene->id );
|
||||
|
||||
asrt( count( $ilse->alias('developer')->ownProject ), 2 );
|
||||
asrt( count( $ilse->alias('designer')->ownProject ), 0 );
|
||||
|
||||
R::store( $ilse );
|
||||
|
||||
$ilse = R::load( 'person', $ilse->id );
|
||||
$irene = R::load( 'person', $irene->id );
|
||||
|
||||
asrt( count( $ilse->alias('designer')->ownProject ), 0 );
|
||||
asrt( count( $ilse->alias('developer')->ownProject ), 2 );
|
||||
|
||||
R::storeAll( array( $ilse, $irene) );
|
||||
|
||||
$ilse = R::load( 'person', $ilse->id );
|
||||
$irene = R::load( 'person', $irene->id );
|
||||
|
||||
asrt( count( $ilse->alias('designer')->ownProject ), 0 );
|
||||
asrt( count( $ilse->alias('developer')->ownProject ), 2 );
|
||||
asrt( count( $irene->alias('designer')->ownProject), 1 );
|
||||
asrt( count( $irene->alias('developer')->ownProject), 0 );
|
||||
|
||||
R::storeAll( array( $ilse, $irene) );
|
||||
|
||||
$ilse = R::load( 'person', $ilse->id );
|
||||
$irene = R::load( 'person', $irene->id );
|
||||
|
||||
asrt( count( $ilse->alias('designer')->ownProject ), 0 );
|
||||
asrt( count( $ilse->alias('developer')->ownProject ), 2 );
|
||||
asrt( count( $irene->alias('designer')->ownProject), 1 );
|
||||
asrt( count( $irene->alias('developer')->ownProject), 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Issue 291. State not cleared.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testFetchTypeConfusionIssue291()
|
||||
{
|
||||
list( $teacher, $student ) = R::dispense( 'person', 2 ) ;
|
||||
$teacher->name = 'jimmy' ;
|
||||
$student->name = 'jacko' ;
|
||||
R::store( $teacher ) ;
|
||||
R::store( $student ) ;
|
||||
|
||||
$client = R::dispense( 'client' ) ;
|
||||
$client->firm = 'bean AG' ;
|
||||
R::store( $client ) ;
|
||||
|
||||
$project = R::dispense( 'project' ) ;
|
||||
$project->teacher = $teacher ;
|
||||
$project->student = $student ;
|
||||
$project->client = $client ;
|
||||
R::store( $project ) ;
|
||||
|
||||
unset( $project->student ) ;
|
||||
R::store( $project ) ;
|
||||
|
||||
$project = R::load( 'project', 1 ) ;
|
||||
$teacher = $project->fetchAs( 'person' )->teacher ;
|
||||
$student = $project->fetchAs( 'person' )->student ;
|
||||
$client = $project->client ; // this will select from "person" instead of "client"
|
||||
|
||||
asrt( $client->firm, 'bean AG' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test switching alias (also issue #291).
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testAliasSwitch()
|
||||
{
|
||||
$student = R::dispense( 'person' );
|
||||
$project = R::dispense( 'project' );
|
||||
$project->student = $student;
|
||||
R::store( $project );
|
||||
$person = R::load( 'person', $student->id );
|
||||
asrt( count( $person->alias( 'student' )->ownProject ), 1);
|
||||
asrt( count( $person->alias( 'teacher' )->ownProject ), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Associating two beans, then loading the associated bean
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testAssociated()
|
||||
{
|
||||
$person = R::dispense( 'person' );
|
||||
$person->name = 'John';
|
||||
|
||||
R::store( $person );
|
||||
|
||||
$course = R::dispense( 'course' );
|
||||
$course->name = 'Math';
|
||||
|
||||
R::store( $course );
|
||||
|
||||
$course->teacher = $person;
|
||||
|
||||
$id = R::store( $course );
|
||||
$course = R::load( 'course', $id );
|
||||
$teacher = $course->fetchAs( 'person' )->teacher;
|
||||
|
||||
asrt( $teacher->name, 'John' );
|
||||
|
||||
/**
|
||||
* Trying to load a property that has an invalid name
|
||||
*/
|
||||
|
||||
$book = R::dispense( 'book' );
|
||||
$page = R::dispense( 'page' );
|
||||
|
||||
$book->wrongProperty = array( $page );
|
||||
|
||||
try {
|
||||
$book->wrongProperty[] = $page;
|
||||
R::store( $book );
|
||||
fail();
|
||||
} catch ( RedException $e ) {
|
||||
pass();
|
||||
} catch (\Exception $e ) {
|
||||
fail();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for quick detect change.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function basic()
|
||||
{
|
||||
$book = R::dispense( 'book' );
|
||||
|
||||
asrt( isset( $book->prop ), FALSE ); //not a very good test
|
||||
asrt( in_array( 'prop', array_keys( $book->export() ) ), FALSE ); //better...
|
||||
|
||||
$book = R::dispense( 'book' );
|
||||
$page = R::dispense( 'page' );
|
||||
|
||||
$book->paper = $page;
|
||||
|
||||
$id = R::store( $book );
|
||||
$book = R::load( 'book', $id );
|
||||
|
||||
asrt( FALSE, ( isset( $book->paper ) ) );
|
||||
asrt( FALSE, ( isset( $book->page ) ) );
|
||||
|
||||
/**
|
||||
* The following tests try to store various things that aren't
|
||||
* beans (which is expected) with the own* and shared* properties
|
||||
* which only accept beans as assignments, so they're expected to fail
|
||||
*/
|
||||
|
||||
foreach (
|
||||
array(
|
||||
"a string", 1928, TRUE, NULL, array()
|
||||
)
|
||||
as $value
|
||||
) {
|
||||
try {
|
||||
$book->ownPage[] = $value;
|
||||
|
||||
R::store( $book );
|
||||
|
||||
$book->sharedPage[] = $value;
|
||||
|
||||
R::store( $book );
|
||||
|
||||
fail();
|
||||
} catch ( RedException $e ) {
|
||||
pass();
|
||||
} catch (\Exception $e ) {
|
||||
fail();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finding $person beans that have been aliased into various roles
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testAliasedFinder()
|
||||
{
|
||||
$message = R::dispense( 'message' );
|
||||
$message->subject = 'Roommate agreement';
|
||||
|
||||
list( $sender, $recipient ) = R::dispense( 'person', 2 );
|
||||
|
||||
$sender->name = 'Sheldon';
|
||||
$recipient->name = 'Leonard';
|
||||
|
||||
$message->sender = $sender;
|
||||
$message->recipient = $recipient;
|
||||
|
||||
$id = R::store( $message );
|
||||
$message = R::load( 'message', $id );
|
||||
|
||||
asrt( $message->fetchAs( 'person' )->sender->name, 'Sheldon' );
|
||||
asrt( $message->fetchAs( 'person' )->recipient->name, 'Leonard' );
|
||||
|
||||
$otherRecipient = R::dispense( 'person' );
|
||||
$otherRecipient->name = 'Penny';
|
||||
|
||||
$message->recipient = $otherRecipient;
|
||||
|
||||
R::store( $message );
|
||||
|
||||
$message = R::load( 'message', $id );
|
||||
|
||||
asrt( $message->fetchAs( 'person' )->sender->name, 'Sheldon' );
|
||||
asrt( $message->fetchAs( 'person' )->recipient->name, 'Penny' );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Basic Fetch AS functionality.
|
||||
*/
|
||||
public function testBasicFetchAs()
|
||||
{
|
||||
$project = R::dispense( 'project' );
|
||||
$project->name = 'Mutant Project';
|
||||
|
||||
list( $teacher, $student ) = R::dispense( 'person', 2 );
|
||||
|
||||
$teacher->name = 'Charles Xavier';
|
||||
|
||||
$project->student = $student;
|
||||
$project->student->name = 'Wolverine';
|
||||
$project->teacher = $teacher;
|
||||
|
||||
$id = R::store( $project );
|
||||
$project = R::load( 'project', $id );
|
||||
|
||||
asrt( $project->fetchAs( 'person' )->teacher->name, 'Charles Xavier' );
|
||||
asrt( $project->fetchAs( 'person' )->student->name, 'Wolverine' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Basic list variations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testBasicListVariations()
|
||||
{
|
||||
$farm = R::dispense( 'building' );
|
||||
$village = R::dispense( 'village' );
|
||||
|
||||
$farm->name = 'farm';
|
||||
$village->name = 'Dusty Mountains';
|
||||
|
||||
$farm->village = $village;
|
||||
|
||||
$id = R::store( $farm );
|
||||
$farm = R::load( 'building', $id );
|
||||
|
||||
asrt( $farm->name, 'farm' );
|
||||
asrt( $farm->village->name, 'Dusty Mountains' );
|
||||
|
||||
$village = R::dispense( 'village' );
|
||||
|
||||
list( $mill, $tavern ) = R::dispense( 'building', 2 );
|
||||
|
||||
$mill->name = 'Mill';
|
||||
$tavern->name = 'Tavern';
|
||||
|
||||
$village->ownBuilding = array( $mill, $tavern );
|
||||
|
||||
$id = R::store( $village );
|
||||
$village = R::load( 'village', $id );
|
||||
|
||||
asrt( count( $village->ownBuilding ), 2 );
|
||||
|
||||
$village2 = R::dispense( 'village' );
|
||||
$army = R::dispense( 'army' );
|
||||
|
||||
$village->sharedArmy[] = $army;
|
||||
$village2->sharedArmy[] = $army;
|
||||
|
||||
$id1 = R::store( $village );
|
||||
$id2 = R::store( $village2 );
|
||||
|
||||
$village1 = R::load( 'village', $id1 );
|
||||
$village2 = R::load( 'village', $id2 );
|
||||
|
||||
asrt( count( $village1->sharedArmy ), 1 );
|
||||
asrt( count( $village2->sharedArmy ), 1 );
|
||||
|
||||
asrt( count( $village1->ownArmy ), 0 );
|
||||
asrt( count( $village2->ownArmy ), 0 );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether aliasing plays nice with beautification.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testAliasWithBeautify()
|
||||
{
|
||||
/**
|
||||
* Ensure that aliased column aren't beautified
|
||||
*/
|
||||
|
||||
$points = R::dispense( 'point', 2 );
|
||||
$line = R::dispense( 'line' );
|
||||
|
||||
$line->pointA = $points[0];
|
||||
$line->pointB = $points[1];
|
||||
|
||||
R::store( $line );
|
||||
|
||||
$line2 = R::dispense( 'line' );
|
||||
|
||||
$line2->pointA = $line->fetchAs('point')->pointA;
|
||||
$line2->pointB = R::dispense( 'point' );
|
||||
|
||||
R::store( $line2 );
|
||||
|
||||
//now we have two points per line (1-to-x)
|
||||
//I want to know which lines cross A:
|
||||
|
||||
$a = R::load( 'point', $line->pointA->id ); //reload A
|
||||
|
||||
$lines = $a->alias( 'pointA' )->ownLine;
|
||||
|
||||
asrt( count( $lines ), 2 );
|
||||
}
|
||||
}
|
|
@ -1,302 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RedUNIT\Base;
|
||||
|
||||
use RedUNIT\Base as Base;
|
||||
use RedBeanPHP\Facade as R;
|
||||
|
||||
/**
|
||||
* Arrays
|
||||
*
|
||||
* @file RedUNIT/Base/Arrays.php
|
||||
* @desc Tests the array interface of beans
|
||||
* @author Gabor de Mooij and the RedBeanPHP Community
|
||||
* @license New BSD/GPLv2
|
||||
*
|
||||
* (c) G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community.
|
||||
* This source file is subject to the New BSD/GPLv2 License that is bundled
|
||||
* with this source code in the file license.txt.
|
||||
*/
|
||||
class Arrays extends Base
|
||||
{
|
||||
/**
|
||||
* Tests basic array access.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testArrayAccess() {
|
||||
|
||||
$bean = R::dispense('bean');
|
||||
$bean->name = 'bean';
|
||||
$bean->taste = 'salty';
|
||||
$properties = array();
|
||||
foreach($bean as $key => $value) {
|
||||
$properties[ $key ] = $value;
|
||||
}
|
||||
asrt( count( $bean ), 3 );
|
||||
asrt( count( $properties ), 3 );
|
||||
asrt( isset( $properties['id'] ), TRUE );
|
||||
asrt( isset( $properties['name'] ), TRUE );
|
||||
asrt( isset( $properties['taste'] ), TRUE );
|
||||
|
||||
$bean = R::dispense('bean');
|
||||
$bean['name'] = 'bean';
|
||||
$bean['taste'] = 'salty';
|
||||
$properties = array();
|
||||
foreach($bean as $key => $value) {
|
||||
$properties[ $key ] = $value;
|
||||
}
|
||||
asrt( count( $bean ), 3 );
|
||||
asrt( count( $properties ), 3 );
|
||||
asrt( isset( $properties['id'] ), TRUE );
|
||||
asrt( isset( $properties['name'] ), TRUE );
|
||||
asrt( isset( $properties['taste'] ), TRUE );
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests array access with lists.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testArrayAccessAndLists()
|
||||
{
|
||||
$book = R::dispense('book');
|
||||
$book['title'] = 'My Book';
|
||||
|
||||
//Can we add a bean in list with array access?
|
||||
$book['ownPage'][] = R::dispense('page');
|
||||
$book['ownPage'][] = R::dispense('page');
|
||||
|
||||
asrt( count( $book ), 3 );
|
||||
|
||||
$properties = array();
|
||||
foreach($book as $key => $value) {
|
||||
$properties[ $key ] = $value;
|
||||
}
|
||||
|
||||
asrt( count( $properties ), 3 );
|
||||
|
||||
//Dont reveal aliased x-own and -List in foreach-loop
|
||||
asrt( isset( $properties['id'] ), TRUE );
|
||||
asrt( isset( $properties['title'] ), TRUE );
|
||||
asrt( isset( $properties['ownPage'] ), TRUE );
|
||||
asrt( isset( $properties['ownPageList'] ), FALSE );
|
||||
asrt( isset( $properties['xownPage'] ), FALSE );
|
||||
asrt( isset( $properties['xownPageList'] ), FALSE );
|
||||
|
||||
//But keep them countable
|
||||
asrt( count( $book['ownPage'] ), 2 );
|
||||
asrt( count( $book['ownPageList'] ), 2 );
|
||||
asrt( count( $book['xownPage'] ), 2 );
|
||||
asrt( count( $book['xownPageList'] ), 2 );
|
||||
|
||||
//And reveal them with isset()
|
||||
asrt( isset( $book['id'] ), TRUE );
|
||||
asrt( isset( $book['title'] ), TRUE );
|
||||
asrt( isset( $book['ownPage'] ), TRUE );
|
||||
asrt( isset( $book['ownPageList'] ), TRUE );
|
||||
asrt( isset( $book['xownPage'] ), TRUE );
|
||||
asrt( isset( $book['xownPageList'] ), TRUE );
|
||||
|
||||
//Can we add using the List alias?
|
||||
$book['ownPageList'][] = R::dispense('page');
|
||||
asrt( count( $book['ownPage'] ), 3 );
|
||||
asrt( count( $book['ownPageList'] ), 3 );
|
||||
asrt( count( $book['xownPage'] ), 3 );
|
||||
asrt( count( $book['xownPageList'] ), 3 );
|
||||
|
||||
//Can we add using the x-mode alias?
|
||||
$book['ownPageList'][] = R::dispense('page');
|
||||
asrt( count( $book['ownPage'] ), 4 );
|
||||
asrt( count( $book['ownPageList'] ), 4 );
|
||||
asrt( count( $book['xownPage'] ), 4 );
|
||||
asrt( count( $book['xownPageList'] ), 4 );
|
||||
|
||||
//Can we unset using array access?
|
||||
unset( $book['ownPage'] );
|
||||
asrt( isset( $book['ownPage'] ), FALSE );
|
||||
asrt( isset( $book['ownPageList'] ), FALSE );
|
||||
asrt( isset( $book['xownPage'] ), FALSE );
|
||||
asrt( isset( $book['xownPageList'] ), FALSE );
|
||||
$book['ownPage'] = array( R::dispense('page') );
|
||||
unset( $book['xownPage'] );
|
||||
asrt( isset( $book['ownPage'] ), FALSE );
|
||||
asrt( isset( $book['ownPageList'] ), FALSE );
|
||||
asrt( isset( $book['xownPage'] ), FALSE );
|
||||
asrt( isset( $book['xownPageList'] ), FALSE );
|
||||
$book['ownPage'] = array( R::dispense('page') );
|
||||
unset( $book['ownPageList'] );
|
||||
asrt( isset( $book['ownPage'] ), FALSE );
|
||||
asrt( isset( $book['ownPageList'] ), FALSE );
|
||||
asrt( isset( $book['xownPage'] ), FALSE );
|
||||
asrt( isset( $book['xownPageList'] ), FALSE );
|
||||
$book['ownPage'] = array( R::dispense('page') );
|
||||
unset( $book['xownPageList'] );
|
||||
asrt( isset( $book['ownPage'] ), FALSE );
|
||||
asrt( isset( $book['ownPageList'] ), FALSE );
|
||||
asrt( isset( $book['xownPage'] ), FALSE );
|
||||
asrt( isset( $book['xownPageList'] ), FALSE );
|
||||
|
||||
//does it work with shared lists as well?
|
||||
$book['sharedCategory'] = array( R::dispense('category') );
|
||||
asrt( count( $book ), 3 );
|
||||
|
||||
$properties = array();
|
||||
foreach($book as $key => $value) {
|
||||
$properties[ $key ] = $value;
|
||||
}
|
||||
|
||||
asrt( isset( $properties['sharedCategory'] ), TRUE );
|
||||
asrt( isset( $properties['sharedCategoryList'] ), FALSE );
|
||||
|
||||
asrt( isset( $book['sharedCategory'] ), TRUE );
|
||||
asrt( isset( $book['sharedCategoryList'] ), TRUE );
|
||||
|
||||
asrt( count( $book['sharedCategory'] ), 1 );
|
||||
asrt( count( $book['sharedCategoryList'] ), 1 );
|
||||
|
||||
$book['sharedCategory'][] = R::dispense( 'category' );
|
||||
|
||||
asrt( count( $book['sharedCategory'] ), 2 );
|
||||
asrt( count( $book['sharedCategoryList'] ), 2 );
|
||||
|
||||
$book['sharedCategoryList'][] = R::dispense( 'category' );
|
||||
|
||||
asrt( count( $book['sharedCategory'] ), 3 );
|
||||
asrt( count( $book['sharedCategoryList'] ), 3 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests array access with parent beans.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testArrayAccessWithBeans()
|
||||
{
|
||||
$book = R::dispense( 'bean' );
|
||||
$book['author'] = R::dispense( 'author' );
|
||||
asrt( isset( $book['author'] ), TRUE );
|
||||
asrt( count( $book ), 2 );
|
||||
$book['author']['name'] = 'me';
|
||||
asrt( $book['author']['name'], 'me' );
|
||||
$book['author']['address'] = R::dispense( 'address' );
|
||||
$book['author']['ownTagList'][] = R::dispense( 'tag' );
|
||||
asrt( isset( $book['author']['address'] ), TRUE );
|
||||
asrt( isset( $book['author']['ownTag'] ), TRUE );
|
||||
asrt( count( $book['author']['ownTag'] ), 1 );
|
||||
asrt( isset( $book['author']['xownTag'] ), TRUE );
|
||||
asrt( count( $book['author']['xownTag'] ), 1 );
|
||||
asrt( isset( $book['author']['ownTagList'] ), TRUE );
|
||||
asrt( count( $book['author']['ownTagList'] ), 1 );
|
||||
asrt( isset( $book['author']['xownTagList'] ), TRUE );
|
||||
asrt( count( $book['author']['xownTagList'] ), 1 );
|
||||
unset( $book['author'] );
|
||||
asrt( isset( $book['author'] ), FALSE );
|
||||
asrt( count( $book ), 1 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests array access with CRUD operations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testArrayAccessWithCRUD()
|
||||
{
|
||||
R::nuke();
|
||||
$book = R::dispense( 'book' );
|
||||
$book['ownPageList'] = R::dispense( 'page', 3 );
|
||||
R::store( $book );
|
||||
|
||||
$book = $book->fresh();
|
||||
//note that isset first returns false, so you can check if a list is loaded
|
||||
asrt( isset( $book['ownPage'] ), FALSE );
|
||||
asrt( isset( $book['ownPageList'] ), FALSE );
|
||||
asrt( isset( $book['xownPage'] ), FALSE );
|
||||
asrt( isset( $book['xownPageList'] ), FALSE );
|
||||
//count triggers load...
|
||||
asrt( count( $book['ownPage'] ), 3 );
|
||||
asrt( isset( $book['ownPage'] ), TRUE );
|
||||
asrt( isset( $book['ownPageList'] ), TRUE );
|
||||
asrt( isset( $book['xownPage'] ), TRUE );
|
||||
asrt( isset( $book['xownPageList'] ), TRUE );
|
||||
$book = $book->fresh();
|
||||
asrt( count( $book['xownPage'] ), 3 );
|
||||
$book = $book->fresh();
|
||||
asrt( count( $book['ownPageList'] ), 3 );
|
||||
$book = $book->fresh();
|
||||
asrt( count( $book['xownPageList'] ), 3 );
|
||||
|
||||
$book['ownPage'][] = R::dispense( 'page' );
|
||||
R::store( $book );
|
||||
|
||||
$book = $book->fresh();
|
||||
asrt( count( $book['ownPage'] ), 4 );
|
||||
$book = $book->fresh();
|
||||
asrt( count( $book['xownPage'] ), 4 );
|
||||
$book = $book->fresh();
|
||||
asrt( count( $book['ownPageList'] ), 4 );
|
||||
$book = $book->fresh();
|
||||
asrt( count( $book['xownPageList'] ), 4 );
|
||||
|
||||
//does dependency still work?
|
||||
$book['xownPageList'] = array();
|
||||
R::store( $book );
|
||||
$book = $book->fresh();
|
||||
asrt( count( $book['ownPage'] ), 0 );
|
||||
$book = $book->fresh();
|
||||
asrt( count( $book['xownPage'] ), 0 );
|
||||
$book = $book->fresh();
|
||||
asrt( count( $book['ownPageList'] ), 0 );
|
||||
$book = $book->fresh();
|
||||
asrt( count( $book['xownPageList'] ), 0 );
|
||||
|
||||
//does shared list work as well?
|
||||
$book['sharedTag'] = R::dispense( 'tag', 2 );
|
||||
R::store( $book );
|
||||
|
||||
$book = $book->fresh();
|
||||
//note that isset first returns false, so you can check if a list is loaded
|
||||
asrt( isset( $book['sharedTagList'] ), FALSE );
|
||||
asrt( isset( $book['sharedTag'] ), FALSE );
|
||||
//count triggers load...
|
||||
asrt( count( $book['sharedTagList'] ), 2 );
|
||||
asrt( count( $book['sharedTag'] ), 2 );
|
||||
asrt( isset( $book['sharedTagList'] ), TRUE );
|
||||
asrt( isset( $book['sharedTag'] ), TRUE );
|
||||
|
||||
$book['sharedTag'][] = R::dispense( 'tag' );
|
||||
R::store( $book );
|
||||
|
||||
$book = $book->fresh();
|
||||
asrt( count( $book['sharedTagList'] ), 3 );
|
||||
asrt( count( $book['sharedTag'] ), 3 );
|
||||
|
||||
$book['sharedTagList'][] = R::dispense( 'tag' );
|
||||
R::store( $book );
|
||||
|
||||
$book = $book->fresh();
|
||||
asrt( count( $book['sharedTagList'] ), 4 );
|
||||
asrt( count( $book['sharedTag'] ), 4 );
|
||||
|
||||
//does it also work with cross-shared
|
||||
$book['sharedBookList'][] = R::dispense( 'book' );
|
||||
R::store( $book );
|
||||
$book = $book->fresh();
|
||||
asrt( isset( $book['sharedBookList'] ), FALSE );
|
||||
asrt( count( $book['sharedBookList'] ), 1 );
|
||||
$first = reset( $book['sharedBookList'] );
|
||||
$id = $first['id'];
|
||||
asrt( count( $book['sharedBookList'][$id]['sharedBookList'] ), 1 );
|
||||
|
||||
$properties = array();
|
||||
foreach($book as $key => $value) {
|
||||
$properties[ $key ] = $value;
|
||||
}
|
||||
|
||||
asrt( count( $properties ), 2 );
|
||||
$keys = array_keys( $properties );
|
||||
sort( $keys );
|
||||
asrt( implode( ',', $keys ), 'id,sharedBook' );
|
||||
}
|
||||
|
||||
}
|
|
@ -1,357 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RedUNIT\Base;
|
||||
|
||||
use RedUNIT\Base as Base;
|
||||
use RedBeanPHP\Facade as R;
|
||||
use RedBeanPHP\ToolBox as ToolBox;
|
||||
use RedBeanPHP\OODB as OODB;
|
||||
use RedBeanPHP\AssociationManager as AssociationManager;
|
||||
use RedBeanPHP\RedException\SQL as SQL;
|
||||
|
||||
/**
|
||||
* Association
|
||||
*
|
||||
* @file RedUNIT/Base/Association.php
|
||||
* @desc Tests Association API (N:N associations)
|
||||
* @author Gabor de Mooij and the RedBeanPHP Community
|
||||
* @license New BSD/GPLv2
|
||||
*
|
||||
* (c) G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community.
|
||||
* This source file is subject to the New BSD/GPLv2 License that is bundled
|
||||
* with this source code in the file license.txt.
|
||||
*/
|
||||
class Association extends Base
|
||||
{
|
||||
/**
|
||||
* MySQL specific tests.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testMySQL()
|
||||
{
|
||||
if ( $this->currentlyActiveDriverID !== 'mysql' ) {
|
||||
return;
|
||||
}
|
||||
|
||||
testpack( 'Throw exception in case of issue with assoc constraint' );
|
||||
|
||||
$bunny = R::dispense( 'bunny' );
|
||||
$carrot = R::dispense( 'carrot' );
|
||||
|
||||
$faultyWriter = new \FaultyWriter( R::getToolBox()->getDatabaseAdapter() );
|
||||
$faultyOODB = new OODB( $faultyWriter );
|
||||
$faultyOODB->setBeanHelper( R::getRedBean()->getBeanHelper() );
|
||||
$faultyToolbox = new ToolBox( $faultyOODB, R::getToolBox()->getDatabaseAdapter(), $faultyWriter );
|
||||
|
||||
$faultyAssociationManager = new AssociationManager( $faultyToolbox );
|
||||
|
||||
$faultyWriter->setSQLState( '23000' );
|
||||
|
||||
$faultyAssociationManager->associate( $bunny, $carrot );
|
||||
|
||||
pass();
|
||||
|
||||
$faultyWriter->setSQLState( '42S22' );
|
||||
|
||||
R::nuke();
|
||||
|
||||
try {
|
||||
$faultyAssociationManager->associate( $bunny, $carrot );
|
||||
fail();
|
||||
} catch ( SQL $exception ) {
|
||||
pass();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test fast-track deletion, i.e. bypassing FUSE.
|
||||
* For link beans.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testFastTrackDeletion()
|
||||
{
|
||||
testpack( 'Test fast-track deletion' );
|
||||
|
||||
$ghost = R::dispense( 'ghost' );
|
||||
$house = R::dispense( 'house' );
|
||||
|
||||
$house->sharedGhost[] = $ghost;
|
||||
|
||||
\Model_Ghost_House::$deleted = FALSE;
|
||||
|
||||
R::getRedBean()->getAssociationManager()->unassociate( $house, $ghost );
|
||||
|
||||
// No fast-track, assoc bean got trashed
|
||||
asrt( \Model_Ghost_House::$deleted, TRUE );
|
||||
|
||||
\Model_Ghost_House::$deleted = FALSE;
|
||||
|
||||
R::getRedBean()->getAssociationManager()->unassociate( $house, $ghost, TRUE );
|
||||
|
||||
// Fast-track, assoc bean got deleted right away
|
||||
asrt( \Model_Ghost_House::$deleted, FALSE );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test self-referential associations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testCrossAssociation()
|
||||
{
|
||||
$ghost = R::dispense( 'ghost' );
|
||||
$ghost2 = R::dispense( 'ghost' );
|
||||
|
||||
R::getRedBean()->getAssociationManager()->associate( $ghost, $ghost2 );
|
||||
|
||||
\Model_Ghost_Ghost::$deleted = FALSE;
|
||||
|
||||
R::getRedBean()->getAssociationManager()->unassociate( $ghost, $ghost2 );
|
||||
|
||||
// No fast-track, assoc bean got trashed
|
||||
asrt( \Model_Ghost_Ghost::$deleted, TRUE );
|
||||
|
||||
\Model_Ghost_Ghost::$deleted = FALSE;
|
||||
|
||||
R::getRedBean()->getAssociationManager()->unassociate( $ghost, $ghost2, TRUE );
|
||||
|
||||
// Fast-track, assoc bean got deleted right away
|
||||
asrt( \Model_Ghost_Ghost::$deleted, FALSE );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test limited support for polymorph associations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testPoly()
|
||||
{
|
||||
testpack( 'Testing poly' );
|
||||
|
||||
$shoe = R::dispense( 'shoe' );
|
||||
$lace = R::dispense( 'lace' );
|
||||
|
||||
$lace->color = 'white';
|
||||
|
||||
$id = R::store( $lace );
|
||||
|
||||
$shoe->itemType = 'lace';
|
||||
$shoe->item = $lace;
|
||||
|
||||
$id = R::store( $shoe );
|
||||
|
||||
$shoe = R::load( 'shoe', $id );
|
||||
|
||||
$x = $shoe->poly( 'itemType' )->item;
|
||||
|
||||
asrt( $x->color, 'white' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test limited support for 1-to-1 associations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testOneToOne()
|
||||
{
|
||||
testpack( 'Testing one-to-ones' );
|
||||
|
||||
$author = R::dispense( 'author' )->setAttr( 'name', 'a' );;
|
||||
$bio = R::dispense( 'bio' )->setAttr( 'name', 'a' );
|
||||
|
||||
R::storeAll( array( $author, $bio ) );
|
||||
|
||||
$id1 = $author->id;
|
||||
|
||||
$author = R::dispense( 'author' )->setAttr( 'name', 'b' );;
|
||||
$bio = R::dispense( 'bio' )->setAttr( 'name', 'b' );
|
||||
|
||||
R::storeAll( array( $author, $bio ) );
|
||||
|
||||
$x = $author->one( 'bio' );
|
||||
$y = $bio->one('author');
|
||||
|
||||
asrt( $x->name, $bio->name );
|
||||
asrt( $y->name, $author->name );
|
||||
asrt( $x->id, $bio->id );
|
||||
asrt( $y->id, $author->id );
|
||||
|
||||
$id2 = $author->id;
|
||||
|
||||
list( $a, $b ) = R::loadMulti( 'author,bio', $id1 );
|
||||
|
||||
asrt( $a->name, $b->name );
|
||||
asrt( $a->name, 'a' );
|
||||
|
||||
list( $a, $b ) = R::loadMulti( 'author,bio', $id2 );
|
||||
|
||||
asrt( $a->name, $b->name );
|
||||
asrt( $a->name, 'b' );
|
||||
|
||||
list( $a, $b ) = R::loadMulti( array( 'author', 'bio' ), $id1 );
|
||||
|
||||
asrt( $a->name, $b->name );
|
||||
asrt( $a->name, 'a' );
|
||||
|
||||
list( $a, $b ) = R::loadMulti( array( 'author', 'bio' ), $id2 );
|
||||
|
||||
asrt( $a->name, $b->name );
|
||||
asrt( $a->name, 'b' );
|
||||
|
||||
asrt( is_array( R::loadMulti( NULL, 1 ) ), TRUE );
|
||||
|
||||
asrt( ( count( R::loadMulti( NULL, 1 ) ) === 0 ), TRUE );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test single column bases unique constraints.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testSingleColUniqueConstraint()
|
||||
{
|
||||
testpack( 'Testing unique constraint on single column' );
|
||||
|
||||
$book = R::dispense( 'book' );
|
||||
|
||||
$book->title = 'bla';
|
||||
$book->extra = 2;
|
||||
|
||||
$id = R::store( $book );
|
||||
R::getWriter()->addUniqueIndex( 'book', array( 'title' ) );
|
||||
|
||||
$book = R::dispense( 'book' );
|
||||
|
||||
$book->title = 'bla';
|
||||
|
||||
$expected = NULL;
|
||||
|
||||
try {
|
||||
R::store( $book );
|
||||
|
||||
fail();
|
||||
} catch ( SQL $e ) {
|
||||
$expected = $e;
|
||||
}
|
||||
|
||||
asrt( ( $expected instanceof SQL ), TRUE );
|
||||
|
||||
asrt( R::count( 'book' ), 1 );
|
||||
|
||||
$book = R::load( 'book', $id );
|
||||
|
||||
// Causes failure, table will be rebuild
|
||||
$book->extra = 'CHANGE';
|
||||
|
||||
$id2 = R::store( $book );
|
||||
|
||||
$book2 = R::load( 'book', $id2 );
|
||||
|
||||
$book = R::dispense( 'book' );
|
||||
|
||||
$book->title = 'bla';
|
||||
|
||||
try {
|
||||
R::store( $book );
|
||||
|
||||
fail();
|
||||
} catch ( SQL $e ) {
|
||||
$expected = $e;
|
||||
}
|
||||
|
||||
asrt( ( $expected instanceof SQL ), TRUE );
|
||||
|
||||
asrt( R::count( 'book' ), 1 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test multiple assiociation.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testMultiAssociationDissociation()
|
||||
{
|
||||
$wines = R::dispense( 'wine', 3 );
|
||||
$cheese = R::dispense( 'cheese', 3 );
|
||||
$olives = R::dispense( 'olive', 3 );
|
||||
|
||||
R::getRedBean()->getAssociationManager()->associate( $wines, array_merge( $cheese, $olives ) );
|
||||
|
||||
asrt( R::count( 'cheese' ), 3 );
|
||||
asrt( R::count( 'olive' ), 3 );
|
||||
asrt( R::count( 'wine' ), 3 );
|
||||
|
||||
asrt( count( $wines[0]->sharedCheese ), 3 );
|
||||
asrt( count( $wines[0]->sharedOlive ), 3 );
|
||||
asrt( count( $wines[1]->sharedCheese ), 3 );
|
||||
asrt( count( $wines[1]->sharedOlive ), 3 );
|
||||
asrt( count( $wines[2]->sharedCheese ), 3 );
|
||||
asrt( count( $wines[2]->sharedOlive ), 3 );
|
||||
|
||||
R::getRedBean()->getAssociationManager()->unassociate( $wines, $olives );
|
||||
|
||||
asrt( count( $wines[0]->sharedCheese ), 3 );
|
||||
asrt( count( $wines[0]->sharedOlive ), 0 );
|
||||
asrt( count( $wines[1]->sharedCheese ), 3 );
|
||||
asrt( count( $wines[1]->sharedOlive ), 0 );
|
||||
asrt( count( $wines[2]->sharedCheese ), 3 );
|
||||
asrt( count( $wines[2]->sharedOlive ), 0 );
|
||||
|
||||
R::getRedBean()->getAssociationManager()->unassociate( array( $wines[1] ), $cheese );
|
||||
|
||||
asrt( count( $wines[0]->sharedCheese ), 3 );
|
||||
asrt( count( $wines[0]->sharedOlive ), 0 );
|
||||
asrt( count( $wines[1]->sharedCheese ), 0 );
|
||||
asrt( count( $wines[1]->sharedOlive ), 0 );
|
||||
asrt( count( $wines[2]->sharedCheese ), 3 );
|
||||
asrt( count( $wines[2]->sharedOlive ), 0 );
|
||||
|
||||
R::getRedBean()->getAssociationManager()->unassociate( array( $wines[2] ), $cheese );
|
||||
|
||||
asrt( count( $wines[0]->sharedCheese ), 3 );
|
||||
asrt( count( $wines[0]->sharedOlive ), 0 );
|
||||
asrt( count( $wines[1]->sharedCheese ), 0 );
|
||||
asrt( count( $wines[1]->sharedOlive ), 0 );
|
||||
asrt( count( $wines[2]->sharedCheese ), 0 );
|
||||
asrt( count( $wines[2]->sharedOlive ), 0 );
|
||||
}
|
||||
|
||||
public function testErrorHandling()
|
||||
{
|
||||
R::nuke();
|
||||
list( $book, $page ) = R::dispenseAll( 'book,page' );
|
||||
$book->sharedPage[] = $page;
|
||||
R::store( $page );
|
||||
|
||||
$redbean = R::getRedBean();
|
||||
$am = $redbean->getAssociationManager();
|
||||
|
||||
//SQLite and CUBRID do not comply with ANSI SQLState codes.
|
||||
$catchAll = ( $this->currentlyActiveDriverID == 'sqlite' || $this->currentlyActiveDriverID === 'CUBRID' );
|
||||
|
||||
try {
|
||||
$am->related( $book, 'page', 'invalid SQL' );
|
||||
if ($catchAll) pass(); else fail();
|
||||
} catch ( SQL $e ) {
|
||||
if ($catchAll) fail(); else pass();
|
||||
}
|
||||
|
||||
try {
|
||||
$am->related( $book, 'cover');
|
||||
pass();
|
||||
} catch ( SQL $e ) {
|
||||
fail();
|
||||
}
|
||||
|
||||
try {
|
||||
$am->related( R::dispense('cover'), 'book' );
|
||||
pass();
|
||||
} catch ( SQL $e ) {
|
||||
fail();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,139 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RedUNIT\Base;
|
||||
|
||||
use RedUNIT\Base as Base;
|
||||
use RedBeanPHP\Facade as R;
|
||||
use RedBeanPHP\OODBBean as OODBBean;
|
||||
use RedBeanPHP\RedException\SQL as SQL;
|
||||
|
||||
/**
|
||||
* Batch
|
||||
*
|
||||
* @file RedUNIT/Base/Batch.php
|
||||
* @desc Tests batch loading of beans, i.e. loading large collections of beans in optimized way.
|
||||
* @author Gabor de Mooij and the RedBeanPHP Community
|
||||
* @license New BSD/GPLv2
|
||||
*
|
||||
* (c) G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community.
|
||||
* This source file is subject to the New BSD/GPLv2 License that is bundled
|
||||
* with this source code in the file license.txt.
|
||||
*/
|
||||
class Batch extends Base
|
||||
{
|
||||
|
||||
/**
|
||||
* Begin testing.
|
||||
* This method runs the actual test pack.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testBatch()
|
||||
{
|
||||
R::freeze( FALSE );
|
||||
$toolbox = R::getToolBox();
|
||||
$adapter = $toolbox->getDatabaseAdapter();
|
||||
$writer = $toolbox->getWriter();
|
||||
$redbean = $toolbox->getRedBean();
|
||||
$pdo = $adapter->getDatabase();
|
||||
|
||||
$page = $redbean->dispense( "page" );
|
||||
|
||||
$page->name = "page no. 1";
|
||||
$page->rating = 1;
|
||||
|
||||
$id1 = $redbean->store( $page );
|
||||
|
||||
$page = $redbean->dispense( "page" );
|
||||
|
||||
$page->name = "page no. 2";
|
||||
|
||||
$id2 = $redbean->store( $page );
|
||||
|
||||
$batch = $redbean->batch( "page", array( $id1, $id2 ) );
|
||||
|
||||
asrt( count( $batch ), 2 );
|
||||
asrt( $batch[$id1]->getMeta( "type" ), "page" );
|
||||
asrt( $batch[$id2]->getMeta( "type" ), "page" );
|
||||
asrt( (int) $batch[$id1]->id, $id1 );
|
||||
asrt( (int) $batch[$id2]->id, $id2 );
|
||||
|
||||
$book = $redbean->dispense( "book" );
|
||||
|
||||
$book->name = "book 1";
|
||||
|
||||
$redbean->store( $book );
|
||||
|
||||
$book = $redbean->dispense( "book" );
|
||||
|
||||
$book->name = "book 2";
|
||||
|
||||
$redbean->store( $book );
|
||||
|
||||
$book = $redbean->dispense( "book" );
|
||||
|
||||
$book->name = "book 3";
|
||||
|
||||
$redbean->store( $book );
|
||||
|
||||
$books = $redbean->batch( "book", $adapter->getCol( "SELECT id FROM book" ) );
|
||||
|
||||
asrt( count( $books ), 3 );
|
||||
|
||||
$a = $redbean->batch( 'book', 9919 );
|
||||
|
||||
asrt( is_array( $a ), TRUE );
|
||||
asrt( count( $a ), 0 );
|
||||
$a = $redbean->batch( 'triangle', 1 );
|
||||
|
||||
asrt( is_array( $a ), TRUE );
|
||||
asrt( count( $a ), 0 );
|
||||
|
||||
R::freeze( TRUE );
|
||||
|
||||
$a = $redbean->batch( 'book', 9919 );
|
||||
|
||||
asrt( is_array( $a ), TRUE );
|
||||
asrt( count( $a ), 0 );
|
||||
try {
|
||||
$a = $redbean->batch( 'triangle', 1 );
|
||||
fail();
|
||||
} catch(SQL $e) {
|
||||
pass();
|
||||
}
|
||||
R::freeze( FALSE );
|
||||
asrt( R::wipe( 'spaghettimonster' ), FALSE );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test missing bean scenarios.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testMissingBeans()
|
||||
{
|
||||
testpack( 'deal with missing beans' );
|
||||
|
||||
$id = R::store( R::dispense( 'beer' ) );
|
||||
$bottles = R::batch( 'beer', array( $id, $id + 1, $id + 2 ) );
|
||||
|
||||
asrt( count( $bottles ), 3 );
|
||||
asrt( (int) $bottles[$id]->id, (int) $id );
|
||||
asrt( (int) $bottles[$id + 1]->id, 0 );
|
||||
asrt( (int) $bottles[$id + 2]->id, 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test batch alias loadAll.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testBatchAliasLoadAll()
|
||||
{
|
||||
$ids = R::storeAll( R::dispense( 'page', 2 ) );
|
||||
$pages = R::loadAll( 'page', $ids );
|
||||
asrt( is_array( $pages ), true );
|
||||
asrt( count( $pages ), 2 );
|
||||
asrt( ( $pages[$ids[0]] instanceof OODBBean ), true );
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,74 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace RedUNIT\Base;
|
||||
|
||||
use RedUNIT\Base as Base;
|
||||
use RedBeanPHP\Facade as R;
|
||||
use RedBeanPHP\SimpleModel as SimpleModel;
|
||||
|
||||
/**
|
||||
* Boxing
|
||||
*
|
||||
* @file RedUNIT/Base/Boxing.php
|
||||
* @desc Tests bean boxing and unboxing functionality.
|
||||
* @author Gabor de Mooij and the RedBeanPHP Community
|
||||
* @license New BSD/GPLv2
|
||||
*
|
||||
* (c) G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community.
|
||||
* This source file is subject to the New BSD/GPLv2 License that is bundled
|
||||
* with this source code in the file license.txt.
|
||||
*/
|
||||
class Boxing extends Base
|
||||
{
|
||||
|
||||
/**
|
||||
* Test boxing beans.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testBoxing()
|
||||
{
|
||||
R::nuke();
|
||||
|
||||
$bean = R::dispense( 'boxedbean' )->box();
|
||||
|
||||
R::trash( $bean );
|
||||
|
||||
pass();
|
||||
|
||||
$bean = R::dispense( 'boxedbean' );
|
||||
|
||||
$bean->sharedBoxbean = R::dispense( 'boxedbean' )->box();
|
||||
|
||||
R::store( $bean );
|
||||
|
||||
pass();
|
||||
|
||||
$bean = R::dispense( 'boxedbean' );
|
||||
|
||||
$bean->ownBoxedbean = R::dispense( 'boxedbean' )->box();
|
||||
|
||||
R::store( $bean );
|
||||
|
||||
pass();
|
||||
|
||||
$bean = R::dispense( 'boxedbean' );
|
||||
|
||||
$bean->other = R::dispense( 'boxedbean' )->box();
|
||||
|
||||
R::store( $bean );
|
||||
|
||||
pass();
|
||||
|
||||
$bean = R::dispense( 'boxedbean' );
|
||||
|
||||
$bean->title = 'MyBean';
|
||||
|
||||
$box = $bean->box();
|
||||
|
||||
asrt( ( $box instanceof \Model_Boxedbean ), TRUE );
|
||||
|
||||
R::store( $box );
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue