mirror of
https://gitlab.com/davical-project/davical.git
synced 2026-01-27 00:33:34 +00:00
Kinda working with both Lightning & Evolution now. About to restructure to
add TODO items and make certain queries easier.
This commit is contained in:
parent
acc28c0faa
commit
a57d690167
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,4 @@
|
||||
caldav.session
|
||||
rscds.session
|
||||
build
|
||||
rscds.bfproject
|
||||
|
||||
@ -4,11 +4,10 @@
|
||||
// $c->admin_email = 'andrew@catalyst.net.nz';
|
||||
// $c->system_name = "Really Simple CalDAV Store";
|
||||
|
||||
$c->pg_connect[] = 'dbname=rscds port=5433 user=general';
|
||||
$c->pg_connect[] = 'dbname=rscds port=5432 user=general';
|
||||
$c->pg_connect[] = 'dbname=caldav port=5433 user=general';
|
||||
$c->pg_connect[] = 'dbname=caldav port=5432 user=general';
|
||||
|
||||
$c->dbg['vevent'] = 1;
|
||||
$c->dbg['put'] = 1;
|
||||
$c->dbg['report'] = 1;
|
||||
$c->dbg['ALL'] = 1;
|
||||
$debuggroups['querystring'] = 1;
|
||||
|
||||
?>
|
||||
@ -5,31 +5,34 @@
|
||||
\i /usr/share/awl/dba/awl-tables.sql
|
||||
\i /usr/share/awl/dba/schema-management.sql
|
||||
|
||||
CREATE TABLE ics_event_data (
|
||||
-- The main event. Where we store the things the calendar throws at us.
|
||||
CREATE TABLE caldav_data (
|
||||
user_no INT references usr(user_no),
|
||||
ics_event_name TEXT,
|
||||
ics_event_etag TEXT,
|
||||
ics_raw_data TEXT,
|
||||
dav_name TEXT,
|
||||
dav_etag TEXT,
|
||||
caldav_data TEXT,
|
||||
caldav_type TEXT,
|
||||
logged_user INT references usr(user_no),
|
||||
|
||||
PRIMARY KEY ( user_no, ics_event_name, ics_event_etag )
|
||||
PRIMARY KEY ( user_no, vevent_name, vevent_etag )
|
||||
);
|
||||
|
||||
GRANT SELECT,INSERT,UPDATE,DELETE ON ics_event_data TO general;
|
||||
GRANT SELECT,INSERT,UPDATE,DELETE ON vevent_data TO general;
|
||||
|
||||
|
||||
CREATE TABLE time_zones (
|
||||
tzid TEXT PRIMARY KEY,
|
||||
location TEXT,
|
||||
tz_spec TEXT,
|
||||
pgtz TEXT
|
||||
-- Not particularly needed, perhaps, except as a way to collect
|
||||
-- a bunch of valid iCalendar time zone specifications... :-)
|
||||
CREATE TABLE time_zone (
|
||||
tz_id TEXT PRIMARY KEY,
|
||||
tz_locn TEXT,
|
||||
tz_spec TEXT
|
||||
);
|
||||
GRANT SELECT,INSERT ON time_zones TO general;
|
||||
GRANT SELECT,INSERT ON time_zone TO general;
|
||||
|
||||
|
||||
CREATE TABLE ical_events (
|
||||
-- The parsed event. Here we have pulled those events apart somewhat.
|
||||
CREATE TABLE event (
|
||||
user_no INT references usr(user_no),
|
||||
ics_event_name TEXT,
|
||||
ics_event_etag TEXT,
|
||||
vevent_name TEXT,
|
||||
vevent_etag TEXT,
|
||||
|
||||
-- Extracted vEvent event data
|
||||
uid TEXT,
|
||||
@ -42,12 +45,33 @@ CREATE TABLE ical_events (
|
||||
transp TEXT,
|
||||
description TEXT,
|
||||
rrule TEXT,
|
||||
tzid TEXT REFERENCES time_zones( tzid ),
|
||||
tz_id TEXT REFERENCES time_zone( tz_id ),
|
||||
|
||||
-- Cascade updates / deletes from the ics_event_data table
|
||||
CONSTRAINT ics_event_exists FOREIGN KEY ( user_no, ics_event_name, ics_event_etag )
|
||||
REFERENCES ics_event_data ( user_no, ics_event_name, ics_event_etag )
|
||||
-- Cascade updates / deletes from the vevent_data table
|
||||
CONSTRAINT vevent_exists FOREIGN KEY ( user_no, vevent_name, vevent_etag )
|
||||
REFERENCES vevent_data ( user_no, vevent_name, vevent_etag )
|
||||
MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE
|
||||
);
|
||||
|
||||
GRANT SELECT,INSERT,UPDATE,DELETE ON ical_events TO general;
|
||||
GRANT SELECT,INSERT,UPDATE,DELETE ON event TO general;
|
||||
|
||||
-- Each user can be related to each other user. This mechanism can also
|
||||
-- be used to define groups of users, since some relationships are transitive.
|
||||
CREATE TABLE relationship_type (
|
||||
rt_id SERIAL PRIMARY KEY,
|
||||
rt_name TEXT,
|
||||
rt_isgroup BOOLEAN,
|
||||
rt_inverse INT,
|
||||
confers TEXT DEFAULT 'RW',
|
||||
prefix_match TEXT DEFAULT ''
|
||||
);
|
||||
|
||||
GRANT SELECT,INSERT,UPDATE,DELETE ON relationship_type TO general;
|
||||
|
||||
CREATE TABLE relationship (
|
||||
from_user INT REFERENCES usr (user_no) ON UPDATE CASCADE,
|
||||
to_user INT REFERENCES usr (user_no) ON UPDATE CASCADE,
|
||||
rt_id INT REFERENCES relationship_type (rt_id) ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
GRANT SELECT,INSERT,UPDATE,DELETE ON relationship TO general;
|
||||
|
||||
@ -3,4 +3,67 @@
|
||||
INSERT INTO usr ( user_no, active, email_ok, updated, username, password, fullname, email )
|
||||
VALUES( 1, TRUE, current_date, current_date, 'admin', '**nimda', 'Calendar Administrator', 'calendars@example.net' );
|
||||
|
||||
SELECT setval('usr_user_no_seq', 1);
|
||||
INSERT INTO usr ( user_no, active, email_ok, updated, username, password, fullname, email )
|
||||
VALUES( 2, TRUE, current_date, current_date, 'andrew', '**x', 'Andrew McMillan', 'andrew@catalyst.net.nz' );
|
||||
|
||||
INSERT INTO usr ( user_no, active, email_ok, updated, username, password, fullname, email )
|
||||
VALUES( 10, TRUE, current_date, current_date, 'user1', '**user1', 'User 1', 'user1@example.net' );
|
||||
INSERT INTO usr ( user_no, active, email_ok, updated, username, password, fullname, email )
|
||||
VALUES( 11, TRUE, current_date, current_date, 'user2', '**user2', 'User 2', 'user2@example.net' );
|
||||
|
||||
INSERT INTO usr ( user_no, active, email_ok, updated, username, password, fullname, email )
|
||||
VALUES( 20, TRUE, current_date, current_date, 'manager1', '**manager1', 'Manager 1', 'manager1@example.net' );
|
||||
|
||||
INSERT INTO usr ( user_no, active, email_ok, updated, username, password, fullname, email )
|
||||
VALUES( 30, TRUE, current_date, current_date, 'assistant1', '**assistant1', 'Assistant 1', 'assistant1@example.net' );
|
||||
|
||||
INSERT INTO usr ( user_no, active, email_ok, updated, username, password, fullname, email )
|
||||
VALUES( 100, TRUE, current_date, current_date, 'resource1', '*salt*unpossible', 'Resource 1', 'resource1@example.net' );
|
||||
INSERT INTO usr ( user_no, active, email_ok, updated, username, password, fullname, email )
|
||||
VALUES( 101, TRUE, current_date, current_date, 'resource2', '*salt*unpossible', 'Resource 2', 'resource2@example.net' );
|
||||
|
||||
INSERT INTO usr ( user_no, active, email_ok, updated, username, password, fullname, email )
|
||||
VALUES( 200, TRUE, current_date, current_date, 'resmgr1', '*salt*unpossible', 'Resource Managers', 'resource-managers@example.net' );
|
||||
|
||||
INSERT INTO usr ( user_no, active, email_ok, updated, username, password, fullname, email )
|
||||
VALUES( 300, TRUE, current_date, current_date, 'teamclient1', '*salt*unpossible', 'Team for Client1', 'team-client1@example.net' );
|
||||
|
||||
SELECT setval('usr_user_no_seq', 1000);
|
||||
|
||||
INSERT INTO roles ( role_no, role_name ) VALUES( 1, 'Admin');
|
||||
|
||||
SELECT setval('roles_role_no_seq', 1);
|
||||
|
||||
INSERT INTO role_member (user_no, role_no) VALUES( 1, 1);
|
||||
|
||||
INSERT INTO relationship_type ( rt_id, rt_name, rt_isgroup, rt_inverse, confers, prefix_match )
|
||||
VALUES( 1, 'Meeting Admin', TRUE, NULL, 'RW', '' );
|
||||
|
||||
INSERT INTO relationship_type ( rt_id, rt_name, rt_isgroup, rt_inverse, confers, prefix_match )
|
||||
VALUES( 2, 'Assisted by', FALSE, 3, 'RW', '' );
|
||||
|
||||
INSERT INTO relationship_type ( rt_id, rt_name, rt_isgroup, rt_inverse, confers, prefix_match )
|
||||
VALUES( 3, 'Assistant to', FALSE, 2, 'RW', '' );
|
||||
|
||||
INSERT INTO relationship_type ( rt_id, rt_name, rt_isgroup, rt_inverse, confers, prefix_match )
|
||||
VALUES( 4, 'Team Member', FALSE, 4, 'R', '' );
|
||||
|
||||
INSERT INTO relationship_type ( rt_id, rt_name, rt_isgroup, rt_inverse, confers, prefix_match )
|
||||
VALUES( 5, 'Meeting Resource', TRUE, NULL, 'RW', '' );
|
||||
|
||||
-- The resources for meetings
|
||||
INSERT INTO relationship ( from_user, to_user, rt_id ) VALUES( 200, 100, 5 );
|
||||
INSERT INTO relationship ( from_user, to_user, rt_id ) VALUES( 200, 101, 5 );
|
||||
|
||||
-- The people who administer meetings
|
||||
INSERT INTO relationship ( from_user, to_user, rt_id ) VALUES( 10, 200, 1 );
|
||||
INSERT INTO relationship ( from_user, to_user, rt_id ) VALUES( 11, 200, 1 );
|
||||
INSERT INTO relationship ( from_user, to_user, rt_id ) VALUES( 30, 200, 1 );
|
||||
|
||||
-- Between a Manager and their PA
|
||||
INSERT INTO relationship ( from_user, to_user, rt_id ) VALUES( 20, 30, 2 );
|
||||
|
||||
-- Between a team
|
||||
INSERT INTO relationship ( from_user, to_user, rt_id ) VALUES( 20, 300, 4 );
|
||||
INSERT INTO relationship ( from_user, to_user, rt_id ) VALUES( 10, 300, 4 );
|
||||
INSERT INTO relationship ( from_user, to_user, rt_id ) VALUES( 30, 300, 4 );
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -5,6 +5,10 @@ require_once("BasicAuthSession.php");
|
||||
$raw_headers = apache_request_headers();
|
||||
$raw_post = file_get_contents ( 'php://input');
|
||||
|
||||
if ( $debugging && isset($_GET['method']) ) {
|
||||
$_SERVER['REQUEST_METHOD'] = $_GET['method'];
|
||||
}
|
||||
|
||||
switch ( $_SERVER['REQUEST_METHOD'] ) {
|
||||
case 'OPTIONS':
|
||||
include_once("caldav-OPTIONS.php");
|
||||
|
||||
@ -3,6 +3,8 @@ require_once("always.php");
|
||||
require_once("RSCDSSession.php");
|
||||
$session->LoginRequired();
|
||||
|
||||
require_once("interactive-page.php");
|
||||
|
||||
$c->title = "Really Simple CalDAV Store - Configuration Help";
|
||||
include("page-header.php");
|
||||
|
||||
@ -22,6 +24,6 @@ echo <<<EOBODY
|
||||
</p>
|
||||
EOBODY;
|
||||
|
||||
include("page-header.php");
|
||||
include("page-footer.php");
|
||||
|
||||
?>
|
||||
BIN
htdocs/images/down.gif
Normal file
BIN
htdocs/images/down.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 58 B |
BIN
htdocs/images/up.gif
Normal file
BIN
htdocs/images/up.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 59 B |
@ -3,6 +3,7 @@ require_once("always.php");
|
||||
require_once("RSCDSSession.php");
|
||||
$session->LoginRequired();
|
||||
|
||||
require_once("interactive-page.php");
|
||||
include("page-header.php");
|
||||
|
||||
echo <<<EOBODY
|
||||
@ -10,7 +11,7 @@ include("page-header.php");
|
||||
<p>You appear to be logged on as $session->username ($session->fullname)</p>
|
||||
<p>Useful links:
|
||||
<ul>
|
||||
<li><a href="/client_configuration_help.php">Help on configuring CalDAV clients with RSCDS</a></li>
|
||||
<li><a href="/help.php">Help on configuring CalDAV clients with RSCDS</a></li>
|
||||
</ul>
|
||||
</p>
|
||||
EOBODY;
|
||||
|
||||
44
htdocs/relationships.php
Normal file
44
htdocs/relationships.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
require_once("always.php");
|
||||
require_once("RSCDSSession.php");
|
||||
$session->LoginRequired();
|
||||
|
||||
require_once("interactive-page.php");
|
||||
|
||||
|
||||
require_once("classBrowser.php");
|
||||
$c->stylesheets[] = "css/browse.css";
|
||||
|
||||
$c->page_title = "User Relationships";
|
||||
$browser = new Browser($c->page_title);
|
||||
|
||||
$browser->AddColumn( 'from_user', 'From', '', '##from_user_link##' );
|
||||
$browser->AddColumn( 'from_name', 'Name', '', '', 'ufrom.fullname' );
|
||||
$browser->AddHidden( 'from_user_link', "'<a href=\"/user.php?user_no=' || from_user || '\">' || from_user || '</a>'" );
|
||||
$browser->AddColumn( 'to_user', 'From', '', '##to_user_link##' );
|
||||
$browser->AddColumn( 'to_name', 'Name', '', '', 'uto.fullname' );
|
||||
$browser->AddHidden( 'to_user_link', "'<a href=\"/user.php?user_no=' || to_user || '\">' || to_user || '</a>'" );
|
||||
|
||||
$browser->SetJoins( 'relationship JOIN usr ufrom ON (ufrom.user_no = from_user) JOIN usr uto ON (uto.user_no = to_user) ' );
|
||||
|
||||
if ( isset( $_GET['o']) && isset($_GET['d']) ) {
|
||||
$browser->AddOrder( $_GET['o'], $_GET['d'] );
|
||||
}
|
||||
else
|
||||
$browser->AddOrder( 'from_user', 'A' );
|
||||
|
||||
$browser->RowFormat( "<tr onMouseover=\"LinkHref(this,1);\" title=\"Click to Display Role Detail\" class=\"r%d\">\n", "</tr>\n", '#even' );
|
||||
$browser->DoQuery();
|
||||
|
||||
|
||||
// if ( $session->AllowedTo("Support") )
|
||||
$relationship_menu->AddOption("New Relationship","/relationship.php?create","Add a new relationship", false, 10);
|
||||
|
||||
$active_menu_pattern = "#^/relationship#";
|
||||
|
||||
include("page-header.php");
|
||||
|
||||
echo $browser->Render();
|
||||
|
||||
include("page-footer.php");
|
||||
?>
|
||||
40
htdocs/roles.php
Normal file
40
htdocs/roles.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
require_once("always.php");
|
||||
require_once("RSCDSSession.php");
|
||||
$session->LoginRequired();
|
||||
|
||||
require_once("interactive-page.php");
|
||||
|
||||
|
||||
require_once("classBrowser.php");
|
||||
$c->stylesheets[] = "css/browse.css";
|
||||
|
||||
$c->page_title = "System Roles";
|
||||
$browser = new Browser($c->page_title);
|
||||
|
||||
$browser->AddColumn( 'role_no', 'No.', '', '##role_link##' );
|
||||
$browser->AddColumn( 'role_name', 'Name' );
|
||||
$browser->AddHidden( 'role_link', "'<a href=\"/role.php?role_no=' || role_no || '\">' || role_no || '</a>'" );
|
||||
|
||||
$browser->SetJoins( "roles" );
|
||||
|
||||
if ( isset( $_GET['o']) && isset($_GET['d']) ) {
|
||||
$browser->AddOrder( $_GET['o'], $_GET['d'] );
|
||||
}
|
||||
else
|
||||
$browser->AddOrder( 'role_no', 'A' );
|
||||
|
||||
$browser->RowFormat( "<tr onMouseover=\"LinkHref(this,1);\" title=\"Click to Display Role Detail\" class=\"r%d\">\n", "</tr>\n", '#even' );
|
||||
$browser->DoQuery();
|
||||
|
||||
|
||||
// if ( $session->AllowedTo("Admin") )
|
||||
$role_menu->AddOption("New Role","/role.php?create","Add a new role", false, 10);
|
||||
|
||||
$active_menu_pattern = "#^/role#";
|
||||
|
||||
include("page-header.php");
|
||||
|
||||
echo $browser->Render();
|
||||
include("page-footer.php");
|
||||
?>
|
||||
108
htdocs/rscds.css
108
htdocs/rscds.css
@ -1,8 +1,106 @@
|
||||
/* Basic overridable CSS for Really Simple CalDAV Store */
|
||||
|
||||
span.prompt {
|
||||
font-weight: bold;
|
||||
width: 12em;
|
||||
padding-right: 1em;
|
||||
display: block;
|
||||
body, p, li, td {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.prompt {
|
||||
font-weight: bold;
|
||||
padding: 1px 1em 1px 0.5em;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.error {
|
||||
/* font-weight: bold; */
|
||||
font-size: 110%;
|
||||
font-family: Bitstream Vera Sans, Vera Sans, sans-serif;
|
||||
padding: 1px 0.3em;
|
||||
background-color: #c00000;
|
||||
color: #ffff00;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5 {
|
||||
font-weight: bold;
|
||||
font-family: Bitstream Vera Sans, Vera Sans, sans-serif;
|
||||
padding-left: 0.3em;
|
||||
padding-right: 0.3em;
|
||||
padding-bottom: 0.1em;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 200%;
|
||||
background-color: #30c050;
|
||||
margin: 0;
|
||||
padding: 0.3em;
|
||||
}
|
||||
|
||||
h1:first-letter {
|
||||
font-size: 120%;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 160%;
|
||||
background-color: #60e080;
|
||||
margin: 0;
|
||||
padding-top: 0.3em;
|
||||
margin-top: 1px;
|
||||
}
|
||||
|
||||
p {
|
||||
padding: 0.1em 0.3em 0.2em;
|
||||
}
|
||||
|
||||
input.text, input.password, label {
|
||||
background-color: ffffe0;
|
||||
color: navy;
|
||||
border: thin solid #000000;
|
||||
padding: 3px;
|
||||
}
|
||||
|
||||
label {
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
#menu {
|
||||
background-color: #084010;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
padding: 2px 1px;
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
|
||||
#menu a.menu, #menu a.menu:hover, #menu a.menu_active, #menu a.menu_active:hover {
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
background-color: #10a020;
|
||||
padding: 1px 0.2em;
|
||||
margin-right: 0.2em;
|
||||
}
|
||||
|
||||
#menu a.menu:hover, #menu a.menu_active:hover {
|
||||
color: yellow;
|
||||
background-color: #088010;
|
||||
}
|
||||
|
||||
#submenu {
|
||||
background-color: #105020;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
padding: 2px 1px;
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
|
||||
#submenu a.submenu, #submenu a.submenu:hover, #submenu a.submenu_active, #submenu a.submenu_active:hover {
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
background-color: #20c040;
|
||||
padding: 1px 0.2em;
|
||||
margin-right: 0.2em;
|
||||
}
|
||||
|
||||
#submenu a.submenu:hover, #submenu a.submenu_active:hover {
|
||||
color: yellow;
|
||||
background-color: #10a020;
|
||||
}
|
||||
41
htdocs/users.php
Normal file
41
htdocs/users.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
require_once("always.php");
|
||||
require_once("RSCDSSession.php");
|
||||
$session->LoginRequired();
|
||||
|
||||
require_once("interactive-page.php");
|
||||
|
||||
|
||||
require_once("classBrowser.php");
|
||||
$c->stylesheets[] = "css/browse.css";
|
||||
|
||||
$browser = new Browser("Calendar Users");
|
||||
|
||||
$browser->AddColumn( 'user_no', 'No.', '', '##user_link##' );
|
||||
$browser->AddColumn( 'username', 'Name' );
|
||||
$browser->AddHidden( 'user_link', "'<a href=\"/user.php?user_no=' || user_no || '\">' || user_no || '</a>'" );
|
||||
|
||||
$browser->SetJoins( 'usr' );
|
||||
|
||||
if ( isset( $_GET['o']) && isset($_GET['d']) ) {
|
||||
$browser->AddOrder( $_GET['o'], $_GET['d'] );
|
||||
}
|
||||
else
|
||||
$browser->AddOrder( 'user_no', 'A' );
|
||||
|
||||
$browser->RowFormat( "<tr onMouseover=\"LinkHref(this,1);\" title=\"Click to Display Role Detail\" class=\"r%d\">\n", "</tr>\n", '#even' );
|
||||
$browser->DoQuery();
|
||||
|
||||
$c->page_title = "Calendar Users";
|
||||
|
||||
// if ( $session->AllowedTo("Support") )
|
||||
$user_menu->AddOption("New User","/user.php?create","Add a new user", false, 10);
|
||||
|
||||
$active_menu_pattern = "#^/user#";
|
||||
|
||||
include("page-header.php");
|
||||
|
||||
echo $browser->Render();
|
||||
|
||||
include("page-footer.php");
|
||||
?>
|
||||
@ -9,8 +9,6 @@
|
||||
* @license http://gnu.org/copyleft/gpl.html GNU GPL v2
|
||||
*/
|
||||
|
||||
require_once("session-util.php");
|
||||
|
||||
/**
|
||||
* A Class for handling a session using HTTP Basic Authentication
|
||||
*
|
||||
|
||||
@ -109,6 +109,49 @@ class RSCDSSession extends Session
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Internal function used to assign the session details to a user's new session.
|
||||
* @param object $u The user+session object we (probably) read from the database.
|
||||
*/
|
||||
function AssignSessionDetails( $u ) {
|
||||
parent::AssignSessionDetails( $u );
|
||||
$this->GetRoles();
|
||||
$this->GetRelationships();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Method used to get the user's roles
|
||||
*/
|
||||
function GetRoles () {
|
||||
$this->roles = array();
|
||||
$sql = 'SELECT role_name FROM roles JOIN role_member ON roles.role_no=role_member.role_no WHERE user_no = '.$this->user_no.';';
|
||||
$qry = new PgQuery( $sql );
|
||||
if ( $qry->Exec('RSCDSSession') && $qry->rows > 0 ) {
|
||||
while( $role = $qry->Fetch() ) {
|
||||
$this->roles[$role->role_name] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Method used to get the user's relationships
|
||||
*/
|
||||
function GetRelationships () {
|
||||
$this->relationships = array();
|
||||
$sql = 'SELECT relationship.rt_id, rt_name, rt_isgroup, confers, prefix_match FROM relationship JOIN relationship_type USING (rt_id) WHERE from_user = '.$this->user_no.' UNION ';
|
||||
$sql .= 'SELECT relationship_type.rt_id, rt_name, rt_isgroup, confers, prefix_match FROM relationship JOIN relationship_type ON (relationship.rt_id = relationship_type.rt_inverse) WHERE to_user = '.$this->user_no.';';
|
||||
$qry = new PgQuery( $sql );
|
||||
if ( $qry->Exec('RSCDSSession') && $qry->rows > 0 ) {
|
||||
while( $relationship = $qry->Fetch() ) {
|
||||
$this->relationships[$relationship->rt_id] = $relationship;
|
||||
dbg_error_log( "RSCDSSession", "Relationships: %d - %s - %d - %s - %s -", $relationship->rt_id, $relationship->rt_name, $relationship->rt_isgroup, $relationship->confers, $relationship->prefix_match );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks that this user is logged in, and presents a login screen if they aren't.
|
||||
*
|
||||
@ -129,6 +172,11 @@ class RSCDSSession extends Session
|
||||
local_index_not_logged_in();
|
||||
}
|
||||
else {
|
||||
if ( $this->login_failed ) {
|
||||
echo <<<EOHTML
|
||||
<p class="error">Invalid user name or password.</p>
|
||||
EOHTML;
|
||||
}
|
||||
echo <<<EOHTML
|
||||
<h1>Log On Please</h1>
|
||||
<p>For access to the $c->system_name you should log on with
|
||||
|
||||
@ -14,36 +14,15 @@ $c->sysabbr = 'rscds';
|
||||
$c->admin_email = 'andrew@catalyst.net.nz';
|
||||
$c->system_name = "Really Simple CalDAV Store";
|
||||
$c->domain_name = $_SERVER['SERVER_NAME'];
|
||||
$c->images = "/images";
|
||||
$c->save_time_zone_defs = 1;
|
||||
|
||||
// Kind of private configuration values
|
||||
$c->total_query_time = 0;
|
||||
|
||||
$c->dbg = array( 'core' => 1 );
|
||||
|
||||
if ( $debugging && isset($_GET['method']) ) {
|
||||
$_SERVER['REQUEST_METHOD'] = $_GET['method'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a debug message into the error log using printf syntax
|
||||
* @package rscds
|
||||
*/
|
||||
function dbg_error_log() {
|
||||
global $c;
|
||||
$argc = func_num_args();
|
||||
$args = func_get_args();
|
||||
$component = array_shift($args);
|
||||
if ( !isset($c->dbg[strtolower($component)]) ) return;
|
||||
|
||||
if ( 2 <= $argc ) {
|
||||
$format = array_shift($args);
|
||||
}
|
||||
else {
|
||||
$format = "%s";
|
||||
}
|
||||
error_log( $c->sysabbr.": DBG: $component:". vsprintf( $format, $args ) );
|
||||
}
|
||||
$c->dbg = array( );
|
||||
|
||||
require_once("AWLUtilities.php");
|
||||
|
||||
dbg_error_log( "core", "==========> method =%s= =%s:%d= =%s= =%s=",
|
||||
$_SERVER['REQUEST_METHOD'], $_SERVER['SERVER_NAME'], $_SERVER['SERVER_PORT'], $_SERVER['SCRIPT_NAME'], $_SERVER['PATH_INFO']);
|
||||
@ -58,45 +37,11 @@ else {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to connect to the configured connect strings
|
||||
*/
|
||||
$dbconn = false;
|
||||
foreach( $c->pg_connect AS $k => $v ) {
|
||||
if ( !$dbconn ) $dbconn = pg_Connect($v);
|
||||
}
|
||||
if ( ! $dbconn ) {
|
||||
echo <<<EOERRMSG
|
||||
<html><head><title>Database Error</title></head><body>
|
||||
<h1>Database Error</h1>
|
||||
<h3>Could not connect to PGPool or to Postgres</h3>
|
||||
</body>
|
||||
</html>
|
||||
EOERRMSG;
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Force the domain name to what was in the configuration file
|
||||
*/
|
||||
$_SERVER['SERVER_NAME'] = $c->domain_name;
|
||||
|
||||
|
||||
if ( !function_exists('apache_request_headers') ) {
|
||||
function apache_request_headers() {
|
||||
return getallheaders();
|
||||
}
|
||||
}
|
||||
|
||||
function dbg_log_array( $component, $name, $arr, $recursive = false ) {
|
||||
foreach ($arr as $key => $value) {
|
||||
dbg_error_log( $component, "%s: >>%s<< = >>%s<<", $name, $key, $value);
|
||||
if ( $recursive && (gettype($value) == 'array' || gettype($value) == 'object') ) {
|
||||
dbg_log_array( $component, "$name"."[$key]", $value, $recursive );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
include_once("PgQuery.php");
|
||||
|
||||
?>
|
||||
@ -7,9 +7,9 @@ dbg_error_log("delete", "DELETE method handler");
|
||||
$get_path = $_SERVER['PATH_INFO'];
|
||||
$etag_none_match = str_replace('"','',$_SERVER["HTTP_IF_NONE_MATCH"]);
|
||||
|
||||
$qry = new PgQuery( "SELECT * FROM ics_event_data WHERE user_no = ? AND ics_event_name = ? AND ics_event_etag = ?;", $session->user_no, $get_path, $etag_none_match );
|
||||
$qry = new PgQuery( "SELECT * FROM vevent_data WHERE user_no = ? AND vevent_name = ? AND vevent_etag = ?;", $session->user_no, $get_path, $etag_none_match );
|
||||
if ( $qry->Exec("caldav-DELETE") && $qry->rows == 1 ) {
|
||||
$qry = new PgQuery( "DELETE FROM ics_event_data WHERE user_no = ? AND ics_event_name = ? AND ics_event_etag = ?;", $session->user_no, $get_path, $etag_none_match );
|
||||
$qry = new PgQuery( "DELETE FROM vevent_data WHERE user_no = ? AND vevent_name = ? AND vevent_etag = ?;", $session->user_no, $get_path, $etag_none_match );
|
||||
if ( $qry->Exec("caldav-DELETE") ) {
|
||||
header("HTTP/1.1 200 OK");
|
||||
dbg_error_log( "delete", "DELETE: User: %d, ETag: %s, Path: %s", $session->user_no, $etag_none_match, $get_path);
|
||||
|
||||
@ -7,21 +7,27 @@ dbg_error_log("get", "GET method handler");
|
||||
$get_path = $_SERVER['PATH_INFO'];
|
||||
$etag_none_match = str_replace('"','',$_SERVER["HTTP_IF_NONE_MATCH"]);
|
||||
|
||||
$qry = new PgQuery( "SELECT * FROM ics_event_data WHERE user_no = ? AND ics_event_name = ? ;", $session->user_no, $get_path);
|
||||
if ( $qry->Exec("caldav-GET") && $qry->rows == 1 ) {
|
||||
$qry = new PgQuery( "SELECT * FROM vevent_data WHERE user_no = ? AND vevent_name = ? ;", $session->user_no, $get_path);
|
||||
dbg_error_log("get", "%s", $qry->querystring );
|
||||
if ( $qry->Exec("GET") && $qry->rows == 1 ) {
|
||||
$event = $qry->Fetch();
|
||||
|
||||
header("HTTP/1.1 200 OK");
|
||||
header("ETag: $event->ics_event_etag");
|
||||
header("ETag: $event->vevent_etag");
|
||||
header("Content-Type: text/calendar");
|
||||
|
||||
print $event->ics_raw_data;
|
||||
print $event->vevent_data;
|
||||
|
||||
dbg_error_log( "GET", "User: %d, ETag: %s, Path: %s", $session->user_no, $event->ics_event_etag, $get_path);
|
||||
dbg_error_log( "GET", "User: %d, ETag: %s, Path: %s", $session->user_no, $event->vevent_etag, $get_path);
|
||||
|
||||
}
|
||||
else if ( $qry->rows != 1 ) {
|
||||
header("HTTP/1.1 500 Internal Server Error");
|
||||
dbg_error_log("ERROR", "Multiple rows match for User: %d, ETag: %s, Path: %s", $session->user_no, $event->vevent_etag, $get_path);
|
||||
}
|
||||
else {
|
||||
header("HTTP/1.1 500 Infernal Server Error");
|
||||
dbg_error_log("get", "Infernal Server Error");
|
||||
}
|
||||
|
||||
?>
|
||||
@ -17,49 +17,74 @@ $etag_match = str_replace('"','',$_SERVER["HTTP_IF_MATCH"]);
|
||||
dbg_log_array( "PUT", 'HEADERS', $raw_headers );
|
||||
dbg_log_array( "PUT", '_SERVER', $_SERVER, true );
|
||||
|
||||
if ( $etag_match == '*' || $etag_match == '' ) {
|
||||
$qry = new PgQuery( "INSERT INTO ics_event_data ( user_no, ics_event_name, ics_event_etag, ics_raw_data ) VALUES( ?, ?, ?, ?)", $session->user_no, $put_path, $etag, $raw_post);
|
||||
$qry->Exec("caldav-PUT");
|
||||
|
||||
header("HTTP/1.1 201 Created");
|
||||
header("ETag: $etag");
|
||||
}
|
||||
else {
|
||||
$qry = new PgQuery( "UPDATE ics_event_data SET ics_raw_data=?, ics_event_etag=? WHERE user_no=? AND ics_event_name=? AND ics_event_etag=?",
|
||||
$raw_post, $etag, $session->user_no, $put_path, $etag_match );
|
||||
$qry->Exec("caldav-PUT");
|
||||
|
||||
header("HTTP/1.1 201 Replaced");
|
||||
header("ETag: $etag");
|
||||
}
|
||||
|
||||
include_once("vEvent.php");
|
||||
$ev = new vEvent(array( 'vevent' => $raw_post ));
|
||||
|
||||
dbg_log_array( "PUT", 'EVENT', $ev, true );
|
||||
|
||||
$sql = "SET TIMEZONE TO ".qpg($ev->tzlocn).";";
|
||||
|
||||
if ( $etag_match == '*' || $etag_match == '' ) {
|
||||
/**
|
||||
* If they didn't send an etag_match header, we need to check if the PUT object already exists
|
||||
* and we are hence updating it. And we just set our etag_match to that.
|
||||
*/
|
||||
$qry = new PgQuery( "SELECT * FROM vevent_data WHERE user_no=? AND vevent_name=?", $session->user_no, $put_path );
|
||||
$qry->Exec("PUT");
|
||||
if ( $qry->rows > 1 ) {
|
||||
header("HTTP/1.1 500 Infernal Server Error");
|
||||
dbg_error_log("ERROR","Multiple events match replaced path for user %d, path %s", $session->user_no, $put_path );
|
||||
exit(0);
|
||||
}
|
||||
elseif ( $qry->rows == 1 ) {
|
||||
$event = $qry->Fetch();
|
||||
$etag_match = $event->vevent_etag;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $etag_match == '*' || $etag_match == '' ) {
|
||||
/**
|
||||
* If we got this far without an etag we must be inserting it.
|
||||
*/
|
||||
$qry = new PgQuery( "INSERT INTO vevent_data ( user_no, vevent_name, vevent_etag, vevent_data, logged_user ) VALUES( ?, ?, ?, ?, ?)",
|
||||
$session->user_no, $put_path, $etag, $raw_post, $session->user_no );
|
||||
$qry->Exec("PUT");
|
||||
|
||||
header("HTTP/1.1 201 Created");
|
||||
header("ETag: $etag");
|
||||
dbg_error_log( "PUT", "INSERT INTO vevent_data ( user_no, vevent_name, vevent_etag, vevent_data, logged_user ) VALUES( %d, '%s', '%s', '%s', %d)",
|
||||
$session->user_no, $put_path, $etag, $raw_post, $session->user_no );
|
||||
}
|
||||
else {
|
||||
$qry = new PgQuery( "UPDATE vevent_data SET vevent_data=?, vevent_etag=?, logged_user=? WHERE user_no=? AND vevent_name=? AND vevent_etag=?",
|
||||
$raw_post, $etag, $session->user_no, $session->user_no, $put_path, $etag_match );
|
||||
$qry->Exec("PUT");
|
||||
|
||||
header("HTTP/1.1 201 Replaced");
|
||||
header("ETag: $etag");
|
||||
}
|
||||
|
||||
$sql = "SET TIMEZONE TO ".qpg($ev->tz_locn).";";
|
||||
if ( $etag_match == '*' || $etag_match == '' ) {
|
||||
$sql .= <<<EOSQL
|
||||
INSERT INTO ical_events (user_no, ics_event_name, ics_event_etag, uid, dtstamp, dtstart, dtend, summary, location, class, transp, description, rrule, tzid)
|
||||
INSERT INTO event (user_no, vevent_name, vevent_etag, uid, dtstamp, dtstart, dtend, summary, location, class, transp, description, rrule, tz_id)
|
||||
VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
|
||||
EOSQL;
|
||||
|
||||
$qry = new PgQuery( $sql, $session->user_no, $put_path, $etag, $ev->Get('uid'), $ev->Get('dtstamp'),
|
||||
$ev->Get('dtstart'), $ev->Get('dtend'), $ev->Get('summary'), $ev->Get('location'),
|
||||
$ev->Get('class'), $ev->Get('transp'), $ev->Get('description'), $ev->Get('rrule'), $ev->Get('tzid') );
|
||||
$qry->Exec("caldav-PUT");
|
||||
$ev->Get('class'), $ev->Get('transp'), $ev->Get('description'), $ev->Get('rrule'), $ev->Get('tz_id') );
|
||||
$qry->Exec("PUT");
|
||||
}
|
||||
else {
|
||||
$sql = <<<EOSQL
|
||||
UPDATE ical_events SET uid=?, dtstamp=?, dtstart=?, dtend=?, summary=?, location=?, class=?, transp=?, description=?, rrule=?, tzid=?
|
||||
WHERE user_no=? AND ics_event_name=? AND ics_event_etag=?
|
||||
UPDATE event SET uid=?, dtstamp=?, dtstart=?, dtend=?, summary=?, location=?, class=?, transp=?, description=?, rrule=?, tz_id=?
|
||||
WHERE user_no=? AND vevent_name=? AND vevent_etag=?
|
||||
EOSQL;
|
||||
|
||||
$qry = new PgQuery( $sql, $ev->Get('uid'), $ev->Get('dtstamp'), $ev->Get('dtstart'), $ev->Get('dtend'), $ev->Get('summary'),
|
||||
$ev->Get('location'), $ev->Get('class'), $ev->Get('transp'), $ev->Get('description'), $ev->Get('rrule'),
|
||||
$ev->Get('tzid'), $session->user_no, $put_path, $etag );
|
||||
$qry->Exec("caldav-PUT");
|
||||
$ev->Get('tz_id'), $session->user_no, $put_path, $etag );
|
||||
$qry->Exec("PUT");
|
||||
}
|
||||
|
||||
dbg_error_log( "PUT", "User: %d, ETag: %s, Path: %s", $session->user_no, $etag, $put_path);
|
||||
|
||||
@ -2,16 +2,18 @@
|
||||
|
||||
dbg_error_log("REPORT", "method handler");
|
||||
|
||||
$attributes = array();
|
||||
$parser = xml_parser_create_ns('UTF-8');
|
||||
xml_parser_set_option ( $parser, XML_OPTION_SKIP_WHITE, 1 );
|
||||
|
||||
function xml_start_callback( $parser, $el_name, $el_attrs ) {
|
||||
dbg_error_log( "REPORT", "Parsing $el_name" );
|
||||
// dbg_error_log( "REPORT", "Parsing $el_name" );
|
||||
dbg_log_array( "REPORT", "$el_name::attrs", $el_attrs, true );
|
||||
$attributes[$el_name] = $el_attrs;
|
||||
}
|
||||
|
||||
function xml_end_callback( $parser, $el_name ) {
|
||||
dbg_error_log( "REPORT", "Finished Parsing $el_name" );
|
||||
// dbg_error_log( "REPORT", "Finished Parsing $el_name" );
|
||||
}
|
||||
|
||||
xml_set_element_handler ( $parser, 'xml_start_callback', 'xml_end_callback' );
|
||||
@ -20,25 +22,68 @@ $rpt_request = array();
|
||||
xml_parse_into_struct( $parser, $raw_post, $rpt_request );
|
||||
xml_parser_free($parser);
|
||||
|
||||
|
||||
$reportnum = -1;
|
||||
$report = array();
|
||||
foreach( $rpt_request AS $k => $v ) {
|
||||
|
||||
switch ( $v['tag'] ) {
|
||||
|
||||
case 'URN:IETF:PARAMS:XML:NS:CALDAV:CALENDAR-DATA':
|
||||
dbg_log_array( "REPORT", "CALENDAR-DATA", $v, true );
|
||||
if ( $v['type'] == "complete" ) {
|
||||
$report[$reportnum]['include_data'] = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'URN:IETF:PARAMS:XML:NS:CALDAV:CALENDAR-QUERY':
|
||||
dbg_log_array( "REPORT", "CALENDAR-QUERY", $v, true );
|
||||
if ( $v['type'] == "open" ) {
|
||||
$reportnum++;
|
||||
$report_type = substr($v['tag'],30);
|
||||
$report[$reportnum]['type'] = $report_type;
|
||||
$report[$reportnum]['include_href'] = 1;
|
||||
$report[$reportnum]['include_data'] = 1;
|
||||
}
|
||||
else {
|
||||
unset($report_type);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'URN:IETF:PARAMS:XML:NS:CALDAV:TIME-RANGE':
|
||||
dbg_log_array( "REPORT", "TIME-RANGE", $v, true );
|
||||
if ( isset($v['attributes']['START']) ) {
|
||||
$report[$reportnum]['start'] = $v['attributes']['START'];
|
||||
}
|
||||
if ( isset($v['attributes']['END']) ) {
|
||||
$report[$reportnum]['end'] = $v['attributes']['END'];
|
||||
}
|
||||
break;
|
||||
|
||||
case 'URN:IETF:PARAMS:XML:NS:CALDAV:COMP-FILTER':
|
||||
dbg_log_array( "REPORT", "COMP-FILTER", $v, true );
|
||||
if ( isset($v['attributes']['NAME']) && ($v['attributes']['NAME'] == 'VCALENDAR' )) {
|
||||
$report[$reportnum]['calendar'] = 1;
|
||||
}
|
||||
if ( isset($v['attributes']['NAME']) ) {
|
||||
if ( isset($report[$reportnum]['calendar']) && ($v['attributes']['NAME'] == 'VEVENT') ) {
|
||||
$report[$reportnum]['calendar-event'] = 1;
|
||||
}
|
||||
if ( isset($report[$reportnum]['calendar']) && ($v['attributes']['NAME'] == 'VTODO') ) {
|
||||
$report[$reportnum]['calendar-todo'] = 1;
|
||||
}
|
||||
if ( isset($report[$reportnum]['calendar']) && ($v['attributes']['NAME'] == 'VFREEBUSY') ) {
|
||||
$report[$reportnum]['calendar-freebusy'] = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'URN:IETF:PARAMS:XML:NS:CALDAV:FILTER':
|
||||
dbg_error_log( "REPORT", "Not using %s information which follows...", $v['tag'] );
|
||||
dbg_log_array( "REPORT", "FILTER", $v, true );
|
||||
break;
|
||||
|
||||
case 'DAV::PROP':
|
||||
dbg_log_array( "REPORT", "DAV::PROP", $v, true );
|
||||
if ( isset($report_type) ) {
|
||||
if ( $v['type'] == "open" ) {
|
||||
$report_properties = array();
|
||||
@ -69,19 +114,33 @@ foreach( $rpt_request AS $k => $v ) {
|
||||
}
|
||||
}
|
||||
|
||||
// dbg_log_array( 'RPT', $rpt_request, true );
|
||||
|
||||
// dbg_log_array( 'REPORT', $report, true );
|
||||
if ( $unsupported_stuff ) {
|
||||
header('HTTP/1.1 403 Forbidden');
|
||||
header('Content-Type: application/xml; charset="utf-8"');
|
||||
echo <<<EOXML
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<D:error xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
|
||||
<C:supported-filter>
|
||||
<C:prop-filter name="X-ABC-GUID"/>
|
||||
</C:supported-filter>
|
||||
</D:error>
|
||||
EOXML;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
header("HTTP/1.1 207 Multi-Status");
|
||||
header("Content-type: text/xml;charset=UTF-8");
|
||||
|
||||
/**
|
||||
* FIXME - this needs to be rewritten using XML libraries, in the same manner
|
||||
* in which the REPORT request is parsed, in fact. For the time being we will
|
||||
* attach importance to the care and feeding of Evolution, however.
|
||||
*/
|
||||
$response_tpl = <<<RESPONSETPL
|
||||
<D:response>
|
||||
<D:href>http://%s:%d%s%s</D:href>
|
||||
<D:response>%s
|
||||
<D:propstat>
|
||||
<D:prop>
|
||||
<D:getetag>"%s"</D:getetag>
|
||||
<D:getetag>"%s"</D:getetag>%s
|
||||
</D:prop>
|
||||
<D:status>HTTP/1.1 200 OK</D:status>
|
||||
</D:propstat>
|
||||
@ -89,6 +148,17 @@ $response_tpl = <<<RESPONSETPL
|
||||
|
||||
RESPONSETPL;
|
||||
|
||||
$calendar_href_tpl = <<<CALDATATPL
|
||||
|
||||
<D:href>http://%s:%d%s%s</D:href>
|
||||
CALDATATPL;
|
||||
|
||||
$calendar_data_tpl = <<<CALDATATPL
|
||||
|
||||
<C:calendar-data>%s </C:calendar-data>
|
||||
CALDATATPL;
|
||||
|
||||
dbg_log_array("REPORT", "report", $report, true );
|
||||
|
||||
echo <<<REPORTHDR
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
@ -96,12 +166,38 @@ echo <<<REPORTHDR
|
||||
|
||||
REPORTHDR;
|
||||
|
||||
$qry = new PgQuery( "SELECT * FROM ics_event_data;" );
|
||||
for ( $i=0; $i <= $reportnum; $i++ ) {
|
||||
dbg_error_log("REPORT", "Report[%d] Start:%s, End: %s, Events: %d, Todos: %d, Freebusy: %d",
|
||||
$i, $report[$i]['start'], $report[$i]['end'], $report[$i]['calendar-event'], $report[$i]['calendar-todo'], $report[$i]['calendar-freebusy']);
|
||||
if ( isset($report[$i]['calendar-event']) ) {
|
||||
if ( isset($report[$i]['include_href']) ) dbg_error_log( "REPORT", "Returning href event data" );
|
||||
if ( isset($report[$i]['include_data']) ) dbg_error_log( "REPORT", "Returning full event data" );
|
||||
$sql = "SELECT * FROM vevent_data NATURAL JOIN event ";
|
||||
$where = "";
|
||||
if ( isset( $report[$i]['start'] ) ) {
|
||||
$where = "WHERE dtend >= ".qpg($report[$i]['start'])."::timestamp with time zone ";
|
||||
}
|
||||
if ( isset( $report[$i]['end'] ) ) {
|
||||
if ( $where != "" ) $where .= "AND ";
|
||||
$where .= "dtstart <= ".qpg($report[$i]['end'])."::timestamp with time zone ";
|
||||
}
|
||||
$sql .= $where;
|
||||
$qry = new PgQuery( $sql );
|
||||
if ( $qry->Exec() && $qry->rows > 0 ) {
|
||||
while( $event = $qry->Fetch() ) {
|
||||
printf( $response_tpl, $_SERVER['SERVER_NAME'], $_SERVER['SERVER_PORT'], $_SERVER['SCRIPT_NAME'], $event->ics_event_name, $event->ics_event_etag );
|
||||
dbg_error_log("REPORT", "ETag >>%s<< >>http://%s:%s%s%s<<", $event->ics_event_etag,
|
||||
$_SERVER['SERVER_NAME'], $_SERVER['SERVER_PORT'], $_SERVER['SCRIPT_NAME'], $event->ics_event_name);
|
||||
$calhref = ( isset($report[$i]['include_href']) ? sprintf( $calendar_href_tpl, $_SERVER['SERVER_NAME'], $_SERVER['SERVER_PORT'], $_SERVER['SCRIPT_NAME'], $event->vevent_name ) : "" );
|
||||
$caldata = ( isset($report[$i]['include_data']) ? sprintf( $calendar_data_tpl, $event->vevent_data ) : "" );
|
||||
printf( $response_tpl, $calhref, $event->vevent_etag, $caldata );
|
||||
dbg_error_log("REPORT", "ETag >>%s<< >>http://%s:%s%s%s<<", $event->vevent_etag,
|
||||
$_SERVER['SERVER_NAME'], $_SERVER['SERVER_PORT'], $_SERVER['SCRIPT_NAME'], $event->vevent_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( isset($report[$i]['calendar-todo']) ) {
|
||||
if ( isset($report[$i]['include_data']) ) dbg_error_log( "REPORT", "FIXME: Not returning full todo data" );
|
||||
}
|
||||
if ( isset($report[$i]['calendar-freebusy']) ) {
|
||||
if ( isset($report[$i]['include_data']) ) dbg_error_log( "REPORT", "FIXME: Not returning full freebusy data" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
14
inc/interactive-page.php
Normal file
14
inc/interactive-page.php
Normal file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
require_once("session-util.php");
|
||||
require_once("MenuSet.php");
|
||||
$page_menu = new MenuSet('menu', 'menu', 'menu_active');
|
||||
$page_menu->AddOption("Home","/","Browse all users", false, 3900 );
|
||||
$page_menu->AddOption("Help","/help.php","Help on something or other", false, 4500 );
|
||||
$page_menu->AddOption("Logout","/?logout","Log out of the $c->system_name", false, 5400 );
|
||||
|
||||
$relationship_menu = new MenuSet('submenu', 'submenu', 'submenu_active');
|
||||
$user_menu = new MenuSet('submenu', 'submenu', 'submenu_active');
|
||||
$role_menu = new MenuSet('submenu', 'submenu', 'submenu_active');
|
||||
|
||||
$active_menu_pattern = '#^/(index.*)?$#'
|
||||
?>
|
||||
@ -14,4 +14,11 @@ echo <<<EOHDR
|
||||
<body>
|
||||
EOHDR;
|
||||
|
||||
if ( isset($page_menu) && is_object($page_menu) ) {
|
||||
$page_menu->AddSubMenu( $relationship_menu, "Relationships", "/relationships.php", "Browse all relationships", false, 4050 );
|
||||
$page_menu->AddSubMenu( $user_menu, "Users", "/users.php", "Browse all users", false, 4100 );
|
||||
$page_menu->AddSubMenu( $role_menu, "Roles", "/roles.php", "Browse all roles", false, 4300 );
|
||||
$page_menu->MakeSomethingActive($active_menu_pattern);
|
||||
echo $page_menu->Render();
|
||||
}
|
||||
?>
|
||||
@ -2,7 +2,7 @@
|
||||
include("page-header.php");
|
||||
|
||||
echo <<<EOBODY
|
||||
<h1>WRMS Not Configured</h1>
|
||||
<h1>RSCDS Not Configured</h1>
|
||||
<h2>The Bad News</h2>
|
||||
<p>There is no configuration file present in <b>/etc/rscds/$_SERVER[SERVER_NAME]-conf.php</b> so
|
||||
your installation is not fully set up.</p>
|
||||
|
||||
@ -52,4 +52,35 @@ if ( !function_exists("session_validate_password") ) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ( !function_exists("replace_uri_params") ) {
|
||||
/**
|
||||
* Given a URL (presumably the current one) and a parameter, replace the value of parameter,
|
||||
* extending the URL as necessary if the parameter is not already there.
|
||||
* @param string $uri The URI we will be replacing parameters in.
|
||||
* @param array $replacements An array of replacement pairs array( "replace_this" => "with this" )
|
||||
* @return string The URI with the replacements done.
|
||||
*/
|
||||
function replace_uri_params( $uri, $replacements ) {
|
||||
$replaced = $uri;
|
||||
foreach( $replacements AS $param => $new_value ) {
|
||||
$rxp = preg_replace( '/([\[\]])/', '\\\\$1', $param ); // Some parameters may be arrays.
|
||||
$regex = "/([&?])($rxp)=([^&]+)/";
|
||||
dbg_error_log("core", "Looking for [%s] to replace with [%s] regex is %s and searching [%s]", $param, $new_value, $regex, $replaced );
|
||||
if ( preg_match( $regex, $replaced ) )
|
||||
$replaced = preg_replace( $regex, "\$1$param=$new_value", $replaced);
|
||||
else
|
||||
$replaced .= "&$param=$new_value";
|
||||
}
|
||||
if ( ! preg_match( '/\?/', $replaced ) ) {
|
||||
$replaced = preg_replace("/&(.+)$/", "?\$1", $replaced);
|
||||
}
|
||||
$replaced = str_replace("&", "--AmPeRsAnD--", $replaced);
|
||||
$replaced = str_replace("&", "&", $replaced);
|
||||
$replaced = str_replace("--AmPeRsAnD--", "&", $replaced);
|
||||
dbg_error_log("core", "URI <<$uri>> morphed to <<$replaced>>");
|
||||
return $replaced;
|
||||
}
|
||||
}
|
||||
?>
|
||||
@ -28,15 +28,15 @@ class vEvent {
|
||||
|
||||
/**
|
||||
* An array of arbitrary properties
|
||||
* @var props array
|
||||
* @var properties array
|
||||
*/
|
||||
var $properties;
|
||||
|
||||
/**
|
||||
* The typical name for the standard timezone
|
||||
* @var tzname string
|
||||
* The typical location name for the standard timezone such as "Pacific/Auckland"
|
||||
* @var tz_locn string
|
||||
*/
|
||||
var $tzname;
|
||||
var $tz_locn;
|
||||
|
||||
/**#@-*/
|
||||
|
||||
@ -49,7 +49,7 @@ class vEvent {
|
||||
global $c;
|
||||
|
||||
// Probably a good idea to always have values for these things...
|
||||
$this->properties['tzid'] = $c->local_tzid;
|
||||
$this->properties['tz_id'] = $c->local_tzid;
|
||||
$this->properties['modified'] = time();
|
||||
$this->properties['sequence'] = 1;
|
||||
$this->properties['uid'] = sprintf( "%s@%s", time() * 1000 + rand(0,1000), $c->domain_name);
|
||||
@ -106,19 +106,16 @@ class vEvent {
|
||||
if ( $state == 'BEGIN:VEVENT' && $state != $v ) {
|
||||
list( $parameter, $value ) = preg_split('/:/', $v );
|
||||
if ( preg_match('/^DT[A-Z]+;TZID=/', $parameter) ) {
|
||||
list( $parameter, $tzid ) = preg_split('/;/', $parameter );
|
||||
$properties['TZID'] = $tzid;
|
||||
list( $parameter, $tz_id ) = preg_split('/;/', $parameter );
|
||||
$properties['TZID'] = $tz_id;
|
||||
}
|
||||
$properties[strtoupper($parameter)] = $value;
|
||||
}
|
||||
if ( $state == 'BEGIN:VTIMEZONE' ) {
|
||||
$vtimezone .= $v . "\n";
|
||||
list( $parameter, $value ) = preg_split('/:/', $v );
|
||||
if ( !isset($this->tzname) && $parameter == 'TZNAME' ) {
|
||||
$this->tzname = $value;
|
||||
}
|
||||
if ( !isset($this->tzlocn) && $parameter == 'X-LIC-LOCATION' ) {
|
||||
$this->tzlocn = $value;
|
||||
if ( !isset($this->tz_locn) && $parameter == 'X-LIC-LOCATION' ) {
|
||||
$this->tz_locn = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -136,19 +133,18 @@ class vEvent {
|
||||
* them into something that PostgreSQL can understand...
|
||||
*/
|
||||
function DealWithTimeZones() {
|
||||
$qry = new PgQuery( "SELECT pgtz, location FROM time_zones WHERE tzid = ?;", $this->properties['TZID'] );
|
||||
$qry = new PgQuery( "SELECT tz_locn FROM time_zone WHERE tz_id = ?;", $this->properties['TZID'] );
|
||||
if ( $qry->Exec('vEvent') && $qry->rows == 1 ) {
|
||||
$row = $qry->Fetch();
|
||||
$this->tzname = $row->pgtz;
|
||||
$this->tzlocn = $row->location;
|
||||
$this->tz_locn = $row->tz_locn;
|
||||
}
|
||||
else {
|
||||
if ( !isset($this->tzlocn) ) {
|
||||
if ( !isset($this->tz_locn) ) {
|
||||
// In case there was no X-LIC-LOCATION defined, let's hope there is something in the TZID
|
||||
$this->tzlocn = preg_replace('/^.*([a-z]+\/[a-z]+)$/i','$1',$this->properties['TZID'] );
|
||||
$this->tz_locn = preg_replace('/^.*([a-z]+\/[a-z]+)$/i','$1',$this->properties['TZID'] );
|
||||
}
|
||||
$qry2 = new PgQuery( "INSERT INTO time_zones (tzid, location, tz_spec, pgtz) VALUES( ?, ?, ?, ? );",
|
||||
$this->properties['TZID'], $this->tzlocn, $this->properties['VTIMEZONE'], $this->tzname );
|
||||
$qry2 = new PgQuery( "INSERT INTO time_zone (tz_id, tz_locn, tz_spec) VALUES( ?, ?, ? );",
|
||||
$this->properties['TZID'], $this->tz_locn, $this->properties['VTIMEZONE'] );
|
||||
$qry2->Exec("vEvent");
|
||||
}
|
||||
}
|
||||
|
||||
10
rscds.webprj
10
rscds.webprj
@ -34,8 +34,12 @@
|
||||
<item url="inc/RSCDSSession.php" uploadstatus="1" />
|
||||
<item url="inc/page-header.php" uploadstatus="1" />
|
||||
<item url="inc/page-footer.php" uploadstatus="1" />
|
||||
<item url="inc/rscds_configuration_missing.php" />
|
||||
<item url="htdocs/client_configuration_help.php" />
|
||||
<item url="htdocs/rscds.css" />
|
||||
<item url="inc/rscds_configuration_missing.php" uploadstatus="1" />
|
||||
<item url="htdocs/rscds.css" uploadstatus="1" />
|
||||
<item url="inc/interactive-page.php" uploadstatus="1" />
|
||||
<item url="htdocs/users.php" uploadstatus="1" />
|
||||
<item url="htdocs/help.php" uploadstatus="1" />
|
||||
<item url="htdocs/roles.php" uploadstatus="1" />
|
||||
<item url="htdocs/relationships.php" uploadstatus="1" />
|
||||
</project>
|
||||
</webproject>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user