Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
project
drupal
Commits
4e9a8851
Commit
4e9a8851
authored
Mar 25, 2014
by
catch
Browse files
Issue
#2204239
by damiankloip, Sutharsan: Simplify and de-duplicate argument validators.
parent
1c22cf66
Changes
8
Hide whitespace changes
Inline
Side-by-side
core/modules/node/lib/Drupal/node/Plugin/views/argument_validator/Node.php
deleted
100644 → 0
View file @
1c22cf66
<?php
/**
* @file
* Definition of Drupal\node\Plugin\views\argument_validator\Node.
*/
namespace
Drupal\node\Plugin\views\argument_validator
;
use
Drupal\views\Plugin\views\argument_validator
\
ArgumentValidatorPluginBase
;
/**
* Validate whether an argument is an acceptable node.
*
* @ViewsArgumentValidator(
* id = "node",
* title = @Translation("Content")
* )
*/
class
Node
extends
ArgumentValidatorPluginBase
{
protected
function
defineOptions
()
{
$options
=
parent
::
defineOptions
();
$options
[
'types'
]
=
array
(
'default'
=>
array
());
$options
[
'access'
]
=
array
(
'default'
=>
FALSE
,
'bool'
=>
TRUE
);
$options
[
'access_op'
]
=
array
(
'default'
=>
'view'
);
$options
[
'nid_type'
]
=
array
(
'default'
=>
'nid'
);
return
$options
;
}
public
function
buildOptionsForm
(
&
$form
,
&
$form_state
)
{
$types
=
node_type_get_types
();
$options
=
array
();
foreach
(
$types
as
$type
=>
$info
)
{
$options
[
$type
]
=
check_plain
(
t
(
$info
->
name
));
}
$form
[
'types'
]
=
array
(
'#type'
=>
'checkboxes'
,
'#title'
=>
t
(
'Content types'
),
'#options'
=>
$options
,
'#default_value'
=>
$this
->
options
[
'types'
],
'#description'
=>
t
(
'Choose one or more content types to validate with.'
),
);
$form
[
'access'
]
=
array
(
'#type'
=>
'checkbox'
,
'#title'
=>
t
(
'Validate user has access to the content'
),
'#default_value'
=>
$this
->
options
[
'access'
],
);
$form
[
'access_op'
]
=
array
(
'#type'
=>
'radios'
,
'#title'
=>
t
(
'Access operation to check'
),
'#options'
=>
array
(
'view'
=>
t
(
'View'
),
'update'
=>
t
(
'Edit'
),
'delete'
=>
t
(
'Delete'
)),
'#default_value'
=>
$this
->
options
[
'access_op'
],
'#states'
=>
array
(
'visible'
=>
array
(
':input[name="options[validate][options][node][access]"]'
=>
array
(
'checked'
=>
TRUE
),
),
),
);
$form
[
'nid_type'
]
=
array
(
'#type'
=>
'select'
,
'#title'
=>
t
(
'Filter value format'
),
'#options'
=>
array
(
'nid'
=>
t
(
'Node ID'
),
'nids'
=>
t
(
'Node IDs separated by , or +'
),
),
'#default_value'
=>
$this
->
options
[
'nid_type'
],
);
}
public
function
submitOptionsForm
(
&
$form
,
&
$form_state
,
&
$options
=
array
())
{
// filter trash out of the options so we don't store giant unnecessary arrays
$options
[
'types'
]
=
array_filter
(
$options
[
'types'
]);
}
public
function
validateArgument
(
$argument
)
{
$types
=
$this
->
options
[
'types'
];
switch
(
$this
->
options
[
'nid_type'
])
{
case
'nid'
:
if
(
!
is_numeric
(
$argument
))
{
return
FALSE
;
}
$node
=
node_load
(
$argument
);
if
(
!
$node
)
{
return
FALSE
;
}
if
(
!
empty
(
$this
->
options
[
'access'
]))
{
if
(
!
$node
->
access
(
$this
->
options
[
'access_op'
]))
{
return
FALSE
;
}
}
// Save the title() handlers some work.
$this
->
argument
->
validated_title
=
check_plain
(
$node
->
label
());
if
(
empty
(
$types
))
{
return
TRUE
;
}
return
isset
(
$types
[
$node
->
getType
()]);
case
'nids'
:
$nids
=
new
stdClass
();
$nids
->
value
=
array
(
$argument
);
$nids
=
$this
->
breakPhrase
(
$argument
,
$nids
);
if
(
$nids
->
value
==
array
(
-
1
))
{
return
FALSE
;
}
$test
=
array_combine
(
$nids
->
value
,
$nids
->
value
);
$titles
=
array
();
$nodes
=
node_load_multiple
(
$nids
->
value
);
foreach
(
$nodes
as
$node
)
{
if
(
$types
&&
empty
(
$types
[
$node
->
getType
()]))
{
return
FALSE
;
}
if
(
!
empty
(
$this
->
options
[
'access'
]))
{
if
(
!
$node
->
access
(
$this
->
options
[
'access_op'
]))
{
return
FALSE
;
}
}
$titles
[]
=
check_plain
(
$node
->
label
());
unset
(
$test
[
$node
->
id
()]);
}
$this
->
argument
->
validated_title
=
implode
(
$nids
->
operator
==
'or'
?
' + '
:
', '
,
$titles
);
// If this is not empty, we did not find a nid.
return
empty
(
$test
);
}
}
}
core/modules/user/lib/Drupal/user/Plugin/views/argument_validator/User.php
View file @
4e9a8851
...
...
@@ -7,9 +7,9 @@
namespace
Drupal\user\Plugin\views\argument_validator
;
use
Drupal\Core\
Database\Connection
;
use
Drupal\
views\Plugin\views\argument_validator
\
ArgumentValidatorPluginBas
e
;
use
Symfony\Component\DependencyInjection\ContainerInterface
;
use
Drupal\Core\
Entity\EntityInterface
;
use
Drupal\
Core\Entity\EntityManagerInterfac
e
;
use
Drupal\views\Plugin\views\argument_validator
\
Entity
;
/**
* Validate whether an argument is a valid user.
...
...
@@ -17,79 +17,54 @@
* This supports either numeric arguments (UID) or strings (username) and
* converts either one into the user's UID. This validator also sets the
* argument's title to the username.
*
* @ViewsArgumentValidator(
* id = "user",
* title = @Translation("User")
* )
*/
class
User
extends
ArgumentValidatorPluginBase
{
class
User
extends
Entity
{
/**
*
Database Service Object
.
*
The user storage controller
.
*
* @var \Drupal\Core\
Database\Connection
* @var \Drupal\Core\
Entity\EntityStorageControllerInterface
*/
protected
$
databas
e
;
protected
$
userStorag
e
;
/**
* Constructs a Drupal\Component\Plugin\PluginBase object.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param array $plugin_definition
* The plugin implementation definition.
* @param \Drupal\Core\Database\Connection $database
* Database Service Object.
* {@inheritdoc}
*/
public
function
__construct
(
array
$configuration
,
$plugin_id
,
array
$plugin_definition
,
Connection
$database
)
{
parent
::
__construct
(
$configuration
,
$plugin_id
,
$plugin_definition
);
public
function
__construct
(
array
$configuration
,
$plugin_id
,
array
$plugin_definition
,
EntityManagerInterface
$entity_manager
)
{
parent
::
__construct
(
$configuration
,
$plugin_id
,
$plugin_definition
,
$entity_manager
);
$this
->
database
=
$database
;
$this
->
userStorage
=
$entity_manager
->
getStorageController
(
'user'
)
;
}
/**
* {@inheritdoc}
*/
public
static
function
create
(
ContainerInterface
$container
,
array
$configuration
,
$plugin_id
,
array
$plugin_definition
)
{
return
new
static
(
$configuration
,
$plugin_id
,
$plugin_definition
,
$container
->
get
(
'database'
));
}
protected
function
defineOptions
()
{
$options
=
parent
::
defineOptions
();
$options
[
'type'
]
=
array
(
'default'
=>
'uid'
);
$options
[
'restrict_roles'
]
=
array
(
'default'
=>
FALSE
,
'bool'
=>
TRUE
);
$options
[
'roles'
]
=
array
(
'default'
=>
array
());
return
$options
;
}
/**
* {@inheritdoc}
*/
public
function
buildOptionsForm
(
&
$form
,
&
$form_state
)
{
$form
[
'type'
]
=
array
(
'#type'
=>
'radios'
,
'#title'
=>
t
(
'Type of user filter value to allow'
),
'#options'
=>
array
(
'uid'
=>
t
(
'Only allow numeric UIDs'
),
'name'
=>
t
(
'Only allow string usernames'
),
'either'
=>
t
(
'Allow both numeric UIDs and string usernames'
),
),
'#default_value'
=>
$this
->
options
[
'type'
],
);
parent
::
buildOptionsForm
(
$form
,
$form_state
);
$form
[
'restrict_roles'
]
=
array
(
'#type'
=>
'checkbox'
,
'#title'
=>
t
(
'Restrict user based on role'
),
'#title'
=>
$this
->
t
(
'Restrict user based on role'
),
'#default_value'
=>
$this
->
options
[
'restrict_roles'
],
);
$form
[
'roles'
]
=
array
(
'#type'
=>
'checkboxes'
,
'#title'
=>
t
(
'Restrict to the selected roles'
),
'#title'
=>
$this
->
t
(
'Restrict to the selected roles'
),
'#options'
=>
array_map
(
'check_plain'
,
user_role_names
(
TRUE
)),
'#default_value'
=>
$this
->
options
[
'roles'
],
'#description'
=>
t
(
'If no roles are selected, users from any role will be allowed.'
),
'#description'
=>
$this
->
t
(
'If no roles are selected, users from any role will be allowed.'
),
'#states'
=>
array
(
'visible'
=>
array
(
':input[name="options[validate][options][user][restrict_roles]"]'
=>
array
(
'checked'
=>
TRUE
),
...
...
@@ -98,79 +73,29 @@ public function buildOptionsForm(&$form, &$form_state) {
);
}
/**
* {@inheritdoc}
*/
public
function
submitOptionsForm
(
&
$form
,
&
$form_state
,
&
$options
=
array
())
{
// filter trash out of the options so we don't store giant unnecessary arrays
$options
[
'roles'
]
=
array_filter
(
$options
[
'roles'
]);
}
public
function
validateArgument
(
$argument
)
{
$type
=
$this
->
options
[
'type'
];
// is_numeric() can return false positives, so we ensure it's an integer.
// However, is_integer() will always fail, since $argument is a string.
if
(
is_numeric
(
$argument
)
&&
$argument
==
(
int
)
$argument
)
{
if
(
$type
==
'uid'
||
$type
==
'either'
)
{
if
(
$argument
==
\
Drupal
::
currentUser
()
->
id
())
{
// If you assign an object to a variable in PHP, the variable
// automatically acts as a reference, not a copy, so we use
// clone to ensure that we don't actually mess with the
// real current user object.
$account
=
clone
\
Drupal
::
currentUser
();
}
$condition
=
'uid'
;
}
}
else
{
if
(
$type
==
'name'
||
$type
==
'either'
)
{
$name
=
\
Drupal
::
currentUser
()
->
getUserName
()
?:
\
Drupal
::
config
(
'user.settings'
)
->
get
(
'anonymous'
);
if
(
$argument
==
$name
)
{
$account
=
clone
\
Drupal
::
currentUser
();
}
$condition
=
'name'
;
}
}
// If we don't have a WHERE clause, the argument is invalid.
if
(
empty
(
$condition
))
{
return
FALSE
;
}
if
(
!
isset
(
$account
))
{
$uid
=
$this
->
database
->
select
(
'users'
,
'u'
)
->
fields
(
'u'
,
array
(
'uid'
))
->
condition
(
$condition
,
$argument
)
->
execute
()
->
fetchField
();
if
(
$uid
===
FALSE
)
{
// User not found.
return
FALSE
;
}
}
$account
=
user_load
(
$uid
);
/**
* {@inheritdoc}
*/
protected
function
validateEntity
(
EntityInterface
$entity
)
{
/** @var \Drupal\user\UserInterface $entity */
$role_check_success
=
TRUE
;
// See if we're filtering users based on roles.
if
(
!
empty
(
$this
->
options
[
'restrict_roles'
])
&&
!
empty
(
$this
->
options
[
'roles'
]))
{
$roles
=
$this
->
options
[
'roles'
];
if
(
!
(
bool
)
array_intersect
(
$
account
->
getRoles
(),
$roles
))
{
return
FALSE
;
if
(
!
(
bool
)
array_intersect
(
$
entity
->
getRoles
(),
$roles
))
{
$role_check_success
=
FALSE
;
}
}
$this
->
argument
->
argument
=
$account
->
id
();
$this
->
argument
->
validated_title
=
check_plain
(
user_format_name
(
$account
));
return
TRUE
;
}
public
function
processSummaryArguments
(
&
$args
)
{
// If the validation says the input is an username, we should reverse the
// argument so it works for example for generation summary urls.
$uids_arg_keys
=
array_flip
(
$args
);
if
(
$this
->
options
[
'type'
]
==
'name'
)
{
$users
=
user_load_multiple
(
$args
);
foreach
(
$users
as
$uid
=>
$account
)
{
$args
[
$uids_arg_keys
[
$uid
]]
=
$account
->
label
();
}
}
return
$role_check_success
&&
parent
::
validateEntity
(
$entity
);
}
}
core/modules/user/lib/Drupal/user/Plugin/views/argument_validator/UserName.php
0 → 100644
View file @
4e9a8851
<?php
/**
* @file
* Contains \Drupal\user\Plugin\views\argument_validator\UserName.
*/
namespace
Drupal\user\Plugin\views\argument_validator
;
/**
* Validates whether a user name is valid.
*
* @ViewsArgumentValidator(
* id = "user_name",
* title = @Translation("User name"),
* entity_type = "user"
* )
*/
class
UserName
extends
User
{
/**
* {@inheritdoc}
*/
public
function
buildOptionsForm
(
&
$form
,
&
$form_state
)
{
parent
::
buildOptionsForm
(
$form
,
$form_state
);
$entity_type
=
$this
->
entityManager
->
getDefinition
(
'user'
);
$form
[
'multiple'
][
'#options'
]
=
array
(
0
=>
$this
->
t
(
'Single name'
,
array
(
'%type'
=>
$entity_type
->
getLabel
())),
1
=>
$this
->
t
(
'One or more names separated by , or +'
,
array
(
'%type'
=>
$entity_type
->
getLabel
())),
);
}
/**
* {@inheritdoc}
*/
public
function
validateArgument
(
$argument
)
{
if
(
$this
->
multipleCapable
&&
$this
->
options
[
'multiple'
])
{
// At this point only interested in individual IDs no matter what type,
// just splitting by the allowed delimiters.
$names
=
array_filter
(
preg_split
(
'/[,+ ]/'
,
$argument
));
}
elseif
(
$argument
)
{
$names
=
array
(
$argument
);
}
// No specified argument should be invalid.
else
{
return
FALSE
;
}
$accounts
=
$this
->
userStorage
->
loadByProperties
(
array
(
'name'
=>
$names
));
// If there are no accounts, return FALSE now. As we will not enter the
// loop below otherwise.
if
(
empty
(
$accounts
))
{
return
FALSE
;
}
// Validate each account. If any fails break out and return false.
foreach
(
$accounts
as
$account
)
{
if
(
!
in_array
(
$account
->
getUserName
(),
$names
)
||
!
$this
->
validateEntity
(
$account
))
{
return
FALSE
;
}
}
return
TRUE
;
}
/**
* {@inheritdoc}
*/
public
function
processSummaryArguments
(
&
$args
)
{
// If the validation says the input is an username, we should reverse the
// argument so it works for example for generation summary urls.
$uids_arg_keys
=
array_flip
(
$args
);
foreach
(
$this
->
userStorage
->
loadMultiple
(
$args
)
as
$uid
=>
$account
)
{
$args
[
$uids_arg_keys
[
$uid
]]
=
$account
->
label
();
}
}
}
core/modules/user/lib/Drupal/user/Tests/Views/ArgumentValidateTest.php
View file @
4e9a8851
...
...
@@ -19,12 +19,12 @@ class ArgumentValidateTest extends UserTestBase {
*
* @var array
*/
public
static
$testViews
=
array
(
'test_view_argument_validate_user'
);
public
static
$testViews
=
array
(
'test_view_argument_validate_user'
,
'test_view_argument_validate_username'
);
public
static
function
getInfo
()
{
return
array
(
'name'
=>
'User: Argument validator'
,
'description'
=>
'Tests user argument validator.'
,
'name'
=>
'User: Argument validator
s
'
,
'description'
=>
'Tests user argument validator
s for ID and name
.'
,
'group'
=>
'Views module integration'
,
);
}
...
...
@@ -35,63 +35,36 @@ protected function setUp() {
$this
->
account
=
$this
->
drupalCreateUser
();
}
/**
* Tests the User (ID) argument validator.
*/
function
testArgumentValidateUserUid
()
{
$account
=
$this
->
account
;
// test 'uid' case
$view
=
$this
->
view_argument_validate_user
(
'uid'
);
$view
=
Views
::
getView
(
'test_view_argument_validate_user'
);
$this
->
executeView
(
$view
);
$this
->
assertTrue
(
$view
->
argument
[
'null'
]
->
validateArgument
(
$account
->
id
()));
// Reset safed argument validation.
$view
->
argument
[
'null'
]
->
argument_validated
=
NULL
;
// Fail for a string variable since type is 'uid'
$this
->
assertFalse
(
$view
->
argument
[
'null'
]
->
validateArgument
(
$account
->
getUsername
()));
// Reset safed argument validation.
// Reset argument validation.
$view
->
argument
[
'null'
]
->
argument_validated
=
NULL
;
// Fail for a valid numeric, but for a user that doesn't exist
$this
->
assertFalse
(
$view
->
argument
[
'null'
]
->
validateArgument
(
32
));
}
function
testArgumentValidateUserName
()
{
/**
* Tests the UserName argument validator.
*/
public
function
testArgumentValidateUserName
()
{
$account
=
$this
->
account
;
// test 'name' case
$view
=
$this
->
view_argument_validate_user
(
'name'
);
$this
->
assertTrue
(
$view
->
argument
[
'null'
]
->
validateArgument
(
$account
->
getUsername
()));
// Reset safed argument validation.
$view
->
argument
[
'null'
]
->
argument_validated
=
NULL
;
// Fail for a uid variable since type is 'name'
$this
->
assertFalse
(
$view
->
argument
[
'null'
]
->
validateArgument
(
$account
->
id
()));
// Reset safed argument validation.
$view
->
argument
[
'null'
]
->
argument_validated
=
NULL
;
// Fail for a valid string, but for a user that doesn't exist
$this
->
assertFalse
(
$view
->
argument
[
'null'
]
->
validateArgument
(
$this
->
randomName
()));
}
function
testArgumentValidateUserEither
()
{
$account
=
$this
->
account
;
// test 'either' case
$view
=
$this
->
view_argument_validate_user
(
'either'
);
$view
=
Views
::
getView
(
'test_view_argument_validate_username'
);
$this
->
executeView
(
$view
);
$this
->
assertTrue
(
$view
->
argument
[
'null'
]
->
validateArgument
(
$account
->
getUsername
()));
// Reset safed argument validation.
$view
->
argument
[
'null'
]
->
argument_validated
=
NULL
;
// Fail for a uid variable since type is 'name'
$this
->
assertTrue
(
$view
->
argument
[
'null'
]
->
validateArgument
(
$account
->
id
()));
// Reset safed argument validation.
// Reset argument validation.
$view
->
argument
[
'null'
]
->
argument_validated
=
NULL
;
// Fail for a valid string, but for a user that doesn't exist
$this
->
assertFalse
(
$view
->
argument
[
'null'
]
->
validateArgument
(
$this
->
randomName
()));
// Reset safed argument validation.
$view
->
argument
[
'null'
]
->
argument_validated
=
NULL
;
// Fail for a valid uid, but for a user that doesn't exist
$this
->
assertFalse
(
$view
->
argument
[
'null'
]
->
validateArgument
(
32
));
}
function
view_argument_validate_user
(
$argtype
)
{
$view
=
Views
::
getView
(
'test_view_argument_validate_user'
);
$view
->
setDisplay
();
$view
->
displayHandlers
->
get
(
'default'
)
->
options
[
'arguments'
][
'null'
][
'validate_options'
][
'type'
]
=
$argtype
;
$view
->
preExecute
();
$view
->
initHandlers
();
return
$view
;
}
}
core/modules/user/tests/modules/user_test_views/test_views/views.view.test_view_argument_validate_user.yml
View file @
4e9a8851
...
...
@@ -16,7 +16,7 @@ display:
style_plugin
:
default_summary
table
:
views
validate
:
type
:
user
type
:
entity:
user
plugin_id
:
'
null'
provider
:
views
cache
:
...
...
core/modules/user/tests/modules/user_test_views/test_views/views.view.test_view_argument_validate_username.yml
0 → 100644
View file @
4e9a8851
base_table
:
node
core
:
'
8'
description
:
'
'
status
:
'
1'
display
:
default
:
display_options
:
access
:
type
:
none
arguments
:
'
null'
:
default_argument_type
:
fixed
field
:
'
null'
id
:
'
null'
must_not_be
:
'
0'
style_plugin
:
default_summary
table
:
views
validate
:
type
:
user_name
plugin_id
:
'
null'
provider
:
views
cache
:
type
:
none
exposed_form
:
type
:
basic
pager
:
type
:
full
style
:
type
:
default
row
:
type
:
fields
display_plugin
:
default
display_title
:
Master
id
:
default
position
:
0
label
:
'
'
id
:
test_view_argument_validate_username
tag
:
'
'
core/modules/user/user.views.inc
View file @
4e9a8851
...
...
@@ -380,3 +380,12 @@ function user_views_data_alter(&$data) {
),
);
}
/**
* Implements hook_views_plugins_argument_validator_alter().
*/
function
user_views_plugins_argument_validator_alter
(
array
&
$plugins
)
{
$plugins
[
'entity:user'
][
'title'
]
=
t
(
'User ID'
);