Commit a8d45429 authored by alexpott's avatar alexpott
Browse files

Issue #2012312 by tim.plunkett: Remove legacy code from filter.module.

parent 9d5cb43e
......@@ -53,7 +53,7 @@ function setUp() {
// text format.
$this->adminUser = $this->drupalCreateUser(array(
'administer blocks',
filter_permission_name($full_html_format),
$full_html_format->getPermissionName(),
'access administration pages',
));
$this->drupalLogin($this->adminUser);
......
......@@ -47,7 +47,7 @@ function hook_ckeditor_plugin_info_alter(array &$plugins) {
* @param $editor
* The text editor object as returned by editor_load(), for which these files
* are being loaded. Based on this information, it is possible to load the
* corresponding text format object as returned by filter_format_load().
* corresponding text format object.
*
* @see _ckeditor_theme_css()
*/
......
......@@ -7,15 +7,17 @@ editor_field_untransformed_text:
requirements:
_permission: 'access in-place editing'
_access_edit_entity_field: 'TRUE'
editor_image_dialog:
pattern: '/editor/dialog/image/{filter_format}'
defaults:
_form: '\Drupal\editor\Form\EditorImageDialog'
requirements:
_filter_access: 'TRUE'
_entity_access: 'filter_format.view'
editor_link_dialog:
pattern: '/editor/dialog/link/{filter_format}'
defaults:
_form: '\Drupal\editor\Form\EditorLinkDialog'
requirements:
_filter_access: 'TRUE'
_entity_access: 'filter_format.view'
......@@ -71,7 +71,7 @@ public function id() {
* Overrides Drupal\Core\Entity\Entity::label().
*/
public function label($langcode = NULL) {
$format = filter_format_load($this->format);
$format = entity_load('filter_format', $this->format);
return $format->name;
}
......
......@@ -5,10 +5,12 @@
* Framework for handling the filtering of content.
*/
use Drupal\Component\Utility\String;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Language\Language;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Template\Attribute;
use Drupal\filter\Entity\FilterFormat;
use Drupal\filter\FilterFormatInterface;
/**
* Non-HTML markup language filters that generate HTML.
......@@ -125,7 +127,7 @@ function filter_menu() {
'type' => MENU_SUGGESTED_ITEM,
'route_name' => 'filter_tips_all',
);
$items['filter/tips/%filter_format'] = array(
$items['filter/tips/%'] = array(
'title' => 'Compose tips',
'route_name' => 'filter_tips',
);
......@@ -154,43 +156,6 @@ function filter_menu() {
return $items;
}
/**
* Loads a text format object from the database.
*
* @param $format_id
* The format ID.
*
* @return
* A fully-populated text format object, if the requested format exists and
* is enabled. If the format does not exist, or exists in the database but
* has been marked as disabled, NULL is returned.
*
* @see filter_format_exists()
*
* @todo Use entity_load().
*/
function filter_format_load($format_id) {
$formats = filter_formats();
return isset($formats[$format_id]) ? $formats[$format_id] : NULL;
}
/**
* Determines if a text format exists.
*
* @param $format_id
* The ID of the text format to check.
*
* @return
* TRUE if the text format exists, FALSE otherwise. Note that for disabled
* formats filter_format_exists() will return TRUE while filter_format_load()
* will return FALSE.
*
* @see filter_format_load()
*/
function filter_format_exists($format_id) {
return entity_load('filter_format', $format_id);
}
/**
* Implements hook_permission().
*/
......@@ -206,14 +171,11 @@ function filter_permission() {
// Generate permissions for each text format. Warn the administrator that any
// of them are potentially unsafe.
foreach (filter_formats() as $format) {
$permission = filter_permission_name($format);
if (!empty($permission)) {
// Only link to the text format configuration page if the user who is
// viewing this will have access to that page.
$format_name_replacement = user_access('administer filters') ? l($format->name, 'admin/config/content/formats/manage/' . $format->format) : drupal_placeholder($format->name);
if ($permission = $format->getPermissionName()) {
$format_name_replacement = l($format->label(), 'admin/config/content/formats/manage/' . $format->id());
$perms[$permission] = array(
'title' => t("Use the !text_format text format", array('!text_format' => $format_name_replacement,)),
'description' => drupal_placeholder(t('Warning: This permission may have security implications depending on how the text format is configured.')),
'description' => String::placeholder(t('Warning: This permission may have security implications depending on how the text format is configured.')),
);
}
}
......@@ -221,70 +183,52 @@ function filter_permission() {
}
/**
* Returns the machine-readable permission name for a provided text format.
* Retrieves a list of enabled text formats, ordered by weight.
*
* @param $format
* An object representing a text format.
*
* @return
* The machine-readable permission name, or FALSE if the provided text format
* is malformed or is the fallback format (which is available to all users).
*/
function filter_permission_name($format) {
if (isset($format->format) && $format->format != filter_fallback_format()) {
return 'use text format ' . $format->format;
}
return FALSE;
}
/**
* Retrieves a list of text formats, ordered by weight.
*
* @param $account
* @param \Drupal\Core\Session\AccountInterface|null $account
* (optional) If provided, only those formats that are allowed for this user
* account will be returned. All formats will be returned otherwise. Defaults
* to NULL.
* account will be returned. All enabled formats will be returned otherwise.
* Defaults to NULL.
*
* @return
* @return \Drupal\filter\FilterFormatInterface[]
* An array of text format objects, keyed by the format ID and ordered by
* weight.
*
* @see filter_formats_reset()
*/
function filter_formats($account = NULL) {
$language_interface = language(Language::TYPE_INTERFACE);
function filter_formats(AccountInterface $account = NULL) {
$formats = &drupal_static(__FUNCTION__, array());
// All available formats are cached for performance.
if (!isset($formats['all'])) {
if ($cache = cache()->get("filter_formats:{$language_interface->id}")) {
$language_interface = Drupal::languageManager()->getLanguage(Language::TYPE_INTERFACE);
if ($cache = Drupal::cache()->get("filter_formats:{$language_interface->id}")) {
$formats['all'] = $cache->data;
}
else {
$filter_formats = entity_load_multiple('filter_format');
$formats['all'] = array();
foreach ($filter_formats as $format_name => $filter_format) {
if ($filter_format->status()) {
$formats['all'][$format_name] = $filter_format;
}
}
$formats['all'] = Drupal::entityManager()->getStorageController('filter_format')->loadByProperties(array('status' => '1'));
uasort($formats['all'], 'Drupal\Core\Config\Entity\ConfigEntityBase::sort');
cache()->set("filter_formats:{$language_interface->id}", $formats['all'], CacheBackendInterface::CACHE_PERMANENT, array('filter_formats' => TRUE));
Drupal::cache()->set("filter_formats:{$language_interface->id}", $formats['all'], CacheBackendInterface::CACHE_PERMANENT, array('filter_formats' => TRUE));
}
}
// If no user was specified, return all formats.
if (!isset($account)) {
return $formats['all'];
}
// Build a list of user-specific formats.
if (isset($account) && !isset($formats['user'][$account->id()])) {
$formats['user'][$account->id()] = array();
$account_id = $account->id();
if (!isset($formats['user'][$account_id])) {
$formats['user'][$account_id] = array();
foreach ($formats['all'] as $format) {
if (filter_access($format, $account)) {
$formats['user'][$account->id()][$format->format] = $format;
if ($format->access('view', $account)) {
$formats['user'][$account_id][$format->format] = $format;
}
}
}
return isset($account) ? $formats['user'][$account->id()] : $formats['all'];
return $formats['user'][$account_id];
}
/**
......@@ -294,27 +238,25 @@ function filter_formats($account = NULL) {
*/
function filter_formats_reset() {
cache()->deleteTags(array('filter_formats' => TRUE));
cache()->delete('filter_list_format');
drupal_static_reset('filter_list_format');
drupal_static_reset('filter_formats');
}
/**
* Retrieves a list of roles that are allowed to use a given text format.
*
* @param $format
* @param \Drupal\filter\FilterFormatInterface $format
* An object representing the text format.
*
* @return
* @return array
* An array of role names, keyed by role ID.
*/
function filter_get_roles_by_format($format) {
function filter_get_roles_by_format(FilterFormatInterface $format) {
// Handle the fallback format upfront (all roles have access to this format).
if ($format->format == filter_fallback_format()) {
if ($format->isFallbackFormat()) {
return user_role_names();
}
// Do not list any roles if the permission does not exist.
$permission = filter_permission_name($format);
$permission = $format->getPermissionName();
return !empty($permission) ? user_role_names(FALSE, $permission) : array();
}
......@@ -324,7 +266,7 @@ function filter_get_roles_by_format($format) {
* @param $rid
* The user role ID to retrieve text formats for.
*
* @return
* @return \Drupal\filter\FilterFormatInterface[]
* An array of text format objects that are allowed for the role, keyed by
* the text format ID and ordered by weight.
*/
......@@ -333,7 +275,7 @@ function filter_get_formats_by_role($rid) {
foreach (filter_formats() as $format) {
$roles = filter_get_roles_by_format($format);
if (isset($roles[$rid])) {
$formats[$format->format] = $format;
$formats[$format->id()] = $format;
}
}
return $formats;
......@@ -355,16 +297,16 @@ function filter_get_formats_by_role($rid) {
* returned by filter_fallback_format() should be used, since that is intended
* to be a safe, consistent format that is always available to all users.
*
* @param $account
* @param \Drupal\Core\Session\AccountInterface|null $account
* (optional) The user account to check. Defaults to the currently logged-in
* user. Defaults to NULL.
*
* @return
* @return string
* The ID of the user's default text format.
*
* @see filter_fallback_format()
*/
function filter_default_format($account = NULL) {
function filter_default_format(AccountInterface $account = NULL) {
global $user;
if (!isset($account)) {
$account = $user;
......@@ -390,10 +332,12 @@ function filter_default_format($account = NULL) {
function filter_get_filter_types_by_format($format_id) {
$filter_types = array();
$filters = filter_list_format($format_id);
foreach ($filters as $filter) {
if ($filter->status) {
$filter_types[] = $filter->getType();
if ($format_id) {
$filters = entity_load('filter_format', $format_id)->filters();
foreach ($filters as $filter) {
if ($filter->status) {
$filter_types[] = $filter->getType();
}
}
}
......@@ -420,7 +364,7 @@ function filter_get_filter_types_by_format($format_id) {
* FALSE means there are no HTML restrictions.
*/
function filter_get_html_restrictions_by_format($format_id) {
$format = filter_format_load($format_id);
$format = entity_load('filter_format', $format_id);
// Ignore filters that are disabled or don't have HTML restrictions.
$filters = array_filter($format->filters()->getAll(), function($filter) {
......@@ -594,69 +538,23 @@ function filter_fallback_format() {
* process can be cached. A text format may allow caching depending on the
* filters enabled.
*
* @param $format_id
* @param string $format_id
* The text format ID to check.
*
* @return
* @return bool
* TRUE if the given text format allows caching, FALSE otherwise.
*/
function filter_format_allowcache($format_id) {
$format = filter_format_load($format_id);
$format = $format_id ? entity_load('filter_format', $format_id) : FALSE;
return !empty($format->cache);
}
/**
* Retrieves a list of filters for a given text format.
*
* Note that this function returns all associated filters regardless of whether
* they are enabled or disabled. All functions working with the filter
* information outside of filter administration should test for $filter->status
* before performing actions with the filter.
*
* @param $format_id
* The format ID to retrieve filters for.
*
* @return
* An array of filter objects associated to the given text format, keyed by
* filter name.
*
* @todo Change this function to only return enabled filters. Code that needs to
* access disabled filters is not regular runtime code and thus can work with
* the FilterFormat::filters().
*/
function filter_list_format($format_id) {
$filters = &drupal_static(__FUNCTION__, array());
if (!isset($filters['all'])) {
if ($cache = cache()->get('filter_list_format')) {
$filters['all'] = $cache->data;
}
else {
$filters['all'] = array();
$filter_formats = filter_formats();
foreach ($filter_formats as $filter_format) {
// This loop must not instantiate the actual filter plugins, since the
// filter bag would be duplicated for each filter plugin instance upon
// unserialization of the cache item.
$filters['all'][$filter_format->id()] = $filter_format->filters();
}
cache()->set('filter_list_format', $filters['all']);
}
}
if (!isset($filters[$format_id]) && isset($filters['all'][$format_id])) {
$filters[$format_id] = $filters['all'][$format_id];
}
return isset($filters[$format_id]) ? $filters[$format_id] : array();
}
/**
* Runs all the enabled filters on a piece of text.
*
* Note: Because filters can inject JavaScript or execute PHP code, security is
* vital here. When a user supplies a text format, you should validate it using
* filter_access() before accepting/using it. This is normally done in the
* $format->access() before accepting/using it. This is normally done in the
* validation stage of the Form API. You should for example never make a
* preview of content in a disallowed format.
*
......@@ -690,7 +588,7 @@ function check_markup($text, $format_id = NULL, $langcode = '', $cache = FALSE,
$format_id = filter_fallback_format();
}
// If the requested text format does not exist, the text cannot be filtered.
if (!$format = filter_format_load($format_id)) {
if (!$format = entity_load('filter_format', $format_id)) {
watchdog('filter', 'Missing text format: %format.', array('%format' => $format_id), WATCHDOG_ALERT);
return '';
}
......@@ -720,7 +618,7 @@ function check_markup($text, $format_id = NULL, $langcode = '', $cache = FALSE,
$text = str_replace(array("\r\n", "\r"), "\n", $text);
// Get a complete list of filters, ordered properly.
$filters = filter_list_format($format->format);
$filters = $format->filters();
// Give filters the chance to escape HTML-like data such as code or formulas.
foreach ($filters as $filter) {
......@@ -749,7 +647,7 @@ function check_markup($text, $format_id = NULL, $langcode = '', $cache = FALSE,
// automatically flushed when the text format is updated.
// @see \Drupal\filter\Entity\FilterFormat::save()
if ($cache) {
cache('filter')->set($cache_id, $text, CacheBackendInterface::CACHE_PERMANENT, array('filter_format' => $format->format));
cache('filter')->set($cache_id, $text, CacheBackendInterface::CACHE_PERMANENT, array('filter_format' => $format->id()));
}
return $text;
......@@ -852,9 +750,10 @@ function filter_process_format($element) {
'#attributes' => array('class' => array('filter-guidelines')),
'#weight' => 20,
);
$options = array();
foreach ($formats as $format) {
$options[$format->format] = $format->name;
$element['format']['guidelines'][$format->format] = array(
$options[$format->id()] = $format->label();
$element['format']['guidelines'][$format->id()] = array(
'#theme' => 'filter_guidelines',
'#format' => $format,
);
......@@ -961,45 +860,17 @@ function theme_text_format_wrapper($variables) {
return $output;
}
/**
* Checks if a user has access to a particular text format.
*
* @param $format
* An object representing the text format.
* @param $account
* (optional) The user account to check access for; if omitted, the currently
* logged-in user is used. Defaults to NULL.
*
* @return
* Boolean TRUE if the user is allowed to access the given format.
*/
function filter_access($format, $account = NULL) {
global $user;
if (!isset($account)) {
$account = $user;
}
// Handle special cases up front. All users have access to the fallback
// format.
if ($format->format == filter_fallback_format()) {
return TRUE;
}
// Check the permission if one exists; otherwise, we have a non-existent
// format so we return FALSE.
$permission = filter_permission_name($format);
return !empty($permission) && user_access($permission, $account);
}
/**
* Retrieves the filter tips.
*
* @param $format_id
* @param string $format_id
* The ID of the text format for which to retrieve tips, or -1 to return tips
* for all formats accessible to the current user.
* @param $long
* @param bool $long
* (optional) Boolean indicating whether the long form of tips should be
* returned. Defaults to FALSE.
*
* @return
* @return array
* An associative array of filtering tips, keyed by filter name. Each
* filtering tip is an associative array with elements:
* - tip: Tip text.
......@@ -1018,12 +889,11 @@ function _filter_tips($format_id, $long = FALSE) {
}
foreach ($formats as $format) {
$filters = filter_list_format($format->format);
foreach ($filters as $name => $filter) {
foreach ($format->filters() as $name => $filter) {
if ($filter->status) {
$tip = $filter->tips($long);
if (isset($tip)) {
$tips[$format->name][$name] = array('tip' => $tip, 'id' => $name);
$tips[$format->label()][$name] = array('tip' => $tip, 'id' => $name);
}
}
}
......
......@@ -10,7 +10,7 @@ filter_tips:
defaults:
_content: '\Drupal\filter\Controller\FilterController::filterTips'
requirements:
_filter_access: 'TRUE'
_entity_access: 'filter_format.view'
filter_admin_overview:
pattern: '/admin/config/content/formats'
......@@ -38,5 +38,8 @@ filter_admin_disable:
pattern: '/admin/config/content/formats/manage/{filter_format}/disable'
defaults:
_entity_form: 'filter_format.disable'
options:
_access_mode: 'ALL'
requirements:
_filter_disable_format_access: 'TRUE'
_permission: 'administer filters'
......@@ -10,10 +10,6 @@ services:
class: Drupal\filter\Access\FormatDisableCheck
tags:
- { name: access_check }
access_check.filter_access:
class: Drupal\filter\Access\FilterAccessCheck
tags:
- { name: access_check }
plugin.manager.filter:
class: Drupal\filter\FilterPluginManager
arguments: ['@container.namespaces', '@cache.cache', '@language_manager', '@module_handler']
<?php
/**
* @file
* Contains \Drupal\filter\Access\FilterAccessCheck.
*/
namespace Drupal\filter\Access;
use Drupal\Core\Access\StaticAccessCheckInterface;
use Symfony\Component\Routing\Route;
use Symfony\Component\HttpFoundation\Request;
/**
* Checks access for text formats.
*/
class FilterAccessCheck implements StaticAccessCheckInterface {
/**
* {@inheritdoc}
*/
public function appliesTo() {
return array('_filter_access');
}
/**
* {@inheritdoc}
*/
public function access(Route $route, Request $request) {
if ($format = $request->attributes->get('filter_format')) {
// Handle special cases up front. All users have access to the fallback
// format.
if ($format->format == filter_fallback_format()) {
return static::ALLOW;
}
// Check the permission if one exists; otherwise, we have a non-existent
// format so we return FALSE.
$permission = filter_permission_name($format);
return !empty($permission) && user_access($permission) ? static::ALLOW : static::DENY;
}
}
}
......@@ -24,14 +24,11 @@ public function appliesTo() {
}
/**
* Implements \Drupal\Core\Access\AccessCheckInterface::access().
* {@inheritdoc}
*/
public function access(Route $route, Request $request) {
if ($format = $request->attributes->get('filter_format')) {
return (user_access('administer filters') && ($format->format != filter_fallback_format())) ? static::ALLOW : static::DENY;
}
return static::DENY;
$format = $request->attributes->get('filter_format');
return ($format && !$format->isFallbackFormat()) ? static::ALLOW : static::DENY;
}
}
......@@ -239,7 +239,7 @@ public function postSave(EntityStorageControllerInterface $storage_controller, $
// Note: user_role_change_permissions() triggers a call chain back into
// filter_permission() and lastly filter_formats(), so its cache must be
// reset upfront.
if (($roles = $this->get('roles')) && $permission = filter_permission_name($this)) {
if (($roles = $this->get('roles')) && $permission = $this->getPermissionName()) {
foreach (user_roles() as $rid => $name) {
$enabled = in_array($rid, $roles, TRUE);
user_role_change_permissions($rid, array($permission => $enabled));
......@@ -261,4 +261,11 @@ public function isFallbackFormat() {
return $this->id() == $fallback_format;
}
/**
* {@inheritdoc}
*/
public function getPermissionName() {
return !$this->isFallbackFormat() ? 'use text format ' . $this->id() : FALSE;
}
}
......@@ -26,21 +26,21 @@ protected function checkAccess(EntityInterface $entity, $operation, $langcode, A
return TRUE;
}