Merge branch 'master' into migration

This commit is contained in:
Tom Needham 2012-03-27 20:19:38 +00:00
commit c8acd4a594
142 changed files with 4438 additions and 2638 deletions

View File

@ -1,3 +1,4 @@
ErrorDocument 403 /core/templates/403.php
ErrorDocument 404 /core/templates/404.php
<IfModule mod_php5.c>
php_value upload_max_filesize 512M

View File

@ -5,6 +5,13 @@ ownCloud is written by:
Jan-Christoph Borchardt
Michael Gapczynski
Arthur Schiwon
Bart Visscher
Georg Ehrke
Brice Maron
Tom Needham
Marvin Thomas Rabe
Florian Pritz
Bartek Przybylski
With help from many libraries and frameworks including:

View File

@ -71,7 +71,7 @@ function getURLMetadata($url) {
return $metadata;
}
function addBookmark($url, $title='', $tags='') {
function addBookmark($url, $title, $tags='') {
$CONFIG_DBTYPE = OC_Config::getValue( "dbtype", "sqlite" );
if( $CONFIG_DBTYPE == 'sqlite' or $CONFIG_DBTYPE == 'sqlite3' ){
$_ut = "strftime('%s','now')";
@ -93,6 +93,11 @@ function addBookmark($url, $title='', $tags='') {
$title = $metadata['title'];
}
if(empty($title)) {
$l = new OC_L10N('bookmarks');
$title = $l->t('unnamed');
}
$params=array(
htmlspecialchars_decode($url),
htmlspecialchars_decode($title),

View File

@ -9,9 +9,7 @@ $(document).ready(function() {
fillWindow($('.bookmarks_list'));
});
$(window).resize();
$($('.bookmarks_list')).scroll(updateOnBottom);
$('.bookmarks_list').empty();
$('.bookmarks_list').scroll(updateOnBottom).empty().width($('#content').width());
getBookmarks();
});
@ -145,7 +143,7 @@ function updateBookmarksList(bookmark) {
'<p class="bookmark_title">'+
'<a href="' + encodeEntities(bookmark.url) + '" target="_blank" class="bookmark_link">' + encodeEntities(bookmark.title) + '</a>' +
'</p>' +
'<p class="bookmark_url">' + encodeEntities(bookmark.url) + '</p>' +
'<p class="bookmark_url"><a href="' + encodeEntities(bookmark.url) + '" target="_blank" class="bookmark_link">' + encodeEntities(bookmark.url) + '</a></p>' +
'</div>'
);
if(taglist != '') {

View File

@ -8,11 +8,13 @@
require_once ('../../../lib/base.php');
require_once('when/When.php');
$l = new OC_L10N('calendar');
$unnamed = $l->t('unnamed');
function create_return_event($event, $vevent){
$return_event = array();
global $unnamed;
$return_event['id'] = (int)$event['id'];
$return_event['title'] = htmlspecialchars($event['summary']);
$return_event['title'] = htmlspecialchars(($event['summary']!=NULL || $event['summary'] != '')?$event['summary']: $unnamed);
$return_event['description'] = isset($vevent->DESCRIPTION)?htmlspecialchars($vevent->DESCRIPTION->value):'';
$last_modified = $vevent->__get('LAST-MODIFIED');
if ($last_modified){
@ -27,8 +29,13 @@ function create_return_event($event, $vevent){
OC_JSON::checkLoggedIn();
OC_JSON::checkAppEnabled('calendar');
$start = DateTime::createFromFormat('U', $_GET['start']);
$end = DateTime::createFromFormat('U', $_GET['end']);
if(version_compare(PHP_VERSION, '5.3.0', '>=')){
$start = DateTime::createFromFormat('U', $_GET['start']);
$end = DateTime::createFromFormat('U', $_GET['end']);
}else{
$start = new DateTime('@' . $_GET['start']);
$end = new DateTime('@' . $_GET['end']);
}
$calendar_id = $_GET['calendar_id'];
if (is_numeric($calendar_id)) {

View File

@ -1,25 +1,23 @@
<?php
if(version_compare(PHP_VERSION, '5.3.0', '>=')){
$l=new OC_L10N('calendar');
OC::$CLASSPATH['OC_Calendar_App'] = 'apps/calendar/lib/app.php';
OC::$CLASSPATH['OC_Calendar_Calendar'] = 'apps/calendar/lib/calendar.php';
OC::$CLASSPATH['OC_Calendar_Object'] = 'apps/calendar/lib/object.php';
OC::$CLASSPATH['OC_Calendar_Hooks'] = 'apps/calendar/lib/hooks.php';
OC::$CLASSPATH['OC_Connector_Sabre_CalDAV'] = 'apps/calendar/lib/connector_sabre.php';
OC::$CLASSPATH['OC_Search_Provider_Calendar'] = 'apps/calendar/lib/search.php';
OC_HOOK::connect('OC_User', 'post_deleteUser', 'OC_Calendar_Hooks', 'deleteUser');
OC_Hook::connect('OC_DAV', 'initialize', 'OC_Calendar_Hooks', 'initializeCalDAV');
OC_Util::addScript('calendar','loader');
OC_App::register( array(
'order' => 10,
'id' => 'calendar',
'name' => 'Calendar' ));
OC_App::addNavigationEntry( array(
'id' => 'calendar_index',
'order' => 10,
'href' => OC_Helper::linkTo( 'calendar', 'index.php' ),
'icon' => OC_Helper::imagePath( 'calendar', 'icon.svg' ),
'name' => $l->t('Calendar')));
OC_App::registerPersonal('calendar', 'settings');
OC_Search::registerProvider('OC_Search_Provider_Calendar');
}
$l=new OC_L10N('calendar');
OC::$CLASSPATH['OC_Calendar_App'] = 'apps/calendar/lib/app.php';
OC::$CLASSPATH['OC_Calendar_Calendar'] = 'apps/calendar/lib/calendar.php';
OC::$CLASSPATH['OC_Calendar_Object'] = 'apps/calendar/lib/object.php';
OC::$CLASSPATH['OC_Calendar_Hooks'] = 'apps/calendar/lib/hooks.php';
OC::$CLASSPATH['OC_Connector_Sabre_CalDAV'] = 'apps/calendar/lib/connector_sabre.php';
OC::$CLASSPATH['OC_Search_Provider_Calendar'] = 'apps/calendar/lib/search.php';
OC_HOOK::connect('OC_User', 'post_deleteUser', 'OC_Calendar_Hooks', 'deleteUser');
OC_Hook::connect('OC_DAV', 'initialize', 'OC_Calendar_Hooks', 'initializeCalDAV');
OC_Util::addScript('calendar','loader');
OC_App::register( array(
'order' => 10,
'id' => 'calendar',
'name' => 'Calendar' ));
OC_App::addNavigationEntry( array(
'id' => 'calendar_index',
'order' => 10,
'href' => OC_Helper::linkTo( 'calendar', 'index.php' ),
'icon' => OC_Helper::imagePath( 'calendar', 'icon.svg' ),
'name' => $l->t('Calendar')));
OC_App::registerPersonal('calendar', 'settings');
OC_Search::registerProvider('OC_Search_Provider_Calendar');

View File

@ -96,8 +96,7 @@ class OC_Calendar_Object{
list($type,$startdate,$enddate,$summary,$repeating,$uid) = self::extractData($object);
if(is_null($uid)){
$uid = self::createUID();
$object->add('UID',$uid);
$object->setUID();
$data = $object->serialize();
}
@ -208,14 +207,6 @@ class OC_Calendar_Object{
return true;
}
/**
* @brief Creates a UID
* @return string
*/
protected static function createUID(){
return substr(md5(rand().time()),0,10);
}
/**
* @brief Extracts data from a vObject-Object
* @param Sabre_VObject $object

View File

@ -31,7 +31,7 @@
</select><input type="checkbox" name="timezonedetection" id="timezonedetection"><label for="timezonedetection"><?php echo $l->t('Check always for changes of the timezone'); ?></label></td></tr>
<tr><td><label for="timeformat" class="bold"><?php echo $l->t('Timeformat');?></label></td><td>
<select style="display: none;" id="timeformat" title="<?php echo "timeformat"; ?>" name="timeformat">
<select style="display: none; width: 60px;" id="timeformat" title="<?php echo "timeformat"; ?>" name="timeformat">
<option value="24" id="24h"><?php echo $l->t("24h"); ?></option>
<option value="ampm" id="ampm"><?php echo $l->t("12h"); ?></option>
</select>

View File

@ -1,103 +0,0 @@
<?php
/**
* ownCloud - Addressbook
*
* @author Jakob Sack
* @copyright 2011 Jakob Sack mail@jakobsack.de
*
* 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/>.
*
*/
// Init owncloud
require_once('../../../lib/base.php');
function bailOut($msg) {
OC_JSON::error(array('data' => array('message' => $msg)));
OC_Log::write('contacts','ajax/addcard.php: '.$msg, OC_Log::DEBUG);
exit();
}
// Check if we are a user
OC_JSON::checkLoggedIn();
OC_JSON::checkAppEnabled('contacts');
$aid = $_POST['id'];
OC_Contacts_App::getAddressbook( $aid ); // is owner access check
$fn = trim($_POST['fn']);
$values = $_POST['value'];
$parameters = $_POST['parameters'];
$vcard = new OC_VObject('VCARD');
$vcard->setUID();
$n = isset($values['N'][0])?trim($values['N'][0]).';':';';
$n .= isset($values['N'][1])?trim($values['N'][1]).';':';';
$n .= isset($values['N'][2])?trim($values['N'][2]).';;':';;';
if(!$fn || ($n == ';;;;')) {
bailOut('You have to enter both the extended name and the display name.');
}
$vcard->setString('N',$n);
$vcard->setString('FN',$fn);
// Data to add ...
$add = array('TEL', 'EMAIL', 'ORG');
$address = false;
for($i = 0; $i < 7; $i++){
if( isset($values['ADR'][$i] ) && $values['ADR'][$i]) $address = true;
}
if( $address ) $add[] = 'ADR';
// Add data
foreach( $add as $propname){
if( !( isset( $values[$propname] ) && $values[$propname] )){
continue;
}
$value = $values[$propname];
if( isset( $parameters[$propname] ) && count( $parameters[$propname] )){
$prop_parameters = $parameters[$propname];
} else {
$prop_parameters = array();
}
if(is_array($value)){
ksort($value); // NOTE: Important, otherwise the compound value will be set in the order the fields appear in the form!
$value = OC_VObject::escapeSemicolons($value);
}
$vcard->addProperty($propname, strip_tags($value)); //, $prop_parameters);
$line = count($vcard->children) - 1;
foreach ($prop_parameters as $key=>$element) {
if(is_array($element) && strtoupper($key) == 'TYPE') {
// FIXME: Maybe this doesn't only apply for TYPE?
// And it probably shouldn't be done here anyways :-/
foreach($element as $e){
if($e != '' && !is_null($e)){
$vcard->children[$line]->parameters[] = new Sabre_VObject_Parameter($key,$e);
}
}
} else {
$vcard->children[$line]->parameters[] = new Sabre_VObject_Parameter($key,$element);
}
}
}
$id = OC_Contacts_VCard::add($aid,$vcard->serialize());
if(!$id) {
OC_JSON::error(array('data' => array('message' => OC_Contacts_App::$l10n->t('There was an error adding the contact.'))));
OC_Log::write('contacts','ajax/addcard.php: Recieved non-positive ID on adding card: '.$id, OC_Log::ERROR);
exit();
}
// NOTE: Why is this in OC_Contacts_App?
OC_Contacts_App::renderDetails($id, $vcard);

View File

@ -52,7 +52,7 @@ $vcard->setUID();
$vcard->setString('FN',$fn);
$vcard->setString('N',$n);
$id = OC_Contacts_VCard::add($aid,$vcard->serialize());
$id = OC_Contacts_VCard::add($aid,$vcard);
if(!$id) {
OC_JSON::error(array('data' => array('message' => OC_Contacts_App::$l10n->t('There was an error adding the contact.'))));
OC_Log::write('contacts','ajax/addcontact.php: Recieved non-positive ID on adding card: '.$id, OC_Log::ERROR);

View File

@ -27,14 +27,16 @@ require_once('../../../lib/base.php');
OC_JSON::checkLoggedIn();
OC_JSON::checkAppEnabled('contacts');
$id = $_POST['id'];
$vcard = OC_Contacts_App::getContactVCard( $id );
$id = isset($_POST['id'])?$_POST['id']:null;
$name = isset($_POST['name'])?$_POST['name']:null;
$value = isset($_POST['value'])?$_POST['value']:null;
$parameters = isset($_POST['parameters'])?$_POST['parameters']:array();
$vcard = OC_Contacts_App::getContactVCard($id);
$name = $_POST['name'];
$value = $_POST['value'];
if(!is_array($value)){
$value = trim($value);
if(!$value && in_array($name, array('TEL', 'EMAIL', 'ORG', 'BDAY', 'NICKNAME'))) {
if(!$value && in_array($name, array('TEL', 'EMAIL', 'ORG', 'BDAY', 'NICKNAME', 'NOTE'))) {
OC_JSON::error(array('data' => array('message' => OC_Contacts_App::$l10n->t('Cannot add empty property.'))));
exit();
}
@ -51,7 +53,6 @@ if(!is_array($value)){
exit();
}
}
$parameters = isset($_POST['parameters']) ? $_POST['parameters'] : array();
// Prevent setting a duplicate entry
$current = $vcard->select($name);
@ -82,7 +83,9 @@ switch($name) {
}
case 'N':
case 'ORG':
case 'NOTE':
case 'NICKNAME':
// TODO: Escape commas and semicolons.
break;
case 'EMAIL':
$value = strtolower($value);
@ -113,19 +116,10 @@ foreach ($parameters as $key=>$element) {
}
$checksum = md5($vcard->children[$line]->serialize());
if(!OC_Contacts_VCard::edit($id,$vcard->serialize())) {
if(!OC_Contacts_VCard::edit($id,$vcard)) {
OC_JSON::error(array('data' => array('message' => OC_Contacts_App::$l10n->t('Error adding contact property.'))));
OC_Log::write('contacts','ajax/addproperty.php: Error updating contact property: '.$name, OC_Log::ERROR);
exit();
}
$adr_types = OC_Contacts_App::getTypesOfProperty('ADR');
$phone_types = OC_Contacts_App::getTypesOfProperty('TEL');
$tmpl = new OC_Template('contacts','part.property');
$tmpl->assign('adr_types',$adr_types);
$tmpl->assign('phone_types',$phone_types);
$tmpl->assign('property',OC_Contacts_VCard::structureProperty($property,$line));
$page = $tmpl->fetchPage();
OC_JSON::success(array('data' => array( 'checksum' => $checksum, 'page' => $page )));
OC_JSON::success(array('data' => array( 'checksum' => $checksum )));

View File

@ -0,0 +1,28 @@
<?php
/**
* Copyright (c) 2012 Thomas Tanghus <thomas@tanghus.net>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
require_once('../../../../lib/base.php');
OC_JSON::checkLoggedIn();
OC_JSON::checkAppEnabled('contacts');
$id = isset($_GET['id'])?$_GET['id']:null;
if(is_null($id)) {
OC_JSON::error(array('data' => array('message' => OC_Contacts_App::$l10n->t('No ID provided'))));
exit();
}
$vcard = OC_Contacts_App::getContactVCard( $id );
foreach($vcard->children as $property){
//OC_Log::write('contacts','ajax/categories/checksumfor.php: '.$property->name, OC_Log::DEBUG);
if($property->name == 'CATEGORIES') {
$checksum = md5($property->serialize());
OC_JSON::success(array('data' => array('value'=>$property->value, 'checksum'=>$checksum)));
exit();
}
}
OC_JSON::error(array('data' => array('message' => OC_Contacts_App::$l10n->t('Error setting checksum.'))));
?>

View File

@ -0,0 +1,60 @@
<?php
/**
* Copyright (c) 2012 Thomas Tanghus <thomas@tanghus.net>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
require_once('../../../../lib/base.php');
OC_JSON::checkLoggedIn();
OC_JSON::checkAppEnabled('contacts');
foreach ($_POST as $key=>$element) {
debug('_POST: '.$key.'=>'.print_r($element, true));
}
function bailOut($msg) {
OC_JSON::error(array('data' => array('message' => $msg)));
OC_Log::write('contacts','ajax/categories/delete.php: '.$msg, OC_Log::DEBUG);
exit();
}
function debug($msg) {
OC_Log::write('contacts','ajax/categories/delete.php: '.$msg, OC_Log::DEBUG);
}
$categories = isset($_POST['categories'])?$_POST['categories']:null;
if(is_null($categories)) {
bailOut(OC_Contacts_App::$l10n->t('No categories selected for deletion.'));
}
debug(print_r($categories, true));
$addressbooks = OC_Contacts_Addressbook::all(OC_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.'));
}
$cards = array();
foreach($contacts as $contact) {
$cards[] = array($contact['id'], $contact['carddata']);
}
debug('Before delete: '.print_r($categories, true));
$catman = new OC_VCategories('contacts');
$catman->delete($categories, $cards);
debug('After delete: '.print_r($catman->categories(), true));
OC_Contacts_VCard::updateDataByID($cards);
OC_JSON::success(array('data' => array('categories'=>$catman->categories())));
?>

View File

@ -0,0 +1,17 @@
<?php
/**
* Copyright (c) 2012 Thomas Tanghus <thomas@tanghus.net>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
require_once('../../../../lib/base.php');
OC_JSON::checkLoggedIn();
OC_JSON::checkAppEnabled('contacts');
$categories = OC_Contacts_App::$categories->categories();
OC_JSON::success(array('data' => array('categories'=>$categories)));
?>

View File

@ -0,0 +1,49 @@
<?php
/**
* Copyright (c) 2012 Thomas Tanghus <thomas@tanghus.net>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
require_once('../../../../lib/base.php');
OC_JSON::checkLoggedIn();
OC_JSON::checkAppEnabled('contacts');
foreach ($_POST as $key=>$element) {
debug('_POST: '.$key.'=>'.print_r($element, true));
}
function bailOut($msg) {
OC_JSON::error(array('data' => array('message' => $msg)));
OC_Log::write('contacts','ajax/categories/rescan.php: '.$msg, OC_Log::DEBUG);
exit();
}
function debug($msg) {
OC_Log::write('contacts','ajax/categories/rescan.php: '.$msg, OC_Log::DEBUG);
}
$addressbooks = OC_Contacts_Addressbook::all(OC_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.'));
}
$cards = array();
foreach($contacts as $contact) {
$cards[] = $contact['carddata'];
}
OC_Contacts_App::$categories->rescan($cards);
$categories = OC_Contacts_App::$categories->categories();
OC_JSON::success(array('data' => array('categories'=>$categories)));
?>

View File

@ -71,5 +71,5 @@ if(isset($details['PHOTO'])) {
$details['PHOTO'] = false;
}
$details['id'] = $id;
OC_Contacts_App::setLastModifiedHeader($vcard);
OC_JSON::success(array('data' => $details));

View File

@ -39,7 +39,7 @@ if(is_null($line)){
unset($vcard->children[$line]);
if(!OC_Contacts_VCard::edit($id,$vcard->serialize())) {
if(!OC_Contacts_VCard::edit($id,$vcard)) {
OC_JSON::error(array('data' => array('message' => OC_Contacts_App::$l10n->t('Error deleting contact property.'))));
OC_Log::write('contacts','ajax/deleteproperty.php: Error deleting contact property', OC_Log::ERROR);
exit();

View File

@ -2,8 +2,8 @@
/**
* ownCloud - Addressbook
*
* @author Jakob Sack
* @copyright 2011 Jakob Sack mail@jakobsack.de
* @author Thomas Tanghus
* @copyright 2012 Thomas Tanghus <thomas@tanghus.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
@ -22,31 +22,38 @@
// Init owncloud
require_once('../../../lib/base.php');
function bailOut($msg) {
OC_JSON::error(array('data' => array('message' => $msg)));
OC_Log::write('contacts','ajax/loadcard.php: '.$msg, OC_Log::DEBUG);
exit();
}
function debug($msg) {
OC_Log::write('contacts','ajax/loadcard.php: '.$msg, OC_Log::DEBUG);
}
// foreach ($_POST as $key=>$element) {
// debug('_POST: '.$key.'=>'.$element);
// }
// Check if we are a user
OC_JSON::checkLoggedIn();
OC_JSON::checkAppEnabled('contacts');
$id = $_GET['id'];
$checksum = $_GET['checksum'];
$vcard = OC_Contacts_App::getContactVCard( $id );
$line = OC_Contacts_App::getPropertyLineByChecksum($vcard, $checksum);
if(is_null($line)){
OC_JSON::error(array('data' => array( 'message' => OC_Contacts_App::$l10n->t('Information about vCard is incorrect. Please reload the page.'))));
exit();
}
$upload_max_filesize = OC_Helper::computerFileSize(ini_get('upload_max_filesize'));
$post_max_size = OC_Helper::computerFileSize(ini_get('post_max_size'));
$maxUploadFilesize = min($upload_max_filesize, $post_max_size);
$freeSpace=OC_Filesystem::free_space('/');
$freeSpace=max($freeSpace,0);
$maxUploadFilesize = min($maxUploadFilesize ,$freeSpace);
$adr_types = OC_Contacts_App::getTypesOfProperty('ADR');
$phone_types = OC_Contacts_App::getTypesOfProperty('TEL');
$tmpl = new OC_Template('contacts','part.setpropertyform');
$tmpl->assign('id',$id);
$tmpl->assign('checksum',$checksum);
$tmpl->assign('property',OC_Contacts_VCard::structureProperty($vcard->children[$line]));
$tmpl = new OC_Template('contacts','part.contact');
$tmpl->assign('uploadMaxFilesize', $maxUploadFilesize);
$tmpl->assign('uploadMaxHumanFilesize', OC_Helper::humanFileSize($maxUploadFilesize));
$tmpl->assign('adr_types',$adr_types);
$tmpl->assign('phone_types',$phone_types);
$tmpl->assign('id','');
$page = $tmpl->fetchPage();
OC_JSON::success(array('data' => array( 'page' => $page )));

View File

@ -18,8 +18,6 @@
* 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/>.
*
* TODO: Translatable strings.
* Remember to delete tmp file at some point.
*/
// Init owncloud
require_once('../../../lib/base.php');
@ -33,7 +31,7 @@ OC_JSON::checkAppEnabled('contacts');
function bailOut($msg) {
OC_JSON::error(array('data' => array('message' => $msg)));
OC_Log::write('contacts','ajax/savecrop.php: '.$msg, OC_Log::DEBUG);
OC_Log::write('contacts','ajax/loadphoto.php: '.$msg, OC_Log::DEBUG);
exit();
}
@ -42,11 +40,20 @@ $image = null;
$id = isset($_GET['id']) ? $_GET['id'] : '';
if($id == '') {
bailOut('Missing contact id.');
bailOut(OC_Contacts_App::$l10n->t('Missing contact id.'));
}
$checksum = '';
$vcard = OC_Contacts_App::getContactVCard( $id );
foreach($vcard->children as $property){
if($property->name == 'PHOTO') {
$checksum = md5($property->serialize());
break;
}
}
$tmpl = new OC_TEMPLATE("contacts", "part.contactphoto");
$tmpl->assign('id', $id);
$page = $tmpl->fetchPage();
OC_JSON::success(array('data' => array('page'=>$page)));
OC_JSON::success(array('data' => array('page'=>$page, 'checksum'=>$checksum)));
?>

View File

@ -1,15 +0,0 @@
<?php
/**
* Copyright (c) 2011 Thomas Tanghus <thomas@tanghus.net>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
require_once('../../../lib/base.php');
OC_JSON::checkLoggedIn();
OC_JSON::checkAppEnabled('contacts');
$output = new OC_TEMPLATE("contacts", "part.messagebox");
$output -> printpage();
?>

View File

@ -95,7 +95,7 @@ if(file_exists($tmp_path)) {
OC_Log::write('contacts','savecrop.php: files: Adding PHOTO property.', OC_Log::DEBUG);
$card->addProperty('PHOTO', $image->__toString(), array('ENCODING' => 'b', 'TYPE' => $image->mimeType()));
}
if(!OC_Contacts_VCard::edit($id,$card->serialize())) {
if(!OC_Contacts_VCard::edit($id,$card)) {
bailOut('Error saving contact.');
}
unlink($tmpfname);
@ -104,6 +104,7 @@ if(file_exists($tmp_path)) {
$tmpl->assign('tmp_path', $tmpfname);
$tmpl->assign('mime', $image->mimeType());
$tmpl->assign('id', $id);
$tmpl->assign('refresh', true);
$tmpl->assign('width', $image->width());
$tmpl->assign('height', $image->height());
$page = $tmpl->fetchPage();

View File

@ -35,9 +35,9 @@ function bailOut($msg) {
function debug($msg) {
OC_Log::write('contacts','ajax/saveproperty.php: '.$msg, OC_Log::DEBUG);
}
foreach ($_POST as $key=>$element) {
debug('_POST: '.$key.'=>'.$element);
}
// foreach ($_POST as $key=>$element) {
// debug('_POST: '.$key.'=>'.print_r($element, true));
// }
$id = isset($_POST['id'])?$_POST['id']:null;
$name = isset($_POST['name'])?$_POST['name']:null;
@ -51,12 +51,8 @@ $checksum = isset($_POST['checksum'])?$_POST['checksum']:null;
// }
// }
if(is_array($value)){
$value = array_map('strip_tags', $value);
ksort($value); // NOTE: Important, otherwise the compound value will be set in the order the fields appear in the form!
$value = OC_VObject::escapeSemicolons($value);
} else {
$value = trim(strip_tags($value));
if(!$name) {
bailOut(OC_Contacts_App::$l10n->t('element name is not set.'));
}
if(!$id) {
bailOut(OC_Contacts_App::$l10n->t('id is not set.'));
@ -64,14 +60,22 @@ if(!$id) {
if(!$checksum) {
bailOut(OC_Contacts_App::$l10n->t('checksum is not set.'));
}
if(!$name) {
bailOut(OC_Contacts_App::$l10n->t('element name is not set.'));
if(is_array($value)){
$value = array_map('strip_tags', $value);
ksort($value); // NOTE: Important, otherwise the compound value will be set in the order the fields appear in the form!
//if($name == 'CATEGORIES') {
// $value = OC_Contacts_VCard::escapeDelimiters($value, ',');
//} else {
$value = OC_Contacts_VCard::escapeDelimiters($value, ';');
//}
} else {
$value = trim(strip_tags($value));
}
$vcard = OC_Contacts_App::getContactVCard( $id );
$line = OC_Contacts_App::getPropertyLineByChecksum($vcard, $checksum);
if(is_null($line)) {
bailOut(OC_Contacts_App::$l10n->t('Information about vCard is incorrect. Please reload the page.'.$checksum.' "'.$line.'"'));
bailOut(OC_Contacts_App::$l10n->t('Information about vCard is incorrect. Please reload the page: ').$checksum);
}
$element = $vcard->children[$line]->name;
@ -79,24 +83,47 @@ if($element != $name) {
bailOut(OC_Contacts_App::$l10n->t('Something went FUBAR. ').$name.' != '.$element);
}
/* preprocessing value */
switch($element) {
case 'BDAY':
$date = New DateTime($value);
//$vcard->setDateTime('BDAY', $date, Sabre_VObject_Element_DateTime::DATE);
$value = $date->format(DateTime::ATOM);
break;
case 'FN':
if(!$value) {
// create a method thats returns an alternative for FN.
//$value = getOtherValue();
}
break;
case 'CATEGORIES':
/* multi autocomplete triggers an save with empty value */
if (!$value) {
$value = $vcard->getAsString('CATEGORIES');
}
break;
case 'EMAIL':
$value = strtolower($value);
break;
}
if(!$value) {
bailOut(OC_Contacts_App::$l10n->t('Cannot save empty value.'));
}
/* setting value */
switch($element) {
case 'BDAY':
case 'FN':
case 'N':
case 'ORG':
case 'NOTE':
case 'NICKNAME':
case 'CATEGORIES':
debug('Setting string:'.$name.' '.$value);
$vcard->setString($name, $value);
break;
case 'EMAIL':
$value = strtolower($value);
case 'TEL':
case 'ADR': // should I delete the property if empty or throw an error?
debug('Setting element: (EMAIL/TEL/ADR)'.$element);
@ -122,13 +149,9 @@ switch($element) {
$checksum = md5($vcard->children[$line]->serialize());
debug('New checksum: '.$checksum);
if(!OC_Contacts_VCard::edit($id,$vcard->serialize())) {
OC_JSON::error(array('data' => array('message' => OC_Contacts_App::$l10n->t('Error updating contact property.'))));
OC_Log::write('contacts','ajax/setproperty.php: Error updating contact property: '.$value, OC_Log::ERROR);
if(!OC_Contacts_VCard::edit($id,$vcard)) {
bailOut(OC_Contacts_App::$l10n->t('Error updating contact property.'));
exit();
}
//$adr_types = OC_Contacts_App::getTypesOfProperty('ADR');
//$phone_types = OC_Contacts_App::getTypesOfProperty('TEL');
OC_JSON::success(array('data' => array( 'line' => $line, 'checksum' => $checksum, 'oldchecksum' => $_POST['checksum'] )));

View File

@ -1,106 +0,0 @@
<?php
/**
* ownCloud - Addressbook
*
* @author Jakob Sack
* @copyright 2011 Jakob Sack mail@jakobsack.de
*
* 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/>.
*
*/
// Init owncloud
require_once('../../../lib/base.php');
// Check if we are a user
OC_JSON::checkLoggedIn();
OC_JSON::checkAppEnabled('contacts');
$id = $_POST['id'];
$checksum = $_POST['checksum'];
$vcard = OC_Contacts_App::getContactVCard( $id );
$line = OC_Contacts_App::getPropertyLineByChecksum($vcard, $checksum);
// Set the value
$value = $_POST['value'];
if(is_array($value)){
ksort($value); // NOTE: Important, otherwise the compound value will be set in the order the fields appear in the form!
foreach(array_keys($value) as $key) {
OC_Log::write('contacts','ajax/setproperty.php: setting: '.$key.': '.$value[$key], OC_Log::DEBUG);
}
$value = OC_VObject::escapeSemicolons($value);
}
OC_Log::write('contacts','ajax/setproperty.php: setting: '.$vcard->children[$line]->name.': '.$value, OC_Log::DEBUG);
$vcard->children[$line]->setValue(strip_tags($value));
// Add parameters
$postparameters = isset($_POST['parameters'])?$_POST['parameters']:array();
if ($vcard->children[$line]->name == 'TEL' && !array_key_exists('TYPE', $postparameters)){
$postparameters['TYPE']='';
}
for($i=0;$i<count($vcard->children[$line]->parameters);$i++){
$name = $vcard->children[$line]->parameters[$i]->name;
if(array_key_exists($name,$postparameters)){
if($postparameters[$name] == '' || is_null($postparameters[$name])){
unset($vcard->children[$line]->parameters[$i]);
}
else{
unset($vcard->children[$line][$name]);
$values = $postparameters[$name];
if (!is_array($values)){
$values = array($values);
}
foreach($values as $value){
$vcard->children[$line]->add($name, $value);
}
}
unset($postparameters[$name]);
}
}
$missingparameters = array_keys($postparameters);
foreach($missingparameters as $i){
if(!$postparameters[$i] == '' && !is_null($postparameters[$i])){
$vcard->children[$line]->parameters[] = new Sabre_VObject_Parameter($i,$postparameters[$i]);
}
}
// Do checksum and be happy
// NOTE: This checksum is not used..?
$checksum = md5($vcard->children[$line]->serialize());
if(!OC_Contacts_VCard::edit($id,$vcard->serialize())) {
OC_JSON::error(array('data' => array('message' => $l->t('Error updating contact property.'))));
OC_Log::write('contacts','ajax/setproperty.php: Error updating contact property: '.$value, OC_Log::ERROR);
exit();
}
$adr_types = OC_Contacts_App::getTypesOfProperty('ADR');
$phone_types = OC_Contacts_App::getTypesOfProperty('TEL');
if ($vcard->children[$line]->name == 'FN'){
$tmpl = new OC_Template('contacts','part.property.FN');
}
elseif ($vcard->children[$line]->name == 'N'){
$tmpl = new OC_Template('contacts','part.property.N');
}
else{
$tmpl = new OC_Template('contacts','part.property');
}
$tmpl->assign('adr_types',$adr_types);
$tmpl->assign('phone_types',$phone_types);
$tmpl->assign('property',OC_Contacts_VCard::structureProperty($vcard->children[$line],$line));
$page = $tmpl->fetchPage();
OC_JSON::success(array('data' => array( 'page' => $page, 'line' => $line, 'checksum' => $checksum, 'oldchecksum' => $_POST['checksum'] )));

View File

@ -1,40 +0,0 @@
<?php
/**
* ownCloud - Addressbook
*
* @author Jakob Sack
* @copyright 2011 Jakob Sack mail@jakobsack.de
*
* 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/>.
*
*/
// Init owncloud
require_once('../../../lib/base.php');
// Check if we are a user
OC_JSON::checkLoggedIn();
OC_JSON::checkAppEnabled('contacts');
$adr_types = OC_Contacts_App::getTypesOfProperty('ADR');
$phone_types = OC_Contacts_App::getTypesOfProperty('TEL');
$addressbooks = OC_Contacts_Addressbook::all(OC_USER::getUser());
$tmpl = new OC_Template('contacts','part.addcardform');
$tmpl->assign('addressbooks',$addressbooks);
$tmpl->assign('adr_types',$adr_types);
$tmpl->assign('phone_types',$phone_types);
$page = $tmpl->fetchPage();
OC_JSON::success(array('data' => array( 'page' => $page )));

View File

@ -1,37 +0,0 @@
<?php
/**
* ownCloud - Addressbook
*
* @author Jakob Sack
* @copyright 2011 Jakob Sack mail@jakobsack.de
*
* 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/>.
*
*/
// Init owncloud
require_once('../../../lib/base.php');
// Check if we are a user
OC_JSON::checkLoggedIn();
OC_JSON::checkAppEnabled('contacts');
$id = $_GET['id'];
$card = OC_Contacts_App::getContactObject( $id );
$tmpl = new OC_Template('contacts','part.addpropertyform');
$tmpl->assign('id',$id);
$page = $tmpl->fetchPage();
OC_JSON::success(array('data' => array( 'page' => $page )));

View File

@ -20,7 +20,8 @@
#firstrun { width: 100%; position: absolute; top: 5em; left: 0; text-align: center; font-weight:bold; font-size:1.5em; color:#777; }
#firstrun #selections { font-size:0.8em; margin: 2em auto auto auto; clear: both; }
#card input[type="text"].contacts_property,input[type="email"].contacts_property { width: 16em; }
#card input[type="text"].contacts_property,input[type="email"].contacts_property { width: 14em; }
.categories { float: left; width: 16em; }
#card input[type="text"],input[type="email"],input[type="tel"],input[type="date"], select { background-color: #f8f8f8; border: 0 !important; -webkit-appearance:none !important; -moz-appearance:none !important; -webkit-box-sizing:none !important; -moz-box-sizing:none !important; box-sizing:none !important; -moz-box-shadow: none; -webkit-box-shadow: none; box-shadow: none; -moz-border-radius: 0px; -webkit-border-radius: 0px; border-radius: 0px; float: left; }
#card input[type="text"]:hover, input[type="text"]:focus, input[type="text"]:active,input[type="email"]:hover,input[type="tel"]:hover,input[type="date"]:hover,input[type="date"],input[type="date"]:hover,input[type="date"]:active,input[type="date"]:active,input[type="date"]:active,input[type="email"]:active,input[type="tel"]:active, select:hover, select:focus, select:active { border: 0 !important; -webkit-appearance:textfield; -moz-appearance:textfield; -webkit-box-sizing:content-box; -moz-box-sizing:content-box; box-sizing:content-box; background:#fff; color:#333; border:1px solid #ddd; -moz-box-shadow:0 1px 1px #fff, 0 2px 0 #bbb inset; -webkit-box-shadow:0 1px 1px #fff, 0 1px 0 #bbb inset; box-shadow:0 1px 1px #fff, 0 1px 0 #bbb inset; -moz-border-radius:.5em; -webkit-border-radius:.5em; border-radius:.5em; outline:none; float: left; }
input[type="text"]:invalid,input[type="email"]:invalid,input[type="tel"]:invalid,input[type="date"]:invalid { background-color: #ffc0c0 !important; }
@ -68,7 +69,7 @@ dl.form
/*background-color: yellow;*/
}
.loading { background: url('../../../core/img/loading.gif') no-repeat center !important;}
.loading { background: url('../../../core/img/loading.gif') no-repeat center !important; /*cursor: progress; */ cursor: wait; }
/*.add { cursor: pointer; width: 25px; height: 25px; margin: 0px; float: right; position:relative; content: "\+"; font-weight: bold; color: #666; font-size: large; bottom: 0px; right: 0px; clear: both; text-align: center; vertical-align: bottom; display: none; }*/
@ -185,4 +186,5 @@ input[type="checkbox"] { width: 20px; height: 20px; vertical-align: bottom; }
.propertylist li > input[type="checkbox"],input[type="radio"] { float: left; clear: left; width: 20px; height: 20px; vertical-align: middle; }
.propertylist li > select { float: left; max-width: 8em; }
.typelist { float: left; max-width: 10em; } /* for multiselect */
.addresslist { clear: both; }
.addresslist { clear: both; }

View File

@ -1,37 +0,0 @@
#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_name_n { font-size:0.8em;margin-left:25%;color:#666;}
#contacts_details_photo { margin:.5em 0em .5em 25%; }
#contacts_deletecard {position:absolute;top:15px;right:25px;}
#contacts_downloadcard {position:absolute;top:15px;right:50px;}
#contacts_details_list { list-style:none; }
#contacts_details_list li { overflow:visible; }
#contacts_details_list li p.contacts_property_name { width:25%; float:left;text-align:right;padding-right:0.3em;color:#666; }
#contacts_details_list li p.contacts_property_data, #contacts_details_list li ul.contacts_property_data { width:72%;float:left; clear: right; }
#contacts_setproperty_button { margin-left:25%; }
#contacts_addcardform legend,label { font-weight: bold; width: 10em; overflow: ellipsis; }
#contacts_addcardform legend { padding-left: 3em; font-size:1.1em; }
#contacts_addcardform input[type="text"] { width: 25em; }
#contacts_addcardform input[type="email"] { width: 15em; }
#contacts_addcardform input[type="tel"] { width: 15em; }
dl.form { width: 100%; float: left; clear: right; margin: 1em; padding: 0; }
.form dt { display: table-cell; clear: left; float: left; min-width: 10em; margin: 0; padding-top: 0.5em; padding-right: 1em;font-weight: bold; text-align:right; vertical-align: text-bottom; bottom: 0px; }
.form dd { display: table-cell; clear: right; float: left; min-width: 20em; margin: 0; padding: 0; white-space: nowrap; top: 0px; }
.form input { position: relative; width: 20em; }
.contacts_property_data ul, ol.contacts_property_data { list-style:none; }
.contacts_property_data li { overflow: hidden; }
.contacts_property_data li label { width:20%; float:left; text-align:right;padding-right:0.3em; }
.contacts_property_data input { float:left; }
.contacts_property_data li input { width:70%;overflow:hidden; }
.chzn-container { margin:3px 0 0; }
.chzn-container .chzn-choices { border-radius: 0.5em; }
.chzn-container.chzn-container-active .chzn-choices { border-bottom-left-radius: 0;border-bottom-right-radius: 0; }
.chzn-container .chzn-drop { border-bottom-left-radius: 0.5em;border-bottom-right-radius: 0.5em; }

View File

@ -97,11 +97,15 @@ if(is_writable('import_tmp/')){
fclose($progressfopen);
}
if(count($parts) == 1){
OC_Contacts_VCard::add($id, $file);
}else{
foreach($importready as $import){
OC_Contacts_VCard::add($id, $import);
$importready = array($file);
}
foreach($importready as $import){
$card = OC_VObject::parse($import);
if (!$card) {
OC_Log::write('contacts','Import: skipping card. Error parsing VCard: '.$import, OC_Log::ERROR);
continue; // Ditch cards that can't be parsed by Sabre.
}
OC_Contacts_VCard::add($id, $card);
}
//done the import
if(is_writable('import_tmp/')){
@ -113,4 +117,4 @@ sleep(3);
if(is_writable('import_tmp/')){
unlink($progressfile);
}
OC_JSON::success();
OC_JSON::success();

View File

@ -34,6 +34,7 @@ if(!is_null($id)) {
}
$property_types = OC_Contacts_App::getAddPropertyOptions();
$phone_types = OC_Contacts_App::getTypesOfProperty('TEL');
$categories = OC_Contacts_App::$categories->categories();
$upload_max_filesize = OC_Helper::computerFileSize(ini_get('upload_max_filesize'));
$post_max_size = OC_Helper::computerFileSize(ini_get('post_max_size'));
@ -44,12 +45,14 @@ $freeSpace=max($freeSpace,0);
$maxUploadFilesize = min($maxUploadFilesize ,$freeSpace);
OC_Util::addScript('','jquery.multiselect');
OC_Util::addScript('','oc-vcategories');
OC_Util::addScript('contacts','contacts');
OC_Util::addScript('contacts','jquery.combobox');
OC_Util::addScript('contacts','jquery.inview');
OC_Util::addScript('contacts','jquery.Jcrop');
OC_Util::addScript('contacts','jquery.multi-autocomplete');
OC_Util::addStyle('','jquery.multiselect');
//OC_Util::addStyle('contacts','styles');
OC_Util::addStyle('','oc-vcategories');
OC_Util::addStyle('contacts','jquery.combobox');
OC_Util::addStyle('contacts','jquery.Jcrop');
OC_Util::addStyle('contacts','contacts');
@ -58,7 +61,9 @@ $tmpl = new OC_Template( "contacts", "index", "user" );
$tmpl->assign('uploadMaxFilesize', $maxUploadFilesize);
$tmpl->assign('uploadMaxHumanFilesize', OC_Helper::humanFileSize($maxUploadFilesize));
$tmpl->assign('property_types',$property_types);
$tmpl->assign('categories',OC_Contacts_App::getCategories());
$tmpl->assign('phone_types',$phone_types);
$tmpl->assign('categories',$categories);
$tmpl->assign('addressbooks', $addressbooks);
$tmpl->assign('contacts', $contacts);
$tmpl->assign('details', $details );

View File

@ -10,17 +10,16 @@ String.prototype.strip_tags = function(){
return stripped;
};
Contacts={
UI:{
notImplemented:function() {
Contacts.UI.messageBox(t('contacts', 'Not implemented'), t('contacts', 'Sorry, this functionality has not been implemented yet'));
OC.dialogs.alert(t('contacts', 'Sorry, this functionality has not been implemented yet'), t('contacts', 'Not implemented'));
},
searchOSM:function(obj) {
var adr = Contacts.UI.propertyContainerFor(obj).find('.adr').val();
console.log('adr 1: ' + adr);
if(adr == undefined) {
Contacts.UI.messageBox(t('contacts', 'Error'), t('contacts', 'Couldn\'t get a valid address.'));
OC.dialogs.alert(t('contacts', 'Couldn\'t get a valid address.'), t('contacts', 'Error'));
return;
}
// FIXME: I suck at regexp. /Tanghus
@ -48,12 +47,11 @@ Contacts={
console.log('uri: ' + uri);
var newWindow = window.open(uri,'_blank');
newWindow.focus();
//Contacts.UI.notImplemented();
},
mailTo:function(obj) {
var adr = Contacts.UI.propertyContainerFor($(obj)).find('input[type="email"]').val().trim();
if(adr == '') {
Contacts.UI.messageBox(t('contacts', 'Error'), t('contacts', 'Please enter an email address.'));
OC.dialogs.alert(t('contacts', 'Please enter an email address.'), t('contacts', 'Error'));
return;
}
window.location.href='mailto:' + adr;
@ -68,7 +66,7 @@ Contacts={
return $(obj).parents('.propertycontainer').first().data('element');
},
showHideContactInfo:function() {
var show = ($('#emaillist li[class*="propertycontainer"]').length > 0 || $('#phonelist li[class*="propertycontainer"]').length > 0 || $('#addressdisplay dl[class*="propertycontainer"]').length > 0);
var show = ($('#emaillist li.propertycontainer').length > 0 || $('#phonelist li.propertycontainer').length > 0 || $('#addressdisplay dl.propertycontainer').length > 0);
console.log('showHideContactInfo: ' + show);
if(show) {
$('#contact_communication').show();
@ -82,19 +80,19 @@ Contacts={
switch (type) {
case 'EMAIL':
console.log('emails: '+$('#emaillist>li').length);
if($('#emaillist li[class*="propertycontainer"]').length == 0) {
if($('#emaillist li.propertycontainer').length == 0) {
$('#emails').hide();
}
break;
case 'TEL':
console.log('phones: '+$('#phonelist>li').length);
if($('#phonelist li[class*="propertycontainer"]').length == 0) {
if($('#phonelist li.propertycontainer').length == 0) {
$('#phones').hide();
}
break;
case 'ADR':
console.log('addresses: '+$('#addressdisplay>dl').length);
if($('#addressdisplay dl[class*="propertycontainer"]').length == 0) {
if($('#addressdisplay dl.propertycontainer').length == 0) {
$('#addresses').hide();
}
break;
@ -116,34 +114,6 @@ Contacts={
$('#carddav_url').show();
$('#carddav_url_close').show();
},
messageBox:function(title, msg) {
if(msg.toLowerCase().indexOf('auth') != -1) {
// fugly hack, I know
alert(msg);
}
if($('#messagebox').dialog('isOpen') == true){
// NOTE: Do we ever get here?
$('#messagebox').dialog('moveToTop');
}else{
$('#dialog_holder').load(OC.filePath('contacts', 'ajax', 'messagebox.php'), function(){
$('#messagebox').dialog(
{
autoOpen: true,
title: title,
buttons: [{
text: "Ok",
click: function() { $(this).dialog("close"); }
}],
close: function(event, ui) {
$(this).dialog('destroy').remove();
},
open: function(event, ui) {
$('#messagebox_msg').html(msg);
}
});
});
};
},
loadListHandlers:function() {
//$('.add,.delete').hide();
$('.globe,.mail,.delete,.edit').tipsy();
@ -182,8 +152,14 @@ Contacts={
$('#bday').datepicker({
dateFormat : 'dd-mm-yy'
});
/*$('#categories_value').find('select').multiselect({
noneSelectedText: t('contacts', 'Select categories'),
header: false,
selectedList: 6,
classes: 'categories'
});*/
// Style phone types
$('#phonelist').find('select[class*="contacts_property"]').multiselect({
$('#phonelist').find('select.contacts_property').multiselect({
noneSelectedText: t('contacts', 'Select type'),
header: false,
selectedList: 4,
@ -223,6 +199,7 @@ Contacts={
click: function() { $(this).dialog('close'); }
}
] );
$('#categories').multiple_autocomplete({source: categories});
Contacts.UI.loadListHandlers();
},
Card:{
@ -252,12 +229,12 @@ Contacts={
if(jsondata.status == 'success'){
Contacts.UI.Card.loadContact(jsondata.data);
} else{
Contacts.UI.messageBox(t('contacts', 'Error'), jsondata.data.message);
OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
}
});
}
} else{
Contacts.UI.messageBox(t('contacts', 'Error'), jsondata.data.message);
OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
}
});
}
@ -269,7 +246,7 @@ Contacts={
$('#rightcontent').data('id','');
$('#rightcontent').html(jsondata.data.page);
} else {
Contacts.UI.messageBox(t('contacts', 'Error'), jsondata.data.message);
OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
}
});
}
@ -309,7 +286,7 @@ Contacts={
}
else{
Contacts.UI.messageBox(t('contacts', 'Error'), jsondata.data.message);
OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
//alert(jsondata.data.message);
}
});
@ -318,7 +295,7 @@ Contacts={
// TODO: Add to contacts list.
}
else{
Contacts.UI.messageBox(t('contacts', 'Error'), jsondata.data.message);
OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
//alert(jsondata.data.message);
}
});
@ -344,13 +321,13 @@ Contacts={
$('#rightcontent').html(jsondata.data.page);
}
else{
Contacts.UI.messageBox(t('contacts', 'Error'), jsondata.data.message);
OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
}
});
}
}
else{
Contacts.UI.messageBox(t('contacts', 'Error'), jsondata.data.message);
OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
//alert(jsondata.data.message);
}
});
@ -361,19 +338,29 @@ Contacts={
this.data = jsondata;
this.id = this.data.id;
$('#rightcontent').data('id',this.id);
//console.log('loaded: ' + this.data.FN[0]['value']);
console.log('loaded: ' + this.data.FN[0]['value']);
this.populateNameFields();
this.loadCategories();
//this.loadCategories();
this.loadPhoto();
this.loadMails();
this.loadPhones();
this.loadAddresses();
this.loadSingleProperties();
// TODO: load NOTE ;-)
if(this.data.NOTE) {
$('#note').data('checksum', this.data.NOTE[0]['checksum']);
$('#note').find('textarea').val(this.data.NOTE[0]['value']);
$('#note').show();
} else {
$('#note').data('checksum', '');
$('#note').find('textarea').val('');
$('#note').hide();
}
},
loadSingleProperties:function() {
var props = ['BDAY', 'NICKNAME', 'ORG'];
var props = ['BDAY', 'NICKNAME', 'ORG', 'CATEGORIES'];
// Clear all elements
$('#ident .propertycontainer[class*="propertycontainer"]').each(function(){
$('#ident .propertycontainer').each(function(){
if(props.indexOf($(this).data('element')) > -1) {
$(this).data('checksum', '');
$(this).find('input').val('');
@ -407,6 +394,12 @@ Contacts={
$('#contact_identity').find('#org_label').show();
$('#contact_identity').find('#org_value').show();
break;
case 'CATEGORIES':
$('#contact_identity').find('#categories').val(value);
$('#contact_identity').find('#categories_value').data('checksum', checksum);
$('#contact_identity').find('#categories_label').show();
$('#contact_identity').find('#categories_value').show();
break;
}
} else {
$('#contacts_propertymenu a[data-type="'+props[prop]+'"]').parent().show();
@ -424,11 +417,11 @@ Contacts={
} else {
narray = this.data.N[0]['value'];
}
this.famname = narray[0];
this.givname = narray[1];
this.addname = narray[2];
this.honpre = narray[3];
this.honsuf = narray[4];
this.famname = narray[0] || '';
this.givname = narray[1] || '';
this.addname = narray[2] || '';
this.honpre = narray[3] || '';
this.honsuf = narray[4] || '';
if(this.honpre.length > 0) {
this.fullname += this.honpre + ' ';
}
@ -448,6 +441,9 @@ Contacts={
$('#fn_select option').remove();
$('#fn_select').combobox('value', this.fn);
var names = [this.fullname, this.givname + ' ' + this.famname, this.famname + ' ' + this.givname, this.famname + ', ' + this.givname];
if(this.data.ORG) {
names[names.length]=this.data.ORG[0].value;
}
$.each(names, function(key, value) {
$('#fn_select')
.append($('<option></option>')
@ -457,36 +453,79 @@ Contacts={
$('#contact_identity').find('*[data-element="FN"]').data('checksum', this.data.FN[0]['checksum']);
$('#contact_identity').show();
},
loadCategories:function(){
hasCategory:function(category) {
if(this.data.CATEGORIES) {
//
var categories = this.data.CATEGORIES[0]['value'].split(/,\s*/);
for(var c in categories) {
var cat = this.data.CATEGORIES[0]['value'][c];
console.log('hasCategory: ' + cat + ' === ' + category + '?');
if(typeof cat === 'string' && (cat.toUpperCase() === category.toUpperCase())) {
console.log('Yes');
return true;
}
}
}
return false;
},
categoriesChanged:function(newcategories) { // Categories added/deleted.
console.log('categoriesChanged for ' + Contacts.UI.Card.id + ' : ' + newcategories);
categories = newcategories;
var categorylist = $('#categories_value').find('input');
$.getJSON(OC.filePath('contacts', 'ajax', 'categories/categoriesfor.php'),{'id':Contacts.UI.Card.id},function(jsondata){
if(jsondata.status == 'success'){
console.log('Setting checksum: ' + jsondata.data.checksum + ', value: ' + jsondata.data.value);
$('#categories_value').data('checksum', jsondata.data.checksum);
categorylist.val(jsondata.data.value);
} else {
OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
}
});
},
/*loadCategories:function(){ // On loading contact.
var categories = $('#categories_value').find('select');
if(this.data.CATEGORIES) {
$('#categories_value').data('checksum', this.data.CATEGORIES[0]['checksum']);
} else {
$('#categories_value').data('checksum', '');
}
categories.find('option').each(function(){
if(Contacts.UI.Card.hasCategory($(this).val())) {
$(this).attr('selected', 'selected');
} else {
$(this).removeAttr('selected');
}
});
categories.multiselect('refresh');
},*/
editNew:function(){ // add a new contact
this.id = ''; this.fn = ''; this.fullname = ''; this.givname = ''; this.famname = ''; this.addname = ''; this.honpre = ''; this.honsuf = '';
$.getJSON('ajax/newcontact.php',{},function(jsondata){
$.getJSON(OC.filePath('contacts', 'ajax', 'newcontact.php'),{},function(jsondata){
if(jsondata.status == 'success'){
id = '';
$('#rightcontent').data('id','');
$('#rightcontent').html(jsondata.data.page);
Contacts.UI.Card.editName();
}
else{
Contacts.UI.messageBox(t('contacts', 'Error'), jsondata.data.message);
} else {
OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
//alert(jsondata.data.message);
}
});
},
savePropertyInternal:function(name, fields, oldchecksum, checksum){
// TODO: Add functionality for new fields.
//console.log('savePropertyInternal: ' + name + ', checksum: ' + checksum);
//console.log('savePropertyInternal: ' + this.data[name]);
console.log('savePropertyInternal: ' + name + ', fields: ' + fields + 'checksum: ' + checksum);
console.log('savePropertyInternal: ' + this.data[name]);
var multivalue = ['CATEGORIES'];
var params = {};
var value = undefined;
var value = multivalue.indexOf(name) != -1 ? new Array() : undefined;
jQuery.each(fields, function(i, field){
//.substring(11,'parameters[TYPE][]'.indexOf(']'))
if(field.name.substring(0, 5) === 'value') {
value = field.value;
if(multivalue.indexOf(name) != -1) {
value.push(field.value);
} else {
value = field.value;
}
} else if(field.name.substring(0, 10) === 'parameters') {
var p = field.name.substring(11,'parameters[TYPE][]'.indexOf(']'));
if(!(p in params)) {
@ -506,11 +545,11 @@ Contacts={
saveProperty:function(obj){
// I couldn't get the selector to filter on 'contacts_property' so I filter by hand here :-/
if(!$(obj).hasClass('contacts_property')) {
//console.log('Filtering out object.' + obj);
console.log('Filtering out object.' + obj);
return false;
}
if($(obj).hasClass('nonempty') && $(obj).val().trim() == '') {
Contacts.UI.messageBox(t('contacts', 'Error'), t('contacts', 'This property has to be non-empty.'));
OC.dialogs.alert(t('contacts', 'This property has to be non-empty.'), t('contacts', 'Error'));
return false;
}
container = $(obj).parents('.propertycontainer').first(); // get the parent holding the metadata.
@ -518,8 +557,8 @@ Contacts={
var checksum = container.data('checksum');
var name = container.data('element');
console.log('saveProperty: ' + name);
var fields = container.find('input[class*="contacts_property"],select[class*="contacts_property"]').serializeArray();
var q = container.find('input[class*="contacts_property"],select[class*="contacts_property"]').serialize();
var fields = container.find('input.contacts_property,select.contacts_property').serializeArray();
var q = container.find('input.contacts_property,select.contacts_property,textarea.contacts_property').serialize();
if(q == '' || q == undefined) {
console.log('Couldn\'t serialize elements.');
Contacts.UI.loading(container, false);
@ -529,32 +568,38 @@ Contacts={
if(checksum != undefined && checksum != '') { // save
q = q + '&checksum=' + checksum;
console.log('Saving: ' + q);
$(obj).attr('disabled', 'disabled');
$.post('ajax/saveproperty.php',q,function(jsondata){
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);
$(obj).removeAttr('disabled');
return true;
}
else{
Contacts.UI.messageBox(t('contacts', 'Error'), jsondata.data.message);
OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
Contacts.UI.loading(container, false);
$(obj).removeAttr('disabled');
return false;
}
},'json');
} else { // add
console.log('Adding: ' + q);
$(obj).attr('disabled', 'disabled');
$.post('ajax/addproperty.php',q,function(jsondata){
if(jsondata.status == 'success'){
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);
$(obj).removeAttr('disabled');
return true;
}
else{
Contacts.UI.messageBox(t('contacts', 'Error'), jsondata.data.message);
OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
Contacts.UI.loading(container, false);
$(obj).removeAttr('disabled');
return false;
}
},'json');
@ -565,9 +610,15 @@ Contacts={
console.log('addProperty:' + type);
switch (type) {
case 'PHOTO':
this.loadPhoto();
this.loadPhoto(true);
$('#file_upload_form').show();
$('#contacts_propertymenu a[data-type="'+type+'"]').parent().hide();
$('#file_upload_start').trigger('click');
break;
case 'NOTE':
$('#note').show();
$('#contacts_propertymenu a[data-type="'+type+'"]').parent().hide();
$('#note').find('textarea').focus();
break;
case 'EMAIL':
if($('#emaillist>li').length == 1) {
@ -593,7 +644,9 @@ Contacts={
case 'NICKNAME':
case 'ORG':
case 'BDAY':
case 'CATEGORIES':
$('dl dt[data-element="'+type+'"],dd[data-element="'+type+'"]').show();
$('dd[data-element="'+type+'"]').find('input').focus();
$('#contacts_propertymenu a[data-type="'+type+'"]').parent().hide();
break;
}
@ -612,17 +665,32 @@ Contacts={
} else if(type == 'single') {
var proptype = Contacts.UI.propertyTypeFor(obj);
console.log('deleteProperty, hiding: ' + proptype);
$('dl dt[data-element="'+proptype+'"],dd[data-element="'+proptype+'"]').hide();
var othertypes = ['NOTE', 'PHOTO'];
if(othertypes.indexOf(proptype) != -1) {
console.log('NOTE or PHOTO');
Contacts.UI.propertyContainerFor(obj).hide();
Contacts.UI.propertyContainerFor(obj).data('checksum', '');
if(proptype == 'PHOTO') {
console.log('Delete PHOTO');
Contacts.UI.Contacts.refreshThumbnail(Contacts.UI.Card.id);
} else if(proptype == 'NOTE') {
$('#note').find('textarea').val('');
}
} else {
$('dl dt[data-element="'+proptype+'"],dd[data-element="'+proptype+'"]').hide();
$('dl dd[data-element="'+proptype+'"]').data('checksum', '');
$('dl dd[data-element="'+proptype+'"]').find('input').val('');
}
$('#contacts_propertymenu a[data-type="'+proptype+'"]').parent().show();
Contacts.UI.loading(obj, false);
} else {
Contacts.UI.messageBox(t('contacts', 'Error'), t('contacts', '\'deleteProperty\' called without type argument. Please report at bugs.owncloud.org'));
OC.dialogs.alert(t('contacts', '\'deleteProperty\' called without type argument. Please report at bugs.owncloud.org'), t('contacts', 'Error'));
Contacts.UI.loading(obj, false);
}
}
else{
Contacts.UI.loading(obj, false);
Contacts.UI.messageBox(t('contacts', 'Error'), jsondata.data.message);
OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
}
});
} else { // Property hasn't been saved so there's nothing to delete.
@ -637,7 +705,7 @@ Contacts={
$('#contacts_propertymenu a[data-type="'+proptype+'"]').parent().show();
Contacts.UI.loading(obj, false);
} else {
Contacts.UI.messageBox(t('contacts', 'Error'), t('contacts', '\'deleteProperty\' called without type argument. Please report at bugs.owncloud.org'));
OC.dialogs.alert(t('contacts', '\'deleteProperty\' called without type argument. Please report at bugs.owncloud.org'), t('contacts', 'Error'));
}
}
},
@ -647,8 +715,9 @@ Contacts={
if($('#edit_name_dialog').dialog('isOpen') == true){
$('#edit_name_dialog').dialog('moveToTop');
}else{ // TODO: If id=='' call addcontact.php (or whatever name) instead and reload view with id.
$('#dialog_holder').load(OC.filePath('contacts', 'ajax', 'editname.php')+'?id='+this.id, function(){
$('#edit_name_dialog' ).dialog({
$('#dialog_holder').load(OC.filePath('contacts', 'ajax', 'editname.php')+'?id='+this.id, function(jsondata){
if(jsondata.status != 'error'){
$('#edit_name_dialog' ).dialog({
modal: (isnew && true || false),
closeOnEscape: (isnew == '' && false || true),
title: (isnew && t('contacts', 'Add contact') || t('contacts', 'Edit name')),
@ -667,7 +736,10 @@ Contacts={
open : function(event, ui) {
// load 'N' property - maybe :-P
}*/
});
});
} else {
OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
}
});
}
},
@ -692,7 +764,14 @@ Contacts={
$('#fn_select option').remove();
//$('#fn_select').combobox('value', this.fn);
var names = [this.fullname, this.givname + ' ' + this.famname, this.famname + ' ' + this.givname, this.famname + ', ' + this.givname];
var tmp = [this.fullname, this.givname + ' ' + this.famname, this.famname + ' ' + this.givname, this.famname + ', ' + this.givname];
var names = new Array();
for(var name in tmp) {
console.log('idx: ' + names.indexOf(tmp[name]));
if(names.indexOf(tmp[name]) == -1) {
names.push(tmp[name]);
}
}
$.each(names, function(key, value) {
$('#fn_select')
.append($('<option></option>')
@ -708,7 +787,7 @@ Contacts={
},
loadAddresses:function(){
$('#addresses').hide();
$('#addressdisplay dl[class*="propertycontainer"]').remove();
$('#addressdisplay dl.propertycontainer').remove();
for(var adr in this.data.ADR) {
$('#addressdisplay dl').first().clone().insertAfter($('#addressdisplay dl').last()).show();
$('#addressdisplay dl').last().removeClass('template').addClass('propertycontainer');
@ -771,8 +850,9 @@ Contacts={
if($('#edit_address_dialog').dialog('isOpen') == true){
$('#edit_address_dialog').dialog('moveToTop');
}else{
$('#dialog_holder').load(OC.filePath('contacts', 'ajax', 'editaddress.php')+q, function(){
$('#edit_address_dialog' ).dialog({
$('#dialog_holder').load(OC.filePath('contacts', 'ajax', 'editaddress.php')+q, function(jsondata){
if(jsondata.status != 'error'){
$('#edit_address_dialog' ).dialog({
/*modal: true,*/
height: 'auto', width: 'auto',
buttons: {
@ -803,7 +883,10 @@ Contacts={
open : function(event, ui) {
// load 'ADR' property - maybe :-P
}*/
});
});
} else {
alert(jsondata.data.message);
}
});
}
},
@ -843,7 +926,7 @@ Contacts={
},
uploadPhoto:function(filelist) {
if(!filelist) {
Contacts.UI.messageBox(t('contacts', 'Error'), t('contacts','No files selected for upload.'));
OC.dialogs.alert(t('contacts','No files selected for upload.'), t('contacts', 'Error'));
return;
}
//var file = filelist.item(0);
@ -852,7 +935,7 @@ Contacts={
var form = $('#file_upload_form');
var totalSize=0;
if(file.size > $('#max_upload').val()){
Contacts.UI.messageBox(t('Upload too large'), t('contacts','The file you are trying to upload exceed the maximum size for file uploads on this server.'));
OC.dialogs.alert(t('contacts','The file you are trying to upload exceed the maximum size for file uploads on this server.'), t('contacts', 'Error'));
return;
} else {
target.load(function(){
@ -861,21 +944,22 @@ Contacts={
Contacts.UI.Card.editPhoto(response.data.id, response.data.tmp);
//alert('File: ' + file.tmp + ' ' + file.name + ' ' + file.mime);
}else{
Contacts.UI.messageBox(t('contacts', 'Error'), response.data.message);
OC.dialogs.alert(response.data.message, t('contacts', 'Error'));
}
});
form.submit();
}
},
loadPhoto:function(){
if(this.data.PHOTO) {
loadPhoto:function(force){
if(this.data.PHOTO||force==true) {
$.getJSON('ajax/loadphoto.php',{'id':this.id},function(jsondata){
if(jsondata.status == 'success'){
//alert(jsondata.data.page);
$('#file_upload_form').data('checksum', jsondata.data.checksum);
$('#contacts_details_photo_wrapper').html(jsondata.data.page);
}
else{
Contacts.UI.messageBox(jsondata.data.message);
OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
}
});
$('#file_upload_form').show();
@ -894,7 +978,7 @@ Contacts={
$('#edit_photo_dialog_img').html(jsondata.data.page);
}
else{
Contacts.UI.messageBox(jsondata.data.message);
OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
}
});
if($('#edit_photo_dialog').dialog('isOpen') == true){
@ -913,22 +997,22 @@ Contacts={
// load cropped photo.
$('#contacts_details_photo_wrapper').html(response.data.page);
}else{
Contacts.UI.messageBox(t('contacts','Error'), response.data.message);
OC.dialogs.alert(response.data.message, t('contacts', 'Error'));
}
});
$('#contacts [data-id="'+this.id+'"]').find('a').css('background','url(thumbnail.php?id='+this.id+'&refresh=1'+Math.random()+') no-repeat');
Contacts.UI.Contacts.refreshThumbnail(this.id);
},
addMail:function() {
//alert('addMail');
$('#emaillist li[class*="template"]:first-child').clone().appendTo($('#emaillist')).show();
$('#emaillist li[class*="template"]:last-child').removeClass('template').addClass('propertycontainer');
$('#emaillist li.template:first-child').clone().appendTo($('#emaillist')).show();
$('#emaillist li.template:last-child').removeClass('template').addClass('propertycontainer');
$('#emaillist li:last-child').find('input[type="email"]').focus();
Contacts.UI.loadListHandlers();
return false;
},
loadMails:function() {
$('#emails').hide();
$('#emaillist li[class*="propertycontainer"]').remove();
$('#emaillist li.propertycontainer').remove();
for(var mail in this.data.EMAIL) {
this.addMail();
//$('#emaillist li:first-child').clone().appendTo($('#emaillist')).show();
@ -950,9 +1034,9 @@ Contacts={
return false;
},
addPhone:function() {
$('#phonelist li[class*="template"]:first-child').clone().appendTo($('#phonelist')); //.show();
$('#phonelist li[class*="template"]:last-child').find('select').addClass('contacts_property');
$('#phonelist li[class*="template"]:last-child').removeClass('template').addClass('propertycontainer');
$('#phonelist li.template:first-child').clone().appendTo($('#phonelist')); //.show();
$('#phonelist li.template:last-child').find('select').addClass('contacts_property');
$('#phonelist li.template:last-child').removeClass('template').addClass('propertycontainer');
$('#phonelist li:last-child').find('input[type="text"]').focus();
Contacts.UI.loadListHandlers();
$('#phonelist li:last-child').find('select').multiselect({
@ -966,7 +1050,7 @@ Contacts={
},
loadPhones:function() {
$('#phones').hide();
$('#phonelist li[class*="propertycontainer"]').remove();
$('#phonelist li.propertycontainer').remove();
for(var phone in this.data.TEL) {
this.addPhone();
$('#phonelist li:last-child').find('select').multiselect('destroy');
@ -1006,13 +1090,17 @@ Contacts={
if($('#chooseaddressbook_dialog').dialog('isOpen') == true){
$('#chooseaddressbook_dialog').dialog('moveToTop');
}else{
$('#dialog_holder').load(OC.filePath('contacts', 'ajax', 'chooseaddressbook.php'), function(){
$('#chooseaddressbook_dialog').dialog({
width : 600,
close : function(event, ui) {
$(this).dialog('destroy').remove();
}
});
$('#dialog_holder').load(OC.filePath('contacts', 'ajax', 'chooseaddressbook.php'), function(jsondata){
if(jsondata.status != 'error'){
$('#chooseaddressbook_dialog').dialog({
width : 600,
close : function(event, ui) {
$(this).dialog('destroy').remove();
}
});
} else {
alert(jsondata.data.message);
}
});
}
},
@ -1049,7 +1137,7 @@ Contacts={
Contacts.UI.Contacts.update();
Contacts.UI.Addressbooks.overview();
} else {
Contacts.UI.messageBox(t('contacts', 'Error'), jsondata.data.message);
OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
//alert('Error: ' + data.message);
}
});
@ -1064,7 +1152,7 @@ Contacts={
var description = $("#description_"+bookid).val();
if(displayname.length == 0) {
Contacts.UI.messageBox(t('contacts', 'Error'), t('contacts', 'Displayname cannot be empty.'));
OC.dialogs.alert(t('contacts', 'Displayname cannot be empty.'), t('contacts', 'Error'));
return false;
}
var url;
@ -1079,7 +1167,7 @@ Contacts={
$(button).closest('tr').prev().html(jsondata.page).show().next().remove();
Contacts.UI.Contacts.update();
} else {
Contacts.UI.messageBox(t('contacts', 'Error'), jsondata.data.message);
OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
}
});
},
@ -1099,7 +1187,7 @@ Contacts={
Contacts.UI.Card.update();
}
else{
Contacts.UI.messageBox(t('contacts', 'Error'),jsondata.data.message);
OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
//alert(jsondata.data.message);
}
});
@ -1114,6 +1202,9 @@ Contacts={
$(this).find('a').css('background','url(thumbnail.php?id='+$(this).data('id')+') no-repeat');
}
});
},
refreshThumbnail:function(id){
$('#contacts [data-id="'+id+'"]').find('a').css('background','url(thumbnail.php?id='+id+'&refresh=1'+Math.random()+') no-repeat');
}
}
}
@ -1121,6 +1212,8 @@ Contacts={
$(document).ready(function(){
Contacts.UI.loadHandlers();
OCCategories.changed = Contacts.UI.Card.categoriesChanged;
OCCategories.app = 'contacts';
/**
* Show the Addressbook chooser
@ -1148,7 +1241,7 @@ $(document).ready(function(){
Contacts.UI.Card.loadContact(jsondata.data);
}
else{
Contacts.UI.messageBox(t('contacts', 'Error'), jsondata.data.message);
OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
//alert(jsondata.data.message);
}
});
@ -1189,7 +1282,8 @@ $(document).ready(function(){
// NOTE: For some reason the selector doesn't work when I select by '.contacts_property' too...
// I do the filtering in the event handler instead.
$('input[type="text"],input[type="checkbox"],input[type="email"],input[type="tel"],input[type="date"], select').live('change', function(){
//$('input[type="text"],input[type="checkbox"],input[type="email"],input[type="tel"],input[type="date"], select').live('change', function(){
$('.contacts_property').live('change', function(){
Contacts.UI.Card.saveProperty(this);
});
@ -1246,17 +1340,17 @@ $(document).ready(function(){
var file = files[0];
console.log('size: '+file.size);
if(file.size > $('#max_upload').val()){
Contacts.UI.messageBox(t('contacts','Upload too large'), t('contacts','The file you are trying to upload exceed the maximum size for file uploads on this server.'));
OC.dialogs.alert(t('contacts','The file you are trying to upload exceed the maximum size for file uploads on this server.'), t('contacts','Upload too large'));
return;
}
if (file.type.indexOf("image") != 0) {
Contacts.UI.messageBox(t('contacts','Wrong file type'), t('contacts','Only image files can be used as profile picture.'));
OC.dialogs.alert(t('contacts','Only image files can be used as profile picture.'), t('contacts','Wrong file type'));
return;
}
var xhr = new XMLHttpRequest();
if (!xhr.upload) {
Contacts.UI.messageBox(t('contacts', 'Error'), t('contacts', 'Your browser doesn\'t support AJAX upload. Please click on the profile picture to select a photo to upload.'))
OC.dialogs.alert(t('contacts', 'Your browser doesn\'t support AJAX upload. Please click on the profile picture to select a photo to upload.'), t('contacts', 'Error'))
}
fileUpload = xhr.upload,
xhr.onreadystatechange = function() {
@ -1266,11 +1360,11 @@ $(document).ready(function(){
if(xhr.status == 200) {
Contacts.UI.Card.editPhoto(response.data.id, response.data.tmp);
} else {
Contacts.UI.messageBox(t('contacts', 'Error'), xhr.status + ': ' + xhr.responseText);
OC.dialogs.alert(xhr.status + ': ' + xhr.responseText, t('contacts', 'Error'));
}
} else {
//alert(xhr.responseText);
Contacts.UI.messageBox(t('contacts', 'Error'), response.data.message);
OC.dialogs.alert(response.data.message, t('contacts', 'Error'));
}
// stop loading indicator
//$('#contacts_details_photo_progress').hide();
@ -1298,8 +1392,19 @@ $(document).ready(function(){
xhr.send(file);
}
$('body').live('click',function(e){
if(!$(e.target).is('#contacts_propertymenu_button')) {
$('#contacts_propertymenu').hide();
}
});
$('#contacts_propertymenu_button').live('click',function(){
$('#contacts_propertymenu').is(':hidden') && $('#contacts_propertymenu').slideDown() || $('#contacts_propertymenu').slideUp();
var menu = $('#contacts_propertymenu');
if(menu.is(':hidden')) {
menu.show();
menu.find('ul').focus();
} else {
menu.hide();
}
});
$('#contacts_propertymenu a').live('click',function(){
Contacts.UI.Card.addProperty(this);

View File

@ -1,409 +0,0 @@
/**
* ownCloud - Addressbook
*
* @author Jakob Sack
* @copyright 2011 Jakob Sack mail@jakobsack.de
* @copyright 2011-2012 Thomas Tanghus <thomas@tanghus.net>
*
* 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/>.
*
*/
Contacts={
UI:{
showCardDAVUrl:function(username, bookname){
$('#carddav_url').val(totalurl + '/' + username + '/' + bookname);
$('#carddav_url').show();
$('#carddav_url_close').show();
},
messageBox:function(title, msg) {
if($('#messagebox').dialog('isOpen') == true){
// NOTE: Do we ever get here?
$('#messagebox').dialog('moveToTop');
}else{
$('#dialog_holder').load(OC.filePath('contacts', 'ajax', 'messagebox.php'), function(){
$('#messagebox').dialog(
{
autoOpen: true,
title: title,
buttons: [{
text: "Ok",
click: function() { $(this).dialog("close"); }
}],
close: function(event, ui) {
$(this).dialog('destroy').remove();
},
open: function(event, ui) {
$('#messagebox_msg').html(msg);
}
});
});
}
},
Addressbooks:{
overview:function(){
if($('#chooseaddressbook_dialog').dialog('isOpen') == true){
$('#chooseaddressbook_dialog').dialog('moveToTop');
}else{
$('#dialog_holder').load(OC.filePath('contacts', 'ajax', 'chooseaddressbook.php'), function(){
$('#chooseaddressbook_dialog').dialog({
width : 600,
close : function(event, ui) {
$(this).dialog('destroy').remove();
}
});
});
}
},
activation:function(checkbox, bookid)
{
$.post(OC.filePath('contacts', 'ajax', 'activation.php'), { bookid: bookid, active: checkbox.checked?1:0 },
function(data) {
/*
* Arguments:
* data.status
* data.bookid
* data.active
*/
if (data.status == 'success'){
checkbox.checked = data.active == 1;
Contacts.UI.Contacts.update();
}
});
},
newAddressbook:function(object){
var tr = $(document.createElement('tr'))
.load(OC.filePath('contacts', 'ajax', 'addbook.php'));
$(object).closest('tr').after(tr).hide();
/* TODO: Shouldn't there be some kinda error checking here? */
},
editAddressbook:function(object, bookid){
var tr = $(document.createElement('tr'))
.load(OC.filePath('contacts', 'ajax', 'editaddressbook.php') + "?bookid="+bookid);
$(object).closest('tr').after(tr).hide();
},
deleteAddressbook:function(bookid){
var check = confirm("Do you really want to delete this address book?");
if(check == false){
return false;
}else{
$.post(OC.filePath('contacts', 'ajax', 'deletebook.php'), { id: bookid},
function(data) {
if (data.status == 'success'){
$('#chooseaddressbook_dialog').dialog('destroy').remove();
Contacts.UI.Contacts.update();
Contacts.UI.Addressbooks.overview();
} else {
Contacts.UI.messageBox(t('contacts', 'Error'), data.message);
//alert('Error: ' + data.message);
}
});
}
},
submit:function(button, bookid){
var displayname = $("#displayname_"+bookid).val();
var active = $("#edit_active_"+bookid+":checked").length;
var description = $("#description_"+bookid).val();
var url;
if (bookid == 'new'){
url = OC.filePath('contacts', 'ajax', 'createaddressbook.php');
}else{
url = OC.filePath('contacts', 'ajax', 'updateaddressbook.php');
}
$.post(url, { id: bookid, name: displayname, active: active, description: description },
function(jsondata){
if(jsondata.status == 'success'){
$(button).closest('tr').prev().html(data.page).show().next().remove();
Contacts.UI.Contacts.update();
} else {
Contacts.UI.messageBox(t('contacts', 'Error'), jsondata.data.message);
}
});
},
cancel:function(button, bookid){
$(button).closest('tr').prev().show().next().remove();
}
},
Contacts:{
/**
* Reload the contacts list.
*/
update:function(){
$.getJSON('ajax/contacts.php',{},function(jsondata){
if(jsondata.status == 'success'){
$('#contacts').html(jsondata.data.page);
}
else{
Contacts.UI.messageBox(t('contacts', 'Error'),jsondata.data.message);
//alert(jsondata.data.message);
}
});
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(thumbnail.php?id='+$(this).data('id')+') no-repeat');
}
});
}
}
}
}
$(document).ready(function(){
/*-------------------------------------------------------------------------
* Event handlers
*-----------------------------------------------------------------------*/
/**
* Load the details view for a contact.
*/
$('#leftcontent li').live('click',function(){
var id = $(this).data('id');
var oldid = $('#rightcontent').data('id');
if(oldid != 0){
$('#leftcontent li[data-id="'+oldid+'"]').removeClass('active');
}
$.getJSON('ajax/getdetails.php',{'id':id},function(jsondata){
if(jsondata.status == 'success'){
$('#rightcontent').data('id',jsondata.data.id);
$('#rightcontent').html(jsondata.data.page);
$('#leftcontent li[data-id="'+jsondata.data.id+'"]').addClass('active');
}
else{
Contacts.UI.messageBox(t('contacts', 'Error'), jsondata.data.message);
//alert(jsondata.data.message);
}
});
return false;
});
/**
* Delete currently selected contact (and clear form?)
*/
$('#contacts_deletecard').live('click',function(){
$('#contacts_deletecard').tipsy('hide');
var id = $('#rightcontent').data('id');
$.getJSON('ajax/deletecard.php',{'id':id},function(jsondata){
if(jsondata.status == 'success'){
$('#leftcontent [data-id="'+jsondata.data.id+'"]').remove();
$('#rightcontent').data('id','');
$('#rightcontent').empty();
}
else{
Contacts.UI.messageBox(t('contacts', 'Error'), jsondata.data.message);
//alert(jsondata.data.message);
}
});
return false;
});
/**
* Add a property to the contact.
* NOTE: Where does 'contacts_addproperty' exist?
*/
$('#contacts_addproperty').live('click',function(){
var id = $('#rightcontent').data('id');
$.getJSON('ajax/showaddproperty.php',{'id':id},function(jsondata){
if(jsondata.status == 'success'){
$('#contacts_details_list').append(jsondata.data.page);
$('#contacts_addproperty').hide();
}
else{
Contacts.UI.messageBox(t('contacts', 'Error'), jsondata.data.message);
alert('From handler: '+jsondata.data.message);
}
});
return false;
});
/**
* Change the inputs based on which type of property is selected for addition.
*/
$('#contacts_addpropertyform [name="name"]').live('change',function(){
$('#contacts_addpropertyform #contacts_addresspart').remove();
$('#contacts_addpropertyform #contacts_phonepart').remove();
$('#contacts_addpropertyform #contacts_fieldpart').remove();
$('#contacts_addpropertyform #contacts_generic').remove();
if($(this).val() == 'ADR'){
$('#contacts_addresspart').clone().insertAfter($('#contacts_addpropertyform .contacts_property_name'));
}
else if($(this).val() == 'TEL'){
$('#contacts_phonepart').clone().insertAfter($('#contacts_addpropertyform .contacts_property_name'));
}
else{
$('#contacts_generic').clone().insertAfter($('#contacts_addpropertyform .contacts_property_name'));
}
$('#contacts_addpropertyform .contacts_property_data select').chosen();
});
$('#contacts_addpropertyform input[type="submit"]').live('click',function(){
$.post('ajax/addproperty.php',$('#contacts_addpropertyform').serialize(),function(jsondata){
if(jsondata.status == 'success'){
$('#contacts_addpropertyform').before(jsondata.data.page);
}
else{
Contacts.UI.messageBox(t('contacts', 'Error'), jsondata.data.message);
}
}, 'json');
return false;
});
/**
* Show the Addressbook chooser
*/
$('#chooseaddressbook').click(function(){
Contacts.UI.Addressbooks.overview();
return false;
});
/**
* Open blank form to add new contact.
*/
$('#contacts_newcontact').click(function(){
$.getJSON('ajax/showaddcard.php',{},function(jsondata){
if(jsondata.status == 'success'){
$('#rightcontent').data('id','');
$('#rightcontent').html(jsondata.data.page)
.find('select').chosen();
}
else{
Contacts.UI.messageBox(t('contacts', 'Error'), jsondata.data.message);
//alert(jsondata.data.message);
}
});
return false;
});
/**
* Add and insert a new contact into the list.
*/
$('#contacts_addcardform input[type="submit"]').live('click',function(){
$.post('ajax/addcard.php',$('#contacts_addcardform').serialize(),function(jsondata){
if(jsondata.status == 'success'){
$('#rightcontent').data('id',jsondata.data.id);
$('#rightcontent').html(jsondata.data.page);
$('#leftcontent .active').removeClass('active');
var item = '<li data-id="'+jsondata.data.id+'" class="active"><a href="index.php?id='+jsondata.data.id+'" style="background: url(thumbnail.php?id='+jsondata.data.id+') no-repeat scroll 0% 0% transparent;">'+jsondata.data.name+'</a></li>';
var added = false;
$('#leftcontent ul li').each(function(){
if ($(this).text().toLowerCase() > jsondata.data.name.toLowerCase()) {
$(this).before(item).fadeIn('fast');
added = true;
return false;
}
});
if(!added) {
$('#leftcontent ul').append(item);
}
}
else{
Contacts.UI.messageBox(t('contacts', 'Error'), jsondata.data.message);
//alert(jsondata.data.message);
}
}, 'json');
return false;
});
/**
* Show inputs for editing a property.
*/
$('.contacts_property [data-use="edit"]').live('click',function(){
var id = $('#rightcontent').data('id');
var checksum = $(this).parents('.contacts_property').first().data('checksum');
$.getJSON('ajax/showsetproperty.php',{'id': id, 'checksum': checksum },function(jsondata){
if(jsondata.status == 'success'){
$('.contacts_property[data-checksum="'+checksum+'"]').html(jsondata.data.page)
.find('select').chosen();
}
else{
Contacts.UI.messageBox(t('contacts', 'Error'), jsondata.data.message);
//alert(jsondata.data.message);
}
});
return false;
});
/**
* Save the edited property
*/
$('#contacts_setpropertyform input[type="submit"]').live('click',function(){
$.post('ajax/setproperty.php',$(this).parents('form').first().serialize(),function(jsondata){
if(jsondata.status == 'success'){
$('.contacts_property[data-checksum="'+jsondata.data.oldchecksum+'"]').replaceWith(jsondata.data.page);
}
else{
Contacts.UI.messageBox(t('contacts', 'Error'), jsondata.data.message);
//alert(jsondata.data.message);
}
},'json');
return false;
});
$('.contacts_property [data-use="delete"]').live('click',function(){
var id = $('#rightcontent').data('id');
var checksum = $(this).parents('li').first().data('checksum');
$.getJSON('ajax/deleteproperty.php',{'id': id, 'checksum': checksum },function(jsondata){
if(jsondata.status == 'success'){
$('.contacts_property[data-checksum="'+checksum+'"]').remove();
}
else{
Contacts.UI.messageBox(t('contacts', 'Error'), jsondata.data.message);
//alert(jsondata.data.message);
}
});
return false;
});
$('.contacts_property').live('mouseenter',function(){
$(this).find('span[data-use]').show();
});
$('.contacts_property').live('mouseleave',function(){
$(this).find('span[data-use]').hide();
});
$('#contacts_addcardform select').chosen();
$('#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
if (visiblePartY == 'top') {
// top part of element is visible
} else if (visiblePartY == 'bottom') {
// bottom part of element is visible
} else {
// whole part of element is visible
if (!$(this).find('a').attr('style')) {
//alert($(this).data('id') + ' has background: ' + $(this).attr('style'));
$(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'));
}*/
}
} else {
// element has gone out of viewport
}
});
$('.button').tipsy();
//Contacts.UI.messageBox('Hello','Sailor');
});

View File

@ -0,0 +1,92 @@
/**
* Inspired by http://jqueryui.com/demos/autocomplete/#multiple
*/
(function( $ ) {
$.widget('ui.multiple_autocomplete', {
_create: function() {
var self = this;
function split( val ) {
return val.split( /,\s*/ );
}
function extractLast( term ) {
return split( term ).pop();
}
function showOptions() {
if(!self.element.autocomplete('widget').is(':visible') && self.element.val().trim() == '') {
self.element.autocomplete('search', '');
}
}
//console.log('_create: ' + this.options['id']);
this.element.bind('click', function( event ) {
showOptions();
});
this.element.bind('input', function( event ) {
showOptions();
});
this.element.bind('blur', function( event ) {
var tmp = self.element.val().trim();
if(tmp[tmp.length-1] == ',') {
self.element.val(tmp.substring(0, tmp.length-1));
} else {
self.element.val(tmp);
}
self.element.trigger('change'); // Changes wasn't saved when only using the dropdown.
});
this.element.bind( "keydown", function( event ) {
if ( event.keyCode === $.ui.keyCode.TAB &&
$( this ).data( "autocomplete" ).menu.active ) {
event.preventDefault();
}
})
.autocomplete({
minLength: 0,
source: function( request, response ) {
// delegate back to autocomplete, but extract the last term
response( $.ui.autocomplete.filter(
self.options.source, extractLast( request.term ) ) );
},
focus: function() {
// prevent value inserted on focus
return false;
},
select: function( event, ui ) {
var terms = split( this.value );
// remove the current input
terms.pop();
// add the selected item
terms.push( ui.item.value );
// add placeholder to get the comma-and-space at the end
terms.push( "" );
this.value = terms.join( ", " );
return false;
}
});
this.button = $( "<button type='button'>&nbsp;</button>" )
.attr( "tabIndex", -1 )
.attr( "title", "Show All Items" )
.insertAfter( this.element )
.addClass('svg')
.addClass('action')
.addClass('combo-button')
.click(function() {
// close if already visible
if ( self.element.autocomplete( "widget" ).is( ":visible" ) ) {
self.element.autocomplete( "close" );
return;
}
// work around a bug (likely same cause as #5265)
$( this ).blur();
var tmp = self.element.val().trim();
if(tmp[tmp.length-1] != ',') {
self.element.val(tmp+', ');
}
// pass empty string as value to search for, displaying all results
self.element.autocomplete( "search", "" );
self.element.focus();
});
},
});
})( jQuery );

View File

@ -77,5 +77,7 @@ $(document).ready(function(){
if(typeof FileActions !== 'undefined'){
FileActions.register('text/vcard','importaddressbook', '', Contacts_Import.importdialog);
FileActions.setDefault('text/vcard','importaddressbook');
FileActions.register('text/x-vcard','importaddressbook', '', Contacts_Import.importdialog);
FileActions.setDefault('text/x-vcard','importaddressbook');
};
});

View File

@ -1,20 +1,17 @@
../appinfo/app.php
../ajax/activation.php
../ajax/addbook.php
../ajax/addcard.php
../ajax/addproperty.php
../ajax/createaddressbook.php
../ajax/deletebook.php
../ajax/deleteproperty.php
../ajax/getdetails.php
../ajax/setproperty.php
../ajax/saveproperty.php
../ajax/updateaddressbook.php
../lib/app.php
../templates/index.php
../templates/part.addcardform.php
../templates/part.chooseaddressbook.php
../templates/part.chooseaddressbook.rowfields.php
../templates/part.details.php
../templates/part.editaddressbook.php
../templates/part.property.php
../templates/part.setpropertyform.php

View File

@ -10,8 +10,10 @@
* This class manages our app actions
*/
OC_Contacts_App::$l10n = new OC_L10N('contacts');
OC_Contacts_App::$categories = new OC_VCategories('contacts');
class OC_Contacts_App {
public static $l10n;
public static $categories;
/**
* Render templates/part.details to json output
@ -92,7 +94,7 @@ class OC_Contacts_App {
OC_Log::write('contacts','getContactVCard, found FN field: '.$vcard->__get('FN'), OC_Log::DEBUG);
$n = implode(';', array_reverse(array_slice(explode(' ', $vcard->__get('FN')), 0, 2))).';;;';
$vcard->setString('N', $n);
OC_Contacts_VCard::edit( $id, $vcard->serialize());
OC_Contacts_VCard::edit( $id, $vcard);
} else { // Else just add an empty 'N' field :-P
$vcard->setString('N', 'Unknown;Name;;;');
}
@ -153,6 +155,10 @@ class OC_Contacts_App {
}
}
public static function getCategories() {
return self::$categories->categories();
}
public static function setLastModifiedHeader($contact) {
$rev = $contact->getAsString('REV');
if ($rev) {

View File

@ -4,6 +4,7 @@
*
* @author Jakob Sack
* @copyright 2011 Jakob Sack mail@jakobsack.de
* @copyright 2012 Thomas Tanghus <thomas@tanghus.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
@ -174,6 +175,9 @@ class OC_Contacts_VCard{
if($property->name == 'UID'){
$uid = $property->value;
}
if($property->name == 'ORG'){
$org = $property->value;
}
if($property->name == 'EMAIL' && is_null($email)){ // only use the first email as substitute for missing N or FN.
$email = $property->value;
}
@ -184,6 +188,8 @@ class OC_Contacts_VCard{
$fn = join(' ', array_reverse(array_slice(explode(';', $n), 0, 2)));
} elseif($email) {
$fn = $email;
} elseif($org) {
$fn = $org;
} else {
$fn = 'Unknown Name';
}
@ -217,31 +223,37 @@ class OC_Contacts_VCard{
/**
* @brief Adds a card
* @param integer $id Addressbook id
* @param string $data vCard file
* @return insertid on success or null if card is not parseable.
* @param integer $aid Addressbook id
* @param OC_VObject $card vCard file
* @param string $uri the uri of the card, default based on the UID
* @return insertid on success or null if no card.
*/
public static function add($id,$data){
$fn = null;
$card = OC_VObject::parse($data);
if(!is_null($card)){
self::updateValuesFromAdd($card);
$data = $card->serialize();
}
else{
OC_Log::write('contacts','OC_Contacts_VCard::add. Error parsing VCard: '.$data,OC_Log::ERROR);
return null; // Ditch cards that can't be parsed by Sabre.
public static function add($aid, OC_VObject $card, $uri=null){
if(is_null($card)){
OC_Log::write('contacts','OC_Contacts_VCard::add. No vCard supplied', OC_Log::ERROR);
return null;
};
OC_Contacts_App::$categories->loadFromVObject($card);
self::updateValuesFromAdd($card);
$fn = $card->getAsString('FN');
$uid = $card->getAsString('UID');
$uri = $uid.'.vcf';
if (empty($fn)) {
$fn = null;
}
if (!$uri) {
$uid = $card->getAsString('UID');
$uri = $uid.'.vcf';
}
$data = $card->serialize();
$stmt = OC_DB::prepare( 'INSERT INTO *PREFIX*contacts_cards (addressbookid,fullname,carddata,uri,lastmodified) VALUES(?,?,?,?,?)' );
$result = $stmt->execute(array($id,$fn,$data,$uri,time()));
$result = $stmt->execute(array($aid,$fn,$data,$uri,time()));
$newid = OC_DB::insertid('*PREFIX*contacts_cards');
OC_Contacts_Addressbook::touch($id);
OC_Contacts_Addressbook::touch($aid);
return $newid;
}
@ -255,49 +267,56 @@ class OC_Contacts_VCard{
*/
public static function addFromDAVData($id,$uri,$data){
$card = OC_VObject::parse($data);
if(!is_null($card)){
self::updateValuesFromAdd($card);
$data = $card->serialize();
} else {
OC_Log::write('contacts','OC_Contacts_VCard::addFromDAVData. Error parsing VCard: '.$data, OC_Log::ERROR);
return null; // Ditch cards that can't be parsed by Sabre.
};
$fn = $card->getAsString('FN');
return self::add($id, $card, $uri);
}
$stmt = OC_DB::prepare( 'INSERT INTO *PREFIX*contacts_cards (addressbookid,fullname,carddata,uri,lastmodified) VALUES(?,?,?,?,?)' );
$result = $stmt->execute(array($id,$fn,$data,$uri,time()));
$newid = OC_DB::insertid('*PREFIX*contacts_cards');
OC_Contacts_Addressbook::touch($id);
return $newid;
/**
* @brief Mass updates an array of cards
* @param array $objects An array of [id, carddata].
*/
public static function updateDataByID($objects){
$stmt = OC_DB::prepare( 'UPDATE *PREFIX*contacts_cards SET carddata = ?, lastmodified = ? WHERE id = ?' );
$now = new DateTime;
foreach($objects as $object) {
$vcard = OC_VObject::parse($object[1]);
if(!is_null($vcard)){
$vcard->setString('REV', $now->format(DateTime::W3C));
$data = $vcard->serialize();
try {
$result = $stmt->execute(array($data,time(),$object[0]));
//OC_Log::write('contacts','OC_Contacts_VCard::updateDataByID, id: '.$object[0].': '.$object[1],OC_Log::DEBUG);
} catch(Exception $e) {
OC_Log::write('contacts','OC_Contacts_VCard::updateDataByID:, exception: '.$e->getMessage(),OC_Log::DEBUG);
OC_Log::write('contacts','OC_Contacts_VCard::updateDataByID, id: '.$object[0],OC_Log::DEBUG);
}
}
}
}
/**
* @brief edits a card
* @param integer $id id of card
* @param string $data vCard file
* @param OC_VObject $card vCard file
* @return boolean
*/
public static function edit($id, $data){
public static function edit($id, OC_VObject $card){
$oldcard = self::find($id);
$fn = null;
$card = OC_VObject::parse($data);
if(!is_null($card)){
foreach($card->children as $property){
if($property->name == 'FN'){
$fn = $property->value;
break;
}
}
} else {
if(is_null($card)) {
return false;
}
OC_Contacts_App::$categories->loadFromVObject($card);
$fn = $card->getAsString('FN');
if (empty($fn)) {
$fn = null;
}
$now = new DateTime;
$card->setString('REV', $now->format(DateTime::W3C));
$data = $card->serialize();
$data = $card->serialize();
$stmt = OC_DB::prepare( 'UPDATE *PREFIX*contacts_cards SET fullname = ?,carddata = ?, lastmodified = ? WHERE id = ?' );
$result = $stmt->execute(array($fn,$data,time(),$id));
@ -315,27 +334,8 @@ class OC_Contacts_VCard{
*/
public static function editFromDAVData($aid,$uri,$data){
$oldcard = self::findWhereDAVDataIs($aid,$uri);
$fn = null;
$card = OC_VObject::parse($data);
if(!is_null($card)){
foreach($card->children as $property){
if($property->name == 'FN'){
$fn = $property->value;
break;
}
}
}
$now = new DateTime;
$card->setString('REV', $now->format(DateTime::W3C));
$data = $card->serialize();
$stmt = OC_DB::prepare( 'UPDATE *PREFIX*contacts_cards SET fullname = ?,carddata = ?, lastmodified = ? WHERE id = ?' );
$result = $stmt->execute(array($fn,$data,time(),$oldcard['id']));
OC_Contacts_Addressbook::touch($oldcard['addressbookid']);
return true;
return self::edit($oldcard['id'], $card);
}
/**
@ -351,14 +351,6 @@ class OC_Contacts_VCard{
return true;
}
/**
* @brief Creates a UID
* @return string
*/
public static function createUID(){
return substr(md5(rand().time()),0,10);
}
/**
* @brief deletes a card with the data provided by sabredav
* @param integer $aid Addressbook id
@ -374,6 +366,43 @@ class OC_Contacts_VCard{
return true;
}
/**
* @brief Escapes delimiters from an array and returns a string.
* @param array $value
* @param char $delimiter
* @return string
*/
public static function escapeDelimiters($value, $delimiter=';') {
foreach($value as &$i ) {
$i = implode("\\$delimiter", explode($delimiter, $i));
}
return implode($delimiter, $value);
}
/**
* @brief Creates an array out of a multivalue property
* @param string $value
* @param char $delimiter
* @return array
*/
public static function unescapeDelimiters($value, $delimiter=';') {
$array = explode($delimiter,$value);
for($i=0;$i<count($array);$i++) {
if(substr($array[$i],-1,1)=="\\") {
if(isset($array[$i+1])) {
$array[$i] = substr($array[$i],0,count($array[$i])-2).$delimiter.$array[$i+1];
unset($array[$i+1]);
} else {
$array[$i] = substr($array[$i],0,count($array[$i])-2).$delimiter;
}
$i = $i - 1;
}
}
$array = array_map('trim', $array);
return $array;
}
/**
* @brief Data structure of vCard
* @param object $property
@ -412,8 +441,10 @@ class OC_Contacts_VCard{
$value = $property->value;
//$value = htmlspecialchars($value);
if($property->name == 'ADR' || $property->name == 'N'){
$value = OC_VObject::unescapeSemicolons($value);
}
$value = self::unescapeDelimiters($value);
}/* elseif($property->name == 'CATEGORIES') {
$value = self::unescapeDelimiters($value, ',');
}*/
$temp = array(
'name' => $property->name,
'value' => $value,

View File

@ -1,5 +1,6 @@
<script type='text/javascript'>
var totalurl = '<?php echo OC_Helper::linkToAbsolute('contacts', 'carddav.php'); ?>/addressbooks';
var categories = <?php sort($_['categories']); echo json_encode($_['categories']); ?>;
</script>
<div id="controls">
<form>

View File

@ -1,138 +0,0 @@
<form id="contacts_addcardform">
<?php if(count($_['addressbooks'])==1): ?>
<input type="hidden" name="id" value="<?php echo $_['addressbooks'][0]['id']; ?>">
<?php else: ?>
<fieldset class="inputs">
<dl class="form">
<dt>
<label for="id"><?php echo $l->t('Addressbook'); ?></label>
</dt>
<dd>
<select name="id" size="1">
<?php echo html_select_options($_['addressbooks'], null, array('value'=>'id', 'label'=>'displayname')); ?>
</select>
</dd>
</dl>
</fieldset>
<?php endif; ?>
<fieldset class="inputs">
<dl class="form">
<dt>
<label for="n1"><?php echo $l->t('Given name'); ?></label>
</dd>
<dd>
<input id="n1" type="text" name="value[N][1]" value="">
</dd>
<dt>
<label for="n0"><?php echo $l->t('Family name'); ?></label>
</dd>
<dd>
<input id="n0" type="text" name="value[N][0]" value="">
</dd>
<dt>
<label for="n2"><?php echo $l->t('Additional names'); ?></label>
</dd>
<dd>
<input id="n2" type="text" name="value[N][2]" value="">
<input type="hidden" name="value[N][4]" value="">
<input type="hidden" name="value[N][5]" value="">
</dd>
</dl>
</fieldset>
<fieldset class="inputs">
<dl class="form">
<dt>
<label for="fn"><?php echo $l->t('Display name'); ?></label>
</dd>
<dd>
<input id="fn" type="text" name="fn" placeholder="<?php echo $l->t('How you want the name displayed in the list'); ?>" value="">
</dd>
<dt>
<label for="org"><?php echo $l->t('Organization'); ?></label>
</dt>
<dd>
<input id="org" type="text" name="value[ORG]" value="">
</dd>
</dl>
</fieldset>
<fieldset class="inputs">
<dl class="form">
<dt>
<label for="email"><?php echo $l->t('Email'); ?></label>
</dt>
<dd>
<input id="email" type="email" name="value[EMAIL]" value="">
</dd>
<dt>
<label for="tel"><?php echo $l->t('Telephone'); ?></label>
</dt>
<dd>
<input type="tel" id="tel" name="value[TEL]" value="">
<select id="TEL" name="parameters[TEL][TYPE][]" multiple="multiple">
<?php echo html_select_options($_['phone_types'], 'CELL') ?>
</select>
</dd>
</dl>
</fieldset>
<fieldset class="inputs">
<legend><?php echo $l->t('Address'); ?></legend>
<dl class="form">
<dt>
<label for="adr_type"><?php echo $l->t('Type'); ?></label>
</dt>
<dd>
<select id="adr_type" name="parameters[ADR][TYPE]" size="1">
<?php echo html_select_options($_['adr_types'], 'HOME') ?>
</select>
</dd>
<dt>
<label for="adr_pobox"><?php echo $l->t('PO Box'); ?></label>
</dt>
<dd>
<input type="text" id="adr_pobox" name="value[ADR][0]" placeholder="<?php echo $l->t('Post Office box'); ?>" value="">
</dd>
<dd>
<!-- dt>
<label class="label" for="adr_extended"><?php echo $l->t('Extended'); ?></label>
</dt>
<dd>
<input type="text" id="adr_extended" name="value[ADR][1]" value="">
</dd -->
<dt>
<label for="adr_street"><?php echo $l->t('Street'); ?></label>
</dt>
<dd>
<input style="width: 12em;" type="text" id="adr_street" name="value[ADR][2]" placeholder="<?php echo $l->t('Street name and no.'); ?>" value="">
<label for="adr_extended"><?php echo $l->t('Extended'); ?></label>
<input style="width: 7em;" type="text" id="adr_extended" name="value[ADR][1]" placeholder="<?php echo $l->t('Apart. no., floor'); ?>" value="">
</dd>
<dt>
<label for="adr_city"><?php echo $l->t('City'); ?></label>
</dt>
<dd>
<input style="width: 12em;" type="text" id="adr_city" name="value[ADR][3]" value="">
<label for="adr_zipcode"><?php echo $l->t('Zipcode'); ?></label>
<input style="width: 5em;" type="text" id="adr_zipcode" name="value[ADR][5]" value="">
</dd>
<dt>
<label for="adr_region"><?php echo $l->t('Region'); ?></label>
</dt>
<dd>
<input type="text" id="adr_region" name="value[ADR][4]" placeholder="<?php echo $l->t('E.g. state or province'); ?>" value="">
</dd>
<!-- dt>
<label class="label" for="adr_zipcode"><?php echo $l->t('Zipcode'); ?></label>
</dt>
<dd>
<input type="text" id="adr_zipcode" name="value[ADR][5]" value="">
</dd -->
<dt>
<label for="adr_country"><?php echo $l->t('Country'); ?></label>
</dt>
<dd>
<input type="text" id="adr_country" name="value[ADR][6]" value="">
</dd>
</dl>
</fieldset>
<input class="create" type="submit" name="submit" value="<?php echo $l->t('Create Contact'); ?>">
</form>

View File

@ -13,6 +13,8 @@ $id = isset($_['id']) ? $_['id'] : '';
<li><a data-type="TEL"><?php echo $l->t('Phone'); ?></a></li>
<li><a data-type="EMAIL"><?php echo $l->t('Email'); ?></a></li>
<li><a data-type="ADR"><?php echo $l->t('Address'); ?></a></li>
<li><a data-type="NOTE"><?php echo $l->t('Note'); ?></a></li>
<li><a data-type="CATEGORIES"><?php echo $l->t('Categories'); ?></a></li>
</ul>
</div>
<img onclick="Contacts.UI.Card.export();" class="svg action" id="contacts_downloadcard" src="<?php echo image_path('', 'actions/download.svg'); ?>" title="<?php echo $l->t('Download contact');?>" />
@ -21,8 +23,9 @@ $id = isset($_['id']) ? $_['id'] : '';
<div class="contactsection">
<form style="display:none;" id="file_upload_form" action="ajax/uploadphoto.php" method="post" enctype="multipart/form-data" target="file_upload_target">
<form style="display:none;" id="file_upload_form" action="ajax/uploadphoto.php" method="post" enctype="multipart/form-data" target="file_upload_target" class="propertycontainer" data-element="PHOTO">
<fieldset id="photo" class="formfloat">
<a class="action delete" onclick="$(this).tipsy('hide');Contacts.UI.Card.deleteProperty(this, 'single');" title="<?php echo $l->t('Delete'); ?>"></a>
<div id="contacts_details_photo_wrapper" title="<?php echo $l->t('Click or drop to upload picture'); ?> (max <?php echo $_['uploadMaxHumanFilesize']; ?>)">
<!-- img style="padding: 1em;" id="contacts_details_photo" alt="Profile picture" src="photo.php?id=<?php echo $_['id']; ?>" / -->
<progress id="contacts_details_photo_progress" style="display:none;" value="0" max="100">0 %</progress>
@ -45,16 +48,29 @@ $id = isset($_['id']) ? $_['id'] : '';
<dt><label for="fn"><?php echo $l->t('Display name'); ?></label></dt>
<dd class="propertycontainer" data-element="FN">
<select id="fn_select" title="<?php echo $l->t('Format custom, Short name, Full name, Reverse or Reverse with comma'); ?>" style="width:16em;">
</select><a id="edit_name" class="edit" title="<?php echo $l->t('Edit name details'); ?>"></a>
</select><a id="edit_name" class="action edit" title="<?php echo $l->t('Edit name details'); ?>"></a>
</dd>
<dt style="display:none;" id="org_label" data-element="ORG"><label for="org"><?php echo $l->t('Organization'); ?></label></dt>
<dd style="display:none;" class="propertycontainer" id="org_value" data-element="ORG"><input id="org" required="required" name="value[ORG]" type="text" class="contacts_property" style="width:16em;" name="value" value="" placeholder="<?php echo $l->t('Organization'); ?>" /><a class="delete" onclick="$(this).tipsy('hide');Contacts.UI.Card.deleteProperty(this, 'single');" title="<?php echo $l->t('Delete'); ?>"></a></dd>
<dd style="display:none;" class="propertycontainer" id="org_value" data-element="ORG"><input id="org" required="required" name="value[ORG]" type="text" class="contacts_property" style="width:16em;" name="value" value="" placeholder="<?php echo $l->t('Organization'); ?>" /><a class="action delete" onclick="$(this).tipsy('hide');Contacts.UI.Card.deleteProperty(this, 'single');" title="<?php echo $l->t('Delete'); ?>"></a></dd>
<dt style="display:none;" id="nickname_label" data-element="NICKNAME"><label for="nickname"><?php echo $l->t('Nickname'); ?></label></dt>
<dd style="display:none;" class="propertycontainer" id="nickname_value" data-element="NICKNAME"><input id="nickname" required="required" name="value[NICKNAME]" type="text" class="contacts_property" style="width:16em;" name="value" value="" placeholder="<?php echo $l->t('Enter nickname'); ?>" /><a class="delete" onclick="$(this).tipsy('hide');Contacts.UI.Card.deleteProperty(this, 'single');" title="<?php echo $l->t('Delete'); ?>"></a></dd>
<dd style="display:none;" class="propertycontainer" id="nickname_value" data-element="NICKNAME"><input id="nickname" required="required" name="value[NICKNAME]" type="text" class="contacts_property" style="width:16em;" name="value" value="" placeholder="<?php echo $l->t('Enter nickname'); ?>" /><a class="action delete" onclick="$(this).tipsy('hide');Contacts.UI.Card.deleteProperty(this, 'single');" title="<?php echo $l->t('Delete'); ?>"></a></dd>
<dt style="display:none;" id="bday_label" data-element="BDAY"><label for="bday"><?php echo $l->t('Birthday'); ?></label></dt>
<dd style="display:none;" class="propertycontainer" id="bday_value" data-element="BDAY"><input id="bday" required="required" name="value" type="text" class="contacts_property" value="" placeholder="<?php echo $l->t('dd-mm-yyyy'); ?>" /><a class="delete" onclick="$(this).tipsy('hide');Contacts.UI.Card.deleteProperty(this, 'single');" title="<?php echo $l->t('Delete'); ?>"></a></dd>
<dd style="display:none;" class="propertycontainer" id="bday_value" data-element="BDAY"><input id="bday" required="required" name="value" type="text" class="contacts_property" value="" placeholder="<?php echo $l->t('dd-mm-yyyy'); ?>" /><a class="action delete" onclick="$(this).tipsy('hide');Contacts.UI.Card.deleteProperty(this, 'single');" title="<?php echo $l->t('Delete'); ?>"></a></dd>
<!-- dt id="categories_label" data-element="CATEGORIES"><label for="categories"><?php echo $l->t('Categories'); ?></label></dt>
<dd class="propertycontainer" id="categories_value" data-element="CATEGORIES">
<select class="contacts_property" multiple="multiple" id="categories" name="value[]">
<?php echo html_select_options($_['categories'], array(), array('combine'=>true)) ?>
</select>
<a class="action edit" onclick="$(this).tipsy('hide');OCCategories.edit();" title="<?php echo $l->t('Edit categories'); ?>"></a>
</dd -->
<dt style="display:none;" id="categories_label" data-element="CATEGORIES"><label for="categories"><?php echo $l->t('Categories'); ?></label></dt>
<dd style="display:none;" class="propertycontainer" id="categories_value" data-element="CATEGORIES"><input id="categories" required="required" name="value[CATEGORIES]" type="text" class="contacts_property" style="width:16em;" name="value" value="" placeholder="<?php echo $l->t('Categories'); ?>" /><a class="action delete" onclick="$(this).tipsy('hide');Contacts.UI.Card.deleteProperty(this, 'single');" title="<?php echo $l->t('Delete'); ?>"></a><a class="action edit" onclick="$(this).tipsy('hide');OCCategories.edit();" title="<?php echo $l->t('Edit categories'); ?>"></a></dd>
</dl>
</fieldset>
<fieldset id="note" class="formfloat propertycontainer contactpart" style="display:none;" data-element="NOTE">
<legend><?php echo $l->t('Note'); ?><a class="action delete" onclick="$(this).tipsy('hide');Contacts.UI.Card.deleteProperty(this, 'single');" title="<?php echo $l->t('Delete'); ?>"></a></legend>
<textarea class="contacts_property note" name="value" cols="60" rows="10"></textarea>
</fieldset>
</form>
</div>
@ -68,8 +84,8 @@ $id = isset($_['id']) ? $_['id'] : '';
<ul id="emaillist" class="propertylist">
<li class="template" style="white-space: nowrap; display: none;" data-element="EMAIL">
<input type="checkbox" class="contacts_property" name="parameters[TYPE][]" value="PREF" title="<?php echo $l->t('Preferred'); ?>" />
<input type="email" required="required" class="nonempty contacts_property" style="width:15em;" name="value" value="" x-moz-errormessage="<?php echo $l->t('Please specify a valid email address.'); ?>" placeholder="<?php echo $l->t('Enter email address'); ?>" /><span class="listactions"><a onclick="Contacts.UI.mailTo(this)" class="mail" title="<?php echo $l->t('Mail to address'); ?>"></a>
<a class="delete" onclick="$(this).tipsy('hide');Contacts.UI.Card.deleteProperty(this, 'list');" title="<?php echo $l->t('Delete email address'); ?>"></a></span></li>
<input type="email" required="required" class="nonempty contacts_property" style="width:15em;" name="value" value="" x-moz-errormessage="<?php echo $l->t('Please specify a valid email address.'); ?>" placeholder="<?php echo $l->t('Enter email address'); ?>" /><span class="listactions"><a onclick="Contacts.UI.mailTo(this)" class="action mail" title="<?php echo $l->t('Mail to address'); ?>"></a>
<a class="action delete" onclick="$(this).tipsy('hide');Contacts.UI.Card.deleteProperty(this, 'list');" title="<?php echo $l->t('Delete email address'); ?>"></a></span></li>
</ul><!-- a id="add_email" class="add" title="<?php echo $l->t('Add email address'); ?>"></a -->
</div> <!-- email addresses-->
@ -84,7 +100,7 @@ $id = isset($_['id']) ? $_['id'] : '';
<select multiple="multiple" name="parameters[TYPE][]">
<?php echo html_select_options($_['phone_types'], array()) ?>
</select>
<a class="delete" onclick="$(this).tipsy('hide');Contacts.UI.Card.deleteProperty(this, 'list');" title="<?php echo $l->t('Delete phone number'); ?>"></a></li>
<a class="action delete" onclick="$(this).tipsy('hide');Contacts.UI.Card.deleteProperty(this, 'list');" title="<?php echo $l->t('Delete phone number'); ?>"></a></li>
</ul><!-- a id="add_phone" class="add" title="<?php echo $l->t('Add phone number'); ?>"></a -->
</div> <!-- Phone numbers -->
@ -96,7 +112,7 @@ $id = isset($_['id']) ? $_['id'] : '';
<dl class="addresscard template" style="display: none;" data-element="ADR"><dt>
<input class="adr contacts_property" name="value" type="hidden" value="" />
<input type="hidden" class="adr_type contacts_property" name="parameters[TYPE][]" value="" />
<span class="adr_type_label"></span><a class="globe" style="float:right;" onclick="$(this).tipsy('hide');Contacts.UI.searchOSM(this);" title="<?php echo $l->t('View on map'); ?>"></a><a class="edit" style="float:right;" onclick="$(this).tipsy('hide');Contacts.UI.Card.editAddress(this, false);" title="<?php echo $l->t('Edit address details'); ?>"></a><a class="delete" style="float:right;" onclick="$(this).tipsy('hide');Contacts.UI.Card.deleteProperty(this, 'list');" title="Delete address"></a>
<span class="adr_type_label"></span><a class="action globe" style="float:right;" onclick="$(this).tipsy('hide');Contacts.UI.searchOSM(this);" title="<?php echo $l->t('View on map'); ?>"></a><a class="action edit" style="float:right;" onclick="$(this).tipsy('hide');Contacts.UI.Card.editAddress(this, false);" title="<?php echo $l->t('Edit address details'); ?>"></a><a class="action delete" style="float:right;" onclick="$(this).tipsy('hide');Contacts.UI.Card.deleteProperty(this, 'list');" title="Delete address"></a>
</dt><dd><ul class="addresslist"></ul></dd></dl>
</fieldset>

View File

@ -2,8 +2,9 @@
$id = $_['id'];
$wattr = isset($_['width'])?'width="'.$_['width'].'"':'';
$hattr = isset($_['height'])?'height="'.$_['height'].'"':'';
$rand = isset($_['refresh'])?'&'.rand().'='.rand():'';
?>
<img class="loading" id="contacts_details_photo" <?php echo $wattr; ?> <?php echo $hattr; ?> src="<?php echo OC_Helper::linkToAbsolute('contacts', 'photo.php'); ?>?id=<?php echo $id; ?>&amp;refresh=<?php echo rand(); ?>" />
<img class="loading" id="contacts_details_photo" <?php echo $wattr; ?> <?php echo $hattr; ?> src="<?php echo OC_Helper::linkToAbsolute('contacts', 'photo.php'); ?>?id=<?php echo $id.$rand; ?>" />
<progress id="contacts_details_photo_progress" style="display:none;" value="0" max="100">0 %</progress>

View File

@ -1,96 +0,0 @@
<?php if(array_key_exists('FN',$_['details'])): ?>
<?php echo $this->inc('part.property.FN', array('property' => $_['details']['FN'][0])); ?>
<?php echo $this->inc('part.property.N', array('property' => $_['details']['N'][0])); ?>
<a href="export.php?contactid=<?php echo $_['id']; ?>"><img class="svg action" id="contacts_downloadcard" src="<?php echo image_path('', 'actions/download.svg'); ?>" title="<?php echo $l->t('Download contact');?>" /></a>
<img class="svg action" id="contacts_deletecard" src="<?php echo image_path('', 'actions/delete.svg'); ?>" title="<?php echo $l->t('Delete contact');?>" />
<?php if(isset($_['details']['PHOTO'])): // Emails first ?>
<img id="contacts_details_photo" src="photo.php?id=<?php echo $_['id']; ?>">
<?php endif; ?>
<ul id="contacts_details_list">
<?php if(isset($_['details']['BDAY'])): // Emails first ?>
<?php echo $this->inc('part.property', array('property' => $_['details']['BDAY'][0])); ?>
<?php endif; ?>
<?php if(isset($_['details']['ORG'])): // Emails first ?>
<?php echo $this->inc('part.property', array('property' => $_['details']['ORG'][0])); ?>
<?php endif; ?>
<?php foreach(array('EMAIL','TEL','ADR') as $type): ?>
<?php if(isset($_['details'][$type])): // Emails first ?>
<?php foreach($_['details'][$type] as $property): ?>
<?php echo $this->inc('part.property',array('property' => $property )); ?>
<?php endforeach; ?>
<?php endif; ?>
<?php endforeach; ?>
<li class="contacts_property_add">
<form id="contacts_addpropertyform">
<input type="hidden" name="id" value="<?php echo $_['id']; ?>">
<p class="contacts_property_name">
<select name="name" size="1">
<?php echo html_select_options($_['property_types'], 'EMAIL') ?>
</select>
<br>
<input id="contacts_addproperty_button" type="submit" value="<?php echo $l->t('Add'); ?>">
</p>
<p class="contacts_property_data" id="contacts_generic">
<input type="text" name="value" value="">
</p>
</form>
<div id="contacts_addcontactsparts" style="display:none;">
<ul class="contacts_property_data" id="contacts_addresspart">
<li>
<label for="adr_type"><?php echo $l->t('Type'); ?></label>
<select id="adr_type" name="parameters[TYPE]" size="1">
<?php echo html_select_options($_['adr_types'], 'HOME') ?>
</select>
</li>
<li>
<label for="adr_pobox"><?php echo $l->t('PO Box'); ?></label>
<input id="adr_pobox" type="text" name="value[0]" value="">
</li>
<li>
<label for="adr_extended"><?php echo $l->t('Extended'); ?></label>
<input id="adr_extended" type="text" name="value[1]" value="">
</li>
<li>
<label for="adr_street"><?php echo $l->t('Street'); ?></label>
<input id="adr_street" type="text" name="value[2]" value="">
</li>
<li>
<label for="adr_city"><?php echo $l->t('City'); ?></label>
<input id="adr_city" type="text" name="value[3]" value="">
</li>
<li>
<label for="adr_region"><?php echo $l->t('Region'); ?></label>
<input id="adr_region" type="text" name="value[4]" value="">
</li>
<li>
<label for="adr_zipcode"><?php echo $l->t('Zipcode'); ?></label>
<input id="adr_zipcode" type="text" name="value[5]" value="">
</li>
<li>
<label for="adr_country"><?php echo $l->t('Country'); ?></label>
<input id="adr_country" type="text" name="value[6]" value="">
</li>
</ul>
<p class="contacts_property_data" id="contacts_phonepart">
<input type="text" name="value" value="">
<select name="parameters[TYPE][]" multiple="multiple" data-placeholder="<?php echo $l->t('Type') ?>">
<?php echo html_select_options($_['phone_types'], 'CELL') ?>
</select>
</p>
<p class="contacts_property_data" id="contacts_generic">
<input type="text" name="value" value="">
</p>
</div>
</li>
</ul>
<?php endif; ?>
<script language="Javascript">
/* Re-tipsify ;-)*/
$('#contacts_deletecard').tipsy({gravity: 'ne'});
$('#contacts_downloadcard').tipsy({gravity: 'ne'});
$('.button').tipsy();
</script>

View File

@ -0,0 +1,16 @@
<?php
$categories = isset($_['categories'])?$_['categories']:array();
?>
<div id="edit_categories_dialog" title="<?php echo $l->t('Edit categories'); ?>">
<!-- ?php print_r($types); ? -->
<form method="post" id="categoryform">
<div class="scrollarea">
<ul id="categorylist">
<?php foreach($categories as $category) { ?>
<li><input type="checkbox" name="categories[]" value="<?php echo $category; ?>" /><?php echo $category; ?></li>
<?php } ?>
</ul>
</div>
<div class="bottombuttons"><input type="text" id="category_addinput" name="category" /><button id="category_addbutton" disabled="disabled"><?php echo $l->t('Add'); ?></button></div>
</form>
</div>

View File

@ -1,3 +0,0 @@
<div id="messagebox">
<div id="messagebox_msg"></div>
</di>

View File

@ -1,8 +0,0 @@
<div id="firstrun">
You have no contacts in your list.
<div id="selections">
<input type="button" value="Import contacts" onclick="Contacts.UI.Addressbooks.import()" />
<input type="button" value="Add contact" onclick="Contacts.UI.Card.editNew()" />
<input type="button" value="Edit addressbooks" onclick="Contacts.UI.Addressbooks.overview()" />
</div>
</div>

View File

@ -1,9 +0,0 @@
<p id="contacts_details_name" class="contacts_property" data-checksum="<?php echo $_['property']['checksum']; ?>">
<?php echo htmlspecialchars($_['property']['value']); ?>
<span style="display:none;" data-use="edit"><img class="svg action" src="<?php echo image_path('', 'actions/rename.svg'); ?>" /></span>
</p>
<?php if (!isset($_['details'])): ?>
<script>
$('#leftcontent li.active a').text('<?php echo htmlspecialchars($_['property']['value']); ?>');
</script>
<?php endif ?>

View File

@ -1,4 +0,0 @@
<p id="contacts_details_name_n" class="contacts_property" data-checksum="<?php echo $_['property']['checksum']; ?>">
(<?php echo $_['property']['value'][0].', '.$_['property']['value'][1].' '.$_['property']['value'][2]; ?>)
<span style="display:none;" data-use="edit"><img class="svg action" src="<?php echo image_path('', 'actions/rename.svg'); ?>" /></span>
</p>

View File

@ -1,86 +0,0 @@
<li class="contacts_property" data-checksum="<?php echo $_['property']['checksum']; ?>">
<?php if($_['property']['name'] == 'BDAY'): ?>
<p class="contacts_property_name"><?php echo $l->t('Birthday'); ?></p>
<p class="contacts_property_data">
<?php echo $l->l('date',new DateTime($_['property']['value'])); ?>
<span style="display:none;" data-use="delete"><img class="svg action" src="<?php echo image_path('', 'actions/delete.svg'); ?>" /></span>
</p>
<?php elseif($_['property']['name'] == 'ORG'): ?>
<p class="contacts_property_name"><?php echo $l->t('Organization'); ?></p>
<p class="contacts_property_data">
<?php echo htmlspecialchars($_['property']['value']); ?>
<span style="display:none;" data-use="edit"><img class="svg action" src="<?php echo image_path('', 'actions/rename.svg'); ?>" /></span>
<span style="display:none;" data-use="delete"><img class="svg action" src="<?php echo image_path('', 'actions/delete.svg'); ?>" /></span>
</p>
<?php elseif($_['property']['name'] == 'EMAIL'): ?>
<p class="contacts_property_name"><?php echo $l->t('Email'); ?></p>
<p class="contacts_property_data">
<?php echo htmlspecialchars($_['property']['value']); ?>
<span style="display:none;" data-use="edit"><img class="svg action" src="<?php echo image_path('', 'actions/rename.svg'); ?>" /></span>
<span style="display:none;" data-use="delete"><img class="svg action" src="<?php echo image_path('', 'actions/delete.svg'); ?>" /></span>
</p>
<?php elseif($_['property']['name'] == 'TEL'): ?>
<p class="contacts_property_name"><?php echo (isset($_['property']['parameters']['PREF']) && $_['property']['parameters']['PREF']) ? $l->t('Preferred').' ' : '' ?><?php echo $l->t('Phone'); ?></p>
<p class="contacts_property_data">
<?php echo htmlspecialchars($_['property']['value']); ?>
<?php if(isset($_['property']['parameters']['TYPE']) && !empty($_['property']['parameters']['TYPE'])): ?>
<?php
foreach($_['property']['parameters']['TYPE'] as $type) {
if (isset($_['phone_types'][strtoupper($type)])){
$types[]=$_['phone_types'][strtoupper($type)];
}
else{
$types[]=$l->t(ucwords(strtolower($type)));
}
}
$label = join(' ', $types);
?>
(<?php echo $label; ?>)
<?php endif; ?>
<span style="display:none;" data-use="edit"><img class="svg action" src="<?php echo image_path('', 'actions/rename.svg'); ?>" /></span>
<span style="display:none;" data-use="delete"><img class="svg action" src="<?php echo image_path('', 'actions/delete.svg'); ?>" /></span>
</p>
<?php elseif($_['property']['name'] == 'ADR'): ?>
<p class="contacts_property_name">
<?php echo $l->t('Address'); ?>
<?php if(isset($_['property']['parameters']['TYPE'])): ?>
<br>
<?php
$type = $_['property']['parameters']['TYPE'];
if (isset($_['adr_types'][strtoupper($type)])){
$label=$_['adr_types'][strtoupper($type)];
}
else{
$label=$l->t(ucwords(strtolower($type)));
}
?>
(<?php echo $label; ?>)
<?php endif; ?>
</p>
<p class="contacts_property_data">
<?php if(!empty($_['property']['value'][0])): ?>
<?php echo htmlspecialchars($_['property']['value'][0]); ?><br>
<?php endif; ?>
<?php if(!empty($_['property']['value'][1])): ?>
<?php echo htmlspecialchars($_['property']['value'][1]); ?><br>
<?php endif; ?>
<?php if(!empty($_['property']['value'][2])): ?>
<?php echo htmlspecialchars($_['property']['value'][2]); ?><br>
<?php endif; ?>
<?php if(!empty($_['property']['value'][3])): ?>
<?php echo htmlspecialchars($_['property']['value'][3]); ?><br>
<?php endif; ?>
<?php if(!empty($_['property']['value'][4])): ?>
<?php echo htmlspecialchars($_['property']['value'][4]); ?><br>
<?php endif; ?>
<?php if(!empty($_['property']['value'][5])): ?>
<?php echo htmlspecialchars($_['property']['value'][5]); ?><br>
<?php endif; ?>
<?php if(!empty($_['property']['value'][6])): ?>
<?php echo htmlspecialchars($_['property']['value'][6]); ?>
<?php endif; ?>
<span style="display:none;" data-use="edit"><img class="svg action" src="<?php echo image_path('', 'actions/rename.svg'); ?>" /></span>
<span style="display:none;" data-use="delete"><img class="svg action" src="<?php echo image_path('', 'actions/delete.svg'); ?>" /></span>
</p>
<?php endif; ?>
</li>

View File

@ -1,91 +0,0 @@
<form id="contacts_setpropertyform">
<input type="hidden" name="checksum" value="<?php echo $_['property']['checksum']; ?>">
<input type="hidden" name="id" value="<?php echo $_['id']; ?>">
<?php if($_['property']['name']=='N'): ?>
<p class="contacts_property_name">
<dl class="contacts_property_data form">
<dt><label for="n1"><?php echo $l->t('Given name'); ?></label></dt>
<dd><input id="n1" type="text" name="value[1]" value="<?php echo htmlspecialchars($_['property']['value'][1]); ?>"></dd>
<dt><label for="n0"><?php echo $l->t('Family name'); ?></dt>
<dd><input id="n0" type="text" name="value[0]" value="<?php echo htmlspecialchars($_['property']['value'][0]); ?>"></dd>
<dt><label for="n2"><?php echo $l->t('Additional names'); ?></dt>
<dd><input id="n2" type="text" name="value[2]" value="<?php echo htmlspecialchars($_['property']['value'][2]); ?>">
<input id="n3" type="hidden" name="value[3]" value="<?php echo htmlspecialchars($_['property']['value'][3]); ?>">
<input id="n4" type="hidden" name="value[4]" value="<?php echo htmlspecialchars($_['property']['value'][4]); ?>">
</dd>
</dl>
</p>
<?php elseif($_['property']['name']=='FN'): ?>
<p class="contacts_property_data"><input id="fn" type="text" name="value" value="<?php echo htmlspecialchars($_['property']['value']); ?>"></p>
<?php elseif($_['property']['name']=='ADR'): ?>
<p class="contacts_property_name"><label for="adr_pobox"><?php echo $l->t('Address'); ?></label></p>
<dl class="contacts_property_data form" id="contacts_addresspart">
<dt>
<label class="label" for="adr_type"><?php echo $l->t('Type'); ?></label>
</dt>
<dd>
<select id="adr_type" name="parameters[TYPE]" size="1">
<?php echo html_select_options($_['adr_types'], strtoupper($_['property']['parameters']['TYPE'])) ?>
</select>
</dd>
<dt>
<label for="adr_pobox"><?php echo $l->t('PO Box'); ?></label>
</dt>
<dd>
<input id="adr_pobox" type="text" name="value[0]" value="<?php echo htmlspecialchars($_['property']['value'][0]) ?>">
</dd>
<!-- dt>
<label for="adr_extended"><?php echo $l->t('Extended'); ?></label>
</dt>
<dd>
<input style="width: 7em;" id="adr_extended" type="text" name="value[1]" value="<?php echo htmlspecialchars($_['property']['value'][1]) ?>">
</dd -->
<dt>
<label for="adr_street"><?php echo $l->t('Street'); ?></label>
</dt>
<dd>
<input style="width: 12em;" id="adr_street" type="text" name="value[2]" value="<?php echo htmlspecialchars($_['property']['value'][2]) ?>">
<label for="adr_extended"><?php echo $l->t('Extended'); ?></label><input style="width: 7em;" id="adr_extended" type="text" name="value[1]" value="<?php echo htmlspecialchars($_['property']['value'][1]) ?>">
</dd>
<dt>
<label for="adr_city"><?php echo $l->t('City'); ?></label>
</dt>
<dd>
<input style="width: 12em;" id="adr_city" type="text" name="value[3]" value="<?php echo htmlspecialchars($_['property']['value'][3]) ?>">
<label for="adr_zipcode"><?php echo $l->t('Zipcode'); ?></label>
<input style="width: 5em;" id="adr_zipcode" type="text" name="value[5]" value="<?php echo htmlspecialchars($_['property']['value'][5]) ?>">
</dd>
<dt>
<label for="adr_region"><?php echo $l->t('Region'); ?></label>
</dt>
<dd>
<input id="adr_region" type="text" name="value[4]" value="<?php echo htmlspecialchars($_['property']['value'][4]) ?>">
</dd>
<!-- dt>
<label for="adr_zipcode"><?php echo $l->t('Zipcode'); ?></label>
</dt>
<dd>
<input style="width: 7em;" id="adr_zipcode" type="text" name="value[5]" value="<?php echo htmlspecialchars($_['property']['value'][5]) ?>">
</dd -->
<dt>
<label for="adr_country"><?php echo $l->t('Country'); ?></label>
</dt>
<dd>
<input style="width: 25em;" id="adr_country" type="text" name="value[6]" value="<?php echo htmlspecialchars($_['property']['value'][6]) ?>">
</dd>
</dl>
<?php elseif($_['property']['name']=='TEL'): ?>
<p class="contacts_property_name"><label for="tel"><?php echo $l->t('Phone'); ?></label></p>
<p class="contacts_property_data"><input id="tel" type="phone" name="value" value="<?php echo htmlspecialchars($_['property']['value']) ?>">
<select id="tel_type<?php echo $_['property']['checksum'] ?>" name="parameters[TYPE][]" multiple="multiple" data-placeholder="<?php echo $l->t('Type') ?>">
<?php echo html_select_options($_['phone_types'], isset($_['property']['parameters']['TYPE'])?$_['property']['parameters']['TYPE']:array()) ?>
</select></p>
<?php elseif($_['property']['name']=='EMAIL'): ?>
<p class="contacts_property_name"><label for="email"><?php echo $l->t('Email'); ?></label></p>
<p class="contacts_property_data"><input id="email" type="text" name="value" value="<?php echo htmlspecialchars($_['property']['value']); ?>"></p>
<?php elseif($_['property']['name']=='ORG'): ?>
<p class="contacts_property_name"><label for="org"><?php echo $l->t('Organization'); ?></label></p>
<p class="contacts_property_data"><input id="org" type="text" name="value" value="<?php echo htmlspecialchars($_['property']['value']); ?>"></p>
<?php endif; ?>
<input id="contacts_setproperty_button" type="submit" value="<?php echo $l->t('Update'); ?>">
</form>

View File

@ -1,7 +1,12 @@
<form id="mediaform">
<form id="contacts">
<fieldset class="personalblock">
<strong><?php echo $l->t('Contacts'); ?></strong><br />
<?php echo $l->t('CardDAV syncing address:'); ?>
<?php echo OC_Helper::linkToAbsolute('contacts', 'carddav.php'); ?><br />
<?php echo $l->t('CardDAV syncing addresses:'); ?>
<dl>
<dt><?php echo $l->t('Primary address (Kontact et al)'); ?></dt>
<dd><code><?php echo OC_Helper::linkToAbsolute('contacts', 'carddav.php'); ?>/</code></dd>
<dt><?php echo $l->t('iOS/OS X'); ?></dt>
<dd><code><?php echo OC_Helper::linkToAbsolute('contacts', 'carddav.php'); ?>/principals/<?php echo OC_User::getUser(); ?></code>/</dd>
</dl>
</fieldset>
</form>

25
apps/external/ajax/setsites.php vendored Normal file
View File

@ -0,0 +1,25 @@
<?php
/**
* Copyright (c) 2011, Frank Karlitschek <karlitschek@kde.org>
* This file is licensed under the Affero General Public License version 3 or later.
* See the COPYING-README file.
*/
require_once('../../../lib/base.php');
OC_Util::checkAdminUser();
$sites = array();
for ($i = 0; $i < sizeof($_POST['site_name']); $i++) {
if (!empty($_POST['site_name'][$i]) && !empty($_POST['site_url'][$i])) {
array_push($sites, array($_POST['site_name'][$i], $_POST['site_url'][$i]));
}
}
if (sizeof($sites) == 0)
OC_Appconfig::deleteKey('external', 'sites');
else
OC_Appconfig::setValue('external', 'sites', json_encode($sites));
echo 'true';
?>

View File

@ -1,24 +0,0 @@
<?php
/**
* Copyright (c) 2011, Frank Karlitschek <karlitschek@kde.org>
* This file is licensed under the Affero General Public License version 3 or later.
* See the COPYING-README file.
*/
require_once('../../../lib/base.php');
OC_Util::checkAdminUser();
if(isset($_POST['s1name'])) OC_Appconfig::setValue( 'external','site1name', $_POST['s1name'] );
if(isset($_POST['s1url'])) OC_Appconfig::setValue( 'external','site1url', $_POST['s1url'] );
if(isset($_POST['s2name'])) OC_Appconfig::setValue( 'external','site2name', $_POST['s2name'] );
if(isset($_POST['s2url'])) OC_Appconfig::setValue( 'external','site2url', $_POST['s2url'] );
if(isset($_POST['s3name'])) OC_Appconfig::setValue( 'external','site3name', $_POST['s3name'] );
if(isset($_POST['s3url'])) OC_Appconfig::setValue( 'external','site3url', $_POST['s3url'] );
if(isset($_POST['s4name'])) OC_Appconfig::setValue( 'external','site4name', $_POST['s4name'] );
if(isset($_POST['s4url'])) OC_Appconfig::setValue( 'external','site4url', $_POST['s4url'] );
if(isset($_POST['s5name'])) OC_Appconfig::setValue( 'external','site5name', $_POST['s5name'] );
if(isset($_POST['s5url'])) OC_Appconfig::setValue( 'external','site5url', $_POST['s5url'] );
echo 'true';
?>

View File

@ -1,37 +1,35 @@
<?php
/**
* ownCloud - External plugin
*
* @author Frank Karlitschek
* @copyright 2011 Frank Karlitschek karlitschek@kde.org
*
* 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 - External plugin
*
* @author Frank Karlitschek
* @copyright 2011 Frank Karlitschek karlitschek@kde.org
*
* 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/>.
*
*/
OC_APP::registerAdmin('external','settings');
OC::$CLASSPATH['OC_External'] = 'apps/external/lib/external.php';
OC_Util::addStyle( 'external', 'style');
OC_App::register( array( 'order' => 70, 'id' => 'external', 'name' => 'External' ));
OC_APP::registerAdmin('external', 'settings');
if(OC_Appconfig::getValue( "external","site1name", '' )<>'') OC_App::addNavigationEntry( array( 'id' => 'external_index1', 'order' => 80, 'href' => OC_Helper::linkTo( 'external', 'index.php' ).'?id=1', 'icon' => OC_Helper::imagePath( 'external', 'external.png' ), 'name' => OC_Appconfig::getValue( "external","site1name", '' )));
if(OC_Appconfig::getValue( "external","site2name", '' )<>'') OC_App::addNavigationEntry( array( 'id' => 'external_index2', 'order' => 80, 'href' => OC_Helper::linkTo( 'external', 'index.php' ).'?id=2', 'icon' => OC_Helper::imagePath( 'external', 'external.png' ), 'name' => OC_Appconfig::getValue( "external","site2name", '' )));
if(OC_Appconfig::getValue( "external","site3name", '' )<>'') OC_App::addNavigationEntry( array( 'id' => 'external_index3', 'order' => 80, 'href' => OC_Helper::linkTo( 'external', 'index.php' ).'?id=3', 'icon' => OC_Helper::imagePath( 'external', 'external.png' ), 'name' => OC_Appconfig::getValue( "external","site3name", '' )));
if(OC_Appconfig::getValue( "external","site4name", '' )<>'') OC_App::addNavigationEntry( array( 'id' => 'external_index4', 'order' => 80, 'href' => OC_Helper::linkTo( 'external', 'index.php' ).'?id=4', 'icon' => OC_Helper::imagePath( 'external', 'external.png' ), 'name' => OC_Appconfig::getValue( "external","site4name", '' )));
if(OC_Appconfig::getValue( "external","site5name", '' )<>'') OC_App::addNavigationEntry( array( 'id' => 'external_index5', 'order' => 80, 'href' => OC_Helper::linkTo( 'external', 'index.php' ).'?id=5', 'icon' => OC_Helper::imagePath( 'external', 'external.png' ), 'name' => OC_Appconfig::getValue( "external","site5name", '' )));
OC_App::register(array('order' => 70, 'id' => 'external', 'name' => 'External'));
$sites = OC_External::getSites();
for ($i = 0; $i < sizeof($sites); $i++) {
OC_App::addNavigationEntry(
array('id' => 'external_index' . ($i + 1), 'order' => 80 + $i, 'href' => OC_Helper::linkTo('external', 'index.php') . '?id=' . ($i + 1), 'icon' => OC_Helper::imagePath('external', 'external.png'), 'name' => $sites[$i][0]));
}

14
apps/external/css/style.css vendored Normal file
View File

@ -0,0 +1,14 @@
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- /
/* vim: set shiftwidth=4 tabstop=8 autoindent cindent expandtab: */
.site_url {
width: 250px;
}
.delete_button {
display: none;
}
.external_sites {
width: 450px;
}

View File

@ -1,42 +1,43 @@
<?php
/**
* ownCloud - External plugin
*
* @author Frank Karlitschek
* @copyright 2011 Frank Karlitschek karlitschek@kde.org
*
* 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 - External plugin
*
* @author Frank Karlitschek
* @copyright 2011 Frank Karlitschek karlitschek@kde.org
*
* 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/>.
*
*/
require_once('../../lib/base.php');
require_once('lib/external.php');
OC_Util::checkLoggedIn();
if(isset($_GET['id'])){
if (isset($_GET['id'])) {
$id=$_GET['id'];
$id = $_GET['id'];
$id = (int) $id;
$url=OC_Appconfig::getValue( "external","site".$id."url", '' );
OC_App::setActiveNavigationEntry( 'external_index'.$id );
$tmpl = new OC_Template( 'external', 'frame', 'user' );
$tmpl->assign('url',$url);
$tmpl->printPage();
$sites = OC_External::getSites();
if (sizeof($sites) >= $id) {
$url = $sites[$id - 1][1];
OC_App::setActiveNavigationEntry('external_index' . $id);
$tmpl = new OC_Template('external', 'frame', 'user');
$tmpl->assign('url', $url);
$tmpl->printPage();
}
}
?>

View File

@ -1,68 +1,57 @@
$(document).ready(function(){
newSiteHtml = '<li><input type="text" class="site_name" name="site_name[]" value="" placeholder="Name" />\n\
<input type="text" name="site_url[]" class="site_url" value="" placeholder="URL" />\n\
<img class="svg action delete_button" src="'+OC.imagePath("core", "actions/delete") +'" title="Remove site" /></li>';
$('#s1name').blur(function(event){
// Handler functions
function addSiteEventHandler(event) {
event.preventDefault();
var post = $( "#s1name" ).serialize();
$.post( OC.filePath('external','ajax','seturls.php') , post, function(data){ OC.msg.finishedSaving('#s1name .msg', data); });
});
saveSites();
}
$('#s2name').blur(function(event){
function deleteButtonEventHandler(event) {
event.preventDefault();
var post = $( "#s2name" ).serialize();
$.post( OC.filePath('external','ajax','seturls.php') , post, function(data){ OC.msg.finishedSaving('#s2name .msg', data); });
});
$('#s3name').blur(function(event){
$(this).tipsy('hide');
$(this).parent().remove();
saveSites();
}
function saveSites() {
var post = $('#external').serialize();
$.post( OC.filePath('external','ajax','setsites.php') , post, function(data) {
// OC.msg.finishedSaving('#site_name .msg', data);
});
}
function showDeleteButton(event) {
$(this).find('img.delete_button').fadeIn(100);
}
function hideDeleteButton(event) {
$(this).find('img.delete_button').fadeOut(100);
}
// Initialize events
$('input[name^=site_]').change(addSiteEventHandler);
$('img.delete_button').click(deleteButtonEventHandler);
$('img.delete_button').tipsy();
$('#external li').hover(showDeleteButton, hideDeleteButton);
$('#add_external_site').click(function(event) {
event.preventDefault();
var post = $( "#s3name" ).serialize();
$.post( OC.filePath('external','ajax','seturls.php') , post, function(data){ OC.msg.finishedSaving('#s3name .msg', data); });
});
$('#external ul').append(newSiteHtml);
$('#s4name').blur(function(event){
event.preventDefault();
var post = $( "#s4name" ).serialize();
$.post( OC.filePath('external','ajax','seturls.php') , post, function(data){ OC.msg.finishedSaving('#s4name .msg', data); });
$('input.site_url:last').prev('input.site_name').andSelf().change(addSiteEventHandler);
$('img.delete_button').click(deleteButtonEventHandler);
$('img.delete_button:last').tipsy();
$('#external li:last').hover(showDeleteButton, hideDeleteButton);
});
$('#s5name').blur(function(event){
event.preventDefault();
var post = $( "#s5name" ).serialize();
$.post( OC.filePath('external','ajax','seturls.php') , post, function(data){ OC.msg.finishedSaving('#s5name .msg', data); });
});
$('#s1url').blur(function(event){
event.preventDefault();
var post = $( "#s1url" ).serialize();
$.post( OC.filePath('external','ajax','seturls.php') , post, function(data){ OC.msg.finishedSaving('#s1url .msg', data); });
});
$('#s2url').blur(function(event){
event.preventDefault();
var post = $( "#s2url" ).serialize();
$.post( OC.filePath('external','ajax','seturls.php') , post, function(data){ OC.msg.finishedSaving('#s2url .msg', data); });
});
$('#s3url').blur(function(event){
event.preventDefault();
var post = $( "#s3url" ).serialize();
$.post( OC.filePath('external','ajax','seturls.php') , post, function(data){ OC.msg.finishedSaving('#s3url .msg', data); });
});
$('#s4url').blur(function(event){
event.preventDefault();
var post = $( "#s4url" ).serialize();
$.post( OC.filePath('external','ajax','seturls.php') , post, function(data){ OC.msg.finishedSaving('#s4url .msg', data); });
});
$('#s5url').blur(function(event){
event.preventDefault();
var post = $( "#s5url" ).serialize();
$.post( OC.filePath('external','ajax','seturls.php') , post, function(data){ OC.msg.finishedSaving('#s5url .msg', data); });
});
});

36
apps/external/lib/external.php vendored Normal file
View File

@ -0,0 +1,36 @@
<?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/>.
*
*/
class OC_External {
public static function getSites() {
if (($sites = json_decode(OC_Appconfig::getValue("external", "sites", ''))) != NULL) {
return $sites;
}
return array();
}
}
?>

View File

@ -6,17 +6,5 @@ OC_Util::addScript( "external", "admin" );
$tmpl = new OC_Template( 'external', 'settings');
$tmpl->assign('s1name',OC_Appconfig::getValue( "external","site1name", '' ));
$tmpl->assign('s2name',OC_Appconfig::getValue( "external","site2name", '' ));
$tmpl->assign('s3name',OC_Appconfig::getValue( "external","site3name", '' ));
$tmpl->assign('s4name',OC_Appconfig::getValue( "external","site4name", '' ));
$tmpl->assign('s5name',OC_Appconfig::getValue( "external","site5name", '' ));
$tmpl->assign('s1url',OC_Appconfig::getValue( "external","site1url", '' ));
$tmpl->assign('s2url',OC_Appconfig::getValue( "external","site2url", '' ));
$tmpl->assign('s3url',OC_Appconfig::getValue( "external","site3url", '' ));
$tmpl->assign('s4url',OC_Appconfig::getValue( "external","site4url", '' ));
$tmpl->assign('s5url',OC_Appconfig::getValue( "external","site5url", '' ));
return $tmpl->fetchPage();
?>

View File

@ -1,23 +1,21 @@
<form id="external">
<fieldset class="personalblock">
<strong>External Sites</strong><br />
<input type="text" name="s1name" id="s1name" value="<?php echo $_['s1name']; ?>" placeholder="<?php echo $l->t('Name');?>" />
<input type="text" name="s1url" id="s1url" value="<?php echo $_['s1url']; ?>" placeholder="<?php echo $l->t('Url');?>" />
<br />
<input type="text" name="s2name" id="s2name" value="<?php echo $_['s2name']; ?>" placeholder="<?php echo $l->t('Name');?>" />
<input type="text" name="s2url" id="s2url" value="<?php echo $_['s2url']; ?>" placeholder="<?php echo $l->t('Url');?>" />
<br />
<input type="text" name="s3name" id="s3name" value="<?php echo $_['s3name']; ?>" placeholder="<?php echo $l->t('Name');?>" />
<input type="text" name="s3url" id="s3url" value="<?php echo $_['s3url']; ?>" placeholder="<?php echo $l->t('Url');?>" />
<br />
<input type="text" name="s4name" id="s4name" value="<?php echo $_['s4name']; ?>" placeholder="<?php echo $l->t('Name');?>" />
<input type="text" name="s4url" id="s4url" value="<?php echo $_['s4url']; ?>" placeholder="<?php echo $l->t('Url');?>" />
<br />
<input type="text" name="s5name" id="s5name" value="<?php echo $_['s5name']; ?>" placeholder="<?php echo $l->t('Name');?>" />
<input type="text" name="s5url" id="s5url" value="<?php echo $_['s5url']; ?>" placeholder="<?php echo $l->t('Url');?>" />
<br />
<ul class="external_sites">
<?php
$sites = OC_External::getSites();
for($i = 0; $i < sizeof($sites); $i++) {
echo '<li><input type="text" name="site_name[]" class="site_name" value="'.$sites[$i][0].'" placeholder="'.$l->t('Name').'" />
<input type="text" class="site_url" name="site_url[]" value="'.$sites[$i][1].'" placeholder="'.$l->t('URL').'" />
<img class="svg action delete_button" src="'.image_path("", "actions/delete.svg") .'" title="'.$l->t("Remove site").'" />
</li>';
}
?>
<span class="msg"></span>
</ul>
<input type="button" id="add_external_site" value="Add" />
<span class="msg"></span>
</fieldset>
</form>

View File

@ -0,0 +1,18 @@
<?php
/**
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
OC::$CLASSPATH['OC_Archive'] = 'apps/files_archive/lib/archive.php';
foreach(array('ZIP') as $type){
OC::$CLASSPATH['OC_Archive_'.$type] = 'apps/files_archive/lib/'.strtolower($type).'.php';
}
OC::$CLASSPATH['OC_Filestorage_Archive']='apps/files_archive/lib/storage.php';
OC_Hook::connect('OC_Filesystem','get_mountpoint','OC_Filestorage_Archive','autoMount');
OC_Util::addScript( 'files_archive', 'archive' );

View File

@ -0,0 +1,10 @@
<?xml version="1.0"?>
<info>
<id>files_archive</id>
<name>Archive support</name>
<description>Transparent opening of archives</description>
<version>0.1</version>
<licence>AGPL</licence>
<author>Robin Appelman</author>
<require>3</require>
</info>

View File

@ -0,0 +1,15 @@
/**
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
$(document).ready(function() {
if(typeof FileActions!=='undefined'){
FileActions.register('application/zip','Open','',function(filename){
window.location='index.php?dir='+encodeURIComponent($('#dir').val()).replace(/%2F/g, '/')+'/'+encodeURIComponent(filename);
});
FileActions.setDefault('application/zip','Open');
}
});

View File

@ -0,0 +1,99 @@
<?php
/**
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
abstract class OC_Archive{
/**
* open any of the supporeted archive types
* @param string path
* @return OC_Archive
*/
public static function open($path){
$ext=substr($path,strrpos($path,'.'));
switch($ext){
case '.zip':
return new OC_Archive_ZIP($path);
}
}
abstract function __construct($source);
/**
* add an empty folder to the archive
* @param string path
* @return bool
*/
abstract function addFolder($path);
/**
* add a file to the archive
* @param string path
* @param string source either a local file or string data
* @return bool
*/
abstract function addFile($path,$source='');
/**
* rename a file or folder in the archive
* @param string source
* @param string dest
* @return bool
*/
abstract function rename($source,$dest);
/**
* get the uncompressed size of a file in the archive
* @param string path
* @return int
*/
abstract function filesize($path);
/**
* get the last modified time of a file in the archive
* @param string path
* @return int
*/
abstract function mtime($path);
/**
* get the files in a folder
* @param path
* @return array
*/
abstract function getFolder($path);
/**
*get all files in the archive
* @return array
*/
abstract function getFiles();
/**
* get the content of a file
* @param string path
* @return string
*/
abstract function getFile($path);
/**
* extract a single file from the archive
* @param string path
* @param string dest
* @return bool
*/
abstract function extractFile($path,$dest);
/**
* check if a file or folder exists in the archive
* @param string path
* @return bool
*/
abstract function fileExists($path);
/**
* remove a file or folder from the archive
* @param string path
* @return bool
*/
abstract function remove($path);
/**
* get a file handler
* @param string path
* @param string mode
* @return resource
*/
abstract function getStream($path,$mode);
}

View File

@ -0,0 +1,142 @@
<?php
/**
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
class OC_Filestorage_Archive extends OC_Filestorage_Common{
/**
* underlying local storage used for missing functions
* @var OC_Archive
*/
private $archive;
private $path;
private static $mounted=array();
private static $enableAutomount=true;
private static $rootView;
private function stripPath($path){//files should never start with /
if(substr($path,0,1)=='/'){
$path=substr($path,1);
}
return $path;
}
public function __construct($params){
$this->archive=OC_Archive::open($params['archive']);
$this->path=$params['archive'];
}
public function mkdir($path){
$path=$this->stripPath($path);
return $this->archive->addFolder($path);
}
public function rmdir($path){
$path=$this->stripPath($path);
return $this->archive->remove($path.'/');
}
public function opendir($path){
$path=$this->stripPath($path);
$content=$this->archive->getFolder($path);
foreach($content as &$file){
if(substr($file,-1)=='/'){
$file=substr($file,0,-1);
}
}
$id=md5($this->path.$path);
OC_FakeDirStream::$dirs[$id]=$content;
return opendir('fakedir://'.$id);
}
public function stat($path){
$ctime=filectime($this->path);
$path=$this->stripPath($path);
if($path==''){
$stat=stat($this->path);
}else{
if($this->is_dir($path)){
$stat=array('size'=>0);
$stat['mtime']=filemtime($this->path);
}else{
$stat=array();
$stat['mtime']=$this->archive->mtime($path);
$stat['size']=$this->archive->filesize($path);
}
}
$stat['ctime']=$ctime;
return $stat;
}
public function filetype($path){
$path=$this->stripPath($path);
if($path==''){
return 'dir';
}
if(substr($path,-1)=='/'){
return $this->archive->fileExists($path)?'dir':'file';
}else{
return $this->archive->fileExists($path.'/')?'dir':'file';
}
}
public function is_readable($path){
return is_readable($this->path);
}
public function is_writable($path){
return is_writable($this->path);
}
public function file_exists($path){
$path=$this->stripPath($path);
if($path==''){
return file_exists($this->path);
}
return $this->archive->fileExists($path) or $this->archive->fileExists($path.'/');
}
public function unlink($path){
$path=$this->stripPath($path);
return $this->archive->remove($path);
}
public function fopen($path,$mode){
$path=$this->stripPath($path);
return $this->archive->getStream($path,$mode);
}
public function free_space($path){
return 0;
}
public function touch($path, $mtime=null){
if(is_null($mtime)){
$tmpFile=OC_Helper::tmpFile();
$this->archive->extractFile($path,$tmpFile);
$this->archive->addfile($path,$tmpFile);
}else{
return false;//not supported
}
}
/**
* automount paths from file hooks
* @param aray params
*/
public static function autoMount($params){
if(!self::$enableAutomount){
return;
}
$path=$params['path'];
if(!self::$rootView){
self::$rootView=new OC_FilesystemView('');
}
self::$enableAutomount=false;//prevent recursion
$supported=array('zip');
foreach($supported as $type){
$ext='.'.$type.'/';
if(($pos=strpos(strtolower($path),$ext))!==false){
$archive=substr($path,0,$pos+strlen($ext)-1);
if(self::$rootView->file_exists($archive) and array_search($archive,self::$mounted)===false){
$localArchive=self::$rootView->getLocalFile($archive);
OC_Filesystem::mount('OC_Filestorage_Archive',array('archive'=>$localArchive),$archive.'/');
self::$mounted[]=$archive;
}
}
}
self::$enableAutomount=true;
}
}

View File

@ -0,0 +1,182 @@
<?php
/**
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
class OC_Archive_ZIP extends OC_Archive{
/**
* @var ZipArchive zip
*/
private $zip=null;
private $contents=array();
private $success=false;
private $path;
function __construct($source){
$this->path=$source;
$this->zip=new ZipArchive();
if($this->zip->open($source,ZipArchive::CREATE)){
}else{
OC_LOG::write('files_archive','Error while opening archive '.$source,OC_Log::WARN);
}
}
/**
* add an empty folder to the archive
* @param string path
* @return bool
*/
function addFolder($path){
return $this->zip->addEmptyDir($path);
}
/**
* add a file to the archive
* @param string path
* @param string source either a local file or string data
* @return bool
*/
function addFile($path,$source=''){
if(file_exists($source)){
$result=$this->zip->addFile($source,$path);
}else{
$result=$this->zip->addFromString($path,$source);
}
if($result){
$this->zip->close();//close and reopen to save the zip
$this->zip->open($this->path);
}
return $result;
}
/**
* rename a file or folder in the archive
* @param string source
* @param string dest
* @return bool
*/
function rename($source,$dest){
return $this->zip->renameName($source,$dest);
}
/**
* get the uncompressed size of a file in the archive
* @param string path
* @return int
*/
function filesize($path){
$stat=$this->zip->statName($path);
return $stat['size'];
}
/**
* get the last modified time of a file in the archive
* @param string path
* @return int
*/
function mtime($path){
$stat=$this->zip->statName($path);
return $stat['mtime'];
}
/**
* get the files in a folder
* @param path
* @return array
*/
function getFolder($path){
$files=$this->getFiles();
$folderContent=array();
$pathLength=strlen($path);
foreach($files as $file){
if(substr($file,0,$pathLength)==$path and $file!=$path){
if(strrpos(substr($file,0,-1),'/')<=$pathLength){
$folderContent[]=substr($file,$pathLength);
}
}
}
return $folderContent;
}
/**
*get all files in the archive
* @return array
*/
function getFiles(){
if(count($this->contents)){
return $this->contents;
}
$fileCount=$this->zip->numFiles;
$files=array();
for($i=0;$i<$fileCount;$i++){
$files[]=$this->zip->getNameIndex($i);
}
$this->contents=$files;
return $files;
}
/**
* get the content of a file
* @param string path
* @return string
*/
function getFile($path){
return $this->zip->getFromName($path);
}
/**
* extract a single file from the archive
* @param string path
* @param string dest
* @return bool
*/
function extractFile($path,$dest){
$fp = $this->zip->getStream($path);
file_put_contents($dest,$fp);
}
/**
* check if a file or folder exists in the archive
* @param string path
* @return bool
*/
function fileExists($path){
return $this->zip->locateName($path)!==false;
}
/**
* remove a file or folder from the archive
* @param string path
* @return bool
*/
function remove($path){
return $this->zip->deleteName($path);
}
/**
* get a file handler
* @param string path
* @param string mode
* @return resource
*/
function getStream($path,$mode){
if($mode=='r' or $mode=='rb'){
return $this->zip->getStream($path);
}else{//since we cant directly get a writable stream, make a temp copy of the file and put it back in the archive when the stream is closed
if(strrpos($path,'.')!==false){
$ext=substr($path,strrpos($path,'.'));
}else{
$ext='';
}
$tmpFile=OC_Helper::tmpFile($ext);
OC_CloseStreamWrapper::$callBacks[$tmpFile]=array($this,'writeBack');
if($this->fileExists($path)){
$this->extractFile($path,$tmpFile);
}
self::$tempFiles[$tmpFile]=$path;
return fopen('close://'.$tmpFile,$mode);
}
}
private static $tempFiles=array();
/**
* write back temporary files
*/
function writeBack($tmpFile){
if(isset(self::$tempFiles[$tmpFile])){
$this->addFile(self::$tempFiles[$tmpFile],$tmpFile);
unlink($tmpFile);
}
}
}

View File

@ -0,0 +1,97 @@
<?php
/**
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
abstract class Test_Archive extends UnitTestCase {
/**
* @var OC_Archive
*/
protected $instance;
/**
* get the existing test archive
* @return OC_Archive
*/
abstract protected function getExisting();
/**
* get a new archive for write testing
* @return OC_Archive
*/
abstract protected function getNew();
public function testGetFiles(){
$this->instance=$this->getExisting();
$allFiles=$this->instance->getFiles();
$expected=array('lorem.txt','logo-wide.png','dir/','dir/lorem.txt');
$this->assertEqual(4,count($allFiles));
foreach($expected as $file){
$this->assertNotIdentical(false,array_search($file,$allFiles),'cant find '.$file.' in archive');
$this->assertTrue($this->instance->fileExists($file));
}
$this->assertFalse($this->instance->fileExists('non/existing/file'));
$rootContent=$this->instance->getFolder('');
$expected=array('lorem.txt','logo-wide.png','dir/');
$this->assertEqual(3,count($rootContent));
foreach($expected as $file){
$this->assertNotIdentical(false,array_search($file,$rootContent),'cant find '.$file.' in archive');
}
$dirContent=$this->instance->getFolder('dir/');
$expected=array('lorem.txt');
$this->assertEqual(1,count($dirContent));
foreach($expected as $file){
$this->assertNotIdentical(false,array_search($file,$dirContent),'cant find '.$file.' in archive');
}
}
public function testContent(){
$this->instance=$this->getExisting();
$dir=OC::$SERVERROOT.'/apps/files_archive/tests/data';
$textFile=$dir.'/lorem.txt';
$this->assertEqual(file_get_contents($textFile),$this->instance->getFile('lorem.txt'));
$tmpFile=OC_Helper::tmpFile('.txt');
$this->instance->extractFile('lorem.txt',$tmpFile);
$this->assertEqual(file_get_contents($textFile),file_get_contents($tmpFile));
}
public function testWrite(){
$dir=OC::$SERVERROOT.'/apps/files_archive/tests/data';
$textFile=$dir.'/lorem.txt';
$this->instance=$this->getNew();
$this->assertEqual(0,count($this->instance->getFiles()));
$this->instance->addFile('lorem.txt',$textFile);
$this->assertEqual(1,count($this->instance->getFiles()));
$this->assertTrue($this->instance->fileExists('lorem.txt'));
$this->assertEqual(file_get_contents($textFile),$this->instance->getFile('lorem.txt'));
$this->instance->addFile('lorem.txt','foobar');
$this->assertEqual('foobar',$this->instance->getFile('lorem.txt'));
}
public function testReadStream(){
$dir=OC::$SERVERROOT.'/apps/files_archive/tests/data';
$this->instance=$this->getExisting();
$fh=$this->instance->getStream('lorem.txt','r');
$this->assertTrue($fh);
$content=fread($fh,$this->instance->filesize('lorem.txt'));
fclose($fh);
$this->assertEqual(file_get_contents($dir.'/lorem.txt'),$content);
}
public function testWriteStream(){
$dir=OC::$SERVERROOT.'/apps/files_archive/tests/data';
$this->instance=$this->getNew();
$fh=$this->instance->getStream('lorem.txt','w');
$source=fopen($dir.'/lorem.txt','r');
OC_Helper::streamCopy($source,$fh);
fclose($source);
fclose($fh);
$this->assertTrue($this->instance->fileExists('lorem.txt'));
$this->assertEqual(file_get_contents($dir.'/lorem.txt'),$this->instance->getFile('lorem.txt'));
}
}

View File

@ -0,0 +1,25 @@
<?php
/**
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
class Test_Filestorage_Archive_Zip extends Test_FileStorage {
/**
* @var string tmpDir
*/
private $tmpFile;
public function setUp(){
$this->tmpFile=OC_Helper::tmpFile('.zip');
$this->instance=new OC_Filestorage_Archive(array('archive'=>$this->tmpFile));
}
public function tearDown(){
unlink($this->tmpFile);
}
}
?>

View File

@ -0,0 +1,20 @@
<?php
/**
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
require_once('archive.php');
class Test_Archive_ZIP extends Test_Archive{
protected function getExisting(){
$dir=OC::$SERVERROOT.'/apps/files_archive/tests/data';
return new OC_Archive_ZIP($dir.'/data.zip');
}
protected function getNew(){
return new OC_Archive_ZIP(OC_Helper::tmpFile('.zip'));
}
}

View File

@ -26,7 +26,7 @@
// - Crypt/decrypt button in the userinterface
// - Setting if crypto should be on by default
// - Add a setting "Don´t encrypt files larger than xx because of performance reasons"
// - Transparent decrypt/encrpt in filesystem.php. Autodetect if a file is encrypted (.encrypted extensio)
// - Transparent decrypt/encrypt in filesystem.php. Autodetect if a file is encrypted (.encrypted extension)
// - Don't use a password directly as encryption key. but a key which is stored on the server and encrypted with the user password. -> password change faster
// - IMPORTANT! Check if the block lenght of the encrypted data stays the same

View File

@ -0,0 +1,11 @@
<?php
/**
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
OC::$CLASSPATH['OC_Filestorage_FTP']='apps/files_remote/lib/ftp.php';
OC::$CLASSPATH['OC_Filestorage_DAV']='apps/files_remote/lib/webdav.php';
OC::$CLASSPATH['OC_Filestorage_Google']='apps/files_remote/lib/google.php';

View File

@ -0,0 +1,10 @@
<?xml version="1.0"?>
<info>
<id>files_remote</id>
<name>Remote storage support</name>
<description>Mount remote storage sources</description>
<version>0.1</version>
<licence>AGPL</licence>
<author>Robin Appelman</author>
<require>3</require>
</info>

View File

@ -0,0 +1,157 @@
<?php
/**
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
class OC_FileStorage_FTP extends OC_Filestorage_Common{
private $password;
private $user;
private $host;
private $secure;
private $root;
private static $tempFiles=array();
public function __construct($params){
$this->host=$params['host'];
$this->user=$params['user'];
$this->password=$params['password'];
$this->secure=isset($params['secure'])?(bool)$params['secure']:false;
$this->root=isset($params['root'])?$params['root']:'/';
if(substr($this->root,0,1)!='/'){
$this->root='/'.$this->root;
}
//create the root folder if necesary
mkdir($this->constructUrl(''));
}
/**
* construct the ftp url
* @param string path
* @return string
*/
public function constructUrl($path){
$url='ftp';
if($this->secure){
$url.='s';
}
$url.='://'.$this->user.':'.$this->password.'@'.$this->host.$this->root.$path;
return $url;
}
public function mkdir($path){
return mkdir($this->constructUrl($path));
}
public function rmdir($path){
if($this->file_exists($path)){
$succes=rmdir($this->constructUrl($path));
clearstatcache();
return $succes;
}else{
return false;
}
}
public function opendir($path){
return opendir($this->constructUrl($path));
}
public function filetype($path){
return filetype($this->constructUrl($path));
}
public function is_readable($path){
return true;//not properly supported
}
public function is_writable($path){
return true;//not properly supported
}
public function file_exists($path){
return file_exists($this->constructUrl($path));
}
public function unlink($path){
$succes=unlink($this->constructUrl($path));
clearstatcache();
return $succes;
}
public function fopen($path,$mode){
switch($mode){
case 'r':
case 'rb':
case 'w':
case 'wb':
case 'a':
case 'ab':
//these are supported by the wrapper
$context = stream_context_create(array('ftp' => array('overwrite' => true)));
return fopen($this->constructUrl($path),$mode,false,$context);
case 'r+':
case 'w+':
case 'wb+':
case 'a+':
case 'x':
case 'x+':
case 'c':
case 'c+':
//emulate these
if(strrpos($path,'.')!==false){
$ext=substr($path,strrpos($path,'.'));
}else{
$ext='';
}
$tmpFile=OC_Helper::tmpFile($ext);
OC_CloseStreamWrapper::$callBacks[$tmpFile]=array($this,'writeBack');
if($this->file_exists($path)){
$this->getFile($path,$tmpFile);
}
self::$tempFiles[$tmpFile]=$path;
return fopen('close://'.$tmpFile,$mode);
}
}
public function writeBack($tmpFile){
if(isset(self::$tempFiles[$tmpFile])){
$this->uploadFile($tmpFile,self::$tempFiles[$tmpFile]);
unlink($tmpFile);
}
}
public function free_space($path){
return 0;
}
public function touch($path,$mtime=null){
if(is_null($mtime)){
$fh=$this->fopen($path,'a');
fwrite($fh,'');
fclose($fh);
}else{
return false;//not supported
}
}
public function getFile($path,$target){
return copy($this->constructUrl($path),$target);
}
public function uploadFile($path,$target){
return copy($path,$this->constructUrl($target));
}
public function rename($path1,$path2){
return rename($this->constructUrl($path1),$this->constructUrl($path2));
}
public function stat($path){
return stat($this->constructUrl($path));
}
}

View File

@ -24,14 +24,12 @@ require_once 'common.inc.php';
class OC_Filestorage_Google extends OC_Filestorage_Common {
private $datadir;
private $consumer;
private $oauth_token;
private $sig_method;
private $entries;
public function __construct($arguments) {
$this->datadir = $arguments['datadir'];
$consumer_key = isset($arguments['consumer_key']) ? $arguments['consumer_key'] : 'anonymous';
$consumer_secret = isset($arguments['consumer_secret']) ? $arguments['consumer_secret'] : 'anonymous';
$this->consumer = new OAuthConsumer($consumer_key, $consumer_secret);
@ -40,7 +38,7 @@ class OC_Filestorage_Google extends OC_Filestorage_Common {
$this->entries = array();
}
private function sendRequest($feedUri, $http_method, $postData = null) {
private function sendRequest($feedUri, $http_method, $isDownload = false, $postData = null) {
$feedUri = trim($feedUri);
// create an associative array from each key/value url query param pair.
$params = array();
@ -54,30 +52,71 @@ class OC_Filestorage_Google extends OC_Filestorage_Common {
$tempStr .= '&' . urlencode($key) . '=' . urlencode($value);
}
$feedUri = preg_replace('/&/', '?', $tempStr, 1);
$req = OAuthRequest::from_consumer_and_token($this->consumer, $this->oauth_token, $http_method, $feedUri, $params);
$req->sign_request($this->sig_method, $this->consumer, $this->oauth_token);
$auth_header = $req->to_header();
$result = send_signed_request($http_method, $feedUri, array($auth_header, 'Content-Type: application/atom+xml', 'GData-Version: 3.0'), $postData);
// TODO Return false if error is received
if (!$result) {
return false;
$request = OAuthRequest::from_consumer_and_token($this->consumer, $this->oauth_token, $http_method, $feedUri, $params);
$request->sign_request($this->sig_method, $this->consumer, $this->oauth_token);
$auth_header = $request->to_header();
$headers = array($auth_header, 'Content-Type: application/atom+xml', 'GData-Version: 3.0');
$curl = curl_init($feedUri);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_FAILONERROR, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
switch ($http_method) {
case 'GET':
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
break;
case 'POST':
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
break;
case 'PUT':
$headers[] = 'If-Match: *';
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $http_method);
curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
break;
case 'DELETE':
$headers[] = 'If-Match: *';
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $http_method);
break;
default:
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
}
$result = explode('<', $result, 2);
$result = isset($result[1]) ? '<'.$result[1] : $result[0];
if ($isDownload) {
$tmpFile = OC_Helper::tmpFile();
$fp = fopen($tmpFile, 'w');
curl_setopt($curl, CURLOPT_FILE, $fp);
curl_exec($curl);
curl_close($curl);
return $tmpFile;
}
$result = curl_exec($curl);
curl_close($curl);
$dom = new DOMDocument();
$dom->loadXML($result);
return $dom;
}
private function getResource($path) {
if (array_key_exists($path, $this->entries)) {
return $this->entries[$path];
$file = basename($path);
if (array_key_exists($file, $this->entries)) {
return $this->entries[$file];
} else {
$title = basename($path);
$dom = $this->sendRequest('https://docs.google.com/feeds/default/private/full?showfolders=true&title='.$title, 'GET');
// Strip the file extension; file could be a native Google Docs resource
if ($pos = strpos($file, '.')) {
$title = substr($file, 0, $pos);
$dom = $this->sendRequest('https://docs.google.com/feeds/default/private/full?showfolders=true&title='.$title, 'GET');
// Check if request was successful and entry exists
if ($dom && $entry = $dom->getElementsByTagName('entry')->item(0)) {
$this->entries[$file] = $entry;
return $entry;
}
}
$dom = $this->sendRequest('https://docs.google.com/feeds/default/private/full?showfolders=true&title='.$file, 'GET');
// Check if request was successful and entry exists
if ($dom && $entry = $dom->getElementsByTagName('entry')->item(0)) {
$this->entries[$path] = $entry;
$this->entries[$file] = $entry;
return $entry;
}
return false;
@ -86,7 +125,7 @@ class OC_Filestorage_Google extends OC_Filestorage_Common {
private function getExtension($entry) {
$mimetype = $this->getMimeType('', $entry);
switch($mimetype) {
switch ($mimetype) {
case 'httpd/unix-directory':
return '';
case 'application/vnd.oasis.opendocument.text':
@ -158,7 +197,10 @@ class OC_Filestorage_Google extends OC_Filestorage_Common {
$name = $entry->getElementsByTagName('title')->item(0)->nodeValue;
// Google Docs resources don't always include extensions in title
if (!strpos($name, '.')) {
$name .= '.'.$this->getExtension($entry);
$extension = $this->getExtension($entry);
if ($extension != '') {
$name .= '.'.$extension;
}
}
$files[] = $name;
// Cache entry for future use
@ -178,11 +220,15 @@ class OC_Filestorage_Google extends OC_Filestorage_Common {
} else if ($entry = $this->getResource($path)) {
// NOTE: Native resources don't have a file size
$stat['size'] = $entry->getElementsByTagNameNS('http://schemas.google.com/g/2005', 'quotaBytesUsed')->item(0)->nodeValue;
$stat['atime'] = strtotime($entry->getElementsByTagNameNS('http://schemas.google.com/g/2005', 'lastViewed')->item(0)->nodeValue);
// if (isset($atime = $entry->getElementsByTagNameNS('http://schemas.google.com/g/2005', 'lastViewed')->item(0)->nodeValue))
// $stat['atime'] = strtotime($entry->getElementsByTagNameNS('http://schemas.google.com/g/2005', 'lastViewed')->item(0)->nodeValue);
$stat['mtime'] = strtotime($entry->getElementsByTagName('updated')->item(0)->nodeValue);
$stat['ctime'] = strtotime($entry->getElementsByTagName('published')->item(0)->nodeValue);
}
return $stat;
if (isset($stat)) {
return $stat;
}
return false;
}
public function filetype($path) {
@ -278,14 +324,36 @@ class OC_Filestorage_Google extends OC_Filestorage_Common {
public function fopen($path, $mode) {
if ($entry = $this->getResource($path)) {
$extension = $this->getExtension($path);
$downloadUri = $entry->getElementsByTagName('content')->item(0)->getAttribute('src');
// TODO Non-native documents don't need these additional parameters
$downloadUri .= '&exportFormat='.$extension.'&format='.$extension;
switch ($mode) {
case 'r':
case 'rb':
$extension = $this->getExtension($entry);
$downloadUri = $entry->getElementsByTagName('content')->item(0)->getAttribute('src');
// TODO Non-native documents don't need these additional parameters
$downloadUri .= '&exportFormat='.$extension.'&format='.$extension;
$tmpFile = $this->sendRequest($downloadUri, 'GET', true);
return fopen($tmpFile, 'r');
case 'w':
case 'wb':
case 'a':
case 'ab':
case 'r+':
case 'w+':
case 'wb+':
case 'a+':
case 'x':
case 'x+':
case 'c':
case 'c+':
// TODO Edit documents
}
}
return false;
}
public function getMimeType($path, $entry = null) {
// Entry can be passed, because extension is required for opendir and the entry can't be cached without the extension
if ($entry == null) {
if ($path == '' || $path == '/') {
return 'httpd/unix-directory';
@ -297,7 +365,7 @@ class OC_Filestorage_Google extends OC_Filestorage_Common {
$mimetype = $entry->getElementsByTagName('content')->item(0)->getAttribute('type');
// Native Google Docs resources often default to text/html, but it may be more useful to default to a corresponding ODF mimetype
// Collections get reported as application/atom+xml, make sure it actually is a folder and fix the mimetype
if ($mimetype == 'text/html' || $mimetype == 'application/atom+xml') {
if ($mimetype == 'text/html' || $mimetype == 'application/atom+xml;type=feed') {
$categories = $entry->getElementsByTagName('category');
foreach ($categories as $category) {
if ($category->getAttribute('scheme') == 'http://schemas.google.com/g/2005#kind') {
@ -334,8 +402,8 @@ class OC_Filestorage_Google extends OC_Filestorage_Common {
return false;
}
public function search($query) {
public function touch($path, $mtime = null) {
}
}

View File

@ -0,0 +1,293 @@
<?php
/**
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
class OC_FileStorage_DAV extends OC_Filestorage_Common{
private $password;
private $user;
private $host;
private $secure;
private $root;
/**
* @var Sabre_DAV_Client
*/
private $client;
private static $tempFiles=array();
public function __construct($params){
$this->host=$params['host'];
$this->user=$params['user'];
$this->password=$params['password'];
$this->secure=isset($params['secure'])?(bool)$params['secure']:false;
$this->root=isset($params['root'])?$params['root']:'/';
if(substr($this->root,0,1)!='/'){
$this->root='/'.$this->root;
}
if(substr($this->root,-1,1)!='/'){
$this->root.='/';
}
$settings = array(
'baseUri' => $this->createBaseUri(),
'userName' => $this->user,
'password' => $this->password,
);
$this->client = new Sabre_DAV_Client($settings);
//create the root folder if necesary
$this->mkdir('');
}
private function createBaseUri(){
$baseUri='http';
if($this->secure){
$baseUri.'s';
}
$baseUri.='://'.$this->host.$this->root;
return $baseUri;
}
public function mkdir($path){
$path=$this->cleanPath($path);
return $this->simpleResponse('MKCOL',$path,null,201);
}
public function rmdir($path){
$path=$this->cleanPath($path);
return $this->simpleResponse('DELETE',$path,null,204);
}
public function opendir($path){
$path=$this->cleanPath($path);
try{
$response=$this->client->propfind($path, array(),1);
$stripLength=strlen($this->root)+strlen($path);
$id=md5('webdav'.$this->root.$path);
OC_FakeDirStream::$dirs[$id]=array();
foreach($response as $file=>$data){
//strip root and path
$file=trim(substr($file,$stripLength));
$file=trim($file,'/');
if($file){
OC_FakeDirStream::$dirs[$id][]=$file;
}
}
return opendir('fakedir://'.$id);
}catch(Exception $e){
return false;
}
}
public function filetype($path){
$path=$this->cleanPath($path);
try{
$response=$this->client->propfind($path, array('{DAV:}resourcetype'));
$responseType=$response["{DAV:}resourcetype"]->resourceType;
return (count($responseType)>0 and $responseType[0]=="{DAV:}collection")?'dir':'file';
}catch(Exception $e){
return false;
}
}
public function is_readable($path){
return true;//not properly supported
}
public function is_writable($path){
return true;//not properly supported
}
public function file_exists($path){
$path=$this->cleanPath($path);
try{
$response=$this->client->propfind($path, array('{DAV:}resourcetype'));
return true;//no 404 exception
}catch(Exception $e){
return false;
}
}
public function unlink($path){
return $this->simpleResponse('DELETE',$path,null,204);
}
public function fopen($path,$mode){
$path=$this->cleanPath($path);
switch($mode){
case 'r':
case 'rb':
//straight up curl instead of sabredav here, sabredav put's the entire get result in memory
$curl = curl_init();
$fp = fopen('php://temp', 'r+');
curl_setopt($curl,CURLOPT_USERPWD,$this->user.':'.$this->password);
curl_setopt($curl, CURLOPT_URL, $this->createBaseUri().$path);
curl_setopt($curl, CURLOPT_FILE, $fp);
curl_exec ($curl);
curl_close ($curl);
rewind($fp);
return $fp;
case 'w':
case 'wb':
case 'a':
case 'ab':
case 'r+':
case 'w+':
case 'wb+':
case 'a+':
case 'x':
case 'x+':
case 'c':
case 'c+':
//emulate these
if(strrpos($path,'.')!==false){
$ext=substr($path,strrpos($path,'.'));
}else{
$ext='';
}
$tmpFile=OC_Helper::tmpFile($ext);
OC_CloseStreamWrapper::$callBacks[$tmpFile]=array($this,'writeBack');
if($this->file_exists($path)){
$this->getFile($path,$tmpFile);
}
self::$tempFiles[$tmpFile]=$path;
return fopen('close://'.$tmpFile,$mode);
}
}
public function writeBack($tmpFile){
if(isset(self::$tempFiles[$tmpFile])){
$this->uploadFile($tmpFile,self::$tempFiles[$tmpFile]);
unlink($tmpFile);
}
}
public function free_space($path){
$path=$this->cleanPath($path);
try{
$response=$this->client->propfind($path, array('{DAV:}quota-available-bytes'));
if(isset($response['{DAV:}quota-available-bytes'])){
return (int)$response['{DAV:}quota-available-bytes'];
}else{
return 0;
}
}catch(Exception $e){
return 0;
}
}
public function touch($path,$mtime=null){
if(is_null($mtime)){
$mtime=time();
}
$path=$this->cleanPath($path);
$this->client->proppatch($path, array('{DAV:}lastmodified' => $mtime,));
}
public function getFile($path,$target){
$source=$this->fopen($path,'r');
file_put_contents($target,$source);
}
public function uploadFile($path,$target){
$source=fopen($path,'r');
$curl = curl_init();
curl_setopt($curl,CURLOPT_USERPWD,$this->user.':'.$this->password);
curl_setopt($curl, CURLOPT_URL, $this->createBaseUri().$target);
curl_setopt($curl, CURLOPT_BINARYTRANSFER, true);
curl_setopt($curl, CURLOPT_INFILE, $source); // file pointer
curl_setopt($curl, CURLOPT_INFILESIZE, filesize($path));
curl_setopt($curl, CURLOPT_PUT, true);
curl_exec ($curl);
curl_close ($curl);
}
public function rename($path1,$path2){
$path1=$this->cleanPath($path1);
$path2=$this->root.$this->cleanPath($path2);
try{
$response=$this->client->request('MOVE',$path1,null,array('Destination'=>$path2));
return true;
}catch(Exception $e){
echo $e;
echo 'fail';
var_dump($response);
return false;
}
}
public function copy($path1,$path2){
$path1=$this->cleanPath($path1);
$path2=$this->root.$this->cleanPath($path2);
try{
$response=$this->client->request('COPY',$path1,null,array('Destination'=>$path2));
return true;
}catch(Exception $e){
echo $e;
echo 'fail';
var_dump($response);
return false;
}
}
public function stat($path){
$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();
}
}catch(Exception $e){
return array();
}
}
public function getMimeType($path){
$path=$this->cleanPath($path);
try{
$response=$this->client->propfind($path, array('{DAV:}getcontenttype','{DAV:}resourcetype'));
$responseType=$response["{DAV:}resourcetype"]->resourceType;
$type=(count($responseType)>0 and $responseType[0]=="{DAV:}collection")?'dir':'file';
if($type=='dir'){
return 'httpd/unix-directory';
}elseif(isset($response['{DAV:}getcontenttype'])){
return $response['{DAV:}getcontenttype'];
}else{
return false;
}
}catch(Exception $e){
return false;
}
}
private function cleanPath($path){
if(substr($path,0,1)=='/'){
return substr($path,1);
}else{
return $path;
}
}
private function simpleResponse($method,$path,$body,$expected){
$path=$this->cleanPath($path);
try{
$response=$this->client->request($method,$path,$body);
return $response['statusCode']==$expected;
}catch(Exception $e){
return false;
}
}
}

View File

@ -0,0 +1,22 @@
<?php
return array(
'ftp'=>array(
'host'=>'localhost',
'user'=>'test',
'password'=>'test',
'root'=>'/test',
),
'webdav'=>array(
'host'=>'localhost',
'user'=>'test',
'password'=>'test',
'root'=>'/owncloud/files/webdav.php',
),
'google'=>array(
'consumer_key'=>'anonymous',
'consumer_secret'=>'anonymous',
'token'=>'test',
'token_secret'=>'test',
'root'=>'/google',
)
);

View File

@ -0,0 +1,23 @@
<?php
/**
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
class Test_Filestorage_FTP extends Test_FileStorage {
private $config;
private $id;
public function setUp(){
$id=uniqid();
$this->config=include('apps/files_remote/tests/config.php');
$this->config['ftp']['root'].='/'.$id;//make sure we have an new empty folder to work in
$this->instance=new OC_Filestorage_FTP($this->config['ftp']);
}
public function tearDown(){
OC_Helper::rmdirr($this->instance->constructUrl(''));
}
}

View File

@ -0,0 +1,38 @@
<?php
/**
* ownCloud
*
* @author Michael Gapczynski
* @copyright 2012 Michael Gapczynski mtgap@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 Test_Filestorage_Google extends Test_FileStorage {
private $config;
private $id;
public function setUp(){
$id=uniqid();
$this->config=include('apps/files_remote/tests/config.php');
$this->config['google']['root'].='/'.$id;//make sure we have an new empty folder to work in
$this->instance=new OC_Filestorage_Google($this->config['google']);
}
public function tearDown(){
$this->instance->rmdir('/');
}
}

View File

@ -0,0 +1,23 @@
<?php
/**
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
class Test_Filestorage_DAV extends Test_FileStorage {
private $config;
private $id;
public function setUp(){
$id=uniqid();
$this->config=include('apps/files_remote/tests/config.php');
$this->config['webdav']['root'].='/'.$id;//make sure we have an new empty folder to work in
$this->instance=new OC_Filestorage_DAV($this->config['webdav']);
}
public function tearDown(){
$this->instance->rmdir('/');
}
}

View File

@ -28,7 +28,7 @@ require_once('../../../lib/base.php');
OC_JSON::checkLoggedIn();
// Get paramteres
$filecontents = htmlspecialchars_decode($_POST['filecontents']);
$filecontents = $_POST['filecontents'];
$path = isset($_POST['path']) ? $_POST['path'] : '';
$mtime = isset($_POST['mtime']) ? $_POST['mtime'] : '';

View File

@ -5,7 +5,7 @@
left: 12.5em;
}
#editorwrapper{
position: absoloute;
position: absolute;
height: 0;
width: 0;
top: 41px;

View File

@ -11,37 +11,43 @@ function getFileExtension(file){
function setSyntaxMode(ext){
// Loads the syntax mode files and tells the editor
var filetype = new Array();
// Todo finish these
filetype["h"] = "c_cpp";
filetype["c"] = "c_cpp";
filetype["clj"] = "clojure";
filetype["coffee"] = "coffee"; // coffescript can be compiled to javascript
filetype["coldfusion"] = "cfc";
filetype["cpp"] = "c_cpp";
filetype["cs"] = "csharp";
// add file extensions like this: filetype["extension"] = "filetype":
filetype["h"] = "c_cpp";
filetype["c"] = "c_cpp";
filetype["clj"] = "clojure";
filetype["coffee"] = "coffee"; // coffescript can be compiled to javascript
filetype["coldfusion"] = "cfc";
filetype["cpp"] = "c_cpp";
filetype["cs"] = "csharp";
filetype["css"] = "css";
filetype["groovy"] = "groovy";
filetype["haxe"] = "hx";
filetype["groovy"] = "groovy";
filetype["haxe"] = "hx";
filetype["html"] = "html";
filetype["java"] = "java";
filetype["java"] = "java";
filetype["js"] = "javascript";
filetype["json"] = "json";
filetype["latex"] = "latex";
filetype["lua"] = "lua";
filetype["markdown"] = "markdown"; // also: .md .markdown .mdown .mdwn
filetype["ml"] = "ocaml";
filetype["mli"] = "ocaml";
filetype["json"] = "json";
filetype["latex"] = "latex";
filetype["ly"] = "latex";
filetype["ily"] = "latex";
filetype["lua"] = "lua";
filetype["markdown"] = "markdown";
filetype["md"] = "markdown";
filetype["mdown"] = "markdown";
filetype["mdwn"] = "markdown";
filetype["mkd"] = "markdown";
filetype["ml"] = "ocaml";
filetype["mli"] = "ocaml";
filetype["pl"] = "perl";
filetype["php"] = "php";
filetype["powershell"] = "ps1";
filetype["py"] = "python";
filetype["rb"] = "ruby";
filetype["scad"] = "scad"; // seems to be something like 3d model files printed with e.g. reprap
filetype["scala"] = "scala";
filetype["scss"] = "scss"; // "sassy css"
filetype["sql"] = "sql";
filetype["svg"] = "svg";
filetype["textile"] = "textile"; // related to markdown
filetype["scad"] = "scad"; // seems to be something like 3d model files printed with e.g. reprap
filetype["scala"] = "scala";
filetype["scss"] = "scss"; // "sassy css"
filetype["sql"] = "sql";
filetype["svg"] = "svg";
filetype["textile"] = "textile"; // related to markdown
filetype["xml"] = "xml";
if(filetype[ext]!=null){
@ -142,7 +148,7 @@ function doFileSave(){
// Show saving spinner
$("#editor_save").die('click',doFileSave);
$('#save_result').remove();
$('#editor_save').text(t('files_texteditor','Saving...'));//after('<img id="saving_icon" src="'+OC.filePath('core','img','loading.gif')+'"></img>');
$('#editor_save').text(t('files_texteditor','Saving...'));
// Get the data
var filecontents = window.aceEditor.getSession().getValue();
// Send the data
@ -192,6 +198,7 @@ function showFileEditor(dir,filename){
$('#editor').attr('data-filename', filename);
window.aceEditor = ace.edit("editor");
aceEditor.setShowPrintMargin(false);
aceEditor.getSession().setUseWrapMode(true);
if(result.data.write=='false'){
aceEditor.setReadOnly(true);
}

View File

@ -21,6 +21,7 @@
*
*/
header('Content-type: text/html; charset=UTF-8') ;
require_once('../../../lib/base.php');
OC_JSON::checkLoggedIn();
@ -41,35 +42,28 @@ function handleRemove($name) {
function handleGetThumbnails($albumname) {
OC_Response::enableCaching(3600 * 24); // 24 hour
error_log(htmlentities($albumname));
$thumbnail = OC::$CONFIG_DATADIRECTORY.'/../gallery/'.urldecode($albumname).'.png';
header('Content-Type: '.OC_Image::getMimeTypeForFile($thumbnail));
OC_Response::sendFile($thumbnail);
}
function handleGalleryScanning() {
OC_Gallery_Scanner::cleanup();
OC_JSON::success(array('albums' => OC_Gallery_Scanner::scan('/')));
OC_DB::beginTransaction();
set_time_limit(0);
OC_Gallery_Album::cleanup();
$eventSource = new OC_EventSource();
OC_Gallery_Scanner::scan($eventSource);
$eventSource->close();
OC_DB::commit();
}
function handleFilescan($cleanup) {
if ($cleanup) OC_Gallery_Album::cleanup();
$root = OC_Preferences::getValue(OC_User::getUser(), 'gallery', 'root', '').'/';
$pathlist = OC_Gallery_Scanner::find_paths($root);
$pathlist = OC_Gallery_Scanner::find_paths();
sort($pathlist);
OC_JSON::success(array('paths' => $pathlist));
}
function handlePartialCreate($path) {
if (empty($path)) OC_JSON::error(array('cause' => 'No path specified'));
if (!OC_Filesystem::is_dir($path)) OC_JSON::error(array('cause' => 'Invalid path given'));
$album = OC_Gallery_Album::find(OC_User::getUser(), null, $path);
$albums = array();
OC_Gallery_Scanner::scanDir($path, $albums);
OC_JSON::success(array('album_details' => $albums));
}
function handleStoreSettings($root, $order) {
if (!OC_Filesystem::file_exists($root)) {
OC_JSON::error(array('cause' => 'No such file or directory'));
@ -81,13 +75,84 @@ function handleStoreSettings($root, $order) {
}
$current_root = OC_Preferences::getValue(OC_User::getUser(),'gallery', 'root', '/');
$root = trim(rtrim($root, '/'));
$root = trim($root);
$root = rtrim($root, '/').'/';
$rescan = $current_root==$root?'no':'yes';
OC_Preferences::setValue(OC_User::getUser(), 'gallery', 'root', $root);
OC_Preferences::setValue(OC_User::getUser(), 'gallery', 'order', $order);
OC_JSON::success(array('rescan' => $rescan));
}
function handleGetGallery($path) {
$a = array();
$root = OC_Preferences::getValue(OC_User::getUser(),'gallery', 'root', '/');
$path = utf8_decode(rtrim($root.$path,'/'));
if($path == '') $path = '/';
$pathLen = strlen($path);
$result = OC_Gallery_Album::find(OC_User::getUser(), null, $path);
$album_details = $result->fetchRow();
$result = OC_Gallery_Album::find(OC_User::getUser(), null, null, $path);
while ($r = $result->fetchRow()) {
$album_name = $r['album_name'];
$size=OC_Gallery_Album::getAlbumSize($r['album_id']);
// this is a fallback mechanism and seems expensive
if ($size == 0) $size = OC_Gallery_Album::getIntermediateGallerySize($r['album_path']);
$a[] = array('name' => utf8_encode($album_name), 'numOfItems' => min($size, 10),'path'=>substr($r['album_path'], $pathLen));
}
$result = OC_Gallery_Photo::find($album_details['album_id']);
$p = array();
while ($r = $result->fetchRow()) {
$p[] = utf8_encode($r['file_path']);
}
$r = OC_Gallery_Sharing::getEntryByAlbumId($album_details['album_id']);
$shared = false;
$recursive = false;
$token = '';
if ($row = $r->fetchRow()) {
$shared = true;
$recursive = ($row['recursive'] == 1)? true : false;
$token = $row['token'];
}
OC_JSON::success(array('albums'=>$a, 'photos'=>$p, 'shared' => $shared, 'recursive' => $recursive, 'token' => $token));
}
function handleShare($path, $share, $recursive) {
$recursive = $recursive == 'true' ? 1 : 0;
$owner = OC_User::getUser();
$r = OC_Gallery_Album::find($owner, null, $path);
if ($row = $r->fetchRow()) {
$albumId = $row['album_id'];
} else {
OC_JSON::error(array('cause' => 'Couldn\'t find requested gallery'));
exit;
}
if ($share == false) {
OC_Gallery_Sharing::remove($albumId);
OC_JSON::success(array('sharing' => false));
} else { // share, yeah \o/
$r = OC_Gallery_Sharing::getEntryByAlbumId($albumId);
if (($row = $r->fetchRow())) { // update entry
OC_Gallery_Sharing::updateSharingByToken($row['token'], $recursive);
OC_JSON::success(array('sharing' => true, 'token' => $row['token'], 'recursive' => $recursive == 1 ? true : false ));
} else { // and new sharing entry
$date = new DateTime();
$token = md5($owner . $date->getTimestamp());
OC_Gallery_Sharing::addShared($token, intval($albumId), $recursive);
OC_JSON::success(array('sharing' => true, 'token' => $token, 'recursive' => $recursive == 1 ? true : false ));
}
}
}
if ($_GET['operation']) {
switch($_GET['operation']) {
case 'rename':
@ -104,15 +169,15 @@ if ($_GET['operation']) {
case 'scan':
handleGalleryScanning();
break;
case 'filescan':
handleFilescan($_GET['cleanup']);
break;
case 'partial_create':
handlePartialCreate(urldecode($_GET['path']));
break;
case 'store_settings':
handleStoreSettings($_GET['root'], $_GET['order']);
break;
case 'get_gallery':
handleGetGallery($_GET['path']);
break;
case 'share':
handleShare($_GET['path'], $_GET['share'] == 'true' ? true : false, $_GET['recursive']);
break;
default:
OC_JSON::error(array('cause' => 'Unknown operation'));
}

View File

@ -1,41 +0,0 @@
<?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/>.
*
*/
require_once('../../../lib/base.php');
OC_JSON::checkLoggedIn();
OC_JSON::checkAppEnabled('gallery');
$a = array();
$result = OC_Gallery_Album::find(OC_User::getUser());
while ($r = $result->fetchRow()) {
$album_name = $r['album_name'];
$tmp_res = OC_Gallery_Photo::find($r['album_id']);
$a[] = array('name' => utf8_encode($album_name), 'numOfItems' => min($tmp_res->numRows(), 10), 'bgPath' => OC::$WEBROOT.'/data/'.OC_User::getUser().'/gallery/'.$album_name.'.png');
}
OC_JSON::success(array('albums'=>$a));
?>

View File

@ -0,0 +1,115 @@
<?php
/**
* ownCloud - gallery application
*
* @author Bartek Przybylski
* @copyright 2012 Bartek Przybylski bartek@alefzero.eu
*
* 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/>.
*
*/
require_once('../../../lib/base.php');
if (!isset($_GET['token']) || !isset($_GET['operation'])) {
OC_JSON::error(array('cause' => 'Not enought arguments'));
exit;
}
$operation = $_GET['operation'];
$token = $_GET['token'];
if (!OC_Gallery_Sharing::isTokenValid($token)) {
OC_JSON::error(array('cause' => 'Given token is not valid'));
exit;
}
function handleGetGallery($token, $path) {
$owner = OC_Gallery_Sharing::getTokenOwner($token);
$apath = OC_Gallery_Sharing::getPath($token);
if ($path == false)
$root = $apath;
else
$root = rtrim($apath,'/').$path;
$r = OC_Gallery_Album::find($owner, null, $root);
$albums = array();
$photos = array();
$albumId = -1;
if ($row = $r->fetchRow()) {
$albumId = $row['album_id'];
}
if ($albumId != -1) {
if (OC_Gallery_Sharing::isRecursive($token)) {
$r = OC_Gallery_Album::find($owner, null, null, $root);
while ($row = $r->fetchRow())
$albums[] = $row['album_name'];
}
$r = OC_Gallery_Photo::find($albumId);
while ($row = $r->fetchRow())
$photos[] = $row['file_path'];
}
OC_JSON::success(array('albums' => $albums, 'photos' => $photos));
}
function handleGetThumbnail($token, $imgpath) {
$owner = OC_Gallery_Sharing::getTokenOwner($token);
$image = OC_Gallery_Photo::getThumbnail($imgpath, $owner);
if ($image) {
OC_Response::enableCaching(3600 * 24); // 24 hour
$image->show();
}
}
function handleGetAlbumThumbnail($token, $albumname)
{
$owner = OC_Gallery_Sharing::getTokenOwner($token);
$file = OC_Config::getValue("datadirectory").'/'. $owner .'/gallery/'.$albumname.'.png';
$image = new OC_Image($file);
if ($image->valid()) {
$image->centerCrop();
$image->resize(200);
$image->fixOrientation();
OC_Response::enableCaching(3600 * 24); // 24 hour
$image->show();
}
}
function handleGetPhoto($token, $photo) {
$owner = OC_Gallery_Sharing::getTokenOwner($token);
$file = OC_Config::getValue( "datadirectory", OC::$SERVERROOT."/data" ).'/'.$owner.'/files'.urldecode($photo);
header('Content-Type: '.OC_Image::getMimeTypeForFile($file));
OC_Response::sendFile($file);
}
switch ($operation) {
case 'get_gallery':
handleGetGallery($token, isset($_GET['path'])? $_GET['path'] : false);
break;
case 'get_thumbnail':
handleGetThumbnail($token, urldecode($_GET['img']));
break;
case 'get_album_thumbnail':
handleGetAlbumThumbnail($token, urldecode($_GET['albumname']));
break;
case 'get_photo':
handleGetPhoto($token, urldecode($_GET['photo']));
break;
}

View File

@ -24,6 +24,7 @@
OC::$CLASSPATH['OC_Gallery_Album'] = 'apps/gallery/lib/album.php';
OC::$CLASSPATH['OC_Gallery_Photo'] = 'apps/gallery/lib/photo.php';
OC::$CLASSPATH['OC_Gallery_Scanner'] = 'apps/gallery/lib/scanner.php';
OC::$CLASSPATH['OC_Gallery_Sharing'] = 'apps/gallery/lib/sharing.php';
OC::$CLASSPATH['OC_Gallery_Hooks_Handlers'] = 'apps/gallery/lib/hooks_handlers.php';
$l = new OC_L10N('gallery');

View File

@ -11,9 +11,9 @@
<name>album_id</name>
<type>integer</type>
<default>0</default>
<notnull>true</notnull>
<autoincrement>1</autoincrement>
<length>4</length>
<notnull>true</notnull>
<autoincrement>1</autoincrement>
<length>4</length>
</field>
<field>
<name>uid_owner</name>
@ -27,12 +27,18 @@
<notnull>true</notnull>
<length>100</length>
</field>
<field>
<name>album_path</name>
<type>text</type>
<notnull>true</notnull>
<length>100</length>
</field>
<field>
<name>album_path</name>
<type>text</type>
<notnull>true</notnull>
<length>100</length>
</field>
<field>
<name>parent_path</name>
<type>text</type>
<notnull>true</notnull>
<length>100</length>
</field>
</declaration>
</table>
<table>
@ -42,16 +48,16 @@
<name>photo_id</name>
<type>integer</type>
<default>0</default>
<notnull>true</notnull>
<autoincrement>1</autoincrement>
<length>4</length>
<notnull>true</notnull>
<autoincrement>1</autoincrement>
<length>4</length>
</field>
<field>
<name>album_id</name>
<type>integer</type>
<default>0</default>
<notnull>true</notnull>
<length>4</length>
<notnull>true</notnull>
<length>4</length>
</field>
<field>
<name>file_path</name>
@ -61,4 +67,28 @@
</field>
</declaration>
</table>
<table>
<name>*dbprefix*gallery_sharing</name>
<declaration>
<field>
<name>token</name>
<type>text</type>
<notnull>true</notnull>
<length>64</length>
</field>
<field>
<name>gallery_id</name>
<type>integer</type>
<default>0</default>
<notnull>true</notnull>
<length>4</length>
</field>
<field>
<name>recursive</name>
<type>integer</type>
<notnull>true</notnull>
<length>1</length>
</field>
</declaration>
</table>
</database>

View File

@ -2,7 +2,7 @@
<info>
<id>gallery</id>
<name>Gallery</name>
<version>0.3</version>
<version>0.4</version>
<licence>AGPL</licence>
<author>Bartek Przybylski</author>
<require>2</require>

View File

@ -0,0 +1,8 @@
body { background-color: #eee; margin: 0; padding: 0;}
#gallery_list { height: 100%; width: 80%; background-color: white; margin: 0 auto; box-shadow: 0 0 8px #888; }
div.gallery_box { width: 200px; position:relative; text-align: center; border: 0; display: inline-block; margin: 5pt; vertical-align: top; padding: 5px 5px 5px 5px; position: relative; cursor: pointer; -webkit-transition: color 0.5s ease-in-out; -o-transition: color 0.5s ease-in-out; -moz-transition: color 0.5s ease-in-out;color: #BBB;}
div.gallery_box:hover { color: black; }
div.gallery_box h1 {font-size: 17px; font-weight: normal;}
div#breadcrumb { border: 0; width: 70%; margin: 0 auto; padding: 25px 0; font-family: Verdana; text-align: center;}
span.breadcrumbelement { margin: 10px; margin-right: 0; cursor: pointer;}
span.inside { background-image: url('../img/breadcrumb.png'); padding-left: 20px; background-position: left; background-repeat: no-repeat;}

View File

@ -1,13 +1,14 @@
div#gallery_list { margin: 4.5em 2em 0 2em; }
div#gallery_list.leftcontent { padding-top: 15pt; margin: 0; position: absolute; bottom:0px; text-align: center; overflow: auto; }
div.gallery_album_box { width: 200px; position:relative; text-align: center; border: 0; display: inline-block; margin: 5pt; vertical-align: top; padding: 5px 5px 5px 5px; position: relative; -webkit-transition: color 0.5s ease-in-out; -o-transition: color 0.5s ease-in-out; -moz-transition: color 0.5s ease-in-out;color: #BBB;}
div.gallery_album_box h1 { font-size: 9pt; font-family: Verdana; }
div.gallery_album_decoration { width: 200px; position: absolute; border: 0; height: 20px; top: 5px; text-align:right; vertical-align:middle; background-color: #eee; opacity: 0; -webkit-transition: opacity 0.5s ease-in-out; -moz-transition: opacity 0.5s ease-in-out; -o-transition: opacity 0.5s ease-in-out; border-bottom-right-radius: 7px; border-bottom-left-radius: 7px; -moz-border-radius-bottomright: 7px; -moz-border-radius-bottomleft:7px;}
div.gallery_album_box:hover { color: black; }
div.gallery_album_box:hover div.gallery_album_decoration { opacity: 0.7;}
div.gallery_box { width: 200px; position:relative; text-align: center; border: 0; display: inline-block; margin: 5pt; vertical-align: top; padding: 5px 5px 5px 5px; position: relative; -webkit-transition: color 0.5s ease-in-out; -o-transition: color 0.5s ease-in-out; -moz-transition: color 0.5s ease-in-out;color: #BBB;}
div.album {border: 1px solid #e0e0e0; border-radius: 7px;}
div.gallery_box h1 { font-size: 9pt; font-family: Verdana; }
div.gallery_album_decoration { width: 200px; position: absolute; border: 0; height: 20px; top: 5px; text-align:right; vertical-align:middle; background-color: #eee; opacity: 0; -webkit-transition: opacity 0.5s ease-in-out; -moz-transition: opacity 0.5s ease-in-out; -o-transition: opacity 0.5s ease-in-out; }
div.gallery_box:hover { color: black; }
div.gallery_box:hover div.gallery_album_decoration { opacity: 0.7;}
div.gallery_album_decoration a {padding: 0 4pt; cursor: pointer;}
div.gallery_album_cover { width: 200px; height: 200px; border: 0; padding: 0; position:relative;}
div.gallery_album_box:hover div.gallery_control_overlay { opacity:0.5 }
div.gallery_box:hover div.gallery_control_overlay { opacity:0.5 }
div.gallery_control_overlay a { color:white; }
#gallery_images.rightcontent { padding:10px 5px; bottom: 0px; overflow: auto; right:0px}
#scan { position:absolute; right:13.5em; top:0em; }
@ -15,3 +16,5 @@ div.gallery_control_overlay a { color:white; }
#g-settings {position: absolute; left 13.5em; top: 0;}
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}
input[type=button]:disabled { opacity: 0.5 }
.ui-dialog tr {background-color: #eee;}
.ui-dialog input {width: 90%;}

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -4,7 +4,7 @@
* ownCloud - gallery application
*
* @author Bartek Przybylski
* @copyright 2012 Bartek Przybylski bart.p.pl@gmail.com
* @copyright 2012 Bartek Przybylski bartek@alefzero.eu
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
@ -29,9 +29,6 @@ OC_App::setActiveNavigationEntry( 'gallery_index' );
if (!file_exists(OC_Config::getValue("datadirectory").'/'. OC_User::getUser() .'/gallery')) {
mkdir(OC_Config::getValue("datadirectory").'/'. OC_User::getUser() .'/gallery');
$f = fopen(OC_Config::getValue("datadirectory").'/'. OC_User::getUser() .'/gallery/.htaccess', 'w');
fwrite($f, "allow from all");
fclose($f);
}
if (!isset($_GET['view'])) {

View File

@ -1,190 +1,153 @@
var actual_cover;
$(document).ready(function() {
$.getJSON('ajax/getAlbums.php', function(r) {
if (r.status == 'success') {
for (var i in r.albums) {
var a = r.albums[i];
Albums.add(a.name, a.numOfItems);
}
var targetDiv = document.getElementById('gallery_list');
if (targetDiv) {
$(targetDiv).html('');
Albums.display(targetDiv);
$('#gallery_list').sortable({revert:true});
$('.gallery_album_box').each(function(i, e) {
$(e).draggable({connectToSortable: '#gallery_list', handle: '.dummy'})
});
} else {
alert('Error occured: no such layer `gallery_list`');
}
} else {
alert('Error occured: ' + r.message);
}
});
});
var paths = [];
var crumbCount = 0;
$(document).ready(returnToElement(0));
function createNewAlbum() {
var name = prompt("album name", "");
if (name != null && name != "") {
$.getJSON("ajax/createAlbum.php", {album_name: name}, function(r) {
if (r.status == "success") {
var v = '<div class="gallery_album_box"><a href="?view='+r.name+'"><img class="gallery_album_cover"/></a><h1>'+r.name+'</h1></div>';
$('div#gallery_list').append(v);
function returnToElement(num) {
while (crumbCount != num) {
$('#g-album-navigation .last').remove();
$('#g-album-navigation .crumb :last').parent().addClass('last');
crumbCount--;
paths.pop();
}
var p='';
for (var i in paths) p += paths[i]+'/';
$('#g-album-loading').show();
$.getJSON(OC.filePath('gallery','ajax','galleryOp.php'), {operation: 'get_gallery', path: p }, albumClickHandler);
}
function albumClick(title) {
paths.push(title);
crumbCount++;
var p = '';
for (var i in paths) p += paths[i]+'/';
$('#g-album-loading').show();
$.getJSON(OC.filePath('gallery','ajax','galleryOp.php'), {operation: 'get_gallery', path: p }, function(r) {
albumClickHandler(r);
if ($('#g-album-navigation :last-child'))
$('#g-album-navigation :last-child').removeClass('last');
$('#g-album-navigation').append('<div class="crumb last real" style="background-image:url(\''+OC.imagePath('core','breadcrumb')+'\')"><a href=\"javascript:returnToElement('+crumbCount+');\">'+decodeURIComponent(escape(title))+'</a></div>');
});
}
function constructSharingPath() {
return document.location.protocol + '//' + document.location.host + OC.linkTo('gallery', 'sharing.php') + '?token=' + Albums.token;
}
function shareGallery() {
var existing_token = '';
if (Albums.token)
existing_token = constructSharingPath();
var form_fields = [{text: 'Share', name: 'share', type: 'checkbox', value: Albums.shared},
{text: 'Share recursive', name: 'recursive', type: 'checkbox', value: Albums.recursive},
{text: 'Shared gallery address', name: 'address', type: 'text', value: existing_token}];
OC.dialogs.form(form_fields, t('gallery', 'Share gallery'), function(values){
var p = '';
for (var i in paths) p += '/'+paths[i];
if (p == '') p = '/';
$.getJSON(OC.filePath('gallery', 'ajax', 'galleryOp.php'), {operation: 'share', path: p, share: values[0].value, recursive: values[1].value}, function(r) {
if (r.status == 'success') {
Albums.shared = r.sharing;
if (Albums.shared) {
Albums.token = r.token;
Albums.recursive = r.recursive;
} else {
Albums.token = '';
Albums.recursive = false;
}
var actual_addr = '';
if (Albums.token)
actual_addr = constructSharingPath();
$('input[name="address"]').val(actual_addr);
} else {
OC.dialogs.alert(t('gallery', 'Error: ') + r.cause, t('gallery', 'Internal error'));
}
});
}
});
}
function albumClickHandler(r) {
Albums.photos = [];
Albums.albums = [];
if (r.status == 'success') {
for (var i in r.albums) {
var a = r.albums[i];
Albums.add(a.name, a.numOfItems, a.path, a.shared, a.recursive, a.token);
}
for (var i in r.photos) {
Albums.photos.push(r.photos[i]);
}
Albums.shared = r.shared;
if (Albums.shared) {
Albums.recursive = r.recursive;
Albums.token = r.token;
} else {
Albums.recursive = false;
Albums.token = '';
}
var targetDiv = document.getElementById('gallery_list');
if (targetDiv) {
$(targetDiv).html('');
Albums.display(targetDiv);
//$('#gallery_list').sortable({revert:true});
$('.album').each(function(i, el) {
$(el).click(albumClick.bind(null,$(el).attr('title')));
//$(el).draggable({connectToSortable: '#gallery_list', handle: '.dummy'});
});
} else {
OC.dialogs.alert(t('gallery', 'Error: no such layer `gallery_list`'), t('gallery', 'Internal error'));
}
} else {
OC.dialogs.alert(t('gallery', 'Error: ') + r.cause, t('gallery', 'Internal error'));
}
$('#g-album-loading').hide();
}
var albumCounter = 0;
var totalAlbums = 0;
function scanForAlbums(cleanup) {
cleanup = cleanup?true:false;
var albumCounter = 0;
var totalAlbums = 0;
$('#g-scan-button').attr('disabled', 'true');
$.getJSON('ajax/galleryOp.php?operation=filescan', {cleanup: cleanup}, function(r) {
if (r.status == 'success') {
totalAlbums = r.paths.length;
if (totalAlbums == 0) {
$('#notification').text(t('gallery', "No photos found")).fadeIn().slideDown().delay(3000).fadeOut().slideUp();
return;
}
$('#scanprogressbar').progressbar({ value: (albumCounter/totalAlbums)*100 }).fadeIn();
for(var a in r.paths) {
$.getJSON('ajax/galleryOp.php?operation=partial_create&path='+r.paths[a], function(r) {
if (r.status == 'success') {
Albums.add(r.album_details.albumName, r.album_details.imagesCount);
}
albumCounter++;
$('#scanprogressbar').progressbar({ value: (albumCounter/totalAlbums)*100 });
if (albumCounter == totalAlbums) {
$('#scanprogressbar').fadeOut();
var targetDiv = document.getElementById('gallery_list');
if (targetDiv) {
targetDiv.innerHTML = '';
Albums.display(targetDiv);
} else {
alert('Error occured: no such layer `gallery_list`');
}
$('#g-scan-button').attr('disabled', null);
}
});
}
} else {
alert('Error occured: ' + r.message);
}
});
}
function galleryRemove(albumName) {
// a workaround for a flaw in the demo system (http://dev.jqueryui.com/ticket/4375), ignore!
$( "#dialog:ui-dialog" ).dialog( "destroy" );
$('#albumName', $("#dialog-confirm")).text(albumName);
$( '#dialog-confirm' ).dialog({
resizable: false,
height:150,
buttons: [{
text: t('gallery', 'OK'),
click: function() {
$.getJSON("ajax/galleryOp.php", {operation: "remove", name: albumName}, function(r) {
if (r.status == "success") {
$(".gallery_album_box").filterAttr('data-album',albumName).remove();
Albums.remove(albumName);
} else {
alert("Error: " + r.cause);
}
$('#dialog-confirm').dialog('close');
});
}},
{
text: t('gallery', 'Cancel'),
click: function() {
$( this ).dialog( 'close' );
}}]
});
}
function galleryRename(name) {
$('#name', $('#dialog-form')).val(name);
$( "#dialog-form" ).dialog({
height: 140,
width: 350,
modal: false,
buttons: [{
text: t('gallery', 'Change name'),
click: function() {
var newname = $('#name', $('#dialog-form')).val();
if (newname == name || newname == '') {
$(this).dialog("close");
return;
}
if (Albums.find(newname)) {
alert("Album ", newname, " exists");
$(this).dialog("close");
return;
}
$.getJSON('ajax/galleryOp.php', {operation: 'rename', oldname: name, newname: newname}, function(r) {
if (r.status == "success") {
Albums.rename($(".gallery_album_box").filterAttr('data-album',name), newname);
} else {
alert("Error: " + r.cause);
}
$('#dialog-form').dialog('close');
});
}
},
{
text: t('gallery', 'Cancel'),
click: function() {
$( this ).dialog('close');
}
}
],
});
Scanner.scanAlbums();
return;
}
function settings() {
$( '#g-dialog-settings' ).dialog({
height: 180,
width: 350,
modal: false,
buttons: [{
text: t('gallery', 'Apply'),
click: function() {
var scanning_root = $('#g-scanning-root').val();
var disp_order = $('#g-display-order option:selected').val();
if (scanning_root == '') {
alert('Scanning root cannot be empty');
return;
}
$.getJSON('ajax/galleryOp.php', {operation: 'store_settings', root: scanning_root, order: disp_order}, function(r) {
if (r.status == 'success') {
if (r.rescan == 'yes') {
$('#g-dialog-settings').dialog('close');
Albums.clear(document.getElementById('gallery_list'));
scanForAlbums(true);
return;
}
} else {
alert('Error: ' + r.cause);
return;
}
$('#g-dialog-settings').dialog('close');
});
}
},
{
text: t('gallery', 'Cancel'),
click: function() {
$(this).dialog('close');
}
}
],
});
$( '#g-dialog-settings' ).dialog({
height: 180,
width: 350,
modal: false,
buttons: [
{
text: t('gallery', 'Apply'),
click: function() {
var scanning_root = $('#g-scanning-root').val();
var disp_order = $('#g-display-order option:selected').val();
if (scanning_root == '') {
alert('Scanning root cannot be empty');
return;
}
$.getJSON(OC.filePath('gallery','ajax','galleryOp.php'), {operation: 'store_settings', root: scanning_root, order: disp_order}, function(r) {
if (r.status == 'success') {
if (r.rescan == 'yes') {
$('#g-dialog-settings').dialog('close');
Albums.clear(document.getElementById('gallery_list'));
scanForAlbums(true);
return;
}
} else {
alert('Error: ' + r.cause);
return;
}
$('#g-dialog-settings').dialog('close');
});
}
},
{
text: t('gallery', 'Cancel'),
click: function() {
$(this).dialog('close');
}
}
],
});
}

View File

@ -1,89 +1,101 @@
Albums={
// album item in this array should look as follow
// {name: string,
// numOfCovers: int}
//
// previews array should be an array of base64 decoded images
// to display to user as preview picture when scrolling throught
// the album cover
albums:new Array(),
// add simply adds new album to internal structure
// however albums names must be unique so other
// album with the same name wont be insered,
// and false will be returned
// true on success
add: function(album_name, num) {
if (Albums.albums[album_name] != undefined) return false;
Albums.albums[album_name] = {name: album_name, numOfCovers: num};
return true;
},
// remove element with given name
// returns remove element or undefined if no such element was present
remove: function(name) {
var i = -1, tmp = 0;
for (var a in Albums.albums) {
if (a.name == name) {
i = tmp;
break;
}
tmp++;
}
if (i != -1) {
return Albums.albums.splice(i,1);
}
return undefined;
},
// return element which match given name
// of undefined if such element do not exist
find: function(name) {
return Albums.albums[name];
},
// displays gallery in linear representation
// on given element, and apply default styles for gallery
display: function(element) {
var displayTemplate = '<div class="gallery_album_box"><div class="dummy"></div><a class="view"><div class="gallery_album_cover"></div></a><h1></h1><div class="gallery_album_decoration"><a><img src="img/share.png" title="Share"></a><a class="rename"><img src="img/rename.png" title="Rename"></a><a class="remove"><img src="img/delete.png" title="Delete"></a></div></div>';
for (var i in Albums.albums) {
var a = Albums.albums[i];
var local=$(displayTemplate);
local.attr('data-album',a.name);
$(".gallery_album_decoration a.rename", local).bind('click', {name: a.name},function(event){
event.preventDefault();
galleryRename(event.data.name);
});
$(".gallery_album_decoration a.remove", local).bind('click', {name: a.name},function(event){
event.preventDefault();
galleryRemove(event.data.name);
});
$("a.view", local).attr('href','?view='+decodeURIComponent(escape(a.name)));
$('h1',local).text(decodeURIComponent(escape(a.name)));
$(".gallery_album_cover", local).attr('title',decodeURIComponent(escape(a.name)));
$(".gallery_album_cover", local).css('background-repeat', 'no-repeat');
$(".gallery_album_cover", local).css('background-position', '0');
$(".gallery_album_cover", local).css('background-image','url("ajax/galleryOp.php?operation=get_covers&albumname='+escape(a.name)+'")');
$(".gallery_album_cover", local).mousemove(function(e) {
var albumMetadata = Albums.find(this.title);
if (albumMetadata == undefined) {
return;
}
var x = Math.floor((e.layerX - this.offsetLeft)/(this.offsetWidth/albumMetadata.numOfCovers));
x *= this.offsetWidth;
if (x < 0) x=0;
$(this).css('background-position', -x+'px 0');
});
$(element).append(local);
}
},
rename: function(element, new_name) {
if (new_name) {
$(element).attr("data-album", new_name);
$("a.view", element).attr("href", "?view="+new_name);
$("h1", element).text(new_name);
// album item in this array should look as follow
// {name: string,
// numOfCovers: int}
//
// previews array should be an array of base64 decoded images
// to display to user as preview picture when scrolling throught
// the album cover
albums:new Array(),
photos:new Array(),
shared: false,
recursive: false,
token: '',
// add simply adds new album to internal structure
// however albums names must be unique so other
// album with the same name wont be insered,
// and false will be returned
// true on success
add: function(album_name, num, path) {
if (Albums.albums[album_name] != undefined) return false;
Albums.albums[album_name] = {name: album_name, numOfCovers: num, path:path};
return true;
},
// remove element with given name
// returns remove element or undefined if no such element was present
remove: function(name) {
var i = -1, tmp = 0;
for (var a in Albums.albums) {
if (a.name == name) {
i = tmp;
break;
}
tmp++;
}
if (i != -1) {
return Albums.albums.splice(i,1);
}
return undefined;
},
// return element which match given name
// of undefined if such element do not exist
find: function(name) {
return Albums.albums[name];
},
// displays gallery in linear representation
// on given element, and apply default styles for gallery
display: function(element) {
var displayTemplate = '<div class="gallery_box album"><div class="dummy"></div><a class="view"><div class="gallery_album_cover"></div></a><h1></h1></div>';
for (var i in Albums.albums) {
var a = Albums.albums[i];
var local=$(displayTemplate);
local.attr('title', a.name);
local.attr('data-path', a.path);
local.attr('data-album',a.name);
$(".gallery_album_decoration a.rename", local).bind('click', {name: a.name},function(name,event){
event.preventDefault();
event.stopPropagation();
galleryRename(name);
}.bind(null,a.name));
$(".gallery_album_decoration a.remove", local).bind('click', {name: a.name},function(name,event){
event.preventDefault();
event.stopPropagation();
galleryRemove(name);
}.bind(null,a.name));
$('h1',local).text(decodeURIComponent(escape(a.name)));
$(".gallery_album_cover", local).attr('title',decodeURIComponent(escape(a.name)));
$(".gallery_album_cover", local).css('background-repeat', 'no-repeat');
$(".gallery_album_cover", local).css('background-position', '0');
$(".gallery_album_cover", local).css('background-image','url("'+OC.filePath('gallery','ajax','galleryOp.php')+'?operation=get_covers&albumname='+escape(a.name)+'")');
$(".gallery_album_cover", local).mousemove(function(event) {
var albumMetadata = Albums.find(this.title);
if (albumMetadata == undefined) {
return;
}
var x = Math.floor(event.offsetX/(this.offsetWidth/albumMetadata.numOfCovers));
x *= this.offsetWidth;
if (x < 0 || isNaN(x)) x=0;
$(this).css('background-position', -x+'px 0');
});
$(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>';
for (var i in Albums.photos) {
$(element).append(photoDisplayTemplate.replace("IMGPATH", escape(Albums.photos[i])).replace("URLPATH", escape(Albums.photos[i])));
}
$("a[rel=images]").fancybox({
'titlePosition': 'inside'
});
},
rename: function(element, new_name) {
if (new_name) {
$(element).attr("data-album", new_name);
$("a.view", element).attr("href", "?view="+new_name);
$("h1", element).text(new_name);
}
},
clear: function(element) {
Albums.albums = new Array();
element.innerHTML = '';
}
},
clear: function(element) {
Albums.albums = new Array();
element.innerHTML = '';
}
}

View File

@ -0,0 +1,34 @@
Scanner={
albumsFound:0,
eventSource:null,
albumsScanned:0,
scanAlbums:function(callback){
$('#scanprogressbar').progressbar({value:0});
$('#scanprogressbar').fadeIn();
$('#scan input.start').hide();
$('#scan input.stop').show();
Scanner.albumsScanned=0;
Scanner.eventSource=new OC.EventSource(OC.linkTo('gallery', 'ajax/galleryOp.php'),{operation:'scan'});
Scanner.eventSource.listen('count', function(total){Scanner.albumsFound=total;});
Scanner.eventSource.listen('scanned', function(data) {
Scanner.albumsScanned++;
var progress=(Scanner.albumsScanned/Scanner.albumsFound)*100;
$('#scanprogressbar').progressbar('value',progress);
});
Scanner.eventSource.listen('done', function(count){
$('#scan input.start').show();
$('#scan input.stop').hide();
$('#scanprogressbar').fadeOut();
returnToElement(0);
});
if (callback)
callback();
},
stop:function() {
Scanner.eventSource.close();
$('#scan input.start').show();
$('#scan input.stop').hide();
$('#scanprogressbar').fadeOut();
}
}

View File

@ -0,0 +1,57 @@
$(document).ready(function() {
$.getJSON('ajax/sharing.php', {operation: 'get_gallery', token: TOKEN}, albumClickHandler);
});
var paths = [];
var counter = 0;
function returnTo(num) {
while (num != counter) {
paths.pop();
$('.breadcrumbelement:last').remove();
counter--;
}
path = '';
for (var e in paths) path += '/' + paths[e];
$.getJSON('ajax/sharing.php', {operation: 'get_gallery', token: TOKEN, path: path}, function(r) {
albumClickHandler(r);
});
}
function albumClickHandler(r) {
var element = $('div#gallery_list');
element.html('');
var album_template = '<div class="gallery_box"><div><a rel="images"><img src="ajax/sharing.php?token='+TOKEN+'&operation=get_album_thumbnail&albumname=IMGPATH"></a></div><h1></h1></div>';
for (var i in r.albums) {
var a = r.albums[i];
var local = $(album_template.replace('IMGPATH', encodeURIComponent(a)));
local.attr('title', a);
$('h1', local).html(a);
element.append(local);
}
$('div.gallery_box').each(function(i, element) {
$(element).click(function() {
paths.push($(this).attr('title'));
path = '';
for (var e in paths) path += '/' + paths[e];
$.getJSON('ajax/sharing.php', {operation: 'get_gallery', token: TOKEN, path: path}, function(r) {
var name = paths[paths.length-1];
counter++;
var d = '<span class="breadcrumbelement" onclick="javascript:returnTo('+counter+');return false;">'+name+'</span>';
d = $(d).addClass('inside');
$('#breadcrumb').append(d);
albumClickHandler(r);
});
});
});
var pat = '';
for (var a in paths) pat += '/'+paths[a];
var photo_template = '<div class="gallery_box"><div><a rel="images" href="*HREF*" target="_blank"><img src="ajax/sharing.php?token='+TOKEN+'&operation=get_thumbnail&img=IMGPATH"></a></div></div>';
for (var a in r.photos) {
var local = photo_template.replace('IMGPATH', encodeURIComponent(r.photos[a])).replace('*HREF*', 'ajax/sharing.php?token='+TOKEN+'&operation=get_photo&photo='+encodeURIComponent(r.photos[a]));
element.append(local);
}
}

View File

@ -4,97 +4,113 @@
* ownCloud - gallery application
*
* @author Bartek Przybylski
* @copyright 2012 Bartek Przybylski bart.p.pl@gmail.com
*
* @copyright 2012 Bartek Przybylski <bartek@alefzero.eu>
*
* 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
* 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/>.
*
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
require_once('base.php');
class OC_Gallery_Album {
public static function create($owner, $name, $path){
$stmt = OC_DB::prepare('INSERT INTO *PREFIX*gallery_albums (uid_owner, album_name, album_path) VALUES (?, ?, ?)');
$stmt->execute(array($owner, $name, $path));
}
public static function rename($oldname, $newname, $owner) {
$stmt = OC_DB::prepare('UPDATE *PREFIX*gallery_albums SET album_name=? WHERE uid_owner=? AND album_name=?');
$stmt->execute(array($newname, $owner, $oldname));
$stmt = OC_DB::prepare('INSERT INTO *PREFIX*gallery_albums (uid_owner, album_name, album_path, parent_path) VALUES (?, ?, ?, ?)');
$stmt->execute(array($owner, $name, $path, self::getParentPath($path)));
}
public static function cleanup() {
$albums = self::find(OC_User::getUser());
while ($r = $albums->fetchRow()) {
OC_Gallery_Photo::removeByAlbumId($r['album_id']);
self::remove(OC_User::getUser(), $r['album_name']);
}
}
public static function remove($owner, $name=null) {
$sql = 'DELETE FROM *PREFIX*gallery_albums WHERE uid_owner = ?';
public static function cleanup() {
$albums = self::find(OC_User::getUser());
while ($r = $albums->fetchRow()) {
OC_Gallery_Photo::removeByAlbumId($r['album_id']);
self::remove(OC_User::getUser(), $r['album_name']);
}
}
public static function getParentPath($path) {
return $path === '/' ? '' : dirname($path);
}
public static function remove($owner, $name=null, $path=null, $parent=null) {
$sql = 'DELETE FROM *PREFIX*gallery_albums WHERE uid_owner LIKE ?';
$args = array($owner);
if (!is_null($name)){
$sql .= ' AND album_name = ?';
$sql .= ' AND album_name LIKE ?';
$args[] = $name;
}
if (!is_null($path)){
$sql .= ' AND album_path LIKE ?';
$args[] = $path;
}
if (!is_null($parent)){
$sql .= ' AND parent_path LIKE ?';
$args[] = $parent;
}
$stmt = OC_DB::prepare($sql);
return $stmt->execute($args);
}
public static function removeByPath($path, $owner) {
$album = self::find($owner, null, $path);
$album = $album->fetchRow();
self::remove($owner, $album['album_name']);
OC_Gallery_Photo::removeByAlbumId($album['album_id']);
// find and remove any gallery which might be stored lower in dir hierarchy
$path = $path.'/%';
$stmt = OC_DB::prepare('SELECT * FROM *PREFIX*gallery_albums WHERE album_path LIKE ? AND uid_owner = ?');
$result = $stmt->execute(array($path, $owner));
while (($album = $result->fetchRow())) {
OC_Gallery_Photo::removeByAlbumId($album['album_id']);
self::remove($owner, $album['album_name']);
}
}
public static function removeByName($owner, $name) { self::remove($ownmer, $name); }
public static function removeByPath($owner, $path) { self::remove($owner, null, $path); }
public static function removeByParentPath($owner, $parent) { self::remove($owner, null, null, $parent); }
public static function find($owner, $name=null, $path=null){
public static function find($owner, $name=null, $path=null, $parent=null){
$sql = 'SELECT * FROM *PREFIX*gallery_albums WHERE uid_owner = ?';
$args = array($owner);
if (!is_null($name)){
$sql .= ' AND album_name = ?';
$args[] = $name;
}
if (!is_null($path)){
$sql .= ' AND album_path = ?';
$args[] = $path;
}
$order = OC_Preferences::getValue(OC_User::getUser(), 'gallery', 'order', 'ASC');
$sql .= ' ORDER BY album_name ' . $order;
}
if (!is_null($path)){
$sql .= ' AND album_path = ?';
$args[] = $path;
}
if (!is_null($parent)){
$sql .= ' AND parent_path = ?';
$args[] = $parent;
}
$order = OC_Preferences::getValue($owner, 'gallery', 'order', 'ASC');
$sql .= ' ORDER BY album_name ' . $order;
$stmt = OC_DB::prepare($sql);
return $stmt->execute($args);
}
public static function changePath($oldname, $newname, $owner) {
$stmt = OC_DB::prepare('UPDATE *PREFIX*gallery_albums SET album_path=? WHERE uid_owner=? AND album_path=?');
$stmt->execute(array($newname, $owner, $oldname));
}
public static function changePath($oldname, $newname, $owner) {
$stmt = OC_DB::prepare('UPDATE *PREFIX*gallery_albums SET album_path=? WHERE uid_owner=? AND album_path=?');
$stmt->execute(array($newname, $owner, $oldname));
}
public static function changeThumbnailPath($oldname, $newname) {
require_once('../../../lib/base.php');
$thumbpath = OC::$CONFIG_DATADIRECTORY.'/../gallery/';
rename($thumbpath.$oldname.'.png', $thumbpath.$newname.'.png');
}
public static function changeThumbnailPath($oldname, $newname) {
require_once('../../../lib/base.php');
$thumbpath = OC::$CONFIG_DATADIRECTORY.'/../gallery/';
rename($thumbpath.$oldname.'.png', $thumbpath.$newname.'.png');
}
public static function getAlbumSize($id){
$sql = 'SELECT COUNT(*) as size FROM *PREFIX*gallery_photos WHERE album_id = ?';
$stmt = OC_DB::prepare($sql);
$result=$stmt->execute(array($id))->fetchRow();
return $result['size'];
}
public static function getIntermediateGallerySize($path) {
$path .= '%';
$sql = 'SELECT COUNT(*) as size FROM *PREFIX*gallery_photos photos, *PREFIX*gallery_albums albums WHERE photos.album_id = albums.album_id AND uid_owner = ? AND file_path LIKE ?';
$stmt = OC_DB::prepare($sql);
$result = $stmt->execute(array(OC_User::getUser(), $path))->fetchRow();
return $result['size'];
}
}
?>

View File

@ -21,9 +21,9 @@
*
*/
OC_Hook::connect(OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_write, "OC_Gallery_Hooks_Handlers", "addPhotoFromPath");
OC_Hook::connect(OC_Filesystem::CLASSNAME, OC_Filesystem::signal_delete, "OC_Gallery_Hooks_Handlers", "removePhoto");
OC_Hook::connect(OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_rename, "OC_Gallery_Hooks_Handlers", "renamePhoto");
//OC_Hook::connect(OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_write, "OC_Gallery_Hooks_Handlers", "addPhotoFromPath");
//OC_Hook::connect(OC_Filesystem::CLASSNAME, OC_Filesystem::signal_delete, "OC_Gallery_Hooks_Handlers", "removePhoto");
//OC_Hook::connect(OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_rename, "OC_Gallery_Hooks_Handlers", "renamePhoto");
require_once(OC::$CLASSPATH['OC_Gallery_Album']);
require_once(OC::$CLASSPATH['OC_Gallery_Photo']);
@ -37,7 +37,7 @@ class OC_Gallery_Hooks_Handlers {
}
private static function directoryContainsPhotos($dirpath) {
$dirhandle = opendir(OC::$CONFIG_DATADIRECTORY.$dirpath);
$dirhandle = OC_Filesystem::opendir($dirpath.'/');
if ($dirhandle != FALSE) {
while (($filename = readdir($dirhandle)) != FALSE) {
if ($filename[0] == '.') continue;
@ -68,7 +68,7 @@ class OC_Gallery_Hooks_Handlers {
if (!self::isPhoto($fullpath)) return;
$path = substr($fullpath, 0, strrpos($fullpath, '/'));
$path = dirname($fullpath);
if (!self::pathInRoot($path)) return;
OC_Gallery_Scanner::scanDir($path, $albums);
@ -76,9 +76,9 @@ class OC_Gallery_Hooks_Handlers {
public static function removePhoto($params) {
$path = $params[OC_Filesystem::signal_param_path];
if (OC_Filesystem::is_dir($path) && self::directoryContainsPhotos($path)) {
if (OC_Filesystem::is_dir($path.'/') && self::directoryContainsPhotos($path)) {
if(!self::pathInRoot($path)) return;
OC_Gallery_Album::removeByPath($path.'/', OC_User::getUser());
OC_Gallery_Album::removeByPath($path, OC_User::getUser());
} elseif (self::isPhoto($path)) {
OC_Gallery_Photo::removeByPath($path);
}
@ -87,11 +87,11 @@ class OC_Gallery_Hooks_Handlers {
public static function renamePhoto($params) {
$oldpath = $params[OC_Filesystem::signal_param_oldpath];
$newpath = $params[OC_Filesystem::signal_param_newpath];
if (OC_Filesystem::is_dir($newpath) && self::directoryContainsPhotos($newpath)) {
if (OC_Filesystem::is_dir($newpath.'/') && self::directoryContainsPhotos($newpath)) {
OC_Gallery_Album::changePath($oldpath, $newpath, OC_User::getUser());
} elseif (!self::isPhoto($newpath)) {
$olddir = substr($oldpath, 0, strrpos($oldpath, '/'));
$newdir = substr($newpath, 0, strrpos($newpath, '/'));
} elseif (self::isPhoto($newpath)) {
$olddir = dirname($oldpath);
$newdir = dirname($newpath);
if ($olddir == '') $olddir = '/';
if ($newdir == '') $newdir = '/';
if (!self::isPhoto($newpath)) return;
@ -101,25 +101,26 @@ class OC_Gallery_Hooks_Handlers {
$oldAlbumId;
if ($olddir == $newdir) {
// album changing is not needed
$album = OC_Gallery_Album::find(OC_User::getUser(), null, $olddir);
if ($album->numRows() == 0) {
$album = self::createAlbum($newdir);
$albums = OC_Gallery_Album::find(OC_User::getUser(), null, $olddir);
$album = $albums->fetchRow();
if (!$album) {
$albums = self::createAlbum($newdir);
$album = $albums->fetchRow();
}
$album = $album->fetchRow();
$newAlbumId = $oldAlbumId = $album['album_id'];
} else {
$newalbum = OC_Gallery_Album::find(OC_User::getUser(), null, $newdir);
$oldalbum = OC_Gallery_Album::find(OC_User::getUser(), null, $olddir);
if ($newalbum->numRows() == 0) {
if (!($newalbum = $newalbum->fetchRow())) {
$newalbum = self::createAlbum($newdir);
$newalbum = $newalbum->fetchRow();
}
$newalbum = $newalbum->fetchRow();
if ($oldalbum->numRows() == 0) {
$oldalbum = $oldalbum->fetchRow();
if (!$oldalbum) {
OC_Gallery_Photo::create($newalbum['album_id'], $newpath);
return;
}
$oldalbum = $oldalbum->fetchRow();
$newAlbumId = $newalbum['album_id'];
$oldAlbumId = $oldalbum['album_id'];

View File

@ -13,11 +13,11 @@
*
* 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
* 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/>.
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
@ -46,51 +46,58 @@ class OC_Gallery_Photo {
return $stmt->execute(array($owner, $album_name));
}
public static function removeByPath($path) {
$stmt = OC_DB::prepare('DELETE FROM *PREFIX*gallery_photos WHERE file_path LIKE ?');
$stmt->execute(array($path));
}
public static function removeByPath($path) {
$stmt = OC_DB::prepare('DELETE FROM *PREFIX*gallery_photos WHERE file_path LIKE ?');
$stmt->execute(array($path));
}
public static function removeById($id) {
$stmt = OC_DB::prepare('DELETE FROM *PREFIX*gallery_photos WHERE photo_id = ?');
$stmt->execute(array($id));
}
public static function removeById($id) {
$stmt = OC_DB::prepare('DELETE FROM *PREFIX*gallery_photos WHERE photo_id = ?');
$stmt->execute(array($id));
}
public static function removeByAlbumId($albumid) {
$stmt = OC_DB::prepare('DELETE FROM *PREFIX*gallery_photos WHERE album_id = ?');
$stmt->execute(array($albumid));
}
public static function removeByAlbumId($albumid) {
$stmt = OC_DB::prepare('DELETE FROM *PREFIX*gallery_photos WHERE album_id = ?');
$stmt->execute(array($albumid));
}
public static function changePath($oldAlbumId, $newAlbumId, $oldpath, $newpath) {
$stmt = OC_DB::prepare("UPDATE *PREFIX*gallery_photos SET file_path = ?, album_id = ? WHERE album_id = ? and file_path = ?");
$stmt->execute(array($newpath, $newAlbumId, $oldAlbumId, $oldpath));
}
public static function changePath($oldAlbumId, $newAlbumId, $oldpath, $newpath) {
$stmt = OC_DB::prepare("UPDATE *PREFIX*gallery_photos SET file_path = ?, album_id = ? WHERE album_id = ? and file_path = ?");
$stmt->execute(array($newpath, $newAlbumId, $oldAlbumId, $oldpath));
}
public static function getThumbnail($image_name) {
$save_dir = OC_Config::getValue("datadirectory").'/'. OC_User::getUser() .'/gallery/';
public static function getThumbnail($image_name, $owner = null) {
if (!$owner) $owner = OC_User::getUser();
$save_dir = OC_Config::getValue("datadirectory").'/'. $owner .'/gallery/';
$save_dir .= dirname($image_name). '/';
$thumb_file = $save_dir . $image_name;
$image_path = $image_name;
$thumb_file = $save_dir . basename($image_name);
if (!is_dir($save_dir)) {
mkdir($save_dir, 0777, true);
}
if (file_exists($thumb_file)) {
$image = new OC_Image($thumb_file);
} else {
$imagePath = OC_Filesystem::getLocalFile($image_name);
if(!file_exists($imagePath)) {
$image_path = OC_Filesystem::getLocalFile($image_path);
if(!file_exists($image_path)) {
return null;
}
$image = new OC_Image($imagePath);
$image = new OC_Image($image_path);
if ($image->valid()) {
$image->centerCrop();
$image->resize(200);
$image->centerCrop(200);
$image->fixOrientation();
if (!is_dir($save_dir)) {
mkdir($save_dir, 0777, true);
}
$image->save($thumb_file);
}
}
if ($image->valid()) {
return $image;
}else{
$image->destroy();
}
return null;
}
public static function getGalleryRoot() {
return OC_Preferences::getValue(OC_User::getUser(), 'gallery', 'root', '');
}
}

View File

@ -4,7 +4,7 @@
* ownCloud - gallery application
*
* @author Bartek Przybylski
* @copyright 2012 Bartek Przybylski bart.p.pl@gmail.com
* @copyright 2012 Bartek Przybylski <bartek@alefzero.eu>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
@ -13,111 +13,132 @@
*
* 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
* 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/>.
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
require_once('base.php'); // base lib
require_once('images_utils.php');
class OC_Gallery_Scanner {
public static function scan($root) {
$albums = array();
self::scanDir($root, $albums);
return $albums;
}
public static function getGalleryRoot() {
return OC_Preferences::getValue(OC_User::getUser(), 'gallery', 'root', '/');
}
public static function getScanningRoot() {
return OC_Filesystem::getRoot().self::getGalleryRoot();
}
public static function cleanUp() {
$stmt = OC_DB::prepare('DELETE FROM *PREFIX*gallery_albums');
$stmt->execute(array());
$stmt = OC_DB::prepare('DELETE FROM *PREFIX*gallery_photos');
$stmt->execute(array());
}
public static function cleanUp() {
OC_Gallery_Album::cleanup();
}
public static function createName($name) {
$root = OC_Preferences::getValue(OC_User::getUser(), 'gallery', 'root', '/');
$name = str_replace('/', '.', str_replace(OC::$CONFIG_DATADIRECTORY, '', $name));
if (substr($name, 0, strlen($root)) == str_replace('/','.',$root)) {
$name = substr($name, strlen($root));
}
$name = ($name==='.') ? 'main' : trim($name,'.');
return $name;
}
public static function createName($name) {
$name = basename($name);
return $name == '.' ? '' : $name;
}
public static function scanDir($path, &$albums) {
$current_album = array('name'=> $path, 'imagesCount' => 0, 'images' => array());
$current_album['name'] = self::createName($current_album['name']);
// Scan single dir relative to gallery root
public static function scan($eventSource) {
$paths = self::findPaths();
$eventSource->send('count', count($paths)+1);
$owner = OC_User::getUser();
foreach ($paths as $path) {
$name = self::createName($path);
$images = self::findFiles($path);
if ($dh = OC_Filesystem::opendir($path)) {
while (($filename = readdir($dh)) !== false) {
$filepath = ($path[strlen($path)-1]=='/'?$path:$path.'/').$filename;
if (substr($filename, 0, 1) == '.') continue;
if (self::isPhoto($path.'/'.$filename)) {
$current_album['images'][] = $filepath;
}
}
}
$current_album['imagesCount'] = count($current_album['images']);
$albums['imagesCount'] = $current_album['imagesCount'];
$albums['albumName'] = $current_album['name'];
$result = OC_Gallery_Album::find($owner, null, $path);
// don't duplicate galleries with same path
if (!($albumId = $result->fetchRow())) {
OC_Gallery_Album::create($owner, $name, $path);
$result = OC_Gallery_Album::find($owner, $name, $path);
$albumId = $result->fetchRow();
}
$albumId = $albumId['album_id'];
foreach ($images as $img) {
$result = OC_Gallery_Photo::find($albumId, $img);
if (!$result->fetchRow())
OC_Gallery_Photo::create($albumId, $img);
}
if (count($images))
self::createThumbnails($name, $images);
$eventSource->send('scanned', '');
}
self::createIntermediateAlbums();
$eventSource->send('scanned', '');
$eventSource->send('done', 1);
}
$result = OC_Gallery_Album::find(OC_User::getUser(), /*$current_album['name']*/ null, $path);
// don't duplicate galleries with same path (bug oc-33)
if ($result->numRows() == 0 && count($current_album['images'])) {
OC_Gallery_Album::create(OC_User::getUser(), $current_album['name'], $path);
$result = OC_Gallery_Album::find(OC_User::getUser(), $current_album['name']);
}
$albumId = $result->fetchRow();
$albumId = $albumId['album_id'];
foreach ($current_album['images'] as $img) {
$result = OC_Gallery_Photo::find($albumId, $img);
if ($result->numRows() == 0) {
OC_Gallery_Photo::create($albumId, $img);
}
}
if (count($current_album['images'])) {
self::createThumbnail($current_album['name'],$current_album['images']);
}
}
public static function createThumbnails($albumName, $files) {
// create gallery thumbnail
$file_count = min(count($files), 10);
$thumbnail = imagecreatetruecolor($file_count*200, 200);
for ($i = 0; $i < $file_count; $i++) {
$image = OC_Gallery_Photo::getThumbnail($files[$i]);
if ($image && $image->valid()) {
imagecopyresampled($thumbnail, $image->resource(), $i*200, 0, 0, 0, 200, 200, 200, 200);
$image->destroy();
}
}
imagepng($thumbnail, OC_Config::getValue("datadirectory").'/'. OC_User::getUser() .'/gallery/' . $albumName.'.png');
imagedestroy($thumbnail);
}
public static function createThumbnail($albumName, $files) {
$file_count = min(count($files), 10);
$thumbnail = imagecreatetruecolor($file_count*200, 200);
for ($i = 0; $i < $file_count; $i++) {
$image = OC_Gallery_Photo::getThumbnail($files[$i]);
if ($image && $image->valid()) {
imagecopyresampled($thumbnail, $image->resource(), $i*200, 0, 0, 0, 200, 200, 200, 200);
}
}
imagepng($thumbnail, OC_Config::getValue("datadirectory").'/'. OC_User::getUser() .'/gallery/' . $albumName.'.png');
}
public static function createIntermediateAlbums() {
$paths = self::findPaths();
for ($i = 1; $i < count($paths); $i++) {
$prevLen = strlen($paths[$i-1]);
if (strncmp($paths[$i-1], $paths[$i], $prevLen)==0) {
$s = substr($paths[$i], $prevLen);
if (strrpos($s, '/') != 0) {
$a = explode('/', trim($s, '/'));
$p = $paths[$i-1];
foreach ($a as $e) {
$p .= ($p == '/'?'':'/').$e;
OC_Gallery_Album::create(OC_User::getUser(), $e, $p);
$arr = OC_FileCache::searchByMime('image','', OC_Filesystem::getRoot().$p);
$step = floor(count($arr)/10);
if ($step == 0) $step = 1;
$na = array();
for ($j = 0; $j < count($arr); $j+=$step) {
$na[] = $p.$arr[$j];
}
if (count($na))
self::createThumbnails($e, $na);
}
}
}
}
}
public static function isPhoto($filename) {
$ext = strtolower(substr($filename, strrpos($filename, '.')+1));
return $ext=='png' || $ext=='jpeg' || $ext=='jpg' || $ext=='gif';
}
public static function isPhoto($filename) {
$ext = strtolower(substr($filename, strrpos($filename, '.')+1));
return $ext=='png' || $ext=='jpeg' || $ext=='jpg' || $ext=='gif';
}
public static function find_paths($path) {
$ret = array();
$dirres;
$addpath = FALSE;
if (($dirres = OC_Filesystem::opendir($path)) == FALSE) return $ret;
public static function findFiles($path) {
$images = OC_FileCache::searchByMime('image','', OC_Filesystem::getRoot().$path);
$new = array();
foreach ($images as $i)
if (strpos($i, '/',1) === FALSE)
$new[] = $path.$i;
return $new;
}
while (($file = readdir($dirres)) != FALSE) {
if ($file[0] == '.') continue;
if (OC_Filesystem::is_dir($path.$file))
$ret = array_merge($ret, self::find_paths($path.$file.'/'));
if (self::isPhoto($path.$file)) $addpath = TRUE;
}
if ($addpath) $ret[] = urlencode($path);
return $ret;
}
public static function findPaths() {
$images=OC_FileCache::searchByMime('image','', self::getScanningRoot());
$paths=array();
foreach($images as $image){
$path=dirname($image);
$path = self::getGalleryRoot().($path=='.'?'':$path);
if ($path !== '/') $path=rtrim($path,'/');
if(array_search($path,$paths)===false){
$paths[]=$path;
}
}
sort($paths);
return $paths;
}
}
?>

View File

@ -0,0 +1,89 @@
<?php
/**
* ownCloud - gallery application
*
* @author Bartek Przybylski
* @copyright 2012 Bartek Przybylski bartek@alefzero.eu
*
* 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_Sharing {
private static function getEntries($token) {
$sql = 'SELECT * FROM *PREFIX*gallery_sharing WHERE token = ?';
$stmt = OC_DB::prepare($sql);
return $stmt->execute(array($token));
}
public static function isTokenValid($token) {
$r = self::getEntries($token);
$row = $r->fetchRow();
return $row != null;
}
public static function isRecursive($token) {
$r = self::getEntries($token);
if ($row = $r->fetchRow()) return $row['recursive'] == 1;
return false;
}
public static function getTokenOwner($token) {
$r = self::getEntries($token);
if ($row = $r->fetchRow()) {
$galleryId = $row['gallery_id'];
$sql = 'SELECT * FROM *PREFIX*gallery_albums WHERE album_id = ?';
$stmt = OC_DB::prepare($sql);
$r = $stmt->execute(array($galleryId));
if ($row = $r->fetchRow())
return $row['uid_owner'];
}
return false;
}
public static function getPath($token) {
$r = self::getEntries($token);
if ($row = $r->fetchRow()) {
$galleryId = $row['gallery_id'];
$sql = 'SELECT * FROM *PREFIX*gallery_albums WHERE album_id = ?';
$stmt = OC_DB::prepare($sql);
$r = $stmt->execute(array($galleryId));
if ($row = $r->fetchRow())
return $row['album_path'];
}
}
public static function updateSharingByToken($token, $recursive) {
$stmt = OC_DB::prepare('UPDATE *PREFIX*gallery_sharing SET recursive = ? WHERE token = ?');
$stmt->execute(array($recursive, $token));
}
public static function getEntryByAlbumId($album_id) {
$stmt = OC_DB::prepare('SELECT * FROM *PREFIX*gallery_sharing WHERE gallery_id = ?');
return $stmt->execute(array($album_id));
}
public static function addShared($token, $albumId, $recursive) {
$sql = 'INSERT INTO *PREFIX*gallery_sharing (token, gallery_id, recursive) VALUES (?, ?, ?)';
$stmt = OC_DB::prepare($sql);
$stmt->execute(array($token, $albumId, $recursive));
}
public static function remove($albumId) {
$stmt = OC_DB::prepare('DELETE FROM *PREFIX*gallery_sharing WHERE gallery_id = ?');
$stmt->execute(array($albumId));
}
}

Some files were not shown because too many files have changed in this diff Show More