Home
Zarafa WebApp - Developers` Manual
Contents
1. 71 Chapter 14 Translations have a different one when dealing with zero Some other languages make it even more complex with different cases for numbers ending with one except for eleven 14 3 2 Implemented Functions on the Client Side The client side implements the same function we have on the server side Except for the functions that implement the gettext category the c functions The msgid argument is the translatable string The msgctxt is the context argument _ key domain dgettext domain msgid ngettext msgid msgid_plural count dngettext domain msgid msgid_plural count pgettext msgctxt msgid dpgettext domain msgctxt msgid npgettext msgctxt msgid msgid_plural count dnpgettext domain msgctxt msgid msgid_plural count The Translations object will use the plural forms string that was extracted from the binary mo file and passed on to the client It is put into a function to be called when dealing with a plural translation 72 Appendix A Coding Standards A 1 Naming Conventions A 1 1 Namespace Structure The bulk of the code lives in client zarafa representing the Zarafa namespace e Zarafa the root namespace e core the application core framework Includes global models such as the folder hierarchy the plugin contexts and widgets system etc e ui Ul components used in the core framework Navigation panel main viewport etc e dialog core dialogs common co
2. zarafa gt Array v1 gt Array plugins gt Array spreed gt Array enable gt PLUGIN_SPREED_USER_DEFAULT_ENABLE default_timezone gt date_default_timezone_get You can add any other settings as you wish For example again in the Spreed plugin spreed gt Array enable gt PLUGIN_SPREED_ENABLE default_timezone gt PLUGIN_SPREED_DEFAULT_TIMEZONE 40 Settings model spreed_setup gt Array width gt 940 height gt 480 Next to enable there are settings for the default time zone default_timezone and the size of the dialog The default time zone is taken from the value that is defined in config php in this case the WebApp global one not the one distributed by the plugin Default timezone of the spreed meeting define PLUGIN_SPREED_DEFAULT_TIMEZONE Europe Amsterdam Obviously if you have something to configure on the server side the names can differ but the functionality should be the same In the end the result looks something like in Figure 9 7 Plugin settings General Advanced settings MA Mail Setting a Value Calendar default_reminder_time 15 freebusy_load_end_offset 90 Arme E freebusy_load_start_offset 7 3 common contact hierarchy O mail notes task today 3 main 4 3 plugins facebook 4 3 spreed C spreed_setup E default_timezone Europe Amsterdam A A EEE C statsloggi
3. 13 1 Deployment All plugins files should be created in a special separate plugin directory webapp plugins Each plugin or widget should have one separate directory For example Spreed plugin has the following items inside e js folder e data folder all classes realted to working with data are stored here e dialogs folder all classes realted to dialogs and ui should be placed here e SpreedPlugin js cannot be sorted properly being the main plugin class and is separate php folder data folder data stored here like list of languages and timezones e inc folder php classes stored here e resources folder e css folder css resources places here e icons folder different icons stored here e build xml for building spreed plugin discussed further in chapter Build System build system e config php defined php constants manifest xml manifest file Example widget hierarchy let be end of world widget e js folder FBWidget js widget class e resources folder css folder css files for widget placed here images folder images for widget go here facebook png build xml e manifest xml If you want your plugin to be enabled disabled using Zarafa Settings menu you should create a new folder in WebApp root folder plugins directory with the name of your plugin e g plugins facebook plugins spreed There you should create at least two files manifest xml plugin facebook php
4. Array enable gt PLUGIN_FACEBOOK_ENABLE An example from the Spreed plugin is the default meeting duration When creating the time panel for the Setup Spreed meeting dialog we set predefined values for the Spreed meeting duration The duration is retrieved by getting the default value from calendar default appointment period See Figure 9 6 Settings of calendar 39 Chapter 9 Data Models General Advanced settings Mail Setting a Value Calendar 4 Settings 4 zarafa a s 4 contexts 4 A calendar dialogs C modelstate searchbar state E defautt_allday_reminder_time 1080 E default_reminder true E default_reminder_time 15 freebusy_load_end_offset 90 freebusy_load_start_offset F J E common J contact hierarchy mail notes task Apply Discard Figure 9 6 Settings of calendar The implementation is shown here var duration container getSettingsModel get zarafa v1 contexts calendar default_appointment_period To add your plugin settings to the Zarafa settings model the injectPluginSet tings function should be implemented on the server side y Called when the core Settings class is initialized and ready to accept the sysadmin s default settings Registers the sysadmin defaults for the Spreed plugin param Array data Reference to the data of the triggered hook y function injectPluginSettings amp data data settingsObj gt addSysAdminDefaults Array
5. JsonAttachmentwriter Jp eres Similar to link Zarafa core data JsonAttachmentWriter toHash Here we serializing only the data of the records in spreed attachment store Note that we serialize all the records not only removed or modified param Ext data Record record The record to hash return Object The hashed object override private EU toPropHash function record var attachmentStore record getAttachmentStore var hash if Ext isDefined attachmentStore return hash Overwrite previous definition to something we can work with hash attachments hash attachments dialog_attachments attachmentStore getId var attachmentRecords attachmentStore getRange Ext each attachmentRecords function attach if Ext isDefined hash attachments add hash attachments add var data attach data hash attachments add push data this return hash y y The name of the SubStore is used for the Json Data The contents of the SubStore will be serialized with this name into the Json Object Let s consider spreed substores code for example pis dependsFile client zarafa core data IPMRecipientStore js Ext namespace Zarafa plugins spreed data Yes class Zarafa plugins spreed data SpreedParticipantStore extends Zarafa core data IPMRecipientStore 27 Zarafa plugins spreed data SpreedParticipantStore Ext extend Zarafa core data IPMRecipientStore ar con
6. Points The first thing plugin developers should really learn to start implementing new plugins are insertion points An insertion point is a named location in the Ul component hierarchy where plugins may add their own components Insertion points are typically added to toolbars and context menus and are intended to be easy hooks for adding new buttons button groups or menuitems The name of an insertion point is hierarchical so most things specifically related to e mail will start with context mail and have a more precise indication of the location after that Note that work with insertion points is implemented as a call to the container which collects Ul components from registered plugins and returns them You can easily create your custom insertion points See the listing below var toolbar new Ext Toolbar items Fixed items always present iconCls icon_new iconCls icon_delete Create insertion point example toolbar container populateInsertionPoint example toolbar H And now you have created a new insertion point which can be used in future By design the names of the insertion points should reflect the structure of the application Therefore the proposed naming scheme follows a hierarchy separated by dots More information and recommendations on the naming conventions are given in Appendix A Coding Standards In some cases it s useful to have insertion points that provide extr
7. footer bar or bbar bottom bar fields However for these fields additional path seperators are needed since these are actually separate containers inside the main container 3 3 Enums Enumerations in Zarafa are extended from Zarafa core Enum See the following example from the Spreed plugin Ext namespace Zarafa plugins spreed data iid class Zarafa plugins spreed data DialogTypes extends Zarafa core Enum Chapter 3 Ext JS and OO Javascript Enum containing the different types of dialogs needed to display spreed meeting singleton ny Zarafa plugins spreed data DialogTypes Zarafa core Enum create fits The dialog with empty fields Brandly new property type Number 27 EMPTY 1 are The dialog with filled subject and participants property type Number 77 FILLED 2 prs The dialog with only participants field prefilled property type Number yf PARTICIPANTS FILLED 3 y So this example contains as usual the namespace specification then comments explaining what the purpose of this enumeration is Then the constructor create of the superclass followed by the list of properties and their values You can also add extra items to an enumeration at a later stage this might be especially helpful for plugins This requires to extend from Zarafa core data RecordCustomObjectType It is connected with RecordFactory so all custom record
8. is needed across the application As you can see even the Mail Calendar etc contexts are plugins building on the core UI and model frameworks r Mail Calendar Note age Plug ins Plug ins lt Alfresco SugarCR M Model UI Framework ExtJS Figure 2 1 WebApp architecture overview The framework also provides a user interface infrastructure with a main screen that carries the standard components that are used by all contexts The framework supplies a communications API that allows for both low level and high level interaction with the server side back end A more advanced explanation of the architecture of Zarafa WebApp can be found in Chapter 10 MAPI Chapter 3 Ext JS and OO Javascript Chapter 9 Data Models http docs sencha com ext js 3 4 api z http www sencha com Chapter 3 Ext JS and OO Javascript JavaScript is not a real object oriented language it is a prototyping language that is the difference with other object oriented languages In Javascript you don t use classes you create objects from other objects When developing your own plugins it s a good idea to place all of your classes and singletons into namespaces to avoid collisions with other developers code With Ext JS it s easy to do this using Ext namespace 3 1 Classes To declare a new class one usually starts with defi
9. messaging functionality Extended MAPI allows complete control over the messaging system on the client computer creation and management of messages management of the client mailbox service providers and so forth Simple MAPI ships with Microsoft Windows as a part of Outlook Express Windows Mail while the full Extended MAPI ships with Office Outlook and Exchange For more information about MAPI concepts refer to corresponding MSDN article Zarafa provides its own OpenMAPI Zarafa realisation The data model provides an API for working with client side and server side data A user has access to a set of MAPI stores which contain MAPI folders which in turn contain MAPI messages A simplified view of the MAPI model is shown in Figure 10 1 MAPI data model MAPI Store MAPI Folder MAPI Message Figure 10 1 MAPI data model MAPI Messaging Application Programming Interface Store is actually the base one which can be extended with plugins See Figure 10 2 MAPI store table An important note here is that Zarafa core data MAPIStore is not a MAPI Store as it is but an Ext data Store used to collect MAPI Messages f http msdn microsoft com en us library cc815323 aspx 45 Chapter 10 MAPI Profile Default Store Default Store Public Store Shared Store Hierarchy Table Figure 10 2 MAPI store table One of the main MAPI concepts is a folder Folders are MAPI objects th
10. of the application can be easily unit tested outside the browser View controller components never need communicating with each other or even need to know of each others existence as all data requests and modifications are done through the models A concrete example of how models and view controllers interact is shown in Figure 9 3 Deleting a message item from a data store the ContextMenu deletes item in the model and on Shown at the top is a store containing a set of message items representing the model Three Ul components act as view controllers mutating and displaying information in the store http developer zarafa com webapp class Zarafa hierarchy HierarchyContext i http developer zarafa com webapp class Zarafa settings SettingsContext 36 Separable model architecture Server Store DE delete save ContextMenu PaginationToolbar GridPanel Figure 9 3 Deleting a message item from a data store the ContextMenu deletes item in the model Server delete delete Store ContextMenu PaginationToolbar GridPanel Figure 9 4 Deleting a message item from a data store the model commits the change Server Store ong delete delete delete Conte xtMe nu PaginationToolbar GridPanel Figure 9 5 Deleting a message item from a data store the model fires a delete event on completion In this example if a user deletes an item the ContextMenu object calls the delete method on the store and
11. sadly doesn t support Java 6 for OS X 10 4 or on 32 bit intel macs with OS X 10 5 On these platforms install SoyLatte instead To test if everything works as it should go to the root of you WebApp 7 folder and simply type ant Your system should build the tools build the client application and run the test suite 13 2 2 Ant Introduction Ant is an XML based build system written in Java and is quite well known in the Java community We have chosen Ant to build our application because many of the tools that we use to process our JavaScript code were written in Java such as the ext doc documentation tool our own JsConcat concatenation tool and others Ant build files are XML files usually called build xml They define a project with several nested properties typedefs and tasks Here s a partial example lt project name example default all gt lt property name foo value bar gt lt target name all depends compile gt lt target name init gt lt do something here gt lt target gt lt target name compile depends init gt http www java com en download index jsp i http landonf bikemonkey org static soylatte 65 Chapter 13 Deployment and Build System lt do something here gt lt target gt lt project gt The target tag defines a target Targets have nested tasks like calling a compiler creating an output directory etc The property tag acts like key value in mak
12. shows how to use the Shared Component mechanism var componentType Zarafa core data SharedComponentType componentType var dialog container getSharedComponent componentType record if dialog config record record dialog create config The plugins that take part in the bidding round for the component can then base their bid on the data within the record For example the mail context can bid differently for records that have the object_type set to MAPI_MESSAGE and a message_class of IPM Note than for the records with amessage_class of IPM Appointment On the other hand the calendar context would bid higher for the latter one The hierarchy context would look for records that contain an object_type set to MAPI_FOLDER to do its bidding 8 4 Example The following snippet of code shows how the plugin can participate in the bidding round 32 Example Bid for the type of shared component and the given record This will bid on a common dialog create or common dialog view for a record with a message class set to IPM or IPM Note param Zarafa core data SharedComponentType type Type of component a context can bid for param Ext data Record record Optionally passed record return Number The bid for the shared component N bidSharedComponent function type record var bid 1 if Ext isArray record record record 0 if record amp amp record store re
13. spreed dialogs SpreedParticipantBox superclass f http docs sencha com ext js 3 4 api Ext method namespace Chapter 3 Ext JS and OO Javascript constructor call this config F other functions y Ext reg spreed spreedparticipantbox Zarafa plugins spreed dialogs SpreedParticipantBox The Ext namespace call on the first line ensures that there exists a JavaScript object called Zarafa plugins spreed dialogs to act as an enclosing namespace object for our new class The Ext JS Ext namespace function declares a namespace We place chunks of related functionality in namespaces and let the code tree reflect the namespace hierarchy For example classes in the Zarafa plugins spreed dialogs namespace are defined in JavaScript files that can be found in plugins spreed dialogs and are related to Spreed Meeting dialogs After this come several lines of documentation the class name its parent class and xtype to register It s good practice to always do this since the build system extracts this information to determine the inclusion order of JavaScript files The call to Ext extend expresses that Zarafa plugins spreed dialogs SpreedParticipantBox extends is a child class of Zarafa common recipientfield ui RecipientBox It is now possible to substitute an instance of the former for the latter In most cases you can easily extend already existing classes to add some small functionality If the class you re writing is n
14. tell Ext JS the property is valid for this Record This is where the RecordFactory is utilized The RecordFactory contains the complete field definitions for all possible Record definitions During loading Contexts and Plugins can tell the RecordFactory which fields they wish to use for a particular Message class or object type For example Zarafa core data RecordFactory addFieldToMessageClass IPM Note name from D This adds the field from to the Record definition for any Record with messageclass PM Note Or according to Spreed plugin Zarafa core data RecordFactory addFieldToCustomType Zarafa core data RecordCustomObjectType ZARAFA_SPREED_ATTACHMENT Zarafa plugins spreed data SpreedAttachmentRecordFields Where Zarafa plugins spreed data SpreedAttachmentRecordFields is a set of fields to add to our record Zarafa plugins spreed data SpreedAttachmentRecordFields name original_record_entryid type string defaultValue name original_record_store_entryid type string defaultValue name original_attach_num type int name original_attachment_store_id type string defaultValue 1 When adding a new object type it should be added to RecordCustomObjectType enum refer to enum for more information Zarafa core data RecordCustomObjectType addProperty ZARAFA_SPREED_ATTACHMENT When the user creates a new Record it must call the RecordFactory to reques
15. the core and common packages to the top of the list For example Foo bar will move all files which have classes in the root package i e Date Foo to the top of the list after wich come all files which have classes in Foo bar or any of its descending packages and finally all the files that match neither of these criteria Example Build File lt Define the jsconcat task gt lt taskdef name jsconcat classname com zarafa jsconcat JsConcatTask gt lt classpath path JsConcat jar gt lt taskdef gt lt Concatenates JavaScript files with automatic dependency generation gt lt target name concat gt lt jsconcat verbose false destfile debugfile prioritize w Foo bar lt fileset dir sourcedir includes js gt lt jsconcat gt lt target gt 13 2 3 2 Ext doc Ext JS comes with a JavaDoc inspired code documentation tool that generates nice HTML documentation There is a fork of this tool in the svn that supports extra tags to document insertion points More information can be found at the ext doc google project page 13 2 3 3 Closure Compiler The Closure Compiler is a Javascript minimisation tool from Google It will compile a concatenated JavaScript file It supports multiple compile modes only whitespace guarantees to only change the whitespaces and minimise the Javascript file without changing the code itself The other compilation modes will change the code itsel
16. then calls save Figure 9 3 Deleting a message item from a data store the ContextMenu 37 Chapter 9 Data Models deletes item in the model to tell the store to synchronise with the server Figure 9 4 Deleting a message item from a data store the model commits the change When this asynchronous operation has finished a delete event is fired to notify the three components that an item was removed Figure 9 5 Deleting a message item from a data store the model fires a delete event on completion This in turn causes the grid and tool bar to update and reflect the change Refer to Chapter 11 Communication for more detailed information on how the change is communicated to the server 9 3 Hierarchy model The HierarchyModel is a model class containing a structured tree for all MAPI stores and MAPI folders in the application It can be used to receive entryid store_entryid or parent_entryid of any of its contained elements but to receive the data from these stores you should use context models Loading the hierarchy from the server can be done by calling the Load method Load the folder hierarchy container getHierarchyModel load This method triggers an asynchronous HTTP request When the hierarchy has loaded or when an error occurred the model fires the load event Hook the load event container getHierarchyModel on load function alert Hierarchy loaded y Load the
17. AEUEOTEETEHRSEREEEERTETTETRERLERESTRTERRFTUERERELRETFEERTEFERRREBERE 8 3 Bidding on a shared component 444ssnenssennnnnnnnnnnsnnnnnnnnnnnnnnnnnnnnnnnnnen 8 42 EXAmplet arena he uni blanket aAA ain 9 Data Models 9 1 Model based architecture cece cece eect teeter reer nn nennen a taa 9 2 Separable model architecture u sssssnssennnnennnnnnnsnennnnnennnnnnnnnen nenn nennen 9 3 Hier rchy model re er er Ban 94 Settings Modei nern a ra ne nee here ende hehe dee Ill Advanced topics 10 MAPI 11 Communication 11 1 Conceptual Overview ocoocccnnccccnoccnnconcnncncnncnnononnnnncnnnnnnnnncrcnnnnnnnrnnnnrinnarnnnnercnnnss A A a eA a eh 11 3 Javascript Communication cece ceee cece cece cee e ee nt eee e tees ae essa eeee aa eeeeeeeeaaeeeeaeeeeaees 23 23 27 28 29 31 31 32 35 Zarafa WebApp 11 4 Response Handlers scooters 11 5 NoUfications as dada rita 12 Stores and RecordFactory 12 7 Stores and Substores na ii did a 12 1 1 MARI Store ne ars an Saba hea Ga da 12 1 2 IPM Stores and ShadowStore ocoocccccoccccnnnccnnnnononononononononnnoronanaronanaronons 12 2 RECOPUFACONY semiak aa a a a aa a ea aaa 13 Deployment and Build System 13 1 Deployment ast agian da 13 2 BUIN System ero rara 13 21 Getting Started musica dr lapa ep 13 2 2 Ant Introduction ish E 2 1 HH Anker he sab ote weg Eee yee Racin 14 Translations TA Ge
18. App is built all the blocks of the architectural stack are identified Then we show some concepts of object oriented programming and how they are translated to WebApp this is not always obvious luckily the Ext JS framework will help us out there Finally we show how and where WebApp can be extended Chapter 1 Introduction 1 1 WebApp WebApp and its plugins are complete as the communication platform of the future The WebApp is essentially a front end for a server side database driven application zarafa server The user interface portion of the WebApp is written using the Ext JS 3 4 framework which provides a desktop like UI with a programming interface WebApp architecture is very flexible allowing community to easily create new plugins contexts or widgets Some useful links to online resources are listed in Appendix B References The latest version of this document is always published online 1 2 Requirements To use WebApp the following is required a web server that is capable of running PHP 5 1 or higher access to a Zarafa server with either a 7 0 version later than 7 0 8 or any 7 1 version the PHP MAPI extension matching the Zarafa server version As for browsers community users only have support for the latest of the following brands e Internet Explorer 9 Firefox e Safari Customers have support for the browser versions which are at most 1 year old but they should refer to the documentation
19. Model and Zarafa core SettingsModel 35 Chapter 9 Data Models The hierarchy model is a separate context see Section 9 3 Hierarchy model For more information refer to the API documentation on the HierarchyContext class and other classes in the same module The settings model is also a separate context see Section 9 4 Settings model For more information on settings refer to the API documentation on the SettingsContext class and other classes in the same module 9 2 Separable model architecture To promote code re use and separation of concepts a separable model architecture is used In essence this is just aMVC Model View Controller design with the view and controller collapsed into a single entity The responsibility of the model is to store and validate data and synchronize with the server On the other side the view controller components present the data to the user allow him to edit the data and generally drive the model The view controller components contain a reference to one or more model objects They interact with the models with method calls and get notified of changes through events This principle is shown in Figure 9 2 Separable model architecture function call Vie wController Model So id gt yenis F Figure 9 2 Separable model architecture Since this design decouples data manipulation and client server communication from the user interface the model part
20. You may also create config php file to set default value for your plugin settings Here goes the example of FB plugin config php file 63 Chapter 13 Deployment and Build System The subfolder names and hierarchy can be changed but it still should stay intuitively understandable Manifest is a file where all the files of your plugin are described The structure should be strict lt xml version 1 0 gt lt DOCTYPE plugin SYSTEM manifest dtd gt lt plugin version 2 gt First block represents the common info about plugin lt info gt lt version gt 0 1 lt version gt lt name gt facebook lt name gt lt title gt Zarafa Facebook Integration lt title gt lt author gt Zarafa lt author gt lt authorURL gt http www zarafa com lt authorURL gt lt description gt Zarafa Facebook Integration allows you to import your Facebook events to Zarafa calendar lt description gt lt info gt Second block describes where to find config file of your plugin lt config gt lt configfile gt config php lt configfile gt lt config gt Third block describes files that are used in your plugin lt components gt lt component gt lt files gt lt server gt lt serverfile gt php plugin facebook php lt serverfile gt lt server gt lt client gt loaded client files should have an attribute load which can take one of three values source debug and release Source are files that you created during develop
21. ZCP trunk build 51963 Zarafa WebApp Developers Manual Zarafa Zarafa WebApp ZCP trunk build 51963 Zarafa WebApp Developers Manual Edition 1 2 Copyright 2015 Zarafa BV The text of and illustrations in this document are licensed by Zarafa BV under a Creative Commons Attribution Share Alike 3 0 Unported license CC BY SA An explanation of CC BY SA is available at the creativecommons org website In accordance with CC BY SA if you distribute this document or an adaptation of it you must provide the URL for the original version Linux is a registered trademark of Linus Torvalds in the United States and other countries MySQL is a registered trademark of MySQL AB in the United States the European Union and other countries Red Hat Red Hat Enterprise Linux Fedora and RHCE are trademarks of Red Hat Inc registered in the United States and other countries Ubuntu and Canonical are registered trademarks of Canonical Ltd Debian is a registered trademark of Software in the Public Interest Inc SUSE and eDirectory are registered trademarks of Novell Inc Microsoft Windows Microsoft Office Outlook Microsoft Exchange and Microsoft Active Directory are registered trademarks of Microsoft Corporation in the United States and or other countries The Trademark BlackBerry is owned by BlackBerry and is registered in the United States and may be pending or registered in other
22. Zarafa WebApp A store is a client side cache of items that exist on the server and provides a clean interface for loading and CRUD create read update and delete operations Many standard Ext JS components use stores to manage the data they display and operate on In MVC Model View Controller terms a store is the default model for many UI components A common example is the grid panel Ext grid GridPanel Displaying a list of tasks in a tasks folder is a matter of constructing a store instance connecting it to the grid and calling the load method with a Folder object as a parameter The grid will automatically issue a generic load command to the store to populate it with data which is then displayed Clie nt Server XML List Module XML Figure 12 2 Data flow Figure 12 2 Data flow shows how the various components connect to get data from the server to display in a data grid in the browser A grid panel is connected to a store which acts as a local cache containing a set of records The store uses a proxy to talk to the server which in turn tasks with a server side list module using the Zarafa communication scheme Figure 11 4 Request Response flow The server has different list modules for each type of data tasks mail etc and there are corresponding stores and proxies on the client Stores can do more than just plain data loading They sup
23. a information to the plugin An example is an insertion point in a context menu where it s useful to pass the menu object Ext menu Menu to the creation function Yet another example is a toolbar in a read mail dialog which might pass the entry ID of the item that is being shown to the plugin container populateInsertionPoint dialog readmail toolbar mailEntryId A plugin is then able to register a function that uses these parameters createButton function insertionPoint mailEntryId return xtype button text Hello handler function alert Message ID mailEntryld y The returned component has an xtype field This field is the unique identifier for that class and is registered using Ext reg together with the corresponding constructor However in most cases you need to use an already existing insertion point 17 Chapter 5 Insertion Points 5 1 Zdeveloper plugin Now while we do not have a list of insertion points in the documentation it is possible to get an overview of them by enabling the zdeveloper plug in Doing so you will be able to visually identify locations where WebApp can be extended it highlights all existing insertion points even those provided by third party plugins Do this by navigating to Settings gt Advanced select Settings zarafa v1 plugins zdeveloper and double click the false to show a checkbox check it to turn the plug in on and
24. and testing the application and also generating documentation are automated in a build system The tool we use is Ant 64 Getting Started An important note here is that the build system is something that Zarafa company use but it is not really mandatory for all plugin developers to use it too Zarafa provides the required tools in the source package but not in the normal installation packages Plugin developers do not require the source package to create plugins so the presence of build xml is also completely optional and only can be present if plugin developers want to use Zarafa building system 13 2 1 Getting Started Prerequisites for using the build system is a Java 6 JDK and Ant Other libraries and tools are kept in svn either as binaries or as source 13 2 1 1 Linux On most distributions both Java 6 and Ant should be in the repositories Make sure you don t get GNU Java gcj but get the sun jdk or openjdk On Ubuntu simply type sudo apt get install sun java6 jdk ant ant optional update alternatives auto java Especially the last line is important since multiple versions of Java can be installed side by side ona system and the default has to be selected explicitly Ant should be installed and configured properly by your package manager 13 2 1 2 Windows Mac These platforms have not been tested but should work The Java 6 JDK can be downloaded from Sun Mac users should already have a working java 6 Apple
25. ass Zarafa plugins facebook data FbEvent JSONReader extends Zarafa core data JsonReader Zarafa plugins facebook data FbEventJSONReader Ext extend Zarafa core data JsonReader Wei k cfg Zarafa core data RecordCustomObjectType customObjectType The custom object type which represents the link Ext data Record records which should be created using link Zarafa core data RecordFactory createRecordObjectByCustomType 2 customObjectType Zarafa core data RecordCustomObjectType ZARAFA_FACEBOOK_EVENT Jr constructor param Object config Configuration options y constructor function meta recordType meta Ext applyIf meta alah Vail idProperty id dynamicRecord false y If no recordType is provided force the type to be a recipient if Ext isDefined recordType recordType Zarafa core data RecordFactory getRecordClassByCustomType meta customObjectType this customObjectType Zarafa plugins facebook data FbEventJSONReader superclass constructor call this meta recordType H Plugin JSON writer can be found for example in Spreed attachments JSON writer 55 Chapter 12 Stores and RecordFactory Ext namespace Zarafa plugins spreed data JER class Zarafa plugins spreed data SpreedJsonAttachmentwriter extends Zarafa core data JsonAttachmentwriter yp Zarafa plugins spreed data SpreedJsonAttachmentwriter Ext extend Zarafa core data
26. at serve as the basic unit of organization for messages Arranged hierarchically folders can contain messages and other folders Folders make it easier to locate and work with messages MAPI store uses such parameters to build a hierarchy as entryid parent_entryid and store_entryid entryid is an id of current object in MAPI structure for example of the store with calendar appointments parent_entryid is used to unite this object with hierarchy so for a store with calendar appointments it would be an entryid of a folder with calendar store store_entryid is a value that represent an entryid of current item s store For example for a store with calendar appointments it would be an entryid of IPFStore the main store where all stores belong A MAPI folder can be seen as a flat list of items much like a table in a database Instead of directly issuing action requests from the client to list or mutate items a high level API is provided that exposes a MAPI folder as an Ext JS store Ext data Store Refer to chapter mapi store for more information on MAPI Store 46 Chapter 11 Communication 11 1 Conceptual Overview The back end has a pluggable architecture with functionality divided among a set of modules Each module is a named entity such as maillistmodule or taskitemmodule or for Spreed plugin class spreedmodule and exposes a specific part of the Zarafa server functionality The client communicates with a module
27. ata DialogTypes Zarafa core Enum create Wits The dialog with empty fields Brandly new property type Number 27 EMPTY 1 frz The dialog with filled subject and participants property type Number 77 Appendix A Coding Standards 7 FILLED 2 pike The dialog with only participants field prefilled property type Number ag PARTICIPANTS_FILLED 3 y 78 Appendix B References Spreed Meeting plugin Zarafa WebApp homepage e Zarafa WebApp API reference e Zarafa WebApp user manual Zarafa WebApp developers manual 79 80
28. by sending it one or more actions Each request may contain one or more actions for one or more modules Several modules may implement the same actions Such as list so actions are grouped by target module The server processes each of the actions ina sequence and formulates a response also containing actions The process is shown in Figure 11 1 Message exchange Figure 11 1 Message exchange A Client Server A a Er al NN T T l L l l A l a 1 1 on ME _________ Action ie A I TER EN ity H ee l l ee I loj loj ae a l i 7 Action Il nn MN ARS H I Teen l l l l l Although there is usually a one to one mapping between request and response actions this does not neccesarily have to hold As an example consider the situation in Figure 11 2 Message exchange for creating a new item client request and Figure 11 3 Message exchange for creating a new item server response In this exchange the client wants to create a new task and sends save action to the tasklistmodule on the server as shown in Figure 11 2 Message exchange for creating a new item client request If successful the module on the server side responds with an item action with information about the created task such as the generated entry ID but it will also send a folderupdate action containing updated information abou
29. click Apply Then log out and back in again You will immediately notice why this plugin is disabled by default Firefox A Zarafa WebApp A https email zarafa com webapp trunk index php Zarafa Salenda Contact Task IN main maintabbar left WINE TUT gt bf Ra C main toolbar actions m z v main toolbar actions last Mail Inbox Ih Page 10f39 gt M cont By Open I Search in Inbox amp Print My Mail N I From Subject Show all folders Reply a amp Inbox Michael Scofield htmleuh CNN com International Head A Reply Al f Deleted Items 13 CNN Poli The CNN Political Ticker Mor gt Forward BG Drafts 1 BBC Bre UK soldiers killed in Afghani htmiasi CNN com International Headli context mail contentmenu actions A K BBC Bre Spain trounce Italy to win Eui E Essentials Equipment Bs Later 1 BBC Bre Barclays chairman Agius to r D Junk E mail 4 E Categories gt Vv Y Ba Escape Plans Mark Unread Ey Outbox previewpanel toolbar left 4 DASS Feeds B Sent tems 3 Today s headlines from CNN E set20120118 121 CNNMorningNews lt mailings mail cnn com gt Sent Monday 2nd July 2012 11 32 E Public Folders To Michael Scofield lt m scofield zarafacom gt Ei Favorites previewpanel toolbar detaillinks 3 By Public Folders Opens Create E Mail Delete sen B TM context mail mailcreatedialog toolbar actions zu TTA cantes mat materesesao
30. cord instanceof Zarafa addressbook AddressBookRecord switch type case Zarafa core data SharedComponentType common create case Zarafa core data SharedComponentType common view case Zarafa core data SharedComponentType common contextmenu if record store customObjectType Zarafa core data RecordCustom0bjectType ZARAFA_SPREED_PARTICIPANT record instanceof Zarafa addressbook AddressBookRecord bid 2 break case Zarafa core data SharedComponentType common dialog attachments if record instanceof Zarafa plugins spreed data SpreedRecord bid 2 ui break F return bid When the plugin is the highest bidder the function getSharedComponent will be called to actually deliver the class to be constructed as component ites Will return the reference to the shared component Based on the type of component requested a component is returned param Zarafa core data SharedComponentType type Type of component a context can bid for param Ext data Record record Optionally passed record return Ext Component Component 8 getSharedComponent function type record var component switch type case Zarafa core data SharedComponentType common create case Zarafa core data SharedComponentType common view component Zarafa plugins spreed dialogs EditSpreedParticipantDialog break case Zarafa core data SharedComponentType common contextmenu component Zarafa plugins
31. countries Zarafa BV is not endorsed sponsored affiliated with or otherwise authorized by BlackBerry All trademarks are the property of their respective owners Disclaimer Although all documentation is written and compiled with care Zarafa is not responsible for direct actions or consequences derived from using this documentation including unclear instructions or missing information not contained in these documents The Zarafa Collaboration Platform ZCP combines the usability of Outlook with the stability and flexibility of a Linux server It features a rich web interface the Zarafa WebApp and provides brilliant integration options with all sorts of clients including all most popular mobile platforms Most components of ZCP including Zarafa WebApp are open source They are licensed under the AGPLVv3 and can therefore be downloaded freely as ZCP s Community Edition This document the Zarafa WebApp Developers Manual describes how to create additional components for Zarafa WebApp This allows third party developers to either extend Zarafa WebApp with more functionality or even to integrate it with some existing application 5 http creativecommons org licenses by sa 3 0 j http www gnu org licenses agpl 3 0 html i http www zarafa com content community I WebApp Introduction 1 Introduction LL WOEDAPP tit rd a trad 152 Requirements za nes decis citan eco facet cas led coded ens Laden ace eae een iia 1 3 Do
32. cument Structure OVervieW eessenenssensnnnnnsnnnnsnnnnnnnnsnnn nen nnnnnnsnennnnnnnnnn nn 1 4 Examples uri ms hl Ban np evades ut Rebe a be Henn gr Fi ne 1 4 1 Facebook Events moniin ei idi e i id ii d id e i nenn 1 4 2 Spreed mMeetings aenaran A data 1 4 3 Facebook Widget ostien ia a a i aaia an a La iaa eaa 2 Architecture Overview 3 Ext JS and OO Javascript O OO 3 2 ACCESSING COMPONENTS ussssssssnennsnnensnennnnnnnnnnnnnnnnnnnnnnnennnnnnnnnnnnnnnnnnnnnnnnn 3 3 ENUM See Aaaa aiaa Taa S utucteerteduekenuteludcsfesvedl autniteaytedecteutietetietaaved satan 3 45 SIMNGIETONS aa 2 BR beh laces nck aa eto es rada 4 Extending WebApp 4 1 Ways of Extending WebApp cc ceceeceeeee eee ee eeee ae eeeeeeeeaeeeeeaeeesaeeeeaaeeeseeeeaaees ll Extending WebApp 5 Insertion Points 5 1 Zdeveloper plo ir I ih lee 5 2 Example adding a button 4essssssssnennnnnnnnsnnnnnnnnnnnnnsnennnnnnnnnn nenn nnnnn nen 6 Widgets 6 1 Creating a widget un en ee nr ae are 6 2 Widget configur tion nen a rue oe cage sk hen ern OSs TO ENGER ERDE EDER ENTER 7 Dialogs di Events a ner ns iii AS NT 1 3 Dealing with MAPI record S cotorra tere date 7 3 1 Displaying a TecoOrd u 0 nenn in ann Lin 8 Bidding System 8 1 Bidding and insertion points e eect e eee ee eee e eee etre settee aa eeee eee aa eee ae eeeaeeeeaa 8 2 4 010 4 1 0 sii PRPFUERRRELFENEEORFEREEREELE
33. de that is common to all contexts and plugins e ui common UI components value pickers form panels e dialog dialogs used by multiple contexts context context specific code i e freebusy mail contact etc e ui Ul components used exclusively in this context dialog context specific dialogs e plugins Zarafa standard plugins e widgets Zarafa standard widgets A 1 2 Naming Packages and Classes Package names are lower case except the top level Zarafa package Class method and field names follow Java conventions classes are camel case starting with a capital letter i e CalendarMultiView MailStore methods and fields start with a lower case letter i e getParentView load folderList The package class structure follows the folder file structure much like with a Java project For instance Zarafa calendar ui CalendarPanel can be found in zarafa calendar ui CalendarPanel js Most complex classes will have their own file Small trivial classes that are used from only one place may be placed inside another class s file A 1 3 Naming Insertion Points Insertion points also follow a hierarchy Top level e Main application main e Hierarchy panel hierarchy Contexts context name i e context task context mail e Plug ins plugin name i e plugin folderstatus plugin sugarcrm 73 Appendix A Coding Standards Widgets widget name i e widget clock widget news Common nod
34. e with the exception that properties are defined only once and become immutable Any redefinition of the property is ignored The following example illustrates the use of properties and how redefinitions are ignored lt project name example2 default all gt lt property name foo value bar gt lt property name foo value not bar gt lt Will output bar gt lt echo message foo gt lt project gt This mechanism is used by ant build files calling other build files If an ant file calls another ant file to build a sub project for instance the caller may override properties in the callee to set configuration switches output directories and so forth Properties in ant build files may also be overridden from the command line Running the above example with and Dfoo foo would cause ant to echo foo Ant is a build system that can be both powerful and frustrating and it is certainly quite different from tools like make or scons For more information please refer to the Ant manual 13 2 3 Tools The build system uses several tools to accomplish various tasks Some of these are third party and some of these are custom 13 2 3 1 JsConcat Large Ext JS applications tend to be made up of many individual files Our naming convention dictates that most classes are defined in their own files When the application is deployed all these files are bundled together by concatenating them into a single JavaScript file
35. e types Dialog dialog name i e dialog edit e Context menu contextmenu Tool bar toolbar e Status bar status Most common insertion points names are of the following structure main hierarchy context context name plugin plugin name widget widget name dialog dialog name contextmenu toolbar status A 2 Coding Style Guidelines In order to maintain consistency a few guidelines shall be followed in the WA projects Placement of brackets Function declarations shall always have brackets on a new line getModel function return this model If else statements shall use a condensed style if item isXType zarafa recipientfield item setRecipientStore record getRecipients else item setValue value When an if statement scope only consists of one row then the brackets should also be present if this bodyInitialised this initBody Never use single line if statements WRONG if this bodyInitialised this initBody For the ternary operator one line is ok iconClass record isRead icon_mail_read icon_mail_unread It s also highly recommended to use tabs instead of usual four spaces characters in indentation as long as each developer can determine whether he wants his editor to show the appropriate number of spaces for each indentation of the code 74 Documentation After the first charachter spaces are used A 3 Documenta
36. e wants them 51 Chapter 11 Communication Notifications cannot be processed by the ResponseHandler provided by the requestee that response handler is dedicated to handling the response for the request that s why an alternative route is required When a response is received for which no ResponseHandler has been registered the ResponseR outer will give the response data to the Zarafa core data NotificationResolver This NotificationResolver will analyze the response and return a ResponseHandler which is suitable for handling this response Figure fig rspnsrtr With this ResponseHandler the ResponseRouter can then continue its normal procedure to deserialize objects handling the actions and updating Ext data Store objects Refer to API documentation for more information g http developer zarafa com webapp class Zarafa core ui notifier Notifier 52 Chapter 12 Stores and RecordFactory 12 1 Stores and Substores When you need to save and keep some information you should use stores Figure 12 1 Store types shows different types of stores at their hierarchy MAPIStore C usiore gt C trrsiore gt ShadowStore PluginStores istModuleStore HierarchyStore IPFSubStore PluginSubStores CMAPIFolderSubStore AddressBookStore App QLO ContactStore NoteStore Figure 12 1 Store types 12 1 1 MAPI Store Zarafa MAPi Store is an extension of the Ext JS store which adds support for the open command w
37. ecommendations for the code style to use concerning comments and documentation 1 4 Examples The manual frequently gives code examples These are taken from the Facebook Events plugin the Spreed Plugin and the Facebook widget plugin The Facebook Events plugin and the Spreed Meeting Plugin are published as separate projects the Facebook widget is part of the WebApp package 1 4 1 Facebook Events The core example of this manual will be the Facebook Events integration plugin The Facebook Event plugin allows the WebApp user to copy Facebook events to his Zarafa calendar When the Facebook button in the navigation panel of the user s Calendar is clicked for the first time he ll be asked to login to Facebook and provide Zarafa WebApp access to your personal data After getting confirmation you ll see the progress bar while the event list is loading After this you ll see the list of all your events selected Unchecking unnecessary events you can select which events to import Your Facebook events will be added as new Zarafa events of special type For the next time you can synchronise data by clicking the same button in the Calendar Navigation Panel The period of the events in the future to import can be specified in settings 1 4 2 Spreed meetings The Spreed Meeting plugin allows the user to setup Spreed meetings online web meetings directly from Zarafa WebApp A spreed conference can be started from an existing email and the part
38. ecord to IPM Note we can use the statement as follows Zarafa core data RecordFactory setBaseClassToMessageClass IPM Note Zarafa core data IPMRecord Now all new Record instances of Zarafa core data IPMRecord for IPM Note will inherit from Zarafa core data IPMRecord The same example with Spreed plugin Zarafa core data RecordFactory setBaseClassToCustomType Zarafa core data RecordCustom0bjectType ZARAFA_SPREED_ATTACHMENT Zarafa core data IPMAttachmentRecord Inheritence for the messageclass works quite simple The inheritence tree for Message class is IPM gt IPM Note gt IPM Note test gt IPM Contact When a field default value or base class is assigned to IPM it is automatically propogated to IPM Note and PM Contact These values can simply be overridden within such a subdefinition For example Zarafa core data RecordFactory addFieldToMessageClass IPM name body 1 Zarafa core data RecordFactory addFieldToMessageClass IPM Note name from D Now all Record instances of IPM IPM Note and IPM Contact will contain the field body but only IPM Note will have the additional from field If we now extend our example with default values Zarafa core data RecordFactory addDefaultValueToMessageClass IPM body test Zarafa core data RecordFactory addDefaultValueToMessageClass IPM Contact body contact 61 Chapter 12 Stores and RecordFactory The record ins
39. ents or callbacks Consider the code example listed below A call is made to the request object a global instance of which can be obtained from the container using getRequest to retrieve a single message The first two arguments are module name and action type which are taken from enumeration objects Zarafa core ModuleNames and Zarafa core Actions respectively note that the unique request identification as mentioned earlier is auto generated by the Zarafa core Request Class The third argument is a Javascript object containing the parameters to the action which in this case are the message s MAPI store Id and MAPI entry Id container getRequest singleRequest pluginNAMEmodule e g REMINDER actionToPerform e g reminderlistmodule data inclufed in action tag actions actions 49 Chapter 11 Communication 11 4 Response Handlers As described in the previous section a client should be able to handle the response data which is being send back from the server For this we use Zarafa core ResponseRouter in combination with Zarafa core data AbstractResponseHandler objects Whenever the Zarafa core Request has received a response from the server it will send this response to Zarafa core ResponseRouter which can then send out some events and process the response To notify the requestee of the initial request for which the response was received a Zarafa core data AbstractResponseHandler is used As d
40. escribed in the previous section a request can be created using the singleRequest function this function has however a fourth argument The Zarafa core data AbstractResponseHandler object container getRequest singleRequest Zarafa core ModuleNames getListName moduleName actionToPerform setting parameters new Zarafa core data ProxyResponseHandler proxy this action Ext data Api actions update options parameters When a Request is made with the help of ResponseHandler object the Zarafa core Request object will first generate a new Request idenfitication number and then register the ID together with the ResponseHandler to the Zarafa core ResponseRouter After receiving a new response the Router will search for all ID s and use the registered ResponseHandler for processing this response Figure 11 5 Different class diagrams The ResponseHandler which is used in the above example is a basic implementation which provides the basic communication with the Ext data DataProxy which made the request Its primary task is checking for errors and firing the appropriate event in the Ext data DataProxy when a request has failed See the class Diagram below for the various Response handlers AbstractResponseHandler ProxyResponseHandler o Po extends mande LK V lt gt extend extends extends NotificationResponseHandler IPMResponseHandler AddressbookResponseHandler RemoteWiteR
41. esponseHandler LE o FSGABTADA EN doltem 1 1 IPMProxy AddressbookProxy RemoteWipeProxy Figure 11 5 Different class diagrams 50 Notifications 11 5 Notifications In some situations the user might want to be notified of particular events for example Errors Warnings New mail etc There are various methods to display such a message to the user To streamline the interface the Zarafa core ui notifier Notifier class is provided which is accessible as singleton object through the Container class using container getNotifier The Zarafa core ui notifier Notifier class holds references to various Zarafa core ui notifier NotifyPlugin plugins Each plugin provides a single method for displaying the message to the user For example the ConsolePlugin will send all messages to the browser console the MessageBoxPlugin will show an Ext MessageBox for each message Creating a new plugin only requires that Zarafa core ui notifier NotifyPlugin is extended which only requires the notify function to be overridden The plugin itself must then be registered with a unique name For example container getNotifier registerPlugin console new Zarafa core ui notifier ConsolePlugin When using the Notifier class to display a message to the user one simply has to call the notify function on the Notifier container getNotifier notify error Panic This is a very serious panic The first argument is the categ
42. ext 2 gt JavaScript TRANSLATORS Comment Extra comment _ English text TRANSLATORS Comment Extra comment _ English text 70 Server Side For the extraction of the translations from the JavaScript files gettext offers the utility xgettext However this utility cannot read a JavaScript file To make it work we set the language to Python yes that is not a joke The downside of this is that comments directed at the translators need to be formatted a certain way Python does not understand the JavaScript comments so we need to add a on every line preceeding the gettext function Also when you are using the multiline comment the last line must contain the character 14 2 Server Side On the server side the PHP has by default some gettext functions implemented already It still misses a few though That is why the of the WebApp server side implements the following functions pgettext npgettext dpgettext and dcpgettext More information about the default PHP functions can be found at http Avww php net gettext 14 2 1 Implemented Functions on the Server Side PHP misses the context gettext functions and that is what the WebApp implements The msgctxt argument supplies the context of the translation The msgid is the translatable string The different functions implement the context together with the normal gettext function plural domain and category gettext functions l
43. ext translation iconCls icon_spreed_setup handler this setUpMeeting scope this Hl 14 1 Gettext Information about the GNU gettext project can be found at http www gnu org software gettext 69 Chapter 14 Translations GNU gettext allows us to supply the entire WebApp in the language of the user s choosing It also allows the developer to implement plural translations and context based translations With plural translations you can have gettext handle whether you should use a singular or plural translation PHP lt php echo sprintf ngettext Deleted s file Deleted s files count count gt JavaScript ngettext Deleted s file Deleted s files count sprintf count Context based translations allows you to translate the same word in English but different in other languages You add a context in which you specify where you use the translatable text and gettext can distinquish the different strings PHP lt php echo pgettext Menu Open echo pgettext Dialog toolbar Open gt JavaScript pgettext Menu Open pgettext Dialog toolbar Open For developers it is also possible to add commentary for the translators You can do this by adding the following comment to the code just above the gettext function PHP lt php TRANSLATORS Comment Extra comment 27 _ English text TRANSLATORS Comment Extra comment _ English t
44. f for example rename variables make functions inline etc 4 http code google com p ext doc 67 68 Chapter 14 Translations Zarafa WebApp provides a multilanguage interface The language can be switched in settings See Figure 14 1 Languages changed in settings Oem Account information Alexandra Stepanchuk Favorite settings Mail Display Name Alexandra Stepanchuk bn Signatures E9 Calendar E mail a stepanchuk zarafa com Out of Office Assistant Advanced Language English aN English Italiano Nederlands nwy English US Deutsch Pyccxu Francais PX Apply Discard Figure 14 1 Languages changed in settings The WebApp uses GNU gettext for translating In your js code just rememer to translate each string label using _ your string label Example Create all buttons which should be added by default the the Actions link Ext ButtonGroup ButtonGroup This will create link Ext ButtonGroup ButtonGroup element with Spreed setup button return Array The link Ext ButtonGroup ButtonGroup elements which should be added in the Actions section of the link Ext Toolbar Toolbar private yf createActionButtons function return xtype button text _ Setup Meeting button text translation tooltip title _ Setup Meeting tooltip title translation text _ Setup meeting with provided details tooltip t
45. folder hierarchy container getHierarchyModel load Once the hierarchy has been successfully loaded it can be queried for stores folders default folders etc Get the calendar folder used in the Facebook plugin var calendarFolder container getHierarchyStore getDefaultFolder calendar in convertToAppointmentRecord we create a new record of appointment type so we need to set parent_entryid of this new record to entryid of the needed folder and store_entryid of this new record to store_id which is store id hierarchy var calendarRecord facebookEventRecord convertToAppointmentRecord calendarFolder 9 4 Settings model The settings model is a tree of key value pairs that is saved to the server It is loaded once when the application loads however writes are always committed immediately All plugin developers should implement a settings module to enable and disable their plugins or widgets There is a separate settings page for plugins that becomes visible if you use the zdeveloper plugin see Section 5 1 Zdeveloper plugin Here you can let the user configure any options in your plugin if the need arises to make something configurable For widgets the recommended approach is to create a config method see Section 6 2 Widget configuration for an explanation and example If you want your plugin to be enabled disabled by default you may create a config php file to set default values for your plu
46. function container registerwidget Zarafa widgets FBwWidget Tibi _ Facebook plugins facebookwidget resources images facebook png H 6 2 Widget configuration To allow the widget to do something you need to add the custom functionality inside the class In our example we save the URL of the site which activity we want to monitor in the widget s settings To use them we need to initialize parameter hasConf ig in constructor and set it to true For example here is the part of the constructor that tells this to the widget framework constructor function config config config Ext applyIf config name fb height 600 hasConfig true H E By default if you use WebApp for the first time the Today and Tasks widgets are visible 2 Globally Unique Identifier 3 You can see this in the Advanced tab of the settings 23 Chapter 6 Widgets After this the gear icon will appear in the right top corner of the widget See e g Figure 6 1 Widget settings Today A Facebook http zarafa com A Xx MocneaHme CODbITMA facebook gt WebApp 2 NOABSOBAaTEAA PEKOMEHAYIOT 3TO Figure 6 1 Widget settings When you click on this icon the config method of the widget will be called In this method we can setup the widget s settings dialog and show it TEE Called when a user clicks the config button on the widget panel Shows the window with url field where
47. g name spreed H Zarafa plugins spreed SpreedPlugin superclass constructor call this config this init A 3 4 Documenting Methods The following listing shows how to document methods Parameters can be specified using param with a type name and description The method name will be extracted automatically but if for any reason this fails adding method name will solve that If an argument is an optional one can make this explicitly by using optional as exemplified by the errorCallBack parameter For method which are private only visible for the own class then private annotation shall be added Do not use the old way of describing private private in the method description and or with one less in the comment opening If this old documenting format is found in the code base it shall be updated to use private Similar to link Ext data Jsonwriter toHash Convert recipients into a hash Recipients exists as link Zarafa core data IPMRecipientRecord IPMRecipientRecord within a link Zarafa core data IPMRecord IPMRecord and thus must be serialized seperately into the hash object param Ext data Record record The record to hash return Object The hashed object override private y toPropHash function record i 76 Documenting Insertion Points code return hash A 3 5 Documenting Insertion Points Insertion points should be documented just after t
48. gin settings Here is an example from the Facebook plugin s config php file 38 Settings model Disable the facebook plugin for all clients define PLUGIN_FACEBOOK_USER_DEFAULT_ENABLE false PLUGIN_FACEBOOK_ENABLE is used in the injectPluginSettings function in plugin facebook php here are the contents of that file pits Facebook Plugin Integrates Facebook events in to the Zarafa calendar ey class Pluginfacebook extends Plugin Constructor 2 function Pluginfacebook Hotes Function initializes the Plugin and registers all hooks return void function init this gt registerHook server core settings init before Utes Function is executed when a hook is triggered by the PluginManager param string eventID the id of the triggered hook param mixed data object s related to the hook return void a function execute eventID amp data switch eventID case server core settings init before this gt injectPluginSettings data break s Called when the core Settings class is initialized and ready to accept the sysadmin s default settings Registers the sysadmin defaults for the Facebook plugin param Array data Reference to the data of the triggered hook Hf function injectPluginSettings amp data data settingsObj gt addSysAdminDefaults Array zarafa gt Array v1 gt Array plugins gt Array facebook gt
49. gs A plugin that requires a component like a dialog context menu or a preview panel can ask the container to get it a specific type of the shared component The container will start a bidding round across all the registered plugins and each plugin will be able to bid and the highest bidder is asked to deliver this component The system makes it possible to implement a dialog for reading mail by a mail context and the dialog for showing an appointment or a meeting request by the calendar context 31 Chapter 8 Bidding System l l l OpenDialog N I l getSharedComponent type record N M l bidSharedComponent type record x bidSharedComponent type record aeteharedComponent iypo record E nn component class K 4 component class 2 2 gt 3 4 l l lt lt creale gt gt N ME i l 1 l l Figure 8 1 Shared Component bidding sequence 8 3 Bidding on a shared component When the shared component is requested a component type is also supplied This can be used to bid more detailed based on the component type The various component types are defined as valuess in the enumeration Zarafa core data SharedComponentType Other types can be added using the addProperty method of the enumeration Next to the type of the component a record can also be added as an argument The following snippet of code
50. guration property is navigationContext used here for our Facebook button to be displayed only when Calendar context is the active one After specifying all the necessary properties for items to insert we should register our plugin by calling the following function Zarafa onReady function if container getSettingsModel get zarafa vi plugins facebook enable true container registerPlugin new Zarafa plugins facebook FacebookEventsPlugin y Zarafa onReady function is called when all essentials have been loaded and Container is ready for work so it is high time for plugins to start their work container getSettingsModel function is used 20 Example adding a button to check in Settings if the plugin is enabled More information about Settings can be found in the corresponding chapter settings container registerPlugin function registers the plugin itself for work So our Facebook button looks like in Figure 5 2 New Facebook button in Calendar Context Z Calendar Contact Tas Note You are logged on as Zarafa Test Sett Bac aa Zarafa Calendars Calendar 4 16 20Apri2012 gt ap S 4 April 2012 gt Search in Calendar Yo 2 2 2 al Aa dal 4 A 9 10 nu 12 13 14 15 16 v 83 B 2 a zn 5 23 24 25 26 27 28 29 12 o BP tad My Calendars 15 0 A Show all folders Br ed gg Calendar Open Shared Calendars 17 00 coh eta 19 20 E ta Imp
51. he class declaration The name of the insertion point can be specified using insert with a name of the insertion point Parameters can be specified using param with a type name and description For example populating insertion point for new menu item Zarafa core ui MainToolbar Ext extend Zarafa core ui Toolbar Insertion points for this class ee insert main maintoolbar new item Insertion point for populating the New item menu It will be placed in the item part of the list Each item inserted to this list is accessible from all contexts param Zarafa core ui MainToolbar toolbar This toolbar Sy population of insertion point itself var itemMenu container populateInsertionPoint main maintoolbar new item this A 3 6 Documenting Enumerations An example of documenting enumeration is Spreed Dialog types enumeration An enumeration is declared using the class statement inside a multi line comment One can use extends to indicate that the enum extends Zarafa core Enum A description of the class follows these two statements Optionally the singleton statement can be used to declare the class a singleton Each property of the enum should be documented telling what it means and what type it is picid class Zarafa plugins spreed data DialogTypes extends Zarafa core Enum Enum containing the different types of dialogs needed to display spreed meeting singleton Ey Zarafa plugins spreed d
52. hich is not recommended 12 1 2 IPM Stores and ShadowStore The Zarafa implementation of the Ext data Store is the IPMStore Refer to Figure 12 4 IPM Store explanation This Store contains IPMRecords and any IPMRecord must always belong to an IPMStore Each IPMStore is managed by the IPMStoreMgr singleton The IPMStore has two base classes the first one is the ListWoduleStore which is used in each Context to list all IPMRecords which must be displayed in the Context 57 Chapter 12 Stores and RecordFactory Figure 12 3 Store UML diagram The second one is ShadowStore contains IPMRecords which are currently being edited within a Dialog this includes new IPMRecords which must still be created on the server side 58 RecordFactory subtree_entryid IPMSubtree entryid default_calendarfolder_entryid entryid ontainer class entryid Personal Calendar entryid Mail Folder entryid subFolde parent_entryid Figure 12 4 IPM Store explanation When a Dialog starts editing a IPMRecord it must copy the IPMRecord to the ShadowStore and work on that copy When a Dialog closes it must remove record from the ShadowStore after optionally saving the IPMRecord to the server Any events from a IPMStore regarding the update for IPMRecords will always be caught by the IPMStoreMgr and raised as separate event from this manager Any Ul Component which contains an IPMRecord must listen to the IPMStoreMgr for eve
53. hich is used by MAPI to request additional data for a record An important note here is that Zarafa core data MAPIStore is not a store itself but is used to collect MAPI Messages For example Ext namespace Zarafa plugins facebook data class Zarafa plugins facebook data FbEventStore extends Zarafa core data MAPIStore This class extends MAPIStore to configure the proxy and reader in custom way Instead of defining the records dynamically reader will create link Zarafa plugins facebook data fbEventRecord instance NS 53 Chapter 12 Stores and RecordFactory Zarafa plugins facebook data FbEventStore Ext extend Zarafa core data MAPIStore eta constructor param Object config Configuration object constructor function config config config Ext applyIf config reader new Zarafa plugins facebook data FbEventJSONReader og alt idProperty id dynamicRecord false 3 writer new Zarafa core data Jsonwriter proxy new Zarafa core data IPMProxy y Zarafa plugins facebook data FbEventStore superclass constructor call this config y Ext reg facebook fbeventstore Zarafa plugins facebook data FbEventStore This is a code example of Facebook plugin We use the MAPI interface for compatibility with Microsoft Outlook As far as MAPI provides full control over the messaging system it is convenient to use it in
54. his class integrates Spreed plugin in existing system It allows user to setup spreed web meeting settings Zarafa plugins spreed SpreedPlugin Ext extend Zarafa core Plugin class code A 3 2 Documenting Fields Within a class configuration fields which are configured using the config parameter in the constructor must be added and documented These fields must be documented using the c fg within a multi line comment Zarafa plugins spreed SpreedPlugin Ext extend Zarafa core Plugin Ye Contains link to the spreedStore class initialized once when plugin is created property type Object private Sy spreedStore null i http code google com p ext doc wilist 75 Appendix A Coding Standards Unique id which works instead entryid for SpreedRecord property type Integer private sequenceld 0 code A 3 3 Documenting Constructors Constructors must be documented inside a multi line comment Use constructor to mark the function as a constructor Other than that the function is simly documented as a regular function It is recommended but not mandatory to use single line comments which will not be parsed for online documentation to document configuration value overrides for the superclass or constructor param Object config Configuration object constructor function config config config Ext applyIf confi
55. ibed in Chapter 5 Insertion Points are perfect for extending WebApp in predefined places with a small additions Next to this another way of extending functionality is to override existing user interface components The way WebApp decides which user interface class to use when presenting some kind of data is called the bidding system WebApp allows all components to bid on functionality The way this works roughly is that WebApp will ask all registered plugins to place bids on something and the highest bidder is chosen to deliver the functionality The shared component system is not meant to be used for each and every button but for components of some magnitude This is due to the time it takes to ask each component to place a bid so for items that need to be shown often and quickly the system is too slow Therefore if we would use the shared component system for these smaller components as well it will have a negative effect on the performance Dialogs and preview panels are examples of components that are suitable for the bidding system it takes a lot of time to initialize them anyway so the bidding rounds don t have a noticeable negative impact there For smaller components a more suitable approach is to use an insertion point these are easily iterated over in rapid succession 8 2 Working The shared component bidding system is a mechanism to prevent tight coupling between plugins and allowing plugins to override existing dialo
56. icipants meeting subject body attachments will be copied from that email Or alternatively a completely new meeting can be set up In any case the user can edit any of the meeting details before starting it 1 4 3 Facebook widget Finally the Facebook widget plugin allows the user to follow activity on Facebook It is possible to select any account by default the Zarafa Facebook page is followed http www zarafa com 7 http www zarafa com content introduction spreed web meeting integration Chapter 2 Architecture Overview Zarafa WebApp was developed to provide possibilities for third party developers to add new or build upon existing functionality These developers have the choice to build a plugin or a widget but all components are easily extensible and allow easy and fast integration with Zarafa WebApp The base framework for Zarafa WebApp is Ext JS a Javascript toolkit built by Sencha The Ext JS toolkit was founded on a solid object oriented inspired design using classes and inheritance which makes it particularly suitable for a complex application as this WebApp is developed using the same extensible structures as those provided by Ext JS so that the WebApp code integrates well with existing Ext JS components Figure 2 1 WebApp architecture overview shows the rough architecture of WebApp The application framework provided by Zarafa builds on the Ext JS library to provide all the functionality that
57. if you already know where to look you can use it to get the exact name of the insertion point that you need For all the rest such as finding out the exact type of the object you should return when registering to an insertion point you still need the API reference documentation 5 2 Example adding a button The following code snippet shows an example with the Facebook events integration plugin Zarafa plugins facebook FacebookEventsPlugin Ext extend Zarafa core Plugin Poked constructor param Object config Configuration object 2 constructor function config config config Zarafa plugins facebook FacebookEventsPlugin superclass constructor call this config this init ores Called after constructor Registers insertion point for facebook button private ey init function this registerInsertionPoint navigation south this createFacebookButton this Pits Creates the button by clicking on which the Facebook will be imported to the Zarafa calendar return Object Configuration object for a link Ext Button button private 7 createFacebookButton function var button xtype button text _ Import Facebook events iconCls icon_facebook_button navigationContext container getContextByName calendar return button y Zarafa onReady function 19 Chapter 5 Insertion Points if container getSettingsModel get
58. ing card layouts to switch between them aC Zarafa Mail amp stuff Page 1 of 1 A i nar Sc aT lt All Folders Search in stuff PY We have finally done it Felix Bartels lt f bartels zarafaserver de gt Show all folders f B From Received i Sent Mon 20 Feb 2012 11 08 gt Assessment of the fi nth 2 To All lt all zarafa com gt A amp Inbox Alexandra Stepanchuk 152 Calendar amp John van der Kamp Tue 13 03 2012 14 26 v That s the best sign of success someone is searching for a Zarafa key in a Warez bulletin board Q Contacts RE Upgrade to Jenki f Deleted Items A Dratts 2 oe DEE http www boerse bz hard software andere betriebssysteme linux 1020437 suche zarafa open source 3 ES Inbox groupware htm Es Important 2 Naomi de Jonge Tue 13 03 2012 09 45 y Es JIRA notifications 9 8 2 Demo 0 gt Meeting notifications S Mirjam Scholtes Wed 07 03 2012 10 56 Y Zarata New sday 8 March 2012 it freundlic rub E gt welcome Z N T M 1 Mit freundlichem Gru Journal amp Mirjam Schotes Mon 05 03 2012 15 52 N Felix Bartels Junk E mail How to deal with Press at CeBIT Sales and Customer Relations Ba Misc info 49 511 22001980 9 Mirjam Scholtes Mon 05 03 2012 12 06 notes os Tuesday 6h raf Ci ible E Bioutbox 2 Zarata Nev y L 1 Zarafa Open Compatible Enterprise DASS Feeds 2 Nathanael van Toorn Fri 24 02 2012 18 09 Y B Sent Items businesscards News Zarafa is the most popula
59. lly the EditRecordDialog automatically places all edited IPMRecords into the ShadowStore For further explanation of the shadow store and why it is relevant see Section 12 1 2 IPM Stores and ShadowStore See Figure 7 1 RecordDialog UML diagram for how they relate to eachother 28 Displaying a record Figure 7 1 RecordDialog UML diagram 7 3 1 Displaying a record When adding a Panel to the RecordDialog or EditRecordDialog it is recommended to extend the RecordDialogPanel This Panel will take the RecordDialog update features into account and automatically updates the Panel when the RecordDialog signals a change in the IPMRecord for this Dialog Any subclass of RecordDialogPanel is required only to implement the function update record which will be called when the Record is updated The constructor of the subclass does not receive a record field furthermore the constructor must assure that any components which display particular fields of the IPMRecord are initialized to display a default value i e undefined or an empty string When the Dialog is rendered the update record function will be used to set the IPMRecord for the first time Both the RecordDialog and EditRecordDialog offer default buttons for the Toolbar for saving and deleting the IPMRecord which is contained in the Dialog 29 30 Chapter 8 Bidding System 8 1 Bidding and insertion points Insertion points as descr
60. m dialog This is just the definition of the dialog and its contents it does not yet make it available to WebApp yet Ext namespace Dialogs dialogsexample dialogs ote class Dialogs dialogsexample dialogs SimpleDialog extends Zarafa core ui ContentPanel The simple dialog which contains Ext panel xtype simpledialog Sy Dialogs dialogsexample dialogs SimpleDialog Ext extend Zarafa core ui ContentPanel JEF constructor param config Configuration structure 27 constructor function config config config Ext applyIf config defaultTitle _ Simple Dialog alwaysUseDefaultTitle true width 340 height 200 Add panel items il xtype panel H 27 Chapter 7 Dialogs Call superclass constructor Dialogs dialogsexample dialogs SimpleDialog superclass constructor call this config H Register the dialog xtype Zarafa core ui ContentPanel register Dialogs dialogsexample dialogs SimpleDialog simpledialog You can see that to create a custom dialog we need to extend Zarafa core ui ContentPanel and call the superclass constructor inside the dialog constructor Finally the last step that should be done is to register this dialog with a custom xtype Zarafa core ui ContentPanel register Dialogs dialogsexample dialogs SimpleDialog simpledialog And that s it In the items list you can put the content that you wish It can be any subclass of Ext Com
61. mat is JSON JavaScript Object Notation As explained in the previous section a request may contain multiple actions for multiple modules 48 Javascript Communication The following listing shows a minimal client request for listing mails in a folder First object is zarafa to define the correct scope for our request The objects beneath there are different modules which are being accessed Beneath each module can be one or more identifiers Each request receives its own unique identifier This is later used to match a response to the corresponding request Beneath the identifier object the action tag is found which may contain a forest of key value pairs The server will respond with a similarly constructed reply zarafa maillistmodule maillistmodule1 list store store MAPI ID entryid folder MAPI ID A possible response from the server is shown below zarafa previewmailitemmodule previewmailitemmodule1 item mail item details would be included here mailnotificationmodule mailnotificationmodulei newitem mail item details would be included here 11 3 Javascript Communication To avoid having to construct HTTP requests manually all client requests are made through a global instance of the Zarafa core Request class This object provides JavaScript JSON de serialisation and allows other components to react to server actions via either ev
62. ment debug the one file compiled from all your files and the release is the compressed debug file lt clientfile load release gt js facebook js lt clientfile gt lt clientfile load debug gt js facebook debug js lt clientfile gt lt clientfile load source gt js FacebookEventsPlugin js lt clientfile gt lt clientfile load source gt js FbEventSelectionDialog js lt clientfile gt lt clientfile load source gt js FbIntegrationDialog js lt clientfile gt lt clientfile load source gt js FbEventSelectionGrid js lt clientfile gt lt clientfile load source gt js FbIntegrationPanel js lt clientfile gt lt clientfile load source gt js data FbEventDataReader js lt clientfile gt lt clientfile load source gt js data FbEventProxy js lt clientfile gt lt clientfile load source gt js data FbEventRecord js lt clientfile gt lt clientfile load source gt js data FbEventStore js lt clientfile gt lt client gt lt resources gt here are css files needed in your plugin lt resourcefile load release gt resources css facebook css lt resourcefile gt lt resourcefile load source gt resources css plugin facebookstyles css lt resourcefile gt lt resources gt lt files gt lt component gt lt components gt lt plugin gt 13 2 Build System The WebApp is a relatively complex application consisting of a server part written in PHP and a client part written in JavaScript Tasks such as building deploying
63. ng C xmpp state widgets Apply Discard Figure 9 7 Plugin settings Finally the settings model also supports simple get and set functions for getting and setting values For quick access to your configuration values the path to a value is delimited with the forward slash character Read flag to 2 seconds container getSettingsModel set zarafa v1 contexts mail readflag_time 2 More information about the settings model can be found in the API documentation of the SettingsModel class 3 http developer zarafa com webapp class Zarafa settings SettingsModel 41 42 Part Ill Advanced topics If you have survived part Il and have written a plugin that does something with the usual interfaces but are hungry for more then this is where you will find all the nitty gritty details of WebApp We dive into MAPI the communication protocol between WebApp and the server This will require an understanding of how Zarafa works and how data is stored in MAPI Finally a few subjects such as the ant based build system and server side translations are handled Chapter 10 MAPI Zarafa provides its groupware functionality by connecting the Linux based server with Outlook clients using MAPI Messaging Application Programming Interface MAPI is a messaging architecture and a Component Object Model based API for Microsoft Windows Simple MAPI is a subset of 12 functions which enable developers to add basic
64. ng some new notes Mon 23 04 2012 12 43 Figure 4 3 Notes context Plugins can be of arbitrary complexity they have the liberty to work with dialogs stores and other extended Zarafa features When you need a deeper integration with Zarafa you will need to work with a plugin Example plugins are the Spreed plugin XMPP plugin Facebook plugin Plugins can be shown visually as some Ul components which trigger some work buttons or context menu items to integrate Facebook events setup a Spreed meeting etc Finally Widgets appear only in the Today context and the side bar They can be be added or removed from there by the user Each time the Today context is opened the configured widgets are shown Also if you enable and lock the side bar the widgets put in there are shown continuously Widgets are small plugins usually only visual with very simple functionality Example widgets a simple visual shell game a customized clock 14 Part Il Extending WebApp In part I we have seen what the possibilities are In this part we will explain the background and show how to implement a plugin that actually extends WebApp We will use the plugins that were introduced in the introduction chapter This part is probably the most useful one to casual plugin and widget developers We explain how to implement a widget a dialog and how to access globally available data Any advanced topics are left for part III Chapter 5 Insertion
65. ning the constructor It is customary but not required to have a configuration object as the first parameter Configuration parameters are object value pairs that configure specific parts of an object s instantiation avoiding large sparse parameter lists The constructor calls the constructor of its parent manually in case the class doesn t have its native constructor If it does have one then the following code should be executed to call the constructor depending on which parameters you need to pass My NameSpace ObjectClass superclass constructor call this config or My NameSpace ObjectClass superclass constructor apply this arguments This is the way all the classes in WebApp should be created We ll use the Spreed plugin code as an example with a snippet of the code of the class SpreedParticipantBox Ext namespace Zarafa plugins spreed dialogs TER class Zarafa plugins spreed dialogs SpreedParticipantBox extends Zarafa common recipientfield ui RecipientBox xtype zarafa spreedparticipantbox Extension to the link Zarafa common recipientfield ui RecipientBox This box offers adding moderator icon for the moderator participant S Zarafa plugins spreed dialogs SpreedParticipantBox Ext extend Zarafa common recipientfield ui RecipientBox ee constructor param config Configuration object 2 constructor function config config config Ext applyIf config y Zarafa plugins
66. nts to determine if the IPMRecord has changed and the component has to be updated Note that listening to the IPMStore to which the Record belongs is not sufficient because Dialogs place a copy of the IPMRecord into the ShadowStore In which case the same Message with the same Entryld is represented by two IPMRecords in two different IPMStores 12 2 RecordFactory Record definitions are managed by the Zarafa core data RecordFactory Within the RecordFactory two groups of Record definitions exists the first group is based on the message class PM Note IPM Contact etc while the other group is based on the object type MAPI_MAILUSER MAPI_DISTLIST etc The reason for having two groups comes from MAPI which does not define the 59 Chapter 12 Stores and RecordFactory PR_MESSAGE_CLASS property for all possible objects most notably for Address Book items they are missing while the PR_OBJECT_TYPE is too global to be used in all cases There is no different value for a Mail and a Contact for instance Ext JS allows Records to be defined using a list of possible fields these fields have a name the property name and possible serialiation deserialization information conversion from text to Integer Date Boolean etc When a Record is created this list is used to define which properties will be serialized deserialized during the communication with the server As a result if a Plugin wishes to send an extra property it somehow has to
67. on the customer portal or to zarafa com doc see the Release Notes for more up to date information 1 3 Document Structure Overview The manual is logically divided into 2 parts and one appendix The first part covers chapters 2 8 and represents general information about programming for Zarafa WebApp These chapters contain the things that are relevant to all plug in developers An overview of the WebApp architecture is given in Chapter 2 Architecture Overview and Ext JS is introduced in Chapter 3 Ext JS and OO Javascript How to extend WebApp is given in the chapters Chapter 8 Bidding System Chapter 7 Dialogs and Chapter 9 Data Models The second part with chapters 9 14 contains advanced information about WebApp This part explains things that probably won t be used by all plugin developers for example additional information about Chapter 9 Data Models and Chapter 10 MAPI Some more detailed explanation of the Chapter 11 Communication and Chapter 12 Stores and RecordFactory Also some advanced things to know but not obligatory to use such as the Chapter 13 Deployment and Build System and dealing with Chapter 14 Translations 5 http www zarafa com webapp 2 http docs sencha com ext js 3 4 api d http doc zarafa com trunk WebApp_Developers_Manual en US html single E https portal zarafa com s http www zarafa com doc Chapter 1 Introduction Appendix A Coding Standards contains coding guidelines and r
68. ort Facebook events 21 er s Figure 5 2 New Facebook button in Calendar Context 21 22 Chapter 6 Widgets As was mentioned in Section 4 1 Ways of Extending WebApp widgets appear in the Today context or the side panel The user can add or remove them at will Auser can also add multiple instances of the same widget but with different parameters Having multiple instances of the same widget is made possible because each widget s instance object has a unique identifier to keep multiple instances apart As soon as you add a new widget to the Today context or the side panel the widget receives a new identifier a GUID which will be used to store the widget s state This newly added instance of the widget can maintain his own settings its settings are stored in the settings tree in the folder zarafa v1 widgets GUID When a widget is removed from the Today context or the side panel this folder is deleted 6 1 Creating a widget We will look at the widget s architecture based on the Facebook Widget example It shows the activity stream from a site that you can change in the widget s configuration To create a custom widget you need to do two simple steps 1 Create your own class that extends Zarafa core ui widget Widget 2 Register this widget class in the container Zarafa widgets FBWidget Ext extend Zarafa core ui widget wWidget The widget s code goes here H Zarafa onReady
69. ory This category should start with error warning info or debug but subtypes are also possible e g error json info newmail Based on the category the Notifier class will determine which plugin must be loaded to display the message This decision is fully configurable through the Settings When a notification arrives for a certain category the settings which belong to that category will be requested For the category error the setting zarafa v1 main notifier error for the warning category the setting will be zarafa v1 main notifier warning When using subtypes the will be converted into a thus a category named info newmail will result in a request to the setting zarafa v1 main notifier info newmail The value of this setting is the unique name of the NotifyPlugin which is registered So when newmail notifications should be send to the ConsolePlugin then the setting will be zarafa v1 main notifier info newmail value console When a subtype is not found in the Settings for example error json is requested but the setting Zarafa v1 main notifier error json does not exist then the system will automatically fallback to zarafa v1 main notifier error when that also is not defined then the final fallback will be zarafa v1 main notifier default Using this system with settings allows 3rd party developers to easily develop new notification systems while the user is capable of configuring the notifications exactly as h
70. ot a child class of anything simply extend it from Object When creating a common user interface class in the core it should be registered using the Ext reg function to allow the usage of xtype when creating the object It is registered with the prefix Zarafa name to prevent name clashes with Ext JS registered classes At the bottom of the derived class register it Ext reg spreed spreedparticipantbox Zarafa plugins spreed dialogs SpreedParticipantBox When using the derived editor in any class xtype spreed spreedparticipantbox New classes should always be created in a new file within the correct folder Exceptions might be made if the new class is a helper class which only consists of a few lines of code and it is bound to the other class defined in the same file in such a way that moving it into a separate file is not logical 3 2 Accessing Components Often when writing Panels which contain Components combined with the lazy instantation as discussed further the problem arises that somewhere in the code of the container a particular component must be accessed Because the items array cannot be read this only contains the lazy configuration objects and not the Component instantiations other methods like panel findBy findById or findByType must be used Because these functions always search through all items and all subitems in case containers are embedded in the main panel performance of these function
71. ponent Now we can use our dialog from WebApp just run the following from the Javascript console while WebApp is loaded Dialogs dialogsexample dialogs SimpleDialog create title _ My Custom Dialog y This piece of code will create an instance and show the dialog on screen 7 3 Dealing with MAPI records When working with MAPTRecor d instances it is useful to use the Zarafa core ui RecordDialog because it has better support for managing MAPIRecords and has extra functionality for saving the record For Messages e g Mail and Meeting Requests we have the Zarafa core ui MessageDialog which extends the RecordDialog functionality to support sending the message to all recipients A Dialog that displays the contents of an IPMRecord must always inherit from RecordDialog This dialog accepts the record configuration option which will be opened by default otherwise it is possible to set the displayed IPMRecord through the setRecord function on this dialog Using the RecordDialog the dialog will automatically hook into the IPMStoreManager to listen for update events regarding the IPMRecord which is opened by the dialog Also with the setrecord and updaterecord events the dialog can inform all components within the dialog about record changes A Dialog that is used for creating or editing an IPMRecord must always inherit from EditRecordDialog EditRecordDialog is a subclass of RecordDialog and therefore offers the same features Additiona
72. port pagination and sorting and it s very easy to get this to work with the standard Ext JS components Records can be added removed or updated Changes made to the data in a store can be committed to the server by calling the save method 54 MAPI Store Add grid example here A MAPI message consists of properties but in some cases also a contents table A spreed meting request could for example contain Recipients or Attachments Distribution lists on the other hand have a list of Members This data does not fit into the Ext JS model by default But in the Zarafa core data MAPIRecord support for SubStores has been added Each MAPIRecord can contain multiple SubStores which are all serialized deserialized to from JSON during the communication with the server The implementation has been generalized in such a way that plugins are able to define their own SubStores for records The contents of a SubStore is serialized deserialized using the JsonReader JsonWriter which have been configured on the SubStore itself This means that for plugin developers they can easily create their custom table by registering the name and the type of the SubStore on the RecordFactory and make sure a custom JsonReader and JsonWriter are set on the SubStore Example of plugin JSONreader is Facebook event JSON reader FE dependsFile client zarafa core data RecordCustomObjectType js 2 Ext namespace Zarafa plugins facebook data Eis k cl
73. proper location and takes care of loading the settings and so on Zarafa widgets FBWidget superclass constructor call this config 6 3 Events As the Zarafa core ui widget Widget class extends the Ext ux Portlet and finally Ext Panel you can override some helpful methods to gain more consistency and readability inside your widget One of these methods is initEvents it will be called after the panel is rendered It is a useful place in the code to initialize the widget s events But remember each time you override the methods of the parent class you need to call the superclass method explicitly initEvents function Zarafa widgets FBWidget superclass initEvents apply this arguments this mon this bodyresize this reloadIframe this Finally another useful method is onRender which is called after the component was rendered You can use it to render your custom elements inside the widget To check if the widget is visible in the current moment or not you can use isWidgetVisible method It will return true if the widget is visible and the widgetPanel on which it resides is not collapsed When you click the cross close icon then the widgetPanel on which the widgets resides will unregister the widget s GUID and it will destroy the widget It will then fire the destroy event Therefore you can define an onDestroy method to do some tasks after widget is destroyed 25 26 Chapter 7 Dialog
74. r open source groupware solution according to TecChannel Q Suggested Contacts amp Ivo Timmermans Fri 24 02 2012 14 53 v Event CeBIT 2012 Zarafa for 7th time in a row in Main Hall together with many partners Hall 2 booth i Tasks ian Away again for a few day D54 6 10 March 8 Public Folders Nathanael van Toon Fri 24 02 2012 13 14 gt Support our growth Zarafa has job vacancies in the field of sales development and testing Apply 4 now Open Shared Folders Businessc P Zarafa Deutschland GmbH Schiffgraben 13 30159 Hannover Germany Kontakt 49 511 22001980 www zarafaserver de www twitter com zarafagroupware Registergericht Amtsgericht Hannover HRB201370 M Figure 4 1 Mail context 13 Chapter 4 Extending WebApp Mail Calendar Co Ei aa C a a ea Zarafa Calendars Calendar 4 9 13April2012 gt aa 4 April 2012 gt MTW TFS Ss 1 8 2345 67 o u 12 13 1 35 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 My Calendars Show all folders gt Y Calendar Y Calendar of Remon van 4 Open Shared Calendars w mc Zarafa Notes lt Notes K lt 4 Page 10f1 b N num My Notes Search in Notes p ame E aes Created Categories u Hello World Mon 23 04 2012 12 42 ltest4 in Public Folders El New Pink note for you Mon 23 04 2012 12 44 Open Shared Notes F Simple White note Mon 23 04 2012 12 43 Testi
75. s are used throughout the WebApp Dialogs are an important part in the application When you are creating an email appointment a contact or when opening the address book the contents will always be shown in a dialog The Zarafa core ui ContentPanel has a couple of generic subclasses that might help in managing MAPI objects objects that contain information on e g e mail appointments etc There are two basic types of dialogs in WebApp Zarafa core ui RecordContentPanel and Zarafa core ui ContentPanel Each Dialog must inherit from either one to benefit from any automatically added user interface elements and styling Usually you would use Zarafa core ui ContentPanel If you want to handle MAPI records then see Section 7 3 Dealing with MAPI records and Chapter 12 Stores and RecordFactory for more background information 7 1 Events For plugins it is possible to detect when a Dialog is about to be displayed to the user allowing it to hook into further events of the Dialog itself or any of its components To do this the plugin must listen to the createdialog event from the Zarafa core data ContentPanelMgr singleton object This event will pass the dialog that is being displayed as argument Note that the event is called before the dialog is rendered The DialogMgr will inform the plugin that the dialog has disapeared using the destroydialog event 7 2 Example The following code snippet shows how we can create our own custo
76. s get a BASE_TYPE that is higher than 1000 so you can see it is a custom record Thus BASE_TYPE is equal to 1000 and the next one you add is then 1001 as the value of the previous highest value is incremented See an example of its use in the class FbEventRecord Zarafa core data RecordCustom0bjectType addProperty ZARAFA_FACEBOOK_EVENT Now our Facebook records are of our custom type ZARAFA_FACEBOOK_EVENT 3 4 Singletons Static functions can be declared inside a singleton object A singleton in object oriented design is a class that only has a single instance This can be easily simulated in JavaScript by just creating one instance and re using it Consider the following example of the definition of a singleton emulated in Javascript by a struct are class Zarafa core XMLSerialisation Functions used by Request for converting between XML and JavaScript objects JSON singleton y Zarafa core XMLSerialisation 10 Singletons snip y For singleton classes which extend an existing class consider the following example Visi class Ext StoreMgr extends Ext util MixedCollection The default global group of stores singleton RA Ext StoreMgr Ext extend Ext util MixedCollection snip J Make it a singleton Ext StoreMgr new Ext StoreMgr There is now an instance of Ext StoreMgr that is given the same name of the original class definition effectively making it the onl
77. s is quite low Ext JS offers an easy way to assign a component to a variable in the panel during rendering If the ref option is used in the component the variable name can be specified of the component inside the parent panel By using a path specifier it is even possible to assign the variable to the parent of the parent container Consider the following example Enums xtype panel id panel1 items xtype textarea ref myTextArea hl After rendering the panel with id panel1 will contain the field myTextArea which will point to the given textarea For specifying the path consider the following example xtype panel id panel1 items xtype panel id panel2 items xtype textarea ref myTextArea By using the path seperator the field myTextArea will now be assigned to panel1 Within the textarea itself panel1 can be accessed through the refOwner field Using the above objects one can use the following code within the textarea reset function The panel owns the record for which we display the data this setText this refOwner record get data While in panel1 we can use the following code to access the textarea component update function record Update the textarea with the new record data this myTextArea update record get data This will work for any component including components added in the tbar top bar fbar
78. sootaractos Options From context mail contextmenu options To RS Archive to SugarCRM 1 Soreed mesg Figure 5 1 Zdeveloper plugin turned on all extension points are labeled in the user interface of WebApp Set Flag Complete None Move to Junk Folder WebApp now shows little text boxes containing the names of all existing insertion points such as in the screenshot in Figure 5 1 Zdeveloper plugin turned on all extension points are labeled in the user interface of WebApp So for example next to the Reload button in the main tool bar there is a label with the text main toolbar actions This means that if you register to that insertion point the result will be put there in the toolbar as a button this registerInsertionPoint main toolbar actions this addCustomAction this addCustomAction function insertionpoint return xtype button tooltip _ Custom Action iconCls icon_customAction 18 Example adding a button In this case the function addCustomAction is defined in your plug in and returns an instance of Ext Button which is also suitable for inclusion in a tool bar like this Other insertion points require different types of objects please refer to the API documentation for the object type that the insertion point expects Thus using the zdeveloper plug in you can quickly identify where you can add user interface elements to WebApp Moreover
79. spreed dialogs SpreedParticipantContextMenu break case Zarafa core data SharedComponentType common dialog attachments component Zarafa plugins spreed dialogs AttachmentsDialog break return component 33 Chapter 8 Bidding System 34 Chapter 9 Data Models 9 1 Model based architecture A data model encapsulates data providing a way for the interested parties to query load and modify said information and get notified in case of changes The WebApp framework contains a global model that provides an API for handling plugins and insertion points the hierarchy model store folder hierarchy and settings The Ext JS library provides a way of working with server backed data stores and standard UI components Most notably the data grid component i e data representing a list of mails appointments etc integrates with them The framework contains base classes for creating such data stores that use the PHP code as backend The global model stores information required across contexts and plugins A schematic overview is shown in Figure 9 1 Global data model Container 1 1 1 Plugin HierarchyModel Settn gsModel Context Store Folder Figure 9 1 Global data model A global instance of the Zarafa core Container object simply called container maintains a list of the registered plugins lazily created instances of Zarafa core Hierarchy
80. structor param config Object Configuration object af constructor function config config config 56 IPM Stores and ShadowStore Ext applyIf config writer new Zarafa plugins spreed data SpreedJsonParticipantwriter customObjectType Zarafa core data RecordCustomObjectType ZARAFA_SPREED_PARTICIPANT reader new Zarafa core data JsonRecipientReader id entryid idProperty entryid dynamicRecord false H Zarafa plugins spreed data SpreedParticipantStore superclass constructor call this config 3 Ext reg spreed spreedparticipantstore Zarafa plugins spreed data SpreedParticipantStore This is how it is reflected in SpreedRecord class in constructor constructor function data data data this initialRecordData participants new Ext util MixedCollection Zarafa plugins spreed data SpreedRecord superclass constructor call this data this collectedDataRecords this subStoresTypes recipients Zarafa plugins spreed data SpreedParticipantStore y Where initialRecordData is an Object of recipients taken from the mailRecords if they are opened An important note regarding SubStores is that the SubStore is guaranteed to be available when the Record has been opened or when it is a phantom record When the Record has not yet been opened the SubStore will only have been allocated if the original JsonData contains the data for the SubStore w
81. t php pgettext msgctxt msgid npgettext msgctxt msgid msgid_plural num dpgettext domain msgctxt msgid dcpgettext domain msgctxt msgid category gt 14 3 Client Side 14 3 1 Reading Translations and Passing it to the Client The language class is the server side PHP class that reads the binary mo file in the language folder of the WebApp and returns a list of those translations The client requests the page index php load translations js which includes the file client translations js php In this file the Translations class is defined and the translations are added inside this global Javascript object The plural forms are defined inside the first defintion This first defition is an empty string with the value containing information like the following msgid msgstr Project Id Version PHP Langadmin 1 0 n POT Creation Date 2008 12 16 16 16 06 0100 n PO Revision Date 2008 12 16 16 16 06 0100 n Last Translator PHP Langadmin automatic translator lt foo bar foobar gt n Language Team nl_NL lt nl li org gt n MIME Version 1 0 n Content Type text plain charset iso 8859 1 n Content Transfer Encoding 8bit n Plural Forms nplurals 3 plural n 1 0 n 2 1 2 As you can see the last line defines the plural forms Based on this string gettext will understand what singular or plural form it needs to use In English there are only two but in other languages you might
82. t the Record object Zarafa core data RecordFactory createRecordObjectByMessageClass IPM Note This will create a new phantom record for the messageclass PM Note This Record now only has a single field which is allowed namely from The plugin variant as we used in SpreedRecord in conversion function convertToSpreedAttachment function attachmentRecord return Zarafa core data RecordFactory createRecordObjectByCustomType Zarafa core data RecordCustomObjectType ZARAFA_SPREED_ATTACHMENT enums 60 RecordFactory attachmentRecord data Here we obtain a new Record object of the custom type ZARAFA_SPREED_ATTACHMENT with field values taken from the second parameter object If the second parameter is not specified values are taken from the field default value will be assigned e g for original_attachment_store_ id default value will be If we want that a new phantom Records for PM Note contain a default value we can also instruct the RecordFactory Zarafa core data RecordFactory addDefaultValueToMessageClass IPM Note from me Now when we create a new Record for messageclass PM Note the record will automatically have the property from initialized to me By default all Record instances which are created by the Record factory use the Ext data Record as baseclass This however is also configurable using the function setBaseClass ToMessageClass To force the usage of Zarafa core data IPMR
83. t the folder the item was created in This is 47 Chapter 11 Communication shown in Figure 11 3 Message exchange for creating a new item server response This last action is to notify the client that there is now one more item in the folder Server Cle nt TaskListModule item Figure 11 2 Message exchange for creating a new item client request Server az en TaskListModule Clent E 7 folder HierarchyMo dule update Figure 11 3 Message exchange for creating a new item server response The exact data flow through the various classes is shown in Figure 11 4 Request Response flow The important components inside this diagram will be explained in details further down in this chapter PHP Response Module ID Data Module ID Response Module Response Request ResonseRouter Module ID Response save module ID callbacks data get module ID response data gt ResponseHandler gt decode Wrapper object of ResponseHandler event functions 1 Notification save Resolver JSONReader JSON Writer Legend Path after encode Road to server server response _ Unknown call Return value update Store Figure 11 4 Request Response flow 11 2 Protocol Communication with the back end starts with the client initiating a request The data exchange for
84. tances of IPM and IPM Note will by default have the value test in the body property However PM Contact will have the value contact in that property To add support for a SubStore the following function can be called Zarafa core data RecordFactory setSubStoreToMessageClass IPM Note recipients Zarafa core data IPMRecipientStore This will register the SubStore with the name recipients to all Records which have the MessageClass PM Note The SubStore will be created using the passed constructor Zarafa core data IPMRecipientStore The name can be used on a MAPIRecord to detect if it supports this particular SubStore var record Zarafa core data RecordFactory createRecordObjectByMessageClass IPM Note record supportsSubStore recipients True if the record supports the subStore record getSubStore recipients this returns the Zarafa core data IPMRecipientStore allocated for this record A final warning adding fields default values or base classes can only be done during initial loading This means that these statements must be done outside any function or class Calling Zarafa core data RecordFactory createRecordObjectByMessageClass can only be made safely after the initial loading thus it can be done safely in functions and classes Refer to API documentation for more details s http developer zarafa com webapp class Zarafa core data RecordFactory 62 Chapter 13 Deployment and Build System
85. the user need to put new value for Facebook Activity Site config function var configwindow new Ext Window title _ Configure widget layout fit width 350 height 120 items xtype form frame true ref formPanel labelwidth 180 items xtype textfield anchor 100 fieldLabel _ Site name to track the activity allowBlank false vtype url ref siteurlField name site_url value this get site_url gt buttons text _ Save scope this ref savebutton handler this saveUserUrlToSettings Y text _ Cancel scope this ref cancelbutton handler this closeConfigwindow configwindow show this 24 Events To save or receive the settings value we use this set and this get methods respectively In our example we get the default value of the site url field using this get site_url If it was not stored before with this set site_url it will return undefined You will need to take care of this by yourself That is why we use Ext isEmpty check the value in the constructor var siteUrl this get site_url if Ext isEmpty siteUrl siteUrl this defaultFbActivitySite this set site_url siteurl this setTitle _ Facebook siteurl Don t forget to call parent constructor or the widget will not work the parent class constructor puts it in the
86. tion The application is documented using the ext doc documentation tool provided by the Ext JS people It allows documenting JavaScript code much like Javadoc or Doxygen This section describes code is documented Since Javascript is a very dynamic language it s pretty much impossible to detect class method and field definitions and the relationships between them Therefore documentation is quite explicit One has to declare classes methods and fields manually This section briefly describes the most important aspects of documenting with ext doc Please refer to the ext doc documentation wiki for more information A 3 1 Documenting Classes A class is declared using the class statement inside a multi line comment One can use extends to indicate that the class is a subclass of another class A description of the class follows these two statements Optionally the singleton statement can be used to declare the class a singleton For classes which inherit directly or indirectly from Ext Component should use the xtype to document which xtype can be used to automatically instantiate the object through the xtype The constructor will be documented separately and is documented much like a method Finally use cfg to declare configuration options for this class Note that parameters and configuration options are typed Spreed Plugin example eats class Zarafa plugins spreed SpreedPlugin extends Zarafa core Plugin T
87. ttext O RENT 14 22 SeNet SIGE nn ages Biased ste teed ea deed Gata aon 14 2 1 Implemented Functions on the Server Side c ccceeeeeeeeeeeeeeeeeeeeeeeeeaes 1453 Chet SIGS a aa 14 3 1 Reading Translations and Passing it to the Client ueeen 14 3 2 Implemented Functions on the Client Side ccceeeeeeeeeeeeeeeeeeeeeeaaes A Coding Standards Al Naming CONVENTOS rennen nee eine A 1 1 Namespace Structure css nee llana dlls A 1 2 Naming Packages and Classes oocococcccncconnccnnnncccnncnnnncnnnnncnnnnnnnnncnonnnnnonarcnnncins A 1 3 Naming Insertion Points sssssssnnnsnennnnnnnsnennnnnnnnnnnnnnnennnnnnsnnnnnnnnnrnnnnnnnn A 2 Coding Style Gulde lin S ss carta e Aa eea nadana Naah Aao Documentation costilla iio ile ica ieee AB I Documenting ClaSses in ads A 3 2 Documenting FICISS a A 3 3 Documenting ConstructorS 22 0 0 cece cece e eee cece eee ttrt tAr tees cane ee deeeedeeee aa nen rnnnnnnnn A 3 4 Documenting Methods ccccccecceceeeee eee eee ee ae atakia aiaia iai eaaa naianei A 3 5 Documenting Insertion Points eceee eee ee cece eee eee reece eee nenn nnnnnnnnnnnnnn nen A 3 6 Documenting Enumerations ooccooccccnccinnccnnnnccnnnonnnncnnnnncnnnnonnnncrnnnnnnnnarnnnncronnnnns B References vi Part I WebApp Introduction Part contains information on WebApp without diving into details just yet An overview is given of how Web
88. which is then minimised A standard concat ant task exists that concatenates a set of files The file order is important because files may depend on one or more global variables declared other files Specifically in Ext JS applications if some class Foo extends another class Bar bar js must be included before foo js It is possible to specify this inclusion order by hand but considering the large number of files to manage this is a maintenance nightmare Therefore JsConcat was created a concatenation task that scans the input files and determines the proper inclusion order automatically Inclusion Order There are three ways to influence the inclusion order First there are explicit dependencies that you can enter in your file This file needs to be included after bar js dependsFile foo bar js ey Dependencies are also extracted from class and extends 3 http ant apache org manual index html 66 Tools ets Foo extends Bar so the file in which Bar is defined should come before this file class Foo extends Bar 57 Finally formatted as a comma separated list of regular expressions the prioritise argument can be used to move groups of files up the list Files that have classes defined in them have those full class names matched against the regexps Files that match the first priority group have the highest priority files that match the second group come after that and so on We use this mainly to move
89. y possible instance of it 11 12 Chapter 4 Extending WebApp 4 1 Ways of Extending WebApp Refer back to Figure 2 1 WebApp architecture overview showing the software stack Here a few plug ins are given as an example However there are actually three ways of extending WebApp we call them contexts plugins and widgets Contexts are implemented as plugins and third party developers can develop their own contexts to extend or customise the application Figure fig layout gives three examples of contexts the Mail Calendar and Note contexts Each context is a kind of special plugin that has additional functionality allowing it to take over the toolbar and main content section of the screen Only a single context can be active at any given time For example folders in the folder hierarchy are linked to contexts that display their contents so that when a user clicks his or her inbox the Mail context is shown The main application screen consists of several areas Some of these are independent shown in e g Figure 4 1 Mail context The UI provides a standard hierarchy panel showing a list of folders the user has access to as well as a bottom tool bar Each context has its own content panel and tool bar but only the ones belonging to the currently active context are visible while all others are hidden This is achieved by loading the toolbars and content panels of all contexts into their respective areas and us
90. zarafa vi plugins facebook enable true container registerPlugin new Zarafa plugins facebook FacebookEventsPlugin 3 So let s look closer on what is happening after the each function call Just after calling the constructor we call init function which registers insertion point in the navigation panel south part init function this registerInsertionPoint navigation south this createFacebookButton this Here we initiate our plugin insertion point by registerInsertionPoint function Which takes three parameters registerInsertionPoint match func scope Where match is a string or regular expression naming the existing insertion point where new item will be added Regular expression can be used like in the example below this registerInsertionPoint context toolbar this createButton this func is a function that creates one or more Ext JS components at the specified insertion point and scope is an optional parameter of the scope in which the items will be created createFacebookButton function var button xtype button text _ Import Facebook events iconCls icon_facebook_button navigationContext container getContextByName calendar y return button Here comes the button the returned component may be any other UI component Ext Component instances itself with specified xtype and text We also specify the icon css style And the last confi
Download Pdf Manuals
Related Search
Related Contents
TM-CA 72-4 ELISA SECRET - Babyliss.com ステンレスボトル MMY-AX V10_A_Manual_RHT_Modbus_ Spanish _Em alteração Samsung BCD-199NMMR-C 用户手册 User Manual Copyright © All rights reserved.
Failed to retrieve file