Merge branch 'master' into bugfix/url-anchors-not-working-9844

This commit is contained in:
Matthias Jentsch 2015-09-07 16:11:36 +02:00
commit a5351933fc
1772 changed files with 81852 additions and 28300 deletions

View File

@ -1,10 +1,10 @@
<?php
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
# namespace Icinga\Application\Controllers;
namespace Icinga\Controllers;
use Icinga\Web\Controller\ActionController;
use Icinga\Application\Version;
use Icinga\Web\Controller\ActionController;
class AboutController extends ActionController
{

View File

@ -1,12 +1,11 @@
<?php
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
# namespace Icinga\Application\Controllers;
namespace Icinga\Controllers;
use Icinga\Application\Icinga;
use Icinga\Forms\Authentication\LoginForm;
use Icinga\Web\Controller;
use Icinga\Web\Cookie;
use Icinga\Web\Url;
/**
@ -39,8 +38,11 @@ class AuthenticationController extends Controller
}
if (! $requiresSetup) {
if (! $this->getRequest()->hasCookieSupport()) {
echo $this->translate("Cookies must be enabled to run this application.\n");
$this->getResponse()->setHttpResponseCode(403)->sendHeaders();
$this
->getResponse()
->setBody("Cookies must be enabled to run this application.\n")
->setHttpResponseCode(403)
->sendResponse();
exit();
}
$form->handleRequest();

View File

@ -1,21 +1,24 @@
<?php
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
namespace Icinga\Controllers;
use Exception;
use InvalidArgumentException;
use Icinga\Application\Config;
use Icinga\Application\Icinga;
use Icinga\Application\Modules\Module;
use Icinga\Data\ResourceFactory;
use Icinga\Exception\ConfigurationError;
use Icinga\Exception\NotFoundError;
use Icinga\Forms\Config\UserBackendConfigForm;
use Icinga\Forms\Config\UserBackendReorderForm;
use Icinga\Forms\Config\GeneralConfigForm;
use Icinga\Forms\Config\ResourceConfigForm;
use Icinga\Forms\Config\UserBackendConfigForm;
use Icinga\Forms\Config\UserBackendReorderForm;
use Icinga\Forms\ConfirmRemovalForm;
use Icinga\Security\SecurityException;
use Icinga\Web\Controller;
use Icinga\Web\Notification;
use Icinga\Web\Url;
use Icinga\Web\Widget;
/**

View File

@ -1,12 +1,16 @@
<?php
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
namespace Icinga\Controllers;
use Exception;
use Zend_Controller_Action_Exception;
use Icinga\Exception\ProgrammingError;
use Icinga\Forms\ConfirmRemovalForm;
use Icinga\Forms\Dashboard\DashletForm;
use Icinga\Web\Controller\ActionController;
use Icinga\Web\Form;
use Icinga\Web\Notification;
use Icinga\Web\Controller\ActionController;
use Icinga\Web\Url;
use Icinga\Web\Widget\Dashboard;
use Icinga\Web\Widget\Tabextension\DashboardSettings;

View File

@ -1,8 +1,13 @@
<?php
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
namespace Icinga\Controllers;
use Icinga\Web\Response\JsonResponse;
use Zend_Controller_Plugin_ErrorHandler;
use Icinga\Application\Icinga;
use Icinga\Application\Logger;
use Icinga\Exception\Http\HttpBadRequestException;
use Icinga\Exception\Http\HttpMethodNotAllowedException;
use Icinga\Exception\Http\HttpNotFoundException;
use Icinga\Exception\MissingParameterException;
@ -14,6 +19,9 @@ use Icinga\Web\Controller\ActionController;
*/
class ErrorController extends ActionController
{
/**
* {@inheritdoc}
*/
protected $requiresAuthentication = false;
/**
@ -23,7 +31,7 @@ class ErrorController extends ActionController
{
$error = $this->_getParam('error_handler');
$exception = $error->exception;
/** @var \Exception $exception */
Logger::error($exception);
Logger::error('Stacktrace: %s', $exception->getTraceAsString());
@ -61,6 +69,9 @@ class ErrorController extends ActionController
'Missing parameter ' . $exception->getParameter()
);
break;
case $exception instanceof HttpBadRequestException:
$this->getResponse()->setHttpResponseCode(400);
break;
case $exception instanceof SecurityException:
$this->getResponse()->setHttpResponseCode(403);
break;
@ -74,6 +85,13 @@ class ErrorController extends ActionController
}
break;
}
if ($this->getRequest()->isApiRequest()) {
$this->getResponse()->json()
->setErrorMessage($this->view->message)
->sendResponse();
}
$this->view->request = $error->request;
}
}

View File

@ -1,92 +0,0 @@
<?php
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
use Icinga\Web\Controller\ActionController;
use Icinga\Filter\Filter;
use Icinga\Application\Logger;
/**
* Application wide interface for filtering
*/
class FilterController extends ActionController
{
/**
* The current filter registry
*
* @var Filter
*/
private $registry;
private $moduleRegistry;
/**
* Entry point for filtering, uses the filter_domain and filter_module request parameter
* to determine which filter registry should be used
*/
public function indexAction()
{
$this->registry = new Filter();
$query = $this->getRequest()->getParam('query', '');
$target = $this->getRequest()->getParam('filter_domain', '');
if ($this->getRequest()->getHeader('accept') == 'application/json') {
$this->getResponse()->setHeader('Content-Type', 'application/json');
$this->setupQueries(
$target,
$this->getParam('filter_module', '')
);
$this->_helper->json($this->parse($query, $target));
} else {
$this->setupQueries(
$target,
$this->getParam('filter_module')
);
$urlTarget = $this->parse($query, $target);
$this->redirect($urlTarget['urlParam']);
}
}
/**
* Set up the query handler for the given domain and module
*
* @param string $domain The domain to use
* @param string $module The module to use
*/
private function setupQueries($domain, $module = 'default')
{
$class = '\\Icinga\\Module\\' . ucfirst($module) . '\\Filter\\Registry';
$factory = strtolower($domain) . 'Filter';
$this->moduleRegistry = $class;
$this->registry->addDomain($class::$factory());
}
/**
* Parse the given query text and returns the json as expected by the semantic search box
*
* @param String $text The query to parse
* @return array The result structure to be returned in json format
*/
private function parse($text, $target)
{
try {
$queryTree = $this->registry->createQueryTreeForFilter($text);
$registry = $this->moduleRegistry;
return array(
'state' => 'success',
'proposals' => $this->registry->getProposalsForQuery($text),
'urlParam' => $registry::getUrlForTarget($target, $queryTree),
'valid' => count($this->registry->getIgnoredQueryParts()) === 0
);
} catch (\Exception $exc) {
Logger::error($exc);
$this->getResponse()->setHttpResponseCode(500);
return array(
'state' => 'error',
'message' => 'Search service is currently not available'
);
}
}
}

View File

@ -1,10 +1,13 @@
<?php
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
namespace Icinga\Controllers;
use Exception;
use Icinga\Application\Logger;
use Icinga\Data\DataArray\ArrayDatasource;
use Icinga\Data\Reducible;
use Icinga\Data\Filter\Filter;
use Icinga\Data\Reducible;
use Icinga\Exception\NotFoundError;
use Icinga\Forms\Config\UserGroup\AddMemberForm;
use Icinga\Forms\Config\UserGroup\UserGroupForm;

View File

@ -1,10 +1,9 @@
<?php
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
# namespace Icinga\Application\Controllers;
namespace Icinga\Controllers;
use Icinga\Web\Controller\ActionController;
use Icinga\Application\Benchmark;
use Icinga\Web\Url;
/**
@ -18,6 +17,7 @@ class IndexController extends ActionController
public function preDispatch()
{
if ($this->getRequest()->getActionName() !== 'welcome') {
// @TODO(el): Avoid landing page redirects: https://dev.icinga.org/issues/9656
$this->redirectNow(Url::fromRequest()->setPath('dashboard'));
}
}

View File

@ -1,10 +1,12 @@
<?php
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
use Icinga\Web\MenuRenderer;
namespace Icinga\Controllers;
use Icinga\Web\Controller\ActionController;
use Icinga\Web\Hook;
use Icinga\Web\Menu;
use Icinga\Web\MenuRenderer;
use Icinga\Web\Url;
/**

View File

@ -1,6 +1,8 @@
<?php
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
namespace Icinga\Controllers;
use Icinga\Application\Config;
use Icinga\Application\Logger;
use Icinga\Data\ConfigObject;
@ -11,8 +13,6 @@ use Icinga\Web\Widget\Tabextension\DashboardAction;
use Icinga\Web\Widget\Tabextension\OutputFormat;
/**
* Class ListController
*
* Application wide controller for various listing actions
*/
class ListController extends Controller

View File

