init without trunk
This commit is contained in:
parent
ed24ac4994
commit
bb809e7233
14652 changed files with 177862 additions and 94817 deletions
79
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/AttachEntityListenersListener.php
vendored
Normal file
79
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/AttachEntityListenersListener.php
vendored
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the MIT license. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace Doctrine\ORM\Tools;
|
||||
|
||||
use Doctrine\ORM\Event\LoadClassMetadataEventArgs;
|
||||
|
||||
/**
|
||||
* Mechanism to programmatically attach entity listeners.
|
||||
*
|
||||
* @author Fabio B. SIlva <fabio.bat.silva@gmail.com>
|
||||
*
|
||||
* @since 2.5
|
||||
*/
|
||||
class AttachEntityListenersListener
|
||||
{
|
||||
/**
|
||||
* @var array[]
|
||||
*/
|
||||
private $entityListeners = array();
|
||||
|
||||
/**
|
||||
* Adds a entity listener for a specific entity.
|
||||
*
|
||||
* @param string $entityClass The entity to attach the listener.
|
||||
* @param string $listenerClass The listener class.
|
||||
* @param string $eventName The entity lifecycle event.
|
||||
* @param string $listenerCallback|null The listener callback method or NULL to use $eventName.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addEntityListener($entityClass, $listenerClass, $eventName, $listenerCallback = null)
|
||||
{
|
||||
$this->entityListeners[ltrim($entityClass, '\\')][] = array(
|
||||
'event' => $eventName,
|
||||
'class' => $listenerClass,
|
||||
'method' => $listenerCallback ?: $eventName
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes event and attach the entity listener.
|
||||
*
|
||||
* @param \Doctrine\ORM\Event\LoadClassMetadataEventArgs $event
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function loadClassMetadata(LoadClassMetadataEventArgs $event)
|
||||
{
|
||||
/** @var $metadata \Doctrine\ORM\Mapping\ClassMetadata */
|
||||
$metadata = $event->getClassMetadata();
|
||||
|
||||
if ( ! isset($this->entityListeners[$metadata->name])) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($this->entityListeners[$metadata->name] as $listener) {
|
||||
$metadata->addEntityListener($listener['event'], $listener['class'], $listener['method']);
|
||||
}
|
||||
|
||||
unset($this->entityListeners[$metadata->name]);
|
||||
}
|
||||
}
|
||||
134
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/CollectionRegionCommand.php
vendored
Normal file
134
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/CollectionRegionCommand.php
vendored
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
<?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\ORM\Tools\Console\Command\ClearCache;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Doctrine\ORM\Cache\Region\DefaultRegion;
|
||||
use Doctrine\ORM\Cache;
|
||||
|
||||
/**
|
||||
* Command to clear a collection cache region.
|
||||
*
|
||||
* @since 2.5
|
||||
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
|
||||
*/
|
||||
class CollectionRegionCommand extends Command
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setName('orm:clear-cache:region:collection')
|
||||
->setDescription('Clear a second-level cache collection region.')
|
||||
->addArgument('owner-class', InputArgument::OPTIONAL, 'The owner entity name.')
|
||||
->addArgument('association', InputArgument::OPTIONAL, 'The association collection name.')
|
||||
->addArgument('owner-id', InputArgument::OPTIONAL, 'The owner identifier.')
|
||||
->addOption('all', null, InputOption::VALUE_NONE, 'If defined, all entity regions will be deleted/invalidated.')
|
||||
->addOption('flush', null, InputOption::VALUE_NONE,'If defined, all cache entries will be flushed.');
|
||||
|
||||
|
||||
$this->setHelp(<<<EOT
|
||||
The <info>%command.name%</info> command is meant to clear a second-level cache collection regions for an associated Entity Manager.
|
||||
It is possible to delete/invalidate all collection region, a specific collection region or flushes the cache provider.
|
||||
|
||||
The execution type differ on how you execute the command.
|
||||
If you want to invalidate all entries for an collection region this command would do the work:
|
||||
|
||||
<info>%command.name% 'Entities\MyEntity' 'collectionName'</info>
|
||||
|
||||
To invalidate a specific entry you should use :
|
||||
|
||||
<info>%command.name% 'Entities\MyEntity' 'collectionName' 1</info>
|
||||
|
||||
If you want to invalidate all entries for the all collection regions:
|
||||
|
||||
<info>%command.name% --all</info>
|
||||
|
||||
Alternatively, if you want to flush the configured cache provider for an collection region use this command:
|
||||
|
||||
<info>%command.name% 'Entities\MyEntity' 'collectionName' --flush</info>
|
||||
|
||||
Finally, be aware that if <info>--flush</info> option is passed,
|
||||
not all cache providers are able to flush entries, because of a limitation of its execution nature.
|
||||
EOT
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$em = $this->getHelper('em')->getEntityManager();
|
||||
$ownerClass = $input->getArgument('owner-class');
|
||||
$assoc = $input->getArgument('association');
|
||||
$ownerId = $input->getArgument('owner-id');
|
||||
$cache = $em->getCache();
|
||||
|
||||
if ( ! $cache instanceof Cache) {
|
||||
throw new \InvalidArgumentException('No second-level cache is configured on the given EntityManager.');
|
||||
}
|
||||
|
||||
if ( (! $ownerClass || ! $assoc) && ! $input->getOption('all')) {
|
||||
throw new \InvalidArgumentException('Missing arguments "--owner-class" "--association"');
|
||||
}
|
||||
|
||||
if ($input->getOption('flush')) {
|
||||
$collectionRegion = $cache->getCollectionCacheRegion($ownerClass, $assoc);
|
||||
|
||||
if ( ! $collectionRegion instanceof DefaultRegion) {
|
||||
throw new \InvalidArgumentException(sprintf(
|
||||
'The option "--flush" expects a "Doctrine\ORM\Cache\Region\DefaultRegion", but got "%s".',
|
||||
is_object($collectionRegion) ? get_class($collectionRegion) : gettype($collectionRegion)
|
||||
));
|
||||
}
|
||||
|
||||
$collectionRegion->getCache()->flushAll();
|
||||
|
||||
$output->writeln(sprintf('Flushing cache provider configured for <info>"%s#%s"</info>', $ownerClass, $assoc));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($input->getOption('all')) {
|
||||
$output->writeln('Clearing <info>all</info> second-level cache collection regions');
|
||||
|
||||
$cache->evictEntityRegions();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($ownerId) {
|
||||
$output->writeln(sprintf('Clearing second-level cache entry for collection <info>"%s#%s"</info> owner entity identified by <info>"%s"</info>', $ownerClass, $assoc, $ownerId));
|
||||
$cache->evictCollection($ownerClass, $assoc, $ownerId);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$output->writeln(sprintf('Clearing second-level cache for collection <info>"%s#%s"</info>', $ownerClass, $assoc));
|
||||
$cache->evictCollectionRegion($ownerClass, $assoc);
|
||||
}
|
||||
}
|
||||
132
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/EntityRegionCommand.php
vendored
Normal file
132
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/EntityRegionCommand.php
vendored
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
<?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\ORM\Tools\Console\Command\ClearCache;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Doctrine\ORM\Cache\Region\DefaultRegion;
|
||||
use Doctrine\ORM\Cache;
|
||||
|
||||
/**
|
||||
* Command to clear a entity cache region.
|
||||
*
|
||||
* @since 2.5
|
||||
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
|
||||
*/
|
||||
class EntityRegionCommand extends Command
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setName('orm:clear-cache:region:entity')
|
||||
->setDescription('Clear a second-level cache entity region.')
|
||||
->addArgument('entity-class', InputArgument::OPTIONAL, 'The entity name.')
|
||||
->addArgument('entity-id', InputArgument::OPTIONAL, 'The entity identifier.')
|
||||
->addOption('all', null, InputOption::VALUE_NONE, 'If defined, all entity regions will be deleted/invalidated.')
|
||||
->addOption('flush', null, InputOption::VALUE_NONE,'If defined, all cache entries will be flushed.');
|
||||
|
||||
|
||||
$this->setHelp(<<<EOT
|
||||
The <info>%command.name%</info> command is meant to clear a second-level cache entity region for an associated Entity Manager.
|
||||
It is possible to delete/invalidate all entity region, a specific entity region or flushes the cache provider.
|
||||
|
||||
The execution type differ on how you execute the command.
|
||||
If you want to invalidate all entries for an entity region this command would do the work:
|
||||
|
||||
<info>%command.name% 'Entities\MyEntity'</info>
|
||||
|
||||
To invalidate a specific entry you should use :
|
||||
|
||||
<info>%command.name% 'Entities\MyEntity' 1</info>
|
||||
|
||||
If you want to invalidate all entries for the all entity regions:
|
||||
|
||||
<info>%command.name% --all</info>
|
||||
|
||||
Alternatively, if you want to flush the configured cache provider for an entity region use this command:
|
||||
|
||||
<info>%command.name% 'Entities\MyEntity' --flush</info>
|
||||
|
||||
Finally, be aware that if <info>--flush</info> option is passed,
|
||||
not all cache providers are able to flush entries, because of a limitation of its execution nature.
|
||||
EOT
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$em = $this->getHelper('em')->getEntityManager();
|
||||
$entityClass = $input->getArgument('entity-class');
|
||||
$entityId = $input->getArgument('entity-id');
|
||||
$cache = $em->getCache();
|
||||
|
||||
if ( ! $cache instanceof Cache) {
|
||||
throw new \InvalidArgumentException('No second-level cache is configured on the given EntityManager.');
|
||||
}
|
||||
|
||||
if ( ! $entityClass && ! $input->getOption('all')) {
|
||||
throw new \InvalidArgumentException('Invalid argument "--entity-class"');
|
||||
}
|
||||
|
||||
if ($input->getOption('flush')) {
|
||||
$entityRegion = $cache->getEntityCacheRegion($entityClass);
|
||||
|
||||
if ( ! $entityRegion instanceof DefaultRegion) {
|
||||
throw new \InvalidArgumentException(sprintf(
|
||||
'The option "--flush" expects a "Doctrine\ORM\Cache\Region\DefaultRegion", but got "%s".',
|
||||
is_object($entityRegion) ? get_class($entityRegion) : gettype($entityRegion)
|
||||
));
|
||||
}
|
||||
|
||||
$entityRegion->getCache()->flushAll();
|
||||
|
||||
$output->writeln(sprintf('Flushing cache provider configured for entity named <info>"%s"</info>', $entityClass));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($input->getOption('all')) {
|
||||
$output->writeln('Clearing <info>all</info> second-level cache entity regions');
|
||||
|
||||
$cache->evictEntityRegions();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($entityId) {
|
||||
$output->writeln(sprintf('Clearing second-level cache entry for entity <info>"%s"</info> identified by <info>"%s"</info>', $entityClass, $entityId));
|
||||
$cache->evictEntity($entityClass, $entityId);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$output->writeln(sprintf('Clearing second-level cache for entity <info>"%s"</info>', $entityClass));
|
||||
$cache->evictEntityRegion($entityClass);
|
||||
}
|
||||
}
|
||||
109
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/MetadataCommand.php
vendored
Normal file
109
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/MetadataCommand.php
vendored
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
<?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\ORM\Tools\Console\Command\ClearCache;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Doctrine\Common\Cache\ApcCache;
|
||||
use Doctrine\Common\Cache\XcacheCache;
|
||||
|
||||
/**
|
||||
* Command to clear the metadata cache of the various cache drivers.
|
||||
*
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
class MetadataCommand extends Command
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setName('orm:clear-cache:metadata')
|
||||
->setDescription('Clear all metadata cache of the various cache drivers.')
|
||||
->setDefinition(array(
|
||||
new InputOption(
|
||||
'flush', null, InputOption::VALUE_NONE,
|
||||
'If defined, cache entries will be flushed instead of deleted/invalidated.'
|
||||
)
|
||||
));
|
||||
|
||||
$this->setHelp(<<<EOT
|
||||
The <info>%command.name%</info> command is meant to clear the metadata cache of associated Entity Manager.
|
||||
It is possible to invalidate all cache entries at once - called delete -, or flushes the cache provider
|
||||
instance completely.
|
||||
|
||||
The execution type differ on how you execute the command.
|
||||
If you want to invalidate the entries (and not delete from cache instance), this command would do the work:
|
||||
|
||||
<info>%command.name%</info>
|
||||
|
||||
Alternatively, if you want to flush the cache provider using this command:
|
||||
|
||||
<info>%command.name% --flush</info>
|
||||
|
||||
Finally, be aware that if <info>--flush</info> option is passed, not all cache providers are able to flush entries,
|
||||
because of a limitation of its execution nature.
|
||||
EOT
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$em = $this->getHelper('em')->getEntityManager();
|
||||
$cacheDriver = $em->getConfiguration()->getMetadataCacheImpl();
|
||||
|
||||
if ( ! $cacheDriver) {
|
||||
throw new \InvalidArgumentException('No Metadata cache driver is configured on given EntityManager.');
|
||||
}
|
||||
|
||||
if ($cacheDriver instanceof ApcCache) {
|
||||
throw new \LogicException("Cannot clear APC Cache from Console, its shared in the Webserver memory and not accessible from the CLI.");
|
||||
}
|
||||
|
||||
if ($cacheDriver instanceof XcacheCache) {
|
||||
throw new \LogicException("Cannot clear XCache Cache from Console, its shared in the Webserver memory and not accessible from the CLI.");
|
||||
}
|
||||
|
||||
|
||||
$output->writeln('Clearing ALL Metadata cache entries');
|
||||
|
||||
$result = $cacheDriver->deleteAll();
|
||||
$message = ($result) ? 'Successfully deleted cache entries.' : 'No cache entries were deleted.';
|
||||
|
||||
if (true === $input->getOption('flush')) {
|
||||
$result = $cacheDriver->flushAll();
|
||||
$message = ($result) ? 'Successfully flushed cache entries.' : $message;
|
||||
}
|
||||
|
||||
$output->writeln($message);
|
||||
}
|
||||
}
|
||||
107
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/QueryCommand.php
vendored
Normal file
107
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/QueryCommand.php
vendored
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
<?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\ORM\Tools\Console\Command\ClearCache;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Doctrine\Common\Cache\ApcCache;
|
||||
use Doctrine\Common\Cache\XcacheCache;
|
||||
|
||||
/**
|
||||
* Command to clear the query cache of the various cache drivers.
|
||||
*
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
class QueryCommand extends Command
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setName('orm:clear-cache:query')
|
||||
->setDescription('Clear all query cache of the various cache drivers.')
|
||||
->setDefinition(array(
|
||||
new InputOption(
|
||||
'flush', null, InputOption::VALUE_NONE,
|
||||
'If defined, cache entries will be flushed instead of deleted/invalidated.'
|
||||
)
|
||||
));
|
||||
|
||||
$this->setHelp(<<<EOT
|
||||
The <info>%command.name%</info> command is meant to clear the query cache of associated Entity Manager.
|
||||
It is possible to invalidate all cache entries at once - called delete -, or flushes the cache provider
|
||||
instance completely.
|
||||
|
||||
The execution type differ on how you execute the command.
|
||||
If you want to invalidate the entries (and not delete from cache instance), this command would do the work:
|
||||
|
||||
<info>%command.name%</info>
|
||||
|
||||
Alternatively, if you want to flush the cache provider using this command:
|
||||
|
||||
<info>%command.name% --flush</info>
|
||||
|
||||
Finally, be aware that if <info>--flush</info> option is passed, not all cache providers are able to flush entries,
|
||||
because of a limitation of its execution nature.
|
||||
EOT
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$em = $this->getHelper('em')->getEntityManager();
|
||||
$cacheDriver = $em->getConfiguration()->getQueryCacheImpl();
|
||||
|
||||
if ( ! $cacheDriver) {
|
||||
throw new \InvalidArgumentException('No Query cache driver is configured on given EntityManager.');
|
||||
}
|
||||
|
||||
if ($cacheDriver instanceof ApcCache) {
|
||||
throw new \LogicException("Cannot clear APC Cache from Console, its shared in the Webserver memory and not accessible from the CLI.");
|
||||
}
|
||||
if ($cacheDriver instanceof XcacheCache) {
|
||||
throw new \LogicException("Cannot clear XCache Cache from Console, its shared in the Webserver memory and not accessible from the CLI.");
|
||||
}
|
||||
|
||||
$output->write('Clearing ALL Query cache entries' . PHP_EOL);
|
||||
|
||||
$result = $cacheDriver->deleteAll();
|
||||
$message = ($result) ? 'Successfully deleted cache entries.' : 'No cache entries were deleted.';
|
||||
|
||||
if (true === $input->getOption('flush')) {
|
||||
$result = $cacheDriver->flushAll();
|
||||
$message = ($result) ? 'Successfully flushed cache entries.' : $message;
|
||||
}
|
||||
|
||||
$output->write($message . PHP_EOL);
|
||||
}
|
||||
}
|
||||
124
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/QueryRegionCommand.php
vendored
Normal file
124
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/QueryRegionCommand.php
vendored
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
<?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\ORM\Tools\Console\Command\ClearCache;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Doctrine\ORM\Cache\Region\DefaultRegion;
|
||||
use Doctrine\ORM\Cache;
|
||||
|
||||
/**
|
||||
* Command to clear a query cache region.
|
||||
*
|
||||
* @since 2.5
|
||||
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
|
||||
*/
|
||||
class QueryRegionCommand extends Command
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setName('orm:clear-cache:region:query')
|
||||
->setDescription('Clear a second-level cache query region.')
|
||||
->addArgument('region-name', InputArgument::OPTIONAL, 'The query region to clear.')
|
||||
->addOption('all', null, InputOption::VALUE_NONE, 'If defined, all query regions will be deleted/invalidated.')
|
||||
->addOption('flush', null, InputOption::VALUE_NONE,'If defined, all cache entries will be flushed.');
|
||||
|
||||
|
||||
$this->setHelp(<<<EOT
|
||||
The <info>%command.name%</info> command is meant to clear a second-level cache query region for an associated Entity Manager.
|
||||
It is possible to delete/invalidate all query region, a specific query region or flushes the cache provider.
|
||||
|
||||
The execution type differ on how you execute the command.
|
||||
If you want to invalidate all entries for the default query region this command would do the work:
|
||||
|
||||
<info>%command.name%</info>
|
||||
|
||||
To invalidate entries for a specific query region you should use :
|
||||
|
||||
<info>%command.name% my_region_name</info>
|
||||
|
||||
If you want to invalidate all entries for the all query region:
|
||||
|
||||
<info>%command.name% --all</info>
|
||||
|
||||
Alternatively, if you want to flush the configured cache provider use this command:
|
||||
|
||||
<info>%command.name% my_region_name --flush</info>
|
||||
|
||||
Finally, be aware that if <info>--flush</info> option is passed,
|
||||
not all cache providers are able to flush entries, because of a limitation of its execution nature.
|
||||
EOT
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$em = $this->getHelper('em')->getEntityManager();
|
||||
$name = $input->getArgument('region-name');
|
||||
$cache = $em->getCache();
|
||||
|
||||
if ($name === null) {
|
||||
$name = Cache::DEFAULT_QUERY_REGION_NAME;
|
||||
}
|
||||
|
||||
if ( ! $cache instanceof Cache) {
|
||||
throw new \InvalidArgumentException('No second-level cache is configured on the given EntityManager.');
|
||||
}
|
||||
|
||||
if ($input->getOption('flush')) {
|
||||
$queryCache = $cache->getQueryCache($name);
|
||||
$queryRegion = $queryCache->getRegion();
|
||||
|
||||
if ( ! $queryRegion instanceof DefaultRegion) {
|
||||
throw new \InvalidArgumentException(sprintf(
|
||||
'The option "--flush" expects a "Doctrine\ORM\Cache\Region\DefaultRegion", but got "%s".',
|
||||
is_object($queryRegion) ? get_class($queryRegion) : gettype($queryRegion)
|
||||
));
|
||||
}
|
||||
|
||||
$queryRegion->getCache()->flushAll();
|
||||
|
||||
$output->writeln(sprintf('Flushing cache provider configured for second-level cache query region named <info>"%s"</info>', $name));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($input->getOption('all')) {
|
||||
$output->writeln('Clearing <info>all</info> second-level cache query regions');
|
||||
|
||||
$cache->evictQueryRegions();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$output->writeln(sprintf('Clearing second-level cache query region named <info>"%s"</info>', $name));
|
||||
$cache->evictQueryRegion($name);
|
||||
}
|
||||
}
|
||||
108
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/ResultCommand.php
vendored
Normal file
108
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/ResultCommand.php
vendored
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
<?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\ORM\Tools\Console\Command\ClearCache;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Doctrine\Common\Cache\ApcCache;
|
||||
use Doctrine\Common\Cache\XcacheCache;
|
||||
|
||||
/**
|
||||
* Command to clear the result cache of the various cache drivers.
|
||||
*
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
class ResultCommand extends Command
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setName('orm:clear-cache:result')
|
||||
->setDescription('Clear all result cache of the various cache drivers.')
|
||||
->setDefinition(array(
|
||||
new InputOption(
|
||||
'flush', null, InputOption::VALUE_NONE,
|
||||
'If defined, cache entries will be flushed instead of deleted/invalidated.'
|
||||
)
|
||||
));
|
||||
|
||||
$this->setHelp(<<<EOT
|
||||
The <info>%command.name%</info> command is meant to clear the result cache of associated Entity Manager.
|
||||
It is possible to invalidate all cache entries at once - called delete -, or flushes the cache provider
|
||||
instance completely.
|
||||
|
||||
The execution type differ on how you execute the command.
|
||||
If you want to invalidate the entries (and not delete from cache instance), this command would do the work:
|
||||
|
||||
<info>%command.name%</info>
|
||||
|
||||
Alternatively, if you want to flush the cache provider using this command:
|
||||
|
||||
<info>%command.name% --flush</info>
|
||||
|
||||
Finally, be aware that if <info>--flush</info> option is passed, not all cache providers are able to flush entries,
|
||||
because of a limitation of its execution nature.
|
||||
EOT
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$em = $this->getHelper('em')->getEntityManager();
|
||||
$cacheDriver = $em->getConfiguration()->getResultCacheImpl();
|
||||
|
||||
if ( ! $cacheDriver) {
|
||||
throw new \InvalidArgumentException('No Result cache driver is configured on given EntityManager.');
|
||||
}
|
||||
|
||||
if ($cacheDriver instanceof ApcCache) {
|
||||
throw new \LogicException("Cannot clear APC Cache from Console, its shared in the Webserver memory and not accessible from the CLI.");
|
||||
}
|
||||
|
||||
if ($cacheDriver instanceof XcacheCache) {
|
||||
throw new \LogicException("Cannot clear XCache Cache from Console, its shared in the Webserver memory and not accessible from the CLI.");
|
||||
}
|
||||
|
||||
$output->writeln('Clearing ALL Result cache entries');
|
||||
|
||||
$result = $cacheDriver->deleteAll();
|
||||
$message = ($result) ? 'Successfully deleted cache entries.' : 'No cache entries were deleted.';
|
||||
|
||||
if (true === $input->getOption('flush')) {
|
||||
$result = $cacheDriver->flushAll();
|
||||
$message = ($result) ? 'Successfully flushed cache entries.' : $message;
|
||||
}
|
||||
|
||||
$output->writeln($message);
|
||||
}
|
||||
}
|
||||
230
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/ConvertDoctrine1SchemaCommand.php
vendored
Normal file
230
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/ConvertDoctrine1SchemaCommand.php
vendored
Normal file
|
|
@ -0,0 +1,230 @@
|
|||
<?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\ORM\Tools\Console\Command;
|
||||
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console;
|
||||
use Doctrine\ORM\Tools\Export\ClassMetadataExporter;
|
||||
use Doctrine\ORM\Tools\ConvertDoctrine1Schema;
|
||||
use Doctrine\ORM\Tools\EntityGenerator;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
|
||||
/**
|
||||
* Command to convert a Doctrine 1 schema to a Doctrine 2 mapping file.
|
||||
*
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
class ConvertDoctrine1SchemaCommand extends Command
|
||||
{
|
||||
/**
|
||||
* @var EntityGenerator|null
|
||||
*/
|
||||
private $entityGenerator = null;
|
||||
|
||||
/**
|
||||
* @var ClassMetadataExporter|null
|
||||
*/
|
||||
private $metadataExporter = null;
|
||||
|
||||
/**
|
||||
* @return EntityGenerator
|
||||
*/
|
||||
public function getEntityGenerator()
|
||||
{
|
||||
if ($this->entityGenerator == null) {
|
||||
$this->entityGenerator = new EntityGenerator();
|
||||
}
|
||||
|
||||
return $this->entityGenerator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param EntityGenerator $entityGenerator
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setEntityGenerator(EntityGenerator $entityGenerator)
|
||||
{
|
||||
$this->entityGenerator = $entityGenerator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ClassMetadataExporter
|
||||
*/
|
||||
public function getMetadataExporter()
|
||||
{
|
||||
if ($this->metadataExporter == null) {
|
||||
$this->metadataExporter = new ClassMetadataExporter();
|
||||
}
|
||||
|
||||
return $this->metadataExporter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ClassMetadataExporter $metadataExporter
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setMetadataExporter(ClassMetadataExporter $metadataExporter)
|
||||
{
|
||||
$this->metadataExporter = $metadataExporter;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setName('orm:convert-d1-schema')
|
||||
->setAliases(array('orm:convert:d1-schema'))
|
||||
->setDescription('Converts Doctrine 1.X schema into a Doctrine 2.X schema.')
|
||||
->setDefinition(array(
|
||||
new InputArgument(
|
||||
'from-path', InputArgument::REQUIRED, 'The path of Doctrine 1.X schema information.'
|
||||
),
|
||||
new InputArgument(
|
||||
'to-type', InputArgument::REQUIRED, 'The destination Doctrine 2.X mapping type.'
|
||||
),
|
||||
new InputArgument(
|
||||
'dest-path', InputArgument::REQUIRED,
|
||||
'The path to generate your Doctrine 2.X mapping information.'
|
||||
),
|
||||
new InputOption(
|
||||
'from', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
|
||||
'Optional paths of Doctrine 1.X schema information.',
|
||||
array()
|
||||
),
|
||||
new InputOption(
|
||||
'extend', null, InputOption::VALUE_OPTIONAL,
|
||||
'Defines a base class to be extended by generated entity classes.'
|
||||
),
|
||||
new InputOption(
|
||||
'num-spaces', null, InputOption::VALUE_OPTIONAL,
|
||||
'Defines the number of indentation spaces', 4
|
||||
)
|
||||
))
|
||||
->setHelp(<<<EOT
|
||||
Converts Doctrine 1.X schema into a Doctrine 2.X schema.
|
||||
EOT
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
// Process source directories
|
||||
$fromPaths = array_merge(array($input->getArgument('from-path')), $input->getOption('from'));
|
||||
|
||||
// Process destination directory
|
||||
$destPath = realpath($input->getArgument('dest-path'));
|
||||
|
||||
$toType = $input->getArgument('to-type');
|
||||
$extend = $input->getOption('extend');
|
||||
$numSpaces = $input->getOption('num-spaces');
|
||||
|
||||
$this->convertDoctrine1Schema($fromPaths, $destPath, $toType, $numSpaces, $extend, $output);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $fromPaths
|
||||
* @param string $destPath
|
||||
* @param string $toType
|
||||
* @param int $numSpaces
|
||||
* @param string|null $extend
|
||||
* @param OutputInterface $output
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function convertDoctrine1Schema(array $fromPaths, $destPath, $toType, $numSpaces, $extend, OutputInterface $output)
|
||||
{
|
||||
foreach ($fromPaths as &$dirName) {
|
||||
$dirName = realpath($dirName);
|
||||
|
||||
if ( ! file_exists($dirName)) {
|
||||
throw new \InvalidArgumentException(
|
||||
sprintf("Doctrine 1.X schema directory '<info>%s</info>' does not exist.", $dirName)
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! is_readable($dirName)) {
|
||||
throw new \InvalidArgumentException(
|
||||
sprintf("Doctrine 1.X schema directory '<info>%s</info>' does not have read permissions.", $dirName)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! file_exists($destPath)) {
|
||||
throw new \InvalidArgumentException(
|
||||
sprintf("Doctrine 2.X mapping destination directory '<info>%s</info>' does not exist.", $destPath)
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! is_writable($destPath)) {
|
||||
throw new \InvalidArgumentException(
|
||||
sprintf("Doctrine 2.X mapping destination directory '<info>%s</info>' does not have write permissions.", $destPath)
|
||||
);
|
||||
}
|
||||
|
||||
$cme = $this->getMetadataExporter();
|
||||
$exporter = $cme->getExporter($toType, $destPath);
|
||||
|
||||
if (strtolower($toType) === 'annotation') {
|
||||
$entityGenerator = $this->getEntityGenerator();
|
||||
$exporter->setEntityGenerator($entityGenerator);
|
||||
|
||||
$entityGenerator->setNumSpaces($numSpaces);
|
||||
|
||||
if ($extend !== null) {
|
||||
$entityGenerator->setClassToExtend($extend);
|
||||
}
|
||||
}
|
||||
|
||||
$converter = new ConvertDoctrine1Schema($fromPaths);
|
||||
$metadata = $converter->getMetadata();
|
||||
|
||||
if ($metadata) {
|
||||
$output->writeln('');
|
||||
|
||||
foreach ($metadata as $class) {
|
||||
$output->writeln(sprintf('Processing entity "<info>%s</info>"', $class->name));
|
||||
}
|
||||
|
||||
$exporter->setMetadata($metadata);
|
||||
$exporter->export();
|
||||
|
||||
$output->writeln(PHP_EOL . sprintf(
|
||||
'Converting Doctrine 1.X schema to "<info>%s</info>" mapping type in "<info>%s</info>"', $toType, $destPath
|
||||
));
|
||||
} else {
|
||||
$output->writeln('No Metadata Classes to process.');
|
||||
}
|
||||
}
|
||||
}
|
||||
200
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php
vendored
Normal file
200
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php
vendored
Normal file
|
|
@ -0,0 +1,200 @@
|
|||
<?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\ORM\Tools\Console\Command;
|
||||
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Doctrine\ORM\Tools\Console\MetadataFilter;
|
||||
use Doctrine\ORM\Tools\Export\ClassMetadataExporter;
|
||||
use Doctrine\ORM\Tools\EntityGenerator;
|
||||
use Doctrine\ORM\Tools\DisconnectedClassMetadataFactory;
|
||||
use Doctrine\ORM\Mapping\Driver\DatabaseDriver;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
|
||||
/**
|
||||
* Command to convert your mapping information between the various formats.
|
||||
*
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
class ConvertMappingCommand extends Command
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setName('orm:convert-mapping')
|
||||
->setAliases(array('orm:convert:mapping'))
|
||||
->setDescription('Convert mapping information between supported formats.')
|
||||
->setDefinition(array(
|
||||
new InputOption(
|
||||
'filter', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
|
||||
'A string pattern used to match entities that should be processed.'
|
||||
),
|
||||
new InputArgument(
|
||||
'to-type', InputArgument::REQUIRED, 'The mapping type to be converted.'
|
||||
),
|
||||
new InputArgument(
|
||||
'dest-path', InputArgument::REQUIRED,
|
||||
'The path to generate your entities classes.'
|
||||
),
|
||||
new InputOption(
|
||||
'force', 'f', InputOption::VALUE_NONE,
|
||||
'Force to overwrite existing mapping files.'
|
||||
),
|
||||
new InputOption(
|
||||
'from-database', null, null, 'Whether or not to convert mapping information from existing database.'
|
||||
),
|
||||
new InputOption(
|
||||
'extend', null, InputOption::VALUE_OPTIONAL,
|
||||
'Defines a base class to be extended by generated entity classes.'
|
||||
),
|
||||
new InputOption(
|
||||
'num-spaces', null, InputOption::VALUE_OPTIONAL,
|
||||
'Defines the number of indentation spaces', 4
|
||||
),
|
||||
new InputOption(
|
||||
'namespace', null, InputOption::VALUE_OPTIONAL,
|
||||
'Defines a namespace for the generated entity classes, if converted from database.'
|
||||
),
|
||||
))
|
||||
->setHelp(<<<EOT
|
||||
Convert mapping information between supported formats.
|
||||
|
||||
This is an execute <info>one-time</info> command. It should not be necessary for
|
||||
you to call this method multiple times, especially when using the <comment>--from-database</comment>
|
||||
flag.
|
||||
|
||||
Converting an existing database schema into mapping files only solves about 70-80%
|
||||
of the necessary mapping information. Additionally the detection from an existing
|
||||
database cannot detect inverse associations, inheritance types,
|
||||
entities with foreign keys as primary keys and many of the
|
||||
semantical operations on associations such as cascade.
|
||||
|
||||
<comment>Hint:</comment> There is no need to convert YAML or XML mapping files to annotations
|
||||
every time you make changes. All mapping drivers are first class citizens
|
||||
in Doctrine 2 and can be used as runtime mapping for the ORM.
|
||||
|
||||
<comment>Hint:</comment> If you have a database with tables that should not be managed
|
||||
by the ORM, you can use a DBAL functionality to filter the tables and sequences down
|
||||
on a global level:
|
||||
|
||||
\$config->setFilterSchemaAssetsExpression(\$regexp);
|
||||
EOT
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$em = $this->getHelper('em')->getEntityManager();
|
||||
|
||||
if ($input->getOption('from-database') === true) {
|
||||
$databaseDriver = new DatabaseDriver(
|
||||
$em->getConnection()->getSchemaManager()
|
||||
);
|
||||
|
||||
$em->getConfiguration()->setMetadataDriverImpl(
|
||||
$databaseDriver
|
||||
);
|
||||
|
||||
if (($namespace = $input->getOption('namespace')) !== null) {
|
||||
$databaseDriver->setNamespace($namespace);
|
||||
}
|
||||
}
|
||||
|
||||
$cmf = new DisconnectedClassMetadataFactory();
|
||||
$cmf->setEntityManager($em);
|
||||
$metadata = $cmf->getAllMetadata();
|
||||
$metadata = MetadataFilter::filter($metadata, $input->getOption('filter'));
|
||||
|
||||
// Process destination directory
|
||||
if ( ! is_dir($destPath = $input->getArgument('dest-path'))) {
|
||||
mkdir($destPath, 0775, true);
|
||||
}
|
||||
$destPath = realpath($destPath);
|
||||
|
||||
if ( ! file_exists($destPath)) {
|
||||
throw new \InvalidArgumentException(
|
||||
sprintf("Mapping destination directory '<info>%s</info>' does not exist.", $input->getArgument('dest-path'))
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! is_writable($destPath)) {
|
||||
throw new \InvalidArgumentException(
|
||||
sprintf("Mapping destination directory '<info>%s</info>' does not have write permissions.", $destPath)
|
||||
);
|
||||
}
|
||||
|
||||
$toType = strtolower($input->getArgument('to-type'));
|
||||
|
||||
$exporter = $this->getExporter($toType, $destPath);
|
||||
$exporter->setOverwriteExistingFiles($input->getOption('force'));
|
||||
|
||||
if ($toType == 'annotation') {
|
||||
$entityGenerator = new EntityGenerator();
|
||||
$exporter->setEntityGenerator($entityGenerator);
|
||||
|
||||
$entityGenerator->setNumSpaces($input->getOption('num-spaces'));
|
||||
|
||||
if (($extend = $input->getOption('extend')) !== null) {
|
||||
$entityGenerator->setClassToExtend($extend);
|
||||
}
|
||||
}
|
||||
|
||||
if (count($metadata)) {
|
||||
foreach ($metadata as $class) {
|
||||
$output->writeln(sprintf('Processing entity "<info>%s</info>"', $class->name));
|
||||
}
|
||||
|
||||
$exporter->setMetadata($metadata);
|
||||
$exporter->export();
|
||||
|
||||
$output->writeln(PHP_EOL . sprintf(
|
||||
'Exporting "<info>%s</info>" mapping information to "<info>%s</info>"', $toType, $destPath
|
||||
));
|
||||
} else {
|
||||
$output->writeln('No Metadata Classes to process.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $toType
|
||||
* @param string $destPath
|
||||
*
|
||||
* @return \Doctrine\ORM\Tools\Export\Driver\AbstractExporter
|
||||
*/
|
||||
protected function getExporter($toType, $destPath)
|
||||
{
|
||||
$cme = new ClassMetadataExporter();
|
||||
|
||||
return $cme->getExporter($toType, $destPath);
|
||||
}
|
||||
}
|
||||
81
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/EnsureProductionSettingsCommand.php
vendored
Normal file
81
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/EnsureProductionSettingsCommand.php
vendored
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
<?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\ORM\Tools\Console\Command;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
/**
|
||||
* Command to ensure that Doctrine is properly configured for a production environment.
|
||||
*
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @version $Revision$
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
class EnsureProductionSettingsCommand extends Command
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setName('orm:ensure-production-settings')
|
||||
->setDescription('Verify that Doctrine is properly configured for a production environment.')
|
||||
->setDefinition(array(
|
||||
new InputOption(
|
||||
'complete', null, InputOption::VALUE_NONE,
|
||||
'Flag to also inspect database connection existence.'
|
||||
)
|
||||
))
|
||||
->setHelp(<<<EOT
|
||||
Verify that Doctrine is properly configured for a production environment.
|
||||
EOT
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$em = $this->getHelper('em')->getEntityManager();
|
||||
|
||||
try {
|
||||
$em->getConfiguration()->ensureProductionSettings();
|
||||
|
||||
if ($input->getOption('complete') !== null) {
|
||||
$em->getConnection()->connect();
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$output->writeln('<error>' . $e->getMessage() . '</error>');
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
$output->writeln('<info>Environment is correctly configured for production.</info>');
|
||||
}
|
||||
}
|
||||
169
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/GenerateEntitiesCommand.php
vendored
Normal file
169
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/GenerateEntitiesCommand.php
vendored
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
<?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\ORM\Tools\Console\Command;
|
||||
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Doctrine\ORM\Tools\Console\MetadataFilter;
|
||||
use Doctrine\ORM\Tools\EntityGenerator;
|
||||
use Doctrine\ORM\Tools\DisconnectedClassMetadataFactory;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
|
||||
/**
|
||||
* Command to generate entity classes and method stubs from your mapping information.
|
||||
*
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
class GenerateEntitiesCommand extends Command
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setName('orm:generate-entities')
|
||||
->setAliases(array('orm:generate:entities'))
|
||||
->setDescription('Generate entity classes and method stubs from your mapping information.')
|
||||
->setDefinition(array(
|
||||
new InputOption(
|
||||
'filter', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
|
||||
'A string pattern used to match entities that should be processed.'
|
||||
),
|
||||
new InputArgument(
|
||||
'dest-path', InputArgument::REQUIRED, 'The path to generate your entity classes.'
|
||||
),
|
||||
new InputOption(
|
||||
'generate-annotations', null, InputOption::VALUE_OPTIONAL,
|
||||
'Flag to define if generator should generate annotation metadata on entities.', false
|
||||
),
|
||||
new InputOption(
|
||||
'generate-methods', null, InputOption::VALUE_OPTIONAL,
|
||||
'Flag to define if generator should generate stub methods on entities.', true
|
||||
),
|
||||
new InputOption(
|
||||
'regenerate-entities', null, InputOption::VALUE_OPTIONAL,
|
||||
'Flag to define if generator should regenerate entity if it exists.', false
|
||||
),
|
||||
new InputOption(
|
||||
'update-entities', null, InputOption::VALUE_OPTIONAL,
|
||||
'Flag to define if generator should only update entity if it exists.', true
|
||||
),
|
||||
new InputOption(
|
||||
'extend', null, InputOption::VALUE_REQUIRED,
|
||||
'Defines a base class to be extended by generated entity classes.'
|
||||
),
|
||||
new InputOption(
|
||||
'num-spaces', null, InputOption::VALUE_REQUIRED,
|
||||
'Defines the number of indentation spaces', 4
|
||||
),
|
||||
new InputOption(
|
||||
'no-backup', null, InputOption::VALUE_NONE,
|
||||
'Flag to define if generator should avoid backuping existing entity file if it exists.'
|
||||
)
|
||||
))
|
||||
->setHelp(<<<EOT
|
||||
Generate entity classes and method stubs from your mapping information.
|
||||
|
||||
If you use the <comment>--update-entities</comment> or <comment>--regenerate-entities</comment> flags your existing
|
||||
code gets overwritten. The EntityGenerator will only append new code to your
|
||||
file and will not delete the old code. However this approach may still be prone
|
||||
to error and we suggest you use code repositories such as GIT or SVN to make
|
||||
backups of your code.
|
||||
|
||||
It makes sense to generate the entity code if you are using entities as Data
|
||||
Access Objects only and don't put much additional logic on them. If you are
|
||||
however putting much more logic on the entities you should refrain from using
|
||||
the entity-generator and code your entities manually.
|
||||
|
||||
<error>Important:</error> Even if you specified Inheritance options in your
|
||||
XML or YAML Mapping files the generator cannot generate the base and
|
||||
child classes for you correctly, because it doesn't know which
|
||||
class is supposed to extend which. You have to adjust the entity
|
||||
code manually for inheritance to work!
|
||||
EOT
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$em = $this->getHelper('em')->getEntityManager();
|
||||
|
||||
$cmf = new DisconnectedClassMetadataFactory();
|
||||
$cmf->setEntityManager($em);
|
||||
$metadatas = $cmf->getAllMetadata();
|
||||
$metadatas = MetadataFilter::filter($metadatas, $input->getOption('filter'));
|
||||
|
||||
// Process destination directory
|
||||
$destPath = realpath($input->getArgument('dest-path'));
|
||||
|
||||
if ( ! file_exists($destPath)) {
|
||||
throw new \InvalidArgumentException(
|
||||
sprintf("Entities destination directory '<info>%s</info>' does not exist.", $input->getArgument('dest-path'))
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! is_writable($destPath)) {
|
||||
throw new \InvalidArgumentException(
|
||||
sprintf("Entities destination directory '<info>%s</info>' does not have write permissions.", $destPath)
|
||||
);
|
||||
}
|
||||
|
||||
if (count($metadatas)) {
|
||||
// Create EntityGenerator
|
||||
$entityGenerator = new EntityGenerator();
|
||||
|
||||
$entityGenerator->setGenerateAnnotations($input->getOption('generate-annotations'));
|
||||
$entityGenerator->setGenerateStubMethods($input->getOption('generate-methods'));
|
||||
$entityGenerator->setRegenerateEntityIfExists($input->getOption('regenerate-entities'));
|
||||
$entityGenerator->setUpdateEntityIfExists($input->getOption('update-entities'));
|
||||
$entityGenerator->setNumSpaces($input->getOption('num-spaces'));
|
||||
$entityGenerator->setBackupExisting(!$input->getOption('no-backup'));
|
||||
|
||||
if (($extend = $input->getOption('extend')) !== null) {
|
||||
$entityGenerator->setClassToExtend($extend);
|
||||
}
|
||||
|
||||
foreach ($metadatas as $metadata) {
|
||||
$output->writeln(
|
||||
sprintf('Processing entity "<info>%s</info>"', $metadata->name)
|
||||
);
|
||||
}
|
||||
|
||||
// Generating Entities
|
||||
$entityGenerator->generate($metadatas, $destPath);
|
||||
|
||||
// Outputting information message
|
||||
$output->writeln(PHP_EOL . sprintf('Entity classes generated to "<info>%s</INFO>"', $destPath));
|
||||
} else {
|
||||
$output->writeln('No Metadata Classes to process.');
|
||||
}
|
||||
}
|
||||
}
|
||||
115
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/GenerateProxiesCommand.php
vendored
Normal file
115
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/GenerateProxiesCommand.php
vendored
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
<?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\ORM\Tools\Console\Command;
|
||||
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Doctrine\ORM\Tools\Console\MetadataFilter;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
|
||||
/**
|
||||
* Command to (re)generate the proxy classes used by doctrine.
|
||||
*
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
class GenerateProxiesCommand extends Command
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setName('orm:generate-proxies')
|
||||
->setAliases(array('orm:generate:proxies'))
|
||||
->setDescription('Generates proxy classes for entity classes.')
|
||||
->setDefinition(array(
|
||||
new InputOption(
|
||||
'filter', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
|
||||
'A string pattern used to match entities that should be processed.'
|
||||
),
|
||||
new InputArgument(
|
||||
'dest-path', InputArgument::OPTIONAL,
|
||||
'The path to generate your proxy classes. If none is provided, it will attempt to grab from configuration.'
|
||||
),
|
||||
))
|
||||
->setHelp(<<<EOT
|
||||
Generates proxy classes for entity classes.
|
||||
EOT
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$em = $this->getHelper('em')->getEntityManager();
|
||||
|
||||
$metadatas = $em->getMetadataFactory()->getAllMetadata();
|
||||
$metadatas = MetadataFilter::filter($metadatas, $input->getOption('filter'));
|
||||
|
||||
// Process destination directory
|
||||
if (($destPath = $input->getArgument('dest-path')) === null) {
|
||||
$destPath = $em->getConfiguration()->getProxyDir();
|
||||
}
|
||||
|
||||
if ( ! is_dir($destPath)) {
|
||||
mkdir($destPath, 0775, true);
|
||||
}
|
||||
|
||||
$destPath = realpath($destPath);
|
||||
|
||||
if ( ! file_exists($destPath)) {
|
||||
throw new \InvalidArgumentException(
|
||||
sprintf("Proxies destination directory '<info>%s</info>' does not exist.", $em->getConfiguration()->getProxyDir())
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! is_writable($destPath)) {
|
||||
throw new \InvalidArgumentException(
|
||||
sprintf("Proxies destination directory '<info>%s</info>' does not have write permissions.", $destPath)
|
||||
);
|
||||
}
|
||||
|
||||
if ( count($metadatas)) {
|
||||
foreach ($metadatas as $metadata) {
|
||||
$output->writeln(
|
||||
sprintf('Processing entity "<info>%s</info>"', $metadata->name)
|
||||
);
|
||||
}
|
||||
|
||||
// Generating Proxies
|
||||
$em->getProxyFactory()->generateProxyClasses($metadatas, $destPath);
|
||||
|
||||
// Outputting information message
|
||||
$output->writeln(PHP_EOL . sprintf('Proxy classes generated to "<info>%s</INFO>"', $destPath));
|
||||
} else {
|
||||
$output->writeln('No Metadata Classes to process.');
|
||||
}
|
||||
}
|
||||
}
|
||||
121
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/GenerateRepositoriesCommand.php
vendored
Normal file
121
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/GenerateRepositoriesCommand.php
vendored
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
<?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\ORM\Tools\Console\Command;
|
||||
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Doctrine\ORM\Tools\Console\MetadataFilter;
|
||||
use Doctrine\ORM\Tools\EntityRepositoryGenerator;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
|
||||
/**
|
||||
* Command to generate repository classes for mapping information.
|
||||
*
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
class GenerateRepositoriesCommand extends Command
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setName('orm:generate-repositories')
|
||||
->setAliases(array('orm:generate:repositories'))
|
||||
->setDescription('Generate repository classes from your mapping information.')
|
||||
->setDefinition(array(
|
||||
new InputOption(
|
||||
'filter', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
|
||||
'A string pattern used to match entities that should be processed.'
|
||||
),
|
||||
new InputArgument(
|
||||
'dest-path', InputArgument::REQUIRED, 'The path to generate your repository classes.'
|
||||
)
|
||||
))
|
||||
->setHelp(<<<EOT
|
||||
Generate repository classes from your mapping information.
|
||||
EOT
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$em = $this->getHelper('em')->getEntityManager();
|
||||
|
||||
$metadatas = $em->getMetadataFactory()->getAllMetadata();
|
||||
$metadatas = MetadataFilter::filter($metadatas, $input->getOption('filter'));
|
||||
|
||||
$repositoryName = $em->getConfiguration()->getDefaultRepositoryClassName();
|
||||
|
||||
// Process destination directory
|
||||
$destPath = realpath($input->getArgument('dest-path'));
|
||||
|
||||
if ( ! file_exists($destPath)) {
|
||||
throw new \InvalidArgumentException(
|
||||
sprintf("Entities destination directory '<info>%s</info>' does not exist.", $input->getArgument('dest-path'))
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! is_writable($destPath)) {
|
||||
throw new \InvalidArgumentException(
|
||||
sprintf("Entities destination directory '<info>%s</info>' does not have write permissions.", $destPath)
|
||||
);
|
||||
}
|
||||
|
||||
if (count($metadatas)) {
|
||||
$numRepositories = 0;
|
||||
$generator = new EntityRepositoryGenerator();
|
||||
|
||||
$generator->setDefaultRepositoryName($repositoryName);
|
||||
|
||||
foreach ($metadatas as $metadata) {
|
||||
if ($metadata->customRepositoryClassName) {
|
||||
$output->writeln(
|
||||
sprintf('Processing repository "<info>%s</info>"', $metadata->customRepositoryClassName)
|
||||
);
|
||||
|
||||
$generator->writeEntityRepositoryClass($metadata->customRepositoryClassName, $destPath);
|
||||
|
||||
$numRepositories++;
|
||||
}
|
||||
}
|
||||
|
||||
if ($numRepositories) {
|
||||
// Outputting information message
|
||||
$output->writeln(PHP_EOL . sprintf('Repository classes generated to "<info>%s</INFO>"', $destPath) );
|
||||
} else {
|
||||
$output->writeln('No Repository classes were found to be processed.' );
|
||||
}
|
||||
} else {
|
||||
$output->writeln('No Metadata Classes to process.' );
|
||||
}
|
||||
}
|
||||
}
|
||||
90
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/InfoCommand.php
vendored
Normal file
90
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/InfoCommand.php
vendored
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
<?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\ORM\Tools\Console\Command;
|
||||
|
||||
use Doctrine\ORM\Mapping\MappingException;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
|
||||
/**
|
||||
* Show information about mapped entities.
|
||||
*
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.1
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
*/
|
||||
class InfoCommand extends Command
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setName('orm:info')
|
||||
->setDescription('Show basic information about all mapped entities')
|
||||
->setHelp(<<<EOT
|
||||
The <info>%command.name%</info> shows basic information about which
|
||||
entities exist and possibly if their mapping information contains errors or
|
||||
not.
|
||||
EOT
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
/* @var $entityManager \Doctrine\ORM\EntityManager */
|
||||
$entityManager = $this->getHelper('em')->getEntityManager();
|
||||
|
||||
$entityClassNames = $entityManager->getConfiguration()
|
||||
->getMetadataDriverImpl()
|
||||
->getAllClassNames();
|
||||
|
||||
if (!$entityClassNames) {
|
||||
throw new \Exception(
|
||||
'You do not have any mapped Doctrine ORM entities according to the current configuration. '.
|
||||
'If you have entities or mapping files you should check your mapping configuration for errors.'
|
||||
);
|
||||
}
|
||||
|
||||
$output->writeln(sprintf("Found <info>%d</info> mapped entities:", count($entityClassNames)));
|
||||
|
||||
$failure = false;
|
||||
|
||||
foreach ($entityClassNames as $entityClassName) {
|
||||
try {
|
||||
$entityManager->getClassMetadata($entityClassName);
|
||||
$output->writeln(sprintf("<info>[OK]</info> %s", $entityClassName));
|
||||
} catch (MappingException $e) {
|
||||
$output->writeln("<error>[FAIL]</error> ".$entityClassName);
|
||||
$output->writeln(sprintf("<comment>%s</comment>", $e->getMessage()));
|
||||
$output->writeln('');
|
||||
|
||||
$failure = true;
|
||||
}
|
||||
}
|
||||
|
||||
return $failure ? 1 : 0;
|
||||
}
|
||||
}
|
||||
298
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/MappingDescribeCommand.php
vendored
Normal file
298
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/MappingDescribeCommand.php
vendored
Normal file
|
|
@ -0,0 +1,298 @@
|
|||
<?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\ORM\Tools\Console\Command;
|
||||
|
||||
use Doctrine\Common\Persistence\Mapping\MappingException;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Helper\Table;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
/**
|
||||
* Show information about mapped entities.
|
||||
*
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.4
|
||||
* @author Daniel Leech <daniel@dantleech.com>
|
||||
*/
|
||||
final class MappingDescribeCommand extends Command
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setName('orm:mapping:describe')
|
||||
->addArgument('entityName', InputArgument::REQUIRED, 'Full or partial name of entity')
|
||||
->setDescription('Display information about mapped objects')
|
||||
->setHelp(<<<EOT
|
||||
The %command.full_name% command describes the metadata for the given full or partial entity class name.
|
||||
|
||||
<info>%command.full_name%</info> My\Namespace\Entity\MyEntity
|
||||
|
||||
Or:
|
||||
|
||||
<info>%command.full_name%</info> MyEntity
|
||||
EOT
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
/* @var $entityManager \Doctrine\ORM\EntityManagerInterface */
|
||||
$entityManager = $this->getHelper('em')->getEntityManager();
|
||||
|
||||
$this->displayEntity($input->getArgument('entityName'), $entityManager, $output);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display all the mapping information for a single Entity.
|
||||
*
|
||||
* @param string $entityName Full or partial entity class name
|
||||
* @param EntityManagerInterface $entityManager
|
||||
* @param OutputInterface $output
|
||||
*/
|
||||
private function displayEntity($entityName, EntityManagerInterface $entityManager, OutputInterface $output)
|
||||
{
|
||||
$table = new Table($output);
|
||||
|
||||
$table->setHeaders(array('Field', 'Value'));
|
||||
|
||||
$metadata = $this->getClassMetadata($entityName, $entityManager);
|
||||
|
||||
array_map(
|
||||
array($table, 'addRow'),
|
||||
array_merge(
|
||||
array(
|
||||
$this->formatField('Name', $metadata->name),
|
||||
$this->formatField('Root entity name', $metadata->rootEntityName),
|
||||
$this->formatField('Custom generator definition', $metadata->customGeneratorDefinition),
|
||||
$this->formatField('Custom repository class', $metadata->customRepositoryClassName),
|
||||
$this->formatField('Mapped super class?', $metadata->isMappedSuperclass),
|
||||
$this->formatField('Embedded class?', $metadata->isEmbeddedClass),
|
||||
$this->formatField('Parent classes', $metadata->parentClasses),
|
||||
$this->formatField('Sub classes', $metadata->subClasses),
|
||||
$this->formatField('Embedded classes', $metadata->subClasses),
|
||||
$this->formatField('Named queries', $metadata->namedQueries),
|
||||
$this->formatField('Named native queries', $metadata->namedNativeQueries),
|
||||
$this->formatField('SQL result set mappings', $metadata->sqlResultSetMappings),
|
||||
$this->formatField('Identifier', $metadata->identifier),
|
||||
$this->formatField('Inheritance type', $metadata->inheritanceType),
|
||||
$this->formatField('Discriminator column', $metadata->discriminatorColumn),
|
||||
$this->formatField('Discriminator value', $metadata->discriminatorValue),
|
||||
$this->formatField('Discriminator map', $metadata->discriminatorMap),
|
||||
$this->formatField('Generator type', $metadata->generatorType),
|
||||
$this->formatField('Table', $metadata->table),
|
||||
$this->formatField('Composite identifier?', $metadata->isIdentifierComposite),
|
||||
$this->formatField('Foreign identifier?', $metadata->containsForeignIdentifier),
|
||||
$this->formatField('Sequence generator definition', $metadata->sequenceGeneratorDefinition),
|
||||
$this->formatField('Table generator definition', $metadata->tableGeneratorDefinition),
|
||||
$this->formatField('Change tracking policy', $metadata->changeTrackingPolicy),
|
||||
$this->formatField('Versioned?', $metadata->isVersioned),
|
||||
$this->formatField('Version field', $metadata->versionField),
|
||||
$this->formatField('Read only?', $metadata->isReadOnly),
|
||||
|
||||
$this->formatEntityListeners($metadata->entityListeners),
|
||||
),
|
||||
array($this->formatField('Association mappings:', '')),
|
||||
$this->formatMappings($metadata->associationMappings),
|
||||
array($this->formatField('Field mappings:', '')),
|
||||
$this->formatMappings($metadata->fieldMappings)
|
||||
)
|
||||
);
|
||||
|
||||
$table->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all mapped entity class names
|
||||
*
|
||||
* @param EntityManagerInterface $entityManager
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
private function getMappedEntities(EntityManagerInterface $entityManager)
|
||||
{
|
||||
$entityClassNames = $entityManager
|
||||
->getConfiguration()
|
||||
->getMetadataDriverImpl()
|
||||
->getAllClassNames();
|
||||
|
||||
if ( ! $entityClassNames) {
|
||||
throw new \InvalidArgumentException(
|
||||
'You do not have any mapped Doctrine ORM entities according to the current configuration. '.
|
||||
'If you have entities or mapping files you should check your mapping configuration for errors.'
|
||||
);
|
||||
}
|
||||
|
||||
return $entityClassNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the class metadata for the given entity
|
||||
* name
|
||||
*
|
||||
* @param string $entityName Full or partial entity name
|
||||
* @param EntityManagerInterface $entityManager
|
||||
*
|
||||
* @return \Doctrine\ORM\Mapping\ClassMetadata
|
||||
*/
|
||||
private function getClassMetadata($entityName, EntityManagerInterface $entityManager)
|
||||
{
|
||||
try {
|
||||
return $entityManager->getClassMetadata($entityName);
|
||||
} catch (MappingException $e) {
|
||||
}
|
||||
|
||||
$matches = array_filter(
|
||||
$this->getMappedEntities($entityManager),
|
||||
function ($mappedEntity) use ($entityName) {
|
||||
return preg_match('{' . preg_quote($entityName) . '}', $mappedEntity);
|
||||
}
|
||||
);
|
||||
|
||||
if ( ! $matches) {
|
||||
throw new \InvalidArgumentException(sprintf(
|
||||
'Could not find any mapped Entity classes matching "%s"',
|
||||
$entityName
|
||||
));
|
||||
}
|
||||
|
||||
if (count($matches) > 1) {
|
||||
throw new \InvalidArgumentException(sprintf(
|
||||
'Entity name "%s" is ambigous, possible matches: "%s"',
|
||||
$entityName, implode(', ', $matches)
|
||||
));
|
||||
}
|
||||
|
||||
return $entityManager->getClassMetadata(current($matches));
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the given value for console output
|
||||
*
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function formatValue($value)
|
||||
{
|
||||
if ('' === $value) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (null === $value) {
|
||||
return '<comment>Null</comment>';
|
||||
}
|
||||
|
||||
if (is_bool($value)) {
|
||||
return '<comment>' . ($value ? 'True' : 'False') . '</comment>';
|
||||
}
|
||||
|
||||
if (empty($value)) {
|
||||
return '<comment>Empty</comment>';
|
||||
}
|
||||
|
||||
if (is_array($value)) {
|
||||
if (defined('JSON_UNESCAPED_UNICODE') && defined('JSON_UNESCAPED_SLASHES')) {
|
||||
return json_encode($value, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||
}
|
||||
|
||||
return json_encode($value);
|
||||
}
|
||||
|
||||
if (is_object($value)) {
|
||||
return sprintf('<%s>', get_class($value));
|
||||
}
|
||||
|
||||
if (is_scalar($value)) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
throw new \InvalidArgumentException(sprintf('Do not know how to format value "%s"', print_r($value, true)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the given label and value to the two column table output
|
||||
*
|
||||
* @param string $label Label for the value
|
||||
* @param mixed $value A Value to show
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function formatField($label, $value)
|
||||
{
|
||||
if (null === $value) {
|
||||
$value = '<comment>None</comment>';
|
||||
}
|
||||
|
||||
return array(sprintf('<info>%s</info>', $label), $this->formatValue($value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the association mappings
|
||||
*
|
||||
* @param array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function formatMappings(array $propertyMappings)
|
||||
{
|
||||
$output = array();
|
||||
|
||||
foreach ($propertyMappings as $propertyName => $mapping) {
|
||||
$output[] = $this->formatField(sprintf(' %s', $propertyName), '');
|
||||
|
||||
foreach ($mapping as $field => $value) {
|
||||
$output[] = $this->formatField(sprintf(' %s', $field), $this->formatValue($value));
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the entity listeners
|
||||
*
|
||||
* @param array $entityListeners
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function formatEntityListeners(array $entityListeners)
|
||||
{
|
||||
return $this->formatField(
|
||||
'Entity listeners',
|
||||
array_map(
|
||||
function ($entityListener) {
|
||||
return get_class($entityListener);
|
||||
},
|
||||
$entityListeners
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
133
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/RunDqlCommand.php
vendored
Normal file
133
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/RunDqlCommand.php
vendored
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
<?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\ORM\Tools\Console\Command;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Doctrine\Common\Util\Debug;
|
||||
|
||||
/**
|
||||
* Command to execute DQL queries in a given EntityManager.
|
||||
*
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
class RunDqlCommand extends Command
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setName('orm:run-dql')
|
||||
->setDescription('Executes arbitrary DQL directly from the command line.')
|
||||
->setDefinition(array(
|
||||
new InputArgument('dql', InputArgument::REQUIRED, 'The DQL to execute.'),
|
||||
new InputOption(
|
||||
'hydrate', null, InputOption::VALUE_REQUIRED,
|
||||
'Hydration mode of result set. Should be either: object, array, scalar or single-scalar.',
|
||||
'object'
|
||||
),
|
||||
new InputOption(
|
||||
'first-result', null, InputOption::VALUE_REQUIRED,
|
||||
'The first result in the result set.'
|
||||
),
|
||||
new InputOption(
|
||||
'max-result', null, InputOption::VALUE_REQUIRED,
|
||||
'The maximum number of results in the result set.'
|
||||
),
|
||||
new InputOption(
|
||||
'depth', null, InputOption::VALUE_REQUIRED,
|
||||
'Dumping depth of Entity graph.', 7
|
||||
),
|
||||
new InputOption(
|
||||
'show-sql', null, InputOption::VALUE_NONE,
|
||||
'Dump generated SQL instead of executing query'
|
||||
)
|
||||
))
|
||||
->setHelp(<<<EOT
|
||||
Executes arbitrary DQL directly from the command line.
|
||||
EOT
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
/* @var $em \Doctrine\ORM\EntityManagerInterface */
|
||||
$em = $this->getHelper('em')->getEntityManager();
|
||||
|
||||
if (($dql = $input->getArgument('dql')) === null) {
|
||||
throw new \RuntimeException("Argument 'DQL' is required in order to execute this command correctly.");
|
||||
}
|
||||
|
||||
$depth = $input->getOption('depth');
|
||||
|
||||
if ( ! is_numeric($depth)) {
|
||||
throw new \LogicException("Option 'depth' must contains an integer value");
|
||||
}
|
||||
|
||||
$hydrationModeName = $input->getOption('hydrate');
|
||||
$hydrationMode = 'Doctrine\ORM\Query::HYDRATE_' . strtoupper(str_replace('-', '_', $hydrationModeName));
|
||||
|
||||
if ( ! defined($hydrationMode)) {
|
||||
throw new \RuntimeException(
|
||||
"Hydration mode '$hydrationModeName' does not exist. It should be either: object. array, scalar or single-scalar."
|
||||
);
|
||||
}
|
||||
|
||||
$query = $em->createQuery($dql);
|
||||
|
||||
if (($firstResult = $input->getOption('first-result')) !== null) {
|
||||
if ( ! is_numeric($firstResult)) {
|
||||
throw new \LogicException("Option 'first-result' must contains an integer value");
|
||||
}
|
||||
|
||||
$query->setFirstResult((int) $firstResult);
|
||||
}
|
||||
|
||||
if (($maxResult = $input->getOption('max-result')) !== null) {
|
||||
if ( ! is_numeric($maxResult)) {
|
||||
throw new \LogicException("Option 'max-result' must contains an integer value");
|
||||
}
|
||||
|
||||
$query->setMaxResults((int) $maxResult);
|
||||
}
|
||||
|
||||
if ($input->getOption('show-sql')) {
|
||||
$output->writeln(Debug::dump($query->getSQL(), 2, true, false));
|
||||
return;
|
||||
}
|
||||
|
||||
$resultSet = $query->execute(array(), constant($hydrationMode));
|
||||
|
||||
$output->writeln(Debug::dump($resultSet, $input->getOption('depth'), true, false));
|
||||
}
|
||||
}
|
||||
71
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/AbstractCommand.php
vendored
Normal file
71
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/AbstractCommand.php
vendored
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
<?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\ORM\Tools\Console\Command\SchemaTool;
|
||||
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Doctrine\ORM\Tools\SchemaTool;
|
||||
|
||||
/**
|
||||
* Base class for CreateCommand, DropCommand and UpdateCommand.
|
||||
*
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
abstract class AbstractCommand extends Command
|
||||
{
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
* @param SchemaTool $schemaTool
|
||||
* @param array $metadatas
|
||||
*
|
||||
* @return null|int Null or 0 if everything went fine, or an error code.
|
||||
*/
|
||||
abstract protected function executeSchemaCommand(InputInterface $input, OutputInterface $output, SchemaTool $schemaTool, array $metadatas);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$emHelper = $this->getHelper('em');
|
||||
|
||||
/* @var $em \Doctrine\ORM\EntityManager */
|
||||
$em = $emHelper->getEntityManager();
|
||||
|
||||
$metadatas = $em->getMetadataFactory()->getAllMetadata();
|
||||
|
||||
if ( ! empty($metadatas)) {
|
||||
// Create SchemaTool
|
||||
$tool = new SchemaTool($em);
|
||||
|
||||
return $this->executeSchemaCommand($input, $output, $tool, $metadatas);
|
||||
} else {
|
||||
$output->writeln('No Metadata Classes to process.');
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
85
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/CreateCommand.php
vendored
Normal file
85
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/CreateCommand.php
vendored
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
<?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\ORM\Tools\Console\Command\SchemaTool;
|
||||
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Doctrine\ORM\Tools\SchemaTool;
|
||||
|
||||
/**
|
||||
* Command to create the database schema for a set of classes based on their mappings.
|
||||
*
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
class CreateCommand extends AbstractCommand
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setName('orm:schema-tool:create')
|
||||
->setDescription(
|
||||
'Processes the schema and either create it directly on EntityManager Storage Connection or generate the SQL output.'
|
||||
)
|
||||
->setDefinition(array(
|
||||
new InputOption(
|
||||
'dump-sql', null, InputOption::VALUE_NONE,
|
||||
'Instead of trying to apply generated SQLs into EntityManager Storage Connection, output them.'
|
||||
)
|
||||
))
|
||||
->setHelp(<<<EOT
|
||||
Processes the schema and either create it directly on EntityManager Storage Connection or generate the SQL output.
|
||||
|
||||
<comment>Hint:</comment> If you have a database with tables that should not be managed
|
||||
by the ORM, you can use a DBAL functionality to filter the tables and sequences down
|
||||
on a global level:
|
||||
|
||||
\$config->setFilterSchemaAssetsExpression(\$regexp);
|
||||
EOT
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function executeSchemaCommand(InputInterface $input, OutputInterface $output, SchemaTool $schemaTool, array $metadatas)
|
||||
{
|
||||
if ($input->getOption('dump-sql')) {
|
||||
$sqls = $schemaTool->getCreateSchemaSql($metadatas);
|
||||
$output->writeln(implode(';' . PHP_EOL, $sqls) . ';');
|
||||
} else {
|
||||
$output->writeln('ATTENTION: This operation should not be executed in a production environment.' . PHP_EOL);
|
||||
|
||||
$output->writeln('Creating database schema...');
|
||||
$schemaTool->createSchema($metadatas);
|
||||
$output->writeln('Database schema created successfully!');
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
130
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/DropCommand.php
vendored
Normal file
130
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/DropCommand.php
vendored
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
<?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\ORM\Tools\Console\Command\SchemaTool;
|
||||
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Doctrine\ORM\Tools\SchemaTool;
|
||||
|
||||
/**
|
||||
* Command to drop the database schema for a set of classes based on their mappings.
|
||||
*
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
class DropCommand extends AbstractCommand
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setName('orm:schema-tool:drop')
|
||||
->setDescription(
|
||||
'Drop the complete database schema of EntityManager Storage Connection or generate the corresponding SQL output.'
|
||||
)
|
||||
->setDefinition(array(
|
||||
new InputOption(
|
||||
'dump-sql', null, InputOption::VALUE_NONE,
|
||||
'Instead of trying to apply generated SQLs into EntityManager Storage Connection, output them.'
|
||||
),
|
||||
new InputOption(
|
||||
'force', 'f', InputOption::VALUE_NONE,
|
||||
"Don't ask for the deletion of the database, but force the operation to run."
|
||||
),
|
||||
new InputOption(
|
||||
'full-database', null, InputOption::VALUE_NONE,
|
||||
'Instead of using the Class Metadata to detect the database table schema, drop ALL assets that the database contains.'
|
||||
),
|
||||
))
|
||||
->setHelp(<<<EOT
|
||||
Processes the schema and either drop the database schema of EntityManager Storage Connection or generate the SQL output.
|
||||
Beware that the complete database is dropped by this command, even tables that are not relevant to your metadata model.
|
||||
|
||||
<comment>Hint:</comment> If you have a database with tables that should not be managed
|
||||
by the ORM, you can use a DBAL functionality to filter the tables and sequences down
|
||||
on a global level:
|
||||
|
||||
\$config->setFilterSchemaAssetsExpression(\$regexp);
|
||||
EOT
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function executeSchemaCommand(InputInterface $input, OutputInterface $output, SchemaTool $schemaTool, array $metadatas)
|
||||
{
|
||||
$isFullDatabaseDrop = $input->getOption('full-database');
|
||||
|
||||
if ($input->getOption('dump-sql')) {
|
||||
if ($isFullDatabaseDrop) {
|
||||
$sqls = $schemaTool->getDropDatabaseSQL();
|
||||
} else {
|
||||
$sqls = $schemaTool->getDropSchemaSQL($metadatas);
|
||||
}
|
||||
$output->writeln(implode(';' . PHP_EOL, $sqls));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ($input->getOption('force')) {
|
||||
$output->writeln('Dropping database schema...');
|
||||
|
||||
if ($isFullDatabaseDrop) {
|
||||
$schemaTool->dropDatabase();
|
||||
} else {
|
||||
$schemaTool->dropSchema($metadatas);
|
||||
}
|
||||
|
||||
$output->writeln('Database schema dropped successfully!');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
$output->writeln('<comment>ATTENTION</comment>: This operation should not be executed in a production environment.' . PHP_EOL);
|
||||
|
||||
if ($isFullDatabaseDrop) {
|
||||
$sqls = $schemaTool->getDropDatabaseSQL();
|
||||
} else {
|
||||
$sqls = $schemaTool->getDropSchemaSQL($metadatas);
|
||||
}
|
||||
|
||||
if (count($sqls)) {
|
||||
$output->writeln(sprintf('The Schema-Tool would execute <info>"%s"</info> queries to update the database.', count($sqls)));
|
||||
$output->writeln('Please run the operation by passing one - or both - of the following options:');
|
||||
|
||||
$output->writeln(sprintf(' <info>%s --force</info> to execute the command', $this->getName()));
|
||||
$output->writeln(sprintf(' <info>%s --dump-sql</info> to dump the SQL statements to the screen', $this->getName()));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
$output->writeln('Nothing to drop. The database is empty!');
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
157
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/UpdateCommand.php
vendored
Normal file
157
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/UpdateCommand.php
vendored
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
<?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\ORM\Tools\Console\Command\SchemaTool;
|
||||
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Doctrine\ORM\Tools\SchemaTool;
|
||||
|
||||
/**
|
||||
* Command to generate the SQL needed to update the database schema to match
|
||||
* the current mapping information.
|
||||
*
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @author Ryan Weaver <ryan@thatsquality.com>
|
||||
*/
|
||||
class UpdateCommand extends AbstractCommand
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $name = 'orm:schema-tool:update';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setName($this->name)
|
||||
->setDescription(
|
||||
'Executes (or dumps) the SQL needed to update the database schema to match the current mapping metadata.'
|
||||
)
|
||||
->setDefinition(array(
|
||||
new InputOption(
|
||||
'complete', null, InputOption::VALUE_NONE,
|
||||
'If defined, all assets of the database which are not relevant to the current metadata will be dropped.'
|
||||
),
|
||||
|
||||
new InputOption(
|
||||
'dump-sql', null, InputOption::VALUE_NONE,
|
||||
'Dumps the generated SQL statements to the screen (does not execute them).'
|
||||
),
|
||||
new InputOption(
|
||||
'force', 'f', InputOption::VALUE_NONE,
|
||||
'Causes the generated SQL statements to be physically executed against your database.'
|
||||
),
|
||||
));
|
||||
|
||||
$this->setHelp(<<<EOT
|
||||
The <info>%command.name%</info> command generates the SQL needed to
|
||||
synchronize the database schema with the current mapping metadata of the
|
||||
default entity manager.
|
||||
|
||||
For example, if you add metadata for a new column to an entity, this command
|
||||
would generate and output the SQL needed to add the new column to the database:
|
||||
|
||||
<info>%command.name% --dump-sql</info>
|
||||
|
||||
Alternatively, you can execute the generated queries:
|
||||
|
||||
<info>%command.name% --force</info>
|
||||
|
||||
If both options are specified, the queries are output and then executed:
|
||||
|
||||
<info>%command.name% --dump-sql --force</info>
|
||||
|
||||
Finally, be aware that if the <info>--complete</info> option is passed, this
|
||||
task will drop all database assets (e.g. tables, etc) that are *not* described
|
||||
by the current metadata. In other words, without this option, this task leaves
|
||||
untouched any "extra" tables that exist in the database, but which aren't
|
||||
described by any metadata.
|
||||
|
||||
<comment>Hint:</comment> If you have a database with tables that should not be managed
|
||||
by the ORM, you can use a DBAL functionality to filter the tables and sequences down
|
||||
on a global level:
|
||||
|
||||
\$config->setFilterSchemaAssetsExpression(\$regexp);
|
||||
EOT
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function executeSchemaCommand(InputInterface $input, OutputInterface $output, SchemaTool $schemaTool, array $metadatas)
|
||||
{
|
||||
// Defining if update is complete or not (--complete not defined means $saveMode = true)
|
||||
$saveMode = ! $input->getOption('complete');
|
||||
|
||||
$sqls = $schemaTool->getUpdateSchemaSql($metadatas, $saveMode);
|
||||
|
||||
if (0 === count($sqls)) {
|
||||
$output->writeln('Nothing to update - your database is already in sync with the current entity metadata.');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
$dumpSql = true === $input->getOption('dump-sql');
|
||||
$force = true === $input->getOption('force');
|
||||
|
||||
if ($dumpSql) {
|
||||
$output->writeln(implode(';' . PHP_EOL, $sqls) . ';');
|
||||
}
|
||||
|
||||
if ($force) {
|
||||
if ($dumpSql) {
|
||||
$output->writeln('');
|
||||
}
|
||||
$output->writeln('Updating database schema...');
|
||||
$schemaTool->updateSchema($metadatas, $saveMode);
|
||||
|
||||
$pluralization = (1 === count($sqls)) ? 'query was' : 'queries were';
|
||||
|
||||
$output->writeln(sprintf('Database schema updated successfully! "<info>%s</info>" %s executed', count($sqls), $pluralization));
|
||||
}
|
||||
|
||||
if ($dumpSql || $force) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$output->writeln('<comment>ATTENTION</comment>: This operation should not be executed in a production environment.');
|
||||
$output->writeln(' Use the incremental update to detect changes during development and use');
|
||||
$output->writeln(' the SQL DDL provided to manually update your database in production.');
|
||||
$output->writeln('');
|
||||
|
||||
$output->writeln(sprintf('The Schema-Tool would execute <info>"%s"</info> queries to update the database.', count($sqls)));
|
||||
$output->writeln('Please run the operation by passing one - or both - of the following options:');
|
||||
|
||||
$output->writeln(sprintf(' <info>%s --force</info> to execute the command', $this->getName()));
|
||||
$output->writeln(sprintf(' <info>%s --dump-sql</info> to dump the SQL statements to the screen', $this->getName()));
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
106
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/ValidateSchemaCommand.php
vendored
Normal file
106
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Command/ValidateSchemaCommand.php
vendored
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
<?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\ORM\Tools\Console\Command;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Doctrine\ORM\Tools\SchemaValidator;
|
||||
|
||||
/**
|
||||
* Command to validate that the current mapping is valid.
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT
|
||||
* @link www.doctrine-project.com
|
||||
* @since 1.0
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
class ValidateSchemaCommand extends Command
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setName('orm:validate-schema')
|
||||
->setDescription('Validate the mapping files.')
|
||||
->addOption(
|
||||
'skip-mapping',
|
||||
null,
|
||||
InputOption::VALUE_NONE,
|
||||
'Skip the mapping validation check'
|
||||
)
|
||||
->addOption(
|
||||
'skip-sync',
|
||||
null,
|
||||
InputOption::VALUE_NONE,
|
||||
'Skip checking if the mapping is in sync with the database'
|
||||
)
|
||||
->setHelp(
|
||||
<<<EOT
|
||||
'Validate that the mapping files are correct and in sync with the database.'
|
||||
EOT
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$em = $this->getHelper('em')->getEntityManager();
|
||||
$validator = new SchemaValidator($em);
|
||||
$exit = 0;
|
||||
|
||||
if ($input->getOption('skip-mapping')) {
|
||||
$output->writeln('<comment>[Mapping] Skipped mapping check.</comment>');
|
||||
} elseif ($errors = $validator->validateMapping()) {
|
||||
foreach ($errors as $className => $errorMessages) {
|
||||
$output->writeln("<error>[Mapping] FAIL - The entity-class '" . $className . "' mapping is invalid:</error>");
|
||||
|
||||
foreach ($errorMessages as $errorMessage) {
|
||||
$output->writeln('* ' . $errorMessage);
|
||||
}
|
||||
|
||||
$output->writeln('');
|
||||
}
|
||||
|
||||
$exit += 1;
|
||||
} else {
|
||||
$output->writeln('<info>[Mapping] OK - The mapping files are correct.</info>');
|
||||
}
|
||||
|
||||
if ($input->getOption('skip-sync')) {
|
||||
$output->writeln('<comment>[Database] SKIPPED - The database was not checked for synchronicity.</comment>');
|
||||
} elseif (!$validator->schemaInSyncWithMetadata()) {
|
||||
$output->writeln('<error>[Database] FAIL - The database schema is not in sync with the current mapping file.</error>');
|
||||
$exit += 2;
|
||||
} else {
|
||||
$output->writeln('<info>[Database] OK - The database schema is in sync with the mapping files.</info>');
|
||||
}
|
||||
|
||||
return $exit;
|
||||
}
|
||||
}
|
||||
136
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/ConsoleRunner.php
vendored
Normal file
136
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/ConsoleRunner.php
vendored
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
<?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\ORM\Tools\Console;
|
||||
|
||||
use Symfony\Component\Console\Application;
|
||||
use Symfony\Component\Console\Helper\HelperSet;
|
||||
use Doctrine\ORM\Version;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
|
||||
use Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper;
|
||||
use Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper;
|
||||
|
||||
/**
|
||||
* Handles running the Console Tools inside Symfony Console context.
|
||||
*/
|
||||
class ConsoleRunner
|
||||
{
|
||||
/**
|
||||
* Create a Symfony Console HelperSet
|
||||
*
|
||||
* @param EntityManagerInterface $entityManager
|
||||
* @return HelperSet
|
||||
*/
|
||||
public static function createHelperSet(EntityManagerInterface $entityManager)
|
||||
{
|
||||
return new HelperSet(array(
|
||||
'db' => new ConnectionHelper($entityManager->getConnection()),
|
||||
'em' => new EntityManagerHelper($entityManager)
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs console with the given helperset.
|
||||
*
|
||||
* @param \Symfony\Component\Console\Helper\HelperSet $helperSet
|
||||
* @param \Symfony\Component\Console\Command\Command[] $commands
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
static public function run(HelperSet $helperSet, $commands = array())
|
||||
{
|
||||
$cli = self::createApplication($helperSet, $commands);
|
||||
$cli->run();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a console application with the given helperset and
|
||||
* optional commands.
|
||||
*
|
||||
* @param \Symfony\Component\Console\Helper\HelperSet $helperSet
|
||||
* @param array $commands
|
||||
*
|
||||
* @return \Symfony\Component\Console\Application
|
||||
*/
|
||||
static public function createApplication(HelperSet $helperSet, $commands = array())
|
||||
{
|
||||
$cli = new Application('Doctrine Command Line Interface', Version::VERSION);
|
||||
$cli->setCatchExceptions(true);
|
||||
$cli->setHelperSet($helperSet);
|
||||
self::addCommands($cli);
|
||||
$cli->addCommands($commands);
|
||||
|
||||
return $cli;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Application $cli
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
static public function addCommands(Application $cli)
|
||||
{
|
||||
$cli->addCommands(array(
|
||||
// DBAL Commands
|
||||
new \Doctrine\DBAL\Tools\Console\Command\RunSqlCommand(),
|
||||
new \Doctrine\DBAL\Tools\Console\Command\ImportCommand(),
|
||||
|
||||
// ORM Commands
|
||||
new \Doctrine\ORM\Tools\Console\Command\ClearCache\MetadataCommand(),
|
||||
new \Doctrine\ORM\Tools\Console\Command\ClearCache\ResultCommand(),
|
||||
new \Doctrine\ORM\Tools\Console\Command\ClearCache\QueryCommand(),
|
||||
new \Doctrine\ORM\Tools\Console\Command\SchemaTool\CreateCommand(),
|
||||
new \Doctrine\ORM\Tools\Console\Command\SchemaTool\UpdateCommand(),
|
||||
new \Doctrine\ORM\Tools\Console\Command\SchemaTool\DropCommand(),
|
||||
new \Doctrine\ORM\Tools\Console\Command\EnsureProductionSettingsCommand(),
|
||||
new \Doctrine\ORM\Tools\Console\Command\ConvertDoctrine1SchemaCommand(),
|
||||
new \Doctrine\ORM\Tools\Console\Command\GenerateRepositoriesCommand(),
|
||||
new \Doctrine\ORM\Tools\Console\Command\GenerateEntitiesCommand(),
|
||||
new \Doctrine\ORM\Tools\Console\Command\GenerateProxiesCommand(),
|
||||
new \Doctrine\ORM\Tools\Console\Command\ConvertMappingCommand(),
|
||||
new \Doctrine\ORM\Tools\Console\Command\RunDqlCommand(),
|
||||
new \Doctrine\ORM\Tools\Console\Command\ValidateSchemaCommand(),
|
||||
new \Doctrine\ORM\Tools\Console\Command\InfoCommand(),
|
||||
new \Doctrine\ORM\Tools\Console\Command\MappingDescribeCommand(),
|
||||
));
|
||||
}
|
||||
|
||||
static public function printCliConfigTemplate()
|
||||
{
|
||||
echo <<<'HELP'
|
||||
You are missing a "cli-config.php" or "config/cli-config.php" file in your
|
||||
project, which is required to get the Doctrine Console working. You can use the
|
||||
following sample as a template:
|
||||
|
||||
<?php
|
||||
use Doctrine\ORM\Tools\Console\ConsoleRunner;
|
||||
|
||||
// replace with file to your own project bootstrap
|
||||
require_once 'bootstrap.php';
|
||||
|
||||
// replace with mechanism to retrieve EntityManager in your app
|
||||
$entityManager = GetEntityManager();
|
||||
|
||||
return ConsoleRunner::createHelperSet($entityManager);
|
||||
|
||||
HELP;
|
||||
|
||||
}
|
||||
}
|
||||
72
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Helper/EntityManagerHelper.php
vendored
Normal file
72
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/Helper/EntityManagerHelper.php
vendored
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
<?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\ORM\Tools\Console\Helper;
|
||||
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Component\Console\Helper\Helper;
|
||||
|
||||
|
||||
/**
|
||||
* Doctrine CLI Connection Helper.
|
||||
*
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
class EntityManagerHelper extends Helper
|
||||
{
|
||||
/**
|
||||
* Doctrine ORM EntityManagerInterface.
|
||||
*
|
||||
* @var EntityManagerInterface
|
||||
*/
|
||||
protected $_em;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param EntityManagerInterface $em
|
||||
*/
|
||||
public function __construct(EntityManagerInterface $em)
|
||||
{
|
||||
$this->_em = $em;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves Doctrine ORM EntityManager.
|
||||
*
|
||||
* @return EntityManagerInterface
|
||||
*/
|
||||
public function getEntityManager()
|
||||
{
|
||||
return $this->_em;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'entityManager';
|
||||
}
|
||||
}
|
||||
102
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/MetadataFilter.php
vendored
Normal file
102
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Console/MetadataFilter.php
vendored
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
<?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\ORM\Tools\Console;
|
||||
|
||||
/**
|
||||
* Used by CLI Tools to restrict entity-based commands to given patterns.
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT
|
||||
* @link www.doctrine-project.com
|
||||
* @since 1.0
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
class MetadataFilter extends \FilterIterator implements \Countable
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $filter = array();
|
||||
|
||||
/**
|
||||
* Filter Metadatas by one or more filter options.
|
||||
*
|
||||
* @param array $metadatas
|
||||
* @param array|string $filter
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
static public function filter(array $metadatas, $filter)
|
||||
{
|
||||
$metadatas = new MetadataFilter(new \ArrayIterator($metadatas), $filter);
|
||||
|
||||
return iterator_to_array($metadatas);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \ArrayIterator $metadata
|
||||
* @param array|string $filter
|
||||
*/
|
||||
public function __construct(\ArrayIterator $metadata, $filter)
|
||||
{
|
||||
$this->filter = (array) $filter;
|
||||
|
||||
parent::__construct($metadata);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function accept()
|
||||
{
|
||||
if (count($this->filter) == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$it = $this->getInnerIterator();
|
||||
$metadata = $it->current();
|
||||
|
||||
foreach ($this->filter as $filter) {
|
||||
$pregResult = preg_match("/$filter/", $metadata->name);
|
||||
|
||||
if ($pregResult === false) {
|
||||
throw new \RuntimeException(
|
||||
sprintf("Error while evaluating regex '/%s/'.", $filter)
|
||||
);
|
||||
}
|
||||
|
||||
if ($pregResult) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return count($this->getInnerIterator());
|
||||
}
|
||||
}
|
||||
344
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/ConvertDoctrine1Schema.php
vendored
Normal file
344
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/ConvertDoctrine1Schema.php
vendored
Normal file
|
|
@ -0,0 +1,344 @@
|
|||
<?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\ORM\Tools;
|
||||
|
||||
use Doctrine\ORM\Mapping\ClassMetadataInfo;
|
||||
use Doctrine\Common\Util\Inflector;
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
|
||||
/**
|
||||
* Class to help with converting Doctrine 1 schema files to Doctrine 2 mapping files
|
||||
*
|
||||
*
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
class ConvertDoctrine1Schema
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $from;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $legacyTypeMap = array(
|
||||
// TODO: This list may need to be updated
|
||||
'clob' => 'text',
|
||||
'timestamp' => 'datetime',
|
||||
'enum' => 'string'
|
||||
);
|
||||
|
||||
/**
|
||||
* Constructor passes the directory or array of directories
|
||||
* to convert the Doctrine 1 schema files from.
|
||||
*
|
||||
* @param array $from
|
||||
*
|
||||
* @author Jonathan Wage
|
||||
*/
|
||||
public function __construct($from)
|
||||
{
|
||||
$this->from = (array) $from;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an array of ClassMetadataInfo instances from the passed
|
||||
* Doctrine 1 schema.
|
||||
*
|
||||
* @return array An array of ClassMetadataInfo instances
|
||||
*/
|
||||
public function getMetadata()
|
||||
{
|
||||
$schema = array();
|
||||
foreach ($this->from as $path) {
|
||||
if (is_dir($path)) {
|
||||
$files = glob($path . '/*.yml');
|
||||
foreach ($files as $file) {
|
||||
$schema = array_merge($schema, (array) Yaml::parse(file_get_contents($file)));
|
||||
}
|
||||
} else {
|
||||
$schema = array_merge($schema, (array) Yaml::parse(file_get_contents($path)));
|
||||
}
|
||||
}
|
||||
|
||||
$metadatas = array();
|
||||
foreach ($schema as $className => $mappingInformation) {
|
||||
$metadatas[] = $this->convertToClassMetadataInfo($className, $mappingInformation);
|
||||
}
|
||||
|
||||
return $metadatas;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $className
|
||||
* @param array $mappingInformation
|
||||
*
|
||||
* @return \Doctrine\ORM\Mapping\ClassMetadataInfo
|
||||
*/
|
||||
private function convertToClassMetadataInfo($className, $mappingInformation)
|
||||
{
|
||||
$metadata = new ClassMetadataInfo($className);
|
||||
|
||||
$this->convertTableName($className, $mappingInformation, $metadata);
|
||||
$this->convertColumns($className, $mappingInformation, $metadata);
|
||||
$this->convertIndexes($className, $mappingInformation, $metadata);
|
||||
$this->convertRelations($className, $mappingInformation, $metadata);
|
||||
|
||||
return $metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $className
|
||||
* @param array $model
|
||||
* @param ClassMetadataInfo $metadata
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function convertTableName($className, array $model, ClassMetadataInfo $metadata)
|
||||
{
|
||||
if (isset($model['tableName']) && $model['tableName']) {
|
||||
$e = explode('.', $model['tableName']);
|
||||
|
||||
if (count($e) > 1) {
|
||||
$metadata->table['schema'] = $e[0];
|
||||
$metadata->table['name'] = $e[1];
|
||||
} else {
|
||||
$metadata->table['name'] = $e[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $className
|
||||
* @param array $model
|
||||
* @param ClassMetadataInfo $metadata
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function convertColumns($className, array $model, ClassMetadataInfo $metadata)
|
||||
{
|
||||
$id = false;
|
||||
|
||||
if (isset($model['columns']) && $model['columns']) {
|
||||
foreach ($model['columns'] as $name => $column) {
|
||||
$fieldMapping = $this->convertColumn($className, $name, $column, $metadata);
|
||||
|
||||
if (isset($fieldMapping['id']) && $fieldMapping['id']) {
|
||||
$id = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $id) {
|
||||
$fieldMapping = array(
|
||||
'fieldName' => 'id',
|
||||
'columnName' => 'id',
|
||||
'type' => 'integer',
|
||||
'id' => true
|
||||
);
|
||||
$metadata->mapField($fieldMapping);
|
||||
$metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $className
|
||||
* @param string $name
|
||||
* @param string|array $column
|
||||
* @param ClassMetadataInfo $metadata
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws ToolsException
|
||||
*/
|
||||
private function convertColumn($className, $name, $column, ClassMetadataInfo $metadata)
|
||||
{
|
||||
if (is_string($column)) {
|
||||
$string = $column;
|
||||
$column = array();
|
||||
$column['type'] = $string;
|
||||
}
|
||||
|
||||
if ( ! isset($column['name'])) {
|
||||
$column['name'] = $name;
|
||||
}
|
||||
|
||||
// check if a column alias was used (column_name as field_name)
|
||||
if (preg_match("/(\w+)\sas\s(\w+)/i", $column['name'], $matches)) {
|
||||
$name = $matches[1];
|
||||
$column['name'] = $name;
|
||||
$column['alias'] = $matches[2];
|
||||
}
|
||||
|
||||
if (preg_match("/([a-zA-Z]+)\(([0-9]+)\)/", $column['type'], $matches)) {
|
||||
$column['type'] = $matches[1];
|
||||
$column['length'] = $matches[2];
|
||||
}
|
||||
|
||||
$column['type'] = strtolower($column['type']);
|
||||
// check if legacy column type (1.x) needs to be mapped to a 2.0 one
|
||||
if (isset($this->legacyTypeMap[$column['type']])) {
|
||||
$column['type'] = $this->legacyTypeMap[$column['type']];
|
||||
}
|
||||
|
||||
if ( ! Type::hasType($column['type'])) {
|
||||
throw ToolsException::couldNotMapDoctrine1Type($column['type']);
|
||||
}
|
||||
|
||||
$fieldMapping = array();
|
||||
|
||||
if (isset($column['primary'])) {
|
||||
$fieldMapping['id'] = true;
|
||||
}
|
||||
|
||||
$fieldMapping['fieldName'] = isset($column['alias']) ? $column['alias'] : $name;
|
||||
$fieldMapping['columnName'] = $column['name'];
|
||||
$fieldMapping['type'] = $column['type'];
|
||||
|
||||
if (isset($column['length'])) {
|
||||
$fieldMapping['length'] = $column['length'];
|
||||
}
|
||||
|
||||
$allowed = array('precision', 'scale', 'unique', 'options', 'notnull', 'version');
|
||||
|
||||
foreach ($column as $key => $value) {
|
||||
if (in_array($key, $allowed)) {
|
||||
$fieldMapping[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
$metadata->mapField($fieldMapping);
|
||||
|
||||
if (isset($column['autoincrement'])) {
|
||||
$metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO);
|
||||
} elseif (isset($column['sequence'])) {
|
||||
$metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_SEQUENCE);
|
||||
|
||||
$definition = array(
|
||||
'sequenceName' => is_array($column['sequence']) ? $column['sequence']['name']:$column['sequence']
|
||||
);
|
||||
|
||||
if (isset($column['sequence']['size'])) {
|
||||
$definition['allocationSize'] = $column['sequence']['size'];
|
||||
}
|
||||
|
||||
if (isset($column['sequence']['value'])) {
|
||||
$definition['initialValue'] = $column['sequence']['value'];
|
||||
}
|
||||
|
||||
$metadata->setSequenceGeneratorDefinition($definition);
|
||||
}
|
||||
|
||||
return $fieldMapping;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $className
|
||||
* @param array $model
|
||||
* @param ClassMetadataInfo $metadata
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function convertIndexes($className, array $model, ClassMetadataInfo $metadata)
|
||||
{
|
||||
if (empty($model['indexes'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($model['indexes'] as $name => $index) {
|
||||
$type = (isset($index['type']) && $index['type'] == 'unique')
|
||||
? 'uniqueConstraints' : 'indexes';
|
||||
|
||||
$metadata->table[$type][$name] = array(
|
||||
'columns' => $index['fields']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $className
|
||||
* @param array $model
|
||||
* @param ClassMetadataInfo $metadata
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function convertRelations($className, array $model, ClassMetadataInfo $metadata)
|
||||
{
|
||||
if (empty($model['relations'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($model['relations'] as $name => $relation) {
|
||||
if ( ! isset($relation['alias'])) {
|
||||
$relation['alias'] = $name;
|
||||
}
|
||||
if ( ! isset($relation['class'])) {
|
||||
$relation['class'] = $name;
|
||||
}
|
||||
if ( ! isset($relation['local'])) {
|
||||
$relation['local'] = Inflector::tableize($relation['class']);
|
||||
}
|
||||
if ( ! isset($relation['foreign'])) {
|
||||
$relation['foreign'] = 'id';
|
||||
}
|
||||
if ( ! isset($relation['foreignAlias'])) {
|
||||
$relation['foreignAlias'] = $className;
|
||||
}
|
||||
|
||||
if (isset($relation['refClass'])) {
|
||||
$type = 'many';
|
||||
$foreignType = 'many';
|
||||
$joinColumns = array();
|
||||
} else {
|
||||
$type = isset($relation['type']) ? $relation['type'] : 'one';
|
||||
$foreignType = isset($relation['foreignType']) ? $relation['foreignType'] : 'many';
|
||||
$joinColumns = array(
|
||||
array(
|
||||
'name' => $relation['local'],
|
||||
'referencedColumnName' => $relation['foreign'],
|
||||
'onDelete' => isset($relation['onDelete']) ? $relation['onDelete'] : null,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ($type == 'one' && $foreignType == 'one') {
|
||||
$method = 'mapOneToOne';
|
||||
} elseif ($type == 'many' && $foreignType == 'many') {
|
||||
$method = 'mapManyToMany';
|
||||
} else {
|
||||
$method = 'mapOneToMany';
|
||||
}
|
||||
|
||||
$associationMapping = array();
|
||||
$associationMapping['fieldName'] = $relation['alias'];
|
||||
$associationMapping['targetEntity'] = $relation['class'];
|
||||
$associationMapping['mappedBy'] = $relation['foreignAlias'];
|
||||
$associationMapping['joinColumns'] = $joinColumns;
|
||||
|
||||
$metadata->$method($associationMapping);
|
||||
}
|
||||
}
|
||||
}
|
||||
184
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/DebugUnitOfWorkListener.php
vendored
Normal file
184
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/DebugUnitOfWorkListener.php
vendored
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
<?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\ORM\Tools;
|
||||
|
||||
use Doctrine\Common\Persistence\Proxy;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\Event\OnFlushEventArgs;
|
||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||
use Doctrine\ORM\PersistentCollection;
|
||||
use Doctrine\ORM\UnitOfWork;
|
||||
|
||||
/**
|
||||
* Use this logger to dump the identity map during the onFlush event. This is useful for debugging
|
||||
* weird UnitOfWork behavior with complex operations.
|
||||
*/
|
||||
class DebugUnitOfWorkListener
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $file;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $context;
|
||||
|
||||
/**
|
||||
* Pass a stream and context information for the debugging session.
|
||||
*
|
||||
* The stream can be php://output to print to the screen.
|
||||
*
|
||||
* @param string $file
|
||||
* @param string $context
|
||||
*/
|
||||
public function __construct($file = 'php://output', $context = '')
|
||||
{
|
||||
$this->file = $file;
|
||||
$this->context = $context;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Doctrine\ORM\Event\OnFlushEventArgs $args
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function onFlush(OnFlushEventArgs $args)
|
||||
{
|
||||
$this->dumpIdentityMap($args->getEntityManager());
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps the contents of the identity map into a stream.
|
||||
*
|
||||
* @param EntityManagerInterface $em
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function dumpIdentityMap(EntityManagerInterface $em)
|
||||
{
|
||||
$uow = $em->getUnitOfWork();
|
||||
$identityMap = $uow->getIdentityMap();
|
||||
|
||||
$fh = fopen($this->file, "x+");
|
||||
if (count($identityMap) == 0) {
|
||||
fwrite($fh, "Flush Operation [".$this->context."] - Empty identity map.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
fwrite($fh, "Flush Operation [".$this->context."] - Dumping identity map:\n");
|
||||
foreach ($identityMap as $className => $map) {
|
||||
fwrite($fh, "Class: ". $className . "\n");
|
||||
|
||||
foreach ($map as $entity) {
|
||||
fwrite($fh, " Entity: " . $this->getIdString($entity, $uow) . " " . spl_object_hash($entity)."\n");
|
||||
fwrite($fh, " Associations:\n");
|
||||
|
||||
$cm = $em->getClassMetadata($className);
|
||||
|
||||
foreach ($cm->associationMappings as $field => $assoc) {
|
||||
fwrite($fh, " " . $field . " ");
|
||||
$value = $cm->getFieldValue($entity, $field);
|
||||
|
||||
if ($assoc['type'] & ClassMetadata::TO_ONE) {
|
||||
if ($value === null) {
|
||||
fwrite($fh, " NULL\n");
|
||||
} else {
|
||||
if ($value instanceof Proxy && !$value->__isInitialized()) {
|
||||
fwrite($fh, "[PROXY] ");
|
||||
}
|
||||
|
||||
fwrite($fh, $this->getIdString($value, $uow) . " " . spl_object_hash($value) . "\n");
|
||||
}
|
||||
} else {
|
||||
$initialized = !($value instanceof PersistentCollection) || $value->isInitialized();
|
||||
if ($value === null) {
|
||||
fwrite($fh, " NULL\n");
|
||||
} elseif ($initialized) {
|
||||
fwrite($fh, "[INITIALIZED] " . $this->getType($value). " " . count($value) . " elements\n");
|
||||
|
||||
foreach ($value as $obj) {
|
||||
fwrite($fh, " " . $this->getIdString($obj, $uow) . " " . spl_object_hash($obj)."\n");
|
||||
}
|
||||
} else {
|
||||
fwrite($fh, "[PROXY] " . $this->getType($value) . " unknown element size\n");
|
||||
foreach ($value->unwrap() as $obj) {
|
||||
fwrite($fh, " " . $this->getIdString($obj, $uow) . " " . spl_object_hash($obj)."\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose($fh);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $var
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getType($var)
|
||||
{
|
||||
if (is_object($var)) {
|
||||
$refl = new \ReflectionObject($var);
|
||||
|
||||
return $refl->getShortname();
|
||||
}
|
||||
|
||||
return gettype($var);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param object $entity
|
||||
* @param UnitOfWork $uow
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getIdString($entity, UnitOfWork $uow)
|
||||
{
|
||||
if ($uow->isInIdentityMap($entity)) {
|
||||
$ids = $uow->getEntityIdentifier($entity);
|
||||
$idstring = "";
|
||||
|
||||
foreach ($ids as $k => $v) {
|
||||
$idstring .= $k."=".$v;
|
||||
}
|
||||
} else {
|
||||
$idstring = "NEWOBJECT ";
|
||||
}
|
||||
|
||||
$state = $uow->getEntityState($entity);
|
||||
|
||||
if ($state == UnitOfWork::STATE_NEW) {
|
||||
$idstring .= " [NEW]";
|
||||
} elseif ($state == UnitOfWork::STATE_REMOVED) {
|
||||
$idstring .= " [REMOVED]";
|
||||
} elseif ($state == UnitOfWork::STATE_MANAGED) {
|
||||
$idstring .= " [MANAGED]";
|
||||
} elseif ($state == UnitOfwork::STATE_DETACHED) {
|
||||
$idstring .= " [DETACHED]";
|
||||
}
|
||||
|
||||
return $idstring;
|
||||
}
|
||||
}
|
||||
48
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/DisconnectedClassMetadataFactory.php
vendored
Normal file
48
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/DisconnectedClassMetadataFactory.php
vendored
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
<?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\ORM\Tools;
|
||||
|
||||
use Doctrine\Common\Persistence\Mapping\StaticReflectionService;
|
||||
use Doctrine\ORM\Mapping\ClassMetadataFactory;
|
||||
|
||||
/**
|
||||
* The DisconnectedClassMetadataFactory is used to create ClassMetadataInfo objects
|
||||
* that do not require the entity class actually exist. This allows us to
|
||||
* load some mapping information and use it to do things like generate code
|
||||
* from the mapping information.
|
||||
*
|
||||
*
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
class DisconnectedClassMetadataFactory extends ClassMetadataFactory
|
||||
{
|
||||
/**
|
||||
* @return \Doctrine\Common\Persistence\Mapping\StaticReflectionService
|
||||
*/
|
||||
public function getReflectionService()
|
||||
{
|
||||
return new StaticReflectionService();
|
||||
}
|
||||
}
|
||||
1819
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/EntityGenerator.php
vendored
Normal file
1819
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/EntityGenerator.php
vendored
Normal file
File diff suppressed because it is too large
Load diff
171
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/EntityRepositoryGenerator.php
vendored
Normal file
171
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/EntityRepositoryGenerator.php
vendored
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
<?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\ORM\Tools;
|
||||
|
||||
/**
|
||||
* Class to generate entity repository classes
|
||||
*
|
||||
*
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
class EntityRepositoryGenerator
|
||||
{
|
||||
private $repositoryName;
|
||||
|
||||
protected static $_template =
|
||||
'<?php
|
||||
|
||||
<namespace>
|
||||
|
||||
/**
|
||||
* <className>
|
||||
*
|
||||
* This class was generated by the Doctrine ORM. Add your own custom
|
||||
* repository methods below.
|
||||
*/
|
||||
class <className> extends <repositoryName>
|
||||
{
|
||||
}
|
||||
';
|
||||
|
||||
/**
|
||||
* @param string $fullClassName
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function generateEntityRepositoryClass($fullClassName)
|
||||
{
|
||||
$variables = array(
|
||||
'<namespace>' => $this->generateEntityRepositoryNamespace($fullClassName),
|
||||
'<repositoryName>' => $this->generateEntityRepositoryName($fullClassName),
|
||||
'<className>' => $this->generateClassName($fullClassName)
|
||||
);
|
||||
|
||||
return str_replace(array_keys($variables), array_values($variables), self::$_template);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the namespace, if class do not have namespace, return empty string instead.
|
||||
*
|
||||
* @param string $fullClassName
|
||||
*
|
||||
* @return string $namespace
|
||||
*/
|
||||
private function getClassNamespace($fullClassName)
|
||||
{
|
||||
$namespace = substr($fullClassName, 0, strrpos($fullClassName, '\\'));
|
||||
|
||||
return $namespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the class name
|
||||
*
|
||||
* @param string $fullClassName
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function generateClassName($fullClassName)
|
||||
{
|
||||
$namespace = $this->getClassNamespace($fullClassName);
|
||||
|
||||
$className = $fullClassName;
|
||||
|
||||
if ($namespace) {
|
||||
$className = substr($fullClassName, strrpos($fullClassName, '\\') + 1, strlen($fullClassName));
|
||||
}
|
||||
|
||||
return $className;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the namespace statement, if class do not have namespace, return empty string instead.
|
||||
*
|
||||
* @param string $fullClassName The full repository class name.
|
||||
*
|
||||
* @return string $namespace
|
||||
*/
|
||||
private function generateEntityRepositoryNamespace($fullClassName)
|
||||
{
|
||||
$namespace = $this->getClassNamespace($fullClassName);
|
||||
|
||||
return $namespace ? 'namespace ' . $namespace . ';' : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fullClassName
|
||||
*
|
||||
* @return string $repositoryName
|
||||
*/
|
||||
private function generateEntityRepositoryName($fullClassName)
|
||||
{
|
||||
$namespace = $this->getClassNamespace($fullClassName);
|
||||
|
||||
$repositoryName = $this->repositoryName ?: 'Doctrine\ORM\EntityRepository';
|
||||
|
||||
if ($namespace && $repositoryName[0] !== '\\') {
|
||||
$repositoryName = '\\' . $repositoryName;
|
||||
}
|
||||
|
||||
return $repositoryName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fullClassName
|
||||
* @param string $outputDirectory
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function writeEntityRepositoryClass($fullClassName, $outputDirectory)
|
||||
{
|
||||
$code = $this->generateEntityRepositoryClass($fullClassName);
|
||||
|
||||
$path = $outputDirectory . DIRECTORY_SEPARATOR
|
||||
. str_replace('\\', \DIRECTORY_SEPARATOR, $fullClassName) . '.php';
|
||||
$dir = dirname($path);
|
||||
|
||||
if ( ! is_dir($dir)) {
|
||||
mkdir($dir, 0775, true);
|
||||
}
|
||||
|
||||
if ( ! file_exists($path)) {
|
||||
file_put_contents($path, $code);
|
||||
chmod($path, 0664);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $repositoryName
|
||||
*
|
||||
* @return \Doctrine\ORM\Tools\EntityRepositoryGenerator
|
||||
*/
|
||||
public function setDefaultRepositoryName($repositoryName)
|
||||
{
|
||||
$this->repositoryName = $repositoryName;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
||||
71
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Event/GenerateSchemaEventArgs.php
vendored
Normal file
71
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Event/GenerateSchemaEventArgs.php
vendored
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
<?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\ORM\Tools\Event;
|
||||
|
||||
use Doctrine\Common\EventArgs;
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
|
||||
/**
|
||||
* Event Args used for the Events::postGenerateSchema event.
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT
|
||||
* @link www.doctrine-project.com
|
||||
* @since 1.0
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
*/
|
||||
class GenerateSchemaEventArgs extends EventArgs
|
||||
{
|
||||
/**
|
||||
* @var \Doctrine\ORM\EntityManagerInterface
|
||||
*/
|
||||
private $em;
|
||||
|
||||
/**
|
||||
* @var \Doctrine\DBAL\Schema\Schema
|
||||
*/
|
||||
private $schema;
|
||||
|
||||
/**
|
||||
* @param EntityManagerInterface $em
|
||||
* @param Schema $schema
|
||||
*/
|
||||
public function __construct(EntityManagerInterface $em, Schema $schema)
|
||||
{
|
||||
$this->em = $em;
|
||||
$this->schema = $schema;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return EntityManagerInterface
|
||||
*/
|
||||
public function getEntityManager()
|
||||
{
|
||||
return $this->em;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Schema
|
||||
*/
|
||||
public function getSchema()
|
||||
{
|
||||
return $this->schema;
|
||||
}
|
||||
}
|
||||
86
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Event/GenerateSchemaTableEventArgs.php
vendored
Normal file
86
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Event/GenerateSchemaTableEventArgs.php
vendored
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
<?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\ORM\Tools\Event;
|
||||
|
||||
use Doctrine\Common\EventArgs;
|
||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\DBAL\Schema\Table;
|
||||
|
||||
/**
|
||||
* Event Args used for the Events::postGenerateSchemaTable event.
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT
|
||||
* @link www.doctrine-project.com
|
||||
* @since 1.0
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
*/
|
||||
class GenerateSchemaTableEventArgs extends EventArgs
|
||||
{
|
||||
/**
|
||||
* @var \Doctrine\ORM\Mapping\ClassMetadata
|
||||
*/
|
||||
private $classMetadata;
|
||||
|
||||
/**
|
||||
* @var \Doctrine\DBAL\Schema\Schema
|
||||
*/
|
||||
private $schema;
|
||||
|
||||
/**
|
||||
* @var \Doctrine\DBAL\Schema\Table
|
||||
*/
|
||||
private $classTable;
|
||||
|
||||
/**
|
||||
* @param ClassMetadata $classMetadata
|
||||
* @param Schema $schema
|
||||
* @param Table $classTable
|
||||
*/
|
||||
public function __construct(ClassMetadata $classMetadata, Schema $schema, Table $classTable)
|
||||
{
|
||||
$this->classMetadata = $classMetadata;
|
||||
$this->schema = $schema;
|
||||
$this->classTable = $classTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ClassMetadata
|
||||
*/
|
||||
public function getClassMetadata()
|
||||
{
|
||||
return $this->classMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Schema
|
||||
*/
|
||||
public function getSchema()
|
||||
{
|
||||
return $this->schema;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Table
|
||||
*/
|
||||
public function getClassTable()
|
||||
{
|
||||
return $this->classTable;
|
||||
}
|
||||
}
|
||||
76
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Export/ClassMetadataExporter.php
vendored
Normal file
76
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Export/ClassMetadataExporter.php
vendored
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
<?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\ORM\Tools\Export;
|
||||
|
||||
/**
|
||||
* Class used for converting your mapping information between the
|
||||
* supported formats: yaml, xml, and php/annotation.
|
||||
*
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
*/
|
||||
class ClassMetadataExporter
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private static $_exporterDrivers = array(
|
||||
'xml' => 'Doctrine\ORM\Tools\Export\Driver\XmlExporter',
|
||||
'yaml' => 'Doctrine\ORM\Tools\Export\Driver\YamlExporter',
|
||||
'yml' => 'Doctrine\ORM\Tools\Export\Driver\YamlExporter',
|
||||
'php' => 'Doctrine\ORM\Tools\Export\Driver\PhpExporter',
|
||||
'annotation' => 'Doctrine\ORM\Tools\Export\Driver\AnnotationExporter'
|
||||
);
|
||||
|
||||
/**
|
||||
* Registers a new exporter driver class under a specified name.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $class
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function registerExportDriver($name, $class)
|
||||
{
|
||||
self::$_exporterDrivers[$name] = $class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an exporter driver instance.
|
||||
*
|
||||
* @param string $type The type to get (yml, xml, etc.).
|
||||
* @param string|null $dest The directory where the exporter will export to.
|
||||
*
|
||||
* @return Driver\AbstractExporter
|
||||
*
|
||||
* @throws ExportException
|
||||
*/
|
||||
public function getExporter($type, $dest = null)
|
||||
{
|
||||
if ( ! isset(self::$_exporterDrivers[$type])) {
|
||||
throw ExportException::invalidExporterDriverType($type);
|
||||
}
|
||||
|
||||
$class = self::$_exporterDrivers[$type];
|
||||
|
||||
return new $class($dest);
|
||||
}
|
||||
}
|
||||
269
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Export/Driver/AbstractExporter.php
vendored
Normal file
269
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Export/Driver/AbstractExporter.php
vendored
Normal file
|
|
@ -0,0 +1,269 @@
|
|||
<?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\ORM\Tools\Export\Driver;
|
||||
|
||||
use Doctrine\ORM\Mapping\ClassMetadataInfo;
|
||||
use Doctrine\ORM\Tools\Export\ExportException;
|
||||
|
||||
/**
|
||||
* Abstract base class which is to be used for the Exporter drivers
|
||||
* which can be found in \Doctrine\ORM\Tools\Export\Driver.
|
||||
*
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
*/
|
||||
abstract class AbstractExporter
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $_metadata = array();
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
protected $_outputDir;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
protected $_extension;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $_overwriteExistingFiles = false;
|
||||
|
||||
/**
|
||||
* @param string|null $dir
|
||||
*/
|
||||
public function __construct($dir = null)
|
||||
{
|
||||
$this->_outputDir = $dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $overwrite
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setOverwriteExistingFiles($overwrite)
|
||||
{
|
||||
$this->_overwriteExistingFiles = $overwrite;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a single ClassMetadata instance to the exported format
|
||||
* and returns it.
|
||||
*
|
||||
* @param ClassMetadataInfo $metadata
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract public function exportClassMetadata(ClassMetadataInfo $metadata);
|
||||
|
||||
/**
|
||||
* Sets the array of ClassMetadataInfo instances to export.
|
||||
*
|
||||
* @param array $metadata
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setMetadata(array $metadata)
|
||||
{
|
||||
$this->_metadata = $metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the extension used to generated the path to a class.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getExtension()
|
||||
{
|
||||
return $this->_extension;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the directory to output the mapping files to.
|
||||
*
|
||||
* [php]
|
||||
* $exporter = new YamlExporter($metadata);
|
||||
* $exporter->setOutputDir(__DIR__ . '/yaml');
|
||||
* $exporter->export();
|
||||
*
|
||||
* @param string $dir
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setOutputDir($dir)
|
||||
{
|
||||
$this->_outputDir = $dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exports each ClassMetadata instance to a single Doctrine Mapping file
|
||||
* named after the entity.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws \Doctrine\ORM\Tools\Export\ExportException
|
||||
*/
|
||||
public function export()
|
||||
{
|
||||
if ( ! is_dir($this->_outputDir)) {
|
||||
mkdir($this->_outputDir, 0775, true);
|
||||
}
|
||||
|
||||
foreach ($this->_metadata as $metadata) {
|
||||
// In case output is returned, write it to a file, skip otherwise
|
||||
if($output = $this->exportClassMetadata($metadata)){
|
||||
$path = $this->_generateOutputPath($metadata);
|
||||
$dir = dirname($path);
|
||||
if ( ! is_dir($dir)) {
|
||||
mkdir($dir, 0775, true);
|
||||
}
|
||||
if (file_exists($path) && !$this->_overwriteExistingFiles) {
|
||||
throw ExportException::attemptOverwriteExistingFile($path);
|
||||
}
|
||||
file_put_contents($path, $output);
|
||||
chmod($path, 0664);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the path to write the class for the given ClassMetadataInfo instance.
|
||||
*
|
||||
* @param ClassMetadataInfo $metadata
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function _generateOutputPath(ClassMetadataInfo $metadata)
|
||||
{
|
||||
return $this->_outputDir . '/' . str_replace('\\', '.', $metadata->name) . $this->_extension;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the directory to output the mapping files to.
|
||||
*
|
||||
* [php]
|
||||
* $exporter = new YamlExporter($metadata, __DIR__ . '/yaml');
|
||||
* $exporter->setExtension('.yml');
|
||||
* $exporter->export();
|
||||
*
|
||||
* @param string $extension
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setExtension($extension)
|
||||
{
|
||||
$this->_extension = $extension;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $type
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function _getInheritanceTypeString($type)
|
||||
{
|
||||
switch ($type) {
|
||||
case ClassMetadataInfo::INHERITANCE_TYPE_NONE:
|
||||
return 'NONE';
|
||||
|
||||
case ClassMetadataInfo::INHERITANCE_TYPE_JOINED:
|
||||
return 'JOINED';
|
||||
|
||||
case ClassMetadataInfo::INHERITANCE_TYPE_SINGLE_TABLE:
|
||||
return 'SINGLE_TABLE';
|
||||
|
||||
case ClassMetadataInfo::INHERITANCE_TYPE_TABLE_PER_CLASS:
|
||||
return 'PER_CLASS';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $mode
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function _getFetchModeString($mode)
|
||||
{
|
||||
switch ($mode) {
|
||||
case ClassMetadataInfo::FETCH_EAGER:
|
||||
return 'EAGER';
|
||||
|
||||
case ClassMetadataInfo::FETCH_EXTRA_LAZY:
|
||||
return 'EXTRA_LAZY';
|
||||
|
||||
case ClassMetadataInfo::FETCH_LAZY:
|
||||
return 'LAZY';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $policy
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function _getChangeTrackingPolicyString($policy)
|
||||
{
|
||||
switch ($policy) {
|
||||
case ClassMetadataInfo::CHANGETRACKING_DEFERRED_IMPLICIT:
|
||||
return 'DEFERRED_IMPLICIT';
|
||||
|
||||
case ClassMetadataInfo::CHANGETRACKING_DEFERRED_EXPLICIT:
|
||||
return 'DEFERRED_EXPLICIT';
|
||||
|
||||
case ClassMetadataInfo::CHANGETRACKING_NOTIFY:
|
||||
return 'NOTIFY';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $type
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function _getIdGeneratorTypeString($type)
|
||||
{
|
||||
switch ($type) {
|
||||
case ClassMetadataInfo::GENERATOR_TYPE_AUTO:
|
||||
return 'AUTO';
|
||||
|
||||
case ClassMetadataInfo::GENERATOR_TYPE_SEQUENCE:
|
||||
return 'SEQUENCE';
|
||||
|
||||
case ClassMetadataInfo::GENERATOR_TYPE_TABLE:
|
||||
return 'TABLE';
|
||||
|
||||
case ClassMetadataInfo::GENERATOR_TYPE_IDENTITY:
|
||||
return 'IDENTITY';
|
||||
|
||||
case ClassMetadataInfo::GENERATOR_TYPE_UUID:
|
||||
return 'UUID';
|
||||
|
||||
case ClassMetadataInfo::GENERATOR_TYPE_CUSTOM:
|
||||
return 'CUSTOM';
|
||||
}
|
||||
}
|
||||
}
|
||||
80
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Export/Driver/AnnotationExporter.php
vendored
Normal file
80
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Export/Driver/AnnotationExporter.php
vendored
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
<?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\ORM\Tools\Export\Driver;
|
||||
|
||||
use Doctrine\ORM\Mapping\ClassMetadataInfo;
|
||||
use Doctrine\ORM\Tools\EntityGenerator;
|
||||
|
||||
/**
|
||||
* ClassMetadata exporter for PHP classes with annotations.
|
||||
*
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
*/
|
||||
class AnnotationExporter extends AbstractExporter
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $_extension = '.php';
|
||||
|
||||
/**
|
||||
* @var EntityGenerator|null
|
||||
*/
|
||||
private $_entityGenerator;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function exportClassMetadata(ClassMetadataInfo $metadata)
|
||||
{
|
||||
if ( ! $this->_entityGenerator) {
|
||||
throw new \RuntimeException('For the AnnotationExporter you must set an EntityGenerator instance with the setEntityGenerator() method.');
|
||||
}
|
||||
|
||||
$this->_entityGenerator->setGenerateAnnotations(true);
|
||||
$this->_entityGenerator->setGenerateStubMethods(false);
|
||||
$this->_entityGenerator->setRegenerateEntityIfExists(false);
|
||||
$this->_entityGenerator->setUpdateEntityIfExists(false);
|
||||
|
||||
return $this->_entityGenerator->generateEntityClass($metadata);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Doctrine\ORM\Mapping\ClassMetadataInfo $metadata
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function _generateOutputPath(ClassMetadataInfo $metadata)
|
||||
{
|
||||
return $this->_outputDir . '/' . str_replace('\\', '/', $metadata->name) . $this->_extension;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Doctrine\ORM\Tools\EntityGenerator $entityGenerator
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setEntityGenerator(EntityGenerator $entityGenerator)
|
||||
{
|
||||
$this->_entityGenerator = $entityGenerator;
|
||||
}
|
||||
}
|
||||
177
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Export/Driver/PhpExporter.php
vendored
Normal file
177
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Export/Driver/PhpExporter.php
vendored
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
<?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\ORM\Tools\Export\Driver;
|
||||
|
||||
use Doctrine\ORM\Mapping\ClassMetadataInfo;
|
||||
|
||||
/**
|
||||
* ClassMetadata exporter for PHP code.
|
||||
*
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
*/
|
||||
class PhpExporter extends AbstractExporter
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $_extension = '.php';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function exportClassMetadata(ClassMetadataInfo $metadata)
|
||||
{
|
||||
$lines = array();
|
||||
$lines[] = '<?php';
|
||||
$lines[] = null;
|
||||
$lines[] = 'use Doctrine\ORM\Mapping\ClassMetadataInfo;';
|
||||
$lines[] = null;
|
||||
|
||||
if ($metadata->isMappedSuperclass) {
|
||||
$lines[] = '$metadata->isMappedSuperclass = true;';
|
||||
}
|
||||
|
||||
if ($metadata->inheritanceType) {
|
||||
$lines[] = '$metadata->setInheritanceType(ClassMetadataInfo::INHERITANCE_TYPE_' . $this->_getInheritanceTypeString($metadata->inheritanceType) . ');';
|
||||
}
|
||||
|
||||
if ($metadata->customRepositoryClassName) {
|
||||
$lines[] = "\$metadata->customRepositoryClassName = '" . $metadata->customRepositoryClassName . "';";
|
||||
}
|
||||
|
||||
if ($metadata->table) {
|
||||
$lines[] = '$metadata->setPrimaryTable(' . $this->_varExport($metadata->table) . ');';
|
||||
}
|
||||
|
||||
if ($metadata->discriminatorColumn) {
|
||||
$lines[] = '$metadata->setDiscriminatorColumn(' . $this->_varExport($metadata->discriminatorColumn) . ');';
|
||||
}
|
||||
|
||||
if ($metadata->discriminatorMap) {
|
||||
$lines[] = '$metadata->setDiscriminatorMap(' . $this->_varExport($metadata->discriminatorMap) . ');';
|
||||
}
|
||||
|
||||
if ($metadata->changeTrackingPolicy) {
|
||||
$lines[] = '$metadata->setChangeTrackingPolicy(ClassMetadataInfo::CHANGETRACKING_' . $this->_getChangeTrackingPolicyString($metadata->changeTrackingPolicy) . ');';
|
||||
}
|
||||
|
||||
if ($metadata->lifecycleCallbacks) {
|
||||
foreach ($metadata->lifecycleCallbacks as $event => $callbacks) {
|
||||
foreach ($callbacks as $callback) {
|
||||
$lines[] = "\$metadata->addLifecycleCallback('$callback', '$event');";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($metadata->fieldMappings as $fieldMapping) {
|
||||
$lines[] = '$metadata->mapField(' . $this->_varExport($fieldMapping) . ');';
|
||||
}
|
||||
|
||||
if ( ! $metadata->isIdentifierComposite && $generatorType = $this->_getIdGeneratorTypeString($metadata->generatorType)) {
|
||||
$lines[] = '$metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_' . $generatorType . ');';
|
||||
}
|
||||
|
||||
foreach ($metadata->associationMappings as $associationMapping) {
|
||||
$cascade = array('remove', 'persist', 'refresh', 'merge', 'detach');
|
||||
foreach ($cascade as $key => $value) {
|
||||
if ( ! $associationMapping['isCascade'.ucfirst($value)]) {
|
||||
unset($cascade[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
if (count($cascade) === 5) {
|
||||
$cascade = array('all');
|
||||
}
|
||||
|
||||
$associationMappingArray = array(
|
||||
'fieldName' => $associationMapping['fieldName'],
|
||||
'targetEntity' => $associationMapping['targetEntity'],
|
||||
'cascade' => $cascade,
|
||||
);
|
||||
|
||||
if (isset($associationMapping['fetch'])) {
|
||||
$associationMappingArray['fetch'] = $associationMapping['fetch'];
|
||||
}
|
||||
|
||||
if ($associationMapping['type'] & ClassMetadataInfo::TO_ONE) {
|
||||
$method = 'mapOneToOne';
|
||||
$oneToOneMappingArray = array(
|
||||
'mappedBy' => $associationMapping['mappedBy'],
|
||||
'inversedBy' => $associationMapping['inversedBy'],
|
||||
'joinColumns' => $associationMapping['isOwningSide'] ? $associationMapping['joinColumns'] : [],
|
||||
'orphanRemoval' => $associationMapping['orphanRemoval'],
|
||||
);
|
||||
|
||||
$associationMappingArray = array_merge($associationMappingArray, $oneToOneMappingArray);
|
||||
} elseif ($associationMapping['type'] == ClassMetadataInfo::ONE_TO_MANY) {
|
||||
$method = 'mapOneToMany';
|
||||
$potentialAssociationMappingIndexes = array(
|
||||
'mappedBy',
|
||||
'orphanRemoval',
|
||||
'orderBy',
|
||||
);
|
||||
foreach ($potentialAssociationMappingIndexes as $index) {
|
||||
if (isset($associationMapping[$index])) {
|
||||
$oneToManyMappingArray[$index] = $associationMapping[$index];
|
||||
}
|
||||
}
|
||||
$associationMappingArray = array_merge($associationMappingArray, $oneToManyMappingArray);
|
||||
} elseif ($associationMapping['type'] == ClassMetadataInfo::MANY_TO_MANY) {
|
||||
$method = 'mapManyToMany';
|
||||
$potentialAssociationMappingIndexes = array(
|
||||
'mappedBy',
|
||||
'joinTable',
|
||||
'orderBy',
|
||||
);
|
||||
foreach ($potentialAssociationMappingIndexes as $index) {
|
||||
if (isset($associationMapping[$index])) {
|
||||
$manyToManyMappingArray[$index] = $associationMapping[$index];
|
||||
}
|
||||
}
|
||||
$associationMappingArray = array_merge($associationMappingArray, $manyToManyMappingArray);
|
||||
}
|
||||
|
||||
$lines[] = '$metadata->' . $method . '(' . $this->_varExport($associationMappingArray) . ');';
|
||||
}
|
||||
|
||||
return implode("\n", $lines);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $var
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function _varExport($var)
|
||||
{
|
||||
$export = var_export($var, true);
|
||||
$export = str_replace("\n", PHP_EOL . str_repeat(' ', 8), $export);
|
||||
$export = str_replace(' ', ' ', $export);
|
||||
$export = str_replace('array (', 'array(', $export);
|
||||
$export = str_replace('array( ', 'array(', $export);
|
||||
$export = str_replace(',)', ')', $export);
|
||||
$export = str_replace(', )', ')', $export);
|
||||
$export = str_replace(' ', ' ', $export);
|
||||
|
||||
return $export;
|
||||
}
|
||||
}
|
||||
453
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php
vendored
Normal file
453
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php
vendored
Normal file
|
|
@ -0,0 +1,453 @@
|
|||
<?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\ORM\Tools\Export\Driver;
|
||||
|
||||
use Doctrine\ORM\Mapping\ClassMetadataInfo;
|
||||
|
||||
/**
|
||||
* ClassMetadata exporter for Doctrine XML mapping files.
|
||||
*
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
*/
|
||||
class XmlExporter extends AbstractExporter
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $_extension = '.dcm.xml';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function exportClassMetadata(ClassMetadataInfo $metadata)
|
||||
{
|
||||
$xml = new \SimpleXmlElement("<?xml version=\"1.0\" encoding=\"utf-8\"?><doctrine-mapping ".
|
||||
"xmlns=\"http://doctrine-project.org/schemas/orm/doctrine-mapping\" " .
|
||||
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ".
|
||||
"xsi:schemaLocation=\"http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd\" />");
|
||||
|
||||
if ($metadata->isMappedSuperclass) {
|
||||
$root = $xml->addChild('mapped-superclass');
|
||||
} else {
|
||||
$root = $xml->addChild('entity');
|
||||
}
|
||||
|
||||
if ($metadata->customRepositoryClassName) {
|
||||
$root->addAttribute('repository-class', $metadata->customRepositoryClassName);
|
||||
}
|
||||
|
||||
$root->addAttribute('name', $metadata->name);
|
||||
|
||||
if (isset($metadata->table['name'])) {
|
||||
$root->addAttribute('table', $metadata->table['name']);
|
||||
}
|
||||
|
||||
if (isset($metadata->table['schema'])) {
|
||||
$root->addAttribute('schema', $metadata->table['schema']);
|
||||
}
|
||||
|
||||
if ($metadata->inheritanceType && $metadata->inheritanceType !== ClassMetadataInfo::INHERITANCE_TYPE_NONE) {
|
||||
$root->addAttribute('inheritance-type', $this->_getInheritanceTypeString($metadata->inheritanceType));
|
||||
}
|
||||
|
||||
if (isset($metadata->table['options'])) {
|
||||
$optionsXml = $root->addChild('options');
|
||||
|
||||
$this->exportTableOptions($optionsXml, $metadata->table['options']);
|
||||
}
|
||||
|
||||
if ($metadata->discriminatorColumn) {
|
||||
$discriminatorColumnXml = $root->addChild('discriminator-column');
|
||||
$discriminatorColumnXml->addAttribute('name', $metadata->discriminatorColumn['name']);
|
||||
$discriminatorColumnXml->addAttribute('type', $metadata->discriminatorColumn['type']);
|
||||
|
||||
if (isset($metadata->discriminatorColumn['length'])) {
|
||||
$discriminatorColumnXml->addAttribute('length', $metadata->discriminatorColumn['length']);
|
||||
}
|
||||
}
|
||||
|
||||
if ($metadata->discriminatorMap) {
|
||||
$discriminatorMapXml = $root->addChild('discriminator-map');
|
||||
|
||||
foreach ($metadata->discriminatorMap as $value => $className) {
|
||||
$discriminatorMappingXml = $discriminatorMapXml->addChild('discriminator-mapping');
|
||||
$discriminatorMappingXml->addAttribute('value', $value);
|
||||
$discriminatorMappingXml->addAttribute('class', $className);
|
||||
}
|
||||
}
|
||||
|
||||
$trackingPolicy = $this->_getChangeTrackingPolicyString($metadata->changeTrackingPolicy);
|
||||
|
||||
if ( $trackingPolicy != 'DEFERRED_IMPLICIT') {
|
||||
$root->addChild('change-tracking-policy', $trackingPolicy);
|
||||
}
|
||||
|
||||
if (isset($metadata->table['indexes'])) {
|
||||
$indexesXml = $root->addChild('indexes');
|
||||
|
||||
foreach ($metadata->table['indexes'] as $name => $index) {
|
||||
$indexXml = $indexesXml->addChild('index');
|
||||
$indexXml->addAttribute('name', $name);
|
||||
$indexXml->addAttribute('columns', implode(',', $index['columns']));
|
||||
if(isset($index['flags'])) {
|
||||
$indexXml->addAttribute('flags', implode(',', $index['flags']));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($metadata->table['uniqueConstraints'])) {
|
||||
$uniqueConstraintsXml = $root->addChild('unique-constraints');
|
||||
|
||||
foreach ($metadata->table['uniqueConstraints'] as $name => $unique) {
|
||||
$uniqueConstraintXml = $uniqueConstraintsXml->addChild('unique-constraint');
|
||||
$uniqueConstraintXml->addAttribute('name', $name);
|
||||
$uniqueConstraintXml->addAttribute('columns', implode(',', $unique['columns']));
|
||||
}
|
||||
}
|
||||
|
||||
$fields = $metadata->fieldMappings;
|
||||
|
||||
$id = array();
|
||||
foreach ($fields as $name => $field) {
|
||||
if (isset($field['id']) && $field['id']) {
|
||||
$id[$name] = $field;
|
||||
unset($fields[$name]);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($metadata->associationMappings as $name => $assoc) {
|
||||
if (isset($assoc['id']) && $assoc['id']) {
|
||||
$id[$name] = array(
|
||||
'fieldName' => $name,
|
||||
'associationKey' => true
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $metadata->isIdentifierComposite && $idGeneratorType = $this->_getIdGeneratorTypeString($metadata->generatorType)) {
|
||||
$id[$metadata->getSingleIdentifierFieldName()]['generator']['strategy'] = $idGeneratorType;
|
||||
}
|
||||
|
||||
if ($id) {
|
||||
foreach ($id as $field) {
|
||||
$idXml = $root->addChild('id');
|
||||
$idXml->addAttribute('name', $field['fieldName']);
|
||||
|
||||
if (isset($field['type'])) {
|
||||
$idXml->addAttribute('type', $field['type']);
|
||||
}
|
||||
|
||||
if (isset($field['columnName'])) {
|
||||
$idXml->addAttribute('column', $field['columnName']);
|
||||
}
|
||||
|
||||
if (isset($field['length'])) {
|
||||
$idXml->addAttribute('length', $field['length']);
|
||||
}
|
||||
|
||||
if (isset($field['associationKey']) && $field['associationKey']) {
|
||||
$idXml->addAttribute('association-key', 'true');
|
||||
}
|
||||
|
||||
if ($idGeneratorType = $this->_getIdGeneratorTypeString($metadata->generatorType)) {
|
||||
$generatorXml = $idXml->addChild('generator');
|
||||
$generatorXml->addAttribute('strategy', $idGeneratorType);
|
||||
|
||||
$this->exportSequenceInformation($idXml, $metadata);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($fields) {
|
||||
foreach ($fields as $field) {
|
||||
$fieldXml = $root->addChild('field');
|
||||
$fieldXml->addAttribute('name', $field['fieldName']);
|
||||
$fieldXml->addAttribute('type', $field['type']);
|
||||
|
||||
if (isset($field['columnName'])) {
|
||||
$fieldXml->addAttribute('column', $field['columnName']);
|
||||
}
|
||||
|
||||
if (isset($field['length'])) {
|
||||
$fieldXml->addAttribute('length', $field['length']);
|
||||
}
|
||||
|
||||
if (isset($field['precision'])) {
|
||||
$fieldXml->addAttribute('precision', $field['precision']);
|
||||
}
|
||||
|
||||
if (isset($field['scale'])) {
|
||||
$fieldXml->addAttribute('scale', $field['scale']);
|
||||
}
|
||||
|
||||
if (isset($field['unique']) && $field['unique']) {
|
||||
$fieldXml->addAttribute('unique', $field['unique'] ? 'true' : 'false');
|
||||
}
|
||||
|
||||
if (isset($field['options'])) {
|
||||
$optionsXml = $fieldXml->addChild('options');
|
||||
foreach ($field['options'] as $key => $value) {
|
||||
$optionXml = $optionsXml->addChild('option', $value);
|
||||
$optionXml->addAttribute('name', $key);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($field['version'])) {
|
||||
$fieldXml->addAttribute('version', $field['version']);
|
||||
}
|
||||
|
||||
if (isset($field['columnDefinition'])) {
|
||||
$fieldXml->addAttribute('column-definition', $field['columnDefinition']);
|
||||
}
|
||||
|
||||
if (isset($field['nullable'])) {
|
||||
$fieldXml->addAttribute('nullable', $field['nullable'] ? 'true' : 'false');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$orderMap = array(
|
||||
ClassMetadataInfo::ONE_TO_ONE,
|
||||
ClassMetadataInfo::ONE_TO_MANY,
|
||||
ClassMetadataInfo::MANY_TO_ONE,
|
||||
ClassMetadataInfo::MANY_TO_MANY,
|
||||
);
|
||||
|
||||
uasort($metadata->associationMappings, function($m1, $m2) use (&$orderMap){
|
||||
$a1 = array_search($m1['type'], $orderMap);
|
||||
$a2 = array_search($m2['type'], $orderMap);
|
||||
|
||||
return strcmp($a1, $a2);
|
||||
});
|
||||
|
||||
foreach ($metadata->associationMappings as $associationMapping) {
|
||||
if ($associationMapping['type'] == ClassMetadataInfo::ONE_TO_ONE) {
|
||||
$associationMappingXml = $root->addChild('one-to-one');
|
||||
} elseif ($associationMapping['type'] == ClassMetadataInfo::MANY_TO_ONE) {
|
||||
$associationMappingXml = $root->addChild('many-to-one');
|
||||
} elseif ($associationMapping['type'] == ClassMetadataInfo::ONE_TO_MANY) {
|
||||
$associationMappingXml = $root->addChild('one-to-many');
|
||||
} elseif ($associationMapping['type'] == ClassMetadataInfo::MANY_TO_MANY) {
|
||||
$associationMappingXml = $root->addChild('many-to-many');
|
||||
}
|
||||
|
||||
$associationMappingXml->addAttribute('field', $associationMapping['fieldName']);
|
||||
$associationMappingXml->addAttribute('target-entity', $associationMapping['targetEntity']);
|
||||
|
||||
if (isset($associationMapping['mappedBy'])) {
|
||||
$associationMappingXml->addAttribute('mapped-by', $associationMapping['mappedBy']);
|
||||
}
|
||||
|
||||
if (isset($associationMapping['inversedBy'])) {
|
||||
$associationMappingXml->addAttribute('inversed-by', $associationMapping['inversedBy']);
|
||||
}
|
||||
|
||||
if (isset($associationMapping['indexBy'])) {
|
||||
$associationMappingXml->addAttribute('index-by', $associationMapping['indexBy']);
|
||||
}
|
||||
|
||||
if (isset($associationMapping['orphanRemoval']) && $associationMapping['orphanRemoval'] !== false) {
|
||||
$associationMappingXml->addAttribute('orphan-removal', 'true');
|
||||
}
|
||||
|
||||
if (isset($associationMapping['fetch'])) {
|
||||
$associationMappingXml->addAttribute('fetch', $this->_getFetchModeString($associationMapping['fetch']));
|
||||
}
|
||||
|
||||
$cascade = array();
|
||||
if ($associationMapping['isCascadeRemove']) {
|
||||
$cascade[] = 'cascade-remove';
|
||||
}
|
||||
|
||||
if ($associationMapping['isCascadePersist']) {
|
||||
$cascade[] = 'cascade-persist';
|
||||
}
|
||||
|
||||
if ($associationMapping['isCascadeRefresh']) {
|
||||
$cascade[] = 'cascade-refresh';
|
||||
}
|
||||
|
||||
if ($associationMapping['isCascadeMerge']) {
|
||||
$cascade[] = 'cascade-merge';
|
||||
}
|
||||
|
||||
if ($associationMapping['isCascadeDetach']) {
|
||||
$cascade[] = 'cascade-detach';
|
||||
}
|
||||
|
||||
if (count($cascade) === 5) {
|
||||
$cascade = array('cascade-all');
|
||||
}
|
||||
|
||||
if ($cascade) {
|
||||
$cascadeXml = $associationMappingXml->addChild('cascade');
|
||||
|
||||
foreach ($cascade as $type) {
|
||||
$cascadeXml->addChild($type);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($associationMapping['joinTable']) && $associationMapping['joinTable']) {
|
||||
$joinTableXml = $associationMappingXml->addChild('join-table');
|
||||
$joinTableXml->addAttribute('name', $associationMapping['joinTable']['name']);
|
||||
$joinColumnsXml = $joinTableXml->addChild('join-columns');
|
||||
|
||||
foreach ($associationMapping['joinTable']['joinColumns'] as $joinColumn) {
|
||||
$joinColumnXml = $joinColumnsXml->addChild('join-column');
|
||||
$joinColumnXml->addAttribute('name', $joinColumn['name']);
|
||||
$joinColumnXml->addAttribute('referenced-column-name', $joinColumn['referencedColumnName']);
|
||||
|
||||
if (isset($joinColumn['onDelete'])) {
|
||||
$joinColumnXml->addAttribute('on-delete', $joinColumn['onDelete']);
|
||||
}
|
||||
}
|
||||
|
||||
$inverseJoinColumnsXml = $joinTableXml->addChild('inverse-join-columns');
|
||||
|
||||
foreach ($associationMapping['joinTable']['inverseJoinColumns'] as $inverseJoinColumn) {
|
||||
$inverseJoinColumnXml = $inverseJoinColumnsXml->addChild('join-column');
|
||||
$inverseJoinColumnXml->addAttribute('name', $inverseJoinColumn['name']);
|
||||
$inverseJoinColumnXml->addAttribute('referenced-column-name', $inverseJoinColumn['referencedColumnName']);
|
||||
|
||||
if (isset($inverseJoinColumn['onDelete'])) {
|
||||
$inverseJoinColumnXml->addAttribute('on-delete', $inverseJoinColumn['onDelete']);
|
||||
}
|
||||
|
||||
if (isset($inverseJoinColumn['columnDefinition'])) {
|
||||
$inverseJoinColumnXml->addAttribute('column-definition', $inverseJoinColumn['columnDefinition']);
|
||||
}
|
||||
|
||||
if (isset($inverseJoinColumn['nullable'])) {
|
||||
$inverseJoinColumnXml->addAttribute('nullable', $inverseJoinColumn['nullable']);
|
||||
}
|
||||
|
||||
if (isset($inverseJoinColumn['orderBy'])) {
|
||||
$inverseJoinColumnXml->addAttribute('order-by', $inverseJoinColumn['orderBy']);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isset($associationMapping['joinColumns'])) {
|
||||
$joinColumnsXml = $associationMappingXml->addChild('join-columns');
|
||||
|
||||
foreach ($associationMapping['joinColumns'] as $joinColumn) {
|
||||
$joinColumnXml = $joinColumnsXml->addChild('join-column');
|
||||
$joinColumnXml->addAttribute('name', $joinColumn['name']);
|
||||
$joinColumnXml->addAttribute('referenced-column-name', $joinColumn['referencedColumnName']);
|
||||
|
||||
if (isset($joinColumn['onDelete'])) {
|
||||
$joinColumnXml->addAttribute('on-delete', $joinColumn['onDelete']);
|
||||
}
|
||||
|
||||
if (isset($joinColumn['columnDefinition'])) {
|
||||
$joinColumnXml->addAttribute('column-definition', $joinColumn['columnDefinition']);
|
||||
}
|
||||
|
||||
if (isset($joinColumn['nullable'])) {
|
||||
$joinColumnXml->addAttribute('nullable', $joinColumn['nullable']);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isset($associationMapping['orderBy'])) {
|
||||
$orderByXml = $associationMappingXml->addChild('order-by');
|
||||
|
||||
foreach ($associationMapping['orderBy'] as $name => $direction) {
|
||||
$orderByFieldXml = $orderByXml->addChild('order-by-field');
|
||||
$orderByFieldXml->addAttribute('name', $name);
|
||||
$orderByFieldXml->addAttribute('direction', $direction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($metadata->lifecycleCallbacks) && count($metadata->lifecycleCallbacks)>0) {
|
||||
$lifecycleCallbacksXml = $root->addChild('lifecycle-callbacks');
|
||||
|
||||
foreach ($metadata->lifecycleCallbacks as $name => $methods) {
|
||||
foreach ($methods as $method) {
|
||||
$lifecycleCallbackXml = $lifecycleCallbacksXml->addChild('lifecycle-callback');
|
||||
$lifecycleCallbackXml->addAttribute('type', $name);
|
||||
$lifecycleCallbackXml->addAttribute('method', $method);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->_asXml($xml);
|
||||
}
|
||||
|
||||
/**
|
||||
* Exports (nested) option elements.
|
||||
*
|
||||
* @param \SimpleXMLElement $parentXml
|
||||
* @param array $options
|
||||
*/
|
||||
private function exportTableOptions(\SimpleXMLElement $parentXml, array $options)
|
||||
{
|
||||
foreach ($options as $name => $option) {
|
||||
$isArray = is_array($option);
|
||||
$optionXml = $isArray
|
||||
? $parentXml->addChild('option')
|
||||
: $parentXml->addChild('option', (string) $option);
|
||||
|
||||
$optionXml->addAttribute('name', (string) $name);
|
||||
|
||||
if ($isArray) {
|
||||
$this->exportTableOptions($optionXml, $option);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Export sequence information (if available/configured) into the current identifier XML node
|
||||
*
|
||||
* @param \SimpleXMLElement $identifierXmlNode
|
||||
* @param ClassMetadataInfo $metadata
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function exportSequenceInformation(\SimpleXMLElement $identifierXmlNode, ClassMetadataInfo $metadata)
|
||||
{
|
||||
$sequenceDefinition = $metadata->sequenceGeneratorDefinition;
|
||||
|
||||
if (! ($metadata->generatorType === ClassMetadataInfo::GENERATOR_TYPE_SEQUENCE && $sequenceDefinition)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$sequenceGeneratorXml = $identifierXmlNode->addChild('sequence-generator');
|
||||
|
||||
$sequenceGeneratorXml->addAttribute('sequence-name', $sequenceDefinition['sequenceName']);
|
||||
$sequenceGeneratorXml->addAttribute('allocation-size', $sequenceDefinition['allocationSize']);
|
||||
$sequenceGeneratorXml->addAttribute('initial-value', $sequenceDefinition['initialValue']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \SimpleXMLElement $simpleXml
|
||||
*
|
||||
* @return string $xml
|
||||
*/
|
||||
private function _asXml($simpleXml)
|
||||
{
|
||||
$dom = new \DOMDocument('1.0', 'UTF-8');
|
||||
$dom->loadXML($simpleXml->asXML());
|
||||
$dom->formatOutput = true;
|
||||
|
||||
return $dom->saveXML();
|
||||
}
|
||||
}
|
||||
235
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Export/Driver/YamlExporter.php
vendored
Normal file
235
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Export/Driver/YamlExporter.php
vendored
Normal file
|
|
@ -0,0 +1,235 @@
|
|||
<?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\ORM\Tools\Export\Driver;
|
||||
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
use Doctrine\ORM\Mapping\ClassMetadataInfo;
|
||||
|
||||
/**
|
||||
* ClassMetadata exporter for Doctrine YAML mapping files.
|
||||
*
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
*/
|
||||
class YamlExporter extends AbstractExporter
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $_extension = '.dcm.yml';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function exportClassMetadata(ClassMetadataInfo $metadata)
|
||||
{
|
||||
$array = array();
|
||||
|
||||
if ($metadata->isMappedSuperclass) {
|
||||
$array['type'] = 'mappedSuperclass';
|
||||
} else {
|
||||
$array['type'] = 'entity';
|
||||
}
|
||||
|
||||
$array['table'] = $metadata->table['name'];
|
||||
|
||||
if (isset($metadata->table['schema'])) {
|
||||
$array['schema'] = $metadata->table['schema'];
|
||||
}
|
||||
|
||||
$inheritanceType = $metadata->inheritanceType;
|
||||
|
||||
if ($inheritanceType !== ClassMetadataInfo::INHERITANCE_TYPE_NONE) {
|
||||
$array['inheritanceType'] = $this->_getInheritanceTypeString($inheritanceType);
|
||||
}
|
||||
|
||||
if ($column = $metadata->discriminatorColumn) {
|
||||
$array['discriminatorColumn'] = $column;
|
||||
}
|
||||
|
||||
if ($map = $metadata->discriminatorMap) {
|
||||
$array['discriminatorMap'] = $map;
|
||||
}
|
||||
|
||||
if ($metadata->changeTrackingPolicy !== ClassMetadataInfo::CHANGETRACKING_DEFERRED_IMPLICIT) {
|
||||
$array['changeTrackingPolicy'] = $this->_getChangeTrackingPolicyString($metadata->changeTrackingPolicy);
|
||||
}
|
||||
|
||||
if (isset($metadata->table['indexes'])) {
|
||||
$array['indexes'] = $metadata->table['indexes'];
|
||||
}
|
||||
|
||||
if ($metadata->customRepositoryClassName) {
|
||||
$array['repositoryClass'] = $metadata->customRepositoryClassName;
|
||||
}
|
||||
|
||||
if (isset($metadata->table['uniqueConstraints'])) {
|
||||
$array['uniqueConstraints'] = $metadata->table['uniqueConstraints'];
|
||||
}
|
||||
|
||||
if (isset($metadata->table['options'])) {
|
||||
$array['options'] = $metadata->table['options'];
|
||||
}
|
||||
|
||||
$fieldMappings = $metadata->fieldMappings;
|
||||
|
||||
$ids = array();
|
||||
foreach ($fieldMappings as $name => $fieldMapping) {
|
||||
$fieldMapping['column'] = $fieldMapping['columnName'];
|
||||
|
||||
unset($fieldMapping['columnName'], $fieldMapping['fieldName']);
|
||||
|
||||
if ($fieldMapping['column'] == $name) {
|
||||
unset($fieldMapping['column']);
|
||||
}
|
||||
|
||||
if (isset($fieldMapping['id']) && $fieldMapping['id']) {
|
||||
$ids[$name] = $fieldMapping;
|
||||
unset($fieldMappings[$name]);
|
||||
continue;
|
||||
}
|
||||
|
||||
$fieldMappings[$name] = $fieldMapping;
|
||||
}
|
||||
|
||||
if ( ! $metadata->isIdentifierComposite && $idGeneratorType = $this->_getIdGeneratorTypeString($metadata->generatorType)) {
|
||||
$ids[$metadata->getSingleIdentifierFieldName()]['generator']['strategy'] = $idGeneratorType;
|
||||
}
|
||||
|
||||
$array['id'] = $ids;
|
||||
|
||||
if ($fieldMappings) {
|
||||
if ( ! isset($array['fields'])) {
|
||||
$array['fields'] = array();
|
||||
}
|
||||
$array['fields'] = array_merge($array['fields'], $fieldMappings);
|
||||
}
|
||||
|
||||
foreach ($metadata->associationMappings as $name => $associationMapping) {
|
||||
$cascade = array();
|
||||
|
||||
if ($associationMapping['isCascadeRemove']) {
|
||||
$cascade[] = 'remove';
|
||||
}
|
||||
|
||||
if ($associationMapping['isCascadePersist']) {
|
||||
$cascade[] = 'persist';
|
||||
}
|
||||
|
||||
if ($associationMapping['isCascadeRefresh']) {
|
||||
$cascade[] = 'refresh';
|
||||
}
|
||||
|
||||
if ($associationMapping['isCascadeMerge']) {
|
||||
$cascade[] = 'merge';
|
||||
}
|
||||
|
||||
if ($associationMapping['isCascadeDetach']) {
|
||||
$cascade[] = 'detach';
|
||||
}
|
||||
if (count($cascade) === 5) {
|
||||
$cascade = array('all');
|
||||
}
|
||||
|
||||
$associationMappingArray = array(
|
||||
'targetEntity' => $associationMapping['targetEntity'],
|
||||
'cascade' => $cascade,
|
||||
);
|
||||
|
||||
if (isset($associationMapping['fetch'])) {
|
||||
$associationMappingArray['fetch'] = $this->_getFetchModeString($associationMapping['fetch']);
|
||||
}
|
||||
|
||||
if (isset($mapping['id']) && $mapping['id'] === true) {
|
||||
$array['id'][$name]['associationKey'] = true;
|
||||
}
|
||||
|
||||
if ($associationMapping['type'] & ClassMetadataInfo::TO_ONE) {
|
||||
$joinColumns = $associationMapping['isOwningSide'] ? $associationMapping['joinColumns'] : [];
|
||||
$newJoinColumns = array();
|
||||
|
||||
foreach ($joinColumns as $joinColumn) {
|
||||
$newJoinColumns[$joinColumn['name']]['referencedColumnName'] = $joinColumn['referencedColumnName'];
|
||||
|
||||
if (isset($joinColumn['onDelete'])) {
|
||||
$newJoinColumns[$joinColumn['name']]['onDelete'] = $joinColumn['onDelete'];
|
||||
}
|
||||
}
|
||||
|
||||
$oneToOneMappingArray = array(
|
||||
'mappedBy' => $associationMapping['mappedBy'],
|
||||
'inversedBy' => $associationMapping['inversedBy'],
|
||||
'joinColumns' => $newJoinColumns,
|
||||
'orphanRemoval' => $associationMapping['orphanRemoval'],
|
||||
);
|
||||
|
||||
$associationMappingArray = array_merge($associationMappingArray, $oneToOneMappingArray);
|
||||
|
||||
if ($associationMapping['type'] & ClassMetadataInfo::ONE_TO_ONE) {
|
||||
$array['oneToOne'][$name] = $associationMappingArray;
|
||||
} else {
|
||||
$array['manyToOne'][$name] = $associationMappingArray;
|
||||
}
|
||||
} elseif ($associationMapping['type'] == ClassMetadataInfo::ONE_TO_MANY) {
|
||||
$oneToManyMappingArray = array(
|
||||
'mappedBy' => $associationMapping['mappedBy'],
|
||||
'inversedBy' => $associationMapping['inversedBy'],
|
||||
'orphanRemoval' => $associationMapping['orphanRemoval'],
|
||||
'orderBy' => isset($associationMapping['orderBy']) ? $associationMapping['orderBy'] : null
|
||||
);
|
||||
|
||||
$associationMappingArray = array_merge($associationMappingArray, $oneToManyMappingArray);
|
||||
$array['oneToMany'][$name] = $associationMappingArray;
|
||||
} elseif ($associationMapping['type'] == ClassMetadataInfo::MANY_TO_MANY) {
|
||||
$manyToManyMappingArray = array(
|
||||
'mappedBy' => $associationMapping['mappedBy'],
|
||||
'inversedBy' => $associationMapping['inversedBy'],
|
||||
'joinTable' => isset($associationMapping['joinTable']) ? $associationMapping['joinTable'] : null,
|
||||
'orderBy' => isset($associationMapping['orderBy']) ? $associationMapping['orderBy'] : null
|
||||
);
|
||||
|
||||
$associationMappingArray = array_merge($associationMappingArray, $manyToManyMappingArray);
|
||||
$array['manyToMany'][$name] = $associationMappingArray;
|
||||
}
|
||||
}
|
||||
if (isset($metadata->lifecycleCallbacks)) {
|
||||
$array['lifecycleCallbacks'] = $metadata->lifecycleCallbacks;
|
||||
}
|
||||
|
||||
return $this->yamlDump(array($metadata->name => $array), 10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps a PHP array to a YAML string.
|
||||
*
|
||||
* The yamlDump method, when supplied with an array, will do its best
|
||||
* to convert the array into friendly YAML.
|
||||
*
|
||||
* @param array $array PHP array
|
||||
* @param integer $inline [optional] The level where you switch to inline YAML
|
||||
*
|
||||
* @return string A YAML string representing the original PHP array
|
||||
*/
|
||||
protected function yamlDump($array, $inline = 2)
|
||||
{
|
||||
return Yaml::dump($array, $inline);
|
||||
}
|
||||
}
|
||||
38
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Export/ExportException.php
vendored
Normal file
38
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Export/ExportException.php
vendored
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
namespace Doctrine\ORM\Tools\Export;
|
||||
|
||||
use Doctrine\ORM\ORMException;
|
||||
|
||||
class ExportException extends ORMException
|
||||
{
|
||||
/**
|
||||
* @param string $type
|
||||
*
|
||||
* @return ExportException
|
||||
*/
|
||||
public static function invalidExporterDriverType($type)
|
||||
{
|
||||
return new self("The specified export driver '$type' does not exist");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
*
|
||||
* @return ExportException
|
||||
*/
|
||||
public static function invalidMappingDriverType($type)
|
||||
{
|
||||
return new self("The mapping driver '$type' does not exist");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
*
|
||||
* @return ExportException
|
||||
*/
|
||||
public static function attemptOverwriteExistingFile($file)
|
||||
{
|
||||
return new self("Attempting to overwrite an existing file '".$file."'.");
|
||||
}
|
||||
}
|
||||
148
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Pagination/CountOutputWalker.php
vendored
Normal file
148
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Pagination/CountOutputWalker.php
vendored
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
<?php
|
||||
/**
|
||||
* Doctrine ORM
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to kontakt@beberlei.de so I can send you a copy immediately.
|
||||
*/
|
||||
|
||||
namespace Doctrine\ORM\Tools\Pagination;
|
||||
|
||||
use Doctrine\ORM\Query\SqlWalker;
|
||||
use Doctrine\ORM\Query\AST\SelectStatement;
|
||||
|
||||
/**
|
||||
* Wraps the query in order to accurately count the root objects.
|
||||
*
|
||||
* Given a DQL like `SELECT u FROM User u` it will generate an SQL query like:
|
||||
* SELECT COUNT(*) (SELECT DISTINCT <id> FROM (<original SQL>))
|
||||
*
|
||||
* Works with composite keys but cannot deal with queries that have multiple
|
||||
* root entities (e.g. `SELECT f, b from Foo, Bar`)
|
||||
*
|
||||
* @author Sander Marechal <s.marechal@jejik.com>
|
||||
*/
|
||||
class CountOutputWalker extends SqlWalker
|
||||
{
|
||||
/**
|
||||
* @var \Doctrine\DBAL\Platforms\AbstractPlatform
|
||||
*/
|
||||
private $platform;
|
||||
|
||||
/**
|
||||
* @var \Doctrine\ORM\Query\ResultSetMapping
|
||||
*/
|
||||
private $rsm;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $queryComponents;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Stores various parameters that are otherwise unavailable
|
||||
* because Doctrine\ORM\Query\SqlWalker keeps everything private without
|
||||
* accessors.
|
||||
*
|
||||
* @param \Doctrine\ORM\Query $query
|
||||
* @param \Doctrine\ORM\Query\ParserResult $parserResult
|
||||
* @param array $queryComponents
|
||||
*/
|
||||
public function __construct($query, $parserResult, array $queryComponents)
|
||||
{
|
||||
$this->platform = $query->getEntityManager()->getConnection()->getDatabasePlatform();
|
||||
$this->rsm = $parserResult->getResultSetMapping();
|
||||
$this->queryComponents = $queryComponents;
|
||||
|
||||
parent::__construct($query, $parserResult, $queryComponents);
|
||||
}
|
||||
|
||||
/**
|
||||
* Walks down a SelectStatement AST node, wrapping it in a COUNT (SELECT DISTINCT).
|
||||
*
|
||||
* Note that the ORDER BY clause is not removed. Many SQL implementations (e.g. MySQL)
|
||||
* are able to cache subqueries. By keeping the ORDER BY clause intact, the limitSubQuery
|
||||
* that will most likely be executed next can be read from the native SQL cache.
|
||||
*
|
||||
* @param SelectStatement $AST
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function walkSelectStatement(SelectStatement $AST)
|
||||
{
|
||||
if ($this->platform->getName() === "mssql") {
|
||||
$AST->orderByClause = null;
|
||||
}
|
||||
|
||||
$sql = parent::walkSelectStatement($AST);
|
||||
|
||||
if ($AST->groupByClause) {
|
||||
return sprintf(
|
||||
'SELECT %s AS dctrn_count FROM (%s) dctrn_table',
|
||||
$this->platform->getCountExpression('*'),
|
||||
$sql
|
||||
);
|
||||
}
|
||||
|
||||
// Find out the SQL alias of the identifier column of the root entity
|
||||
// It may be possible to make this work with multiple root entities but that
|
||||
// would probably require issuing multiple queries or doing a UNION SELECT
|
||||
// so for now, It's not supported.
|
||||
|
||||
// Get the root entity and alias from the AST fromClause
|
||||
$from = $AST->fromClause->identificationVariableDeclarations;
|
||||
if (count($from) > 1) {
|
||||
throw new \RuntimeException("Cannot count query which selects two FROM components, cannot make distinction");
|
||||
}
|
||||
|
||||
$fromRoot = reset($from);
|
||||
$rootAlias = $fromRoot->rangeVariableDeclaration->aliasIdentificationVariable;
|
||||
$rootClass = $this->queryComponents[$rootAlias]['metadata'];
|
||||
$rootIdentifier = $rootClass->identifier;
|
||||
|
||||
// For every identifier, find out the SQL alias by combing through the ResultSetMapping
|
||||
$sqlIdentifier = array();
|
||||
foreach ($rootIdentifier as $property) {
|
||||
if (isset($rootClass->fieldMappings[$property])) {
|
||||
foreach (array_keys($this->rsm->fieldMappings, $property) as $alias) {
|
||||
if ($this->rsm->columnOwnerMap[$alias] == $rootAlias) {
|
||||
$sqlIdentifier[$property] = $alias;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($rootClass->associationMappings[$property])) {
|
||||
$joinColumn = $rootClass->associationMappings[$property]['joinColumns'][0]['name'];
|
||||
|
||||
foreach (array_keys($this->rsm->metaMappings, $joinColumn) as $alias) {
|
||||
if ($this->rsm->columnOwnerMap[$alias] == $rootAlias) {
|
||||
$sqlIdentifier[$property] = $alias;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (count($rootIdentifier) != count($sqlIdentifier)) {
|
||||
throw new \RuntimeException(sprintf(
|
||||
'Not all identifier properties can be found in the ResultSetMapping: %s',
|
||||
implode(', ', array_diff($rootIdentifier, array_keys($sqlIdentifier)))
|
||||
));
|
||||
}
|
||||
|
||||
// Build the counter query
|
||||
return sprintf('SELECT %s AS dctrn_count FROM (SELECT DISTINCT %s FROM (%s) dctrn_result) dctrn_table',
|
||||
$this->platform->getCountExpression('*'),
|
||||
implode(', ', $sqlIdentifier),
|
||||
$sql
|
||||
);
|
||||
}
|
||||
}
|
||||
88
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Pagination/CountWalker.php
vendored
Normal file
88
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Pagination/CountWalker.php
vendored
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
<?php
|
||||
/**
|
||||
* Doctrine ORM
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to kontakt@beberlei.de so I can send you a copy immediately.
|
||||
*/
|
||||
|
||||
namespace Doctrine\ORM\Tools\Pagination;
|
||||
|
||||
use Doctrine\ORM\Query\TreeWalkerAdapter;
|
||||
use Doctrine\ORM\Query\AST\SelectStatement;
|
||||
use Doctrine\ORM\Query\AST\SelectExpression;
|
||||
use Doctrine\ORM\Query\AST\PathExpression;
|
||||
use Doctrine\ORM\Query\AST\AggregateExpression;
|
||||
|
||||
/**
|
||||
* Replaces the selectClause of the AST with a COUNT statement.
|
||||
*
|
||||
* @category DoctrineExtensions
|
||||
* @package DoctrineExtensions\Paginate
|
||||
* @author David Abdemoulaie <dave@hobodave.com>
|
||||
* @copyright Copyright (c) 2010 David Abdemoulaie (http://hobodave.com/)
|
||||
* @license http://hobodave.com/license.txt New BSD License
|
||||
*/
|
||||
class CountWalker extends TreeWalkerAdapter
|
||||
{
|
||||
/**
|
||||
* Distinct mode hint name.
|
||||
*/
|
||||
const HINT_DISTINCT = 'doctrine_paginator.distinct';
|
||||
|
||||
/**
|
||||
* Walks down a SelectStatement AST node, modifying it to retrieve a COUNT.
|
||||
*
|
||||
* @param SelectStatement $AST
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function walkSelectStatement(SelectStatement $AST)
|
||||
{
|
||||
if ($AST->havingClause) {
|
||||
throw new \RuntimeException('Cannot count query that uses a HAVING clause. Use the output walkers for pagination');
|
||||
}
|
||||
|
||||
$queryComponents = $this->_getQueryComponents();
|
||||
// Get the root entity and alias from the AST fromClause
|
||||
$from = $AST->fromClause->identificationVariableDeclarations;
|
||||
|
||||
if (count($from) > 1) {
|
||||
throw new \RuntimeException("Cannot count query which selects two FROM components, cannot make distinction");
|
||||
}
|
||||
|
||||
$fromRoot = reset($from);
|
||||
$rootAlias = $fromRoot->rangeVariableDeclaration->aliasIdentificationVariable;
|
||||
$rootClass = $queryComponents[$rootAlias]['metadata'];
|
||||
$identifierFieldName = $rootClass->getSingleIdentifierFieldName();
|
||||
|
||||
$pathType = PathExpression::TYPE_STATE_FIELD;
|
||||
if (isset($rootClass->associationMappings[$identifierFieldName])) {
|
||||
$pathType = PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION;
|
||||
}
|
||||
|
||||
$pathExpression = new PathExpression(
|
||||
PathExpression::TYPE_STATE_FIELD | PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION, $rootAlias,
|
||||
$identifierFieldName
|
||||
);
|
||||
$pathExpression->type = $pathType;
|
||||
|
||||
$distinct = $this->_getQuery()->getHint(self::HINT_DISTINCT);
|
||||
$AST->selectClause->selectExpressions = array(
|
||||
new SelectExpression(
|
||||
new AggregateExpression('count', $pathExpression, $distinct), null
|
||||
)
|
||||
);
|
||||
|
||||
// ORDER BY is not needed, only increases query execution through unnecessary sorting.
|
||||
$AST->orderByClause = null;
|
||||
}
|
||||
}
|
||||
|
||||
589
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php
vendored
Normal file
589
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php
vendored
Normal file
|
|
@ -0,0 +1,589 @@
|
|||
<?php
|
||||
/**
|
||||
* Doctrine ORM
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE.txt.
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to kontakt@beberlei.de so I can send you a copy immediately.
|
||||
*/
|
||||
|
||||
namespace Doctrine\ORM\Tools\Pagination;
|
||||
|
||||
use Doctrine\DBAL\Platforms\DB2Platform;
|
||||
use Doctrine\DBAL\Platforms\OraclePlatform;
|
||||
use Doctrine\DBAL\Platforms\PostgreSqlPlatform;
|
||||
use Doctrine\DBAL\Platforms\SQLAnywherePlatform;
|
||||
use Doctrine\DBAL\Platforms\SQLServerPlatform;
|
||||
use Doctrine\ORM\Query\AST\ArithmeticExpression;
|
||||
use Doctrine\ORM\Query\AST\ArithmeticFactor;
|
||||
use Doctrine\ORM\Query\AST\ArithmeticTerm;
|
||||
use Doctrine\ORM\Query\AST\Literal;
|
||||
use Doctrine\ORM\Query\AST\OrderByClause;
|
||||
use Doctrine\ORM\Query\AST\OrderByItem;
|
||||
use Doctrine\ORM\Query\AST\PartialObjectExpression;
|
||||
use Doctrine\ORM\Query\AST\PathExpression;
|
||||
use Doctrine\ORM\Query\AST\SelectExpression;
|
||||
use Doctrine\ORM\Query\AST\SimpleArithmeticExpression;
|
||||
use Doctrine\ORM\Query\Expr\OrderBy;
|
||||
use Doctrine\ORM\Query\Expr\Select;
|
||||
use Doctrine\ORM\Query\SqlWalker;
|
||||
use Doctrine\ORM\Query\AST\SelectStatement;
|
||||
|
||||
/**
|
||||
* Wraps the query in order to select root entity IDs for pagination.
|
||||
*
|
||||
* Given a DQL like `SELECT u FROM User u` it will generate an SQL query like:
|
||||
* SELECT DISTINCT <id> FROM (<original SQL>) LIMIT x OFFSET y
|
||||
*
|
||||
* Works with composite keys but cannot deal with queries that have multiple
|
||||
* root entities (e.g. `SELECT f, b from Foo, Bar`)
|
||||
*
|
||||
* @author Sander Marechal <s.marechal@jejik.com>
|
||||
*/
|
||||
class LimitSubqueryOutputWalker extends SqlWalker
|
||||
{
|
||||
/**
|
||||
* @var \Doctrine\DBAL\Platforms\AbstractPlatform
|
||||
*/
|
||||
private $platform;
|
||||
|
||||
/**
|
||||
* @var \Doctrine\ORM\Query\ResultSetMapping
|
||||
*/
|
||||
private $rsm;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $queryComponents;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $firstResult;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $maxResults;
|
||||
|
||||
/**
|
||||
* @var \Doctrine\ORM\EntityManager
|
||||
*/
|
||||
private $em;
|
||||
|
||||
/**
|
||||
* The quote strategy.
|
||||
*
|
||||
* @var \Doctrine\ORM\Mapping\QuoteStrategy
|
||||
*/
|
||||
private $quoteStrategy;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $orderByPathExpressions = [];
|
||||
|
||||
/**
|
||||
* @var bool We don't want to add path expressions from sub-selects into the select clause of the containing query.
|
||||
* This state flag simply keeps track on whether we are walking on a subquery or not
|
||||
*/
|
||||
private $inSubSelect = false;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Stores various parameters that are otherwise unavailable
|
||||
* because Doctrine\ORM\Query\SqlWalker keeps everything private without
|
||||
* accessors.
|
||||
*
|
||||
* @param \Doctrine\ORM\Query $query
|
||||
* @param \Doctrine\ORM\Query\ParserResult $parserResult
|
||||
* @param array $queryComponents
|
||||
*/
|
||||
public function __construct($query, $parserResult, array $queryComponents)
|
||||
{
|
||||
$this->platform = $query->getEntityManager()->getConnection()->getDatabasePlatform();
|
||||
$this->rsm = $parserResult->getResultSetMapping();
|
||||
$this->queryComponents = $queryComponents;
|
||||
|
||||
// Reset limit and offset
|
||||
$this->firstResult = $query->getFirstResult();
|
||||
$this->maxResults = $query->getMaxResults();
|
||||
$query->setFirstResult(null)->setMaxResults(null);
|
||||
|
||||
$this->em = $query->getEntityManager();
|
||||
$this->quoteStrategy = $this->em->getConfiguration()->getQuoteStrategy();
|
||||
|
||||
parent::__construct($query, $parserResult, $queryComponents);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the platform supports the ROW_NUMBER window function.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function platformSupportsRowNumber()
|
||||
{
|
||||
return $this->platform instanceof PostgreSqlPlatform
|
||||
|| $this->platform instanceof SQLServerPlatform
|
||||
|| $this->platform instanceof OraclePlatform
|
||||
|| $this->platform instanceof SQLAnywherePlatform
|
||||
|| $this->platform instanceof DB2Platform
|
||||
|| (method_exists($this->platform, 'supportsRowNumberFunction')
|
||||
&& $this->platform->supportsRowNumberFunction());
|
||||
}
|
||||
|
||||
/**
|
||||
* Rebuilds a select statement's order by clause for use in a
|
||||
* ROW_NUMBER() OVER() expression.
|
||||
*
|
||||
* @param SelectStatement $AST
|
||||
*/
|
||||
private function rebuildOrderByForRowNumber(SelectStatement $AST)
|
||||
{
|
||||
$orderByClause = $AST->orderByClause;
|
||||
$selectAliasToExpressionMap = [];
|
||||
// Get any aliases that are available for select expressions.
|
||||
foreach ($AST->selectClause->selectExpressions as $selectExpression) {
|
||||
$selectAliasToExpressionMap[$selectExpression->fieldIdentificationVariable] = $selectExpression->expression;
|
||||
}
|
||||
|
||||
// Rebuild string orderby expressions to use the select expression they're referencing
|
||||
foreach ($orderByClause->orderByItems as $orderByItem) {
|
||||
if (is_string($orderByItem->expression) && isset($selectAliasToExpressionMap[$orderByItem->expression])) {
|
||||
$orderByItem->expression = $selectAliasToExpressionMap[$orderByItem->expression];
|
||||
}
|
||||
}
|
||||
$func = new RowNumberOverFunction('dctrn_rownum');
|
||||
$func->orderByClause = $AST->orderByClause;
|
||||
$AST->selectClause->selectExpressions[] = new SelectExpression($func, 'dctrn_rownum', true);
|
||||
|
||||
// No need for an order by clause, we'll order by rownum in the outer query.
|
||||
$AST->orderByClause = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Walks down a SelectStatement AST node, wrapping it in a SELECT DISTINCT.
|
||||
*
|
||||
* @param SelectStatement $AST
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function walkSelectStatement(SelectStatement $AST)
|
||||
{
|
||||
if ($this->platformSupportsRowNumber()) {
|
||||
return $this->walkSelectStatementWithRowNumber($AST);
|
||||
}
|
||||
return $this->walkSelectStatementWithoutRowNumber($AST);
|
||||
}
|
||||
|
||||
/**
|
||||
* Walks down a SelectStatement AST node, wrapping it in a SELECT DISTINCT.
|
||||
* This method is for use with platforms which support ROW_NUMBER.
|
||||
*
|
||||
* @param SelectStatement $AST
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function walkSelectStatementWithRowNumber(SelectStatement $AST)
|
||||
{
|
||||
$hasOrderBy = false;
|
||||
$outerOrderBy = ' ORDER BY dctrn_minrownum ASC';
|
||||
$orderGroupBy = '';
|
||||
if ($AST->orderByClause instanceof OrderByClause) {
|
||||
$hasOrderBy = true;
|
||||
$this->rebuildOrderByForRowNumber($AST);
|
||||
}
|
||||
|
||||
$innerSql = $this->getInnerSQL($AST);
|
||||
|
||||
$sqlIdentifier = $this->getSQLIdentifier($AST);
|
||||
|
||||
if ($hasOrderBy) {
|
||||
$orderGroupBy = ' GROUP BY ' . implode(', ', $sqlIdentifier);
|
||||
$sqlIdentifier[] = 'MIN(' . $this->walkResultVariable('dctrn_rownum') . ') AS dctrn_minrownum';
|
||||
}
|
||||
|
||||
// Build the counter query
|
||||
$sql = sprintf(
|
||||
'SELECT DISTINCT %s FROM (%s) dctrn_result',
|
||||
implode(', ', $sqlIdentifier),
|
||||
$innerSql
|
||||
);
|
||||
|
||||
if ($hasOrderBy) {
|
||||
$sql .= $orderGroupBy . $outerOrderBy;
|
||||
}
|
||||
|
||||
// Apply the limit and offset.
|
||||
$sql = $this->platform->modifyLimitQuery(
|
||||
$sql,
|
||||
$this->maxResults,
|
||||
$this->firstResult
|
||||
);
|
||||
|
||||
// Add the columns to the ResultSetMapping. It's not really nice but
|
||||
// it works. Preferably I'd clear the RSM or simply create a new one
|
||||
// but that is not possible from inside the output walker, so we dirty
|
||||
// up the one we have.
|
||||
foreach ($sqlIdentifier as $property => $alias) {
|
||||
$this->rsm->addScalarResult($alias, $property);
|
||||
}
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Walks down a SelectStatement AST node, wrapping it in a SELECT DISTINCT.
|
||||
* This method is for platforms which DO NOT support ROW_NUMBER.
|
||||
*
|
||||
* @param SelectStatement $AST
|
||||
* @param bool $addMissingItemsFromOrderByToSelect
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function walkSelectStatementWithoutRowNumber(SelectStatement $AST, $addMissingItemsFromOrderByToSelect = true)
|
||||
{
|
||||
// We don't want to call this recursively!
|
||||
if ($AST->orderByClause instanceof OrderByClause && $addMissingItemsFromOrderByToSelect) {
|
||||
// In the case of ordering a query by columns from joined tables, we
|
||||
// must add those columns to the select clause of the query BEFORE
|
||||
// the SQL is generated.
|
||||
$this->addMissingItemsFromOrderByToSelect($AST);
|
||||
}
|
||||
|
||||
// Remove order by clause from the inner query
|
||||
// It will be re-appended in the outer select generated by this method
|
||||
$orderByClause = $AST->orderByClause;
|
||||
$AST->orderByClause = null;
|
||||
|
||||
$innerSql = $this->getInnerSQL($AST);
|
||||
|
||||
$sqlIdentifier = $this->getSQLIdentifier($AST);
|
||||
|
||||
// Build the counter query
|
||||
$sql = sprintf('SELECT DISTINCT %s FROM (%s) dctrn_result',
|
||||
implode(', ', $sqlIdentifier), $innerSql);
|
||||
|
||||
// http://www.doctrine-project.org/jira/browse/DDC-1958
|
||||
$sql = $this->preserveSqlOrdering($sqlIdentifier, $innerSql, $sql, $orderByClause);
|
||||
|
||||
// Apply the limit and offset.
|
||||
$sql = $this->platform->modifyLimitQuery(
|
||||
$sql, $this->maxResults, $this->firstResult
|
||||
);
|
||||
|
||||
// Add the columns to the ResultSetMapping. It's not really nice but
|
||||
// it works. Preferably I'd clear the RSM or simply create a new one
|
||||
// but that is not possible from inside the output walker, so we dirty
|
||||
// up the one we have.
|
||||
foreach ($sqlIdentifier as $property => $alias) {
|
||||
$this->rsm->addScalarResult($alias, $property);
|
||||
}
|
||||
|
||||
// Restore orderByClause
|
||||
$AST->orderByClause = $orderByClause;
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds all PathExpressions in an AST's OrderByClause, and ensures that
|
||||
* the referenced fields are present in the SelectClause of the passed AST.
|
||||
*
|
||||
* @param SelectStatement $AST
|
||||
*/
|
||||
private function addMissingItemsFromOrderByToSelect(SelectStatement $AST)
|
||||
{
|
||||
$this->orderByPathExpressions = [];
|
||||
|
||||
// We need to do this in another walker because otherwise we'll end up
|
||||
// polluting the state of this one.
|
||||
$walker = clone $this;
|
||||
|
||||
// This will populate $orderByPathExpressions via
|
||||
// LimitSubqueryOutputWalker::walkPathExpression, which will be called
|
||||
// as the select statement is walked. We'll end up with an array of all
|
||||
// path expressions referenced in the query.
|
||||
$walker->walkSelectStatementWithoutRowNumber($AST, false);
|
||||
$orderByPathExpressions = $walker->getOrderByPathExpressions();
|
||||
|
||||
// Get a map of referenced identifiers to field names.
|
||||
$selects = [];
|
||||
foreach ($orderByPathExpressions as $pathExpression) {
|
||||
$idVar = $pathExpression->identificationVariable;
|
||||
$field = $pathExpression->field;
|
||||
if (!isset($selects[$idVar])) {
|
||||
$selects[$idVar] = [];
|
||||
}
|
||||
$selects[$idVar][$field] = true;
|
||||
}
|
||||
|
||||
// Loop the select clause of the AST and exclude items from $select
|
||||
// that are already being selected in the query.
|
||||
foreach ($AST->selectClause->selectExpressions as $selectExpression) {
|
||||
if ($selectExpression instanceof SelectExpression) {
|
||||
$idVar = $selectExpression->expression;
|
||||
if (!is_string($idVar)) {
|
||||
continue;
|
||||
}
|
||||
$field = $selectExpression->fieldIdentificationVariable;
|
||||
if ($field === null) {
|
||||
// No need to add this select, as we're already fetching the whole object.
|
||||
unset($selects[$idVar]);
|
||||
} else {
|
||||
unset($selects[$idVar][$field]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add select items which were not excluded to the AST's select clause.
|
||||
foreach ($selects as $idVar => $fields) {
|
||||
$AST->selectClause->selectExpressions[] = new SelectExpression(new PartialObjectExpression($idVar, array_keys($fields)), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates new SQL for statements with an order by clause
|
||||
*
|
||||
* @param array $sqlIdentifier
|
||||
* @param string $innerSql
|
||||
* @param string $sql
|
||||
* @param OrderByClause $orderByClause
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function preserveSqlOrdering(array $sqlIdentifier, $innerSql, $sql, $orderByClause)
|
||||
{
|
||||
// If the sql statement has an order by clause, we need to wrap it in a new select distinct
|
||||
// statement
|
||||
if (! $orderByClause instanceof OrderByClause) {
|
||||
return $sql;
|
||||
}
|
||||
|
||||
// Rebuild the order by clause to work in the scope of the new select statement
|
||||
/* @var array $orderBy an array of rebuilt order by items */
|
||||
$orderBy = $this->rebuildOrderByClauseForOuterScope($orderByClause);
|
||||
|
||||
// Build the select distinct statement
|
||||
$sql = sprintf(
|
||||
'SELECT DISTINCT %s FROM (%s) dctrn_result ORDER BY %s',
|
||||
implode(', ', $sqlIdentifier),
|
||||
$innerSql,
|
||||
implode(', ', $orderBy)
|
||||
);
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a new order by clause that works in the scope of a select query wrapping the original
|
||||
*
|
||||
* @param OrderByClause $orderByClause
|
||||
* @return array
|
||||
*/
|
||||
private function rebuildOrderByClauseForOuterScope(OrderByClause $orderByClause)
|
||||
{
|
||||
$dqlAliasToSqlTableAliasMap
|
||||
= $searchPatterns
|
||||
= $replacements
|
||||
= $dqlAliasToClassMap
|
||||
= $selectListAdditions
|
||||
= $orderByItems
|
||||
= [];
|
||||
|
||||
// Generate DQL alias -> SQL table alias mapping
|
||||
foreach(array_keys($this->rsm->aliasMap) as $dqlAlias) {
|
||||
$dqlAliasToClassMap[$dqlAlias] = $class = $this->queryComponents[$dqlAlias]['metadata'];
|
||||
$dqlAliasToSqlTableAliasMap[$dqlAlias] = $this->getSQLTableAlias($class->getTableName(), $dqlAlias);
|
||||
}
|
||||
|
||||
// Pattern to find table path expressions in the order by clause
|
||||
$fieldSearchPattern = '/(?<![a-z0-9_])%s\.%s(?![a-z0-9_])/i';
|
||||
|
||||
// Generate search patterns for each field's path expression in the order by clause
|
||||
foreach($this->rsm->fieldMappings as $fieldAlias => $fieldName) {
|
||||
$dqlAliasForFieldAlias = $this->rsm->columnOwnerMap[$fieldAlias];
|
||||
$class = $dqlAliasToClassMap[$dqlAliasForFieldAlias];
|
||||
|
||||
// If the field is from a joined child table, we won't be ordering
|
||||
// on it.
|
||||
if (!isset($class->fieldMappings[$fieldName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$fieldMapping = $class->fieldMappings[$fieldName];
|
||||
|
||||
// Get the proper column name as will appear in the select list
|
||||
$columnName = $this->quoteStrategy->getColumnName(
|
||||
$fieldName,
|
||||
$dqlAliasToClassMap[$dqlAliasForFieldAlias],
|
||||
$this->em->getConnection()->getDatabasePlatform()
|
||||
);
|
||||
|
||||
// Get the SQL table alias for the entity and field
|
||||
$sqlTableAliasForFieldAlias = $dqlAliasToSqlTableAliasMap[$dqlAliasForFieldAlias];
|
||||
if (isset($fieldMapping['declared']) && $fieldMapping['declared'] !== $class->name) {
|
||||
// Field was declared in a parent class, so we need to get the proper SQL table alias
|
||||
// for the joined parent table.
|
||||
$otherClassMetadata = $this->em->getClassMetadata($fieldMapping['declared']);
|
||||
if (!$otherClassMetadata->isMappedSuperclass) {
|
||||
$sqlTableAliasForFieldAlias = $this->getSQLTableAlias($otherClassMetadata->getTableName(), $dqlAliasForFieldAlias);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Compose search/replace patterns
|
||||
$searchPatterns[] = sprintf($fieldSearchPattern, $sqlTableAliasForFieldAlias, $columnName);
|
||||
$replacements[] = $fieldAlias;
|
||||
}
|
||||
|
||||
foreach($orderByClause->orderByItems as $orderByItem) {
|
||||
// Walk order by item to get string representation of it
|
||||
$orderByItemString = $this->walkOrderByItem($orderByItem);
|
||||
|
||||
// Replace path expressions in the order by clause with their column alias
|
||||
$orderByItemString = preg_replace($searchPatterns, $replacements, $orderByItemString);
|
||||
|
||||
$orderByItems[] = $orderByItemString;
|
||||
}
|
||||
|
||||
return $orderByItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* getter for $orderByPathExpressions
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getOrderByPathExpressions()
|
||||
{
|
||||
return $this->orderByPathExpressions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SelectStatement $AST
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws \Doctrine\ORM\OptimisticLockException
|
||||
* @throws \Doctrine\ORM\Query\QueryException
|
||||
*/
|
||||
private function getInnerSQL(SelectStatement $AST)
|
||||
{
|
||||
// Set every select expression as visible(hidden = false) to
|
||||
// make $AST have scalar mappings properly - this is relevant for referencing selected
|
||||
// fields from outside the subquery, for example in the ORDER BY segment
|
||||
$hiddens = [];
|
||||
|
||||
foreach ($AST->selectClause->selectExpressions as $idx => $expr) {
|
||||
$hiddens[$idx] = $expr->hiddenAliasResultVariable;
|
||||
$expr->hiddenAliasResultVariable = false;
|
||||
}
|
||||
|
||||
$innerSql = parent::walkSelectStatement($AST);
|
||||
|
||||
// Restore hiddens
|
||||
foreach ($AST->selectClause->selectExpressions as $idx => $expr) {
|
||||
$expr->hiddenAliasResultVariable = $hiddens[$idx];
|
||||
}
|
||||
|
||||
return $innerSql;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SelectStatement $AST
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getSQLIdentifier(SelectStatement $AST)
|
||||
{
|
||||
// Find out the SQL alias of the identifier column of the root entity.
|
||||
// It may be possible to make this work with multiple root entities but that
|
||||
// would probably require issuing multiple queries or doing a UNION SELECT.
|
||||
// So for now, it's not supported.
|
||||
|
||||
// Get the root entity and alias from the AST fromClause.
|
||||
$from = $AST->fromClause->identificationVariableDeclarations;
|
||||
if (count($from) !== 1) {
|
||||
throw new \RuntimeException('Cannot count query which selects two FROM components, cannot make distinction');
|
||||
}
|
||||
|
||||
$fromRoot = reset($from);
|
||||
$rootAlias = $fromRoot->rangeVariableDeclaration->aliasIdentificationVariable;
|
||||
$rootClass = $this->queryComponents[$rootAlias]['metadata'];
|
||||
$rootIdentifier = $rootClass->identifier;
|
||||
|
||||
// For every identifier, find out the SQL alias by combing through the ResultSetMapping
|
||||
$sqlIdentifier = [];
|
||||
foreach ($rootIdentifier as $property) {
|
||||
if (isset($rootClass->fieldMappings[$property])) {
|
||||
foreach (array_keys($this->rsm->fieldMappings, $property) as $alias) {
|
||||
if ($this->rsm->columnOwnerMap[$alias] == $rootAlias) {
|
||||
$sqlIdentifier[$property] = $alias;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($rootClass->associationMappings[$property])) {
|
||||
$joinColumn = $rootClass->associationMappings[$property]['joinColumns'][0]['name'];
|
||||
|
||||
foreach (array_keys($this->rsm->metaMappings, $joinColumn) as $alias) {
|
||||
if ($this->rsm->columnOwnerMap[$alias] == $rootAlias) {
|
||||
$sqlIdentifier[$property] = $alias;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (count($sqlIdentifier) === 0) {
|
||||
throw new \RuntimeException('The Paginator does not support Queries which only yield ScalarResults.');
|
||||
}
|
||||
|
||||
if (count($rootIdentifier) != count($sqlIdentifier)) {
|
||||
throw new \RuntimeException(sprintf(
|
||||
'Not all identifier properties can be found in the ResultSetMapping: %s',
|
||||
implode(', ', array_diff($rootIdentifier, array_keys($sqlIdentifier)))
|
||||
));
|
||||
}
|
||||
|
||||
return $sqlIdentifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function walkPathExpression($pathExpr)
|
||||
{
|
||||
if (!$this->inSubSelect && !$this->platformSupportsRowNumber() && !in_array($pathExpr, $this->orderByPathExpressions)) {
|
||||
$this->orderByPathExpressions[] = $pathExpr;
|
||||
}
|
||||
|
||||
return parent::walkPathExpression($pathExpr);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function walkSubSelect($subselect)
|
||||
{
|
||||
$this->inSubSelect = true;
|
||||
|
||||
$sql = parent::walkSubselect($subselect);
|
||||
|
||||
$this->inSubSelect = false;
|
||||
|
||||
return $sql;
|
||||
}
|
||||
}
|
||||
175
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryWalker.php
vendored
Normal file
175
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryWalker.php
vendored
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Doctrine ORM
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE. This license can also be viewed
|
||||
* at http://hobodave.com/license.txt
|
||||
*
|
||||
* @category DoctrineExtensions
|
||||
* @package DoctrineExtensions\Paginate
|
||||
* @author David Abdemoulaie <dave@hobodave.com>
|
||||
* @copyright Copyright (c) 2010 David Abdemoulaie (http://hobodave.com/)
|
||||
* @license http://hobodave.com/license.txt New BSD License
|
||||
*/
|
||||
|
||||
namespace Doctrine\ORM\Tools\Pagination;
|
||||
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
use Doctrine\ORM\Mapping\ClassMetadataInfo;
|
||||
use Doctrine\ORM\ORMException;
|
||||
use Doctrine\ORM\Query;
|
||||
use Doctrine\ORM\Query\TreeWalkerAdapter;
|
||||
use Doctrine\ORM\Query\AST\Functions\IdentityFunction;
|
||||
use Doctrine\ORM\Query\AST\PathExpression;
|
||||
use Doctrine\ORM\Query\AST\SelectExpression;
|
||||
use Doctrine\ORM\Query\AST\SelectStatement;
|
||||
|
||||
/**
|
||||
* Replaces the selectClause of the AST with a SELECT DISTINCT root.id equivalent.
|
||||
*
|
||||
* @category DoctrineExtensions
|
||||
* @package DoctrineExtensions\Paginate
|
||||
* @author David Abdemoulaie <dave@hobodave.com>
|
||||
* @copyright Copyright (c) 2010 David Abdemoulaie (http://hobodave.com/)
|
||||
* @license http://hobodave.com/license.txt New BSD License
|
||||
*/
|
||||
class LimitSubqueryWalker extends TreeWalkerAdapter
|
||||
{
|
||||
/**
|
||||
* ID type hint.
|
||||
*/
|
||||
const IDENTIFIER_TYPE = 'doctrine_paginator.id.type';
|
||||
|
||||
/**
|
||||
* Counter for generating unique order column aliases.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $_aliasCounter = 0;
|
||||
|
||||
/**
|
||||
* Walks down a SelectStatement AST node, modifying it to retrieve DISTINCT ids
|
||||
* of the root Entity.
|
||||
*
|
||||
* @param SelectStatement $AST
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function walkSelectStatement(SelectStatement $AST)
|
||||
{
|
||||
$queryComponents = $this->_getQueryComponents();
|
||||
// Get the root entity and alias from the AST fromClause
|
||||
$from = $AST->fromClause->identificationVariableDeclarations;
|
||||
$fromRoot = reset($from);
|
||||
$rootAlias = $fromRoot->rangeVariableDeclaration->aliasIdentificationVariable;
|
||||
$rootClass = $queryComponents[$rootAlias]['metadata'];
|
||||
$selectExpressions = array();
|
||||
|
||||
$this->validate($AST);
|
||||
|
||||
foreach ($queryComponents as $dqlAlias => $qComp) {
|
||||
// Preserve mixed data in query for ordering.
|
||||
if (isset($qComp['resultVariable'])) {
|
||||
$selectExpressions[] = new SelectExpression($qComp['resultVariable'], $dqlAlias);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$identifier = $rootClass->getSingleIdentifierFieldName();
|
||||
|
||||
if (isset($rootClass->associationMappings[$identifier])) {
|
||||
throw new \RuntimeException("Paginating an entity with foreign key as identifier only works when using the Output Walkers. Call Paginator#setUseOutputWalkers(true) before iterating the paginator.");
|
||||
}
|
||||
|
||||
$this->_getQuery()->setHint(
|
||||
self::IDENTIFIER_TYPE,
|
||||
Type::getType($rootClass->getTypeOfField($identifier))
|
||||
);
|
||||
|
||||
$pathExpression = new PathExpression(
|
||||
PathExpression::TYPE_STATE_FIELD | PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION,
|
||||
$rootAlias,
|
||||
$identifier
|
||||
);
|
||||
$pathExpression->type = PathExpression::TYPE_STATE_FIELD;
|
||||
|
||||
array_unshift($selectExpressions, new SelectExpression($pathExpression, '_dctrn_id'));
|
||||
$AST->selectClause->selectExpressions = $selectExpressions;
|
||||
|
||||
if (isset($AST->orderByClause)) {
|
||||
foreach ($AST->orderByClause->orderByItems as $item) {
|
||||
if ( ! $item->expression instanceof PathExpression) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$AST->selectClause->selectExpressions[] = new SelectExpression(
|
||||
$this->createSelectExpressionItem($item->expression),
|
||||
'_dctrn_ord' . $this->_aliasCounter++
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$AST->selectClause->isDistinct = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the AST to ensure that this walker is able to properly manipulate it.
|
||||
*
|
||||
* @param SelectStatement $AST
|
||||
*/
|
||||
private function validate(SelectStatement $AST)
|
||||
{
|
||||
// Prevent LimitSubqueryWalker from being used with queries that include
|
||||
// a limit, a fetched to-many join, and an order by condition that
|
||||
// references a column from the fetch joined table.
|
||||
$queryComponents = $this->getQueryComponents();
|
||||
$query = $this->_getQuery();
|
||||
$from = $AST->fromClause->identificationVariableDeclarations;
|
||||
$fromRoot = reset($from);
|
||||
|
||||
if ($query instanceof Query
|
||||
&& $query->getMaxResults()
|
||||
&& $AST->orderByClause
|
||||
&& count($fromRoot->joins)) {
|
||||
// Check each orderby item.
|
||||
// TODO: check complex orderby items too...
|
||||
foreach ($AST->orderByClause->orderByItems as $orderByItem) {
|
||||
$expression = $orderByItem->expression;
|
||||
if ($orderByItem->expression instanceof PathExpression
|
||||
&& isset($queryComponents[$expression->identificationVariable])) {
|
||||
$queryComponent = $queryComponents[$expression->identificationVariable];
|
||||
if (isset($queryComponent['parent'])
|
||||
&& $queryComponent['relation']['type'] & ClassMetadataInfo::TO_MANY) {
|
||||
throw new \RuntimeException("Cannot select distinct identifiers from query with LIMIT and ORDER BY on a column from a fetch joined to-many association. Use output walkers.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve either an IdentityFunction (IDENTITY(u.assoc)) or a state field (u.name).
|
||||
*
|
||||
* @param \Doctrine\ORM\Query\AST\PathExpression $pathExpression
|
||||
*
|
||||
* @return \Doctrine\ORM\Query\AST\Functions\IdentityFunction
|
||||
*/
|
||||
private function createSelectExpressionItem(PathExpression $pathExpression)
|
||||
{
|
||||
if ($pathExpression->type === PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION) {
|
||||
$identity = new IdentityFunction('identity');
|
||||
|
||||
$identity->pathExpression = clone $pathExpression;
|
||||
|
||||
return $identity;
|
||||
}
|
||||
|
||||
return clone $pathExpression;
|
||||
}
|
||||
}
|
||||
279
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Pagination/Paginator.php
vendored
Normal file
279
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Pagination/Paginator.php
vendored
Normal file
|
|
@ -0,0 +1,279 @@
|
|||
<?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\ORM\Tools\Pagination;
|
||||
|
||||
use Doctrine\ORM\Query\Parser;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Doctrine\ORM\Query;
|
||||
use Doctrine\ORM\Query\ResultSetMapping;
|
||||
use Doctrine\ORM\NoResultException;
|
||||
|
||||
/**
|
||||
* The paginator can handle various complex scenarios with DQL.
|
||||
*
|
||||
* @author Pablo Díez <pablodip@gmail.com>
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @license New BSD
|
||||
*/
|
||||
class Paginator implements \Countable, \IteratorAggregate
|
||||
{
|
||||
/**
|
||||
* @var Query
|
||||
*/
|
||||
private $query;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $fetchJoinCollection;
|
||||
|
||||
/**
|
||||
* @var bool|null
|
||||
*/
|
||||
private $useOutputWalkers;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $count;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Query|QueryBuilder $query A Doctrine ORM query or query builder.
|
||||
* @param boolean $fetchJoinCollection Whether the query joins a collection (true by default).
|
||||
*/
|
||||
public function __construct($query, $fetchJoinCollection = true)
|
||||
{
|
||||
if ($query instanceof QueryBuilder) {
|
||||
$query = $query->getQuery();
|
||||
}
|
||||
|
||||
$this->query = $query;
|
||||
$this->fetchJoinCollection = (Boolean) $fetchJoinCollection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the query.
|
||||
*
|
||||
* @return Query
|
||||
*/
|
||||
public function getQuery()
|
||||
{
|
||||
return $this->query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the query joins a collection.
|
||||
*
|
||||
* @return boolean Whether the query joins a collection.
|
||||
*/
|
||||
public function getFetchJoinCollection()
|
||||
{
|
||||
return $this->fetchJoinCollection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the paginator will use an output walker.
|
||||
*
|
||||
* @return bool|null
|
||||
*/
|
||||
public function getUseOutputWalkers()
|
||||
{
|
||||
return $this->useOutputWalkers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the paginator will use an output walker.
|
||||
*
|
||||
* @param bool|null $useOutputWalkers
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setUseOutputWalkers($useOutputWalkers)
|
||||
{
|
||||
$this->useOutputWalkers = $useOutputWalkers;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
if ($this->count === null) {
|
||||
try {
|
||||
$this->count = array_sum(array_map('current', $this->getCountQuery()->getScalarResult()));
|
||||
} catch(NoResultException $e) {
|
||||
$this->count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->count;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getIterator()
|
||||
{
|
||||
$offset = $this->query->getFirstResult();
|
||||
$length = $this->query->getMaxResults();
|
||||
|
||||
if ($this->fetchJoinCollection) {
|
||||
$subQuery = $this->cloneQuery($this->query);
|
||||
|
||||
if ($this->useOutputWalker($subQuery)) {
|
||||
$subQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\LimitSubqueryOutputWalker');
|
||||
} else {
|
||||
$this->appendTreeWalker($subQuery, 'Doctrine\ORM\Tools\Pagination\LimitSubqueryWalker');
|
||||
}
|
||||
|
||||
$subQuery->setFirstResult($offset)->setMaxResults($length);
|
||||
|
||||
$ids = array_map('current', $subQuery->getScalarResult());
|
||||
|
||||
$whereInQuery = $this->cloneQuery($this->query);
|
||||
// don't do this for an empty id array
|
||||
if (count($ids) == 0) {
|
||||
return new \ArrayIterator(array());
|
||||
}
|
||||
|
||||
$this->appendTreeWalker($whereInQuery, 'Doctrine\ORM\Tools\Pagination\WhereInWalker');
|
||||
$whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, count($ids));
|
||||
$whereInQuery->setFirstResult(null)->setMaxResults(null);
|
||||
$whereInQuery->setParameter(WhereInWalker::PAGINATOR_ID_ALIAS, $ids);
|
||||
$whereInQuery->setCacheable($this->query->isCacheable());
|
||||
|
||||
$result = $whereInQuery->getResult($this->query->getHydrationMode());
|
||||
} else {
|
||||
$result = $this->cloneQuery($this->query)
|
||||
->setMaxResults($length)
|
||||
->setFirstResult($offset)
|
||||
->setCacheable($this->query->isCacheable())
|
||||
->getResult($this->query->getHydrationMode())
|
||||
;
|
||||
}
|
||||
|
||||
return new \ArrayIterator($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clones a query.
|
||||
*
|
||||
* @param Query $query The query.
|
||||
*
|
||||
* @return Query The cloned query.
|
||||
*/
|
||||
private function cloneQuery(Query $query)
|
||||
{
|
||||
/* @var $cloneQuery Query */
|
||||
$cloneQuery = clone $query;
|
||||
|
||||
$cloneQuery->setParameters(clone $query->getParameters());
|
||||
$cloneQuery->setCacheable(false);
|
||||
|
||||
foreach ($query->getHints() as $name => $value) {
|
||||
$cloneQuery->setHint($name, $value);
|
||||
}
|
||||
|
||||
return $cloneQuery;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether to use an output walker for the query.
|
||||
*
|
||||
* @param Query $query The query.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function useOutputWalker(Query $query)
|
||||
{
|
||||
if ($this->useOutputWalkers === null) {
|
||||
return (Boolean) $query->getHint(Query::HINT_CUSTOM_OUTPUT_WALKER) == false;
|
||||
}
|
||||
|
||||
return $this->useOutputWalkers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a custom tree walker to the tree walkers hint.
|
||||
*
|
||||
* @param Query $query
|
||||
* @param string $walkerClass
|
||||
*/
|
||||
private function appendTreeWalker(Query $query, $walkerClass)
|
||||
{
|
||||
$hints = $query->getHint(Query::HINT_CUSTOM_TREE_WALKERS);
|
||||
|
||||
if ($hints === false) {
|
||||
$hints = array();
|
||||
}
|
||||
|
||||
$hints[] = $walkerClass;
|
||||
$query->setHint(Query::HINT_CUSTOM_TREE_WALKERS, $hints);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Query prepared to count.
|
||||
*
|
||||
* @return Query
|
||||
*/
|
||||
private function getCountQuery()
|
||||
{
|
||||
/* @var $countQuery Query */
|
||||
$countQuery = $this->cloneQuery($this->query);
|
||||
|
||||
if ( ! $countQuery->hasHint(CountWalker::HINT_DISTINCT)) {
|
||||
$countQuery->setHint(CountWalker::HINT_DISTINCT, true);
|
||||
}
|
||||
|
||||
if ($this->useOutputWalker($countQuery)) {
|
||||
$platform = $countQuery->getEntityManager()->getConnection()->getDatabasePlatform(); // law of demeter win
|
||||
|
||||
$rsm = new ResultSetMapping();
|
||||
$rsm->addScalarResult($platform->getSQLResultCasing('dctrn_count'), 'count');
|
||||
|
||||
$countQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\CountOutputWalker');
|
||||
$countQuery->setResultSetMapping($rsm);
|
||||
} else {
|
||||
$this->appendTreeWalker($countQuery, 'Doctrine\ORM\Tools\Pagination\CountWalker');
|
||||
}
|
||||
|
||||
$countQuery->setFirstResult(null)->setMaxResults(null);
|
||||
|
||||
$parser = new Parser($countQuery);
|
||||
$parameterMappings = $parser->parse()->getParameterMappings();
|
||||
/* @var $parameters \Doctrine\Common\Collections\Collection|\Doctrine\ORM\Query\Parameter[] */
|
||||
$parameters = $countQuery->getParameters();
|
||||
|
||||
foreach ($parameters as $key => $parameter) {
|
||||
$parameterName = $parameter->getName();
|
||||
|
||||
if( ! (isset($parameterMappings[$parameterName]) || array_key_exists($parameterName, $parameterMappings))) {
|
||||
unset($parameters[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
$countQuery->setParameters($parameters);
|
||||
|
||||
return $countQuery;
|
||||
}
|
||||
}
|
||||
61
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Pagination/RowNumberOverFunction.php
vendored
Normal file
61
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Pagination/RowNumberOverFunction.php
vendored
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the MIT license. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace Doctrine\ORM\Tools\Pagination;
|
||||
|
||||
use Doctrine\ORM\ORMException;
|
||||
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
|
||||
|
||||
|
||||
/**
|
||||
* RowNumberOverFunction
|
||||
*
|
||||
* Provides ROW_NUMBER() OVER(ORDER BY...) construct for use in LimitSubqueryOutputWalker
|
||||
*
|
||||
* @since 2.5
|
||||
* @author Bill Schaller <bill@zeroedin.com>
|
||||
*/
|
||||
class RowNumberOverFunction extends FunctionNode
|
||||
{
|
||||
/**
|
||||
* @var \Doctrine\ORM\Query\AST\OrderByClause
|
||||
*/
|
||||
public $orderByClause;
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
|
||||
{
|
||||
return 'ROW_NUMBER() OVER(' . trim($sqlWalker->walkOrderByClause(
|
||||
$this->orderByClause
|
||||
)) . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*
|
||||
* @throws ORMException
|
||||
*/
|
||||
public function parse(\Doctrine\ORM\Query\Parser $parser)
|
||||
{
|
||||
throw new ORMException("The RowNumberOverFunction is not intended for, nor is it enabled for use in DQL.");
|
||||
}
|
||||
}
|
||||
142
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Pagination/WhereInWalker.php
vendored
Normal file
142
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Pagination/WhereInWalker.php
vendored
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
<?php
|
||||
/**
|
||||
* Doctrine ORM
|
||||
*
|
||||
* LICENSE
|
||||
*
|
||||
* This source file is subject to the new BSD license that is bundled
|
||||
* with this package in the file LICENSE. This license can also be viewed
|
||||
* at http://hobodave.com/license.txt
|
||||
*
|
||||
* @category DoctrineExtensions
|
||||
* @package DoctrineExtensions\Paginate
|
||||
* @author David Abdemoulaie <dave@hobodave.com>
|
||||
* @copyright Copyright (c) 2010 David Abdemoulaie (http://hobodave.com/)
|
||||
* @license http://hobodave.com/license.txt New BSD License
|
||||
*/
|
||||
|
||||
namespace Doctrine\ORM\Tools\Pagination;
|
||||
|
||||
use Doctrine\ORM\Query\AST\ArithmeticExpression;
|
||||
use Doctrine\ORM\Query\AST\SimpleArithmeticExpression;
|
||||
use Doctrine\ORM\Query\TreeWalkerAdapter;
|
||||
use Doctrine\ORM\Query\AST\SelectStatement;
|
||||
use Doctrine\ORM\Query\AST\PathExpression;
|
||||
use Doctrine\ORM\Query\AST\InExpression;
|
||||
use Doctrine\ORM\Query\AST\NullComparisonExpression;
|
||||
use Doctrine\ORM\Query\AST\InputParameter;
|
||||
use Doctrine\ORM\Query\AST\ConditionalPrimary;
|
||||
use Doctrine\ORM\Query\AST\ConditionalTerm;
|
||||
use Doctrine\ORM\Query\AST\ConditionalExpression;
|
||||
use Doctrine\ORM\Query\AST\ConditionalFactor;
|
||||
use Doctrine\ORM\Query\AST\WhereClause;
|
||||
|
||||
/**
|
||||
* Replaces the whereClause of the AST with a WHERE id IN (:foo_1, :foo_2) equivalent.
|
||||
*
|
||||
* @category DoctrineExtensions
|
||||
* @package DoctrineExtensions\Paginate
|
||||
* @author David Abdemoulaie <dave@hobodave.com>
|
||||
* @copyright Copyright (c) 2010 David Abdemoulaie (http://hobodave.com/)
|
||||
* @license http://hobodave.com/license.txt New BSD License
|
||||
*/
|
||||
class WhereInWalker extends TreeWalkerAdapter
|
||||
{
|
||||
/**
|
||||
* ID Count hint name.
|
||||
*/
|
||||
const HINT_PAGINATOR_ID_COUNT = 'doctrine.id.count';
|
||||
|
||||
/**
|
||||
* Primary key alias for query.
|
||||
*/
|
||||
const PAGINATOR_ID_ALIAS = 'dpid';
|
||||
|
||||
/**
|
||||
* Replaces the whereClause in the AST.
|
||||
*
|
||||
* Generates a clause equivalent to WHERE IN (:dpid_1, :dpid_2, ...)
|
||||
*
|
||||
* The parameter namespace (dpid) is defined by
|
||||
* the PAGINATOR_ID_ALIAS
|
||||
*
|
||||
* The total number of parameters is retrieved from
|
||||
* the HINT_PAGINATOR_ID_COUNT query hint.
|
||||
*
|
||||
* @param SelectStatement $AST
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function walkSelectStatement(SelectStatement $AST)
|
||||
{
|
||||
$queryComponents = $this->_getQueryComponents();
|
||||
// Get the root entity and alias from the AST fromClause
|
||||
$from = $AST->fromClause->identificationVariableDeclarations;
|
||||
|
||||
if (count($from) > 1) {
|
||||
throw new \RuntimeException("Cannot count query which selects two FROM components, cannot make distinction");
|
||||
}
|
||||
|
||||
$fromRoot = reset($from);
|
||||
$rootAlias = $fromRoot->rangeVariableDeclaration->aliasIdentificationVariable;
|
||||
$rootClass = $queryComponents[$rootAlias]['metadata'];
|
||||
$identifierFieldName = $rootClass->getSingleIdentifierFieldName();
|
||||
|
||||
$pathType = PathExpression::TYPE_STATE_FIELD;
|
||||
if (isset($rootClass->associationMappings[$identifierFieldName])) {
|
||||
$pathType = PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION;
|
||||
}
|
||||
|
||||
$pathExpression = new PathExpression(PathExpression::TYPE_STATE_FIELD | PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION, $rootAlias, $identifierFieldName);
|
||||
$pathExpression->type = $pathType;
|
||||
|
||||
$count = $this->_getQuery()->getHint(self::HINT_PAGINATOR_ID_COUNT);
|
||||
|
||||
if ($count > 0) {
|
||||
$arithmeticExpression = new ArithmeticExpression();
|
||||
$arithmeticExpression->simpleArithmeticExpression = new SimpleArithmeticExpression(
|
||||
array($pathExpression)
|
||||
);
|
||||
$expression = new InExpression($arithmeticExpression);
|
||||
$expression->literals[] = new InputParameter(":" . self::PAGINATOR_ID_ALIAS);
|
||||
|
||||
} else {
|
||||
$expression = new NullComparisonExpression($pathExpression);
|
||||
$expression->not = false;
|
||||
}
|
||||
|
||||
$conditionalPrimary = new ConditionalPrimary;
|
||||
$conditionalPrimary->simpleConditionalExpression = $expression;
|
||||
if ($AST->whereClause) {
|
||||
if ($AST->whereClause->conditionalExpression instanceof ConditionalTerm) {
|
||||
$AST->whereClause->conditionalExpression->conditionalFactors[] = $conditionalPrimary;
|
||||
} elseif ($AST->whereClause->conditionalExpression instanceof ConditionalPrimary) {
|
||||
$AST->whereClause->conditionalExpression = new ConditionalExpression(array(
|
||||
new ConditionalTerm(array(
|
||||
$AST->whereClause->conditionalExpression,
|
||||
$conditionalPrimary
|
||||
))
|
||||
));
|
||||
} elseif ($AST->whereClause->conditionalExpression instanceof ConditionalExpression
|
||||
|| $AST->whereClause->conditionalExpression instanceof ConditionalFactor
|
||||
) {
|
||||
$tmpPrimary = new ConditionalPrimary;
|
||||
$tmpPrimary->conditionalExpression = $AST->whereClause->conditionalExpression;
|
||||
$AST->whereClause->conditionalExpression = new ConditionalTerm(array(
|
||||
$tmpPrimary,
|
||||
$conditionalPrimary
|
||||
));
|
||||
}
|
||||
} else {
|
||||
$AST->whereClause = new WhereClause(
|
||||
new ConditionalExpression(array(
|
||||
new ConditionalTerm(array(
|
||||
$conditionalPrimary
|
||||
))
|
||||
))
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
144
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/ResolveTargetEntityListener.php
vendored
Normal file
144
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/ResolveTargetEntityListener.php
vendored
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
<?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\ORM\Tools;
|
||||
|
||||
use Doctrine\ORM\Event\LoadClassMetadataEventArgs;
|
||||
use Doctrine\ORM\Event\OnClassMetadataNotFoundEventArgs;
|
||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||
use Doctrine\Common\EventSubscriber;
|
||||
use Doctrine\ORM\Events;
|
||||
|
||||
/**
|
||||
* ResolveTargetEntityListener
|
||||
*
|
||||
* Mechanism to overwrite interfaces or classes specified as association
|
||||
* targets.
|
||||
*
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @since 2.2
|
||||
*/
|
||||
class ResolveTargetEntityListener implements EventSubscriber
|
||||
{
|
||||
/**
|
||||
* @var array[] indexed by original entity name
|
||||
*/
|
||||
private $resolveTargetEntities = array();
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getSubscribedEvents()
|
||||
{
|
||||
return array(
|
||||
Events::loadClassMetadata,
|
||||
Events::onClassMetadataNotFound
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a target-entity class name to resolve to a new class name.
|
||||
*
|
||||
* @param string $originalEntity
|
||||
* @param string $newEntity
|
||||
* @param array $mapping
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addResolveTargetEntity($originalEntity, $newEntity, array $mapping)
|
||||
{
|
||||
$mapping['targetEntity'] = ltrim($newEntity, "\\");
|
||||
$this->resolveTargetEntities[ltrim($originalEntity, "\\")] = $mapping;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param OnClassMetadataNotFoundEventArgs $args
|
||||
*
|
||||
* @internal this is an event callback, and should not be called directly
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function onClassMetadataNotFound(OnClassMetadataNotFoundEventArgs $args)
|
||||
{
|
||||
if (array_key_exists($args->getClassName(), $this->resolveTargetEntities)) {
|
||||
$args->setFoundMetadata(
|
||||
$args
|
||||
->getObjectManager()
|
||||
->getClassMetadata($this->resolveTargetEntities[$args->getClassname()]['targetEntity'])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes event and resolves new target entity names.
|
||||
*
|
||||
* @param LoadClassMetadataEventArgs $args
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @internal this is an event callback, and should not be called directly
|
||||
*/
|
||||
public function loadClassMetadata(LoadClassMetadataEventArgs $args)
|
||||
{
|
||||
/* @var $cm \Doctrine\ORM\Mapping\ClassMetadata */
|
||||
$cm = $args->getClassMetadata();
|
||||
|
||||
foreach ($cm->associationMappings as $mapping) {
|
||||
if (isset($this->resolveTargetEntities[$mapping['targetEntity']])) {
|
||||
$this->remapAssociation($cm, $mapping);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->resolveTargetEntities as $interface => $data) {
|
||||
if ($data['targetEntity'] == $cm->getName()) {
|
||||
$args->getEntityManager()->getMetadataFactory()->setMetadataFor($interface, $cm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Doctrine\ORM\Mapping\ClassMetadataInfo $classMetadata
|
||||
* @param array $mapping
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function remapAssociation($classMetadata, $mapping)
|
||||
{
|
||||
$newMapping = $this->resolveTargetEntities[$mapping['targetEntity']];
|
||||
$newMapping = array_replace_recursive($mapping, $newMapping);
|
||||
$newMapping['fieldName'] = $mapping['fieldName'];
|
||||
|
||||
unset($classMetadata->associationMappings[$mapping['fieldName']]);
|
||||
|
||||
switch ($mapping['type']) {
|
||||
case ClassMetadata::MANY_TO_MANY:
|
||||
$classMetadata->mapManyToMany($newMapping);
|
||||
break;
|
||||
case ClassMetadata::MANY_TO_ONE:
|
||||
$classMetadata->mapManyToOne($newMapping);
|
||||
break;
|
||||
case ClassMetadata::ONE_TO_MANY:
|
||||
$classMetadata->mapOneToMany($newMapping);
|
||||
break;
|
||||
case ClassMetadata::ONE_TO_ONE:
|
||||
$classMetadata->mapOneToOne($newMapping);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
874
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/SchemaTool.php
vendored
Normal file
874
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/SchemaTool.php
vendored
Normal file
|
|
@ -0,0 +1,874 @@
|
|||
<?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\ORM\Tools;
|
||||
|
||||
use Doctrine\ORM\ORMException;
|
||||
use Doctrine\DBAL\Schema\Comparator;
|
||||
use Doctrine\DBAL\Schema\Index;
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\DBAL\Schema\Table;
|
||||
use Doctrine\DBAL\Schema\Visitor\DropSchemaSqlCollector;
|
||||
use Doctrine\DBAL\Schema\Visitor\RemoveNamespacedAssets;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||
use Doctrine\ORM\Tools\Event\GenerateSchemaTableEventArgs;
|
||||
use Doctrine\ORM\Tools\Event\GenerateSchemaEventArgs;
|
||||
|
||||
/**
|
||||
* The SchemaTool is a tool to create/drop/update database schemas based on
|
||||
* <tt>ClassMetadata</tt> class descriptors.
|
||||
*
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @author Stefano Rodriguez <stefano.rodriguez@fubles.com>
|
||||
*/
|
||||
class SchemaTool
|
||||
{
|
||||
/**
|
||||
* @var \Doctrine\ORM\EntityManagerInterface
|
||||
*/
|
||||
private $em;
|
||||
|
||||
/**
|
||||
* @var \Doctrine\DBAL\Platforms\AbstractPlatform
|
||||
*/
|
||||
private $platform;
|
||||
|
||||
/**
|
||||
* The quote strategy.
|
||||
*
|
||||
* @var \Doctrine\ORM\Mapping\QuoteStrategy
|
||||
*/
|
||||
private $quoteStrategy;
|
||||
|
||||
/**
|
||||
* Initializes a new SchemaTool instance that uses the connection of the
|
||||
* provided EntityManager.
|
||||
*
|
||||
* @param \Doctrine\ORM\EntityManagerInterface $em
|
||||
*/
|
||||
public function __construct(EntityManagerInterface $em)
|
||||
{
|
||||
$this->em = $em;
|
||||
$this->platform = $em->getConnection()->getDatabasePlatform();
|
||||
$this->quoteStrategy = $em->getConfiguration()->getQuoteStrategy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the database schema for the given array of ClassMetadata instances.
|
||||
*
|
||||
* @param array $classes
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws ToolsException
|
||||
*/
|
||||
public function createSchema(array $classes)
|
||||
{
|
||||
$createSchemaSql = $this->getCreateSchemaSql($classes);
|
||||
$conn = $this->em->getConnection();
|
||||
|
||||
foreach ($createSchemaSql as $sql) {
|
||||
try {
|
||||
$conn->executeQuery($sql);
|
||||
} catch (\Exception $e) {
|
||||
throw ToolsException::schemaToolFailure($sql, $e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of DDL statements that are required to create the database schema for
|
||||
* the given list of ClassMetadata instances.
|
||||
*
|
||||
* @param array $classes
|
||||
*
|
||||
* @return array The SQL statements needed to create the schema for the classes.
|
||||
*/
|
||||
public function getCreateSchemaSql(array $classes)
|
||||
{
|
||||
$schema = $this->getSchemaFromMetadata($classes);
|
||||
return $schema->toSql($this->platform);
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects instances of ClassMetadata that don't need to be processed in the SchemaTool context.
|
||||
*
|
||||
* @param ClassMetadata $class
|
||||
* @param array $processedClasses
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function processingNotRequired($class, array $processedClasses)
|
||||
{
|
||||
return (
|
||||
isset($processedClasses[$class->name]) ||
|
||||
$class->isMappedSuperclass ||
|
||||
$class->isEmbeddedClass ||
|
||||
($class->isInheritanceTypeSingleTable() && $class->name != $class->rootEntityName)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Schema instance from a given set of metadata classes.
|
||||
*
|
||||
* @param array $classes
|
||||
*
|
||||
* @return Schema
|
||||
*
|
||||
* @throws \Doctrine\ORM\ORMException
|
||||
*/
|
||||
public function getSchemaFromMetadata(array $classes)
|
||||
{
|
||||
// Reminder for processed classes, used for hierarchies
|
||||
$processedClasses = array();
|
||||
$eventManager = $this->em->getEventManager();
|
||||
$schemaManager = $this->em->getConnection()->getSchemaManager();
|
||||
$metadataSchemaConfig = $schemaManager->createSchemaConfig();
|
||||
|
||||
$metadataSchemaConfig->setExplicitForeignKeyIndexes(false);
|
||||
$schema = new Schema(array(), array(), $metadataSchemaConfig);
|
||||
|
||||
$addedFks = array();
|
||||
$blacklistedFks = array();
|
||||
|
||||
foreach ($classes as $class) {
|
||||
/** @var \Doctrine\ORM\Mapping\ClassMetadata $class */
|
||||
if ($this->processingNotRequired($class, $processedClasses)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$table = $schema->createTable($this->quoteStrategy->getTableName($class, $this->platform));
|
||||
|
||||
if ($class->isInheritanceTypeSingleTable()) {
|
||||
$this->gatherColumns($class, $table);
|
||||
$this->gatherRelationsSql($class, $table, $schema, $addedFks, $blacklistedFks);
|
||||
|
||||
// Add the discriminator column
|
||||
$this->addDiscriminatorColumnDefinition($class, $table);
|
||||
|
||||
// Aggregate all the information from all classes in the hierarchy
|
||||
foreach ($class->parentClasses as $parentClassName) {
|
||||
// Parent class information is already contained in this class
|
||||
$processedClasses[$parentClassName] = true;
|
||||
}
|
||||
|
||||
foreach ($class->subClasses as $subClassName) {
|
||||
$subClass = $this->em->getClassMetadata($subClassName);
|
||||
$this->gatherColumns($subClass, $table);
|
||||
$this->gatherRelationsSql($subClass, $table, $schema, $addedFks, $blacklistedFks);
|
||||
$processedClasses[$subClassName] = true;
|
||||
}
|
||||
} elseif ($class->isInheritanceTypeJoined()) {
|
||||
// Add all non-inherited fields as columns
|
||||
$pkColumns = array();
|
||||
foreach ($class->fieldMappings as $fieldName => $mapping) {
|
||||
if ( ! isset($mapping['inherited'])) {
|
||||
$columnName = $this->quoteStrategy->getColumnName(
|
||||
$mapping['fieldName'],
|
||||
$class,
|
||||
$this->platform
|
||||
);
|
||||
$this->gatherColumn($class, $mapping, $table);
|
||||
|
||||
if ($class->isIdentifier($fieldName)) {
|
||||
$pkColumns[] = $columnName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->gatherRelationsSql($class, $table, $schema, $addedFks, $blacklistedFks);
|
||||
|
||||
// Add the discriminator column only to the root table
|
||||
if ($class->name == $class->rootEntityName) {
|
||||
$this->addDiscriminatorColumnDefinition($class, $table);
|
||||
} else {
|
||||
// Add an ID FK column to child tables
|
||||
$inheritedKeyColumns = array();
|
||||
foreach ($class->identifier as $identifierField) {
|
||||
$idMapping = $class->fieldMappings[$identifierField];
|
||||
if (isset($idMapping['inherited'])) {
|
||||
$this->gatherColumn($class, $idMapping, $table);
|
||||
$columnName = $this->quoteStrategy->getColumnName(
|
||||
$identifierField,
|
||||
$class,
|
||||
$this->platform
|
||||
);
|
||||
// TODO: This seems rather hackish, can we optimize it?
|
||||
$table->getColumn($columnName)->setAutoincrement(false);
|
||||
|
||||
$pkColumns[] = $columnName;
|
||||
$inheritedKeyColumns[] = $columnName;
|
||||
}
|
||||
}
|
||||
if (!empty($inheritedKeyColumns)) {
|
||||
// Add a FK constraint on the ID column
|
||||
$table->addForeignKeyConstraint(
|
||||
$this->quoteStrategy->getTableName(
|
||||
$this->em->getClassMetadata($class->rootEntityName),
|
||||
$this->platform
|
||||
),
|
||||
$inheritedKeyColumns,
|
||||
$inheritedKeyColumns,
|
||||
array('onDelete' => 'CASCADE')
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$table->setPrimaryKey($pkColumns);
|
||||
|
||||
} elseif ($class->isInheritanceTypeTablePerClass()) {
|
||||
throw ORMException::notSupported();
|
||||
} else {
|
||||
$this->gatherColumns($class, $table);
|
||||
$this->gatherRelationsSql($class, $table, $schema, $addedFks, $blacklistedFks);
|
||||
}
|
||||
|
||||
$pkColumns = array();
|
||||
foreach ($class->identifier as $identifierField) {
|
||||
if (isset($class->fieldMappings[$identifierField])) {
|
||||
$pkColumns[] = $this->quoteStrategy->getColumnName($identifierField, $class, $this->platform);
|
||||
} elseif (isset($class->associationMappings[$identifierField])) {
|
||||
/* @var $assoc \Doctrine\ORM\Mapping\OneToOne */
|
||||
$assoc = $class->associationMappings[$identifierField];
|
||||
foreach ($assoc['joinColumns'] as $joinColumn) {
|
||||
$pkColumns[] = $this->quoteStrategy->getJoinColumnName($joinColumn, $class, $this->platform);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $table->hasIndex('primary')) {
|
||||
$table->setPrimaryKey($pkColumns);
|
||||
}
|
||||
|
||||
if (isset($class->table['indexes'])) {
|
||||
foreach ($class->table['indexes'] as $indexName => $indexData) {
|
||||
if( ! isset($indexData['flags'])) {
|
||||
$indexData['flags'] = array();
|
||||
}
|
||||
|
||||
$table->addIndex($indexData['columns'], is_numeric($indexName) ? null : $indexName, (array)$indexData['flags'], isset($indexData['options']) ? $indexData['options'] : array());
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($class->table['uniqueConstraints'])) {
|
||||
foreach ($class->table['uniqueConstraints'] as $indexName => $indexData) {
|
||||
$uniqIndex = new Index($indexName, $indexData['columns'], true, false, [], isset($indexData['options']) ? $indexData['options'] : []);
|
||||
|
||||
foreach ($table->getIndexes() as $tableIndexName => $tableIndex) {
|
||||
if ($tableIndex->isFullfilledBy($uniqIndex)) {
|
||||
$table->dropIndex($tableIndexName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$table->addUniqueIndex($indexData['columns'], is_numeric($indexName) ? null : $indexName, isset($indexData['options']) ? $indexData['options'] : array());
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($class->table['options'])) {
|
||||
foreach ($class->table['options'] as $key => $val) {
|
||||
$table->addOption($key, $val);
|
||||
}
|
||||
}
|
||||
|
||||
$processedClasses[$class->name] = true;
|
||||
|
||||
if ($class->isIdGeneratorSequence() && $class->name == $class->rootEntityName) {
|
||||
$seqDef = $class->sequenceGeneratorDefinition;
|
||||
$quotedName = $this->quoteStrategy->getSequenceName($seqDef, $class, $this->platform);
|
||||
if ( ! $schema->hasSequence($quotedName)) {
|
||||
$schema->createSequence(
|
||||
$quotedName,
|
||||
$seqDef['allocationSize'],
|
||||
$seqDef['initialValue']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ($eventManager->hasListeners(ToolEvents::postGenerateSchemaTable)) {
|
||||
$eventManager->dispatchEvent(
|
||||
ToolEvents::postGenerateSchemaTable,
|
||||
new GenerateSchemaTableEventArgs($class, $schema, $table)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $this->platform->supportsSchemas() && ! $this->platform->canEmulateSchemas() ) {
|
||||
$schema->visit(new RemoveNamespacedAssets());
|
||||
}
|
||||
|
||||
if ($eventManager->hasListeners(ToolEvents::postGenerateSchema)) {
|
||||
$eventManager->dispatchEvent(
|
||||
ToolEvents::postGenerateSchema,
|
||||
new GenerateSchemaEventArgs($this->em, $schema)
|
||||
);
|
||||
}
|
||||
|
||||
return $schema;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a portable column definition as required by the DBAL for the discriminator
|
||||
* column of a class.
|
||||
*
|
||||
* @param ClassMetadata $class
|
||||
* @param Table $table
|
||||
*
|
||||
* @return array The portable column definition of the discriminator column as required by
|
||||
* the DBAL.
|
||||
*/
|
||||
private function addDiscriminatorColumnDefinition($class, Table $table)
|
||||
{
|
||||
$discrColumn = $class->discriminatorColumn;
|
||||
|
||||
if ( ! isset($discrColumn['type']) ||
|
||||
(strtolower($discrColumn['type']) == 'string' && ! isset($discrColumn['length']))
|
||||
) {
|
||||
$discrColumn['type'] = 'string';
|
||||
$discrColumn['length'] = 255;
|
||||
}
|
||||
|
||||
$options = array(
|
||||
'length' => isset($discrColumn['length']) ? $discrColumn['length'] : null,
|
||||
'notnull' => true
|
||||
);
|
||||
|
||||
if (isset($discrColumn['columnDefinition'])) {
|
||||
$options['columnDefinition'] = $discrColumn['columnDefinition'];
|
||||
}
|
||||
|
||||
$table->addColumn($discrColumn['name'], $discrColumn['type'], $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gathers the column definitions as required by the DBAL of all field mappings
|
||||
* found in the given class.
|
||||
*
|
||||
* @param ClassMetadata $class
|
||||
* @param Table $table
|
||||
*
|
||||
* @return array The list of portable column definitions as required by the DBAL.
|
||||
*/
|
||||
private function gatherColumns($class, Table $table)
|
||||
{
|
||||
$pkColumns = array();
|
||||
|
||||
foreach ($class->fieldMappings as $mapping) {
|
||||
if ($class->isInheritanceTypeSingleTable() && isset($mapping['inherited'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->gatherColumn($class, $mapping, $table);
|
||||
|
||||
if ($class->isIdentifier($mapping['fieldName'])) {
|
||||
$pkColumns[] = $this->quoteStrategy->getColumnName($mapping['fieldName'], $class, $this->platform);
|
||||
}
|
||||
}
|
||||
|
||||
// For now, this is a hack required for single table inheritence, since this method is called
|
||||
// twice by single table inheritence relations
|
||||
if (!$table->hasIndex('primary')) {
|
||||
//$table->setPrimaryKey($pkColumns);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a column definition as required by the DBAL from an ORM field mapping definition.
|
||||
*
|
||||
* @param ClassMetadata $class The class that owns the field mapping.
|
||||
* @param array $mapping The field mapping.
|
||||
* @param Table $table
|
||||
*
|
||||
* @return array The portable column definition as required by the DBAL.
|
||||
*/
|
||||
private function gatherColumn($class, array $mapping, Table $table)
|
||||
{
|
||||
$columnName = $this->quoteStrategy->getColumnName($mapping['fieldName'], $class, $this->platform);
|
||||
$columnType = $mapping['type'];
|
||||
|
||||
$options = array();
|
||||
$options['length'] = isset($mapping['length']) ? $mapping['length'] : null;
|
||||
$options['notnull'] = isset($mapping['nullable']) ? ! $mapping['nullable'] : true;
|
||||
if ($class->isInheritanceTypeSingleTable() && count($class->parentClasses) > 0) {
|
||||
$options['notnull'] = false;
|
||||
}
|
||||
|
||||
$options['platformOptions'] = array();
|
||||
$options['platformOptions']['version'] = $class->isVersioned && $class->versionField == $mapping['fieldName'] ? true : false;
|
||||
|
||||
if (strtolower($columnType) == 'string' && $options['length'] === null) {
|
||||
$options['length'] = 255;
|
||||
}
|
||||
|
||||
if (isset($mapping['precision'])) {
|
||||
$options['precision'] = $mapping['precision'];
|
||||
}
|
||||
|
||||
if (isset($mapping['scale'])) {
|
||||
$options['scale'] = $mapping['scale'];
|
||||
}
|
||||
|
||||
if (isset($mapping['default'])) {
|
||||
$options['default'] = $mapping['default'];
|
||||
}
|
||||
|
||||
if (isset($mapping['columnDefinition'])) {
|
||||
$options['columnDefinition'] = $mapping['columnDefinition'];
|
||||
}
|
||||
|
||||
if (isset($mapping['options'])) {
|
||||
$knownOptions = array('comment', 'unsigned', 'fixed', 'default');
|
||||
|
||||
foreach ($knownOptions as $knownOption) {
|
||||
if (array_key_exists($knownOption, $mapping['options'])) {
|
||||
$options[$knownOption] = $mapping['options'][$knownOption];
|
||||
|
||||
unset($mapping['options'][$knownOption]);
|
||||
}
|
||||
}
|
||||
|
||||
$options['customSchemaOptions'] = $mapping['options'];
|
||||
}
|
||||
|
||||
if ($class->isIdGeneratorIdentity() && $class->getIdentifierFieldNames() == array($mapping['fieldName'])) {
|
||||
$options['autoincrement'] = true;
|
||||
}
|
||||
if ($class->isInheritanceTypeJoined() && $class->name != $class->rootEntityName) {
|
||||
$options['autoincrement'] = false;
|
||||
}
|
||||
|
||||
if ($table->hasColumn($columnName)) {
|
||||
// required in some inheritance scenarios
|
||||
$table->changeColumn($columnName, $options);
|
||||
} else {
|
||||
$table->addColumn($columnName, $columnType, $options);
|
||||
}
|
||||
|
||||
$isUnique = isset($mapping['unique']) ? $mapping['unique'] : false;
|
||||
if ($isUnique) {
|
||||
$table->addUniqueIndex(array($columnName));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gathers the SQL for properly setting up the relations of the given class.
|
||||
* This includes the SQL for foreign key constraints and join tables.
|
||||
*
|
||||
* @param ClassMetadata $class
|
||||
* @param Table $table
|
||||
* @param Schema $schema
|
||||
* @param array $addedFks
|
||||
* @param array $blacklistedFks
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws \Doctrine\ORM\ORMException
|
||||
*/
|
||||
private function gatherRelationsSql($class, $table, $schema, &$addedFks, &$blacklistedFks)
|
||||
{
|
||||
foreach ($class->associationMappings as $mapping) {
|
||||
if (isset($mapping['inherited'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$foreignClass = $this->em->getClassMetadata($mapping['targetEntity']);
|
||||
|
||||
if ($mapping['type'] & ClassMetadata::TO_ONE && $mapping['isOwningSide']) {
|
||||
$primaryKeyColumns = array(); // PK is unnecessary for this relation-type
|
||||
|
||||
$this->gatherRelationJoinColumns(
|
||||
$mapping['joinColumns'],
|
||||
$table,
|
||||
$foreignClass,
|
||||
$mapping,
|
||||
$primaryKeyColumns,
|
||||
$addedFks,
|
||||
$blacklistedFks
|
||||
);
|
||||
} elseif ($mapping['type'] == ClassMetadata::ONE_TO_MANY && $mapping['isOwningSide']) {
|
||||
//... create join table, one-many through join table supported later
|
||||
throw ORMException::notSupported();
|
||||
} elseif ($mapping['type'] == ClassMetadata::MANY_TO_MANY && $mapping['isOwningSide']) {
|
||||
// create join table
|
||||
$joinTable = $mapping['joinTable'];
|
||||
|
||||
$theJoinTable = $schema->createTable(
|
||||
$this->quoteStrategy->getJoinTableName($mapping, $foreignClass, $this->platform)
|
||||
);
|
||||
|
||||
$primaryKeyColumns = array();
|
||||
|
||||
// Build first FK constraint (relation table => source table)
|
||||
$this->gatherRelationJoinColumns(
|
||||
$joinTable['joinColumns'],
|
||||
$theJoinTable,
|
||||
$class,
|
||||
$mapping,
|
||||
$primaryKeyColumns,
|
||||
$addedFks,
|
||||
$blacklistedFks
|
||||
);
|
||||
|
||||
// Build second FK constraint (relation table => target table)
|
||||
$this->gatherRelationJoinColumns(
|
||||
$joinTable['inverseJoinColumns'],
|
||||
$theJoinTable,
|
||||
$foreignClass,
|
||||
$mapping,
|
||||
$primaryKeyColumns,
|
||||
$addedFks,
|
||||
$blacklistedFks
|
||||
);
|
||||
|
||||
$theJoinTable->setPrimaryKey($primaryKeyColumns);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the class metadata that is responsible for the definition of the referenced column name.
|
||||
*
|
||||
* Previously this was a simple task, but with DDC-117 this problem is actually recursive. If its
|
||||
* not a simple field, go through all identifier field names that are associations recursively and
|
||||
* find that referenced column name.
|
||||
*
|
||||
* TODO: Is there any way to make this code more pleasing?
|
||||
*
|
||||
* @param ClassMetadata $class
|
||||
* @param string $referencedColumnName
|
||||
*
|
||||
* @return array (ClassMetadata, referencedFieldName)
|
||||
*/
|
||||
private function getDefiningClass($class, $referencedColumnName)
|
||||
{
|
||||
$referencedFieldName = $class->getFieldName($referencedColumnName);
|
||||
|
||||
if ($class->hasField($referencedFieldName)) {
|
||||
return array($class, $referencedFieldName);
|
||||
}
|
||||
|
||||
if (in_array($referencedColumnName, $class->getIdentifierColumnNames())) {
|
||||
// it seems to be an entity as foreign key
|
||||
foreach ($class->getIdentifierFieldNames() as $fieldName) {
|
||||
if ($class->hasAssociation($fieldName)
|
||||
&& $class->getSingleAssociationJoinColumnName($fieldName) == $referencedColumnName) {
|
||||
return $this->getDefiningClass(
|
||||
$this->em->getClassMetadata($class->associationMappings[$fieldName]['targetEntity']),
|
||||
$class->getSingleAssociationReferencedJoinColumnName($fieldName)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gathers columns and fk constraints that are required for one part of relationship.
|
||||
*
|
||||
* @param array $joinColumns
|
||||
* @param Table $theJoinTable
|
||||
* @param ClassMetadata $class
|
||||
* @param array $mapping
|
||||
* @param array $primaryKeyColumns
|
||||
* @param array $addedFks
|
||||
* @param array $blacklistedFks
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws \Doctrine\ORM\ORMException
|
||||
*/
|
||||
private function gatherRelationJoinColumns(
|
||||
$joinColumns,
|
||||
$theJoinTable,
|
||||
$class,
|
||||
$mapping,
|
||||
&$primaryKeyColumns,
|
||||
&$addedFks,
|
||||
&$blacklistedFks
|
||||
) {
|
||||
$localColumns = array();
|
||||
$foreignColumns = array();
|
||||
$fkOptions = array();
|
||||
$foreignTableName = $this->quoteStrategy->getTableName($class, $this->platform);
|
||||
$uniqueConstraints = array();
|
||||
|
||||
foreach ($joinColumns as $joinColumn) {
|
||||
|
||||
list($definingClass, $referencedFieldName) = $this->getDefiningClass(
|
||||
$class,
|
||||
$joinColumn['referencedColumnName']
|
||||
);
|
||||
|
||||
if ( ! $definingClass) {
|
||||
throw new \Doctrine\ORM\ORMException(
|
||||
"Column name `".$joinColumn['referencedColumnName']."` referenced for relation from ".
|
||||
$mapping['sourceEntity'] . " towards ". $mapping['targetEntity'] . " does not exist."
|
||||
);
|
||||
}
|
||||
|
||||
$quotedColumnName = $this->quoteStrategy->getJoinColumnName($joinColumn, $class, $this->platform);
|
||||
$quotedRefColumnName = $this->quoteStrategy->getReferencedJoinColumnName(
|
||||
$joinColumn,
|
||||
$class,
|
||||
$this->platform
|
||||
);
|
||||
|
||||
$primaryKeyColumns[] = $quotedColumnName;
|
||||
$localColumns[] = $quotedColumnName;
|
||||
$foreignColumns[] = $quotedRefColumnName;
|
||||
|
||||
if ( ! $theJoinTable->hasColumn($quotedColumnName)) {
|
||||
// Only add the column to the table if it does not exist already.
|
||||
// It might exist already if the foreign key is mapped into a regular
|
||||
// property as well.
|
||||
|
||||
$fieldMapping = $definingClass->getFieldMapping($referencedFieldName);
|
||||
|
||||
$columnDef = null;
|
||||
if (isset($joinColumn['columnDefinition'])) {
|
||||
$columnDef = $joinColumn['columnDefinition'];
|
||||
} elseif (isset($fieldMapping['columnDefinition'])) {
|
||||
$columnDef = $fieldMapping['columnDefinition'];
|
||||
}
|
||||
|
||||
$columnOptions = array('notnull' => false, 'columnDefinition' => $columnDef);
|
||||
|
||||
if (isset($joinColumn['nullable'])) {
|
||||
$columnOptions['notnull'] = !$joinColumn['nullable'];
|
||||
}
|
||||
|
||||
if (isset($fieldMapping['options'])) {
|
||||
$columnOptions['options'] = $fieldMapping['options'];
|
||||
}
|
||||
|
||||
if ($fieldMapping['type'] == "string" && isset($fieldMapping['length'])) {
|
||||
$columnOptions['length'] = $fieldMapping['length'];
|
||||
} elseif ($fieldMapping['type'] == "decimal") {
|
||||
$columnOptions['scale'] = $fieldMapping['scale'];
|
||||
$columnOptions['precision'] = $fieldMapping['precision'];
|
||||
}
|
||||
|
||||
$theJoinTable->addColumn($quotedColumnName, $fieldMapping['type'], $columnOptions);
|
||||
}
|
||||
|
||||
if (isset($joinColumn['unique']) && $joinColumn['unique'] == true) {
|
||||
$uniqueConstraints[] = array('columns' => array($quotedColumnName));
|
||||
}
|
||||
|
||||
if (isset($joinColumn['onDelete'])) {
|
||||
$fkOptions['onDelete'] = $joinColumn['onDelete'];
|
||||
}
|
||||
}
|
||||
|
||||
// Prefer unique constraints over implicit simple indexes created for foreign keys.
|
||||
// Also avoids index duplication.
|
||||
foreach ($uniqueConstraints as $indexName => $unique) {
|
||||
$theJoinTable->addUniqueIndex($unique['columns'], is_numeric($indexName) ? null : $indexName);
|
||||
}
|
||||
|
||||
$compositeName = $theJoinTable->getName().'.'.implode('', $localColumns);
|
||||
if (isset($addedFks[$compositeName])
|
||||
&& ($foreignTableName != $addedFks[$compositeName]['foreignTableName']
|
||||
|| 0 < count(array_diff($foreignColumns, $addedFks[$compositeName]['foreignColumns'])))
|
||||
) {
|
||||
foreach ($theJoinTable->getForeignKeys() as $fkName => $key) {
|
||||
if (0 === count(array_diff($key->getLocalColumns(), $localColumns))
|
||||
&& (($key->getForeignTableName() != $foreignTableName)
|
||||
|| 0 < count(array_diff($key->getForeignColumns(), $foreignColumns)))
|
||||
) {
|
||||
$theJoinTable->removeForeignKey($fkName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
$blacklistedFks[$compositeName] = true;
|
||||
} elseif (!isset($blacklistedFks[$compositeName])) {
|
||||
$addedFks[$compositeName] = array('foreignTableName' => $foreignTableName, 'foreignColumns' => $foreignColumns);
|
||||
$theJoinTable->addUnnamedForeignKeyConstraint(
|
||||
$foreignTableName,
|
||||
$localColumns,
|
||||
$foreignColumns,
|
||||
$fkOptions
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Drops the database schema for the given classes.
|
||||
*
|
||||
* In any way when an exception is thrown it is suppressed since drop was
|
||||
* issued for all classes of the schema and some probably just don't exist.
|
||||
*
|
||||
* @param array $classes
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function dropSchema(array $classes)
|
||||
{
|
||||
$dropSchemaSql = $this->getDropSchemaSQL($classes);
|
||||
$conn = $this->em->getConnection();
|
||||
|
||||
foreach ($dropSchemaSql as $sql) {
|
||||
try {
|
||||
$conn->executeQuery($sql);
|
||||
} catch (\Exception $e) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Drops all elements in the database of the current connection.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function dropDatabase()
|
||||
{
|
||||
$dropSchemaSql = $this->getDropDatabaseSQL();
|
||||
$conn = $this->em->getConnection();
|
||||
|
||||
foreach ($dropSchemaSql as $sql) {
|
||||
$conn->executeQuery($sql);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the SQL needed to drop the database schema for the connections database.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getDropDatabaseSQL()
|
||||
{
|
||||
$sm = $this->em->getConnection()->getSchemaManager();
|
||||
$schema = $sm->createSchema();
|
||||
|
||||
$visitor = new DropSchemaSqlCollector($this->platform);
|
||||
$schema->visit($visitor);
|
||||
|
||||
return $visitor->getQueries();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets SQL to drop the tables defined by the passed classes.
|
||||
*
|
||||
* @param array $classes
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getDropSchemaSQL(array $classes)
|
||||
{
|
||||
$visitor = new DropSchemaSqlCollector($this->platform);
|
||||
$schema = $this->getSchemaFromMetadata($classes);
|
||||
|
||||
$sm = $this->em->getConnection()->getSchemaManager();
|
||||
$fullSchema = $sm->createSchema();
|
||||
|
||||
foreach ($fullSchema->getTables() as $table) {
|
||||
if ( ! $schema->hasTable($table->getName())) {
|
||||
foreach ($table->getForeignKeys() as $foreignKey) {
|
||||
/* @var $foreignKey \Doctrine\DBAL\Schema\ForeignKeyConstraint */
|
||||
if ($schema->hasTable($foreignKey->getForeignTableName())) {
|
||||
$visitor->acceptForeignKey($table, $foreignKey);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$visitor->acceptTable($table);
|
||||
foreach ($table->getForeignKeys() as $foreignKey) {
|
||||
$visitor->acceptForeignKey($table, $foreignKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->platform->supportsSequences()) {
|
||||
foreach ($schema->getSequences() as $sequence) {
|
||||
$visitor->acceptSequence($sequence);
|
||||
}
|
||||
|
||||
foreach ($schema->getTables() as $table) {
|
||||
/* @var $sequence Table */
|
||||
if ($table->hasPrimaryKey()) {
|
||||
$columns = $table->getPrimaryKey()->getColumns();
|
||||
if (count($columns) == 1) {
|
||||
$checkSequence = $table->getName() . "_" . $columns[0] . "_seq";
|
||||
if ($fullSchema->hasSequence($checkSequence)) {
|
||||
$visitor->acceptSequence($fullSchema->getSequence($checkSequence));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $visitor->getQueries();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the database schema of the given classes by comparing the ClassMetadata
|
||||
* instances to the current database schema that is inspected. If $saveMode is set
|
||||
* to true the command is executed in the Database, else SQL is returned.
|
||||
*
|
||||
* @param array $classes
|
||||
* @param boolean $saveMode
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function updateSchema(array $classes, $saveMode = false)
|
||||
{
|
||||
$updateSchemaSql = $this->getUpdateSchemaSql($classes, $saveMode);
|
||||
$conn = $this->em->getConnection();
|
||||
|
||||
foreach ($updateSchemaSql as $sql) {
|
||||
$conn->executeQuery($sql);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the sequence of SQL statements that need to be performed in order
|
||||
* to bring the given class mappings in-synch with the relational schema.
|
||||
* If $saveMode is set to true the command is executed in the Database,
|
||||
* else SQL is returned.
|
||||
*
|
||||
* @param array $classes The classes to consider.
|
||||
* @param boolean $saveMode True for writing to DB, false for SQL string.
|
||||
*
|
||||
* @return array The sequence of SQL statements.
|
||||
*/
|
||||
public function getUpdateSchemaSql(array $classes, $saveMode = false)
|
||||
{
|
||||
$sm = $this->em->getConnection()->getSchemaManager();
|
||||
|
||||
$fromSchema = $sm->createSchema();
|
||||
$toSchema = $this->getSchemaFromMetadata($classes);
|
||||
|
||||
$comparator = new Comparator();
|
||||
$schemaDiff = $comparator->compare($fromSchema, $toSchema);
|
||||
|
||||
if ($saveMode) {
|
||||
return $schemaDiff->toSaveSql($this->platform);
|
||||
}
|
||||
|
||||
return $schemaDiff->toSql($this->platform);
|
||||
}
|
||||
}
|
||||
272
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/SchemaValidator.php
vendored
Normal file
272
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/SchemaValidator.php
vendored
Normal file
|
|
@ -0,0 +1,272 @@
|
|||
<?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\ORM\Tools;
|
||||
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\Mapping\ClassMetadataInfo;
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
|
||||
/**
|
||||
* Performs strict validation of the mapping schema
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT
|
||||
* @link www.doctrine-project.com
|
||||
* @since 1.0
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
|
||||
* @author Jonathan Wage <jonwage@gmail.com>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
class SchemaValidator
|
||||
{
|
||||
/**
|
||||
* @var EntityManagerInterface
|
||||
*/
|
||||
private $em;
|
||||
|
||||
/**
|
||||
* @param EntityManagerInterface $em
|
||||
*/
|
||||
public function __construct(EntityManagerInterface $em)
|
||||
{
|
||||
$this->em = $em;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the internal consistency of all mapping files.
|
||||
*
|
||||
* There are several checks that can't be done at runtime or are too expensive, which can be verified
|
||||
* with this command. For example:
|
||||
*
|
||||
* 1. Check if a relation with "mappedBy" is actually connected to that specified field.
|
||||
* 2. Check if "mappedBy" and "inversedBy" are consistent to each other.
|
||||
* 3. Check if "referencedColumnName" attributes are really pointing to primary key columns.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function validateMapping()
|
||||
{
|
||||
$errors = array();
|
||||
$cmf = $this->em->getMetadataFactory();
|
||||
$classes = $cmf->getAllMetadata();
|
||||
|
||||
foreach ($classes as $class) {
|
||||
if ($ce = $this->validateClass($class)) {
|
||||
$errors[$class->name] = $ce;
|
||||
}
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a single class of the current.
|
||||
*
|
||||
* @param ClassMetadataInfo $class
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function validateClass(ClassMetadataInfo $class)
|
||||
{
|
||||
$ce = array();
|
||||
$cmf = $this->em->getMetadataFactory();
|
||||
|
||||
foreach ($class->fieldMappings as $fieldName => $mapping) {
|
||||
if (!Type::hasType($mapping['type'])) {
|
||||
$ce[] = "The field '" . $class->name . "#" . $fieldName."' uses a non-existant type '" . $mapping['type'] . "'.";
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($class->associationMappings as $fieldName => $assoc) {
|
||||
if (!class_exists($assoc['targetEntity']) || $cmf->isTransient($assoc['targetEntity'])) {
|
||||
$ce[] = "The target entity '" . $assoc['targetEntity'] . "' specified on " . $class->name . '#' . $fieldName . ' is unknown or not an entity.';
|
||||
return $ce;
|
||||
}
|
||||
|
||||
if ($assoc['mappedBy'] && $assoc['inversedBy']) {
|
||||
$ce[] = "The association " . $class . "#" . $fieldName . " cannot be defined as both inverse and owning.";
|
||||
}
|
||||
|
||||
$targetMetadata = $cmf->getMetadataFor($assoc['targetEntity']);
|
||||
|
||||
if (isset($assoc['id']) && $targetMetadata->containsForeignIdentifier) {
|
||||
$ce[] = "Cannot map association '" . $class->name. "#". $fieldName ." as identifier, because " .
|
||||
"the target entity '". $targetMetadata->name . "' also maps an association as identifier.";
|
||||
}
|
||||
|
||||
if ($assoc['mappedBy']) {
|
||||
if ($targetMetadata->hasField($assoc['mappedBy'])) {
|
||||
$ce[] = "The association " . $class->name . "#" . $fieldName . " refers to the owning side ".
|
||||
"field " . $assoc['targetEntity'] . "#" . $assoc['mappedBy'] . " which is not defined as association, but as field.";
|
||||
}
|
||||
if (!$targetMetadata->hasAssociation($assoc['mappedBy'])) {
|
||||
$ce[] = "The association " . $class->name . "#" . $fieldName . " refers to the owning side ".
|
||||
"field " . $assoc['targetEntity'] . "#" . $assoc['mappedBy'] . " which does not exist.";
|
||||
} elseif ($targetMetadata->associationMappings[$assoc['mappedBy']]['inversedBy'] == null) {
|
||||
$ce[] = "The field " . $class->name . "#" . $fieldName . " is on the inverse side of a ".
|
||||
"bi-directional relationship, but the specified mappedBy association on the target-entity ".
|
||||
$assoc['targetEntity'] . "#" . $assoc['mappedBy'] . " does not contain the required ".
|
||||
"'inversedBy=\"" . $fieldName . "\"' attribute.";
|
||||
} elseif ($targetMetadata->associationMappings[$assoc['mappedBy']]['inversedBy'] != $fieldName) {
|
||||
$ce[] = "The mappings " . $class->name . "#" . $fieldName . " and " .
|
||||
$assoc['targetEntity'] . "#" . $assoc['mappedBy'] . " are ".
|
||||
"inconsistent with each other.";
|
||||
}
|
||||
}
|
||||
|
||||
if ($assoc['inversedBy']) {
|
||||
if ($targetMetadata->hasField($assoc['inversedBy'])) {
|
||||
$ce[] = "The association " . $class->name . "#" . $fieldName . " refers to the inverse side ".
|
||||
"field " . $assoc['targetEntity'] . "#" . $assoc['inversedBy'] . " which is not defined as association.";
|
||||
}
|
||||
|
||||
if (!$targetMetadata->hasAssociation($assoc['inversedBy'])) {
|
||||
$ce[] = "The association " . $class->name . "#" . $fieldName . " refers to the inverse side ".
|
||||
"field " . $assoc['targetEntity'] . "#" . $assoc['inversedBy'] . " which does not exist.";
|
||||
} elseif ($targetMetadata->associationMappings[$assoc['inversedBy']]['mappedBy'] == null) {
|
||||
$ce[] = "The field " . $class->name . "#" . $fieldName . " is on the owning side of a ".
|
||||
"bi-directional relationship, but the specified mappedBy association on the target-entity ".
|
||||
$assoc['targetEntity'] . "#" . $assoc['mappedBy'] . " does not contain the required ".
|
||||
"'inversedBy' attribute.";
|
||||
} elseif ($targetMetadata->associationMappings[$assoc['inversedBy']]['mappedBy'] != $fieldName) {
|
||||
$ce[] = "The mappings " . $class->name . "#" . $fieldName . " and " .
|
||||
$assoc['targetEntity'] . "#" . $assoc['inversedBy'] . " are ".
|
||||
"inconsistent with each other.";
|
||||
}
|
||||
|
||||
// Verify inverse side/owning side match each other
|
||||
if (array_key_exists($assoc['inversedBy'], $targetMetadata->associationMappings)) {
|
||||
$targetAssoc = $targetMetadata->associationMappings[$assoc['inversedBy']];
|
||||
if ($assoc['type'] == ClassMetadataInfo::ONE_TO_ONE && $targetAssoc['type'] !== ClassMetadataInfo::ONE_TO_ONE){
|
||||
$ce[] = "If association " . $class->name . "#" . $fieldName . " is one-to-one, then the inversed " .
|
||||
"side " . $targetMetadata->name . "#" . $assoc['inversedBy'] . " has to be one-to-one as well.";
|
||||
} elseif ($assoc['type'] == ClassMetadataInfo::MANY_TO_ONE && $targetAssoc['type'] !== ClassMetadataInfo::ONE_TO_MANY){
|
||||
$ce[] = "If association " . $class->name . "#" . $fieldName . " is many-to-one, then the inversed " .
|
||||
"side " . $targetMetadata->name . "#" . $assoc['inversedBy'] . " has to be one-to-many.";
|
||||
} elseif ($assoc['type'] == ClassMetadataInfo::MANY_TO_MANY && $targetAssoc['type'] !== ClassMetadataInfo::MANY_TO_MANY){
|
||||
$ce[] = "If association " . $class->name . "#" . $fieldName . " is many-to-many, then the inversed " .
|
||||
"side " . $targetMetadata->name . "#" . $assoc['inversedBy'] . " has to be many-to-many as well.";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($assoc['isOwningSide']) {
|
||||
if ($assoc['type'] == ClassMetadataInfo::MANY_TO_MANY) {
|
||||
$identifierColumns = $class->getIdentifierColumnNames();
|
||||
foreach ($assoc['joinTable']['joinColumns'] as $joinColumn) {
|
||||
if (!in_array($joinColumn['referencedColumnName'], $identifierColumns)) {
|
||||
$ce[] = "The referenced column name '" . $joinColumn['referencedColumnName'] . "' " .
|
||||
"has to be a primary key column on the target entity class '".$class->name."'.";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$identifierColumns = $targetMetadata->getIdentifierColumnNames();
|
||||
foreach ($assoc['joinTable']['inverseJoinColumns'] as $inverseJoinColumn) {
|
||||
if (!in_array($inverseJoinColumn['referencedColumnName'], $identifierColumns)) {
|
||||
$ce[] = "The referenced column name '" . $joinColumn['referencedColumnName'] . "' " .
|
||||
"has to be a primary key column on the target entity class '".$targetMetadata->name."'.";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (count($targetMetadata->getIdentifierColumnNames()) != count($assoc['joinTable']['inverseJoinColumns'])) {
|
||||
$ce[] = "The inverse join columns of the many-to-many table '" . $assoc['joinTable']['name'] . "' " .
|
||||
"have to contain to ALL identifier columns of the target entity '". $targetMetadata->name . "', " .
|
||||
"however '" . implode(", ", array_diff($targetMetadata->getIdentifierColumnNames(), array_values($assoc['relationToTargetKeyColumns']))) .
|
||||
"' are missing.";
|
||||
}
|
||||
|
||||
if (count($class->getIdentifierColumnNames()) != count($assoc['joinTable']['joinColumns'])) {
|
||||
$ce[] = "The join columns of the many-to-many table '" . $assoc['joinTable']['name'] . "' " .
|
||||
"have to contain to ALL identifier columns of the source entity '". $class->name . "', " .
|
||||
"however '" . implode(", ", array_diff($class->getIdentifierColumnNames(), array_values($assoc['relationToSourceKeyColumns']))) .
|
||||
"' are missing.";
|
||||
}
|
||||
|
||||
} elseif ($assoc['type'] & ClassMetadataInfo::TO_ONE) {
|
||||
$identifierColumns = $targetMetadata->getIdentifierColumnNames();
|
||||
foreach ($assoc['joinColumns'] as $joinColumn) {
|
||||
if (!in_array($joinColumn['referencedColumnName'], $identifierColumns)) {
|
||||
$ce[] = "The referenced column name '" . $joinColumn['referencedColumnName'] . "' " .
|
||||
"has to be a primary key column on the target entity class '".$targetMetadata->name."'.";
|
||||
}
|
||||
}
|
||||
|
||||
if (count($identifierColumns) != count($assoc['joinColumns'])) {
|
||||
$ids = array();
|
||||
|
||||
foreach ($assoc['joinColumns'] as $joinColumn) {
|
||||
$ids[] = $joinColumn['name'];
|
||||
}
|
||||
|
||||
$ce[] = "The join columns of the association '" . $assoc['fieldName'] . "' " .
|
||||
"have to match to ALL identifier columns of the target entity '". $targetMetadata->name . "', " .
|
||||
"however '" . implode(", ", array_diff($targetMetadata->getIdentifierColumnNames(), $ids)) .
|
||||
"' are missing.";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($assoc['orderBy']) && $assoc['orderBy'] !== null) {
|
||||
foreach ($assoc['orderBy'] as $orderField => $orientation) {
|
||||
if (!$targetMetadata->hasField($orderField) && !$targetMetadata->hasAssociation($orderField)) {
|
||||
$ce[] = "The association " . $class->name."#".$fieldName." is ordered by a foreign field " .
|
||||
$orderField . " that is not a field on the target entity " . $targetMetadata->name . ".";
|
||||
continue;
|
||||
}
|
||||
if ($targetMetadata->isCollectionValuedAssociation($orderField)) {
|
||||
$ce[] = "The association " . $class->name."#".$fieldName." is ordered by a field " .
|
||||
$orderField . " on " . $targetMetadata->name . " that is a collection-valued association.";
|
||||
continue;
|
||||
}
|
||||
if ($targetMetadata->isAssociationInverseSide($orderField)) {
|
||||
$ce[] = "The association " . $class->name."#".$fieldName." is ordered by a field " .
|
||||
$orderField . " on " . $targetMetadata->name . " that is the inverse side of an association.";
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($class->subClasses as $subClass) {
|
||||
if (!in_array($class->name, class_parents($subClass))) {
|
||||
$ce[] = "According to the discriminator map class '" . $subClass . "' has to be a child ".
|
||||
"of '" . $class->name . "' but these entities are not related through inheritance.";
|
||||
}
|
||||
}
|
||||
|
||||
return $ce;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the Database Schema is in sync with the current metadata state.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function schemaInSyncWithMetadata()
|
||||
{
|
||||
$schemaTool = new SchemaTool($this->em);
|
||||
|
||||
$allMetadata = $this->em->getMetadataFactory()->getAllMetadata();
|
||||
|
||||
return count($schemaTool->getUpdateSchemaSql($allMetadata, true)) == 0;
|
||||
}
|
||||
}
|
||||
210
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Setup.php
vendored
Normal file
210
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/Setup.php
vendored
Normal file
|
|
@ -0,0 +1,210 @@
|
|||
<?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\ORM\Tools;
|
||||
|
||||
use Doctrine\Common\ClassLoader;
|
||||
use Doctrine\Common\Cache\Cache;
|
||||
use Doctrine\Common\Cache\CacheProvider;
|
||||
use Doctrine\Common\Cache\ArrayCache;
|
||||
use Doctrine\ORM\Configuration;
|
||||
use Doctrine\ORM\Mapping\Driver\XmlDriver;
|
||||
use Doctrine\ORM\Mapping\Driver\YamlDriver;
|
||||
|
||||
/**
|
||||
* Convenience class for setting up Doctrine from different installations and configurations.
|
||||
*
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
*/
|
||||
class Setup
|
||||
{
|
||||
/**
|
||||
* Use this method to register all autoloads for a downloaded Doctrine library.
|
||||
* Pick the directory the library was uncompressed into.
|
||||
*
|
||||
* @param string $directory
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function registerAutoloadDirectory($directory)
|
||||
{
|
||||
if (!class_exists('Doctrine\Common\ClassLoader', false)) {
|
||||
require_once $directory . "/Doctrine/Common/ClassLoader.php";
|
||||
}
|
||||
|
||||
$loader = new ClassLoader("Doctrine", $directory);
|
||||
$loader->register();
|
||||
|
||||
$loader = new ClassLoader("Symfony\Component", $directory . "/Doctrine");
|
||||
$loader->register();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a configuration with an annotation metadata driver.
|
||||
*
|
||||
* @param array $paths
|
||||
* @param boolean $isDevMode
|
||||
* @param string $proxyDir
|
||||
* @param Cache $cache
|
||||
* @param bool $useSimpleAnnotationReader
|
||||
*
|
||||
* @return Configuration
|
||||
*/
|
||||
public static function createAnnotationMetadataConfiguration(array $paths, $isDevMode = false, $proxyDir = null, Cache $cache = null, $useSimpleAnnotationReader = true)
|
||||
{
|
||||
$config = self::createConfiguration($isDevMode, $proxyDir, $cache);
|
||||
$config->setMetadataDriverImpl($config->newDefaultAnnotationDriver($paths, $useSimpleAnnotationReader));
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a configuration with a xml metadata driver.
|
||||
*
|
||||
* @param array $paths
|
||||
* @param boolean $isDevMode
|
||||
* @param string $proxyDir
|
||||
* @param Cache $cache
|
||||
*
|
||||
* @return Configuration
|
||||
*/
|
||||
public static function createXMLMetadataConfiguration(array $paths, $isDevMode = false, $proxyDir = null, Cache $cache = null)
|
||||
{
|
||||
$config = self::createConfiguration($isDevMode, $proxyDir, $cache);
|
||||
$config->setMetadataDriverImpl(new XmlDriver($paths));
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a configuration with a yaml metadata driver.
|
||||
*
|
||||
* @param array $paths
|
||||
* @param boolean $isDevMode
|
||||
* @param string $proxyDir
|
||||
* @param Cache $cache
|
||||
*
|
||||
* @return Configuration
|
||||
*/
|
||||
public static function createYAMLMetadataConfiguration(array $paths, $isDevMode = false, $proxyDir = null, Cache $cache = null)
|
||||
{
|
||||
$config = self::createConfiguration($isDevMode, $proxyDir, $cache);
|
||||
$config->setMetadataDriverImpl(new YamlDriver($paths));
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a configuration without a metadata driver.
|
||||
*
|
||||
* @param bool $isDevMode
|
||||
* @param string $proxyDir
|
||||
* @param Cache $cache
|
||||
*
|
||||
* @return Configuration
|
||||
*/
|
||||
public static function createConfiguration($isDevMode = false, $proxyDir = null, Cache $cache = null)
|
||||
{
|
||||
$proxyDir = $proxyDir ?: sys_get_temp_dir();
|
||||
$cache = self::createCacheConfiguration($isDevMode, $proxyDir, $cache);
|
||||
|
||||
$config = new Configuration();
|
||||
$config->setMetadataCacheImpl($cache);
|
||||
$config->setQueryCacheImpl($cache);
|
||||
$config->setResultCacheImpl($cache);
|
||||
$config->setProxyDir($proxyDir);
|
||||
$config->setProxyNamespace('DoctrineProxies');
|
||||
$config->setAutoGenerateProxyClasses($isDevMode);
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $isDevMode
|
||||
* @param string $proxyDir
|
||||
* @param Cache|null $cache
|
||||
*
|
||||
* @return Cache
|
||||
*/
|
||||
private static function createCacheConfiguration($isDevMode, $proxyDir, Cache $cache = null)
|
||||
{
|
||||
$cache = self::createCacheInstance($isDevMode, $cache);
|
||||
|
||||
if ( ! $cache instanceof CacheProvider) {
|
||||
return $cache;
|
||||
}
|
||||
|
||||
$namespace = $cache->getNamespace();
|
||||
|
||||
if ($namespace !== '') {
|
||||
$namespace .= ':';
|
||||
}
|
||||
|
||||
$cache->setNamespace($namespace . 'dc2_' . md5($proxyDir) . '_'); // to avoid collisions
|
||||
|
||||
return $cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $isDevMode
|
||||
* @param Cache|null $cache
|
||||
*
|
||||
* @return Cache
|
||||
*/
|
||||
private static function createCacheInstance($isDevMode, Cache $cache = null)
|
||||
{
|
||||
if ($cache !== null) {
|
||||
return $cache;
|
||||
}
|
||||
|
||||
if ($isDevMode === true) {
|
||||
return new ArrayCache();
|
||||
}
|
||||
|
||||
if (extension_loaded('apc')) {
|
||||
return new \Doctrine\Common\Cache\ApcCache();
|
||||
}
|
||||
|
||||
if (extension_loaded('xcache')) {
|
||||
return new \Doctrine\Common\Cache\XcacheCache();
|
||||
}
|
||||
|
||||
if (extension_loaded('memcache')) {
|
||||
$memcache = new \Memcache();
|
||||
$memcache->connect('127.0.0.1');
|
||||
|
||||
$cache = new \Doctrine\Common\Cache\MemcacheCache();
|
||||
$cache->setMemcache($memcache);
|
||||
|
||||
return $cache;
|
||||
}
|
||||
|
||||
if (extension_loaded('redis')) {
|
||||
$redis = new \Redis();
|
||||
$redis->connect('127.0.0.1');
|
||||
|
||||
$cache = new \Doctrine\Common\Cache\RedisCache();
|
||||
$cache->setRedis($redis);
|
||||
|
||||
return $cache;
|
||||
}
|
||||
|
||||
return new ArrayCache();
|
||||
}
|
||||
}
|
||||
42
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/ToolEvents.php
vendored
Normal file
42
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/ToolEvents.php
vendored
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
<?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\ORM\Tools;
|
||||
|
||||
class ToolEvents
|
||||
{
|
||||
/**
|
||||
* The postGenerateSchemaTable event occurs in SchemaTool#getSchemaFromMetadata()
|
||||
* whenever an entity class is transformed into its table representation. It receives
|
||||
* the current non-complete Schema instance, the Entity Metadata Class instance and
|
||||
* the Schema Table instance of this entity.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const postGenerateSchemaTable = 'postGenerateSchemaTable';
|
||||
|
||||
/**
|
||||
* The postGenerateSchema event is triggered in SchemaTool#getSchemaFromMetadata()
|
||||
* after all entity classes have been transformed into the related Schema structure.
|
||||
* The EventArgs contain the EntityManager and the created Schema instance.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const postGenerateSchema = 'postGenerateSchema';
|
||||
}
|
||||
51
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/ToolsException.php
vendored
Normal file
51
vendor/doctrine/orm/lib/Doctrine/ORM/Tools/ToolsException.php
vendored
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
<?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\ORM\Tools;
|
||||
|
||||
use Doctrine\ORM\ORMException;
|
||||
|
||||
/**
|
||||
* Tools related Exceptions.
|
||||
*
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
*/
|
||||
class ToolsException extends ORMException
|
||||
{
|
||||
/**
|
||||
* @param string $sql
|
||||
* @param \Exception $e
|
||||
*
|
||||
* @return ToolsException
|
||||
*/
|
||||
public static function schemaToolFailure($sql, \Exception $e)
|
||||
{
|
||||
return new self("Schema-Tool failed with Error '" . $e->getMessage() . "' while executing DDL: " . $sql, "0", $e);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
*
|
||||
* @return ToolsException
|
||||
*/
|
||||
public static function couldNotMapDoctrine1Type($type)
|
||||
{
|
||||
return new self("Could not map doctrine 1 type '$type'!");
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue