Showing with 656 additions and 275 deletions.
  1. +15 −0 CHANGELOG.md
  2. +2 −2 composer.json
  3. +2 −0 src/Command/DoctrineMigrationsDiffCommand.php
  4. +4 −1 src/Command/InstallCommand.php
  5. +4 −4 src/Composer/ScriptHandler.php
  6. +63 −0 src/Cors/WebsiteRootsConfigProvider.php
  7. +18 −49 src/DependencyInjection/Compiler/DoctrineMigrationsPass.php
  8. +55 −10 src/Doctrine/Schema/DcaSchemaProvider.php
  9. +1 −1 src/EventListener/MergeHttpHeadersListener.php
  10. +1 −1 src/Resources/config/listener.yml
  11. +10 −5 src/Resources/config/services.yml
  12. +1 −1 src/Resources/contao/classes/Frontend.php
  13. +8 −0 src/Resources/contao/classes/FrontendTemplate.php
  14. +1 −1 src/Resources/contao/config/constants.php
  15. +8 −1 src/Resources/contao/dca/tl_files.php
  16. +6 −0 src/Resources/contao/drivers/DC_Folder.php
  17. +14 −2 src/Resources/contao/drivers/DC_Table.php
  18. +11 −0 src/Resources/contao/languages/es/default.xlf
  19. +1 −0 src/Resources/contao/languages/es/exception.xlf
  20. +2 −0 src/Resources/contao/languages/es/explain.xlf
  21. +1 −0 src/Resources/contao/languages/es/languages.xlf
  22. +3 −1 src/Resources/contao/languages/es/tl_image_size.xlf
  23. +1 −0 src/Resources/contao/languages/es/tl_layout.xlf
  24. +6 −0 src/Resources/contao/languages/es/tl_page.xlf
  25. +2 −0 src/Resources/contao/languages/es/tl_theme.xlf
  26. +4 −0 src/Resources/contao/languages/zh/default.xlf
  27. +1 −0 src/Resources/contao/languages/zh/exception.xlf
  28. +2 −0 src/Resources/contao/languages/zh/explain.xlf
  29. +6 −0 src/Resources/contao/languages/zh/tl_page.xlf
  30. +1 −1 src/Resources/contao/library/Contao/Config.php
  31. +4 −15 src/Resources/contao/library/Contao/Controller.php
  32. +2 −1 src/Resources/contao/library/Contao/Environment.php
  33. +5 −1 src/Resources/contao/library/Contao/Feed.php
  34. +1 −1 src/Resources/contao/library/Contao/Folder.php
  35. +10 −3 src/Resources/contao/library/Contao/Search.php
  36. +44 −11 src/Resources/contao/library/Contao/Widget.php
  37. +1 −1 src/Resources/contao/themes/flexible/main.css
  38. +5 −13 src/Resources/contao/themes/flexible/src/main.css
  39. +3 −3 src/Resources/public/core.js
  40. +1 −1 src/Resources/public/core.min.js
  41. +4 −2 tests/Contao/EnvironmentTest.php
  42. +180 −0 tests/Cors/WebsiteRootsConfigProviderTest.php
  43. +15 −41 tests/DependencyInjection/Compiler/DoctrineMigrationsPassTest.php
  44. +10 −39 tests/Doctrine/Schema/DcaSchemaProviderTest.php
  45. +4 −1 tests/Doctrine/Schema/MigrationsSchemaProviderTest.php
  46. +92 −0 tests/DoctrineTestCase.php
  47. +21 −62 tests/EventListener/DoctrineSchemaListenerTest.php
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
# Contao core bundle change log

### 4.3.6 (2017-03-22)

* Correctly initialize custom entry points (see #713).
* Correctly parse Doctrine SQL arrays in DCA files (see #721).
* Also apply the tree view filter settings to the child table (see #716).
* Also delete the symlink if a public folder is deleted (see #710).
* Use the selected template for custom sections (see #703).
* Handle absolute URLs in Environment::requestUri() (see contao/core#8661).
* Correctly store numbers with leading zero in the Config class (see contao/core#4035).
* Delete an old search entry if the new URL is more canonical (see contao/core#8647).
* Also make Folder::$dirname an absolute path again (see contao/core#8325).
* Reduce the meta description length to 160 characters (see #706).
* Do not add empty author tags to an Atom feed (see contao/news-bundle#9).
* Fix the position of the sort hint if the widget is not the first one (see #722).

### 4.3.5 (2017-02-14)

* Skip the incomplete installation test in the install tool.
Expand Down
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"league/uri": "^4.0",
"matthiasmullie/minify": "^1.3",
"michelf/php-markdown": "^1.4",
"nelmio/cors-bundle": "^1.5",
"oyejorge/less.php": "^1.7",
"patchwork/utf8": "^1.2",
"phpspec/php-diff": "^1.0",
Expand Down Expand Up @@ -59,7 +60,7 @@
"contao-components/mediaelement": "^2.21.1",
"contao-components/mootools": "^1.6.0.1",
"contao-components/respimage": "^1.4",
"contao-components/simplemodal": "^1.2.3",
"contao-components/simplemodal": "^1.2.4",
"contao-components/swipe": "^2.0.3",
"contao-components/tablesort": "^3.4.5",
"contao-components/tablesorter": "^2.0.5.3",
Expand Down Expand Up @@ -95,7 +96,6 @@
"src/Resources/contao/"
],
"exclude-from-classmap": [
"tests/",
"src/Resources/contao/config/",
"src/Resources/contao/dca/",
"src/Resources/contao/helper/",
Expand Down
2 changes: 2 additions & 0 deletions src/Command/DoctrineMigrationsDiffCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
*/
class DoctrineMigrationsDiffCommand extends DiffCommand
{
const COMMAND_ID = 'console.command.contao_corebundle_command_doctrinemigrationsdiffcommand';

/**
* {@inheritdoc}
*/
Expand Down
5 changes: 4 additions & 1 deletion src/Command/InstallCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,11 @@ private function addInitializePhp()
/** @var Composer\Autoload\ClassLoader */
$loader = require __DIR__ . '/../app/autoload.php';
$request = Request::create('/_contao/initialize', 'GET', [], $_COOKIE, [], $_SERVER);
$request->attributes->set('_scope', ('BE' === TL_MODE ? 'backend' : 'frontend'));
$kernel = new AppKernel('prod', false);
$response = $kernel->handle(Request::create('/_contao/initialize', 'GET', [], [], [], $_SERVER));
$response = $kernel->handle($request);
// Send the response if not generated by the InitializeController
if (!($response instanceof InitializeControllerResponse)) {
Expand Down
8 changes: 4 additions & 4 deletions src/Composer/ScriptHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -147,14 +147,14 @@ private static function getVerbosityFlag(Event $event)
$io = $event->getIO();

switch (true) {
case $io->isVerbose():
return ' -v';
case $io->isDebug():
return ' -vvv';

case $io->isVeryVerbose():
return ' -vv';

case $io->isDebug():
return ' -vvv';
case $io->isVerbose():
return ' -v';

default:
return '';
Expand Down
63 changes: 63 additions & 0 deletions src/Cors/WebsiteRootsConfigProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php

/*
* This file is part of Contao.
*
* Copyright (c) 2005-2017 Leo Feyer
*
* @license LGPL-3.0+
*/

namespace Contao\CoreBundle\Cors;

use Doctrine\DBAL\Connection;
use Nelmio\CorsBundle\Options\ProviderInterface;
use Symfony\Component\HttpFoundation\Request;

/**
* Provides the configuration for the nelmio/cors-bundle.
*
* @author Yanick Witschi <https://github.com/toflar>
*/
class WebsiteRootsConfigProvider implements ProviderInterface
{
/**
* @var Connection
*/
private $connection;

/**
* Constructor.
*
* @param Connection $connection
*/
public function __construct(Connection $connection)
{
$this->connection = $connection;
}

/**
* {@inheritdoc}
*/
public function getOptions(Request $request)
{
if (!$request->headers->has('Origin') || '' === $request->headers->get('Origin')) {
return [];
}

$stmt = $this->connection->prepare('SELECT id FROM tl_page WHERE type=:type AND dns=:dns');
$stmt->bindValue('type', 'root');
$stmt->bindValue('dns', preg_replace('@^https?://@', '', $request->headers->get('origin')));
$stmt->execute();

if (0 === $stmt->rowCount()) {
return [];
}

return [
'allow_origin' => true,
'allow_methods' => ['HEAD', 'GET'],
'allow_headers' => ['x-requested-with'],
];
}
}
67 changes: 18 additions & 49 deletions src/DependencyInjection/Compiler/DoctrineMigrationsPass.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@

namespace Contao\CoreBundle\DependencyInjection\Compiler;

use Contao\CoreBundle\Command\DoctrineMigrationsDiffCommand;
use Contao\CoreBundle\Doctrine\Schema\MigrationsSchemaProvider;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\DefinitionDecorator;
use Symfony\Component\DependencyInjection\Reference;

/**
* @author Andreas Schempp <https://github.com/aschempp>
Expand All @@ -31,21 +33,23 @@ public function process(ContainerBuilder $container)
return;
}

if ($this->hasOrm($container)) {
// Use Doctrine mapping (enhanced by our listeners) for schema if ORM is installed
$provider = new Definition(
'Doctrine\DBAL\Migrations\Provider\OrmSchemaProvider',
[$container->findDefinition('doctrine.orm.entity_manager')]
);
} else {
// Migrations schema provider must implement interface (only available if bundle is installed)
$provider = new DefinitionDecorator('contao.doctrine.dca_schema_provider');
$provider->setClass('Contao\CoreBundle\Doctrine\Schema\MigrationsSchemaProvider');
$provider = new Definition(MigrationsSchemaProvider::class);
$provider->addArgument(new Reference('contao.framework'));
$provider->addArgument(new Reference('doctrine'));

$this->registerDiffCommand($container, $provider);
}
$command = new Definition(DoctrineMigrationsDiffCommand::class);
$command->setArguments([$provider]);
$command->addTag('console.command');

$container->setDefinition(DoctrineMigrationsDiffCommand::COMMAND_ID, $command);

// Required if Symfony's compiler pass has already handled the "console.command" tags
if ($container->hasParameter('console.command.ids')) {
$ids = $container->getParameter('console.command.ids');
$ids[] = static::DIFF_COMMAND_ID;

$container->setDefinition('contao.doctrine.schema_provider', $provider);
$container->setParameter('console.command.ids', $ids);
}
}

/**
Expand All @@ -63,39 +67,4 @@ private function hasMigrationsBundle(ContainerBuilder $container)
true
);
}

/**
* Checks if Doctrine ORM is enabled.
*
* @param ContainerBuilder $container
*
* @return bool
*/
private function hasOrm(ContainerBuilder $container)
{
return $container->has('doctrine.orm.entity_manager');
}

/**
* Registers the custom doctrine:schema:diff command that works without ORM.
*
* @param ContainerBuilder $container
* @param Definition $provider
*/
private function registerDiffCommand(ContainerBuilder $container, Definition $provider)
{
$command = new Definition('Contao\CoreBundle\Command\DoctrineMigrationsDiffCommand');
$command->setArguments([$provider]);
$command->addTag('console.command');

$container->setDefinition(static::DIFF_COMMAND_ID, $command);

// Required if Symfony's compiler pass has already handled the "console.command" tags
if ($container->hasParameter('console.command.ids')) {
$ids = $container->getParameter('console.command.ids');
$ids[] = static::DIFF_COMMAND_ID;

$container->setParameter('console.command.ids', $ids);
}
}
}
65 changes: 55 additions & 10 deletions src/Doctrine/Schema/DcaSchemaProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,29 +10,40 @@

namespace Contao\CoreBundle\Doctrine\Schema;

use Contao\CoreBundle\Framework\ContaoFrameworkInterface;
use Contao\Database\Installer;
use Doctrine\Bundle\DoctrineBundle\Registry;
use Doctrine\DBAL\Platforms\MySqlPlatform;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Schema\Table;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Tools\SchemaTool;

/**
* @author Andreas Schempp <https://github.com/aschempp>
*/
class DcaSchemaProvider
{
/**
* @var ContainerInterface
* @var ContaoFrameworkInterface
*/
private $container;
private $framework;

/**
* @var Registry
*/
private $doctrine;

/**
* Constructor.
*
* @param ContainerInterface $container
* @param ContaoFrameworkInterface $framework
* @param Registry|null $doctrine
*/
public function __construct(ContainerInterface $container)
public function __construct(ContaoFrameworkInterface $framework, Registry $doctrine = null)
{
$this->container = $container;
$this->framework = $framework;
$this->doctrine = $doctrine;
}

/**
Expand All @@ -41,6 +52,40 @@ public function __construct(ContainerInterface $container)
* @return Schema
*/
public function createSchema()
{
if (0 !== count($this->doctrine->getManagerNames())) {
return $this->createSchemaFromOrm();
}

return $this->createSchemaFromDca();
}

/**
* Creates a Schema instance from Doctrine ORM metadata.
*
* @return Schema
*/
private function createSchemaFromOrm()
{
/** @var EntityManagerInterface $manager */
$manager = $this->doctrine->getManager();
$metadata = $manager->getMetadataFactory()->getAllMetadata();

if (empty($metadata)) {
return $this->createSchemaFromDca();
}

$tool = new SchemaTool($manager);

return $tool->getSchemaFromMetadata($metadata);
}

/**
* Creates a Schema instance and adds DCA metadata.
*
* @return Schema
*/
private function createSchemaFromDca()
{
$schema = new Schema();

Expand Down Expand Up @@ -113,7 +158,7 @@ private function parseColumnSql(Table $table, $columnName, $sql)

$this->setLengthAndPrecisionByType($type, $dbType, $length, $scale, $precision, $fixed);

$type = $this->container->get('database_connection')->getDatabasePlatform()->getDoctrineTypeMapping($type);
$type = $this->doctrine->getConnection()->getDatabasePlatform()->getDoctrineTypeMapping($type);
$length = (0 === (int) $length) ? null : (int) $length;

if (preg_match('/default (\'[^\']*\'|\d+)/', $def, $match)) {
Expand Down Expand Up @@ -262,10 +307,10 @@ private function parseIndexSql(Table $table, $keyName, $sql)
*/
private function getSqlDefinitions()
{
$framework = $this->container->get('contao.framework');
$framework->initialize();
$this->framework->initialize();

$installer = $framework->createInstance('Contao\Database\Installer');
/** @var Installer $installer */
$installer = $this->framework->createInstance('Contao\Database\Installer');

$sqlTarget = $installer->getFromDca();
$sqlLegacy = $installer->getFromFile();
Expand Down
2 changes: 1 addition & 1 deletion src/EventListener/MergeHttpHeadersListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ private function mergeHttpHeaders(Response $response)
foreach ($this->getHeaders() as $header) {
list($name, $content) = explode(':', $header, 2);

if ('cli' !== PHP_SAPI) {
if ('cli' !== PHP_SAPI && !headers_sent()) {
header_remove($name);
}

Expand Down
2 changes: 1 addition & 1 deletion src/Resources/config/listener.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ services:
contao.listener.doctrine_schema:
class: Contao\CoreBundle\EventListener\DoctrineSchemaListener
arguments:
- "@contao.doctrine.dca_schema_provider"
- "@contao.doctrine.schema_provider"
tags:
- { name: doctrine.event_listener, event: onSchemaIndexDefinition }
- { name: doctrine.event_listener, event: postGenerateSchema }
Expand Down
Loading