Commit f42f3c28 authored by Tino Goratsch's avatar Tino Goratsch

Merge branch 'release/v4.4.0'

parents c6b3a494 45aeebed
# Auto detect text files and perform LF normalization
* text=auto
# Custom for Visual Studio
*.cs diff=csharp
*.sln merge=union
*.csproj merge=union
*.vbproj merge=union
*.fsproj merge=union
*.dbproj merge=union
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain
.codeclimate.yml export.ignore
.coveralls.yml export.ignore
.eslintignore.yml export.ignore
.eslintrc export.ignore
.travis.yml export.ignore
/ACP3/Core/Test export-ignore
/ACP3/Modules/*/Test export-ignore
.codeclimate.yml export-ignore
.coveralls.yml export-ignore
.editorconfig export-ignore
.eslintignore export-ignore
.eslintrc export-ignore
.gitattributes export-ignore
.gitignore export-ignore
.travis.yml export-ignore
# Auto detect text files and perform LF normalization
* text=auto
# Custom for Visual Studio
*.cs diff=csharp
*.sln merge=union
*.csproj merge=union
*.vbproj merge=union
*.fsproj merge=union
*.dbproj merge=union
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain
/Test export-ignore
/.gitattributes export-ignore
/.gitignore export-ignore
......@@ -14,7 +14,7 @@ interface BootstrapInterface extends HttpKernelInterface
/**
* Contains the current ACP3 version string
*/
const VERSION = '4.3.6';
const VERSION = '4.4.0';
/**
* Performs some startup checks
......
......@@ -10,9 +10,9 @@ use ACP3\Core;
class PageCssClasses
{
/**
* @var \ACP3\Core\Breadcrumb\Steps
* @var Core\Helpers\StringFormatter
*/
protected $breadcrumb;
protected $stringFormatter;
/**
* @var \ACP3\Core\Breadcrumb\Title
*/
......@@ -28,18 +28,18 @@ class PageCssClasses
protected $details;
/**
* @param \ACP3\Core\Breadcrumb\Steps $breadcrumb
* @param \ACP3\Core\Breadcrumb\Title $title
* @param Core\Helpers\StringFormatter $stringFormatter
* @param \ACP3\Core\Breadcrumb\Title $title
* @param \ACP3\Core\Http\RequestInterface $request
*/
public function __construct(
Core\Breadcrumb\Steps $breadcrumb,
Core\Helpers\StringFormatter $stringFormatter,
Core\Breadcrumb\Title $title,
Core\Http\RequestInterface $request
) {
$this->breadcrumb = $breadcrumb;
$this->title = $title;
$this->request = $request;
$this->stringFormatter = $stringFormatter;
}
/**
......@@ -64,21 +64,7 @@ class PageCssClasses
public function getDetails()
{
if ($this->details === null) {
$pageTitle = preg_replace(
'=[^a-z0-9\-]=',
'',
\Patchwork\Utf8::toAscii(
html_entity_decode(
str_replace(
' ',
'-',
strtolower($this->title->getPageTitle())
),
ENT_QUOTES,
'UTF-8'
)
)
);
$pageTitle = $this->stringFormatter->makeStringUrlSafe($this->title->getPageTitle());
$this->details = $this->request->getModule() . '-' . $this->request->getController() . '-' . $pageTitle;
}
......
......@@ -62,7 +62,7 @@ class Purge
if (is_dir($path)) {
static::purgeCurrentDirectory($path, $cacheId);
if (empty($cacheId)) {
@rmdir($directory);
@rmdir($path);
}
} elseif (empty($cacheId) || strpos($dirContent, $cacheId) !== false) {
@unlink($path);
......
......@@ -63,19 +63,11 @@ abstract class AbstractFrontendAction extends Core\Controller\AbstractWidgetActi
parent::preDispatch();
$this->view->assign([
'PHP_SELF' => $this->appPath->getPhpSelf(),
'REQUEST_URI' => $this->request->getServer()->get('REQUEST_URI'),
'ROOT_DIR' => $this->appPath->getWebRoot(),
'HOST_NAME' => $this->request->getHttpHost(),
'ROOT_DIR_ABSOLUTE' => $this->request->getScheme() . '://' . $this->request->getHttpHost() . $this->appPath->getWebRoot(),
'DESIGN_PATH' => $this->appPath->getDesignPathWeb(),
'DESIGN_PATH_ABSOLUTE' => $this->appPath->getDesignPathAbsolute(),
'UA_IS_MOBILE' => $this->request->getUserAgent()->isMobileBrowser(),
'IN_ADM' => $this->request->getArea() === AreaEnum::AREA_ADMIN,
'IS_HOMEPAGE' => $this->request->isHomepage(),
'IS_AJAX' => $this->request->isXmlHttpRequest(),
'LANG_DIRECTION' => $this->translator->getDirection(),
'LANG' => $this->translator->getShortIsoCode(),
]);
return $this;
......
......@@ -69,6 +69,10 @@ abstract class AbstractWidgetAction implements ActionInterface
* @var Response
*/
protected $response;
/**
* @var Core\Helpers\ResultsPerPage
*/
protected $resultsPerPage;
/**
* WidgetController constructor.
......@@ -90,6 +94,7 @@ abstract class AbstractWidgetAction implements ActionInterface
$this->config = $context->getConfig();
$this->appPath = $context->getAppPath();
$this->response = $context->getResponse();
$this->resultsPerPage = $context->getResultsPerPage();
}
/**
......@@ -104,6 +109,17 @@ abstract class AbstractWidgetAction implements ActionInterface
throw new Core\ACL\Exception\AccessForbiddenException();
}
$this->view->assign([
'PHP_SELF' => $this->appPath->getPhpSelf(),
'ROOT_DIR' => $this->appPath->getWebRoot(),
'HOST_NAME' => $this->request->getHttpHost(),
'ROOT_DIR_ABSOLUTE' => $this->request->getScheme() . '://' . $this->request->getHttpHost() . $this->appPath->getWebRoot(),
'DESIGN_PATH' => $this->appPath->getDesignPathWeb(),
'DESIGN_PATH_ABSOLUTE' => $this->appPath->getDesignPathAbsolute(),
'LANG_DIRECTION' => $this->translator->getDirection(),
'LANG' => $this->translator->getShortIsoCode(),
]);
return $this;
}
......
......@@ -58,7 +58,8 @@ class FrontendContext extends Core\Controller\Context\WidgetContext
$context->getView(),
$context->getConfig(),
$context->getAppPath(),
$context->getResponse()
$context->getResponse(),
$context->getResultsPerPage()
);
$this->assets = $assets;
......
......@@ -7,6 +7,7 @@ namespace ACP3\Core\Controller\Context;
use ACP3\Core\ACL;
use ACP3\Core\Environment\ApplicationPath;
use ACP3\Core\Helpers\ResultsPerPage;
use ACP3\Core\Http\RequestInterface;
use ACP3\Core\I18n\Translator;
use ACP3\Core\Modules;
......@@ -77,6 +78,10 @@ class WidgetContext
* @var \Symfony\Component\HttpFoundation\Response
*/
private $response;
/**
* @var ResultsPerPage
*/
private $resultsPerPage;
/**
* WidgetContext constructor.
......@@ -94,6 +99,7 @@ class WidgetContext
* @param \ACP3\Core\Settings\SettingsInterface $config
* @param \ACP3\Core\Environment\ApplicationPath $appPath
* @param Response $response
* @param ResultsPerPage $resultsPerPage
*/
public function __construct(
ContainerInterface $container,
......@@ -108,7 +114,8 @@ class WidgetContext
View $view,
SettingsInterface $config,
ApplicationPath $appPath,
Response $response
Response $response,
ResultsPerPage $resultsPerPage
) {
$this->container = $container;
$this->eventDispatcher = $eventDispatcher;
......@@ -123,6 +130,7 @@ class WidgetContext
$this->config = $config;
$this->appPath = $appPath;
$this->response = $response;
$this->resultsPerPage = $resultsPerPage;
}
/**
......@@ -228,4 +236,12 @@ class WidgetContext
{
return $this->response;
}
/**
* @return ResultsPerPage
*/
public function getResultsPerPage()
{
return $this->resultsPerPage;
}
}
......@@ -87,7 +87,7 @@ class ServiceContainerBuilder extends ContainerBuilder
// Try to get all available services
/** @var Modules $modules */
$modules = $this->get('core.modules');
$availableModules = ($this->allModules === true) ? $modules->getAllModules() : $modules->getInstalledModules();
$availableModules = ($this->allModules === true) ? $modules->getAllModules() : $modules->getActiveModules();
$vendors = $this->get('core.modules.vendors')->getVendors();
foreach ($availableModules as $module) {
......
<?php
/**
* Copyright (c) 2016 by the ACP3 Developers.
* See the LICENCE file at the top-level module directory for licencing details.
*/
namespace ACP3\Core\Helpers;
use ACP3\Core\Settings\SettingsInterface;
use ACP3\Modules\ACP3\System\Installer\Schema;
class ResultsPerPage
{
/**
* @var SettingsInterface
*/
private $settings;
/**
* @var array
*/
private $resultsPerPage = [];
/**
* ResultsPerPage constructor.
* @param SettingsInterface $settings
*/
public function __construct(SettingsInterface $settings)
{
$this->settings = $settings;
}
/**
* @param string $moduleName
* @return int
*/
public function getResultsPerPage($moduleName)
{
if (!isset($this->resultsPerPage[$moduleName])) {
$moduleSettings = $this->settings->getSettings($moduleName);
if (!empty($moduleSettings['entries'])) {
$this->resultsPerPage[$moduleName] = $moduleSettings['entries'];
} else {
$moduleName = Schema::MODULE_NAME;
$this->getResultsPerPage($moduleName);
}
}
return (int)$this->resultsPerPage[$moduleName];
}
}
......@@ -55,6 +55,35 @@ class Logger
$this->channels[$channel]->{$level}($message, $context);
}
/**
* @param string $channel
* @param string $level
*/
private function createChannel($channel, $level)
{
$fileName = $this->appPath->getCacheDir() . 'logs/' . $channel . '.log';
$logLevelConst = constant(\Monolog\Logger::class . '::' . strtoupper($level));
$stream = new StreamHandler($fileName, $logLevelConst);
$stream->setFormatter(new LineFormatter(null, null, true));
$this->channels[$channel] = new \Monolog\Logger($channel, [$stream]);
}
/**
* @param $message
*
* @return string
*/
private function prettyPrintMessage($message)
{
if (is_array($message) || is_object($message)) {
$message = var_export($message, true);
}
return $message;
}
/**
* Debug log
*
......@@ -150,33 +179,4 @@ class Logger
{
$this->log($channel, LogLevel::EMERGENCY, $message, $context);
}
/**
* @param string $channel
* @param string $level
*/
private function createChannel($channel, $level)
{
$fileName = $this->appPath->getCacheDir() . 'logs/' . $channel . '.log';
$logLevelConst = constant(\Monolog\Logger::class . '::' . strtoupper($level));
$stream = new StreamHandler($fileName, $logLevelConst);
$stream->setFormatter(new LineFormatter(null, null, true));
$this->channels[$channel] = new \Monolog\Logger($channel, [$stream]);
}
/**
* @param $message
*
* @return string
*/
private function prettyPrintMessage($message)
{
if (is_array($message) || is_object($message)) {
$message = var_export($message, true);
}
return $message;
}
}
......@@ -122,7 +122,7 @@ class Modules
}
/**
* Checks, whether a modules in currently installed or not
* Checks, whether a module is currently installed or not
*
* @param string $moduleName
*
......
......@@ -6,7 +6,6 @@ use ACP3\Core\Controller\AreaEnum;
use ACP3\Core\Http\RequestInterface;
use ACP3\Core\I18n\Translator;
use ACP3\Core\Router\RouterInterface;
use ACP3\Modules\ACP3\Users\Model\UserModel;
/**
* Class Pagination
......@@ -69,15 +68,12 @@ class Pagination
/**
* Pagination constructor.
*
* @param \ACP3\Modules\ACP3\Users\Model\UserModel $user
* @param \ACP3\Core\Breadcrumb\Title $title
* @param \ACP3\Core\I18n\Translator $translator
* @param \ACP3\Core\Http\RequestInterface $request
* @param \ACP3\Core\Router\RouterInterface $router
* @param Title $title
* @param Translator $translator
* @param RequestInterface $request
* @param RouterInterface $router
*/
public function __construct(
UserModel $user,
Title $title,
Translator $translator,
RequestInterface $request,
......@@ -87,56 +83,72 @@ class Pagination
$this->translator = $translator;
$this->request = $request;
$this->router = $router;
$this->resultsPerPage = $user->getEntriesPerPage();
}
/**
* @param int $results
* @return $this
*/
public function setResultsPerPage($results)
{
$this->resultsPerPage = (int)$results;
return $this;
}
/**
* @param int $results
* @return $this
*/
public function setTotalResults($results)
{
$this->totalResults = (int)$results;
return $this;
}
/**
* @param string $fragment
* @return $this
*/
public function setUrlFragment($fragment)
{
$this->urlFragment = $fragment;
return $this;
}
/**
* @param int $pagesToDisplay
* @return $this
*/
public function setPagesToDisplay($pagesToDisplay)
{
$this->pagesToDisplay = (int)$pagesToDisplay;
return $this;
}
/**
* @param int $showFirstLast
* @return $this
*/
public function setShowFirstLast($showFirstLast)
{
$this->showFirstLast = (int)$showFirstLast;
return $this;
}
/**
* @param int $showPreviousNext
* @return $this
*/
public function setShowPreviousNext($showPreviousNext)
{
$this->showPreviousNext = (int)$showPreviousNext;
return $this;
}
/**
......
<?php
/**
* Copyright (c) 2016 by the ACP3 Developers.
* See the LICENCE file at the top-level module directory for licencing details.
*/
namespace ACP3\Core\Test\Assets;
use ACP3\Core\Assets\Libraries;
use Symfony\Component\EventDispatcher\EventDispatcher;
class LibrariesTest extends \PHPUnit_Framework_TestCase
{
/**
* @var Libraries
*/
private $libraries;
/**
* @var \PHPUnit_Framework_MockObject_MockObject
*/
private $eventDispatcherMock;
protected function setUp()
{
$this->eventDispatcherMock = $this->getMockBuilder(EventDispatcher::class)
->disableOriginalConstructor()
->getMock();
$this->libraries = new Libraries($this->eventDispatcherMock);
}
public function testAddLibrary()
{
$data = [
'enabled' => false,
'dependencies' => ['jquery'],
'css' => 'foo.css',
'js' => 'bar.js'
];
$this->libraries->addLibrary('foobar', $data);
$this->assertArraySubset(['foobar' => $data], $this->libraries->getLibraries());
}
public function testEnableLibraries()
{
$this->testAddLibrary();
$this->libraries->enableLibraries(['foobar']);
$this->assertEquals(['jquery', 'foobar'], $this->libraries->getEnabledLibraries());
}
}
<?php
/**
* Copyright (c) 2016 by the ACP3 Developers.
* See the LICENCE file at the top-level module directory for licencing details.
*/
namespace ACP3\Core\Test\Assets;
use ACP3\Core\Assets\PageCssClasses;
use ACP3\Core\Breadcrumb\Title;
use ACP3\Core\Helpers\StringFormatter;
use ACP3\Core\Http\Request;
class PageCssClassesTest extends \PHPUnit_Framework_TestCase
{
/**
* @var PageCssClasses
*/
private $pageCssClasses;
/**
* @var \PHPUnit_Framework_MockObject_MockObject
*/
private $titleMock;
/**
* @var \PHPUnit_Framework_MockObject_MockObject
*/
private $requestMock;
/**
* @var \PHPUnit_Framework_MockObject_MockObject
*/
private $stringFormatterMock;
protected function setUp()
{
$this->setUpMockObjects();
$this->pageCssClasses = new PageCssClasses(
$this->stringFormatterMock,
$this->titleMock,
$this->requestMock
);
}
private function setUpMockObjects()
{
$this->titleMock = $this->getMockBuilder(Title::class)
->disableOriginalConstructor()
->getMock();
$this->requestMock = $this->getMockBuilder(Request::class)
->disableOriginalConstructor()
->getMock();
$this->stringFormatterMock = $this->getMockBuilder(StringFormatter::class)
->disableOriginalConstructor()
->getMock();
}
public function testGetModule()
{
$this->requestMock->expects($this->once())
->method('getModule')
->willReturn('foo');
$this->assertEquals('foo', $this->pageCssClasses->getModule());
}
public function testGetControllerAction()