Smarty.php

00001 <?php
00008 require_once('Smarty/Smarty.class.php');
00009 
00016 class Dsao_View_Smarty extends Smarty
00017 {
00022   const CONTENT = 'content';
00023 
00028   const POST_CONTENT = 'postContent';
00029 
00034   const PRE_CONTENT = 'preContent';
00035 
00040   protected $_addDefaultTemplate = true;
00041 
00045   protected $_ajaxResponse = null;
00046 
00050   protected static $_debug = array();
00051 
00055   protected $_initialised = false;
00056 
00060   protected $_isXmlHttpRequest = null;
00061 
00066   protected $_layouts = null;
00067 
00072   protected $_layoutsDefault = array();
00073 
00078   protected $_jsFiles = false;
00079 
00084   protected $_jsMessages = array();
00085 
00089   protected $_request = null;
00090 
00100   protected $_scriptaculous = null;
00101 
00105   protected $_templateDirController = null;
00106 
00110   protected $_templates = null;
00111 
00115   protected $_translate = null;
00116 
00123   public function __construct($isXmlHttpRequest = false)
00124   {
00125     $this->_messages  = new ArrayObject();
00126 
00127     $this->_translate = Dsao_Registry::get('translate');
00128 
00129     $config = Dsao_Registry::get('config');
00130 
00131     // Falls Ajax-Anfrage vorliegt, an dieser Stelle abbrechen
00132     if ($this->_isXmlHttpRequest = $isXmlHttpRequest)
00133     {
00134       $this->_ajaxResponse = new Dsao_Ajax_Response();
00135 
00136       return;
00137     }
00138 
00139     $this->_request   = Zend_Controller_Front::getInstance()->getRequest();
00140 
00141     // Standardlayouts
00142     $this->_layoutsDefault = explode(',', $config->smarty->layoutsDefault);
00143 
00144     // Templateobjekt initialisieren
00145     $this->_templates  = new stdClass();
00146     // Inhaltstemplates
00147     $this->_templates->content = new ArrayObject();
00148     // Haupttemplate
00149     $this->_templates->main = null;
00150     // Nach dem Inhalt anzuzeigende Templates
00151     $this->_templates->postContent = new ArrayObject();
00152     // Vor dem Inhalt anzuzeigende Templates
00153     $this->_templates->preContent = new ArrayObject();
00154 
00155     // Smartyverzeichnisse aus Konfiguration holen
00156     $this->template_dir = $config->smarty->templateDir;
00157 
00158     $this->compile_dir  = $config->smarty->compileDir;
00159 
00160     // Templateordner
00161     $this->_templateDirController = $this->_request->getModuleName().'/'.
00162       $this->_request->getControllerName().'/';
00163 
00164     // Falls Debug-Konsole angezeigt werden soll
00165     if ($config->smarty->debug->console)
00166     {
00167       $this->debugging = true;
00168     }
00169   }
00170 
00179   protected function _getTemplatePath($template, $prefix = null)
00180   {
00181     // string, Pfad des Templates relativ zum Templateordner
00182     $templatePath = $prefix.$template.'.tpl';
00183 
00184     // Layouts durchgehen und passenden Pfad zurueckgeben
00185     foreach ($this->_layoutsDefault as $layout)
00186     {
00187       // string, Resultierender, korrekter Pfad des Templates
00188       $resultPath = $layout.'/'.$templatePath;
00189 
00190       // Falls Template vorhanden, dieses zurueckgeben
00191       if (is_file($this->template_dir.$resultPath))
00192       {
00193         return $resultPath;
00194       }
00195     }
00196 
00197     return false;
00198   }
00199 
00209   protected function _init()
00210   {
00211     // Falls bereits initialisiert
00212     if ($this->_initialised)
00213     {
00214       return;
00215     }
00216 
00217     // Layouts initialisieren
00218 
00219     // Falls Benutzer ein Layout gewaehlt hat, dieses zu Array hinzufuegen
00220     if (Dsao_Registry::get('user')->layout)
00221     {
00222       $this->_layoutsDefault[] = Dsao_Registry::get('user')->layout;
00223     }
00224 
00225     // Reihenfolge der Layouts umkehren
00226     $this->_layoutsDefault   = array_reverse($this->_layoutsDefault);
00227 
00228     // Haupttemplate setzen
00229     $this->_templates->main = $this->_getTemplatePath('index');
00230 
00231     // Ggf. modulspefische CSS-Datei / JS-Datei uebergeben
00232     $this->_setModuleCssFile();
00233 
00234     // Ausgabefilter
00235     if (Dsao_Registry::get('config')->smarty->stripOutput)
00236     {
00237       $this->load_filter('output','trimwhitespace');
00238     }
00239 
00240     // Templatesystem ist initialisiert
00241     $this->_initialised = true;
00242   }
00243 
00252   protected function _setModuleCssFile()
00253   {
00254     // Layouts durchgehen
00255     foreach ($this->_layoutsDefault as $layout)
00256     {
00260       $cssFileSystemPath = 'htdocs/css/'.$layout.'/'.
00261         $this->_request->getModuleName().'.css';
00262 
00263       // Falls CSS-Datei in aktuellem Layout vorhanden, diese uebergeben
00264       if (is_file(BASE_DIR.$cssFileSystemPath))
00265       {
00266         $cssFilePath = '/css/'.$layout.'/'.$this->_request->getModuleName();
00267 
00268         $this->assign('moduleCssFile', $cssFilePath);
00269 
00270         return true;
00271       }
00272     }
00273 
00274     return false;
00275   }
00276 
00285   public function addConfirmationTemplate($question, $uri)
00286   {
00287     // Falls Array übergeben wurde, diesen an sprintf übergeben
00288     if (is_array($question))
00289     {
00290       $question = call_user_func_array('Dsao_View_Smarty::sprintf', $question);
00291     }
00292     // Ansonsten einfach Frage übersetzen lassen
00293     else
00294     {
00295       $question = self::sprintf($question);
00296     }
00297 
00298     if (!is_object($uri))
00299     {
00300       $uri = new Dsao_Uri_Http($uri);
00301     }
00302 
00303     // Informationen fuer das Abfragentemplate
00304     $globalConfirm = array
00305       (
00306         'question'  => $question,
00307         'uri'       => $uri,
00308       );
00309 
00310     $this->addTemplate('/global/confirm')
00311     ->assign_by_ref('globalConfirm', $globalConfirm);
00312   }
00313 
00324   public function addJsFile($file)
00325   {
00326     // Falls Ajax-Anfrage, abbrechen
00327     if ($this->_isXmlHttpRequest)
00328     {
00329       return $this;
00330     }
00331 
00332     // string, Relativer Pfad zur JS-Datei auf Dateisystemebene
00333     $jsFileSystemPath = 'htdocs/js'.$file.'.js';
00334 
00335     // Falls JS-Datei vorhanden, diese uebergeben
00336     if (is_file(BASE_DIR.$jsFileSystemPath))
00337     {
00338       // Falls noch keine JavaScript-Dateien hinzugefügt wurden
00339       if (false === $this->_jsFiles)
00340       {
00341         $this->_jsFiles = array();
00342       }
00343 
00344       $this->_jsFiles[] = '/js'.$file;
00345     }
00346 
00347     return $this;
00348   }
00349 
00359   public function addJsTexts($messageIds)
00360   {
00361     // Ggf. in Array umwandeln
00362     $messageIds = (array) $messageIds;
00363 
00364     foreach ($messageIds as $messageId)
00365     {
00366       // Falls keine Uebersetzung existiert, gueltigen Index erstellen
00367       if (($translation = $this->_translate->_($messageId)) == $messageId)
00368       {
00369         $messageId = preg_replace('/\W/', '_', $messageId);
00370       }
00371 
00372       $this->_jsMessages[$messageId] = $translation;
00373     }
00374 
00375     return $this;
00376   }
00377 
00388   public function addScriptaculousFiles(array $files = array())
00389   {
00390     // Falls Objekt noch nicht initialisiert wurde
00391     if (null === $this->_scriptaculous)
00392     {
00393       $this->_scriptaculous = new stdClass();
00394 
00395       $this->_scriptaculous->files = array
00396       (
00397         'builder'   => true,
00398         'effects'   => true,
00399         'dragdrop'  => true,
00400         'controls'  => true,
00401         'slider'    => true,
00402       );
00403 
00404       $this->_scriptaculous->loadScriptaculous = false;
00405       $this->_scriptaculous->queryString = null;
00406     }
00407 
00408     // Falls nichts übergeben wurde, alle Dateien übernehmen
00409     if (empty($files))
00410     {
00411       $files = $this->_scriptaculous->files;
00412     }
00413 
00414     foreach ($files as $file)
00415     {
00416       // Falls Schluessel vorhanden
00417       if (array_key_exists($file, $this->_scriptaculous->files))
00418       {
00419         unset($this->_scriptaculous->files[$file]);
00420 
00421         // Falls Query-String noch leer ist
00422         if (null === $this->_scriptaculous->queryString)
00423         {
00424           $this->_scriptaculous->queryString = '?load='.$file;
00425           $this->_scriptaculous->loadScriptaculous = true;
00426         }
00427         else
00428         {
00429           $this->_scriptaculous->queryString .= ','.$file;
00430         }
00431       }
00432     }
00433 
00434     // Falls bereits alle Dateien zum Laden ausgewählt wurden
00435     if (empty($this->_scriptaculous->files))
00436     {
00437       $this->_scriptaculous->loadScriptaculous = true;
00438       $this->_scriptaculous->queryString = null;
00439     }
00440   }
00441 
00449   public function addTemplate($template = null, $templatePosition = self::CONTENT)
00450   {
00451     // Falls kein Standardtemplate hinzugefuegt werden soll oder Ajax-Anfrage
00452     // vorliegt, abbrechen
00453     if (false === $template || $this->_isXmlHttpRequest)
00454     {
00455        $this->_addDefaultTemplate = false;
00456 
00457        return $this;
00458     }
00459 
00460     // Falls noch nicht geschehen, initialisieren
00461     $this->_init();
00462 
00463     // Falls $_templates->{$templatePosition} nicht existiert oder kein Objekt
00464     // ist, abbrechen
00465     if (!isset($this->_templates->$templatePosition)
00466         || !is_object($this->_templates->$templatePosition))
00467     {
00468       return $this;
00469     }
00470 
00471     // Falls Template nicht uebergeben, Aktionnamen nehmen
00472     if (!$template)
00473     {
00474       $template = $this->_request->getActionName();
00475     }
00476 
00477     // string, bei relativen Angaben wird als Praefix der Pfad zum Verzeichnis
00478     // des Controllers uebergeben
00479     $prefix = null;
00480 
00481     // Falls absolute Angabe
00482     if (substr($template, 0, 1) == '/')
00483     {
00484       // Slash entfernen
00485       $template = substr($template, 1);
00486     }
00487     // Ansonsten Praefix setzen
00488     else
00489     {
00490       $prefix = $this->_templateDirController;
00491     }
00492 
00493     // bool|string, der Pfad zum Template, relativ zum /templates-Ordner oder
00494     // false
00495     $templateFile = $this->_getTemplatePath($template, $prefix);
00496 
00497     // Falls Template existiert
00498     if ($templateFile)
00499     {
00500       // Vor oder nach Inhalt
00501       $this->_templates->$templatePosition->append($templateFile);
00502     }
00503 
00504     return $this;
00505   }
00506 
00518   public static function debug($debugVariable, $value = null, $metaInfo = null)
00519   {
00520     // Falls Array uebergeben wurde, Methode rekursiv aufrufen
00521     if (is_array($debugVariable))
00522     {
00523       foreach ($debugVariable as $variable => $value)
00524       {
00525         self::debug($variable, $value, $metaInfo);
00526       }
00527 
00528       return;
00529     }
00530 
00531         // Falls Debug-Array noch nicht initialisiert wurde
00532     if (null === Dsao_View_Smarty::$_debug)
00533     {
00534       self::$_debug = array();
00535       self::$_debug['metaInfo'] = array();
00536     }
00537 
00538     self::$_debug[$debugVariable] = print_r($value, true);
00539 
00540     // Falls Meta-Informationen übergeben wurden
00541     if ($metaInfo)
00542     {
00543       self::$_debug[$debugVariable.':metaInfo'] = print_r($metaInfo, true);
00544     }
00545   }
00546 
00552   public function getAjaxResponse()
00553   {
00554     return $this->_ajaxResponse;
00555   }
00556 
00562   public function getLayoutDefault()
00563   {
00564     return end($this->_layoutsDefault);
00565   }
00566 
00572   public function getLayouts()
00573   {
00574     // Falls Ajax-Anfrage vorliegt, abbrechen
00575     if ($this->_isXmlHttpRequest)
00576     {
00577       return array();
00578     }
00579 
00580     // Falls Layouts bereits initialisiert wurden, diese zurueckgeben
00581     if ($this->_layouts)
00582     {
00583       return $this->_layouts;
00584     }
00585 
00586     // Ansonsten $_layout initialisieren
00587     $this->_layouts = array();
00588 
00589     // DirectoryIterator, Ordner, der alle Layouts enthaelt (/templates)
00590     $layoutDir = new DirectoryIterator(Dsao_Registry::get('config')->smarty->templateDir);
00591 
00592     // Eintraege durchlaufen
00593     while ($layoutDir->valid())
00594     {
00595       // Falls Verzeichnis gueltiges Layoutverzeichnis
00596       if (!$layoutDir->isDot()
00597           && $layoutDir->isDir()
00598           // Keine Verzeichnisse, die mit einem Punkt beginnen ('.svn' etc.)
00599           && substr($layoutDir->getFilename(), 0, 1) != '.'
00600           // Temporär, um Default-Layout zu 'verstecken'
00601           && $layoutDir->getFilename() != 'default')
00602       {
00603         $this->_layouts[] = $layoutDir->getFilename();
00604       }
00605 
00606       $layoutDir->next();
00607     }
00608 
00609     return $this->_layouts;
00610   }
00611 
00621   public function render()
00622   {
00623     $config = Dsao_Registry::get('config');
00624 
00625     // Ggf. Debug-Informationen uebergeben
00626     if ($config->smarty->debug->output)
00627     {
00628       $this->assign('debug', self::$_debug);
00629     }
00630 
00631     // Falls Ajax-Anfrage vorliegt, nur bis hierhin ausführen
00632     if ($this->_isXmlHttpRequest)
00633     {
00634       // Daten ausgeben (u.U werden Nachrichten und Variablen nicht uebergeben)
00635       return $this->_ajaxResponse->setData
00636         ($this->get_template_vars(), Dsao_Ajax_Response::JSON, false);
00637     }
00638 
00639     // Nachrichten und Templatedateien uebergeben
00640     $this->assign(array
00641       (
00642         'jsFiles'             => $this->_jsFiles,
00643         'jsMessages'          => $this->_jsMessages,
00644         'scriptaculous'       => $this->_scriptaculous,
00645         'templates'           => $this->_templates,
00646       ));
00647 
00648     // Falls noch kein Inhaltstemplate uebergeben wurde, Standardtemplate
00649     // hinzufuegen
00650     if (!count($this->_templates->content) && $this->_addDefaultTemplate)
00651     {
00652       $this->addTemplate();
00653     }
00654 
00655     // Falls Smarty noch nicht initialisiert wurde
00656     if (!$this->_initialised)
00657     {
00658       $this->_init();
00659     }
00660 
00661     // Profiling
00662     $profiler = Dsao_Registry::get('db')->getProfiler();
00663 
00664     // Falls Profiler aktiviert
00665     if ($profiler->getEnabled())
00666     {
00667       $this->assign('footerProfiling', self::sprintf('footer_profiling',
00668         array(
00669           'count' => $profiler->getTotalNumQueries(),
00670           'time' => $profiler->getTotalElapsedSecs())
00671       ));
00672 
00673       // Falls ausführliches Profiling aktiviert wurde
00674       if ($config->db->profiler == 'verbose'
00675           && false !== $profiler->getQueryProfiles())
00676       {
00677         $queries = '';
00678 
00679         foreach ($profiler->getQueryProfiles() as $queryProfile)
00680         {
00681           $queries .= '<br />'.$queryProfile->getQuery();
00682         }
00683 
00684         $this->assign_by_ref('footerProfilingQueries', $queries);
00685       }
00686     }
00687 
00688     // Nun darf Smarty loslegen
00689     $this->display($this->_templates->main);
00690 
00691     return $this;
00692   }
00693 
00704   public function setModuleNavigation(array $navigation = array())
00705   {
00706     $this->assign('moduleNavigation', $navigation);
00707   }
00708 
00723   public static function sprintf($string = null, array $variables = array(), $translateVariables = false, $translateString = true)
00724   {
00725     // Falls leerer String uebergeben
00726     if (!$string)
00727     {
00728       return '';
00729     }
00730 
00731     $translate = Dsao_Registry::get('translate');
00732 
00733     if ($translateString)
00734     {
00735       $string = $translate->_($string);
00736     }
00737 
00738     // Zu ersetzende Variablen durchgehen
00739     if (count($variables) > 0)
00740     {
00741       // array, Schluessel, also zu ersetzende Variablen
00742       $keys = array_keys($variables);
00743 
00744       // Schluessel durchgehen und '%' voranstellen
00745       foreach ($keys as &$key)
00746       {
00747         $key = '%'.$key;
00748       }
00749 
00750       // array, die einzusetzenden Werte
00751       $values = array_values($variables);
00752 
00753       // Falls Variablen uebersetzt werden sollen, durchgehen und uebersetzen
00754       if ($translateVariables)
00755       {
00756         foreach ($values as &$value)
00757         {
00758             $value = $translate->_($value);
00759         }
00760       }
00761 
00762       // Variablen durch Werte ersetzen
00763       $string = str_replace($keys, $values, $string);
00764     }
00765 
00766     return $string;
00767   }
00768 }

Erzeugt am Fri Sep 18 19:04:12 2009 für DSA online - Morgendaemmerung von  doxygen 1.5.7.1