Example #1
0
 /**
  * helper function to get the html content of an entry
  * for both this class and the full glossary exporter
  * this is a very simplified version of the dictionary format output,
  * but with its 500 levels of indirection removed
  * and file rewriting handled by the portfolio export format.
  *
  * @param stdclass $course
  * @param stdclass $cm
  * @param stdclass $glossary
  * @param stdclass $entry
  *
  * @return string
  */
 public static function entry_content($course, $cm, $glossary, $entry, $aliases, $format)
 {
     global $OUTPUT, $DB;
     $entry = clone $entry;
     $context = get_context_instance(CONTEXT_MODULE, $cm->id);
     $options = portfolio_format_text_options();
     $options->trusted = $entry->definitiontrust;
     $options->context = $context;
     $output = '<table class="glossarypost dictionary" cellspacing="0">' . "\n";
     $output .= '<tr valign="top">' . "\n";
     $output .= '<td class="entry">' . "\n";
     $output .= '<div class="concept">';
     $output .= format_text($OUTPUT->heading($entry->concept, 3), FORMAT_MOODLE, $options);
     $output .= '</div> ' . "\n";
     $entry->definition = format_text($entry->definition, $entry->definitionformat, $options);
     $output .= portfolio_rewrite_pluginfile_urls($entry->definition, $context->id, 'mod_glossary', 'entry', $entry->id, $format);
     if (isset($entry->footer)) {
         $output .= $entry->footer;
     }
     $output .= '</td></tr>' . "\n";
     if (!empty($aliases)) {
         $aliases = explode(',', $aliases->alias);
         $output .= '<tr valign="top"><td class="entrylowersection">';
         $key = count($aliases) == 1 ? 'alias' : 'aliases';
         $output .= get_string($key, 'glossary') . ': ';
         foreach ($aliases as $alias) {
             $output .= s($alias) . ',';
         }
         $output = substr($output, 0, -1);
         $output .= '</td></tr>' . "\n";
     }
     if ($entry->sourceglossaryid == $cm->instance) {
         if (!($maincm = get_coursemodule_from_instance('glossary', $entry->glossaryid))) {
             return '';
         }
         $filecontext = get_context_instance(CONTEXT_MODULE, $maincm->id);
     } else {
         $filecontext = $context;
     }
     $fs = get_file_storage();
     if ($files = $fs->get_area_files($filecontext->id, 'mod_glossary', 'attachment', $entry->id, "timemodified", false)) {
         $output .= '<table border="0" width="100%"><tr><td>' . "\n";
         foreach ($files as $file) {
             $output .= $format->file_output($file);
         }
         $output .= '</td></tr></table>' . "\n";
     }
     $output .= '</table>' . "\n";
     return $output;
 }
