Merge branch 'master' into multi_app_dir

Conflicts:
	lib/app.php
	lib/base.php
	lib/minimizer/css.php
	lib/minimizer/js.php
	lib/template.php
	lib/util.php
remotes/origin/stable45
Brice Maron 12 years ago
commit e5c56b2433

@ -146,33 +146,6 @@ class MDB2_Schema_Parser extends XML_Parser
);
}
/**
* PHP 4 compatible constructor
*
* @param array $variables mixed array with user defined schema
* variables
* @param bool $fail_on_invalid_names array with reserved words per RDBMS
* @param array $structure multi dimensional array with
* database schema and data
* @param array $valid_types information of all valid fields
* types
* @param bool $force_defaults if true sets a default value to
* field when not explicit
* @param int $max_identifiers_length maximum allowed size for entities
* name
*
* @return void
*
* @access public
* @static
*/
function MDB2_Schema_Parser($variables, $fail_on_invalid_names = true,
$structure = false, $valid_types = array(), $force_defaults = true,
$max_identifiers_length = null
) {
$this->__construct($variables, $fail_on_invalid_names, $structure, $valid_types, $force_defaults);
}
/**
* Triggered when reading a XML open tag <element>
*

@ -143,33 +143,6 @@ class MDB2_Schema_Parser2 extends XML_Unserializer
parent::XML_Unserializer($this->options);
}
/**
* PHP 4 compatible constructor
*
* @param array $variables mixed array with user defined schema
* variables
* @param bool $fail_on_invalid_names array with reserved words per RDBMS
* @param array $structure multi dimensional array with
* database schema and data
* @param array $valid_types information of all valid fields
* types
* @param bool $force_defaults if true sets a default value to
* field when not explicit
* @param int $max_identifiers_length maximum allowed size for entities
* name
*
* @return void
*
* @access public
* @static
*/
function MDB2_Schema_Parser2($variables, $fail_on_invalid_names = true,
$structure = false, $valid_types = array(), $force_defaults = true,
$max_identifiers_length = null
) {
$this->__construct($variables, $fail_on_invalid_names, $structure, $valid_types, $force_defaults);
}
/**
* Main method. Parses XML Schema File.
*

@ -108,28 +108,6 @@ class MDB2_Schema_Validate
$this->max_identifiers_length = $max_identifiers_length;
}
/**
* PHP 4 compatible constructor
*
* @param bool $fail_on_invalid_names array with reserved words per RDBMS
* @param array $valid_types information of all valid fields
* types
* @param bool $force_defaults if true sets a default value to
* field when not explicit
* @param int $max_identifiers_length maximum allowed size for entities
* name
*
* @return void
*
* @access public
* @static
*/
function MDB2_Schema_Validate($fail_on_invalid_names = true, $valid_types = array(),
$force_defaults = true, $max_identifiers_length = null
) {
$this->__construct($fail_on_invalid_names, $valid_types, $force_defaults);
}
// }}}
// {{{ raiseError()

@ -82,22 +82,6 @@ class MDB2_Schema_Writer
$this->valid_types = $valid_types;
}
/**
* PHP 4 compatible constructor
*
* @param array $valid_types information of all valid fields
* types
*
* @return void
*
* @access public
* @static
*/
function MDB2_Schema_Writer($valid_types = array())
{
$this->__construct($valid_types);
}
// }}}
// {{{ raiseError()

