From 4793d25c577dcad3516853d05d62cf264fc54448 Mon Sep 17 00:00:00 2001 From: Thomas Tanghus Date: Fri, 30 Dec 2011 21:07:16 +0100 Subject: [PATCH 01/16] Added license and waiver of conditions for jquery.inview. CSS fix on contact list. Query contacts from multiple address books. --- apps/contacts/ajax/addcard.php | 1 + apps/contacts/ajax/contacts.php | 9 +++--- apps/contacts/css/styles.css | 1 + apps/contacts/index.php | 9 ++++-- apps/contacts/js/LICENSE.jquery.inview | 41 ++++++++++++++++++++++++++ apps/contacts/js/jquery.inview.txt | 15 ++++++++++ apps/contacts/lib/addressbook.php | 25 ++++++++++++++-- apps/contacts/lib/vcard.php | 19 ++++++++++-- 8 files changed, 110 insertions(+), 10 deletions(-) create mode 100644 apps/contacts/js/LICENSE.jquery.inview create mode 100644 apps/contacts/js/jquery.inview.txt diff --git a/apps/contacts/ajax/addcard.php b/apps/contacts/ajax/addcard.php index 9d782246a0..54c455e515 100644 --- a/apps/contacts/ajax/addcard.php +++ b/apps/contacts/ajax/addcard.php @@ -61,5 +61,6 @@ foreach( $add as $propname){ $vcard->addProperty($propname, $value, $prop_parameters); } $id = OC_Contacts_VCard::add($aid,$vcard->serialize()); +OC_Log::write('contacts','ajax/addcard.php - adding id: '.$id,OC_Log::DEBUG); OC_Contacts_App::renderDetails($id, $vcard); diff --git a/apps/contacts/ajax/contacts.php b/apps/contacts/ajax/contacts.php index b34cf41424..54ad3e4c10 100644 --- a/apps/contacts/ajax/contacts.php +++ b/apps/contacts/ajax/contacts.php @@ -6,14 +6,14 @@ * See the COPYING-README file. */ -function contacts_namesort($a,$b){ - return strcasecmp($a['fullname'],$b['fullname']); -} - require_once('../../../lib/base.php'); OC_JSON::checkLoggedIn(); OC_JSON::checkAppEnabled('contacts'); +$ids = OC_Contacts_Addressbook::activeIds(OC_User::getUser()); +$contacts = OC_Contacts_VCard::all($ids); +//OC_Log::write('contacts','contacts.php: '.count($contacts).' contacts.',OC_Log::DEBUG); +/* $addressbooks = OC_Contacts_Addressbook::active(OC_User::getUser()); $contacts = array(); foreach( $addressbooks as $addressbook ){ @@ -26,6 +26,7 @@ foreach( $addressbooks as $addressbook ){ } } usort($contacts,'contacts_namesort'); +*/ $tmpl = new OC_TEMPLATE("contacts", "part.contacts"); $tmpl->assign('contacts', $contacts); $page = $tmpl->fetchPage(); diff --git a/apps/contacts/css/styles.css b/apps/contacts/css/styles.css index b6709c5a79..53b469e6ee 100644 --- a/apps/contacts/css/styles.css +++ b/apps/contacts/css/styles.css @@ -1,3 +1,4 @@ +#contacts { padding-left:5px; padding-top: 5px; background: #fff; } #contacts li { padding-left:25px;background:url('../img/person.svg') no-repeat; } #chooseaddressbook {margin-right: 170px; float: right;} #contacts_details_name { font-weight:bold;font-size:1.1em;margin-left:25%;} diff --git a/apps/contacts/index.php b/apps/contacts/index.php index a6af54c878..5ab6f293ab 100644 --- a/apps/contacts/index.php +++ b/apps/contacts/index.php @@ -32,6 +32,9 @@ OC_Util::checkLoggedIn(); OC_Util::checkAppEnabled('contacts'); // Get active address books. This creates a default one if none exists. +$ids = OC_Contacts_Addressbook::activeIds(OC_User::getUser()); +$contacts = OC_Contacts_VCard::all($ids); + $addressbooks = OC_Contacts_Addressbook::active(OC_User::getUser()); // Load the files we need @@ -39,7 +42,7 @@ OC_App::setActiveNavigationEntry( 'contacts_index' ); // Load a specific user? $id = isset( $_GET['id'] ) ? $_GET['id'] : null; - +/* // sort addressbooks (use contactsort) usort($addressbooks,'contacts_namesort'); @@ -55,8 +58,10 @@ foreach( $addressbooks as $addressbook ){ } usort($contacts,'contacts_namesort'); - +*/ $details = array(); + +// FIXME: This cannot work..? if( !is_null($id)/* || count($contacts)*/){ if(is_null($id)) $id = $contacts[0]['id']; $vcard = OC_Contacts_App::getContactVCard($id); diff --git a/apps/contacts/js/LICENSE.jquery.inview b/apps/contacts/js/LICENSE.jquery.inview new file mode 100644 index 0000000000..1ed340edbe --- /dev/null +++ b/apps/contacts/js/LICENSE.jquery.inview @@ -0,0 +1,41 @@ +Attribution-Non-Commercial-Share Alike 2.0 UK: England & Wales + +http://creativecommons.org/licenses/by-nc-sa/2.0/uk/ + +You are free: + + * to copy, distribute, display, and perform the work + * to make derivative works + + +Under the following conditions: + + * Attribution — You must give the original author credit. + Attribute this work: + Information + What does "Attribute this work" mean? + The page you came from contained embedded licensing metadata, + including how the creator wishes to be attributed for re-use. + You can use the HTML here to cite the work. Doing so will + also include metadata on your page so that others can find the + original work as well. + + * Non-Commercial — You may not use this work for commercial + purposes. + * Share Alike — If you alter, transform, or build upon this + work, you may distribute the resulting work only under a + licence identical to this one. + +With the understanding that: + + * Waiver — Any of the above conditions can be waived if you get + permission from the copyright holder. + * Other Rights — In no way are any of the following rights + affected by the license: + o Your fair dealing or fair use rights; + o The author's moral rights; + o Rights other persons may have either in the work itself + or in how the work is used, such as publicity or privacy rights. + * Notice — For any reuse or distribution, you must make clear to + others the licence terms of this work. + diff --git a/apps/contacts/js/jquery.inview.txt b/apps/contacts/js/jquery.inview.txt new file mode 100644 index 0000000000..c53dbd1d97 --- /dev/null +++ b/apps/contacts/js/jquery.inview.txt @@ -0,0 +1,15 @@ +jQuery.inview is licensed Attribution-Non-Commercial-Share Alike 2.0 but the +conditions has been waived by the author in the following tweet: + +https://twitter.com/#!/ChristopherBlum/status/148382899887013888 + +Saying: + +Thomas Tanghus @tanghus 18 Dec. 2011 + +@ChristopherBlum Hi. Is it OK if I use https://github.com/protonet/jquery.inview in ownCloud? Preferably under an AGPL license ;-) owncloud.org + + +Christopher Blum Christopher Blum @ChristopherBlum 18 Dec. 2011 + +@tanghus Feel free to! :) diff --git a/apps/contacts/lib/addressbook.php b/apps/contacts/lib/addressbook.php index 6f2f34225d..b3c981a541 100644 --- a/apps/contacts/lib/addressbook.php +++ b/apps/contacts/lib/addressbook.php @@ -140,6 +140,25 @@ 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. @@ -170,7 +189,8 @@ class OC_Contacts_Addressbook{ public static function active($uid){ $active = self::activeIds($uid); $addressbooks = array(); - /** FIXME: Is there a way to prepare a statement 'WHERE id IN ([range])'? + /* FIXME: Is there a way to prepare a statement 'WHERE id IN ([range])'? + * See OC_Contacts_VCard:all. */ foreach( $active as $aid ){ $stmt = OC_DB::prepare( 'SELECT * FROM *PREFIX*contacts_addressbooks WHERE id = ? ORDER BY displayname' ); @@ -208,6 +228,7 @@ class OC_Contacts_Addressbook{ unset($openaddressbooks[array_search($id, $openaddressbooks)]); } } + $openaddressbooks = self::cleanArray($openaddressbooks, false); sort($openaddressbooks, SORT_NUMERIC); // FIXME: I alway end up with a ';' prepending when imploding the array..? OC_Preferences::setValue(OC_User::getUser(),'contacts','openaddressbooks',implode(';', $openaddressbooks)); @@ -221,7 +242,7 @@ class OC_Contacts_Addressbook{ * @return boolean */ public static function isActive($id){ - OC_Log::write('contacts','OC_Contacts_Addressbook::isActive('.$id.'):'.in_array($id, self::activeIds()), OC_Log::DEBUG); + //OC_Log::write('contacts','OC_Contacts_Addressbook::isActive('.$id.'):'.in_array($id, self::activeIds()), OC_Log::DEBUG); return in_array($id, self::activeIds()); } diff --git a/apps/contacts/lib/vcard.php b/apps/contacts/lib/vcard.php index 7285761fd5..81519b3d05 100644 --- a/apps/contacts/lib/vcard.php +++ b/apps/contacts/lib/vcard.php @@ -47,9 +47,24 @@ class OC_Contacts_VCard{ * ['carddata'] */ public static function all($id){ - $stmt = OC_DB::prepare( 'SELECT * FROM *PREFIX*contacts_cards WHERE addressbookid = ? ORDER BY fullname' ); - $result = $stmt->execute(array($id)); + //$stmt = OC_DB::prepare( 'SELECT * FROM *PREFIX*contacts_cards WHERE addressbookid = ? ORDER BY fullname' ); + //$result = $stmt->execute(array($id)); + if(is_array($id)) { + $id_sql = join(',', array_fill(0, count($id), '?')); + $prep = 'SELECT * FROM *PREFIX*contacts_cards WHERE addressbookid IN ('.$id_sql.') ORDER BY fullname'; + try { + $stmt = OC_DB::prepare( $prep ); + $result = $stmt->execute($id); + } catch(Exception $e) { + OC_Log::write('contacts','OC_Contacts_VCard:all:, exception: '.$e->getMessage(),OC_Log::DEBUG); + OC_Log::write('contacts','OC_Contacts_VCard:all, ids: '.join(',', $id),OC_Log::DEBUG); + OC_Log::write('contacts','SQL:'.$prep,OC_Log::DEBUG); + } + } else { + $stmt = OC_DB::prepare( 'SELECT * FROM *PREFIX*contacts_cards WHERE addressbookid = ? ORDER BY fullname' ); + $result = $stmt->execute(array($id)); + } $cards = array(); while( $row = $result->fetchRow()){ $cards[] = $row; From 97471b5c2a079be34aeff099019f219135b9cb2c Mon Sep 17 00:00:00 2001 From: Thomas Tanghus Date: Fri, 30 Dec 2011 23:39:31 +0100 Subject: [PATCH 02/16] Thumbnails was overwriting default style so hover and active didn't work. Moved them to the 'a' element instead. --- apps/contacts/css/styles.css | 4 ++-- apps/contacts/js/interface.js | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/contacts/css/styles.css b/apps/contacts/css/styles.css index 53b469e6ee..c890be8582 100644 --- a/apps/contacts/css/styles.css +++ b/apps/contacts/css/styles.css @@ -1,5 +1,5 @@ -#contacts { padding-left:5px; padding-top: 5px; background: #fff; } -#contacts li { padding-left:25px;background:url('../img/person.svg') no-repeat; } +#contacts { padding-left:2px; padding-top: 5px; background: #fff; } +#leftcontent a { height: 23px; display: block; margin: 0 0 0 0; padding: 0 0 0 25px; } #chooseaddressbook {margin-right: 170px; float: right;} #contacts_details_name { font-weight:bold;font-size:1.1em;margin-left:25%;} #contacts_details_photo { margin:.5em 0em .5em 25%; } diff --git a/apps/contacts/js/interface.js b/apps/contacts/js/interface.js index 3190efae3c..35639ef6cc 100644 --- a/apps/contacts/js/interface.js +++ b/apps/contacts/js/interface.js @@ -113,9 +113,9 @@ Contacts={ lazyupdate:function(){ //alert('lazyupdate'); $('#contacts li').live('inview', function(){ - if (!$(this).attr('style')) { + if (!$(this).find('a').attr('style')) { //alert($(this).data('id') + ' has background: ' + $(this).attr('style')); - $(this).css('background','url(thumbnail.php?id='+$(this).data('id')+') no-repeat'); + $(this).find('a').css('background','url(thumbnail.php?id='+$(this).data('id')+') no-repeat'); }/* else { alert($(this).data('id') + ' has style ' + $(this).attr('style').match('url')); }*/ @@ -301,9 +301,9 @@ $(document).ready(function(){ // bottom part of element is visible } else { // whole part of element is visible - if (!$(this).attr('style')) { + if (!$(this).find('a').attr('style')) { //alert($(this).data('id') + ' has background: ' + $(this).attr('style')); - $(this).css('background','url(thumbnail.php?id='+$(this).data('id')+') no-repeat'); + $(this).find('a').css('background','url(thumbnail.php?id='+$(this).data('id')+') no-repeat'); }/* else { alert($(this).data('id') + ' has style ' + $(this).attr('style').match('url')); }*/ From 1b146b85d2b645dc4ae4f16d9757ad4bd939c0e2 Mon Sep 17 00:00:00 2001 From: Thomas Tanghus Date: Sat, 31 Dec 2011 01:34:22 +0100 Subject: [PATCH 03/16] Removed redundant DB queries. --- apps/contacts/lib/addressbook.php | 20 ++++++++++++++++---- apps/contacts/lib/vcard.php | 3 --- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/apps/contacts/lib/addressbook.php b/apps/contacts/lib/addressbook.php index b3c981a541..78792f5f94 100644 --- a/apps/contacts/lib/addressbook.php +++ b/apps/contacts/lib/addressbook.php @@ -189,9 +189,21 @@ class OC_Contacts_Addressbook{ public static function active($uid){ $active = self::activeIds($uid); $addressbooks = array(); - /* FIXME: Is there a way to prepare a statement 'WHERE id IN ([range])'? - * See OC_Contacts_VCard:all. - */ + $ids_sql = join(',', array_fill(0, count($active), '?')); + $prep = 'SELECT * FROM *PREFIX*contacts_addressbooks WHERE id IN ('.$ids_sql.') ORDER BY displayname'; + try { + $stmt = OC_DB::prepare( $prep ); + $result = $stmt->execute($active); + } catch(Exception $e) { + OC_Log::write('contacts','OC_Contacts_Addressbook:active:, exception: '.$e->getMessage(),OC_Log::DEBUG); + OC_Log::write('contacts','OC_Contacts_Addressbook:active, ids: '.join(',', $active),OC_Log::DEBUG); + OC_Log::write('contacts','OC_Contacts_Addressbook::active, SQL:'.$prep,OC_Log::DEBUG); + } + + while( $row = $result->fetchRow()){ + $addressbooks[] = $row; + } + /* foreach( $active as $aid ){ $stmt = OC_DB::prepare( 'SELECT * FROM *PREFIX*contacts_addressbooks WHERE id = ? ORDER BY displayname' ); $result = $stmt->execute(array($aid,)); @@ -199,7 +211,7 @@ class OC_Contacts_Addressbook{ while( $row = $result->fetchRow()){ $addressbooks[] = $row; } - } + }*/ return $addressbooks; } diff --git a/apps/contacts/lib/vcard.php b/apps/contacts/lib/vcard.php index 81519b3d05..beb291b481 100644 --- a/apps/contacts/lib/vcard.php +++ b/apps/contacts/lib/vcard.php @@ -47,9 +47,6 @@ class OC_Contacts_VCard{ * ['carddata'] */ public static function all($id){ - //$stmt = OC_DB::prepare( 'SELECT * FROM *PREFIX*contacts_cards WHERE addressbookid = ? ORDER BY fullname' ); - //$result = $stmt->execute(array($id)); - if(is_array($id)) { $id_sql = join(',', array_fill(0, count($id), '?')); $prep = 'SELECT * FROM *PREFIX*contacts_cards WHERE addressbookid IN ('.$id_sql.') ORDER BY fullname'; From 6207c0444be7c383838beb0ddc3d684ffee0262b Mon Sep 17 00:00:00 2001 From: Thomas Tanghus Date: Sun, 1 Jan 2012 17:57:26 +0100 Subject: [PATCH 04/16] Added class OC_Image --- lib/image.php | 297 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 297 insertions(+) create mode 100644 lib/image.php diff --git a/lib/image.php b/lib/image.php new file mode 100644 index 0000000000..4b63ea5ff3 --- /dev/null +++ b/lib/image.php @@ -0,0 +1,297 @@ + +* +* 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 . +* +*/ + +/** + * Class for image manipulation + * Ideas: imagerotate, chunk_split(base64_encode()) + * + */ +class OC_Image { + static private $resource = false; // tmp resource. + static private $destroy = false; // if the resource is created withing the object. + /** + * @brief Constructor. + * @param $imageref The path to a local file, a base64 encoded string or a resource created by an imagecreate* function. + * If a resource is passed it is the job of the caller to destroy it using imagedestroy($var) + * @returns bool False on error + */ + function __construct($imageref = null) { + OC_Log::write('core','OC_Image::__construct, start', OC_Log::DEBUG); + if(!function_exists('imagecreatefromjpeg')) { // FIXME: Find a better way to check for GD + OC_Log::write('core','OC_Image::__construct, GD module not installed', OC_Log::ERROR); + return false; + } + if(!is_null($imageref)) { + self::load($imageref); + } + } + + /** + * @brief Destructor. + */ + function __destruct() { + if(self::$resource && self::$destroy) { + imagedestroy(self::$resource); // Why does this issue a warning. + } + } + + /** + * @brief Prints the image. + */ + public function show() { + header('Content-Type: image/png'); + imagepng(self::$resource); + } + + /** + * @brief Prints the image when called as $image(). + */ + public function __invoke() { + self::show(); + } + + /** + * @returns Returns the image resource in any. + */ + public function imageResource() { + return self::$resource; + } + + /** + * @returns Returns a base64 encoded string suitable for embedding in a VCard. + */ + function __toString() { + ob_start(); + $res = imagepng(self::$resource); + if (!$res) { + OC_Log::write('core','OC_Image::_string. Error writing image',OC_Log::ERROR); + } + return chunk_split(base64_encode(ob_get_clean())); + } + + /** + * @brief Loads an image from a local file, a base64 encoded string or a resource created by an imagecreate* function. + * @param $imageref The path to a local file, a base64 encoded string or a resource created by an imagecreate* function. + * If a resource is passed it is the job of the caller to destroy it using imagedestroy($var) + * @returns An image resource or false on error + */ + static public function load($imageref) { + if(self::loadFromFile($imageref) !== false) { + return self::$resource; + } elseif(self::loadFromBase64($imageref) !== false) { + return self::$resource; + } elseif(self::loadFromData($imageref) !== false) { + return self::$resource; + } elseif(self::loadFromResource($imageref) !== false) { + return self::$resource; + } else { + OC_Log::write('core','OC_Image::load, couldn\'t load anything. Giving up!', OC_Log::DEBUG); + return false; + } + } + + /** + * @brief Loads an image from a local file. + * @param $imageref The path to a local file. + * @returns An image resource or false on error + */ + static public function loadFromFile($imagepath=false) { + if(!is_string($imagepath)) { + return false; + } + if(!is_file($imagepath) || !file_exists($imagepath) || !is_readable($imagepath)) { + OC_Log::write('core','OC_Image::loadFromFile, couldn\'t load'.$imagepath, OC_Log::DEBUG); + return false; + } + self::$resource = imagecreatefromstring(file_get_contents($imagepath)); + self::$destroy = true; + return self::$resource; + } + + /** + * @brief Loads an image from a string of data. + * @param $str A string of image data as read from a file. + * @returns An image resource or false on error + */ + static public function loadFromData($str) { + if(is_resource($str)) { + return false; + } + self::$resource = imagecreatefromstring($str); + if(!self::$resource) { + OC_Log::write('core','OC_Image::loadFromData, couldn\'t load', OC_Log::DEBUG); + return false; + } + self::$destroy = true; + return self::$resource; + } + + /** + * @brief Loads an image from a base64 encoded string. + * @param $str A string base64 encoded string of image data. + * @returns An image resource or false on error + */ + static public function loadFromBase64($str) { + if(!is_string($str)) { + return false; + } + $data = base64_decode($str); + if($data) { // try to load from string data + self::$resource = imagecreatefromstring($data); + if(!self::$resource) { + OC_Log::write('core','OC_Image::loadFromBase64, couldn\'t load', OC_Log::DEBUG); + return false; + } + self::$destroy = true; + return self::$resource; + } else { + return false; + } + } + + /** + * @brief Checks if image resource is valid and assigns it to self::$resource. + * @param $res An image resource. + * @returns An image resource or false on error + */ + static public function loadFromResource($res) { + if(!is_resource($res)) { + return false; + } + self::$resource = $res; + } + + /** + * @brief Resizes the image preserving ratio. + * @param $maxsize The maximum size of either the width or height. + * @returns bool + */ + public function resize($maxsize) { + if(!self::$resource) { + OC_Log::write('core','OC_Image::resize, No image loaded', OC_Log::ERROR); + throw new Exception('OC_Image::resize, No image loaded!', self::ERR_NO_IMAGE); + } + $width_orig=imageSX(self::$resource); + $height_orig=imageSY(self::$resource); + $ratio_orig = $width_orig/$height_orig; + + if ($ratio_orig > 1) { + $new_height = round($maxsize/$ratio_orig); + $new_width = $maxsize; + } else { + $new_width = round($maxsize*$ratio_orig); + $new_height = $maxsize; + } + + $process = imagecreatetruecolor(round($new_width), round($new_height)); + if ($process == false) { + OC_Log::write('core','OC_Image::resize. Error creating true color image',OC_Log::ERROR); + imagedestroy($process); + return false; + } + + imagecopyresampled($process, self::$resource, 0, 0, 0, 0, $new_width, $new_height, $width_orig, $height_orig); + if ($process == false) { + OC_Log::write('core','OC_Image::resize. Error resampling process image '.$new_width.'x'.$new_height,OC_Log::ERROR); + imagedestroy($process); + return false; + } + self::$resource = $process; + return true; + } + + /** + * @brief Crops the image to the middle square. If the image is already square it just returns. + * @returns bool for success or failure + */ + public function centerCrop() { + if(!self::$resource) { + OC_Log::write('core','OC_Image::centerCrop, No image loaded', OC_Log::ERROR); + return false; + } + $width_orig=imageSX(self::$resource); + $height_orig=imageSY(self::$resource); + OC_Log::write('core','OC_Image::centerCrop. Original size: '.$width_orig.'x'.$height_orig, OC_Log::DEBUG); + if($width_orig === $height_orig) { + return true; + } + $ratio_orig = $width_orig/$height_orig; + OC_Log::write('core','OC_Image::centerCrop. Ratio: '.$ratio_orig, OC_Log::DEBUG); + $width = $height = min($width_orig, $height_orig); + OC_Log::write('core','OC_Image::centerCrop. New size: '.$width.'x'.$height, OC_Log::DEBUG); + + if ($ratio_orig > 1) { + $x = ($width_orig/2) - ($width/2); + $y = 0; + } else { + $y = ($height_orig/2) - ($height/2); + $x = 0; + } + $process = imagecreatetruecolor($width, $height); + if ($process == false) { + OC_Log::write('core','OC_Image::centerCrop. Error creating true color image',OC_Log::ERROR); + imagedestroy($process); + return false; + } + imagecopyresampled($process, self::$resource, 0, 0, $x, $y, $width, $height, $width, $height); + if ($process == false) { + OC_Log::write('core','OC_Image::centerCrop. Error resampling process image '.$width.'x'.$height,OC_Log::ERROR); + imagedestroy($process); + return false; + } + self::$resource = $process; + return true; + } + + /** + * @brief Crops the image from point $x$y with dimension $wx$h. + * @param $x Horizontal position + * @param $y Vertical position + * @param $w Width + * @param $h Hight + * @returns bool for success or failure + */ + public function crop($x, $y, $w, $h) { + if(!self::$resource) { + OC_Log::write('core','OC_Image::crop, No image loaded', OC_Log::ERROR); + return false; + } + $width_orig=imageSX(self::$resource); + $height_orig=imageSY(self::$resource); + //OC_Log::write('core','OC_Image::crop. Original size: '.$width_orig.'x'.$height_orig, OC_Log::DEBUG); + $process = imagecreatetruecolor($w, $h); + if ($process == false) { + OC_Log::write('core','OC_Image::crop. Error creating true color image',OC_Log::ERROR); + imagedestroy($process); + return false; + } + imagecopyresampled($process, self::$resource, 0, 0, $x, $y, $w, $h, $w, $h); + if ($process == false) { + OC_Log::write('core','OC_Image::crop. Error resampling process image '.$w.'x'.$h,OC_Log::ERROR); + imagedestroy($process); + return false; + } + self::$resource = $process; + return true; + } +} From c500c1e9307fd10f009f19351a101083969bfed2 Mon Sep 17 00:00:00 2001 From: Thomas Tanghus Date: Sun, 1 Jan 2012 18:07:46 +0100 Subject: [PATCH 05/16] Removed some denug statements and an exception thrown. --- lib/image.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/image.php b/lib/image.php index 4b63ea5ff3..67290d21f3 100644 --- a/lib/image.php +++ b/lib/image.php @@ -189,7 +189,7 @@ class OC_Image { public function resize($maxsize) { if(!self::$resource) { OC_Log::write('core','OC_Image::resize, No image loaded', OC_Log::ERROR); - throw new Exception('OC_Image::resize, No image loaded!', self::ERR_NO_IMAGE); + return false; } $width_orig=imageSX(self::$resource); $height_orig=imageSY(self::$resource); @@ -231,14 +231,11 @@ class OC_Image { } $width_orig=imageSX(self::$resource); $height_orig=imageSY(self::$resource); - OC_Log::write('core','OC_Image::centerCrop. Original size: '.$width_orig.'x'.$height_orig, OC_Log::DEBUG); if($width_orig === $height_orig) { return true; } $ratio_orig = $width_orig/$height_orig; - OC_Log::write('core','OC_Image::centerCrop. Ratio: '.$ratio_orig, OC_Log::DEBUG); $width = $height = min($width_orig, $height_orig); - OC_Log::write('core','OC_Image::centerCrop. New size: '.$width.'x'.$height, OC_Log::DEBUG); if ($ratio_orig > 1) { $x = ($width_orig/2) - ($width/2); From 929ce2b56621ceda47b910a0fea5452f01812554 Mon Sep 17 00:00:00 2001 From: Thomas Tanghus Date: Sun, 1 Jan 2012 20:06:35 +0100 Subject: [PATCH 06/16] Small fixes --- lib/image.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/image.php b/lib/image.php index 67290d21f3..0e1d1ee327 100644 --- a/lib/image.php +++ b/lib/image.php @@ -55,6 +55,15 @@ class OC_Image { } } + /** + * @brief Determine whether the object contains an image resource. + * returns bool + */ + function empty() { + if(self::$resource && self::$destroy) { + } + } + /** * @brief Prints the image. */ @@ -116,9 +125,6 @@ class OC_Image { * @returns An image resource or false on error */ static public function loadFromFile($imagepath=false) { - if(!is_string($imagepath)) { - return false; - } if(!is_file($imagepath) || !file_exists($imagepath) || !is_readable($imagepath)) { OC_Log::write('core','OC_Image::loadFromFile, couldn\'t load'.$imagepath, OC_Log::DEBUG); return false; From 312e7993bb8edf95a746e62d9b3816d3a0e62fad Mon Sep 17 00:00:00 2001 From: Thomas Tanghus Date: Sun, 1 Jan 2012 23:26:24 +0100 Subject: [PATCH 07/16] Added image type specific loading and displaying. Added method 'valid()' to tell if image contains a valid resource. Renamed imageResource() to resource(). --- lib/image.php | 139 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 128 insertions(+), 11 deletions(-) diff --git a/lib/image.php b/lib/image.php index 0e1d1ee327..b23e3507c3 100644 --- a/lib/image.php +++ b/lib/image.php @@ -21,6 +21,18 @@ * */ +/** From user comments at http://dk2.php.net/manual/en/function.exif-imagetype.php + * Don't know if it can come in handy? +if ( ! function_exists( 'exif_imagetype' ) ) { + function exif_imagetype ( $filename ) { + if ( ( list($width, $height, $type, $attr) = getimagesize( $filename ) ) !== false ) { + return $type; + } + return false; + } +} +*/ + /** * Class for image manipulation * Ideas: imagerotate, chunk_split(base64_encode()) @@ -29,6 +41,7 @@ class OC_Image { static private $resource = false; // tmp resource. static private $destroy = false; // if the resource is created withing the object. + static private $imagetype = IMAGETYPE_PNG; // Default to png if file type isn't evident. /** * @brief Constructor. * @param $imageref The path to a local file, a base64 encoded string or a resource created by an imagecreate* function. @@ -50,26 +63,69 @@ class OC_Image { * @brief Destructor. */ function __destruct() { - if(self::$resource && self::$destroy) { + if(is_resource(self::$resource) && self::$destroy) { imagedestroy(self::$resource); // Why does this issue a warning. } } /** * @brief Determine whether the object contains an image resource. - * returns bool + * @returns bool */ - function empty() { - if(self::$resource && self::$destroy) { - } + public function valid() { // apparently you can't name a method 'empty'... + $ret = is_resource(self::$resource); + return $ret; + } + + /** + * @brief Returns the MIME type of the image or an empty string if no image is loaded. + * @returns int + */ + public function mimeType() { + return is_resource(self::$resource) ? image_type_to_mime_type(self::$imagetype) : ''; + } + + /** + * @brief Returns the width of the image or -1 if no image is loaded. + * @returns int + */ + public function width() { + return is_resource(self::$resource) ? imagesx(self::$resource) : -1; + } + + /** + * @brief Returns the height of the image or -1 if no image is loaded. + * @returns int + */ + public function height() { + return is_resource(self::$resource) ? imagesy(self::$resource) : -1; } /** * @brief Prints the image. */ public function show() { - header('Content-Type: image/png'); - imagepng(self::$resource); + header('Content-Type: '.self::mimeType()); + switch(self::$imagetype) { + case IMAGETYPE_GIF: + imagegif(self::$resource); + break; + case IMAGETYPE_JPEG: + imagepng(self::$resource); + break; + case IMAGETYPE_PNG: + imagejpeg(self::$resource); + break; + case IMAGETYPE_XBM: + imagexbm(self::$resource); + break; + case IMAGETYPE_WBMP: + case IMAGETYPE_BMP: + imagewbmp(self::$resource); + break; + default: + imagepng(self::$resource); + } } /** @@ -82,7 +138,7 @@ class OC_Image { /** * @returns Returns the image resource in any. */ - public function imageResource() { + public function resource() { return self::$resource; } @@ -126,11 +182,72 @@ class OC_Image { */ static public function loadFromFile($imagepath=false) { if(!is_file($imagepath) || !file_exists($imagepath) || !is_readable($imagepath)) { - OC_Log::write('core','OC_Image::loadFromFile, couldn\'t load'.$imagepath, OC_Log::DEBUG); + OC_Log::write('core','OC_Image::loadFromFile, couldn\'t load', OC_Log::DEBUG); return false; } - self::$resource = imagecreatefromstring(file_get_contents($imagepath)); - self::$destroy = true; + $itype = exif_imagetype($imagepath); + switch($itype) { + case IMAGETYPE_GIF: + if (imagetypes() & IMG_GIF) { + self::$resource = imagecreatefromgif($imagepath); + } + break; + case IMAGETYPE_JPEG: + if (imagetypes() & IMG_JPG) { + self::$resource = imagecreatefromjpeg($imagepath); + } + break; + case IMAGETYPE_PNG: + if (imagetypes() & IMG_PNG) { + self::$resource = imagecreatefrompng($imagepath); + } + break; + case IMAGETYPE_XBM: + if (imagetypes() & IMG_XPM) { + self::$resource = imagecreatefromxbm($imagepath); + } + break; + case IMAGETYPE_WBMP: + case IMAGETYPE_BMP: + if (imagetypes() & IMG_WBMP) { + self::$resource = imagecreatefromwbmp($imagepath); + } + break; + /* + case IMAGETYPE_TIFF_II: // (intel byte order) + break; + case IMAGETYPE_TIFF_MM: // (motorola byte order) + break; + case IMAGETYPE_JPC: + break; + case IMAGETYPE_JP2: + break; + case IMAGETYPE_JPX: + break; + case IMAGETYPE_JB2: + break; + case IMAGETYPE_SWC: + break; + case IMAGETYPE_IFF: + break; + case IMAGETYPE_ICO: + break; + case IMAGETYPE_SWF: + break; + case IMAGETYPE_PSD: + break; + */ + default: + self::$resource = imagecreatefromstring(file_get_contents($imagepath)); + $itype = IMAGETYPE_PNG; + OC_Log::write('core','OC_Image::loadFromFile, Default', OC_Log::DEBUG); + break; + } + // if($this->valid()) { // FIXME: I get an error: "PHP Fatal error: Using $this when not in object context..." WTF? + if(self::valid()) { // And here I get a warning: "PHP Strict Standards: Non-static method OC_Image::valid() should not be called statically..." valid() shouldn't be a static member as it would fail on a non-instantiated class. + self::$imagetype = $itype; + self::$destroy = true; + } return self::$resource; } From db6738478b6e0efe5a2484151e01e37ae358ac18 Mon Sep 17 00:00:00 2001 From: Thomas Tanghus Date: Sun, 1 Jan 2012 23:34:26 +0100 Subject: [PATCH 08/16] Mixed up two lines :-P --- lib/image.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/image.php b/lib/image.php index b23e3507c3..a8948956bf 100644 --- a/lib/image.php +++ b/lib/image.php @@ -111,10 +111,10 @@ class OC_Image { imagegif(self::$resource); break; case IMAGETYPE_JPEG: - imagepng(self::$resource); + imagejpeg(self::$resource); break; case IMAGETYPE_PNG: - imagejpeg(self::$resource); + imagepng(self::$resource); break; case IMAGETYPE_XBM: imagexbm(self::$resource); From a8789ebe2975564bee851b895d636d7503135257 Mon Sep 17 00:00:00 2001 From: Thomas Tanghus Date: Mon, 2 Jan 2012 00:43:27 +0100 Subject: [PATCH 09/16] Removed static declaration from loadFrom* methods. --- lib/image.php | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/lib/image.php b/lib/image.php index a8948956bf..21580f40b8 100644 --- a/lib/image.php +++ b/lib/image.php @@ -160,7 +160,7 @@ class OC_Image { * If a resource is passed it is the job of the caller to destroy it using imagedestroy($var) * @returns An image resource or false on error */ - static public function load($imageref) { + public function load($imageref) { if(self::loadFromFile($imageref) !== false) { return self::$resource; } elseif(self::loadFromBase64($imageref) !== false) { @@ -180,7 +180,7 @@ class OC_Image { * @param $imageref The path to a local file. * @returns An image resource or false on error */ - static public function loadFromFile($imagepath=false) { + public function loadFromFile($imagepath=false) { if(!is_file($imagepath) || !file_exists($imagepath) || !is_readable($imagepath)) { OC_Log::write('core','OC_Image::loadFromFile, couldn\'t load', OC_Log::DEBUG); return false; @@ -243,8 +243,7 @@ class OC_Image { OC_Log::write('core','OC_Image::loadFromFile, Default', OC_Log::DEBUG); break; } - // if($this->valid()) { // FIXME: I get an error: "PHP Fatal error: Using $this when not in object context..." WTF? - if(self::valid()) { // And here I get a warning: "PHP Strict Standards: Non-static method OC_Image::valid() should not be called statically..." valid() shouldn't be a static member as it would fail on a non-instantiated class. + if($this->valid()) { self::$imagetype = $itype; self::$destroy = true; } @@ -256,7 +255,7 @@ class OC_Image { * @param $str A string of image data as read from a file. * @returns An image resource or false on error */ - static public function loadFromData($str) { + public function loadFromData($str) { if(is_resource($str)) { return false; } @@ -274,7 +273,7 @@ class OC_Image { * @param $str A string base64 encoded string of image data. * @returns An image resource or false on error */ - static public function loadFromBase64($str) { + public function loadFromBase64($str) { if(!is_string($str)) { return false; } @@ -297,7 +296,7 @@ class OC_Image { * @param $res An image resource. * @returns An image resource or false on error */ - static public function loadFromResource($res) { + public function loadFromResource($res) { if(!is_resource($res)) { return false; } From 534b6f3a098c8f2bb5993592e73f5af75c3c86bc Mon Sep 17 00:00:00 2001 From: Georg Ehrke Date: Mon, 2 Jan 2012 11:49:53 +0100 Subject: [PATCH 10/16] Fix whitespace username --- lib/user.php | 2 +- settings/js/users.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/user.php b/lib/user.php index 241d9aa8b1..0a5881ec0f 100644 --- a/lib/user.php +++ b/lib/user.php @@ -120,7 +120,7 @@ class OC_User { return false; } // No empty username - if( !$uid ){ + if(trim($uid) == ''){ return false; } // Check if user already exists diff --git a/settings/js/users.js b/settings/js/users.js index 4fea52e4a1..79b4e80870 100644 --- a/settings/js/users.js +++ b/settings/js/users.js @@ -126,7 +126,7 @@ $(document).ready(function(){ $('#newuser').submit(function(event){ event.preventDefault(); var username=$('#newusername').val(); - if(username == '') { + if($.trim(username) == '') { alert('Please provide a username!'); return false; } From c62c55fb81ced8710ab0290c272a1c0922640afd Mon Sep 17 00:00:00 2001 From: Thomas Tanghus Date: Mon, 2 Jan 2012 12:09:45 +0100 Subject: [PATCH 11/16] Added save() to OC_Image. --- lib/image.php | 53 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 44 insertions(+), 9 deletions(-) diff --git a/lib/image.php b/lib/image.php index 21580f40b8..57a0caa140 100644 --- a/lib/image.php +++ b/lib/image.php @@ -42,6 +42,7 @@ class OC_Image { static private $resource = false; // tmp resource. static private $destroy = false; // if the resource is created withing the object. static private $imagetype = IMAGETYPE_PNG; // Default to png if file type isn't evident. + static private $filepath = null; /** * @brief Constructor. * @param $imageref The path to a local file, a base64 encoded string or a resource created by an imagecreate* function. @@ -49,7 +50,7 @@ class OC_Image { * @returns bool False on error */ function __construct($imageref = null) { - OC_Log::write('core','OC_Image::__construct, start', OC_Log::DEBUG); + //OC_Log::write('core','OC_Image::__construct, start', OC_Log::DEBUG); if(!function_exists('imagecreatefromjpeg')) { // FIXME: Find a better way to check for GD OC_Log::write('core','OC_Image::__construct, GD module not installed', OC_Log::ERROR); return false; @@ -102,30 +103,63 @@ class OC_Image { } /** - * @brief Prints the image. + * @brief Outputs the image. + * @returns bool */ public function show() { + return $this->_output(); + } + + /** + * @brief Saves the image. + * @returns bool + */ + public function save($filepath=null) { + if($filepath === null && $this->filepath === null) { + OC_Log::write('core','OC_Image::save. save() called with no path.', OC_Log::ERROR); + return false; + } elseif($filepath === null && $this->filepath !== null) { + $filepath = $this->filepath; + } + return $this->_output($filepath, true); + } + + /** + * @brief Outputs/saves the image. + */ + private function _output($filepath=null, $really=false) { header('Content-Type: '.self::mimeType()); + if($really === false) { + $filepath = null; // Just being cautious ;-) + } else { + // TODO: Check for writability etc. + if(!is_writable($filepath)) { + OC_Log::write('core','OC_Image::save. \''.$filepath.'\' is not writable.', OC_Log::ERROR); + return false; + } + } + $retval = false; switch(self::$imagetype) { case IMAGETYPE_GIF: - imagegif(self::$resource); + $retval = imagegif(self::$resource, $filepath); break; case IMAGETYPE_JPEG: - imagejpeg(self::$resource); + $retval = imagejpeg(self::$resource, $filepath); break; case IMAGETYPE_PNG: - imagepng(self::$resource); + $retval = imagepng(self::$resource, $filepath); break; case IMAGETYPE_XBM: - imagexbm(self::$resource); + $retval = imagexbm(self::$resource, $filepath); break; case IMAGETYPE_WBMP: case IMAGETYPE_BMP: - imagewbmp(self::$resource); + $retval = imagewbmp(self::$resource, $filepath); break; default: - imagepng(self::$resource); + $retval = imagepng(self::$resource, $filepath); } + return $retval; } /** @@ -186,7 +220,7 @@ class OC_Image { return false; } $itype = exif_imagetype($imagepath); - switch($itype) { + switch($itype) { // TODO: Log if image type is not supported. case IMAGETYPE_GIF: if (imagetypes() & IMG_GIF) { self::$resource = imagecreatefromgif($imagepath); @@ -245,6 +279,7 @@ class OC_Image { } if($this->valid()) { self::$imagetype = $itype; + self::$filepath = $imagepath; self::$destroy = true; } return self::$resource; From 6a7fbf9d136c44c7bdb9fab80354cbf44fadc105 Mon Sep 17 00:00:00 2001 From: Thomas Tanghus Date: Mon, 2 Jan 2012 13:40:23 +0100 Subject: [PATCH 12/16] Added more error checking and debug on missing image support. --- lib/image.php | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/lib/image.php b/lib/image.php index 57a0caa140..b797f331f4 100644 --- a/lib/image.php +++ b/lib/image.php @@ -33,6 +33,14 @@ if ( ! function_exists( 'exif_imagetype' ) ) { } */ +function ellipsis($str, $maxlen) { + if (strlen($str) > $maxlen) { + $characters = floor($maxlen / 2); + return substr($str, 0, $characters) . '...' . substr($str, -1 * $characters); + } + return $str; +} + /** * Class for image manipulation * Ideas: imagerotate, chunk_split(base64_encode()) @@ -51,7 +59,8 @@ class OC_Image { */ function __construct($imageref = null) { //OC_Log::write('core','OC_Image::__construct, start', OC_Log::DEBUG); - if(!function_exists('imagecreatefromjpeg')) { // FIXME: Find a better way to check for GD + if(!extension_loaded('gd') || !function_exists('gd_info')) { + //if(!function_exists('imagecreatefromjpeg')) { OC_Log::write('core','OC_Image::__construct, GD module not installed', OC_Log::ERROR); return false; } @@ -114,6 +123,7 @@ class OC_Image { * @brief Saves the image. * @returns bool */ + public function save($filepath=null) { if($filepath === null && $this->filepath === null) { OC_Log::write('core','OC_Image::save. save() called with no path.', OC_Log::ERROR); @@ -132,9 +142,11 @@ class OC_Image { if($really === false) { $filepath = null; // Just being cautious ;-) } else { - // TODO: Check for writability etc. - if(!is_writable($filepath)) { - OC_Log::write('core','OC_Image::save. \''.$filepath.'\' is not writable.', OC_Log::ERROR); + if(!is_writable(dirname($filepath))) { + OC_Log::write('core','OC_Image::save. Directory \''.dirname($filepath).'\' is not writable.', OC_Log::ERROR); + return false; + } elseif(is_writable(dirname($filepath)) && !is_writable($filepath)) { + OC_Log::write('core','OC_Image::save. File \''.$filepath.'\' is not writable.', OC_Log::ERROR); return false; } } @@ -216,35 +228,46 @@ class OC_Image { */ public function loadFromFile($imagepath=false) { if(!is_file($imagepath) || !file_exists($imagepath) || !is_readable($imagepath)) { - OC_Log::write('core','OC_Image::loadFromFile, couldn\'t load', OC_Log::DEBUG); + // Debug output disabled because this method is tried before loadFromBase64? + OC_Log::write('core','OC_Image::loadFromFile, couldn\'t load: '.ellipsis($imagepath, 50), OC_Log::DEBUG); return false; } $itype = exif_imagetype($imagepath); - switch($itype) { // TODO: Log if image type is not supported. + switch($itype) { case IMAGETYPE_GIF: if (imagetypes() & IMG_GIF) { self::$resource = imagecreatefromgif($imagepath); + } else { + OC_Log::write('core','OC_Image::loadFromFile, GIF images not supported: '.$imagepath, OC_Log::DEBUG); } break; case IMAGETYPE_JPEG: if (imagetypes() & IMG_JPG) { self::$resource = imagecreatefromjpeg($imagepath); + } else { + OC_Log::write('core','OC_Image::loadFromFile, JPG images not supported: '.$imagepath, OC_Log::DEBUG); } break; case IMAGETYPE_PNG: if (imagetypes() & IMG_PNG) { self::$resource = imagecreatefrompng($imagepath); + } else { + OC_Log::write('core','OC_Image::loadFromFile, PNG images not supported: '.$imagepath, OC_Log::DEBUG); } break; case IMAGETYPE_XBM: if (imagetypes() & IMG_XPM) { self::$resource = imagecreatefromxbm($imagepath); + } else { + OC_Log::write('core','OC_Image::loadFromFile, XBM/XPM images not supported: '.$imagepath, OC_Log::DEBUG); } break; case IMAGETYPE_WBMP: case IMAGETYPE_BMP: if (imagetypes() & IMG_WBMP) { self::$resource = imagecreatefromwbmp($imagepath); + } else { + OC_Log::write('core','OC_Image::loadFromFile, (W)BMP images not supported: '.$imagepath, OC_Log::DEBUG); } break; /* From a1af757ef6e99fc17d635ab05470671b41fc44db Mon Sep 17 00:00:00 2001 From: Georg Ehrke Date: Mon, 2 Jan 2012 14:21:46 +0100 Subject: [PATCH 13/16] Fix whitespace username in the installation form --- core/js/setup.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/js/setup.js b/core/js/setup.js index b765d41ba3..94097785e4 100644 --- a/core/js/setup.js +++ b/core/js/setup.js @@ -7,7 +7,9 @@ $(document).ready(function() { $('#dbhost').hide(); $('#dbhostlabel').hide(); } - + $('#adminlogin').change(function(){ + $('#adminlogin').val($.trim($('#adminlogin').val())); + }); $('#sqlite').click(function() { $('#use_other_db').slideUp(250); $('#dbhost').hide(250); From cc55f00481dd00c4db54714d79e1f13158a87850 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 2 Jan 2012 16:38:10 +0100 Subject: [PATCH 14/16] fix is_readable and is_writable --- lib/filesystem.php | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/lib/filesystem.php b/lib/filesystem.php index 1205a6aa51..627f494c93 100644 --- a/lib/filesystem.php +++ b/lib/filesystem.php @@ -199,11 +199,26 @@ class OC_Filesystem{ */ static public function getLocalFile($path){ $parent=substr($path,0,strrpos($path,'/')); - if(self::is_readable($parent) and $storage=self::getStorage($path)){ + if(self::isValidPath($parent) and $storage=self::getStorage($path)){ return $storage->getLocalFile(self::getInternalPath($path)); } } + /** + * check if the requested path is valid + * @param string path + * @return bool + */ + static public function isValidPath($path){ + if(substr($path,0,1)!=='/'){ + $path='/'.$path; + } + if(strstr($path,'/../') || strrchr($path, '/') === '/..' ){ + return false; + } + return true; + } + static public function mkdir($path){ return self::basicOperation('mkdir',$path,array('create','write')); } @@ -238,24 +253,10 @@ class OC_Filesystem{ return self::basicOperation('readfile',$path,array('read')); } static public function is_readable($path){ - if(substr($path,0,1)!=='/'){ - $path='/'.$path; - } - if(strstr($path,'/../') || strrchr($path, '/') === '/..' ){ - return false; - } - $storage=self::getStorage($path); - return $storage->is_readable(self::getInternalPath($path)); + return self::basicOperation('is_readable',$path); } static public function is_writeable($path){ - if(substr($path,0,1)!=='/'){ - $path='/'.$path; - } - if(strstr($path,'/../') || strrchr($path, '/') === '/..' ){ - return false; - } - $storage=self::getStorage($path); - return $storage->is_writeable(self::getInternalPath($path)); + return self::basicOperation('is_writeable',$path); } static public function file_exists($path){ if($path=='/'){ @@ -358,7 +359,7 @@ class OC_Filesystem{ return self::basicOperation('fopen',$path,$hooks,$mode); } static public function toTmpFile($path){ - if(OC_FileProxy::runPreProxies('toTmpFile',$path) and self::is_readable($path) and $storage=self::getStorage($path)){ + if(OC_FileProxy::runPreProxies('toTmpFile',$path) and self::isValidPath($path) and $storage=self::getStorage($path)){ OC_Hook::emit( 'OC_Filesystem', 'read', array( 'path' => $path)); return $storage->toTmpFile(self::getInternalPath($path)); } @@ -447,7 +448,7 @@ class OC_Filesystem{ * @return mixed */ private static function basicOperation($operation,$path,$hooks=array(),$extraParam=null){ - if(OC_FileProxy::runPreProxies($operation,$path, $extraParam) and self::is_readable($path) and $storage=self::getStorage($path)){ + if(OC_FileProxy::runPreProxies($operation,$path, $extraParam) and self::isValidPath($path) and $storage=self::getStorage($path)){ $interalPath=self::getInternalPath($path); $run=true; foreach($hooks as $hook){ From b8cffbc0eec099e0fb7ffbb53e7fc1dc5bbc4035 Mon Sep 17 00:00:00 2001 From: Thomas Tanghus Date: Mon, 2 Jan 2012 23:17:15 +0100 Subject: [PATCH 15/16] OC_Image::__invoke didn't return anything thus causing contacts/thumbnail.php to spit out lots of error messages. --- lib/image.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/image.php b/lib/image.php index b797f331f4..e09486be08 100644 --- a/lib/image.php +++ b/lib/image.php @@ -178,7 +178,7 @@ class OC_Image { * @brief Prints the image when called as $image(). */ public function __invoke() { - self::show(); + return self::show(); } /** From 4c8f17ad4747592cc01525c663de32962552cf18 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 3 Jan 2012 04:55:19 +0100 Subject: [PATCH 16/16] don't try to use mod_rewrite when it isn't enabled having a broken web/card/caldav is much better as having no ownCloud at all :) --- .htaccess | 2 ++ lib/setup.php | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.htaccess b/.htaccess index b181f8b845..86a2de6b94 100644 --- a/.htaccess +++ b/.htaccess @@ -5,6 +5,8 @@ php_value post_max_size 512M php_value memory_limit 512M SetEnv htaccessWorking true + RewriteEngine on RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization},last] + Options -Indexes diff --git a/lib/setup.php b/lib/setup.php index 8afe0070e9..b53c626c9a 100644 --- a/lib/setup.php +++ b/lib/setup.php @@ -275,7 +275,7 @@ class OC_Setup { $content.= "php_value post_max_size 512M\n"; $content.= "SetEnv htaccessWorking true\n"; $content.= "\n"; - $content.= "\n"; + $content.= ""; $content.= "RewriteEngine on\n"; $content.= "RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization},last]\n"; $content.= "\n";