includes/template.php
changeset 229 97ae8e9d5e29
parent 228 b0a4d179be85
child 231 b11a2f1353c0
equal deleted inserted replaced
147:d8156d18ac58 229:97ae8e9d5e29
    40     $this->toolbar_menu = '';
    40     $this->toolbar_menu = '';
    41     $this->additional_headers = '';
    41     $this->additional_headers = '';
    42     $this->plugin_blocks = Array();
    42     $this->plugin_blocks = Array();
    43     $this->theme_loaded = false;
    43     $this->theme_loaded = false;
    44     
    44     
    45     $this->fading_button = '<div style="background-image: url('.scriptPath.'/images/about-powered-enano-hover.png); background-repeat: no-repeat; width: 88px; height: 31px; margin: 0 auto;">
    45     $this->fading_button = '<div style="background-image: url('.scriptPath.'/images/about-powered-enano-hover.png); background-repeat: no-repeat; width: 88px; height: 31px; margin: 0 auto 5px auto;">
    46                               <a href="http://enanocms.org/" onclick="window.open(this.href); return false;"><img style="border-width: 0;" alt=" " src="'.scriptPath.'/images/about-powered-enano.png" onmouseover="domOpacity(this, 100, 0, 500);" onmouseout="domOpacity(this, 0, 100, 500);" /></a>
    46                               <a href="http://enanocms.org/" onclick="window.open(this.href); return false;"><img style="border-width: 0;" alt=" " src="'.scriptPath.'/images/about-powered-enano.png" onmouseover="domOpacity(this, 100, 0, 500);" onmouseout="domOpacity(this, 0, 100, 500);" /></a>
    47                             </div>';
    47                             </div>';
    48     
    48     
    49     $this->theme_list = Array();
    49     $this->theme_list = Array();
    50     $this->named_theme_list = Array();
    50     $this->named_theme_list = Array();
   133   
   133   
   134   function init_vars()
   134   function init_vars()
   135   {
   135   {
   136     global $db, $session, $paths, $template, $plugins; // Common objects
   136     global $db, $session, $paths, $template, $plugins; // Common objects
   137     global $email;
   137     global $email;
       
   138     global $lang;
   138     
   139     
   139     dc_here("template: initializing all variables");
   140     dc_here("template: initializing all variables");
   140     
   141     
   141     if(!$this->theme || !$this->style)
   142     if(!$this->theme || !$this->style)
   142     {
   143     {
   195     
   196     
   196     // Get the "article" button text (depends on namespace)
   197     // Get the "article" button text (depends on namespace)
   197     switch($paths->namespace) {
   198     switch($paths->namespace) {
   198       case "Article":
   199       case "Article":
   199       default:
   200       default:
   200         $ns = 'article';
   201         $ns = $lang->get('onpage_lbl_page_article');
   201         break;
   202         break;
   202       case "Admin":
   203       case "Admin":
   203         $ns = 'administration page';
   204         $ns = $lang->get('onpage_lbl_page_admin');
   204         break;
   205         break;
   205       case "System":
   206       case "System":
   206         $ns = 'system message';
   207         $ns = $lang->get('onpage_lbl_page_system');
   207         break;
   208         break;
   208       case "File":
   209       case "File":
   209         $ns = 'uploaded file';
   210         $ns = $lang->get('onpage_lbl_page_file');
   210         break;
   211         break;
   211       case "Help":
   212       case "Help":
   212         $ns = 'documentation page';
   213         $ns = $lang->get('onpage_lbl_page_help');
   213         break;
   214         break;
   214       case "User":
   215       case "User":
   215         $ns = 'user page';
   216         $ns = $lang->get('onpage_lbl_page_user');
   216         break;
   217         break;
   217       case "Special":
   218       case "Special":
   218         $ns = 'special page';
   219         $ns = $lang->get('onpage_lbl_page_special');
   219         break;
   220         break;
   220       case "Template":
   221       case "Template":
   221         $ns = 'template';
   222         $ns = $lang->get('onpage_lbl_page_template');
   222         break;
   223         break;
   223       case "Project":
   224       case "Project":
   224         $ns = 'project page';
   225         $ns = $lang->get('onpage_lbl_page_project');
   225         break;
   226         break;
   226       case "Category":
   227       case "Category":
   227         $ns = 'category';
   228         $ns = $lang->get('onpage_lbl_page_category');
   228         break;
   229         break;
   229     }
   230     }
   230     $this->namespace_string = $ns;
   231     $this->namespace_string = $ns;
       
   232     unset($ns);
   231     $code = $plugins->setHook('page_type_string_set');
   233     $code = $plugins->setHook('page_type_string_set');
   232     foreach ( $code as $cmd )
   234     foreach ( $code as $cmd )
   233     {
   235     {
   234       eval($cmd);
   236       eval($cmd);
   235     }
   237     }
   282       
   284       
   283       $db->free_result();
   285       $db->free_result();
   284       $n = ( $session->get_permissions('mod_comments') ) ? (string)$nc : (string)$na;
   286       $n = ( $session->get_permissions('mod_comments') ) ? (string)$nc : (string)$na;
   285       if ( $session->get_permissions('mod_comments') && $nu > 0 )
   287       if ( $session->get_permissions('mod_comments') && $nu > 0 )
   286       {
   288       {
   287         $n .= ' total/'.$nu.' unapp.';
   289         $subst = array(
       
   290             'num_comments' => $nc,
       
   291             'num_unapp' => $nu
       
   292           );
       
   293         $btn_text = $lang->get('onpage_btn_discussion_unapp', $subst);
       
   294       }
       
   295       else
       
   296       {
       
   297         $subst = array(
       
   298           'num_comments' => $nc
       
   299         );
       
   300         $btn_text = $lang->get('onpage_btn_discussion', $subst);
   288       }
   301       }
   289       
   302       
   290       $button->assign_vars(array(
   303       $button->assign_vars(array(
   291           'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { void(ajaxComments()); return false; }" title="View the comments that other users have posted about this page (alt-c)" accesskey="c"',
   304           'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { void(ajaxComments()); return false; }" title="View the comments that other users have posted about this page (alt-c)" accesskey="c"',
   292           'PARENTFLAGS' => 'id="mdgToolbar_discussion"',
   305           'PARENTFLAGS' => 'id="mdgToolbar_discussion"',
   293           'HREF' => makeUrl($paths->page, 'do=comments', true),
   306           'HREF' => makeUrl($paths->page, 'do=comments', true),
   294           'TEXT' => 'discussion ('.$n.')',
   307           'TEXT' => $btn_text,
   295         ));
   308         ));
   296       
   309       
   297       $tb .= $button->run();
   310       $tb .= $button->run();
   298     }
   311     }
   299     // Edit button
   312     // Edit button
   301     {
   314     {
   302       $button->assign_vars(array(
   315       $button->assign_vars(array(
   303         'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { void(ajaxEditor()); return false; }" title="Edit the contents of this page (alt-e)" accesskey="e"',
   316         'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { void(ajaxEditor()); return false; }" title="Edit the contents of this page (alt-e)" accesskey="e"',
   304         'PARENTFLAGS' => 'id="mdgToolbar_edit"',
   317         'PARENTFLAGS' => 'id="mdgToolbar_edit"',
   305         'HREF' => makeUrl($paths->page, 'do=edit', true),
   318         'HREF' => makeUrl($paths->page, 'do=edit', true),
   306         'TEXT' => 'edit this page'
   319         'TEXT' => $lang->get('onpage_btn_edit')
   307         ));
   320         ));
   308       $tb .= $button->run();
   321       $tb .= $button->run();
   309     // View source button
   322     // View source button
   310     }
   323     }
   311     else if($session->get_permissions('view_source') && ( !$session->get_permissions('edit_page') || !$session->get_permissions('even_when_protected') && $paths->page_protected ) && $paths->namespace != 'Special' && $paths->namespace != 'Admin') 
   324     else if($session->get_permissions('view_source') && ( !$session->get_permissions('edit_page') || !$session->get_permissions('even_when_protected') && $paths->page_protected ) && $paths->namespace != 'Special' && $paths->namespace != 'Admin') 
   312     {
   325     {
   313       $button->assign_vars(array(
   326       $button->assign_vars(array(
   314         'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { void(ajaxViewSource()); return false; }" title="View the source code (wiki markup) that this page uses (alt-e)" accesskey="e"',
   327         'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { void(ajaxViewSource()); return false; }" title="View the source code (wiki markup) that this page uses (alt-e)" accesskey="e"',
   315         'PARENTFLAGS' => 'id="mdgToolbar_edit"',
   328         'PARENTFLAGS' => 'id="mdgToolbar_edit"',
   316         'HREF' => makeUrl($paths->page, 'do=viewsource', true),
   329         'HREF' => makeUrl($paths->page, 'do=viewsource', true),
   317         'TEXT' => 'view source'
   330         'TEXT' => $lang->get('onpage_btn_viewsource')
   318         ));
   331         ));
   319       $tb .= $button->run();
   332       $tb .= $button->run();
   320     }
   333     }
   321     // History button
   334     // History button
   322     if ( $session->get_permissions('read') /* && $paths->wiki_mode */ && $paths->page_exists && $paths->namespace != 'Special' && $paths->namespace != 'Admin' && $session->get_permissions('history_view') )
   335     if ( $session->get_permissions('read') /* && $paths->wiki_mode */ && $paths->page_exists && $paths->namespace != 'Special' && $paths->namespace != 'Admin' && $session->get_permissions('history_view') )
   323     {
   336     {
   324       $button->assign_vars(array(
   337       $button->assign_vars(array(
   325         'FLAGS'       => 'onclick="if ( !KILL_SWITCH ) { void(ajaxHistory()); return false; }" title="View a log of actions taken on this page (alt-h)" accesskey="h"',
   338         'FLAGS'       => 'onclick="if ( !KILL_SWITCH ) { void(ajaxHistory()); return false; }" title="View a log of actions taken on this page (alt-h)" accesskey="h"',
   326         'PARENTFLAGS' => 'id="mdgToolbar_history"',
   339         'PARENTFLAGS' => 'id="mdgToolbar_history"',
   327         'HREF'        => makeUrl($paths->page, 'do=history', true),
   340         'HREF'        => makeUrl($paths->page, 'do=history', true),
   328         'TEXT'        => 'history'
   341         'TEXT'        => $lang->get('onpage_btn_history')
   329         ));
   342         ));
   330       $tb .= $button->run();
   343       $tb .= $button->run();
   331     }
   344     }
   332     
   345     
   333     $menubtn = $this->makeParserText($tplvars['toolbar_menu_button']);
   346     $menubtn = $this->makeParserText($tplvars['toolbar_menu_button']);
   337     if ( $session->get_permissions('read') && $paths->page_exists && ( $session->get_permissions('rename') && ( $paths->page_protected && $session->get_permissions('even_when_protected') || !$paths->page_protected ) ) && $paths->namespace != 'Special' && $paths->namespace != 'Admin' )
   350     if ( $session->get_permissions('read') && $paths->page_exists && ( $session->get_permissions('rename') && ( $paths->page_protected && $session->get_permissions('even_when_protected') || !$paths->page_protected ) ) && $paths->namespace != 'Special' && $paths->namespace != 'Admin' )
   338     {
   351     {
   339       $menubtn->assign_vars(array(
   352       $menubtn->assign_vars(array(
   340           'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { void(ajaxRename()); return false; }" title="Change the display name of this page (alt-r)" accesskey="r"',
   353           'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { void(ajaxRename()); return false; }" title="Change the display name of this page (alt-r)" accesskey="r"',
   341           'HREF'  => makeUrl($paths->page, 'do=rename', true),
   354           'HREF'  => makeUrl($paths->page, 'do=rename', true),
   342           'TEXT'  => 'rename',
   355           'TEXT'  => $lang->get('onpage_btn_rename'),
   343         ));
   356         ));
   344       $this->toolbar_menu .= $menubtn->run();
   357       $this->toolbar_menu .= $menubtn->run();
   345     }
   358     }
   346     
   359     
   347     // Vote-to-delete button
   360     // Vote-to-delete button
   348     if ( $paths->wiki_mode && $session->get_permissions('vote_delete') && $paths->page_exists && $paths->namespace != 'Special' && $paths->namespace != 'Admin')
   361     if ( $paths->wiki_mode && $session->get_permissions('vote_delete') && $paths->page_exists && $paths->namespace != 'Special' && $paths->namespace != 'Admin')
   349     {
   362     {
   350       $menubtn->assign_vars(array(
   363       $menubtn->assign_vars(array(
   351           'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { void(ajaxDelVote()); return false; }" title="Vote to have this page deleted (alt-d)" accesskey="d"',
   364           'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { void(ajaxDelVote()); return false; }" title="Vote to have this page deleted (alt-d)" accesskey="d"',
   352           'HREF'  => makeUrl($paths->page, 'do=delvote', true),
   365           'HREF'  => makeUrl($paths->page, 'do=delvote', true),
   353           'TEXT'  => 'vote to delete this page',
   366           'TEXT'  => $lang->get('onpage_btn_votedelete'),
   354         ));
   367         ));
   355       $this->toolbar_menu .= $menubtn->run();
   368       $this->toolbar_menu .= $menubtn->run();
   356     }
   369     }
   357     
   370     
   358     // Clear-votes button
   371     // Clear-votes button
   359     if ( $session->get_permissions('read') && $paths->wiki_mode && $paths->page_exists && $paths->namespace != 'Special' && $paths->namespace != 'Admin' && $session->get_permissions('vote_reset') && $paths->cpage['delvotes'] > 0)
   372     if ( $session->get_permissions('read') && $paths->wiki_mode && $paths->page_exists && $paths->namespace != 'Special' && $paths->namespace != 'Admin' && $session->get_permissions('vote_reset') && $paths->cpage['delvotes'] > 0)
   360     {
   373     {
   361       $menubtn->assign_vars(array(
   374       $menubtn->assign_vars(array(
   362           'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { void(ajaxResetDelVotes()); return false; }" title="Vote to have this page deleted (alt-y)" accesskey="y"',
   375           'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { void(ajaxResetDelVotes()); return false; }" title="Vote to have this page deleted (alt-y)" accesskey="y"',
   363           'HREF'  => makeUrl($paths->page, 'do=resetvotes', true),
   376           'HREF'  => makeUrl($paths->page, 'do=resetvotes', true),
   364           'TEXT'  => 'reset deletion votes',
   377           'TEXT'  => $lang->get('onpage_btn_votedelete_reset'),
   365         ));
   378         ));
   366       $this->toolbar_menu .= $menubtn->run();
   379       $this->toolbar_menu .= $menubtn->run();
   367     }
   380     }
   368     
   381     
   369     // Printable page button
   382     // Printable page button
   370     if ( $paths->page_exists && $paths->namespace != 'Special' && $paths->namespace != 'Admin' )
   383     if ( $paths->page_exists && $paths->namespace != 'Special' && $paths->namespace != 'Admin' )
   371     {
   384     {
   372       $menubtn->assign_vars(array(
   385       $menubtn->assign_vars(array(
   373           'FLAGS' => 'title="View a version of this page that is suitable for printing"',
   386           'FLAGS' => 'title="View a version of this page that is suitable for printing"',
   374           'HREF'  => makeUrl($paths->page, 'printable=yes', true),
   387           'HREF'  => makeUrl($paths->page, 'printable=yes', true),
   375           'TEXT'  => 'view printable version',
   388           'TEXT'  => $lang->get('onpage_btn_printable'),
   376         ));
   389         ));
   377       $this->toolbar_menu .= $menubtn->run();
   390       $this->toolbar_menu .= $menubtn->run();
   378     }
   391     }
   379     
   392     
   380     // Protect button
   393     // Protect button
   381     if($session->get_permissions('read') && $paths->wiki_mode && $paths->page_exists && $paths->namespace != 'Special' && $paths->namespace != 'Admin' && $session->get_permissions('protect'))
   394     if($session->get_permissions('read') && $paths->wiki_mode && $paths->page_exists && $paths->namespace != 'Special' && $paths->namespace != 'Admin' && $session->get_permissions('protect'))
   382     {
   395     {
   383       
   396       
   384       $label = $this->makeParserText($tplvars['toolbar_label']);
   397       $label = $this->makeParserText($tplvars['toolbar_label']);
   385       $label->assign_vars(array('TEXT' => 'protection:'));
   398       $label->assign_vars(array('TEXT' => $lang->get('onpage_lbl_protect')));
   386       $t0 = $label->run();
   399       $t0 = $label->run();
   387       
   400       
   388       $ctmp = ''; 
   401       $ctmp = ''; 
   389       if ( $paths->cpage['protected'] == 1 )
   402       if ( $paths->cpage['protected'] == 1 )
   390       {
   403       {
   391         $ctmp=' style="text-decoration: underline;"';
   404         $ctmp=' style="text-decoration: underline;"';
   392       }
   405       }
   393       $menubtn->assign_vars(array(
   406       $menubtn->assign_vars(array(
   394           'FLAGS' => 'accesskey="i" onclick="if ( !KILL_SWITCH ) { ajaxProtect(1); return false; }" id="protbtn_1" title="Prevents all non-administrators from editing this page. [alt-i]"'.$ctmp,
   407           'FLAGS' => 'accesskey="i" onclick="if ( !KILL_SWITCH ) { ajaxProtect(1); return false; }" id="protbtn_1" title="Prevents all non-administrators from editing this page. [alt-i]"'.$ctmp,
   395           'HREF'  => makeUrl($paths->page, 'do=protect&level=1', true),
   408           'HREF'  => makeUrl($paths->page, 'do=protect&level=1', true),
   396           'TEXT'  => 'on'
   409           'TEXT'  => $lang->get('onpage_btn_protect_on')
   397         ));
   410         ));
   398       $t1 = $menubtn->run();
   411       $t1 = $menubtn->run();
   399       
   412       
   400       $ctmp = '';
   413       $ctmp = '';
   401       if ( $paths->cpage['protected'] == 0 )
   414       if ( $paths->cpage['protected'] == 0 )
   403         $ctmp=' style="text-decoration: underline;"';
   416         $ctmp=' style="text-decoration: underline;"';
   404       }
   417       }
   405       $menubtn->assign_vars(array(
   418       $menubtn->assign_vars(array(
   406           'FLAGS' => 'accesskey="o" onclick="if ( !KILL_SWITCH ) { ajaxProtect(0); return false; }" id="protbtn_0" title="Allows everyone to edit this page. [alt-o]"'.$ctmp,
   419           'FLAGS' => 'accesskey="o" onclick="if ( !KILL_SWITCH ) { ajaxProtect(0); return false; }" id="protbtn_0" title="Allows everyone to edit this page. [alt-o]"'.$ctmp,
   407           'HREF'  => makeUrl($paths->page, 'do=protect&level=0', true),
   420           'HREF'  => makeUrl($paths->page, 'do=protect&level=0', true),
   408           'TEXT'  => 'off'
   421           'TEXT'  => $lang->get('onpage_btn_protect_off')
   409         ));
   422         ));
   410       $t2 = $menubtn->run();
   423       $t2 = $menubtn->run();
   411       
   424       
   412       $ctmp = '';
   425       $ctmp = '';
   413       if ( $paths->cpage['protected'] == 2 )
   426       if ( $paths->cpage['protected'] == 2 )
   415         $ctmp = ' style="text-decoration: underline;"';
   428         $ctmp = ' style="text-decoration: underline;"';
   416       }
   429       }
   417       $menubtn->assign_vars(array(
   430       $menubtn->assign_vars(array(
   418           'FLAGS' => 'accesskey="p" onclick="if ( !KILL_SWITCH ) { ajaxProtect(2); return false; }" id="protbtn_2" title="Allows only users who have been registered for 4 days to edit this page. [alt-p]"'.$ctmp,
   431           'FLAGS' => 'accesskey="p" onclick="if ( !KILL_SWITCH ) { ajaxProtect(2); return false; }" id="protbtn_2" title="Allows only users who have been registered for 4 days to edit this page. [alt-p]"'.$ctmp,
   419           'HREF'  => makeUrl($paths->page, 'do=protect&level=2', true),
   432           'HREF'  => makeUrl($paths->page, 'do=protect&level=2', true),
   420           'TEXT'  => 'semi'
   433           'TEXT'  => $lang->get('onpage_btn_protect_semi')
   421         ));
   434         ));
   422       $t3 = $menubtn->run();
   435       $t3 = $menubtn->run();
   423       
   436       
   424       $this->toolbar_menu .= '        <table border="0" cellspacing="0" cellpadding="0">
   437       $this->toolbar_menu .= '        <table border="0" cellspacing="0" cellpadding="0">
   425           <tr>
   438           <tr>
   434     // Wiki mode button
   447     // Wiki mode button
   435     if($session->get_permissions('read') && $paths->page_exists && $session->get_permissions('set_wiki_mode') && $paths->namespace != 'Special' && $paths->namespace != 'Admin')
   448     if($session->get_permissions('read') && $paths->page_exists && $session->get_permissions('set_wiki_mode') && $paths->namespace != 'Special' && $paths->namespace != 'Admin')
   436     {
   449     {
   437       // label at start
   450       // label at start
   438       $label = $this->makeParserText($tplvars['toolbar_label']);
   451       $label = $this->makeParserText($tplvars['toolbar_label']);
   439       $label->assign_vars(array('TEXT' => 'page wiki mode:'));
   452       $label->assign_vars(array('TEXT' => $lang->get('onpage_lbl_wikimode')));
   440       $t0 = $label->run();
   453       $t0 = $label->run();
   441       
   454       
   442       // on button
   455       // on button
   443       $ctmp = '';
   456       $ctmp = '';
   444       if ( $paths->cpage['wiki_mode'] == 1 )
   457       if ( $paths->cpage['wiki_mode'] == 1 )
   446         $ctmp = ' style="text-decoration: underline;"';
   459         $ctmp = ' style="text-decoration: underline;"';
   447       }
   460       }
   448       $menubtn->assign_vars(array(
   461       $menubtn->assign_vars(array(
   449           'FLAGS' => /* 'onclick="if ( !KILL_SWITCH ) { ajaxSetWikiMode(1); return false; }" id="wikibtn_1" title="Forces wiki functions to be allowed on this page."'. */ $ctmp,
   462           'FLAGS' => /* 'onclick="if ( !KILL_SWITCH ) { ajaxSetWikiMode(1); return false; }" id="wikibtn_1" title="Forces wiki functions to be allowed on this page."'. */ $ctmp,
   450           'HREF' => makeUrl($paths->page, 'do=setwikimode&level=1', true),
   463           'HREF' => makeUrl($paths->page, 'do=setwikimode&level=1', true),
   451           'TEXT' => 'on'
   464           'TEXT' => $lang->get('onpage_btn_wikimode_on')
   452         ));
   465         ));
   453       $t1 = $menubtn->run();
   466       $t1 = $menubtn->run();
   454       
   467       
   455       // off button
   468       // off button
   456       $ctmp = '';
   469       $ctmp = '';
   459         $ctmp=' style="text-decoration: underline;"';
   472         $ctmp=' style="text-decoration: underline;"';
   460       }
   473       }
   461       $menubtn->assign_vars(array(
   474       $menubtn->assign_vars(array(
   462           'FLAGS' => /* 'onclick="if ( !KILL_SWITCH ) { ajaxSetWikiMode(0); return false; }" id="wikibtn_0" title="Forces wiki functions to be disabled on this page."'. */ $ctmp,
   475           'FLAGS' => /* 'onclick="if ( !KILL_SWITCH ) { ajaxSetWikiMode(0); return false; }" id="wikibtn_0" title="Forces wiki functions to be disabled on this page."'. */ $ctmp,
   463           'HREF' => makeUrl($paths->page, 'do=setwikimode&level=0', true),
   476           'HREF' => makeUrl($paths->page, 'do=setwikimode&level=0', true),
   464           'TEXT' => 'off'
   477           'TEXT' => $lang->get('onpage_btn_wikimode_off')
   465         ));
   478         ));
   466       $t2 = $menubtn->run();
   479       $t2 = $menubtn->run();
   467       
   480       
   468       // global button
   481       // global button
   469       $ctmp = ''; 
   482       $ctmp = ''; 
   472         $ctmp=' style="text-decoration: underline;"';
   485         $ctmp=' style="text-decoration: underline;"';
   473       }
   486       }
   474       $menubtn->assign_vars(array(
   487       $menubtn->assign_vars(array(
   475           'FLAGS' => /* 'onclick="if ( !KILL_SWITCH ) { ajaxSetWikiMode(2); return false; }" id="wikibtn_2" title="Causes this page to use the global wiki mode setting (default)"'. */ $ctmp,
   488           'FLAGS' => /* 'onclick="if ( !KILL_SWITCH ) { ajaxSetWikiMode(2); return false; }" id="wikibtn_2" title="Causes this page to use the global wiki mode setting (default)"'. */ $ctmp,
   476           'HREF' => makeUrl($paths->page, 'do=setwikimode&level=2', true),
   489           'HREF' => makeUrl($paths->page, 'do=setwikimode&level=2', true),
   477           'TEXT' => 'global'
   490           'TEXT' => $lang->get('onpage_btn_wikimode_global')
   478         ));
   491         ));
   479       $t3 = $menubtn->run();
   492       $t3 = $menubtn->run();
   480       
   493       
   481       // Tack it onto the list of buttons that are already there...
   494       // Tack it onto the list of buttons that are already there...
   482       $this->toolbar_menu .= '        <table border="0" cellspacing="0" cellpadding="0">
   495       $this->toolbar_menu .= '        <table border="0" cellspacing="0" cellpadding="0">
   493     if ( $session->get_permissions('read') && $session->get_permissions('clear_logs') && $paths->namespace != 'Special' && $paths->namespace != 'Admin' )
   506     if ( $session->get_permissions('read') && $session->get_permissions('clear_logs') && $paths->namespace != 'Special' && $paths->namespace != 'Admin' )
   494     {
   507     {
   495       $menubtn->assign_vars(array(
   508       $menubtn->assign_vars(array(
   496           'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { void(ajaxClearLogs()); return false; }" title="Remove all edit and action logs for this page from the database. IRREVERSIBLE! (alt-l)" accesskey="l"',
   509           'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { void(ajaxClearLogs()); return false; }" title="Remove all edit and action logs for this page from the database. IRREVERSIBLE! (alt-l)" accesskey="l"',
   497           'HREF'  => makeUrl($paths->page, 'do=flushlogs', true),
   510           'HREF'  => makeUrl($paths->page, 'do=flushlogs', true),
   498           'TEXT'  => 'clear page logs',
   511           'TEXT'  => $lang->get('onpage_btn_clearlogs'),
   499         ));
   512         ));
   500       $this->toolbar_menu .= $menubtn->run();
   513       $this->toolbar_menu .= $menubtn->run();
   501     }
   514     }
   502     
   515     
   503     // Delete page button
   516     // Delete page button
   504     if ( $session->get_permissions('read') && $session->get_permissions('delete_page') && $paths->page_exists && $paths->namespace != 'Special' && $paths->namespace != 'Admin' )
   517     if ( $session->get_permissions('read') && $session->get_permissions('delete_page') && $paths->page_exists && $paths->namespace != 'Special' && $paths->namespace != 'Admin' )
   505     {
   518     {
   506       $s = 'delete this page';
   519       $s = $lang->get('onpage_btn_deletepage');
   507       if ( $paths->cpage['delvotes'] == 1 )
   520       if ( $paths->cpage['delvotes'] == 1 )
   508       {
   521       {
   509         $s .= ' (<b>'.$paths->cpage['delvotes'].'</b> vote)';
   522         $subst = array(
       
   523           'num_votes' => $paths->cpage['delvotes'],
       
   524           'plural' => ''
       
   525           );
       
   526         $s .= $lang->get('onpage_btn_deletepage_votes', $subst);
   510       }
   527       }
   511       else if ( $paths->cpage['delvotes'] > 1 )
   528       else if ( $paths->cpage['delvotes'] > 1 )
   512       {
   529       {
   513         $s .= ' (<b>'.$paths->cpage['delvotes'].'</b> votes)';
   530         $subst = array(
       
   531           'num_votes' => $paths->cpage['delvotes'],
       
   532           'plural' => $lang->get('meta_plural')
       
   533           );
       
   534         $s .= $lang->get('onpage_btn_deletepage_votes', $subst);
   514       }
   535       }
   515       
   536       
   516       $menubtn->assign_vars(array(
   537       $menubtn->assign_vars(array(
   517           'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { void(ajaxDeletePage()); return false; }" title="Delete this page. This is always reversible unless the logs are cleared. (alt-k)" accesskey="k"',
   538           'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { void(ajaxDeletePage()); return false; }" title="Delete this page. This is always reversible unless the logs are cleared. (alt-k)" accesskey="k"',
   518           'HREF'  => makeUrl($paths->page, 'do=deletepage', true),
   539           'HREF'  => makeUrl($paths->page, 'do=deletepage', true),
   540     }
   561     }
   541     if ( $a && $session->get_permissions('read') && $paths->page_exists && $paths->namespace != 'Special' && $paths->namespace != 'Admin' )
   562     if ( $a && $session->get_permissions('read') && $paths->page_exists && $paths->namespace != 'Special' && $paths->namespace != 'Admin' )
   542     {
   563     {
   543       // label at start
   564       // label at start
   544       $label = $this->makeParserText($tplvars['toolbar_label']);
   565       $label = $this->makeParserText($tplvars['toolbar_label']);
   545       $label->assign_vars(array('TEXT' => 'page password:'));
   566       $label->assign_vars(array('TEXT' => $lang->get('onpage_lbl_password')));
   546       $t0 = $label->run();
   567       $t0 = $label->run();
   547       
   568       
   548       $menubtn->assign_vars(array(
   569       $menubtn->assign_vars(array(
   549           'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { void(ajaxSetPassword()); return false; }" title="Require a password in order for this page to be viewed"',
   570           'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { void(ajaxSetPassword()); return false; }" title="Require a password in order for this page to be viewed"',
   550           'HREF'  => '#',
   571           'HREF'  => '#',
   551           'TEXT'  => 'set',
   572           'TEXT'  => $lang->get('onpage_btn_password_set'),
   552         ));
   573         ));
   553       $t = $menubtn->run();
   574       $t = $menubtn->run();
   554       
   575       
   555       $this->toolbar_menu .= '<table border="0" cellspacing="0" cellpadding="0"><tr><td>'.$t0.'</td><td><input type="password" id="mdgPassSetField" size="10" /></td><td>'.$t.'</td></tr></table>';
   576       $this->toolbar_menu .= '<table border="0" cellspacing="0" cellpadding="0"><tr><td>'.$t0.'</td><td><input type="password" id="mdgPassSetField" size="10" /></td><td>'.$t.'</td></tr></table>';
   556     }
   577     }
   559     if($session->get_permissions('edit_acl') || $session->user_level >= USER_LEVEL_ADMIN)
   580     if($session->get_permissions('edit_acl') || $session->user_level >= USER_LEVEL_ADMIN)
   560     {
   581     {
   561       $menubtn->assign_vars(array(
   582       $menubtn->assign_vars(array(
   562           'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { return ajaxOpenACLManager(); }" title="Manage who can do what with this page (alt-m)" accesskey="m"',
   583           'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { return ajaxOpenACLManager(); }" title="Manage who can do what with this page (alt-m)" accesskey="m"',
   563           'HREF'  => makeUrl($paths->page, 'do=aclmanager', true),
   584           'HREF'  => makeUrl($paths->page, 'do=aclmanager', true),
   564           'TEXT'  => 'manage page access',
   585           'TEXT'  => $lang->get('onpage_btn_acl'),
   565         ));
   586         ));
   566       $this->toolbar_menu .= $menubtn->run();
   587       $this->toolbar_menu .= $menubtn->run();
   567     }
   588     }
   568     
   589     
   569     // Administer page button
   590     // Administer page button
   570     if ( $session->user_level >= USER_LEVEL_ADMIN && $paths->page_exists && $paths->namespace != 'Special' && $paths->namespace != 'Admin' )
   591     if ( $session->user_level >= USER_LEVEL_ADMIN && $paths->page_exists && $paths->namespace != 'Special' && $paths->namespace != 'Admin' )
   571     {
   592     {
   572       $menubtn->assign_vars(array(
   593       $menubtn->assign_vars(array(
   573           'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { void(ajaxAdminPage()); return false; }" title="Administrative options for this page" accesskey="g"',
   594           'FLAGS' => 'onclick="if ( !KILL_SWITCH ) { void(ajaxAdminPage()); return false; }" title="Administrative options for this page" accesskey="g"',
   574           'HREF'  => makeUrlNS('Special', 'Administration', 'module='.$paths->nslist['Admin'].'PageManager', true),
   595           'HREF'  => makeUrlNS('Special', 'Administration', 'module='.$paths->nslist['Admin'].'PageManager', true),
   575           'TEXT'  => 'administrative options',
   596           'TEXT'  => $lang->get('onpage_btn_admin'),
   576         ));
   597         ));
   577       $this->toolbar_menu .= $menubtn->run();
   598       $this->toolbar_menu .= $menubtn->run();
   578     }
   599     }
   579     
   600     
   580     if ( strlen($this->toolbar_menu) > 0 )
   601     if ( strlen($this->toolbar_menu) > 0 )
   581     {
   602     {
   582       $button->assign_vars(array(
   603       $button->assign_vars(array(
   583         'FLAGS'       => 'id="mdgToolbar_moreoptions" onclick="if ( !KILL_SWITCH ) { return false; }" title="Additional options for working with this page"',
   604         'FLAGS'       => 'id="mdgToolbar_moreoptions" onclick="if ( !KILL_SWITCH ) { return false; }" title="Additional options for working with this page"',
   584         'PARENTFLAGS' => '',
   605         'PARENTFLAGS' => '',
   585         'HREF'        => makeUrl($paths->page, 'do=moreoptions', true),
   606         'HREF'        => makeUrl($paths->page, 'do=moreoptions', true),
   586         'TEXT'        => 'more options'
   607         'TEXT'        => $lang->get('onpage_btn_moreoptions')
   587         ));
   608         ));
   588       $tb .= $button->run();
   609       $tb .= $button->run();
   589     }
   610     }
   590     
   611     
   591     $is_opera = (isset($_SERVER['HTTP_USER_AGENT']) && strstr($_SERVER['HTTP_USER_AGENT'], 'Opera')) ? true : false;
   612     $is_opera = (isset($_SERVER['HTTP_USER_AGENT']) && strstr($_SERVER['HTTP_USER_AGENT'], 'Opera')) ? true : false;
   623     
   644     
   624     $this->tpl_bool['enable_uploads'] = ( getConfig('enable_uploads') == '1' && $session->get_permissions('upload_files') ) ? true : false;
   645     $this->tpl_bool['enable_uploads'] = ( getConfig('enable_uploads') == '1' && $session->get_permissions('upload_files') ) ? true : false;
   625     
   646     
   626     $this->tpl_bool['stupid_mode'] = false;
   647     $this->tpl_bool['stupid_mode'] = false;
   627     
   648     
   628     if($paths->page == $paths->nslist['Special'].'Administration') $this->tpl_bool['in_admin'] = true;
   649     $this->tpl_bool['in_admin'] = ( ( $paths->cpage['urlname_nons'] == 'Administration' && $paths->namespace == 'Special' ) || $paths->namespace == 'Admin' );
   629     else $this->tpl_bool['in_admin'] = false;
       
   630     
   650     
   631     $p = ( isset($_GET['printable']) ) ? '/printable' : '';
   651     $p = ( isset($_GET['printable']) ) ? '/printable' : '';
   632     
   652     
   633     // Add the e-mail address client code to the header
   653     // Add the e-mail address client code to the header
   634     $this->add_header($email->jscode());
   654     $this->add_header($email->jscode());
       
   655     
       
   656     // Add language file
       
   657     $lang_uri = makeUrlNS('Special', 'LangExportJSON/' . $lang->lang_id, false, true);
       
   658     $this->add_header("<script type=\"text/javascript\" src=\"$lang_uri\"></script>");
   635     
   659     
   636     // Generate the code for the Log out and Change theme sidebar buttons
   660     // Generate the code for the Log out and Change theme sidebar buttons
   637     // Once again, the new template parsing system can be used here
   661     // Once again, the new template parsing system can be used here
   638     
   662     
   639     $parser = $this->makeParserText($tplvars['sidebar_button']);
   663     $parser = $this->makeParserText($tplvars['sidebar_button']);
   640     
   664     
   641     $parser->assign_vars(Array(
   665     $parser->assign_vars(Array(
   642         'HREF'=>makeUrlNS('Special', 'Logout'),
   666         'HREF'=>makeUrlNS('Special', 'Logout'),
   643         'FLAGS'=>'onclick="if ( !KILL_SWITCH ) { mb_logout(); return false; }"',
   667         'FLAGS'=>'onclick="if ( !KILL_SWITCH ) { mb_logout(); return false; }"',
   644         'TEXT'=>'Log out',
   668         'TEXT'=>$lang->get('sidebar_btn_logout'),
   645       ));
   669       ));
   646     
   670     
   647     $logout_link = $parser->run();
   671     $logout_link = $parser->run();
   648     
   672     
   649     $parser->assign_vars(Array(
   673     $parser->assign_vars(Array(
   650         'HREF'=>makeUrlNS('Special', 'Login/' . $paths->page),
   674         'HREF'=>makeUrlNS('Special', 'Login/' . $paths->page),
   651         'FLAGS'=>'onclick="if ( !KILL_SWITCH ) { ajaxStartLogin(); return false; }"',
   675         'FLAGS'=>'onclick="if ( !KILL_SWITCH ) { ajaxStartLogin(); return false; }"',
   652         'TEXT'=>'Log in',
   676         'TEXT'=>$lang->get('sidebar_btn_login'),
   653       ));
   677       ));
   654     
   678     
   655     $login_link = $parser->run();
   679     $login_link = $parser->run();
   656     
   680     
   657     $parser->assign_vars(Array(
   681     $parser->assign_vars(Array(
   658         'HREF'=>makeUrlNS('Special', 'ChangeStyle/'.$paths->page),
   682         'HREF'=>makeUrlNS('Special', 'ChangeStyle/'.$paths->page),
   659         'FLAGS'=>'onclick="if ( !KILL_SWITCH ) { ajaxChangeStyle(); return false; }"',
   683         'FLAGS'=>'onclick="if ( !KILL_SWITCH ) { ajaxChangeStyle(); return false; }"',
   660         'TEXT'=>'Change theme',
   684         'TEXT'=>$lang->get('sidebar_btn_changestyle'),
   661       ));
   685       ));
   662     
   686     
   663     $theme_link = $parser->run();
   687     $theme_link = $parser->run();
   664     
   688     
   665     $parser->assign_vars(Array(
   689     $parser->assign_vars(Array(
   666         'HREF'=>makeUrlNS('Special', 'Administration'),
   690         'HREF'=>makeUrlNS('Special', 'Administration'),
   667         'FLAGS'=>'onclick="if ( !KILL_SWITCH ) { void(ajaxStartAdminLogin()); return false; }"',
   691         'FLAGS'=>'onclick="if ( !KILL_SWITCH ) { void(ajaxStartAdminLogin()); return false; }"',
   668         'TEXT'=>'Administration',
   692         'TEXT'=>$lang->get('sidebar_btn_administration'),
   669       ));
   693       ));
   670     
   694     
   671     $admin_link = $parser->run();
   695     $admin_link = $parser->run();
   672     
   696     
   673     $SID = ($session->sid_super) ? $session->sid_super : '';
   697     $SID = ($session->sid_super) ? $session->sid_super : '';
   709               // if($t['theme_id'] == $session->theme) $js_dynamic .= ' selected="selected"';
   733               // if($t['theme_id'] == $session->theme) $js_dynamic .= ' selected="selected"';
   710               $js_dynamic .= '>'.$t['theme_name'].'</option>';
   734               $js_dynamic .= '>'.$t['theme_name'].'</option>';
   711             }
   735             }
   712           }
   736           }
   713       $js_dynamic .= '\';
   737       $js_dynamic .= '\';
   714       var ENANO_CURRENT_THEME = \''. $session->theme .'\';';
   738       var ENANO_CURRENT_THEME = \''. $session->theme .'\';
       
   739       var ENANO_LANG_ID = ' . $lang->lang_id . ';
       
   740       var ENANO_PAGE_TYPE = "' . addslashes($this->namespace_string) . '";';
   715       foreach($paths->nslist as $k => $c)
   741       foreach($paths->nslist as $k => $c)
   716       {
   742       {
   717         $js_dynamic .= "namespace_list['{$k}'] = '$c';";
   743         $js_dynamic .= "namespace_list['{$k}'] = '$c';";
   718       }
   744       }
   719       $js_dynamic .= "\n    //]]>\n    </script>";
   745       $js_dynamic .= "\n    //]]>\n    </script>";
   771   }
   797   }
   772   
   798   
   773   function header($simple = false) 
   799   function header($simple = false) 
   774   {
   800   {
   775     global $db, $session, $paths, $template, $plugins; // Common objects
   801     global $db, $session, $paths, $template, $plugins; // Common objects
       
   802     global $lang;
       
   803     
   776     ob_start();
   804     ob_start();
   777     
   805     
   778     if(!$this->theme_loaded)
   806     if(!$this->theme_loaded)
   779     {
   807     {
   780       $this->load_theme($session->theme, $session->style);
   808       $this->load_theme($session->theme, $session->style);
   782     
   810     
   783     $headers_sent = true;
   811     $headers_sent = true;
   784     dc_here('template: generating and sending the page header');
   812     dc_here('template: generating and sending the page header');
   785     if(!defined('ENANO_HEADERS_SENT'))
   813     if(!defined('ENANO_HEADERS_SENT'))
   786       define('ENANO_HEADERS_SENT', '');
   814       define('ENANO_HEADERS_SENT', '');
   787     if(!$this->no_headers) echo ( $simple ) ? $this->process_template('simple-header.tpl') : $this->process_template('header.tpl');
   815     if ( !$this->no_headers )
       
   816     {
       
   817       $header = ( $simple ) ?
       
   818         $this->process_template('simple-header.tpl') :
       
   819         $this->process_template('header.tpl');
       
   820       echo $header;
       
   821     }
   788     if ( !$simple && $session->user_logged_in && $session->unread_pms > 0 )
   822     if ( !$simple && $session->user_logged_in && $session->unread_pms > 0 )
   789     {
   823     {
   790       echo $this->notify_unread_pms();
   824       echo $this->notify_unread_pms();
   791     }
   825     }
   792     if ( !$simple && $session->sw_timed_out )
   826     if ( !$simple && $session->sw_timed_out )
   793     {
   827     {
   794       $login_link = makeUrlNS('Special', 'Login/' . $paths->fullpage, 'level=' . $session->user_level, true);
   828       $login_link = makeUrlNS('Special', 'Login/' . $paths->fullpage, 'level=' . $session->user_level, true);
   795       echo '<div class="usermessage">';
   829       echo '<div class="usermessage">';
   796       echo '<b>Your administrative session has timed out.</b> <a href="' . $login_link . '">Log in again</a>';
   830       echo $lang->get('user_msg_elev_timed_out', array( 'login_link' => $login_link ));
   797       echo '</div>';
   831       echo '</div>';
   798     }
   832     }
   799     if ( $this->site_disabled && $session->user_level >= USER_LEVEL_ADMIN && ( $paths->page != $paths->nslist['Special'] . 'Administration' ) )
   833     if ( $this->site_disabled && $session->user_level >= USER_LEVEL_ADMIN && ( $paths->page != $paths->nslist['Special'] . 'Administration' ) )
   800     {
   834     {
   801       $admin_link = makeUrlNS('Special', 'Administration', 'module=' . $paths->nslist['Admin'] . 'GeneralConfig', true);
   835       $admin_link = makeUrlNS('Special', 'Administration', 'module=' . $paths->nslist['Admin'] . 'GeneralConfig', true);
   869       return $t;
   903       return $t;
   870     }
   904     }
   871     else return '';
   905     else return '';
   872   }
   906   }
   873   
   907   
   874   function process_template($file) {
   908   /**
       
   909    * Compiles and executes a template based on the current variables and booleans. Loads
       
   910    * the theme and initializes variables if needed. This mostly just calls child functions.
       
   911    * @param string File to process
       
   912    * @return string
       
   913    */
       
   914   
       
   915   function process_template($file)
       
   916   {
   875     global $db, $session, $paths, $template, $plugins; // Common objects
   917     global $db, $session, $paths, $template, $plugins; // Common objects
   876     if(!defined('ENANO_TEMPLATE_LOADED'))
   918     if(!defined('ENANO_TEMPLATE_LOADED'))
   877     {
   919     {
   878       $this->load_theme();
   920       $this->load_theme();
   879       $this->init_vars();
   921       $this->init_vars();
   880     }
   922     }
   881     eval($this->compile_template($file));
   923     
   882     return $tpl_code;
   924     $compiled = $this->compile_template($file);
   883   }
   925     return eval($compiled);
   884   
   926   }
   885   function extract_vars($file) {
   927   
   886     global $db, $session, $paths, $template, $plugins; // Common objects
   928   /**
   887     if(!$this->theme)
   929    * Loads variables from the specified template file. Returns an associative array containing the variables.
       
   930    * @param string Template file to process (elements.tpl)
       
   931    * @return array
       
   932    */
       
   933   
       
   934   function extract_vars($file)
       
   935   {
       
   936     global $db, $session, $paths, $template, $plugins; // Common objects
       
   937     
       
   938     // Sometimes this function gets called before the theme is loaded
       
   939     // This is a bad coding practice so this function will always be picky.
       
   940     if ( !$this->theme )
   888     {
   941     {
   889       die('$template->extract_vars(): theme not yet loaded, so we can\'t open template files yet...this is a bug and should be reported.<br /><br />Backtrace, most recent call first:<pre>'.enano_debug_print_backtrace(true).'</pre>');
   942       die('$template->extract_vars(): theme not yet loaded, so we can\'t open template files yet...this is a bug and should be reported.<br /><br />Backtrace, most recent call first:<pre>'.enano_debug_print_backtrace(true).'</pre>');
   890     }
   943     }
   891     if(!is_file(ENANO_ROOT . '/themes/'.$this->theme.'/'.$file)) die('Cannot find '.$file.' file for style "'.$this->theme.'", exiting');
   944     
   892     $text = file_get_contents(ENANO_ROOT . '/themes/'.$this->theme.'/'.$file);
   945     // Full pathname of template file
       
   946     $tpl_file_fullpath = ENANO_ROOT . '/themes/' . $this->theme . '/' . $file;
       
   947     
       
   948     // Make sure the template even exists
       
   949     if ( !is_file($tpl_file_fullpath) )
       
   950     {
       
   951       die_semicritical('Cannot find template file',
       
   952                        '<p>The template parser was asked to load the file "' . htmlspecialchars($filename) . '", but that file couldn\'t be found in the directory for
       
   953                            the current theme.</p>
       
   954                         <p>Additional debugging information:<br />
       
   955                            <b>Theme currently in use: </b>' . $this->theme . '<br />
       
   956                            <b>Requested file: </b>' . $file . '
       
   957                            </p>');
       
   958     }
       
   959     // Retrieve file contents
       
   960     $text = file_get_contents($tpl_file_fullpath);
       
   961     if ( !$text )
       
   962     {
       
   963       return false;
       
   964     }
       
   965     
       
   966     // Get variables, regular expressions FTW
   893     preg_match_all('#<\!-- VAR ([A-z0-9_-]*) -->(.*?)<\!-- ENDVAR \\1 -->#is', $text, $matches);
   967     preg_match_all('#<\!-- VAR ([A-z0-9_-]*) -->(.*?)<\!-- ENDVAR \\1 -->#is', $text, $matches);
       
   968     
       
   969     // Initialize return values
   894     $tplvars = Array();
   970     $tplvars = Array();
   895     for($i=0;$i<sizeof($matches[1]);$i++)
   971     
   896     {
   972     // Loop through each match, setting $tplvars[ $first_subpattern ] to $second_subpattern
   897       $tplvars[$matches[1][$i]] = $matches[2][$i];
   973     for ( $i = 0; $i < sizeof($matches[1]); $i++ )
   898     }
   974     {
       
   975       $tplvars[ $matches[1][$i] ] = $matches[2][$i];
       
   976     }
       
   977     
       
   978     // All done!
   899     return $tplvars;
   979     return $tplvars;
   900   }
   980   }
   901   function compile_template($text) {
   981   
   902     global $db, $session, $paths, $template, $plugins; // Common objects
   982   /**
   903     if(!is_file(ENANO_ROOT . '/themes/'.$this->theme.'/'.$text)) die('Cannot find '.$text.' file for style, exiting');
   983    * Compiles a block of template code.
   904     $n = $text;
   984    * @param string The text to process
   905     $tpl_filename = ENANO_ROOT . '/cache/' . $this->theme . '-' . str_replace('/', '-', $n) . '.php';
   985    * @return string
   906     if(!is_file(ENANO_ROOT . '/themes/'.$this->theme.'/'.$text)) die('Cannot find '.$text.' file for style, exiting');
   986    */
   907     if(file_exists($tpl_filename) && getConfig('cache_thumbs')=='1')
   987   
   908     {
   988   function compile_tpl_code($text)
   909       include($tpl_filename);
   989   {
   910       $text = file_get_contents(ENANO_ROOT . '/themes/'.$this->theme.'/'.$text);
   990     global $db, $session, $paths, $template, $plugins; // Common objects
   911       if(isset($md5) && $md5 == md5($text)) {
   991     // A random seed used to salt tags
   912         return str_replace('\\"', '"', $tpl_text);
   992     $seed = md5 ( microtime() . mt_rand() );
   913       }
   993     
   914     }
   994     // Strip out PHP sections
   915     $text = file_get_contents(ENANO_ROOT . '/themes/'.$this->theme.'/'.$n);
   995     preg_match_all('/<\?php(.+?)\?>/is', $text, $php_matches);
   916     
   996     
       
   997     foreach ( $php_matches[0] as $i => $match )
       
   998     {
       
   999       // Substitute the PHP section with a random tag
       
  1000       $tag = "{PHP:$i:$seed}";
       
  1001       $text = str_replace_once($match, $tag, $text);
       
  1002     }
       
  1003     
       
  1004     // Escape slashes and single quotes in template code
       
  1005     $text = str_replace('\\', '\\\\', $text);
       
  1006     $text = str_replace('\'', '\\\'', $text);
       
  1007     
       
  1008     // Initialize the PHP compiled code
       
  1009     $text = 'ob_start(); echo \''.$text.'\'; $tpl_code = ob_get_contents(); ob_end_clean(); return $tpl_code;';
       
  1010     
       
  1011     ##
       
  1012     ## Main rules
       
  1013     ##
       
  1014     
       
  1015     //
       
  1016     // Conditionals
       
  1017     //
       
  1018     
       
  1019     $keywords = array('BEGIN', 'BEGINNOT', 'IFSET', 'IFPLUGIN');
       
  1020     $code = $plugins->setHook('template_compile_logic_keyword');
       
  1021     foreach ( $code as $cmd )
       
  1022     {
       
  1023       eval($cmd);
       
  1024     }
       
  1025     
       
  1026     $keywords = implode('|', $keywords);
       
  1027     
       
  1028     // Matches
       
  1029     //          1     2                               3                 4   56                       7     8
       
  1030     $regexp = '/(<!-- ('. $keywords .') ([A-z0-9_-]+) -->)(.*)((<!-- BEGINELSE \\3 -->)(.*))?(<!-- END \\3 -->)/isU';
       
  1031     
       
  1032     /*
       
  1033     The way this works is: match all blocks using the standard form with a different keyword in the block each time,
       
  1034     and replace them with appropriate PHP logic. Plugin-extensible now. :-)
       
  1035     
       
  1036     The while-loop is to bypass what is apparently a PCRE bug. It's hackish but it works. Properly written plugins should only need
       
  1037     to compile templates (using this method) once for each time the template file is changed.
       
  1038     */
       
  1039     while ( preg_match($regexp, $text) )
       
  1040     {
       
  1041       preg_match_all($regexp, $text, $matches);
       
  1042       for ( $i = 0; $i < count($matches[0]); $i++ )
       
  1043       {
       
  1044         $start_tag =& $matches[1][$i];
       
  1045         $type =& $matches[2][$i];
       
  1046         $test =& $matches[3][$i];
       
  1047         $particle_true  =& $matches[4][$i];
       
  1048         $else_tag =& $matches[6][$i];
       
  1049         $particle_else =& $matches[7][$i];
       
  1050         $end_tag =& $matches[8][$i];
       
  1051         
       
  1052         switch($type)
       
  1053         {
       
  1054           case 'BEGIN':
       
  1055             $cond = "isset(\$this->tpl_bool['$test']) && \$this->tpl_bool['$test']";
       
  1056             break;
       
  1057           case 'BEGINNOT':
       
  1058             $cond = "!isset(\$this->tpl_bool['$test']) || ( isset(\$this->tpl_bool['$test']) && !\$this->tpl_bool['$test'] )";
       
  1059             break;
       
  1060           case 'IFPLUGIN':
       
  1061             $cond = "getConfig('plugin_$test') == '1'";
       
  1062             break;
       
  1063           case 'IFSET':
       
  1064             $cond = "isset(\$this->tpl_strings['$test'])";
       
  1065             break;
       
  1066           default:
       
  1067             $code = $plugins->setHook('template_compile_logic_cond');
       
  1068             foreach ( $code as $cmd )
       
  1069             {
       
  1070               eval($cmd);
       
  1071             }
       
  1072             break;
       
  1073         }
       
  1074         
       
  1075         if ( !isset($cond) || ( isset($cond) && !is_string($cond) ) )
       
  1076           continue;
       
  1077         
       
  1078         $tag_complete = <<<TPLCODE
       
  1079         ';
       
  1080         /* START OF CONDITION: $type ($test) */
       
  1081         if ( $cond )
       
  1082         {
       
  1083           echo '$particle_true';
       
  1084         /* ELSE OF CONDITION: $type ($test) */
       
  1085         }
       
  1086         else
       
  1087         {
       
  1088           echo '$particle_else';
       
  1089         /* END OF CONDITION: $type ($test) */
       
  1090         }
       
  1091         echo '
       
  1092 TPLCODE;
       
  1093         
       
  1094         $text = str_replace_once($matches[0][$i], $tag_complete, $text);
       
  1095         
       
  1096       }
       
  1097     }
       
  1098     
       
  1099     // For debugging ;-)
       
  1100     // die("<pre>&lt;?php\n" . htmlspecialchars($text."\n\n".print_r($matches,true)) . "\n\n?&gt;</pre>");
       
  1101     
       
  1102     //
       
  1103     // Data substitution/variables
       
  1104     //
       
  1105     
       
  1106     // System messages
       
  1107     $text = preg_replace('/<!-- SYSMSG ([A-z0-9\._-]+?) -->/is', '\' . $this->tplWikiFormat($pages->sysMsg(\'\\1\')) . \'', $text);
       
  1108     
       
  1109     // Template variables
       
  1110     $text = preg_replace('/\{([A-z0-9_-]+?)\}/is', '\' . $this->tpl_strings[\'\\1\'] . \'', $text);
       
  1111     
       
  1112     // Reinsert PHP
       
  1113     
       
  1114     foreach ( $php_matches[1] as $i => $match )
       
  1115     {
       
  1116       // Substitute the random tag with the "real" PHP code
       
  1117       $tag = "{PHP:$i:$seed}";
       
  1118       $text = str_replace_once($tag, "'; $match echo '", $text);
       
  1119     }
       
  1120     
       
  1121     // echo('<pre>' . htmlspecialchars($text) . '</pre>');
       
  1122     
       
  1123     return $text;  
       
  1124     
       
  1125   }
       
  1126   
       
  1127   /**
       
  1128    * Compiles the contents of a given template file, possibly using a cached copy, and returns the compiled code.
       
  1129    * @param string Filename of template (header.tpl)
       
  1130    * @return string
       
  1131    */
       
  1132   
       
  1133   function compile_template($filename)
       
  1134   {
       
  1135     global $db, $session, $paths, $template, $plugins; // Common objects
       
  1136     
       
  1137     // Full path to template file
       
  1138     $tpl_file_fullpath = ENANO_ROOT . '/themes/' . $this->theme . '/' . $filename;
       
  1139     
       
  1140     // Make sure the file exists
       
  1141     if ( !is_file($tpl_file_fullpath) )
       
  1142     {
       
  1143       die_semicritical('Cannot find template file',
       
  1144                        '<p>The template parser was asked to load the file "' . htmlspecialchars($filename) . '", but that file couldn\'t be found in the directory for
       
  1145                            the current theme.</p>
       
  1146                         <p>Additional debugging information:<br />
       
  1147                            <b>Theme currently in use: </b>' . $this->theme . '<br />
       
  1148                            <b>Requested file: </b>' . $file . '
       
  1149                            </p>');
       
  1150     }
       
  1151     
       
  1152     // Check for cached copy
       
  1153     // This will make filenames in the pattern of theme-file.tpl.php
       
  1154     $cache_file = ENANO_ROOT . '/cache/' . $this->theme . '-' . str_replace('/', '-', $filename) . '.php';
       
  1155     
       
  1156     // Only use cached copy if caching is enabled
       
  1157     //   (it is enabled by default I think)
       
  1158     if ( file_exists($cache_file) && getConfig('cache_thumbs') == '1' )
       
  1159     {
       
  1160       // Cache files are auto-generated, but otherwise are normal PHP files
       
  1161       include($cache_file);
       
  1162       
       
  1163       // Fetch content of the ORIGINAL
       
  1164       $text = file_get_contents($tpl_file_fullpath);
       
  1165       
       
  1166       // $md5 will be set by the cached file
       
  1167       // This makes sure that a cached copy of the template is used only if its MD5
       
  1168       // matches the MD5 of the file that the compiled file was compiled from.
       
  1169       if ( isset($md5) && $md5 == md5($text) )
       
  1170       {
       
  1171         return $this->compile_template_text_post(str_replace('\\"', '"', $tpl_text));
       
  1172       }
       
  1173     }
       
  1174     
       
  1175     // We won't use the cached copy here
       
  1176     $text = file_get_contents($tpl_file_fullpath);
       
  1177     
       
  1178     // This will be used later when writing the cached file
   917     $md5 = md5($text);
  1179     $md5 = md5($text);
   918     
  1180     
   919     $seed = md5 ( microtime() . mt_rand() );
  1181     // Preprocessing and checks complete - compile the code
   920     preg_match_all("/<\?php(.*?)\?>/is", $text, $m);
  1182     $text = $this->compile_tpl_code($text);
   921     //die('<pre>'.htmlspecialchars(print_r($m, true)).'</pre>');
  1183     
   922     for($i = 0; $i < sizeof($m[1]); $i++)
  1184     // Perhaps caching is enabled and the admin has changed the template?
   923     {
  1185     if ( is_writable( ENANO_ROOT . '/cache/' ) && getConfig('cache_thumbs') == '1' )
   924       $text = str_replace("<?php{$m[1][$i]}?>", "{PHPCODE:{$i}:{$seed}}", $text);
  1186     {
   925     }
  1187       $h = fopen($cache_file, 'w');
   926     //die('<pre>'.htmlspecialchars($text).'</pre>');
  1188       if ( !$h )
   927     $text = 'ob_start(); echo \''.str_replace('\'', '\\\'', $text).'\'; $tpl_code = ob_get_contents(); ob_end_clean();';
  1189       {
   928     $text = preg_replace('#<!-- BEGIN (.*?) -->#is', '\'; if(isset($this->tpl_bool[\'\\1\']) && $this->tpl_bool[\'\\1\']) { echo \'', $text);
  1190         // Couldn't open the file - silently ignore and return
   929     $text = preg_replace('#<!-- IFSET (.*?) -->#is', '\'; if(isset($this->tpl_strings[\'\\1\'])) { echo \'', $text);
  1191         return $text;
   930     $text = preg_replace('#<!-- IFPLUGIN (.*?) -->#is', '\'; if(getConfig(\'plugin_\\1\')==\'1\') { echo \'', $text);
  1192       }
   931     $text = preg_replace('#<!-- SYSMSG (.*?) -->#is', '\'; echo $template->tplWikiFormat($paths->sysMsg(\'\\1\')); echo \'', $text);
  1193       
   932     $text = preg_replace('#<!-- BEGINNOT (.*?) -->#is', '\'; if(!$this->tpl_bool[\'\\1\']) { echo \'', $text);
  1194       // Escape the compiled code so it can be eval'ed
   933     $text = preg_replace('#<!-- BEGINELSE (.*?) -->#is', '\'; } else { echo \'', $text);
  1195       $text_escaped = addslashes($text);
   934     $text = preg_replace('#<!-- END (.*?) -->#is', '\'; } echo \'', $text);
       
   935     $text = preg_replace('#\{([A-z0-9]*)\}#is', '\'.$this->tpl_strings[\'\\1\'].\'', $text);
       
   936     for($i = 0; $i < sizeof($m[1]); $i++)
       
   937     {
       
   938       $text = str_replace("{PHPCODE:{$i}:{$seed}}", "'; {$m[1][$i]} echo '", $text);
       
   939     }
       
   940     if(is_writable(ENANO_ROOT.'/cache/') && getConfig('cache_thumbs')=='1')
       
   941     {
       
   942       //die($tpl_filename);
       
   943       $h = fopen($tpl_filename, 'w');
       
   944       if(!$h) return $text;
       
   945       $t = addslashes($text);
       
   946       $notice = <<<EOF
  1196       $notice = <<<EOF
   947 
  1197 
   948 /*
  1198 /*
   949  * NOTE: This file was automatically generated by Enano and is based on compiled code. Do not edit this file.
  1199  * NOTE: This file was automatically generated by Enano and is based on compiled code. Do not edit this file.
   950  * If you edit this file, any changes you make will be lost the next time the associated source template file is edited.
  1200  * If you edit this file, any changes you make will be lost the next time the associated source template file is edited.
   951  */
  1201  */
   952 
  1202 
   953 EOF;
  1203 EOF;
   954       fwrite($h, '<?php ' . $notice . ' $md5 = \''.$md5.'\'; $tpl_text = \''.$t.'\'; ?>');
  1204       // This is really just a normal PHP file that sets a variable or two and exits.
       
  1205       // $tpl_text actually will contain the compiled code
       
  1206       fwrite($h, '<?php ' . $notice . ' $md5 = \'' . $md5 . '\'; $tpl_text = \'' . $text_escaped . '\'; ?>');
   955       fclose($h);
  1207       fclose($h);
   956     }
  1208     }
   957     return $text; //('<pre>'.htmlspecialchars($text).'</pre>');
  1209     
   958   }
  1210     return $this->compile_template_text_post($text); //('<pre>'.htmlspecialchars($text).'</pre>');
   959   
  1211   }
   960   function compile_template_text($text) {
  1212   
   961     $seed = md5 ( microtime() . mt_rand() );
  1213   
   962     preg_match_all("/<\?php(.*?)\?>/is", $text, $m);
  1214   /**
   963     //die('<pre>'.htmlspecialchars(print_r($m, true)).'</pre>');
  1215    * Compiles (parses) some template code with the current master set of variables and booleans.
   964     for($i = 0; $i < sizeof($m[1]); $i++)
  1216    * @param string Text to process
   965     {
  1217    * @return string
   966       $text = str_replace("<?php{$m[1][$i]}?>", "{PHPCODE:{$i}:{$seed}}", $text);
  1218    */
   967     }
  1219   
   968     //die('<pre>'.htmlspecialchars($text).'</pre>');
  1220   function compile_template_text($text)
   969     $text = 'ob_start(); echo \''.str_replace('\'', '\\\'', $text).'\'; $tpl_code = ob_get_contents(); ob_end_clean(); return $tpl_code;';
  1221   {
   970     $text = preg_replace('#<!-- BEGIN (.*?) -->#is', '\'; if(isset($this->tpl_bool[\'\\1\']) && $this->tpl_bool[\'\\1\']) { echo \'', $text);
  1222     // this might do something else in the future, possibly cache large templates
   971     $text = preg_replace('#<!-- IFSET (.*?) -->#is', '\'; if(isset($this->tpl_strings[\'\\1\'])) { echo \'', $text);
  1223     return $this->compile_template_text_post($this->compile_tpl_code($text));
   972     $text = preg_replace('#<!-- IFPLUGIN (.*?) -->#is', '\'; if(getConfig(\'plugin_\\1\')==\'1\') { echo \'', $text);
  1224   }
   973     $text = preg_replace('#<!-- SYSMSG (.*?) -->#is', '\'; echo $template->tplWikiFormat($paths->sysMsg(\'\\1\')); echo \'', $text);
  1225   
   974     $text = preg_replace('#<!-- BEGINNOT (.*?) -->#is', '\'; if(!$this->tpl_bool[\'\\1\']) { echo \'', $text);
  1226   /**
   975     $text = preg_replace('#<!-- BEGINELSE (.*?) -->#is', '\'; } else { echo \'', $text);
  1227    * For convenience - compiles AND parses some template code.
   976     $text = preg_replace('#<!-- END (.*?) -->#is', '\'; } echo \'', $text);
  1228    * @param string Text to process
   977     $text = preg_replace('#\{([A-z0-9]*)\}#is', '\'.$this->tpl_strings[\'\\1\'].\'', $text);
  1229    * @return string
   978     for($i = 0; $i < sizeof($m[1]); $i++)
  1230    */
   979     {
       
   980       $text = str_replace("{PHPCODE:{$i}:{$seed}}", "'; {$m[1][$i]} echo '", $text);
       
   981     }
       
   982     return $text; //('<pre>'.htmlspecialchars($text).'</pre>');
       
   983   }
       
   984   
  1231   
   985   function parse($text)
  1232   function parse($text)
   986   {
  1233   {
   987     $text = $this->compile_template_text($text);
  1234     $text = $this->compile_template_text($text);
       
  1235     $text = $this->compile_template_text_post($text);
   988     return eval($text);
  1236     return eval($text);
       
  1237   }
       
  1238   
       
  1239   /**
       
  1240    * Post-processor for template code. Basically what this does is it localizes {lang:foo} blocks.
       
  1241    * @param string Mostly-processed TPL code
       
  1242    * @return string
       
  1243    */
       
  1244   
       
  1245   function compile_template_text_post($text)
       
  1246   {
       
  1247     global $lang;
       
  1248     preg_match_all('/\{lang:([a-z0-9]+_[a-z0-9_]+)\}/', $text, $matches);
       
  1249     foreach ( $matches[1] as $i => $string_id )
       
  1250     {
       
  1251       $string = $lang->get($string_id);
       
  1252       $string = str_replace('\\', '\\\\', $string);
       
  1253       $string = str_replace('\'', '\\\'', $string);
       
  1254       $text = str_replace_once($matches[0][$i], $string, $text);
       
  1255     }
       
  1256     return $text;
   989   }
  1257   }
   990   
  1258   
   991   // Steps to turn this:
  1259   // Steps to turn this:
   992   //   [[Project:Community Portal]]
  1260   //   [[Project:Community Portal]]
   993   // into this:
  1261   // into this:
  1002   
  1270   
  1003   // The template language is really a miniature programming language; with variables, conditionals, everything!
  1271   // The template language is really a miniature programming language; with variables, conditionals, everything!
  1004   // So you can implement custom logic into your sidebar if you wish.
  1272   // So you can implement custom logic into your sidebar if you wish.
  1005   // "Real" PHP support coming soon :-D
  1273   // "Real" PHP support coming soon :-D
  1006   
  1274   
  1007   function tplWikiFormat($message, $filter_links = false, $filename = 'elements.tpl') {
  1275   /**
  1008     global $db, $session, $paths, $template, $plugins; // Common objects
  1276    * Takes a blob of HTML with the specially formatted template-oriented wikitext and formats it. Does not use eval().
       
  1277    * This function butchers every coding standard in Enano and should eventually be rewritten. The fact is that the
       
  1278    * code _works_ and does a good job of checking for errors and cleanly complaining about them.
       
  1279    * @param string Text to process
       
  1280    * @param bool Ignored for backwards compatibility
       
  1281    * @param string File to get variables for sidebar data from
       
  1282    * @return string
       
  1283    */
       
  1284   
       
  1285   function tplWikiFormat($message, $filter_links = false, $filename = 'elements.tpl')
       
  1286   {
       
  1287     global $db, $session, $paths, $template, $plugins; // Common objects
       
  1288     global $lang;
       
  1289     
  1009     $filter_links = false;
  1290     $filter_links = false;
  1010     $tplvars = $this->extract_vars($filename);
  1291     $tplvars = $this->extract_vars($filename);
  1011     if($session->sid_super) $as = htmlspecialchars(urlSeparator).'auth='.$session->sid_super;
  1292     if($session->sid_super) $as = htmlspecialchars(urlSeparator).'auth='.$session->sid_super;
  1012     else $as = '';
  1293     else $as = '';
  1013     error_reporting(E_ALL);
  1294     error_reporting(E_ALL);
  1027       $message = str_replace('$'.$links[$i].'$', $this->tpl_strings[$links[$i]], $message);
  1308       $message = str_replace('$'.$links[$i].'$', $this->tpl_strings[$links[$i]], $message);
  1028     }
  1309     }
  1029     
  1310     
  1030     // Conditionals
  1311     // Conditionals
  1031     
  1312     
  1032     preg_match_all('#\{if ([A-Za-z0-9_ &\|\!-]*)\}(.*?)\{\/if\}#is', $message, $links);
  1313     preg_match_all('#\{if ([A-Za-z0-9_ \(\)&\|\!-]*)\}(.*?)\{\/if\}#is', $message, $links);
  1033     
  1314     
  1034     for($i=0;$i<sizeof($links[1]);$i++)
  1315     // Temporary exception from coding standards - using tab length of 4 here for clarity
  1035     {
  1316     for ( $i = 0; $i < sizeof($links[1]); $i++ )
  1036       $message = str_replace('{if '.$links[1][$i].'}'.$links[2][$i].'{/if}', '{CONDITIONAL:'.$i.':'.$random_id.'}', $message);
  1317     {
  1037       
  1318         $condition =& $links[1][$i];
  1038       // Time for some manual parsing...
  1319         $message = str_replace('{if '.$condition.'}'.$links[2][$i].'{/if}', '{CONDITIONAL:'.$i.':'.$random_id.'}', $message);
  1039       $chk = false;
       
  1040       $current_id = '';
       
  1041       $prn_level = 0;
       
  1042       // Used to keep track of where we are in the conditional
       
  1043       // Object of the game: turn {if this && ( that OR !something_else )} ... {/if} into if( ( isset($this->tpl_bool['that']) && $this->tpl_bool['that'] ) && ...
       
  1044       // Method of attack: escape all variables, ignore all else. Non-valid code is filtered out by a regex above.
       
  1045       $in_var_now = true;
       
  1046       $in_var_last = false;
       
  1047       $current_var = '';
       
  1048       $current_var_start_pos = 0;
       
  1049       $current_var_end_pos   = 0;
       
  1050       $j = -1;
       
  1051       $links[1][$i] = $links[1][$i] . ' ';
       
  1052       $d = strlen($links[1][$i]);
       
  1053       while($j < $d)
       
  1054       {
       
  1055         $j++;
       
  1056         $in_var_last = $in_var_now;
       
  1057         
  1320         
  1058         $char = substr($links[1][$i], $j, 1);
  1321         // Time for some manual parsing...
  1059         $in_var_now = ( preg_match('#^([A-z0-9_]*){1}$#', $char) ) ? true : false;
  1322         $chk = false;
  1060         if(!$in_var_last && $in_var_now)
  1323         $current_id = '';
       
  1324         $prn_level = 0;
       
  1325         // Used to keep track of where we are in the conditional
       
  1326         // Object of the game: turn {if this && ( that OR !something_else )} ... {/if} into if( ( isset($this->tpl_bool['that']) && $this->tpl_bool['that'] ) && ...
       
  1327         // Method of attack: escape all variables, ignore all else. Non-valid code is filtered out by a regex above.
       
  1328         $in_var_now = true;
       
  1329         $in_var_last = false;
       
  1330         $current_var = '';
       
  1331         $current_var_start_pos = 0;
       
  1332         $current_var_end_pos     = 0;
       
  1333         $j = -1;
       
  1334         $condition = $condition . ' ';
       
  1335         $d = strlen($condition);
       
  1336         while($j < $d)
  1061         {
  1337         {
  1062           $current_var_start_pos = $j;
  1338             $j++;
       
  1339             $in_var_last = $in_var_now;
       
  1340             
       
  1341             $char = substr($condition, $j, 1);
       
  1342             $in_var_now = ( preg_match('#^([A-z0-9_]*){1}$#', $char) ) ? true : false;
       
  1343             if(!$in_var_last && $in_var_now)
       
  1344             {
       
  1345                 $current_var_start_pos = $j;
       
  1346             }
       
  1347             if($in_var_last && !$in_var_now)
       
  1348             {
       
  1349                 $current_var_end_pos = $j;
       
  1350             }
       
  1351             if($in_var_now)
       
  1352             {
       
  1353                 $current_var .= $char;
       
  1354                 continue;
       
  1355             }
       
  1356             // OK we are not inside of a variable. That means that we JUST hit the end because the counter ($j) will be advanced to the beginning of the next variable once processing here is complete.
       
  1357             if($char != ' ' && $char != '(' && $char != ')' && $char != 'A' && $char != 'N' && $char != 'D' && $char != 'O' && $char != 'R' && $char != '&' && $char != '|' && $char != '!' && $char != '<' && $char != '>' && $char != '0' && $char != '1' && $char != '2' && $char != '3' && $char != '4' && $char != '5' && $char != '6' && $char != '7' && $char != '8' && $char != '9')
       
  1358             {
       
  1359                 // XSS attack! Bail out
       
  1360                 $errmsg    = '<p><b>Error:</b> Syntax error (possibly XSS attack) caught in template code:</p>';
       
  1361                 $errmsg .= '<pre>';
       
  1362                 $errmsg .= '{if '.htmlspecialchars($condition).'}';
       
  1363                 $errmsg .= "\n    ";
       
  1364                 for ( $k = 0; $k < $j; $k++ )
       
  1365                 {
       
  1366                     $errmsg .= " ";
       
  1367                 }
       
  1368                 // Show position of error
       
  1369                 $errmsg .= '<span style="color: red;">^</span>';
       
  1370                 $errmsg .= '</pre>';
       
  1371                 $message = str_replace('{CONDITIONAL:'.$i.':'.$random_id.'}', $errmsg, $message);
       
  1372                 continue 2;
       
  1373             }
       
  1374             if($current_var != '')
       
  1375             {
       
  1376                 $cd = '( isset($this->tpl_bool[\''.$current_var.'\']) && $this->tpl_bool[\''.$current_var.'\'] )';
       
  1377                 $cvt = substr($condition, 0, $current_var_start_pos) . $cd . substr($condition, $current_var_end_pos, strlen($condition));
       
  1378                 $j = $j + strlen($cd) - strlen($current_var);
       
  1379                 $current_var = '';
       
  1380                 $condition = $cvt;
       
  1381                 $d = strlen($condition);
       
  1382             }
  1063         }
  1383         }
  1064         if($in_var_last && !$in_var_now)
  1384         $condition = substr($condition, 0, strlen($condition)-1);
       
  1385         $condition = '$chk = ( '.$condition.' ) ? true : false;';
       
  1386         eval($condition);
       
  1387         
       
  1388         if($chk)
  1065         {
  1389         {
  1066           $current_var_end_pos = $j;
  1390             if(strstr($links[2][$i], '{else}')) $c = substr($links[2][$i], 0, strpos($links[2][$i], '{else}'));
       
  1391             else $c = $links[2][$i];
       
  1392             $message = str_replace('{CONDITIONAL:'.$i.':'.$random_id.'}', $c, $message);
  1067         }
  1393         }
  1068         if($in_var_now)
  1394         else
  1069         {
  1395         {
  1070           $current_var .= $char;
  1396             if(strstr($links[2][$i], '{else}')) $c = substr($links[2][$i], strpos($links[2][$i], '{else}')+6, strlen($links[2][$i]));
  1071           continue;
  1397             else $c = '';
       
  1398             $message = str_replace('{CONDITIONAL:'.$i.':'.$random_id.'}', $c, $message);
  1072         }
  1399         }
  1073         // OK we are not inside of a variable. That means that we JUST hit the end because the counter ($j) will be advanced to the beginning of the next variable once processing here is complete.
       
  1074         if($char != ' ' && $char != '(' && $char != ')' && $char != 'A' && $char != 'N' && $char != 'D' && $char != 'O' && $char != 'R' && $char != '&' && $char != '|' && $char != '!' && $char != '<' && $char != '>' && $char != '0' && $char != '1' && $char != '2' && $char != '3' && $char != '4' && $char != '5' && $char != '6' && $char != '7' && $char != '8' && $char != '9')
       
  1075         {
       
  1076           // XSS attack! Bail out
       
  1077           echo '<p><b>Error:</b> Syntax error (possibly XSS attack) caught in template code:</p>';
       
  1078           echo '<pre>';
       
  1079           echo '{if '.$links[1][$i].'}';
       
  1080           echo "\n    ";
       
  1081           for($k=0;$k<$j;$k++) echo " ";
       
  1082           echo '<span style="color: red;">^</span>';
       
  1083           echo '</pre>';
       
  1084           continue 2;
       
  1085         }
       
  1086         if($current_var != '')
       
  1087         {
       
  1088           $cd = '( isset($this->tpl_bool[\''.$current_var.'\']) && $this->tpl_bool[\''.$current_var.'\'] )';
       
  1089           $cvt = substr($links[1][$i], 0, $current_var_start_pos) . $cd . substr($links[1][$i], $current_var_end_pos, strlen($links[1][$i]));
       
  1090           $j = $j + strlen($cd) - strlen($current_var);
       
  1091           $current_var = '';
       
  1092           $links[1][$i] = $cvt;
       
  1093           $d = strlen($links[1][$i]);
       
  1094         }
       
  1095       }
       
  1096       $links[1][$i] = substr($links[1][$i], 0, strlen($links[1][$i])-1);
       
  1097       $links[1][$i] = '$chk = ( '.$links[1][$i].' ) ? true : false;';
       
  1098       eval($links[1][$i]);
       
  1099       
       
  1100       if($chk) { // isset($this->tpl_bool[$links[1][$i]]) && $this->tpl_bool[$links[1][$i]]
       
  1101         if(strstr($links[2][$i], '{else}')) $c = substr($links[2][$i], 0, strpos($links[2][$i], '{else}'));
       
  1102         else $c = $links[2][$i];
       
  1103         $message = str_replace('{CONDITIONAL:'.$i.':'.$random_id.'}', $c, $message);
       
  1104       } else {
       
  1105         if(strstr($links[2][$i], '{else}')) $c = substr($links[2][$i], strpos($links[2][$i], '{else}')+6, strlen($links[2][$i]));
       
  1106         else $c = '';
       
  1107         $message = str_replace('{CONDITIONAL:'.$i.':'.$random_id.'}', $c, $message);
       
  1108       }
       
  1109     }
  1400     }
  1110     
  1401     
  1111     preg_match_all('#\{!if ([A-Za-z_-]*)\}(.*?)\{\/if\}#is', $message, $links);
  1402     preg_match_all('#\{!if ([A-Za-z_-]*)\}(.*?)\{\/if\}#is', $message, $links);
  1112     
  1403     
  1113     for($i=0;$i<sizeof($links[1]);$i++)
  1404     for($i=0;$i<sizeof($links[1]);$i++)
  1122         else $c = $links[2][$i];
  1413         else $c = $links[2][$i];
  1123         $message = str_replace('{CONDITIONAL:'.$i.':'.$random_id.'}', $c, $message);
  1414         $message = str_replace('{CONDITIONAL:'.$i.':'.$random_id.'}', $c, $message);
  1124       }
  1415       }
  1125     }
  1416     }
  1126     
  1417     
       
  1418     preg_match_all('/\{lang:([a-z0-9]+_[a-z0-9_]+)\}/', $message, $matches);
       
  1419     foreach ( $matches[1] as $i => $string_id )
       
  1420     {
       
  1421       $string = $lang->get($string_id);
       
  1422       $string = str_replace('\\', '\\\\', $string);
       
  1423       $string = str_replace('\'', '\\\'', $string);
       
  1424       $message = str_replace_once($matches[0][$i], $string, $message);
       
  1425     }
       
  1426     
  1127     /*
  1427     /*
  1128      * HTML RENDERER
  1428      * HTML RENDERER
  1129      */
  1429      */
  1130      
  1430      
  1131     // Images
  1431     // Images
  1172     
  1472     
  1173     // External links
  1473     // External links
  1174     // $message = preg_replace('#\[(http|ftp|irc):\/\/([a-z0-9\/:_\.\?&%\#@_\\\\-]+?) ([^\]]+)\\]#', '<a href="\\1://\\2">\\3</a><br style="display: none;" />', $message);
  1474     // $message = preg_replace('#\[(http|ftp|irc):\/\/([a-z0-9\/:_\.\?&%\#@_\\\\-]+?) ([^\]]+)\\]#', '<a href="\\1://\\2">\\3</a><br style="display: none;" />', $message);
  1175     // $message = preg_replace('#\[(http|ftp|irc):\/\/([a-z0-9\/:_\.\?&%\#@_\\\\-]+?)\\]#', '<a href="\\1://\\2">\\1://\\2</a><br style="display: none;" />', $message);
  1475     // $message = preg_replace('#\[(http|ftp|irc):\/\/([a-z0-9\/:_\.\?&%\#@_\\\\-]+?)\\]#', '<a href="\\1://\\2">\\1://\\2</a><br style="display: none;" />', $message);
  1176     
  1476     
  1177     preg_match_all('#\[(http|ftp|irc):\/\/([a-z0-9\/:_\.\?&%\#@_\\\\-]+?)\\ ([^\]]+)]#', $message, $ext_link);
  1477     preg_match_all('/\[((https?|ftp|irc):\/\/([^@\s\]"\':]+)?((([a-z0-9-]+\.)*)[a-z0-9-]+)(\/[A-z0-9_%\|~`!\!@#\$\^&\*\(\):;\.,\/-]*(\?(([a-z0-9_-]+)(=[A-z0-9_%\|~`\!@#\$\^&\*\(\):;\.,\/-\[\]]+)?((&([a-z0-9_-]+)(=[A-z0-9_%\|~`!\!@#\$\^&\*\(\):;\.,\/-]+)?)*))?)?)?) ([^\]]+)\]/is', $message, $ext_link);
       
  1478     
       
  1479     // die('<pre>' . htmlspecialchars( print_r($ext_link, true) ) . '</pre>');
  1178     
  1480     
  1179     for ( $i = 0; $i < count($ext_link[0]); $i++ )
  1481     for ( $i = 0; $i < count($ext_link[0]); $i++ )
  1180     {
  1482     {
  1181       $text_parser->assign_vars(Array(  
  1483       $text_parser->assign_vars(Array(  
  1182           'HREF'  => "{$ext_link[1][$i]}://{$ext_link[2][$i]}",
  1484           'HREF'  => $ext_link[1][$i],
  1183           'FLAGS' => '',
  1485           'FLAGS' => '',
  1184           'TEXT'  => $ext_link[3][$i]
  1486           'TEXT'  => $ext_link[16][$i]
  1185         ));
  1487         ));
  1186       $message = str_replace($ext_link[0][$i], $text_parser->run(), $message);
  1488       $message = str_replace($ext_link[0][$i], $text_parser->run(), $message);
  1187     }
  1489     }
  1188     
  1490     
  1189     preg_match_all('#\[(http|ftp|irc):\/\/([a-z0-9\/:_\.\?&%\#@_\\\\-]+?)\\]#', $message, $ext_link);
  1491     preg_match_all('/\[((https?|ftp|irc):\/\/([^@\s\]"\':]+)?((([a-z0-9-]+\.)*)[a-z0-9-]+)(\/[A-z0-9_%\|~`!\!@#\$\^&\*\(\):;\.,\/-]*(\?(([a-z0-9_-]+)(=[A-z0-9_%\|~`\!@#\$\^&\*\(\):;\.,\/-\[\]]+)?((&([a-z0-9_-]+)(=[A-z0-9_%\|~`!\!@#\$\^&\*\(\):;\.,\/-]+)?)*))?)?)?)\]/is', $message, $ext_link);
  1190     
  1492     
  1191     for ( $i = 0; $i < count($ext_link[0]); $i++ )
  1493     for ( $i = 0; $i < count($ext_link[0]); $i++ )
  1192     {
  1494     {
  1193       $text_parser->assign_vars(Array(  
  1495       $text_parser->assign_vars(Array(  
  1194           'HREF'  => "{$ext_link[1][$i]}://{$ext_link[2][$i]}",
  1496           'HREF'  => $ext_link[1][$i],
  1195           'FLAGS' => '',
  1497           'FLAGS' => '',
  1196           'TEXT'  => htmlspecialchars("{$ext_link[1][$i]}://{$ext_link[2][$i]}")
  1498           'TEXT'  => htmlspecialchars($ext_link[1][$i])
  1197         ));
  1499         ));
  1198       $message = str_replace($ext_link[0][$i], $text_parser->run(), $message);
  1500       $message = str_replace($ext_link[0][$i], $text_parser->run(), $message);
  1199     }
  1501     }
  1200     
  1502     
  1201     $parser1 = $this->makeParserText($tplvars['sidebar_section']);
  1503     $parser1 = $this->makeParserText($tplvars['sidebar_section']);
  1232    */
  1534    */
  1233    
  1535    
  1234   function username_field($name, $value = false)
  1536   function username_field($name, $value = false)
  1235   {
  1537   {
  1236     $randomid = md5( time() . microtime() . mt_rand() );
  1538     $randomid = md5( time() . microtime() . mt_rand() );
  1237     $text = '<input name="'.$name.'" onkeyup="ajaxUserNameComplete(this)" autocomplete="off" type="text" size="30" id="userfield_'.$randomid.'"';
  1539     $text = '<input name="'.$name.'" onkeyup="new AutofillUsername(this);" autocomplete="off" type="text" size="30" id="userfield_'.$randomid.'"';
  1238     if($value) $text .= ' value="'.$value.'"';
  1540     if($value) $text .= ' value="'.$value.'"';
  1239     $text .= ' />';
  1541     $text .= ' />';
  1240     return $text;
  1542     return $text;
  1241   }
  1543   }
  1242   
  1544   
  1432     // SourceForge/W3C buttons
  1734     // SourceForge/W3C buttons
  1433     $ob = Array();
  1735     $ob = Array();
  1434     $admintitle = ( $session->user_level >= USER_LEVEL_ADMIN ) ? 'title="You may disable this button in the admin panel under General Configuration."' : '';
  1736     $admintitle = ( $session->user_level >= USER_LEVEL_ADMIN ) ? 'title="You may disable this button in the admin panel under General Configuration."' : '';
  1435     if(getConfig('sflogo_enabled')=='1')
  1737     if(getConfig('sflogo_enabled')=='1')
  1436     {
  1738     {
  1437       $ob[] = '<a style="text-align: center;" href="http://sourceforge.net/" onclick="if ( !KILL_SWITCH ) { window.open(this.href);return false; }"><img style="border-width: 0px;" alt="SourceForge.net Logo" src="http://sflogo.sourceforge.net/sflogo.php?group_id='.getConfig('sflogo_groupid').'&amp;type='.getConfig('sflogo_type').'" /></a>';
  1739       $sflogo_secure = ( isset($_SERVER['HTTPS']) ) ? 'https' : 'http';
       
  1740       $ob[] = '<a style="text-align: center;" href="http://sourceforge.net/" onclick="if ( !KILL_SWITCH ) { window.open(this.href);return false; }"><img style="border-width: 0px;" alt="SourceForge.net Logo" src="' . $sflogo_secure . '://sflogo.sourceforge.net/sflogo.php?group_id='.getConfig('sflogo_groupid').'&amp;type='.getConfig('sflogo_type').'" /></a>';
  1438     }
  1741     }
  1439     if(getConfig('w3c_v32')     =='1') $ob[] = '<a style="text-align: center;" href="http://validator.w3.org/check?uri=referer" onclick="if ( !KILL_SWITCH ) { window.open(this.href);return false; }"><img style="border: 0px solid #FFFFFF;" alt="Valid HTML 3.2"  src="http://www.w3.org/Icons/valid-html32" /></a>';
  1742     if(getConfig('w3c_v32')     =='1') $ob[] = '<a style="text-align: center;" href="http://validator.w3.org/check?uri=referer" onclick="if ( !KILL_SWITCH ) { window.open(this.href);return false; }"><img style="border: 0px solid #FFFFFF;" alt="Valid HTML 3.2"  src="http://www.w3.org/Icons/valid-html32" /></a>';
  1440     if(getConfig('w3c_v40')     =='1') $ob[] = '<a style="text-align: center;" href="http://validator.w3.org/check?uri=referer" onclick="if ( !KILL_SWITCH ) { window.open(this.href);return false; }"><img style="border: 0px solid #FFFFFF;" alt="Valid HTML 4.0"  src="http://www.w3.org/Icons/valid-html40" /></a>';
  1743     if(getConfig('w3c_v40')     =='1') $ob[] = '<a style="text-align: center;" href="http://validator.w3.org/check?uri=referer" onclick="if ( !KILL_SWITCH ) { window.open(this.href);return false; }"><img style="border: 0px solid #FFFFFF;" alt="Valid HTML 4.0"  src="http://www.w3.org/Icons/valid-html40" /></a>';
  1441     if(getConfig('w3c_v401')    =='1') $ob[] = '<a style="text-align: center;" href="http://validator.w3.org/check?uri=referer" onclick="if ( !KILL_SWITCH ) { window.open(this.href);return false; }"><img style="border: 0px solid #FFFFFF;" alt="Valid HTML 4.01" src="http://www.w3.org/Icons/valid-html401" /></a>';
  1744     if(getConfig('w3c_v401')    =='1') $ob[] = '<a style="text-align: center;" href="http://validator.w3.org/check?uri=referer" onclick="if ( !KILL_SWITCH ) { window.open(this.href);return false; }"><img style="border: 0px solid #FFFFFF;" alt="Valid HTML 4.01" src="http://www.w3.org/Icons/valid-html401" /></a>';
  1442     if(getConfig('w3c_vxhtml10')=='1') $ob[] = '<a style="text-align: center;" href="http://validator.w3.org/check?uri=referer" onclick="if ( !KILL_SWITCH ) { window.open(this.href);return false; }"><img style="border: 0px solid #FFFFFF;" alt="Valid XHTML 1.0" src="http://www.w3.org/Icons/valid-xhtml10" /></a>';
  1745     if(getConfig('w3c_vxhtml10')=='1') $ob[] = '<a style="text-align: center;" href="http://validator.w3.org/check?uri=referer" onclick="if ( !KILL_SWITCH ) { window.open(this.href);return false; }"><img style="border: 0px solid #FFFFFF;" alt="Valid XHTML 1.0" src="http://www.w3.org/Icons/valid-xhtml10" /></a>';