Note:

If you want to create a new page for developers, you should create it on the Moodle Developer Resource site.

Privacy API/Utilities: Difference between revisions

From MoodleDocs
m (Add link back to the API docs page)
m (Put a note about the purpose of the scripts)
Line 1: Line 1:
While implementing the privacy API into your plugin, there are CLI scripts that can help you to test things on the fly. Just don't forget these are not supposed to replace proper unit tests.
Put these scripts into the root of your Moodle development installation and run them via command line. See [[Privacy API]] for the full guide on implementing the API in your plugin.
Put these scripts into the root of your Moodle development installation and run them via command line. See [[Privacy API]] for the full guide on implementing the API in your plugin.



Revision as of 12:51, 12 April 2018

While implementing the privacy API into your plugin, there are CLI scripts that can help you to test things on the fly. Just don't forget these are not supposed to replace proper unit tests.

Put these scripts into the root of your Moodle development installation and run them via command line. See Privacy API for the full guide on implementing the API in your plugin.

Test of privacy API compliance

<?php

// Set this if you want to run the script for one component only. Otherwise leave empty. $CHECK_COMPONENT = ;

define('CLI_SCRIPT', true);

require_once('config.php');

$user = \core_user::get_user(2);

\core\session\manager::init_empty_session(); \core\session\manager::set_user($user);

$rc = new \ReflectionClass(\core_privacy\manager::class); $rcm = $rc->getMethod('get_component_list'); $rcm->setAccessible(true);

$manager = new \core_privacy\manager(); $components = $rcm->invoke($manager);

$list = (object) [

   'good' => [],
   'bad' => [],

];

foreach ($components as $component) {

   if ($CHECK_COMPONENT && $component !== $CHECK_COMPONENT) {
       continue;
   }
   $compliant = $manager->component_is_compliant($component);
   if ($compliant) {
       $list->good[] = $component;
   } else {
       $list->bad[] = $component;
   }

}

echo "The following plugins are not compliant:\n"; echo "=> " . implode("\n=> ", array_values($list->bad)) . "\n";

echo "\n"; echo "Testing the compliant plugins:\n"; foreach ($list->good as $component) {

   $classname = \core_privacy\manager::get_provider_classname_for_component($component);
   echo "== {$component} ($classname) ==\n";
   if (check_implements($component, \core_privacy\local\metadata\null_provider::class)) {
       echo "    Claims not to store any data with reason:\n";
       echo "      '" . get_string($classname::get_reason(), $component) . "'\n";
   }
   else if (check_implements($component, \core_privacy\local\metadata\provider::class)) {
       $collection = new \core_privacy\local\metadata\collection($component);
       $classname::get_metadata($collection);
       $count = count($collection);
       echo "    Found {$count} items of metadata\n";
       if (empty($count)) {
           echo "!!! No metadata found!!! This an error.\n";
       }
       if (check_implements($component, \core_privacy\local\request\user_preference_provider::class)) {
           $userprefdescribed = false;
           foreach ($collection->get_collection() as $item) {
               if ($item instanceof \core_privacy\local\metadata\types\user_preference) {
                   $userprefdescribed = true;
                   echo "     ".$item->get_name()." : ".get_string($item->get_summary(), $component) . "\n";
               }
           }
           if (!$userprefdescribed) {
               echo "!!! User preference found, but was not described in metadata\n";
           }
       }
       if (check_implements($component, \core_privacy\local\request\core_user_data_provider::class)) {
           // No need to check the return type - it's enforced by the interface.
           $contextlist = $classname::get_contexts_for_userid($user->id);
           $approvedcontextlist = new \core_privacy\local\request\approved_contextlist($user, $contextlist->get_component(), $contextlist->get_contextids());
           if (count($approvedcontextlist)) {
               $classname::export_user_data($approvedcontextlist);
               echo "    Successfully ran a test export\n";
           } else {
               echo "    Nothing to export.\n";
           }
       }
       if (check_implements($component, \core_privacy\local\request\shared_data_provider::class)) {
           echo "    This is a shared data provider\n";
       }
   }

}

echo "\n\n== Done ==\n";

function check_implements($component, $interface) {

   $manager = new \core_privacy\manager();
   $rc = new \ReflectionClass(\core_privacy\manager::class);
   $rcm = $rc->getMethod('component_implements');
   $rcm->setAccessible(true);
   return $rcm->invoke($manager, $component, $interface);

}

Test of exporting user data

<?php

define('CLI_SCRIPT', true);

require_once('config.php');

$user = \core_user::get_user(2);

\core\session\manager::init_empty_session(); \core\session\manager::set_user($user);

$manager = new \core_privacy\manager();

$approvedlist = new \core_privacy\local\request\contextlist_collection($user->id);

$contextlists = $manager->get_contexts_for_userid($user->id); foreach ($contextlists as $contextlist) {

   $approvedlist->add_contextlist(new \core_privacy\local\request\approved_contextlist(
       $user,
       $contextlist->get_component(),
       $contextlist->get_contextids()
   ));

}

$exportedcontent = $manager->export_user_data($approvedlist);

echo "\n"; echo "== File was successfully exported to {$exportedcontent}\n";

$basedir = make_temp_directory('privacy'); $exportpath = make_unique_writable_directory($basedir, true); $fp = get_file_packer(); $fp->extract_to_pathname($exportedcontent, $exportpath);

echo "== File export was uncompressed to {$exportpath}\n"; echo "============================================================================\n";