Example #2
0
 /**
  * Prepares the package up before control is passed to the portfolio plugin.
  *
  * @throws portfolio_caller_exception
  * @return mixed
  */
 public function prepare_package()
 {
     if ($this->plugin && $this->editor) {
         $options = portfolio_format_text_options();
         $context = context_module::instance($this->cmid);
         $options->context = $context;
         $plugin = $this->get_submission_plugin();
         $text = $plugin->get_editor_text($this->editor, $this->sid);
         $format = $plugin->get_editor_format($this->editor, $this->sid);
         $html = format_text($text, $format, $options);
         $html = portfolio_rewrite_pluginfile_urls($html, $context->id, 'mod_assign', $this->area, $this->sid, $this->exporter->get('format'));
         $exporterclass = $this->exporter->get('formatclass');
         if (in_array($exporterclass, array(PORTFOLIO_FORMAT_PLAINHTML, PORTFOLIO_FORMAT_RICHHTML))) {
             if ($files = $this->exporter->get('caller')->get('multifiles')) {
                 foreach ($files as $file) {
                     $this->exporter->copy_existing_file($file);
                 }
             }
             return $this->exporter->write_new_file($html, 'assignment.html', !empty($files));
         } else {
             if ($this->exporter->get('formatclass') == PORTFOLIO_FORMAT_LEAP2A) {
                 $leapwriter = $this->exporter->get('format')->leap2a_writer();
                 $entry = new portfolio_format_leap2a_entry($this->area . $this->cmid, $context->get_context_name(), 'resource', $html);
                 $entry->add_category('web', 'resource_type');
                 $entry->author = $this->user;
                 $leapwriter->add_entry($entry);
                 if ($files = $this->exporter->get('caller')->get('multifiles')) {
                     $leapwriter->link_files($entry, $files, $this->area . $this->cmid . 'file');
                     foreach ($files as $file) {
                         $this->exporter->copy_existing_file($file);
                     }
                 }
                 return $this->exporter->write_new_file($leapwriter->to_xml(), $this->exporter->get('format')->manifest_name(), true);
             } else {
                 debugging('invalid format class: ' . $this->exporter->get('formatclass'));
             }
         }
     }
     if ($this->exporter->get('formatclass') == PORTFOLIO_FORMAT_LEAP2A) {
         $leapwriter = $this->exporter->get('format')->leap2a_writer();
         $files = array();
         if ($this->singlefile) {
             $files[] = $this->singlefile;
         } else {
             if ($this->multifiles) {
                 $files = $this->multifiles;
             } else {
                 throw new portfolio_caller_exception('invalidpreparepackagefile', 'portfolio', $this->get_return_url());
             }
         }
         $entryids = array();
         foreach ($files as $file) {
             $entry = new portfolio_format_leap2a_file($file->get_filename(), $file);
             $entry->author = $this->user;
             $leapwriter->add_entry($entry);
             $this->exporter->copy_existing_file($file);
             $entryids[] = $entry->id;
         }
         if (count($files) > 1) {
             $baseid = 'assign' . $this->cmid . $this->area;
             $context = context_module::instance($this->cmid);
             // If we have multiple files, they should be grouped together into a folder.
             $entry = new portfolio_format_leap2a_entry($baseid . 'group', $context->get_context_name(), 'selection');
             $leapwriter->add_entry($entry);
             $leapwriter->make_selection($entry, $entryids, 'Folder');
         }
         return $this->exporter->write_new_file($leapwriter->to_xml(), $this->exporter->get('format')->manifest_name(), true);
     }
     return $this->prepare_package_file();
 }
Example #3
0
 /**
  * this is a very cut down version of what is in forum_make_mail_post
  *
  * @global object
  * @param int $post
  * @return string
  */
 private function prepare_post($post, $fileoutputextras = null)
 {
     global $DB;
     static $users;
     if (empty($users)) {
         $users = array($this->user->id => $this->user);
     }
     if (!array_key_exists($post->userid, $users)) {
         $users[$post->userid] = $DB->get_record('user', array('id' => $post->userid));
     }
     // add the user object on to the post so we can pass it to the leap writer if necessary
     $post->author = $users[$post->userid];
     $viewfullnames = true;
     // format the post body
     $options = portfolio_format_text_options();
     $format = $this->get('exporter')->get('format');
     $formattedtext = format_text($post->message, $post->messageformat, $options, $this->get('course')->id);
     $formattedtext = portfolio_rewrite_pluginfile_urls($formattedtext, $this->modcontext->id, 'mod_forum', 'post', $post->id, $format);
     $output = '<table border="0" cellpadding="3" cellspacing="0" class="forumpost">';
     $output .= '<tr class="header"><td>';
     // can't print picture.
     $output .= '</td>';
     if ($post->parent) {
         $output .= '<td class="topic">';
     } else {
         $output .= '<td class="topic starter">';
     }
     $output .= '<div class="subject">' . format_string($post->subject) . '</div>';
     $fullname = fullname($users[$post->userid], $viewfullnames);
     $by = new stdClass();
     $by->name = $fullname;
     $by->date = userdate($post->modified, '', $this->user->timezone);
     $output .= '<div class="author">' . get_string('bynameondate', 'forum', $by) . '</div>';
     $output .= '</td></tr>';
     $output .= '<tr><td class="left side" valign="top">';
     $output .= '</td><td class="content">';
     $output .= $formattedtext;
     if (is_array($this->keyedfiles) && array_key_exists($post->id, $this->keyedfiles) && is_array($this->keyedfiles[$post->id]) && count($this->keyedfiles[$post->id]) > 0) {
         $output .= '<div class="attachments">';
         $output .= '<br /><b>' . get_string('attachments', 'forum') . '</b>:<br /><br />';
         foreach ($this->keyedfiles[$post->id] as $file) {
             $output .= $format->file_output($file) . '<br/ >';
         }
         $output .= "</div>";
     }
     $output .= '</td></tr></table>' . "\n\n";
     return $output;
 }
