You shouldn't have to do both of these - it's one or the other (if I
understand correctly what you are saying).
>
> The only problem I have with that is that after the call to
> updateCalendarObject the CalDAV-Clients call only getCalendarObject
> for the updated Object and then the edited single entry disapears
> until a manual total reload.
>
> Is it somehow possible to send back to the client some information
> that I want a full reload or can I somehow send back the newly
> created Entry with the other record on the next load?
I believe the "right" way to do what you want is to store the
exceptional VEVENT in the same resource (VCALENDAR object) as the
original recurring event, with a RECURRENCE-ID to identify which
instance is to be overridden. Unless the client asks for
expand-recurrences, then the server should return the entire VCALENDAR
object, containing both the original recurring event and the exception.
And if the client *does* request expand-recurrences, then the question
is moot, I think.
Thunderbird/Lightning seems to do this.
You can also use an EXDATE property on the original recurring event; but
that just changes the date/time of some occurrence - you can't change
other properties like the subject using EXDATE.
--
MrD.
Note that SabreDAV doesn't support expansion of recurrences yet.
>
> Thunderbird/Lightning seems to do this.
>
> You can also use an EXDATE property on the original recurring event; but
> that just changes the date/time of some occurrence - you can't change
> other properties like the subject using EXDATE.
I'm pretty sure you need both; An EXDATE to specify which instance of
the recurrence to exclude, and a new VEVENT object with a
Recurrence-ID matching that value from EXDATE exactly.
An easy way to test how it's done, is to fire up iCal and do it
through that client first. It will make it pretty obvious what the
correct way is.
Evert
EXDATE is only used when deleting single instances.
My problem is, that the way it is done by iCal (and Thunderbird) is
quite a mess to implement with the backend (would have to introduce a
tree like structure). So I wanted to cheat and do it in another obvious
way: add an EXDATE and create a non-related Event.
That would work if I could somehow force the client to reload the
calendar (or at least send it the new event), but i had no luck with that.
It may be worth trying to implement it the proper way =) Sure, it's a
tree-like structure, but only 1 level deep really..
>
> That would work if I could somehow force the client to reload the calendar
> (or at least send it the new event), but i had no luck with that.
iCal has 'push' support nowadays, but it works through xmpp, and I
have no idea about the details. Going through this effort will likely
be harder than just implement it the usual way though.
That's as far as I know the only way, otherwise you're going to have
to wait for the automatic refresh.
But yeah you're right won't really have another option.
Thanks,
Stefan
Ah. I need to do some (more) re-reading in that case.
>
> An easy way to test how it's done, is to fire up iCal and do it
> through that client first. It will make it pretty obvious what the
> correct way is.
Of course. But that assumes I'm an Apple weenie. In fact I have no Apple
equipment, and so I can't run iCal.
Isn't it dreadful that RFC 5545 is written so badly that it can only be
interpreted by reference to a specific piece of proprietary software.
--
MrD.
Oh yes, I believe that's correct; EXDATE is not an exception, it's an
*exclusion*.
--
MrD.
Hi Musonic,
Please include the original email if you reply to the list. I use a
regular email client so it's hard to see what was discussed. Found it
in the archives though.
You can actually also fake the http request in this, just construct a
'fake'
Sabre_HTTP_Request and
Sabre_HTTP_Response
You'll need to subclass Sabre_HTTP_Response so it doesn't
automatically send back everything to a browser, but this is
effectively how the unittests 'fake' all the requests.
This last method will allow you to do 'pretend' requests locally.
Up to you though, depending on your requirements you may feel it's not
worth the trouble :) The SabreDAV stack will likely be heavier than
your needs.
Evert
>
>
> On Thursday, 9 February 2012 19:38:22 UTC, Evert Pot wrote:
> Hi Musonic,
>
> Please include the original email if you reply to the list. I use a
> regular email client so it's hard to see what was discussed. Found it
> in the archives though.
>
> Apologies for this. I didn't realise that when using the Google groups UI it didn't include the orignal thread by default.
>
No worries, and sorry for the slow reply.. Had some family stuff to attend to.
The underlying design idea is that a 'user' of the API never interacts directly with the node objects directly.
You can access the CalendarObject directly, by calling:
$server->tree->getNodeForPath('calendars/[user]/[calendar]/[object]');
This will return a CalendarObject instance (or throw a NotFound exception).
However, if you do that, you circumvent some parts of the system that may be important. The ACL layer will be ignored, for instance.
But sometimes you need to, this part of the API isn't 100% feature complete.
So main access to the file tree is through the 'tree' object, the API for this can be found in Sabre_DAV_ObjectTree.
>
>
> You can actually also fake the http request in this, just construct a
> 'fake'
>
> Sabre_HTTP_Request and
> Sabre_HTTP_Response
>
> You'll need to subclass Sabre_HTTP_Response so it doesn't
> automatically send back everything to a browser, but this is
> effectively how the unittests 'fake' all the requests.
>
> This last method will allow you to do 'pretend' requests locally.
>
> This sounds great, but I'm not sure I know exactly how to go about implementing it. It looks like I need to override the global _SERVER array when I instantiate the request class, but I'm really not very clear.
You don't need to override it, you can just create a 'fake' one.
Here's an example of how you would create a 'fake' GET request:
// We're assuming you fully setup your '$server' object.
$serverArray = array(
'REQUEST_URI' => '/calendars/[user]/[calendar]/[calendarobject]',
'REQUEST_METHOD' => 'GET'
);
$request = new Sabre_HTTP_Request($serverArray);
$response = Sabre_HTTP_ResponseMock();
$server->httpRequest = $request;
$server->httpResponse = $response;
// Now to execute the request:
$server->exec();
After this, the full response can be found in your $response object.
Now the only missing bit is the Sabre_HTTP_ResponseMock class.
This isn't part of the main codebase, but can be found in:
tests/Sabre/HTTP
instead of:
lib/Sabre/HTTP
If you feel this is what you want, I can move the 'Mock' response class to the main codebase. Let me know if that's helpful. Otherwise you can just pull it from the tests directly, or easily create your own.
>
> Up to you though, depending on your requirements you may feel it's not
> worth the trouble :) The SabreDAV stack will likely be heavier than
> your needs.
> Evert
>
> I'm really keen to get my head around SabreDAV because my primary reason for using it rather than just rolling my own iCal-like data model to use with my local application is so that users can choose which client they want to access their information with.
> I really appreciate all your help.
Well I hope the explanation makes sense :)
Cheers,
Evert
Yes!
resource(92) of type (stream)
This is fine because the method then converts it into a string. Unfortunately, if I check the variable after this I find that it is simply an empty string! No wonder it's being classed as invalid.
So, I then tried to pass the VCALENDAR object as the second parameter when creating a new instance of the Sabre_HTTP_Request class. I tried passing it as a string, as an array and as an array with the key 'body'. I keep on hitting the same problem. When 'validateICalendar' tries to convert the stream, it just gets an empty string.
What am I doing wrong?!
On Feb 18, 2012, at 12:02 PM, musonic wrote:
> So, I've been playing around and trying to implement the Client class, modified to make "fake" requests. I've overwritten the 'request' method and have been able to make simple GET requests successfully. I then tried to make a PUT request to create a new calendar object. Unfortunately this has not been successful. I built up a new VCALENDAR object using the VObject library and passed that to Request method as the third parameter. This threw an exception:
>
> Sabre_DAV_Exception_UnsupportedMediaType This resource only supports valid iCalendar 2.0 data. Parse error: Invalid VObject, line 1 did not follow the icalendar/vcard format.
>
> I was pretty confident that having built the object using VObject it would be valid, so I checked through the backtrace to see what was being passed around. This is where I found something weird. The method that is throwing the error is the 'validateICalendar' method in the Sabre_CalDAV_Plugin class. If I check what is being passed to this method before it tries to do anything at all I find that the parameter is:
>
> resource(92) of type (stream)
>
> This is fine because the method then converts it into a string. Unfortunately, if I check the variable after this I find that it is simply an empty string! No wonder it's being classed as invalid.
>
> So, I then tried to pass the VCALENDAR object as the second parameter when creating a new instance of the Sabre_HTTP_Request class. I tried passing it as a string, as an array and as an array with the key 'body'. I keep on hitting the same problem. When 'validateICalendar' tries to convert the stream, it just gets an empty string.
>
> What am I doing wrong?!
Not sure why this would happen.
Can you show some code? Just put it up on Gist (https://gist.github.com/)
Evert
> --
> You received this message because you are subscribed to the Google Groups "SabreDAV Discussion" group.
> To post to this group, send email to sabredav...@googlegroups.com.
> To unsubscribe from this group, send email to sabredav-discu...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/sabredav-discuss?hl=en.
>