view includes/class.skeleton.php @ 41:8d209692d734

Conversion des atomes de type ?param&param2=truc en param=param Cela correspond à ce qui se fait par exemple sur les attributs lors du passage de XML à XHTML, avec checked='checked' pour les checkbox par exemple.
author Franck Deroche <webmaster@defr.org>
date Mon, 12 Nov 2007 17:05:37 +0100
parents 33d1c5a13acd
children 1cdb1a68634b
line wrap: on
line source
<?php
class Skeleton extends Template {

  private $styleSheets;
  private $blogPosts;
  private $lastUpdate = 0;
  private $showCalendar = false;
  private $calendarMonth;
  private $calendarYear;
  private $useXML;

  const OUTPUT_XHTML = 'xhtml';
  const OUTPUT_ATOM  = 'atom';
  const OUTPUT_RSS   = 'rss';

  private static $outputType = OUTPUT_XHTML;
  private static $templates = array();

  public function __construct() {
     parent::__construct(Skeleton::getTemplateFile('skeleton'));
     parent::shouldStripAttributesInTemplateNS(true);
     $this->styleSheets = array();
     $this->addDefaultSheets();
     $this->blogPosts = array();
     $this->useXML = empty($_SERVER['HTTP_ACCEPT']) || 
     		     stristr($_SERVER['HTTP_ACCEPT'], 'application/xhtml+xml');
  }

  public function setTitle($titre) {
    $this->setParams(array('title' => $titre));
  }

  private function buildSidebar() {
      $sidebar = new Template('sidebar.xml');
      // 1. Récupération des archives
      $db = Factory::getDB();
      $db->Query("
        SELECT 
            MONTH(DatePost) As Month, 
            YEAR(DatePost) As Year, 
            COUNT(num_mess) As Nb 
        FROM Mess 
        GROUP BY 
            MONTH(DatePost), 
            YEAR(DatePost) 
        ORDER BY 
            YEAR(DatePost) DESC, 
            Month(DatePost) DESC
       ");
       $archives = array();
	   while($row = $db->GetRow()) {
            $curArchiveTpl = new Template('archive.xml');
            $monthName = TextUtils::getMonthName($row['Month']);
            $curArchiveTpl->setParams(array(
                'a' =>  $monthName . ' ' . $row['Year'],
                'a@href' => "http://defr.org/blog/posts/{$row['Year']}/{$row['Month']}",
                'postCount' => '(' . $row['Nb'] . ')'
            ));
            $archives[] = array('li' => $curArchiveTpl);
	   }
      // 2. Récupération des derniers commentaires
      $db->Query("
        SELECT C.*, M.Titre 
        FROM Commentaires C, Mess M 
        WHERE C.MessId = M.num_mess AND C.Visible=1
        ORDER BY num_comm DESC LIMIT 20");
      $i = 0;
      $comments = array();
      while($row = $db->GetRow()) {
        $curCommentTpl = new Template('commentIndex.xml');
        // On récupère une version filtrée du titre du post ...
        $tf = TextUtils::StripTitle($row['Titre']);
        // ... Qui nous permet d'obtenir l'adresse du commentaire sur le post
        $c_url = "/blog/post/{$row['MessId']}-$tf#c{$row['num_comm']}";
        // Si jamais on a une adresse mail, on rajoute un mailto:
        if(strpos($row['Adresse'], '@') !== false) 
            $row['Adresse'] = 'mailto:' . $row['Adresse'];
        // On commence par définir les paramètres généraux
        $params = array(                
                '#CommentAuthor' => $row['Auteur'],
                '#CommentAuthor@href' => $row['Adresse'],
                '#Post' => $row['Titre'],
                '#Post@href' => $c_url
        );
        // On affiche les 5 commentaires les plus récents en version complète
        // puis les 15 autres en versions résumées
        if($i < 5) {
            $Comment = nl2br($row['Comment']);
        }
        else {
            $Comment = str_replace("\n", " ", strip_tags($row['Comment']));
    		if(strlen($Comment > 100))
                $Comment = utf8_encode(substr(utf8_decode($Comment), 0, 97)) . "...";
            $params['li@class'] = 'fold';
        }

        $frag = $curCommentTpl->getDocumentFragment();
        $frag->appendXML($Comment);
        $params['comment'] = $frag;
        $curCommentTpl->setParams($params);
        $comments[] = array('blogComment' => $curCommentTpl);
        $i++;
      }
      // 3. Application des paramètres
      $sidebar->setParams(array(
            '#archives' => $archives,
            '#BlogCommentIndex' => $comments
      ));
      return $sidebar;
  }

  private function buildLinks() {
      $links = new Template('links.xml');
      return $links;
  }

  private function buildCalendar() {
    $retVal = null;
    if($this->showCalendar) {
       $cMonth = $this->calendarMonth;
       $cYear = $this->calendarYear;
       $nextMonth = ($cMonth % 12) + 1;
       $nextYear = ($nextMonth == 1) ? $cYear + 1 : $cYear;
       $prevMonth = $cMonth - 1;
       if($prevMonth == 0)
       	 $prevMonth = 12;
       $prevYear = ($prevMonth == 12) ? $cYear - 1 : $cYear;
       $retVal = new Template('calendar.xml');
       $retVal->setParams(array(
         '#calPrev' => TextUtils::getMonthName($prevMonth) . ' ' . $prevYear,
         '#calPrev@href' => '/blog/posts/' . $prevYear . '/' . $prevMonth,
         '#calNext' => TextUtils::getMonthName($nextMonth) . ' ' . $nextYear,
         '#calNext@href' => '/blog/posts/' . $nextYear . '/' . $nextMonth,
         'currentMonth' => TextUtils::getMonthName($cMonth) . ' ' . $cYear
       ));
    } else {
      $retVal = '';
    }
    return $retVal;
  }

  public function addStyleSheet($SheetName, $CSSFile, $enabled = false) {
    $this->styleSheets[] = (object)array(
        'name' => $SheetName,
        'CSSFile' => $CSSFile,
        'enabled' => $enabled
    );
  }

  public function enableStyleSheet($styleSheetName) {
    foreach($this->styleSheets as $styleSheet) {
      $styleSheet->enabled = ($styleSheet->name == $styleSheetName);
    }
  }

  public function addDefaultSheets() {
    $StyleSheets = array(
   	    "Somatic" => "Somatic.css",
	    "OliveVerde" => "OliveVerde.css",
	    "Lite:Reloaded" => "Lite_nv.css",
	    "Brushed" => "Brushed.css",
	    ":Hover" => "HoverExp.css");
    $CkStyle = (array_key_exists("style", $_COOKIE) && 
                array_key_exists($_COOKIE['style'], $StyleSheets))
               ? $_COOKIE['style']
               :"Somatic";
    foreach($StyleSheets as $SheetName => $CSSFile)
        $this->addStyleSheet($SheetName, $CSSFile, ($SheetName == $CkStyle));
  }

  public function addBlogPost(Template $blogPost) {
    $this->blogPosts[] = $blogPost;
  }

  public function checkUpdateTime($time) {
    if($time > $this->lastUpdate)
        $this->lastUpdate = $time;
  }

  public function showCalendar($newValue = false) {
    $this->showCalendar = $newValue;
  }

  public function setCalendarMonth($month, $year) {
    $this->calendarMonth = $month;
    $this->calendarYear = $year;
  }

  private function prepareOutput() {
     $params = array();

     // Ajout de la sidebar
     $params['sidebar'] = $this->buildSideBar();

     // Ajout de la liste des liens
     $params['links']   = $this->buildLinks();

     // Ajout des feuilles de style
     $params['possibleStyleSheets'] = array();
     foreach($this->styleSheets as $styleSheet) {
        $type = ($styleSheet->enabled) ? "" : "Alternate ";
        $type .= "StyleSheet";
        $params['possibleStyleSheets'][] = array(
            'link@href'  => '/blog/css/' . $styleSheet->CSSFile,
            'link@rel'   => $type,
            'link@title' => $styleSheet->name
        );
     }

     // Affichage éventuel des liens vers les mois précédents et suivants
     $params['calendarPrevNext'] = $this->buildCalendar();

     // Ajout des posts de blog
     $params['#Posts'] = array();
     foreach($this->blogPosts as $blogPost) {
        $params['#Posts'][] = array('post' => $blogPost);
     }

     // Date de dernière modification
     $params['modifiedDate'] = date('c', $this->lastUpdate);

     // Application des l'ensemble de ces paramètres
     $this->setParams($params);
  }

  public function __toString() {
    $this->prepareOutput();
    $returnValue = parent::__toString();
    $this->setContentTypeHeader();
    // L'ajout d'un preambule XML fait sortir IE de son mode de
    // respect des standards
    if(!$this->useXML)
      $returnValue = ereg_replace('<\?xml[^\?]*\?>', '', $returnValue);
    return $returnValue;
  }

  private function setContentTypeHeader() {
    $contentType = null;
    if(Skeleton::getOutputType() == Skeleton::OUTPUT_ATOM)
        $contentType = 'application/atom+xml';
    else if($this->useXML && Skeleton::getOutputType() == Skeleton::OUTPUT_XHTML)
        $contentType = 'application/xhtml+xml; charset=utf-8';
    if(!is_null($contentType))
        header('Content-Type: ' . $contentType);
  }

  public static function getTemplateFile($type) {
    if(count(Skeleton::$templates) == 0) {
      // Construction du tableau des différents templates
      // permettant de répondre au "type" de sortie demandé
      $iniFile = parse_ini_file('templates.conf', true);
     
      $format = Factory::getRequete()
                       ->get('outputType', null, Skeleton::OUTPUT_XHTML);

      if(array_key_exists($format, $iniFile)) {
        Skeleton::$templates = $iniFile[$format];
        Skeleton::$outputType = $format;
      } else {
        Skeleton::$templates = $iniFile[Skeleton::OUTPUT_XHTML];
        Skeleton::$outputType = Skeleton::OUTPUT_XHTML;
      }
    }
    return Skeleton::$templates[$type];
  }

  public static function getOutputType() {
    // On s'assure que la demande a été analysée, si ce n'est pas
    // le cas on le fait maintenant, en demandant un template
    if(count(Skeleton::$templates) == 0)
        Skeleton::getTemplateFile('skeleton');
    return Skeleton::$outputType;
  }
}
?>