starting rework for 2.2.0

This commit is contained in:
Christoph Haas 2016-06-20 15:04:53 +02:00
parent c387565a45
commit e76893d82f
33 changed files with 14133 additions and 11836 deletions

8
.idea/calendarimporter.iml generated Normal file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

4
.idea/encodings.xml generated Normal file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
</project>

8
.idea/modules.xml generated Normal file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/calendarimporter.iml" filepath="$PROJECT_DIR$/.idea/calendarimporter.iml" />
</modules>
</component>
</project>

4
.idea/php.xml generated Normal file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="PhpProjectSharedConfiguration" php_language_level="5.5.0" />
</project>

5
.idea/scopes/scope_settings.xml generated Normal file

@ -0,0 +1,5 @@
<component name="DependencyValidationManager">
<state>
<option name="SKIP_IMPORT_STATEMENTS" value="false" />
</state>
</component>

6
.idea/vcs.xml generated Normal file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

206
build.xml

@ -1,18 +1,15 @@
<project default="all"> <project default="all">
<!--############# CONFIGURE ALL PROPERTIES FOR THE REPLACER HERE ################--> <property environment="env"/>
<property name="plugin_version" value="2.1.0"/> <property name="root-folder" value="${basedir}/../../"/>
<!-- EOC --> <property name="tools-folder" value="${root-folder}/tools/"/>
<property name="target-folder" value="${root-folder}/deploy/plugins"/>
<property name="root-folder" value="${basedir}/../"/> <property name="server-folder" value="${root-folder}/server"/>
<property name="tools-folder" value="${root-folder}/TOOLS/"/>
<property name="target-folder" value="${root-folder}/DEPLOY/plugins"/>
<import file="${tools-folder}/antutil.xml"/> <import file="${tools-folder}/antutil.xml"/>
<typedef file="${tools-folder}/antlib.xml"> <typedef file="${tools-folder}/antlib.xml">
<classpath> <classpath>
<pathelement location="${tools-folder}/tools.jar"/> <pathelement location="${tools-folder}/tools.jar"/>
<pathelement location="${tools-folder}/lib/compiler.jar"/>
</classpath> </classpath>
</typedef> </typedef>
@ -22,29 +19,7 @@
</classpath> </classpath>
</taskdef> </taskdef>
<!-- os checks for xmllint... -->
<condition property="isWindows" value="true">
<os family="windows" />
</condition>
<!-- define nicknames for libraries -->
<property name="yui-compressor" location="${tools-folder}/lib/yuicompressor-2.4.2.jar" />
<property name="yui-compressor-ant-task" location="${tools-folder}/lib/yui-compressor-ant-task-0.5.jar" />
<!-- adds libraries to the classpath -->
<path id="yui.classpath">
<pathelement location="${yui-compressor}" />
<pathelement location="${yui-compressor-ant-task}" />
</path>
<!-- define tasks -->
<taskdef name="yui-compressor" classname="net.noha.tools.ant.yuicompressor.tasks.YuiCompressorTask">
<classpath refid="yui.classpath" />
</taskdef>
<!-- Determine plugin name --> <!-- Determine plugin name -->
<var name="plugin" unset="true"/>
<basename file="${basedir}" property="plugin"/> <basename file="${basedir}" property="plugin"/>
<!-- The Plugin distribution files --> <!-- The Plugin distribution files -->
@ -54,8 +29,7 @@
<!-- The Plugin CSS files --> <!-- The Plugin CSS files -->
<property name="plugin-css-folder" value="resources/css"/> <property name="plugin-css-folder" value="resources/css"/>
<property name="plugin-css-file" value="${plugin}-min.css"/> <property name="plugin-css-file" value="${plugin}.css"/>
<property name="plugin-css-debug-file" value="${plugin}.css"/>
<!-- Meta target --> <!-- Meta target -->
<target name="all" depends="concat, compress"/> <target name="all" depends="concat, compress"/>
@ -68,16 +42,6 @@
<include name="${plugin-file}"/> <include name="${plugin-file}"/>
<include name="${plugin-debugfile}"/> <include name="${plugin-debugfile}"/>
</fileset> </fileset>
<fileset dir="${target-folder}/${plugin-folder}/php">
<include name="**/*.php"/>
</fileset>
<fileset dir="${target-folder}/${plugin-folder}/resources">
<include name="**/*"/>
</fileset>
<fileset dir="${target-folder}/${plugin-folder}/${plugin-css-folder}">
<include name="${plugin-css-debug-file}"/>
<include name="${plugin-css-file}"/>
</fileset>
</delete> </delete>
</target> </target>
@ -89,27 +53,11 @@
<then> <then>
<mkdir dir="${target-folder}/${plugin-folder}/js"/> <mkdir dir="${target-folder}/${plugin-folder}/js"/>
<echo message="Concatenating: ${plugin-debugfile}"/> <echo message="Concatenating: ${plugin-debugfile}"/>
<!-- TODO: fix JS files for zConcat --> <zConcat outputFolder="${target-folder}/${plugin-folder}/js" outputFile="${plugin-debugfile}" prioritize="\w+">
<!--zConcat outputFolder="${target-folder}/${plugin-folder}/js" outputFile="${plugin-debugfile}" prioritize="\w+">
<concatfiles> <concatfiles>
<fileset dir="js" includes="**/*.js" /> <fileset dir="js" includes="**/*.js" />
</concatfiles> </concatfiles>
</zConcat--> </zConcat>
<concat destfile="${target-folder}/${plugin-folder}/js/${plugin-debugfile}">
<fileset file="js/ABOUT.js" />
<fileset file="js/external/Ext.util.base64.js" />
<fileset file="js/data/timezones.js" />
<fileset file="js/plugin.calendarimporter.js" />
<fileset file="js/data/ResponseHandler.js" />
<fileset file="js/dialogs/ImportContentPanel.js" />
<fileset file="js/dialogs/ImportPanel.js" />
<fileset file="js/settings/SettingsWidget.js" />
<fileset file="js/settings/SettingsCalSyncWidget.js" />
<fileset file="js/settings/ui/CalSyncPanel.js" />
<fileset file="js/settings/ui/CalSyncGrid.js" />
<fileset file="js/settings/dialogs/CalSyncEditContentPanel.js" />
<fileset file="js/settings/dialogs/CalSyncEditPanel.js" />
</concat>
</then> </then>
</if> </if>
@ -118,8 +66,8 @@
<available file="${plugin-css-folder}" type="dir" /> <available file="${plugin-css-folder}" type="dir" />
<then> <then>
<mkdir dir="${target-folder}/${plugin-folder}/${plugin-css-folder}"/> <mkdir dir="${target-folder}/${plugin-folder}/${plugin-css-folder}"/>
<echo message="Concatenating: ${plugin-css-debug-file}"/> <echo message="Concatenating: ${plugin-css-file}"/>
<zConcat outputFolder="${target-folder}/${plugin-folder}/${plugin-css-folder}" outputFile="${plugin-css-debug-file}"> <zConcat outputFolder="${target-folder}/${plugin-folder}/${plugin-css-folder}" outputFile="${plugin-css-file}">
<concatfiles> <concatfiles>
<fileset dir="${plugin-css-folder}" includes="**/*.css" /> <fileset dir="${plugin-css-folder}" includes="**/*.css" />
</concatfiles> </concatfiles>
@ -164,15 +112,6 @@
var pgettext = function(msgctxt, msgid) {}; var pgettext = function(msgctxt, msgid) {};
</externs> </externs>
</zCompile> </zCompile>
<!--yui-compressor
warn="false"
munge="true"
preserveallsemicolons="false"
fromdir="${target-folder}/${plugin-folder}/js"
todir="${target-folder}/${plugin-folder}/js">
<include name="${plugin-debugfile}" />
</yui-compressor-->
</then> </then>
</if> </if>
</target> </target>
@ -180,105 +119,82 @@
<!-- syntax check all PHP files --> <!-- syntax check all PHP files -->
<target name="validate"> <target name="validate">
<if> <if>
<available file="config.php" type="file" /> <available file="php" filepath="${env.PATH}" />
<then> <then>
<antcall target="syntax-check"> <if>
<param name="file" value="config.php"/> <available file="config.php" type="file" />
</antcall> <then>
</then> <antcall target="syntax-check">
</if> <param name="file" value="config.php"/>
<if> </antcall>
<available file="php" type="dir" /> </then>
<then> </if>
<foreach target="syntax-check" param="file"> <if>
<path> <available file="php" type="dir" />
<fileset dir="."> <then>
<include name="**/*.php"/> <foreach target="syntax-check" param="file">
</fileset> <path>
</path> <fileset dir=".">
</foreach> <exclude name="php/vendor/**" />
<include name="**/*.php"/>
</fileset>
</path>
</foreach>
</then>
</if>
</then> </then>
<else>
<echo message="WARNING: PHP not available, not performing syntax-check on php files"/>
</else>
</if> </if>
</target> </target>
<target name="syntax-check"> <target name="syntax-check">
<echo message="validating ${file}"/> <echo message="validating ${file}"/>
<exec executable="php" failonerror="true" failifexecutionfails="false"> <exec executable="php" failonerror="true">
<arg value="-l"/> <arg value="-l"/>
<arg value="${file}"/> <arg value="${file}"/>
</exec> </exec>
</target> </target>
<!-- on windows we do not check the xml file -->
<target name="xml-os-sel" depends="xml-check,xml-copy">
<echo>Processing manifest.xml</echo>
</target>
<!-- check manifest.xml if we are on windows... -->
<target name="xml-check" unless="isWindows">
<echo message="Checking xml: manifest.xml" />
<!-- Copy (and validate) manifest.xml -->
<exec executable="xmllint" output="${target-folder}/${plugin-folder}/manifest.xml" failonerror="true" error="/dev/stdout" failifexecutionfails="false">
<arg value="--valid"/>
<arg value="--path"/>
<arg value="${root-folder}/server"/>
<arg value="manifest.xml"/>
</exec>
</target>
<!-- check manifest.xml if we are on windows... -->
<target name="xml-copy" if="isWindows">
<echo message="Copying xml: manifest.xml" />
<!-- Copy manifest.xml -->
<copy todir="${target-folder}/${plugin-folder}">
<fileset dir=".">
<include name="manifest.xml"/>
</fileset>
</copy>
</target>
<!-- Install all files into the target folder --> <!-- Install all files into the target folder -->
<target name="deploy" depends="clean, compress, compresscss, validate, xml-os-sel"> <target name="deploy" depends="compress, validate">
<mkdir dir="${target-folder}/${plugin-folder}"/> <mkdir dir="${target-folder}/${plugin-folder}"/>
<!-- Copy (and validate) manifest.xml -->
<if>
<available file="xmllint" filepath="${env.PATH}" />
<then>
<exec executable="xmllint" output="${target-folder}/${plugin-folder}/manifest.xml" failonerror="true">
<arg value="--valid"/>
<arg value="--path"/>
<arg value="${server-folder}"/>
<arg value="manifest.xml"/>
</exec>
</then>
<else>
<echo message="WARNING: xmllint not available, not performing syntax-check on manifest.xml"/>
<!-- xmllint is not available, so we must copy the file manually -->
<copy todir="${target-folder}/${plugin-folder}">
<fileset dir=".">
<include name="manifest.xml"/>
</fileset>
</copy>
</else>
</if>
<!-- copy files --> <!-- copy files -->
<copy todir="${target-folder}/${plugin-folder}"> <copy todir="${target-folder}/${plugin-folder}">
<fileset dir="."> <fileset dir=".">
<include name="resources/**/*"/> <include name="resources/**/*.*"/>
<include name="external/**/*.*"/>
<include name="php/**/*.php"/> <include name="php/**/*.php"/>
<include name="config.php"/> <include name="config.php"/>
<include name="changelog.txt"/>
<!-- exclude the ant script --> <!-- exclude the ant script -->
<exclude name="build.xml"/> <exclude name="build.xml"/>
<!-- CSS is generated during build --> <!-- CSS is generated during build -->
<exclude name="resources/css/*.*"/> <exclude name="resources/css/*.*"/>
</fileset> </fileset>
</copy> </copy>
<!-- replace all variables... -->
<replace file="${target-folder}/${plugin-folder}/manifest.xml" token="@_@PLUGIN_VERSION@_@" value="${plugin_version}" />
</target> </target>
<!-- compresses each CSS file -->
<target name="compresscss" depends="concat">
<available file="${tools-folder}/lib/yui-compressor-ant-task-0.5.jar" property="YUIANT_AVAILABLE" />
<fail unless="YUIANT_AVAILABLE" message="yui-compressor-ant-task-0.5.jar not found" />
<if>
<available file="${target-folder}/${plugin-folder}/${plugin-css-folder}/${plugin-css-debug-file}" type="file" />
<then>
<yui-compressor
warn="false"
munge="true"
preserveallsemicolons="false"
fromdir="${target-folder}/${plugin-folder}/${plugin-css-folder}"
todir="${target-folder}/${plugin-folder}/${plugin-css-folder}">
<include name="${plugin-css-debug-file}" />
</yui-compressor>
</then>
</if>
</target>
</project> </project>

@ -1,87 +0,0 @@
/**
* A small tool to create our timezone mappings list =)
*/
import java.util.TimeZone;
public class Main {
static String map[] = new String[51]; // one field = 30 minutes step
private static void initMap() {
map[0] = "Pacific/Midway";
map[1] = "";
map[2] = "Pacific/Fakaofo";
map[3] = "Pacific/Marquesas";
map[4] = "America/Anchorage";
map[5] = "";
map[6] = "America/Dawson";
map[7] = "";
map[8] = "America/Dawson_Creek";
map[9] = "";
map[10] = "America/Chicago";
map[11] = "America/Caracas";
map[12] = "America/Detroit";
map[13] = "America/Caracas";
map[14] = "America/Santiago";
map[15] = "America/St_Johns";
map[16] = "America/Sao_Paulo";
map[17] = "";
map[18] = "America/Noronha";
map[19] = "";
map[20] = "Atlantic/Cape_Verde";
map[21] = "";
map[22] = "Africa/Abidjan";
map[23] = "";
map[24] = "Europe/Vienna";
map[25] = "";
map[26] = "Asia/Jerusalem";
map[27] = "";
map[28] = "Africa/Addis_Ababa";
map[29] = "Asia/Tehran";
map[30] = "Asia/Dubai";
map[31] = "Asia/Kabul";
map[32] = "Antarctica/Mawson";
map[33] = "Asia/Colombo";
map[34] = "Antarctica/Vostok";
map[35] = "Asia/Rangoon";
map[36] = "Antarctica/Davis";
map[37] = "";
map[38] = "Antarctica/Casey";
map[39] = "";
map[40] = "Asia/Dili";
map[41] = "Australia/Darwin";
map[42] = "Australia/Currie";
map[43] = "Australia/Lord_Howe";
map[44] = "Antarctica/Macquarie";
map[45] = "Pacific/Norfolk";
map[46] = "Antarctica/McMurdo";
map[47] = "";
map[48] = "Pacific/Enderbury";
map[49] = "";
map[50] = "Pacific/Kiritimati";
}
/**
* @param args
*/
public static void main(String[] args) {
initMap();
int i = 0;
for(int time = -660; time < 900; time += 30) {
int hours = time / 60;
int minutes = Math.abs(time) % 60;
String[] avaiId = TimeZone.getAvailableIDs(time*60*1000);
if(avaiId.length > 0) {
System.out.printf("\t\t/*%+d:%02d*/\n", hours, minutes);
for (String string : avaiId) {
System.out.println("\t\t'" + string + "' : '" + map[i] + "',");
}
}
i++;
}
}
}

@ -2,7 +2,7 @@
* ABOUT.js zarafa calender to ics im/exporter * ABOUT.js zarafa calender to ics im/exporter
* *
* Author: Christoph Haas <christoph.h@sprinternet.at> * Author: Christoph Haas <christoph.h@sprinternet.at>
* Copyright (C) 2012-2013 Christoph Haas * Copyright (C) 2012-2016 Christoph Haas
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -29,7 +29,7 @@ Ext.namespace('Zarafa.plugins.calendarimporter');
* The copyright string holding the copyright notice for the Zarafa calendarimporter Plugin. * The copyright string holding the copyright notice for the Zarafa calendarimporter Plugin.
*/ */
Zarafa.plugins.calendarimporter.ABOUT = "" Zarafa.plugins.calendarimporter.ABOUT = ""
+ "<p>Copyright (C) 2012-2013 Christoph Haas &lt;christoph.h@sprinternet.at&gt;</p>" + "<p>Copyright (C) 2012-2016 Christoph Haas &lt;christoph.h@sprinternet.at&gt;</p>"
+ "<p>This program is free software; you can redistribute it and/or " + "<p>This program is free software; you can redistribute it and/or "
+ "modify it under the terms of the GNU Lesser General Public " + "modify it under the terms of the GNU Lesser General Public "

@ -2,7 +2,7 @@
* ResponseHandler.js zarafa calender to ics im/exporter * ResponseHandler.js zarafa calender to ics im/exporter
* *
* Author: Christoph Haas <christoph.h@sprinternet.at> * Author: Christoph Haas <christoph.h@sprinternet.at>
* Copyright (C) 2012-2013 Christoph Haas * Copyright (C) 2012-2016 Christoph Haas
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public

File diff suppressed because it is too large Load Diff

