diff options
author | Michael Gapczynski <mtgap@owncloud.com> | 2012-07-11 20:25:59 -0400 |
---|---|---|
committer | Michael Gapczynski <mtgap@owncloud.com> | 2012-07-11 20:25:59 -0400 |
commit | 4bf13adff25f012c735931c0578b1f5d0790bdbe (patch) | |
tree | a7c5451ff25e2f39936ae984ceb5b3b9eb519088 /apps | |
parent | 88f4845ca33fd6f2988f230116e2190d15ab1866 (diff) | |
parent | 8890a4128015df0ad57101703d6c164ea54fe4ee (diff) | |
download | nextcloud-server-4bf13adff25f012c735931c0578b1f5d0790bdbe.tar.gz nextcloud-server-4bf13adff25f012c735931c0578b1f5d0790bdbe.zip |
Merge branch 'master' into share_api
Conflicts:
apps/contacts/lib/addressbook.php
apps/files_sharing/js/share.js
apps/files_sharing/sharedstorage.php
Diffstat (limited to 'apps')
187 files changed, 3452 insertions, 1211 deletions
diff --git a/apps/bookmarks/ajax/addBookmark.php b/apps/bookmarks/ajax/addBookmark.php index 6b5a0f71d4e..483716405a1 100644 --- a/apps/bookmarks/ajax/addBookmark.php +++ b/apps/bookmarks/ajax/addBookmark.php @@ -28,6 +28,8 @@ $RUNTIME_NOSETUPFS=true; // Check if we are a user OCP\JSON::checkLoggedIn(); +OCP\JSON::callCheck(); + OCP\JSON::checkAppEnabled('bookmarks'); require_once(OC_App::getAppPath('bookmarks').'/bookmarksHelper.php'); diff --git a/apps/bookmarks/ajax/delBookmark.php b/apps/bookmarks/ajax/delBookmark.php index 5a067701c9f..f40f02ebab7 100644 --- a/apps/bookmarks/ajax/delBookmark.php +++ b/apps/bookmarks/ajax/delBookmark.php @@ -28,6 +28,8 @@ $RUNTIME_NOSETUPFS=true; // Check if we are a user OCP\JSON::checkLoggedIn(); +OCP\JSON::callCheck(); + OCP\JSON::checkAppEnabled('bookmarks'); $id = $_POST['id']; diff --git a/apps/bookmarks/ajax/editBookmark.php b/apps/bookmarks/ajax/editBookmark.php index 439b680dc20..0b37d161af1 100644 --- a/apps/bookmarks/ajax/editBookmark.php +++ b/apps/bookmarks/ajax/editBookmark.php @@ -28,6 +28,8 @@ $RUNTIME_NOSETUPFS=true; // Check if we are a user OCP\JSON::checkLoggedIn(); +OCP\JSON::callCheck(); + OCP\JSON::checkAppEnabled('bookmarks'); $CONFIG_DBTYPE = OCP\Config::getSystemValue( "dbtype", "sqlite" ); diff --git a/apps/bookmarks/appinfo/migrate.php b/apps/bookmarks/appinfo/migrate.php index e7e572f52dc..f1353f1887e 100644 --- a/apps/bookmarks/appinfo/migrate.php +++ b/apps/bookmarks/appinfo/migrate.php @@ -40,8 +40,8 @@ class OC_Migration_Provider_Bookmarks extends OC_Migration_Provider{ $idmap = array(); while( $row = $results->fetchRow() ){ // Import each bookmark, saving its id into the map - $query = OCP\DB::prepare( "INSERT INTO *PREFIX*bookmarks(url, title, user_id, public, added, lastmodified) VALUES (?, ?, ?, ?, ?, ?)" ); - $query->execute( array( $row['url'], $row['title'], $this->uid, $row['public'], $row['added'], $row['lastmodified'] ) ); + $bookmarkquery = OCP\DB::prepare( "INSERT INTO *PREFIX*bookmarks(url, title, user_id, public, added, lastmodified) VALUES (?, ?, ?, ?, ?, ?)" ); + $bookmarkquery->execute( array( $row['url'], $row['title'], $this->uid, $row['public'], $row['added'], $row['lastmodified'] ) ); // Map the id $idmap[$row['id']] = OCP\DB::insertid(); } @@ -51,8 +51,8 @@ class OC_Migration_Provider_Bookmarks extends OC_Migration_Provider{ $results = $query->execute( array( $oldid ) ); while( $row = $results->fetchRow() ){ // Import the tags for this bookmark, using the new bookmark id - $query = OCP\DB::prepare( "INSERT INTO *PREFIX*bookmarks_tags(bookmark_id, tag) VALUES (?, ?)" ); - $query->execute( array( $newid, $row['tag'] ) ); + $tagquery = OCP\DB::prepare( "INSERT INTO *PREFIX*bookmarks_tags(bookmark_id, tag) VALUES (?, ?)" ); + $tagquery->execute( array( $newid, $row['tag'] ) ); } } // All done! diff --git a/apps/bookmarks/lib/bookmarks.php b/apps/bookmarks/lib/bookmarks.php index e0005968f31..86fba45a50c 100644 --- a/apps/bookmarks/lib/bookmarks.php +++ b/apps/bookmarks/lib/bookmarks.php @@ -145,5 +145,4 @@ class OC_Bookmarks_Bookmarks{ $result = $query->execute(); return true; } -} -?> +}
\ No newline at end of file diff --git a/apps/calendar/appinfo/app.php b/apps/calendar/appinfo/app.php index f1f2a26d87d..3c8cc76133e 100644 --- a/apps/calendar/appinfo/app.php +++ b/apps/calendar/appinfo/app.php @@ -8,12 +8,18 @@ OC::$CLASSPATH['OC_Connector_Sabre_CalDAV'] = 'apps/calendar/lib/connector_sabre OC::$CLASSPATH['OC_Calendar_Repeat'] = 'apps/calendar/lib/repeat.php'; OC::$CLASSPATH['OC_Calendar_Share'] = 'apps/calendar/lib/share.php'; OC::$CLASSPATH['OC_Search_Provider_Calendar'] = 'apps/calendar/lib/search.php'; +OC::$CLASSPATH['OC_Calendar_Export'] = 'apps/calendar/lib/export.php'; +//General Hooks OCP\Util::connectHook('OC_User', 'post_deleteUser', 'OC_Calendar_Hooks', 'deleteUser'); +//Repeating Events Hooks OCP\Util::connectHook('OC_Calendar', 'addEvent', 'OC_Calendar_Repeat', 'generate'); OCP\Util::connectHook('OC_Calendar', 'editEvent', 'OC_Calendar_Repeat', 'update'); OCP\Util::connectHook('OC_Calendar', 'deleteEvent', 'OC_Calendar_Repeat', 'clean'); OCP\Util::connectHook('OC_Calendar', 'moveEvent', 'OC_Calendar_Repeat', 'update'); OCP\Util::connectHook('OC_Calendar', 'deleteCalendar', 'OC_Calendar_Repeat', 'cleanCalendar'); +//Sharing Hooks +OCP\Util::connectHook('OC_Calendar', 'deleteEvent', 'OC_Calendar_Share', 'post_eventdelete'); +OCP\Util::connectHook('OC_Calendar', 'deleteCalendar', 'OC_Calendar_Share', 'post_caldelete'); OCP\Util::addscript('calendar','loader'); OCP\Util::addscript("3rdparty", "chosen/chosen.jquery.min"); OCP\Util::addStyle("3rdparty", "chosen/chosen"); diff --git a/apps/calendar/appinfo/remote.php b/apps/calendar/appinfo/remote.php index 7ab546245f6..e8f9e80c7a8 100644 --- a/apps/calendar/appinfo/remote.php +++ b/apps/calendar/appinfo/remote.php @@ -34,6 +34,6 @@ $server->addPlugin(new Sabre_DAV_Auth_Plugin($authBackend,'ownCloud')); $server->addPlugin(new Sabre_CalDAV_Plugin()); $server->addPlugin(new Sabre_DAVACL_Plugin()); $server->addPlugin(new Sabre_DAV_Browser_Plugin(false)); // Show something in the Browser, but no upload - +$server->addPlugin(new Sabre_CalDAV_ICSExportPlugin()); // And off we go! $server->exec(); diff --git a/apps/calendar/export.php b/apps/calendar/export.php index 5780d191a57..1374c49cc0d 100644 --- a/apps/calendar/export.php +++ b/apps/calendar/export.php @@ -5,35 +5,26 @@ * later. * See the COPYING-README file. */ - - OCP\User::checkLoggedIn(); OCP\App::checkAppEnabled('calendar'); $cal = isset($_GET['calid']) ? $_GET['calid'] : NULL; $event = isset($_GET['eventid']) ? $_GET['eventid'] : NULL; -$nl = "\r\n"; if(isset($cal)){ $calendar = OC_Calendar_App::getCalendar($cal, true); if(!$calendar){ header('HTTP/1.0 404 Not Found'); exit; } - $calobjects = OC_Calendar_Object::all($cal); header('Content-Type: text/Calendar'); - header('Content-Disposition: inline; filename=' . $calendar['displayname'] . '.ics'); - foreach($calobjects as $calobject){ - echo $calobject['calendardata'] . $nl; - } + header('Content-Disposition: inline; filename=' . str_replace(' ', '-', $calendar['displayname']) . '.ics'); + echo OC_Calendar_Export::export($cal, OC_Calendar_Export::CALENDAR); }elseif(isset($event)){ $data = OC_Calendar_App::getEventObject($_GET['eventid'], true); if(!$data){ header('HTTP/1.0 404 Not Found'); exit; } - $calendarid = $data['calendarid']; - $calendar = OC_Calendar_App::getCalendar($calendarid); header('Content-Type: text/Calendar'); - header('Content-Disposition: inline; filename=' . $data['summary'] . '.ics'); - echo $data['calendardata']; -} -?> + header('Content-Disposition: inline; filename=' . str_replace(' ', '-', $data['summary']) . '.ics'); + echo OC_Calendar_Export::export($event, OC_Calendar_Export::EVENT); +}
\ No newline at end of file diff --git a/apps/calendar/js/calendar.js b/apps/calendar/js/calendar.js index e17f88e38be..004b2386fb1 100644 --- a/apps/calendar/js/calendar.js +++ b/apps/calendar/js/calendar.js @@ -547,7 +547,7 @@ Calendar={ $('#share_user').live('change', function(){ if($('#sharewithuser_' + $('#share_user option:selected').text()).length == 0){ Calendar.UI.Share.share(Calendar.UI.Share.currentid, Calendar.UI.Share.idtype, $('#share_user option:selected').text(), 'user'); - var newitem = '<li id="sharewithuser_' + $('#share_user option:selected').text() +'"><input type="checkbox" width="12px" style="visibility:hidden;" title="' + $('#share_user option:selected').text() + '">' + $('#share_user option:selected').text() + '<img src="' + oc_webroot + '/core/img/actions/delete.svg" class="svg action" style="display:none;float:right;"></li>'; + var newitem = '<li id="sharewithuser_' + $('#share_user option:selected').text() +'"><input type="checkbox" width="12px" style="visibility:hidden;" title="' + $('#share_user option:selected').text() + '">' + $('#share_user option:selected').text() + '<img src="' + OC.imagePath('core', 'actions/delete.svg') + '" class="svg action" style="display:none;float:right;"></li>'; $('#sharewithuser_list').append(newitem); $('#sharewithuser_' + $('#share_user option:selected').text() + ' > img').click(function(){ $('#share_user option[value="' + $(this).parent().text() + '"]').removeAttr('disabled'); @@ -562,7 +562,7 @@ Calendar={ $('#share_group').live('change', function(){ if($('#sharewithgroup_' + $('#share_group option:selected').text()).length == 0){ Calendar.UI.Share.share(Calendar.UI.Share.currentid, Calendar.UI.Share.idtype, $('#share_group option:selected').text(), 'group'); - var newitem = '<li id="sharewithgroup_' + $('#share_group option:selected').text() +'"><input type="checkbox" width="12px" style="visibility:hidden;" title="' + $('#share_group option:selected').text() + '">' + $('#share_group option:selected').text() + '<img src="' + oc_webroot + '/core/img/actions/delete.svg" class="svg action" style="display:none;float:right;"></li>'; + var newitem = '<li id="sharewithgroup_' + $('#share_group option:selected').text() +'"><input type="checkbox" width="12px" style="visibility:hidden;" title="' + $('#share_group option:selected').text() + '">' + $('#share_group option:selected').text() + '<img src="' + OC.imagePath('core', 'actions/delete.svg') + '" class="svg action" style="display:none;float:right;"></li>'; $('#sharewithgroup_list').append(newitem); $('#sharewithgroup_' + $('#share_group option:selected').text() + ' > img').click(function(){ $('#share_group option[value="' + $(this).parent().text() + '"]').removeAttr('disabled'); @@ -870,7 +870,7 @@ $(document).ready(function(){ eventDrop: Calendar.UI.moveEvent, eventResize: Calendar.UI.resizeEvent, eventRender: function(event, element) { - element.find('.fc-event-title').html(element.find('.fc-event-title').html()); + element.find('.fc-event-title').html(element.find('.fc-event-title').text()); element.tipsy({ className: 'tipsy-event', opacity: 0.9, diff --git a/apps/calendar/js/loader.js b/apps/calendar/js/loader.js index 0fc5018e89c..cef95afc3aa 100644 --- a/apps/calendar/js/loader.js +++ b/apps/calendar/js/loader.js @@ -44,7 +44,7 @@ Calendar_Import={ $('#newcalendar').attr('readonly', 'readonly'); $('#calendar').attr('disabled', 'disabled'); var progresskey = $('#progresskey').val(); - $.post(OC.filePath('calendar', 'ajax/import', 'import.php') + '?progresskey='+progresskey, {method: String (method), calname: String (calname), path: String (path), file: String (filename), id: String (calid)}, function(data){ + $.post(OC.filePath('calendar', 'ajax/import', 'import.php'), {progresskey: progresskey, method: String (method), calname: String (calname), path: String (path), file: String (filename), id: String (calid)}, function(data){ if(data.status == 'success'){ $('#progressbar').progressbar('option', 'value', 100); $('#import_done').css('display', 'block'); diff --git a/apps/calendar/lib/app.php b/apps/calendar/lib/app.php index 344c89f36b0..1a13f2958c0 100644 --- a/apps/calendar/lib/app.php +++ b/apps/calendar/lib/app.php @@ -13,22 +13,22 @@ OC_Calendar_App::$tz = OCP\Config::getUserValue(OCP\USER::getUser(), 'calendar', class OC_Calendar_App{ const CALENDAR = 'calendar'; const EVENT = 'event'; - /* + /** * @brief language object for calendar app */ public static $l10n; - /* + /** * @brief categories of the user */ protected static $categories = null; - /* + /** * @brief timezone of the user */ public static $tz; - /* + /** * @brief returns informations about a calendar * @param int $id - id of the calendar * @param bool $security - check access rights or not @@ -53,7 +53,7 @@ class OC_Calendar_App{ return $calendar; } - /* + /** * @brief returns informations about an event * @param int $id - id of the event * @param bool $security - check access rights or not @@ -79,7 +79,7 @@ class OC_Calendar_App{ return $event; } - /* + /** * @brief returns the parsed calendar data * @param int $id - id of the event * @param bool $security - check access rights or not @@ -97,7 +97,7 @@ class OC_Calendar_App{ return $vobject; } - /* + /** * @brief checks if an event was edited and dies if it was * @param (object) $vevent - vevent object of the event * @param (int) $lastmodified - time of last modification as unix timestamp @@ -112,7 +112,7 @@ class OC_Calendar_App{ return true; } - /* + /** * @brief returns the default categories of ownCloud * @return (array) $categories */ @@ -136,7 +136,7 @@ class OC_Calendar_App{ ); } - /* + /** * @brief returns the vcategories object of the user * @return (object) $vcategories */ @@ -147,7 +147,7 @@ class OC_Calendar_App{ return self::$categories; } - /* + /** * @brief returns the categories of the vcategories object * @return (array) $categories */ @@ -202,12 +202,16 @@ class OC_Calendar_App{ self::getVCategories()->loadFromVObject($object, true); } } - + + /** + * @brief returns the options for the repeat rule of an repeating event + * @return array - valid inputs for the repeat rule of an repeating event + */ public static function getRepeatOptions(){ return OC_Calendar_Object::getRepeatOptions(self::$l10n); } - /* + /** * @brief returns the options for the end of an repeating event * @return array - valid inputs for the end of an repeating events */ @@ -215,7 +219,7 @@ class OC_Calendar_App{ return OC_Calendar_Object::getEndOptions(self::$l10n); } - /* + /** * @brief returns the options for an monthly repeating event * @return array - valid inputs for monthly repeating events */ @@ -223,7 +227,7 @@ class OC_Calendar_App{ return OC_Calendar_Object::getMonthOptions(self::$l10n); } - /* + /** * @brief returns the options for an weekly repeating event * @return array - valid inputs for weekly repeating events */ @@ -231,7 +235,7 @@ class OC_Calendar_App{ return OC_Calendar_Object::getWeeklyOptions(self::$l10n); } - /* + /** * @brief returns the options for an yearly repeating event * @return array - valid inputs for yearly repeating events */ @@ -239,7 +243,7 @@ class OC_Calendar_App{ return OC_Calendar_Object::getYearOptions(self::$l10n); } - /* + /** * @brief returns the options for an yearly repeating event which occurs on specific days of the year * @return array - valid inputs for yearly repeating events */ @@ -247,7 +251,7 @@ class OC_Calendar_App{ return OC_Calendar_Object::getByYearDayOptions(); } - /* + /** * @brief returns the options for an yearly repeating event which occurs on specific month of the year * @return array - valid inputs for yearly repeating events */ @@ -255,7 +259,7 @@ class OC_Calendar_App{ return OC_Calendar_Object::getByMonthOptions(self::$l10n); } - /* + /** * @brief returns the options for an yearly repeating event which occurs on specific week numbers of the year * @return array - valid inputs for yearly repeating events */ @@ -263,7 +267,7 @@ class OC_Calendar_App{ return OC_Calendar_Object::getByWeekNoOptions(); } - /* + /** * @brief returns the options for an yearly or monthly repeating event which occurs on specific days of the month * @return array - valid inputs for yearly or monthly repeating events */ @@ -271,7 +275,7 @@ class OC_Calendar_App{ return OC_Calendar_Object::getByMonthDayOptions(); } - /* + /** * @brief returns the options for an monthly repeating event which occurs on specific weeks of the month * @return array - valid inputs for monthly repeating events */ @@ -279,7 +283,7 @@ class OC_Calendar_App{ return OC_Calendar_Object::getWeekofMonth(self::$l10n); } - /* + /** * @brief checks the access for a calendar / an event * @param (int) $id - id of the calendar / event * @param (string) $type - type of the id (calendar/event) @@ -320,7 +324,7 @@ class OC_Calendar_App{ } } - /* + /** * @brief analyses the parameter for calendar parameter and returns the objects * @param (string) $calendarid - calendarid * @param (int) $start - unixtimestamp of start @@ -360,7 +364,7 @@ class OC_Calendar_App{ return $events; } - /* + /** * @brief generates the output for an event which will be readable for our js * @param (mixed) $event - event object / array * @param (int) $start - DateTime object of start @@ -368,12 +372,14 @@ class OC_Calendar_App{ * @return (array) $output - readable output */ public static function generateEventOutput($event, $start, $end){ - if(isset($event['calendardata'])){ - $object = OC_VObject::parse($event['calendardata']); - $vevent = $object->VEVENT; - }else{ - $vevent = $event['vevent']; + if(!isset($event['calendardata']) && !isset($event['vevent'])){ + return false; + } + if(!isset($event['calendardata']) && isset($event['vevent'])){ + $event['calendardata'] = "BEGIN:VCALENDAR\nVERSION:2.0\nPRODID:ownCloud's Internal iCal System\n" . $event['vevent']->serialize() . "END:VCALENDAR"; } + $object = OC_VObject::parse($event['calendardata']); + $vevent = $object->VEVENT; $return = array(); $id = $event['id']; $allday = ($vevent->DTSTART->getDateType() == Sabre_VObject_Element_DateTime::DATE)?true:false; @@ -404,7 +410,7 @@ class OC_Calendar_App{ $return[] = array_merge($staticoutput, $dynamicoutput); } }else{ - if(OC_Calendar_Object::isrepeating($id)){ + if(OC_Calendar_Object::isrepeating($id) || $event['repeating'] == 1){ $object->expand($start, $end); } foreach($object->getComponents() as $singleevent){ @@ -412,7 +418,7 @@ class OC_Calendar_App{ continue; } $dynamicoutput = OC_Calendar_Object::generateStartEndDate($singleevent->DTSTART, OC_Calendar_Object::getDTEndFromVEvent($singleevent), $allday, self::$tz); - $return[] = array_merge($staticoutput, $dynamicoutput); + $return[] = array_merge($staticoutput, $dynamicoutput); } } return $return; diff --git a/apps/calendar/lib/calendar.php b/apps/calendar/lib/calendar.php index 1bfab5cd645..128b55c48e9 100644 --- a/apps/calendar/lib/calendar.php +++ b/apps/calendar/lib/calendar.php @@ -5,24 +5,11 @@ * later. * See the COPYING-README file. */ -/* +/** * * The following SQL statement is just a help for developers and will not be * executed! * - * CREATE TABLE calendar_objects ( - * id INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, - * calendarid INTEGER UNSIGNED NOT NULL, - * objecttype VARCHAR(40) NOT NULL, - * startdate DATETIME, - * enddate DATETIME, - * repeating INT(1), - * summary VARCHAR(255), - * calendardata TEXT, - * uri VARCHAR(100), - * lastmodified INT(11) - * ); - * * CREATE TABLE calendar_calendars ( * id INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, * userid VARCHAR(255), @@ -35,6 +22,7 @@ * timezone TEXT, * components VARCHAR(20) * ); + * */ /** @@ -212,7 +200,20 @@ class OC_Calendar_Calendar{ return true; } - + + /** + * @brief merges two calendars + * @param integer $id1 + * @param integer $id2 + * @return boolean + */ + public static function mergeCalendar($id1, $id2){ + $stmt = OCP\DB::prepare('UPDATE *PREFIX*calendar_objects SET calendarid = ? WHERE calendarid = ?'); + $stmt->execute(array($id1, $id2)); + self::touchCalendar($id1); + self::deleteCalendar($id2); + } + /** * @brief Creates a URI for Calendar * @param string $name name of the calendar @@ -238,6 +239,11 @@ class OC_Calendar_Calendar{ list($prefix,$userid) = Sabre_DAV_URLUtil::splitPath($principaluri); return $userid; } + + /** + * @brief returns the possible color for calendars + * @return array + */ public static function getCalendarColorOptions(){ return array( '#ff0000', // "Red" @@ -251,6 +257,11 @@ class OC_Calendar_Calendar{ ); } + /** + * @brief generates the Event Source Info for our JS + * @param array $calendar calendar data + * @return array + */ public static function getEventSourceInfo($calendar){ return array( 'url' => OCP\Util::linkTo('calendar', 'ajax/events.php').'?calendar_id='.$calendar['id'], diff --git a/apps/calendar/lib/export.php b/apps/calendar/lib/export.php new file mode 100644 index 00000000000..8f26891f366 --- /dev/null +++ b/apps/calendar/lib/export.php @@ -0,0 +1,94 @@ +<?php +/** + * Copyright (c) 2012 Georg Ehrke <ownclouddev@georgswebsite.de> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ +/** + * This class does export and converts all times to UTC + */ +class OC_Calendar_Export{ + /** + * @brief Use one of these constants as second parameter if you call OC_Calendar_Export::export() + */ + const CALENDAR = 'calendar'; + const EVENT = 'event'; + + /** + * @brief export a calendar or an event + * @param integer $id id of calendar / event + * @param string $type use OC_Calendar_Export constants + * @return string + */ + public static function export($id, $type){ + if($type == self::EVENT){ + $return = self::event($id); + }else{ + $return = self::calendar($id); + } + return self::fixLineBreaks($return); + } + + /** + * @brief exports a calendar and convert all times to UTC + * @param integer $id id of the calendar + * @return string + */ + private static function calendar($id){ + $events = OC_Calendar_Object::all($id); + $calendar = OC_Calendar_Calendar::find($id); + $return = "BEGIN:VCALENDAR\nVERSION:2.0\nPRODID:ownCloud Calendar " . OCP\App::getAppVersion('calendar') . "\nX-WR-CALNAME:" . $calendar['displayname'] . "\n"; + foreach($events as $event){ + $return .= self::generateEvent($event); + } + $return .= "END:VCALENDAR"; + return $return; + } + + /** + * @brief exports an event and convert all times to UTC + * @param integer $id id of the event + * @return string + */ + private static function event($id){ + $event = OC_Calendar_Object::find($id); + $return = "BEGIN:VCALENDAR\nVERSION:2.0\nPRODID:ownCloud Calendar " . OCP\App::getAppVersion('calendar') . "\nX-WR-CALNAME:" . $event['summary'] . "\n"; + $return .= self::generateEvent($event); + $return .= "END:VCALENDAR"; + return $return; + } + + /** + * @brief generates the VEVENT with UTC dates + * @param array $event + * @return string + */ + private static function generateEvent($event){ + $object = OC_VObject::parse($event['calendardata']); + $dtstart = $object->VEVENT->DTSTART; + $start_dt = $dtstart->getDateTime(); + $dtend = OC_Calendar_Object::getDTEndFromVEvent($object->VEVENT); + $end_dt = $dtend->getDateTime(); + if($dtstart->getDateType() !== Sabre_VObject_Element_DateTime::DATE){ + $start_dt->setTimezone(new DateTimeZone('UTC')); + $end_dt->setTimezone(new DateTimeZone('UTC')); + $object->VEVENT->setDateTime('DTSTART', $start_dt, Sabre_VObject_Property_DateTime::UTC); + $object->VEVENT->setDateTime('DTEND', $end_dt, Sabre_VObject_Property_DateTime::UTC); + } + return $object->VEVENT->serialize(); + } + + /** + * @brief fixes new line breaks + * (fixes problems with Apple iCal) + * @param string $string to fix + * @return string + */ + private static function fixLineBreaks($string){ + $string = str_replace("\r\n", "\n", $string); + $string = str_replace("\r", "\n", $string); + $string = str_replace("\n", "\r\n", $string); + return $string; + } +} diff --git a/apps/calendar/lib/object.php b/apps/calendar/lib/object.php index 0531a56fc50..140542bf4fb 100644 --- a/apps/calendar/lib/object.php +++ b/apps/calendar/lib/object.php @@ -1,10 +1,31 @@ <?php /** * Copyright (c) 2011 Jakob Sack <mail@jakobsack.de> + * Copyright (c) 2012 Bart Visscher <bartv@thisnet.nl> + * Copyright (c) 2012 Georg Ehrke <ownclouddev at georgswebsite dot de> * This file is licensed under the Affero General Public License version 3 or * later. * See the COPYING-README file. */ + /** + * + * The following SQL statement is just a help for developers and will not be + * executed! + * + * CREATE TABLE calendar_objects ( + * id INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, + * calendarid INTEGER UNSIGNED NOT NULL, + * objecttype VARCHAR(40) NOT NULL, + * startdate DATETIME, + * enddate DATETIME, + * repeating INT(1), + * summary VARCHAR(255), + * calendardata TEXT, + * uri VARCHAR(100), + * lastmodified INT(11) + * ); + * + */ /** * This class manages our calendar objects @@ -311,7 +332,12 @@ class OC_Calendar_Object{ public static function getUTCforMDB($datetime){ return date('Y-m-d H:i', $datetime->format('U') - $datetime->getOffset()); } - + + /** + * @brief returns the DTEND of an $vevent object + * @param object $vevent vevent object + * @return object + */ public static function getDTEndFromVEvent($vevent){ if ($vevent->DTEND) { $dtend = $vevent->DTEND; @@ -336,9 +362,12 @@ class OC_Calendar_Object{ } return $dtend; } - - public static function getRepeatOptions($l10n) - { + + /** + * @brief returns the options for the repeat rule of an repeating event + * @return array - valid inputs for the repeat rule of an repeating event + */ + public static function getRepeatOptions($l10n){ return array( 'doesnotrepeat' => $l10n->t('Does not repeat'), 'daily' => $l10n->t('Daily'), @@ -349,26 +378,35 @@ class OC_Calendar_Object{ 'yearly' => $l10n->t('Yearly') ); } - - public static function getEndOptions($l10n) - { + + /** + * @brief returns the options for the end of an repeating event + * @return array - valid inputs for the end of an repeating events + */ + public static function getEndOptions($l10n){ return array( 'never' => $l10n->t('never'), 'count' => $l10n->t('by occurrences'), 'date' => $l10n->t('by date') ); } - - public static function getMonthOptions($l10n) - { + + /** + * @brief returns the options for an monthly repeating event + * @return array - valid inputs for monthly repeating events + */ + public static function getMonthOptions($l10n){ return array( 'monthday' => $l10n->t('by monthday'), 'weekday' => $l10n->t('by weekday') ); } - - public static function getWeeklyOptions($l10n) - { + + /** + * @brief returns the options for an weekly repeating event + * @return array - valid inputs for weekly repeating events + */ + public static function getWeeklyOptions($l10n){ return array( 'MO' => $l10n->t('Monday'), 'TU' => $l10n->t('Tuesday'), @@ -379,9 +417,12 @@ class OC_Calendar_Object{ 'SU' => $l10n->t('Sunday') ); } - - public static function getWeekofMonth($l10n) - { + + /** + * @brief returns the options for an monthly repeating event which occurs on specific weeks of the month + * @return array - valid inputs for monthly repeating events + */ + public static function getWeekofMonth($l10n){ return array( 'auto' => $l10n->t('events week of month'), '1' => $l10n->t('first'), @@ -392,7 +433,11 @@ class OC_Calendar_Object{ '-1' => $l10n->t('last') ); } - + + /** + * @brief returns the options for an yearly repeating event which occurs on specific days of the year + * @return array - valid inputs for yearly repeating events + */ public static function getByYearDayOptions(){ $return = array(); foreach(range(1,366) as $num){ @@ -400,7 +445,11 @@ class OC_Calendar_Object{ } return $return; } - + + /** + * @brief returns the options for an yearly or monthly repeating event which occurs on specific days of the month + * @return array - valid inputs for yearly or monthly repeating events + */ public static function getByMonthDayOptions(){ $return = array(); foreach(range(1,31) as $num){ @@ -408,7 +457,11 @@ class OC_Calendar_Object{ } return $return; } - + + /** + * @brief returns the options for an yearly repeating event which occurs on specific month of the year + * @return array - valid inputs for yearly repeating events + */ public static function getByMonthOptions($l10n){ return array( '1' => $l10n->t('January'), @@ -425,7 +478,11 @@ class OC_Calendar_Object{ '12' => $l10n->t('December') ); } - + + /** + * @brief returns the options for an yearly repeating event + * @return array - valid inputs for yearly repeating events + */ public static function getYearOptions($l10n){ return array( 'bydate' => $l10n->t('by events date'), @@ -434,13 +491,21 @@ class OC_Calendar_Object{ 'bydaymonth' => $l10n->t('by day and month') ); } - + + /** + * @brief returns the options for an yearly repeating event which occurs on specific week numbers of the year + * @return array - valid inputs for yearly repeating events + */ public static function getByWeekNoOptions(){ return range(1, 52); } - - public static function validateRequest($request) - { + + /** + * @brief validates a request + * @param array $request + * @return mixed (array / boolean) + */ + public static function validateRequest($request){ $errnum = 0; $errarr = array('title'=>'false', 'cal'=>'false', 'from'=>'false', 'fromtime'=>'false', 'to'=>'false', 'totime'=>'false', 'endbeforestart'=>'false'); if($request['title'] == ''){ @@ -587,17 +652,24 @@ class OC_Calendar_Object{ } return false; } - - protected static function checkTime($time) - { + + /** + * @brief validates time + * @param string $time + * @return boolean + */ + protected static function checkTime($time){ list($hours, $minutes) = explode(':', $time); return empty($time) || $hours < 0 || $hours > 24 || $minutes < 0 || $minutes > 60; } - - public static function createVCalendarFromRequest($request) - { + + /** + * @brief creates an VCalendar Object from the request data + * @param array $request + * @return object created $vcalendar + */ public static function createVCalendarFromRequest($request){ $vcalendar = new OC_VObject('VCALENDAR'); $vcalendar->add('PRODID', 'ownCloud Calendar'); $vcalendar->add('VERSION', '2.0'); @@ -610,9 +682,14 @@ class OC_Calendar_Object{ $vevent->setUID(); return self::updateVCalendarFromRequest($request, $vcalendar); } - - public static function updateVCalendarFromRequest($request, $vcalendar) - { + + /** + * @brief updates an VCalendar Object from the request data + * @param array $request + * @param object $vcalendar + * @return object updated $vcalendar + */ + public static function updateVCalendarFromRequest($request, $vcalendar){ $title = $request["title"]; $location = $request["location"]; $categories = $request["categories"]; @@ -792,29 +869,52 @@ class OC_Calendar_Object{ $vevent->setString('DESCRIPTION', $description); $vevent->setString('CATEGORIES', $categories); - /*if($repeat == "true"){ + /**if($repeat == "true"){ $vevent->RRULE = $repeat; }*/ return $vcalendar; } - + + /** + * @brief returns the owner of an object + * @param integer $id + * @return string + */ public static function getowner($id){ $event = self::find($id); $cal = OC_Calendar_Calendar::find($event['calendarid']); return $cal['userid']; } + /** + * @brief returns the calendarid of an object + * @param integer $id + * @return integer + */ public static function getCalendarid($id){ $event = self::find($id); return $event['calendarid']; } - + + /** + * @brief checks if an object is repeating + * @param integer $id + * @return boolean + */ public static function isrepeating($id){ $event = self::find($id); return ($event['repeating'] == 1)?true:false; } - + + /** + * @brief converts the start_dt and end_dt to a new timezone + * @param object $dtstart + * @param object $dtend + * @param boolean $allday + * @param string $tz + * @return array + */ public static function generateStartEndDate($dtstart, $dtend, $allday, $tz){ $start_dt = $dtstart->getDateTime(); $end_dt = $dtend->getDateTime(); diff --git a/apps/calendar/lib/repeat.php b/apps/calendar/lib/repeat.php index 204f96a5a2a..b9fbee8fe0a 100644 --- a/apps/calendar/lib/repeat.php +++ b/apps/calendar/lib/repeat.php @@ -5,12 +5,12 @@ * later. * See the COPYING-README file. */ -/* +/** * This class manages the caching of repeating events * Events will be cached for the current year ± 5 years */ class OC_Calendar_Repeat{ - /* + /** * @brief returns the cache of an event * @param (int) $id - id of the event * @return (array) @@ -24,7 +24,7 @@ class OC_Calendar_Repeat{ } return $return; } - /* + /** * @brief returns the cache of an event in a specific peroid * @param (int) $id - id of the event * @param (DateTime) $from - start for period in UTC @@ -44,7 +44,7 @@ class OC_Calendar_Repeat{ } return $return; } - /* + /** * @brief returns the cache of all repeating events of a calendar * @param (int) $id - id of the calendar * @return (array) @@ -58,7 +58,7 @@ class OC_Calendar_Repeat{ } return $return; } - /* + /** * @brief returns the cache of all repeating events of a calendar in a specific period * @param (int) $id - id of the event * @param (string) $from - start for period in UTC @@ -78,7 +78,7 @@ class OC_Calendar_Repeat{ } return $return; } - /* + /** * @brief generates the cache the first time * @param (int) id - id of the event * @return (bool) @@ -104,7 +104,7 @@ class OC_Calendar_Repeat{ } return true; } - /* + /** * @brief generates the cache the first time for all repeating event of an calendar * @param (int) id - id of the calendar * @return (bool) @@ -116,7 +116,7 @@ class OC_Calendar_Repeat{ } return true; } - /* + /** * @brief updates an event that is already cached * @param (int) id - id of the event * @return (bool) @@ -126,7 +126,7 @@ class OC_Calendar_Repeat{ self::generate($id); return true; } - /* + /** * @brief updates all repating events of a calendar that are already cached * @param (int) id - id of the calendar * @return (bool) @@ -136,7 +136,7 @@ class OC_Calendar_Repeat{ self::generateCalendar($id); return true; } - /* + /** * @brief checks if an event is already cached * @param (int) id - id of the event * @return (bool) @@ -148,7 +148,7 @@ class OC_Calendar_Repeat{ return false; } } - /* + /** * @brief checks if an event is already cached in a specific period * @param (int) id - id of the event * @param (DateTime) $from - start for period in UTC @@ -163,7 +163,7 @@ class OC_Calendar_Repeat{ } } - /* + /** * @brief checks if a whole calendar is already cached * @param (int) id - id of the calendar * @return (bool) @@ -183,7 +183,7 @@ class OC_Calendar_Repeat{ return true; } } - /* + /** * @brief removes the cache of an event * @param (int) id - id of the event * @return (bool) @@ -192,7 +192,7 @@ class OC_Calendar_Repeat{ $stmt = OCP\DB::prepare('DELETE FROM *PREFIX*calendar_repeat WHERE eventid = ?'); $stmt->execute(array($id)); } - /* + /** * @brief removes the cache of all events of a calendar * @param (int) id - id of the calendar * @return (bool) diff --git a/apps/calendar/lib/share.php b/apps/calendar/lib/share.php index 54c531892f0..4fe88171403 100644 --- a/apps/calendar/lib/share.php +++ b/apps/calendar/lib/share.php @@ -5,17 +5,17 @@ * later. * See the COPYING-README file. */ -/* +/** * This class manages shared calendars */ class OC_Calendar_Share{ const CALENDAR = 'calendar'; const EVENT = 'event'; - /* + /** * @brief: returns informations about all calendar or events which users are sharing with the user - userid - * @param: (string) $userid - id of the user - * @param: (string) $type - use const self::CALENDAR or self::EVENT - * @return: (array) $return - information about calendars + * @param: string $userid - id of the user + * @param: string $type - use const self::CALENDAR or self::EVENT + * @return: array $return - information about calendars */ public static function allSharedwithuser($userid, $type, $active=null, $permission=null){ $group_where = self::group_sql(OC_Group::getUserGroups($userid)); @@ -33,11 +33,11 @@ class OC_Calendar_Share{ } return $return; } - /* + /** * @brief: returns all users a calendar / event is shared with - * @param: (int) id - id of the calendar / event - * @param: (string) $type - use const self::CALENDAR or self::EVENT - * @return: (array) $users - information about users a calendar / event is shared with + * @param: integer id - id of the calendar / event + * @param: string $type - use const self::CALENDAR or self::EVENT + * @return: array $users - information about users a calendar / event is shared with */ public static function allUsersSharedwith($id, $type){ $stmt = OCP\DB::prepare('SELECT * FROM *PREFIX*calendar_share_' . $type . ' WHERE ' . $type . 'id = ? ORDER BY share'); @@ -48,13 +48,13 @@ class OC_Calendar_Share{ } return $users; } - /* + /** * @brief: shares a calendar / event - * @param: (string) $owner - userid of the owner - * @param: (string) $share - userid (if $sharetype == user) / groupid (if $sharetype == group) / token (if $sharetype == public) - * @param: (string) $sharetype - type of sharing (can be: user/group/public) - * @param: (string) $id - id of the calendar / event - * @param: (string) $type - use const self::CALENDAR or self::EVENT + * @param: string $owner - userid of the owner + * @param: string $share - userid (if $sharetype == user) / groupid (if $sharetype == group) / token (if $sharetype == public) + * @param: string $sharetype - type of sharing (can be: user/group/public) + * @param: string $id - id of the calendar / event + * @param: string $type - use const self::CALENDAR or self::EVENT * @return (mixed) - token (if $sharetype == public) / bool (if $sharetype != public) */ public static function share($owner, $share, $sharetype, $id, $type){ @@ -80,14 +80,14 @@ class OC_Calendar_Share{ return true; } } - /* + /** * @brief: stops sharing a calendar / event - * @param: (string) $owner - userid of the owner - * @param: (string) $share - userid (if $sharetype == user) / groupid (if $sharetype == group) / token (if $sharetype == public) - * @param: (string) $sharetype - type of sharing (can be: user/group/public) - * @param: (string) $id - id of the calendar / event - * @param: (string) $type - use const self::CALENDAR or self::EVENT - * @return (bool) + * @param: string $owner - userid of the owner + * @param: string $share - userid (if $sharetype == user) / groupid (if $sharetype == group) / token (if $sharetype == public) + * @param: string $sharetype - type of sharing (can be: user/group/public) + * @param: string $id - id of the calendar / event + * @param: string $type - use const self::CALENDAR or self::EVENT + * @return boolean */ public static function unshare($owner, $share, $sharetype, $id, $type){ $stmt = OCP\DB::prepare('DELETE FROM *PREFIX*calendar_share_' . $type . ' WHERE owner = ? ' . (($sharetype != 'public')?'AND share = ?':'') . ' AND sharetype = ? AND ' . $type . 'id = ?'); @@ -98,14 +98,14 @@ class OC_Calendar_Share{ } return true; } - /* + /** * @brief: changes the permission for a calendar / event - * @param: (string) $share - userid (if $sharetype == user) / groupid (if $sharetype == group) / token (if $sharetype == public) - * @param: (string) $sharetype - type of sharing (can be: user/group/public) - * @param: (string) $id - id of the calendar / event - * @param: (int) $permission - permission of user the calendar / event is shared with (if $sharetype == public then $permission = 0) - * @param: (string) $type - use const self::CALENDAR or self::EVENT - * @return (bool) + * @param: string $share - userid (if $sharetype == user) / groupid (if $sharetype == group) / token (if $sharetype == public) + * @param: string $sharetype - type of sharing (can be: user/group/public) + * @param: string $id - id of the calendar / event + * @param: integer $permission - permission of user the calendar / event is shared with (if $sharetype == public then $permission = 0) + * @param: string $type - use const self::CALENDAR or self::EVENT + * @return boolean */ public static function changepermission($share, $sharetype, $id, $permission, $type){ if($sharetype == 'public' && $permission == 1){ @@ -115,9 +115,9 @@ class OC_Calendar_Share{ $stmt->execute(array($permission, $share, $sharetype, $id)); return true; } - /* + /** * @brief: generates a token for public calendars / events - * @return: (string) $token + * @return: string $token */ private static function generate_token($id, $type){ $uniqid = uniqid(); @@ -138,14 +138,14 @@ class OC_Calendar_Share{ $token = md5($string); return substr($token, rand(0,16), 15); } - /* + /** * @brief: checks if it is already shared - * @param: (string) $owner - userid of the owner - * @param: (string) $share - userid (if $sharetype == user) / groupid (if $sharetype == group) / token (if $sharetype == public) - * @param: (string) $sharetype - type of sharing (can be: user/group/public) - * @param: (string) $id - id of the calendar / event - * @param: (string) $type - use const self::CALENDAR or self::EVENT - * @return (bool) + * @param: string $owner - userid of the owner + * @param: string $share - userid (if $sharetype == user) / groupid (if $sharetype == group) / token (if $sharetype == public) + * @param: string $sharetype - type of sharing (can be: user/group/public) + * @param: string $id - id of the calendar / event + * @param: string $type - use const self::CALENDAR or self::EVENT + * @return boolean */ public static function is_already_shared($owner, $share, $sharetype, $id, $type){ $stmt = OCP\DB::prepare('SELECT * FROM *PREFIX*calendar_share_' . $type . ' WHERE owner = ? AND share = ? AND sharetype = ? AND ' . $type . 'id = ?'); @@ -181,12 +181,12 @@ class OC_Calendar_Share{ } return $active_where; } - /* + /** * @brief: checks the permission for editing an event - * @param: (string) $share - userid (if $sharetype == user) / groupid (if $sharetype == group) / token (if $sharetype == public) - * @param: (string) $id - id of the calendar / event - * @param: (string) $type - use const self::CALENDAR or self::EVENT - * @return (bool) + * @param: string $share - userid (if $sharetype == user) / groupid (if $sharetype == group) / token (if $sharetype == public) + * @param: string $id - id of the calendar / event + * @param: string $type - use const self::CALENDAR or self::EVENT + * @return boolean */ public static function is_editing_allowed($share, $id, $type){ $group_where = self::group_sql(OC_Group::getUserGroups($share)); @@ -202,12 +202,12 @@ class OC_Calendar_Share{ } return false; } - /* + /** * @brief: checks the access of - * @param: (string) $share - userid (if $sharetype == user) / groupid (if $sharetype == group) / token (if $sharetype == public) - * @param: (string) $id - id of the calendar / event - * @param: (string) $type - use const self::CALENDAR or self::EVENT - * @return (bool) + * @param: string $share - userid (if $sharetype == user) / groupid (if $sharetype == group) / token (if $sharetype == public) + * @param: string $id - id of the calendar / event + * @param: string $type - use const self::CALENDAR or self::EVENT + * @return boolean */ public static function check_access($share, $id, $type){ $group_where = self::group_sql(OC_Group::getUserGroups($share)); @@ -223,9 +223,9 @@ class OC_Calendar_Share{ return false; } } - /* + /** * @brief: returns the calendardata of an event or a calendar - * @param: (string) $token - token which should be searched + * @param: string $token - token which should be searched * @return: mixed - bool if false, array with type and id if true */ public static function getElementByToken($token){ @@ -248,19 +248,19 @@ class OC_Calendar_Share{ return $return; } - /* + /** * @brief sets the active status of the calendar - * @param (string) $ + * @param string */ public static function set_active($share, $id, $active){ $stmt = OCP\DB::prepare("UPDATE *PREFIX*calendar_share_calendar SET active = ? WHERE share = ? AND sharetype = 'user' AND calendarid = ?"); $stmt->execute(array($active, $share, $id)); } - /* - * @brief delete all shared calendars / events after a user was deleted - * @param (string) $userid - * @return (bool) + /** + * @brief deletes all shared calendars / events after a user was deleted + * @param string $userid + * @return boolean */ public static function post_userdelete($userid){ $stmt = OCP\DB::prepare('DELETE FROM *PREFIX*calendar_share_calendar WHERE owner = ?'); @@ -273,4 +273,26 @@ class OC_Calendar_Share{ $stmt->execute(array($userid)); return true; } + + /** + * @brief deletes all shared events of a calendar + * @param integer $calid + * @return boolean + */ + public static function post_caldelete($calid){ + $stmt = OCP\DB::prepare('DELETE FROM *PREFIX*calendar_share_calendar WHERE calendarid = ?'); + $stmt->execute(array($calid)); + return true; + } + + /** + * @brief deletes all shares of an event + * @param integer $eventid + * @return boolean + */ + public static function post_eventdelete($eventid){ + $stmt = OCP\DB::prepare('DELETE FROM *PREFIX*calendar_share_event WHERE eventid = ?'); + $stmt->execute(array($eventid)); + return true; + } }
\ No newline at end of file diff --git a/apps/calendar/settings.php b/apps/calendar/settings.php index a18b1ca9f42..eaa20c6c9b4 100644 --- a/apps/calendar/settings.php +++ b/apps/calendar/settings.php @@ -10,6 +10,7 @@ $tmpl = new OCP\Template( 'calendar', 'settings'); $timezone=OCP\Config::getUserValue(OCP\USER::getUser(),'calendar','timezone',''); $tmpl->assign('timezone',$timezone); $tmpl->assign('timezones',DateTimeZone::listIdentifiers()); +$tmpl->assign('calendars', OC_Calendar_Calendar::allCalendars(OCP\USER::getUser()), false); OCP\Util::addscript('calendar','settings'); diff --git a/apps/calendar/share.php b/apps/calendar/share.php index 68c7d0ffae2..bffcf0b4709 100644 --- a/apps/calendar/share.php +++ b/apps/calendar/share.php @@ -1,22 +1,31 @@ <?php +/** + * Copyright (c) 2012 Georg Ehrke <ownclouddev at georgswebsite dot de> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ $token = strip_tags($_GET['t']); $shared = OC_Calendar_Share::getElementByToken($token); -$nl = "\n\r"; if($shared['type'] == OC_Calendar_Share::CALENDAR){ $calendar = OC_Calendar_App::getCalendar($shared['id'], false); - $calobjects = OC_Calendar_Object::all($shared['id']); - header('Content-Type: text/Calendar'); - header('Content-Disposition: inline; filename=' . $calendar['displayname'] . '.ics'); - foreach($calobjects as $calobject){ - echo $calobject['calendardata'] . $nl; + if(!$calendar){ + header('HTTP/1.0 404 Not Found'); + exit; } + header('Content-Type: text/Calendar'); + header('Content-Disposition: inline; filename=' . str_replace(' ', '-', $calendar['displayname']) . '.ics'); + echo OC_Calendar_Export::export($shared['id'], OC_Calendar_Export::CALENDAR); }elseif($shared['type'] == OC_Calendar_Share::EVENT){ $data = OC_Calendar_App::getEventObject($shared['id'], false); - $calendarid = $data['calendarid']; - $calendar = OC_Calendar_App::getCalendar($calendarid); + if(!$data){ + header('HTTP/1.0 404 Not Found'); + exit; + } header('Content-Type: text/Calendar'); - header('Content-Disposition: inline; filename=' . $data['summary'] . '.ics'); - echo $data['calendardata']; + header('Content-Disposition: inline; filename=' . str_replace(' ', '-', $data['summary']) . '.ics'); + echo OC_Calendar_Export::export($shared['id'], OC_Calendar_Export::EVENT); }else{ - header('Error 404: Not Found'); -}
\ No newline at end of file + header('HTTP/1.0 404 Not Found'); + exit; +} diff --git a/apps/calendar/templates/settings.php b/apps/calendar/templates/settings.php index 6d018f15110..28c357621a8 100644 --- a/apps/calendar/templates/settings.php +++ b/apps/calendar/templates/settings.php @@ -56,6 +56,12 @@ <dd><code><?php echo OCP\Util::linkToRemote('caldav'); ?></code></dd> <dt><?php echo $l->t('iOS/OS X'); ?></dt> <dd><code><?php echo OCP\Util::linkToRemote('caldav'); ?>principals/<?php echo OCP\USER::getUser(); ?></code>/</dd> + <dt><?php echo $l->t('Read only iCalendar link(s)'); ?></dt> + <dd> + <?php foreach($_['calendars'] as $calendar) { ?> + <a href="<?php echo OCP\Util::linkToRemote('caldav').'calendars/'.OCP\USER::getUser().'/'.rawurlencode($calendar['uri']) ?>?export"><?php echo $calendar['displayname'] ?></a><br /> + <?php } ?> + </dd> </dl> </fieldset> </form> diff --git a/apps/contacts/ajax/addbook.php b/apps/contacts/ajax/addbook.php index 70f47cc8123..751185b44fd 100644 --- a/apps/contacts/ajax/addbook.php +++ b/apps/contacts/ajax/addbook.php @@ -17,4 +17,3 @@ $tmpl = new OCP\Template('contacts', 'part.editaddressbook'); $tmpl->assign('new', true); $tmpl->assign('addressbook', $book); $tmpl->printPage(); -?> diff --git a/apps/contacts/ajax/categories/categoriesfor.php b/apps/contacts/ajax/categories/categoriesfor.php index 846af300de8..6b6fcad0ebb 100644 --- a/apps/contacts/ajax/categories/categoriesfor.php +++ b/apps/contacts/ajax/categories/categoriesfor.php @@ -25,4 +25,3 @@ foreach($vcard->children as $property){ } } OCP\JSON::error(array('data' => array('message' => OC_Contacts_App::$l10n->t('Error setting checksum.')))); -?> diff --git a/apps/contacts/ajax/categories/delete.php b/apps/contacts/ajax/categories/delete.php index 76c23d6487d..7c3261446bb 100644 --- a/apps/contacts/ajax/categories/delete.php +++ b/apps/contacts/ajax/categories/delete.php @@ -45,5 +45,3 @@ $catman->delete($categories, $cards); debug('After delete: '.print_r($catman->categories(), true)); OC_Contacts_VCard::updateDataByID($cards); OCP\JSON::success(array('data' => array('categories'=>$catman->categories()))); - -?> diff --git a/apps/contacts/ajax/categories/list.php b/apps/contacts/ajax/categories/list.php index 3ae7635390c..f234116ba8c 100644 --- a/apps/contacts/ajax/categories/list.php +++ b/apps/contacts/ajax/categories/list.php @@ -13,5 +13,3 @@ OCP\JSON::checkAppEnabled('contacts'); $categories = OC_Contacts_App::getCategories(); OCP\JSON::success(array('data' => array('categories'=>$categories))); - -?> diff --git a/apps/contacts/ajax/categories/rescan.php b/apps/contacts/ajax/categories/rescan.php index 48ec165381f..fd875a965dc 100644 --- a/apps/contacts/ajax/categories/rescan.php +++ b/apps/contacts/ajax/categories/rescan.php @@ -10,24 +10,7 @@ OCP\JSON::checkLoggedIn(); OCP\JSON::checkAppEnabled('contacts'); -require_once('../loghandler.php'); - -$addressbooks = OC_Contacts_Addressbook::all(OCP\USER::getUser()); -if(count($addressbooks) == 0) { - bailOut(OC_Contacts_App::$l10n->t('No address books found.')); -} -$addressbookids = array(); -foreach($addressbooks as $addressbook) { - $addressbookids[] = $addressbook['id']; -} -$contacts = OC_Contacts_VCard::all($addressbookids); -if(count($contacts) == 0) { - bailOut(OC_Contacts_App::$l10n->t('No contacts found.')); -} - -OC_Contacts_App::scanCategories($contacts); +OC_Contacts_App::scanCategories(); $categories = OC_Contacts_App::getCategories(); OCP\JSON::success(array('data' => array('categories'=>$categories))); - -?> diff --git a/apps/contacts/ajax/contacts.php b/apps/contacts/ajax/contacts.php index 4bb7801cb2d..67ebcaf7362 100644 --- a/apps/contacts/ajax/contacts.php +++ b/apps/contacts/ajax/contacts.php @@ -17,40 +17,58 @@ function cmp($a, $b) OCP\JSON::checkLoggedIn(); OCP\JSON::checkAppEnabled('contacts'); -$active_addressbooks = OC_Contacts_Addressbook::active(OCP\USER::getUser()); +$start = isset($_GET['startat'])?$_GET['startat']:0; +$aid = isset($_GET['aid'])?$_GET['aid']:null; +if(is_null($aid)) { + // Called initially to get the active addressbooks. + $active_addressbooks = OC_Contacts_Addressbook::active(OCP\USER::getUser()); +} else { + // called each time more contacts has to be shown. + $active_addressbooks = array(OC_Contacts_Addressbook::find($aid)); +} + + +session_write_close(); + +// create the addressbook associate array $contacts_addressbook = array(); $ids = array(); foreach($active_addressbooks as $addressbook) { $ids[] = $addressbook['id']; if(!isset($contacts_addressbook[$addressbook['id']])) { - $contacts_addressbook[$addressbook['id']] = array('contacts' => array()); + $contacts_addressbook[$addressbook['id']] = array('contacts' => array('type' => 'book',)); $contacts_addressbook[$addressbook['id']]['displayname'] = $addressbook['displayname']; } } -$contacts_alphabet = OC_Contacts_VCard::all($ids); -// Our new array for the contacts sorted by addressbook -foreach($contacts_alphabet as $contact) { - if(!isset($contacts_addressbook[$contact['addressbookid']])) { // It should never execute. - $contacts_addressbook[$contact['addressbookid']] = array('contacts' => array()); +$contacts_alphabet = array(); + +// get next 50 for each addressbook. +foreach($ids as $id) { + if($id) { + $contacts_alphabet = array_merge($contacts_alphabet, OC_Contacts_VCard::all($id, $start, 50)); } - $display = trim($contact['fullname']); - if(!$display) { - $vcard = OC_Contacts_App::getContactVCard($contact['id']); - if(!is_null($vcard)) { - $struct = OC_Contacts_VCard::structureContact($vcard); - $display = isset($struct['EMAIL'][0])?$struct['EMAIL'][0]['value']:'[UNKNOWN]'; +} +// Our new array for the contacts sorted by addressbook +if($contacts_alphabet) { + foreach($contacts_alphabet as $contact) { + if(!isset($contacts_addressbook[$contact['addressbookid']])) { // It should never execute. + $contacts_addressbook[$contact['addressbookid']] = array('contacts' => array('type' => 'book',)); } + $display = trim($contact['fullname']); + if(!$display) { + $vcard = OC_Contacts_App::getContactVCard($contact['id']); + if(!is_null($vcard)) { + $struct = OC_Contacts_VCard::structureContact($vcard); + $display = isset($struct['EMAIL'][0])?$struct['EMAIL'][0]['value']:'[UNKNOWN]'; + } + } + $contacts_addressbook[$contact['addressbookid']]['contacts'][] = array('type' => 'contact', 'id' => $contact['id'], 'addressbookid' => $contact['addressbookid'], 'displayname' => htmlspecialchars($display)); } - $contacts_addressbook[$contact['addressbookid']]['contacts'][] = array('id' => $contact['id'], 'addressbookid' => $contact['addressbookid'], 'displayname' => htmlspecialchars($display)); } unset($contacts_alphabet); uasort($contacts_addressbook, 'cmp'); -$tmpl = new OCP\Template("contacts", "part.contacts"); -$tmpl->assign('books', $contacts_addressbook, false); -$page = $tmpl->fetchPage(); - -OCP\JSON::success(array('data' => array( 'page' => $page ))); +OCP\JSON::success(array('data' => array('entries' => $contacts_addressbook))); diff --git a/apps/contacts/ajax/currentphoto.php b/apps/contacts/ajax/currentphoto.php index b10e752c453..8f60eca08ec 100644 --- a/apps/contacts/ajax/currentphoto.php +++ b/apps/contacts/ajax/currentphoto.php @@ -51,5 +51,3 @@ if( is_null($contact)) { bailOut(OC_Contacts_App::$l10n->t('The loading photo is not valid.')); } } - -?> diff --git a/apps/contacts/ajax/editaddress.php b/apps/contacts/ajax/editaddress.php index 2d7aba11b0e..1eb9429d79c 100644 --- a/apps/contacts/ajax/editaddress.php +++ b/apps/contacts/ajax/editaddress.php @@ -39,5 +39,3 @@ $tmpl->assign('adr_types',$adr_types); $page = $tmpl->fetchPage(); OCP\JSON::success(array('data' => array('page'=>$page, 'checksum'=>$checksum))); - -?> diff --git a/apps/contacts/ajax/editaddressbook.php b/apps/contacts/ajax/editaddressbook.php index 7a9b757ae0d..4bc77302e5b 100644 --- a/apps/contacts/ajax/editaddressbook.php +++ b/apps/contacts/ajax/editaddressbook.php @@ -14,4 +14,3 @@ $tmpl = new OCP\Template("contacts", "part.editaddressbook"); $tmpl->assign('new', false); $tmpl->assign('addressbook', $addressbook); $tmpl->printPage(); -?> diff --git a/apps/contacts/ajax/editname.php b/apps/contacts/ajax/editname.php index 868ca222e0a..9e7c090eeed 100644 --- a/apps/contacts/ajax/editname.php +++ b/apps/contacts/ajax/editname.php @@ -32,5 +32,3 @@ if($id) { } $page = $tmpl->fetchPage(); OCP\JSON::success(array('data' => array('page'=>$page))); - -?> diff --git a/apps/contacts/ajax/importaddressbook.php b/apps/contacts/ajax/importaddressbook.php index f93bbfa4d9d..6b5b06681ce 100644 --- a/apps/contacts/ajax/importaddressbook.php +++ b/apps/contacts/ajax/importaddressbook.php @@ -18,6 +18,6 @@ $maxUploadFilesize = min($maxUploadFilesize ,$freeSpace); $tmpl = new OCP\Template('contacts', 'part.importaddressbook'); $tmpl->assign('uploadMaxFilesize', $maxUploadFilesize); +$tmpl->assign('requesttoken', $_SERVER['HTTP_REQUESTTOKEN']); $tmpl->assign('uploadMaxHumanFilesize', OCP\Util::humanFileSize($maxUploadFilesize)); $tmpl->printpage(); -?> diff --git a/apps/contacts/ajax/importdialog.php b/apps/contacts/ajax/importdialog.php index 5f8805a6106..691522538fb 100644 --- a/apps/contacts/ajax/importdialog.php +++ b/apps/contacts/ajax/importdialog.php @@ -13,4 +13,3 @@ $tmpl = new OCP\Template('contacts', 'part.import'); $tmpl->assign('path', $_POST['path']); $tmpl->assign('filename', $_POST['filename']); $tmpl->printpage(); -?> diff --git a/apps/contacts/ajax/loadphoto.php b/apps/contacts/ajax/loadphoto.php index 61b5356edce..a35631055eb 100644 --- a/apps/contacts/ajax/loadphoto.php +++ b/apps/contacts/ajax/loadphoto.php @@ -42,11 +42,5 @@ foreach($vcard->children as $property){ } } -$tmpl = new OCP\Template("contacts", "part.contactphoto"); -$tmpl->assign('id', $id); -if($refresh) { - $tmpl->assign('refresh', 1); -} -$page = $tmpl->fetchPage(); -OCP\JSON::success(array('data' => array('page'=>$page, 'checksum'=>$checksum))); -?> +OCP\JSON::success(array('data' => array('checksum'=>$checksum))); + diff --git a/apps/contacts/ajax/oc_photo.php b/apps/contacts/ajax/oc_photo.php index 5c50ba92dbe..710179fffcc 100644 --- a/apps/contacts/ajax/oc_photo.php +++ b/apps/contacts/ajax/oc_photo.php @@ -58,5 +58,3 @@ if(OC_Cache::set($tmpkey, $image->data(), 600)) { } else { bailOut('Couldn\'t save temporary image: '.$tmpkey); } - -?> diff --git a/apps/contacts/ajax/uploadimport.php b/apps/contacts/ajax/uploadimport.php index c1e9c8b1ad1..80b282f38a3 100644 --- a/apps/contacts/ajax/uploadimport.php +++ b/apps/contacts/ajax/uploadimport.php @@ -23,6 +23,7 @@ // Check if we are a user OCP\JSON::checkLoggedIn(); OCP\JSON::checkAppEnabled('contacts'); +OCP\JSON::callCheck(); require_once('loghandler.php'); $view = OCP\Files::getStorage('contacts'); @@ -69,6 +70,3 @@ if(file_exists($file['tmp_name'])) { } else { bailOut('Temporary file: \''.$file['tmp_name'].'\' has gone AWOL?'); } - - -?> diff --git a/apps/contacts/ajax/uploadphoto.php b/apps/contacts/ajax/uploadphoto.php index 8545ca84eee..6bb3fe8a5e0 100644 --- a/apps/contacts/ajax/uploadphoto.php +++ b/apps/contacts/ajax/uploadphoto.php @@ -102,4 +102,3 @@ if(file_exists($file['tmp_name'])) { } else { bailOut('Temporary file: \''.$file['tmp_name'].'\' has gone AWOL?'); } -?> diff --git a/apps/contacts/appinfo/app.php b/apps/contacts/appinfo/app.php index cec0f3e88cd..daf7bee1c97 100644 --- a/apps/contacts/appinfo/app.php +++ b/apps/contacts/appinfo/app.php @@ -5,6 +5,7 @@ OC::$CLASSPATH['OC_Contacts_VCard'] = 'apps/contacts/lib/vcard.php'; OC::$CLASSPATH['OC_Contacts_Hooks'] = 'apps/contacts/lib/hooks.php'; OC::$CLASSPATH['OC_Contacts_Share'] = 'apps/contacts/lib/share.php'; OC::$CLASSPATH['OC_Connector_Sabre_CardDAV'] = 'apps/contacts/lib/connector_sabre.php'; +OC::$CLASSPATH['Sabre_CardDAV_VCFExportPlugin'] = 'apps/contacts/lib/VCFExportPlugin.php'; OC::$CLASSPATH['OC_Search_Provider_Contacts'] = 'apps/contacts/lib/search.php'; OCP\Util::connectHook('OC_User', 'post_createUser', 'OC_Contacts_Hooks', 'createUser'); OCP\Util::connectHook('OC_User', 'post_deleteUser', 'OC_Contacts_Hooks', 'deleteUser'); diff --git a/apps/contacts/appinfo/database.xml b/apps/contacts/appinfo/database.xml index 7c8268d71f5..9b269d765dc 100644 --- a/apps/contacts/appinfo/database.xml +++ b/apps/contacts/appinfo/database.xml @@ -62,6 +62,14 @@ <length>4</length> </field> + <field> + <name>active</name> + <type>integer</type> + <default>1</default> + <notnull>true</notnull> + <length>4</length> + </field> + </declaration> </table> diff --git a/apps/contacts/appinfo/migrate.php b/apps/contacts/appinfo/migrate.php index 1400cdf79d4..02026c5979c 100644 --- a/apps/contacts/appinfo/migrate.php +++ b/apps/contacts/appinfo/migrate.php @@ -30,7 +30,7 @@ class OC_Migration_Provider_Contacts extends OC_Migration_Provider{ } - // Import function for bookmarks + // Import function for contacts function import( ){ switch( $this->appinfo->version ){ default: @@ -39,20 +39,23 @@ class OC_Migration_Provider_Contacts extends OC_Migration_Provider{ $results = $query->execute( array( $this->olduid ) ); $idmap = array(); while( $row = $results->fetchRow() ){ - // Import each bookmark, saving its id into the map - $query = OCP\DB::prepare( "INSERT INTO *PREFIX*contacts_addressbooks (`userid`, `displayname`, `uri`, `description`, `ctag`) VALUES (?, ?, ?, ?, ?)" ); - $query->execute( array( $this->uid, $row['displayname'], $row['uri'], $row['description'], $row['ctag'] ) ); + // Import each addressbook + $addressbookquery = OCP\DB::prepare( "INSERT INTO *PREFIX*contacts_addressbooks (`userid`, `displayname`, `uri`, `description`, `ctag`) VALUES (?, ?, ?, ?, ?)" ); + $addressbookquery->execute( array( $this->uid, $row['displayname'], $row['uri'], $row['description'], $row['ctag'] ) ); // Map the id - $idmap[$row['id']] = OCP\DB::insertid(); + $idmap[$row['id']] = OCP\DB::insertid('*PREFIX*contacts_addressbooks'); + // Make the addressbook active + OC_Contacts_Addressbook::setActive($idmap[$row['id']], true); } // Now tags foreach($idmap as $oldid => $newid){ + $query = $this->content->prepare( "SELECT * FROM contacts_cards WHERE addressbookid LIKE ?" ); $results = $query->execute( array( $oldid ) ); while( $row = $results->fetchRow() ){ - // Import the tags for this bookmark, using the new bookmark id - $query = OCP\DB::prepare( "INSERT INTO *PREFIX*contacts_cards (`addressbookid`, `fullname`, `carddata`, `uri`, `lastmodified`) VALUES (?, ?, ?, ?, ?)" ); - $query->execute( array( $newid, $row['fullname'], $row['carddata'], $row['uri'], $row['lastmodified'] ) ); + // Import the contacts + $contactquery = OCP\DB::prepare( "INSERT INTO *PREFIX*contacts_cards (`addressbookid`, `fullname`, `carddata`, `uri`, `lastmodified`) VALUES (?, ?, ?, ?, ?)" ); + $contactquery->execute( array( $newid, $row['fullname'], $row['carddata'], $row['uri'], $row['lastmodified'] ) ); } } // All done! diff --git a/apps/contacts/appinfo/remote.php b/apps/contacts/appinfo/remote.php index 5add3bc6889..09c2de17990 100644 --- a/apps/contacts/appinfo/remote.php +++ b/apps/contacts/appinfo/remote.php @@ -49,6 +49,7 @@ $server->addPlugin(new Sabre_DAV_Auth_Plugin($authBackend,'ownCloud')); $server->addPlugin(new Sabre_CardDAV_Plugin()); $server->addPlugin(new Sabre_DAVACL_Plugin()); $server->addPlugin(new Sabre_DAV_Browser_Plugin(false)); // Show something in the Browser, but no upload +$server->addPlugin(new Sabre_CardDAV_VCFExportPlugin()); // And off we go! $server->exec(); diff --git a/apps/contacts/appinfo/update.php b/apps/contacts/appinfo/update.php new file mode 100644 index 00000000000..873899f578b --- /dev/null +++ b/apps/contacts/appinfo/update.php @@ -0,0 +1,25 @@ +<?php + +$installedVersion=OCP\Config::getAppValue('contacts', 'installed_version'); +if (version_compare($installedVersion, '0.2.90', '<')) { + // First set all address books in-active. + $stmt = OCP\DB::prepare( 'UPDATE *PREFIX*contacts_addressbooks SET active=0' ); + $result = $stmt->execute(array()); + + // Then get all the active address books. + $stmt = OCP\DB::prepare( 'SELECT userid,configvalue FROM *PREFIX*preferences WHERE appid=\'contacts\' AND configkey=\'openaddressbooks\'' ); + $result = $stmt->execute(array()); + + // Prepare statement for updating the new 'active' field. + $stmt = OCP\DB::prepare( 'UPDATE *PREFIX*contacts_addressbooks SET active=? WHERE id=? AND userid=?' ); + while( $row = $result->fetchRow()) { + $ids = explode(';', $row['configvalue']); + foreach($ids as $id) { + $r = $stmt->execute(array(1, $id, $row['userid'])); + } + } + + // Remove the old preferences. + $stmt = OCP\DB::prepare( 'DELETE FROM *PREFIX*preferences WHERE appid=\'contacts\' AND configkey=\'openaddressbooks\'' ); + $result = $stmt->execute(array()); +} diff --git a/apps/contacts/appinfo/version b/apps/contacts/appinfo/version index 2f4536184bc..7dff5b89211 100644 --- a/apps/contacts/appinfo/version +++ b/apps/contacts/appinfo/version @@ -1 +1 @@ -0.2
\ No newline at end of file +0.2.1
\ No newline at end of file diff --git a/apps/contacts/css/contacts.css b/apps/contacts/css/contacts.css index b3e5efb7859..439c611b1dc 100644 --- a/apps/contacts/css/contacts.css +++ b/apps/contacts/css/contacts.css @@ -12,12 +12,13 @@ .ui-draggable-dragging { width: 16em; } .ui-state-hover { border: 1px solid dashed; } #bottomcontrols { padding: 0; bottom:0px; height:2.8em; width: 20em; margin:0; background:#eee; border-top:1px solid #ccc; position:fixed; -moz-box-shadow: 0 -3px 3px -3px #000; -webkit-box-shadow: 0 -3px 3px -3px #000; box-shadow: 0 -3px 3px -3px #000;} +#bottomcontrols img { margin-top: 0.35em; } #contacts_newcontact { float: left; margin: 0.2em 0 0 1em; } #chooseaddressbook { float: right; margin: 0.2em 1em 0 0; } -#actionbar { height: 30px; width: 60px; position: fixed; right: 0px; top: 4em; margin: 0 0 0 0; padding: 0 0 0 0; z-index: 1000; } +#actionbar { position: relative; clear: both; height: 30px;} #contacts_deletecard {position:relative; float:left; background:url('%webroot%/core/img/actions/delete.svg') no-repeat center; } #contacts_downloadcard {position:relative; float:left; background:url('%webroot%/core/img/actions/download.svg') no-repeat center; } -#contacts_propertymenu { clear: both; max-width: 15em; margin: 2em; } +#contacts_propertymenu { clear: left; float:left; max-width: 15em; margin: 2em; } #contacts_propertymenu_button { position:relative;top:0;left:0; margin: 0; } #contacts_propertymenu_dropdown { background-color: #fff; position:relative; right:0; overflow:hidden; text-overflow:ellipsis; border: thin solid #1d2d44; box-shadow: 0 3px 5px #bbb; /* -moz-box-shadow:0 0 10px #000; -webkit-box-shadow:0 0 10px #000; box-shadow:0 0 10px #000; -moz-border-radius:0.5em; -webkit-border-radius:0.5em; border-radius:0.5em; -moz-border-radius:0.5em; -webkit-border-radius:0.5em;*/ border-radius: 3px; } #contacts_propertymenu li { display: block; font-weight: bold; height: 20px; } @@ -74,10 +75,10 @@ label:hover, dt:hover { color: #333; } .contactsection { position: relative; float: left; /*max-width: 40em;*/ padding: 0.5em; height: auto: border: thin solid lightgray;/* -webkit-border-radius: 0.5em; -moz-border-radius: 0.5em; border-radius: 0.5em; background-color: #f8f8f8;*/ } #cropbox { margin: auto; } -#contacts_details_photo_wrapper { min-width: 120px; } +#contacts_details_photo_wrapper { width: 200px; } #contacts_details_photo_wrapper.wait { opacity: 0.6; filter:alpha(opacity=0.6); z-index:1000; background: url('%webroot%/core/img/loading.gif') no-repeat center center; cursor: wait; } -#contacts_details_photo { border-radius: 0.5em; border: thin solid #bbb; margin: 0.3em; background: url('%webroot%/core/img/loading.gif') no-repeat center center; -moz-box-shadow: 0 1px 3px #777; -webkit-box-shadow: 0 1px 3px #777; box-shadow: 0 1px 3px #777; } -#contacts_details_photo:hover { background: #fff; cursor: default; } +.contacts_details_photo { border-radius: 0.5em; border: thin solid #bbb; margin: 0.3em; background: url('%webroot%/core/img/loading.gif') no-repeat center center; -moz-box-shadow: 0 1px 3px #777; -webkit-box-shadow: 0 1px 3px #777; box-shadow: 0 1px 3px #777; opacity: 1; } +.contacts_details_photo:hover { background: #fff; cursor: default; } #phototools { position:absolute; margin: 5px 0 0 10px; width:auto; height:22px; padding:0px; background-color:#fff; list-style-type:none; border-radius: 0.5em; -moz-box-shadow: 0 1px 3px #777; -webkit-box-shadow: 0 1px 3px #777; box-shadow: 0 1px 3px #777; } #phototools li { display: inline; } #phototools li a { float:left; cursor:pointer; width:22px; height:22px; opacity: 0.6; } diff --git a/apps/contacts/export.php b/apps/contacts/export.php index f84a10c1388..eb506506c42 100644 --- a/apps/contacts/export.php +++ b/apps/contacts/export.php @@ -14,12 +14,17 @@ $contactid = isset($_GET['contactid']) ? $_GET['contactid'] : NULL; $nl = "\n"; if(isset($bookid)){ $addressbook = OC_Contacts_App::getAddressbook($bookid); - $cardobjects = OC_Contacts_VCard::all($bookid); + //$cardobjects = OC_Contacts_VCard::all($bookid); header('Content-Type: text/directory'); header('Content-Disposition: inline; filename=' . str_replace(' ', '_', $addressbook['displayname']) . '.vcf'); - foreach($cardobjects as $card) { - echo $card['carddata'] . $nl; + $start = 0; + $batchsize = OCP\Config::getUserValue(OCP\User::getUser(), 'contacts', 'export_batch_size', 20); + while($cardobjects = OC_Contacts_VCard::all($bookid, $start, $batchsize)){ + foreach($cardobjects as $card) { + echo $card['carddata'] . $nl; + } + $start += $batchsize; } }elseif(isset($contactid)){ $data = OC_Contacts_App::getContactObject($contactid); @@ -27,4 +32,3 @@ if(isset($bookid)){ header('Content-Disposition: inline; filename=' . str_replace(' ', '_', $data['fullname']) . '.vcf'); echo $data['carddata']; } -?> diff --git a/apps/contacts/import.php b/apps/contacts/import.php index c95fd970fe1..93c47ef2667 100644 --- a/apps/contacts/import.php +++ b/apps/contacts/import.php @@ -12,6 +12,7 @@ OCP\JSON::checkLoggedIn(); OCP\App::checkAppEnabled('contacts'); session_write_close(); +$cr = "\r"; $nl = "\n"; global $progresskey; @@ -35,20 +36,20 @@ if(isset($_POST['fstype']) && $_POST['fstype'] == 'OC_FilesystemView') { $file = OC_Filesystem::file_get_contents($_POST['path'] . '/' . $_POST['file']); } if(!$file) { - OCP\JSON::error(array('message' => 'Import file was empty.')); + OCP\JSON::error(array('data' => array('message' => 'Import file was empty.'))); exit(); } if(isset($_POST['method']) && $_POST['method'] == 'new'){ $id = OC_Contacts_Addressbook::add(OCP\USER::getUser(), $_POST['addressbookname']); if(!$id) { - OCP\JSON::error(array('message' => 'Error creating address book.')); + OCP\JSON::error(array('data' => array('message' => 'Error creating address book.'))); exit(); } OC_Contacts_Addressbook::setActive($id, 1); }else{ $id = $_POST['id']; if(!$id) { - OCP\JSON::error(array('message' => 'Error getting the ID of the address book.')); + OCP\JSON::error(array('data' => array('message' => 'Error getting the ID of the address book.'))); exit(); } OC_Contacts_App::getAddressbook($id); // is owner access check @@ -56,6 +57,10 @@ if(isset($_POST['method']) && $_POST['method'] == 'new'){ //analyse the contacts file writeProgress('40'); $lines = explode($nl, $file); +if(count($lines) == 1) { // Mac eol + $lines = explode($cr, $file); +} + $inelement = false; $parts = array(); $card = array(); @@ -77,7 +82,7 @@ writeProgress('70'); $imported = 0; $failed = 0; if(!count($parts) > 0) { - OCP\JSON::error(array('message' => 'No contacts to import in .'.$_POST['file'].' Please check if the file is corrupted.')); + OCP\JSON::error(array('data' => array('message' => 'No contacts to import in .'.$_POST['file'].' Please check if the file is corrupted.'))); exit(); } foreach($parts as $part){ diff --git a/apps/contacts/index.php b/apps/contacts/index.php index 0b4f89b30c0..c1e33252f56 100644 --- a/apps/contacts/index.php +++ b/apps/contacts/index.php @@ -14,28 +14,16 @@ OCP\App::checkAppEnabled('contacts'); // Get active address books. This creates a default one if none exists. $ids = OC_Contacts_Addressbook::activeIds(OCP\USER::getUser()); -$contacts = OC_Contacts_VCard::all($ids); +$has_contacts = (count(OC_Contacts_VCard::all($ids, 0, 1)) > 0 ? true : false); // just to check if there are any contacts. if($contacts === false) { OCP\Util::writeLog('contacts','index.html: No contacts found.',OCP\Util::DEBUG); } -$addressbooks = OC_Contacts_Addressbook::active(OCP\USER::getUser()); - // Load the files we need OCP\App::setActiveNavigationEntry( 'contacts_index' ); // Load a specific user? $id = isset( $_GET['id'] ) ? $_GET['id'] : null; -$details = array(); - -if(is_null($id) && count($contacts) > 0) { - $id = $contacts[0]['id']; -} -unset($contacts); -if(!is_null($id)) { - $vcard = OC_Contacts_App::getContactVCard($id); - $details = OC_Contacts_VCard::structureContact($vcard); -} $property_types = OC_Contacts_App::getAddPropertyOptions(); $phone_types = OC_Contacts_App::getTypesOfProperty('TEL'); $email_types = OC_Contacts_App::getTypesOfProperty('EMAIL'); @@ -63,15 +51,12 @@ OCP\Util::addStyle('contacts','jquery.Jcrop'); OCP\Util::addStyle('contacts','contacts'); $tmpl = new OCP\Template( "contacts", "index", "user" ); -$tmpl->assign('uploadMaxFilesize', $maxUploadFilesize); -$tmpl->assign('uploadMaxHumanFilesize', OCP\Util::humanFileSize($maxUploadFilesize)); -$tmpl->assign('property_types', $property_types); -$tmpl->assign('phone_types', $phone_types); -$tmpl->assign('email_types', $email_types); -$tmpl->assign('categories', $categories); -$tmpl->assign('addressbooks', $addressbooks); -$tmpl->assign('details', $details ); -$tmpl->assign('id',$id); +$tmpl->assign('uploadMaxFilesize', $maxUploadFilesize, false); +$tmpl->assign('uploadMaxHumanFilesize', OCP\Util::humanFileSize($maxUploadFilesize), false); +$tmpl->assign('property_types', $property_types, false); +$tmpl->assign('phone_types', $phone_types, false); +$tmpl->assign('email_types', $email_types, false); +$tmpl->assign('categories', $categories, false); +$tmpl->assign('has_contacts', $has_contacts, false); +$tmpl->assign('id',$id, false); $tmpl->printPage(); - -?> diff --git a/apps/contacts/js/contacts.js b/apps/contacts/js/contacts.js index 64b7af850ea..dd194db0161 100644 --- a/apps/contacts/js/contacts.js +++ b/apps/contacts/js/contacts.js @@ -48,7 +48,7 @@ Contacts={ adrstr = adrstr + adrarr[6].trim(); } adrstr = encodeURIComponent(adrstr); - var uri = 'http://open.mapquestapi.com/nominatim/v1/search.php?q=' + adrstr + '&limit=10&addressdetails=1&zoom='; + var uri = 'http://open.mapquestapi.com/nominatim/v1/search.php?q=' + adrstr + '&limit=10&addressdetails=1&polygon=1&zoom='; var newWindow = window.open(uri,'_blank'); newWindow.focus(); }, @@ -144,6 +144,31 @@ Contacts={ $('#edit_name').click(function(){Contacts.UI.Card.editName()}); $('#edit_name').keydown(function(){Contacts.UI.Card.editName()}); + $('#phototools li a').click(function() { + $(this).tipsy('hide'); + }); + $('#contacts_details_photo_wrapper').hover( + function () { + $('#phototools').slideDown(200); + }, + function () { + $('#phototools').slideUp(200); + } + ); + $('#phototools').hover( + function () { + $(this).removeClass('transparent'); + }, + function () { + $(this).addClass('transparent'); + } + ); + $('#phototools .upload').click(function() { + $('#file_upload_start').trigger('click'); + }); + $('#phototools .cloud').click(function() { + OC.dialogs.filepicker(t('contacts', 'Select photo'), Contacts.UI.Card.cloudPhotoSelected, false, 'image', true); + }); /* Initialize the photo edit dialog */ $('#edit_photo_dialog').dialog({ autoOpen: false, modal: true, height: 'auto', width: 'auto' @@ -234,6 +259,30 @@ Contacts={ $('#contacts_downloadcard').tipsy({gravity: 'ne'}); $('#contacts_propertymenu_button').tipsy(); $('#contacts_newcontact, #chooseaddressbook').tipsy({gravity: 'sw'}); + + $('body').click(function(e){ + if(!$(e.target).is('#contacts_propertymenu_button')) { + $('#contacts_propertymenu_dropdown').hide(); + } + }); + function propertyMenu(){ + var menu = $('#contacts_propertymenu_dropdown'); + if(menu.is(':hidden')) { + menu.show(); + menu.find('li').first().focus(); + } else { + menu.hide(); + } + } + $('#contacts_propertymenu_button').click(propertyMenu); + $('#contacts_propertymenu_button').keydown(propertyMenu); + function propertyMenuItem(){ + var type = $(this).data('type'); + Contacts.UI.Card.addProperty(type); + $('#contacts_propertymenu_dropdown').hide(); + } + $('#contacts_propertymenu_dropdown a').click(propertyMenuItem); + $('#contacts_propertymenu_dropdown a').keydown(propertyMenuItem); }, Card:{ id:'', @@ -249,7 +298,7 @@ Contacts={ update:function(id, bookid) { var newid, firstitem; if(!id) { - firstitem = $('#contacts:first-child li:first-child'); + firstitem = $('#contacts ul').first().find('li:first-child'); if(firstitem.length > 0) { newid = firstitem.data('id'); bookid = firstitem.data('bookid'); @@ -261,12 +310,13 @@ Contacts={ if(!bookid) { bookid = $('#contacts h3').first().data('id'); } + console.log('bookid: ' +bookid); var localLoadContact = function(newid, bookid) { if($('.contacts li').length > 0) { $('#contacts li[data-id="'+newid+'"]').addClass('active'); $.getJSON(OC.filePath('contacts', 'ajax', 'contactdetails.php'),{'id':newid},function(jsondata){ if(jsondata.status == 'success'){ - $('#contacts h3[data-id="'+bookid+'"]').trigger('click'); + $('#contacts ul[data-id="'+bookid+'"]').slideDown(300); Contacts.UI.Card.loadContact(jsondata.data, bookid); } else { OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error')); @@ -276,8 +326,9 @@ Contacts={ } // Make sure proper DOM is loaded. - if(!$('#card')[0] && newid) { - $.getJSON(OC.filePath('contacts', 'ajax', 'loadcard.php'),{},function(jsondata){ + if(!$('#card').length && newid) { + console.log('Loading card DOM'); + $.getJSON(OC.filePath('contacts', 'ajax', 'loadcard.php'),{requesttoken:requesttoken},function(jsondata){ if(jsondata.status == 'success'){ $('#rightcontent').html(jsondata.data.page).ready(function() { Contacts.UI.loadHandlers(); @@ -289,6 +340,7 @@ Contacts={ }); } else if(!newid) { + console.log('Loading intro'); // load intro page $.getJSON(OC.filePath('contacts', 'ajax', 'loadintro.php'),{},function(jsondata){ if(jsondata.status == 'success'){ @@ -316,7 +368,11 @@ Contacts={ Contacts.UI.Card.add(';;;;;', '', '', true); return false; }, + createEntry:function(data) { + return $('<li data-id="'+data.id+'" data-bookid="'+data.addressbookid+'" role="button"><a href="'+OC.linkTo('contacts', 'index.php')+'&id='+data.id+'" style="background: url('+OC.filePath('contacts', '', 'thumbnail.php')+'?id='+data.id+') no-repeat scroll 0% 0% transparent;">'+data.displayname+'</a></li>'); + }, add:function(n, fn, aid, isnew){ // add a new contact + console.log('Adding ' + fn); aid = aid?aid:$('#contacts h3.active').first().data('id'); var localAddcontact = function(n, fn, aid, isnew) { $.post(OC.filePath('contacts', 'ajax', 'addcontact.php'), { n: n, fn: fn, aid: aid, isnew: isnew }, @@ -360,8 +416,8 @@ Contacts={ }); } - var card = $('#card')[0]; - if(!card) { + if(!$('#card').length) { + console.log('Loading card DOM'); $.getJSON(OC.filePath('contacts', 'ajax', 'loadcard.php'),{'requesttoken': requesttoken},function(jsondata){ if(jsondata.status == 'success'){ $('#rightcontent').html(jsondata.data.page).ready(function() { @@ -607,7 +663,7 @@ Contacts={ return false; } container = $(obj).parents('.propertycontainer').first(); // get the parent holding the metadata. - Contacts.UI.loading(container, true); + Contacts.UI.loading(obj, true); var checksum = container.data('checksum'); var name = container.data('element'); var fields = container.find('input.contacts_property,select.contacts_property').serializeArray(); @@ -630,7 +686,7 @@ Contacts={ var q = container.find('input.contacts_property,select.contacts_property,textarea.contacts_property').serialize(); if(q == '' || q == undefined) { OC.dialogs.alert(t('contacts', 'Couldn\'t serialize elements.'), t('contacts', 'Error')); - Contacts.UI.loading(container, false); + Contacts.UI.loading(obj, false); return false; } q = q + '&id=' + this.id + '&name=' + name; @@ -642,13 +698,13 @@ Contacts={ if(jsondata.status == 'success'){ container.data('checksum', jsondata.data.checksum); Contacts.UI.Card.savePropertyInternal(name, fields, checksum, jsondata.data.checksum); - Contacts.UI.loading(container, false); + Contacts.UI.loading(obj, false); $(obj).removeAttr('disabled'); return true; } else{ OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error')); - Contacts.UI.loading(container, false); + Contacts.UI.loading(obj, false); $(obj).removeAttr('disabled'); return false; } @@ -661,13 +717,13 @@ Contacts={ container.data('checksum', jsondata.data.checksum); // TODO: savePropertyInternal doesn't know about new fields //Contacts.UI.Card.savePropertyInternal(name, fields, checksum, jsondata.data.checksum); - Contacts.UI.loading(container, false); + Contacts.UI.loading(obj, false); $(obj).removeAttr('disabled'); return true; } else{ OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error')); - Contacts.UI.loading(container, false); + Contacts.UI.loading(obj, false); $(obj).removeAttr('disabled'); return false; } @@ -1081,25 +1137,6 @@ Contacts={ loadPhotoHandlers:function(){ $('#phototools li a').tipsy('hide'); $('#phototools li a').tipsy(); - $('#phototools li a').click(function() { - $(this).tipsy('hide'); - }); - $('#contacts_details_photo_wrapper').hover( - function () { - $('#phototools').slideDown(200); - }, - function () { - $('#phototools').slideUp(200); - } - ); - $('#phototools').hover( - function () { - $(this).removeClass('transparent'); - }, - function () { - $(this).addClass('transparent'); - } - ); if(this.data.PHOTO) { $('#phototools .delete').click(function() { $(this).tipsy('hide'); @@ -1110,16 +1147,12 @@ Contacts={ $(this).tipsy('hide'); Contacts.UI.Card.editCurrentPhoto(); }); + $('#phototools .delete').show(); + $('#phototools .edit').show(); } else { $('#phototools .delete').hide(); $('#phototools .edit').hide(); } - $('#phototools .upload').click(function() { - $('#file_upload_start').trigger('click'); - }); - $('#phototools .cloud').click(function() { - OC.dialogs.filepicker(t('contacts', 'Select photo'), Contacts.UI.Card.cloudPhotoSelected, false, 'image', true); - }); }, cloudPhotoSelected:function(path){ $.getJSON(OC.filePath('contacts', 'ajax', 'oc_photo.php'),{'path':path,'id':Contacts.UI.Card.id},function(jsondata){ @@ -1134,22 +1167,33 @@ Contacts={ }); }, loadPhoto:function(refresh){ + var self = this; + var refreshstr = (refresh?'&refresh=1'+Math.random():'') $('#phototools li a').tipsy('hide'); var wrapper = $('#contacts_details_photo_wrapper'); - wrapper.addClass('wait'); + wrapper.addClass('loading').addClass('wait'); + + var img = new Image(); + $(img).load(function () { + $('img.contacts_details_photo').remove() + $(this).addClass('contacts_details_photo').hide(); + wrapper.removeClass('loading').removeClass('wait'); + $(this).insertAfter($('#phototools')).fadeIn(); + }).error(function () { + // notify the user that the image could not be loaded + $(t('contacts','something went wrong.')).insertAfter($('#phototools')); + }).attr('src', OC.linkTo('contacts', 'photo.php')+'?id='+self.id+refreshstr); + $.getJSON(OC.filePath('contacts', 'ajax', 'loadphoto.php'),{'id':this.id, 'refresh': refresh},function(jsondata){ if(jsondata.status == 'success'){ $('#contacts_details_photo_wrapper').data('checksum', jsondata.data.checksum); - wrapper.html(jsondata.data.page).ready(function(){ wrapper.removeClass('wait').tipsy() }); Contacts.UI.Card.loadPhotoHandlers(); } else{ - wrapper.removeClass('wait'); OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error')); } }); $('#file_upload_form').show(); - $('#contacts_propertymenu_dropdown a[data-type="PHOTO"]').parent().hide(); }, editCurrentPhoto:function(){ $.getJSON(OC.filePath('contacts', 'ajax', 'currentphoto.php'),{'id':this.id},function(jsondata){ @@ -1185,15 +1229,15 @@ Contacts={ var target = $('#crop_target'); var form = $('#cropform'); var wrapper = $('#contacts_details_photo_wrapper'); + var self = this; wrapper.addClass('wait'); form.submit(); target.load(function(){ var response=jQuery.parseJSON(target.contents().text()); if(response != undefined && response.status == 'success'){ // load cropped photo. - wrapper.html(response.data.page).ready(function(){ wrapper.removeClass('wait') }); + self.loadPhoto(true); Contacts.UI.Card.data.PHOTO = true; - Contacts.UI.Card.loadPhotoHandlers(); }else{ OC.dialogs.alert(response.data.message, t('contacts', 'Error')); wrapper.removeClass('wait'); @@ -1318,13 +1362,18 @@ Contacts={ } return false; }, - activation:function(checkbox, bookid) - { - $.post(OC.filePath('contacts', 'ajax', 'activation.php'), { bookid: bookid, active: checkbox.checked?1:0 }, - function(data) { - if (data.status == 'success'){ - checkbox.checked = data.active == 1; - Contacts.UI.Contacts.update(); + activation:function(checkbox, bookid){ + var active = checkbox.checked; + $.post(OC.filePath('contacts', 'ajax', 'activation.php'), {bookid: bookid, active: (active?1:0)}, function(jsondata) { + if (jsondata.status == 'success'){ + if(!active) { + $('#contacts h3[data-id="'+bookid+'"],#contacts ul[data-id="'+bookid+'"]').remove(); + } else { + Contacts.UI.Contacts.update(); + } + } else { + OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error')); + checkbox.checked = !active; } }); }, @@ -1347,6 +1396,7 @@ Contacts={ function(jsondata) { if (jsondata.status == 'success'){ $(obj).closest('tr').remove(); + $('#contacts h3[data-id="'+bookid+'"],#contacts ul[data-id="'+bookid+'"]').remove(); Contacts.UI.Contacts.update(); } else { OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error')); @@ -1419,7 +1469,7 @@ Contacts={ } } }; - xhr.open('POST', OC.filePath('contacts', 'ajax', 'uploadimport.php') + '?file='+encodeURIComponent(file.name), true); + xhr.open('POST', OC.filePath('contacts', 'ajax', 'uploadimport.php') + '?file='+encodeURIComponent(file.name)+'&requesttoken='+requesttoken, true); xhr.setRequestHeader('Cache-Control', 'no-cache'); xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); xhr.setRequestHeader('X_FILE_NAME', encodeURIComponent(file.name)); @@ -1508,6 +1558,7 @@ Contacts={ } }, Contacts:{ + batchnum:50, drop:function(event, ui) { var dragitem = ui.draggable, droptarget = $(this); //console.log('Drop ' + dragitem.data('id') +' on: ' + droptarget.data('id')); @@ -1539,64 +1590,81 @@ Contacts={ }); }, // Reload the contacts list. - update:function(id){ - $.getJSON(OC.filePath('contacts', 'ajax', 'contacts.php'),{},function(jsondata){ + update:function(id, aid, start){ + self = this; + console.log('update: ' + aid + ' ' + start); + var firstrun = false; + var opts = {}; + opts['startat'] = (start?start:0); + if(aid) { + opts['aid'] = aid; + } + $.getJSON(OC.filePath('contacts', 'ajax', 'contacts.php'),opts,function(jsondata){ if(jsondata.status == 'success'){ - $('#contacts').html(jsondata.data.page).ready(function() { - /*setTimeout(function() { - $('.contacts li').unbind('inview'); - $('.contacts li:visible').bind('inview', function(event, isInView, visiblePartX, visiblePartY) { - if (isInView) { - if (!$(this).find('a').attr('style')) { - $(this).find('a').css('background','url('+OC.filePath('contacts', '', 'thumbnail.php')+'?id='+$(this).data('id')+') no-repeat'); - } + var books = jsondata.data.entries; + $.each(jsondata.data.entries, function(b, book) { + if($('#contacts h3[data-id="'+b+'"]').length == 0) { + firstrun = true; + + if($('#contacts h3').length == 0) { + $('#contacts').html('<h3 class="addressbook" data-id="'+b+'">'+book.displayname+'</h3><ul class="contacts hidden" data-id="'+b+'"></ul>'); + } else { + if(!$('#contacts h3[data-id="'+b+'"]').length) { + $('<h3 class="addressbook" data-id="'+b+'">'+book.displayname+'</h3><ul class="contacts hidden" data-id="'+b+'"></ul>') + .appendTo('#contacts'); } - })}, 100); - setTimeout(Contacts.UI.Contacts.lazyupdate, 500);*/ - if($('#contacts h3').length > 1) { - $('#contacts h3,#contacts ul').each(function(index) { - var id = $(this).data('id'); - var accept = 'li:not([data-bookid="'+id+'"])'; - $(this).droppable({ - drop: Contacts.UI.Contacts.drop, - activeClass: 'ui-state-hover', - accept: accept - }); + } + $('#contacts h3[data-id="'+b+'"]').on('click', function(event) { + $('#contacts h3').removeClass('active'); + $(this).addClass('active'); + $('#contacts ul[data-id="'+b+'"]').slideToggle(300); + return false; }); - $('#contacts li').draggable({ - revert: 'invalid', - axis: 'y', containment: '#contacts', - scroll: true, scrollSensitivity: 100, - opacity: 0.7, helper: 'clone' + var accept = 'li:not([data-bookid="'+b+'"])'; + $('#contacts h3[data-id="'+b+'"]').droppable({ + drop: Contacts.UI.Contacts.drop, + activeClass: 'ui-state-hover', + accept: accept }); - } else { - $('#contacts h3').first().addClass('active'); + } + var contactlist = $('#contacts ul[data-id="'+b+'"]'); + for(var c in book.contacts) { + if(book.contacts[c].id == undefined) { continue; } + if($('#contacts li[data-id="'+book.contacts[c]['id']+'"][data-id="'+book.contacts[c]['bookid']+'"]').length == 0) { + var contact = Contacts.UI.Card.createEntry(book.contacts[c]); + if(c == self.batchnum-5) { + contact.bind('inview', function(event, isInView, visiblePartX, visiblePartY) { + $(this).unbind(event); + var bookid = $(this).data('bookid'); + var numsiblings = $('.contacts li[data-bookid="'+bookid+'"]').length; + if (isInView && numsiblings >= self.batchnum) { + console.log('This would be a good time to load more contacts.'); + Contacts.UI.Contacts.update(id, bookid, $('#contacts li[data-bookid="'+bookid+'"]').length); + } + }); + } + contactlist.append(contact); + } } }); - Contacts.UI.Card.update(id); + if($('#contacts h3').length > 1) { + $('#contacts li').draggable({ + revert: 'invalid', + axis: 'y', containment: '#contacts', + scroll: true, scrollSensitivity: 100, + opacity: 0.7, helper: 'clone' + }); + } else { + $('#contacts h3').first().addClass('active'); + } + if(opts['startat'] == 0) { // only update card on first load. + Contacts.UI.Card.update(); + } } else{ OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error')); } }); - /*setTimeout(function() { - $('.contacts li').unbind('inview'); - $('.contacts li:visible').bind('inview', function(event, isInView, visiblePartX, visiblePartY) { - if (isInView) { - if (!$(this).find('a').attr('style')) { - $(this).find('a').css('background','url('+OC.filePath('contacts', '', 'thumbnail.php')+'?id='+$(this).data('id')+') no-repeat'); - } - } - })}, 500); - setTimeout(Contacts.UI.Contacts.lazyupdate, 500);*/ - }, - // Add thumbnails to the contact list as they become visible in the viewport. - lazyupdate:function(){ - $('.contacts li').live('inview', function(){ - if (!$(this).find('a').attr('style')) { - $(this).find('a').css('background','url('+OC.filePath('contacts', '', 'thumbnail.php')+'?id='+$(this).data('id')+') no-repeat'); - } - }); }, refreshThumbnail:function(id){ var item = $('.contacts li[data-id="'+id+'"]').find('a'); @@ -1657,13 +1725,6 @@ $(document).ready(function(){ return false; }); - $(document).on('click', '.addressbook', function(event){ - $('#contacts h3').removeClass('active'); - $(this).addClass('active'); - $(this).next().slideToggle(300); - return false; - }); - /*$('.contacts li').bind('inview', function(event, isInView, visiblePartX, visiblePartY) { if (isInView) { //NOTE: I've kept all conditions for future reference ;-) // element is now visible in the viewport @@ -1739,30 +1800,6 @@ $(document).ready(function(){ xhr.send(file); } - $('body').click(function(e){ - if(!$(e.target).is('#contacts_propertymenu_button')) { - $('#contacts_propertymenu_dropdown').hide(); - } - }); - function propertyMenu(){ - var menu = $('#contacts_propertymenu_dropdown'); - if(menu.is(':hidden')) { - menu.show(); - menu.find('li').first().focus(); - } else { - menu.hide(); - } - } - $('#contacts_propertymenu_button').click(propertyMenu); - $('#contacts_propertymenu_button').keydown(propertyMenu); - function propertyMenuItem(){ - var type = $(this).data('type'); - Contacts.UI.Card.addProperty(type); - $('#contacts_propertymenu_dropdown').hide(); - } - $('#contacts_propertymenu_dropdown a').click(propertyMenuItem); - $('#contacts_propertymenu_dropdown a').keydown(propertyMenuItem); - Contacts.UI.loadHandlers(); Contacts.UI.Contacts.update(id); }); diff --git a/apps/contacts/lib/VCFExportPlugin.php b/apps/contacts/lib/VCFExportPlugin.php new file mode 100644 index 00000000000..6554cb258e8 --- /dev/null +++ b/apps/contacts/lib/VCFExportPlugin.php @@ -0,0 +1,100 @@ +<?php + +/** + * VCF Exporter + * + * This plugin adds the ability to export entire address books as .vcf files. + * This is useful for clients that don't support CardDAV yet. They often do + * support vcf files. + * + * @package Sabre + * @subpackage CardDAV + * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved. + * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License + */ +class Sabre_CardDAV_VCFExportPlugin extends Sabre_DAV_ServerPlugin { + + /** + * Reference to Server class + * + * @var Sabre_DAV_Server + */ + private $server; + + /** + * Initializes the plugin and registers event handlers + * + * @param Sabre_DAV_Server $server + * @return void + */ + public function initialize(Sabre_DAV_Server $server) { + + $this->server = $server; + $this->server->subscribeEvent('beforeMethod',array($this,'beforeMethod'), 90); + + } + + /** + * 'beforeMethod' event handles. This event handles intercepts GET requests ending + * with ?export + * + * @param string $method + * @param string $uri + * @return bool + */ + public function beforeMethod($method, $uri) { + + if ($method!='GET') return; + if ($this->server->httpRequest->getQueryString()!='export') return; + + // splitting uri + list($uri) = explode('?',$uri,2); + + $node = $this->server->tree->getNodeForPath($uri); + + if (!($node instanceof Sabre_CardDAV_IAddressBook)) return; + + // Checking ACL, if available. + if ($aclPlugin = $this->server->getPlugin('acl')) { + $aclPlugin->checkPrivileges($uri, '{DAV:}read'); + } + + $this->server->httpResponse->setHeader('Content-Type','text/directory'); + $this->server->httpResponse->sendStatus(200); + + $nodes = $this->server->getPropertiesForPath($uri, array( + '{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}address-data', + ),1); + + $this->server->httpResponse->sendBody($this->generateVCF($nodes)); + + // Returning false to break the event chain + return false; + + } + + /** + * Merges all vcard objects, and builds one big vcf export + * + * @param array $nodes + * @return string + */ + public function generateVCF(array $nodes) { + $objects = array(); + + foreach($nodes as $node) { + + if (!isset($node[200]['{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}address-data'])) { + continue; + } + $nodeData = $node[200]['{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}address-data']; + $objects[] = $nodeData; + + } + + return implode("\r\n", $objects); + + } + +} diff --git a/apps/contacts/lib/addressbook.php b/apps/contacts/lib/addressbook.php index 4f00ce1f9e3..4077d26e58a 100644 --- a/apps/contacts/lib/addressbook.php +++ b/apps/contacts/lib/addressbook.php @@ -41,28 +41,63 @@ class OC_Contacts_Addressbook{ /** * @brief Returns the list of addressbooks for a specific user. * @param string $uid + * @param boolean $active Only return addressbooks with this $active state, default(=false) is don't care * @return array or false. */ - public static function all($uid){ + public static function all($uid, $active=false){ + $values = array($uid); + $active_where = ''; + if ($active){ + $active_where = ' AND active = ?'; + $values[] = 1; + } try { - $stmt = OCP\DB::prepare( 'SELECT * FROM *PREFIX*contacts_addressbooks WHERE userid = ? ORDER BY displayname' ); - $result = $stmt->execute(array($uid)); + $stmt = OCP\DB::prepare( 'SELECT * FROM *PREFIX*contacts_addressbooks WHERE userid = ? ' . $active_where . ' ORDER BY displayname' ); + $result = $stmt->execute($values); } catch(Exception $e) { OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.' exception: '.$e->getMessage(),OCP\Util::ERROR); OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.' uid: '.$uid,OCP\Util::DEBUG); return false; } - $addressbooks = array(); while( $row = $result->fetchRow()){ $addressbooks[] = $row; } $addressbooks = array_merge($addressbooks, OCP\Share::getItemsSharedWith('addressbook', OC_Contacts_Share::FORMAT_ADDRESSBOOKS)); + if(!$active && !count($addressbooks)) { + self::addDefault($uid); + } return $addressbooks; } /** + * @brief Get active addressbook IDs for a user. + * @param integer $uid User id. If null current user will be used. + * @return array + */ + public static function activeIds($uid = null){ + if(is_null($uid)){ + $uid = OCP\USER::getUser(); + } + $activeaddressbooks = self::all($uid, true); + $ids = array(); + foreach($activeaddressbooks as $addressbook) { + $ids[] = $addressbook['id']; + } + return $ids; + } + + /** + * @brief Returns the list of active addressbooks for a specific user. + * @param string $uid + * @return array + */ + public static function active($uid){ + return self::all($uid, true); + } + + /** * @brief Returns the list of addressbooks for a principal (DAV term of user) * @param string $principaluri * @return array @@ -113,10 +148,17 @@ class OC_Contacts_Addressbook{ * @return insertid */ public static function add($uid,$name,$description=''){ - $all = self::all($uid); + try { + $stmt = OCP\DB::prepare( 'SELECT uri FROM *PREFIX*contacts_addressbooks WHERE userid = ? ' ); + $result = $stmt->execute(array($uid)); + } catch(Exception $e) { + OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.' exception: '.$e->getMessage(),OCP\Util::ERROR); + OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.' uid: '.$uid,OCP\Util::DEBUG); + return false; + } $uris = array(); - foreach($all as $i){ - $uris[] = $i['uri']; + while($row = $result->fetchRow()){ + $uris[] = $row['uri']; } $uri = self::createURI($name, $uris ); @@ -186,88 +228,6 @@ class OC_Contacts_Addressbook{ return true; } - public static function cleanArray($array, $remove_null_number = true){ - $new_array = array(); - - $null_exceptions = array(); - - foreach ($array as $key => $value){ - $value = trim($value); - - if($remove_null_number){ - $null_exceptions[] = '0'; - } - - if(!in_array($value, $null_exceptions) && $value != "") { - $new_array[] = $value; - } - } - return $new_array; - } - - /** - * @brief Get active addressbooks for a user. - * @param integer $uid User id. If null current user will be used. - * @return array - */ - public static function activeIds($uid = null){ - if(is_null($uid)){ - $uid = OCP\USER::getUser(); - } - $prefbooks = OCP\Config::getUserValue($uid,'contacts','openaddressbooks',null); - if(!$prefbooks){ - $addressbooks = OC_Contacts_Addressbook::all($uid); - if(count($addressbooks) == 0){ - self::addDefault($uid); - } - } - $prefbooks = OCP\Config::getUserValue($uid,'contacts','openaddressbooks',null); - return explode(';',$prefbooks); - } - - /** - * @brief Returns the list of active addressbooks for a specific user. - * @param string $uid - * @return array - */ - public static function active($uid){ - if(is_null($uid)){ - $uid = OCP\USER::getUser(); - } - $active = self::activeIds($uid); - $shared = OCP\Share::getItemsSharedWith('addressbook', OC_Contacts_Share::FORMAT_ADDRESSBOOKS); - $addressbooks = array(); - $ids_sql = join(',', array_fill(0, count($active), '?')); - $prep = 'SELECT * FROM *PREFIX*contacts_addressbooks WHERE id IN ('.$ids_sql.') ORDER BY displayname'; - try { - $stmt = OCP\DB::prepare( $prep ); - $result = $stmt->execute($active); - } catch(Exception $e) { - OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', exception: '.$e->getMessage(),OCP\Util::ERROR); - OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', uid: '.$uid,OCP\Util::DEBUG); - OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', ids: '.join(',', $active),OCP\Util::DEBUG); - OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', SQL:'.$prep,OCP\Util::DEBUG); - } - - while( $row = $result->fetchRow()){ - // Insert formatted shared addressbook instead - if ($row['userid'] != $uid) { - foreach ($shared as $addressbook) { - if ($addressbook['id'] == $row['id']) { - $addressbooks[] = $addressbook; - break; - } - } - } else { - $addressbooks[] = $row; - } - } - if(!count($addressbooks)) { - self::addDefault($uid); - } - return $addressbooks; - } - /** * @brief Activates an addressbook * @param integer $id @@ -275,30 +235,16 @@ class OC_Contacts_Addressbook{ * @return boolean */ public static function setActive($id,$active){ - // Need these ones for checking uri - //$addressbook = self::find($id); - - if(is_null($id)){ - $id = 0; - } - - $openaddressbooks = self::activeIds(); - if($active) { - if(!in_array($id, $openaddressbooks)) { - $openaddressbooks[] = $id; - } - } else { - if(in_array($id, $openaddressbooks)) { - unset($openaddressbooks[array_search($id, $openaddressbooks)]); - } + $sql = 'UPDATE *PREFIX*contacts_addressbooks SET active = ? WHERE id = ?'; + OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', id: '.$id.', active: '.intval($active),OCP\Util::ERROR); + try { + $stmt = OCP\DB::prepare($sql); + $stmt->execute(array(intval($active), $id)); + return true; + } catch(Exception $e) { + OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', exception for '.$id.': '.$e->getMessage(),OCP\Util::ERROR); + return false; } - // NOTE: Ugly hack... - $openaddressbooks = self::cleanArray($openaddressbooks, false); - sort($openaddressbooks, SORT_NUMERIC); - // FIXME: I alway end up with a ';' prepending when imploding the array..? - OCP\Config::setUserValue(OCP\USER::getUser(),'contacts','openaddressbooks',implode(';', $openaddressbooks)); - - return true; } /** @@ -307,8 +253,15 @@ class OC_Contacts_Addressbook{ * @return boolean */ public static function isActive($id){ - //OCP\Util::writeLog('contacts','OC_Contacts_Addressbook::isActive('.$id.'):'.in_array($id, self::activeIds()), OCP\Util::DEBUG); - return in_array($id, self::activeIds()); + $sql = 'SELECT active FROM *PREFIX*contacts_addressbooks WHERE id = ?'; + try { + $stmt = OCP\DB::prepare( $sql ); + $result = $stmt->execute(array($id)); + $row = $result->fetchRow(); + return (bool)$row['active']; + } catch(Exception $e) { + OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', exception: '.$e->getMessage(),OCP\Util::ERROR); + } } /** diff --git a/apps/contacts/lib/app.php b/apps/contacts/lib/app.php index 3b16ffd5c16..ed2300adae0 100644 --- a/apps/contacts/lib/app.php +++ b/apps/contacts/lib/app.php @@ -10,7 +10,6 @@ * This class manages our app actions */ OC_Contacts_App::$l10n = OC_L10N::get('contacts'); -OC_Contacts_App::$categories = new OC_VCategories('contacts'); class OC_Contacts_App { /* * @brief language object for calendar app @@ -139,31 +138,55 @@ class OC_Contacts_App { } } - /* + /** * @brief returns the vcategories object of the user * @return (object) $vcategories */ protected static function getVCategories() { if (is_null(self::$categories)) { - self::$categories = new OC_VCategories('contacts'); + self::$categories = new OC_VCategories('contacts', null, self::getDefaultCategories()); } return self::$categories; } - /* + /** * @brief returns the categories for the user * @return (Array) $categories */ public static function getCategories() { - $categories = self::$categories->categories(); + $categories = self::getVCategories()->categories(); if(count($categories) == 0) { self::scanCategories(); $categories = self::$categories->categories(); } - return $categories; + return ($categories ? $categories : self::getDefaultCategories()); } /** + * @brief returns the default categories of ownCloud + * @return (array) $categories + */ + public static function getDefaultCategories(){ + return array( + (string)self::$l10n->t('Birthday'), + (string)self::$l10n->t('Business'), + (string)self::$l10n->t('Call'), + (string)self::$l10n->t('Clients'), + (string)self::$l10n->t('Deliverer'), + (string)self::$l10n->t('Holidays'), + (string)self::$l10n->t('Ideas'), + (string)self::$l10n->t('Journey'), + (string)self::$l10n->t('Jubilee'), + (string)self::$l10n->t('Meeting'), + (string)self::$l10n->t('Other'), + (string)self::$l10n->t('Personal'), + (string)self::$l10n->t('Projects'), + (string)self::$l10n->t('Questions'), + (string)self::$l10n->t('Work'), + ); + } + + /** * scan vcards for categories. * @param $vccontacts VCards to scan. null to check all vcards for the current user. */ @@ -175,16 +198,19 @@ class OC_Contacts_App { foreach($vcaddressbooks as $vcaddressbook) { $vcaddressbookids[] = $vcaddressbook['id']; } - $vccontacts = OC_Contacts_VCard::all($vcaddressbookids); - } - } - if(is_array($vccontacts) && count($vccontacts) > 0) { - $cards = array(); - foreach($vccontacts as $vccontact) { - $cards[] = $vccontact['carddata']; + $start = 0; + $batchsize = 10; + while($vccontacts = OC_Contacts_VCard::all($vcaddressbookids, $start, $batchsize)){ + $cards = array(); + foreach($vccontacts as $vccontact) { + $cards[] = $vccontact['carddata']; + } + OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', scanning: '.$batchsize.' starting from '.$start,OCP\Util::DEBUG); + // only reset on first batch. + self::getVCategories()->rescan($cards, true, ($start==0?true:false)); + $start += $batchsize; + } } - - self::$categories->rescan($cards); } } diff --git a/apps/contacts/lib/connector_sabre.php b/apps/contacts/lib/connector_sabre.php index c967e906601..99b94fc767e 100644 --- a/apps/contacts/lib/connector_sabre.php +++ b/apps/contacts/lib/connector_sabre.php @@ -138,7 +138,9 @@ class OC_Connector_Sabre_CardDAV extends Sabre_CardDAV_Backend_Abstract { foreach($data as $i){ $cards[] = array( 'id' => $i['id'], - 'carddata' => $i['carddata'], + //'carddata' => $i['carddata'], + 'size' => strlen($i['carddata']), + 'etag' => md5($i['carddata']), 'uri' => $i['uri'], 'lastmodified' => $i['lastmodified'] ); } diff --git a/apps/contacts/lib/hooks.php b/apps/contacts/lib/hooks.php index 9794a9c9b94..d91d3c565b5 100644 --- a/apps/contacts/lib/hooks.php +++ b/apps/contacts/lib/hooks.php @@ -90,9 +90,10 @@ class OC_Contacts_Hooks{ if ($birthday) { $date = new DateTime($birthday); $vevent = new OC_VObject('VEVENT'); - $vevent->setDateTime('LAST-MODIFIED', new DateTime($vcard->REV)); + //$vevent->setDateTime('LAST-MODIFIED', new DateTime($vcard->REV)); $vevent->setDateTime('DTSTART', $date, Sabre_VObject_Element_DateTime::DATE); $vevent->setString('DURATION', 'P1D'); + $vevent->setString('UID', substr(md5(rand().time()),0,10)); // DESCRIPTION? $vevent->setString('RRULE', 'FREQ=YEARLY'); $title = str_replace('{name}', $vcard->getAsString('FN'), OC_Contacts_App::$l10n->t('{name}\'s Birthday')); @@ -101,6 +102,7 @@ class OC_Contacts_Hooks{ 'vevent' => $vevent, 'repeating' => true, 'summary' => $title, + 'calendardata' => "BEGIN:VCALENDAR\nVERSION:2.0\nPRODID:ownCloud Contacts " . OCP\App::getAppVersion('contacts') . "\n" . $vevent->serialize() . "END:VCALENDAR" ); } } diff --git a/apps/contacts/lib/vcard.php b/apps/contacts/lib/vcard.php index bf22be0de74..e3b65605624 100644 --- a/apps/contacts/lib/vcard.php +++ b/apps/contacts/lib/vcard.php @@ -47,11 +47,18 @@ class OC_Contacts_VCard{ * The cards are associative arrays. You'll find the original vCard in * ['carddata'] */ - public static function all($id){ + public static function all($id, $start=null, $num=null){ + $limitsql = ''; + if(!is_null($num)) { + $limitsql = ' LIMIT '.$num; + } + if(!is_null($start) && !is_null($num)) { + $limitsql .= ' OFFSET '.$start.' '; + } $result = null; if(is_array($id) && count($id)) { $id_sql = join(',', array_fill(0, count($id), '?')); - $prep = 'SELECT * FROM *PREFIX*contacts_cards WHERE addressbookid IN ('.$id_sql.') ORDER BY fullname'; + $prep = 'SELECT * FROM *PREFIX*contacts_cards WHERE addressbookid IN ('.$id_sql.') ORDER BY fullname '.$limitsql; try { $stmt = OCP\DB::prepare( $prep ); $result = $stmt->execute($id); @@ -63,7 +70,8 @@ class OC_Contacts_VCard{ } } elseif(is_int($id) || is_string($id)) { try { - $stmt = OCP\DB::prepare( 'SELECT * FROM *PREFIX*contacts_cards WHERE addressbookid = ? ORDER BY fullname' ); + $sql = 'SELECT * FROM *PREFIX*contacts_cards WHERE addressbookid = ? ORDER BY fullname'.$limitsql; + $stmt = OCP\DB::prepare( $sql ); $result = $stmt->execute(array($id)); } catch(Exception $e) { OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', exception: '.$e->getMessage(),OCP\Util::ERROR); diff --git a/apps/contacts/settings.php b/apps/contacts/settings.php index c88fed0b4d6..a079499381b 100644 --- a/apps/contacts/settings.php +++ b/apps/contacts/settings.php @@ -1,6 +1,6 @@ <?php $tmpl = new OCP\Template( 'contacts', 'settings'); +$tmpl->assign('addressbooks', OC_Contacts_Addressbook::all(OCP\USER::getUser()), false); return $tmpl->fetchPage(); -?> diff --git a/apps/contacts/templates/index.php b/apps/contacts/templates/index.php index 0d4219c9f2d..5b49b68e954 100644 --- a/apps/contacts/templates/index.php +++ b/apps/contacts/templates/index.php @@ -9,14 +9,14 @@ </div> <div id="bottomcontrols"> <form> - <button class="svg" id="contacts_newcontact" title="<?php echo $l->t('Add Contact'); ?>"><img class="svg" src="<?php echo OCP\Util::linkTo('contacts', 'img/contact-new.svg'); ?>" alt="<?php echo $l->t('Add Contact'); ?>" /></button> + <button class="svg" id="contacts_newcontact" title="<?php echo $l->t('Add Contact'); ?>"><img class="svg" src="<?php echo OCP\Util::imagePath('contacts', 'contact-new.svg'); ?>" alt="<?php echo $l->t('Add Contact'); ?>" /></button> <button class="svg" id="chooseaddressbook" title="<?php echo $l->t('Addressbooks'); ?>"><img class="svg" src="core/img/actions/settings.svg" alt="<?php echo $l->t('Addressbooks'); ?>" /></button> </form> </div> </div> <div id="rightcontent" class="rightcontent" data-id="<?php echo $_['id']; ?>"> <?php - if ($_['id']){ + if($_['has_contacts']){ echo $this->inc('part.contact'); } else{ diff --git a/apps/contacts/templates/part.contact.php b/apps/contacts/templates/part.contact.php index 5757563fe5b..4233bffede3 100644 --- a/apps/contacts/templates/part.contact.php +++ b/apps/contacts/templates/part.contact.php @@ -9,16 +9,19 @@ $id = isset($_['id']) ? $_['id'] : ''; <input type="hidden" class="max_human_file_size" value="(max <?php echo $_['uploadMaxHumanFilesize']; ?>)"> <input id="file_upload_start" type="file" accept="image/*" name="imagefile" /> </form> - <div id="actionbar"> - <button class="svg action" id="contacts_downloadcard" title="<?php echo $l->t('Download contact');?>"></button> - <button class="svg action" id="contacts_deletecard" title="<?php echo $l->t('Delete contact');?>"></button> - </div> <div id="contact_photo" class="contactsection"> <iframe name="file_upload_target" id='file_upload_target' src=""></iframe> <div class="tip propertycontainer" id="contacts_details_photo_wrapper" title="<?php echo $l->t('Drop photo to upload'); ?> (max <?php echo $_['uploadMaxHumanFilesize']; ?>)" data-element="PHOTO"> + <ul id="phototools" class="transparent hidden"> + <li><a class="svg delete" title="<?php echo $l->t('Delete current photo'); ?>"></a></li> + <li><a class="svg edit" title="<?php echo $l->t('Edit current photo'); ?>"></a></li> + <li><a class="svg upload" title="<?php echo $l->t('Upload new photo'); ?>"></a></li> + <li><a class="svg cloud" title="<?php echo $l->t('Select photo from ownCloud'); ?>"></a></li> + </ul> </div> + <img /> </div> <!-- contact_photo --> <div id="contact_identity" class="contactsection"> @@ -101,20 +104,23 @@ $id = isset($_['id']) ? $_['id'] : ''; </form> </div> <!-- contact_note --> - <div id="contacts_propertymenu"> - <button class="button" id="contacts_propertymenu_button"><?php echo $l->t('Add field'); ?></button> - <ul id="contacts_propertymenu_dropdown" role="menu" class="hidden"> - <li><a role="menuitem" data-type="PHOTO"><?php echo $l->t('Profile picture'); ?></a></li> - <li><a role="menuitem" data-type="ORG"><?php echo $l->t('Organization'); ?></a></li> - <li><a role="menuitem" data-type="NICKNAME"><?php echo $l->t('Nickname'); ?></a></li> - <li><a role="menuitem" data-type="BDAY"><?php echo $l->t('Birthday'); ?></a></li> - <li><a role="menuitem" data-type="TEL"><?php echo $l->t('Phone'); ?></a></li> - <li><a role="menuitem" data-type="EMAIL"><?php echo $l->t('Email'); ?></a></li> - <li><a role="menuitem" data-type="ADR"><?php echo $l->t('Address'); ?></a></li> - <li><a role="menuitem" data-type="NOTE"><?php echo $l->t('Note'); ?></a></li> - <li><a role="menuitem" data-type="URL"><?php echo $l->t('Web site'); ?></a></li> - <li><a role="menuitem" data-type="CATEGORIES"><?php echo $l->t('Groups'); ?></a></li> - </ul> + <div id="actionbar"> + <div id="contacts_propertymenu"> + <button class="button" id="contacts_propertymenu_button"><?php echo $l->t('Add field'); ?></button> + <ul id="contacts_propertymenu_dropdown" role="menu" class="hidden"> + <li><a role="menuitem" data-type="ORG"><?php echo $l->t('Organization'); ?></a></li> + <li><a role="menuitem" data-type="NICKNAME"><?php echo $l->t('Nickname'); ?></a></li> + <li><a role="menuitem" data-type="BDAY"><?php echo $l->t('Birthday'); ?></a></li> + <li><a role="menuitem" data-type="TEL"><?php echo $l->t('Phone'); ?></a></li> + <li><a role="menuitem" data-type="EMAIL"><?php echo $l->t('Email'); ?></a></li> + <li><a role="menuitem" data-type="ADR"><?php echo $l->t('Address'); ?></a></li> + <li><a role="menuitem" data-type="NOTE"><?php echo $l->t('Note'); ?></a></li> + <li><a role="menuitem" data-type="URL"><?php echo $l->t('Web site'); ?></a></li> + <li><a role="menuitem" data-type="CATEGORIES"><?php echo $l->t('Groups'); ?></a></li> + </ul> + </div> + <button class="svg action" id="contacts_downloadcard" title="<?php echo $l->t('Download contact');?>"></button> + <button class="svg action" id="contacts_deletecard" title="<?php echo $l->t('Delete contact');?>"></button> </div> </div> <!-- card --> diff --git a/apps/contacts/templates/part.contactphoto.php b/apps/contacts/templates/part.contactphoto.php deleted file mode 100644 index bddf4cc8a81..00000000000 --- a/apps/contacts/templates/part.contactphoto.php +++ /dev/null @@ -1,16 +0,0 @@ -<?php -$id = $_['id']; -$wattr = isset($_['width'])?'width="'.$_['width'].'"':''; -$hattr = isset($_['height'])?'height="'.$_['height'].'"':''; -$rand = isset($_['refresh'])?'&refresh='.rand():''; -?> -<ul id="phototools" class="transparent hidden"> - <li><a class="svg delete" title="<?php echo $l->t('Delete current photo'); ?>"></a></li> - <li><a class="svg edit" title="<?php echo $l->t('Edit current photo'); ?>"></a></li> - <li><a class="svg upload" title="<?php echo $l->t('Upload new photo'); ?>"></a></li> - <li><a class="svg cloud" title="<?php echo $l->t('Select photo from ownCloud'); ?>"></a></li> -</ul> -<img class="loading" id="contacts_details_photo" <?php echo $wattr; ?> <?php echo $hattr; ?> src="<?php echo OCP\Util::linkToAbsolute('contacts', 'photo.php'); ?>?id=<?php echo $id.$rand; ?>" /> -<progress id="contacts_details_photo_progress" style="display:none;" value="0" max="100">0 %</progress> - - diff --git a/apps/contacts/templates/part.contacts.php b/apps/contacts/templates/part.contacts.php deleted file mode 100644 index c33c5832e82..00000000000 --- a/apps/contacts/templates/part.contacts.php +++ /dev/null @@ -1,10 +0,0 @@ -<?php -foreach($_['books'] as $id => $addressbook) { - echo '<h3 class="addressbook" data-id="'.$id.'">'.$addressbook['displayname'].'</h3>'; - echo '<ul class="contacts hidden" data-id="'.$id.'">'; - foreach($addressbook['contacts'] as $contact) { - echo '<li role="button" data-bookid="'.$contact['addressbookid'].'" data-id="'.$contact['id'].'"><a href="'.link_to('contacts','index.php').'&id='.$contact['id'].'" style="background: url('.link_to('contacts','thumbnail.php').'?id='.$contact['id'].') no-repeat scroll 0 0 transparent;">'.$contact['displayname'].'</a></li>'; - } - echo '</ul>'; -} -?> diff --git a/apps/contacts/templates/part.importaddressbook.php b/apps/contacts/templates/part.importaddressbook.php index 01f8dd77d0a..8ceb5f3538b 100644 --- a/apps/contacts/templates/part.importaddressbook.php +++ b/apps/contacts/templates/part.importaddressbook.php @@ -12,6 +12,7 @@ <th><?php echo $l->t('Select address book to import to:') ?></th> <td> <form id="import_upload_form" action="<?php echo OCP\Util::linkTo('contacts', 'ajax/uploadimport.php'); ?>" method="post" enctype="multipart/form-data" target="import_upload_target"> + <input type="hidden" name="requesttoken" value="<?php echo $_['requesttoken'] ?>"> <select id="book" name="book" class="float"> <?php $contacts_options = OC_Contacts_Addressbook::all(OCP\USER::getUser()); diff --git a/apps/contacts/templates/settings.php b/apps/contacts/templates/settings.php index 216003b6c69..f520559d143 100644 --- a/apps/contacts/templates/settings.php +++ b/apps/contacts/templates/settings.php @@ -7,6 +7,12 @@ <dd><code><?php echo OCP\Util::linkToRemote('carddav'); ?></code></dd> <dt><?php echo $l->t('iOS/OS X'); ?></dt> <dd><code><?php echo OCP\Util::linkToRemote('carddav'); ?>principals/<?php echo OCP\USER::getUser(); ?></code>/</dd> + <dt><?php echo $l->t('Read only vCard directory link(s)'); ?></dt> + <dd> + <?php foreach($_['addressbooks'] as $addressbook) { ?> + <a href="<?php echo OCP\Util::linkToRemote('carddav').'addressbooks/'.OCP\USER::getUser().'/'.rawurlencode($addressbook['uri']) ?>?export"><?php echo $addressbook['displayname'] ?></a><br /> + <?php } ?> + </dd> </dl> Powered by <a href="http://geonames.org/" target="_blank">geonames.org webservice</a> </fieldset> diff --git a/apps/external/ajax/setsites.php b/apps/external/ajax/setsites.php index 772863974ae..0f9e061d0e0 100644 --- a/apps/external/ajax/setsites.php +++ b/apps/external/ajax/setsites.php @@ -8,6 +8,7 @@ OCP\User::checkAdminUser(); +OCP\JSON::callCheck(); $sites = array(); for ($i = 0; $i < sizeof($_POST['site_name']); $i++) { @@ -22,4 +23,3 @@ else OCP\Config::setAppValue('external', 'sites', json_encode($sites)); echo 'true'; -?> diff --git a/apps/external/index.php b/apps/external/index.php index 81819e76e2f..3b6f06e1bff 100644 --- a/apps/external/index.php +++ b/apps/external/index.php @@ -40,4 +40,3 @@ if (isset($_GET['id'])) { $tmpl->printPage(); } } -?> diff --git a/apps/external/lib/external.php b/apps/external/lib/external.php index 9fff5d5569a..d13a7cf6dd7 100644 --- a/apps/external/lib/external.php +++ b/apps/external/lib/external.php @@ -32,5 +32,3 @@ class OC_External { } } - -?> diff --git a/apps/external/settings.php b/apps/external/settings.php index c109733e548..488444c119a 100644 --- a/apps/external/settings.php +++ b/apps/external/settings.php @@ -7,4 +7,3 @@ OCP\Util::addscript( "external", "admin" ); $tmpl = new OCP\Template( 'external', 'settings'); return $tmpl->fetchPage(); -?> diff --git a/apps/files/ajax/autocomplete.php b/apps/files/ajax/autocomplete.php index 7ff34da96b3..e504bb24bf8 100644 --- a/apps/files/ajax/autocomplete.php +++ b/apps/files/ajax/autocomplete.php @@ -52,5 +52,3 @@ if(OC_Filesystem::file_exists($base) and OC_Filesystem::is_dir($base)){ } } OCP\JSON::encodedPrint($files); - -?> diff --git a/apps/files/ajax/delete.php b/apps/files/ajax/delete.php index ed155de0dc7..695f803884e 100644 --- a/apps/files/ajax/delete.php +++ b/apps/files/ajax/delete.php @@ -4,6 +4,7 @@ OCP\JSON::checkLoggedIn(); +OCP\JSON::callCheck(); // Get data $dir = stripslashes($_GET["dir"]); @@ -25,5 +26,3 @@ if($success) { } else { OCP\JSON::error(array("data" => array( "message" => "Could not delete:\n" . $filesWithError ))); } - -?> diff --git a/apps/files/ajax/download.php b/apps/files/ajax/download.php index e9373f5f6ac..b9a4ddaf5e7 100644 --- a/apps/files/ajax/download.php +++ b/apps/files/ajax/download.php @@ -34,4 +34,3 @@ $files = $_GET["files"]; $dir = $_GET["dir"]; OC_Files::get($dir, $files, $_SERVER['REQUEST_METHOD'] == 'HEAD' ? true : false); -?> diff --git a/apps/files/ajax/list.php b/apps/files/ajax/list.php index f0600a179d0..dae0c1a828d 100644 --- a/apps/files/ajax/list.php +++ b/apps/files/ajax/list.php @@ -42,5 +42,3 @@ $list->assign( "files", $files, false ); $data = array('files' => $list->fetchPage()); OCP\JSON::success(array('data' => $data)); - -?> diff --git a/apps/files/ajax/mimeicon.php b/apps/files/ajax/mimeicon.php index 57898cd82d9..80d50f84528 100644 --- a/apps/files/ajax/mimeicon.php +++ b/apps/files/ajax/mimeicon.php @@ -7,5 +7,3 @@ $RUNTIME_NOAPPS=false; print OC_Helper::mimetypeIcon($_GET['mime']); - -?> diff --git a/apps/files/ajax/move.php b/apps/files/ajax/move.php index 945fe4e7b82..3d4003a8edc 100644 --- a/apps/files/ajax/move.php +++ b/apps/files/ajax/move.php @@ -4,6 +4,7 @@ OCP\JSON::checkLoggedIn(); +OCP\JSON::callCheck(); // Get data $dir = stripslashes($_GET["dir"]); @@ -16,5 +17,3 @@ if(OC_Files::move($dir,$file,$target,$file)){ }else{ OCP\JSON::error(array("data" => array( "message" => "Could not move $file" ))); } - -?> diff --git a/apps/files/ajax/newfile.php b/apps/files/ajax/newfile.php index edb78414872..7236deb65c9 100644 --- a/apps/files/ajax/newfile.php +++ b/apps/files/ajax/newfile.php @@ -4,6 +4,7 @@ OCP\JSON::checkLoggedIn(); +OCP\JSON::callCheck(); // Get the params $dir = isset( $_POST['dir'] ) ? stripslashes($_POST['dir']) : ''; diff --git a/apps/files/ajax/newfolder.php b/apps/files/ajax/newfolder.php index c5c37914c6a..ae92bcf09bb 100644 --- a/apps/files/ajax/newfolder.php +++ b/apps/files/ajax/newfolder.php @@ -4,6 +4,7 @@ OCP\JSON::checkLoggedIn(); +OCP\JSON::callCheck(); // Get the params $dir = isset( $_POST['dir'] ) ? stripslashes($_POST['dir']) : ''; diff --git a/apps/files/ajax/rawlist.php b/apps/files/ajax/rawlist.php index 7cb02f79673..d159f6e152f 100644 --- a/apps/files/ajax/rawlist.php +++ b/apps/files/ajax/rawlist.php @@ -22,5 +22,3 @@ foreach( OC_Files::getdirectorycontent( $dir, $mimetype ) as $i ){ } OCP\JSON::success(array('data' => $files)); - -?> diff --git a/apps/files/ajax/rename.php b/apps/files/ajax/rename.php index e2fa3d54a61..45448279fa1 100644 --- a/apps/files/ajax/rename.php +++ b/apps/files/ajax/rename.php @@ -4,6 +4,7 @@ OCP\JSON::checkLoggedIn(); +OCP\JSON::callCheck(); // Get data $dir = stripslashes($_GET["dir"]); @@ -17,5 +18,3 @@ if( OC_Files::move( $dir, $file, $dir, $newname )) { else{ OCP\JSON::error(array("data" => array( "message" => "Unable to rename file" ))); } - -?> diff --git a/apps/files/ajax/timezone.php b/apps/files/ajax/timezone.php index cafb5074ece..0be441a36a2 100644 --- a/apps/files/ajax/timezone.php +++ b/apps/files/ajax/timezone.php @@ -3,4 +3,4 @@ // see lib/base.php for an example //session_start(); $_SESSION['timezone'] = $_GET['time']; -?> +
\ No newline at end of file diff --git a/apps/files/ajax/upload.php b/apps/files/ajax/upload.php index b779924cfb4..74e6eb560d8 100644 --- a/apps/files/ajax/upload.php +++ b/apps/files/ajax/upload.php @@ -7,6 +7,7 @@ OCP\JSON::setContentTypeHeader('text/plain'); OCP\JSON::checkLoggedIn(); +OCP\JSON::callCheck(); if (!isset($_FILES['files'])) { OCP\JSON::error(array("data" => array( "message" => "No file was uploaded. Unknown error" ))); @@ -59,5 +60,3 @@ if(strpos($dir,'..') === false){ } OCP\JSON::error(array('data' => array('error' => $error, "file" => $fileName))); - -?> diff --git a/apps/files/download.php b/apps/files/download.php index 2b5d4e2d876..4e2478d1ad7 100644 --- a/apps/files/download.php +++ b/apps/files/download.php @@ -46,4 +46,3 @@ header('Content-Length: '.OC_Filesystem::filesize($filename)); @ob_end_clean(); OC_Filesystem::readfile( $filename ); -?> diff --git a/apps/files/index.php b/apps/files/index.php index 907dfda3656..79bed8e357e 100644 --- a/apps/files/index.php +++ b/apps/files/index.php @@ -99,5 +99,3 @@ $tmpl->assign( 'uploadMaxFilesize', $maxUploadFilesize); $tmpl->assign( 'uploadMaxHumanFilesize', OCP\Util::humanFileSize($maxUploadFilesize)); $tmpl->assign( 'allowZipDownload', intval(OCP\Config::getSystemValue('allowZipDownload', true))); $tmpl->printPage(); - -?> diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index e6a9a6883af..3645258f98f 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -14,7 +14,7 @@ FileList={ var extension=false; } html+='<td class="filename" style="background-image:url('+img+')"><input type="checkbox" />'; - html+='<a class="name" href="download.php?file='+$('#dir').val()+'/'+name+'"><span class="nametext">'+basename + html+='<a class="name" href="download.php?file='+$('#dir').val().replace(/</, '<').replace(/>/, '>')+'/'+name+'"><span class="nametext">'+basename if(extension){ html+='<span class="extension">'+extension+'</span>'; } diff --git a/apps/files/js/files.js b/apps/files/js/files.js index 3ba473e023d..86c5185bf72 100644 --- a/apps/files/js/files.js +++ b/apps/files/js/files.js @@ -451,7 +451,7 @@ $(document).ready(function() { $(this).append(input); input.focus(); input.change(function(){ - var name=$(this).val(); + var name=getUniqueName($(this).val()); if(type != 'web' && name.indexOf('/')!=-1){ $('#notification').text(t('files','Invalid name, \'/\' is not allowed.')); $('#notification').fadeIn(); @@ -496,6 +496,7 @@ $(document).ready(function() { }else{//or the domain localName=(localName.match(/:\/\/(.[^/]+)/)[1]).replace('www.',''); } + localName = getUniqueName(localName); $.post( OC.filePath('files','ajax','newfile.php'), {dir:$('#dir').val(),source:name,filename:localName}, @@ -737,7 +738,10 @@ getMimeIcon.cache={}; function getUniqueName(name){ if($('tr').filterAttr('data-file',name).length>0){ var parts=name.split('.'); - var extension=parts.pop(); + var extension = ""; + if (parts.length > 1) { + extension=parts.pop(); + } var base=parts.join('.'); numMatch=base.match(/\((\d+)\)/); var num=2; @@ -747,7 +751,10 @@ function getUniqueName(name){ base.pop(); base=base.join('(').trim(); } - name=base+' ('+num+').'+extension; + name=base+' ('+num+')'; + if (extension) { + name = name+'.'+extension; + } return getUniqueName(name); } return name; diff --git a/apps/files/settings.php b/apps/files/settings.php index e5a66239ebd..cd6dd8c1616 100644 --- a/apps/files/settings.php +++ b/apps/files/settings.php @@ -56,5 +56,3 @@ $tmpl = new OCP\Template( "files", "index", "user" ); $tmpl->assign( 'files', $files ); $tmpl->assign( "breadcrumb", $breadcrumb ); $tmpl->printPage(); - -?> diff --git a/apps/files_encryption/js/settings.js b/apps/files_encryption/js/settings.js index 37d62265c94..8cc433246cb 100644 --- a/apps/files_encryption/js/settings.js +++ b/apps/files_encryption/js/settings.js @@ -17,8 +17,8 @@ $(document).ready(function(){ OC.AppConfig.setValue('files_encryption','type_blacklist',blackList); } - $('#enbale_encryption').change(function(){ - var checked=$('#enbale_encryption').is(':checked'); + $('#enable_encryption').change(function(){ + var checked=$('#enable_encryption').is(':checked'); OC.AppConfig.setValue('files_encryption','enable_encryption',(checked)?'true':'false'); }) })
\ No newline at end of file diff --git a/apps/files_encryption/templates/settings.php b/apps/files_encryption/templates/settings.php index 25b5a06f56c..79780d694cf 100644 --- a/apps/files_encryption/templates/settings.php +++ b/apps/files_encryption/templates/settings.php @@ -7,6 +7,6 @@ <option selected="selected" value="<?php echo $type;?>"><?php echo $type;?></option> <?php endforeach;?> </select> - <input type='checkbox' id='enbale_encryption' <?php if($_['encryption_enabled']){echo 'checked="checked"';} ?>></input><label for='enbale_encryption'><?php echo $l->t('Enable Encryption')?></label> + <input type='checkbox' id='enable_encryption' <?php if($_['encryption_enabled']){echo 'checked="checked"';} ?>></input><label for='enable_encryption'><?php echo $l->t('Enable Encryption')?></label> </fieldset> </form> diff --git a/apps/files_encryption/tests/proxy.php b/apps/files_encryption/tests/proxy.php index fcfc4cfb9f0..5463836a209 100644 --- a/apps/files_encryption/tests/proxy.php +++ b/apps/files_encryption/tests/proxy.php @@ -11,6 +11,8 @@ class Test_CryptProxy extends UnitTestCase { private $oldKey; public function setUp(){ + $user=OC_User::getUser(); + $this->oldConfig=OCP\Config::getAppValue('files_encryption','enable_encryption','true'); OCP\Config::setAppValue('files_encryption','enable_encryption','true'); $this->oldKey=isset($_SESSION['enckey'])?$_SESSION['enckey']:null; @@ -30,10 +32,12 @@ class Test_CryptProxy extends UnitTestCase { OC_Filesystem::clearMounts(); OC_Filesystem::mount('OC_Filestorage_Temporary',array(),'/'); + OC_Filesystem::init('/'.$user.'/files'); + //set up the users home folder in the temp storage $rootView=new OC_FilesystemView(''); - $rootView->mkdir('/'.OC_User::getUser()); - $rootView->mkdir('/'.OC_User::getUser().'/files'); + $rootView->mkdir('/'.$user); + $rootView->mkdir('/'.$user.'/files'); } public function tearDown(){ diff --git a/apps/files_external/ajax/addMountPoint.php b/apps/files_external/ajax/addMountPoint.php index 549cb6a3427..e08f805942f 100644 --- a/apps/files_external/ajax/addMountPoint.php +++ b/apps/files_external/ajax/addMountPoint.php @@ -1,6 +1,8 @@ <?php OCP\JSON::checkAppEnabled('files_external'); +OCP\JSON::callCheck(); + if ($_POST['isPersonal'] == 'true') { OCP\JSON::checkLoggedIn(); $isPersonal = true; @@ -9,5 +11,3 @@ if ($_POST['isPersonal'] == 'true') { $isPersonal = false; } OC_Mount_Config::addMountPoint($_POST['mountPoint'], $_POST['class'], $_POST['classOptions'], $_POST['mountType'], $_POST['applicable'], $isPersonal); - -?> diff --git a/apps/files_external/ajax/addRootCertificate.php b/apps/files_external/ajax/addRootCertificate.php new file mode 100644 index 00000000000..d28a7d24b2d --- /dev/null +++ b/apps/files_external/ajax/addRootCertificate.php @@ -0,0 +1,28 @@ +<?php + +OCP\JSON::checkAppEnabled('files_external'); + +$view = \OCP\Files::getStorage("files_external"); +$from = $_FILES['rootcert_import']['tmp_name']; +$path = \OCP\Config::getSystemValue('datadirectory').$view->getAbsolutePath("").'uploads/'; +if(!file_exists($path)) mkdir($path,0700,true); +$to = $path.$_FILES['rootcert_import']['name']; +move_uploaded_file($from, $to); + +//check if it is a PEM certificate, otherwise convert it if possible +$fh = fopen($to, 'r'); +$data = fread($fh, filesize($to)); +fclose($fh); +if (!strpos($data, 'BEGIN CERTIFICATE')) { + $pem = chunk_split(base64_encode($data), 64, "\n");
+ $pem = "-----BEGIN CERTIFICATE-----\n".$pem."-----END CERTIFICATE-----\n"; + $fh = fopen($to, 'w'); + fwrite($fh, $pem); + fclose($fh); +} + +OC_Mount_Config::createCertificateBundle(); + +header("Location: settings/personal.php"); +exit; +?>
\ No newline at end of file diff --git a/apps/files_external/ajax/removeMountPoint.php b/apps/files_external/ajax/removeMountPoint.php index b77b306bcb5..aa446426202 100644 --- a/apps/files_external/ajax/removeMountPoint.php +++ b/apps/files_external/ajax/removeMountPoint.php @@ -1,6 +1,8 @@ <?php OCP\JSON::checkAppEnabled('files_external'); +OCP\JSON::callCheck(); + if ($_POST['isPersonal'] == 'true') { OCP\JSON::checkLoggedIn(); $isPersonal = true; @@ -9,5 +11,3 @@ if ($_POST['isPersonal'] == 'true') { $isPersonal = false; } OC_Mount_Config::removeMountPoint($_POST['mountPoint'], $_POST['mountType'], $_POST['applicable'], $isPersonal); - -?> diff --git a/apps/files_external/ajax/removeRootCertificate.php b/apps/files_external/ajax/removeRootCertificate.php new file mode 100644 index 00000000000..a00922f4210 --- /dev/null +++ b/apps/files_external/ajax/removeRootCertificate.php @@ -0,0 +1,10 @@ +<?php + +OCP\JSON::checkAppEnabled('files_external'); + +$view = \OCP\Files::getStorage("files_external"); +$cert = $_POST['cert']; +$file = \OCP\Config::getSystemValue('datadirectory').$view->getAbsolutePath("").'uploads/'.$cert; +unlink($file); +OC_Mount_Config::createCertificateBundle(); +?>
\ No newline at end of file diff --git a/apps/files_external/js/dropbox.js b/apps/files_external/js/dropbox.js index 67f3c46a6ed..08796cbbdc9 100644 --- a/apps/files_external/js/dropbox.js +++ b/apps/files_external/js/dropbox.js @@ -23,7 +23,6 @@ $(document).ready(function() { }); } } - return false; } }); diff --git a/apps/files_external/js/google.js b/apps/files_external/js/google.js index 84c74c57421..55042194c7d 100644 --- a/apps/files_external/js/google.js +++ b/apps/files_external/js/google.js @@ -24,7 +24,6 @@ $(document).ready(function() { }); } } - return false; } }); diff --git a/apps/files_external/js/settings.js b/apps/files_external/js/settings.js index 57188a6a266..0d942e7845b 100644 --- a/apps/files_external/js/settings.js +++ b/apps/files_external/js/settings.js @@ -1,4 +1,4 @@ -OC.MountConfig={ +OC.MountConfig={ saveStorage:function(tr) { var mountPoint = $(tr).find('.mountPoint input').val(); if (mountPoint == '') { @@ -27,7 +27,7 @@ OC.MountConfig={ } }); if (addMountPoint) { - if ($('#externalStorage').data('admin')) { + if ($('#externalStorage').data('admin') === true) { var isPersonal = false; var multiselect = $(tr).find('.chzn-select').val(); var oldGroups = $(tr).find('.applicable').data('applicable-groups'); @@ -68,12 +68,12 @@ OC.MountConfig={ } $(document).ready(function() { - $('.chzn-select').chosen(); $('#selectBackend').live('change', function() { var tr = $(this).parent().parent(); - $('#externalStorage tbody').last().append($(tr).clone()); + $('#externalStorage tbody').append($(tr).clone()); + $('#externalStorage tbody tr').last().find('.mountPoint input').val(''); var selected = $(this).find('option:selected').text(); var backendClass = $(this).val(); $(this).parent().text(selected); @@ -103,6 +103,7 @@ $(document).ready(function() { }); $('.chz-select').chosen(); $(tr).find('td').last().attr('class', 'remove'); + $(tr).find('td').last().removeAttr('style'); $(tr).removeAttr('id'); $(this).remove(); }); @@ -114,10 +115,13 @@ $(document).ready(function() { $('td.remove>img').live('click', function() { var tr = $(this).parent().parent(); var mountPoint = $(tr).find('.mountPoint input').val(); - if (mountPoint == '') { - return false; + if (!mountPoint) { + var row=this.parentNode.parentNode; + $.post(OC.filePath('files_external', 'ajax', 'removeRootCertificate.php'), { cert: row.id }); + $(tr).remove(); + return true; } - if ($('#externalStorage').data('admin')) { + if ($('#externalStorage').data('admin') === true) { var isPersonal = false; var multiselect = $(tr).find('.chzn-select').val(); $.each(multiselect, function(index, value) { diff --git a/apps/files_external/lib/amazons3.php b/apps/files_external/lib/amazons3.php index b8e5b9b079b..9feb490dac0 100644 --- a/apps/files_external/lib/amazons3.php +++ b/apps/files_external/lib/amazons3.php @@ -96,8 +96,8 @@ class OC_Filestorage_AmazonS3 extends OC_Filestorage_Common { foreach ($response->body->CommonPrefixes as $object) { $files[] = basename($object->Prefix); } - OC_FakeDirStream::$dirs['amazons3'] = $files; - return opendir('fakedir://amazons3'); + OC_FakeDirStream::$dirs['amazons3'.$path] = $files; + return opendir('fakedir://amazons3'.$path); } return false; } diff --git a/apps/files_external/lib/config.php b/apps/files_external/lib/config.php index 5b9e00a3783..5630df77a91 100755 --- a/apps/files_external/lib/config.php +++ b/apps/files_external/lib/config.php @@ -45,7 +45,7 @@ class OC_Mount_Config { 'OC_Filestorage_FTP' => array('backend' => 'FTP', 'configuration' => array('host' => 'URL', 'user' => 'Username', 'password' => '*Password', 'root' => '&Root', 'secure' => '!Secure ftps://')), 'OC_Filestorage_Google' => array('backend' => 'Google Drive', 'configuration' => array('token' => '#token', 'token_secret' => '#token secret'), 'custom' => 'google'), 'OC_Filestorage_SWIFT' => array('backend' => 'OpenStack Swift', 'configuration' => array('host' => 'URL', 'user' => 'Username', 'token' => '*Token', 'root' => '&Root', 'secure' => '!Secure ftps://')), - 'OC_Filestorage_SMB' => array('backend' => 'SMB', 'configuration' => array('host' => 'URL', 'user' => 'Username', 'password' => '*Password', 'root' => '&Root')), + 'OC_Filestorage_SMB' => array('backend' => 'SMB', 'configuration' => array('host' => 'URL', 'user' => 'Username', 'password' => '*Password', 'share' => 'Share', 'root' => '&Root')), 'OC_Filestorage_DAV' => array('backend' => 'WebDAV', 'configuration' => array('host' => 'URL', 'user' => 'Username', 'password' => '*Password', 'root' => '&Root', 'secure' => '!Secure https://')) ); } @@ -237,6 +237,46 @@ class OC_Mount_Config { $content .= ");\n?>"; @file_put_contents($file, $content); } + + /**
+ * Returns all user uploaded ssl root certificates
+ * @return array
+ */
+ public static function getCertificates() { + $view = \OCP\Files::getStorage('files_external'); + $path=\OCP\Config::getSystemValue('datadirectory').$view->getAbsolutePath("").'uploads/'; + if (!is_dir($path)) mkdir($path); + $result = array(); + $handle = opendir($path); + while (false !== ($file = readdir($handle))) { + if($file != '.' && $file != '..') $result[] = $file; + } + return $result; + } + + /** + * creates certificate bundle + */ + public static function createCertificateBundle() { + $view = \OCP\Files::getStorage("files_external");
+ $path = \OCP\Config::getSystemValue('datadirectory').$view->getAbsolutePath("");
+
+ $certs = OC_Mount_Config::getCertificates();
+ $fh_certs = fopen($path."/rootcerts.crt", 'w');
+ foreach ($certs as $cert) {
+ $file=$path.'/uploads/'.$cert;
+ $fh = fopen($file, "r");
+ $data = fread($fh, filesize($file));
+ fclose($fh); + if (strpos($data, 'BEGIN CERTIFICATE')) {
+ fwrite($fh_certs, $data); + }
+ }
+
+ fclose($fh_certs); + + return true; + } } diff --git a/apps/files_external/lib/dropbox.php b/apps/files_external/lib/dropbox.php index 5e94277c6d4..35663d431f8 100755 --- a/apps/files_external/lib/dropbox.php +++ b/apps/files_external/lib/dropbox.php @@ -33,7 +33,6 @@ class OC_Filestorage_Dropbox extends OC_Filestorage_Common { $oauth = new Dropbox_OAuth_Curl($params['app_key'], $params['app_secret']); $oauth->setToken($params['token'], $params['token_secret']); $this->dropbox = new Dropbox_API($oauth, 'dropbox'); - } private function getMetaData($path, $list = false) { @@ -41,7 +40,11 @@ class OC_Filestorage_Dropbox extends OC_Filestorage_Common { return $this->metaData[$path]; } else { if ($list) { - $response = $this->dropbox->getMetaData($path); + try { + $response = $this->dropbox->getMetaData($path); + } catch (Exception $exception) { + return false; + } if ($response && isset($response['contents'])) { $contents = $response['contents']; // Cache folder's contents @@ -67,11 +70,16 @@ class OC_Filestorage_Dropbox extends OC_Filestorage_Common { } public function mkdir($path) { - return $this->dropbox->createFolder($path); + try { + $this->dropbox->createFolder($path); + return true; + } catch (Exception $exception) { + return false; + } } public function rmdir($path) { - return $this->dropbox->delete($path); + return $this->unlink($path); } public function opendir($path) { @@ -80,8 +88,8 @@ class OC_Filestorage_Dropbox extends OC_Filestorage_Common { foreach ($contents as $file) { $files[] = basename($file['path']); } - OC_FakeDirStream::$dirs['dropbox'] = $files; - return opendir('fakedir://dropbox'); + OC_FakeDirStream::$dirs['dropbox'.$path] = $files; + return opendir('fakedir://dropbox'.$path); } return false; } @@ -90,7 +98,7 @@ class OC_Filestorage_Dropbox extends OC_Filestorage_Common { if ($metaData = $this->getMetaData($path)) { $stat['size'] = $metaData['bytes']; $stat['atime'] = time(); - $stat['mtime'] = strtotime($metaData['modified']); + $stat['mtime'] = (isset($metaData['modified'])) ? strtotime($metaData['modified']) : time(); $stat['ctime'] = $stat['mtime']; return $stat; } @@ -111,11 +119,11 @@ class OC_Filestorage_Dropbox extends OC_Filestorage_Common { } public function is_readable($path) { - return true; + return $this->file_exists($path); } public function is_writable($path) { - return true; + return $this->file_exists($path); } public function file_exists($path) { @@ -129,7 +137,30 @@ class OC_Filestorage_Dropbox extends OC_Filestorage_Common { } public function unlink($path) { - return $this->dropbox->delete($path); + try { + $this->dropbox->delete($path); + return true; + } catch (Exception $exception) { + return false; + } + } + + public function rename($path1, $path2) { + try { + $this->dropbox->move($path1, $path2); + return true; + } catch (Exception $exception) { + return false; + } + } + + public function copy($path1, $path2) { + try { + $this->dropbox->copy($path1, $path2); + return true; + } catch (Exception $exception) { + return false; + } } public function fopen($path, $mode) { @@ -137,8 +168,13 @@ class OC_Filestorage_Dropbox extends OC_Filestorage_Common { case 'r': case 'rb': $tmpFile = OC_Helper::tmpFile(); - file_put_contents($tmpFile, $this->dropbox->getFile($path)); - return fopen($tmpFile, 'r'); + try { + $data = $this->dropbox->getFile($path); + file_put_contents($tmpFile, $data); + return fopen($tmpFile, 'r'); + } catch (Exception $exception) { + return false; + } case 'w': case 'wb': case 'a': @@ -171,9 +207,11 @@ class OC_Filestorage_Dropbox extends OC_Filestorage_Common { public function writeBack($tmpFile) { if (isset(self::$tempFiles[$tmpFile])) { $handle = fopen($tmpFile, 'r'); - $response = $this->dropbox->putFile(self::$tempFiles[$tmpFile], $handle); - if ($response) { + try { + $response = $this->dropbox->putFile(self::$tempFiles[$tmpFile], $handle); unlink($tmpFile); + } catch (Exception $exception) { + } } } @@ -188,10 +226,12 @@ class OC_Filestorage_Dropbox extends OC_Filestorage_Common { } public function free_space($path) { - if ($info = $this->dropbox->getAccountInfo()) { + try { + $info = $this->dropbox->getAccountInfo(); return $info['quota_info']['quota'] - $info['quota_info']['normal']; + } catch (Exception $exception) { + return false; } - return false; } public function touch($path, $mtime = null) { diff --git a/apps/files_external/lib/google.php b/apps/files_external/lib/google.php index fe60a06629a..41b560ae84e 100644 --- a/apps/files_external/lib/google.php +++ b/apps/files_external/lib/google.php @@ -237,8 +237,8 @@ class OC_Filestorage_Google extends OC_Filestorage_Common { $this->entries[$name] = $entry; } } - OC_FakeDirStream::$dirs['google'] = $files; - return opendir('fakedir://google'); + OC_FakeDirStream::$dirs['google'.$path] = $files; + return opendir('fakedir://google'.$path); } public function stat($path) { diff --git a/apps/files_external/lib/webdav.php b/apps/files_external/lib/webdav.php index d136f04f3eb..3d13518f57b 100644 --- a/apps/files_external/lib/webdav.php +++ b/apps/files_external/lib/webdav.php @@ -20,10 +20,14 @@ class OC_FileStorage_DAV extends OC_Filestorage_Common{ private static $tempFiles=array(); public function __construct($params){ - $this->host=$params['host']; + $host = $params['host']; + //remove leading http[s], will be generated in createBaseUri() + if (substr($host,0,8) == "https://") $host = substr($host, 8); + else if (substr($host,0,7) == "http://") $host = substr($host, 7); + $this->host=$host; $this->user=$params['user']; $this->password=$params['password']; - $this->secure=isset($params['secure'])?(bool)$params['secure']:false; + $this->secure=(isset($params['secure']) && $params['secure'] == 'true')?true:false; $this->root=isset($params['root'])?$params['root']:'/'; if(!$this->root || $this->root[0]!='/'){ $this->root='/'.$this->root; @@ -37,8 +41,15 @@ class OC_FileStorage_DAV extends OC_Filestorage_Common{ 'userName' => $this->user, 'password' => $this->password, ); - $this->client = new Sabre_DAV_Client($settings); + $this->client = new OC_Connector_Sabre_Client($settings); + + if($caview = \OCP\Files::getStorage('files_external')) { + $certPath=\OCP\Config::getSystemValue('datadirectory').$caview->getAbsolutePath("").'rootcerts.crt'; + if (file_exists($certPath)) { + $this->client->addTrustedCertificates($certPath); + } + } //create the root folder if necesary $this->mkdir(''); } @@ -46,7 +57,7 @@ class OC_FileStorage_DAV extends OC_Filestorage_Common{ private function createBaseUri(){ $baseUri='http'; if($this->secure){ - $baseUri.'s'; + $baseUri.='s'; } $baseUri.='://'.$this->host.$this->root; return $baseUri; @@ -69,13 +80,15 @@ class OC_FileStorage_DAV extends OC_Filestorage_Common{ $stripLength=strlen($this->root)+strlen($path); $id=md5('webdav'.$this->root.$path); OC_FakeDirStream::$dirs[$id]=array(); + $skip = true; foreach($response as $file=>$data){ - //strip root and path - $file=trim(substr($file,$stripLength)); - $file=trim($file,'/'); - if($file){ - OC_FakeDirStream::$dirs[$id][]=$file; + // Skip the first file, because it is the current directory + if ($skip) { + $skip = false; + continue; } + $file = urldecode(basename($file)); + OC_FakeDirStream::$dirs[$id][]=$file; } return opendir('fakedir://'.$id); }catch(Exception $e){ @@ -90,6 +103,8 @@ class OC_FileStorage_DAV extends OC_Filestorage_Common{ $responseType=$response["{DAV:}resourcetype"]->resourceType; return (count($responseType)>0 and $responseType[0]=="{DAV:}collection")?'dir':'file'; }catch(Exception $e){ + error_log($e->getMessage()); + \OCP\Util::writeLog("webdav client", \OCP\Util::sanitizeHTML($e->getMessage()), \OCP\Util::ERROR); return false; } } @@ -240,15 +255,11 @@ class OC_FileStorage_DAV extends OC_Filestorage_Common{ $path=$this->cleanPath($path); try{ $response=$this->client->propfind($path, array('{DAV:}getlastmodified','{DAV:}getcontentlength')); - if(isset($response['{DAV:}getlastmodified']) and isset($response['{DAV:}getcontentlength'])){ - return array( - 'mtime'=>strtotime($response['{DAV:}getlastmodified']), - 'size'=>(int)$response['{DAV:}getcontentlength'], - 'ctime'=>-1, - ); - }else{ - return array(); - } + return array( + 'mtime'=>strtotime($response['{DAV:}getlastmodified']), + 'size'=>(int)isset($response['{DAV:}getcontentlength']) ? $response['{DAV:}getcontentlength'] : 0, + 'ctime'=>-1, + ); }catch(Exception $e){ return array(); } diff --git a/apps/files_external/personal.php b/apps/files_external/personal.php index 32e08742442..dec501741b6 100755 --- a/apps/files_external/personal.php +++ b/apps/files_external/personal.php @@ -26,8 +26,9 @@ $backends = OC_Mount_Config::getBackends(); // Remove local storage unset($backends['OC_Filestorage_Local']); $tmpl = new OCP\Template('files_external', 'settings'); -$tmpl->assign('isAdminPage', false); +$tmpl->assign('isAdminPage', false, false); $tmpl->assign('mounts', OC_Mount_Config::getPersonalMountPoints()); +$tmpl->assign('certs', OC_Mount_Config::getCertificates()); $tmpl->assign('backends', $backends); return $tmpl->fetchPage(); diff --git a/apps/files_external/settings.php b/apps/files_external/settings.php index 983855ecdcc..acc9036b299 100644 --- a/apps/files_external/settings.php +++ b/apps/files_external/settings.php @@ -23,7 +23,7 @@ OCP\Util::addScript('files_external', 'settings'); OCP\Util::addStyle('files_external', 'settings'); $tmpl = new OCP\Template('files_external', 'settings'); -$tmpl->assign('isAdminPage', true); +$tmpl->assign('isAdminPage', true, false); $tmpl->assign('mounts', OC_Mount_Config::getSystemMountPoints()); $tmpl->assign('backends', OC_Mount_Config::getBackends()); $tmpl->assign('groups', OC_Group::getGroups()); diff --git a/apps/files_external/templates/settings.php b/apps/files_external/templates/settings.php index 6c37df8001e..e8bc94790dc 100644 --- a/apps/files_external/templates/settings.php +++ b/apps/files_external/templates/settings.php @@ -1,7 +1,7 @@ -<form id="files_external"> +<form id="files_external" method="post" enctype="multipart/form-data" action="<?php echo OCP\Util::linkTo('files_external', 'ajax/addRootCertificate.php'); ?>"> <fieldset class="personalblock"> <legend><strong><?php echo $l->t('External Storage'); ?></strong></legend> - <table id="externalStorage" data-admin="<?php echo json_encode($_['isAdminPage']); ?>"> + <table id="externalStorage" data-admin='<?php echo json_encode($_['isAdminPage']); ?>'> <thead> <tr> <th><?php echo $l->t('Mount point'); ?></th> @@ -39,7 +39,7 @@ <?php elseif(strpos($placeholder, '!') !== false): ?> <label><input type="checkbox" data-parameter="<?php echo $parameter; ?>" <?php if ($value == 'true') echo ' checked="checked"'; ?> /><?php echo substr($placeholder, 1); ?></label> <?php elseif (strpos($placeholder, '&') !== false): ?> - <input type="text" class="optional" data-parameter="<?php echo $parameter; ?>" value="<?php echo $value; ?>" placeholder="<?php echo substr($placeholder, 1); ?>" /> + <input type="text" class="optional" data-parameter="<?php echo $parameter; ?>" value="<?php echo $value; ?>" placeholder="<?php echo substr($placeholder, 5); ?>" /> <?php elseif (strpos($placeholder, '#') !== false): ?> <input type="hidden" data-parameter="<?php echo $parameter; ?>" value="<?php echo $value; ?>" /> <?php else: ?> @@ -74,11 +74,34 @@ </select> </td> <?php endif; ?> - <td <?php if ($mountPoint != '') echo 'class="remove"'; ?>><img alt="<?php echo $l->t('Delete'); ?>" title="<?php echo $l->t('Delete'); ?>" class="svg action" src="<?php echo image_path('core', 'actions/delete.svg'); ?>" /></td> + <td <?php echo ($mountPoint != '') ? 'class="remove"' : 'style="visibility:hidden;"'; ?>><img alt="<?php echo $l->t('Delete'); ?>" title="<?php echo $l->t('Delete'); ?>" class="svg action" src="<?php echo image_path('core', 'actions/delete.svg'); ?>" /></td> </tr> <?php endforeach; ?> </tbody> </table> + <br /> + + <?php if (!$_['isAdminPage']): ?> + <table id="sslCertificate" data-admin='<?php echo json_encode($_['isAdminPage']); ?>'> + <thead> + <tr> + <th><?php echo $l->t('SSL root certificates'); ?></th> + <th> </th> + </tr> + </thead> + <tbody width="100%"> + <?php foreach ($_['certs'] as $rootCert): ?> + <tr id="<?php echo $rootCert ?>"> + <td class="rootCert"><?php echo $rootCert ?></td> + <td <?php echo ($rootCert != '') ? 'class="remove"' : 'style="visibility:hidden;"'; ?>><img alt="<?php echo $l->t('Delete'); ?>" title="<?php echo $l->t('Delete'); ?>" class="svg action" src="<?php echo image_path('core', 'actions/delete.svg'); ?>" /></td> + </tr> + <?php endforeach; ?> + </tbody> + </table> + <input type="file" id="rootcert_import" name="rootcert_import" style="width:230px;"> + <input type="submit" name="cert_import" value="<?php echo $l->t('Import Root Certificate'); ?>" /> + <?php endif; ?> + <?php if ($_['isAdminPage']): ?> <br /> <input type="checkbox" name="allowUserMounting" id="allowUserMounting" value="1" <?php if ($_['allowUserMounting'] == 'yes') echo ' checked="checked"'; ?> /> @@ -86,4 +109,4 @@ <em><?php echo $l->t('Allow users to mount their own external storage'); ?></em> <?php endif; ?> </fieldset> -</form>
\ No newline at end of file +</form> diff --git a/apps/files_external/tests/amazons3.php b/apps/files_external/tests/amazons3.php index d0084c94afd..b9b4cf65bd6 100644 --- a/apps/files_external/tests/amazons3.php +++ b/apps/files_external/tests/amazons3.php @@ -45,6 +45,3 @@ if (!is_array($config) or !isset($config['amazons3']) or !$config['amazons3']['r } } } - -?> - diff --git a/apps/files_imageviewer/appinfo/app.php b/apps/files_imageviewer/appinfo/app.php index 6c8d8c30cad..6184585cff3 100644 --- a/apps/files_imageviewer/appinfo/app.php +++ b/apps/files_imageviewer/appinfo/app.php @@ -4,5 +4,3 @@ OCP\Util::addscript( 'files_imageviewer', 'lightbox' ); OCP\Util::addscript('files_imageviewer', 'jquery.mousewheel-3.0.4.pack'); OCP\Util::addscript('files_imageviewer', 'jquery.fancybox-1.3.4.pack'); OCP\Util::addStyle( 'files_imageviewer', 'jquery.fancybox-1.3.4' ); - -?> diff --git a/apps/files_pdfviewer/appinfo/app.php b/apps/files_pdfviewer/appinfo/app.php index c8ca2dc8d94..e4771ee517f 100644 --- a/apps/files_pdfviewer/appinfo/app.php +++ b/apps/files_pdfviewer/appinfo/app.php @@ -6,4 +6,3 @@ OCP\Util::addscript( 'files_pdfviewer', 'pdfjs/compatibility'); OCP\Util::addscript( 'files_pdfviewer', 'viewer'); OCP\Util::addscript( 'files_pdfviewer', 'pdfjs/build/pdf'); OCP\Util::addscript( 'files_pdfviewer', 'pdfjs/viewer'); -?> diff --git a/apps/files_pdfviewer/js/pdfjs/viewer.js b/apps/files_pdfviewer/js/pdfjs/viewer.js index f49257d7929..90dd1eef020 100644 --- a/apps/files_pdfviewer/js/pdfjs/viewer.js +++ b/apps/files_pdfviewer/js/pdfjs/viewer.js @@ -1432,7 +1432,7 @@ var DocumentOutlineView = function documentOutlineView(outline) { queue.push({parent: itemsDiv, items: item.items}); } - levelData.parent.appendChild(div); +// levelData.parent.appendChild(div); } } }; @@ -1751,10 +1751,9 @@ function updateThumbViewArea() { } window.addEventListener('resize', function webViewerResize(evt) { - if (PDFView.initialized && + if (PDFView.initialized && PDFView.active && (document.getElementById('pageWidthOption').selected || - document.getElementById('pageFitOption').selected || - document.getElementById('pageAutoOption').selected)) + document.getElementById('pageFitOption').selected )) PDFView.parseScale(document.getElementById('scaleSelect').value); updateViewarea(); }); @@ -1788,8 +1787,8 @@ window.addEventListener('change', function webViewerChange(evt) { document.title = file.name; // URL does not reflect proper document location - hiding some icons. - document.getElementById('viewBookmark').setAttribute('hidden', 'true'); - document.getElementById('download').setAttribute('hidden', 'true'); +// document.getElementById('viewBookmark').setAttribute('hidden', 'true'); +// document.getElementById('download').setAttribute('hidden', 'true'); }, true); function selectScaleOption(value) { diff --git a/apps/files_sharing/ajax/email.php b/apps/files_sharing/ajax/email.php index 523c3d2078b..3026eb74675 100644 --- a/apps/files_sharing/ajax/email.php +++ b/apps/files_sharing/ajax/email.php @@ -1,6 +1,8 @@ <?php OCP\JSON::checkLoggedIn(); OCP\JSON::checkAppEnabled('files_sharing'); +OCP\JSON::callCheck(); + $user = OCP\USER::getUser(); // TODO translations $type = (strpos($_POST['file'], '.') === false) ? 'folder' : 'file'; @@ -8,6 +10,4 @@ $subject = $user.' shared a '.$type.' with you'; $link = $_POST['link']; $text = $user.' shared the '.$type.' '.$_POST['file'].' with you. It is available for download here: '.$link; $fromaddress = OCP\Config::getUserValue($user, 'settings', 'email', 'sharing-noreply@'.OCP\Util::getServerHost()); -OC_Mail::send($_POST['toaddress'], $_POST['toaddress'], $subject, $text, $fromaddress, $user); - -?> +OCP\Util::sendMail($_POST['toaddress'], $_POST['toaddress'], $subject, $text, $fromaddress, $user); diff --git a/apps/files_sharing/ajax/getitem.php b/apps/files_sharing/ajax/getitem.php index 94f0890d706..ff6c29b6a0a 100644 --- a/apps/files_sharing/ajax/getitem.php +++ b/apps/files_sharing/ajax/getitem.php @@ -64,5 +64,3 @@ while ($path != $userDirectory) { } OCP\JSON::success(array('data' => $item)); - -?> diff --git a/apps/files_sharing/ajax/getstatuses.php b/apps/files_sharing/ajax/getstatuses.php index 488cab13bc9..1be4d9a0d9c 100644 --- a/apps/files_sharing/ajax/getstatuses.php +++ b/apps/files_sharing/ajax/getstatuses.php @@ -20,5 +20,3 @@ if ($rows = OC_Share::getMySharedItems()) { } OCP\JSON::success(array('data' => $items)); - -?> diff --git a/apps/files_sharing/ajax/setpermissions.php b/apps/files_sharing/ajax/setpermissions.php index 4d19cd40f2d..0a2cf78f765 100644 --- a/apps/files_sharing/ajax/setpermissions.php +++ b/apps/files_sharing/ajax/setpermissions.php @@ -2,6 +2,7 @@ OCP\JSON::checkAppEnabled('files_sharing'); OCP\JSON::checkLoggedIn(); +OCP\JSON::callCheck(); $source = '/'.OCP\USER::getUser().'/files'.$_POST['source']; $uid_shared_with = $_POST['uid_shared_with']; @@ -9,5 +10,3 @@ $permissions = $_POST['permissions']; OC_Share::setPermissions($source, $uid_shared_with, $permissions); OCP\JSON::success(); - -?> diff --git a/apps/files_sharing/ajax/share.php b/apps/files_sharing/ajax/share.php index 1ee8c3f791a..3f224d1b67b 100644 --- a/apps/files_sharing/ajax/share.php +++ b/apps/files_sharing/ajax/share.php @@ -2,6 +2,7 @@ OCP\JSON::checkAppEnabled('files_sharing'); OCP\JSON::checkLoggedIn(); +OCP\JSON::callCheck(); $userDirectory = '/'.OCP\USER::getUser().'/files'; $sources = explode(';', $_POST['sources']); @@ -34,5 +35,3 @@ foreach ($sources as $source) { } } } - -?> diff --git a/apps/files_sharing/ajax/toggleresharing.php b/apps/files_sharing/ajax/toggleresharing.php index 673f00c5d18..7da4fdfeea8 100644 --- a/apps/files_sharing/ajax/toggleresharing.php +++ b/apps/files_sharing/ajax/toggleresharing.php @@ -7,5 +7,3 @@ if ($_POST['resharing'] == true) { } else { OCP\Config::setAppValue('files_sharing', 'resharing', 'no'); } - -?> diff --git a/apps/files_sharing/ajax/unshare.php b/apps/files_sharing/ajax/unshare.php index d50e7963a05..02a59c4016b 100644 --- a/apps/files_sharing/ajax/unshare.php +++ b/apps/files_sharing/ajax/unshare.php @@ -2,11 +2,10 @@ OCP\JSON::checkAppEnabled('files_sharing'); OCP\JSON::checkLoggedIn(); +OCP\JSON::callCheck(); $source = '/'.OCP\USER::getUser().'/files'.$_POST['source']; $uid_shared_with = $_POST['uid_shared_with']; OC_Share::unshare($source, $uid_shared_with); OCP\JSON::success(); - -?> diff --git a/apps/files_sharing/ajax/userautocomplete.php b/apps/files_sharing/ajax/userautocomplete.php index 0e1bf6d588e..388a4844b95 100644 --- a/apps/files_sharing/ajax/userautocomplete.php +++ b/apps/files_sharing/ajax/userautocomplete.php @@ -28,5 +28,3 @@ $users[] = "</optgroup>"; $groups[] = "</optgroup>"; $users = array_merge($users, $groups); OCP\JSON::encodedPrint($users); - -?> diff --git a/apps/files_sharing/get.php b/apps/files_sharing/get.php index 40a90a1530c..70a5162d382 100644 --- a/apps/files_sharing/get.php +++ b/apps/files_sharing/get.php @@ -86,4 +86,3 @@ if (isset($_GET['token']) && $source = OC_Share::getSource($_GET['token'])) { $tmpl->printPage(); die(); } -?> diff --git a/apps/files_sharing/lib_share.php b/apps/files_sharing/lib_share.php index 6e092269250..0237acfc1ac 100644 --- a/apps/files_sharing/lib_share.php +++ b/apps/files_sharing/lib_share.php @@ -513,5 +513,3 @@ class OC_Share { } } - -?> diff --git a/apps/files_sharing/list.php b/apps/files_sharing/list.php index 2fd24840d36..54704c942fd 100644 --- a/apps/files_sharing/list.php +++ b/apps/files_sharing/list.php @@ -33,5 +33,3 @@ OCP\Util::addscript("files_sharing", "list"); $tmpl = new OCP\Template("files_sharing", "list", "user"); $tmpl->assign("shared_items", OC_Share::getMySharedItems()); $tmpl->printPage(); - -?> diff --git a/apps/files_texteditor/ajax/loadfile.php b/apps/files_texteditor/ajax/loadfile.php index c263306e719..5a5affa46be 100644 --- a/apps/files_texteditor/ajax/loadfile.php +++ b/apps/files_texteditor/ajax/loadfile.php @@ -43,6 +43,7 @@ if(!empty($filename)) { $mtime = OC_Filesystem::filemtime($path); $filecontents = OC_Filesystem::file_get_contents($path); + $filecontents = iconv(mb_detect_encoding($filecontents), "UTF-8", $filecontents); OCP\JSON::success(array('data' => array('filecontents' => $filecontents, 'write' => 'false', 'mtime' => $mtime))); } } else { diff --git a/apps/files_texteditor/ajax/savefile.php b/apps/files_texteditor/ajax/savefile.php index f789112d7d7..f3ac323e32f 100644 --- a/apps/files_texteditor/ajax/savefile.php +++ b/apps/files_texteditor/ajax/savefile.php @@ -26,6 +26,7 @@ // Check if we are a user OCP\JSON::checkLoggedIn(); +OCP\JSON::callCheck(); // Get paramteres $filecontents = isset($_POST['filecontents']) ? $_POST['filecontents'] : false; @@ -48,6 +49,7 @@ if($path != '' && $mtime != '' && $filecontents) // Save file if(OC_Filesystem::is_writable($path)) { + $filecontents = iconv(mb_detect_encoding($filecontents), "UTF-8", $filecontents); OC_Filesystem::file_put_contents($path, $filecontents); // Clear statcache clearstatcache(); diff --git a/apps/files_texteditor/appinfo/app.php b/apps/files_texteditor/appinfo/app.php index c745170018e..1f9773bca3a 100644 --- a/apps/files_texteditor/appinfo/app.php +++ b/apps/files_texteditor/appinfo/app.php @@ -4,4 +4,3 @@ OCP\Util::addStyle( 'files_texteditor', 'DroidSansMono/stylesheet' ); OCP\Util::addStyle( 'files_texteditor', 'style' ); OCP\Util::addscript( 'files_texteditor', 'editor'); OCP\Util::addscript( 'files_texteditor', 'aceeditor/ace'); -?> diff --git a/apps/files_versions/ajax/expireAll.php b/apps/files_versions/ajax/expireAll.php index f9cd74aed02..4f165be0ae9 100644 --- a/apps/files_versions/ajax/expireAll.php +++ b/apps/files_versions/ajax/expireAll.php @@ -28,7 +28,9 @@ OCP\JSON::checkLoggedIn(); OCP\App::checkAppEnabled('files_versions'); -if( OCA_Versions\Storage::expireAll() ){ +$versions = new OCA_Versions\Storage(); + +if( $versions->expireAll() ){ OCP\JSON::success(); die(); diff --git a/apps/files_versions/ajax/getVersions.php b/apps/files_versions/ajax/getVersions.php index bee60543339..1a0e21732cc 100644 --- a/apps/files_versions/ajax/getVersions.php +++ b/apps/files_versions/ajax/getVersions.php @@ -1,11 +1,8 @@ <?php OCP\JSON::checkAppEnabled('files_versions'); -require_once('apps/files_versions/versions.php'); - $userDirectory = "/".OCP\USER::getUser()."/files"; $source = $_GET['source']; -$source = strip_tags( $source ); if( OCA_Versions\Storage::isversioned( $source ) ) { @@ -14,9 +11,7 @@ if( OCA_Versions\Storage::isversioned( $source ) ) { $versionsFormatted = array(); foreach ( $versions AS $version ) { - - $versionsFormatted[] = OCP\Util::formatDate( $version ); - + $versionsFormatted[] = OCP\Util::formatDate( $version['version'] ); } $versionsSorted = array_reverse( $versions ); diff --git a/apps/files_versions/ajax/rollbackVersion.php b/apps/files_versions/ajax/rollbackVersion.php index 127592f3b58..8d1092f8b8e 100644 --- a/apps/files_versions/ajax/rollbackVersion.php +++ b/apps/files_versions/ajax/rollbackVersion.php @@ -2,8 +2,6 @@ OCP\JSON::checkAppEnabled('files_versions'); -require_once('apps/files_versions/versions.php'); - $userDirectory = "/".OCP\USER::getUser()."/files"; $file = $_GET['file']; diff --git a/apps/files_versions/ajax/togglesettings.php b/apps/files_versions/ajax/togglesettings.php index d513d12dd6c..86f614c5c89 100644 --- a/apps/files_versions/ajax/togglesettings.php +++ b/apps/files_versions/ajax/togglesettings.php @@ -7,5 +7,3 @@ if (OCP\Config::getSystemValue('versions', 'true')=='true') { } else { OCP\Config::setSystemValue('versions', 'true'); } - -?> diff --git a/apps/files_versions/appinfo/app.php b/apps/files_versions/appinfo/app.php index bd06dc0ced3..9ac7f6d5cde 100644 --- a/apps/files_versions/appinfo/app.php +++ b/apps/files_versions/appinfo/app.php @@ -1,6 +1,8 @@ <?php -require_once('files_versions/versions.php'); +//require_once('files_versions/versions.php'); +OC::$CLASSPATH['OCA_Versions\Storage'] = 'apps/files_versions/lib/versions.php'; +OC::$CLASSPATH['OCA_Versions\Hooks'] = 'apps/files_versions/lib/hooks.php'; OCP\App::registerAdmin('files_versions', 'settings'); OCP\App::registerPersonal('files_versions','settings-personal'); @@ -8,4 +10,7 @@ OCP\App::registerPersonal('files_versions','settings-personal'); OCP\Util::addscript('files_versions', 'versions'); // Listen to write signals -OCP\Util::connectHook('OC_Filesystem', 'post_write', "OCA_Versions\Storage", "write_hook"); +OCP\Util::connectHook('OC_Filesystem', 'post_write', "OCA_Versions\Hooks", "write_hook"); +// Listen to delete and rename signals +OCP\Util::connectHook('OC_Filesystem', 'delete', "OCA_Versions\Hooks", "remove_hook"); +OCP\Util::connectHook('OC_Filesystem', 'rename', "OCA_Versions\Hooks", "rename_hook");
\ No newline at end of file diff --git a/apps/files_versions/appinfo/update.php b/apps/files_versions/appinfo/update.php new file mode 100644 index 00000000000..9569ca10485 --- /dev/null +++ b/apps/files_versions/appinfo/update.php @@ -0,0 +1,16 @@ +<?php + +$installedVersion=OCP\Config::getAppValue('files_versions', 'installed_version'); +// move versions to new directory +if (version_compare($installedVersion, '1.0.2', '<')) { + $users = \OCP\User::getUsers(); + $datadir = \OCP\Config::getSystemValue('datadirectory').'/'; + foreach ($users as $user) { + $oldPath = $datadir.$user.'/versions';
+ $newPath = $datadir.$user.'/files_versions'; + if(is_dir($oldPath)) { + rename($oldPath, $newPath); + } + } + +} diff --git a/apps/files_versions/appinfo/version b/apps/files_versions/appinfo/version index 7f207341d5d..e6d5cb833c6 100644 --- a/apps/files_versions/appinfo/version +++ b/apps/files_versions/appinfo/version @@ -1 +1 @@ -1.0.1
\ No newline at end of file +1.0.2
\ No newline at end of file diff --git a/apps/files_versions/history.php b/apps/files_versions/history.php index cb4726e8d0e..a34c92ee422 100644 --- a/apps/files_versions/history.php +++ b/apps/files_versions/history.php @@ -30,21 +30,22 @@ if ( isset( $_GET['path'] ) ) { $path = $_GET['path']; $path = strip_tags( $path ); $tmpl->assign( 'path', $path ); + $versions = new OCA_Versions\Storage(); // roll back to old version if button clicked if( isset( $_GET['revert'] ) ) { - if( \OCA_Versions\Storage::rollback( $path, $_GET['revert'] ) ) { + if( $versions->rollback( $path, $_GET['revert'] ) ) { $tmpl->assign( 'outcome_stat', 'success' ); - $tmpl->assign( 'outcome_msg', "File {$_GET['path']} was reverted to version ".OCP\Util::formatDate( $_GET['revert'] ) ); + $tmpl->assign( 'outcome_msg', "File {$_GET['path']} was reverted to version ".OCP\Util::formatDate( doubleval($_GET['revert']) ) ); } else { $tmpl->assign( 'outcome_stat', 'failure' ); - $tmpl->assign( 'outcome_msg', "File {$_GET['path']} could not be reverted to version ".OCP\Util::formatDate( $_GET['revert'] ) ); + $tmpl->assign( 'outcome_msg', "File {$_GET['path']} could not be reverted to version ".OCP\Util::formatDate( doubleval($_GET['revert']) ) ); } @@ -70,5 +71,3 @@ if ( isset( $_GET['path'] ) ) { } $tmpl->printPage( ); - -?> diff --git a/apps/files_versions/js/versions.js b/apps/files_versions/js/versions.js index 82d569fa0f6..a090fde446e 100644 --- a/apps/files_versions/js/versions.js +++ b/apps/files_versions/js/versions.js @@ -104,9 +104,9 @@ function createVersionsDropdown(filename, files) { } function addVersion(revision ) { - name=formatDate(revision*1000); + name=formatDate(revision.version*1000); var version=$('<option/>'); - version.attr('value',revision); + version.attr('value',revision.version); version.text(name); // } else { diff --git a/apps/files_versions/lib/hooks.php b/apps/files_versions/lib/hooks.php new file mode 100644 index 00000000000..bfc8fd3a378 --- /dev/null +++ b/apps/files_versions/lib/hooks.php @@ -0,0 +1,75 @@ +<?php +/** + * Copyright (c) 2012 Sam Tuke <samtuke@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +/** + * This class contains all hooks. + */ + +namespace OCA_Versions; + +class Hooks { + + /** + * listen to write event. + */ + public static function write_hook( $params ) { + + if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') { + + $versions = new Storage( new \OC_FilesystemView('') ); + + $path = $params[\OC_Filesystem::signal_param_path]; + + if($path<>'') $versions->store( $path ); + + } + } + + + /**
+ * @brief Erase versions of deleted file
+ * @param array
+ *
+ * This function is connected to the delete signal of OC_Filesystem
+ * cleanup the versions directory if the actual file gets deleted
+ */
+ public static function remove_hook($params) { + $versions_fileview = \OCP\Files::getStorage('files_versions');
+ $rel_path = $params['path'];
+ $abs_path = \OCP\Config::getSystemValue('datadirectory').$versions_fileview->getAbsolutePath('').$rel_path.'.v';
+ if(Storage::isversioned($rel_path)) {
+ $versions = Storage::getVersions($rel_path);
+ foreach ($versions as $v){
+ unlink($abs_path . $v['version']);
+ }
+ }
+ }
+
+ /**
+ * @brief rename/move versions of renamed/moved files
+ * @param array with oldpath and newpath
+ *
+ * This function is connected to the rename signal of OC_Filesystem and adjust the name and location
+ * of the stored versions along the actual file
+ */
+ public static function rename_hook($params) { + $versions_fileview = \OCP\Files::getStorage('files_versions');
+ $rel_oldpath = $params['oldpath'];
+ $abs_oldpath = \OCP\Config::getSystemValue('datadirectory').$versions_fileview->getAbsolutePath('').$rel_oldpath.'.v';
+ $abs_newpath = \OCP\Config::getSystemValue('datadirectory').$versions_fileview->getAbsolutePath('').$params['newpath'].'.v';
+ if(Storage::isversioned($rel_oldpath)) { + $info=pathinfo($abs_newpath);
+ if(!file_exists($info['dirname'])) mkdir($info['dirname'],0700,true);
+ $versions = Storage::getVersions($rel_oldpath);
+ foreach ($versions as $v){
+ rename($abs_oldpath.$v['version'], $abs_newpath.$v['version']);
+ }
+ }
+ } + +} diff --git a/apps/files_versions/versions.php b/apps/files_versions/lib/versions.php index 9c0829ff1de..0ce884c3ea0 100644 --- a/apps/files_versions/versions.php +++ b/apps/files_versions/lib/versions.php @@ -1,313 +1,306 @@ -<?php -/** - * Copyright (c) 2012 Frank Karlitschek <frank@owncloud.org> - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. - */ - -/** - * Versions - * - * A class to handle the versioning of files. - */ - -namespace OCA_Versions; - -class Storage { - - - // config.php configuration: - // - files_versions - // - files_versionsfolder - // - files_versionsblacklist - // - files_versionsmaxfilesize - // - files_versionsinterval - // - files_versionmaxversions - // - // todo: - // - port to oc_filesystem to enable network transparency - // - implement expire all function. And find a place to call it ;-) - // - add transparent compression. first test if it´s worth it. - - const DEFAULTENABLED=true; - const DEFAULTFOLDER='versions'; - const DEFAULTBLACKLIST='avi mp3 mpg mp4 ctmp'; - const DEFAULTMAXFILESIZE=1048576; // 10MB - const DEFAULTMININTERVAL=1; // 2 min - const DEFAULTMAXVERSIONS=50; - - /** - * init the versioning and create the versions folder. - */ - public static function init() { - if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') { - // create versions folder - $foldername=\OCP\Config::getSystemValue('datadirectory').'/'. \OCP\USER::getUser() .'/'.\OCP\Config::getSystemValue('files_versionsfolder', Storage::DEFAULTFOLDER); - if(!is_dir($foldername)){ - mkdir($foldername); - } - } - } - - - /** - * listen to write event. - */ - public static function write_hook($params) { - if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') { - $path = $params[\OC_Filesystem::signal_param_path]; - if($path<>'') Storage::store($path); - } - } - - - - /** - * store a new version of a file. - */ - public static function store($filename) { - if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') { - if (\OCP\App::isEnabled('files_sharing') && $source = \OC_Share::getSource('/'.\OCP\User::getUser().'/files'.$filename)) { - $pos = strpos($source, '/files', 1); - $uid = substr($source, 1, $pos - 1); - $filename = substr($source, $pos + 6); - } else { - $uid = \OCP\User::getUser(); - } - $versionsFolderName=\OCP\Config::getSystemValue('datadirectory').'/'. $uid .'/'.\OCP\Config::getSystemValue('files_versionsfolder', Storage::DEFAULTFOLDER); - $filesfoldername=\OCP\Config::getSystemValue('datadirectory').'/'. $uid .'/files'; - Storage::init(); - - // check if filename is a directory - if(is_dir($filesfoldername.'/'.$filename)){ - return false; - } - - // check filetype blacklist - $blacklist=explode(' ',\OCP\Config::getSystemValue('files_versionsblacklist', Storage::DEFAULTBLACKLIST)); - foreach($blacklist as $bl) { - $parts=explode('.', $filename); - $ext=end($parts); - if(strtolower($ext)==$bl) { - return false; - } - } - - // check filesize - if(filesize($filesfoldername.'/'.$filename)>\OCP\Config::getSystemValue('files_versionsmaxfilesize', Storage::DEFAULTMAXFILESIZE)){ - return false; - } - - - // check mininterval if the file is being modified by the owner (all shared files should be versioned despite mininterval) - if ($uid == \OCP\User::getUser()) { - $matches=glob($versionsFolderName.'/'.$filename.'.v*'); - sort($matches); - $parts=explode('.v',end($matches)); - if((end($parts)+Storage::DEFAULTMININTERVAL)>time()){ - return false; - } - } - - - // create all parent folders - $info=pathinfo($filename); - if(!file_exists($versionsFolderName.'/'.$info['dirname'])) mkdir($versionsFolderName.'/'.$info['dirname'],0700,true); - - // store a new version of a file - copy($filesfoldername.'/'.$filename,$versionsFolderName.'/'.$filename.'.v'.time()); - - // expire old revisions if necessary - Storage::expire($filename); - } - } - - - /** - * rollback to an old version of a file. - */ - public static function rollback($filename,$revision) { - - if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') { - if (\OCP\App::isEnabled('files_sharing') && $source = \OC_Share::getSource('/'.\OCP\User::getUser().'/files'.$filename)) { - $pos = strpos($source, '/files', 1); - $uid = substr($source, 1, $pos - 1); - $filename = substr($source, $pos + 6); - } else { - $uid = \OCP\User::getUser(); - } - $versionsFolderName=\OCP\Config::getSystemValue('datadirectory').'/'.$uid .'/'.\OCP\Config::getSystemValue('files_versionsfolder', Storage::DEFAULTFOLDER); - - $filesfoldername=\OCP\Config::getSystemValue('datadirectory').'/'. $uid .'/files'; - - // rollback - if ( @copy($versionsFolderName.'/'.$filename.'.v'.$revision,$filesfoldername.'/'.$filename) ) { - - return true; - - }else{ - - return false; - - } - - } - - } - - /** - * check if old versions of a file exist. - */ - public static function isversioned($filename) { - if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') { - if (\OCP\App::isEnabled('files_sharing') && $source = \OC_Share::getSource('/'.\OCP\User::getUser().'/files'.$filename)) { - $pos = strpos($source, '/files', 1); - $uid = substr($source, 1, $pos - 1); - $filename = substr($source, $pos + 6); - } else { - $uid = \OCP\User::getUser(); - } - $versionsFolderName=\OCP\Config::getSystemValue('datadirectory').'/'. $uid .'/'.\OCP\Config::getSystemValue('files_versionsfolder', Storage::DEFAULTFOLDER); - - // check for old versions - $matches=glob($versionsFolderName.'/'.$filename.'.v*'); - if(count($matches)>1){ - return true; - }else{ - return false; - } - }else{ - return(false); - } - } - - - - /** - * @brief get a list of all available versions of a file in descending chronological order - * @param $filename file to find versions of, relative to the user files dir - * @param $count number of versions to return - * @returns array - */ - public static function getVersions( $filename, $count = 0 ) { - - if( \OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true' ) { - - if (\OCP\App::isEnabled('files_sharing') && $source = \OC_Share::getSource('/'.\OCP\User::getUser().'/files'.$filename)) { - $pos = strpos($source, '/files', 1); - $uid = substr($source, 1, $pos - 1); - $filename = substr($source, $pos + 6); - } else { - $uid = \OCP\User::getUser(); - } - $versionsFolderName = \OCP\Config::getSystemValue('datadirectory').'/'. $uid .'/'.\OCP\Config::getSystemValue('files_versionsfolder', Storage::DEFAULTFOLDER); - $versions = array(); - - // fetch for old versions - $matches = glob( $versionsFolderName.'/'.$filename.'.v*' ); - - sort( $matches ); - - $i = 0; - - foreach( $matches as $ma ) { - - $i++; - $versions[$i]['cur'] = 0; - $parts = explode( '.v', $ma ); - $versions[$i]['version'] = ( end( $parts ) ); - - // if file with modified date exists, flag it in array as currently enabled version - $curFile['fileName'] = basename( $parts[0] ); - $curFile['filePath'] = \OCP\Config::getSystemValue('datadirectory').\OC_Filesystem::getRoot().'/'.$curFile['fileName']; - - ( \md5_file( $ma ) == \md5_file( $curFile['filePath'] ) ? $versions[$i]['fileMatch'] = 1 : $versions[$i]['fileMatch'] = 0 ); - - } - - $versions = array_reverse( $versions ); - - foreach( $versions as $key => $value ) { - - // flag the first matched file in array (which will have latest modification date) as current version - if ( $versions[$key]['fileMatch'] ) { - - $versions[$key]['cur'] = 1; - break; - - } - - } - - $versions = array_reverse( $versions ); - - // only show the newest commits - if( $count != 0 and ( count( $versions )>$count ) ) { - - $versions = array_slice( $versions, count( $versions ) - $count ); - - } - - return( $versions ); - - - } else { - - // if versioning isn't enabled then return an empty array - return( array() ); - - } - - } - - /** - * @brief Erase a file's versions which exceed the set quota - */ - public static function expire($filename) { - if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') { - - if (\OCP\App::isEnabled('files_sharing') && $source = \OC_Share::getSource('/'.\OCP\User::getUser().'/files'.$filename)) { - $pos = strpos($source, '/files', 1); - $uid = substr($source, 1, $pos - 1); - $filename = substr($source, $pos + 6); - } else { - $uid = \OCP\User::getUser(); - } - $versionsFolderName=\OCP\Config::getSystemValue('datadirectory').'/'. $uid .'/'.\OCP\Config::getSystemValue('files_versionsfolder', Storage::DEFAULTFOLDER); - - // check for old versions - $matches = glob( $versionsFolderName.'/'.$filename.'.v*' ); - - if( count( $matches ) > \OCP\Config::getSystemValue( 'files_versionmaxversions', Storage::DEFAULTMAXVERSIONS ) ) { - - $numberToDelete = count( $matches-\OCP\Config::getSystemValue( 'files_versionmaxversions', Storage::DEFAULTMAXVERSIONS ) ); - - // delete old versions of a file - $deleteItems = array_slice( $matches, 0, $numberToDelete ); - - foreach( $deleteItems as $de ) { - - unlink( $versionsFolderName.'/'.$filename.'.v'.$de ); - - } - } - } - } - - /** - * @brief Erase all old versions of all user files - * @return true/false - */ - public static function expireAll() { - - $view = new \OC_FilesystemView(''); - - $dir = \OCP\Config::getSystemValue('files_versionsfolder', Storage::DEFAULTFOLDER); - - return $view->deleteAll( $dir, true ); - - } - - -} +<?php
+/**
+ * Copyright (c) 2012 Frank Karlitschek <frank@owncloud.org>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+/**
+ * Versions
+ *
+ * A class to handle the versioning of files.
+ */
+
+namespace OCA_Versions;
+
+class Storage {
+
+
+ // config.php configuration:
+ // - files_versions
+ // - files_versionsfolder
+ // - files_versionsblacklist
+ // - files_versionsmaxfilesize
+ // - files_versionsinterval
+ // - files_versionmaxversions
+ //
+ // todo:
+ // - finish porting to OC_FilesystemView to enable network transparency
+ // - add transparent compression. first test if it´s worth it.
+
+ const DEFAULTENABLED=true;
+ const DEFAULTBLACKLIST='avi mp3 mpg mp4 ctmp';
+ const DEFAULTMAXFILESIZE=1048576; // 10MB
+ const DEFAULTMININTERVAL=60; // 1 min
+ const DEFAULTMAXVERSIONS=50;
+
+ private $view;
+
+ function __construct() {
+
+ $this->view = \OCP\Files::getStorage('files_versions');
+
+ }
+
+ /**
+ * listen to write event.
+ */
+ public static function write_hook($params) {
+ if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') {
+ $path = $params[\OC_Filesystem::signal_param_path];
+ if($path<>'') $this->store($path);
+ }
+ }
+
+
+
+ /**
+ * store a new version of a file.
+ */
+ public function store($filename) {
+ if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') {
+
+ $files_view = \OCP\Files::getStorage("files");
+ $users_view = \OCP\Files::getStorage("files_versions");
+ $users_view->chroot(\OCP\User::getUser().'/');
+
+ if (\OCP\App::isEnabled('files_sharing') && $source = \OC_Share::getSource('/'.\OCP\User::getUser().'/files'.$filename)) {
+ $pos = strpos($source, '/files', 1);
+ $uid = substr($source, 1, $pos - 1);
+ $filename = substr($source, $pos + 6);
+ } else {
+ $uid = \OCP\User::getUser();
+ }
+
+ $versionsFolderName=\OCP\Config::getSystemValue('datadirectory') . $this->view->getAbsolutePath('');
+
+ //check if source file already exist as version to avoid recursions.
+ if ($users_view->file_exists($filename)) {
+ return false;
+ }
+
+ // check if filename is a directory
+ if($files_view->is_dir($filename)){
+ return false;
+ }
+
+ // check filetype blacklist
+ $blacklist=explode(' ',\OCP\Config::getSystemValue('files_versionsblacklist', Storage::DEFAULTBLACKLIST));
+ foreach($blacklist as $bl) {
+ $parts=explode('.', $filename);
+ $ext=end($parts);
+ if(strtolower($ext)==$bl) {
+ return false;
+ }
+ }
+
+ // check filesize
+ if($files_view->filesize($filename)>\OCP\Config::getSystemValue('files_versionsmaxfilesize', Storage::DEFAULTMAXFILESIZE)){
+ return false;
+ }
+
+
+ // check mininterval if the file is being modified by the owner (all shared files should be versioned despite mininterval)
+ if ($uid == \OCP\User::getUser()) {
+ $matches=glob($versionsFolderName.'/'.$filename.'.v*');
+ sort($matches);
+ $parts=explode('.v',end($matches));
+ if((end($parts)+Storage::DEFAULTMININTERVAL)>time()){
+ return false;
+ }
+ }
+
+
+ // create all parent folders
+ $info=pathinfo($filename);
+ if(!file_exists($versionsFolderName.'/'.$info['dirname'])) mkdir($versionsFolderName.'/'.$info['dirname'],0700,true);
+
+ // store a new version of a file
+ @$users_view->copy('files'.$filename, 'files_versions'.$filename.'.v'.time());
+
+ // expire old revisions if necessary
+ Storage::expire($filename);
+ }
+ }
+
+
+ /**
+ * rollback to an old version of a file.
+ */
+ public static function rollback($filename,$revision) {
+
+ if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') {
+ $users_view = \OCP\Files::getStorage("files_versions");
+ $users_view->chroot(\OCP\User::getUser().'/');
+
+ if (\OCP\App::isEnabled('files_sharing') && $source = \OC_Share::getSource('/'.\OCP\User::getUser().'/files'.$filename)) {
+ $pos = strpos($source, '/files', 1);
+ $uid = substr($source, 1, $pos - 1);
+ $filename = substr($source, $pos + 6);
+ } else {
+ $uid = \OCP\User::getUser();
+ }
+
+ // rollback
+ if( @$users_view->copy('files_versions'.$filename.'.v'.$revision, 'files'.$filename) ) {
+
+ return true;
+
+ }else{
+
+ return false;
+
+ }
+
+ }
+
+ }
+
+ /**
+ * check if old versions of a file exist.
+ */
+ public static function isversioned($filename) {
+ if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') {
+ $versions_fileview = \OCP\Files::getStorage("files_versions");
+ if (\OCP\App::isEnabled('files_sharing') && $source = \OC_Share::getSource('/'.\OCP\User::getUser().'/files'.$filename)) {
+ $pos = strpos($source, '/files', 1);
+ $filename = substr($source, $pos + 6);
+ }
+
+ $versionsFolderName=\OCP\Config::getSystemValue('datadirectory'). $versions_fileview->getAbsolutePath('');
+
+ // check for old versions
+ $matches=glob($versionsFolderName.$filename.'.v*');
+ if(count($matches)>0){
+ return true;
+ }else{
+ return false;
+ }
+ }else{
+ return(false);
+ }
+ }
+
+
+
+ /**
+ * @brief get a list of all available versions of a file in descending chronological order
+ * @param $filename file to find versions of, relative to the user files dir
+ * @param $count number of versions to return
+ * @returns array
+ */
+ public static function getVersions( $filename, $count = 0 ) {
+
+ if( \OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true' ) {
+
+ if (\OCP\App::isEnabled('files_sharing') && $source = \OC_Share::getSource('/'.\OCP\User::getUser().'/files'.$filename)) {
+ $pos = strpos($source, '/files', 1);
+ $uid = substr($source, 1, $pos - 1);
+ $filename = substr($source, $pos + 6);
+ } else {
+ $uid = \OCP\User::getUser();
+ }
+ $versions_fileview = \OCP\Files::getStorage('files_versions');
+ $versionsFolderName = \OCP\Config::getSystemValue('datadirectory'). $versions_fileview->getAbsolutePath('');
+ $versions = array();
+
+ // fetch for old versions
+ $matches = glob( $versionsFolderName.'/'.$filename.'.v*' );
+
+ sort( $matches );
+
+ $i = 0;
+
+ $files_view = \OCP\Files::getStorage('files');
+ $local_file = $files_view->getLocalFile($filename);
+ foreach( $matches as $ma ) {
+
+ $i++;
+ $versions[$i]['cur'] = 0;
+ $parts = explode( '.v', $ma );
+ $versions[$i]['version'] = ( end( $parts ) );
+
+ // if file with modified date exists, flag it in array as currently enabled version
+ ( \md5_file( $ma ) == \md5_file( $local_file ) ? $versions[$i]['fileMatch'] = 1 : $versions[$i]['fileMatch'] = 0 );
+
+ }
+
+ $versions = array_reverse( $versions );
+
+ foreach( $versions as $key => $value ) {
+
+ // flag the first matched file in array (which will have latest modification date) as current version
+ if ( $versions[$key]['fileMatch'] ) {
+
+ $versions[$key]['cur'] = 1;
+ break;
+
+ }
+
+ }
+
+ $versions = array_reverse( $versions );
+
+ // only show the newest commits
+ if( $count != 0 and ( count( $versions )>$count ) ) {
+
+ $versions = array_slice( $versions, count( $versions ) - $count );
+
+ }
+
+ return( $versions );
+
+
+ } else {
+
+ // if versioning isn't enabled then return an empty array
+ return( array() );
+
+ }
+
+ }
+
+ /**
+ * @brief Erase a file's versions which exceed the set quota
+ */
+ public static function expire($filename) {
+ if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') {
+
+ if (\OCP\App::isEnabled('files_sharing') && $source = \OC_Share::getSource('/'.\OCP\User::getUser().'/files'.$filename)) {
+ $pos = strpos($source, '/files', 1);
+ $uid = substr($source, 1, $pos - 1);
+ $filename = substr($source, $pos + 6);
+ } else {
+ $uid = \OCP\User::getUser();
+ }
+ $versions_fileview = \OCP\Files::getStorage("files_versions");
+ $versionsFolderName=\OCP\Config::getSystemValue('datadirectory'). $versions_fileview->getAbsolutePath('');
+
+ // check for old versions
+ $matches = glob( $versionsFolderName.'/'.$filename.'.v*' );
+
+ if( count( $matches ) > \OCP\Config::getSystemValue( 'files_versionmaxversions', Storage::DEFAULTMAXVERSIONS ) ) {
+
+ $numberToDelete = count( $matches-\OCP\Config::getSystemValue( 'files_versionmaxversions', Storage::DEFAULTMAXVERSIONS ) );
+
+ // delete old versions of a file
+ $deleteItems = array_slice( $matches, 0, $numberToDelete );
+
+ foreach( $deleteItems as $de ) {
+
+ unlink( $versionsFolderName.'/'.$filename.'.v'.$de );
+
+ }
+ }
+ }
+ }
+
+ /**
+ * @brief Erase all old versions of all user files
+ * @return true/false
+ */
+ public function expireAll() {
+ return $this->view->deleteAll('', true);
+ }
+}
diff --git a/apps/files_versions/settings.php b/apps/files_versions/settings.php index 5f9e60fc589..f2873b8f7c2 100644 --- a/apps/files_versions/settings.php +++ b/apps/files_versions/settings.php @@ -7,4 +7,3 @@ OCP\Util::addscript( 'files_versions', 'versions' ); $tmpl = new OCP\Template( 'files_versions', 'settings'); return $tmpl->fetchPage(); -?> diff --git a/apps/files_versions/templates/history.php b/apps/files_versions/templates/history.php index 13e104152b7..1b442556421 100644 --- a/apps/files_versions/templates/history.php +++ b/apps/files_versions/templates/history.php @@ -20,13 +20,11 @@ if( isset( $_['message'] ) ) { echo('<p><em>Revert a file to a previous version by clicking on its revert button</em></p><br />'); foreach ( $_['versions'] as $v ) { - echo ' '; - echo OCP\Util::formatDate( $v['version'] ); + echo OCP\Util::formatDate( doubleval($v['version']) ); echo ' <a href="'.OCP\Util::linkTo('files_versions', 'history.php').'?path='.urlencode( $_['path'] ).'&revert='. $v['version'] .'" class="button">Revert</a><br /><br />'; if ( $v['cur'] ) { echo ' (<b>Current</b>)'; } echo '<br /><br />'; - } } diff --git a/apps/gallery/ajax/createAlbum.php b/apps/gallery/ajax/createAlbum.php index 61e2e9ae2e9..5bfa5aa9a93 100644 --- a/apps/gallery/ajax/createAlbum.php +++ b/apps/gallery/ajax/createAlbum.php @@ -28,5 +28,3 @@ OCP\JSON::checkAppEnabled('gallery'); OC_Gallery_Album::create(OCP\USER::getUser(), $_GET['album_name']); OCP\JSON::success(array('name' => $_GET['album_name'])); - -?> diff --git a/apps/gallery/ajax/galleryOp.php b/apps/gallery/ajax/galleryOp.php index 7cbe3e46e21..ab8c64e28ad 100644 --- a/apps/gallery/ajax/galleryOp.php +++ b/apps/gallery/ajax/galleryOp.php @@ -186,4 +186,3 @@ if ($_GET['operation']) { OCP\JSON::error(array('cause' => 'Unknown operation')); } } -?> diff --git a/apps/gallery/ajax/viewImage.php b/apps/gallery/ajax/viewImage.php new file mode 100644 index 00000000000..daf0ab741f0 --- /dev/null +++ b/apps/gallery/ajax/viewImage.php @@ -0,0 +1,32 @@ +<?php + +/** + * ownCloud - gallery application + * + * @author Ike Devolder + * @copyright 2012 Ike Devolder + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ +OCP\JSON::checkLoggedIn(); +OCP\JSON::checkAppEnabled('gallery'); + +$img = $_GET['img']; + +$image = OC_Gallery_Photo::getViewImage($img); +if ($image) { + OCP\Response::enableCaching(3600 * 24); // 24 hour + $image->show(); +} diff --git a/apps/gallery/css/styles.css b/apps/gallery/css/styles.css index dcef1f08c6d..63f645662dd 100644 --- a/apps/gallery/css/styles.css +++ b/apps/gallery/css/styles.css @@ -1,11 +1,11 @@ #gallerycontent { margin-top: 2.8em; overflow: visible; } -#g-settings {position: absolute; left 13.5em; top: 0;} +#g-settings {position: absolute; left: 13.5em; top: 0;} div#controls input[type=button] { -webkit-transition: opacity 0.5s ease-in-out; -moz-transition: opacity 0.5s ease-in-out; -o-transition: opacity 0.5s ease-in-out; opacity: 1; position:absolute; right:13.5em; top:0em; } input[type=button]:disabled { opacity: 0.5 } .ui-dialog tr {background-color: #eee;} .ui-dialog input {width: 90%;} -div.gallery_div {position:relative; display: inline-block; height: 152px; width: 150px; margin: 5px;} +div.gallery_div {position:relative; display: inline-block; height: 150px; width: 150px; margin: 5px;} div.miniature_border {position:absolute; height: 150px; -moz-transition-duration: 0.2s; -o-transition-duration:0.2s; -webkit-transition-duration: .2s; background-position: 50%;} div.line {display:inline-block; border: 0; width: auto; height: 160px} div.gallery_div img{position:absolute; top: 1; left: 0; -moz-transition-duration: 0.3s; -o-transition-duration:0.3s; -webkit-transition-duration: 0.3s; height:150px; width: auto;} diff --git a/apps/gallery/css/supersized.css b/apps/gallery/css/supersized.css new file mode 100644 index 00000000000..57ee7e23a50 --- /dev/null +++ b/apps/gallery/css/supersized.css @@ -0,0 +1,25 @@ +/* + + Supersized - Fullscreen Slideshow jQuery Plugin + Version : 3.2.7 + Site : www.buildinternet.com/project/supersized + + Author : Sam Dunn + Company : One Mighty Roar (www.onemightyroar.com) + License : MIT License / GPL License + +*/ +#supersized-holder #supersized-loader { display:none; position:absolute; top:50%; left:50%; z-index:0; width:60px; height:60px; margin:-30px 0 0 -30px; text-indent:-999em; background:url('%appswebroot%/gallery/img/supersized/progress.gif') no-repeat center center;} + +#supersized-holder #supersized { visibility:hidden; display:block; position:fixed; left:0; top:0; overflow:hidden; z-index:200; height:100%; width:100%; } +#supersized-holder #supersized img { width:auto; height:auto; position:relative; display:none; outline:none; border:none; } +#supersized-holder #supersized.speed img { -ms-interpolation-mode:nearest-neighbor; image-rendering: -moz-crisp-edges; } /*Speed*/ +#supersized-holder #supersized.quality img { -ms-interpolation-mode:bicubic; image-rendering: optimizeQuality; } /*Quality*/ + +#supersized-holder #supersized li { display:block; list-style:none; z-index:150; position:fixed; overflow:hidden; top:0; left:0; width:100%; height:100%; background:#111; } +#supersized-holder #supersized a { width:100%; height:100%; display:block; } +#supersized-holder #supersized li.prevslide { z-index:160; } +#supersized-holder #supersized li.activeslide { z-index:170; } +#supersized-holder #supersized li.image-loading { background:#111 url('%appswebroot%/gallery/img/supersized/progress.gif') no-repeat center center; width:100%; height:100%; } +#supersized-holder #supersized li.image-loading img{ visibility:hidden; } +#supersized-holder #supersized li.prevslide img, #supersized-holder #supersized li.activeslide img{ display:inline; } diff --git a/apps/gallery/css/supersized.shutter.css b/apps/gallery/css/supersized.shutter.css new file mode 100644 index 00000000000..428c254c3b2 --- /dev/null +++ b/apps/gallery/css/supersized.shutter.css @@ -0,0 +1,74 @@ +/* + + Supersized - Fullscreen Slideshow jQuery Plugin + Version : 3.2.7 + Site : www.buildinternet.com/project/supersized + + Theme : Shutter 1.2 + Author : Sam Dunn + Company : One Mighty Roar (www.onemightyroar.com) + License : MIT License / GPL License + +*/ + +/* Controls Bar +----------------------------*/ +#slideshow-content #slideshow-controls-wrapper { margin:0 auto; height:42px; width:100%; bottom:0px; left:0; z-index:204; background:url('%appswebroot%/gallery/img/supersized/nav-bg.png') repeat-x; position:fixed; } +#slideshow-content #slideshow-controls { overflow:hidden; height:100%; position:relative; text-align:left; z-index:205; } +#slideshow-content #slidecounter { float:left; color:#999; font:14px "Helvetica Neue", Helvetica, Arial, sans-serif; text-shadow:#000 0 -1px 0; margin:0px 10px 0 15px; line-height:42px; } +#slideshow-content #slidecaption { overflow:hidden; float:left; color:#FFF; font:400 14px "Helvetica Neue", Helvetica, Arial, sans-serif; text-shadow:#000 1px 1px 2px; margin:0 20px 0 0; line-height:42px; } + +/*#navigation { float:right; margin:0px 20px 0 0; }*/ +#slideshow-content #play-button{ float:left; margin-top:1px;border-right:1px solid #333; background:url('%appswebroot%/gallery/img/supersized/bg-hover.png') repeat-x 0 44px; } +#slideshow-content #play-button:hover{ background-position:0 1px; cursor:pointer; } + +#slideshow-content #prevslide, #nextslide{ position:fixed; height:43px; width:43px; top:50%; margin-top:-21px; opacity:0.6; z-index:204; } +#slideshow-content #prevslide{ left:10px; background:url('%appswebroot%/gallery/img/supersized/back.png'); } +#slideshow-content #nextslide{ right:10px; background:url('%appswebroot%/gallery/img/supersized/forward.png'); } +#slideshow-content #prevslide:active, #nextslide:active{ margin-top:-19px; } +#slideshow-content #prevslide:hover, #nextslide:hover{ cursor:pointer; } + +#slideshow-content ul#slide-list{ padding:15px 0; float:left; position:absolute; left:50%; } +#slideshow-content ul#slide-list li{ list-style:none; width:12px; height:12px; float:left; margin:0 5px 0 0; } +#slideshow-content ul#slide-list li.current-slide a, ul#slide-list li.current-slide a:hover{ background-position:0 0px; } +#slideshow-content ul#slide-list li a{ display:block; width:12px; height:12px; background:url('%appswebroot%/gallery/img/supersized/nav-dot.png') no-repeat 0 -24px; } +#slideshow-content ul#slide-list li a:hover{ background-position:0 -12px; cursor:pointer; } + +#slideshow-content #tray-button{ float:right; margin-top:1px; border-left:1px solid #333; background:url('%appswebroot%/gallery/img/supersized/bg-hover.png') repeat-x 0 44px; } +#slideshow-content #tray-button:hover{ background-position:0 1px; cursor:pointer; } + + +/* Progress Bar +----------------------------*/ +#slideshow-content #progress-back{ z-index:205; position:fixed; bottom:42px; left:0; height:8px; width:100%; background:url('%appswebroot%/gallery/img/supersized/progress-back.png') repeat-x; } +#slideshow-content #progress-bar{ position:relative; height:8px; width:100%; background:url('%appswebroot%/gallery/img/supersized/progress-bar.png') repeat-x; } + + +/* Thumbnail Navigation +----------------------------*/ +#slideshow-content #nextthumb, #slideshow-content #prevthumb { z-index:202; display:none; position:fixed; bottom:61px; height:75px; width:100px; overflow:hidden; background:#ddd; border:1px solid #fff; -webkit-box-shadow:0 0 5px #000; } +#slideshow-content #nextthumb { right:12px; } +#slideshow-content #prevthumb { left:12px; } +#slideshow-content #nextthumb img, #slideshow-content #prevthumb img { width:150px; height:auto; } +#slideshow-content #nextthumb:active, #slideshow-content #prevthumb:active { bottom:59px; } +#slideshow-content #nextthumb:hover, #slideshow-content #prevthumb:hover { cursor:pointer; } + + +/* Thumbnail Tray +----------------------------*/ +#slideshow-content #thumb-tray{ position:fixed; z-index:203; bottom:0; left:0; background:url('%appswebroot%/gallery/img/supersized/bg-black.png'); height:150px; width:100%; overflow:hidden; text-align:center; -moz-box-shadow: 0px 0px 4px #000; -webkit-box-shadow: 0px 0px 4px #000; box-shadow: 0px 0px 4px #000; } + +#slideshow-content #thumb-back, #slideshow-content #thumb-forward{ position:absolute; z-index:5; bottom:42px; height:108px; width:40px; } +#slideshow-content #thumb-back{ left:0; background: url('%appswebroot%/gallery/img/supersized/thumb-back.png') no-repeat center center;} +#slideshow-content #thumb-forward{ right:0; background:url('%appswebroot%/gallery/img/supersized/thumb-forward.png') no-repeat center center;} +#slideshow-content #thumb-back:hover, #slideshow-content #thumb-forward:hover{ cursor:pointer; background-color:rgba(256,256,256, 0.1); } +#slideshow-content #thumb-back:hover{ border-right:1px solid rgba(256,256,256, 0.2); } +#slideshow-content #thumb-forward:hover{ border-left:1px solid rgba(256,256,256, 0.2); } + + +#slideshow-content ul#thumb-list{ display:inline-block; list-style:none; position:relative; left:0px; padding:0 0px; } +#slideshow-content ul#thumb-list li{ background:#111; list-style:none; display:inline; width:150px; height:108px; overflow:hidden; float:left; margin:0; } +#slideshow-content ul#thumb-list li img { width:200px; height:auto; opacity:0.5; -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)"; filter:alpha(opacity=60); -webkit-transition: all 100ms ease-in-out; -moz-transition: all 100ms ease-in-out; -o-transition: all 100ms ease-in-out; -ms-transition: all 100ms ease-in-out; transition: all 100ms ease-in-out; } +#slideshow-content ul#thumb-list li.current-thumb img, #slideshow-content ul#thumb-list li:hover img{ opacity:1; -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; filter:alpha(opacity=100); } +#slideshow-content ul#thumb-list li:hover{ cursor:pointer; } + diff --git a/apps/gallery/img/supersized/back.png b/apps/gallery/img/supersized/back.png Binary files differnew file mode 100644 index 00000000000..44cd0ae703c --- /dev/null +++ b/apps/gallery/img/supersized/back.png diff --git a/apps/gallery/img/supersized/bg-black.png b/apps/gallery/img/supersized/bg-black.png Binary files differnew file mode 100644 index 00000000000..8c2f00140d6 --- /dev/null +++ b/apps/gallery/img/supersized/bg-black.png diff --git a/apps/gallery/img/supersized/bg-hover.png b/apps/gallery/img/supersized/bg-hover.png Binary files differnew file mode 100644 index 00000000000..1ca2022e106 --- /dev/null +++ b/apps/gallery/img/supersized/bg-hover.png diff --git a/apps/gallery/img/supersized/button-tray-down.png b/apps/gallery/img/supersized/button-tray-down.png Binary files differnew file mode 100644 index 00000000000..99b92aef122 --- /dev/null +++ b/apps/gallery/img/supersized/button-tray-down.png diff --git a/apps/gallery/img/supersized/button-tray-up.png b/apps/gallery/img/supersized/button-tray-up.png Binary files differnew file mode 100644 index 00000000000..7cc57785f0a --- /dev/null +++ b/apps/gallery/img/supersized/button-tray-up.png diff --git a/apps/gallery/img/supersized/forward.png b/apps/gallery/img/supersized/forward.png Binary files differnew file mode 100644 index 00000000000..e2084ab3faf --- /dev/null +++ b/apps/gallery/img/supersized/forward.png diff --git a/apps/gallery/img/supersized/nav-bg.png b/apps/gallery/img/supersized/nav-bg.png Binary files differnew file mode 100644 index 00000000000..800f904ddc7 --- /dev/null +++ b/apps/gallery/img/supersized/nav-bg.png diff --git a/apps/gallery/img/supersized/nav-dot.png b/apps/gallery/img/supersized/nav-dot.png Binary files differnew file mode 100644 index 00000000000..a28a50789f3 --- /dev/null +++ b/apps/gallery/img/supersized/nav-dot.png diff --git a/apps/gallery/img/supersized/pause.png b/apps/gallery/img/supersized/pause.png Binary files differnew file mode 100644 index 00000000000..a2c21a51cee --- /dev/null +++ b/apps/gallery/img/supersized/pause.png diff --git a/apps/gallery/img/supersized/play.png b/apps/gallery/img/supersized/play.png Binary files differnew file mode 100644 index 00000000000..16e53f86745 --- /dev/null +++ b/apps/gallery/img/supersized/play.png diff --git a/apps/gallery/img/supersized/progress-back.png b/apps/gallery/img/supersized/progress-back.png Binary files differnew file mode 100644 index 00000000000..68cd45b6706 --- /dev/null +++ b/apps/gallery/img/supersized/progress-back.png diff --git a/apps/gallery/img/supersized/progress-bar.png b/apps/gallery/img/supersized/progress-bar.png Binary files differnew file mode 100644 index 00000000000..49ebb0513b7 --- /dev/null +++ b/apps/gallery/img/supersized/progress-bar.png diff --git a/apps/gallery/img/supersized/progress.gif b/apps/gallery/img/supersized/progress.gif Binary files differnew file mode 100644 index 00000000000..f3e45e0569c --- /dev/null +++ b/apps/gallery/img/supersized/progress.gif diff --git a/apps/gallery/img/supersized/supersized-logo.png b/apps/gallery/img/supersized/supersized-logo.png Binary files differnew file mode 100644 index 00000000000..b1243a29784 --- /dev/null +++ b/apps/gallery/img/supersized/supersized-logo.png diff --git a/apps/gallery/img/supersized/thumb-back.png b/apps/gallery/img/supersized/thumb-back.png Binary files differnew file mode 100644 index 00000000000..3c969ebd527 --- /dev/null +++ b/apps/gallery/img/supersized/thumb-back.png diff --git a/apps/gallery/img/supersized/thumb-forward.png b/apps/gallery/img/supersized/thumb-forward.png Binary files differnew file mode 100644 index 00000000000..afe451c75d0 --- /dev/null +++ b/apps/gallery/img/supersized/thumb-forward.png diff --git a/apps/gallery/index.php b/apps/gallery/index.php index b8aadacb47f..ce79f8f8782 100644 --- a/apps/gallery/index.php +++ b/apps/gallery/index.php @@ -30,8 +30,14 @@ OCP\App::setActiveNavigationEntry( 'gallery_index' ); OCP\Util::addStyle('files', 'files'); OCP\Util::addStyle('gallery', 'styles'); OCP\Util::addScript('gallery', 'pictures'); +OCP\Util::addStyle( 'gallery', 'supersized' ); +OCP\Util::addStyle( 'gallery', 'supersized.shutter' ); +OCP\Util::addScript('gallery', 'slideshow'); +OCP\Util::addScript('gallery', 'jquery.easing.min'); +OCP\Util::addScript('gallery', 'supersized.3.2.7.min'); +OCP\Util::addScript('gallery', 'supersized.shutter.min'); -include('gallery/lib/tiles.php'); +include 'gallery/lib/tiles.php'; $root = !empty($_GET['root']) ? $_GET['root'] : '/'; $images = \OC_FileCache::searchByMime('image', null, '/'.\OCP\USER::getUser().'/files'.$root); @@ -97,4 +103,3 @@ $tmpl = new OCP\Template( 'gallery', 'index', 'user' ); $tmpl->assign('root', $root, false); $tmpl->assign('tl', $tl, false); $tmpl->printPage(); -?> diff --git a/apps/gallery/js/albums.js b/apps/gallery/js/albums.js index 413c71471a3..62d3f783ece 100644 --- a/apps/gallery/js/albums.js +++ b/apps/gallery/js/albums.js @@ -79,7 +79,7 @@ Albums={ }); element.append(local); } - var photoDisplayTemplate = '<div class="gallery_box"><div class="dummy"></div><div><a rel="images" href="'+OC.linkTo('files','download.php')+'?file=URLPATH"><img src="'+OC.filePath('gallery','ajax','thumbnail.php')+'?img=IMGPATH"></a></div></div>'; + var photoDisplayTemplate = '<div class="gallery_box"><div class="dummy"></div><div><a rel="images" href="'+OC.linkTo('gallery/ajax','viewImage.php')+'?img=URLPATH"><img src="'+OC.filePath('gallery','ajax','thumbnail.php')+'?img=IMGPATH"></a></div></div>'; for (var i in Albums.photos) { element.append(photoDisplayTemplate.replace("IMGPATH", escape(Albums.photos[i])).replace("URLPATH", escape(Albums.photos[i]))); } diff --git a/apps/gallery/js/jquery.easing.min.js b/apps/gallery/js/jquery.easing.min.js new file mode 100644 index 00000000000..bbf8410391a --- /dev/null +++ b/apps/gallery/js/jquery.easing.min.js @@ -0,0 +1,71 @@ +/* + * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/ + * + * Uses the built in easing capabilities added In jQuery 1.1 + * to offer multiple easing options + * + * TERMS OF USE - jQuery Easing + * + * Open source under the BSD License. + * + * Copyright å© 2008 George McGinley Smith + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the author nor the names of contributors may be used to endorse + * or promote products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * +*/ + +jQuery.easing.jswing=jQuery.easing.swing;jQuery.extend(jQuery.easing,{def:"easeOutQuad",swing:function(e,f,a,h,g){return jQuery.easing[jQuery.easing.def](e,f,a,h,g)},easeInQuad:function(e,f,a,h,g){return h*(f/=g)*f+a},easeOutQuad:function(e,f,a,h,g){return -h*(f/=g)*(f-2)+a},easeInOutQuad:function(e,f,a,h,g){if((f/=g/2)<1){return h/2*f*f+a}return -h/2*((--f)*(f-2)-1)+a},easeInCubic:function(e,f,a,h,g){return h*(f/=g)*f*f+a},easeOutCubic:function(e,f,a,h,g){return h*((f=f/g-1)*f*f+1)+a},easeInOutCubic:function(e,f,a,h,g){if((f/=g/2)<1){return h/2*f*f*f+a}return h/2*((f-=2)*f*f+2)+a},easeInQuart:function(e,f,a,h,g){return h*(f/=g)*f*f*f+a},easeOutQuart:function(e,f,a,h,g){return -h*((f=f/g-1)*f*f*f-1)+a},easeInOutQuart:function(e,f,a,h,g){if((f/=g/2)<1){return h/2*f*f*f*f+a}return -h/2*((f-=2)*f*f*f-2)+a},easeInQuint:function(e,f,a,h,g){return h*(f/=g)*f*f*f*f+a},easeOutQuint:function(e,f,a,h,g){return h*((f=f/g-1)*f*f*f*f+1)+a},easeInOutQuint:function(e,f,a,h,g){if((f/=g/2)<1){return h/2*f*f*f*f*f+a}return h/2*((f-=2)*f*f*f*f+2)+a},easeInSine:function(e,f,a,h,g){return -h*Math.cos(f/g*(Math.PI/2))+h+a},easeOutSine:function(e,f,a,h,g){return h*Math.sin(f/g*(Math.PI/2))+a},easeInOutSine:function(e,f,a,h,g){return -h/2*(Math.cos(Math.PI*f/g)-1)+a},easeInExpo:function(e,f,a,h,g){return(f==0)?a:h*Math.pow(2,10*(f/g-1))+a},easeOutExpo:function(e,f,a,h,g){return(f==g)?a+h:h*(-Math.pow(2,-10*f/g)+1)+a},easeInOutExpo:function(e,f,a,h,g){if(f==0){return a}if(f==g){return a+h}if((f/=g/2)<1){return h/2*Math.pow(2,10*(f-1))+a}return h/2*(-Math.pow(2,-10*--f)+2)+a},easeInCirc:function(e,f,a,h,g){return -h*(Math.sqrt(1-(f/=g)*f)-1)+a},easeOutCirc:function(e,f,a,h,g){return h*Math.sqrt(1-(f=f/g-1)*f)+a},easeInOutCirc:function(e,f,a,h,g){if((f/=g/2)<1){return -h/2*(Math.sqrt(1-f*f)-1)+a}return h/2*(Math.sqrt(1-(f-=2)*f)+1)+a},easeInElastic:function(f,h,e,l,k){var i=1.70158;var j=0;var g=l;if(h==0){return e}if((h/=k)==1){return e+l}if(!j){j=k*0.3}if(g<Math.abs(l)){g=l;var i=j/4}else{var i=j/(2*Math.PI)*Math.asin(l/g)}return -(g*Math.pow(2,10*(h-=1))*Math.sin((h*k-i)*(2*Math.PI)/j))+e},easeOutElastic:function(f,h,e,l,k){var i=1.70158;var j=0;var g=l;if(h==0){return e}if((h/=k)==1){return e+l}if(!j){j=k*0.3}if(g<Math.abs(l)){g=l;var i=j/4}else{var i=j/(2*Math.PI)*Math.asin(l/g)}return g*Math.pow(2,-10*h)*Math.sin((h*k-i)*(2*Math.PI)/j)+l+e},easeInOutElastic:function(f,h,e,l,k){var i=1.70158;var j=0;var g=l;if(h==0){return e}if((h/=k/2)==2){return e+l}if(!j){j=k*(0.3*1.5)}if(g<Math.abs(l)){g=l;var i=j/4}else{var i=j/(2*Math.PI)*Math.asin(l/g)}if(h<1){return -0.5*(g*Math.pow(2,10*(h-=1))*Math.sin((h*k-i)*(2*Math.PI)/j))+e}return g*Math.pow(2,-10*(h-=1))*Math.sin((h*k-i)*(2*Math.PI)/j)*0.5+l+e},easeInBack:function(e,f,a,i,h,g){if(g==undefined){g=1.70158}return i*(f/=h)*f*((g+1)*f-g)+a},easeOutBack:function(e,f,a,i,h,g){if(g==undefined){g=1.70158}return i*((f=f/h-1)*f*((g+1)*f+g)+1)+a},easeInOutBack:function(e,f,a,i,h,g){if(g==undefined){g=1.70158}if((f/=h/2)<1){return i/2*(f*f*(((g*=(1.525))+1)*f-g))+a}return i/2*((f-=2)*f*(((g*=(1.525))+1)*f+g)+2)+a},easeInBounce:function(e,f,a,h,g){return h-jQuery.easing.easeOutBounce(e,g-f,0,h,g)+a},easeOutBounce:function(e,f,a,h,g){if((f/=g)<(1/2.75)){return h*(7.5625*f*f)+a}else{if(f<(2/2.75)){return h*(7.5625*(f-=(1.5/2.75))*f+0.75)+a}else{if(f<(2.5/2.75)){return h*(7.5625*(f-=(2.25/2.75))*f+0.9375)+a}else{return h*(7.5625*(f-=(2.625/2.75))*f+0.984375)+a}}}},easeInOutBounce:function(e,f,a,h,g){if(f<g/2){return jQuery.easing.easeInBounce(e,f*2,0,h,g)*0.5+a}return jQuery.easing.easeOutBounce(e,f*2-g,0,h,g)*0.5+h*0.5+a}}); + +/* + * + * TERMS OF USE - EASING EQUATIONS + * + * Open source under the BSD License. + * + * Copyright å© 2001 Robert Penner + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the author nor the names of contributors may be used to endorse + * or promote products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */
\ No newline at end of file diff --git a/apps/gallery/js/slideshow.js b/apps/gallery/js/slideshow.js new file mode 100644 index 00000000000..cc5dfc44a26 --- /dev/null +++ b/apps/gallery/js/slideshow.js @@ -0,0 +1,58 @@ +$(document).ready(function(){ + + $.endSlideshow = function () { + if($.supersized.vars.slideshow_interval){ + clearInterval($.supersized.vars.slideshow_interval); + }; + + $('#supersized-holder').remove(); + $('#slideshow-content').hide(); + $('#thumb-list').remove(); + } + + // add slideshow in holder div + $('#slideshow input.start').click(function(){ + + var images=[]; + $('#gallerycontent div a').each(function(i,a){ + images.push({image : a.href, title : a.title.replace(/</, '<').replace(/>/, '>'), thumb : a.children[0].src, url : 'javascript:$.endSlideshow()'}); + }); + + if (images.length <= 0) { + return; + } + + $('body').append("<div id='supersized-holder'></div>"); + $('#supersized-loader').remove(); + $('#supersized').remove(); + $('#supersized-holder').append("<div id='supersized-loader'></div><ul id='supersized'></ul>"); + $('#supersized').show(); + $('#slideshow-content').show(); + + + jQuery(function($){ + + $.supersized({ + + // Functionality + slide_interval : 3000, // Length between transitions + transition : 1, // 0-None, 1-Fade, 2-Slide Top, 3-Slide Right, 4-Slide Bottom, 5-Slide Left, 6-Carousel Right, 7-Carousel Left + transition_speed : 700, // Speed of transition + + // Components + slide_links : 'blank', // Individual links for each slide (Options: false, 'num', 'name', 'blank') + slides : images // Slideshow Images + + }); + }); + + }); + + //close slideshow on esc and remove holder + $(document).keyup(function(e) { + if (e.keyCode == 27) { // esc + $.endSlideshow(); + } + }); + +}); diff --git a/apps/gallery/js/supersized.3.2.7.js b/apps/gallery/js/supersized.3.2.7.js new file mode 100644 index 00000000000..f5a1c0bbc2d --- /dev/null +++ b/apps/gallery/js/supersized.3.2.7.js @@ -0,0 +1,930 @@ +/* + + Supersized - Fullscreen Slideshow jQuery Plugin + Version : 3.2.7 + Site : www.buildinternet.com/project/supersized + + Author : Sam Dunn + Company : One Mighty Roar (www.onemightyroar.com) + License : MIT License / GPL License + +*/ + +(function($){ + + /* Place Supersized Elements + ----------------------------*/ + $(document).ready(function() { + $('body').append('<div id="supersized-loader"></div><ul id="supersized"></ul>'); + }); + + + $.supersized = function(options){ + + /* Variables + ----------------------------*/ + var el = '#supersized', + base = this; + // Access to jQuery and DOM versions of element + base.$el = $(el); + base.el = el; + vars = $.supersized.vars; + // Add a reverse reference to the DOM object + base.$el.data("supersized", base); + api = base.$el.data('supersized'); + + base.init = function(){ + // Combine options and vars + $.supersized.vars = $.extend($.supersized.vars, $.supersized.themeVars); + $.supersized.vars.options = $.extend({},$.supersized.defaultOptions, $.supersized.themeOptions, options); + base.options = $.supersized.vars.options; + + base._build(); + }; + + + /* Build Elements + ----------------------------*/ + base._build = function(){ + // Add in slide markers + var thisSlide = 0, + slideSet = '', + markers = '', + markerContent, + thumbMarkers = '', + thumbImage; + + while(thisSlide <= base.options.slides.length-1){ + //Determine slide link content + switch(base.options.slide_links){ + case 'num': + markerContent = thisSlide; + break; + case 'name': + markerContent = base.options.slides[thisSlide].title; + break; + case 'blank': + markerContent = ''; + break; + } + + slideSet = slideSet+'<li class="slide-'+thisSlide+'"></li>'; + + if(thisSlide == base.options.start_slide-1){ + // Slide links + if (base.options.slide_links)markers = markers+'<li class="slide-link-'+thisSlide+' current-slide"><a>'+markerContent+'</a></li>'; + // Slide Thumbnail Links + if (base.options.thumb_links){ + base.options.slides[thisSlide].thumb ? thumbImage = base.options.slides[thisSlide].thumb : thumbImage = base.options.slides[thisSlide].image; + thumbMarkers = thumbMarkers+'<li class="thumb'+thisSlide+' current-thumb"><img src="'+thumbImage+'"/></li>'; + }; + }else{ + // Slide links + if (base.options.slide_links) markers = markers+'<li class="slide-link-'+thisSlide+'" ><a>'+markerContent+'</a></li>'; + // Slide Thumbnail Links + if (base.options.thumb_links){ + base.options.slides[thisSlide].thumb ? thumbImage = base.options.slides[thisSlide].thumb : thumbImage = base.options.slides[thisSlide].image; + thumbMarkers = thumbMarkers+'<li class="thumb'+thisSlide+'"><img src="'+thumbImage+'"/></li>'; + }; + } + thisSlide++; + } + + if (base.options.slide_links) $(vars.slide_list).html(markers); + if (base.options.thumb_links && vars.thumb_tray.length){ + $(vars.thumb_tray).append('<ul id="'+vars.thumb_list.replace('#','')+'">'+thumbMarkers+'</ul>'); + } + + $(base.el).append(slideSet); + + // Add in thumbnails + if (base.options.thumbnail_navigation){ + // Load previous thumbnail + vars.current_slide - 1 < 0 ? prevThumb = base.options.slides.length - 1 : prevThumb = vars.current_slide - 1; + $(vars.prev_thumb).show().html($("<img/>").attr("src", base.options.slides[prevThumb].image)); + + // Load next thumbnail + vars.current_slide == base.options.slides.length - 1 ? nextThumb = 0 : nextThumb = vars.current_slide + 1; + $(vars.next_thumb).show().html($("<img/>").attr("src", base.options.slides[nextThumb].image)); + } + + base._start(); // Get things started + }; + + + /* Initialize + ----------------------------*/ + base._start = function(){ + + // Determine if starting slide random + if (base.options.start_slide){ + vars.current_slide = base.options.start_slide - 1; + }else{ + vars.current_slide = Math.floor(Math.random()*base.options.slides.length); // Generate random slide number + } + + // If links should open in new window + var linkTarget = base.options.new_window ? ' target="_blank"' : ''; + + // Set slideshow quality (Supported only in FF and IE, no Webkit) + if (base.options.performance == 3){ + base.$el.addClass('speed'); // Faster transitions + } else if ((base.options.performance == 1) || (base.options.performance == 2)){ + base.$el.addClass('quality'); // Higher image quality + } + + // Shuffle slide order if needed + if (base.options.random){ + arr = base.options.slides; + for(var j, x, i = arr.length; i; j = parseInt(Math.random() * i), x = arr[--i], arr[i] = arr[j], arr[j] = x); // Fisher-Yates shuffle algorithm (jsfromhell.com/array/shuffle) + base.options.slides = arr; + } + + /*-----Load initial set of images-----*/ + + if (base.options.slides.length > 1){ + if(base.options.slides.length > 2){ + // Set previous image + vars.current_slide - 1 < 0 ? loadPrev = base.options.slides.length - 1 : loadPrev = vars.current_slide - 1; // If slide is 1, load last slide as previous + var imageLink = (base.options.slides[loadPrev].url) ? "href='" + base.options.slides[loadPrev].url + "'" : ""; + + var imgPrev = $('<img src="'+base.options.slides[loadPrev].image+'"/>'); + var slidePrev = base.el+' li:eq('+loadPrev+')'; + imgPrev.appendTo(slidePrev).wrap('<a ' + imageLink + linkTarget + '></a>').parent().parent().addClass('image-loading prevslide'); + + imgPrev.load(function(){ + $(this).data('origWidth', $(this).width()).data('origHeight', $(this).height()); + base.resizeNow(); // Resize background image + }); // End Load + } + } else { + // Slideshow turned off if there is only one slide + base.options.slideshow = 0; + } + + // Set current image + imageLink = (api.getField('url')) ? "href='" + api.getField('url') + "'" : ""; + var img = $('<img src="'+api.getField('image')+'"/>'); + + var slideCurrent= base.el+' li:eq('+vars.current_slide+')'; + img.appendTo(slideCurrent).wrap('<a ' + imageLink + linkTarget + '></a>').parent().parent().addClass('image-loading activeslide'); + + img.load(function(){ + base._origDim($(this)); + base.resizeNow(); // Resize background image + base.launch(); + if( typeof theme != 'undefined' && typeof theme._init == "function" ) theme._init(); // Load Theme + }); + + if (base.options.slides.length > 1){ + // Set next image + vars.current_slide == base.options.slides.length - 1 ? loadNext = 0 : loadNext = vars.current_slide + 1; // If slide is last, load first slide as next + imageLink = (base.options.slides[loadNext].url) ? "href='" + base.options.slides[loadNext].url + "'" : ""; + + var imgNext = $('<img src="'+base.options.slides[loadNext].image+'"/>'); + var slideNext = base.el+' li:eq('+loadNext+')'; + imgNext.appendTo(slideNext).wrap('<a ' + imageLink + linkTarget + '></a>').parent().parent().addClass('image-loading'); + + imgNext.load(function(){ + $(this).data('origWidth', $(this).width()).data('origHeight', $(this).height()); + base.resizeNow(); // Resize background image + }); // End Load + } + /*-----End load initial images-----*/ + + // Hide elements to be faded in + base.$el.css('visibility','hidden'); + $('.load-item').hide(); + + }; + + + /* Launch Supersized + ----------------------------*/ + base.launch = function(){ + + base.$el.css('visibility','visible'); + $('#supersized-loader').remove(); //Hide loading animation + + // Call theme function for before slide transition + if( typeof theme != 'undefined' && typeof theme.beforeAnimation == "function" ) theme.beforeAnimation('next'); + $('.load-item').show(); + + // Keyboard Navigation + if (base.options.keyboard_nav){ + $(document.documentElement).keyup(function (event) { + + if(vars.in_animation) return false; // Abort if currently animating + + // Left Arrow or Down Arrow + if ((event.keyCode == 37) || (event.keyCode == 40)) { + clearInterval(vars.slideshow_interval); // Stop slideshow, prevent buildup + base.prevSlide(); + + // Right Arrow or Up Arrow + } else if ((event.keyCode == 39) || (event.keyCode == 38)) { + clearInterval(vars.slideshow_interval); // Stop slideshow, prevent buildup + base.nextSlide(); + + // Spacebar + } else if (event.keyCode == 32 && !vars.hover_pause) { + clearInterval(vars.slideshow_interval); // Stop slideshow, prevent buildup + base.playToggle(); + } + + }); + } + + // Pause when hover on image + if (base.options.slideshow && base.options.pause_hover){ + $(base.el).hover(function() { + if(vars.in_animation) return false; // Abort if currently animating + vars.hover_pause = true; // Mark slideshow paused from hover + if(!vars.is_paused){ + vars.hover_pause = 'resume'; // It needs to resume afterwards + base.playToggle(); + } + }, function() { + if(vars.hover_pause == 'resume'){ + base.playToggle(); + vars.hover_pause = false; + } + }); + } + + if (base.options.slide_links){ + // Slide marker clicked + $(vars.slide_list+'> li').click(function(){ + + index = $(vars.slide_list+'> li').index(this); + targetSlide = index + 1; + + base.goTo(targetSlide); + return false; + + }); + } + + // Thumb marker clicked + if (base.options.thumb_links){ + $(vars.thumb_list+'> li').click(function(){ + + index = $(vars.thumb_list+'> li').index(this); + targetSlide = index + 1; + + api.goTo(targetSlide); + return false; + + }); + } + + // Start slideshow if enabled + if (base.options.slideshow && base.options.slides.length > 1){ + + // Start slideshow if autoplay enabled + if (base.options.autoplay && base.options.slides.length > 1){ + vars.slideshow_interval = setInterval(base.nextSlide, base.options.slide_interval); // Initiate slide interval + }else{ + vars.is_paused = true; // Mark as paused + } + + //Prevent navigation items from being dragged + $('.load-item img').bind("contextmenu mousedown",function(){ + return false; + }); + + } + + // Adjust image when browser is resized + $(window).resize(function(){ + base.resizeNow(); + }); + + }; + + + /* Resize Images + ----------------------------*/ + base.resizeNow = function(){ + + return base.$el.each(function() { + // Resize each image seperately + $('img', base.el).each(function(){ + + thisSlide = $(this); + var ratio = (thisSlide.data('origHeight')/thisSlide.data('origWidth')).toFixed(2); // Define image ratio + + // Gather browser size + var browserwidth = base.$el.width(), + browserheight = base.$el.height(), + offset; + + /*-----Resize Image-----*/ + if (base.options.fit_always){ // Fit always is enabled + if ((browserheight/browserwidth) > ratio){ + resizeWidth(); + } else { + resizeHeight(); + } + }else{ // Normal Resize + if ((browserheight <= base.options.min_height) && (browserwidth <= base.options.min_width)){ // If window smaller than minimum width and height + + if ((browserheight/browserwidth) > ratio){ + base.options.fit_landscape && ratio < 1 ? resizeWidth(true) : resizeHeight(true); // If landscapes are set to fit + } else { + base.options.fit_portrait && ratio >= 1 ? resizeHeight(true) : resizeWidth(true); // If portraits are set to fit + } + + } else if (browserwidth <= base.options.min_width){ // If window only smaller than minimum width + + if ((browserheight/browserwidth) > ratio){ + base.options.fit_landscape && ratio < 1 ? resizeWidth(true) : resizeHeight(); // If landscapes are set to fit + } else { + base.options.fit_portrait && ratio >= 1 ? resizeHeight() : resizeWidth(true); // If portraits are set to fit + } + + } else if (browserheight <= base.options.min_height){ // If window only smaller than minimum height + + if ((browserheight/browserwidth) > ratio){ + base.options.fit_landscape && ratio < 1 ? resizeWidth() : resizeHeight(true); // If landscapes are set to fit + } else { + base.options.fit_portrait && ratio >= 1 ? resizeHeight(true) : resizeWidth(); // If portraits are set to fit + } + + } else { // If larger than minimums + + if ((browserheight/browserwidth) > ratio){ + base.options.fit_landscape && ratio < 1 ? resizeWidth() : resizeHeight(); // If landscapes are set to fit + } else { + base.options.fit_portrait && ratio >= 1 ? resizeHeight() : resizeWidth(); // If portraits are set to fit + } + + } + } + /*-----End Image Resize-----*/ + + + /*-----Resize Functions-----*/ + + function resizeWidth(minimum){ + if (minimum){ // If minimum height needs to be considered + if(thisSlide.width() < browserwidth || thisSlide.width() < base.options.min_width ){ + if (thisSlide.width() * ratio >= base.options.min_height){ + thisSlide.width(base.options.min_width); + thisSlide.height(thisSlide.width() * ratio); + }else{ + resizeHeight(); + } + } + }else{ + if (base.options.min_height >= browserheight && !base.options.fit_landscape){ // If minimum height needs to be considered + if (browserwidth * ratio >= base.options.min_height || (browserwidth * ratio >= base.options.min_height && ratio <= 1)){ // If resizing would push below minimum height or image is a landscape + thisSlide.width(browserwidth); + thisSlide.height(browserwidth * ratio); + } else if (ratio > 1){ // Else the image is portrait + thisSlide.height(base.options.min_height); + thisSlide.width(thisSlide.height() / ratio); + } else if (thisSlide.width() < browserwidth) { + thisSlide.width(browserwidth); + thisSlide.height(thisSlide.width() * ratio); + } + }else{ // Otherwise, resize as normal + thisSlide.width(browserwidth); + thisSlide.height(browserwidth * ratio); + } + } + }; + + function resizeHeight(minimum){ + if (minimum){ // If minimum height needs to be considered + if(thisSlide.height() < browserheight){ + if (thisSlide.height() / ratio >= base.options.min_width){ + thisSlide.height(base.options.min_height); + thisSlide.width(thisSlide.height() / ratio); + }else{ + resizeWidth(true); + } + } + }else{ // Otherwise, resized as normal + if (base.options.min_width >= browserwidth){ // If minimum width needs to be considered + if (browserheight / ratio >= base.options.min_width || ratio > 1){ // If resizing would push below minimum width or image is a portrait + thisSlide.height(browserheight); + thisSlide.width(browserheight / ratio); + } else if (ratio <= 1){ // Else the image is landscape + thisSlide.width(base.options.min_width); + thisSlide.height(thisSlide.width() * ratio); + } + }else{ // Otherwise, resize as normal + thisSlide.height(browserheight); + thisSlide.width(browserheight / ratio); + } + } + }; + + /*-----End Resize Functions-----*/ + + if (thisSlide.parents('li').hasClass('image-loading')){ + $('.image-loading').removeClass('image-loading'); + } + + // Horizontally Center + if (base.options.horizontal_center){ + $(this).css('left', (browserwidth - $(this).width())/2); + } + + // Vertically Center + if (base.options.vertical_center){ + $(this).css('top', (browserheight - $(this).height())/2); + } + + }); + + // Basic image drag and right click protection + if (base.options.image_protect){ + + $('img', base.el).bind("contextmenu mousedown",function(){ + return false; + }); + + } + + return false; + + }); + + }; + + + /* Next Slide + ----------------------------*/ + base.nextSlide = function(){ + + if(vars.in_animation || !api.options.slideshow) return false; // Abort if currently animating + else vars.in_animation = true; // Otherwise set animation marker + + clearInterval(vars.slideshow_interval); // Stop slideshow + + var slides = base.options.slides, // Pull in slides array + liveslide = base.$el.find('.activeslide'); // Find active slide + $('.prevslide').removeClass('prevslide'); + liveslide.removeClass('activeslide').addClass('prevslide'); // Remove active class & update previous slide + + // Get the slide number of new slide + vars.current_slide + 1 == base.options.slides.length ? vars.current_slide = 0 : vars.current_slide++; + + var nextslide = $(base.el+' li:eq('+vars.current_slide+')'), + prevslide = base.$el.find('.prevslide'); + + // If hybrid mode is on drop quality for transition + if (base.options.performance == 1) base.$el.removeClass('quality').addClass('speed'); + + + /*-----Load Image-----*/ + + loadSlide = false; + + vars.current_slide == base.options.slides.length - 1 ? loadSlide = 0 : loadSlide = vars.current_slide + 1; // Determine next slide + + var targetList = base.el+' li:eq('+loadSlide+')'; + if (!$(targetList).html()){ + + // If links should open in new window + var linkTarget = base.options.new_window ? ' target="_blank"' : ''; + + imageLink = (base.options.slides[loadSlide].url) ? "href='" + base.options.slides[loadSlide].url + "'" : ""; // If link exists, build it + var img = $('<img src="'+base.options.slides[loadSlide].image+'"/>'); + + img.appendTo(targetList).wrap('<a ' + imageLink + linkTarget + '></a>').parent().parent().addClass('image-loading').css('visibility','hidden'); + + img.load(function(){ + base._origDim($(this)); + base.resizeNow(); + }); // End Load + }; + + // Update thumbnails (if enabled) + if (base.options.thumbnail_navigation == 1){ + + // Load previous thumbnail + vars.current_slide - 1 < 0 ? prevThumb = base.options.slides.length - 1 : prevThumb = vars.current_slide - 1; + $(vars.prev_thumb).html($("<img/>").attr("src", base.options.slides[prevThumb].image)); + + // Load next thumbnail + nextThumb = loadSlide; + $(vars.next_thumb).html($("<img/>").attr("src", base.options.slides[nextThumb].image)); + + } + + + + /*-----End Load Image-----*/ + + + // Call theme function for before slide transition + if( typeof theme != 'undefined' && typeof theme.beforeAnimation == "function" ) theme.beforeAnimation('next'); + + //Update slide markers + if (base.options.slide_links){ + $('.current-slide').removeClass('current-slide'); + $(vars.slide_list +'> li' ).eq(vars.current_slide).addClass('current-slide'); + } + + nextslide.css('visibility','hidden').addClass('activeslide'); // Update active slide + + switch(base.options.transition){ + case 0: case 'none': // No transition + nextslide.css('visibility','visible'); vars.in_animation = false; base.afterAnimation(); + break; + case 1: case 'fade': // Fade + nextslide.animate({opacity : 0},0).css('visibility','visible').animate({opacity : 1, avoidTransforms : false}, base.options.transition_speed, function(){ base.afterAnimation(); }); + break; + case 2: case 'slideTop': // Slide Top + nextslide.animate({top : -base.$el.height()}, 0 ).css('visibility','visible').animate({ top:0, avoidTransforms : false }, base.options.transition_speed, function(){ base.afterAnimation(); }); + break; + case 3: case 'slideRight': // Slide Right + nextslide.animate({left : base.$el.width()}, 0 ).css('visibility','visible').animate({ left:0, avoidTransforms : false }, base.options.transition_speed, function(){ base.afterAnimation(); }); + break; + case 4: case 'slideBottom': // Slide Bottom + nextslide.animate({top : base.$el.height()}, 0 ).css('visibility','visible').animate({ top:0, avoidTransforms : false }, base.options.transition_speed, function(){ base.afterAnimation(); }); + break; + case 5: case 'slideLeft': // Slide Left + nextslide.animate({left : -base.$el.width()}, 0 ).css('visibility','visible').animate({ left:0, avoidTransforms : false }, base.options.transition_speed, function(){ base.afterAnimation(); }); + break; + case 6: case 'carouselRight': // Carousel Right + nextslide.animate({left : base.$el.width()}, 0 ).css('visibility','visible').animate({ left:0, avoidTransforms : false }, base.options.transition_speed, function(){ base.afterAnimation(); }); + liveslide.animate({ left: -base.$el.width(), avoidTransforms : false }, base.options.transition_speed ); + break; + case 7: case 'carouselLeft': // Carousel Left + nextslide.animate({left : -base.$el.width()}, 0 ).css('visibility','visible').animate({ left:0, avoidTransforms : false }, base.options.transition_speed, function(){ base.afterAnimation(); }); + liveslide.animate({ left: base.$el.width(), avoidTransforms : false }, base.options.transition_speed ); + break; + } + return false; + }; + + + /* Previous Slide + ----------------------------*/ + base.prevSlide = function(){ + + if(vars.in_animation || !api.options.slideshow) return false; // Abort if currently animating + else vars.in_animation = true; // Otherwise set animation marker + + clearInterval(vars.slideshow_interval); // Stop slideshow + + var slides = base.options.slides, // Pull in slides array + liveslide = base.$el.find('.activeslide'); // Find active slide + $('.prevslide').removeClass('prevslide'); + liveslide.removeClass('activeslide').addClass('prevslide'); // Remove active class & update previous slide + + // Get current slide number + vars.current_slide == 0 ? vars.current_slide = base.options.slides.length - 1 : vars.current_slide-- ; + + var nextslide = $(base.el+' li:eq('+vars.current_slide+')'), + prevslide = base.$el.find('.prevslide'); + + // If hybrid mode is on drop quality for transition + if (base.options.performance == 1) base.$el.removeClass('quality').addClass('speed'); + + + /*-----Load Image-----*/ + + loadSlide = vars.current_slide; + + var targetList = base.el+' li:eq('+loadSlide+')'; + if (!$(targetList).html()){ + // If links should open in new window + var linkTarget = base.options.new_window ? ' target="_blank"' : ''; + imageLink = (base.options.slides[loadSlide].url) ? "href='" + base.options.slides[loadSlide].url + "'" : ""; // If link exists, build it + var img = $('<img src="'+base.options.slides[loadSlide].image+'"/>'); + + img.appendTo(targetList).wrap('<a ' + imageLink + linkTarget + '></a>').parent().parent().addClass('image-loading').css('visibility','hidden'); + + img.load(function(){ + base._origDim($(this)); + base.resizeNow(); + }); // End Load + }; + + // Update thumbnails (if enabled) + if (base.options.thumbnail_navigation == 1){ + + // Load previous thumbnail + //prevThumb = loadSlide; + loadSlide == 0 ? prevThumb = base.options.slides.length - 1 : prevThumb = loadSlide - 1; + $(vars.prev_thumb).html($("<img/>").attr("src", base.options.slides[prevThumb].image)); + + // Load next thumbnail + vars.current_slide == base.options.slides.length - 1 ? nextThumb = 0 : nextThumb = vars.current_slide + 1; + $(vars.next_thumb).html($("<img/>").attr("src", base.options.slides[nextThumb].image)); + } + + /*-----End Load Image-----*/ + + + // Call theme function for before slide transition + if( typeof theme != 'undefined' && typeof theme.beforeAnimation == "function" ) theme.beforeAnimation('prev'); + + //Update slide markers + if (base.options.slide_links){ + $('.current-slide').removeClass('current-slide'); + $(vars.slide_list +'> li' ).eq(vars.current_slide).addClass('current-slide'); + } + + nextslide.css('visibility','hidden').addClass('activeslide'); // Update active slide + + switch(base.options.transition){ + case 0: case 'none': // No transition + nextslide.css('visibility','visible'); vars.in_animation = false; base.afterAnimation(); + break; + case 1: case 'fade': // Fade + nextslide.animate({opacity : 0},0).css('visibility','visible').animate({opacity : 1, avoidTransforms : false}, base.options.transition_speed, function(){ base.afterAnimation(); }); + break; + case 2: case 'slideTop': // Slide Top (reverse) + nextslide.animate({top : base.$el.height()}, 0 ).css('visibility','visible').animate({ top:0, avoidTransforms : false }, base.options.transition_speed, function(){ base.afterAnimation(); }); + break; + case 3: case 'slideRight': // Slide Right (reverse) + nextslide.animate({left : -base.$el.width()}, 0 ).css('visibility','visible').animate({ left:0, avoidTransforms : false }, base.options.transition_speed, function(){ base.afterAnimation(); }); + break; + case 4: case 'slideBottom': // Slide Bottom (reverse) + nextslide.animate({top : -base.$el.height()}, 0 ).css('visibility','visible').animate({ top:0, avoidTransforms : false }, base.options.transition_speed, function(){ base.afterAnimation(); }); + break; + case 5: case 'slideLeft': // Slide Left (reverse) + nextslide.animate({left : base.$el.width()}, 0 ).css('visibility','visible').animate({ left:0, avoidTransforms : false }, base.options.transition_speed, function(){ base.afterAnimation(); }); + break; + case 6: case 'carouselRight': // Carousel Right (reverse) + nextslide.animate({left : -base.$el.width()}, 0 ).css('visibility','visible').animate({ left:0, avoidTransforms : false }, base.options.transition_speed, function(){ base.afterAnimation(); }); + liveslide.animate({left : 0}, 0 ).animate({ left: base.$el.width(), avoidTransforms : false}, base.options.transition_speed ); + break; + case 7: case 'carouselLeft': // Carousel Left (reverse) + nextslide.animate({left : base.$el.width()}, 0 ).css('visibility','visible').animate({ left:0, avoidTransforms : false }, base.options.transition_speed, function(){ base.afterAnimation(); }); + liveslide.animate({left : 0}, 0 ).animate({ left: -base.$el.width(), avoidTransforms : false }, base.options.transition_speed ); + break; + } + return false; + }; + + + /* Play/Pause Toggle + ----------------------------*/ + base.playToggle = function(){ + + if (vars.in_animation || !api.options.slideshow) return false; // Abort if currently animating + + if (vars.is_paused){ + + vars.is_paused = false; + + // Call theme function for play + if( typeof theme != 'undefined' && typeof theme.playToggle == "function" ) theme.playToggle('play'); + + // Resume slideshow + vars.slideshow_interval = setInterval(base.nextSlide, base.options.slide_interval); + + }else{ + + vars.is_paused = true; + + // Call theme function for pause + if( typeof theme != 'undefined' && typeof theme.playToggle == "function" ) theme.playToggle('pause'); + + // Stop slideshow + clearInterval(vars.slideshow_interval); + + } + + return false; + + }; + + + /* Go to specific slide + ----------------------------*/ + base.goTo = function(targetSlide){ + if (vars.in_animation || !api.options.slideshow) return false; // Abort if currently animating + + var totalSlides = base.options.slides.length; + + // If target outside range + if(targetSlide < 0){ + targetSlide = totalSlides; + }else if(targetSlide > totalSlides){ + targetSlide = 1; + } + targetSlide = totalSlides - targetSlide + 1; + + clearInterval(vars.slideshow_interval); // Stop slideshow, prevent buildup + + // Call theme function for goTo trigger + if (typeof theme != 'undefined' && typeof theme.goTo == "function" ) theme.goTo(); + + if (vars.current_slide == totalSlides - targetSlide){ + if(!(vars.is_paused)){ + vars.slideshow_interval = setInterval(base.nextSlide, base.options.slide_interval); + } + return false; + } + + // If ahead of current position + if(totalSlides - targetSlide > vars.current_slide ){ + + // Adjust for new next slide + vars.current_slide = totalSlides-targetSlide-1; + vars.update_images = 'next'; + base._placeSlide(vars.update_images); + + //Otherwise it's before current position + }else if(totalSlides - targetSlide < vars.current_slide){ + + // Adjust for new prev slide + vars.current_slide = totalSlides-targetSlide+1; + vars.update_images = 'prev'; + base._placeSlide(vars.update_images); + + } + + // set active markers + if (base.options.slide_links){ + $(vars.slide_list +'> .current-slide').removeClass('current-slide'); + $(vars.slide_list +'> li').eq((totalSlides-targetSlide)).addClass('current-slide'); + } + + if (base.options.thumb_links){ + $(vars.thumb_list +'> .current-thumb').removeClass('current-thumb'); + $(vars.thumb_list +'> li').eq((totalSlides-targetSlide)).addClass('current-thumb'); + } + + }; + + + /* Place Slide + ----------------------------*/ + base._placeSlide = function(place){ + + // If links should open in new window + var linkTarget = base.options.new_window ? ' target="_blank"' : ''; + + loadSlide = false; + + if (place == 'next'){ + + vars.current_slide == base.options.slides.length - 1 ? loadSlide = 0 : loadSlide = vars.current_slide + 1; // Determine next slide + + var targetList = base.el+' li:eq('+loadSlide+')'; + + if (!$(targetList).html()){ + // If links should open in new window + var linkTarget = base.options.new_window ? ' target="_blank"' : ''; + + imageLink = (base.options.slides[loadSlide].url) ? "href='" + base.options.slides[loadSlide].url + "'" : ""; // If link exists, build it + var img = $('<img src="'+base.options.slides[loadSlide].image+'"/>'); + + img.appendTo(targetList).wrap('<a ' + imageLink + linkTarget + '></a>').parent().parent().addClass('image-loading').css('visibility','hidden'); + + img.load(function(){ + base._origDim($(this)); + base.resizeNow(); + }); // End Load + }; + + base.nextSlide(); + + }else if (place == 'prev'){ + + vars.current_slide - 1 < 0 ? loadSlide = base.options.slides.length - 1 : loadSlide = vars.current_slide - 1; // Determine next slide + + var targetList = base.el+' li:eq('+loadSlide+')'; + + if (!$(targetList).html()){ + // If links should open in new window + var linkTarget = base.options.new_window ? ' target="_blank"' : ''; + + imageLink = (base.options.slides[loadSlide].url) ? "href='" + base.options.slides[loadSlide].url + "'" : ""; // If link exists, build it + var img = $('<img src="'+base.options.slides[loadSlide].image+'"/>'); + + img.appendTo(targetList).wrap('<a ' + imageLink + linkTarget + '></a>').parent().parent().addClass('image-loading').css('visibility','hidden'); + + img.load(function(){ + base._origDim($(this)); + base.resizeNow(); + }); // End Load + }; + base.prevSlide(); + } + + }; + + + /* Get Original Dimensions + ----------------------------*/ + base._origDim = function(targetSlide){ + targetSlide.data('origWidth', targetSlide.width()).data('origHeight', targetSlide.height()); + }; + + + /* After Slide Animation + ----------------------------*/ + base.afterAnimation = function(){ + + // If hybrid mode is on swap back to higher image quality + if (base.options.performance == 1){ + base.$el.removeClass('speed').addClass('quality'); + } + + // Update previous slide + if (vars.update_images){ + vars.current_slide - 1 < 0 ? setPrev = base.options.slides.length - 1 : setPrev = vars.current_slide-1; + vars.update_images = false; + $('.prevslide').removeClass('prevslide'); + $(base.el+' li:eq('+setPrev+')').addClass('prevslide'); + } + + vars.in_animation = false; + + // Resume slideshow + if (!vars.is_paused && base.options.slideshow){ + vars.slideshow_interval = setInterval(base.nextSlide, base.options.slide_interval); + if (base.options.stop_loop && vars.current_slide == base.options.slides.length - 1 ) base.playToggle(); + } + + // Call theme function for after slide transition + if (typeof theme != 'undefined' && typeof theme.afterAnimation == "function" ) theme.afterAnimation(); + + return false; + + }; + + base.getField = function(field){ + return base.options.slides[vars.current_slide][field]; + }; + + // Make it go! + base.init(); + }; + + + /* Global Variables + ----------------------------*/ + $.supersized.vars = { + + // Elements + thumb_tray : '#thumb-tray', // Thumbnail tray + thumb_list : '#thumb-list', // Thumbnail list + slide_list : '#slide-list', // Slide link list + + // Internal variables + current_slide : 0, // Current slide number + in_animation : false, // Prevents animations from stacking + is_paused : false, // Tracks paused on/off + hover_pause : false, // If slideshow is paused from hover + slideshow_interval : false, // Stores slideshow timer + update_images : false, // Trigger to update images after slide jump + options : {} // Stores assembled options list + + }; + + + /* Default Options + ----------------------------*/ + $.supersized.defaultOptions = { + + // Functionality + slideshow : 1, // Slideshow on/off + autoplay : 1, // Slideshow starts playing automatically + start_slide : 1, // Start slide (0 is random) + stop_loop : 0, // Stops slideshow on last slide + random : 0, // Randomize slide order (Ignores start slide) + slide_interval : 5000, // Length between transitions + transition : 1, // 0-None, 1-Fade, 2-Slide Top, 3-Slide Right, 4-Slide Bottom, 5-Slide Left, 6-Carousel Right, 7-Carousel Left + transition_speed : 750, // Speed of transition + new_window : 1, // Image links open in new window/tab + pause_hover : 0, // Pause slideshow on hover + keyboard_nav : 1, // Keyboard navigation on/off + performance : 1, // 0-Normal, 1-Hybrid speed/quality, 2-Optimizes image quality, 3-Optimizes transition speed // (Only works for Firefox/IE, not Webkit) + image_protect : 1, // Disables image dragging and right click with Javascript + + // Size & Position + fit_always : 0, // Image will never exceed browser width or height (Ignores min. dimensions) + fit_landscape : 0, // Landscape images will not exceed browser width + fit_portrait : 1, // Portrait images will not exceed browser height + min_width : 0, // Min width allowed (in pixels) + min_height : 0, // Min height allowed (in pixels) + horizontal_center : 1, // Horizontally center background + vertical_center : 1, // Vertically center background + + + // Components + slide_links : 1, // Individual links for each slide (Options: false, 'num', 'name', 'blank') + thumb_links : 1, // Individual thumb links for each slide + thumbnail_navigation : 0 // Thumbnail navigation + + }; + + $.fn.supersized = function(options){ + return this.each(function(){ + (new $.supersized(options)); + }); + }; + +})(jQuery); + diff --git a/apps/gallery/js/supersized.3.2.7.min.js b/apps/gallery/js/supersized.3.2.7.min.js new file mode 100644 index 00000000000..b9cea9cee1c --- /dev/null +++ b/apps/gallery/js/supersized.3.2.7.min.js @@ -0,0 +1,13 @@ +/* + + Supersized - Fullscreen Slideshow jQuery Plugin + Version : 3.2.7 + Site : www.buildinternet.com/project/supersized + + Author : Sam Dunn + Company : One Mighty Roar (www.onemightyroar.com) + License : MIT License / GPL License + +*/ + +(function(a){a(document).ready(function(){a("body").append('<div id="supersized-loader"></div><ul id="supersized"></ul>')});a.supersized=function(b){var c="#supersized",d=this;d.$el=a(c);d.el=c;vars=a.supersized.vars;d.$el.data("supersized",d);api=d.$el.data("supersized");d.init=function(){a.supersized.vars=a.extend(a.supersized.vars,a.supersized.themeVars);a.supersized.vars.options=a.extend({},a.supersized.defaultOptions,a.supersized.themeOptions,b);d.options=a.supersized.vars.options;d._build()};d._build=function(){var g=0,e="",j="",h,f="",i;while(g<=d.options.slides.length-1){switch(d.options.slide_links){case"num":h=g;break;case"name":h=d.options.slides[g].title;break;case"blank":h="";break}e=e+'<li class="slide-'+g+'"></li>';if(g==d.options.start_slide-1){if(d.options.slide_links){j=j+'<li class="slide-link-'+g+' current-slide"><a>'+h+"</a></li>"}if(d.options.thumb_links){d.options.slides[g].thumb?i=d.options.slides[g].thumb:i=d.options.slides[g].image;f=f+'<li class="thumb'+g+' current-thumb"><img src="'+i+'"/></li>'}}else{if(d.options.slide_links){j=j+'<li class="slide-link-'+g+'" ><a>'+h+"</a></li>"}if(d.options.thumb_links){d.options.slides[g].thumb?i=d.options.slides[g].thumb:i=d.options.slides[g].image;f=f+'<li class="thumb'+g+'"><img src="'+i+'"/></li>'}}g++}if(d.options.slide_links){a(vars.slide_list).html(j)}if(d.options.thumb_links&&vars.thumb_tray.length){a(vars.thumb_tray).append('<ul id="'+vars.thumb_list.replace("#","")+'">'+f+"</ul>")}a(d.el).append(e);if(d.options.thumbnail_navigation){vars.current_slide-1<0?prevThumb=d.options.slides.length-1:prevThumb=vars.current_slide-1;a(vars.prev_thumb).show().html(a("<img/>").attr("src",d.options.slides[prevThumb].image));vars.current_slide==d.options.slides.length-1?nextThumb=0:nextThumb=vars.current_slide+1;a(vars.next_thumb).show().html(a("<img/>").attr("src",d.options.slides[nextThumb].image))}d._start()};d._start=function(){if(d.options.start_slide){vars.current_slide=d.options.start_slide-1}else{vars.current_slide=Math.floor(Math.random()*d.options.slides.length)}var o=d.options.new_window?' target="_blank"':"";if(d.options.performance==3){d.$el.addClass("speed")}else{if((d.options.performance==1)||(d.options.performance==2)){d.$el.addClass("quality")}}if(d.options.random){arr=d.options.slides;for(var h,m,k=arr.length;k;h=parseInt(Math.random()*k),m=arr[--k],arr[k]=arr[h],arr[h]=m){}d.options.slides=arr}if(d.options.slides.length>1){if(d.options.slides.length>2){vars.current_slide-1<0?loadPrev=d.options.slides.length-1:loadPrev=vars.current_slide-1;var g=(d.options.slides[loadPrev].url)?"href='"+d.options.slides[loadPrev].url+"'":"";var q=a('<img src="'+d.options.slides[loadPrev].image+'"/>');var n=d.el+" li:eq("+loadPrev+")";q.appendTo(n).wrap("<a "+g+o+"></a>").parent().parent().addClass("image-loading prevslide");q.load(function(){a(this).data("origWidth",a(this).width()).data("origHeight",a(this).height());d.resizeNow()})}}else{d.options.slideshow=0}g=(api.getField("url"))?"href='"+api.getField("url")+"'":"";var l=a('<img src="'+api.getField("image")+'"/>');var f=d.el+" li:eq("+vars.current_slide+")";l.appendTo(f).wrap("<a "+g+o+"></a>").parent().parent().addClass("image-loading activeslide");l.load(function(){d._origDim(a(this));d.resizeNow();d.launch();if(typeof theme!="undefined"&&typeof theme._init=="function"){theme._init()}});if(d.options.slides.length>1){vars.current_slide==d.options.slides.length-1?loadNext=0:loadNext=vars.current_slide+1;g=(d.options.slides[loadNext].url)?"href='"+d.options.slides[loadNext].url+"'":"";var e=a('<img src="'+d.options.slides[loadNext].image+'"/>');var p=d.el+" li:eq("+loadNext+")";e.appendTo(p).wrap("<a "+g+o+"></a>").parent().parent().addClass("image-loading");e.load(function(){a(this).data("origWidth",a(this).width()).data("origHeight",a(this).height());d.resizeNow()})}d.$el.css("visibility","hidden");a(".load-item").hide()};d.launch=function(){d.$el.css("visibility","visible");a("#supersized-loader").remove();if(typeof theme!="undefined"&&typeof theme.beforeAnimation=="function"){theme.beforeAnimation("next")}a(".load-item").show();if(d.options.keyboard_nav){a(document.documentElement).keyup(function(e){if(vars.in_animation){return false}if((e.keyCode==37)||(e.keyCode==40)){clearInterval(vars.slideshow_interval);d.prevSlide()}else{if((e.keyCode==39)||(e.keyCode==38)){clearInterval(vars.slideshow_interval);d.nextSlide()}else{if(e.keyCode==32&&!vars.hover_pause){clearInterval(vars.slideshow_interval);d.playToggle()}}}})}if(d.options.slideshow&&d.options.pause_hover){a(d.el).hover(function(){if(vars.in_animation){return false}vars.hover_pause=true;if(!vars.is_paused){vars.hover_pause="resume";d.playToggle()}},function(){if(vars.hover_pause=="resume"){d.playToggle();vars.hover_pause=false}})}if(d.options.slide_links){a(vars.slide_list+"> li").click(function(){index=a(vars.slide_list+"> li").index(this);targetSlide=index+1;d.goTo(targetSlide);return false})}if(d.options.thumb_links){a(vars.thumb_list+"> li").click(function(){index=a(vars.thumb_list+"> li").index(this);targetSlide=index+1;api.goTo(targetSlide);return false})}if(d.options.slideshow&&d.options.slides.length>1){if(d.options.autoplay&&d.options.slides.length>1){vars.slideshow_interval=setInterval(d.nextSlide,d.options.slide_interval)}else{vars.is_paused=true}a(".load-item img").bind("contextmenu mousedown",function(){return false})}a(window).resize(function(){d.resizeNow()})};d.resizeNow=function(){return d.$el.each(function(){a("img",d.el).each(function(){thisSlide=a(this);var f=(thisSlide.data("origHeight")/thisSlide.data("origWidth")).toFixed(2);var e=d.$el.width(),h=d.$el.height(),i;if(d.options.fit_always){if((h/e)>f){g()}else{j()}}else{if((h<=d.options.min_height)&&(e<=d.options.min_width)){if((h/e)>f){d.options.fit_landscape&&f<1?g(true):j(true)}else{d.options.fit_portrait&&f>=1?j(true):g(true)}}else{if(e<=d.options.min_width){if((h/e)>f){d.options.fit_landscape&&f<1?g(true):j()}else{d.options.fit_portrait&&f>=1?j():g(true)}}else{if(h<=d.options.min_height){if((h/e)>f){d.options.fit_landscape&&f<1?g():j(true)}else{d.options.fit_portrait&&f>=1?j(true):g()}}else{if((h/e)>f){d.options.fit_landscape&&f<1?g():j()}else{d.options.fit_portrait&&f>=1?j():g()}}}}}function g(k){if(k){if(thisSlide.width()<e||thisSlide.width()<d.options.min_width){if(thisSlide.width()*f>=d.options.min_height){thisSlide.width(d.options.min_width);thisSlide.height(thisSlide.width()*f)}else{j()}}}else{if(d.options.min_height>=h&&!d.options.fit_landscape){if(e*f>=d.options.min_height||(e*f>=d.options.min_height&&f<=1)){thisSlide.width(e);thisSlide.height(e*f)}else{if(f>1){thisSlide.height(d.options.min_height);thisSlide.width(thisSlide.height()/f)}else{if(thisSlide.width()<e){thisSlide.width(e);thisSlide.height(thisSlide.width()*f)}}}}else{thisSlide.width(e);thisSlide.height(e*f)}}}function j(k){if(k){if(thisSlide.height()<h){if(thisSlide.height()/f>=d.options.min_width){thisSlide.height(d.options.min_height);thisSlide.width(thisSlide.height()/f)}else{g(true)}}}else{if(d.options.min_width>=e){if(h/f>=d.options.min_width||f>1){thisSlide.height(h);thisSlide.width(h/f)}else{if(f<=1){thisSlide.width(d.options.min_width);thisSlide.height(thisSlide.width()*f)}}}else{thisSlide.height(h);thisSlide.width(h/f)}}}if(thisSlide.parents("li").hasClass("image-loading")){a(".image-loading").removeClass("image-loading")}if(d.options.horizontal_center){a(this).css("left",(e-a(this).width())/2)}if(d.options.vertical_center){a(this).css("top",(h-a(this).height())/2)}});if(d.options.image_protect){a("img",d.el).bind("contextmenu mousedown",function(){return false})}return false})};d.nextSlide=function(){if(vars.in_animation||!api.options.slideshow){return false}else{vars.in_animation=true}clearInterval(vars.slideshow_interval);var h=d.options.slides,e=d.$el.find(".activeslide");a(".prevslide").removeClass("prevslide");e.removeClass("activeslide").addClass("prevslide");vars.current_slide+1==d.options.slides.length?vars.current_slide=0:vars.current_slide++;var g=a(d.el+" li:eq("+vars.current_slide+")"),i=d.$el.find(".prevslide");if(d.options.performance==1){d.$el.removeClass("quality").addClass("speed")}loadSlide=false;vars.current_slide==d.options.slides.length-1?loadSlide=0:loadSlide=vars.current_slide+1;var k=d.el+" li:eq("+loadSlide+")";if(!a(k).html()){var j=d.options.new_window?' target="_blank"':"";imageLink=(d.options.slides[loadSlide].url)?"href='"+d.options.slides[loadSlide].url+"'":"";var f=a('<img src="'+d.options.slides[loadSlide].image+'"/>');f.appendTo(k).wrap("<a "+imageLink+j+"></a>").parent().parent().addClass("image-loading").css("visibility","hidden");f.load(function(){d._origDim(a(this));d.resizeNow()})}if(d.options.thumbnail_navigation==1){vars.current_slide-1<0?prevThumb=d.options.slides.length-1:prevThumb=vars.current_slide-1;a(vars.prev_thumb).html(a("<img/>").attr("src",d.options.slides[prevThumb].image));nextThumb=loadSlide;a(vars.next_thumb).html(a("<img/>").attr("src",d.options.slides[nextThumb].image))}if(typeof theme!="undefined"&&typeof theme.beforeAnimation=="function"){theme.beforeAnimation("next")}if(d.options.slide_links){a(".current-slide").removeClass("current-slide");a(vars.slide_list+"> li").eq(vars.current_slide).addClass("current-slide")}g.css("visibility","hidden").addClass("activeslide");switch(d.options.transition){case 0:case"none":g.css("visibility","visible");vars.in_animation=false;d.afterAnimation();break;case 1:case"fade":g.animate({opacity:0},0).css("visibility","visible").animate({opacity:1,avoidTransforms:false},d.options.transition_speed,function(){d.afterAnimation()});break;case 2:case"slideTop":g.animate({top:-d.$el.height()},0).css("visibility","visible").animate({top:0,avoidTransforms:false},d.options.transition_speed,function(){d.afterAnimation()});break;case 3:case"slideRight":g.animate({left:d.$el.width()},0).css("visibility","visible").animate({left:0,avoidTransforms:false},d.options.transition_speed,function(){d.afterAnimation()});break;case 4:case"slideBottom":g.animate({top:d.$el.height()},0).css("visibility","visible").animate({top:0,avoidTransforms:false},d.options.transition_speed,function(){d.afterAnimation()});break;case 5:case"slideLeft":g.animate({left:-d.$el.width()},0).css("visibility","visible").animate({left:0,avoidTransforms:false},d.options.transition_speed,function(){d.afterAnimation()});break;case 6:case"carouselRight":g.animate({left:d.$el.width()},0).css("visibility","visible").animate({left:0,avoidTransforms:false},d.options.transition_speed,function(){d.afterAnimation()});e.animate({left:-d.$el.width(),avoidTransforms:false},d.options.transition_speed);break;case 7:case"carouselLeft":g.animate({left:-d.$el.width()},0).css("visibility","visible").animate({left:0,avoidTransforms:false},d.options.transition_speed,function(){d.afterAnimation()});e.animate({left:d.$el.width(),avoidTransforms:false},d.options.transition_speed);break}return false};d.prevSlide=function(){if(vars.in_animation||!api.options.slideshow){return false}else{vars.in_animation=true}clearInterval(vars.slideshow_interval);var h=d.options.slides,e=d.$el.find(".activeslide");a(".prevslide").removeClass("prevslide");e.removeClass("activeslide").addClass("prevslide");vars.current_slide==0?vars.current_slide=d.options.slides.length-1:vars.current_slide--;var g=a(d.el+" li:eq("+vars.current_slide+")"),i=d.$el.find(".prevslide");if(d.options.performance==1){d.$el.removeClass("quality").addClass("speed")}loadSlide=vars.current_slide;var k=d.el+" li:eq("+loadSlide+")";if(!a(k).html()){var j=d.options.new_window?' target="_blank"':"";imageLink=(d.options.slides[loadSlide].url)?"href='"+d.options.slides[loadSlide].url+"'":"";var f=a('<img src="'+d.options.slides[loadSlide].image+'"/>');f.appendTo(k).wrap("<a "+imageLink+j+"></a>").parent().parent().addClass("image-loading").css("visibility","hidden");f.load(function(){d._origDim(a(this));d.resizeNow()})}if(d.options.thumbnail_navigation==1){loadSlide==0?prevThumb=d.options.slides.length-1:prevThumb=loadSlide-1;a(vars.prev_thumb).html(a("<img/>").attr("src",d.options.slides[prevThumb].image));vars.current_slide==d.options.slides.length-1?nextThumb=0:nextThumb=vars.current_slide+1;a(vars.next_thumb).html(a("<img/>").attr("src",d.options.slides[nextThumb].image))}if(typeof theme!="undefined"&&typeof theme.beforeAnimation=="function"){theme.beforeAnimation("prev")}if(d.options.slide_links){a(".current-slide").removeClass("current-slide");a(vars.slide_list+"> li").eq(vars.current_slide).addClass("current-slide")}g.css("visibility","hidden").addClass("activeslide");switch(d.options.transition){case 0:case"none":g.css("visibility","visible");vars.in_animation=false;d.afterAnimation();break;case 1:case"fade":g.animate({opacity:0},0).css("visibility","visible").animate({opacity:1,avoidTransforms:false},d.options.transition_speed,function(){d.afterAnimation()});break;case 2:case"slideTop":g.animate({top:d.$el.height()},0).css("visibility","visible").animate({top:0,avoidTransforms:false},d.options.transition_speed,function(){d.afterAnimation()});break;case 3:case"slideRight":g.animate({left:-d.$el.width()},0).css("visibility","visible").animate({left:0,avoidTransforms:false},d.options.transition_speed,function(){d.afterAnimation()});break;case 4:case"slideBottom":g.animate({top:-d.$el.height()},0).css("visibility","visible").animate({top:0,avoidTransforms:false},d.options.transition_speed,function(){d.afterAnimation()});break;case 5:case"slideLeft":g.animate({left:d.$el.width()},0).css("visibility","visible").animate({left:0,avoidTransforms:false},d.options.transition_speed,function(){d.afterAnimation()});break;case 6:case"carouselRight":g.animate({left:-d.$el.width()},0).css("visibility","visible").animate({left:0,avoidTransforms:false},d.options.transition_speed,function(){d.afterAnimation()});e.animate({left:0},0).animate({left:d.$el.width(),avoidTransforms:false},d.options.transition_speed);break;case 7:case"carouselLeft":g.animate({left:d.$el.width()},0).css("visibility","visible").animate({left:0,avoidTransforms:false},d.options.transition_speed,function(){d.afterAnimation()});e.animate({left:0},0).animate({left:-d.$el.width(),avoidTransforms:false},d.options.transition_speed);break}return false};d.playToggle=function(){if(vars.in_animation||!api.options.slideshow){return false}if(vars.is_paused){vars.is_paused=false;if(typeof theme!="undefined"&&typeof theme.playToggle=="function"){theme.playToggle("play")}vars.slideshow_interval=setInterval(d.nextSlide,d.options.slide_interval)}else{vars.is_paused=true;if(typeof theme!="undefined"&&typeof theme.playToggle=="function"){theme.playToggle("pause")}clearInterval(vars.slideshow_interval)}return false};d.goTo=function(f){if(vars.in_animation||!api.options.slideshow){return false}var e=d.options.slides.length;if(f<0){f=e}else{if(f>e){f=1}}f=e-f+1;clearInterval(vars.slideshow_interval);if(typeof theme!="undefined"&&typeof theme.goTo=="function"){theme.goTo()}if(vars.current_slide==e-f){if(!(vars.is_paused)){vars.slideshow_interval=setInterval(d.nextSlide,d.options.slide_interval)}return false}if(e-f>vars.current_slide){vars.current_slide=e-f-1;vars.update_images="next";d._placeSlide(vars.update_images)}else{if(e-f<vars.current_slide){vars.current_slide=e-f+1;vars.update_images="prev";d._placeSlide(vars.update_images)}}if(d.options.slide_links){a(vars.slide_list+"> .current-slide").removeClass("current-slide");a(vars.slide_list+"> li").eq((e-f)).addClass("current-slide")}if(d.options.thumb_links){a(vars.thumb_list+"> .current-thumb").removeClass("current-thumb");a(vars.thumb_list+"> li").eq((e-f)).addClass("current-thumb")}};d._placeSlide=function(e){var h=d.options.new_window?' target="_blank"':"";loadSlide=false;if(e=="next"){vars.current_slide==d.options.slides.length-1?loadSlide=0:loadSlide=vars.current_slide+1;var g=d.el+" li:eq("+loadSlide+")";if(!a(g).html()){var h=d.options.new_window?' target="_blank"':"";imageLink=(d.options.slides[loadSlide].url)?"href='"+d.options.slides[loadSlide].url+"'":"";var f=a('<img src="'+d.options.slides[loadSlide].image+'"/>');f.appendTo(g).wrap("<a "+imageLink+h+"></a>").parent().parent().addClass("image-loading").css("visibility","hidden");f.load(function(){d._origDim(a(this));d.resizeNow()})}d.nextSlide()}else{if(e=="prev"){vars.current_slide-1<0?loadSlide=d.options.slides.length-1:loadSlide=vars.current_slide-1;var g=d.el+" li:eq("+loadSlide+")";if(!a(g).html()){var h=d.options.new_window?' target="_blank"':"";imageLink=(d.options.slides[loadSlide].url)?"href='"+d.options.slides[loadSlide].url+"'":"";var f=a('<img src="'+d.options.slides[loadSlide].image+'"/>');f.appendTo(g).wrap("<a "+imageLink+h+"></a>").parent().parent().addClass("image-loading").css("visibility","hidden");f.load(function(){d._origDim(a(this));d.resizeNow()})}d.prevSlide()}}};d._origDim=function(e){e.data("origWidth",e.width()).data("origHeight",e.height())};d.afterAnimation=function(){if(d.options.performance==1){d.$el.removeClass("speed").addClass("quality")}if(vars.update_images){vars.current_slide-1<0?setPrev=d.options.slides.length-1:setPrev=vars.current_slide-1;vars.update_images=false;a(".prevslide").removeClass("prevslide");a(d.el+" li:eq("+setPrev+")").addClass("prevslide")}vars.in_animation=false;if(!vars.is_paused&&d.options.slideshow){vars.slideshow_interval=setInterval(d.nextSlide,d.options.slide_interval);if(d.options.stop_loop&&vars.current_slide==d.options.slides.length-1){d.playToggle()}}if(typeof theme!="undefined"&&typeof theme.afterAnimation=="function"){theme.afterAnimation()}return false};d.getField=function(e){return d.options.slides[vars.current_slide][e]};d.init()};a.supersized.vars={thumb_tray:"#thumb-tray",thumb_list:"#thumb-list",slide_list:"#slide-list",current_slide:0,in_animation:false,is_paused:false,hover_pause:false,slideshow_interval:false,update_images:false,options:{}};a.supersized.defaultOptions={slideshow:1,autoplay:1,start_slide:1,stop_loop:0,random:0,slide_interval:5000,transition:1,transition_speed:750,new_window:1,pause_hover:0,keyboard_nav:1,performance:1,image_protect:1,fit_always:0,fit_landscape:0,fit_portrait:1,min_width:0,min_height:0,horizontal_center:1,vertical_center:1,slide_links:1,thumb_links:1,thumbnail_navigation:0};a.fn.supersized=function(b){return this.each(function(){(new a.supersized(b))})}})(jQuery);
\ No newline at end of file diff --git a/apps/gallery/js/supersized.shutter.js b/apps/gallery/js/supersized.shutter.js new file mode 100644 index 00000000000..cc3025a94a3 --- /dev/null +++ b/apps/gallery/js/supersized.shutter.js @@ -0,0 +1,337 @@ +/* + + Supersized - Fullscreen Slideshow jQuery Plugin + Version : 3.2.7 + Theme : Shutter 1.1 + + Site : www.buildinternet.com/project/supersized + Author : Sam Dunn + Company : One Mighty Roar (www.onemightyroar.com) + License : MIT License / GPL License + +*/ + +(function($){ + + theme = { + + + /* Initial Placement + ----------------------------*/ + _init : function(){ + + // Center Slide Links + if (api.options.slide_links) $(vars.slide_list).css('margin-left', -$(vars.slide_list).width()/2); + + // Start progressbar if autoplay enabled + if (api.options.autoplay){ + if (api.options.progress_bar) theme.progressBar(); + }else{ + if ($(vars.play_button).attr('src')) $(vars.play_button).attr("src", vars.image_path + "play.png"); // If pause play button is image, swap src + if (api.options.progress_bar) $(vars.progress_bar).stop().animate({left : -$(window).width()}, 0 ); // Place progress bar + } + + + /* Thumbnail Tray + ----------------------------*/ + // Hide tray off screen + $(vars.thumb_tray).animate({bottom : -$(vars.thumb_tray).height()}, 0 ); + + // Thumbnail Tray Toggle + $(vars.tray_button).toggle(function(){ + $(vars.thumb_tray).stop().animate({bottom : 0, avoidTransforms : true}, 300 ); + if ($(vars.tray_arrow).attr('src')) $(vars.tray_arrow).attr("src", vars.image_path + "button-tray-down.png"); + return false; + }, function() { + $(vars.thumb_tray).stop().animate({bottom : -$(vars.thumb_tray).height(), avoidTransforms : true}, 300 ); + if ($(vars.tray_arrow).attr('src')) $(vars.tray_arrow).attr("src", vars.image_path + "button-tray-up.png"); + return false; + }); + + // Make thumb tray proper size + $(vars.thumb_list).width($('> li', vars.thumb_list).length * $('> li', vars.thumb_list).outerWidth(true)); //Adjust to true width of thumb markers + + // Display total slides + if ($(vars.slide_total).length){ + $(vars.slide_total).html(api.options.slides.length); + } + + + /* Thumbnail Tray Navigation + ----------------------------*/ + if (api.options.thumb_links){ + //Hide thumb arrows if not needed + if ($(vars.thumb_list).width() <= $(vars.thumb_tray).width()){ + $(vars.thumb_back +','+vars.thumb_forward).fadeOut(0); + } + + // Thumb Intervals + vars.thumb_interval = Math.floor($(vars.thumb_tray).width() / $('> li', vars.thumb_list).outerWidth(true)) * $('> li', vars.thumb_list).outerWidth(true); + vars.thumb_page = 0; + + // Cycle thumbs forward + $(vars.thumb_forward).click(function(){ + if (vars.thumb_page - vars.thumb_interval <= -$(vars.thumb_list).width()){ + vars.thumb_page = 0; + $(vars.thumb_list).stop().animate({'left': vars.thumb_page}, {duration:500, easing:'easeOutExpo'}); + }else{ + vars.thumb_page = vars.thumb_page - vars.thumb_interval; + $(vars.thumb_list).stop().animate({'left': vars.thumb_page}, {duration:500, easing:'easeOutExpo'}); + } + }); + + // Cycle thumbs backwards + $(vars.thumb_back).click(function(){ + if (vars.thumb_page + vars.thumb_interval > 0){ + vars.thumb_page = Math.floor($(vars.thumb_list).width() / vars.thumb_interval) * -vars.thumb_interval; + if ($(vars.thumb_list).width() <= -vars.thumb_page) vars.thumb_page = vars.thumb_page + vars.thumb_interval; + $(vars.thumb_list).stop().animate({'left': vars.thumb_page}, {duration:500, easing:'easeOutExpo'}); + }else{ + vars.thumb_page = vars.thumb_page + vars.thumb_interval; + $(vars.thumb_list).stop().animate({'left': vars.thumb_page}, {duration:500, easing:'easeOutExpo'}); + } + }); + + } + + + /* Navigation Items + ----------------------------*/ + $(vars.next_slide).click(function() { + api.nextSlide(); + }); + + $(vars.prev_slide).click(function() { + api.prevSlide(); + }); + + // Full Opacity on Hover + if(jQuery.support.opacity){ + $(vars.prev_slide +','+vars.next_slide).mouseover(function() { + $(this).stop().animate({opacity:1},100); + }).mouseout(function(){ + $(this).stop().animate({opacity:0.6},100); + }); + } + + if (api.options.thumbnail_navigation){ + // Next thumbnail clicked + $(vars.next_thumb).click(function() { + api.nextSlide(); + }); + // Previous thumbnail clicked + $(vars.prev_thumb).click(function() { + api.prevSlide(); + }); + } + + $(vars.play_button).click(function() { + api.playToggle(); + }); + + + /* Thumbnail Mouse Scrub + ----------------------------*/ + if (api.options.mouse_scrub){ + $(vars.thumb_tray).mousemove(function(e) { + var containerWidth = $(vars.thumb_tray).width(), + listWidth = $(vars.thumb_list).width(); + if (listWidth > containerWidth){ + var mousePos = 1, + diff = e.pageX - mousePos; + if (diff > 10 || diff < -10) { + mousePos = e.pageX; + newX = (containerWidth - listWidth) * (e.pageX/containerWidth); + diff = parseInt(Math.abs(parseInt($(vars.thumb_list).css('left'))-newX )).toFixed(0); + $(vars.thumb_list).stop().animate({'left':newX}, {duration:diff*3, easing:'easeOutExpo'}); + } + } + }); + } + + + /* Window Resize + ----------------------------*/ + $(window).resize(function(){ + + // Delay progress bar on resize + if (api.options.progress_bar && !vars.in_animation){ + if (vars.slideshow_interval) clearInterval(vars.slideshow_interval); + if (api.options.slides.length - 1 > 0) clearInterval(vars.slideshow_interval); + + $(vars.progress_bar).stop().animate({left : -$(window).width()}, 0 ); + + if (!vars.progressDelay && api.options.slideshow){ + // Delay slideshow from resuming so Chrome can refocus images + vars.progressDelay = setTimeout(function() { + if (!vars.is_paused){ + theme.progressBar(); + vars.slideshow_interval = setInterval(api.nextSlide, api.options.slide_interval); + } + vars.progressDelay = false; + }, 1000); + } + } + + // Thumb Links + if (api.options.thumb_links && vars.thumb_tray.length){ + // Update Thumb Interval & Page + vars.thumb_page = 0; + vars.thumb_interval = Math.floor($(vars.thumb_tray).width() / $('> li', vars.thumb_list).outerWidth(true)) * $('> li', vars.thumb_list).outerWidth(true); + + // Adjust thumbnail markers + if ($(vars.thumb_list).width() > $(vars.thumb_tray).width()){ + $(vars.thumb_back +','+vars.thumb_forward).fadeIn('fast'); + $(vars.thumb_list).stop().animate({'left':0}, 200); + }else{ + $(vars.thumb_back +','+vars.thumb_forward).fadeOut('fast'); + } + + } + }); + + + }, + + + /* Go To Slide + ----------------------------*/ + goTo : function(){ + if (api.options.progress_bar && !vars.is_paused){ + $(vars.progress_bar).stop().animate({left : -$(window).width()}, 0 ); + theme.progressBar(); + } + }, + + /* Play & Pause Toggle + ----------------------------*/ + playToggle : function(state){ + + if (state =='play'){ + // If image, swap to pause + if ($(vars.play_button).attr('src')) $(vars.play_button).attr("src", vars.image_path + "pause.png"); + if (api.options.progress_bar && !vars.is_paused) theme.progressBar(); + }else if (state == 'pause'){ + // If image, swap to play + if ($(vars.play_button).attr('src')) $(vars.play_button).attr("src", vars.image_path + "play.png"); + if (api.options.progress_bar && vars.is_paused)$(vars.progress_bar).stop().animate({left : -$(window).width()}, 0 ); + } + + }, + + + /* Before Slide Transition + ----------------------------*/ + beforeAnimation : function(direction){ + if (api.options.progress_bar && !vars.is_paused) $(vars.progress_bar).stop().animate({left : -$(window).width()}, 0 ); + + /* Update Fields + ----------------------------*/ + // Update slide caption + if ($(vars.slide_caption).length){ + (api.getField('title')) ? $(vars.slide_caption).html(api.getField('title')) : $(vars.slide_caption).html(''); + } + // Update slide number + if (vars.slide_current.length){ + $(vars.slide_current).html(vars.current_slide + 1); + } + + + // Highlight current thumbnail and adjust row position + if (api.options.thumb_links){ + + $('.current-thumb').removeClass('current-thumb'); + $('li', vars.thumb_list).eq(vars.current_slide).addClass('current-thumb'); + + // If thumb out of view + if ($(vars.thumb_list).width() > $(vars.thumb_tray).width()){ + // If next slide direction + if (direction == 'next'){ + if (vars.current_slide == 0){ + vars.thumb_page = 0; + $(vars.thumb_list).stop().animate({'left': vars.thumb_page}, {duration:500, easing:'easeOutExpo'}); + } else if ($('.current-thumb').offset().left - $(vars.thumb_tray).offset().left >= vars.thumb_interval){ + vars.thumb_page = vars.thumb_page - vars.thumb_interval; + $(vars.thumb_list).stop().animate({'left': vars.thumb_page}, {duration:500, easing:'easeOutExpo'}); + } + // If previous slide direction + }else if(direction == 'prev'){ + if (vars.current_slide == api.options.slides.length - 1){ + vars.thumb_page = Math.floor($(vars.thumb_list).width() / vars.thumb_interval) * -vars.thumb_interval; + if ($(vars.thumb_list).width() <= -vars.thumb_page) vars.thumb_page = vars.thumb_page + vars.thumb_interval; + $(vars.thumb_list).stop().animate({'left': vars.thumb_page}, {duration:500, easing:'easeOutExpo'}); + } else if ($('.current-thumb').offset().left - $(vars.thumb_tray).offset().left < 0){ + if (vars.thumb_page + vars.thumb_interval > 0) return false; + vars.thumb_page = vars.thumb_page + vars.thumb_interval; + $(vars.thumb_list).stop().animate({'left': vars.thumb_page}, {duration:500, easing:'easeOutExpo'}); + } + } + } + + + } + + }, + + + /* After Slide Transition + ----------------------------*/ + afterAnimation : function(){ + if (api.options.progress_bar && !vars.is_paused) theme.progressBar(); // Start progress bar + }, + + + /* Progress Bar + ----------------------------*/ + progressBar : function(){ + $(vars.progress_bar).stop().animate({left : -$(window).width()}, 0 ).animate({left:0}, api.options.slide_interval); + } + + + }; + + + /* Theme Specific Variables + ----------------------------*/ + $.supersized.themeVars = { + + // Internal Variables + progress_delay : false, // Delay after resize before resuming slideshow + thumb_page : false, // Thumbnail page + thumb_interval : false, // Thumbnail interval + image_path : OC.webroot+"/apps/gallery/img/supersized/", // Default image path + + // General Elements + play_button : '#pauseplay', // Play/Pause button + next_slide : '#nextslide', // Next slide button + prev_slide : '#prevslide', // Prev slide button + next_thumb : '#nextthumb', // Next slide thumb button + prev_thumb : '#prevthumb', // Prev slide thumb button + + slide_caption : '#slidecaption', // Slide caption + slide_current : '.slidenumber', // Current slide number + slide_total : '.totalslides', // Total Slides + slide_list : '#slide-list', // Slide jump list + + thumb_tray : '#thumb-tray', // Thumbnail tray + thumb_list : '#thumb-list', // Thumbnail list + thumb_forward : '#thumb-forward', // Cycles forward through thumbnail list + thumb_back : '#thumb-back', // Cycles backwards through thumbnail list + tray_arrow : '#tray-arrow', // Thumbnail tray button arrow + tray_button : '#tray-button', // Thumbnail tray button + + progress_bar : '#progress-bar' // Progress bar + + }; + + /* Theme Specific Options + ----------------------------*/ + $.supersized.themeOptions = { + + progress_bar : 1, // Timer for each slide + mouse_scrub : 0 // Thumbnails move with mouse + + }; + + +})(jQuery); diff --git a/apps/gallery/js/supersized.shutter.min.js b/apps/gallery/js/supersized.shutter.min.js new file mode 100644 index 00000000000..52ea4a3384a --- /dev/null +++ b/apps/gallery/js/supersized.shutter.min.js @@ -0,0 +1,14 @@ +/* + + Supersized - Fullscreen Slideshow jQuery Plugin + Version : 3.2.7 + Theme : Shutter 1.1 + + Site : www.buildinternet.com/project/supersized + Author : Sam Dunn + Company : One Mighty Roar (www.onemightyroar.com) + License : MIT License / GPL License + +*/ + +(function(a){theme={_init:function(){if(api.options.slide_links){a(vars.slide_list).css("margin-left",-a(vars.slide_list).width()/2)}if(api.options.autoplay){if(api.options.progress_bar){theme.progressBar()}}else{if(a(vars.play_button).attr("src")){a(vars.play_button).attr("src",vars.image_path+"play.png")}if(api.options.progress_bar){a(vars.progress_bar).stop().animate({left:-a(window).width()},0)}}a(vars.thumb_tray).animate({bottom:-a(vars.thumb_tray).height()},0);a(vars.tray_button).toggle(function(){a(vars.thumb_tray).stop().animate({bottom:0,avoidTransforms:true},300);if(a(vars.tray_arrow).attr("src")){a(vars.tray_arrow).attr("src",vars.image_path+"button-tray-down.png")}return false},function(){a(vars.thumb_tray).stop().animate({bottom:-a(vars.thumb_tray).height(),avoidTransforms:true},300);if(a(vars.tray_arrow).attr("src")){a(vars.tray_arrow).attr("src",vars.image_path+"button-tray-up.png")}return false});a(vars.thumb_list).width(a("> li",vars.thumb_list).length*a("> li",vars.thumb_list).outerWidth(true));if(a(vars.slide_total).length){a(vars.slide_total).html(api.options.slides.length)}if(api.options.thumb_links){if(a(vars.thumb_list).width()<=a(vars.thumb_tray).width()){a(vars.thumb_back+","+vars.thumb_forward).fadeOut(0)}vars.thumb_interval=Math.floor(a(vars.thumb_tray).width()/a("> li",vars.thumb_list).outerWidth(true))*a("> li",vars.thumb_list).outerWidth(true);vars.thumb_page=0;a(vars.thumb_forward).click(function(){if(vars.thumb_page-vars.thumb_interval<=-a(vars.thumb_list).width()){vars.thumb_page=0;a(vars.thumb_list).stop().animate({left:vars.thumb_page},{duration:500,easing:"easeOutExpo"})}else{vars.thumb_page=vars.thumb_page-vars.thumb_interval;a(vars.thumb_list).stop().animate({left:vars.thumb_page},{duration:500,easing:"easeOutExpo"})}});a(vars.thumb_back).click(function(){if(vars.thumb_page+vars.thumb_interval>0){vars.thumb_page=Math.floor(a(vars.thumb_list).width()/vars.thumb_interval)*-vars.thumb_interval;if(a(vars.thumb_list).width()<=-vars.thumb_page){vars.thumb_page=vars.thumb_page+vars.thumb_interval}a(vars.thumb_list).stop().animate({left:vars.thumb_page},{duration:500,easing:"easeOutExpo"})}else{vars.thumb_page=vars.thumb_page+vars.thumb_interval;a(vars.thumb_list).stop().animate({left:vars.thumb_page},{duration:500,easing:"easeOutExpo"})}})}a(vars.next_slide).click(function(){api.nextSlide()});a(vars.prev_slide).click(function(){api.prevSlide()});if(jQuery.support.opacity){a(vars.prev_slide+","+vars.next_slide).mouseover(function(){a(this).stop().animate({opacity:1},100)}).mouseout(function(){a(this).stop().animate({opacity:0.6},100)})}if(api.options.thumbnail_navigation){a(vars.next_thumb).click(function(){api.nextSlide()});a(vars.prev_thumb).click(function(){api.prevSlide()})}a(vars.play_button).click(function(){api.playToggle()});if(api.options.mouse_scrub){a(vars.thumb_tray).mousemove(function(f){var c=a(vars.thumb_tray).width(),g=a(vars.thumb_list).width();if(g>c){var b=1,d=f.pageX-b;if(d>10||d<-10){b=f.pageX;newX=(c-g)*(f.pageX/c);d=parseInt(Math.abs(parseInt(a(vars.thumb_list).css("left"))-newX)).toFixed(0);a(vars.thumb_list).stop().animate({left:newX},{duration:d*3,easing:"easeOutExpo"})}}})}a(window).resize(function(){if(api.options.progress_bar&&!vars.in_animation){if(vars.slideshow_interval){clearInterval(vars.slideshow_interval)}if(api.options.slides.length-1>0){clearInterval(vars.slideshow_interval)}a(vars.progress_bar).stop().animate({left:-a(window).width()},0);if(!vars.progressDelay&&api.options.slideshow){vars.progressDelay=setTimeout(function(){if(!vars.is_paused){theme.progressBar();vars.slideshow_interval=setInterval(api.nextSlide,api.options.slide_interval)}vars.progressDelay=false},1000)}}if(api.options.thumb_links&&vars.thumb_tray.length){vars.thumb_page=0;vars.thumb_interval=Math.floor(a(vars.thumb_tray).width()/a("> li",vars.thumb_list).outerWidth(true))*a("> li",vars.thumb_list).outerWidth(true);if(a(vars.thumb_list).width()>a(vars.thumb_tray).width()){a(vars.thumb_back+","+vars.thumb_forward).fadeIn("fast");a(vars.thumb_list).stop().animate({left:0},200)}else{a(vars.thumb_back+","+vars.thumb_forward).fadeOut("fast")}}})},goTo:function(b){if(api.options.progress_bar&&!vars.is_paused){a(vars.progress_bar).stop().animate({left:-a(window).width()},0);theme.progressBar()}},playToggle:function(b){if(b=="play"){if(a(vars.play_button).attr("src")){a(vars.play_button).attr("src",vars.image_path+"pause.png")}if(api.options.progress_bar&&!vars.is_paused){theme.progressBar()}}else{if(b=="pause"){if(a(vars.play_button).attr("src")){a(vars.play_button).attr("src",vars.image_path+"play.png")}if(api.options.progress_bar&&vars.is_paused){a(vars.progress_bar).stop().animate({left:-a(window).width()},0)}}}},beforeAnimation:function(b){if(api.options.progress_bar&&!vars.is_paused){a(vars.progress_bar).stop().animate({left:-a(window).width()},0)}if(a(vars.slide_caption).length){(api.getField("title"))?a(vars.slide_caption).html(api.getField("title")):a(vars.slide_caption).html("")}if(vars.slide_current.length){a(vars.slide_current).html(vars.current_slide+1)}if(api.options.thumb_links){a(".current-thumb").removeClass("current-thumb");a("li",vars.thumb_list).eq(vars.current_slide).addClass("current-thumb");if(a(vars.thumb_list).width()>a(vars.thumb_tray).width()){if(b=="next"){if(vars.current_slide==0){vars.thumb_page=0;a(vars.thumb_list).stop().animate({left:vars.thumb_page},{duration:500,easing:"easeOutExpo"})}else{if(a(".current-thumb").offset().left-a(vars.thumb_tray).offset().left>=vars.thumb_interval){vars.thumb_page=vars.thumb_page-vars.thumb_interval;a(vars.thumb_list).stop().animate({left:vars.thumb_page},{duration:500,easing:"easeOutExpo"})}}}else{if(b=="prev"){if(vars.current_slide==api.options.slides.length-1){vars.thumb_page=Math.floor(a(vars.thumb_list).width()/vars.thumb_interval)*-vars.thumb_interval;if(a(vars.thumb_list).width()<=-vars.thumb_page){vars.thumb_page=vars.thumb_page+vars.thumb_interval}a(vars.thumb_list).stop().animate({left:vars.thumb_page},{duration:500,easing:"easeOutExpo"})}else{if(a(".current-thumb").offset().left-a(vars.thumb_tray).offset().left<0){if(vars.thumb_page+vars.thumb_interval>0){return false}vars.thumb_page=vars.thumb_page+vars.thumb_interval;a(vars.thumb_list).stop().animate({left:vars.thumb_page},{duration:500,easing:"easeOutExpo"})}}}}}}},afterAnimation:function(){if(api.options.progress_bar&&!vars.is_paused){theme.progressBar()}},progressBar:function(){a(vars.progress_bar).stop().animate({left:-a(window).width()},0).animate({left:0},api.options.slide_interval)}};a.supersized.themeVars={progress_delay:false,thumb_page:false,thumb_interval:false,image_path:OC.webroot+"/apps/gallery/img/supersized/",play_button:"#pauseplay",next_slide:"#nextslide",prev_slide:"#prevslide",next_thumb:"#nextthumb",prev_thumb:"#prevthumb",slide_caption:"#slidecaption",slide_current:".slidenumber",slide_total:".totalslides",slide_list:"#slide-list",thumb_tray:"#thumb-tray",thumb_list:"#thumb-list",thumb_forward:"#thumb-forward",thumb_back:"#thumb-back",tray_arrow:"#tray-arrow",tray_button:"#tray-button",progress_bar:"#progress-bar"};a.supersized.themeOptions={progress_bar:1,mouse_scrub:0}})(jQuery); diff --git a/apps/gallery/lib/hooks_handlers.php b/apps/gallery/lib/hooks_handlers.php index 093979834da..3bafdb5cf4d 100644 --- a/apps/gallery/lib/hooks_handlers.php +++ b/apps/gallery/lib/hooks_handlers.php @@ -38,5 +38,3 @@ class OC_Gallery_Hooks_Handlers { //TODO: implement this } } - -?> diff --git a/apps/gallery/lib/images_utils.php b/apps/gallery/lib/images_utils.php index ac3a383c977..f5e37cf1dee 100644 --- a/apps/gallery/lib/images_utils.php +++ b/apps/gallery/lib/images_utils.php @@ -60,5 +60,3 @@ function CroppedThumbnail($imgSrc,$thumbnail_width,$thumbnail_height, $tgtImg, $ imagedestroy($process); imagedestroy($myImage); } - -?> diff --git a/apps/gallery/lib/managers.php b/apps/gallery/lib/managers.php index fcce3f40e23..b6ade3d1b1e 100644 --- a/apps/gallery/lib/managers.php +++ b/apps/gallery/lib/managers.php @@ -2,8 +2,9 @@ namespace OC\Pictures; -class DatabaseManager { +class DatabaseManager { private static $instance = null; + protected $cache = array(); const TAG = 'DatabaseManager'; public static function getInstance() { @@ -12,22 +13,45 @@ class DatabaseManager { return self::$instance; } + protected function getPathData($path) { + $stmt = \OCP\DB::prepare('SELECT * FROM *PREFIX*pictures_images_cache + WHERE uid_owner LIKE ? AND path like ? AND path not like ?'); + $path_match = $path.'/%'; + $path_notmatch = $path.'/%/%'; + $result = $stmt->execute(array(\OCP\USER::getUser(), $path_match, $path_notmatch)); + $this->cache[$path] = array(); + while (($row = $result->fetchRow()) != false) { + $this->cache[$path][$row['path']] = $row; + } + } + + public function setFileData($path, $width, $height) { + $stmt = \OCP\DB::prepare('INSERT INTO *PREFIX*pictures_images_cache (uid_owner, path, width, height) VALUES (?, ?, ?, ?)'); + $stmt->execute(array(\OCP\USER::getUser(), $path, $width, $height)); + $ret = array('path' => $path, 'width' => $width, 'height' => $height); + unset($image); + $dir = dirname($path); + $this->cache[$dir][$path] = $ret; + return $ret; + } + public function getFileData($path) { $gallery_path = \OCP\Config::getSystemValue( 'datadirectory' ).'/'.\OC_User::getUser().'/gallery'; $path = $gallery_path.$path; - $stmt = \OCP\DB::prepare('SELECT * FROM *PREFIX*pictures_images_cache WHERE uid_owner LIKE ? AND path = ?'); - $result = $stmt->execute(array(\OCP\USER::getUser(), $path)); - if (($row = $result->fetchRow()) != false) { - return $row; + $dir = dirname($path); + if (!isset($this->cache[$dir])) { + $this->getPathData($dir); + } + if (isset($this->cache[$dir][$path])) { + return $this->cache[$dir][$path]; } $image = new \OC_Image(); if (!$image->loadFromFile($path)) { return false; } - $stmt = \OCP\DB::prepare('INSERT INTO *PREFIX*pictures_images_cache (uid_owner, path, width, height) VALUES (?, ?, ?, ?)'); - $stmt->execute(array(\OCP\USER::getUser(), $path, $image->width(), $image->height())); - $ret = array('path' => $path, 'width' => $image->width(), 'height' => $image->height()); + $ret = $this->setFileData($path, $image->width(), $image->height()); unset($image); + $this->cache[$dir][$path] = $ret; return $ret; } @@ -38,6 +62,7 @@ class ThumbnailsManager { private static $instance = null; const TAG = 'ThumbnailManager'; + const THUMBNAIL_HEIGHT = 150; public static function getInstance() { if (self::$instance === null) @@ -46,9 +71,9 @@ class ThumbnailsManager { } public function getThumbnail($path) { - $gallery_path = \OCP\Config::getSystemValue( 'datadirectory' ).'/'.\OC_User::getUser().'/gallery'; - if (file_exists($gallery_path.$path)) { - return new \OC_Image($gallery_path.$path); + $gallery_storage = \OCP\Files::getStorage('gallery'); + if ($gallery_storage->file_exists($path)) { + return new \OC_Image($gallery_storage->getLocalFile($path)); } if (!\OC_Filesystem::file_exists($path)) { \OC_Log::write(self::TAG, 'File '.$path.' don\'t exists', \OC_Log::WARN); @@ -57,27 +82,39 @@ class ThumbnailsManager { $image = new \OC_Image(); $image->loadFromFile(\OC_Filesystem::getLocalFile($path)); if (!$image->valid()) return false; - + $image->fixOrientation(); - - $ret = $image->preciseResize(floor((150*$image->width())/$image->height()), 150); + + $ret = $image->preciseResize( floor((self::THUMBNAIL_HEIGHT*$image->width())/$image->height()), self::THUMBNAIL_HEIGHT ); if (!$ret) { \OC_Log::write(self::TAG, 'Couldn\'t resize image', \OC_Log::ERROR); unset($image); return false; } - - $image->save($gallery_path.'/'.$path); + $l = $gallery_storage->getLocalFile($path); + + $image->save($l); return $image; } - + + public function getThumbnailWidth($image) { + return floor((self::THUMBNAIL_HEIGHT*$image->widthTopLeft())/$image->heightTopLeft()); + } + public function getThumbnailInfo($path) { $arr = DatabaseManager::getInstance()->getFileData($path); if (!$arr) { - $thubnail = $this->getThumbnail($path); - unset($thubnail); - $arr = DatabaseManager::getInstance()->getFileData($path); + if (!\OC_Filesystem::file_exists($path)) { + \OC_Log::write(self::TAG, 'File '.$path.' don\'t exists', \OC_Log::WARN); + return false; + } + $image = new \OC_Image(); + $image->loadFromFile(\OC_Filesystem::getLocalFile($path)); + if (!$image->valid()) { + return false; + } + $arr = DatabaseManager::getInstance()->setFileData($path, $this->getThumbnailWidth($image), self::THUMBNAIL_HEIGHT); } $ret = array('filepath' => $arr['path'], 'width' => $arr['width'], @@ -86,13 +123,12 @@ class ThumbnailsManager { } public function delete($path) { - $thumbnail = \OCP\Config::getSystemValue('datadirectory').'/'.\OC_User::getUser()."/gallery".$path;
- if (file_exists($thumbnail)) {
- unlink($thumbnail);
+ $thumbnail_storage = \OCP\Files::getStorage('gallery'); + if ($thumbnail_storage->file_exists($path)) { + $thumbnail_storage->unlink($path); } } private function __construct() {} } -?> diff --git a/apps/gallery/lib/photo.php b/apps/gallery/lib/photo.php index f9527cb5fdb..3b4e74641b3 100644 --- a/apps/gallery/lib/photo.php +++ b/apps/gallery/lib/photo.php @@ -1,53 +1,55 @@ <?php /** -* ownCloud - gallery application -* -* @author Bartek Przybylski -* @copyright 2012 Bartek Przybylski bart.p.pl@gmail.com -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the License, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Lesser General Public -* License along with this library. If not, see <http://www.gnu.org/licenses/>. -* -*/ - + * ownCloud - gallery application + * + * @author Bartek Przybylski + * @copyright 2012 Bartek Przybylski bart.p.pl@gmail.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ class OC_Gallery_Photo { - public static function create($albumId, $img){ + + public static function create($albumId, $img) { $stmt = OCP\DB::prepare('INSERT INTO *PREFIX*gallery_photos (album_id, file_path) VALUES (?, ?)'); $stmt->execute(array($albumId, $img)); } - public static function find($albumId, $img=null){ + + public static function find($albumId, $img = null) { $sql = 'SELECT * FROM *PREFIX*gallery_photos WHERE album_id = ?'; $args = array($albumId); - if (!is_null($img)){ + if (!is_null($img)) { $sql .= ' AND file_path = ?'; $args[] = $img; } $stmt = OCP\DB::prepare($sql); return $stmt->execute($args); } - public static function findForAlbum($owner, $album_name){ + + public static function findForAlbum($owner, $album_name) { $stmt = OCP\DB::prepare('SELECT *' - .' FROM *PREFIX*gallery_photos photos,' - .' *PREFIX*gallery_albums albums' - .' WHERE albums.uid_owner = ?' - .' AND albums.album_name = ?' - .' AND photos.album_id = albums.album_id'); + .' FROM *PREFIX*gallery_photos photos,' + .' *PREFIX*gallery_albums albums' + .' WHERE albums.uid_owner = ?' + .' AND albums.album_name = ?' + .' AND photos.album_id = albums.album_id'); return $stmt->execute(array($owner, $album_name)); } - public static function removeByPath($path, $album_id) { - $stmt = OCP\DB::prepare('DELETE FROM *PREFIX*gallery_photos WHERE file_path LIKE ? and album_id = ?'); + public static function removeByPath($path, $album_id) { + $stmt = OCP\DB::prepare('DELETE FROM *PREFIX*gallery_photos WHERE file_path LIKE ? and album_id = ?'); $stmt->execute(array($path, $album_id)); } @@ -67,19 +69,20 @@ class OC_Gallery_Photo { } public static function getThumbnail($image_name, $owner = null) { - if (!$owner) $owner = OCP\USER::getUser(); + if (!$owner) + $owner = OCP\USER::getUser(); $view = OCP\Files::getStorage('gallery'); $save_dir = dirname($image_name); if (!$view->is_dir($save_dir)) { $view->mkdir($save_dir); } - $view->chroot($view->getRoot().'/'.$save_dir); + $view->chroot($view->getRoot() . '/' . $save_dir); $thumb_file = basename($image_name); if ($view->file_exists($thumb_file)) { $image = new OC_Image($view->fopen($thumb_file, 'r')); } else { $image_path = OC_Filesystem::getLocalFile($image_name); - if(!file_exists($image_path)) { + if (!file_exists($image_path)) { return null; } $image = new OC_Image($image_path); @@ -91,7 +94,38 @@ class OC_Gallery_Photo { } if ($image->valid()) { return $image; - }else{ + } else { + $image->destroy(); + } + return null; + } + + public static function getViewImage($image_name, $owner = null) { + if (!$owner) $owner = OCP\USER::getUser(); + $save_dir = OCP\Config::getSystemValue("datadirectory") . '/' . $owner . '/gallery'; + $save_dir .= dirname($image_name) . '/view/'; + $image_path = $image_name; + $view_file = $save_dir . basename($image_name); + if (!is_dir($save_dir)) { + mkdir($save_dir, 0777, true); + } + if (file_exists($view_file)) { + $image = new OC_Image($view_file); + } else { + $image_path = OC_Filesystem::getLocalFile($image_path); + if (!file_exists($image_path)) { + return null; + } + $image = new OC_Image($image_path); + if ($image->valid()) { + $image->resize(1200); + $image->fixOrientation(); + $image->save($view_file); + } + } + if ($image->valid()) { + return $image; + } else { $image->destroy(); } return null; @@ -100,4 +134,5 @@ class OC_Gallery_Photo { public static function getGalleryRoot() { return OCP\Config::getUserValue(OCP\USER::getUser(), 'gallery', 'root', ''); } + } diff --git a/apps/gallery/lib/tiles.php b/apps/gallery/lib/tiles.php index 5efe0d7a299..754734e609e 100644 --- a/apps/gallery/lib/tiles.php +++ b/apps/gallery/lib/tiles.php @@ -95,7 +95,7 @@ class TileSingle extends TileBase { public function get($extra = '') { // !HACK! file path needs to be encoded twice because files app decode twice url, so any special chars like + or & in filename // !HACK! will result in failing of opening them - return '<a rel="images" title="'.htmlentities(basename($this->getPath())).'" href="'.\OCP\Util::linkTo('files', 'download.php').'?file='.urlencode(urlencode($this->getPath())).'"><img rel="images" src="'.\OCP\Util::linkTo('gallery', 'ajax/thumbnail.php').'&filepath='.urlencode($this->getPath()).'" '.$extra.'></a>'; + return '<a rel="images" title="'.htmlentities(basename($this->getPath())).'" href="'.\OCP\Util::linkTo('gallery','ajax/viewImage.php').'?img='.urlencode(urlencode($this->getPath())).'"><img rel="images" src="'.\OCP\Util::linkTo('gallery', 'ajax/thumbnail.php').'&filepath='.urlencode($this->getPath()).'" '.$extra.'></a>'; } public function getMiniatureSrc() { @@ -174,5 +174,3 @@ class TileStack extends TileBase { private $tiles_array; private $stack_name; } - -?> diff --git a/apps/gallery/lib/tiles_test.php b/apps/gallery/lib/tiles_test.php index 022a88f75cc..02d567c628d 100644 --- a/apps/gallery/lib/tiles_test.php +++ b/apps/gallery/lib/tiles_test.php @@ -83,5 +83,3 @@ if ($ts->getCount() != 0) { } echo $tl->get(); - -?> diff --git a/apps/gallery/templates/index.php b/apps/gallery/templates/index.php index c90932cefd0..b2efd5342ff 100644 --- a/apps/gallery/templates/index.php +++ b/apps/gallery/templates/index.php @@ -22,7 +22,10 @@ $(document).ready(function() { } } -?><br/> +?> + <div id="slideshow"> + <input type="button" class="start" value="<?php echo $l->t('Slideshow')?>" /> + </div> </div> <div id="gallerycontent"> <?php @@ -32,3 +35,50 @@ echo $_['tl']->get(); ?> </div> + +<!-- start supersized block --> +<div id="slideshow-content" style="display:none;"> + + <!--Thumbnail Navigation--> + <div id="prevthumb"></div> + <div id="nextthumb"></div> + + <!--Arrow Navigation--> + <a id="prevslide" class="load-item"></a> + <a id="nextslide" class="load-item"></a> + + <div id="thumb-tray" class="load-item"> + <div id="thumb-back"></div> + <div id="thumb-forward"></div> + </div> + + <!--Time Bar--> + <div id="progress-back" class="load-item"> + <div id="progress-bar"></div> + </div> + + <!--Control Bar--> + <div id="slideshow-controls-wrapper" class="load-item"> + <div id="slideshow-controls"> + + <a id="play-button"><img id="pauseplay" src="<?php echo OCP\image_path('gallery', 'supersized/pause.png'); ?>"/></a> + + <!--Slide counter--> + <div id="slidecounter"> + <span class="slidenumber"></span> / <span class="totalslides"></span> + </div> + + <!--Slide captions displayed here--> + <div id="slidecaption"></div> + + <!--Thumb Tray button--> + <a id="tray-button"><img id="tray-arrow" src="<?php echo OCP\image_path('gallery', 'supersized/button-tray-up.png'); ?>"/></a> + + <!--Navigation--> + <!-- + <ul id="slide-list"></ul> + --> + </div> + </div> + +</div><!-- end supersized block --> diff --git a/apps/gallery/templates/view_album.php b/apps/gallery/templates/view_album.php index c16ed69c065..00e891103f1 100644 --- a/apps/gallery/templates/view_album.php +++ b/apps/gallery/templates/view_album.php @@ -1,9 +1,9 @@ <?php OCP\Util::addStyle('gallery', 'styles'); -OCP\Util::addscript('gallery', 'albums'); -OCP\Util::addscript('gallery', 'album_cover'); -OCP\Util::addscript('files_imageviewer', 'jquery.mousewheel-3.0.4.pack'); -OCP\Util::addscript('files_imageviewer', 'jquery.fancybox-1.3.4.pack'); +OCP\Util::addScript('gallery', 'albums'); +OCP\Util::addScript('gallery', 'album_cover'); +OCP\Util::addScript('files_imageviewer', 'jquery.mousewheel-3.0.4.pack'); +OCP\Util::addScript('files_imageviewer', 'jquery.fancybox-1.3.4.pack'); OCP\Util::addStyle( 'files_imageviewer', 'jquery.fancybox-1.3.4' ); $l = OC_L10N::get('gallery'); ?> diff --git a/apps/media/ajax/api.php b/apps/media/ajax/api.php index 23abc579272..7f5cdb22c12 100644 --- a/apps/media/ajax/api.php +++ b/apps/media/ajax/api.php @@ -131,4 +131,3 @@ if($arguments['action']){ exit; } } -?> diff --git a/apps/media/ajax/autoupdate.php b/apps/media/ajax/autoupdate.php index 3122c7e6754..c2dbf27a004 100644 --- a/apps/media/ajax/autoupdate.php +++ b/apps/media/ajax/autoupdate.php @@ -35,4 +35,3 @@ $autoUpdate=(isset($_GET['autoupdate']) and $_GET['autoupdate']=='true'); OCP\Config::setUserValue(OCP\USER::getUser(),'media','autoupdate',(integer)$autoUpdate); OCP\JSON::success(array('data' => $autoUpdate)); -?> diff --git a/apps/media/index.php b/apps/media/index.php index fb51aa0b17a..ae85abc8aab 100644 --- a/apps/media/index.php +++ b/apps/media/index.php @@ -40,5 +40,3 @@ OCP\App::setActiveNavigationEntry( 'media_index' ); $tmpl = new OCP\Template( 'media', 'music', 'user' ); $tmpl->printPage(); -?> - diff --git a/apps/media/lib_ampache.php b/apps/media/lib_ampache.php index 255e6f468f8..d35cca150b2 100644 --- a/apps/media/lib_ampache.php +++ b/apps/media/lib_ampache.php @@ -419,5 +419,3 @@ class OC_MEDIA_AMPACHE{ echo('</root>'); } } - -?> diff --git a/apps/media/lib_collection.php b/apps/media/lib_collection.php index 598c08d32e2..e65930f551d 100644 --- a/apps/media/lib_collection.php +++ b/apps/media/lib_collection.php @@ -387,5 +387,3 @@ class OC_MEDIA_COLLECTION{ $query->execute(array($newPath,$oldPath)); } } - -?> diff --git a/apps/media/settings.php b/apps/media/settings.php index 227298fafec..53738f02f9f 100644 --- a/apps/media/settings.php +++ b/apps/media/settings.php @@ -3,4 +3,3 @@ $tmpl = new OCP\Template( 'media', 'settings'); return $tmpl->fetchPage(); -?> diff --git a/apps/remoteStorage/settings.php b/apps/remoteStorage/settings.php index 9c48549fe6d..3be8b0984d8 100644 --- a/apps/remoteStorage/settings.php +++ b/apps/remoteStorage/settings.php @@ -4,4 +4,3 @@ require_once('lib_remoteStorage.php'); $tmpl = new OCP\Template( 'remoteStorage', 'settings'); return $tmpl->fetchPage(); -?> diff --git a/apps/user_ldap/appinfo/update.php b/apps/user_ldap/appinfo/update.php index dc437ce21ce..badceb378d1 100644 --- a/apps/user_ldap/appinfo/update.php +++ b/apps/user_ldap/appinfo/update.php @@ -31,3 +31,21 @@ if($state == 'doCheck'){ OCP\Config::setSystemValue('ldapIgnoreNamingRules', true); } } + + +//from version 0.2 to 0.2.1 +$objects = array('user', 'group'); + +foreach($objects as $object) { + $fetchDNSql = 'SELECT ldap_dn from *PREFIX*ldap_'.$object.'_mapping'; + $updateSql = 'UPDATE *PREFIX*ldap_'.$object.'_mapping SET ldap_DN = ? WHERE ldap_dn = ?'; + + $query = OCP\DB::prepare($fetchDNSql); + $res = $query->execute(); + $DNs = $res->fetchAll(); + $updateQuery = OCP\DB::prepare($updateSql); + foreach($DNs as $dn) { + $newDN = mb_strtolower($dn['ldap_dn'], 'UTF-8'); + $updateQuery->execute(array($newDN, $dn['ldap_dn'])); + } +} diff --git a/apps/user_ldap/appinfo/version b/apps/user_ldap/appinfo/version index 2f4536184bc..5f021e960ec 100644 --- a/apps/user_ldap/appinfo/version +++ b/apps/user_ldap/appinfo/version @@ -1 +1 @@ -0.2
\ No newline at end of file +0.2.0.5
\ No newline at end of file diff --git a/apps/user_ldap/group_ldap.php b/apps/user_ldap/group_ldap.php index a3117b5a41e..d438c7d84df 100644 --- a/apps/user_ldap/group_ldap.php +++ b/apps/user_ldap/group_ldap.php @@ -158,7 +158,7 @@ class OC_GROUP_LDAP extends OC_Group_Backend { $isMemberUid = (strtolower($this->ldapGroupMemberAssocAttr) == 'memberuid'); foreach($members as $member) { if($isMemberUid) { - $filter = str_replace('%uid', $member, OC_LDAP::conf('ldapLoginFilter')); + $filter = OCP\Util::mb_str_replace('%uid', $member, OC_LDAP::conf('ldapLoginFilter'), 'UTF-8'); $ldap_users = OC_LDAP::fetchListOfUsers($filter, 'dn'); if(count($ldap_users) < 1) { continue; diff --git a/apps/user_ldap/lib_ldap.php b/apps/user_ldap/lib_ldap.php index 21c4e57e293..08b09304d78 100644 --- a/apps/user_ldap/lib_ldap.php +++ b/apps/user_ldap/lib_ldap.php @@ -171,7 +171,7 @@ class OC_LDAP { * returns the internal ownCloud name for the given LDAP DN of the group */ static public function dn2groupname($dn, $ldapname = null) { - if(strripos($dn, self::$ldapBaseGroups) !== (strlen($dn)-strlen(self::$ldapBaseGroups))) { + if(mb_strripos($dn, self::$ldapBaseGroups, 0, 'UTF-8') !== (mb_strlen($dn, 'UTF-8')-mb_strlen(self::$ldapBaseGroups, 'UTF-8'))) { return false; } return self::dn2ocname($dn, $ldapname, false); @@ -186,7 +186,7 @@ class OC_LDAP { * returns the internal ownCloud name for the given LDAP DN of the user, false on DN outside of search DN */ static public function dn2username($dn, $ldapname = null) { - if(strripos($dn, self::$ldapBaseUsers) !== (strlen($dn)-strlen(self::$ldapBaseUsers))) { + if(mb_strripos($dn, self::$ldapBaseUsers, 0, 'UTF-8') !== (mb_strlen($dn, 'UTF-8')-mb_strlen(self::$ldapBaseUsers, 'UTF-8'))) { return false; } return self::dn2ocname($dn, $ldapname, true); @@ -304,7 +304,7 @@ class OC_LDAP { */ static private function alternateOwnCloudName($name, $dn) { $ufn = ldap_dn2ufn($dn); - $name = $name . '@' . trim(substr_replace($ufn, '', 0, strpos($ufn, ','))); + $name = $name . '@' . trim(OCP\Util::mb_substr_replace($ufn, '', 0, mb_strpos($ufn, ',', 0, 'UTF-8'), 'UTF-8')); $name = self::sanitizeUsername($name); return $name; } @@ -419,8 +419,8 @@ class OC_LDAP { $rr = ldap_read($cr, $dn, 'objectClass=*', array($attr)); $er = ldap_first_entry($cr, $rr); //LDAP attributes are not case sensitive - $result = array_change_key_case(ldap_get_attributes($cr, $er)); - $attr = strtolower($attr); + $result = OCP\Util::mb_array_change_key_case(ldap_get_attributes($cr, $er), MB_CASE_LOWER, 'UTF-8'); + $attr = mb_strtolower($attr, 'UTF-8'); if(isset($result[$attr]) && $result[$attr]['count'] > 0){ $values = array(); @@ -469,22 +469,21 @@ class OC_LDAP { */ static private function search($filter, $base, $attr = null) { if(!is_null($attr) && !is_array($attr)) { - $attr = array(strtolower($attr)); + $attr = array(mb_strtolower($attr, 'UTF-8')); } // See if we have a resource $link_resource = self::getConnectionResource(); - if($link_resource) - { + if(is_resource($link_resource)) { $sr = ldap_search($link_resource, $base, $filter, $attr); $findings = ldap_get_entries($link_resource, $sr ); + // if we're here, probably no connection resource is returned. // to make ownCloud behave nicely, we simply give back an empty array. if(is_null($findings)) { return array(); } - } else - { + } else { // Seems like we didn't find any resource. // Return an empty array just like before. return array(); @@ -501,11 +500,11 @@ class OC_LDAP { if(!is_array($item)) { continue; } - $item = array_change_key_case($item); + $item = OCP\Util::mb_array_change_key_case($item, MB_CASE_LOWER, 'UTF-8'); if($multiarray) { foreach($attr as $key) { - $key = strtolower($key); + $key = mb_strtolower($key, 'UTF-8'); if(isset($item[$key])) { if($key != 'dn'){ $selection[$i][$key] = self::resemblesDN($key) ? self::sanitizeDN($item[$key][0]) : $item[$key][0]; @@ -518,7 +517,7 @@ class OC_LDAP { $i++; } else { //tribute to case insensitivity - $key = strtolower($attr[0]); + $key = mb_strtolower($attr[0], 'UTF-8'); if(isset($item[$key])) { if(self::resemblesDN($key)) { @@ -547,10 +546,10 @@ class OC_LDAP { static private function sanitizeDN($dn) { //OID sometimes gives back DNs with whitespace after the comma a la "uid=foo, cn=bar, dn=..." We need to tackle this! - $dn = preg_replace('/([^\\\]),(\s+)/','\1,',$dn); + $dn = preg_replace('/([^\\\]),(\s+)/u','\1,',$dn); //make comparisons and everything work - $dn = strtolower($dn); + $dn = mb_strtolower($dn, 'UTF-8'); return $dn; } @@ -561,10 +560,10 @@ class OC_LDAP { } //REPLACEMENTS - $name = str_replace(' ', '_', $name); + $name = OCP\Util::mb_str_replace(' ', '_', $name, 'UTF-8'); //every remaining unallowed characters will be removed - $name = preg_replace('/[^a-zA-Z0-9_.@-]/', '', $name); + $name = preg_replace('/[^a-zA-Z0-9_.@-]/u', '', $name); return $name; } @@ -638,10 +637,10 @@ class OC_LDAP { self::$ldapBaseGroups = OCP\Config::getAppValue('user_ldap', 'ldap_base_groups', self::$ldapBase); self::$ldapTLS = OCP\Config::getAppValue('user_ldap', 'ldap_tls',0); self::$ldapNoCase = OCP\Config::getAppValue('user_ldap', 'ldap_nocase', 0); - self::$ldapUserDisplayName = strtolower(OCP\Config::getAppValue('user_ldap', 'ldap_display_name', 'uid')); + self::$ldapUserDisplayName = mb_strtolower(OCP\Config::getAppValue('user_ldap', 'ldap_display_name', 'uid'), 'UTF-8'); self::$ldapUserFilter = OCP\Config::getAppValue('user_ldap', 'ldap_userlist_filter','objectClass=person'); self::$ldapLoginFilter = OCP\Config::getAppValue('user_ldap', 'ldap_login_filter', '(uid=%uid)'); - self::$ldapGroupDisplayName = strtolower(OCP\Config::getAppValue('user_ldap', 'ldap_group_display_name', LDAP_GROUP_DISPLAY_NAME_ATTR)); + self::$ldapGroupDisplayName = mb_strtolower(OCP\Config::getAppValue('user_ldap', 'ldap_group_display_name', LDAP_GROUP_DISPLAY_NAME_ATTR), 'UTF-8'); self::$ldapIgnoreNamingRules = OCP\Config::getSystemValue('ldapIgnoreNamingRules', false); if(empty(self::$ldapBaseUsers)) { @@ -690,6 +689,7 @@ class OC_LDAP { $ldapLogin = @ldap_bind(self::$ldapConnectionRes, self::$ldapAgentName, self::$ldapAgentPassword ); if(!$ldapLogin) { OCP\Util::writeLog('ldap', 'Bind failed: ' . ldap_errno(self::$ldapConnectionRes) . ': ' . ldap_error(self::$ldapConnectionRes), OCP\Util::ERROR); + self::$ldapConnectionRes = null; return false; } } diff --git a/apps/user_ldap/user_ldap.php b/apps/user_ldap/user_ldap.php index 85b3d88973c..b51d9a55cc7 100644 --- a/apps/user_ldap/user_ldap.php +++ b/apps/user_ldap/user_ldap.php @@ -84,7 +84,7 @@ class OC_USER_LDAP extends OC_User_Backend { */ public function checkPassword($uid, $password){ //find out dn of the user name - $filter = str_replace('%uid', $uid, OC_LDAP::conf('ldapLoginFilter')); + $filter = OCP\Util::mb_str_replace('%uid', $uid, OC_LDAP::conf('ldapLoginFilter'), 'UTF-8'); $ldap_users = OC_LDAP::fetchListOfUsers($filter, 'dn'); if(count($ldap_users) < 1) { return false; diff --git a/apps/user_migrate/appinfo/app.php b/apps/user_migrate/appinfo/app.php index 9d314b59ce7..366c4004932 100644 --- a/apps/user_migrate/appinfo/app.php +++ b/apps/user_migrate/appinfo/app.php @@ -31,4 +31,3 @@ $entry = array( 'href' => OCP\Util::linkTo( "user_migrate", "admin.php" ), 'name' => 'Import' ); -?> diff --git a/apps/user_openid/appinfo/app.php b/apps/user_openid/appinfo/app.php index c683254101f..fe57b189fac 100644 --- a/apps/user_openid/appinfo/app.php +++ b/apps/user_openid/appinfo/app.php @@ -27,7 +27,7 @@ OC_User::useBackend('openid'); //check for results from openid requests if(isset($_GET['openid_mode']) and $_GET['openid_mode'] == 'id_res'){ OCP\Util::writeLog('user_openid','openid retured',OCP\Util::DEBUG); - $openid = new SimpleOpenID; + $openid = new SimpleOpenID(); $openid->SetIdentity($_GET['openid_identity']); $openid_validation_result = $openid->ValidateWithServer(); if ($openid_validation_result == true){ // OK HERE KEY IS VALID @@ -50,5 +50,3 @@ if(isset($_GET['openid_mode']) and $_GET['openid_mode'] == 'id_res'){ OCP\Util::writeLog('user_openid','USER CANCELED REQUEST',OCP\Util::DEBUG); return false; } - -?> diff --git a/apps/user_openid/appinfo/version b/apps/user_openid/appinfo/version index 6da28dde76d..d917d3e26ad 100644 --- a/apps/user_openid/appinfo/version +++ b/apps/user_openid/appinfo/version @@ -1 +1 @@ -0.1.1
\ No newline at end of file +0.1.2 diff --git a/apps/user_openid/class.openid.v3.php b/apps/user_openid/class.openid.v3.php index 8afb9e5b817..eeb31986659 100644 --- a/apps/user_openid/class.openid.v3.php +++ b/apps/user_openid/class.openid.v3.php @@ -324,5 +324,3 @@ class SimpleOpenID{ } } } - -?>
\ No newline at end of file diff --git a/apps/user_openid/phpmyid.php b/apps/user_openid/phpmyid.php index 5aaab642856..13fd31c47ca 100644 --- a/apps/user_openid/phpmyid.php +++ b/apps/user_openid/phpmyid.php @@ -1705,4 +1705,3 @@ $run_mode = (isset($_REQUEST['openid_mode']) debug("Run mode: $run_mode at: " . time()); debug($_REQUEST, 'Request params'); call_user_func($run_mode . '_mode'); -?> diff --git a/apps/user_openid/user.php b/apps/user_openid/user.php index 392424795f8..d25b95259e0 100644 --- a/apps/user_openid/user.php +++ b/apps/user_openid/user.php @@ -45,6 +45,3 @@ if(!OCP\User::userExists($USERNAME)){ $IDENTITY=OCP\Util::linkToAbsolute( "user_openid", "user.php" ).'/'.$USERNAME; require_once 'phpmyid.php'; - - -?> diff --git a/apps/user_openid/user_openid.php b/apps/user_openid/user_openid.php index e228de95e9e..70b193a30b1 100644 --- a/apps/user_openid/user_openid.php +++ b/apps/user_openid/user_openid.php @@ -37,7 +37,7 @@ class OC_USER_OPENID extends OC_User_Backend { */ public function checkPassword( $uid, $password ){ // Get identity from user and redirect browser to OpenID Server - $openid = new SimpleOpenID; + $openid = new SimpleOpenID(); $openid->SetIdentity($uid); $openid->SetTrustRoot('http://' . OCP\Util::getServerHost()); if ($openid->GetOpenIDServer()){ @@ -63,7 +63,3 @@ class OC_USER_OPENID extends OC_User_Backend { } } } - - - -?> diff --git a/apps/user_webfinger/webfinger.php b/apps/user_webfinger/webfinger.php index 6b64a7e2860..e5b7f042d5a 100644 --- a/apps/user_webfinger/webfinger.php +++ b/apps/user_webfinger/webfinger.php @@ -58,4 +58,3 @@ foreach($apps as $app) { } } echo "]}"; -?> |