Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow * and # in phone numbers and config option to disable image processing #40

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@ Now you should have everything setup and checked out to a 'carddav2fb' directory
$config['addnames'] = false; // include additionalnames in fullname if existing
$config['orgname'] = false; // include organisation (company) in fullname if existing

$config['quickdial_keyword'] = 'Quickdial:'; // once activated you may add 'Quickdial:+49030123456:**709' to the contact note field and the number will be set as quickdialnumber in your FRITZ!Box. It is possible to add more quickdials for one contact each in a new line
// $config['images'] = false; // option to disable image processing and FTP-Upload

$config['quickdial_keyword'] = 'Quickdial:'; // once activated you may add 'Quickdial:+49030123456:**709' to the contact note field and the number will be set as quickdialnumber in your FRITZ!Box. It is possible to add more quickdials for one contact each in a new line. The number used in in the quickdialnote must be found in as phonenumber in the contact as well.

// first
$config['carddav'][0] = array(
Expand All @@ -97,4 +99,4 @@ This script is using third-party libraries for downloading VCards from CardDAV s
This script is released under Public Domain.

## Authors
Copyright (c) 2012-2016 Karl Glatz, Martin Rost, Jens Maus, Johannes Freiburger
Copyright (c) 2012-2016 Karl Glatz, Martin Rost, Jens Maus, Johannes Freiburger, holzhannes
241 changes: 124 additions & 117 deletions carddav2fb.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@
* Martin Rost
* Jens Maus <[email protected]>
* Johannes Freiburger
* holzhannes <[email protected]>
*
*/
error_reporting(E_ALL);
setlocale(LC_ALL, 'de_DE.UTF8');

// Version identifier for CardDAV2FB
$carddav2fb_version = '1.11 (2016-05-12)';
$carddav2fb_version = '1.12 (2017-11-12)';

// check for the minimum php version
$php_min_version = '5.3.6';
Expand Down Expand Up @@ -56,7 +57,7 @@
$config['suffix'] = false;
$config['addnames'] = false;
$config['orgname'] = false;
$config['build_photos'] = true;
$config['images'] = true;
$config['quickdial_keyword'] = 'Quickdial:';

if(is_file($config_file_name))
Expand All @@ -70,7 +71,7 @@
// ---------------------------------------------
// MAIN
print "carddav2fb.php " . $carddav2fb_version . " - CardDAV to FRITZ!Box phonebook conversion tool" . PHP_EOL;
print "Copyright (c) 2012-2016 Karl Glatz, Martin Rost, Jens Maus, Johannes Freiburger" . PHP_EOL . PHP_EOL;
print "Copyright (c) 2012-2016 Karl Glatz, Martin Rost, Jens Maus, Johannes Freiburger, holzhannes" . PHP_EOL . PHP_EOL;

$client = new CardDAV2FB($config);

Expand Down Expand Up @@ -111,7 +112,8 @@ public function __construct($config)
$this->config = $config;

// create a temp directory where we store photos
$this->tmpdir = $this->mktemp($this->config['tmp_dir']);
if($config['images'])
$this->tmpdir = $this->mktemp($this->config['tmp_dir']);
}

public function __destruct()
Expand Down Expand Up @@ -392,7 +394,7 @@ public function get_carddav_entries()
if($found > 0)
{
$pos_qd_start = strrpos($linecontent, ":**7");
$quick_dial_for_nr = preg_replace("/[^0-9+]/", "", substr($linecontent, 0, $pos_qd_start));
$quick_dial_for_nr = $this->_clear_phone_number(substr($linecontent, 0, $pos_qd_start));
$quick_dial_nr = intval(substr($linecontent, $pos_qd_start + 4, 3));
$quick_dial_arr[$quick_dial_for_nr] = $quick_dial_nr;
}
Expand Down Expand Up @@ -434,7 +436,7 @@ public function get_carddav_entries()
{
$phone_number = $t['value'];

$phone_number_clean = preg_replace("/[^0-9+]/", "", $phone_number);
$phone_number_clean = $this->_clear_phone_number($phone_number);
foreach($quick_dial_arr as $qd_phone_nr => $value)
{
if($qd_phone_nr == $phone_number_clean)
Expand Down Expand Up @@ -517,7 +519,7 @@ public function get_carddav_entries()

private function _clear_phone_number($number)
{
return preg_replace("/[^0-9+]/", "", $number);
return preg_replace("/[^0-9+*#]/", "", $number);
}

public function build_fb_xml()
Expand Down Expand Up @@ -577,53 +579,55 @@ public function build_fb_xml()
print " Added email: " . $mail['value'] . " (" . $mail['type'] . ")" . PHP_EOL;
}

// check for a photo being part of the VCard
if(($entry['photo']) and ($entry['photo_data']) and (is_array($entry['photo_data'])) and ($entry['photo_data'][0]))
{
// check if 'photo_data'[0] is an array as well because then
// we have to extract ['value'] and friends.
if(is_array($entry['photo_data'][0]) and (array_key_exists('value', $entry['photo_data'][0])))
if($this->config['images']) {
// check for a photo being part of the VCard
if(($entry['photo']) and ($entry['photo_data']) and (is_array($entry['photo_data'])) and ($entry['photo_data'][0]))
{
// check if photo_data really contains JPEG data
if((array_key_exists('type', $entry['photo_data'][0])) and (is_array($entry['photo_data'][0]['type'])) and
($entry['photo_data'][0]['type'][0] == 'jpeg' or $entry['photo_data'][0]['type'][0] == 'jpg' or $entry['photo_data'][0]['type'][0] == 'image/jpeg'))
// check if 'photo_data'[0] is an array as well because then
// we have to extract ['value'] and friends.
if(is_array($entry['photo_data'][0]) and (array_key_exists('value', $entry['photo_data'][0])))
{
// get photo, rename, base64 convert and save as jpg
$photo_data = $entry['photo_data'][0]['value'];
$photo_version = substr(sha1($photo_data), 0, 5);
$photo_file = $this->tmpdir . '/' . "{$entry['photo']}_{$photo_version}.jpg";

// check for base64 encoding of the photo data and convert it
// accordingly.
if(((array_key_exists('encoding', $entry['photo_data'][0])) and ($entry['photo_data'][0]['encoding'] == 'b')) or $this->is_base64($photo_data))
// check if photo_data really contains JPEG data
if((array_key_exists('type', $entry['photo_data'][0])) and (is_array($entry['photo_data'][0]['type'])) and
($entry['photo_data'][0]['type'][0] == 'jpeg' or $entry['photo_data'][0]['type'][0] == 'jpg' or $entry['photo_data'][0]['type'][0] == 'image/jpeg'))
{
file_put_contents($photo_file . ".b64", $photo_data);
$this->base64_to_jpeg($photo_file . ".b64", $photo_file);
unlink($photo_file . ".b64");
// get photo, rename, base64 convert and save as jpg
$photo_data = $entry['photo_data'][0]['value'];
$photo_version = substr(sha1($photo_data), 0, 5);
$photo_file = $this->tmpdir . '/' . "{$entry['photo']}_{$photo_version}.jpg";

// check for base64 encoding of the photo data and convert it
// accordingly.
if(((array_key_exists('encoding', $entry['photo_data'][0])) and ($entry['photo_data'][0]['encoding'] == 'b')) or $this->is_base64($photo_data))
{
file_put_contents($photo_file . ".b64", $photo_data);
$this->base64_to_jpeg($photo_file . ".b64", $photo_file);
unlink($photo_file . ".b64");
}
else
{
print " WARNING: non-base64 encoded photo data found and used." . PHP_EOL;
file_put_contents($photo_file, $photo_data);
}

// add contact photo to xml
$person->addChild("imageURL", $this->config['fritzbox_path'] . $this->config['usb_disk'] . "FRITZ/fonpix/" . basename($photo_file));

print " Added photo: " . basename($photo_file) . PHP_EOL;
}
else
{
print " WARNING: non-base64 encoded photo data found and used." . PHP_EOL;
file_put_contents($photo_file, $photo_data);
}

print " WARNING: Only jpg contact photos are currently supported." . PHP_EOL;
}
elseif(substr($entry['photo_data'][0], 0, 4) == 'http')
{
// add contact photo to xml
$person->addChild("imageURL", $this->config['fritzbox_path'] . $this->config['usb_disk'] . "FRITZ/fonpix/" . basename($photo_file));
$person->addChild("imageURL", $entry['photo_data'][0]);

print " Added photo: " . basename($photo_file) . PHP_EOL;
print " Added photo: " . $entry['photo_data'][0] . PHP_EOL;
}
else
print " WARNING: Only jpg contact photos are currently supported." . PHP_EOL;
}
elseif(substr($entry['photo_data'][0], 0, 4) == 'http')
{
// add contact photo to xml
$person->addChild("imageURL", $entry['photo_data'][0]);

print " Added photo: " . $entry['photo_data'][0] . PHP_EOL;
print " WARNING: Only VCard embedded photo data or a reference URL is currently supported." . PHP_EOL;
}
else
print " WARNING: Only VCard embedded photo data or a reference URL is currently supported." . PHP_EOL;
}

$contact->addChild("services");
Expand Down Expand Up @@ -697,102 +701,105 @@ public function upload_to_fb()
// temp directory.

// perform an ftps-connection to copy over the photos to a specified directory
$ftp_server = $this->config['fritzbox_ip_ftp'];
$conn_id = ftp_ssl_connect($ftp_server);
if($conn_id == false)
{
print " WARNING: Secure connection to FTP-server '" . $ftp_server . "' failed, retrying without SSL." . PHP_EOL;
$conn_id = ftp_connect($ftp_server);
}

if($conn_id != false)
{
ftp_set_option($conn_id, FTP_TIMEOUT_SEC, 60);
$login_result = ftp_login($conn_id, $this->config['fritzbox_user'], $this->config['fritzbox_pw']);
if($login_result === true)
if ($this->config['images']) {
$ftp_server = $this->config['fritzbox_ip_ftp'];
$conn_id = ftp_ssl_connect($ftp_server);
if($conn_id == false)
{
ftp_pasv($conn_id, true);
print " WARNING: Secure connection to FTP-server '" . $ftp_server . "' failed, retrying without SSL." . PHP_EOL;
$conn_id = ftp_connect($ftp_server);
}

// create remote photo path on FRITZ!Box if it doesn't exist
$remote_path = $this->config['usb_disk'] . "/FRITZ/fonpix";
$all_existing_files = ftp_nlist($conn_id, $remote_path);
if($all_existing_files == false)
if($conn_id != false)
{
ftp_set_option($conn_id, FTP_TIMEOUT_SEC, 60);
$login_result = ftp_login($conn_id, $this->config['fritzbox_user'], $this->config['fritzbox_pw']);
if($login_result === true)
{
ftp_mkdir($conn_id, $remote_path);
$all_existing_files = array();
}
ftp_pasv($conn_id, true);

// now iterate through all jpg files in tempdir and upload them if necessary
$dir = new DirectoryIterator($this->tmpdir);
foreach($dir as $fileinfo)
{
if(!$fileinfo->isDot())
// create remote photo path on FRITZ!Box if it doesn't exist
$remote_path = $this->config['usb_disk'] . "/FRITZ/fonpix";
$all_existing_files = ftp_nlist($conn_id, $remote_path);
if($all_existing_files == false)
{
if($fileinfo->getExtension() == "jpg")
{
$file = $fileinfo->getFilename();
ftp_mkdir($conn_id, $remote_path);
$all_existing_files = array();
}

print " FTP-Upload '" . $file . "'...";
if(!in_array($remote_path . "/" . $file, $all_existing_files))
// now iterate through all jpg files in tempdir and upload them if necessary
$dir = new DirectoryIterator($this->tmpdir);
foreach($dir as $fileinfo)
{
if(!$fileinfo->isDot())
{
if($fileinfo->getExtension() == "jpg")
{
if(!ftp_put($conn_id, $remote_path . "/" . $file, $fileinfo->getPathname(), FTP_BINARY))
{
// retry when a fault occurs.
print " retrying... ";
$conn_id = ftp_ssl_connect($ftp_server);
if($conn_id == false)
{
print " WARNING: Secure re-connection to FTP-server '" . $ftp_server . "' failed, retrying without SSL." . PHP_EOL;
$conn_id = ftp_connect($ftp_server);
}

if($conn_id == false)
{
print " ERROR: couldn't re-connect to FTP server '" . $ftp_server . "', abortіng." . PHP_EOL;
break;
}
$file = $fileinfo->getFilename();

$login_result = ftp_login($conn_id, $this->config['fritzbox_user'], $this->config['fritzbox_pw']);
if($login_result === false)
print " FTP-Upload '" . $file . "'...";
if(!in_array($remote_path . "/" . $file, $all_existing_files))
{
if(!ftp_put($conn_id, $remote_path . "/" . $file, $fileinfo->getPathname(), FTP_BINARY))
{
print " ERROR: couldn't re-login to FTP-server '" . $ftp_server . "' with provided username/password settings." . PHP_EOL;
break;
// retry when a fault occurs.
print " retrying... ";
$conn_id = ftp_ssl_connect($ftp_server);
if($conn_id == false)
{
print " WARNING: Secure re-connection to FTP-server '" . $ftp_server . "' failed, retrying without SSL." . PHP_EOL;
$conn_id = ftp_connect($ftp_server);
}

if($conn_id == false)
{
print " ERROR: couldn't re-connect to FTP server '" . $ftp_server . "', abortіng." . PHP_EOL;
break;
}

$login_result = ftp_login($conn_id, $this->config['fritzbox_user'], $this->config['fritzbox_pw']);
if($login_result === false)
{
print " ERROR: couldn't re-login to FTP-server '" . $ftp_server . "' with provided username/password settings." . PHP_EOL;
break;
}

ftp_pasv($conn_id, true);
if(!ftp_put($conn_id, $remote_path . "/" . $file, $fileinfo->getPathname(), FTP_BINARY))
print " ERROR: while uploading file " . $fileinfo->getFilename() . PHP_EOL;
else
print " ok." . PHP_EOL;
}

ftp_pasv($conn_id, true);
if(!ftp_put($conn_id, $remote_path . "/" . $file, $fileinfo->getPathname(), FTP_BINARY))
print " ERROR: while uploading file " . $fileinfo->getFilename() . PHP_EOL;
else
print " ok." . PHP_EOL;
}
else
print " ok." . PHP_EOL;

// cleanup old files
foreach($all_existing_files as $existing_file)
{
if(strpos($existing_file, $remote_path . "/" . substr($file, 0, -10)) !== false)
// cleanup old files
foreach($all_existing_files as $existing_file)
{
print " FTP-Delete: " . $existing_file . PHP_EOL;
ftp_delete($conn_id, $remote_path . "/" . basename($existing_file));
if(strpos($existing_file, $remote_path . "/" . substr($file, 0, -10)) !== false)
{
print " FTP-Delete: " . $existing_file . PHP_EOL;
ftp_delete($conn_id, $remote_path . "/" . basename($existing_file));
}
}
}
else
print " already exists." . PHP_EOL;
}
else
print " already exists." . PHP_EOL;
}
}
}
else
print " ERROR: couldn't login to FTP-server '" . $ftp_server . "' with provided username/password settings." . PHP_EOL;

// close ftp connection
ftp_close($conn_id);
}
else
print " ERROR: couldn't login to FTP-server '" . $ftp_server . "' with provided username/password settings." . PHP_EOL;

// close ftp connection
ftp_close($conn_id);
print " ERROR: couldn't connect to FTP server '" . $ftp_server . "'." . PHP_EOL;
} else {
print " INFO: Image processing is disabled. Just remove value from the config to enable.". PHP_EOL;
}
else
print " ERROR: couldn't connect to FTP server '" . $ftp_server . "'." . PHP_EOL;

// lets post the phonebook xml to the FRITZ!Box
print " Uploading Phonebook XML to " . $this->config['fritzbox_ip'] . PHP_EOL;
try
Expand Down
2 changes: 2 additions & 0 deletions config.example.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
$config['addnames'] = false; // include additionalnames in fullname if existing
$config['orgname'] = false; // include organisation (company) in fullname if existing

//$config['images'] = false; // option to disable image processing and FTP-Upload

// Quickdial starting keyword in notes
//$config['quickdial_keyword'] = 'Quickdial:'; // once activated you may add 'Quickdial:+49030123456:**709' to the contact note field and the number will set as quickdialnumber. You may add more quickdials for a single contact each in a new line

Expand Down