@ -2,7 +2,7 @@
* ImportContentPanel.js zarafa calender to ics im/exporter * ImportContentPanel.js zarafa calender to ics im/exporter
* *
* Author: Christoph Haas <christoph.h@sprinternet.at> * Author: Christoph Haas <christoph.h@sprinternet.at>
* Copyright (C) 2012-2013 Christoph Haas * Copyright (C) 2012-2016 Christoph Haas
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -42,13 +42,9 @@ Zarafa.plugins.calendarimporter.dialogs.ImportContentPanel = Ext.extend(Zarafa.c
*/ */
constructor : function(config) { constructor : function(config) {
config = config || {}; config = config || {};
var title = _('Import Calendar File');
if(container.getSettingsModel().get("zarafa/v1/plugins/calendarimporter/enable_export")){
title = _('Import/Export Calendar File');
}
Ext.applyIf(config, { Ext.applyIf(config, {
layout : 'fit', layout : 'fit',
title : title, title : _('Import Calendar File'),
closeOnSave : true, closeOnSave : true,
width : 800, width : 800,
height : 700, height : 700,
@ -56,7 +52,8 @@ Zarafa.plugins.calendarimporter.dialogs.ImportContentPanel = Ext.extend(Zarafa.c
items : [ items : [
{ {
xtype : 'calendarimporter.importpanel', xtype : 'calendarimporter.importpanel',
filename : config.filename filename : config.filename,
folder : config.folder
} }
] ]
}); });

@ -2,7 +2,7 @@
* ImportPanel.js zarafa calender to ics im/exporter * ImportPanel.js zarafa calender to ics im/exporter
* *
* Author: Christoph Haas <christoph.h@sprinternet.at> * Author: Christoph Haas <christoph.h@sprinternet.at>
* Copyright (C) 2012-2013 Christoph Haas * Copyright (C) 2012-2016 Christoph Haas
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -29,7 +29,7 @@ Ext.namespace("Zarafa.plugins.calendarimporter.dialogs");
/** /**
* @class Zarafa.plugins.calendarimporter.dialogs.ImportPanel * @class Zarafa.plugins.calendarimporter.dialogs.ImportPanel
* @extends Ext.form.FormPanel * @extends Ext.Panel
*/ */
Zarafa.plugins.calendarimporter.dialogs.ImportPanel = Ext.extend(Ext.Panel, { Zarafa.plugins.calendarimporter.dialogs.ImportPanel = Ext.extend(Ext.Panel, {
@ -46,7 +46,7 @@ Zarafa.plugins.calendarimporter.dialogs.ImportPanel = Ext.extend(Ext.Panel, {
loadMask: null, loadMask: null,
/* export event buffer */ /* export event buffer */
exportResponse: new Array(), exportResponse: [],
/* how many requests are still running? */ /* how many requests are still running? */
runningRequests: null, runningRequests: null,
@ -54,13 +54,8 @@ Zarafa.plugins.calendarimporter.dialogs.ImportPanel = Ext.extend(Ext.Panel, {
/* The store for the selection grid */ /* The store for the selection grid */
store: null, store: null,
/** /* selected folder */
* The internal 'iframe' which is hidden from the user, which is used for downloading folder : null,
* attachments. See {@link #doOpen}.
* @property
* @type Ext.Element
*/
downloadFrame : undefined,
/** /**
* @constructor * @constructor
@ -71,10 +66,14 @@ Zarafa.plugins.calendarimporter.dialogs.ImportPanel = Ext.extend(Ext.Panel, {
var self = this; var self = this;
this.timezone = container.getSettingsModel().get("zarafa/v1/plugins/calendarimporter/default_timezone"); this.timezone = container.getSettingsModel().get("zarafa/v1/plugins/calendarimporter/default_timezone");
if(typeof config.filename !== "undefined") { if (!Ext.isEmpty(config.filename)) {
this.icsfile = config.filename; this.icsfile = config.filename;
} }
if (!Ext.isEmpty(config.folder)) {
this.folder = config.folder;
}
// create the data store // create the data store
this.store = new Ext.data.ArrayStore({ this.store = new Ext.data.ArrayStore({
fields: [ fields: [
@ -114,29 +113,19 @@ Zarafa.plugins.calendarimporter.dialogs.ImportPanel = Ext.extend(Ext.Panel, {
this.createGrid() this.createGrid()
], ],
buttons: [ buttons: [
this.createExportAllButton(),
this.createSubmitAllButton(), this.createSubmitAllButton(),
this.createSubmitButton(), this.createSubmitButton(),
this.createCancelButton() this.createCancelButton()
], ],
listeners: { listeners: {
afterrender: function (cmp) { afterrender: function (cmp) {
Ext.getCmp('importbutton').disable(); this.loadMask = new Ext.LoadMask(this.getEl(), {msg:'Loading...'});
this.loadMask = new Ext.LoadMask(Ext.getCmp("importpanel").getEl(), {msg:'Loading...'});
if(this.icsfile != null) { // if we have got the filename from an attachment if(this.icsfile != null) { // if we have got the filename from an attachment
this.parseCalendar(this.icsfile, this.timezone, this.ignoredst); this.parseCalendar(this.icsfile, this.timezone, this.ignoredst);
} }
}, },
close: function (cmp) { scope: this
Ext.getCmp('importbutton').enable();
},
hide: function (cmp) {
Ext.getCmp('importbutton').enable();
},
destroy: function (cmp) {
Ext.getCmp('importbutton').enable();
}
} }
}); });
@ -167,6 +156,119 @@ Zarafa.plugins.calendarimporter.dialogs.ImportPanel = Ext.extend(Ext.Panel, {
}; };
}, },
/**
* Get all calendar folders.
* @param {boolean} asDropdownStore If true, a simple array store will be returned.
* @returns {*}
*/
getAllCalendarFolders: function (asDropdownStore) {
asDropdownStore = Ext.isEmpty(asDropdownStore) ? false : asDropdownStore;
var allFolders = [];
var inbox = container.getHierarchyStore().getDefaultStore();
var pub = container.getHierarchyStore().getPublicStore();
if (!Ext.isEmpty(inbox.subStores) && inbox.subStores.folders.totalLength > 0) {
for (var i = 0; i < inbox.subStores.folders.totalLength; i++) {
var folder = inbox.subStores.folders.getAt(i);
if (folder.get("container_class") == "IPF.Appointment") {
if (asDropdownStore) {
allFolders.push([
folder.get("entryid"),
folder.get("display_name")
]);
} else {
allFolders.push({
display_name : folder.get("display_name"),
entryid : folder.get("entryid"),
store_entryid: folder.get("store_entryid"),
is_public : false
});
}
}
}
}
if (!Ext.isEmpty(pub.subStores) && pub.subStores.folders.totalLength > 0) {
for (var j = 0; j < pub.subStores.folders.totalLength; j++) {
var folder = pub.subStores.folders.getAt(j);
if (folder.get("container_class") == "IPF.Appointment") {
if (asDropdownStore) {
allFolders.push([
folder.get("entryid"),
folder.get("display_name") + " (Public)"
]);
} else {
allFolders.push({
display_name : folder.get("display_name"),
entryid : folder.get("entryid"),
store_entryid: folder.get("store_entryid"),
is_public : true
});
}
}
}
}
if (asDropdownStore) {
return allFolders.sort(this.dynamicSort(1));
} else {
return allFolders;
}
},
/**
* Dynamic sort function, sorts by property name.
* @param {string|int} property
* @returns {Function}
*/
dynamicSort: function (property) {
var sortOrder = 1;
if (property[0] === "-") {
sortOrder = -1;
property = property.substr(1);
}
return function (a, b) {
var result = (a[property].toLowerCase() < b[property].toLowerCase()) ? -1 : (a[property].toLowerCase() > b[property].toLowerCase()) ? 1 : 0;
return result * sortOrder;
}
},
/**
* Return a calendar folder element by name.
* @param {string} name
* @returns {*}
*/
getCalendarFolderByName: function (name) {
var folders = this.getAllCalendarFolders(false);
for (var i = 0; i < folders.length; i++) {
if (folders[i].display_name == name) {
return folders[i];
}
}
return container.getHierarchyStore().getDefaultFolder('calendar');
},
/**
* Return a calendar folder element by entryid.
* @param {string} entryid
* @returns {*}
*/
getCalendarFolderByEntryid: function (entryid) {
var folders = this.getAllCalendarFolders(false);
for (var i = 0; i < folders.length; i++) {
if (folders[i].entryid == entryid) {
return folders[i];
}
}
return container.getHierarchyStore().getDefaultFolder('calendar');
},
/** /**
* Reloads the data of the grid * Reloads the data of the grid
* @private * @private
@ -241,52 +343,23 @@ Zarafa.plugins.calendarimporter.dialogs.ImportPanel = Ext.extend(Ext.Panel, {
}, },
createSelectBox: function() { createSelectBox: function() {
var defaultFolder = container.getHierarchyStore().getDefaultFolder('calendar'); // @type: Zarafa.hierarchy.data.MAPIFolderRecord var myStore = this.getAllCalendarFolders(true);
var subFolders = defaultFolder.getChildren();
var myStore = [];
/* add all local calendar folders */
var i = 0;
myStore.push(new Array(defaultFolder.getDefaultFolderKey(), defaultFolder.getDisplayName()));
for(i = 0; i < subFolders.length; i++) {
/* Store all subfolders */
myStore.push(new Array(subFolders[i].getDisplayName(), subFolders[i].getDisplayName(), false)); // 3rd field = isPublicfolder
}
/* add all shared calendar folders */
var pubStore = container.getHierarchyStore().getPublicStore();
if(typeof pubStore !== "undefined") {
try {
var pubFolder = pubStore.getDefaultFolder("publicfolders");
var pubSubFolders = pubFolder.getChildren();
for(i = 0; i < pubSubFolders.length; i++) {
if(pubSubFolders[i].isContainerClass("IPF.Appointment")){
myStore.push(new Array(pubSubFolders[i].getDisplayName(), pubSubFolders[i].getDisplayName() + " [Shared]", true)); // 3rd field = isPublicfolder
}
}
} catch (e) {
console.log("Error opening the shared folder...");
console.log(e);
}
}
return { return {
xtype: "selectbox", xtype: "selectbox",
ref: 'calendarselector', ref: 'calendarselector',
id: 'calendarselector',
editable: false, editable: false,
name: "choosen_calendar", name: "choosen_calendar",
value: container.getSettingsModel().get("zarafa/v1/plugins/calendarimporter/default_calendar"), value: Ext.isEmpty(this.folder) ? this.getCalendarFolderByName(container.getSettingsModel().get("zarafa/v1/plugins/calendarimporter/default_calendar")).entryid : this.folder,
width: 100, width: 100,
fieldLabel: "Select a calender", fieldLabel: "Select folder",
store: myStore, store: myStore,
mode: 'local', mode: 'local',
labelSeperator: ":", labelSeperator: ":",
border: false, border: false,
anchor: "100%", anchor: "100%",
scope: this, scope: this,
hidden : Ext.isEmpty(this.folder) ? false : true,
allowBlank: false allowBlank: false
} }
}, },
@ -295,7 +368,6 @@ Zarafa.plugins.calendarimporter.dialogs.ImportPanel = Ext.extend(Ext.Panel, {
return { return {
xtype: "selectbox", xtype: "selectbox",
ref: 'timezoneselector', ref: 'timezoneselector',
id: 'timezoneselector',
editable: false, editable: false,
name: "choosen_timezone", name: "choosen_timezone",
value: Zarafa.plugins.calendarimporter.data.Timezones.unMap(container.getSettingsModel().get("zarafa/v1/plugins/calendarimporter/default_timezone")), value: Zarafa.plugins.calendarimporter.data.Timezones.unMap(container.getSettingsModel().get("zarafa/v1/plugins/calendarimporter/default_timezone")),
@ -309,7 +381,7 @@ Zarafa.plugins.calendarimporter.dialogs.ImportPanel = Ext.extend(Ext.Panel, {
scope: this, scope: this,
allowBlank: true, allowBlank: true,
listeners: { listeners: {
'select': this.onTimezoneSelected, select: this.onTimezoneSelected,
scope: this scope: this
} }
} }
@ -319,7 +391,6 @@ Zarafa.plugins.calendarimporter.dialogs.ImportPanel = Ext.extend(Ext.Panel, {
return { return {
xtype: "checkbox", xtype: "checkbox",
ref: 'dstcheck', ref: 'dstcheck',
id: 'dstcheck',
name: "dst_check", name: "dst_check",
width: 100, width: 100,
fieldLabel: "Ignore DST (optional)", fieldLabel: "Ignore DST (optional)",
@ -330,7 +401,7 @@ Zarafa.plugins.calendarimporter.dialogs.ImportPanel = Ext.extend(Ext.Panel, {
scope: this, scope: this,
allowBlank: true, allowBlank: true,
listeners: { listeners: {
'check': this.onDstChecked, check: this.onDstChecked,
scope: this scope: this
} }
} }
@ -346,10 +417,11 @@ Zarafa.plugins.calendarimporter.dialogs.ImportPanel = Ext.extend(Ext.Panel, {
emptyText: 'Select an .ics calendar', emptyText: 'Select an .ics calendar',
border: false, border: false,
anchor: "100%", anchor: "100%",
height : "30",
scope: this, scope: this,
allowBlank: false, allowBlank: false,
listeners: { listeners: {
'fileselected': this.onFileSelected, fileselected: this.onFileSelected,
scope: this scope: this
} }
} }
@ -359,15 +431,13 @@ Zarafa.plugins.calendarimporter.dialogs.ImportPanel = Ext.extend(Ext.Panel, {
return { return {
xtype: "button", xtype: "button",
ref: "submitButton", ref: "submitButton",
id: "submitButton",
disabled: true, disabled: true,
width: 100, width: 100,
border: false, border: false,
text: _("Import"), text: _("Import"),
anchor: "100%", anchor: "100%",
handler: this.importCheckedEvents, handler: this.importCheckedEvents,
scope: this, scope: this
allowBlank: false
} }
}, },
@ -375,31 +445,13 @@ Zarafa.plugins.calendarimporter.dialogs.ImportPanel = Ext.extend(Ext.Panel, {
return { return {
xtype: "button", xtype: "button",
ref: "submitAllButton", ref: "submitAllButton",
id: "submitAllButton",
disabled: true, disabled: true,
width: 100, width: 100,
border: false, border: false,
text: _("Import All"), text: _("Import All"),
anchor: "100%", anchor: "100%",
handler: this.importAllEvents, handler: this.importAllEvents,
scope: this, scope: this
allowBlank: false
}
},
createExportAllButton: function() {
return {
xtype: "button",
ref: "exportAllButton",
id: "exportAllButton",
hidden: !container.getSettingsModel().get("zarafa/v1/plugins/calendarimporter/enable_export"),
width: 100,
border: false,
text: _("Export All"),
anchor: "100%",
handler: this.exportAllEvents,
scope: this,
allowBlank: false
} }
}, },
@ -411,8 +463,7 @@ Zarafa.plugins.calendarimporter.dialogs.ImportPanel = Ext.extend(Ext.Panel, {
text: _("Cancel"), text: _("Cancel"),
anchor: "100%", anchor: "100%",
handler: this.close, handler: this.close,
scope: this, scope: this
allowBlank: false
} }
}, },
@ -432,7 +483,7 @@ Zarafa.plugins.calendarimporter.dialogs.ImportPanel = Ext.extend(Ext.Panel, {
/** /**
* This is called when the dst checkbox has been selected * This is called when the dst checkbox has been selected
* @param {Ext.form.CheckBox} combo * @param {Ext.form.CheckBox} checkbox
* @param {boolean} checked * @param {boolean} checked
*/ */
onDstChecked : function(checkbox, checked) { onDstChecked : function(checkbox, checked) {

@ -2,7 +2,7 @@
* plugin.calendarimporter.js zarafa calender to ics im/exporter * plugin.calendarimporter.js zarafa calender to ics im/exporter
* *
* Author: Christoph Haas <christoph.h@sprinternet.at> * Author: Christoph Haas <christoph.h@sprinternet.at>
* Copyright (C) 2012-2013 Christoph Haas * Copyright (C) 2012-2016 Christoph Haas
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public

158
js/ui/ContextMenu.js Normal file

@ -0,0 +1,158 @@
/**
* ContectMenu.js zarafa calender to ics im/exporter
*
* Author: Christoph Haas <christoph.h@sprinternet.at>
* Copyright (C) 2012-2016 Christoph Haas
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
Ext.namespace('Zarafa.plugins.calendarimporter.ui');
/**
* @class Zarafa.plugins.calendarimporter.ui.ContextMenu
* @extends Zarafa.hierarchy.ui.ContextMenu
* @xtype calendarimporter.hierarchycontextmenu
*/
Zarafa.plugins.calendarimporter.ui.ContextMenu = Ext.extend(Zarafa.hierarchy.ui.ContextMenu, {
/**
* @constructor
* @param {Object} config Configuration object
*/
constructor: function (config) {
config = config || {};
if (config.contextNode) {
config.contextTree = config.contextNode.getOwnerTree();
}
Zarafa.plugins.calendarimporter.ui.ContextMenu.superclass.constructor.call(this, config);
// add item to menu
var additionalItems = this.createAdditionalContextMenuItems(config);
for (var i = 0; i < additionalItems.length; i++) {
config.items[0].push(additionalItems[i]);
}
Zarafa.plugins.calendarimporter.ui.ContextMenu.superclass.constructor.call(this, config); // redo ... otherwise menu does not get published
},
/**
* Create the Action context menu items.
* @param {Object} config Configuration object for the {@link Zarafa.plugins.calendarimporter.ui.ContextMenu ContextMenu}
* @return {Zarafa.core.ui.menu.ConditionalItem[]} The list of Action context menu items
* @private
*
* Note: All handlers are called within the scope of {@link Zarafa.plugins.calendarimporter.ui.ContextMenu HierarchyContextMenu}
*/
createAdditionalContextMenuItems: function (config) {
return [{
xtype: 'menuseparator'
}, {
text : _('Import Calendar'),
iconCls : 'icon_calendarimporter_import',
handler : this.onContextItemImport,
beforeShow: function (item, record) {
var access = record.get('access') & Zarafa.core.mapi.Access.ACCESS_MODIFY;
if (!access || (record.isIPMSubTree() && !record.getMAPIStore().isDefaultStore())) {
item.setDisabled(true);
} else {
item.setDisabled(false);
}
}
}, {
text : _('Export Calendar'),
iconCls : 'icon_calendarimporter_export',
handler : this.onContextItemExport,
beforeShow: function (item, record) {
var access = record.get('access') & Zarafa.core.mapi.Access.ACCESS_READ;
if (!access || (record.isIPMSubTree() && !record.getMAPIStore().isDefaultStore())) {
item.setDisabled(true);
} else {
item.setDisabled(false);
}
}
}];
},
/**
* Fires on selecting 'Open' menu option from {@link Zarafa.plugins.calendarimporter.ui.ContextMenu ContextMenu}
* @private
*/
onContextItemExport: function () {
var responseHandler = new Zarafa.plugins.calendarimporter.data.ResponseHandler({
successCallback: this.downloadICS,
scope : this
});
// request attachment preperation
container.getRequest().singleRequest(
'calendarmodule',
'export',
{
storeid: this.records.get("store_entryid"),
folder : this.records.get("entryid")
},
responseHandler
);
},
/**
* Fires on selecting 'Open' menu option from {@link Zarafa.plugins.calendarimporter.ui.ContextMenu ContextMenu}
* @private
*/
onContextItemImport: function () {
var componentType = Zarafa.core.data.SharedComponentType['plugins.calendarimporter.dialogs.importcontacts'];
var config = {
modal : true,
folder: this.records.get("entryid")
};
Zarafa.core.data.UIFactory.openLayerComponent(componentType, undefined, config);
},
/**
* Callback for the export request.
* @param {Object} response
*/
downloadICS: function (response) {
if (response.status == false) {
Zarafa.common.dialogs.MessageBox.show({
title : dgettext('plugin_files', 'Warning'),
msg : dgettext('plugin_files', response.message),
icon : Zarafa.common.dialogs.MessageBox.WARNING,
buttons: Zarafa.common.dialogs.MessageBox.OK
});
} else {
var downloadFrame = Ext.getBody().createChild({
tag: 'iframe',
cls: 'x-hidden'
});
var url = document.URL;
var link = url.substring(0, url.lastIndexOf('/') + 1);
link += "index.php?sessionid=" + container.getUser().getSessionId() + "&load=custom&name=download_ics";
link = Ext.urlAppend(link, "token=" + encodeURIComponent(response.download_token));
link = Ext.urlAppend(link, "filename=" + encodeURIComponent(response.filename));
downloadFrame.dom.contentWindow.location = link;
}
}
});
Ext.reg('calendarimporter.hierarchycontextmenu', Zarafa.plugins.calendarimporter.ui.ContextMenu);

@ -2,7 +2,7 @@
<!DOCTYPE plugin SYSTEM "manifest.dtd"> <!DOCTYPE plugin SYSTEM "manifest.dtd">
<plugin version="2"> <plugin version="2">
<info> <info>
<version>@_@PLUGIN_VERSION@_@</version> <version>2.2.0</version>
<name>calendarimporter</name> <name>calendarimporter</name>
<title>ICS Calendar Importer/Exporter</title> <title>ICS Calendar Importer/Exporter</title>
<author>Christoph Haas</author> <author>Christoph Haas</author>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,897 @@
<?php
/*********************************************************************************/
/**
*
* iCalcreator, a PHP rfc2445/rfc5545 solution.
*
* @copyright Copyright (c) 2007-2015 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* @link http://kigkonsult.se/iCalcreator/index.php
* @license http://kigkonsult.se/downloads/dl.php?f=LGPL
* @package iCalcreator
* @version 2.22
*/
/**
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*********************************************************************************/
/* iCalcreator XML (rfc6321) helper functions */
/*********************************************************************************/
/**
* format iCal XML output, rfc6321, using PHP SimpleXMLElement
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.18.1 - 2013-08-18
* @param object $calendar iCalcreator vcalendar instance reference
* @uses ICALCREATOR_VERSION
* @uses vcalendar::getProperty()
* @uses _addXMLchild()
* @uses vcalendar::getConfig()
* @uses vcalendar::getComponent()
* @uses calendarComponent::$objName
* @uses calendarComponent::getProperty()
* @return string
*/
function iCal2XML( $calendar ) {
/** fix an SimpleXMLElement instance and create root element */
$xmlstr = '<?xml version="1.0" encoding="utf-8"?><icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0">';
$xmlstr .= '<!-- created '.gmdate( 'Ymd\THis\Z' );
$xmlstr .= ' using kigkonsult.se '.ICALCREATOR_VERSION.' iCal2XMl (rfc6321) -->';
$xmlstr .= '</icalendar>';
$xml = new SimpleXMLElement( $xmlstr );
$vcalendar = $xml->addChild( 'vcalendar' );
/** fix calendar properties */
$properties = $vcalendar->addChild( 'properties' );
$calProps = array( 'version', 'prodid', 'calscale', 'method' );
foreach( $calProps as $calProp ) {
if( FALSE !== ( $content = $calendar->getProperty( $calProp )))
_addXMLchild( $properties, $calProp, 'text', $content );
}
while( FALSE !== ( $content = $calendar->getProperty( FALSE, FALSE, TRUE )))
_addXMLchild( $properties, $content[0], 'unknown', $content[1]['value'], $content[1]['params'] );
$langCal = $calendar->getConfig( 'language' );
/** prepare to fix components with properties */
$components = $vcalendar->addChild( 'components' );
/** fix component properties */
while( FALSE !== ( $component = $calendar->getComponent())) {
$compName = $component->objName;
$child = $components->addChild( $compName );
$properties = $child->addChild( 'properties' );
$langComp = $component->getConfig( 'language' );
$props = $component->getConfig( 'setPropertyNames' );
foreach( $props as $prop ) {
switch( strtolower( $prop )) {
case 'attach': // may occur multiple times, below
while( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE ))) {
$type = ( isset( $content['params']['VALUE'] ) && ( 'BINARY' == $content['params']['VALUE'] )) ? 'binary' : 'uri';
unset( $content['params']['VALUE'] );
_addXMLchild( $properties, $prop, $type, $content['value'], $content['params'] );
}
break;
case 'attendee':
while( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE ))) {
if( isset( $content['params']['CN'] ) && !isset( $content['params']['LANGUAGE'] )) {
if( $langComp )
$content['params']['LANGUAGE'] = $langComp;
elseif( $langCal )
$content['params']['LANGUAGE'] = $langCal;
}
_addXMLchild( $properties, $prop, 'cal-address', $content['value'], $content['params'] );
}
break;
case 'exdate':
while( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE ))) {
$type = ( isset( $content['params']['VALUE'] ) && ( 'DATE' == $content['params']['VALUE'] )) ? 'date' : 'date-time';
unset( $content['params']['VALUE'] );
_addXMLchild( $properties, $prop, $type, $content['value'], $content['params'] );
}
break;
case 'freebusy':
while( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE ))) {
if( is_array( $content ) && isset( $content['value']['fbtype'] )) {
$content['params']['FBTYPE'] = $content['value']['fbtype'];
unset( $content['value']['fbtype'] );
}
_addXMLchild( $properties, $prop, 'period', $content['value'], $content['params'] );
}
break;
case 'request-status':
while( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE ))) {
if( !isset( $content['params']['LANGUAGE'] )) {
if( $langComp )
$content['params']['LANGUAGE'] = $langComp;
elseif( $langCal )
$content['params']['LANGUAGE'] = $langCal;
}
_addXMLchild( $properties, $prop, 'rstatus', $content['value'], $content['params'] );
}
break;
case 'rdate':
while( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE ))) {
$type = 'date-time';
if( isset( $content['params']['VALUE'] )) {
if( 'DATE' == $content['params']['VALUE'] )
$type = 'date';
elseif( 'PERIOD' == $content['params']['VALUE'] )
$type = 'period';
}
unset( $content['params']['VALUE'] );
_addXMLchild( $properties, $prop, $type, $content['value'], $content['params'] );
}
break;
case 'categories':
case 'comment':
case 'contact':
case 'description':
case 'related-to':
case 'resources':
while( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE ))) {
if(( 'related-to' != $prop ) && !isset( $content['params']['LANGUAGE'] )) {
if( $langComp )
$content['params']['LANGUAGE'] = $langComp;
elseif( $langCal )
$content['params']['LANGUAGE'] = $langCal;
}
_addXMLchild( $properties, $prop, 'text', $content['value'], $content['params'] );
}
break;
case 'x-prop':
while( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE )))
_addXMLchild( $properties, $content[0], 'unknown', $content[1]['value'], $content[1]['params'] );
break;
case 'created': // single occurence below, if set
case 'completed':
case 'dtstamp':
case 'last-modified':
$utcDate = TRUE;
case 'dtstart':
case 'dtend':
case 'due':
case 'recurrence-id':
if( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE ))) {
$type = ( isset( $content['params']['VALUE'] ) && ( 'DATE' == $content['params']['VALUE'] )) ? 'date' : 'date-time';
unset( $content['params']['VALUE'] );
if(( isset( $content['params']['TZID'] ) && empty( $content['params']['TZID'] )) || @is_null( $content['params']['TZID'] ))
unset( $content['params']['TZID'] );
_addXMLchild( $properties, $prop, $type, $content['value'], $content['params'] );
}
unset( $utcDate );
break;
case 'duration':
if( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE )))
_addXMLchild( $properties, $prop, 'duration', $content['value'], $content['params'] );
break;
case 'exrule':
case 'rrule':
while( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE )))
_addXMLchild( $properties, $prop, 'recur', $content['value'], $content['params'] );
break;
case 'class':
case 'location':
case 'status':
case 'summary':
case 'transp':
case 'tzid':
case 'uid':
if( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE ))) {
if((( 'location' == $prop ) || ( 'summary' == $prop )) && !isset( $content['params']['LANGUAGE'] )) {
if( $langComp )
$content['params']['LANGUAGE'] = $langComp;
elseif( $langCal )
$content['params']['LANGUAGE'] = $langCal;
}
_addXMLchild( $properties, $prop, 'text', $content['value'], $content['params'] );
}
break;
case 'geo':
if( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE )))
_addXMLchild( $properties, $prop, 'geo', $content['value'], $content['params'] );
break;
case 'organizer':
if( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE ))) {
if( isset( $content['params']['CN'] ) && !isset( $content['params']['LANGUAGE'] )) {
if( $langComp )
$content['params']['LANGUAGE'] = $langComp;
elseif( $langCal )
$content['params']['LANGUAGE'] = $langCal;
}
_addXMLchild( $properties, $prop, 'cal-address', $content['value'], $content['params'] );
}
break;
case 'percent-complete':
case 'priority':
case 'sequence':
if( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE )))
_addXMLchild( $properties, $prop, 'integer', $content['value'], $content['params'] );
break;
case 'tzurl':
case 'url':
if( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE )))
_addXMLchild( $properties, $prop, 'uri', $content['value'], $content['params'] );
break;
} // end switch( $prop )
} // end foreach( $props as $prop )
/** fix subComponent properties, if any */
while( FALSE !== ( $subcomp = $component->getComponent())) {
$subCompName = $subcomp->objName;
$child2 = $child->addChild( $subCompName );
$properties = $child2->addChild( 'properties' );
$langComp = $subcomp->getConfig( 'language' );
$subCompProps = $subcomp->getConfig( 'setPropertyNames' );
foreach( $subCompProps as $prop ) {
switch( strtolower( $prop )) {
case 'attach': // may occur multiple times, below
while( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE ))) {
$type = ( isset( $content['params']['VALUE'] ) && ( 'BINARY' == $content['params']['VALUE'] )) ? 'binary' : 'uri';
unset( $content['params']['VALUE'] );
_addXMLchild( $properties, $prop, $type, $content['value'], $content['params'] );
}
break;
case 'attendee':
while( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE ))) {
if( isset( $content['params']['CN'] ) && !isset( $content['params']['LANGUAGE'] )) {
if( $langComp )
$content['params']['LANGUAGE'] = $langComp;
elseif( $langCal )
$content['params']['LANGUAGE'] = $langCal;
}
_addXMLchild( $properties, $prop, 'cal-address', $content['value'], $content['params'] );
}
break;
case 'comment':
case 'tzname':
while( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE ))) {
if( !isset( $content['params']['LANGUAGE'] )) {
if( $langComp )
$content['params']['LANGUAGE'] = $langComp;
elseif( $langCal )
$content['params']['LANGUAGE'] = $langCal;
}
_addXMLchild( $properties, $prop, 'text', $content['value'], $content['params'] );
}
break;
case 'rdate':
while( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE ))) {
$type = 'date-time';
if( isset( $content['params']['VALUE'] )) {
if( 'DATE' == $content['params']['VALUE'] )
$type = 'date';
elseif( 'PERIOD' == $content['params']['VALUE'] )
$type = 'period';
}
unset( $content['params']['VALUE'] );
_addXMLchild( $properties, $prop, $type, $content['value'], $content['params'] );
}
break;
case 'x-prop':
while( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE )))
_addXMLchild( $properties, $content[0], 'unknown', $content[1]['value'], $content[1]['params'] );
break;
case 'action': // single occurence below, if set
case 'description':
case 'summary':
if( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE ))) {
if(( 'action' != $prop ) && !isset( $content['params']['LANGUAGE'] )) {
if( $langComp )
$content['params']['LANGUAGE'] = $langComp;
elseif( $langCal )
$content['params']['LANGUAGE'] = $langCal;
}
_addXMLchild( $properties, $prop, 'text', $content['value'], $content['params'] );
}
break;
case 'dtstart':
if( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE ))) {
unset( $content['value']['tz'], $content['params']['VALUE'] ); // always local time
_addXMLchild( $properties, $prop, 'date-time', $content['value'], $content['params'] );
}
break;
case 'duration':
if( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE )))
_addXMLchild( $properties, $prop, 'duration', $content['value'], $content['params'] );
break;
case 'repeat':
if( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE )))
_addXMLchild( $properties, $prop, 'integer', $content['value'], $content['params'] );
break;
case 'trigger':
if( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE ))) {
if( isset( $content['value']['year'] ) &&
isset( $content['value']['month'] ) &&
isset( $content['value']['day'] ))
$type = 'date-time';
else {
$type = 'duration';
if( !isset( $content['value']['relatedStart'] ) || ( TRUE !== $content['value']['relatedStart'] ))
$content['params']['RELATED'] = 'END';
}
_addXMLchild( $properties, $prop, $type, $content['value'], $content['params'] );
}
break;
case 'tzoffsetto':
case 'tzoffsetfrom':
if( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE )))
_addXMLchild( $properties, $prop, 'utc-offset', $content['value'], $content['params'] );
break;
case 'rrule':
while( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE )))
_addXMLchild( $properties, $prop, 'recur', $content['value'], $content['params'] );
break;
} // switch( $prop )
} // end foreach( $subCompProps as $prop )
} // end while( FALSE !== ( $subcomp = $component->getComponent()))
} // end while( FALSE !== ( $component = $calendar->getComponent()))
return $xml->asXML();
}
/**
* Add children to a SimpleXMLelement
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.18.10 - 2013-09-04
* @param object $parent reference to a SimpleXMLelement node
* @param string $name new element node name
* @param string $type content type, subelement(-s) name
* @param string $content new subelement content
* @param array $params new element 'attributes'
* @uses iCalUtilityFunctions::_duration2str()
* @uses iCalUtilityFunctions::_geo2str2()
* @uses iCalUtilityFunctions::$geoLatFmt
* @uses iCalUtilityFunctions::$geoLongFmt
* @return void
*/
function _addXMLchild( & $parent, $name, $type, $content, $params=array()) {
static $fmtYmd = '%04d-%02d-%02d';
static $fmtYmdHis = '%04d-%02d-%02dT%02d:%02d:%02d';
/** create new child node */
$name = strtolower( $name );
$child = $parent->addChild( $name );
if( !empty( $params )) {
$parameters = $child->addChild( 'parameters' );
foreach( $params as $param => $parVal ) {
if( 'VALUE' == $param )
continue;
$param = strtolower( $param );
if( 'x-' == substr( $param, 0, 2 )) {
$p1 = $parameters->addChild( $param );
$p2 = $p1->addChild( 'unknown', htmlspecialchars( $parVal ));
}
else {
$p1 = $parameters->addChild( $param );
switch( $param ) {
case 'altrep':
case 'dir': $ptype = 'uri'; break;
case 'delegated-from':
case 'delegated-to':
case 'member':
case 'sent-by': $ptype = 'cal-address'; break;
case 'rsvp': $ptype = 'boolean'; break ;
default: $ptype = 'text'; break;
}
if( is_array( $parVal )) {
foreach( $parVal as $pV )
$p2 = $p1->addChild( $ptype, htmlspecialchars( $pV ));
}
else
$p2 = $p1->addChild( $ptype, htmlspecialchars( $parVal ));
}
}
} // end if( !empty( $params ))
if(( empty( $content ) && ( '0' != $content )) || ( !is_array( $content) && ( '-' != substr( $content, 0, 1 ) && ( 0 > $content ))))
return;
/** store content */
switch( $type ) {
case 'binary':
$v = $child->addChild( $type, $content );
break;
case 'boolean':
break;
case 'cal-address':
$v = $child->addChild( $type, $content );
break;
case 'date':
if( array_key_exists( 'year', $content ))
$content = array( $content );
foreach( $content as $date ) {
$str = sprintf( $fmtYmd, (int) $date['year'], (int) $date['month'], (int) $date['day'] );
$v = $child->addChild( $type, $str );
}
break;
case 'date-time':
if( array_key_exists( 'year', $content ))
$content = array( $content );
foreach( $content as $dt ) {
if( !isset( $dt['hour'] )) $dt['hour'] = 0;
if( !isset( $dt['min'] )) $dt['min'] = 0;
if( !isset( $dt['sec'] )) $dt['sec'] = 0;
$str = sprintf( $fmtYmdHis, (int) $dt['year'], (int) $dt['month'], (int) $dt['day'], (int) $dt['hour'], (int) $dt['min'], (int) $dt['sec'] );
if( isset( $dt['tz'] ) && ( 'Z' == $dt['tz'] ))
$str .= 'Z';
$v = $child->addChild( $type, $str );
}
break;
case 'duration':
$output = (( 'trigger' == $name ) && ( FALSE !== $content['before'] )) ? '-' : '';
$v = $child->addChild( $type, $output.iCalUtilityFunctions::_duration2str( $content ) );
break;
case 'geo':
if( !empty( $content )) {
$v1 = $child->addChild( 'latitude', iCalUtilityFunctions::_geo2str2( $content['latitude'], iCalUtilityFunctions::$geoLatFmt ));
$v1 = $child->addChild( 'longitude', iCalUtilityFunctions::_geo2str2( $content['longitude'], iCalUtilityFunctions::$geoLongFmt ));
}
break;
case 'integer':
$v = $child->addChild( $type, (string) $content );
break;
case 'period':
if( !is_array( $content ))
break;
foreach( $content as $period ) {
$v1 = $child->addChild( $type );
$str = sprintf( $fmtYmdHis, (int) $period[0]['year'], (int) $period[0]['month'], (int) $period[0]['day'], (int) $period[0]['hour'], (int) $period[0]['min'], (int) $period[0]['sec'] );
if( isset( $period[0]['tz'] ) && ( 'Z' == $period[0]['tz'] ))
$str .= 'Z';
$v2 = $v1->addChild( 'start', $str );
if( array_key_exists( 'year', $period[1] )) {
$str = sprintf( $fmtYmdHis, (int) $period[1]['year'], (int) $period[1]['month'], (int) $period[1]['day'], (int) $period[1]['hour'], (int) $period[1]['min'], (int) $period[1]['sec'] );
if( isset($period[1]['tz'] ) && ( 'Z' == $period[1]['tz'] ))
$str .= 'Z';
$v2 = $v1->addChild( 'end', $str );
}
else
$v2 = $v1->addChild( 'duration', iCalUtilityFunctions::_duration2str( $period[1] ));
}
break;
case 'recur':
$content = array_change_key_case( $content );
foreach( $content as $rulelabel => $rulevalue ) {
switch( $rulelabel ) {
case 'until':
if( isset( $rulevalue['hour'] ))
$str = sprintf( $fmtYmdHis, (int) $rulevalue['year'], (int) $rulevalue['month'], (int) $rulevalue['day'], (int) $rulevalue['hour'], (int) $rulevalue['min'], (int) $rulevalue['sec'] ).'Z';
else
$str = sprintf( $fmtYmd, (int) $rulevalue['year'], (int) $rulevalue['month'], (int) $rulevalue['day'] );
$v = $child->addChild( $rulelabel, $str );
break;
case 'bysecond':
case 'byminute':
case 'byhour':
case 'bymonthday':
case 'byyearday':
case 'byweekno':
case 'bymonth':
case 'bysetpos': {
if( is_array( $rulevalue )) {
foreach( $rulevalue as $vix => $valuePart )
$v = $child->addChild( $rulelabel, $valuePart );
}
else
$v = $child->addChild( $rulelabel, $rulevalue );
break;
}
case 'byday': {
if( isset( $rulevalue['DAY'] )) {
$str = ( isset( $rulevalue[0] )) ? $rulevalue[0] : '';
$str .= $rulevalue['DAY'];
$p = $child->addChild( $rulelabel, $str );
}
else {
foreach( $rulevalue as $valuePart ) {
if( isset( $valuePart['DAY'] )) {
$str = ( isset( $valuePart[0] )) ? $valuePart[0] : '';
$str .= $valuePart['DAY'];
$p = $child->addChild( $rulelabel, $str );
}
else
$p = $child->addChild( $rulelabel, $valuePart );
}
}
break;
}
case 'freq':
case 'count':
case 'interval':
case 'wkst':
default:
$p = $child->addChild( $rulelabel, $rulevalue );
break;
} // end switch( $rulelabel )
} // end foreach( $content as $rulelabel => $rulevalue )
break;
case 'rstatus':
$v = $child->addChild( 'code', number_format( (float) $content['statcode'], 2, '.', ''));
$v = $child->addChild( 'description', htmlspecialchars( $content['text'] ));
if( isset( $content['extdata'] ))
$v = $child->addChild( 'data', htmlspecialchars( $content['extdata'] ));
break;
case 'text':
if( !is_array( $content ))
$content = array( $content );
foreach( $content as $part )
$v = $child->addChild( $type, htmlspecialchars( $part ));
break;
case 'time':
break;
case 'uri':
$v = $child->addChild( $type, $content );
break;
case 'utc-offset':
if( in_array( substr( $content, 0, 1 ), array( '-', '+' ))) {
$str = substr( $content, 0, 1 );
$content = substr( $content, 1 );
}
else
$str = '+';
$str .= substr( $content, 0, 2 ).':'.substr( $content, 2, 2 );
if( 4 < strlen( $content ))
$str .= ':'.substr( $content, 4 );
$v = $child->addChild( $type, $str );
break;
case 'unknown':
default:
if( is_array( $content ))
$content = implode( '', $content );
$v = $child->addChild( 'unknown', htmlspecialchars( $content ));
break;
}
}
/**
* parse xml file into iCalcreator instance
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.16.22 - 2013-06-18
* @param string $xmlfile
* @param array $iCalcfg iCalcreator config array (opt)
* @return mixediCalcreator instance or FALSE on error
*/
function XMLfile2iCal( $xmlfile, $iCalcfg=array()) {
if( FALSE === ( $xmlstr = file_get_contents( $xmlfile )))
return FALSE;
return xml2iCal( $xmlstr, $iCalcfg );
}
/**
* parse xml string into iCalcreator instance, alias of XML2iCal
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.16.22 - 2013-06-18
* @param string $xmlstr
* @param array $iCalcfg iCalcreator config array (opt)
* @return mixed iCalcreator instance or FALSE on error
*/
function XMLstr2iCal( $xmlstr, $iCalcfg=array()) {
return XML2iCal( $xmlstr, $iCalcfg);
}
/**
* parse xml string into iCalcreator instance
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.16.22 - 2013-06-20
* @param string $xmlstr
* @param array $iCalcfg iCalcreator config array (opt)
* @uses vcalendar::vcalendar()
* @uses XMLgetComps()
* @return mixed iCalcreator instance or FALSE on error
*/
function XML2iCal( $xmlstr, $iCalcfg=array()) {
$xmlstr = str_replace( array( "\r\n", "\n\r", "\n", "\r" ), '', $xmlstr );
$xml = XMLgetTagContent1( $xmlstr, 'vcalendar', $endIx );
$iCal = new vcalendar( $iCalcfg );
XMLgetComps( $iCal, $xmlstr );
unset( $xmlstr );
return $iCal;
}
/**
* parse XML string into iCalcreator components
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.21.11 - 2015-03-21
* @param object $iCal iCalcreator vcalendar or component object instance
* @param string $xml
* @uses iCalUtilityFunctions::$allComps
* @uses XMLgetTagContent1()
* @uses XMLgetProps()
* @uses XMLgetTagContent2()
* @uses vcalendar::newComponent()
* @uses iCalUtilityFunctions::$allComps
* @uses XMLgetComps()
* @return object
*/
function XMLgetComps( $iCal, $xml ) {
$sx = 0;
while(( FALSE !== substr( $xml, ( $sx + 11 ), 1 )) &&
( '<properties>' != substr( $xml, $sx, 12 )) && ( '<components>' != substr( $xml, $sx, 12 )))
$sx += 1;
if( FALSE === substr( $xml, ( $sx + 11 ), 1 ))
return FALSE;
if( '<properties>' == substr( $xml, $sx, 12 )) {
$xml2 = XMLgetTagContent1( $xml, 'properties', $endIx );
XMLgetProps( $iCal, $xml2 );
$xml = substr( $xml, $endIx );
}
if( '<components>' == substr( $xml, 0, 12 ))
$xml = XMLgetTagContent1( $xml, 'components', $endIx );
while( ! empty( $xml )) {
$xml2 = XMLgetTagContent2( $xml, $tagName, $endIx );
if( in_array( strtolower( $tagName ), iCalUtilityFunctions::$allComps ) &&
( FALSE !== ( $subComp = $iCal->newComponent( $tagName ))))
XMLgetComps( $subComp, $xml2 );
$xml = substr( $xml, $endIx);
}
unset( $xml );
return $iCal;
}
/**
* parse XML into iCalcreator properties
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.21.11 - 2015-03-21
* @param array $iCal iCalcreator calendar/component instance
* @param string $xml
* @uses XMLgetTagContent2()
* @uses vcalendar::setProperty()
* @uses calendarComponent::setproperty()
* @uses XMLgetTagContent1()
* @uses vcalendar::setProperty()
* @return void
*/
function XMLgetProps( $iCal, $xml) {
while( ! empty( $xml )) {
$xml2 = XMLgetTagContent2( $xml, $propName, $endIx );
$propName = strtoupper( $propName );
if( empty( $xml2 ) && ( '0' != $xml2 )) {
$iCal->setProperty( $propName );
$xml = substr( $xml, $endIx);
continue;
}
$params = array();
if( '<parameters/>' == substr( $xml2, 0, 13 ))
$xml2 = substr( $xml2, 13 );
elseif( '<parameters>' == substr( $xml2, 0, 12 )) {
$xml3 = XMLgetTagContent1( $xml2, 'parameters', $endIx2 );
while( ! empty( $xml3 )) {
$xml4 = XMLgetTagContent2( $xml3, $paramKey, $endIx3 );
$pType = FALSE; // skip parameter valueType
$paramKey = strtoupper( $paramKey );
static $mParams = array( 'DELEGATED-FROM', 'DELEGATED-TO', 'MEMBER' );
if( in_array( $paramKey, $mParams )) {
while( ! empty( $xml4 )) {
if( ! isset( $params[$paramKey] ))
$params[$paramKey] = array( XMLgetTagContent1( $xml4, 'cal-address', $endIx4 ));
else
$params[$paramKey][] = XMLgetTagContent1( $xml4, 'cal-address', $endIx4 );
$xml4 = substr( $xml4, $endIx4 );
}
}
else {
if( ! isset( $params[$paramKey] ))
$params[$paramKey] = html_entity_decode( XMLgetTagContent2( $xml4, $pType, $endIx4 ));
else
$params[$paramKey] .= ','.html_entity_decode( XMLgetTagContent2( $xml4, $pType, $endIx4 ));
}
$xml3 = substr( $xml3, $endIx3 );
}
$xml2 = substr( $xml2, $endIx2 );
} // if( '<parameters>' == substr( $xml2, 0, 12 ))
$valueType = FALSE;
$value = ( ! empty( $xml2 ) || ( '0' == $xml2 )) ? XMLgetTagContent2( $xml2, $valueType, $endIx3 ) : '';
switch( $propName ) {
case 'CATEGORIES':
case 'RESOURCES':
$tValue = array();
while( ! empty( $xml2 )) {
$tValue[] = html_entity_decode( XMLgetTagContent2( $xml2, $valueType, $endIx4 ));
$xml2 = substr( $xml2, $endIx4 );
}
$value = $tValue;
break;
case 'EXDATE': // multiple single-date(-times) may exist
case 'RDATE':
if( 'period' != $valueType ) {
if( 'date' == $valueType )
$params['VALUE'] = 'DATE';
$t = array();
while( ! empty( $xml2 ) && ( '<date' == substr( $xml2, 0, 5 ))) {
$t[] = XMLgetTagContent2( $xml2, $pType, $endIx4 );
$xml2 = substr( $xml2, $endIx4 );
}
$value = $t;
break;
}
case 'FREEBUSY':
if( 'RDATE' == $propName )
$params['VALUE'] = 'PERIOD';
$value = array();
while( ! empty( $xml2 ) && ( '<period>' == substr( $xml2, 0, 8 ))) {
$xml3 = XMLgetTagContent1( $xml2, 'period', $endIx4 ); // period
$t = array();
while( ! empty( $xml3 )) {
$t[] = XMLgetTagContent2( $xml3, $pType, $endIx5 ); // start - end/duration
$xml3 = substr( $xml3, $endIx5 );
}
$value[] = $t;
$xml2 = substr( $xml2, $endIx4 );
}
break;
case 'TZOFFSETTO':
case 'TZOFFSETFROM':
$value = str_replace( ':', '', $value );
break;
case 'GEO':
$tValue = array( 'latitude' => $value );
$tValue['longitude'] = XMLgetTagContent1( substr( $xml2, $endIx3 ), 'longitude', $endIx3 );
$value = $tValue;
break;
case 'EXRULE':
case 'RRULE':
$tValue = array( $valueType => $value );
$xml2 = substr( $xml2, $endIx3 );
$valueType = FALSE;
while( ! empty( $xml2 )) {
$t = XMLgetTagContent2( $xml2, $valueType, $endIx4 );
switch( $valueType ) {
case 'freq':
case 'count':
case 'until':
case 'interval':
case 'wkst':
$tValue[$valueType] = $t;
break;
case 'byday':
if( 2 == strlen( $t ))
$tValue[$valueType][] = array( 'DAY' => $t );
else {
$day = substr( $t, -2 );
$key = substr( $t, 0, ( strlen( $t ) - 2 ));
$tValue[$valueType][] = array( $key, 'DAY' => $day );
}
break;
default:
$tValue[$valueType][] = $t;
}
$xml2 = substr( $xml2, $endIx4 );
}
$value = $tValue;
break;
case 'REQUEST-STATUS':
$tValue = array();
while( ! empty( $xml2 )) {
$t = html_entity_decode( XMLgetTagContent2( $xml2, $valueType, $endIx4 ));
$tValue[$valueType] = $t;
$xml2 = substr( $xml2, $endIx4 );
}
if( ! empty( $tValue ))
$value = $tValue;
else
$value = array( 'code' => null, 'description' => null );
break;
default:
switch( $valueType ) {
case 'binary': $params['VALUE'] = 'BINARY'; break;
case 'date': $params['VALUE'] = 'DATE'; break;
case 'date-time': $params['VALUE'] = 'DATE-TIME'; break;
case 'text':
case 'unknown': $value = html_entity_decode( $value ); break;
}
break;
} // end switch( $propName )
if( 'FREEBUSY' == $propName ) {
$fbtype = $params['FBTYPE'];
unset( $params['FBTYPE'] );
$iCal->setProperty( $propName, $fbtype, $value, $params );
}
elseif( 'GEO' == $propName )
$iCal->setProperty( $propName, $value['latitude'], $value['longitude'], $params );
elseif( 'REQUEST-STATUS' == $propName ) {
if( !isset( $value['data'] ))
$value['data'] = FALSE;
$iCal->setProperty( $propName, $value['code'], $value['description'], $value['data'], $params );
}
else {
if( empty( $value ) && ( is_array( $value ) || ( '0' > $value )))
$value = '';
$iCal->setProperty( $propName, $value, $params );
}
$xml = substr( $xml, $endIx);
} // end while( ! empty( $xml ))
}
/**
* fetch a specific XML tag content
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.16.22 - 2013-06-20
* @param string $xml
* @param string $tagName
* @param int $endIx
* @return mixed
*/
function XMLgetTagContent1( $xml, $tagName, & $endIx=0 ) {
$strlen = strlen( $tagName );
$sx1 = 0;
while( FALSE !== substr( $xml, $sx1, 1 )) {
if(( FALSE !== substr( $xml, ( $sx1 + $strlen + 1 ), 1 )) &&
( strtolower( "<$tagName>" ) == strtolower( substr( $xml, $sx1, ( $strlen + 2 )))))
break;
if(( FALSE !== substr( $xml, ( $sx1 + $strlen + 3 ), 1 )) &&
( strtolower( "<$tagName />" ) == strtolower( substr( $xml, $sx1, ( $strlen + 4 ))))) { // empty tag
$endIx = $strlen + 5;
return '';
}
if(( FALSE !== substr( $xml, ( $sx1 + $strlen + 2 ), 1 )) &&
( strtolower( "<$tagName/>" ) == strtolower( substr( $xml, $sx1, ( $strlen + 3 ))))) { // empty tag
$endIx = $strlen + 4;
return '';
}
$sx1 += 1;
}
if( FALSE === substr( $xml, $sx1, 1 )) {
$endIx = ( empty( $sx )) ? 0 : $sx - 1;
return '';
}
if( FALSE === ( $pos = stripos( $xml, "</$tagName>" ))) { // missing end tag??
$endIx = strlen( $xml ) + 1;
return '';
}
$endIx = $pos + $strlen + 3;
return substr( $xml, ( $sx1 + $strlen + 2 ), ( $pos - $sx1 - 2 - $strlen ));
}
/**
* fetch next (unknown) XML tagname AND content
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.16.22 - 2013-06-20
* @param string $xml
* @param string $tagName
* @param int $endIx
* @return mixed
*/
function XMLgetTagContent2( $xml, & $tagName, & $endIx ) {
$endIx = strlen( $xml ) + 1; // just in case.. .
$sx1 = 0;
while( FALSE !== substr( $xml, $sx1, 1 )) {
if( '<' == substr( $xml, $sx1, 1 )) {
if(( FALSE !== substr( $xml, ( $sx1 + 3 ), 1 )) && ( '<!--' == substr( $xml, $sx1, 4 ))) // skip comment
$sx1 += 1;
else
break; // tagname start here
}
else
$sx1 += 1;
}
$sx2 = $sx1;
while( FALSE !== substr( $xml, $sx2 )) {
if(( FALSE !== substr( $xml, ( $sx2 + 1 ), 1 )) && ( '/>' == substr( $xml, $sx2, 2 ))) { // empty tag
$tagName = trim( substr( $xml, ( $sx1 + 1 ), ( $sx2 - $sx1 - 1 )));
$endIx = $sx2 + 2;
return '';
}
if( '>' == substr( $xml, $sx2, 1 )) // tagname ends here
break;
$sx2 += 1;
}
$tagName = substr( $xml, ( $sx1 + 1 ), ( $sx2 - $sx1 - 1 ));
$endIx = $sx2 + 1;
if( FALSE === substr( $xml, $sx2, 1 )) {
return '';
}
$strlen = strlen( $tagName );
if(( 'duration' == $tagName ) &&
( FALSE !== ( $pos1 = stripos( $xml, "<duration>", $sx1+1 ))) &&
( FALSE !== ( $pos2 = stripos( $xml, "</duration>", $pos1+1 ))) &&
( FALSE !== ( $pos3 = stripos( $xml, "</duration>", $pos2+1 ))) &&
( $pos1 < $pos2 ) && ( $pos2 < $pos3 ))
$pos = $pos3;
elseif( FALSE === ( $pos = stripos( $xml, "</$tagName>", $sx2 )))
return '';
$endIx = $pos + $strlen + 3;
return substr( $xml, ( $sx1 + $strlen + 2 ), ( $pos - $strlen - 2 ));
}

@ -0,0 +1,292 @@
<?php
/*********************************************************************************/
/* Additional functions to use with vtimezone components */
/*********************************************************************************/
/**
* For use with
* iCalcreator (kigkonsult.se/iCalcreator/index.php)
* copyright (c) 2011 Yitzchok Lavi
* icalcreator@onebigsystem.com
* @version 2.22
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/**
* Additional functions to use with vtimezone components
*
* Before calling the functions, set time zone 'GMT' ('date_default_timezone_set')!
*
* @author Yitzchok Lavi <icalcreator@onebigsystem.com>
* adjusted for iCalcreator Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @version 1.0.2 - 2011-02-24
*
*/
/**
* Returns array with the offset information from UTC for a (UTC) datetime/timestamp in the
* timezone, according to the VTIMEZONE information in the input array.
*
* @param array $timezonesarray output from function getTimezonesAsDateArrays (below)
* @param string $tzid time zone identifier
* @param mixed $timestamp timestamp or a UTC datetime (in array format)
* @return array time zone data with keys for 'offsetHis', 'offsetSec' and 'tzname'
*
*/
function getTzOffsetForDate($timezonesarray, $tzid, $timestamp) {
if( is_array( $timestamp )) {
//$disp = sprintf( '%04d%02d%02d %02d%02d%02d', $timestamp['year'], $timestamp['month'], $timestamp['day'], $timestamp['hour'], $timestamp['min'], $timestamp['sec'] ); // test ###
$timestamp = gmmktime(
$timestamp['hour'],
$timestamp['min'],
$timestamp['sec'],
$timestamp['month'],
$timestamp['day'],
$timestamp['year']
) ;
}
$tzoffset = array();
// something to return if all goes wrong (such as if $tzid doesn't find us an array of dates)
$tzoffset['offsetHis'] = '+0000';
$tzoffset['offsetSec'] = 0;
$tzoffset['tzname'] = '?';
if( !isset( $timezonesarray[$tzid] ))
return $tzoffset;
$tzdatearray = $timezonesarray[$tzid];
if ( is_array($tzdatearray) ) {
sort($tzdatearray); // just in case
if ( $timestamp < $tzdatearray[0]['timestamp'] ) {
// our date is before the first change
$tzoffset['offsetHis'] = $tzdatearray[0]['tzbefore']['offsetHis'] ;
$tzoffset['offsetSec'] = $tzdatearray[0]['tzbefore']['offsetSec'] ;
$tzoffset['tzname'] = $tzdatearray[0]['tzbefore']['offsetHis'] ; // we don't know the tzname in this case
} elseif ( $timestamp >= $tzdatearray[count($tzdatearray)-1]['timestamp'] ) {
// our date is after the last change (we do this so our scan can stop at the last record but one)
$tzoffset['offsetHis'] = $tzdatearray[count($tzdatearray)-1]['tzafter']['offsetHis'] ;
$tzoffset['offsetSec'] = $tzdatearray[count($tzdatearray)-1]['tzafter']['offsetSec'] ;
$tzoffset['tzname'] = $tzdatearray[count($tzdatearray)-1]['tzafter']['tzname'] ;
} else {
// our date somewhere in between
// loop through the list of dates and stop at the one where the timestamp is before our date and the next one is after it
// we don't include the last date in our loop as there isn't one after it to check
for ( $i = 0 ; $i <= count($tzdatearray)-2 ; $i++ ) {
if(( $timestamp >= $tzdatearray[$i]['timestamp'] ) && ( $timestamp < $tzdatearray[$i+1]['timestamp'] )) {
$tzoffset['offsetHis'] = $tzdatearray[$i]['tzafter']['offsetHis'] ;
$tzoffset['offsetSec'] = $tzdatearray[$i]['tzafter']['offsetSec'] ;
$tzoffset['tzname'] = $tzdatearray[$i]['tzafter']['tzname'] ;
break;
}
}
}
}
return $tzoffset;
}
/**
* Returns an array containing all the timezone data in the vcalendar object
*
* @param object $vcalendar iCalcreator calendar instance
* @return array time zone transition timestamp, array before(offsetHis, offsetSec), array after(offsetHis, offsetSec, tzname)
* based on the timezone data in the vcalendar object
*
*/
function getTimezonesAsDateArrays($vcalendar) {
$timezonedata = array();
while( $vtz = $vcalendar->getComponent( 'vtimezone' )) {
$tzid = $vtz->getProperty('tzid');
$alltzdates = array();
while ( $vtzc = $vtz->getComponent( 'standard' )) {
$newtzdates = expandTimezoneDates($vtzc);
$alltzdates = array_merge($alltzdates, $newtzdates);
}
while ( $vtzc = $vtz->getComponent( 'daylight' )) {
$newtzdates = expandTimezoneDates($vtzc);
$alltzdates = array_merge($alltzdates, $newtzdates);
}
sort($alltzdates);
$timezonedata[$tzid] = $alltzdates;
}
return $timezonedata;
}
/**
* Returns an array containing time zone data from vtimezone standard/daylight instances
*
* @param object $vtzc an iCalcreator calendar standard/daylight instance
* @return array time zone data; array before(offsetHis, offsetSec), array after(offsetHis, offsetSec, tzname)
*
*/
function expandTimezoneDates($vtzc) {
$tzdates = array();
// prepare time zone "description" to attach to each change
$tzbefore = array();
$tzbefore['offsetHis'] = $vtzc->getProperty('tzoffsetfrom') ;
$tzbefore['offsetSec'] = iCalUtilityFunctions::_tz2offset($tzbefore['offsetHis']);
if(( '-' != substr( (string) $tzbefore['offsetSec'], 0, 1 )) && ( '+' != substr( (string) $tzbefore['offsetSec'], 0, 1 )))
$tzbefore['offsetSec'] = '+'.$tzbefore['offsetSec'];
$tzafter = array();
$tzafter['offsetHis'] = $vtzc->getProperty('tzoffsetto') ;
$tzafter['offsetSec'] = iCalUtilityFunctions::_tz2offset($tzafter['offsetHis']);
if(( '-' != substr( (string) $tzafter['offsetSec'], 0, 1 )) && ( '+' != substr( (string) $tzafter['offsetSec'], 0, 1 )))
$tzafter['offsetSec'] = '+'.$tzafter['offsetSec'];
if( FALSE === ( $tzafter['tzname'] = $vtzc->getProperty('tzname')))
$tzafter['tzname'] = $tzafter['offsetHis'];
// find out where to start from
$dtstart = $vtzc->getProperty('dtstart');
$dtstarttimestamp = mktime(
$dtstart['hour'],
$dtstart['min'],
$dtstart['sec'],
$dtstart['month'],
$dtstart['day'],
$dtstart['year']
) ;
if( !isset( $dtstart['unparsedtext'] )) // ??
$dtstart['unparsedtext'] = sprintf( '%04d%02d%02dT%02d%02d%02d', $dtstart['year'], $dtstart['month'], $dtstart['day'], $dtstart['hour'], $dtstart['min'], $dtstart['sec'] );
if ( $dtstarttimestamp == 0 ) {
// it seems that the dtstart string may not have parsed correctly
// let's set a timestamp starting from 1902, using the time part of the original string
// so that the time will change at the right time of day
// at worst we'll get midnight again
$origdtstartsplit = explode('T',$dtstart['unparsedtext']) ;
$dtstarttimestamp = strtotime("19020101",0);
$dtstarttimestamp = strtotime($origdtstartsplit[1],$dtstarttimestamp);
}
// the date (in dtstart and opt RDATE/RRULE) is ALWAYS LOCAL (not utc!!), adjust from 'utc' to 'local' timestamp
$diff = -1 * $tzbefore['offsetSec'];
$dtstarttimestamp += $diff;
// add this (start) change to the array of changes
$tzdates[] = array(
'timestamp' => $dtstarttimestamp,
'tzbefore' => $tzbefore,
'tzafter' => $tzafter
);
$datearray = getdate($dtstarttimestamp);
// save original array to use time parts, because strtotime (used below) apparently loses the time
$changetime = $datearray ;
// generate dates according to an RRULE line
$rrule = $vtzc->getProperty('rrule') ;
if ( is_array($rrule) ) {
if ( $rrule['FREQ'] == 'YEARLY' ) {
// calculate transition dates starting from DTSTART
$offsetchangetimestamp = $dtstarttimestamp;
// calculate transition dates until 10 years in the future
$stoptimestamp = strtotime("+10 year",time());
// if UNTIL is set, calculate until then (however far ahead)
if ( isset( $rrule['UNTIL'] ) && ( $rrule['UNTIL'] != '' )) {
$stoptimestamp = mktime(
$rrule['UNTIL']['hour'],
$rrule['UNTIL']['min'],
$rrule['UNTIL']['sec'],
$rrule['UNTIL']['month'],
$rrule['UNTIL']['day'],
$rrule['UNTIL']['year']
) ;
}
$count = 0 ;
$stopcount = isset( $rrule['COUNT'] ) ? $rrule['COUNT'] : 0 ;
$daynames = array(
'SU' => 'Sunday',
'MO' => 'Monday',
'TU' => 'Tuesday',
'WE' => 'Wednesday',
'TH' => 'Thursday',
'FR' => 'Friday',
'SA' => 'Saturday'
);
// repeat so long as we're between DTSTART and UNTIL, or we haven't prepared COUNT dates
while ( $offsetchangetimestamp < $stoptimestamp && ( $stopcount == 0 || $count < $stopcount ) ) {
// break up the timestamp into its parts
$datearray = getdate($offsetchangetimestamp);
if ( isset( $rrule['BYMONTH'] ) && ( $rrule['BYMONTH'] != 0 )) {
// set the month
$datearray['mon'] = $rrule['BYMONTH'] ;
}
if ( isset( $rrule['BYMONTHDAY'] ) && ( $rrule['BYMONTHDAY'] != 0 )) {
// set specific day of month
$datearray['mday'] = $rrule['BYMONTHDAY'];
} elseif ( is_array($rrule['BYDAY']) ) {
// find the Xth WKDAY in the month
// the starting point for this process is the first of the month set above
$datearray['mday'] = 1 ;
// turn $datearray as it is now back into a timestamp
$offsetchangetimestamp = mktime(
$datearray['hours'],
$datearray['minutes'],
$datearray['seconds'],
$datearray['mon'],
$datearray['mday'],
$datearray['year']
);
if ($rrule['BYDAY'][0] > 0) {
// to find Xth WKDAY in month, we find last WKDAY in month before
// we do that by finding first WKDAY in this month and going back one week
// then we add X weeks (below)
$offsetchangetimestamp = strtotime($daynames[$rrule['BYDAY']['DAY']],$offsetchangetimestamp);
$offsetchangetimestamp = strtotime("-1 week",$offsetchangetimestamp);
} else {
// to find Xth WKDAY before the end of the month, we find the first WKDAY in the following month
// we do that by going forward one month and going to WKDAY there
// then we subtract X weeks (below)
$offsetchangetimestamp = strtotime("+1 month",$offsetchangetimestamp);
$offsetchangetimestamp = strtotime($daynames[$rrule['BYDAY']['DAY']],$offsetchangetimestamp);
}
// now move forward or back the appropriate number of weeks, into the month we want
$offsetchangetimestamp = strtotime($rrule['BYDAY'][0] . " week",$offsetchangetimestamp);
$datearray = getdate($offsetchangetimestamp);
}
// convert the date parts back into a timestamp, setting the time parts according to the
// original time data which we stored
$offsetchangetimestamp = mktime(
$changetime['hours'],
$changetime['minutes'],
$changetime['seconds'] + $diff,
$datearray['mon'],
$datearray['mday'],
$datearray['year']
);
// add this change to the array of changes
$tzdates[] = array(
'timestamp' => $offsetchangetimestamp,
'tzbefore' => $tzbefore,
'tzafter' => $tzafter
);
// update counters (timestamp and count)
$offsetchangetimestamp = strtotime("+" . (( isset( $rrule['INTERVAL'] ) && ( $rrule['INTERVAL'] != 0 )) ? $rrule['INTERVAL'] : 1 ) . " year",$offsetchangetimestamp);
$count += 1 ;
}
}
}
// generate dates according to RDATE lines
while ($rdates = $vtzc->getProperty('rdate')) {
if ( is_array($rdates) ) {
foreach ( $rdates as $rdate ) {
// convert the explicit change date to a timestamp
$offsetchangetimestamp = mktime(
$rdate['hour'],
$rdate['min'],
$rdate['sec'] + $diff,
$rdate['month'],
$rdate['day'],
$rdate['year']
) ;
// add this change to the array of changes
$tzdates[] = array(
'timestamp' => $offsetchangetimestamp,
'tzbefore' => $tzbefore,
'tzafter' => $tzafter
);
}
}
}
return $tzdates;
}

