1
0
Fork 0
mirror of https://github.com/YunoHost-Apps/kanboard_ynh.git synced 2024-09-03 19:36:17 +02:00

Download dependencies during installation

Upgrade to 1.0.36
This commit is contained in:
Jimmy Monin 2017-01-02 10:38:16 +01:00
parent 5eadb538b0
commit 6e4f673ca9
1311 changed files with 85 additions and 118352 deletions

68
scripts/_common.sh Normal file
View file

@ -0,0 +1,68 @@
#
# Common variables
#
# Application version
VERSION="1.0.36"
# Remote URL to fetch application source tarball
APPLICATION_SOURCE_URL="https://github.com/kanboard/kanboard/archive/v${VERSION}.tar.gz"
#
# Common helpers
#
# Download and extract application sources to the given directory
# usage: extract_application_to DESTDIR
extract_application() {
local DESTDIR=$1
rc_tarball="${DESTDIR}/application.tar.gz"
wget -q -O "$rc_tarball" "$APPLICATION_SOURCE_URL" \
|| ynh_die "Unable to download application tarball"
tar xf "$rc_tarball" -C "$DESTDIR" --strip-components 1 \
|| ynh_die "Unable to extract application tarball"
rm "$rc_tarball"
}
# Execute a command as another user
# usage: exec_as USER COMMAND [ARG ...]
exec_as() {
local USER=$1
shift 1
if [[ $USER = $(whoami) ]]; then
eval $@
else
# use sudo twice to be root and be allowed to use another user
sudo sudo -u "$USER" $@
fi
}
# Execute a composer command from a given directory
# usage: composer_exec AS_USER WORKDIR COMMAND [ARG ...]
exec_composer() {
local AS_USER=$1
local WORKDIR=$2
shift 2
exec_as "$AS_USER" COMPOSER_HOME="${WORKDIR}/.composer" \
php "${WORKDIR}/composer.phar" $@ \
-d "${WORKDIR}" --quiet --no-interaction
}
# Install and initialize Composer in the given directory
# usage: init_composer DESTDIR [AS_USER]
init_composer() {
local DESTDIR=$1
local AS_USER=${2:-admin}
# install composer
curl -sS https://getcomposer.org/installer \
| exec_as "$AS_USER" COMPOSER_HOME="${DESTDIR}/.composer" \
php -- --quiet --install-dir="$DESTDIR" \
|| ynh_die "Unable to install Composer"
# update dependencies to create composer.lock
exec_composer "$AS_USER" "$DESTDIR" install --no-dev \
|| ynh_die "Unable to update application core dependencies"
}

View file

@ -4,6 +4,9 @@ set -eu
app="kanboard"
# Source local helpers
source ./_common.sh
# Source app helpers
source /usr/share/yunohost/helpers
@ -42,17 +45,12 @@ ynh_app_setting_set $app mysqlpwd $dbpass
ynh_app_setting_set $app adminusername $admin
ynh_app_setting_set $app is_public $is_public
# Download sources
sudo wget -q https://github.com/kanboard/kanboard/archive/v1.0.35.zip -O kanboard.zip
# Create tmp directory and install app inside
TMPDIR=$(ynh_mkdir_tmp)
extract_application "$TMPDIR"
init_composer "$TMPDIR"
# Uncompress
sudo unzip -qq kanboard.zip -d ..
# Copy sources
sudo mkdir -p $DESTDIR
sudo cp -a ../kanboard*/. $DESTDIR
# Copy dependencies
sudo cp -a ../sources/. ${DESTDIR}
sudo mv "$TMPDIR" "$DESTDIR"
# Copy and edit config.php
sudo cp ../conf/config.php ${DESTDIR}

View file

@ -4,6 +4,9 @@ set -eu
app="kanboard"
# Source local helpers
source ./_common.sh
# Set app specific variables
dbname=$app
dbuser=$app
@ -36,20 +39,16 @@ sudo rm -rf /var/lib/php5/session/*
# Move old app dir
sudo mv ${DESTDIR} ${DESTDIR}.old
sudo mkdir -p ${DESTDIR}
# Create tmp directory and install app inside
TMPDIR=$(ynh_mkdir_tmp)
extract_application "$TMPDIR"
init_composer "$TMPDIR"
# Download sources
sudo wget -q https://github.com/kanboard/kanboard/archive/v1.0.35.zip -O kanboard.zip
sudo mv "$TMPDIR" "$DESTDIR"
# Uncompress
sudo unzip -qq kanboard.zip -d ..
# Copy sources
sudo cp -a ../kanboard*/. ${DESTDIR}
# Copy dependencies
sudo cp -a ../sources/. ${DESTDIR}
# restore data
sudo cp -a ${DESTDIR}.old/data ${DESTDIR}
# restore plugins
if [ -e ${DESTDIR}.old/plugins ]
then

View file

@ -1,7 +0,0 @@
<?php
// autoload.php @generated by Composer
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInit2cd1f3bd373661a524b2e9ae060681e4::getLoader();

View file

@ -1 +0,0 @@
../fguillot/picofeed/picofeed

View file

@ -1,3 +0,0 @@
composer.lock
build/
vendor/

View file

