Commit 717fd143 authored by Richard Mansfield's avatar Richard Mansfield

Merge branch 'grouptyperework'

Conflicts:

	htdocs/group/edit.php
	htdocs/lib/db/upgrade.php
parents 5cec5a52 d6d5a16a
......@@ -41,8 +41,8 @@ $wwwroot = get_config('wwwroot');
$javascript = <<<JAVASCRIPT
var copyrightnotice = '{$copyright}';
var browser = new FileBrowser('filelist', '{$wwwroot}artefact/file/myfiles.json.php', {'adminfiles':true});
var uploader = new FileUploader('uploader', '{$wwwroot}artefact/file/upload.php', {'adminfiles':true},
var browser = new FileBrowser('filelist', '{$wwwroot}artefact/file/myfiles.json.php', {'institution':'mahara'});
var uploader = new FileUploader('uploader', '{$wwwroot}artefact/file/upload.php', {'institution':'mahara'},
null, null, browser.refresh, browser.fileexists);
browser.changedircallback = uploader.updatedestination;
......
......@@ -61,7 +61,7 @@ class PluginBlocktypeBlog extends PluginBlocktype {
$result = '';
if (!empty($configdata['artefactid'])) {
require_once(get_config('docroot') . 'artefact/lib.php');
$blog = artefact_instance_from_id($configdata['artefactid']);
$blog = $instance->get_artefact_instance($configdata['artefactid']);
$configdata['hidetitle'] = true;
$configdata['viewid'] = $instance->get('view');
$result = $blog->render_self($configdata);
......
......@@ -61,7 +61,7 @@ class PluginBlocktypeBlogpost extends PluginBlocktype {
$result = '';
if (!empty($configdata['artefactid'])) {
require_once(get_config('docroot') . 'artefact/lib.php');
$blogpost = artefact_instance_from_id($configdata['artefactid']);
$blogpost = $instance->get_artefact_instance($configdata['artefactid']);
$configdata['hidetitle'] = true;
$configdata['viewid'] = $instance->get('view');
$result = $blogpost->render_self($configdata);
......
......@@ -652,7 +652,6 @@ class ArtefactTypeBlogPost extends ArtefactType {
$data->description = $description;
$data->tags = $tags;
$data->owner = $USER->get('id');
$data->adminfiles = 0; // No admin blogs yet...
$data->parent = $blogfilesid;
$data->oldextension = $oldextension;
......
......@@ -47,7 +47,12 @@ class PluginBlocktypeFiledownload extends PluginBlocktype {
$result = '';
if (isset($configdata['artefactids']) && is_array($configdata['artefactids'])) {
foreach ($configdata['artefactids'] as $artefactid) {
$artefact = artefact_instance_from_id($artefactid);
try {
$artefact = $instance->get_artefact_instance($artefactid);
}
catch (ArtefactNotFoundException $e) {
continue;
}
$icondata = array(
'id' => $artefactid,
......
......@@ -65,7 +65,7 @@ class PluginBlocktypeFolder extends PluginBlocktype {
// render_self
$result = '';
if (isset($configdata['artefactid'])) {
$folder = artefact_instance_from_id($configdata['artefactid']);
$folder = $instance->get_artefact_instance($configdata['artefactid']);
$result = $folder->render_self($configdata);
$result = $result['html'];
}
......
......@@ -41,7 +41,6 @@ class PluginBlocktypeImage extends PluginBlocktype {
}
public static function render_instance(BlockInstance $instance) {
require_once(get_config('docroot') . 'artefact/lib.php');
$configdata = $instance->get('configdata'); // this will make sure to unserialize it for us
$configdata['viewid'] = $instance->get('view');
......@@ -49,7 +48,7 @@ class PluginBlocktypeImage extends PluginBlocktype {
// render_self
$result = '';
if (isset($configdata['artefactid'])) {
$image = artefact_instance_from_id($configdata['artefactid']);
$image = $instance->get_artefact_instance($configdata['artefactid']);
if ($image instanceof ArtefactTypeProfileIcon) {
$src = get_config('wwwroot') . 'thumb.php?type=profileiconbyid&id=' . $configdata['artefactid'];
......
......@@ -63,7 +63,7 @@ class PluginBlocktypeInternalmedia extends PluginBlocktype {
}
$result = self::get_js_source();
require_once(get_config('docroot') . 'artefact/lib.php');
$artefact = artefact_instance_from_id($configdata['artefactid']);
$artefact = $instance->get_artefact_instance($configdata['artefactid']);
$width = (!empty($configdata['width'])) ? hsc($configdata['width']) : '300';
$height = (!empty($configdata['height'])) ? hsc($configdata['height']) : '300';
$extn = strtolower($artefact->get('oldextension'));
......
......@@ -29,7 +29,6 @@ define('JSON', 1);
require(dirname(dirname(dirname(__FILE__))) . '/init.php');
safe_require('artefact', 'file');
global $USER;
json_headers();
......@@ -38,7 +37,8 @@ $title = param_variable('name');
$description = param_variable('description', null);
$tags = param_variable('tags', null);
$collideaction = param_variable('collideaction', 'fail');
$adminfiles = param_boolean('adminfiles', false);
$institution = param_alpha('institution', null);
$group = param_integer('group', null);
$data = new StdClass;
if ($parentfolder) {
......@@ -47,10 +47,24 @@ if ($parentfolder) {
$data->title = $title;
$data->description = $description;
$data->tags = $tags;
$data->owner = $USER->get('id');
$data->adminfiles = (int)$adminfiles;
$data->owner = null;
if ($institution) {
$data->institution = $institution;
} else if ($group) {
require_once(get_config('docroot') . 'artefact/lib.php');
require_once(get_config('docroot') . 'lib/group.php');
if ($parentfolder && !$USER->can_edit_artefact(artefact_instance_from_id($parentfolder))) {
json_reply('local', get_string('cannoteditfolder', 'artefact.file'));
} else if (!$parentfolder && !group_user_access($group)) {
json_reply('local', get_string('usernotingroup', 'mahara'));
}
$data->group = $group;
$data->rolepermissions = json_decode(param_variable('permissions'));
} else {
$data->owner = $USER->get('id');
}
if ($oldid = ArtefactTypeFileBase::file_exists($data->title, $data->owner, $parentfolder, $adminfiles)) {
if ($oldid = ArtefactTypeFileBase::file_exists($data->title, $data->owner, $parentfolder, $institution, $group)) {
if ($collideaction == 'replace') {
require_once(get_config('docroot') . 'artefact/lib.php');
$obj = artefact_instance_from_id($oldid);
......
......@@ -8,7 +8,6 @@
<FIELDS>
<FIELD NAME="artefact" TYPE="int" LENGTH="10" NOTNULL="true" />
<FIELD NAME="size" TYPE="int" LENGTH="10" NOTNULL="false" />
<FIELD NAME="adminfiles" TYPE="int" LENGTH="1" NOTNULL="true" />
<FIELD NAME="oldextension" TYPE="text" NOTNULL="false" />
</FIELDS>
<KEYS>
......
......@@ -36,10 +36,11 @@ $fileid = param_integer('id');
require_once(get_config('docroot') . 'artefact/lib.php');
$artefact = artefact_instance_from_id($fileid);
if (!$USER->can_edit_artefact($artefact)) {
json_reply('local', get_string('nodeletepermission', 'mahara'));
}
$artefact->delete();
global $USER;
json_reply(false, array('message' => get_string('filethingdeleted', 'artefact.file',
get_string($artefact->get('artefacttype'),
'artefact.file')),
......
......@@ -68,22 +68,21 @@ else {
// If the file is in the public directory, it's fine to serve
$fileispublic = $file->get('parent') == ArtefactTypeFolder::admin_public_folder_id();
$fileispublic &= $file->get('adminfiles');
$fileispublic &= $file->get('institution') == 'mahara';
$fileispublic &= record_exists('site_menu', 'file', $fileid, 'public', 1);
if (!$fileispublic) {
// If the file is in the logged in menu and the user is logged in then
// they can view it
$fileinloggedinmenu = $file->get('adminfiles');
$fileinloggedinmenu = $file->get('institution') == 'mahara';
$fileinloggedinmenu &= $file->get('parent') == null;
$fileinloggedinmenu &= record_exists('site_menu', 'file', $fileid, 'public', 0);
$fileinloggedinmenu &= $USER->is_logged_in();
if (!$fileinloggedinmenu) {
// Alternatively, if you own the file or you are an admin, it should always work
$fileisavailable = $USER->get('admin') || $file->get('owner') == $USER->get('id');
if (!$fileisavailable) {
if (!$USER->can_view_artefact($file)) {
throw new AccessDeniedException();
}
}
......
<?php
/**
* Mahara: Electronic portfolio, weblog, resume builder and social networking
* Copyright (C) 2006-2008 Catalyst IT Ltd (http://www.catalyst.net.nz)
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package mahara
* @subpackage artefact-file
* @author Catalyst IT Ltd
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL
* @copyright (C) 2006-2008 Catalyst IT Ltd http://catalyst.net.nz
*
*/
define('INTERNAL', 1);
define('MENUITEM', 'groups');
require(dirname(dirname(dirname(__FILE__))) . '/init.php');
require_once(get_config('libroot') . 'group.php');
safe_require('artefact', 'file');
$javascript = ArtefactTypeFileBase::get_my_files_js(param_integer('folder', null));
$groupid = param_integer('group');
if (!$group = get_record('group', 'id', $groupid, 'deleted', 0)) {
throw new GroupNotFoundException("Couldn't find group with id $groupid");
}
if (!group_user_access($groupid)) {
throw new AccessDeniedException();
}
define('TITLE', $group->name . ' - ' . get_string('groupfiles', 'artefact.file'));
require_once(get_config('docroot') . 'interaction/lib.php');
$groupdata = json_encode($group);
$grouproles = json_encode(array_values(group_get_role_info($groupid)));
$javascript .= <<<GROUPJS
var group = {$groupdata};
group.roles = {$grouproles};
browser.setgroup({$groupid});
uploader.setgroup({$groupid});
GROUPJS;
$smarty = smarty(
array('tablerenderer', 'artefact/file/js/file.js'),
array(),
array(),
array(
'sideblocks' => array(
interaction_sideblock($groupid),
),
)
);
$smarty->assign('heading', $group->name);
$smarty->assign('groupid', $groupid);
$smarty->assign('grouptabs', group_get_menu_tabs($group));
$smarty->assign('INLINEJAVASCRIPT', $javascript);
$smarty->display('artefact:file:index.tpl');
?>
......@@ -34,46 +34,7 @@ require(dirname(dirname(dirname(__FILE__))) . '/init.php');
define('TITLE', get_string('myfiles', 'artefact.file'));
safe_require('artefact', 'file');
$folder_id = param_integer('folder', null);
if ($folder_id) {
$folder_list = array();
$current_folder = get_record('artefact', 'id', $folder_id);
if ($current_folder->artefacttype == 'folder') {
$folder_list[] = array(
'id' => $current_folder->id,
'name' => $current_folder->title,
);
}
while ($current_folder->parent) {
$current_folder = get_record('artefact', 'id', $current_folder->parent);
$folder_list[] = array(
'id' => $current_folder->id,
'name' => $current_folder->title,
);
}
$enc_folders = json_encode(array_reverse($folder_list));
}
else {
$enc_folders = json_encode(array());
}
$copyright = get_field('site_content', 'content', 'name', 'uploadcopyright');
$javascript = <<<JAVASCRIPT
var copyrightnotice = '{$copyright}';
var browser = new FileBrowser('filelist', 'myfiles.json.php', null, null, null, null, {$enc_folders});
var uploader = new FileUploader('uploader', 'upload.php', {}, null, null,
browser.refresh, browser.fileexists);
browser.changedircallback = uploader.updatedestination;
JAVASCRIPT;
$javascript = ArtefactTypeFileBase::get_my_files_js(param_integer('folder', null));
$smarty = smarty(
array('tablerenderer', 'artefact/file/js/file.js'),
......@@ -89,8 +50,8 @@ $smarty = smarty(
),
)
);
$smarty->assign('INLINEJAVASCRIPT', $javascript);
$smarty->assign('heading', get_string('myfiles', 'artefact.file'));
$smarty->assign('INLINEJAVASCRIPT', $javascript);
$smarty->display('artefact:file:index.tpl');
?>
......@@ -23,6 +23,53 @@ function ajaxlogin_iframe(form, crap) {
save_orig_data = true;
}
var group = 0;
function getpermissions(formid) {
var result = {};
var perms = getElementsByTagAndClassName('input', 'permission', formid);
for (var i = 0; i < perms.length; i++) {
var parts = perms[i].name.split(":");
if (!result[parts[1]]) {
result[parts[1]] = {};
}
result[parts[1]][parts[2]] = perms[i].checked;
}
return result;
}
var permissiontypes = ['view', 'edit', 'republish'];
function permissionform_inputs(permissions, role) {
var cells = [TD(null, role.display)];
for (var i = 0; i < permissiontypes.length; i++) {
var properties = {
'type':'checkbox',
'class':'permission',
'name':'permission:'+role.name+':'+permissiontypes[i]
};
if (role.name == 'admin' || permissions.all || permissions[role.name] && permissions[role.name][permissiontypes[i]] == 1) {
properties.checked = true;
if (role.name == 'admin') {
properties.disabled = true;
}
}
cells.push(TD(null, INPUT(properties)));
}
return cells;
}
function permissionform_row(permissions) {
if (!group) {
return null;
}
var rows = map(partial(TR, null), map(partial(permissionform_inputs, permissions), group.roles));
return TR(null, TH(null, LABEL(null, get_string('Permissions'))), TD(null,
TABLE({'class':'editpermissions'}, TBODY(null,
TR(null, TH(null, get_string('Role')), map(partial(TH, null), map(get_string, permissiontypes))),
rows))));
}
// The file browser part needs to be kept relatively separated from
// the file uploader because they are used slightly differently in the
// my files screen and the edit blog post screen
......@@ -86,7 +133,7 @@ function FileBrowser(element, source, statevars, changedircallback, actionname,
}
else {
this.lastcolumnfunc = function (r) {
if (r.isparent) {
if (r.isparent || r.can_edit == 0) {
return TD(null);
}
var editb = INPUT({'type':'button', 'class':'button', 'value':get_string('edit')});
......@@ -107,6 +154,11 @@ function FileBrowser(element, source, statevars, changedircallback, actionname,
}
}
this.setgroup = function(gid) {
self.source += '?group=' + gid;
self.createfolderscript += '?group=' + gid;
};
this.init = function() {
if (self.canmodify) {
......@@ -255,6 +307,10 @@ function FileBrowser(element, source, statevars, changedircallback, actionname,
data['description'] = $(formid).description.value;
data['tags'] = $(formid).tags.value;
if (group) {
data['permissions'] = serializeJSON(getpermissions(formid));
}
if (fileid) {
var script = self.updatemetadatascript;
data['id'] = fileid;
......@@ -284,8 +340,14 @@ function FileBrowser(element, source, statevars, changedircallback, actionname,
var cancelbutton = INPUT({'type':'button', 'class':'button',
'value':get_string('cancel'), 'onclick':cancelform});
var editformtitle = get_string(fileinfo.artefacttype == 'folder' ? 'editfolder' : 'editfile');
var edittable = TABLE({'align':'center'},TBODY(null,
TR(null,TH({'colspan':2},LABEL(editformtitle))),
if (group) {
var perm = permissionform_row(fileinfo.permissions);
}
else {
var perm = null;
}
var edittable = TABLE(null, TBODY(null,
TR(null,TH({'colSpan':2},LABEL(editformtitle))),
TR(null,TH(null,LABEL(get_string('Name'))),
TD(null,INPUT({'type':'text','class':'text','name':'name',
'value':fileinfo.title,'size':40}))),
......@@ -294,8 +356,9 @@ function FileBrowser(element, source, statevars, changedircallback, actionname,
'value':fileinfo.description,'size':40}))),
TR(null, TH(null, LABEL(null, get_string('tags'))),
TD(null, create_tags_control('tags', fileinfo.tags))),
TR(null,TD({'colspan':2},SPAN({'id':formid+'message'}))),
TR(null,TD({'colspan':2}, savebutton, replacebutton, cancelbutton))));
perm,
TR(null,TD({'colSpan':2},SPAN({'id':formid+'message'}))),
TR(null,TD({'colSpan':2}, savebutton, replacebutton, cancelbutton))));
hideElement(rowid);
insertSiblingNodesBefore(rowid, TR({'id':editid},
TD({'colSpan':6},
......@@ -329,6 +392,12 @@ function FileBrowser(element, source, statevars, changedircallback, actionname,
cancelcreateform();
}
}});
if (group) {
var perm = permissionform_row({'all':1});
}
else {
var perm = null;
}
return FORM({'method':'post', 'id':formid, 'style':'display: none;'},
TABLE(null,
TBODY(null,
......@@ -342,6 +411,7 @@ function FileBrowser(element, source, statevars, changedircallback, actionname,
TD(null,INPUT({'type':'text','class':'text','name':'description',
'value':'','size':40}))),
TR(null, TH(null, LABEL(null, get_string('tags'))), TD({'colspan':'2'}, create_tags_control('tags'))),
perm,
TR(null,TD({'colspan':2},SPAN({'id':formid+'message'}))),
TR(null,TD({'colspan':2},createbutton,replacebutton,cancelbutton)))));
};
......@@ -504,6 +574,10 @@ function FileUploader(element, uploadscript, statevars, foldername, folderid, up
this.fileexists = function (filename) { alert(filename); };
}
this.setgroup = function(gid) {
self.uploadscript += '?group=' + gid;
};
this.init = function() {
self.nextupload = 1;
......@@ -542,6 +616,12 @@ function FileUploader(element, uploadscript, statevars, foldername, folderid, up
var notice = SPAN(null);
notice.innerHTML = copyrightnotice + get_string('notice.help');
var destinationattributes = (self.folderid === false) ? {'style':'display: none;'} : null;
if (group) {
var perm = permissionform_row({'all':1});
}
else {
var perm = null;
}
appendChildNodes(form,
TABLE(null,
TBODY(null,
......@@ -560,6 +640,7 @@ function FileUploader(element, uploadscript, statevars, foldername, folderid, up
TD(null, INPUT({'type':'text', 'class':'text', 'name':'description', 'size':40}))),
TR(null, TH(null, LABEL(null, get_string('tags'))),
TD({'colspan': 2}, create_tags_control('tags'))),
perm,
TR(null,TD({'colspan':2, 'id':'uploadformmessage'})),
TR(null,TD({'colspan':2},
INPUT({'name':'upload','type':'button','class':'button',
......@@ -643,6 +724,14 @@ function FileUploader(element, uploadscript, statevars, foldername, folderid, up
INPUT({'type':'hidden', 'name':'createid', 'value':self.createid}));
}
if (group) {
appendChildNodes(self.form, INPUT({
'type':'hidden',
'name':'permissions',
'value':serializeJSON(getpermissions('uploadform'))
}));
}
self.form.submit();
// Display upload status
......
......@@ -52,6 +52,7 @@ $string['file'] = 'file';
$string['File'] = 'File';
$string['filealreadyindestination'] = 'The file you moved is already in that folder';
$string['files'] = 'files';
$string['Files'] = 'Files';
$string['fileexists'] = 'File exists';
$string['fileexistsonserver'] = 'A file with the name %s already exists.';
$string['fileexistsoverwritecancel'] = 'A file with that name already exists. You can try a different name, or overwrite the existing file.';
......@@ -63,9 +64,12 @@ $string['filethingdeleted'] = '%s deleted';
$string['filetypes'] = 'Configure Uploadable File Types';
$string['filetypedescription'] = '<p>You may configure the allowed file types that users can upload here. This grants you more control over what can be uploaded. This checking is performed in addition to virus checking, if you have virus checking turned on.</p><p>Note that &quot;Unknown Application&quot; may be necessary for some movies and archive files (such as gzip) to work.<p>';
$string['folder'] = 'Folder';
$string['Folders'] = 'Folders';
$string['foldercreated'] = 'Folder created';
$string['groupfiles'] = 'Group Files';
$string['home'] = 'Home';
$string['htmlremovedmessage'] = 'You are viewing <strong>%s</strong> by <a href="%s">%s</a>. The file displayed below has been filtered to remove malicious content, and is only a rough representation of the original.';
$string['htmlremovedmessagenoowner'] = 'You are viewing <strong>%s</strong>. The file displayed below has been filtered to remove malicious content, and is only a rough representation of the original.';
$string['image'] = 'Image';
$string['lastmodified'] = 'Last Modified';
$string['myfiles'] = 'My Files';
......
<h3>Group Files</h3>
<p>The group files area is a repository for shared folders and files to use within your group's views.</p>
<p>You can use drag and drop to organise group files and folders.</p>
<p>For security reasons your Site Administrator may restrict some file types from being uploaded to the system. </p>
......@@ -55,6 +55,15 @@ class PluginArtefactFile extends PluginArtefact {
);
}
public static function group_tabs($groupid) {
return array(
'files' => array(
'url' => 'artefact/file/groupfiles.php?group='.$groupid,
'title' => get_string('Files', 'artefact.file'),
),
);
}
public static function get_event_subscriptions() {
$subscriptions = array(
(object)array(
......@@ -109,7 +118,10 @@ class PluginArtefactFile extends PluginArtefact {
'cancel',
'delete',
'edit',
'Permissions',
'republish',
'tags',
'view',
),
'artefact.file' => array(
'copyrightnotice',
......@@ -140,6 +152,9 @@ class PluginArtefactFile extends PluginArtefact {
'uploadingfiletofolder',
'youmustagreetothecopyrightnotice',
),
'group' => array(
'Role',
),
),
);
return $jsstrings[$type];
......@@ -255,7 +270,6 @@ class PluginArtefactFile extends PluginArtefact {
abstract class ArtefactTypeFileBase extends ArtefactType {