Example #4
0
 function portfolio_prepare_package($exporter, $user)
 {
     $submission = $this->get_submission($user->id);
     $options = new stdClass();
     $options->para = false;
     $options->filter = false;
     $html = format_text($submission->data1, $submission->data2, $options);
     $html = portfolio_rewrite_pluginfile_urls($html, $this->context->id, 'mod_assignment', $this->filearea, $submission->id, $exporter->get('format'));
     if (in_array($exporter->get('formatclass'), array(PORTFOLIO_FORMAT_PLAINHTML, PORTFOLIO_FORMAT_RICHHTML))) {
         if ($files = $exporter->get('caller')->get('multifiles')) {
             foreach ($files as $f) {
                 $exporter->copy_existing_file($f);
             }
         }
         return $exporter->write_new_file($html, 'assignment.html', !empty($files));
     } else {
         if ($exporter->get('formatclass') == PORTFOLIO_FORMAT_LEAP2A) {
             $leapwriter = $exporter->get('format')->leap2a_writer();
             $entry = new portfolio_format_leap2a_entry('assignmentonline' . $this->assignment->id, $this->assignment->name, 'resource', $html);
             $entry->add_category('web', 'resource_type');
             $entry->published = $submission->timecreated;
             $entry->updated = $submission->timemodified;
             $entry->author = $user;
             $leapwriter->add_entry($entry);
             if ($files = $exporter->get('caller')->get('multifiles')) {
                 $leapwriter->link_files($entry, $files, 'assignmentonline' . $this->assignment->id . 'file');
                 foreach ($files as $f) {
                     $exporter->copy_existing_file($f);
                 }
             }
             $exporter->write_new_file($leapwriter->to_xml(), $exporter->get('format')->manifest_name(), true);
         } else {
             debugging('invalid format class: ' . $exporter->get('formatclass'));
         }
     }
 }
Example #5
0
    /**
     * Render the content of an assessment.
     *
     * @param workshop_assessment $assessment
     * @return string HTML
     */
    protected function export_assessment(workshop_assessment $assessment) {

        $output = '';

        if (empty($assessment->title)) {
            $title = get_string('assessment', 'workshop');
        } else {
            $title = s($assessment->title);
        }

        $output .= html_writer::tag('h3', $title);

        if ($assessment->reviewer) {
            $output .= html_writer::div(get_string('byfullnamewithoutlink', 'mod_workshop', fullname($assessment->reviewer)));
            $output .= html_writer::empty_tag('br');
        }

        if ($this->workshop->overallfeedbackmode) {
            if ($assessment->feedbackauthorattachment or trim($assessment->feedbackauthor) !== '') {
                $output .= html_writer::tag('h3', get_string('overallfeedback', 'mod_workshop'));
                $content = $this->format_exported_text($assessment->feedbackauthor, $assessment->feedbackauthorformat);
                $content = portfolio_rewrite_pluginfile_urls($content, $this->workshop->context->id, 'mod_workshop',
                    'overallfeedback_content', $assessment->id , $this->exporter->get('format'));
                $output .= $content;

                $output .= $this->export_files_list('overallfeedback_attachment');
            }
        }

        if ($assessment->form) {
            $output .= $assessment->form->render();
        }

        return $output;
    }