@ -1,14 +0,0 @@
before_commands:
- "composer install --prefer-dist"
tools:
php_mess_detector: true
php_code_sniffer: true
php_analyzer: true
sensiolabs_security_checker: true
php_code_coverage: true
php_cpd: true
php_pdepend:
excluded_dirs: [vendor/, tests/*]
filter:
excluded_paths: [vendor/]

View file

@ -1,19 +0,0 @@
language: php
php:
- 5.3
- 5.4
- 5.5
- 5.6
- hhvm
before_script:
- composer install
before_script:
- curl -s http://getcomposer.org/installer | php
- php composer.phar update --dev --no-interaction
- mkdir -p build/logs
script:
- php vendor/bin/phpunit --coverage-text

View file

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

View file

@ -1,60 +0,0 @@
base32
======
Base32 Encoder/Decoder for PHP according to RFC 4648
[![Build Status](https://secure.travis-ci.org/ChristianRiesen/base32.png)](http://travis-ci.org/ChristianRiesen/base32)
[![HHVM Status](http://hhvm.h4cc.de/badge/christian-riesen/base32.png)](http://hhvm.h4cc.de/package/christian-riesen/base32)
[![Latest Stable Version](https://poser.pugx.org/christian-riesen/base32/v/stable.png)](https://packagist.org/packages/christian-riesen/base32) [![Total Downloads](https://poser.pugx.org/christian-riesen/base32/downloads.png)](https://packagist.org/packages/christian-riesen/base32) [![Latest Unstable Version](https://poser.pugx.org/christian-riesen/base32/v/unstable.png)](https://packagist.org/packages/christian-riesen/base32) [![License](https://poser.pugx.org/christian-riesen/base32/license.png)](https://packagist.org/packages/christian-riesen/base32)
Do you like this? Flattr it:
[![Flattr base32](http://api.flattr.com/button/flattr-badge-large.png)](http://flattr.com/thing/720563/ChristianRiesenbase32-on-GitHub)
Usage
-----
<?php
// Include class or user autoloader
use Base32\Base32;
$string = 'fooba';
$encoded = Base32::encode($string);
// $encoded contains now 'MZXW6YTB'
$decoded = Base32::decode($encoded);
// $decoded is again 'fooba'
About
=====
Use
---
Initially created to work with the [one time password project](https://github.com/ChristianRiesen/otp), yet it can stand alone just as well as [Jordi Boggiano](http://seld.be/) kindly pointed out. It's the only Base32 implementation I could make work that passes the test vectors (and contains unit tests).
Goal
----
Have a RFC compliant Base32 encoder and decoder. The implementation could be improved, but for now, it does the job and has unit tests. Ideally, the class can be enhanced while the unit tests keep passing.
Requirements
------------
PHP 5.3.x+
If you want to run the tests, PHPUnit 3.6 or up is required.
Author
------
Christian Riesen <chris.riesen@gmail.com> http://christianriesen.com
Acknowledgements
----------------
Base32 is mostly based on the work of https://github.com/NTICompass/PHP-Base32

View file

@ -1,130 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="christianriesen-base32" default="build">
<target name="build" depends="prepare,lint,phploc,pdepend,phpmd-ci,phpcs-ci,phpcpd,phpunit,phpcb"/>
<target name="build-parallel" depends="prepare,lint,tools-parallel,phpunit,phpcb"/>
<target name="tools-parallel" description="Run tools in parallel">
<parallel threadCount="2">
<sequential>
<antcall target="pdepend"/>
<antcall target="phpmd-ci"/>
</sequential>
<antcall target="phpcpd"/>
<antcall target="phpcs-ci"/>
<antcall target="phploc"/>
</parallel>
</target>
<target name="clean" description="Cleanup build artifacts">
<delete dir="${basedir}/build/code-browser"/>
<delete dir="${basedir}/build/coverage"/>
<delete dir="${basedir}/build/logs"/>
<delete dir="${basedir}/build/pdepend"/>
<exec executable="bash">
<arg value="-c" />
<arg value="curl -s http://getcomposer.org/installer | php" />
</exec>
<exec executable="php">
<arg value="composer.phar" />
<arg value="install" />
</exec>
</target>
<target name="prepare" depends="clean" description="Prepare for build">
<mkdir dir="${basedir}/build/code-browser"/>
<mkdir dir="${basedir}/build/coverage"/>
<mkdir dir="${basedir}/build/logs"/>
<mkdir dir="${basedir}/build/pdepend"/>
</target>
<target name="lint" description="Perform syntax check of sourcecode files">
<apply executable="php" failonerror="true">
<arg value="-l"/>
<fileset dir="${basedir}/src">
<include name="**/*.php"/>
<modified/>
</fileset>
<fileset dir="${basedir}/tests">
<include name="**/*.php"/>
<modified/>
</fileset>
</apply>
</target>
<target name="phploc" description="Measure project size using PHPLOC">
<exec executable="phploc">
<arg value="--log-csv"/>
<arg value="${basedir}/build/logs/phploc.csv"/>
<arg path="${basedir}/src"/>
</exec>
</target>
<target name="pdepend" description="Calculate software metrics using PHP_Depend">
<exec executable="pdepend">
<arg value="--jdepend-xml=${basedir}/build/logs/jdepend.xml"/>
<arg value="--jdepend-chart=${basedir}/build/pdepend/dependencies.svg"/>
<arg value="--overview-pyramid=${basedir}/build/pdepend/overview-pyramid.svg"/>
<arg path="${basedir}/src"/>
</exec>
</target>
<target name="phpmd" description="Perform project mess detection using PHPMD and print human readable output. Intended for usage on the command line before committing.">
<exec executable="phpmd">
<arg path="${basedir}/src"/>
<arg value="text"/>
<arg value="${basedir}/build/phpmd.xml"/>
</exec>
</target>
<target name="phpmd-ci" description="Perform project mess detection using PHPMD creating a log file for the continuous integration server">
<exec executable="phpmd">
<arg path="${basedir}/src"/>
<arg value="xml"/>
<arg value="${basedir}/build/phpmd.xml"/>
<arg value="--reportfile"/>
<arg value="${basedir}/build/logs/pmd.xml"/>
</exec>
</target>
<target name="phpcs" description="Find coding standard violations using PHP_CodeSniffer and print human readable output. Intended for usage on the command line before committing.">
<exec executable="phpcs">
<arg value="--standard=${basedir}/build/phpcs.xml"/>
<arg path="${basedir}/src"/>
</exec>
</target>
<target name="phpcs-ci" description="Find coding standard violations using PHP_CodeSniffer creating a log file for the continuous integration server">
<exec executable="phpcs" output="/dev/null">
<arg value="--report=checkstyle"/>
<arg value="--report-file=${basedir}/build/logs/checkstyle.xml"/>
<arg value="--standard=${basedir}/build/phpcs.xml"/>
<arg path="${basedir}/src"/>
</exec>
</target>
<target name="phpcpd" description="Find duplicate code using PHPCPD">
<exec executable="phpcpd">
<arg value="--log-pmd"/>
<arg value="${basedir}/build/logs/pmd-cpd.xml"/>
<arg path="${basedir}/src"/>
</exec>
</target>
<target name="phpunit" description="Run unit tests with PHPUnit">
<exec executable="phpunit" failonerror="true"/>
</target>
<target name="phpcb" description="Aggregate tool output with PHP_CodeBrowser">
<exec executable="phpcb">
<arg value="--log"/>
<arg path="${basedir}/build/logs"/>
<arg value="--source"/>
<arg path="${basedir}/src"/>
<arg value="--output"/>
<arg path="${basedir}/build/code-browser"/>
</exec>
</target>
</project>

View file

@ -1,33 +0,0 @@
{
"name": "christian-riesen/base32",
"type": "library",
"description": "Base32 encoder/decoder according to RFC 4648",
"keywords": ["base32","encode","decode","rfc4648"],
"homepage": "https://github.com/ChristianRiesen/base32",
"license": "MIT",
"authors": [
{
"name": "Christian Riesen",
"email": "chris.riesen@gmail.com",
"homepage": "http://christianriesen.com",
"role": "Developer"
}
],
"require": {
"php": ">=5.3.0"
},
"require-dev": {
"phpunit/phpunit": "4.*",
"satooshi/php-coveralls": "0.*"
},
"autoload": {
"psr-4": {
"Base32\\": "src/"
}
},
"extra": {
"branch-alias": {
"dev-master": "1.1.x-dev"
}
}
}

View file

@ -1,32 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
backupGlobals="false"
backupStaticAttributes="false"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false"
bootstrap="tests/bootstrap.php"
colors="true">
<testsuites>
<testsuite name="Base32 Test Suite">
<directory suffix="Test.php">tests/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">src/</directory>
</whitelist>
</filter>
<logging>
<log type="coverage-html" target="build/coverage" title="Base32"
charset="UTF-8" yui="true" highlight="true"
lowUpperBound="35" highLowerBound="70"/>
<log type="coverage-clover" target="build/logs/clover.xml"/>
<log type="junit" target="build/logs/junit.xml" logIncompleteSkipped="false"/>
</logging>
</phpunit>

View file

@ -1,146 +0,0 @@
<?php
namespace Base32;
/**
* Base32 encoder and decoder
*
* Last update: 2012-06-20
*
* RFC 4648 compliant
* @link http://www.ietf.org/rfc/rfc4648.txt
*
* Some groundwork based on this class
* https://github.com/NTICompass/PHP-Base32
*
* @author Christian Riesen <chris.riesen@gmail.com>
* @link http://christianriesen.com
* @license MIT License see LICENSE file
*/
class Base32
{
/**
* Alphabet for encoding and decoding base32
*
* @var array
*/
private static $alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=';
/**
* Creates an array from a binary string into a given chunk size
*
* @param string $binaryString String to chunk
* @param integer $bits Number of bits per chunk
* @return array
*/
private static function chunk($binaryString, $bits)
{
$binaryString = chunk_split($binaryString, $bits, ' ');
if (substr($binaryString, (strlen($binaryString)) - 1) == ' ') {
$binaryString = substr($binaryString, 0, strlen($binaryString)-1);
}
return explode(' ', $binaryString);
}
/**
* Encodes into base32
*
* @param string $string Clear text string
* @return string Base32 encoded string
*/
public static function encode($string)
{
if (strlen($string) == 0) {
// Gives an empty string
return '';
}
// Convert string to binary
$binaryString = '';
foreach (str_split($string) as $s) {
// Return each character as an 8-bit binary string
$binaryString .= sprintf('%08b', ord($s));
}
// Break into 5-bit chunks, then break that into an array
$binaryArray = self::chunk($binaryString, 5);
// Pad array to be divisible by 8
while (count($binaryArray) % 8 !== 0) {
$binaryArray[] = null;
}
$base32String = '';
// Encode in base32
foreach ($binaryArray as $bin) {
$char = 32;
if (!is_null($bin)) {
// Pad the binary strings
$bin = str_pad($bin, 5, 0, STR_PAD_RIGHT);
$char = bindec($bin);
}
// Base32 character
$base32String .= self::$alphabet[$char];
}
return $base32String;
}
/**
* Decodes base32
*
* @param string $base32String Base32 encoded string
* @return string Clear text string
*/
public static function decode($base32String)
{
// Only work in upper cases
$base32String = strtoupper($base32String);
// Remove anything that is not base32 alphabet
$pattern = '/[^A-Z2-7]/';
$base32String = preg_replace($pattern, '', $base32String);
if (strlen($base32String) == 0) {
// Gives an empty string
return '';
}
$base32Array = str_split($base32String);
$string = '';
foreach ($base32Array as $str) {
$char = strpos(self::$alphabet, $str);
// Ignore the padding character
if ($char !== 32) {
$string .= sprintf('%05b', $char);
}
}
while (strlen($string) %8 !== 0) {
$string = substr($string, 0, strlen($string)-1);
}
$binaryArray = self::chunk($string, 8);
$realString = '';
foreach ($binaryArray as $bin) {
// Pad each value to 8 bits
$bin = str_pad($bin, 8, 0, STR_PAD_RIGHT);
// Convert binary strings to ASCII
$realString .= chr(bindec($bin));
}
return $realString;
}
}

View file

@ -1,51 +0,0 @@
<?php
namespace Base32;
use Base32\Base32;
/**
* Base32 test case.
*/
class Base32Test extends \PHPUnit_Framework_TestCase
{
/**
* Tests Base32->decode()
*
* Testing test vectors according to RFC 4648
* http://www.ietf.org/rfc/rfc4648.txt
*/
public function testDecode()
{
// RFC test vectors say that empty string returns empty string
$this->assertEquals('', Base32::decode(''));
// these strings are taken from the RFC
$this->assertEquals('f', Base32::decode('MY======'));
$this->assertEquals('fo', Base32::decode('MZXQ===='));
$this->assertEquals('foo', Base32::decode('MZXW6==='));
$this->assertEquals('foob', Base32::decode('MZXW6YQ='));
$this->assertEquals('fooba', Base32::decode('MZXW6YTB'));
$this->assertEquals('foobar', Base32::decode('MZXW6YTBOI======'));
// Decoding a string made up entirely of invalid characters
$this->assertEquals('', Base32::decode('8908908908908908'));
}
/**
* Encoder tests, reverse of the decodes
*/
public function testEncode()
{
// RFC test vectors say that empty string returns empty string
$this->assertEquals('', Base32::encode(''));
// these strings are taken from the RFC
$this->assertEquals('MY======', Base32::encode('f'));
$this->assertEquals('MZXQ====', Base32::encode('fo'));
$this->assertEquals('MZXW6===', Base32::encode('foo'));
$this->assertEquals('MZXW6YQ=', Base32::encode('foob'));
$this->assertEquals('MZXW6YTB', Base32::encode('fooba'));
$this->assertEquals('MZXW6YTBOI======', Base32::encode('foobar'));
}
}

View file

@ -1,5 +0,0 @@
<?php
$loader = require __DIR__ . '/../vendor/autoload.php';
$loader->add("Base32", __DIR__);
$loader->register();

View file

@ -1,5 +0,0 @@
.svn
/.buildpath
/.project
/.settings

View file

@ -1,11 +0,0 @@
language: php
php:
- 5.3
- 5.4
- 5.5
- 5.6
- 7.0
script: phpunit

View file

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

View file

@ -1,105 +0,0 @@
One Time Passwords
==================
[![Build Status](https://secure.travis-ci.org/ChristianRiesen/otp.png)](http://travis-ci.org/ChristianRiesen/otp)
Did you like this? Flattr it:
[![Flattr otp](http://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/thing/719284/ChristianRiesenotp-on-GitHub)
Installation
------------
Use [composer](http://getcomposer.org/) and require the library in your `composer.json`
{
"require": {
"christian-riesen/otp": "1.*",
}
}
Usage
-----
```php
<?php
use Otp\Otp;
use Otp\GoogleAuthenticator;
// Seperate class, see https://github.com/ChristianRiesen/base32
use Base32\Base32;
// Get a Pseudo Secret
// Defaults to 16 characters
$secret = GoogleAuthenticator::generateRandom();
// Url for the QR code
// Using totp method
$url = GoogleAuthenticator::getQrCodeUrl('totp', 'Label like user@host.com', $secret);
// Save the secret with the users account
// Display QR Code to the user
// Now how to check
$otp = new Otp();
// $key is a 6 digit number, coming from the User
// Assuming this is present and sanitized
// Allows for a 1 code time drift by default
// Third parameter can alter that behavior
if ($otp->checkTotp(Base32::decode($secret), $key)) {
// Correct key
// IMPORTANT! Note this key as being used
// so nobody could launch a replay attack.
// Cache that for the next minutes and you
// should be good.
} else {
// Wrong key
}
// Just to create a key for display (testing)
$key = $otp->totp($secret);
```
Sample script in `example` folder. Requires sessions to work (for secret storage).
Class Otp
---------
Implements hotp according to [RFC4226](https://tools.ietf.org/html/rfc4226) and totp according to [RFC6238](https://tools.ietf.org/html/rfc6238) (only sha1 algorithm). Once you have a secret, you can use it directly in this class to create the passwords themselves (mainly for debugging use) or use the check functions to safely check the validity of the keys. The `checkTotp` function also includes a helper to battle timedrift.
Class GoogleAuthenticator
-------------------------
Static function class to generate a correct url for the QR code, so you can easy scan it with your device. Google Authenticator is avaiaible as application for iPhone and Android. This removes the burden to create such an app from the developers of websites by using this set of classes.
There are also older open source versions of the Google Authenticator app for both [iPhone](https://github.com/google/google-authenticator) and [Android](https://github.com/google/google-authenticator-android)
This helper class uses the random_int function from PHP7, or the polyfill method from [paragonie/random_compat](https://packagist.org/packages/paragonie/random_compat) if present and falls back on other (less "secure") random generators.
About
=====
Requirements
------------
PHP 5.3.x+
Uses [Base32 class](https://github.com/ChristianRiesen/base32).
If you want to run the tests, PHPUnit 3.6 or up is required.
Author
------
Christian Riesen <chris.riesen@gmail.com> http://christianriesen.com
Acknowledgements
----------------
The classes have been inspired by many different places that were talking about otp and Google Authenticator. Thank you all for your help.
Project setup ideas blantently taken from https://github.com/Seldaek/monolog

View file

@ -1,28 +0,0 @@
{
"name": "christian-riesen/otp",
"type": "library",
"description": "One Time Passwords, hotp and totp according to RFC4226 and RFC6238",
"keywords": ["otp","hotp","totp","googleauthenticator","rfc4226","rfc6238"],
"homepage": "https://github.com/ChristianRiesen/otp",
"license": "MIT",
"authors": [
{
"name": "Christian Riesen",
"email": "chris.riesen@gmail.com",
"homepage": "http://christianriesen.com",
"role": "Developer"
}
],
"require": {
"php": ">=5.3.0",
"christian-riesen/base32": ">=1.0"
},
"suggest": {
"paragonie/random_compat": "Optional polyfill for a more secure random generator for pre PHP7 versions"
},
"autoload": {
"psr-0": {
"Otp": "src"
}
}
}

View file

@ -1,100 +0,0 @@
<?php
session_start(); // using it as storage temporary
require_once __DIR__ . '/../vendor/autoload.php';
use Otp\Otp;
use Otp\GoogleAuthenticator;
use Base32\Base32;
// Getting a secret, either by generating or from storage
// DON'T use sessions as storage for this in production!!!
$secret = 0;
if (isset($_SESSION['otpsecret'])) {
$secret = $_SESSION['otpsecret'];
}
if (strlen($secret) != 16) {
$secret = GoogleAuthenticator::generateRandom();
$_SESSION['otpsecret'] = $secret;
}
// The secret is now an easy stored Base32 string.
// To use it in totp though we need to decode it into the original
$otp = new Otp();
$currentTotp = $otp->totp(Base32::decode($secret));
$qrCode = GoogleAuthenticator::getQrCodeUrl('totp', 'otpsample@cr', $secret);
$keyUri = GoogleAuthenticator::getKeyUri('totp', 'otpsample@cr', $secret);
?><html>
<head>
<title>One Time Passwords Example</title>
</head>
<body>
<h1>One Time Passwords Example</h1>
Secret is <?php echo $secret; ?>. This is saved with the users credentials.
<br />
<br />
<hr />
QR Code for totp:<br />
<img src="<?php echo $qrCode; ?>" />
<br />
This QR Code contains the Key URI: <?php echo $keyUri; ?>
<br />
<hr />
Current totp would be <?php echo $currentTotp; ?><br />
<br />
<hr />
Because of timedrift, you could technically enter a code before or after it
would actually be used. This form uses the checkTotp function. To test this,
open this page, wait until the key changes once or twice (not more) on your
Google Authenticator, then hit submit. Even though the key is "wrong" because of
small time differences, you can still use it.
<form action="" method="post">
<input type="text" name="otpkey" value="<?php echo $currentTotp; ?>" /><br />
<input type="submit">
</form>
<br />
Output:<br />
<br />
<?php
if (isset($_POST['otpkey'])) {
// Sanatizing, this should take care of it
$key = preg_replace('/[^0-9]/', '', $_POST['otpkey']);
// Standard is 6 for keys, but can be changed with setDigits on $otp
if (strlen($key) == 6) {
// Remember that the secret is a base32 string that needs decoding
// to use it here!
if ($otp->checkTotp(Base32::decode($secret), $key)) {
echo 'Key correct!';
// Add here something that makes note of this key and will not allow
// the use of it, for this user for the next 2 minutes. This way you
// prevent a replay attack. Otherwise your OTP is missing one of the
// key features it can bring in security to your application!
} else {
echo 'Wrong key!';
}
} else {
echo 'Key not the correct size';
}
}
?>
</body>
</html>

View file

@ -1,15 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit colors="true">
<testsuites>
<testsuite name="Otp Test Suite">
<directory>tests/Otp/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">src/Otp/</directory>
</whitelist>
</filter>
</phpunit>

View file

@ -1,189 +0,0 @@
<?php
namespace Otp;
/**
* Google Authenticator
*
* Last update: 2014-08-19
*
* Can be easy used with Google Authenticator
* @link https://code.google.com/p/google-authenticator/
*
* @author Christian Riesen <chris.riesen@gmail.com>
* @link http://christianriesen.com
* @license MIT License see LICENSE file
*/
class GoogleAuthenticator
{
protected static $allowedTypes = array('hotp', 'totp');
protected static $height = 200;
protected static $width = 200;
/**
* Returns the Key URI
*
* Format of encoded url is here:
* https://code.google.com/p/google-authenticator/wiki/KeyUriFormat
* Should be done in a better fashion
*
* @param string $type totp or hotp
* @param string $label Label to display this as to the user
* @param string $secret Base32 encoded secret
* @param integer $counter Required by hotp, otherwise ignored
* @param array $options Optional fields that will be set if present
*
* @return string Key URI
*/
public static function getKeyUri($type, $label, $secret, $counter = null, $options = array())
{
// two types only..
if (!in_array($type, self::$allowedTypes)) {
throw new \InvalidArgumentException('Type has to be of allowed types list');
}
// Label can't be empty
$label = trim($label);
if (strlen($label) < 1) {
throw new \InvalidArgumentException('Label has to be one or more printable characters');
}
if (substr_count($label, ':') > 2) {
throw new \InvalidArgumentException('Account name contains illegal colon characters');
}
// Secret needs to be here
if (strlen($secret) < 1) {
throw new \InvalidArgumentException('No secret present');
}
// check for counter on hotp
if ($type == 'hotp' && is_null($counter)) {
throw new \InvalidArgumentException('Counter required for hotp');
}
// This is the base, these are at least required
$otpauth = 'otpauth://' . $type . '/' . str_replace(array(':', ' '), array('%3A', '%20'), $label) . '?secret=' . rawurlencode($secret);
if ($type == 'hotp' && !is_null($counter)) {
$otpauth .= '&counter=' . intval($counter);
}
// Now check the options array
// algorithm (currently ignored by Authenticator)
// Defaults to SHA1
if (array_key_exists('algorithm', $options)) {
$otpauth .= '&algorithm=' . rawurlencode($options['algorithm']);
}
// digits (currently ignored by Authenticator)
// Defaults to 6
if (array_key_exists('digits', $options) && intval($options['digits']) !== 6 && intval($options['digits']) !== 8) {
throw new \InvalidArgumentException('Digits can only have the values 6 or 8, ' . $options['digits'] . ' given');
} elseif (array_key_exists('digits', $options)) {
$otpauth .= '&digits=' . intval($options['digits']);
}
// period, only for totp (currently ignored by Authenticator)
// Defaults to 30
if ($type == 'totp' && array_key_exists('period', $options)) {
$otpauth .= '&period=' . rawurlencode($options['period']);
}
// issuer
// Defaults to none
if (array_key_exists('issuer', $options)) {
$otpauth .= '&issuer=' . rawurlencode($options['issuer']);
}
return $otpauth;
}
/**
* Returns the QR code url
*
* Format of encoded url is here:
* https://code.google.com/p/google-authenticator/wiki/KeyUriFormat
* Should be done in a better fashion
*
* @param string $type totp or hotp
* @param string $label Label to display this as to the user
* @param string $secret Base32 encoded secret
* @param integer $counter Required by hotp, otherwise ignored
* @param array $options Optional fields that will be set if present
*
* @return string URL to the QR code
*/
public static function getQrCodeUrl($type, $label, $secret, $counter = null, $options = array())
{
// Width and height can be overwritten
$width = self::$width;
if (array_key_exists('width', $options) && is_numeric($options['width'])) {
$width = $options['width'];
}
$height = self::$height;
if (array_key_exists('height', $options) && is_numeric($options['height'])) {
$height = $options['height'];
}
$otpauth = self::getKeyUri($type, $label, $secret, $counter, $options);
$url = 'https://chart.googleapis.com/chart?chs=' . $width . 'x'
. $height . '&cht=qr&chld=M|0&chl=' . urlencode($otpauth);
return $url;
}
/**
* Creates a pseudo random Base32 string
*
* This could decode into anything. It's located here as a small helper
* where code that might need base32 usually also needs something like this.
*
* @param integer $length Exact length of output string
* @return string Base32 encoded random
*/
public static function generateRandom($length = 16)
{
$keys = array_merge(range('A','Z'), range(2,7)); // No padding char
$string = '';
for ($i = 0; $i < $length; $i++) {
$string .= $keys[self::getRand()];
}
return $string;
}
/**
* Get random number
*
* @return int Random number between 0 and 31 (including)
*/
private static function getRand()
{
if (function_exists('random_int')) {
// Uses either the PHP7 internal function or the polyfill if present
return random_int(0, 31);
} elseif (function_exists('openssl_random_pseudo_bytes')) {
$bytes = openssl_random_pseudo_bytes(2);
$number = hexdec(bin2hex($bytes));
if ($number > 31) {
$number = $number % 32;
}
return $number;
} else {
return mt_rand(0, 31);
}
}
}

View file

@ -1,310 +0,0 @@
<?php
namespace Otp;
/**
* One Time Passwords
*
* Last update: 2012-06-16
*
* Implements HOTP and TOTP
*
* HMAC-Based One-time Password(HOTP) algorithm specified in RFC 4226
* @link https://tools.ietf.org/html/rfc4226
*
* Time-based One-time Password (TOTP) algorithm specified in RFC 6238
* @link https://tools.ietf.org/html/rfc6238
*
* As a note: This code is NOT 2038 proof! The min concern is the function
* getBinaryCounter that uses the pack function which can't handle 64bit yet.
*
* Can be easy used with Google Authenticator
* @link https://code.google.com/p/google-authenticator/
*
* @author Christian Riesen <chris.riesen@gmail.com>
* @link http://christianriesen.com
* @license MIT License see LICENSE file
*/
class Otp implements OtpInterface
{
/**
* The digits the code can have
*
* Either 6 or 8.
* Authenticator does only support 6.
*
* @var integer
*/
protected $digits = 6;
/**
* Time in seconds one counter period is long
*
* @var integer
*/
protected $period = 30;
/**
* Possible algorithms
*
* @var array
*/
protected $allowedAlgorithms = array('sha1', 'sha256', 'sha512');
/**
* Currently used algorithm
*
* @var string
*/
protected $algorithm = 'sha1';
/* (non-PHPdoc)
* @see Otp.OtpInterface::hotp()
*/
public function hotp($secret, $counter)
{
if (!is_numeric($counter)) {
throw new \InvalidArgumentException('Counter must be integer');
}
$hash = hash_hmac(
$this->algorithm,
$this->getBinaryCounter($counter),
$secret,
true
);
return str_pad($this->truncate($hash), $this->digits, '0', STR_PAD_LEFT);
}
/* (non-PHPdoc)
* @see Otp.OtpInterface::totp()
*/
public function totp($secret, $timecounter = null)
{
if (is_null($timecounter)) {
$timecounter = $this->getTimecounter();
}
return $this->hotp($secret, $timecounter);
}
/* (non-PHPdoc)
* @see Otp.OtpInterface::checkHotp()
*/
public function checkHotp($secret, $counter, $key)
{
return $this->safeCompare($this->hotp($secret, $counter), $key);
}
/* (non-PHPdoc)
* @see Otp.OtpInterface::checkTotp()
*/
public function checkTotp($secret, $key, $timedrift = 1)
{
if (!is_numeric($timedrift) || $timedrift < 0) {
throw new \InvalidArgumentException('Invalid timedrift supplied');
}
// Counter comes from time now
// Also we check the current timestamp as well as previous and future ones
// according to $timerange
$timecounter = $this->getTimecounter();
$start = $timecounter - ($timedrift);
$end = $timecounter + ($timedrift);
// We first try the current, as it is the most likely to work
if ($this->safeCompare($this->totp($secret, $timecounter), $key)) {
return true;
} elseif ($timedrift == 0) {
// When timedrift is 0, this is the end of the checks
return false;
}
// Well, that didn't work, so try the others
for ($t = $start; $t <= $end; $t = $t + 1) {
if ($t == $timecounter) {
// Already tried that one
continue;
}
if ($this->safeCompare($this->totp($secret, $t), $key)) {
return true;
}
}
// if none worked, then return false
return false;
}
/**
* Changing the used algorithm for hashing
*
* Can only be one of the algorithms in the allowedAlgorithms property.
*
* @param string $algorithm
* @throws \InvalidArgumentException
* @return \Otp\Otp
*/
/*
* This has been disabled since it does not bring the expected results
* according to the RFC test vectors for sha256 or sha512.
* Until that is fixed, the algorithm simply stays at sha1.
* Google Authenticator does not support sha256 and sha512 at the moment.
*
public function setAlgorithm($algorithm)
{
if (!in_array($algorithm, $this->allowedAlgorithms)) {
throw new \InvalidArgumentException('Not an allowed algorithm: ' . $algorithm);
}
$this->algorithm = $algorithm;
return $this;
}
// */
/**
* Get the algorithms name (lowercase)
*
* @return string
*/
public function getAlgorithm()
{
return $this->algorithm;
}
/**
* Setting period lenght for totp
*
* @param integer $period
* @throws \InvalidArgumentException
* @return \Otp\Otp
*/
public function setPeriod($period)
{
if (!is_int($period)) {
throw new \InvalidArgumentException('Period must be an integer');
}
$this->period = $period;
return $this;
}
/**
* Returns the set period value
*
* @return integer
*/
public function getPeriod()
{
return $this->period;
}
/**
* Setting number of otp digits
*
* @param integer $digits Number of digits for the otp (6 or 8)
* @throws \InvalidArgumentException
* @return \Otp\Otp
*/
public function setDigits($digits)
{
if (!in_array($digits, array(6, 8))) {
throw new \InvalidArgumentException('Digits must be 6 or 8');
}
$this->digits = $digits;
return $this;
}
/**
* Returns number of digits in the otp
*
* @return integer
*/
public function getDigits()
{
return $this->digits;
}
/**
* Generates a binary counter for hashing
*
* Warning: Not 2038 safe. Maybe until then pack supports 64bit.
*
* @param integer $counter Counter in integer form
* @return string Binary string
*/
protected function getBinaryCounter($counter)
{
return pack('N*', 0) . pack('N*', $counter);
}
/**
* Generating time counter
*
* This is the time divided by 30 by default.
*
* @return integer Time counter
*/
protected function getTimecounter()
{
return floor(time() / $this->period);
}
/**
* Creates the basic number for otp from hash
*
* This number is left padded with zeros to the required length by the
* calling function.
*
* @param string $hash hmac hash
* @return number
*/
protected function truncate($hash)
{
$offset = ord($hash[19]) & 0xf;
return (
((ord($hash[$offset+0]) & 0x7f) << 24 ) |
((ord($hash[$offset+1]) & 0xff) << 16 ) |
((ord($hash[$offset+2]) & 0xff) << 8 ) |
(ord($hash[$offset+3]) & 0xff)
) % pow(10, $this->digits);
}
/**
* Safely compares two inputs
*
* Assumed inputs are numbers and strings.
* Compares them in a time linear manner. No matter how much you guess
* correct of the partial content, it does not change the time it takes to
* run the entire comparison.
*
* @param mixed $a
* @param mixed $b
* @return boolean
*/
protected function safeCompare($a, $b)
{
$sha1a = sha1($a);
$sha1b = sha1($b);
// Now the compare is always the same length. Even considering minute
// time differences in sha1 creation, all you know is that a longer
// input takes longer to hash, not how long the actual compared value is
$result = 0;
for ($i = 0; $i < 40; $i++) {
$result |= ord($sha1a[$i]) ^ ord($sha1b[$i]);
}
return $result == 0;
}
}

View file

@ -1,65 +0,0 @@
<?php
namespace Otp;
/**
* Interface for HOTP and TOTP
*
* Last update: 2012-06-16
*
* HMAC-Based One-time Password(HOTP) algorithm specified in RFC 4226
* @link https://tools.ietf.org/html/rfc4226
*
* Time-based One-time Password (TOTP) algorithm specified in RFC 6238
* @link https://tools.ietf.org/html/rfc6238
*
* @author Christian Riesen <chris.riesen@gmail.com>
* @link http://christianriesen.com
* @license MIT License see LICENSE file
*/
interface OtpInterface
{
/**
* Returns OTP using the HOTP algorithm
*
* @param string $secret
* @param integer $counter
* @return string One Time Password
*/
function hotp($secret, $counter);
/**
* Returns OTP using the TOTP algorithm
*
* @param string $secret
* @param integer $timecounter Optional: Uses current time if null
* @return string One Time Password
*/
function totp($secret, $timecounter = null);
/**
* Checks Hotp against a key
*
* This is a helper function, but is here to ensure the Totp can be checked
* in the same manner.
*
* @param string $secret
* @param integer $counter
* @param string $key
*
* @return boolean If key is correct
*/
function checkHotp($secret, $counter, $key);
/**
* Checks Totp agains a key
*
*
* @param string $secret
* @param integer $key
* @param integer $timedrift
*
* @return boolean If key is correct
*/
function checkTotp($secret, $key, $timedrift = 1);
}

View file

@ -1,88 +0,0 @@
<?php
require_once __DIR__ . '/../../src/Otp/GoogleAuthenticator.php';
use Otp\GoogleAuthenticator;
/**
* GoogleAuthenticator test case.
*/
class GoogleAuthenticatorTest extends \PHPUnit_Framework_TestCase
{
/**
* Tests getQrCodeUrl
*/
public function testGetQrCodeUrl()
{
$secret = 'MEP3EYVA6XNFNVNM'; // testing secret
// Standard totp case
$this->assertEquals(
'https://chart.googleapis.com/chart?chs=200x200&cht=qr&chld=M|0&chl=otpauth%3A%2F%2Ftotp%2Fuser%40host.com%3Fsecret%3DMEP3EYVA6XNFNVNM',
GoogleAuthenticator::getQrCodeUrl('totp', 'user@host.com', $secret)
);
// hotp (include a counter)
$this->assertEquals(
'https://chart.googleapis.com/chart?chs=200x200&cht=qr&chld=M|0&chl=otpauth%3A%2F%2Fhotp%2Fuser%40host.com%3Fsecret%3DMEP3EYVA6XNFNVNM%26counter%3D1234',
GoogleAuthenticator::getQrCodeUrl('hotp', 'user@host.com', $secret, 1234)
);
// totp, this time with a parameter for chaning the size of the QR
$this->assertEquals(
'https://chart.googleapis.com/chart?chs=300x300&cht=qr&chld=M|0&chl=otpauth%3A%2F%2Ftotp%2Fuser%40host.com%3Fsecret%3DMEP3EYVA6XNFNVNM',
GoogleAuthenticator::getQrCodeUrl('totp', 'user@host.com', $secret, null, array('height' => 300, 'width' => 300))
);
}
/**
* Tests getKeyUri
*/
public function testGetKeyUri()
{
$secret = 'MEP3EYVA6XNFNVNM'; // testing secret
// Standard totp case
$this->assertEquals(
'otpauth://totp/user@host.com?secret=MEP3EYVA6XNFNVNM',
GoogleAuthenticator::getKeyUri('totp', 'user@host.com', $secret)
);
// hotp (include a counter)
$this->assertEquals(
'otpauth://hotp/user@host.com?secret=MEP3EYVA6XNFNVNM&counter=1234',
GoogleAuthenticator::getKeyUri('hotp', 'user@host.com', $secret, 1234)
);
// totp/hotp with an issuer in the label
$this->assertEquals(
'otpauth://hotp/issuer%3Auser@host.com?secret=MEP3EYVA6XNFNVNM&counter=1234',
GoogleAuthenticator::getKeyUri('hotp', 'issuer:user@host.com', $secret, 1234)
);
// totp/hotp with an issuer and spaces in the label
$this->assertEquals(
'otpauth://hotp/an%20issuer%3A%20user@host.com?secret=MEP3EYVA6XNFNVNM&counter=1234',
GoogleAuthenticator::getKeyUri('hotp', 'an issuer: user@host.com', $secret, 1234)
);
// totp/hotp with an issuer as option
$this->assertEquals(
'otpauth://hotp/an%20issuer%3Auser@host.com?secret=MEP3EYVA6XNFNVNM&counter=1234&issuer=an%20issuer',
GoogleAuthenticator::getKeyUri('hotp', 'an issuer:user@host.com', $secret, 1234, array('issuer' => 'an issuer'))
);
}
/**
* Tests generateRandom
*/
public function testGenerateRandom()
{
// contains numbers 2-7 and letters A-Z in large letters, 16 chars long
$this->assertRegExp('/[2-7A-Z]{16}/', GoogleAuthenticator::generateRandom());
// Can be told to make a longer secret
$this->assertRegExp('/[2-7A-Z]{18}/', GoogleAuthenticator::generateRandom(18));
}
}

View file

@ -1,124 +0,0 @@
<?php
require_once __DIR__ . '/../../src/Otp/OtpInterface.php';
require_once __DIR__ . '/../../src/Otp/Otp.php';
use Otp\Otp;
/**
* Otp test case.
*/
class OtpTest extends \PHPUnit_Framework_TestCase
{
/**
*
* @var Otp
*/
private $Otp;
private $secret = "12345678901234567890";
/**
* Prepares the environment before running a test.
*/
protected function setUp()
{
parent::setUp();
$this->Otp = new Otp();
}
/**
* Cleans up the environment after running a test.
*/
protected function tearDown()
{
$this->Otp = null;
parent::tearDown();
}
/**
* Tests Otp->hotp()
*
* Using test vectors from RFC
* https://tools.ietf.org/html/rfc4226
*/
public function testHotpRfc()
{
$secret = $this->secret;
$this->assertEquals('755224', $this->Otp->hotp($secret, 0));
$this->assertEquals('287082', $this->Otp->hotp($secret, 1));
$this->assertEquals('359152', $this->Otp->hotp($secret, 2));
$this->assertEquals('969429', $this->Otp->hotp($secret, 3));
$this->assertEquals('338314', $this->Otp->hotp($secret, 4));
$this->assertEquals('254676', $this->Otp->hotp($secret, 5));
$this->assertEquals('287922', $this->Otp->hotp($secret, 6));
$this->assertEquals('162583', $this->Otp->hotp($secret, 7));
$this->assertEquals('399871', $this->Otp->hotp($secret, 8));
$this->assertEquals('520489', $this->Otp->hotp($secret, 9));
}
/**
* Tests TOTP general construction
*
* Still uses the hotp function, but since totp is a bit more special, has
* its own tests
* Using test vectors from RFC
* https://tools.ietf.org/html/rfc6238
*/
public function testTotpRfc()
{
$secret = $this->secret;
// Test vectors are in 8 digits
$this->Otp->setDigits(8);
// The time presented in the test vector has to be first divided through 30
// to count as the key
// SHA 1 grouping
$this->assertEquals('94287082', $this->Otp->hotp($secret, floor(59/30)), 'sha1 with time 59');
$this->assertEquals('07081804', $this->Otp->hotp($secret, floor(1111111109/30)), 'sha1 with time 1111111109');
$this->assertEquals('14050471', $this->Otp->hotp($secret, floor(1111111111/30)), 'sha1 with time 1111111111');
$this->assertEquals('89005924', $this->Otp->hotp($secret, floor(1234567890/30)), 'sha1 with time 1234567890');
$this->assertEquals('69279037', $this->Otp->hotp($secret, floor(2000000000/30)), 'sha1 with time 2000000000');
$this->assertEquals('65353130', $this->Otp->hotp($secret, floor(20000000000/30)), 'sha1 with time 20000000000');
/*
The following tests do NOT pass.
Once the otp class can deal with these correctly, they can be used again.
They are here for completeness test vectors from the RFC.
// SHA 256 grouping
$this->Otp->setAlgorithm('sha256');
$this->assertEquals('46119246', $this->Otp->hotp($secret, floor(59/30)), 'sha256 with time 59');
$this->assertEquals('07081804', $this->Otp->hotp($secret, floor(1111111109/30)), 'sha256 with time 1111111109');
$this->assertEquals('14050471', $this->Otp->hotp($secret, floor(1111111111/30)), 'sha256 with time 1111111111');
$this->assertEquals('89005924', $this->Otp->hotp($secret, floor(1234567890/30)), 'sha256 with time 1234567890');
$this->assertEquals('69279037', $this->Otp->hotp($secret, floor(2000000000/30)), 'sha256 with time 2000000000');
$this->assertEquals('65353130', $this->Otp->hotp($secret, floor(20000000000/30)), 'sha256 with time 20000000000');
// SHA 512 grouping
$this->Otp->setAlgorithm('sha512');
$this->assertEquals('90693936', $this->Otp->hotp($secret, floor(59/30)), 'sha512 with time 59');
$this->assertEquals('25091201', $this->Otp->hotp($secret, floor(1111111109/30)), 'sha512 with time 1111111109');
$this->assertEquals('99943326', $this->Otp->hotp($secret, floor(1111111111/30)), 'sha512 with time 1111111111');
$this->assertEquals('93441116', $this->Otp->hotp($secret, floor(1234567890/30)), 'sha512 with time 1234567890');
$this->assertEquals('38618901', $this->Otp->hotp($secret, floor(2000000000/30)), 'sha512 with time 2000000000');
$this->assertEquals('47863826', $this->Otp->hotp($secret, floor(20000000000/30)), 'sha512 with time 20000000000');
*/
}
/**
* @expectedException InvalidArgumentException
* @expectedExceptionMessage Counter must be integer
*/
public function testHotpInvalidCounter()
{
$this->Otp->hotp($this->secret, 'a');
}
}

View file

@ -1,441 +0,0 @@
<?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\Autoload;
/**
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
*
* $loader = new \Composer\Autoload\ClassLoader();
*
* // register classes with namespaces
* $loader->add('Symfony\Component', __DIR__.'/component');
* $loader->add('Symfony', __DIR__.'/framework');
*
* // activate the autoloader
* $loader->register();
*
* // to enable searching the include path (eg. for PEAR packages)
* $loader->setUseIncludePath(true);
*
* In this example, if you try to use a class in the Symfony\Component
* namespace or one of its children (Symfony\Component\Console for instance),
* the autoloader will first look for the class under the component/
* directory, and it will then fallback to the framework/ directory if not
* found before giving up.
*
* This class is loosely based on the Symfony UniversalClassLoader.
*
* @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/
*/
class ClassLoader
{
// PSR-4
private $prefixLengthsPsr4 = array();
private $prefixDirsPsr4 = array();
private $fallbackDirsPsr4 = array();
// PSR-0
private $prefixesPsr0 = array();
private $fallbackDirsPsr0 = array();
private $useIncludePath = false;
private $classMap = array();
private $classMapAuthoritative = false;
private $missingClasses = array();
private $apcuPrefix;
public function getPrefixes()
{
if (!empty($this->prefixesPsr0)) {
return call_user_func_array('array_merge', $this->prefixesPsr0);
}
return array();
}
public function getPrefixesPsr4()
{
return $this->prefixDirsPsr4;
}
public function getFallbackDirs()
{
return $this->fallbackDirsPsr0;
}
public function getFallbackDirsPsr4()
{
return $this->fallbackDirsPsr4;
}
public function getClassMap()
{
return $this->classMap;
}
/**
* @param array $classMap Class to filename map
*/
public function addClassMap(array $classMap)
{
if ($this->classMap) {
$this->classMap = array_merge($this->classMap, $classMap);
} else {
$this->classMap = $classMap;
}
}
/**
* 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
*/
public function add($prefix, $paths, $prepend = false)
{
if (!$prefix) {
if ($prepend) {
$this->fallbackDirsPsr0 = array_merge(
(array) $paths,
$this->fallbackDirsPsr0
);
} else {
$this->fallbackDirsPsr0 = array_merge(
$this->fallbackDirsPsr0,
(array) $paths
);
}
return;
}
$first = $prefix[0];
if (!isset($this->prefixesPsr0[$first][$prefix])) {
$this->prefixesPsr0[$first][$prefix] = (array) $paths;
return;
}
if ($prepend) {
$this->prefixesPsr0[$first][$prefix] = array_merge(
(array) $paths,
$this->prefixesPsr0[$first][$prefix]
);
} else {
$this->prefixesPsr0[$first][$prefix] = array_merge(
$this->prefixesPsr0[$first][$prefix],
(array) $paths
);
}
}
/**
* 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
*
* @throws \InvalidArgumentException
*/
public function addPsr4($prefix, $paths, $prepend = false)
{
if (!$prefix) {
// Register directories for the root namespace.
if ($prepend) {
$this->fallbackDirsPsr4 = array_merge(
(array) $paths,
$this->fallbackDirsPsr4
);
} else {
$this->fallbackDirsPsr4 = array_merge(
$this->fallbackDirsPsr4,
(array) $paths
);
}
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
// Register directories for a new namespace.
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
} elseif ($prepend) {
// Prepend directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
(array) $paths,
$this->prefixDirsPsr4[$prefix]
);
} else {
// Append directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
$this->prefixDirsPsr4[$prefix],
(array) $paths
);
}
}
/**
* 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
*/
public function set($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr0 = (array) $paths;
} else {
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
}
}
/**
* 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
*
* @throws \InvalidArgumentException
*/
public function setPsr4($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr4 = (array) $paths;
} else {
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
}
}
/**
* Turns on searching the include path for class files.
*
* @param bool $useIncludePath
*/
public function setUseIncludePath($useIncludePath)
{
$this->useIncludePath = $useIncludePath;
}
/**
* Can be used to check if the autoloader uses the include path to check
* for classes.
*
* @return bool
*/
public function getUseIncludePath()
{
return $this->useIncludePath;
}
/**
* Turns off searching the prefix and fallback directories for classes
* that have not been registered with the class map.
*
* @param bool $classMapAuthoritative
*/
public function setClassMapAuthoritative($classMapAuthoritative)
{
$this->classMapAuthoritative = $classMapAuthoritative;
}
/**
* Should class lookup fail if not found in the current class map?
*
* @return bool
*/
public function isClassMapAuthoritative()
{
return $this->classMapAuthoritative;
}
/**
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
*
* @param string|null $apcuPrefix
*/
public function setApcuPrefix($apcuPrefix)
{
$this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null;
}
/**
* The APCu prefix in use, or null if APCu caching is not enabled.
*
* @return string|null
*/
public function getApcuPrefix()
{
return $this->apcuPrefix;
}
/**
* Registers this instance as an autoloader.
*
* @param bool $prepend Whether to prepend the autoloader or not
*/
public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
}
/**
* Unregisters this instance as an autoloader.
*/
public function unregister()
{
spl_autoload_unregister(array($this, 'loadClass'));
}
/**
* Loads the given class or interface.
*
* @param string $class The name of the class
* @return bool|null True if loaded, null otherwise
*/
public function loadClass($class)
{
if ($file = $this->findFile($class)) {
includeFile($file);
return true;
}
}
/**
* Finds the path to the file where the class is defined.
*
* @param string $class The name of the class
*
* @return string|false The path if found, false otherwise
*/
public function findFile($class)
{
// class map lookup
if (isset($this->classMap[$class])) {
return $this->classMap[$class];
}
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
return false;
}
if (null !== $this->apcuPrefix) {
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
if ($hit) {
return $file;
}
}
$file = $this->findFileWithExtension($class, '.php');
// Search for Hack files if we are running on HHVM
if (false === $file && defined('HHVM_VERSION')) {
$file = $this->findFileWithExtension($class, '.hh');
}
if (null !== $this->apcuPrefix) {
apcu_add($this->apcuPrefix.$class, $file);
}
if (false === $file) {
// Remember that this class does not exist.
$this->missingClasses[$class] = true;
}
return $file;
}
private function findFileWithExtension($class, $ext)
{
// PSR-4 lookup
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
$first = $class[0];
if (isset($this->prefixLengthsPsr4[$first])) {
foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) {
if (0 === strpos($class, $prefix)) {
foreach ($this->prefixDirsPsr4[$prefix] as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
return $file;
}
}
}
}
}
// PSR-4 fallback dirs
foreach ($this->fallbackDirsPsr4 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
return $file;
}
}
// PSR-0 lookup
if (false !== $pos = strrpos($class, '\\')) {
// namespaced class name
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
} else {
// PEAR-like class name
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
}
if (isset($this->prefixesPsr0[$first])) {
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
if (0 === strpos($class, $prefix)) {
foreach ($dirs as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
}
}
}
// PSR-0 fallback dirs
foreach ($this->fallbackDirsPsr0 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
// PSR-0 include paths.
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
return $file;
}
return false;
}
}
/**
* Scope isolated include.
*
* Prevents access to $this/self from included files.
*/
function includeFile($file)
{
include $file;
}

View file

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

View file

@ -1,866 +0,0 @@
<?php
// autoload_classmap.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'Base32\\Base32' => $vendorDir . '/christian-riesen/base32/src/Base32.php',
'Eluceo\\iCal\\Component' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/Component.php',
'Eluceo\\iCal\\Component\\Alarm' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/Component/Alarm.php',
'Eluceo\\iCal\\Component\\Calendar' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/Component/Calendar.php',
'Eluceo\\iCal\\Component\\Event' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/Component/Event.php',
'Eluceo\\iCal\\Component\\Timezone' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/Component/Timezone.php',
'Eluceo\\iCal\\Component\\TimezoneRule' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/Component/TimezoneRule.php',
'Eluceo\\iCal\\ParameterBag' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/ParameterBag.php',
'Eluceo\\iCal\\Property' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/Property.php',
'Eluceo\\iCal\\PropertyBag' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/PropertyBag.php',
'Eluceo\\iCal\\Property\\ArrayValue' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/Property/ArrayValue.php',
'Eluceo\\iCal\\Property\\DateTimeProperty' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/Property/DateTimeProperty.php',
'Eluceo\\iCal\\Property\\DateTimesProperty' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/Property/DateTimesProperty.php',
'Eluceo\\iCal\\Property\\Event\\Attendees' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/Property/Event/Attendees.php',
'Eluceo\\iCal\\Property\\Event\\Description' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/Property/Event/Description.php',
'Eluceo\\iCal\\Property\\Event\\Organizer' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/Property/Event/Organizer.php',
'Eluceo\\iCal\\Property\\Event\\RecurrenceId' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/Property/Event/RecurrenceId.php',
'Eluceo\\iCal\\Property\\Event\\RecurrenceRule' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/Property/Event/RecurrenceRule.php',
'Eluceo\\iCal\\Property\\StringValue' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/Property/StringValue.php',
'Eluceo\\iCal\\Property\\ValueInterface' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/Property/ValueInterface.php',
'Eluceo\\iCal\\Util\\ComponentUtil' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/Util/ComponentUtil.php',
'Eluceo\\iCal\\Util\\DateUtil' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/Util/DateUtil.php',
'Eluceo\\iCal\\Util\\PropertyValueUtil' => $vendorDir . '/eluceo/ical/src/Eluceo/iCal/Util/PropertyValueUtil.php',
'Gregwar\\Captcha\\CaptchaBuilder' => $vendorDir . '/gregwar/captcha/CaptchaBuilder.php',
'Gregwar\\Captcha\\CaptchaBuilderInterface' => $vendorDir . '/gregwar/captcha/CaptchaBuilderInterface.php',
'Gregwar\\Captcha\\ImageFileHandler' => $vendorDir . '/gregwar/captcha/ImageFileHandler.php',
'Gregwar\\Captcha\\PhraseBuilder' => $vendorDir . '/gregwar/captcha/PhraseBuilder.php',
'Gregwar\\Captcha\\PhraseBuilderInterface' => $vendorDir . '/gregwar/captcha/PhraseBuilderInterface.php',
'JsonRPC\\Client' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Client.php',
'JsonRPC\\Exception\\AccessDeniedException' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Exception/AccessDeniedException.php',
'JsonRPC\\Exception\\AuthenticationFailureException' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Exception/AuthenticationFailureException.php',
'JsonRPC\\Exception\\ConnectionFailureException' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Exception/ConnectionFailureException.php',
'JsonRPC\\Exception\\InvalidJsonFormatException' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Exception/InvalidJsonFormatException.php',
'JsonRPC\\Exception\\InvalidJsonRpcFormatException' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Exception/InvalidJsonRpcFormatException.php',
'JsonRPC\\Exception\\ResponseEncodingFailureException' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Exception/ResponseEncodingFailureException.php',
'JsonRPC\\Exception\\ResponseException' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Exception/ResponseException.php',
'JsonRPC\\Exception\\ServerErrorException' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Exception/ServerErrorException.php',
'JsonRPC\\HttpClient' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/HttpClient.php',
'JsonRPC\\MiddlewareHandler' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/MiddlewareHandler.php',
'JsonRPC\\MiddlewareInterface' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/MiddlewareInterface.php',
'JsonRPC\\ProcedureHandler' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/ProcedureHandler.php',
'JsonRPC\\Request\\BatchRequestParser' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Request/BatchRequestParser.php',
'JsonRPC\\Request\\RequestBuilder' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Request/RequestBuilder.php',
'JsonRPC\\Request\\RequestParser' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Request/RequestParser.php',
'JsonRPC\\Response\\ResponseBuilder' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Response/ResponseBuilder.php',
'JsonRPC\\Response\\ResponseParser' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Response/ResponseParser.php',
'JsonRPC\\Server' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Server.php',
'JsonRPC\\Validator\\HostValidator' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Validator/HostValidator.php',
'JsonRPC\\Validator\\JsonEncodingValidator' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Validator/JsonEncodingValidator.php',
'JsonRPC\\Validator\\JsonFormatValidator' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Validator/JsonFormatValidator.php',
'JsonRPC\\Validator\\RpcFormatValidator' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Validator/RpcFormatValidator.php',
'JsonRPC\\Validator\\UserValidator' => $vendorDir . '/fguillot/json-rpc/src/JsonRPC/Validator/UserValidator.php',
'Kanboard\\Action\\Base' => $baseDir . '/app/Action/Base.php',
'Kanboard\\Action\\CommentCreation' => $baseDir . '/app/Action/CommentCreation.php',
'Kanboard\\Action\\CommentCreationMoveTaskColumn' => $baseDir . '/app/Action/CommentCreationMoveTaskColumn.php',
'Kanboard\\Action\\TaskAssignCategoryColor' => $baseDir . '/app/Action/TaskAssignCategoryColor.php',
'Kanboard\\Action\\TaskAssignCategoryLabel' => $baseDir . '/app/Action/TaskAssignCategoryLabel.php',
'Kanboard\\Action\\TaskAssignCategoryLink' => $baseDir . '/app/Action/TaskAssignCategoryLink.php',
'Kanboard\\Action\\TaskAssignColorCategory' => $baseDir . '/app/Action/TaskAssignColorCategory.php',
'Kanboard\\Action\\TaskAssignColorColumn' => $baseDir . '/app/Action/TaskAssignColorColumn.php',
'Kanboard\\Action\\TaskAssignColorLink' => $baseDir . '/app/Action/TaskAssignColorLink.php',
'Kanboard\\Action\\TaskAssignColorPriority' => $baseDir . '/app/Action/TaskAssignColorPriority.php',
'Kanboard\\Action\\TaskAssignColorSwimlane' => $baseDir . '/app/Action/TaskAssignColorSwimlane.php',
'Kanboard\\Action\\TaskAssignColorUser' => $baseDir . '/app/Action/TaskAssignColorUser.php',
'Kanboard\\Action\\TaskAssignCurrentUser' => $baseDir . '/app/Action/TaskAssignCurrentUser.php',
'Kanboard\\Action\\TaskAssignCurrentUserColumn' => $baseDir . '/app/Action/TaskAssignCurrentUserColumn.php',
'Kanboard\\Action\\TaskAssignDueDateOnCreation' => $baseDir . '/app/Action/TaskAssignDueDateOnCreation.php',
'Kanboard\\Action\\TaskAssignPrioritySwimlane' => $baseDir . '/app/Action/TaskAssignPrioritySwimlane.php',
'Kanboard\\Action\\TaskAssignSpecificUser' => $baseDir . '/app/Action/TaskAssignSpecificUser.php',
'Kanboard\\Action\\TaskAssignUser' => $baseDir . '/app/Action/TaskAssignUser.php',
'Kanboard\\Action\\TaskClose' => $baseDir . '/app/Action/TaskClose.php',
'Kanboard\\Action\\TaskCloseColumn' => $baseDir . '/app/Action/TaskCloseColumn.php',
'Kanboard\\Action\\TaskCloseNoActivity' => $baseDir . '/app/Action/TaskCloseNoActivity.php',
'Kanboard\\Action\\TaskCloseNoActivityColumn' => $baseDir . '/app/Action/TaskCloseNoActivityColumn.php',
'Kanboard\\Action\\TaskCloseNotMovedColumn' => $baseDir . '/app/Action/TaskCloseNotMovedColumn.php',
'Kanboard\\Action\\TaskCreation' => $baseDir . '/app/Action/TaskCreation.php',
'Kanboard\\Action\\TaskDuplicateAnotherProject' => $baseDir . '/app/Action/TaskDuplicateAnotherProject.php',
'Kanboard\\Action\\TaskEmail' => $baseDir . '/app/Action/TaskEmail.php',
'Kanboard\\Action\\TaskEmailNoActivity' => $baseDir . '/app/Action/TaskEmailNoActivity.php',
'Kanboard\\Action\\TaskMoveAnotherProject' => $baseDir . '/app/Action/TaskMoveAnotherProject.php',
'Kanboard\\Action\\TaskMoveColumnAssigned' => $baseDir . '/app/Action/TaskMoveColumnAssigned.php',
'Kanboard\\Action\\TaskMoveColumnCategoryChange' => $baseDir . '/app/Action/TaskMoveColumnCategoryChange.php',
'Kanboard\\Action\\TaskMoveColumnClosed' => $baseDir . '/app/Action/TaskMoveColumnClosed.php',
'Kanboard\\Action\\TaskMoveColumnNotMovedPeriod' => $baseDir . '/app/Action/TaskMoveColumnNotMovedPeriod.php',
'Kanboard\\Action\\TaskMoveColumnUnAssigned' => $baseDir . '/app/Action/TaskMoveColumnUnAssigned.php',
'Kanboard\\Action\\TaskOpen' => $baseDir . '/app/Action/TaskOpen.php',
'Kanboard\\Action\\TaskUpdateStartDate' => $baseDir . '/app/Action/TaskUpdateStartDate.php',
'Kanboard\\Analytic\\AverageLeadCycleTimeAnalytic' => $baseDir . '/app/Analytic/AverageLeadCycleTimeAnalytic.php',
'Kanboard\\Analytic\\AverageTimeSpentColumnAnalytic' => $baseDir . '/app/Analytic/AverageTimeSpentColumnAnalytic.php',
'Kanboard\\Analytic\\EstimatedTimeComparisonAnalytic' => $baseDir . '/app/Analytic/EstimatedTimeComparisonAnalytic.php',
'Kanboard\\Analytic\\TaskDistributionAnalytic' => $baseDir . '/app/Analytic/TaskDistributionAnalytic.php',
'Kanboard\\Analytic\\UserDistributionAnalytic' => $baseDir . '/app/Analytic/UserDistributionAnalytic.php',
'Kanboard\\Api\\Authorization\\ActionAuthorization' => $baseDir . '/app/Api/Authorization/ActionAuthorization.php',
'Kanboard\\Api\\Authorization\\CategoryAuthorization' => $baseDir . '/app/Api/Authorization/CategoryAuthorization.php',
'Kanboard\\Api\\Authorization\\ColumnAuthorization' => $baseDir . '/app/Api/Authorization/ColumnAuthorization.php',
'Kanboard\\Api\\Authorization\\CommentAuthorization' => $baseDir . '/app/Api/Authorization/CommentAuthorization.php',
'Kanboard\\Api\\Authorization\\ProcedureAuthorization' => $baseDir . '/app/Api/Authorization/ProcedureAuthorization.php',
'Kanboard\\Api\\Authorization\\ProjectAuthorization' => $baseDir . '/app/Api/Authorization/ProjectAuthorization.php',
'Kanboard\\Api\\Authorization\\SubtaskAuthorization' => $baseDir . '/app/Api/Authorization/SubtaskAuthorization.php',
'Kanboard\\Api\\Authorization\\TagAuthorization' => $baseDir . '/app/Api/Authorization/TagAuthorization.php',
'Kanboard\\Api\\Authorization\\TaskAuthorization' => $baseDir . '/app/Api/Authorization/TaskAuthorization.php',
'Kanboard\\Api\\Authorization\\TaskFileAuthorization' => $baseDir . '/app/Api/Authorization/TaskFileAuthorization.php',
'Kanboard\\Api\\Authorization\\TaskLinkAuthorization' => $baseDir . '/app/Api/Authorization/TaskLinkAuthorization.php',
'Kanboard\\Api\\Authorization\\UserAuthorization' => $baseDir . '/app/Api/Authorization/UserAuthorization.php',
'Kanboard\\Api\\Middleware\\AuthenticationMiddleware' => $baseDir . '/app/Api/Middleware/AuthenticationMiddleware.php',
'Kanboard\\Api\\Procedure\\ActionProcedure' => $baseDir . '/app/Api/Procedure/ActionProcedure.php',
'Kanboard\\Api\\Procedure\\AppProcedure' => $baseDir . '/app/Api/Procedure/AppProcedure.php',
'Kanboard\\Api\\Procedure\\BaseProcedure' => $baseDir . '/app/Api/Procedure/BaseProcedure.php',
'Kanboard\\Api\\Procedure\\BoardProcedure' => $baseDir . '/app/Api/Procedure/BoardProcedure.php',
'Kanboard\\Api\\Procedure\\CategoryProcedure' => $baseDir . '/app/Api/Procedure/CategoryProcedure.php',
'Kanboard\\Api\\Procedure\\ColumnProcedure' => $baseDir . '/app/Api/Procedure/ColumnProcedure.php',
'Kanboard\\Api\\Procedure\\CommentProcedure' => $baseDir . '/app/Api/Procedure/CommentProcedure.php',
'Kanboard\\Api\\Procedure\\GroupMemberProcedure' => $baseDir . '/app/Api/Procedure/GroupMemberProcedure.php',
'Kanboard\\Api\\Procedure\\GroupProcedure' => $baseDir . '/app/Api/Procedure/GroupProcedure.php',
'Kanboard\\Api\\Procedure\\LinkProcedure' => $baseDir . '/app/Api/Procedure/LinkProcedure.php',
'Kanboard\\Api\\Procedure\\MeProcedure' => $baseDir . '/app/Api/Procedure/MeProcedure.php',
'Kanboard\\Api\\Procedure\\ProjectFileProcedure' => $baseDir . '/app/Api/Procedure/ProjectFileProcedure.php',
'Kanboard\\Api\\Procedure\\ProjectPermissionProcedure' => $baseDir . '/app/Api/Procedure/ProjectPermissionProcedure.php',
'Kanboard\\Api\\Procedure\\ProjectProcedure' => $baseDir . '/app/Api/Procedure/ProjectProcedure.php',
'Kanboard\\Api\\Procedure\\SubtaskProcedure' => $baseDir . '/app/Api/Procedure/SubtaskProcedure.php',
'Kanboard\\Api\\Procedure\\SubtaskTimeTrackingProcedure' => $baseDir . '/app/Api/Procedure/SubtaskTimeTrackingProcedure.php',
'Kanboard\\Api\\Procedure\\SwimlaneProcedure' => $baseDir . '/app/Api/Procedure/SwimlaneProcedure.php',
'Kanboard\\Api\\Procedure\\TagProcedure' => $baseDir . '/app/Api/Procedure/TagProcedure.php',
'Kanboard\\Api\\Procedure\\TaskExternalLinkProcedure' => $baseDir . '/app/Api/Procedure/TaskExternalLinkProcedure.php',
'Kanboard\\Api\\Procedure\\TaskFileProcedure' => $baseDir . '/app/Api/Procedure/TaskFileProcedure.php',
'Kanboard\\Api\\Procedure\\TaskLinkProcedure' => $baseDir . '/app/Api/Procedure/TaskLinkProcedure.php',
'Kanboard\\Api\\Procedure\\TaskMetadataProcedure' => $baseDir . '/app/Api/Procedure/TaskMetadataProcedure.php',
'Kanboard\\Api\\Procedure\\TaskProcedure' => $baseDir . '/app/Api/Procedure/TaskProcedure.php',
'Kanboard\\Api\\Procedure\\TaskTagProcedure' => $baseDir . '/app/Api/Procedure/TaskTagProcedure.php',
'Kanboard\\Api\\Procedure\\UserProcedure' => $baseDir . '/app/Api/Procedure/UserProcedure.php',
'Kanboard\\Auth\\ApiAccessTokenAuth' => $baseDir . '/app/Auth/ApiAccessTokenAuth.php',
'Kanboard\\Auth\\DatabaseAuth' => $baseDir . '/app/Auth/DatabaseAuth.php',
'Kanboard\\Auth\\LdapAuth' => $baseDir . '/app/Auth/LdapAuth.php',
'Kanboard\\Auth\\RememberMeAuth' => $baseDir . '/app/Auth/RememberMeAuth.php',
'Kanboard\\Auth\\ReverseProxyAuth' => $baseDir . '/app/Auth/ReverseProxyAuth.php',
'Kanboard\\Auth\\TotpAuth' => $baseDir . '/app/Auth/TotpAuth.php',
'Kanboard\\Console\\BaseCommand' => $baseDir . '/app/Console/BaseCommand.php',
'Kanboard\\Console\\CronjobCommand' => $baseDir . '/app/Console/CronjobCommand.php',
'Kanboard\\Console\\DatabaseMigrationCommand' => $baseDir . '/app/Console/DatabaseMigrationCommand.php',
'Kanboard\\Console\\DatabaseVersionCommand' => $baseDir . '/app/Console/DatabaseVersionCommand.php',
'Kanboard\\Console\\LocaleComparatorCommand' => $baseDir . '/app/Console/LocaleComparatorCommand.php',
'Kanboard\\Console\\LocaleSyncCommand' => $baseDir . '/app/Console/LocaleSyncCommand.php',
'Kanboard\\Console\\PluginInstallCommand' => $baseDir . '/app/Console/PluginInstallCommand.php',
'Kanboard\\Console\\PluginUninstallCommand' => $baseDir . '/app/Console/PluginUninstallCommand.php',
'Kanboard\\Console\\PluginUpgradeCommand' => $baseDir . '/app/Console/PluginUpgradeCommand.php',
'Kanboard\\Console\\ProjectDailyColumnStatsExportCommand' => $baseDir . '/app/Console/ProjectDailyColumnStatsExportCommand.php',
'Kanboard\\Console\\ProjectDailyStatsCalculationCommand' => $baseDir . '/app/Console/ProjectDailyStatsCalculationCommand.php',
'Kanboard\\Console\\ResetPasswordCommand' => $baseDir . '/app/Console/ResetPasswordCommand.php',
'Kanboard\\Console\\ResetTwoFactorCommand' => $baseDir . '/app/Console/ResetTwoFactorCommand.php',
'Kanboard\\Console\\SubtaskExportCommand' => $baseDir . '/app/Console/SubtaskExportCommand.php',
'Kanboard\\Console\\TaskExportCommand' => $baseDir . '/app/Console/TaskExportCommand.php',
'Kanboard\\Console\\TaskOverdueNotificationCommand' => $baseDir . '/app/Console/TaskOverdueNotificationCommand.php',
'Kanboard\\Console\\TaskTriggerCommand' => $baseDir . '/app/Console/TaskTriggerCommand.php',
'Kanboard\\Console\\TransitionExportCommand' => $baseDir . '/app/Console/TransitionExportCommand.php',
'Kanboard\\Console\\WorkerCommand' => $baseDir . '/app/Console/WorkerCommand.php',
'Kanboard\\Controller\\ActionController' => $baseDir . '/app/Controller/ActionController.php',
'Kanboard\\Controller\\ActionCreationController' => $baseDir . '/app/Controller/ActionCreationController.php',
'Kanboard\\Controller\\ActivityController' => $baseDir . '/app/Controller/ActivityController.php',
'Kanboard\\Controller\\AnalyticController' => $baseDir . '/app/Controller/AnalyticController.php',
'Kanboard\\Controller\\AppController' => $baseDir . '/app/Controller/AppController.php',
'Kanboard\\Controller\\AuthController' => $baseDir . '/app/Controller/AuthController.php',
'Kanboard\\Controller\\AvatarFileController' => $baseDir . '/app/Controller/AvatarFileController.php',
'Kanboard\\Controller\\BaseController' => $baseDir . '/app/Controller/BaseController.php',
'Kanboard\\Controller\\BoardAjaxController' => $baseDir . '/app/Controller/BoardAjaxController.php',
'Kanboard\\Controller\\BoardPopoverController' => $baseDir . '/app/Controller/BoardPopoverController.php',
'Kanboard\\Controller\\BoardTooltipController' => $baseDir . '/app/Controller/BoardTooltipController.php',
'Kanboard\\Controller\\BoardViewController' => $baseDir . '/app/Controller/BoardViewController.php',
'Kanboard\\Controller\\CalendarController' => $baseDir . '/app/Controller/CalendarController.php',
'Kanboard\\Controller\\CaptchaController' => $baseDir . '/app/Controller/CaptchaController.php',
'Kanboard\\Controller\\CategoryController' => $baseDir . '/app/Controller/CategoryController.php',
'Kanboard\\Controller\\ColumnController' => $baseDir . '/app/Controller/ColumnController.php',
'Kanboard\\Controller\\ColumnMoveRestrictionController' => $baseDir . '/app/Controller/ColumnMoveRestrictionController.php',
'Kanboard\\Controller\\ColumnRestrictionController' => $baseDir . '/app/Controller/ColumnRestrictionController.php',
'Kanboard\\Controller\\CommentController' => $baseDir . '/app/Controller/CommentController.php',
'Kanboard\\Controller\\ConfigController' => $baseDir . '/app/Controller/ConfigController.php',
'Kanboard\\Controller\\CurrencyController' => $baseDir . '/app/Controller/CurrencyController.php',
'Kanboard\\Controller\\CustomFilterController' => $baseDir . '/app/Controller/CustomFilterController.php',
'Kanboard\\Controller\\DashboardController' => $baseDir . '/app/Controller/DashboardController.php',
'Kanboard\\Controller\\DocumentationController' => $baseDir . '/app/Controller/DocumentationController.php',
'Kanboard\\Controller\\ExportController' => $baseDir . '/app/Controller/ExportController.php',
'Kanboard\\Controller\\ExternalTaskCreationController' => $baseDir . '/app/Controller/ExternalTaskCreationController.php',
'Kanboard\\Controller\\ExternalTaskViewController' => $baseDir . '/app/Controller/ExternalTaskViewController.php',
'Kanboard\\Controller\\FeedController' => $baseDir . '/app/Controller/FeedController.php',
'Kanboard\\Controller\\FileViewerController' => $baseDir . '/app/Controller/FileViewerController.php',
'Kanboard\\Controller\\GroupAjaxController' => $baseDir . '/app/Controller/GroupAjaxController.php',
'Kanboard\\Controller\\GroupCreationController' => $baseDir . '/app/Controller/GroupCreationController.php',
'Kanboard\\Controller\\GroupListController' => $baseDir . '/app/Controller/GroupListController.php',
'Kanboard\\Controller\\GroupModificationController' => $baseDir . '/app/Controller/GroupModificationController.php',
'Kanboard\\Controller\\ICalendarController' => $baseDir . '/app/Controller/ICalendarController.php',
'Kanboard\\Controller\\LinkController' => $baseDir . '/app/Controller/LinkController.php',
'Kanboard\\Controller\\OAuthController' => $baseDir . '/app/Controller/OAuthController.php',
'Kanboard\\Controller\\PasswordResetController' => $baseDir . '/app/Controller/PasswordResetController.php',
'Kanboard\\Controller\\PluginController' => $baseDir . '/app/Controller/PluginController.php',
'Kanboard\\Controller\\ProjectActionDuplicationController' => $baseDir . '/app/Controller/ProjectActionDuplicationController.php',
'Kanboard\\Controller\\ProjectCreationController' => $baseDir . '/app/Controller/ProjectCreationController.php',
'Kanboard\\Controller\\ProjectEditController' => $baseDir . '/app/Controller/ProjectEditController.php',
'Kanboard\\Controller\\ProjectFileController' => $baseDir . '/app/Controller/ProjectFileController.php',
'Kanboard\\Controller\\ProjectGanttController' => $baseDir . '/app/Controller/ProjectGanttController.php',
'Kanboard\\Controller\\ProjectListController' => $baseDir . '/app/Controller/ProjectListController.php',
'Kanboard\\Controller\\ProjectOverviewController' => $baseDir . '/app/Controller/ProjectOverviewController.php',
'Kanboard\\Controller\\ProjectPermissionController' => $baseDir . '/app/Controller/ProjectPermissionController.php',
'Kanboard\\Controller\\ProjectRoleController' => $baseDir . '/app/Controller/ProjectRoleController.php',
'Kanboard\\Controller\\ProjectRoleRestrictionController' => $baseDir . '/app/Controller/ProjectRoleRestrictionController.php',
'Kanboard\\Controller\\ProjectStatusController' => $baseDir . '/app/Controller/ProjectStatusController.php',
'Kanboard\\Controller\\ProjectTagController' => $baseDir . '/app/Controller/ProjectTagController.php',
'Kanboard\\Controller\\ProjectUserOverviewController' => $baseDir . '/app/Controller/ProjectUserOverviewController.php',
'Kanboard\\Controller\\ProjectViewController' => $baseDir . '/app/Controller/ProjectViewController.php',
'Kanboard\\Controller\\SearchController' => $baseDir . '/app/Controller/SearchController.php',
'Kanboard\\Controller\\SubtaskController' => $baseDir . '/app/Controller/SubtaskController.php',
'Kanboard\\Controller\\SubtaskConverterController' => $baseDir . '/app/Controller/SubtaskConverterController.php',
'Kanboard\\Controller\\SubtaskRestrictionController' => $baseDir . '/app/Controller/SubtaskRestrictionController.php',
'Kanboard\\Controller\\SubtaskStatusController' => $baseDir . '/app/Controller/SubtaskStatusController.php',
'Kanboard\\Controller\\SwimlaneController' => $baseDir . '/app/Controller/SwimlaneController.php',
'Kanboard\\Controller\\TagController' => $baseDir . '/app/Controller/TagController.php',
'Kanboard\\Controller\\TaskAjaxController' => $baseDir . '/app/Controller/TaskAjaxController.php',
'Kanboard\\Controller\\TaskBulkController' => $baseDir . '/app/Controller/TaskBulkController.php',
'Kanboard\\Controller\\TaskCreationController' => $baseDir . '/app/Controller/TaskCreationController.php',
'Kanboard\\Controller\\TaskDuplicationController' => $baseDir . '/app/Controller/TaskDuplicationController.php',
'Kanboard\\Controller\\TaskExternalLinkController' => $baseDir . '/app/Controller/TaskExternalLinkController.php',
'Kanboard\\Controller\\TaskFileController' => $baseDir . '/app/Controller/TaskFileController.php',
'Kanboard\\Controller\\TaskGanttController' => $baseDir . '/app/Controller/TaskGanttController.php',
'Kanboard\\Controller\\TaskGanttCreationController' => $baseDir . '/app/Controller/TaskGanttCreationController.php',
'Kanboard\\Controller\\TaskImportController' => $baseDir . '/app/Controller/TaskImportController.php',
'Kanboard\\Controller\\TaskInternalLinkController' => $baseDir . '/app/Controller/TaskInternalLinkController.php',
'Kanboard\\Controller\\TaskListController' => $baseDir . '/app/Controller/TaskListController.php',
'Kanboard\\Controller\\TaskModificationController' => $baseDir . '/app/Controller/TaskModificationController.php',
'Kanboard\\Controller\\TaskMovePositionController' => $baseDir . '/app/Controller/TaskMovePositionController.php',
'Kanboard\\Controller\\TaskPopoverController' => $baseDir . '/app/Controller/TaskPopoverController.php',
'Kanboard\\Controller\\TaskRecurrenceController' => $baseDir . '/app/Controller/TaskRecurrenceController.php',
'Kanboard\\Controller\\TaskStatusController' => $baseDir . '/app/Controller/TaskStatusController.php',
'Kanboard\\Controller\\TaskSuppressionController' => $baseDir . '/app/Controller/TaskSuppressionController.php',
'Kanboard\\Controller\\TaskViewController' => $baseDir . '/app/Controller/TaskViewController.php',
'Kanboard\\Controller\\TwoFactorController' => $baseDir . '/app/Controller/TwoFactorController.php',
'Kanboard\\Controller\\UserAjaxController' => $baseDir . '/app/Controller/UserAjaxController.php',
'Kanboard\\Controller\\UserApiAccessController' => $baseDir . '/app/Controller/UserApiAccessController.php',
'Kanboard\\Controller\\UserCreationController' => $baseDir . '/app/Controller/UserCreationController.php',
'Kanboard\\Controller\\UserCredentialController' => $baseDir . '/app/Controller/UserCredentialController.php',
'Kanboard\\Controller\\UserImportController' => $baseDir . '/app/Controller/UserImportController.php',
'Kanboard\\Controller\\UserListController' => $baseDir . '/app/Controller/UserListController.php',
'Kanboard\\Controller\\UserModificationController' => $baseDir . '/app/Controller/UserModificationController.php',
'Kanboard\\Controller\\UserStatusController' => $baseDir . '/app/Controller/UserStatusController.php',
'Kanboard\\Controller\\UserViewController' => $baseDir . '/app/Controller/UserViewController.php',
'Kanboard\\Controller\\WebNotificationController' => $baseDir . '/app/Controller/WebNotificationController.php',
'Kanboard\\Core\\Action\\ActionManager' => $baseDir . '/app/Core/Action/ActionManager.php',
'Kanboard\\Core\\Base' => $baseDir . '/app/Core/Base.php',
'Kanboard\\Core\\Cache\\BaseCache' => $baseDir . '/app/Core/Cache/BaseCache.php',
'Kanboard\\Core\\Cache\\CacheInterface' => $baseDir . '/app/Core/Cache/CacheInterface.php',
'Kanboard\\Core\\Cache\\FileCache' => $baseDir . '/app/Core/Cache/FileCache.php',
'Kanboard\\Core\\Cache\\MemoryCache' => $baseDir . '/app/Core/Cache/MemoryCache.php',
'Kanboard\\Core\\Controller\\AccessForbiddenException' => $baseDir . '/app/Core/Controller/AccessForbiddenException.php',
'Kanboard\\Core\\Controller\\BaseException' => $baseDir . '/app/Core/Controller/BaseException.php',
'Kanboard\\Core\\Controller\\BaseMiddleware' => $baseDir . '/app/Core/Controller/BaseMiddleware.php',
'Kanboard\\Core\\Controller\\PageNotFoundException' => $baseDir . '/app/Core/Controller/PageNotFoundException.php',
'Kanboard\\Core\\Controller\\Runner' => $baseDir . '/app/Core/Controller/Runner.php',
'Kanboard\\Core\\Csv' => $baseDir . '/app/Core/Csv.php',
'Kanboard\\Core\\DateParser' => $baseDir . '/app/Core/DateParser.php',
'Kanboard\\Core\\Event\\EventManager' => $baseDir . '/app/Core/Event/EventManager.php',
'Kanboard\\Core\\ExternalLink\\ExternalLinkInterface' => $baseDir . '/app/Core/ExternalLink/ExternalLinkInterface.php',
'Kanboard\\Core\\ExternalLink\\ExternalLinkManager' => $baseDir . '/app/Core/ExternalLink/ExternalLinkManager.php',
'Kanboard\\Core\\ExternalLink\\ExternalLinkProviderInterface' => $baseDir . '/app/Core/ExternalLink/ExternalLinkProviderInterface.php',
'Kanboard\\Core\\ExternalLink\\ExternalLinkProviderNotFound' => $baseDir . '/app/Core/ExternalLink/ExternalLinkProviderNotFound.php',
'Kanboard\\Core\\ExternalTask\\AccessForbiddenException' => $baseDir . '/app/Core/ExternalTask/AccessForbiddenException.php',
'Kanboard\\Core\\ExternalTask\\ExternalTaskException' => $baseDir . '/app/Core/ExternalTask/ExternalTaskException.php',
'Kanboard\\Core\\ExternalTask\\ExternalTaskInterface' => $baseDir . '/app/Core/ExternalTask/ExternalTaskInterface.php',
'Kanboard\\Core\\ExternalTask\\ExternalTaskManager' => $baseDir . '/app/Core/ExternalTask/ExternalTaskManager.php',
'Kanboard\\Core\\ExternalTask\\ExternalTaskProviderInterface' => $baseDir . '/app/Core/ExternalTask/ExternalTaskProviderInterface.php',
'Kanboard\\Core\\ExternalTask\\NotFoundException' => $baseDir . '/app/Core/ExternalTask/NotFoundException.php',
'Kanboard\\Core\\ExternalTask\\ProviderNotFoundException' => $baseDir . '/app/Core/ExternalTask/ProviderNotFoundException.php',
'Kanboard\\Core\\Filter\\CriteriaInterface' => $baseDir . '/app/Core/Filter/CriteriaInterface.php',
'Kanboard\\Core\\Filter\\FilterInterface' => $baseDir . '/app/Core/Filter/FilterInterface.php',
'Kanboard\\Core\\Filter\\FormatterInterface' => $baseDir . '/app/Core/Filter/FormatterInterface.php',
'Kanboard\\Core\\Filter\\Lexer' => $baseDir . '/app/Core/Filter/Lexer.php',
'Kanboard\\Core\\Filter\\LexerBuilder' => $baseDir . '/app/Core/Filter/LexerBuilder.php',
'Kanboard\\Core\\Filter\\OrCriteria' => $baseDir . '/app/Core/Filter/OrCriteria.php',
'Kanboard\\Core\\Filter\\QueryBuilder' => $baseDir . '/app/Core/Filter/QueryBuilder.php',
'Kanboard\\Core\\Group\\GroupBackendProviderInterface' => $baseDir . '/app/Core/Group/GroupBackendProviderInterface.php',
'Kanboard\\Core\\Group\\GroupManager' => $baseDir . '/app/Core/Group/GroupManager.php',
'Kanboard\\Core\\Group\\GroupProviderInterface' => $baseDir . '/app/Core/Group/GroupProviderInterface.php',
'Kanboard\\Core\\Helper' => $baseDir . '/app/Core/Helper.php',
'Kanboard\\Core\\Http\\Client' => $baseDir . '/app/Core/Http/Client.php',
'Kanboard\\Core\\Http\\OAuth2' => $baseDir . '/app/Core/Http/OAuth2.php',
'Kanboard\\Core\\Http\\RememberMeCookie' => $baseDir . '/app/Core/Http/RememberMeCookie.php',
'Kanboard\\Core\\Http\\Request' => $baseDir . '/app/Core/Http/Request.php',
'Kanboard\\Core\\Http\\Response' => $baseDir . '/app/Core/Http/Response.php',
'Kanboard\\Core\\Http\\Route' => $baseDir . '/app/Core/Http/Route.php',
'Kanboard\\Core\\Http\\Router' => $baseDir . '/app/Core/Http/Router.php',
'Kanboard\\Core\\Ldap\\Client' => $baseDir . '/app/Core/Ldap/Client.php',
'Kanboard\\Core\\Ldap\\ClientException' => $baseDir . '/app/Core/Ldap/ClientException.php',
'Kanboard\\Core\\Ldap\\Entries' => $baseDir . '/app/Core/Ldap/Entries.php',
'Kanboard\\Core\\Ldap\\Entry' => $baseDir . '/app/Core/Ldap/Entry.php',
'Kanboard\\Core\\Ldap\\Group' => $baseDir . '/app/Core/Ldap/Group.php',
'Kanboard\\Core\\Ldap\\Query' => $baseDir . '/app/Core/Ldap/Query.php',
'Kanboard\\Core\\Ldap\\User' => $baseDir . '/app/Core/Ldap/User.php',
'Kanboard\\Core\\Mail\\Client' => $baseDir . '/app/Core/Mail/Client.php',
'Kanboard\\Core\\Mail\\ClientInterface' => $baseDir . '/app/Core/Mail/ClientInterface.php',
'Kanboard\\Core\\Mail\\Transport\\Mail' => $baseDir . '/app/Core/Mail/Transport/Mail.php',
'Kanboard\\Core\\Mail\\Transport\\Sendmail' => $baseDir . '/app/Core/Mail/Transport/Sendmail.php',
'Kanboard\\Core\\Mail\\Transport\\Smtp' => $baseDir . '/app/Core/Mail/Transport/Smtp.php',
'Kanboard\\Core\\Markdown' => $baseDir . '/app/Core/Markdown.php',
'Kanboard\\Core\\Notification\\NotificationInterface' => $baseDir . '/app/Core/Notification/NotificationInterface.php',
'Kanboard\\Core\\ObjectStorage\\FileStorage' => $baseDir . '/app/Core/ObjectStorage/FileStorage.php',
'Kanboard\\Core\\ObjectStorage\\ObjectStorageException' => $baseDir . '/app/Core/ObjectStorage/ObjectStorageException.php',
'Kanboard\\Core\\ObjectStorage\\ObjectStorageInterface' => $baseDir . '/app/Core/ObjectStorage/ObjectStorageInterface.php',
'Kanboard\\Core\\Paginator' => $baseDir . '/app/Core/Paginator.php',
'Kanboard\\Core\\Plugin\\Base' => $baseDir . '/app/Core/Plugin/Base.php',
'Kanboard\\Core\\Plugin\\Directory' => $baseDir . '/app/Core/Plugin/Directory.php',
'Kanboard\\Core\\Plugin\\Hook' => $baseDir . '/app/Core/Plugin/Hook.php',
'Kanboard\\Core\\Plugin\\Installer' => $baseDir . '/app/Core/Plugin/Installer.php',
'Kanboard\\Core\\Plugin\\Loader' => $baseDir . '/app/Core/Plugin/Loader.php',
'Kanboard\\Core\\Plugin\\PluginInstallerException' => $baseDir . '/app/Core/Plugin/PluginInstallerException.php',
'Kanboard\\Core\\Plugin\\SchemaHandler' => $baseDir . '/app/Core/Plugin/SchemaHandler.php',
'Kanboard\\Core\\Queue\\JobHandler' => $baseDir . '/app/Core/Queue/JobHandler.php',
'Kanboard\\Core\\Queue\\QueueManager' => $baseDir . '/app/Core/Queue/QueueManager.php',
'Kanboard\\Core\\Security\\AccessMap' => $baseDir . '/app/Core/Security/AccessMap.php',
'Kanboard\\Core\\Security\\AuthenticationManager' => $baseDir . '/app/Core/Security/AuthenticationManager.php',
'Kanboard\\Core\\Security\\AuthenticationProviderInterface' => $baseDir . '/app/Core/Security/AuthenticationProviderInterface.php',
'Kanboard\\Core\\Security\\Authorization' => $baseDir . '/app/Core/Security/Authorization.php',
'Kanboard\\Core\\Security\\OAuthAuthenticationProviderInterface' => $baseDir . '/app/Core/Security/OAuthAuthenticationProviderInterface.php',
'Kanboard\\Core\\Security\\PasswordAuthenticationProviderInterface' => $baseDir . '/app/Core/Security/PasswordAuthenticationProviderInterface.php',
'Kanboard\\Core\\Security\\PostAuthenticationProviderInterface' => $baseDir . '/app/Core/Security/PostAuthenticationProviderInterface.php',
'Kanboard\\Core\\Security\\PreAuthenticationProviderInterface' => $baseDir . '/app/Core/Security/PreAuthenticationProviderInterface.php',
'Kanboard\\Core\\Security\\Role' => $baseDir . '/app/Core/Security/Role.php',
'Kanboard\\Core\\Security\\SessionCheckProviderInterface' => $baseDir . '/app/Core/Security/SessionCheckProviderInterface.php',
'Kanboard\\Core\\Security\\Token' => $baseDir . '/app/Core/Security/Token.php',
'Kanboard\\Core\\Session\\FlashMessage' => $baseDir . '/app/Core/Session/FlashMessage.php',
'Kanboard\\Core\\Session\\SessionManager' => $baseDir . '/app/Core/Session/SessionManager.php',
'Kanboard\\Core\\Session\\SessionStorage' => $baseDir . '/app/Core/Session/SessionStorage.php',
'Kanboard\\Core\\Template' => $baseDir . '/app/Core/Template.php',
'Kanboard\\Core\\Thumbnail' => $baseDir . '/app/Core/Thumbnail.php',
'Kanboard\\Core\\Tool' => $baseDir . '/app/Core/Tool.php',
'Kanboard\\Core\\Translator' => $baseDir . '/app/Core/Translator.php',
'Kanboard\\Core\\User\\Avatar\\AvatarManager' => $baseDir . '/app/Core/User/Avatar/AvatarManager.php',
'Kanboard\\Core\\User\\Avatar\\AvatarProviderInterface' => $baseDir . '/app/Core/User/Avatar/AvatarProviderInterface.php',
'Kanboard\\Core\\User\\GroupSync' => $baseDir . '/app/Core/User/GroupSync.php',
'Kanboard\\Core\\User\\UserProfile' => $baseDir . '/app/Core/User/UserProfile.php',
'Kanboard\\Core\\User\\UserProperty' => $baseDir . '/app/Core/User/UserProperty.php',
'Kanboard\\Core\\User\\UserProviderInterface' => $baseDir . '/app/Core/User/UserProviderInterface.php',
'Kanboard\\Core\\User\\UserSession' => $baseDir . '/app/Core/User/UserSession.php',
'Kanboard\\Core\\User\\UserSync' => $baseDir . '/app/Core/User/UserSync.php',
'Kanboard\\Decorator\\ColumnMoveRestrictionCacheDecorator' => $baseDir . '/app/Decorator/ColumnMoveRestrictionCacheDecorator.php',
'Kanboard\\Decorator\\ColumnRestrictionCacheDecorator' => $baseDir . '/app/Decorator/ColumnRestrictionCacheDecorator.php',
'Kanboard\\Decorator\\MetadataCacheDecorator' => $baseDir . '/app/Decorator/MetadataCacheDecorator.php',
'Kanboard\\Decorator\\ProjectRoleRestrictionCacheDecorator' => $baseDir . '/app/Decorator/ProjectRoleRestrictionCacheDecorator.php',
'Kanboard\\Decorator\\UserCacheDecorator' => $baseDir . '/app/Decorator/UserCacheDecorator.php',
'Kanboard\\EventBuilder\\BaseEventBuilder' => $baseDir . '/app/EventBuilder/BaseEventBuilder.php',
'Kanboard\\EventBuilder\\CommentEventBuilder' => $baseDir . '/app/EventBuilder/CommentEventBuilder.php',
'Kanboard\\EventBuilder\\EventIteratorBuilder' => $baseDir . '/app/EventBuilder/EventIteratorBuilder.php',
'Kanboard\\EventBuilder\\ProjectFileEventBuilder' => $baseDir . '/app/EventBuilder/ProjectFileEventBuilder.php',
'Kanboard\\EventBuilder\\SubtaskEventBuilder' => $baseDir . '/app/EventBuilder/SubtaskEventBuilder.php',
'Kanboard\\EventBuilder\\TaskEventBuilder' => $baseDir . '/app/EventBuilder/TaskEventBuilder.php',
'Kanboard\\EventBuilder\\TaskFileEventBuilder' => $baseDir . '/app/EventBuilder/TaskFileEventBuilder.php',
'Kanboard\\EventBuilder\\TaskLinkEventBuilder' => $baseDir . '/app/EventBuilder/TaskLinkEventBuilder.php',
'Kanboard\\Event\\AuthFailureEvent' => $baseDir . '/app/Event/AuthFailureEvent.php',
'Kanboard\\Event\\AuthSuccessEvent' => $baseDir . '/app/Event/AuthSuccessEvent.php',
'Kanboard\\Event\\CommentEvent' => $baseDir . '/app/Event/CommentEvent.php',
'Kanboard\\Event\\GenericEvent' => $baseDir . '/app/Event/GenericEvent.php',
'Kanboard\\Event\\ProjectFileEvent' => $baseDir . '/app/Event/ProjectFileEvent.php',
'Kanboard\\Event\\SubtaskEvent' => $baseDir . '/app/Event/SubtaskEvent.php',
'Kanboard\\Event\\TaskEvent' => $baseDir . '/app/Event/TaskEvent.php',
'Kanboard\\Event\\TaskFileEvent' => $baseDir . '/app/Event/TaskFileEvent.php',
'Kanboard\\Event\\TaskLinkEvent' => $baseDir . '/app/Event/TaskLinkEvent.php',
'Kanboard\\Event\\TaskListEvent' => $baseDir . '/app/Event/TaskListEvent.php',
'Kanboard\\Event\\UserProfileSyncEvent' => $baseDir . '/app/Event/UserProfileSyncEvent.php',
'Kanboard\\Export\\SubtaskExport' => $baseDir . '/app/Export/SubtaskExport.php',
'Kanboard\\Export\\TaskExport' => $baseDir . '/app/Export/TaskExport.php',
'Kanboard\\Export\\TransitionExport' => $baseDir . '/app/Export/TransitionExport.php',
'Kanboard\\ExternalLink\\AttachmentLink' => $baseDir . '/app/ExternalLink/AttachmentLink.php',
'Kanboard\\ExternalLink\\AttachmentLinkProvider' => $baseDir . '/app/ExternalLink/AttachmentLinkProvider.php',
'Kanboard\\ExternalLink\\BaseLink' => $baseDir . '/app/ExternalLink/BaseLink.php',
'Kanboard\\ExternalLink\\BaseLinkProvider' => $baseDir . '/app/ExternalLink/BaseLinkProvider.php',
'Kanboard\\ExternalLink\\FileLink' => $baseDir . '/app/ExternalLink/FileLink.php',
'Kanboard\\ExternalLink\\FileLinkProvider' => $baseDir . '/app/ExternalLink/FileLinkProvider.php',
'Kanboard\\ExternalLink\\WebLink' => $baseDir . '/app/ExternalLink/WebLink.php',
'Kanboard\\ExternalLink\\WebLinkProvider' => $baseDir . '/app/ExternalLink/WebLinkProvider.php',
'Kanboard\\Filter\\BaseDateFilter' => $baseDir . '/app/Filter/BaseDateFilter.php',
'Kanboard\\Filter\\BaseFilter' => $baseDir . '/app/Filter/BaseFilter.php',
'Kanboard\\Filter\\ProjectActivityCreationDateFilter' => $baseDir . '/app/Filter/ProjectActivityCreationDateFilter.php',
'Kanboard\\Filter\\ProjectActivityCreatorFilter' => $baseDir . '/app/Filter/ProjectActivityCreatorFilter.php',
'Kanboard\\Filter\\ProjectActivityProjectIdFilter' => $baseDir . '/app/Filter/ProjectActivityProjectIdFilter.php',
'Kanboard\\Filter\\ProjectActivityProjectIdsFilter' => $baseDir . '/app/Filter/ProjectActivityProjectIdsFilter.php',
'Kanboard\\Filter\\ProjectActivityProjectNameFilter' => $baseDir . '/app/Filter/ProjectActivityProjectNameFilter.php',
'Kanboard\\Filter\\ProjectActivityTaskIdFilter' => $baseDir . '/app/Filter/ProjectActivityTaskIdFilter.php',
'Kanboard\\Filter\\ProjectActivityTaskStatusFilter' => $baseDir . '/app/Filter/ProjectActivityTaskStatusFilter.php',
'Kanboard\\Filter\\ProjectActivityTaskTitleFilter' => $baseDir . '/app/Filter/ProjectActivityTaskTitleFilter.php',
'Kanboard\\Filter\\ProjectGroupRoleProjectFilter' => $baseDir . '/app/Filter/ProjectGroupRoleProjectFilter.php',
'Kanboard\\Filter\\ProjectGroupRoleUsernameFilter' => $baseDir . '/app/Filter/ProjectGroupRoleUsernameFilter.php',
'Kanboard\\Filter\\ProjectIdsFilter' => $baseDir . '/app/Filter/ProjectIdsFilter.php',
'Kanboard\\Filter\\ProjectStatusFilter' => $baseDir . '/app/Filter/ProjectStatusFilter.php',
'Kanboard\\Filter\\ProjectTypeFilter' => $baseDir . '/app/Filter/ProjectTypeFilter.php',
'Kanboard\\Filter\\ProjectUserRoleProjectFilter' => $baseDir . '/app/Filter/ProjectUserRoleProjectFilter.php',
'Kanboard\\Filter\\ProjectUserRoleUsernameFilter' => $baseDir . '/app/Filter/ProjectUserRoleUsernameFilter.php',
'Kanboard\\Filter\\TaskAssigneeFilter' => $baseDir . '/app/Filter/TaskAssigneeFilter.php',
'Kanboard\\Filter\\TaskCategoryFilter' => $baseDir . '/app/Filter/TaskCategoryFilter.php',
'Kanboard\\Filter\\TaskColorFilter' => $baseDir . '/app/Filter/TaskColorFilter.php',
'Kanboard\\Filter\\TaskColumnFilter' => $baseDir . '/app/Filter/TaskColumnFilter.php',
'Kanboard\\Filter\\TaskCommentFilter' => $baseDir . '/app/Filter/TaskCommentFilter.php',
'Kanboard\\Filter\\TaskCompletionDateFilter' => $baseDir . '/app/Filter/TaskCompletionDateFilter.php',
'Kanboard\\Filter\\TaskCreationDateFilter' => $baseDir . '/app/Filter/TaskCreationDateFilter.php',
'Kanboard\\Filter\\TaskCreatorFilter' => $baseDir . '/app/Filter/TaskCreatorFilter.php',
'Kanboard\\Filter\\TaskDescriptionFilter' => $baseDir . '/app/Filter/TaskDescriptionFilter.php',
'Kanboard\\Filter\\TaskDueDateFilter' => $baseDir . '/app/Filter/TaskDueDateFilter.php',
'Kanboard\\Filter\\TaskDueDateRangeFilter' => $baseDir . '/app/Filter/TaskDueDateRangeFilter.php',
'Kanboard\\Filter\\TaskIdExclusionFilter' => $baseDir . '/app/Filter/TaskIdExclusionFilter.php',
'Kanboard\\Filter\\TaskIdFilter' => $baseDir . '/app/Filter/TaskIdFilter.php',
'Kanboard\\Filter\\TaskLinkFilter' => $baseDir . '/app/Filter/TaskLinkFilter.php',
'Kanboard\\Filter\\TaskModificationDateFilter' => $baseDir . '/app/Filter/TaskModificationDateFilter.php',
'Kanboard\\Filter\\TaskMovedDateFilter' => $baseDir . '/app/Filter/TaskMovedDateFilter.php',
'Kanboard\\Filter\\TaskPriorityFilter' => $baseDir . '/app/Filter/TaskPriorityFilter.php',
'Kanboard\\Filter\\TaskProjectFilter' => $baseDir . '/app/Filter/TaskProjectFilter.php',
'Kanboard\\Filter\\TaskProjectsFilter' => $baseDir . '/app/Filter/TaskProjectsFilter.php',
'Kanboard\\Filter\\TaskReferenceFilter' => $baseDir . '/app/Filter/TaskReferenceFilter.php',
'Kanboard\\Filter\\TaskStartDateFilter' => $baseDir . '/app/Filter/TaskStartDateFilter.php',
'Kanboard\\Filter\\TaskStartsWithIdFilter' => $baseDir . '/app/Filter/TaskStartsWithIdFilter.php',
'Kanboard\\Filter\\TaskStatusFilter' => $baseDir . '/app/Filter/TaskStatusFilter.php',
'Kanboard\\Filter\\TaskSubtaskAssigneeFilter' => $baseDir . '/app/Filter/TaskSubtaskAssigneeFilter.php',
'Kanboard\\Filter\\TaskSwimlaneFilter' => $baseDir . '/app/Filter/TaskSwimlaneFilter.php',
'Kanboard\\Filter\\TaskTagFilter' => $baseDir . '/app/Filter/TaskTagFilter.php',
'Kanboard\\Filter\\TaskTitleFilter' => $baseDir . '/app/Filter/TaskTitleFilter.php',
'Kanboard\\Filter\\UserNameFilter' => $baseDir . '/app/Filter/UserNameFilter.php',
'Kanboard\\Formatter\\BaseFormatter' => $baseDir . '/app/Formatter/BaseFormatter.php',
'Kanboard\\Formatter\\BaseTaskCalendarFormatter' => $baseDir . '/app/Formatter/BaseTaskCalendarFormatter.php',
'Kanboard\\Formatter\\BoardColumnFormatter' => $baseDir . '/app/Formatter/BoardColumnFormatter.php',
'Kanboard\\Formatter\\BoardFormatter' => $baseDir . '/app/Formatter/BoardFormatter.php',
'Kanboard\\Formatter\\BoardSwimlaneFormatter' => $baseDir . '/app/Formatter/BoardSwimlaneFormatter.php',
'Kanboard\\Formatter\\BoardTaskFormatter' => $baseDir . '/app/Formatter/BoardTaskFormatter.php',
'Kanboard\\Formatter\\GroupAutoCompleteFormatter' => $baseDir . '/app/Formatter/GroupAutoCompleteFormatter.php',
'Kanboard\\Formatter\\ProjectActivityEventFormatter' => $baseDir . '/app/Formatter/ProjectActivityEventFormatter.php',
'Kanboard\\Formatter\\ProjectGanttFormatter' => $baseDir . '/app/Formatter/ProjectGanttFormatter.php',
'Kanboard\\Formatter\\SubtaskTimeTrackingCalendarFormatter' => $baseDir . '/app/Formatter/SubtaskTimeTrackingCalendarFormatter.php',
'Kanboard\\Formatter\\TaskAutoCompleteFormatter' => $baseDir . '/app/Formatter/TaskAutoCompleteFormatter.php',
'Kanboard\\Formatter\\TaskCalendarFormatter' => $baseDir . '/app/Formatter/TaskCalendarFormatter.php',
'Kanboard\\Formatter\\TaskGanttFormatter' => $baseDir . '/app/Formatter/TaskGanttFormatter.php',
'Kanboard\\Formatter\\TaskICalFormatter' => $baseDir . '/app/Formatter/TaskICalFormatter.php',
'Kanboard\\Formatter\\TaskSuggestMenuFormatter' => $baseDir . '/app/Formatter/TaskSuggestMenuFormatter.php',
'Kanboard\\Formatter\\UserAutoCompleteFormatter' => $baseDir . '/app/Formatter/UserAutoCompleteFormatter.php',
'Kanboard\\Formatter\\UserMentionFormatter' => $baseDir . '/app/Formatter/UserMentionFormatter.php',
'Kanboard\\Group\\DatabaseBackendGroupProvider' => $baseDir . '/app/Group/DatabaseBackendGroupProvider.php',
'Kanboard\\Group\\DatabaseGroupProvider' => $baseDir . '/app/Group/DatabaseGroupProvider.php',
'Kanboard\\Group\\LdapBackendGroupProvider' => $baseDir . '/app/Group/LdapBackendGroupProvider.php',
'Kanboard\\Group\\LdapGroupProvider' => $baseDir . '/app/Group/LdapGroupProvider.php',
'Kanboard\\Helper\\AppHelper' => $baseDir . '/app/Helper/AppHelper.php',
'Kanboard\\Helper\\AssetHelper' => $baseDir . '/app/Helper/AssetHelper.php',
'Kanboard\\Helper\\AvatarHelper' => $baseDir . '/app/Helper/AvatarHelper.php',
'Kanboard\\Helper\\BoardHelper' => $baseDir . '/app/Helper/BoardHelper.php',
'Kanboard\\Helper\\CalendarHelper' => $baseDir . '/app/Helper/CalendarHelper.php',
'Kanboard\\Helper\\DateHelper' => $baseDir . '/app/Helper/DateHelper.php',
'Kanboard\\Helper\\FileHelper' => $baseDir . '/app/Helper/FileHelper.php',
'Kanboard\\Helper\\FormHelper' => $baseDir . '/app/Helper/FormHelper.php',
'Kanboard\\Helper\\HookHelper' => $baseDir . '/app/Helper/HookHelper.php',
'Kanboard\\Helper\\ICalHelper' => $baseDir . '/app/Helper/ICalHelper.php',
'Kanboard\\Helper\\LayoutHelper' => $baseDir . '/app/Helper/LayoutHelper.php',
'Kanboard\\Helper\\MailHelper' => $baseDir . '/app/Helper/MailHelper.php',
'Kanboard\\Helper\\ModelHelper' => $baseDir . '/app/Helper/ModelHelper.php',
'Kanboard\\Helper\\ProjectActivityHelper' => $baseDir . '/app/Helper/ProjectActivityHelper.php',
'Kanboard\\Helper\\ProjectHeaderHelper' => $baseDir . '/app/Helper/ProjectHeaderHelper.php',
'Kanboard\\Helper\\ProjectRoleHelper' => $baseDir . '/app/Helper/ProjectRoleHelper.php',
'Kanboard\\Helper\\SubtaskHelper' => $baseDir . '/app/Helper/SubtaskHelper.php',
'Kanboard\\Helper\\TaskHelper' => $baseDir . '/app/Helper/TaskHelper.php',
'Kanboard\\Helper\\TextHelper' => $baseDir . '/app/Helper/TextHelper.php',
'Kanboard\\Helper\\UrlHelper' => $baseDir . '/app/Helper/UrlHelper.php',
'Kanboard\\Helper\\UserHelper' => $baseDir . '/app/Helper/UserHelper.php',
'Kanboard\\Import\\TaskImport' => $baseDir . '/app/Import/TaskImport.php',
'Kanboard\\Import\\UserImport' => $baseDir . '/app/Import/UserImport.php',
'Kanboard\\Job\\BaseJob' => $baseDir . '/app/Job/BaseJob.php',
'Kanboard\\Job\\CommentEventJob' => $baseDir . '/app/Job/CommentEventJob.php',
'Kanboard\\Job\\EmailJob' => $baseDir . '/app/Job/EmailJob.php',
'Kanboard\\Job\\HttpAsyncJob' => $baseDir . '/app/Job/HttpAsyncJob.php',
'Kanboard\\Job\\NotificationJob' => $baseDir . '/app/Job/NotificationJob.php',
'Kanboard\\Job\\ProjectFileEventJob' => $baseDir . '/app/Job/ProjectFileEventJob.php',
'Kanboard\\Job\\ProjectMetricJob' => $baseDir . '/app/Job/ProjectMetricJob.php',
'Kanboard\\Job\\SubtaskEventJob' => $baseDir . '/app/Job/SubtaskEventJob.php',
'Kanboard\\Job\\TaskEventJob' => $baseDir . '/app/Job/TaskEventJob.php',
'Kanboard\\Job\\TaskFileEventJob' => $baseDir . '/app/Job/TaskFileEventJob.php',
'Kanboard\\Job\\TaskLinkEventJob' => $baseDir . '/app/Job/TaskLinkEventJob.php',
'Kanboard\\Job\\UserMentionJob' => $baseDir . '/app/Job/UserMentionJob.php',
'Kanboard\\Middleware\\ApplicationAuthorizationMiddleware' => $baseDir . '/app/Middleware/ApplicationAuthorizationMiddleware.php',
'Kanboard\\Middleware\\AuthenticationMiddleware' => $baseDir . '/app/Middleware/AuthenticationMiddleware.php',
'Kanboard\\Middleware\\BootstrapMiddleware' => $baseDir . '/app/Middleware/BootstrapMiddleware.php',
'Kanboard\\Middleware\\PostAuthenticationMiddleware' => $baseDir . '/app/Middleware/PostAuthenticationMiddleware.php',
'Kanboard\\Middleware\\ProjectAuthorizationMiddleware' => $baseDir . '/app/Middleware/ProjectAuthorizationMiddleware.php',
'Kanboard\\Model\\ActionModel' => $baseDir . '/app/Model/ActionModel.php',
'Kanboard\\Model\\ActionParameterModel' => $baseDir . '/app/Model/ActionParameterModel.php',
'Kanboard\\Model\\AvatarFileModel' => $baseDir . '/app/Model/AvatarFileModel.php',
'Kanboard\\Model\\BoardModel' => $baseDir . '/app/Model/BoardModel.php',
'Kanboard\\Model\\CategoryModel' => $baseDir . '/app/Model/CategoryModel.php',
'Kanboard\\Model\\ColorModel' => $baseDir . '/app/Model/ColorModel.php',
'Kanboard\\Model\\ColumnModel' => $baseDir . '/app/Model/ColumnModel.php',
'Kanboard\\Model\\ColumnMoveRestrictionModel' => $baseDir . '/app/Model/ColumnMoveRestrictionModel.php',
'Kanboard\\Model\\ColumnRestrictionModel' => $baseDir . '/app/Model/ColumnRestrictionModel.php',
'Kanboard\\Model\\CommentModel' => $baseDir . '/app/Model/CommentModel.php',
'Kanboard\\Model\\ConfigModel' => $baseDir . '/app/Model/ConfigModel.php',
'Kanboard\\Model\\CurrencyModel' => $baseDir . '/app/Model/CurrencyModel.php',
'Kanboard\\Model\\CustomFilterModel' => $baseDir . '/app/Model/CustomFilterModel.php',
'Kanboard\\Model\\FileModel' => $baseDir . '/app/Model/FileModel.php',
'Kanboard\\Model\\GroupMemberModel' => $baseDir . '/app/Model/GroupMemberModel.php',
'Kanboard\\Model\\GroupModel' => $baseDir . '/app/Model/GroupModel.php',
'Kanboard\\Model\\LanguageModel' => $baseDir . '/app/Model/LanguageModel.php',
'Kanboard\\Model\\LastLoginModel' => $baseDir . '/app/Model/LastLoginModel.php',
'Kanboard\\Model\\LinkModel' => $baseDir . '/app/Model/LinkModel.php',
'Kanboard\\Model\\MetadataModel' => $baseDir . '/app/Model/MetadataModel.php',
'Kanboard\\Model\\NotificationModel' => $baseDir . '/app/Model/NotificationModel.php',
'Kanboard\\Model\\NotificationTypeModel' => $baseDir . '/app/Model/NotificationTypeModel.php',
'Kanboard\\Model\\PasswordResetModel' => $baseDir . '/app/Model/PasswordResetModel.php',
'Kanboard\\Model\\ProjectActivityModel' => $baseDir . '/app/Model/ProjectActivityModel.php',
'Kanboard\\Model\\ProjectDailyColumnStatsModel' => $baseDir . '/app/Model/ProjectDailyColumnStatsModel.php',
'Kanboard\\Model\\ProjectDailyStatsModel' => $baseDir . '/app/Model/ProjectDailyStatsModel.php',
'Kanboard\\Model\\ProjectDuplicationModel' => $baseDir . '/app/Model/ProjectDuplicationModel.php',
'Kanboard\\Model\\ProjectFileModel' => $baseDir . '/app/Model/ProjectFileModel.php',
'Kanboard\\Model\\ProjectGroupRoleModel' => $baseDir . '/app/Model/ProjectGroupRoleModel.php',
'Kanboard\\Model\\ProjectMetadataModel' => $baseDir . '/app/Model/ProjectMetadataModel.php',
'Kanboard\\Model\\ProjectModel' => $baseDir . '/app/Model/ProjectModel.php',
'Kanboard\\Model\\ProjectNotificationModel' => $baseDir . '/app/Model/ProjectNotificationModel.php',
'Kanboard\\Model\\ProjectNotificationTypeModel' => $baseDir . '/app/Model/ProjectNotificationTypeModel.php',
'Kanboard\\Model\\ProjectPermissionModel' => $baseDir . '/app/Model/ProjectPermissionModel.php',
'Kanboard\\Model\\ProjectRoleModel' => $baseDir . '/app/Model/ProjectRoleModel.php',
'Kanboard\\Model\\ProjectRoleRestrictionModel' => $baseDir . '/app/Model/ProjectRoleRestrictionModel.php',
'Kanboard\\Model\\ProjectTaskDuplicationModel' => $baseDir . '/app/Model/ProjectTaskDuplicationModel.php',
'Kanboard\\Model\\ProjectTaskPriorityModel' => $baseDir . '/app/Model/ProjectTaskPriorityModel.php',
'Kanboard\\Model\\ProjectUserRoleModel' => $baseDir . '/app/Model/ProjectUserRoleModel.php',
'Kanboard\\Model\\RememberMeSessionModel' => $baseDir . '/app/Model/RememberMeSessionModel.php',
'Kanboard\\Model\\SettingModel' => $baseDir . '/app/Model/SettingModel.php',
'Kanboard\\Model\\SubtaskModel' => $baseDir . '/app/Model/SubtaskModel.php',
'Kanboard\\Model\\SubtaskPositionModel' => $baseDir . '/app/Model/SubtaskPositionModel.php',
'Kanboard\\Model\\SubtaskStatusModel' => $baseDir . '/app/Model/SubtaskStatusModel.php',
'Kanboard\\Model\\SubtaskTaskConversionModel' => $baseDir . '/app/Model/SubtaskTaskConversionModel.php',
'Kanboard\\Model\\SubtaskTimeTrackingModel' => $baseDir . '/app/Model/SubtaskTimeTrackingModel.php',
'Kanboard\\Model\\SwimlaneModel' => $baseDir . '/app/Model/SwimlaneModel.php',
'Kanboard\\Model\\TagDuplicationModel' => $baseDir . '/app/Model/TagDuplicationModel.php',
'Kanboard\\Model\\TagModel' => $baseDir . '/app/Model/TagModel.php',
'Kanboard\\Model\\TaskAnalyticModel' => $baseDir . '/app/Model/TaskAnalyticModel.php',
'Kanboard\\Model\\TaskCreationModel' => $baseDir . '/app/Model/TaskCreationModel.php',
'Kanboard\\Model\\TaskDuplicationModel' => $baseDir . '/app/Model/TaskDuplicationModel.php',
'Kanboard\\Model\\TaskExternalLinkModel' => $baseDir . '/app/Model/TaskExternalLinkModel.php',
'Kanboard\\Model\\TaskFileModel' => $baseDir . '/app/Model/TaskFileModel.php',
'Kanboard\\Model\\TaskFinderModel' => $baseDir . '/app/Model/TaskFinderModel.php',
'Kanboard\\Model\\TaskLinkModel' => $baseDir . '/app/Model/TaskLinkModel.php',
'Kanboard\\Model\\TaskMetadataModel' => $baseDir . '/app/Model/TaskMetadataModel.php',
'Kanboard\\Model\\TaskModel' => $baseDir . '/app/Model/TaskModel.php',
'Kanboard\\Model\\TaskModificationModel' => $baseDir . '/app/Model/TaskModificationModel.php',
'Kanboard\\Model\\TaskPositionModel' => $baseDir . '/app/Model/TaskPositionModel.php',
'Kanboard\\Model\\TaskProjectDuplicationModel' => $baseDir . '/app/Model/TaskProjectDuplicationModel.php',
'Kanboard\\Model\\TaskProjectMoveModel' => $baseDir . '/app/Model/TaskProjectMoveModel.php',
'Kanboard\\Model\\TaskRecurrenceModel' => $baseDir . '/app/Model/TaskRecurrenceModel.php',
'Kanboard\\Model\\TaskStatusModel' => $baseDir . '/app/Model/TaskStatusModel.php',
'Kanboard\\Model\\TaskTagModel' => $baseDir . '/app/Model/TaskTagModel.php',
'Kanboard\\Model\\TimezoneModel' => $baseDir . '/app/Model/TimezoneModel.php',
'Kanboard\\Model\\TransitionModel' => $baseDir . '/app/Model/TransitionModel.php',
'Kanboard\\Model\\UserLockingModel' => $baseDir . '/app/Model/UserLockingModel.php',
'Kanboard\\Model\\UserMetadataModel' => $baseDir . '/app/Model/UserMetadataModel.php',
'Kanboard\\Model\\UserModel' => $baseDir . '/app/Model/UserModel.php',
'Kanboard\\Model\\UserNotificationFilterModel' => $baseDir . '/app/Model/UserNotificationFilterModel.php',
'Kanboard\\Model\\UserNotificationModel' => $baseDir . '/app/Model/UserNotificationModel.php',
'Kanboard\\Model\\UserNotificationTypeModel' => $baseDir . '/app/Model/UserNotificationTypeModel.php',
'Kanboard\\Model\\UserUnreadNotificationModel' => $baseDir . '/app/Model/UserUnreadNotificationModel.php',
'Kanboard\\Notification\\ActivityStreamNotification' => $baseDir . '/app/Notification/ActivityStreamNotification.php',
'Kanboard\\Notification\\MailNotification' => $baseDir . '/app/Notification/MailNotification.php',
'Kanboard\\Notification\\WebNotification' => $baseDir . '/app/Notification/WebNotification.php',
'Kanboard\\Notification\\WebhookNotification' => $baseDir . '/app/Notification/WebhookNotification.php',
'Kanboard\\Pagination\\ProjectPagination' => $baseDir . '/app/Pagination/ProjectPagination.php',
'Kanboard\\Pagination\\SubtaskPagination' => $baseDir . '/app/Pagination/SubtaskPagination.php',
'Kanboard\\Pagination\\TaskPagination' => $baseDir . '/app/Pagination/TaskPagination.php',
'Kanboard\\Pagination\\UserPagination' => $baseDir . '/app/Pagination/UserPagination.php',
'Kanboard\\ServiceProvider\\ActionProvider' => $baseDir . '/app/ServiceProvider/ActionProvider.php',
'Kanboard\\ServiceProvider\\ApiProvider' => $baseDir . '/app/ServiceProvider/ApiProvider.php',
'Kanboard\\ServiceProvider\\AuthenticationProvider' => $baseDir . '/app/ServiceProvider/AuthenticationProvider.php',
'Kanboard\\ServiceProvider\\AvatarProvider' => $baseDir . '/app/ServiceProvider/AvatarProvider.php',
'Kanboard\\ServiceProvider\\CacheProvider' => $baseDir . '/app/ServiceProvider/CacheProvider.php',
'Kanboard\\ServiceProvider\\ClassProvider' => $baseDir . '/app/ServiceProvider/ClassProvider.php',
'Kanboard\\ServiceProvider\\CommandProvider' => $baseDir . '/app/ServiceProvider/CommandProvider.php',
'Kanboard\\ServiceProvider\\DatabaseProvider' => $baseDir . '/app/ServiceProvider/DatabaseProvider.php',
'Kanboard\\ServiceProvider\\EventDispatcherProvider' => $baseDir . '/app/ServiceProvider/EventDispatcherProvider.php',
'Kanboard\\ServiceProvider\\ExternalLinkProvider' => $baseDir . '/app/ServiceProvider/ExternalLinkProvider.php',
'Kanboard\\ServiceProvider\\ExternalTaskProvider' => $baseDir . '/app/ServiceProvider/ExternalTaskProvider.php',
'Kanboard\\ServiceProvider\\FilterProvider' => $baseDir . '/app/ServiceProvider/FilterProvider.php',
'Kanboard\\ServiceProvider\\FormatterProvider' => $baseDir . '/app/ServiceProvider/FormatterProvider.php',
'Kanboard\\ServiceProvider\\GroupProvider' => $baseDir . '/app/ServiceProvider/GroupProvider.php',
'Kanboard\\ServiceProvider\\HelperProvider' => $baseDir . '/app/ServiceProvider/HelperProvider.php',
'Kanboard\\ServiceProvider\\JobProvider' => $baseDir . '/app/ServiceProvider/JobProvider.php',
'Kanboard\\ServiceProvider\\LoggingProvider' => $baseDir . '/app/ServiceProvider/LoggingProvider.php',
'Kanboard\\ServiceProvider\\MailProvider' => $baseDir . '/app/ServiceProvider/MailProvider.php',
'Kanboard\\ServiceProvider\\NotificationProvider' => $baseDir . '/app/ServiceProvider/NotificationProvider.php',
'Kanboard\\ServiceProvider\\PluginProvider' => $baseDir . '/app/ServiceProvider/PluginProvider.php',
'Kanboard\\ServiceProvider\\QueueProvider' => $baseDir . '/app/ServiceProvider/QueueProvider.php',
'Kanboard\\ServiceProvider\\RouteProvider' => $baseDir . '/app/ServiceProvider/RouteProvider.php',
'Kanboard\\ServiceProvider\\SessionProvider' => $baseDir . '/app/ServiceProvider/SessionProvider.php',
'Kanboard\\Subscriber\\AuthSubscriber' => $baseDir . '/app/Subscriber/AuthSubscriber.php',
'Kanboard\\Subscriber\\BaseSubscriber' => $baseDir . '/app/Subscriber/BaseSubscriber.php',
'Kanboard\\Subscriber\\BootstrapSubscriber' => $baseDir . '/app/Subscriber/BootstrapSubscriber.php',
'Kanboard\\Subscriber\\LdapUserPhotoSubscriber' => $baseDir . '/app/Subscriber/LdapUserPhotoSubscriber.php',
'Kanboard\\Subscriber\\NotificationSubscriber' => $baseDir . '/app/Subscriber/NotificationSubscriber.php',
'Kanboard\\Subscriber\\ProjectDailySummarySubscriber' => $baseDir . '/app/Subscriber/ProjectDailySummarySubscriber.php',
'Kanboard\\Subscriber\\ProjectModificationDateSubscriber' => $baseDir . '/app/Subscriber/ProjectModificationDateSubscriber.php',
'Kanboard\\Subscriber\\RecurringTaskSubscriber' => $baseDir . '/app/Subscriber/RecurringTaskSubscriber.php',
'Kanboard\\Subscriber\\TransitionSubscriber' => $baseDir . '/app/Subscriber/TransitionSubscriber.php',
'Kanboard\\User\\Avatar\\AvatarFileProvider' => $baseDir . '/app/User/Avatar/AvatarFileProvider.php',
'Kanboard\\User\\Avatar\\GravatarProvider' => $baseDir . '/app/User/Avatar/GravatarProvider.php',
'Kanboard\\User\\Avatar\\LetterAvatarProvider' => $baseDir . '/app/User/Avatar/LetterAvatarProvider.php',
'Kanboard\\User\\DatabaseUserProvider' => $baseDir . '/app/User/DatabaseUserProvider.php',
'Kanboard\\User\\LdapUserProvider' => $baseDir . '/app/User/LdapUserProvider.php',
'Kanboard\\User\\OAuthUserProvider' => $baseDir . '/app/User/OAuthUserProvider.php',
'Kanboard\\User\\ReverseProxyUserProvider' => $baseDir . '/app/User/ReverseProxyUserProvider.php',
'Kanboard\\Validator\\ActionValidator' => $baseDir . '/app/Validator/ActionValidator.php',
'Kanboard\\Validator\\AuthValidator' => $baseDir . '/app/Validator/AuthValidator.php',
'Kanboard\\Validator\\BaseValidator' => $baseDir . '/app/Validator/BaseValidator.php',
'Kanboard\\Validator\\CategoryValidator' => $baseDir . '/app/Validator/CategoryValidator.php',
'Kanboard\\Validator\\ColumnMoveRestrictionValidator' => $baseDir . '/app/Validator/ColumnMoveRestrictionValidator.php',
'Kanboard\\Validator\\ColumnRestrictionValidator' => $baseDir . '/app/Validator/ColumnRestrictionValidator.php',
'Kanboard\\Validator\\ColumnValidator' => $baseDir . '/app/Validator/ColumnValidator.php',
'Kanboard\\Validator\\CommentValidator' => $baseDir . '/app/Validator/CommentValidator.php',
'Kanboard\\Validator\\CurrencyValidator' => $baseDir . '/app/Validator/CurrencyValidator.php',
'Kanboard\\Validator\\CustomFilterValidator' => $baseDir . '/app/Validator/CustomFilterValidator.php',
'Kanboard\\Validator\\ExternalLinkValidator' => $baseDir . '/app/Validator/ExternalLinkValidator.php',
'Kanboard\\Validator\\GroupValidator' => $baseDir . '/app/Validator/GroupValidator.php',
'Kanboard\\Validator\\LinkValidator' => $baseDir . '/app/Validator/LinkValidator.php',
'Kanboard\\Validator\\PasswordResetValidator' => $baseDir . '/app/Validator/PasswordResetValidator.php',
'Kanboard\\Validator\\ProjectRoleValidator' => $baseDir . '/app/Validator/ProjectRoleValidator.php',
'Kanboard\\Validator\\ProjectValidator' => $baseDir . '/app/Validator/ProjectValidator.php',
'Kanboard\\Validator\\SubtaskValidator' => $baseDir . '/app/Validator/SubtaskValidator.php',
'Kanboard\\Validator\\SwimlaneValidator' => $baseDir . '/app/Validator/SwimlaneValidator.php',
'Kanboard\\Validator\\TagValidator' => $baseDir . '/app/Validator/TagValidator.php',
'Kanboard\\Validator\\TaskLinkValidator' => $baseDir . '/app/Validator/TaskLinkValidator.php',
'Kanboard\\Validator\\TaskValidator' => $baseDir . '/app/Validator/TaskValidator.php',
'Kanboard\\Validator\\UserValidator' => $baseDir . '/app/Validator/UserValidator.php',
'Otp\\GoogleAuthenticator' => $vendorDir . '/christian-riesen/otp/src/Otp/GoogleAuthenticator.php',
'Otp\\Otp' => $vendorDir . '/christian-riesen/otp/src/Otp/Otp.php',
'Otp\\OtpInterface' => $vendorDir . '/christian-riesen/otp/src/Otp/OtpInterface.php',
'Parsedown' => $vendorDir . '/erusev/parsedown/Parsedown.php',
'ParsedownTest' => $vendorDir . '/erusev/parsedown/test/ParsedownTest.php',
'PicoDb\\Builder\\BaseBuilder' => $vendorDir . '/fguillot/picodb/lib/PicoDb/Builder/BaseBuilder.php',
'PicoDb\\Builder\\ConditionBuilder' => $vendorDir . '/fguillot/picodb/lib/PicoDb/Builder/ConditionBuilder.php',
'PicoDb\\Builder\\InsertBuilder' => $vendorDir . '/fguillot/picodb/lib/PicoDb/Builder/InsertBuilder.php',
'PicoDb\\Builder\\OrConditionBuilder' => $vendorDir . '/fguillot/picodb/lib/PicoDb/Builder/OrConditionBuilder.php',
'PicoDb\\Builder\\UpdateBuilder' => $vendorDir . '/fguillot/picodb/lib/PicoDb/Builder/UpdateBuilder.php',
'PicoDb\\Database' => $vendorDir . '/fguillot/picodb/lib/PicoDb/Database.php',
'PicoDb\\DriverFactory' => $vendorDir . '/fguillot/picodb/lib/PicoDb/DriverFactory.php',
'PicoDb\\Driver\\Base' => $vendorDir . '/fguillot/picodb/lib/PicoDb/Driver/Base.php',
'PicoDb\\Driver\\Mssql' => $vendorDir . '/fguillot/picodb/lib/PicoDb/Driver/Mssql.php',
'PicoDb\\Driver\\Mysql' => $vendorDir . '/fguillot/picodb/lib/PicoDb/Driver/Mysql.php',
'PicoDb\\Driver\\Postgres' => $vendorDir . '/fguillot/picodb/lib/PicoDb/Driver/Postgres.php',
'PicoDb\\Driver\\Sqlite' => $vendorDir . '/fguillot/picodb/lib/PicoDb/Driver/Sqlite.php',
'PicoDb\\Hashtable' => $vendorDir . '/fguillot/picodb/lib/PicoDb/Hashtable.php',
'PicoDb\\LargeObject' => $vendorDir . '/fguillot/picodb/lib/PicoDb/LargeObject.php',
'PicoDb\\SQLException' => $vendorDir . '/fguillot/picodb/lib/PicoDb/SQLException.php',
'PicoDb\\Schema' => $vendorDir . '/fguillot/picodb/lib/PicoDb/Schema.php',
'PicoDb\\StatementHandler' => $vendorDir . '/fguillot/picodb/lib/PicoDb/StatementHandler.php',
'PicoDb\\Table' => $vendorDir . '/fguillot/picodb/lib/PicoDb/Table.php',
'PicoDb\\UrlParser' => $vendorDir . '/fguillot/picodb/lib/PicoDb/UrlParser.php',
'PicoFeed\\Base' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Base.php',
'PicoFeed\\Client\\Client' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Client/Client.php',
'PicoFeed\\Client\\ClientException' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Client/ClientException.php',
'PicoFeed\\Client\\Curl' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Client/Curl.php',
'PicoFeed\\Client\\ForbiddenException' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Client/ForbiddenException.php',
'PicoFeed\\Client\\HttpHeaders' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Client/HttpHeaders.php',
'PicoFeed\\Client\\InvalidCertificateException' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Client/InvalidCertificateException.php',
'PicoFeed\\Client\\InvalidUrlException' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Client/InvalidUrlException.php',
'PicoFeed\\Client\\MaxRedirectException' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Client/MaxRedirectException.php',
'PicoFeed\\Client\\MaxSizeException' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Client/MaxSizeException.php',
'PicoFeed\\Client\\Stream' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Client/Stream.php',
'PicoFeed\\Client\\TimeoutException' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Client/TimeoutException.php',
'PicoFeed\\Client\\UnauthorizedException' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Client/UnauthorizedException.php',
'PicoFeed\\Client\\Url' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Client/Url.php',
'PicoFeed\\Config\\Config' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Config/Config.php',
'PicoFeed\\Encoding\\Encoding' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Encoding/Encoding.php',
'PicoFeed\\Filter\\Attribute' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Filter/Attribute.php',
'PicoFeed\\Filter\\Filter' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Filter/Filter.php',
'PicoFeed\\Filter\\Html' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Filter/Html.php',
'PicoFeed\\Filter\\Tag' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Filter/Tag.php',
'PicoFeed\\Generator\\ContentGeneratorInterface' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Generator/ContentGeneratorInterface.php',
'PicoFeed\\Generator\\FileContentGenerator' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Generator/FileContentGenerator.php',
'PicoFeed\\Generator\\YoutubeContentGenerator' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Generator/YoutubeContentGenerator.php',
'PicoFeed\\Logging\\Logger' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Logging/Logger.php',
'PicoFeed\\Parser\\Atom' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Parser/Atom.php',
'PicoFeed\\Parser\\DateParser' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Parser/DateParser.php',
'PicoFeed\\Parser\\Feed' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Parser/Feed.php',
'PicoFeed\\Parser\\Item' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Parser/Item.php',
'PicoFeed\\Parser\\MalformedXmlException' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Parser/MalformedXmlException.php',
'PicoFeed\\Parser\\Parser' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Parser/Parser.php',
'PicoFeed\\Parser\\ParserException' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Parser/ParserException.php',
'PicoFeed\\Parser\\ParserInterface' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Parser/ParserInterface.php',
'PicoFeed\\Parser\\Rss10' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Parser/Rss10.php',
'PicoFeed\\Parser\\Rss20' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Parser/Rss20.php',
'PicoFeed\\Parser\\Rss91' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Parser/Rss91.php',
'PicoFeed\\Parser\\Rss92' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Parser/Rss92.php',
'PicoFeed\\Parser\\XmlEntityException' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Parser/XmlEntityException.php',
'PicoFeed\\Parser\\XmlParser' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Parser/XmlParser.php',
'PicoFeed\\PicoFeedException' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/PicoFeedException.php',
'PicoFeed\\Processor\\ContentFilterProcessor' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Processor/ContentFilterProcessor.php',
'PicoFeed\\Processor\\ContentGeneratorProcessor' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Processor/ContentGeneratorProcessor.php',
'PicoFeed\\Processor\\ItemPostProcessor' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Processor/ItemPostProcessor.php',
'PicoFeed\\Processor\\ItemProcessorInterface' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Processor/ItemProcessorInterface.php',
'PicoFeed\\Processor\\ScraperProcessor' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Processor/ScraperProcessor.php',
'PicoFeed\\Reader\\Favicon' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Reader/Favicon.php',
'PicoFeed\\Reader\\Reader' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Reader/Reader.php',
'PicoFeed\\Reader\\ReaderException' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Reader/ReaderException.php',
'PicoFeed\\Reader\\SubscriptionNotFoundException' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Reader/SubscriptionNotFoundException.php',
'PicoFeed\\Reader\\UnsupportedFeedFormatException' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Reader/UnsupportedFeedFormatException.php',
'PicoFeed\\Scraper\\CandidateParser' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Scraper/CandidateParser.php',
'PicoFeed\\Scraper\\ParserInterface' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Scraper/ParserInterface.php',
'PicoFeed\\Scraper\\RuleLoader' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Scraper/RuleLoader.php',
'PicoFeed\\Scraper\\RuleParser' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Scraper/RuleParser.php',
'PicoFeed\\Scraper\\Scraper' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Scraper/Scraper.php',
'PicoFeed\\Serialization\\Subscription' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Serialization/Subscription.php',
'PicoFeed\\Serialization\\SubscriptionList' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Serialization/SubscriptionList.php',
'PicoFeed\\Serialization\\SubscriptionListBuilder' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Serialization/SubscriptionListBuilder.php',
'PicoFeed\\Serialization\\SubscriptionListParser' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Serialization/SubscriptionListParser.php',
'PicoFeed\\Serialization\\SubscriptionParser' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Serialization/SubscriptionParser.php',
'PicoFeed\\Syndication\\AtomFeedBuilder' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Syndication/AtomFeedBuilder.php',
'PicoFeed\\Syndication\\AtomHelper' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Syndication/AtomHelper.php',
'PicoFeed\\Syndication\\AtomItemBuilder' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Syndication/AtomItemBuilder.php',
'PicoFeed\\Syndication\\FeedBuilder' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Syndication/FeedBuilder.php',
'PicoFeed\\Syndication\\ItemBuilder' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Syndication/ItemBuilder.php',
'PicoFeed\\Syndication\\Rss20FeedBuilder' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Syndication/Rss20FeedBuilder.php',
'PicoFeed\\Syndication\\Rss20Helper' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Syndication/Rss20Helper.php',
'PicoFeed\\Syndication\\Rss20ItemBuilder' => $vendorDir . '/fguillot/picofeed/lib/PicoFeed/Syndication/Rss20ItemBuilder.php',
'Pimple\\Container' => $vendorDir . '/pimple/pimple/src/Pimple/Container.php',
'Pimple\\ServiceProviderInterface' => $vendorDir . '/pimple/pimple/src/Pimple/ServiceProviderInterface.php',
'Pimple\\Tests\\Fixtures\\Invokable' => $vendorDir . '/pimple/pimple/src/Pimple/Tests/Fixtures/Invokable.php',
'Pimple\\Tests\\Fixtures\\NonInvokable' => $vendorDir . '/pimple/pimple/src/Pimple/Tests/Fixtures/NonInvokable.php',
'Pimple\\Tests\\Fixtures\\PimpleServiceProvider' => $vendorDir . '/pimple/pimple/src/Pimple/Tests/Fixtures/PimpleServiceProvider.php',
'Pimple\\Tests\\Fixtures\\Service' => $vendorDir . '/pimple/pimple/src/Pimple/Tests/Fixtures/Service.php',
'Pimple\\Tests\\PimpleServiceProviderInterfaceTest' => $vendorDir . '/pimple/pimple/src/Pimple/Tests/PimpleServiceProviderInterfaceTest.php',
'Pimple\\Tests\\PimpleTest' => $vendorDir . '/pimple/pimple/src/Pimple/Tests/PimpleTest.php',
'Psr\\Log\\AbstractLogger' => $vendorDir . '/psr/log/Psr/Log/AbstractLogger.php',
'Psr\\Log\\InvalidArgumentException' => $vendorDir . '/psr/log/Psr/Log/InvalidArgumentException.php',
'Psr\\Log\\LogLevel' => $vendorDir . '/psr/log/Psr/Log/LogLevel.php',
'Psr\\Log\\LoggerAwareInterface' => $vendorDir . '/psr/log/Psr/Log/LoggerAwareInterface.php',
'Psr\\Log\\LoggerAwareTrait' => $vendorDir . '/psr/log/Psr/Log/LoggerAwareTrait.php',
'Psr\\Log\\LoggerInterface' => $vendorDir . '/psr/log/Psr/Log/LoggerInterface.php',
'Psr\\Log\\LoggerTrait' => $vendorDir . '/psr/log/Psr/Log/LoggerTrait.php',
'Psr\\Log\\NullLogger' => $vendorDir . '/psr/log/Psr/Log/NullLogger.php',
'Psr\\Log\\Test\\DummyTest' => $vendorDir . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php',
'Psr\\Log\\Test\\LoggerInterfaceTest' => $vendorDir . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php',
'SimpleLogger\\Base' => $vendorDir . '/fguillot/simpleLogger/src/SimpleLogger/Base.php',
'SimpleLogger\\File' => $vendorDir . '/fguillot/simpleLogger/src/SimpleLogger/File.php',
'SimpleLogger\\Logger' => $vendorDir . '/fguillot/simpleLogger/src/SimpleLogger/Logger.php',
'SimpleLogger\\Stderr' => $vendorDir . '/fguillot/simpleLogger/src/SimpleLogger/Stderr.php',
'SimpleLogger\\Stdout' => $vendorDir . '/fguillot/simpleLogger/src/SimpleLogger/Stdout.php',
'SimpleLogger\\Syslog' => $vendorDir . '/fguillot/simpleLogger/src/SimpleLogger/Syslog.php',
'SimpleQueue\\Adapter\\AmqpQueueAdapter' => $vendorDir . '/fguillot/simple-queue/src/Adapter/AmqpQueueAdapter.php',
'SimpleQueue\\Adapter\\AwsSqsQueueAdapter' => $vendorDir . '/fguillot/simple-queue/src/Adapter/AwsSqsQueueAdapter.php',
'SimpleQueue\\Adapter\\BeanstalkQueueAdapter' => $vendorDir . '/fguillot/simple-queue/src/Adapter/BeanstalkQueueAdapter.php',
'SimpleQueue\\Adapter\\DisqueQueueAdapter' => $vendorDir . '/fguillot/simple-queue/src/Adapter/DisqueQueueAdapter.php',
'SimpleQueue\\Adapter\\MemoryQueueAdapter' => $vendorDir . '/fguillot/simple-queue/src/Adapter/MemoryQueueAdapter.php',
'SimpleQueue\\Exception\\NotSupportedException' => $vendorDir . '/fguillot/simple-queue/src/Exception/NotSupportedException.php',
'SimpleQueue\\Job' => $vendorDir . '/fguillot/simple-queue/src/Job.php',
'SimpleQueue\\Queue' => $vendorDir . '/fguillot/simple-queue/src/Queue.php',
'SimpleQueue\\QueueAdapterInterface' => $vendorDir . '/fguillot/simple-queue/src/QueueAdapterInterface.php',
'SimpleValidator\\Validator' => $vendorDir . '/fguillot/simple-validator/src/SimpleValidator/Validator.php',
'SimpleValidator\\Validators\\Alpha' => $vendorDir . '/fguillot/simple-validator/src/SimpleValidator/Validators/Alpha.php',
'SimpleValidator\\Validators\\AlphaNumeric' => $vendorDir . '/fguillot/simple-validator/src/SimpleValidator/Validators/AlphaNumeric.php',
'SimpleValidator\\Validators\\Base' => $vendorDir . '/fguillot/simple-validator/src/SimpleValidator/Validators/Base.php',
'SimpleValidator\\Validators\\Date' => $vendorDir . '/fguillot/simple-validator/src/SimpleValidator/Validators/Date.php',
'SimpleValidator\\Validators\\Email' => $vendorDir . '/fguillot/simple-validator/src/SimpleValidator/Validators/Email.php',
'SimpleValidator\\Validators\\Equals' => $vendorDir . '/fguillot/simple-validator/src/SimpleValidator/Validators/Equals.php',
'SimpleValidator\\Validators\\Exists' => $vendorDir . '/fguillot/simple-validator/src/SimpleValidator/Validators/Exists.php',
'SimpleValidator\\Validators\\GreaterThan' => $vendorDir . '/fguillot/simple-validator/src/SimpleValidator/Validators/GreaterThan.php',
'SimpleValidator\\Validators\\InArray' => $vendorDir . '/fguillot/simple-validator/src/SimpleValidator/Validators/InArray.php',
'SimpleValidator\\Validators\\Integer' => $vendorDir . '/fguillot/simple-validator/src/SimpleValidator/Validators/Integer.php',
'SimpleValidator\\Validators\\Ip' => $vendorDir . '/fguillot/simple-validator/src/SimpleValidator/Validators/Ip.php',
'SimpleValidator\\Validators\\Length' => $vendorDir . '/fguillot/simple-validator/src/SimpleValidator/Validators/Length.php',
'SimpleValidator\\Validators\\MaxLength' => $vendorDir . '/fguillot/simple-validator/src/SimpleValidator/Validators/MaxLength.php',
'SimpleValidator\\Validators\\MinLength' => $vendorDir . '/fguillot/simple-validator/src/SimpleValidator/Validators/MinLength.php',
'SimpleValidator\\Validators\\NotEmpty' => $vendorDir . '/fguillot/simple-validator/src/SimpleValidator/Validators/NotEmpty.php',
'SimpleValidator\\Validators\\NotEquals' => $vendorDir . '/fguillot/simple-validator/src/SimpleValidator/Validators/NotEquals.php',
'SimpleValidator\\Validators\\NotInArray' => $vendorDir . '/fguillot/simple-validator/src/SimpleValidator/Validators/NotInArray.php',
'SimpleValidator\\Validators\\Numeric' => $vendorDir . '/fguillot/simple-validator/src/SimpleValidator/Validators/Numeric.php',
'SimpleValidator\\Validators\\Range' => $vendorDir . '/fguillot/simple-validator/src/SimpleValidator/Validators/Range.php',
'SimpleValidator\\Validators\\Required' => $vendorDir . '/fguillot/simple-validator/src/SimpleValidator/Validators/Required.php',
'SimpleValidator\\Validators\\Unique' => $vendorDir . '/fguillot/simple-validator/src/SimpleValidator/Validators/Unique.php',
'Symfony\\Component\\Console\\Application' => $vendorDir . '/symfony/console/Application.php',
'Symfony\\Component\\Console\\Command\\Command' => $vendorDir . '/symfony/console/Command/Command.php',
'Symfony\\Component\\Console\\Command\\HelpCommand' => $vendorDir . '/symfony/console/Command/HelpCommand.php',
'Symfony\\Component\\Console\\Command\\ListCommand' => $vendorDir . '/symfony/console/Command/ListCommand.php',
'Symfony\\Component\\Console\\ConsoleEvents' => $vendorDir . '/symfony/console/ConsoleEvents.php',
'Symfony\\Component\\Console\\Descriptor\\ApplicationDescription' => $vendorDir . '/symfony/console/Descriptor/ApplicationDescription.php',
'Symfony\\Component\\Console\\Descriptor\\Descriptor' => $vendorDir . '/symfony/console/Descriptor/Descriptor.php',
'Symfony\\Component\\Console\\Descriptor\\DescriptorInterface' => $vendorDir . '/symfony/console/Descriptor/DescriptorInterface.php',
'Symfony\\Component\\Console\\Descriptor\\JsonDescriptor' => $vendorDir . '/symfony/console/Descriptor/JsonDescriptor.php',
'Symfony\\Component\\Console\\Descriptor\\MarkdownDescriptor' => $vendorDir . '/symfony/console/Descriptor/MarkdownDescriptor.php',
'Symfony\\Component\\Console\\Descriptor\\TextDescriptor' => $vendorDir . '/symfony/console/Descriptor/TextDescriptor.php',
'Symfony\\Component\\Console\\Descriptor\\XmlDescriptor' => $vendorDir . '/symfony/console/Descriptor/XmlDescriptor.php',
'Symfony\\Component\\Console\\Event\\ConsoleCommandEvent' => $vendorDir . '/symfony/console/Event/ConsoleCommandEvent.php',
'Symfony\\Component\\Console\\Event\\ConsoleEvent' => $vendorDir . '/symfony/console/Event/ConsoleEvent.php',
'Symfony\\Component\\Console\\Event\\ConsoleExceptionEvent' => $vendorDir . '/symfony/console/Event/ConsoleExceptionEvent.php',
'Symfony\\Component\\Console\\Event\\ConsoleTerminateEvent' => $vendorDir . '/symfony/console/Event/ConsoleTerminateEvent.php',
'Symfony\\Component\\Console\\Exception\\CommandNotFoundException' => $vendorDir . '/symfony/console/Exception/CommandNotFoundException.php',
'Symfony\\Component\\Console\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/console/Exception/ExceptionInterface.php',
'Symfony\\Component\\Console\\Exception\\InvalidArgumentException' => $vendorDir . '/symfony/console/Exception/InvalidArgumentException.php',
'Symfony\\Component\\Console\\Exception\\InvalidOptionException' => $vendorDir . '/symfony/console/Exception/InvalidOptionException.php',
'Symfony\\Component\\Console\\Exception\\LogicException' => $vendorDir . '/symfony/console/Exception/LogicException.php',
'Symfony\\Component\\Console\\Exception\\RuntimeException' => $vendorDir . '/symfony/console/Exception/RuntimeException.php',
'Symfony\\Component\\Console\\Formatter\\OutputFormatter' => $vendorDir . '/symfony/console/Formatter/OutputFormatter.php',
'Symfony\\Component\\Console\\Formatter\\OutputFormatterInterface' => $vendorDir . '/symfony/console/Formatter/OutputFormatterInterface.php',
'Symfony\\Component\\Console\\Formatter\\OutputFormatterStyle' => $vendorDir . '/symfony/console/Formatter/OutputFormatterStyle.php',
'Symfony\\Component\\Console\\Formatter\\OutputFormatterStyleInterface' => $vendorDir . '/symfony/console/Formatter/OutputFormatterStyleInterface.php',
'Symfony\\Component\\Console\\Formatter\\OutputFormatterStyleStack' => $vendorDir . '/symfony/console/Formatter/OutputFormatterStyleStack.php',
'Symfony\\Component\\Console\\Helper\\DebugFormatterHelper' => $vendorDir . '/symfony/console/Helper/DebugFormatterHelper.php',
'Symfony\\Component\\Console\\Helper\\DescriptorHelper' => $vendorDir . '/symfony/console/Helper/DescriptorHelper.php',
'Symfony\\Component\\Console\\Helper\\DialogHelper' => $vendorDir . '/symfony/console/Helper/DialogHelper.php',
'Symfony\\Component\\Console\\Helper\\FormatterHelper' => $vendorDir . '/symfony/console/Helper/FormatterHelper.php',
'Symfony\\Component\\Console\\Helper\\Helper' => $vendorDir . '/symfony/console/Helper/Helper.php',
'Symfony\\Component\\Console\\Helper\\HelperInterface' => $vendorDir . '/symfony/console/Helper/HelperInterface.php',
'Symfony\\Component\\Console\\Helper\\HelperSet' => $vendorDir . '/symfony/console/Helper/HelperSet.php',
'Symfony\\Component\\Console\\Helper\\InputAwareHelper' => $vendorDir . '/symfony/console/Helper/InputAwareHelper.php',
'Symfony\\Component\\Console\\Helper\\ProcessHelper' => $vendorDir . '/symfony/console/Helper/ProcessHelper.php',
'Symfony\\Component\\Console\\Helper\\ProgressBar' => $vendorDir . '/symfony/console/Helper/ProgressBar.php',
'Symfony\\Component\\Console\\Helper\\ProgressHelper' => $vendorDir . '/symfony/console/Helper/ProgressHelper.php',
'Symfony\\Component\\Console\\Helper\\ProgressIndicator' => $vendorDir . '/symfony/console/Helper/ProgressIndicator.php',
'Symfony\\Component\\Console\\Helper\\QuestionHelper' => $vendorDir . '/symfony/console/Helper/QuestionHelper.php',
'Symfony\\Component\\Console\\Helper\\SymfonyQuestionHelper' => $vendorDir . '/symfony/console/Helper/SymfonyQuestionHelper.php',
'Symfony\\Component\\Console\\Helper\\Table' => $vendorDir . '/symfony/console/Helper/Table.php',
'Symfony\\Component\\Console\\Helper\\TableCell' => $vendorDir . '/symfony/console/Helper/TableCell.php',
'Symfony\\Component\\Console\\Helper\\TableHelper' => $vendorDir . '/symfony/console/Helper/TableHelper.php',
'Symfony\\Component\\Console\\Helper\\TableSeparator' => $vendorDir . '/symfony/console/Helper/TableSeparator.php',
'Symfony\\Component\\Console\\Helper\\TableStyle' => $vendorDir . '/symfony/console/Helper/TableStyle.php',
'Symfony\\Component\\Console\\Input\\ArgvInput' => $vendorDir . '/symfony/console/Input/ArgvInput.php',
'Symfony\\Component\\Console\\Input\\ArrayInput' => $vendorDir . '/symfony/console/Input/ArrayInput.php',
'Symfony\\Component\\Console\\Input\\Input' => $vendorDir . '/symfony/console/Input/Input.php',
'Symfony\\Component\\Console\\Input\\InputArgument' => $vendorDir . '/symfony/console/Input/InputArgument.php',
'Symfony\\Component\\Console\\Input\\InputAwareInterface' => $vendorDir . '/symfony/console/Input/InputAwareInterface.php',
'Symfony\\Component\\Console\\Input\\InputDefinition' => $vendorDir . '/symfony/console/Input/InputDefinition.php',
'Symfony\\Component\\Console\\Input\\InputInterface' => $vendorDir . '/symfony/console/Input/InputInterface.php',
'Symfony\\Component\\Console\\Input\\InputOption' => $vendorDir . '/symfony/console/Input/InputOption.php',
'Symfony\\Component\\Console\\Input\\StringInput' => $vendorDir . '/symfony/console/Input/StringInput.php',
'Symfony\\Component\\Console\\Logger\\ConsoleLogger' => $vendorDir . '/symfony/console/Logger/ConsoleLogger.php',
'Symfony\\Component\\Console\\Output\\BufferedOutput' => $vendorDir . '/symfony/console/Output/BufferedOutput.php',
'Symfony\\Component\\Console\\Output\\ConsoleOutput' => $vendorDir . '/symfony/console/Output/ConsoleOutput.php',
'Symfony\\Component\\Console\\Output\\ConsoleOutputInterface' => $vendorDir . '/symfony/console/Output/ConsoleOutputInterface.php',
'Symfony\\Component\\Console\\Output\\NullOutput' => $vendorDir . '/symfony/console/Output/NullOutput.php',
'Symfony\\Component\\Console\\Output\\Output' => $vendorDir . '/symfony/console/Output/Output.php',
'Symfony\\Component\\Console\\Output\\OutputInterface' => $vendorDir . '/symfony/console/Output/OutputInterface.php',
'Symfony\\Component\\Console\\Output\\StreamOutput' => $vendorDir . '/symfony/console/Output/StreamOutput.php',
'Symfony\\Component\\Console\\Question\\ChoiceQuestion' => $vendorDir . '/symfony/console/Question/ChoiceQuestion.php',
'Symfony\\Component\\Console\\Question\\ConfirmationQuestion' => $vendorDir . '/symfony/console/Question/ConfirmationQuestion.php',
'Symfony\\Component\\Console\\Question\\Question' => $vendorDir . '/symfony/console/Question/Question.php',
'Symfony\\Component\\Console\\Shell' => $vendorDir . '/symfony/console/Shell.php',
'Symfony\\Component\\Console\\Style\\OutputStyle' => $vendorDir . '/symfony/console/Style/OutputStyle.php',
'Symfony\\Component\\Console\\Style\\StyleInterface' => $vendorDir . '/symfony/console/Style/StyleInterface.php',
'Symfony\\Component\\Console\\Style\\SymfonyStyle' => $vendorDir . '/symfony/console/Style/SymfonyStyle.php',
'Symfony\\Component\\Console\\Tester\\ApplicationTester' => $vendorDir . '/symfony/console/Tester/ApplicationTester.php',
'Symfony\\Component\\Console\\Tester\\CommandTester' => $vendorDir . '/symfony/console/Tester/CommandTester.php',
'Symfony\\Component\\EventDispatcher\\ContainerAwareEventDispatcher' => $vendorDir . '/symfony/event-dispatcher/ContainerAwareEventDispatcher.php',
'Symfony\\Component\\EventDispatcher\\Debug\\TraceableEventDispatcher' => $vendorDir . '/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php',
'Symfony\\Component\\EventDispatcher\\Debug\\TraceableEventDispatcherInterface' => $vendorDir . '/symfony/event-dispatcher/Debug/TraceableEventDispatcherInterface.php',
'Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener' => $vendorDir . '/symfony/event-dispatcher/Debug/WrappedListener.php',
'Symfony\\Component\\EventDispatcher\\DependencyInjection\\RegisterListenersPass' => $vendorDir . '/symfony/event-dispatcher/DependencyInjection/RegisterListenersPass.php',
'Symfony\\Component\\EventDispatcher\\Event' => $vendorDir . '/symfony/event-dispatcher/Event.php',
'Symfony\\Component\\EventDispatcher\\EventDispatcher' => $vendorDir . '/symfony/event-dispatcher/EventDispatcher.php',
'Symfony\\Component\\EventDispatcher\\EventDispatcherInterface' => $vendorDir . '/symfony/event-dispatcher/EventDispatcherInterface.php',
'Symfony\\Component\\EventDispatcher\\EventSubscriberInterface' => $vendorDir . '/symfony/event-dispatcher/EventSubscriberInterface.php',
'Symfony\\Component\\EventDispatcher\\GenericEvent' => $vendorDir . '/symfony/event-dispatcher/GenericEvent.php',
'Symfony\\Component\\EventDispatcher\\ImmutableEventDispatcher' => $vendorDir . '/symfony/event-dispatcher/ImmutableEventDispatcher.php',
'Symfony\\Polyfill\\Mbstring\\Mbstring' => $vendorDir . '/symfony/polyfill-mbstring/Mbstring.php',
'ZendXml\\Exception\\ExceptionInterface' => $vendorDir . '/zendframework/zendxml/library/ZendXml/Exception/ExceptionInterface.php',
'ZendXml\\Exception\\InvalidArgumentException' => $vendorDir . '/zendframework/zendxml/library/ZendXml/Exception/InvalidArgumentException.php',
'ZendXml\\Exception\\RuntimeException' => $vendorDir . '/zendframework/zendxml/library/ZendXml/Exception/RuntimeException.php',
'ZendXml\\Security' => $vendorDir . '/zendframework/zendxml/library/ZendXml/Security.php',
);

