Commit 3f98f87f authored by Richard Mansfield's avatar Richard Mansfield

Merge branch 'viewaccess'

parents dbec09a8 b4cf6ab1
......@@ -44,7 +44,7 @@ define('TITLE', $title);
$createviewform = pieform(create_view_form(null, 'mahara'));
$smarty = smarty();
$smarty = smarty(array('jquery', 'myviews'));
$smarty->assign('PAGEHEADING', TITLE);
$data = View::get_myviews_data($limit, $offset, null, 'mahara');
......
......@@ -51,7 +51,7 @@ class PluginArtefactBlog extends PluginArtefact {
global $USER;
$tab = array(
'path' => 'myportfolio/blogs',
'weight' => 30,
'weight' => 50,
);
if ($USER->get_account_preference('multipleblogs')) {
$tab['url'] = 'artefact/blog/';
......
......@@ -53,7 +53,7 @@ class PluginArtefactFile extends PluginArtefact {
'path' => 'myportfolio/files',
'url' => 'artefact/file/',
'title' => get_string('myfiles', 'artefact.file'),
'weight' => 20,
'weight' => 40,
),
array(
'path' => 'profile/icons',
......@@ -70,7 +70,7 @@ class PluginArtefactFile extends PluginArtefact {
'path' => 'groups/files',
'url' => 'artefact/file/groupfiles.php?group='.$groupid,
'title' => get_string('Files', 'artefact.file'),
'weight' => 60,
'weight' => 70,
),
);
}
......
......@@ -49,7 +49,7 @@ class PluginArtefactPlans extends PluginArtefact {
'path' => 'myportfolio/plans',
'url' => 'artefact/plans/',
'title' => get_string('myplans', 'artefact.plans'),
'weight' => 40,
'weight' => 60,
),
);
}
......
......@@ -121,7 +121,7 @@ $elements['navigation'] = array(
if ($new) {
$elements['submit'] = array(
'type' => 'cancelbackcreate',
'value' => array(get_string('cancel'), get_string('back','collection'), get_string('next') . ': ' . get_string('editaccess', 'collection')),
'value' => array(get_string('cancel'), get_string('back','collection'), get_string('savecollection', 'collection')),
'confirm' => array(get_string('confirmcancelcreatingcollection', 'collection'), null, null),
);
}
......@@ -171,19 +171,22 @@ function manageviews_cancel_submit() {
}
function manageviews_submit(Pieform $form, $values) {
global $collection, $new;
global $collection, $new, $SESSION, $views;
if (param_boolean('back')) {
redirect('/collection/edit.php?id='.$collection->get('id').'&new=1');
}
else {
$collection->set('navigation',(int)$values['navigation']);
$collection->commit();
if ($new) {
redirect('/view/access.php?collection='.$collection->get('id').'&new=1');
}
else {
$collection->set('navigation',(int)$values['navigation']);
$collection->commit();
redirect('/collection/');
if ($views) {
$SESSION->add_ok_msg(get_string('collectioncreatedsuccessfullyshare', 'collection'));
}
else {
$SESSION->add_ok_msg(get_string('collectioncreatedsuccessfully', 'collection'));
}
}
redirect('/collection/');
}
}
......
<?php
/**
* Mahara: Electronic portfolio, weblog, resume builder and social networking
* Copyright (C) 2006-2009 Catalyst IT Ltd and others; see:
* http://wiki.mahara.org/Contributors
*
* 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 core
* @author Catalyst IT Ltd
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL
* @copyright (C) 2006-2009 Catalyst IT Ltd http://catalyst.net.nz
*
*/
define('INTERNAL', 1);
require(dirname(dirname(__FILE__)) . '/init.php');
require_once(get_config('libroot') . 'view.php');
require_once(get_config('libroot') . 'group.php');
define('TITLE', get_string('share', 'view'));
define('MENUITEM', 'groups/share');
define('GROUP', param_integer('group'));
$group = group_current_group();
if (!group_user_can_edit_views($group->id)) {
throw new AccessDeniedException();
}
$accesslists = View::get_accesslists(null, $group->id);
$js = <<<EOF
addLoadEvent(function () {
forEach(getElementsByTagAndClassName('a', 'secreturl', null), function (elem) {
connect(elem, 'onclick', function(e) {
e.stop();
var displayelem = getFirstElementByTagAndClassName(null, 'expandurl', getFirstParentByTagAndClassName(elem, null, 'accesslistitem'));
toggleElementClass('hidden', displayelem);
});
});
});
EOF;
$smarty = smarty();
$smarty->assign('PAGEHEADING', TITLE);
$smarty->assign('INLINEJAVASCRIPT', $js);
$smarty->assign('accesslists', $accesslists);
$smarty->display('view/share.tpl');
$j = jQuery;
$j(function() {
$j('.expand').click(function(e) {
e.preventDefault();
$j('#' + this.id + '-expand').toggleClass('js-hidden');
});
});
\ No newline at end of file
......@@ -48,6 +48,7 @@ $string['collectionaccesseditedsuccessfully'] = 'Collection access saved success
$string['collectioneditaccess'] = 'You are editing access for %d Views in this Collection';
$string['collectionconfirmdelete'] = 'Views in this collection will not be deleted. Are you sure you wish to delete this collection?';
$string['collectioncreatedsuccessfully'] = 'Collection created successfully.';
$string['collectioncreatedsuccessfullyshare'] = 'Your collection has been created successfully. Share your collection with others using the access links below.';
$string['collectiondeleted'] = 'Collection deleted successfully.';
$string['collectiondescription'] = 'A Collection is a set of Views that are linked to one another and have the same access permissions. You can create as many collections as you like, but a View cannot appear in more than one collection.';
$string['confirmcancelcreatingcollection'] = 'This Collection has not been completed. Do you really want to cancel?';
......
......@@ -182,6 +182,7 @@ $string['notamember'] = 'You are not a member of this group';
$string['notmembermayjoin'] = 'You must join the group \'%s\' to see this page.';
$string['declinerequestsuccess'] = 'Group membership request has been declined sucessfully.';
$string['notpublic'] = 'This group is not public.';
$string['moregroups'] = 'More groups';
// Bulk add, invite
$string['addmembers'] = 'Add members';
......
......@@ -881,6 +881,8 @@ $string['Created'] = 'Created';
$string['Updated'] = 'Updated';
$string['Total'] = 'Total';
$string['Visits'] = 'Visits';
$string['after'] = 'after';
$string['before'] = 'before';
// import related strings (maybe separated later)
$string['importedfrom'] = 'Imported from %s';
......
......@@ -39,6 +39,7 @@ $string['title'] = 'View Title';
$string['description'] = 'View Description';
$string['startdate'] = 'Access Start Date/Time';
$string['stopdate'] = 'Access End Date/Time';
$string['accessdates'] = 'Access Date/Time';
$string['stopdatecannotbeinpast'] = 'The stop date cannot be in the past';
$string['startdatemustbebeforestopdate'] = 'The start date must be before the stop date';
$string['unrecogniseddateformat'] = 'Unrecognised date format';
......@@ -49,6 +50,7 @@ $string['profileviewtitle'] = 'Profile View';
$string['dashboardviewtitle'] = 'Dashboard View';
$string['editprofileview'] = 'Edit profile view';
$string['grouphomepageviewtitle'] = 'Group Homepage View';
$string['showdescription'] = 'Show Description';
// my views
$string['artefacts'] = 'Artefacts';
......@@ -75,6 +77,7 @@ $string['viewsubmittedtogroupon'] = 'This View was submitted to <a href="%s">%s<
$string['nobodycanseethisview2'] = 'Only you can see this View';
$string['noviews'] = 'No Views.';
$string['youhavenoviews'] = 'You have no Views.';
$string['youhaventcreatedanyviewsyet'] = "You haven't created any Views yet.";
$string['youhaveoneview'] = 'You have 1 View.';
$string['youhaveviews'] = 'You have %s Views.';
$string['viewsownedbygroup'] = 'Views owned by this group';
......@@ -91,14 +94,18 @@ $string['loggedin'] = 'Logged In Users';
$string['friends'] = 'Friends';
$string['groups'] = 'Groups';
$string['users'] = 'Users';
$string['friendslower'] = 'friends';
$string['grouplower'] = 'group';
$string['tutors'] = 'tutors';
$string['loggedinlower'] = 'logged in users';
$string['publiclower'] = 'public';
$string['everyoneingroup'] = 'Everyone in Group';
// secret url
$string['token'] = 'Secret URL';
$string['peoplewiththesecreturl'] = 'People with the Secret URL';
$string['editsecreturlaccess'] = 'Edit secret URL access';
$string['newsecreturl'] = 'New Secret URL';
$string['reallydeletesecreturl'] = 'Are you sure you want to delete this url?';
$string['secreturldeleted'] = 'Your secret URL was deleted.';
$string['secreturlupdated'] = 'Secret URL updated';
$string['generatesecreturl'] = 'Generate a new secret URL for %s';
$string['secreturls'] = 'Secret URLs';
// view user
$string['inviteusertojoingroup'] = 'Invite this user to join a group';
......@@ -133,6 +140,12 @@ $string['profileicon'] = 'Profile Icon';
// general views stuff
$string['Added'] = 'Added';
$string['share'] = 'Share';
$string['sharewith'] = 'Share with';
$string['accesslist'] = 'Access list';
$string['sharewithmygroups'] = 'Share with My Groups';
$string['otherusersandgroups'] = 'Share with other users and groups';
$string['moreoptions'] = 'Advanced Options';
$string['allviews'] = 'All Views';
$string['submitviewconfirm'] = 'If you submit \'%s\' to \'%s\' for assessment, you will not be able to edit the View until your tutor has finished marking the View. Are you sure you want to submit this View now?';
......@@ -145,8 +158,8 @@ $string['deletespecifiedview'] = 'Delete View "%s"';
$string['deleteviewconfirm'] = 'Do you really want to delete this View? It cannot be undone.';
$string['deleteviewconfirmnote'] = '<p><strong>Note:</strong> all the content blocks that have been added to the view will not be deleted. However, any feedback placed against the view will be deleted. Consider backing up the view by exporting it first.</p>';
$string['editaccessdescription'] = '<p>By default, only you can see your %s. You can share your %s with others by adding access rules on this page.</p>
<p>Once you are done, scroll down and click Save to continue.</p>';
$string['editaccesspagedescription3'] = 'By default, only you can see your Views. You can share views with others by adding access rules on this page. Once you are done, scroll down and click Save to continue.';
$string['editaccessinvalidviewset'] = 'Attempt to edit access on an invalid set of views and collections';
$string['overridingstartstopdate'] = 'Overriding Start/Stop Dates';
$string['overridingstartstopdatesdescription'] = 'If you want, you can set an overriding start and/or stop date. Other people will not be able to see your View before the start date and after the end date, regardless of any other access you have granted.';
......@@ -163,7 +176,8 @@ $string['submittedforassessment'] = 'Submitted for assessment';
$string['addtutors'] = 'Add Tutors';
$string['viewcreatedsuccessfully'] = 'View created successfully';
$string['viewaccesseditedsuccessfully'] = 'View access saved successfully';
$string['viewcreatedsuccessfullyshare'] = 'Your View has been created. You can share your view with others by adding access rules below.';
$string['updatedaccessfornumviews'] = 'Access rules were updated for %d View(s)';
$string['viewsavedsuccessfully'] = 'View saved successfully';
$string['invalidcolumn'] = 'Column %s out of range';
......
......@@ -294,6 +294,7 @@ class Collection {
* @return integer count so we know what SESSION message to display
*/
public function add_views($values) {
require_once(get_config('libroot') . 'view.php');
$count = 0; // how many views we are adding
db_begin();
......@@ -315,7 +316,24 @@ class Collection {
}
}
$this->combine_access();
$viewids = get_column('collection_view', 'view', 'collection', $this->id);
// Set the most permissive access records on all views
View::combine_access($viewids, true);
// Copy the whole view config from the first view to all the others
if (count($viewids)) {
$firstview = new View($viewids[0]);
$viewconfig = array(
'startdate' => $firstview->get('startdate'),
'stopdate' => $firstview->get('stopdate'),
'template' => $firstview->get('template'),
'allowcomments' => $firstview->get('allowcomments'),
'approvecomments' => (int) ($firstview->get('allowcomments') && $firstview->get('approvecomments')),
'accesslist' => $firstview->get_access(),
);
View::update_view_access($viewconfig, $viewids);
}
db_commit();
......@@ -338,79 +356,6 @@ class Collection {
db_commit();
}
/**
* Update access in collection
*
* Copy access records from one view to all other views
*/
public function set_access($viewid) {
if (!$views = $this->views()) {
return;
}
if ($views['count'] < 2) {
return;
}
$toupdate = array();
foreach ($views['views'] as &$v) {
if ($v->view != $viewid) {
$toupdate[] = $v->view;
}
}
if (count($toupdate) != $views['count'] - 1) {
throw new SystemException('error setting collection access');
}
db_begin();
delete_records_select('view_access', 'view IN (' . join(',', $toupdate) . ') AND visible = 1');
$this->combine_access();
db_commit();
}
/**
* Synchronise access records across all views in the collection by
* copying all access records to all views
*
* @todo: allow access records to apply to things other than views,
* (e.g. collections), so we don't have to do this.
*/
public function combine_access() {
if (!$viewids = get_column('collection_view', 'view', 'collection', $this->id)) {
return;
}
$select = 'view IN (' . join(',', $viewids) . ') AND visible = 1';
if (!$access = get_records_select_array('view_access', $select)) {
return;
}
$unique = array();
foreach ($access as &$a) {
unset($a->view);
$k = serialize($a);
if (!isset($unique[$k])) {
$unique[$k] = $a;
}
}
db_begin();
delete_records_select('view_access', $select);
foreach ($unique as &$a) {
foreach ($viewids as $id) {
$a->view = $id;
insert_record('view_access', $a);
}
}
db_commit();
}
/**
* Sets the displayorder for a view
*
......
......@@ -615,6 +615,7 @@
<FIELD NAME="visits" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" />
<FIELD NAME="allowcomments" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="1" />
<FIELD NAME="approvecomments" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" />
<FIELD NAME="accessconf" TYPE="char" LENGTH="40" NOTNULL="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id" />
......
......@@ -2228,5 +2228,12 @@ function xmldb_core_upgrade($oldversion=0) {
set_field('institution', 'priority', 0, 'name', 'mahara');
}
if ($oldversion < 2010122201) {
$table = new XMLDBTable('view');
$field = new XMLDBField('accessconf');
$field->setAttributes(XMLDB_TYPE_CHAR, 40, XMLDB_UNSIGNED, null);
add_field($table, $field);
}
return $status;
}
<?php
/**
* Mahara: Electronic portfolio, weblog, resume builder and social networking
* Copyright (C) 2006-2009 Catalyst IT Ltd and others; see:
* http://wiki.mahara.org/Contributors
*
* 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 form-element
* @author Catalyst IT Ltd
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL
* @copyright (C) 2006-2009 Catalyst IT Ltd http://catalyst.net.nz
*
*/
function pieform_element_checkboxes(Pieform $form, $element) {/*{{{*/
$global = ($form->get_property('method') == 'get') ? $_GET : $_POST;
$submitted = $form->is_submitted();
if ($submitted && isset($global[$element['name']])) {
$value = $global[$element['name']];
}
$element['name'] .= '[]';
$result = '';
foreach ($element['elements'] as $e) {
$checked = ($submitted && !empty($value[$e['value']])) || (!$submitted && !empty($e['defaultvalue']));
$result .= '<div class="checkboxes-option"><input type="checkbox" value="' . $e['value'] . '" '
. $form->element_attributes($element)
. ($checked ? ' checked="checked"' : '')
. '>' . Pieform::hsc(str_shorten_text($e['title'], 17, true)) . '</div>';
}
$result .= '<div class="cl"></div>';
return $result;
}/*}}}*/
function pieform_element_checkboxes_get_value(Pieform $form, $element) {/*{{{*/
$global = ($form->get_property('method') == 'get') ? $_GET : $_POST;
if (isset($element['value'])) {
$values = (array) $element['value'];
}
else if ($form->is_submitted() && isset($global[$element['name']])) {
$values = (array) $global[$element['name']];
}
else if (!$form->is_submitted() && isset($element['defaultvalue'])) {
$values = (array) $element['defaultvalue'];
}
else {
$values = array();
}
return $values;
}/*}}}*/
......@@ -33,6 +33,7 @@
* @return string The HTML for the element
*/
function pieform_element_viewacl(Pieform $form, $element) {
global $USER;
$smarty = smarty_core();
$smarty->left_delimiter = '{{';
$smarty->right_delimiter = '}}';
......@@ -51,9 +52,6 @@ function pieform_element_viewacl(Pieform $form, $element) {
if ($form->get_property('userview')) {
$presets[] = 'friends';
}
if ($public) {
$presets[] = 'token';
}
if ($value) {
foreach ($value as $key => &$item) {
......@@ -65,6 +63,9 @@ function pieform_element_viewacl(Pieform $form, $element) {
else {
$item['name'] = pieform_render_viewacl_getvaluebytype($item['type'], $item['id']);
}
if (mb_strlen($item['name']) > 30) {
$item['shortname'] = str_shorten_text($item['name'], 30, true);
}
// only show access that is still current. Expired access will be deleted if the form is saved
if($item['stopdate'] && (time() > strtotime($item['stopdate']))) {
unset($value[$key]);
......@@ -87,12 +88,38 @@ function pieform_element_viewacl(Pieform $form, $element) {
'preset' => true
);
}
$allgroups = array(
'type' => 'allgroups',
'id' => 'allgroups',
'start' => null,
'end' => null,
'name' => get_string('allmygroups', 'group'),
'preset' => true
);
$mygroups = array();
foreach (group_get_user_groups($USER->get('id')) as $g) {
$mygroups[] = array(
'type' => 'group',
'id' => $g->id,
'start' => null,
'end' => null,
'name' => $g->name,
'preset' => false
);
if (mb_strlen($g->name) > 30) {
$mygroups[key($mygroups)]['shortname'] = str_shorten_text($g->name, 30, true);
}
}
$smarty->assign('potentialpresets', json_encode($potentialpresets));
$smarty->assign('loggedinindex', $loggedinindex);
$smarty->assign('accesslist', json_encode($value));
$smarty->assign('viewid', $form->get_property('viewid'));
$smarty->assign('formname', $form->get_property('name'));
$smarty->assign('allowcomments', $element['allowcomments']);
$smarty->assign('allgroups', json_encode($allgroups));
$smarty->assign('mygroups', json_encode($mygroups));
return $smarty->fetch('form/viewacl.tpl');
}
......
......@@ -1055,6 +1055,12 @@ function group_get_menu_tabs() {
'title' => get_string('Views', 'group'),
'weight' => 50,
);
$menu['share'] = array(
'path' => 'groups/share',
'url' => 'group/shareviews.php?group='.$group->id,
'title' => get_string('share', 'view'),
'weight' => 60,
);
if (group_user_access($group->id)) {
safe_require('grouptype', $group->grouptype);
......
......@@ -38,11 +38,15 @@ $_PIEFORM_FIELDSETS = array();
function pieform_element_fieldset(Pieform $form, $element) {/*{{{*/
global $_PIEFORM_FIELDSETS;
$result = "\n<fieldset";
if (!empty($element['collapsible']) || !empty($element['class'])) {
$classes = array('pieform-fieldset');
if (!empty($element['class'])) {
$classes[] = Pieform::hsc($element['class']);
}
if (!empty($element['collapsible'])) {
if (!isset($element['legend']) || $element['legend'] === '') {
Pieform::info('Collapsible fieldsets should have a legend so they can be toggled');
}
$classes = array('collapsible');
$classes[] = 'collapsible';
$formname = $form->get_name();
if (!isset($_PIEFORM_FIELDSETS['forms'][$formname])) {
$_PIEFORM_FIELDSETS['forms'][$formname] = array('formname' => $formname);
......@@ -58,11 +62,8 @@ function pieform_element_fieldset(Pieform $form, $element) {/*{{{*/
if (!empty($element['collapsed']) && !$error) {
$classes[] = 'collapsed';
}
if (!empty($element['class'])) {
$classes[] = Pieform::hsc($element['class']);
}
$result .= ' class="' . implode(' ', $classes) . '"';
}
$result .= ' class="' . implode(' ', $classes) . '"';
$result .= ">\n";
if (isset($element['legend'])) {
$result .= '<legend>';
......@@ -104,6 +105,9 @@ function pieform_update_legends(element) {
element = getFirstElementByTagAndClassName('body');
}
forEach(getElementsByTagAndClassName('fieldset', 'collapsible', element), function(fieldset) {
if (!hasElementClass(fieldset, 'pieform-fieldset')) {
return;
}
var legend = getFirstElementByTagAndClassName('legend', null, fieldset);
if (legend.firstChild.tagName == 'A') {
connect(legend.firstChild, 'onclick', function(e) {
......
......@@ -38,6 +38,9 @@ function pieform_element_image(Pieform $form, $element) {/*{{{*/
if (!isset($element['value'])) {
$element['value'] = true;
}
if (isset($element['confirm'])) {
$element['onclick'] = 'return confirm(' . json_encode($element['confirm']) . ');';
}
return '<input type="image" src="' . Pieform::hsc($element['src']) . '"'
. $form->element_attributes($element)
. ' value="' . Pieform::hsc($form->get_value($element)) . '">';
......
......@@ -28,7 +28,7 @@
defined('INTERNAL') || die();
$config = new StdClass;
$config->version = 2010122200;
$config->version = 2010122201;
$config->release = '1.4.0dev';
$config->minupgradefrom = 2008040200;
$config->minupgraderelease = '1.0.0 (release tag 1.0.0_RELEASE)';
......
This diff is collapsed.
......@@ -1951,18 +1951,24 @@ function mahara_standard_nav() {
'title' => get_string('myviews'),
'weight' => 10,
),
array(
'path' => 'myportfolio/share',
'url' => 'view/share.php',