* @license PHP License * @package WB * @subpackage content */ /** * load base class */ WBClass::load('WBFormProcessor'); /** * Content component * * @version 1.4.0 * @package WB * @subpackage content */ class WBContent extends WBFormProcessor { const ALERT_TYPE_SUCCESS = 'success'; const ALERT_TYPE_INFO = 'info'; const ALERT_TYPE_WARNING = 'warning'; const ALERT_TYPE_DANGER = 'danger'; const ENV_DEFAULT = 'default'; const ENV_SITE = 'site'; const ENV_JSONP = 'jsonp'; /** * my part * @var string */ protected $part = 'main'; /** * my parameter list * @var array */ protected $config = array( 'tmplDir' => '', 'usefilter' => 0, 'searchfields' => array(), 'requiredgroup' => self::GROUP_ANON ); /** * variables meant to bubble up * @var array */ protected $bubbles = array(); /** * tell whether to use dynanmic bubbles * @var bool */ protected $useBubbles = true; /** * user object * @var WBUser_Auth */ protected $user; /** * whether to use template engine or not * @var bool */ protected $withFormTmpl = true; /** * template engine * @var patTemplate */ protected $tmpl; /** * session object * @var patSession_Storage */ protected $sess; /** * request object * @var WBRequest */ protected $req; /** * HTTP Status for Response * @var int */ private $httpResponseStatus = 200; /** * This content component is cachable * @var bool */ protected $cachable = true; /** * @var WBFormProcessor_Filter */ protected $filter; /** * List of Form Fiddler for Filter * * @var array */ private $filterFiddler = array(); /** * Current Alerts * * @var array */ private $alert = array(); /** * anonymous user */ const GROUP_ANON = '__anonymous'; /** * Current environment * @var string */ private $environment = self::ENV_DEFAULT; /** * constructor * * Configure template folder by class name * * Instantiate a vew standard objects * - req: request object * - tmpl: template engine patTemplate * - sess: session storage patSession_Storage * - user: current user * * Make sure all subclasses execute this constructor * @var array parameter */ public function __construct($parameter = array()) { $this->config['tmplDir'] = str_replace('_', '/', substr(get_class($this), strlen(__CLASS__) + 1)); $this->req = WBClass::create('WBRequest'); $this->sess = WBClass::create('patSession'); $this->tmpl = WBClass::create('patTemplate'); WBClass::load('WBUser'); $this->user = WBUser::getCurrent(); } /** * location of form config * * Return sub directory where form element definitions are located * * @return string folder */ protected function getFormConfigDir() { return strtolower(str_replace('_', '/', substr(get_class($this), strlen(__CLASS__) + 1))); } /** * Set Current Environment * * Call this method before configure() * @param string $env */ public function setEnvironment($env) { $this->environment = $env; $this->tmpl->addGlobalVar('wb_environment', $this->environment); } /** * Get Current Environment * * @return string $env */ public function getEnvironment() { return $this->environment; } /** * Set config values * * Setup and configure this content component. * * @param string $part named part where the content is located * @param array configuration options * @param array bubbles * @return bool true on success */ public function configure($part, $config, $bubbles) { if (!is_array($config)) { $config = array(); } if (!is_array($bubbles)) { if (1 > intval($bubbles)) { $this->useBubbles = false; } $bubbles = array(); } $this->part = $part; $this->config = array_merge($this->config, $config); $this->bubbles = $bubbles; // force leading slash if (strlen($part) && $part[0] != '/') { $part = '/' . $part; } // add user data and group membership if ($this->user && $this->user->isAuthenticated()) { $this->tmpl->addGlobalVars($this->user->getData(), 'user_current_'); $this->tmpl->addGlobalVar('user_current_mandatorid', $this->user->getMandatorId()); $groups = array(); foreach ($this->user->getGroups() as $gid => $gname) { $groups[$gname] = '1'; } $this->tmpl->addGlobalVars($groups, 'user_current_group_'); if (!empty($this->config['requiredgroup']) && $this->isUserInGroup($this->config['requiredgroup'])) { $this->tmpl->addGlobalVar('user_current_requiredgroup', 1); } } // misc global variables $globals = array( 'request_path' => $this->req->path, 'content_path' => $part, 'session_name' => $this->sess->getName(), 'session_id' => $this->sess->getId(), ); $this->tmpl->addGlobalVars($globals); $this->init(); // tell fiddler about config $this->configureFiddler($this->config); foreach ($this->filterFiddler as $ff) { $ff->configure($this->config); } return true; } /** * Add Fiddler * * @param WBFormProcessor_Fiddler */ protected function addFilterFiddler($object) { $this->filterFiddler[] = $object; } /** * 2nd constructor * * Called after configuration was done */ protected function init() { } /** * Get List of Variables 4 Filter * * @return */ protected function getFilterVars() { return array(); } /** * Initialize Filter * * Instantiate filter and configure it. */ protected function initFilter() { if ($this->filter) { return; } $this->filter = WBClass::create('WBFormProcessor_Filter'); if (!empty($this->filterFiddler)) { foreach ($this->filterFiddler as $ff) { $this->filter->addFiddler($ff); } } $this->filter->setRequest($this->req); $this->filter->setTemplate($this->tmpl, $this->config['tmplDir']); $tmp = array(); $this->addGlobalVars($this->config, 'CONFIG_', $tmp); $this->filter->addTmplVars($tmp, 'CONFIG_'); $this->filter->setExternalVars($this->getFilterVars()); if ($this->config['usefilter']) { $this->filter->setFormConfigDir($this->getFormConfigDir(), 'snippet'); } $this->filter->buildClause($this->config['searchfields']); } /** * Run Component * * Actually do stuff :-) * * @return array parameter list */ public function run() { return $this->config; } /** * Add Alert * * @param string alert type * @param string title * @param string alert message * @param array data to poplate msg */ protected function addAlert($type, $title, $msg = '', $data = array()) { if (!$this->tmpl->exists('alert')) { $this->tmpl->readTemplatesFromInput('common/alert.tmpl'); } // verify type switch ($type) { case self::ALERT_TYPE_SUCCESS: case self::ALERT_TYPE_INFO: case self::ALERT_TYPE_WARNING: case self::ALERT_TYPE_DANGER: break; default: $type = self::ALERT_TYPE_INFO; break; } $this->tmpl->clearTemplate('alert'); $alert = array( 'type' => $type, 'title' => $title, 'body' => WBString::populate($msg, $data) ); $this->tmpl->addVars('alert', $alert); $this->alert[] = $this->tmpl->getParsedTemplate('alert'); $this->tmpl->addGlobalVar('ALERT', implode("\n", $this->alert)); } /** * Receive output * * Fetch output of this content component. Implemented standard behaviour: * get parsed template named "snippet". * * @return string */ public function getString() { return $this->tmpl->getParsedTemplate('snippet'); } /** * Download file * * CAUTION: This method usually does not return! * If file exists, it will send file to browser and exit programme! * * @param string $file * @param string $type mime-type * @param string $disposition file name for content disposition */ protected function downloadFile($file, $type = 'text/xml', $disposition = '') { /** @var WBResponse */ $res = WBClass::create('WBResponse'); /** @var $res WBResponse */ if (!file_exists($file)) { $res->addHeader('Content-Type', 'text/plain'); $res->add('not found'); $res->send($this->req); exit(0); } // switch off compression - otherwise complete download files are loaded to RAM WBParam::set('wb/response/compress', 0); WBParam::set('wb/cache/use', 0); $res->addHeader('Content-Type', $type); $res->addHeader('Cache-Control', 'no-cache, must-revalidate'); $res->addHeader('Expires', gmdate('D, d M Y H:i:s') . ' GMT'); if (!empty($disposition)) { $res->addHeader('Content-Disposition', 'inline; filename="' . $disposition . '"'); } $res->addStream(fopen($file, 'r'), md5_file($file)); $res->send($this->req); exit(0); } /** * Get response status code * * @return int */ public function getStatusCode() { return $this->httpResponseStatus; } /** * Set Http Response Status * * @see getStatusCode() * @param int http response status */ protected function setStatusCode($code = 200) { $this->httpResponseStatus = $code; } /** * fetch variables to bubble up * * @return array parameter list */ public function getBubbles() { if ($this->useBubbles) { return $this->bubbles; } return array(); } /** * tell whether this component is cachable * * @return bool */ public function isCachable() { return $this->cachable; } /** * Fill List in Template * * Standard method to add rows to list template * * @param array list * @param string template name stump */ protected function list2Template($list, $name = 'list') { $this->tmpl->addGlobalVar($name . '_count', count($list)); if (!$this->tmpl->exists($name . '_entry')) { return; } $this->tmpl->addRows($name . '_entry', $list); $max = WBParam::get('wb/template/listtemplatemax', 10); for ($i = 1; $i < $max; ++$i) { if (!$this->tmpl->exists($name . '_entry_' . $i)) { break; } $this->tmpl->addRows($name . '_entry_' . $i, $list); } } /** * load templates from file * * @param string $tmpl * @param bool local templates */ protected function loadTemplates($tmpl, $local = true) { if ($local) { $tmpl = $this->config['tmplDir'] . '/' . $tmpl; } return $this->tmpl->readTemplatesFromInput($tmpl . '.tmpl'); } /** * Add Config to Template * * Most content components make the current config available as template variables * * @see addGlobalVars() * @return bool */ protected function addConfigAsGlobalVars() { return $this->addGlobalVars($this->config, 'CONFIG_'); } /** * Add Scala Values as Global Vars * * Auxilliary method to add template variables without notices. * * @param array $vars * @param string prefix - optional * @param $out * @return bool */ protected function addGlobalVars($vars, $prefix = '', &$out = null) { $tmp = array(); foreach ($vars as $k => $v) { if (is_scalar($v)) { $tmp[$k] = $v; continue; } if (is_array($v)) { $tmp[$k . '_count'] = count($v); if (isset($v[0]) && is_scalar($v[0])) { $tmp[$k . '_list'] = implode(',', $v); } } } if (is_array($out)) { $out = $tmp; return true; } return $this->tmpl->addGlobalVars($tmp, $prefix); } /** * Verify if user is in group * * Checks if user is in specified group * * @param string $name group name to validate * @param bool $id whether $name is the group's id * @return bool true in case user is member of given group */ protected function isUserInGroup($name, $id = false) { if (self::GROUP_ANON == $name) { return true; } return $this->user->isInGroup($name, $id); } /** * Login user if not already logged in * * Check for authentication and try to login. * CAUTION: this uses form processor, therefore form defintion and templates are required * * @return bool true for authenticated users */ protected function autoAuthenticate() { if ($this->user->isAuthenticated()) { return true; } $this->processForm('login'); return $this->user->isAuthenticated(); } /** * login user * * Use form data to login */ public function onLoginValid($form, $values) { $this->user->login($values); if ($this->user->isAuthenticated()) { WBClass::load('WBService'); WBService::addEvent('login'); return false; } return true; } }