Commit 1b70c877 authored by Sebastian Kummer's avatar Sebastian Kummer

ZP-998 First commit of the gab2contact script.

Released under the Affero GNU General Public License (AGPL) version 3.
parent a93e5be5
This diff is collapsed.
<?php
/***********************************************
* File : config.php
* Project : Z-Push - tools - GAB2Contacts
* Descr : Configuration file.
*
* Created : 20.07.2016
*
* Copyright 2016 Zarafa Deutschland GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation with the following additional
* term according to sec. 7:
*
* According to sec. 7 of the GNU Affero General Public License, version 3,
* the terms of the AGPL are supplemented with the following terms:
*
* "Zarafa" is a registered trademark of Zarafa B.V.
* "Z-Push" is a registered trademark of Zarafa Deutschland GmbH
* The licensing of the Program under the AGPL does not imply a trademark license.
* Therefore any rights, title and interest in our trademarks remain entirely with us.
*
* However, if you propagate an unmodified version of the Program you are
* allowed to use the term "Z-Push" to indicate that you distribute the Program.
* Furthermore you may use our trademarks where it is necessary to indicate
* the intended purpose of a product or service provided you use it in accordance
* with honest practices in industrial or commercial matters.
* If you want to propagate modified versions of the Program under the name "Z-Push",
* you may only do so if you have a written permission by Zarafa Deutschland GmbH
* (to acquire a permission please contact Zarafa at trademark@zarafa.com).
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Consult LICENSE file for details
* ************************************************/
// The field to be hashed that is unique and never changes
// in the entire lifetime of the GAB entry.
define('HASHFIELD', 'account');
// ContactWorker implementation to be used
define('CONTACTWORKER', 'Kopano');
// Server connection settings
// Depending on your setup, it might be advisable to change the lines below to one defined with your
// default socket location.
// Normally "default:" points to the default setting ("file:///var/run/kopano/server.sock")
// Examples: define("SERVER", "default:");
// define("SERVER", "http://localhost:236/kopano");
// define("SERVER", "https://localhost:237/kopano");
// define("SERVER", "file:///var/run/kopano/server.sock)";
// If you are using ZCP >= 7.2.0, set it to the zarafa location, e.g.
// define("SERVER", "http://localhost:236/zarafa");
// define("SERVER", "https://localhost:237/zarafa");
// define("SERVER", "file:///var/run/zarafad/server.sock)";
// For ZCP versions prior to 7.2.0 the socket location is different (http(s) sockets are the same):
// define("SERVER", "file:///var/run/zarafa");
define('SERVER', 'default:');
define('USERNAME', 'SYSTEM');
define('PASSWORD', '');
define('CERTIFICATE', null);
define('CERTIFICATE_PASSWORD', null);
// The GAB to be used. This only needs to be set on a multi-tenant system.
// For standard installations, keep it at 'default'.
define('SOURCE_GAB', 'default');
// Store where the target contact folder is located.
// For the public folder, use SYSTEM.
// To use another store, use the same as USERNAME
// or another store where USERNAME has full access to.
define('CONTACT_FOLDERSTORE', 'SYSTEM');
// Set the target FolderId.
// You can find the id e.g. with the listfolders script of Kopano backend.
define('CONTACT_FOLDERID', '');
// Set the fileas (save as) order for contacts.
// Possible values are:
// SYNC_FILEAS_FIRSTLAST - fileas will be "Firstname Lastname"
// SYNC_FILEAS_LASTFIRST - fileas will be "Lastname, Firstname"
// SYNC_FILEAS_COMPANYONLY - fileas will be "Company"
// SYNC_FILEAS_COMPANYLAST - fileas will be "Company (Lastname, Firstname)"
// SYNC_FILEAS_COMPANYFIRST - fileas will be "Company (Firstname Lastname)"
// SYNC_FILEAS_LASTCOMPANY - fileas will be "Lastname, Firstname (Company)"
// SYNC_FILEAS_FIRSTCOMPANY - fileas will be "Firstname Lastname (Company)"
//
// The company-fileas will only be set if a contact has a company set. If one of
// company-fileas is selected and a contact doesn't have a company set, it will default
// to SYNC_FILEAS_FIRSTLAST or SYNC_FILEAS_LASTFIRST (depending on if last or first
// option is selected for company).
// If SYNC_FILEAS_COMPANYONLY is selected and company of the contact is not set
// SYNC_FILEAS_LASTFIRST will be used
define('FILEAS_ORDER', SYNC_FILEAS_LASTFIRST);
#!/usr/bin/env php
<?php
/***********************************************
* File : gab2contacts.php
* Project : Z-Push - tools - GAB2Contacts
* Descr : Copies the GAB into a contact folder and can be used to keep them updated.
*
* Created : 20.07.2016
*
* Copyright 2016 Zarafa Deutschland GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation with the following additional
* term according to sec. 7:
*
* According to sec. 7 of the GNU Affero General Public License, version 3,
* the terms of the AGPL are supplemented with the following terms:
*
* "Zarafa" is a registered trademark of Zarafa B.V.
* "Z-Push" is a registered trademark of Zarafa Deutschland GmbH
* The licensing of the Program under the AGPL does not imply a trademark license.
* Therefore any rights, title and interest in our trademarks remain entirely with us.
*
* However, if you propagate an unmodified version of the Program you are
* allowed to use the term "Z-Push" to indicate that you distribute the Program.
* Furthermore you may use our trademarks where it is necessary to indicate
* the intended purpose of a product or service provided you use it in accordance
* with honest practices in industrial or commercial matters.
* If you want to propagate modified versions of the Program under the name "Z-Push",
* you may only do so if you have a written permission by Zarafa Deutschland GmbH
* (to acquire a permission please contact Zarafa at trademark@zarafa.com).
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Consult LICENSE file for details
* ************************************************/
// Path to the Z-Push directory relative to the gab2contacts script.
// The path set by default is as required for a GIT checkout.
define('PATH_TO_ZPUSH', '../../src/');
/************************************************
* MAIN
*/
define('BASE_PATH_CLI', dirname(__FILE__) ."/");
set_include_path(get_include_path() . PATH_SEPARATOR . BASE_PATH_CLI . PATH_SEPARATOR . PATH_TO_ZPUSH);
include_once("vendor/autoload.php");
if (!defined('CONTACT_CONFIG')) define('CONTACT_CONFIG', 'config.php');
include_once(CONTACT_CONFIG);
try {
GAB2ContactsCLI::CheckEnv();
GAB2ContactsCLI::CheckOptions();
if (! GAB2ContactsCLI::SureWhatToDo()) {
// show error message if available
if (GAB2ContactsCLI::GetErrorMessage())
fwrite(STDERR, GAB2ContactsCLI::GetErrorMessage() . PHP_EOL.PHP_EOL);
echo GAB2ContactsCLI::UsageInstructions();
exit(1);
}
else if (!GAB2ContactsCLI::SetupContactWorker()) {
fwrite(STDERR, GAB2ContactsCLI::GetErrorMessage() . PHP_EOL);
exit(1);
}
GAB2ContactsCLI::RunCommand();
}
catch (Exception $ex) {
die(get_class($ex) . ": ". $ex->getMessage() . PHP_EOL);
}
/************************************************
* GAB2Contacts CLI
*/
class GAB2ContactsCLI {
const COMMAND_SYNC = 1;
const COMMAND_DELETE = 2;
static private $contactWorker;
static private $command;
static private $sourceGAB;
static private $errormessage;
/**
* Returns usage instructions.
*
* @access public
* @return string
*/
static public function UsageInstructions() {
return "Usage:" .PHP_EOL.
"\tgab2contact.php -a ACTION [options]" .PHP_EOL.PHP_EOL.
"Parameters:" .PHP_EOL.
"\t-a sync | delete" .PHP_EOL.PHP_EOL.
"Actions:" .PHP_EOL.
"\tsync\t Synchronizes all data from the GAB to the target contact folder" .PHP_EOL.
"\tdelete\t Removes all previously created contacts in the target contact folder." .PHP_EOL.
PHP_EOL;
}
/**
* Setup of the ContactWorker implementation.
*
* @access public
* @return boolean
*/
static public function SetupContactWorker() {
$file = "lib/" .strtolower(CONTACTWORKER).".php";
include_once($file);
if (!class_exists(CONTACTWORKER)) {
self::$errormessage = "ContactWorker file loaded, but class '".CONTACTWORKER."' can not be found. Check your configuration or implementation.";
}
else {
self::$sourceGAB = @constant('SOURCE_GAB');
$s = @constant('CONTACTWORKER');
self::$contactWorker = new $s();
return true;
}
return false;
}
/**
* Checks the environment.
*
* @access public
* @return void
*/
static public function CheckEnv() {
if (php_sapi_name() != "cli")
self::$errormessage = "This script can only be called from the CLI.";
if (!function_exists("getopt"))
self::$errormessage = "PHP Function getopt not found. Please check your PHP version and settings.";
if (!defined('CONTACT_FOLDERID') || CONTACT_FOLDERID == "")
self::$errormessage = "No value set for 'CONTACT_FOLDERID'. Please check your configuration.";
}
/**
* Checks the options from the command line.
*
* @access public
* @return void
*/
static public function CheckOptions() {
if (self::$errormessage)
return;
$options = getopt("a:");
// get 'action'
$action = false;
if (isset($options['a']) && !empty($options['a']))
$action = strtolower(trim($options['a']));
elseif (isset($options['action']) && !empty($options['action']))
$action = strtolower(trim($options['action']));
// get a command for the requested action
switch ($action) {
// sync!
case "sync":
self::$command = self::COMMAND_SYNC;
break;
// delete
case "delete":
self::$command = self::COMMAND_DELETE;
break;
default:
self::UsageInstructions();
}
}
/**
* Indicates if the options from the command line
* could be processed correctly.
*
* @access public
* @return boolean
*/
static public function SureWhatToDo() {
return isset(self::$command);
}
/**
* Returns a errormessage of things which could have gone wrong.
*
* @access public
* @return string
*/
static public function GetErrorMessage() {
return (isset(self::$errormessage))?self::$errormessage:"";
}
/**
* Runs a command requested from an action of the command line.
*
* @access public
* @return void
*/
static public function RunCommand() {
switch(self::$command) {
case self::COMMAND_SYNC:
self::$contactWorker->Sync(self::$sourceGAB);
break;
case self::COMMAND_DELETE:
echo "Are you sure you want to remove all contacts of GAB folder in the target folder? [y/N]: ";
$confirm = strtolower(trim(fgets(STDIN)));
if ( $confirm === 'y' || $confirm === 'yes')
self::$contactWorker->Delete(self::$sourceGAB);
else
echo "Aborted!".PHP_EOL;
break;
}
echo PHP_EOL;
}
/**
* Returns the Worker object.
*
* @access public
* @return ContactWorker implementation
*/
static public function GetWorker() {
return self::$contactWorker;
}
}
\ No newline at end of file
<?php
/***********************************************
* File : contactworker.php
* Project : Z-Push - tools - GAB2Contacts
* Descr : Main contact synchronization class.
*
* Created : 20.07.2016
*
* Copyright 2016 Zarafa Deutschland GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation with the following additional
* term according to sec. 7:
*
* According to sec. 7 of the GNU Affero General Public License, version 3,
* the terms of the AGPL are supplemented with the following terms:
*
* "Zarafa" is a registered trademark of Zarafa B.V.
* "Z-Push" is a registered trademark of Zarafa Deutschland GmbH
* The licensing of the Program under the AGPL does not imply a trademark license.
* Therefore any rights, title and interest in our trademarks remain entirely with us.
*
* However, if you propagate an unmodified version of the Program you are
* allowed to use the term "Z-Push" to indicate that you distribute the Program.
* Furthermore you may use our trademarks where it is necessary to indicate
* the intended purpose of a product or service provided you use it in accordance
* with honest practices in industrial or commercial matters.
* If you want to propagate modified versions of the Program under the name "Z-Push",
* you may only do so if you have a written permission by Zarafa Deutschland GmbH
* (to acquire a permission please contact Zarafa at trademark@zarafa.com).
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Consult LICENSE file for details
* ************************************************/
abstract class ContactWorker {
/**
* Constructor
*/
public function __construct() {
}
/**
* Performs the synchronization.
* - finds the correct GAB
* - gets all GAB entries
* - decides if it has to create/update/delete them
*
* @access public
* @return void
*/
public function Sync($sourceGAB = 'default') {
$targetFolderId = CONTACT_FOLDERID;
// gets a list of GABs
$gabs = $this->GetGABs();
if (empty($gabs) || $sourceGAB == 'default') {
// no multi-GABs, just go default
$this->doSync($targetFolderId, null, 'default');
}
else {
$found = false;
foreach($gabs as $gabName => $gabId) {
if (!$sourceGAB || $sourceGAB == $gabName || $sourceGAB == $gabId) {
$this->doSync($targetFolderId, $gabId, $gabName);
$found = true;
break;
}
}
if (!$found) {
$this->Terminate(sprintf("Specified GAB '%s' can not be found. Aborting.", $sourceGAB));
}
}
}
/**
* Clears all data from the hidden folder and removes it.
* This will cause a serverside clearing of all user gabs and a synchronization stop.
*
* @param string $targetGab A gab where the data should be cleared. If not set, it's 'default' or all.
*
* @access public
* @return void
*/
public function Delete($sourceGAB) {
$targetFolderId = CONTACT_FOLDERID;
// gets a list of GABs
$gabs = $this->GetGABs();
if (empty($gabs) || $sourceGAB == 'default') {
// no multi-GABs, just go default
$this->doDelete($targetFolderId, null, 'default');
}
else {
$found = false;
foreach($gabs as $gabName => $gabId) {
if (!$sourceGAB || $sourceGAB == $gabName || $sourceGAB == $gabId) {
$this->doDelete($gabId, $gabName);
$found = true;
break;
}
}
if (!$found) {
$this->Terminate(sprintf("Specified GAB '%s' can not be found. Aborting.", $sourceGAB));
}
}
}
/**
* Logs a message to the command line.
*
* @param string $msg the message
*
* @access protected
* @return void
*/
protected function Log($msg, $error = false) {
echo $msg . PHP_EOL;
}
/**
* Writes a message to STDERR and terminates the script.
*
* @param string $msg the message
*
* @access protected
* @return void
*/
protected function Terminate($msg) {
fwrite(STDERR, $msg);
echo PHP_EOL.PHP_EOL;
exit(1);
}
/*********************************
* Abstract methods
*********************************/
/**
* Returns a list of Global Address Books with their name and ids.
*
* @access protected
* @return array
*/
protected abstract function GetGABs();
/**
* Performs the actual synchronization for a single GAB.
*
* @param string $targetFolderId the id of the folder where the contacts should be stored.
* @param string $gabId the id of the gab to be synchronized. If not set (null) the default gab is synchronized.
* @param string $gabName the name of the gab to be synchronized. If not set (null) the default gab is synchronized.
*
* @access protected
* @return void
*/
protected abstract function doSync($targetFolderId, $gabId = null, $gabName = 'default');
/**
* Deletes all contacts that were created by the script before.
*
* @param string $targetFolderId the id of the folder where the contacts should be deleted.
* @param string $gabId the id of the gab to be synchronized. If not set (null) the default gab is synchronized.
* @param string $gabName the name of the gab to be synchronized. If not set (null) the default gab is synchronized.
*
* @access protected
* @return boolean
*/
protected abstract function doDelete($targetFolderId, $gabId = null, $gabName = 'default');
}
/**
* Overwrite ZLog class to provide basic logging.
* All debug messages are ignored, others are logged.
*/
class ZLog {
static public function Write($level, $msg, $truncate = false) {
if ($level < LOGLEVEL_INFO) {
GAB2ContactsCLI::GetWorker()->Log($msg);
}
}
}
This diff is collapsed.
<?php
/***********************************************
* File : synccontact.php
* Project : Z-Push
* Descr : A simplified version of Z-Pushs SyncContact object.
*
* Created : 05.09.2011
*
* Copyright 2007 - 2016 Zarafa Deutschland GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation with the following additional
* term according to sec. 7:
*
* According to sec. 7 of the GNU Affero General Public License, version 3,
* the terms of the AGPL are supplemented with the following terms:
*
* "Zarafa" is a registered trademark of Zarafa B.V.
* "Z-Push" is a registered trademark of Zarafa Deutschland GmbH
* The licensing of the Program under the AGPL does not imply a trademark license.
* Therefore any rights, title and interest in our trademarks remain entirely with us.
*
* However, if you propagate an unmodified version of the Program you are
* allowed to use the term "Z-Push" to indicate that you distribute the Program.
* Furthermore you may use our trademarks where it is necessary to indicate
* the intended purpose of a product or service provided you use it in accordance
* with honest practices in industrial or commercial matters.
* If you want to propagate modified versions of the Program under the name "Z-Push",
* you may only do so if you have a written permission by Zarafa Deutschland GmbH
* (to acquire a permission please contact Zarafa at trademark@zarafa.com).
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Consult LICENSE file for details
************************************************/
class SyncContact {
// ContactObject variable MAPI Property Default LDAP parameter
public $accountname; // PR_ACCOUNT username
public $firstname; // PR_GIVEN_NAME givenName
public $lastname; // PR_SURNAME sn
public $officelocation; // PR_OFFICE_LOCATION physicalDeliveryOfficeName
public $companyname; // PR_COMPANY_NAME
public $jobtitle; // PR_TITLE title
public $email1address; // PR_SMTP_ADDRESS Email
public $businessphonenumber; // PR_BUSINESS_TELEPHONE_NUMBER
public $businessfaxnumber; // PR_PRIMARY_FAX_NUMBER Fax
public $businessstreet; // PR_POSTAL_ADDRESS postalAddress
public $businesspostalcode; // PR_BUSINESS_ADDRESS_POSTAL_CODE postalCode
public $businessstate; // PR_BUSINESS_ADDRESS_STATE_OR_PROVINCE st
public $businesscity; // PR_BUSINESS_ADDRESS_CITY location
public $mobilephonenumber; // PR_MOBILE_TELEPHONE_NUMBER mobile
public $homephonenumber; // PR_HOME_TELEPHONE_NUMBER Telephone
public $pagernumber; // PR_BEEPER_TELEPHONE_NUMBER pager
public $picture; // PR_EMS_AB_THUMBNAIL_PHOTO jpegPhoto // needs to be set base64_encoded
public $customerid; // PR_ORGANIZATIONAL_ID_NUMBER employeeNumber
/* Not mappable GAB variables
*
* - PR_BUSINESS_ADDRESS_POST_OFFICE_BOX postBoxOffice
* - PR_INITIALS initials
* - PR_LANGUAGE preferredLanguage
*/
// hash of the object
public $hash;
// untouched SyncObject variables
public $anniversary;
public $assistantname;
public $assistnamephonenumber;
public $birthday;
public $body;
public $bodysize;
public $bodytruncated;
public $business2phonenumber;
public $businesscountry;
public $carphonenumber;
public $children;
public $email2address;
public $email3address;
public $fileas;
public $home2phonenumber;
public $homecity;
public $homecountry;
public $homepostalcode;
public $homestate;
public $homestreet;
public $homefaxnumber;
public $title;
public $middlename;
public $othercity;
public $othercountry;
public $otherpostalcode;
public $otherstate;
public $otherstreet;
public $radiophonenumber;
public $spouse;
public $suffix;
public $webpage;
public $yomicompanyname;
public $yomifirstname;
public $yomilastname;
public $rtf;
public $categories;
public $governmentid;
public $imaddress;
public $imaddress2;
public $imaddress3;
public $managername;
public $companymainphone;
public $nickname;
public $mms;
public $asbody;
/**
* Returns a hash of the data mapped from the GAB.
*
* @access public
* @return string
*/
public function GetHash() {
if (!isset($this->hash) || $this->hash == "") {
$this->hash = md5(serialize($this));
}
return $this->hash;
}
/**
* Returns the properties which have to be unset on the server.
*
* @access public
* @return array
*/
public function getUnsetVars() {
return array();
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment