Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 3.9.x will end* 10 May 2021 (12 months).
  • Bug fixes for security issues in 3.9.x will end* 8 May 2023 (36 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

Differences Between: [Versions 39 and 310]

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  18   * Data provider tests.
  19   *
  20   * @package    core_blog
  21   * @category   test
  22   * @copyright  2018 Frédéric Massart
  23   * @author     Frédéric Massart <fred@branchup.tech>
  24   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  25   */
  26  
  27  defined('MOODLE_INTERNAL') || die();
  28  global $CFG;
  29  
  30  use core_privacy\tests\provider_testcase;
  31  use core_privacy\local\request\approved_contextlist;
  32  use core_privacy\local\request\transform;
  33  use core_privacy\local\request\writer;
  34  use core_blog\privacy\provider;
  35  
  36  require_once($CFG->dirroot . '/blog/locallib.php');
  37  require_once($CFG->dirroot . '/comment/lib.php');
  38  
  39  /**
  40   * Data provider testcase class.
  41   *
  42   * @package    core_blog
  43   * @category   test
  44   * @copyright  2018 Frédéric Massart
  45   * @author     Frédéric Massart <fred@branchup.tech>
  46   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  47   */
  48  class core_blog_privacy_testcase extends provider_testcase {
  49  
  50      public function setUp() {
  51          $this->resetAfterTest();
  52      }
  53  
  54      public function test_get_contexts_for_userid() {
  55          $dg = $this->getDataGenerator();
  56          $c1 = $dg->create_course();
  57          $c2 = $dg->create_course();
  58          $c3 = $dg->create_course();
  59          $cm1a = $dg->create_module('page', ['course' => $c1]);
  60          $cm1b = $dg->create_module('page', ['course' => $c1]);
  61          $cm2a = $dg->create_module('page', ['course' => $c2]);
  62          $u1 = $dg->create_user();
  63          $u2 = $dg->create_user();
  64          $u1ctx = context_user::instance($u1->id);
  65  
  66          // Blog share a table with notes, so throw data in there and make sure it doesn't get reported.
  67          $dg->get_plugin_generator('core_notes')->create_instance(['userid' => $u1->id, 'courseid' => $c3->id]);
  68  
  69          $this->assertEmpty(provider::get_contexts_for_userid($u1->id)->get_contextids());
  70          $this->assertEmpty(provider::get_contexts_for_userid($u2->id)->get_contextids());
  71  
  72          // Gradually create blog posts for user 1. First system one.
  73          $this->create_post(['userid' => $u1->id]);
  74          $contextids = provider::get_contexts_for_userid($u1->id)->get_contextids();
  75          $this->assertCount(1, $contextids);
  76          $this->assertEquals($u1ctx->id, $contextids[0]);
  77          $this->assertEmpty(provider::get_contexts_for_userid($u2->id)->get_contextids());
  78  
  79          // Create a blog post associated with c1.
  80          $post = $this->create_post(['userid' => $u1->id, 'courseid' => $c1->id]);
  81          $entry = new blog_entry($post->id);
  82          $entry->add_association(context_course::instance($c1->id)->id);
  83          $contextids = provider::get_contexts_for_userid($u1->id)->get_contextids();
  84          $this->assertCount(2, $contextids);
  85          $this->assertTrue(in_array($u1ctx->id, $contextids));
  86          $this->assertTrue(in_array(context_course::instance($c1->id)->id, $contextids));
  87          $this->assertEmpty(provider::get_contexts_for_userid($u2->id)->get_contextids());
  88  
  89          // Create a blog post associated with cm2a.
  90          $post = $this->create_post(['userid' => $u1->id, 'courseid' => $c2->id]);
  91          $entry = new blog_entry($post->id);
  92          $entry->add_association(context_module::instance($cm2a->cmid)->id);
  93          $contextids = provider::get_contexts_for_userid($u1->id)->get_contextids();
  94          $this->assertCount(3, $contextids);
  95          $this->assertTrue(in_array($u1ctx->id, $contextids));
  96          $this->assertTrue(in_array(context_course::instance($c1->id)->id, $contextids));
  97          $this->assertTrue(in_array(context_module::instance($cm2a->cmid)->id, $contextids));
  98          $this->assertEmpty(provider::get_contexts_for_userid($u2->id)->get_contextids());
  99  
 100          // User 2 comments on u1's post.
 101          $comment = $this->get_comment_object($u1ctx, $post->id);
 102          $this->setUser($u2);
 103          $comment->add('Hello, it\'s me!');
 104          $contextids = provider::get_contexts_for_userid($u1->id)->get_contextids();
 105          $this->assertCount(3, $contextids);
 106          $this->assertTrue(in_array($u1ctx->id, $contextids));
 107          $this->assertTrue(in_array(context_course::instance($c1->id)->id, $contextids));
 108          $this->assertTrue(in_array(context_module::instance($cm2a->cmid)->id, $contextids));
 109          $contextids = provider::get_contexts_for_userid($u2->id)->get_contextids();
 110          $this->assertCount(1, $contextids);
 111          $this->assertTrue(in_array($u1ctx->id, $contextids));
 112      }
 113  
 114      public function test_get_contexts_for_userid_with_one_associated_post_only() {
 115          $dg = $this->getDataGenerator();
 116          $c1 = $dg->create_course();
 117          $u1 = $dg->create_user();
 118          $u1ctx = context_user::instance($u1->id);
 119  
 120          $this->assertEmpty(provider::get_contexts_for_userid($u1->id)->get_contextids());
 121  
 122          // Create a blog post associated with c1. It should always return both the course and user context.
 123          $post = $this->create_post(['userid' => $u1->id, 'courseid' => $c1->id]);
 124          $entry = new blog_entry($post->id);
 125          $entry->add_association(context_course::instance($c1->id)->id);
 126          $contextids = provider::get_contexts_for_userid($u1->id)->get_contextids();
 127          $this->assertCount(2, $contextids);
 128          $this->assertTrue(in_array($u1ctx->id, $contextids));
 129          $this->assertTrue(in_array(context_course::instance($c1->id)->id, $contextids));
 130      }
 131  
 132      /**
 133       * Test that user IDs are returned for a specificed course or module context.
 134       */
 135      public function test_get_users_in_context_course_and_module() {
 136          $user1 = $this->getDataGenerator()->create_user();
 137          $user2 = $this->getDataGenerator()->create_user();
 138          $course = $this->getDataGenerator()->create_course();
 139          $c1ctx = context_course::instance($course->id);
 140  
 141          $post = $this->create_post(['userid' => $user1->id, 'courseid' => $course->id]);
 142          $entry = new blog_entry($post->id);
 143          $entry->add_association($c1ctx->id);
 144  
 145          // Add a comment from user 2.
 146          $comment = $this->get_comment_object(context_user::instance($user1->id), $entry->id);
 147          $this->setUser($user2);
 148          $comment->add('Nice blog post');
 149  
 150          $userlist = new \core_privacy\local\request\userlist($c1ctx, 'core_blog');
 151          provider::get_users_in_context($userlist);
 152          $userids = $userlist->get_userids();
 153          $this->assertCount(2, $userids);
 154  
 155          // Add an association for a module.
 156          $cm1a = $this->getDataGenerator()->create_module('page', ['course' => $course]);
 157          $cm1ctx = context_module::instance($cm1a->cmid);
 158  
 159          $post2 = $this->create_post(['userid' => $user2->id, 'courseid' => $course->id]);
 160          $entry2 = new blog_entry($post2->id);
 161          $entry2->add_association($cm1ctx->id);
 162  
 163          $userlist = new \core_privacy\local\request\userlist($cm1ctx, 'core_blog');
 164          provider::get_users_in_context($userlist);
 165          $userids = $userlist->get_userids();
 166          $this->assertCount(1, $userids);
 167      }
 168  
 169      /**
 170       * Test that user IDs are returned for a specificed user context.
 171       */
 172      public function test_get_users_in_context_user_context() {
 173          $user1 = $this->getDataGenerator()->create_user();
 174          $user2 = $this->getDataGenerator()->create_user();
 175          $u1ctx = context_user::instance($user1->id);
 176  
 177          $post = $this->create_post(['userid' => $user1->id]);
 178          $entry = new blog_entry($post->id);
 179  
 180          // Add a comment from user 2.
 181          $comment = $this->get_comment_object($u1ctx, $entry->id);
 182          $this->setUser($user2);
 183          $comment->add('Another nice blog post');
 184  
 185          $userlist = new \core_privacy\local\request\userlist($u1ctx, 'core_blog');
 186          provider::get_users_in_context($userlist);
 187          $userids = $userlist->get_userids();
 188          $this->assertCount(2, $userids);
 189      }
 190  
 191      /**
 192       * Test that user IDs are returned for a specificed user context for an external blog.
 193       */
 194      public function test_get_users_in_context_external_blog() {
 195          $user1 = $this->getDataGenerator()->create_user();
 196          $u1ctx = context_user::instance($user1->id);
 197          $extu1 = $this->create_external_blog(['userid' => $user1->id]);
 198  
 199          $userlist = new \core_privacy\local\request\userlist($u1ctx, 'core_blog');
 200          provider::get_users_in_context($userlist);
 201          $userids = $userlist->get_userids();
 202          $this->assertCount(1, $userids);
 203      }
 204  
 205      public function test_delete_data_for_user() {
 206          global $DB;
 207  
 208          $dg = $this->getDataGenerator();
 209          $c1 = $dg->create_course();
 210          $c2 = $dg->create_course();
 211          $cm1a = $dg->create_module('page', ['course' => $c1]);
 212          $cm1b = $dg->create_module('page', ['course' => $c1]);
 213          $cm2a = $dg->create_module('page', ['course' => $c2]);
 214          $u1 = $dg->create_user();
 215          $u2 = $dg->create_user();
 216          $u3 = $dg->create_user();
 217  
 218          $c1ctx = context_course::instance($c1->id);
 219          $c2ctx = context_course::instance($c2->id);
 220          $cm1actx = context_module::instance($cm1a->cmid);
 221          $cm1bctx = context_module::instance($cm1b->cmid);
 222          $cm2actx = context_module::instance($cm2a->cmid);
 223          $u1ctx = context_user::instance($u1->id);
 224          $u2ctx = context_user::instance($u2->id);
 225  
 226          // Blog share a table with notes, so throw data in there and make sure it doesn't get deleted.
 227          $this->assertFalse($DB->record_exists('post', ['courseid' => $c1->id, 'userid' => $u1->id, 'module' => 'notes']));
 228          $dg->get_plugin_generator('core_notes')->create_instance(['userid' => $u1->id, 'courseid' => $c1->id]);
 229          $this->assertTrue($DB->record_exists('post', ['courseid' => $c1->id, 'userid' => $u1->id, 'module' => 'notes']));
 230  
 231          // Create two external blogs.
 232          $extu1 = $this->create_external_blog(['userid' => $u1->id]);
 233          $extu2 = $this->create_external_blog(['userid' => $u2->id]);
 234  
 235          // Create a set of posts.
 236          $entry = new blog_entry($this->create_post(['userid' => $u1->id])->id);
 237          $commentedon = $entry;
 238          $entry = new blog_entry($this->create_post(['userid' => $u2->id])->id);
 239  
 240          // Two course associations for u1.
 241          $entry = new blog_entry($this->create_post(['userid' => $u1->id, 'courseid' => $c1->id])->id);
 242          $entry->add_association($c1ctx->id);
 243          $entry = new blog_entry($this->create_post(['userid' => $u1->id, 'courseid' => $c1->id])->id);
 244          $entry->add_association($c1ctx->id);
 245  
 246          // Two module associations with cm1a, and 1 with cm1b for u1.
 247          $entry = new blog_entry($this->create_post(['userid' => $u1->id, 'courseid' => $c1->id])->id);
 248          $entry->add_association($cm1actx->id);
 249          $entry = new blog_entry($this->create_post(['userid' => $u1->id, 'courseid' => $c1->id])->id);
 250          $entry->add_association($cm1actx->id);
 251          $entry = new blog_entry($this->create_post(['userid' => $u1->id, 'courseid' => $c1->id])->id);
 252          $entry->add_association($cm1bctx->id);
 253  
 254          // One association for u2 in c1, cm1a and cm2a.
 255          $entry = new blog_entry($this->create_post(['userid' => $u2->id, 'courseid' => $c1->id])->id);
 256          $entry->add_association($c1ctx->id);
 257          $entry = new blog_entry($this->create_post(['userid' => $u2->id, 'courseid' => $c1->id])->id);
 258          $entry->add_association($cm1actx->id);
 259          $entry = new blog_entry($this->create_post(['userid' => $u2->id, 'courseid' => $c2->id])->id);
 260          $entry->add_association($cm2actx->id);
 261  
 262          // One association for u1 in c2 and cm2a.
 263          $entry = new blog_entry($this->create_post(['userid' => $u1->id, 'courseid' => $c2->id])->id);
 264          $entry->add_association($c2ctx->id);
 265          $entry = new blog_entry($this->create_post(['userid' => $u1->id, 'courseid' => $c2->id])->id);
 266          $entry->add_association($cm2actx->id);
 267  
 268          // Add comments.
 269          $comment = $this->get_comment_object($u1ctx, $commentedon->id);
 270          $this->setUser($u1);
 271          $comment->add('Hello, it\'s me!');
 272          $comment->add('I was wondering...');
 273          $this->setUser($u2);
 274          $comment->add('If after all these years');
 275          $this->setUser($u3);
 276          $comment->add('You\'d like to meet');
 277  
 278          // Assert current setup.
 279          $this->assertCount(6, provider::get_contexts_for_userid($u1->id)->get_contextids());
 280          $this->assertCount(9, $DB->get_records('post', ['userid' => $u1->id]));
 281          $this->assertCount(5, provider::get_contexts_for_userid($u2->id)->get_contextids());
 282          $this->assertCount(4, $DB->get_records('post', ['userid' => $u2->id]));
 283          $this->assertCount(1, $DB->get_records('blog_external', ['userid' => $u1->id]));
 284          $this->assertCount(1, $DB->get_records('blog_external', ['userid' => $u2->id]));
 285          $this->assertCount(2, $DB->get_records('comments', ['userid' => $u1->id]));
 286          $this->assertCount(1, $DB->get_records('comments', ['userid' => $u2->id]));
 287          $this->assertCount(1, $DB->get_records('comments', ['userid' => $u3->id]));
 288  
 289          // Delete for u1 in cm1a.
 290          $appctxs = new approved_contextlist($u1, 'core_blog', [$cm1actx->id]);
 291          provider::delete_data_for_user($appctxs);
 292          $contextids = provider::get_contexts_for_userid($u1->id)->get_contextids();
 293          $this->assertCount(5, $contextids);
 294          $this->assertFalse(in_array($cm1actx->id, $contextids));
 295          $this->assertCount(9, $DB->get_records('post', ['userid' => $u1->id]));
 296          $this->assertCount(5, provider::get_contexts_for_userid($u2->id)->get_contextids());
 297          $this->assertCount(4, $DB->get_records('post', ['userid' => $u2->id]));
 298          $this->assertCount(1, $DB->get_records('blog_external', ['userid' => $u1->id]));
 299          $this->assertCount(1, $DB->get_records('blog_external', ['userid' => $u2->id]));
 300          $this->assertTrue($DB->record_exists('post', ['courseid' => $c1->id, 'userid' => $u1->id, 'module' => 'notes']));
 301  
 302          // Delete for u1 in c1.
 303          $appctxs = new approved_contextlist($u1, 'core_blog', [$c1ctx->id]);
 304          provider::delete_data_for_user($appctxs);
 305          $contextids = provider::get_contexts_for_userid($u1->id)->get_contextids();
 306          $this->assertCount(4, $contextids);
 307          $this->assertFalse(in_array($c1ctx->id, $contextids));
 308          $this->assertCount(9, $DB->get_records('post', ['userid' => $u1->id]));
 309          $this->assertCount(5, provider::get_contexts_for_userid($u2->id)->get_contextids());
 310          $this->assertCount(4, $DB->get_records('post', ['userid' => $u2->id]));
 311          $this->assertCount(1, $DB->get_records('blog_external', ['userid' => $u1->id]));
 312          $this->assertCount(1, $DB->get_records('blog_external', ['userid' => $u2->id]));
 313          $this->assertTrue($DB->record_exists('post', ['courseid' => $c1->id, 'userid' => $u1->id, 'module' => 'notes']));
 314  
 315          // Delete for u1 in c2.
 316          $appctxs = new approved_contextlist($u1, 'core_blog', [$c2ctx->id]);
 317          provider::delete_data_for_user($appctxs);
 318          $contextids = provider::get_contexts_for_userid($u1->id)->get_contextids();
 319          $this->assertCount(3, $contextids);
 320          $this->assertFalse(in_array($c2ctx->id, $contextids));
 321          $this->assertCount(9, $DB->get_records('post', ['userid' => $u1->id]));
 322          $this->assertCount(5, provider::get_contexts_for_userid($u2->id)->get_contextids());
 323          $this->assertCount(4, $DB->get_records('post', ['userid' => $u2->id]));
 324          $this->assertCount(1, $DB->get_records('blog_external', ['userid' => $u1->id]));
 325          $this->assertCount(1, $DB->get_records('blog_external', ['userid' => $u2->id]));
 326          $this->assertTrue($DB->record_exists('post', ['courseid' => $c1->id, 'userid' => $u1->id, 'module' => 'notes']));
 327  
 328          // Delete for u1 in another user's context, shouldn't do anything.
 329          provider::delete_data_for_user(new approved_contextlist($u1, 'core_blog', [$u2ctx->id]));
 330          $contextids = provider::get_contexts_for_userid($u1->id)->get_contextids();
 331          $this->assertCount(3, $contextids);
 332          $this->assertFalse(in_array($c2ctx->id, $contextids));
 333          $this->assertCount(9, $DB->get_records('post', ['userid' => $u1->id]));
 334          $this->assertCount(5, provider::get_contexts_for_userid($u2->id)->get_contextids());
 335          $this->assertCount(4, $DB->get_records('post', ['userid' => $u2->id]));
 336          $this->assertCount(1, $DB->get_records('blog_external', ['userid' => $u1->id]));
 337          $this->assertCount(1, $DB->get_records('blog_external', ['userid' => $u2->id]));
 338          $this->assertTrue($DB->record_exists('post', ['courseid' => $c1->id, 'userid' => $u1->id, 'module' => 'notes']));
 339          $this->assertCount(2, $DB->get_records('comments', ['userid' => $u1->id]));
 340          $this->assertCount(1, $DB->get_records('comments', ['userid' => $u2->id]));
 341  
 342          // Delete for u2 in u1 context.
 343          provider::delete_data_for_user(new approved_contextlist($u2, 'core_blog', [$u1ctx->id]));
 344          $contextids = provider::get_contexts_for_userid($u1->id)->get_contextids();
 345          $this->assertCount(3, $contextids);
 346          $this->assertFalse(in_array($c2ctx->id, $contextids));
 347          $this->assertCount(9, $DB->get_records('post', ['userid' => $u1->id]));
 348          $this->assertCount(4, provider::get_contexts_for_userid($u2->id)->get_contextids());
 349          $this->assertCount(4, $DB->get_records('post', ['userid' => $u2->id]));
 350          $this->assertCount(1, $DB->get_records('blog_external', ['userid' => $u1->id]));
 351          $this->assertCount(1, $DB->get_records('blog_external', ['userid' => $u2->id]));
 352          $this->assertTrue($DB->record_exists('post', ['courseid' => $c1->id, 'userid' => $u1->id, 'module' => 'notes']));
 353          $this->assertCount(2, $DB->get_records('comments', ['userid' => $u1->id]));
 354          $this->assertCount(0, $DB->get_records('comments', ['userid' => $u2->id]));
 355          $this->assertCount(1, $DB->get_records('comments', ['userid' => $u3->id]));
 356  
 357          // Delete for u1 in their context.
 358          $appctxs = new approved_contextlist($u1, 'core_blog', [$u1ctx->id]);
 359          provider::delete_data_for_user($appctxs);
 360          $contextids = provider::get_contexts_for_userid($u1->id)->get_contextids();
 361          $this->assertCount(0, $contextids);
 362          $this->assertCount(1, $DB->get_records('post', ['userid' => $u1->id]));
 363          $this->assertCount(4, provider::get_contexts_for_userid($u2->id)->get_contextids());
 364          $this->assertCount(4, $DB->get_records('post', ['userid' => $u2->id]));
 365          $this->assertCount(0, $DB->get_records('blog_external', ['userid' => $u1->id]));
 366          $this->assertCount(1, $DB->get_records('blog_external', ['userid' => $u2->id]));
 367          $this->assertCount(0, $DB->get_records('comments', ['userid' => $u1->id]));
 368          $this->assertCount(0, $DB->get_records('comments', ['userid' => $u2->id]));
 369          $this->assertCount(0, $DB->get_records('comments', ['userid' => $u3->id]));
 370          $this->assertTrue($DB->record_exists('post', ['courseid' => $c1->id, 'userid' => $u1->id, 'module' => 'notes']));
 371      }
 372  
 373      /**
 374       * Test provider delete_data_for_user with a context that contains no entries
 375       *
 376       * @return void
 377       */
 378      public function test_delete_data_for_user_empty_context() {
 379          global $DB;
 380  
 381          $user = $this->getDataGenerator()->create_user();
 382          $course = $this->getDataGenerator()->create_course();
 383          $context = context_course::instance($course->id);
 384  
 385          // Create a blog entry for user, associated with course.
 386          $entry = new blog_entry($this->create_post(['userid' => $user->id, 'courseid' => $course->id])->id);
 387          $entry->add_association($context->id);
 388  
 389          // Generate list of contexts for user.
 390          $contexts = provider::get_contexts_for_userid($user->id);
 391          $this->assertContains($context->id, $contexts->get_contextids());
 392  
 393          // Now delete the blog entry.
 394          $entry->delete();
 395  
 396          // Try to delete user data using contexts obtained prior to entry deletion.
 397          $contextlist = new approved_contextlist($user, 'core_blog', $contexts->get_contextids());
 398          provider::delete_data_for_user($contextlist);
 399  
 400          // Sanity check to ensure blog_associations is really empty.
 401          $this->assertEmpty($DB->get_records('blog_association', ['contextid' => $context->id]));
 402      }
 403  
 404      public function test_delete_data_for_all_users_in_context() {
 405          global $DB;
 406  
 407          $dg = $this->getDataGenerator();
 408          $c1 = $dg->create_course();
 409          $c2 = $dg->create_course();
 410          $cm1a = $dg->create_module('page', ['course' => $c1]);
 411          $cm1b = $dg->create_module('page', ['course' => $c1]);
 412          $cm2a = $dg->create_module('page', ['course' => $c2]);
 413          $u1 = $dg->create_user();
 414          $u2 = $dg->create_user();
 415  
 416          $c1ctx = context_course::instance($c1->id);
 417          $c2ctx = context_course::instance($c2->id);
 418          $cm1actx = context_module::instance($cm1a->cmid);
 419          $cm1bctx = context_module::instance($cm1b->cmid);
 420          $cm2actx = context_module::instance($cm2a->cmid);
 421          $u1ctx = context_user::instance($u1->id);
 422  
 423          // Create two external blogs.
 424          $extu1 = $this->create_external_blog(['userid' => $u1->id]);
 425          $extu2 = $this->create_external_blog(['userid' => $u2->id]);
 426  
 427          // Create a set of posts.
 428          $entry = new blog_entry($this->create_post(['userid' => $u1->id])->id);
 429          $entry = new blog_entry($this->create_post(['userid' => $u2->id])->id);
 430  
 431          // Course associations for u1 and u2.
 432          $entry = new blog_entry($this->create_post(['userid' => $u1->id, 'courseid' => $c1->id])->id);
 433          $entry->add_association($c1ctx->id);
 434          $entry = new blog_entry($this->create_post(['userid' => $u1->id, 'courseid' => $c1->id])->id);
 435          $entry->add_association($c1ctx->id);
 436          $entry = new blog_entry($this->create_post(['userid' => $u2->id, 'courseid' => $c1->id])->id);
 437          $entry->add_association($c1ctx->id);
 438  
 439          // Module associations for u1 and u2.
 440          $entry = new blog_entry($this->create_post(['userid' => $u1->id, 'courseid' => $c1->id])->id);
 441          $entry->add_association($cm1actx->id);
 442          $entry = new blog_entry($this->create_post(['userid' => $u1->id, 'courseid' => $c1->id])->id);
 443          $entry->add_association($cm1actx->id);
 444          $entry = new blog_entry($this->create_post(['userid' => $u1->id, 'courseid' => $c1->id])->id);
 445          $entry->add_association($cm1bctx->id);
 446          $entry = new blog_entry($this->create_post(['userid' => $u2->id, 'courseid' => $c1->id])->id);
 447          $entry->add_association($cm1actx->id);
 448  
 449          // Foreign associations for u1, u2.
 450          $entry = new blog_entry($this->create_post(['userid' => $u1->id, 'courseid' => $c2->id])->id);
 451          $entry->add_association($c2ctx->id);
 452          $entry = new blog_entry($this->create_post(['userid' => $u2->id, 'courseid' => $c2->id])->id);
 453          $entry->add_association($c2ctx->id);
 454          $entry = new blog_entry($this->create_post(['userid' => $u1->id, 'courseid' => $cm2a->id])->id);
 455          $entry->add_association($cm2actx->id);
 456  
 457          // Validate what we've got.
 458          $contextids = provider::get_contexts_for_userid($u1->id)->get_contextids();
 459          $this->assertCount(8, $DB->get_records('post', ['userid' => $u1->id]));
 460          $this->assertCount(6, $contextids);
 461          $this->assertTrue(in_array($c1ctx->id, $contextids));
 462          $this->assertTrue(in_array($c2ctx->id, $contextids));
 463          $this->assertTrue(in_array($cm1actx->id, $contextids));
 464          $this->assertTrue(in_array($cm1bctx->id, $contextids));
 465          $this->assertTrue(in_array($cm2actx->id, $contextids));
 466          $this->assertTrue(in_array($u1ctx->id, $contextids));
 467          $contextids = provider::get_contexts_for_userid($u2->id)->get_contextids();
 468          $this->assertCount(4, $DB->get_records('post', ['userid' => $u2->id]));
 469          $this->assertCount(4, $contextids);
 470          $this->assertTrue(in_array($c1ctx->id, $contextids));
 471          $this->assertTrue(in_array($c2ctx->id, $contextids));
 472          $this->assertTrue(in_array($cm1actx->id, $contextids));
 473  
 474          $this->assertCount(1, $DB->get_records('blog_external', ['userid' => $u1->id]));
 475          $this->assertCount(1, $DB->get_records('blog_external', ['userid' => $u2->id]));
 476  
 477          // Delete cm1a context.
 478          provider::delete_data_for_all_users_in_context($cm1actx);
 479          $contextids = provider::get_contexts_for_userid($u1->id)->get_contextids();
 480          $this->assertCount(8, $DB->get_records('post', ['userid' => $u1->id]));
 481          $this->assertCount(5, $contextids);
 482          $this->assertTrue(in_array($c1ctx->id, $contextids));
 483          $this->assertTrue(in_array($c2ctx->id, $contextids));
 484          $this->assertFalse(in_array($cm1actx->id, $contextids));
 485          $this->assertTrue(in_array($cm1bctx->id, $contextids));
 486          $this->assertTrue(in_array($cm2actx->id, $contextids));
 487          $this->assertTrue(in_array($u1ctx->id, $contextids));
 488          $contextids = provider::get_contexts_for_userid($u2->id)->get_contextids();
 489          $this->assertCount(4, $DB->get_records('post', ['userid' => $u2->id]));
 490          $this->assertCount(3, $contextids);
 491          $this->assertTrue(in_array($c1ctx->id, $contextids));
 492          $this->assertTrue(in_array($c2ctx->id, $contextids));
 493          $this->assertFalse(in_array($cm1actx->id, $contextids));
 494  
 495          $this->assertCount(1, $DB->get_records('blog_external', ['userid' => $u1->id]));
 496          $this->assertCount(1, $DB->get_records('blog_external', ['userid' => $u2->id]));
 497  
 498          // Delete c1 context.
 499          provider::delete_data_for_all_users_in_context($c1ctx);
 500          $contextids = provider::get_contexts_for_userid($u1->id)->get_contextids();
 501          $this->assertCount(8, $DB->get_records('post', ['userid' => $u1->id]));
 502          $this->assertCount(4, $contextids);
 503          $this->assertFalse(in_array($c1ctx->id, $contextids));
 504          $this->assertTrue(in_array($c2ctx->id, $contextids));
 505          $this->assertFalse(in_array($cm1actx->id, $contextids));
 506          $this->assertTrue(in_array($cm1bctx->id, $contextids));
 507          $this->assertTrue(in_array($cm2actx->id, $contextids));
 508          $this->assertTrue(in_array($u1ctx->id, $contextids));
 509          $contextids = provider::get_contexts_for_userid($u2->id)->get_contextids();
 510          $this->assertCount(4, $DB->get_records('post', ['userid' => $u2->id]));
 511          $this->assertCount(2, $contextids);
 512          $this->assertFalse(in_array($c1ctx->id, $contextids));
 513          $this->assertTrue(in_array($c2ctx->id, $contextids));
 514          $this->assertFalse(in_array($cm1actx->id, $contextids));
 515  
 516          $this->assertCount(1, $DB->get_records('blog_external', ['userid' => $u1->id]));
 517          $this->assertCount(1, $DB->get_records('blog_external', ['userid' => $u2->id]));
 518  
 519          // Delete u1 context.
 520          provider::delete_data_for_all_users_in_context($u1ctx);
 521          $contextids = provider::get_contexts_for_userid($u1->id)->get_contextids();
 522          $this->assertCount(0, $DB->get_records('post', ['userid' => $u1->id]));
 523          $this->assertCount(0, $contextids);
 524          $this->assertFalse(in_array($c1ctx->id, $contextids));
 525          $this->assertFalse(in_array($c2ctx->id, $contextids));
 526          $this->assertFalse(in_array($cm1actx->id, $contextids));
 527          $this->assertFalse(in_array($cm1bctx->id, $contextids));
 528          $this->assertFalse(in_array($cm2actx->id, $contextids));
 529          $this->assertFalse(in_array($u1ctx->id, $contextids));
 530          $contextids = provider::get_contexts_for_userid($u2->id)->get_contextids();
 531          $this->assertCount(4, $DB->get_records('post', ['userid' => $u2->id]));
 532          $this->assertCount(2, $contextids);
 533          $this->assertFalse(in_array($c1ctx->id, $contextids));
 534          $this->assertTrue(in_array($c2ctx->id, $contextids));
 535          $this->assertFalse(in_array($cm1actx->id, $contextids));
 536  
 537          $this->assertCount(0, $DB->get_records('blog_external', ['userid' => $u1->id]));
 538          $this->assertCount(1, $DB->get_records('blog_external', ['userid' => $u2->id]));
 539      }
 540  
 541      public function test_export_data_for_user() {
 542          global $DB;
 543          $dg = $this->getDataGenerator();
 544  
 545          $c1 = $dg->create_course();
 546          $cm1a = $dg->create_module('page', ['course' => $c1]);
 547          $cm1b = $dg->create_module('page', ['course' => $c1]);
 548          $u1 = $dg->create_user();
 549          $u2 = $dg->create_user();
 550          $c1ctx = context_course::instance($c1->id);
 551          $cm1actx = context_module::instance($cm1a->cmid);
 552          $cm1bctx = context_module::instance($cm1b->cmid);
 553          $u1ctx = context_user::instance($u1->id);
 554          $u2ctx = context_user::instance($u2->id);
 555  
 556          // System entries.
 557          $e1 = new blog_entry($this->create_post(['userid' => $u1->id, 'subject' => 'Hello world!',
 558              'publishstate' => 'public'])->id);
 559          $e2 = new blog_entry($this->create_post(['userid' => $u1->id, 'subject' => 'Hi planet!',
 560              'publishstate' => 'draft'])->id);
 561          $e3 = new blog_entry($this->create_post(['userid' => $u2->id, 'subject' => 'Ignore me'])->id);
 562  
 563          // Create a blog entry associated with contexts.
 564          $e4 = new blog_entry($this->create_post(['userid' => $u1->id, 'courseid' => $c1->id, 'subject' => 'Course assoc'])->id);
 565          $e4->add_association($c1ctx->id);
 566          $e4b = new blog_entry($this->create_post(['userid' => $u1->id, 'courseid' => $c1->id, 'subject' => 'Course assoc 2'])->id);
 567          $e4b->add_association($c1ctx->id);
 568          $e5 = new blog_entry($this->create_post(['userid' => $u1->id, 'courseid' => $c1->id, 'subject' => 'Module assoc',
 569              'publishstate' => 'public'])->id);
 570          $e5->add_association($cm1actx->id);
 571          $e5b = new blog_entry($this->create_post(['userid' => $u1->id, 'courseid' => $c1->id, 'subject' => 'C/CM assoc'])->id);
 572          $e5b->add_association($c1ctx->id);
 573          $e5b->add_association($cm1actx->id);
 574          $e6 = new blog_entry($this->create_post(['userid' => $u2->id, 'courseid' => $c1->id, 'subject' => 'Module assoc'])->id);
 575          $e6->add_association($cm1actx->id);
 576  
 577          // External blogs.
 578          $ex1 = $this->create_external_blog(['userid' => $u1->id, 'url' => 'https://moodle.org', 'name' => 'Moodle RSS']);
 579          $ex2 = $this->create_external_blog(['userid' => $u1->id, 'url' => 'https://example.com', 'name' => 'Example']);
 580          $ex3 = $this->create_external_blog(['userid' => $u2->id, 'url' => 'https://example.com', 'name' => 'Ignore me']);
 581  
 582          // Attach tags.
 583          core_tag_tag::set_item_tags('core', 'post', $e1->id, $u1ctx, ['Beer', 'Golf']);
 584          core_tag_tag::set_item_tags('core', 'blog_external', $ex1->id, $u1ctx, ['Car', 'Golf']);
 585          core_tag_tag::set_item_tags('core', 'post', $e3->id, $u2ctx, ['ITG']);
 586          core_tag_tag::set_item_tags('core', 'blog_external', $ex3->id, $u2ctx, ['DDR']);
 587          core_tag_tag::set_item_tags('core', 'dontfindme', $e1->id, $u1ctx, ['Lone tag']);
 588  
 589          // Attach comments.
 590          $comment = $this->get_comment_object($u1ctx, $e1->id);
 591          $this->setUser($u1);
 592          $comment->add('Hello, it\'s me!');
 593          $this->setUser($u2);
 594          $comment->add('I was wondering if after');
 595          $this->setUser($u1);
 596          $comment = $this->get_comment_object($u2ctx, $e3->id);
 597          $comment->add('All these years');
 598  
 599          // Blog share a table with notes, so throw some data in there, it should not be exported.
 600          $note = $dg->get_plugin_generator('core_notes')->create_instance(['userid' => $u1->id, 'courseid' => $c1->id,
 601              'subject' => 'ABC']);
 602  
 603          // Validate module associations.
 604          $contextlist = new approved_contextlist($u1, 'core_blog', [$cm1actx->id]);
 605          provider::export_user_data($contextlist);
 606          $writer = writer::with_context($cm1actx);
 607          $assocs = $writer->get_data([get_string('privacy:path:blogassociations', 'core_blog')]);
 608          $this->assertCount(2, $assocs->associations);
 609          $this->assertTrue(in_array('Module assoc', $assocs->associations));
 610          $this->assertTrue(in_array('C/CM assoc', $assocs->associations));
 611  
 612          // Validate course associations.
 613          $contextlist = new approved_contextlist($u1, 'core_blog', [$c1ctx->id]);
 614          provider::export_user_data($contextlist);
 615          $writer = writer::with_context($c1ctx);
 616          $assocs = $writer->get_data([get_string('privacy:path:blogassociations', 'core_blog')]);
 617          $this->assertCount(3, $assocs->associations);
 618          $this->assertTrue(in_array('Course assoc', $assocs->associations));
 619          $this->assertTrue(in_array('Course assoc 2', $assocs->associations));
 620          $this->assertTrue(in_array('C/CM assoc', $assocs->associations));
 621  
 622          // Confirm we're not exporting for another user.
 623          $contextlist = new approved_contextlist($u2, 'core_blog', [$u2ctx->id]);
 624          $writer = writer::with_context($u1ctx);
 625          $this->assertFalse($writer->has_any_data());
 626  
 627          // Now export user context for u2.
 628          $this->setUser($u2);
 629          $contextlist = new approved_contextlist($u2, 'core_blog', [$u1ctx->id]);
 630          provider::export_user_data($contextlist);
 631          $writer = writer::with_context($u1ctx);
 632          $data = $writer->get_data([get_string('blog', 'core_blog'), get_string('externalblogs', 'core_blog'),
 633              $ex1->name . " ({$ex1->id})"]);
 634          $this->assertEmpty($data);
 635          $data = $writer->get_data([get_string('blog', 'core_blog'), get_string('blogentries', 'core_blog'),
 636              $e2->subject . " ({$e2->id})"]);
 637          $this->assertEmpty($data);
 638          $data = $writer->get_data([get_string('blog', 'core_blog'), get_string('blogentries', 'core_blog'),
 639              $e1->subject . " ({$e1->id})"]);
 640          $this->assertEmpty($data);
 641          $data = $writer->get_data([get_string('blog', 'core_blog'), get_string('blogentries', 'core_blog'),
 642              $e1->subject . " ({$e1->id})", get_string('commentsubcontext', 'core_comment')]);
 643          $this->assertNotEmpty($data);
 644          $this->assertCount(1, $data->comments);
 645          $comment = array_shift($data->comments);
 646          $this->assertEquals('I was wondering if after', strip_tags($comment->content));
 647  
 648          // Now export user context data.
 649          $this->setUser($u1);
 650          $contextlist = new approved_contextlist($u1, 'core_blog', [$u1ctx->id]);
 651          writer::reset();
 652          provider::export_user_data($contextlist);
 653          $writer = writer::with_context($u1ctx);
 654  
 655          // Check external blogs.
 656          $externals = [$ex1, $ex2];
 657          foreach ($externals as $ex) {
 658              $data = $writer->get_data([get_string('blog', 'core_blog'), get_string('externalblogs', 'core_blog'),
 659                  $ex->name . " ({$ex->id})"]);
 660              $this->assertNotEmpty($data);
 661              $this->assertEquals($data->name, $ex->name);
 662              $this->assertEquals($data->description, $ex->description);
 663              $this->assertEquals($data->url, $ex->url);
 664              $this->assertEquals($data->filtertags, $ex->filtertags);
 665              $this->assertEquals($data->modified, transform::datetime($ex->timemodified));
 666              $this->assertEquals($data->lastfetched, transform::datetime($ex->timefetched));
 667          }
 668  
 669          // Check entries.
 670          $entries = [$e1, $e2, $e4, $e4b, $e5, $e5b];
 671          $associations = [
 672              $e1->id => null,
 673              $e2->id => null,
 674              $e4->id => $c1ctx->get_context_name(),
 675              $e4b->id => $c1ctx->get_context_name(),
 676              $e5->id => $cm1actx->get_context_name(),
 677              $e5b->id => [$c1ctx->get_context_name(), $cm1actx->get_context_name()],
 678          ];
 679          foreach ($entries as $e) {
 680              $path = [get_string('blog', 'core_blog'), get_string('blogentries', 'core_blog'), $e->subject . " ({$e->id})"];
 681              $data = $writer->get_data($path);
 682              $this->assertNotEmpty($data);
 683              $this->assertEquals($data->subject, $e->subject);
 684              $this->assertEquals($data->summary, $e->summary);
 685              $this->assertEquals($data->publishstate, provider::transform_publishstate($e->publishstate));
 686              $this->assertEquals($data->created, transform::datetime($e->created));
 687              $this->assertEquals($data->lastmodified, transform::datetime($e->lastmodified));
 688  
 689              // We attached comments and tags to this entry.
 690              $commentpath = array_merge($path, [get_string('commentsubcontext', 'core_comment')]);
 691              if ($e->id == $e1->id) {
 692                  $tagdata = $writer->get_related_data($path, 'tags');
 693                  $this->assertEquals(['Beer', 'Golf'], $tagdata, '', 0, 10, true);
 694  
 695                  $comments = $writer->get_data($commentpath);
 696                  $this->assertCount(2, $comments->comments);
 697  
 698                  $c0 = strip_tags($comments->comments[0]->content);
 699                  $c1 = strip_tags($comments->comments[1]->content);
 700                  $expectedcomments = [
 701                      'Hello, it\'s me!',
 702                      'I was wondering if after',
 703                  ];
 704  
 705                  $this->assertNotFalse(array_search($c0, $expectedcomments));
 706                  $this->assertNotFalse(array_search($c1, $expectedcomments));
 707                  $this->assertNotEquals($c0, $c1);
 708  
 709              } else {
 710                  $tagdata = $writer->get_related_data($path, 'tags');
 711                  $this->assertEmpty($tagdata);
 712                  $comments = $writer->get_data($commentpath);
 713                  $this->assertEmpty($comments);
 714              }
 715  
 716              if (isset($associations[$e->id])) {
 717                  $assocs = $associations[$e->id];
 718                  if (is_array($assocs)) {
 719                      $this->assertCount(count($assocs), $data->associations);
 720                      foreach ($assocs as $v) {
 721                          $this->assertTrue(in_array($v, $data->associations));
 722                      }
 723                  } else {
 724                      $this->assertCount(1, $data->associations);
 725                      $this->assertTrue(in_array($assocs, $data->associations));
 726                  }
 727              }
 728          }
 729  
 730          // The note was not exported.
 731          $path = [get_string('blog', 'core_blog'), get_string('blogentries', 'core_blog'), "ABC ($note->id)"];
 732          $this->assertEmpty($writer->get_data($path));
 733  
 734      }
 735  
 736      /**
 737       * Test that deleting of blog information in a user context works as desired.
 738       */
 739      public function test_delete_data_for_users_user_context() {
 740          global $DB;
 741  
 742          $u1 = $this->getDataGenerator()->create_user();
 743          $u2 = $this->getDataGenerator()->create_user();
 744          $u3 = $this->getDataGenerator()->create_user();
 745          $u4 = $this->getDataGenerator()->create_user();
 746          $u5 = $this->getDataGenerator()->create_user();
 747  
 748          $u1ctx = context_user::instance($u1->id);
 749  
 750          $post = $this->create_post(['userid' => $u1->id]);
 751          $entry = new blog_entry($post->id);
 752  
 753          $comment = $this->get_comment_object($u1ctx, $entry->id);
 754          $this->setUser($u1);
 755          $comment->add('Hello, I created the blog');
 756          $this->setUser($u2);
 757          $comment->add('User 2 making a comment.');
 758          $this->setUser($u3);
 759          $comment->add('User 3 here.');
 760          $this->setUser($u4);
 761          $comment->add('User 4 is nice.');
 762          $this->setUser($u5);
 763          $comment->add('User 5 for the win.');
 764  
 765          // This will only delete the comments made by user 4 and 5.
 766          $this->assertCount(5, $DB->get_records('comments', ['contextid' => $u1ctx->id]));
 767          $userlist = new \core_privacy\local\request\approved_userlist($u1ctx, 'core_blog', [$u4->id, $u5->id]);
 768          provider::delete_data_for_users($userlist);
 769          $this->assertCount(3, $DB->get_records('comments', ['contextid' => $u1ctx->id]));
 770          $this->assertCount(1, $DB->get_records('post', ['userid' => $u1->id]));
 771  
 772          // As the owner of the post is here everything will be deleted.
 773          $userlist = new \core_privacy\local\request\approved_userlist($u1ctx, 'core_blog', [$u1->id, $u2->id]);
 774          provider::delete_data_for_users($userlist);
 775          $this->assertEmpty($DB->get_records('comments', ['contextid' => $u1ctx->id]));
 776          $this->assertEmpty($DB->get_records('post', ['userid' => $u1->id]));
 777      }
 778  
 779      /**
 780       * Test that deleting of an external blog in a user context works as desired.
 781       */
 782      public function test_delete_data_for_users_external_blog() {
 783          global $DB;
 784  
 785          $u1 = $this->getDataGenerator()->create_user();
 786          $u2 = $this->getDataGenerator()->create_user();
 787  
 788          $u1ctx = context_user::instance($u1->id);
 789          $u2ctx = context_user::instance($u2->id);
 790  
 791          $post = $this->create_external_blog(['userid' => $u1->id, 'url' => 'https://moodle.org', 'name' => 'Moodle RSS']);
 792          $post2 = $this->create_external_blog(['userid' => $u2->id, 'url' => 'https://moodle.com', 'name' => 'Some other thing']);
 793  
 794          // Check that we have two external blogs created.
 795          $this->assertCount(2, $DB->get_records('blog_external'));
 796          // This will only delete the external blog for user 1.
 797          $userlist = new \core_privacy\local\request\approved_userlist($u1ctx, 'core_blog', [$u1->id, $u2->id]);
 798          provider::delete_data_for_users($userlist);
 799          $this->assertCount(1, $DB->get_records('blog_external'));
 800      }
 801  
 802      public function test_delete_data_for_users_course_and_module_context() {
 803          global $DB;
 804  
 805          $u1 = $this->getDataGenerator()->create_user();
 806          $u2 = $this->getDataGenerator()->create_user();
 807          $u3 = $this->getDataGenerator()->create_user();
 808          $u4 = $this->getDataGenerator()->create_user();
 809          $u5 = $this->getDataGenerator()->create_user();
 810  
 811          $course = $this->getDataGenerator()->create_course();
 812          $module = $this->getDataGenerator()->create_module('page', ['course' => $course]);
 813  
 814          $u1ctx = context_user::instance($u1->id);
 815          $u3ctx = context_user::instance($u3->id);
 816          $c1ctx = context_course::instance($course->id);
 817          $cm1ctx = context_module::instance($module->cmid);
 818  
 819          // Blog with course association.
 820          $post1 = $this->create_post(['userid' => $u1->id, 'courseid' => $course->id]);
 821          $entry1 = new blog_entry($post1->id);
 822          $entry1->add_association($c1ctx->id);
 823  
 824          // Blog with module association.
 825          $post2 = $this->create_post(['userid' => $u3->id, 'courseid' => $course->id]);
 826          $entry2 = new blog_entry($post2->id);
 827          $entry2->add_association($cm1ctx->id);
 828  
 829          $comment = $this->get_comment_object($u1ctx, $entry1->id);
 830          $this->setUser($u1);
 831          $comment->add('Hello, I created the blog');
 832          $this->setUser($u2);
 833          $comment->add('comment on first course blog');
 834          $this->setUser($u4);
 835          $comment->add('user 4 on course blog');
 836  
 837          $comment = $this->get_comment_object($u3ctx, $entry2->id);
 838          $this->setUser($u3);
 839          $comment->add('Hello, I created the module blog');
 840          $this->setUser($u2);
 841          $comment->add('I am commenting on both');
 842          $this->setUser($u5);
 843          $comment->add('User 5 for modules');
 844  
 845          $this->assertCount(6, $DB->get_records('comments', ['component' => 'blog']));
 846          $this->assertCount(2, $DB->get_records('post', ['courseid' => $course->id]));
 847          $this->assertCount(2, $DB->get_records('blog_association'));
 848  
 849          // When using the course or module context we are only removing the blog associations and the comments.
 850          $userlist = new \core_privacy\local\request\approved_userlist($c1ctx, 'core_blog', [$u2->id, $u1->id, $u5->id]);
 851          provider::delete_data_for_users($userlist);
 852          // Only one of the blog_associations should be removed. Everything else should be as before.
 853          $this->assertCount(6, $DB->get_records('comments', ['component' => 'blog']));
 854          $this->assertCount(2, $DB->get_records('post', ['courseid' => $course->id]));
 855          $this->assertCount(1, $DB->get_records('blog_association'));
 856  
 857          $userlist = new \core_privacy\local\request\approved_userlist($cm1ctx, 'core_blog', [$u2->id, $u1->id, $u3->id]);
 858          provider::delete_data_for_users($userlist);
 859          // Now we've removed the other association.
 860          $this->assertCount(6, $DB->get_records('comments', ['component' => 'blog']));
 861          $this->assertCount(2, $DB->get_records('post', ['courseid' => $course->id]));
 862          $this->assertEmpty($DB->get_records('blog_association'));
 863      }
 864  
 865      /**
 866       * Create a blog post.
 867       *
 868       * @param array $params The params.
 869       * @return stdClass
 870       */
 871      protected function create_post(array $params) {
 872          global $DB;
 873          $post = new stdClass();
 874          $post->module = 'blog';
 875          $post->courseid = 0;
 876          $post->subject = 'the test post';
 877          $post->summary = 'test post summary text';
 878          $post->summaryformat = FORMAT_PLAIN;
 879          $post->publishstate = 'site';
 880          $post->created = time() - HOURSECS;
 881          $post->lastmodified = time();
 882          foreach ($params as $key => $value) {
 883              $post->{$key} = $value;
 884          }
 885  
 886          $post->id = $DB->insert_record('post', $post);
 887          return $post;
 888      }
 889  
 890      /**
 891       * Create an extenral blog.
 892       *
 893       * @param array $params The params.
 894       * @return stdClass
 895       */
 896      protected function create_external_blog(array $params) {
 897          global $DB;
 898          $post = new stdClass();
 899          $post->name = 'test external';
 900          $post->description = 'the description';
 901          $post->url = 'http://example.com';
 902          $post->filtertags = 'a, c, b';
 903          $post->timefetched = time() - HOURSECS;
 904          $post->timemodified = time();
 905          foreach ($params as $key => $value) {
 906              $post->{$key} = $value;
 907          }
 908          $post->id = $DB->insert_record('blog_external', $post);
 909          return $post;
 910      }
 911  
 912      /**
 913       * Get the comment area.
 914       *
 915       * @param context $context The context.
 916       * @param int $itemid The item ID.
 917       * @param string $component The component.
 918       * @param string $area The area.
 919       * @return comment
 920       */
 921      protected function get_comment_object(context $context, $itemid) {
 922          $args = new stdClass();
 923          $args->context = $context;
 924          $args->course = get_course(SITEID);
 925          $args->area = 'format_blog';
 926          $args->itemid = $itemid;
 927          $args->component = 'blog';
 928          $comment = new comment($args);
 929          $comment->set_post_permission(true);
 930          return $comment;
 931      }
 932  }