Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
moodle
moodle
Commits
3b002c86
Commit
3b002c86
authored
Oct 17, 2018
by
Andrew Nicols
Browse files
MDL-63619 tool_dataprivacy: Performance improvement
parent
d2aed789
Changes
1
Hide whitespace changes
Inline
Side-by-side
admin/tool/dataprivacy/classes/data_registry.php
View file @
3b002c86
...
...
@@ -177,60 +177,92 @@ class data_registry {
* @return persistent|false It return a 'purpose' instance or a 'category' instance, depending on $element
*/
public
static
function
get_effective_context_value
(
\
context
$context
,
$element
,
$forcedvalue
=
false
)
{
global
$DB
;
if
(
$element
!==
'purpose'
&&
$element
!==
'category'
)
{
throw
new
coding_exception
(
'Only \'purpose\' and \'category\' are supported.'
);
}
$fieldname
=
$element
.
'id'
;
if
(
!
empty
(
$forcedvalue
)
&&
(
$forcedvalue
===
context_instance
::
INHERIT
))
{
// Do not include the current context when calculating the value.
// This has the effect that an inheritted value is calculated.
$parentcontextids
=
$context
->
get_parent_context_ids
(
false
);
}
else
if
(
!
empty
(
$forcedvalue
)
&&
(
$forcedvalue
!==
context_instance
::
NOTSET
))
{
return
self
::
get_element_instance
(
$element
,
$forcedvalue
);
}
else
{
// Fetch all parent contexts, including self.
$parentcontextids
=
$context
->
get_parent_context_ids
(
true
);
}
list
(
$insql
,
$inparams
)
=
$DB
->
get_in_or_equal
(
$parentcontextids
,
SQL_PARAMS_NAMED
);
$inparams
[
'contextmodule'
]
=
CONTEXT_MODULE
;
if
(
'purpose'
===
$element
)
{
$elementjoin
=
'LEFT JOIN {tool_dataprivacy_purpose} ele ON ctxins.purposeid = ele.id'
;
$elementfields
=
purpose
::
get_sql_fields
(
'ele'
,
'ele'
);
}
else
{
$elementjoin
=
'LEFT JOIN {tool_dataprivacy_category} ele ON ctxins.categoryid = ele.id'
;
$elementfields
=
category
::
get_sql_fields
(
'ele'
,
'ele'
);
}
$contextfields
=
\
context_helper
::
get_preload_record_columns_sql
(
'ctx'
);
$fields
=
implode
(
', '
,
[
'ctx.id'
,
'm.name AS modname'
,
$contextfields
,
$elementfields
]);
$sql
=
"SELECT
$fields
FROM
{
context
}
ctx
LEFT JOIN
{
tool_dataprivacy_ctxinstance
}
ctxins ON ctx.id = ctxins.contextid
LEFT JOIN
{
course_modules
}
cm ON ctx.contextlevel = :contextmodule AND ctx.instanceid = cm.id
LEFT JOIN
{
modules
}
m ON m.id = cm.module
{
$elementjoin
}
WHERE ctx.id
{
$insql
}
ORDER BY ctx.path DESC"
;
$contextinstances
=
$DB
->
get_records_sql
(
$sql
,
$inparams
);
// Check whether this context is a user context, or a child of a user context.
// User contexts share the same context and cannot be set individually.
$parents
=
$context
->
get_parent_contexts
(
true
);
foreach
(
$parents
as
$parent
)
{
// All children of a User context share the same context and cannot be set individually.
foreach
(
$contextinstances
as
$record
)
{
\
context_helper
::
preload_from_record
(
$record
);
$parent
=
\
context
::
instance_by_id
(
$record
->
id
,
false
);
if
(
$parent
->
contextlevel
==
CONTEXT_USER
)
{
// Use the context level value for the user.
return
self
::
get_effective_contextlevel_value
(
CONTEXT_USER
,
$element
);
}
}
$instancevalue
=
context_instance
::
NOTSET
;
if
(
empty
(
$forcedvalue
))
{
if
(
$instance
=
context_instance
::
get_record_by_contextid
(
$context
->
id
,
false
))
{
$instancevalue
=
$instance
->
get
(
$fieldname
);
foreach
(
$contextinstances
as
$record
)
{
$parent
=
\
context
::
instance_by_id
(
$record
->
id
,
false
);
$checkcontextlevel
=
false
;
if
(
empty
(
$record
->
eleid
))
{
$checkcontextlevel
=
true
;
}
}
else
{
$instancevalue
=
$forcedvalue
;
}
// Not set.
if
(
$instancevalue
==
context_instance
::
NOTSET
)
{
// Check if we need to pass the plugin name of an activity.
$forplugin
=
''
;
if
(
$context
->
contextlevel
==
CONTEXT_MODULE
)
{
list
(
$course
,
$cm
)
=
get_course_and_cm_from_cmid
(
$context
->
instanceid
);
$forplugin
=
$cm
->
modname
;
if
(
!
empty
(
$forcedvalue
)
&&
context_instance
::
NOTSET
===
$forcedvalue
)
{
$checkcontextlevel
=
true
;
}
// Use the default context level value.
list
(
$purposeid
,
$categoryid
)
=
self
::
get_effective_default_contextlevel_purpose_and_category
(
$context
->
contextlevel
,
false
,
false
,
$forplugin
);
$instancevalue
=
$$fieldname
;
}
if
(
$checkcontextlevel
)
{
// Check for a value at the contextlevel
$forplugin
=
empty
(
$record
->
modname
)
?
''
:
$record
->
modname
;
list
(
$purposeid
,
$categoryid
)
=
self
::
get_effective_default_contextlevel_purpose_and_category
(
$parent
->
contextlevel
,
false
,
false
,
$forplugin
);
if
(
context_instance
::
NOTSET
!==
$instancevalue
&&
context_instance
::
INHERIT
!==
$instancevalue
)
{
// There is an actual value. Return it.
return
self
::
get_element_instance
(
$element
,
$instancevalue
);
}
$instancevalue
=
$$fieldname
;
// There is no value set (or it is set to inherit).
// Fetch from the parent context.
$parent
=
$context
->
get_parent_context
();
if
(
context_instance
::
NOTSET
!==
$instancevalue
&&
context_instance
::
INHERIT
!==
$instancevalue
)
{
// There is an actual value. Return it.
return
self
::
get_element_instance
(
$element
,
$instancevalue
);
}
}
else
{
$elementclass
=
"
\\
tool_dataprivacy
\\
{
$element
}
"
;
$instance
=
new
$elementclass
(
null
,
$elementclass
::
extract_record
(
$record
,
'ele'
));
$instance
->
validate
();
if
(
CONTEXT_SYSTEM
==
$parent
->
contextlevel
)
{
return
self
::
get_effective_contextlevel_value
(
CONTEXT_SYSTEM
,
$element
);
}
else
{
return
self
::
get_effective_context_value
(
$context
->
get_parent_context
(),
$element
);
return
$instance
;
}
}
throw
new
coding_exception
(
'Something went wrong, system defaults should be set and we should already have a value.'
);
}
/**
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment