diff --git a/htdocs/usr.php b/htdocs/usr.php index 3db41adf..41655800 100644 --- a/htdocs/usr.php +++ b/htdocs/usr.php @@ -35,35 +35,6 @@ $c->page_title = $user->Get("user_no"). " - " . $user->Get("fullname"); } } - if ( $_FILES['ics_file']['name'] && $_POST['path_ics'] ) { - $ics = file_get_contents($_FILES['ics_file']['tmp_name']); - $ics = trim($ics); - $path_ics = $_POST['path_ics']; - - if ( substr($path_ics,-1,1) != '/' ) $path_ics .= '/'; // ensure that we target a collection - if ( substr($path_ics,0,1) != '/' ) $path_ics = '/'.$path_ics; // ensure that we target a collection - - if ( $ics !='' ) { - /** - * If the user has uploaded a .ics file as a calendar, we fake this out - * as if it were a "PUT" request against a collection. This is something - * of a hack. It works though :-) - */ - include('check_UTF8.php'); - if ( check_string($ics) ) { - $path = "/".$user->Get("username").$path_ics; - include("caldav-PUT-functions.php"); - if(controlRequestContainer($user->Get("username"),$user->user_no, $path,false) === true ){ - import_collection($ics,$user->user_no,$path,$session->user_no); - $c->messages[] = sprintf(translate("All events of user %s were deleted and replaced by those from the file."),$user->Get("username")); - } - } else - $c->messages[] = sprintf(translate("The file %s is not UTF-8 encoded, please check the error for more details."),$dir.'/'.$file); - } - } - else { - unset($ics); - } } else { /** @@ -85,7 +56,7 @@ $user_menu->AddOption( sprintf(translate("Edit %s"), $user->Values->fullname), "$c->base_url/usr.php?user_no=$user->user_no&edit=1", translate("Edit this user record"), true, 900 ); } else { - $user_menu->AddOption( sprintf(translate("View %s"), $user->Values->fullname), "$c->base_url/usr.php?user_no=$user->user_no", translate("View this user record"), true, 900 ); + $user_menu->AddOption( sprintf(translate("View %s"), $user->Get('fullname')), "$c->base_url/usr.php?user_no=$user->user_no", translate("View this user record"), true, 900 ); } } diff --git a/inc/DAViCalUser.php b/inc/DAViCalUser.php index a52b7d47..41b8f1df 100644 --- a/inc/DAViCalUser.php +++ b/inc/DAViCalUser.php @@ -9,12 +9,14 @@ * @license http://gnu.org/copyleft/gpl.html GNU GPL v2 */ -require("User.php"); -require_once("classBrowser.php"); -require_once("auth-functions.php"); +include('User.php'); +include('classBrowser.php'); +include('auth-functions.php'); +include('check_UTF8.php'); +include('caldav-PUT-functions.php'); -$c->stylesheets[] = "$c->base_url/css/browse.css"; -$c->scripts[] = "$c->base_url/js/browse.js"; +$c->stylesheets[] = $c->base_url.'/css/browse.css'; +$c->scripts[] = $c->base_url.'/js/browse.js'; /** * A class for viewing and maintaining DAViCal User records @@ -25,13 +27,15 @@ class DAViCalUser extends User { var $delete_collection_confirmation_required; + var $delete_user_confirmation_required; /** * Constructor - nothing fancy as yet. */ - function DAViCalUser( $id , $prefix = "") { + function DAViCalUser( $id , $prefix = '') { global $c; $this->delete_collection_confirmation_required = null; + $this->delete_user_confirmation_required = null; parent::User( $id, $prefix ); if ( $this->user_no == 0 && isset($c->template_usr) && is_array($c->template_usr) ) { foreach( $c->template_usr AS $k => $v ) { @@ -44,40 +48,50 @@ class DAViCalUser extends User * Render the form / viewer as HTML to show the user * @return string An HTML fragment to display in the page. */ - function Render($title = "" ) { + function Render($title = '' ) { global $c; - $html = ""; - dbg_error_log("User", ":Render: type=$this->WriteType, edit_mode=$this->EditMode" ); + $html = ''; + dbg_error_log('User', ":Render: type=$this->WriteType, edit_mode=$this->EditMode" ); $ef = new EntryForm( $_SERVER['REQUEST_URI'], $this->Values, $this->EditMode ); $ef->NoHelp(); // Prefer this style, for the moment $html = '
'; - $html .= sprintf("

%s

\n", translate("You are ".($ef->EditMode?"editing":"viewing"))." ".translate($title)); + $html .= sprintf('

%s

', translate('You are '.($ef->EditMode?'editing':'viewing')).' '.translate($title)); if ( $ef->EditMode ) { - $html .= $ef->StartForm( array("autocomplete" => "off" ) ); - if ( $this->user_no > 0 ) $html .= $ef->HiddenField( "user_no", $this->user_no ); + $html .= $ef->StartForm( array('autocomplete' => 'off' ) ); + if ( $this->user_no > 0 ) $html .= $ef->HiddenField( 'user_no', $this->user_no ); } - $html .= "\n"; + if ( isset($this->delete_user_confirmation_required) ) { + $html .= '

'; + $html .= sprintf('User: %s: %s', $this->Get('username'), $_SERVER['REQUEST_URI'], $this->delete_user_confirmation_required, translate('Confirm Deletion of the User') ); + $html .= "

\n"; + } - $html .= $this->RenderFields($ef,""); + $html .= '
'; + + $html .= $this->RenderFields($ef,''); $html .= $this->RenderRoles($ef); - $html .= $this->RenderRelationshipsFrom($ef); - $html .= $this->RenderRelationshipsTo($ef); - $html .= $this->RenderCollections($ef); + if ( 'insert' != $this->WriteType ) { + $html .= $this->RenderRelationshipsFrom($ef); + $html .= $this->RenderRelationshipsTo($ef); + $html .= $this->RenderCollections($ef); + } - $html .= $this->RenderImportIcs($ef); - - $html .= "
\n"; - $html .= "
"; + $html .= ''; + $html .= ''; if ( $ef->EditMode ) { $html .= ''; $html .= $ef->EndForm(); } @@ -86,29 +100,6 @@ class DAViCalUser extends User } - /** - * Render input file to import ics in calendar user - * - * @return string The string of html to be output - */ - function RenderImportIcs( $ef, $title = null ) { - if ( !$ef->EditMode ) return; - if ( $title == null ) $title = i18n("Import ICS file to new collection"); - $html = ( $title == "" ? "" : $ef->BreakLine(translate($title)) ); - $html .= sprintf( " %s\n", translate("WARNING: all events in this path will be deleted before inserting all of the ics file")); - $html .= $ef->DataEntryLine( translate("Calendar"), "%s", "text", "path_ics", - array( "size" => 20, - "title" => translate("set the path to store your ics ex:home if you get it by caldav.php/me/home/"), - "help" => translate("WARNING: all events in this path will be deleted before inserting all of the ics file") - ) - , $this->prefix ); - - $html .= $ef->DataEntryLine( translate("Your .ics calendar"), "%s", "file", "ics_file", - array( "size" => 20, "title" => translate("Upload your .ics calendar in ical format ")), $this->prefix ); - return $html; - } - - /** * Render the user's relationships to other users & resources * @@ -117,18 +108,18 @@ class DAViCalUser extends User function RenderRelationshipsFrom( $ef, $title = null ) { global $session, $c; - if ( $title == null ) $title = i18n("Relationships from this user"); + if ( $title == null ) $title = i18n('Relationships from this user'); - $browser = new Browser(""); + $browser = new Browser(''); $browser->AddHidden( 'user_link', "'base_url/usr.php?user_no=' || user_no || '\">' || fullname || ''" ); - $browser->AddColumn( 'rt_name', translate('Relationship') ); - $browser->AddColumn( 'fullname', translate('Linked To'), 'left', '##user_link##' ); + $browser->AddColumn( 'rt_name', translate('Relationship'), 'left w20' ); + $browser->AddColumn( 'fullname', translate('Linked To'), 'left w20', '##user_link##' ); $browser->AddHidden( 'confers' ); - $browser->AddColumn( 'email', translate('EMail') ); + $browser->AddColumn( 'email', translate('EMail'), 'left' ); $browser->SetJoins( 'relationship NATURAL JOIN relationship_type rt LEFT JOIN usr ON (to_user = user_no)' ); - $browser->SetWhere( "from_user = $this->user_no" ); + $browser->SetWhere( 'from_user = '.$this->user_no ); if ( isset( $_GET['o']) && isset($_GET['d']) ) { $browser->AddOrder( $_GET['o'], $_GET['d'] ); @@ -140,7 +131,7 @@ class DAViCalUser extends User } if ( $c->enable_row_linking ) { - $browser->RowFormat( "\n", "\n", '#even' ); + $browser->RowFormat( "\n", "\n", '#even' ); } else { $browser->RowFormat( "\n", "\n", '#even' ); @@ -149,8 +140,8 @@ class DAViCalUser extends User $browser->DoQuery(); - $html = ( $title == "" ? "" : $ef->BreakLine(translate($title)) ); - $html .= " \n"; + $html = ( $title == '' ? '' : $ef->BreakLine(translate($title)) ); + $html .= ''; $html .= $browser->Render(); $html .= "\n"; @@ -166,20 +157,20 @@ class DAViCalUser extends User function RenderRelationshipsTo( $ef, $title = null ) { global $session, $c; - if ( $title == null ) $title = i18n("Relationships to this user"); - $browser = new Browser(""); + if ( $title == null ) $title = i18n('Relationships to this user'); + $browser = new Browser(''); $browser->AddHidden( 'user_link', "'base_url/usr.php?user_no=' || user_no || '\">' || fullname || ''" ); - $browser->AddColumn( 'fullname', translate('Linked From'), 'left', '##user_link##' ); - $browser->AddColumn( 'rt_name', translate('Relationship') ); + $browser->AddColumn( 'fullname', translate('Linked From'), 'left w20', '##user_link##' ); + $browser->AddColumn( 'rt_name', translate('Relationship'), 'left w20' ); $browser->AddHidden( 'confers' ); - $browser->AddColumn( 'email', translate('EMail') ); - if ( $ef->EditMode ) { // && $session->AllowedTo("MaintainRelationships") ) { - $browser->AddColumn( 'delete', translate('Delete'), 'centre', '', "'base_url/usr.php?edit=1&user_no=$this->user_no&action=delete_relationship&from_user=' || user_no || '\">Delete'" ); + $browser->AddColumn( 'email', translate('EMail'), 'left' ); + if ( $ef->EditMode ) { + $browser->AddColumn( 'delete', translate('Delete'), 'centre', '', "'base_url/usr.php?edit=1&user_no=$this->user_no&action=delete_relationship&from_user=' || user_no || '\">Delete'" ); } $browser->SetJoins( 'relationship NATURAL JOIN relationship_type rt LEFT JOIN usr ON (from_user = user_no)' ); - $browser->SetWhere( "to_user = $this->user_no" ); + $browser->SetWhere( 'to_user = '.$this->user_no ); if ( isset( $_GET['o']) && isset($_GET['d']) ) { $browser->AddOrder( $_GET['o'], $_GET['d'] ); @@ -191,14 +182,14 @@ class DAViCalUser extends User $browser->AddOrder( 'fullname', 'A', 0, 1 ); } - $browser->RowFormat( "\n", "\n", '#even' ); + $browser->RowFormat( "\n", "\n", '#even' ); $browser->SetTranslatable( array('rt_name') ); $browser->DoQuery(); /** * Present an extra editable row at the bottom of the browse. */ - if ( $ef->EditMode ) { // && $session->AllowedTo("MaintainRelationships") ) { + if ( $ef->EditMode ) { if ( isset($this->roles['Group']) ) { /** * We only allow individuals to link to groups at this stage. @@ -214,28 +205,28 @@ SELECT user_no, fullname FROM usr EOSQL; if ( ! isset($this->roles['Group']) ) - $nullvalue = translate( "--- select a user, group or resource ---" ); + $nullvalue = translate( '--- select a user, group or resource ---' ); else - $nullvalue = translate( "--- select a user or resource ---" ); - $person_selection = $ef->DataEntryField( "", "lookup", "relate_to", - array("title" => translate("Select the user, resource or group to relate this user to"), - "_null" => $nullvalue, - "_sql" => $sql ) ); + $nullvalue = translate( '--- select a user or resource ---' ); + $person_selection = $ef->DataEntryField( '', 'lookup', 'relate_to', + array('title' => translate('Select the user, resource or group to relate this user to'), + '_null' => $nullvalue, + '_sql' => $sql ) ); - $relationship_type_selection = $ef->DataEntryField( "", "lookup", "relate_as", - array("title" => translate("Select the type of relationship from this user"), - "_null" => translate("--- select a relationship type ---"), - "_sql" => "SELECT rt_id, rt_name FROM relationship_type " ) ); + $relationship_type_selection = $ef->DataEntryField( '', 'lookup', 'relate_as', + array('title' => translate('Select the type of relationship from this user'), + '_null' => translate('--- select a relationship type ---'), + '_sql' => 'SELECT rt_id, rt_name FROM relationship_type ' ) ); $browser->AddRow( array( 'user_link' => $person_selection, 'rt_name' => $relationship_type_selection, /* Since 'fullname' is formatted to display this value */ - 'delete' => sprintf('', htmlspecialchars(translate("Add Relationship"))) + 'delete' => sprintf('', htmlspecialchars(translate('Add Relationship'))) ) ); } - $html = ( $title == "" ? "" : $ef->BreakLine(translate($title)) ); - $html .= " \n"; + $html = ( $title == '' ? '' : $ef->BreakLine(translate($title)) ); + $html .= ''; $html .= $browser->Render(); $html .= "\n"; @@ -251,20 +242,19 @@ EOSQL; function RenderCollections( $ef, $title = null ) { global $session, $c; - if ( $title == null ) $title = i18n("This user's collections"); - $browser = new Browser(""); + if ( $title == null ) $title = i18n('This user\'s collections'); + $browser = new Browser(''); $browser->AddHidden( 'collection_link', "'base_url/collection.php?user_no=' || user_no || '&dav_name=' || dav_name || '\">' || dav_name || ''" ); $browser->AddColumn( 'dav_name', translate('Collection Path'), 'left', '##collection_link##' ); - $browser->AddColumn( 'is_calendar', translate('Is a Calendar?'), 'centre', '', "CASE WHEN is_calendar THEN 'Yes' ELSE 'No' END" ); - $browser->AddColumn( 'created', translate('Created On'), 'centre', '', "to_char(created,'YYYY-MM-DD HH24:MI')" ); - $browser->AddColumn( 'modified', translate('Changed On'), 'centre', '', "to_char(created,'YYYY-MM-DD HH24:MI')" ); + $browser->AddColumn( 'is_calendar', translate('Is a Calendar?'), 'centre', '', 'CASE WHEN is_calendar THEN \'Yes\' ELSE \'No\' END' ); + $browser->AddColumn( 'created', translate('Created On'), 'centre', '', 'to_char(created,\'YYYY-MM-DD HH24:MI\')' ); + $browser->AddColumn( 'modified', translate('Changed On'), 'centre', '', 'to_char(created,\'YYYY-MM-DD HH24:MI\')' ); if ( $ef->EditMode ) { - $browser->AddColumn( 'TRUE', translate('Action'), 'left', "base_url/usr.php?user_no=$this->user_no&dav_name=##URL:dav_name##&action=delete_collection\">Delete" ); + $browser->AddColumn( 'delete', translate('Action'), 'left', '', "'base_url/usr.php?user_no=$this->user_no&dav_name=##URL:dav_name##&action=delete_collection\">Delete'" ); } - $browser->SetJoins( 'collection LEFT JOIN usr USING (user_no)' ); - $browser->SetWhere( "collection.user_no = $this->user_no" ); + $browser->SetWhere( "collection.user_no = $this->user_no AND NOT collection.dav_name LIKE ('/' || usr.username || '/.%')" ); if ( isset( $_GET['o']) && isset($_GET['d']) ) { $browser->AddOrder( $_GET['o'], $_GET['d'] ); @@ -272,16 +262,37 @@ EOSQL; else $browser->AddOrder( 'dav_name', 'A' ); - $browser->RowFormat( "\n", "\n", '#even' ); $browser->DoQuery(); - $html = ( $title == "" ? "" : $ef->BreakLine(translate($title)) ); + /** + * Present an extra editable row at the bottom of the browse. + */ + if ( $ef->EditMode && ('insert' != $this->WriteType) ) { + $calendar_name = $ef->DataEntryField( '', 'text', 'path_ics', + array( 'size' => 10, + 'title' => translate('The calendar name part of the path to store your ics. E.g. the "home" part of "/caldav.php/username/home/"') + ) ); + $calendar_name = '/'.$this->Get('username').'/  ' . $calendar_name . ' /'; + + $icalendar_file = $ef->DataEntryField( '', 'file', 'ics_file', + array( 'size' => 20, 'title' => translate('Upload a .ics calendar in iCalendar format ')) ); + + $browser->AddRow( array( + 'collection_link' => $calendar_name, + 'created' => $icalendar_file, + 'delete' => sprintf('', htmlspecialchars(translate('Create Calendar'))) + ) ); + } + + $browser->RowFormat( "\n", "\n", '#even' ); + + $html = ( $title == '' ? '' : $ef->BreakLine(translate($title)) ); if ( isset($this->delete_collection_confirmation_required) ) { - $html .= "\n"; - $html .= sprintf('Collection: %s: %s', $_GET['dav_name'], $_SERVER['REQUEST_URI'], $this->delete_collection_confirmation_required, translate("Confirm Deletion of the Collection") ); + $html .= ''; + $html .= sprintf('Collection: %s: %s', $_GET['dav_name'], $_SERVER['REQUEST_URI'], $this->delete_collection_confirmation_required, translate('Confirm Deletion of the Collection') ); $html .= "\n"; } - $html .= "\n"; + $html .= ''; $html .= $browser->Render(); $html .= "\n"; @@ -311,12 +322,12 @@ EOSQL; switch( strtolower($whatever) ) { case 'deleterelationship': - $rc = ( $session->AllowedTo("Admin") + $rc = ( $session->AllowedTo('Admin') || ($this->user_no > 0 && $session->user_no == $this->user_no) ); break; case 'deletecollection': - $rc = ( $session->AllowedTo("Admin") + $rc = ( $session->AllowedTo('Admin') || ($this->user_no > 0 && $session->user_no == $this->user_no) ); break; @@ -334,46 +345,68 @@ EOSQL; function HandleAction( $action ) { global $session, $c; - dbg_error_log("User",":HandleAction: Action %s", $action ); + dbg_error_log('User',':HandleAction: Action %s', $action ); switch( $action ) { case 'delete_relationship': - dbg_error_log("User",":HandleAction: Deleting relationship to %d from %d", $this->user_no, $_GET['from_user'] ); - if ( $this->AllowedTo("DeleteRelationship") ) { - dbg_error_log("User",":HandleAction: Deleting relationship to %d from %d", $this->user_no, $_GET['from_user'] ); - $qry = new PgQuery("DELETE FROM relationship WHERE to_user=? AND from_user=?;", $this->user_no, $_GET['from_user'] ); + dbg_error_log('User',':HandleAction: Deleting relationship to %d from %d', $this->user_no, $_GET['from_user'] ); + if ( $this->AllowedTo('DeleteRelationship') ) { + dbg_error_log('User',':HandleAction: Deleting relationship to %d from %d', $this->user_no, $_GET['from_user'] ); + $qry = new PgQuery('DELETE FROM relationship WHERE to_user=? AND from_user=?;', $this->user_no, $_GET['from_user'] ); if ( $qry->Exec() ) { - $c->messages[] = i18n("Relationship deleted"); + $c->messages[] = i18n('Relationship deleted'); } else { - $c->messages[] = i18n("There was an error writing to the database."); + $c->messages[] = i18n('There was an error writing to the database.'); return false; } } return true; case 'delete_collection': - dbg_error_log("User",":HandleAction: Deleting collection %s for user %d", $_GET['dav_name'], $this->user_no ); - if ( $this->AllowedTo("DeleteCollection") ) { + dbg_error_log('User',':HandleAction: Deleting collection %s for user %d', $_GET['dav_name'], $this->user_no ); + if ( $this->AllowedTo('DeleteCollection') ) { if ( $session->CheckConfirmationHash('GET', 'confirm') ) { - dbg_error_log("User",":HandleAction: Allowed to delete collection %s for user %d", $_GET['dav_name'], $this->user_no ); - $qry = new PgQuery("DELETE FROM collection WHERE user_no=? AND dav_name=?;", $this->user_no, $_GET['dav_name'] ); + dbg_error_log('User',':HandleAction: Allowed to delete collection %s for user %d', $_GET['dav_name'], $this->user_no ); + $qry = new PgQuery('DELETE FROM collection WHERE user_no=? AND dav_name=?;', $this->user_no, $_GET['dav_name'] ); if ( $qry->Exec() ) { - $c->messages[] = i18n("Collection deleted"); + $c->messages[] = i18n('Collection deleted'); return true; } else { - $c->messages[] = i18n("There was an error writing to the database."); + $c->messages[] = i18n('There was an error writing to the database.'); return false; } } else { - $c->messages[] = i18n("Please confirm deletion of collection - see below"); + $c->messages[] = i18n('Please confirm deletion of collection - see below'); $this->delete_collection_confirmation_required = $session->BuildConfirmationHash('GET', 'confirm'); return false; } } + case 'delete_user': + dbg_error_log('User',':HandleAction: Deleting user %d', $this->user_no ); + if ( $this->AllowedTo('DeleteUser') ) { + if ( $session->CheckConfirmationHash('GET', 'confirm') ) { + dbg_error_log('User',':HandleAction: Allowed to delete user %d -%s', $this->user_no, $this->get('user_name') ); + $qry = new PgQuery('DELETE FROM usr WHERE user_no=?;', $this->user_no ); + if ( $qry->Exec() ) { + $c->messages[] = i18n('User deleted'); + return true; + } + else { + $c->messages[] = i18n('There was an error writing to the database.'); + return false; + } + } + else { + $c->messages[] = i18n('Please confirm deletion of user'); + $this->delete_user_confirmation_required = $session->BuildConfirmationHash('GET', 'confirm'); + return false; + } + } + default: return false; } @@ -385,7 +418,7 @@ EOSQL; * Write the record to the file */ function Write( ) { - global $session, $c; + global $session, $c, $path_ics; if ( parent::Write() ) { if ( $this->WriteType == 'insert' ) { @@ -394,16 +427,39 @@ EOSQL; CreateDefaultRelationships($username); } if ( isset($_POST['relate_to']) && $_POST['relate_to'] != '' && isset($_POST['relate_as']) && $_POST['relate_as'] != '' && isset($_POST['submit']) && $_POST['submit'] == htmlspecialchars(translate('Add Relationship')) ) { - dbg_error_log("User",":Write: Adding relationship as %d to %d", $_POST['relate_as'], isset($_POST['relate_to'] ) ); - $qry = new PgQuery("INSERT INTO relationship (from_user, to_user, rt_id ) VALUES( ?, $this->user_no, ? )", $_POST['relate_to'], $_POST['relate_as'] ); + dbg_error_log('User',':Write: Adding relationship as %d to %d', $_POST['relate_as'], isset($_POST['relate_to'] ) ); + $qry = new PgQuery('INSERT INTO relationship (from_user, to_user, rt_id ) VALUES( ?, $this->user_no, ? )', $_POST['relate_to'], $_POST['relate_as'] ); if ( $qry->Exec() ) { - $c->messages[] = i18n("Relationship added."); + $c->messages[] = i18n('Relationship added.'); } else { - $c->messages[] = i18n("There was an error writing to the database."); + $c->messages[] = i18n('There was an error writing to the database.'); return false; } } + param_to_global('path_ics', '#^[^/]+$#'); + if ( isset($path_ics) && $path_ics != '' ) { + $ics = ''; + if ( isset($_FILES['ics_file']['tmp_name']) && $_FILES['ics_file']['tmp_name'] != '' ) { + $ics = trim(file_get_contents($_FILES['ics_file']['tmp_name'])); + } + + /** + * If the user has uploaded a .ics file as a calendar, we fake this out + * as if it were a "PUT" request against a collection. This is something + * of a hack. It works though :-) + */ + if ( check_string($ics) ) { + $path = '/'.$this->Get('username').'/'.$path_ics.'/'; + if( controlRequestContainer($this->Get('username'),$this->user_no, $path,false) === true ){ + import_collection($ics,$this->user_no,$path,$session->user_no); + $c->messages[] = sprintf(translate('Calendar "%s" for user "%s" was created.'), $path_ics, $this->Get('username')); + } + } + else { + $c->messages[] = sprintf(translate('The file is not UTF-8 encoded, please check the error for more details.') ); + } + } return true; } return false;