View file

@ -1,15 +0,0 @@
<?php
// autoload_files.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
'5255c38a0faeba867671b61dfda6d864' => $vendorDir . '/paragonie/random_compat/lib/random.php',
'8cd2fca4db21bffce1ad0612f7caeec4' => $vendorDir . '/ramsey/array_column/src/array_column.php',
'2c102faa651ef8ea5874edb585946bce' => $vendorDir . '/swiftmailer/swiftmailer/lib/swift_required.php',
'f51af1d1e172536bcdb5baf6f649449d' => $baseDir . '/app/functions.php',
'da6e17f7b0fa11d4819751ff2afd0bac' => $baseDir . '/app/Library/password.php',
);

View file

@ -1,20 +0,0 @@
<?php
// autoload_namespaces.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'ZendXml\\' => array($vendorDir . '/zendframework/zendxml/library'),
'SimpleValidator' => array($vendorDir . '/fguillot/simple-validator/src'),
'SimpleLogger' => array($vendorDir . '/fguillot/simpleLogger/src'),
'Psr\\Log\\' => array($vendorDir . '/psr/log'),
'Pimple' => array($vendorDir . '/pimple/pimple/src'),
'PicoFeed' => array($vendorDir . '/fguillot/picofeed/lib'),
'PicoDb' => array($vendorDir . '/fguillot/picodb/lib'),
'Parsedown' => array($vendorDir . '/erusev/parsedown'),
'Otp' => array($vendorDir . '/christian-riesen/otp/src'),
'JsonRPC' => array($vendorDir . '/fguillot/json-rpc/src'),
'Eluceo\\iCal' => array($vendorDir . '/eluceo/ical/src'),
);

