<?php
/**
 * Smarty plugin
 * @package Smarty
 * @subpackage plugins
 *
 * version 1.0
 * Copyright (c) 2010 by Willem van Engen <dev-smarty at willem dot engen dot nl>
 * Licensed under GPL version 2 or later
 */

/** Stack of sql results (for nested invocations) */
global $smarty_block_forsql_results, $sqlconn;
$smarty_block_forsql_results = array();
$sqlconn = null;

/**
 * Smarty {forsql}{/forsql} block plugin
 *
 * Type:     block function<br>
 * Name:     forsql<br>
 * Purpose:  iterate over the results of a SQL SELECT.
 * @param params array
 * <pre>
 * Params:   select: string (the select statement)
 *           item: string (name of the row variable, like foreach)
 * </pre>
 * @param content string contents of the block
 * @param smarty Smarty object
 * @param repeat whether to call this method again
 * @return content with row variable set to the current row
 * @author Willem van Engen <dev-smarty at willem dot engen dot nl>
 */
function smarty_block_forsql($params, $content, &$smarty, &$repeat)
{
    global $smarty_block_forsql_results, $sqlconn;

    // gather config
    $select = null;
    $item = null;
    foreach ($params as $_key => $_val) {
        switch ($_key) {
            case 'select':
            case 'item':
                $$_key = (string)$_val;
                break;

            default:
                $smarty->trigger_error("forsql: unknown attribute '$_key'");
        }
    }

    if ($select==null)
        $smarty->trigger_error("forsql: require parameter select");
    if ($item==null)
        $smarty->trigger_error("forsql: require parameter item");

    // open tag: execute query
    if (is_null($content)) {
        if (!$sqlconn) {
            // TODO make configurable
            $sqlconn = sqlite_open($smarty->forsql_db, 0440, $sqliteerror);
            if (!$sqlconn)
                $smarty->trigger_error("forsql: could not connect to database: $sqliteerror");
        }
        $result = sqlite_query($sqlconn, sqlfix($select), SQLITE_ASSOC, $sqliteerror);
        if (!$result)
            $smarty->trigger_error("forsql: query error: $sqliteerror");
        array_unshift($smarty_block_forsql_results, $result);
    }

    // get data set row variable for coming block
    $data = sqlite_fetch_array($smarty_block_forsql_results[0]);
    if ($data) {
        $smarty->assign($item, $data);
        $repeat = true;
    } else {
        array_shift($smarty_block_forsql_results);
        $smarty->clear_assign($item);
        $repeat = false;
    }

    return $content;
}

/** translates some mysql tricks to sqlite */
function sqlfix($select) {
	$select = preg_replace('/DATE\s*\(\s*NOW\s*\(\s*\)\s*\)/i', 'DATE("now","localtime")', $select);
	return $select;
}

/* vim: set expandtab ts=4 sw=4: */
?>
