inc/record.php - index

















































































































































































































































































































































































<?php

// RECORD.PHP - manipulate 'records' and write/read them to/from database
//
// This code was written in like 1982 but will only occasionally get tweaked.
//
// The following functions are defined:
//
// readrecord()
// readfilerecord()
// writerecord()
// createrecord()
// arraytorecord()
// recordtostring()
// sortrecords()
// recorduserdata()


/* readrecord - read an entry (post) and process it into a "record" */

// Fields are verified, adjusted, translated, etc. This function is for 
// reading before displaying. $data is a way for admin to preview.

function readrecord($id$data NULL) {

    
debug("'$id'");

    
// first, read file into a "record"

    
if ($data)
        
$record arraytorecord($data);
    else
        
$record dbreadrecord($id);

    
// $record will be FALSE if record not found - an alternative is to 
    // check for existence with if (!dblistrecords($id)) ... which is 
    // what we now do (only ADMIN and DISPLAY call this function)

    
if ($record == FALSE) {
        
$record createrecord("Error #49",htmlgeterror('NOTFOUND'));
        
$record['nocomments'] = 1;
    }

    
$record['id'] = $id;

// look at all these things here - this is a perfect example of code that 
// should be "data code" so that all of these defaults and things are 
// set/determined by an external, editible data file so we do not have to 
// keep updating this code to support new features! and in providing for that 
// each installation -- and theme -- can do their own thing! and *THAT* is the
// meaning of "customizable"

    // if date string use it else use time string

    
if (!isset($record['date']) && isset($record['time']))
        
$record['date'] = date(config('datestr'),$record['time']);

    if (!isset(
$record['time']) && isset($record['date']))
        
$record['time'] = strtotime($record['date']);

    if (!isset(
$record['time']))
        
$record['time'] = time();

    if (!isset(
$record['date']))
        
$record['date'] = date(config('datestr'),$record['time']);

    if (isset(
$record['from']))
        
$record['from'] = convertchars($record['from']);

    if (isset(
$record['title']))
        
$record['title'] = convertchars($record['title']);
    else
        
$record['title'] = "";          // have to have a title

    
if (!isset($record['linktitle']))
        
$record['linktitle'] = $record['title'];

    
_recordrefs($record,$record['body']);        // modifies body

// NOTE this is where usercode skips the convert code; we are thinking about
// changing this

    
if ($record['body'] != "" && !isset($record['usercode']))
        
$record['body'] = convert($record['body']);

    if (isset(
$record['more']))
        
_morefunc($record);

    return 
$record;
}


/* readfilerecord - read a file in the format of an internal record */

function readfilerecord($id) {

    
// $record will be FALSE if page not found - an alternative is to 
    // check for existence with if (!dblistpages($id)) ... which is 
    // what we now do (only ADMIN and DISPLAY call this function)

// although the function name to read a page begins with 'db' that is a 
// misnomer as the page is actually a file - but we like the consistency!
// (the page API is INC/PAGES.PHP)

    
$record dbreadpage($id);
    if (
$record == FALSE)
        return 
createrecord("Error #21 ($id)",htmlgeterror('NOTFOUND'));

    
$record['body'] = convert($record['body']);

    return 
$record;
}


/* writerecord - write a new record (previously non-existent) */

function writerecord($record$logdata true) {

    
debug("");

    if (!
is_array($record))
        
$record arraytorecord($record);

    if (!isset(
$record['time']) && !isset($record['date']))
        
$record['time'] = time();

    if (
config('loguserdata') && $logdata)
        
recorduserdata($record);                // modifies $record

    
return dbnewrecord($record);
}


/* arraytorecord - convert record string/array to associative array */

function arraytorecord(/*mixed*/ $data) {

    if (!
is_array($data))
        
$data explode(THIS_EOL,$data);

    
// PREG_SPLIT__DELIM_CAPTURE is wanted here... we put the LFs back

    // we think this (or something like it) is more logical (slower)
//    function nl(&$a) { $a = $a.THIS_EOL; }
//    array_walk($data,'nl');

    // as this modifies itself inside the loop which is odd (faster)
    
foreach ($data as $a => $b)
        
$data[$a] = $b.THIS_EOL;

    
// but they both need this!
    
reset($data);

        while (list( ,
$_) = each($data)) {
                if (
$_ == THIS_EOL) break;
        
$h explode(':',$_);
        
$name array_shift($h);
        
$name strtolower($name);
        
$value implode(':',$h);
        
$record[$name] = trim($value);
    }

        
$record['body'] = '';
        while (list( ,
$_) = each($data))
                
$record['body'] .= $_;

    return 
$record;
}


/* recordtostring - convert record array into a string */

function recordtostring($record) {

    
$data =  '';
    foreach (
$record as $key => $value)
        if (
$key != 'body')
            
$data .= $key.':'.$value.THIS_EOL;

    return 
$data THIS_EOL $record['body'];
}


