diff --git a/.travis.yml b/.travis.yml index c14a093d11..0336bfca77 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,15 +13,25 @@ matrix: services: - memcached - - mysql + - mysql #we use mariadb instead installed via addons below # - postgres +#addons: +# mariadb: '10.0' + sudo: required before_script: - sudo apt-get update -qq - - sudo apt-get install -y libpcre3-dev apache2 libapache2-mod-fastcgi + - sudo apt-get install -y libpcre3-dev - case $(phpenv version-name) in + "5.6") + yes "" | pecl install memcache; + yes "" | pecl install apcu-4.0.11; + yes "" | pecl install igbinary; + echo "extension=memcached.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini; + phpenv config-rm xdebug.ini; + ;; "7"|"7.0"|"7.1"|"7.2") yes "" | pecl install apcu; echo "extension=memcached.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini; @@ -31,23 +41,15 @@ before_script: echo "extension=memcached.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini; ;; esac - # enable apache with php-fpm see https://docs.travis-ci.com/user/languages/php/#apache--php - - sudo cp ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.conf.default ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.conf - - sudo a2enmod rewrite actions fastcgi alias - - echo "cgi.fix_pathinfo = 1" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini - - sudo sed -i -e "s,www-data,travis,g" /etc/apache2/envvars - - sudo chown -R travis:travis /var/lib/apache2/fastcgi - - ~/.phpenv/versions/$(phpenv version-name)/sbin/php-fpm - # configure apache virtual hosts - - sudo cp -f doc/travis-ci-apache.conf /etc/apache2/sites-available/000-default.conf - - sudo sed -e "s?%TRAVIS_BUILD_DIR%?$(pwd)?g" --in-place /etc/apache2/sites-available/000-default.conf - - sudo service apache2 restart - case $(phpenv version-name) in - "7.2") - composer require --ignore-platform-reqs 'phpunit/phpunit:~8'; - ;; + "5.6") + composer require 'phpunit/phpunit:~5.7'; + ;; + "7"|"7.0") + composer require 'phpunit/phpunit:~6'; + ;; *) - composer require --ignore-platform-reqs 'phpunit/phpunit:~9'; + composer require --ignore-platform-reqs 'phpunit/phpunit:~7'; ;; esac - php -m diff --git a/api/src/Accounts.php b/api/src/Accounts.php index 15f2b6db61..2c7b6541a8 100644 --- a/api/src/Accounts.php +++ b/api/src/Accounts.php @@ -983,7 +983,7 @@ class Accounts if (!is_array($app_users)) { self::setup_cache(); - $cache = &self::$cache['account_split'][$app_users]; + $cache = &self::$cache['account_split'][$app_user]; if (is_array($cache)) { diff --git a/api/src/Accounts/Ldap.php b/api/src/Accounts/Ldap.php index f18f898449..ddd4303fc3 100644 --- a/api/src/Accounts/Ldap.php +++ b/api/src/Accounts/Ldap.php @@ -125,7 +125,7 @@ class Ldap * * @var Api\Accounts */ - protected $frontend; + private $frontend; /** * Instance of the ldap class diff --git a/api/src/Cache.php b/api/src/Cache.php index c859e0f6a5..ba34282990 100644 --- a/api/src/Cache.php +++ b/api/src/Cache.php @@ -769,10 +769,9 @@ class Cache if (is_null(Cache::$default_provider)) { Cache::$default_provider = - PHP_SAPI === 'cli' ? 'EGroupware\Api\Cache\Files' : - (function_exists('apcu_fetch') && Cache\Apcu::available() ? 'EGroupware\Api\Cache\Apcu' : - (function_exists('apc_fetch') && Cache\Apc::available() ? 'EGroupware\Api\Cache\Apc' : - 'EGroupware\Api\Cache\Files')); + function_exists('apcu_fetch') && Cache\Apcu::available() ? 'EGroupware\Api\Cache\Apcu' : + (function_exists('apc_fetch') && Cache\Apc::available() ? 'EGroupware\Api\Cache\Apc' : + 'EGroupware\Api\Cache\Files'); } //error_log('Cache::$default_provider='.array2string(Cache::$default_provider)); diff --git a/api/src/Cache/Memcache.php b/api/src/Cache/Memcache.php index d1f3819b0a..8523e92d50 100644 --- a/api/src/Cache/Memcache.php +++ b/api/src/Cache/Memcache.php @@ -13,9 +13,6 @@ namespace EGroupware\Api\Cache; -// fix warning in tests, if memcache extension not available -if (defined('MEMCACHE_COMPRESSED')) define('MEMCACHE_COMPRESSED', 2); - /** * Caching provider storing data in memcached via PHP's memcache extension * diff --git a/api/src/Session.php b/api/src/Session.php index 17dc2ec68e..c800446693 100644 --- a/api/src/Session.php +++ b/api/src/Session.php @@ -1658,8 +1658,6 @@ class Session */ private static function set_cookiedomain() { - if (PHP_SAPI === "cli") return; // gives warnings and has no benefit - if ($GLOBALS['egw_info']['server']['cookiedomain']) { // Admin set domain, eg. .domain.com to allow egw.domain.com and www.domain.com diff --git a/api/src/Translation.php b/api/src/Translation.php index 59fa77fb23..bc5381793a 100644 --- a/api/src/Translation.php +++ b/api/src/Translation.php @@ -395,11 +395,7 @@ class Translation static function &load_app($app,$lang) { //$start = microtime(true); - if (!isset(self::$db)) - { - self::init(false); - if (!isset(self::$db)) return; - } + if (is_null(self::$db)) self::init(false); $loaded = array(); foreach(self::$db->select(self::LANG_TABLE,'message_id,content',array( 'lang' => $lang, diff --git a/api/tests/CalDAVTest.php b/api/tests/CalDAVTest.php deleted file mode 100644 index 426459cdfe..0000000000 --- a/api/tests/CalDAVTest.php +++ /dev/null @@ -1,375 +0,0 @@ - - * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License - */ - -namespace EGroupware\Api; - -// so tests can run standalone -require_once __DIR__.'/../src/loader/common.php'; // autoloader - -use PHPUnit\Framework\TestCase; -use GuzzleHttp\Client, GuzzleHttp\RequestOptions; -use Horde_Icalendar, Horde_Icalendar_Exception; -use Psr\Http\Message\ResponseInterface; - -/** - * Abstract CalDAVTest using GuzzleHttp\Client against EGroupware CalDAV/CardDAV server - * - * @see http://docs.guzzlephp.org/en/v6/quickstart.html - * - * @package EGroupware\Api - */ -abstract class CalDAVTest extends TestCase -{ - /** - * Base URL of CalDAV server - */ - const CALDAV_BASE = 'http://localhost/egroupware/groupdav.php'; - - /** - * Get full URL for a CalDAV path - * - * @param string $path CalDAV path - * @return string URL - */ - protected function url($path='/') - { - $base = self::CALDAV_BASE; - if (!empty($GLOBALS['EGW_DOMAIN']) && $GLOBALS['EGW_DOMAIN'] !== 'default') - { - $base = str_replace('localhost', $GLOBALS['EGW_DOMAIN'], $base); - } - return $base.$path; - } - - /** - * Default options for GuzzleHttp\Client - * - * @var array - * @see http://docs.guzzlephp.org/en/v6/request-options.html - */ - protected $client_options = [ - RequestOptions::HTTP_ERRORS => false, // return all HTTP status, not throwing exceptions - RequestOptions::HEADERS => [ - 'Cookie' => 'XDEBUG_SESSION=PHPSTORM', - //'User-Agent' => 'CalDAVSynchronizer', - ], - ]; - - /** - * Get HTTP client for tests - * - * It will use by default the always existing user "demo" with password "guest" (use [] to NOT authenticate). - * Additional users need to be created with $this->createUser("name"). - * - * @param string|array $user_or_options ='demo' string with account_lid of user for authentication or array of options - * @return Client - * @see http://docs.guzzlephp.org/en/v6/request-options.html - * @see http://docs.guzzlephp.org/en/v6/quickstart.html - */ - protected function getClient($user_or_options='demo') - { - if (!is_array($user_or_options)) - { - $user_or_options = $this->auth($user_or_options); - } - return new Client(array_merge($this->client_options, $user_or_options)); - } - - /** - * Create a number of users with optional ACL rights too - * - * Example with boss granting secretary full rights on his calendar, plus one other user: - * - * $this->users = [ - * 'boss' => [], - * 'secretary' => ['rights' => ['boss' => Acl::READ|Acl::ADD|Acl::EDIT|Acl::DELETE]], - * 'other' => [], - * ]; - * $this->createUsersACL($this->users); - * - * @param array& $users $account_lid => array with values for keys with (defaults) "firstname" ($_acount_lid), "lastname" ("User"), - * "email" ("$_account_lid@example.org"), "password" (random string), "primary_group" ("NoGroups" to not set rights) - * "rights" array with $grantee => $rights pairs (need to be created before!) - * @param string $app app to create the rights for, default "calendar" - * @throws \Exception - */ - protected function createUsersACL(array &$users, $app='calendar') - { - foreach($users as $user => $data) - { - $data['id'] = $this->createUser($user, $data); - - foreach($data['rights'] ?? [] as $grantee => $rights) - { - $this->addAcl('calendar', $data['id'], $grantee, $rights); - } - } - } - - /** - * Array to track created users for tearDown and authentication - * - * @var array $account_lid => array with other data pairs - */ - private $created_users = []; - - /** - * Create a user - * - * Created users are automatic deleted in tearDown() and can be passed to auth() or getClient() methods. - * Users have random passwords to force new/different sessions! - * - * @param string $_account_lid - * @param array& $data =[] values for keys with (defaults) "firstname" ($_acount_lid), "lastname" ("User"), - * "email" ("$_account_lid@example.org"), "password" (random string), "primary_group" ("NoGroups" to not set rights) - * on return: with defaults set - * @return int account_id of created user - * @throws \Exception - */ - protected function createUser($_account_lid, array &$data=[]) - { - // add some defaults - $data = array_merge([ - 'firstname' => ucfirst($_account_lid), - 'lastname' => 'User', - 'email' => $_account_lid.'@example.org', - 'password' => 'secret',//Auth::randomstring(12), - 'primary_group' => 'NoGroup', - ], $data); - - $data['id'] = $this->getSetup()->add_account($_account_lid, $data['firstname'], $data['lastname'], - $data['password'], $data['primary_group'], false, $data['email']); - - // give use run rights for CalDAV apps, as NoGroup does NOT! - $this->addAcl(['groupdav','calendar','infolog','addressbook'], 'run', $data['id']); - - $this->created_users[$_account_lid] = $data; - - return $data['id']; - } - - /** - * Get authentication information for given user to use - * - * @param string $_account_lid ='demo' - * @return array - */ - protected function auth($_account_lid='demo') - { - if ($_account_lid === 'demo') - { - $password = 'guest'; - } - elseif (!isset($this->created_users[$_account_lid])) - { - throw new \InvalidArgumentException("No user '$_account_lid' exist, need to create it with createUser('$_account_lid')"); - } - else - { - $password = $this->created_users[$_account_lid]['password']; - } - return [RequestOptions::AUTH => [$_account_lid, $password]]; - } - - /** - * Tear down: - * - delete users created by createUser() incl. their ACL and data - */ - public function tearDown() - { - $setup = $this->getSetup(); - - foreach($this->created_users as $account_lid => $data) - { -// if ($id) $setup->accounts->delete($data['id']); - unset($this->created_users[$account_lid]); - } - } - - /** - * Add ACL rights - * - * @param string|array $apps app-names - * @param string $location eg. "run" - * @param int|string $account accountid or account_lid - * @param int $rights rights to set, default 1 - */ - function addAcl($apps, $location, $account, $rights=1) - { - return $this->getSetup()->add_acl($apps, $location, $account, $rights); - } - - /** - * Return instance of setup object eg. to create users - * - * @return \setup - */ - private function getSetup() - { - if (!isset($_REQUEST['domain'])) - { - $_REQUEST['domain'] = $GLOBALS['EGW_DOMAIN'] ?? 'default'; - } - $_REQUEST['ConfigDomain'] = $_REQUEST['domain']; - require_once __DIR__.'/../../setup/inc/functions.inc.php'; - - return $GLOBALS['egw_setup']; - } - - /** - * Check HTTP status in response - * - * @param int|array $expected one or more valid status codes - * @param ResponseInterface $response - * @param string $message ='' additional message to prefix result message - */ - protected function assertHttpStatus($expected, ResponseInterface $response, $message='') - { - $status = $response->getStatusCode(); - $this->assertEquals(in_array($status, (array)$expected) ? $status : ((array)$expected)[0], $status, - (!empty($message) ? $message.': ' : ''). 'Expected HTTP status: '.json_encode($expected). - ", Server returned: $status ".$response->getReasonPhrase()); - } - - /** - * Asserts an iCal file matches an expected one taking into account $_overwrites - * - * @param string $_expected - * @param string $_acctual - * @param string $_message - * @param array $_overwrites =[] eg. ['vEvent' => [['ATTENDEE' => ['mailto:boss@example.org' => ['PARTSTAT' => 'DECLINED']]]]] - * (first vEvent attendee with value 'mailto:boss@...' has param 'PARTSTAT=DECLINED') - * @throws Horde_Icalendar_Exception - */ - protected function assertIcal($_expected, $_acctual, $_message=null, $_overwrites=[]) - { - // enable to see full iCals - //$this->assertEquals($_expected, (string)$_acctual, $_message.": iCal not byte-by-byte identical"); - - $expected = new Horde_Icalendar(); - $expected->parsevCalendar($_expected); - $acctual = new Horde_Icalendar(); - $acctual->parsevCalendar($_acctual); - - if (($msgs = $this->checkComponentEqual($expected, $acctual, $_overwrites))) - { - $this->assertEquals($_expected, (string)$_acctual, ($_message ? $_message.":\n" : '').implode("\n", $msgs)); - } - else - { - $this->assertTrue(true); // due to $_overwrite probable $_expected !== $_acctual - } - } - - /** - * Check two iCal components are equal modulo overwrites / expected difference - * - * Only a whitelist of attributes per component are checked, see $component_attrs2check variable. - * - * @param Horde_Icalendar $_expected - * @param Horde_Icalendar $_acctual - * @param string $_message - * @param array $_overwrites =[] eg. ['ATTENDEE' => ['boss@example.org' => ['PARTSTAT' => 'DECLINED']]] - * @throws Horde_Icalendar_Exception - * @return array message(s) what's not equal - */ - protected function checkComponentEqual(Horde_Icalendar $_expected, Horde_Icalendar $_acctual, $_overwrites=[]) - { - // only following attributes in these components are checked: - static $component_attrs2check = [ - 'vcalendar' => ['VERSION'], - 'vTimeZone' => ['TZID'], - 'vEvent' => ['UID', 'SUMMARY', 'LOCATION', 'DESCRIPTION', 'DTSTART', 'DTEND', 'ORGANIZER', 'ATTENDEE'], - ]; - - if ($_expected->getType() !== $_acctual->getType()) - { - return ["component type not equal"]; - } - $msgs = []; - foreach ($component_attrs2check[$_expected->getType()] ?? [] as $attr) - { - $acctualAttrs = $_acctual->getAllAttributes($attr); - foreach($_expected->getAllAttributes($attr) as $expectedAttr) - { - $found = false; - foreach($acctualAttrs as $acctualAttr) - { - if (count($acctualAttrs) === 1 || $expectedAttr['value'] === $acctualAttr['value']) - { - $found = true; - break; - } - } - if (!$found) - { - $msgs[] = "No $attr {$expectedAttr['value']} found"; - continue; - } - // remove / ignore X-parameters, eg. X-EGROUPWARE-UID in ATTENDEE or ORGANIZER - $acctualAttr['params'] = array_filter($acctualAttr['params'], function ($key) { - return substr($key, 0, 2) !== 'X-'; - }, ARRAY_FILTER_USE_KEY); - - if (isset($_overwrites[$attr]) && is_scalar($_overwrites[$attr])) - { - $expectedAttr = [ - 'name' => $attr, - 'value' => $_overwrites[$attr], - 'values' => [$_overwrites[$attr]], - 'params' => [], - ]; - } - elseif (isset($_overwrites[$attr]) && is_array($_overwrites[$attr])) - { - foreach ($_overwrites[$attr] as $value => $params) - { - if ($value === $expectedAttr['value']) - { - $expectedAttr['params'] = array_merge($expectedAttr['params'], $params); - } - } - } - if ($expectedAttr != $acctualAttr) - { - $this->assertEquals($expectedAttr, $acctualAttr, "$attr not equal"); - $msgs[] = "$attr not equal"; - } - } - } - // check sub-components, overrites use an index by type eg. 1. vEvent: ['vEvent'=>[[getComponents() as $idx => $component) - { - if (!isset($idx_by_type[$type = $component->getType()])) $idx_by_type[$type] = 0; - $msgs = array_merge($msgs, $this->checkComponentEqual($component, $_acctual->getComponent($idx), - $_overwrites[$type][$idx_by_type[$type]] ?? [])); - $idx_by_type[$type]++; - } - return $msgs; - } - - public static function setUpBeforeClass() - { - parent::setUpBeforeClass(); - } - - public static function tearDownAfterClass() - { - parent::tearDownAfterClass(); - } - - public function setUp() - { - - } -} \ No newline at end of file diff --git a/calendar/inc/class.calendar_bo.inc.php b/calendar/inc/class.calendar_bo.inc.php index a359103607..a275c8e7fc 100644 --- a/calendar/inc/class.calendar_bo.inc.php +++ b/calendar/inc/class.calendar_bo.inc.php @@ -1338,7 +1338,7 @@ class calendar_bo elseif ($grants[$uid] & Acl::READ) { // if we have a READ grant from a participant, we dont give an implicit privat grant too - $grant |= self::ACL_FREEBUSY | Acl::READ; + $grant |= Acl::READ; // we cant break here, as we might be a participant too, and would miss the privat grant } elseif (!is_numeric($uid)) diff --git a/calendar/inc/class.calendar_groupdav.inc.php b/calendar/inc/class.calendar_groupdav.inc.php index 59d1c04502..aeb87ad367 100644 --- a/calendar/inc/class.calendar_groupdav.inc.php +++ b/calendar/inc/class.calendar_groupdav.inc.php @@ -1375,56 +1375,35 @@ class calendar_groupdav extends Api\CalDAV\Handler return true; // simply ignore DELETE in inbox for now } $return_no_access = true; // to allow to check if current use is a participant and reject the event for him - $event = $this->_common_get_put_delete('DELETE',$options,$id,$return_no_access); - - // no event found --> 404 Not Found - if (!is_array($event)) + if (!is_array($event = $this->_common_get_put_delete('DELETE',$options,$id,$return_no_access)) || !$return_no_access || + // Work around problems with Outlook CalDAV Synchroniser (https://caldavsynchronizer.org/) + // - sends a DELETE to reject a meeting request --> deletes event for all participants, if user has delete rights on the calendar + // --> only set status for everyone else but the organizer + self::get_agent() == 'caldavsynchronizer' && is_array($event) && $event['owner'] != $user) { - $ret = $event; - error_log("_common_get_put_delete('DELETE', ..., $id) user=$user, return_no_access=".array2string($return_no_access)." returned ".array2string($event)); - } - // Work around problems with Outlook CalDAV Synchronizer (https://caldavsynchronizer.org/) - // - sends a DELETE to reject a meeting request --> deletes event for all participants, if user has delete rights from the organizer - // --> only set status for everyone else but the organizer - // OR no delete rights and deleting an event in someone else calendar --> check if calendar owner is a participant --> reject him - elseif ((!$return_no_access || (self::get_agent() === 'caldavsynchronizer' && $event['owner'] != $user)) && - // check if current user has edit rights for calendar of $user, can change status / reject invitation for him - $this->bo->check_perms(Acl::EDIT, 0, $user)) - { - // check if user is a participant or one of the groups he is a member of --> reject the meeting request - $ret = '403 Forbidden'; - $memberships = $GLOBALS['egw']->accounts->memberships($user, true); - foreach(array_keys($event['participants']) as $uid) + if (is_array($event) && (!$return_no_access || $event['owner'] != $user)) { - if ($user == $uid || in_array($uid, $memberships)) + // check if user is a participant or one of the groups he is a member of --> reject the meeting request + $ret = '403 Forbidden'; + $memberships = $GLOBALS['egw']->accounts->memberships($this->bo->user, true); + foreach(array_keys($event['participants']) as $uid) { - $this->bo->set_status($event, $user, 'R'); - $ret = true; - break; + if ($this->bo->user == $uid || in_array($uid, $memberships)) + { + $this->bo->set_status($event,$this->bo->user, 'R'); + $ret = true; + break; + } } } - } - // current user has no delete rights for event --> reject invitation, if he is a participant - elseif (!$return_no_access) - { - // check if current user is a participant or one of the groups he is a member of --> reject the meeting request - $ret = '403 Forbidden'; - $memberships = $GLOBALS['egw']->accounts->memberships($this->bo->user, true); - foreach(array_keys($event['participants']) as $uid) + else { - if ($this->bo->user == $uid || in_array($uid, $memberships)) - { - $this->bo->set_status($event, $this->bo->user, 'R'); - $ret = true; - break; - } + $ret = $event; } } - // we have delete rights on the event and (try to) delete it else { $ret = $this->bo->delete($event['id']); - if (!$ret) { error_log("delete($event[id]) returned FALSE"); $ret = '400 Failed to delete event';} } if ($this->debug) error_log(__METHOD__."(,$id) return_no_access=$return_no_access, event[participants]=".array2string(is_array($event)?$event['participants']:null).", user={$this->bo->user} --> return ".array2string($ret)); return $ret; diff --git a/calendar/tests/CalDAV/CalDAVcreateReadDelete.php b/calendar/tests/CalDAV/CalDAVcreateReadDelete.php deleted file mode 100644 index 4ccdf12e95..0000000000 --- a/calendar/tests/CalDAV/CalDAVcreateReadDelete.php +++ /dev/null @@ -1,121 +0,0 @@ - - * @package calendar - * @subpackage tests - * @copyright (c) 2020 by Ralf Becker - * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License - */ - -namespace EGroupware\calendar; - -require_once __DIR__.'/../../../api/tests/CalDAVTest.php'; - -use EGroupware\Api\CalDAVTest; -use GuzzleHttp\RequestOptions; - -class CalDAVcreateReadDelete extends CalDAVTest -{ - /** - * Test accessing CalDAV without authentication - */ - public function testNoAuth() - { - $response = $this->getClient([])->get($this->url('/')); - - $this->assertHttpStatus(401, $response); - } - - /** - * Test accessing CalDAV with authentication - */ - public function testAuth() - { - $response = $this->getClient()->get($this->url('/')); - - $this->assertHttpStatus(200, $response); - } - - const EVENT_URL = '/demo/calendar/new-event-1233456789-new.ics'; - const EVENT_ICAL = <<getClient()->put($this->url(self::EVENT_URL), [ - RequestOptions::HEADERS => [ - 'Content-Type' => 'text/calendar', - 'If-None-Match' => '*', - ], - RequestOptions::BODY => self::EVENT_ICAL, - ]); - - $this->assertHttpStatus(201, $response); - } - - /** - * Read created event - */ - public function testRead() - { - $response = $this->getClient()->get($this->url(self::EVENT_URL)); - - $this->assertHttpStatus(200, $response); - $this->assertIcal(self::EVENT_ICAL, $response->getBody()); - } - - /** - * Delete created event - */ - public function testDelete() - { - $response = $this->getClient()->delete($this->url(self::EVENT_URL)); - - $this->assertHttpStatus(204, $response); - } - - /** - * Read created event - */ - public function testReadDeleted() - { - $response = $this->getClient()->get($this->url(self::EVENT_URL)); - - $this->assertHttpStatus(404, $response); - } -} \ No newline at end of file diff --git a/calendar/tests/CalDAV/CalDAVsingleDELETE.php b/calendar/tests/CalDAV/CalDAVsingleDELETE.php deleted file mode 100644 index d5af90eb96..0000000000 --- a/calendar/tests/CalDAV/CalDAVsingleDELETE.php +++ /dev/null @@ -1,368 +0,0 @@ - - * @package calendar - * @subpackage tests - * @copyright (c) 2020 by Ralf Becker - * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License - */ - -namespace EGroupware\calendar; - -require_once __DIR__.'/../../../api/tests/CalDAVTest.php'; - -use EGroupware\Api\CalDAVTest; -use GuzzleHttp\RequestOptions; -use EGroupware\Api\Acl; - -/** - * Class CalDAVsingleDELETE - * - * This tests check all sorts of DELETE requests by organizer and attendees, with and without (delete) rights on the organizer. - * - * For CalDAV Synchronizer, which does not distingues between deleting and rejecting events, we only allow the - * organizer to delete an event. - * - * @package EGroupware\calendar - * @covers \calendar_groupdav::delete() - * @uses \calendar_groupdav::put() - * @uses \calendar_groupdav::get() - */ -class CalDAVsingleDELETE extends CalDAVTest -{ - /** - * Users and their ACL for the test - * - * @var array - */ - protected $users = [ - 'boss' => [], - 'secretary' => [ - 'rights' => [ - 'boss' => Acl::READ|Acl::ADD|Acl::EDIT|Acl::DELETE, - ] - ], - 'other' => [], - ]; - - /** - * Create some users incl. ACL - */ - public function setUp() - { - parent::setUp(); - - $this->createUsersACL($this->users, 'calendar'); - } - - /** - * Check created users - */ - public function testPrincipals() - { - foreach($this->users as $user => &$data) - { - $response = $this->getClient()->propfind($this->url('/principals/users/'.$user.'/'), [ - RequestOptions::HEADERS => [ - 'Depth' => 0, - ], - ]); - $this->assertHttpStatus(207, $response); - } - } - - const EVENT_BOSS_ATTENDEE_ORGANIZER_URL = '/other/calendar/new-event-boss-attendee-123456789-new.ics'; - const EVENT_BOSS_ATTENDEE_URL = '/boss/calendar/new-event-boss-attendee-123456789-new.ics'; - const EVENT_BOSS_ATTENDEE_ICAL = <<getClient('other')->put($this->url(self::EVENT_BOSS_ATTENDEE_ORGANIZER_URL), [ - RequestOptions::HEADERS => [ - 'Content-Type' => 'text/calendar', - 'Prefer' => 'return=representation' - ], - RequestOptions::BODY => self::EVENT_BOSS_ATTENDEE_ICAL, - ]); - $this->assertHttpStatus([200,201], $response); - $this->assertIcal(self::EVENT_BOSS_ATTENDEE_ICAL, $response->getBody()); - - // secretrary deletes event in boss's calendar - $response = $this->getClient('secretary')->delete($this->url(self::EVENT_BOSS_ATTENDEE_URL)); - $this->assertHttpStatus(204, $response, 'Secretary delete/rejects for boss'); - - // use organizer to check event still exists and boss rejected - $response = $this->getClient('other')->get($this->url(self::EVENT_BOSS_ATTENDEE_ORGANIZER_URL)); - $this->assertHttpStatus(200, $response, 'Check event still exists after DELETE in attendee calendar'); - $this->assertIcal(self::EVENT_BOSS_ATTENDEE_ICAL, $response->getBody(), - 'Boss should have declined the invitation', - ['vEvent' => [['ATTENDEE' => ['mailto:boss@example.org' => ['PARTSTAT' => 'DECLINED', 'RSVP' => 'FALSE']]]]] - ); - - // secretary tries to delete event in organizers calendar - $response = $this->getClient('secretary')->delete($this->url(self::EVENT_BOSS_ATTENDEE_ORGANIZER_URL)); - $this->assertHttpStatus(403, $response, 'Secretary not allowed to delete for organizer'); - - // boss deletes/rejects event in his calendar - $response = $this->getClient('boss')->delete($this->url(self::EVENT_BOSS_ATTENDEE_URL)); - $this->assertHttpStatus(204, $response, 'Boss deletes/rejects in his calendar'); - - // boss deletes/rejects event in organizers calendar - $response = $this->getClient('boss')->delete($this->url(self::EVENT_BOSS_ATTENDEE_ORGANIZER_URL)); - $this->assertHttpStatus(204, $response, 'Boss deletes/rejects in organizers calendar'); - - // use organizer to delete event - $response = $this->getClient('other')->delete($this->url(self::EVENT_BOSS_ATTENDEE_ORGANIZER_URL)); - $this->assertHttpStatus(204, $response); - - // use organizer to check event deleted - $response = $this->getClient('other')->get($this->url(self::EVENT_BOSS_ATTENDEE_ORGANIZER_URL)); - $this->assertHttpStatus(404, $response, "Check event deleted by organizer"); - } - - const EVENT_BOSS_ORGANIZER_URL = '/boss/calendar/new-event-boss-organizer-123456789-new.ics'; - const EVENT_BOSS_ORGANIZER_OTHER_URL = '/other/calendar/new-event-boss-organizer-123456789-new.ics'; - const EVENT_BOSS_ORGANIZER_ICAL = <<getClient('boss')->put($this->url(self::EVENT_BOSS_ORGANIZER_URL), [ - RequestOptions::HEADERS => [ - 'Content-Type' => 'text/calendar', - 'Prefer' => 'return=representation' - ], - RequestOptions::BODY => self::EVENT_BOSS_ORGANIZER_ICAL, - ]); - $this->assertHttpStatus([200,201], $response); - $this->assertIcal(self::EVENT_BOSS_ORGANIZER_ICAL, $response->getBody()); - - // attendee deletes/rejects event in his calendar - $response = $this->getClient('other')->delete($this->url(self::EVENT_BOSS_ORGANIZER_OTHER_URL)); - $this->assertHttpStatus(204, $response); - - // secretrary deletes event in boss's calendar - $response = $this->getClient('secretary')->delete($this->url(self::EVENT_BOSS_ORGANIZER_URL)); - $this->assertHttpStatus(204, $response, 'Secretary deletes for boss'); - - // use organizer/boss to check event deleted - $response = $this->getClient('boss')->get($this->url(self::EVENT_BOSS_ORGANIZER_URL)); - $this->assertHttpStatus(404, $response, "Check event deleted by secretary"); - } - - /** - * Check organizer (boss) can delete event in his calendar - * - * @throws \Horde_Icalendar_Exception - */ - public function testOrganizerDeletes() - { - // create invitation by boss as organizer - $response = $this->getClient('boss')->put($this->url(self::EVENT_BOSS_ORGANIZER_URL), [ - RequestOptions::HEADERS => [ - 'Content-Type' => 'text/calendar', - 'Prefer' => 'return=representation' - ], - RequestOptions::BODY => self::EVENT_BOSS_ORGANIZER_ICAL, - ]); - $this->assertHttpStatus([200,201], $response); - $this->assertIcal(self::EVENT_BOSS_ORGANIZER_ICAL, $response->getBody()); - - // organizer deletes event in his calendar - $response = $this->getClient('boss')->delete($this->url(self::EVENT_BOSS_ORGANIZER_URL)); - $this->assertHttpStatus(204, $response, 'Organizer deletes'); - - // use organizer/boss to check event deleted - $response = $this->getClient('boss')->get($this->url(self::EVENT_BOSS_ORGANIZER_URL)); - $this->assertHttpStatus(404, $response, "Check event deleted by organizer"); - - // use attendee to check event deleted - $response = $this->getClient('other')->get($this->url(self::EVENT_BOSS_ORGANIZER_OTHER_URL)); - $this->assertHttpStatus(404, $response, "Check event deleted by organizer"); - } - - const EVENT_SECRETARY_ATTENDEE_URL = '/secretary/calendar/new-event-secreatary-attendee-123456789-new.ics'; - const EVENT_SECRETARY_ATTENDEE_ORGANIZER_URL = '/boss/calendar/new-event-secreatary-attendee-123456789-new.ics'; - const EVENT_SECRETARY_ATTENDEE_ICAL = <<getClient('boss')->put($this->url(self::EVENT_SECRETARY_ATTENDEE_ORGANIZER_URL), [ - RequestOptions::HEADERS => [ - 'Content-Type' => 'text/calendar', - 'Prefer' => 'return=representation' - ], - RequestOptions::BODY => self::EVENT_SECRETARY_ATTENDEE_ICAL, - ]); - $this->assertHttpStatus([200,201], $response); - $this->assertIcal(self::EVENT_SECRETARY_ATTENDEE_ICAL, $response->getBody()); - - // secretary deletes in her calendar - $response = $this->getClient('secretary')->delete($this->url(self::EVENT_SECRETARY_ATTENDEE_URL)); - $this->assertHttpStatus(204, $response, 'Secretary (attendee) deletes'); - - // use organizer to check it's really deleted - $response = $this->getClient('boss')->get($this->url(self::EVENT_SECRETARY_ATTENDEE_ORGANIZER_URL)); - $this->assertHttpStatus(404, $response, "Check event deleted by secretary"); - } - - /** - * Check secretary as attendee deletes event with CalDAVSynchronizer - * - * @throws \Horde_Icalendar_Exception - */ - public function testSecretaryAttendeeDeletesCalDAVSynchronizer() - { - // create invitation by boss as organizer - $response = $this->getClient('boss')->put($this->url(self::EVENT_SECRETARY_ATTENDEE_ORGANIZER_URL), [ - RequestOptions::HEADERS => [ - 'Content-Type' => 'text/calendar', - 'Prefer' => 'return=representation' - ], - RequestOptions::BODY => self::EVENT_SECRETARY_ATTENDEE_ICAL, - ]); - $this->assertHttpStatus([200,201], $response); - $this->assertIcal(self::EVENT_SECRETARY_ATTENDEE_ICAL, $response->getBody()); - - // secretary deletes in her calendar with CalDAVSynchronizer - $response = $this->getClient('secretary')->delete($this->url(self::EVENT_SECRETARY_ATTENDEE_URL), - [RequestOptions::HEADERS => ['User-Agent' => 'CalDAVSynchronizer']]); - $this->assertHttpStatus(204, $response, 'Secretary (attendee) deletes/rejects'); - - // use organizer to check it's NOT deleted, as CalDAVSynchronizer / Outlook does not distinguish between reject and delete - $response = $this->getClient('boss')->get($this->url(self::EVENT_SECRETARY_ATTENDEE_ORGANIZER_URL)); - $this->assertHttpStatus(200, $response, "Check event NOT deleted by secretary"); - $this->assertIcal(self::EVENT_SECRETARY_ATTENDEE_ICAL, $response->getBody(), - 'Secretary should have declined the invitation', - ['vEvent' => [['ATTENDEE' => ['mailto:secretary@example.org' => ['PARTSTAT' => 'DECLINED', 'RSVP' => 'FALSE']]]]] - ); - - // organizer deletes in his calendar with CalDAVSynchronizer - $response = $this->getClient('boss')->delete($this->url(self::EVENT_SECRETARY_ATTENDEE_ORGANIZER_URL), - [RequestOptions::HEADERS => ['User-Agent' => 'CalDAVSynchronizer']]); - $this->assertHttpStatus(204, $response, 'Organizer deletes'); - - // use organizer to check it's deleted, as CalDAVSynchronizer / Outlook should still delete for organizer - $response = $this->getClient('boss')->get($this->url(self::EVENT_SECRETARY_ATTENDEE_ORGANIZER_URL)); - $this->assertHttpStatus(404, $response, "Check event deleted by organizer"); - } -} \ No newline at end of file diff --git a/composer.json b/composer.json index 46e5d3c13c..4aa102eeda 100644 --- a/composer.json +++ b/composer.json @@ -101,8 +101,6 @@ "tinymce/tinymce": "^5.0" }, "require-dev": { - "guzzlehttp/guzzle": "^6.5", - "phpunit/phpunit": "^6.5" }, "suggests": { "ext-opcache": "Opcode cache to speed up PHP", diff --git a/composer.lock b/composer.lock index a546e3def5..2bf77c5761 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "27faeaf9e9bc34e41c89222565e6db06", + "content-hash": "0f9cd7cf5343e5c411b2e04d75b2fa71", "packages": [ { "name": "adldap2/adldap2", @@ -575,7 +575,6 @@ ], "description": "Promoting the interoperability of container objects (DIC, SL, etc.)", "homepage": "https://github.com/container-interop/container-interop", - "abandoned": "psr/container", "time": "2017-02-14T19:40:03+00:00" }, { @@ -3973,1754 +3972,10 @@ "psr", "psr-7" ], - "abandoned": "laminas/laminas-diactoros", "time": "2018-09-05T19:29:37+00:00" } ], - "packages-dev": [ - { - "name": "doctrine/instantiator", - "version": "1.0.5", - "source": { - "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", - "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", - "shasum": "" - }, - "require": { - "php": ">=5.3,<8.0-DEV" - }, - "require-dev": { - "athletic/athletic": "~0.1.8", - "ext-pdo": "*", - "ext-phar": "*", - "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "~2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "homepage": "http://ocramius.github.com/" - } - ], - "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://github.com/doctrine/instantiator", - "keywords": [ - "constructor", - "instantiate" - ], - "time": "2015-06-14T21:17:01+00:00" - }, - { - "name": "guzzlehttp/guzzle", - "version": "6.5.2", - "source": { - "type": "git", - "url": "https://github.com/guzzle/guzzle.git", - "reference": "43ece0e75098b7ecd8d13918293029e555a50f82" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/43ece0e75098b7ecd8d13918293029e555a50f82", - "reference": "43ece0e75098b7ecd8d13918293029e555a50f82", - "shasum": "" - }, - "require": { - "ext-json": "*", - "guzzlehttp/promises": "^1.0", - "guzzlehttp/psr7": "^1.6.1", - "php": ">=5.5" - }, - "require-dev": { - "ext-curl": "*", - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0", - "psr/log": "^1.1" - }, - "suggest": { - "ext-intl": "Required for Internationalized Domain Name (IDN) support", - "psr/log": "Required for using the Log middleware" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "6.5-dev" - } - }, - "autoload": { - "psr-4": { - "GuzzleHttp\\": "src/" - }, - "files": [ - "src/functions_include.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - } - ], - "description": "Guzzle is a PHP HTTP client library", - "homepage": "http://guzzlephp.org/", - "keywords": [ - "client", - "curl", - "framework", - "http", - "http client", - "rest", - "web service" - ], - "time": "2019-12-23T11:57:10+00:00" - }, - { - "name": "guzzlehttp/promises", - "version": "v1.3.1", - "source": { - "type": "git", - "url": "https://github.com/guzzle/promises.git", - "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646", - "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646", - "shasum": "" - }, - "require": { - "php": ">=5.5.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4-dev" - } - }, - "autoload": { - "psr-4": { - "GuzzleHttp\\Promise\\": "src/" - }, - "files": [ - "src/functions_include.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - } - ], - "description": "Guzzle promises library", - "keywords": [ - "promise" - ], - "time": "2016-12-20T10:07:11+00:00" - }, - { - "name": "guzzlehttp/psr7", - "version": "1.6.1", - "source": { - "type": "git", - "url": "https://github.com/guzzle/psr7.git", - "reference": "239400de7a173fe9901b9ac7c06497751f00727a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/239400de7a173fe9901b9ac7c06497751f00727a", - "reference": "239400de7a173fe9901b9ac7c06497751f00727a", - "shasum": "" - }, - "require": { - "php": ">=5.4.0", - "psr/http-message": "~1.0", - "ralouphie/getallheaders": "^2.0.5 || ^3.0.0" - }, - "provide": { - "psr/http-message-implementation": "1.0" - }, - "require-dev": { - "ext-zlib": "*", - "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8" - }, - "suggest": { - "zendframework/zend-httphandlerrunner": "Emit PSR-7 responses" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.6-dev" - } - }, - "autoload": { - "psr-4": { - "GuzzleHttp\\Psr7\\": "src/" - }, - "files": [ - "src/functions_include.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - }, - { - "name": "Tobias Schultze", - "homepage": "https://github.com/Tobion" - } - ], - "description": "PSR-7 message implementation that also provides common utility methods", - "keywords": [ - "http", - "message", - "psr-7", - "request", - "response", - "stream", - "uri", - "url" - ], - "time": "2019-07-01T23:21:34+00:00" - }, - { - "name": "myclabs/deep-copy", - "version": "1.7.0", - "source": { - "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", - "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.0" - }, - "require-dev": { - "doctrine/collections": "^1.0", - "doctrine/common": "^2.6", - "phpunit/phpunit": "^4.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "DeepCopy\\": "src/DeepCopy/" - }, - "files": [ - "src/DeepCopy/deep_copy.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Create deep copies (clones) of your objects", - "keywords": [ - "clone", - "copy", - "duplicate", - "object", - "object graph" - ], - "time": "2017-10-19T19:58:43+00:00" - }, - { - "name": "phar-io/manifest", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/phar-io/manifest.git", - "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/2df402786ab5368a0169091f61a7c1e0eb6852d0", - "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-phar": "*", - "phar-io/version": "^1.0.1", - "php": "^5.6 || ^7.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", - "time": "2017-03-05T18:14:27+00:00" - }, - { - "name": "phar-io/version", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/phar-io/version.git", - "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/a70c0ced4be299a63d32fa96d9281d03e94041df", - "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Library for handling version information and constraints", - "time": "2017-03-05T17:38:23+00:00" - }, - { - "name": "phpdocumentor/reflection-common", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", - "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", - "shasum": "" - }, - "require": { - "php": ">=5.5" - }, - "require-dev": { - "phpunit/phpunit": "^4.6" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" - } - ], - "description": "Common reflection classes used by phpdocumentor to reflect the code structure", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "FQSEN", - "phpDocumentor", - "phpdoc", - "reflection", - "static analysis" - ], - "time": "2017-09-11T18:02:19+00:00" - }, - { - "name": "phpdocumentor/reflection-docblock", - "version": "4.3.4", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "da3fd972d6bafd628114f7e7e036f45944b62e9c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/da3fd972d6bafd628114f7e7e036f45944b62e9c", - "reference": "da3fd972d6bafd628114f7e7e036f45944b62e9c", - "shasum": "" - }, - "require": { - "php": "^7.0", - "phpdocumentor/reflection-common": "^1.0.0 || ^2.0.0", - "phpdocumentor/type-resolver": "~0.4 || ^1.0.0", - "webmozart/assert": "^1.0" - }, - "require-dev": { - "doctrine/instantiator": "^1.0.5", - "mockery/mockery": "^1.0", - "phpdocumentor/type-resolver": "0.4.*", - "phpunit/phpunit": "^6.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ], - "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2019-12-28T18:55:12+00:00" - }, - { - "name": "phpdocumentor/type-resolver", - "version": "0.5.1", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "cf842904952e64e703800d094cdf34e715a8a3ae" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/cf842904952e64e703800d094cdf34e715a8a3ae", - "reference": "cf842904952e64e703800d094cdf34e715a8a3ae", - "shasum": "" - }, - "require": { - "php": "^7.0", - "phpdocumentor/reflection-common": "^1.0" - }, - "require-dev": { - "mockery/mockery": "^1.0", - "phpunit/phpunit": "^6.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ], - "time": "2017-12-30T13:23:38+00:00" - }, - { - "name": "phpspec/prophecy", - "version": "v1.10.2", - "source": { - "type": "git", - "url": "https://github.com/phpspec/prophecy.git", - "reference": "b4400efc9d206e83138e2bb97ed7f5b14b831cd9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/b4400efc9d206e83138e2bb97ed7f5b14b831cd9", - "reference": "b4400efc9d206e83138e2bb97ed7f5b14b831cd9", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.0.2", - "php": "^5.3|^7.0", - "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0", - "sebastian/comparator": "^1.2.3|^2.0|^3.0|^4.0", - "sebastian/recursion-context": "^1.0|^2.0|^3.0|^4.0" - }, - "require-dev": { - "phpspec/phpspec": "^2.5 || ^3.2", - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.10.x-dev" - } - }, - "autoload": { - "psr-4": { - "Prophecy\\": "src/Prophecy" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - }, - { - "name": "Marcello Duarte", - "email": "marcello.duarte@gmail.com" - } - ], - "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "https://github.com/phpspec/prophecy", - "keywords": [ - "Double", - "Dummy", - "fake", - "mock", - "spy", - "stub" - ], - "time": "2020-01-20T15:57:02+00:00" - }, - { - "name": "phpunit/php-code-coverage", - "version": "5.3.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "c89677919c5dd6d3b3852f230a663118762218ac" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c89677919c5dd6d3b3852f230a663118762218ac", - "reference": "c89677919c5dd6d3b3852f230a663118762218ac", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-xmlwriter": "*", - "php": "^7.0", - "phpunit/php-file-iterator": "^1.4.2", - "phpunit/php-text-template": "^1.2.1", - "phpunit/php-token-stream": "^2.0.1", - "sebastian/code-unit-reverse-lookup": "^1.0.1", - "sebastian/environment": "^3.0", - "sebastian/version": "^2.0.1", - "theseer/tokenizer": "^1.1" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "suggest": { - "ext-xdebug": "^2.5.5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.3.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", - "homepage": "https://github.com/sebastianbergmann/php-code-coverage", - "keywords": [ - "coverage", - "testing", - "xunit" - ], - "time": "2018-04-06T15:36:58+00:00" - }, - { - "name": "phpunit/php-file-iterator", - "version": "1.4.5", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", - "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "FilterIterator implementation that filters files based on a list of suffixes.", - "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", - "keywords": [ - "filesystem", - "iterator" - ], - "time": "2017-11-27T13:52:08+00:00" - }, - { - "name": "phpunit/php-text-template", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", - "keywords": [ - "template" - ], - "time": "2015-06-21T13:50:34+00:00" - }, - { - "name": "phpunit/php-timer", - "version": "1.0.9", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", - "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", - "shasum": "" - }, - "require": { - "php": "^5.3.3 || ^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", - "keywords": [ - "timer" - ], - "time": "2017-02-26T11:10:40+00:00" - }, - { - "name": "phpunit/php-token-stream", - "version": "2.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "791198a2c6254db10131eecfe8c06670700904db" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/791198a2c6254db10131eecfe8c06670700904db", - "reference": "791198a2c6254db10131eecfe8c06670700904db", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.2.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Wrapper around PHP's tokenizer extension.", - "homepage": "https://github.com/sebastianbergmann/php-token-stream/", - "keywords": [ - "tokenizer" - ], - "time": "2017-11-27T05:48:46+00:00" - }, - { - "name": "phpunit/phpunit", - "version": "6.5.14", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "bac23fe7ff13dbdb461481f706f0e9fe746334b7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/bac23fe7ff13dbdb461481f706f0e9fe746334b7", - "reference": "bac23fe7ff13dbdb461481f706f0e9fe746334b7", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-xml": "*", - "myclabs/deep-copy": "^1.6.1", - "phar-io/manifest": "^1.0.1", - "phar-io/version": "^1.0", - "php": "^7.0", - "phpspec/prophecy": "^1.7", - "phpunit/php-code-coverage": "^5.3", - "phpunit/php-file-iterator": "^1.4.3", - "phpunit/php-text-template": "^1.2.1", - "phpunit/php-timer": "^1.0.9", - "phpunit/phpunit-mock-objects": "^5.0.9", - "sebastian/comparator": "^2.1", - "sebastian/diff": "^2.0", - "sebastian/environment": "^3.1", - "sebastian/exporter": "^3.1", - "sebastian/global-state": "^2.0", - "sebastian/object-enumerator": "^3.0.3", - "sebastian/resource-operations": "^1.0", - "sebastian/version": "^2.0.1" - }, - "conflict": { - "phpdocumentor/reflection-docblock": "3.0.2", - "phpunit/dbunit": "<3.0" - }, - "require-dev": { - "ext-pdo": "*" - }, - "suggest": { - "ext-xdebug": "*", - "phpunit/php-invoker": "^1.1" - }, - "bin": [ - "phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "6.5.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "The PHP Unit Testing framework.", - "homepage": "https://phpunit.de/", - "keywords": [ - "phpunit", - "testing", - "xunit" - ], - "time": "2019-02-01T05:22:47+00:00" - }, - { - "name": "phpunit/phpunit-mock-objects", - "version": "5.0.10", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "cd1cf05c553ecfec36b170070573e540b67d3f1f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/cd1cf05c553ecfec36b170070573e540b67d3f1f", - "reference": "cd1cf05c553ecfec36b170070573e540b67d3f1f", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.0.5", - "php": "^7.0", - "phpunit/php-text-template": "^1.2.1", - "sebastian/exporter": "^3.1" - }, - "conflict": { - "phpunit/phpunit": "<6.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.5.11" - }, - "suggest": { - "ext-soap": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Mock Object library for PHPUnit", - "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", - "keywords": [ - "mock", - "xunit" - ], - "abandoned": true, - "time": "2018-08-09T05:50:03+00:00" - }, - { - "name": "ralouphie/getallheaders", - "version": "3.0.3", - "source": { - "type": "git", - "url": "https://github.com/ralouphie/getallheaders.git", - "reference": "120b605dfeb996808c31b6477290a714d356e822" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", - "reference": "120b605dfeb996808c31b6477290a714d356e822", - "shasum": "" - }, - "require": { - "php": ">=5.6" - }, - "require-dev": { - "php-coveralls/php-coveralls": "^2.1", - "phpunit/phpunit": "^5 || ^6.5" - }, - "type": "library", - "autoload": { - "files": [ - "src/getallheaders.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ralph Khattar", - "email": "ralph.khattar@gmail.com" - } - ], - "description": "A polyfill for getallheaders.", - "time": "2019-03-08T08:55:37+00:00" - }, - { - "name": "sebastian/code-unit-reverse-lookup", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", - "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^5.7 || ^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Looks up which function or method a line of code belongs to", - "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", - "time": "2017-03-04T06:30:41+00:00" - }, - { - "name": "sebastian/comparator", - "version": "2.1.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "34369daee48eafb2651bea869b4b15d75ccc35f9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/34369daee48eafb2651bea869b4b15d75ccc35f9", - "reference": "34369daee48eafb2651bea869b4b15d75ccc35f9", - "shasum": "" - }, - "require": { - "php": "^7.0", - "sebastian/diff": "^2.0 || ^3.0", - "sebastian/exporter": "^3.1" - }, - "require-dev": { - "phpunit/phpunit": "^6.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.1.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides the functionality to compare PHP values for equality", - "homepage": "https://github.com/sebastianbergmann/comparator", - "keywords": [ - "comparator", - "compare", - "equality" - ], - "time": "2018-02-01T13:46:46+00:00" - }, - { - "name": "sebastian/diff", - "version": "2.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/347c1d8b49c5c3ee30c7040ea6fc446790e6bddd", - "reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd", - "shasum": "" - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Diff implementation", - "homepage": "https://github.com/sebastianbergmann/diff", - "keywords": [ - "diff" - ], - "time": "2017-08-03T08:09:46+00:00" - }, - { - "name": "sebastian/environment", - "version": "3.1.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/cd0871b3975fb7fc44d11314fd1ee20925fce4f5", - "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5", - "shasum": "" - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "http://www.github.com/sebastianbergmann/environment", - "keywords": [ - "Xdebug", - "environment", - "hhvm" - ], - "time": "2017-07-01T08:51:00+00:00" - }, - { - "name": "sebastian/exporter", - "version": "3.1.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/68609e1261d215ea5b21b7987539cbfbe156ec3e", - "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e", - "shasum": "" - }, - "require": { - "php": "^7.0", - "sebastian/recursion-context": "^3.0" - }, - "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "http://www.github.com/sebastianbergmann/exporter", - "keywords": [ - "export", - "exporter" - ], - "time": "2019-09-14T09:02:43+00:00" - }, - { - "name": "sebastian/global-state", - "version": "2.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", - "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", - "shasum": "" - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "suggest": { - "ext-uopz": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", - "keywords": [ - "global state" - ], - "time": "2017-04-27T15:39:26+00:00" - }, - { - "name": "sebastian/object-enumerator", - "version": "3.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5", - "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5", - "shasum": "" - }, - "require": { - "php": "^7.0", - "sebastian/object-reflector": "^1.1.1", - "sebastian/recursion-context": "^3.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Traverses array structures and object graphs to enumerate all referenced objects", - "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "time": "2017-08-03T12:35:26+00:00" - }, - { - "name": "sebastian/object-reflector", - "version": "1.1.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "773f97c67f28de00d397be301821b06708fca0be" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", - "reference": "773f97c67f28de00d397be301821b06708fca0be", - "shasum": "" - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Allows reflection of object attributes, including inherited and non-public ones", - "homepage": "https://github.com/sebastianbergmann/object-reflector/", - "time": "2017-03-29T09:07:27+00:00" - }, - { - "name": "sebastian/recursion-context", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", - "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", - "shasum": "" - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - } - ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "time": "2017-03-03T06:23:57+00:00" - }, - { - "name": "sebastian/resource-operations", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", - "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", - "shasum": "" - }, - "require": { - "php": ">=5.6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides a list of PHP built-in functions that operate on resources", - "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "time": "2015-07-28T20:34:47+00:00" - }, - { - "name": "sebastian/version", - "version": "2.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", - "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", - "shasum": "" - }, - "require": { - "php": ">=5.6" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version", - "time": "2016-10-03T07:35:21+00:00" - }, - { - "name": "symfony/polyfill-ctype", - "version": "v1.14.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "fbdeaec0df06cf3d51c93de80c7eb76e271f5a38" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/fbdeaec0df06cf3d51c93de80c7eb76e271f5a38", - "reference": "fbdeaec0df06cf3d51c93de80c7eb76e271f5a38", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "suggest": { - "ext-ctype": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.14-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for ctype functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "ctype", - "polyfill", - "portable" - ], - "time": "2020-01-13T11:15:53+00:00" - }, - { - "name": "theseer/tokenizer", - "version": "1.1.3", - "source": { - "type": "git", - "url": "https://github.com/theseer/tokenizer.git", - "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/11336f6f84e16a720dae9d8e6ed5019efa85a0f9", - "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": "^7.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - } - ], - "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", - "time": "2019-06-13T22:48:21+00:00" - }, - { - "name": "webmozart/assert", - "version": "1.7.0", - "source": { - "type": "git", - "url": "https://github.com/webmozart/assert.git", - "reference": "aed98a490f9a8f78468232db345ab9cf606cf598" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/aed98a490f9a8f78468232db345ab9cf606cf598", - "reference": "aed98a490f9a8f78468232db345ab9cf606cf598", - "shasum": "" - }, - "require": { - "php": "^5.3.3 || ^7.0", - "symfony/polyfill-ctype": "^1.8" - }, - "conflict": { - "vimeo/psalm": "<3.6.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.36 || ^7.5.13" - }, - "type": "library", - "autoload": { - "psr-4": { - "Webmozart\\Assert\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Assertions to validate method input/output with nice error messages.", - "keywords": [ - "assert", - "check", - "validate" - ], - "time": "2020-02-14T12:15:55+00:00" - } - ], + "packages-dev": [], "aliases": [], "minimum-stability": "dev", "stability-flags": { diff --git a/doc/travis-ci-apache.conf b/doc/travis-ci-apache.conf deleted file mode 100644 index 1703920bb4..0000000000 --- a/doc/travis-ci-apache.conf +++ /dev/null @@ -1,27 +0,0 @@ - - # https://docs.travis-ci.com/user/languages/php/#apache--php - - DocumentRoot %TRAVIS_BUILD_DIR% - - # tests assume EGroupware to be under /egroupware not docroot - Alias /egroupware %TRAVIS_BUILD_DIR% - - - Options FollowSymLinks MultiViews ExecCGI - AllowOverride All - Require all granted - - - # Wire up Apache to use Travis CI's php-fpm. - - AddHandler php5-fcgi .php - Action php5-fcgi /php5-fcgi - Alias /php5-fcgi /usr/lib/cgi-bin/php5-fcgi - FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -host 127.0.0.1:9000 -pass-header Authorization - - - Require all granted - - - - \ No newline at end of file diff --git a/setup/inc/class.setup.inc.php b/setup/inc/class.setup.inc.php index fc0013785b..e332a071ac 100644 --- a/setup/inc/class.setup.inc.php +++ b/setup/inc/class.setup.inc.php @@ -253,7 +253,6 @@ class setup case PHP_SESSION_DISABLED: throw new \ErrorException('EGroupware requires PHP session extension!'); case PHP_SESSION_NONE: - if (headers_sent()) return false; ini_set('session.use_cookie', true); session_name(self::SESSIONID); session_set_cookie_params(0, '/', self::cookiedomain(), diff --git a/setup/inc/functions.inc.php b/setup/inc/functions.inc.php index b8261eebee..e24cbd8a9f 100644 --- a/setup/inc/functions.inc.php +++ b/setup/inc/functions.inc.php @@ -25,9 +25,9 @@ $GLOBALS['egw_info'] = array( 'currentapp' => 'setup', 'noapi' => True )); -if(file_exists(__DIR__.'/../../header.inc.php')) +if(file_exists('../header.inc.php')) { - include_once(__DIR__.'/../../header.inc.php'); + include('../header.inc.php'); } // for an old header we need to setup a reference for the domains if (!is_array($GLOBALS['egw_domain'])) $GLOBALS['egw_domain'] =& $GLOBALS['phpgw_domain']; @@ -56,17 +56,14 @@ require_once(EGW_INCLUDE_ROOT . '/api/src/loader/common.php'); * function to handle multilanguage support * */ -if (!function_exists('lang')) +function lang($key,$vars=null) { - function lang($key, $vars = null) + if(!is_array($vars)) { - if (!is_array($vars)) - { - $vars = func_get_args(); - array_shift($vars); // remove $key - } - return $GLOBALS['egw_setup']->translation->translate("$key", $vars); + $vars = func_get_args(); + array_shift($vars); // remove $key } + return $GLOBALS['egw_setup']->translation->translate("$key", $vars); } if(file_exists(EGW_SERVER_ROOT.'/api/setup/setup.inc.php'))