function get_fields(&$args) { Args::label($args, 'route', 'user'); /* first check direct route */ $route = $args->route; if (!isset($this->_schema[$route])) { /* no direct route for this, check for generic */ $fragments = explode('/', $args->route, 2); $route = $fragments[0] . '/*'; error_log($route); if (!isset($this->_schema[$route])) { throw new NotFoundException($args->route . ', invalid route'); } } if ($args->retval == NULL) { $args->retval = array(); } $args->retval = array_merge_recursive($args->retval, $this->_schema[$route]); }
function put_model($args) { Args::label($args, 'route', 'model'); $model =& $this->_model; // XXX: add support for matching based named items - search children rather than keys $fragments = explode('/', $args->route); for ($i = 0; $i < count($fragments); $i++) { if (isset($model[$fragments[$i]]) !== true) { /* create if it doesn't exist */ $model[$fragments[$i]] = array(); } $model =& $model[$fragments[$i]]; } $model = array_replace_recursive($model, $args->model); // XXX: error_log('put_model: '.$args->params[0].' - '.print_r($model, true)); JSON::encode_file($this->_model_file, $this->_model); /* generate site with data */ $this->_teapot->generate($args->route); }
function __call($name, $params) { /* although the user defines MODULES in 'put' order we reverse it at load as 'get' is far more common a request - to help make calling code as simple as possible we also support no prefix. If the call is a 'get' we add an additional reference parameter [first one]. This is used to pass the return value up the chain */ $args = new Args($params); if (strpos($name, Teapot::DOWN_PREFIX) === 0) { foreach (array_reverse($this->_modules) as &$mod) { if (method_exists($mod, $name) === true) { Args::label($args); /* reset labels */ $mod->{$name}($args); } } } else { /* call needs a return value */ $called = 0; foreach ($this->_modules as &$mod) { if (method_exists($mod, $name) === true) { $mod->{$name}($args); $called += 1; } } if ($called === 0) { throw new ConfigException('error; nobody handled call: ' . $name); } } return $args->retval; }
function generate(&$args) { Args::label($args, 'route'); /* load the template system */ $loader = new \Twig_Loader_Filesystem($this->_module_name); $twig = new \Twig_Environment($loader); /* no cache */ /* cleanup the dst directory */ $dir = $this->_outputdir . DIRECTORY_SEPARATOR; if (is_dir($dir)) { if ($dh = opendir($dir)) { while (($file = readdir($dh)) !== false) { $fp = $this->_outputdir . DIRECTORY_SEPARATOR . $file; /* delete any file which doens't start with a '.' and * the attachments dir - is_file is unreliable */ if (is_dir($fp) !== false) { if ($file == 'attachments') { Theme::rmtree($fp); } } else { /* file */ if ($file[0] !== '.') { @unlink($fp); } } } closedir($dh); } } /* filter to copy attachments to publically readable location */ $filter = new \Twig_SimpleFilter('attachment', function ($file) { $retval = ''; if ($file !== NULL && $file != '') { $attachments = $this->_outputdir . DIRECTORY_SEPARATOR . 'attachments' . DIRECTORY_SEPARATOR; $dst = $attachments . $file; @mkdir($attachments); copy('attachments' . DIRECTORY_SEPARATOR . $file, $dst); /* return must be page relative url */ $retval = 'attachments/' . $file; } return $retval; }); $twig->addFilter($filter); /* single page site - so just pass the whole model to the template */ $index = 'index.html'; if (defined('Teapot\\TEAPOT_DEBUG') === true) { $index = '_' . $index; file_put_contents($this->_outputdir . DIRECTORY_SEPARATOR . 'index.php', '<?php namespace Teapot; chdir("admin"); require_once "teapot.php"; $teapot = new Teapot(); $teapot->generate(); error_log("regenerating site"); $finfo = finfo_open(FILEINFO_MIME_TYPE); $content_type = finfo_file($finfo, "..' . DIRECTORY_SEPARATOR . $index . '"); finfo_close($finfo); header("Content-Type: ".$content_type); readfile("..' . DIRECTORY_SEPARATOR . $index . '"); ?>'); } file_put_contents($this->_outputdir . DIRECTORY_SEPARATOR . $index, $twig->render('index.html', $this->_teapot->get_model(NULL)), LOCK_EX); /* copy all the files in frontend.ui out as well */ $src = $this->_module_name . DIRECTORY_SEPARATOR . 'frontend.ui'; $dir = @opendir($src); if ($dir !== false) { while (false !== ($file = readdir($dir))) { if ($file != '.' && $file != '..') { copy($src . DIRECTORY_SEPARATOR . $file, $this->_outputdir . DIRECTORY_SEPARATOR . $file); } } closedir($dir); } }