View file

@ -1,16 +0,0 @@
<?php
// autoload_psr4.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'),
'Symfony\\Component\\EventDispatcher\\' => array($vendorDir . '/symfony/event-dispatcher'),
'Symfony\\Component\\Console\\' => array($vendorDir . '/symfony/console'),
'SimpleQueue\\' => array($vendorDir . '/fguillot/simple-queue/src'),
'Kanboard\\' => array($baseDir . '/app'),
'Gregwar\\Captcha\\' => array($vendorDir . '/gregwar/captcha'),
'Base32\\' => array($vendorDir . '/christian-riesen/base32/src'),
);

View file

@ -1,70 +0,0 @@
<?php
// autoload_real.php @generated by Composer
class ComposerAutoloaderInit2cd1f3bd373661a524b2e9ae060681e4
{
private static $loader;
public static function loadClassLoader($class)
{
if ('Composer\Autoload\ClassLoader' === $class) {
require __DIR__ . '/ClassLoader.php';
}
}
public static function getLoader()
{
if (null !== self::$loader) {
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInit2cd1f3bd373661a524b2e9ae060681e4', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
spl_autoload_unregister(array('ComposerAutoloaderInit2cd1f3bd373661a524b2e9ae060681e4', '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';
call_user_func(\Composer\Autoload\ComposerStaticInit2cd1f3bd373661a524b2e9ae060681e4::getInitializer($loader));
} else {
$map = require __DIR__ . '/autoload_namespaces.php';
foreach ($map as $namespace => $path) {
$loader->set($namespace, $path);
}
$map = require __DIR__ . '/autoload_psr4.php';
foreach ($map as $namespace => $path) {
$loader->setPsr4($namespace, $path);
}
$classMap = require __DIR__ . '/autoload_classmap.php';
if ($classMap) {
$loader->addClassMap($classMap);
}
}
$loader->register(true);
if ($useStaticLoader) {
$includeFiles = Composer\Autoload\ComposerStaticInit2cd1f3bd373661a524b2e9ae060681e4::$files;
} else {
$includeFiles = require __DIR__ . '/autoload_files.php';
}
foreach ($includeFiles as $fileIdentifier => $file) {
composerRequire2cd1f3bd373661a524b2e9ae060681e4($fileIdentifier, $file);
}
return $loader;
}
}
function composerRequire2cd1f3bd373661a524b2e9ae060681e4($fileIdentifier, $file)
{
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
require $file;
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,990 +0,0 @@
[
{
"name": "christian-riesen/base32",
"version": "1.3.1",
"version_normalized": "1.3.1.0",
"source": {
"type": "git",
"url": "https://github.com/ChristianRiesen/base32.git",
"reference": "0a31e50c0fa9b1692d077c86ac188eecdcbaf7fa"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ChristianRiesen/base32/zipball/0a31e50c0fa9b1692d077c86ac188eecdcbaf7fa",
"reference": "0a31e50c0fa9b1692d077c86ac188eecdcbaf7fa",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"require-dev": {
"phpunit/phpunit": "4.*",
"satooshi/php-coveralls": "0.*"
},
"time": "2016-05-05T11:49:03+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.1.x-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-4": {
"Base32\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Christian Riesen",
"email": "chris.riesen@gmail.com",
"homepage": "http://christianriesen.com",
"role": "Developer"
}
],
"description": "Base32 encoder/decoder according to RFC 4648",
"homepage": "https://github.com/ChristianRiesen/base32",
"keywords": [
"base32",
"decode",
"encode",
"rfc4648"
]
},
{
"name": "christian-riesen/otp",
"version": "1.4.3",
"version_normalized": "1.4.3.0",
"source": {
"type": "git",
"url": "https://github.com/ChristianRiesen/otp.git",
"reference": "20a539ce6280eb029030f4e7caefd5709a75e1ad"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ChristianRiesen/otp/zipball/20a539ce6280eb029030f4e7caefd5709a75e1ad",
"reference": "20a539ce6280eb029030f4e7caefd5709a75e1ad",
"shasum": ""
},
"require": {
"christian-riesen/base32": ">=1.0",
"php": ">=5.3.0"
},
"suggest": {
"paragonie/random_compat": "Optional polyfill for a more secure random generator for pre PHP7 versions"
},
"time": "2015-10-08T08:17:59+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-0": {
"Otp": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Christian Riesen",
"email": "chris.riesen@gmail.com",
"homepage": "http://christianriesen.com",
"role": "Developer"
}
],
"description": "One Time Passwords, hotp and totp according to RFC4226 and RFC6238",
"homepage": "https://github.com/ChristianRiesen/otp",
"keywords": [
"googleauthenticator",
"hotp",
"otp",
"rfc4226",
"rfc6238",
"totp"
]
},
{
"name": "eluceo/ical",
"version": "0.10.1",
"version_normalized": "0.10.1.0",
"source": {
"type": "git",
"url": "https://github.com/markuspoerschke/iCal.git",
"reference": "2dd99c12c0aa961c541380ab0c113135e14af33e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/markuspoerschke/iCal/zipball/2dd99c12c0aa961c541380ab0c113135e14af33e",
"reference": "2dd99c12c0aa961c541380ab0c113135e14af33e",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"require-dev": {
"phpunit/phpunit": "~4.3"
},
"time": "2016-06-09T09:08:55+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-0": {
"Eluceo\\iCal": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Maciej Łebkowski",
"email": "m.lebkowski@gmail.com",
"role": "Contributor"
},
{
"name": "Markus Poerschke",
"email": "markus@eluceo.de",
"role": "Developer"
}
],
"description": "The eluceo/iCal package offers a abstraction layer for creating iCalendars. You can easily create iCal files by using PHP object instead of typing your *.ics file by hand. The output will follow RFC 2445 as best as possible.",
"homepage": "https://github.com/markuspoerschke/iCal",
"keywords": [
"calendar",
"iCalendar",
"ical",
"ics",
"php calendar"
]
},
{
"name": "erusev/parsedown",
"version": "1.6.0",
"version_normalized": "1.6.0.0",
"source": {
"type": "git",
"url": "https://github.com/erusev/parsedown.git",
"reference": "3ebbd730b5c2cf5ce78bc1bf64071407fc6674b7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/erusev/parsedown/zipball/3ebbd730b5c2cf5ce78bc1bf64071407fc6674b7",
"reference": "3ebbd730b5c2cf5ce78bc1bf64071407fc6674b7",
"shasum": ""
},
"time": "2015-10-04T16:44:32+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-0": {
"Parsedown": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Emanuil Rusev",
"email": "hello@erusev.com",
"homepage": "http://erusev.com"
}
],
"description": "Parser for Markdown.",
"homepage": "http://parsedown.org",
"keywords": [
"markdown",
"parser"
]
},
{
"name": "fguillot/json-rpc",
"version": "v1.2.1",
"version_normalized": "1.2.1.0",
"source": {
"type": "git",
"url": "https://github.com/fguillot/JsonRPC.git",
"reference": "d491bb549bfa11aff4c37abcea2ffb28c9523f69"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/fguillot/JsonRPC/zipball/d491bb549bfa11aff4c37abcea2ffb28c9523f69",
"reference": "d491bb549bfa11aff4c37abcea2ffb28c9523f69",
"shasum": ""
},
"require": {
"php": ">=5.3.4"
},
"require-dev": {
"phpunit/phpunit": "4.8.*"
},
"time": "2016-06-25T23:11:10+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-0": {
"JsonRPC": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Frédéric Guillot"
}
],
"description": "Simple Json-RPC client/server library that just works",
"homepage": "https://github.com/fguillot/JsonRPC"
},
{
"name": "fguillot/picodb",
"version": "v1.0.14",
"version_normalized": "1.0.14.0",
"source": {
"type": "git",
"url": "https://github.com/fguillot/picoDb.git",
"reference": "86a831302ab10af800c83dbe4b3b01c88d5433f1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/fguillot/picoDb/zipball/86a831302ab10af800c83dbe4b3b01c88d5433f1",
"reference": "86a831302ab10af800c83dbe4b3b01c88d5433f1",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"require-dev": {
"phpunit/phpunit": "4.8.*"
},
"time": "2016-07-16T22:59:59+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-0": {
"PicoDb": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Frédéric Guillot",
"homepage": "https://github.com/fguillot/"
}
],
"description": "Minimalist database query builder",
"homepage": "https://github.com/fguillot/picoDb"
},
{
"name": "zendframework/zendxml",
"version": "1.0.2",
"version_normalized": "1.0.2.0",
"source": {
"type": "git",
"url": "https://github.com/zendframework/ZendXml.git",
"reference": "7b64507bc35d841c9c5802d67f6f87ef8e1a58c9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/zendframework/ZendXml/zipball/7b64507bc35d841c9c5802d67f6f87ef8e1a58c9",
"reference": "7b64507bc35d841c9c5802d67f6f87ef8e1a58c9",
"shasum": ""
},
"require": {
"php": "^5.3.3 || ^7.0"
},
"require-dev": {
"phpunit/phpunit": "^3.7 || ^4.0",
"squizlabs/php_codesniffer": "^1.5"
},
"time": "2016-02-04T21:02:08+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-0": {
"ZendXml\\": "library/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"description": "Utility library for XML usage, best practices, and security in PHP",
"homepage": "http://packages.zendframework.com/",
"keywords": [
"security",
"xml",
"zf2"
]
},
{
"name": "fguillot/picofeed",
"version": "v0.1.24",
"version_normalized": "0.1.24.0",
"source": {
"type": "git",
"url": "https://github.com/fguillot/picoFeed.git",
"reference": "25f9653ca663e098f51eabbdf495eb9a130c041b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/fguillot/picoFeed/zipball/25f9653ca663e098f51eabbdf495eb9a130c041b",
"reference": "25f9653ca663e098f51eabbdf495eb9a130c041b",
"shasum": ""
},
"require": {
"ext-dom": "*",
"ext-iconv": "*",
"ext-libxml": "*",
"ext-simplexml": "*",
"ext-xml": "*",
"php": ">=5.3.0",
"zendframework/zendxml": "^1.0"
},
"suggest": {
"ext-curl": "PicoFeed will use cURL if present"
},
"time": "2016-07-03T00:02:03+00:00",
"bin": [
"picofeed"
],
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-0": {
"PicoFeed": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Frédéric Guillot"
}
],
"description": "Modern library to handle RSS/Atom feeds",
"homepage": "https://github.com/fguillot/picoFeed"
},
{
"name": "fguillot/simple-queue",
"version": "v1.0.1",
"version_normalized": "1.0.1.0",
"source": {
"type": "git",
"url": "https://github.com/fguillot/simple-queue.git",
"reference": "ce7801c507f9501bcca455129fb04c3d2107d5ff"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/fguillot/simple-queue/zipball/ce7801c507f9501bcca455129fb04c3d2107d5ff",
"reference": "ce7801c507f9501bcca455129fb04c3d2107d5ff",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"aws/aws-sdk-php": "~3.0",
"mariano/disque-php": "~2.0",
"pda/pheanstalk": "~3.0",
"php-amqplib/php-amqplib": "2.6.*",
"phpunit/phpunit": "5.3.*"
},
"suggest": {
"aws/aws-sdk-php": "Required to use the AWS SQS queue driver (~3.0).",
"mariano/disque-php": "Required to use the Disque queue driver (~2.0).",
"pda/pheanstalk": "Required to use the Beanstalk queue driver (~3.0).",
"php-amqplib/php-amqplib": "Required to use the RabbitMQ queue driver (2.6.*)."
},
"time": "2016-06-05T21:34:56+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-4": {
"SimpleQueue\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Frédéric Guillot"
}
],
"description": "Abstraction layer for multiple queue systems",
"homepage": "https://github.com/fguillot/simple-queue"
},
{
"name": "fguillot/simple-validator",
"version": "v1.0.1",
"version_normalized": "1.0.1.0",
"source": {
"type": "git",
"url": "https://github.com/fguillot/simpleValidator.git",
"reference": "23b0a99c5f11ad74d05f8845feaafbcfd9223eda"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/fguillot/simpleValidator/zipball/23b0a99c5f11ad74d05f8845feaafbcfd9223eda",
"reference": "23b0a99c5f11ad74d05f8845feaafbcfd9223eda",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"time": "2016-06-26T15:09:26+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-0": {
"SimpleValidator": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Frédéric Guillot"
}
],
"description": "Simple validator library",
"homepage": "https://github.com/fguillot/simpleValidator"
},
{
"name": "psr/log",
"version": "1.0.0",
"version_normalized": "1.0.0.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/log.git",
"reference": "fe0936ee26643249e916849d48e3a51d5f5e278b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b",
"reference": "fe0936ee26643249e916849d48e3a51d5f5e278b",
"shasum": ""
},
"time": "2012-12-21T11:40:51+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-0": {
"Psr\\Log\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common interface for logging libraries",
"keywords": [
"log",
"psr",
"psr-3"
]
},
{
"name": "fguillot/simpleLogger",
"version": "v1.0.1",
"version_normalized": "1.0.1.0",
"source": {
"type": "git",
"url": "https://github.com/fguillot/simpleLogger.git",
"reference": "c6831841193bb265b7900ecc8b6a8918371a7c98"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/fguillot/simpleLogger/zipball/c6831841193bb265b7900ecc8b6a8918371a7c98",
"reference": "c6831841193bb265b7900ecc8b6a8918371a7c98",
"shasum": ""
},
"require": {
"php": ">=5.3.0",
"psr/log": "~1.0"
},
"time": "2016-05-07T18:01:57+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-0": {
"SimpleLogger": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Frédéric Guillot"
}
],
"description": "PHP library to write logs (compatible with PSR-3)",
"homepage": "https://github.com/fguillot/simpleLogger"
},
{
"name": "gregwar/captcha",
"version": "v1.1.1",
"version_normalized": "1.1.1.0",
"source": {
"type": "git",
"url": "https://github.com/Gregwar/Captcha.git",
"reference": "1240ab993ca713680573b2d4166900da5f758623"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Gregwar/Captcha/zipball/1240ab993ca713680573b2d4166900da5f758623",
"reference": "1240ab993ca713680573b2d4166900da5f758623",
"shasum": ""
},
"require": {
"ext-gd": "*",
"php": ">=5.3.0"
},
"time": "2015-09-11T15:23:20+00:00",
"type": "captcha",
"installation-source": "dist",
"autoload": {
"psr-4": {
"Gregwar\\Captcha\\": "/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Grégoire Passault",
"email": "g.passault@gmail.com",
"homepage": "http://www.gregwar.com/"
},
{
"name": "Jeremy Livingston",
"email": "jeremy.j.livingston@gmail.com"
}
],
"description": "Captcha generator",
"homepage": "https://github.com/Gregwar/Captcha",
"keywords": [
"bot",
"captcha",
"spam"
]
},
{
"name": "paragonie/random_compat",
"version": "v2.0.2",
"version_normalized": "2.0.2.0",
"source": {
"type": "git",
"url": "https://github.com/paragonie/random_compat.git",
"reference": "088c04e2f261c33bed6ca5245491cfca69195ccf"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/088c04e2f261c33bed6ca5245491cfca69195ccf",
"reference": "088c04e2f261c33bed6ca5245491cfca69195ccf",
"shasum": ""
},
"require": {
"php": ">=5.2.0"
},
"require-dev": {
"phpunit/phpunit": "4.*|5.*"
},
"suggest": {
"ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
},
"time": "2016-04-03T06:00:07+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"files": [
"lib/random.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Paragon Initiative Enterprises",
"email": "security@paragonie.com",
"homepage": "https://paragonie.com"
}
],
"description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
"keywords": [
"csprng",
"pseudorandom",
"random"
]
},
{
"name": "pimple/pimple",
"version": "v3.0.2",
"version_normalized": "3.0.2.0",
"source": {
"type": "git",
"url": "https://github.com/silexphp/Pimple.git",
"reference": "a30f7d6e57565a2e1a316e1baf2a483f788b258a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/silexphp/Pimple/zipball/a30f7d6e57565a2e1a316e1baf2a483f788b258a",
"reference": "a30f7d6e57565a2e1a316e1baf2a483f788b258a",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"time": "2015-09-11T15:10:35+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.0.x-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-0": {
"Pimple": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
}
],
"description": "Pimple, a simple Dependency Injection Container",
"homepage": "http://pimple.sensiolabs.org",
"keywords": [
"container",
"dependency injection"
]
},
{
"name": "ramsey/array_column",
"version": "1.1.3",
"version_normalized": "1.1.3.0",
"source": {
"type": "git",
"url": "https://github.com/ramsey/array_column.git",
"reference": "f8e52eb28e67eb50e613b451dd916abcf783c1db"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ramsey/array_column/zipball/f8e52eb28e67eb50e613b451dd916abcf783c1db",
"reference": "f8e52eb28e67eb50e613b451dd916abcf783c1db",
"shasum": ""
},
"require-dev": {
"jakub-onderka/php-parallel-lint": "0.8.*",
"phpunit/phpunit": "~4.5",
"satooshi/php-coveralls": "0.6.*",
"squizlabs/php_codesniffer": "~2.2"
},
"time": "2015-03-20T22:07:39+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"files": [
"src/array_column.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Ben Ramsey",
"homepage": "http://benramsey.com"
}
],
"description": "Provides functionality for array_column() to projects using PHP earlier than version 5.5.",
"homepage": "https://github.com/ramsey/array_column",
"keywords": [
"array",
"array_column",
"column"
]
},
{
"name": "swiftmailer/swiftmailer",
"version": "v5.4.2",
"version_normalized": "5.4.2.0",
"source": {
"type": "git",
"url": "https://github.com/swiftmailer/swiftmailer.git",
"reference": "d8db871a54619458a805229a057ea2af33c753e8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/d8db871a54619458a805229a057ea2af33c753e8",
"reference": "d8db871a54619458a805229a057ea2af33c753e8",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"mockery/mockery": "~0.9.1,<0.9.4"
},
"time": "2016-05-01T08:45:47+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "5.4-dev"
}
},
"installation-source": "dist",
"autoload": {
"files": [
"lib/swift_required.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Chris Corbyn"
},
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
}
],
"description": "Swiftmailer, free feature-rich PHP mailer",
"homepage": "http://swiftmailer.org",
"keywords": [
"email",
"mail",
"mailer"
]
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.2.0",
"version_normalized": "1.2.0.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "dff51f72b0706335131b00a7f49606168c582594"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/dff51f72b0706335131b00a7f49606168c582594",
"reference": "dff51f72b0706335131b00a7f49606168c582594",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"suggest": {
"ext-mbstring": "For best performance"
},
"time": "2016-05-18T14:26:46+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.2-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Mbstring\\": ""
},
"files": [
"bootstrap.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for the Mbstring extension",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"mbstring",
"polyfill",
"portable",
"shim"
]
},
{
"name": "symfony/console",
"version": "v2.8.7",
"version_normalized": "2.8.7.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
"reference": "5ac8bc9aa77bb2edf06af3a1bb6bc1020d23acd3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/5ac8bc9aa77bb2edf06af3a1bb6bc1020d23acd3",
"reference": "5ac8bc9aa77bb2edf06af3a1bb6bc1020d23acd3",
"shasum": ""
},
"require": {
"php": ">=5.3.9",
"symfony/polyfill-mbstring": "~1.0"
},
"require-dev": {
"psr/log": "~1.0",
"symfony/event-dispatcher": "~2.1|~3.0.0",
"symfony/process": "~2.1|~3.0.0"
},
"suggest": {
"psr/log": "For using the console logger",
"symfony/event-dispatcher": "",
"symfony/process": ""
},
"time": "2016-06-06T15:06:25+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.8-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-4": {
"Symfony\\Component\\Console\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony Console Component",
"homepage": "https://symfony.com"
},
{
"name": "symfony/event-dispatcher",
"version": "v2.7.14",
"version_normalized": "2.7.14.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher.git",
"reference": "d3e09ed1224503791f31b913d22196f65f9afed5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/d3e09ed1224503791f31b913d22196f65f9afed5",
"reference": "d3e09ed1224503791f31b913d22196f65f9afed5",
"shasum": ""
},
"require": {
"php": ">=5.3.9"
},
"require-dev": {
"psr/log": "~1.0",
"symfony/config": "~2.0,>=2.0.5",
"symfony/dependency-injection": "~2.6",
"symfony/expression-language": "~2.6",
"symfony/stopwatch": "~2.3"
},
"suggest": {
"symfony/dependency-injection": "",
"symfony/http-kernel": ""
},
"time": "2016-06-06T11:03:51+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.7-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-4": {
"Symfony\\Component\\EventDispatcher\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony EventDispatcher Component",
"homepage": "https://symfony.com"
}
]

