/**
  * Lists all files in a playspace.
  * @param string $playspaceid ID of playspace (two comma-separated numbers)
  * @param bool $duplicates If true, actually lists duplicate files
  * @return array Array of full names including paths
  */
 static function get_attachment_playspace_files($playspaceid, $duplicates)
 {
     $folder = self::get_attachment_playspace_folder($playspaceid);
     if ($duplicates) {
         self::delete_attachment_playspace($playspaceid, true);
         forum_utils::mkdir("{$folder}/" . self::DUPLICATESFOLDER);
     }
     $handle = forum_utils::opendir($folder);
     $result = array();
     while (false !== ($name = readdir($handle))) {
         if ($name != '.' && $name != '..' && $name != self::DUPLICATESFOLDER) {
             $path = "{$folder}/{$name}";
             if ($duplicates) {
                 $duplicate = "{$folder}/" . self::DUPLICATESFOLDER . "/{$name}";
                 forum_utils::copy($path, $duplicate);
                 $result[] = $duplicate;
             } else {
                 $result[] = $path;
             }
         }
     }
     closedir($handle);
     return $result;
 }
 /**
  * Edits an existing message. The previous version of the message is
  * retained for admins to view if needed.
  * @param string $subject Subject
  * @param string $message Message
  * @param int $format Moodle format ID
  * @param mixed $deleteattachments Array of names (only) of existing 
  *   attachments to delete, or 'true' to delete all
  * @param array $newattachments Additional attachments to add (if any)
  * @param bool $setimportant If true, highlight the post
  * @param bool $mailnow New value of mailnow flag (ignored if message was already mailed)
  * @param int $userid Userid doing the editing (0 = current)
  */
 function edit($subject, $message, $format, $deleteattachments = array(), $newattachments = array(), $setimportant = false, $mailnow = false, $userid = 0, $log = true)
 {
     $now = time();
     // Create copy of existing entry ('old version')
     $copy = clone $this->postfields;
     $copy->subject = is_null($copy->subject) ? null : addslashes($copy->subject);
     $copy->message = addslashes($copy->message);
     // Copy has oldversion set to 1 and parentpost set to id of real post
     $copy->oldversion = 1;
     $copy->parentpostid = $copy->id;
     unset($copy->id);
     // OK, add copy
     forum_utils::start_transaction();
     $copyid = forum_utils::insert_record('forumng_posts', $copy);
     // If there are attachments...
     $attachments = $this->get_attachment_names();
     $copiedattachments = 0;
     if ($attachments) {
         // NOTE: The names are confusing. $newfolder is the EXISTING folder
         // but it relates to the attachments for the NEW version of the
         // post. $oldfolder is a newly-created folder but it relates to
         // attachments for the OLD version of the posdt
         $newfolder = $this->get_attachment_folder();
         $oldfolder = $this->get_attachment_folder($copyid);
         // Copy the attachments folder to an 'old' historic one, then
         // delete files from the current attachment folder. This used to be
         // done with rename but we experienced failures when creating the
         // folder with the same name as the one we just renamed away.
         forum_utils::mkdir($oldfolder);
         $handle = forum_utils::opendir($newfolder);
         $keepfolder = false;
         while (false !== ($name = readdir($handle))) {
             if ($name != '.' && $name != '..') {
                 $source = "{$newfolder}/{$name}";
                 // Copy file to the 'old' version folder
                 forum_utils::copy($source, "{$oldfolder}/{$name}");
                 // Consider whether it should be deleted from the 'new'
                 // version folder
                 if ($deleteattachments === true || $deleteattachments && in_array($name, $deleteattachments)) {
                     forum_utils::unlink($source);
                 } else {
                     $keepfolder = true;
                     $copiedattachments++;
                 }
             }
         }
         closedir($handle);
         if (!$keepfolder) {
             forum_utils::rmdir($newfolder);
         }
     }
     // Update existing entry with new data where it changed
     $update = new StdClass();
     $gotsubject = false;
     if ($subject !== $this->postfields->subject) {
         $update->subject = strlen(trim($subject)) == 0 ? null : addslashes($subject);
         $gotsubject = true;
     }
     if ($message !== $this->postfields->message) {
         $update->message = addslashes($message);
     }
     if ($format != $this->postfields->format) {
         $update->format = $format;
     }
     if ($copiedattachments == 0 && count($newattachments) == 0 && $this->postfields->attachments) {
         $update->attachments = 0;
     } else {
         if (count($newattachments) > 0 && !$this->postfields->attachments) {
             $update->attachments = 1;
         }
     }
     if ($setimportant) {
         $update->important = 1;
     } else {
         $update->important = 0;
     }
     if ($this->postfields->mailstate == forum::MAILSTATE_NOT_MAILED && $mailnow) {
         $update->mailstate = forum::MAILSTATE_NOW_NOT_MAILED;
     } else {
         if ($this->postfields->mailstate == forum::MAILSTATE_NOW_NOT_MAILED && !$mailnow) {
             $update->mailstate = forum::MAILSTATE_NOT_MAILED;
         }
     }
     $update->modified = $now;
     $update->edituserid = forum_utils::get_real_userid($userid);
     if (count((array) $update) > 0) {
         $update->id = $this->postfields->id;
         forum_utils::update_record('forumng_posts', $update);
     }
     // Add new attachments
     foreach ($newattachments as $path) {
         $this->add_attachment($path);
     }
     if ($log) {
         $this->log('edit post');
     }
     // Update in-memory representation
     foreach ((array) $update as $name => $value) {
         $this->postfields->{$name} = $value === null ? null : stripslashes($value);
     }
     // If this is the root post, then changing its subject affects
     // the discussion subhject
     if ($this->is_root_post() && $gotsubject) {
         $this->discussion->hack_subject($this->postfields->subject);
     }
     // Uncache before updating search (want to make sure that the recursive
     // update gets latest data)
     $this->get_discussion()->uncache();
     // Update search index
     if (isset($update->message) || $gotsubject) {
         // Update for this post
         $this->search_update();
         // If changing the subject of a root post, update all posts in the
         // discussion (ugh)
         if ($this->is_root_post() && $gotsubject) {
             $this->search_update_children();
         }
     }
     forum_utils::finish_transaction();
 }