@ -0,0 +1,166 @@
<?php
/*********************************************************************************/
/**
*
* iCalcreator, a PHP rfc2445/rfc5545 solution.
*
* @copyright Copyright (c) 2007-2015 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* @link http://kigkonsult.se/iCalcreator/index.php
* @license http://kigkonsult.se/downloads/dl.php?f=LGPL
* @package iCalcreator
* @version 2.22
*/
/**
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*********************************************************************************/
/* iCalcreator vCard helper functions */
/*********************************************************************************/
/**
* convert single ATTENDEE, CONTACT or ORGANIZER (in email format) to vCard
* returns vCard/TRUE or if directory (if set) or file write is unvalid, FALSE
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.12.2 - 2012-07-11
* @param string $email
* @param string $version vCard version (default 2.1)
* @param string $directory where to save vCards (default FALSE)
* @param string $ext vCard file extension (default 'vcf')
* @uses ICALCREATOR_VERSION
* @return mixed
*/
function iCal2vCard( $email, $version='2.1', $directory=FALSE, $ext='vcf' ) {
if( FALSE === ( $pos = strpos( $email, '@' )))
return FALSE;
if( $directory ) {
if( DIRECTORY_SEPARATOR != substr( $directory, ( 0 - strlen( DIRECTORY_SEPARATOR ))))
$directory .= DIRECTORY_SEPARATOR;
if( !is_dir( $directory ) || !is_writable( $directory ))
return FALSE;
}
/* prepare vCard */
$email = str_replace( 'MAILTO:', '', $email );
$name = $person = substr( $email, 0, $pos );
if( ctype_upper( $name ) || ctype_lower( $name ))
$name = array( $name );
else {
if( FALSE !== ( $pos = strpos( $name, '.' ))) {
$name = explode( '.', $name );
foreach( $name as $k => $part )
$name[$k] = ucfirst( $part );
}
else { // split camelCase
$chars = $name;
$name = array( $chars[0] );
$k = 0;
$x = 1;
while( FALSE !== ( $char = substr( $chars, $x, 1 ))) {
if( ctype_upper( $char )) {
$k += 1;
$name[$k] = '';
}
$name[$k] .= $char;
$x++;
}
}
}
$nl = "\r\n";
$FN = 'FN:'.implode( ' ', $name ).$nl;
$name = array_reverse( $name );
$N = 'N:'.array_shift( $name );
$scCnt = 0;
while( NULL != ( $part = array_shift( $name ))) {
if(( '4.0' != $version ) || ( 4 > $scCnt ))
$scCnt += 1;
$N .= ';'.$part;
}
while(( '4.0' == $version ) && ( 4 > $scCnt )) {
$N .= ';';
$scCnt += 1;
}
$N .= $nl;
$EMAIL = 'EMAIL:'.$email.$nl;
/* create vCard */
$vCard = 'BEGIN:VCARD'.$nl;
$vCard .= "VERSION:$version$nl";
$vCard .= 'PRODID:-//kigkonsult.se '.ICALCREATOR_VERSION."//$nl";
$vCard .= $N;
$vCard .= $FN;
$vCard .= $EMAIL;
$vCard .= 'REV:'.gmdate( 'Ymd\THis\Z' ).$nl;
$vCard .= 'END:VCARD'.$nl;
/* save each vCard as (unique) single file */
if( $directory ) {
$fname = $directory.preg_replace( '/[^a-z0-9.]/i', '', $email );
$cnt = 1;
$dbl = '';
while( is_file ( $fname.$dbl.'.'.$ext )) {
$cnt += 1;
$dbl = "_$cnt";
}
if( FALSE === file_put_contents( $fname, $fname.$dbl.'.'.$ext ))
return FALSE;
return TRUE;
}
/* return vCard */
else
return $vCard;
}
/**
* convert ATTENDEEs, CONTACTs and ORGANIZERs (in email format) to vCards
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.12.2 - 2012-05-07
* @param object $calendar iCalcreator vcalendar instance reference
* @param string $version vCard version (default 2.1)
* @param string $directory where to save vCards (default FALSE)
* @param string $ext vCard file extension (default 'vcf')
* @uses vcalendar::getProperty()
* @return mixed
*/
function iCal2vCards( & $calendar, $version='2.1', $directory=FALSE, $ext='vcf' ) {
$hits = array();
$vCardP = array( 'ATTENDEE', 'CONTACT', 'ORGANIZER' );
foreach( $vCardP as $prop ) {
$hits2 = $calendar->getProperty( $prop );
foreach( $hits2 as $propValue => $occCnt ) {
if( FALSE === ( $pos = strpos( $propValue, '@' )))
continue;
$propValue = str_replace( 'MAILTO:', '', $propValue );
if( isset( $hits[$propValue] ))
$hits[$propValue] += $occCnt;
else
$hits[$propValue] = $occCnt;
}
}
if( empty( $hits ))
return FALSE;
ksort( $hits );
$output = '';
foreach( $hits as $email => $skip ) {
$res = iCal2vCard( $email, $version, $directory, $ext );
if( $directory && !$res )
return FALSE;
elseif( !$res )
return $res;
else
$output .= $res;
}
if( $directory )
return TRUE;
if( !empty( $output ))
return $output;
return FALSE;
}