View file

@ -1,3 +0,0 @@
vendor
composer.lock
bin

View file

@ -1,26 +0,0 @@
<?php
Symfony\CS\Fixer\Contrib\HeaderCommentFixer::setHeader(<<<EOF
This file is part of the eluceo/iCal package.
(c) Markus Poerschke <markus@eluceo.de>
This source file is subject to the MIT license that is bundled
with this source code in the file LICENSE.
EOF
);
$finder = Symfony\CS\Finder\DefaultFinder::create();
$finder->in(__DIR__ . '/src');
return Symfony\CS\Config\Config::create()
->fixers(array(
'header_comment',
'concat_with_spaces',
'align_equals',
'align_double_arrow',
'unused_use',
'long_array_syntax',
))
->finder($finder)
;

View file

@ -1,20 +0,0 @@
filter:
excluded_paths:
- tests/*
tools:
php_cs_fixer: true
php_code_sniffer:
config:
standard: PSR2
php_mess_detector: true
php_analyzer: true
sensiolabs_security_checker: true
external_code_coverage:
timeout: 300
runs: 1
checks:
php:
code_rating: true
duplication: true

View file

@ -1,19 +0,0 @@
language: php
php:
- 5.3
- 5.4
- 5.5
- 5.6
- 7.0
- hhvm
before_script:
- composer self-update
- composer install
script: ./bin/phpunit --coverage-clover=coverage.clover
after_script:
- wget https://scrutinizer-ci.com/ocular.phar
- php ocular.phar code-coverage:upload --format=php-clover coverage.clover

View file

@ -1,31 +0,0 @@
# Change Log
All notable changes to this project will be documented in this file.
## [0.10.1] - 2016-05-09
### Fixed
- Problem with GEO property when importing into Google Calendar [#74](https://github.com/markuspoerschke/iCal/pull/74)
## [0.10.0] - 2016-04-26
### Changed
- Use 'escapeValue' to escape the new line character. [#60](https://github.com/markuspoerschke/iCal/pull/60)
- Order components by type when building ical file. [#65](https://github.com/markuspoerschke/iCal/pull/65)
### Added
- X-ALT-DESC for HTML types with new descriptionHTML field. [#55](https://github.com/markuspoerschke/iCal/pull/55)
- Added a property and setter for calendar color. [#68](https://github.com/markuspoerschke/iCal/pull/68)
- Write also GEO property if geo location is given. [#66](https://github.com/markuspoerschke/iCal/pull/66)
## [0.9.0] - 2015-11-13
### Added
- CHANGELOG.md based on [Keep a CHANGELOG](https://github.com/olivierlacan/keep-a-changelog)
- Support event properties EXDATE and RECURRENCE-ID [#50](https://github.com/markuspoerschke/iCal/pull/53)
### Changed
- Allow new lines in event descriptions [#53](https://github.com/markuspoerschke/iCal/pull/53)
- **Breaking Change:** Changed signature of the ```Event::setOrganizer``` method. Now there is is only one parameter that must be an instance of ```Property\Organizer```.
- Updated install section in README.md [#54](https://github.com/markuspoerschke/iCal/pull/53)
[Unreleased]: https://github.com/markuspoerschke/iCal/compare/0.10.1...HEAD
[0.10.1]: https://github.com/markuspoerschke/iCal/compare/0.10.0...0.10.1
[0.10.0]: https://github.com/markuspoerschke/iCal/compare/0.9.0...0.10.0
[0.9.0]: https://github.com/markuspoerschke/iCal/compare/0.8.0...0.9.0

View file

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

View file

@ -1,158 +0,0 @@
# eluceo — iCal
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/markuspoerschke/iCal/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/markuspoerschke/iCal/?branch=master) [![Code Coverage](https://scrutinizer-ci.com/g/markuspoerschke/iCal/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/markuspoerschke/iCal/?branch=master) [![Build Status](https://travis-ci.org/markuspoerschke/iCal.svg?branch=master)](https://travis-ci.org/markuspoerschke/iCal)
This package offers a abstraction layer for creating iCalendars. The output will
follow [RFC 5545](http://www.ietf.org/rfc/rfc5545.txt) as best as possible.
The following components are supported at this time:
* VCALENDAR
* VEVENT
* VALARM
* VTIMEZONE
## Installation
You can install this package by using [Composer](http://getcomposer.org), running this command:
```sh
composer require eluceo/ical
```
Link to Packagist: https://packagist.org/packages/eluceo/ical
## Usage
### Basic Usage
#### 1. Create a Calendar object
```PHP
$vCalendar = new \Eluceo\iCal\Component\Calendar('www.example.com');
```
#### 2. Create an Event object
```PHP
$vEvent = new \Eluceo\iCal\Component\Event();
```
#### 3. Add your information to the Event
```PHP
$vEvent
->setDtStart(new \DateTime('2012-12-24'))
->setDtEnd(new \DateTime('2012-12-24'))
->setNoTime(true)
->setSummary('Christmas')
;
```
#### 4. Add Event to Calendar
```PHP
$vCalendar->addComponent($vEvent);
```
#### 5. Set HTTP-headers
```PHP
header('Content-Type: text/calendar; charset=utf-8');
header('Content-Disposition: attachment; filename="cal.ics"');
```
#### 6. Send output
```PHP
echo $vCalendar->render();
```
### Timezone support
This package supports three different types of handling timezones:
#### 1. UTC (default)
In the default setting, UTC/GMT will be used as Timezone. The time will be formated as following:
```
DTSTART:20121224T180000Z
```
#### 2. Use explicit timezone
You can use an explicit timezone by calling `$vEvent->setUseTimezone(true);`. The timezone of your
`\DateTime` object will be used. In this case the non-standard field "X-WR-TIMEZONE" will be used.
Be awre that this is a simple solution which is not supported by all calendar clients.
The output will be as following:
```
DTSTART;TZID=Europe/Berlin:20121224T180000
```
#### 3. Use explicit timezone with definition
You can use an explicit timezone and define it using `Timezone()` and `TimezoneRule()` (see example5.php).
The timezone of your `\DateTime` object will be used. The output will be as following:
```
BEGIN:VTIMEZONE
TZID:Europe/Berlin
X-LIC-LOCATION:Europe/Berlin
BEGIN:DAYLIGHT
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
DTSTART:19810329T030000
RRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=3;BYDAY=-1SU
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
DTSTART:19961027T030000
RRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=10;BYDAY=-1SU
END:STANDARD
END:VTIMEZONE
...
DTSTART;TZID=Europe/Berlin:20121224T180000
```
#### 4. Use locale time
You can use local time by calling `$vEvent->setUseUtc(false);`. The output will be:
```
DTSTART:20121224T180000
```
## Running the tests
To setup and run tests:
- go to the root directory of this project
- download composer: `wget https://getcomposer.org/composer.phar`
- install dev dependencies: `php composer.phar install --dev`
- run `./bin/phpunit`
## License
This package is released under the __MIT license__.
Copyright (c) 2012-2015 Markus Poerschke
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View file

@ -1,9 +0,0 @@
# v0.8.0 -> v0.9.0
- The signature of the ```Event::setOrganizer``` method was changed:
Now there is is only one parameter that must be an instance of ```Property\Organizer```.
# v0.7.0 -> v0.8.0
- The signature of the ```Event::setOrganizer``` method was changed: Now there are
two parameters name and email instead of an already formatted string.

View file

@ -1,43 +0,0 @@
{
"name": "eluceo/ical",
"description": "The eluceo/iCal package offers a abstraction layer for creating iCalendars. You can easily create iCal files by using PHP object instead of typing your *.ics file by hand. The output will follow RFC 2445 as best as possible.",
"license": "MIT",
"homepage": "https://github.com/markuspoerschke/iCal",
"authors": [
{
"name": "Markus Poerschke",
"email": "markus@eluceo.de",
"role": "Developer"
},
{
"name": "Maciej Łebkowski",
"email": "m.lebkowski@gmail.com",
"role": "Contributor"
}
],
"keywords": [
"ical",
"php calendar",
"icalendar",
"ics",
"calendar"
],
"support": {
"issues": "https://github.com/markuspoerschke/iCal/issues",
"source": "https://github.com/markuspoerschke/iCal"
},
"autoload": {
"psr-0": {
"Eluceo\\iCal": "src/"
}
},
"require": {
"php": ">=5.3.0"
},
"require-dev": {
"phpunit/phpunit": "~4.3"
},
"config": {
"bin-dir": "bin"
}
}

View file

@ -1,30 +0,0 @@
<?php
// use composer autoloader
require_once __DIR__ . '/../vendor/autoload.php';
// set default timezone (PHP 5.4)
date_default_timezone_set('Europe/Berlin');
// 1. Create new calendar
$vCalendar = new \Eluceo\iCal\Component\Calendar('www.example.com');
// 2. Create an event
$vEvent = new \Eluceo\iCal\Component\Event();
$vEvent->setDtStart(new \DateTime('2012-12-24'));
$vEvent->setDtEnd(new \DateTime('2012-12-24'));
$vEvent->setNoTime(true);
$vEvent->setSummary('Christmas');
// Adding Timezone (optional)
$vEvent->setUseTimezone(true);
// 3. Add event to calendar
$vCalendar->addComponent($vEvent);
// 4. Set headers
header('Content-Type: text/calendar; charset=utf-8');
header('Content-Disposition: attachment; filename="cal.ics"');
// 5. Output
echo $vCalendar->render();

View file

@ -1,31 +0,0 @@
<?php
// use composer autoloader
require_once __DIR__ . '/../vendor/autoload.php';
// set default timezone (PHP 5.4)
date_default_timezone_set('Europe/Berlin');
// 1. Create new calendar
$vCalendar = new \Eluceo\iCal\Component\Calendar('www.example.com');
// 2. Create an event
$vEvent = new \Eluceo\iCal\Component\Event();
$vEvent->setDtStart(new \DateTime('2012-12-24'));
$vEvent->setDtEnd(new \DateTime('2012-12-24'));
$vEvent->setNoTime(true);
$vEvent->setSummary('Summary with some german "umlauten" and a backslash \\: Kinder mögen Äpfel pflücken.');
$vEvent->setCategories(['holidays']);
// Adding Timezone (optional)
$vEvent->setUseTimezone(true);
// 3. Add event to calendar
$vCalendar->addComponent($vEvent);
// 4. Set headers
header('Content-Type: text/calendar; charset=utf-8');
header('Content-Disposition: attachment; filename="cal.ics"');
// 5. Output
echo $vCalendar->render();

View file

@ -1,36 +0,0 @@
<?php
// use composer autoloader
require_once __DIR__ . '/../vendor/autoload.php';
// set default timezone (PHP 5.4)
date_default_timezone_set('Europe/Berlin');
// 1. Create new calendar
$vCalendar = new \Eluceo\iCal\Component\Calendar('www.example.com');
// 2. Create an event
$vEvent = new \Eluceo\iCal\Component\Event();
$vEvent->setDtStart(new \DateTime('2012-12-31'));
$vEvent->setDtEnd(new \DateTime('2012-12-31'));
$vEvent->setNoTime(true);
$vEvent->setSummary('New Years Eve');
// Set recurrence rule
$recurrenceRule = new \Eluceo\iCal\Property\Event\RecurrenceRule();
$recurrenceRule->setFreq(\Eluceo\iCal\Property\Event\RecurrenceRule::FREQ_YEARLY);
$recurrenceRule->setInterval(1);
$vEvent->setRecurrenceRule($recurrenceRule);
// Adding Timezone (optional)
$vEvent->setUseTimezone(true);
// 3. Add event to calendar
$vCalendar->addComponent($vEvent);
// 4. Set headers
header('Content-Type: text/calendar; charset=utf-8');
header('Content-Disposition: attachment; filename="cal.ics"');
// 5. Output
echo $vCalendar->render();

View file

@ -1,35 +0,0 @@
<?php
// use composer autoloader
require_once __DIR__ . '/../vendor/autoload.php';
// set default timezone (PHP 5.4)
date_default_timezone_set('Europe/Berlin');
// 1. Create new calendar
$vCalendar = new \Eluceo\iCal\Component\Calendar('www.example.com');
// 2. Create an event
$vEvent = new \Eluceo\iCal\Component\Event();
$vEvent->setDtStart(new \DateTime('2012-11-11 13:00:00'));
$vEvent->setDtEnd(new \DateTime('2012-11-11 14:30:00'));
$vEvent->setSummary('Weekly lunch with Markus');
// Set recurrence rule
$recurrenceRule = new \Eluceo\iCal\Property\Event\RecurrenceRule();
$recurrenceRule->setFreq(\Eluceo\iCal\Property\Event\RecurrenceRule::FREQ_WEEKLY);
$recurrenceRule->setInterval(1);
$vEvent->setRecurrenceRule($recurrenceRule);
// Adding Timezone (optional)
$vEvent->setUseTimezone(true);
// 3. Add event to calendar
$vCalendar->addComponent($vEvent);
// 4. Set headers
header('Content-Type: text/calendar; charset=utf-8');
header('Content-Disposition: attachment; filename="cal.ics"');
// 5. Output
echo $vCalendar->render();

View file

@ -1,66 +0,0 @@
<?php
/**
* example to show how to create an ICal calendar which
* provides a full timezone definition
*/
// use composer autoloader
require_once __DIR__ . '/../vendor/autoload.php';
// set default timezone (PHP 5.4)
$tz = 'Europe/Berlin';
$dtz = new \DateTimeZone($tz);
date_default_timezone_set($tz);
// 1. Create new calendar
$vCalendar = new \Eluceo\iCal\Component\Calendar('www.example.com');
// 2. Create timezone rule object for Daylight Saving Time
$vTimezoneRuleDst = new \Eluceo\iCal\Component\TimezoneRule(\Eluceo\iCal\Component\TimezoneRule::TYPE_DAYLIGHT);
$vTimezoneRuleDst->setTzName('CEST');
$vTimezoneRuleDst->setDtStart(new \DateTime('1981-03-29 02:00:00', $dtz));
$vTimezoneRuleDst->setTzOffsetFrom('+0100');
$vTimezoneRuleDst->setTzOffsetTo('+0200');
$dstRecurrenceRule = new \Eluceo\iCal\Property\Event\RecurrenceRule();
$dstRecurrenceRule->setFreq(\Eluceo\iCal\Property\Event\RecurrenceRule::FREQ_YEARLY);
$dstRecurrenceRule->setByMonth(3);
$dstRecurrenceRule->setByDay('-1SU');
$vTimezoneRuleDst->setRecurrenceRule($dstRecurrenceRule);
// 3. Create timezone rule object for Standard Time
$vTimezoneRuleStd = new \Eluceo\iCal\Component\TimezoneRule(\Eluceo\iCal\Component\TimezoneRule::TYPE_STANDARD);
$vTimezoneRuleStd->setTzName('CET');
$vTimezoneRuleStd->setDtStart(new \DateTime('1996-10-27 03:00:00', $dtz));
$vTimezoneRuleStd->setTzOffsetFrom('+0200');
$vTimezoneRuleStd->setTzOffsetTo('+0100');
$stdRecurrenceRule = new \Eluceo\iCal\Property\Event\RecurrenceRule();
$stdRecurrenceRule->setFreq(\Eluceo\iCal\Property\Event\RecurrenceRule::FREQ_YEARLY);
$stdRecurrenceRule->setByMonth(10);
$stdRecurrenceRule->setByDay('-1SU');
$vTimezoneRuleStd->setRecurrenceRule($stdRecurrenceRule);
// 4. Create timezone definition and add rules
$vTimezone = new \Eluceo\iCal\Component\Timezone($tz);
$vTimezone->addComponent($vTimezoneRuleDst);
$vTimezone->addComponent($vTimezoneRuleStd);
$vCalendar->setTimezone($vTimezone);
// 5. Create an event
$vEvent = new \Eluceo\iCal\Component\Event();
$vEvent->setDtStart(new \DateTime('2012-12-24', $dtz));
$vEvent->setDtEnd(new \DateTime('2012-12-24', $dtz));
$vEvent->setSummary('Summary with some german "umlauten" and a backslash \\: Kinder mögen Äpfel pflücken.');
// 6. Adding Timezone
$vEvent->setUseTimezone(true);
// 7. Add event to calendar
$vCalendar->addComponent($vEvent);
// 8. Set headers
header('Content-Type: text/calendar; charset=utf-8');
header('Content-Disposition: attachment; filename="cal.ics"');
// 9. Output
echo $vCalendar->render();

