source: extensions/ColorStat/cstat_aip.class.inc.php @ 16859

Last change on this file since 16859 was 16010, checked in by grum, 12 years ago

feature:2639- compatibility with Piwigo 2.4

  • Property svn:executable set to *
File size: 22.0 KB
Line 
1<?php
2/* -----------------------------------------------------------------------------
3  Plugin     : ColorStat
4  Author     : Grum
5    email    : grum@piwigo.org
6    website  : http://photos.grum.fr
7
8    << May the Little SpaceFrog be with you ! >>
9  ------------------------------------------------------------------------------
10  See main.inc.php for release information
11
12  CStat_AIP : classe to manage plugin admin pages
13
14  --------------------------------------------------------------------------- */
15
16if(!defined('PHPWG_ROOT_PATH')) die('Hacking attempt!');
17
18include_once('cstat_root.class.inc.php');
19include_once(PHPWG_PLUGINS_PATH.'GrumPluginClasses/classes/GPCAjax.class.inc.php');
20include_once(PHPWG_PLUGINS_PATH.'GrumPluginClasses/classes/GPCTables.class.inc.php');
21include_once(PHPWG_PLUGINS_PATH.'GrumPluginClasses/classes/GPCTabSheet.class.inc.php');
22include_once(PHPWG_PLUGINS_PATH.'GrumPluginClasses/classes/GPCRequestBuilder.class.inc.php');
23include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php');
24
25class CStat_AIP extends CStat_root
26{
27  protected $tabsheet;
28
29  public function __construct($prefixeTable, $filelocation)
30  {
31    parent::__construct($prefixeTable, $filelocation);
32    $this->checkRequest();
33
34    $this->loadConfig();
35    $this->initEvents();
36
37    $this->tabsheet = new tabsheet();
38    $this->tabsheet->add('database',
39                          l10n('cstat_database'),
40                          $this->getAdminLink()."-database");
41    $this->tabsheet->add('stat',
42                          l10n('cstat_stat'),
43                          $this->getAdminLink()."-stat");
44    $this->tabsheet->add('search',
45                          l10n('cstat_search'),
46                          $this->getAdminLink()."-search");
47    $this->tabsheet->add('config',
48                          l10n('cstat_config'),
49                          $this->getAdminLink()."-config");
50  }
51
52  public function __destruct()
53  {
54    unset($this->tabsheet);
55    parent::__destruct();
56  }
57
58  /*
59    initialize events call for the plugin
60  */
61  public function initEvents()
62  {
63    parent::initEvents();
64    if($_GET['tab']=='search')
65    {
66      // load request builder JS only on the search page
67      GPCRequestBuilder::loadJSandCSS();
68    }
69  }
70
71
72  public function loadCSS()
73  {
74    parent::loadCSS();
75    GPCCore::addUI('gpcCSS');
76    GPCCore::addHeaderCSS('cstat.css', 'plugins/'.$this->getDirectory().'/'.$this->getPluginNameFiles().".css");
77  }
78
79  /*
80    display administration page
81  */
82  public function manage()
83  {
84    global $template;
85
86    $this->returnAjaxContent();
87
88    GPCCore::setTemplateToken();
89    $template->set_filename('plugin_admin_content', dirname(__FILE__)."/admin/cstat_admin.tpl");
90
91    switch($_GET['tab'])
92    {
93      case 'database':
94        $this->displayDatabasePage();
95        break;
96      case 'stat':
97        $this->displayStatPage();
98        break;
99      case 'search':
100        $this->displaySearchPage();
101        break;
102      case 'config':
103        $this->displayConfigPage();
104        break;
105    }
106
107    $this->tabsheet->select($_GET['tab']);
108    $this->tabsheet->assign();
109    $selected_tab=$this->tabsheet->get_selected();
110    $template->assign($this->tabsheet->get_titlename(), "[".$selected_tab['caption']."]");
111
112    $template_plugin["CSTAT_VERSION"] = "<i>".$this->getPluginName()."</i> ".l10n('cstat_release').CSTAT_VERSION;
113
114    $template->assign('plugin', $template_plugin);
115    $template->assign_var_from_handle('ADMIN_CONTENT', 'plugin_admin_content');
116  }
117
118
119  /*
120    return ajax content
121  */
122  protected function returnAjaxContent()
123  {
124    global $ajax, $template;
125
126    if($_REQUEST['ajaxfct']!='')
127    {
128      //$this->debug("AJAXFCT:".$_REQUEST['ajaxfct']);
129      $result="<p class='errors'>An error has occured</p>";
130      switch($_REQUEST['ajaxfct'])
131      {
132        case 'updateDatabaseGetStatus':
133          $result=$this->ajax_cstat_updateDatabaseGetStatus();
134          break;
135        case 'updateDatabaseGetList':
136          $result=$this->ajax_cstat_updateDatabaseGetList($_REQUEST['selectMode'], $_REQUEST['numOfItems']);
137          break;
138        case 'updateDatabaseDoAnalyze':
139          $result=$this->ajax_cstat_updateDatabaseDoAnalyze($_REQUEST['imagesList']);
140          break;
141        case 'updateDatabaseConsolidation':
142          $result=$this->ajax_cstat_updateDatabaseConsolidation();
143          break;
144        case 'showStatsGetListColors':
145          $result=$this->ajax_cstat_showStatsGetListColors($_REQUEST['orderType']);
146          break;
147        case 'doPpsBench':
148          $result=$this->ajax_cstat_ppsBench($_REQUEST['quality'], true);
149          break;
150      }
151      GPCAjax::returnResult($result);
152    }
153  }
154
155  /**
156   * check the $_REQUEST values and set default values
157   *
158   */
159  protected function checkRequest()
160  {
161    if(!isset($_GET['tab'])) $_GET['tab']='stat';
162
163
164    if(!($_GET['tab']=='database' or
165         $_GET['tab']=='stat' or
166         $_GET['tab']=='search' or
167         $_GET['tab']=='config')) $_GET['tab']='stat';
168
169    GPCAjax::checkToken();
170
171    if(isset($_REQUEST['ajaxfct']))
172    {
173      if($_REQUEST['ajaxfct']=='updateDatabaseGetList')
174      {
175        if(!isset($_REQUEST['selectMode'])) $_REQUEST['selectMode']='caddieAdd';
176        if(!isset($_REQUEST['numOfItems'])) $_REQUEST['numOfItems']=$this->config['analyze_itemPerRequest'];
177
178        if(!($_REQUEST['selectMode']=='notAnalyzed' or
179             $_REQUEST['selectMode']=='all' or
180             $_REQUEST['selectMode']=='caddieAdd' or
181             $_REQUEST['selectMode']=='caddieReplace')) $_REQUEST['selectMode']='caddieAdd';
182
183        if($_REQUEST['numOfItems'] <=0 or $_REQUEST['numOfItems']>100) $_REQUEST['numOfItems']=10;
184      }
185
186
187      if($_REQUEST['ajaxfct']=='updateDatabaseDoAnalyze')
188      {
189        if(!isset($_REQUEST['imagesList'])) $_REQUEST['imagesList']='';
190      }
191
192      if($_REQUEST['ajaxfct']=='showStatsGetListColors')
193      {
194        if(!isset($_REQUEST['orderType'])) $_REQUEST['orderType']='img';
195
196        if(!($_REQUEST['orderType']=='color' or
197             $_REQUEST['orderType']=='img' or
198             $_REQUEST['orderType']=='pixels')) $_REQUEST['orderType']=='img';
199      }
200
201
202      if($_REQUEST['ajaxfct']=='doPpsBench')
203      {
204        if(!isset($_REQUEST['quality'])) $_REQUEST['quality']=8;
205        if($_REQUEST['quality']>50 or $_REQUEST['quality']<1) $_REQUEST['quality']=8;
206      }
207    }
208
209  }
210
211  /**
212   * display the database page
213   */
214  protected function displayDatabasePage()
215  {
216    global $template;
217
218    $template->set_filename('body_page',
219                dirname($this->getFileLocation()).'/admin/cstat_database.tpl');
220
221    pwg_query("INSERT INTO ".$this->tables['images']."
222                SELECT id, 'n', 0, 0, 0, 0, 0, 0, '', ''
223                  FROM ".IMAGES_TABLE."
224                  WHERE id NOT IN (SELECT image_id FROM ".$this->tables['images'].")");
225
226    $datas=Array(
227      'urlRequest' => $this->getAdminLink(),
228      'numberOfItemsPerRequest' => $this->config['analyze_itemPerRequest']
229    );
230    $template->assign('datas', $datas);
231    $template->assign_var_from_handle('CSTAT_BODY_PAGE', 'body_page');
232  } //displayDatabasePage
233
234  /**
235   * display the stat page
236   */
237  protected function displayStatPage()
238  {
239    global $template;
240
241    GPCCore::addUI('simpleTip');
242    $template->set_filename('body_page',
243                dirname($this->getFileLocation()).'/admin/cstat_stat.tpl');
244
245    $colorTable=CStat_functions::getColorTableWithStat();
246
247
248    $datas=Array(
249      //'themeconf' => Array('name' => $template->get_themeconf('name')),
250      'colorTable' => CStat_functions::htmlColorTable(
251                        $colorTable,
252                        ($this->config['analyze_colorTable']=='small')?19:10,
253                        "",
254                        "color0px",
255                        "<br>"
256                      ),
257      'urlRequest' => $this->getAdminLink(),
258      'config_GetListColors_OrderType' => $this->config['display_stat_orderType'],
259    );
260    $template->assign('datas', $datas);
261    $template->assign_var_from_handle('CSTAT_BODY_PAGE', 'body_page');
262  } //displayStatPage
263
264
265  /**
266   * display search page
267   */
268  protected function displaySearchPage()
269  {
270    global $template, $lang;
271
272    $template->set_filename('body_page',
273                dirname($this->getFileLocation()).'/admin/cstat_search.tpl');
274
275    $template->assign('cstat_search_page', GPCRequestBuilder::displaySearchPage($this->getPluginName()));
276
277    $template->assign_var_from_handle('CSTAT_BODY_PAGE', 'body_page');
278  } //displaySearchPage
279
280
281  /**
282   * manage display of config page & save config
283   */
284  protected function displayConfigPage()
285  {
286    $tmpPct=$this->config['stat_minPct'];
287
288    if(!$this->adviser_abort())
289    {
290      if(isset($_POST['submit_save_config']))
291      {
292        foreach($this->config as $key => $val)
293        {
294          if(isset($_REQUEST['f_'.$key]))
295          {
296            $this->config[$key] = $_REQUEST['f_'.$key];
297          }
298        }
299        $this->displayResult(l10n('cstat_save_config'), $this->saveConfig());
300      }
301    }
302
303    if($tmpPct!=$this->config['stat_minPct'])
304    {
305      $this->updateDatabaseConsolidation();
306    }
307
308    $this->displayConfig();
309  }
310
311  /**
312   * display config page
313   */
314  protected function displayConfig()
315  {
316    global $template, $lang;
317
318    $configTabs=new GPCTabSheet('configTabsheet', $this->tabsheet->get_titlename(), 'tabsheet2 gcBorder', 'itab2');
319    $configTabs->add('database',
320                      l10n('cstat_database'),
321                      '', true, "displayConfig('database');");
322    $configTabs->add('statsearch',
323                      l10n('cstat_stat_and_search'),
324                      '', false, "displayConfig('statsearch');");
325    $configTabs->add('display',
326                      l10n('cstat_gallery_integration'),
327                      '', false, "displayConfig('display');");
328    $configTabs->assign();
329
330    $template->set_filename('body_page',
331                dirname($this->getFileLocation()).'/admin/cstat_config.tpl');
332
333    $nbPictures=0;
334    $sql="SELECT COUNT(image_id) FROM ".$this->tables['images'];
335    $result=pwg_query($sql);
336    if($result)
337    {
338      while($row=pwg_db_fetch_row($result))
339      {
340        $nbPictures=$row[0];
341      }
342    }
343
344
345    $datas=Array(
346      'nbPictures' => $nbPictures,
347      'pps' => $this->config['analyze_pps'],
348      'quality' => $this->config['analyze_ppsQuality'],
349      'qualityHighest' => 14000,
350      'qualityHigh' => 7500,
351      'qualityNormal' => 3500,
352      'qualityLow' => 1200,
353      'qualityLowest' => 600,
354      'urlRequest' => $this->getAdminLink(),
355      'minPct' => $this->config['stat_minPct'],
356      'showColors' => $this->config['display_gallery_showColors'],
357      'colorSize' => $this->config['display_gallery_colorSize'],
358    );
359
360    $template->assign('datas', $datas);
361
362    $template->assign_var_from_handle('CSTAT_BODY_PAGE', 'body_page');
363  } //displayConfig
364
365
366  /**
367   * manage adviser profile
368   * return true if user is adviser
369   */
370  protected function adviser_abort()
371  {
372    if(is_adviser())
373    {
374      $this->displayResult(l10n("cstat_adviser_not_allowed"), false);
375      return(true);
376    }
377    return(false);
378  }
379
380
381  /* ---------------------------------------------------------------------------
382    function to manage database manipulation
383  --------------------------------------------------------------------------- */
384  protected function analyzeImageFile($fileName, $imageId, $colorTable)
385  {
386    // set the picture to the 'try to analyze' statut
387    $sql="UPDATE ".$this->tables['images']." SET analyzed='t'
388          WHERE image_id=".$imageId.";";
389    pwg_query($sql);
390
391    $colors=ColorStat::getFileColors(
392      $fileName,
393      $colorTable,
394      Array(
395        'mode' => 'numAnalyzed',
396        'numColors' => 24,
397        'numAnalyzed' => $this->config['analyze_ppsQuality'],
398      )
399    );
400
401    if($colors!==false and
402       ColorStat::$fileColorsStat['colors']>0 and
403       ColorStat::$fileColorsStat['analyzed']>0)
404    {
405      $sql="UPDATE ".$this->tables['images']."
406              SET analyzed='y',
407                  num_colors='".ColorStat::$fileColorsStat['colors']."',
408                  num_pixels='".ColorStat::$fileColorsStat['pixels']."',
409                  analyzed_pixels='".ColorStat::$fileColorsStat['analyzed']."',
410                  pps='".ColorStat::$fileColorsStat['pps']."',
411                  time='".ColorStat::$fileColorsStat['time']."',
412                  quality='".ColorStat::$fileColorsStat['quality']."'
413            WHERE image_id=".$imageId.";";
414      pwg_query($sql);
415      $sql="";
416      foreach($colors as $key=>$val)
417      {
418        /*
419         * $key => RGB color #RRGGBB
420         * $val => Array (
421         *            'hsv' => Array ('H', 'S', 'V')
422         *            'num' => integer
423         *            'pct' => float
424         *          )
425         */
426
427        $sql.=(($sql=="")?"":", ")."
428              ('".$imageId."', '".$key."', ".$val['pct'].", ".$val['num'].")";
429      }
430      $sql="REPLACE INTO ".$this->tables['images_colors']."
431                VALUES ".$sql;
432      pwg_query($sql);
433
434      return($imageId.'='.ColorStat::$fileColorsStat['colors'].';');
435    }
436    else
437    {
438      return($imageId.'=KO;');
439    }
440  }
441
442
443  /**
444   * make consolidation for the color_table :
445   *  - count number of images using a color
446   *  - count number of pixels of a color
447   */
448  protected function updateDatabaseConsolidation()
449  {
450    $sql="UPDATE ".$this->tables['color_table']." cct
451          SET cct.num_images=0,
452              cct.num_pixels=0;";
453    pwg_query($sql);
454
455    $sql="UPDATE ".$this->tables['color_table']." cct,
456                 (SELECT color_id,
457                         count(image_id) AS num_images,
458                         sum(num_pixels) AS num_pixels
459                  FROM ".$this->tables['images_colors']."
460                  WHERE pct >= ".$this->config['stat_minPct']."
461                  GROUP BY color_id) cic
462          SET cct.num_images=cic.num_images,
463              cct.num_pixels=cic.num_pixels
464          WHERE cct.color_id=cic.color_id;";
465    pwg_query($sql);
466
467    $sql="UPDATE ".$this->tables['images']." pci
468          SET pci.colors = '',
469              pci.colors_pct = ''";
470    pwg_query($sql);
471
472    $sql="UPDATE ".$this->tables['images']." pci,
473          (SELECT image_id,
474                  GROUP_CONCAT(color_id ORDER BY pct DESC SEPARATOR ',') AS colors,
475                  GROUP_CONCAT(pct ORDER BY pct DESC SEPARATOR ',') AS colors_pct
476           FROM ".$this->tables['images_colors']."
477           WHERE pct >= ".$this->config['stat_minPct']."
478           GROUP BY image_id) pcic
479          SET pci.colors = pcic.colors,
480              pci.colors_pct = pcic.colors_pct
481          WHERE pci.image_id = pcic.image_id;";
482    pwg_query($sql);
483  }
484
485  /* ---------------------------------------------------------------------------
486    ajax functions
487  --------------------------------------------------------------------------- */
488
489  /**
490   * returns a list of formated string, separated with a semi-colon :
491   *  - number of current analyzed pictures
492   *  - number of pictures not analyzed + number of picture in error
493   *
494   * @return String
495   */
496  private function ajax_cstat_updateDatabaseGetStatus()
497  {
498    $numOfPictures=0;
499    $numOfPicturesNotAnalyzed=0;
500    $numOfPicturesInError=0;
501
502    $sql="SELECT COUNT(image_id), analyzed FROM ".$this->tables['images']."
503            GROUP BY analyzed;";
504    $result=pwg_query($sql);
505    if($result)
506    {
507      while($row=pwg_db_fetch_row($result))
508      {
509        switch($row[1])
510        {
511          case 'n': //no
512            $numOfPicturesNotAnalyzed=$row[0];
513            break;
514          case 'y': //yes
515            $numOfPictures=$row[0];
516            break;
517          case 't': //tried to be analyzed, but not finished
518            $numOfPicturesInError=$row[0];
519            break;
520        }
521      }
522    }
523
524    return(sprintf(l10n("cstat_numberOfAnalyzedPictures"), $numOfPictures).";".
525           sprintf(l10n("cstat_numberOfNotAnalyzedPictures"), $numOfPicturesNotAnalyzed).";".
526           sprintf(l10n("cstat_numberOfPicturesInError"), $numOfPicturesInError));
527  }
528
529
530  /**
531   * return a list of picture Id
532   *
533   * picture id are separated with a space " "
534   * picture id are grouped in blocks of 'NumberOfItemsPerRequest' items and
535   * are separated with a semi-colon ";"
536   *
537   * client side just have to split blocks, and transmit it to the server
538   *
539   * There is four mode to determine the pictures being analyzed :
540   *  - "all"           : analyze all the images (add & replace)
541   *  - "notAnalyzed"   : analyze only the images not yet analyzed (add)
542   *  - "caddieAdd"     : analyze all the images of the caddie (add)
543   *  - "caddieReplace" : analyze all the images of the caddie (add & replace)
544   *
545   * @param String $mode
546   * @param Integer $nbOfItems : number of items per request
547   * @return String : list of image id to be analyzed, separated with a space
548   *                      "23 78 4523 5670"
549   */
550  private function ajax_cstat_updateDatabaseGetList($mode, $nbOfItems)
551  {
552    global $user;
553
554    $returned="";
555
556    $sql="SELECT cit.image_id FROM ".$this->tables['images']." cit";
557    if($mode=="notAnalyzed")
558    {
559      $sql.=" WHERE cit.analyzed='n'";
560    }
561    elseif($mode=="caddieAdd" or $mode=="caddieReplace")
562    {
563      $sql.=" LEFT JOIN ".CADDIE_TABLE." ct ON cit.image_id = ct.element_id
564            WHERE ct.user_id = ".$user['id']." ";
565      if($mode=="caddieAdd") $sql.=" AND cit.analyzed='n'";
566    }
567
568    if($mode=="all" or $mode=="caddieReplace")
569    {
570      pwg_query("UPDATE ".$this->tables['images']."
571                  SET analyzed='n',
572                      num_colors=0,
573                      num_pixels=0,
574                      analyzed_pixels=0,
575                      pps=0,
576                      time=0,
577                      quality=0
578                  WHERE analyzed<>'t'");
579      pwg_query("DELETE FROM ".$this->tables['images_colors']);
580      pwg_query("UPDATE ".$this->tables['color_table']."
581                 SET num_pixels=0, num_images=0;");
582    }
583
584    $result=pwg_query($sql);
585    if($result)
586    {
587      $i=0;
588      while($row=pwg_db_fetch_row($result))
589      {
590        $returned.=$row[0];
591        $i++;
592        if($i>=$nbOfItems)
593        {
594          $returned.=";";
595          $i=0;
596        }
597        else
598        {
599          $returned.=" ";
600        }
601      }
602    }
603    return(trim($returned).";");
604  }
605
606
607
608  /**
609   * extract metadata from images
610   *
611   * @param String $imageList : list of image id to be analyzed, separated with
612   *                            a space
613   *                                "23 78 4523 5670"
614   * @return String : list of the analyzed pictures, with number of colors found
615   *                  for each picture
616   *                    "23=0;78=66;4523=33;5670=91;"
617   */
618  private function ajax_cstat_updateDatabaseDoAnalyze($imagesList)
619  {
620    $list=explode(" ", trim($imagesList));
621
622    $returned="";
623
624    if(count($list)>0 and trim($imagesList)!='')
625    {
626      // $path = path of piwigo's on the server filesystem
627      $path=dirname(dirname(dirname(__FILE__)));
628
629      $sql="SELECT id, path FROM ".IMAGES_TABLE." WHERE id IN (".implode(", ", $list).")";
630      $result=pwg_query($sql);
631      if($result)
632      {
633        $colorTable=ColorStat::getColorTable(
634          CStat_root::$colorTableSize[$this->config['analyze_colorTable']][0],
635          CStat_root::$colorTableSize[$this->config['analyze_colorTable']][1]
636        );
637
638        while($row=pwg_db_fetch_assoc($result))
639        {
640          /*
641           * in some case (in a combination of some pictures), when there is too
642           * much pictures to analyze in the same request, a fatal error occurs
643           * with the message : "Allowed memory size of XXXXX bytes exhausted"
644           *
645           *
646           * tracking memory leak is not easy... :-(
647           *
648           */
649          //echo "analyzing:".$row['id']."\n";
650          //$mem1=memory_get_usage();
651          //echo "memory before analyze:".$mem1."\n";
652          $returned.=$this->analyzeImageFile($path."/".$row['path'], $row['id'], $colorTable);
653          //echo $returned."\n";
654          //$mem2=memory_get_usage();
655          //echo "memory after analyze:".$mem2." (".($mem2-$mem1).")\n";
656        }
657      }
658    }
659    return($returned);
660  }
661
662
663  /**
664   * make consolidation for the color_table :
665   *  - count number of images using a color
666   *  - count number of pixels of a color
667   */
668  private function ajax_cstat_updateDatabaseConsolidation()
669  {
670    $this->updateDatabaseConsolidation();
671    return("ok");
672  }
673
674
675
676  /**
677   * return a formatted <table> (using the template "cstat_stat_show_iListColors")
678   * of used tag with, for each tag, the number and the percentage of pictures
679   * where the tag was found
680   *
681   * @param String $orderType : order for the list (by color 'color' or by number
682   *                            of pictures 'img' or by number of pixels 'pixels')
683   * @return String
684   */
685  private function ajax_cstat_showStatsGetListColors($orderType)
686  {
687    global $template;
688
689    $this->config['display_stat_orderType'] = $orderType;
690    $this->saveConfig();
691
692    $local_tpl = new Template(CSTAT_PATH."admin/", "");
693    $local_tpl->set_filename('body_page',
694                  dirname($this->getFileLocation()).'/admin/cstat_stat_show_iListColors.tpl');
695
696    $generalStats=CStat_functions::getGeneralStats();
697
698    $sql="SELECT color_id, num_images, num_pixels
699          FROM ".$this->tables['color_table']."
700          WHERE num_images > 0 ";
701    if($orderType=='color')
702    {
703      $sql.=" ORDER BY hue ASC, saturation ASC, value DESC";
704    }
705    elseif($orderType=='img')
706    {
707      $sql.=" ORDER BY num_images DESC, num_pixels DESC ";
708    }
709    elseif($orderType=='pixels')
710    {
711      $sql.=" ORDER BY num_pixels DESC, num_images DESC ";
712    }
713
714    $datas=Array();
715    $result=pwg_query($sql);
716    if($result)
717    {
718      while($row=pwg_db_fetch_assoc($result))
719      {
720        $row['pct_images']=sprintf('%.2f', round(100*$row['num_images']/$generalStats['nbImages'],2));
721        $row['pct_pixels']=sprintf('%.2f', round(100*$row['num_pixels']/$generalStats['pixelsAnalyzedSum'],2));
722        $datas[]=$row;
723      }
724    }
725
726    $local_tpl->assign('themeconf', Array('name' => $template->get_themeconf('name')));
727    $local_tpl->assign('datas', $datas);
728
729    return($local_tpl->parse('body_page', true));
730  }
731
732} //class
733
734
735?>
Note: See TracBrowser for help on using the repository browser.