@ -4662,7 +4662,7 @@ function DayEventRenderer() {
"</span>";
}
html +=
"<span class='fc-event-title'>" + htmlEscape(event.title) + "</span>" +
"<span class='fc-event-title'>" + event.title + "</span>" +
"</div>";
if (seg.isEnd && isEventResizable(event)) {
html +=

@ -326,8 +326,11 @@ class smb_stream_wrapper extends smb {
$this->dir = array_keys($o['info']);
$this->dir_index = 0;
$this->adddircache ($url, $this->dir);
if(substr($url,-1,1)=='/'){
$url=substr($url,0,-1);
}
foreach ($o['info'] as $name => $info) {
smb::addstatcache($url . '/' . urlencode($name), $info);
smb::addstatcache($url . '/' . $name, $info);
}
} else {
trigger_error ("dir_opendir(): dir failed for path '".$pu['path']."'", E_USER_WARNING);

@ -1,9 +0,0 @@
License
Copyright (c) 2010 Thomas Planer
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

@ -1,731 +0,0 @@
<?php
/**
* Name: When
* Author: Thomas Planer <tplaner@gmail.com>
* Location: http://github.com/tplaner/When
* Created: September 2010
* Description: Determines the next date of recursion given an iCalendar "rrule" like pattern.
* Requirements: PHP 5.3+ - makes extensive use of the Date and Time library (http://us2.php.net/manual/en/book.datetime.php)
*/
class When
{
protected $frequency;
protected $start_date;
protected $try_date;
protected $end_date;
protected $gobymonth;
protected $bymonth;
protected $gobyweekno;
protected $byweekno;
protected $gobyyearday;
protected $byyearday;
protected $gobymonthday;
protected $bymonthday;
protected $gobyday;
protected $byday;
protected $gobysetpos;
protected $bysetpos;
protected $suggestions;
protected $count;
protected $counter;
protected $goenddate;
protected $interval;
protected $wkst;
protected $valid_week_days;
protected $valid_frequency;
/**
* __construct
*/
public function __construct()
{
$this->frequency = null;
$this->gobymonth = false;
$this->bymonth = range(1,12);
$this->gobymonthday = false;
$this->bymonthday = range(1,31);
$this->gobyday = false;
// setup the valid week days (0 = sunday)
$this->byday = range(0,6);
$this->gobyyearday = false;
$this->byyearday = range(0,366);
$this->gobysetpos = false;
$this->bysetpos = range(1,366);
$this->gobyweekno = false;
// setup the range for valid weeks
$this->byweekno = range(0,54);
$this->suggestions = array();
// this will be set if a count() is specified
$this->count = 0;
// how many *valid* results we returned
$this->counter = 0;
// max date we'll return
$this->end_date = new DateTime('9999-12-31');
// the interval to increase the pattern by
$this->interval = 1;
// what day does the week start on? (0 = sunday)
$this->wkst = 0;
$this->valid_week_days = array('SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA');
$this->valid_frequency = array('SECONDLY', 'MINUTELY', 'HOURLY', 'DAILY', 'WEEKLY', 'MONTHLY', 'YEARLY');
}
/**
* @param DateTime|string $start_date of the recursion - also is the first return value.
* @param string $frequency of the recrusion, valid frequencies: secondly, minutely, hourly, daily, weekly, monthly, yearly
*/
public function recur($start_date, $frequency = "daily")
{
try
{
if(is_object($start_date))
{
$this->start_date = clone $start_date;
}
else
{
// timestamps within the RFC have a 'Z' at the end of them, remove this.
$start_date = trim($start_date, 'Z');
$this->start_date = new DateTime($start_date);
}
$this->try_date = clone $this->start_date;
}
catch(Exception $e)
{
throw new InvalidArgumentException('Invalid start date DateTime: ' . $e);
}
$this->freq($frequency);
return $this;
}
public function freq($frequency)
{
if(in_array(strtoupper($frequency), $this->valid_frequency))
{
$this->frequency = strtoupper($frequency);
}
else
{
throw new InvalidArgumentException('Invalid frequency type.');
}
return $this;
}
// accepts an rrule directly
public function rrule($rrule)
{
// strip off a trailing semi-colon
$rrule = trim($rrule, ";");
$parts = explode(";", $rrule);
foreach($parts as $part)
{
list($rule, $param) = explode("=", $part);
$rule = strtoupper($rule);
$param = strtoupper($param);
switch($rule)
{
case "FREQ":
$this->frequency = $param;
break;
case "UNTIL":
$this->until($param);
break;
case "COUNT":
$this->count($param);
break;
case "INTERVAL":
$this->interval($param);
break;
case "BYDAY":
$params = explode(",", $param);
$this->byday($params);
break;
case "BYMONTHDAY":
$params = explode(",", $param);
$this->bymonthday($params);
break;
case "BYYEARDAY":
$params = explode(",", $param);
$this->byyearday($params);
break;
case "BYWEEKNO":
$params = explode(",", $param);
$this->byweekno($params);
break;
case "BYMONTH":
$params = explode(",", $param);
$this->bymonth($params);
break;
case "BYSETPOS":
$params = explode(",", $param);
$this->bysetpos($params);
break;
case "WKST":
$this->wkst($param);
break;
}
}
return $this;
}
//max number of items to return based on the pattern
public function count($count)
{
$this->count = (int)$count;
return $this;
}
// how often the recurrence rule repeats
public function interval($interval)
{
$this->interval = (int)$interval;
return $this;
}
// starting day of the week
public function wkst($day)
{
switch($day)
{
case 'SU':
$this->wkst = 0;
break;
case 'MO':
$this->wkst = 1;
break;
case 'TU':
$this->wkst = 2;
break;
case 'WE':
$this->wkst = 3;
break;
case 'TH':
$this->wkst = 4;
break;
case 'FR':
$this->wkst = 5;
break;
case 'SA':
$this->wkst = 6;
break;
}
return $this;
}
// max date
public function until($end_date)
{
try
{
if(is_object($end_date))
{
$this->end_date = clone $end_date;
}
else
{
// timestamps within the RFC have a 'Z' at the end of them, remove this.
$end_date = trim($end_date, 'Z');
$this->end_date = new DateTime($end_date);
}
}
catch(Exception $e)
{
throw new InvalidArgumentException('Invalid end date DateTime: ' . $e);
}
return $this;
}
public function bymonth($months)
{
if(is_array($months))
{
$this->gobymonth = true;
$this->bymonth = $months;
}
return $this;
}
public function bymonthday($days)
{
if(is_array($days))
{
$this->gobymonthday = true;
$this->bymonthday = $days;
}
return $this;
}
public function byweekno($weeks)
{
$this->gobyweekno = true;
if(is_array($weeks))
{
$this->byweekno = $weeks;
}
return $this;
}
public function bysetpos($days)
{
$this->gobysetpos = true;
if(is_array($days))
{
$this->bysetpos = $days;
}
return $this;
}
public function byday($days)
{
$this->gobyday = true;
if(is_array($days))
{
$this->byday = array();
foreach($days as $day)
{
$len = strlen($day);
$as = '+';
// 0 mean no occurence is set
$occ = 0;
if($len == 3)
{
$occ = substr($day, 0, 1);
}
if($len == 4)
{
$as = substr($day, 0, 1);
$occ = substr($day, 1, 1);
}
if($as == '-')
{
$occ = '-' . $occ;
}
else
{
$occ = '+' . $occ;
}
$day = substr($day, -2, 2);
switch($day)
{
case 'SU':
$this->byday[] = $occ . 'SU';
break;
case 'MO':
$this->byday[] = $occ . 'MO';
break;
case 'TU':
$this->byday[] = $occ . 'TU';
break;
case 'WE':
$this->byday[] = $occ . 'WE';
break;
case 'TH':
$this->byday[] = $occ . 'TH';
break;
case 'FR':
$this->byday[] = $occ . 'FR';
break;
case 'SA':
$this->byday[] = $occ . 'SA';
break;
}
}
}
return $this;
}
public function byyearday($days)
{
$this->gobyyearday = true;
if(is_array($days))
{
$this->byyearday = $days;
}
return $this;
}
// this creates a basic list of dates to "try"
protected function create_suggestions()
{
switch($this->frequency)
{
case "YEARLY":
$interval = 'year';
break;
case "MONTHLY":
$interval = 'month';
break;
case "WEEKLY":
$interval = 'week';
break;
case "DAILY":
$interval = 'day';
break;
case "HOURLY":
$interval = 'hour';
break;
case "MINUTELY":
$interval = 'minute';
break;
case "SECONDLY":
$interval = 'second';
break;
}
$month_day = $this->try_date->format('j');
$month = $this->try_date->format('n');
$year = $this->try_date->format('Y');
$timestamp = $this->try_date->format('H:i:s');
if($this->gobysetpos)
{
if($this->try_date == $this->start_date)
{
$this->suggestions[] = clone $this->try_date;
}
else
{
if($this->gobyday)
{
foreach($this->bysetpos as $_pos)
{
$tmp_array = array();
$_mdays = range(1, date('t',mktime(0,0,0,$month,1,$year)));
foreach($_mdays as $_mday)
{
$date_time = new DateTime($year . '-' . $month . '-' . $_mday . ' ' . $timestamp);
$occur = ceil($_mday / 7);
$day_of_week = $date_time->format('l');
$dow_abr = strtoupper(substr($day_of_week, 0, 2));
// set the day of the month + (positive)
$occur = '+' . $occur . $dow_abr;
$occur_zero = '+0' . $dow_abr;
// set the day of the month - (negative)
$total_days = $date_time->format('t') - $date_time->format('j');
$occur_neg = '-' . ceil(($total_days + 1)/7) . $dow_abr;
$day_from_end_of_month = $date_time->format('t') + 1 - $_mday;
if(in_array($occur, $this->byday) || in_array($occur_zero, $this->byday) || in_array($occur_neg, $this->byday))
{
$tmp_array[] = clone $date_time;
}
}
if($_pos > 0)
{
$this->suggestions[] = clone $tmp_array[$_pos - 1];
}
else
{
$this->suggestions[] = clone $tmp_array[count($tmp_array) + $_pos];
}
}
}
}
}
elseif($this->gobyyearday)
{
foreach($this->byyearday as $_day)
{
if($_day >= 0)
{
$_day--;
$_time = strtotime('+' . $_day . ' days', mktime(0, 0, 0, 1, 1, $year));
$this->suggestions[] = new Datetime(date('Y-m-d', $_time) . ' ' . $timestamp);
}
else
{
$year_day_neg = 365 + $_day;
$leap_year = $this->try_date->format('L');
if($leap_year == 1)
{
$year_day_neg = 366 + $_day;
}
$_time = strtotime('+' . $year_day_neg . ' days', mktime(0, 0, 0, 1, 1, $year));
$this->suggestions[] = new Datetime(date('Y-m-d', $_time) . ' ' . $timestamp);
}
}
}
// special case because for years you need to loop through the months too
elseif($this->gobyday && $interval == "year")
{
foreach($this->bymonth as $_month)
{
// this creates an array of days of the month
$_mdays = range(1, date('t',mktime(0,0,0,$_month,1,$year)));
foreach($_mdays as $_mday)
{
$date_time = new DateTime($year . '-' . $_month . '-' . $_mday . ' ' . $timestamp);
// get the week of the month (1, 2, 3, 4, 5, etc)
$week = $date_time->format('W');
if($date_time >= $this->start_date && in_array($week, $this->byweekno))
{
$this->suggestions[] = clone $date_time;
}
}
}
}
elseif($interval == "day")
{
$this->suggestions[] = clone $this->try_date;
}
elseif($interval == "week")
{
$this->suggestions[] = clone $this->try_date;
if($this->gobyday)
{
$week_day = $this->try_date->format('w');
$days_in_month = $this->try_date->format('t');
$overflow_count = 1;
$_day = $month_day;
$run = true;
while($run)
{
$_day++;
if($_day <= $days_in_month)
{
$tmp_date = new DateTime($year . '-' . $month . '-' . $_day . ' ' . $timestamp);
}
else
{
//$tmp_month = $month+1;
$tmp_date = new DateTime($year . '-' . $month . '-' . $overflow_count . ' ' . $timestamp);
$tmp_date->modify('+1 month');
$overflow_count++;
}
$week_day = $tmp_date->format('w');
if($this->try_date == $this->start_date)
{
if($week_day == $this->wkst)
{
$this->try_date = clone $tmp_date;
$this->try_date->modify('-7 days');
$run = false;
}
}
if($week_day != $this->wkst)
{
$this->suggestions[] = clone $tmp_date;
}
else
{
$run = false;
}
}
}
}
elseif($this->gobyday && $interval == "month")
{
$_mdays = range(1, date('t',mktime(0,0,0,$month,1,$year)));
foreach($_mdays as $_mday)
{
$date_time = new DateTime($year . '-' . $month . '-' . $_mday . ' ' . $timestamp);
// get the week of the month (1, 2, 3, 4, 5, etc)
$week = $date_time->format('W');
if($date_time >= $this->start_date && in_array($week, $this->byweekno))
{
$this->suggestions[] = clone $date_time;
}
}
}
elseif($this->gobymonth)
{
foreach($this->bymonth as $_month)
{
$date_time = new DateTime($year . '-' . $_month . '-' . $month_day . ' ' . $timestamp);
if($date_time >= $this->start_date)
{
$this->suggestions[] = clone $date_time;
}
}
}
else
{
$this->suggestions[] = clone $this->try_date;
}
if($interval == "month")
{
$this->try_date->modify('first day of next month');
if((int) date('t', $this->try_date->format('U')) > (int) $this->start_date->format('j')){
$this->try_date->modify('+' . (int) $this->start_date->format('j') - 1 . ' day');
}else{
$this->try_date->modify('+' . (int) date('t', $this->try_date->format('U')) - 1 . ' day');
}
}
else
{
$this->try_date->modify($this->interval . ' ' . $interval);
}
}
protected function valid_date($date)
{
$year = $date->format('Y');
$month = $date->format('n');
$day = $date->format('j');
$year_day = $date->format('z') + 1;
$year_day_neg = -366 + $year_day;
$leap_year = $date->format('L');
if($leap_year == 1)
{
$year_day_neg = -367 + $year_day;
}
// this is the nth occurence of the date
$occur = ceil($day / 7);
$week = $date->format('W');
$day_of_week = $date->format('l');
$dow_abr = strtoupper(substr($day_of_week, 0, 2));
// set the day of the month + (positive)
$occur = '+' . $occur . $dow_abr;
$occur_zero = '+0' . $dow_abr;
// set the day of the month - (negative)
$total_days = $date->format('t') - $date->format('j');
$occur_neg = '-' . ceil(($total_days + 1)/7) . $dow_abr;
$day_from_end_of_month = $date->format('t') + 1 - $day;
if(in_array($month, $this->bymonth) &&
(in_array($occur, $this->byday) || in_array($occur_zero, $this->byday) || in_array($occur_neg, $this->byday)) &&
in_array($week, $this->byweekno) &&
(in_array($day, $this->bymonthday) || in_array(-$day_from_end_of_month, $this->bymonthday)) &&
(in_array($year_day, $this->byyearday) || in_array($year_day_neg, $this->byyearday)))
{
return true;
}
else
{
return false;
}
}
// return the next valid DateTime object which matches the pattern and follows the rules
public function next()
{
// check the counter is set
if($this->count !== 0)
{
if($this->counter >= $this->count)
{
return false;
}
}
// create initial set of suggested dates
if(count($this->suggestions) === 0)
{
$this->create_suggestions();
}
// loop through the suggested dates
while(count($this->suggestions) > 0)
{
// get the first one on the array
$try_date = array_shift($this->suggestions);
// make sure the date doesn't exceed the max date
if($try_date > $this->end_date)
{
return false;
}
// make sure it falls within the allowed days
if($this->valid_date($try_date) === true)
{
$this->counter++;
return $try_date;
}
else
{
// we might be out of suggested days, so load some more
if(count($this->suggestions) === 0)
{
$this->create_suggestions();
}
}
}
}
}

@ -0,0 +1,18 @@
<?php
OC::$CLASSPATH['OC_Admin_Audit_Hooks_Handlers'] = 'apps/admin_audit/lib/hooks_handlers.php';
OCP\Util::connectHook('OCP\User', 'pre_login', 'OC_Admin_Audit_Hooks_Handlers', 'pre_login');
OCP\Util::connectHook('OCP\User', 'post_login', 'OC_Admin_Audit_Hooks_Handlers', 'post_login');
OCP\Util::connectHook('OCP\User', 'logout', 'OC_Admin_Audit_Hooks_Handlers', 'logout');
OCP\Util::connectHook(OC_Filesystem::CLASSNAME, OC_Filesystem::signal_rename, 'OC_Admin_Audit_Hooks_Handlers', 'rename');
OCP\Util::connectHook(OC_Filesystem::CLASSNAME, OC_Filesystem::signal_create, 'OC_Admin_Audit_Hooks_Handlers', 'create');
OCP\Util::connectHook(OC_Filesystem::CLASSNAME, OC_Filesystem::signal_copy, 'OC_Admin_Audit_Hooks_Handlers', 'copy');
OCP\Util::connectHook(OC_Filesystem::CLASSNAME, OC_Filesystem::signal_write, 'OC_Admin_Audit_Hooks_Handlers', 'write');
OCP\Util::connectHook(OC_Filesystem::CLASSNAME, OC_Filesystem::signal_read, 'OC_Admin_Audit_Hooks_Handlers', 'read');
OCP\Util::connectHook(OC_Filesystem::CLASSNAME, OC_Filesystem::signal_delete, 'OC_Admin_Audit_Hooks_Handlers', 'delete');
OCP\Util::connectHook('OC_Share', 'public', 'OC_Admin_Audit_Hooks_Handlers', 'share_public');
OCP\Util::connectHook('OC_Share', 'public-download', 'OC_Admin_Audit_Hooks_Handlers', 'share_public_download');
OCP\Util::connectHook('OC_Share', 'user', 'OC_Admin_Audit_Hooks_Handlers', 'share_user');

@ -0,0 +1,10 @@
<?xml version="1.0"?>
<info>
<id>admin_audit</id>
<name>Log audit info</name>
<version>0.1</version>
<licence>AGPL</licence>
<author>Bart Visscher</author>
<require>2</require>
<description>Audit user actions in Owncloud</description>
</info>

@ -0,0 +1,72 @@
<?php
class OC_Admin_Audit_Hooks_Handlers {
static public function pre_login($params) {
$path = $params['uid'];
self::log('Trying login '.$user);
}
static public function post_login($params) {
$path = $params['uid'];
self::log('Login '.$user);
}
static public function logout($params) {
$user = OCP\User::getUser();
self::log('Logout '.$user);
}
static public function rename($params) {
$oldpath = $params[OC_Filesystem::signal_param_oldpath];
$newpath = $params[OC_Filesystem::signal_param_newpath];
$user = OCP\User::getUser();
self::log('Rename "'.$oldpath.'" to "'.$newpath.'" by '.$user);
}
static public function create($params) {
$path = $params[OC_Filesystem::signal_param_path];
$user = OCP\User::getUser();
self::log('Create "'.$path.'" by '.$user);
}
static public function copy($params) {
$oldpath = $params[OC_Filesystem::signal_param_oldpath];
$newpath = $params[OC_Filesystem::signal_param_newpath];
$user = OCP\User::getUser();
self::log('Copy "'.$oldpath.'" to "'.$newpath.'" by '.$user);
}
static public function write($params) {
$path = $params[OC_Filesystem::signal_param_path];
$user = OCP\User::getUser();
self::log('Write "'.$path.'" by '.$user);
}
static public function read($params) {
$path = $params[OC_Filesystem::signal_param_path];
$user = OCP\User::getUser();
self::log('Read "'.$path.'" by '.$user);
}
static public function delete($params) {
$path = $params[OC_Filesystem::signal_param_path];
$user = OCP\User::getUser();
self::log('Delete "'.$path.'" by '.$user);
}
static public function share_public($params) {
$path = $params['source'];
$token = $params['token'];
$user = OCP\User::getUser();
self::log('Shared "'.$path.'" with public, token="'.$token.'" by '.$user);
}
static public function share_public_download($params) {
$path = $params['source'];
$token = $params['token'];
$user = $_SERVER['REMOTE_ADDR'];
self::log('Download of shared "'.$path.'" token="'.$token.'" by '.$user);
}
static public function share_user($params) {
$path = $params['source'];
$permissions = $params['permissions'];
$with = $params['with'];
$user = OCP\User::getUser();
$rw = $permissions & OC_Share::WRITE ? 'w' : 'o';
self::log('Shared "'.$path.'" (r'.$rw.') with user "'.$with.'" by '.$user);
}
static protected function log($msg) {
OCP\Util::writeLog('admin_audit', $msg, OCP\Util::INFO);
}
}

@ -5,20 +5,20 @@
*
* @author Arthur Schiwon
* @copyright 2011 Arthur Schiwon blizzz@arthur-schiwon.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
* 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
*
* 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/>.
*
*
*/
@ -28,6 +28,6 @@ OCP\User::checkLoggedIn();
OCP\App::checkAppEnabled('bookmarks');
require_once('bookmarksHelper.php');
addBookmark($_POST['url'], '', 'Read-Later');
addBookmark($_GET['url'], '', 'Read-Later');
include 'templates/addBm.php';

@ -40,18 +40,26 @@ if( $CONFIG_DBTYPE == 'sqlite' or $CONFIG_DBTYPE == 'sqlite3' ){
}
$bookmark_id = (int)$_POST["id"];
$user_id = OCP\USER::getUser();
$query = OCP\DB::prepare("
UPDATE *PREFIX*bookmarks
SET url = ?, title =?, lastmodified = $_ut
WHERE id = $bookmark_id
WHERE id = ?
AND user_id = ?
");
$params=array(
htmlspecialchars_decode($_POST["url"]),
htmlspecialchars_decode($_POST["title"]),
$bookmark_id,
$user_id,
);
$query->execute($params);
$result = $query->execute($params);
# Abort the operation if bookmark couldn't be set (probably because the user is not allowed to edit this bookmark)
if ($result->numRows() == 0) exit();
# Remove old tags and insert new ones.
$query = OCP\DB::prepare("
@ -66,7 +74,7 @@ $query = OCP\DB::prepare("
(bookmark_id, tag)
VALUES (?, ?)
");
$tags = explode(' ', urldecode($_POST["tags"]));
foreach ($tags as $tag) {
if(empty($tag)) {

@ -1,5 +1,5 @@
#content { overflow: auto; height: 100%; }
#firstrun { width: 80%; margin: 5em auto auto auto; text-align: center; font-weight:bold; font-size:1.5em; color:#777;}
#firstrun { width: 80%; margin: 5em auto auto auto; text-align: center; font-weight:bold; font-size:1.5em; color:#777; position: relative;}
#firstrun small { display: block; font-weight: normal; font-size: 0.5em; margin-bottom: 1.5em; }
#firstrun .button { font-size: 0.7em; }
#firstrun #selections { font-size:0.8em; font-weight: normal; width: 100%; margin: 2em auto auto auto; clear: both; }

@ -7,7 +7,7 @@
* See the COPYING-README file.
*/
?>
<input type="hidden" id="bookmarkFilterTag" value="<?php if(isset($_GET['tag'])) echo htmlentities($_GET['tag'],ENT_COMPAT,'utf-8'); ?>" />
<input type="hidden" id="bookmarkFilterTag" value="<?php if(isset($_GET['tag'])) echo OCP\Util::sanitizeHTML($_GET['tag']); ?>" />
<div id="controls">
<input type="hidden" id="bookmark_add_id" value="0" />
<input type="text" id="bookmark_add_url" placeholder="<?php echo $l->t('Address'); ?>" class="bookmarks_input" />

@ -0,0 +1,15 @@
<?php
/**
* Copyright (c) 2012 Georg Ehrke <georg@ownCloud.com>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
OCP\JSON::checkLoggedIn();
OCP\JSON::checkAppEnabled('calendar');
$calendars = OC_Calendar_Calendar::allCalendars(OCP\USER::getUser());
foreach($calendars as $calendar){
OC_Calendar_Repeat::cleancalendar($calendar['id']);
OC_Calendar_Repeat::generatecalendar($calendar['id']);
}
OCP\JSON::success();

@ -0,0 +1,22 @@
<?php
/**
* Copyright (c) 2012 Georg Ehrke <georg@ownCloud.com>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
OCP\JSON::checkLoggedIn();
OCP\JSON::checkAppEnabled('calendar');
$calendars = OC_Calendar_Calendar::allCalendars(OCP\USER::getUser());
$allcached = true;
foreach($calendars as $calendar){
if(!OC_Calendar_Repeat::is_calendar_cached($calendar['id'])){
$allcached = false;
}
}
$l = new OC_L10N('calendar');
if(!$allcached){
OCP\JSON::error(array('message'=>'Not all calendars are completely cached', 'l10n'=>$l->t('Not all calendars are completely cached')));
}else{
OCP\JSON::success(array('message'=>'Everything seems to be completely cached', 'l10n'=>$l->t('Everything seems to be completely cached')));
}

@ -20,4 +20,4 @@ $calendar = OC_Calendar_App::getCalendar($calendarid);
OCP\JSON::success(array(
'active' => $calendar['active'],
'eventSource' => OC_Calendar_Calendar::getEventSourceInfo($calendar),
));
));

@ -21,5 +21,4 @@ if($del == true){
OCP\JSON::success();
}else{
OCP\JSON::error(array('error'=>'dberror'));
}
?>
}

@ -16,5 +16,4 @@ $tmpl = new OCP\Template("calendar", "part.editcalendar");
$tmpl->assign('new', false);
$tmpl->assign('calendarcolor_options', $calendarcolor_options);
$tmpl->assign('calendar', $calendar);
$tmpl->printPage();
?>
$tmpl->printPage();

@ -20,5 +20,4 @@ $tmpl = new OCP\Template("calendar", "part.editcalendar");
$tmpl->assign('new', false);
$tmpl->assign('calendarcolor_options', $calendarcolor_options);
$tmpl->assign('calendar', $calendar);
$tmpl->printPage();
?>
$tmpl->printPage();

@ -19,5 +19,4 @@ $tmpl = new OCP\Template('calendar', 'part.editcalendar');
$tmpl->assign('new', true);
$tmpl->assign('calendarcolor_options', $calendarcolor_options);
$tmpl->assign('calendar', $calendar);
$tmpl->printPage();
?>
$tmpl->printPage();

@ -34,4 +34,4 @@ $tmpl->assign('calendar', $calendar);
OCP\JSON::success(array(
'page' => $tmpl->fetchPage(),
'eventSource' => OC_Calendar_Calendar::getEventSourceInfo($calendar),
));
));

@ -11,5 +11,4 @@ $l10n = OC_L10N::get('calendar');
OCP\JSON::checkLoggedIn();
OCP\JSON::checkAppEnabled('calendar');
$output = new OCP\Template("calendar", "part.choosecalendar");
$output -> printpage();
?>
$output -> printpage();

@ -39,4 +39,4 @@ $tmpl->assign('calendar', $calendar);
OCP\JSON::success(array(
'page' => $tmpl->fetchPage(),
'eventSource' => OC_Calendar_Calendar::getEventSourceInfo($calendar),
));
));

@ -39,4 +39,4 @@ if(count($events) == 0) {
OC_Calendar_App::scanCategories($events);
$categories = OC_Calendar_App::getCategoryOptions();
OCP\JSON::success(array('data' => array('categories'=>$categories)));
OCP\JSON::success(array('data' => array('categories'=>$categories)));

@ -18,5 +18,4 @@ switch($view){
exit;
}
OCP\Config::setUserValue(OCP\USER::getUser(), 'calendar', 'currentview', $view);
OCP\JSON::success();
?>
OCP\JSON::success();

@ -17,4 +17,4 @@ if($access != 'owner' && $access != 'rw'){
exit;
}
$result = OC_Calendar_Object::delete($id);
OCP\JSON::success();
OCP\JSON::success();

@ -27,6 +27,14 @@ $vevent = $object->VEVENT;
$dtstart = $vevent->DTSTART;
$dtend = OC_Calendar_Object::getDTEndFromVEvent($vevent);
switch($dtstart->getDateType()) {
case Sabre_VObject_Property_DateTime::UTC:
$timeOffset = OC_Calendar_App::$tz*60;
$newDT = $dtstart->getDateTime();
$newDT->add(new DateInterval("PT" . $timeOffset . "M"));
$dtstart->setDateTime($newDT);
$newDT = $dtend->getDateTime();
$newDT->add(new DateInterval("PT" . $timeOffset . "M"));
$dtend->setDateTime($newDT);
case Sabre_VObject_Property_DateTime::LOCALTZ:
case Sabre_VObject_Property_DateTime::LOCAL:
$startdate = $dtstart->getDateTime()->format('d-m-Y');
@ -261,4 +269,4 @@ if($repeat['repeat'] != 'doesnotrepeat'){
$tmpl->assign('repeat_date', '');
$tmpl->assign('repeat_year', 'bydate');
}
$tmpl->printpage();
$tmpl->printpage();

@ -42,5 +42,4 @@ if($errarr){
OC_Calendar_Object::moveToCalendar($id, $cal);
}
OCP\JSON::success();
}
?>
}

@ -43,4 +43,4 @@ $vevent->setDateTime('DTSTAMP', 'now', Sabre_VObject_Property_DateTime::UTC);
$result = OC_Calendar_Object::edit($id, $vcalendar->serialize());
$lastmodified = $vevent->__get('LAST-MODIFIED')->getDateTime();
OCP\JSON::success(array('lastmodified'=>(int)$lastmodified->format('U')));
OCP\JSON::success(array('lastmodified'=>(int)$lastmodified->format('U')));

@ -72,4 +72,4 @@ $tmpl->assign('repeat_count', '10');
$tmpl->assign('repeat_weekofmonth', 'auto');
$tmpl->assign('repeat_date', '');
$tmpl->assign('repeat_year', 'bydate');
$tmpl->printpage();
$tmpl->printpage();

@ -21,5 +21,4 @@ if($errarr){
$vcalendar = OC_Calendar_Object::createVCalendarFromRequest($_POST);
$result = OC_Calendar_Object::add($cal, $vcalendar->serialize());
OCP\JSON::success();
}
?>
}

@ -35,4 +35,4 @@ $vevent->setDateTime('DTSTAMP', 'now', Sabre_VObject_Property_DateTime::UTC);
OC_Calendar_Object::edit($id, $vcalendar->serialize());
$lastmodified = $vevent->__get('LAST-MODIFIED')->getDateTime();
OCP\JSON::success(array('lastmodified'=>(int)$lastmodified->format('U')));
OCP\JSON::success(array('lastmodified'=>(int)$lastmodified->format('U')));

@ -5,30 +5,26 @@
* later.
* See the COPYING-README file.
*/
require_once('when/When.php');
OCP\JSON::checkLoggedIn();
OCP\JSON::checkAppEnabled('calendar');
session_write_close();
// Look for the calendar id
$calendar_id = OC_Calendar_App::getCalendar($_GET['calendar_id'], false, false);
if($calendar_id !== false){
if(! is_numeric($calendar_id['userid']) && $calendar_id['userid'] != OCP\User::getUser()){
OCP\JSON::error();
exit;
$calendar_id = null;
if (strval(intval($_GET['calendar_id'])) == strval($_GET['calendar_id'])) { // integer for sure.
$id = intval($_GET['calendar_id']);
$calendarrow = OC_Calendar_App::getCalendar($id, true, false); // Let's at least security check otherwise we might as well use OC_Calendar_Calendar::find()
if($calendarrow !== false && is_int($calendar_id['userid']) && $id == $calendar_id['userid']) {
$calendar_id = $id;
}
}
else {
$calendar_id = $_GET['calendar_id'];
}
$calendar_id = (is_null($calendar_id)?strip_tags($_GET['calendar_id']):$calendar_id);
$start = (version_compare(PHP_VERSION, '5.3.0', '>='))?DateTime::createFromFormat('U', $_GET['start']):new DateTime('@' . $_GET['start']);
$end = (version_compare(PHP_VERSION, '5.3.0', '>='))?DateTime::createFromFormat('U', $_GET['end']):new DateTime('@' . $_GET['end']);
$events = OC_Calendar_App::getrequestedEvents($calendar_id, $start, $end);
$events = OC_Calendar_App::getrequestedEvents($_GET['calendar_id'], $start, $end);
$output = array();
foreach($events as $event){
$output = array_merge($output, OC_Calendar_App::generateEventOutput($event, $start, $end));
}
OCP\JSON::encodedPrint($output);
OCP\JSON::encodedPrint(OCP\Util::sanitizeHTML($output));

@ -12,5 +12,4 @@ OCP\App::checkAppEnabled('calendar');
$tmpl = new OCP\Template('calendar', 'part.import');
$tmpl->assign('path', $_POST['path']);
$tmpl->assign('filename', $_POST['filename']);
$tmpl->printpage();
?>
$tmpl->printpage();

@ -45,7 +45,7 @@ foreach($lines as $line) {
}
$i++;
}
$calendars = OC_Calendar_Calendar::allCalendars(OCP\USER::getUser(), 1);
$calendars = OC_Calendar_Calendar::allCalendars(OCP\USER::getUser(), true);
$id = $calendars[0]['id'];
foreach($uids as $uid) {
$prefix=$suffix=$content=array();
@ -70,5 +70,4 @@ foreach($uids as $uid) {
OC_Calendar_Object::add($id, $import);
}
}
OCP\JSON::success();
?>
OCP\JSON::success();

@ -119,4 +119,4 @@ foreach($uids as $uid) {
writeProgress('100');
sleep(3);
OC_Cache::remove($progresskey);
OCP\JSON::success();
OCP\JSON::success();

@ -8,5 +8,4 @@
OCP\JSON::checkLoggedIn();
$firstday = OCP\Config::getUserValue( OCP\USER::getUser(), 'calendar', 'firstday', 'mo');
OCP\JSON::encodedPrint(array('firstday' => $firstday));
?>
OCP\JSON::encodedPrint(array('firstday' => $firstday));

@ -23,5 +23,4 @@ if($timezone == OCP\Config::getUserValue(OCP\USER::getUser(), 'calendar', 'timez
}
OCP\Config::setUserValue(OCP\USER::getUser(), 'calendar', 'timezone', $timezone);
$message = array('message'=> $l->t('New Timezone:') . $timezone);
OCP\JSON::success($message);
?>
OCP\JSON::success($message);

@ -12,6 +12,4 @@ if(isset($_POST["firstday"])){
OCP\JSON::success();
}else{
OCP\JSON::error();
}
?>
}

@ -12,6 +12,4 @@ if(isset($_POST["timeformat"])){
OCP\JSON::success();
}else{
OCP\JSON::error();
}
?>
}

@ -22,6 +22,4 @@ if( isset( $_POST['timezone'] ) ){
OCP\JSON::success(array('data' => array( 'message' => $l->t('Timezone changed') )));
}else{
OCP\JSON::error(array('data' => array( 'message' => $l->t('Invalid request') )));
}
?>
}

@ -8,5 +8,4 @@
OCP\JSON::checkLoggedIn();
$timeformat = OCP\Config::getUserValue( OCP\USER::getUser(), 'calendar', 'timeformat', "24");
OCP\JSON::encodedPrint(array("timeformat" => $timeformat));
?>
OCP\JSON::encodedPrint(array("timeformat" => $timeformat));

@ -5,9 +5,15 @@ 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_Calendar_Repeat'] = 'apps/calendar/lib/repeat.php';
OC::$CLASSPATH['OC_Calendar_Share'] = 'apps/calendar/lib/share.php';
OC::$CLASSPATH['OC_Search_Provider_Calendar'] = 'apps/calendar/lib/search.php';
OCP\Util::connectHook('OC_User', 'post_deleteUser', 'OC_Calendar_Hooks', 'deleteUser');
OCP\Util::connectHook('OC_Calendar', 'addEvent', 'OC_Calendar_Repeat', 'generate');
OCP\Util::connectHook('OC_Calendar', 'editEvent', 'OC_Calendar_Repeat', 'update');
OCP\Util::connectHook('OC_Calendar', 'deleteEvent', 'OC_Calendar_Repeat', 'clean');
OCP\Util::connectHook('OC_Calendar', 'moveEvent', 'OC_Calendar_Repeat', 'update');
OCP\Util::connectHook('OC_Calendar', 'deleteCalendar', 'OC_Calendar_Repeat', 'cleanCalendar');
OCP\Util::addscript('calendar','loader');
OCP\Util::addscript("3rdparty", "chosen/chosen.jquery.min");
OCP\Util::addStyle("3rdparty", "chosen/chosen");

@ -290,4 +290,56 @@
</table>
<table>
<name>*dbprefix*calendar_repeat</name>
<declaration>
<field>
<name>id</name>
<type>integer</type>
<default>0</default>
<notnull>true</notnull>
<autoincrement>1</autoincrement>
<unsigned>true</unsigned>
<length>4</length>
</field>
<field>
<name>eventid</name>
<type>integer</type>
<default>0</default>
<notnull>true</notnull>
<unsigned>true</unsigned>
<length>4</length>
</field>
<field>
<name>calid</name>
<type>integer</type>
<default>0</default>
<notnull>true</notnull>
<unsigned>true</unsigned>
<length>4</length>
</field>
<field>
<name>startdate</name>
<type>timestamp</type>
<default>0000-00-00 00:00:00</default>
<notnull>false</notnull>
</field>
<field>
<name>enddate</name>
<type>timestamp</type>
<default>0000-00-00 00:00:00</default>
<notnull>false</notnull>
</field>
</declaration>
</table>
</database>

@ -14,4 +14,11 @@ if (version_compare($installedVersion, '0.2.1', '<')) {
$stmt = OCP\DB::prepare( 'UPDATE *PREFIX*calendar_calendars SET calendarcolor=? WHERE id=?' );
$r = $stmt->execute(array($color,$id));
}
}
if (version_compare($installedVersion, '0.5', '<')) {
$calendars = OC_Calendar_Calendar::allCalendars(OCP\USER::getUser());
foreach($calendars as $calendar){
OC_Calendar_Repeat::cleanCalendar($calendar['id']);
OC_Calendar_Repeat::generateCalendar($calendar['id']);
}
}

@ -11,15 +11,17 @@ OCP\User::checkLoggedIn();
OCP\App::checkAppEnabled('calendar');
// Create default calendar ...
$calendars = OC_Calendar_Calendar::allCalendars(OCP\USER::getUser(), 1);
$calendars = OC_Calendar_Calendar::allCalendars(OCP\USER::getUser(), false);
if( count($calendars) == 0){
OC_Calendar_Calendar::addCalendar(OCP\USER::getUser(),'Default calendar');
$calendars = OC_Calendar_Calendar::allCalendars(OCP\USER::getUser(), 1);
$calendars = OC_Calendar_Calendar::allCalendars(OCP\USER::getUser(), true);
}
$eventSources = array();
foreach($calendars as $calendar){
$eventSources[] = OC_Calendar_Calendar::getEventSourceInfo($calendar);
if($calendar['active'] == 1) {
$eventSources[] = OC_Calendar_Calendar::getEventSourceInfo($calendar);
}
}
$eventSources[] = array('url' => '?app=calendar&getfile=ajax/events.php?calendar_id=shared_rw', 'backgroundColor' => '#1D2D44', 'borderColor' => '#888', 'textColor' => 'white', 'editable'=>'true');

@ -430,6 +430,7 @@ Calendar={
$('#calendar_holder').fullCalendar('removeEventSource', url);
$('#choosecalendar_dialog').dialog('destroy').remove();
Calendar.UI.Calendar.overview();
$('#calendar_holder').fullCalendar('refetchEvents');
}
});
}
@ -868,7 +869,7 @@ $(document).ready(function(){
eventDrop: Calendar.UI.moveEvent,
eventResize: Calendar.UI.resizeEvent,
eventRender: function(event, element) {
element.find('.fc-event-title').html(element.find('.fc-event-title').text());
element.find('.fc-event-title').html(element.find('.fc-event-title').html());
element.tipsy({
className: 'tipsy-event',
opacity: 0.9,

@ -44,4 +44,24 @@ $(document).ready(function(){
$('#' + jsondata.firstday).attr('selected',true);
$('#firstday').chosen();
});
$('#cleancalendarcache').click(function(){
$.getJSON(OC.filePath('calendar', 'ajax/cache', 'rescan.php'), function(){
calendarcachecheck();
});
});
calendarcachecheck();
});
function calendarcachecheck(){
$.getJSON(OC.filePath('calendar', 'ajax/cache', 'status.php'), function(jsondata, status) {
$('#cleancalendarcache').attr('title', jsondata.l10n.text);
if(jsondata.status == 'success'){
$('#cleancalendarcache').css('background', '#90EE90');
$('#cleancalendarcache').css('color', '#333');
$('#cleancalendarcache').css('text-shadow', '#fff 0 1px 0');
}else{
$('#cleancalendarcache').css('background', '#DC143C');
$('#cleancalendarcache').css('color', '#FFFFFF');
$('#cleancalendarcache').css('text-shadow', '0px 0px 0px #fff, 0px 0px #fff');
}
});
}

@ -50,10 +50,7 @@ class OC_Calendar_App{
return false;
}
}
if($calendar === false){
return false;
}
return OC_Calendar_Calendar::find($id);
return $calendar;
}
/*
@ -119,8 +116,7 @@ class OC_Calendar_App{
* @brief returns the default categories of ownCloud
* @return (array) $categories
*/
protected static function getDefaultCategories()
{
protected static function getDefaultCategories(){
return array(
self::$l10n->t('Birthday'),
self::$l10n->t('Business'),
@ -155,8 +151,7 @@ class OC_Calendar_App{
* @brief returns the categories of the vcategories object
* @return (array) $categories
*/
public static function getCategoryOptions()
{
public static function getCategoryOptions(){
$categories = self::getVCategories()->categories();
return $categories;
}
@ -343,6 +338,9 @@ class OC_Calendar_App{
$singleevents = OC_Calendar_Share::allSharedwithuser(OCP\USER::getUser(), OC_Calendar_Share::EVENT, 1, ($_GET['calendar_id'] == 'shared_rw')?'rw':'r');
foreach($singleevents as $singleevent){
$event = OC_Calendar_Object::find($singleevent['eventid']);
if(!array_key_exists('summary', $event)){
$event['summary'] = self::$l10n->t('unnamed');
}
$event['summary'] .= ' (' . self::$l10n->t('by') . ' ' . OC_Calendar_Object::getowner($event['id']) . ')';
$events[] = $event;
}
@ -362,94 +360,57 @@ class OC_Calendar_App{
/*
* @brief generates the output for an event which will be readable for our js
* @param (mixed) $event - event object / array
* @param (int) $start - unixtimestamp of start
* @param (int) $end - unixtimestamp of end
* @param (int) $start - DateTime object of start
* @param (int) $end - DateTime object of end
* @return (array) $output - readable output
*/
public static function generateEventOutput($event, $start, $end){
$output = array();
if(isset($event['calendardata'])){
$object = OC_VObject::parse($event['calendardata']);
$vevent = $object->VEVENT;
}else{
$vevent = $event['vevent'];
}
$return = array();
$id = $event['id'];
$allday = ($vevent->DTSTART->getDateType() == Sabre_VObject_Element_DateTime::DATE)?true:false;
$last_modified = @$vevent->__get('LAST-MODIFIED');
$lastmodified = ($last_modified)?$last_modified->getDateTime()->format('U'):0;
$output = array('id'=>(int)$event['id'],
'title' => ($event['summary']!=NULL || $event['summary'] != '')?$event['summary']: self::$l10n->t('unnamed'),
'description' => isset($vevent->DESCRIPTION)?$vevent->DESCRIPTION->value:'',
'lastmodified'=>$lastmodified);
$dtstart = $vevent->DTSTART;
$start_dt = $dtstart->getDateTime();
$dtend = OC_Calendar_Object::getDTEndFromVEvent($vevent);
$end_dt = $dtend->getDateTime();
if ($dtstart->getDateType() == Sabre_VObject_Element_DateTime::DATE){
$output['allDay'] = true;
}else{
$output['allDay'] = false;
$start_dt->setTimezone(new DateTimeZone(self::$tz));
$end_dt->setTimezone(new DateTimeZone(self::$tz));
}
// Handle exceptions to recurring events
$exceptionDateObjects = $vevent->select('EXDATE');
$exceptionDateMap = Array();
foreach ($exceptionDateObjects as $exceptionObject) {
foreach($exceptionObject->getDateTimes() as $datetime) {
$ts = $datetime->getTimestamp();
$exceptionDateMap[idate('Y',$ts)][idate('m', $ts)][idate('d', $ts)] = true;
}
}
$return = array();
if($event['repeating'] == 1){
$duration = (double) $end_dt->format('U') - (double) $start_dt->format('U');
$r = new When();
$r->recur($start_dt)->rrule((string) $vevent->RRULE);
/*$r = new iCal_Repeat_Generator(array('RECUR' => $start_dt,
* 'RRULE' => (string)$vevent->RRULE
* 'RDATE' => (string)$vevent->RDATE
* 'EXRULE' => (string)$vevent->EXRULE
* 'EXDATE' => (string)$vevent->EXDATE));*/
while($result = $r->next()){
if($result < $start){
continue;
}
if($result > $end){
break;
}
// Check for exceptions to recurring events
$ts = $result->getTimestamp();
if (isset($exceptionDateMap[idate('Y',$ts)][idate('m', $ts)][idate('d', $ts)])) {
continue;
}
unset($ts);
if($output['allDay'] == true){
$output['start'] = $result->format('Y-m-d');
$output['end'] = date('Y-m-d', $result->format('U') + --$duration);
$staticoutput = array('id'=>(int)$event['id'],
'title' => htmlspecialchars(($event['summary']!=NULL || $event['summary'] != '')?$event['summary']: self::$l10n->t('unnamed')),
'description' => isset($vevent->DESCRIPTION)?htmlspecialchars($vevent->DESCRIPTION->value):'',
'lastmodified'=>$lastmodified,
'allDay'=>$allday);
if(OC_Calendar_Object::isrepeating($id) && OC_Calendar_Repeat::is_cached_inperiod($event['id'], $start, $end)){
$cachedinperiod = OC_Calendar_Repeat::get_inperiod($id, $start, $end);
foreach($cachedinperiod as $cachedevent){
$dynamicoutput = array();
if($allday){
$start_dt = new DateTime($cachedevent['startdate'], new DateTimeZone('UTC'));
$end_dt = new DateTime($cachedevent['enddate'], new DateTimeZone('UTC'));
$dynamicoutput['start'] = $start_dt->format('Y-m-d');
$dynamicoutput['end'] = $end_dt->format('Y-m-d');
}else{
$output['start'] = $result->format('Y-m-d H:i:s');
$output['end'] = date('Y-m-d H:i:s', $result->format('U') + $duration);
$start_dt = new DateTime($cachedevent['startdate'], new DateTimeZone('UTC'));
$end_dt = new DateTime($cachedevent['enddate'], new DateTimeZone('UTC'));
$start_dt->setTimezone(new DateTimeZone(self::$tz));
$end_dt->setTimezone(new DateTimeZone(self::$tz));
$dynamicoutput['start'] = $start_dt->format('Y-m-d H:i:s');
$dynamicoutput['end'] = $end_dt->format('Y-m-d H:i:s');
}
$return[] = $output;
$return[] = array_merge($staticoutput, $dynamicoutput);
}
}else{
if($output['allDay'] == true){
$output['start'] = $start_dt->format('Y-m-d');
$end_dt->modify('-1 sec');
$output['end'] = $end_dt->format('Y-m-d');
}else{
$output['start'] = $start_dt->format('Y-m-d H:i:s');
$output['end'] = $end_dt->format('Y-m-d H:i:s');
if(OC_Calendar_Object::isrepeating($id)){
$object->expand($start, $end);
}
foreach($object->getComponents() as $singleevent){
if(!($singleevent instanceof Sabre_VObject_Component_VEvent)){
continue;
}
$dynamicoutput = OC_Calendar_Object::generateStartEndDate($singleevent->DTSTART, OC_Calendar_Object::getDTEndFromVEvent($singleevent), $allday, self::$tz);
$return[] = array_merge($staticoutput, $dynamicoutput);
}
$return[] = $output;
}
return $return;
}

@ -44,13 +44,13 @@ class OC_Calendar_Calendar{
/**
* @brief Returns the list of calendars for a specific user.
* @param string $uid User ID
* @param boolean $active Only return calendars with this $active state, default(=null) is don't care
* @param boolean $active Only return calendars with this $active state, default(=false) is don't care
* @return array
*/
public static function allCalendars($uid, $active=null){
public static function allCalendars($uid, $active=false){
$values = array($uid);
$active_where = '';
if (!is_null($active) && $active){
if ($active){
$active_where = ' AND active = ?';
$values[] = $active;
}
@ -109,7 +109,10 @@ class OC_Calendar_Calendar{
$stmt = OCP\DB::prepare( 'INSERT INTO *PREFIX*calendar_calendars (userid,displayname,uri,ctag,calendarorder,calendarcolor,timezone,components) VALUES(?,?,?,?,?,?,?,?)' );
$result = $stmt->execute(array($userid,$name,$uri,1,$order,$color,$timezone,$components));
return OCP\DB::insertid('*PREFIX*calendar_calendars');
$insertid = OCP\DB::insertid('*PREFIX*calendar_calendars');
OCP\Util::emitHook('OC_Calendar', 'addCalendar', $insertid);
return $insertid;
}
/**
@ -129,7 +132,10 @@ class OC_Calendar_Calendar{
$stmt = OCP\DB::prepare( 'INSERT INTO *PREFIX*calendar_calendars (userid,displayname,uri,ctag,calendarorder,calendarcolor,timezone,components) VALUES(?,?,?,?,?,?,?,?)' );
$result = $stmt->execute(array($userid,$name,$uri,1,$order,$color,$timezone,$components));
return OCP\DB::insertid('*PREFIX*calendar_calendars');
$insertid = OCP\DB::insertid('*PREFIX*calendar_calendars');
OCP\Util::emitHook('OC_Calendar', 'addCalendar', $insertid);
return $insertid;
}
/**
@ -158,6 +164,7 @@ class OC_Calendar_Calendar{
$stmt = OCP\DB::prepare( 'UPDATE *PREFIX*calendar_calendars SET displayname=?,calendarorder=?,calendarcolor=?,timezone=?,components=?,ctag=ctag+1 WHERE id=?' );
$result = $stmt->execute(array($name,$order,$color,$timezone,$components,$id));
OCP\Util::emitHook('OC_Calendar', 'editCalendar', $id);
return true;
}
@ -198,6 +205,11 @@ class OC_Calendar_Calendar{
$stmt = OCP\DB::prepare( 'DELETE FROM *PREFIX*calendar_objects WHERE calendarid = ?' );
$stmt->execute(array($id));
OCP\Util::emitHook('OC_Calendar', 'deleteCalendar', $id);
if(count(self::allCalendars()) == 0) {
self::addCalendar(OCP\USER::getUser(),'Default calendar');
}
return true;
}

@ -108,7 +108,7 @@ class OC_Calendar_Object{
$object_id = OCP\DB::insertid('*PREFIX*calendar_objects');
OC_Calendar_Calendar::touchCalendar($id);
OCP\Util::emitHook('OC_Calendar', 'addEvent', $object_id);
return $object_id;
}
@ -128,7 +128,7 @@ class OC_Calendar_Object{
$object_id = OCP\DB::insertid('*PREFIX*calendar_objects');
OC_Calendar_Calendar::touchCalendar($id);
OCP\Util::emitHook('OC_Calendar', 'addEvent', $object_id);
return $object_id;
}
@ -149,6 +149,7 @@ class OC_Calendar_Object{
$stmt->execute(array($type,$startdate,$enddate,$repeating,$summary,$data,time(),$id));
OC_Calendar_Calendar::touchCalendar($oldobject['calendarid']);
OCP\Util::emitHook('OC_Calendar', 'editEvent', $id);
return true;
}
@ -170,6 +171,7 @@ class OC_Calendar_Object{
$stmt->execute(array($type,$startdate,$enddate,$repeating,$summary,$data,time(),$oldobject['id']));
OC_Calendar_Calendar::touchCalendar($oldobject['calendarid']);
OCP\Util::emitHook('OC_Calendar', 'editEvent', $oldobject['id']);
return true;
}
@ -184,6 +186,7 @@ class OC_Calendar_Object{
$stmt = OCP\DB::prepare( 'DELETE FROM *PREFIX*calendar_objects WHERE id = ?' );
$stmt->execute(array($id));
OC_Calendar_Calendar::touchCalendar($oldobject['calendarid']);
OCP\Util::emitHook('OC_Calendar', 'deleteEvent', $id);
return true;
}
@ -195,9 +198,11 @@ class OC_Calendar_Object{
* @return boolean
*/
public static function deleteFromDAVData($cid,$uri){
$oldobject = self::findWhereDAVDataIs($cid, $uri);
$stmt = OCP\DB::prepare( 'DELETE FROM *PREFIX*calendar_objects WHERE calendarid = ? AND uri=?' );
$stmt->execute(array($cid,$uri));
OC_Calendar_Calendar::touchCalendar($cid);
OCP\Util::emitHook('OC_Calendar', 'deleteEvent', $oldobject['id']);
return true;
}
@ -207,6 +212,7 @@ class OC_Calendar_Object{
$stmt->execute(array($calendarid,$id));
OC_Calendar_Calendar::touchCalendar($id);
OCP\Util::emitHook('OC_Calendar', 'moveEvent', $id);
return true;
}
@ -294,12 +300,11 @@ class OC_Calendar_Object{
* This function creates a date string that can be used by MDB2.
* Furthermore it converts the time to UTC.
*/
protected static function getUTCforMDB($datetime){
public static function getUTCforMDB($datetime){
return date('Y-m-d H:i', $datetime->format('U') - $datetime->getOffset());
}
public static function getDTEndFromVEvent($vevent)
{
public static function getDTEndFromVEvent($vevent){
if ($vevent->DTEND) {
$dtend = $vevent->DTEND;
}else{
@ -600,8 +605,8 @@ class OC_Calendar_Object{
public static function updateVCalendarFromRequest($request, $vcalendar)
{
$title = strip_tags($request["title"]);
$location = strip_tags($request["location"]);
$title = $request["title"];
$location = $request["location"];
$categories = $request["categories"];
$allday = isset($request["allday"]);
$from = $request["from"];
@ -611,7 +616,7 @@ class OC_Calendar_Object{
$totime = $request['totime'];
}
$vevent = $vcalendar->VEVENT;
$description = strip_tags($request["description"]);
$description = $request["description"];
$repeat = $request["repeat"];
if($repeat != 'doesnotrepeat'){
$rrule = '';
@ -796,4 +801,29 @@ class OC_Calendar_Object{
$event = self::find($id);
return $event['calendarid'];
}
public static function isrepeating($id){
$event = self::find($id);
return ($event['repeating'] == 1)?true:false;
}
public static function generateStartEndDate($dtstart, $dtend, $allday, $tz){
$start_dt = $dtstart->getDateTime();
$end_dt = $dtend->getDateTime();
$return = array();
if($allday){
$return['start'] = $start_dt->format('Y-m-d');
$end_dt->modify('-1 minute');
while($start_dt >= $end_dt){
$end_dt->modify('+1 day');
}
$return['end'] = $end_dt->format('Y-m-d');
}else{
$start_dt->setTimezone(new DateTimeZone($tz));
$end_dt->setTimezone(new DateTimeZone($tz));
$return['start'] = $start_dt->format('Y-m-d H:i:s');
$return['end'] = $end_dt->format('Y-m-d H:i:s');
}
return $return;
}
}

@ -0,0 +1,204 @@
<?php
/**
* Copyright (c) 2012 Georg Ehrke <ownclouddev@georgswebsite.de>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
/*
* This class manages the caching of repeating events
* Events will be cached for the current year ± 5 years
*/
class OC_Calendar_Repeat{
/*
* @brief returns the cache of an event
* @param (int) $id - id of the event
* @return (array)
*/
public static function get($id){
$stmt = OCP\DB::prepare('SELECT * FROM *PREFIX*calendar_repeat WHERE eventid = ?');
$result = $stmt->execute(array($id));
$return = array();
while($row = $result->fetchRow()){
$return[] = $row;
}
return $return;
}
/*
* @brief returns the cache of an event in a specific peroid
* @param (int) $id - id of the event
* @param (DateTime) $from - start for period in UTC
* @param (DateTime) $until - end for period in UTC
* @return (array)
*/
public static function get_inperiod($id, $from, $until){
$stmt = OCP\DB::prepare( 'SELECT * FROM *PREFIX*calendar_repeat WHERE eventid = ?'
.' AND ((startdate >= ? AND startdate <= ?)'
.' OR (enddate >= ? AND enddate <= ?))');
$result = $stmt->execute(array($id,
OC_Calendar_Object::getUTCforMDB($from), OC_Calendar_Object::getUTCforMDB($until),
OC_Calendar_Object::getUTCforMDB($from), OC_Calendar_Object::getUTCforMDB($until)));
$return = array();
while($row = $result->fetchRow()){
$return[] = $row;
}
return $return;
}
/*
* @brief returns the cache of all repeating events of a calendar
* @param (int) $id - id of the calendar
* @return (array)
*/
public static function getCalendar($id){
$stmt = OCP\DB::prepare('SELECT * FROM *PREFIX*calendar_repeat WHERE calid = ?');
$result = $stmt->execute(array($id));
$return = array();
while($row = $result->fetchRow()){
$return[] = $row;
}
return $return;
}
/*
* @brief returns the cache of all repeating events of a calendar in a specific period
* @param (int) $id - id of the event
* @param (string) $from - start for period in UTC
* @param (string) $until - end for period in UTC
* @return (array)
*/
public static function getCalendar_inperiod($id, $from, $until){
$stmt = OCP\DB::prepare( 'SELECT * FROM *PREFIX*calendar_repeat WHERE calid = ?'
.' AND ((startdate >= ? AND startdate <= ?)'
.' OR (enddate >= ? AND enddate <= ?))');
$result = $stmt->execute(array($id,
$from, $until,
$from, $until));
$return = array();
while($row = $result->fetchRow()){
$return[] = $row;
}
return $return;
}
/*
* @brief generates the cache the first time
* @param (int) id - id of the event
* @return (bool)
*/
public static function generate($id){
$event = OC_Calendar_Object::find($id);
if($event['repeating'] == 0){
return false;
}
$object = OC_VObject::parse($event['calendardata']);
$start = new DateTime('01-01-' . date('Y') . ' 00:00:00', new DateTimeZone('UTC'));
$start->modify('-5 years');
$end = new DateTime('31-12-' . date('Y') . ' 23:59:59', new DateTimeZone('UTC'));
$end->modify('+5 years');
$object->expand($start, $end);
foreach($object->getComponents() as $vevent){
if(!($vevent instanceof Sabre_VObject_Component_VEvent)){
continue;
}
$startenddate = OC_Calendar_Object::generateStartEndDate($vevent->DTSTART, OC_Calendar_Object::getDTEndFromVEvent($vevent), ($vevent->DTSTART->getDateType() == Sabre_VObject_Element_DateTime::DATE)?true:false, 'UTC');
$stmt = OCP\DB::prepare('INSERT INTO *PREFIX*calendar_repeat (eventid,calid,startdate,enddate) VALUES(?,?,?,?)');
$stmt->execute(array($id,OC_Calendar_Object::getCalendarid($id),$startenddate['start'],$startenddate['end']));
}
return true;
}
/*
* @brief generates the cache the first time for all repeating event of an calendar
* @param (int) id - id of the calendar
* @return (bool)
*/
public static function generateCalendar($id){
$allobjects = OC_Calendar_Object::all($id);
foreach($allobjects as $event){
self::generate($event['id']);
}
return true;
}
/*
* @brief updates an event that is already cached
* @param (int) id - id of the event
* @return (bool)
*/
public static function update($id){
self::clean($id);
self::generate($id);
return true;
}
/*
* @brief updates all repating events of a calendar that are already cached
* @param (int) id - id of the calendar
* @return (bool)
*/
public static function updateCalendar($id){
self::cleanCalendar($id);
self::generateCalendar($id);
return true;
}
/*
* @brief checks if an event is already cached
* @param (int) id - id of the event
* @return (bool)
*/
public static function is_cached($id){
if(count(self::get($id)) != 0){
return true;
}else{
return false;
}
}
/*
* @brief checks if an event is already cached in a specific period
* @param (int) id - id of the event
* @param (DateTime) $from - start for period in UTC
* @param (DateTime) $until - end for period in UTC
* @return (bool)
*/
public static function is_cached_inperiod($id, $start, $end){
if(count(self::get_inperiod($id, $start, $end)) != 0){
return true;
}else{
return false;
}
}
/*
* @brief checks if a whole calendar is already cached
* @param (int) id - id of the calendar
* @return (bool)
*/
public static function is_calendar_cached($id){
$cachedevents = count(self::getCalendar($id));
$repeatingevents = 0;
$allevents = OC_Calendar_Object::all($id);
foreach($allevents as $event){
if($event['repeating'] === 1){
$repeatingevents++;
}
}
if($cachedevents < $repeatingevents){
return false;
}else{
return true;
}
}
/*
* @brief removes the cache of an event
* @param (int) id - id of the event
* @return (bool)
*/
public static function clean($id){
$stmt = OCP\DB::prepare('DELETE FROM *PREFIX*calendar_repeat WHERE eventid = ?');
$stmt->execute(array($id));
}
/*
* @brief removes the cache of all events of a calendar
* @param (int) id - id of the calendar
* @return (bool)
*/
public static function cleanCalendar($id){
$stmt = OCP\DB::prepare('DELETE FROM *PREFIX*calendar_repeat WHERE calid = ?');
$stmt->execute(array($id));
}
}

@ -1,7 +1,7 @@
<?php
class OC_Search_Provider_Calendar extends OC_Search_Provider{
function search($query){
$calendars = OC_Calendar_Calendar::allCalendars(OCP\USER::getUser(), 1);
$calendars = OC_Calendar_Calendar::allCalendars(OCP\USER::getUser(), true);
if(count($calendars)==0 || !OCP\App::isEnabled('calendar')){
//return false;
}

@ -1,7 +1,7 @@
<?php
/**
* Copyright (c) 2011 Bart Visscher <bartv@thisnet.nl>
* Copyright (c) 2011 Georg Ehrke <ownclouddev at georgswebsite dot de>
* Copyright (c) 2012 Georg Ehrke <ownclouddev at georgswebsite dot de>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
@ -44,7 +44,11 @@
</select>
</td></tr>
</table>
<tr><td><label for="" class="bold"><?php echo $l->t('Cache');?></label></td><td>
<input id="cleancalendarcache" type="button" class="button" value="<?php echo $l->t('Clear cache for repeating events');?>">
</td></tr>
</table>
<?php echo $l->t('Calendar CalDAV syncing addresses'); ?> (<a href="http://owncloud.org/synchronisation/" target="_blank"><?php echo $l->t('more info'); ?></a>)
<dl>

@ -47,4 +47,4 @@ if(!$id) {
exit();
}
OCP\JSON::success(array('data' => array( 'id' => $id )));
OCP\JSON::success(array('data' => array( 'id' => $id, 'aid' => $aid )));

@ -6,15 +6,54 @@
* See the COPYING-README file.
*/
function cmp($a, $b)
{
if ($a['displayname'] == $b['displayname']) {
return 0;
}
return ($a['displayname'] < $b['displayname']) ? -1 : 1;
}
OCP\JSON::checkLoggedIn();
OCP\JSON::checkAppEnabled('contacts');
$ids = OC_Contacts_Addressbook::activeIds(OCP\USER::getUser());
$contacts = OC_Contacts_VCard::all($ids);
$active_addressbooks = OC_Contacts_Addressbook::active(OCP\USER::getUser());
error_log('active_addressbooks: '.print_r($active_addressbooks, true));
$contacts_addressbook = array();
$ids = array();
foreach($active_addressbooks as $addressbook) {
$ids[] = $addressbook['id'];
if(!isset($contacts_addressbook[$addressbook['id']])) {
$contacts_addressbook[$addressbook['id']] = array('contacts' => array());
$contacts_addressbook[$addressbook['id']]['displayname'] = $addressbook['displayname'];
}
}
error_log('ids: '.print_r($ids, true));
$contacts_alphabet = OC_Contacts_VCard::all($ids);
error_log('contacts_alphabet: '.print_r($contacts_alphabet, true));
// Our new array for the contacts sorted by addressbook
foreach($contacts_alphabet as $contact) {
if(!isset($contacts_addressbook[$contact['addressbookid']])) { // It should never execute.
$contacts_addressbook[$contact['addressbookid']] = array('contacts' => array());
}
$display = trim($contact['fullname']);
if(!$display) {
$vcard = OC_Contacts_App::getContactVCard($contact['id']);
if(!is_null($vcard)) {
$struct = OC_Contacts_VCard::structureContact($vcard);
$display = isset($struct['EMAIL'][0])?$struct['EMAIL'][0]['value']:'[UNKNOWN]';
}
}
$contacts_addressbook[$contact['addressbookid']]['contacts'][] = array('id' => $contact['id'], 'addressbookid' => $contact['addressbookid'], 'displayname' => htmlspecialchars($display));
}
uasort($contacts_addressbook, 'cmp');
$tmpl = new OCP\Template("contacts", "part.contacts");
$tmpl->assign('contacts', $contacts);
$tmpl->assign('books', $contacts_addressbook, false);
$page = $tmpl->fetchPage();
OCP\JSON::success(array('data' => array( 'page' => $page )));
?>

@ -20,7 +20,18 @@ if($checksum) {
$line = OC_Contacts_App::getPropertyLineByChecksum($vcard, $checksum);
$element = $vcard->children[$line];
$adr = OC_Contacts_VCard::structureProperty($element);
$tmpl->assign('adr',$adr);
$types = array();
if(isset($adr['parameters']['TYPE'])) {
if(is_array($adr['parameters']['TYPE'])) {
$types = array_map('htmlspecialchars', $adr['parameters']['TYPE']);
$types = array_map('strtoupper', $types);
} else {
$types = array(strtoupper(htmlspecialchars($adr['parameters']['TYPE'])));
}
}
$tmpl->assign('types', $types, false);
$adr = array_map('htmlspecialchars', $adr['value']);
$tmpl->assign('adr', $adr, false);
}
$tmpl->assign('id',$id);

@ -28,8 +28,9 @@ if($id) {
$name = OC_Contacts_VCard::structureProperty($property);
}
}
$tmpl->assign('name',$name);
$tmpl->assign('id',$id);
$name = array_map('htmlspecialchars', $name['value']);
$tmpl->assign('name',$name, false);
$tmpl->assign('id',$id, false);
} else {
bailOut(OC_Contacts_App::$l10n->t('Contact ID is missing.'));
}

@ -2,9 +2,12 @@
font-weight: bold;
}*/
#leftcontent { top: 3.5em !important; padding: 0; margin: 0; }
#leftcontent a { padding: 0 0 0 25px; }
#rightcontent { top: 3.5em !important; padding-top: 5px; }
#contacts { background: #fff; width: 20em; left: 12.5em; top: 3.7em; bottom:3em; position: fixed; overflow: auto; padding: 0; margin: 0; }
#contacts a { height: 23px; display: block; margin: 0 0 0 0; padding: 0 0 0 25px; }
#leftcontent h3 { cursor: pointer; -moz-transition: background 300ms ease 0s; background: none no-repeat scroll 1em center #eee; border-bottom: 1px solid #ddd; border-top: 1px solid #fff; display: block; max-width: 100%; padding: 0.5em 0.8em; color: #666; text-shadow: 0 1px 0 #f8f8f8; font-size: 1.2em; }
#leftcontent h3:hover { background-color: #DBDBDB; border-bottom: 1px solid #CCCCCC; border-top: 1px solid #D4D4D4; color: #333333; }
#contacts { position: fixed; background: #fff; max-width: 100%; width: 20em; left: 12.5em; top: 3.7em; bottom: 3em; overflow: auto; padding: 0; margin: 0; }
.contacts a { height: 23px; display: block; left: 12.5em; margin: 0 0 0 0; padding: 0 0 0 25px; }
#bottomcontrols { padding: 0; bottom:0px; height:2.8em; width: 20em; margin:0; background:#eee; border-top:1px solid #ccc; position:fixed; -moz-box-shadow: 0 -3px 3px -3px #000; -webkit-box-shadow: 0 -3px 3px -3px #000; box-shadow: 0 -3px 3px -3px #000;}
#contacts_newcontact { float: left; margin: 0.2em 0 0 1em; }
#chooseaddressbook { float: right; margin: 0.2em 1em 0 0; }
@ -22,10 +25,10 @@
#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: 14em; float: left; font-weight: bold; }
#card input[type="text"].contacts_property,input[type="email"].contacts_property,input[type="url"].contacts_property { width: 14em; float: left; font-weight: bold; }
.categories { float: left; width: 16em; }
#card input[type="text"],input[type="email"],input[type="tel"],input[type="date"], select, textarea { background-color: #fefefe; 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, textarea:focus, textarea:hover { 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 #ddd, 0 2px 0 #bbb inset; -webkit-box-shadow:0 1px 1px #ddd, 0 1px 0 #bbb inset; box-shadow:0 1px 1px #ddd, 0 1px 0 #bbb inset; -moz-border-radius:.5em; -webkit-border-radius:.5em; border-radius:.5em; outline:none; float: left; }
#card input[type="text"],input[type="email"],input[type="url"],input[type="tel"],input[type="date"], select, textarea { background-color: #fefefe; 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="url"]: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="url"]:active,input[type="tel"]:active, select:hover, select:focus, select:active, textarea:focus, textarea:hover { 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 #ddd, 0 2px 0 #bbb inset; -webkit-box-shadow:0 1px 1px #ddd, 0 1px 0 #bbb inset; box-shadow:0 1px 1px #ddd, 0 1px 0 #bbb inset; -moz-border-radius:.5em; -webkit-border-radius:.5em; border-radius:.5em; outline:none; float: left; }
textarea { width: 80%; min-height: 5em; min-width: 30em; margin: 0 !important; padding: 0 !important; outline: 0 !important;}
dl.form { width: 100%; float: left; clear: right; margin: 0; padding: 0; }
.form dt { display: table-cell; clear: left; float: left; width: 7em; margin: 0; padding: 0.8em 0.5em 0 0; text-align:right; text-overflow:ellipsis; o-text-overflow: ellipsis; vertical-align: text-bottom; color: #bbb;/* white-space: pre-wrap; white-space: -moz-pre-wrap !important; white-space: -pre-wrap; white-space: -o-pre-wrap;*/ }

@ -66,7 +66,7 @@ $tmpl->assign('phone_types', $phone_types);
$tmpl->assign('email_types', $email_types);
$tmpl->assign('categories', $categories);
$tmpl->assign('addressbooks', $addressbooks);
$tmpl->assign('contacts', $contacts);
$tmpl->assign('contacts', $contacts, false);
$tmpl->assign('details', $details );
$tmpl->assign('id',$id);
$tmpl->printPage();

@ -171,13 +171,14 @@ Contacts={
});*/
// Name has changed. Update it and reorder.
// TODO: Take addressbook into account
$('#fn').change(function(){
var name = $('#fn').val().strip_tags();
var item = $('#contacts [data-id="'+Contacts.UI.Card.id+'"]');
var item = $('.contacts li[data-id="'+Contacts.UI.Card.id+'"]');
$(item).find('a').html(name);
Contacts.UI.Card.fn = name;
var added = false;
$('#contacts li').each(function(){
$('.contacts li[data-bookid="'+Contacts.UI.Card.bookid+'"]').each(function(){
if ($(this).text().toLowerCase() > name.toLowerCase()) {
$(this).before(item).fadeIn('fast');
added = true;
@ -185,7 +186,7 @@ Contacts={
}
});
if(!added) {
$('#leftcontent ul').append(item);
$('#contacts ul[data-id="'+Contacts.UI.Card.bookid+'"]').append(item);
}
Contacts.UI.Contacts.scrollTo(Contacts.UI.Card.id);
});
@ -245,19 +246,23 @@ Contacts={
honpre:'',
honsuf:'',
data:undefined,
update:function(id) {
var newid;
update:function(id, bookid) {
var newid, firstitem;
if(!id) {
newid = $('#contacts li:first-child').data('id');
firstitem = $('#contacts:first-child li:first-child');
if(firstitem.length > 0) {
newid = firstitem.data('id');
bookid = firstitem.data('bookid');
}
} else {
newid = id;
}
var localLoadContact = function(id) {
if($('#contacts li').length > 0) {
$('#leftcontent li[data-id="'+newid+'"]').addClass('active');
var localLoadContact = function(newid, bookid) {
if($('.contacts li').length > 0) {
firstitem.addClass('active');
$.getJSON(OC.filePath('contacts', 'ajax', 'contactdetails.php'),{'id':newid},function(jsondata){
if(jsondata.status == 'success'){
Contacts.UI.Card.loadContact(jsondata.data);
Contacts.UI.Card.loadContact(jsondata.data, bookid);
} else {
OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
}
@ -266,19 +271,19 @@ Contacts={
}
// Make sure proper DOM is loaded.
if(!$('#card')[0]) {
if(!$('#card')[0] && newid) {
$.getJSON(OC.filePath('contacts', 'ajax', 'loadcard.php'),{},function(jsondata){
if(jsondata.status == 'success'){
$('#rightcontent').html(jsondata.data.page).ready(function() {
Contacts.UI.loadHandlers();
localLoadContact(newid);
localLoadContact(newid, bookid);
});
} else {
OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
}
});
}
else if($('#contacts li').length == 0) {
else if(!newid) {
// load intro page
$.getJSON(OC.filePath('contacts', 'ajax', 'loadintro.php'),{},function(jsondata){
if(jsondata.status == 'success'){
@ -291,7 +296,7 @@ Contacts={
});
}
else {
localLoadContact();
localLoadContact(newid, bookid);
}
},
doExport:function() {
@ -313,13 +318,14 @@ Contacts={
if (jsondata.status == 'success'){
$('#rightcontent').data('id',jsondata.data.id);
var id = jsondata.data.id;
var aid = jsondata.data.aid;
$.getJSON(OC.filePath('contacts', 'ajax', 'contactdetails.php'),{'id':id},function(jsondata){
if(jsondata.status == 'success'){
Contacts.UI.Card.loadContact(jsondata.data);
$('#leftcontent .active').removeClass('active');
Contacts.UI.Card.loadContact(jsondata.data, aid);
$('#contacts .active').removeClass('active');
var item = $('<li data-id="'+jsondata.data.id+'" class="active"><a href="index.php?id='+jsondata.data.id+'" style="background: url('+OC.filePath('contacts', '', 'thumbnail.php')+'?id='+jsondata.data.id+') no-repeat scroll 0% 0% transparent;">'+Contacts.UI.Card.fn+'</a></li>');
var added = false;
$('#leftcontent ul li').each(function(){
$('#contacts ul[data-id="'+aid+'"] li').each(function(){
if ($(this).text().toLowerCase() > Contacts.UI.Card.fn.toLowerCase()) {
$(this).before(item).fadeIn('fast');
added = true;
@ -327,7 +333,7 @@ Contacts={
}
});
if(!added) {
$('#leftcontent ul').append(item);
$('#contacts ul[data-id="'+aid+'"]').append(item);
}
if(isnew) { // add some default properties
Contacts.UI.Card.addProperty('EMAIL');
@ -370,8 +376,8 @@ Contacts={
if(answer == true) {
$.post(OC.filePath('contacts', 'ajax', 'deletecard.php'),{'id':Contacts.UI.Card.id},function(jsondata){
if(jsondata.status == 'success'){
var newid = '';
var curlistitem = $('#leftcontent [data-id="'+jsondata.data.id+'"]');
var newid = '', bookid;
var curlistitem = $('#contacts li[data-id="'+jsondata.data.id+'"]');
var newlistitem = curlistitem.prev();
if(newlistitem == undefined) {
newlistitem = curlistitem.next();
@ -379,13 +385,14 @@ Contacts={
curlistitem.remove();
if(newlistitem != undefined) {
newid = newlistitem.data('id');
bookid = newlistitem.data('id');
}
$('#rightcontent').data('id',newid);
this.id = this.fn = this.fullname = this.shortname = this.famname = this.givname = this.addname = this.honpre = this.honsuf = '';
this.data = undefined;
if($('#contacts li').length > 0) { // Load first in list.
Contacts.UI.Card.update(newid);
if($('.contacts li').length > 0) { // Load first in list.
Contacts.UI.Card.update(newid, bookid);
} else {
// load intro page
$.getJSON(OC.filePath('contacts', 'ajax', 'loadintro.php'),{},function(jsondata){
@ -408,9 +415,10 @@ Contacts={
});
return false;
},
loadContact:function(jsondata){
loadContact:function(jsondata, bookid){
this.data = jsondata;
this.id = this.data.id;
this.bookid = bookid;
$('#rightcontent').data('id',this.id);
this.populateNameFields();
this.loadPhoto();
@ -1498,40 +1506,54 @@ Contacts={
update:function(){
$.getJSON(OC.filePath('contacts', 'ajax', 'contacts.php'),{},function(jsondata){
if(jsondata.status == 'success'){
$('#contacts').html(jsondata.data.page);
$('#contacts').html(jsondata.data.page).ready(function() {
/*setTimeout(function() {
$('.contacts li').unbind('inview');
$('.contacts li:visible').bind('inview', function(event, isInView, visiblePartX, visiblePartY) {
if (isInView) {
if (!$(this).find('a').attr('style')) {
$(this).find('a').css('background','url('+OC.filePath('contacts', '', 'thumbnail.php')+'?id='+$(this).data('id')+') no-repeat');
}
}
})}, 100);
setTimeout(Contacts.UI.Contacts.lazyupdate, 500);*/
});
Contacts.UI.Card.update();
}
else{
OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
}
});
setTimeout(function() {
$('#contacts li').unbind('inview');
$('#contacts li').bind('inview', function(event, isInView, visiblePartX, visiblePartY) {
/*setTimeout(function() {
$('.contacts li').unbind('inview');
$('.contacts li:visible').bind('inview', function(event, isInView, visiblePartX, visiblePartY) {
if (isInView) {
if (!$(this).find('a').attr('style')) {
$(this).find('a').css('background','url('+OC.filePath('contacts', '', 'thumbnail.php')+'?id='+$(this).data('id')+') no-repeat');
}
}
})}, 500);
setTimeout(Contacts.UI.Contacts.lazyupdate, 500);
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(){
$('.contacts li').live('inview', function(){
if (!$(this).find('a').attr('style')) {
$(this).find('a').css('background','url('+OC.filePath('contacts', '', 'thumbnail.php')+'?id='+$(this).data('id')+') no-repeat');
}
});
},
refreshThumbnail:function(id){
var item = $('#contacts [data-id="'+id+'"]').find('a');
var item = $('.contacts li[data-id="'+id+'"]').find('a');
item.html(Contacts.UI.Card.fn);
item.css('background','url('+OC.filePath('contacts', '', 'thumbnail.php')+'?id='+id+'&refresh=1'+Math.random()+') no-repeat');
},
scrollTo:function(id){
$('#contacts').animate({
scrollTop: $('#leftcontent li[data-id="'+id+'"]').offset().top-20}, 'slow','swing');
var item = $('#contacts li[data-id="'+id+'"]');
if(item) {
$('.contacts').animate({
scrollTop: $('#contacts li[data-id="'+id+'"]').offset().top-20}, 'slow','swing');
}
}
}
}
@ -1552,24 +1574,25 @@ $(document).ready(function(){
$('#contacts_newcontact').keydown(Contacts.UI.Card.editNew);
// Load a contact.
$('#contacts').keydown(function(event) {
$('.contacts').keydown(function(event) {
if(event.which == 13) {
$('#contacts').click();
$('.contacts').click();
}
});
$('#contacts').click(function(event){
$(document).on('click', '.contacts', function(event){
var $tgt = $(event.target);
if ($tgt.is('li') || $tgt.is('a')) {
var item = $tgt.is('li')?$($tgt):($tgt).parent();
var id = item.data('id');
var bookid = item.data('bookid');
item.addClass('active');
var oldid = $('#rightcontent').data('id');
if(oldid != 0){
$('#contacts li[data-id="'+oldid+'"]').removeClass('active');
$('.contacts li[data-id="'+oldid+'"]').removeClass('active');
}
$.getJSON(OC.filePath('contacts', 'ajax', 'contactdetails.php'),{'id':id},function(jsondata){
if(jsondata.status == 'success'){
Contacts.UI.Card.loadContact(jsondata.data);
Contacts.UI.Card.loadContact(jsondata.data, bookid);
}
else{
OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
@ -1579,7 +1602,12 @@ $(document).ready(function(){
return false;
});
$('#contacts li').bind('inview', function(event, isInView, visiblePartX, visiblePartY) {
$(document).on('click', '.addressbook', function(event){
$(this).next().slideToggle(300);
return false;
});
/*$('.contacts li').bind('inview', function(event, isInView, visiblePartX, visiblePartY) {
if (isInView) { //NOTE: I've kept all conditions for future reference ;-)
// element is now visible in the viewport
if (visiblePartY == 'top') {
@ -1591,14 +1619,14 @@ $(document).ready(function(){
if (!$(this).find('a').attr('style')) {
//alert($(this).data('id') + ' has background: ' + $(this).attr('style'));
$(this).find('a').css('background','url('+OC.filePath('contacts', '', 'thumbnail.php')+'?id='+$(this).data('id')+') no-repeat');
}/* else {
alert($(this).data('id') + ' has style ' + $(this).attr('style').match('url'));
}*/
}// else {
// alert($(this).data('id') + ' has style ' + $(this).attr('style').match('url'));
//}
}
} else {
// element has gone out of viewport
}
});
});*/
$('.contacts_property').live('change', function(){
Contacts.UI.Card.saveProperty(this);
@ -1677,4 +1705,7 @@ $(document).ready(function(){
}
$('#contacts_propertymenu_dropdown a').click(propertyMenuItem);
$('#contacts_propertymenu_dropdown a').keydown(propertyMenuItem);
Contacts.UI.loadHandlers();
Contacts.UI.Contacts.update();
});

@ -172,12 +172,11 @@ class OC_Contacts_Addressbook{
if(!$prefbooks){
$addressbooks = OC_Contacts_Addressbook::all($uid);
if(count($addressbooks) == 0){
OC_Contacts_Addressbook::add($uid,'default','Default Address Book');
$addressbooks = OC_Contacts_Addressbook::all($uid);
$id = OC_Contacts_Addressbook::add($uid,'default','Default Address Book');
self::setActive($id, true);
}
$prefbooks = $addressbooks[0]['id'];
OCP\Config::setUserValue($uid,'contacts','openaddressbooks',$prefbooks);
}
$prefbooks = OCP\Config::getUserValue($uid,'contacts','openaddressbooks',null);
return explode(';',$prefbooks);
}
@ -195,7 +194,7 @@ class OC_Contacts_Addressbook{
$stmt = OCP\DB::prepare( $prep );
$result = $stmt->execute($active);
} catch(Exception $e) {
OCP\Util::writeLog('contacts','OC_Contacts_Addressbook:active:, exception: '.$e->getMessage(),OCP\Util::DEBUG);
OCP\Util::writeLog('contacts','OC_Contacts_Addressbook:active:, exception: '.$e->getMessage(),OCP\Util::ERROR);
OCP\Util::writeLog('contacts','OC_Contacts_Addressbook:active, ids: '.join(',', $active),OCP\Util::DEBUG);
OCP\Util::writeLog('contacts','OC_Contacts_Addressbook::active, SQL:'.$prep,OCP\Util::DEBUG);
}
@ -210,7 +209,7 @@ class OC_Contacts_Addressbook{
/**
* @brief Activates an addressbook
* @param integer $id
* @param integer $name
* @param boolean $active
* @return boolean
*/
public static function setActive($id,$active){
@ -256,11 +255,15 @@ class OC_Contacts_Addressbook{
* @return boolean
*/
public static function delete($id){
// FIXME: There's no error checking at all.
self::setActive($id, false);
$stmt = OCP\DB::prepare( 'DELETE FROM *PREFIX*contacts_addressbooks WHERE id = ?' );
$stmt->execute(array($id));
try {
$stmt = OCP\DB::prepare( 'DELETE FROM *PREFIX*contacts_addressbooks WHERE id = ?' );
$stmt->execute(array($id));
} catch(Exception $e) {
OCP\Util::writeLog('contacts','OC_Contacts_Addressbook:delete:, exception for '.$id.': '.$e->getMessage(),OCP\Util::ERROR);
return false;
}
$cards = OC_Contacts_VCard::all($id);
foreach($cards as $card){
OC_Contacts_VCard::delete($card['id']);

@ -56,7 +56,7 @@ class OC_Contacts_Hooks{
static public function getBirthdayEvents($parameters) {
$name = $parameters['calendar_id'];
if (strpos('birthday_', $name) != 0) {
if (strpos($name, 'birthday_') != 0) {
return;
}
$info = explode('_', $name);

@ -2,17 +2,10 @@
class OC_Search_Provider_Contacts extends OC_Search_Provider{
function search($query){
$addressbooks = OC_Contacts_Addressbook::all(OCP\USER::getUser(), 1);
// if(count($calendars)==0 || !OCP\App::isEnabled('contacts')){
// //return false;
// }
// NOTE: Does the following do anything
$results=array();
$searchquery=array();
if(substr_count($query, ' ') > 0){
$searchquery = explode(' ', $query);
}else{
$searchquery[] = $query;
if(count($addressbooks)==0 || !OCP\App::isEnabled('contacts')){
return array();
}
$results=array();
$l = new OC_l10n('contacts');
foreach($addressbooks as $addressbook){
$vcards = OC_Contacts_VCard::all($addressbook['id']);

@ -56,7 +56,7 @@ class OC_Contacts_VCard{
$stmt = OCP\DB::prepare( $prep );
$result = $stmt->execute($id);
} catch(Exception $e) {
OCP\Util::writeLog('contacts','OC_Contacts_VCard:all:, exception: '.$e->getMessage(),OCP\Util::DEBUG);
OCP\Util::writeLog('contacts','OC_Contacts_VCard:all:, exception: '.$e->getMessage(),OCP\Util::ERROR);
OCP\Util::writeLog('contacts','OC_Contacts_VCard:all, ids: '.join(',', $id),OCP\Util::DEBUG);
OCP\Util::writeLog('contacts','SQL:'.$prep,OCP\Util::DEBUG);
}

@ -3,16 +3,15 @@
var categories = <?php echo json_encode($_['categories']); ?>;
var lang = '<?php echo OCP\Config::getUserValue(OCP\USER::getUser(), 'core', 'lang', 'en'); ?>';
</script>
<div id="leftcontent" class="leftcontent">
<ul id="contacts">
<?php echo $this->inc("part.contacts"); ?>
</ul>
</div>
<div id="bottomcontrols">
<form>
<button class="svg" id="contacts_newcontact" title="<?php echo $l->t('Add Contact'); ?>"><img class="svg" src="<?php echo OCP\Util::linkTo('contacts', 'img/contact-new.svg'); ?>" alt="<?php echo $l->t('Add Contact'); ?>" /></button>
<button class="svg" id="chooseaddressbook" title="<?php echo $l->t('Addressbooks'); ?>"><img class="svg" src="core/img/actions/settings.svg" alt="<?php echo $l->t('Addressbooks'); ?>" /></button>
</form>
<div id="leftcontent">
<div id="contacts">
</div>
<div id="bottomcontrols">
<form>
<button class="svg" id="contacts_newcontact" title="<?php echo $l->t('Add Contact'); ?>"><img class="svg" src="<?php echo OCP\Util::linkTo('contacts', 'img/contact-new.svg'); ?>" alt="<?php echo $l->t('Add Contact'); ?>" /></button>
<button class="svg" id="chooseaddressbook" title="<?php echo $l->t('Addressbooks'); ?>"><img class="svg" src="core/img/actions/settings.svg" alt="<?php echo $l->t('Addressbooks'); ?>" /></button>
</form>
</div>
</div>
<div id="rightcontent" class="rightcontent" data-id="<?php echo $_['id']; ?>">
<?php

@ -33,15 +33,15 @@ $id = isset($_['id']) ? $_['id'] : '';
</span>
<dl id="identityprops" class="form">
<dt class="hidden" id="org_label" data-element="ORG"><label for="org"><?php echo $l->t('Organization'); ?></label></dt>
<dd class="propertycontainer hidden" id="org_value" data-element="ORG"><input id="org" required="required" name="value[ORG]" type="text" class="contacts_property big" name="value" value="" placeholder="<?php echo $l->t('Organization'); ?>" /><a role="button" class="action delete" title="<?php echo $l->t('Delete'); ?>"></a></dd>
<dd class="propertycontainer hidden" id="org_value" data-element="ORG"><input id="org" required="required" type="text" class="contacts_property big" name="value" value="" placeholder="<?php echo $l->t('Organization'); ?>" /><a role="button" class="action delete" title="<?php echo $l->t('Delete'); ?>"></a></dd>
<dt class="hidden" id="nickname_label" data-element="NICKNAME"><label for="nickname"><?php echo $l->t('Nickname'); ?></label></dt>
<dd class="propertycontainer hidden" id="nickname_value" data-element="NICKNAME"><input id="nickname" required="required" name="value[NICKNAME]" type="text" class="contacts_property big" name="value" value="" placeholder="<?php echo $l->t('Enter nickname'); ?>" /><a role="button" class="action delete" title="<?php echo $l->t('Delete'); ?>"></a></dd>
<dd class="propertycontainer hidden" id="nickname_value" data-element="NICKNAME"><input id="nickname" required="required" type="text" class="contacts_property big" name="value" value="" placeholder="<?php echo $l->t('Enter nickname'); ?>" /><a role="button" class="action delete" title="<?php echo $l->t('Delete'); ?>"></a></dd>
<dt class="hidden" id="url_label" data-element="URL"><label for="url"><?php echo $l->t('Web site'); ?></label></dt>
<dd class="propertycontainer hidden" id="url_value" data-element="URL"><input id="url" required="required" name="value[URL]" type="text" class="contacts_property big" name="value" value="" placeholder="<?php echo $l->t('http://www.somesite.com'); ?>" /><a role="button" class="action globe" title="<?php echo $l->t('Go to web site'); ?>"><a role="button" class="action delete" title="<?php echo $l->t('Delete'); ?>"></a></dd>
<dd class="propertycontainer hidden" id="url_value" data-element="URL"><input id="url" required="required" type="url" class="contacts_property big" name="value" value="" placeholder="<?php echo $l->t('http://www.somesite.com'); ?>" /><a role="button" class="action globe" title="<?php echo $l->t('Go to web site'); ?>"><a role="button" class="action delete" title="<?php echo $l->t('Delete'); ?>"></a></dd>
<dt class="hidden" id="bday_label" data-element="BDAY"><label for="bday"><?php echo $l->t('Birthday'); ?></label></dt>
<dd class="propertycontainer hidden" id="bday_value" data-element="BDAY"><input id="bday" required="required" name="value" type="text" class="contacts_property big" value="" placeholder="<?php echo $l->t('dd-mm-yyyy'); ?>" /><a role="button" class="action delete" title="<?php echo $l->t('Delete'); ?>"></a></dd>
<dt class="hidden" id="categories_label" data-element="CATEGORIES"><label for="categories"><?php echo $l->t('Groups'); ?></label></dt>
<dd class="propertycontainer hidden" id="categories_value" data-element="CATEGORIES"><input id="categories" required="required" name="value[CATEGORIES]" type="text" class="contacts_property bold" name="value" value="" placeholder="
<dd class="propertycontainer hidden" id="categories_value" data-element="CATEGORIES"><input id="categories" required="required" type="text" class="contacts_property bold" name="value" value="" placeholder="
<?php echo $l->t('Separate groups with commas'); ?>" />
<a role="button" class="action delete" title="<?php echo $l->t('Delete'); ?>"></a><a role="button" class="action edit" title="<?php echo $l->t('Edit groups'); ?>"></a></dd>
</dl>
@ -121,19 +121,3 @@ $id = isset($_['id']) ? $_['id'] : '';
<div id="edit_photo_dialog" title="Edit photo">
<div id="edit_photo_dialog_img"></div>
</div>
<script language="Javascript">
$(document).ready(function(){
if('<?php echo $id; ?>'!='') {
$.getJSON(OC.filePath('contacts', 'ajax', 'contactdetails.php'),{'id':'<?php echo $id; ?>'},function(jsondata){
if(jsondata.status == 'success'){
$('#leftcontent li[data-id="<?php echo $id; ?>"]').addClass('active');
Contacts.UI.Card.loadContact(jsondata.data);
Contacts.UI.loadHandlers();
}
else{
OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
}
});
}
});
</script>

@ -1,12 +1,10 @@
<?php foreach( $_['contacts'] as $contact ):
$display = trim($contact['fullname']);
if(!$display) {
$vcard = OC_Contacts_App::getContactVCard($contact['id']);
if(!is_null($vcard)) {
$struct = OC_Contacts_VCard::structureContact($vcard);
$display = isset($struct['EMAIL'][0])?$struct['EMAIL'][0]['value']:'[UNKNOWN]';
}
<?php
foreach($_['books'] as $id => $addressbook) {
echo '<h3 class="addressbook" data-id="'.$id.'">'.$addressbook['displayname'].'</h3>';
echo '<ul class="contacts hidden" data-id="'.$id.'">';
foreach($addressbook['contacts'] as $contact) {
echo '<li role="button" data-bookid="'.$contact['addressbookid'].'" data-id="'.$contact['id'].'"><a href="index.php?id='.$contact['id'].'" style="background: url('.link_to('contacts','thumbnail.php').'?id='.$contact['id'].') no-repeat scroll 0 0 transparent;">'.$contact['displayname'].'</a></li>';
}
echo '</ul>';
}
?>
<li role="button" book-id="<?php echo $contact['addressbookid']; ?>" data-id="<?php echo $contact['id']; ?>"><a href="index.php?id=<?php echo $contact['id']; ?>"><?php echo $display; ?></a></li>
<?php endforeach; ?>

@ -4,7 +4,7 @@ $tmpkey = $_['tmpkey'];
$requesttoken = $_['requesttoken'];
OCP\Util::writeLog('contacts','templates/part.cropphoto.php: tmpkey: '.$tmpkey, OCP\Util::DEBUG);
?>
<script language="Javascript">
<script type="text/javascript">
jQuery(function($) {
$('#cropbox').Jcrop({
onChange: showCoords,

@ -1,13 +1,9 @@
<?php
$adr = isset($_['adr'])?$_['adr']:array();
$id = $_['id'];
$types = array();
foreach(isset($adr['parameters']['TYPE'])?array($adr['parameters']['TYPE']):array() as $type) {
$types[] = strtoupper($type);
}
$id = isset($_['id'])?$_['id']:array();
$types = isset($_['types'])?$_['types']:array();
?>
<div id="edit_address_dialog" title="<?php echo $l->t('Edit address'); ?>">
<!-- ?php print_r($types); ? -->
<fieldset id="address">
<dl class="form">
<dt>
@ -22,43 +18,43 @@ foreach(isset($adr['parameters']['TYPE'])?array($adr['parameters']['TYPE']):arra
<label class="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('PO Box'); ?>" value="<?php echo isset($adr['value'][0])?$adr['value'][0]:''; ?>">
<input type="text" id="adr_pobox" name="value[ADR][0]" placeholder="<?php echo $l->t('PO Box'); ?>" value="<?php echo isset($adr[0])?$adr[0]:''; ?>">
</dd>
<dt>
<label class="label" for="adr_street"><?php echo $l->t('Street address'); ?></label>
</dt>
<dd>
<input type="text" id="adr_street" name="value[ADR][2]" placeholder="<?php echo $l->t('Street and number'); ?>" value="<?php echo isset($adr['value'][2])?$adr['value'][2]:''; ?>">
<input type="text" id="adr_street" name="value[ADR][2]" placeholder="<?php echo $l->t('Street and number'); ?>" value="<?php echo isset($adr[2])?$adr[2]:''; ?>">
</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]" placeholder="<?php echo $l->t('Apartment number etc.'); ?>" value="<?php echo isset($adr['value'][1])?$adr['value'][1]:''; ?>">
<input type="text" id="adr_extended" name="value[ADR][1]" placeholder="<?php echo $l->t('Apartment number etc.'); ?>" value="<?php echo isset($adr[1])?$adr[1]:''; ?>">
</dd>
<dt>
<label class="label" for="adr_city"><?php echo $l->t('City'); ?></label>
</dt>
<dd>
<input type="text" id="adr_city" name="value[ADR][3]" placeholder="<?php echo $l->t('City'); ?>" value="<?php echo isset($adr['value'][3])?$adr['value'][3]:''; ?>">
<input type="text" id="adr_city" name="value[ADR][3]" placeholder="<?php echo $l->t('City'); ?>" value="<?php echo isset($adr[3])?$adr[3]:''; ?>">
</dd>
<dt>
<label class="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="<?php echo isset($adr['value'][4])?$adr['value'][4]:''; ?>">
<input type="text" id="adr_region" name="value[ADR][4]" placeholder="<?php echo $l->t('E.g. state or province'); ?>" value="<?php echo isset($adr[4])?$adr[4]:''; ?>">
</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]" placeholder="<?php echo $l->t('Postal code'); ?>" value="<?php echo isset($adr['value'][5])?$adr['value'][5]:''; ?>">
<input type="text" id="adr_zipcode" name="value[ADR][5]" placeholder="<?php echo $l->t('Postal code'); ?>" value="<?php echo isset($adr[5])?$adr[5]:''; ?>">
</dd>
<dt>
<label class="label" for="adr_country"><?php echo $l->t('Country'); ?></label>
</dt>
<dd>
<input type="text" id="adr_country" name="value[ADR][6]" placeholder="<?php echo $l->t('Country'); ?>" value="<?php echo isset($adr['value'][6])?$adr['value'][6]:''; ?>">
<input type="text" id="adr_country" name="value[ADR][6]" placeholder="<?php echo $l->t('Country'); ?>" value="<?php echo isset($adr[6])?$adr[6]:''; ?>">
</dd>
</dl>
</fieldset>

@ -22,7 +22,7 @@ $addressbooks = isset($_['addressbooks'])?$_['addressbooks']:null;
<?php }} ?>
<dt><label for="pre"><?php echo $l->t('Hon. prefixes'); ?></label></dt>
<dd>
<input name="pre" id="pre" value="<?php echo isset($name['value'][3]) ? $name['value'][3] : ''; ?>" type="text" list="prefixes" />
<input name="pre" id="pre" value="<?php echo isset($name[3]) ? $name[3] : ''; ?>" type="text" list="prefixes" />
<datalist id="prefixes">
<option value="<?php echo $l->t('Miss'); ?>">
<option value="<?php echo $l->t('Ms'); ?>">
@ -33,14 +33,14 @@ $addressbooks = isset($_['addressbooks'])?$_['addressbooks']:null;
</datalist>
</dd>
<dt><label for="giv"><?php echo $l->t('Given name'); ?></label></dt>
<dd><input name="giv" id="giv" value="<?php echo isset($name['value'][1]) ? $name['value'][1] : ''; ?>" type="text" /></dd>
<dd><input name="giv" id="giv" value="<?php echo isset($name[1]) ? $name[1] : ''; ?>" type="text" /></dd>
<dt><label for="add"><?php echo $l->t('Additional names'); ?></label></dt>
<dd><input name="add" id="add" value="<?php echo isset($name['value'][2]) ? $name['value'][2] : ''; ?>" type="text" /></dd>
<dd><input name="add" id="add" value="<?php echo isset($name[2]) ? $name[2] : ''; ?>" type="text" /></dd>
<dt><label for="fam"><?php echo $l->t('Family name'); ?></label></dt>
<dd><input name="fam" id="fam" value="<?php echo isset($name['value'][0]) ? $name['value'][0] : ''; ?>" type="text" /></dd>
<dd><input name="fam" id="fam" value="<?php echo isset($name[0]) ? $name[0] : ''; ?>" type="text" /></dd>
<dt><label for="suf"><?php echo $l->t('Hon. suffixes'); ?></label></dt>
<dd>
<input name="suf" id="suf" value="<?php echo isset($name['value'][4]) ? $name['value'][4] : ''; ?>" type="text" list="suffixes" />
<input name="suf" id="suf" value="<?php echo isset($name[4]) ? $name[4] : ''; ?>" type="text" list="suffixes" />
<datalist id="suffixes">
<option value="<?php echo $l->t('J.D.'); ?>">
<option value="<?php echo $l->t('M.D.'); ?>">

@ -10,6 +10,7 @@ if(!$checkOnly){
$eventSource=new OC_EventSource();
}
session_write_close();
//create the file cache if necesary
if($force or !OC_FileCache::inCache('')){

@ -48,7 +48,7 @@ if(strpos($dir,'..') === false){
for($i=0;$i<$fileCount;$i++){
$target = OCP\Files::buildNotExistingFileName(stripslashes($dir), $files['name'][$i]);
if(is_uploaded_file($files['tmp_name'][$i]) and OC_Filesystem::fromTmpFile($files['tmp_name'][$i],$target)){
$meta=OC_FileCache::getCached($target);
$meta=OC_FileCache_Cached::get($target);
$result[]=array( "status" => "success", 'mime'=>$meta['mimetype'],'size'=>$meta['size'],'name'=>basename($target));
}
}

@ -141,7 +141,7 @@ $(document).ready(function(){
var downloadScope = 'file';
}
FileActions.register(downloadScope,'Download',function(){return OC.imagePath('core','actions/download')},function(filename){
window.location=OC.filePath('files', 'ajax', 'download.php') + '?files='+encodeURIComponent(filename)+'&dir='+encodeURIComponent($('#dir').val());
window.location=OC.filePath('files', 'ajax', 'download.php') + encodeURIComponent('?files='+encodeURIComponent(filename)+'&dir='+encodeURIComponent($('#dir').val()));
});
});

@ -1,6 +1,6 @@
<?php for($i=0; $i<count($_["breadcrumb"]); $i++):
$crumb = $_["breadcrumb"][$i]; ?>
<div class="crumb <?php if($i == count($_["breadcrumb"])-1) echo 'last';?> svg" data-dir='<?php echo $crumb["dir"];?>' style='background-image:url("<?php echo OCP\image_path('core','breadcrumb.png');?>")'>
<a href="<?php echo $_['baseURL'].$crumb["dir"]; ?>"><?php echo htmlentities($crumb["name"],ENT_COMPAT,'utf-8'); ?></a>
<a href="<?php echo $_['baseURL'].$crumb["dir"]; ?>"><?php echo OCP\Util::sanitizeHTML($crumb["name"]); ?></a>
</div>
<?php endfor;?>

@ -43,22 +43,20 @@ class OC_Crypt {
self::init($params['uid'],$params['password']);
}
public static function init($login,$password) {
$view1=new OC_FilesystemView('/');
if(!$view1->file_exists('/'.$login)){
$view1->mkdir('/'.$login);
}
$view=new OC_FilesystemView('/'.$login);
OC_FileProxy::$enabled=false;
if(!$view->file_exists('/encryption.key')){// does key exist?
OC_Crypt::createkey($login,$password);
}
$key=$view->file_get_contents('/encryption.key');
OC_FileProxy::$enabled=true;
$_SESSION['enckey']=OC_Crypt::decrypt($key, $password);
}
public static function init($login,$password) {
$view=new OC_FilesystemView('/');
if(!$view->file_exists('/'.$login)){
$view->mkdir('/'.$login);
}
OC_FileProxy::$enabled=false;
if(!$view->file_exists('/'.$login.'/encryption.key')){// does key exist?
OC_Crypt::createkey($login,$password);
}
$key=$view->file_get_contents('/'.$login.'/encryption.key');
OC_FileProxy::$enabled=true;
$_SESSION['enckey']=OC_Crypt::decrypt($key, $password);
}
/**
@ -140,7 +138,7 @@ class OC_Crypt {
public static function decrypt( $content, $key='') {
$bf = self::getBlowfish($key);
$data=$bf->decrypt($content);
return rtrim($data, "\0");
return $data;
}
/**
@ -181,6 +179,9 @@ class OC_Crypt {
while (!feof($handleread)) {
$content = fread($handleread, 8192);
$enccontent=OC_CRYPT::decrypt( $content, $key);
if(feof($handleread)){
$enccontent=rtrim($enccontent, "\0");
}
fwrite($handlewrite, $enccontent);
}
fclose($handlewrite);
@ -203,12 +204,16 @@ class OC_Crypt {
/**
* decrypt data in 8192b sized blocks
*/
public static function blockDecrypt($data, $key=''){
public static function blockDecrypt($data, $key='',$maxLength=0){
$result='';
while(strlen($data)){
$result.=self::decrypt(substr($data,0,8192),$key);
$data=substr($data,8192);
}
return $result;
if($maxLength>0){
return substr($result,0,$maxLength);
}else{
return rtrim($result, "\0");
}
}
}

@ -35,6 +35,7 @@ class OC_CryptStream{
private $meta=array();//header/meta for source stream
private $count;
private $writeCache;
private $size;
private static $rootView;
public function stream_open($path, $mode, $options, &$opened_path){
@ -45,9 +46,14 @@ class OC_CryptStream{
if(dirname($path)=='streams' and isset(self::$sourceStreams[basename($path)])){
$this->source=self::$sourceStreams[basename($path)]['stream'];
$this->path=self::$sourceStreams[basename($path)]['path'];
$this->size=self::$sourceStreams[basename($path)]['size'];
}else{
$this->path=$path;
OCP\Util::writeLog('files_encryption','open encrypted '.$path. ' in '.$mode,OCP\Util::DEBUG);
if($mode=='w' or $mode=='w+' or $mode=='wb' or $mode=='wb+'){
$this->size=0;
}else{
$this->size=self::$rootView->filesize($path,$mode);
}
OC_FileProxy::$enabled=false;//disable fileproxies so we can open the source file
$this->source=self::$rootView->fopen($path,$mode);
OC_FileProxy::$enabled=true;
@ -78,12 +84,17 @@ class OC_CryptStream{
OCP\Util::writeLog('files_encryption','php bug 21641 no longer holds, decryption will not work',OCP\Util::FATAL);
die();
}
$pos=ftell($this->source);
$data=fread($this->source,8192);
if(strlen($data)){
$result=OC_Crypt::decrypt($data);
}else{
$result='';
}
$length=$this->size-$pos;
if($length<8192){
$result=substr($result,0,$length);
}
return $result;
}
@ -104,8 +115,9 @@ class OC_CryptStream{
$data=substr($block,0,$currentPos%8192).$data;
fseek($this->source,-($currentPos%8192),SEEK_CUR);
}
while(strlen($data)>0){
if(strlen($data)<8192){
$currentPos=ftell($this->source);
while($remainingLength=strlen($data)>0){
if($remainingLength<8192){
$this->writeCache=$data;
$data='';
}else{
@ -114,6 +126,7 @@ class OC_CryptStream{
$data=substr($data,8192);
}
}
$this->size=max($this->size,$currentPos+$length);
return $length;
}
@ -157,7 +170,7 @@ class OC_CryptStream{
public function stream_close(){
$this->flush();
if($this->meta['mode']!='r' and $this->meta['mode']!='rb'){
OC_FileCache::put($this->path,array('encrypted'=>true));
OC_FileCache::put($this->path,array('encrypted'=>true,'size'=>$this->size),'');
}
return fclose($this->source);
}

@ -59,22 +59,24 @@ class OC_FileProxy_Encryption extends OC_FileProxy{
* @return bool
*/
private static function isEncrypted($path){
$metadata=OC_FileCache::getCached($path,'');
$metadata=OC_FileCache_Cached::get($path,'');
return isset($metadata['encrypted']) and (bool)$metadata['encrypted'];
}
public function preFile_put_contents($path,&$data){
if(self::shouldEncrypt($path)){
if (!is_resource($data)) {//stream put contents should have been converter to fopen
$size=strlen($data);
$data=OC_Crypt::blockEncrypt($data);
OC_FileCache::put($path,array('encrypted'=>true));
OC_FileCache::put($path,array('encrypted'=>true,'size'=>$size),'');
}
}
}
public function postFile_get_contents($path,$data){
if(self::isEncrypted($path)){
$data=OC_Crypt::blockDecrypt($data);
$cached=OC_FileCache_Cached::get($path,'');
$data=OC_Crypt::blockDecrypt($data,'',$cached['size']);
}
return $data;
}
@ -108,4 +110,21 @@ class OC_FileProxy_Encryption extends OC_FileProxy{
}
return $mime;
}
public function postStat($path,$data){
if(self::isEncrypted($path)){
$cached=OC_FileCache_Cached::get($path,'');
$data['size']=$cached['size'];
}
return $data;
}
public function postFileSize($path,$size){
if(self::isEncrypted($path)){
$cached=OC_FileCache_Cached::get($path,'');
return $cached['size'];
}else{
return $size;
}
}
}

@ -13,6 +13,7 @@ class Test_Encryption extends UnitTestCase {
$source=file_get_contents($file); //nice large text file
$encrypted=OC_Crypt::encrypt($source,$key);
$decrypted=OC_Crypt::decrypt($encrypted,$key);
$decrypted=rtrim($decrypted, "\0");
$this->assertNotEqual($encrypted,$source);
$this->assertEqual($decrypted,$source);
@ -20,6 +21,7 @@ class Test_Encryption extends UnitTestCase {
$encrypted=OC_Crypt::encrypt($chunk,$key);
$this->assertEqual(strlen($chunk),strlen($encrypted));
$decrypted=OC_Crypt::decrypt($encrypted,$key);
$decrypted=rtrim($decrypted, "\0");
$this->assertEqual($decrypted,$chunk);
$encrypted=OC_Crypt::blockEncrypt($source,$key);
@ -43,6 +45,7 @@ class Test_Encryption extends UnitTestCase {
$source=file_get_contents($file); //binary file
$encrypted=OC_Crypt::encrypt($source,$key);
$decrypted=OC_Crypt::decrypt($encrypted,$key);
$decrypted=rtrim($decrypted, "\0");
$this->assertEqual($decrypted,$source);
$encrypted=OC_Crypt::blockEncrypt($source,$key);
@ -50,4 +53,20 @@ class Test_Encryption extends UnitTestCase {
$this->assertEqual($decrypted,$source);
}
function testBinary(){
$key=uniqid();
$file=__DIR__.'/binary';
$source=file_get_contents($file); //binary file
$encrypted=OC_Crypt::encrypt($source,$key);
$decrypted=OC_Crypt::decrypt($encrypted,$key);
$decrypted=rtrim($decrypted, "\0");
$this->assertEqual($decrypted,$source);
$encrypted=OC_Crypt::blockEncrypt($source,$key);
$decrypted=OC_Crypt::blockDecrypt($encrypted,$key,strlen($source));
$this->assertEqual($decrypted,$source);
}
}

@ -7,8 +7,13 @@
*/
class Test_CryptProxy extends UnitTestCase {
private $oldConfig;
public function setUp(){
$this->oldConfig=OCP\Config::getAppValue('files_encryption','enable_encryption','true');
OCP\Config::setAppValue('files_encryption','enable_encryption','true');
//set testing key
$_SESSION['enckey']=md5(time());
@ -29,10 +34,11 @@ class Test_CryptProxy extends UnitTestCase {
$rootView->mkdir('/'.OC_User::getUser().'/files');
}
public function tearDown(){
OCP\Config::setAppValue('files_encryption','enable_encryption',$this->oldConfig);
}
public function testSimple(){
$oldConfig=OCP\Config::getAppValue('files_encryption','enable_encryption','true');
OCP\Config::setAppValue('files_encryption','enable_encryption','true');
$file=OC::$SERVERROOT.'/3rdparty/MDB2.php';
$original=file_get_contents($file);
@ -44,18 +50,59 @@ class Test_CryptProxy extends UnitTestCase {
$fromFile=OC_Filesystem::file_get_contents('/file');
$this->assertNotEqual($original,$stored);
$this->assertEqual(strlen($original),strlen($fromFile));
$this->assertEqual($original,$fromFile);
}
public function testView(){
$file=OC::$SERVERROOT.'/3rdparty/MDB2.php';
$original=file_get_contents($file);
$rootView=new OC_FilesystemView('');
$view=new OC_FilesystemView('/'.OC_User::getUser());
$userDir='/'.OC_User::getUser().'/files';
$rootView->file_put_contents($userDir.'/file',$original);
OC_FileProxy::$enabled=false;
$stored=$rootView->file_get_contents($userDir.'/file');
OC_FileProxy::$enabled=true;
$this->assertNotEqual($original,$stored);
$fromFile=$rootView->file_get_contents($userDir.'/file');
$this->assertEqual($original,$fromFile);
$fromFile=$view->file_get_contents('files/file');
$this->assertEqual($original,$fromFile);
}
public function testBinary(){
$file=__DIR__.'/binary';
$original=file_get_contents($file);
OC_Filesystem::file_put_contents('/file',$original);
OC_FileProxy::$enabled=false;
$stored=OC_Filesystem::file_get_contents('/file');
OC_FileProxy::$enabled=true;
$fromFile=OC_Filesystem::file_get_contents('/file');
$this->assertNotEqual($original,$stored);
$this->assertEqual(strlen($original),strlen($fromFile));
$this->assertEqual($original,$fromFile);
OCP\Config::setAppValue('files_encryption','enable_encryption',$oldConfig);
$file=__DIR__.'/zeros';
$original=file_get_contents($file);
OC_Filesystem::file_put_contents('/file',$original);
OC_FileProxy::$enabled=false;
$stored=OC_Filesystem::file_get_contents('/file');
OC_FileProxy::$enabled=true;
$fromFile=OC_Filesystem::file_get_contents('/file');
$this->assertNotEqual($original,$stored);
$this->assertEqual(strlen($original),strlen($fromFile));
}
}

@ -10,23 +10,23 @@ class Test_CryptStream extends UnitTestCase {
private $tmpFiles=array();
function testStream(){
$stream=$this->getStream('test1','w');
$stream=$this->getStream('test1','w',strlen('foobar'));
fwrite($stream,'foobar');
fclose($stream);
$stream=$this->getStream('test1','r');
$stream=$this->getStream('test1','r',strlen('foobar'));
$data=fread($stream,6);
fclose($stream);
$this->assertEqual('foobar',$data);
$file=OC::$SERVERROOT.'/3rdparty/MDB2.php';
$source=fopen($file,'r');
$target=$this->getStream('test2','w');
$target=$this->getStream('test2','w',0);
OCP\Files::streamCopy($source,$target);
fclose($target);
fclose($source);
$stream=$this->getStream('test2','r');
$stream=$this->getStream('test2','r',filesize($file));
$data=stream_get_contents($stream);
$original=file_get_contents($file);
$this->assertEqual(strlen($original),strlen($data));
@ -37,9 +37,10 @@ class Test_CryptStream extends UnitTestCase {
* get a cryptstream to a temporary file
* @param string $id
* @param string $mode
* @param int size
* @return resource
*/
function getStream($id,$mode){
function getStream($id,$mode,$size){
if($id===''){
$id=uniqid();
}
@ -50,7 +51,35 @@ class Test_CryptStream extends UnitTestCase {
$file=$this->tmpFiles[$id];
}
$stream=fopen($file,$mode);
OC_CryptStream::$sourceStreams[$id]=array('path'=>'dummy','stream'=>$stream);
OC_CryptStream::$sourceStreams[$id]=array('path'=>'dummy'.$id,'stream'=>$stream,'size'=>$size);
return fopen('crypt://streams/'.$id,$mode);
}
function testBinary(){
$file=__DIR__.'/binary';
$source=file_get_contents($file);
$stream=$this->getStream('test','w',strlen($source));
fwrite($stream,$source);
fclose($stream);
$stream=$this->getStream('test','r',strlen($source));
$data=stream_get_contents($stream);
fclose($stream);
$this->assertEqual(strlen($data),strlen($source));
$this->assertEqual($source,$data);
$file=__DIR__.'/zeros';
$source=file_get_contents($file);
$stream=$this->getStream('test2','w',strlen($source));
fwrite($stream,$source);
fclose($stream);
$stream=$this->getStream('test2','r',strlen($source));
$data=stream_get_contents($stream);
fclose($stream);
$this->assertEqual(strlen($data),strlen($source));
$this->assertEqual($source,$data);
}
}

Binary file not shown.

@ -40,7 +40,7 @@ class OC_Filestorage_Google extends OC_Filestorage_Common {
$this->entries = array();
}
private function sendRequest($uri, $httpMethod, $postData = null, $extraHeaders = null, $isDownload = false, $returnHeaders = false, $isContentXML = true) {
private function sendRequest($uri, $httpMethod, $postData = null, $extraHeaders = null, $isDownload = false, $returnHeaders = false, $isContentXML = true, $returnHTTPCode = false) {
$uri = trim($uri);
// create an associative array from each key/value url query param pair.
$params = array();
@ -108,6 +108,8 @@ class OC_Filestorage_Google extends OC_Filestorage_Common {
if ($httpCode <= 308) {
if ($isDownload) {
return $tmpFile;
} else if ($returnHTTPCode) {
return array('result' => $result, 'code' => $httpCode);
} else {
return $result;
}
@ -425,7 +427,7 @@ class OC_Filestorage_Google extends OC_Filestorage_Common {
$etag = $entry->getAttribute('gd:etag');
$links = $entry->getElementsByTagName('link');
foreach ($links as $link) {
if ($link->getAttribute('rel') == 'http://schemas.google.com/g/2005#resumable-edit-media') {
if ($link->getAttribute('rel') == 'http://schemas.google.com/g/2005#resumable-create-media') {
$uploadUri = $link->getAttribute('href');
break;
}
@ -461,12 +463,12 @@ class OC_Filestorage_Google extends OC_Filestorage_Common {
}
}
$end = $i + $chunkSize - 1;
$headers = array('Content-Length: '.$chunkSize, 'Content-Type: '.$mimetype, 'Content Range: bytes '.$i.'-'.$end.'/'.$size);
$headers = array('Content-Length: '.$chunkSize, 'Content-Type: '.$mimetype, 'Content-Range: bytes '.$i.'-'.$end.'/'.$size);
$postData = fread($handle, $chunkSize);
$result = $this->sendRequest($uploadUri, 'PUT', $postData, $headers, false, true, false);
if ($result) {
// Get next location to upload file chunk
if (preg_match('@^Location: (.*)$@m', $result, $matches)) {
$result = $this->sendRequest($uploadUri, 'PUT', $postData, $headers, false, true, false, true);
if ($result['code'] == '308') {
if (preg_match('@^Location: (.*)$@m', $result['result'], $matches)) {
// Get next location to upload file chunk
$uploadUri = trim($matches[1]);
}
$i += $chunkSize;

@ -47,6 +47,52 @@ class OC_FileStorage_SMB extends OC_FileStorage_StreamWrapper{
$path=substr($path,0,-1);
}
return 'smb://'.$this->user.':'.$this->password.'@'.$this->host.$this->share.$this->root.$path;
}
public function stat($path){
if(!$path and $this->root=='/'){//mtime doesn't work for shares
$mtime=$this->shareMTime();
$stat=stat($this->constructUrl($path));
$stat['mtime']=$mtime;
return $stat;
}else{
return stat($this->constructUrl($path));
}
}
public function filetype($path){
return (bool)@$this->opendir($path);//using opendir causes the same amount of requests and caches the content of the folder in one go
}
/**
* check if a file or folder has been updated since $time
* @param int $time
* @return bool
*/
public function hasUpdated($path,$time){
if(!$path and $this->root=='/'){
//mtime doesn't work for shares, but giving the nature of the backend, doing a full update is still just fast enough
return true;
}else{
$actualTime=$this->filemtime($path);
return $actualTime>$time;
}
}
/**
* get the best guess for the modification time of the share
*/
private function shareMTime(){
$dh=$this->opendir('');
$lastCtime=0;
while($file=readdir($dh)){
if($file!='.' and $file!='..'){
$ctime=$this->filemtime($file);
if($ctime>$lastCtime){
$lastCtime=$ctime;
}
}
}
return $lastCtime;
}
}

@ -22,7 +22,7 @@ function viewImage(dir, file) {
if(file.indexOf('.psd')>0){//can't view those
return;
}
var location=OC.filePath('files','ajax','download.php')+'?files='+encodeURIComponent(file)+'&dir='+encodeURIComponent(dir);
var location=OC.filePath('files','ajax','download.php')+encodeURIComponent('?files='+encodeURIComponent(file)+'&dir='+encodeURIComponent(dir));
$.fancybox({
"href": location,
"title": file.replace(/</, "&lt;").replace(/>/, "&gt;"),

@ -13,7 +13,7 @@ function hidePDFviewer() {
function showPDFviewer(dir,filename){
if(!showPDFviewer.shown){
$("#editor").hide();
var url = OC.filePath('files','ajax','download.php')+'?files='+encodeURIComponent(filename)+"&dir="+encodeURIComponent(dir);
var url = OC.filePath('files','ajax','download.php')+encodeURIComponent('?files='+encodeURIComponent(filename)+"&dir="+encodeURIComponent(dir));
$('table').hide();
function im(path) { return OC.filePath('files_pdfviewer','js','pdfjs/web/images/'+path); }
showPDFviewer.oldcode = $("#controls").html();

@ -1,15 +1,20 @@
<?php
require_once('apps/files_sharing/sharedstorage.php');
OC::$CLASSPATH['OC_Share'] = "apps/files_sharing/lib_share.php";
OC::$CLASSPATH['OC_Filestorage_Shared'] = "apps/files_sharing/sharedstorage.php";
OCP\App::registerAdmin('files_sharing', 'settings');
OCP\Util::connectHook('OC_Filesystem', 'setup', 'OC_Filestorage_Shared', 'setup');
OCP\Util::connectHook("OC_Filesystem", "post_delete", "OC_Share", "deleteItem");
OCP\Util::connectHook("OC_Filesystem", "post_rename", "OC_Share", "renameItem");
OCP\Util::connectHook("OC_Filesystem", "post_write", "OC_Share", "updateItem");
OCP\Util::connectHook('OC_User', 'post_deleteUser', 'OC_Share', 'removeUser');
OCP\Util::connectHook('OC_User', 'post_addToGroup', 'OC_Share', 'addToGroupShare');
OCP\Util::connectHook('OC_User', 'post_removeFromGroup', 'OC_Share', 'removeFromGroupShare');
$dir = isset($_GET['dir']) ? $_GET['dir'] : '/';
if ($dir != '/Shared' || OCP\Config::getAppValue('files_sharing', 'resharing', 'yes') == 'yes') {
OCP\Util::addscript("files_sharing", "share");

@ -61,7 +61,7 @@ if (isset($_GET['token']) && $source = OC_Share::getSource($_GET['token'])) {
$list->assign("downloadURL", OCP\Util::linkTo("", "public.php")."?service=files&token=".$token."&path=");
$list->assign("readonly", true);
$tmpl = new OCP\Template("files", "index", "user");
$tmpl->assign("fileList", $list->fetchPage());
$tmpl->assign("fileList", $list->fetchPage(), false);
$tmpl->assign("breadcrumb", $breadcrumbNav->fetchPage());
$tmpl->assign("readonly", true);
$tmpl->assign("allowZipDownload", false);
@ -77,6 +77,7 @@ if (isset($_GET['token']) && $source = OC_Share::getSource($_GET['token'])) {
header("Content-Length: " . OC_Filesystem::filesize($source));
//download the file
@ob_clean();
OCP\Util::emitHook('OC_Share', 'public-download', array('source'=>$source, 'token'=>$token);
OC_Filesystem::readfile($source);
}
} else {

@ -47,6 +47,7 @@ class OC_Share {
}
if ($uid_shared_with == self::PUBLICLINK) {
$token = sha1("$uid_shared_with-$source");
OCP\Util::emitHook('OC_Share', 'public', array('source'=>$source, 'token'=>$token, 'permissions'=>$permissions));
$query->execute(array($uid_owner, self::PUBLICLINK, $source, $token, $permissions));
$this->token = $token;
} else {
@ -118,6 +119,7 @@ class OC_Share {
if (isset($gid)) {
$uid = $uid."@".$gid;
}
OCP\Util::emitHook('OC_Share', 'user', array('source'=>$source, 'target'=>$target, 'with'=>$uid, 'permissions'=>$permissions));
$query->execute(array($uid_owner, $uid, $source, $target, $permissions));
}
}

@ -320,6 +320,11 @@ class OC_Filestorage_Shared extends OC_Filestorage {
public function file_get_contents($path) {
$source = $this->getSource($path);
if ($source) {
$info = array(
'target' => $this->datadir.$path,
'source' => $source,
);
OCP\Util::emitHook('OC_Filestorage_Shared', 'file_get_contents', $info);
$storage = OC_Filesystem::getStorage($source);
return $storage->file_get_contents($this->getInternalPath($source));
}
@ -329,6 +334,11 @@ class OC_Filestorage_Shared extends OC_Filestorage {
if ($this->is_writable($path)) {
$source = $this->getSource($path);
if ($source) {
$info = array(
'target' => $this->datadir.$path,
'source' => $source,
);
OCP\Util::emitHook('OC_Filestorage_Shared', 'file_put_contents', $info);
$storage = OC_Filesystem::getStorage($source);
$result = $storage->file_put_contents($this->getInternalPath($source), $data);
if ($result) {
@ -416,6 +426,12 @@ class OC_Filestorage_Shared extends OC_Filestorage {
public function fopen($path, $mode) {
$source = $this->getSource($path);
if ($source) {
$info = array(
'target' => $this->datadir.$path,
'source' => $source,
'mode' => $mode,
);
OCP\Util::emitHook('OC_Filestorage_Shared', 'fopen', $info);
$storage = OC_Filesystem::getStorage($source);
return $storage->fopen($this->getInternalPath($source), $mode);
}
@ -508,16 +524,18 @@ class OC_Filestorage_Shared extends OC_Filestorage {
}
}
public static function setup() {
OC_Filesystem::mount('OC_Filestorage_Shared', array('datadir' => '/'.OCP\USER::getUser().'/files/Shared'), '/'.OCP\USER::getUser().'/files/Shared/');
public static function setup($options) {
$user_dir = $options['user_dir'];
OC_Filesystem::mount('OC_Filestorage_Shared', array('datadir' => $user_dir.'/Shared'), $user_dir.'/Shared/');
}
/**
* check if a file or folder has been updated since $time
* @param int $time
* @return bool
*/
public function hasUpdated($path,$time){
//TODO
return $this->filemtime($path)>$time;
}
}
if (OCP\USER::isLoggedIn()) {
OC_Filestorage_Shared::setup();
} else {
OCP\Util::connectHook('OC_User', 'post_login', 'OC_Filestorage_Shared', 'setup');
}
?>

@ -0,0 +1,22 @@
<?php
/**
* Copyright (c) 2012 Bart Visscher <bartv@thisnet.nl>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
OC::$CLASSPATH['OC_Files_Sharing_Log'] = 'apps/files_sharing_log/log.php';
$l=new OC_L10N('files_sharing_log');
OCP\App::addNavigationEntry( array(
'id' => 'files_sharing_log_index',
'order' => 5,
'href' => OCP\Util::linkTo( 'files_sharing_log', 'index.php' ),
'icon' => OCP\Util::imagePath( 'files_sharing_log', 'icon.png' ),
'name' => $l->t('Shared files log'))
);
OCP\Util::connectHook('OC_Filestorage_Shared', 'fopen', 'OC_Files_Sharing_Log', 'fopen');
OCP\Util::connectHook('OC_Filestorage_Shared', 'file_get_contents', 'OC_Files_Sharing_Log', 'file_get_contents');
OCP\Util::connectHook('OC_Filestorage_Shared', 'file_put_contents', 'OC_Files_Sharing_Log', 'file_put_contents');

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="ISO-8859-1" ?>
<database>
<name>*dbname*</name>
<create>true</create>
<overwrite>false</overwrite>
<charset>latin1</charset>
<table>
<name>*dbprefix*sharing_log</name>
<declaration>
<field>
<name>user_id</name>
<type>text</type>
<notnull>true</notnull>
<length>64</length>
</field>
<field>
<name>source</name>
<type>text</type>
<notnull>true</notnull>
<length>128</length>
</field>
<field>
<name>uid_who</name>
<type>text</type>
<notnull>true</notnull>
<length>64</length>
</field>
<field>
<name>when</name>
<type>integer</type>
<default></default>
<notnull>false</notnull>
<unsigned>true</unsigned>
<length>4</length>
</field>
<field>
<name>mode</name>
<type>text</type>
<notnull>true</notnull>
<length>4</length>
</field>
</declaration>
</table>
</database>

@ -0,0 +1,10 @@
<?xml version="1.0"?>
<info>
<id>files_sharing_log</id>
<name>File Shared access logging app</name>
<description>Log access to shared files</description>
<licence>AGPL</licence>
<author>Bart Visscher</author>
<require>4</require>
<shipped>true</shipped>
</info>

@ -0,0 +1,7 @@
#files_sharing_log {
padding: 2em;
}
#files_sharing_log th,
#files_sharing_log td {
padding: 0 1em;
}

@ -0,0 +1,21 @@
<?php
/**
* Copyright (c) 2012 Bart Visscher <bartv@thisnet.nl>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
OCP\User::checkLoggedIn();
OCP\App::checkAppEnabled('files_sharing_log');
OCP\App::setActiveNavigationEntry('files_sharing_log_index');
OCP\Util::addStyle('files_sharing_log', 'style');
$query = OCP\DB::prepare('SELECT * FROM *PREFIX*sharing_log WHERE user_id = ?');
$log = $query->execute(array(OCP\User::getUser()))->fetchAll();
$output = new OCP\Template('files_sharing_log', 'index', 'user');
$output->assign('log', $log);
$output->printPage();

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

Loading…
Cancel
Save