Commit 1df767ef authored by Tino Goratsch's avatar Tino Goratsch

Merge branch 'release/v4.12.0'

parents a4cbcdab fe93902b
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
/ACP3/Core/Test export-ignore /ACP3/Core/Test export-ignore
/ACP3/Modules/*/Test export-ignore /ACP3/Modules/*/Test export-ignore
/build export-ignore
.codeclimate.yml export-ignore .codeclimate.yml export-ignore
.coveralls.yml export-ignore .coveralls.yml export-ignore
.editorconfig export-ignore .editorconfig export-ignore
...@@ -10,4 +11,6 @@ ...@@ -10,4 +11,6 @@
.eslintrc export-ignore .eslintrc export-ignore
.gitattributes export-ignore .gitattributes export-ignore
.gitignore export-ignore .gitignore export-ignore
.php_cs.dist export-ignore
.sami.php export-ignore
.travis.yml export-ignore .travis.yml export-ignore
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
/.php_cs.cache /.php_cs.cache
/ACP3/config.yml /ACP3/config.yml
/build/logs/ /build/logs/
/build/sami/
/cache/* /cache/*
/node_modules /node_modules
/tests/cache/ /tests/cache/
......
<?php
/**
* Copyright (c) by the ACP3 Developers.
* See the LICENCE file at the top-level module directory for licencing details.
*/
use Sami\Sami;
use Symfony\Component\Finder\Finder;
$iterator = Finder::create()
->files()
->name('*.php')
->exclude('Resources')
->exclude('Tests')
->exclude('Modules/ACP3/Filemanager/libraries/kcfinder')
->in($dir = __DIR__ . '/ACP3');
return new Sami($iterator, array(
'title' => 'ACP3 CMS API',
'build_dir' => __DIR__ . '/build/sami/docs',
'cache_dir' => __DIR__ . '/build/sami/cache',
'default_opened_level' => 2,
));
...@@ -54,6 +54,12 @@ deploy: ...@@ -54,6 +54,12 @@ deploy:
on: on:
tags: true tags: true
condition: "$TRAVIS_PHP_VERSION = 7.0*" condition: "$TRAVIS_PHP_VERSION = 7.0*"
- provider: script
script: ./build/travis/generate_api_docs.sh
skip_cleanup: true
on:
branch: master
condition: "$TRAVIS_PHP_VERSION = 7.0*"
cache: cache:
directories: directories:
......
...@@ -14,7 +14,7 @@ interface BootstrapInterface extends HttpKernelInterface ...@@ -14,7 +14,7 @@ interface BootstrapInterface extends HttpKernelInterface
/** /**
* Contains the current ACP3 version string * Contains the current ACP3 version string
*/ */
const VERSION = '4.11.1'; const VERSION = '4.12.0';
/** /**
* Performs some startup checks * Performs some startup checks
......
...@@ -11,21 +11,9 @@ use ACP3\Core; ...@@ -11,21 +11,9 @@ use ACP3\Core;
/** /**
* Class AbstractAdminAction * Class AbstractAdminAction
* @package ACP3\Core\Controller * @package ACP3\Core\Controller
*
* @deprecated Since version 4.12.0. To be removed with version 5.0.0. Use the AbstractFrontendAction instead
*/ */
abstract class AbstractAdminAction extends Core\Controller\AbstractFrontendAction abstract class AbstractAdminAction extends Core\Controller\AbstractFrontendAction
{ {
/**
* @return $this
* @throws \ACP3\Core\Authentication\Exception\UnauthorizedAccessException
*/
public function preDispatch()
{
if ($this->user->isAuthenticated() === false) {
throw new Core\Authentication\Exception\UnauthorizedAccessException();
}
parent::preDispatch();
return $this;
}
} }
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
namespace ACP3\Core\I18n; namespace ACP3\Core\I18n;
use Giggsey\Locale\Locale;
class CountryList class CountryList
{ {
/** /**
...@@ -16,6 +18,10 @@ class CountryList ...@@ -16,6 +18,10 @@ class CountryList
* @var null|array * @var null|array
*/ */
private $countries = null; private $countries = null;
/**
* @var null|array
*/
private $supportedLocales = null;
/** /**
* Country constructor. * Country constructor.
...@@ -42,36 +48,33 @@ class CountryList ...@@ -42,36 +48,33 @@ class CountryList
private function cacheWorldCountries() private function cacheWorldCountries()
{ {
$basePath = ACP3_ROOT_DIR . 'vendor/giggsey/locale/data/';
$supportedLocales = include $basePath . '_list.php';
$this->countries = []; $this->countries = [];
if ($this->isSupportedLocale($supportedLocales)) {
$paths = [
$basePath . $this->getTransformedLocale() . '.php',
$basePath . $this->translator->getShortIsoCode() . '.php'
];
foreach ($paths as $path) {
if (is_file($path)) {
$this->countries = include $path;
break;
}
}
asort($this->countries, SORT_STRING); $locales = [
$this->getTransformedLocale(),
$this->translator->getShortIsoCode()
];
foreach ($locales as $locale) {
if ($this->isSupportedLocale($locale)) {
$this->countries = Locale::getAllCountriesForLocale($locale);
}
} }
asort($this->countries, SORT_STRING);
} }
/** /**
* @param array $supportedLocales * @param string $locale
* @return bool * @return bool
*/ */
private function isSupportedLocale(array $supportedLocales) private function isSupportedLocale($locale)
{ {
$localeAndRegion = $this->getTransformedLocale(); if ($this->supportedLocales === null) {
$this->supportedLocales = Locale::getSupportedLocales();
}
return array_key_exists($localeAndRegion, $supportedLocales) return in_array($locale, $this->supportedLocales);
|| array_key_exists($this->translator->getShortIsoCode(), $supportedLocales);
} }
/** /**
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
namespace ACP3\Core; namespace ACP3\Core;
use ACP3\Core\Environment\ApplicationPath; use ACP3\Core\Environment\ApplicationPath;
use FastImageSize\FastImageSize;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
/** /**
...@@ -50,6 +51,10 @@ class Picture ...@@ -50,6 +51,10 @@ class Picture
*/ */
protected $forceResample = false; protected $forceResample = false;
/**
* @var FastImageSize
*/
private $fastImageSize;
/** /**
* @var \Symfony\Component\HttpFoundation\Response * @var \Symfony\Component\HttpFoundation\Response
*/ */
...@@ -69,15 +74,18 @@ class Picture ...@@ -69,15 +74,18 @@ class Picture
protected $image; protected $image;
/** /**
* @param FastImageSize $fastImageSize
* @param \Symfony\Component\HttpFoundation\Response $response * @param \Symfony\Component\HttpFoundation\Response $response
* @param \ACP3\Core\Environment\ApplicationPath $appPath * @param \ACP3\Core\Environment\ApplicationPath $appPath
* @param string $environment * @param string $environment
*/ */
public function __construct( public function __construct(
FastImageSize $fastImageSize,
Response $response, Response $response,
ApplicationPath $appPath, ApplicationPath $appPath,
$environment $environment
) { ) {
$this->fastImageSize = $fastImageSize;
$this->response = $response; $this->response = $response;
$this->appPath = $appPath; $this->appPath = $appPath;
$this->environment = $environment; $this->environment = $environment;
...@@ -216,12 +224,13 @@ class Picture ...@@ -216,12 +224,13 @@ class Picture
{ {
if (is_file($this->file) === true) { if (is_file($this->file) === true) {
$cacheFile = $this->getCacheFileName(); $cacheFile = $this->getCacheFileName();
$picInfo = getimagesize($this->file);
$width = $picInfo[0];
$height = $picInfo[1];
$type = $picInfo[2];
$this->setHeaders($picInfo['mime']); $picInfo = $this->fastImageSize->getImageSize($this->file);
$width = $picInfo['width'];
$height = $picInfo['height'];
$type = $picInfo['type'];
$this->setHeaders($this->getMimeType($type));
// Direct output of the picture, if it is already cached // Direct output of the picture, if it is already cached
if ($this->enableCache === true && is_file($cacheFile) === true) { if ($this->enableCache === true && is_file($cacheFile) === true) {
...@@ -250,6 +259,24 @@ class Picture ...@@ -250,6 +259,24 @@ class Picture
return false; return false;
} }
/**
* @param int $pictureType
* @return string
*/
private function getMimeType($pictureType)
{
switch($pictureType) {
case IMAGETYPE_GIF:
return 'image/gif';
case IMAGETYPE_JPEG:
return 'image/jpeg';
case IMAGETYPE_PNG:
return 'image/png';
}
return '';
}
/** /**
* @return \Symfony\Component\HttpFoundation\Response * @return \Symfony\Component\HttpFoundation\Response
*/ */
...@@ -325,17 +352,17 @@ class Picture ...@@ -325,17 +352,17 @@ class Picture
{ {
$this->image = imagecreatetruecolor($newWidth, $newHeight); $this->image = imagecreatetruecolor($newWidth, $newHeight);
switch ($type) { switch ($type) {
case 1: case IMAGETYPE_GIF:
$origPicture = imagecreatefromgif($this->file); $origPicture = imagecreatefromgif($this->file);
$this->scalePicture($newWidth, $newHeight, $width, $height, $origPicture); $this->scalePicture($newWidth, $newHeight, $width, $height, $origPicture);
imagegif($this->image, $cacheFile); imagegif($this->image, $cacheFile);
break; break;
case 2: case IMAGETYPE_JPEG:
$origPicture = imagecreatefromjpeg($this->file); $origPicture = imagecreatefromjpeg($this->file);
$this->scalePicture($newWidth, $newHeight, $width, $height, $origPicture); $this->scalePicture($newWidth, $newHeight, $width, $height, $origPicture);
imagejpeg($this->image, $cacheFile, $this->jpgQuality); imagejpeg($this->image, $cacheFile, $this->jpgQuality);
break; break;
case 3: case IMAGETYPE_PNG:
imagealphablending($this->image, false); imagealphablending($this->image, false);
$origPicture = imagecreatefrompng($this->file); $origPicture = imagecreatefrompng($this->file);
$this->scalePicture($newWidth, $newHeight, $width, $height, $origPicture); $this->scalePicture($newWidth, $newHeight, $width, $height, $origPicture);
...@@ -382,7 +409,8 @@ class Picture ...@@ -382,7 +409,8 @@ class Picture
*/ */
protected function resamplingIsNecessary($width, $height, $type) protected function resamplingIsNecessary($width, $height, $type)
{ {
return ($this->forceResample === true || ($width > $this->maxWidth || $height > $this->maxHeight)) && ($type === 1 || $type === 2 || $type === 3); return ($this->forceResample === true || ($width > $this->maxWidth || $height > $this->maxHeight))
&& in_array($type, [IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG]);
} }
/** /**
......
...@@ -32,7 +32,7 @@ class CountryListTest extends \PHPUnit_Framework_TestCase ...@@ -32,7 +32,7 @@ class CountryListTest extends \PHPUnit_Framework_TestCase
public function testValidLocale() public function testValidLocale()
{ {
$this->translatorMock->expects($this->exactly(6)) $this->translatorMock->expects($this->exactly(3))
->method('getLocale') ->method('getLocale')
->willReturn('en_US'); ->willReturn('en_US');
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
"fisharebest/localization": "^1.10", "fisharebest/localization": "^1.10",
"giggsey/locale": "^1.2", "giggsey/locale": "^1.2",
"inlinestyle/inlinestyle": "^1.2", "inlinestyle/inlinestyle": "^1.2",
"marc1706/fast-image-size": "^1.1",
"monolog/monolog": "^1.21", "monolog/monolog": "^1.21",
"mrclay/minify": "^3.0", "mrclay/minify": "^3.0",
"patchwork/utf8": "^1.3", "patchwork/utf8": "^1.3",
......
...@@ -45,9 +45,13 @@ services: ...@@ -45,9 +45,13 @@ services:
core.environment.application_path: core.environment.application_path:
synthetic: true synthetic: true
fast_image_size:
class: FastImageSize\FastImageSize
core.image: core.image:
class: ACP3\Core\Picture class: ACP3\Core\Picture
arguments: arguments:
- '@fast_image_size'
- '@core.http.response' - '@core.http.response'
- '@core.environment.application_path' - '@core.environment.application_path'
- '%core.environment%' - '%core.environment%'
......
...@@ -12,7 +12,7 @@ use ACP3\Core; ...@@ -12,7 +12,7 @@ use ACP3\Core;
* Class Index * Class Index
* @package ACP3\Modules\ACP3\Acp\Controller\Admin\Index * @package ACP3\Modules\ACP3\Acp\Controller\Admin\Index
*/ */
class Index extends Core\Controller\AbstractAdminAction class Index extends Core\Controller\AbstractFrontendAction
{ {
/** /**
* @return array * @return array
......
...@@ -17,12 +17,12 @@ ...@@ -17,12 +17,12 @@
"prefer-stable": true, "prefer-stable": true,
"require": { "require": {
"acp3/composer-installer": "*", "acp3/composer-installer": "*",
"acp3/core": "^4.11.1", "acp3/core": "^4.12.0",
"acp3/setup": "^4.11.1", "acp3/setup": "^4.12.0",
"acp3/module-errors": "^4.11.1", "acp3/module-errors": "^4.12.0",
"acp3/module-permissions": "^4.11.1", "acp3/module-permissions": "^4.12.0",
"acp3/module-system": "^4.11.1", "acp3/module-system": "^4.12.0",
"acp3/module-users": "^4.11.1" "acp3/module-users": "^4.12.0"
}, },
"autoload": { "autoload": {
"psr-4": { "psr-4": {
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
namespace ACP3\Modules\ACP3\Articles\Controller\Admin\Index; namespace ACP3\Modules\ACP3\Articles\Controller\Admin\Index;
use ACP3\Core; use ACP3\Core;
use ACP3\Core\Controller\AbstractAdminAction; use ACP3\Core\Controller\AbstractFrontendAction;
use ACP3\Modules\ACP3\Articles; use ACP3\Modules\ACP3\Articles;
use ACP3\Modules\ACP3\Menus; use ACP3\Modules\ACP3\Menus;
...@@ -15,7 +15,7 @@ use ACP3\Modules\ACP3\Menus; ...@@ -15,7 +15,7 @@ use ACP3\Modules\ACP3\Menus;
* Class AbstractFormAction * Class AbstractFormAction
* @package ACP3\Modules\ACP3\Articles\Controller\Admin\Index * @package ACP3\Modules\ACP3\Articles\Controller\Admin\Index
*/ */
abstract class AbstractFormAction extends AbstractAdminAction abstract class AbstractFormAction extends AbstractFrontendAction
{ {
/** /**
* @var Core\Helpers\Forms * @var Core\Helpers\Forms
......
...@@ -13,7 +13,7 @@ use ACP3\Modules\ACP3\Articles; ...@@ -13,7 +13,7 @@ use ACP3\Modules\ACP3\Articles;
* Class Delete * Class Delete
* @package ACP3\Modules\ACP3\Articles\Controller\Admin\Index * @package ACP3\Modules\ACP3\Articles\Controller\Admin\Index
*/ */
class Delete extends Core\Controller\AbstractAdminAction class Delete extends Core\Controller\AbstractFrontendAction
{ {
/** /**
* @var Articles\Model\ArticlesModel * @var Articles\Model\ArticlesModel
......
...@@ -7,11 +7,11 @@ ...@@ -7,11 +7,11 @@
namespace ACP3\Modules\ACP3\Articles\Controller\Admin\Index; namespace ACP3\Modules\ACP3\Articles\Controller\Admin\Index;
use ACP3\Core\Controller\AbstractAdminAction; use ACP3\Core\Controller\AbstractFrontendAction;
use ACP3\Core\Controller\Context\FrontendContext; use ACP3\Core\Controller\Context\FrontendContext;
use ACP3\Modules\ACP3\Articles\Model\ArticlesModel; use ACP3\Modules\ACP3\Articles\Model\ArticlesModel;
class Duplicate extends AbstractAdminAction class Duplicate extends AbstractFrontendAction
{ {
/** /**
* @var ArticlesModel * @var ArticlesModel
......
...@@ -14,7 +14,7 @@ use ACP3\Modules\ACP3\System\Installer\Schema; ...@@ -14,7 +14,7 @@ use ACP3\Modules\ACP3\System\Installer\Schema;
* Class Index * Class Index
* @package ACP3\Modules\ACP3\Articles\Controller\Admin\Index * @package ACP3\Modules\ACP3\Articles\Controller\Admin\Index
*/ */
class Index extends Core\Controller\AbstractAdminAction class Index extends Core\Controller\AbstractFrontendAction
{ {
/** /**
* @var \ACP3\Modules\ACP3\Articles\Model\Repository\DataGridRepository * @var \ACP3\Modules\ACP3\Articles\Model\Repository\DataGridRepository
......
...@@ -17,12 +17,12 @@ ...@@ -17,12 +17,12 @@
"prefer-stable": true, "prefer-stable": true,
"require": { "require": {
"acp3/composer-installer": "*", "acp3/composer-installer": "*",
"acp3/core": "^4.11.1", "acp3/core": "^4.12.0",
"acp3/setup": "^4.11.1", "acp3/setup": "^4.12.0",
"acp3/module-errors": "^4.11.1", "acp3/module-errors": "^4.12.0",
"acp3/module-permissions": "^4.11.1", "acp3/module-permissions": "^4.12.0",
"acp3/module-system": "^4.11.1", "acp3/module-system": "^4.12.0",
"acp3/module-users": "^4.11.1" "acp3/module-users": "^4.12.0"
}, },
"suggest": { "suggest": {
"acp3/module-seo": "Provides additional SEO capabilities" "acp3/module-seo": "Provides additional SEO capabilities"
......
...@@ -6,9 +6,9 @@ ...@@ -6,9 +6,9 @@
namespace ACP3\Modules\ACP3\Captcha\Controller\Admin\Index; namespace ACP3\Modules\ACP3\Captcha\Controller\Admin\Index;
use ACP3\Core\Controller\AbstractAdminAction; use ACP3\Core\Controller\AbstractFrontendAction;
class Index extends AbstractAdminAction class Index extends AbstractFrontendAction
{ {
public function execute() public function execute()
{ {
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
namespace ACP3\Modules\ACP3\Captcha\Controller\Admin\Index; namespace ACP3\Modules\ACP3\Captcha\Controller\Admin\Index;
use ACP3\Core\Controller\AbstractAdminAction; use ACP3\Core\Controller\AbstractFrontendAction;
use ACP3\Core\Controller\Context\FrontendContext; use ACP3\Core\Controller\Context\FrontendContext;
use ACP3\Core\Helpers\Forms; use ACP3\Core\Helpers\Forms;
use ACP3\Core\Helpers\FormToken; use ACP3\Core\Helpers\FormToken;
...@@ -15,7 +15,7 @@ use ACP3\Modules\ACP3\Captcha\Installer\Schema; ...@@ -15,7 +15,7 @@ use ACP3\Modules\ACP3\Captcha\Installer\Schema;
use ACP3\Modules\ACP3\Captcha\Utility\CaptchaRegistrar; use ACP3\Modules\ACP3\Captcha\Utility\CaptchaRegistrar;
use ACP3\Modules\ACP3\Captcha\Validation\AdminSettingsFormValidation; use ACP3\Modules\ACP3\Captcha\Validation\AdminSettingsFormValidation;
class Settings extends AbstractAdminAction class Settings extends AbstractFrontendAction
{ {
/** /**
* @var Forms * @var Forms
......
...@@ -17,12 +17,12 @@ ...@@ -17,12 +17,12 @@
"prefer-stable": true, "prefer-stable": true,
"require": { "require": {
"acp3/composer-installer": "*", "acp3/composer-installer": "*",
"acp3/core": "^4.11.1", "acp3/core": "^4.12.0",
"acp3/setup": "^4.11.1", "acp3/setup": "^4.12.0",
"acp3/module-errors": "^4.11.1", "acp3/module-errors": "^4.12.0",
"acp3/module-permissions": "^4.11.1", "acp3/module-permissions": "^4.12.0",
"acp3/module-system": "^4.11.1", "acp3/module-system": "^4.12.0",
"acp3/module-users": "^4.11.1", "acp3/module-users": "^4.12.0",
"google/recaptcha": "^1.1.0" "google/recaptcha": "^1.1.0"
}, },
"autoload": { "autoload": {
......
...@@ -13,7 +13,7 @@ use ACP3\Modules\ACP3\Categories; ...@@ -13,7 +13,7 @@ use ACP3\Modules\ACP3\Categories;
* Class Create * Class Create
* @package ACP3\Modules\ACP3\Categories\Controller\Admin\Index * @package ACP3\Modules\ACP3\Categories\Controller\Admin\Index
*/ */
class Create extends Core\Controller\AbstractAdminAction class Create extends Core\Controller\AbstractFrontendAction
{ {
/** /**
* @var \ACP3\Modules\ACP3\Categories\Validation\AdminFormValidation * @var \ACP3\Modules\ACP3\Categories\Validation\AdminFormValidation
......
...@@ -13,7 +13,7 @@ use ACP3\Modules\ACP3\Categories; ...@@ -13,7 +13,7 @@ use ACP3\Modules\ACP3\Categories;
* Class Delete * Class Delete
* @package ACP3\Modules\ACP3\Categories\Controller\Admin\Index * @package ACP3\Modules\ACP3\Categories\Controller\Admin\Index
*/ */
class Delete extends Core\Controller\AbstractAdminAction class Delete extends Core\Controller\AbstractFrontendAction
{