View file

@ -1,30 +0,0 @@
<?php
// use composer autoloader
require_once __DIR__ . '/../vendor/autoload.php';
// set default timezone (PHP 5.4)
date_default_timezone_set('Europe/Berlin');
// 1. Create new calendar
$vCalendar = new \Eluceo\iCal\Component\Calendar('www.example.com');
// 2. Create an event
$vEvent = new \Eluceo\iCal\Component\Event();
$vEvent->setDtStart(new \DateTime('2012-12-24'));
$vEvent->setDtEnd(new \DateTime('2012-12-24'));
$vEvent->setNoTime(true);
$vEvent->setSummary('Christmas');
// add some location information for apple devices
$vEvent->setLocation("Infinite Loop\nCupertino CA 95014", 'Infinite Loop', '37.332095,-122.030743');
// 3. Add event to calendar
$vCalendar->addComponent($vEvent);
// 4. Set headers
header('Content-Type: text/calendar; charset=utf-8');
header('Content-Disposition: attachment; filename="cal.ics"');
// 5. Output
echo $vCalendar->render();

View file

@ -1,33 +0,0 @@
<?php
// use composer autoloader
require_once __DIR__ . '/../vendor/autoload.php';
// set default timezone (PHP 5.4)
date_default_timezone_set('Europe/Berlin');
// 1. Create new calendar
$vCalendar = new \Eluceo\iCal\Component\Calendar('www.example.com');
// 2. Create an event
$vEvent = new \Eluceo\iCal\Component\Event();
$vEvent->setDtStart(new \DateTime('2012-12-24'));
$vEvent->setDtEnd(new \DateTime('2012-12-24'));
$vEvent->setNoTime(true);
$vEvent->setSummary('Christmas');
$vEvent->setDescription('Happy Christmas!');
$vEvent->setDescriptionHTML('<b>Happy Christmas!</b>');
// add some location information for apple devices
$vEvent->setLocation("Infinite Loop\nCupertino CA 95014", 'Infinite Loop', '37.332095,-122.030743');
// 3. Add event to calendar
$vCalendar->addComponent($vEvent);
// 4. Set headers
header('Content-Type: text/calendar; charset=utf-8');
header('Content-Disposition: attachment; filename="cal.ics"');
// 5. Output
echo $vCalendar->render();

View file

@ -1,21 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false"
bootstrap="./vendor/autoload.php">
<logging>
<log type="coverage-text" target="php://stdout" showUncoveredFiles="true" showOnlySummary="true"/>
</logging>
<testsuites>
<testsuite name="eluceo iCal Test Suite">
<directory suffix="Test.php">./tests/Eluceo/iCal/</directory>
</testsuite>
</testsuites>
</phpunit>

View file

@ -1,172 +0,0 @@
<?php
/*
* This file is part of the eluceo/iCal package.
*
* (c) Markus Poerschke <markus@eluceo.de>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Eluceo\iCal;
use Eluceo\iCal\Util\ComponentUtil;
/**
* Abstract Calender Component.
*/
abstract class Component
{
/**
* Array of Components.
*
* @var Component[]
*/
protected $components = array();
/**
* The order in which the components will be rendered during build.
*
* Not defined components will be appended at the end.
*
* @var array
*/
private $componentsBuildOrder = array('VTIMEZONE', 'DAYLIGHT', 'STANDARD');
/**
* The type of the concrete Component.
*
* @abstract
*
* @return string
*/
abstract public function getType();
/**
* Building the PropertyBag.
*
* @abstract
*
* @return PropertyBag
*/
abstract public function buildPropertyBag();
/**
* Adds a Component.
*
* If $key is given, the component at $key will be replaced else the component will be append.
*
* @param Component $component The Component that will be added
* @param null $key The key of the Component
*/
public function addComponent(Component $component, $key = null)
{
if (null == $key) {
$this->components[] = $component;
} else {
$this->components[$key] = $component;
}
}
/**
* Renders an array containing the lines of the iCal file.
*
* @return array
*/
public function build()
{
$lines = array();
$lines[] = sprintf('BEGIN:%s', $this->getType());
/** @var $property Property */
foreach ($this->buildPropertyBag() as $property) {
foreach ($property->toLines() as $l) {
$lines[] = $l;
}
}
$this->buildComponents($lines);
$lines[] = sprintf('END:%s', $this->getType());
$ret = array();
foreach ($lines as $line) {
foreach (ComponentUtil::fold($line) as $l) {
$ret[] = $l;
}
}
return $ret;
}
/**
* Renders the output.
*
* @return string
*/
public function render()
{
return implode("\r\n", $this->build());
}
/**
* Renders the output when treating the class as a string.
*
* @return string
*/
public function __toString()
{
return $this->render();
}
/**
* @param $lines
*
* @return array
*/
private function buildComponents(array &$lines)
{
$componentsByType = array();
/** @var $component Component */
foreach ($this->components as $component) {
$type = $component->getType();
if (!isset($componentsByType[$type])) {
$componentsByType[$type] = array();
}
$componentsByType[$type][] = $component;
}
// render ordered components
foreach ($this->componentsBuildOrder as $type) {
if (!isset($componentsByType[$type])) {
continue;
}
foreach ($componentsByType[$type] as $component) {
$this->addComponentLines($lines, $component);
}
unset($componentsByType[$type]);
}
// render all other
foreach ($componentsByType as $components) {
foreach ($components as $component) {
$this->addComponentLines($lines, $component);
}
}
}
/**
* @param array $lines
* @param Component $component
*/
private function addComponentLines(array &$lines, Component $component)
{
foreach ($component->build() as $l) {
$lines[] = $l;
}
}
}

View file

@ -1,151 +0,0 @@
<?php
/*
* This file is part of the eluceo/iCal package.
*
* (c) Markus Poerschke <markus@eluceo.de>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Eluceo\iCal\Component;
use Eluceo\iCal\Component;
use Eluceo\iCal\PropertyBag;
use Eluceo\iCal\Property;
/**
* Implementation of the VALARM component.
*/
class Alarm extends Component
{
/**
* Alarm ACTION property.
*
* According to RFC 5545: 3.8.6.1. Action
*
* @link http://tools.ietf.org/html/rfc5545#section-3.8.6.1
*/
const ACTION_AUDIO = 'AUDIO';
const ACTION_DISPLAY = 'DISPLAY';
const ACTION_EMAIL = 'EMAIL';
protected $action;
protected $repeat;
protected $duration;
protected $description;
protected $attendee;
protected $trigger;
public function getType()
{
return 'VALARM';
}
public function getAction()
{
return $this->action;
}
public function getRepeat()
{
return $this->repeat;
}
public function getDuration()
{
return $this->duration;
}
public function getDescription()
{
return $this->description;
}
public function getAttendee()
{
return $this->attendee;
}
public function getTrigger()
{
return $this->trigger;
}
public function setAction($action)
{
$this->action = $action;
return $this;
}
public function setRepeat($repeat)
{
$this->repeat = $repeat;
return $this;
}
public function setDuration($duration)
{
$this->duration = $duration;
return $this;
}
public function setDescription($description)
{
$this->description = $description;
return $this;
}
public function setAttendee($attendee)
{
$this->attendee = $attendee;
return $this;
}
public function setTrigger($trigger)
{
$this->trigger = $trigger;
return $this;
}
/**
* {@inheritdoc}
*/
public function buildPropertyBag()
{
$propertyBag = new PropertyBag();
if (null != $this->trigger) {
$propertyBag->set('TRIGGER', $this->trigger);
}
if (null != $this->action) {
$propertyBag->set('ACTION', $this->action);
}
if (null != $this->repeat) {
$propertyBag->set('REPEAT', $this->repeat);
}
if (null != $this->duration) {
$propertyBag->set('DURATION', $this->duration);
}
if (null != $this->description) {
$propertyBag->set('DESCRIPTION', $this->description);
}
if (null != $this->attendee) {
$propertyBag->set('ATTENDEE', $this->attendee);
}
return $propertyBag;
}
}

View file

@ -1,323 +0,0 @@
<?php
/*
* This file is part of the eluceo/iCal package.
*
* (c) Markus Poerschke <markus@eluceo.de>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Eluceo\iCal\Component;
use Eluceo\iCal\Component;
use Eluceo\iCal\PropertyBag;
class Calendar extends Component
{
/**
* Methods for calendar components.
*
* According to RFP 5545: 3.7.2. Method
*
* @link http://tools.ietf.org/html/rfc5545#section-3.7.2
*
* And then according to RFC 2446: 3 APPLICATION PROTOCOL ELEMENTS
* @link https://www.ietf.org/rfc/rfc2446.txt
*/
const METHOD_PUBLISH = 'PUBLISH';
const METHOD_REQUEST = 'REQUEST';
const METHOD_REPLY = 'REPLY';
const METHOD_ADD = 'ADD';
const METHOD_CANCEL = 'CANCEL';
const METHOD_REFRESH = 'REFRESH';
const METHOD_COUNTER = 'COUNTER';
const METHOD_DECLINECOUNTER = 'DECLINECOUNTER';
/**
* This property defines the calendar scale used for the calendar information specified in the iCalendar object.
*
* According to RFC 5545: 3.7.1. Calendar Scale
*
* @link http://tools.ietf.org/html/rfc5545#section-3.7
*/
const CALSCALE_GREGORIAN = 'GREGORIAN';
/**
* The Product Identifier.
*
* According to RFC 2445: 4.7.3 Product Identifier
*
* This property specifies the identifier for the product that created the Calendar object.
*
* @link http://www.ietf.org/rfc/rfc2445.txt
*
* @var string
*/
protected $prodId = null;
protected $method = null;
protected $name = null;
protected $description = null;
protected $timezone = null;
/**
* This property defines the calendar scale used for the
* calendar information specified in the iCalendar object.
*
* Also identifies the calendar type of a non-Gregorian recurring appointment.
*
* @var string
*
* @see http://tools.ietf.org/html/rfc5545#section-3.7
* @see http://msdn.microsoft.com/en-us/library/ee237520(v=exchg.80).aspx
*/
protected $calendarScale = null;
/**
* Specifies whether or not the iCalendar file only contains one appointment.
*
* @var bool
*
* @see http://msdn.microsoft.com/en-us/library/ee203486(v=exchg.80).aspx
*/
protected $forceInspectOrOpen = false;
/**
* Specifies a globally unique identifier for the calendar.
*
* @var string
*
* @see http://msdn.microsoft.com/en-us/library/ee179588(v=exchg.80).aspx
*/
protected $calId = null;
/**
* Specifies a suggested iCalendar file download frequency for clients and
* servers with sync capabilities.
*
* @var string
*
* @see http://msdn.microsoft.com/en-us/library/ee178699(v=exchg.80).aspx
*/
protected $publishedTTL = 'P1W';
/**
* Specifies a color for the calendar in calendar for Apple/Outlook.
*
* @var string
*
* @see http://msdn.microsoft.com/en-us/library/ee179588(v=exchg.80).aspx
*/
protected $calendarColor = null;
public function __construct($prodId)
{
if (empty($prodId)) {
throw new \UnexpectedValueException('PRODID cannot be empty');
}
$this->prodId = $prodId;
}
/**
* {@inheritdoc}
*/
public function getType()
{
return 'VCALENDAR';
}
/**
* @param $method
*
* @return $this
*/
public function setMethod($method)
{
$this->method = $method;
return $this;
}
/**
* @param $name
*
* @return $this
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* @param $description
*
* @return $this
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* @param $timezone
*
* @return $this
*/
public function setTimezone($timezone)
{
$this->timezone = $timezone;
return $this;
}
/**
* @param $calendarColor
*
* @return $this
*/
public function setCalendarColor($calendarColor)
{
$this->calendarColor = $calendarColor;
return $this;
}
/**
* @param $calendarScale
*
* @return $this
*/
public function setCalendarScale($calendarScale)
{
$this->calendarScale = $calendarScale;
return $this;
}
/**
* @param bool $forceInspectOrOpen
*
* @return $this
*/
public function setForceInspectOrOpen($forceInspectOrOpen)
{
$this->forceInspectOrOpen = $forceInspectOrOpen;
return $this;
}
/**
* @param string $calId
*
* @return $this
*/
public function setCalId($calId)
{
$this->calId = $calId;
return $this;
}
/**
* @param string $ttl
*
* @return $this
*/
public function setPublishedTTL($ttl)
{
$this->publishedTTL = $ttl;
return $this;
}
/**
* {@inheritdoc}
*/
public function buildPropertyBag()
{
$propertyBag = new PropertyBag();
$propertyBag->set('VERSION', '2.0');
$propertyBag->set('PRODID', $this->prodId);
if ($this->method) {
$propertyBag->set('METHOD', $this->method);
}
if ($this->calendarColor) {
$propertyBag->set('X-APPLE-CALENDAR-COLOR', $this->calendarColor);
$propertyBag->set('X-OUTLOOK-COLOR', $this->calendarColor);
$propertyBag->set('X-FUNAMBOL-COLOR', $this->calendarColor);
}
if ($this->calendarScale) {
$propertyBag->set('CALSCALE', $this->calendarScale);
$propertyBag->set('X-MICROSOFT-CALSCALE', $this->calendarScale);
}
if ($this->name) {
$propertyBag->set('X-WR-CALNAME', $this->name);
}
if ($this->description) {
$propertyBag->set('X-WR-CALDESC', $this->description);
}
if ($this->timezone) {
if ($this->timezone instanceof Timezone) {
$propertyBag->set('X-WR-TIMEZONE', $this->timezone->getZoneIdentifier());
$this->addComponent($this->timezone);
} else {
$propertyBag->set('X-WR-TIMEZONE', $this->timezone);
$this->addComponent(new Timezone($this->timezone));
}
}
if ($this->forceInspectOrOpen) {
$propertyBag->set('X-MS-OLK-FORCEINSPECTOROPEN', $this->forceInspectOrOpen);
}
if ($this->calId) {
$propertyBag->set('X-WR-RELCALID', $this->calId);
}
if ($this->publishedTTL) {
$propertyBag->set('X-PUBLISHED-TTL', $this->publishedTTL);
}
return $propertyBag;
}
/**
* Adds an Event to the Calendar.
*
* Wrapper for addComponent()
*
* @see Eluceo\iCal::addComponent
* @deprecated Please, use public method addComponent() from abstract Component class
*
* @param Event $event
*/
public function addEvent(Event $event)
{
$this->addComponent($event);
}
/**
* @return null|string
*/
public function getProdId()
{
return $this->prodId;
}
public function getMethod()
{
return $this->method;
}
}