@ -0,0 +1,427 @@
<?php
/*********************************************************************************/
/**
*
* iCalcreator, a PHP rfc2445/rfc5545 solution.
*
* @copyright Copyright (c) 2007-2015 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* @link http://kigkonsult.se/iCalcreator/index.php
* @license http://kigkonsult.se/downloads/dl.php?f=LGPL
* @package iCalcreator
* @version 2.22
*/
/**
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*********************************************************************************/
/**
* iCalcreator base class
*
* properties and functions shared by vcalendar and calendarComponents
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.21.11 - 2015-03-31
*/
abstract class iCalBase {
/**
* @var array component property X-property value
* @access protected
*/
protected $xprop;
/** @var array container for sub-components */
public $components;
/** @var array $unparsed calendar/components in 'raw' text... */
public $unparsed;
/**
* @var bool $allowEmpty config variable
* @var string $language config variable
* @var string $nl config variable
* @var string $unique_id config variable
* @var string $format config variable
* @var string $dtzid config variable
* @access protected
*/
protected $allowEmpty;
protected $language;
protected $nl;
protected $unique_id;
protected $format;
protected $dtzid;
/**
* @var string $componentStart1 valendar/component internal variable
* @var string $componentStart2 valendar/component internal variable
* @var string $componentEnd1 valendar/component internal variable
* @var string $componentEnd2 valendar/component internal variable
* @var string $elementStart1 valendar/component internal variable
* @var string $elementStart2 valendar/component internal variable
* @var string $elementEnd1 valendar/component internal variable
* @var string $elementEnd2 valendar/component internal variable
* @var string $intAttrDelimiter valendar/component internal variable
* @var string $attributeDelimiter valendar/component internal variable
* @var string $valueInit valendar/component internal variable
* @access protected
*/
protected $componentStart1;
protected $componentStart2;
protected $componentEnd1;
protected $componentEnd2;
protected $elementStart1;
protected $elementStart2;
protected $elementEnd1;
protected $elementEnd2;
protected $intAttrDelimiter;
protected $attributeDelimiter;
protected $valueInit;
/**
* @var array $xcaldecl xCal declaration container
* @access protected
*/
protected $xcaldecl;
/**
* Property Name: x-prop
*/
/**
* creates formatted output for calendar/component property x-prop
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.21.11 - 2015-03-31
* @uses iCalBase::$xprop
* @uses vcalendar::getConfig()
* @uses calendarComponent::getConfig()
* @uses iCalBase::_createElement()
* @uses iCalBase::_createParams()
* @uses iCalUtilityFunctions::_strrep()
* @uses iCalBase::$format
* @uses iCalBase::$nl
* @return string
*/
public function createXprop() {
if( empty( $this->xprop ) || !is_array( $this->xprop )) return FALSE;
$output = null;
foreach( $this->xprop as $label => $xpropPart ) {
if( ! isset( $xpropPart['value']) || ( empty( $xpropPart['value'] ) && !is_numeric( $xpropPart['value'] ))) {
if( $this->getConfig( 'allowEmpty' ))
$output .= $this->_createElement( $label );
continue;
}
$attributes = $this->_createParams( $xpropPart['params'], array( 'LANGUAGE' ));
if( is_array( $xpropPart['value'] )) {
foreach( $xpropPart['value'] as $pix => $theXpart )
$xpropPart['value'][$pix] = iCalUtilityFunctions::_strrep( $theXpart, $this->format, $this->nl );
$xpropPart['value'] = implode( ',', $xpropPart['value'] );
}
else
$xpropPart['value'] = iCalUtilityFunctions::_strrep( $xpropPart['value'], $this->format, $this->nl );
$output .= $this->_createElement( $label, $attributes, $xpropPart['value'] );
}
return $output;
}
/**
* set calendar property x-prop
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.21.11 - 2015-03-31
* @param string $label
* @param string $value
* @param array $params optional
* @uses vcalendar::getConfig()
* @uses iCalUtilityFunctions::_setParams()
* @uses iCalBase::$xprop
* @return bool
*/
public function setXprop( $label, $value, $params=FALSE ) {
if( empty( $label ))
return FALSE;
$label = strtoupper( $label );
if( 'X-' != substr( $label, 0, 2 ))
return FALSE;
if( empty( $value ) && !is_numeric( $value )) if( $this->getConfig( 'allowEmpty' )) $value = ''; else return FALSE;
$xprop = array( 'value' => $value );
$xprop['params'] = iCalUtilityFunctions::_setParams( $params );
if( ! is_array( $this->xprop ))
$this->xprop = array();
$this->xprop[$label] = $xprop;
return TRUE;
}
/**
* create element format parts
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.21.11 - 2015-03-31
* @uses iCalBase::$format
* @uses iCalBase::$objName
* @uses iCalBase::$componentStart1
* @uses iCalBase::$elementStart1
* @uses iCalBase::$componentStart2
* @uses iCalBase::$elementStart2
* @uses iCalBase::$componentEnd1
* @uses iCalBase::$elementEnd1
* @uses iCalBase::$componentEnd2
* @uses iCalBase::$elementEnd2
* @uses iCalBase::$nl;
* @uses iCalBase::$intAttrDelimiter
* @uses iCalBase::$attributeDelimiter
* @uses iCalBase::$valueInit
* @return bool
*/
function _createFormat() {
switch( $this->format ) {
case 'xcal':
$this->componentStart1 = $this->elementStart1 = '<';
$this->componentStart2 = $this->elementStart2 = '>';
$this->componentEnd1 = $this->elementEnd1 = '</';
$this->componentEnd2 = $this->elementEnd2 = '>'.$this->nl;
$this->intAttrDelimiter = '<!-- -->';
$this->attributeDelimiter = $this->nl;
$this->valueInit = null;
break;
default:
$this->componentStart1 = 'BEGIN:';
$this->componentStart2 = null;
$this->componentEnd1 = 'END:';
$this->componentEnd2 = $this->nl;
$this->elementStart1 = null;
$this->elementStart2 = null;
$this->elementEnd1 = null;
$this->elementEnd2 = $this->nl;
$this->intAttrDelimiter = '<!-- -->';
$this->attributeDelimiter = ';';
$this->valueInit = ':';
break;
}
return TRUE;
}
/**
* creates formatted output for calendar component property
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.21.11 - 2015-03-31
* @param string $label property name
* @param string $attributes property attributes
* @param string $content property content (optional)
* @uses iCalBase::$format
* @uses iCalBase::$elementStart1
* @uses iCalBase::$xcaldecl
* @uses iCalBase::$intAttrDelimiter
* @uses iCalBase::$attributeDelimiter
* @uses iCalBase::_createElement()
* @uses iCalBase::$elementStart2
* @uses iCalBase::$nl
* @uses iCalBase::$valueInit
* @uses iCalUtilityFunctions::_size75()
* @uses iCalBase::$elementEnd1
* @uses iCalBase::$elementEnd2
* @access protected
* @return string
*/
protected function _createElement( $label, $attributes=null, $content=FALSE ) {
switch( $this->format ) {
case 'xcal':
$label = strtolower( $label );
break;
default:
$label = strtoupper( $label );
break;
}
$output = $this->elementStart1.$label;
$categoriesAttrLang = null;
$attachInlineBinary = FALSE;
$attachfmttype = null;
if (( 'xcal' == $this->format) && ( 'x-' == substr( $label, 0, 2 ))) {
$this->xcaldecl[] = array( 'xmldecl' => 'ELEMENT'
, 'ref' => $label
, 'type2' => '(#PCDATA)' );
}
if( !empty( $attributes )) {
$attributes = trim( $attributes );
if ( 'xcal' == $this->format ) {
$attributes2 = explode( $this->intAttrDelimiter, $attributes );
$attributes = null;
foreach( $attributes2 as $aix => $attribute ) {
$attrKVarr = explode( '=', $attribute );
if( empty( $attrKVarr[0] ))
continue;
if( !isset( $attrKVarr[1] )) {
$attrValue = $attrKVarr[0];
$attrKey = $aix;
}
elseif( 2 == count( $attrKVarr)) {
$attrKey = strtolower( $attrKVarr[0] );
$attrValue = $attrKVarr[1];
}
else {
$attrKey = strtolower( $attrKVarr[0] );
unset( $attrKVarr[0] );
$attrValue = implode( '=', $attrKVarr );
}
if(( 'attach' == $label ) && ( in_array( $attrKey, array( 'fmttype', 'encoding', 'value' )))) {
$attachInlineBinary = TRUE;
if( 'fmttype' == $attrKey )
$attachfmttype = $attrKey.'='.$attrValue;
continue;
}
elseif(( 'categories' == $label ) && ( 'language' == $attrKey ))
$categoriesAttrLang = $attrKey.'='.$attrValue;
else {
$attributes .= ( empty( $attributes )) ? ' ' : $this->attributeDelimiter.' ';
$attributes .= ( !empty( $attrKey )) ? $attrKey.'=' : null;
if(( '"' == substr( $attrValue, 0, 1 )) && ( '"' == substr( $attrValue, -1 ))) {
$attrValue = substr( $attrValue, 1, ( strlen( $attrValue ) - 2 ));
$attrValue = str_replace( '"', '', $attrValue );
}
$attributes .= '"'.htmlspecialchars( $attrValue ).'"';
}
}
}
else {
$attributes = str_replace( $this->intAttrDelimiter, $this->attributeDelimiter, $attributes );
}
}
if(( 'xcal' == $this->format) &&
((( 'attach' == $label ) && !$attachInlineBinary ) || ( in_array( $label, array( 'tzurl', 'url' ))))) {
$pos = strrpos( $content, "/" );
$docname = ( $pos !== false) ? substr( $content, (1 - strlen( $content ) + $pos )) : $content;
$this->xcaldecl[] = array( 'xmldecl' => 'ENTITY'
, 'uri' => $docname
, 'ref' => 'SYSTEM'
, 'external' => $content
, 'type' => 'NDATA'
, 'type2' => 'BINERY' );
$attributes .= ( empty( $attributes )) ? ' ' : $this->attributeDelimiter.' ';
$attributes .= 'uri="'.$docname.'"';
$content = null;
if( 'attach' == $label ) {
$attributes = str_replace( $this->attributeDelimiter, $this->intAttrDelimiter, $attributes );
$content = $this->nl.$this->_createElement( 'extref', $attributes, null );
$attributes = null;
}
}
elseif(( 'xcal' == $this->format) && ( 'attach' == $label ) && $attachInlineBinary ) {
$content = $this->nl.$this->_createElement( 'b64bin', $attachfmttype, $content ); // max one attribute
}
$output .= $attributes;
if( !$content && ( '0' != $content )) {
switch( $this->format ) {
case 'xcal':
$output .= ' /';
$output .= $this->elementStart2.$this->nl;
return $output;
break;
default:
$output .= $this->elementStart2.$this->valueInit;
return iCalUtilityFunctions::_size75( $output, $this->nl );
break;
}
}
$output .= $this->elementStart2;
$output .= $this->valueInit.$content;
switch( $this->format ) {
case 'xcal':
return $output.$this->elementEnd1.$label.$this->elementEnd2;
break;
default:
return iCalUtilityFunctions::_size75( $output, $this->nl );
break;
}
}
/**
* creates formatted output for calendar component property parameters
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.21.11 - 2015-03-31
* @param array $params optional
* @param array $ctrKeys optional
* @uses iCalBase::$intAttrDelimiter
* @uses vcalendar::getConfig()
* @uses calendarComponent::getConfig()
* @access protected
* @return string
*/
protected function _createParams( $params=array(), $ctrKeys=array() ) {
if( !is_array( $params ) || empty( $params ))
$params = array();
$attrLANG = $attr1 = $attr2 = $lang = null;
$CNattrKey = ( in_array( 'CN', $ctrKeys )) ? TRUE : FALSE ;
$LANGattrKey = ( in_array( 'LANGUAGE', $ctrKeys )) ? TRUE : FALSE ;
$CNattrExist = $LANGattrExist = FALSE;
$xparams = array();
$params = array_change_key_case( $params, CASE_UPPER );
foreach( $params as $paramKey => $paramValue ) {
if(( FALSE !== strpos( $paramValue, ':' )) ||
( FALSE !== strpos( $paramValue, ';' )) ||
( FALSE !== strpos( $paramValue, ',' )))
$paramValue = '"'.$paramValue.'"';
if( ctype_digit( (string) $paramKey )) {
$xparams[] = $paramValue;
continue;
}
if( !in_array( $paramKey, array( 'ALTREP', 'CN', 'DIR', 'ENCODING', 'FMTTYPE', 'LANGUAGE', 'RANGE', 'RELTYPE', 'SENT-BY', 'TZID', 'VALUE' )))
$xparams[$paramKey] = $paramValue;
else
$params[$paramKey] = $paramValue;
}
ksort( $xparams, SORT_STRING );
foreach( $xparams as $paramKey => $paramValue ) {
if( ctype_digit( (string) $paramKey ))
$attr2 .= $this->intAttrDelimiter.$paramValue;
else
$attr2 .= $this->intAttrDelimiter."$paramKey=$paramValue";
}
if( isset( $params['FMTTYPE'] ) && !in_array( 'FMTTYPE', $ctrKeys )) {
$attr1 .= $this->intAttrDelimiter.'FMTTYPE='.$params['FMTTYPE'].$attr2;
$attr2 = null;
}
if( isset( $params['ENCODING'] ) && !in_array( 'ENCODING', $ctrKeys )) {
if( !empty( $attr2 )) {
$attr1 .= $attr2;
$attr2 = null;
}
$attr1 .= $this->intAttrDelimiter.'ENCODING='.$params['ENCODING'];
}
if( isset( $params['VALUE'] ) && !in_array( 'VALUE', $ctrKeys ))
$attr1 .= $this->intAttrDelimiter.'VALUE='.$params['VALUE'];
if( isset( $params['TZID'] ) && !in_array( 'TZID', $ctrKeys )) {
$attr1 .= $this->intAttrDelimiter.'TZID='.$params['TZID'];
}
if( isset( $params['RANGE'] ) && !in_array( 'RANGE', $ctrKeys ))
$attr1 .= $this->intAttrDelimiter.'RANGE='.$params['RANGE'];
if( isset( $params['RELTYPE'] ) && !in_array( 'RELTYPE', $ctrKeys ))
$attr1 .= $this->intAttrDelimiter.'RELTYPE='.$params['RELTYPE'];
if( isset( $params['CN'] ) && $CNattrKey ) {
$attr1 = $this->intAttrDelimiter.'CN='.$params['CN'];
$CNattrExist = TRUE;
}
if( isset( $params['DIR'] ) && in_array( 'DIR', $ctrKeys )) {
$delim = ( FALSE !== strpos( $params['DIR'], '"' )) ? '' : '"';
$attr1 .= $this->intAttrDelimiter.'DIR='.$delim.$params['DIR'].$delim;
}
if( isset( $params['SENT-BY'] ) && in_array( 'SENT-BY', $ctrKeys ))
$attr1 .= $this->intAttrDelimiter.'SENT-BY='.$params['SENT-BY'];
if( isset( $params['ALTREP'] ) && in_array( 'ALTREP', $ctrKeys )) {
$delim = ( FALSE !== strpos( $params['ALTREP'], '"' )) ? '' : '"';
$attr1 .= $this->intAttrDelimiter.'ALTREP='.$delim.$params['ALTREP'].$delim;
}
if( isset( $params['LANGUAGE'] ) && $LANGattrKey ) {
$attrLANG .= $this->intAttrDelimiter.'LANGUAGE='.$params['LANGUAGE'];
$LANGattrExist = TRUE;
}
if( !$LANGattrExist ) {
$lang = $this->getConfig( 'language' );
if(( $CNattrExist || $LANGattrKey ) && $lang )
$attrLANG .= $this->intAttrDelimiter.'LANGUAGE='.$lang;
}
return $attr1.$attrLANG.$attr2;
}
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,129 @@
<?php
/*********************************************************************************/
/**
*
* iCalcreator, a PHP rfc2445/rfc5545 solution.
*
* @copyright Copyright (c) 2007-2015 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* @link http://kigkonsult.se/iCalcreator/index.php
* @license http://kigkonsult.se/downloads/dl.php?f=LGPL
* @package iCalcreator
* @version 2.22
*/
/**
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*********************************************************************************/
/**
* selectComponent help class
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.21.7 - 2015-03-10
*/
class iCaldateTime extends dateTime {
/** @var string default date[-time] format */
public $dateFormat = 'Y-m-d H:i:s e';
/** @var string default object instance date[-time] 'key' */
public $key = null;
/** @var array date[-time] origin */
public $SCbools = array();
/**
* return time (His) array
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.21.7 - 2015-03-07
* @return array
*/
public function getTime() {
return explode( ':', $this->format( 'H:i:s' ));
}
/**
* return the timezone name
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.21.7 - 2015-03-07
* @return string
*/
public function getTimezoneName() {
$tz = $this->getTimezone();
return $tz->getName();
}
/**
* return formatted date
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.21.7 - 2015-03-07
* @param string $format
* @uses iCaldateTime::$dateFormat
* @return string
*/
public function format( $format=null ) {
if( empty( $format ) && isset( $this->dateFormat ))
$format = $this->dateFormat;
return parent::format( $format );
}
/**
* return iCaldateTime object instance based on date array and timezone(s)
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.21.11 - 2015-03-28
* @param array $date
* @param array $params
* @param array $tz
* @param string $dtstartTz
* @uses iCalUtilityFunctions::$fmt
* @uses iCaldateTime::getTimezoneName()
* @uses iCaldateTime::$dateFormat
* @uses iCaldateTime::$key
* @return object instance
*/
public static function factory( array $date, $params=null, $tz=null, $dtstartTz=null ) {
if( isset( $params['TZID'] ) && ! empty( $params['TZID'] ))
$tz = ( 'Z' == $params['TZID'] ) ? 'UTC' : $params['TZID'];
elseif( isset( $tz['tz'] ) && ! empty( $tz['tz'] ))
$tz = ( 'Z' == $tz['tz'] ) ? 'UTC' : $tz['tz'];
else
$tz = ini_get( 'date_default_timezone_set' );
$strdate = sprintf( iCalUtilityFunctions::$fmt['Ymd'], (int) $date['year'], (int) $date['month'], (int) $date['day'] );
if( isset( $date['hour'] ))
$strdate .= 'T'.sprintf( iCalUtilityFunctions::$fmt['His'], (int) $date['hour'], (int) $date['min'], (int) $date['sec'] );
try {
$timezone = new DateTimeZone( $tz );
$d = new iCaldateTime( $strdate, $timezone );
}
catch( Exception $e ) {
$d = new iCaldateTime( $strdate );
}
if( ! empty( $dtstartTz )) {
if( 'Z' == $dtstartTz )
$dtstartTz = 'UTC';
if( $dtstartTz != $d->getTimezoneName()) { // set the same timezone as dtstart
try {
$timezone = new DateTimeZone( $dtstartTz );
$d->setTimezone( $timezone );
}
catch( Exception $e ) {}
}
}
unset( $timezone, $strdate );
if( isset( $params['VALUE'] ) && ( 'DATE' == $params['VALUE'] )) {
$d->dateFormat = 'Y-m-d';
$d->key = $d->format( 'Ymd' );
}
else
$d->key = $d->format( 'YmdHis' );
return $d;
}
}

@ -0,0 +1,135 @@
<?php
/*********************************************************************************/
/**
*
* iCalcreator, a PHP rfc2445/rfc5545 solution.
*
* @copyright Copyright (c) 2007-2015 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* @link http://kigkonsult.se/iCalcreator/index.php
* @license http://kigkonsult.se/downloads/dl.php?f=LGPL
* @package iCalcreator
* @version 2.22
*/
/**
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*********************************************************************************/
/**
* class for calendar component VALARM
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.5.1 - 2008-10-12
*/
class valarm extends calendarComponent {
/**
* @var array $action component property value
* @var array $attach component property value
* @var array $attendee component property value
* @var array $description component property value
* @var array $duration component property value
* @var array $repeat component property value
* @var array $summary component property value
* @var array $trigger component property value
* @access protected
*/
protected $action;
protected $attach;
protected $attendee;
protected $description;
protected $duration;
protected $repeat;
protected $summary;
protected $trigger;
/**
* constructor for calendar component VALARM object
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.8.2 - 2011-05-01
* @param array $config
* @uses valarm::calendarComponent()
* @uses valarm::$action
* @uses valarm::$attach
* @uses valarm::$attendee
* @uses valarm::$description
* @uses valarm::$duration
* @uses valarm::$repeat
* @uses valarm::$summary
* @uses valarm::$trigger
* @uses valarm::$xprop
* @uses calendarComponent::setConfig()
*/
function valarm( $config = array()) {
$this->calendarComponent();
$this->action = '';
$this->attach = '';
$this->attendee = '';
$this->description = '';
$this->duration = '';
$this->repeat = '';
$this->summary = '';
$this->trigger = '';
$this->xprop = '';
if( defined( 'ICAL_LANG' ) && !isset( $config['language'] ))
$config['language'] = ICAL_LANG;
if( !isset( $config['allowEmpty'] )) $config['allowEmpty'] = TRUE;
if( !isset( $config['nl'] )) $config['nl'] = "\r\n";
if( !isset( $config['format'] )) $config['format'] = 'iCal';
if( !isset( $config['delimiter'] )) $config['delimiter'] = DIRECTORY_SEPARATOR;
$this->setConfig( $config );
}
/**
* create formatted output for calendar component VALARM object instance
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.5.1 - 2008-10-22
* @param array $xcaldecl
* @uses calendarComponent::_createFormat()
* @uses calendarComponent::$componentStart1
* @uses calendarComponent::$componentStart2
* @uses calendarComponent::$nl
* @uses calendarComponent::createAction()
* @uses calendarComponent::createAttach()
* @uses calendarComponent::createAttendee()
* @uses calendarComponent::createDescription()
* @uses calendarComponent::createDuration()
* @uses calendarComponent::createRepeat()
* @uses calendarComponent::createSummary()
* @uses calendarComponent::createTrigger()
* @uses calendarComponent::createXprop()
* @uses calendarComponent::$componentEnd1
* @uses calendarComponent::$componentEnd2
* @uses calendarComponent::$xcaldecl
* @return string
*/
function createComponent( & $xcaldecl ) {
$objectname = $this->_createFormat();
$component = $this->componentStart1.$objectname.$this->componentStart2.$this->nl;
$component .= $this->createAction();
$component .= $this->createAttach();
$component .= $this->createAttendee();
$component .= $this->createDescription();
$component .= $this->createDuration();
$component .= $this->createRepeat();
$component .= $this->createSummary();
$component .= $this->createTrigger();
$component .= $this->createXprop();
$component .= $this->componentEnd1.$objectname.$this->componentEnd2;
if( is_array( $this->xcaldecl ) && ( 0 < count( $this->xcaldecl ))) {
foreach( $this->xcaldecl as $localxcaldecl )
$xcaldecl[] = $localxcaldecl;
}
return $component;
}
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,269 @@
<?php
/*********************************************************************************/
/**
*
* iCalcreator, a PHP rfc2445/rfc5545 solution.
*
* @copyright Copyright (c) 2007-2015 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* @link http://kigkonsult.se/iCalcreator/index.php
* @license http://kigkonsult.se/downloads/dl.php?f=LGPL
* @package iCalcreator
* @version 2.22
*/
/**
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*********************************************************************************/
/**
* class for calendar component VEVENT
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.5.1 - 2008-10-12
*/
class vevent extends calendarComponent {
/**
* @var array $attach component property value
* @var array $attendee component property value
* @var array $categories component property value
* @var array $comment component property value
* @var array $contact component property value
* @var array $class component property value
* @var array $created component property value
* @var array $description component property value
* @var array $dtend component property value
* @var array $dtstart component property value
* @var array $duration component property value
* @var array $exdate component property value
* @var array $exrule component property value
* @var array $geo component property value
* @var array $lastmodified component property value
* @var array $location component property value
* @var array $organizer component property value
* @var array $priority component property value
* @var array $rdate component property value
* @var array $recurrenceid component property value
* @var array $relatedto component property value
* @var array $requeststatus component property value
* @var array $resources component property value
* @var array $rrule component property value
* @var array $sequence component property value
* @var array $status component property value
* @var array $summary component property value
* @var array $transp component property value
* @var array $url component property value
* @access protected
*/
protected $attach;
protected $attendee;
protected $categories;
protected $comment;
protected $contact;
protected $class;
protected $created;
protected $description;
protected $dtend;
protected $dtstart;
protected $duration;
protected $exdate;
protected $exrule;
protected $geo;
protected $lastmodified;
protected $location;
protected $organizer;
protected $priority;
protected $rdate;
protected $recurrenceid;
protected $relatedto;
protected $requeststatus;
protected $resources;
protected $rrule;
protected $sequence;
protected $status;
protected $summary;
protected $transp;
protected $url;
/**
* constructor for calendar component VEVENT object
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.8.2 - 2011-05-01
* @param array $config
* @uses vevent::calendarComponent()
* @uses vevent::$attach
* @uses vevent::$attendee
* @uses vevent::$categories
* @uses vevent::$class
* @uses vevent::$comment
* @uses vevent::$contact
* @uses vevent::$created
* @uses vevent::$description
* @uses vevent::$dtstart
* @uses vevent::$dtend
* @uses vevent::$duration
* @uses vevent::$exdate
* @uses vevent::$exrule
* @uses vevent::$geo
* @uses vevent::$lastmodified
* @uses vevent::$location
* @uses vevent::$organizer
* @uses vevent::$priority
* @uses vevent::$rdate
* @uses vevent::$recurrenceid
* @uses vevent::$relatedto
* @uses vevent::$requeststatus
* @uses vevent::$resources
* @uses vevent::$rrule
* @uses vevent::$sequence
* @uses vevent::$status
* @uses vevent::$summary
* @uses vevent::$transp
* @uses vevent::$url
* @uses vevent::$xprop
* @uses vevent::$components
* @uses calendarComponent::setConfig()
*/
function vevent( $config = array()) {
$this->calendarComponent();
$this->attach = '';
$this->attendee = '';
$this->categories = '';
$this->class = '';
$this->comment = '';
$this->contact = '';
$this->created = '';
$this->description = '';
$this->dtstart = '';
$this->dtend = '';
$this->duration = '';
$this->exdate = '';
$this->exrule = '';
$this->geo = '';
$this->lastmodified = '';
$this->location = '';
$this->organizer = '';
$this->priority = '';
$this->rdate = '';
$this->recurrenceid = '';
$this->relatedto = '';
$this->requeststatus = '';
$this->resources = '';
$this->rrule = '';
$this->sequence = '';
$this->status = '';
$this->summary = '';
$this->transp = '';
$this->url = '';
$this->xprop = '';
$this->components = array();
if( defined( 'ICAL_LANG' ) && !isset( $config['language'] ))
$config['language'] = ICAL_LANG;
if( !isset( $config['allowEmpty'] )) $config['allowEmpty'] = TRUE;
if( !isset( $config['nl'] )) $config['nl'] = "\r\n";
if( !isset( $config['format'] )) $config['format'] = 'iCal';
if( !isset( $config['delimiter'] )) $config['delimiter'] = DIRECTORY_SEPARATOR;
$this->setConfig( $config );
}
/**
* create formatted output for calendar component VEVENT object instance
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.10.16 - 2011-10-28
* @param array $xcaldecl
* @uses calendarComponent::_createFormat()
* @uses calendarComponent::$componentStart1
* @uses calendarComponent::$componentStart2
* @uses calendarComponent::$nl;
* @uses calendarComponent::createUid()
* @uses calendarComponent::createDtstamp()
* @uses calendarComponent::createAttach()
* @uses calendarComponent::createAttendee()
* @uses calendarComponent::createCategories()
* @uses calendarComponent::createComment()
* @uses calendarComponent::createContact()
* @uses calendarComponent::createClass()
* @uses calendarComponent::createCreated()
* @uses calendarComponent::createDescription()
* @uses calendarComponent::createDtstart()
* @uses calendarComponent::createDtend()
* @uses calendarComponent::createDuration()
* @uses calendarComponent::createExdate()
* @uses calendarComponent::createExrule()
* @uses calendarComponent::createGeo()
* @uses calendarComponent::createLastModified()
* @uses calendarComponent::createLocation()
* @uses calendarComponent::createOrganizer()
* @uses calendarComponent::createPriority()
* @uses calendarComponent::createRdate()
* @uses calendarComponent::createRrule()
* @uses calendarComponent::createRelatedTo()
* @uses calendarComponent::createRequestStatus()
* @uses calendarComponent::createRecurrenceid()
* @uses calendarComponent::createResources()
* @uses calendarComponent::createSequence()
* @uses calendarComponent::createStatus()
* @uses calendarComponent::createSummary()
* @uses calendarComponent::createTransp()
* @uses calendarComponent::createUrl()
* @uses calendarComponent::createXprop()
* @uses calendarComponent::createSubComponent()
* @uses calendarComponent::$componentEnd1
* @uses calendarComponent::$componentEnd2
* @uses calendarComponent::$xcaldecl
* @return string
*/
function createComponent( & $xcaldecl ) {
$objectname = $this->_createFormat();
$component = $this->componentStart1.$objectname.$this->componentStart2.$this->nl;
$component .= $this->createUid();
$component .= $this->createDtstamp();
$component .= $this->createAttach();
$component .= $this->createAttendee();
$component .= $this->createCategories();
$component .= $this->createComment();
$component .= $this->createContact();
$component .= $this->createClass();
$component .= $this->createCreated();
$component .= $this->createDescription();
$component .= $this->createDtstart();
$component .= $this->createDtend();
$component .= $this->createDuration();
$component .= $this->createExdate();
$component .= $this->createExrule();
$component .= $this->createGeo();
$component .= $this->createLastModified();
$component .= $this->createLocation();
$component .= $this->createOrganizer();
$component .= $this->createPriority();
$component .= $this->createRdate();
$component .= $this->createRrule();
$component .= $this->createRelatedTo();
$component .= $this->createRequestStatus();
$component .= $this->createRecurrenceid();
$component .= $this->createResources();
$component .= $this->createSequence();
$component .= $this->createStatus();
$component .= $this->createSummary();
$component .= $this->createTransp();
$component .= $this->createUrl();
$component .= $this->createXprop();
$component .= $this->createSubComponent();
$component .= $this->componentEnd1.$objectname.$this->componentEnd2;
if( is_array( $this->xcaldecl ) && ( 0 < count( $this->xcaldecl ))) {
foreach( $this->xcaldecl as $localxcaldecl )
$xcaldecl[] = $localxcaldecl;
}
return $component;
}
}

@ -0,0 +1,149 @@
<?php
/*********************************************************************************/
/**
*
* iCalcreator, a PHP rfc2445/rfc5545 solution.
*
* @copyright Copyright (c) 2007-2015 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* @link http://kigkonsult.se/iCalcreator/index.php
* @license http://kigkonsult.se/downloads/dl.php?f=LGPL
* @package iCalcreator
* @version 2.22
*/
/**
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*********************************************************************************/
/**
* class for calendar component VFREEBUSY
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.5.1 - 2008-10-12
*/
class vfreebusy extends calendarComponent {
/**
* @var array $attendee component property value
* @var array $comment component property value
* @var array $contact component property value
* @var array $dtend component property value
* @var array $dtstart component property value
* @var array $duration component property value
* @var array $freebusy component property value
* @var array $organizer component property value
* @var array $requeststatus component property value
* @var array $url component property value
* @access protected
*/
protected $attendee;
protected $comment;
protected $contact;
protected $dtend;
protected $dtstart;
protected $duration;
protected $freebusy;
protected $organizer;
protected $requeststatus;
protected $url;
/**
* constructor for calendar component VFREEBUSY object
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.8.2 - 2011-05-01
* @param array $config
* @uses vjournal::calendarComponent()
* @uses vjournal::$attendee
* @uses vjournal::$comment
* @uses vjournal::$contact
* @uses vjournal::$dtend
* @uses vjournal::$dtstart
* @uses vjournal::$dtduration
* @uses vjournal::$organizer
* @uses vjournal::$requeststatus
* @uses vjournal::$url
* @uses vjournal::$xprop
* @uses calendarComponent::setConfig()
*/
function vfreebusy( $config = array()) {
$this->calendarComponent();
$this->attendee = '';
$this->comment = '';
$this->contact = '';
$this->dtend = '';
$this->dtstart = '';
$this->duration = '';
$this->freebusy = '';
$this->organizer = '';
$this->requeststatus = '';
$this->url = '';
$this->xprop = '';
if( defined( 'ICAL_LANG' ) && !isset( $config['language'] ))
$config['language'] = ICAL_LANG;
if( !isset( $config['allowEmpty'] )) $config['allowEmpty'] = TRUE;
if( !isset( $config['nl'] )) $config['nl'] = "\r\n";
if( !isset( $config['format'] )) $config['format'] = 'iCal';
if( !isset( $config['delimiter'] )) $config['delimiter'] = DIRECTORY_SEPARATOR;
$this->setConfig( $config );
}
/**
* create formatted output for calendar component VFREEBUSY object instance
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.3.1 - 2007-11-19
* @param array $xcaldecl
* @uses calendarComponent::_createFormat()
* @uses calendarComponent::createUid()
* @uses calendarComponent::createDtstamp()
* @uses calendarComponent::createAttendee()
* @uses calendarComponent::createComment()
* @uses calendarComponent::createContact()
* @uses calendarComponent::createDtstart()
* @uses calendarComponent::createDtend()
* @uses calendarComponent::createDuration()
* @uses calendarComponent::createFreebusy()
* @uses calendarComponent::createOrganizer()
* @uses calendarComponent::createRequestStatus()
* @uses calendarComponent::createUrl()
* @uses calendarComponent::createXprop()
* @uses calendarComponent::createUrl()
* @uses calendarComponent::createXprop()
* @uses calendarComponent::$componentEnd1
* @uses calendarComponent::$componentEnd2
* @uses calendarComponent::$xcaldecl
* @return string
*/
function createComponent( &$xcaldecl ) {
$objectname = $this->_createFormat();
$component = $this->componentStart1.$objectname.$this->componentStart2.$this->nl;
$component .= $this->createUid();
$component .= $this->createDtstamp();
$component .= $this->createAttendee();
$component .= $this->createComment();
$component .= $this->createContact();
$component .= $this->createDtstart();
$component .= $this->createDtend();
$component .= $this->createDuration();
$component .= $this->createFreebusy();
$component .= $this->createOrganizer();
$component .= $this->createRequestStatus();
$component .= $this->createUrl();
$component .= $this->createXprop();
$component .= $this->componentEnd1.$objectname.$this->componentEnd2;
if( is_array( $this->xcaldecl ) && ( 0 < count( $this->xcaldecl ))) {
foreach( $this->xcaldecl as $localxcaldecl )
$xcaldecl[] = $localxcaldecl;
}
return $component;
}
}

@ -0,0 +1,222 @@
<?php
/*********************************************************************************/
/**
*
* iCalcreator, a PHP rfc2445/rfc5545 solution.
*
* @copyright Copyright (c) 2007-2015 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* @link http://kigkonsult.se/iCalcreator/index.php
* @license http://kigkonsult.se/downloads/dl.php?f=LGPL
* @package iCalcreator
* @version 2.22
*/
/**
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*********************************************************************************/
/**
* class for calendar component VJOURNAL
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.5.1 - 2008-10-12
*/
class vjournal extends calendarComponent {
/**
* @var array $attach component property value
* @var array $attendee component property value
* @var array $categories component property value
* @var array $comment component property value
* @var array $contact component property value
* @var array $class component property value
* @var array $created component property value
* @var array $description component property value
* @var array $dtstart component property value
* @var array $exdate component property value
* @var array $exrule component property value
* @var array $lastmodified component property value
* @var array $organizer component property value
* @var array $rdate component property value
* @var array $recurrenceid component property value
* @var array $relatedto component property value
* @var array $requeststatus component property value
* @var array $rrule component property value
* @var array $sequence component property value
* @var array $status component property value
* @var array $summary component property value
* @var array $url component property value
* @access protected
*/
protected $attach;
protected $attendee;
protected $categories;
protected $comment;
protected $contact;
protected $class;
protected $created;
protected $description;
protected $dtstart;
protected $exdate;
protected $exrule;
protected $lastmodified;
protected $organizer;
protected $rdate;
protected $recurrenceid;
protected $relatedto;
protected $requeststatus;
protected $rrule;
protected $sequence;
protected $status;
protected $summary;
protected $url;
/**
* constructor for calendar component VJOURNAL object
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.8.2 - 2011-05-01
* @param array $config
* @uses vjournal::calendarComponent()
* @uses vjournal::$attach
* @uses vjournal::$attendee
* @uses vjournal::$categories
* @uses vjournal::$class
* @uses vjournal::$comment
* @uses vjournal::$contact
* @uses vjournal::$created
* @uses vjournal::$description
* @uses vjournal::$dtstart
* @uses vjournal::$exdate
* @uses vjournal::$exrule
* @uses vjournal::$lastmodified
* @uses vjournal::$organizer
* @uses vjournal::$rdate
* @uses vjournal::$recurrenceid
* @uses vjournal::$relatedto
* @uses vjournal::$requeststatus
* @uses vjournal::$rrule
* @uses vjournal::$sequence
* @uses vjournal::$status
* @uses vjournal::$summary
* @uses vjournal::$url
* @uses vjournal::$xprop
* @uses calendarComponent::setConfig()
*/
function vjournal( $config = array()) {
$this->calendarComponent();
$this->attach = '';
$this->attendee = '';
$this->categories = '';
$this->class = '';
$this->comment = '';
$this->contact = '';
$this->created = '';
$this->description = '';
$this->dtstart = '';
$this->exdate = '';
$this->exrule = '';
$this->lastmodified = '';
$this->organizer = '';
$this->rdate = '';
$this->recurrenceid = '';
$this->relatedto = '';
$this->requeststatus = '';
$this->rrule = '';
$this->sequence = '';
$this->status = '';
$this->summary = '';
$this->url = '';
$this->xprop = '';
if( defined( 'ICAL_LANG' ) && !isset( $config['language'] ))
$config['language'] = ICAL_LANG;
if( !isset( $config['allowEmpty'] )) $config['allowEmpty'] = TRUE;
if( !isset( $config['nl'] )) $config['nl'] = "\r\n";
if( !isset( $config['format'] )) $config['format'] = 'iCal';
if( !isset( $config['delimiter'] )) $config['delimiter'] = DIRECTORY_SEPARATOR;
$this->setConfig( $config );
}
/**
* create formatted output for calendar component VJOURNAL object instance
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.5.1 - 2008-10-12
* @param array $xcaldecl
* @uses calendarComponent::_createFormat()
* @uses calendarComponent::$componentStart1
* @uses calendarComponent::$componentStart2
* @uses calendarComponent::$nl
* @uses calendarComponent::createUid()
* @uses calendarComponent::createDtstamp()
* @uses calendarComponent::createAttach()
* @uses calendarComponent::createAttendee()
* @uses calendarComponent::createCategories()
* @uses calendarComponent::createClass()
* @uses calendarComponent::createComment()
* @uses calendarComponent::createContact()
* @uses calendarComponent::createDescription()
* @uses calendarComponent::createDtstart()
* @uses calendarComponent::createExdate()
* @uses calendarComponent::createExrule()
* @uses calendarComponent::createLastModified()
* @uses calendarComponent::createOrganizer()
* @uses calendarComponent::createRdate()
* @uses calendarComponent::createRelatedTo()
* @uses calendarComponent::createRequestStatus()
* @uses calendarComponent::createRecurrenceid()
* @uses calendarComponent::createRrule()
* @uses calendarComponent::createSequence()
* @uses calendarComponent::createStatus()
* @uses calendarComponent::createSummary()
* @uses calendarComponent::createUrl()
* @uses calendarComponent::createXprop()
* @uses calendarComponent::$componentEnd1
* @uses calendarComponent::$componentEnd2
* @uses calendarComponent::$xcaldecl
* @return string
*/
function createComponent( &$xcaldecl ) {
$objectname = $this->_createFormat();
$component = $this->componentStart1.$objectname.$this->componentStart2.$this->nl;
$component .= $this->createUid();
$component .= $this->createDtstamp();
$component .= $this->createAttach();
$component .= $this->createAttendee();
$component .= $this->createCategories();
$component .= $this->createClass();
$component .= $this->createComment();
$component .= $this->createContact();
$component .= $this->createCreated();
$component .= $this->createDescription();
$component .= $this->createDtstart();
$component .= $this->createExdate();
$component .= $this->createExrule();
$component .= $this->createLastModified();
$component .= $this->createOrganizer();
$component .= $this->createRdate();
$component .= $this->createRequestStatus();
$component .= $this->createRecurrenceid();
$component .= $this->createRelatedTo();
$component .= $this->createRrule();
$component .= $this->createSequence();
$component .= $this->createStatus();
$component .= $this->createSummary();
$component .= $this->createUrl();
$component .= $this->createXprop();
$component .= $this->componentEnd1.$objectname.$this->componentEnd2;
if( is_array( $this->xcaldecl ) && ( 0 < count( $this->xcaldecl ))) {
foreach( $this->xcaldecl as $localxcaldecl )
$xcaldecl[] = $localxcaldecl;
}
return $component;
}
}

@ -0,0 +1,164 @@
<?php
/*********************************************************************************/
/**
*
* iCalcreator, a PHP rfc2445/rfc5545 solution.
*
* @copyright Copyright (c) 2007-2015 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* @link http://kigkonsult.se/iCalcreator/index.php
* @license http://kigkonsult.se/downloads/dl.php?f=LGPL
* @package iCalcreator
* @version 2.22
*/
/**
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*********************************************************************************/
/**
* class for calendar component VTIMEZONE
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.5.1 - 2008-10-12
*/
class vtimezone extends calendarComponent {
/** @var array $timezonetype component property value */
public $timezonetype;
/**
* @var array $comment component property value
* @var array $dtstart component property value
* @var array $lastmodified component property value
* @var array $rdate component property value
* @var array $rrule component property value
* @var array $tzid component property value
* @var array $tzname component property value
* @var array $tzoffsetfrom component property value
* @var array $tzoffsetto component property value
* @var array $tzurl component property value
* @access protected
*/
protected $comment;
protected $dtstart;
protected $lastmodified;
protected $rdate;
protected $rrule;
protected $tzid;
protected $tzname;
protected $tzoffsetfrom;
protected $tzoffsetto;
protected $tzurl;
/**
* constructor for calendar component VTIMEZONE object
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.8.2 - 2011-05-01
* @param mixed $timezonetype default FALSE ( STANDARD / DAYLIGHT )
* @param array $config
* @uses vtimezone::$timezonetype
* @uses vtimezone::calendarComponent()
* @uses vtimezone::$comment
* @uses vtimezone::$dtstart
* @uses vtimezone::$lastmodified
* @uses vtimezone::$rdate
* @uses vtimezone::$rrule
* @uses vtimezone::$tzid
* @uses vtimezone::$tzname
* @uses vtimezone::$tzoffsetfrom
* @uses vtimezone::$tzoffsetto
* @uses vtimezone::$tzurl
* @uses vtimezone::$xprop
* @uses vtimezone::$components
* @uses calendarComponent::setConfig()
*/
function vtimezone( $timezonetype=FALSE, $config = array()) {
if( is_array( $timezonetype )) {
$config = $timezonetype;
$timezonetype = FALSE;
}
if( !$timezonetype )
$this->timezonetype = 'VTIMEZONE';
else
$this->timezonetype = strtoupper( $timezonetype );
$this->calendarComponent();
$this->comment = '';
$this->dtstart = '';
$this->lastmodified = '';
$this->rdate = '';
$this->rrule = '';
$this->tzid = '';
$this->tzname = '';
$this->tzoffsetfrom = '';
$this->tzoffsetto = '';
$this->tzurl = '';
$this->xprop = '';
$this->components = array();
if( defined( 'ICAL_LANG' ) && !isset( $config['language'] ))
$config['language'] = ICAL_LANG;
if( !isset( $config['allowEmpty'] )) $config['allowEmpty'] = TRUE;
if( !isset( $config['nl'] )) $config['nl'] = "\r\n";
if( !isset( $config['format'] )) $config['format'] = 'iCal';
if( !isset( $config['delimiter'] )) $config['delimiter'] = DIRECTORY_SEPARATOR;
$this->setConfig( $config );
}
/**
* create formatted output for calendar component VTIMEZONE object instance
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.5.1 - 2008-10-25
* @param array $xcaldecl
* @uses calendarComponent::_createFormat()
* @uses calendarComponent::$componentStart1
* @uses calendarComponent::$componentStart2
* @uses calendarComponent::$nl
* @uses calendarComponent::createTzid()
* @uses calendarComponent::createLastModified()
* @uses calendarComponent::createTzurl()
* @uses calendarComponent::createDtstart()
* @uses calendarComponent::createTzoffsetfrom()
* @uses calendarComponent::createTzoffsetto()
* @uses calendarComponent::createComment()
* @uses calendarComponent::createRdate()
* @uses calendarComponent::createRrule()
* @uses calendarComponent::createTzname()
* @uses calendarComponent::createXprop()
* @uses calendarComponent::createSubComponent()
* @uses calendarComponent::createXprop()
* @uses calendarComponent::$componentEnd1
* @uses calendarComponent::$componentEnd2
* @uses calendarComponent::$xcaldecl
* @return string
*/
function createComponent( &$xcaldecl ) {
$objectname = $this->_createFormat();
$component = $this->componentStart1.$objectname.$this->componentStart2.$this->nl;
$component .= $this->createTzid();
$component .= $this->createLastModified();
$component .= $this->createTzurl();
$component .= $this->createDtstart();
$component .= $this->createTzoffsetfrom();
$component .= $this->createTzoffsetto();
$component .= $this->createComment();
$component .= $this->createRdate();
$component .= $this->createRrule();
$component .= $this->createTzname();
$component .= $this->createXprop();
$component .= $this->createSubComponent();
$component .= $this->componentEnd1.$objectname.$this->componentEnd2;
if( is_array( $this->xcaldecl ) && ( 0 < count( $this->xcaldecl ))) {
foreach( $this->xcaldecl as $localxcaldecl )
$xcaldecl[] = $localxcaldecl;
}
return $component;
}
}

@ -0,0 +1,273 @@
<?php
/*********************************************************************************/
/**
*
* A PHP implementation of rfc2445/rfc5545.
*
* @copyright Copyright (c) 2007-2015 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* @link http://kigkonsult.se/iCalcreator/index.php
* @license http://kigkonsult.se/downloads/dl.php?f=LGPL
* @package iCalcreator
* @version 2.22
*/
/**
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*********************************************************************************/
/**
* class for calendar component VTODO
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.5.1 - 2008-10-12
*/
class vtodo extends calendarComponent {
/**
* @var array $attach component property value
* @var array $attendee component property value
* @var array $categories component property value
* @var array $comment component property value
* @var array $completed component property value
* @var array $contact component property value
* @var array $class component property value
* @var array $created component property value
* @var array $description component property value
* @var array $dtstart component property value
* @var array $due component property value
* @var array $duration component property value
* @var array $exdate component property value
* @var array $exrule component property value
* @var array $geo component property value
* @var array $lastmodified component property value
* @var array $location component property value
* @var array $organizer component property value
* @var array $percentcomplete component property value
* @var array $priority component property value
* @var array $rdate component property value
* @var array $recurrenceid component property value
* @var array $relatedto component property value
* @var array $requeststatus component property value
* @var array $resources component property value
* @var array $rrule component property value
* @var array $sequence component property value
* @var array $status component property value
* @var array $summary component property value
* @var arrayr $url;
* @access protected
*/
protected $attach;
protected $attendee;
protected $categories;
protected $comment;
protected $completed;
protected $contact;
protected $class;
protected $created;
protected $description;
protected $dtstart;
protected $due;
protected $duration;
protected $exdate;
protected $exrule;
protected $geo;
protected $lastmodified;
protected $location;
protected $organizer;
protected $percentcomplete;
protected $priority;
protected $rdate;
protected $recurrenceid;
protected $relatedto;
protected $requeststatus;
protected $resources;
protected $rrule;
protected $sequence;
protected $status;
protected $summary;
protected $url;
/**
* constructor for calendar component VTODO object
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.8.2 - 2011-05-01
* @param array $config
* @uses vtodo::calendarComponent()
* @uses vtodo::$attach
* @uses vtodo::$attendee
* @uses vtodo::$categories
* @uses vtodo::$class
* @uses vtodo::$comment
* @uses vtodo::$completed
* @uses vtodo::$contact
* @uses vtodo::$created
* @uses vtodo::$description
* @uses vtodo::$dtstart
* @uses vtodo::$due
* @uses vtodo::$duration
* @uses vtodo::$exdate
* @uses vtodo::$exrule
* @uses vtodo::$geo
* @uses vtodo::$lastmodified
* @uses vtodo::$location
* @uses vtodo::$organizer
* @uses vtodo::$percentcomplete
* @uses vtodo::$priority
* @uses vtodo::$rdate
* @uses vtodo::$recurrenceid
* @uses vtodo::$relatedto
* @uses vtodo::$requeststatus
* @uses vtodo::$resources
* @uses vtodo::$rrule
* @uses vtodo::$sequence
* @uses vtodo::$status
* @uses vtodo::$summary
* @uses vtodo::$url
* @uses vtodo::$xprop
* @uses vtodo::$components
* @uses calendarComponent::setConfig()
*/
function vtodo( $config = array()) {
$this->calendarComponent();
$this->attach = '';
$this->attendee = '';
$this->categories = '';
$this->class = '';
$this->comment = '';
$this->completed = '';
$this->contact = '';
$this->created = '';
$this->description = '';
$this->dtstart = '';
$this->due = '';
$this->duration = '';
$this->exdate = '';
$this->exrule = '';
$this->geo = '';
$this->lastmodified = '';
$this->location = '';
$this->organizer = '';
$this->percentcomplete = '';
$this->priority = '';
$this->rdate = '';
$this->recurrenceid = '';
$this->relatedto = '';
$this->requeststatus = '';
$this->resources = '';
$this->rrule = '';
$this->sequence = '';
$this->status = '';
$this->summary = '';
$this->url = '';
$this->xprop = '';
$this->components = array();
if( defined( 'ICAL_LANG' ) && !isset( $config['language'] ))
$config['language'] = ICAL_LANG;
if( !isset( $config['allowEmpty'] )) $config['allowEmpty'] = TRUE;
if( !isset( $config['nl'] )) $config['nl'] = "\r\n";
if( !isset( $config['format'] )) $config['format'] = 'iCal';
if( !isset( $config['delimiter'] )) $config['delimiter'] = DIRECTORY_SEPARATOR;
$this->setConfig( $config );
}
/**
* create formatted output for calendar component VTODO object instance
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.5.1 - 2008-11-07
* @param array $xcaldecl
* @uses calendarComponent::_createFormat()
* @uses calendarComponent::$componentStart1
* @uses calendarComponent::$componentStart2
* @uses calendarComponent::$nl;
* @uses calendarComponent::createUid()
* @uses calendarComponent::createDtstamp()
* @uses calendarComponent::createAttach()
* @uses calendarComponent::createAttendee()
* @uses calendarComponent::createCategories()
* @uses calendarComponent::createClass()
* @uses calendarComponent::createComment()
* @uses calendarComponent::createCompleted()
* @uses calendarComponent::createContact()
* @uses calendarComponent::createDescription()
* @uses calendarComponent::createDtstart()
* @uses calendarComponent::createDtend()
* @uses calendarComponent::createDuration()
* @uses calendarComponent::createExdate()
* @uses calendarComponent::createExrule()
* @uses calendarComponent::createGeo()
* @uses calendarComponent::createLastModified()
* @uses calendarComponent::createLocation()
* @uses calendarComponent::createOrganizer()
* @uses calendarComponent::createPriority()
* @uses calendarComponent::createRdate()
* @uses calendarComponent::createRelatedTo()
* @uses calendarComponent::createRequestStatus()
* @uses calendarComponent::createRecurrenceid()
* @uses calendarComponent::createResources()
* @uses calendarComponent::createRrule()
* @uses calendarComponent::createSequence()
* @uses calendarComponent::createStatus()
* @uses calendarComponent::createSummary()
* @uses calendarComponent::createUrl()
* @uses calendarComponent::createXprop()
* @uses calendarComponent::createSubComponent()
* @uses calendarComponent::$componentEnd1
* @uses calendarComponent::$componentEnd2
* @uses calendarComponent::$xcaldecl
* @return string
*/
function createComponent( &$xcaldecl ) {
$objectname = $this->_createFormat();
$component = $this->componentStart1.$objectname.$this->componentStart2.$this->nl;
$component .= $this->createUid();
$component .= $this->createDtstamp();
$component .= $this->createAttach();
$component .= $this->createAttendee();
$component .= $this->createCategories();
$component .= $this->createClass();
$component .= $this->createComment();
$component .= $this->createCompleted();
$component .= $this->createContact();
$component .= $this->createCreated();
$component .= $this->createDescription();
$component .= $this->createDtstart();
$component .= $this->createDue();
$component .= $this->createDuration();
$component .= $this->createExdate();
$component .= $this->createExrule();
$component .= $this->createGeo();
$component .= $this->createLastModified();
$component .= $this->createLocation();
$component .= $this->createOrganizer();
$component .= $this->createPercentComplete();
$component .= $this->createPriority();
$component .= $this->createRdate();
$component .= $this->createRelatedTo();
$component .= $this->createRequestStatus();
$component .= $this->createRecurrenceid();
$component .= $this->createResources();
$component .= $this->createRrule();
$component .= $this->createSequence();
$component .= $this->createStatus();
$component .= $this->createSummary();
$component .= $this->createUrl();
$component .= $this->createXprop();
$component .= $this->createSubComponent();
$component .= $this->componentEnd1.$objectname.$this->componentEnd2;
if( is_array( $this->xcaldecl ) && ( 0 < count( $this->xcaldecl ))) {
foreach( $this->xcaldecl as $localxcaldecl )
$xcaldecl[] = $localxcaldecl;
}
return $component;
}
}

@ -21,9 +21,8 @@
* *
*/ */
include_once('mapi/class.recurrence.php'); include_once('ical/class.icalcreator.php');
include_once('plugins/calendarimporter/php/ical/class.icalcreator.php'); include_once('ical/class.icalparser.php');
include_once('plugins/calendarimporter/php/ical/class.icalparser.php');
class CalendarModule extends Module { class CalendarModule extends Module {