/* sortentries - sort the entries (natural sort is the default) */

function _cmptitle($a$b) { return strcmp($a['title'],$b['title']); }
function 
_cmptime($a$b)  { return strcmp($a['time'],$b['time']);   }

function 
sortrecords(&$ids$sort NULL) {

    if (
$sort === NULL)
        
$sort config('sortfunc');

    if (
$sort == "date") {
        
$i 0;
        foreach (
$ids as $id) {
            
$headers[$i] = _getrecordheaders($id);
            
$headers[$i]['file'] = $id;
            
$i++;
        }
        
usort($headers,"_cmptime");
        
$i 0;
        foreach (
$headers as $h) {
            
$ids[$i] = $h['file'];
            
$i++;
        }
    }
    else
    if (
$sort == "name") {
        
$i 0;
        foreach (
$ids as $id) {
            
$headers[$i] = _getrecordheaders($id);
            
$headers[$i]['file'] = $id;
            
$i++;
        }
        
usort($headers,"_cmptitle");
        
$i 0;
        foreach (
$headers as $h) {
            
$ids[$i] = $h['file'];
            
$i++;
        }
    }

    if (
config('reversesort') || $sort == "rsort")
        
$ids array_reverse($ids);
}


/* _internal functions */


/* _getrecordheaders - read a record header into an associative array */

function _getrecordheaders($id) {

    
debug("'$id'");

    
// no error checking as we have a valid ID at this point

    
$record dbreadrecord($id);
    unset(
$record['body']);

    
$record['id'] = $id;

    
// if no date create it (convert time from number to people string)

    
if (!isset($record['date']))
        
$record['date'] = date(config('datestr'),$record['time']);

    return 
$record;
}


/* createrecord - create an empty record */

function createrecord($title NULL$body "") {

    if (
$title == NULL)
        return 
"date: " date(config('datestr')) . 
            
"\ntitle: Title\n\nPlace content here.";

    
$record['title'] = $title;
    
$record['body'] = $body;
    
$record['date'] =  date(config('datestr'));
    
$record['id'] = 0;
    return 
$record;
}


/* recorduserdata - add some server data to a record */

function recorduserdata(&$record) {

    if (isset(
$_SERVER['REMOTE_ADDR']))
        
$record['REMOTE_ADDR'] = $_SERVER['REMOTE_ADDR'];
    if (isset(
$_SERVER['HTTP_USER_AGENT']))
        
$record['HTTP_USER_AGENT'] = $_SERVER['HTTP_USER_AGENT'];
    if (isset(
$_SERVER['HTTP_REFERER']))
        
$record['HTTP_REFERER'] = $_SERVER['HTTP_REFERER'];
}


/* _recordrefs - replace record vars (marked by "[]") in a string */

// This substitutes a [words] in body with a record header value, ie.
// with a record header of "title: Foobar", the string "Hey there, [title]!" 
// would result in "Hey there, Foobar!".

// this is currently a "used here only function" but it spcifically lacks
// a leading underscore...

function _recordrefs($record,&$body) {

    
$re '/\[([a-zA-Z]+)\]/';
    if (
preg_match_all($re,$body,$res))
        foreach (
$res[0] as $k => $v) {
            
$h $res[1][$k];
            if (isset(
$record[$h]))
                
$body str_replace($v,$record[$h],$body);
        }
}


/* "more" functions */


/* _morefunc - process "more" function */

function _morefunc(&$record) {

    
$bodydata explode(THIS_EOL,$record['body']);

    if ((
$t $record['more']))
        if (!
is_numeric($t) || ($t || $t >= count($bodydata)))
            
$t 0;

    
$c = ($t) ? $t _morecheck($bodydata);

    if (
$c) {
        
$bodydata _moretruncate($bodydata,$c);
        
$record['more'] = implode(THIS_EOL,$bodydata);
    }
}


/* _morecheck - return index to "more" marker (or Nth blank line) */

function _morecheck($data) {

    
// this would be nice:
    //$count = array_search('moremark',$data);
    // but we need a substring search, i.e. array_strstr()...

    
for ($i 0$n count($data); $i $n$i++)
        if (
strstr($data[$i],config('moremark')))
            break;

    
$count $i+1;    // NOTE note next line; this fixes a really bad bug
            //  if the moremark immediately follows a <?php 
            //   block in a post body

    
if (!$count) {
        
$p = ($p config('morepara')) ? $p 6;
        
$para 0;

        while (list( ,
$_) = each($data)) {
            if (
$para++ == $p)
                break;
            
$count++;
        }
    }

    return 
$count;
}


/* _moretruncate - truncate body array at more marker index */

function _moretruncate($data$count) {

    return 
array_slice($data,0,$count);
// the arbitrariness of the slice can possibly result in the removal of a 
// needed closing tag so the <!--more--> marker must not be placed before 
// an ending tag
}

?>