View file

@ -1,783 +0,0 @@
<?php
/*
* This file is part of the eluceo/iCal package.
*
* (c) Markus Poerschke <markus@eluceo.de>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Eluceo\iCal\Component;
use Eluceo\iCal\Component;
use Eluceo\iCal\Property;
use Eluceo\iCal\Property\DateTimeProperty;
use Eluceo\iCal\Property\Event\Attendees;
use Eluceo\iCal\Property\Event\Organizer;
use Eluceo\iCal\Property\Event\RecurrenceRule;
use Eluceo\iCal\Property\Event\Description;
use Eluceo\iCal\PropertyBag;
use Eluceo\iCal\Property\Event\RecurrenceId;
use Eluceo\iCal\Property\DateTimesProperty;
/**
* Implementation of the EVENT component.
*/
class Event extends Component
{
const TIME_TRANSPARENCY_OPAQUE = 'OPAQUE';
const TIME_TRANSPARENCY_TRANSPARENT = 'TRANSPARENT';
const STATUS_TENTATIVE = 'TENTATIVE';
const STATUS_CONFIRMED = 'CONFIRMED';
const STATUS_CANCELLED = 'CANCELLED';
/**
* @var string
*/
protected $uniqueId;
/**
* The property indicates the date/time that the instance of
* the iCalendar object was created.
*
* The value MUST be specified in the UTC time format.
*
* @var \DateTime
*/
protected $dtStamp;
/**
* @var \DateTime
*/
protected $dtStart;
/**
* Preferentially chosen over the duration if both are set.
*
* @var \DateTime
*/
protected $dtEnd;
/**
* @var \DateInterval
*/
protected $duration;
/**
* @var bool
*/
protected $noTime = false;
/**
* @var string
*/
protected $url;
/**
* @var string
*/
protected $location;
/**
* @var string
*/
protected $locationTitle;
/**
* @var string
*/
protected $locationGeo;
/**
* @var string
*/
protected $summary;
/**
* @var Organizer
*/
protected $organizer;
/**
* @see http://www.ietf.org/rfc/rfc2445.txt 4.8.2.7 Time Transparency
*
* @var string
*/
protected $transparency = self::TIME_TRANSPARENCY_OPAQUE;
/**
* If set to true the timezone will be added to the event.
*
* @var bool
*/
protected $useTimezone = false;
/**
* @var int
*/
protected $sequence = 0;
/**
* @var Attendees
*/
protected $attendees;
/**
* @var string
*/
protected $description;
/**
* @var string
*/
protected $descriptionHTML;
/**
* @var string
*/
protected $status;
/**
* @var RecurrenceRule
*/
protected $recurrenceRule;
/**
* This property specifies the date and time that the calendar
* information was created.
*
* The value MUST be specified in the UTC time format.
*
* @var \DateTime
*/
protected $created;
/**
* The property specifies the date and time that the information
* associated with the calendar component was last revised.
*
* The value MUST be specified in the UTC time format.
*
* @var \DateTime
*/
protected $modified;
/**
* Indicates if the UTC time should be used or not.
*
* @var bool
*/
protected $useUtc = true;
/**
* @var bool
*/
protected $cancelled;
/**
* This property is used to specify categories or subtypes
* of the calendar component. The categories are useful in searching
* for a calendar component of a particular type and category.
*
* @see https://tools.ietf.org/html/rfc5545#section-3.8.1.2
*
* @var array
*/
protected $categories;
/**
* https://tools.ietf.org/html/rfc5545#section-3.8.1.3.
*
* @var bool
*/
protected $isPrivate = false;
/**
* Dates to be excluded from a series of events.
*
* @var \DateTime[]
*/
protected $exDates = array();
/**
* @var RecurrenceId
*/
protected $recurrenceId;
public function __construct($uniqueId = null)
{
if (null == $uniqueId) {
$uniqueId = uniqid();
}
$this->uniqueId = $uniqueId;
}
/**
* {@inheritdoc}
*/
public function getType()
{
return 'VEVENT';
}
/**
* {@inheritdoc}
*/
public function buildPropertyBag()
{
$propertyBag = new PropertyBag();
// mandatory information
$propertyBag->set('UID', $this->uniqueId);
$propertyBag->add(new DateTimeProperty('DTSTART', $this->dtStart, $this->noTime, $this->useTimezone, $this->useUtc));
$propertyBag->set('SEQUENCE', $this->sequence);
$propertyBag->set('TRANSP', $this->transparency);
if ($this->status) {
$propertyBag->set('STATUS', $this->status);
}
// An event can have a 'dtend' or 'duration', but not both.
if (null != $this->dtEnd) {
$propertyBag->add(new DateTimeProperty('DTEND', $this->dtEnd, $this->noTime, $this->useTimezone, $this->useUtc));
} elseif (null != $this->duration) {
$propertyBag->set('DURATION', $this->duration->format('P%dDT%hH%iM%sS'));
}
// optional information
if (null != $this->url) {
$propertyBag->set('URL', $this->url);
}
if (null != $this->location) {
$propertyBag->set('LOCATION', $this->location);
if (null != $this->locationGeo) {
$propertyBag->add(
new Property(
'X-APPLE-STRUCTURED-LOCATION',
'geo:' . $this->locationGeo,
array(
'VALUE' => 'URI',
'X-ADDRESS' => $this->location,
'X-APPLE-RADIUS' => 49,
'X-TITLE' => $this->locationTitle,
)
)
);
$propertyBag->set('GEO', str_replace(',', ';', $this->locationGeo));
}
}
if (null != $this->summary) {
$propertyBag->set('SUMMARY', $this->summary);
}
if (null != $this->attendees) {
$propertyBag->add($this->attendees);
}
$propertyBag->set('CLASS', $this->isPrivate ? 'PRIVATE' : 'PUBLIC');
if (null != $this->description) {
$propertyBag->set('DESCRIPTION', new Description($this->description));
}
if (null != $this->descriptionHTML) {
$propertyBag->add(
new Property(
'X-ALT-DESC',
$this->descriptionHTML,
array(
'FMTTYPE' => 'text/html',
)
)
);
}
if (null != $this->recurrenceRule) {
$propertyBag->set('RRULE', $this->recurrenceRule);
}
if (null != $this->recurrenceId) {
$this->recurrenceId->applyTimeSettings($this->noTime, $this->useTimezone, $this->useUtc);
$propertyBag->add($this->recurrenceId);
}
if (!empty($this->exDates)) {
$propertyBag->add(new DateTimesProperty('EXDATE', $this->exDates, $this->noTime, $this->useTimezone, $this->useUtc));
}
if ($this->cancelled) {
$propertyBag->set('STATUS', 'CANCELLED');
}
if (null != $this->organizer) {
$propertyBag->add($this->organizer);
}
if ($this->noTime) {
$propertyBag->set('X-MICROSOFT-CDO-ALLDAYEVENT', 'TRUE');
}
if (null != $this->categories) {
$propertyBag->set('CATEGORIES', $this->categories);
}
$propertyBag->add(
new DateTimeProperty('DTSTAMP', $this->dtStamp ?: new \DateTime(), false, false, true)
);
if ($this->created) {
$propertyBag->add(new DateTimeProperty('CREATED', $this->created, false, false, true));
}
if ($this->modified) {
$propertyBag->add(new DateTimeProperty('LAST-MODIFIED', $this->modified, false, false, true));
}
return $propertyBag;
}
/**
* @param $dtEnd
*
* @return $this
*/
public function setDtEnd($dtEnd)
{
$this->dtEnd = $dtEnd;
return $this;
}
public function getDtEnd()
{
return $this->dtEnd;
}
public function setDtStart($dtStart)
{
$this->dtStart = $dtStart;
return $this;
}
/**
* @param $dtStamp
*
* @return $this
*/
public function setDtStamp($dtStamp)
{
$this->dtStamp = $dtStamp;
return $this;
}
/**
* @param $duration
*
* @return $this
*/
public function setDuration($duration)
{
$this->duration = $duration;
return $this;
}
/**
* @param $location
* @param string $title
* @param null $geo
*
* @return $this
*/
public function setLocation($location, $title = '', $geo = null)
{
$this->location = $location;
$this->locationTitle = $title;
$this->locationGeo = $geo;
return $this;
}
/**
* @param $noTime
*
* @return $this
*/
public function setNoTime($noTime)
{
$this->noTime = $noTime;
return $this;
}
/**
* @param int $sequence
*
* @return $this
*/
public function setSequence($sequence)
{
$this->sequence = $sequence;
return $this;
}
/**
* @return int
*/
public function getSequence()
{
return $this->sequence;
}
/**
* @param Organizer $organizer
*
* @return $this
*/
public function setOrganizer(Organizer $organizer)
{
$this->organizer = $organizer;
return $this;
}
/**
* @param $summary
*
* @return $this
*/
public function setSummary($summary)
{
$this->summary = $summary;
return $this;
}
/**
* @param $uniqueId
*
* @return $this
*/
public function setUniqueId($uniqueId)
{
$this->uniqueId = $uniqueId;
return $this;
}
/**
* @return string
*/
public function getUniqueId()
{
return $this->uniqueId;
}
/**
* @param $url
*
* @return $this
*/
public function setUrl($url)
{
$this->url = $url;
return $this;
}
/**
* @param $useTimezone
*
* @return $this
*/
public function setUseTimezone($useTimezone)
{
$this->useTimezone = $useTimezone;
return $this;
}
/**
* @return bool
*/
public function getUseTimezone()
{
return $this->useTimezone;
}
/**
* @param Attendees $attendees
*
* @return $this
*/
public function setAttendees(Attendees $attendees)
{
$this->attendees = $attendees;
return $this;
}
/**
* @param string $attendee
* @param array $params
*
* @return $this
*/
public function addAttendee($attendee, $params = array())
{
if (!isset($this->attendees)) {
$this->attendees = new Attendees();
}
$this->attendees->add($attendee, $params);
return $this;
}
/**
* @return Attendees
*/
public function getAttendees()
{
return $this->attendees;
}
/**
* @param $description
*
* @return $this
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* @param $descriptionHTML
*
* @return $this
*/
public function setDescriptionHTML($descriptionHTML)
{
$this->descriptionHTML = $descriptionHTML;
return $this;
}
/**
* @param bool $useUtc
*
* @return $this
*/
public function setUseUtc($useUtc = true)
{
$this->useUtc = $useUtc;
return $this;
}
/**
* @return string
*/
public function getDescription()
{
return $this->description;
}
/**
* @return string
*/
public function getDescriptionHTML()
{
return $this->descriptionHTML;
}
/**
* @param $status
*
* @return $this
*/
public function setCancelled($status)
{
$this->cancelled = (bool) $status;
return $this;
}
/**
* @param $transparency
*
* @return $this
*
* @throws \InvalidArgumentException
*/
public function setTimeTransparency($transparency)
{
$transparency = strtoupper($transparency);
if ($transparency === self::TIME_TRANSPARENCY_OPAQUE
|| $transparency === self::TIME_TRANSPARENCY_TRANSPARENT
) {
$this->transparency = $transparency;
} else {
throw new \InvalidArgumentException('Invalid value for transparancy');
}
return $this;
}
/**
* @param $status
*
* @return $this
*
* @throws \InvalidArgumentException
*/
public function setStatus($status)
{
$status = strtoupper($status);
if ($status == self::STATUS_CANCELLED
|| $status == self::STATUS_CONFIRMED
|| $status == self::STATUS_TENTATIVE
) {
$this->status = $status;
} else {
throw new \InvalidArgumentException('Invalid value for status');
}
return $this;
}
/**
* @param RecurrenceRule $recurrenceRule
*
* @return $this
*/
public function setRecurrenceRule(RecurrenceRule $recurrenceRule)
{
$this->recurrenceRule = $recurrenceRule;
return $this;
}
/**
* @return RecurrenceRule
*/
public function getRecurrenceRule()
{
return $this->recurrenceRule;
}
/**
* @param $dtStamp
*
* @return $this
*/
public function setCreated($dtStamp)
{
$this->created = $dtStamp;
return $this;
}
/**
* @param $dtStamp
*
* @return $this
*/
public function setModified($dtStamp)
{
$this->modified = $dtStamp;
return $this;
}
/**
* @param $categories
*
* @return $this
*/
public function setCategories($categories)
{
$this->categories = $categories;
return $this;
}
/**
* Sets the event privacy.
*
* @param bool $flag
*
* @return $this
*/
public function setIsPrivate($flag)
{
$this->isPrivate = (bool) $flag;
return $this;
}
/**
* @param \DateTime $dateTime
*
* @return \Eluceo\iCal\Component\Event
*/
public function addExDate(\DateTime $dateTime)
{
$this->exDates[] = $dateTime;
return $this;
}
/**
* @return \DateTime[]
*/
public function getExDates()
{
return $this->exDates;
}
/**
* @param \DateTime[]
*
* @return \Eluceo\iCal\Component\Event
*/
public function setExDates(array $exDates)
{
$this->exDates = $exDates;
return $this;
}
/**
* @return \Eluceo\iCal\Property\Event\RecurrenceId
*/
public function getRecurrenceId()
{
return $this->recurrenceId;
}
/**
* @param RecurrenceId $recurrenceId
*
* @return \Eluceo\iCal\Component\Event
*/
public function setRecurrenceId(RecurrenceId $recurrenceId)
{
$this->recurrenceId = $recurrenceId;
return $this;
}
}

View file

@ -1,57 +0,0 @@
<?php
/*
* This file is part of the eluceo/iCal package.
*
* (c) Markus Poerschke <markus@eluceo.de>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Eluceo\iCal\Component;
use Eluceo\iCal\Component;
use Eluceo\iCal\PropertyBag;
/**
* Implementation of the TIMEZONE component.
*/
class Timezone extends Component
{
/**
* @var string
*/
protected $timezone;
public function __construct($timezone)
{
$this->timezone = $timezone;
}
/**
* {@inheritdoc}
*/
public function getType()
{
return 'VTIMEZONE';
}
/**
* {@inheritdoc}
*/
public function buildPropertyBag()
{
$propertyBag = new PropertyBag();
$propertyBag->set('TZID', $this->timezone);
$propertyBag->set('X-LIC-LOCATION', $this->timezone);
return $propertyBag;
}
public function getZoneIdentifier()
{
return $this->timezone;
}
}

View file

@ -1,215 +0,0 @@
<?php
/*
* This file is part of the eluceo/iCal package.
*
* (c) Markus Poerschke <markus@eluceo.de>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Eluceo\iCal\Component;
use Eluceo\iCal\Component;
use Eluceo\iCal\PropertyBag;
use Eluceo\iCal\Property\Event\RecurrenceRule;
/**
* Implementation of Standard Time and Daylight Saving Time observances (or rules)
* which define the TIMEZONE component.
*/
class TimezoneRule extends Component
{
const TYPE_DAYLIGHT = 'DAYLIGHT';
const TYPE_STANDARD = 'STANDARD';
/**
* @var string
*/
protected $type;
/**
* @var string
*/
protected $tzOffsetFrom;
/**
* @var string
*/
protected $tzOffsetTo;
/**
* @var string
*/
protected $tzName;
/**
* @var \DateTime
*/
protected $dtStart;
/**
* @var RecurrenceRule
*/
protected $recurrenceRule;
/**
* create new Timezone Rule object by giving a rule type identifier.
*
* @param string $ruleType one of DAYLIGHT or STANDARD
*
* @throws \InvalidArgumentException
*/
public function __construct($ruleType)
{
$ruleType = strtoupper($ruleType);
if ($ruleType === self::TYPE_DAYLIGHT || $ruleType === self::TYPE_STANDARD) {
$this->type = $ruleType;
} else {
throw new \InvalidArgumentException('Invalid value for timezone rule type');
}
}
/**
* {@inheritdoc}
*/
public function buildPropertyBag()
{
$propertyBag = new PropertyBag();
if ($this->getTzName()) {
$propertyBag->set('TZNAME', $this->getTzName());
}
if ($this->getTzOffsetFrom()) {
$propertyBag->set('TZOFFSETFROM', $this->getTzOffsetFrom());
}
if ($this->getTzOffsetTo()) {
$propertyBag->set('TZOFFSETTO', $this->getTzOffsetTo());
}
if ($this->getDtStart()) {
$propertyBag->set('DTSTART', $this->getDtStart());
}
if ($this->recurrenceRule) {
$propertyBag->set('RRULE', $this->recurrenceRule);
}
return $propertyBag;
}
/**
* @param $offset
*
* @return $this
*/
public function setTzOffsetFrom($offset)
{
$this->tzOffsetFrom = $offset;
return $this;
}
/**
* @param $offset
*
* @return $this
*/
public function setTzOffsetTo($offset)
{
$this->tzOffsetTo = $offset;
return $this;
}
/**
* @param $name
*
* @return $this
*/
public function setTzName($name)
{
$this->tzName = $name;
return $this;
}
/**
* @param \DateTime $dtStart
*
* @return $this
*/
public function setDtStart(\DateTime $dtStart)
{
$this->dtStart = $dtStart;
return $this;
}
/**
* @param RecurrenceRule $recurrenceRule
*
* @return $this
*/
public function setRecurrenceRule(RecurrenceRule $recurrenceRule)
{
$this->recurrenceRule = $recurrenceRule;
return $this;
}
/**
* {@inheritdoc}
*/
public function getType()
{
return $this->type;
}
/**
* @return string
*/
public function getTzOffsetFrom()
{
return $this->tzOffsetFrom;
}
/**
* @return string
*/
public function getTzOffsetTo()
{
return $this->tzOffsetTo;
}
/**
* @return string
*/
public function getTzName()
{
return $this->tzName;
}
/**
* @return RecurrenceRule
*/
public function getRecurrenceRule()
{
return $this->recurrenceRule;
}
/**
* @return mixed return string representation of start date or NULL if no date was given
*/
public function getDtStart()
{
if ($this->dtStart) {
return $this->dtStart->format('Ymd\THis');
}
return;
}
}

View file

@ -1,108 +0,0 @@
<?php
/*
* This file is part of the eluceo/iCal package.
*
* (c) Markus Poerschke <markus@eluceo.de>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Eluceo\iCal;
class ParameterBag
{
/**
* The params.
*
* @var array
*/
protected $params;
public function __construct($params = array())
{
$this->params = $params;
}
/**
* @param string $name
* @param mixed $value
*/
public function setParam($name, $value)
{
$this->params[$name] = $value;
}
/**
* @param $name
*/
public function getParam($name)
{
if (array_key_exists($name, $this->params)) {
return $this->params[$name];
}
}
/**
* Checks if there are any params.
*
* @return bool
*/
public function hasParams()
{
return count($this->params) > 0;
}
/**
* @return string
*/
public function toString()
{
$line = '';
foreach ($this->params as $param => $paramValues) {
if (!is_array($paramValues)) {
$paramValues = array($paramValues);
}
foreach ($paramValues as $k => $v) {
$paramValues[$k] = $this->escapeParamValue($v);
}
if ('' != $line) {
$line .= ';';
}
$line .= $param . '=' . implode(',', $paramValues);
}
return $line;
}
/**
* Returns an escaped string for a param value.
*
* @param string $value
*
* @return string
*/
public function escapeParamValue($value)
{
$count = 0;
$value = str_replace('\\', '\\\\', $value);
$value = str_replace('"', '\"', $value, $count);
$value = str_replace("\n", '\\n', $value);
if (false !== strpos($value, ';') || false !== strpos($value, ',') || false !== strpos($value, ':') || $count) {
$value = '"' . $value . '"';
}
return $value;
}
/**
* @return string
*/
public function __toString()
{
return $this->toString();
}
}

View file

@ -1,148 +0,0 @@
<?php
/*
* This file is part of the eluceo/iCal package.
*
* (c) Markus Poerschke <markus@eluceo.de>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Eluceo\iCal;
use Eluceo\iCal\Property\ArrayValue;
use Eluceo\iCal\Property\StringValue;
use Eluceo\iCal\Property\ValueInterface;
/**
* The Property Class represents a property as defined in RFC 2445.
*
* The content of a line (unfolded) will be rendered in this class
*/
class Property
{
/**
* The value of the Property.
*
* @var ValueInterface
*/
protected $value;
/**
* The params of the Property.
*
* @var ParameterBag
*/
protected $parameterBag;
/**
* @var string
*/
protected $name;
/**
* @param $name
* @param $value
* @param array $params
*/
public function __construct($name, $value, $params = array())
{
$this->name = $name;
$this->setValue($value);
$this->parameterBag = new ParameterBag($params);
}
/**
* Renders an unfolded line.
*
* @return string
*/
public function toLine()
{
// Property-name
$line = $this->getName();
// Adding params
//@todo added check for $this->parameterBag because doctrine/orm proxies won't execute constructor - ok?
if ($this->parameterBag && $this->parameterBag->hasParams()) {
$line .= ';' . $this->parameterBag->toString();
}
// Property value
$line .= ':' . $this->value->getEscapedValue();
return $line;
}
/**
* Get all unfolded lines.
*
* @return array
*/
public function toLines()
{
return array($this->toLine());
}
/**
* @param string $name
* @param mixed $value
*
* @return $this
*/
public function setParam($name, $value)
{
$this->parameterBag->setParam($name, $value);
return $this;
}
/**
* @param $name
*/
public function getParam($name)
{
return $this->parameterBag->getParam($name);
}
/**
* @param mixed $value
*
* @return $this
*
* @throws \Exception
*/
public function setValue($value)
{
if (is_scalar($value)) {
$this->value = new StringValue($value);
} elseif (is_array($value)) {
$this->value = new ArrayValue($value);
} else {
if (!$value instanceof ValueInterface) {
throw new \Exception('The value must implement the ValueInterface.');
} else {
$this->value = $value;
}
}
return $this;
}
/**
* @return mixed
*/
public function getValue()
{
return $this->value;
}
/**
* @return string
*/
public function getName()
{
return $this->name;
}
}

View file

@ -1,43 +0,0 @@
<?php
/*
* This file is part of the eluceo/iCal package.
*
* (c) Markus Poerschke <markus@eluceo.de>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Eluceo\iCal\Property;
use Eluceo\iCal\Util\PropertyValueUtil;
class ArrayValue implements ValueInterface
{
/**
* The value.
*
* @var array
*/
protected $values;
public function __construct(array $values)
{
$this->values = $values;
}
public function setValues(array $values)
{
$this->values = $values;
return $this;
}
public function getEscapedValue()
{
return implode(',', array_map(function ($value) {
return PropertyValueUtil::escapeValue((string) $value);
}, $this->values));
}
}

View file

@ -1,38 +0,0 @@
<?php
/*
* This file is part of the eluceo/iCal package.
*
* (c) Markus Poerschke <markus@eluceo.de>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Eluceo\iCal\Property;
use Eluceo\iCal\Property;
use Eluceo\iCal\Util\DateUtil;
class DateTimeProperty extends Property
{
/**
* @param string $name
* @param \DateTime $dateTime
* @param bool $noTime
* @param bool $useTimezone
* @param bool $useUtc
*/
public function __construct(
$name,
\DateTime $dateTime = null,
$noTime = false,
$useTimezone = false,
$useUtc = false
) {
$dateString = DateUtil::getDateString($dateTime, $noTime, $useTimezone, $useUtc);
$params = DateUtil::getDefaultParams($dateTime, $noTime, $useTimezone);
parent::__construct($name, $dateString, $params);
}
}

View file

@ -1,41 +0,0 @@
<?php
/*
* This file is part of the eluceo/iCal package.
*
* (c) Markus Poerschke <markus@eluceo.de>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Eluceo\iCal\Property;
use Eluceo\iCal\Property;
use Eluceo\iCal\Util\DateUtil;
class DateTimesProperty extends Property
{
/**
* @param string $name
* @param \DateTime[] $dateTimes
* @param bool $noTime
* @param bool $useTimezone
* @param bool $useUtc
*/
public function __construct(
$name,
$dateTimes = array(),
$noTime = false,
$useTimezone = false,
$useUtc = false
) {
$dates = array();
foreach ($dateTimes as $dateTime) {
$dates[] = DateUtil::getDateString($dateTime, $noTime, $useTimezone, $useUtc);
}
$params = DateUtil::getDefaultParams($dateTime, $noTime, $useTimezone);
parent::__construct($name, $dates, $params);
}
}

View file

@ -1,102 +0,0 @@
<?php
/*
* This file is part of the eluceo/iCal package.
*
* (c) Markus Poerschke <markus@eluceo.de>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Eluceo\iCal\Property\Event;
use Eluceo\iCal\Property;
class Attendees extends Property
{
/** @var Property[] */
protected $attendees = array();
const PROPERTY_NAME = 'ATTENDEES';
public function __construct()
{
// Overwrites constructor functionality of Property
}
/**
* @param $value
* @param array $params
*
* @return $this
*/
public function add($value, $params = array())
{
$this->attendees[] = new Property('ATTENDEE', $value, $params);
return $this;
}
/**
* @param Property[] $value
*
* @return $this
*/
public function setValue($value)
{
$this->attendees = $value;
return $this;
}
/**
* @return Property[]
*/
public function getValue()
{
return $this->attendees;
}
/**
* {@inheritdoc}
*/
public function toLines()
{
$lines = array();
foreach ($this->attendees as $attendee) {
$lines[] = $attendee->toLine();
}
return $lines;
}
/**
* @param string $name
* @param mixed $value
*
* @throws \BadMethodCallException
*/
public function setParam($name, $value)
{
throw new \BadMethodCallException('Cannot call setParam on Attendees Property');
}
/**
* @param $name
*
* @throws \BadMethodCallException
*/
public function getParam($name)
{
throw new \BadMethodCallException('Cannot call getParam on Attendees Property');
}
/**
* {@inheritdoc}
*/
public function getName()
{
return self::PROPERTY_NAME;
}
}

View file

@ -1,66 +0,0 @@
<?php
/*
* This file is part of the eluceo/iCal package.
*
* (c) Markus Poerschke <markus@eluceo.de>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Eluceo\iCal\Property\Event;
use Eluceo\iCal\Property\ValueInterface;
use Eluceo\iCal\Util\PropertyValueUtil;
/**
* Class Description
* Alows new line charectars to be in the description.
*/
class Description implements ValueInterface
{
/**
* The value.
*
* @var string
*/
protected $value;
public function __construct($value)
{
$this->value = $value;
}
/**
* Return the value of the Property as an escaped string.
*
* Escape values as per RFC 2445. See http://www.kanzaki.com/docs/ical/text.html
*
* @return string
*/
public function getEscapedValue()
{
return PropertyValueUtil::escapeValue((string) $this->value);
}
/**
* @param string $value
*
* @return $this
*/
public function setValue($value)
{
$this->value = $value;
return $this;
}
/**
* @return string
*/
public function getValue()
{
return $this->value;
}
}

View file

@ -1,39 +0,0 @@
<?php
/*
* This file is part of the eluceo/iCal package.
*
* (c) Markus Poerschke <markus@eluceo.de>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Eluceo\iCal\Property\Event;
use Eluceo\iCal\Property;
/**
* Class Organizer.
*/
class Organizer extends Property
{
const PROPERTY_NAME = 'ORGANIZER';
/**
* @param string $value
* @param array $params
*/
public function __construct($value, $params = array())
{
parent::__construct(self::PROPERTY_NAME, $value, $params);
}
/**
* {@inheritdoc}
*/
public function getName()
{
return self::PROPERTY_NAME;
}
}

View file

@ -1,130 +0,0 @@
<?php
/*
* This file is part of the eluceo/iCal package.
*
* (c) Markus Poerschke <markus@eluceo.de>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Eluceo\iCal\Property\Event;
use Eluceo\iCal\ParameterBag;
use Eluceo\iCal\Property;
use Eluceo\iCal\Util\DateUtil;
use Eluceo\iCal\Property\ValueInterface;
/**
* Implementation of Recurrence Id.
*
* @see http://www.ietf.org/rfc/rfc2445.txt 4.8.4.4 Recurrence ID
*/
class RecurrenceId extends Property
{
const PROPERTY_NAME = 'RECURRENCE-ID';
/**
* The effective range of recurrence instances from the instance
* specified by the recurrence identifier specified by the property.
*/
const RANGE_THISANDPRIOR = 'THISANDPRIOR';
const RANGE_THISANDFUTURE = 'THISANDFUTURE';
/**
* The dateTime to identify a particular instance of a recurring event which is getting modified.
*
* @var \DateTime
*/
protected $dateTime;
/**
* Specify the effective range of recurrence instances from the instance.
*
* @var string
*/
protected $range;
public function __construct(\DateTime $dateTime = null)
{
$this->parameterBag = new ParameterBag();
if (isset($dateTime)) {
$this->dateTime = $dateTime;
}
}
public function applyTimeSettings($noTime = false, $useTimezone = false, $useUtc = false)
{
$params = DateUtil::getDefaultParams($this->dateTime, $noTime, $useTimezone, $useUtc);
foreach ($params as $name => $value) {
$this->parameterBag->setParam($name, $value);
}
if ($this->range) {
$this->parameterBag->setParam('RANGE', $this->range);
}
$this->setValue(DateUtil::getDateString($this->dateTime, $noTime, $useTimezone, $useUtc));
}
/**
* @return DateTime
*/
public function getDatetime()
{
return $this->dateTime;
}
/**
* @param \DateTime $dateTime
*
* @return \Eluceo\iCal\Property\Event\RecurrenceId
*/
public function setDatetime(\DateTime $dateTime)
{
$this->dateTime = $dateTime;
return $this;
}
/**
* @return string
*/
public function getRange()
{
return $this->range;
}
/**
* @param string $range
*
* @return \Eluceo\iCal\Property\Event\RecurrenceId
*/
public function setRange($range)
{
$this->range = $range;
}
/**
* Get all unfolded lines.
*
* @return array
*/
public function toLines()
{
if (!$this->value instanceof ValueInterface) {
throw new \Exception('The value must implement the ValueInterface. Call RecurrenceId::applyTimeSettings() before adding RecurrenceId.');
} else {
return parent::toLines();
}
}
/**
* {@inheritdoc}
*/
public function getName()
{
return self::PROPERTY_NAME;
}
}

View file

