Projects
Kolab:16
iRony
Log In
Username
Password
We truncated the diff of some files because they were too big. If you want to see the full diff for every file,
click here
.
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 30
View file
iRony.spec
Changed
@@ -37,7 +37,7 @@ %global _ap_sysconfdir %{_sysconfdir}/%{httpd_name} Name: iRony -Version: 0.4.5 +Version: 0.4.6 Release: 1%{?dist} Summary: DAV for Kolab Groupware @@ -53,12 +53,6 @@ BuildArch: noarch Requires: chwala >= 0.5.2 -%if 0%{?rhel} < 8 -Requires: php-sabre-dav >= 2.1.11 -Requires: php-sabre-event >= 2.0.2 -Requires: php-sabre-http >= 3.0.5 -Requires: php-sabre-vobject >= 3.5.3 -%endif Requires: roundcubemail(core) >= 1.3 %if 0%{?plesk} < 1 Requires: roundcubemail-plugin-kolab_auth >= 3.3.6 @@ -109,19 +103,6 @@ %setup -q %build -rm -rvf vendor/sabre - -%if 0%{?rhel} < 8 -rm -rf composer.json -mv composer.json-dist composer.json -mkdir -p $HOME/.composer/ -echo '{}' > $HOME/.composer/composer.json -%if 0%{?fedora} >= 25 -# workaround for misbehaving Kolab modules for PHP7, probably a swig issue -export USE_ZEND_ALLOC=0 -%endif -composer -vvv dumpautoload --optimize -%endif %install mkdir -p \ @@ -162,6 +143,11 @@ ln -s ../../../..%{_sysconfdir}/roundcubemail/config.inc.php popd +%if 0%{?rhel} < 8 +rm -rf vendor +ln -s ../roundcubemail/vendor vendor +%endif + rm -rf lib/Roundcube pushd lib/ ln -s ../../chwala/lib FileAPI @@ -185,8 +171,8 @@ %if 0%{?plesk} < 1 %config(noreplace) %{_ap_sysconfdir}/conf.d/%{name}.conf %endif -%attr(0750,root,%{httpd_group}) %dir %{_sysconfdir}/%{name} -%attr(0640,root,%{httpd_group}) %config(noreplace) %{_sysconfdir}/%{name}/dav.inc.php +%attr(0755,root,%{httpd_group}) %dir %{_sysconfdir}/%{name} +%attr(0644,root,%{httpd_group}) %config(noreplace) %{_sysconfdir}/%{name}/dav.inc.php %config(noreplace) %{_sysconfdir}/logrotate.d/%{name} %{_datadir}/%{name} %attr(0770,%{httpd_user},%{httpd_group}) %{_localstatedir}/cache/%{name} @@ -194,6 +180,10 @@ %attr(0770,%{httpd_user},%{httpd_group}) %{_localstatedir}/log/%{name} %changelog +* Sat Dec 25 2020 Christian Mollekopf <mollekopf@kolabsys.com> - 0.4.5-2 +- Fixed configuration directory permissions +- Link to roundcubemail vendor directory in ootpa + * Mon Oct 19 2020 Jeroen van Meeuwen <vanmeeuwen@kolabsys.com> - 0.4.5-1 - Release of version 0.4.5
View file
add-sabre21-path-for-debian.patch
Deleted
@@ -1,11 +0,0 @@ -diff -u iRony-0.4.orig/composer.json-dist iRony-0.4/composer.json-dist ---- iRony-0.4.orig/composer.json-dist 2016-03-13 23:48:10.000000000 +0100 -+++ iRony-0.4/composer.json-dist 2016-12-07 10:22:02.000000000 +0100 -@@ -11,6 +11,7 @@ - "": "/usr/share/pear/" - }, - "psr-4": { -+ "Sabre\\": "/usr/share/php/sabre21/Sabre/", - "": "/usr/share/php/" - } - }
View file
debian.changelog
Changed
@@ -1,3 +1,9 @@ +irony (0.4.6-1~kolab1) unstable; urgency=low + + * Release of version 0.4.6 + + -- Jeroen van Meeuwen <vanmeeuwen@kolabsys.com> Tue, 11 Jan 2022 12:12:13 +0100 + irony (0.4.5-1~kolab2) unstable; urgency=low * Release of version 0.4.5
View file
debian.rules
Changed
@@ -7,23 +7,6 @@ dh $@ override_dh_auto_configure: - rm -rvf vendor/sabre - - rm -rf composer.json - mv composer.json-dist composer.json - mkdir -p $$HOME/.composer/ - echo '{}' > $$HOME/.composer/composer.json - sed -i \ - -e 's/"\^/"/g' \ - composer.lock \ - vendor/composer/installed.json - - composer -vvv dumpautoload --optimize - - # Fix wrong paths generated by Composer: they contain one '../' too many - sed -i 's/\/\.\.\/\.\.\/\.\.\//\/..\/..\//' \ - vendor/composer/autoload_*.php - if [ -f "/etc/plesk-release" ]; then \ sed -i -e 's/www-data adm/roundcube_sysuser roundcube_sysgroup/g' debian/irony.logrotate ; \ fi
View file
debian.series
Changed
@@ -1,1 +0,0 @@ -add-sabre21-path-for-debian.patch -p1
View file
iRony-0.4.5.tar.gz/composer.lock -> iRony-0.4.6.tar.gz/composer.lock
Changed
@@ -78,6 +78,11 @@ "framework", "iCalendar" ], + "support": { + "forum": "https://groups.google.com/group/sabredav-discuss", + "issues": "https://github.com/sabre-io/dav/issues", + "source": "https://github.com/fruux/sabre-dav" + }, "time": "2016-10-07T03:29:06+00:00" }, { @@ -129,6 +134,11 @@ "promise", "signal" ], + "support": { + "forum": "https://groups.google.com/group/sabredav-discuss", + "issues": "https://github.com/sabre-io/event/issues", + "source": "https://github.com/fruux/sabre-event" + }, "time": "2015-05-19T10:24:22+00:00" }, { @@ -180,6 +190,11 @@ "keywords": [ "http" ], + "support": { + "forum": "https://groups.google.com/group/sabredav-discuss", + "issues": "https://github.com/sabre-io/http/issues", + "source": "https://github.com/fruux/sabre-http" + }, "time": "2015-05-11T15:25:57+00:00" }, { @@ -246,42 +261,42 @@ "jCard", "vCard" ], + "support": { + "forum": "https://groups.google.com/group/sabredav-discuss", + "issues": "https://github.com/sabre-io/vobject/issues", + "source": "https://github.com/fruux/sabre-vobject" + }, "time": "2016-10-07T03:20:40+00:00" } ], "packages-dev": [ { "name": "doctrine/instantiator", - "version": "1.3.1", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "f350df0268e904597e3bd9c4685c53e0e333feea" + "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/f350df0268e904597e3bd9c4685c53e0e333feea", - "reference": "f350df0268e904597e3bd9c4685c53e0e333feea", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b", + "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^6.0", + "doctrine/coding-standard": "^8.0", "ext-pdo": "*", "ext-phar": "*", - "phpbench/phpbench": "^0.13", - "phpstan/phpstan-phpunit": "^0.11", - "phpstan/phpstan-shim": "^0.11", - "phpunit/phpunit": "^7.0" + "phpbench/phpbench": "^0.13 || 1.0.0-alpha2", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-phpunit": "^0.12", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } - }, "autoload": { "psr-4": { "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" @@ -295,7 +310,7 @@ { "name": "Marco Pivetta", "email": "ocramius@gmail.com", - "homepage": "http://ocramius.github.com/" + "homepage": "https://ocramius.github.io/" } ], "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", @@ -304,6 +319,10 @@ "constructor", "instantiate" ], + "support": { + "issues": "https://github.com/doctrine/instantiator/issues", + "source": "https://github.com/doctrine/instantiator/tree/1.4.0" + }, "funding": [ { "url": "https://www.doctrine-project.org/sponsorship.html", @@ -318,7 +337,7 @@ "type": "tidelift" } ], - "time": "2020-05-29T17:27:14+00:00" + "time": "2020-11-10T18:47:58+00:00" }, { "name": "kolab/net_ldap3", @@ -326,12 +345,13 @@ "source": { "type": "git", "url": "https://git.kolab.org/diffusion/PNL/php-net_ldap.git", - "reference": "e1835e36fa5d3434f9804670fc3cdd16992ec66a" + "reference": "ec4f0d6918aa4b5364e99e1132e0a5a9b3ab23ab" }, "require": { "pear/net_ldap2": ">=2.0.12", "php": ">=5.3.3" }, + "default-branch": true, "type": "library", "autoload": { "classmap": [ @@ -365,7 +385,7 @@ "pear", "vlv" ], - "time": "2019-10-21T11:18:59+00:00" + "time": "2021-11-11T09:02:56+00:00" }, { "name": "pear/auth_sasl", @@ -418,6 +438,10 @@ } ], "description": "Abstraction of various SASL mechanism responses", + "support": { + "issues": "http://pear.php.net/bugs/search.php?cmd=display&package_name[]=Auth_SASL", + "source": "https://github.com/pear/Auth_SASL" + }, "time": "2017-03-07T14:37:05+00:00" }, { @@ -465,24 +489,29 @@ } ], "description": "More info available on: http://pear.php.net/package/Console_Getopt", + "support": { + "issues": "http://pear.php.net/bugs/search.php?cmd=display&package_name[]=Console_Getopt", + "source": "https://github.com/pear/Console_Getopt" + }, "time": "2019-11-20T18:27:48+00:00" }, { "name": "pear/mail_mime", - "version": "1.10.9", + "version": "1.10.11", "source": { "type": "git", "url": "https://github.com/pear/Mail_Mime.git", - "reference": "1e7ae4e5258b6c0d385a8e76add567934245d38d" + "reference": "d4fb9ce61201593d0f8c6db629c45e29c3409c14" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pear/Mail_Mime/zipball/1e7ae4e5258b6c0d385a8e76add567934245d38d", - "reference": "1e7ae4e5258b6c0d385a8e76add567934245d38d", + "url": "https://api.github.com/repos/pear/Mail_Mime/zipball/d4fb9ce61201593d0f8c6db629c45e29c3409c14", + "reference": "d4fb9ce61201593d0f8c6db629c45e29c3409c14", "shasum": "" }, "require": { - "pear/pear-core-minimal": "*" + "pear/pear-core-minimal": "*", + "php": ">=5.2.0" }, "type": "library", "autoload": { @@ -495,7 +524,7 @@ "./" ], "license": [ - "BSD-3-clause" + "BSD-3-Clause" ], "authors": [
View file
iRony-0.4.5.tar.gz/lib/Kolab/CalDAV/CalendarBackend.php -> iRony-0.4.6.tar.gz/lib/Kolab/CalDAV/CalendarBackend.php
Changed
@@ -300,6 +300,11 @@ continue; } + // Make sure to not return invalid objects + if (empty($event) || empty($event['uid'])) { + continue; + } + // get tags/categories from relations $this->load_tags($event);
View file
iRony-0.4.5.tar.gz/lib/Roundcube/bootstrap.php -> iRony-0.4.6.tar.gz/lib/Roundcube/bootstrap.php
Changed
@@ -58,7 +58,7 @@ } // framework constants -define('RCUBE_VERSION', '1.4.9'); +define('RCUBE_VERSION', '1.4.11'); define('RCUBE_CHARSET', 'UTF-8'); define('RCUBE_TEMP_FILE_PREFIX', 'RCMTEMP');
View file
iRony-0.4.5.tar.gz/lib/Roundcube/rcube_imap.php -> iRony-0.4.6.tar.gz/lib/Roundcube/rcube_imap.php
Changed
@@ -2356,7 +2356,7 @@ $filename_encoded = $fmatches[2]; } - $part->filename = rcube_charset::convert(urldecode($filename_encoded), $filename_charset); + $part->filename = rcube_charset::convert(rawurldecode($filename_encoded), $filename_charset); } }
View file
iRony-0.4.5.tar.gz/lib/Roundcube/rcube_ldap.php -> iRony-0.4.6.tar.gz/lib/Roundcube/rcube_ldap.php
Changed
@@ -884,6 +884,9 @@ $filter = 'e:' . $filter; } + // Reset the previous search result + $this->reset(); + // set filter string and execute search $this->set_search_set($filter);
View file
iRony-0.4.5.tar.gz/lib/Roundcube/rcube_message.php -> iRony-0.4.6.tar.gz/lib/Roundcube/rcube_message.php
Changed
@@ -49,6 +49,7 @@ private $mime; private $opt = array(); private $parse_alternative = false; + private $tnef_decode = false; public $uid; public $folder; @@ -104,6 +105,8 @@ return; } + $this->tnef_decode = (bool) $this->app->config->get('tnef_decode', true); + $this->set_safe($is_safe || $_SESSION['safe_messages'][$this->folder.':'.$uid]); $this->opt = array( 'safe' => $this->is_safe, @@ -378,7 +381,13 @@ $last = $parent->real_mimetype ?: $parent->mimetype; if (!preg_match('/^multipart\/(alternative|related|signed|encrypted|mixed)$/', $last) - || ($last == 'multipart/mixed' && $parent_depth < $max_delta)) { + || ($last == 'multipart/mixed' && $parent_depth < $max_delta) + ) { + // The HTML body part extracted from a winmail.dat attachment part + if (strpos($part->mime_id, 'winmail.') === 0) { + return true; + } + continue 2; } } @@ -817,11 +826,35 @@ continue; } // part is Microsoft Outlook TNEF (winmail.dat) - else if ($part_mimetype == 'application/ms-tnef') { + else if ($part_mimetype == 'application/ms-tnef' && $this->tnef_decode) { $tnef_parts = (array) $this->tnef_decode($mail_part); + $tnef_body = ''; + foreach ($tnef_parts as $tpart) { $this->mime_parts[$tpart->mime_id] = $tpart; - $this->add_part($tpart, 'attachment'); + + if (strpos($tpart->mime_id, '.html')) { + $tnef_body = $tpart->body; + if ($this->opt['prefer_html']) { + $tpart->type = 'content'; + + // Reset type on the plain text part that usually is added to winmail.dat messages + // (on the same level in the structure as the attachment itself) + $level = count(explode('.', $mail_part->mime_id)); + foreach ($this->parts as $p) { + if ($p->type == 'content' && $p->mimetype == 'text/plain' + && count(explode('.', $p->mime_id)) == $level + ) { + $p->type = null; + } + } + } + $this->add_part($tpart); + } + else { + $inline = !empty($tpart->content_id) && strpos($tnef_body, "cid:{$tpart->content_id}") !== false; + $this->add_part($tpart, $inline ? 'inline' : 'attachment'); + } } // add winmail.dat to the list if it's content is unknown @@ -1002,6 +1035,26 @@ unset($body); + // HTML body + if ( + !empty($tnef_arr['message']) + && !empty($tnef_arr['message']['size']) + && $tnef_arr['message']['subtype'] == 'html' + ) { + $tpart = new rcube_message_part; + + $tpart->encoding = 'stream'; + $tpart->ctype_primary = 'text'; + $tpart->ctype_secondary = 'html'; + $tpart->mimetype = 'text/html'; + $tpart->mime_id = 'winmail.' . $part->mime_id . '.html'; + $tpart->size = $tnef_arr['message']['size']; + $tpart->body = $tnef_arr['message']['stream']; + + $parts[] = $tpart; + } + + // Attachments foreach ($tnef_arr['attachments'] as $pid => $winatt) { $tpart = new rcube_message_part; @@ -1014,6 +1067,10 @@ $tpart->size = $winatt['size']; $tpart->body = $winatt['stream']; + if (!empty($winatt['content-id'])) { + $tpart->content_id = $winatt['content-id']; + } + $parts[] = $tpart; unset($tnef_arr[$pid]); }
View file
iRony-0.4.5.tar.gz/lib/Roundcube/rcube_string_replacer.php -> iRony-0.4.6.tar.gz/lib/Roundcube/rcube_string_replacer.php
Changed
@@ -25,7 +25,7 @@ */ class rcube_string_replacer { - public static $pattern = '/##str_replacement_(\d+)##/'; + public $pattern; public $mailto_pattern; public $link_pattern; public $linkref_index; @@ -45,6 +45,10 @@ */ function __construct($options = array()) { + // Create hard-to-guess replacement string + $uniq_ident = sprintf('%010d%010d', mt_rand(), mt_rand()); + $this->pattern = '/##' . $uniq_ident . '##(\d+)##/'; + // Simplified domain expression for UTF8 characters handling // Support unicode/punycode in top-level domain part $utf_domain = '[^?&@"\'\\/()<>\s\r\t\n]+\\.?([^\\x00-\\x2f\\x3b-\\x40\\x5b-\\x60\\x7b-\\x7f]{2,}|xn--[a-zA-Z0-9]{2,})'; @@ -55,7 +59,7 @@ $link_prefix = "([\w]+:\/\/|{$this->noword}[Ww][Ww][Ww]\.|^[Ww][Ww][Ww]\.)"; $this->options = $options; - $this->linkref_index = '/\[([^\]#]+)\](:?\s*##str_replacement_(\d+)##)/'; + $this->linkref_index = '/\[([^\]#]+)\](:?\s*' . substr($this->pattern, 1, -1) . ')/'; $this->linkref_pattern = '/\[([^\]#]+)\]/'; $this->link_pattern = "/$link_prefix($utf_domain([$url1]*[$url2]+)*)/"; $this->mailto_pattern = "/(" @@ -88,7 +92,7 @@ */ public function get_replacement($i) { - return '##str_replacement_' . $i . '##'; + return str_replace('(\d+)', $i, substr($this->pattern, 1, -1)); } /** @@ -135,7 +139,7 @@ public function linkref_addindex($matches) { $key = $matches[1]; - $this->linkrefs[$key] = $this->urls[$matches[3]]; + $this->linkrefs[$key] = isset($this->urls[$matches[3]]) ? $this->urls[$matches[3]] : null; return $this->get_replacement($this->add('['.$key.']')) . $matches[2]; } @@ -185,7 +189,7 @@ */ public function replace_callback($matches) { - return $this->values[$matches[1]]; + return isset($this->values[$matches[1]]) ? $this->values[$matches[1]] : null; } /** @@ -216,7 +220,7 @@ */ public function resolve($str) { - return preg_replace_callback(self::$pattern, array($this, 'replace_callback'), $str); + return preg_replace_callback($this->pattern, array($this, 'replace_callback'), $str); } /**
View file
iRony-0.4.5.tar.gz/lib/Roundcube/rcube_tnef_decoder.php -> iRony-0.4.6.tar.gz/lib/Roundcube/rcube_tnef_decoder.php
Changed
@@ -362,6 +362,10 @@ $result['subtype'] = $value[1]; break; + case self::MAPI_ATTACH_CONTENT_ID: + $result['content-id'] = $value; + break; + case self::MAPI_ATTACH_DATA: $this->_getx($value, 16); $att = new rcube_tnef_decoder;
View file
iRony-0.4.5.tar.gz/lib/Roundcube/rcube_utils.php -> iRony-0.4.6.tar.gz/lib/Roundcube/rcube_utils.php
Changed
@@ -399,7 +399,7 @@ $styles = preg_replace('/position[^a-z]*:[\s\r\n]*fixed/i', 'position: absolute', $styles); // Remove 'page' attributes (#7604) - $styles = preg_replace('/(^|[\n\s;])page:[^;]+;*/im', '', $styles); + $styles = preg_replace('/((^|[\n\s;])page:)[^;]+;*/im', '\\1 unset;', $styles); // check every line of a style block... if ($allow_remote) { @@ -435,10 +435,10 @@ // add #container to each tag selector and prefix to id/class identifiers if ($container_id || $prefix) { - // (?!##str) below is to not match with ##str_replacement_0## - // from rcube_string_replacer used above, this is needed for - // cases like @media { body { position: fixed; } } (#5811) - $regexp = '/(^\s*|,\s*|\}\s*|\{\s*)((?!##str):?[a-z0-9\._#\*\[][a-z0-9\._:\(\)#=~ \[\]"\|\>\+\$\^-]*)/im'; + // Exclude rcube_string_replacer pattern matches, this is needed + // for cases like @media { body { position: fixed; } } (#5811) + $excl = '(?!' . substr($replacements->pattern, 1, -1) . ')'; + $regexp = '/(^\s*|,\s*|\}\s*|\{\s*)(' . $excl . ':?[a-z0-9\._#\*\[][a-z0-9\._:\(\)#=~ \[\]"\|\>\+\$\^-]*)/im'; $callback = function($matches) use ($container_id, $prefix) { $replace = $matches[2];
View file
iRony-0.4.5.tar.gz/lib/Roundcube/spellchecker/googie.php -> iRony-0.4.6.tar.gz/lib/Roundcube/spellchecker/googie.php
Changed
@@ -26,9 +26,6 @@ */ class rcube_spellchecker_googie extends rcube_spellchecker_engine { - const GOOGIE_HOST = 'ssl://spell.roundcube.net'; - const GOOGIE_PORT = 443; - private $matches = array(); private $content; @@ -71,9 +68,8 @@ $path = $a_uri['path'] . ($a_uri['query'] ? '?'.$a_uri['query'] : '') . $this->lang; } else { - $host = self::GOOGIE_HOST; - $port = self::GOOGIE_PORT; - $path = '/tbproxy/spell?lang=' . $this->lang; + $this->error = "Missing 'spellcheck_uri' config option"; + return $this->matches = array(); } $path .= sprintf('&key=%06d', $_SESSION['user_id']);
View file
iRony-0.4.5.tar.gz/lib/plugins/calendar/calendar.php -> iRony-0.4.6.tar.gz/lib/plugins/calendar/calendar.php
Changed
@@ -25,3573 +25,3947 @@ class calendar extends rcube_plugin { - const FREEBUSY_UNKNOWN = 0; - const FREEBUSY_FREE = 1; - const FREEBUSY_BUSY = 2; - const FREEBUSY_TENTATIVE = 3; - const FREEBUSY_OOF = 4; - - const SESSION_KEY = 'calendar_temp'; - - public $task = '?(?!logout).*'; - public $rc; - public $lib; - public $resources_dir; - public $home; // declare public to be used in other classes - public $urlbase; - public $timezone; - public $timezone_offset; - public $gmt_offset; - public $ui; - - public $defaults = array( - 'calendar_default_view' => "agendaWeek", - 'calendar_timeslots' => 2, - 'calendar_work_start' => 6, - 'calendar_work_end' => 18, - 'calendar_agenda_range' => 60, - 'calendar_event_coloring' => 0, - 'calendar_time_indicator' => true, - 'calendar_allow_invite_shared' => false, - 'calendar_itip_send_option' => 3, - 'calendar_itip_after_action' => 0, - ); - -// These are implemented with __get() -// private $ical; -// private $itip; -// private $driver; - - - /** - * Plugin initialization. - */ - function init() - { - $this->rc = rcube::get_instance(); - - $this->register_task('calendar', 'calendar'); - - // load calendar configuration - $this->load_config(); - - // catch iTIP confirmation requests that don're require a valid session - if ($this->rc->action == 'attend' && !empty($_REQUEST['_t'])) { - $this->add_hook('startup', array($this, 'itip_attend_response')); - } - else if ($this->rc->action == 'feed' && !empty($_REQUEST['_cal'])) { - $this->add_hook('startup', array($this, 'ical_feed_export')); - } - else if ($this->rc->task != 'login') { - // default startup routine - $this->add_hook('startup', array($this, 'startup')); - } - - $this->add_hook('user_delete', array($this, 'user_delete')); - } - - /** - * Setup basic plugin environment and UI - */ - protected function setup() - { - $this->require_plugin('libcalendaring'); - $this->require_plugin('libkolab'); - - $this->lib = libcalendaring::get_instance(); - $this->timezone = $this->lib->timezone; - $this->gmt_offset = $this->lib->gmt_offset; - $this->dst_active = $this->lib->dst_active; - $this->timezone_offset = $this->gmt_offset / 3600 - $this->dst_active; - - // load localizations - $this->add_texts('localization/', $this->rc->task == 'calendar' && (!$this->rc->action || $this->rc->action == 'print')); - - require($this->home . '/lib/calendar_ui.php'); - $this->ui = new calendar_ui($this); - } - - /** - * Startup hook - */ - public function startup($args) - { - // the calendar module can be enabled/disabled by the kolab_auth plugin - if ($this->rc->config->get('calendar_disabled', false) || !$this->rc->config->get('calendar_enabled', true)) - return; - - $this->setup(); - - // load Calendar user interface - if (!$this->rc->output->ajax_call && (!$this->rc->output->env['framed'] || $args['action'] == 'preview')) { - $this->ui->init(); - - // settings are required in (almost) every GUI step - if ($args['action'] != 'attend') - $this->rc->output->set_env('calendar_settings', $this->load_settings()); + const FREEBUSY_UNKNOWN = 0; + const FREEBUSY_FREE = 1; + const FREEBUSY_BUSY = 2; + const FREEBUSY_TENTATIVE = 3; + const FREEBUSY_OOF = 4; + + const SESSION_KEY = 'calendar_temp'; + + public $task = '?(?!logout).*'; + public $rc; + public $lib; + public $resources_dir; + public $home; // declare public to be used in other classes + public $urlbase; + public $timezone; + public $timezone_offset; + public $gmt_offset; + public $ui; + + public $defaults = [ + 'calendar_default_view' => "agendaWeek", + 'calendar_timeslots' => 2, + 'calendar_work_start' => 6, + 'calendar_work_end' => 18, + 'calendar_agenda_range' => 60, + 'calendar_show_weekno' => 0, + 'calendar_first_day' => 1, + 'calendar_first_hour' => 6, + 'calendar_time_format' => null, + 'calendar_event_coloring' => 0, + 'calendar_time_indicator' => true, + 'calendar_allow_invite_shared' => false, + 'calendar_itip_send_option' => 3, + 'calendar_itip_after_action' => 0, + ]; + + // These are implemented with __get() + // private $ical; + // private $itip; + // private $driver; + + + /** + * Plugin initialization. + */ + function init() + { + $this->rc = rcube::get_instance(); + + $this->register_task('calendar', 'calendar'); + + // load calendar configuration + $this->load_config(); + + // catch iTIP confirmation requests that don're require a valid session + if ($this->rc->action == 'attend' && !empty($_REQUEST['_t'])) { + $this->add_hook('startup', [$this, 'itip_attend_response']); + } + else if ($this->rc->action == 'feed' && !empty($_REQUEST['_cal'])) { + $this->add_hook('startup', [$this, 'ical_feed_export']); + } + else if ($this->rc->task != 'login') { + // default startup routine + $this->add_hook('startup', [$this, 'startup']); + } + + $this->add_hook('user_delete', [$this, 'user_delete']); + } + + /** + * Setup basic plugin environment and UI + */ + protected function setup() + { + $this->require_plugin('libcalendaring'); + $this->require_plugin('libkolab'); + + $this->lib = libcalendaring::get_instance(); + $this->timezone = $this->lib->timezone; + $this->gmt_offset = $this->lib->gmt_offset; + $this->dst_active = $this->lib->dst_active; + $this->timezone_offset = $this->gmt_offset / 3600 - $this->dst_active; + + // load localizations + $this->add_texts('localization/', $this->rc->task == 'calendar' && (!$this->rc->action || $this->rc->action == 'print')); + + require($this->home . '/lib/calendar_ui.php'); + $this->ui = new calendar_ui($this); + } + + /** + * Startup hook
View file
iRony-0.4.5.tar.gz/lib/plugins/calendar/calendar_ui.js -> iRony-0.4.6.tar.gz/lib/plugins/calendar/calendar_ui.js
Changed
@@ -82,6 +82,7 @@ dayNamesShort: settings.days_short, weekNumbers: settings.show_weekno > 0, weekNumberTitle: rcmail.gettext('weekshort', 'calendar') + ' ', + weekNumberCalculation: 'ISO', firstDay: settings.first_day, firstHour: settings.first_hour, slotDuration: {minutes: 60/settings.timeslots},
View file
iRony-0.4.5.tar.gz/lib/plugins/calendar/composer.json -> iRony-0.4.6.tar.gz/lib/plugins/calendar/composer.json
Changed
@@ -4,7 +4,7 @@ "description": "Calendar plugin", "homepage": "https://git.kolab.org/diffusion/RPK/", "license": "AGPLv3", - "version": "3.5.5", + "version": "3.5.10", "authors": [ { "name": "Thomas Bruederli", @@ -24,7 +24,7 @@ } ], "require": { - "php": ">=5.3.0", + "php": ">=5.4.0", "roundcube/plugin-installer": ">=0.1.3", "kolab/libcalendaring": ">=3.4.0", "kolab/libkolab": ">=3.4.0"
View file
iRony-0.4.5.tar.gz/lib/plugins/calendar/drivers/calendar_driver.php -> iRony-0.4.6.tar.gz/lib/plugins/calendar/drivers/calendar_driver.php
Changed
@@ -94,740 +94,770 @@ */ abstract class calendar_driver { - const FILTER_ALL = 0; - const FILTER_WRITEABLE = 1; - const FILTER_INSERTABLE = 2; - const FILTER_ACTIVE = 4; - const FILTER_PERSONAL = 8; - const FILTER_PRIVATE = 16; - const FILTER_CONFIDENTIAL = 32; - const FILTER_SHARED = 64; - const BIRTHDAY_CALENDAR_ID = '__bdays__'; - - // features supported by backend - public $alarms = false; - public $attendees = false; - public $freebusy = false; - public $attachments = false; - public $undelete = false; - public $history = false; - public $categoriesimmutable = false; - public $alarm_types = array('DISPLAY'); - public $alarm_absolute = true; - public $last_error; - - protected $default_categories = array( - 'Personal' => 'c0c0c0', - 'Work' => 'ff0000', - 'Family' => '00ff00', - 'Holiday' => 'ff6600', - ); - - /** - * Get a list of available calendars from this source - * - * @param integer Bitmask defining filter criterias. - * See FILTER_* constants for possible values. - * @return array List of calendars - */ - abstract function list_calendars($filter = 0); - - /** - * Create a new calendar assigned to the current user - * - * @param array Hash array with calendar properties - * name: Calendar name - * color: The color of the calendar - * showalarms: True if alarms are enabled - * @return mixed ID of the calendar on success, False on error - */ - abstract function create_calendar($prop); - - /** - * Update properties of an existing calendar - * - * @param array Hash array with calendar properties - * id: Calendar Identifier - * name: Calendar name - * color: The color of the calendar - * showalarms: True if alarms are enabled (if supported) - * @return boolean True on success, Fales on failure - */ - abstract function edit_calendar($prop); - - /** - * Set active/subscribed state of a calendar - * - * @param array Hash array with calendar properties - * id: Calendar Identifier - * active: True if calendar is active, false if not - * @return boolean True on success, Fales on failure - */ - abstract function subscribe_calendar($prop); - - /** - * Delete the given calendar with all its contents - * - * @param array Hash array with calendar properties - * id: Calendar Identifier - * @return boolean True on success, Fales on failure - */ - abstract function delete_calendar($prop); - - /** - * Search for shared or otherwise not listed calendars the user has access - * - * @param string Search string - * @param string Section/source to search - * @return array List of calendars - */ - abstract function search_calendars($query, $source); - - /** - * Add a single event to the database - * - * @param array Hash array with event properties (see header of this file) - * @return mixed New event ID on success, False on error - */ - abstract function new_event($event); - - /** - * Update an event entry with the given data - * - * @param array Hash array with event properties (see header of this file) - * @return boolean True on success, False on error - */ - abstract function edit_event($event); - - /** - * Extended event editing with possible changes to the argument - * - * @param array Hash array with event properties - * @param string New participant status - * @param array List of hash arrays with updated attendees - * @return boolean True on success, False on error - */ - public function edit_rsvp(&$event, $status, $attendees) - { - return $this->edit_event($event); - } - - /** - * Update the participant status for the given attendee - * - * @param array Hash array with event properties - * @param array List of hash arrays each represeting an updated attendee - * @return boolean True on success, False on error - */ - public function update_attendees(&$event, $attendees) - { - return $this->edit_event($event); - } - - /** - * Move a single event - * - * @param array Hash array with event properties: - * id: Event identifier - * start: Event start date/time as DateTime object - * end: Event end date/time as DateTime object - * allday: Boolean flag if this is an all-day event - * @return boolean True on success, False on error - */ - abstract function move_event($event); - - /** - * Resize a single event - * - * @param array Hash array with event properties: - * id: Event identifier - * start: Event start date/time as DateTime object with timezone - * end: Event end date/time as DateTime object with timezone - * @return boolean True on success, False on error - */ - abstract function resize_event($event); - - /** - * Remove a single event from the database - * - * @param array Hash array with event properties: - * id: Event identifier - * @param boolean Remove event irreversible (mark as deleted otherwise, - * if supported by the backend) - * - * @return boolean True on success, False on error - */ - abstract function remove_event($event, $force = true); - - /** - * Restores a single deleted event (if supported) - * - * @param array Hash array with event properties: - * id: Event identifier - * - * @return boolean True on success, False on error - */ - public function restore_event($event) - { - return false; - } - - /** - * Return data of a single event - * - * @param mixed UID string or hash array with event properties: - * id: Event identifier - * uid: Event UID - * _instance: Instance identifier in combination with uid (optional) - * calendar: Calendar identifier (optional) - * @param integer Bitmask defining the scope to search events in. - * See FILTER_* constants for possible values. - * @param boolean If true, recurrence exceptions shall be added - * - * @return array Event object as hash array - */ - abstract function get_event($event, $scope = 0, $full = false); - - /** - * Get events from source.
View file
iRony-0.4.5.tar.gz/lib/plugins/calendar/drivers/database/SQL/mysql.initial.sql -> iRony-0.4.6.tar.gz/lib/plugins/calendar/drivers/database/SQL/mysql.initial.sql
Changed
@@ -8,8 +8,7 @@ * @licence GNU AGPL * @copyright (c) 2010 Lazlo Westerhof - Netherlands * @copyright (c) 2014 Kolab Systems AG - * - **/ + */ CREATE TABLE IF NOT EXISTS `calendars` ( `calendar_id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, @@ -21,7 +20,7 @@ INDEX `user_name_idx` (`user_id`, `name`), CONSTRAINT `fk_calendars_user_id` FOREIGN KEY (`user_id`) REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE -) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */; +) ROW_FORMAT=DYNAMIC ENGINE=INNODB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE TABLE IF NOT EXISTS `events` ( `event_id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, @@ -55,7 +54,7 @@ INDEX `calendar_notify_idx` (`calendar_id`,`notifyat`), CONSTRAINT `fk_events_calendar_id` FOREIGN KEY (`calendar_id`) REFERENCES `calendars`(`calendar_id`) ON DELETE CASCADE ON UPDATE CASCADE -) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */; +) ROW_FORMAT=DYNAMIC ENGINE=INNODB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE TABLE IF NOT EXISTS `attachments` ( `attachment_id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, @@ -67,7 +66,7 @@ PRIMARY KEY(`attachment_id`), CONSTRAINT `fk_attachments_event_id` FOREIGN KEY (`event_id`) REFERENCES `events`(`event_id`) ON DELETE CASCADE ON UPDATE CASCADE -) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */; +) ROW_FORMAT=DYNAMIC ENGINE=INNODB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE TABLE IF NOT EXISTS `itipinvitations` ( `token` VARCHAR(64) NOT NULL, @@ -80,6 +79,6 @@ INDEX `uid_idx` (`user_id`,`event_uid`), CONSTRAINT `fk_itipinvitations_user_id` FOREIGN KEY (`user_id`) REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE -) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */; +) ROW_FORMAT=DYNAMIC ENGINE=INNODB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -REPLACE INTO system (name, value) VALUES ('calendar-database-version', '2015022700'); +REPLACE INTO `system` (`name`, `value`) VALUES ('calendar-database-version', '2021102600');
View file
iRony-0.4.6.tar.gz/lib/plugins/calendar/drivers/database/SQL/mysql/2021102600.sql
Added
@@ -0,0 +1,24 @@ +-- changing table format and dropping foreign keys is needed for some versions of MySQL +ALTER TABLE `calendars` DROP FOREIGN KEY `fk_calendars_user_id`; +ALTER TABLE `events` DROP FOREIGN KEY`fk_events_calendar_id`; +ALTER TABLE `attachments` DROP FOREIGN KEY`fk_attachments_event_id`; +ALTER TABLE `itipinvitations` DROP FOREIGN KEY`fk_itipinvitations_user_id`; + +ALTER TABLE `calendars` ROW_FORMAT=DYNAMIC; +ALTER TABLE `events` ROW_FORMAT=DYNAMIC; +ALTER TABLE `attachments` ROW_FORMAT=DYNAMIC; +ALTER TABLE `itipinvitations` ROW_FORMAT=DYNAMIC; + +ALTER TABLE `calendars` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE `events` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE `attachments` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE `itipinvitations` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +ALTER TABLE `calendars` ADD CONSTRAINT `fk_calendars_user_id` FOREIGN KEY (`user_id`) + REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE `events` ADD CONSTRAINT `fk_events_calendar_id` FOREIGN KEY (`calendar_id`) + REFERENCES `calendars`(`calendar_id`) ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE `attachments` ADD CONSTRAINT `fk_attachments_event_id` FOREIGN KEY (`event_id`) + REFERENCES `events`(`event_id`) ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE `itipinvitations` ADD CONSTRAINT `fk_itipinvitations_user_id` FOREIGN KEY (`user_id`) + REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE;
View file
iRony-0.4.5.tar.gz/lib/plugins/calendar/drivers/database/SQL/postgres.initial.sql -> iRony-0.4.6.tar.gz/lib/plugins/calendar/drivers/database/SQL/postgres.initial.sql
Changed
@@ -9,9 +9,7 @@ * @licence GNU AGPL * @copyright (c) 2010 Lazlo Westerhof - Netherlands * @copyright (c) 2014 Kolab Systems AG - * - **/ - + */ CREATE SEQUENCE calendars_seq INCREMENT BY 1 @@ -106,4 +104,4 @@ CREATE INDEX itipinvitations_user_id_event_uid_idx ON itipinvitations (user_id, event_uid); -INSERT INTO system (name, value) VALUES ('calendar-database-version', '2015022700'); +INSERT INTO system (name, value) VALUES ('calendar-database-version', '2021102600');
View file
iRony-0.4.6.tar.gz/lib/plugins/calendar/drivers/database/SQL/postgres/2021102600.sql
Added
@@ -0,0 +1,1 @@ +-- empty
View file
iRony-0.4.5.tar.gz/lib/plugins/calendar/drivers/database/SQL/sqlite.initial.sql -> iRony-0.4.6.tar.gz/lib/plugins/calendar/drivers/database/SQL/sqlite.initial.sql
Changed
@@ -9,8 +9,7 @@ * @licence GNU AGPL * @copyright (c) 2010 Lazlo Westerhof - Netherlands * @copyright (c) 2014 Kolab Systems AG - * - **/ + */ CREATE TABLE calendars ( calendar_id integer NOT NULL PRIMARY KEY, @@ -76,4 +75,4 @@ CREATE INDEX ix_itipinvitations_uid ON itipinvitations(user_id, event_uid); -INSERT INTO system (name, value) VALUES ('calendar-database-version', '2015022700'); +INSERT INTO system (name, value) VALUES ('calendar-database-version', '2021102600');
View file
iRony-0.4.6.tar.gz/lib/plugins/calendar/drivers/database/SQL/sqlite/2021102600.sql
Added
@@ -0,0 +1,1 @@ +-- empty
View file
iRony-0.4.5.tar.gz/lib/plugins/calendar/drivers/database/database_driver.php -> iRony-0.4.6.tar.gz/lib/plugins/calendar/drivers/database/database_driver.php
Changed
@@ -136,7 +136,7 @@ $hidden = array_filter(explode(',', $this->rc->config->get('hidden_calendars', ''))); $id = self::BIRTHDAY_CALENDAR_ID; - if (!$active || !in_array($id, $hidden)) { + if (empty($active) || !in_array($id, $hidden)) { $calendars[$id] = array( 'id' => $id, 'name' => $this->cal->gettext('birthdays'), @@ -172,7 +172,7 @@ $this->rc->user->ID, $prop['name'], strval($prop['color']), - $prop['showalarms'] ? 1 : 0 + !empty($prop['showalarms']) ? 1 : 0 ); if ($result) { @@ -321,24 +321,24 @@ . " VALUES (?, $now, $now, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $event['calendar'], strval($event['uid']), - intval($event['recurrence_id']), - strval($event['_instance']), - intval($event['isexception']), + isset($event['recurrence_id']) ? intval($event['recurrence_id']) : 0, + isset($event['_instance']) ? strval($event['_instance']) : '', + isset($event['isexception']) ? intval($event['isexception']) : 0, $event['start']->format(self::DB_DATE_FORMAT), $event['end']->format(self::DB_DATE_FORMAT), intval($event['all_day']), $event['_recurrence'], strval($event['title']), - strval($event['description']), - strval($event['location']), - join(',', (array)$event['categories']), - strval($event['url']), + isset($event['description']) ? strval($event['description']) : '', + isset($event['location']) ? strval($event['location']) : '', + isset($event['categories']) ? join(',', (array) $event['categories']) : '', + isset($event['url']) ? strval($event['url']) : '', intval($event['free_busy']), intval($event['priority']), intval($event['sensitivity']), - strval($event['status']), + isset($event['status']) ? strval($event['status']) : '', $event['attendees'], - $event['alarms'], + isset($event['alarms']) ? $event['alarms'] : null, $event['notifyat'] ); @@ -381,7 +381,7 @@ // increment sequence number if (empty($event['sequence']) && $reschedule) { - $event['sequence'] = max($event['sequence'], $old['sequence']) + 1; + $event['sequence'] = $old['sequence'] + 1; } // modify a recurring event, check submitted savemode to do the right things @@ -389,11 +389,12 @@ $master = $old['recurrence_id'] ? $this->get_event(array('id' => $old['recurrence_id'])) : $old; // keep saved exceptions (not submitted by the client) - if ($old['recurrence']['EXDATE']) { + if (!empty($old['recurrence']['EXDATE'])) { $event['recurrence']['EXDATE'] = $old['recurrence']['EXDATE']; } - switch ($event['_savemode']) { + $savemode = isset($event['_savemode']) ? $event['_savemode'] : null; + switch ($savemode) { case 'new': $event['uid'] = $this->cal->generate_uid(); return $this->new_event($event); @@ -582,10 +583,12 @@ // iterate through the list of properties considered 'significant' for scheduling foreach (self::$scheduling_properties as $prop) { - $a = $old[$prop]; - $b = $event[$prop]; + $a = isset($old[$prop]) ? $old[$prop] : null; + $b = isset($event[$prop]) ? $event[$prop] : null; - if ($event['allday'] && ($prop == 'start' || $prop == 'end') && $a instanceof DateTime && $b instanceof DateTime) { + if (!empty($event['allday']) && ($prop == 'start' || $prop == 'end') + && $a instanceof DateTime && $b instanceof DateTime + ) { $a = $a->format('Y-m-d'); $b = $b->format('Y-m-d'); } @@ -596,10 +599,10 @@ $b = array_filter($b); // advanced rrule comparison: no rescheduling if series was shortened - if ($a['COUNT'] && $b['COUNT'] && $b['COUNT'] < $a['COUNT']) { + if (!empty($a['COUNT']) && !empty($b['COUNT']) && $b['COUNT'] < $a['COUNT']) { unset($a['COUNT'], $b['COUNT']); } - else if ($a['UNTIL'] && $b['UNTIL'] && $b['UNTIL'] < $a['UNTIL']) { + else if (!empty($a['UNTIL']) && !empty($b['UNTIL']) && $b['UNTIL'] < $a['UNTIL']) { unset($a['UNTIL'], $b['UNTIL']); } } @@ -652,24 +655,24 @@ } // compose vcalendar-style recurrencue rule from structured data - $rrule = $event['recurrence'] ? libcalendaring::to_rrule($event['recurrence']) : ''; + $rrule = !empty($event['recurrence']) ? libcalendaring::to_rrule($event['recurrence']) : ''; + + $sensitivity = strtolower($event['sensitivity']); + $free_busy = strtolower($event['free_busy']); $event['_recurrence'] = rtrim($rrule, ';'); - $event['free_busy'] = intval($this->free_busy_map[strtolower($event['free_busy'])]); - $event['sensitivity'] = intval($this->sensitivity_map[strtolower($event['sensitivity'])]); + $event['free_busy'] = isset($this->free_busy_map[$free_busy]) ? $this->free_busy_map[$free_busy] : null; + $event['sensitivity'] = isset($this->sensitivity_map[$sensitivity]) ? $this->sensitivity_map[$sensitivity] : null; + $event['all_day'] = !empty($event['allday']) ? 1 : 0; if ($event['free_busy'] == 'tentative') { $event['status'] = 'TENTATIVE'; } - if (isset($event['allday'])) { - $event['all_day'] = $event['allday'] ? 1 : 0; - } - // compute absolute time to notify the user $event['notifyat'] = $this->_get_notification($event); - if (is_array($event['valarms'])) { + if (!empty($event['valarms'])) { $event['alarms'] = $this->serialize_alarms($event['valarms']); } @@ -689,7 +692,7 @@ */ private function _get_notification($event) { - if ($event['valarms'] && $event['start'] > new DateTime()) { + if (!empty($event['valarms']) && $event['start'] > new DateTime()) { $alarm = libcalendaring::get_next_alarm($event); if ($alarm['time'] && in_array($alarm['action'], $this->alarm_types)) { @@ -714,26 +717,23 @@ ); foreach ($set_cols as $col) { - if (is_object($event[$col]) && is_a($event[$col], 'DateTime')) { + if (!empty($event[$col]) && is_a($event[$col], 'DateTime')) { $sql_args[$col] = $event[$col]->format(self::DB_DATE_FORMAT); } - else if (is_array($event[$col])) { - $sql_args[$col] = join(',', $event[$col]); - } else if (array_key_exists($col, $event)) { - $sql_args[$col] = $event[$col]; + $sql_args[$col] = is_array($event[$col]) ? join(',', $event[$col]) : $event[$col]; } } - if ($event['_recurrence']) { + if (!empty($event['_recurrence'])) { $sql_args['recurrence'] = $event['_recurrence']; } - if ($event['_instance']) { + if (!empty($event['_instance'])) { $sql_args['instance'] = $event['_instance']; } - if ($event['_fromcalendar'] && $event['_fromcalendar'] != $event['calendar']) { + if (!empty($event['_fromcalendar']) && $event['_fromcalendar'] != $event['calendar']) { $sql_args['calendar_id'] = $event['calendar']; } @@ -763,7 +763,7 @@ } // remove attachments - if ($success && !empty($event['deleted_attachments'])) { + if ($success && !empty($event['deleted_attachments']) && is_array($event['deleted_attachments'])) { foreach ($event['deleted_attachments'] as $attachment) { $this->remove_attachment($attachment, $event['id']); } @@ -822,7 +822,7 @@ // skip exceptions // TODO: merge updated data from master event - if ($exdata[$datestr]) { + if (!empty($exdata[$datestr])) { continue; } @@ -831,7 +831,7 @@ $next_end->add($duration);
View file
iRony-0.4.5.tar.gz/lib/plugins/calendar/drivers/kolab/SQL/mysql.initial.sql -> iRony-0.4.6.tar.gz/lib/plugins/calendar/drivers/kolab/SQL/mysql.initial.sql
Changed
@@ -1,7 +1,6 @@ /** * Roundcube Calendar Kolab backend * - * @version @package_version@ * @author Thomas Bruederli * @licence GNU AGPL **/ @@ -14,7 +13,7 @@ PRIMARY KEY(`alarm_id`,`user_id`), CONSTRAINT `fk_kolab_alarms_user_id` FOREIGN KEY (`user_id`) REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE -) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */; +) ROW_FORMAT=DYNAMIC ENGINE=INNODB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE TABLE IF NOT EXISTS `itipinvitations` ( `token` VARCHAR(64) NOT NULL, @@ -27,6 +26,6 @@ INDEX `uid_idx` (`event_uid`,`user_id`), CONSTRAINT `fk_itipinvitations_user_id` FOREIGN KEY (`user_id`) REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE -) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */; +) ROW_FORMAT=DYNAMIC ENGINE=INNODB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -REPLACE INTO system (name, value) VALUES ('calendar-kolab-version', '2014041700'); +REPLACE INTO `system` (`name`, `value`) VALUES ('calendar-kolab-version', '2021102600');
View file
iRony-0.4.6.tar.gz/lib/plugins/calendar/drivers/kolab/SQL/mysql/2021102600.sql
Added
@@ -0,0 +1,14 @@ +-- changing table format and dropping foreign keys is needed for some versions of MySQL +ALTER TABLE `kolab_alarms` DROP FOREIGN KEY `fk_kolab_alarms_user_id`; +ALTER TABLE `itipinvitations` DROP FOREIGN KEY`fk_itipinvitations_user_id`; + +ALTER TABLE `kolab_alarms` ROW_FORMAT=DYNAMIC; +ALTER TABLE `itipinvitations` ROW_FORMAT=DYNAMIC; + +ALTER TABLE `kolab_alarms` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE `itipinvitations` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +ALTER TABLE `kolab_alarms` ADD CONSTRAINT `fk_kolab_alarms_user_id` FOREIGN KEY (`user_id`) + REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE `itipinvitations` ADD CONSTRAINT `fk_itipinvitations_user_id` FOREIGN KEY (`user_id`) + REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE;
View file
iRony-0.4.5.tar.gz/lib/plugins/calendar/drivers/kolab/SQL/sqlite.initial.sql -> iRony-0.4.6.tar.gz/lib/plugins/calendar/drivers/kolab/SQL/sqlite.initial.sql
Changed
@@ -1,7 +1,6 @@ /** * Roundcube Calendar Kolab backend * - * @version @package_version@ * @author Thomas Bruederli * @licence GNU AGPL **/
View file
iRony-0.4.5.tar.gz/lib/plugins/calendar/drivers/kolab/kolab_calendar.php -> iRony-0.4.6.tar.gz/lib/plugins/calendar/drivers/kolab/kolab_calendar.php
Changed
@@ -26,888 +26,933 @@ class kolab_calendar extends kolab_storage_folder_api { - public $ready = false; - public $rights = 'lrs'; - public $editable = false; - public $attachments = true; - public $alarms = false; - public $history = false; - public $subscriptions = true; - public $categories = array(); - public $storage; - - public $type = 'event'; - - protected $cal; - protected $events = array(); - protected $search_fields = array('title', 'description', 'location', 'attendees', 'categories'); - - /** - * Factory method to instantiate a kolab_calendar object - * - * @param string Calendar ID (encoded IMAP folder name) - * @param object calendar plugin object - * @return object kolab_calendar instance - */ - public static function factory($id, $calendar) - { - $imap = $calendar->rc->get_storage(); - $imap_folder = kolab_storage::id_decode($id); - $info = $imap->folder_info($imap_folder, true); - if (empty($info) || $info['noselect'] || strpos(kolab_storage::folder_type($imap_folder), 'event') !== 0) { - return new kolab_user_calendar($imap_folder, $calendar); - } - else { - return new kolab_calendar($imap_folder, $calendar); - } - } - - /** - * Default constructor - */ - public function __construct($imap_folder, $calendar) - { - $this->cal = $calendar; - $this->imap = $calendar->rc->get_storage(); - $this->name = $imap_folder; - - // ID is derrived from folder name - $this->id = kolab_storage::folder_id($this->name, true); - $old_id = kolab_storage::folder_id($this->name, false); - - // fetch objects from the given IMAP folder - $this->storage = kolab_storage::get_folder($this->name); - $this->ready = $this->storage && $this->storage->valid; - - // Set writeable and alarms flags according to folder permissions - if ($this->ready) { - if ($this->storage->get_namespace() == 'personal') { - $this->editable = true; - $this->rights = 'lrswikxteav'; - $this->alarms = true; - } - else { - $rights = $this->storage->get_myrights(); - if ($rights && !PEAR::isError($rights)) { - $this->rights = $rights; - if (strpos($rights, 't') !== false || strpos($rights, 'd') !== false) - $this->editable = strpos($rights, 'i');; - } - } - - // user-specific alarms settings win - $prefs = $this->cal->rc->config->get('kolab_calendars', array()); - if (isset($prefs[$this->id]['showalarms'])) - $this->alarms = $prefs[$this->id]['showalarms']; - else if (isset($prefs[$old_id]['showalarms'])) - $this->alarms = $prefs[$old_id]['showalarms']; - } + public $ready = false; + public $rights = 'lrs'; + public $editable = false; + public $attachments = true; + public $alarms = false; + public $history = false; + public $subscriptions = true; + public $categories = []; + public $storage; + + public $type = 'event'; + + protected $cal; + protected $events = []; + protected $search_fields = ['title', 'description', 'location', 'attendees', 'categories']; + + /** + * Factory method to instantiate a kolab_calendar object + * + * @param string Calendar ID (encoded IMAP folder name) + * @param object Calendar plugin object + * + * @return kolab_calendar Self instance + */ + public static function factory($id, $calendar) + { + $imap = $calendar->rc->get_storage(); + $imap_folder = kolab_storage::id_decode($id); + $info = $imap->folder_info($imap_folder, true); + + if ( + empty($info) + || !empty($info['noselect']) + || strpos(kolab_storage::folder_type($imap_folder), 'event') !== 0 + ) { + return new kolab_user_calendar($imap_folder, $calendar); + } - $this->default = $this->storage->default; - $this->subtype = $this->storage->subtype; - } - - - /** - * Getter for the IMAP folder name - * - * @return string Name of the IMAP folder - */ - public function get_realname() - { - return $this->name; - } - - /** - * - */ - public function get_title() - { - return null; - } - - - /** - * Return color to display this calendar - */ - public function get_color($default = null) - { - // color is defined in folder METADATA - if ($color = $this->storage->get_color()) { - return $color; + return new kolab_calendar($imap_folder, $calendar); } - // calendar color is stored in user prefs (temporary solution) - $prefs = $this->cal->rc->config->get('kolab_calendars', array()); - - if (!empty($prefs[$this->id]) && !empty($prefs[$this->id]['color'])) - return $prefs[$this->id]['color']; - - return $default ?: 'cc0000'; - } - - /** - * Compose an URL for CalDAV access to this calendar (if configured) - */ - public function get_caldav_url() - { - if ($template = $this->cal->rc->config->get('calendar_caldav_url', null)) { - return strtr($template, array( - '%h' => $_SERVER['HTTP_HOST'], - '%u' => urlencode($this->cal->rc->get_user_name()), - '%i' => urlencode($this->storage->get_uid()), - '%n' => urlencode($this->name), - )); - } + /** + * Default constructor + */ + public function __construct($imap_folder, $calendar) + { + $this->cal = $calendar; + $this->imap = $calendar->rc->get_storage(); + $this->name = $imap_folder; - return false; - } + // ID is derrived from folder name + $this->id = kolab_storage::folder_id($this->name, true); + $old_id = kolab_storage::folder_id($this->name, false); + // fetch objects from the given IMAP folder + $this->storage = kolab_storage::get_folder($this->name); + $this->ready = $this->storage && $this->storage->valid; + + // Set writeable and alarms flags according to folder permissions + if ($this->ready) { + if ($this->storage->get_namespace() == 'personal') { + $this->editable = true; + $this->rights = 'lrswikxteav'; + $this->alarms = true;
View file
iRony-0.4.5.tar.gz/lib/plugins/calendar/drivers/kolab/kolab_driver.php -> iRony-0.4.6.tar.gz/lib/plugins/calendar/drivers/kolab/kolab_driver.php
Changed
@@ -25,2409 +25,2621 @@ class kolab_driver extends calendar_driver { - const INVITATIONS_CALENDAR_PENDING = '--invitation--pending'; - const INVITATIONS_CALENDAR_DECLINED = '--invitation--declined'; - - // features this backend supports - public $alarms = true; - public $attendees = true; - public $freebusy = true; - public $attachments = true; - public $undelete = true; - public $alarm_types = array('DISPLAY','AUDIO'); - public $categoriesimmutable = true; - - private $rc; - private $cal; - private $calendars; - private $has_writeable = false; - private $freebusy_trigger = false; - private $bonnie_api = false; - - /** - * Default constructor - */ - public function __construct($cal) - { - $cal->require_plugin('libkolab'); - - // load helper classes *after* libkolab has been loaded (#3248) - require_once(dirname(__FILE__) . '/kolab_calendar.php'); - require_once(dirname(__FILE__) . '/kolab_user_calendar.php'); - require_once(dirname(__FILE__) . '/kolab_invitation_calendar.php'); - - $this->cal = $cal; - $this->rc = $cal->rc; - - $this->cal->register_action('push-freebusy', array($this, 'push_freebusy')); - $this->cal->register_action('calendar-acl', array($this, 'calendar_acl')); - - $this->freebusy_trigger = $this->rc->config->get('calendar_freebusy_trigger', false); - - if (kolab_storage::$version == '2.0') { - $this->alarm_types = array('DISPLAY'); - $this->alarm_absolute = false; - } + const INVITATIONS_CALENDAR_PENDING = '--invitation--pending'; + const INVITATIONS_CALENDAR_DECLINED = '--invitation--declined'; + + // features this backend supports + public $alarms = true; + public $attendees = true; + public $freebusy = true; + public $attachments = true; + public $undelete = true; + public $alarm_types = ['DISPLAY', 'AUDIO']; + public $categoriesimmutable = true; + + private $rc; + private $cal; + private $calendars; + private $has_writeable = false; + private $freebusy_trigger = false; + private $bonnie_api = false; + + /** + * Default constructor + */ + public function __construct($cal) + { + $cal->require_plugin('libkolab'); + + // load helper classes *after* libkolab has been loaded (#3248) + require_once(__DIR__ . '/kolab_calendar.php'); + require_once(__DIR__ . '/kolab_user_calendar.php'); + require_once(__DIR__ . '/kolab_invitation_calendar.php'); + + $this->cal = $cal; + $this->rc = $cal->rc; + + $this->cal->register_action('push-freebusy', [$this, 'push_freebusy']); + $this->cal->register_action('calendar-acl', [$this, 'calendar_acl']); + + $this->freebusy_trigger = $this->rc->config->get('calendar_freebusy_trigger', false); + + if (kolab_storage::$version == '2.0') { + $this->alarm_types = ['DISPLAY']; + $this->alarm_absolute = false; + } - // get configuration for the Bonnie API - $this->bonnie_api = libkolab::get_bonnie_api(); + // get configuration for the Bonnie API + $this->bonnie_api = libkolab::get_bonnie_api(); - // calendar uses fully encoded identifiers - kolab_storage::$encode_ids = true; - } + // calendar uses fully encoded identifiers + kolab_storage::$encode_ids = true; + } + /** + * Read available calendars from server + */ + private function _read_calendars() + { + // already read sources + if (isset($this->calendars)) { + return $this->calendars; + } - /** - * Read available calendars from server - */ - private function _read_calendars() - { - // already read sources - if (isset($this->calendars)) - return $this->calendars; + // get all folders that have "event" type, sorted by namespace/name + $folders = kolab_storage::sort_folders( + kolab_storage::get_folders('event') + kolab_storage::get_user_folders('event', true) + ); - // get all folders that have "event" type, sorted by namespace/name - $folders = kolab_storage::sort_folders(kolab_storage::get_folders('event') + kolab_storage::get_user_folders('event', true)); + $this->calendars = []; - $this->calendars = array(); - foreach ($folders as $folder) { - $calendar = $this->_to_calendar($folder); - if ($calendar->ready) { - $this->calendars[$calendar->id] = $calendar; - if ($calendar->editable) { - $this->has_writeable = true; + foreach ($folders as $folder) { + $calendar = $this->_to_calendar($folder); + if ($calendar->ready) { + $this->calendars[$calendar->id] = $calendar; + if ($calendar->editable) { + $this->has_writeable = true; + } + } } - } + + return $this->calendars; } - return $this->calendars; - } + /** + * Convert kolab_storage_folder into kolab_calendar + */ + private function _to_calendar($folder) + { + if ($folder instanceof kolab_calendar) { + return $folder; + } + + if ($folder instanceof kolab_storage_folder_user) { + $calendar = new kolab_user_calendar($folder, $this->cal); + $calendar->subscriptions = count($folder->children) > 0; + } + else { + $calendar = new kolab_calendar($folder->name, $this->cal); + } - /** - * Convert kolab_storage_folder into kolab_calendar - */ - private function _to_calendar($folder) - { - if ($folder instanceof kolab_calendar) { - return $folder; + return $calendar; } - if ($folder instanceof kolab_storage_folder_user) { - $calendar = new kolab_user_calendar($folder, $this->cal); - $calendar->subscriptions = count($folder->children) > 0; + /** + * Get a list of available calendars from this source + * + * @param int $filter Bitmask defining filter criterias + * @param object $tree Reference to hierarchical folder tree object + * + * @return array List of calendars + */ + public function list_calendars($filter = 0, &$tree = null) + { + $this->_read_calendars(); + + // attempt to create a default calendar for this user + if (!$this->has_writeable) { + if ($this->create_calendar(['name' => 'Calendar', 'color' => 'cc0000'])) { + unset($this->calendars); + $this->_read_calendars();
View file
iRony-0.4.5.tar.gz/lib/plugins/calendar/drivers/kolab/kolab_invitation_calendar.php -> iRony-0.4.6.tar.gz/lib/plugins/calendar/drivers/kolab/kolab_invitation_calendar.php
Changed
@@ -23,389 +23,402 @@ class kolab_invitation_calendar { - public $id = '__invitation__'; - public $ready = true; - public $alarms = false; - public $rights = 'lrsv'; - public $editable = false; - public $attachments = false; - public $subscriptions = false; - public $partstats = array('unknown'); - public $categories = array(); - public $name = 'Invitations'; - - - /** - * Default constructor - */ - public function __construct($id, $calendar) - { - $this->cal = $calendar; - $this->id = $id; - - switch ($this->id) { - case kolab_driver::INVITATIONS_CALENDAR_PENDING: - $this->partstats = array('NEEDS-ACTION'); - $this->name = $this->cal->gettext('invitationspending'); - if (!empty($_REQUEST['_quickview'])) - $this->partstats[] = 'TENTATIVE'; - break; - - case kolab_driver::INVITATIONS_CALENDAR_DECLINED: - $this->partstats = array('DECLINED'); - $this->name = $this->cal->gettext('invitationsdeclined'); - break; + public $id = '__invitation__'; + public $ready = true; + public $alarms = false; + public $rights = 'lrsv'; + public $editable = false; + public $attachments = false; + public $subscriptions = false; + public $partstats = ['unknown']; + public $categories = []; + public $name = 'Invitations'; + + + /** + * Default constructor + */ + public function __construct($id, $calendar) + { + $this->cal = $calendar; + $this->id = $id; + + switch ($this->id) { + case kolab_driver::INVITATIONS_CALENDAR_PENDING: + $this->partstats = ['NEEDS-ACTION']; + $this->name = $this->cal->gettext('invitationspending'); + + if (!empty($_REQUEST['_quickview'])) { + $this->partstats[] = 'TENTATIVE'; + } + break; + + case kolab_driver::INVITATIONS_CALENDAR_DECLINED: + $this->partstats = ['DECLINED']; + $this->name = $this->cal->gettext('invitationsdeclined'); + break; + } + + // user-specific alarms settings win + $prefs = $this->cal->rc->config->get('kolab_calendars', []); + if (isset($prefs[$this->id]['showalarms'])) { + $this->alarms = $prefs[$this->id]['showalarms']; + } + } + + /** + * Getter for a nice and human readable name for this calendar + * + * @return string Name of this calendar + */ + public function get_name() + { + return $this->name; } - // user-specific alarms settings win - $prefs = $this->cal->rc->config->get('kolab_calendars', array()); - if (isset($prefs[$this->id]['showalarms'])) - $this->alarms = $prefs[$this->id]['showalarms']; - } - - /** - * Getter for a nice and human readable name for this calendar - * - * @return string Name of this calendar - */ - public function get_name() - { - return $this->name; - } - - /** - * Getter for the IMAP folder owner - * - * @return string Name of the folder owner - */ - public function get_owner() - { - return $this->cal->rc->get_user_name(); - } - - /** - * - */ - public function get_title() - { - return $this->get_name(); - } - - /** - * Getter for the name of the namespace to which the IMAP folder belongs - * - * @return string Name of the namespace (personal, other, shared) - */ - public function get_namespace() - { - return 'x-special'; - } - - /** - * Getter for the top-end calendar folder name (not the entire path) - * - * @return string Name of this calendar - */ - public function get_foldername() - { - return $this->get_name(); - } - - /** - * Getter for the Cyrus mailbox identifier corresponding to this folder - * - * @return string Mailbox ID - */ - public function get_mailbox_id() - { - // this is a virtual collection and has no concrete mailbox ID - return null; - } - - /** - * Return color to display this calendar - */ - public function get_color() - { - // calendar color is stored in local user prefs - $prefs = $this->cal->rc->config->get('kolab_calendars', array()); - - if (!empty($prefs[$this->id]) && !empty($prefs[$this->id]['color'])) - return $prefs[$this->id]['color']; - - return 'ffffff'; - } - - /** - * Compose an URL for CalDAV access to this calendar (if configured) - */ - public function get_caldav_url() - { - return false; - } - - /** - * Check activation status of this folder - * - * @return boolean True if enabled, false if not - */ - public function is_active() - { - $prefs = $this->cal->rc->config->get('kolab_calendars', array()); // read local prefs - return (bool)$prefs[$this->id]['active']; - } - - /** - * Update properties of this calendar folder - * - * @see calendar_driver::edit_calendar() - */ - public function update(&$prop) - { - // don't change anything. - // let kolab_driver save props in local prefs - return $prop['id']; - } - - /**
View file
iRony-0.4.5.tar.gz/lib/plugins/calendar/drivers/kolab/kolab_user_calendar.php -> iRony-0.4.6.tar.gz/lib/plugins/calendar/drivers/kolab/kolab_user_calendar.php
Changed
@@ -23,402 +23,423 @@ class kolab_user_calendar extends kolab_calendar { - public $id = 'unknown'; - public $ready = false; - public $editable = false; - public $attachments = false; - public $subscriptions = false; - - protected $userdata = array(); - protected $timeindex = array(); - - - /** - * Default constructor - */ - public function __construct($user_or_folder, $calendar) - { - $this->cal = $calendar; - $this->imap = $calendar->rc->get_storage(); - - // full user record is provided - if (is_array($user_or_folder)) { - $this->userdata = $user_or_folder; - $this->storage = new kolab_storage_folder_user($this->userdata['kolabtargetfolder'], '', $this->userdata); + public $id = 'unknown'; + public $ready = false; + public $editable = false; + public $attachments = false; + public $subscriptions = false; + + protected $userdata = []; + protected $timeindex = []; + + + /** + * Default constructor + */ + public function __construct($user_or_folder, $calendar) + { + $this->cal = $calendar; + $this->imap = $calendar->rc->get_storage(); + + // full user record is provided + if (is_array($user_or_folder)) { + $this->userdata = $user_or_folder; + $this->storage = new kolab_storage_folder_user($this->userdata['kolabtargetfolder'], '', $this->userdata); + } + else if ($user_or_folder instanceof kolab_storage_folder_user) { + $this->storage = $user_or_folder; + $this->userdata = $this->storage->ldaprec; + } + else { + // get user record from LDAP + $this->storage = new kolab_storage_folder_user($user_or_folder); + $this->userdata = $this->storage->ldaprec; + } + + $this->ready = !empty($this->userdata['kolabtargetfolder']); + $this->storage->type = 'event'; + + if ($this->ready) { + // ID is derrived from the user's kolabtargetfolder attribute + $this->id = kolab_storage::folder_id($this->userdata['kolabtargetfolder'], true); + $this->imap_folder = $this->userdata['kolabtargetfolder']; + $this->name = $this->storage->name; + $this->parent = ''; // user calendars are top level + + // user-specific alarms settings win + $prefs = $this->cal->rc->config->get('kolab_calendars', []); + if (isset($prefs[$this->id]['showalarms'])) { + $this->alarms = $prefs[$this->id]['showalarms']; + } + } } - else if ($user_or_folder instanceof kolab_storage_folder_user) { - $this->storage = $user_or_folder; - $this->userdata = $this->storage->ldaprec; + + /** + * Getter for a nice and human readable name for this calendar + * + * @return string Name of this calendar + */ + public function get_name() + { + if (!empty($this->userdata['displayname'])) { + return $this->userdata['displayname']; + } + + return !empty($this->userdata['name']) ? $this->userdata['name'] : $this->userdata['mail']; } - else { // get user record from LDAP - $this->storage = new kolab_storage_folder_user($user_or_folder); - $this->userdata = $this->storage->ldaprec; + + /** + * Getter for the IMAP folder owner + * + * @param bool Return a fully qualified owner name (unused) + * + * @return string Name of the folder owner + */ + public function get_owner($fully_qualified = false) + { + return $this->userdata['mail']; } - $this->ready = !empty($this->userdata['kolabtargetfolder']); - $this->storage->type = 'event'; + /** + * + */ + public function get_title() + { + $title = []; + + if (!empty($this->userdata['displayname'])) { + $title[] = $this->userdata['displayname']; + } + + $title[] = $this->userdata['mail']; - if ($this->ready) { - // ID is derrived from the user's kolabtargetfolder attribute - $this->id = kolab_storage::folder_id($this->userdata['kolabtargetfolder'], true); - $this->imap_folder = $this->userdata['kolabtargetfolder']; - $this->name = $this->storage->name; - $this->parent = ''; // user calendars are top level + return implode('; ', $title); + } - // user-specific alarms settings win - $prefs = $this->cal->rc->config->get('kolab_calendars', array()); - if (isset($prefs[$this->id]['showalarms'])) - $this->alarms = $prefs[$this->id]['showalarms']; + /** + * Getter for the name of the namespace to which the IMAP folder belongs + * + * @return string Name of the namespace (personal, other, shared) + */ + public function get_namespace() + { + return 'other user'; } - } - - /** - * Getter for a nice and human readable name for this calendar - * - * @return string Name of this calendar - */ - public function get_name() - { - return $this->userdata['displayname'] ?: ($this->userdata['name'] ?: $this->userdata['mail']); - } - - /** - * Getter for the IMAP folder owner - * - * @param bool Return a fully qualified owner name (unused) - * - * @return string Name of the folder owner - */ - public function get_owner($fully_qualified = false) - { - return $this->userdata['mail']; - } - - /** - * - */ - public function get_title() - { - return trim($this->userdata['displayname'] . '; ' . $this->userdata['mail'], '; '); - } - - /** - * Getter for the name of the namespace to which the IMAP folder belongs - * - * @return string Name of the namespace (personal, other, shared) - */ - public function get_namespace() - { - return 'other user'; - } - - /** - * Getter for the top-end calendar folder name (not the entire path) - * - * @return string Name of this calendar - */ - public function get_foldername() - { - return $this->get_name(); - } - - /** - * Return color to display this calendar
View file
iRony-0.4.5.tar.gz/lib/plugins/calendar/drivers/ldap/resources_driver_ldap.php -> iRony-0.4.6.tar.gz/lib/plugins/calendar/drivers/ldap/resources_driver_ldap.php
Changed
@@ -41,72 +41,76 @@ /** * Fetch resource objects to be displayed for booking * - * @param string Search query (optional) - * @return array List of resource records available for booking + * @param string $query Search query (optional) + * @param int $num Max size of the result + * + * @return array List of resource records available for booking */ public function load_resources($query = null, $num = 5000) { - if (!($ldap = $this->connect())) { - return array(); - } - - // TODO: apply paging - $ldap->set_pagesize($num); - - if (isset($query)) { - $results = $ldap->search('*', $query, 0, true, true); - } - else { - $results = $ldap->list_records(); - } - - if ($results instanceof ArrayAccess) { - foreach ($results as $i => $rec) { - $results[$i] = $this->decode_resource($rec); + if (!($ldap = $this->connect())) { + return []; + } + + // TODO: apply paging + $ldap->set_pagesize($num); + + if (isset($query)) { + $results = $ldap->search('*', $query, 0, true, true); + } + else { + $results = $ldap->list_records(); } - } - return $results; + if ($results instanceof ArrayAccess) { + foreach ($results as $i => $rec) { + $results[$i] = $this->decode_resource($rec); + } + } + + return $results; } /** * Return properties of a single resource * - * @param string Unique resource identifier + * @param string $id Unique resource identifier + * * @return array Resource object as hash array */ public function get_resource($dn) { - $rec = null; + $rec = null; - if ($ldap = $this->connect()) { - $rec = $ldap->get_record(rcube_ldap::dn_encode($dn), true); + if ($ldap = $this->connect()) { + $rec = $ldap->get_record(rcube_ldap::dn_encode($dn), true); - if (!empty($rec)) { - $rec = $this->decode_resource($rec); + if (!empty($rec)) { + $rec = $this->decode_resource($rec); + } } - } - return $rec; + return $rec; } /** * Return properties of a resource owner * - * @param string Owner identifier - * @return array Resource object as hash array + * @param string $dn Owner identifier + * + * @return array Resource object as hash array */ public function get_resource_owner($dn) { - $owner = null; + $owner = null; - if ($ldap = $this->connect()) { - $owner = $ldap->get_record(rcube_ldap::dn_encode($dn), true); - $owner['ID'] = rcube_ldap::dn_decode($owner['ID']); - unset($owner['_raw_attrib'], $owner['_type']); - } + if ($ldap = $this->connect()) { + $owner = $ldap->get_record(rcube_ldap::dn_encode($dn), true); + $owner['ID'] = rcube_ldap::dn_decode($owner['ID']); + unset($owner['_raw_attrib'], $owner['_type']); + } - return $owner; + return $owner; } /** @@ -114,41 +118,40 @@ */ private function decode_resource($rec) { - $rec['ID'] = rcube_ldap::dn_decode($rec['ID']); - - $attributes = array(); - - foreach ((array) $rec['attributes'] as $sattr) { - $sattr = trim($sattr); - if ($sattr && $sattr[0] === '{') { - $attr = @json_decode($sattr, true); - $attributes += $attr; + $rec['ID'] = rcube_ldap::dn_decode($rec['ID']); + + $attributes = []; + + foreach ((array) $rec['attributes'] as $sattr) { + $sattr = trim($sattr); + if (!empty($sattr) && $sattr[0] === '{') { + $attr = @json_decode($sattr, true); + $attributes += $attr; + } + else if (!empty($sattr) && empty($rec['description'])) { + $rec['description'] = $sattr; + } } - else if ($sattr && empty($rec['description'])) { - $rec['description'] = $sattr; - } - } - $rec['attributes'] = $attributes; + $rec['attributes'] = $attributes; - // force $rec['members'] to be an array - if (!empty($rec['members']) && !is_array($rec['members'])) { - $rec['members'] = array($rec['members']); - } + // force $rec['members'] to be an array + if (!empty($rec['members']) && !is_array($rec['members'])) { + $rec['members'] = [$rec['members']]; + } - // remove unused cruft - unset($rec['_raw_attrib']); + // remove unused cruft + unset($rec['_raw_attrib']); - return $rec; + return $rec; } private function connect() { - if (!isset($this->ldap)) { - $this->ldap = new rcube_ldap($this->rc->config->get('calendar_resources_directory'), true); - } + if (!isset($this->ldap)) { + $this->ldap = new rcube_ldap($this->rc->config->get('calendar_resources_directory'), true); + } - return $this->ldap->ready ? $this->ldap : null; + return $this->ldap->ready ? $this->ldap : null; } - -} \ No newline at end of file +}
View file
iRony-0.4.5.tar.gz/lib/plugins/calendar/drivers/resources_driver.php -> iRony-0.4.6.tar.gz/lib/plugins/calendar/drivers/resources_driver.php
Changed
@@ -26,87 +26,93 @@ */ abstract class resources_driver { - protected $cal; + protected $cal; - /** - * Default constructor - */ - function __construct($cal) - { - $this->cal = $cal; - } + /** + * Default constructor + */ + function __construct($cal) + { + $this->cal = $cal; + } - /** - * Fetch resource objects to be displayed for booking - * - * @param string Search query (optional) - * @return array List of resource records available for booking - */ - abstract public function load_resources($query = null); + /** + * Fetch resource objects to be displayed for booking + * + * @param string $query Search query (optional) + * + * @return array List of resource records available for booking + */ + abstract public function load_resources($query = null); - /** - * Return properties of a single resource - * - * @param string Unique resource identifier - * @return array Resource object as hash array - */ - abstract public function get_resource($id); + /** + * Return properties of a single resource + * + * @param string $id Unique resource identifier + * + * @return array Resource object as hash array + */ + abstract public function get_resource($id); - /** - * Return properties of a resource owner - * - * @param string Owner identifier - * @return array Resource object as hash array - */ - public function get_resource_owner($id) - { - return null; - } + /** + * Return properties of a resource owner + * + * @param string $id Owner identifier + * + * @return array Resource object as hash array + */ + public function get_resource_owner($id) + { + return null; + } - /** - * Get event data to display a resource's calendar - * - * The default implementation extracts the resource's email address - * and fetches free-busy data using the calendar backend driver. - * - * @param integer Event's new start (unix timestamp) - * @param integer Event's new end (unix timestamp) - * @return array A list of event objects (see calendar_driver specification) - */ - public function get_resource_calendar($id, $start, $end) - { - $events = array(); - $rec = $this->get_resource($id); - if ($rec && !empty($rec['email']) && $this->cal->driver) { - $fbtypemap = array( - calendar::FREEBUSY_BUSY => 'busy', - calendar::FREEBUSY_TENTATIVE => 'tentative', - calendar::FREEBUSY_OOF => 'outofoffice', - ); + /** + * Get event data to display a resource's calendar + * + * The default implementation extracts the resource's email address + * and fetches free-busy data using the calendar backend driver. + * + * @param string $id Calendar identifier + * @param int $start Event's new start (unix timestamp) + * @param int $end Event's new end (unix timestamp) + * + * @return array A list of event objects (see calendar_driver specification) + */ + public function get_resource_calendar($id, $start, $end) + { + $events = []; + $rec = $this->get_resource($id); - // if the backend has free-busy information - $fblist = $this->cal->driver->get_freebusy_list($rec['email'], $start, $end); - if (is_array($fblist)) { - foreach ($fblist as $slot) { - list($from, $to, $type) = $slot; - if ($type == calendar::FREEBUSY_FREE || $type == calendar::FREEBUSY_UNKNOWN) { - continue; - } - if ($from < $end && $to > $start) { - $event = array( - 'id' => sha1($id . $from . $to), - 'title' => $rec['name'], - 'start' => new DateTime('@' . $from), - 'end' => new DateTime('@' . $to), - 'status' => $fbtypemap[$type], - 'calendar' => '_resource', - ); - $events[] = $event; - } - } - } - } + if ($rec && !empty($rec['email']) && !empty($this->cal->driver)) { + $fbtypemap = [ + calendar::FREEBUSY_BUSY => 'busy', + calendar::FREEBUSY_TENTATIVE => 'tentative', + calendar::FREEBUSY_OOF => 'outofoffice', + ]; - return $events; - } + // if the backend has free-busy information + $fblist = $this->cal->driver->get_freebusy_list($rec['email'], $start, $end); + if (is_array($fblist)) { + foreach ($fblist as $slot) { + list($from, $to, $type) = $slot; + if ($type == calendar::FREEBUSY_FREE || $type == calendar::FREEBUSY_UNKNOWN) { + continue; + } + + if ($from < $end && $to > $start) { + $events[] = [ + 'id' => sha1($id . $from . $to), + 'title' => $rec['name'], + 'start' => new DateTime('@' . $from), + 'end' => new DateTime('@' . $to), + 'status' => $fbtypemap[$type], + 'calendar' => '_resource', + ]; + } + } + } + } + + return $events; + } }
View file
iRony-0.4.5.tar.gz/lib/plugins/calendar/lib/calendar_itip.php -> iRony-0.4.6.tar.gz/lib/plugins/calendar/lib/calendar_itip.php
Changed
@@ -28,213 +28,231 @@ */ class calendar_itip extends libcalendaring_itip { - /** - * Constructor to set text domain to calendar - */ - function __construct($plugin, $domain = 'calendar') - { - parent::__construct($plugin, $domain); - - $this->db_itipinvitations = $this->rc->db->table_name('itipinvitations', true); - } - - /** - * Handler for calendar/itip-status requests - */ - public function get_itip_status($event, $existing = null) - { - $status = parent::get_itip_status($event, $existing); - - // don't ask for deleting events when declining - if ($this->rc->config->get('kolab_invitation_calendars')) - $status['saved'] = false; - - return $status; - } - - /** - * Find invitation record by token - * - * @param string Invitation token - * @return mixed Invitation record as hash array or False if not found - */ - public function get_invitation($token) - { - if ($parts = $this->decode_token($token)) { - $result = $this->rc->db->query("SELECT * FROM $this->db_itipinvitations WHERE `token` = ?", $parts['base']); - if ($result && ($rec = $this->rc->db->fetch_assoc($result))) { - $rec['event'] = unserialize($rec['event']); - $rec['attendee'] = $parts['attendee']; - return $rec; - } + /** + * Constructor to set text domain to calendar + */ + function __construct($plugin, $domain = 'calendar') + { + parent::__construct($plugin, $domain); + + $this->db_itipinvitations = $this->rc->db->table_name('itipinvitations', true); + } + + /** + * Handler for calendar/itip-status requests + */ + public function get_itip_status($event, $existing = null) + { + $status = parent::get_itip_status($event, $existing); + + // don't ask for deleting events when declining + if ($this->rc->config->get('kolab_invitation_calendars')) { + $status['saved'] = false; + } + + return $status; } - - return false; - } - - /** - * Update the attendee status of the given invitation record - * - * @param array Invitation record as fetched with calendar_itip::get_invitation() - * @param string Attendee email address - * @param string New attendee status - */ - public function update_invitation($invitation, $email, $newstatus) - { - if (is_string($invitation)) - $invitation = $this->get_invitation($invitation); - - if ($invitation['token'] && $invitation['event']) { - // update attendee record in event data - foreach ($invitation['event']['attendees'] as $i => $attendee) { - if ($attendee['role'] == 'ORGANIZER') { - $organizer = $attendee; + + /** + * Find invitation record by token + * + * @param string $token Invitation token + * + * @return mixed Invitation record as hash array or False if not found + */ + public function get_invitation($token) + { + if ($parts = $this->decode_token($token)) { + $result = $this->rc->db->query("SELECT * FROM $this->db_itipinvitations WHERE `token` = ?", $parts['base']); + if ($result && ($rec = $this->rc->db->fetch_assoc($result))) { + $rec['event'] = unserialize($rec['event']); + $rec['attendee'] = $parts['attendee']; + + return $rec; + } + } + + return false; + } + + /** + * Update the attendee status of the given invitation record + * + * @param array $invitation Invitation record as fetched with calendar_itip::get_invitation() + * @param string $email Attendee email address + * @param string $newstatus New attendee status + */ + public function update_invitation($invitation, $email, $newstatus) + { + if (is_string($invitation)) { + $invitation = $this->get_invitation($invitation); + } + + if (!empty($invitation['token']) && !empty($invitation['event'])) { + // update attendee record in event data + foreach ($invitation['event']['attendees'] as $i => $attendee) { + if ($attendee['role'] == 'ORGANIZER') { + $organizer = $attendee; + } + else if ($attendee['email'] == $email) { + // nothing to be done here + if ($attendee['status'] == $newstatus) { + return true; + } + + $invitation['event']['attendees'][$i]['status'] = $newstatus; + $this->sender = $attendee; + } + } + + $invitation['event']['changed'] = new DateTime(); + + // send iTIP REPLY message to organizer + if (!empty($organizer)) { + $status = strtolower($newstatus); + if ($this->send_itip_message($invitation['event'], 'REPLY', $organizer, 'itipsubject' . $status, 'itipmailbody' . $status)) { + $mailto = !empty($organizer['name']) ? $organizer['name'] : $organizer['email']; + $message = $this->plugin->gettext([ + 'name' => 'sentresponseto', + 'vars' => ['mailto' => $mailto] + ]); + $this->rc->output->command('display_message', $message, 'confirmation'); + } + else { + $this->rc->output->command('display_message', $this->plugin->gettext('itipresponseerror'), 'error'); + } + } + + // update record in DB + $query = $this->rc->db->query( + "UPDATE $this->db_itipinvitations SET `event` = ? WHERE `token` = ?", + self::serialize_event($invitation['event']), + $invitation['token'] + ); + + if ($this->rc->db->affected_rows($query)) { + return true; + } + } + + return false; + } + + /** + * Create iTIP invitation token for later replies via URL + * + * @param array $event Hash array with event properties + * @param string $attendee Attendee email address + * + * @return string Invitation token + */ + public function store_invitation($event, $attendee) + { + static $stored = []; + + if (empty($event['uid']) || !$attendee) { + return false; + } + + // generate token for this invitation + $token = $this->generate_token($event, $attendee); + $base = substr($token, 0, 40); + + // already stored this + if (!empty($stored[$base])) { + return $token; } - else if ($attendee['email'] == $email) { - // nothing to be done here
View file
iRony-0.4.5.tar.gz/lib/plugins/calendar/lib/calendar_recurrence.php -> iRony-0.4.6.tar.gz/lib/plugins/calendar/lib/calendar_recurrence.php
Changed
@@ -26,63 +26,64 @@ */ class calendar_recurrence extends libcalendaring_recurrence { - private $event; - private $duration; + private $event; + private $duration; - /** - * Default constructor - * - * @param object calendar The calendar plugin instance - * @param array The event object to operate on - */ - function __construct($cal, $event) - { - parent::__construct($cal->lib); + /** + * Default constructor + * + * @param calendar $cal The calendar plugin instance + * @param array $event The event object to operate on + */ + function __construct($cal, $event) + { + parent::__construct($cal->lib); - $this->event = $event; + $this->event = $event; - if (is_object($event['start']) && is_object($event['end'])) - $this->duration = $event['start']->diff($event['end']); + if (is_object($event['start']) && is_object($event['end'])) { + $this->duration = $event['start']->diff($event['end']); + } - $event['start']->_dateonly |= $event['allday']; - $this->init($event['recurrence'], $event['start']); - } + $event['start']->_dateonly = !empty($event['allday']); - /** - * Alias of libcalendaring_recurrence::next() - * - * @return mixed DateTime object or False if recurrence ended - */ - public function next_start() - { - return $this->next(); - } + $this->init($event['recurrence'], $event['start']); + } - /** - * Get the next recurring instance of this event - * - * @return mixed Array with event properties or False if recurrence ended - */ - public function next_instance() - { - if ($next_start = $this->next()) { - $next = $this->event; - $next['start'] = $next_start; + /** + * Alias of libcalendaring_recurrence::next() + * + * @return mixed DateTime object or False if recurrence ended + */ + public function next_start() + { + return $this->next(); + } - if ($this->duration) { - $next['end'] = clone $next_start; - $next['end']->add($this->duration); - } + /** + * Get the next recurring instance of this event + * + * @return mixed Array with event properties or False if recurrence ended + */ + public function next_instance() + { + if ($next_start = $this->next()) { + $next = $this->event; + $next['start'] = $next_start; - $next['recurrence_date'] = clone $next_start; - $next['_instance'] = libcalendaring::recurrence_instance_identifier($next, $this->event['allday']); + if ($this->duration) { + $next['end'] = clone $next_start; + $next['end']->add($this->duration); + } - unset($next['_formatobj']); + $next['recurrence_date'] = clone $next_start; + $next['_instance'] = libcalendaring::recurrence_instance_identifier($next, $this->event['allday']); - return $next; - } + unset($next['_formatobj']); - return false; - } + return $next; + } + return false; + } }
View file
iRony-0.4.5.tar.gz/lib/plugins/calendar/lib/calendar_ui.php -> iRony-0.4.6.tar.gz/lib/plugins/calendar/lib/calendar_ui.php
Changed
@@ -25,819 +25,1001 @@ class calendar_ui { - private $rc; - private $cal; - private $ready = false; - public $screen; - - function __construct($cal) - { - $this->cal = $cal; - $this->rc = $cal->rc; - $this->screen = $this->rc->task == 'calendar' ? ($this->rc->action ? $this->rc->action: 'calendar') : 'other'; - } - - /** - * Calendar UI initialization and requests handlers - */ - public function init() - { - if ($this->ready) // already done - return; - - // add taskbar button - $this->cal->add_button(array( - 'command' => 'calendar', - 'class' => 'button-calendar', - 'classsel' => 'button-calendar button-selected', - 'innerclass' => 'button-inner', - 'label' => 'calendar.calendar', - 'type' => 'link' - ), 'taskbar'); - - // load basic client script - if ($this->rc->action != 'print') { - $this->cal->include_script('calendar_base.js'); - } - - $this->addCSS(); - - $this->ready = true; - } - - /** - * Register handler methods for the template engine - */ - public function init_templates() - { - $this->cal->register_handler('plugin.calendar_css', array($this, 'calendar_css')); - $this->cal->register_handler('plugin.calendar_list', array($this, 'calendar_list')); - $this->cal->register_handler('plugin.calendar_select', array($this, 'calendar_select')); - $this->cal->register_handler('plugin.identity_select', array($this, 'identity_select')); - $this->cal->register_handler('plugin.category_select', array($this, 'category_select')); - $this->cal->register_handler('plugin.status_select', array($this, 'status_select')); - $this->cal->register_handler('plugin.freebusy_select', array($this, 'freebusy_select')); - $this->cal->register_handler('plugin.priority_select', array($this, 'priority_select')); - $this->cal->register_handler('plugin.sensitivity_select', array($this, 'sensitivity_select')); - $this->cal->register_handler('plugin.alarm_select', array($this, 'alarm_select')); - $this->cal->register_handler('plugin.recurrence_form', array($this->cal->lib, 'recurrence_form')); - $this->cal->register_handler('plugin.attendees_list', array($this, 'attendees_list')); - $this->cal->register_handler('plugin.attendees_form', array($this, 'attendees_form')); - $this->cal->register_handler('plugin.resources_form', array($this, 'resources_form')); - $this->cal->register_handler('plugin.resources_list', array($this, 'resources_list')); - $this->cal->register_handler('plugin.resources_searchform', array($this, 'resources_search_form')); - $this->cal->register_handler('plugin.resource_info', array($this, 'resource_info')); - $this->cal->register_handler('plugin.resource_calendar', array($this, 'resource_calendar')); - $this->cal->register_handler('plugin.attendees_freebusy_table', array($this, 'attendees_freebusy_table')); - $this->cal->register_handler('plugin.edit_attendees_notify', array($this, 'edit_attendees_notify')); - $this->cal->register_handler('plugin.edit_recurrence_sync', array($this, 'edit_recurrence_sync')); - $this->cal->register_handler('plugin.edit_recurring_warning', array($this, 'recurring_event_warning')); - $this->cal->register_handler('plugin.event_rsvp_buttons', array($this, 'event_rsvp_buttons')); - $this->cal->register_handler('plugin.agenda_options', array($this, 'agenda_options')); - $this->cal->register_handler('plugin.events_import_form', array($this, 'events_import_form')); - $this->cal->register_handler('plugin.events_export_form', array($this, 'events_export_form')); - $this->cal->register_handler('plugin.object_changelog_table', array('libkolab', 'object_changelog_table')); - $this->cal->register_handler('plugin.searchform', array($this->rc->output, 'search_form')); // use generic method from rcube_template - - kolab_attachments_handler::ui(); - } - - /** - * Adds CSS stylesheets to the page header - */ - public function addCSS() - { - $skin_path = $this->cal->local_skin_path(); + private $rc; + private $cal; + private $ready = false; + + public $screen; + + function __construct($cal) + { + $this->cal = $cal; + $this->rc = $cal->rc; + $this->screen = $this->rc->task == 'calendar' ? ($this->rc->action ?: 'calendar') : 'other'; + } + + /** + * Calendar UI initialization and requests handlers + */ + public function init() + { + if ($this->ready) { + // already done + return; + } + + // add taskbar button + $this->cal->add_button([ + 'command' => 'calendar', + 'class' => 'button-calendar', + 'classsel' => 'button-calendar button-selected', + 'innerclass' => 'button-inner', + 'label' => 'calendar.calendar', + 'type' => 'link' + ], + 'taskbar' + ); + + // load basic client script + if ($this->rc->action != 'print') { + $this->cal->include_script('calendar_base.js'); + } + + $this->addCSS(); + + $this->ready = true; + } + + /** + * Register handler methods for the template engine + */ + public function init_templates() + { + $this->cal->register_handler('plugin.calendar_css', [$this, 'calendar_css']); + $this->cal->register_handler('plugin.calendar_list', [$this, 'calendar_list']); + $this->cal->register_handler('plugin.calendar_select', [$this, 'calendar_select']); + $this->cal->register_handler('plugin.identity_select', [$this, 'identity_select']); + $this->cal->register_handler('plugin.category_select', [$this, 'category_select']); + $this->cal->register_handler('plugin.status_select', [$this, 'status_select']); + $this->cal->register_handler('plugin.freebusy_select', [$this, 'freebusy_select']); + $this->cal->register_handler('plugin.priority_select', [$this, 'priority_select']); + $this->cal->register_handler('plugin.sensitivity_select', [$this, 'sensitivity_select']); + $this->cal->register_handler('plugin.alarm_select', [$this, 'alarm_select']); + $this->cal->register_handler('plugin.recurrence_form', [$this->cal->lib, 'recurrence_form']); + $this->cal->register_handler('plugin.attendees_list', [$this, 'attendees_list']); + $this->cal->register_handler('plugin.attendees_form', [$this, 'attendees_form']); + $this->cal->register_handler('plugin.resources_form', [$this, 'resources_form']); + $this->cal->register_handler('plugin.resources_list', [$this, 'resources_list']); + $this->cal->register_handler('plugin.resources_searchform', [$this, 'resources_search_form']); + $this->cal->register_handler('plugin.resource_info', [$this, 'resource_info']); + $this->cal->register_handler('plugin.resource_calendar', [$this, 'resource_calendar']); + $this->cal->register_handler('plugin.attendees_freebusy_table', [$this, 'attendees_freebusy_table']); + $this->cal->register_handler('plugin.edit_attendees_notify', [$this, 'edit_attendees_notify']); + $this->cal->register_handler('plugin.edit_recurrence_sync', [$this, 'edit_recurrence_sync']); + $this->cal->register_handler('plugin.edit_recurring_warning', [$this, 'recurring_event_warning']); + $this->cal->register_handler('plugin.event_rsvp_buttons', [$this, 'event_rsvp_buttons']); + $this->cal->register_handler('plugin.agenda_options', [$this, 'agenda_options']); + $this->cal->register_handler('plugin.events_import_form', [$this, 'events_import_form']); + $this->cal->register_handler('plugin.events_export_form', [$this, 'events_export_form']); + $this->cal->register_handler('plugin.object_changelog_table', ['libkolab', 'object_changelog_table']); + $this->cal->register_handler('plugin.searchform', [$this->rc->output, 'search_form']); + + kolab_attachments_handler::ui(); + } + + /** + * Adds CSS stylesheets to the page header + */ + public function addCSS() + { + $skin_path = $this->cal->local_skin_path(); - if ($this->rc->task == 'calendar' && (!$this->rc->action || in_array($this->rc->action, array('index', 'print')))) { - // Include fullCalendar style before skin file for simpler style overriding - $this->cal->include_stylesheet($skin_path . '/fullcalendar.css'); - } - - $this->cal->include_stylesheet($skin_path . '/calendar.css'); - - if ($this->rc->task == 'calendar' && $this->rc->action == 'print') { - $this->cal->include_stylesheet($skin_path . '/print.css'); + if ( + $this->rc->task == 'calendar' + && (!$this->rc->action || in_array($this->rc->action, ['index', 'print'])) + ) { + // Include fullCalendar style before skin file for simpler style overriding + $this->cal->include_stylesheet($skin_path . '/fullcalendar.css'); + } + + $this->cal->include_stylesheet($skin_path . '/calendar.css'); + + if ($this->rc->task == 'calendar' && $this->rc->action == 'print') { + $this->cal->include_stylesheet($skin_path . '/print.css'); + } + } +
View file
iRony-0.4.5.tar.gz/lib/plugins/calendar/localization/de.inc -> iRony-0.4.6.tar.gz/lib/plugins/calendar/localization/de.inc
Changed
@@ -27,12 +27,18 @@ $labels['aftermoveto'] = 'Verschiebe nach...'; $labels['itipoptions'] = 'Veranstaltungseinladungen'; $labels['afteraction'] = 'Nachdem eine Einladungs- oder Aktualisierungsnachricht verarbeitet wurde'; +$labels['showweekno'] = 'Wochennummern anzeigen'; $labels['weeknonone'] = 'nie'; +$labels['weeknodatepicker'] = 'nur in der Datumsauswahl'; +$labels['weeknoall'] = 'in der Datumsauswahl und Kalenderansicht'; $labels['calendar'] = 'Kalender'; $labels['calendars'] = 'Kalender'; $labels['category'] = 'Kategorie'; $labels['categories'] = 'Kategorien'; +$labels['addcalendar'] = 'Kalender hinzufügen'; $labels['createcalendar'] = 'Neuen Kalender erstellen'; +$labels['editcalendar'] = 'Kalender bearbeiten/freigeben'; +$labels['deletecalendar'] = 'Kalender löschen'; $labels['name'] = 'Name'; $labels['color'] = 'Farbe'; $labels['day'] = 'Tag'; @@ -95,6 +101,7 @@ $labels['parentcalendar'] = 'Erstellen in'; $labels['searchearlierdates'] = '« Frühere Termine suchen'; $labels['searchlaterdates'] = 'Spätere Termine suchen »'; +$labels['earlierevents'] = 'Früher'; $labels['laterevents'] = 'Später'; $labels['andnmore'] = '$nr weitere …'; $labels['togglerole'] = 'Zum Ändern der Rolle klicken'; @@ -106,8 +113,11 @@ $labels['showurl'] = 'URL anzeigen'; $labels['showurldescription'] = 'Über die folgende Adresse können Sie mit einem beliebigen Kalenderprogramm Ihren Kalender abrufen (nur lesend), sofern dieses das iCal-Format unterstützt.'; $labels['caldavurldescription'] = 'Diese Adresse in einen <a href="http://en.wikipedia.org/wiki/CalDAV" target="_blank">CalDAV</a>-Klienten (z.B. Evolution oder Mozilla Thunderbird) kopieren, um den Kalender in Gänze mit einem mobilen Gerät zu synchronisieren.'; +$labels['showfburl'] = 'Free-Busy-URL anzeigen'; +$labels['fburldescription'] = 'Verwenden Sie die folgende Adresse, um auf Free-Busy-Informationen aus anderen Anwendungen zuzugreifen. Sie können dies kopieren und in jede Kalendersoftware einfügen, die Free-Busy-Informationen im iCal-Format unterstützt. Für diese URL ist keine Authentifizierung erforderlich.'; $labels['findcalendars'] = 'Kalender finden …'; $labels['searchterms'] = 'Suchbegriffe'; +$labels['findevents'] = 'Ereignis finden'; $labels['calsearchresults'] = 'Verfügbare Kalender'; $labels['calendarsubscribe'] = 'Permanent anzeigen'; $labels['nocalendarsfound'] = 'Keine Kalender gefunden'; @@ -117,6 +127,7 @@ $labels['invitationsdeclined'] = 'Abgelehnte Einladungen'; $labels['changepartstat'] = 'Teilnehmerstatus ändern'; $labels['rsvpcomment'] = 'Einladungstext'; +$labels['eventstartsync'] = 'Das Startdatum des Ereignisses auf das erste Vorkommen verschieben.'; $labels['listrange'] = 'Angezeigter Bereich:'; $labels['listsections'] = 'Unterteilung:'; $labels['smartsections'] = 'Intelligent'; @@ -190,11 +201,13 @@ $labels['openpreview'] = 'Kalender überprüfen'; $labels['noearlierevents'] = 'Keine früheren Ereignisse'; $labels['nolaterevents'] = 'Keine späteren Ereignisse'; +$labels['legend'] = 'Legende'; $labels['resource'] = 'Ressource'; $labels['addresource'] = 'Ressource buchen'; $labels['findresources'] = 'Ressourcen finden'; $labels['resourcedetails'] = 'Details'; $labels['resourceavailability'] = 'Verfügbarkeit'; +$labels['resourceprops'] = 'Ressourceneigenschaften'; $labels['resourceowner'] = 'Eigentümer'; $labels['resourceadded'] = 'Diese Ressource wurde Ihrem Termin hinzugefügt'; $labels['tabsummary'] = 'Übersicht'; @@ -211,6 +224,7 @@ $labels['errorsaving'] = 'Fehler beim Speichern.'; $labels['operationfailed'] = 'Die Aktion ist fehlgeschlagen.'; $labels['invalideventdates'] = 'Ungültige Daten eingegeben! Bitte überprüfen Sie die Eingaben.'; +$labels['emptyeventtitle'] = 'Die Ereigniszusammenfassung darf nicht leer sein.'; $labels['invalidcalendarproperties'] = 'Ungültige Kalenderinformationen! Bitte geben Sie einen Namen ein.'; $labels['searchnoresults'] = 'Keine Termine in den gewählten Kalendern gefunden.'; $labels['successremoval'] = 'Der Termin wurde erfolgreich gelöscht.'; @@ -223,6 +237,7 @@ $labels['importedsuccessfully'] = 'Der Termin wurde erfolgreich in »$calendar« gespeichert'; $labels['updatedsuccessfully'] = 'Der Termin wurde erfolgreich in »$calendar« geändert'; $labels['attendeupdateesuccess'] = 'Teilnehmerstatus erfolgreich aktualisiert'; +$labels['errorunknownattendee'] = 'Die Teilnehmerinformationen konnten nicht gefunden werden.'; $labels['itipsendsuccess'] = 'Einladung an Teilnehmer versendet.'; $labels['itipresponseerror'] = 'Die Antwort auf diese Einladung konnte nicht versendet werden'; $labels['itipinvalidrequest'] = 'Diese Einladung ist nicht mehr gültig.'; @@ -241,6 +256,7 @@ $labels['futurevents'] = 'Zukünftige'; $labels['allevents'] = 'Alle'; $labels['saveasnew'] = 'Als neu speichern'; +$labels['recurrenceerror'] = 'Wiederholungsregel für angegebenes Startdatum kann nicht aufgelöst werden.'; $labels['birthdays'] = 'Geburtstage'; $labels['birthdayscalendar'] = 'Geburtstagskalender'; $labels['displaybirthdayscalendar'] = 'Geburtstagskalender anzeigen'; @@ -261,8 +277,10 @@ $labels['arialabelquicksearchbox'] = 'Sucheingabe für Termine'; $labels['arialabelcalsearchform'] = 'Suchformular für Kalender'; $labels['calendaractions'] = 'Kalenderaktionen'; +$labels['calendarprops'] = 'Kalender Einstellungen'; $labels['arialabeleventattendees'] = 'Teilehmerliste'; $labels['arialabeleventresources'] = 'Liste der Terminressourcen'; $labels['arialabelresourcesearchform'] = 'Suchformular für Ressourcen'; $labels['arialabelresourceselection'] = 'Verfügbare Ressourcen'; +$labels['arialabeleventform'] = 'Ereignisbearbeitungsformular'; ?>
View file
iRony-0.4.5.tar.gz/lib/plugins/calendar/localization/es_ES.inc -> iRony-0.4.6.tar.gz/lib/plugins/calendar/localization/es_ES.inc
Changed
@@ -27,12 +27,18 @@ $labels['aftermoveto'] = 'Mover a...'; $labels['itipoptions'] = 'Invitaciones para el evento'; $labels['afteraction'] = 'Se procesa después de un mensaje de invitación o actualización'; -$labels['weeknonone'] = 'never'; +$labels['showweekno'] = 'Mostrar números de semana'; +$labels['weeknonone'] = 'nunca'; +$labels['weeknodatepicker'] = 'solo en selector de fechas'; +$labels['weeknoall'] = 'en selector de fechas y vista de calendario'; $labels['calendar'] = 'Calendario'; $labels['calendars'] = 'Calendarios'; $labels['category'] = 'Categoría'; $labels['categories'] = 'Categorías'; +$labels['addcalendar'] = 'Añadir calendario'; $labels['createcalendar'] = 'Crear nuevo calendario'; +$labels['editcalendar'] = 'Editar/Compartir calendario'; +$labels['deletecalendar'] = 'Eliminar calendario'; $labels['name'] = 'Nombre'; $labels['color'] = 'Color'; $labels['day'] = 'Día'; @@ -95,6 +101,7 @@ $labels['parentcalendar'] = 'Inserte en el interior'; $labels['searchearlierdates'] = '« Búsqueda de eventos anteriores'; $labels['searchlaterdates'] = 'Búsqueda de eventos posteriores »'; +$labels['earlierevents'] = 'Anterior'; $labels['laterevents'] = 'Luego'; $labels['andnmore'] = '$nr más...'; $labels['togglerole'] = 'Haga clic para cambiar el rol'; @@ -106,8 +113,11 @@ $labels['showurl'] = 'Mostrar URL del calendario'; $labels['showurldescription'] = 'Usar la siguiente dirección para acceder (sólo lectura) en su calendario desde otras aplicaciones. Puede copiar y pegar esto en cualquier software de calendario que admita el formato iCal.'; $labels['caldavurldescription'] = 'Copie esta dirección en un <a href="http://en.wikipedia.org/wiki/CalDAV" target="_blank">CalDAV</a> cliente (Evolution o Mozilla Thunderbird) para sincronizar esta tarea con su ordenador o celular.'; +$labels['showfburl'] = 'Mostrar URL libre-ocupado'; +$labels['fburldescription'] = 'Usar la siguiente dirección para acceder Libre-Ocupado en su calendario desde otras aplicaciones. Puede copiar y pegar esto en cualquier software de calendario que admita el formato iCal. No es necesaria la autentificación para esta URL.'; $labels['findcalendars'] = 'Buscar calendarios ...'; $labels['searchterms'] = 'Buscar términos'; +$labels['findevents'] = 'Buscar eventos'; $labels['calsearchresults'] = 'Calendarios disponibles'; $labels['calendarsubscribe'] = 'Lista Permanente'; $labels['nocalendarsfound'] = 'No se han encontrado calendarios'; @@ -117,6 +127,8 @@ $labels['invitationsdeclined'] = 'Invitaciones rechazada'; $labels['changepartstat'] = 'Cambiar el estado del participante'; $labels['rsvpcomment'] = 'Texto de la invitación'; +$labels['eventstartsync'] = 'Mueve la fecha de inicio del evento a la primera aparición'; +$labels['weekshort'] = 'Sem.'; $labels['listrange'] = 'Rango de visualización:'; $labels['listsections'] = 'Dividir en:'; $labels['smartsections'] = 'Secciones inteligentes'; @@ -164,6 +176,7 @@ $labels['suggestedslot'] = 'Ranura sugerida'; $labels['noslotfound'] = 'Incapaz de encontrar un intervalo de tiempo libre'; $labels['invitationsubject'] = 'Usted sido invitado a "$title"'; +$labels['invitationmailbody'] = "*\$title*\n\nWhen: \$date\n\nInvitees: \$attendees\n\nSe adjunta un archivo iCalendar con los detalles del evento actualizados que se puede importar a la aplicación de calendario."; $labels['invitationattendlinks'] = "En caso de que su cliente de correo electrónico no admite solicitudes iTIP que puede utilizar el siguiente enlace para aceptar o rechazar esta invitación:\n\$url"; $labels['eventupdatesubject'] = '"$title" Ha sido actualizado'; $labels['eventupdatesubjectempty'] = 'Un evento que le concierne ha sido actualizado'; @@ -189,11 +202,13 @@ $labels['openpreview'] = 'Revisar en calendario'; $labels['noearlierevents'] = 'No hay eventos anteriores'; $labels['nolaterevents'] = 'No hay eventos posteriores'; +$labels['legend'] = 'Leyenda'; $labels['resource'] = 'Recurso'; $labels['addresource'] = 'Reservar recursos'; $labels['findresources'] = 'Encontrar recursos'; $labels['resourcedetails'] = 'Detalles'; $labels['resourceavailability'] = 'Disponibilidad'; +$labels['resourceprops'] = 'Propiedades del archivo'; $labels['resourceowner'] = 'Propietario'; $labels['resourceadded'] = 'Se ha añadido un recurso a su evento'; $labels['tabsummary'] = 'Sumario'; @@ -210,6 +225,7 @@ $labels['errorsaving'] = 'Error al guardar cambios'; $labels['operationfailed'] = 'Error en la operación solicitada'; $labels['invalideventdates'] = 'Se han introducido fechas erróneas; por favor, revise su entrada'; +$labels['emptyeventtitle'] = 'El nombre del evento no puede estar vacío.'; $labels['invalidcalendarproperties'] = 'Propiedades de portátiles erróneas; establezca un nombre válido.'; $labels['searchnoresults'] = 'No se han encontrado eventos en los calendarios seleccionados.'; $labels['successremoval'] = 'El evento se ha eliminado correctamente.'; @@ -222,6 +238,7 @@ $labels['importedsuccessfully'] = 'El evento se agregó correctamente a \'$calendar\''; $labels['updatedsuccessfully'] = 'El evento se actualizó correctamente en \'$calendar\''; $labels['attendeupdateesuccess'] = 'Se ha actualizado correctamente el estado del participante'; +$labels['errorunknownattendee'] = 'Error al buscar información de a los participantes del evento.'; $labels['itipsendsuccess'] = 'Invitación enviada a los participantes.'; $labels['itipresponseerror'] = 'Error al enviar la respuesta a esta invitación de evento'; $labels['itipinvalidrequest'] = 'Esta invitación ya no es válida'; @@ -231,6 +248,7 @@ $labels['importnone'] = 'No se han encontrado eventos para importar'; $labels['importerror'] = 'Se ha producido un error durante la importación'; $labels['aclnorights'] = 'No tiene derechos de administrador en este calendario.'; +$labels['importtext'] = 'Puede subir eventos en formato (.ics) <a href="https://wikipedia.org/wiki/ICalendar">iCalendar</a>.'; $labels['changeeventconfirm'] = 'Cambiar evento'; $labels['removeeventconfirm'] = 'Eliminar evento'; $labels['changerecurringeventwarning'] = 'Este es un evento recurrente. ¿Desea editar solo el evento actual, este y todos los futuros casos, todos los casos o guardarlo como un nuevo evento?'; @@ -240,6 +258,7 @@ $labels['futurevents'] = 'Futuro'; $labels['allevents'] = 'Todo'; $labels['saveasnew'] = 'Guardar como nuevo'; +$labels['recurrenceerror'] = 'No se puede resolver la regla de recurrencia para la fecha de inicio especificada.'; $labels['birthdays'] = 'Cumpleaños'; $labels['birthdayscalendar'] = 'Calendario de cumpleaños'; $labels['displaybirthdayscalendar'] = 'Mostrar calendarios de cumpleaños'; @@ -260,8 +279,10 @@ $labels['arialabelquicksearchbox'] = 'Entrada en búsqueda de eventos'; $labels['arialabelcalsearchform'] = 'Formulario de búsqueda de calendarios'; $labels['calendaractions'] = 'acciones del calendario'; +$labels['calendarprops'] = 'Propiedades del calendario'; $labels['arialabeleventattendees'] = 'Lista de participantes del evento'; $labels['arialabeleventresources'] = 'Lista de recursos del evento'; $labels['arialabelresourcesearchform'] = 'Formulario de búsqueda de recursos'; $labels['arialabelresourceselection'] = 'Recursos disponibles'; +$labels['arialabeleventform'] = 'Formulario de edición de eventos'; ?>
View file
iRony-0.4.5.tar.gz/lib/plugins/calendar/localization/ko_KR.inc -> iRony-0.4.6.tar.gz/lib/plugins/calendar/localization/ko_KR.inc
Changed
@@ -24,11 +24,15 @@ $labels['afterflagdeleted'] = '삭제로 표시'; $labels['aftermoveto'] = '이동'; $labels['itipoptions'] = '일정에 초대'; +$labels['showweekno'] = '몇 번째 주인지 표시'; $labels['calendar'] = '캘린더'; $labels['calendars'] = '캘린더'; $labels['category'] = '카테고리'; $labels['categories'] = '카테고리'; +$labels['addcalendar'] = '캘린더 추가'; $labels['createcalendar'] = '새 캘린더 추가'; +$labels['editcalendar'] = '캘린더 수정/공유'; +$labels['deletecalendar'] = '캘린더 삭제'; $labels['name'] = '이름'; $labels['color'] = '색상'; $labels['day'] = '일'; @@ -86,6 +90,8 @@ $labels['printdescriptions'] = '내용 출력'; $labels['searchearlierdates'] = '이전 일정 검색'; $labels['searchlaterdates'] = '이후 일정 검색'; +$labels['earlierevents'] = '더 일찍'; +$labels['laterevents'] = '이후에'; $labels['andnmore'] = '$nr 더...'; $labels['createfrommail'] = '일정으로 저장'; $labels['importevents'] = '일정 가져오기'; @@ -93,6 +99,7 @@ $labels['nmonthsback'] = '$nr개월 전'; $labels['showurl'] = '캘린더 URL 보이기'; $labels['findcalendars'] = '캘린더 검색'; +$labels['findevents'] = '일정 검색'; $labels['calsearchresults'] = '가능한 캘린더'; $labels['nocalendarsfound'] = '캘린더 없음'; $labels['nrcalendarsfound'] = '$nr개의 캘린더 검색됨'; @@ -101,6 +108,7 @@ $labels['invitationsdeclined'] = '거절된 초대장'; $labels['changepartstat'] = '참가상태 변경'; $labels['rsvpcomment'] = '초대 문구'; +$labels['weekshort'] = '주'; $labels['listrange'] = '표시 범위'; $labels['listsections'] = '분류 :'; $labels['smartsections'] = '스마트 선택'; @@ -119,6 +127,7 @@ $labels['defaultalarmtype'] = '기본 알림 설정'; $labels['defaultalarmoffset'] = '기본 알림 시간'; $labels['attendee'] = '참가자'; +$labels['role'] = '역할'; $labels['availability'] = '가능'; $labels['confirmstate'] = '상태'; $labels['addattendee'] = '참가자 추가'; @@ -130,6 +139,7 @@ $labels['cutypeindividual'] = '개인'; $labels['cutypegroup'] = '그룹'; $labels['cutyperesource'] = '자원'; +$labels['cutyperoom'] = '공간'; $labels['availfree'] = '한가함'; $labels['availbusy'] = '바쁨'; $labels['availunknown'] = '알 수 없는'; @@ -145,6 +155,8 @@ $labels['noslotfound'] = '여유 시간 슬롯을 찾을 수 없습니다.'; $labels['invitationsubject'] = '"$title"에 초대되었습니다'; $labels['invitationattendlinks'] = "당신과 관련된 이벤트가 업데이트되었습니다"; +$labels['eventupdatesubject'] = '"$title" 이 변경되었습니다'; +$labels['eventcancelsubject'] = '"$title" 이 취소되었습니다'; $labels['itipobjectnotfound'] = '이 메시지와 관련된 일정을 캘린더에서 찾을 수 없습니다.'; $labels['itipdeclineevent'] = '이 일정에 초대를 거절할까요?'; $labels['declinedeleteconfirm'] = '당신이 당신의 달력에서 이벤트를 사퇴 삭제 하시겠습니까?'; @@ -156,9 +168,13 @@ $labels['noearlierevents'] = '이전 일정이 없습니다'; $labels['nolaterevents'] = '이후 일정이 없습니다'; $labels['resource'] = '자원'; +$labels['resourcedetails'] = '상세정보'; +$labels['resourceowner'] = '소유자'; $labels['tabsummary'] = '요약'; $labels['tabrecurrence'] = '반복'; $labels['tabattendees'] = '참가자'; +$labels['tabattachments'] = '첨부'; +$labels['tabsharing'] = '공유'; $labels['deleteobjectconfirm'] = '이 일정을 정말 삭제 하시겠습니까?'; $labels['deleteventconfirm'] = '이 일정을 정말 삭제 하시겠습니까?'; $labels['deletecalendarconfirm'] = '이 캘린더와 포함된 모든 일정을 정말 삭제하겠습니까?'; @@ -176,7 +192,10 @@ $labels['importwarningexists'] = '캘린더에 이미 동일한 일정이 존재합니다.'; $labels['newerversionexists'] = '최근에 수정한 내용이 이미 저장되어 있습니다. 작업이 취소되었습니다.'; $labels['nowritecalendarfound'] = '일정을 저장할 캘린더가 없습니다'; +$labels['itipsendsuccess'] = '참석자에게 초대장을 발송했습니다.'; +$labels['itipresponseerror'] = '초대장에 응답을 보내는데 실패하였습니다'; $labels['itipinvalidrequest'] = '이 초대장은 더이상 유효하지 않습니다'; +$labels['sentresponseto'] = '$mailto 의 초대장에 응답을 보내는데 성공하였습니다'; $labels['importnone'] = '가져올 일정이 없습니다'; $labels['importerror'] = '가져오는 도중 오류가 발생했습니다'; $labels['aclnorights'] = '이 캘린더에 대한 관리권한이 없습니다.'; @@ -192,7 +211,9 @@ $labels['birthdayscalendarsources'] = '주소록에서'; $labels['birthdayeventtitle'] = '$name의 생일'; $labels['birthdayage'] = '$age세'; +$labels['objectchangelog'] = '이력 변경'; $labels['objectnotfound'] = '일정 데이터를 읽지 못하였습니다'; +$labels['objectchangelognotavailable'] = '이 일정에 대한 이력을 변경할 수 없습니다'; $labels['objectrestoreerror'] = '이전 버전으로 복구하지 못하였습니다'; $labels['arialabelcalendarview'] = '캘린더 보기'; $labels['arialabelsearchform'] = '일정 검색 폼';
View file
iRony-0.4.5.tar.gz/lib/plugins/kolab_2fa/composer.json -> iRony-0.4.6.tar.gz/lib/plugins/kolab_2fa/composer.json
Changed
@@ -4,7 +4,7 @@ "description": "Kolab 2-Factor Authentication", "homepage": "https://git.kolab.org/diffusion/RPK/", "license": "AGPLv3", - "version": "3.5.2", + "version": "3.5.8", "authors": [ { "name": "Thomas Bruederli",
View file
iRony-0.4.5.tar.gz/lib/plugins/kolab_2fa/kolab_2fa.php -> iRony-0.4.6.tar.gz/lib/plugins/kolab_2fa/kolab_2fa.php
Changed
@@ -88,24 +88,34 @@ // parse $host URL $a_host = parse_url($args['host']); $hostname = $_SESSION['hostname'] = $a_host['host'] ?: $args['host']; + $username = !empty($_SESSION['kolab_auth_admin']) ? $_SESSION['kolab_auth_admin'] : $args['user']; - // 1. find user record (and its prefs) before IMAP login - if ($user = rcube_user::query($args['user'], $hostname)) { - $rcmail->config->set_user_prefs($user->get_prefs()); + // Convert username to lowercase. Copied from rcmail::login() + $login_lc = $rcmail->config->get('login_lc', 2); + if ($login_lc) { + if ($login_lc == 2 || $login_lc === true) { + $username = mb_strtolower($username); + } + else if (strpos($username, '@')) { + // lowercase domain name + list($local, $domain) = explode('@', $username); + $username = $local . '@' . mb_strtolower($domain); + } } // 2a. let plugins provide the list of active authentication factors $lookup = $rcmail->plugins->exec_hook('kolab_2fa_lookup', array( - 'user' => $args['user'], + 'user' => $username, 'host' => $hostname, - 'factors' => $rcmail->config->get('kolab_2fa_factors'), + 'factors' => null, 'check' => $rcmail->config->get('kolab_2fa_check', true), )); + if (isset($lookup['factors'])) { $factors = (array)$lookup['factors']; } // 2b. check storage if this user has 2FA enabled - else if ($lookup['check'] !== false && ($storage = $this->get_storage($args['user']))) { + else if ($lookup['check'] !== false && ($storage = $this->get_storage($username))) { $factors = (array)$storage->enumerate(); } @@ -149,14 +159,15 @@ */ public function login_verify($args) { - $rcmail = rcmail::get_instance(); + $this->login_verified = false; - $time = $_SESSION['kolab_2fa_time']; - $nonce = $_SESSION['kolab_2fa_nonce']; - $factors = (array)$_SESSION['kolab_2fa_factors']; + $rcmail = rcmail::get_instance(); - $this->login_verified = false; - $expired = $time < time() - $rcmail->config->get('kolab_2fa_timeout', 120); + $time = $_SESSION['kolab_2fa_time']; + $nonce = $_SESSION['kolab_2fa_nonce']; + $factors = (array)$_SESSION['kolab_2fa_factors']; + $expired = $time < time() - $rcmail->config->get('kolab_2fa_timeout', 120); + $username = !empty($_SESSION['kolab_auth_admin']) ? $_SESSION['kolab_auth_admin'] : $_SESSION['username']; if (!empty($factors) && !empty($nonce) && !$expired) { // TODO: check signature @@ -167,7 +178,7 @@ // verify the submitted code $code = rcube_utils::get_input_value("_${nonce}_${method}", rcube_utils::INPUT_POST); - $this->login_verified = $this->verify_factor_auth($factor, $code); + $this->login_verified = $this->verify_factor_auth($factor, $code, $username); // accept first successful method if ($this->login_verified) { @@ -181,6 +192,11 @@ $_POST['_user'] = $_SESSION['username']; $_POST['_host'] = $_SESSION['host']; $_POST['_pass'] = $rcmail->decrypt($_SESSION['password']); + + if ($_SESSION['kolab_auth_admin']) { + $_POST['_user'] = $_SESSION['kolab_auth_admin']; + $_POST['_loginas'] = $_SESSION['username']; + } } // proceed with regular login ... @@ -195,15 +211,15 @@ return $args; } - + /** * Helper method to verify the given method/code tuple */ - protected function verify_factor_auth($method, $code) + protected function verify_factor_auth($method, $code, $username) { if (strlen($code) && ($driver = $this->get_driver($method))) { // set properties from login - $driver->username = $_SESSION['username']; + $driver->username = $username; try { // verify the submitted code
View file
iRony-0.4.5.tar.gz/lib/plugins/kolab_2fa/lib/Kolab2FA/Driver/Yubikey.php -> iRony-0.4.6.tar.gz/lib/plugins/kolab_2fa/lib/Kolab2FA/Driver/Yubikey.php
Changed
@@ -32,7 +32,7 @@ /** * */ - public function init(array $config) + public function init($config) { parent::init($config); @@ -89,7 +89,7 @@ /** * @override */ - public function set($key, $value) + public function set($key, $value, $persistent = true) { if ($key == 'yubikeyid' && strlen($value) > 12) { // verify the submitted code @@ -108,7 +108,7 @@ $value = substr($value, 0, 12); } - return parent::set($key, $value); + return parent::set($key, $value, $persistent); } /**
View file
iRony-0.4.5.tar.gz/lib/plugins/kolab_activesync/composer.json -> iRony-0.4.6.tar.gz/lib/plugins/kolab_activesync/composer.json
Changed
@@ -4,7 +4,7 @@ "description": "ActiveSync configuration utility for Kolab accounts", "homepage": "https://git.kolab.org/diffusion/RPK/", "license": "AGPLv3", - "version": "3.5.2", + "version": "3.5.6", "authors": [ { "name": "Thomas Bruederli",
View file
iRony-0.4.5.tar.gz/lib/plugins/kolab_activesync/config.inc.php.dist -> iRony-0.4.6.tar.gz/lib/plugins/kolab_activesync/config.inc.php.dist
Changed
@@ -2,3 +2,6 @@ // The page with Activesync clients configuration manual $config['activesync_setup_url'] = 'https://kb.kolabenterprise.com/documentation/setting-up-an-activesync-client'; +// Force a subscription state per devicetype (lowercase) and folder +// States can be: 0 => not subscribed, 1 => subscribed, 2 => subscribed with alarm +$config['activesync_force_subscriptions'] = array('windowsoutlook15' => array('INBOX' => 1, 'Sent' => 1, 'Trash' => 1, 'Calendar' => 1, 'Contacts' => 1, 'Tasks' => 1));
View file
iRony-0.4.5.tar.gz/lib/plugins/kolab_activesync/kolab_activesync.js -> iRony-0.4.6.tar.gz/lib/plugins/kolab_activesync/kolab_activesync.js
Changed
@@ -65,7 +65,7 @@ var fn = function(elem) { var classname = elem.className.split(' ')[0], - list = $(elem).closest('table').find('input.' + classname), + list = $(elem).closest('table').find('input.' + classname).not('[disabled]'), check = list.not(':checked').length > 0; list.prop('checked', check).change();
View file
iRony-0.4.5.tar.gz/lib/plugins/kolab_activesync/kolab_activesync_ui.php -> iRony-0.4.6.tar.gz/lib/plugins/kolab_activesync/kolab_activesync_ui.php
Changed
@@ -27,6 +27,7 @@ { private $rc; private $plugin; + private $force_subscriptions = array(); public $device = array(); const SETUP_URL = 'https://kb.kolabenterprise.com/documentation/setting-up-an-activesync-client'; @@ -39,6 +40,9 @@ $skin_path = $this->plugin->local_skin_path() . '/'; $this->skin_path = 'plugins/kolab_activesync/' . $skin_path; + $this->plugin->load_config(); + $this->force_subscriptions = $this->rc->config->get('activesync_force_subscriptions', array()); + $this->plugin->include_stylesheet($skin_path . 'config.css'); } @@ -94,6 +98,15 @@ } + private function is_protected($folder, $devicetype) + { + $devicetype = strtolower($devicetype); + if (array_key_exists($devicetype, $this->force_subscriptions)) { + return array_key_exists($folder, $this->force_subscriptions[$devicetype]); + } + return false; + } + public function folder_subscriptions($attrib = array()) { if (!$attrib['id']) { @@ -111,6 +124,9 @@ $folder_meta = $this->plugin->folder_meta(); } + $devicetype = strtolower($this->device['TYPE']); + $device_force_subscriptions = $this->force_subscriptions[$devicetype]; + foreach ($this->plugin->list_folders() as $folder) { if ($folder_types[$folder]) { list($type, ) = explode('.', $folder_types[$folder]); @@ -122,7 +138,9 @@ if (is_array($folder_groups[$type])) { $folder_groups[$type][] = $folder; - if (!empty($folder_meta) && ($meta = $folder_meta[$folder]) + if ($device_force_subscriptions && array_key_exists($folder, $device_force_subscriptions)) { + $subscribed[$folder] = intval($device_force_subscriptions[$folder]); + } else if (!empty($folder_meta) && ($meta = $folder_meta[$folder]) && $meta['FOLDER'] && $meta['FOLDER'][$imei]['S'] ) { $subscribed[$folder] = intval($meta['FOLDER'][$imei]['S']); @@ -185,7 +203,7 @@ $names = array(); foreach ($a_folders as $folder) { - $foldername = $origname = preg_replace('/^INBOX »\s+/', '', kolab_storage::object_prettyname($folder)); + $foldername = $origname = kolab_storage::object_prettyname($folder); // find folder prefix to truncate (the same code as in kolab_addressbook plugin) for ($i = count($names)-1; $i >= 0; $i--) { @@ -210,14 +228,17 @@ } $table->add_row(); + + $disabled = $this->is_protected($folder, $this->device['TYPE']); + $table->add('subscription checkbox-cell', $checkbox_sync->show( !empty($subscribed[$folder]) ? $folder : null, - array('value' => $folder, 'id' => $folder_id))); + array('value' => $folder, 'id' => $folder_id, 'disabled' => $disabled))); if ($alarms) { $table->add('alarm checkbox-cell', $checkbox_alarm->show( intval($subscribed[$folder]) > 1 ? $folder : null, - array('value' => $folder, 'id' => $folder_id.'_alarm'))); + array('value' => $folder, 'id' => $folder_id.'_alarm', 'disabled' => $disabled))); } $table->add(join(' ', $classes), html::label($folder_id, $foldername)); @@ -258,15 +279,17 @@ } } + $disabled = $this->is_protected($folder_name, $device['TYPE']); + $table->add_row(); $table->add(array('class' => 'device', 'title' => $title), $name); - $table->add('subscription checkbox-cell', $checkbox->show(!empty($folder_data[$id]['S']) ? 1 : 0)); + $table->add('subscription checkbox-cell', $checkbox->show(!empty($folder_data[$id]['S']) ? 1 : 0, array('disabled' => $disabled))); if ($alarms) { $checkbox_alarm = new html_checkbox(array('name' => "_alarms[$id]", 'value' => 1, 'onchange' => 'return activesync_object.update_sync_data(this)')); - $table->add('alarm checkbox-cell', $checkbox_alarm->show($folder_data[$id]['S'] > 1 ? 1 : 0)); + $table->add('alarm checkbox-cell', $checkbox_alarm->show($folder_data[$id]['S'] > 1 ? 1 : 0, array('disabled' => $disabled))); } }
View file
iRony-0.4.5.tar.gz/lib/plugins/kolab_addressbook/composer.json -> iRony-0.4.6.tar.gz/lib/plugins/kolab_addressbook/composer.json
Changed
@@ -4,7 +4,7 @@ "description": "Kolab addressbook", "homepage": "https://git.kolab.org/diffusion/RPK/", "license": "AGPLv3", - "version": "3.5.5", + "version": "3.5.10", "authors": [ { "name": "Thomas Bruederli",
View file
iRony-0.4.5.tar.gz/lib/plugins/kolab_addressbook/kolab_addressbook.php -> iRony-0.4.6.tar.gz/lib/plugins/kolab_addressbook/kolab_addressbook.php
Changed
@@ -1196,5 +1196,4 @@ $this->rc->user->save_prefs(array('calendar_birthday_adressbooks' => $bday_addressbooks)); } } - }
View file
iRony-0.4.5.tar.gz/lib/plugins/kolab_addressbook/lib/rcube_kolab_contacts.php -> iRony-0.4.6.tar.gz/lib/plugins/kolab_addressbook/lib/rcube_kolab_contacts.php
Changed
@@ -34,52 +34,78 @@ public $undelete = true; public $groups = true; public $coltypes = array( - 'name' => array('limit' => 1), - 'firstname' => array('limit' => 1), - 'surname' => array('limit' => 1), - 'middlename' => array('limit' => 1), - 'prefix' => array('limit' => 1), - 'suffix' => array('limit' => 1), - 'nickname' => array('limit' => 1), - 'jobtitle' => array('limit' => 1), - 'organization' => array('limit' => 1), - 'department' => array('limit' => 1), - 'email' => array('subtypes' => array('home','work','other')), - 'phone' => array(), - 'address' => array('subtypes' => array('home','work','office')), - 'website' => array('subtypes' => array('homepage','blog')), - 'im' => array('subtypes' => null), - 'gender' => array('limit' => 1), - 'birthday' => array('limit' => 1), - 'anniversary' => array('limit' => 1), - 'profession' => array('type' => 'text', 'size' => 40, 'maxlength' => 80, 'limit' => 1, - 'label' => 'kolab_addressbook.profession', 'category' => 'personal'), - 'manager' => array('limit' => null), - 'assistant' => array('limit' => null), - 'spouse' => array('limit' => 1), - 'children' => array('type' => 'text', 'size' => 40, 'maxlength' => 80, 'limit' => null, - 'label' => 'kolab_addressbook.children', 'category' => 'personal'), - 'freebusyurl' => array('type' => 'text', 'size' => 40, 'limit' => 1, - 'label' => 'kolab_addressbook.freebusyurl'), - 'pgppublickey' => array('type' => 'textarea', 'size' => 70, 'rows' => 10, 'limit' => 1, - 'label' => 'kolab_addressbook.pgppublickey'), - 'pkcs7publickey' => array('type' => 'textarea', 'size' => 70, 'rows' => 10, 'limit' => 1, - 'label' => 'kolab_addressbook.pkcs7publickey'), - 'notes' => array('limit' => 1), - 'photo' => array('limit' => 1), - // TODO: define more Kolab-specific fields such as: language, latitude, longitude, crypto settings + 'name' => array('limit' => 1), + 'firstname' => array('limit' => 1), + 'surname' => array('limit' => 1), + 'middlename' => array('limit' => 1), + 'prefix' => array('limit' => 1), + 'suffix' => array('limit' => 1), + 'nickname' => array('limit' => 1), + 'jobtitle' => array('limit' => 1), + 'organization' => array('limit' => 1), + 'department' => array('limit' => 1), + 'email' => array('subtypes' => array('home','work','other')), + 'phone' => array(), + 'address' => array('subtypes' => array('home','work','office')), + 'website' => array('subtypes' => array('homepage','blog')), + 'im' => array('subtypes' => null), + 'gender' => array('limit' => 1), + 'birthday' => array('limit' => 1), + 'anniversary' => array('limit' => 1), + 'profession' => array( + 'type' => 'text', + 'size' => 40, + 'maxlength' => 80, + 'limit' => 1, + 'label' => 'kolab_addressbook.profession', + 'category' => 'personal' + ), + 'manager' => array('limit' => null), + 'assistant' => array('limit' => null), + 'spouse' => array('limit' => 1), + 'children' => array( + 'type' => 'text', + 'size' => 40, + 'maxlength' => 80, + 'limit' => null, + 'label' => 'kolab_addressbook.children', + 'category' => 'personal' + ), + 'freebusyurl' => array( + 'type' => 'text', + 'size' => 40, + 'limit' => 1, + 'label' => 'kolab_addressbook.freebusyurl' + ), + 'pgppublickey' => array( + 'type' => 'textarea', + 'size' => 70, + 'rows' => 10, + 'limit' => 1, + 'label' => 'kolab_addressbook.pgppublickey' + ), + 'pkcs7publickey' => array( + 'type' => 'textarea', + 'size' => 70, + 'rows' => 10, + 'limit' => 1, + 'label' => 'kolab_addressbook.pkcs7publickey' + ), + 'notes' => array('limit' => 1), + 'photo' => array('limit' => 1), + // TODO: define more Kolab-specific fields such as: language, latitude, longitude, crypto settings ); /** * vCard additional fields mapping */ public $vcard_map = array( - 'profession' => 'X-PROFESSION', - 'officelocation' => 'X-OFFICE-LOCATION', - 'initials' => 'X-INITIALS', - 'children' => 'X-CHILDREN', - 'freebusyurl' => 'X-FREEBUSY-URL', - 'pgppublickey' => 'KEY', + 'profession' => 'X-PROFESSION', + 'officelocation' => 'X-OFFICE-LOCATION', + 'initials' => 'X-INITIALS', + 'children' => 'X-CHILDREN', + 'freebusyurl' => 'X-FREEBUSY-URL', + 'pgppublickey' => 'KEY', ); /** @@ -102,25 +128,25 @@ // list of fields used for searching in "All fields" mode private $search_fields = array( - 'name', - 'firstname', - 'surname', - 'middlename', - 'prefix', - 'suffix', - 'nickname', - 'jobtitle', - 'organization', - 'department', - 'email', - 'phone', - 'address', - 'profession', - 'manager', - 'assistant', - 'spouse', - 'children', - 'notes', + 'name', + 'firstname', + 'surname', + 'middlename', + 'prefix', + 'suffix', + 'nickname', + 'jobtitle', + 'organization', + 'department', + 'email', + 'phone', + 'address', + 'profession', + 'manager', + 'assistant', + 'spouse', + 'children', + 'notes', ); @@ -132,15 +158,17 @@ // extend coltypes configuration $format = kolab_format::factory('contact'); - $this->coltypes['phone']['subtypes'] = array_keys($format->phonetypes); + + $this->coltypes['phone']['subtypes'] = array_keys($format->phonetypes); $this->coltypes['address']['subtypes'] = array_keys($format->addresstypes); $rcube = rcube::get_instance(); // set localized labels for proprietary cols foreach ($this->coltypes as $col => $prop) { - if (is_string($prop['label'])) + if (is_string($prop['label'])) { $this->coltypes[$col]['label'] = $rcube->gettext($prop['label']); + } } // fetch objects from the given IMAP folder @@ -157,8 +185,9 @@ $rights = $this->storagefolder->get_myrights(); if ($rights && !PEAR::isError($rights)) { $this->rights = $rights; - if (strpos($rights, 'i') !== false && strpos($rights, 't') !== false) + if (strpos($rights, 'i') !== false && strpos($rights, 't') !== false) { $this->readonly = false; + } } } } @@ -233,17 +262,17 @@ */ public function get_carddav_url() { - $rcmail = rcmail::get_instance();
View file
iRony-0.4.5.tar.gz/lib/plugins/kolab_addressbook/localization/de.inc -> iRony-0.4.6.tar.gz/lib/plugins/kolab_addressbook/localization/de.inc
Changed
@@ -31,7 +31,7 @@ $labels['bookname'] = 'Name des Buches'; $labels['parentbook'] = 'Übergeordnetes Buch'; $labels['bookshowurl'] = 'CardDAV URL anzeigen'; -$labels['carddavurldescription'] = 'Diese Adresse in einen <a href="http://en.wikipedia.org/wiki/CardDAV" target="_blank">CardDAV</a>-Klienten kopieren, um dasAdressbuch mit einem Computer oder mobilen Gerät zu synchronisieren.'; +$labels['carddavurldescription'] = 'Diese Adresse in einen <a href="http://en.wikipedia.org/wiki/CardDAV" target="_blank">CardDAV</a>-Klienten kopieren, um das Adressbuch mit einem Computer oder mobilen Gerät zu synchronisieren.'; $labels['addressbookprio'] = 'Reihenfolge der Adressbücher'; $labels['personalfirst'] = 'Private(s) Adressbuch/Adressbücher zuerst'; $labels['globalfirst'] = 'Globale(s) Adressbuch/Adressbücher zuerst';
View file
iRony-0.4.5.tar.gz/lib/plugins/kolab_addressbook/localization/ko_KR.inc -> iRony-0.4.6.tar.gz/lib/plugins/kolab_addressbook/localization/ko_KR.inc
Changed
@@ -7,5 +7,6 @@ * For translation see https://www.transifex.com/projects/p/kolab/resource/kolab_addressbook/ */ $labels['bookremove'] = '목록에서 삭제'; +$labels['objectchangelog'] = '이력 변경'; $labels['objectrestoreerror'] = '이전 버전으로 복구하지 못하였습니다'; ?>
View file
iRony-0.4.5.tar.gz/lib/plugins/kolab_auth/composer.json -> iRony-0.4.6.tar.gz/lib/plugins/kolab_auth/composer.json
Changed
@@ -4,7 +4,7 @@ "description": "Kolab authentication", "homepage": "https://git.kolab.org/diffusion/RPK/", "license": "AGPLv3", - "version": "3.5.4", + "version": "3.5.8", "authors": [ { "name": "Thomas Bruederli",
View file
iRony-0.4.5.tar.gz/lib/plugins/kolab_auth/kolab_auth.php -> iRony-0.4.6.tar.gz/lib/plugins/kolab_auth/kolab_auth.php
Changed
@@ -433,13 +433,20 @@ return $args; } + // Don't add the extra field on 2FA form + if (strpos($args['content'], 'plugin.kolab-2fa-login')) { + return $args; + } + $input = new html_inputfield(array('name' => '_loginas', 'id' => 'rcmloginas', 'type' => 'text', 'autocomplete' => 'off')); $row = html::tag('tr', null, html::tag('td', 'title', html::label('rcmloginas', rcube::Q($this->gettext('loginas')))) . html::tag('td', 'input', $input->show(trim(rcube_utils::get_input_value('_loginas', rcube_utils::INPUT_POST)))) ); - $args['content'] = preg_replace('/<\/tbody>/i', $row . '</tbody>', $args['content']); + // add icon style for Elastic + $style = html::tag('style', [], '#login-form .input-group .icon.loginas::before { content: "\f508"; } '); + $args['content'] = preg_replace('/<\/tbody>/i', $row . '</tbody>' . $style, $args['content']); return $args; }
View file
iRony-0.4.5.tar.gz/lib/plugins/kolab_delegation/composer.json -> iRony-0.4.6.tar.gz/lib/plugins/kolab_delegation/composer.json
Changed
@@ -4,7 +4,7 @@ "description": "Kolab delegation feature", "homepage": "https://git.kolab.org/diffusion/RPK/", "license": "AGPLv3", - "version": "3.5.2", + "version": "3.5.6", "authors": [ { "name": "Aleksander Machniak",
View file
iRony-0.4.5.tar.gz/lib/plugins/kolab_delegation/kolab_delegation.php -> iRony-0.4.6.tar.gz/lib/plugins/kolab_delegation/kolab_delegation.php
Changed
@@ -563,7 +563,7 @@ $names = array(); foreach ($a_folders as $folder) { - $foldername = $origname = preg_replace('/^INBOX »\s+/', '', kolab_storage::object_prettyname($folder)); + $foldername = $origname = kolab_storage::object_prettyname($folder); // find folder prefix to truncate (the same code as in kolab_addressbook plugin) for ($i = count($names)-1; $i >= 0; $i--) {
View file
iRony-0.4.5.tar.gz/lib/plugins/kolab_files/localization/ko_KR.inc -> iRony-0.4.6.tar.gz/lib/plugins/kolab_files/localization/ko_KR.inc
Changed
@@ -16,4 +16,5 @@ $labels['status'] = '상태'; $labels['addparticipant'] = '참가자 추가'; $labels['statusorganizer'] = '주최자'; +$labels['owner'] = '소유자'; $labels['comment'] = '코멘트';
View file
iRony-0.4.5.tar.gz/lib/plugins/kolab_notes/localization/ko_KR.inc -> iRony-0.4.6.tar.gz/lib/plugins/kolab_notes/localization/ko_KR.inc
Changed
@@ -9,5 +9,6 @@ $labels['created'] = '작성됨'; $labels['changed'] = '마지막으로 수정됨'; $labels['listname'] = '이름'; +$labels['tabsharing'] = '공우'; $labels['removelist'] = '목록에서 삭제'; $labels['savingdata'] = '자료 저장중...';
View file
iRony-0.4.6.tar.gz/lib/plugins/kolab_sso/localization/de.inc
Added
@@ -0,0 +1,14 @@ +<?php +/** + * Localizations for the Kolab SSO plugin + * + * Copyright (C) 2018, Kolab Systems AG + * + * For translation see https://www.transifex.com/projects/p/kolab/resource/kolab_sso/ + */ +$labels['loginby'] = 'Login über $provider'; +$labels['errorunknown'] = 'Unbekannter SSO Fehler.'; +$labels['errorservererror'] = 'SSO Serverfehler.'; +$labels['errorinteractionrequired'] = 'Benutzereingriff notwendig.'; +$labels['errorloginrequired'] = 'Benutzer-Authentifizierung notwendig.'; +$labels['erroraccountselectionrequired'] = 'Benutzerkonto-Auswahl notwendig.';
View file
iRony-0.4.5.tar.gz/lib/plugins/libcalendaring/composer.json -> iRony-0.4.6.tar.gz/lib/plugins/libcalendaring/composer.json
Changed
@@ -4,7 +4,7 @@ "description": "Library providing common functions for calendaring plugins", "homepage": "https://git.kolab.org/diffusion/RPK/", "license": "AGPLv3", - "version": "3.5.2", + "version": "3.5.10", "authors": [ { "name": "Thomas Bruederli",
View file
iRony-0.4.5.tar.gz/lib/plugins/libcalendaring/lib/Horde_Date.php -> iRony-0.4.6.tar.gz/lib/plugins/libcalendaring/lib/Horde_Date.php
Changed
@@ -292,7 +292,7 @@ */ public function toDateTime() { - $date = new DateTime(null, new DateTimeZone($this->_timezone)); + $date = new DateTime('now', new DateTimeZone($this->_timezone)); $date->setDate($this->_year, $this->_month, $this->_mday); $date->setTime($this->_hour, $this->_min, $this->_sec); return $date;
View file
iRony-0.4.5.tar.gz/lib/plugins/libcalendaring/lib/libcalendaring_itip.php -> iRony-0.4.6.tar.gz/lib/plugins/libcalendaring/lib/libcalendaring_itip.php
Changed
@@ -118,14 +118,15 @@ // compose a list of all event attendees $attendees_list = array(); foreach ((array)$event['attendees'] as $attendee) { - $attendees_list[] = ($attendee['name'] && $attendee['email']) ? + $attendees_list[] = (!empty($attendee['name']) && !empty($attendee['email'])) ? $attendee['name'] . ' <' . $attendee['email'] . '>' : - ($attendee['name'] ? $attendee['name'] : $attendee['email']); + (!empty($attendee['name']) ? $attendee['name'] : $attendee['email']); } $recurrence_info = ''; if (!empty($event['recurrence_id'])) { - $recurrence_info = "\n\n** " . $this->gettext($event['thisandfuture'] ? 'itipmessagefutureoccurrence' : 'itipmessagesingleoccurrence') . ' **'; + $msg = $this->gettext(!empty($event['thisandfuture']) ? 'itipmessagefutureoccurrence' : 'itipmessagesingleoccurrence'); + $recurrence_info = "\n\n** $msg **"; } else if (!empty($event['recurrence'])) { $recurrence_info = sprintf("\n%s: %s", $this->gettext('recurring'), $this->lib->recurrence_text($event['recurrence'])); @@ -139,7 +140,7 @@ 'attendees' => join(",\n ", $attendees_list), 'sender' => $this->sender['name'], 'organizer' => $this->sender['name'], - 'description' => $event['description'], + 'description' => isset($event['description']) ? $event['description'] : '', ) )); @@ -243,8 +244,14 @@ // set RSVP for every attendee else if ($method == 'REQUEST') { foreach ($event['attendees'] as $i => $attendee) { - if (($rsvp || !isset($attendee['rsvp'])) && ($attendee['status'] != 'DELEGATED' && $attendee['role'] != 'NON-PARTICIPANT')) { - $event['attendees'][$i]['rsvp']= (bool)$rsvp; + if ( + ($rsvp || !isset($attendee['rsvp'])) + && ( + (empty($attendee['status']) || $attendee['status'] != 'DELEGATED') + && $attendee['role'] != 'NON-PARTICIPANT' + ) + ) { + $event['attendees'][$i]['rsvp']= (bool) $rsvp; } } } @@ -293,7 +300,7 @@ // attach ics file for this event $ical = libcalendaring::get_ical(); $ics = $ical->export(array($event), $method, false, $method == 'REQUEST' && $this->plugin->driver ? array($this->plugin->driver, 'get_attachment_body') : false); - $filename = $event['_type'] == 'task' ? 'todo.ics' : 'event.ics'; + $filename = !empty($event['_type']) && $event['_type'] == 'task' ? 'todo.ics' : 'event.ics'; $message->addAttachment($ics, 'text/calendar', $filename, false, '8bit', '', RCUBE_CHARSET . "; method=" . $method); return $message; @@ -521,7 +528,7 @@ protected function get_itip_diff($event, $existing) { - if (empty($event) || empty($existing) || empty($event['message_uid'])) { + if (empty($event) || empty($existing) || empty($event['message_uid']) || empty($event['mime_id'])) { return; } @@ -556,14 +563,14 @@ $attendee['status'] = 'ACCEPTED'; // sometimes is not set for exceptions $existing['attendees'][$idx] = $attendee; } - $existing_attendees[] = $attendee['email'].$attendee['name']; + $existing_attendees[] = $attendee['email'] . (isset($attendee['name']) ? $attendee['name'] : ''); } foreach ((array) $itip['attendees'] as $idx => $attendee) { - if ($attendee['email'] && ($_status = $status[strtolower($attendee['email'])])) { - $attendee['status'] = $_status; + if (!empty($attendee['email']) && !empty($status[strtolower($attendee['email'])])) { + $attendee['status'] = $status[strtolower($attendee['email'])]; $itip['attendees'][$idx] = $attendee; } - $itip_attendees[] = $attendee['email'].$attendee['name']; + $itip_attendees[] = $attendee['email'] . (isset($attendee['name']) ? $attendee['name'] : ''); } if ($itip_attendees != $existing_attendees) { @@ -597,14 +604,16 @@ public function mail_itip_inline_ui($event, $method, $mime_id, $task, $message_date = null, $preview_url = null) { $buttons = array(); - $dom_id = asciiwords($event['uid'], true); - $rsvp_status = 'unknown'; + $dom_id = asciiwords($event['uid'], true); + + $rsvp_status = 'unknown'; + $rsvp_buttons = ''; // pass some metadata about the event and trigger the asynchronous status check $changed = is_object($event['changed']) ? $event['changed'] : $message_date; $metadata = array( 'uid' => $event['uid'], - '_instance' => $event['_instance'], + '_instance' => isset($event['_instance']) ? $event['_instance'] : null, 'changed' => $changed ? $changed->format('U') : 0, 'sequence' => intval($event['sequence']), 'method' => $method, @@ -744,7 +753,7 @@ } // add itip reply message controls - $rsvp_buttons .= html::div('itip-reply-controls', $this->itip_rsvp_options_ui($dom_id, $metadata['nosave'])); + $rsvp_buttons .= html::div('itip-reply-controls', $this->itip_rsvp_options_ui($dom_id, !empty($metadata['nosave']))); $buttons[] = html::div(array('id' => 'rsvp-'.$dom_id, 'class' => 'rsvp-buttons', 'style' => 'display:none'), $rsvp_buttons); $buttons[] = html::div(array('id' => 'update-'.$dom_id, 'style' => 'display:none'), $update_button); @@ -759,8 +768,8 @@ $title = $this->gettext('itipcancellation'); $event_prop = array_filter(array( 'uid' => $event['uid'], - '_instance' => $event['_instance'], - '_savemode' => $event['_savemode'], + '_instance' => isset($event['_instance']) ? $event['_instance'] : null, + '_savemode' => isset($event['_savemode']) ? $event['_savemode'] : null, )); // 1. remove the event from our calendar @@ -786,7 +795,7 @@ } // append generic import button - if ($import_button) { + if (!empty($import_button)) { $buttons[] = html::div(array('id' => 'import-'.$dom_id, 'style' => 'display:none'), $import_button); } @@ -815,13 +824,16 @@ { $attrib += array('type' => 'button'); - if (!$actions) + if (!$actions) { $actions = $this->rsvp_actions; + } + + $buttons = ''; foreach ($actions as $method) { $buttons .= html::tag('input', array( 'type' => $attrib['type'], - 'name' => $attrib['iname'], + 'name' => !empty($attrib['iname']) ? $attrib['iname'] : null, 'class' => 'button', 'rel' => $method, 'value' => $this->gettext('itip' . $method), @@ -923,7 +935,7 @@ $table->add('label', $this->gettext('recurring')); $table->add('recurrence', $this->lib->recurrence_text($event['recurrence'])); } - if ($location = trim($event['location'])) { + if (isset($event['location']) && ($location = trim($event['location']))) { $table->add('label', $this->gettext('location')); $table->add('location', rcube::Q($location)); } @@ -931,11 +943,11 @@ $table->add('label', $this->gettext('sensitivity')); $table->add('sensitivity', ucfirst($this->gettext($sensitivity)) . '!'); } - if ($event['status'] == 'COMPLETED' || $event['status'] == 'CANCELLED') { + if (!empty($event['status']) && ($event['status'] == 'COMPLETED' || $event['status'] == 'CANCELLED')) { $table->add('label', $this->gettext('status')); $table->add('status', $this->gettext('status-' . strtolower($event['status']))); } - if ($comment = trim($event['comment'])) { + if (isset($event['comment']) && ($comment = trim($event['comment']))) { $table->add('label', $this->gettext('comment')); $table->add('location', rcube::Q($comment)); }
View file
iRony-0.4.5.tar.gz/lib/plugins/libcalendaring/lib/libcalendaring_recurrence.php -> iRony-0.4.6.tar.gz/lib/plugins/libcalendaring/lib/libcalendaring_recurrence.php
Changed
@@ -61,15 +61,15 @@ $this->set_start($start); - if (is_array($recurrence['EXDATE'])) { - foreach ($recurrence['EXDATE'] as $exdate) { + if (!empty($recurrence['EXDATE'])) { + foreach ((array) $recurrence['EXDATE'] as $exdate) { if (is_a($exdate, 'DateTime')) { $this->engine->addException($exdate->format('Y'), $exdate->format('n'), $exdate->format('j')); } } } - if (is_array($recurrence['RDATE'])) { - foreach ($recurrence['RDATE'] as $rdate) { + if (!empty($recurrence['RDATE'])) { + foreach ((array) $recurrence['RDATE'] as $rdate) { if (is_a($rdate, 'DateTime')) { $this->engine->addRDate($rdate->format('Y'), $rdate->format('n'), $rdate->format('j')); } @@ -160,9 +160,10 @@ $start = clone $this->start; $orig_start = clone $this->start; $r = $this->recurrence; - $interval = intval($r['INTERVAL'] ?: 1); + $interval = !empty($r['INTERVAL']) ? intval($r['INTERVAL']) : 1; + $frequency = isset($this->recurrence['FREQ']) ? $this->recurrence['FREQ'] : null; - switch ($this->recurrence['FREQ']) { + switch ($frequency) { case 'WEEKLY': if (empty($this->recurrence['BYDAY'])) { return $start; @@ -193,7 +194,7 @@ $r = $this->recurrence; $r['INTERVAL'] = $interval; - if ($r['COUNT']) { + if (!empty($r['COUNT'])) { // Increase count so we do not stop the loop to early $r['COUNT'] += 100; }
View file
iRony-0.4.5.tar.gz/lib/plugins/libcalendaring/libcalendaring.js -> iRony-0.4.6.tar.gz/lib/plugins/libcalendaring/libcalendaring.js
Changed
@@ -371,7 +371,7 @@ */ this.text2html = function(str, maxlen, maxlines) { - var html = Q(String(str)); + var html = Q($.trim(String(str))); // limit visible text length if (maxlen) { @@ -411,21 +411,35 @@ // simple link parser (similar to rcube_string_replacer class in PHP) var utf_domain = '[^?&@"\'/\\(\\)\\s\\r\\t\\n]+\\.([^\x00-\x2f\x3b-\x40\x5b-\x60\x7b-\x7f]{2,}|xn--[a-z0-9]{2,})'; - var url1 = '.:;,', url2 = 'a-z0-9%=#@+?&/_~\\[\\]-'; + var url1 = '.;,', url2 = 'a-z0-9%=:#@+?&/_~\\[\\]-'; var link_pattern = new RegExp('([hf]t+ps?://)('+utf_domain+'(['+url1+']?['+url2+']+)*)', 'ig'); var mailto_pattern = new RegExp('([^\\s\\n\\(\\);]+@'+utf_domain+')', 'ig'); var link_replace = function(matches, p1, p2) { - var title = '', text = p2; + var title = '', suffix = ''; + if (p2 && p2.substr(-3) == '>') { + suffix = '>'; + p2 = p2.substr(0, p2.length - 3); + } + var href = p1 + p2; if (p2 && p2.length > 55) { - text = p2.substr(0, 45) + '...' + p2.substr(-8); title = p1 + p2; + p2 = p2.substr(0, 45) + '...' + p2.substr(-8); } - return '<a href="'+p1+p2+'" class="extlink" target="_blank" title="'+title+'">'+p1+text+'</a>' + + return '<a href="'+href+'" class="extlink" target="_blank" title="'+title+'">' + p1 + p2 + '</a>' + suffix + }; + + var mailto_replace = function(matches, p1, p2) { + // ignore links (created in link_replace() above + if (matches.match(/^(title|href)=/)) + return matches; + else + return '<a href="mailto:' + p1 + '">' + p1 + '</a>'; }; return html .replace(link_pattern, link_replace) - .replace(mailto_pattern, '<a href="mailto:$1">$1</a>') + .replace(mailto_pattern, mailto_replace) .replace(/(mailto:)([^"]+)"/g, '$1$2" onclick="rcmail.command(\'compose\', \'$2\');return false"') .replace(/\n/g, "<br/>"); };
View file
iRony-0.4.5.tar.gz/lib/plugins/libcalendaring/libcalendaring.php -> iRony-0.4.6.tar.gz/lib/plugins/libcalendaring/libcalendaring.php
Changed
@@ -40,23 +40,23 @@ public $ical_message; public $defaults = array( - 'calendar_date_format' => "Y-m-d", - 'calendar_date_short' => "M-j", - 'calendar_date_long' => "F j Y", - 'calendar_date_agenda' => "l M-d", - 'calendar_time_format' => "H:m", - 'calendar_first_day' => 1, - 'calendar_first_hour' => 6, - 'calendar_date_format_sets' => array( - 'Y-m-d' => array('d M Y', 'm-d', 'l m-d'), - 'Y/m/d' => array('d M Y', 'm/d', 'l m/d'), - 'Y.m.d' => array('d M Y', 'm.d', 'l m.d'), - 'd-m-Y' => array('d M Y', 'd-m', 'l d-m'), - 'd/m/Y' => array('d M Y', 'd/m', 'l d/m'), - 'd.m.Y' => array('d M Y', 'd.m', 'l d.m'), - 'j.n.Y' => array('d M Y', 'd.m', 'l d.m'), - 'm/d/Y' => array('M d Y', 'm/d', 'l m/d'), - ), + 'calendar_date_format' => "Y-m-d", + 'calendar_date_short' => "M-j", + 'calendar_date_long' => "F j Y", + 'calendar_date_agenda' => "l M-d", + 'calendar_time_format' => "H:m", + 'calendar_first_day' => 1, + 'calendar_first_hour' => 6, + 'calendar_date_format_sets' => array( + 'Y-m-d' => array('d M Y', 'm-d', 'l m-d'), + 'Y/m/d' => array('d M Y', 'm/d', 'l m/d'), + 'Y.m.d' => array('d M Y', 'm.d', 'l m.d'), + 'd-m-Y' => array('d M Y', 'd-m', 'l d-m'), + 'd/m/Y' => array('d M Y', 'd/m', 'l d/m'), + 'd.m.Y' => array('d M Y', 'd.m', 'l d.m'), + 'j.n.Y' => array('d M Y', 'd.m', 'l d.m'), + 'm/d/Y' => array('M d Y', 'm/d', 'l m/d'), + ), ); private static $instance; @@ -187,19 +187,20 @@ */ public function adjust_timezone($dt, $dateonly = false) { - if (is_numeric($dt)) + if (is_numeric($dt)) { $dt = new DateTime('@'.$dt); - else if (is_string($dt)) + } + else if (is_string($dt)) { $dt = rcube_utils::anytodatetime($dt); + } - if ($dt instanceof DateTime && !($dt->_dateonly || $dateonly)) { + if ($dt instanceof DateTime && empty($dt->_dateonly) && !$dateonly) { $dt->setTimezone($this->timezone); } return $dt; } - /** * */ @@ -289,11 +290,12 @@ */ public function event_date_text($event, $tzinfo = false) { - $fromto = '--'; + $fromto = '--'; + $is_task = !empty($event['_type']) && $event['_type'] == 'task'; // handle task objects - if ($event['_type'] == 'task' && is_object($event['due'])) { - $date_format = $event['due']->_dateonly ? self::to_php_date_format($this->rc->config->get('calendar_date_format', $this->defaults['calendar_date_format'])) : null; + if ($is_task && !empty($event['due']) && is_object($event['due'])) { + $date_format = !empty($event['due']->_dateonly) ? self::to_php_date_format($this->rc->config->get('calendar_date_format', $this->defaults['calendar_date_format'])) : null; $fromto = $this->rc->format_date($event['due'], $date_format, false); // add timezone information @@ -351,18 +353,21 @@ $select_type = new html_select(array('name' => 'alarmtype[]', 'class' => 'edit-alarm-type form-control', 'id' => $attrib['id'])); $select_offset = new html_select(array('name' => 'alarmoffset[]', 'class' => 'edit-alarm-offset form-control')); $select_related = new html_select(array('name' => 'alarmrelated[]', 'class' => 'edit-alarm-related form-control')); - $object_type = $attrib['_type'] ?: 'event'; + $object_type = !empty($attrib['_type']) ? $attrib['_type'] : 'event'; $select_type->add($this->gettext('none'), ''); - foreach ($alarm_types as $type) + foreach ($alarm_types as $type) { $select_type->add($this->gettext(strtolower("alarm{$type}option")), $type); + } - foreach (array('-M','-H','-D','+M','+H','+D') as $trigger) + foreach (array('-M','-H','-D','+M','+H','+D') as $trigger) { $select_offset->add($this->gettext('trigger' . $trigger), $trigger); + } $select_offset->add($this->gettext('trigger0'), '0'); - if ($absolute_time) + if ($absolute_time) { $select_offset->add($this->gettext('trigger@'), '@'); + } $select_related->add($this->gettext('relatedstart'), 'start'); $select_related->add($this->gettext('relatedend' . $object_type), 'end'); @@ -399,7 +404,7 @@ } // return cached result - if (is_array($_emails[$user])) { + if (isset($_emails[$user])) { return $_emails[$user]; } @@ -548,13 +553,18 @@ */ public static function alarm_text($alarm) { + $related = null; + if (is_string($alarm)) { list($trigger, $action) = explode(':', $alarm); } else { $trigger = $alarm['trigger']; $action = $alarm['action']; - $related = $alarm['related']; + + if (!empty($alarm['related'])) { + $related = $alarm['related']; + } } $text = ''; @@ -610,33 +620,45 @@ */ public static function get_next_alarm($rec, $type = 'event') { - if (!($rec['valarms'] || $rec['alarms']) || $rec['cancelled'] || $rec['status'] == 'CANCELLED') + if ( + (empty($rec['valarms']) && empty($rec['alarms'])) + || !empty($rec['cancelled']) + || (!empty($rec['status']) && $rec['status'] == 'CANCELLED') + ) { return null; + } if ($type == 'task') { $timezone = self::get_instance()->timezone; - if ($rec['startdate']) - $rec['start'] = new DateTime($rec['startdate'] . ' ' . ($rec['starttime'] ?: '12:00'), $timezone); - if ($rec['date']) - $rec[($rec['start'] ? 'end' : 'start')] = new DateTime($rec['date'] . ' ' . ($rec['time'] ?: '12:00'), $timezone); + if (!empty($rec['startdate'])) { + $time = !empty($rec['starttime']) ? $rec['starttime'] : '12:00'; + $rec['start'] = new DateTime($rec['startdate'] . ' ' . $time, $timezone); + } + if (!empty($rec['date'])) { + $time = !empty($rec['time']) ? $rec['time'] : '12:00'; + $rec[!empty($rec['start']) ? 'end' : 'start'] = new DateTime($rec['date'] . ' ' . $time, $timezone); + } } - if (!$rec['end']) + if (empty($rec['end'])) { $rec['end'] = $rec['start']; + } // support legacy format - if (!$rec['valarms']) { + if (empty($rec['valarms'])) { list($trigger, $action) = explode(':', $rec['alarms'], 2); if ($alarm = self::parse_alarm_value($trigger)) { $rec['valarms'] = array(array('action' => $action, 'trigger' => $alarm[3] ?: $alarm[0])); } } - $expires = new DateTime('now - 12 hours'); - $alarm_id = $rec['id']; // alarm ID eq. record ID by default to keep backwards compatibility + // alarm ID eq. record ID by default to keep backwards compatibility + $alarm_id = isset($rec['id']) ? $rec['id'] : null; + $alarm_prop = null; + $expires = new DateTime('now - 12 hours'); + $notify_at = null; // handle multiple alarms - $notify_at = null; foreach ($rec['valarms'] as $alarm) { $notify_time = null; @@ -644,11 +666,12 @@ $notify_time = $alarm['trigger']; } else if (is_string($alarm['trigger'])) { - $refdate = $alarm['related'] == 'END' ? $rec['end'] : $rec['start']; + $refdate = !empty($alarm['related']) && $alarm['related'] == 'END' ? $rec['end'] : $rec['start'];
View file
iRony-0.4.5.tar.gz/lib/plugins/libcalendaring/libvcalendar.php -> iRony-0.4.6.tar.gz/lib/plugins/libcalendaring/libvcalendar.php
Changed
@@ -326,10 +326,11 @@ $object = $this->_to_array($ve); // temporarily store this as exception - if ($object['recurrence_date']) { + if (!empty($object['recurrence_date'])) { $exceptions[] = $object; } - else if (!$seen[$object['uid']]++) { + else if (empty($seen[$object['uid']])) { + $seen[$object['uid']] = true; $this->objects[] = $object; } } @@ -343,7 +344,8 @@ $uid = $exception['uid']; // make this exception the master - if (!$seen[$uid]++) { + if (empty($seen[$uid])) { + $seen[$uid] = true; $this->objects[] = $exception; } else { @@ -412,7 +414,7 @@ // We can skip these fields, they aren't critical foreach (array('CREATED' => 'created', 'LAST-MODIFIED' => 'changed', 'DTSTAMP' => 'changed') as $attr => $field) { try { - if (!$event[$field] && $ve->{$attr}) { + if (empty($event[$field]) && !empty($ve->{$attr})) { $event[$field] = $ve->{$attr}->getDateTime(); } } catch (Exception $e) {} @@ -461,15 +463,17 @@ break; case 'RRULE': - $params = is_array($event['recurrence']) ? $event['recurrence'] : array(); + $params = !empty($event['recurrence']) && is_array($event['recurrence']) ? $event['recurrence'] : array(); // parse recurrence rule attributes foreach ($prop->getParts() as $k => $v) { $params[strtoupper($k)] = is_array($v) ? implode(',', $v) : $v; } - if ($params['UNTIL']) + if (!empty($params['UNTIL'])) { $params['UNTIL'] = date_create($params['UNTIL']); - if (!$params['INTERVAL']) + } + if (empty($params['INTERVAL'])) { $params['INTERVAL'] = 1; + } $event['recurrence'] = array_filter($params); break; @@ -477,14 +481,24 @@ case 'EXDATE': if (!empty($value)) { $exdates = array_map(function($_) { return is_array($_) ? $_[0] : $_; }, self::convert_datetime($prop, true)); - $event['recurrence']['EXDATE'] = array_merge((array)$event['recurrence']['EXDATE'], $exdates); + if (!empty($event['recurrence']['EXDATE'])) { + $event['recurrence']['EXDATE'] = array_merge($event['recurrence']['EXDATE'], $exdates); + } + else { + $event['recurrence']['EXDATE'] = $exdates; + } } break; case 'RDATE': if (!empty($value)) { $rdates = array_map(function($_) { return is_array($_) ? $_[0] : $_; }, self::convert_datetime($prop, true)); - $event['recurrence']['RDATE'] = array_merge((array)$event['recurrence']['RDATE'], $rdates); + if (!empty($event['recurrence']['RDATE'])) { + $event['recurrence']['RDATE'] = array_merge($event['recurrence']['RDATE'], $rdates); + } + else { + $event['recurrence']['RDATE'] = $rdates; + } } break; @@ -519,7 +533,12 @@ case 'CATEGORY': case 'CATEGORIES': - $event['categories'] = array_merge((array)$event['categories'], $prop->getParts()); + if (!empty($event['categories'])) { + $event['categories'] = array_merge((array) $event['categories'], $prop->getParts()); + } + else { + $event['categories'] = $prop->getParts(); + } break; case 'CLASS': @@ -528,10 +547,12 @@ break; case 'X-MICROSOFT-CDO-BUSYSTATUS': - if ($value == 'OOF') + if ($value == 'OOF') { $event['free_busy'] = 'outofoffice'; - else if (in_array($value, array('FREE', 'BUSY', 'TENTATIVE'))) + } + else if (in_array($value, array('FREE', 'BUSY', 'TENTATIVE'))) { $event['free_busy'] = strtolower($value); + } break; case 'ATTENDEE': @@ -556,7 +577,7 @@ $schedule_agent = $attendee['schedule-agent']; } } - else if ($attendee['email'] != $event['organizer']['email']) { + else if (empty($event['organizer']) || $attendee['email'] != $event['organizer']['email']) { $event['attendees'][] = $attendee; } break; @@ -596,12 +617,7 @@ // validate event dates if ($event['_type'] == 'event') { - $event['allday'] = false; - - // check for all-day dates - if ($event['start']->_dateonly) { - $event['allday'] = true; - } + $event['allday'] = !empty($event['start']->_dateonly); // events may lack the DTEND property, set it to DTSTART (RFC5545 3.6.1) if (empty($event['end'])) { @@ -647,11 +663,12 @@ $trigger = $values[2]; } - if (!$alarm['trigger']) { + if (empty($alarm['trigger'])) { $alarm['trigger'] = rtrim(preg_replace('/([A-Z])0[WDHMS]/', '\\1', $value), 'T'); // if all 0-values have been stripped, assume 'at time' - if ($alarm['trigger'] == 'P') + if ($alarm['trigger'] == 'P') { $alarm['trigger'] = 'PT0S'; + } } break; @@ -684,23 +701,26 @@ } if ($action != 'NONE') { - if ($trigger && !$event['alarms']) // store first alarm in legacy property + // store first alarm in legacy property + if ($trigger && empty($event['alarms'])) { $event['alarms'] = $trigger . ':' . $action; + } - if ($alarm['trigger']) + if (!empty($alarm['trigger'])) { $event['valarms'][] = $alarm; + } } } // assign current timezone to event start/end - if ($event['start'] instanceof DateTime) { + if (!empty($event['start']) && $event['start'] instanceof DateTime) { $this->_apply_timezone($event['start']); } else { unset($event['start']); } - if ($event['end'] instanceof DateTime) { + if (!empty($event['end']) && $event['end'] instanceof DateTime) { $this->_apply_timezone($event['end']); } else { @@ -708,7 +728,7 @@ } // some iTip CANCEL messages only contain the start date - if (!$event['end'] && $event['start'] && $this->method == 'CANCEL') { + if (empty($event['end']) && !empty($event['start']) && $this->method == 'CANCEL') { $event['end'] = clone $event['start']; } @@ -736,7 +756,7 @@ } // For date-only we'll keep the date and time intact - if ($date->_dateonly) { + if (!empty($date->_dateonly)) { $dt = new DateTime(null, $this->timezone); $dt->setDate($date->format('Y'), $date->format('n'), $date->format('j')); $dt->setTime($date->format('G'), $date->format('i'), 0); @@ -767,7 +787,13 @@ case 'DTSTAMP': case 'DTSTART':
View file
iRony-0.4.5.tar.gz/lib/plugins/libcalendaring/tests/libcalendaring.php -> iRony-0.4.6.tar.gz/lib/plugins/libcalendaring/tests/libcalendaring.php
Changed
@@ -21,7 +21,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -class libcalendaring_test extends PHPUnit_Framework_TestCase +class libcalendaring_test extends PHPUnit\Framework\TestCase { function setUp() {
View file
iRony-0.4.5.tar.gz/lib/plugins/libcalendaring/tests/libvcalendar.php -> iRony-0.4.6.tar.gz/lib/plugins/libcalendaring/tests/libvcalendar.php
Changed
@@ -21,7 +21,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -class libvcalendar_test extends PHPUnit_Framework_TestCase +class libvcalendar_test extends PHPUnit\Framework\TestCase { function setUp() { @@ -209,7 +209,7 @@ $this->assertEquals('-PT30M', $alarm[3], "Unified alarm string (stripped zero-values)"); $this->assertEquals('DISPLAY', $event['valarms'][0]['action'], "First alarm action"); - $this->assertEquals('', $event['valarms'][0]['related'], "First alarm related property"); + $this->assertTrue(empty($event['valarms'][0]['related']), "First alarm related property"); $this->assertEquals('This is the first event reminder', $event['valarms'][0]['description'], "First alarm text"); $this->assertEquals(3, count($event['valarms']), "List all VALARM blocks"); @@ -553,7 +553,7 @@ $this->assertEquals('4', $vtz->{'X-MICROSOFT-CDO-TZID'}); // check for transition to daylight saving time which is BEFORE the given date - $dst = reset($vtz->select('DAYLIGHT')); + $dst = array_first($vtz->select('DAYLIGHT')); $this->assertEquals('DAYLIGHT', $dst->name); $this->assertEquals('20140330T010000', $dst->DTSTART); $this->assertEquals('+0100', $dst->TZOFFSETFROM); @@ -561,7 +561,8 @@ $this->assertEquals('CEST', $dst->TZNAME); // check (last) transition to standard time which is AFTER the given date - $std = end($vtz->select('STANDARD')); + $std = $vtz->select('STANDARD'); + $std = end($std); $this->assertEquals('STANDARD', $std->name); $this->assertEquals('20141026T010000', $std->DTSTART); $this->assertEquals('+0200', $std->TZOFFSETFROM);
View file
iRony-0.4.5.tar.gz/lib/plugins/libkolab/README -> iRony-0.4.6.tar.gz/lib/plugins/libkolab/README
Changed
@@ -32,7 +32,6 @@ IMPORTANT --------- - This plugin doesn't work with the Classic skin of Roundcube because no templates are available for that skin.
View file
iRony-0.4.5.tar.gz/lib/plugins/libkolab/SQL/mysql.initial.sql -> iRony-0.4.6.tar.gz/lib/plugins/libkolab/SQL/mysql.initial.sql
Changed
@@ -1,12 +1,11 @@ /** * libkolab database schema * - * @version 1.2 * @author Thomas Bruederli * @licence GNU AGPL - **/ + */ -/*!40014 SET FOREIGN_KEY_CHECKS=0 */; +SET FOREIGN_KEY_CHECKS=0; DROP TABLE IF EXISTS `kolab_folders`; @@ -20,7 +19,7 @@ `objectcount` BIGINT DEFAULT NULL, PRIMARY KEY(`folder_id`), INDEX `resource_type` (`resource`, `type`) -) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */; +) ROW_FORMAT=DYNAMIC ENGINE=INNODB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; DROP TABLE IF EXISTS `kolab_cache`; @@ -45,7 +44,7 @@ PRIMARY KEY(`folder_id`,`msguid`), INDEX `contact_type` (`folder_id`,`type`), INDEX `contact_uid2msguid` (`folder_id`,`uid`,`msguid`) -) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */; +) ROW_FORMAT=DYNAMIC ENGINE=INNODB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; DROP TABLE IF EXISTS `kolab_cache_event`; @@ -64,7 +63,7 @@ REFERENCES `kolab_folders`(`folder_id`) ON DELETE CASCADE ON UPDATE CASCADE, PRIMARY KEY(`folder_id`,`msguid`), INDEX `event_uid2msguid` (`folder_id`,`uid`,`msguid`) -) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */; +) ROW_FORMAT=DYNAMIC ENGINE=INNODB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; DROP TABLE IF EXISTS `kolab_cache_task`; @@ -83,7 +82,7 @@ REFERENCES `kolab_folders`(`folder_id`) ON DELETE CASCADE ON UPDATE CASCADE, PRIMARY KEY(`folder_id`,`msguid`), INDEX `task_uid2msguid` (`folder_id`,`uid`,`msguid`) -) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */; +) ROW_FORMAT=DYNAMIC ENGINE=INNODB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; DROP TABLE IF EXISTS `kolab_cache_journal`; @@ -102,7 +101,7 @@ REFERENCES `kolab_folders`(`folder_id`) ON DELETE CASCADE ON UPDATE CASCADE, PRIMARY KEY(`folder_id`,`msguid`), INDEX `journal_uid2msguid` (`folder_id`,`uid`,`msguid`) -) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */; +) ROW_FORMAT=DYNAMIC ENGINE=INNODB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; DROP TABLE IF EXISTS `kolab_cache_note`; @@ -119,7 +118,7 @@ REFERENCES `kolab_folders`(`folder_id`) ON DELETE CASCADE ON UPDATE CASCADE, PRIMARY KEY(`folder_id`,`msguid`), INDEX `note_uid2msguid` (`folder_id`,`uid`,`msguid`) -) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */; +) ROW_FORMAT=DYNAMIC ENGINE=INNODB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; DROP TABLE IF EXISTS `kolab_cache_file`; @@ -138,7 +137,7 @@ PRIMARY KEY(`folder_id`,`msguid`), INDEX `folder_filename` (`folder_id`, `filename`), INDEX `file_uid2msguid` (`folder_id`,`uid`,`msguid`) -) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */; +) ROW_FORMAT=DYNAMIC ENGINE=INNODB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; DROP TABLE IF EXISTS `kolab_cache_configuration`; @@ -157,7 +156,7 @@ PRIMARY KEY(`folder_id`,`msguid`), INDEX `configuration_type` (`folder_id`,`type`), INDEX `configuration_uid2msguid` (`folder_id`,`uid`,`msguid`) -) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */; +) ROW_FORMAT=DYNAMIC ENGINE=INNODB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; DROP TABLE IF EXISTS `kolab_cache_freebusy`; @@ -176,8 +175,8 @@ REFERENCES `kolab_folders`(`folder_id`) ON DELETE CASCADE ON UPDATE CASCADE, PRIMARY KEY(`folder_id`,`msguid`), INDEX `freebusy_uid2msguid` (`folder_id`,`uid`,`msguid`) -) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */; +) ROW_FORMAT=DYNAMIC ENGINE=INNODB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -/*!40014 SET FOREIGN_KEY_CHECKS=1 */; +SET FOREIGN_KEY_CHECKS=1; -REPLACE INTO `system` (`name`, `value`) VALUES ('libkolab-version', '2019092900'); +REPLACE INTO `system` (`name`, `value`) VALUES ('libkolab-version', '2021101100');
View file
iRony-0.4.6.tar.gz/lib/plugins/libkolab/SQL/mysql/2021101100.sql
Added
@@ -0,0 +1,46 @@ +-- changing table format and dropping foreign keys is needed for some versions of MySQL +ALTER TABLE `kolab_cache_contact` DROP FOREIGN KEY `fk_kolab_cache_contact_folder`; +ALTER TABLE `kolab_cache_event` DROP FOREIGN KEY`fk_kolab_cache_event_folder`; +ALTER TABLE `kolab_cache_task` DROP FOREIGN KEY`fk_kolab_cache_task_folder`; +ALTER TABLE `kolab_cache_journal` DROP FOREIGN KEY`fk_kolab_cache_journal_folder`; +ALTER TABLE `kolab_cache_note` DROP FOREIGN KEY`fk_kolab_cache_note_folder`; +ALTER TABLE `kolab_cache_file` DROP FOREIGN KEY`fk_kolab_cache_file_folder`; +ALTER TABLE `kolab_cache_configuration` DROP FOREIGN KEY`fk_kolab_cache_configuration_folder`; +ALTER TABLE `kolab_cache_freebusy` DROP FOREIGN KEY`fk_kolab_cache_freebusy_folder`; + +ALTER TABLE `kolab_folders` ROW_FORMAT=DYNAMIC; +ALTER TABLE `kolab_cache_contact` ROW_FORMAT=DYNAMIC; +ALTER TABLE `kolab_cache_event` ROW_FORMAT=DYNAMIC; +ALTER TABLE `kolab_cache_task` ROW_FORMAT=DYNAMIC; +ALTER TABLE `kolab_cache_journal` ROW_FORMAT=DYNAMIC; +ALTER TABLE `kolab_cache_note` ROW_FORMAT=DYNAMIC; +ALTER TABLE `kolab_cache_file` ROW_FORMAT=DYNAMIC; +ALTER TABLE `kolab_cache_configuration` ROW_FORMAT=DYNAMIC; +ALTER TABLE `kolab_cache_freebusy` ROW_FORMAT=DYNAMIC; + +ALTER TABLE `kolab_folders` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE `kolab_cache_contact` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE `kolab_cache_event` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE `kolab_cache_task` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE `kolab_cache_journal` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE `kolab_cache_note` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE `kolab_cache_file` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE `kolab_cache_configuration` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE `kolab_cache_freebusy` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +ALTER TABLE `kolab_cache_contact` ADD CONSTRAINT `fk_kolab_cache_contact_folder` FOREIGN KEY (`folder_id`) + REFERENCES `kolab_folders`(`folder_id`) ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE `kolab_cache_event` ADD CONSTRAINT `fk_kolab_cache_event_folder` FOREIGN KEY (`folder_id`) + REFERENCES `kolab_folders`(`folder_id`) ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE `kolab_cache_task` ADD CONSTRAINT `fk_kolab_cache_task_folder` FOREIGN KEY (`folder_id`) + REFERENCES `kolab_folders`(`folder_id`) ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE `kolab_cache_journal` ADD CONSTRAINT `fk_kolab_cache_journal_folder` FOREIGN KEY (`folder_id`) + REFERENCES `kolab_folders`(`folder_id`) ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE `kolab_cache_note` ADD CONSTRAINT `fk_kolab_cache_note_folder` FOREIGN KEY (`folder_id`) + REFERENCES `kolab_folders`(`folder_id`) ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE `kolab_cache_file` ADD CONSTRAINT `fk_kolab_cache_file_folder` FOREIGN KEY (`folder_id`) + REFERENCES `kolab_folders`(`folder_id`) ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE `kolab_cache_configuration` ADD CONSTRAINT `fk_kolab_cache_configuration_folder` FOREIGN KEY (`folder_id`) + REFERENCES `kolab_folders`(`folder_id`) ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE `kolab_cache_freebusy` ADD CONSTRAINT `fk_kolab_cache_freebusy_folder` FOREIGN KEY (`folder_id`) + REFERENCES `kolab_folders`(`folder_id`) ON DELETE CASCADE ON UPDATE CASCADE;
View file
iRony-0.4.5.tar.gz/lib/plugins/libkolab/SQL/oracle.initial.sql -> iRony-0.4.6.tar.gz/lib/plugins/libkolab/SQL/oracle.initial.sql
Changed
@@ -1,11 +1,9 @@ /** * libkolab database schema * - * @version 1.2 * @author Aleksander Machniak * @licence GNU AGPL - **/ - + */ CREATE TABLE "kolab_folders" ( "folder_id" number NOT NULL PRIMARY KEY, @@ -175,4 +173,4 @@ CREATE INDEX "kolab_cache_fb_uid2msguid" ON "kolab_cache_freebusy" ("folder_id", "uid", "msguid"); -INSERT INTO "system" ("name", "value") VALUES ('libkolab-version', '2019092900'); +INSERT INTO "system" ("name", "value") VALUES ('libkolab-version', '2021101100');
View file
iRony-0.4.6.tar.gz/lib/plugins/libkolab/SQL/oracle/2021101100.sql
Added
@@ -0,0 +1,1 @@ +-- empty \ No newline at end of file
View file
iRony-0.4.5.tar.gz/lib/plugins/libkolab/SQL/sqlite.initial.sql -> iRony-0.4.6.tar.gz/lib/plugins/libkolab/SQL/sqlite.initial.sql
Changed
@@ -1,10 +1,9 @@ /** * libkolab database schema * - * @version 1.2 * @author Thomas Bruederli * @licence GNU AGPL - **/ + */ CREATE TABLE kolab_folders ( folder_id INTEGER NOT NULL PRIMARY KEY, @@ -148,4 +147,4 @@ CREATE INDEX ix_freebusy_uid2msguid ON kolab_cache_freebusy(folder_id,uid,msguid); -INSERT INTO system (name, value) VALUES ('libkolab-version', '2019092900'); +INSERT INTO system (name, value) VALUES ('libkolab-version', '2021101100');
View file
iRony-0.4.6.tar.gz/lib/plugins/libkolab/SQL/sqlite/2021101100.sql
Added
@@ -0,0 +1,1 @@ +-- empty \ No newline at end of file
View file
iRony-0.4.5.tar.gz/lib/plugins/libkolab/bin/modcache.sh -> iRony-0.4.6.tar.gz/lib/plugins/libkolab/bin/modcache.sh
Changed
@@ -201,7 +201,7 @@ // prompt for password if (empty($opts['password']) && ($opts['username'] || $opts['user'])) { - $opts['password'] = prompt_silent("Password: "); + $opts['password'] = rcube_utils::prompt_silent("Password: "); } // simulate "login as" feature @@ -210,9 +210,22 @@ else if (empty($opts['user'])) $opts['user'] = $opts['username']; + // parse $host URL + $url = parse_url(trim($opts['host'])); + if (!empty($url['host'])) { + $imap_host = $url['host']; + $imap_ssl = isset($url['scheme']) && in_array($url['scheme'], array('ssl','imaps','tls')) ? $url['scheme'] : false; + $imap_port = isset($url['port']) ? $url['port'] : ($imap_ssl && $imap_ssl != 'tls' ? 993 : 143); + } + else { + $imap_host = trim($opts['host']); + $imap_port = 143; + $imap_ssl = false; + } + // let the kolab_auth plugin do its magic $auth = $rcmail->plugins->exec_hook('authenticate', array( - 'host' => trim($opts['host']), + 'host' => $imap_host, 'user' => trim($opts['user']), 'pass' => $opts['password'], 'cookiecheck' => false, @@ -221,7 +234,7 @@ if ($auth['valid']) { $storage = $rcmail->get_storage(); - if ($storage->connect($auth['host'], $auth['user'], $auth['pass'], 143, false)) { + if ($storage->connect($imap_host, $auth['user'], $auth['pass'], $imap_port, $imap_ssl)) { if ($opts['verbose']) echo "IMAP login succeeded.\n"; if (($user = rcube_user::query($opts['username'], $auth['host'])) && $user->ID)
View file
iRony-0.4.5.tar.gz/lib/plugins/libkolab/composer.json -> iRony-0.4.6.tar.gz/lib/plugins/libkolab/composer.json
Changed
@@ -4,7 +4,7 @@ "description": "Plugin to setup a basic environment for the interaction with a Kolab server.", "homepage": "https://git.kolab.org/diffusion/RPK/", "license": "AGPLv3", - "version": "3.5.5", + "version": "3.5.10", "authors": [ { "name": "Thomas Bruederli",
View file
iRony-0.4.5.tar.gz/lib/plugins/libkolab/config.inc.php.dist -> iRony-0.4.6.tar.gz/lib/plugins/libkolab/config.inc.php.dist
Changed
@@ -5,10 +5,6 @@ // Enable caching of Kolab objects in local database $config['kolab_cache'] = true; -// Cache refresh interval (default is 12 hours) -// after this period, cache is forced to synchronize with IMAP -$config['kolab_cache_refresh'] = '12h'; - // Specify format version to write Kolab objects (must be a string value!) $config['kolab_format_version'] = '3.0';
View file
iRony-0.4.5.tar.gz/lib/plugins/libkolab/lib/kolab_attachments_handler.php -> iRony-0.4.6.tar.gz/lib/plugins/libkolab/lib/kolab_attachments_handler.php
Changed
@@ -48,7 +48,7 @@ */ public function files_list($attrib = array()) { - if (!$attrib['id']) { + if (empty($attrib['id'])) { $attrib['id'] = 'kolabattachmentlist'; } @@ -67,7 +67,7 @@ public function files_form($attrib = array()) { // add ID if not given - if (!$attrib['id']) { + if (empty($attrib['id'])) { $attrib['id'] = 'kolabuploadform'; } @@ -80,7 +80,7 @@ public function files_drop_area($attrib = array()) { // add ID if not given - if (!$attrib['id']) { + if (empty($attrib['id'])) { $attrib['id'] = 'kolabfiledroparea'; } @@ -117,7 +117,7 @@ $recid = $id_prefix . rcube_utils::get_input_value('_id', rcube_utils::INPUT_GPC); $uploadid = rcube_utils::get_input_value('_uploadid', rcube_utils::INPUT_GPC); - if (!is_array($_SESSION[$session_key]) || $_SESSION[$session_key]['id'] != $recid) { + if (empty($_SESSION[$session_key]) || $_SESSION[$session_key]['id'] != $recid) { $_SESSION[$session_key] = array(); $_SESSION[$session_key]['id'] = $recid; $_SESSION[$session_key]['attachments'] = array(); @@ -151,13 +151,16 @@ unset($attachment['status'], $attachment['abort']); $this->rc->session->append($session_key . '.attachments', $id, $attachment); - if (($icon = $_SESSION[$session_key . '_deleteicon']) && is_file($icon)) { + if (!empty($_SESSION[$session_key . '_deleteicon']) + && ($icon = $_SESSION[$session_key . '_deleteicon']) + && is_file($icon) + ) { $button = html::img(array( 'src' => $icon, 'alt' => $this->rc->gettext('delete') )); } - else if ($_SESSION[$session_key . '_textbuttons']) { + else if (!empty($_SESSION[$session_key . '_textbuttons'])) { $button = rcube::Q($this->rc->gettext('delete')); } else { @@ -181,7 +184,8 @@ 'onclick' => 'return false', // sprintf("return %s.command('load-attachment','rcmfile%s', this, event)", rcmail_output::JS_OBJECT_NAME, $id), ), $link_content); - $content .= $_SESSION[$session_key . '_icon_pos'] == 'left' ? $delete_link.$content_link : $content_link.$delete_link; + $left = !empty($_SESSION[$session_key . '_icon_pos']) && $_SESSION[$session_key . '_icon_pos'] == 'left'; + $content = $left ? $delete_link.$content_link : $content_link.$delete_link; $this->rc->output->command('add2attachment_list', "rcmfile$id", array( 'html' => $content, @@ -196,7 +200,7 @@ $msg = $this->rc->gettext(array('name' => 'filesizeerror', 'vars' => array( 'size' => $this->rc->show_bytes(parse_bytes(ini_get('upload_max_filesize')))))); } - else if ($attachment['error']) { + else if (!empty($attachment['error'])) { $msg = $attachment['error']; } else { @@ -211,11 +215,13 @@ else if ($_SERVER['REQUEST_METHOD'] == 'POST') { // if filesize exceeds post_max_size then $_FILES array is empty, // show filesizeerror instead of fileuploaderror - if ($maxsize = ini_get('post_max_size')) + if ($maxsize = ini_get('post_max_size')) { $msg = $this->rc->gettext(array('name' => 'filesizeerror', 'vars' => array( 'size' => $this->rc->show_bytes(parse_bytes($maxsize))))); - else + } + else { $msg = $this->rc->gettext('fileuploaderror'); + } $this->rc->output->command('display_message', $msg, 'error'); $this->rc->output->command('remove_from_attachment_list', $uploadid); @@ -233,7 +239,7 @@ { ob_end_clean(); - if ($attachment && $attachment['body']) { + if ($attachment && !empty($attachment['body'])) { // allow post-processing of the attachment body $part = new rcube_message_part; $part->filename = $attachment['name'];
View file
iRony-0.4.5.tar.gz/lib/plugins/libkolab/lib/kolab_bonnie_api.php -> iRony-0.4.6.tar.gz/lib/plugins/libkolab/lib/kolab_bonnie_api.php
Changed
@@ -93,5 +93,4 @@ { return $this->client->execute($method, $params); } - -} \ No newline at end of file +}
View file
iRony-0.4.5.tar.gz/lib/plugins/libkolab/lib/kolab_bonnie_api_client.php -> iRony-0.4.6.tar.gz/lib/plugins/libkolab/lib/kolab_bonnie_api_client.php
Changed
@@ -235,5 +235,4 @@ rcube::write_log('bonnie', join(";\n", $msg)); } - -} \ No newline at end of file +}
View file
iRony-0.4.5.tar.gz/lib/plugins/libkolab/lib/kolab_format_task.php -> iRony-0.4.6.tar.gz/lib/plugins/libkolab/lib/kolab_format_task.php
Changed
@@ -151,5 +151,4 @@ return array_unique($tags); } - }
View file
iRony-0.4.5.tar.gz/lib/plugins/libkolab/lib/kolab_storage.php -> iRony-0.4.6.tar.gz/lib/plugins/libkolab/lib/kolab_storage.php
Changed
@@ -47,7 +47,6 @@ private static $with_tempsubs = true; private static $subscriptions; private static $ldapcache = array(); - private static $typedata = array(); private static $ldap = array(); private static $states; private static $config; @@ -869,7 +868,8 @@ return array(); } - // In some conditions we can skip LIST command (?) + // If we only want groupware folders and don't care about the subscription state, + // then the metadata will already contain all folder names and we can avoid the LIST below. if (!$subscribed && $filter != 'mail' && $prefix == '*') { foreach ($folderdata as $folder => $type) { if (!preg_match($regexp, $type)) { @@ -1106,11 +1106,6 @@ return false; } - // return cached result - if (is_array(self::$typedata[$prefix])) { - return self::$typedata[$prefix]; - } - $type_keys = array(self::CTYPE_KEY, self::CTYPE_KEY_PRIVATE); // fetch metadata from *some* folders only @@ -1153,10 +1148,7 @@ return false; } - // keep list in memory - self::$typedata[$prefix] = array_map(array('kolab_storage', 'folder_select_metadata'), $folderdata); - - return self::$typedata[$prefix]; + return array_map(array('kolab_storage', 'folder_select_metadata'), $folderdata); } /** @@ -1185,13 +1177,6 @@ { self::setup(); - // return in-memory cached result - foreach (self::$typedata as $typedata) { - if (array_key_exists($folder, $typedata)) { - return $typedata[$folder]; - } - } - $metadata = self::$imap->get_metadata($folder, array(self::CTYPE_KEY, self::CTYPE_KEY_PRIVATE)); if (!is_array($metadata)) {
View file
iRony-0.4.5.tar.gz/lib/plugins/libkolab/lib/kolab_storage_cache.php -> iRony-0.4.6.tar.gz/lib/plugins/libkolab/lib/kolab_storage_cache.php
Changed
@@ -27,8 +27,6 @@ const DB_DATE_FORMAT = 'Y-m-d H:i:s'; const MAX_RECORDS = 500; - public $sync_complete = false; - protected $db; protected $imap; protected $folder; @@ -42,7 +40,6 @@ protected $synclock = false; protected $ready = false; protected $cache_table; - protected $cache_refresh = 3600; protected $folders_table; protected $max_sql_packet; protected $max_sync_lock_time = 600; @@ -85,7 +82,6 @@ $this->imap = $rcmail->get_storage(); $this->enabled = $rcmail->config->get('kolab_cache', false); $this->folders_table = $this->db->table_name('kolab_folders'); - $this->cache_refresh = get_offset_sec($rcmail->config->get('kolab_cache_refresh', '12h')); $this->server_timezone = new DateTimeZone(date_default_timezone_get()); if ($this->enabled) { @@ -174,16 +170,6 @@ if ($this->synched) return; - // increase time limit - @set_time_limit($this->max_sync_lock_time - 60); - - // get effective time limit we have for synchronization (~70% of the execution time) - $time_limit = ini_get('max_execution_time') * 0.7; - $sync_start = time(); - - // assume sync will be completed - $this->sync_complete = true; - if (!$this->ready) { // kolab cache is disabled, synchronize IMAP mailbox cache only $this->imap_mode(true); @@ -191,124 +177,312 @@ $this->imap_mode(false); } else { + $this->sync_start = time(); + // read cached folder metadata $this->_read_folder_data(); + // Read folder data from IMAP + $ctag = $this->folder->get_ctag(); + + // Validate current ctag + list($uidvalidity, $highestmodseq, $uidnext) = explode('-', $ctag); + + if (empty($uidvalidity) || empty($highestmodseq)) { + rcube::raise_error(array( + 'code' => 900, + 'message' => "Failed to sync the kolab cache (Invalid ctag)" + ), true); + } // check cache status ($this->metadata is set in _read_folder_data()) - if ( empty($this->metadata['ctag']) || - empty($this->metadata['changed']) || - $this->metadata['objectcount'] === null || - $this->metadata['changed'] < date(self::DB_DATE_FORMAT, time() - $this->cache_refresh) || - $this->metadata['ctag'] != $this->folder->get_ctag() || - intval($this->metadata['objectcount']) !== $this->count() + else if ( + empty($this->metadata['ctag']) + || empty($this->metadata['changed']) + || $this->metadata['ctag'] !== $ctag ) { // lock synchronization for this folder or wait if locked $this->_sync_lock(); - // disable messages cache if configured to do so - $this->imap_mode(true); + // Run a full-sync (initial sync or continue the aborted sync) + if (empty($this->metadata['changed']) || empty($this->metadata['ctag'])) { + $result = $this->synchronize_full(); + } + // Synchronize only the changes since last sync + else { + $result = $this->synchronize_update($ctag); + } + + // update ctag value (will be written to database in _sync_unlock()) + if ($result) { + $this->metadata['ctag'] = $ctag; + $this->metadata['changed'] = date(self::DB_DATE_FORMAT, time()); + } + + // remove lock + $this->_sync_unlock(); + } + } - // synchronize IMAP mailbox cache - $this->imap->folder_sync($this->folder->name); + $this->check_error(); + $this->synched = time(); + } - // compare IMAP index with object cache index - $imap_index = $this->imap->index($this->folder->name, null, null, true, true); + /** + * Perform full cache synchronization + */ + protected function synchronize_full() + { + // get effective time limit we have for synchronization (~70% of the execution time) + $time_limit = $this->_max_sync_lock_time() * 0.7; - $this->imap_mode(false); + if (time() - $this->sync_start > $time_limit) { + return false; + } - // determine objects to fetch or to invalidate - if (!$imap_index->is_error()) { - $imap_index = $imap_index->get(); - $old_index = array(); - $del_index = array(); + // disable messages cache if configured to do so + $this->imap_mode(true); - // read cache index - $sql_result = $this->db->query( - "SELECT `msguid`, `uid` FROM `{$this->cache_table}` WHERE `folder_id` = ?" - . " ORDER BY `msguid` DESC", $this->folder_id - ); + // synchronize IMAP mailbox cache, does nothing if messages cache is disabled + $this->imap->folder_sync($this->folder->name); - while ($sql_arr = $this->db->fetch_assoc($sql_result)) { - // Mark all duplicates for removal (note sorting order above) - // Duplicates here should not happen, but they do sometimes - if (isset($old_index[$sql_arr['uid']])) { - $del_index[] = $sql_arr['msguid']; - } - else { - $old_index[$sql_arr['uid']] = $sql_arr['msguid']; - } - } + // compare IMAP index with object cache index + $imap_index = $this->imap->index($this->folder->name, null, null, true, true); - // fetch new objects from imap - $i = 0; - foreach (array_diff($imap_index, $old_index) as $msguid) { - // Note: We'll store only objects matching the folder type - // anything else will be silently ignored - if ($object = $this->folder->read_object($msguid)) { - // Deduplication: remove older objects with the same UID - // Here we do not resolve conflicts, we just make sure - // the most recent version of the object will be used - if ($old_msguid = $old_index[$object['uid']]) { - if ($old_msguid < $msguid) { - $del_index[] = $old_msguid; - } - else { - $del_index[] = $msguid; - continue; - } - } - - $old_index[$object['uid']] = $msguid; - - $this->_extended_insert($msguid, $object); - - // check time limit and abort sync if running too long - if (++$i % 50 == 0 && time() - $sync_start > $time_limit) { - $this->sync_complete = false; - break; - } - } - } - $this->_extended_insert(0, null); + $this->imap_mode(false); - $del_index = array_unique($del_index); + if ($imap_index->is_error()) { + rcube::raise_error(array( + 'code' => 900, + 'message' => "Failed to sync the kolab cache (SEARCH failed)" + ), true); + return false; + } - // delete duplicate entries from IMAP - $rem_index = array_intersect($del_index, $imap_index); - if (!empty($rem_index)) { - $this->imap_mode(true); - $this->imap->delete_message($rem_index, $this->folder->name); - $this->imap_mode(false); - } + // determine objects to fetch or to invalidate
View file
iRony-0.4.5.tar.gz/lib/plugins/libkolab/lib/kolab_storage_dataset.php -> iRony-0.4.6.tar.gz/lib/plugins/libkolab/lib/kolab_storage_dataset.php
Changed
@@ -150,5 +150,4 @@ { return !empty($this->index[$this->iteratorkey]); } - }
View file
iRony-0.4.5.tar.gz/lib/plugins/libkolab/lib/kolab_storage_folder.php -> iRony-0.4.6.tar.gz/lib/plugins/libkolab/lib/kolab_storage_folder.php
Changed
@@ -578,6 +578,8 @@ 'line' => __LINE__, 'message' => "Could not parse Kolab object data in message $msguid ($this->name)." . $msgadd, ), true); + + self::save_user_xml("$msguid.xml", $xml); } return false; @@ -1144,4 +1146,22 @@ return true; } + + /** + * Log content to a file in per_user_loggin dir if configured + */ + private static function save_user_xml($filename, $content) + { + $rcmail = rcube::get_instance(); + + if ($rcmail->config->get('kolab_format_error_log')) { + $log_dir = $rcmail->config->get('log_dir', RCUBE_INSTALL_PATH . 'logs'); + $user_name = $rcmail->get_user_name(); + $log_dir = $log_dir . '/' . $user_name; + + if (!empty($user_name) && is_writable($log_dir)) { + file_put_contents("$log_dir/$filename", $content); + } + } + } }
View file
iRony-0.4.5.tar.gz/lib/plugins/libkolab/libkolab.php -> iRony-0.4.6.tar.gz/lib/plugins/libkolab/libkolab.php
Changed
@@ -60,7 +60,7 @@ $this->add_texts('localization/', false); - if ($rcmail->output->type == 'html') { + if (!empty($rcmail->output->type) && $rcmail->output->type == 'html') { $rcmail->output->add_handler('libkolab.folder_search_form', array($this, 'folder_search_form')); $this->include_stylesheet($this->local_skin_path() . '/libkolab.css'); } @@ -93,7 +93,15 @@ */ function storage_init($p) { - $p['fetch_headers'] = trim($p['fetch_headers'] .' X-KOLAB-TYPE X-KOLAB-MIME-VERSION MESSAGE-ID'); + $kolab_headers = 'X-KOLAB-TYPE X-KOLAB-MIME-VERSION MESSAGE-ID'; + + if (!empty($p['fetch_headers'])) { + $p['fetch_headers'] .= ' ' . $kolab_headers; + } + else { + $p['fetch_headers'] = $kolab_headers; + } + return $p; }
View file
iRony-0.4.5.tar.gz/lib/plugins/libkolab/localization/ko_KR.inc -> iRony-0.4.6.tar.gz/lib/plugins/libkolab/localization/ko_KR.inc
Changed
@@ -7,3 +7,4 @@ * For translation see https://www.transifex.com/projects/p/kolab/resource/libkolab/ */ $labels['objectchangelog'] = '이력'; +$labels['tabsharing'] = '공우';
View file
iRony-0.4.5.tar.gz/lib/plugins/libkolab/skins/elastic/include/calendar.less -> iRony-0.4.6.tar.gz/lib/plugins/libkolab/skins/elastic/include/calendar.less
Changed
@@ -137,7 +137,7 @@ .event-row { white-space: nowrap; - .overflow-ellipsis; + .overflow-ellipsis(); &.current { color: #333; @@ -166,7 +166,8 @@ } #calendar.content { - overflow: hidden !important; // fullcalendar widget implements scrolling on its own + // fullcalendar widget implements scrolling on its own + overflow: hidden !important; position: relative; } @@ -567,7 +568,7 @@ @media screen and (min-width: (@screen-width-small + 1px)) and (max-width: 920px) { .fc-center { - .overflow-ellipsis; + .overflow-ellipsis(); flex: 1; h2 { @@ -715,7 +716,7 @@ span { display: block; - .overflow-ellipsis; + .overflow-ellipsis(); } } } @@ -729,7 +730,7 @@ } .event-location { - .overflow-ellipsis; + .overflow-ellipsis(); white-space: nowrap; } @@ -819,7 +820,7 @@ } &.loading:before { - .animated-icon-class; + .animated-icon-class(); content: @fa-var-circle-notch; display: block; line-height: 1; @@ -967,7 +968,7 @@ } &.loading:before { - .animated-icon-class; + .animated-icon-class(); .font-icon-solid(@fa-var-circle-notch); }
View file
iRony-0.4.6.tar.gz/lib/plugins/libkolab/skins/elastic/include/darkmode.less
Added
@@ -0,0 +1,168 @@ +/** + * Kolab core library + * + * This file contains Elastic skin dark mode styles for all Kolab plugins + * + * @author Aleksander Machniak <machniak@kolabsys.com> + * + * Copyright (C) 2012-2018, Kolab Systems AG <contact@kolabsys.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +html.dark-mode { + // Use icons-only on taskmenu with small screen height + @media screen and (max-height: 750px) and (min-width: (@screen-width-small + 1px)) { + #taskmenu a { + width: @layout-menu-width-sm - 1px; + } + } + + .watermark { + background-color: @color-dark-background; + background-blend-mode: soft-light; + + &:before { + background: none; + } + } + + #filelistcontainer, + .fc-scroller { + scrollbar-width: thin; + } + + .fc { + .fc-header-toolbar { + background-color: @color-dark-list-selected-background; + } + + #timezone-display, + .fc-center h2 { + color: @color-dark-font; + } + } + + .filelist tr.session.owner > td.name::after, + .rsvp-status:not(.accepted):not(.tentative):not(.declined)::before, + .resources-dialog .listing li.resource > a { + color: @color-dark-font; + } + + .fc-unthemed th, + .fc-unthemed td, + .fc-unthemed .fc-divider, + .fc-unthemed .fc-row, + .fc-unthemed .fc-content, + .fc-unthemed .fc-popover, + .fc-unthemed .fc-list-view, + .fc-unthemed .fc-list-heading td, + #tasklist li.taskitem > div, + #tasklist li.taskitem > span { + border-color: @color-dark-list-border; + } + + .files-dialog .selection-content, + .calendar-scheduler .schedule-table td.times td, + .calendar-scheduler .attendees-list div.attendee, + .calendar-scheduler .schedule-table .timesheader, + .calendar-scheduler .schedule-table td.attendees .attendees-list, + .fc-unthemed th, + .fc-unthemed td { + border-color: @color-dark-border; + } + + #resource-availability .fc, + #resource-availability .fc-view { + border-color: @color-dark-border; + } + + .selection-dialog .form-addon, + .selection-dialog .header, + .selection-dialog .selection-list, + .edit-attendees-table th { + border-color: @color-dark-border !important; + } + + .selection-dialog .listing ul, + .selection-dialog .form-addon, + .selection-dialog .header { + background-color: transparent; + } + + .fc-unthemed .fc-divider, + .fc-unthemed .fc-popover .fc-header, + .fc-unthemed .fc-list-heading td, + body.task-calendar .ui-datepicker-inline .ui-datepicker-activerange, + .listing li.selected > div > *, + #tasklist li.taskitem div.taskhead.selected { + color: @color-dark-list-selected; + background-color: @color-dark-list-selected-background; + } + + #folder-mount-form td.source.selected { + background-color: @color-dark-list-selected-background; + } + + #tagsform option, + .tagedit-list li.tagedit-listelement-new input { + color: @color-dark-input; + } + + .fc .fc-axis, + .fc .fc-day-number, + .fc .fc-week-number, + .fc .fc-day-header, + .fc .fc-week-header, + .formcontent.text-only .faded *, + .availability span, + .invitebox td.label, + .invitebox .rsvp-status.hint, + .calendar-agenda-preview .event-row.current, + #tasklist span.date, + #kolabnoteslist td.date, + #notedetailstitle .dates { + color: @color-dark-hint; + } + + .invitebox .folder-select select { + background-color: @color-dark-input-background; + } + + .tagedit-list[tabindex="-1"] { + border-color: @color-dark-input-border-focus; + box-shadow: 0 0 0 .2rem @color-input-border-focus-shadow; + background: @color-dark-input-background-focus; + } + + #tasklist .progressbar .progressvalue { + border-color: @color-dark-warning; + } + + .listing { + li > div.readonly a:first-child, + li.readonly:not(.virtual) > div a:first-child { + &:after { + color: @color-dark-font; + background-color: @color-dark-background; + } + } + } + + .dialog-message { + opacity: 1; + color: @color-dark-font; + background-color: @color-dark-warning; + } +}
View file
iRony-0.4.5.tar.gz/lib/plugins/libkolab/skins/elastic/include/kolab_activesync.less -> iRony-0.4.6.tar.gz/lib/plugins/libkolab/skins/elastic/include/kolab_activesync.less
Changed
@@ -37,7 +37,7 @@ } span { - .overflow-ellipsis; + .overflow-ellipsis(); } }
View file
iRony-0.4.5.tar.gz/lib/plugins/libkolab/skins/elastic/include/kolab_files.less -> iRony-0.4.6.tar.gz/lib/plugins/libkolab/skins/elastic/include/kolab_files.less
Changed
@@ -492,7 +492,7 @@ td,th { padding-left: .15rem; max-width: 10vw; // needed for overflow - .overflow-ellipsis; + .overflow-ellipsis(); &:last-child { padding-right: .15rem;
View file
iRony-0.4.5.tar.gz/lib/plugins/libkolab/skins/elastic/include/kolab_notes.less -> iRony-0.4.6.tar.gz/lib/plugins/libkolab/skins/elastic/include/kolab_notes.less
Changed
@@ -67,7 +67,7 @@ } td.title { - .overflow-ellipsis; + .overflow-ellipsis(); flex: 1; &:before { @@ -89,7 +89,7 @@ } & > a { - .overflow-ellipsis; + .overflow-ellipsis(); white-space: nowrap; display: block; text-decoration: none;
View file
iRony-0.4.5.tar.gz/lib/plugins/libkolab/skins/elastic/include/kolab_tags.less -> iRony-0.4.6.tar.gz/lib/plugins/libkolab/skins/elastic/include/kolab_tags.less
Changed
@@ -62,16 +62,9 @@ select { padding: 0; margin-bottom: .5rem; - - &:focus { - box-shadow: none !important; - border: 1px solid @color-layout-border; - } } option { - color: @color-font; // fix Firefox issue caused by text-shadow below - text-shadow: none; padding: .5rem; outline: 0; border: 0;
View file
iRony-0.4.5.tar.gz/lib/plugins/libkolab/skins/elastic/include/libcalendaring.less -> iRony-0.4.6.tar.gz/lib/plugins/libkolab/skins/elastic/include/libcalendaring.less
Changed
@@ -129,7 +129,7 @@ &.loading:before { &:extend(.font-icon-class); - .animated-icon-class; + .animated-icon-class(); content: @fa-var-circle-notch; line-height: 1; } @@ -279,7 +279,7 @@ display: flex; & > :first-child { - .overflow-ellipsis; + .overflow-ellipsis(); // width and flex is required to make overflow working flex: 1; width: 1px; @@ -357,7 +357,7 @@ input[type=button] { margin-left: .5em; - .overflow-ellipsis; + .overflow-ellipsis(); } } @@ -611,7 +611,7 @@ font-size: .9rem; color: @color-black-shade-text; white-space: nowrap; - .overflow-ellipsis; + .overflow-ellipsis(); } .alarm-actions { @@ -695,7 +695,7 @@ padding: .5rem .5rem .5rem .65rem; &:before { - .font-icon-class; + .font-icon-class(); margin: 0 1rem 0 0; width: 1em; line-height: 1.2;
View file
iRony-0.4.5.tar.gz/lib/plugins/libkolab/skins/elastic/include/tasklist.less -> iRony-0.4.6.tar.gz/lib/plugins/libkolab/skins/elastic/include/tasklist.less
Changed
@@ -160,7 +160,7 @@ padding: 0 0 0 .2em; padding-left: (1 * @listing-treetoggle-width + .25rem); margin-right: 2em; - .overflow-ellipsis; + .overflow-ellipsis(); } span.tags { @@ -350,7 +350,7 @@ } .taskitem-draghelper { - .overflow-ellipsis; + .overflow-ellipsis(); } .quickview-active { @@ -360,4 +360,3 @@ #rootdroppable { // TODO ? } -
View file
iRony-0.4.5.tar.gz/lib/plugins/libkolab/skins/elastic/libkolab.less -> iRony-0.4.6.tar.gz/lib/plugins/libkolab/skins/elastic/libkolab.less
Changed
@@ -24,6 +24,10 @@ @skin: "elastic"; @skin-path: "../../../../skins/@{skin}"; +// Disable dark mode support for compatibility with Roundcube 1.4. +// The variable has been added to variables.less in Roundcube 1.5. +@dark-mode-enabled: false; + @import (reference) "@{skin-path}/styles/variables"; @import (reference) "@{skin-path}/styles/mixins"; @@ -47,7 +51,7 @@ display: flex; & > a:first-child { - .overflow-ellipsis; + .overflow-ellipsis(); position: relative; flex-grow: 1; @@ -155,7 +159,7 @@ content: @fa-var-lock; position: absolute; left: 2.25rem; - top: @listing-line-height / 2; + top: (@listing-line-height / 2); font-size: .9em !important; width: .9em; line-height: 1; @@ -166,7 +170,7 @@ opacity: .9; html.touch & { - top: @listing-touch-line-height / 2; + top: (@listing-touch-line-height / 2); left: 2.7rem; } } @@ -219,7 +223,7 @@ right: 0; min-width: 2em; line-height: 1.4rem; - margin: (@listing-line-height - 1.4 * @page-font-size)/2; + margin: ((@listing-line-height - 1.4 * @page-font-size) / 2); padding: 0 .3em; border-radius: .4em; background: @color-list-secondary; @@ -229,7 +233,7 @@ html.touch & { line-height: 2rem; - margin: (@listing-touch-line-height - 2 * @page-font-size)/2; + margin: ((@listing-touch-line-height - 2 * @page-font-size) / 2); } } } @@ -429,7 +433,7 @@ } a.messagelink { - .overflow-ellipsis; + .overflow-ellipsis(); } a.delete .inner { @@ -589,7 +593,7 @@ } // Use icons-only on taskmenu with small screen height -@media screen and (max-height: 640px) and (min-width: (@screen-width-small + 1px)) { +@media screen and (max-height: 750px) and (min-width: (@screen-width-small + 1px)) { #layout-menu .popover-header img, #layout-menu { width: @layout-menu-width-sm; @@ -598,7 +602,7 @@ #taskmenu { a { height: @layout-menu-width-sm; - width: 100%; + width: @layout-menu-width-sm; font-size: 1.2rem !important; } @@ -620,3 +624,7 @@ @import "include/kolab_tags"; @import "include/libcalendaring"; @import "include/tasklist"; + +& when (@dark-mode-enabled = true) { + @import "include/darkmode"; +}
View file
iRony-0.4.5.tar.gz/lib/plugins/libkolab/tests/kolab_date_recurrence.php -> iRony-0.4.6.tar.gz/lib/plugins/libkolab/tests/kolab_date_recurrence.php
Changed
@@ -21,7 +21,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -class kolab_date_recurrence_test extends PHPUnit_Framework_TestCase +class kolab_date_recurrence_test extends PHPUnit\Framework\TestCase { function setUp() {
View file
iRony-0.4.5.tar.gz/lib/plugins/libkolab/tests/kolab_storage_config.php -> iRony-0.4.6.tar.gz/lib/plugins/libkolab/tests/kolab_storage_config.php
Changed
@@ -1,6 +1,6 @@ <?php -class kolab_storage_config_test extends PHPUnit_Framework_TestCase +class kolab_storage_config_test extends PHPUnit\Framework\TestCase { private $params_personal = array( 'folder' => 'Archive',
View file
iRony-0.4.5.tar.gz/lib/plugins/libkolab/tests/kolab_storage_folder.php -> iRony-0.4.6.tar.gz/lib/plugins/libkolab/tests/kolab_storage_folder.php
Changed
@@ -21,7 +21,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -class kolab_storage_folder_test extends PHPUnit_Framework_TestCase +class kolab_storage_folder_test extends PHPUnit\Framework\TestCase { public static function setUpBeforeClass() {
View file
iRony-0.4.5.tar.gz/lib/plugins/tasklist/composer.json -> iRony-0.4.6.tar.gz/lib/plugins/tasklist/composer.json
Changed
@@ -4,7 +4,7 @@ "description": "Task management plugin", "homepage": "https://git.kolab.org/diffusion/RPK/", "license": "AGPLv3", - "version": "3.5.4", + "version": "3.5.10", "authors": [ { "name": "Thomas Bruederli",
View file
iRony-0.4.5.tar.gz/lib/plugins/tasklist/drivers/database/SQL/mysql.initial.sql -> iRony-0.4.6.tar.gz/lib/plugins/tasklist/drivers/database/SQL/mysql.initial.sql
Changed
@@ -1,7 +1,6 @@ /** * Roundcube Tasklist plugin database * - * @version @package_version@ * @author Thomas Bruederli * @licence GNU AGPL * @copyright (C) 2012, Kolab Systems AG @@ -17,7 +16,7 @@ KEY `user_id` (`user_id`), CONSTRAINT `fk_tasklist_user_id` FOREIGN KEY (`user_id`) REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE -) /*!40000 ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci */; +) ROW_FORMAT=DYNAMIC ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE TABLE IF NOT EXISTS `tasks` ( `task_id` int(10) unsigned NOT NULL AUTO_INCREMENT, @@ -47,6 +46,6 @@ KEY `uid` (`uid`), CONSTRAINT `fk_tasks_tasklist_id` FOREIGN KEY (`tasklist_id`) REFERENCES `tasklists`(`tasklist_id`) ON DELETE CASCADE ON UPDATE CASCADE -) /*!40000 ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci */; +) ROW_FORMAT=DYNAMIC ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -REPLACE INTO `system` (`name`, `value`) VALUES ('tasklist-database-version', '2014051900'); +REPLACE INTO `system` (`name`, `value`) VALUES ('tasklist-database-version', '2021102600');
View file
iRony-0.4.6.tar.gz/lib/plugins/tasklist/drivers/database/SQL/mysql/2021102600.sql
Added
@@ -0,0 +1,14 @@ +-- changing table format and dropping foreign keys is needed for some versions of MySQL +ALTER TABLE `tasklists` DROP FOREIGN KEY `fk_tasklists_user_id`; +ALTER TABLE `tasks` DROP FOREIGN KEY`fk_tasks_tasklist_id`; + +ALTER TABLE `tasklists` ROW_FORMAT=DYNAMIC; +ALTER TABLE `tasks` ROW_FORMAT=DYNAMIC; + +ALTER TABLE `tasklists` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE `tasks` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +ALTER TABLE `tasklists` ADD CONSTRAINT `fk_tasklist_user_id` FOREIGN KEY (`user_id`) + REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE `tasks` ADD CONSTRAINT `fk_tasks_tasklist_id` FOREIGN KEY (`tasklist_id`) + REFERENCES `tasklists`(`tasklist_id`) ON DELETE CASCADE ON UPDATE CASCADE;
View file
iRony-0.4.5.tar.gz/lib/plugins/tasklist/drivers/database/SQL/postgres.initial.sql -> iRony-0.4.6.tar.gz/lib/plugins/tasklist/drivers/database/SQL/postgres.initial.sql
Changed
@@ -1,7 +1,6 @@ /** * Roundcube Tasklist plugin database * - * @version @package_version@ * @author Thomas Bruederli * @licence GNU AGPL * @copyright (C) 2014, Kolab Systems AG
View file
iRony-0.4.5.tar.gz/lib/plugins/tasklist/drivers/database/tasklist_database_driver.php -> iRony-0.4.6.tar.gz/lib/plugins/tasklist/drivers/database/tasklist_database_driver.php
Changed
@@ -118,8 +118,8 @@ . " VALUES (?, ?, ?, ?)", $this->rc->user->ID, strval($prop['name']), - strval($prop['color']), - $prop['showalarms'] ? 1 : 0 + isset($prop['color']) ? strval($prop['color']) : '', + !empty($prop['showalarms']) ? 1 : 0 ); if ($result) { @@ -143,8 +143,8 @@ "UPDATE " . $this->db_lists . " SET `name` = ?, `color` = ?, `showalarms` = ?" . " WHERE `tasklist_id` = ? AND `user_id` = ?", strval($prop['name']), - strval($prop['color']), - $prop['showalarms'] ? 1 : 0, + isset($prop['color']) ? strval($prop['color']) : '', + !empty($prop['showalarms']) ? 1 : 0, $prop['id'], $this->rc->user->ID ); @@ -163,7 +163,7 @@ { $hidden = array_flip(explode(',', $this->rc->config->get('hidden_tasklists', ''))); - if ($prop['active']) { + if (!empty($prop['active'])) { unset($hidden[$prop['id']]); } else { @@ -291,56 +291,53 @@ $sql_add = ''; // add filter criteria - if ($filter['from'] || ($filter['mask'] & tasklist::FILTER_MASK_TODAY)) { - $sql_add .= " AND (`date` IS NULL OR `date` >= ?)"; - $datefrom = $filter['from']; - } - if ($filter['to']) { - if ($filter['mask'] & tasklist::FILTER_MASK_OVERDUE) { - $sql_add .= " AND (`date` IS NOT NULL AND `date` <= " . $this->rc->db->quote($filter['to']) . ")"; - } - else { - $sql_add .= " AND (`date` IS NULL OR `date` <= " . $this->rc->db->quote($filter['to']) . ")"; + if ($filter) { + if (!empty($filter['from']) || ($filter['mask'] & tasklist::FILTER_MASK_TODAY)) { + $sql_add .= " AND (`date` IS NULL OR `date` >= " . $this->rc->db->quote($filter['from']) . ")"; } - } - // special case 'today': also show all events with date before today - if ($filter['mask'] & tasklist::FILTER_MASK_TODAY) { - $datefrom = date('Y-m-d', 0); - } + if (!empty($filter['to'])) { + if ($filter['mask'] & tasklist::FILTER_MASK_OVERDUE) { + $sql_add .= " AND (`date` IS NOT NULL AND `date` <= " . $this->rc->db->quote($filter['to']) . ")"; + } + else { + $sql_add .= " AND (`date` IS NULL OR `date` <= " . $this->rc->db->quote($filter['to']) . ")"; + } + } - if ($filter['mask'] & tasklist::FILTER_MASK_NODATE) { - $sql_add = " AND `date` IS NULL"; - } + if ($filter['mask'] & tasklist::FILTER_MASK_NODATE) { + $sql_add = " AND `date` IS NULL"; + } - if ($filter['mask'] & tasklist::FILTER_MASK_COMPLETE) { - $sql_add .= " AND " . self::IS_COMPLETE_SQL; - } - else if (empty($filter['since'])) { - // don't show complete tasks by default - $sql_add .= " AND NOT " . self::IS_COMPLETE_SQL; - } + if ($filter['mask'] & tasklist::FILTER_MASK_COMPLETE) { + $sql_add .= " AND " . self::IS_COMPLETE_SQL; + } + else if (empty($filter['since'])) { + // don't show complete tasks by default + $sql_add .= " AND NOT " . self::IS_COMPLETE_SQL; + } - if ($filter['mask'] & tasklist::FILTER_MASK_FLAGGED) { - $sql_add .= " AND `flagged` = 1"; - } + if ($filter['mask'] & tasklist::FILTER_MASK_FLAGGED) { + $sql_add .= " AND `flagged` = 1"; + } - // compose (slow) SQL query for searching - // FIXME: improve searching using a dedicated col and normalized values - if ($filter['search']) { - $sql_query = array(); - foreach (array('title', 'description', 'organizer', 'attendees') as $col) { - $sql_query[] = $this->rc->db->ilike($col, '%' . $filter['search'] . '%'); + // compose (slow) SQL query for searching + // FIXME: improve searching using a dedicated col and normalized values + if ($filter['search']) { + $sql_query = array(); + foreach (array('title', 'description', 'organizer', 'attendees') as $col) { + $sql_query[] = $this->rc->db->ilike($col, '%' . $filter['search'] . '%'); + } + $sql_add = " AND (" . join(" OR ", $sql_query) . ")"; } - $sql_add = " AND (" . join(" OR ", $sql_query) . ")"; - } - if ($filter['since'] && is_numeric($filter['since'])) { - $sql_add .= " AND `changed` >= " . $this->rc->db->quote(date('Y-m-d H:i:s', $filter['since'])); - } + if (!empty($filter['since']) && is_numeric($filter['since'])) { + $sql_add .= " AND `changed` >= " . $this->rc->db->quote(date('Y-m-d H:i:s', $filter['since'])); + } - if ($filter['uid']) { - $sql_add .= " AND `uid` IN (" . implode(',', array_map(array($this->rc->db, 'quote'), $filter['uid'])) . ")"; + if (!empty($filter['uid'])) { + $sql_add .= " AND `uid` IN (" . implode(',', array_map(array($this->rc->db, 'quote'), $filter['uid'])) . ")"; + } } $tasks = array(); @@ -348,8 +345,7 @@ $result = $this->rc->db->query("SELECT * FROM " . $this->db_tasks . " WHERE `tasklist_id` IN (" . join(',', $list_ids) . ")" . " AND `del` = 0" . $sql_add - . " ORDER BY `parent_id`, `task_id` ASC", - $datefrom + . " ORDER BY `parent_id`, `task_id` ASC" ); while ($result && ($rec = $this->rc->db->fetch_assoc($result))) { @@ -375,12 +371,12 @@ $prop['uid'] = $prop; } - $query_col = $prop['id'] ? 'task_id' : 'uid'; + $query_col = !empty($prop['id']) ? 'task_id' : 'uid'; $result = $this->rc->db->query("SELECT * FROM " . $this->db_tasks . " WHERE `tasklist_id` IN (" . $this->list_ids . ")" . " AND `$query_col` = ? AND `del` = 0", - $prop['id'] ? $prop['id'] : $prop['uid'] + !empty($prop['id']) ? $prop['id'] : $prop['uid'] ); if ($result && ($rec = $this->rc->db->fetch_assoc($result))) { @@ -557,22 +553,24 @@ public function create_task($prop) { // check list permissions - $list_id = $prop['list'] ? $prop['list'] : reset(array_keys($this->lists)); - if (!$this->lists[$list_id] || $this->lists[$list_id]['readonly']) { + $list_id = !empty($prop['list']) ? $prop['list'] : reset(array_keys($this->lists)); + if (empty($this->lists[$list_id]) || !empty($this->lists[$list_id]['readonly'])) { return false; } - if (is_array($prop['valarms'])) { + if (!empty($prop['valarms'])) { $prop['alarms'] = $this->serialize_alarms($prop['valarms']); } - if (is_array($prop['recurrence'])) { + + if (!empty($prop['recurrence'])) { $prop['recurrence'] = $this->serialize_recurrence($prop['recurrence']); } - if (array_key_exists('complete', $prop)) { + + if (array_key_exists('complete', $prop) && !empty($prop['complete'])) { $prop['complete'] = number_format($prop['complete'], 2, '.', ''); } - foreach (array('parent_id', 'date', 'time', 'startdate', 'starttime', 'alarms', 'recurrence', 'status') as $col) { + foreach (array('parent_id', 'date', 'time', 'startdate', 'starttime', 'alarms', 'recurrence', 'status', 'complete') as $col) { if (empty($prop[$col])) { $prop[$col] = null; } @@ -594,13 +592,13 @@ $prop['time'], $prop['startdate'], $prop['starttime'], - strval($prop['description']), - join(',', (array)$prop['tags']), - $prop['flagged'] ? 1 : 0, + isset($prop['description']) ? strval($prop['description']) : '', + !empty($prop['tags']) ? join(',', (array)$prop['tags']) : '', + !empty($prop['flagged']) ? 1 : 0, $prop['complete'] ?: 0, strval($prop['status']), - $prop['alarms'], - $prop['recurrence'], + isset($prop['alarms']) ? $prop['alarms'] : '', + isset($prop['recurrence']) ? $prop['recurrence'] : '', $notify_at );
View file
iRony-0.4.5.tar.gz/lib/plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php -> iRony-0.4.6.tar.gz/lib/plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php
Changed
@@ -1682,7 +1682,7 @@ if (strlen($folder_name)) { $path_imap = explode($delim, $folder_name); array_pop($path_imap); // pop off name part - $path_imap = implode($path_imap, $delim); + $path_imap = implode($delim, $path_imap); $options = $storage->folder_info($folder_name); }
View file
iRony-0.4.5.tar.gz/lib/plugins/tasklist/localization/ko_KR.inc -> iRony-0.4.6.tar.gz/lib/plugins/tasklist/localization/ko_KR.inc
Changed
@@ -26,13 +26,17 @@ $labels['all'] = '전체'; $labels['today'] = '오늘'; $labels['tomorrow'] = '내일'; +$labels['later'] = '이후에'; $labels['save'] = '저장'; $labels['cancel'] = '취소'; $labels['tabsummary'] = '요약'; $labels['tabrecurrence'] = '반복'; +$labels['tabattachments'] = '첨부'; +$labels['tabsharing'] = '공우'; $labels['listname'] = '이름'; $labels['showalarms'] = '알림 보이기'; $labels['savingdata'] = '자료 저장중...'; +$labels['role'] = '역할'; $labels['availability'] = '가능'; $labels['confirmstate'] = '상태'; $labels['roleorganizer'] = '주최자'; @@ -40,7 +44,10 @@ $labels['roleoptional'] = '선택'; $labels['rolechair'] = '좌석'; $labels['sendinvitations'] = '초대장 보내기'; +$labels['itipupdatesubject'] = '"$title" 이 변경되었습니다'; +$labels['itipcancelsubject'] = '"$title" 이 취소되었습니다'; $labels['taskhistory'] = '이력'; +$labels['objectchangelog'] = '이력 변경'; $labels['objectrestoreerror'] = '이전 버전으로 복구하지 못하였습니다'; $labels['andnmore'] = '$nr 더...'; $labels['comment'] = '코멘트';
View file
iRony-0.4.5.tar.gz/lib/plugins/tasklist/tasklist.js -> iRony-0.4.6.tar.gz/lib/plugins/tasklist/tasklist.js
Changed
@@ -1430,8 +1430,11 @@ ) .attr('tabindex', '0') .attr('aria-labelledby', label_id) - .data('id', rec.id) - .draggable({ + .data('id', rec.id); + + // Make the task draggable, but not in the Elastic skin on touch devices, to fix scrolling + if (!window.UI || !UI.is_touch || !window.UI.is_touch()) { + div.draggable({ revert: 'invalid', addClasses: false, cursorAt: { left:-10, top:12 }, @@ -1442,6 +1445,7 @@ drag: task_draggable_move, revertDuration: 300 }); + } if (window.kolab_tags_text_block) { var tags = rec.tags || [];
View file
iRony-0.4.5.tar.gz/lib/plugins/tasklist/tasklist.php -> iRony-0.4.6.tar.gz/lib/plugins/tasklist/tasklist.php
Changed
@@ -66,6 +66,7 @@ private $collapsed_tasks = array(); private $message_tasks = array(); + private $task_titles = array(); /** @@ -139,7 +140,7 @@ } // add 'Create event' item to message menu - if ($this->api->output->type == 'html' && $_GET['_rel'] != 'task') { + if ($this->api->output->type == 'html' && (empty($_GET['_rel']) || $_GET['_rel'] != 'task')) { $this->api->add_content(html::tag('li', array('role' => 'menuitem'), $this->api->output->button(array( 'command' => 'tasklist-create-from-mail', @@ -155,7 +156,7 @@ } } - if (!$this->rc->output->ajax_call && !$this->rc->output->env['framed']) { + if (!$this->rc->output->ajax_call && empty($this->rc->output->env['framed'])) { $this->load_ui(); $this->ui->init(); } @@ -181,7 +182,7 @@ */ private function load_driver() { - if (is_object($this->driver)) { + if (!empty($this->driver)) { return; } @@ -209,15 +210,16 @@ // force notify if hidden + active $itip_send_option = (int)$this->rc->config->get('calendar_itip_send_option', 3); - if ($itip_send_option === 1 && empty($rec['_reportpartstat'])) + if ($itip_send_option === 1 && empty($rec['_reportpartstat'])) { $rec['_notify'] = 1; + } switch ($action) { case 'new': $oldrec = null; $rec = $this->prepare_task($rec); $rec['uid'] = $this->generate_uid(); - $temp_id = $rec['tempid']; + $temp_id = !empty($rec['tempid']) ? $rec['tempid'] : null; if ($success = $this->driver->create_task($rec)) { $refresh = $this->driver->get_task($rec); if ($temp_id) $refresh['tempid'] = $temp_id; @@ -514,7 +516,7 @@ } // send out notifications - if ($success && $rec['_notify'] && ($rec['attendees'] || $oldrec['attendees'])) { + if ($success && !empty($rec['_notify']) && ($rec['attendees'] || $oldrec['attendees'])) { // make sure we have the complete record $task = $action == 'delete' ? $oldrec : $this->driver->get_task($rec); @@ -528,7 +530,7 @@ } } - if ($success && $rec['_reportpartstat'] && $rec['_reportpartstat'] != 'NEEDS-ACTION') { + if ($success && !empty($rec['_reportpartstat']) && $rec['_reportpartstat'] != 'NEEDS-ACTION') { // get the full record after update if (!$task) { $task = $this->driver->get_task($rec); @@ -556,7 +558,7 @@ $this->rc->output->command('plugin.unlock_saving', $success); if ($refresh) { - if ($refresh['id']) { + if (!empty($refresh['id'])) { $this->encode_task($refresh); } else if (is_array($refresh)) { @@ -575,8 +577,8 @@ */ private function load_itip() { - if (!$this->itip) { - require_once realpath(__DIR__ . '/../libcalendaring/lib/libcalendaring_itip.php'); + if (empty($this->itip)) { + require_once __DIR__ . '/../libcalendaring/lib/libcalendaring_itip.php'; $this->itip = new libcalendaring_itip($this, 'tasklist'); $this->itip->set_rsvp_actions(array('accepted','declined','delegated')); $this->itip->set_rsvp_status(array('accepted','tentative','declined','delegated','in-process','completed')); @@ -591,7 +593,7 @@ private function prepare_task($rec) { // try to be smart and extract date from raw input - if ($rec['raw']) { + if (!empty($rec['raw'])) { foreach (array('today','tomorrow','sunday','monday','tuesday','wednesday','thursday','friday','saturday','sun','mon','tue','wed','thu','fri','sat') as $word) { $locwords[] = '/^' . preg_quote(mb_strtolower($this->gettext($word))) . '\b/i'; $normwords[] = $word; @@ -675,7 +677,7 @@ } // convert the submitted alarm values - if ($rec['valarms']) { + if (!empty($rec['valarms'])) { $valarms = array(); foreach (libcalendaring::from_client_alarms($rec['valarms']) as $alarm) { // alarms can only work with a date (either task start, due or absolute alarm date) @@ -701,7 +703,7 @@ // translate count into an absolute end date. // why? because when shifting completed tasks to the next recurrence, // the initial start date to count from gets lost. - if ($rec['recurrence']['COUNT']) { + if (!empty($rec['recurrence']['COUNT'])) { $engine = libcalendaring::get_recurrence(); $engine->init($rec['recurrence'], $refdate); if ($until = $engine->end()) { @@ -717,7 +719,7 @@ $attachments = array(); $taskid = $rec['id']; - if (is_array($_SESSION[self::SESSION_KEY]) && $_SESSION[self::SESSION_KEY]['id'] == $taskid) { + if (!empty($_SESSION[self::SESSION_KEY]) && $_SESSION[self::SESSION_KEY]['id'] == $taskid) { if (!empty($_SESSION[self::SESSION_KEY]['attachments'])) { foreach ($_SESSION[self::SESSION_KEY]['attachments'] as $id => $attachment) { if (is_array($rec['attachments']) && in_array($id, $rec['attachments'])) { @@ -736,12 +738,15 @@ } // convert invalid data - if (isset($rec['attendees']) && !is_array($rec['attendees'])) + if (isset($rec['attendees']) && !is_array($rec['attendees'])) { $rec['attendees'] = array(); + } - foreach ((array)$rec['attendees'] as $i => $attendee) { - if (is_string($attendee['rsvp'])) { - $rec['attendees'][$i]['rsvp'] = $attendee['rsvp'] == 'true' || $attendee['rsvp'] == '1'; + if (!empty($rec['attendees'])) { + foreach ((array) $rec['attendees'] as $i => $attendee) { + if (is_string($attendee['rsvp'])) { + $rec['attendees'][$i]['rsvp'] = $attendee['rsvp'] == 'true' || $attendee['rsvp'] == '1'; + } } } @@ -1000,7 +1005,7 @@ $list += array('showalarms' => true, 'active' => true, 'editable' => true); if ($insert_id = $this->driver->create_list($list)) { $list['id'] = $insert_id; - if (!$list['_reload']) { + if (empty($list['_reload'])) { $this->load_ui(); $list['html'] = $this->ui->tasklist_list_item($insert_id, $list, $jsenv); $list += (array)$jsenv[$insert_id]; @@ -1048,7 +1053,7 @@ $results[] = $prop; } // report more results available - if ($this->driver->search_more_results) { + if (!empty($this->driver->search_more_results)) { $this->rc->output->show_message('autocompletemore', 'notice'); } @@ -1056,10 +1061,12 @@ return; } - if ($success) + if ($success) { $this->rc->output->show_message('successfullysaved', 'confirmation'); - else + } + else { $this->rc->output->show_message('tasklist.errorsaving', 'error'); + } $this->rc->output->command('plugin.unlock_saving'); } @@ -1074,8 +1081,9 @@ } else { foreach ($this->driver->get_lists() as $list) { - if ($list['active']) + if (!empty($list['active'])) { $lists[] = $list['id']; + } } } $counts = $this->driver->count_tasks($lists); @@ -1161,7 +1169,7 @@ $data = $this->task_tree = $this->task_titles = array(); foreach ($records as $rec) { - if ($rec['parent_id']) { + if (!empty($rec['parent_id'])) { $this->task_tree[$rec['id']] = $rec['parent_id']; }
View file
iRony-0.4.5.tar.gz/lib/plugins/tasklist/tasklist_ui.php -> iRony-0.4.6.tar.gz/lib/plugins/tasklist/tasklist_ui.php
Changed
@@ -83,8 +83,9 @@ // get user identity to create default attendee foreach ($this->rc->user->list_emails() as $rec) { - if (!$identity) + if (empty($identity)) { $identity = $rec; + } $identity['emails'][] = $rec['email']; $settings['identities'][$rec['identity_id']] = $rec['email']; @@ -184,14 +185,15 @@ $html = ''; foreach ((array)$lists as $id => $prop) { - if ($attrib['activeonly'] && !$prop['active']) - continue; + if (!empty($attrib['activeonly']) && empty($prop['active'])) { + continue; + } $html .= html::tag('li', array( 'id' => 'rcmlitasklist' . rcube_utils::html_identifier($id), - 'class' => $prop['group'], + 'class' => isset($prop['group']) ? $prop['group'] : null, ), - $this->tasklist_list_item($id, $prop, $jsenv, $attrib['activeonly']) + $this->tasklist_list_item($id, $prop, $jsenv, !empty($attrib['activeonly'])) ); } } @@ -241,7 +243,7 @@ public function tasklist_list_item($id, $prop, &$jsenv, $activeonly = false) { // enrich list properties with settings from the driver - if (!$prop['virtual']) { + if (empty($prop['virtual'])) { unset($prop['user_id']); $prop['alarms'] = $this->plugin->driver->alarms; $prop['undelete'] = $this->plugin->driver->undelete; @@ -253,17 +255,27 @@ } $classes = array('tasklist'); - $title = $prop['title'] ?: ($prop['name'] != $prop['listname'] || strlen($prop['name']) > 25 ? - html_entity_decode($prop['name'], ENT_COMPAT, RCUBE_CHARSET) : ''); + $title = ''; - if ($prop['virtual']) + if (!empty($prop['title'])) { + $title = $prop['title']; + } + else if (empty($prop['listname']) || $prop['name'] != $prop['listname'] || strlen($prop['name']) > 25) { + html_entity_decode($prop['name'], ENT_COMPAT, RCUBE_CHARSET); + } + + if (!empty($prop['virtual'])) { $classes[] = 'virtual'; - else if (!$prop['editable']) + } + else if (empty($prop['editable'])) { $classes[] = 'readonly'; - if ($prop['subscribed']) + } + if (!empty($prop['subscribed'])) { $classes[] = 'subscribed'; - if ($prop['class']) + } + if (!empty($prop['class'])) { $classes[] = $prop['class']; + } if (!$activeonly || $prop['active']) { $label_id = 'tl:' . $id; @@ -277,9 +289,10 @@ )); return html::div(join(' ', $classes), - html::a(array('class' => 'listname', 'title' => $title, 'href' => '#', 'id' => $label_id), $prop['listname'] ?: $prop['name']) . - ($prop['virtual'] ? '' : $chbox . html::span('actions', - ($prop['removable'] ? html::a(array('href' => '#', 'class' => 'remove', 'title' => $this->plugin->gettext('removelist')), ' ') : '') + html::a(array('class' => 'listname', 'title' => $title, 'href' => '#', 'id' => $label_id), + !empty($prop['listname']) ? $prop['listname'] : $prop['name']) . + (!empty($prop['virtual']) ? '' : $chbox . html::span('actions', + (!empty($prop['removable']) ? html::a(array('href' => '#', 'class' => 'remove', 'title' => $this->plugin->gettext('removelist')), ' ') : '') . html::a(array('href' => '#', 'class' => 'quickview', 'title' => $this->plugin->gettext('focusview'), 'role' => 'checkbox', 'aria-checked' => 'false'), ' ') . (isset($prop['subscribed']) ? html::a(array('href' => '#', 'class' => 'subscribed', 'title' => $this->plugin->gettext('tasklistsubscribe'), 'role' => 'checkbox', 'aria-checked' => $prop['subscribed'] ? 'true' : 'false'), ' ') : '') ) @@ -319,15 +332,18 @@ $select = new html_select($attrib); $default = null; - foreach ((array) $attrib['extra'] as $id => $name) { - $select->add($name, $id); + if (!empty($attrib['extra'])) { + foreach ((array) $attrib['extra'] as $id => $name) { + $select->add($name, $id); + } } - foreach ((array)$this->plugin->driver->get_lists() as $id => $prop) { - if ($prop['editable'] || strpos($prop['rights'], 'i') !== false) { + foreach ((array) $this->plugin->driver->get_lists() as $id => $prop) { + if (!empty($prop['editable']) || strpos($prop['rights'], 'i') !== false) { $select->add($prop['name'], $id); - if (!$default || $prop['default']) + if (!$default || !empty($prop['default'])) { $default = $id; + } } } @@ -421,7 +437,12 @@ $attrib += array('id' => 'rcmtasktagsedit'); $this->register_gui_object('edittagline', $attrib['id']); - $input = new html_inputfield(array('name' => 'tags[]', 'class' => 'tag', 'size' => $attrib['size'], 'tabindex' => $attrib['tabindex'])); + $input = new html_inputfield(array( + 'name' => 'tags[]', + 'class' => 'tag', + 'size' => !empty($attrib['size']) ? $attrib['size'] : null, + 'tabindex' => isset($attrib['tabindex']) ? $attrib['tabindex'] : null, + )); unset($attrib['tabindex']); return html::div($attrib, $input->show('')); } @@ -461,9 +482,21 @@ */ function attendees_form($attrib = array()) { - $input = new html_inputfield(array('name' => 'participant', 'id' => 'edit-attendee-name', 'size' => $attrib['size'], 'class' => 'form-control')); - $textarea = new html_textarea(array('name' => 'comment', 'id' => 'edit-attendees-comment', - 'rows' => 4, 'cols' => 55, 'title' => $this->plugin->gettext('itipcommenttitle'), 'class' => 'form-control')); + $input = new html_inputfield(array( + 'name' => 'participant', + 'id' => 'edit-attendee-name', + 'size' => !empty($attrib['size']) ? $attrib['size'] : null, + 'class' => 'form-control' + )); + + $textarea = new html_textarea(array( + 'name' => 'comment', + 'id' => 'edit-attendees-comment', + 'rows' => 4, + 'cols' => 55, + 'title' => $this->plugin->gettext('itipcommenttitle'), + 'class' => 'form-control' + )); return html::div($attrib, html::div('form-searchbar', $input->show() . " " . @@ -488,7 +521,7 @@ */ function tasks_import_form($attrib = array()) { - if (!$attrib['id']) { + if (empty($attrib['id'])) { $attrib['id'] = 'rcmImportForm'; } @@ -503,7 +536,7 @@ 'id' => 'importfile', 'type' => 'file', 'name' => '_data', - 'size' => $attrib['uploadfieldsize'], + 'size' => !empty($attrib['uploadfieldsize']) ? $attrib['uploadfieldsize'] : null, 'accept' => $accept )); @@ -537,11 +570,11 @@ */ function tasks_export_form($attrib = array()) { - if (!$attrib['id']) { + if (empty($attrib['id'])) { $attrib['id'] = 'rcmTaskExportForm'; } - $html .= html::div('form-section form-group row', + $html = html::div('form-section form-group row', html::label(array('for' => 'task-export-list', 'class' => 'col-sm-4 col-form-label'), $this->plugin->gettext('list')) . html::div('col-sm-8', $this->tasklist_select(array( 'name' => 'source',
View file
iRony-0.4.5.tar.gz/vendor/autoload.php -> iRony-0.4.6.tar.gz/vendor/autoload.php
Changed
@@ -4,4 +4,4 @@ require_once __DIR__ . '/composer/autoload_real.php'; -return ComposerAutoloaderInitef3ffbf0545085bdea11201abb358b1d::getLoader(); +return ComposerAutoloaderInitc5e5a57e810b5438e3f904fba572f99b::getLoader();
View file
iRony-0.4.5.tar.gz/vendor/bin/generate_vcards -> iRony-0.4.6.tar.gz/vendor/bin/generate_vcards
Changed
-(symlink to ../sabre/vobject/bin/generate_vcards) @@ -0,0 +1,107 @@ +#!/usr/bin/env php +<?php + +/** + * Proxy PHP file generated by Composer + * + * This file includes the referenced bin path (../sabre/vobject/bin/generate_vcards) + * using a stream wrapper to prevent the shebang from being output on PHP<8 + * + * @generated + */ + +namespace Composer; + +$GLOBALS['_composer_bin_dir'] = __DIR__; +$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..'.'/autoload.php'; + +if (PHP_VERSION_ID < 80000) { + if (!class_exists('Composer\BinProxyWrapper')) { + /** + * @internal + */ + final class BinProxyWrapper + { + private $handle; + private $position; + private $realpath; + + public function stream_open($path, $mode, $options, &$opened_path) + { + // get rid of phpvfscomposer:// prefix for __FILE__ & __DIR__ resolution + $opened_path = substr($path, 17); + $this->realpath = realpath($opened_path) ?: $opened_path; + $opened_path = $this->realpath; + $this->handle = fopen($this->realpath, $mode); + $this->position = 0; + + return (bool) $this->handle; + } + + public function stream_read($count) + { + $data = fread($this->handle, $count); + + if ($this->position === 0) { + $data = preg_replace('{^#!.*\r?\n}', '', $data); + } + + $this->position += strlen($data); + + return $data; + } + + public function stream_cast($castAs) + { + return $this->handle; + } + + public function stream_close() + { + fclose($this->handle); + } + + public function stream_lock($operation) + { + return $operation ? flock($this->handle, $operation) : true; + } + + public function stream_tell() + { + return $this->position; + } + + public function stream_eof() + { + return feof($this->handle); + } + + public function stream_stat() + { + return array(); + } + + public function stream_set_option($option, $arg1, $arg2) + { + return true; + } + + public function url_stat($path, $flags) + { + $path = substr($path, 17); + if (file_exists($path)) { + return stat($path); + } + + return false; + } + } + } + + if (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) { + include("phpvfscomposer://" . __DIR__ . '/..'.'/sabre/vobject/bin/generate_vcards'); + exit(0); + } +} + +include __DIR__ . '/..'.'/sabre/vobject/bin/generate_vcards';
View file
iRony-0.4.5.tar.gz/vendor/bin/naturalselection -> iRony-0.4.6.tar.gz/vendor/bin/naturalselection
Changed
-(symlink to ../sabre/dav/bin/naturalselection) @@ -0,0 +1,37 @@ +#!/usr/bin/env sh + +# Support bash to support `source` with fallback on $0 if this does not run with bash +# https://stackoverflow.com/a/35006505/6512 +selfArg="$BASH_SOURCE" +if [ -z "$selfArg" ]; then + selfArg="$0" +fi + +self=$(realpath $selfArg 2> /dev/null) +if [ -z "$self" ]; then + self="$selfArg" +fi + +dir=$(cd "${self%[/\\]*}" > /dev/null; cd '../sabre/dav/bin' && pwd) + +if [ -d /proc/cygdrive ]; then + case $(which php) in + $(readlink -n /proc/cygdrive)/*) + # We are in Cygwin using Windows php, so the path must be translated + dir=$(cygpath -m "$dir"); + ;; + esac +fi + +export COMPOSER_BIN_DIR=$(cd "${self%[/\\]*}" > /dev/null; pwd) + +# If bash is sourcing this file, we have to source the target as well +bashSource="$BASH_SOURCE" +if [ -n "$bashSource" ]; then + if [ "$bashSource" != "$0" ]; then + source "${dir}/naturalselection" "$@" + return + fi +fi + +"${dir}/naturalselection" "$@"
View file
iRony-0.4.5.tar.gz/vendor/bin/sabredav -> iRony-0.4.6.tar.gz/vendor/bin/sabredav
Changed
-(symlink to ../sabre/dav/bin/sabredav) @@ -0,0 +1,37 @@ +#!/usr/bin/env sh + +# Support bash to support `source` with fallback on $0 if this does not run with bash +# https://stackoverflow.com/a/35006505/6512 +selfArg="$BASH_SOURCE" +if [ -z "$selfArg" ]; then + selfArg="$0" +fi + +self=$(realpath $selfArg 2> /dev/null) +if [ -z "$self" ]; then + self="$selfArg" +fi + +dir=$(cd "${self%[/\\]*}" > /dev/null; cd '../sabre/dav/bin' && pwd) + +if [ -d /proc/cygdrive ]; then + case $(which php) in + $(readlink -n /proc/cygdrive)/*) + # We are in Cygwin using Windows php, so the path must be translated + dir=$(cygpath -m "$dir"); + ;; + esac +fi + +export COMPOSER_BIN_DIR=$(cd "${self%[/\\]*}" > /dev/null; pwd) + +# If bash is sourcing this file, we have to source the target as well +bashSource="$BASH_SOURCE" +if [ -n "$bashSource" ]; then + if [ "$bashSource" != "$0" ]; then + source "${dir}/sabredav" "$@" + return + fi +fi + +"${dir}/sabredav" "$@"
View file
iRony-0.4.5.tar.gz/vendor/bin/vobject -> iRony-0.4.6.tar.gz/vendor/bin/vobject
Changed
-(symlink to ../sabre/vobject/bin/vobject) @@ -0,0 +1,107 @@ +#!/usr/bin/env php +<?php + +/** + * Proxy PHP file generated by Composer + * + * This file includes the referenced bin path (../sabre/vobject/bin/vobject) + * using a stream wrapper to prevent the shebang from being output on PHP<8 + * + * @generated + */ + +namespace Composer; + +$GLOBALS['_composer_bin_dir'] = __DIR__; +$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..'.'/autoload.php'; + +if (PHP_VERSION_ID < 80000) { + if (!class_exists('Composer\BinProxyWrapper')) { + /** + * @internal + */ + final class BinProxyWrapper + { + private $handle; + private $position; + private $realpath; + + public function stream_open($path, $mode, $options, &$opened_path) + { + // get rid of phpvfscomposer:// prefix for __FILE__ & __DIR__ resolution + $opened_path = substr($path, 17); + $this->realpath = realpath($opened_path) ?: $opened_path; + $opened_path = $this->realpath; + $this->handle = fopen($this->realpath, $mode); + $this->position = 0; + + return (bool) $this->handle; + } + + public function stream_read($count) + { + $data = fread($this->handle, $count); + + if ($this->position === 0) { + $data = preg_replace('{^#!.*\r?\n}', '', $data); + } + + $this->position += strlen($data); + + return $data; + } + + public function stream_cast($castAs) + { + return $this->handle; + } + + public function stream_close() + { + fclose($this->handle); + } + + public function stream_lock($operation) + { + return $operation ? flock($this->handle, $operation) : true; + } + + public function stream_tell() + { + return $this->position; + } + + public function stream_eof() + { + return feof($this->handle); + } + + public function stream_stat() + { + return array(); + } + + public function stream_set_option($option, $arg1, $arg2) + { + return true; + } + + public function url_stat($path, $flags) + { + $path = substr($path, 17); + if (file_exists($path)) { + return stat($path); + } + + return false; + } + } + } + + if (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) { + include("phpvfscomposer://" . __DIR__ . '/..'.'/sabre/vobject/bin/vobject'); + exit(0); + } +} + +include __DIR__ . '/..'.'/sabre/vobject/bin/vobject';
View file
iRony-0.4.5.tar.gz/vendor/composer/ClassLoader.php -> iRony-0.4.6.tar.gz/vendor/composer/ClassLoader.php
Changed
@@ -37,26 +37,80 @@ * * @author Fabien Potencier <fabien@symfony.com> * @author Jordi Boggiano <j.boggiano@seld.be> - * @see http://www.php-fig.org/psr/psr-0/ - * @see http://www.php-fig.org/psr/psr-4/ + * @see https://www.php-fig.org/psr/psr-0/ + * @see https://www.php-fig.org/psr/psr-4/ */ class ClassLoader { + /** @var ?string */ + private $vendorDir; + // PSR-4 + /** + * @var array[] + * @psalm-var array<string, array<string, int>> + */ private $prefixLengthsPsr4 = array(); + /** + * @var array[] + * @psalm-var array<string, array<int, string>> + */ private $prefixDirsPsr4 = array(); + /** + * @var array[] + * @psalm-var array<string, string> + */ private $fallbackDirsPsr4 = array(); // PSR-0 + /** + * @var array[] + * @psalm-var array<string, array<string, string[]>> + */ private $prefixesPsr0 = array(); + /** + * @var array[] + * @psalm-var array<string, string> + */ private $fallbackDirsPsr0 = array(); + /** @var bool */ private $useIncludePath = false; + + /** + * @var string[] + * @psalm-var array<string, string> + */ private $classMap = array(); + + /** @var bool */ private $classMapAuthoritative = false; + + /** + * @var bool[] + * @psalm-var array<string, bool> + */ private $missingClasses = array(); + + /** @var ?string */ private $apcuPrefix; + /** + * @var self[] + */ + private static $registeredLoaders = array(); + + /** + * @param ?string $vendorDir + */ + public function __construct($vendorDir = null) + { + $this->vendorDir = $vendorDir; + } + + /** + * @return string[] + */ public function getPrefixes() { if (!empty($this->prefixesPsr0)) { @@ -66,28 +120,47 @@ return array(); } + /** + * @return array[] + * @psalm-return array<string, array<int, string>> + */ public function getPrefixesPsr4() { return $this->prefixDirsPsr4; } + /** + * @return array[] + * @psalm-return array<string, string> + */ public function getFallbackDirs() { return $this->fallbackDirsPsr0; } + /** + * @return array[] + * @psalm-return array<string, string> + */ public function getFallbackDirsPsr4() { return $this->fallbackDirsPsr4; } + /** + * @return string[] Array of classname => path + * @psalm-return array<string, string> + */ public function getClassMap() { return $this->classMap; } /** - * @param array $classMap Class to filename map + * @param string[] $classMap Class to filename map + * @psalm-param array<string, string> $classMap + * + * @return void */ public function addClassMap(array $classMap) { @@ -102,9 +175,11 @@ * Registers a set of PSR-0 directories for a given prefix, either * appending or prepending to the ones previously set for this prefix. * - * @param string $prefix The prefix - * @param array|string $paths The PSR-0 root directories - * @param bool $prepend Whether to prepend the directories + * @param string $prefix The prefix + * @param string[]|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories + * + * @return void */ public function add($prefix, $paths, $prepend = false) { @@ -147,11 +222,13 @@ * Registers a set of PSR-4 directories for a given namespace, either * appending or prepending to the ones previously set for this namespace. * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param array|string $paths The PSR-4 base directories - * @param bool $prepend Whether to prepend the directories + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param string[]|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories * * @throws \InvalidArgumentException + * + * @return void */ public function addPsr4($prefix, $paths, $prepend = false) { @@ -195,8 +272,10 @@ * Registers a set of PSR-0 directories for a given prefix, * replacing any others previously set for this prefix. * - * @param string $prefix The prefix - * @param array|string $paths The PSR-0 base directories + * @param string $prefix The prefix + * @param string[]|string $paths The PSR-0 base directories + * + * @return void */ public function set($prefix, $paths) { @@ -211,10 +290,12 @@ * Registers a set of PSR-4 directories for a given namespace, * replacing any others previously set for this namespace. * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param array|string $paths The PSR-4 base directories + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param string[]|string $paths The PSR-4 base directories * * @throws \InvalidArgumentException + * + * @return void */ public function setPsr4($prefix, $paths) { @@ -234,6 +315,8 @@ * Turns on searching the include path for class files. * * @param bool $useIncludePath + * + * @return void */ public function setUseIncludePath($useIncludePath)
View file
iRony-0.4.6.tar.gz/vendor/composer/InstalledVersions.php
Added
@@ -0,0 +1,350 @@ +<?php + +/* + * This file is part of Composer. + * + * (c) Nils Adermann <naderman@naderman.de> + * Jordi Boggiano <j.boggiano@seld.be> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer; + +use Composer\Autoload\ClassLoader; +use Composer\Semver\VersionParser; + +/** + * This class is copied in every Composer installed project and available to all + * + * See also https://getcomposer.org/doc/07-runtime.md#installed-versions + * + * To require its presence, you can require `composer-runtime-api ^2.0` + */ +class InstalledVersions +{ + /** + * @var mixed[]|null + * @psalm-var array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}|array{}|null + */ + private static $installed; + + /** + * @var bool|null + */ + private static $canGetVendors; + + /** + * @var array[] + * @psalm-var array<string, array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}> + */ + private static $installedByVendor = array(); + + /** + * Returns a list of all package names which are present, either by being installed, replaced or provided + * + * @return string[] + * @psalm-return list<string> + */ + public static function getInstalledPackages() + { + $packages = array(); + foreach (self::getInstalled() as $installed) { + $packages[] = array_keys($installed['versions']); + } + + if (1 === \count($packages)) { + return $packages[0]; + } + + return array_keys(array_flip(\call_user_func_array('array_merge', $packages))); + } + + /** + * Returns a list of all package names with a specific type e.g. 'library' + * + * @param string $type + * @return string[] + * @psalm-return list<string> + */ + public static function getInstalledPackagesByType($type) + { + $packagesByType = array(); + + foreach (self::getInstalled() as $installed) { + foreach ($installed['versions'] as $name => $package) { + if (isset($package['type']) && $package['type'] === $type) { + $packagesByType[] = $name; + } + } + } + + return $packagesByType; + } + + /** + * Checks whether the given package is installed + * + * This also returns true if the package name is provided or replaced by another package + * + * @param string $packageName + * @param bool $includeDevRequirements + * @return bool + */ + public static function isInstalled($packageName, $includeDevRequirements = true) + { + foreach (self::getInstalled() as $installed) { + if (isset($installed['versions'][$packageName])) { + return $includeDevRequirements || empty($installed['versions'][$packageName]['dev_requirement']); + } + } + + return false; + } + + /** + * Checks whether the given package satisfies a version constraint + * + * e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call: + * + * Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3') + * + * @param VersionParser $parser Install composer/semver to have access to this class and functionality + * @param string $packageName + * @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package + * @return bool + */ + public static function satisfies(VersionParser $parser, $packageName, $constraint) + { + $constraint = $parser->parseConstraints($constraint); + $provided = $parser->parseConstraints(self::getVersionRanges($packageName)); + + return $provided->matches($constraint); + } + + /** + * Returns a version constraint representing all the range(s) which are installed for a given package + * + * It is easier to use this via isInstalled() with the $constraint argument if you need to check + * whether a given version of a package is installed, and not just whether it exists + * + * @param string $packageName + * @return string Version constraint usable with composer/semver + */ + public static function getVersionRanges($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + $ranges = array(); + if (isset($installed['versions'][$packageName]['pretty_version'])) { + $ranges[] = $installed['versions'][$packageName]['pretty_version']; + } + if (array_key_exists('aliases', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']); + } + if (array_key_exists('replaced', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']); + } + if (array_key_exists('provided', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']); + } + + return implode(' || ', $ranges); + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present + */ + public static function getVersion($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['version'])) { + return null; + } + + return $installed['versions'][$packageName]['version']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present + */ + public static function getPrettyVersion($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['pretty_version'])) { + return null; + } + + return $installed['versions'][$packageName]['pretty_version']; + }
View file
iRony-0.4.5.tar.gz/vendor/composer/autoload_classmap.php -> iRony-0.4.6.tar.gz/vendor/composer/autoload_classmap.php
Changed
@@ -6,4 +6,5 @@ $baseDir = dirname($vendorDir); return array( + 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php', );
View file
iRony-0.4.5.tar.gz/vendor/composer/autoload_real.php -> iRony-0.4.6.tar.gz/vendor/composer/autoload_real.php
Changed
@@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInitef3ffbf0545085bdea11201abb358b1d +class ComposerAutoloaderInitc5e5a57e810b5438e3f904fba572f99b { private static $loader; @@ -22,15 +22,17 @@ return self::$loader; } - spl_autoload_register(array('ComposerAutoloaderInitef3ffbf0545085bdea11201abb358b1d', 'loadClassLoader'), true, true); - self::$loader = $loader = new \Composer\Autoload\ClassLoader(); - spl_autoload_unregister(array('ComposerAutoloaderInitef3ffbf0545085bdea11201abb358b1d', 'loadClassLoader')); + require __DIR__ . '/platform_check.php'; + + spl_autoload_register(array('ComposerAutoloaderInitc5e5a57e810b5438e3f904fba572f99b', 'loadClassLoader'), true, true); + self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__))); + spl_autoload_unregister(array('ComposerAutoloaderInitc5e5a57e810b5438e3f904fba572f99b', 'loadClassLoader')); $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); if ($useStaticLoader) { - require_once __DIR__ . '/autoload_static.php'; + require __DIR__ . '/autoload_static.php'; - call_user_func(\Composer\Autoload\ComposerStaticInitef3ffbf0545085bdea11201abb358b1d::getInitializer($loader)); + call_user_func(\Composer\Autoload\ComposerStaticInitc5e5a57e810b5438e3f904fba572f99b::getInitializer($loader)); } else { $map = require __DIR__ . '/autoload_namespaces.php'; foreach ($map as $namespace => $path) {
View file
iRony-0.4.5.tar.gz/vendor/composer/autoload_static.php -> iRony-0.4.6.tar.gz/vendor/composer/autoload_static.php
Changed
@@ -4,7 +4,7 @@ namespace Composer\Autoload; -class ComposerStaticInitef3ffbf0545085bdea11201abb358b1d +class ComposerStaticInitc5e5a57e810b5438e3f904fba572f99b { public static $prefixLengthsPsr4 = array ( 'S' => @@ -50,11 +50,16 @@ ), ); + public static $classMap = array ( + 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', + ); + public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInitef3ffbf0545085bdea11201abb358b1d::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInitef3ffbf0545085bdea11201abb358b1d::$prefixDirsPsr4; + $loader->prefixLengthsPsr4 = ComposerStaticInitc5e5a57e810b5438e3f904fba572f99b::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInitc5e5a57e810b5438e3f904fba572f99b::$prefixDirsPsr4; + $loader->classMap = ComposerStaticInitc5e5a57e810b5438e3f904fba572f99b::$classMap; }, null, ClassLoader::class); }
View file
iRony-0.4.5.tar.gz/vendor/composer/installed.json -> iRony-0.4.6.tar.gz/vendor/composer/installed.json
Changed
@@ -1,252 +1,280 @@ -[ - { - "name": "sabre/dav", - "version": "2.1.11", - "version_normalized": "2.1.11.0", - "source": { - "type": "git", - "url": "https://github.com/sabre-io/dav.git", - "reference": "fa10928802aea9b3136519640aa3c3c59e9e1084" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sabre-io/dav/zipball/fa10928802aea9b3136519640aa3c3c59e9e1084", - "reference": "fa10928802aea9b3136519640aa3c3c59e9e1084", - "shasum": "" - }, - "require": { - "ext-ctype": "*", - "ext-date": "*", - "ext-dom": "*", - "ext-iconv": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-pcre": "*", - "ext-simplexml": "*", - "ext-spl": "*", - "php": ">=5.4.1", - "sabre/event": "^2.0.0", - "sabre/http": "^3.0.0", - "sabre/vobject": "^3.3.4" - }, - "require-dev": { - "evert/phpdoc-md": "~0.1.0", - "phpunit/phpunit": "~4.2", - "squizlabs/php_codesniffer": "~1.5.3" - }, - "suggest": { - "ext-curl": "*", - "ext-pdo": "*" - }, - "time": "2016-10-07T03:29:06+00:00", - "bin": [ - "bin/sabredav", - "bin/naturalselection" - ], - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "Sabre\\DAV\\": "lib/DAV/", - "Sabre\\DAVACL\\": "lib/DAVACL/", - "Sabre\\CalDAV\\": "lib/CalDAV/", - "Sabre\\CardDAV\\": "lib/CardDAV/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Evert Pot", - "email": "me@evertpot.com", - "homepage": "http://evertpot.com/", - "role": "Developer" - } - ], - "description": "WebDAV Framework for PHP", - "homepage": "http://sabre.io/", - "keywords": [ - "CalDAV", - "CardDAV", - "WebDAV", - "framework", - "iCalendar" - ] - }, - { - "name": "sabre/event", - "version": "2.0.2", - "version_normalized": "2.0.2.0", - "source": { - "type": "git", - "url": "https://github.com/sabre-io/event.git", - "reference": "337b6f5e10ea6e0b21e22c7e5788dd3883ae73ff" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sabre-io/event/zipball/337b6f5e10ea6e0b21e22c7e5788dd3883ae73ff", - "reference": "337b6f5e10ea6e0b21e22c7e5788dd3883ae73ff", - "shasum": "" - }, - "require": { - "php": ">=5.4.1" - }, - "require-dev": { - "phpunit/phpunit": "*", - "sabre/cs": "~0.0.1" - }, - "time": "2015-05-19T10:24:22+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "Sabre\\Event\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Evert Pot", - "email": "me@evertpot.com", - "homepage": "http://evertpot.com/", - "role": "Developer" - } - ], - "description": "sabre/event is a library for lightweight event-based programming", - "homepage": "http://sabre.io/event/", - "keywords": [ - "EventEmitter", - "events", - "hooks", - "plugin", - "promise", - "signal" - ] - }, - { - "name": "sabre/http", - "version": "3.0.5", - "version_normalized": "3.0.5.0", - "source": { - "type": "git", - "url": "https://github.com/sabre-io/http.git", - "reference": "6b06c03376219b3d608e1f878514ec105ed1b577" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sabre-io/http/zipball/6b06c03376219b3d608e1f878514ec105ed1b577", - "reference": "6b06c03376219b3d608e1f878514ec105ed1b577", - "shasum": "" - }, - "require": { - "ext-mbstring": "*", - "php": ">=5.4", - "sabre/event": ">=1.0.0,<3.0.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.3", - "squizlabs/php_codesniffer": "~1.5.3" - }, - "suggest": { - "ext-curl": " to make http requests with the Client class" - }, - "time": "2015-05-11T15:25:57+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "Sabre\\HTTP\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Evert Pot", - "email": "me@evertpot.com", - "homepage": "http://evertpot.com/", - "role": "Developer" - } - ], - "description": "The sabre/http library provides utilities for dealing with http requests and responses. ", - "homepage": "https://github.com/fruux/sabre-http", - "keywords": [ - "http" - ] - }, - { - "name": "sabre/vobject", - "version": "3.5.3", - "version_normalized": "3.5.3.0", - "source": { - "type": "git", - "url": "https://github.com/sabre-io/vobject.git", - "reference": "129d80533a9ec0d9cacfb50b51180c34edb6874c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sabre-io/vobject/zipball/129d80533a9ec0d9cacfb50b51180c34edb6874c", - "reference": "129d80533a9ec0d9cacfb50b51180c34edb6874c", - "shasum": "" - }, - "require": {
View file
iRony-0.4.6.tar.gz/vendor/composer/installed.php
Added
@@ -0,0 +1,59 @@ +<?php return array( + 'root' => array( + 'pretty_version' => '0.4-dev', + 'version' => '0.4.0.0-dev', + 'type' => 'library', + 'install_path' => __DIR__ . '/../../', + 'aliases' => array(), + 'reference' => NULL, + 'name' => 'kolab/irony', + 'dev' => false, + ), + 'versions' => array( + 'kolab/irony' => array( + 'pretty_version' => '0.4-dev', + 'version' => '0.4.0.0-dev', + 'type' => 'library', + 'install_path' => __DIR__ . '/../../', + 'aliases' => array(), + 'reference' => NULL, + 'dev_requirement' => false, + ), + 'sabre/dav' => array( + 'pretty_version' => '2.1.11', + 'version' => '2.1.11.0', + 'type' => 'library', + 'install_path' => __DIR__ . '/../sabre/dav', + 'aliases' => array(), + 'reference' => 'fa10928802aea9b3136519640aa3c3c59e9e1084', + 'dev_requirement' => false, + ), + 'sabre/event' => array( + 'pretty_version' => '2.0.2', + 'version' => '2.0.2.0', + 'type' => 'library', + 'install_path' => __DIR__ . '/../sabre/event', + 'aliases' => array(), + 'reference' => '337b6f5e10ea6e0b21e22c7e5788dd3883ae73ff', + 'dev_requirement' => false, + ), + 'sabre/http' => array( + 'pretty_version' => '3.0.5', + 'version' => '3.0.5.0', + 'type' => 'library', + 'install_path' => __DIR__ . '/../sabre/http', + 'aliases' => array(), + 'reference' => '6b06c03376219b3d608e1f878514ec105ed1b577', + 'dev_requirement' => false, + ), + 'sabre/vobject' => array( + 'pretty_version' => '3.5.3', + 'version' => '3.5.3.0', + 'type' => 'library', + 'install_path' => __DIR__ . '/../sabre/vobject', + 'aliases' => array(), + 'reference' => '129d80533a9ec0d9cacfb50b51180c34edb6874c', + 'dev_requirement' => false, + ), + ), +);
View file
iRony-0.4.6.tar.gz/vendor/composer/platform_check.php
Added
@@ -0,0 +1,26 @@ +<?php + +// platform_check.php @generated by Composer + +$issues = array(); + +if (!(PHP_VERSION_ID >= 50401)) { + $issues[] = 'Your Composer dependencies require a PHP version ">= 5.4.1". You are running ' . PHP_VERSION . '.'; +} + +if ($issues) { + if (!headers_sent()) { + header('HTTP/1.1 500 Internal Server Error'); + } + if (!ini_get('display_errors')) { + if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { + fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL); + } elseif (!headers_sent()) { + echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL; + } + } + trigger_error( + 'Composer detected issues in your platform: ' . implode(' ', $issues), + E_USER_ERROR + ); +}
View file
iRony.dsc
Changed
@@ -2,7 +2,7 @@ Source: irony Binary: irony Architecture: all -Version: 0.4.5-1~kolab2 +Version: 0.4.6-1~kolab1 Maintainer: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com> Uploaders: Paul Klos <kolab@klos2day.nl> Homepage: http://www.kolab.org/ @@ -12,15 +12,11 @@ Build-Depends: debhelper (>= 8), composer, - php-sabre-dav-2.1 (>= 2.1.10), - php-sabre-event (>= 2.0.2), - php-sabre-http-3 (>= 3.0.5), - php-sabre-vobject-3 (>= 3.5.2), roundcubemail-core, roundcubemail-plugin-libcalendaring (>= 3.1.12), roundcubemail-plugin-libkolab (>= 3.1.12) Package-List: iRony deb admin extra Files: - 00000000000000000000000000000000 0 iRony-0.4.5.tar.gz + 00000000000000000000000000000000 0 iRony-0.4.6.tar.gz 00000000000000000000000000000000 0 debian.tar.gz
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.