@ -1,16 +1,20 @@
<?php
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
namespace Icinga\Controllers;
use Icinga\Application\Config;
use Icinga\Data\ConfigObject;
use Icinga\Forms\PreferenceForm;
use Icinga\User\Preferences\PreferencesStore;
use Icinga\Web\Controller\BasePreferenceController;
use Icinga\Web\Url;
use Icinga\Web\Widget\Tab;
use Icinga\Application\Config;
use Icinga\Forms\PreferenceForm;
use Icinga\Data\ConfigObject;
use Icinga\User\Preferences\PreferencesStore;
/**
* Application wide preference controller for user preferences
*
* @TODO(el): Rename to PreferencesController: https://dev.icinga.org/issues/10014
*/
class PreferenceController extends BasePreferenceController
{

View File

@ -1,12 +1,21 @@
<?php
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
namespace Icinga\Controllers;
use Icinga\Application\Config;
use Icinga\Exception\AlreadyExistsException;
use Icinga\Exception\NotFoundError;
use Icinga\Forms\ConfirmRemovalForm;
use Icinga\Forms\Security\RoleForm;
use Icinga\Web\Controller\AuthBackendController;
use Icinga\Web\Notification;
/**
* Manage user permissions and restrictions based on roles
*
* @TODO(el): Rename to RolesController: https://dev.icinga.org/issues/10015
*/
class RoleController extends AuthBackendController
{
/**
@ -31,7 +40,7 @@ class RoleController extends AuthBackendController
$values = $role->getValues();
try {
$role->add($name, $values);
} catch (InvalidArgumentException $e) {
} catch (AlreadyExistsException $e) {
$role->addError($e->getMessage());
return false;
}
@ -54,19 +63,11 @@ class RoleController extends AuthBackendController
/**
* Update a role
*
* @throws Zend_Controller_Action_Exception If the required parameter 'role' is missing or the role does not exist
*/
public function editAction()
{
$this->assertPermission('config/authentication/roles/edit');
$name = $this->_request->getParam('role');
if (empty($name)) {
throw new Zend_Controller_Action_Exception(
sprintf($this->translate('Required parameter \'%s\' missing'), 'role'),
400
);
}
$name = $this->params->getRequired('role');
$role = new RoleForm();
$role->setTitle(sprintf($this->translate('Update Role %s'), $name));
$role->setSubmitLabel($this->translate('Update Role'));
@ -74,11 +75,8 @@ class RoleController extends AuthBackendController
$role
->setIniConfig(Config::app('roles', true))
->load($name);
} catch (InvalidArgumentException $e) {
throw new Zend_Controller_Action_Exception(
$e->getMessage(),
400
);
} catch (NotFoundError $e) {
$this->httpNotFound($e->getMessage());
}
$role
->setOnSuccess(function (RoleForm $role) use ($name) {
@ -87,7 +85,7 @@ class RoleController extends AuthBackendController
$values = $role->getValues();
try {
$role->update($name, $values, $oldName);
} catch (InvalidArgumentException $e) {
} catch (NotFoundError $e) {
$role->addError($e->getMessage());
return false;
}
@ -105,35 +103,24 @@ class RoleController extends AuthBackendController
/**
* Remove a role
*
* @throws Zend_Controller_Action_Exception If the required parameter 'role' is missing or the role does not exist
*/
public function removeAction()
{
$this->assertPermission('config/authentication/roles/remove');
$name = $this->_request->getParam('role');
if (empty($name)) {
throw new Zend_Controller_Action_Exception(
sprintf($this->translate('Required parameter \'%s\' missing'), 'role'),
400
);
}
$name = $this->params->getRequired('role');
$role = new RoleForm();
try {
$role
->setIniConfig(Config::app('roles', true))
->load($name);
} catch (InvalidArgumentException $e) {
throw new Zend_Controller_Action_Exception(
$e->getMessage(),
400
);
} catch (NotFoundError $e) {
$this->httpNotFound($e->getMessage());
}
$confirmation = new ConfirmRemovalForm(array(
'onSuccess' => function (ConfirmRemovalForm $confirmation) use ($name, $role) {
try {
$role->remove($name);
} catch (InvalidArgumentException $e) {
} catch (NotFoundError $e) {
Notification::error($e->getMessage());
return false;
}
@ -162,15 +149,15 @@ class RoleController extends AuthBackendController
$tabs->add(
'role/list',
array(
'title' => $this->translate(
'baseTarget' => '_main',
'label' => $this->translate('Roles'),
'title' => $this->translate(
'Configure roles to permit or restrict users and groups accessing Icinga Web 2'
),
'label' => $this->translate('Roles'),
'url' => 'role/list',
'baseTarget' => '_main'
'url' => 'role/list'
)
);
return $tabs;
}
}

View File

@ -1,6 +1,8 @@
<?php
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
namespace Icinga\Controllers;
use Icinga\Web\Controller\ActionController;
use Icinga\Web\Widget;
use Icinga\Web\Widget\SearchDashboard;

View File

@ -1,16 +1,18 @@
<?php
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
use Icinga\Web\Controller\ActionController;
namespace Icinga\Controllers;
use Icinga\Web\Controller;
use Icinga\Application\Icinga;
use Icinga\Application\Logger;
use Icinga\Web\FileCache;
use Zend_Controller_Action_Exception as ActionException;
use Icinga\Web\LessCompiler;
/**
* Delivery static content to clients
*/
class StaticController extends ActionController
class StaticController extends Controller
{
/**
* Static routes don't require authentication
@ -57,17 +59,15 @@ class StaticController extends ActionController
*/
public function imgAction()
{
// TODO(el): I think this action only retrieves images from modules
$module = $this->_getParam('module_name');
$file = $this->_getParam('file');
$basedir = Icinga::app()->getModuleManager()->getModule($module)->getBaseDir();
$filePath = realpath($basedir . '/public/img/' . $file);
if (! $filePath || strpos($filePath, $basedir) !== 0) {
throw new ActionException(sprintf(
'%s does not exist',
$filePath
), 404);
if ($filePath === false) {
$this->httpNotFound('%s does not exist', $filePath);
}
if (preg_match('/\.([a-z]+)$/i', $file, $m)) {
$extension = $m[1];
@ -80,10 +80,7 @@ class StaticController extends ActionController
header(sprintf('ETag: "%x-%x-%x"', $s['ino'], $s['size'], (float) str_pad($s['mtime'], 16, '0')));
header('Cache-Control: public, max-age=3600');
header('Pragma: cache');
header('Last-Modified: ' . gmdate(
'D, d M Y H:i:s',
$s['mtime']
) . ' GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $s['mtime']) . ' GMT');
readfile($filePath);
}
@ -100,7 +97,7 @@ class StaticController extends ActionController
$basedir = Icinga::app()->getApplicationDir('../public/js/icinga/components/');
$filePath = $basedir . $file;
} else {
if (!Icinga::app()->getModuleManager()->hasEnabled($module)) {
if (! Icinga::app()->getModuleManager()->hasEnabled($module)) {
Logger::error(
'Non-existing frontend component "' . $module . '/' . $file
. '" was requested. The module "' . $module . '" does not exist or is not active.'
@ -112,7 +109,7 @@ class StaticController extends ActionController
$filePath = $basedir . '/public/js/' . $file;
}
if (!file_exists($filePath)) {
if (! file_exists($filePath)) {
Logger::error(
'Non-existing frontend component "' . $module . '/' . $file
. '" was requested, which would resolve to the the path: ' . $filePath
@ -122,41 +119,41 @@ class StaticController extends ActionController
}
$response = $this->getResponse();
$response->setHeader('Content-Type', 'text/javascript');
$this->setCacheHeader(3600);
$this->setCacheHeader();
$response->setHeader(
'Last-Modified',
gmdate(
'D, d M Y H:i:s',
filemtime($filePath)
) . ' GMT'
gmdate('D, d M Y H:i:s', filemtime($filePath)) . ' GMT'
);
readfile($filePath);
}
/**
* Set cache header for this response
* Set cache header for the response
*
* @param integer $maxAge The maximum age to set
* @param int $maxAge The maximum age to set
*/
private function setCacheHeader($maxAge)
private function setCacheHeader($maxAge = 3600)
{
$this->_response->setHeader('Cache-Control', 'max-age=3600', true);
$this->_response->setHeader('Pragma', 'cache', true);
$this->_response->setHeader(
'Expires',
gmdate(
'D, d M Y H:i:s',
time()+3600
) . ' GMT',
true
);
$maxAge = (int) $maxAge;
$this
->getResponse()
->setHeader('Cache-Control', sprintf('max-age=%d', $maxAge), true)
->setHeader('Pragma', 'cache', true)
->setHeader(
'Expires',
gmdate('D, d M Y H:i:s', time() + $maxAge) . ' GMT',
true
);
}
/**
* Send application's and modules' CSS
*/
public function stylesheetAction()
{
$lessCompiler = new \Icinga\Web\LessCompiler();
$lessCompiler = new LessCompiler();
$moduleManager = Icinga::app()->getModuleManager();
$publicDir = realpath(dirname($_SERVER['SCRIPT_FILENAME']));
@ -172,7 +169,7 @@ class StaticController extends ActionController
}
}
$this->_response->setHeader('Content-Type', 'text/css');
$this->getResponse()->setHeader('Content-Type', 'text/css');
$this->setCacheHeader(3600);
$lessCompiler->printStack();

View File

@ -1,12 +1,15 @@
<?php
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
namespace Icinga\Controllers;
use Exception;
use Icinga\Application\Logger;
use Icinga\Data\DataArray\ArrayDatasource;
use Icinga\Exception\ConfigurationError;
use Icinga\Exception\NotFoundError;
use Icinga\Forms\Config\User\CreateMembershipForm;
use Icinga\Forms\Config\User\UserForm;
use Icinga\Data\DataArray\ArrayDatasource;
use Icinga\User;
use Icinga\Web\Controller\AuthBackendController;
use Icinga\Web\Form;

View File

@ -1,13 +1,15 @@
<?php
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
namespace Icinga\Controllers;
use Exception;
use Icinga\Application\Config;
use Icinga\Exception\NotFoundError;
use Icinga\Forms\ConfirmRemovalForm;
use Icinga\Forms\Config\UserGroup\UserGroupBackendForm;
use Icinga\Forms\ConfirmRemovalForm;
use Icinga\Web\Controller;
use Icinga\Web\Notification;
use Icinga\Web\Url;
/**
* Controller to configure user group backends

View File

@ -540,6 +540,12 @@
"code": 59414,
"src": "fontawesome"
},
{
"uid": "130380e481a7defc690dfb24123a1f0c",
"css": "circle",
"code": 59516,
"src": "fontawesome"
},
{
"uid": "266d5d9adf15a61800477a5acf9a4462",
"css": "chart-bar",
@ -672,6 +678,12 @@
"code": 59492,
"src": "entypo"
},
{
"uid": "p57wgnf4glngbchbucdi029iptu8oxb8",
"css": "pin",
"code": 59513,
"src": "typicons"
},
{
"uid": "c16a63e911bc47b46dc2a7129d2f0c46",
"css": "down-small",

View File

@ -119,4 +119,6 @@
.icon-down-small:before { content: '\e875'; } /* '' */
.icon-left-small:before { content: '\e876'; } /* '' */
.icon-right-small:before { content: '\e877'; } /* '' */
.icon-up-small:before { content: '\e878'; } /* '' */
.icon-up-small:before { content: '\e878'; } /* '' */
.icon-pin:before { content: '\e879'; } /* '' */
.icon-circle:before { content: '\e87c'; } /* '' */

File diff suppressed because one or more lines are too long

View File

@ -119,4 +119,6 @@
.icon-down-small { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe875;&nbsp;'); }
.icon-left-small { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe876;&nbsp;'); }
.icon-right-small { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe877;&nbsp;'); }
.icon-up-small { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe878;&nbsp;'); }
.icon-up-small { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe878;&nbsp;'); }
.icon-pin { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe879;&nbsp;'); }
.icon-circle { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe87c;&nbsp;'); }

View File

@ -130,4 +130,6 @@
.icon-down-small { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe875;&nbsp;'); }
.icon-left-small { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe876;&nbsp;'); }
.icon-right-small { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe877;&nbsp;'); }
.icon-up-small { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe878;&nbsp;'); }
.icon-up-small { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe878;&nbsp;'); }
.icon-pin { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe879;&nbsp;'); }
.icon-circle { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe87c;&nbsp;'); }

View File

@ -1,10 +1,10 @@
@font-face {
font-family: 'ifont';
src: url('../font/ifont.eot?54745533');
src: url('../font/ifont.eot?54745533#iefix') format('embedded-opentype'),
url('../font/ifont.woff?54745533') format('woff'),
url('../font/ifont.ttf?54745533') format('truetype'),
url('../font/ifont.svg?54745533#ifont') format('svg');
src: url('../font/ifont.eot?82929165');
src: url('../font/ifont.eot?82929165#iefix') format('embedded-opentype'),
url('../font/ifont.woff?82929165') format('woff'),
url('../font/ifont.ttf?82929165') format('truetype'),
url('../font/ifont.svg?82929165#ifont') format('svg');
font-weight: normal;
font-style: normal;
}
@ -14,7 +14,7 @@
@media screen and (-webkit-min-device-pixel-ratio:0) {
@font-face {
font-family: 'ifont';
src: url('../font/ifont.svg?54745533#ifont') format('svg');
src: url('../font/ifont.svg?82929165#ifont') format('svg');
}
}
*/
@ -174,4 +174,6 @@
.icon-down-small:before { content: '\e875'; } /* '' */
.icon-left-small:before { content: '\e876'; } /* '' */
.icon-right-small:before { content: '\e877'; } /* '' */
.icon-up-small:before { content: '\e878'; } /* '' */
.icon-up-small:before { content: '\e878'; } /* '' */
.icon-pin:before { content: '\e879'; } /* '' */
.icon-circle:before { content: '\e87c'; } /* '' */

View File

@ -229,11 +229,11 @@ body {
}
@font-face {
font-family: 'ifont';
src: url('./font/ifont.eot?11424534');
src: url('./font/ifont.eot?11424534#iefix') format('embedded-opentype'),
url('./font/ifont.woff?11424534') format('woff'),
url('./font/ifont.ttf?11424534') format('truetype'),
url('./font/ifont.svg?11424534#ifont') format('svg');
src: url('./font/ifont.eot?83291894');
src: url('./font/ifont.eot?83291894#iefix') format('embedded-opentype'),
url('./font/ifont.woff?83291894') format('woff'),
url('./font/ifont.ttf?83291894') format('truetype'),
url('./font/ifont.svg?83291894#ifont') format('svg');
font-weight: normal;
font-style: normal;
}
@ -482,6 +482,8 @@ body {
</div>
<div class="row">
<div title="Code: 0xe878" class="the-icons span3"><i class="demo-icon icon-up-small">&#xe878;</i> <span class="i-name">icon-up-small</span><span class="i-code">0xe878</span></div>
<div title="Code: 0xe879" class="the-icons span3"><i class="demo-icon icon-pin">&#xe879;</i> <span class="i-name">icon-pin</span><span class="i-code">0xe879</span></div>
<div title="Code: 0xe87c" class="the-icons span3"><i class="demo-icon icon-circle">&#xe87c;</i> <span class="i-name">icon-circle</span><span class="i-code">0xe87c</span></div>
</div>
</div>
<div class="container footer">Generated by <a href="http://fontello.com">fontello.com</a></div>

View File

@ -350,8 +350,21 @@ class ResourceConfigForm extends ConfigForm
'decorators' => array('ViewHelper')
)
);
$this->setAttrib('data-progress-element', 'resource-progress');
$this->addElement(
'note',
'resource-progress',
array(
'decorators' => array(
'ViewHelper',
array('Spinner', array('id' => 'resource-progress'))
)
)
);
$this->addDisplayGroup(
array('btn_submit', 'resource_validation'),
array('btn_submit', 'resource_validation', 'resource-progress'),
'submit_validation',
array(
'decorators' => array(

View File

@ -34,7 +34,7 @@ class UserForm extends RepositoryForm
)
);
$this->addElement(
'text',
'password',
'password',
array(
'required' => true,
@ -56,10 +56,11 @@ class UserForm extends RepositoryForm
$this->createInsertElements($formData);
$this->addElement(
'text',
'password',
'password',
array(
'label' => $this->translate('Password')
'description' => $this->translate('Leave empty for not updating the user\'s password'),
'label' => $this->translate('Password'),
)
);

View File

@ -177,13 +177,25 @@ class LdapUserGroupBackendForm extends Form
'preserveDefault' => true,
'ignore' => $disabled,
'disabled' => $disabled,
'label' => $this->translate('LDAP Group Name Attribute'),
'label' => $this->translate('LDAP Group Name Attribute'),
'description' => $this->translate(
'The attribute name used for storing a group\'s name on the LDAP server.'
),
'value' => $defaults->group_name_attribute
)
);
$this->addElement(
'text',
'group_member_attribute',
array(
'preserveDefault' => true,
'ignore' => $disabled,
'disabled' => $disabled,
'label' => $this->translate('LDAP Group Member Attribute'),
'description' => $this->translate('The attribute name used for storing a group\'s members.'),
'value' => $defaults->group_member_attribute
)
);
$this->addElement(
'text',
'base_dn',
@ -258,7 +270,7 @@ class LdapUserGroupBackendForm extends Form
'preserveDefault' => true,
'ignore' => $disabled,
'disabled' => $disabled,
'label' => $this->translate('LDAP User Name Attribute'),
'label' => $this->translate('LDAP User Name Attribute'),
'description' => $this->translate(
'The attribute name used for storing a user\'s name on the LDAP server.'
),

View File

@ -3,10 +3,11 @@
namespace Icinga\Forms\Security;
use InvalidArgumentException;
use LogicException;
use Zend_Form_Element;
use Icinga\Application\Icinga;
use Icinga\Exception\AlreadyExistsException;
use Icinga\Exception\NotFoundError;
use Icinga\Forms\ConfigForm;
use Icinga\Util\String;
@ -168,6 +169,7 @@ class RoleForm extends ConfigForm
* @return $this
*
* @throws LogicException If the config is not set
* @throws NotFoundError If the given role does not exist
* @see ConfigForm::setConfig() For setting the config.
*/
public function load($name)
@ -176,10 +178,10 @@ class RoleForm extends ConfigForm
throw new LogicException(sprintf('Can\'t load role \'%s\'. Config is not set', $name));
}
if (! $this->config->hasSection($name)) {
throw new InvalidArgumentException(sprintf(
throw new NotFoundError(
$this->translate('Can\'t load role \'%s\'. Role does not exist'),
$name
));
);
}
$role = $this->config->getSection($name)->toArray();
$role['permissions'] = ! empty($role['permissions'])
@ -202,14 +204,14 @@ class RoleForm extends ConfigForm
/**
* Add a role
*
* @param string $name The name of the role
* @param string $name The name of the role
* @param array $values
*
* @return $this
*
* @throws LogicException If the config is not set
* @throws InvalidArgumentException If the role to add already exists
* @see ConfigForm::setConfig() For setting the config.
* @throws LogicException If the config is not set
* @throws AlreadyExistsException If the role to add already exists
* @see ConfigForm::setConfig() For setting the config.
*/
public function add($name, array $values)
{
@ -217,10 +219,10 @@ class RoleForm extends ConfigForm
throw new LogicException(sprintf('Can\'t add role \'%s\'. Config is not set', $name));
}
if ($this->config->hasSection($name)) {
throw new InvalidArgumentException(sprintf(
throw new AlreadyExistsException(
$this->translate('Can\'t add role \'%s\'. Role already exists'),
$name
));
);
}
$this->config->setSection($name, $values);
return $this;
@ -229,13 +231,13 @@ class RoleForm extends ConfigForm
/**
* Remove a role
*
* @param string $name The name of the role
* @param string $name The name of the role
*
* @return $this
*
* @throws LogicException If the config is not set
* @throws InvalidArgumentException If the role does not exist
* @see ConfigForm::setConfig() For setting the config.
* @throws LogicException If the config is not set
* @throws NotFoundError If the role does not exist
* @see ConfigForm::setConfig() For setting the config.
*/
public function remove($name)
{
@ -243,10 +245,10 @@ class RoleForm extends ConfigForm
throw new LogicException(sprintf('Can\'t remove role \'%s\'. Config is not set', $name));
}
if (! $this->config->hasSection($name)) {
throw new InvalidArgumentException(sprintf(
throw new NotFoundError(
$this->translate('Can\'t remove role \'%s\'. Role does not exist'),
$name
));
);
}
$this->config->removeSection($name);
return $this;
@ -255,15 +257,15 @@ class RoleForm extends ConfigForm
/**
* Update a role
*
* @param string $name The possibly new name of the role
* @param string $name The possibly new name of the role
* @param array $values
* @param string $oldName The name of the role to update
* @param string $oldName The name of the role to update
*
* @return $this
*
* @throws LogicException If the config is not set
* @throws InvalidArgumentException If the role to update does not exist
* @see ConfigForm::setConfig() For setting the config.
* @throws LogicException If the config is not set
* @throws NotFoundError If the role to update does not exist
* @see ConfigForm::setConfig() For setting the config.
*/
public function update($name, array $values, $oldName)
{
@ -276,10 +278,10 @@ class RoleForm extends ConfigForm
$this->add($name, $values);
} else {
if (! $this->config->hasSection($name)) {
throw new InvalidArgumentException(sprintf(
throw new NotFoundError(
$this->translate('Can\'t update role \'%s\'. Role does not exist'),
$name
));
);
}
$this->config->setSection($name, $values);
}

View File

@ -2,33 +2,36 @@
# Copyright (C) 2015 Icinga Development Team
# This file is distributed under the same license as Icinga Web 2.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
#
msgid ""
msgstr ""
"Project-Id-Version: Icinga Web 2 (None)\n"
"Project-Id-Version: Icinga Web 2\n"
"Report-Msgid-Bugs-To: dev@icinga.org\n"
"POT-Creation-Date: 2015-03-13 14:55+0100\n"
"PO-Revision-Date: 2015-03-13 14:51+0100\n"
"PO-Revision-Date: 2015-07-17 10:17+0200\n"
"Last-Translator: Davide Demuru <davide.demuru@gmail.com>\n"
"Language: it_IT\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"Language-Team: \n"
"X-Generator: Poedit 1.8.2\n"
"X-Poedit-KeywordsList: translate\n"
"X-Poedit-Basepath: ../..\n"
"X-Poedit-SearchPath-0: .\n"
#: /usr/share/icingaweb2/library/Icinga/Web/Form/Validator/InArray.php:16
#, php-format
msgid "\"%s\" is not in the list of allowed values."
msgstr ""
msgstr "\"%s\" non è tra i valori ammessi."
#: /usr/share/icingaweb2/library/Icinga/Web/Form/Validator/InArray.php:19
#, php-format
msgid ""
"\"%s\" is not in the list of allowed values. Did you mean one of the "
"following?: %s"
msgstr ""
msgstr "\"%s\" non è tra i valori ammessi. Intendevi uno dei seguenti?: %s"
#: /usr/share/icingaweb2/application/forms/Config/Authentication/ExternalBackendForm.php:56
#: /usr/share/icingaweb2/application/forms/Config/Resource/FileResourceForm.php:50
@ -38,23 +41,23 @@ msgstr "\"%value%\" non è un'espressione regolare valida"
#: /usr/share/icingaweb2/library/Icinga/Web/Menu/MonitoringMenuItemRenderer.php:40
#, php-format
msgid "%d unhandled hosts down"
msgstr ""
msgstr "%d host down non gestiti"
#: /usr/share/icingaweb2/library/Icinga/Web/Menu/MonitoringMenuItemRenderer.php:41
#, php-format
msgid "%d unhandled services critical"
msgstr ""
msgstr "%d servizi down non gestiti"
#: /usr/share/icingaweb2/library/Icinga/Web/View/DateTimeRenderer.php:185
msgctxt "timespan"
msgid "%im %ss"
msgstr ""
msgstr "%im %ss"
#: /usr/share/icingaweb2/library/Icinga/Web/Form/ErrorLabeller.php:47
#, fuzzy, php-format
#, php-format
msgctxt "config.path"
msgid "%s does not exist"
msgstr "%s non è scrivibile"
msgstr "%s non esiste"
#: /usr/share/icingaweb2/library/Icinga/Web/Form/ErrorLabeller.php:48
#, php-format
@ -81,10 +84,10 @@ msgstr "%s non è nel formato previsto: %%value%%"
#: /usr/share/icingaweb2/application/views/scripts/pivottablePagination.phtml:9
#, php-format
msgid "%s: %d to %d of %d (on the %s-axis)"
msgstr "%s: %d a %d di %d (nell asse %s)"
msgstr "%s: %d a %d di %d (dell'asse %s)"
#: /usr/share/icingaweb2/application/views/scripts/joystickPagination.phtml:9
#, fuzzy, php-format
#, php-format
msgctxt "pagination.joystick"
msgid "%s: Show %s %u to %u out of %u"
msgstr "%s: Mostra %s %u a %u di %u"
@ -100,7 +103,7 @@ msgstr "...e password"
#: /usr/share/icingaweb2/application/layouts/scripts/parts/navigation.phtml:14
msgid "Accessibility Skip Links"
msgstr ""
msgstr "Salta Controllo di Accessibilità"
#: /usr/share/icingaweb2/application/controllers/DashboardController.php:69
msgid "Add Dashlet To Dashboard"
@ -112,9 +115,8 @@ msgid "Add To Dashboard"
msgstr "Aggiungi alla Dashboard"
#: /usr/share/icingaweb2/library/Icinga/Web/Widget/FilterEditor.php:327
#, fuzzy
msgid "Add another filter"
msgstr "Cliccare per aggiungere un altro filtro"
msgstr "Aggiungi un altro filtro"
#: /usr/share/icingaweb2/library/Icinga/Web/Widget/FilterWidget.php:80
msgid "Add filter..."
@ -127,7 +129,7 @@ msgstr "Cambia la configurazione generale di Icinga Web 2"
#: /usr/share/icingaweb2/application/controllers/PreferenceController.php:28
msgid "Adjust the preferences of Icinga Web 2 according to your needs"
msgstr ""
msgstr "Modifica le preferenze di Icinga Web 2 in base alle tue esigenze"
#: /usr/share/icingaweb2/application/controllers/AuthenticationController.php:111
msgid ""
@ -337,11 +339,11 @@ msgstr ""
#: /usr/share/icingaweb2/library/Icinga/Chart/GridChart.php:90
msgid "Contains data in a bar or line chart."
msgstr ""
msgstr "Contiene i dati in grafici a barre o linee"
#: /usr/share/icingaweb2/library/Icinga/Chart/PieChart.php:56
msgid "Contains data in a pie chart."
msgstr ""
msgstr "Contiene i dati in grafici a torta"
#: /usr/share/icingaweb2/application/forms/Config/General/ApplicationConfigForm.php:37
msgid ""
@ -622,7 +624,7 @@ msgstr "Configurazione Generale"
#: /usr/share/icingaweb2/library/Icinga/Chart/GridChart.php:89
msgid "Grid Chart"
msgstr ""
msgstr "Grafico a Griglia"
#: /usr/share/icingaweb2/application/forms/Security/RoleForm.php:98
#: /usr/share/icingaweb2/application/views/scripts/roles/index.phtml:16
@ -700,8 +702,8 @@ msgstr "Tipo \"%s\" di risorsa non valido"
msgid ""
"It appears that you did not configure Icinga Web 2 yet so it's not possible "
"to log in without any defined authentication method. Please define a "
"authentication method by following the instructions in the %1$sdocumentation%"
"3$s or by using our %2$sweb-based setup-wizard%3$s."
"authentication method by following the instructions in the %1$sdocumentation"
"%3$s or by using our %2$sweb-based setup-wizard%3$s."
msgstr ""
"Icinga Web 2 non è stato configurato e quindi non è possibile autenticarsi "
"senza aver definito nessun metodo di autenticazione. Si prega di definire un "
@ -951,7 +953,7 @@ msgstr "Permessi"
#: /usr/share/icingaweb2/library/Icinga/Chart/PieChart.php:55
msgid "Pie Chart"
msgstr ""
msgstr "Grafico a Torta"
#: /usr/share/icingaweb2/application/views/scripts/dashboard/error.phtml:4
msgid "Please copy the following dashboard snippet to "
@ -1007,12 +1009,16 @@ msgid ""
"Push this button to update the form to reflect the change that was made in "
"the field on the left"
msgstr ""
"Premere questo bottone per aggiornare il form e mostrare i cambiamenti "
"effettuati nel campo a sinistra"
#: /usr/share/icingaweb2/library/Icinga/Web/Form/Decorator/Autosubmit.php:119
msgid ""
"Push this button to update the form to reflect the changes that were made "
"below"
msgstr ""
"Premere questo bottone per aggiornare il form e mostrare i cambiamenti "
"effettuati sotto"
#: /usr/share/icingaweb2/library/Icinga/Web/Widget/SearchDashboard.php:63
msgid "Ready to search"
@ -1533,6 +1539,8 @@ msgid ""
"Upon any of this form's fields were changed, this page is being updated "
"automatically."
msgstr ""
"Cambiando un qualsiasi valore del form la pagina verrà ricaricata "
"automaticamente."
#: /usr/share/icingaweb2/library/Icinga/Web/Form.php:693
#: /usr/share/icingaweb2/library/Icinga/Web/Form/Decorator/Autosubmit.php:100

View File

@ -43,6 +43,7 @@ Directive | Description
**resource** | The name of the LDAP resource defined in [resources.ini](resources.md#resources).
**user_class** | LDAP user class.
**user_name_attribute** | LDAP attribute which contains the username.
**filter** | LDAP search filter.
**Example:**
@ -52,6 +53,7 @@ backend = ldap
resource = my_ldap
user_class = inetOrgPerson
user_name_attribute = uid
filter = "memberOf=cn=icinga_users,cn=groups,cn=accounts,dc=icinga,dc=org"
```
Note that in case the set *user_name_attribute* holds multiple values it is required that all of its

View File

@ -101,12 +101,11 @@ The packages for Debian wheezy depend on other packages which are distributed as
### <a id="installing-from-package-example"></a> Installing Icinga Web 2
You can install Icinga Web 2 by using your distribution's package manager to install the `icingaweb2` package.
Below is a list with examples for various distributions. The additional package `icingacli` is necessary
for being able to follow further steps in this guide.
Below is a list with examples for various distributions. The additional package `icingacli` is necessary on RPM based systems for being able to follow further steps in this guide. In DEB based systems, the icingacli binary is included in the icingaweb2 package.
**Debian and Ubuntu**:
````
apt-get install icingaweb2 icingacli
apt-get install icingaweb2
````
For Debian wheezy please read the [package repositories notes](#package-repositories-wheezy-notes).
@ -275,9 +274,11 @@ The first release candidate of Icinga Web 2 introduces the following non-backwar
`icingaweb_group_membership` were altered to ensure referential integrity.
Please use the upgrade script located in **etc/schema/** to update your
database schema
* Users who are using PostgreSQL < v9.1 are required to upgrade their
environment to v9.1+ as this is the new minimum required version
for utilizing PostgreSQL as database backend
* The restrictions `monitoring/hosts/filter` and `monitoring/services/filter`
provided by the monitoring module were merged together. The new
restriction is called `monitoring/filter/objects` and supports only a
@ -287,12 +288,16 @@ The first release candidate of Icinga Web 2 introduces the following non-backwar
## <a id="upgrading-to-2.0.0"></a> Upgrading to Icinga Web 2 2.0.0
* Icinga Web 2 installations from package on RHEL/CentOS 7 now depend on `php-ZendFramework` which is available through
the [EPEL repository](http://fedoraproject.org/wiki/EPEL). Before, Zend was installed as Icinga Web 2 vendor library
through the package `icingaweb2-vendor-zend`. After upgrading, please make sure to remove the package
`icingaweb2-vendor-zend`.
the [EPEL repository](http://fedoraproject.org/wiki/EPEL). Before, Zend was installed as Icinga Web 2 vendor library
through the package `icingaweb2-vendor-zend`. After upgrading, please make sure to remove the package
`icingaweb2-vendor-zend`.
* Icinga Web 2 version 2.0.0 requires permissions for accessing modules. Those permissions are automatically generated
for each installed module in the format `module/<moduleName>`. Administrators have to grant the module permissions to
users and/or user groups in the roles configuration for permitting access to specific modules.
In addition, restrictions provided by modules are now configurable for each installed module too. Before,
a module had to be enabled before having the possibility to configure restrictions.
for each installed module in the format `module/<moduleName>`. Administrators have to grant the module permissions to
users and/or user groups in the roles configuration for permitting access to specific modules.
In addition, restrictions provided by modules are now configurable for each installed module too. Before,
a module had to be enabled before having the possibility to configure restrictions.
* The **instances.ini** configuration file provided by the monitoring module
has been renamed to **commandtransports.ini**. The content and location of
the file remains unchanged.

View File

@ -78,9 +78,9 @@ abstract class ApplicationBootstrap
protected $configDir;
/**
* Icinga auto loader
* Icinga class loader
*
* @var Loader
* @var ClassLoader
*/
private $loader;
@ -183,7 +183,7 @@ abstract class ApplicationBootstrap
/**
* Getter for class loader
*
* @return Loader
* @return ClassLoader
*/
public function getLoader()
{
@ -339,15 +339,15 @@ abstract class ApplicationBootstrap
}
/**
* Setup Icinga auto loader
* Setup Icinga class loader
*
* @return $this
*/
public function setupAutoloader()
{
require $this->libDir . '/Icinga/Application/Loader.php';
require $this->libDir . '/Icinga/Application/ClassLoader.php';
$this->loader = new Loader();
$this->loader = new ClassLoader();
$this->loader->registerNamespace('Icinga', $this->libDir. '/Icinga');
$this->loader->register();

View File

@ -0,0 +1,113 @@
<?php
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
namespace Icinga\Application;
/**
* PSR-4 class loader
*/
class ClassLoader
{
/**
* Namespace separator
*/
const NAMESPACE_SEPARATOR = '\\';
/**
* Namespaces
*
* @var array
*/
private $namespaces = array();
/**
* Register a base directory for a namespace prefix
*
* @param string $namespace
* @param string $directory
*
* @return $this
*/
public function registerNamespace($namespace, $directory)
{
$this->namespaces[$namespace] = $directory;
return $this;
}
/**
* Test whether a namespace exists
*
* @param string $namespace
*
* @return bool
*/
public function hasNamespace($namespace)
{
return array_key_exists($namespace, $this->namespaces);
}
/**
* Get the source file of the given class or interface
*
* @param string $class Name of the class or interface
*
* @return string|null
*/
public function getSourceFile($class)
{
foreach ($this->namespaces as $namespace => $dir) {
if ($class === strstr($class, $namespace)) {
$classPath = str_replace(
self::NAMESPACE_SEPARATOR,
DIRECTORY_SEPARATOR,
substr($class, strlen($namespace))
) . '.php';
if (file_exists($file = $dir . $classPath)) {
return $file;
}
}
}
return null;
}
/**
* Load the given class or interface
*
* @param string $class Name of the class or interface
*
* @return bool Whether the class or interface has been loaded
*/
public function loadClass($class)
{
if ($file = $this->getSourceFile($class)) {
require $file;
return true;
}
return false;
}
/**
* Register {@link loadClass()} as an autoloader
*/
public function register()
{
spl_autoload_register(array($this, 'loadClass'));
}
/**
* Unregister {@link loadClass()} as an autoloader
*/
public function unregister()
{
spl_autoload_unregister(array($this, 'loadClass'));
}
/**
* Unregister this as an autoloader
*/
public function __destruct()
{
$this->unregister();
}
}

View File

@ -1,138 +0,0 @@
<?php
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
namespace Icinga\Application;
use Icinga\Exception\ProgrammingError;
class Loader
{
/**
* Namespace separator
*/
const NAMESPACE_SEPARATOR = '\\';
/**
* List of namespaces
*
* @var array
*/
private $namespaces = array();
/**
* Detach spl autoload method from stack
*/
public function __destruct()
{
$this->unRegister();
}
/**
* Register new namespace for directory
*
* @param string $namespace
* @param string $directory
*
* @throws ProgrammingError
*/
public function registerNamespace($namespace, $directory)
{
if (!is_dir($directory)) {
throw new ProgrammingError(
'Directory "%s" for namespace "%s" does not exist',
$directory,
$namespace
);
}
$this->namespaces[$namespace] = $directory;
}
/**
* Test if a namespace exists
*
* @param string $namespace
*
* @return bool
*/
public function hasNamespace($namespace)
{
return array_key_exists($namespace, $this->namespaces);
}
/**
* Class loader
*
* Ignores all but classes in registered namespaces.
*
* @param string $class
*
* @return boolean
*/
public function loadClass($class)
{
$namespace = $this->getNamespaceForClass($class);
if ($namespace) {
$file = $this->namespaces[$namespace] . preg_replace('/^' . preg_quote($namespace) . '/', '', $class);
$file = str_replace(self::NAMESPACE_SEPARATOR, '/', $file) . '.php';
if (@file_exists($file)) {
require_once $file;
return true;
}
}
return false;
}
/**
* Test if we have a registered namespaces for this class
*
* Return is the longest match in the array found
*
* @param string $className
*
* @return bool|string
*/
private function getNamespaceForClass($className)
{
$testNamespace = '';
$testLength = 0;
foreach (array_keys($this->namespaces) as $namespace) {
$stub = preg_replace(
'/^' . preg_quote($namespace) . '(' . preg_quote(self::NAMESPACE_SEPARATOR) . '|$)/', '', $className
);
$length = strlen($className) - strlen($stub);
if ($length > $testLength) {
$testLength = $length;
$testNamespace = $namespace;
}
}
if ($testLength > 0) {
return $testNamespace;
}
return false;
}
/**
* Effectively registers the autoloader the PHP/SPL way
*/
public function register()
{
// Think about to add class pathes to php include path
// this could be faster (tg)
spl_autoload_register(array(&$this, 'loadClass'));
}
/**
* Detach autoloader from spl registration
*/
public function unRegister()
{
spl_autoload_unregister(array(&$this, 'loadClass'));
}
}

View File

@ -36,7 +36,7 @@ class StdoutWriter extends LogWriter
$color = 'red';
break;
case Logger::WARNING:
$color = 'orange';
$color = 'yellow';
break;
case Logger::INFO:
$color = 'green';

View File

@ -4,23 +4,24 @@
namespace Icinga\Application\Modules;
use Exception;
use Zend_Controller_Router_Route;
use Zend_Controller_Router_Route_Abstract;
use Zend_Controller_Router_Route as Route;
use Zend_Controller_Router_Route_Regex as RegexRoute;
use Zend_Controller_Router_Route_Regex;
use Icinga\Application\ApplicationBootstrap;
use Icinga\Application\Config;
use Icinga\Application\Icinga;
use Icinga\Application\Logger;
use Icinga\Data\ConfigObject;
use Icinga\Exception\IcingaException;
use Icinga\Exception\ProgrammingError;
use Icinga\Module\Setup\SetupWizard;
use Icinga\Util\File;
use Icinga\Util\Translator;
use Icinga\Web\Controller\Dispatcher;
use Icinga\Web\Hook;
use Icinga\Web\Menu;
use Icinga\Web\Widget;
use Icinga\Web\Widget\Dashboard\Pane;
use Icinga\Module\Setup\SetupWizard;
use Icinga\Util\File;
use Icinga\Exception\ProgrammingError;
use Icinga\Exception\IcingaException;
/**
* Module handling
@ -188,7 +189,7 @@ class Module
/**
* A set of menu elements
*
* @var array
* @var Menu[]
*/
protected $menuItems = array();
@ -770,6 +771,7 @@ class Module
{
$this->launchConfigScript();
$tabs = Widget::create('tabs');
/** @var \Icinga\Web\Widget\Tabs $tabs */
$tabs->add('info', array(
'url' => 'config/module',
'urlParams' => array('name' => $this->getName()),
@ -934,7 +936,7 @@ class Module
}
/**
* Register module namespaces on the autoloader
* Register module namespaces on our class loader
*
* @return $this
*/
@ -944,16 +946,17 @@ class Module
return $this;
}
$loader = $this->app->getLoader();
$moduleName = ucfirst($this->getName());
$moduleLibraryDir = $this->getLibDir(). '/'. $moduleName;
if (is_dir($moduleLibraryDir)) {
$this->app->getLoader()->registerNamespace('Icinga\\Module\\' . $moduleName, $moduleLibraryDir);
$loader->registerNamespace('Icinga\\Module\\' . $moduleName, $moduleLibraryDir);
}
$moduleFormDir = $this->getFormDir();
if (is_dir($moduleFormDir)) {
$this->app->getLoader()->registerNamespace('Icinga\\Module\\' . $moduleName. '\\Forms', $moduleFormDir);
$loader->registerNamespace('Icinga\\Module\\' . $moduleName. '\\Forms', $moduleFormDir);
}
$this->registeredAutoloader = true;
@ -1015,19 +1018,23 @@ class Module
*/
protected function registerWebIntegration()
{
if (!$this->app->isWeb()) {
if (! $this->app->isWeb()) {
return $this;
}
if (file_exists($this->controllerdir) && is_dir($this->controllerdir)) {
$moduleControllerDir = $this->getControllerDir();
if (is_dir($moduleControllerDir)) {
$this->app->getfrontController()->addControllerDirectory(
$this->controllerdir,
$this->name
$moduleControllerDir,
$this->getName()
);
$this->app->getLoader()->registerNamespace(
'Icinga\\Module\\' . ucfirst($this->getName()) . '\\' . Dispatcher::CONTROLLER_NAMESPACE,
$moduleControllerDir
);
}
$this->registerLocales()
->registerRoutes();
$this
->registerLocales()
->registerRoutes();
return $this;
}
@ -1039,27 +1046,30 @@ class Module
protected function registerRoutes()
{
$router = $this->app->getFrontController()->getRouter();
/** @var \Zend_Controller_Router_Rewrite $router */
foreach ($this->routes as $name => $route) {
$router->addRoute($name, $route);
}
$router->addRoute(
$this->name . '_jsprovider',
new Route(
new Zend_Controller_Router_Route(
'js/' . $this->name . '/:file',
array(
'action' => 'javascript',
'controller' => 'static',
'action' =>'javascript',
'module' => 'default',
'module_name' => $this->name
)
)
);
$router->addRoute(
$this->name . '_img',
new RegexRoute(
new Zend_Controller_Router_Route_Regex(
'img/' . $this->name . '/(.+)',
array(
'controller' => 'static',
'action' => 'img',
'controller' => 'static',
'module' => 'default',
'module_name' => $this->name
),
array(

View File

@ -3,12 +3,15 @@
namespace Icinga\Application;
/**
* Retrieve the version of Icinga Web 2
*/
class Version
{
/**
* Get the version of this instance of Icinga Web 2
*
* @return array|bool array on success, false otherwise
* @return array|false array on success, false otherwise
*/
public static function get()
{

View File

@ -15,6 +15,7 @@ use Icinga\Authentication\Auth;
use Icinga\User;
use Icinga\Util\TimezoneDetect;
use Icinga\Util\Translator;
use Icinga\Web\Controller\Dispatcher;
use Icinga\Web\Notification;
use Icinga\Web\Session;
use Icinga\Web\Session\Session as BaseSession;
@ -83,14 +84,14 @@ class Web extends EmbeddedWeb
->setupNotifications()
->setupRequest()
->setupResponse()
->setupUserBackendFactory()
->setupUser()
->setupTimezone()
->setupLogger()
->setupInternationalization()
->setupZendMvc()
->setupFormNamespace()
->setupNamespaces()
->setupModuleManager()
->setupUserBackendFactory()
->loadSetupModuleIfNecessary()
->loadEnabledModules()
->setupRoute()
@ -210,6 +211,7 @@ class Web extends EmbeddedWeb
private function setupFrontController()
{
$this->frontController = Zend_Controller_Front::getInstance();
$this->frontController->setDispatcher(new Dispatcher());
$this->frontController->setRequest($this->getRequest());
$this->frontController->setControllerDirectory($this->getApplicationDir('/controllers'));
@ -306,16 +308,22 @@ class Web extends EmbeddedWeb
}
/**
* Setup an autoloader namespace for Icinga\Forms
* Setup class loader namespaces for Icinga\Controllers and Icinga\Forms
*
* @return $this
*/
private function setupFormNamespace()
private function setupNamespaces()
{
$this->getLoader()->registerNamespace(
'Icinga\\Forms',
$this->getApplicationDir('forms')
);
$this
->getLoader()
->registerNamespace(
'Icinga\\' . Dispatcher::CONTROLLER_NAMESPACE,
$this->getApplicationDir('controllers')
)
->registerNamespace(
'Icinga\\Forms',
$this->getApplicationDir('forms')
);
return $this;
}
}

View File

@ -3,11 +3,9 @@
namespace Icinga\Application;
use Icinga\Application\EmbeddedWeb;
use Icinga\Application\Web;
use Icinga\Web\StyleSheet;
use Icinga\Web\JavaScript;
use Icinga\Chart\Inline\PieChart;
use Icinga\Web\JavaScript;
use Icinga\Web\StyleSheet;
error_reporting(E_ALL | E_STRICT);

View File

@ -284,7 +284,7 @@ class DbUserBackend extends DbRepository implements UserBackendInterface, Inspec
$insp->write($this->ds->inspect());
try {
$users = $this->select()->where('is_active', true)->count();
if ($users >= 1) {
if ($users > 0) {
$insp->write(sprintf('%s active users', $users));
} else {
return $insp->error('0 active users', $users);

View File

@ -43,7 +43,7 @@ class DbConnection implements Selectable, Extensible, Updatable, Reducible, Insp
private $dbType;
/**
* @var Zend_Db_Adapter_Abstract
* @var \Zend_Db_Adapter_Abstract
*/
private $dbAdapter;
@ -112,7 +112,7 @@ class DbConnection implements Selectable, Extensible, Updatable, Reducible, Insp
/**
* Getter for the Zend_Db_Adapter
*
* @return Zend_Db_Adapter_Abstract
* @return \Zend_Db_Adapter_Abstract
*/
public function getDbAdapter()
{

View File

@ -227,6 +227,8 @@ abstract class Filter
* Create filter from queryString
*
* This is still pretty basic, need improvement
*
* @return static
*/
public static function fromQueryString($query)
{

View File

@ -4,12 +4,11 @@
namespace Icinga\Data;
use Icinga\Data\Filter\Filter;
use Icinga\Data\SimpleQuery;
use Icinga\Application\Icinga;
use Icinga\Web\Paginator\Adapter\QueryAdapter;
use Zend_Paginator;
class PivotTable
class PivotTable implements Sortable
{
/**
* The query to fetch as pivot table
@ -19,53 +18,74 @@ class PivotTable
protected $baseQuery;
/**
* The query to fetch the x axis labels
*
* @var SimpleQuery
*/
protected $xAxisQuery;
/**
* The query to fetch the y axis labels
*
* @var SimpleQuery
*/
protected $yAxisQuery;
/**
* The column that contains the labels for the x axis
* X-axis pivot column
*
* @var string
*/
protected $xAxisColumn;
/**
* The column that contains the labels for the y axis
* Y-axis pivot column
*
* @var string
*/
protected $yAxisColumn;
/**
* The filter being applied on the query for the x axis
* Column for sorting the result set
*
* @var array
*/
protected $order = array();
/**
* The filter being applied on the query for the x-axis
*
* @var Filter
*/
protected $xAxisFilter;
/**
* The filter being applied on the query for the y axis
* The filter being applied on the query for the y-axis
*
* @var Filter
*/
protected $yAxisFilter;
/**
* The query to fetch the leading x-axis rows and their headers
*
* @var SimpleQuery
*/
protected $xAxisQuery;
/**
* The query to fetch the leading y-axis rows and their headers
*
* @var SimpleQuery
*/
protected $yAxisQuery;
/**
* X-axis header column
*
* @var string|null
*/
protected $xAxisHeader;
/**
* Y-axis header column
*
* @var string|null
*/
protected $yAxisHeader;
/**
* Create a new pivot table
*
* @param SimpleQuery $query The query to fetch as pivot table
* @param string $xAxisColumn The column that contains the labels for the x axis
* @param string $yAxisColumn The column that contains the labels for the y axis
* @param SimpleQuery $query The query to fetch as pivot table
* @param string $xAxisColumn X-axis pivot column
* @param string $yAxisColumn Y-axis pivot column
*/
public function __construct(SimpleQuery $query, $xAxisColumn, $yAxisColumn)
{
@ -75,7 +95,32 @@ class PivotTable
}
/**
* Set the filter to apply on the query for the x axis
* {@inheritdoc}
*/
public function getOrder()
{
return $this->order;
}
/**
* {@inheritdoc}
*/
public function hasOrder()
{
return ! empty($this->order);
}
/**
* {@inheritdoc}
*/
public function order($field, $direction = null)
{
$this->order[$field] = $direction;
return $this;
}
/**
* Set the filter to apply on the query for the x-axis
*
* @param Filter $filter
*
@ -88,7 +133,7 @@ class PivotTable
}
/**
* Set the filter to apply on the query for the y axis
* Set the filter to apply on the query for the y-axis
*
* @param Filter $filter
*
@ -100,6 +145,56 @@ class PivotTable
return $this;
}
/**
* Get the x-axis header
*
* Defaults to {@link $xAxisColumn} in case no x-axis header has been set using {@link setXAxisHeader()}
*
* @return string
*/
public function getXAxisHeader()
{
return $this->xAxisHeader !== null ? $this->xAxisHeader : $this->xAxisColumn;
}
/**
* Set the x-axis header
*
* @param string $xAxisHeader
*
* @return $this
*/
public function setXAxisHeader($xAxisHeader)
{
$this->xAxisHeader = (string) $xAxisHeader;
return $this;
}
/**
* Get the y-axis header
*
* Defaults to {@link $yAxisColumn} in case no x-axis header has been set using {@link setYAxisHeader()}
*
* @return string
*/
public function getYAxisHeader()
{
return $this->yAxisHeader !== null ? $this->yAxisHeader : $this->yAxisColumn;
}
/**
* Set the y-axis header
*
* @param string $yAxisHeader
*
* @return $this
*/
public function setYAxisHeader($yAxisHeader)
{
$this->yAxisHeader = (string) $yAxisHeader;
return $this;
}
/**
* Return the value for the given request parameter
*
@ -107,7 +202,7 @@ class PivotTable
* @param string $param The parameter name to return
* @param int $default The default value to return
*
* @return int
* @return int
*/
protected function getPaginationParameter($axis, $param, $default = null)
{
@ -125,23 +220,25 @@ class PivotTable
/**
* Query horizontal (x) axis
*
* @return SimpleQuery
* @return SimpleQuery
*/
protected function queryXAxis()
{
if ($this->xAxisQuery === null) {
$this->xAxisQuery = clone $this->baseQuery;
$this->xAxisQuery->group($this->xAxisColumn);
$this->xAxisQuery->columns(array($this->xAxisColumn));
$this->xAxisQuery->setUseSubqueryCount();
$xAxisHeader = $this->getXAxisHeader();
$columns = array($this->xAxisColumn, $xAxisHeader);
$this->xAxisQuery->group(array_unique($columns)); // xAxisColumn and header may be the same column
$this->xAxisQuery->columns($columns);
if ($this->xAxisFilter !== null) {
$this->xAxisQuery->addFilter($this->xAxisFilter);
}
if (! $this->xAxisQuery->hasOrder($this->xAxisColumn)) {
$this->xAxisQuery->order($this->xAxisColumn, 'asc');
}
$this->xAxisQuery->order(
$xAxisHeader,
isset($this->order[$xAxisHeader]) ? $this->order[$xAxisHeader] : self::SORT_ASC
);
}
return $this->xAxisQuery;
@ -150,30 +247,31 @@ class PivotTable
/**
* Query vertical (y) axis
*
* @return SimpleQuery
* @return SimpleQuery
*/
protected function queryYAxis()
{
if ($this->yAxisQuery === null) {
$this->yAxisQuery = clone $this->baseQuery;
$this->yAxisQuery->group($this->yAxisColumn);
$this->yAxisQuery->columns(array($this->yAxisColumn));
$this->yAxisQuery->setUseSubqueryCount();
$yAxisHeader = $this->getYAxisHeader();
$columns = array($this->yAxisColumn, $yAxisHeader);
$this->yAxisQuery->group(array_unique($columns)); // yAxisColumn and header may be the same column
$this->yAxisQuery->columns($columns);
if ($this->yAxisFilter !== null) {
$this->yAxisQuery->addFilter($this->yAxisFilter);
}
if (! $this->yAxisQuery->hasOrder($this->yAxisColumn)) {
$this->yAxisQuery->order($this->yAxisColumn, 'asc');
}
$this->yAxisQuery->order(
$yAxisHeader,
isset($this->order[$yAxisHeader]) ? $this->order[$yAxisHeader] : self::SORT_ASC
);
}
return $this->yAxisQuery;
}
/**
* Return a pagination adapter for the x axis query
* Return a pagination adapter for the x-axis query
*
* $limit and $page are taken from the current request if not given.
*
@ -204,7 +302,7 @@ class PivotTable
}
/**
* Return a pagination adapter for the y axis query
* Return a pagination adapter for the y-axis query
*
* $limit and $page are taken from the current request if not given.
*
@ -235,9 +333,9 @@ class PivotTable
}
/**
* Return the pivot table as array
* Return the pivot table as an array of pivot data and pivot header
*
* @return array
* @return array
*/
public function toArray()
{
@ -245,33 +343,39 @@ class PivotTable
($this->xAxisFilter === null && $this->yAxisFilter === null)
|| ($this->xAxisFilter !== null && $this->yAxisFilter !== null)
) {
$xAxis = $this->queryXAxis()->fetchColumn();
$yAxis = $this->queryYAxis()->fetchColumn();
$xAxis = $this->queryXAxis()->fetchPairs();
$yAxis = $this->queryYAxis()->fetchPairs();
} else {
if ($this->xAxisFilter !== null) {
$xAxis = $this->queryXAxis()->fetchColumn();
$yAxis = $this->queryYAxis()->where($this->xAxisColumn, $xAxis)->fetchColumn();
$xAxis = $this->queryXAxis()->fetchPairs();
$yAxis = $this->queryYAxis()->where($this->xAxisColumn, $xAxis)->fetchPairs();
} else { // $this->yAxisFilter !== null
$yAxis = $this->queryYAxis()->fetchColumn();
$xAxis = $this->queryXAxis()->where($this->yAxisColumn, $yAxis)->fetchColumn();
$yAxis = $this->queryYAxis()->fetchPairs();
$xAxis = $this->queryXAxis()->where($this->yAxisColumn, $yAxis)->fetchPairs();
}
}
$pivotData = array();
$pivotHeader = array(
'cols' => $xAxis,
'rows' => $yAxis
);
if (! empty($xAxis) && ! empty($yAxis)) {
$xAxisKeys = array_keys($xAxis);
$yAxisKeys = array_keys($yAxis);
$this->baseQuery
->where($this->xAxisColumn, $xAxisKeys)
->where($this->yAxisColumn, $yAxisKeys);
$pivot = array();
if (!empty($xAxis) && !empty($yAxis)) {
$this->baseQuery->where($this->xAxisColumn, $xAxis)->where($this->yAxisColumn, $yAxis);
foreach ($yAxis as $yLabel) {
foreach ($xAxis as $xLabel) {
$pivot[$yLabel][$xLabel] = null;
foreach ($yAxisKeys as $yAxisKey) {
foreach ($xAxisKeys as $xAxisKey) {
$pivotData[$yAxisKey][$xAxisKey] = null;
}
}
foreach ($this->baseQuery as $row) {
$pivot[$row->{$this->yAxisColumn}][$row->{$this->xAxisColumn}] = $row;
$pivotData[$row->{$this->yAxisColumn}][$row->{$this->xAxisColumn}] = $row;
}
}
return $pivot;
return array($pivotData, $pivotHeader);
}
}

View File

@ -0,0 +1,11 @@
<?php
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
namespace Icinga\Exception;
/**
* Exception thrown if something to add already exists
*/
class AlreadyExistsException extends IcingaException
{
}

View File

@ -0,0 +1,11 @@
<?php
namespace Icinga\Exception\Http;
/**
* Exception thrown for sending a HTTP 400 response w/ a custom message
*/
class HttpBadRequestException extends HttpException
{
}

View File

@ -358,10 +358,30 @@ class LdapConnection implements Selectable, Inspectable
*/
public function count(LdapQuery $query)
{
$ds = $this->getConnection();
$this->bind();
$res = $this->runQuery($query, array());
return count($res);
$results = @ldap_search(
$ds,
$query->getBase() ?: $this->getDn(),
(string) $query,
array('dn'),
0,
0
);
if ($results === false) {
if (ldap_errno($ds) !== self::LDAP_NO_SUCH_OBJECT) {
throw new LdapException(
'LDAP count query "%s" (base %s) failed: %s',
(string) $query,
$query->getBase() ?: $this->getDn(),
ldap_error($ds)
);
}
}
return ldap_count_entries($ds, $results);
}
/**
@ -538,9 +558,9 @@ class LdapConnection implements Selectable, Inspectable
*/
public function hasDn($dn)
{
$ds = $this->getConnection();
$this->bind();
$ds = $this->getConnection();
$result = ldap_read($ds, $dn, '(objectClass=*)', array('objectClass'));
return ldap_count_entries($ds, $result) > 0;
}
@ -556,9 +576,9 @@ class LdapConnection implements Selectable, Inspectable
*/
public function deleteRecursively($dn)
{
$ds = $this->getConnection();
$this->bind();
$ds = $this->getConnection();
$result = @ldap_list($ds, $dn, '(objectClass=*)', array('objectClass'));
if ($result === false) {
if (ldap_errno($ds) === self::LDAP_NO_SUCH_OBJECT) {
@ -591,9 +611,9 @@ class LdapConnection implements Selectable, Inspectable
*/
public function deleteDn($dn)
{
$ds = $this->getConnection();
$this->bind();
$ds = $this->getConnection();
$result = @ldap_delete($ds, $dn);
if ($result === false) {
if (ldap_errno($ds) === self::LDAP_NO_SUCH_OBJECT) {
@ -646,7 +666,7 @@ class LdapConnection implements Selectable, Inspectable
$ds = $this->getConnection();
$serverSorting = false;//$this->capabilities->hasOid(Capability::LDAP_SERVER_SORT_OID);
$serverSorting = $this->getCapabilities()->hasOid(LdapCapabilities::LDAP_SERVER_SORT_OID);
if ($serverSorting && $query->hasOrder()) {
ldap_set_option($ds, LDAP_OPT_SERVER_CONTROLS, array(
array(
@ -741,15 +761,8 @@ class LdapConnection implements Selectable, Inspectable
$ds = $this->getConnection();
$serverSorting = false;//$this->capabilities->hasOid(Capability::LDAP_SERVER_SORT_OID);
if ($serverSorting && $query->hasOrder()) {
ldap_set_option($ds, LDAP_OPT_SERVER_CONTROLS, array(
array(
'oid' => LdapCapabilities::LDAP_SERVER_SORT_OID,
'value' => $this->encodeSortRules($query->getOrder())
)
));
} elseif ($query->hasOrder()) {
$serverSorting = $this->getCapabilities()->hasOid(LdapCapabilities::LDAP_SERVER_SORT_OID);
if (! $serverSorting && $query->hasOrder()) {
foreach ($query->getOrder() as $rule) {
if (! in_array($rule[0], $fields)) {
$fields[] = $rule[0];
@ -765,6 +778,15 @@ class LdapConnection implements Selectable, Inspectable
// server to return results even if the paged search request cannot be satisfied
ldap_control_paged_result($ds, $pageSize, false, $cookie);
if ($serverSorting) {
ldap_set_option($ds, LDAP_OPT_SERVER_CONTROLS, array(
array(
'oid' => LdapCapabilities::LDAP_SERVER_SORT_OID,
'value' => $this->encodeSortRules($query->getOrder())
)
));
}
$results = @ldap_search(
$ds,
$base,
@ -910,28 +932,49 @@ class LdapConnection implements Selectable, Inspectable
*
* @param array $sortRules
*
* @return string
* @throws ProgrammingError
*
* @todo Produces an invalid stream, obviously
* @return string Binary representation of the octet stream
*/
protected function encodeSortRules(array $sortRules)
{
if (count($sortRules) > 127) {
throw new ProgrammingError(
'Cannot encode more than 127 sort rules. Only length octets in short form are supported'
);
}
$sequenceOf = '';
$seq = '30' . str_pad(dechex(count($sortRules)), 2, '0', STR_PAD_LEFT);
foreach ($sortRules as $rule) {
$hexdAttribute = unpack('H*', $rule[0]);
$seq .= '3002'
. '04' . str_pad(dechex(strlen($rule[0])), 2, '0', STR_PAD_LEFT) . $hexdAttribute[1]
. '0101' . ($rule[1] === Sortable::SORT_DESC ? 'ff' : '00');
if (false && $rule[1] === Sortable::SORT_DESC) {
$reversed = '0101ff';
} else {
$reversed = '';
}
$attributeType = unpack('H*', $rule[0]);
$attributeType = $attributeType[1];
$attributeOctets = strlen($attributeType) / 2;
if ($attributeOctets >= 127) {
// Use the indefinite form of the length octets (the long form would be another option)
$attributeType = '0440' . $attributeType . '0000';
} else {
$attributeType = '04' . str_pad(dechex($attributeOctets), 2, '0', STR_PAD_LEFT) . $attributeType;
}
$sequence = $attributeType . $reversed;
$sequenceOctects = strlen($sequence) / 2;
if ($sequenceOctects >= 127) {
$sequence = '3040' . $sequence . '0000';
} else {
$sequence = '30' . str_pad(dechex($sequenceOctects), 2, '0', STR_PAD_LEFT) . $sequence;
}
$sequenceOf .= $sequence;
}
return $seq;
$sequenceOfOctets = strlen($sequenceOf) / 2;
if ($sequenceOfOctets >= 127) {
$sequenceOf = '3040' . $sequenceOf . '0000';
} else {
$sequenceOf = '30' . str_pad(dechex($sequenceOfOctets), 2, '0', STR_PAD_LEFT) . $sequenceOf;
}
return hex2bin($sequenceOf);
}
/**

View File

@ -452,16 +452,19 @@ class User
if (isset($this->permissions['*']) || isset($this->permissions[$requiredPermission])) {
return true;
}
// If the permission to check contains a wildcard, grant the permission if any permit related to the permission
// matches
$any = strpos($requiredPermission, '*');
$requiredWildcard = strpos($requiredPermission, '*');
foreach ($this->permissions as $grantedPermission) {
if ($any !== false) {
$wildcard = $any;
if ($requiredWildcard !== false) {
if (($grantedWildcard = strpos($grantedPermission, '*')) !== false) {
$wildcard = min($requiredWildcard, $grantedWildcard);
} else {
$wildcard = $requiredWildcard;
}
} else {
// If the permit contains a wildcard, grant the permission if it's related to the permit
$wildcard = strpos($grantedPermission, '*');
}
if ($wildcard !== false) {
if (substr($requiredPermission, 0, $wildcard) === substr($grantedPermission, 0, $wildcard)) {
return true;
@ -470,6 +473,7 @@ class User
return true;
}
}
return false;
}
}

View File

@ -195,13 +195,13 @@ class Translator
*
* @param string $locale The locale code to split, or null to split the current locale
*
* @return stdClass An object with a 'language' and 'country' attribute
* @return object An object with a 'language' and 'country' attribute
*/
public static function splitLocaleCode($locale = null)
{
$matches = array();
$locale = $locale !== null ? $locale : setlocale(LC_ALL, 0);
if (preg_match('@([a-z]{2})[_-]([A-Z]{2})@', $locale, $matches)) {
if (preg_match('@([a-z]{2})[_-]([a-z]{2})@i', $locale, $matches)) {
list($languageCode, $countryCode) = array_slice($matches, 1);
} elseif ($locale === 'C') {
list($languageCode, $countryCode) = preg_split('@[_-]@', static::DEFAULT_LOCALE, 2);
@ -272,36 +272,40 @@ class Translator
}
$requestedLocales[] = str_replace('-', '_', $headerValue);
}
$requestedLocales = array_combine(
array_map('strtolower', array_values($requestedLocales)),
array_values($requestedLocales)
);
$availableLocales = static::getAvailableLocaleCodes();
$availableLocales = array_combine(
array_map('strtolower', array_values($availableLocales)),
array_values($availableLocales)
);
$similarMatch = null;
$availableLocales = static::getAvailableLocaleCodes();
$perfectMatch = array_shift((array_intersect($requestedLocales, $availableLocales)));
foreach ($requestedLocales as $requestedLocale) {
if ($perfectMatch === $requestedLocale) {
// The perfect match must be preferred when reached before a similar match is found
return $perfectMatch;
foreach ($requestedLocales as $requestedLocaleLowered => $requestedLocale) {
$localeObj = static::splitLocaleCode($requestedLocaleLowered);
if (isset($availableLocales[$requestedLocaleLowered])
&& (! $similarMatch || static::splitLocaleCode($similarMatch)->language === $localeObj->language)
) {
// Prefer perfect match only if no similar match has been found yet or the perfect match is more precise
// than the similar match
return $availableLocales[$requestedLocaleLowered];
}
$similarMatches = array();
$localeObj = static::splitLocaleCode($requestedLocale);
foreach ($availableLocales as $availableLocale) {
if (static::splitLocaleCode($availableLocale)->language === $localeObj->language) {
$similarMatches[] = $availableLocale;
if (! $similarMatch) {
foreach ($availableLocales as $availableLocaleLowered => $availableLocale) {
if (static::splitLocaleCode($availableLocaleLowered)->language === $localeObj->language) {
$similarMatch = $availableLocaleLowered;
break;
}
}
}
if (!empty($similarMatches)) {
$similarMatch = array_shift($similarMatches); // There is no "best" similar match, just use the first
break;
}
}
if (!$perfectMatch && $similarMatch) {
return $similarMatch;
} elseif ($similarMatch && static::splitLocaleCode($similarMatch)->language === static::splitLocaleCode($perfectMatch)->language) {
return $perfectMatch;
} elseif ($similarMatch) {
return $similarMatch;
}
return static::DEFAULT_LOCALE;
return $similarMatch ? $availableLocales[$similarMatch] : static::DEFAULT_LOCALE;
}
}

View File

@ -6,6 +6,7 @@ namespace Icinga\Web;
use Icinga\Data\Filterable;
use Icinga\Data\Sortable;
use Icinga\Data\QueryInterface;
use Icinga\Exception\Http\HttpBadRequestException;
use Icinga\Exception\Http\HttpNotFoundException;
use Icinga\Web\Controller\ModuleActionController;
use Icinga\Web\Widget\Limiter;
@ -51,6 +52,19 @@ class Controller extends ModuleActionController
}
}
/**
* Immediately respond w/ HTTP 400
*
* @param string $message Exception message or exception format string
* @param mixed ...$arg Format string argument
*
* @throws HttpBadRequestException
*/
public function httpBadRequest($message)
{
throw HttpBadRequestException::create(func_get_args());
}
/**
* Immediately respond w/ HTTP 404
*

View File

@ -3,6 +3,10 @@
namespace Icinga\Web\Controller;
use Zend_Controller_Action;
use Zend_Controller_Action_HelperBroker;
use Zend_Controller_Request_Abstract;
use Zend_Controller_Response_Abstract;
use Icinga\Application\Benchmark;
use Icinga\Application\Config;
use Icinga\Authentication\Auth;
@ -19,15 +23,21 @@ use Icinga\Web\Url;
use Icinga\Web\UrlParams;
use Icinga\Web\Widget\Tabs;
use Icinga\Web\Window;
use Zend_Controller_Action;
use Zend_Controller_Action_HelperBroker as ActionHelperBroker;
use Zend_Controller_Request_Abstract as Request;
use Zend_Controller_Response_Abstract as Response;
/**
* Base class for all core action controllers
*
* All Icinga Web core controllers should extend this class
*
* @method \Icinga\Web\Request getRequest() {
* {@inheritdoc}
* @return \Icinga\Web\Request
* }
*
* @method \Icinga\Web\Response getResponse() {
* {@inheritdoc}
* @return \Icinga\Web\Response
* }
*/
class ActionController extends Zend_Controller_Action
{
@ -80,13 +90,13 @@ class ActionController extends Zend_Controller_Action
* The constructor starts benchmarking, loads the configuration and sets
* other useful controller properties
*
* @param Request $request
* @param Response $response
* @param array $invokeArgs Any additional invocation arguments
* @param Zend_Controller_Request_Abstract $request
* @param Zend_Controller_Response_Abstract $response
* @param array $invokeArgs Any additional invocation arguments
*/
public function __construct(
Request $request,
Response $response,
Zend_Controller_Request_Abstract $request,
Zend_Controller_Response_Abstract $response,
array $invokeArgs = array()
) {
$this->params = UrlParams::fromQueryString();
@ -94,7 +104,7 @@ class ActionController extends Zend_Controller_Action
$this->setRequest($request)
->setResponse($response)
->_setInvokeArgs($invokeArgs);
$this->_helper = new ActionHelperBroker($this);
$this->_helper = new Zend_Controller_Action_HelperBroker($this);
$this->handlerBrowserWindows();
$moduleName = $this->getModuleName();

View File

@ -8,26 +8,24 @@ use Icinga\Application\Icinga;
use Icinga\Web\Widget\Tabs;
/**
* Static helper class that collects tabs provided by the 'createProvidedTabs' method
* of controllers.
* Static helper class that collects tabs provided by the 'createProvidedTabs' method of controllers
*/
class ControllerTabCollector
{
/**
* Scan all controllers with the provided name
* in the application and (loaded) module folders and collects their provided tabs
* Scan all controllers with given name in the application and (loaded) module folders and collects their provided
* tabs
*
* @param string $controller The name of the controllers to use for tab collection
* @param string $controllerName The name of the controllers to use for tab collection
*
* @return Tabs A @see Tabs instance containing the application tabs first
* followed by the tabs provided from the modules
* @return Tabs A {@link Tabs} instance containing the application tabs first followed by the
* tabs provided from the modules
*/
public static function collectControllerTabs($controller)
public static function collectControllerTabs($controllerName)
{
require_once(Icinga::app()->getApplicationDir('/controllers/'.$controller.'.php'));
$controller = '\Icinga\\' . Dispatcher::CONTROLLER_NAMESPACE . '\\' . $controllerName;
$applicationTabs = $controller::createProvidedTabs();
$moduleTabs = self::collectModuleTabs($controller);
$moduleTabs = self::collectModuleTabs($controllerName);
$tabs = new Tabs();
foreach ($applicationTabs as $name => $tab) {
@ -35,7 +33,7 @@ class ControllerTabCollector
}
foreach ($moduleTabs as $name => $tab) {
// don't overwrite application tabs if the module wants to
// Don't overwrite application tabs if the module wants to
if ($tabs->has($name)) {
continue;
}
@ -66,29 +64,30 @@ class ControllerTabCollector
/**
* Collects the tabs from the createProvidedTabs() method in the configuration controller
*
* If the module doesn't have the given controller or createProvidedTabs method in the controller
* an empty array will be returned
* If the module doesn't have the given controller or createProvidedTabs method in the controller an empty array
* will be returned
*
* @param string $controller The name of the controller that provides tabs via createProvidedTabs
* @param Module $module The module instance that provides the controller
* @param string $controllerName The name of the controller that provides tabs via createProvidedTabs
* @param Module $module The module instance that provides the controller
*
* @return array
* @return array
*/
private static function createModuleConfigurationTabs($controller, Module $module)
private static function createModuleConfigurationTabs($controllerName, Module $module)
{
// TODO(el): Only works for controllers w/o namepsace: https://dev.icinga.org/issues/4149
$controllerDir = $module->getControllerDir();
$name = $module->getName();
$controllerDir = $controllerDir . '/' . $controller . '.php';
$controllerName = ucfirst($name) . '_' . $controller;
$controllerDir = $controllerDir . '/' . $controllerName . '.php';
$controllerName = ucfirst($name) . '_' . $controllerName;
if (is_readable($controllerDir)) {
require_once(realpath($controllerDir));
if (!method_exists($controllerName, "createProvidedTabs")) {
if (! method_exists($controllerName, 'createProvidedTabs')) {
return array();
}
$tab = $controllerName::createProvidedTabs();
if (!is_array($tab)) {
if (! is_array($tab)) {
$tab = array($name => $tab);
}
return $tab;

View File

@ -0,0 +1,92 @@
<?php
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
namespace Icinga\Web\Controller;
use Exception;
use Zend_Controller_Action;
use Zend_Controller_Action_Interface;
use Zend_Controller_Dispatcher_Exception;
use Zend_Controller_Dispatcher_Standard;
use Zend_Controller_Request_Abstract;
use Zend_Controller_Response_Abstract;
/**
* Dispatcher supporting Zend-style and namespaced controllers
*
* Does not support a namespaced default controller in combination w/ the Zend parameter useDefaultControllerAlways.
*/
class Dispatcher extends Zend_Controller_Dispatcher_Standard
{
/**
* Controller namespace
*
* @var string
*/
const CONTROLLER_NAMESPACE = 'Controllers';
/**
* Dispatch request to a controller and action
*
* @param Zend_Controller_Request_Abstract $request
* @param Zend_Controller_Response_Abstract $response
*
* @throws Zend_Controller_Dispatcher_Exception If the controller is not an instance of
* Zend_Controller_Action_Interface
* @throws Exception If dispatching the request fails
*/
public function dispatch(Zend_Controller_Request_Abstract $request, Zend_Controller_Response_Abstract $response)
{
$this->setResponse($response);
$controllerName = $request->getControllerName();
if (! $controllerName) {
parent::dispatch($request, $response);
return;
}
$controllerName = ucfirst($controllerName) . 'Controller';
$moduleName = $request->getModuleName();
if ($moduleName === null || $moduleName === $this->_defaultModule) {
$controllerClass = 'Icinga\\' . self::CONTROLLER_NAMESPACE . '\\' . $controllerName;
} else {
$controllerClass = 'Icinga\\Module\\' . ucfirst($moduleName) . '\\' . self::CONTROLLER_NAMESPACE . '\\'
. $controllerName;
}
if (! class_exists($controllerClass)) {
parent::dispatch($request, $response);
return;
}
$controller = new $controllerClass($request, $response, $this->getParams());
if (! $controller instanceof Zend_Controller_Action
&& ! $controller instanceof Zend_Controller_Action_Interface
) {
throw new Zend_Controller_Dispatcher_Exception(
'Controller "' . $controllerClass . '" is not an instance of Zend_Controller_Action_Interface'
);
}
$action = $this->getActionMethod($request);
$request->setDispatched(true);
// Buffer output by default
$disableOb = $this->getParam('disableOutputBuffering');
$obLevel = ob_get_level();
if (empty($disableOb)) {
ob_start();
}
try {
$controller->dispatch($action);
} catch (Exception $e) {
// Clean output buffer on error
$curObLevel = ob_get_level();
if ($curObLevel > $obLevel) {
do {
ob_get_clean();
$curObLevel = ob_get_level();
} while ($curObLevel > $obLevel);
}
throw $e;
}
if (empty($disableOb)) {
$content = ob_get_clean();
$response->appendBody($content);
}
}
}

View File

@ -30,6 +30,11 @@ use Icinga\Web\Form\Element\CsrfCounterMeasure;
*
* @return $this
* }
*
* @method \Zend_Form_Element[] getElements() {
* {@inheritdoc}
* @return \Zend_Form_Element[]
* }
*/
class Form extends Zend_Form
{
@ -60,6 +65,17 @@ class Form extends Zend_Form
*/
protected $created = false;
/**
* Whether the form is an API target
*
* When the form is an API target, the form evaluates as submitted if the request method equals the form method.
* That means, that the submit button and form identification are not taken into account. In addition, the CSRF
* counter measure will not be added to the form's elements.
*
* @var bool
*/
protected $isApiTarget = false;
/**
* The request associated with this form
*
@ -687,6 +703,29 @@ class Form extends Zend_Form
return $this->useFormAutosubmit;
}
/**
* Get whether the form is an API target
*
* @return bool
*/
public function getIsApiTarget()
{
return $this->isApiTarget;
}
/**
* Set whether the form is an API target
*
* @param bool $isApiTarget
*
* @return $this
*/
public function setIsApiTarget($isApiTarget = true)
{
$this->isApiTarget = (bool) $isApiTarget;
return $this;
}
/**
* Create this form
*
@ -997,7 +1036,7 @@ class Form extends Zend_Form
if (! $this->tokenDisabled) {
$request = $this->getRequest();
if (! $request->isXmlHttpRequest()
&& $request->getIsApiRequest()
&& ($this->getIsApiTarget() || $request->isApiRequest())
) {
return $this;
}
@ -1012,6 +1051,8 @@ class Form extends Zend_Form
* Populate the elements with the given values
*
* @param array $defaults The values to populate the elements with
*
* @return $this
*/
public function populate(array $defaults)
{
@ -1062,21 +1103,40 @@ class Form extends Zend_Form
}
$formData = $this->getRequestData();
if ($this->getUidDisabled() || $this->wasSent($formData)) {
if ($this->getIsApiTarget() || $this->getUidDisabled() || $this->wasSent($formData)) {
if (($frameUpload = (bool) $request->getUrl()->shift('_frameUpload', false))) {
$this->getView()->layout()->setLayout('wrapped');
}
$this->populate($formData); // Necessary to get isSubmitted() to work
if (! $this->getSubmitLabel() || $this->isSubmitted()) {
if ($this->isValid($formData)
&& (($this->onSuccess !== null && false !== call_user_func($this->onSuccess, $this))
|| ($this->onSuccess === null && false !== $this->onSuccess()))) {
if (! $frameUpload) {
|| ($this->onSuccess === null && false !== $this->onSuccess()))
) {
if ($this->getIsApiTarget() || $this->getRequest()->isApiRequest()) {
// API targets and API requests will never redirect but immediately respond w/ JSON-encoded
// notifications
$notifications = Notification::getInstance()->popMessages();
$message = null;
foreach ($notifications as $notification) {
if ($notification->type === Notification::SUCCESS) {
$message = $notification->message;
break;
}
}
$this->getResponse()->json()
->setSuccessData($message !== null ? array('message' => $message) : null)
->sendResponse();
} elseif (! $frameUpload) {
$this->getResponse()->redirectAndExit($this->getRedirectUrl());
} else {
$this->getView()->layout()->redirectUrl = $this->getRedirectUrl()->getAbsoluteUrl();
}
} elseif ($this->getIsApiTarget()) {
$this->getResponse()->sendJson(array(
'status' => 'fail',
'data' => array_merge($this->getMessages(), $this->getErrorMessages())
));
}
} elseif ($this->getValidatePartial()) {
// The form can't be processed but we may want to show validation errors though
@ -1098,6 +1158,12 @@ class Form extends Zend_Form
*/
public function isSubmitted()
{
if (strtolower($this->getRequest()->getMethod()) !== $this->getMethod()) {
return false;
}
if ($this->getIsApiTarget()) {
return true;
}
if ($this->getSubmitLabel()) {
return $this->getElement('btn_submit')->isChecked();
}
@ -1188,7 +1254,7 @@ class Form extends Zend_Form
* Load the default decorators
*
* Overwrites Zend_Form::loadDefaultDecorators to avoid having
* the HtmlTag-Decorator added and to provide viewscript usage
* the HtmlTag-Decorator added and to provide view script usage
*
* @return $this
*/
@ -1330,6 +1396,19 @@ class Form extends Zend_Form
return $this->request;
}
/**
* Set the request
*
* @param Request $request
*
* @return $this
*/
public function setRequest(Request $request)
{
$this->request = $request;
return $this;
}
/**
* Return the current Response
*
@ -1462,7 +1541,7 @@ class Form extends Zend_Form
/**
* Add a error notification and prevent the form from being successfully validated
*
* @param string|array $message The notfication's message
* @param string|array $message The notification message
*
* @return $this
*/
@ -1476,7 +1555,7 @@ class Form extends Zend_Form
/**
* Add a warning notification and prevent the form from being successfully validated
*
* @param string|array $message The notfication's message
* @param string|array $message The notification message
*
* @return $this
*/
@ -1490,7 +1569,7 @@ class Form extends Zend_Form
/**
* Add a info notification
*
* @param string|array $message The notfication's message
* @param string|array $message The notification message
* @param bool $markAsError Whether to prevent the form from being successfully validated or not
*
* @return $this

View File

@ -3,8 +3,8 @@
namespace Icinga\Web;
use Icinga\Application\Icinga;
use Zend_Controller_Request_Http;
use Icinga\Application\Icinga;
use Icinga\User;
/**
@ -13,11 +13,11 @@ use Icinga\User;
class Request extends Zend_Controller_Request_Http
{
/**
* User if authenticated
* Response
*
* @var User|null
* @var Response
*/
protected $user;
protected $response;
/**
* Unique identifier
@ -34,20 +34,24 @@ class Request extends Zend_Controller_Request_Http
protected $url;
/**
* Response
* User if authenticated
*
* @var Response
* @var User|null
*/
protected $response;
protected $user;
/**
* Get whether the request seems to be an API request
* Get the response
*
* @return bool
* @return Response
*/
public function getIsApiRequest()
public function getResponse()
{
return $this->getHeader('Accept') === 'application/json';
if ($this->response === null) {
$this->response = Icinga::app()->getResponse();
}
return $this->response;
}
/**
@ -87,17 +91,13 @@ class Request extends Zend_Controller_Request_Http
}
/**
* Get the response
* Get whether the request seems to be an API request
*
* @return Response
* @return bool
*/
public function getResponse()
public function isApiRequest()
{
if ($this->response === null) {
$this->response = Icinga::app()->getResponse();
}
return $this->response;
return $this->getHeader('Accept') === 'application/json';
}
/**

View File

@ -5,6 +5,7 @@ namespace Icinga\Web;
use Zend_Controller_Response_Http;
use Icinga\Application\Icinga;
use Icinga\Web\Response\JsonResponse;
class Response extends Zend_Controller_Response_Http
{
@ -96,6 +97,16 @@ class Response extends Zend_Controller_Response_Http
return $this;
}
/**
* Entry point for HTTP responses in JSON format
*
* @return JsonResponse
*/
public static function json()
{
return new JsonResponse();
}
/**
* Prepare the request before sending
*/

View File

@ -0,0 +1,205 @@
<?php
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
namespace Icinga\Web\Response;
use Zend_Controller_Action_HelperBroker;
use Icinga\Web\Response;
/**
* HTTP response in JSON format
*/
class JsonResponse extends Response
{
/**
* Status identifier for failed API calls due to an error on the server
*
* @var string
*/
const STATUS_ERROR = 'error';
/**
* Status identifier for rejected API calls most due to invalid data or call conditions
*
* @var string
*/
const STATUS_FAIL = 'fail';
/**
* Status identifier for successful API requests
*
* @var string
*/
const STATUS_SUCCESS = 'success';
/**
* JSON encoding options
*
* @var int
*/
protected $encodingOptions = 0;
/**
* Error message if the API call failed due to a server error
*
* @var string|null
*/
protected $errorMessage;
/**
* Fail data for rejected API calls
*
* @var array|null
*/
protected $failData;
/**
* API request status
*
* @var string
*/
protected $status;
/**
* Success data for successful API requests
*
* @var array|null
*/
protected $successData;
/**
* Get the JSON encoding options
*
* @return int
*/
public function getEncodingOptions()
{
return $this->encodingOptions;
}
/**
* Set the JSON encoding options
*
* @param int $encodingOptions
*
* @return $this
*/
public function setEncodingOptions($encodingOptions)
{
$this->encodingOptions = (int) $encodingOptions;
return $this;
}
/**
* Get the error message if the API call failed due to a server error
*
* @return string|null
*/
public function getErrorMessage()
{
return $this->errorMessage;
}
/**
* Set the error message if the API call failed due to a server error
*
* @param string $errorMessage
*
* @return $this
*/
public function setErrorMessage($errorMessage)
{
$this->errorMessage = (string) $errorMessage;
$this->status = static::STATUS_ERROR;
return $this;
}
/**
* Get the fail data for rejected API calls
*
* @return array|null
*/
public function getFailData()
{
return $this->failData;
}
/**
* Set the fail data for rejected API calls
*
* @param array $failData
*
* @return $this
*/
public function setFailData(array $failData)
{
$this->failData = $failData;
$this->status = static::STATUS_FAIL;
return $this;
}
/**
* Get the data for successful API requests
*
* @return array|null
*/
public function getSuccessData()
{
return (! is_array($this->successData) || empty($this->successData)) ? null : $this->successData;
}
/**
* Set the data for successful API requests
*
* @param array $successData
*
* @return $this
*/
public function setSuccessData(array $successData = null)
{
$this->successData = $successData;
$this->status = static::STATUS_SUCCESS;
return $this;
}
/**
* {@inheritdoc}
*/
public function outputBody()
{
$body = array(
'status' => $this->status
);
switch ($this->status) {
case static::STATUS_ERROR:
$body['message'] = $this->getErrorMessage();
break;
case static::STATUS_FAIL:
$body['data'] = $this->getFailData();
break;
case static::STATUS_SUCCESS:
$body['data'] = $this->getSuccessData();
break;
}
echo json_encode($body, $this->getEncodingOptions());
}
/**
* {@inheritdoc}
*/
public function sendHeaders()
{
$this->setHeader('Content-Type', 'application/json', true);
parent::sendHeaders();
}
/**
* {@inheritdoc}
*/
public function sendResponse()
{
Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer')->setNoRender(true);
parent::sendResponse();
exit;
}
}

View File

@ -12,6 +12,7 @@ class StyleSheet
protected static $lessFiles = array(
'../application/fonts/fontello-ifont/css/ifont-embedded.css',
'css/vendor/tipsy.css',
'css/icinga/mixins.less',
'css/icinga/defaults.less',
'css/icinga/animation.less',
'css/icinga/layout-colors.less',

View File

@ -6,7 +6,7 @@ namespace Icinga\Web;
use Icinga\Application\Icinga;
use Icinga\Cli\FakeRequest;
use Icinga\Exception\ProgrammingError;
use Icinga\Web\UrlParams;
use Icinga\Data\Filter\Filter;
/**
* Url class that provides convenient access to parameters, allows to modify query parameters and
@ -156,6 +156,26 @@ class Url
return $urlObject;
}
/**
* Create a new filter that needs to fullfill the base filter and the optional filter (if it exists)
*
* @param string $url The url to apply the new filter to
* @param Filter $filter The base filter
* @param Filter $optional The optional filter
*
* @return Url The altered URL containing the new filter
* @throws ProgrammingError
*/
public static function urlAddFilterOptional($url, $filter, $optional)
{
$url = Url::fromPath($url);
$f = $filter;
if (isset($optional)) {
$f = Filter::matchAll($filter, $optional);
}
return $url->setQueryString($f->toQueryString());
}
/**
* Overwrite the baseUrl
*

View File

@ -118,12 +118,12 @@ class SortBox extends AbstractWidget
if ($request === null) {
$request = Icinga::app()->getRequest();
}
if (($sort = $request->getParam('sort'))) {
$this->query->order($sort, $request->getParam('dir'));
} elseif (($dir = $request->getParam('dir'))) {
$this->query->order(null, $dir);
if (null === $sort = $request->getParam('sort')) {
list($sort, $dir) = $this->getSortDefaults();
} else {
list($_, $dir) = $this->getSortDefaults($sort);
}
$this->query->order($sort, $request->getParam('dir', $dir));
}
return $this;
@ -148,8 +148,10 @@ class SortBox extends AbstractWidget
if ($column !== null && isset($sortRules[$column]['order'])) {
$direction = strtoupper($sortRules[$column]['order']) === Sortable::SORT_DESC ? 'desc' : 'asc';
}
} elseif ($column === null) {
reset($this->sortFields);
$column = key($this->sortFields);
}
return array($column, $direction);
}

View File

@ -44,7 +44,7 @@ class HTMLPurifier_AttrDef_CSS_Multiple extends HTMLPurifier_AttrDef
*/
public function validate($string, $config, $context)
{
$string = $this->parseCDATA($string);
$string = $this->mungeRgb($this->parseCDATA($string));
if ($string === '') {
return false;
}

View File

@ -32,9 +32,6 @@ class HTMLPurifier_AttrDef_HTML_Bool extends HTMLPurifier_AttrDef
*/
public function validate($string, $config, $context)
{
if (empty($string)) {
return false;
}
return $this->name;
}

View File

@ -350,8 +350,7 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
$this->info['scrollbar-highlight-color'] = new HTMLPurifier_AttrDef_CSS_Color();
$this->info['scrollbar-shadow-color'] = new HTMLPurifier_AttrDef_CSS_Color();
// technically not proprietary, but CSS3, and no one supports it
$this->info['opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue();
// vendor specific prefixes of opacity
$this->info['-moz-opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue();
$this->info['-khtml-opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue();
@ -404,6 +403,7 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
array('visible', 'hidden', 'collapse')
);
$this->info['overflow'] = new HTMLPurifier_AttrDef_Enum(array('visible', 'hidden', 'auto', 'scroll'));
$this->info['opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue();
}
/**

View File

@ -21,7 +21,7 @@ class HTMLPurifier_Config
* HTML Purifier's version
* @type string
*/
public $version = '4.6.0';
public $version = '4.7.0';
/**
* Whether or not to automatically finalize
@ -646,16 +646,25 @@ class HTMLPurifier_Config
return $this->getDefinition($name, true, true);
}
/**
* @return HTMLPurifier_HTMLDefinition
*/
public function maybeGetRawHTMLDefinition()
{
return $this->getDefinition('HTML', true, true);
}
/**
* @return HTMLPurifier_CSSDefinition
*/
public function maybeGetRawCSSDefinition()
{
return $this->getDefinition('CSS', true, true);
}
/**
* @return HTMLPurifier_URIDefinition
*/
public function maybeGetRawURIDefinition()
{
return $this->getDefinition('URI', true, true);

View File

@ -0,0 +1,14 @@
AutoFormat.RemoveEmpty.Predicate
TYPE: hash
VERSION: 4.7.0
DEFAULT: array('colgroup' => array(), 'th' => array(), 'td' => array(), 'iframe' => array('src'))
--DESCRIPTION--
<p>
Given that an element has no contents, it will be removed by default, unless
this predicate dictates otherwise. The predicate can either be an associative
map from tag name to list of attributes that must be present for the element
to be considered preserved: thus, the default always preserves <code>colgroup</code>,
<code>th</code> and <code>td</code>, and also <code>iframe</code> if it
has a <code>src</code>.
</p>
--# vim: et sw=4 sts=4

View File

@ -4,6 +4,6 @@ VERSION: 2.0.1
DEFAULT: NULL
--DESCRIPTION--
A custom doctype for power-users who defined there own document
A custom doctype for power-users who defined their own document
type. This directive only applies when %HTML.Doctype is blank.
--# vim: et sw=4 sts=4

View File

@ -219,9 +219,15 @@ class HTMLPurifier_DefinitionCache_Serializer extends HTMLPurifier_DefinitionCac
} elseif (!$this->_testPermissions($base, $chmod)) {
return false;
}
$old = umask(0000);
mkdir($directory, $chmod);
umask($old);
if (!$this->_testPermissions($directory, $chmod)) {
trigger_error(
'Base directory ' . $base . ' does not exist,
please create or change using %Cache.SerializerPath',
E_USER_WARNING
);
return false;
}
} elseif (!$this->_testPermissions($directory, $chmod)) {
return false;
}

View File

@ -17,7 +17,7 @@ class HTMLPurifier_Filter_YouTube extends HTMLPurifier_Filter
public function preFilter($html, $config, $context)
{
$pre_regex = '#<object[^>]+>.+?' .
'http://www.youtube.com/((?:v|cp)/[A-Za-z0-9\-_=]+).+?</object>#s';
'(?:http:)?//www.youtube.com/((?:v|cp)/[A-Za-z0-9\-_=]+).+?</object>#s';
$pre_replace = '<span class="youtube-embed">\1</span>';
return preg_replace($pre_regex, $pre_replace, $html);
}
@ -51,10 +51,10 @@ class HTMLPurifier_Filter_YouTube extends HTMLPurifier_Filter
{
$url = $this->armorUrl($matches[1]);
return '<object width="425" height="350" type="application/x-shockwave-flash" ' .
'data="http://www.youtube.com/' . $url . '">' .
'<param name="movie" value="http://www.youtube.com/' . $url . '"></param>' .
'data="//www.youtube.com/' . $url . '">' .
'<param name="movie" value="//www.youtube.com/' . $url . '"></param>' .
'<!--[if IE]>' .
'<embed src="http://www.youtube.com/' . $url . '"' .
'<embed src="//www.youtube.com/' . $url . '"' .
'type="application/x-shockwave-flash"' .
'wmode="transparent" width="425" height="350" />' .
'<![endif]-->' .

View File

@ -1,4 +1,4 @@
<?php
if (!defined('HTMLPURIFIER_PREFIX')) {
define('HTMLPURIFIER_PREFIX', __DIR__);
define('HTMLPURIFIER_PREFIX', dirname(__FILE__));
}

View File

@ -7,7 +7,7 @@
* primary concern and you are using an opcode cache. PLEASE DO NOT EDIT THIS
* FILE, changes will be overwritten the next time the script is run.
*
* @version 4.6.0
* @version 4.7.0
*
* @warning
* You must *not* include any other HTML Purifier files before this file,

View File

@ -19,7 +19,7 @@
*/
/*
HTML Purifier 4.6.0 - Standards Compliant HTML Filtering
HTML Purifier 4.7.0 - Standards Compliant HTML Filtering
Copyright (C) 2006-2008 Edward Z. Yang
This library is free software; you can redistribute it and/or
@ -58,12 +58,12 @@ class HTMLPurifier
* Version of HTML Purifier.
* @type string
*/
public $version = '4.6.0';
public $version = '4.7.0';
/**
* Constant with version of HTML Purifier.
*/
const VERSION = '4.6.0';
const VERSION = '4.7.0';
/**
* Global configuration object.

View File

@ -44,7 +44,7 @@ class HTMLPurifier_AttrDef_CSS_Multiple extends HTMLPurifier_AttrDef
*/
public function validate($string, $config, $context)
{
$string = $this->parseCDATA($string);
$string = $this->mungeRgb($this->parseCDATA($string));
if ($string === '') {
return false;
}

View File

@ -32,9 +32,6 @@ class HTMLPurifier_AttrDef_HTML_Bool extends HTMLPurifier_AttrDef
*/
public function validate($string, $config, $context)
{
if (empty($string)) {
return false;
}
return $this->name;
}

View File

@ -350,8 +350,7 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
$this->info['scrollbar-highlight-color'] = new HTMLPurifier_AttrDef_CSS_Color();
$this->info['scrollbar-shadow-color'] = new HTMLPurifier_AttrDef_CSS_Color();
// technically not proprietary, but CSS3, and no one supports it
$this->info['opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue();
// vendor specific prefixes of opacity
$this->info['-moz-opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue();
$this->info['-khtml-opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue();
@ -404,6 +403,7 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
array('visible', 'hidden', 'collapse')
);
$this->info['overflow'] = new HTMLPurifier_AttrDef_Enum(array('visible', 'hidden', 'auto', 'scroll'));
$this->info['opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue();
}
/**

View File

@ -21,7 +21,7 @@ class HTMLPurifier_Config
* HTML Purifier's version
* @type string
*/
public $version = '4.6.0';
public $version = '4.7.0';
/**
* Whether or not to automatically finalize
@ -646,16 +646,25 @@ class HTMLPurifier_Config
return $this->getDefinition($name, true, true);
}
/**
* @return HTMLPurifier_HTMLDefinition
*/
public function maybeGetRawHTMLDefinition()
{
return $this->getDefinition('HTML', true, true);
}
/**
* @return HTMLPurifier_CSSDefinition
*/
public function maybeGetRawCSSDefinition()
{
return $this->getDefinition('CSS', true, true);
}
/**
* @return HTMLPurifier_URIDefinition
*/
public function maybeGetRawURIDefinition()
{
return $this->getDefinition('URI', true, true);

View File

@ -219,9 +219,15 @@ class HTMLPurifier_DefinitionCache_Serializer extends HTMLPurifier_DefinitionCac
} elseif (!$this->_testPermissions($base, $chmod)) {
return false;
}
$old = umask(0000);
mkdir($directory, $chmod);
umask($old);
if (!$this->_testPermissions($directory, $chmod)) {
trigger_error(
'Base directory ' . $base . ' does not exist,
please create or change using %Cache.SerializerPath',
E_USER_WARNING
);
return false;
}
} elseif (!$this->_testPermissions($directory, $chmod)) {
return false;
}

View File

@ -17,7 +17,7 @@ class HTMLPurifier_Filter_YouTube extends HTMLPurifier_Filter
public function preFilter($html, $config, $context)
{
$pre_regex = '#<object[^>]+>.+?' .
'http://www.youtube.com/((?:v|cp)/[A-Za-z0-9\-_=]+).+?</object>#s';
'(?:http:)?//www.youtube.com/((?:v|cp)/[A-Za-z0-9\-_=]+).+?</object>#s';
$pre_replace = '<span class="youtube-embed">\1</span>';
return preg_replace($pre_regex, $pre_replace, $html);
}
@ -51,10 +51,10 @@ class HTMLPurifier_Filter_YouTube extends HTMLPurifier_Filter
{
$url = $this->armorUrl($matches[1]);
return '<object width="425" height="350" type="application/x-shockwave-flash" ' .
'data="http://www.youtube.com/' . $url . '">' .
'<param name="movie" value="http://www.youtube.com/' . $url . '"></param>' .
'data="//www.youtube.com/' . $url . '">' .
'<param name="movie" value="//www.youtube.com/' . $url . '"></param>' .
'<!--[if IE]>' .
'<embed src="http://www.youtube.com/' . $url . '"' .
'<embed src="//www.youtube.com/' . $url . '"' .
'type="application/x-shockwave-flash"' .
'wmode="transparent" width="425" height="350" />' .
'<![endif]-->' .

View File

@ -28,10 +28,10 @@ class HTMLPurifier_Injector_RemoveEmpty extends HTMLPurifier_Injector
private $removeNbspExceptions;
/**
* Cached contents of %AutoFormat.RemoveEmpty.Predicate
* @type array
* TODO: make me configurable
*/
private $_exclude = array('colgroup' => 1, 'th' => 1, 'td' => 1, 'iframe' => 1);
private $exclude;
/**
* @param HTMLPurifier_Config $config
@ -45,6 +45,7 @@ class HTMLPurifier_Injector_RemoveEmpty extends HTMLPurifier_Injector
$this->context = $context;
$this->removeNbsp = $config->get('AutoFormat.RemoveEmpty.RemoveNbsp');
$this->removeNbspExceptions = $config->get('AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions');
$this->exclude = $config->get('AutoFormat.RemoveEmpty.Predicate');
$this->attrValidator = new HTMLPurifier_AttrValidator();
}
@ -75,11 +76,15 @@ class HTMLPurifier_Injector_RemoveEmpty extends HTMLPurifier_Injector
break;
}
if (!$next || ($next instanceof HTMLPurifier_Token_End && $next->name == $token->name)) {
if (isset($this->_exclude[$token->name])) {
return;
}
$this->attrValidator->validateToken($token, $this->config, $this->context);
$token->armor['ValidateAttributes'] = true;
if (isset($this->exclude[$token->name])) {
$r = true;
foreach ($this->exclude[$token->name] as $elem) {
if (!isset($token->attr[$elem])) $r = false;
}
if ($r) return;
}
if (isset($token->attr['id']) || isset($token->attr['name'])) {
return;
}

View File

@ -75,8 +75,7 @@ class HTMLPurifier_Lexer_DOMLex extends HTMLPurifier_Lexer
$tokens = array();
$this->tokenizeDOM(
$doc->getElementsByTagName('html')->item(0)-> // <html>
getElementsByTagName('body')->item(0)-> // <body>
getElementsByTagName('div')->item(0), // <div>
getElementsByTagName('body')->item(0), // <body>
$tokens
);
return $tokens;
@ -272,7 +271,7 @@ class HTMLPurifier_Lexer_DOMLex extends HTMLPurifier_Lexer
$ret .= '<html><head>';
$ret .= '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />';
// No protection if $html contains a stray </div>!
$ret .= '</head><body><div>' . $html . '</div></body></html>';
$ret .= '</head><body>' . $html . '</body></html>';
return $ret;
}
}

View File

@ -34,8 +34,7 @@ class HTMLPurifier_Lexer_PH5P extends HTMLPurifier_Lexer_DOMLex
$tokens = array();
$this->tokenizeDOM(
$doc->getElementsByTagName('html')->item(0)-> // <html>
getElementsByTagName('body')->item(0)-> // <body>
getElementsByTagName('div')->item(0) // <div>
getElementsByTagName('body')->item(0) // <body>
,
$tokens
);

View File

@ -28,10 +28,10 @@ class HTMLPurifier_Injector_RemoveEmpty extends HTMLPurifier_Injector
private $removeNbspExceptions;
/**
* Cached contents of %AutoFormat.RemoveEmpty.Predicate
* @type array
* TODO: make me configurable
*/
private $_exclude = array('colgroup' => 1, 'th' => 1, 'td' => 1, 'iframe' => 1);
private $exclude;
/**
* @param HTMLPurifier_Config $config
@ -45,6 +45,7 @@ class HTMLPurifier_Injector_RemoveEmpty extends HTMLPurifier_Injector
$this->context = $context;
$this->removeNbsp = $config->get('AutoFormat.RemoveEmpty.RemoveNbsp');
$this->removeNbspExceptions = $config->get('AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions');
$this->exclude = $config->get('AutoFormat.RemoveEmpty.Predicate');
$this->attrValidator = new HTMLPurifier_AttrValidator();
}
@ -75,11 +76,15 @@ class HTMLPurifier_Injector_RemoveEmpty extends HTMLPurifier_Injector
break;
}
if (!$next || ($next instanceof HTMLPurifier_Token_End && $next->name == $token->name)) {
if (isset($this->_exclude[$token->name])) {
return;
}
$this->attrValidator->validateToken($token, $this->config, $this->context);
$token->armor['ValidateAttributes'] = true;
if (isset($this->exclude[$token->name])) {
$r = true;
foreach ($this->exclude[$token->name] as $elem) {
if (!isset($token->attr[$elem])) $r = false;
}
if ($r) return;
}
if (isset($token->attr['id']) || isset($token->attr['name'])) {
return;
}

View File

@ -75,8 +75,7 @@ class HTMLPurifier_Lexer_DOMLex extends HTMLPurifier_Lexer
$tokens = array();
$this->tokenizeDOM(
$doc->getElementsByTagName('html')->item(0)-> // <html>
getElementsByTagName('body')->item(0)-> // <body>
getElementsByTagName('div')->item(0), // <div>
getElementsByTagName('body')->item(0), // <body>
$tokens
);
return $tokens;
@ -272,7 +271,7 @@ class HTMLPurifier_Lexer_DOMLex extends HTMLPurifier_Lexer
$ret .= '<html><head>';
$ret .= '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />';
// No protection if $html contains a stray </div>!
$ret .= '</head><body><div>' . $html . '</div></body></html>';
$ret .= '</head><body>' . $html . '</body></html>';
return $ret;
}
}

View File

@ -34,8 +34,7 @@ class HTMLPurifier_Lexer_PH5P extends HTMLPurifier_Lexer_DOMLex
$tokens = array();
$this->tokenizeDOM(
$doc->getElementsByTagName('html')->item(0)-> // <html>
getElementsByTagName('body')->item(0)-> // <body>
getElementsByTagName('div')->item(0) // <div>
getElementsByTagName('body')->item(0) // <body>
,
$tokens
);

View File

@ -1,5 +1,5 @@
curl https://codeload.github.com/ezyang/htmlpurifier/tar.gz/v4.6.0 -o htmlpurifier-4.6.0.tar.gz
tar xzf htmlpurifier-4.6.0.tar.gz --strip-components 1 htmlpurifier-4.6.0/LICENSE
tar xzf htmlpurifier-4.6.0.tar.gz --strip-components 2 htmlpurifier-4.6.0/library/*.php
tar xzf htmlpurifier-4.6.0.tar.gz --strip-components 3 htmlpurifier-4.6.0/library/HTMLPurifier/*
rm htmlpurifier-4.6.0.tar.gz
curl https://codeload.github.com/ezyang/htmlpurifier/tar.gz/v4.7.0 -o htmlpurifier-4.7.0.tar.gz
tar xzf htmlpurifier-4.7.0.tar.gz --strip-components 1 htmlpurifier-4.7.0/LICENSE
tar xzf htmlpurifier-4.7.0.tar.gz --strip-components 2 htmlpurifier-4.7.0/library/*.php
tar xzf htmlpurifier-4.7.0.tar.gz --strip-components 3 htmlpurifier-4.7.0/library/HTMLPurifier/*
rm htmlpurifier-4.7.0.tar.gz

View File

@ -222,7 +222,7 @@ class Minifier
default:
// check for some regex that breaks stuff
if ($this->a == '/' && ($this->b == '\'' || $this->b == '"')) {
if ($this->a === '/' && ($this->b === '\'' || $this->b === '"')) {
$this->saveRegex();
continue;
}
@ -311,10 +311,10 @@ class Minifier
$this->c = $this->getChar();
if ($this->c == '/') {
if ($this->c === '/') {
return $this->processOneLineComments($startIndex);
} elseif ($this->c == '*') {
} elseif ($this->c === '*') {
return $this->processMultiLineComments($startIndex);
}
@ -336,7 +336,7 @@ class Minifier
$this->getNext("\n");
if ($thirdCommentString == '@') {
$endPoint = ($this->index) - $startIndex;
$endPoint = $this->index - $startIndex;
unset($this->c);
$char = "\n" . substr($this->input, $startIndex, $endPoint);
} else {
@ -369,8 +369,8 @@ class Minifier
$char = $this->getChar(); // get next real character
// Now we reinsert conditional comments and YUI-style licensing comments
if (($this->options['flaggedComments'] && $thirdCommentString == '!')
|| ($thirdCommentString == '@') ) {
if (($this->options['flaggedComments'] && $thirdCommentString === '!')
|| ($thirdCommentString === '@') ) {
// If conditional comments or flagged comments are not the first thing in the script
// we need to echo a and fill it with a space before moving on.
@ -379,7 +379,7 @@ class Minifier
$this->a = " ";
// If the comment started on a new line we let it stay on the new line
if ($this->input[($startIndex - 1)] == "\n") {
if ($this->input[($startIndex - 1)] === "\n") {
echo "\n";
}
}
@ -444,7 +444,7 @@ class Minifier
$this->a = $this->b;
// If this isn't a string we don't need to do anything.
if ($this->a != "'" && $this->a != '"') {
if ($this->a !== "'" && $this->a !== '"') {
return;
}
@ -455,7 +455,7 @@ class Minifier
echo $this->a;
// Loop until the string is done
while (1) {
while (true) {
// Grab the very next character and load it into a
$this->a = $this->getChar();
@ -485,7 +485,7 @@ class Minifier
$this->b = $this->getChar();
// If b is a new line we discard a and b and restart the loop.
if ($this->b == "\n") {
if ($this->b === "\n") {
break;
}
@ -513,15 +513,15 @@ class Minifier
echo $this->a . $this->b;
while (($this->a = $this->getChar()) !== false) {
if($this->a == '/')
if($this->a === '/')
break;
if ($this->a == '\\') {
if ($this->a === '\\') {
echo $this->a;
$this->a = $this->getChar();
}
if($this->a == "\n")
if($this->a === "\n")
throw new \RuntimeException('Unclosed regex pattern at position: ' . $this->index);
echo $this->a;
@ -537,7 +537,7 @@ class Minifier
*/
protected static function isAlphaNumeric($char)
{
return preg_match('/^[\w\$]$/', $char) === 1 || $char == '/';
return preg_match('/^[\w\$\pL]$/', $char) === 1 || $char == '/';
}
/**
@ -552,14 +552,14 @@ class Minifier
$lock = '"LOCK---' . crc32(time()) . '"';
$matches = array();
preg_match('/([+-])(\s+)([+-])/', $js, $matches);
preg_match('/([+-])(\s+)([+-])/S', $js, $matches);
if (empty($matches)) {
return $js;
}
$this->locks[$lock] = $matches[2];
$js = preg_replace('/([+-])\s+([+-])/', "$1{$lock}$2", $js);
$js = preg_replace('/([+-])\s+([+-])/S', "$1{$lock}$2", $js);
/* -- */
return $js;
@ -573,7 +573,7 @@ class Minifier
*/
protected function unlock($js)
{
if (!count($this->locks)) {
if (empty($this->locks)) {
return $js;
}

View File

@ -1,4 +1,4 @@
curl https://codeload.github.com/tedious/JShrink/tar.gz/v1.0.1 -o JShrink-1.0.1.tar.gz
tar xzf JShrink-1.0.1.tar.gz --strip-components 1 JShrink-1.0.1/LICENSE
tar xzf JShrink-1.0.1.tar.gz --strip-components 3 JShrink-1.0.1/src/JShrink/Minifier.php
rm JShrink-1.0.1.tar.gz
curl https://codeload.github.com/tedious/JShrink/tar.gz/v1.1.0 -o JShrink-1.1.0.tar.gz
tar xzf JShrink-1.1.0.tar.gz --strip-components 1 JShrink-1.1.0/LICENSE
tar xzf JShrink-1.1.0.tar.gz --strip-components 3 JShrink-1.1.0/src/JShrink/Minifier.php
rm JShrink-1.1.0.tar.gz

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
RELEASE=1.0.0
FILENAME=parsedown-$RELEASE
DESTINATION=.
wget -O ${FILENAME}.tar.gz https://github.com/erusev/parsedown/archive/${RELEASE}.tar.gz
tar xfz ${FILENAME}.tar.gz -C $DESTINATION/ --strip-components 1 $FILENAME/Parsedown.php $FILENAME/LICENSE.txt
chmod 644 $DESTINATION/Parsedown.php
RELEASE=1.5.0
PARSEDOWN=parsedown-$RELEASE
curl https://codeload.github.com/erusev/parsedown/tar.gz/${RELEASE} -o ${PARSEDOWN}.tar.gz
tar xfz ${PARSEDOWN}.tar.gz --strip-components 1 ${PARSEDOWN}/Parsedown.php ${PARSEDOWN}/LICENSE.txt
chmod 0644 Parsedown.php
mv LICENSE.txt LICENSE
rm ${PARSEDOWN}.tar.gz

View File

@ -14,7 +14,7 @@
*
* @category Zend
* @package Zend_Acl
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id$
*/
@ -48,7 +48,7 @@
/**
* @category Zend
* @package Zend_Acl
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Acl

View File

@ -14,7 +14,7 @@
*
* @category Zend
* @package Zend_Acl
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id$
*/
@ -38,7 +38,7 @@
/**
* @category Zend
* @package Zend_Acl
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
interface Zend_Acl_Assert_Interface

View File

@ -14,7 +14,7 @@
*
* @category Zend
* @package Zend_Acl
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id$
*/
@ -28,7 +28,7 @@
/**
* @category Zend
* @package Zend_Acl
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Acl_Exception extends Zend_Exception

View File

@ -14,7 +14,7 @@
*
* @category Zend
* @package Zend_Acl
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id$
*/
@ -28,7 +28,7 @@
/**
* @category Zend
* @package Zend_Acl
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Acl_Resource implements Zend_Acl_Resource_Interface

View File

@ -14,7 +14,7 @@
*
* @category Zend
* @package Zend_Acl
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id$
*/
@ -23,7 +23,7 @@
/**
* @category Zend
* @package Zend_Acl
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
interface Zend_Acl_Resource_Interface

View File

@ -14,7 +14,7 @@
*
* @category Zend
* @package Zend_Acl
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id$
*/
@ -28,7 +28,7 @@
/**
* @category Zend
* @package Zend_Acl
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Acl_Role implements Zend_Acl_Role_Interface

View File

@ -14,7 +14,7 @@
*
* @category Zend
* @package Zend_Acl
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id$
*/
@ -23,7 +23,7 @@
/**
* @category Zend
* @package Zend_Acl
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
interface Zend_Acl_Role_Interface

View File

@ -14,7 +14,7 @@
*
* @category Zend
* @package Zend_Acl
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id$
*/
@ -28,7 +28,7 @@
/**
* @category Zend
* @package Zend_Acl
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Acl_Role_Registry

View File

@ -14,7 +14,7 @@
*
* @category Zend
* @package Zend_Acl
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id$
*/
@ -28,7 +28,7 @@
/**
* @category Zend
* @package Zend_Acl
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Acl_Role_Registry_Exception extends Zend_Acl_Exception

View File

@ -1,131 +0,0 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* 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 license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Amf
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id$
*/
/** @see Zend_Amf_Auth_Abstract */
/** @see Zend_Acl */
/** @see Zend_Auth_Result */
/** @see Zend_Xml_Security */
/**
* This class implements authentication against XML file with roles for Flex Builder.
*
* @package Zend_Amf
* @subpackage Adobe
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Amf_Adobe_Auth extends Zend_Amf_Auth_Abstract
{
/**
* ACL for authorization
*
* @var Zend_Acl
*/
protected $_acl;
/**
* Username/password array
*
* @var array
*/
protected $_users = array();
/**
* Create auth adapter
*
* @param string $rolefile File containing XML with users and roles
*/
public function __construct($rolefile)
{
$this->_acl = new Zend_Acl();
$xml = Zend_Xml_Security::scanFile($rolefile);
/*
Roles file format:
<roles>
<role id=”admin”>
<user name=”user1” password=”pwd”/>
</role>
<role id=”hr”>
<user name=”user2” password=”pwd2”/>
</role>
</roles>
*/
foreach($xml->role as $role) {
$this->_acl->addRole(new Zend_Acl_Role((string)$role["id"]));
foreach($role->user as $user) {
$this->_users[(string)$user["name"]] = array("password" => (string)$user["password"],
"role" => (string)$role["id"]);
}
}
}
/**
* Get ACL with roles from XML file
*
* @return Zend_Acl
*/
public function getAcl()
{
return $this->_acl;
}
/**
* Perform authentication
*
* @throws Zend_Auth_Adapter_Exception
* @return Zend_Auth_Result
* @see Zend_Auth_Adapter_Interface#authenticate()
*/
public function authenticate()
{
if (empty($this->_username) ||
empty($this->_password)) {
/**
* @see Zend_Auth_Adapter_Exception
*/
throw new Zend_Auth_Adapter_Exception('Username/password should be set');
}
if(!isset($this->_users[$this->_username])) {
return new Zend_Auth_Result(Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND,
null,
array('Username not found')
);
}
$user = $this->_users[$this->_username];
if($user["password"] != $this->_password) {
return new Zend_Auth_Result(Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID,
null,
array('Authentication failed')
);
}
$id = new stdClass();
$id->role = $user["role"];
$id->name = $this->_username;
return new Zend_Auth_Result(Zend_Auth_Result::SUCCESS, $id);
}
}

View File

@ -1,103 +0,0 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* 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 license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Amf
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id$
*/
/**
* This class implements authentication against XML file with roles for Flex Builder.
*
* @package Zend_Amf
* @subpackage Adobe
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Amf_Adobe_DbInspector
{
/**
* Connect to the database
*
* @param string $dbType Database adapter type for Zend_Db
* @param array|object $dbDescription Adapter-specific connection settings
* @return Zend_Db_Adapter_Abstract
* @see Zend_Db::factory()
*/
protected function _connect($dbType, $dbDescription)
{
if(is_object($dbDescription)) {
$dbDescription = get_object_vars($dbDescription);
}
return Zend_Db::factory($dbType, $dbDescription);
}
/**
* Describe database object.
*
* Usage example:
* $inspector->describeTable('Pdo_Mysql',
* array(
* 'host' => '127.0.0.1',
* 'username' => 'webuser',
* 'password' => 'xxxxxxxx',
* 'dbname' => 'test'
* ),
* 'mytable'
* );
*
* @param string $dbType Database adapter type for Zend_Db
* @param array|object $dbDescription Adapter-specific connection settings
* @param string $tableName Table name
* @return array Table description
* @see Zend_Db::describeTable()
* @see Zend_Db::factory()
*/
public function describeTable($dbType, $dbDescription, $tableName)
{
$db = $this->_connect($dbType, $dbDescription);
return $db->describeTable($tableName);
}
/**
* Test database connection
*
* @param string $dbType Database adapter type for Zend_Db
* @param array|object $dbDescription Adapter-specific connection settings
* @return bool
* @see Zend_Db::factory()
*/
public function connect($dbType, $dbDescription)
{
$db = $this->_connect($dbType, $dbDescription);
$db->listTables();
return true;
}
/**
* Get the list of database tables
*
* @param string $dbType Database adapter type for Zend_Db
* @param array|object $dbDescription Adapter-specific connection settings
* @return array List of the tables
*/
public function getTables($dbType, $dbDescription)
{
$db = $this->_connect($dbType, $dbDescription);
return $db->listTables();
}
}

View File

@ -1,314 +0,0 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* 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 license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Amf
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id$
*/
/** @see Zend_Amf_Parse_TypeLoader */
/** @see Zend_Reflection_Class */
/** @see Zend_Server_Reflection */
/**
* This class implements a service for generating AMF service descriptions as XML.
*
* @package Zend_Amf
* @subpackage Adobe
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Amf_Adobe_Introspector
{
/**
* Options used:
* - server: instance of Zend_Amf_Server to use
* - directories: directories where class files may be looked up
*
* @var array Introspector options
*/
protected $_options;
/**
* @var DOMElement DOM element to store types
*/
protected $_types;
/**
* @var array Map of the known types
*/
protected $_typesMap = array();
/**
* @var DOMDocument XML document to store data
*/
protected $_xml;
/**
* Constructor
*
* @return void
*/
public function __construct()
{
$this->_xml = new DOMDocument('1.0', 'utf-8');
}
/**
* Create XML definition on an AMF service class
*
* @param string $serviceClass Service class name
* @param array $options invocation options
* @return string XML with service class introspection
*/
public function introspect($serviceClass, $options = array())
{
$this->_options = $options;
if (strpbrk($serviceClass, '\\/<>')) {
return $this->_returnError('Invalid service name');
}
// Transform com.foo.Bar into com_foo_Bar
$serviceClass = str_replace('.' , '_', $serviceClass);
// Introspect!
if (!class_exists($serviceClass)) {
Zend_Loader::loadClass($serviceClass, $this->_getServicePath());
}
$serv = $this->_xml->createElement('service-description');
$serv->setAttribute('xmlns', 'http://ns.adobe.com/flex/service-description/2008');
$this->_types = $this->_xml->createElement('types');
$this->_ops = $this->_xml->createElement('operations');
$r = Zend_Server_Reflection::reflectClass($serviceClass);
$this->_addService($r, $this->_ops);
$serv->appendChild($this->_types);
$serv->appendChild($this->_ops);
$this->_xml->appendChild($serv);
return $this->_xml->saveXML();
}
/**
* Authentication handler
*
* @param Zend_Acl $acl
* @return unknown_type
*/
public function initAcl(Zend_Acl $acl)
{
return false; // we do not need auth for this class
}
/**
* Generate map of public class attributes
*
* @param string $typename type name
* @param DOMElement $typexml target XML element
* @return void
*/
protected function _addClassAttributes($typename, DOMElement $typexml)
{
// Do not try to autoload here because _phpTypeToAS should
// have already attempted to load this class
if (!class_exists($typename, false)) {
return;
}
$rc = new Zend_Reflection_Class($typename);
foreach ($rc->getProperties() as $prop) {
if (!$prop->isPublic()) {
continue;
}
$propxml = $this->_xml->createElement('property');
$propxml->setAttribute('name', $prop->getName());
$type = $this->_registerType($this->_getPropertyType($prop));
$propxml->setAttribute('type', $type);
$typexml->appendChild($propxml);
}
}
/**
* Build XML service description from reflection class
*
* @param Zend_Server_Reflection_Class $refclass
* @param DOMElement $target target XML element
* @return void
*/
protected function _addService(Zend_Server_Reflection_Class $refclass, DOMElement $target)
{
foreach ($refclass->getMethods() as $method) {
if (!$method->isPublic()
|| $method->isConstructor()
|| ('__' == substr($method->name, 0, 2))
) {
continue;
}
foreach ($method->getPrototypes() as $proto) {
$op = $this->_xml->createElement('operation');
$op->setAttribute('name', $method->getName());
$rettype = $this->_registerType($proto->getReturnType());
$op->setAttribute('returnType', $rettype);
foreach ($proto->getParameters() as $param) {
$arg = $this->_xml->createElement('argument');
$arg->setAttribute('name', $param->getName());
$type = $param->getType();
if ($type == 'mixed' && ($pclass = $param->getClass())) {
$type = $pclass->getName();
}
$ptype = $this->_registerType($type);
$arg->setAttribute('type', $ptype);
if($param->isDefaultValueAvailable()) {
$arg->setAttribute('defaultvalue', $param->getDefaultValue());
}
$op->appendChild($arg);
}
$target->appendChild($op);
}
}
}
/**
* Extract type of the property from DocBlock
*
* @param Zend_Reflection_Property $prop reflection property object
* @return string Property type
*/
protected function _getPropertyType(Zend_Reflection_Property $prop)
{
$docBlock = $prop->getDocComment();
if (!$docBlock) {
return 'Unknown';
}
if (!$docBlock->hasTag('var')) {
return 'Unknown';
}
$tag = $docBlock->getTag('var');
return trim($tag->getDescription());
}
/**
* Get the array of service directories
*
* @return array Service class directories
*/
protected function _getServicePath()
{
if (isset($this->_options['server'])) {
return $this->_options['server']->getDirectory();
}
if (isset($this->_options['directories'])) {
return $this->_options['directories'];
}
return array();
}
/**
* Map from PHP type name to AS type name
*
* @param string $typename PHP type name
* @return string AS type name
*/
protected function _phpTypeToAS($typename)
{
if (class_exists($typename)) {
$vars = get_class_vars($typename);
if (isset($vars['_explicitType'])) {
return $vars['_explicitType'];
}
}
if (false !== ($asname = Zend_Amf_Parse_TypeLoader::getMappedClassName($typename))) {
return $asname;
}
return $typename;
}
/**
* Register new type on the system
*
* @param string $typename type name
* @return string New type name
*/
protected function _registerType($typename)
{
// Known type - return its AS name
if (isset($this->_typesMap[$typename])) {
return $this->_typesMap[$typename];
}
// Standard types
if (in_array($typename, array('void', 'null', 'mixed', 'unknown_type'))) {
return 'Unknown';
}
// Arrays
if ('array' == $typename) {
return 'Unknown[]';
}
if (in_array($typename, array('int', 'integer', 'bool', 'boolean', 'float', 'string', 'object', 'Unknown', 'stdClass'))) {
return $typename;
}
// Resolve and store AS name
$asTypeName = $this->_phpTypeToAS($typename);
$this->_typesMap[$typename] = $asTypeName;
// Create element for the name
$typeEl = $this->_xml->createElement('type');
$typeEl->setAttribute('name', $asTypeName);
$this->_addClassAttributes($typename, $typeEl);
$this->_types->appendChild($typeEl);
return $asTypeName;
}
/**
* Return error with error message
*
* @param string $msg Error message
* @return string
*/
protected function _returnError($msg)
{
return 'ERROR: $msg';
}
}

Some files were not shown because too many files have changed in this diff Show More