From a1eda425ed8db211a8432ed3a375e641246e067c Mon Sep 17 00:00:00 2001 From: Georg Ehrke Date: Fri, 21 Oct 2011 18:19:44 +0200 Subject: [PATCH 01/59] added transition function from 'old' calendar to fullcalendar (fixed currentview bug) --- apps/calendar/ajax/changeview.php | 5 ++--- apps/calendar/index.php | 11 +++++++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/apps/calendar/ajax/changeview.php b/apps/calendar/ajax/changeview.php index b396ff4945..ef05c7cd49 100644 --- a/apps/calendar/ajax/changeview.php +++ b/apps/calendar/ajax/changeview.php @@ -7,10 +7,9 @@ */ require_once ("../../../lib/base.php"); -if(!OC_USER::isLoggedIn()) { - die(""); -} +OC_JSON::checkLoggedIn(); OC_JSON::checkAppEnabled('calendar'); $currentview = $_GET["v"]; OC_Preferences::setValue(OC_USER::getUser(), "calendar", "currentview", $currentview); +OC_JSON::success(); ?> diff --git a/apps/calendar/index.php b/apps/calendar/index.php index 7150fb8490..2442d27db4 100644 --- a/apps/calendar/index.php +++ b/apps/calendar/index.php @@ -19,6 +19,17 @@ $eventSources = array(); foreach($calendars as $calendar){ $eventSources[] = OC_Calendar_Calendar::getEventSourceInfo($calendar); } +//Fix currentview for fullcalendar +if(OC_Preferences::getValue(OC_USER::getUser(), 'calendar', 'currentview', 'month') == "oneweekview"){ + OC_Preferences::setValue(OC_USER::getUser(), "calendar", "currentview", "agendaWeek"); +} +if(OC_Preferences::getValue(OC_USER::getUser(), 'calendar', 'currentview', 'month') == "onemonthview"){ + OC_Preferences::setValue(OC_USER::getUser(), "calendar", "currentview", "month"); +} +if(OC_Preferences::getValue(OC_USER::getUser(), 'calendar', 'currentview', 'month') == "listview"){ + OC_Preferences::setValue(OC_USER::getUser(), "calendar", "currentview", "list"); +} + OC_Util::addScript('3rdparty/fullcalendar', 'fullcalendar'); OC_Util::addStyle('3rdparty/fullcalendar', 'fullcalendar'); OC_Util::addScript('calendar', 'calendar'); From eb68201bc5e8b9c6a23af8aa1f7f8c8990c5b3dc Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Fri, 21 Oct 2011 21:47:42 +0200 Subject: [PATCH 02/59] Better event popup --- apps/calendar/css/style.css | 30 ++++++++++++++++++++++-- apps/calendar/js/calendar.js | 45 ++++++++++++++++++------------------ 2 files changed, 50 insertions(+), 25 deletions(-) diff --git a/apps/calendar/css/style.css b/apps/calendar/css/style.css index e6d212ef53..0204f2fc12 100644 --- a/apps/calendar/css/style.css +++ b/apps/calendar/css/style.css @@ -24,8 +24,6 @@ #listview #events {width:25em;padding: 4px;} #listview #events .day {width:auto;padding-left:10px;border-bottom: 2px solid #EEEEEE;text-align:left;} -#sysbox{display: none;} - .actions {height: 33px; min-width: 800px;} .controls {min-width: 800px;} .center {text-align: center;} @@ -99,3 +97,31 @@ button.category{margin:0 3px;} { cursor: pointer; } +.tipsy-event .tipsy-inner{ +background-color:#0098E4; +border:2px solid #1d2d44; +max-width:400px; +padding:0; +} +.tipsy-event .tipsy-arrow-s{ +border-top-color:#1d2d44; +} +.tipsy-event .tipsy-arrow-n{ +border-bottom-color:#1d2d44; +} +.tipsy-event .summary, +.tipsy-event .timespan, +.tipsy-event .description{ +padding:0 8px; +} +.tipsy-event .summary{ +background-color:#1d2d44; +font-size:1.2em; +font-weight:bold; +text-align:left; +padding:0 8px 2px; +} +.tipsy-event .description{ +line-height:1.2; +margin-bottom:4px; +} diff --git a/apps/calendar/js/calendar.js b/apps/calendar/js/calendar.js index bf9e2628ff..a29d667285 100644 --- a/apps/calendar/js/calendar.js +++ b/apps/calendar/js/calendar.js @@ -148,32 +148,20 @@ Calendar={ $("#advanced_options").css("display", "block"); $("#advanced_options_button").css("display", "none"); }, - createEventPopup:function(event, e, view){ - var popup = $(this).data('popup'); - if (!popup){ - popup = $(document.createElement('div')); - $(this).data('popup', popup).append(popup); - popup.addClass('popup') - popup.addClass('event_popup') - .html(Calendar.UI.getEventPopupText(event)); - } - popup.css('left', -(popup.width() - $(this).width())/2) - .show(); - }, - hideEventPopup:function(){ - $(this).data('popup').hide(); - }, getEventPopupText:function(event){ if (event.allDay){ - var timespan = $.fullCalendar.formatDates(event.start, event.end, t('calendar', "MMMM d[ yyyy]{ '—'[ MMMM][ d] yyyy}")); + var timespan = $.fullCalendar.formatDates(event.start, event.end, t('calendar', "ddd d MMMM[ yyyy]{ -[ddd d] MMMM yyyy}")); }else{ - var timespan = $.fullCalendar.formatDates(event.start, event.end, t('calendar', "HH:mm[ MMMM d yyyy]{ '—' HH:mm MMMM d yyyy}")); + var timespan = $.fullCalendar.formatDates(event.start, event.end, t('calendar', "ddd d MMMM[ yyyy] HH:mm{ -[ ddd d MMMM yyyy] HH:mm}")); // Tue 18 October 2011 08:00 - 16:00 } - return '' + timespan + '' - + ' ' - + '' + event.title + '' - + '' + event.description + ''; + var html = + '
' + event.title + '
' + + '
' + timespan + '
'; + if (event.description){ + html += '
' + event.description + '
'; + } + return html; }, lockTime:function(){ if($('#allday_checkbox').is(':checked')) { @@ -522,8 +510,19 @@ $(document).ready(function(){ eventClick: Calendar.UI.editEvent, eventDrop: Calendar.UI.moveEvent, eventResize: Calendar.UI.resizeEvent, - eventMouseover: Calendar.UI.createEventPopup, - eventMouseout: Calendar.UI.hideEventPopup, + eventRender: function(event, element) { + element.tipsy({ + className: 'tipsy-event', + opacity: 0.9, + gravity:$.fn.tipsy.autoBounds(150, 's'), + fade:true, + delayIn: 400, + html:true, + title:function() { + return Calendar.UI.getEventPopupText(event); + } + }); + }, eventSources: eventSources }); $('#oneweekview_radio').click(function(){ From 92fa6f0a48408d7064b5896d9ee8c9157d3efb12 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Fri, 21 Oct 2011 21:49:03 +0200 Subject: [PATCH 03/59] Fix size calculation with css styling of tipsy popup --- core/js/jquery-tipsy.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/core/js/jquery-tipsy.js b/core/js/jquery-tipsy.js index 9567ed3bac..ef4bbfd87a 100644 --- a/core/js/jquery-tipsy.js +++ b/core/js/jquery-tipsy.js @@ -31,6 +31,10 @@ height: this.$element[0].offsetHeight }); + if (this.options.className) { + $tip.addClass(maybeCall(this.options.className, this.$element[0])); + } + var actualWidth = $tip[0].offsetWidth, actualHeight = $tip[0].offsetHeight, gravity = maybeCall(this.options.gravity, this.$element[0]); @@ -61,9 +65,6 @@ $tip.css(tp).addClass('tipsy-' + gravity); $tip.find('.tipsy-arrow')[0].className = 'tipsy-arrow tipsy-arrow-' + gravity.charAt(0); - if (this.options.className) { - $tip.addClass(maybeCall(this.options.className, this.$element[0])); - } if (this.options.fade) { $tip.stop().css({opacity: 0, display: 'block', visibility: 'visible'}).animate({opacity: this.options.opacity}); From d50b014aba3296693f3be8829e605a29de207f0c Mon Sep 17 00:00:00 2001 From: Georg Ehrke Date: Fri, 21 Oct 2011 22:47:31 +0200 Subject: [PATCH 04/59] fix allday bug --- apps/calendar/ajax/events.php | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/apps/calendar/ajax/events.php b/apps/calendar/ajax/events.php index 8f466bee91..c08c2e6758 100644 --- a/apps/calendar/ajax/events.php +++ b/apps/calendar/ajax/events.php @@ -25,23 +25,26 @@ foreach($events as $event) $dtstart = $vevent->DTSTART; $dtend = OC_Calendar_Object::getDTEndFromVEvent($vevent); $start_dt = $dtstart->getDateTime(); - $start_dt->setTimezone(new DateTimeZone($user_timezone)); $end_dt = $dtend->getDateTime(); - $end_dt->setTimezone(new DateTimeZone($user_timezone)); - + if ($dtstart->getDateType() == Sabre_VObject_Element_DateTime::DATE) + { + $return_event['allDay'] = true; + $return_event['start'] = $start_dt->format('Y-m-d'); + $end_dt->modify('-1 sec'); + $return_event['end'] = $end_dt->format('Y-m-d'); + }else{ + $start_dt->setTimezone(new DateTimeZone($user_timezone)); + $end_dt->setTimezone(new DateTimeZone($user_timezone)); + $return_event['start'] = $start_dt->format('Y-m-d H:i:s'); + $return_event['end'] = $end_dt->format('Y-m-d H:i:s'); + $return_event['allDay'] = false; + } $return_event = array(); $return_event['id'] = $event['id']; $return_event['title'] = $event['summary']; $return_event['description'] = isset($vevent->DESCRIPTION)?$vevent->DESCRIPTION->value:''; $return_event['start'] = $start_dt->format('Y-m-d H:i:s'); $return_event['end'] = $end_dt->format('Y-m-d H:i:s'); - $return_event['allDay'] = false; - if ($dtstart->getDateType() == Sabre_VObject_Element_DateTime::DATE) - { - $return_event['allDay'] = true; - $end_dt->modify('-1 sec'); - $return_event['end'] = $end_dt->format('Y-m-d H:i:s'); - } $return[] = $return_event; } OC_JSON::encodedPrint($return); From 433b57c3156cc90410d0242cb098793259bea848 Mon Sep 17 00:00:00 2001 From: Georg Ehrke Date: Fri, 21 Oct 2011 22:59:26 +0200 Subject: [PATCH 05/59] fix new allday bug --- apps/calendar/ajax/events.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/apps/calendar/ajax/events.php b/apps/calendar/ajax/events.php index c08c2e6758..5c4cced8d2 100644 --- a/apps/calendar/ajax/events.php +++ b/apps/calendar/ajax/events.php @@ -20,6 +20,7 @@ $user_timezone = OC_Preferences::getValue(OC_USER::getUser(), "calendar", "timez $return = array(); foreach($events as $event) { + $return_event = array(); $object = Sabre_VObject_Reader::read($event['calendardata']); $vevent = $object->VEVENT; $dtstart = $vevent->DTSTART; @@ -39,12 +40,9 @@ foreach($events as $event) $return_event['end'] = $end_dt->format('Y-m-d H:i:s'); $return_event['allDay'] = false; } - $return_event = array(); $return_event['id'] = $event['id']; $return_event['title'] = $event['summary']; $return_event['description'] = isset($vevent->DESCRIPTION)?$vevent->DESCRIPTION->value:''; - $return_event['start'] = $start_dt->format('Y-m-d H:i:s'); - $return_event['end'] = $end_dt->format('Y-m-d H:i:s'); $return[] = $return_event; } OC_JSON::encodedPrint($return); From 268e667bef3bd06f10638aa33b6dc7fa2ef6d796 Mon Sep 17 00:00:00 2001 From: Georg Ehrke Date: Sat, 22 Oct 2011 13:11:55 +0200 Subject: [PATCH 06/59] update pot file for calendar --- l10n/templates/calendar.pot | 366 ++++++++++++++---------------------- 1 file changed, 137 insertions(+), 229 deletions(-) diff --git a/l10n/templates/calendar.pot b/l10n/templates/calendar.pot index 66cc90a4bf..56fce2285e 100644 --- a/l10n/templates/calendar.pot +++ b/l10n/templates/calendar.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2011-09-24 23:05+0200\n" +"POT-Creation-Date: 2011-10-22 13:05+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,318 +17,180 @@ msgstr "" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" -#: ajax/createcalendar.php:18 ajax/settimezone.php:19 -#: ajax/updatecalendar.php:18 -msgid "Authentication error" -msgstr "" - -#: ajax/editeventform.php:25 +#: ajax/editeventform.php:26 msgid "Wrong calendar" msgstr "" -#: ajax/settimezone.php:27 +#: ajax/settimezone.php:22 msgid "Timezone changed" msgstr "" -#: ajax/settimezone.php:29 +#: ajax/settimezone.php:24 msgid "Invalid request" msgstr "" -#: appinfo/app.php:19 templates/part.eventform.php:27 -#: templates/part.eventinfo.php:18 +#: appinfo/app.php:21 templates/calendar.php:11 +#: templates/part.eventform.php:21 msgid "Calendar" msgstr "" -#: lib/object.php:292 +#: js/calendar.js:153 +msgid "ddd d MMMM[ yyyy]{ -[ddd d] MMMM yyyy}" +msgstr "" + +#: js/calendar.js:155 +msgid "ddd d MMMM[ yyyy] HH:mm{ -[ ddd d MMMM yyyy] HH:mm}" +msgstr "" + +#: lib/object.php:344 msgid "Birthday" msgstr "" -#: lib/object.php:293 +#: lib/object.php:345 msgid "Business" msgstr "" -#: lib/object.php:294 +#: lib/object.php:346 msgid "Call" msgstr "" -#: lib/object.php:295 +#: lib/object.php:347 msgid "Clients" msgstr "" -#: lib/object.php:296 +#: lib/object.php:348 msgid "Deliverer" msgstr "" -#: lib/object.php:297 +#: lib/object.php:349 msgid "Holidays" msgstr "" -#: lib/object.php:298 +#: lib/object.php:350 msgid "Ideas" msgstr "" -#: lib/object.php:299 +#: lib/object.php:351 msgid "Journey" msgstr "" -#: lib/object.php:300 +#: lib/object.php:352 msgid "Jubilee" msgstr "" -#: lib/object.php:301 +#: lib/object.php:353 msgid "Meeting" msgstr "" -#: lib/object.php:302 +#: lib/object.php:354 msgid "Other" msgstr "" -#: lib/object.php:303 +#: lib/object.php:355 msgid "Personal" msgstr "" -#: lib/object.php:304 +#: lib/object.php:356 msgid "Projects" msgstr "" -#: lib/object.php:305 +#: lib/object.php:357 msgid "Questions" msgstr "" -#: lib/object.php:306 +#: lib/object.php:358 msgid "Work" msgstr "" -#: lib/object.php:313 +#: lib/object.php:365 msgid "Does not repeat" msgstr "" -#: lib/object.php:314 +#: lib/object.php:366 msgid "Daily" msgstr "" -#: lib/object.php:315 +#: lib/object.php:367 msgid "Weekly" msgstr "" -#: lib/object.php:316 +#: lib/object.php:368 msgid "Every Weekday" msgstr "" -#: lib/object.php:317 +#: lib/object.php:369 msgid "Bi-Weekly" msgstr "" -#: lib/object.php:318 +#: lib/object.php:370 msgid "Monthly" msgstr "" -#: lib/object.php:319 +#: lib/object.php:371 msgid "Yearly" msgstr "" -#: lib/object.php:337 +#: lib/object.php:389 msgid "Not an array" msgstr "" -#: templates/calendar.php:3 +#: templates/calendar.php:8 msgid "All day" msgstr "" -#: templates/calendar.php:32 -msgid "Sunday" +#: templates/calendar.php:9 +msgid "Missing fields" msgstr "" -#: templates/calendar.php:32 -msgid "Monday" +#: templates/calendar.php:10 templates/part.eventform.php:3 +msgid "Title" msgstr "" -#: templates/calendar.php:32 -msgid "Tuesday" +#: templates/calendar.php:12 +msgid "From Date" msgstr "" -#: templates/calendar.php:32 -msgid "Wednesday" +#: templates/calendar.php:13 +msgid "From Time" msgstr "" -#: templates/calendar.php:32 -msgid "Thursday" +#: templates/calendar.php:14 +msgid "To Date" msgstr "" -#: templates/calendar.php:32 -msgid "Friday" +#: templates/calendar.php:15 +msgid "To Time" msgstr "" -#: templates/calendar.php:32 -msgid "Saturday" +#: templates/calendar.php:16 +msgid "The event ends before it starts" msgstr "" -#: templates/calendar.php:33 -msgid "Sun." +#: templates/calendar.php:17 +msgid "There was a database fail" msgstr "" -#: templates/calendar.php:33 -msgid "Mon." -msgstr "" - -#: templates/calendar.php:33 -msgid "Tue." -msgstr "" - -#: templates/calendar.php:33 -msgid "Wed." -msgstr "" - -#: templates/calendar.php:33 -msgid "Thu." -msgstr "" - -#: templates/calendar.php:33 -msgid "Fri." -msgstr "" - -#: templates/calendar.php:33 -msgid "Sat." -msgstr "" - -#: templates/calendar.php:34 -msgid "January" -msgstr "" - -#: templates/calendar.php:34 -msgid "February" -msgstr "" - -#: templates/calendar.php:34 -msgid "March" -msgstr "" - -#: templates/calendar.php:34 -msgid "April" -msgstr "" - -#: templates/calendar.php:34 -msgid "May" -msgstr "" - -#: templates/calendar.php:34 -msgid "June" -msgstr "" - -#: templates/calendar.php:34 -msgid "July" -msgstr "" - -#: templates/calendar.php:34 -msgid "August" -msgstr "" - -#: templates/calendar.php:34 -msgid "September" -msgstr "" - -#: templates/calendar.php:34 -msgid "October" -msgstr "" - -#: templates/calendar.php:34 -msgid "November" -msgstr "" - -#: templates/calendar.php:34 -msgid "December" -msgstr "" - -#: templates/calendar.php:35 -msgid "Jan." -msgstr "" - -#: templates/calendar.php:35 -msgid "Feb." -msgstr "" - -#: templates/calendar.php:35 -msgid "Mar." -msgstr "" - -#: templates/calendar.php:35 -msgid "Apr." -msgstr "" - -#: templates/calendar.php:35 -msgid "May." -msgstr "" - -#: templates/calendar.php:35 -msgid "Jun." -msgstr "" - -#: templates/calendar.php:35 -msgid "Jul." -msgstr "" - -#: templates/calendar.php:35 -msgid "Aug." -msgstr "" - -#: templates/calendar.php:35 -msgid "Sep." -msgstr "" - -#: templates/calendar.php:35 -msgid "Oct." -msgstr "" - -#: templates/calendar.php:35 -msgid "Nov." -msgstr "" - -#: templates/calendar.php:35 -msgid "Dec." -msgstr "" - -#: templates/calendar.php:36 templates/calendar.php:50 -#: templates/calendar.php:116 +#: templates/calendar.php:23 msgid "Week" msgstr "" -#: templates/calendar.php:37 templates/calendar.php:51 -msgid "Weeks" -msgstr "" - -#: templates/calendar.php:38 -msgid "More before {startdate}" -msgstr "" - -#: templates/calendar.php:39 -msgid "More after {enddate}" -msgstr "" - -#: templates/calendar.php:49 -msgid "Day" -msgstr "" - -#: templates/calendar.php:52 +#: templates/calendar.php:24 msgid "Month" msgstr "" -#: templates/calendar.php:53 +#: templates/calendar.php:25 msgid "List" msgstr "" -#: templates/calendar.php:58 +#: templates/calendar.php:30 msgid "Today" msgstr "" -#: templates/calendar.php:59 +#: templates/calendar.php:31 msgid "Calendars" msgstr "" -#: templates/calendar.php:76 templates/calendar.php:94 -msgid "Time" -msgstr "" - -#: templates/calendar.php:169 +#: templates/calendar.php:48 msgid "There was a fail, while parsing the file." msgstr "" @@ -350,7 +212,6 @@ msgid "Download" msgstr "" #: templates/part.choosecalendar.rowfields.php:4 -#: templates/part.eventinfo.php:64 msgid "Edit" msgstr "" @@ -367,7 +228,7 @@ msgstr "" msgid "Edit calendar" msgstr "" -#: templates/part.editcalendar.php:12 +#: templates/part.editcalendar.php:12 templates/part.import.php:29 msgid "Displayname" msgstr "" @@ -375,88 +236,135 @@ msgstr "" msgid "Active" msgstr "" -#: templates/part.editcalendar.php:29 templates/part.eventform.php:88 -#: templates/part.eventinfo.php:58 -msgid "Description" -msgstr "" - -#: templates/part.editcalendar.php:35 +#: templates/part.editcalendar.php:29 msgid "Calendar color" msgstr "" -#: templates/part.editcalendar.php:41 +#: templates/part.editcalendar.php:42 msgid "Save" msgstr "" -#: templates/part.editcalendar.php:41 templates/part.editevent.php:7 +#: templates/part.editcalendar.php:42 templates/part.editevent.php:7 #: templates/part.newevent.php:6 msgid "Submit" msgstr "" -#: templates/part.editcalendar.php:42 +#: templates/part.editcalendar.php:43 msgid "Cancel" msgstr "" -#: templates/part.editevent.php:1 templates/part.eventinfo.php:1 +#: templates/part.editevent.php:1 msgid "Edit an event" msgstr "" -#: templates/part.eventform.php:3 templates/part.eventinfo.php:4 -msgid "Title" +#: templates/part.editevent.php:9 +msgid "Export" msgstr "" #: templates/part.eventform.php:5 msgid "Title of the Event" msgstr "" -#: templates/part.eventform.php:9 templates/part.eventinfo.php:9 -msgid "Location" -msgstr "" - #: templates/part.eventform.php:11 -msgid "Location of the Event" -msgstr "" - -#: templates/part.eventform.php:17 templates/part.eventinfo.php:16 msgid "Category" msgstr "" -#: templates/part.eventform.php:19 +#: templates/part.eventform.php:13 msgid "Select category" msgstr "" -#: templates/part.eventform.php:45 templates/part.eventinfo.php:28 +#: templates/part.eventform.php:39 msgid "All Day Event" msgstr "" -#: templates/part.eventform.php:49 templates/part.eventinfo.php:31 +#: templates/part.eventform.php:43 msgid "From" msgstr "" -#: templates/part.eventform.php:57 templates/part.eventinfo.php:38 +#: templates/part.eventform.php:51 msgid "To" msgstr "" -#: templates/part.eventform.php:65 templates/part.eventinfo.php:44 +#: templates/part.eventform.php:59 +msgid "Advanced options" +msgstr "" + +#: templates/part.eventform.php:64 msgid "Repeat" msgstr "" -#: templates/part.eventform.php:81 templates/part.eventinfo.php:51 +#: templates/part.eventform.php:80 msgid "Attendees" msgstr "" +#: templates/part.eventform.php:87 +msgid "Location" +msgstr "" + #: templates/part.eventform.php:89 +msgid "Location of the Event" +msgstr "" + +#: templates/part.eventform.php:95 +msgid "Description" +msgstr "" + +#: templates/part.eventform.php:96 msgid "Description of the Event" msgstr "" -#: templates/part.eventinfo.php:63 -msgid "Close" +#: templates/part.import.php:1 +msgid "Import Ical File" +msgstr "" + +#: templates/part.import.php:4 +msgid "How to import the new calendar?" +msgstr "" + +#: templates/part.import.php:6 +msgid "Import into an existing calendar" +msgstr "" + +#: templates/part.import.php:7 +msgid "Import into a new calendar" +msgstr "" + +#: templates/part.import.php:10 +msgid "Please choose the calendar" +msgstr "" + +#: templates/part.import.php:20 templates/part.import.php:37 +msgid "Import" +msgstr "" + +#: templates/part.import.php:22 templates/part.import.php:39 +msgid "Back" +msgstr "" + +#: templates/part.import.php:25 +msgid "Please fill out the form" msgstr "" #: templates/part.newevent.php:1 msgid "Create a new event" msgstr "" -#: templates/settings.php:11 +#: templates/settings.php:13 msgid "Timezone" msgstr "" + +#: templates/settings.php:32 +msgid "Timeformat" +msgstr "" + +#: templates/settings.php:34 +msgid "24h" +msgstr "" + +#: templates/settings.php:35 +msgid "12h" +msgstr "" + +#: templates/settings.php:41 +msgid "Calendar CalDAV syncing address:" +msgstr "" From 9761a1de3e92297244a7ff5f0e164dc860d80507 Mon Sep 17 00:00:00 2001 From: Georg Ehrke Date: Sat, 22 Oct 2011 13:14:54 +0200 Subject: [PATCH 07/59] translatable error messages --- apps/calendar/js/calendar.js | 16 ++++++++-------- apps/calendar/l10n/xgettextfiles | 12 ++++++++---- apps/calendar/templates/calendar.php | 11 ++++++++++- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/apps/calendar/js/calendar.js b/apps/calendar/js/calendar.js index a29d667285..afbb1b2858 100644 --- a/apps/calendar/js/calendar.js +++ b/apps/calendar/js/calendar.js @@ -91,27 +91,27 @@ Calendar={ $.post(url, post, function(data){ if(data.status == "error"){ - var output = "Missing fields:
"; + var output = missing_field + ":
"; if(data.title == "true"){ - output = output + "Title
"; + output = output + missing_field_title + "
"; } if(data.cal == "true"){ - output = output + "Calendar
"; + output = output + missing_field_calendar + "
"; } if(data.from == "true"){ - output = output + "From Date
"; + output = output + missing_field_fromdate + "
"; } if(data.fromtime == "true"){ - output = output + "From Time
"; + output = output + missing_field_fromtime + "
"; } if(data.to == "true"){ - output = output + "To Date
"; + output = output + missing_field_todate + "
"; } if(data.totime == "true"){ - output = output + "To Time
"; + output = output + missing_field_totime + "
"; } if(data.endbeforestart == "true"){ - output = "The event ends before it starts!"; + output = output + missing_field_startsbeforeends + "!
"; } if(data.dberror == "true"){ output = "There was a database fail!"; diff --git a/apps/calendar/l10n/xgettextfiles b/apps/calendar/l10n/xgettextfiles index 4cc636436b..27b8e45719 100644 --- a/apps/calendar/l10n/xgettextfiles +++ b/apps/calendar/l10n/xgettextfiles @@ -1,7 +1,11 @@ ../appinfo/app.php +../lib/object.php ../templates/calendar.php -../templates/part.editevent.php -../templates/part.eventinfo.php -../templates/part.newevent.php ../templates/part.choosecalendar.php -../js/calendar.js +../templates/part.choosecalendar.rowfields.php +../templates/part.editcalendar.php +../templates/part.editevent.php +../templates/part.eventform.php +../templates/part.import.php +../templates/part.newevent.php +../templates/settings.php \ No newline at end of file diff --git a/apps/calendar/templates/calendar.php b/apps/calendar/templates/calendar.php index 1c948b948c..0a6a7008fc 100644 --- a/apps/calendar/templates/calendar.php +++ b/apps/calendar/templates/calendar.php @@ -6,6 +6,15 @@ var dayNamesShort = tA(array('Sun.', 'Mon.', 'Tue.', var monthNames = tA(array('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'))) ?>; var monthNamesShort = tA(array('Jan.', 'Feb.', 'Mar.', 'Apr.', 'May.', 'Jun.', 'Jul.', 'Aug.', 'Sep.', 'Oct.', 'Nov.', 'Dec.'))) ?>; var allDayText = 't('All day') ?>'; +var missing_field = 't('Missing fields') ?>'; +var missing_field_title = 't('Title') ?>'; +var missing_field_calendar = 't('Calendar') ?>'; +var missing_field_fromdate = 't('From Date') ?>'; +var missing_field_fromtime = 't('From Time') ?>'; +var missing_field_todate = 't('To Date') ?>'; +var missing_field_totime = 't('To Time') ?>'; +var missing_field_startsbeforeends = 't('The event ends before it starts') ?>'; +var missing_field_dberror = 't('There was a database fail') ?>';
@@ -25,7 +34,7 @@ var allDayText = 't('All day') ?>';
- +
From 950018b5c393898173ebb5ccb515ff12e836f6af Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Tue, 25 Oct 2011 19:56:57 +0200 Subject: [PATCH 08/59] Fix scrolling calendar --- apps/calendar/js/calendar.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/apps/calendar/js/calendar.js b/apps/calendar/js/calendar.js index afbb1b2858..d63b9df36f 100644 --- a/apps/calendar/js/calendar.js +++ b/apps/calendar/js/calendar.js @@ -204,9 +204,12 @@ Calendar={ direction = 'down'; } } - if(direction == 'down'){ + var scroll = $(document).scrollTop(), + doc_height = $(document).height(), + win_height = $(window).height(); + if(direction == 'down' && win_height == (doc_height - scroll)){ $('#calendar_holder').fullCalendar('next'); - }else{ + }else if (direction == 'top' && scroll == 0) { $('#calendar_holder').fullCalendar('prev'); } }, @@ -483,7 +486,7 @@ function ListView(element, calendar) { } } $(document).ready(function(){ - //Calendar.UI.initScroll(); + Calendar.UI.initScroll(); $('#calendar_holder').fullCalendar({ header: false, firstDay: 1, From 50649ad0d19e8dc8ad3f2366673217c752d1774c Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Tue, 25 Oct 2011 19:57:20 +0200 Subject: [PATCH 09/59] Implement select event creation --- apps/calendar/ajax/neweventform.php | 48 +++++++++++++---------------- apps/calendar/js/calendar.js | 35 ++++++--------------- 2 files changed, 31 insertions(+), 52 deletions(-) diff --git a/apps/calendar/ajax/neweventform.php b/apps/calendar/ajax/neweventform.php index d02b116347..588d364871 100644 --- a/apps/calendar/ajax/neweventform.php +++ b/apps/calendar/ajax/neweventform.php @@ -15,39 +15,35 @@ if(!OC_USER::isLoggedIn()) { } OC_JSON::checkAppEnabled('calendar'); +if (!isset($_POST['start'])){ + OC_JSON::error(); + die; +} +$start = $_POST['start']; +$end = $_POST['end']; +$allday = $_POST['allday']; + +if (!$end){ + $duration = OC_Preferences::getValue( OC_User::getUser(), 'calendar', 'duration', '60'); + $end = $start + ($duration * 60); +} +$start = new DateTime('@'.$start); +$end = new DateTime('@'.$end); +$timezone = OC_Preferences::getValue(OC_USER::getUser(), 'calendar', 'timezone', 'Europe/London'); +$start->setTimezone(new DateTimeZone($timezone)); +$end->setTimezone(new DateTimeZone($timezone)); + $calendar_options = OC_Calendar_Calendar::allCalendars(OC_User::getUser()); $category_options = OC_Calendar_Object::getCategoryOptions($l10n); $repeat_options = OC_Calendar_Object::getRepeatOptions($l10n); -$startday = substr($_GET['d'], 0, 2); -$startmonth = substr($_GET['d'], 2, 2); -$startyear = substr($_GET['d'], 4, 4); -$allday = $_GET['t'] == 'allday'; -if(!$allday){ - $starthour = substr($_GET['t'], 0, 2); - $startminutes = substr($_GET['t'], 2, 2); -}else{ - $starthour = '00'; - $startminutes = '00'; -} - -$datetimestamp = mktime($starthour, $startminutes, 0, $startmonth, $startday, $startyear); -$duration = OC_Preferences::getValue( OC_User::getUser(), 'calendar', 'duration', "60"); -$datetimestamp = $datetimestamp + ($duration * 60); -$endmonth = date("m", $datetimestamp); -$endday = date("d", $datetimestamp); -$endyear = date("Y", $datetimestamp); -$endtime = date("G", $datetimestamp); -$endminutes = date("i", $datetimestamp); - - $tmpl = new OC_Template('calendar', 'part.newevent'); $tmpl->assign('calendar_options', $calendar_options); $tmpl->assign('category_options', $category_options); -$tmpl->assign('startdate', $startday . '-' . $startmonth . '-' . $startyear); -$tmpl->assign('starttime', $starthour . ':' . $startminutes); -$tmpl->assign('enddate', $endday . '-' . $endmonth . '-' . $endyear); -$tmpl->assign('endtime', ($endtime <= 9 ? '0' : '') . $endtime . ':' . $endminutes); +$tmpl->assign('startdate', $start->format('d-m-Y')); +$tmpl->assign('starttime', $start->format('H:i')); +$tmpl->assign('enddate', $end->format('d-m-Y')); +$tmpl->assign('endtime', $end->format('H:i')); $tmpl->assign('allday', $allday); $tmpl->printpage(); ?> diff --git a/apps/calendar/js/calendar.js b/apps/calendar/js/calendar.js index d63b9df36f..30015ae68f 100644 --- a/apps/calendar/js/calendar.js +++ b/apps/calendar/js/calendar.js @@ -31,36 +31,17 @@ Calendar={ } }); }, - newEvent:function(date, allDay, jsEvent, view){ - var dayofmonth = date.getDate(); - var month = date.getMonth(); - var year = date.getFullYear(); - var hour = date.getHours(); - var min = date.getMinutes(); - if(dayofmonth <= 9){ - dayofmonth = '0' + dayofmonth; - } - month++; - if(month <= 9){ - month = '0' + month; - } - if(hour <= 9){ - hour = '0' + hour; - } - if(min <= 9){ - min = '0' + min; - } - var date = String(dayofmonth) + String(month) + String(year); - if (allDay){ - var time = 'allday'; - }else{ - var time = String(hour) + String(min); + newEvent:function(start, end, allday){ + start = Math.round(start.getTime()/1000); + if (end){ + end = Math.round(end.getTime()/1000); } + $('#calendar_holder').fullCalendar('unselect'); if($('#event').dialog('isOpen') == true){ // TODO: save event $('#event').dialog('destroy').remove(); }else{ - $('#dialog_holder').load(OC.filePath('calendar', 'ajax', 'neweventform.php') + '?d=' + date + '&t=' + time, Calendar.UI.startEventDialog); + $('#dialog_holder').load(OC.filePath('calendar', 'ajax', 'neweventform.php'), {start:start, end:end, allday:allday?1:0}, Calendar.UI.startEventDialog); } }, editEvent:function(calEvent, jsEvent, view){ @@ -509,7 +490,9 @@ $(document).ready(function(){ $('#datecontrol_date').html(view.title); $.get(OC.filePath('calendar', 'ajax', 'changeview.php') + "?v="+view.name); }, - dayClick: Calendar.UI.newEvent, + selectable: true, + selectHelper: true, + select: Calendar.UI.newEvent, eventClick: Calendar.UI.editEvent, eventDrop: Calendar.UI.moveEvent, eventResize: Calendar.UI.resizeEvent, From 55d957489d3680ca97d70faa70ea15999a7278df Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Tue, 25 Oct 2011 19:59:23 +0200 Subject: [PATCH 10/59] Fix fromtime/totime warnings --- apps/calendar/lib/object.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/calendar/lib/object.php b/apps/calendar/lib/object.php index 4afeb341a9..9a343a2376 100644 --- a/apps/calendar/lib/object.php +++ b/apps/calendar/lib/object.php @@ -426,7 +426,7 @@ class OC_Calendar_Object{ $errarr['endbeforestart'] = 'true'; $errnum++; } - if($fromday == $today && $frommonth == $tomonth && $fromyear == $toyear){ + if(!$allday && $fromday == $today && $frommonth == $tomonth && $fromyear == $toyear){ list($tohours, $tominutes) = explode(':', $request['totime']); list($fromhours, $fromminutes) = explode(':', $request['fromtime']); if($tohours < $fromhours){ @@ -481,9 +481,11 @@ class OC_Calendar_Object{ $categories = isset($request["categories"]) ? $request["categories"] : null; $allday = isset($request["allday"]); $from = $request["from"]; - $fromtime = $request["fromtime"]; $to = $request["to"]; - $totime = $request["totime"]; + if (!$allday){ + $fromtime = $request['fromtime']; + $totime = $request['totime']; + } $description = $request["description"]; //$repeat = $request["repeat"]; /*switch($request["repeatfreq"]){ From d0e9c813993f5f02381f52faf34c9a54247f58fb Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Tue, 25 Oct 2011 20:01:04 +0200 Subject: [PATCH 11/59] Quickfix hanging tipsy popups --- apps/calendar/js/calendar.js | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/calendar/js/calendar.js b/apps/calendar/js/calendar.js index 30015ae68f..cdfc521b22 100644 --- a/apps/calendar/js/calendar.js +++ b/apps/calendar/js/calendar.js @@ -10,6 +10,7 @@ Calendar={ space:' ', UI:{ startEventDialog:function(){ + $('.tipsy').remove(); Calendar.UI.lockTime(); $( "#from" ).datepicker({ dateFormat : 'dd-mm-yy' From 1e8e2ae353312dacc2a05f1005fa322566cb6012 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Thu, 27 Oct 2011 22:54:39 +0200 Subject: [PATCH 12/59] Move unselect call to after the dialog starts --- apps/calendar/js/calendar.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/calendar/js/calendar.js b/apps/calendar/js/calendar.js index cdfc521b22..47db5dc5fc 100644 --- a/apps/calendar/js/calendar.js +++ b/apps/calendar/js/calendar.js @@ -11,6 +11,7 @@ Calendar={ UI:{ startEventDialog:function(){ $('.tipsy').remove(); + $('#calendar_holder').fullCalendar('unselect'); Calendar.UI.lockTime(); $( "#from" ).datepicker({ dateFormat : 'dd-mm-yy' @@ -37,7 +38,6 @@ Calendar={ if (end){ end = Math.round(end.getTime()/1000); } - $('#calendar_holder').fullCalendar('unselect'); if($('#event').dialog('isOpen') == true){ // TODO: save event $('#event').dialog('destroy').remove(); From 8dd2f463f826d44299770919b7e9be21d83075f7 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Thu, 27 Oct 2011 22:56:22 +0200 Subject: [PATCH 13/59] Cleanup tipsy popups on more actions --- apps/calendar/js/calendar.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/calendar/js/calendar.js b/apps/calendar/js/calendar.js index 47db5dc5fc..e943bee705 100644 --- a/apps/calendar/js/calendar.js +++ b/apps/calendar/js/calendar.js @@ -107,6 +107,7 @@ Calendar={ },"json"); }, moveEvent:function(event, dayDelta, minuteDelta, allDay, revertFunc){ + $('.tipsy').remove(); $.post(OC.filePath('calendar', 'ajax', 'moveevent.php'), { id: event.id, dayDelta: dayDelta, minuteDelta: minuteDelta, allDay: allDay?1:0}, function(data) { if (data.status == 'success'){ @@ -117,6 +118,7 @@ Calendar={ }); }, resizeEvent:function(event, dayDelta, minuteDelta, revertFunc){ + $('.tipsy').remove(); $.post(OC.filePath('calendar', 'ajax', 'resizeevent.php'), { id: event.id, dayDelta: dayDelta, minuteDelta: minuteDelta}, function(data) { if (data.status == 'success'){ @@ -171,6 +173,7 @@ Calendar={ //} }, scrollCalendar:function(event){ + $('.tipsy').remove(); var direction; if(event.detail){ if(event.detail < 0){ From c65e4176662aa989e1444c3c584a9d7846469262 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Wed, 9 Nov 2011 22:16:24 +0100 Subject: [PATCH 14/59] Use parse function in Calendar_Object --- apps/calendar/ajax/editevent.php | 2 +- apps/calendar/ajax/editeventform.php | 2 +- apps/calendar/ajax/events.php | 2 +- apps/calendar/ajax/moveevent.php | 2 +- apps/calendar/ajax/resizeevent.php | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/calendar/ajax/editevent.php b/apps/calendar/ajax/editevent.php index 3abf4de98b..a60b0946ad 100644 --- a/apps/calendar/ajax/editevent.php +++ b/apps/calendar/ajax/editevent.php @@ -34,7 +34,7 @@ if($errarr){ OC_JSON::error(); exit; } - $vcalendar = Sabre_VObject_Reader::read($data['calendardata']); + $vcalendar = OC_Calendar_Object::parse($data['calendardata']); OC_Calendar_Object::updateVCalendarFromRequest($_POST, $vcalendar); $result = OC_Calendar_Object::edit($id, $vcalendar->serialize()); if ($data['calendarid'] != $cal) { diff --git a/apps/calendar/ajax/editeventform.php b/apps/calendar/ajax/editeventform.php index 34d6c657ce..e6dc813660 100644 --- a/apps/calendar/ajax/editeventform.php +++ b/apps/calendar/ajax/editeventform.php @@ -26,7 +26,7 @@ if($calendar['userid'] != OC_User::getUser()){ echo $l10n->t('Wrong calendar'); exit; } -$object = Sabre_VObject_Reader::read($data['calendardata']); +$object = OC_Calendar_Object::parse($data['calendardata']); $vevent = $object->VEVENT; $dtstart = $vevent->DTSTART; $dtend = OC_Calendar_Object::getDTEndFromVEvent($vevent); diff --git a/apps/calendar/ajax/events.php b/apps/calendar/ajax/events.php index 5c4cced8d2..5ee2ffb627 100644 --- a/apps/calendar/ajax/events.php +++ b/apps/calendar/ajax/events.php @@ -21,7 +21,7 @@ $return = array(); foreach($events as $event) { $return_event = array(); - $object = Sabre_VObject_Reader::read($event['calendardata']); + $object = OC_Calendar_Object::parse($event['calendardata']); $vevent = $object->VEVENT; $dtstart = $vevent->DTSTART; $dtend = OC_Calendar_Object::getDTEndFromVEvent($vevent); diff --git a/apps/calendar/ajax/moveevent.php b/apps/calendar/ajax/moveevent.php index 1fef1c5b20..834a454fca 100644 --- a/apps/calendar/ajax/moveevent.php +++ b/apps/calendar/ajax/moveevent.php @@ -22,7 +22,7 @@ $delta = new DateInterval('P0D'); $delta->d = $_POST['dayDelta']; $delta->i = $_POST['minuteDelta']; -$vcalendar = Sabre_VObject_Reader::read($data['calendardata']); +$vcalendar = OC_Calendar_Object::parse($data['calendardata']); $vevent = $vcalendar->VEVENT; $dtstart = $vevent->DTSTART; diff --git a/apps/calendar/ajax/resizeevent.php b/apps/calendar/ajax/resizeevent.php index 3a2bf87afd..639ef91ee7 100644 --- a/apps/calendar/ajax/resizeevent.php +++ b/apps/calendar/ajax/resizeevent.php @@ -22,7 +22,7 @@ $delta = new DateInterval('P0D'); $delta->d = $_POST['dayDelta']; $delta->i = $_POST['minuteDelta']; -$vcalendar = Sabre_VObject_Reader::read($data['calendardata']); +$vcalendar = OC_Calendar_Object::parse($data['calendardata']); $vevent = $vcalendar->VEVENT; $dtend = OC_Calendar_Object::getDTEndFromVEvent($vevent); From b095859a928a29bcb738dd820fb13dd57495c8d0 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Wed, 9 Nov 2011 22:17:09 +0100 Subject: [PATCH 15/59] Use Last-Modified property to check for changed events --- apps/calendar/ajax/editevent.php | 7 +++++++ apps/calendar/ajax/editeventform.php | 7 +++++++ apps/calendar/ajax/events.php | 9 ++++++++- apps/calendar/ajax/moveevent.php | 8 +++++++- apps/calendar/ajax/resizeevent.php | 8 +++++++- apps/calendar/js/calendar.js | 8 ++++++-- apps/calendar/lib/object.php | 1 + apps/calendar/templates/part.editevent.php | 1 + 8 files changed, 44 insertions(+), 5 deletions(-) diff --git a/apps/calendar/ajax/editevent.php b/apps/calendar/ajax/editevent.php index a60b0946ad..46feb06849 100644 --- a/apps/calendar/ajax/editevent.php +++ b/apps/calendar/ajax/editevent.php @@ -35,6 +35,13 @@ if($errarr){ exit; } $vcalendar = OC_Calendar_Object::parse($data['calendardata']); + + $last_modified = $vcalendar->VEVENT->__get('LAST-MODIFIED'); + if($last_modified && $_POST['lastmodified'] != $last_modified->getDateTime()->format('U')){ + OC_JSON::error(array('modified'=>true)); + exit; + } + OC_Calendar_Object::updateVCalendarFromRequest($_POST, $vcalendar); $result = OC_Calendar_Object::edit($id, $vcalendar->serialize()); if ($data['calendarid'] != $cal) { diff --git a/apps/calendar/ajax/editeventform.php b/apps/calendar/ajax/editeventform.php index e6dc813660..63c7293407 100644 --- a/apps/calendar/ajax/editeventform.php +++ b/apps/calendar/ajax/editeventform.php @@ -63,9 +63,16 @@ foreach($categories as $category){ } $repeat = isset($vevent->CATEGORY) ? $vevent->CATEGORY->value : ''; $description = isset($vevent->DESCRIPTION) ? $vevent->DESCRIPTION->value : ''; +$last_modified = $vevent->__get('LAST-MODIFIED'); +if ($last_modified){ + $lastmodified = $last_modified->getDateTime()->format('U'); +}else{ + $lastmodified = 0; +} $tmpl = new OC_Template('calendar', 'part.editevent'); $tmpl->assign('id', $id); +$tmpl->assign('lastmodified', $lastmodified); $tmpl->assign('calendar_options', $calendar_options); $tmpl->assign('category_options', $category_options); $tmpl->assign('repeat_options', $repeat_options); diff --git a/apps/calendar/ajax/events.php b/apps/calendar/ajax/events.php index 5ee2ffb627..66aeb1a35b 100644 --- a/apps/calendar/ajax/events.php +++ b/apps/calendar/ajax/events.php @@ -40,9 +40,16 @@ foreach($events as $event) $return_event['end'] = $end_dt->format('Y-m-d H:i:s'); $return_event['allDay'] = false; } - $return_event['id'] = $event['id']; + $return_event['id'] = (int)$event['id']; $return_event['title'] = $event['summary']; $return_event['description'] = isset($vevent->DESCRIPTION)?$vevent->DESCRIPTION->value:''; + $last_modified = $vevent->__get('LAST-MODIFIED'); + if ($last_modified){ + $lastmodified = $last_modified->getDateTime()->format('U'); + }else{ + $lastmodified = 0; + } + $return_event['lastmodified'] = (int)$lastmodified; $return[] = $return_event; } OC_JSON::encodedPrint($return); diff --git a/apps/calendar/ajax/moveevent.php b/apps/calendar/ajax/moveevent.php index 834a454fca..6b315a3921 100644 --- a/apps/calendar/ajax/moveevent.php +++ b/apps/calendar/ajax/moveevent.php @@ -25,6 +25,12 @@ $delta->i = $_POST['minuteDelta']; $vcalendar = OC_Calendar_Object::parse($data['calendardata']); $vevent = $vcalendar->VEVENT; +$last_modified = $vevent->__get('LAST-MODIFIED'); +if($last_modified && $_POST['lastmodified'] != $last_modified->getDateTime()->format('U')){ + OC_JSON::error(); + exit; +} + $dtstart = $vevent->DTSTART; $dtend = OC_Calendar_Object::getDTEndFromVEvent($vevent); $start_type = $dtstart->getDateType(); @@ -50,4 +56,4 @@ $dtstamp->setDateTime($now, Sabre_VObject_Element_DateTime::UTC); $vevent->DTSTAMP = $dtstamp; $result = OC_Calendar_Object::edit($id, $vcalendar->serialize()); -OC_JSON::success(); +OC_JSON::success(array('lastmodified'=>(int)$now->format('U'))); diff --git a/apps/calendar/ajax/resizeevent.php b/apps/calendar/ajax/resizeevent.php index 639ef91ee7..28a185411e 100644 --- a/apps/calendar/ajax/resizeevent.php +++ b/apps/calendar/ajax/resizeevent.php @@ -25,6 +25,12 @@ $delta->i = $_POST['minuteDelta']; $vcalendar = OC_Calendar_Object::parse($data['calendardata']); $vevent = $vcalendar->VEVENT; +$last_modified = $vevent->__get('LAST-MODIFIED'); +if($last_modified && $_POST['lastmodified'] != $last_modified->getDateTime()->format('U')){ + OC_JSON::error(); + exit; +} + $dtend = OC_Calendar_Object::getDTEndFromVEvent($vevent); $end_type = $dtend->getDateType(); $dtend->setDateTime($dtend->getDateTime()->add($delta), $end_type); @@ -40,4 +46,4 @@ $dtstamp->setDateTime($now, Sabre_VObject_Element_DateTime::UTC); $vevent->DTSTAMP = $dtstamp; $result = OC_Calendar_Object::edit($id, $vcalendar->serialize()); -OC_JSON::success(); +OC_JSON::success(array('lastmodified'=>$now->format('U'))); diff --git a/apps/calendar/js/calendar.js b/apps/calendar/js/calendar.js index e943bee705..af5ecd8281 100644 --- a/apps/calendar/js/calendar.js +++ b/apps/calendar/js/calendar.js @@ -108,23 +108,27 @@ Calendar={ }, moveEvent:function(event, dayDelta, minuteDelta, allDay, revertFunc){ $('.tipsy').remove(); - $.post(OC.filePath('calendar', 'ajax', 'moveevent.php'), { id: event.id, dayDelta: dayDelta, minuteDelta: minuteDelta, allDay: allDay?1:0}, + $.post(OC.filePath('calendar', 'ajax', 'moveevent.php'), { id: event.id, dayDelta: dayDelta, minuteDelta: minuteDelta, allDay: allDay?1:0, lastmodified: event.lastmodified}, function(data) { if (data.status == 'success'){ + event.lastmodified = data.lastmodified; console.log("Event moved successfully"); }else{ revertFunc(); + $('#calendar_holder').fullCalendar('refetchEvents'); } }); }, resizeEvent:function(event, dayDelta, minuteDelta, revertFunc){ $('.tipsy').remove(); - $.post(OC.filePath('calendar', 'ajax', 'resizeevent.php'), { id: event.id, dayDelta: dayDelta, minuteDelta: minuteDelta}, + $.post(OC.filePath('calendar', 'ajax', 'resizeevent.php'), { id: event.id, dayDelta: dayDelta, minuteDelta: minuteDelta, lastmodified: event.lastmodified}, function(data) { if (data.status == 'success'){ + event.lastmodified = data.lastmodified; console.log("Event resized successfully"); }else{ revertFunc(); + $('#calendar_holder').fullCalendar('refetchEvents'); } }); }, diff --git a/apps/calendar/lib/object.php b/apps/calendar/lib/object.php index 9a343a2376..221df2b3af 100644 --- a/apps/calendar/lib/object.php +++ b/apps/calendar/lib/object.php @@ -307,6 +307,7 @@ class OC_Calendar_Object{ */ public static function parse($data){ try { + Sabre_VObject_Reader::$elementMap['LAST-MODIFIED'] = 'Sabre_VObject_Element_DateTime'; $calendar = Sabre_VObject_Reader::read($data); return $calendar; } catch (Exception $e) { diff --git a/apps/calendar/templates/part.editevent.php b/apps/calendar/templates/part.editevent.php index ae969f2dc3..b3acfc4a07 100644 --- a/apps/calendar/templates/part.editevent.php +++ b/apps/calendar/templates/part.editevent.php @@ -1,6 +1,7 @@
">
+ inc("part.eventform"); ?>
From 26272c42525e63fedcf2b35d3d875fbec860eae1 Mon Sep 17 00:00:00 2001 From: Georg Ehrke Date: Fri, 11 Nov 2011 15:51:44 +0100 Subject: [PATCH 16/59] automatic timezone detection --- apps/calendar/ajax/guesstimezone.php | 39 ++++++++++++++++++++++++++++ apps/calendar/index.php | 5 +++- apps/calendar/js/geo.js | 20 ++++++++++++++ apps/calendar/templates/calendar.php | 37 +++++++++++++------------- 4 files changed, 82 insertions(+), 19 deletions(-) create mode 100755 apps/calendar/ajax/guesstimezone.php create mode 100755 apps/calendar/js/geo.js mode change 100644 => 100755 apps/calendar/templates/calendar.php diff --git a/apps/calendar/ajax/guesstimezone.php b/apps/calendar/ajax/guesstimezone.php new file mode 100755 index 0000000000..a3594498b0 --- /dev/null +++ b/apps/calendar/ajax/guesstimezone.php @@ -0,0 +1,39 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ +function make_array_out_of_xml ($xml){ + $returnarray = array(); + $xml = (array)$xml ; + foreach ($xml as $property => $value){ + $value = (array)$value; + if(!isset($value[0])){ + $returnarray[$property] = make_array_out_of_xml($value); + }else{ + $returnarray[$property] = trim($value[0]); + } + } + return $returnarray; +} +require_once ("../../../lib/base.php"); +OC_JSON::checkLoggedIn(); +OC_JSON::checkAppEnabled('calendar'); +$l = new OC_L10N('calendar'); +$lat = $_GET['lat']; +$long = $_GET['long']; +$geolocation = file_get_contents('http://ws.geonames.org/timezone?lat=' . $lat . '&lng=' . $long); +//Information are by Geonames (http://www.geonames.org) and licensed under the Creative Commons Attribution 3.0 License +$geoxml = simplexml_load_string($geolocation); +$geoarray = make_array_out_of_xml($geoxml); +if(isset($geoarray['timezone']['timezoneId']) && $geoarray['timezone']['timezoneId'] != ''){ + OC_Preferences::setValue(OC_USER::getUser(), 'calendar', 'timezone', $geoarray['timezone']['timezoneId']); + $message = array('message'=> $l->t('New Timezone:') . $geoarray['timezone']['timezoneId']); + OC_JSON::success($message); +}else{ + OC_JSON::error(); +} + +?> \ No newline at end of file diff --git a/apps/calendar/index.php b/apps/calendar/index.php index e5326d26e9..3313750d52 100644 --- a/apps/calendar/index.php +++ b/apps/calendar/index.php @@ -32,6 +32,9 @@ if(OC_Preferences::getValue(OC_USER::getUser(), 'calendar', 'currentview', 'mont OC_Util::addScript('3rdparty/fullcalendar', 'fullcalendar'); OC_Util::addStyle('3rdparty/fullcalendar', 'fullcalendar'); +if(OC_Preferences::getValue(OC_USER::getUser(), "calendar", "timezone") == null){ + OC_UTIL::addScript('calendar', 'geo'); +} OC_Util::addScript('calendar', 'calendar'); OC_Util::addStyle('calendar', 'style'); OC_Util::addScript('', 'jquery.multiselect'); @@ -39,4 +42,4 @@ OC_Util::addStyle('', 'jquery.multiselect'); OC_App::setActiveNavigationEntry('calendar_index'); $tmpl = new OC_Template('calendar', 'calendar', 'user'); $tmpl->assign('eventSources', $eventSources); -$tmpl->printPage(); +$tmpl->printPage(); \ No newline at end of file diff --git a/apps/calendar/js/geo.js b/apps/calendar/js/geo.js new file mode 100755 index 0000000000..acea17c026 --- /dev/null +++ b/apps/calendar/js/geo.js @@ -0,0 +1,20 @@ +/** + * Copyright (c) 2011 Georg Ehrke + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ +if (navigator.geolocation) { + navigator.geolocation.getCurrentPosition(function(position) { + $.getJSON(OC.filePath('calendar', 'ajax', 'guesstimezone.php?lat=' + position.coords.latitude + '&long=' + position.coords.longitude + ''), + function(data){ + if (data.status == 'success'){ + $('#notification').html(data.message); + $('#notification').slideDown(); + window.setTimeout(function(){$('#notification').slideUp();}, 5000); + }else{ + console.log('Can\'t set new timezone.'); + } + }); + }); +} \ No newline at end of file diff --git a/apps/calendar/templates/calendar.php b/apps/calendar/templates/calendar.php old mode 100644 new mode 100755 index 0a6a7008fc..6654568f5a --- a/apps/calendar/templates/calendar.php +++ b/apps/calendar/templates/calendar.php @@ -1,21 +1,21 @@ - +
@@ -40,6 +40,7 @@ var missing_field_dberror = 't('There was a database fail') ?>';
+
From 03d9fab3c0cf3a3c50259d6a33439a998628b45c Mon Sep 17 00:00:00 2001 From: Georg Ehrke Date: Sat, 12 Nov 2011 14:06:14 +0100 Subject: [PATCH 17/59] fix caldav url --- apps/calendar/templates/calendar.php | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/calendar/templates/calendar.php b/apps/calendar/templates/calendar.php index 6654568f5a..bee98f43e1 100755 --- a/apps/calendar/templates/calendar.php +++ b/apps/calendar/templates/calendar.php @@ -15,6 +15,7 @@ var missing_field_totime = 't('To Time') ?>'; var missing_field_startsbeforeends = 't('The event ends before it starts') ?>'; var missing_field_dberror = 't('There was a database fail') ?>'; + var totalurl = '';
From eea20e51d8d96e91a7899704cad48811152fe143 Mon Sep 17 00:00:00 2001 From: Georg Ehrke Date: Sat, 12 Nov 2011 16:13:27 +0100 Subject: [PATCH 18/59] another fix of caldav url --- apps/calendar/templates/calendar.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/calendar/templates/calendar.php b/apps/calendar/templates/calendar.php index bee98f43e1..76c0249e26 100755 --- a/apps/calendar/templates/calendar.php +++ b/apps/calendar/templates/calendar.php @@ -15,7 +15,7 @@ var missing_field_totime = 't('To Time') ?>'; var missing_field_startsbeforeends = 't('The event ends before it starts') ?>'; var missing_field_dberror = 't('There was a database fail') ?>'; - var totalurl = ''; + var totalurl = '/calendars';
From a303992d781db9d6714522014f4903ce89c62127 Mon Sep 17 00:00:00 2001 From: Georg Ehrke Date: Sat, 12 Nov 2011 22:02:04 +0100 Subject: [PATCH 19/59] support for repeating events --- 3rdparty/when/MIT-LICENSE.txt | 9 + 3rdparty/when/When.php | 725 ++++++++++++++++++++++++++++++++++ apps/calendar/ajax/events.php | 97 +++-- apps/calendar/lib/object.php | 4 +- 4 files changed, 799 insertions(+), 36 deletions(-) create mode 100644 3rdparty/when/MIT-LICENSE.txt create mode 100755 3rdparty/when/When.php diff --git a/3rdparty/when/MIT-LICENSE.txt b/3rdparty/when/MIT-LICENSE.txt new file mode 100644 index 0000000000..b4429c89ac --- /dev/null +++ b/3rdparty/when/MIT-LICENSE.txt @@ -0,0 +1,9 @@ +License + +Copyright (c) 2010 Thomas Planer + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/3rdparty/when/When.php b/3rdparty/when/When.php new file mode 100755 index 0000000000..5f97f0eb9b --- /dev/null +++ b/3rdparty/when/When.php @@ -0,0 +1,725 @@ + + * Location: http://github.com/tplaner/When + * Created: September 2010 + * Description: Determines the next date of recursion given an iCalendar "rrule" like pattern. + * Requirements: PHP 5.3+ - makes extensive use of the Date and Time library (http://us2.php.net/manual/en/book.datetime.php) + */ +class When +{ + protected $frequency; + + protected $start_date; + protected $try_date; + + protected $end_date; + + protected $gobymonth; + protected $bymonth; + + protected $gobyweekno; + protected $byweekno; + + protected $gobyyearday; + protected $byyearday; + + protected $gobymonthday; + protected $bymonthday; + + protected $gobyday; + protected $byday; + + protected $gobysetpos; + protected $bysetpos; + + protected $suggestions; + + protected $count; + protected $counter; + + protected $goenddate; + + protected $interval; + + protected $wkst; + + protected $valid_week_days; + protected $valid_frequency; + + /** + * __construct + */ + public function __construct() + { + $this->frequency = null; + + $this->gobymonth = false; + $this->bymonth = range(1,12); + + $this->gobymonthday = false; + $this->bymonthday = range(1,31); + + $this->gobyday = false; + // setup the valid week days (0 = sunday) + $this->byday = range(0,6); + + $this->gobyyearday = false; + $this->byyearday = range(0,366); + + $this->gobysetpos = false; + $this->bysetpos = range(1,366); + + $this->gobyweekno = false; + // setup the range for valid weeks + $this->byweekno = range(0,54); + + $this->suggestions = array(); + + // this will be set if a count() is specified + $this->count = 0; + // how many *valid* results we returned + $this->counter = 0; + + // max date we'll return + $this->end_date = new DateTime('9999-12-31'); + + // the interval to increase the pattern by + $this->interval = 1; + + // what day does the week start on? (0 = sunday) + $this->wkst = 0; + + $this->valid_week_days = array('SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA'); + + $this->valid_frequency = array('SECONDLY', 'MINUTELY', 'HOURLY', 'DAILY', 'WEEKLY', 'MONTHLY', 'YEARLY'); + } + + /** + * @param DateTime|string $start_date of the recursion - also is the first return value. + * @param string $frequency of the recrusion, valid frequencies: secondly, minutely, hourly, daily, weekly, monthly, yearly + */ + public function recur($start_date, $frequency = "daily") + { + try + { + if(is_object($start_date)) + { + $this->start_date = clone $start_date; + } + else + { + // timestamps within the RFC have a 'Z' at the end of them, remove this. + $start_date = trim($start_date, 'Z'); + $this->start_date = new DateTime($start_date); + } + + $this->try_date = clone $this->start_date; + } + catch(Exception $e) + { + throw new InvalidArgumentException('Invalid start date DateTime: ' . $e); + } + + $this->freq($frequency); + + return $this; + } + + public function freq($frequency) + { + if(in_array(strtoupper($frequency), $this->valid_frequency)) + { + $this->frequency = strtoupper($frequency); + } + else + { + throw new InvalidArgumentException('Invalid frequency type.'); + } + + return $this; + } + + // accepts an rrule directly + public function rrule($rrule) + { + // strip off a trailing semi-colon + $rrule = trim($rrule, ";"); + + $parts = explode(";", $rrule); + + foreach($parts as $part) + { + list($rule, $param) = explode("=", $part); + + $rule = strtoupper($rule); + $param = strtoupper($param); + + switch($rule) + { + case "FREQ": + $this->frequency = $param; + break; + case "UNTIL": + $this->until($param); + break; + case "COUNT": + $this->count($param); + break; + case "INTERVAL": + $this->interval($param); + break; + case "BYDAY": + $params = explode(",", $param); + $this->byday($params); + break; + case "BYMONTHDAY": + $params = explode(",", $param); + $this->bymonthday($params); + break; + case "BYYEARDAY": + $params = explode(",", $param); + $this->byyearday($params); + break; + case "BYWEEKNO": + $params = explode(",", $param); + $this->byweekno($params); + break; + case "BYMONTH": + $params = explode(",", $param); + $this->bymonth($params); + break; + case "BYSETPOS": + $params = explode(",", $param); + $this->bysetpos($params); + break; + case "WKST": + $this->wkst($param); + break; + } + } + + return $this; + } + + //max number of items to return based on the pattern + public function count($count) + { + $this->count = (int)$count; + + return $this; + } + + // how often the recurrence rule repeats + public function interval($interval) + { + $this->interval = (int)$interval; + + return $this; + } + + // starting day of the week + public function wkst($day) + { + switch($day) + { + case 'SU': + $this->wkst = 0; + break; + case 'MO': + $this->wkst = 1; + break; + case 'TU': + $this->wkst = 2; + break; + case 'WE': + $this->wkst = 3; + break; + case 'TH': + $this->wkst = 4; + break; + case 'FR': + $this->wkst = 5; + break; + case 'SA': + $this->wkst = 6; + break; + } + + return $this; + } + + // max date + public function until($end_date) + { + try + { + if(is_object($end_date)) + { + $this->end_date = clone $end_date; + } + else + { + // timestamps within the RFC have a 'Z' at the end of them, remove this. + $end_date = trim($end_date, 'Z'); + $this->end_date = new DateTime($end_date); + } + } + catch(Exception $e) + { + throw new InvalidArgumentException('Invalid end date DateTime: ' . $e); + } + + return $this; + } + + public function bymonth($months) + { + if(is_array($months)) + { + $this->gobymonth = true; + $this->bymonth = $months; + } + + return $this; + } + + public function bymonthday($days) + { + if(is_array($days)) + { + $this->gobymonthday = true; + $this->bymonthday = $days; + } + + return $this; + } + + public function byweekno($weeks) + { + $this->gobyweekno = true; + + if(is_array($weeks)) + { + $this->byweekno = $weeks; + } + + return $this; + } + + public function bysetpos($days) + { + $this->gobysetpos = true; + + if(is_array($days)) + { + $this->bysetpos = $days; + } + + return $this; + } + + public function byday($days) + { + $this->gobyday = true; + + if(is_array($days)) + { + $this->byday = array(); + foreach($days as $day) + { + $len = strlen($day); + + $as = '+'; + + // 0 mean no occurence is set + $occ = 0; + + if($len == 3) + { + $occ = substr($day, 0, 1); + } + if($len == 4) + { + $as = substr($day, 0, 1); + $occ = substr($day, 1, 1); + } + + if($as == '-') + { + $occ = '-' . $occ; + } + else + { + $occ = '+' . $occ; + } + + $day = substr($day, -2, 2); + switch($day) + { + case 'SU': + $this->byday[] = $occ . 'SU'; + break; + case 'MO': + $this->byday[] = $occ . 'MO'; + break; + case 'TU': + $this->byday[] = $occ . 'TU'; + break; + case 'WE': + $this->byday[] = $occ . 'WE'; + break; + case 'TH': + $this->byday[] = $occ . 'TH'; + break; + case 'FR': + $this->byday[] = $occ . 'FR'; + break; + case 'SA': + $this->byday[] = $occ . 'SA'; + break; + } + } + } + + return $this; + } + + public function byyearday($days) + { + $this->gobyyearday = true; + + if(is_array($days)) + { + $this->byyearday = $days; + } + + return $this; + } + + // this creates a basic list of dates to "try" + protected function create_suggestions() + { + switch($this->frequency) + { + case "YEARLY": + $interval = 'year'; + break; + case "MONTHLY": + $interval = 'month'; + break; + case "WEEKLY": + $interval = 'week'; + break; + case "DAILY": + $interval = 'day'; + break; + case "HOURLY": + $interval = 'hour'; + break; + case "MINUTELY": + $interval = 'minute'; + break; + case "SECONDLY": + $interval = 'second'; + break; + } + + $month_day = $this->try_date->format('j'); + $month = $this->try_date->format('n'); + $year = $this->try_date->format('Y'); + + $timestamp = $this->try_date->format('H:i:s'); + + if($this->gobysetpos) + { + if($this->try_date == $this->start_date) + { + $this->suggestions[] = clone $this->try_date; + } + else + { + if($this->gobyday) + { + foreach($this->bysetpos as $_pos) + { + $tmp_array = array(); + $_mdays = range(1, date('t',mktime(0,0,0,$month,1,$year))); + foreach($_mdays as $_mday) + { + $date_time = new DateTime($year . '-' . $month . '-' . $_mday . ' ' . $timestamp); + + $occur = ceil($_mday / 7); + + $day_of_week = $date_time->format('l'); + $dow_abr = strtoupper(substr($day_of_week, 0, 2)); + + // set the day of the month + (positive) + $occur = '+' . $occur . $dow_abr; + $occur_zero = '+0' . $dow_abr; + + // set the day of the month - (negative) + $total_days = $date_time->format('t') - $date_time->format('j'); + $occur_neg = '-' . ceil(($total_days + 1)/7) . $dow_abr; + + $day_from_end_of_month = $date_time->format('t') + 1 - $_mday; + + if(in_array($occur, $this->byday) || in_array($occur_zero, $this->byday) || in_array($occur_neg, $this->byday)) + { + $tmp_array[] = clone $date_time; + } + } + + if($_pos > 0) + { + $this->suggestions[] = clone $tmp_array[$_pos - 1]; + } + else + { + $this->suggestions[] = clone $tmp_array[count($tmp_array) + $_pos]; + } + + } + } + } + } + elseif($this->gobyyearday) + { + foreach($this->byyearday as $_day) + { + if($_day >= 0) + { + $_day--; + + $_time = strtotime('+' . $_day . ' days', mktime(0, 0, 0, 1, 1, $year)); + $this->suggestions[] = new Datetime(date('Y-m-d', $_time) . ' ' . $timestamp); + } + else + { + $year_day_neg = 365 + $_day; + $leap_year = $this->try_date->format('L'); + if($leap_year == 1) + { + $year_day_neg = 366 + $_day; + } + + $_time = strtotime('+' . $year_day_neg . ' days', mktime(0, 0, 0, 1, 1, $year)); + $this->suggestions[] = new Datetime(date('Y-m-d', $_time) . ' ' . $timestamp); + } + } + } + // special case because for years you need to loop through the months too + elseif($this->gobyday && $interval == "year") + { + foreach($this->bymonth as $_month) + { + // this creates an array of days of the month + $_mdays = range(1, date('t',mktime(0,0,0,$_month,1,$year))); + foreach($_mdays as $_mday) + { + $date_time = new DateTime($year . '-' . $_month . '-' . $_mday . ' ' . $timestamp); + + // get the week of the month (1, 2, 3, 4, 5, etc) + $week = $date_time->format('W'); + + if($date_time >= $this->start_date && in_array($week, $this->byweekno)) + { + $this->suggestions[] = clone $date_time; + } + } + } + } + elseif($interval == "day") + { + $this->suggestions[] = clone $this->try_date; + } + elseif($interval == "week") + { + $this->suggestions[] = clone $this->try_date; + + if($this->gobyday) + { + $week_day = $this->try_date->format('w'); + + $days_in_month = $this->try_date->format('t'); + + $overflow_count = 1; + $_day = $month_day; + + $run = true; + while($run) + { + $_day++; + if($_day <= $days_in_month) + { + $tmp_date = new DateTime($year . '-' . $month . '-' . $_day . ' ' . $timestamp); + } + else + { + //$tmp_month = $month+1; + $tmp_date = new DateTime($year . '-' . $month . '-' . $overflow_count . ' ' . $timestamp); + $tmp_date->modify('+1 month'); + $overflow_count++; + } + + $week_day = $tmp_date->format('w'); + + if($this->try_date == $this->start_date) + { + if($week_day == $this->wkst) + { + $this->try_date = clone $tmp_date; + $this->try_date->modify('-7 days'); + $run = false; + } + } + + if($week_day != $this->wkst) + { + $this->suggestions[] = clone $tmp_date; + } + else + { + $run = false; + } + } + } + } + elseif($this->gobyday || $interval == "month") + { + $_mdays = range(1, date('t',mktime(0,0,0,$month,1,$year))); + foreach($_mdays as $_mday) + { + $date_time = new DateTime($year . '-' . $month . '-' . $_mday . ' ' . $timestamp); + + // get the week of the month (1, 2, 3, 4, 5, etc) + $week = $date_time->format('W'); + + if($date_time >= $this->start_date && in_array($week, $this->byweekno)) + { + $this->suggestions[] = clone $date_time; + } + } + } + elseif($this->gobymonth) + { + foreach($this->bymonth as $_month) + { + $date_time = new DateTime($year . '-' . $_month . '-' . $month_day . ' ' . $timestamp); + + if($date_time >= $this->start_date) + { + $this->suggestions[] = clone $date_time; + } + } + } + else + { + $this->suggestions[] = clone $this->try_date; + } + + if($interval == "month") + { + $this->try_date->modify('last day of ' . $this->interval . ' ' . $interval); + } + else + { + $this->try_date->modify($this->interval . ' ' . $interval); + } + } + + protected function valid_date($date) + { + $year = $date->format('Y'); + $month = $date->format('n'); + $day = $date->format('j'); + + $year_day = $date->format('z') + 1; + + $year_day_neg = -366 + $year_day; + $leap_year = $date->format('L'); + if($leap_year == 1) + { + $year_day_neg = -367 + $year_day; + } + + // this is the nth occurence of the date + $occur = ceil($day / 7); + + $week = $date->format('W'); + + $day_of_week = $date->format('l'); + $dow_abr = strtoupper(substr($day_of_week, 0, 2)); + + // set the day of the month + (positive) + $occur = '+' . $occur . $dow_abr; + $occur_zero = '+0' . $dow_abr; + + // set the day of the month - (negative) + $total_days = $date->format('t') - $date->format('j'); + $occur_neg = '-' . ceil(($total_days + 1)/7) . $dow_abr; + + $day_from_end_of_month = $date->format('t') + 1 - $day; + + if(in_array($month, $this->bymonth) && + (in_array($occur, $this->byday) || in_array($occur_zero, $this->byday) || in_array($occur_neg, $this->byday)) && + in_array($week, $this->byweekno) && + (in_array($day, $this->bymonthday) || in_array(-$day_from_end_of_month, $this->bymonthday)) && + (in_array($year_day, $this->byyearday) || in_array($year_day_neg, $this->byyearday))) + { + return true; + } + else + { + return false; + } + } + + // return the next valid DateTime object which matches the pattern and follows the rules + public function next() + { + // check the counter is set + if($this->count !== 0) + { + if($this->counter >= $this->count) + { + return false; + } + } + + // create initial set of suggested dates + if(count($this->suggestions) === 0) + { + $this->create_suggestions(); + } + + // loop through the suggested dates + while(count($this->suggestions) > 0) + { + // get the first one on the array + $try_date = array_shift($this->suggestions); + + // make sure the date doesn't exceed the max date + if($try_date > $this->end_date) + { + return false; + } + + // make sure it falls within the allowed days + if($this->valid_date($try_date) === true) + { + $this->counter++; + return $try_date; + } + else + { + // we might be out of suggested days, so load some more + if(count($this->suggestions) === 0) + { + $this->create_suggestions(); + } + } + } + } +} diff --git a/apps/calendar/ajax/events.php b/apps/calendar/ajax/events.php index 66aeb1a35b..f161bb88a0 100644 --- a/apps/calendar/ajax/events.php +++ b/apps/calendar/ajax/events.php @@ -6,40 +6,10 @@ * See the COPYING-README file. */ -require_once ("../../../lib/base.php"); -if(!OC_USER::isLoggedIn()) { - die(""); -} -OC_JSON::checkAppEnabled('calendar'); +require_once ('../../../lib/base.php'); +require_once('../../../3rdparty/when/When.php'); -$start = DateTime::createFromFormat('U', $_GET['start']); -$end = DateTime::createFromFormat('U', $_GET['end']); - -$events = OC_Calendar_Object::allInPeriod($_GET['calendar_id'], $start, $end); -$user_timezone = OC_Preferences::getValue(OC_USER::getUser(), "calendar", "timezone", "Europe/London"); -$return = array(); -foreach($events as $event) -{ - $return_event = array(); - $object = OC_Calendar_Object::parse($event['calendardata']); - $vevent = $object->VEVENT; - $dtstart = $vevent->DTSTART; - $dtend = OC_Calendar_Object::getDTEndFromVEvent($vevent); - $start_dt = $dtstart->getDateTime(); - $end_dt = $dtend->getDateTime(); - if ($dtstart->getDateType() == Sabre_VObject_Element_DateTime::DATE) - { - $return_event['allDay'] = true; - $return_event['start'] = $start_dt->format('Y-m-d'); - $end_dt->modify('-1 sec'); - $return_event['end'] = $end_dt->format('Y-m-d'); - }else{ - $start_dt->setTimezone(new DateTimeZone($user_timezone)); - $end_dt->setTimezone(new DateTimeZone($user_timezone)); - $return_event['start'] = $start_dt->format('Y-m-d H:i:s'); - $return_event['end'] = $end_dt->format('Y-m-d H:i:s'); - $return_event['allDay'] = false; - } +function addoutput($event, $vevent, $return_event){ $return_event['id'] = (int)$event['id']; $return_event['title'] = $event['summary']; $return_event['description'] = isset($vevent->DESCRIPTION)?$vevent->DESCRIPTION->value:''; @@ -50,6 +20,65 @@ foreach($events as $event) $lastmodified = 0; } $return_event['lastmodified'] = (int)$lastmodified; - $return[] = $return_event; + return $return_event; +} + +OC_JSON::checkLoggedIn(); +OC_JSON::checkAppEnabled('calendar'); + +$start = DateTime::createFromFormat('U', $_GET['start']); +$end = DateTime::createFromFormat('U', $_GET['end']); + +$events = OC_Calendar_Object::allInPeriod($_GET['calendar_id'], $start, $end); +$user_timezone = OC_Preferences::getValue(OC_USER::getUser(), "calendar", "timezone", "Europe/London"); +$return = array(); +foreach($events as $event){ + $object = OC_Calendar_Object::parse($event['calendardata']); + $vevent = $object->VEVENT; + $dtstart = $vevent->DTSTART; + $dtend = OC_Calendar_Object::getDTEndFromVEvent($vevent); + $return_event = array(); + $start_dt = $dtstart->getDateTime(); + $end_dt = $dtend->getDateTime(); + if ($dtstart->getDateType() == Sabre_VObject_Element_DateTime::DATE){ + $return_event['allDay'] = true; + }else{ + $return_event['allDay'] = false; + } + //Repeating Events + if($event['repeating'] == 1){ + $duration = (double) $end_dt->format('U') - (double) $start_dt->format('U'); + $r = new When(); + $r->recur((string) $dtstart)->rrule((string) $vevent->RRULE); + while($result = $r->next()){ + if($result->format('U') > $_GET['end']){ + break; + } + if($return_event['allDay'] == true){ + $return_event['start'] = $result->format('Y-m-d'); + $return_event['end'] = date('Y-m-d', $result->format('U') + $duration--); + }else{ + $return_event['start'] = $result->format('Y-m-d H:i:s'); + $return_event['end'] = date('Y-m-d H:i:s', $result->format('U') + $duration); + } + $return[] = addoutput($event, $vevent, $return_event); + } + }else{ + $return_event = array(); + if ($dtstart->getDateType() == Sabre_VObject_Element_DateTime::DATE){ + $return_event['allDay'] = true; + $return_event['start'] = $start_dt->format('Y-m-d'); + $end_dt->modify('-1 sec'); + $return_event['end'] = $end_dt->format('Y-m-d'); + }else{ + $start_dt->setTimezone(new DateTimeZone($user_timezone)); + $end_dt->setTimezone(new DateTimeZone($user_timezone)); + $return_event['start'] = $start_dt->format('Y-m-d H:i:s'); + $return_event['end'] = $end_dt->format('Y-m-d H:i:s'); + $return_event['allDay'] = false; + } + $return[] = addoutput($event, $vevent, $return_event); + } } OC_JSON::encodedPrint($return); +?> \ No newline at end of file diff --git a/apps/calendar/lib/object.php b/apps/calendar/lib/object.php index ccc62d565e..58d46ce6a7 100644 --- a/apps/calendar/lib/object.php +++ b/apps/calendar/lib/object.php @@ -43,12 +43,12 @@ class OC_Calendar_Object{ public static function allInPeriod($id, $start, $end){ $stmt = OC_DB::prepare( 'SELECT * FROM *PREFIX*calendar_objects WHERE calendarid = ?' .' AND ((startdate >= ? AND startdate <= ? AND repeating = 0)' - .' OR (startdate <= ? AND enddate >= ? AND repeating = 1))' ); + .' OR (startdate <= ? AND repeating = 1))' ); $start = self::getUTCforMDB($start); $end = self::getUTCforMDB($end); $result = $stmt->execute(array($id, $start, $end, - $end, $start)); + $end)); $calendarobjects = array(); while( $row = $result->fetchRow()){ From 89b3a395df12411328c33c1d5460f87eb1972024 Mon Sep 17 00:00:00 2001 From: Georg Ehrke Date: Sat, 12 Nov 2011 22:30:09 +0100 Subject: [PATCH 20/59] fix timezone for repeating events --- apps/calendar/ajax/events.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/calendar/ajax/events.php b/apps/calendar/ajax/events.php index f161bb88a0..9a2ba88060 100644 --- a/apps/calendar/ajax/events.php +++ b/apps/calendar/ajax/events.php @@ -39,7 +39,9 @@ foreach($events as $event){ $dtend = OC_Calendar_Object::getDTEndFromVEvent($vevent); $return_event = array(); $start_dt = $dtstart->getDateTime(); + $start_dt->setTimezone(new DateTimeZone($user_timezone)); $end_dt = $dtend->getDateTime(); + $end_dt->setTimezone(new DateTimeZone($user_timezone)); if ($dtstart->getDateType() == Sabre_VObject_Element_DateTime::DATE){ $return_event['allDay'] = true; }else{ @@ -49,7 +51,7 @@ foreach($events as $event){ if($event['repeating'] == 1){ $duration = (double) $end_dt->format('U') - (double) $start_dt->format('U'); $r = new When(); - $r->recur((string) $dtstart)->rrule((string) $vevent->RRULE); + $r->recur((string) $start_dt->format('Ymd\THis'))->rrule((string) $vevent->RRULE); while($result = $r->next()){ if($result->format('U') > $_GET['end']){ break; @@ -71,8 +73,6 @@ foreach($events as $event){ $end_dt->modify('-1 sec'); $return_event['end'] = $end_dt->format('Y-m-d'); }else{ - $start_dt->setTimezone(new DateTimeZone($user_timezone)); - $end_dt->setTimezone(new DateTimeZone($user_timezone)); $return_event['start'] = $start_dt->format('Y-m-d H:i:s'); $return_event['end'] = $end_dt->format('Y-m-d H:i:s'); $return_event['allDay'] = false; From 3d498002d040603778efbbd558a4d25c6d6734a4 Mon Sep 17 00:00:00 2001 From: Georg Ehrke Date: Mon, 14 Nov 2011 22:52:34 +0100 Subject: [PATCH 21/59] first implementation of the search function --- apps/calendar/appinfo/app.php | 2 ++ apps/calendar/lib/search.php | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 apps/calendar/lib/search.php diff --git a/apps/calendar/appinfo/app.php b/apps/calendar/appinfo/app.php index 2dc01eab0f..5675e624dd 100644 --- a/apps/calendar/appinfo/app.php +++ b/apps/calendar/appinfo/app.php @@ -21,3 +21,5 @@ OC_App::addNavigationEntry( array( 'name' => $l->t('Calendar'))); OC_App::registerPersonal('calendar', 'settings'); + +require_once('apps/calendar/lib/search.php'); \ No newline at end of file diff --git a/apps/calendar/lib/search.php b/apps/calendar/lib/search.php new file mode 100644 index 0000000000..41faf49a51 --- /dev/null +++ b/apps/calendar/lib/search.php @@ -0,0 +1,26 @@ + 0){ + $searchquery = explode(' ', $query); + }else{ + $searchquery[] = $query; + } + foreach($calendars as $calendar){ + $objects = OC_Calendar_Object::all($calendar['id']); + foreach($objects as $object){ + if(substr_count(strtolower($object['summary']), strtolower($query)) > 0){//$name,$text,$link,$type + $results[]=new OC_Search_Result($object['summary'],'','#','Cal.'); + } + } + } + return $results; + } +} +new OC_Search_Provider_Calendar(); \ No newline at end of file From 0d274b0268fc3ffa98775e5e34f35bd50c019707 Mon Sep 17 00:00:00 2001 From: Weng Xuetian Date: Mon, 24 Oct 2011 12:55:05 +0000 Subject: [PATCH 22/59] fix id3 tag resolve. should use utf8 from getID3 directly but not to convert them from ISO8859-1 to utf8 after analyze. --- apps/media/lib_scanner.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/apps/media/lib_scanner.php b/apps/media/lib_scanner.php index ef63cea45d..c2bea2d836 100644 --- a/apps/media/lib_scanner.php +++ b/apps/media/lib_scanner.php @@ -93,6 +93,7 @@ class OC_MEDIA_SCANNER{ } if(!self::$getID3){ self::$getID3=@new getID3(); + self::$getID3->encoding='UTF-8'; } $data=@self::$getID3->analyze($file); getid3_lib::CopyTagsToComments($data); @@ -105,21 +106,18 @@ class OC_MEDIA_SCANNER{ $artist='unknown'; }else{ $artist=stripslashes($data['comments']['artist'][0]); - $artist=utf8_encode($artist); } if(!isset($data['comments']['album'])){ OC_Log::write('media',"error reading album tag in '$file'",OC_Log::WARN); $album='unknown'; }else{ $album=stripslashes($data['comments']['album'][0]); - $album=utf8_encode($album); } if(!isset($data['comments']['title'])){ OC_Log::write('media',"error reading title tag in '$file'",OC_Log::WARN); $title='unknown'; }else{ $title=stripslashes($data['comments']['title'][0]); - $title=utf8_encode($title); } $size=$data['filesize']; $track=(isset($data['comments']['track']))?$data['comments']['track'][0]:0; @@ -150,4 +148,4 @@ class OC_MEDIA_SCANNER{ $ext=substr($filename,strrpos($filename,'.')+1); return $ext=='mp3' || $ext=='flac' || $ext=='m4a' || $ext=='ogg' || $ext=='oga'; } -} \ No newline at end of file +} From 96b91e5b0b54a9070eec55949d4ff13163b25d8c Mon Sep 17 00:00:00 2001 From: Weng Xuetian Date: Mon, 24 Oct 2011 16:43:18 +0000 Subject: [PATCH 23/59] fix ampache encoding problem. use htmlentities encoding parameter directly. --- apps/media/lib_ampache.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/media/lib_ampache.php b/apps/media/lib_ampache.php index 0ad84d6680..bb468d5595 100644 --- a/apps/media/lib_ampache.php +++ b/apps/media/lib_ampache.php @@ -128,7 +128,7 @@ class OC_MEDIA_AMPACHE{ $albums=count(OC_MEDIA_COLLECTION::getAlbums($artist['artist_id'])); $songs=count(OC_MEDIA_COLLECTION::getSongs($artist['artist_id'])); $id=$artist['artist_id']; - $name=utf8_decode(htmlentities($artist['artist_name'])); + $name=htmlentities($artist['artist_name'], ENT_COMPAT | ENT_HTML401, 'UTF-8'); echo("\t\n"); echo("\t\t$name\n"); echo("\t\t$albums\n"); @@ -142,10 +142,10 @@ class OC_MEDIA_AMPACHE{ if(!$artistName){ $artistName=OC_MEDIA_COLLECTION::getArtistName($album['album_artist']); } - $artistName=utf8_decode(htmlentities($artistName)); + $artistName=htmlentities($artistName, ENT_COMPAT | ENT_HTML401, 'UTF-8'); $songs=count(OC_MEDIA_COLLECTION::getSongs($album['album_artist'],$album['album_id'])); $id=$album['album_id']; - $name=utf8_decode(htmlentities($album['album_name'])); + $name=htmlentities($album['album_name'], ENT_COMPAT | ENT_HTML401, 'UTF-8'); $artist=$album['album_artist']; echo("\t\n"); echo("\t\t$name\n"); @@ -163,10 +163,10 @@ class OC_MEDIA_AMPACHE{ if(!$albumName){ $albumName=OC_MEDIA_COLLECTION::getAlbumName($song['song_album']); } - $artistName=utf8_decode(htmlentities($artistName)); - $albumName=utf8_decode(htmlentities($albumName)); + $artistName=htmlentities($artistName, ENT_COMPAT | ENT_HTML401, 'UTF-8'); + $albumName=htmlentities($albumName, ENT_COMPAT | ENT_HTML401, 'UTF-8'); $id=$song['song_id']; - $name=utf8_decode(htmlentities($song['song_name'])); + $name=htmlentities($song['song_name'], ENT_COMPAT | ENT_HTML401, 'UTF-8'); $artist=$song['song_artist']; $album=$song['song_album']; echo("\t\n"); From 28cd41a2a43ce614199e1b966c1d424efd8b23dd Mon Sep 17 00:00:00 2001 From: krzaczek Date: Tue, 4 Oct 2011 15:37:05 +0200 Subject: [PATCH 24/59] users_ldap - added getUsers() method to fetch all existing users from LDAP server --- apps/user_ldap/user_ldap.php | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/apps/user_ldap/user_ldap.php b/apps/user_ldap/user_ldap.php index 1154efc17b..4fb8daf3c4 100644 --- a/apps/user_ldap/user_ldap.php +++ b/apps/user_ldap/user_ldap.php @@ -65,7 +65,7 @@ class OC_USER_LDAP extends OC_User_Backend { $this->ds = ldap_connect( $this->ldap_host, $this->ldap_port ); if(ldap_set_option($this->ds, LDAP_OPT_PROTOCOL_VERSION, 3)) if(ldap_set_option($this->ds, LDAP_OPT_REFERRALS, 0)) - ldap_start_tls($this->ds); + @ldap_start_tls($this->ds); } // login @@ -117,7 +117,36 @@ class OC_USER_LDAP extends OC_User_Backend { $dn = $this->getDn($uid); return !empty($dn); } + + public function getUsers() + { + if(!$this->configured) + return false; + + // connect to server + $ds = $this->getDs(); + if( !$ds ) + return false; + + // get users + $filter = "objectClass=person"; + $sr = ldap_search( $this->getDs(), $this->ldap_base, $filter ); + $entries = ldap_get_entries( $this->getDs(), $sr ); + + if( $entries["count"] == 0 ) + return false; + else { + $users = array(); + foreach($entries as $row) { + if(isset($row['uid'])) { + $users[] = $row['uid'][0]; + } + } + } + + return $users; + } } -?> +?> \ No newline at end of file From a70c2b3cb9752507ea60d7b8d2bbcedad04feb14 Mon Sep 17 00:00:00 2001 From: krzaczek Date: Tue, 4 Oct 2011 15:38:15 +0200 Subject: [PATCH 25/59] apps file_sharing changed $RUNTIME_NOAPPS = true; to $RUNTIME_NOAPPS = false; in ajax/userautocomplete.php - to fetch users also from different user backends - not only database backend --- apps/files_sharing/ajax/userautocomplete.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files_sharing/ajax/userautocomplete.php b/apps/files_sharing/ajax/userautocomplete.php index 21516c3d09..9d971fb62a 100644 --- a/apps/files_sharing/ajax/userautocomplete.php +++ b/apps/files_sharing/ajax/userautocomplete.php @@ -1,5 +1,5 @@ Date: Tue, 4 Oct 2011 15:58:54 +0200 Subject: [PATCH 26/59] apps file_sharing - remove "$RUNTIME_NOAPPS = true" from all ajax file to enable other user backend --- apps/files_sharing/ajax/getitem.php | 2 +- apps/files_sharing/ajax/setpermissions.php | 2 +- apps/files_sharing/ajax/share.php | 2 +- apps/files_sharing/ajax/unshare.php | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/files_sharing/ajax/getitem.php b/apps/files_sharing/ajax/getitem.php index 075ec043ea..d9df4abe98 100644 --- a/apps/files_sharing/ajax/getitem.php +++ b/apps/files_sharing/ajax/getitem.php @@ -1,5 +1,5 @@ Date: Tue, 4 Oct 2011 16:08:14 +0200 Subject: [PATCH 27/59] apps files_sharing - fix in share.js to check the "can edit" checkbox - there was a bug in share.js so the checbox was always unchecked --- apps/files_sharing/js/share.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files_sharing/js/share.js b/apps/files_sharing/js/share.js index 4056d693bf..4457dddbe1 100644 --- a/apps/files_sharing/js/share.js +++ b/apps/files_sharing/js/share.js @@ -224,7 +224,7 @@ function addUser(uid_shared_with, permissions, parentFolder) { var user = '
  • '; user += ''; user += uid_shared_with; - user += ''; + user += ''; user += ''; user += '
  • '; } From 1c7ba0dd9eb79558fd4cd463aafa28bde1b51e85 Mon Sep 17 00:00:00 2001 From: Markus Kalkbrenner Date: Thu, 17 Nov 2011 10:31:30 +0100 Subject: [PATCH 28/59] added .buildpath --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index a84615cf13..68c48822e9 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,4 @@ nbproject # WebFinger .well-known +/.buildpath From 0155effdb75f3c1508ab96a14eb957fb434e51af Mon Sep 17 00:00:00 2001 From: Markus Kalkbrenner Date: Thu, 17 Nov 2011 11:16:56 +0100 Subject: [PATCH 29/59] - bugfix: allow anonymous bind for search, then bind with users credentials. - added explaination how to setup anonymous bind for search to template - make usage of TLS configurable --- apps/user_ldap/settings.php | 6 +++++- apps/user_ldap/templates/settings.php | 4 +++- apps/user_ldap/user_ldap.php | 14 ++++++++------ 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/apps/user_ldap/settings.php b/apps/user_ldap/settings.php index 8dbd3c0462..b922ac99f9 100644 --- a/apps/user_ldap/settings.php +++ b/apps/user_ldap/settings.php @@ -20,12 +20,16 @@ * License along with this library. If not, see . * */ -$params = array('ldap_host', 'ldap_port', 'ldap_dn', 'ldap_password', 'ldap_base', 'ldap_filter'); +$params = array('ldap_host', 'ldap_port', 'ldap_dn', 'ldap_password', 'ldap_base', 'ldap_filter', 'ldap_tls'); foreach($params as $param){ if(isset($_POST[$param])){ OC_Appconfig::setValue('user_ldap', $param, $_POST[$param]); } + elseif('ldap_tls' == $param) { + // unchecked checkboxes are not included in the post paramters + OC_Appconfig::setValue('user_ldap', $param, 0); + } } // fill template diff --git a/apps/user_ldap/templates/settings.php b/apps/user_ldap/templates/settings.php index 32e1b29daf..374f124174 100644 --- a/apps/user_ldap/templates/settings.php +++ b/apps/user_ldap/templates/settings.php @@ -4,9 +4,11 @@

    -

    + + Leave both empty for anonymous bind for search, then bind with users credentials.

    +

    >

    diff --git a/apps/user_ldap/user_ldap.php b/apps/user_ldap/user_ldap.php index 4fb8daf3c4..1100be81eb 100644 --- a/apps/user_ldap/user_ldap.php +++ b/apps/user_ldap/user_ldap.php @@ -33,6 +33,7 @@ class OC_USER_LDAP extends OC_User_Backend { protected $ldap_password; protected $ldap_base; protected $ldap_filter; + protected $ldap_tls; function __construct() { $this->ldap_host = OC_Appconfig::getValue('user_ldap', 'ldap_host',''); @@ -41,11 +42,11 @@ class OC_USER_LDAP extends OC_User_Backend { $this->ldap_password = OC_Appconfig::getValue('user_ldap', 'ldap_password',''); $this->ldap_base = OC_Appconfig::getValue('user_ldap', 'ldap_base',''); $this->ldap_filter = OC_Appconfig::getValue('user_ldap', 'ldap_filter',''); + $this->ldap_tls = OC_Appconfig::getValue('user_tls', 'ldap_tls', 0); if( !empty($this->ldap_host) && !empty($this->ldap_port) - && !empty($this->ldap_dn) - && !empty($this->ldap_password) + && ((!empty($this->ldap_dn) && !empty($this->ldap_password)) || (empty($this->ldap_dn) && empty($this->ldap_password))) && !empty($this->ldap_base) && !empty($this->ldap_filter) ) @@ -63,9 +64,10 @@ class OC_USER_LDAP extends OC_User_Backend { private function getDs() { if(!$this->ds) { $this->ds = ldap_connect( $this->ldap_host, $this->ldap_port ); - if(ldap_set_option($this->ds, LDAP_OPT_PROTOCOL_VERSION, 3)) - if(ldap_set_option($this->ds, LDAP_OPT_REFERRALS, 0)) - @ldap_start_tls($this->ds); + if(ldap_set_option($this->ds, LDAP_OPT_PROTOCOL_VERSION, 3)) + if(ldap_set_option($this->ds, LDAP_OPT_REFERRALS, 0)) + if($this->ldap_tls) + ldap_start_tls($this->ds); } // login @@ -149,4 +151,4 @@ class OC_USER_LDAP extends OC_User_Backend { } -?> \ No newline at end of file +?> From cff6a41e2b8aa78e682f4b9cc2f28e2a7efa340d Mon Sep 17 00:00:00 2001 From: Markus Kalkbrenner Date: Thu, 17 Nov 2011 15:17:01 +0100 Subject: [PATCH 30/59] fixed copy&paste error: store ldap_tls setting in user_ldap, not user_tls --- apps/user_ldap/user_ldap.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/user_ldap/user_ldap.php b/apps/user_ldap/user_ldap.php index 1100be81eb..dd831f57aa 100644 --- a/apps/user_ldap/user_ldap.php +++ b/apps/user_ldap/user_ldap.php @@ -42,7 +42,7 @@ class OC_USER_LDAP extends OC_User_Backend { $this->ldap_password = OC_Appconfig::getValue('user_ldap', 'ldap_password',''); $this->ldap_base = OC_Appconfig::getValue('user_ldap', 'ldap_base',''); $this->ldap_filter = OC_Appconfig::getValue('user_ldap', 'ldap_filter',''); - $this->ldap_tls = OC_Appconfig::getValue('user_tls', 'ldap_tls', 0); + $this->ldap_tls = OC_Appconfig::getValue('user_ldap', 'ldap_tls', 0); if( !empty($this->ldap_host) && !empty($this->ldap_port) From bf84aa23f40980bae72ced15b1830d6e4dfc49eb Mon Sep 17 00:00:00 2001 From: Markus Kalkbrenner Date: Thu, 17 Nov 2011 16:03:42 +0100 Subject: [PATCH 31/59] - provide a setting for the ldap user display name instead of hardcoded value 'uid' which is not common for Active Directory - provide a sorted list of ldap users - replaced double quotes by single quotes and spaces by tabs according to coding standards - replaced hardcoded strings in template by translatable ones --- apps/user_ldap/appinfo/app.php | 5 ++++- apps/user_ldap/settings.php | 5 ++++- apps/user_ldap/templates/settings.php | 15 ++++++++------- apps/user_ldap/user_ldap.php | 24 ++++++++++++++---------- 4 files changed, 30 insertions(+), 19 deletions(-) diff --git a/apps/user_ldap/appinfo/app.php b/apps/user_ldap/appinfo/app.php index 7906241f79..3261708f59 100644 --- a/apps/user_ldap/appinfo/app.php +++ b/apps/user_ldap/appinfo/app.php @@ -26,7 +26,10 @@ require_once('apps/user_ldap/user_ldap.php'); OC_APP::registerAdmin('user_ldap','settings'); // define LDAP_DEFAULT_PORT -define("OC_USER_BACKEND_LDAP_DEFAULT_PORT", 389); +define('OC_USER_BACKEND_LDAP_DEFAULT_PORT', 389); + +// define OC_USER_BACKEND_LDAP_DEFAULT_DISPLAY_NAME +define('OC_USER_BACKEND_LDAP_DEFAULT_DISPLAY_NAME', 'uid'); // register user backend OC_User::useBackend( "LDAP" ); diff --git a/apps/user_ldap/settings.php b/apps/user_ldap/settings.php index b922ac99f9..e61d82bf8b 100644 --- a/apps/user_ldap/settings.php +++ b/apps/user_ldap/settings.php @@ -20,7 +20,7 @@ * License along with this library. If not, see . * */ -$params = array('ldap_host', 'ldap_port', 'ldap_dn', 'ldap_password', 'ldap_base', 'ldap_filter', 'ldap_tls'); +$params = array('ldap_host', 'ldap_port', 'ldap_dn', 'ldap_password', 'ldap_base', 'ldap_filter', 'ldap_display_name', 'ldap_tls'); foreach($params as $param){ if(isset($_POST[$param])){ @@ -42,4 +42,7 @@ foreach($params as $param){ // ldap_port has a default value $tmpl->assign( 'ldap_port', OC_Appconfig::getValue('user_ldap', 'ldap_port', OC_USER_BACKEND_LDAP_DEFAULT_PORT)); +// ldap_display_name has a default value +$tmpl->assign( 'ldap_display_name', OC_Appconfig::getValue('user_ldap', 'ldap_display_name', OC_USER_BACKEND_LDAP_DEFAULT_DISPLAY_NAME)); + return $tmpl->fetchPage(); diff --git a/apps/user_ldap/templates/settings.php b/apps/user_ldap/templates/settings.php index 374f124174..8a879fa246 100644 --- a/apps/user_ldap/templates/settings.php +++ b/apps/user_ldap/templates/settings.php @@ -1,13 +1,14 @@
    LDAP -

    -

    -

    - - Leave both empty for anonymous bind for search, then bind with users credentials.

    -

    -

    +

    +

    +

    + + t('Leave both empty for anonymous bind for search, then bind with users credentials.');?>

    +

    +

    +

    >

    diff --git a/apps/user_ldap/user_ldap.php b/apps/user_ldap/user_ldap.php index dd831f57aa..8557a7fde5 100644 --- a/apps/user_ldap/user_ldap.php +++ b/apps/user_ldap/user_ldap.php @@ -34,6 +34,7 @@ class OC_USER_LDAP extends OC_User_Backend { protected $ldap_base; protected $ldap_filter; protected $ldap_tls; + protected $ldap_display_name; function __construct() { $this->ldap_host = OC_Appconfig::getValue('user_ldap', 'ldap_host',''); @@ -43,12 +44,14 @@ class OC_USER_LDAP extends OC_User_Backend { $this->ldap_base = OC_Appconfig::getValue('user_ldap', 'ldap_base',''); $this->ldap_filter = OC_Appconfig::getValue('user_ldap', 'ldap_filter',''); $this->ldap_tls = OC_Appconfig::getValue('user_ldap', 'ldap_tls', 0); + $this->ldap_display_name = OC_Appconfig::getValue('user_ldap', 'ldap_display_name', OC_USER_BACKEND_LDAP_DEFAULT_DISPLAY_NAME); if( !empty($this->ldap_host) && !empty($this->ldap_port) && ((!empty($this->ldap_dn) && !empty($this->ldap_password)) || (empty($this->ldap_dn) && empty($this->ldap_password))) && !empty($this->ldap_base) && !empty($this->ldap_filter) + && !empty($this->ldap_display_name) ) { $this->configured = true; @@ -90,15 +93,16 @@ class OC_USER_LDAP extends OC_User_Backend { return false; // get dn - $filter = str_replace("%uid", $uid, $this->ldap_filter); + $filter = str_replace('%uid', $uid, $this->ldap_filter); $sr = ldap_search( $this->getDs(), $this->ldap_base, $filter ); $entries = ldap_get_entries( $this->getDs(), $sr ); - if( $entries["count"] == 0 ) + if( $entries['count'] == 0 ) return false; - return $entries[0]["dn"]; + return $entries[0]['dn']; } + public function checkPassword( $uid, $password ) { if(!$this->configured){ return false; @@ -131,22 +135,22 @@ class OC_USER_LDAP extends OC_User_Backend { return false; // get users - $filter = "objectClass=person"; + $filter = 'objectClass=person'; $sr = ldap_search( $this->getDs(), $this->ldap_base, $filter ); $entries = ldap_get_entries( $this->getDs(), $sr ); - - if( $entries["count"] == 0 ) + if( $entries['count'] == 0 ) return false; else { $users = array(); foreach($entries as $row) { - if(isset($row['uid'])) { - $users[] = $row['uid'][0]; + if(isset($row[$this->ldap_display_name])) { + $users[] = $row[$this->ldap_display_name][0]; } } + // TODO language specific sorting of user names + sort($users); + return $users; } - - return $users; } } From 48ae18a7333a14072bee02cbb31a1753181bc229 Mon Sep 17 00:00:00 2001 From: Markus Kalkbrenner Date: Thu, 17 Nov 2011 17:14:10 +0100 Subject: [PATCH 32/59] - fixed translateable strings in template - added explaination about ldap filter and display name - bugfix: keys in ldap response are lower case => lower display name filed before searching --- apps/user_ldap/templates/settings.php | 7 ++++--- apps/user_ldap/user_ldap.php | 6 ++++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/apps/user_ldap/templates/settings.php b/apps/user_ldap/templates/settings.php index 8a879fa246..5f25570e22 100644 --- a/apps/user_ldap/templates/settings.php +++ b/apps/user_ldap/templates/settings.php @@ -5,10 +5,11 @@

    - t('Leave both empty for anonymous bind for search, then bind with users credentials.');?>

    + t('Leave both empty for anonymous bind for search, then bind with users credentials.');?>

    -

    -

    +

    +

    + t('Currently the display name field needs to be the same you matched %%uid against in the filter above, because ownCloud doesn\'t distinguish between user id and user name.');?>

    >

    diff --git a/apps/user_ldap/user_ldap.php b/apps/user_ldap/user_ldap.php index 8557a7fde5..249def7a1c 100644 --- a/apps/user_ldap/user_ldap.php +++ b/apps/user_ldap/user_ldap.php @@ -143,8 +143,10 @@ class OC_USER_LDAP extends OC_User_Backend { else { $users = array(); foreach($entries as $row) { - if(isset($row[$this->ldap_display_name])) { - $users[] = $row[$this->ldap_display_name][0]; + // TODO ldap_get_entries() seems to lower all keys => needs review + $ldap_display_name = strtolower($this->ldap_display_name); + if(isset($row[$ldap_display_name])) { + $users[] = $row[$ldap_display_name][0]; } } // TODO language specific sorting of user names From 4bebf419d1e06929b86fbb33e146d4e7ef7766fb Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 18 Nov 2011 20:19:55 +0100 Subject: [PATCH 33/59] use oc_appconfig instead of oc_config for the external apps --- apps/external/ajax/seturls.php | 20 ++++++++++---------- apps/external/appinfo/app.php | 10 +++++----- apps/external/index.php | 2 +- apps/external/settings.php | 20 ++++++++++---------- 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/apps/external/ajax/seturls.php b/apps/external/ajax/seturls.php index c8e9775454..e994385a19 100644 --- a/apps/external/ajax/seturls.php +++ b/apps/external/ajax/seturls.php @@ -8,16 +8,16 @@ require_once('../../../lib/base.php'); OC_Util::checkAdminUser(); -if(isset($_POST['s1name'])) OC_Config::setValue( 'external-site1name', $_POST['s1name'] ); -if(isset($_POST['s1url'])) OC_Config::setValue( 'external-site1url', $_POST['s1url'] ); -if(isset($_POST['s2name'])) OC_Config::setValue( 'external-site2name', $_POST['s2name'] ); -if(isset($_POST['s2url'])) OC_Config::setValue( 'external-site2url', $_POST['s2url'] ); -if(isset($_POST['s3name'])) OC_Config::setValue( 'external-site3name', $_POST['s3name'] ); -if(isset($_POST['s3url'])) OC_Config::setValue( 'external-site3url', $_POST['s3url'] ); -if(isset($_POST['s4name'])) OC_Config::setValue( 'external-site4name', $_POST['s4name'] ); -if(isset($_POST['s4url'])) OC_Config::setValue( 'external-site4url', $_POST['s4url'] ); -if(isset($_POST['s5name'])) OC_Config::setValue( 'external-site5name', $_POST['s5name'] ); -if(isset($_POST['s5url'])) OC_Config::setValue( 'external-site5url', $_POST['s5url'] ); +if(isset($_POST['s1name'])) OC_Appconfig::setValue( 'external','site1name', $_POST['s1name'] ); +if(isset($_POST['s1url'])) OC_Appconfig::setValue( 'external','site1url', $_POST['s1url'] ); +if(isset($_POST['s2name'])) OC_Appconfig::setValue( 'external','site2name', $_POST['s2name'] ); +if(isset($_POST['s2url'])) OC_Appconfig::setValue( 'external','site2url', $_POST['s2url'] ); +if(isset($_POST['s3name'])) OC_Appconfig::setValue( 'external','site3name', $_POST['s3name'] ); +if(isset($_POST['s3url'])) OC_Appconfig::setValue( 'external','site3url', $_POST['s3url'] ); +if(isset($_POST['s4name'])) OC_Appconfig::setValue( 'external','site4name', $_POST['s4name'] ); +if(isset($_POST['s4url'])) OC_Appconfig::setValue( 'external','site4url', $_POST['s4url'] ); +if(isset($_POST['s5name'])) OC_Appconfig::setValue( 'external','site5name', $_POST['s5name'] ); +if(isset($_POST['s5url'])) OC_Appconfig::setValue( 'external','site5url', $_POST['s5url'] ); echo 'true'; diff --git a/apps/external/appinfo/app.php b/apps/external/appinfo/app.php index df14954d86..0f536cbf41 100644 --- a/apps/external/appinfo/app.php +++ b/apps/external/appinfo/app.php @@ -25,13 +25,13 @@ OC_APP::registerAdmin('external','settings'); OC_App::register( array( 'order' => 70, 'id' => 'external', 'name' => 'External' )); -if(OC_Config::getValue( "external-site1name", '' )<>'') OC_App::addNavigationEntry( array( 'id' => 'external_index1', 'order' => 80, 'href' => OC_Helper::linkTo( 'external', 'index.php' ).'?id=1', 'icon' => OC_Helper::imagePath( 'external', 'external.png' ), 'name' => OC_Config::getValue( "external-site1name", '' ))); +if(OC_Appconfig::getValue( "external","site1name", '' )<>'') OC_App::addNavigationEntry( array( 'id' => 'external_index1', 'order' => 80, 'href' => OC_Helper::linkTo( 'external', 'index.php' ).'?id=1', 'icon' => OC_Helper::imagePath( 'external', 'external.png' ), 'name' => OC_Appconfig::getValue( "external","site1name", '' ))); -if(OC_Config::getValue( "external-site2name", '' )<>'') OC_App::addNavigationEntry( array( 'id' => 'external_index2', 'order' => 80, 'href' => OC_Helper::linkTo( 'external', 'index.php' ).'?id=2', 'icon' => OC_Helper::imagePath( 'external', 'external.png' ), 'name' => OC_Config::getValue( "external-site2name", '' ))); +if(OC_Appconfig::getValue( "external","site2name", '' )<>'') OC_App::addNavigationEntry( array( 'id' => 'external_index2', 'order' => 80, 'href' => OC_Helper::linkTo( 'external', 'index.php' ).'?id=2', 'icon' => OC_Helper::imagePath( 'external', 'external.png' ), 'name' => OC_Appconfig::getValue( "external","site2name", '' ))); -if(OC_Config::getValue( "external-site3name", '' )<>'') OC_App::addNavigationEntry( array( 'id' => 'external_index3', 'order' => 80, 'href' => OC_Helper::linkTo( 'external', 'index.php' ).'?id=3', 'icon' => OC_Helper::imagePath( 'external', 'external.png' ), 'name' => OC_Config::getValue( "external-site3name", '' ))); +if(OC_Appconfig::getValue( "external","site3name", '' )<>'') OC_App::addNavigationEntry( array( 'id' => 'external_index3', 'order' => 80, 'href' => OC_Helper::linkTo( 'external', 'index.php' ).'?id=3', 'icon' => OC_Helper::imagePath( 'external', 'external.png' ), 'name' => OC_Appconfig::getValue( "external","site3name", '' ))); -if(OC_Config::getValue( "external-site4name", '' )<>'') OC_App::addNavigationEntry( array( 'id' => 'external_index4', 'order' => 80, 'href' => OC_Helper::linkTo( 'external', 'index.php' ).'?id=4', 'icon' => OC_Helper::imagePath( 'external', 'external.png' ), 'name' => OC_Config::getValue( "external-site4name", '' ))); +if(OC_Appconfig::getValue( "external","site4name", '' )<>'') OC_App::addNavigationEntry( array( 'id' => 'external_index4', 'order' => 80, 'href' => OC_Helper::linkTo( 'external', 'index.php' ).'?id=4', 'icon' => OC_Helper::imagePath( 'external', 'external.png' ), 'name' => OC_Appconfig::getValue( "external","site4name", '' ))); -if(OC_Config::getValue( "external-site5name", '' )<>'') OC_App::addNavigationEntry( array( 'id' => 'external_index5', 'order' => 80, 'href' => OC_Helper::linkTo( 'external', 'index.php' ).'?id=5', 'icon' => OC_Helper::imagePath( 'external', 'external.png' ), 'name' => OC_Config::getValue( "external-site5name", '' ))); +if(OC_Appconfig::getValue( "external","site5name", '' )<>'') OC_App::addNavigationEntry( array( 'id' => 'external_index5', 'order' => 80, 'href' => OC_Helper::linkTo( 'external', 'index.php' ).'?id=5', 'icon' => OC_Helper::imagePath( 'external', 'external.png' ), 'name' => OC_Appconfig::getValue( "external","site5name", '' ))); diff --git a/apps/external/index.php b/apps/external/index.php index 116e16d909..86b19abc10 100644 --- a/apps/external/index.php +++ b/apps/external/index.php @@ -35,7 +35,7 @@ if(isset($_GET['id'])){ $id=$_GET['id']; $id = (int) $id; - $url=OC_Config::getValue( "external-site".$id."url", '' ); + $url=OC_Appconfig::getValue( "external","site".$id."url", '' ); OC_App::setActiveNavigationEntry( 'external_index'.$id ); $tmpl = new OC_Template( 'external', 'frame', 'user' ); diff --git a/apps/external/settings.php b/apps/external/settings.php index ad33c16e1b..3e0c342512 100644 --- a/apps/external/settings.php +++ b/apps/external/settings.php @@ -6,17 +6,17 @@ OC_Util::addScript( "external", "admin" ); $tmpl = new OC_Template( 'external', 'settings'); - $tmpl->assign('s1name',OC_Config::getValue( "external-site1name", '' )); - $tmpl->assign('s2name',OC_Config::getValue( "external-site2name", '' )); - $tmpl->assign('s3name',OC_Config::getValue( "external-site3name", '' )); - $tmpl->assign('s4name',OC_Config::getValue( "external-site4name", '' )); - $tmpl->assign('s5name',OC_Config::getValue( "external-site5name", '' )); + $tmpl->assign('s1name',OC_Appconfig::getValue( "external","site1name", '' )); + $tmpl->assign('s2name',OC_Appconfig::getValue( "external","site2name", '' )); + $tmpl->assign('s3name',OC_Appconfig::getValue( "external","site3name", '' )); + $tmpl->assign('s4name',OC_Appconfig::getValue( "external","site4name", '' )); + $tmpl->assign('s5name',OC_Appconfig::getValue( "external","site5name", '' )); - $tmpl->assign('s1url',OC_Config::getValue( "external-site1url", '' )); - $tmpl->assign('s2url',OC_Config::getValue( "external-site2url", '' )); - $tmpl->assign('s3url',OC_Config::getValue( "external-site3url", '' )); - $tmpl->assign('s4url',OC_Config::getValue( "external-site4url", '' )); - $tmpl->assign('s5url',OC_Config::getValue( "external-site5url", '' )); + $tmpl->assign('s1url',OC_Appconfig::getValue( "external","site1url", '' )); + $tmpl->assign('s2url',OC_Appconfig::getValue( "external","site2url", '' )); + $tmpl->assign('s3url',OC_Appconfig::getValue( "external","site3url", '' )); + $tmpl->assign('s4url',OC_Appconfig::getValue( "external","site4url", '' )); + $tmpl->assign('s5url',OC_Appconfig::getValue( "external","site5url", '' )); return $tmpl->fetchPage(); ?> From 949bd2c47a47196f767aa8a6a8e70ae0b834ad90 Mon Sep 17 00:00:00 2001 From: Frank Karlitschek Date: Sat, 19 Nov 2011 11:56:40 +0100 Subject: [PATCH 34/59] first small step to an automatic updating system. At the moment we only have a hint that a new version is avaiable and a link to a not yet existing page if updating information. This has to be improved. --- lib/updater.php | 91 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 lib/updater.php diff --git a/lib/updater.php b/lib/updater.php new file mode 100644 index 0000000000..e4db719a62 --- /dev/null +++ b/lib/updater.php @@ -0,0 +1,91 @@ +. + * + */ + +/** + * Class that handels autoupdating of ownCloud + */ +class OC_Updater{ + + /** + * Check if a new version is available + */ + public static function check(){ + OC_Config::setValue('lastupdatedat',microtime(true)); + + $updaterurl='http://apps.owncloud.com/updater.php'; + $version=OC_Util::getVersion(); + $version['installed']=OC_Config::getValue( "installedat"); + $version['updated']=OC_Config::getValue( "lastupdatedat"); + $version['updatechannel']='stable'; + $versionstring=implode('x',$version); + + //fetch xml data from updater + $url=$updaterurl.'?version='.$versionstring; + $xml=@file_get_contents($url); + if($xml==FALSE){ + return array(); + } + $data=@simplexml_load_string($xml); + + $tmp=array(); + $tmp['version'] = $data->version; + $tmp['versionstring'] = $data->versionstring; + $tmp['url'] = $data->url; + $tmp['web'] = $data->web; + + + return $tmp; + + } + + + + public static function ShowUpdatingHint(){ + $data=OC_Updater::check(); + if(isset($data['version']) and $data['version']<>'') { + $txt=''.$data['versionstring'].' is available. Please click here for more information'; + }else{ + $txt='Your ownCloud is up to date'; + } + return($txt); + + } + + + /** + * do ownCloud update + */ + public static function doUpdate(){ + + //update ownCloud core + + //update all apps + + //update version in config + + } + +} + + + +?> From 7df9d934caecfdbc6e316d79e37d37ebd52bdda6 Mon Sep 17 00:00:00 2001 From: Frank Karlitschek Date: Sat, 19 Nov 2011 12:02:34 +0100 Subject: [PATCH 35/59] second half of the updating stuff --- lib/config.php | 1 - lib/setup.php | 2 ++ settings/templates/personal.php | 4 +++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/config.php b/lib/config.php index 2c82036257..8d03271b3e 100644 --- a/lib/config.php +++ b/lib/config.php @@ -94,7 +94,6 @@ class OC_Config{ // Write changes self::writeData(); - return true; } diff --git a/lib/setup.php b/lib/setup.php index e2d56ddaf4..8afe0070e9 100644 --- a/lib/setup.php +++ b/lib/setup.php @@ -77,6 +77,8 @@ class OC_Setup { OC_Config::setValue('datadirectory', $datadir); OC_Config::setValue('dbtype', $dbtype); OC_Config::setValue('version',implode('.',OC_Util::getVersion())); + OC_Config::setValue('installedat',microtime(true)); + OC_Config::setValue('lastupdatedat',microtime(true)); if($dbtype == 'mysql') { $dbuser = $options['dbuser']; $dbpass = $options['dbpass']; diff --git a/settings/templates/personal.php b/settings/templates/personal.php index 54487165f3..8c5de5ccf2 100644 --- a/settings/templates/personal.php +++ b/settings/templates/personal.php @@ -50,7 +50,9 @@ };?>

    - ownCloud , source code licensed freely under AGPL + ownCloud
    +
    + source code licensed freely under AGPL

    From a38778f9115d3c6463e74bdf27d003e01e7dc88c Mon Sep 17 00:00:00 2001 From: Georg Ehrke Date: Sun, 20 Nov 2011 14:23:26 +0100 Subject: [PATCH 36/59] fix timeformat setting for fullcalendar --- apps/calendar/js/calendar.js | 10 +++++----- apps/calendar/templates/calendar.php | 2 ++ 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/apps/calendar/js/calendar.js b/apps/calendar/js/calendar.js index af5ecd8281..5592e418a4 100644 --- a/apps/calendar/js/calendar.js +++ b/apps/calendar/js/calendar.js @@ -138,9 +138,9 @@ Calendar={ }, getEventPopupText:function(event){ if (event.allDay){ - var timespan = $.fullCalendar.formatDates(event.start, event.end, t('calendar', "ddd d MMMM[ yyyy]{ -[ddd d] MMMM yyyy}")); + var timespan = $.fullCalendar.formatDates(event.start, event.end, 'ddd d MMMM[ yyyy]{ -[ddd d] MMMM yyyy}', {monthNamesShort: monthNamesShort, monthNames: monthNames, dayNames: dayNames, dayNamesShort: dayNamesShort}); //t('calendar', "ddd d MMMM[ yyyy]{ -[ddd d] MMMM yyyy}") }else{ - var timespan = $.fullCalendar.formatDates(event.start, event.end, t('calendar', "ddd d MMMM[ yyyy] HH:mm{ -[ ddd d MMMM yyyy] HH:mm}")); + var timespan = $.fullCalendar.formatDates(event.start, event.end, 'ddd d MMMM[ yyyy] ' + defaulttime + '{ -[ ddd d MMMM yyyy]' + defaulttime + '}', {monthNamesShort: monthNamesShort, monthNames: monthNames, dayNames: dayNames, dayNamesShort: dayNamesShort}); //t('calendar', "ddd d MMMM[ yyyy] HH:mm{ -[ ddd d MMMM yyyy] HH:mm}") // Tue 18 October 2011 08:00 - 16:00 } var html = @@ -482,13 +482,13 @@ $(document).ready(function(){ editable: true, defaultView: defaultView, timeFormat: { - agenda: 'HH:mm{ - HH:mm}', - '': 'HH:mm' + agenda: agendatime, + '': defaulttime }, titleFormat: { list: 'yyyy/MMM/d dddd' }, - axisFormat: 'HH:mm', + axisFormat: defaulttime, monthNames: monthNames, monthNamesShort: monthNamesShort, dayNames: dayNames, diff --git a/apps/calendar/templates/calendar.php b/apps/calendar/templates/calendar.php index 76c0249e26..2003b7efc4 100755 --- a/apps/calendar/templates/calendar.php +++ b/apps/calendar/templates/calendar.php @@ -5,6 +5,8 @@ var dayNamesShort = tA(array('Sun.', 'Mon.', 'Tue.', 'Wed.', 'Thu.', 'Fri.', 'Sat.'))) ?>; var monthNames = tA(array('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'))) ?>; var monthNamesShort = tA(array('Jan.', 'Feb.', 'Mar.', 'Apr.', 'May.', 'Jun.', 'Jul.', 'Aug.', 'Sep.', 'Oct.', 'Nov.', 'Dec.'))) ?>; + var agendatime = '{ - }'; + var defaulttime = ''; var allDayText = 't('All day') ?>'; var missing_field = 't('Missing fields') ?>'; var missing_field_title = 't('Title') ?>'; From ad390d5e42eaa9d56c79f7d81d057ef88eda9117 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Thu, 17 Nov 2011 23:54:14 +0100 Subject: [PATCH 37/59] Add type selects to editing ADR & TEL contact property types --- apps/contacts/ajax/addcard.php | 5 +++++ apps/contacts/ajax/setproperty.php | 5 +++++ apps/contacts/ajax/showsetproperty.php | 2 ++ apps/contacts/index.php | 6 +++++ apps/contacts/templates/part.property.php | 22 +++++++++++++++++-- .../templates/part.setpropertyform.php | 5 ++++- 6 files changed, 42 insertions(+), 3 deletions(-) diff --git a/apps/contacts/ajax/addcard.php b/apps/contacts/ajax/addcard.php index 0cecd3bdc0..dd5b90651f 100644 --- a/apps/contacts/ajax/addcard.php +++ b/apps/contacts/ajax/addcard.php @@ -68,11 +68,16 @@ foreach( $add as $propname){ } $id = OC_Contacts_VCard::add($aid,$vcard->serialize()); +$adr_types = OC_Contacts_VCard::getTypesOfProperty($l10n, 'ADR'); +$phone_types = OC_Contacts_VCard::getTypesOfProperty($l10n, 'TEL'); + $details = OC_Contacts_VCard::structureContact($vcard); $name = $details['FN'][0]['value']; $tmpl = new OC_Template('contacts','part.details'); $tmpl->assign('details',$details); $tmpl->assign('id',$id); +$tmpl->assign('adr_types',$adr_types); +$tmpl->assign('phone_types',$phone_types); $page = $tmpl->fetchPage(); OC_JSON::success(array('data' => array( 'id' => $id, 'name' => $name, 'page' => $page ))); diff --git a/apps/contacts/ajax/setproperty.php b/apps/contacts/ajax/setproperty.php index 18e0087247..9164f86913 100644 --- a/apps/contacts/ajax/setproperty.php +++ b/apps/contacts/ajax/setproperty.php @@ -94,7 +94,12 @@ $checksum = md5($vcard->children[$line]->serialize()); OC_Contacts_VCard::edit($id,$vcard->serialize()); +$adr_types = OC_Contacts_VCard::getTypesOfProperty($l10n, 'ADR'); +$phone_types = OC_Contacts_VCard::getTypesOfProperty($l10n, 'TEL'); + $tmpl = new OC_Template('contacts','part.property'); +$tmpl->assign('adr_types',$adr_types); +$tmpl->assign('phone_types',$phone_types); $tmpl->assign('property',OC_Contacts_VCard::structureProperty($vcard->children[$line],$line)); $page = $tmpl->fetchPage(); diff --git a/apps/contacts/ajax/showsetproperty.php b/apps/contacts/ajax/showsetproperty.php index 4ec3dd7d8e..2ec4b89b82 100644 --- a/apps/contacts/ajax/showsetproperty.php +++ b/apps/contacts/ajax/showsetproperty.php @@ -62,12 +62,14 @@ if(is_null($line)){ } $adr_types = OC_Contacts_VCard::getTypesOfProperty($l10n, 'ADR'); +$phone_types = OC_Contacts_VCard::getTypesOfProperty($l10n, 'TEL'); $tmpl = new OC_Template('contacts','part.setpropertyform'); $tmpl->assign('id',$id); $tmpl->assign('checksum',$checksum); $tmpl->assign('property',OC_Contacts_VCard::structureProperty($vcard->children[$line])); $tmpl->assign('adr_types',$adr_types); +$tmpl->assign('phone_types',$phone_types); $page = $tmpl->fetchPage(); OC_JSON::success(array('data' => array( 'page' => $page ))); diff --git a/apps/contacts/index.php b/apps/contacts/index.php index 7e93d6183e..29d41d3c4c 100644 --- a/apps/contacts/index.php +++ b/apps/contacts/index.php @@ -75,8 +75,14 @@ if( !is_null($id) || count($contacts)){ $details = OC_Contacts_VCard::structureContact($vcard); } +$l10n = new OC_L10N('contacts'); +$adr_types = OC_Contacts_VCard::getTypesOfProperty($l10n, 'ADR'); +$phone_types = OC_Contacts_VCard::getTypesOfProperty($l10n, 'TEL'); + // Process the template $tmpl = new OC_Template( 'contacts', 'index', 'user' ); +$tmpl->assign('adr_types',$adr_types); +$tmpl->assign('phone_types',$phone_types); $tmpl->assign('addressbooks', $addressbooks); $tmpl->assign('contacts', $contacts); $tmpl->assign('details', $details ); diff --git a/apps/contacts/templates/part.property.php b/apps/contacts/templates/part.property.php index 4bc3a4d85f..dbd125dc95 100644 --- a/apps/contacts/templates/part.property.php +++ b/apps/contacts/templates/part.property.php @@ -24,7 +24,16 @@

    - (t(ucwords(str_replace('cell','mobile',strtolower($_['property']['parameters']['TYPE'])))); ?>) +t(ucwords(strtolower($type))); + } +?> + () @@ -34,7 +43,16 @@ t('Address'); ?>
    - (t(ucwords($_['property']['parameters']['TYPE'])); ?>) +t(ucwords(strtolower($type))); + } +?> + ()

    diff --git a/apps/contacts/templates/part.setpropertyform.php b/apps/contacts/templates/part.setpropertyform.php index 811b9626ce..9340ce7c71 100644 --- a/apps/contacts/templates/part.setpropertyform.php +++ b/apps/contacts/templates/part.setpropertyform.php @@ -42,7 +42,10 @@

    -

    +

    +

    From a2ecdfcac102395ce3d9da41b4074fd7e4cc927e Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Wed, 23 Nov 2011 21:06:51 +0100 Subject: [PATCH 38/59] Contacts: support multiple phone type parameter --- apps/contacts/ajax/setproperty.php | 12 ++++++++++- apps/contacts/css/formtastic.css | 8 +++----- apps/contacts/css/styles.css | 11 +++++++--- apps/contacts/js/interface.js | 12 +++++++---- apps/contacts/lib/vcard.php | 20 +++++++++++++++++-- apps/contacts/templates/part.addcardform.php | 2 +- apps/contacts/templates/part.property.php | 19 ++++++++++-------- .../templates/part.setpropertyform.php | 6 +++--- 8 files changed, 63 insertions(+), 27 deletions(-) diff --git a/apps/contacts/ajax/setproperty.php b/apps/contacts/ajax/setproperty.php index 9164f86913..c9102c4a2e 100644 --- a/apps/contacts/ajax/setproperty.php +++ b/apps/contacts/ajax/setproperty.php @@ -70,6 +70,9 @@ $vcard->children[$line]->setValue($value); // Add parameters $postparameters = isset($_POST['parameters'])?$_POST['parameters']:array(); +if ($vcard->children[$line]->name == 'TEL' && !array_key_exists('TYPE', $postparameters)){ + $postparameters['TYPE']=''; +} for($i=0;$ichildren[$line]->parameters);$i++){ $name = $vcard->children[$line]->parameters[$i]->name; if(array_key_exists($name,$postparameters)){ @@ -77,7 +80,14 @@ for($i=0;$ichildren[$line]->parameters);$i++){ unset($vcard->children[$line]->parameters[$i]); } else{ - $vcard->children[$line]->parameters[$i]->value = $postparameters[$name]; + unset($vcard->children[$line][$name]); + $values = $postparameters[$name]; + if (!is_array($values)){ + $values = array($values); + } + foreach($values as $value){ + $vcard->children[$line]->add($name, $value); + } } unset($postparameters[$name]); } diff --git a/apps/contacts/css/formtastic.css b/apps/contacts/css/formtastic.css index 629c220732..fede92b61c 100644 --- a/apps/contacts/css/formtastic.css +++ b/apps/contacts/css/formtastic.css @@ -94,16 +94,14 @@ This stylesheet forms part of the Formtastic Rails Plugin /* INPUTS --------------------------------------------------------------------------------------------------*/ .formtastic .inputs { - overflow:hidden; /* clear containing floats */ -} - -.formtastic .input { - overflow:hidden; /* clear containing floats */ padding:0.5em 0; /* padding and negative margin juggling is for Firefox */ margin-top:-0.5em; margin-bottom:1em; } +.formtastic .input { +} + /* LEFT ALIGNED LABELS --------------------------------------------------------------------------------------------------*/ diff --git a/apps/contacts/css/styles.css b/apps/contacts/css/styles.css index ad64c777ee..e226c48ae5 100644 --- a/apps/contacts/css/styles.css +++ b/apps/contacts/css/styles.css @@ -3,16 +3,21 @@ #contacts_deletecard {position:absolute;top:15px;right:0;} #contacts_details_list { list-style:none; } -#contacts_details_list li { overflow:hidden; } #contacts_details_list li p.contacts_property_name { width:25%; float:left;text-align:right;padding-right:0.3em;color:#666; } -#contacts_details_list li p.contacts_property_data, #contacts_details_list li ul.contacts_property_data { width:72%; overflow:hidden; } +#contacts_details_list li p.contacts_property_data, #contacts_details_list li ul.contacts_property_data { width:72%;float:left; } #contacts_addproperty_button, #contacts_setproperty_button { margin-left:25%; } -.contacts_property_data ul, .contacts_property_data ol { list-style:none; } +.contacts_property_data ul, ol.contacts_property_data { list-style:none; } .contacts_property_data li { overflow: hidden; } .contacts_property_data li label { width:20%; float:left; text-align:right;padding-right:0.3em; } +.contacts_property_data input { float:left; } .contacts_property_data li input { width:70%;overflow:hidden; } +.chzn-container { margin:3px 0 0; } +.chzn-container .chzn-choices { border-radius: 0.5em; } +.chzn-container.chzn-container-active .chzn-choices { border-bottom-left-radius: 0;border-bottom-right-radius: 0; } +.chzn-container .chzn-drop { border-bottom-left-radius: 0.5em;border-bottom-right-radius: 0.5em; } + /* Form setup ----------------------------------------------------------------*/ /* .forme {} */ /* .forme ul, .forme ol { list-style:none; } */ diff --git a/apps/contacts/js/interface.js b/apps/contacts/js/interface.js index 1cc3a5dfd6..24b512e532 100644 --- a/apps/contacts/js/interface.js +++ b/apps/contacts/js/interface.js @@ -82,7 +82,8 @@ $(document).ready(function(){ $.getJSON('ajax/showaddcard.php',{},function(jsondata){ if(jsondata.status == 'success'){ $('#rightcontent').data('id',''); - $('#rightcontent').html(jsondata.data.page); + $('#rightcontent').html(jsondata.data.page) + .find('select').chosen(); } else{ alert(jsondata.data.message); @@ -111,7 +112,8 @@ $(document).ready(function(){ var checksum = $(this).parents('li').first().data('checksum'); $.getJSON('ajax/showsetproperty.php',{'id': id, 'checksum': checksum },function(jsondata){ if(jsondata.status == 'success'){ - $('.contacts_property[data-checksum="'+checksum+'"]').html(jsondata.data.page); + $('.contacts_property[data-checksum="'+checksum+'"]').html(jsondata.data.page) + .find('select').chosen(); } else{ alert(jsondata.data.message); @@ -148,10 +150,12 @@ $(document).ready(function(){ $('.contacts_property').live('mouseenter',function(){ - $(this).find('span').show(); + $(this).find('span[data-use]').show(); }); $('.contacts_property').live('mouseleave',function(){ - $(this).find('span').hide(); + $(this).find('span[data-use]').hide(); }); + + $('#contacts_addcardform select').chosen(); }); diff --git a/apps/contacts/lib/vcard.php b/apps/contacts/lib/vcard.php index 56602f25c0..4865fae764 100644 --- a/apps/contacts/lib/vcard.php +++ b/apps/contacts/lib/vcard.php @@ -296,7 +296,13 @@ class OC_Contacts_VCard{ $property = new Sabre_VObject_Property( $name, $value ); $parameternames = array_keys($parameters); foreach($parameternames as $i){ - $property->parameters[] = new Sabre_VObject_Parameter($i,$parameters[$i]); + $values = $parameters[$i]; + if (!is_array($values)){ + $values = array($values); + } + foreach($values as $value){ + $property->add($i, $value); + } } $vcard->add($property); @@ -352,7 +358,17 @@ class OC_Contacts_VCard{ $parameter->name = 'PREF'; $parameter->value = '1'; } - $temp['parameters'][$parameter->name] = $parameter->value; + if ($property->name == 'TEL' && $parameter->name == 'TYPE'){ + if (isset($temp['parameters'][$parameter->name])){ + $temp['parameters'][$parameter->name][] = $parameter->value; + } + else{ + $temp['parameters'][$parameter->name] = array($parameter->value); + } + } + else{ + $temp['parameters'][$parameter->name] = $parameter->value; + } } return $temp; } diff --git a/apps/contacts/templates/part.addcardform.php b/apps/contacts/templates/part.addcardform.php index 037e3629bb..627053547a 100644 --- a/apps/contacts/templates/part.addcardform.php +++ b/apps/contacts/templates/part.addcardform.php @@ -43,7 +43,7 @@
  • -
  • diff --git a/apps/contacts/templates/part.property.php b/apps/contacts/templates/part.property.php index dbd125dc95..afef431126 100644 --- a/apps/contacts/templates/part.property.php +++ b/apps/contacts/templates/part.property.php @@ -23,15 +23,18 @@

    t('Phone'); ?>

    - + t(ucwords(strtolower($type))); - } + $types = array(); + foreach($_['property']['parameters']['TYPE'] as $type): + if (isset($_['phone_types'][strtoupper($type)])){ + $types[]=$_['phone_types'][strtoupper($type)]; + } + else{ + $types[]=$l->t(ucwords(strtolower($type))); + } + endforeach; + $label = join(' ', $types); ?> () diff --git a/apps/contacts/templates/part.setpropertyform.php b/apps/contacts/templates/part.setpropertyform.php index 9340ce7c71..bd18d86b47 100644 --- a/apps/contacts/templates/part.setpropertyform.php +++ b/apps/contacts/templates/part.setpropertyform.php @@ -42,9 +42,9 @@

    -

    - +

    From 5e037bfd5458436e8f6d83d4fe53f62b53cd8ae9 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Wed, 23 Nov 2011 21:07:26 +0100 Subject: [PATCH 39/59] Contacts: remove redundant li in setpropertyform template --- apps/contacts/templates/part.setpropertyform.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/contacts/templates/part.setpropertyform.php b/apps/contacts/templates/part.setpropertyform.php index bd18d86b47..b0bf6645d5 100644 --- a/apps/contacts/templates/part.setpropertyform.php +++ b/apps/contacts/templates/part.setpropertyform.php @@ -1,4 +1,3 @@ -
  • @@ -55,4 +54,3 @@
  • - From ee549dfb3802e98156e96a4cf549854b9d4f791a Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Thu, 17 Nov 2011 23:53:06 +0100 Subject: [PATCH 40/59] Fix scrolling through months --- apps/calendar/js/calendar.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/calendar/js/calendar.js b/apps/calendar/js/calendar.js index 5592e418a4..005e359f8e 100644 --- a/apps/calendar/js/calendar.js +++ b/apps/calendar/js/calendar.js @@ -198,8 +198,12 @@ Calendar={ win_height = $(window).height(); if(direction == 'down' && win_height == (doc_height - scroll)){ $('#calendar_holder').fullCalendar('next'); + $(document).scrollTop(0); + event.preventDefault(); }else if (direction == 'top' && scroll == 0) { $('#calendar_holder').fullCalendar('prev'); + $(document).scrollTop(win_height); + event.preventDefault(); } }, Calendar:{ From 2dd757156c5da230a767152276acd31bcc2a5241 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Wed, 23 Nov 2011 21:31:27 +0100 Subject: [PATCH 41/59] Fix file dropping on root (Files menu entry) --- files/js/files.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/files/js/files.js b/files/js/files.js index 4eaa098241..53437453ff 100644 --- a/files/js/files.js +++ b/files/js/files.js @@ -14,8 +14,8 @@ $(document).ready(function() { $('#fileList tr td.filename').draggable(dragOptions); $('#fileList tr[data-type="dir"] td.filename').droppable(folderDropOptions); $('div.crumb').droppable(crumbDropOptions); - $('#plugins>ul>li:first-child').data('dir',''); - $('#plugins>ul>li:first-child').droppable(crumbDropOptions); + $('ul#apps>li:first-child').data('dir',''); + $('ul#apps>li:first-child').droppable(crumbDropOptions); // Triggers invisible file input $('.file_upload_button_wrapper').live('click', function() { From 6c01175acd21cbc6c2483ad6633877872095407e Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Thu, 24 Nov 2011 02:53:35 +0100 Subject: [PATCH 42/59] fix ampache htmlentity calls --- apps/media/lib_ampache.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/media/lib_ampache.php b/apps/media/lib_ampache.php index bb468d5595..bc1f853047 100644 --- a/apps/media/lib_ampache.php +++ b/apps/media/lib_ampache.php @@ -128,7 +128,7 @@ class OC_MEDIA_AMPACHE{ $albums=count(OC_MEDIA_COLLECTION::getAlbums($artist['artist_id'])); $songs=count(OC_MEDIA_COLLECTION::getSongs($artist['artist_id'])); $id=$artist['artist_id']; - $name=htmlentities($artist['artist_name'], ENT_COMPAT | ENT_HTML401, 'UTF-8'); + $name=htmlentities($artist['artist_name'], ENT_COMPAT, 'UTF-8'); echo("\t\n"); echo("\t\t$name\n"); echo("\t\t$albums\n"); @@ -142,10 +142,10 @@ class OC_MEDIA_AMPACHE{ if(!$artistName){ $artistName=OC_MEDIA_COLLECTION::getArtistName($album['album_artist']); } - $artistName=htmlentities($artistName, ENT_COMPAT | ENT_HTML401, 'UTF-8'); + $artistName=htmlentities($artistName, ENT_COMPAT, 'UTF-8'); $songs=count(OC_MEDIA_COLLECTION::getSongs($album['album_artist'],$album['album_id'])); $id=$album['album_id']; - $name=htmlentities($album['album_name'], ENT_COMPAT | ENT_HTML401, 'UTF-8'); + $name=htmlentities($album['album_name'], ENT_COMPAT, 'UTF-8'); $artist=$album['album_artist']; echo("\t\n"); echo("\t\t$name\n"); @@ -163,10 +163,10 @@ class OC_MEDIA_AMPACHE{ if(!$albumName){ $albumName=OC_MEDIA_COLLECTION::getAlbumName($song['song_album']); } - $artistName=htmlentities($artistName, ENT_COMPAT | ENT_HTML401, 'UTF-8'); - $albumName=htmlentities($albumName, ENT_COMPAT | ENT_HTML401, 'UTF-8'); + $artistName=htmlentities($artistName, ENT_COMPAT, 'UTF-8'); + $albumName=htmlentities($albumName, ENT_COMPAT, 'UTF-8'); $id=$song['song_id']; - $name=htmlentities($song['song_name'], ENT_COMPAT | ENT_HTML401, 'UTF-8'); + $name=htmlentities($song['song_name'], ENT_COMPAT, 'UTF-8'); $artist=$song['song_artist']; $album=$song['song_album']; echo("\t\n"); From 93502b3ef832492c3437a9cae43986e8f16de426 Mon Sep 17 00:00:00 2001 From: Ignacio Daniel Rostagno Date: Sat, 19 Nov 2011 14:51:02 -0300 Subject: [PATCH 43/59] Music - Fix album and artist expand layout. --- apps/media/css/music.css | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/media/css/music.css b/apps/media/css/music.css index 67d5607519..a6738058be 100644 --- a/apps/media/css/music.css +++ b/apps/media/css/music.css @@ -31,7 +31,8 @@ div.jp-volume-bar-value { background:#ccc; width:0; height:0.4em; } #collection li { padding-right:10px; } #searchresults input.play, #searchresults input.add { float:left; height:1em; width:1em; } #collection tr.collapsed td.album, #collection tr.collapsed td.title { color:#ddd; } -a.expander { float:right; padding:0 1em; } +td.artist img, td.artist a, td.album img, td.album a { float: left; } +td.artist a.expander, td.album a.expander { float:right; padding:0 1em; } tr.active td { background-color:#eee; font-weight:bold; } tr td { border-top:1px solid #eee; height:2.2em; } tr .artist img { vertical-align:middle; } From 18d8dc4757400772a950218e2678b08545a1dd47 Mon Sep 17 00:00:00 2001 From: Insanemal Date: Mon, 21 Nov 2011 12:51:13 +1000 Subject: [PATCH 44/59] Added option to lowercase all usernames. This resolves bug with Windows AD servers as LDAP server. Windows is case insensitve on logon requests. If users are stored camel case and logon using all lower it causes issues as OwnCloud is configured to be case sensitive. Signed-off-by: Insanemal --- apps/user_ldap/settings.php | 5 ++++- apps/user_ldap/templates/settings.php | 1 + apps/user_ldap/user_ldap.php | 10 +++++++++- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/apps/user_ldap/settings.php b/apps/user_ldap/settings.php index e61d82bf8b..4be36b0444 100644 --- a/apps/user_ldap/settings.php +++ b/apps/user_ldap/settings.php @@ -20,7 +20,7 @@ * License along with this library. If not, see . * */ -$params = array('ldap_host', 'ldap_port', 'ldap_dn', 'ldap_password', 'ldap_base', 'ldap_filter', 'ldap_display_name', 'ldap_tls'); +$params = array('ldap_host', 'ldap_port', 'ldap_dn', 'ldap_password', 'ldap_base', 'ldap_filter', 'ldap_display_name', 'ldap_tls', 'ldap_nocase'); foreach($params as $param){ if(isset($_POST[$param])){ @@ -28,6 +28,9 @@ foreach($params as $param){ } elseif('ldap_tls' == $param) { // unchecked checkboxes are not included in the post paramters + OC_Appconfig::setValue('user_ldap', $param, 0); + } + elseif('ldap_nocase' == $param) { OC_Appconfig::setValue('user_ldap', $param, 0); } } diff --git a/apps/user_ldap/templates/settings.php b/apps/user_ldap/templates/settings.php index 5f25570e22..587e94e013 100644 --- a/apps/user_ldap/templates/settings.php +++ b/apps/user_ldap/templates/settings.php @@ -11,6 +11,7 @@

    t('Currently the display name field needs to be the same you matched %%uid against in the filter above, because ownCloud doesn\'t distinguish between user id and user name.');?>

    >

    +

    >

    diff --git a/apps/user_ldap/user_ldap.php b/apps/user_ldap/user_ldap.php index 249def7a1c..0b309fd99d 100644 --- a/apps/user_ldap/user_ldap.php +++ b/apps/user_ldap/user_ldap.php @@ -34,6 +34,7 @@ class OC_USER_LDAP extends OC_User_Backend { protected $ldap_base; protected $ldap_filter; protected $ldap_tls; + protected $ldap_nocase; protected $ldap_display_name; function __construct() { @@ -44,6 +45,7 @@ class OC_USER_LDAP extends OC_User_Backend { $this->ldap_base = OC_Appconfig::getValue('user_ldap', 'ldap_base',''); $this->ldap_filter = OC_Appconfig::getValue('user_ldap', 'ldap_filter',''); $this->ldap_tls = OC_Appconfig::getValue('user_ldap', 'ldap_tls', 0); + $this->ldap_nocase = OC_Appconfig::getValue('user_ldap', 'ldap_nocase', 0); $this->ldap_display_name = OC_Appconfig::getValue('user_ldap', 'ldap_display_name', OC_USER_BACKEND_LDAP_DEFAULT_DISPLAY_NAME); if( !empty($this->ldap_host) @@ -146,7 +148,13 @@ class OC_USER_LDAP extends OC_User_Backend { // TODO ldap_get_entries() seems to lower all keys => needs review $ldap_display_name = strtolower($this->ldap_display_name); if(isset($row[$ldap_display_name])) { - $users[] = $row[$ldap_display_name][0]; + if($this->ldap_nocase) { + $users[] = strtolower($row[$ldap_display_name][0]); + } + else + { + $users[] = $row[$ldap_display_name][0]; + } } } // TODO language specific sorting of user names From 8d092434edcabbede56feaf1be925e7d88d8aee2 Mon Sep 17 00:00:00 2001 From: Insanemal Date: Mon, 21 Nov 2011 20:20:26 +1000 Subject: [PATCH 45/59] Adjusted the check user function to lowercase the return. Signed-off-by: Insanemal --- apps/user_ldap/user_ldap.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/apps/user_ldap/user_ldap.php b/apps/user_ldap/user_ldap.php index 0b309fd99d..d35cefcaae 100644 --- a/apps/user_ldap/user_ldap.php +++ b/apps/user_ldap/user_ldap.php @@ -115,7 +115,14 @@ class OC_USER_LDAP extends OC_User_Backend { if (!@ldap_bind( $this->getDs(), $dn, $password )) return false; - return $uid; + + if($this->ldap_nocase) { + return strtolower($uid); + } + else { + return $uid; + } + } public function userExists( $uid ) { From c945989a70b278ddb038d194a5c9b84572ab201b Mon Sep 17 00:00:00 2001 From: Insanemal Date: Tue, 22 Nov 2011 11:08:27 +1000 Subject: [PATCH 46/59] Total rewite of fix. This now re-looks up the username and returns that for use. Signed-off-by: Insanemal --- apps/user_ldap/settings.php | 23 +++++++++++++---------- apps/user_ldap/templates/settings.php | 2 +- apps/user_ldap/user_ldap.php | 24 ++++++++++++++++-------- 3 files changed, 30 insertions(+), 19 deletions(-) diff --git a/apps/user_ldap/settings.php b/apps/user_ldap/settings.php index 4be36b0444..1f2d8ed9af 100644 --- a/apps/user_ldap/settings.php +++ b/apps/user_ldap/settings.php @@ -22,16 +22,19 @@ */ $params = array('ldap_host', 'ldap_port', 'ldap_dn', 'ldap_password', 'ldap_base', 'ldap_filter', 'ldap_display_name', 'ldap_tls', 'ldap_nocase'); -foreach($params as $param){ - if(isset($_POST[$param])){ - OC_Appconfig::setValue('user_ldap', $param, $_POST[$param]); - } - elseif('ldap_tls' == $param) { - // unchecked checkboxes are not included in the post paramters - OC_Appconfig::setValue('user_ldap', $param, 0); - } - elseif('ldap_nocase' == $param) { - OC_Appconfig::setValue('user_ldap', $param, 0); +if ($_POST) { + foreach($params as $param){ + if(isset($_POST[$param])){ + OC_Appconfig::setValue('user_ldap', $param, $_POST[$param]); + } + elseif('ldap_tls' == $param) { + // unchecked checkboxes are not included in the post paramters + OC_Appconfig::setValue('user_ldap', $param, 0); + } + elseif('ldap_nocase' == $param) { + OC_Appconfig::setValue('user_ldap', $param, 0); + } + } } diff --git a/apps/user_ldap/templates/settings.php b/apps/user_ldap/templates/settings.php index 587e94e013..2abb0b4729 100644 --- a/apps/user_ldap/templates/settings.php +++ b/apps/user_ldap/templates/settings.php @@ -11,7 +11,7 @@

    t('Currently the display name field needs to be the same you matched %%uid against in the filter above, because ownCloud doesn\'t distinguish between user id and user name.');?>

    >

    -

    >

    +

    >

    diff --git a/apps/user_ldap/user_ldap.php b/apps/user_ldap/user_ldap.php index d35cefcaae..106240e74b 100644 --- a/apps/user_ldap/user_ldap.php +++ b/apps/user_ldap/user_ldap.php @@ -117,7 +117,21 @@ class OC_USER_LDAP extends OC_User_Backend { return false; if($this->ldap_nocase) { - return strtolower($uid); + $filter = str_replace('%uid', $uid, $this->ldap_filter); + $sr = ldap_search( $this->getDs(), $this->ldap_base, $filter ); + $entries = ldap_get_entries( $this->getDs(), $sr ); + if( $entries['count'] == 1 ) { + foreach($entries as $row) { + $ldap_display_name = strtolower($this->ldap_display_name); + if(isset($row[$ldap_display_name])) { + return $row[$ldap_display_name][0]; + } + } + } + else { + return $uid; + } + } else { return $uid; @@ -155,13 +169,7 @@ class OC_USER_LDAP extends OC_User_Backend { // TODO ldap_get_entries() seems to lower all keys => needs review $ldap_display_name = strtolower($this->ldap_display_name); if(isset($row[$ldap_display_name])) { - if($this->ldap_nocase) { - $users[] = strtolower($row[$ldap_display_name][0]); - } - else - { - $users[] = $row[$ldap_display_name][0]; - } + $users[] = $row[$ldap_display_name][0]; } } // TODO language specific sorting of user names From 76bfc3b547064a5862f72f9165785aa134d8ce4f Mon Sep 17 00:00:00 2001 From: Hendrik Langer Date: Tue, 25 Oct 2011 01:58:37 +0200 Subject: [PATCH 47/59] set http auth headers for apache+php-cgi work around if variable gets renamed by apache --- lib/base.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/base.php b/lib/base.php index c52b4493e0..700236c96c 100644 --- a/lib/base.php +++ b/lib/base.php @@ -92,6 +92,14 @@ class OC{ $_SERVER['PHP_AUTH_PW'] = strip_tags($password); } + //set http auth headers for apache+php-cgi work around if variable gets renamed by apache + if (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION']) && preg_match('/Basic\s+(.*)$/i', $_SERVER['REDIRECT_HTTP_AUTHORIZATION'], $matches)) + { + list($name, $password) = explode(':', base64_decode($matches[1])); + $_SERVER['PHP_AUTH_USER'] = strip_tags($name); + $_SERVER['PHP_AUTH_PW'] = strip_tags($password); + } + // calculate the documentroot OC::$DOCUMENTROOT=realpath($_SERVER['DOCUMENT_ROOT']); OC::$SERVERROOT=str_replace("\\",'/',substr(__FILE__,0,-13)); From fab70cb59062ae945825c820787c05c7f8630bf3 Mon Sep 17 00:00:00 2001 From: Frank Karlitschek Date: Thu, 24 Nov 2011 13:50:29 +0100 Subject: [PATCH 48/59] removed no longer used function and exec command security++ --- lib/util.php | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/lib/util.php b/lib/util.php index 14313569a1..0f79948bc2 100644 --- a/lib/util.php +++ b/lib/util.php @@ -180,7 +180,6 @@ class OC_Util { } $CONFIG_DBTYPE = OC_Config::getValue( "dbtype", "sqlite" ); $CONFIG_DBNAME = OC_Config::getValue( "dbname", "owncloud" ); - $serverUser=OC_Util::checkWebserverUser(); //common hint for all file permissons error messages $permissionsHint="Permissions can usually be fixed by giving the webserver write access to the ownCloud directory"; @@ -239,21 +238,6 @@ class OC_Util { OC_Template::printGuestPage("", "login", $parameters); } - /** - * Try to get the username the httpd server runs on, used in hints - */ - public static function checkWebserverUser(){ - if(is_callable('posix_getuid')){ - $serverUser=posix_getpwuid(posix_getuid()); - $serverUser='\''.$serverUser['name'].'\''; - }elseif(exec('whoami')){ - $serverUser=exec('whoami'); - }else{ - $serverUser='\'www-data\' for ubuntu/debian'; //TODO: try to detect the distro and give a guess based on that - } - return $serverUser; - } - /** * Check if the app is enabled, send json error msg if not From cea6561632b8979da1b5bdc9a57dca26d2b9f90c Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Thu, 24 Nov 2011 21:04:34 +0100 Subject: [PATCH 49/59] Update chosen to v0.9.5 --- 3rdparty/css/chosen/chosen-sprite.png | Bin 742 -> 3998 bytes 3rdparty/css/chosen/chosen.css | 84 ++++++++---- 3rdparty/js/chosen/VERSION | 2 +- 3rdparty/js/chosen/chosen.jquery.js | 171 +++++++++++++++++------- 3rdparty/js/chosen/chosen.jquery.min.js | 4 +- 5 files changed, 180 insertions(+), 81 deletions(-) diff --git a/3rdparty/css/chosen/chosen-sprite.png b/3rdparty/css/chosen/chosen-sprite.png index f20db4439ea5c1038126bf326c8fd048b03a8226..9edce05a6a899eaf98481d12dddbc433331a01ee 100644 GIT binary patch delta 3675 zcmV-h4y5ts1)d*}7k?-S0{{R3m1Swo00009a7bBm000XU000XU0RWnu7ytkYPiaF# zP*7-ZbZ>KLZ*U+IBfRsybQWXdwQbLP> z6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uh>2n?1;Gf_2w45>mM5#WQz#Kz&|EGkvK~TfD`~gdX7S-06<0o zfSs5oQvjd@0DoZ1V`Ad~P%QvpCx7PC0DztNnR@{MTa+Oc0iclpAQNSXL;z?z0Ibhe zibVieFaQ*0OT;+<*ew7sNmph_0I;_Jz|Ig0vH%DS05DOAg((08djMd_BO`bKgqZ*o zM)FrY@hh$n=PCdIc$u<1xgb(Nq-kB6gFW3VVXcL!g-k)GJ!M? z;PcD?0HBc-5#WRK{dmp}uFlRjj{ zU%*%WY=8NFJpA|d;J)G{fihizM+Erb!p!tcr5w+a34~(Y=8s4Gw+sLL9n&JjNn*KJ zDiq^U5^;`1nvC-@r6P$!k}1U{(*I=Q-z@tBKHoI}uxdU5dyy@uU1J0GOD7Ombim^G z008p4Z^6_k2m^pic}y~NFDM$asoMrTt>Q)JIDYsg8YWOM=_LvvQa(M47EeKs5csfMxqPQWOOl_ zj~1Yt&~mgIJ&ZP?=g_NY5897DL&q?{=okkx#B4Aw#=}CfI4lX1W6QB3tPHEh8n9NZ z1G|a!W6!a71QLNozzH@4cS0ax9zjT0On+ET*hr`#93(Um+6gxa1B6k+CnA%mOSC4s z5&6UzVlpv@SV$}*))J2sFA#f(L&P^E5{W}HC%KRUNwK6<(h|}}(r!{C=`5+6G)NjF zlgZj-YqAG9lq?`C$c5yc>d>VnA`E_*3F2Qp##d8RZb=H01_mn13=s zRim0x-Ke2d5jBrmLam{;Qm;{ms1r1GnmNsb7D-E`t)i9F8fX`2_i3-_bh;7Ul^#x) z&{xvS=|||7=mYe33=M`AgU5(xC>fg=2N-7=cNnjjOr{yriy6mMFgG#lnCF=fnQv8C zDz++o6_Lscl}eQ+l^ZHARH>?_s(;?93sv(~%T$l4UQ>OpMpZLY-Tx+V9mzG$oNUKq+N9(;duI;CtroBbGS^I$wLB~obTqj3okIn_1=Tq5J-KPqt z7EL`m^{y_eYo!~ZyF_=tZl~^;p1xjyo=k72-g&*}`W$^P{Z##J`lt0r3|I!U3?v5I z49*xl#WitnJRL8`+woCDU4O$sL#1JrVVB{Ak-5=4qt!-@Mh}c>#$4kh<88)m#-k<% zCLtzEP3leVno>={htGUuD;o7bD)w_sX$S}eAxwzy?U zvgBH(S?;#HZiQMoS*2K2T3xe7t(~nU*1N5{rxB;QPLocnp4Ml>uz&Hk$+oGt8L;Kp z2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C^>JO{ zdeZfso3oq3?Wo(Y?teD!Y3_&IpUgC$DV|v~bI`-cL*P;6(LW2Hl`w1HtbR{JPl0E( z=OZs;FOgTR*RZ#xcdGYc?-xGyK60PqKI1$$-ZI`u$xr8UFki1L{Ox>G0o)(&RAZ;=|I=wN2l97;c zLaHH6leTB-XXa*h%dBOEvi`+xi?=Txl?TadvyiL>S${1GwnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_Iu74EU7nc=(*eKk1(e4|2 zy!JHg)!SRV_x(P}zS~s+RZZ1q)n)rh`?L2yu78QD>G+oWZC$NSZE@|#1JVQi2O|!) z*SXZy9nw8iQjgXv>qid9AHM#b?{_T?HVsvcoW|lKa720J>GuiW_Z|&8+IEb4tl4MXfXY$XC zoqv^`eSR+a++f?HwtMGe&fjVeZ|}Mgbm7uP|BL54ygSZZ^0;*JvfJeoSGZT2uR33C z>U8Qn{*%*B$Ge=nny$HAYq{=vy|sI0_vss+H_qMky?OB#|JK!>IX&II^LlUh#rO5! z7TtbwC;iULyV-Xq?ybB}ykGP{?LpZ?-G7JGKU@CX*zeqbYQT4(^U>T#_XdT7&;F71 zj}JoykC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTP zlfP|zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5 zZ<1fdMgRZ<0Ffp4e^F6UQc_Y=Q&Ut_R8>_~R#sM5S65hASXo(FT3T9LTU%UQTwPsV zUS3{bUteHgU}0flVq#)rV`F4wWMyS#W@ct*XJ=?=XlZF_YHDh0Yin$5Y;A3AZfQa&mHWb8~cbbai!gc6N4mcXxPrczJnwdU|?$e|vj;e0+UdCU$jHda$;ryf%FD~k%*@Qq&CSlv&d<-!f6&m-(b3V;($dq@)6~?|)z#J3 z*4Ee8*Vx$D+1c6J+S=RO+uYpT-QC^Z-rnEe-{9cj;o;%p;^O1ulq(=H}<; z=jiC@>FMd}>gwz3>+J08?d|RE?(XmJ@9^;O@$vEU^78ZZ^Yrxe_4W1k_V)Mp_xSku z`T6i^!0bqY%NklT+>Q{e^Xseq&L0`odh4XD~y+}^OCg<&Q;C~m{JN*e-Gl;yI(`W%3<@})9>$Zidb04T52$N(_ccdKU!p_TnE03fxFWZol0H|Op* z)<^EHqf+IGueD_LN80V3=R6L|tEmi*dG$=BrECtE_0)n=Hho?_wGWw|%CyhIjtmYG zEvd4wTTLj6cK^Z)>{mVaGq8DIyI}jC7{=o?JD?~(}0|0~!uhzlT_-+6I002ovPDHLkV1o5cKhppJ delta 395 zcmV;60d)SJALa#+7Y-%}0{{R3uWtyw00026hW2H=$?x#9xGbV7#^2p!UU?|T2Ii5zE`@j;o)o^r^4@E+uEG;9AL5Yg|RggC18 zQMd^X&mV%1!lnTZ1H(jNQeptiBq%KM5<6S~%8q~;z&Hxm#5>!HTsTvr`c-+u!kZqCC5mm$tL^@ay66=w7#;zQa^u)dMjNZr&1fIxv4F1=b& zcadNb06;rcUjqO(x?<;Ih0@*WcIOs&sq-FrQzYhPPl@+Z-p#CxH zIMkgMhm@g85_XG(@cS18PL%|ofBbiG&?#J$-*DK{d~1+fzG!0bqh{GcR3GYR2<-WG zJWTBwfeThLb2|w9jqK$u0uOqp@wnF32y7N=2g089a+e4!qPiwi*LE5REUGhWvbM9@ pegj?4jMSL~<8&5_rJi)+@d=yNidHAaT2cT2002ovPDHLkV1fyUx26C9 diff --git a/3rdparty/css/chosen/chosen.css b/3rdparty/css/chosen/chosen.css index 247d07bf02..b9c6d88028 100644 --- a/3rdparty/css/chosen/chosen.css +++ b/3rdparty/css/chosen/chosen.css @@ -1,9 +1,4 @@ /* @group Base */ -select.chzn-select { - visibility: hidden; - height: 28px !important; - min-height: 28px !important; -} .chzn-container { font-size: 13px; position: relative; @@ -60,9 +55,21 @@ select.chzn-select { white-space: nowrap; -o-text-overflow: ellipsis; -ms-text-overflow: ellipsis; - -moz-binding: url('/xml/ellipsis.xml#ellipsis'); text-overflow: ellipsis; } +.chzn-container-single .chzn-single abbr { + display: block; + position: absolute; + right: 26px; + top: 8px; + width: 12px; + height: 13px; + font-size: 1px; + background: url(chosen-sprite.png) right top no-repeat; +} +.chzn-container-single .chzn-single abbr:hover { + background-position: right -11px; +} .chzn-container-single .chzn-single div { -webkit-border-radius: 0 4px 4px 0; -moz-border-radius : 0 4px 4px 0; @@ -94,18 +101,19 @@ select.chzn-select { } .chzn-container-single .chzn-search { padding: 3px 4px; + position: relative; margin: 0; white-space: nowrap; } .chzn-container-single .chzn-search input { - background: #fff url('chosen-sprite.png') no-repeat 100% -20px; - background: url('chosen-sprite.png') no-repeat 100% -20px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee)); - background: url('chosen-sprite.png') no-repeat 100% -20px, -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%); - background: url('chosen-sprite.png') no-repeat 100% -20px, -moz-linear-gradient(center bottom, white 85%, #eeeeee 99%); - background: url('chosen-sprite.png') no-repeat 100% -20px, -o-linear-gradient(bottom, white 85%, #eeeeee 99%); - background: url('chosen-sprite.png') no-repeat 100% -20px, -ms-linear-gradient(top, #ffffff 85%,#eeeeee 99%); - background: url('chosen-sprite.png') no-repeat 100% -20px, -ms-linear-gradient(top, #ffffff 85%,#eeeeee 99%); - background: url('chosen-sprite.png') no-repeat 100% -20px, linear-gradient(top, #ffffff 85%,#eeeeee 99%); + background: #fff url('chosen-sprite.png') no-repeat 100% -22px; + background: url('chosen-sprite.png') no-repeat 100% -22px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee)); + background: url('chosen-sprite.png') no-repeat 100% -22px, -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%); + background: url('chosen-sprite.png') no-repeat 100% -22px, -moz-linear-gradient(center bottom, white 85%, #eeeeee 99%); + background: url('chosen-sprite.png') no-repeat 100% -22px, -o-linear-gradient(bottom, white 85%, #eeeeee 99%); + background: url('chosen-sprite.png') no-repeat 100% -22px, -ms-linear-gradient(top, #ffffff 85%,#eeeeee 99%); + background: url('chosen-sprite.png') no-repeat 100% -22px, -ms-linear-gradient(top, #ffffff 85%,#eeeeee 99%); + background: url('chosen-sprite.png') no-repeat 100% -22px, linear-gradient(top, #ffffff 85%,#eeeeee 99%); margin: 1px 0; padding: 4px 20px 4px 5px; outline: 0; @@ -123,6 +131,11 @@ select.chzn-select { } /* @end */ +.chzn-container-single-nosearch .chzn-search input { + position: absolute; + left: -9000px; +} + /* @group Multi Chosen */ .chzn-container-multi .chzn-choices { background-color: #fff; @@ -197,18 +210,18 @@ select.chzn-select { .chzn-container-multi .chzn-choices .search-choice .search-choice-close { display: block; position: absolute; - right: 5px; - top: 6px; - width: 8px; - height: 9px; + right: 3px; + top: 4px; + width: 12px; + height: 13px; font-size: 1px; background: url(chosen-sprite.png) right top no-repeat; } .chzn-container-multi .chzn-choices .search-choice .search-choice-close:hover { - background-position: right -9px; + background-position: right -11px; } .chzn-container-multi .chzn-choices .search-choice-focus .search-choice-close { - background-position: right -9px; + background-position: right -11px; } /* @end */ @@ -226,6 +239,7 @@ select.chzn-select { padding: 0; } .chzn-container .chzn-results li { + display: none; line-height: 80%; padding: 7px 7px 8px; margin: 0; @@ -233,6 +247,7 @@ select.chzn-select { } .chzn-container .chzn-results .active-result { cursor: pointer; + display: list-item; } .chzn-container .chzn-results .highlighted { background: #3875d7; @@ -247,6 +262,7 @@ select.chzn-select { } .chzn-container .chzn-results .no-results { background: #f4f4f4; + display: list-item; } .chzn-container .chzn-results .group-result { cursor: default; @@ -309,6 +325,18 @@ select.chzn-select { } /* @end */ +/* @group Disabled Support */ +.chzn-disabled { + cursor: default; + opacity:0.5 !important; +} +.chzn-disabled .chzn-single { + cursor: default; +} +.chzn-disabled .chzn-choices .search-choice .search-choice-close { + cursor: default; +} + /* @group Right to Left */ .chzn-rtl { direction:rtl;text-align: right; } .chzn-rtl .chzn-single { padding-left: 0; padding-right: 8px; } @@ -327,14 +355,14 @@ select.chzn-select { .chzn-rtl .chzn-results .group-option { padding-left: 0; padding-right: 20px; } .chzn-rtl.chzn-container-active .chzn-single-with-drop div { border-right: none; } .chzn-rtl .chzn-search input { - background: url('chosen-sprite.png') no-repeat -38px -20px, #ffffff; - background: url('chosen-sprite.png') no-repeat -38px -20px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee)); - background: url('chosen-sprite.png') no-repeat -38px -20px, -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%); - background: url('chosen-sprite.png') no-repeat -38px -20px, -moz-linear-gradient(center bottom, white 85%, #eeeeee 99%); - background: url('chosen-sprite.png') no-repeat -38px -20px, -o-linear-gradient(bottom, white 85%, #eeeeee 99%); - background: url('chosen-sprite.png') no-repeat -38px -20px, -ms-linear-gradient(top, #ffffff 85%,#eeeeee 99%); - background: url('chosen-sprite.png') no-repeat -38px -20px, -ms-linear-gradient(top, #ffffff 85%,#eeeeee 99%); - background: url('chosen-sprite.png') no-repeat -38px -20px, linear-gradient(top, #ffffff 85%,#eeeeee 99%); + background: url('chosen-sprite.png') no-repeat -38px -22px, #ffffff; + background: url('chosen-sprite.png') no-repeat -38px -22px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee)); + background: url('chosen-sprite.png') no-repeat -38px -22px, -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%); + background: url('chosen-sprite.png') no-repeat -38px -22px, -moz-linear-gradient(center bottom, white 85%, #eeeeee 99%); + background: url('chosen-sprite.png') no-repeat -38px -22px, -o-linear-gradient(bottom, white 85%, #eeeeee 99%); + background: url('chosen-sprite.png') no-repeat -38px -22px, -ms-linear-gradient(top, #ffffff 85%,#eeeeee 99%); + background: url('chosen-sprite.png') no-repeat -38px -22px, -ms-linear-gradient(top, #ffffff 85%,#eeeeee 99%); + background: url('chosen-sprite.png') no-repeat -38px -22px, linear-gradient(top, #ffffff 85%,#eeeeee 99%); padding: 4px 5px 4px 20px; } /* @end */ \ No newline at end of file diff --git a/3rdparty/js/chosen/VERSION b/3rdparty/js/chosen/VERSION index f374f6662e..b0bb878545 100644 --- a/3rdparty/js/chosen/VERSION +++ b/3rdparty/js/chosen/VERSION @@ -1 +1 @@ -0.9.1 +0.9.5 diff --git a/3rdparty/js/chosen/chosen.jquery.js b/3rdparty/js/chosen/chosen.jquery.js index 5ea409d90e..e7e661c096 100644 --- a/3rdparty/js/chosen/chosen.jquery.js +++ b/3rdparty/js/chosen/chosen.jquery.js @@ -1,7 +1,7 @@ // Chosen, a Select Box Enhancer for jQuery and Protoype // by Patrick Filler for Harvest, http://getharvest.com // -// Version 0.9 +// Version 0.9.5 // Full source at https://github.com/harvesthq/chosen // Copyright (c) 2011 Harvest http://getharvest.com @@ -16,18 +16,22 @@ root = this; $ = jQuery; $.fn.extend({ - chosen: function(data, options) { + chosen: function(options) { + if ($.browser === "msie" && ($.browser.version === "6.0" || $.browser.version === "7.0")) { + return this; + } return $(this).each(function(input_field) { if (!($(this)).hasClass("chzn-done")) { - return new Chosen(this, data, options); + return new Chosen(this, options); } }); } }); Chosen = (function() { - function Chosen(elmn) { + function Chosen(form_field, options) { + this.form_field = form_field; + this.options = options != null ? options : {}; this.set_default_values(); - this.form_field = elmn; this.form_field_jq = $(this.form_field); this.is_multiple = this.form_field.multiple; this.is_rtl = this.form_field_jq.hasClass("chzn-rtl"); @@ -40,22 +44,28 @@ this.click_test_action = __bind(function(evt) { return this.test_active_click(evt); }, this); + this.activate_action = __bind(function(evt) { + return this.activate_field(evt); + }, this); this.active_field = false; this.mouse_on_container = false; this.results_showing = false; this.result_highlighted = null; this.result_single_selected = null; - return this.choices = 0; + this.allow_single_deselect = (this.options.allow_single_deselect != null) && this.form_field.options[0].text === "" ? this.options.allow_single_deselect : false; + this.disable_search_threshold = this.options.disable_search_threshold || 0; + this.choices = 0; + return this.results_none_found = this.options.no_results_text || "No results match"; }; Chosen.prototype.set_up_html = function() { var container_div, dd_top, dd_width, sf_width; this.container_id = this.form_field.id.length ? this.form_field.id.replace(/(:|\.)/g, '_') : this.generate_field_id(); this.container_id += "_chzn"; - this.f_width = this.form_field_jq.width(); + this.f_width = this.form_field_jq.outerWidth(); this.default_text = this.form_field_jq.data('placeholder') ? this.form_field_jq.data('placeholder') : this.default_text_default; container_div = $("
    ", { id: this.container_id, - "class": "chzn-container " + (this.is_rtl ? ' chzn-rtl' : void 0), + "class": "chzn-container" + (this.is_rtl ? ' chzn-rtl' : ''), style: 'width: ' + this.f_width + 'px;' }); if (this.is_multiple) { @@ -66,6 +76,9 @@ this.form_field_jq.hide().after(container_div); this.container = $('#' + this.container_id); this.container.addClass("chzn-container-" + (this.is_multiple ? "multi" : "single")); + if (!this.is_multiple && this.form_field.options.length <= this.disable_search_threshold) { + this.container.addClass("chzn-container-single-nosearch"); + } this.dropdown = this.container.find('div.chzn-drop').first(); dd_top = this.container.height(); dd_width = this.f_width - get_side_border_padding(this.dropdown); @@ -92,8 +105,11 @@ return this.set_tab_index(); }; Chosen.prototype.register_observers = function() { - this.container.click(__bind(function(evt) { - return this.container_click(evt); + this.container.mousedown(__bind(function(evt) { + return this.container_mousedown(evt); + }, this)); + this.container.mouseup(__bind(function(evt) { + return this.container_mouseup(evt); }, this)); this.container.mouseenter(__bind(function(evt) { return this.mouse_enter(evt); @@ -101,8 +117,8 @@ this.container.mouseleave(__bind(function(evt) { return this.mouse_leave(evt); }, this)); - this.search_results.click(__bind(function(evt) { - return this.search_results_click(evt); + this.search_results.mouseup(__bind(function(evt) { + return this.search_results_mouseup(evt); }, this)); this.search_results.mouseover(__bind(function(evt) { return this.search_results_mouseover(evt); @@ -129,30 +145,52 @@ return this.search_field.focus(__bind(function(evt) { return this.input_focus(evt); }, this)); - } else { - return this.selected_item.focus(__bind(function(evt) { - return this.activate_field(evt); - }, this)); } }; - Chosen.prototype.container_click = function(evt) { - if (evt && evt.type === "click") { - evt.stopPropagation(); - } - if (!this.pending_destroy_click) { - if (!this.active_field) { - if (this.is_multiple) { - this.search_field.val(""); - } - $(document).click(this.click_test_action); - this.results_show(); - } else if (!this.is_multiple && evt && ($(evt.target) === this.selected_item || $(evt.target).parents("a.chzn-single").length)) { - evt.preventDefault(); - this.results_toggle(); + Chosen.prototype.search_field_disabled = function() { + this.is_disabled = this.form_field_jq.attr('disabled'); + if (this.is_disabled) { + this.container.addClass('chzn-disabled'); + this.search_field.attr('disabled', true); + if (!this.is_multiple) { + this.selected_item.unbind("focus", this.activate_action); } - return this.activate_field(); + return this.close_field(); } else { - return this.pending_destroy_click = false; + this.container.removeClass('chzn-disabled'); + this.search_field.attr('disabled', false); + if (!this.is_multiple) { + return this.selected_item.bind("focus", this.activate_action); + } + } + }; + Chosen.prototype.container_mousedown = function(evt) { + var target_closelink; + if (!this.is_disabled) { + target_closelink = evt != null ? ($(evt.target)).hasClass("search-choice-close") : false; + if (evt && evt.type === "mousedown") { + evt.stopPropagation(); + } + if (!this.pending_destroy_click && !target_closelink) { + if (!this.active_field) { + if (this.is_multiple) { + this.search_field.val(""); + } + $(document).click(this.click_test_action); + this.results_show(); + } else if (!this.is_multiple && evt && ($(evt.target) === this.selected_item || $(evt.target).parents("a.chzn-single").length)) { + evt.preventDefault(); + this.results_toggle(); + } + return this.activate_field(); + } else { + return this.pending_destroy_click = false; + } + } + }; + Chosen.prototype.container_mouseup = function(evt) { + if (evt.target.nodeName === "ABBR") { + return this.results_reset(evt); } }; Chosen.prototype.mouse_enter = function() { @@ -164,7 +202,7 @@ Chosen.prototype.input_focus = function(evt) { if (!this.active_field) { return setTimeout((__bind(function() { - return this.container_click(); + return this.container_mousedown(); }, this)), 50); } }; @@ -235,9 +273,13 @@ this.choice_build(data); } else if (data.selected && !this.is_multiple) { this.selected_item.find("span").text(data.text); + if (this.allow_single_deselect) { + this.selected_item.find("span").first().after(""); + } } } } + this.search_field_disabled(); this.show_search_field_default(); this.search_field_scale(); this.search_results.html(content); @@ -252,7 +294,7 @@ } }; Chosen.prototype.result_add_option = function(option) { - var classes; + var classes, style; if (!option.disabled) { option.dom_id = this.container_id + "_o_" + option.array_index; classes = option.selected && this.is_multiple ? [] : ["active-result"]; @@ -262,7 +304,11 @@ if (option.group_array_index != null) { classes.push("group-option"); } - return '
  • ' + option.html + '
  • '; + if (option.classes !== "") { + classes.push(option.classes); + } + style = option.style.cssText !== "" ? " style=\"" + option.style + "\"" : ""; + return '
  • ' + option.html + '
  • '; } else { return ""; } @@ -353,12 +399,12 @@ return this.search_field.removeClass("default"); } }; - Chosen.prototype.search_results_click = function(evt) { + Chosen.prototype.search_results_mouseup = function(evt) { var target; target = $(evt.target).hasClass("active-result") ? $(evt.target) : $(evt.target).parents(".active-result").first(); if (target.length) { this.result_highlight = target; - return this.result_select(); + return this.result_select(evt); } }; Chosen.prototype.search_results_mouseover = function(evt) { @@ -391,8 +437,12 @@ }; Chosen.prototype.choice_destroy_link_click = function(evt) { evt.preventDefault(); - this.pending_destroy_click = true; - return this.choice_destroy($(evt.target)); + if (!this.is_disabled) { + this.pending_destroy_click = true; + return this.choice_destroy($(evt.target)); + } else { + return evt.stopPropagation; + } }; Chosen.prototype.choice_destroy = function(link) { this.choices -= 1; @@ -403,18 +453,29 @@ this.result_deselect(link.attr("rel")); return link.parents('li').first().remove(); }; - Chosen.prototype.result_select = function() { + Chosen.prototype.results_reset = function(evt) { + this.form_field.options[0].selected = true; + this.selected_item.find("span").text(this.default_text); + this.show_search_field_default(); + $(evt.target).remove(); + this.form_field_jq.trigger("change"); + if (this.active_field) { + return this.results_hide(); + } + }; + Chosen.prototype.result_select = function(evt) { var high, high_id, item, position; if (this.result_highlight) { high = this.result_highlight; high_id = high.attr("id"); this.result_clear_highlight(); - high.addClass("result-selected"); if (this.is_multiple) { this.result_deactivate(high); } else { + this.search_results.find(".result-selected").removeClass("result-selected"); this.result_single_selected = high; } + high.addClass("result-selected"); position = high_id.substr(high_id.lastIndexOf("_") + 1); item = this.results_data[position]; item.selected = true; @@ -423,18 +484,23 @@ this.choice_build(item); } else { this.selected_item.find("span").first().text(item.text); + if (this.allow_single_deselect) { + this.selected_item.find("span").first().after(""); + } + } + if (!(evt.metaKey && this.is_multiple)) { + this.results_hide(); } - this.results_hide(); this.search_field.val(""); this.form_field_jq.trigger("change"); return this.search_field_scale(); } }; Chosen.prototype.result_activate = function(el) { - return el.addClass("active-result").show(); + return el.addClass("active-result"); }; Chosen.prototype.result_deactivate = function(el) { - return el.removeClass("active-result").hide(); + return el.removeClass("active-result"); }; Chosen.prototype.result_deselect = function(pos) { var result, result_data; @@ -530,17 +596,18 @@ return _results; }; Chosen.prototype.winnow_results_set_highlight = function() { - var do_high; + var do_high, selected_results; if (!this.result_highlight) { - do_high = this.search_results.find(".active-result").first(); - if (do_high) { + selected_results = !this.is_multiple ? this.search_results.find(".result-selected.active-result") : []; + do_high = selected_results.length ? selected_results.first() : this.search_results.find(".active-result").first(); + if (do_high != null) { return this.result_do_highlight(do_high); } } }; Chosen.prototype.no_results = function(terms) { var no_results_html; - no_results_html = $('
  • No results match ""
  • '); + no_results_html = $('
  • ' + this.results_none_found + ' ""
  • '); no_results_html.find("span").first().html(terms); return this.search_results.append(no_results_html); }; @@ -611,7 +678,7 @@ case 13: evt.preventDefault(); if (this.results_showing) { - return this.result_select(); + return this.result_select(evt); } break; case 27: @@ -623,6 +690,8 @@ case 38: case 40: case 16: + case 91: + case 17: break; default: return this.results_search(); @@ -758,7 +827,9 @@ html: option.innerHTML, selected: option.selected, disabled: group_disabled === true ? group_disabled : option.disabled, - group_array_index: group_position + group_array_index: group_position, + classes: option.className, + style: option.style.cssText }); } else { this.parsed.push({ diff --git a/3rdparty/js/chosen/chosen.jquery.min.js b/3rdparty/js/chosen/chosen.jquery.min.js index 1d6a6983d8..371ee53e7a 100644 --- a/3rdparty/js/chosen/chosen.jquery.min.js +++ b/3rdparty/js/chosen/chosen.jquery.min.js @@ -1,10 +1,10 @@ // Chosen, a Select Box Enhancer for jQuery and Protoype // by Patrick Filler for Harvest, http://getharvest.com // -// Version 0.9 +// Version 0.9.5 // Full source at https://github.com/harvesthq/chosen // Copyright (c) 2011 Harvest http://getharvest.com // MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md // This file is generated by `cake build`, do not edit it by hand. -(function(){var a,b,c,d,e=function(a,b){return function(){return a.apply(b,arguments)}};d=this,a=jQuery,a.fn.extend({chosen:function(c,d){return a(this).each(function(e){if(!a(this).hasClass("chzn-done"))return new b(this,c,d)})}}),b=function(){function b(b){this.set_default_values(),this.form_field=b,this.form_field_jq=a(this.form_field),this.is_multiple=this.form_field.multiple,this.is_rtl=this.form_field_jq.hasClass("chzn-rtl"),this.default_text_default=this.form_field.multiple?"Select Some Options":"Select an Option",this.set_up_html(),this.register_observers(),this.form_field_jq.addClass("chzn-done")}b.prototype.set_default_values=function(){this.click_test_action=e(function(a){return this.test_active_click(a)},this),this.active_field=!1,this.mouse_on_container=!1,this.results_showing=!1,this.result_highlighted=null,this.result_single_selected=null;return this.choices=0},b.prototype.set_up_html=function(){var b,d,e,f;this.container_id=this.form_field.id.length?this.form_field.id.replace(/(:|\.)/g,"_"):this.generate_field_id(),this.container_id+="_chzn",this.f_width=this.form_field_jq.width(),this.default_text=this.form_field_jq.data("placeholder")?this.form_field_jq.data("placeholder"):this.default_text_default,b=a("
    ",{id:this.container_id,"class":"chzn-container "+(this.is_rtl?" chzn-rtl":void 0),style:"width: "+this.f_width+"px;"}),this.is_multiple?b.html('
      '):b.html(''+this.default_text+'
        '),this.form_field_jq.hide().after(b),this.container=a("#"+this.container_id),this.container.addClass("chzn-container-"+(this.is_multiple?"multi":"single")),this.dropdown=this.container.find("div.chzn-drop").first(),d=this.container.height(),e=this.f_width-c(this.dropdown),this.dropdown.css({width:e+"px",top:d+"px"}),this.search_field=this.container.find("input").first(),this.search_results=this.container.find("ul.chzn-results").first(),this.search_field_scale(),this.search_no_results=this.container.find("li.no-results").first(),this.is_multiple?(this.search_choices=this.container.find("ul.chzn-choices").first(),this.search_container=this.container.find("li.search-field").first()):(this.search_container=this.container.find("div.chzn-search").first(),this.selected_item=this.container.find(".chzn-single").first(),f=e-c(this.search_container)-c(this.search_field),this.search_field.css({width:f+"px"})),this.results_build();return this.set_tab_index()},b.prototype.register_observers=function(){this.container.click(e(function(a){return this.container_click(a)},this)),this.container.mouseenter(e(function(a){return this.mouse_enter(a)},this)),this.container.mouseleave(e(function(a){return this.mouse_leave(a)},this)),this.search_results.click(e(function(a){return this.search_results_click(a)},this)),this.search_results.mouseover(e(function(a){return this.search_results_mouseover(a)},this)),this.search_results.mouseout(e(function(a){return this.search_results_mouseout(a)},this)),this.form_field_jq.bind("liszt:updated",e(function(a){return this.results_update_field(a)},this)),this.search_field.blur(e(function(a){return this.input_blur(a)},this)),this.search_field.keyup(e(function(a){return this.keyup_checker(a)},this)),this.search_field.keydown(e(function(a){return this.keydown_checker(a)},this));if(this.is_multiple){this.search_choices.click(e(function(a){return this.choices_click(a)},this));return this.search_field.focus(e(function(a){return this.input_focus(a)},this))}return this.selected_item.focus(e(function(a){return this.activate_field(a)},this))},b.prototype.container_click=function(b){b&&b.type==="click"&&b.stopPropagation();if(!this.pending_destroy_click){this.active_field?!this.is_multiple&&b&&(a(b.target)===this.selected_item||a(b.target).parents("a.chzn-single").length)&&(b.preventDefault(),this.results_toggle()):(this.is_multiple&&this.search_field.val(""),a(document).click(this.click_test_action),this.results_show());return this.activate_field()}return this.pending_destroy_click=!1},b.prototype.mouse_enter=function(){return this.mouse_on_container=!0},b.prototype.mouse_leave=function(){return this.mouse_on_container=!1},b.prototype.input_focus=function(a){if(!this.active_field)return setTimeout(e(function(){return this.container_click()},this),50)},b.prototype.input_blur=function(a){if(!this.mouse_on_container){this.active_field=!1;return setTimeout(e(function(){return this.blur_test()},this),100)}},b.prototype.blur_test=function(a){if(!this.active_field&&this.container.hasClass("chzn-container-active"))return this.close_field()},b.prototype.close_field=function(){a(document).unbind("click",this.click_test_action),this.is_multiple||(this.selected_item.attr("tabindex",this.search_field.attr("tabindex")),this.search_field.attr("tabindex",-1)),this.active_field=!1,this.results_hide(),this.container.removeClass("chzn-container-active"),this.winnow_results_clear(),this.clear_backstroke(),this.show_search_field_default();return this.search_field_scale()},b.prototype.activate_field=function(){!this.is_multiple&&!this.active_field&&(this.search_field.attr("tabindex",this.selected_item.attr("tabindex")),this.selected_item.attr("tabindex",-1)),this.container.addClass("chzn-container-active"),this.active_field=!0,this.search_field.val(this.search_field.val());return this.search_field.focus()},b.prototype.test_active_click=function(b){return a(b.target).parents("#"+this.container_id).length?this.active_field=!0:this.close_field()},b.prototype.results_build=function(){var a,b,c,e,f,g;c=new Date,this.parsing=!0,this.results_data=d.SelectParser.select_to_array(this.form_field),this.is_multiple&&this.choices>0?(this.search_choices.find("li.search-choice").remove(),this.choices=0):this.is_multiple||this.selected_item.find("span").text(this.default_text),a="",g=this.results_data;for(e=0,f=g.length;e'+a("
        ").text(b.label).html()+""}return""},b.prototype.result_add_option=function(a){var b;if(!a.disabled){a.dom_id=this.container_id+"_o_"+a.array_index,b=a.selected&&this.is_multiple?[]:["active-result"],a.selected&&b.push("result-selected"),a.group_array_index!=null&&b.push("group-option");return'
      • '+a.html+"
      • "}return""},b.prototype.results_update_field=function(){this.result_clear_highlight(),this.result_single_selected=null;return this.results_build()},b.prototype.result_do_highlight=function(a){var b,c,d,e,f;if(a.length){this.result_clear_highlight(),this.result_highlight=a,this.result_highlight.addClass("highlighted"),d=parseInt(this.search_results.css("maxHeight"),10),f=this.search_results.scrollTop(),e=d+f,c=this.result_highlight.position().top+this.search_results.scrollTop(),b=c+this.result_highlight.outerHeight();if(b>=e)return this.search_results.scrollTop(b-d>0?b-d:0);if(c'+b.html+''),d=a("#"+c).find("a").first();return d.click(e(function(a){return this.choice_destroy_link_click(a)},this))},b.prototype.choice_destroy_link_click=function(b){b.preventDefault(),this.pending_destroy_click=!0;return this.choice_destroy(a(b.target))},b.prototype.choice_destroy=function(a){this.choices-=1,this.show_search_field_default(),this.is_multiple&&this.choices>0&&this.search_field.val().length<1&&this.results_hide(),this.result_deselect(a.attr("rel"));return a.parents("li").first().remove()},b.prototype.result_select=function(){var a,b,c,d;if(this.result_highlight){a=this.result_highlight,b=a.attr("id"),this.result_clear_highlight(),a.addClass("result-selected"),this.is_multiple?this.result_deactivate(a):this.result_single_selected=a,d=b.substr(b.lastIndexOf("_")+1),c=this.results_data[d],c.selected=!0,this.form_field.options[c.options_index].selected=!0,this.is_multiple?this.choice_build(c):this.selected_item.find("span").first().text(c.text),this.results_hide(),this.search_field.val(""),this.form_field_jq.trigger("change");return this.search_field_scale()}},b.prototype.result_activate=function(a){return a.addClass("active-result").show()},b.prototype.result_deactivate=function(a){return a.removeClass("active-result").hide()},b.prototype.result_deselect=function(b){var c,d;d=this.results_data[b],d.selected=!1,this.form_field.options[d.options_index].selected=!1,c=a("#"+this.container_id+"_o_"+b),c.removeClass("result-selected").addClass("active-result").show(),this.result_clear_highlight(),this.winnow_results(),this.form_field_jq.trigger("change");return this.search_field_scale()},b.prototype.results_search=function(a){return this.results_showing?this.winnow_results():this.results_show()},b.prototype.winnow_results=function(){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r;j=new Date,this.no_results_clear(),h=0,i=this.search_field.val()===this.default_text?"":a("
        ").text(a.trim(this.search_field.val())).html(),f=new RegExp("^"+i.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),"i"),m=new RegExp(i.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),"i"),r=this.results_data;for(n=0,p=r.length;n=0||c.html.indexOf("[")===0){e=c.html.replace(/\[|\]/g,"").split(" ");if(e.length)for(o=0,q=e.length;o"+c.html.substr(k+i.length),l=l.substr(0,k)+""+l.substr(k)):l=c.html,a("#"+g).html!==l&&a("#"+g).html(l),this.result_activate(a("#"+g)),c.group_array_index!=null&&a("#"+this.results_data[c.group_array_index].dom_id).show()):(this.result_highlight&&g===this.result_highlight.attr("id")&&this.result_clear_highlight(),this.result_deactivate(a("#"+g)))}}return h<1&&i.length?this.no_results(i):this.winnow_results_set_highlight()},b.prototype.winnow_results_clear=function(){var b,c,d,e,f;this.search_field.val(""),c=this.search_results.find("li"),f=[];for(d=0,e=c.length;dNo results match ""'),c.find("span").first().html(b);return this.search_results.append(c)},b.prototype.no_results_clear=function(){return this.search_results.find(".no-results").remove()},b.prototype.keydown_arrow=function(){var b,c;this.result_highlight?this.results_showing&&(c=this.result_highlight.nextAll("li.active-result").first(),c&&this.result_do_highlight(c)):(b=this.search_results.find("li.active-result").first(),b&&this.result_do_highlight(a(b)));if(!this.results_showing)return this.results_show()},b.prototype.keyup_arrow=function(){var a;if(!this.results_showing&&!this.is_multiple)return this.results_show();if(this.result_highlight){a=this.result_highlight.prevAll("li.active-result");if(a.length)return this.result_do_highlight(a.first());this.choices>0&&this.results_hide();return this.result_clear_highlight()}},b.prototype.keydown_backstroke=function(){if(this.pending_backstroke){this.choice_destroy(this.pending_backstroke.find("a").first());return this.clear_backstroke()}this.pending_backstroke=this.search_container.siblings("li.search-choice").last();return this.pending_backstroke.addClass("search-choice-focus")},b.prototype.clear_backstroke=function(){this.pending_backstroke&&this.pending_backstroke.removeClass("search-choice-focus");return this.pending_backstroke=null},b.prototype.keyup_checker=function(a){var b,c;b=(c=a.which)!=null?c:a.keyCode,this.search_field_scale();switch(b){case 8:if(this.is_multiple&&this.backstroke_length<1&&this.choices>0)return this.keydown_backstroke();if(!this.pending_backstroke){this.result_clear_highlight();return this.results_search()}break;case 13:a.preventDefault();if(this.results_showing)return this.result_select();break;case 27:if(this.results_showing)return this.results_hide();break;case 9:case 38:case 40:case 16:break;default:return this.results_search()}},b.prototype.keydown_checker=function(a){var b,c;b=(c=a.which)!=null?c:a.keyCode,this.search_field_scale(),b!==8&&this.pending_backstroke&&this.clear_backstroke();switch(b){case 8:this.backstroke_length=this.search_field.val().length;break;case 9:this.mouse_on_container=!1;break;case 13:a.preventDefault();break;case 38:a.preventDefault(),this.keyup_arrow();break;case 40:this.keydown_arrow()}},b.prototype.search_field_scale=function(){var b,c,d,e,f,g,h,i,j;if(this.is_multiple){d=0,h=0,f="position:absolute; left: -1000px; top: -1000px; display:none;",g=["font-size","font-style","font-weight","font-family","line-height","text-transform","letter-spacing"];for(i=0,j=g.length;i",{style:f}),c.text(this.search_field.val()),a("body").append(c),h=c.width()+25,c.remove(),h>this.f_width-10&&(h=this.f_width-10),this.search_field.css({width:h+"px"}),b=this.container.height();return this.dropdown.css({top:b+"px"})}},b.prototype.generate_field_id=function(){var a;a=this.generate_random_id(),this.form_field.id=a;return a},b.prototype.generate_random_id=function(){var b;b="sel"+this.generate_random_char()+this.generate_random_char()+this.generate_random_char();while(a("#"+b).length>0)b+=this.generate_random_char();return b},b.prototype.generate_random_char=function(){var a,b,c;a="0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZ",c=Math.floor(Math.random()*a.length);return b=a.substring(c,c+1)};return b}(),c=function(a){var b;return b=a.outerWidth()-a.width()},d.get_side_border_padding=c}).call(this),function(){var a;a=function(){function a(){this.options_index=0,this.parsed=[]}a.prototype.add_node=function(a){return a.nodeName==="OPTGROUP"?this.add_group(a):this.add_option(a)},a.prototype.add_group=function(a){var b,c,d,e,f,g;b=this.parsed.length,this.parsed.push({array_index:b,group:!0,label:a.label,children:0,disabled:a.disabled}),f=a.childNodes,g=[];for(d=0,e=f.length;d",{id:this.container_id,"class":"chzn-container"+(this.is_rtl?" chzn-rtl":""),style:"width: "+this.f_width+"px;"}),this.is_multiple?b.html('
          '):b.html(''+this.default_text+'
            '),this.form_field_jq.hide().after(b),this.container=a("#"+this.container_id),this.container.addClass("chzn-container-"+(this.is_multiple?"multi":"single")),!this.is_multiple&&this.form_field.options.length<=this.disable_search_threshold&&this.container.addClass("chzn-container-single-nosearch"),this.dropdown=this.container.find("div.chzn-drop").first(),d=this.container.height(),e=this.f_width-c(this.dropdown),this.dropdown.css({width:e+"px",top:d+"px"}),this.search_field=this.container.find("input").first(),this.search_results=this.container.find("ul.chzn-results").first(),this.search_field_scale(),this.search_no_results=this.container.find("li.no-results").first(),this.is_multiple?(this.search_choices=this.container.find("ul.chzn-choices").first(),this.search_container=this.container.find("li.search-field").first()):(this.search_container=this.container.find("div.chzn-search").first(),this.selected_item=this.container.find(".chzn-single").first(),f=e-c(this.search_container)-c(this.search_field),this.search_field.css({width:f+"px"})),this.results_build();return this.set_tab_index()},b.prototype.register_observers=function(){this.container.mousedown(e(function(a){return this.container_mousedown(a)},this)),this.container.mouseup(e(function(a){return this.container_mouseup(a)},this)),this.container.mouseenter(e(function(a){return this.mouse_enter(a)},this)),this.container.mouseleave(e(function(a){return this.mouse_leave(a)},this)),this.search_results.mouseup(e(function(a){return this.search_results_mouseup(a)},this)),this.search_results.mouseover(e(function(a){return this.search_results_mouseover(a)},this)),this.search_results.mouseout(e(function(a){return this.search_results_mouseout(a)},this)),this.form_field_jq.bind("liszt:updated",e(function(a){return this.results_update_field(a)},this)),this.search_field.blur(e(function(a){return this.input_blur(a)},this)),this.search_field.keyup(e(function(a){return this.keyup_checker(a)},this)),this.search_field.keydown(e(function(a){return this.keydown_checker(a)},this));if(this.is_multiple){this.search_choices.click(e(function(a){return this.choices_click(a)},this));return this.search_field.focus(e(function(a){return this.input_focus(a)},this))}},b.prototype.search_field_disabled=function(){this.is_disabled=this.form_field_jq.attr("disabled");if(this.is_disabled){this.container.addClass("chzn-disabled"),this.search_field.attr("disabled",!0),this.is_multiple||this.selected_item.unbind("focus",this.activate_action);return this.close_field()}this.container.removeClass("chzn-disabled"),this.search_field.attr("disabled",!1);if(!this.is_multiple)return this.selected_item.bind("focus",this.activate_action)},b.prototype.container_mousedown=function(b){var c;if(!this.is_disabled){c=b!=null?a(b.target).hasClass("search-choice-close"):!1,b&&b.type==="mousedown"&&b.stopPropagation();if(!this.pending_destroy_click&&!c){this.active_field?!this.is_multiple&&b&&(a(b.target)===this.selected_item||a(b.target).parents("a.chzn-single").length)&&(b.preventDefault(),this.results_toggle()):(this.is_multiple&&this.search_field.val(""),a(document).click(this.click_test_action),this.results_show());return this.activate_field()}return this.pending_destroy_click=!1}},b.prototype.container_mouseup=function(a){if(a.target.nodeName==="ABBR")return this.results_reset(a)},b.prototype.mouse_enter=function(){return this.mouse_on_container=!0},b.prototype.mouse_leave=function(){return this.mouse_on_container=!1},b.prototype.input_focus=function(a){if(!this.active_field)return setTimeout(e(function(){return this.container_mousedown()},this),50)},b.prototype.input_blur=function(a){if(!this.mouse_on_container){this.active_field=!1;return setTimeout(e(function(){return this.blur_test()},this),100)}},b.prototype.blur_test=function(a){if(!this.active_field&&this.container.hasClass("chzn-container-active"))return this.close_field()},b.prototype.close_field=function(){a(document).unbind("click",this.click_test_action),this.is_multiple||(this.selected_item.attr("tabindex",this.search_field.attr("tabindex")),this.search_field.attr("tabindex",-1)),this.active_field=!1,this.results_hide(),this.container.removeClass("chzn-container-active"),this.winnow_results_clear(),this.clear_backstroke(),this.show_search_field_default();return this.search_field_scale()},b.prototype.activate_field=function(){!this.is_multiple&&!this.active_field&&(this.search_field.attr("tabindex",this.selected_item.attr("tabindex")),this.selected_item.attr("tabindex",-1)),this.container.addClass("chzn-container-active"),this.active_field=!0,this.search_field.val(this.search_field.val());return this.search_field.focus()},b.prototype.test_active_click=function(b){return a(b.target).parents("#"+this.container_id).length?this.active_field=!0:this.close_field()},b.prototype.results_build=function(){var a,b,c,e,f,g;c=new Date,this.parsing=!0,this.results_data=d.SelectParser.select_to_array(this.form_field),this.is_multiple&&this.choices>0?(this.search_choices.find("li.search-choice").remove(),this.choices=0):this.is_multiple||this.selected_item.find("span").text(this.default_text),a="",g=this.results_data;for(e=0,f=g.length;e')));this.search_field_disabled(),this.show_search_field_default(),this.search_field_scale(),this.search_results.html(a);return this.parsing=!1},b.prototype.result_add_group=function(b){if(!b.disabled){b.dom_id=this.container_id+"_g_"+b.array_index;return'
          • '+a("
            ").text(b.label).html()+"
          • "}return""},b.prototype.result_add_option=function(a){var b,c;if(!a.disabled){a.dom_id=this.container_id+"_o_"+a.array_index,b=a.selected&&this.is_multiple?[]:["active-result"],a.selected&&b.push("result-selected"),a.group_array_index!=null&&b.push("group-option"),a.classes!==""&&b.push(a.classes),c=a.style.cssText!==""?' style="'+a.style+'"':"";return'
          • "+a.html+"
          • "}return""},b.prototype.results_update_field=function(){this.result_clear_highlight(),this.result_single_selected=null;return this.results_build()},b.prototype.result_do_highlight=function(a){var b,c,d,e,f;if(a.length){this.result_clear_highlight(),this.result_highlight=a,this.result_highlight.addClass("highlighted"),d=parseInt(this.search_results.css("maxHeight"),10),f=this.search_results.scrollTop(),e=d+f,c=this.result_highlight.position().top+this.search_results.scrollTop(),b=c+this.result_highlight.outerHeight();if(b>=e)return this.search_results.scrollTop(b-d>0?b-d:0);if(c'+b.html+''),d=a("#"+c).find("a").first();return d.click(e(function(a){return this.choice_destroy_link_click(a)},this))},b.prototype.choice_destroy_link_click=function(b){b.preventDefault();if(!this.is_disabled){this.pending_destroy_click=!0;return this.choice_destroy(a(b.target))}return b.stopPropagation},b.prototype.choice_destroy=function(a){this.choices-=1,this.show_search_field_default(),this.is_multiple&&this.choices>0&&this.search_field.val().length<1&&this.results_hide(),this.result_deselect(a.attr("rel"));return a.parents("li").first().remove()},b.prototype.results_reset=function(b){this.form_field.options[0].selected=!0,this.selected_item.find("span").text(this.default_text),this.show_search_field_default(),a(b.target).remove(),this.form_field_jq.trigger("change");if(this.active_field)return this.results_hide()},b.prototype.result_select=function(a){var b,c,d,e;if(this.result_highlight){b=this.result_highlight,c=b.attr("id"),this.result_clear_highlight(),this.is_multiple?this.result_deactivate(b):(this.search_results.find(".result-selected").removeClass("result-selected"),this.result_single_selected=b),b.addClass("result-selected"),e=c.substr(c.lastIndexOf("_")+1),d=this.results_data[e],d.selected=!0,this.form_field.options[d.options_index].selected=!0,this.is_multiple?this.choice_build(d):(this.selected_item.find("span").first().text(d.text),this.allow_single_deselect&&this.selected_item.find("span").first().after('')),(!a.metaKey||!this.is_multiple)&&this.results_hide(),this.search_field.val(""),this.form_field_jq.trigger("change");return this.search_field_scale()}},b.prototype.result_activate=function(a){return a.addClass("active-result")},b.prototype.result_deactivate=function(a){return a.removeClass("active-result")},b.prototype.result_deselect=function(b){var c,d;d=this.results_data[b],d.selected=!1,this.form_field.options[d.options_index].selected=!1,c=a("#"+this.container_id+"_o_"+b),c.removeClass("result-selected").addClass("active-result").show(),this.result_clear_highlight(),this.winnow_results(),this.form_field_jq.trigger("change");return this.search_field_scale()},b.prototype.results_search=function(a){return this.results_showing?this.winnow_results():this.results_show()},b.prototype.winnow_results=function(){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r;j=new Date,this.no_results_clear(),h=0,i=this.search_field.val()===this.default_text?"":a("
            ").text(a.trim(this.search_field.val())).html(),f=new RegExp("^"+i.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),"i"),m=new RegExp(i.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),"i"),r=this.results_data;for(n=0,p=r.length;n=0||c.html.indexOf("[")===0){e=c.html.replace(/\[|\]/g,"").split(" ");if(e.length)for(o=0,q=e.length;o"+c.html.substr(k+i.length),l=l.substr(0,k)+""+l.substr(k)):l=c.html,a("#"+g).html!==l&&a("#"+g).html(l),this.result_activate(a("#"+g)),c.group_array_index!=null&&a("#"+this.results_data[c.group_array_index].dom_id).show()):(this.result_highlight&&g===this.result_highlight.attr("id")&&this.result_clear_highlight(),this.result_deactivate(a("#"+g)))}}return h<1&&i.length?this.no_results(i):this.winnow_results_set_highlight()},b.prototype.winnow_results_clear=function(){var b,c,d,e,f;this.search_field.val(""),c=this.search_results.find("li"),f=[];for(d=0,e=c.length;d'+this.results_none_found+' ""'),c.find("span").first().html(b);return this.search_results.append(c)},b.prototype.no_results_clear=function(){return this.search_results.find(".no-results").remove()},b.prototype.keydown_arrow=function(){var b,c;this.result_highlight?this.results_showing&&(c=this.result_highlight.nextAll("li.active-result").first(),c&&this.result_do_highlight(c)):(b=this.search_results.find("li.active-result").first(),b&&this.result_do_highlight(a(b)));if(!this.results_showing)return this.results_show()},b.prototype.keyup_arrow=function(){var a;if(!this.results_showing&&!this.is_multiple)return this.results_show();if(this.result_highlight){a=this.result_highlight.prevAll("li.active-result");if(a.length)return this.result_do_highlight(a.first());this.choices>0&&this.results_hide();return this.result_clear_highlight()}},b.prototype.keydown_backstroke=function(){if(this.pending_backstroke){this.choice_destroy(this.pending_backstroke.find("a").first());return this.clear_backstroke()}this.pending_backstroke=this.search_container.siblings("li.search-choice").last();return this.pending_backstroke.addClass("search-choice-focus")},b.prototype.clear_backstroke=function(){this.pending_backstroke&&this.pending_backstroke.removeClass("search-choice-focus");return this.pending_backstroke=null},b.prototype.keyup_checker=function(a){var b,c;b=(c=a.which)!=null?c:a.keyCode,this.search_field_scale();switch(b){case 8:if(this.is_multiple&&this.backstroke_length<1&&this.choices>0)return this.keydown_backstroke();if(!this.pending_backstroke){this.result_clear_highlight();return this.results_search()}break;case 13:a.preventDefault();if(this.results_showing)return this.result_select(a);break;case 27:if(this.results_showing)return this.results_hide();break;case 9:case 38:case 40:case 16:case 91:case 17:break;default:return this.results_search()}},b.prototype.keydown_checker=function(a){var b,c;b=(c=a.which)!=null?c:a.keyCode,this.search_field_scale(),b!==8&&this.pending_backstroke&&this.clear_backstroke();switch(b){case 8:this.backstroke_length=this.search_field.val().length;break;case 9:this.mouse_on_container=!1;break;case 13:a.preventDefault();break;case 38:a.preventDefault(),this.keyup_arrow();break;case 40:this.keydown_arrow()}},b.prototype.search_field_scale=function(){var b,c,d,e,f,g,h,i,j;if(this.is_multiple){d=0,h=0,f="position:absolute; left: -1000px; top: -1000px; display:none;",g=["font-size","font-style","font-weight","font-family","line-height","text-transform","letter-spacing"];for(i=0,j=g.length;i",{style:f}),c.text(this.search_field.val()),a("body").append(c),h=c.width()+25,c.remove(),h>this.f_width-10&&(h=this.f_width-10),this.search_field.css({width:h+"px"}),b=this.container.height();return this.dropdown.css({top:b+"px"})}},b.prototype.generate_field_id=function(){var a;a=this.generate_random_id(),this.form_field.id=a;return a},b.prototype.generate_random_id=function(){var b;b="sel"+this.generate_random_char()+this.generate_random_char()+this.generate_random_char();while(a("#"+b).length>0)b+=this.generate_random_char();return b},b.prototype.generate_random_char=function(){var a,b,c;a="0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZ",c=Math.floor(Math.random()*a.length);return b=a.substring(c,c+1)};return b}(),c=function(a){var b;return b=a.outerWidth()-a.width()},d.get_side_border_padding=c}).call(this),function(){var a;a=function(){function a(){this.options_index=0,this.parsed=[]}a.prototype.add_node=function(a){return a.nodeName==="OPTGROUP"?this.add_group(a):this.add_option(a)},a.prototype.add_group=function(a){var b,c,d,e,f,g;b=this.parsed.length,this.parsed.push({array_index:b,group:!0,label:a.label,children:0,disabled:a.disabled}),f=a.childNodes,g=[];for(d=0,e=f.length;d Date: Thu, 24 Nov 2011 21:28:44 +0100 Subject: [PATCH 50/59] Bookmarks: make a soft-requirement of php-curl --- apps/bookmarks/bookmarksHelper.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/bookmarks/bookmarksHelper.php b/apps/bookmarks/bookmarksHelper.php index 44d4235b9b..ac512fbc24 100644 --- a/apps/bookmarks/bookmarksHelper.php +++ b/apps/bookmarks/bookmarksHelper.php @@ -56,6 +56,9 @@ function getURLMetadata($url) { } $metadata['url'] = $url; + if (!function_exists('curl_init')){ + return $metadata; + } $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); @@ -66,4 +69,4 @@ function getURLMetadata($url) { $metadata['title'] = htmlspecialchars_decode(@$match[1]); return $metadata; -} \ No newline at end of file +} From 43911d9a6f403f8531b5caa5ac843565d98a2417 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Thu, 24 Nov 2011 21:29:48 +0100 Subject: [PATCH 51/59] Template: output better html for select options --- lib/template.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/template.php b/lib/template.php index d1439199e1..881d2a27b1 100644 --- a/lib/template.php +++ b/lib/template.php @@ -121,7 +121,7 @@ function html_select_options($options, $selected, $params=array()) { $label = $label[$label_name]; } $select = in_array($value, $selected) ? ' selected="selected"' : ''; - $html .= ''; + $html .= ''."\n"; } return $html; } From 9701145f830d5d4286e8602d3b0f464914468c34 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Thu, 24 Nov 2011 21:34:50 +0100 Subject: [PATCH 52/59] Contacts: make type of phone property also multiselect in addproperty --- apps/contacts/js/interface.js | 1 + apps/contacts/templates/part.details.php | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/contacts/js/interface.js b/apps/contacts/js/interface.js index 24b512e532..ba1c0e536c 100644 --- a/apps/contacts/js/interface.js +++ b/apps/contacts/js/interface.js @@ -64,6 +64,7 @@ $(document).ready(function(){ else{ $('#contacts_generic').clone().insertAfter($('#contacts_addpropertyform .contacts_property_name')); } + $('#contacts_addpropertyform .contacts_property_data select').chosen(); }); $('#contacts_addpropertyform input[type="submit"]').live('click',function(){ diff --git a/apps/contacts/templates/part.details.php b/apps/contacts/templates/part.details.php index f5bd75809b..5e9a5c5674 100644 --- a/apps/contacts/templates/part.details.php +++ b/apps/contacts/templates/part.details.php @@ -75,7 +75,7 @@

            -

            From 6ce6cbf4894a34c4e5bf1dd13a75be661e5ab520 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Thu, 24 Nov 2011 21:35:41 +0100 Subject: [PATCH 53/59] Contacts: better label for saving a property --- apps/contacts/templates/part.setpropertyform.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/contacts/templates/part.setpropertyform.php b/apps/contacts/templates/part.setpropertyform.php index b0bf6645d5..d31bde009a 100644 --- a/apps/contacts/templates/part.setpropertyform.php +++ b/apps/contacts/templates/part.setpropertyform.php @@ -52,5 +52,5 @@

            - + From 53ff85e2ad631b03b8f1ee788d0019be9a8e8aa1 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Thu, 24 Nov 2011 21:36:14 +0100 Subject: [PATCH 54/59] Contacts: layout updates --- apps/contacts/css/styles.css | 3 ++- apps/contacts/templates/part.details.php | 4 ++-- apps/contacts/templates/part.setpropertyform.php | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/apps/contacts/css/styles.css b/apps/contacts/css/styles.css index e226c48ae5..f351589fe1 100644 --- a/apps/contacts/css/styles.css +++ b/apps/contacts/css/styles.css @@ -3,9 +3,10 @@ #contacts_deletecard {position:absolute;top:15px;right:0;} #contacts_details_list { list-style:none; } +#contacts_details_list li { overflow:visible; } #contacts_details_list li p.contacts_property_name { width:25%; float:left;text-align:right;padding-right:0.3em;color:#666; } #contacts_details_list li p.contacts_property_data, #contacts_details_list li ul.contacts_property_data { width:72%;float:left; } -#contacts_addproperty_button, #contacts_setproperty_button { margin-left:25%; } +#contacts_setproperty_button { margin-left:25%; } .contacts_property_data ul, ol.contacts_property_data { list-style:none; } .contacts_property_data li { overflow: hidden; } diff --git a/apps/contacts/templates/part.details.php b/apps/contacts/templates/part.details.php index 5e9a5c5674..f6d69005a0 100644 --- a/apps/contacts/templates/part.details.php +++ b/apps/contacts/templates/part.details.php @@ -29,12 +29,12 @@ +
            +

            -
            -