diff options
263 files changed, 4182 insertions, 1494 deletions
diff --git a/.gitignore b/.gitignore index e2ff07d14d8..ae636931706 100644 --- a/.gitignore +++ b/.gitignore @@ -34,6 +34,9 @@ RCS/* # netbeans nbproject +# phpStorm +.idea + # geany *.geany diff --git a/3rdparty/Dropbox/API.php b/3rdparty/Dropbox/API.php index cff6c35c7fb..8cdce678e1c 100644 --- a/3rdparty/Dropbox/API.php +++ b/3rdparty/Dropbox/API.php @@ -139,7 +139,7 @@ class Dropbox_API { public function copy($from, $to, $root = null) {
if (is_null($root)) $root = $this->root;
- $response = $this->oauth->fetch($this->api_url . 'fileops/copy', array('from_path' => $from, 'to_path' => $to, 'root' => $root));
+ $response = $this->oauth->fetch($this->api_url . 'fileops/copy', array('from_path' => $from, 'to_path' => $to, 'root' => $root), 'POST');
return json_decode($response['body'],true);
@@ -178,7 +178,7 @@ class Dropbox_API { public function delete($path, $root = null) {
if (is_null($root)) $root = $this->root;
- $response = $this->oauth->fetch($this->api_url . 'fileops/delete', array('path' => $path, 'root' => $root));
+ $response = $this->oauth->fetch($this->api_url . 'fileops/delete', array('path' => $path, 'root' => $root), 'POST');
return json_decode($response['body']);
}
@@ -196,7 +196,7 @@ class Dropbox_API { public function move($from, $to, $root = null) {
if (is_null($root)) $root = $this->root;
- $response = $this->oauth->fetch($this->api_url . 'fileops/move', array('from_path' => rawurldecode($from), 'to_path' => rawurldecode($to), 'root' => $root));
+ $response = $this->oauth->fetch($this->api_url . 'fileops/move', array('from_path' => rawurldecode($from), 'to_path' => rawurldecode($to), 'root' => $root), 'POST');
return json_decode($response['body'],true);
diff --git a/3rdparty/Sabre/DAV/Client.php b/3rdparty/Sabre/DAV/Client.php index a8320dd9782..075e84caa1d 100644 --- a/3rdparty/Sabre/DAV/Client.php +++ b/3rdparty/Sabre/DAV/Client.php @@ -49,6 +49,7 @@ class Sabre_DAV_Client { 'proxy' ); + foreach($validSettings as $validSetting) { if (isset($settings[$validSetting])) { $this->$validSetting = $settings[$validSetting]; @@ -249,6 +250,8 @@ class Sabre_DAV_Client { // Automatically follow redirects CURLOPT_FOLLOWLOCATION => true, CURLOPT_MAXREDIRS => 5, + CURLOPT_SSL_VERIFYPEER => true, + //CURLOPT_SSL_VERIFYPEER => false, ); switch ($method) { 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 "]}"; -?> diff --git a/core/ajax/grouplist.php b/core/ajax/grouplist.php index cc15102bbc3..e3e92fcfa16 100644 --- a/core/ajax/grouplist.php +++ b/core/ajax/grouplist.php @@ -45,5 +45,3 @@ foreach( OC_Group::getGroups() as $i ){ } OC_JSON::encodedPrint($groups); - -?> diff --git a/core/ajax/translations.php b/core/ajax/translations.php index a6433b1964a..2bd6b7ed634 100644 --- a/core/ajax/translations.php +++ b/core/ajax/translations.php @@ -29,4 +29,3 @@ $app = $_POST["app"]; $l = OC_L10N::get( $app ); OC_JSON::success(array('data' => $l->getTranslations())); -?> diff --git a/core/ajax/userlist.php b/core/ajax/userlist.php index c8168eaf460..85ca004ae66 100644 --- a/core/ajax/userlist.php +++ b/core/ajax/userlist.php @@ -44,5 +44,3 @@ foreach( OC_User::getUsers() as $i ){ } OC_JSON::encodedPrint($users); - -?> diff --git a/core/ajax/validateuser.php b/core/ajax/validateuser.php index 258bd50fcad..78ec451fac2 100644 --- a/core/ajax/validateuser.php +++ b/core/ajax/validateuser.php @@ -36,5 +36,3 @@ if(!isset($_SERVER['PHP_AUTH_USER'])){ OC_JSON::encodedPrint(array("username" => $_SERVER["PHP_AUTH_USER"], "user_valid" => "false")); } } - -?> diff --git a/core/ajax/vcategories/add.php b/core/ajax/vcategories/add.php index a58489228d8..e69f8bb726b 100644 --- a/core/ajax/vcategories/add.php +++ b/core/ajax/vcategories/add.php @@ -39,5 +39,3 @@ if($categories->hasCategory($category)) { } OC_JSON::success(array('data' => array('categories'=>$categories->categories()))); - -?> diff --git a/core/ajax/vcategories/delete.php b/core/ajax/vcategories/delete.php index 75def433d30..a41fa083c38 100644 --- a/core/ajax/vcategories/delete.php +++ b/core/ajax/vcategories/delete.php @@ -34,5 +34,3 @@ if(is_null($categories)) { $vcategories = new OC_VCategories($app); $vcategories->delete($categories); OC_JSON::success(array('data' => array('categories'=>$vcategories->categories()))); - -?> diff --git a/core/ajax/vcategories/edit.php b/core/ajax/vcategories/edit.php index 252b3d3454c..3e5540cbc22 100644 --- a/core/ajax/vcategories/edit.php +++ b/core/ajax/vcategories/edit.php @@ -31,5 +31,3 @@ $categories = $vcategories->categories(); debug(print_r($categories, true)); $tmpl->assign('categories',$categories); $tmpl->printpage(); - -?> diff --git a/core/js/js.js b/core/js/js.js index 7a53bb75ef5..df834157cdb 100644 --- a/core/js/js.js +++ b/core/js/js.js @@ -67,6 +67,8 @@ OC={ if(type){ link+= '/'+type+'/'; } + if(link.substring(link.length-1) != '/') + link+='/'; link+=file; }else{ link+='/'; @@ -516,5 +518,5 @@ function formatDate(date){ } var monthNames = [ t('files','January'), t('files','February'), t('files','March'), t('files','April'), t('files','May'), t('files','June'), t('files','July'), t('files','August'), t('files','September'), t('files','October'), t('files','November'), t('files','December') ]; - return monthNames[date.getMonth()]+' '+date.getDate()+', '+date.getFullYear()+', '+((date.getHours()<10)?'0':'')+date.getHours()+':'+date.getMinutes(); + return monthNames[date.getMonth()]+' '+date.getDate()+', '+date.getFullYear()+', '+((date.getHours()<10)?'0':'')+date.getHours()+':'+((date.getMinutes()<10)?'0':'')+date.getMinutes(); } diff --git a/core/js/multiselect.js b/core/js/multiselect.js index db5afa637c9..c4fd74b0475 100644 --- a/core/js/multiselect.js +++ b/core/js/multiselect.js @@ -35,6 +35,7 @@ } button.click(function(event){ + var button=$(this); if(button.parent().children('ul').length>0){ button.parent().children('ul').slideUp(400,function(){ @@ -128,19 +129,30 @@ if(event.keyCode == 13) { event.preventDefault(); event.stopPropagation(); + var value = $(this).val(); + var exists = false; + $.each(options,function(index, item) { + if ($(item).val() == value) { + exists = true; + return false; + } + }); + if (exists) { + return false; + } var li=$(this).parent(); $(this).remove(); li.text('+ '+settings.createText); li.before(createItem(this)); var select=button.parent().next(); var option=$('<option selected="selected"/>'); - option.attr('value',$(this).val()); + option.attr('value',value); option.text($(this).val()); - select.append(options); + select.append(option); li.prev().children('input').trigger('click'); button.parent().data('preventHide',false); if(settings.createCallback){ - settings.createCallback(); + settings.createCallback($(this).val()); } } }); diff --git a/core/strings.php b/core/strings.php index 8c3f64ef14f..01ab3866089 100644 --- a/core/strings.php +++ b/core/strings.php @@ -7,4 +7,3 @@ $l->t("Users"); $l->t("Apps"); $l->t("Admin"); $l->t("Help"); -?> diff --git a/lib/MDB2/Driver/Function/sqlite3.php b/lib/MDB2/Driver/Function/sqlite3.php index a013aea165a..1af262fd7a7 100644 --- a/lib/MDB2/Driver/Function/sqlite3.php +++ b/lib/MDB2/Driver/Function/sqlite3.php @@ -134,4 +134,3 @@ class MDB2_Driver_Function_sqlite3 extends MDB2_Driver_Function_Common // }}} } -?> diff --git a/lib/MDB2/Driver/Manager/sqlite3.php b/lib/MDB2/Driver/Manager/sqlite3.php index 8f4e1312eb8..10255a3619a 100644 --- a/lib/MDB2/Driver/Manager/sqlite3.php +++ b/lib/MDB2/Driver/Manager/sqlite3.php @@ -1360,4 +1360,3 @@ class MDB2_Driver_Manager_sqlite3 extends MDB2_Driver_Manager_Common // }}} } -?> diff --git a/lib/MDB2/Driver/sqlite3.php b/lib/MDB2/Driver/sqlite3.php index 39d3fb6727d..25927aff637 100644 --- a/lib/MDB2/Driver/sqlite3.php +++ b/lib/MDB2/Driver/sqlite3.php @@ -1332,5 +1332,3 @@ class MDB2_Statement_sqlite3 extends MDB2_Statement_Common $this->free(); } } - -?> diff --git a/lib/app.php b/lib/app.php index a9feff1620a..4c2c43ec26b 100755 --- a/lib/app.php +++ b/lib/app.php @@ -36,6 +36,7 @@ class OC_App{ static private $appInfo = array(); static private $appTypes = array(); static private $loadedApps = array(); + static private $checkedApps = array(); /** * @brief loads all apps @@ -349,9 +350,13 @@ class OC_App{ protected static function findAppInDirectories($appid) { + static $app_dir = array(); + if (isset($app_dir[$appid])) { + return $app_dir[$appid]; + } foreach(OC::$APPSROOTS as $dir) { if(file_exists($dir['path'].'/'.$appid)) { - return $dir; + return $app_dir[$appid]=$dir; } } } @@ -530,6 +535,10 @@ class OC_App{ * check if the app need updating and update when needed */ public static function checkUpgrade($app) { + if (in_array($app, self::$checkedApps)) { + return; + } + self::$checkedApps[] = $app; $versions = self::getAppVersions(); $currentVersion=OC_App::getAppVersion($app); if ($currentVersion) { @@ -564,7 +573,7 @@ class OC_App{ } /** - * get the installed version of all papps + * get the installed version of all apps */ public static function getAppVersions(){ static $versions; diff --git a/lib/base.php b/lib/base.php index 11e63e208eb..fe69ad70c0f 100644 --- a/lib/base.php +++ b/lib/base.php @@ -170,8 +170,10 @@ class OC{ public static function checkInstalled() { // Redirect to installer if not installed if (!OC_Config::getValue('installed', false) && OC::$SUBURI != '/index.php') { - $url = 'http://'.$_SERVER['SERVER_NAME'].OC::$WEBROOT.'/index.php'; - header("Location: $url"); + if(!OC::$CLI){ + $url = 'http://'.$_SERVER['SERVER_NAME'].OC::$WEBROOT.'/index.php'; + header("Location: $url"); + } exit(); } } @@ -180,7 +182,7 @@ class OC{ // redirect to https site if configured if( OC_Config::getValue( "forcessl", false )){ ini_set("session.cookie_secure", "on"); - if(OC_Helper::serverProtocol()<>'https') { + if(OC_Helper::serverProtocol()<>'https' and !OC::$CLI) { $url = "https://". OC_Helper::serverHost() . $_SERVER['REQUEST_URI']; header("Location: $url"); exit(); @@ -328,21 +330,6 @@ class OC{ self::checkInstalled(); self::checkSSL(); - - // CSRF protection - if(isset($_SERVER['HTTP_REFERER'])) $referer=$_SERVER['HTTP_REFERER']; else $referer=''; - $refererhost=parse_url($referer); - if(isset($refererhost['host'])) $refererhost=$refererhost['host']; else $refererhost=''; - $server=OC_Helper::serverHost(); - $serverhost=explode(':',$server); - $serverhost=$serverhost['0']; - if(!self::$CLI){ - if(($_SERVER['REQUEST_METHOD']=='POST') and ($refererhost<>$serverhost)) { - $url = OC_Helper::serverProtocol().'://'.$server.OC::$WEBROOT.'/index.php'; - header("Location: $url"); - exit(); - } - } self::initSession(); self::initTemplateEngine(); self::checkUpgrade(); diff --git a/lib/connector/sabre/client.php b/lib/connector/sabre/client.php new file mode 100644 index 00000000000..87f9d59b3ae --- /dev/null +++ b/lib/connector/sabre/client.php @@ -0,0 +1,171 @@ +<?php
+
+/**
+ * ownCloud
+ *
+ * @author Bjoern Schiessle
+ * @copyright 2012 Bjoern Schiessle <schiessle@owncloud.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 Affero General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+class OC_Connector_Sabre_Client extends Sabre_DAV_Client {
+
+ protected $trustedCertificates;
+
+ /**
+ * Add trusted root certificates to the webdav client.
+ *
+ * The parameter certificates should be a absulute path to a file which contains
+ * all trusted certificates
+ *
+ * @param string $certificates
+ */
+ public function addTrustedCertificates($certificates) {
+ $this->trustedCertificates = $certificates;
+ }
+
+ /**
+ * Copied from SabreDAV with some modification to use user defined curlSettings
+ * Performs an actual HTTP request, and returns the result.
+ *
+ * If the specified url is relative, it will be expanded based on the base
+ * url.
+ *
+ * The returned array contains 3 keys:
+ * * body - the response body
+ * * httpCode - a HTTP code (200, 404, etc)
+ * * headers - a list of response http headers. The header names have
+ * been lowercased.
+ *
+ * @param string $method
+ * @param string $url
+ * @param string $body
+ * @param array $headers
+ * @return array
+ */
+ public function request($method, $url = '', $body = null, $headers = array()) {
+
+ $url = $this->getAbsoluteUrl($url);
+
+ $curlSettings = array(
+ CURLOPT_RETURNTRANSFER => true,
+ // Return headers as part of the response
+ CURLOPT_HEADER => true,
+ CURLOPT_POSTFIELDS => $body,
+ // Automatically follow redirects
+ CURLOPT_FOLLOWLOCATION => true,
+ CURLOPT_MAXREDIRS => 5,
+ CURLOPT_SSL_VERIFYPEER => true,
+ //CURLOPT_SSL_VERIFYPEER => false,
+ );
+
+ if($this->trustedCertificates) {
+ $curlSettings[CURLOPT_CAINFO] = $this->trustedCertificates;
+ }
+
+ switch ($method) {
+ case 'PUT':
+ $curlSettings[CURLOPT_PUT] = true;
+ break;
+ case 'HEAD' :
+
+ // do not read body with HEAD requests (this is neccessary because cURL does not ignore the body with HEAD
+ // requests when the Content-Length header is given - which in turn is perfectly valid according to HTTP
+ // specs...) cURL does unfortunately return an error in this case ("transfer closed transfer closed with
+ // ... bytes remaining to read") this can be circumvented by explicitly telling cURL to ignore the
+ // response body
+ $curlSettings[CURLOPT_NOBODY] = true;
+ $curlSettings[CURLOPT_CUSTOMREQUEST] = 'HEAD';
+ break;
+
+ default:
+ $curlSettings[CURLOPT_CUSTOMREQUEST] = $method;
+ break;
+
+ }
+
+ // Adding HTTP headers
+ $nHeaders = array();
+ foreach($headers as $key=>$value) {
+
+ $nHeaders[] = $key . ': ' . $value;
+
+ }
+ $curlSettings[CURLOPT_HTTPHEADER] = $nHeaders;
+
+ if ($this->proxy) {
+ $curlSettings[CURLOPT_PROXY] = $this->proxy;
+ }
+
+ if ($this->userName) {
+ $curlSettings[CURLOPT_HTTPAUTH] = CURLAUTH_BASIC | CURLAUTH_DIGEST;
+ $curlSettings[CURLOPT_USERPWD] = $this->userName . ':' . $this->password;
+ }
+
+ list(
+ $response,
+ $curlInfo,
+ $curlErrNo,
+ $curlError
+ ) = $this->curlRequest($url, $curlSettings);
+
+ $headerBlob = substr($response, 0, $curlInfo['header_size']);
+ $response = substr($response, $curlInfo['header_size']);
+
+ // In the case of 100 Continue, or redirects we'll have multiple lists
+ // of headers for each separate HTTP response. We can easily split this
+ // because they are separated by \r\n\r\n
+ $headerBlob = explode("\r\n\r\n", trim($headerBlob, "\r\n"));
+
+ // We only care about the last set of headers
+ $headerBlob = $headerBlob[count($headerBlob)-1];
+
+ // Splitting headers
+ $headerBlob = explode("\r\n", $headerBlob);
+
+ $headers = array();
+ foreach($headerBlob as $header) {
+ $parts = explode(':', $header, 2);
+ if (count($parts)==2) {
+ $headers[strtolower(trim($parts[0]))] = trim($parts[1]);
+ }
+ }
+
+ $response = array(
+ 'body' => $response,
+ 'statusCode' => $curlInfo['http_code'],
+ 'headers' => $headers
+ );
+
+ if ($curlErrNo) {
+ throw new Sabre_DAV_Exception('[CURL] Error while making request: ' . $curlError . ' (error code: ' . $curlErrNo . ')');
+ }
+
+ if ($response['statusCode']>=400) {
+ switch ($response['statusCode']) {
+ case 404:
+ throw new Sabre_DAV_Exception_NotFound('Resource ' . $url . ' not found.');
+ break;
+
+ default:
+ throw new Sabre_DAV_Exception('HTTP error response. (errorcode ' . $response['statusCode'] . ')');
+ }
+ }
+
+ return $response;
+
+ }
+}
\ No newline at end of file diff --git a/lib/connector/sabre/directory.php b/lib/connector/sabre/directory.php index 9832449af3a..b75bb5c50f5 100644 --- a/lib/connector/sabre/directory.php +++ b/lib/connector/sabre/directory.php @@ -90,16 +90,18 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa foreach($folder_content as $info) { $paths[] = $this->path.'/'.$info['name']; } - $placeholders = join(',', array_fill(0, count($paths), '?')); - $query = OC_DB::prepare( 'SELECT * FROM *PREFIX*properties WHERE userid = ?' . ' AND propertypath IN ('.$placeholders.')' ); - array_unshift($paths, OC_User::getUser()); // prepend userid - $result = $query->execute( $paths ); $properties = array_fill_keys($paths, array()); - while($row = $result->fetchRow()) { - $propertypath = $row['propertypath']; - $propertyname = $row['propertyname']; - $propertyvalue = $row['propertyvalue']; - $properties[$propertypath][$propertyname] = $propertyvalue; + if(count($paths)>0){ + $placeholders = join(',', array_fill(0, count($paths), '?')); + $query = OC_DB::prepare( 'SELECT * FROM *PREFIX*properties WHERE userid = ?' . ' AND propertypath IN ('.$placeholders.')' ); + array_unshift($paths, OC_User::getUser()); // prepend userid + $result = $query->execute( $paths ); + while($row = $result->fetchRow()) { + $propertypath = $row['propertypath']; + $propertyname = $row['propertyname']; + $propertyvalue = $row['propertyvalue']; + $properties[$propertypath][$propertyname] = $propertyvalue; + } } $nodes = array(); diff --git a/lib/connector/sabre/file.php b/lib/connector/sabre/file.php index dd25df78c29..e4dc8c93445 100644 --- a/lib/connector/sabre/file.php +++ b/lib/connector/sabre/file.php @@ -42,7 +42,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D */ public function get() { - return OC_Filesystem::fopen($this->path,'r'); + return OC_Filesystem::readfile($this->path); } diff --git a/lib/db.php b/lib/db.php index 9e6835adc6f..2a06d72ea32 100644 --- a/lib/db.php +++ b/lib/db.php @@ -128,6 +128,14 @@ class OC_DB { }else{ $dsn='pgsql:dbname='.$name.';host='.$host; } + /** + * Ugly fix for pg connections pbm when password use spaces + */ + $e_user = addslashes($user); + $e_password = addslashes($pass); + $pass = $user = null; + $dsn .= ";user='$e_user';password='$e_password'"; + /** END OF FIX***/ break; } try{ @@ -528,7 +536,7 @@ class OC_DB { self::removeDBStructure( OC::$SERVERROOT . '/db_structure.xml' ); foreach($apps as $app){ - $path = self::getAppPath($app).'/appinfo/database.xml'; + $path = OC_App::getAppPath($app).'/appinfo/database.xml'; if(file_exists($path)){ self::removeDBStructure( $path ); } diff --git a/lib/files.php b/lib/files.php index 4f58ff6782d..f7a7aecc167 100644 --- a/lib/files.php +++ b/lib/files.php @@ -186,10 +186,12 @@ class OC_Files { * @param file $target */ public static function move($sourceDir,$source,$targetDir,$target){ - if(OC_User::isLoggedIn() && ($sourceDir != '' || $source != 'Shared')){ + if(OC_User::isLoggedIn() && ($sourceDir != '' || $source != 'Shared') && !OC_Filesystem::file_exists($targetDir.'/'.$target)){ $targetFile=self::normalizePath($targetDir.'/'.$target); $sourceFile=self::normalizePath($sourceDir.'/'.$source); return OC_Filesystem::rename($sourceFile,$targetFile); + } else { + return false; } } diff --git a/lib/filesystem.php b/lib/filesystem.php index 0ab3bd69acd..65318fa3ab6 100644 --- a/lib/filesystem.php +++ b/lib/filesystem.php @@ -153,6 +153,7 @@ class OC_Filesystem{ if($path[0]!=='/'){ $path='/'.$path; } + $path=str_replace('//', '/',$path); $foundMountPoint=''; foreach(OC_Filesystem::$mounts as $mountpoint=>$storage){ if($mountpoint==$path){ diff --git a/lib/filesystemview.php b/lib/filesystemview.php index 99e08c50e75..448663bb081 100644 --- a/lib/filesystemview.php +++ b/lib/filesystemview.php @@ -276,7 +276,7 @@ class OC_FilesystemView { }else{ $source=$this->fopen($path1,'r'); $target=$this->fopen($path2,'w'); - $count=OC_Helper::streamCopy($data,$target); + $count=OC_Helper::streamCopy($source,$target); $storage1=$this->getStorage($path1); $storage1->unlink($this->getInternalPath($path1)); $result=$count>0; @@ -314,7 +314,7 @@ class OC_FilesystemView { }else{ $source=$this->fopen($path1,'r'); $target=$this->fopen($path2,'w'); - $count=OC_Helper::streamCopy($data,$target); + $result=OC_Helper::streamCopy($source,$target); } OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_copy, array( OC_Filesystem::signal_param_oldpath => $path1 , OC_Filesystem::signal_param_newpath=>$path2)); if(!$exists){ diff --git a/lib/helper.php b/lib/helper.php index 37914b73e17..0d18098a4e7 100644 --- a/lib/helper.php +++ b/lib/helper.php @@ -38,21 +38,18 @@ class OC_Helper { */ public static function linkTo( $app, $file ){ if( $app != '' ){ - $app .= '/'; + $app_path = OC_App::getAppPath($app); // Check if the app is in the app folder - if( file_exists( OC_App::getAppPath($app).'/'.$file )){ - if(substr($file, -3) == 'php' || substr($file, -3) == 'css'){ - if(substr($app, -1, 1) == '/'){ - $app = substr($app, 0, strlen($app) - 1); - } + if( $app_path && file_exists( $app_path.'/'.$file )){ + if(substr($file, -3) == 'php' || substr($file, -3) == 'css'){ $urlLinkTo = OC::$WEBROOT . '/?app=' . $app; $urlLinkTo .= ($file!='index.php')?'&getfile=' . urlencode($file):''; }else{ - $urlLinkTo = OC_App::getAppWebPath($app) . $file; + $urlLinkTo = OC_App::getAppWebPath($app) . '/' . $file; } } else{ - $urlLinkTo = OC::$WEBROOT . '/' . $app . $file; + $urlLinkTo = OC::$WEBROOT . '/' . $app . '/' . $file; } } else{ @@ -75,6 +72,9 @@ class OC_Helper { * reverse proxies */ public static function serverHost() { + if(OC::$CLI){ + return 'localhost'; + } if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) { if (strpos($_SERVER['HTTP_X_FORWARDED_HOST'], ",") !== false) { $host = trim(array_pop(explode(",", $_SERVER['HTTP_X_FORWARDED_HOST']))); @@ -379,7 +379,7 @@ class OC_Helper { //trim the character set from the end of the response $mimeType=substr($reply,0,strrpos($reply,' ')); - //trim ; + //trim ; if (strpos($mimeType, ';') !== false) { $mimeType = strstr($mimeType, ';', true); } @@ -586,11 +586,11 @@ class OC_Helper { return $newpath; } - + /* * checks if $sub is a subdirectory of $parent - * - * @param $sub + * + * @param $sub * @param $parent * @return bool */ @@ -620,4 +620,68 @@ class OC_Helper { exit;*/ return false; } + + /** + * @brief Returns an array with all keys from input lowercased or uppercased. Numbered indices are left as is. + * + * @param $input The array to work on + * @param $case Either MB_CASE_UPPER or MB_CASE_LOWER (default) + * @param $encoding The encoding parameter is the character encoding. Defaults to UTF-8 + * @return array + * + * Returns an array with all keys from input lowercased or uppercased. Numbered indices are left as is. + * based on http://www.php.net/manual/en/function.array-change-key-case.php#107715 + * + */ + public static function mb_array_change_key_case($input, $case = MB_CASE_LOWER, $encoding = 'UTF-8'){ + $case = ($case != MB_CASE_UPPER) ? MB_CASE_LOWER : MB_CASE_UPPER; + $ret = array(); + foreach ($input as $k => $v) { + $ret[mb_convert_case($k, $case, $encoding)] = $v; + } + return $ret; + } + + /** + * @brief replaces a copy of string delimited by the start and (optionally) length parameters with the string given in replacement. + * + * @param $input The input string. .Opposite to the PHP build-in function does not accept an array. + * @param $replacement The replacement string. + * @param $start If start is positive, the replacing will begin at the start'th offset into string. If start is negative, the replacing will begin at the start'th character from the end of string. + * @param $length Length of the part to be replaced + * @param $encoding The encoding parameter is the character encoding. Defaults to UTF-8 + * @return string + * + */ + public static function mb_substr_replace($string, $replacement, $start, $length = null, $encoding = 'UTF-8') { + $start = intval($start); + $length = intval($length); + $string = mb_substr($string, 0, $start, $encoding) . + $replacement . + mb_substr($string, $start+$length, mb_strlen($string, 'UTF-8')-$start, $encoding); + + return $string; + } + + /** + * @brief Replace all occurrences of the search string with the replacement string + * + * @param $search The value being searched for, otherwise known as the needle. String. + * @param $replace The replacement string. + * @param $subject The string or array being searched and replaced on, otherwise known as the haystack. + * @param $encoding The encoding parameter is the character encoding. Defaults to UTF-8 + * @param $count If passed, this will be set to the number of replacements performed. + * @return string + * + */ + public static function mb_str_replace($search, $replace, $subject, $encoding = 'UTF-8', &$count = null) { + $offset = -1; + $length = mb_strlen($search, 'UTF-8'); + while(($i = mb_strrpos($subject, $search, $offset, 'UTF-8'))) { + $subject = OC_Helper::mb_substr_replace($subject, $replace, $i, $length); + $offset = $i - mb_strlen($subject, 'UTF-8') - 1; + $count++; + } + return $subject; + } } diff --git a/lib/image.php b/lib/image.php index e5c59bacdc5..01e843d8316 100644 --- a/lib/image.php +++ b/lib/image.php @@ -108,6 +108,56 @@ class OC_Image { } /** + * @brief Returns the width when the image orientation is top-left. + * @returns int + */ + public function widthTopLeft() { + $o = $this->getOrientation(); + OC_Log::write('core','OC_Image->widthTopLeft() Orientation: '.$o, OC_Log::DEBUG); + switch($o) { + case -1: + case 1: + case 2: // Not tested + case 3: + case 4: // Not tested + return $this->width(); + break; + case 5: // Not tested + case 6: + case 7: // Not tested + case 8: + return $this->height(); + break; + } + return $this->width(); + } + + /** + * @brief Returns the height when the image orientation is top-left. + * @returns int + */ + public function heightTopLeft() { + $o = $this->getOrientation(); + OC_Log::write('core','OC_Image->heightTopLeft() Orientation: '.$o, OC_Log::DEBUG); + switch($o) { + case -1: + case 1: + case 2: // Not tested + case 3: + case 4: // Not tested + return $this->height(); + break; + case 5: // Not tested + case 6: + case 7: // Not tested + case 8: + return $this->width(); + break; + } + return $this->height(); + } + + /** * @brief Outputs the image. * @returns bool */ @@ -209,34 +259,46 @@ class OC_Image { /** * (I'm open for suggestions on better method name ;) - * @brief Fixes orientation based on EXIF data. - * @returns bool. + * @brief Get the orientation based on EXIF data. + * @returns The orientation or -1 if no EXIF data is available. */ - public function fixOrientation() { + public function getOrientation() { if(!is_callable('exif_read_data')){ OC_Log::write('core','OC_Image->fixOrientation() Exif module not enabled.', OC_Log::DEBUG); - return false; + return -1; } if(!$this->valid()) { OC_Log::write('core','OC_Image->fixOrientation() No image loaded.', OC_Log::DEBUG); - return false; + return -1; } if(is_null($this->filepath) || !is_readable($this->filepath)) { OC_Log::write('core','OC_Image->fixOrientation() No readable file path set.', OC_Log::DEBUG); - return false; + return -1; } $exif = @exif_read_data($this->filepath, 'IFD0'); if(!$exif) { - return false; + return -1; } if(!isset($exif['Orientation'])) { - return true; // Nothing to fix + return -1; } - $o = $exif['Orientation']; + return $exif['Orientation']; + } + + /** + * (I'm open for suggestions on better method name ;) + * @brief Fixes orientation based on EXIF data. + * @returns bool. + */ + public function fixOrientation() { + $o = $this->getOrientation(); OC_Log::write('core','OC_Image->fixOrientation() Orientation: '.$o, OC_Log::DEBUG); $rotate = 0; $flip = false; switch($o) { + case -1: + return false; //Nothing to fix + break; case 1: $rotate = 0; $flip = false; diff --git a/lib/json.php b/lib/json.php index 4eab4fce9f6..c49b831c12b 100644 --- a/lib/json.php +++ b/lib/json.php @@ -94,12 +94,12 @@ class OC_JSON{ * Encode and print $data in json format */ public static function encodedPrint($data,$setContentType=true){ - if(!isset($_SERVER['PATH_INFO']) || $_SERVER['PATH_INFO'] == '') { + // Disable mimesniffing, don't move this to setContentTypeHeader! + header( 'X-Content-Type-Options: nosniff' ); if($setContentType){ self::setContentTypeHeader(); } array_walk_recursive($data, array('OC_JSON', 'to_string')); echo json_encode($data); - } } } diff --git a/lib/l10n.php b/lib/l10n.php index 4acbc5dcebc..de8514573d3 100644 --- a/lib/l10n.php +++ b/lib/l10n.php @@ -113,13 +113,13 @@ class OC_L10N{ $i18ndir = self::findI18nDir($app); // Localization is in /l10n, Texts are in $i18ndir // (Just no need to define date/time format etc. twice) - if(file_exists($i18ndir.$lang.'.php')){ + if((OC_Helper::issubdirectory($i18ndir.$lang.'.php', OC_App::getAppPath($app).'/l10n/') || OC_Helper::issubdirectory($i18ndir.$lang.'.php', OC::$SERVERROOT.'/core/l10n/') || OC_Helper::issubdirectory($i18ndir.$lang.'.php', OC::$SERVERROOT.'/settings')) && file_exists($i18ndir.$lang.'.php')) { // Include the file, save the data from $CONFIG - include($i18ndir.$lang.'.php'); + include(strip_tags($i18ndir).strip_tags($lang).'.php'); if(isset($TRANSLATIONS) && is_array($TRANSLATIONS)){ $this->translations = $TRANSLATIONS; } - } + } if(file_exists(OC::$SERVERROOT.'/core/l10n/l10n-'.$lang.'.php')){ // Include the file, save the data from $CONFIG diff --git a/lib/log/owncloud.php b/lib/log/owncloud.php index 92914af8fca..9eb21832c55 100644 --- a/lib/log/owncloud.php +++ b/lib/log/owncloud.php @@ -63,25 +63,40 @@ class OC_Log_Owncloud { self::init(); $minLevel=OC_Config::getValue( "loglevel", OC_Log::WARN ); $entries = array(); - $handle = @fopen(self::$logFile, 'r'); + $handle = @fopen(self::$logFile, 'rb'); if ($handle) { - // Just a guess to set the file pointer to the right spot - $maxLineLength = 150; - fseek($handle, -($limit * $maxLineLength + $offset * $maxLineLength), SEEK_END); - // Skip first line, because it is most likely a partial line - fgets($handle); - while (!feof($handle)) { - $line = fgets($handle); - if (!empty($line)) { - $entry = json_decode($line); - if ($entry->level >= $minLevel) { - $entries[] = $entry; + fseek($handle, 0, SEEK_END); + $pos = ftell($handle); + $line = ''; + $entriesCount = 0; + $lines = 0; + // Loop through each character of the file looking for new lines + while ($pos >= 0 && $entriesCount < $limit) { + fseek($handle, $pos); + $ch = fgetc($handle); + if ($ch == "\n" || $pos == 0) { + if ($line != '') { + // Add the first character if at the start of the file, because it doesn't hit the else in the loop + if ($pos == 0) { + $line = $ch.$line; + } + $entry = json_decode($line); + // Add the line as an entry if it is passed the offset and is equal or above the log level + if ($entry->level >= $minLevel) { + $lines++; + if ($lines > $offset) { + $entries[] = $entry; + $entriesCount++; + } + } + $line = ''; } + } else { + $line = $ch.$line; } + $pos--; } fclose($handle); - // Extract the needed entries and reverse the order - $entries = array_reverse(array_slice($entries, -($limit + $offset), $limit)); } return $entries; } diff --git a/lib/mail.php b/lib/mail.php index 7343f5f0d97..7eb2c4770c5 100644 --- a/lib/mail.php +++ b/lib/mail.php @@ -36,7 +36,7 @@ class OC_Mail { $SMTPPASSWORD = OC_Config::getValue( 'mail_smtppassword', '' ); - $mailo = new PHPMailer(); + $mailo = new PHPMailer(true); if($SMTPMODE=='sendmail') { $mailo->IsSendmail(); }elseif($SMTPMODE=='smtp'){ @@ -56,33 +56,35 @@ class OC_Mail { $mailo->From =$fromaddress; $mailo->FromName = $fromname;; $a=explode(' ',$toaddress); - foreach($a as $ad) { - $mailo->AddAddress($ad,$toname); + try { + foreach($a as $ad) { + $mailo->AddAddress($ad,$toname); + } + + if($ccaddress<>'') $mailo->AddCC($ccaddress,$ccname); + if($bcc<>'') $mailo->AddBCC($bcc); + + $mailo->AddReplyTo($fromaddress, $fromname); + + $mailo->WordWrap = 50; + if($html==1) $mailo->IsHTML(true); else $mailo->IsHTML(false); + + $mailo->Subject = $subject; + if($altbody=='') { + $mailo->Body = $mailtext.OC_MAIL::getfooter(); + $mailo->AltBody = ''; + }else{ + $mailo->Body = $mailtext; + $mailo->AltBody = $altbody; + } + $mailo->CharSet = 'UTF-8'; + + $mailo->Send(); + unset($mailo); + OC_Log::write('mail', 'Mail from '.$fromname.' ('.$fromaddress.')'.' to: '.$toname.'('.$toaddress.')'.' subject: '.$subject, OC_Log::DEBUG); + } catch (Exception $exception) { + OC_Log::write('mail', $exception->getMessage(), OC_Log::DEBUG); } - - if($ccaddress<>'') $mailo->AddCC($ccaddress,$ccname); - if($bcc<>'') $mailo->AddBCC($bcc); - - $mailo->AddReplyTo($fromaddress, $fromname); - - $mailo->WordWrap = 50; - if($html==1) $mailo->IsHTML(true); else $mailo->IsHTML(false); - - $mailo->Subject = $subject; - if($altbody=='') { - $mailo->Body = $mailtext.OC_MAIL::getfooter(); - $mailo->AltBody = ''; - }else{ - $mailo->Body = $mailtext; - $mailo->AltBody = $altbody; - } - $mailo->CharSet = 'UTF-8'; - - $mailo->Send(); - unset($mailo); - - OC_Log::write('Mail from '.$fromname.' ('.$fromaddress.')'.' to: '.$toname.'('.$toaddress.')'.' subject: '.$subject,'mail',OC_Log::DEBUG); - } diff --git a/lib/migrate.php b/lib/migrate.php index f26b4b25673..f788a637d3c 100644 --- a/lib/migrate.php +++ b/lib/migrate.php @@ -64,7 +64,7 @@ class OC_Migrate{ $apps = OC_App::getAllApps(); foreach($apps as $app){ - $path = self::getAppPath($app) . '/appinfo/migrate.php'; + $path = OC_App::getAppPath($app) . '/appinfo/migrate.php'; if( file_exists( $path ) ){ include( $path ); } @@ -278,7 +278,7 @@ class OC_Migrate{ return json_encode( array( 'success' => false ) ); } // Done - return json_encode( 'success' => true ); + return json_encode( array( 'success' => true ) ); */ break; } @@ -398,7 +398,7 @@ class OC_Migrate{ if( OC_App::isEnabled( $provider->getID() ) ){ $success = true; // Does this app use the database? - if( file_exists( self::getAppPath($provider->getID()).'/appinfo/database.xml' ) ){ + if( file_exists( OC_App::getAppPath($provider->getID()).'/appinfo/database.xml' ) ){ // Create some app tables $tables = self::createAppTables( $provider->getID() ); if( is_array( $tables ) ){ @@ -443,21 +443,10 @@ class OC_Migrate{ 'ocversion' => OC_Util::getVersion(), 'exporttime' => time(), 'exportedby' => OC_User::getUser(), - 'exporttype' => self::$exporttype + 'exporttype' => self::$exporttype, + 'exporteduser' => self::$uid ); - // Add hash if user export - if( self::$exporttype == 'user' ){ - $query = OC_DB::prepare( "SELECT password FROM *PREFIX*users WHERE uid = ?" ); - $result = $query->execute( array( self::$uid ) ); - $row = $result->fetchRow(); - $hash = $row ? $row['password'] : false; - if( !$hash ){ - OC_Log::write( 'migration', 'Failed to get the users password hash', OC_log::ERROR); - return false; - } - $info['hash'] = $hash; - $info['exporteduser'] = self::$uid; - } + if( !is_array( $array ) ){ OC_Log::write( 'migration', 'Supplied $array was not an array in getExportInfo()', OC_Log::ERROR ); } @@ -539,7 +528,7 @@ class OC_Migrate{ } // There is a database.xml file - $content = file_get_contents(self::getAppPath($appid) . '/appinfo/database.xml' ); + $content = file_get_contents(OC_App::getAppPath($appid) . '/appinfo/database.xml' ); $file2 = 'static://db_scheme'; // TODO get the relative path to migration.db from the data dir diff --git a/lib/public/app.php b/lib/public/app.php index 9e2108818bf..38c51af9cdb 100644 --- a/lib/public/app.php +++ b/lib/public/app.php @@ -158,6 +158,3 @@ class App { } - - -?> diff --git a/lib/public/config.php b/lib/public/config.php index 9f5abe672cb..ab01902ffe6 100644 --- a/lib/public/config.php +++ b/lib/public/config.php @@ -134,5 +134,3 @@ class Config { } - -?> diff --git a/lib/public/db.php b/lib/public/db.php index f7564c0bb6a..3a33f7674d8 100644 --- a/lib/public/db.php +++ b/lib/public/db.php @@ -91,5 +91,3 @@ class DB { } - -?> diff --git a/lib/public/files.php b/lib/public/files.php index fc3004434ba..32b3f036744 100644 --- a/lib/public/files.php +++ b/lib/public/files.php @@ -115,5 +115,3 @@ class Files { } - -?> diff --git a/lib/public/json.php b/lib/public/json.php index b6edbd65bd5..1bc1e3ab4d5 100644 --- a/lib/public/json.php +++ b/lib/public/json.php @@ -105,5 +105,3 @@ class JSON { } } - -?> diff --git a/lib/public/response.php b/lib/public/response.php index cc2137c5cae..8dff3bcd354 100644 --- a/lib/public/response.php +++ b/lib/public/response.php @@ -105,5 +105,3 @@ class Response { } - -?> diff --git a/lib/public/template.php b/lib/public/template.php index b89088bdd06..a0ed618cb2c 100644 --- a/lib/public/template.php +++ b/lib/public/template.php @@ -104,6 +104,3 @@ function html_select_options($options, $selected, $params=array()) { class Template extends \OC_Template { } - - -?> diff --git a/lib/public/user.php b/lib/public/user.php index a0c069f7379..713e366b968 100644 --- a/lib/public/user.php +++ b/lib/public/user.php @@ -120,6 +120,3 @@ class User { } - - -?> diff --git a/lib/public/util.php b/lib/public/util.php index c611d59a533..43f9e3cee5d 100644 --- a/lib/public/util.php +++ b/lib/public/util.php @@ -26,7 +26,7 @@ * */ -// use OCP namespace for all classes that are considered public. +// use OCP namespace for all classes that are considered public. // This means that they should be used by apps instead of the internal ownCloud classes namespace OCP; @@ -54,7 +54,7 @@ class Util { /** - * @brief send an email + * @brief send an email * @param string $toaddress * @param string $toname * @param string $subject @@ -264,18 +264,60 @@ class Util { public static function callCheck(){ return(\OC_Util::callCheck()); } - - /**
- * @brief Used to sanitize HTML
- *
- * This function is used to sanitize HTML and should be applied on any string or array of strings before displaying it on a web page.
- *
- * @param string or array of strings
- * @return array with sanitized strings or a single sinitized string, depends on the input parameter.
- */
- public static function sanitizeHTML( $value ){
- return(\OC_Util::sanitizeHTML($value));
+ + /** + * @brief Used to sanitize HTML + * + * This function is used to sanitize HTML and should be applied on any string or array of strings before displaying it on a web page. + * + * @param string or array of strings + * @return array with sanitized strings or a single sinitized string, depends on the input parameter. + */ + public static function sanitizeHTML( $value ){ + return(\OC_Util::sanitizeHTML($value)); + } + + /** + * @brief Returns an array with all keys from input lowercased or uppercased. Numbered indices are left as is. + * + * @param $input The array to work on + * @param $case Either MB_CASE_UPPER or MB_CASE_LOWER (default) + * @param $encoding The encoding parameter is the character encoding. Defaults to UTF-8 + * @return array + * + * + */ + public static function mb_array_change_key_case($input, $case = MB_CASE_LOWER, $encoding = 'UTF-8'){ + return(\OC_Helper::mb_array_change_key_case($input, $case, $encoding)); } -} -?> + /** + * @brief replaces a copy of string delimited by the start and (optionally) length parameters with the string given in replacement. + * + * @param $input The input string. .Opposite to the PHP build-in function does not accept an array. + * @param $replacement The replacement string. + * @param $start If start is positive, the replacing will begin at the start'th offset into string. If start is negative, the replacing will begin at the start'th character from the end of string. + * @param $length Length of the part to be replaced + * @param $encoding The encoding parameter is the character encoding. Defaults to UTF-8 + * @return string + * + */ + public static function mb_substr_replace($string, $replacement, $start, $length = null, $encoding = 'UTF-8') { + return(\OC_Helper::mb_substr_replace($string, $replacement, $start, $length, $encoding)); + } + + /** + * @brief Replace all occurrences of the search string with the replacement string + * + * @param $search The value being searched for, otherwise known as the needle. String. + * @param $replace The replacement string. + * @param $subject The string or array being searched and replaced on, otherwise known as the haystack. + * @param $encoding The encoding parameter is the character encoding. Defaults to UTF-8 + * @param $count If passed, this will be set to the number of replacements performed. + * @return string + * + */ + public static function mb_str_replace($search, $replace, $subject, $encoding = 'UTF-8', &$count = null) { + return(\OC_Helper::mb_str_replace($search, $replace, $subject, $encoding, $count)); + } +} diff --git a/lib/setup.php b/lib/setup.php index 5f1fb1525ec..2f73c486c9c 100644 --- a/lib/setup.php +++ b/lib/setup.php @@ -150,23 +150,28 @@ class OC_Setup { $dbpass = $options['dbpass']; $dbname = $options['dbname']; $dbhost = $options['dbhost']; - $dbtableprefix = $options['dbtableprefix']; + $dbtableprefix = isset($options['dbtableprefix']) ? $options['dbtableprefix'] : 'oc_'; OC_CONFIG::setValue('dbname', $dbname); OC_CONFIG::setValue('dbhost', $dbhost); OC_CONFIG::setValue('dbtableprefix', $dbtableprefix); + $e_host = addslashes($dbhost); + $e_user = addslashes($dbuser); + $e_password = addslashes($dbpass); //check if the database user has admin right - $connection_string = "host=$dbhost dbname=postgres user=$dbuser password=$dbpass"; + $connection_string = "host='$e_host' dbname=postgres user='$e_user' password='$e_password'"; $connection = @pg_connect($connection_string); if(!$connection) { $error[] = array( 'error' => 'PostgreSQL username and/or password not valid', 'hint' => 'You need to enter either an existing account or the administrator.' ); + return $error; } else { + $e_user = pg_escape_string($dbuser); //check for roles creation rights in postgresql - $query="SELECT 1 FROM pg_roles WHERE rolcreaterole=TRUE AND rolname='$dbuser'"; + $query="SELECT 1 FROM pg_roles WHERE rolcreaterole=TRUE AND rolname='$e_user'"; $result = pg_query($connection, $query); if($result and pg_num_rows($result) > 0) { //use the admin login data for the new database user @@ -198,7 +203,13 @@ class OC_Setup { // connect to the ownCloud database (dbname=$dbname) an check if it needs to be filled $dbuser = OC_CONFIG::getValue('dbuser'); $dbpass = OC_CONFIG::getValue('dbpassword'); - $connection_string = "host=$dbhost dbname=$dbname user=$dbuser password=$dbpass"; + + $e_host = addslashes($dbhost); + $e_dbname = addslashes($dbname); + $e_user = addslashes($dbuser); + $e_password = addslashes($dbpass); + + $connection_string = "host='$e_host' dbname='$e_dbname' user='$e_user' password='$e_password'"; $connection = @pg_connect($connection_string); if(!$connection) { $error[] = array( @@ -284,13 +295,23 @@ class OC_Setup { //we cant use OC_BD functions here because we need to connect as the administrative user. $e_name = pg_escape_string($name); $e_user = pg_escape_string($user); - $query = "CREATE DATABASE \"$e_name\" OWNER \"$e_user\""; + $query = "select datname from pg_database where datname = '$e_name'"; $result = pg_query($connection, $query); if(!$result) { $entry='DB Error: "'.pg_last_error($connection).'"<br />'; $entry.='Offending command was: '.$query.'<br />'; echo($entry); } + if(! pg_fetch_row($result)) { + //The database does not exists... let's create it + $query = "CREATE DATABASE \"$e_name\" OWNER \"$e_user\""; + $result = pg_query($connection, $query); + if(!$result) { + $entry='DB Error: "'.pg_last_error($connection).'"<br />'; + $entry.='Offending command was: '.$query.'<br />'; + echo($entry); + } + } $query = "REVOKE ALL PRIVILEGES ON DATABASE \"$e_name\" FROM PUBLIC"; $result = pg_query($connection, $query); } @@ -298,13 +319,33 @@ class OC_Setup { private static function pg_createDBUser($name,$password,$connection) { $e_name = pg_escape_string($name); $e_password = pg_escape_string($password); - $query = "CREATE USER \"$e_name\" CREATEDB PASSWORD '$e_password';"; + $query = "select * from pg_roles where rolname='$e_name';"; $result = pg_query($connection, $query); if(!$result) { $entry='DB Error: "'.pg_last_error($connection).'"<br />'; $entry.='Offending command was: '.$query.'<br />'; echo($entry); } + + if(! pg_fetch_row($result)) { + //user does not exists let's create it :) + $query = "CREATE USER \"$e_name\" CREATEDB PASSWORD '$e_password';"; + $result = pg_query($connection, $query); + if(!$result) { + $entry='DB Error: "'.pg_last_error($connection).'"<br />'; + $entry.='Offending command was: '.$query.'<br />'; + echo($entry); + } + } + else { // change password of the existing role + $query = "ALTER ROLE \"$e_name\" WITH PASSWORD '$e_password';"; + $result = pg_query($connection, $query); + if(!$result) { + $entry='DB Error: "'.pg_last_error($connection).'"<br />'; + $entry.='Offending command was: '.$query.'<br />'; + echo($entry); + } + } } /** @@ -339,5 +380,3 @@ class OC_Setup { file_put_contents(OC_Config::getValue('datadirectory', OC::$SERVERROOT.'/data').'/index.html', ''); } } - -?> diff --git a/lib/updater.php b/lib/updater.php index 5d97178c30e..332cea03bfc 100644 --- a/lib/updater.php +++ b/lib/updater.php @@ -84,4 +84,3 @@ class OC_Updater{ } } -?> diff --git a/lib/user.php b/lib/user.php index 23b88aa1d06..f1903093d6d 100644 --- a/lib/user.php +++ b/lib/user.php @@ -240,17 +240,13 @@ class OC_User { * Checks if the user is logged in */ public static function isLoggedIn(){ - static $is_login_checked = null; - if (!is_null($is_login_checked)) { - return $is_login_checked; - } if( isset($_SESSION['user_id']) AND $_SESSION['user_id']) { OC_App::loadApps(array('authentication')); if (self::userExists($_SESSION['user_id']) ){ - return $is_login_checked = true; + return true; } } - return $is_login_checked = false; + return false; } /** diff --git a/lib/util.php b/lib/util.php index 0d9f4129442..2a7b8a922f9 100755 --- a/lib/util.php +++ b/lib/util.php @@ -324,16 +324,17 @@ class OC_Util { * Redirect to the user default page */ public static function redirectToDefaultPage(){ - OC_Log::write('core','redirectToDefaultPage',OC_Log::DEBUG); if(isset($_REQUEST['redirect_url']) && (substr($_REQUEST['redirect_url'], 0, strlen(OC::$WEBROOT)) == OC::$WEBROOT || $_REQUEST['redirect_url'][0] == '/')) { - header( 'Location: '.$_REQUEST['redirect_url']); + $location = $_REQUEST['redirect_url']; } else if (isset(OC::$REQUESTEDAPP) && !empty(OC::$REQUESTEDAPP)) { - header( 'Location: '.OC::$WEBROOT.'/?app='.OC::$REQUESTEDAPP ); + $location = OC::$WEBROOT.'/?app='.OC::$REQUESTEDAPP; } else { - header( 'Location: '.OC::$WEBROOT.'/'.OC_Appconfig::getValue('core', 'defaultpage', '?app=files')); + $location = OC::$WEBROOT.'/'.OC_Appconfig::getValue('core', 'defaultpage', '?app=files'); } + OC_Log::write('core', 'redirectToDefaultPage: '.$location, OC_Log::DEBUG); + header( 'Location: '.$location ); exit(); } diff --git a/lib/vcategories.php b/lib/vcategories.php index 8157c343868..d15b7b166ea 100644 --- a/lib/vcategories.php +++ b/lib/vcategories.php @@ -131,8 +131,10 @@ class OC_VCategories { * } * $categories->rescan($objects); */ - public function rescan($objects, $sync=true) { - $this->categories = array(); + public function rescan($objects, $sync=true, $reset=true) { + if($reset === true) { + $this->categories = array(); + } foreach($objects as $object) { //OC_Log::write('core','OC_VCategories::rescan: '.substr($object, 0, 100).'(...)', OC_Log::DEBUG); $vobject = OC_VObject::parse($object); @@ -221,4 +223,3 @@ class OC_VCategories { } } -?> diff --git a/ocs/providers.php b/ocs/providers.php index adaa28db6cd..f9cafd20b01 100644 --- a/ocs/providers.php +++ b/ocs/providers.php @@ -40,6 +40,3 @@ echo(' </provider> </providers> '); - - -?> diff --git a/ocs/v1.php b/ocs/v1.php index 77dd75b9fc2..ab0dc80f4ba 100644 --- a/ocs/v1.php +++ b/ocs/v1.php @@ -24,5 +24,3 @@ require_once('../lib/base.php'); @ob_clean(); OC_OCS::handle(); - -?> diff --git a/remote.php b/remote.php index af48cd922c8..bdce867aaba 100644 --- a/remote.php +++ b/remote.php @@ -25,27 +25,17 @@ if(is_null($file)){ $file = ltrim ($file, '/'); -if(count(explode('/',$file)) == 2) { - $parts=explode('/',$file); - $app=$parts[0]; - switch ($app) { - case 'files': - OC_Util::checkAppEnabled($app); - OC_App::loadApp($app); - break; - case 'core': - break; - default: - OC_Response::setStatus(OC_Response::STATUS_NOT_FOUND); - exit; - } - $baseuri = OC::$WEBROOT . '/remote.php/'.$service.'/'; - require_once( OC::$SERVERROOT.'/'.$file); -} else { - $parts=explode('/', $file, 2); - $app=$parts[0]; - OC_Util::checkAppEnabled($app); - OC_App::loadApp($app); - $baseuri = OC::$WEBROOT . '/remote.php/'.$service.'/'; - require_once(OC_App::getAppPath($app) .'/'. $parts[1]); +$parts=explode('/', $file, 2); +$app=$parts[0]; +switch ($app) { + default: + OC_Util::checkAppEnabled($app); + OC_App::loadApp($app); + $file = OC_App::getAppPath($app) .'/'. $parts[1]; + break; + case 'core': + $file = OC::$SERVERROOT .'/'. $file; + break; } +$baseuri = OC::$WEBROOT . '/remote.php/'.$service.'/'; +require_once($file); diff --git a/search/ajax/search.php b/search/ajax/search.php index 326724d60c4..95ddfedf8ba 100644 --- a/search/ajax/search.php +++ b/search/ajax/search.php @@ -35,5 +35,3 @@ if($query){ }else{ echo 'false'; } - -?> diff --git a/search/index.php b/search/index.php index 518695c56d2..de55aec3999 100644 --- a/search/index.php +++ b/search/index.php @@ -49,5 +49,3 @@ foreach($results as $result){ $tmpl = new OC_Template( 'search', 'index', 'user' ); $tmpl->assign('resultTypes',$resultTypes); $tmpl->printPage(); - -?> diff --git a/settings/ajax/changepassword.php b/settings/ajax/changepassword.php index 860ea987871..4ba6813517b 100644 --- a/settings/ajax/changepassword.php +++ b/settings/ajax/changepassword.php @@ -9,6 +9,8 @@ $oldPassword=isset($_POST["oldpassword"])?$_POST["oldpassword"]:''; // Check if we are a user OC_JSON::checkLoggedIn(); +OCP\JSON::callCheck(); + if( (!OC_Group::inGroup( OC_User::getUser(), 'admin' ) && ($username!=OC_User::getUser() || !OC_User::checkPassword($username,$oldPassword)))) { OC_JSON::error( array( "data" => array( "message" => "Authentication error" ))); exit(); @@ -21,5 +23,3 @@ if( OC_User::setPassword( $username, $password )){ else{ OC_JSON::error(array("data" => array( "message" => "Unable to change password" ))); } - -?> diff --git a/settings/ajax/creategroup.php b/settings/ajax/creategroup.php index 57d82e7bd94..af8ad3dd8c0 100644 --- a/settings/ajax/creategroup.php +++ b/settings/ajax/creategroup.php @@ -9,6 +9,8 @@ if( !OC_User::isLoggedIn() || !OC_Group::inGroup( OC_User::getUser(), 'admin' )) exit(); } +OCP\JSON::callCheck(); + $groupname = $_POST["groupname"]; // Does the group exist? @@ -24,5 +26,3 @@ if( OC_Group::createGroup( $groupname )){ else{ OC_JSON::error(array("data" => array( "message" => "Unable to add group" ))); } - -?> diff --git a/settings/ajax/createuser.php b/settings/ajax/createuser.php index 6714711bc87..c56df4bc15a 100644 --- a/settings/ajax/createuser.php +++ b/settings/ajax/createuser.php @@ -8,6 +8,7 @@ if( !OC_User::isLoggedIn() || !OC_Group::inGroup( OC_User::getUser(), 'admin' )) OC_JSON::error(array("data" => array( "message" => "Authentication error" ))); exit(); } +OCP\JSON::callCheck(); $groups = array(); if( isset( $_POST["groups"] )){ @@ -35,5 +36,3 @@ try { } catch (Exception $exception) { OC_JSON::error(array("data" => array( "message" => $exception->getMessage()))); } - -?> diff --git a/settings/ajax/disableapp.php b/settings/ajax/disableapp.php index 53e9be379e1..cc006988707 100644 --- a/settings/ajax/disableapp.php +++ b/settings/ajax/disableapp.php @@ -2,6 +2,7 @@ // Init owncloud require_once('../../lib/base.php'); OC_JSON::checkAdminUser(); +OCP\JSON::callCheck(); OC_JSON::setContentTypeHeader(); OC_App::disable($_POST['appid']); diff --git a/settings/ajax/enableapp.php b/settings/ajax/enableapp.php index cb116ebe4e8..bd53a50210c 100644 --- a/settings/ajax/enableapp.php +++ b/settings/ajax/enableapp.php @@ -3,6 +3,7 @@ // Init owncloud require_once('../../lib/base.php'); OC_JSON::checkAdminUser(); +OCP\JSON::callCheck(); OC_JSON::setContentTypeHeader(); if(OC_App::enable($_POST['appid'])){ diff --git a/settings/ajax/lostpassword.php b/settings/ajax/lostpassword.php index c6df8551f52..803a424854c 100644 --- a/settings/ajax/lostpassword.php +++ b/settings/ajax/lostpassword.php @@ -2,8 +2,8 @@ // Init owncloud require_once('../../lib/base.php'); - OC_JSON::checkLoggedIn(); +OCP\JSON::callCheck(); $l=OC_L10N::get('core'); @@ -15,5 +15,3 @@ if( isset( $_POST['email'] ) && filter_var( $_POST['email'], FILTER_VALIDATE_EMA }else{ OC_JSON::error(array("data" => array( "message" => $l->t("Invalid email") ))); } - -?> diff --git a/settings/ajax/openid.php b/settings/ajax/openid.php index 58d071255c2..bf4ead06020 100644 --- a/settings/ajax/openid.php +++ b/settings/ajax/openid.php @@ -6,6 +6,7 @@ require_once('../../lib/base.php'); $l=OC_L10N::get('settings'); OC_JSON::checkLoggedIn(); +OCP\JSON::callCheck(); OC_JSON::checkAppEnabled('user_openid'); // Get data @@ -16,5 +17,3 @@ if( isset( $_POST['identity'] ) ){ }else{ OC_JSON::error(array("data" => array( "message" => $l->t("Invalid request") ))); } - -?> diff --git a/settings/ajax/removegroup.php b/settings/ajax/removegroup.php index 4d364781894..f8c2065956c 100644 --- a/settings/ajax/removegroup.php +++ b/settings/ajax/removegroup.php @@ -4,6 +4,7 @@ require_once('../../lib/base.php'); OC_JSON::checkAdminUser(); +OCP\JSON::callCheck(); $name = $_POST["groupname"]; @@ -14,5 +15,3 @@ if( OC_Group::deleteGroup( $name )){ else{ OC_JSON::error(array("data" => array( "message" => "Unable to delete group" ))); } - -?> diff --git a/settings/ajax/removeuser.php b/settings/ajax/removeuser.php index 2c288997a1f..230815217c3 100644 --- a/settings/ajax/removeuser.php +++ b/settings/ajax/removeuser.php @@ -4,6 +4,7 @@ require_once('../../lib/base.php'); OC_JSON::checkAdminUser(); +OCP\JSON::callCheck(); $username = $_POST["username"]; @@ -14,5 +15,3 @@ if( OC_User::deleteUser( $username )){ else{ OC_JSON::error(array("data" => array( "message" => "Unable to delete user" ))); } - -?> diff --git a/settings/ajax/setlanguage.php b/settings/ajax/setlanguage.php index e3b00c3bc80..54b103cd4fe 100644 --- a/settings/ajax/setlanguage.php +++ b/settings/ajax/setlanguage.php @@ -6,6 +6,7 @@ require_once('../../lib/base.php'); $l=OC_L10N::get('settings'); OC_JSON::checkLoggedIn(); +OCP\JSON::callCheck(); // Get data @@ -21,5 +22,3 @@ if( isset( $_POST['lang'] ) ){ }else{ OC_JSON::error(array("data" => array( "message" => $l->t("Invalid request") ))); } - -?> diff --git a/settings/ajax/setloglevel.php b/settings/ajax/setloglevel.php index 298cbd64738..4b97ba2aa32 100644 --- a/settings/ajax/setloglevel.php +++ b/settings/ajax/setloglevel.php @@ -7,6 +7,7 @@ require_once('../../lib/base.php'); OC_Util::checkAdminUser(); +OCP\JSON::callCheck(); OC_Config::setValue( 'loglevel', $_POST['level'] ); diff --git a/settings/ajax/setquota.php b/settings/ajax/setquota.php index f59017600ac..2b412c0f2fd 100644 --- a/settings/ajax/setquota.php +++ b/settings/ajax/setquota.php @@ -9,6 +9,7 @@ require_once('../../lib/base.php'); OC_JSON::checkAdminUser(); +OCP\JSON::callCheck(); $username = isset($_POST["username"])?$_POST["username"]:''; @@ -34,4 +35,3 @@ if($username){ } OC_JSON::success(array("data" => array( "username" => $username ,'quota'=>$quota))); -?> diff --git a/settings/ajax/togglegroups.php b/settings/ajax/togglegroups.php index 7773c1049c3..95338ed0267 100644 --- a/settings/ajax/togglegroups.php +++ b/settings/ajax/togglegroups.php @@ -4,6 +4,7 @@ require_once('../../lib/base.php'); OC_JSON::checkAdminUser(); +OCP\JSON::callCheck(); $success = true; $error = "add user to"; @@ -37,5 +38,3 @@ if( $success ){ else{ OC_JSON::error(array("data" => array( "message" => "Unable to $error group $group" ))); } - -?> diff --git a/settings/apps.php b/settings/apps.php index f4ae8b8d977..762395c031b 100644 --- a/settings/apps.php +++ b/settings/apps.php @@ -97,5 +97,3 @@ $appid = (isset($_GET['appid'])?strip_tags($_GET['appid']):''); $tmpl->assign('appid',$appid); $tmpl->printPage(); - -?> diff --git a/settings/help.php b/settings/help.php index f0abed8f558..b1dc1c5be77 100644 --- a/settings/help.php +++ b/settings/help.php @@ -25,5 +25,3 @@ $tmpl->assign( "kbe", $kbe ); $tmpl->assign( "pagecount", $pagecount ); $tmpl->assign( "page", $page ); $tmpl->printPage(); - -?> diff --git a/settings/js/users.js b/settings/js/users.js index 0de0d1df3bc..771ed51f5fb 100644 --- a/settings/js/users.js +++ b/settings/js/users.js @@ -4,6 +4,72 @@ * See the COPYING-README file. */ +UserList={ + useUndo:true, + + /** + * @brief Initiate user deletion process in UI + * @param string uid the user ID to be deleted + * + * Does not actually delete the user; it sets them for + * deletion when the current page is unloaded, at which point + * finishDelete() completes the process. This allows for 'undo'. + */ + do_delete:function( uid ) { + + UserList.deleteUid = uid; + + // Set undo flag + UserList.deleteCanceled = false; + + // Hide user in table to reflect deletion + $(this).parent().parent().hide(); + $('tr').filterAttr( 'data-uid', UserList.deleteUid ).hide(); + + // Provide user with option to undo + $('#notification').text(t('files','undo delete user')); + $('#notification').data('deleteuser',true); + $('#notification').fadeIn(); + + }, + + /** + * @brief Delete a user via ajax + * @param bool ready whether to use ready() upon completion + * + * Executes deletion via ajax of user identified by property deleteUid + * if 'undo' has not been used. Completes the user deletion procedure + * and reflects success in UI. + */ + finishDelete:function( ready ){ + + // Check deletion has not been undone + if( !UserList.deleteCanceled && UserList.deleteUid ){ + + // Delete user via ajax + $.post( + OC.filePath('settings','ajax','removeuser.php'), + {username:UserList.deleteUid}, + function(result){ + + // Remove undo option, & remove user from table + boolOperationFinished( + data, function(){ + $('#notification').fadeOut(); + $('tr').filterAttr( 'data-uid', username ).remove(); + UserList.deleteCanceled=true; + UserList.deleteFiles=null; + if( ready ){ + ready(); + } + } + ); + } + ); + } + } +} + $(document).ready(function(){ function setQuota(uid,quota,ready){ $.post( @@ -40,7 +106,15 @@ $(document).ready(function(){ }else{ checkHandeler=false; } + var addGroup = function(group) { + $('select[multiple]').each(function(index, element) { + if ($(element).find('option[value="'+group +'"]').length == 0) { + $(element).append('<option value="'+group+'">'+group+'</option>'); + } + }) + }; element.multiSelect({ + createCallback:addGroup, createText:'add group', checked:checked, oncheck:checkHandeler, @@ -53,15 +127,12 @@ $(document).ready(function(){ }); $('td.remove>img').live('click',function(event){ - var uid=$(this).parent().parent().data('uid'); - $.post( - OC.filePath('settings','ajax','removeuser.php'), - {username:uid}, - function(result){ - - } - ); - $(this).parent().parent().remove(); + + var uid = $(this).parent().parent().data('uid'); + + // Call function for handling delete/undo + UserList.do_delete( uid ); + }); $('td.password>img').live('click',function(event){ @@ -115,7 +186,7 @@ $(document).ready(function(){ }) $('input.quota-other').live('change',function(){ - var uid=$(this).parent().parent().data('uid'); + var uid=$(this).parent().parent().parent().data('uid'); var quota=$(this).val(); var select=$(this).prev(); var other=$(this); @@ -213,6 +284,20 @@ $(document).ready(function(){ } } ); - location.reload(); + }); + // Handle undo notifications + $('#notification').hide(); + $('#notification').click(function(){ + if($('#notification').data('deleteuser')) + { + $( 'tr' ).filterAttr( 'data-uid', UserList.deleteUid ).show(); + UserList.deleteCanceled=true; + UserList.deleteFiles=null; + } + $('#notification').fadeOut(); + }); + UserList.useUndo=('onbeforeunload' in window) + $(window).bind('beforeunload', function (){ + UserList.finishDelete(null); }); }); diff --git a/settings/personal.php b/settings/personal.php index 26a9f601d9a..d82db0d0e7e 100644 --- a/settings/personal.php +++ b/settings/personal.php @@ -17,7 +17,7 @@ OC_App::setActiveNavigationEntry( 'personal' ); // calculate the disc space $rootInfo=OC_FileCache::get(''); -$sharedInfo=OC_FileCache::get('/Shared');
+$sharedInfo=OC_FileCache::get('/Shared'); $used=$rootInfo['size']-$sharedInfo['size']; $free=OC_Filesystem::free_space(); $total=$free+$used; @@ -61,5 +61,3 @@ foreach($forms as $form){ $tmpl->append('forms',$form); } $tmpl->printPage(); - -?> diff --git a/settings/templates/admin.php b/settings/templates/admin.php index a9f727d6764..033cd1a1642 100755 --- a/settings/templates/admin.php +++ b/settings/templates/admin.php @@ -54,3 +54,10 @@ if(!$_['htaccessworking']) { </table> <input id='moreLog' type='button' value='<?php echo $l->t('More');?>...'></input> </fieldset> + + +<p class="personalblock"> + <strong>ownCloud</strong> <?php echo(OC_Util::getVersionString()); ?> <?php echo(OC_Util::getEditionString()); ?> (<?php echo(OC_Updater::ShowUpdatingHint()); ?>)<br /> + Developed by the <a href="http://ownCloud.org/contact" target="_blank">ownCloud community</a>, the <a href="http://gitorious.org/owncloud" target="_blank">source code</a> is licensed under the <a href="http://www.gnu.org/licenses/agpl-3.0.html" target="_blank"><abbr title="Affero General Public License">AGPL</abbr></a>. +</p> + diff --git a/settings/templates/personal.php b/settings/templates/personal.php index 014996a5b20..ee40120d724 100644 --- a/settings/templates/personal.php +++ b/settings/templates/personal.php @@ -55,10 +55,5 @@ echo $form; };?> -<p class="personalblock"> - <strong>ownCloud</strong> <?php echo(OC_Util::getVersionString()); ?> <?php echo(OC_Util::getEditionString()); ?> (<?php echo(OC_Updater::ShowUpdatingHint()); ?>)<br /> - Developed by the <a href="http://ownCloud.org/contact" target="_blank">ownCloud community</a>, the <a href="http://gitorious.org/owncloud" target="_blank">source code</a> is freely licensed under the <a href="http://www.gnu.org/licenses/agpl-3.0.html" target="_blank"><abbr title="Affero General Public License">AGPL</abbr></a>. -</p> - diff --git a/settings/templates/users.php b/settings/templates/users.php index c042f2664e2..55112424561 100644 --- a/settings/templates/users.php +++ b/settings/templates/users.php @@ -52,6 +52,8 @@ foreach($_["groups"] as $group) { </div> </div> +<div id='notification'></div> + <table data-groups="<?php echo implode(', ',$allGroups);?>"> <thead> <tr> diff --git a/settings/users.php b/settings/users.php index 026a30a750c..c3259d2a3f1 100644 --- a/settings/users.php +++ b/settings/users.php @@ -48,6 +48,3 @@ $tmpl->assign( 'quota_preset', $quotaPreset); $tmpl->assign( 'default_quota', $defaultQuota); $tmpl->assign( 'share_notice', $shareNotice); $tmpl->printPage(); - -?> - diff --git a/status.php b/status.php index 2d31702ecb3..f314a3a1c6f 100644 --- a/status.php +++ b/status.php @@ -29,6 +29,3 @@ if(OC_Config::getValue('installed')==1) $installed='true'; else $installed='fals $values=array('installed'=>$installed,'version'=>implode('.',OC_Util::getVersion()),'versionstring'=>OC_Util::getVersionString(),'edition'=>OC_Util::getEditionString()); echo(json_encode($values)); - - -?> diff --git a/tests/lib/cache/file.php b/tests/lib/cache/file.php index 226e5068c41..54e60e6569d 100644 --- a/tests/lib/cache/file.php +++ b/tests/lib/cache/file.php @@ -21,7 +21,26 @@ */ class Test_Cache_File extends Test_Cache { + function skip() { + $this->skipUnless(OC_User::isLoggedIn()); + } + public function setUp(){ + //clear all proxies and hooks so we can do clean testing + OC_FileProxy::clearProxies(); + OC_Hook::clear('OC_Filesystem'); + + //enable only the encryption hook + OC_FileProxy::register(new OC_FileProxy_Encryption()); + + //set up temporary storage + OC_Filesystem::clearMounts(); + OC_Filesystem::mount('OC_Filestorage_Temporary',array(),'/'); + + //set up the users dir + $rootView=new OC_FilesystemView(''); + $rootView->mkdir('/'.OC_User::getUser()); + $this->instance=new OC_Cache_File(); } } diff --git a/tests/lib/cache/xcache.php b/tests/lib/cache/xcache.php index a5e954f827c..cc2077076ce 100644 --- a/tests/lib/cache/xcache.php +++ b/tests/lib/cache/xcache.php @@ -28,4 +28,8 @@ class Test_Cache_XCache extends Test_Cache { public function setUp(){ $this->instance=new OC_Cache_XCache(); } + + function testTTL(){ + // ttl doesn't work correctly in the same request + } } diff --git a/webapps.php b/webapps.php index b5fee9bf85f..82e677a51c7 100644 --- a/webapps.php +++ b/webapps.php @@ -52,5 +52,3 @@ if(!OC_User::login($authuser,$authpw)){ } - -?> |