Example #6
0
 /**
  * Print comments which relate to a single blog post
  *
  * @param object $post Structure containing all post info and comments
  * @param object $oublog Blog object
  * @param bool $canmanagecomments Has capability toggle
  * @param bool $canaudit Has capability toggle
  * @param bool $forexport Export output rendering toggle
  * @param object $cm Current course module object
  * @return html
  */
 public function render_comments($post, $oublog, $canaudit, $canmanagecomments, $forexport, $cm, $format = false)
 {
     global $DB, $CFG, $USER, $OUTPUT;
     $viewfullnames = true;
     $strdelete = get_string('delete', 'oublog');
     $strcomments = get_string('comments', 'oublog');
     $output = '';
     $modcontext = context_module::instance($cm->id);
     if (!$canmanagecomments) {
         $context = context_module::instance($cm->id);
         $canmanagecomments = has_capability('mod/oublog:managecomments', $context);
     }
     $output .= html_writer::start_tag('div', array('class' => 'oublog-post-comments', 'id' => 'oublogcomments'));
     $counter = 0;
     foreach ($post->comments as $comment) {
         $extraclasses = $comment->deletedby ? ' oublog-deleted' : '';
         $extraclasses .= ' oublog-hasuserpic';
         $output .= html_writer::start_tag('div', array('class' => 'oublog-comment' . $extraclasses, 'id' => 'cid' . $comment->id));
         if ($counter == 0) {
             $output .= html_writer::tag('h2', format_string($strcomments), array('class' => 'oublog-commentstitle'));
         }
         if ($comment->deletedby) {
             $deluser = new stdClass();
             $fields = get_all_user_name_fields(false, null, 'del');
             foreach ($fields as $field => $dfield) {
                 $deluser->{$field} = $comment->{$dfield};
             }
             $a = new stdClass();
             $a->fullname = '<a href="../../user/view.php?id=' . $comment->deletedby . '">' . fullname($deluser) . '</a>';
             $a->timedeleted = oublog_date($comment->timedeleted);
             $output .= html_writer::tag('div', get_string('deletedby', 'oublog', $a), array('class' => 'oublog-comment-deletedby'));
         }
         if ($comment->userid && !$forexport) {
             $output .= html_writer::start_tag('div', array('class' => 'oublog-userpic'));
             $commentuser = new object();
             $fields = explode(',', user_picture::fields());
             foreach ($fields as $field) {
                 if ($field != 'id') {
                     $commentuser->{$field} = $comment->{$field};
                 }
             }
             $commentuser->id = $comment->userid;
             $output .= $OUTPUT->user_picture($commentuser, array('courseid' => $oublog->course, 'size' => 70));
             $output .= html_writer::end_tag('div');
         }
         if (trim(format_string($comment->title)) !== '') {
             $output .= html_writer::tag('h2', format_string($comment->title), array('class' => 'oublog-title'));
         } else {
             if (!$forexport) {
                 $commenttitle = get_accesshide(get_string('newcomment', 'mod_oublog'));
                 $output .= html_writer::tag('h2', $commenttitle, array('class' => 'oublog-title'));
             }
         }
         $output .= html_writer::start_tag('div', array('class' => 'oublog-post-date'));
         $output .= oublog_date($comment->timeposted);
         $output .= html_writer::start_tag('div', array('class' => 'oublog-postedby'));
         if ($comment->userid) {
             if (!$forexport) {
                 $output .= get_string('postedby', 'oublog', '<a href="../../user/view.php?id=' . $comment->userid . '&amp;course=' . $oublog->course . '">' . fullname($comment) . '</a>');
             } else {
                 $output .= get_string('postedby', 'oublog', fullname($comment));
             }
         } else {
             $output .= get_string($canaudit ? 'postedbymoderatedaudit' : 'postedbymoderated', 'oublog', (object) array('commenter' => s($comment->authorname), 'approver' => '<a href="../../user/view.php?id=' . $comment->userid . '&amp;course=' . $oublog->course . '">' . fullname($post) . '</a>', 'approvedate' => oublog_date($comment->timeapproved), 'ip' => s($comment->authorip)));
         }
         $output .= html_writer::end_tag('div');
         $output .= html_writer::end_tag('div');
         $output .= html_writer::start_tag('div', array('class' => 'oublog-comment-content'));
         if (!$forexport) {
             if ($post->visibility == OUBLOG_VISIBILITY_PUBLIC) {
                 $fileurlbase = 'mod/oublog/pluginfile.php';
             } else {
                 $fileurlbase = 'pluginfile.php';
             }
             $comment->message = file_rewrite_pluginfile_urls($comment->message, $fileurlbase, $modcontext->id, 'mod_oublog', 'messagecomment', $comment->id);
         } else {
             $comment->message = portfolio_rewrite_pluginfile_urls($comment->message, $modcontext->id, 'mod_oublog', 'messagecomment', $comment->id, $format);
         }
         $output .= format_text($comment->message, FORMAT_HTML);
         $output .= html_writer::end_tag('div');
         $output .= html_writer::start_tag('div', array('class' => 'oublog-post-links'));
         if (!$comment->deletedby) {
             // You can delete your own comments, or comments on your own
             // personal blog, or if you can manage comments.
             if ($comment->userid && $comment->userid == $USER->id || $oublog->global && $post->userid == $USER->id || $canmanagecomments) {
                 if (!$forexport) {
                     $output .= '<a href="deletecomment.php?comment=' . $comment->id . '">' . $strdelete . '</a>';
                 } else {
                     $output .= $strdelete;
                 }
             }
         }
         // Show OU Alerts reporting link.
         if (isloggedin() && oublog_oualerts_enabled() && oublog_get_reportingemail($oublog) && !($comment->userid == $USER->id) && !$comment->deletedby) {
             $itmurl = new moodle_url('/mod/oublog/viewpost.php', array('post' => $post->id));
             $itemurl = $itmurl->out() . '#cid' . $comment->id;
             $retnurl = new moodle_url('/mod/oublog/viewpost.php', array('post' => $post->id));
             $returnurl = $retnurl->out() . '#cid' . $comment->id;
             $reportlink = oualerts_generate_alert_form_url('oublog', $modcontext->id, 'comment', $comment->id, $itemurl, $returnurl, '', false, true);
             if ($reportlink != '') {
                 $output .= html_writer::tag('a', get_string('commentalert', 'oublog'), array('href' => $reportlink));
             }
         }
         $output .= html_writer::end_tag('div');
         $output .= html_writer::end_tag('div');
         $counter++;
     }
     $output .= html_writer::end_tag('div');
     return $output;
 }
 /**
  * Obtains page html suitable for use in portfolio export.
  * @param object $pageversion Page and version data
  * @param array $attachments Attachments array indexed by versionid
  * @param object $context Moodle context object
  * @param object $ouwiki OU wiki object
  * @param object $subwiki Subwiki object
  * @param object $course Course object
  * @param bool $withannotations If true, includes annotations
  * @param portfolio_format $portfolioformat Portfolio format
  * @param string $plugin the portfolio plugin being used.
  * @return string HTML code
  */
 static function get_page_html($pageversion, $attachments, $context, $ouwiki, $subwiki, $course, $withannotations, portfolio_format $portfolioformat, $plugin)
 {
     global $DB;
     // Format the page body
     $options = portfolio_format_text_options();
     $formattedtext = format_text($pageversion->xhtml, $pageversion->xhtmlformat, $options, $course->id);
     $formattedtext = portfolio_rewrite_pluginfile_urls($formattedtext, $context->id, 'mod_ouwiki', 'content', $pageversion->versionid, $portfolioformat);
     // Get annotations - only if using annotation system. prevents unnecessary db access
     if ($ouwiki->annotation) {
         $annotations = ouwiki_get_annotations($pageversion);
     } else {
         $annotations = array();
     }
     // Convert or remove the annotations
     if ($ouwiki->annotation && count($annotations)) {
         ouwiki_highlight_existing_annotations($formattedtext, $annotations, $withannotations ? 'portfolio' : 'clear');
     }
     // Do overall page, starting with title
     $title = $pageversion->title;
     if ($title === null) {
         $title = get_string('startpage', 'ouwiki');
     }
     $output = html_writer::tag('h2', s($title));
     // Last change info
     $user = (object) array('id' => $pageversion->userid, 'firstname' => $pageversion->firstname, 'lastname' => $pageversion->lastname);
     $lastchange = get_string('lastchange', 'ouwiki', (object) array('date' => userdate($pageversion->timecreated), 'userlink' => ouwiki_display_user($user, $course->id)));
     $output .= html_writer::tag('p', html_writer::tag('small', html_writer::tag('i', $lastchange)));
     // Main text
     $output .= html_writer::tag('div', $formattedtext);
     // Word count
     if ($ouwiki->enablewordcount) {
         $wordcount = get_string('numwords', 'ouwiki', $pageversion->wordcount);
         $output .= html_writer::tag('div', html_writer::empty_tag('br'));
         $output .= html_writer::tag('p', html_writer::tag('small', $wordcount), array('class' => 'ouw_wordcount'));
     }
     // Attachments
     if ($attachments[$pageversion->versionid]) {
         $output .= html_writer::start_tag('div', array('class' => 'attachments'));
         $output .= html_writer::tag('h3', get_string('attachments', 'ouwiki'));
         $output .= html_writer::start_tag('ul');
         foreach ($attachments[$pageversion->versionid] as $file) {
             if ($plugin == 'rtf') {
                 $filename = $file->get_filename();
                 $path = moodle_url::make_pluginfile_url($context->id, 'mod_ouwiki', 'attachment', $pageversion->versionid, '/', $filename, true);
                 $atag = html_writer::tag('a', $filename, array('href' => $path));
             } else {
                 $atag = $portfolioformat->file_output($file);
             }
             $output .= html_writer::tag('li', $atag);
         }
         $output .= html_writer::end_tag('ul');
         $output .= html_writer::end_tag('div');
     }
     return $output;
 }
