NOT Included in any Wikka versionLast edited by
DomBonj:
1.1.6.5 compatibility Sun, 13 Jul 2008 17:04 EDT [
diff]
This is the development page for the Structdata action.
Installation
- Save the code below as actions/structdata.php
- Give it the same file permissions as the other php files in that directory.
- To achieve the best visual rendering of tables in versions 1.1.6.2 and 1.1.6.3, add the second code block below to the css/wikka.css file
Code
1. New
actions/structdata.php file:
<?php
#
# Defines + optionally displays a structured data item or
# displays the results of a selection request
#
# @package Actions
# @name structdata
#
# @authors DomBonj
# @version 1.01
#
# @input Parameters = (type='mytype' data='datalist' [print=('basic'|'table'|'list'|'false')]
# | req='reqid' [help][p1='val1'][p2='val2"][p3='val3'])
# $datalist: list of 'pname'='pval' parameters, separated by spaces.
# restrictions: pval shall not include a ' followed by a space
# $reqid : the name of a predefined request
# $val1, $val2, $val3 : optional parameters for request $reqid
# $help, if present, displays a one-line help for request $reqid
#
# @uses Wakka::ReturnSafeHTML()
# @uses Wakka::LoadAll()
# @uses Wakka::Href()
# @uses Wakka::GetPageTag()
# @uses Wakka::HasAccess()
# @uses Wakka::UserIsOwner()
#
# @notes Add your code into the flagged areas
#
// i18n strings
if (!
defined('SD_ERROR_PARAMETER_MANDATORY')) define ('SD_ERROR_PARAMETER_MANDATORY',
"The '%s' parameter is mandatory");
if (!
defined('SD_ERROR_INCORRECT_DATE_FORMAT')) define ('SD_ERROR_INCORRECT_DATE_FORMAT',
"Incorrect format for '%s' parameter: use 'yyyy-mm-dd'");
if (!
defined('SD_ERROR_USAGE')) define ('SD_ERROR_USAGE',
'Usage: structdata type=\'<i>mytype</i>\' [print=\'<i>printmode</i>\'] data="[more parameters]"');
if (!
defined('SD_HELP_TODOS')) define ('SD_HELP_TODOS',
' [p1=<i>owner</i>] [p2=<i>status</i>] ');
if (!
defined('SD_HELP_ITEMTABLE')) define ('SD_HELP_ITEMTABLE',
' p1=<i>type</i> [p2=<i>column order list</i>] [p3=<i>scope</i>]');
if (!
defined('SD_HELP_CARDS')) define ('SD_HELP_CARDS',
' [p1=<i>org filter</i>] [p2=<i>sort column name</i>] [p3=<i>format (vCard|table)</i>] ');
if (!
function_exists('SDerror'))
{
function SDerror
($msg)
{
return ('<em class="error">'.
$msg.
'</em><br />');
}
function SDformat_hcard_element
($eltype,
$elvalue)
{
switch ($eltype)
{
case 'family-name':
$ret =
'<span class="family-name">'.
ucwords(strtolower($elvalue)) .
'</span>';
break;
case 'given-name':
$ret =
'<span class="given-name">'.
ucwords(strtolower($elvalue)) .
'</span>';
break;
case 'additional-name':
$ret =
'<span class="additional-name">'.
ucwords(strtolower($elvalue)) .
'</span>';
break;
case 'url':
$ret =
'<a class="url" href="'.
$elvalue.
'">%s</a>';
break;
case 'org':
$ret =
'<div class="org">'.
$elvalue .
'</div>';
break;
case 'title':
$ret =
'<div class="title">'.
$elvalue .
'</div>';
break;
case 'note':
$ret =
'<div class="note">'.
$elvalue .
'</div>';
break;
case 'email':
$ret =
'<div class="email"><a href="mailto:'.
$elvalue.
'">'.
$elvalue .
'</a></div>';
break;
case 'adr':
$adr_array =
split(';',
$elvalue);
$ret =
'<div class="adr"><span class="street-address">'.
$adr_array[0] .
'</span>'.
((isset($adr_array[1]) &&
($adr_array[1]!=
'')) ?
'<span class="locality">'.
$adr_array[1] .
'</span>':
'') .
((isset($adr_array[2]) &&
($adr_array[2]!=
'')) ?
'<span class="postal-code">'.
$adr_array[2] .
'</span>':
'') .
((isset($adr_array[3]) &&
($adr_array[3]!=
'')) ?
'<span class="region">'.
$adr_array[3] .
'</span>':
'') .
((isset($adr_array[4]) &&
($adr_array[4]!=
'')) ?
'<span class="country-name">'.
$adr_array[4] .
'</span>':
'') .
'</div>';
break;
default:
// ignore silently
$ret =
'';
}
return $ret;
}
function SDhandle_item
($type,
$params,
$printmode)
{
$table_css =
'class="data" cellpadding="2" cellspacing="1" border="2"';
$myerr =
'';
extract($params);
$mystr =
'';
switch ($type)
{ // custom formatting, data validation and hyperlink addition
case 'ToDo':
if (!
$owner)
{
$myerr .= SDerror
(sprintf(SD_ERROR_PARAMETER_MANDATORY,
'owner'));
}
if (!
$desc)
{
$myerr .= SDerror
(sprintf(SD_ERROR_PARAMETER_MANDATORY,
'desc'));
}
preg_match('/(\d+)[\-\/](\d+)[\-\/](\d+)/',
$date_open,
$ymd);
if (!
checkdate($ymd[2],
$ymd[3],
$ymd[1]))
{
$myerr .= SDerror
(sprintf(SD_ERROR_INCORRECT_DATE_FORMAT,
'date_open'));
}
preg_match('/(\d+)[\-\/](\d+)[\-\/](\d+)/',
$date_due,
$ymd2);
if (!
checkdate($ymd2[2],
$ymd2[3],
$ymd2[1]))
{
$myerr .= SDerror
(sprintf(SD_ERROR_INCORRECT_DATE_FORMAT,
'date_due'));
}
break;
case 'Card':
if (!
$n)
{
$myerr .= SDerror
(sprintf(SD_ERROR_PARAMETER_MANDATORY,
'n'));
}
$n_array =
split(';',
$n);
if ('hCard' ==
$printmode)
{ // hCard microformat
$lastname = SDformat_hcard_element
('family-name',
$n_array[0]);
$firstname =
isset($n_array[1]) ? SDformat_hcard_element
('given-name',
$n_array[1]).
' ' :
'';
$middlename =
isset($n_array[2]) ? SDformat_hcard_element
('additional-name',
$n_array[2]) :
'';
$fullname =
'<span class="n"><span class="fn">'.
$firstname .
$lastname .
'</span>'.
$middlename .
'</span>';
$hyperlink =
isset($url) ? SDformat_hcard_element
('url',
$url) :
'%s';
$orgname =
'';
if (isset($org))
{
if ($org ==
$n)
{ // this is an organization's card: merge name and organization
$fullname =
str_replace('class="fn"',
'class="fn org"',
$fullname);
}
else
{
$orgname = SDformat_hcard_element
('org',
$org);
}
}
$phone =
isset($tel) ?
'<div class="tel"><span class="value">'.
$tel .
'</span></div>' :
'';
$fax =
isset($fax) ?
'<div class="tel"><span class="type">fax</span> <span class="value">'.
$fax .
'</span></div>' :
'';
$address =
isset($adr) ? SDformat_hcard_element
('adr',
$adr) :
'';
$mystr =
'<div class="vcard">'.
sprintf($hyperlink,
$fullname).
(isset($title) ? SDformat_hcard_element
('title',
$title) :
'').
$orgname .
(isset($email) ? SDformat_hcard_element
('email',
$email) :
'').
$phone .
$fax.
$address .
(isset($note) ? SDformat_hcard_element
('note',
$note) :
'').
'</div>';
}
else
{ // default print mode
$name =
(isset($n_array[1]) ?
(ucwords(strtolower($n_array[1])).
' ') :
'').
ucwords(strtolower($n_array[0]));
$tooltip =
isset($tel) ?
'phone: '.
$tel :
'';
$tooltip .=
(isset($fax) ?
($tooltip ?
' / fax: '.
$fax :
'fax: ' .
$fax) :
'');
$mystr =
"<a href='mailto:$email' title='$tooltip'>".
$name .
'</a>'.
($org !=
'' ?
' ('.
$org.
')' :
'');
}
break;
/*------------------------------- begin customization area -----------------------------
case 'mydataitem':
<my validation and hyperlinking code>
$mystr = <my formatting>;
break;
--------------------------------- end customization area -----------------------------*/
}
if (!
$mystr)
{ // type did not match any custom type : fallback to a standard type
echo ($printmode);
switch ($printmode)
{
case 'table':
$mystr =
'<table '.
$table_css .
'>';
$r1 =
'<thead><tr>';
$r2 =
'<tbody><tr>';
foreach ($params as $name =>
$value)
{
if ($name !=
'print')
{
$r1 .=
'<th>'.
$name .
'</th>';
$r2 .=
'<td>'.
$value .
'</td>';
}
}
$mystr .=
$r1 .
'</tr></thead>'.
$r2 .
'</tr></tbody></table>';
break;
case 'list':
$mystr =
'<table '.
$table_css .
'><thead><tr><th>name</th><th>value</th></tr></thead><tbody>';
foreach ($params as $name =>
$value)
{
if ($name !=
'print')
{
$mystr .=
'<tr><td align="right">'.
$name .
'</td><td>'.
$value .
'</td></tr>';
}
}
$mystr .=
'</tbody></table>';
break;
case 'basic':
default:
$mainparam =
(isset($value) ?
$value :
(isset($id) ?
$id :
(isset($name) ?
$name :
'')));
$mystr =
'<span title="structured data item: '.
$type .
'" class="notes">'.
$type .
(isset($mainparam) ?
' ['.
$mainparam .
']' :
'') .
'</span>';
break;
}
}
if ($myerr)
{
return ($myerr);
}
else if ($printmode !=
'false')
{ // display the data item
return ($mystr);
}
}
function SDbuild_vcard
($row)
{
$n_array =
split(';',
$row['n']);
$name =
(isset($n_array[3])?
$n_array[3].
' ' :
'').
(isset($n_array[1]) ?
(ucwords(strtolower($n_array[1])).
' '):
'').
(isset($n_array[2])?
$n_array[2].
' ':
'').ucwords
(strtolower($n_array[0]));
$str =
"BEGIN:VCARD\r\nVERSION:2.1\r\nN:".
$row['n'] .
"\r\nFN:".
$name .
"\r\n";
$str .=
$row['org'] ?
'ORG:'.
$row['org'] .
"\r\n" :
'';
$str .=
$row['title'] ?
'TITLE:'.
$row['title'] .
"\r\n" :
'';
$str .=
$row['url'] ?
'URL:'.
$row['url'] .
"\r\n" :
'';
$str .=
$row['tel'] ?
'TEL:'.
$row['tel'] .
"\r\n" :
'';
$str .=
$row['fax'] ?
'TEL;FAX:'.
$row['fax'] .
"\r\n" :
'';
$str .=
$row['email'] ?
'EMAIL;INTERNET:'.
$row['email'] .
"\r\n" :
'';
if (isset($row['adr']))
{
$adr_array =
split(';',
$row['adr']);
$str .=
'ADR:;;'.
$adr_array[0] .
';'.
(isset($adr_array[1]) ?
$adr_array[1] :
'') .
';'.
(isset($adr_array[3]) ?
$adr_array[3] :
'') .
';'.
(isset($adr_array[2]) ?
$adr_array[2] :
'') .
';'.
(isset($adr_array[4]) ?
$adr_array[4] :
'') .
"\r\n";
}
$str .=
$row['note'] ?
'NOTE:'.
$row['note'] .
"\r\n" :
'';
$str .=
"END:VCARD\r\n";
return ($str);
}
function SDis_in_scope
($thisone,
$row,
$type,
$scope=
null)
{
if ('all' ==
$scope)
{
$ret =
($thisone->
HasAccess('read',
$row['_wikkapage'])) &&
($row['type'] ==
$type);
}
else if ('user' ==
$scope)
{
$ret =
($thisone->
UserIsOwner($row['_wikkapage'])) &&
($row['type'] ==
$type);
}
else
{ // default scope = page
$ret =
($row['_wikkapage'] ==
$thisone->
GetPageTag()) &&
($row['type'] ==
$type);
}
return $ret;
}
function SDrun_req
($thisone,
$reqid,
$rows,
$p1=
null,
$p2=
null,
$p3=
null)
{ // $rows array row format: ('_wikkapage' => <page tag>, 'type' => <dataitem type>, 'field1' => <val1>, 'field2' => <val2>, ...)
$table_css =
'class="data" cellpadding="2" cellspacing="1" border="2"';
switch($reqid)
{
case 'ItemTable':
// p1 = type of dataitem, p2 = column order list, p3 = scope
$i =
0;
$keyorder =
array();
if ($p2)
{
$mycols =
split(',',
$p2);
foreach ($mycols as $lacol)
{
$keyorder[$lacol] =
$i++;
}
}
$mystr0 =
'<table '.
$table_css .
'><thead><tr>';
foreach ($rows as $row)
{
if (SDis_in_scope
($thisone,
$row,
$p1,
$p3))
{
$tmp_tr =
array();
$mystr .=
'<tr>';
foreach ($row as $key =>
$val)
{
if (($key !=
'_wikkapage') &&
($key !=
'type') &&
($key !=
'print') && !
isset($keyorder[$key]))
{
$keyorder[$key] =
$i++;
}
if (($key !=
'_wikkapage') &&
($key !=
'type') &&
($key !=
'print'))
{
$tmp_tr[$keyorder[$key]] =
$val;
}
}
for ($j =
0;
$j <
$i;
$j++
)
{
$mystr .=
'<td>'.
$tmp_tr[$j] .
'</td>';
}
$mystr .=
'</tr>';
}
}
// build table header row
$tmp_tr =
array();
foreach ($keyorder as $param =>
$k)
{
$tmp_tr[$k] =
$param;
}
for ($j =
0;
$j <
$i;
$j++
)
{
$mystr0 .=
'<th>'.
$tmp_tr[$j] .
'</th>';
}
$mystr =
$mystr0 .
'</tr></thead><tbody>'.
$mystr.
'</tbody></table>';
if (!
$i)
{ // empty table: display nothing
$mystr =
'';
}
break;
case 'ToDos':
// p1 = this owner only; p2 = this status only
$mydata =
array();
$i =
0;
foreach ($rows as $row)
{
if ($row['type'] ==
'ToDo')
{
if ( (!
$p1 ||
($p1 ==
$row['owner'])) &&
(!
$p2 ||
($p2 ==
$row['status'])) )
{ // transform all dates into a common format for sorting purposes
$mydata[date("Y-m-d",
strtotime($row['date_open'])).
"_".
$i++
] =
"<tr><td>{$row['owner']}</td><td>{$row['desc']}</td>".
"<td".
((strtotime($row['date_due'])<time
())?
" style='background-color:red; color:white; '":
"").
">{$row['date_due']}</td>".
"<td align='center'><a href='{$_SERVER['PHP_SELF']}?wakka={$row['_wikkapage']}'>{$row['_wikkapage']}</a></td></tr>";
}
}
}
krsort($mydata);
$mystr =
'<table '.
$table_css .
'><thead><tr><th>owner</th><th>description</th><th>due date</th><th>page link</th></tr></thead><tbody>';
foreach ($mydata as $key =>
$val)
{
$mystr .=
$val;
}
$mystr .=
'</tbody></table>';
break;
case 'Cards':
// p1 = this org only; p2 = sort key ; p3 = format (vCard or table)
$mydata =
array();
$i =
0;
foreach ($rows as $row)
{
if ($row['type'] ==
'Card')
{
if ( (!
$p1 ||
($p1 ==
$row['org'])) )
{
$sortkey =
strtolower((isset($p2) &&
$p2) ?
$row[$p2] :
(isset($row['n']) ?
$row['n'] :
$i)) .
'__'.
$i++;
$n_array =
split(';',
$row['n']);
$mydata[$sortkey] =
"<tr><td>{$n_array[0]}</td><td>{$n_array[1]}</td>".
"<td>{$row['email']}</td><td>{$row['tel']}</td><td>{$row['fax']}</td>".
(isset($p2) ?
"<td>{$row['org']}</td>":
'') .
'</tr>';
$myvcards[$sortkey] = SDbuild_vcard
($row);
}
}
}
if ($p3 ==
'vCard')
{
$mystr =
'';
$cnt =
0;
ksort ($myvcards);
foreach ($myvcards as $key =>
$card)
{
$mystr .=
"$card\r\n";
$cnt++;
}
$mystr =
'<form action="'.
$thisone->
Href().
'/grabcode" method="post" class="grabcode">
<input type="submit" name="save" class="grabcodebutton" style="line-height:10px; float:left; vertical-align: middle; margin-right:20px; margin-top:0px; font-size: 10px; color: #000; font-weight: normal; font-family: Verdana, Arial, sans-serif; background-color: #DDD; text-decoration: none; height:18px;" value="Grab '.
$cnt.
($cnt>
1?
' vCards':
' vCard').
'" title="Download vCard file" />
<input type="hidden" name="code" value="'.
$mystr.
'" /><input type="hidden" name="filename" value="wikka_vcards" /></form>';
}
else
{ // default (table) format
ksort($mydata);
$mystr =
'<table '.
$table_css .
'><thead><tr><th>Last name</th><th>Given name</th><th>Email</th><th>Phone</th><th>Fax</th>'.
(isset($p2) ?
'<th>Organization</th>' :
'') .
'</tr></thead><tbody>';
foreach ($mydata as $key =>
$val)
{
$mystr .=
$val;
}
$mystr .=
'</tbody></table>';
}
break;
/*------------------------------- begin customization area -----------------------------
case 'myreq':
<mycode>
$mystr = <what I want to print>
break;
--------------------------------- end customization area -----------------------------*/
}
return ($mystr);
}
function SDdo_help
($reqid)
{
$helpstr =
'';
switch($reqid)
{
case 'ItemTable':
$helpstr =
$reqid .SD_HELP_ITEMTABLE;
break;
case 'ToDos':
$helpstr =
$reqid .SD_HELP_TODOs;
break;
case 'Cards':
$helpstr =
$reqid .SD_HELP_CARDS;
break;
/*------------------------------- begin customization area -----------------------------
case 'myreq':
$helpstr = 'myfoobar';
break;
--------------------------------- end customization area -----------------------------*/
}
return ($helpstr);
}
}
if ((!
isset($type) || !
$type) &&
(!
isset($req) || !
$req) && !
isset($help))
{
$output = SDerror
(SD_ERROR_USAGE
);
}
else if (isset($help))
{ // display one-line help for $req
$output = SDdo_help
($req);
}
else if (isset($req))
{ // this is a request: load all relevant data in an associative array: $myrows
$query =
'SELECT body, tag FROM '.
$this->
config['table_prefix'] .
'pages WHERE ((latest = \'Y\') AND (body LIKE \'%{{structdata%\'))';
$rows =
$this->
LoadAll($query);
foreach ($rows as $row)
{
if (preg_match_all('/\{\{structdata(.+?)\}\}/',
$row['body'],
$matches))
{
foreach ($matches[1] as $mym)
{
$newrow =
array('_wikkapage' =>
$row['tag']);
if (preg_match('/type=\"(.*?)\"[ \t]*.*?data=\"(.*?)\"/',
$mym,
$matches2))
{ // order: type, then data
$newrow['type'] =
$matches2[1];
preg_match_all('/(\w+?)\=\'(.*?)\'/',
$matches2[2],
$matches3);
}
else if (preg_match('/data=\"(.*?)\"[ \t]*.*?type=\"(.*?)\"/',
$mym,
$matches2))
{ // order: data, then type
$newrow['type'] =
$matches2[2];
preg_match_all('/(\w+?)\=\'(.*?)\'/',
$matches2[1],
$matches3);
}
for ($i =
0;
$i <
count($matches3[1]);
$i++
)
{
$newrow[strtolower($matches3[1][$i])] =
$matches3[2][$i];
}
$myrows[] =
$newrow;
}
}
}
// we run the request
$output = SDrun_req
($this,
$req,
$myrows,
(isset($p1)?
$p1:
''),
(isset($p2)?
$p2:
''),
(isset($p3)?
$p3:
''));
}
else
{ // this is a data item : process it
if ($data)
{
preg_match_all('/(\w*)\=\'(.*?)\'\s*?/',
$data,
$matches);
for ($i =
0;
$i <
count($matches[1]);
$i++
)
{
// parameter name is case-insensitive
$params[strtolower($matches[1][$i])] =
$matches[2][$i];
}
$output = SDhandle_item
($type,
$params,
isset($print) ?
$print :
'');
}
else
{
$output = SDerror
(sprintf(SD_ERROR_PARAMETER_MANDATORY,
'data'));
}
}
if ($output)
{ // print the result
$output =
$this->
ReturnSafeHTML($output);
echo $output;
}
?>