StructData Action

See also:
works with:
  • Wikka 1.1.6.2 to 1.1.6.5
NOT Included in any Wikka version
Last edited by DomBonj:
1.1.6.5 compatibility
Sun, 13 Jul 2008 17:04 UTC [diff]

This is the development page for the Structdata action.

Installation


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]).'&nbsp;' : '';
                    $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>&nbsp;<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])).'&nbsp;') : ''). 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) ? '&nbsp;['. $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;
}
?>


2. [versions 1.1.6.2 & 1.1.6.3 only] Add the following lines to css/wikka.css:

table.data {
    border: 2px solid #CCC;
    border-collapse: collapse;
    border-spacing: 0;
}

table.data caption {
    border: 1px solid #CCC;
    font-size: 95%;
    color: #666;
    margin:5px 0;
    padding:2px;
}

table.data thead {
    background-color: #DDD;
}

table.data tfoot {
    background-color: #DDD;
}

table.data th {
    border: 1px solid #CCC;
    padding: .1em .25em;
}

table.data thead th {
    background-color: #DDD;
}

table.data tfoot th {
    background-color: #DDD;
}

table.data tbody th {
    background-color: #EEE;
}

table.data tbody tr:hover {
    background-color: #E9E9F9;
}

table.data tbody tr.alt:hover {
    background-color: #E9E9F9;
}

table.data td {
    border: 1px solid #CCC;
    padding: .1em .25em;
}

table.data td.number {
    text-align: right;
}

table.data td.datetime {
    text-align: right;
    white-space: nowrap;
}

/* --- alternate row & column color --- */

table.data tr.alt {
    background-color: #EEE;
}

table.data th.c1 {
    background-color: #CDD;
}

table.data th.c2 {
    background-color: #DCC;
}

table.data th.c3 {
    background-color: #DDC;
}

table.data th.c4 {
    background-color: #CDC;
}

table.data th.c5 {
    background-color: #CCD;
}

table.data th.c6 {
    background-color: #DCD;
}

table.data td.c1 {
    background-color: #EFF;
}

table.data td.c2 {
    background-color: #FEE;
}

table.data td.c3 {
    background-color: #FFE;
}

table.data td.c4 {
    background-color: #EFE;
}

table.data td.c5 {
    background-color: #EEF;
}

table.data td.c6 {
    background-color: #FEF;
}

table.data tr.alt td.c1 {
    background-color: #DEE;
}

table.data tr.alt td.c2 {
    background-color: #EDD;
}

table.data tr.alt td.c3 {
    background-color: #EED;
}

table.data tr.alt td.c4 {
    background-color: #DED;
}

table.data tr.alt td.c5 {
    background-color: #DDE;
}

table.data tr.alt td.c6 {
    background-color: #EDE;
}


CategoryUserContributions
Valid XHTML :: Valid CSS: :: Powered by WikkaWiki