Example #8
0
 public function test_portfolio_rewrite_pluginfile_urls()
 {
     $this->resetAfterTest();
     // File info.
     $context = context_system::instance();
     $component = 'core_test';
     $filearea = 'fixture';
     $filepath = '/';
     $itemid = 0;
     $filenameimg = 'file.png';
     $filenamepdf = 'file.pdf';
     // Store 2 test files in the pool.
     $fs = get_file_storage();
     $filerecord = array('contextid' => $context->id, 'component' => $component, 'filearea' => $filearea, 'itemid' => $itemid, 'filepath' => $filepath, 'filename' => $filenameimg);
     $fileimg = $fs->create_file_from_string($filerecord, 'test');
     $filerecord['filename'] = $filenamepdf;
     $filepdf = $fs->create_file_from_string($filerecord, 'test');
     // Test that nothing is matching.
     $format = '';
     $options = null;
     $input = '<div>Here, the <a href="nowhere">@@PLUGINFILE@@' . $filepath . $filenamepdf . ' is</a> not supposed to be an actual URL placeholder.</div>';
     $output = portfolio_rewrite_pluginfile_urls($input, $context->id, $component, $filearea, $itemid, $format, $options);
     $this->assertSame($input, $output);
     $input = '<div>Here, the <img src="nowhere" />@@PLUGINFILE@@' . $filepath . $filenameimg . ' is</a> not supposed to be an actual URL placeholder.</div>';
     $output = portfolio_rewrite_pluginfile_urls($input, $context->id, $component, $filearea, $itemid, $format, $options);
     $this->assertSame($input, $output);
     // Now use our dummy format.
     $format = new core_portfolio_format_dummytest();
     $options = null;
     // Test that the link is matching.
     $input = '<p>Come and <a href="@@PLUGINFILE@@' . $filepath . $filenamepdf . '">join us!</a>?</p>';
     $expected = '<p>Come and <a href="files/' . $filenamepdf . '">' . $filenamepdf . '</a>?</p>';
     $output = portfolio_rewrite_pluginfile_urls($input, $context->id, $component, $filearea, $itemid, $format, $options);
     $this->assertSame($expected, $output);
     $input = '<p>Come and <a href="@@PLUGINFILE@@' . $filepath . $filenamepdf . '"><em>join us!</em></a>?</p>';
     $expected = '<p>Come and <a href="files/' . $filenamepdf . '">' . $filenamepdf . '</a>?</p>';
     $output = portfolio_rewrite_pluginfile_urls($input, $context->id, $component, $filearea, $itemid, $format, $options);
     $this->assertSame($expected, $output);
     // Test that the image is matching.
     $input = '<p>Here is an image <img src="@@PLUGINFILE@@' . $filepath . $filenameimg . '"></p>';
     // No trailing slash.
     $expected = '<p>Here is an image <img src="files/' . $filenameimg . '"/></p>';
     $output = portfolio_rewrite_pluginfile_urls($input, $context->id, $component, $filearea, $itemid, $format, $options);
     $this->assertSame($expected, $output);
     $input = '<p>Here is an image <img src="@@PLUGINFILE@@' . $filepath . $filenameimg . '" /></p>';
     // Trailing slash.
     $expected = '<p>Here is an image <img src="files/' . $filenameimg . '"/></p>';
     $output = portfolio_rewrite_pluginfile_urls($input, $context->id, $component, $filearea, $itemid, $format, $options);
     $this->assertSame($expected, $output);
     // Test that the attributes are kept.
     $input = '<p><a title="hurray!" href="@@PLUGINFILE@@' . $filepath . $filenamepdf . '" target="_blank">join us!</a></p>';
     $expected = '<p><a title="hurray!" href="files/' . $filenamepdf . '" target="_blank">' . $filenamepdf . '</a></p>';
     $output = portfolio_rewrite_pluginfile_urls($input, $context->id, $component, $filearea, $itemid, $format, $options);
     $this->assertSame($expected, $output);
     $input = '<p><img alt="before" src="@@PLUGINFILE@@' . $filepath . $filenameimg . '" title="after"/></p>';
     $expected = '<p><img alt="before" src="files/' . $filenameimg . '" title="after"/></p>';
     $output = portfolio_rewrite_pluginfile_urls($input, $context->id, $component, $filearea, $itemid, $format, $options);
     $this->assertSame($expected, $output);
     // Test with more tags around.
     $input = '<p><span title="@@PLUGINFILE/a.txt"><a href="@@PLUGINFILE@@' . $filepath . $filenamepdf . '">' . '<em>join</em> <b>us!</b></a></span></p>';
     $expected = '<p><span title="@@PLUGINFILE/a.txt"><a href="files/' . $filenamepdf . '">' . $filenamepdf . '</a></span></p>';
     $output = portfolio_rewrite_pluginfile_urls($input, $context->id, $component, $filearea, $itemid, $format, $options);
     $this->assertSame($expected, $output);
     $input = '<p><span title="@@PLUGINFILE/a.txt"><img src="@@PLUGINFILE@@' . $filepath . $filenameimg . '"/></span></p>';
     $expected = '<p><span title="@@PLUGINFILE/a.txt"><img src="files/' . $filenameimg . '"/></span></p>';
     $output = portfolio_rewrite_pluginfile_urls($input, $context->id, $component, $filearea, $itemid, $format, $options);
     $this->assertSame($expected, $output);
     // Test multiple on same line.
     $input = '<p><a rel="1" href="@@PLUGINFILE@@' . $filepath . $filenamepdf . '">join us!</a>' . '<a rel="2" href="@@PLUGINFILE@@' . $filepath . $filenamepdf . '">join us!</a></p>';
     $expected = '<p><a rel="1" href="files/' . $filenamepdf . '">' . $filenamepdf . '</a>' . '<a rel="2" href="files/' . $filenamepdf . '">' . $filenamepdf . '</a></p>';
     $output = portfolio_rewrite_pluginfile_urls($input, $context->id, $component, $filearea, $itemid, $format, $options);
     $this->assertSame($expected, $output);
     $input = '<p><img rel="1" src="@@PLUGINFILE@@' . $filepath . $filenameimg . '"/>' . '<img rel="2" src="@@PLUGINFILE@@' . $filepath . $filenameimg . '"/></p>';
     $expected = '<p><img rel="1" src="files/' . $filenameimg . '"/><img rel="2" src="files/' . $filenameimg . '"/></p>';
     $output = portfolio_rewrite_pluginfile_urls($input, $context->id, $component, $filearea, $itemid, $format, $options);
     $this->assertSame($expected, $output);
     $input = '<p><a href="@@PLUGINFILE@@' . $filepath . $filenamepdf . '">join us!</a>' . '<img src="@@PLUGINFILE@@' . $filepath . $filenameimg . '"/></p>';
     $expected = '<p><a href="files/' . $filenamepdf . '">' . $filenamepdf . '</a>' . '<img src="files/' . $filenameimg . '"/></p>';
     $output = portfolio_rewrite_pluginfile_urls($input, $context->id, $component, $filearea, $itemid, $format, $options);
     $this->assertSame($expected, $output);
 }
 /**
  * Obtains page html suitable for use in portfolio export.
  * @param object $pageversion Page and version data
  * @param array $attachments Attachments array indexed by versionid
  * @param object $context Moodle context object
  * @param object $ouwiki OU wiki object
  * @param object $subwiki Subwiki object
  * @param object $course Course object
  * @param bool $withannotations If true, includes annotations
  * @param portfolio_format $portfolioformat Portfolio format
  * @param string $plugin the portfolio plugin being used.
  * @return string HTML code
  */
 public static function get_page_html($pageversion, $attachments, $context, $ouwiki, $subwiki, $course, $withannotations, portfolio_format $portfolioformat, $plugin)
 {
     global $DB;
     // Format the page body.
     $options = portfolio_format_text_options();
     $options->filter = true;
     $formattedtext = portfolio_rewrite_pluginfile_urls($pageversion->xhtml, $context->id, 'mod_ouwiki', 'content', $pageversion->versionid, $portfolioformat);
     $formattedtext = format_text($formattedtext, $pageversion->xhtmlformat, $options, $course->id);
     // Get annotations - only if using annotation system. prevents unnecessary db access.
     if ($ouwiki->annotation) {
         $annotations = ouwiki_get_annotations($pageversion);
     } else {
         $annotations = array();
     }
     // Convert or remove the annotations.
     if ($ouwiki->annotation && count($annotations)) {
         ouwiki_highlight_existing_annotations($formattedtext, $annotations, $withannotations ? 'portfolio' : 'clear');
     }
     // Do overall page, starting with title.
     $title = $pageversion->title;
     if ($title === '') {
         $title = get_string('startpage', 'ouwiki');
     }
     $output = html_writer::tag('h2', s($title));
     // Last change info.
     $user = new stdClass();
     foreach (explode(',', user_picture::fields()) as $field) {
         if ($field == 'id') {
             $user->id = $pageversion->userid;
         } else {
             $user->{$field} = $pageversion->{$field};
         }
     }
     $lastchange = get_string('lastchange', 'ouwiki', (object) array('date' => userdate($pageversion->timecreated), 'userlink' => ouwiki_display_user($user, $course->id)));
     $output .= html_writer::tag('p', html_writer::tag('small', html_writer::tag('i', $lastchange)));
     // Main text.
     $output .= html_writer::tag('div', $formattedtext);
     // Word count.
     if ($ouwiki->enablewordcount) {
         $wordcount = get_string('numwords', 'ouwiki', $pageversion->wordcount);
         $output .= html_writer::tag('div', html_writer::empty_tag('br'));
         $output .= html_writer::tag('p', html_writer::tag('small', $wordcount), array('class' => 'ouw_wordcount'));
     }
     // Attachments.
     if ($attachments[$pageversion->versionid]) {
         $output .= html_writer::start_tag('div', array('class' => 'attachments'));
         $output .= html_writer::tag('h3', get_string('attachments', 'ouwiki'));
         $output .= html_writer::start_tag('ul');
         foreach ($attachments[$pageversion->versionid] as $file) {
             if ($plugin == 'rtf') {
                 $filename = $file->get_filename();
                 $path = moodle_url::make_pluginfile_url($context->id, 'mod_ouwiki', 'attachment', $pageversion->versionid, '/', $filename, true);
                 $atag = html_writer::tag('a', $filename, array('href' => $path));
             } else {
                 $atag = $portfolioformat->file_output($file);
             }
             $output .= html_writer::tag('li', $atag);
         }
         $output .= html_writer::end_tag('ul');
         $output .= html_writer::end_tag('div');
     }
     // Replace all user links with user name so that you can not access user links from within exported document.
     $output = preg_replace('~<a href="[^"]*/user/view.php[^"]*"\\s*>(.*?)</a>~', '$1', $output);
     return $output;
 }