From 0875cc18e5f1fb1758342c283ef9826bd3cae71a Mon Sep 17 00:00:00 2001 From: Frederic Massart Date: Tue, 8 Dec 2015 16:55:02 +0800 Subject: [PATCH] MDL-52423 tool_lp: Allow null related objects in exporters Note that the related objects MUST always ALL be passed to the constructor when instantiating objets, even if they are null. Related objects were introduced to improve performance and their requirement is one way to ensure that developers don't forget them. --- admin/tool/lp/classes/external/exporter.php | 22 ++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/admin/tool/lp/classes/external/exporter.php b/admin/tool/lp/classes/external/exporter.php index 1e3757a6d73..047eec5298d 100644 --- a/admin/tool/lp/classes/external/exporter.php +++ b/admin/tool/lp/classes/external/exporter.php @@ -63,13 +63,26 @@ abstract class exporter { // Cache the valid related objects. foreach (static::define_related() as $key => $classname) { $isarray = false; + $nullallowed = false; + + // Allow ? to mean null is allowed. + if (substr($classname, -1) === '?') { + $classname = substr($classname, 0, -1); + $nullallowed = true; + } + // Allow [] to mean an array of values. if (substr($classname, -2) === '[]') { $classname = substr($classname, 0, -2); $isarray = true; } + $missingdataerr = 'Exporter class is missing required related data: (' . get_called_class() . ') '; - if ($isarray) { + + if ($nullallowed && array_key_exists($key, $related) && $related[$key] === null) { + $this->related[$key] = $related[$key]; + + } else if ($isarray) { if (array_key_exists($key, $related) && is_array($related[$key])) { foreach ($related[$key] as $index => $value) { if (!$value instanceof $classname) { @@ -80,8 +93,9 @@ abstract class exporter { } else { throw new coding_exception($missingdataerr . $key . ' => ' . $classname . '[]'); } + } else { - if ((array_key_exists($key, $related) && ($related[$key] instanceof $classname))) { + if (array_key_exists($key, $related) && $related[$key] instanceof $classname) { $this->related[$key] = $related[$key]; } else { throw new coding_exception($missingdataerr . $key . ' => ' . $classname); @@ -272,7 +286,9 @@ abstract class exporter { * * Only objects listed here can be cached in this object. * - * The class name can be suffixed with [] to indicate an array of values. + * The class name can be suffixed: + * - with [] to indicate an array of values. + * - with ? to indicate that 'null' is allowed. * * @return array of 'propertyname' => array('type' => classname, 'required' => true) */