Parsing vCard in php - php

Hi i want to parse vCard format to a array. User may upload vCard 2,1 or vCard 3.0 i should be able to parse it. I just want the email with names in the vCard in to a php array.
i have tried vcardphp.sourceforge.net.
<?php
require("vcard.php");
$cards = parse_vcards(file('sample.txt'));
print_r($cards);
function parse_vcards($lines)
{
$cards = array();
$card = new VCard();
while ($card->parse($lines)) {
$property = $card->getProperty('N');
if (!$property) {
return "";
}
$n = $property->getComponents();
$tmp = array();
if ($n[3]) $tmp[] = $n[3]; // Mr.
if ($n[1]) $tmp[] = $n[1]; // John
if ($n[2]) $tmp[] = $n[2]; // Quinlan
if ($n[4]) $tmp[] = $n[4]; // Esq.
$ret = array();
if ($n[0]) $ret[] = $n[0];
$tmp = join(" ", $tmp);
if ($tmp) $ret[] = $tmp;
$key = join(", ", $ret);
$cards[$key] = $card;
// MDH: Create new VCard to prevent overwriting previous one (PHP5)
$card = new VCard();
}
ksort($cards);
return $cards;
}
?>
Undefined index: ENCODING in H:\www\vcardphp\vcard.php on line 146
Notice: Undefined index: CHARSET in H:\www\vcardphp\vcard.php on line 149
and the sample code given doesnt work at all Too many Undefined index: errors

I would take a look at the open source project vCard PHP. Has worked for me!
http://vcardphp.sourceforge.net/

It's just that the http://vcardphp.sourceforge.net/ sample doesn't work with the given code. You can modify the code to make it work (so it doesn't fail on missing data - first from vbook.php:
See the added: if (!empty($n[*])) $tmp[] = $n[*];
function parse_vcards(&$lines)
{
$cards = array();
$card = new VCard();
while ($card->parse($lines)) {
$property = $card->getProperty('N');
if (!$property) {
return "";
}
$n = $property->getComponents();
$tmp = array();
if (!empty($n[3])) $tmp[] = $n[3]; // Mr.
if (!empty($n[1])) $tmp[] = $n[1]; // John
if (!empty($n[2])) $tmp[] = $n[2]; // Quinlan
if (!empty($n[4])) $tmp[] = $n[4]; // Esq.
$ret = array();
if (!empty($n[0])) $ret[] = $n[0];
$tmp = join(" ", $tmp);
if ($tmp) $ret[] = $tmp;
$key = join(", ", $ret);
$cards[$key] = $card;
// MDH: Create new VCard to prevent overwriting previous one (PHP5)
$card = new VCard();
}
ksort($cards);
return $cards;
}
And modify the vcard.php parse function to accomodate not having the expected parameters.
function parse(&$lines)
{
while (list(, $line) = each($lines)) {
$line = rtrim($line);
$tmp = split_quoted_string(":", $line, 2);
if (count($tmp) == 2) {
$this->value = $tmp[1];
$tmp = strtoupper($tmp[0]);
$tmp = split_quoted_string(";", $tmp);
$this->name = $tmp[0];
$this->params = array();
for ($i = 1; $i < count($tmp); $i++) {
$this->_parseParam($tmp[$i]);
}
$encoding_defined = array_key_exists('ENCODING', $this->params);
if ($encoding_defined && $this->params['ENCODING'][0] == 'QUOTED-PRINTABLE') {
$this->_decodeQuotedPrintable($lines);
}
$charset_defined = array_key_exists('CHARSET', $this->params);
if ($charset_defined && $this->params['CHARSET'][0] == 'UTF-8') {
$this->value = utf8_decode($this->value);
}
return true;
}
}
return false;
}

Related

Unable to edit while using trim in function

I am designing an application and in my modal came across a strange error where i am unable to edit the entry
Below is the modal where its showing the error lies :
<?php
include_once dirname(dirname(dirname(__FILE__))) . "/const.php";
include_once PHP_PATH . "/config1.php";
include_once CONFIG_PATH.'/modal/routemgmt/route_mgmt.php';
function sanitize($input) {
if (is_array($input))
return array_map('sanitize', $input);
else
return htmlspecialchars(trim($input));
}
// Sanitize all the incoming data
$sanitized = array_map('sanitize', $_POST);
$reason = $sanitized['reason'];
if($reason == "insert"){
$staffs = [];
$stops = [];
$name = $sanitized['rname'];
$code = $sanitized['rcode'];
$desc = $sanitized['rdesc'];
$vnum = $sanitized['vnum'];
$stf = $_POST['staff'];
$st = isset($_POST['stops'])? $_POST['stops']: [];
$st = [];
// foreach($staffs as $staff){
// $stf[] = array_map('sanitize', $staff);
// }
// if(isset($stops)){
// foreach($stops as $stop){
// $st[] = array_map('sanitize', $stop);
// }
// }
$val = insertRoute($conn,$name, $code, $desc, $vnum, $stf, $stops);
echo $val;
}
if($reason == "view"){
$id = $sanitized['id'];
$val = [];
$val = viewRoute($conn,$id);
echo json_encode($val);
}
if($reason == "edit"){
$stf = [];
$stp = [];
$id = $sanitized['pkid'];
$name = $sanitized['rname'];
$code = $sanitized['rcode'];
$desc = $sanitized['rdesc'];
$vnum = $sanitized['vnum'];
$estaffs = $_POST['estaff'];
$estops = $_POST['estops'];
$edel = $_POST['del'];
foreach($estaffs as $val){
$stf[] = array_map('sanitize', $val);
}
foreach($estops as $val){
$stp[] = array_map('sanitize', $val);
}
$cnt = 0;$n_stp = [];
for($i = 0; $i<sizeof($stp); $i++){
if($stp[$i]['stat'] != "Exist"){
$n_stp[$cnt] = $stp[$i];
$cnt++;
}
}
$val = editValues($conn,$id, $name, $code, $desc, $vnum, $stf, $n_stp, $edel);
echo $val;
}
if($reason == "delRoute"){
$id = $sanitized['id'];
$val = delRoute($conn,$id);
echo $val;
}
I tried changing the function to :
function sanitize($input) {
return htmlspecialchars(trim($input));
}
But then it started giving me the below error
<b>Warning</b>: trim() expects parameter 1 to be string, array given in <b>C:\xampp\htdocs\gurukul\demo2\controller\routemgmt\route_mgmt.php</b> on line <b>7</b><br />
As far as I can understand its passing an array instead of string in trim.
Can someone please guide me how can I resolve this ? Tried few debugging steps but didnt get succeded
In this function you are returning array in your if statement when it should just be a string all the time.
Replace:
function sanitize($input) {
if (is_array($input))
return array_map('sanitize', $input);
else
return htmlspecialchars(trim($input));
}
With:
function sanitize($input) {
if (is_array($input))
return sanitize($input);
else
return htmlspecialchars(trim($input));
}
You need to return value as string not array. Don't mess with the $_POST one.
Replace all:
array_map('sanitize', $val);
With:
sanitize($val);

Trim Error occuring in PHP

I am designing an application and in my modal came across a strange error
<b>Warning</b>: trim() expects parameter 1 to be string, array given in <b>C:\xampp\htdocs\gurukul\demo2\controller\routemgmt\route_mgmt.php</b> on line <b>7</b><br />
61
As far as I can understand its passing an array instead of string in trim. Below is the modal where its showing the error lies :
<?php
include_once dirname(dirname(dirname(__FILE__))) . "/const.php";
include_once PHP_PATH . "/config1.php";
include_once CONFIG_PATH.'/modal/routemgmt/route_mgmt.php';
function sanitize($input) {
return htmlspecialchars(trim($input));
}
// Sanitize all the incoming data
$sanitized = array_map('sanitize', $_POST);
$reason = $sanitized['reason'];
if($reason == "insert"){
$staffs = [];
$stops = [];
$name = $sanitized['rname'];
$code = $sanitized['rcode'];
$desc = $sanitized['rdesc'];
$vnum = $sanitized['vnum'];
$stf = $_POST['staff'];
$st = isset($_POST['stops'])? $_POST['stops']: [];
$st = [];
// foreach($staffs as $staff){
// $stf[] = array_map('sanitize', $staff);
// }
// if(isset($stops)){
// foreach($stops as $stop){
// $st[] = array_map('sanitize', $stop);
// }
// }
$val = insertRoute($conn,$name, $code, $desc, $vnum, $stf, $stops);
echo $val;
}
if($reason == "view"){
$id = $sanitized['id'];
$val = [];
$val = viewRoute($conn,$id);
echo json_encode($val);
}
if($reason == "edit"){
$stf = [];
$stp = [];
$id = $sanitized['pkid'];
$name = $sanitized['rname'];
$code = $sanitized['rcode'];
$desc = $sanitized['rdesc'];
$vnum = $sanitized['vnum'];
$estaffs = $_POST['estaff'];
$estops = $_POST['estops'];
$edel = $_POST['del'];
foreach($estaffs as $val){
$stf[] = array_map('sanitize', $val);
}
foreach($estops as $val){
$stp[] = array_map('sanitize', $val);
}
$cnt = 0;$n_stp = [];
for($i = 0; $i<sizeof($stp); $i++){
if($stp[$i]['stat'] != "Exist"){
$n_stp[$cnt] = $stp[$i];
$cnt++;
}
}
$val = editValues($conn,$id, $name, $code, $desc, $vnum, $stf, $n_stp, $edel);
echo $val;
}
if($reason == "delRoute"){
$id = $sanitized['id'];
$val = delRoute($conn,$id);
echo $val;
}
Can someone please guide me how can I resolve this ? Tried few debugging steps but didnt get succeded
You could rewrite your sanitize function as:
function sanitize($input) {
if (is_array($input))
return array_map('sanitize', $input);
else
return htmlspecialchars(trim($input));
}
That way it will handle a value passed to it which is an array.
Your $_POST variable probably contains some kind of array. Either figure out what you're posting by checking the output of var_dump($input) inside your sanitize function or change it to this:
function sanitize($input) {
return htmlspecialchars(trim((string) $input));
}
if you just want it to work.

How can I parse my Apple Mac contacts vCard correctly?

I am working with the vCard Parser from Sourceforge https://sourceforge.net/projects/vcardphp/files/vcardphp/vcardphp-1.1.2/
I just post an excerpt here:
vcard.php
function parse(&$lines)
{
$this->_map = null;
$property = new VCardProperty();
while ($property->parse($lines)) {
if (is_null($this->_map)) {
if ($property->name == 'BEGIN') {
$this->_map = array();
}
} else {
if ($property->name == 'END') {
break;
} else {
$this->_map[$property->name][] = $property;
}
}
// MDH: Create new property to prevent overwriting previous one
// (PHP5)
$property = new VCardProperty();
}
return $this->_map != null;
}
function parse(&$lines)
{
while (list(, $line) = each($lines)) {
$line = rtrim($line);
$tmp = split_quoted_string(":", $line, 2);
if (count($tmp) == 2) {
$this->value = $tmp[1];
$tmp = strtoupper($tmp[0]);
$tmp = split_quoted_string(";", $tmp);
$this->name = $tmp[0];
$this->params = array();
for ($i = 1; $i < count($tmp); $i++) {
$this->_parseParam($tmp[$i]);
}
if ($this->params['ENCODING'][0] == 'QUOTED-PRINTABLE') {
$this->_decodeQuotedPrintable($lines);
}
if ($this->params['CHARSET'][0] == 'UTF-8') {
$this->value = utf8_decode($this->value);
}
return true;
}
}
return false;
}
and
vbook.php
function parse_vcards(&$lines)
{
$cards = array();
$card = new VCard();
while ($card->parse($lines)) {
$property = $card->getProperty('N');
if (!$property) {
return "";
}
$n = $property->getComponents();
$tmp = array();
if ($n[3]) $tmp[] = $n[3]; // Mr.
if ($n[1]) $tmp[] = $n[1]; // John
if ($n[2]) $tmp[] = $n[2]; // Quinlan
if ($n[4]) $tmp[] = $n[4]; // Esq.
$ret = array();
if ($n[0]) $ret[] = $n[0];
$tmp = join(" ", $tmp);
if ($tmp) $ret[] = $tmp;
$key = join(", ", $ret);
$cards[$key] = $card;
// MDH: Create new VCard to prevent overwriting previous one (PHP5)
$card = new VCard();
}
ksort($cards);
return $cards;
}
function print_vcard($card, $hide)
{
$names = array('N', 'FN', 'TITLE', 'TEL', 'EMAIL', 'URL', 'ADR', 'NOTE');
$row = 0;
foreach ($names as $name) {
if (in_array_case($name, $hide)) {
continue;
}
$properties = $card->getProperties($name);
if ($properties) {
foreach ($properties as $property) {
$show = true;
$types = $property->params['TYPE'];
if ($types) {
foreach ($types as $type) {
if (in_array_case($type, $hide)) {
$show = false;
break;
}
}
}
if ($show) {
$class = ($row++ % 2 == 0) ? "property-even" : "property-odd";
print_vcard_property($property, $class, $hide);
}
}
}
}
}
function print_vcard_property($property, $class, $hide)
{
$name = $property->name;
$value = $property->value;
$types = $property->params['TYPE'];
if ($types) {
print_r(array_filter($types));
}
switch ($name) {
case 'N':
$name = $property->getComponents();
print_r(array_filter($name));
break;
case 'TEL':
$tel = $property->getComponents();
print_r(array_filter($tel));
break;
case 'FN':
$company = $property->getComponents();
print_r(array_filter($company));
break;
case 'ADR':
$adr = $property->getComponents();
print_r(array_filter($adr));
break;
case 'EMAIL':
$email = $property->getComponents();
print_r(array_filter($email));
break;
case 'URL':
$url = $property->getComponents();
print_r(array_filter($url));
break;
default:
$components = $property->getComponents();
$lines = array();
foreach ($components as $component) {
if ($component) {
$lines[] = $component;
}
}
$html = join("\n", $lines);
break;
}
echo "<br>";
echo "<br><br>";
}
It works quite well when I am using the sample vcard file, which looks like this:
BEGIN:VCARD
N:Smith;Jim;Alvin;Mr.
FN:Jim A. Smith
CATEGORIES:Family
BDAY:1977-01-27
ADR;WORK:;Suite 900;11 5th Street;Coco Beach;FL;32082
ADR;HOME:;;198 Elm Street;Coco Beach;FL;32082
TEL;WORK:904-555-9384;
TEL;HOME:904-873-0394
TEL;CELL:904-934-3429
END:VCARD
But my vcard from Apple Contacts looks a little bit different:
BEGIN:VCARD
N:Underwood;Frank;;;
FN:Frank Underwood
item1.EMAIL;type=INTERNET;type=pref:frank.underwood#hoc.com
item2.TEL;type=pref:+01 321 323123123
item2.X-ABLabel:Mobil
item3.ADR;type=pref:;;Richmondstreet 21;Washington D.C;;12312;
item4.URL;type=pref:http://www.frankunderwood.com/
item4.X-ABLabel:_$!<HomePage>!$_
CATEGORIES:Friends
END:VCARD
So in my example only the name of the person is printed, not the email, phone, address or url. So in the parsing I need to remove item1,item2 and so on. But I do not know how to do that.
Here is a solution how to export the Apple Contacts into a proper vCard file, that can be parsed correctly:
Go to Contacts/Settings/vCard and change the format to 2.1 and Unicode (UTF-8)

Comma separated string to parent child relationship array php

I have a comma separated string like
$str = "word1,word2,word3";
And i want to make a parent child relationship array from it.
Here is an example:
Try this simply making own function as
$str = "word1,word2,word3";
$res = [];
function makeNested($arr) {
if(count($arr)<2)
return $arr;
$key = array_shift($arr);
return array($key => makeNested($arr));
}
print_r(makeNested(explode(',', $str)));
Demo
function tooLazyToCode($string)
{
$structure = null;
foreach (array_reverse(explode(',', $string)) as $part) {
$structure = ($structure == null) ? $part : array($part => $structure);
}
return $structure;
}
Please check below code it will take half of the time of the above answers:
<?php
$str = "sports,cricket,football,hockey,tennis";
$arr = explode(',', $str);
$result = array();
$arr_len = count($arr) - 1;
$prev = $arr_len;
for($i = $arr_len; $i>=0;$i--){
if($prev != $i){
$result = array($arr[$i] => $result);
} else {
$result = array ($arr[$i]);
}
$prev = $i;
}
echo '<pre>',print_r($result),'</pre>';
Here is another code for you, it will give you result as you have asked :
<?php
$str = "sports,cricket,football,hockey,tennis";
$arr = explode(',', $str);
$result = array();
$arr_len = count($arr) - 1;
$prev = $arr_len;
for($i = $arr_len; $i>=0;$i--){
if($prev != $i){
if($i == 0){
$result = array($arr[$i] => $result);
}else{
$result = array(array($arr[$i] => $result));
}
} else {
$result = array ($arr[$i]);
}
$prev = $i;
}
echo '<pre>',print_r($result),'</pre>';

Naive Bayes in PHP

I’m trying to implement a Naive Bayes classifier in PHP, and I found this script.
I’m running the script on a standard LAMP stack (php-fpm), and I am getting a an error:
Fatal error: Call to undefined function 3184791920() in
/location/file.php on line 73
But I can't figure out what is causing this, since there is no 3184791920() function. I assume it has something to do with the hashing:
define("LL_NB_HASH_FUNCTION", "crc32");
Here is the full text of my implementation:
<?php
global $LL_NB_STOP_WORDS;
$LL_NB_STOP_WORDS = array("a", "about", "above", "...");
define("LL_NB_HASH_FUNCTION", "crc32");// crc32 is the fastest built in hash function.
// $xs is a bunch of "strings" and ys are their labels.
function ll_naivebayes($xs, $ys, $testStrings) {
$topicWords = array();
foreach($xs as $i=>$x) {
if(isset($topicWords[$ys[$i]]))
$topicWords[$ys[$i]] .= $x;
else
$topicWords[$ys[$i]] = $x;
}
$topicWords = _ll_computeWordCounts($topicWords); // get the number of each word, by topic.
$probWordsGivenTopic = array(); // probability of each word in a given topic.
$countTopics = array();
foreach($topicWords as $topicIndex=>$xWordCounts) {
$totalWordsTopic = array_sum($xWordCounts);
$countTopics[$topicIndex] = $total_wordsTopic;
foreach($xCount as $hash=>$count) {
$probWordsGivenTopic[$topicIndex][$hash] = ($count/$totalWordsTopic);
}
}
$probTopics = array(); // probability of a given topic (number of words / total words), i.e., relative frequency of topics in terms of words
foreach($countTopics as $i=>$topicCount) {
$probTopics[$i] = ($topicCount/$totalWords);
}
if(!is_array($testStrings))
$testStrings = array($testStrings);
// process the input testStrings array
$return = array();
foreach($testStrings as $i=>$string) {
$testStringWords = _ll_computeWordCount($string);
$topicsPosterior = array();
foreach($probTopics as $key=>$probTopic) {
$p = $probTopic;
foreach($testStringWords as $hash=>$count) {
if(isset($probWordsGivenTopic[$key][$hash]))
$p *= $probWordsGivenTopic[$key][$hash] * $count;
}
$topicsPosterior[$key] = $p;
}
sort($topicsPosterior);
$return[$i] = $topicsPosterior;
}
return $return;
}
function _ll_computeWordCounts($strings) {
$wcs = array();
foreach($strings as $string) {
$wcs[] = _ll_computeWordCount($string);
}
return $wcs;
}
function _ll_computeWordCount($string) {
$string = trim($string);
$string = explode(' ', $string);
natcasesort($string);
$hash = LL_NB_HASH_FUNCTION;
$words = array();
for($i=0, $count = count($string); $i<$count; $i++) {
$word = trim($string[$i]);
if(preg_match('/[^a-zA-Z\']/', $word))
continue;
$hash = (string) $hash($word);
if(!isset($words[$hash]))
$words[$hash] = 1; //$words[$hash] = array('word'=>$word, 'count'=>1);
else
$words[$hash]++; //$words[$hash]['count']++;
}
return $words;
}
$output = ll_naivebayes(array("Will I marry John", "Marriage is cool", "A string about Windows XP"), array("marriage", "marriage", "windows"), array("this is about marriage"));
?>
It looks like a bug see my comments in the code
function _ll_computeWordCount($string) {
$string = trim($string);
$string = explode(' ', $string);
natcasesort($string);
$hash = LL_NB_HASH_FUNCTION; // $hash = crc32
$words = array();
for($i=0, $count = count($string); $i<$count; $i++) {
$word = trim($string[$i]);
if(preg_match('/[^a-zA-Z\']/', $word))
continue;
$hash = (string) $hash($word); // 1st iteration $hash = crc32($word)
//2nd iteration $hash = 2949202($word) - fatal error
if(!isset($words[$hash]))
$words[$hash] = 1; //$words[$hash] = array('word'=>$word, 'count'=>1);
else
$words[$hash]++; //$words[$hash]['count']++;
}
return $words;
}
Try this
function _ll_computeWordCount($string) {
$string = trim($string);
$string = explode(' ', $string);
natcasesort($string);
$hash_function = LL_NB_HASH_FUNCTION;
$words = array();
for($i=0, $count = count($string); $i<$count; $i++) {
$word = trim($string[$i]);
if(preg_match('/[^a-zA-Z\']/', $word))
continue;
$hash = (string) $hash_function($word);
if(!isset($words[$hash]))
$words[$hash] = 1; //$words[$hash] = array('word'=>$word, 'count'=>1);
else
$words[$hash]++; //$words[$hash]['count']++;
}
return $words;
}

Categories