@ -1,444 +0,0 @@
<?php
/*
* This file is part of the eluceo/iCal package.
*
* (c) Markus Poerschke <markus@eluceo.de>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Eluceo\iCal\Property\Event;
use Eluceo\iCal\Property\ValueInterface;
use Eluceo\iCal\ParameterBag;
use InvalidArgumentException;
/**
* Implementation of Recurrence Rule.
*
* @see http://www.ietf.org/rfc/rfc2445.txt 3.3.10. Recurrence Rule
*/
class RecurrenceRule implements ValueInterface
{
const FREQ_YEARLY = 'YEARLY';
const FREQ_MONTHLY = 'MONTHLY';
const FREQ_WEEKLY = 'WEEKLY';
const FREQ_DAILY = 'DAILY';
const WEEKDAY_SUNDAY = 'SU';
const WEEKDAY_MONDAY = 'MO';
const WEEKDAY_TUESDAY = 'TU';
const WEEKDAY_WEDNESDAY = 'WE';
const WEEKDAY_THURSDAY = 'TH';
const WEEKDAY_FRIDAY = 'FR';
const WEEKDAY_SATURDAY = 'SA';
/**
* The frequency of an Event.
*
* @var string
*/
protected $freq = self::FREQ_YEARLY;
/**
* @var null|int
*/
protected $interval = 1;
/**
* @var null|int
*/
protected $count = null;
/**
* @var null|\DateTime
*/
protected $until = null;
/**
* @var null|string
*/
protected $wkst;
/**
* @var null|string
*/
protected $byMonth;
/**
* @var null|string
*/
protected $byWeekNo;
/**
* @var null|string
*/
protected $byYearDay;
/**
* @var null|string
*/
protected $byMonthDay;
/**
* @var null|string
*/
protected $byDay;
/**
* @var null|string
*/
protected $byHour;
/**
* @var null|string
*/
protected $byMinute;
/**
* @var null|string
*/
protected $bySecond;
/**
* Return the value of the Property as an escaped string.
*
* Escape values as per RFC 2445. See http://www.kanzaki.com/docs/ical/text.html
*
* @return string
*/
public function getEscapedValue()
{
return $this->buildParameterBag()->toString();
}
/**
* @return ParameterBag
*/
protected function buildParameterBag()
{
$parameterBag = new ParameterBag();
$parameterBag->setParam('FREQ', $this->freq);
if (null !== $this->interval) {
$parameterBag->setParam('INTERVAL', $this->interval);
}
if (null !== $this->count) {
$parameterBag->setParam('COUNT', $this->count);
}
if (null != $this->until) {
$parameterBag->setParam('UNTIL', $this->until->format('Ymd\THis\Z'));
}
if (null !== $this->wkst) {
$parameterBag->setParam('WKST', $this->wkst);
}
if (null !== $this->byMonth) {
$parameterBag->setParam('BYMONTH', $this->byMonth);
}
if (null !== $this->byWeekNo) {
$parameterBag->setParam('BYWEEKNO', $this->byWeekNo);
}
if (null !== $this->byYearDay) {
$parameterBag->setParam('BYYEARDAY', $this->byYearDay);
}
if (null !== $this->byMonthDay) {
$parameterBag->setParam('BYMONTHDAY', $this->byMonthDay);
}
if (null !== $this->byDay) {
$parameterBag->setParam('BYDAY', $this->byDay);
}
if (null !== $this->byHour) {
$parameterBag->setParam('BYHOUR', $this->byHour);
}
if (null !== $this->byMinute) {
$parameterBag->setParam('BYMINUTE', $this->byMinute);
}
if (null !== $this->bySecond) {
$parameterBag->setParam('BYSECOND', $this->bySecond);
}
return $parameterBag;
}
/**
* @param int|null $count
*
* @return $this
*/
public function setCount($count)
{
$this->count = $count;
return $this;
}
/**
* @return int|null
*/
public function getCount()
{
return $this->count;
}
/**
* @param \DateTime|null $until
*
* @return $this
*/
public function setUntil(\DateTime $until = null)
{
$this->until = $until;
return $this;
}
/**
* @return \DateTime|null
*/
public function getUntil()
{
return $this->until;
}
/**
* The FREQ rule part identifies the type of recurrence rule. This
* rule part MUST be specified in the recurrence rule. Valid values
* include.
*
* SECONDLY, to specify repeating events based on an interval of a second or more;
* MINUTELY, to specify repeating events based on an interval of a minute or more;
* HOURLY, to specify repeating events based on an interval of an hour or more;
* DAILY, to specify repeating events based on an interval of a day or more;
* WEEKLY, to specify repeating events based on an interval of a week or more;
* MONTHLY, to specify repeating events based on an interval of a month or more;
* YEARLY, to specify repeating events based on an interval of a year or more.
*
* @param string $freq
*
* @return $this
*
* @throws \InvalidArgumentException
*/
public function setFreq($freq)
{
if (self::FREQ_YEARLY === $freq || self::FREQ_MONTHLY === $freq
|| self::FREQ_WEEKLY === $freq
|| self::FREQ_DAILY === $freq
) {
$this->freq = $freq;
} else {
throw new \InvalidArgumentException("The Frequency {$freq} is not supported.");
}
return $this;
}
/**
* @return string
*/
public function getFreq()
{
return $this->freq;
}
/**
* The INTERVAL rule part contains a positive integer representing at
* which intervals the recurrence rule repeats.
*
* @param int|null $interval
*
* @return $this
*/
public function setInterval($interval)
{
$this->interval = $interval;
return $this;
}
/**
* @return int|null
*/
public function getInterval()
{
return $this->interval;
}
/**
* The WKST rule part specifies the day on which the workweek starts.
* Valid values are MO, TU, WE, TH, FR, SA, and SU.
*
* @param string $value
*
* @return $this
*/
public function setWkst($value)
{
$this->wkst = $value;
return $this;
}
/**
* The BYMONTH rule part specifies a COMMA-separated list of months of the year.
* Valid values are 1 to 12.
*
* @param int $month
*
* @throws InvalidArgumentException
*
* @return $this
*/
public function setByMonth($month)
{
if (!is_integer($month) || $month < 0 || $month > 12) {
throw new InvalidArgumentException('Invalid value for BYMONTH');
}
$this->byMonth = $month;
return $this;
}
/**
* The BYWEEKNO rule part specifies a COMMA-separated list of ordinals specifying weeks of the year.
* Valid values are 1 to 53 or -53 to -1.
*
* @param int $value
*
* @return $this
*/
public function setByWeekNo($value)
{
$this->byWeekNo = $value;
return $this;
}
/**
* The BYYEARDAY rule part specifies a COMMA-separated list of days of the year.
* Valid values are 1 to 366 or -366 to -1.
*
* @param int $day
*
* @return $this
*/
public function setByYearDay($day)
{
$this->byYearDay = $day;
return $this;
}
/**
* The BYMONTHDAY rule part specifies a COMMA-separated list of days of the month.
* Valid values are 1 to 31 or -31 to -1.
*
* @param int $day
*
* @return $this
*/
public function setByMonthDay($day)
{
$this->byMonthDay = $day;
return $this;
}
/**
* The BYDAY rule part specifies a COMMA-separated list of days of the week;.
*
* SU indicates Sunday; MO indicates Monday; TU indicates Tuesday;
* WE indicates Wednesday; TH indicates Thursday; FR indicates Friday; and SA indicates Saturday.
*
* Each BYDAY value can also be preceded by a positive (+n) or negative (-n) integer.
* If present, this indicates the nth occurrence of a specific day within the MONTHLY or YEARLY "RRULE".
*
* @param string $day
*
* @return $this
*/
public function setByDay($day)
{
$this->byDay = $day;
return $this;
}
/**
* The BYHOUR rule part specifies a COMMA-separated list of hours of the day.
* Valid values are 0 to 23.
*
* @param int $value
*
* @return $this
*
* @throws \InvalidArgumentException
*/
public function setByHour($value)
{
if (!is_integer($value) || $value < 0 || $value > 23) {
throw new \InvalidArgumentException('Invalid value for BYHOUR');
}
$this->byHour = $value;
return $this;
}
/**
* The BYMINUTE rule part specifies a COMMA-separated list of minutes within an hour.
* Valid values are 0 to 59.
*
* @param int $value
*
* @return $this
*
* @throws \InvalidArgumentException
*/
public function setByMinute($value)
{
if (!is_integer($value) || $value < 0 || $value > 59) {
throw new \InvalidArgumentException('Invalid value for BYMINUTE');
}
$this->byMinute = $value;
return $this;
}
/**
* The BYSECOND rule part specifies a COMMA-separated list of seconds within a minute.
* Valid values are 0 to 60.
*
* @param int $value
*
* @return $this
*
* @throws \InvalidArgumentException
*/
public function setBySecond($value)
{
if (!is_integer($value) || $value < 0 || $value > 60) {
throw new \InvalidArgumentException('Invalid value for BYSECOND');
}
$this->bySecond = $value;
return $this;
}
}

View file

@ -1,61 +0,0 @@
<?php
/*
* This file is part of the eluceo/iCal package.
*
* (c) Markus Poerschke <markus@eluceo.de>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Eluceo\iCal\Property;
use Eluceo\iCal\Util\PropertyValueUtil;
class StringValue implements ValueInterface
{
/**
* The value.
*
* @var string
*/
protected $value;
public function __construct($value)
{
$this->value = $value;
}
/**
* Return the value of the Property as an escaped string.
*
* Escape values as per RFC 2445. See http://www.kanzaki.com/docs/ical/text.html
*
* @return string
*/
public function getEscapedValue()
{
return PropertyValueUtil::escapeValue((string) $this->value);
}
/**
* @param string $value
*
* @return $this
*/
public function setValue($value)
{
$this->value = $value;
return $this;
}
/**
* @return string
*/
public function getValue()
{
return $this->value;
}
}

View file

@ -1,24 +0,0 @@
<?php
/*
* This file is part of the eluceo/iCal package.
*
* (c) Markus Poerschke <markus@eluceo.de>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Eluceo\iCal\Property;
interface ValueInterface
{
/**
* Return the value of the Property as an escaped string.
*
* Escape values as per RFC 2445. See http://www.kanzaki.com/docs/ical/text.html
*
* @return string
*/
public function getEscapedValue();
}

View file

@ -1,79 +0,0 @@
<?php
/*
* This file is part of the eluceo/iCal package.
*
* (c) Markus Poerschke <markus@eluceo.de>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Eluceo\iCal;
class PropertyBag implements \IteratorAggregate
{
/**
* @var array
*/
protected $elements = array();
/**
* Creates a new Property with $name, $value and $params.
*
* @param $name
* @param $value
* @param array $params
*
* @return $this
*/
public function set($name, $value, $params = array())
{
$property = new Property($name, $value, $params);
$this->elements[] = $property;
return $this;
}
/**
* @param string $name
*
* @return null|Property
*/
public function get($name)
{
// Searching Property in elements-array
/** @var $property Property */
foreach ($this->elements as $property) {
if ($property->getName() == $name) {
return $property;
}
}
}
/**
* Adds a Property. If Property already exists an Exception will be thrown.
*
* @param Property $property
*
* @return $this
*
* @throws \Exception
*/
public function add(Property $property)
{
// Property already exists?
if (null !== $this->get($property->getName())) {
throw new \Exception("Property with name '{$property->getName()}' already exists");
}
$this->elements[] = $property;
return $this;
}
public function getIterator()
{
return new \ArrayObject($this->elements);
}
}

View file

@ -1,48 +0,0 @@
<?php
/*
* This file is part of the eluceo/iCal package.
*
* (c) Markus Poerschke <markus@eluceo.de>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Eluceo\iCal\Util;
class ComponentUtil
{
/**
* Folds a single line.
*
* According to RFC 2445, all lines longer than 75 characters will be folded
*
* @link http://www.ietf.org/rfc/rfc2445.txt
*
* @param $string
*
* @return array
*/
public static function fold($string)
{
$lines = array();
$array = preg_split('/(?<!^)(?!$)/u', $string);
$line = '';
$lineNo = 0;
foreach ($array as $char) {
$charLen = strlen($char);
$lineLen = strlen($line);
if ($lineLen + $charLen > 75) {
$line = ' ' . $char;
++$lineNo;
} else {
$line .= $char;
}
$lines[$lineNo] = $line;
}
return $lines;
}
}

View file

@ -1,69 +0,0 @@
<?php
/*
* This file is part of the eluceo/iCal package.
*
* (c) Markus Poerschke <markus@eluceo.de>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Eluceo\iCal\Util;
class DateUtil
{
public static function getDefaultParams(\DateTime $dateTime = null, $noTime = false, $useTimezone = false)
{
$params = array();
if ($useTimezone) {
$timeZone = $dateTime->getTimezone()->getName();
$params['TZID'] = $timeZone;
}
if ($noTime) {
$params['VALUE'] = 'DATE';
}
return $params;
}
/**
* Returns a formatted date string.
*
* @param \DateTime|null $dateTime The DateTime object
* @param bool $noTime Indicates if the time will be added
* @param bool $useTimezone
* @param bool $useUtc
*
* @return mixed
*/
public static function getDateString(\DateTime $dateTime = null, $noTime = false, $useTimezone = false, $useUtc = false)
{
if (empty($dateTime)) {
$dateTime = new \DateTime();
}
return $dateTime->format(self::getDateFormat($noTime, $useTimezone, $useUtc));
}
/**
* Returns the date format that can be passed to DateTime::format().
*
* @param bool $noTime Indicates if the time will be added
* @param bool $useTimezone
* @param bool $useUtc
*
* @return string
*/
public static function getDateFormat($noTime = false, $useTimezone = false, $useUtc = false)
{
// Do not use UTC time (Z) if timezone support is enabled.
if ($useTimezone || !$useUtc) {
return $noTime ? 'Ymd' : 'Ymd\THis';
}
return $noTime ? 'Ymd' : 'Ymd\THis\Z';
}
}

View file

@ -1,40 +0,0 @@
<?php
/*
* This file is part of the eluceo/iCal package.
*
* (c) Markus Poerschke <markus@eluceo.de>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Eluceo\iCal\Util;
class PropertyValueUtil
{
public static function escapeValue($value)
{
$value = self::escapeValueAllowNewLine($value);
$value = str_replace("\n", '\\n', $value);
return $value;
}
public static function escapeValueAllowNewLine($value)
{
$value = str_replace('\\', '\\\\', $value);
$value = str_replace('"', '\\"', $value);
$value = str_replace(',', '\\,', $value);
$value = str_replace(';', '\\;', $value);
$value = str_replace(array(
"\x00", "\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\x07",
"\x08", "\x09", /* \n*/ "\x0B", "\x0C", "\x0D", "\x0E", "\x0F",
"\x10", "\x11", "\x12", "\x13", "\x14", "\x15", "\x16", "\x17",
"\x18", "\x19", "\x1A", "\x1B", "\x1C", "\x1D", "\x1E", "\x1F",
"\x7F",
), '', $value);
return $value;
}
}

View file

@ -1,64 +0,0 @@
<?php
namespace Eluceo\iCal\Component;
class CalendarIntegrationTest extends \PHPUnit_Framework_TestCase
{
/**
* @coversNothing
*/
public function testExample3()
{
$timeZone = new \DateTimeZone('Europe/Berlin');
// 1. Create new calendar
$vCalendar = new \Eluceo\iCal\Component\Calendar('www.example.com');
// 2. Create an event
$vEvent = new \Eluceo\iCal\Component\Event('123456');
$vEvent->setDtStart(new \DateTime('2012-12-31', $timeZone));
$vEvent->setDtEnd(new \DateTime('2012-12-31', $timeZone));
$vEvent->setNoTime(true);
$vEvent->setIsPrivate(true);
$vEvent->setSummary('New Years Eve');
// Set recurrence rule
$recurrenceRule = new \Eluceo\iCal\Property\Event\RecurrenceRule();
$recurrenceRule->setFreq(\Eluceo\iCal\Property\Event\RecurrenceRule::FREQ_YEARLY);
$recurrenceRule->setInterval(1);
$vEvent->setRecurrenceRule($recurrenceRule);
// Adding Timezone (optional)
$vEvent->setUseTimezone(true);
// 3. Add event to calendar
$vCalendar->addComponent($vEvent);
$lines = array(
'/BEGIN:VCALENDAR/',
'/VERSION:2\.0/',
'/PRODID:www\.example\.com/',
'/X-PUBLISHED-TTL:P1W/',
'/BEGIN:VEVENT/',
'/UID:123456/',
'/DTSTART;TZID=Europe\/Berlin;VALUE=DATE:20121231/',
'/SEQUENCE:0/',
'/TRANSP:OPAQUE/',
'/DTEND;TZID=Europe\/Berlin;VALUE=DATE:20121231/',
'/SUMMARY:New Years Eve/',
'/CLASS:PRIVATE/',
'/RRULE:FREQ=YEARLY;INTERVAL=1/',
'/X-MICROSOFT-CDO-ALLDAYEVENT:TRUE/',
'/DTSTAMP:20\d{6}T\d{6}Z/',
'/END:VEVENT/',
'/END:VCALENDAR/',
);
foreach (explode("\n", $vCalendar->render()) as $key => $line)
{
$this->assertTrue(isset($lines[$key]), 'Too many lines... ' . $line);
$this->assertRegExp($lines[$key], $line);
}
}
}

View file

@ -1,45 +0,0 @@
<?php
namespace Eluceo\iCal;
class ComponentTest extends \PHPUnit_Framework_TestCase
{
public function testFoldWithMultibyte()
{
$input = "x" . str_repeat("あいうえお", 5);
$vCalendar = new \Eluceo\iCal\Component\Calendar('www.example.com');
$vEvent = new \Eluceo\iCal\Component\Event();
$vEvent->setDtStart(new \DateTime('2014-12-24'));
$vEvent->setDtEnd(new \DateTime('2014-12-24'));
$vEvent->setDescription($input);
$vAlarm = new \Eluceo\iCal\Component\Alarm;
$vAlarm->setAction(\Eluceo\iCal\Component\Alarm::ACTION_DISPLAY);
$vAlarm->setDescription($input);
$vAlarm->setTrigger('PT0S', true);
$vEvent->addComponent($vAlarm);
$vCalendar->addComponent($vEvent);
$output = $vCalendar->render();
$output = preg_replace('/\r\n /u', '', $output);
$this->assertContains($input, $output);
}
public function testDescriptionWithNewLines()
{
$input = "new string \n new line \n new line \n new string";
$vCalendar = new \Eluceo\iCal\Component\Calendar('www.example.com');
$vEvent = new \Eluceo\iCal\Component\Event();
$vEvent->setDtStart(new \DateTime('2014-12-24'));
$vEvent->setDtEnd(new \DateTime('2014-12-24'));
$vEvent->setDescription($input);
$vCalendar->addComponent($vEvent);
$output = $vCalendar->render();
$this->assertContains(str_replace("\n", "\\n", $input), $output);
}
}

View file

@ -1,35 +0,0 @@
<?php
namespace Eluceo\iCal;
class ParameterBagTest extends \PHPUnit_Framework_TestCase
{
public function testEscapeParamValue()
{
$propertyObject = new ParameterBag;
$this->assertEquals(
'test string',
$propertyObject->escapeParamValue('test string'),
'No escaping necessary'
);
$this->assertEquals(
'"Containing \\"double-quotes\\""',
$propertyObject->escapeParamValue('Containing "double-quotes"'),
'Text contains double quotes'
);
$this->assertEquals(
'"Containing forbidden chars like a ;"',
$propertyObject->escapeParamValue('Containing forbidden chars like a ;'),
'Text with semicolon'
);
$this->assertEquals(
'"Containing forbidden chars like a :"',
$propertyObject->escapeParamValue('Containing forbidden chars like a :'),
'Text with colon'
);
}
}

View file

@ -1,26 +0,0 @@
<?php
namespace Eluceo\iCal\Property;
class ArrayValueTest extends \PHPUnit_Framework_TestCase
{
/**
* @dataProvider arrayValuesProvider
*/
public function testArrayValue($values, $expectedOutput)
{
$arrayValue = new ArrayValue($values);
$this->assertEquals($expectedOutput, $arrayValue->getEscapedValue());
}
public function arrayValuesProvider()
{
return array(
array(array(), ''),
array(array('Lorem'), 'Lorem'),
array(array('Lorem', 'Ipsum'), 'Lorem,Ipsum'),
array(array('Lorem', '"doublequotes"'), 'Lorem,\"doublequotes\"'),
);
}
}

View file

@ -1,17 +0,0 @@
<?php
namespace Eluceo\iCal\Property\Event;
class DescriptionTest extends \PHPUnit_Framework_TestCase
{
public function testAllowsNewLines()
{
$testString = "New String \n New Line";
$description = new Description($testString);
$this->assertEquals(
str_replace("\n", "\\n", $testString),
$description->getEscapedValue()
);
}
}

View file

@ -1,63 +0,0 @@
<?php
/**
* Eluceo\iCal\Property\Event\OrganizerTest
*
* @author Giulio Troccoli <giulio@troccoli.it>
*/
namespace Eluceo\iCal\Property\Event;
/**
* OrganizerTest
*/
class OrganizerTest extends \PHPUnit_Framework_TestCase
{
public function testOrganizerValueOnly()
{
$value = "MAILTO:name.lastname@example.com";
$expected = "ORGANIZER:$value";
$vCalendar = $this->createCalendarWithOrganizer(
new \Eluceo\iCal\Property\Event\Organizer($value)
);
foreach (explode("\n", $vCalendar->render()) as $line)
{
if (preg_match('/^ORGANIZER[:;](.*)$/', $line)) {
$this->assertEquals($expected, trim($line));
}
}
}
public function testOrganizerValueAndParameter()
{
$value = "MAILTO:name.lastname@example.com";
$param = "Name LastName";
$expected = "ORGANIZER;CN=$param:$value";
$vCalendar = $this->createCalendarWithOrganizer(
new \Eluceo\iCal\Property\Event\Organizer($value, array('CN' => $param))
);
foreach (explode("\n", $vCalendar->render()) as $line)
{
if (preg_match('/^ORGANIZER[:;](.*)$/', $line)) {
$this->assertEquals($expected, trim($line));
}
}
}
/**
* @param Organizer $vOrganizer
* @return \Eluceo\iCal\Component\Calendar
*/
private function createCalendarWithOrganizer(\Eluceo\iCal\Property\Event\Organizer $vOrganizer)
{
$vCalendar = new \Eluceo\iCal\Component\Calendar('www.example.com');
$vEvent = new \Eluceo\iCal\Component\Event('123456');
$vEvent->setOrganizer($vOrganizer);
$vCalendar->addComponent($vEvent);
return $vCalendar;
}
}

View file

@ -1,21 +0,0 @@
<?php
namespace Eluceo\iCal\Property\Event;
class RecurrenceRuleTest extends \PHPUnit_Framework_TestCase
{
/**
* Example taken from http://www.kanzaki.com/docs/ical/rrule.html
*/
public function testUntil()
{
$rule = new RecurrenceRule();
$rule->setFreq(RecurrenceRule::FREQ_DAILY);
$rule->setInterval(null);
$rule->setUntil(new \DateTime('1997-12-24'));
$this->assertEquals(
'FREQ=DAILY;UNTIL=19971224T000000Z',
$rule->getEscapedValue()
);
}
}

View file

@ -1,63 +0,0 @@
<?php
namespace Eluceo\iCal\Property;
use Eluceo\iCal\Property\StringValue;
class StringValueTest extends \PHPUnit_Framework_TestCase
{
public function testNoEscapeNeeded()
{
$stringValue = new StringValue('LOREM');
$this->assertEquals(
'LOREM',
$stringValue->getEscapedValue(),
'No escaping necessary'
);
}
public function testValueContainsBackslash()
{
$stringValue = new StringValue('text contains backslash: \\');
$this->assertEquals(
'text contains backslash: \\\\',
$stringValue->getEscapedValue(),
'Text contains backslash'
);
}
public function testEscapingDoubleQuotes()
{
$stringValue = new StringValue('text with "doublequotes" will be escaped');
$this->assertEquals(
'text with \\"doublequotes\\" will be escaped',
$stringValue->getEscapedValue(),
'Escaping double quotes'
);
}
public function testEscapingSemicolonAndComma()
{
$stringValue = new StringValue('text with , and ; will also be escaped');
$this->assertEquals(
'text with \\, and \\; will also be escaped',
$stringValue->getEscapedValue(),
'Escaping ; and ,'
);
}
public function testNewLineEscaping()
{
$stringValue = new StringValue("Text with new\n line");
$this->assertEquals(
'Text with new\\n line',
$stringValue->getEscapedValue(),
'Escape new line to text'
);
}
}

View file

@ -1,18 +0,0 @@
<?php
namespace Eluceo\iCal;
class PropertyBagTest extends \PHPUnit_Framework_TestCase
{
/**
* @todo Use Mocks instead of a real object!
*/
public function testPropertyAlreadyExistsOnAddingProperty()
{
$this->setExpectedException('\\Exception', "Property with name 'propName' already exists");
$propertyBag = new PropertyBag();
$propertyBag->add(new Property('propName', ''));
$propertyBag->add(new Property('propName', ''));
}
}

View file

@ -1,42 +0,0 @@
<?php
namespace Eluceo\iCal;
class PropertyTest extends \PHPUnit_Framework_TestCase
{
public function testPropertyWithSingleValue()
{
$property = new Property('DTSTAMP', '20131020T153112');
$this->assertEquals(
'DTSTAMP:20131020T153112',
$property->toLine()
);
}
public function testPropertyWithValueAndParams()
{
$property = new Property('DTSTAMP', '20131020T153112', array('TZID' => 'Europe/Berlin'));
$this->assertEquals(
'DTSTAMP;TZID=Europe/Berlin:20131020T153112',
$property->toLine()
);
}
public function testPropertyWithEscapedSingleValue()
{
$property = new Property('SOMEPROP', 'Escape me!"');
$this->assertEquals(
'SOMEPROP:Escape me!\\"',
$property->toLine()
);
}
public function testPropertyWithEscapedValues()
{
$property = new Property('SOMEPROP', 'Escape me!"', array('TEST' => 'Lorem "test" ipsum'));
$this->assertEquals(
'SOMEPROP;TEST="Lorem \\"test\\" ipsum":Escape me!\\"',
$property->toLine()
);
}
}

View file

@ -1,16 +0,0 @@
language: php
php:
- 7.0
- 5.6
- 5.5
- 5.4
- 5.3
- hhvm
- hhvm-nightly
matrix:
fast_finish: true
allow_failures:
- php: 7.0
- php: hhvm-nightly

View file

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

File diff suppressed because it is too large Load diff

View file

@ -1,57 +0,0 @@
## Parsedown
[![Build Status](https://img.shields.io/travis/erusev/parsedown/master.svg?style=flat-square)](https://travis-ci.org/erusev/parsedown)
<!--[![Total Downloads](http://img.shields.io/packagist/dt/erusev/parsedown.svg?style=flat-square)](https://packagist.org/packages/erusev/parsedown)-->
Better Markdown Parser in PHP
[Demo](http://parsedown.org/demo) |
[Benchmarks](http://parsedown.org/speed) |
[Tests](http://parsedown.org/tests/) |
[Documentation](https://github.com/erusev/parsedown/wiki/)
### Features
* Super Fast
* [GitHub flavored](https://help.github.com/articles/github-flavored-markdown)
* Extensible
* Tested in 5.3 to 5.6
* [Markdown Extra extension](https://github.com/erusev/parsedown-extra)
### Installation
Include `Parsedown.php` or install [the composer package](https://packagist.org/packages/erusev/parsedown).
### Example
``` php
$Parsedown = new Parsedown();
echo $Parsedown->text('Hello _Parsedown_!'); # prints: <p>Hello <em>Parsedown</em>!</p>
```
More examples in [the wiki](https://github.com/erusev/parsedown/wiki/) and in [this video tutorial](http://youtu.be/wYZBY8DEikI).
### Questions
**How does Parsedown work?**
It tries to read Markdown like a human. First, it looks at the lines. Its interested in how the lines start. This helps it recognise blocks. It knows, for example, that if a line start with a `-` then it perhaps belong to a list. Once it recognises the blocks, it continues to the content. As it reads, it watches out for special characters. This helps it recognise inline elements (or inlines).
We call this approach "line based". We believe that Parsedown is the first Markdown parser to use it. Since the release of Parsedown, other developers have used the same approach to develop other Markdown parsers in PHP and in other languages.
**Is it compliant with CommonMark?**
It passes most of the CommonMark tests. Most of the tests that don't pass deal with cases that are quite uncommon. Still, as CommonMark matures, compliance should improve.
**Who uses it?**
[phpDocumentor](http://www.phpdoc.org/), [October CMS](http://octobercms.com/), [Bolt CMS](http://bolt.cm/), [Kirby CMS](http://getkirby.com/), [Grav CMS](http://getgrav.org/), [Statamic CMS](http://www.statamic.com/), [RaspberryPi.org](http://www.raspberrypi.org/) and [more](https://www.versioneye.com/php/erusev:parsedown/references).
**How can I help?**
Use it, star it, share it and if you feel generous, [donate](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=528P3NZQMP8N2).
---
You might also like [Caret](http://caret.io) - our Markdown editor for the desktop.

View file

@ -1,18 +0,0 @@
{
"name": "erusev/parsedown",
"description": "Parser for Markdown.",
"keywords": ["markdown", "parser"],
"homepage": "http://parsedown.org",
"type": "library",
"license": "MIT",
"authors": [
{
"name": "Emanuil Rusev",
"email": "hello@erusev.com",
"homepage": "http://erusev.com"
}
],
"autoload": {
"psr-0": {"Parsedown": ""}
}
}

View file

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="test/bootstrap.php" colors="true">
<testsuites>
<testsuite>
<file>test/ParsedownTest.php</file>
</testsuite>
</testsuites>
</phpunit>

View file

@ -1,74 +0,0 @@
<?php
/**
* Test Parsedown against the CommonMark spec.
*
* Some code based on the original JavaScript test runner by jgm.
*
* @link http://commonmark.org/ CommonMark
* @link http://git.io/8WtRvQ JavaScript test runner
*/
class CommonMarkTest extends PHPUnit_Framework_TestCase
{
const SPEC_URL = 'https://raw.githubusercontent.com/jgm/stmd/master/spec.txt';
/**
* @dataProvider data
* @param $section
* @param $markdown
* @param $expectedHtml
*/
function test_($section, $markdown, $expectedHtml)
{
$Parsedown = new Parsedown();
$Parsedown->setUrlsLinked(false);
$actualHtml = $Parsedown->text($markdown);
$actualHtml = $this->normalizeMarkup($actualHtml);
$this->assertEquals($expectedHtml, $actualHtml);
}
function data()
{
$spec = file_get_contents(self::SPEC_URL);
$spec = strstr($spec, '<!-- END TESTS -->', true);
$tests = array();
$currentSection = '';
preg_replace_callback(
'/^\.\n([\s\S]*?)^\.\n([\s\S]*?)^\.$|^#{1,6} *(.*)$/m',
function($matches) use ( & $tests, & $currentSection, & $testCount) {
if (isset($matches[3]) and $matches[3]) {
$currentSection = $matches[3];
} else {
$testCount++;
$markdown = $matches[1];
$markdown = preg_replace('/→/', "\t", $markdown);
$expectedHtml = $matches[2];
$expectedHtml = $this->normalizeMarkup($expectedHtml);
$tests []= array(
$currentSection, # section
$markdown, # markdown
$expectedHtml, # html
);
}
},
$spec
);
return $tests;
}
private function normalizeMarkup($markup)
{
$markup = preg_replace("/\n+/", "\n", $markup);
$markup = preg_replace('/^\s+/m', '', $markup);
$markup = preg_replace('/^((?:<[\w]+>)+)\n/m', '$1', $markup);
$markup = preg_replace('/\n((?:<\/[\w]+>)+)$/m', '$1', $markup);
$markup = trim($markup);
return $markup;
}
}

View file

@ -1,159 +0,0 @@
<?php
class ParsedownTest extends PHPUnit_Framework_TestCase
{
final function __construct($name = null, array $data = array(), $dataName = '')
{
$this->dirs = $this->initDirs();
$this->Parsedown = $this->initParsedown();
parent::__construct($name, $data, $dataName);
}
private $dirs, $Parsedown;
/**
* @return array
*/
protected function initDirs()
{
$dirs []= dirname(__FILE__).'/data/';
return $dirs;
}
/**
* @return Parsedown
*/
protected function initParsedown()
{
$Parsedown = new Parsedown();
return $Parsedown;
}
/**
* @dataProvider data
* @param $test
* @param $dir
*/
function test_($test, $dir)
{
$markdown = file_get_contents($dir . $test . '.md');
$expectedMarkup = file_get_contents($dir . $test . '.html');
$expectedMarkup = str_replace("\r\n", "\n", $expectedMarkup);
$expectedMarkup = str_replace("\r", "\n", $expectedMarkup);
$actualMarkup = $this->Parsedown->text($markdown);
$this->assertEquals($expectedMarkup, $actualMarkup);
}
function data()
{
$data = array();
foreach ($this->dirs as $dir)
{
$Folder = new DirectoryIterator($dir);
foreach ($Folder as $File)
{
/** @var $File DirectoryIterator */
if ( ! $File->isFile())
{
continue;
}
$filename = $File->getFilename();
$extension = pathinfo($filename, PATHINFO_EXTENSION);
if ($extension !== 'md')
{
continue;
}
$basename = $File->getBasename('.md');
if (file_exists($dir . $basename . '.html'))
{
$data []= array($basename, $dir);
}
}
}
return $data;
}
public function test_no_markup()
{
$markdownWithHtml = <<<MARKDOWN_WITH_MARKUP
<div>_content_</div>
sparse:
<div>
<div class="inner">
_content_
</div>
</div>
paragraph
<style type="text/css">
p {
color: red;
}
</style>
comment
<!-- html comment -->
MARKDOWN_WITH_MARKUP;
$expectedHtml = <<<EXPECTED_HTML
<p>&lt;div&gt;<em>content</em>&lt;/div&gt;</p>
<p>sparse:</p>
<p>&lt;div&gt;
&lt;div class=&quot;inner&quot;&gt;
<em>content</em>
&lt;/div&gt;
&lt;/div&gt;</p>
<p>paragraph</p>
<p>&lt;style type=&quot;text/css&quot;&gt;
p {
color: red;
}
&lt;/style&gt;</p>
<p>comment</p>
<p>&lt;!-- html comment --&gt;</p>
EXPECTED_HTML;
$parsedownWithNoMarkup = new Parsedown();
$parsedownWithNoMarkup->setMarkupEscaped(true);
$this->assertEquals($expectedHtml, $parsedownWithNoMarkup->text($markdownWithHtml));
}
public function testLateStaticBinding()
{
include 'test/TestParsedown.php';
$parsedown = Parsedown::instance();
$this->assertInstanceOf('Parsedown', $parsedown);
// After instance is already called on Parsedown
// subsequent calls with the same arguments return the same instance
$sameParsedown = TestParsedown::instance();
$this->assertInstanceOf('Parsedown', $sameParsedown);
$this->assertSame($parsedown, $sameParsedown);
$testParsedown = TestParsedown::instance('test late static binding');
$this->assertInstanceOf('TestParsedown', $testParsedown);
$sameInstanceAgain = TestParsedown::instance('test late static binding');
$this->assertSame($testParsedown, $sameInstanceAgain);
}
}

View file

@ -1,5 +0,0 @@
<?php
class TestParsedown extends Parsedown
{
}

View file

@ -1,3 +0,0 @@
<?php
include 'Parsedown.php';

View file

@ -1,18 +0,0 @@
<table>
<thead>
<tr>
<th>header 1</th>
<th>header 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>cell 1.1</td>
<td>cell 1.2</td>
</tr>
<tr>
<td>cell 2.1</td>
<td>cell 2.2</td>
</tr>
</tbody>
</table>

View file

@ -1,4 +0,0 @@
| header 1 | header 2 |
| -------- | -------- |
| cell 1.1 | cell 1.2 |
| cell 2.1 | cell 2.2 |

View file

@ -1,21 +0,0 @@
<table>
<thead>
<tr>
<th style="text-align: left;">header 1</th>
<th style="text-align: center;">header 2</th>
<th style="text-align: right;">header 2</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: left;">cell 1.1</td>
<td style="text-align: center;">cell 1.2</td>
<td style="text-align: right;">cell 1.3</td>
</tr>
<tr>
<td style="text-align: left;">cell 2.1</td>
<td style="text-align: center;">cell 2.2</td>
<td style="text-align: right;">cell 2.3</td>
</tr>
</tbody>
</table>

View file

@ -1,4 +0,0 @@
| header 1 | header 2 | header 2 |
| :------- | :------: | -------: |
| cell 1.1 | cell 1.2 | cell 1.3 |
| cell 2.1 | cell 2.2 | cell 2.3 |

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