--- /dev/null
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * TinyMCE manage files plugin language file
+ *
+ * @package tinymce_managefiles
+ * @copyright 2013 Marina Glancy
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+$string['pluginname'] = 'Manage embedded files';
+$string['manageareafiles'] = 'Manage files embedded in text editor';
+$string['managefiles:desc'] = 'Manage embedded files';
+$string['allfilesok'] = 'There are no missing or unused files';
+$string['hasmissingfiles'] = 'Warning! The following files that are referenced in the text area appear to be missing:';
+$string['refreshfiles'] = 'Refresh the lists of missing and unused files';
+$string['unusedfilesheader'] = 'Unused files';
+$string['unusedfilesdesc'] = 'The following embedded files are not used in the text area:';
+$string['deleteselected'] = 'Delete selected files';
\ No newline at end of file
--- /dev/null
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Plugin for managing files embedded in the text editor
+ *
+ * @package tinymce_managefiles
+ * @copyright 2013 Marina Glancy
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class tinymce_managefiles extends editor_tinymce_plugin {
+ /** @var array list of buttons defined by this plugin */
+ protected $buttons = array('managefiles');
+
+ /**
+ * Adjusts TinyMCE init parameters for tinymce_managefiles
+ *
+ * Adds file area restrictions parameters and actual 'managefiles' button
+ *
+ * @param array $params TinyMCE init parameters array
+ * @param context $context Context where editor is being shown
+ * @param array $options Options for this editor
+ */
+ protected function update_init_params(array &$params, context $context,
+ array $options = null) {
+ global $USER;
+
+ // Add parameters for filemanager
+ $params['managefiles'] = array('usercontext' => context_user::instance($USER->id)->id);
+ foreach (array('itemid', 'context', 'areamaxbytes', 'maxbytes', 'subdirs', 'return_types') as $key) {
+ if (isset($options[$key])) {
+ if ($key === 'context' && is_object($options[$key])) {
+ // Just context id is enough
+ $params['managefiles'][$key] = $options[$key]->id;
+ } else {
+ $params['managefiles'][$key] = $options[$key];
+ }
+ }
+ }
+
+ // Add button after moodlemedia button in advancedbuttons3.
+ $added = $this->add_button_after($params, 3, 'managefiles', 'moodlemedia', false);
+
+ // So, if no moodlemedia, add after 'image'.
+ if (!$added) {
+ $this->add_button_after($params, 3, 'managefiles', 'image');
+ }
+
+ // Add JS file, which uses default name.
+ $this->add_js_plugin($params);
+ }
+
+ protected function get_sort_order() {
+ return 310;
+ }
+}
--- /dev/null
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Manage files in user draft area attached to texteditor
+ *
+ * @package tinymce_managefiles
+ * @copyright 2013 Marina Glancy
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+require('../../../../../config.php');
+require_once('manage_form.php');
+require_once($CFG->libdir.'/filestorage/file_storage.php');
+
+require_login();
+if (isguestuser()) {
+ print_error('noguest');
+}
+
+$itemid = required_param('itemid', PARAM_INT);
+$maxbytes = optional_param('maxbytes', 0, PARAM_INT);
+$subdirs = optional_param('subdirs', 0, PARAM_INT);
+$accepted_types = optional_param('accepted_types', '*', PARAM_RAW); // TODO not yet passed to this script
+$return_types = optional_param('return_types', null, PARAM_INT);
+$areamaxbytes = optional_param('areamaxbytes', FILE_AREA_MAX_BYTES_UNLIMITED, PARAM_INT);
+$contextid = optional_param('context', SYSCONTEXTID, PARAM_INT);
+
+$title = get_string('manageareafiles', 'tinymce_managefiles');
+
+$PAGE->set_url('/lib/editor/tinymce/plugins/managefiles/manage.php');
+$PAGE->set_context(context::instance_by_id($contextid));
+$PAGE->set_title($title);
+$PAGE->set_heading($title);
+$PAGE->set_pagelayout('popup');
+
+if ($return_types !== null) {
+ $return_types = $return_types ^ 1; // links are allowed in textarea but never allowed in filemanager
+}
+
+$options = array(
+ 'subdirs' => $subdirs,
+ 'maxbytes' => $maxbytes,
+ 'maxfiles' => -1,
+ 'accepted_types' => $accepted_types,
+ 'areamaxbytes' => $areamaxbytes,
+ 'return_types' => $return_types,
+ 'context' => context::instance_by_id($contextid)
+);
+
+$usercontext = context_user::instance($USER->id);
+$fs = get_file_storage();
+$files = $fs->get_directory_files($usercontext->id, 'user', 'draft', $itemid, '/', !empty($subdirs), false);
+$filenames = array();
+foreach ($files as $file) {
+ $filenames[] = ltrim($file->get_filepath(), '/'). $file->get_filename();
+}
+
+$mform = new tinymce_managefiles_manage_form(null,
+ array('options' => $options, 'draftitemid' => $itemid, 'files' => $filenames),
+ 'post', '', array('id' => 'tinymce_managefiles_manageform'));
+
+if ($data = $mform->get_data()) {
+ if (!empty($data->deletefile)) {
+ foreach (array_keys($data->deletefile) as $filename) {
+ $filepath = '/';
+ if (!empty($subdirs) && strlen(dirname($filename)) ) {
+ $filepath = '/'. dirname($filename). '/';
+ }
+ if ($file = $fs->get_file($usercontext->id, 'user', 'draft', $itemid,
+ $filepath, basename($filename))) {
+ $file->delete();
+ }
+ }
+ $filenames = array_diff($filenames, array_keys($data->deletefile));
+ $mform = new tinymce_managefiles_manage_form(null,
+ array('options' => $options, 'draftitemid' => $itemid, 'files' => $filenames),
+ 'post', '', array('id' => 'tinymce_managefiles_manageform'));
+ }
+}
+
+echo $OUTPUT->header();
+$mform->display();
+echo $OUTPUT->footer();
--- /dev/null
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Class tinymce_managefiles_manage_form
+ *
+ * @package tinymce_managefiles
+ * @copyright 2013 Marina Glancy
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+require_once($CFG->libdir."/formslib.php");
+
+/**
+ * Form allowing to edit files in one draft area
+ *
+ * No buttons are necessary since the draft area files are saved immediately using AJAX
+ *
+ * @package tinymce_managefiles
+ * @copyright 2013 Marina Glancy
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class tinymce_managefiles_manage_form extends moodleform {
+ function definition() {
+ global $PAGE;
+ $mform = $this->_form;
+
+ $itemid = $this->_customdata['draftitemid'];
+ $options = $this->_customdata['options'];
+ $files = $this->_customdata['files'];
+
+ $mform->addElement('hidden', 'itemid');
+ $mform->setType('itemid', PARAM_INT);
+ $mform->addElement('hidden', 'maxbytes');
+ $mform->setType('maxbytes', PARAM_INT);
+ $mform->addElement('hidden', 'subdirs');
+ $mform->setType('subdirs', PARAM_INT);
+ $mform->addElement('hidden', 'accepted_types');
+ $mform->setType('accepted_types', PARAM_RAW);
+ $mform->addElement('hidden', 'return_types');
+ $mform->setType('return_types', PARAM_INT);
+ $mform->addElement('hidden', 'context');
+ $mform->setType('context', PARAM_INT);
+ $mform->addElement('hidden', 'areamaxbytes');
+ $mform->setType('areamaxbytes', PARAM_INT);
+
+ $mform->addElement('filemanager', 'files_filemanager', '', null, $options);
+
+ $mform->addElement('submit', 'refresh', get_string('refreshfiles', 'tinymce_managefiles'));
+ $mform->registerNoSubmitButton('refresh');
+
+ $mform->addElement('static', '', '',
+ html_writer::tag('span', '', array('class' => 'managefilesstatus')));
+
+ $mform->addElement('header', 'deletefiles', get_string('unusedfilesheader', 'tinymce_managefiles'));
+ $mform->addElement('static', '', '',
+ html_writer::tag('span', get_string('unusedfilesdesc', 'tinymce_managefiles'), array('class' => 'managefilesunuseddesc')));
+ foreach ($files as $file) {
+ $mform->addElement('checkbox', 'deletefile['.$file.']', '', $file);
+ $mform->setType('deletefile['.$file.']', PARAM_INT);
+ }
+ $mform->addElement('submit', 'delete', get_string('deleteselected', 'tinymce_managefiles'));
+
+ $PAGE->requires->js_init_call('M.tinymce_managefiles.analysefiles', array(), true);
+ $PAGE->requires->strings_for_js(array('allfilesok', 'hasmissingfiles'), 'tinymce_managefiles');
+
+ $this->set_data(array('files_filemanager' => $itemid,
+ 'itemid' => $itemid,
+ 'subdirs' => $options['subdirs'],
+ 'maxbytes' => $options['maxbytes'],
+ 'areamaxbytes' => $options['areamaxbytes'],
+ 'accepted_types' => $options['accepted_types'],
+ 'return_types' => $options['return_types'],
+ 'context' => $options['context']->id,
+ ));
+ }
+}
--- /dev/null
+M.tinymce_managefiles = M.tinymce_managefiles || {}
+M.tinymce_managefiles.analysefiles = function(Y) {
+ var form = Y.one('#tinymce_managefiles_manageform'),
+ usedfiles, missingfiles = '', i;
+ if (!form || !window.parent || !window.parent.tinyMCE.activeEditor) {
+ return;
+ }
+ usedfiles = window.parent.tinyMCE.activeEditor.execCommand('mceManageFilesUsedFiles')
+ var delfilesfieldset = form.one('#deletefiles,#id_deletefiles')
+ for (i in usedfiles) {
+ if (!delfilesfieldset.one('.felement.fcheckbox input[name="deletefile[' + usedfiles[i] + ']"]')) {
+ missingfiles += '<li>' + usedfiles[i] + '</li>';
+ }
+ }
+ if (missingfiles !== '') {
+ form.addClass('hasmissingfiles')
+ form.one('.managefilesstatus').setContent(M.str.tinymce_managefiles.hasmissingfiles + ' <ul>' + missingfiles + '</ul>').addClass('error');
+ }
+ delfilesfieldset.all('.felement.fcheckbox').each(function(el) {
+ var chb = el.one('input[type=checkbox]'),
+ match = /^deletefile\[(.*)\]$/.exec(chb.get('name'));
+ if (match && usedfiles.indexOf(match[1]) === -1) {
+ el.addClass('isunused')
+ form.addClass('hasunusedfiles')
+ }
+ });
+ if (missingfiles === '' && !form.hasClass('hasunusedfiles')) {
+ form.one('.managefilesstatus').setContent(M.str.tinymce_managefiles.allfilesok);
+ }
+}
--- /dev/null
+#tinymce_managefiles_manageform.hasunusedfiles .managefilesstatus {display:none;}
+#tinymce_managefiles_manageform.hasmissingfiles .managefilesstatus {display:inline;}
+
+#tinymce_managefiles_manageform #id_deletefiles {display:none;}
+#tinymce_managefiles_manageform.hasunusedfiles #id_deletefiles {display:block;}
+#tinymce_managefiles_manageform #id_deletefiles .felement.fcheckbox {display:none;}
+#tinymce_managefiles_manageform #id_deletefiles .felement.fcheckbox.isunused {display:block;}
--- /dev/null
+/**
+ * TinyMCE plugin ManageFiles - provides UI to edit files embedded in the text editor.
+ *
+ * @author Marina Glancy
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+(function() {
+ tinymce.create('tinymce.plugins.MoodleManageFiles', {
+ /**
+ * Initializes the plugin, this will be executed after the plugin has been created.
+ * This call is done before the editor instance has finished it's initialization so use the onInit event
+ * of the editor instance to intercept that event.
+ *
+ * @param {tinymce.Editor} ed Editor instance that the plugin is initialized in.
+ * @param {string} url Absolute URL to where the plugin is located.
+ */
+ init : function(ed, url) {
+ ed.addCommand('mceForceRepaint', function() {
+ var root = ed.dom.getRoot();
+ items = root.getElementsByTagName("img");
+ for (var i = 0; i < items.length; i++) {
+ src = items[i].getAttribute('src').replace(/\?\d+$/, '');
+ items[i].setAttribute('src', src+'?'+(new Date().getTime()))
+ }
+ ed.execCommand('mceRepaint');
+ ed.focus();
+ });
+
+ ed.addCommand('mceMaximizeWindow', function(w) {
+ // This function duplicates the TinyMCE windowManager code when 'maximize' button is pressed.
+ var vp = ed.dom.getViewPort(),
+ id = w.id;
+ // Reduce viewport size to avoid scrollbars
+ vp.w -= 2;
+ vp.h -= 2;
+
+ w.oldPos = w.element.getXY();
+ w.oldSize = w.element.getSize();
+
+ w.element.moveTo(vp.x, vp.y);
+ w.element.resizeTo(vp.w, vp.h);
+ ed.dom.setStyles(id + '_ifr', {width : vp.w - w.deltaWidth, height : vp.h - w.deltaHeight});
+ ed.dom.addClass(id + '_wrapper', 'mceMaximized');
+ });
+
+ ed.addCommand('mceManageFiles', function() {
+ var managefiles = ed.getParam('managefiles', {}), key, cnt = 0,
+ fileurl = ed.getParam("moodle_plugin_base") + 'managefiles/manage.php?';
+ for (key in managefiles) {
+ fileurl += (cnt++ ? '&' : '') + encodeURIComponent(key) + "=" + encodeURIComponent(managefiles[key]) + "&";
+ }
+ var onClose = function() {
+ ed.windowManager.onClose.remove(onClose);
+ ed.execCommand('mceForceRepaint');
+ };
+ ed.windowManager.onClose.add(onClose);
+ var vp = ed.dom.getViewPort(),
+ width = 865 + parseInt(ed.getLang('advimage.delta_width', 0)),
+ height = 600 + parseInt(ed.getLang('advimage.delta_height', 0)),
+ maximizedmode = (width >= vp.w - 2 || height >= vp.h - 2);
+ if (maximizedmode) {
+ width = vp.w;
+ height = vp.h;
+ }
+ w = ed.windowManager.open({
+ file : fileurl ,
+ width : width,
+ height : height,
+ inline : 1
+ }, {
+ plugin_url : url // Plugin absolute URL
+ });
+ if (maximizedmode) {
+ ed.execCommand('mceMaximizeWindow', w);
+ }
+ });
+
+ ed.addCommand('mceManageFilesUsedFiles', function() {
+ var managefiles = ed.getParam('managefiles', {}),
+ text = ed.dom.getRoot().innerHTML,
+ base = ed.getParam('document_base_url') + '/draftfile.php/' + managefiles['usercontext'] + '/user/draft/' + managefiles['itemid'] + '/',
+ patt = new RegExp(base.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') + "(.+?)[\\?\"']", 'gm'),
+ arr = [], match, filename;
+ while ((match = patt.exec(text)) !== null) {
+ filename = unescape(match[1]);
+ if (arr.indexOf(filename) === -1) {
+ arr[arr.length] = filename;
+ }
+ }
+ return arr;
+ });
+
+ var managefiles = ed.getParam('managefiles', {});
+ // Get draft area id from filepicker options.
+ if (!managefiles.itemid && M.editor_tinymce.filepicker_options && M.editor_tinymce.filepicker_options[ed.id]) {
+ managefiles.itemid = M.editor_tinymce.filepicker_options[ed.id].image.itemid;
+ ed.settings['managefiles'].itemid = managefiles.itemid;
+ }
+
+ // Register buttons
+ if (managefiles.itemid) {
+ ed.addButton('managefiles', {
+ title : 'managefiles.desc',
+ cmd : 'mceManageFiles',
+ image : url + '/img/managefiles.png'
+ });
+ }
+ },
+ createControl : function(n, cm) {
+ return null;
+ },
+
+ /**
+ * Returns information about the plugin as a name/value array.
+ * The current keys are longname, author, authorurl, infourl and version.
+ *
+ * @return {Object} Name/value array containing information about the plugin.
+ */
+ getInfo : function() {
+ return {
+ longname : 'Moodle Manage embedded files plugin',
+ author : 'Marina Glancy',
+ infourl : 'http://moodle.org',
+ version : "1.0"
+ };
+ }
+ });
+
+ // Register plugin.
+ tinymce.PluginManager.add('managefiles', tinymce.plugins.MoodleManageFiles);
+})();
--- /dev/null
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * TinyMCE manage files plugin version details.
+ *
+ * @package tinymce_managefiles
+ * @copyright 2013 Marina Glancy
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+$plugin->version = 2013071600; // The current plugin version (Date: YYYYMMDDXX).
+$plugin->requires = 2012120300; // Required Moodle version.
+$plugin->component = 'tinymce_managefiles'; // Full name of the plugin (used for diagnostics).
),
'tinymce' => array(
- 'ctrlhelp', 'dragmath', 'moodleemoticon', 'moodleimage', 'moodlemedia', 'moodlenolink', 'spellchecker',
- 'pdw', 'wrap'
+ 'ctrlhelp', 'dragmath', 'managefiles', 'moodleemoticon', 'moodleimage',
+ 'moodlemedia', 'moodlenolink', 'pdw', 'spellchecker', 'wrap'
),
'theme' => array(