includes/namespaces/default.php
changeset 953 323c4cd1aa37
parent 935 9e124177c9a4
child 963 b572ce1114f1
equal deleted inserted replaced
952:d52dfa1f08da 953:323c4cd1aa37
    62    */
    62    */
    63   
    63   
    64   public $title = '';
    64   public $title = '';
    65   
    65   
    66   /**
    66   /**
       
    67    * PathManager info array ("cdata") for this page. (The one with urlname, name, namespace, delvotes, delvote_ips, protected, visible, etc.)
       
    68    * @var array
       
    69    */
       
    70   
       
    71   public $cdata = array();
       
    72   
       
    73   /**
       
    74    * ACL calculation instance for this page.
       
    75    * @var object(Session_ACLPageInfo)
       
    76    */
       
    77   
       
    78   public $perms = false;
       
    79   
       
    80   /**
       
    81    * Protection calculation
       
    82    * @var bool
       
    83    */
       
    84   
       
    85   public $page_protected = false;
       
    86   
       
    87   /**
       
    88    * Wiki mode calculation
       
    89    * @var bool
       
    90    */
       
    91   
       
    92   public $wiki_mode = false;
       
    93   
       
    94   /**
       
    95    * Page conditions. These represent the final decision as to whether an action is allowed or not. They are set to true if ACLs permit AND if
       
    96    * the action "makes sense." (e.g., you can't vote to delete a non-wikimode page.)
       
    97    * @var array
       
    98    */
       
    99   
       
   100   public $conds = array();
       
   101   
       
   102   /**
    67    * Constructor.
   103    * Constructor.
    68    */
   104    */
    69   
   105   
    70   public function __construct($page_id, $namespace, $revision_id = 0)
   106   public function __construct($page_id, $namespace, $revision_id = 0)
    71   {
   107   {
    73     
   109     
    74     $this->page_id = sanitize_page_id($page_id);
   110     $this->page_id = sanitize_page_id($page_id);
    75     $this->namespace = $namespace;
   111     $this->namespace = $namespace;
    76     $this->revision_id = intval($revision_id);
   112     $this->revision_id = intval($revision_id);
    77     
   113     
    78     // only do this if calling from the (very heavily feature filled) abstract
   114     // grab the cdata
    79     // this will still be called if you're using your own handler but not replacing the constructor
   115     $this->build_cdata();
    80     if ( __CLASS__ == 'Namespace_Default' )
   116     
    81     {
   117     $this->page_protected = $this->cdata['really_protected'] ? true : false;
    82       $this->exists = false;
   118     switch($this->cdata['wiki_mode'])
    83       // NOTE! These should already be WELL sanitized before we reach this stage.
   119     {
    84       $q = $db->sql_query('SELECT name FROM ' . table_prefix . "pages WHERE urlname = '$this->page_id' AND namespace = '$this->namespace';");
   120       case 0: $this->wiki_mode = false; break;
    85       if ( !$q )
   121       case 1: $this->wiki_mode = true; break;
    86         $db->_die();
   122       default: case 2: $this->wiki_mode = getConfig('wiki_mode') == 1; break;
    87       
   123     }
    88       if ( $db->numrows() < 1 )
   124   }
    89       {
   125   
    90         // we still have a chance... some older databases don't do dots in the page title right
   126   /**
    91         if ( strstr(dirtify_page_id($this->page_id), '.') )
   127    * Build the page's cdata.
    92         {
   128    */
    93           $page_id = str_replace('.', '.2e', $page_id);
   129   
    94           
   130   public function build_cdata()
    95           $q = $db->sql_query('SELECT name FROM ' . table_prefix . "pages WHERE urlname = '$page_id' AND namespace = '$this->namespace';");
   131   {
    96           if ( !$q )
   132     global $db, $session, $paths, $template, $plugins; // Common objects
    97             $db->_die();
   133     static $cdata_cache = array();
    98           
   134     $pathskey = $paths->get_pathskey($this->page_id, $this->namespace);
    99           if ( $db->numrows() < 1 )
   135     if ( isset($cdata_cache[$pathskey]) )
   100           {
   136     {
   101             $this->title = $paths->nslist[$namespace] . dirtify_page_id($page_id);
   137       $this->cdata = $cdata_cache[$pathskey];
   102           }
   138       $this->exists = $cdata_cache[$pathskey]['page_exists'];
   103           else
   139       $this->title = $cdata_cache[$pathskey]['name'];
   104           {
   140       return null;
   105             list($this->title) = $db->fetchrow_num();
   141     }
   106             $this->exists = true;
   142     
   107             $this->page_id = $page_id;
   143     $this->exists = false;
   108           }
   144     $ns_char = substr($paths->nslist['Special'], -1);
   109         }
   145       
   110         else
   146     $page_name = $this->namespace == 'Article' ? dirtify_page_id($this->page_id) : "{$this->namespace}{$ns_char}" . dirtify_page_id($this->page_id);
   111         {
   147     $this->cdata = array(
   112           $this->title = $paths->nslist[$namespace] . dirtify_page_id($page_id);
   148       'name' => $page_name,
   113         }
   149       'urlname' => $this->page_id,
   114       }
   150       'namespace' => $this->namespace,
   115       else
   151       'special' => 0,
   116       {
   152       'visible' => 0,
   117         list($this->title) = $db->fetchrow_num();
   153       'comments_on' => 1,
   118         $this->exists = true;
   154       'protected' => 0,
   119       }
   155       'delvotes' => 0,
   120       $db->free_result();
   156       'delvote_ips' => '',
   121     }
   157       'wiki_mode' => 2,
       
   158       'page_exists' => false,
       
   159       'page_format' => getConfig('default_page_format', 'wikitext')
       
   160     );
       
   161     
       
   162     if ( $data_from_db = Namespace_Default::get_cdata_from_db($this->page_id, $this->namespace) )
       
   163     {
       
   164       $this->exists = true;
       
   165       $this->cdata = $data_from_db;
       
   166       $this->cdata['page_exists'] = true;
       
   167       $this->title = $this->cdata['name'];
       
   168     }
       
   169         
       
   170     $this->cdata = Namespace_Default::bake_cdata($this->cdata);
       
   171     
       
   172     $cdata_cache[$pathskey] = $this->cdata;
   122   }
   173   }
   123   
   174   
   124   /**
   175   /**
   125    * Pulls the page's actual text from the database.
   176    * Pulls the page's actual text from the database.
   126    */
   177    */
   285     global $lang;
   336     global $lang;
   286     global $output;
   337     global $output;
   287     
   338     
   288     $text = $this->fetch_text();
   339     $text = $this->fetch_text();
   289     
   340     
       
   341     profiler_log("Namespace [$this->namespace, $this->page_id]: pulled text from DB");
       
   342     
   290     $text = preg_replace('/([\s]*)__NOBREADCRUMBS__([\s]*)/', '', $text);
   343     $text = preg_replace('/([\s]*)__NOBREADCRUMBS__([\s]*)/', '', $text);
   291     $text = preg_replace('/([\s]*)__NOTOC__([\s]*)/', '', $text);
   344     $text = preg_replace('/([\s]*)__NOTOC__([\s]*)/', '', $text);
   292     
   345     
   293     $redir_enabled = false;
   346     $redir_enabled = false;
   294     if ( preg_match('/^#redirect \[\[([^\]]+?)\]\]/i', $text, $match ) )
   347     if ( preg_match('/^#redirect \[\[([^\]]+?)\]\]/i', $text, $match ) )
   297       
   350       
   298       $oldtarget = RenderMan::strToPageID($match[1]);
   351       $oldtarget = RenderMan::strToPageID($match[1]);
   299       $oldtarget[0] = sanitize_page_id($oldtarget[0]);
   352       $oldtarget[0] = sanitize_page_id($oldtarget[0]);
   300       
   353       
   301       $url = makeUrlNS($oldtarget[1], $oldtarget[0], false, true);
   354       $url = makeUrlNS($oldtarget[1], $oldtarget[0], false, true);
   302       $page_id_key = $paths->nslist[ $oldtarget[1] ] . $oldtarget[0];
   355       $page_data = $paths->get_cdata($oldtarget[0], $oldtarget[1]);
   303       $page_data = $paths->pages[$page_id_key];
       
   304       $title = ( isset($page_data['name']) ) ? $page_data['name'] : $paths->nslist[$oldtarget[1]] . htmlspecialchars( str_replace('_', ' ', dirtify_page_id( $oldtarget[0] ) ) );
   356       $title = ( isset($page_data['name']) ) ? $page_data['name'] : $paths->nslist[$oldtarget[1]] . htmlspecialchars( str_replace('_', ' ', dirtify_page_id( $oldtarget[0] ) ) );
   305       if ( !isset($page_data['name']) )
   357       if ( !isset($page_data['name']) )
   306       {
   358       {
   307         $cls = 'class="wikilink-nonexistent"';
   359         $cls = 'class="wikilink-nonexistent"';
   308       }
   360       }
   329       $text = trim($text);
   381       $text = trim($text);
   330     }
   382     }
   331     
   383     
   332     if ( $send_headers )
   384     if ( $send_headers )
   333     {
   385     {
   334       $template->init_vars($this);
       
   335       $output->set_title($this->title);
   386       $output->set_title($this->title);
   336       $output->header();
   387       $output->header();
   337     }
   388     }
   338     $this->do_breadcrumbs();
   389     $this->do_breadcrumbs();
   339     
   390     
   340     if ( $incl_inner_headers )
   391     if ( $incl_inner_headers )
   341     {
   392     {
   342       display_page_headers();
   393       if ( !$this->perms )
       
   394         $this->perms = $session->fetch_page_acl($this->page_id, $this->namespace);
       
   395       
       
   396       if ( $this->perms->get_permissions('vote_reset') && $this->cdata['delvotes'] > 0)
       
   397       {
       
   398         $delvote_ips = unserialize($this->cdata['delvote_ips']);
       
   399         $hr = htmlspecialchars(implode(', ', $delvote_ips['u']));
       
   400         
       
   401         $string_id = ( $this->cdata['delvotes'] == 1 ) ? 'delvote_lbl_votes_one' : 'delvote_lbl_votes_plural';
       
   402         $string = $lang->get($string_id, array('num_users' => $this->cdata['delvotes']));
       
   403         
       
   404         echo '<div class="info-box" style="margin-left: 0; margin-top: 5px;" id="mdgDeleteVoteNoticeBox">
       
   405                 <b>' . $lang->get('etc_lbl_notice') . '</b> ' . $string . '<br />
       
   406                 <b>' . $lang->get('delvote_lbl_users_that_voted') . '</b> ' . $hr . '<br />
       
   407                 <a href="'.makeUrl($paths->page, 'do=deletepage').'" onclick="ajaxDeletePage(); return false;">' . $lang->get('delvote_btn_deletepage') . '</a>  |  <a href="'.makeUrl($paths->page, 'do=resetvotes').'" onclick="ajaxResetDelVotes(); return false;">' . $lang->get('delvote_btn_resetvotes') . '</a>
       
   408               </div>';
       
   409       }
   343     }
   410     }
   344     
   411     
   345     if ( $this->revision_id )
   412     if ( $this->revision_id )
   346     {
   413     {
   347       echo '<div class="info-box" style="margin-left: 0; margin-top: 5px;">
   414       echo '<div class="info-box" style="margin-left: 0; margin-top: 5px;">
   361       list($page_format) = $db->fetchrow_num();
   428       list($page_format) = $db->fetchrow_num();
   362       $db->free_result();
   429       $db->free_result();
   363     }
   430     }
   364     else
   431     else
   365     {
   432     {
   366       $pathskey = $paths->nslist[ $this->namespace ] . $this->page_id;
   433       $page_format = $this->cdata['page_format'];
   367       $page_format = $paths->pages[$pathskey]['page_format'];
       
   368     }
   434     }
   369     
   435     
   370     if ( $redir_enabled )
   436     if ( $redir_enabled )
   371     {
   437     {
   372       echo $redir_html;
   438       echo $redir_html;
   375     $code = $plugins->setHook('pageprocess_render_head');
   441     $code = $plugins->setHook('pageprocess_render_head');
   376     foreach ( $code as $cmd )
   442     foreach ( $code as $cmd )
   377     {
   443     {
   378       eval($cmd);
   444       eval($cmd);
   379     }
   445     }
       
   446     
       
   447     $prof_contentevent = profiler_log("Namespace [$this->namespace, $this->page_id]: headers and preprocessing done - about to send content");
   380     
   448     
   381     if ( $incl_inner_headers )
   449     if ( $incl_inner_headers )
   382     {
   450     {
   383       if ( $page_format === 'wikitext' )
   451       if ( $page_format === 'wikitext' )
   384       {
   452       {
   398       $text = preg_replace('/<nowiki>(.*?)<\/nowiki>/s', '\\1', $text);
   466       $text = preg_replace('/<nowiki>(.*?)<\/nowiki>/s', '\\1', $text);
   399     }
   467     }
   400     
   468     
   401     eval ( $text );
   469     eval ( $text );
   402     
   470     
       
   471     profiler_log("Namespace [$this->namespace, $this->page_id]: content sent", true, $prof_contentevent);
       
   472     
   403     $code = $plugins->setHook('pageprocess_render_tail');
   473     $code = $plugins->setHook('pageprocess_render_tail');
   404     foreach ( $code as $cmd )
   474     foreach ( $code as $cmd )
   405     {
   475     {
   406       eval($cmd);
   476       eval($cmd);
   407     }
   477     }
   408     
   478     
   409     if ( $incl_inner_headers )
   479     if ( $incl_inner_headers )
   410     {
   480     {
   411       display_page_footers();
   481       display_page_footers();
   412     }
   482     }
       
   483     
       
   484     profiler_log("Namespace [$this->namespace, $this->page_id]: sent footers");
   413     
   485     
   414     if ( $send_headers )
   486     if ( $send_headers )
   415       $output->footer();
   487       $output->footer();
   416   }
   488   }
   417   
   489   
   707           $cid = sanitize_page_id($row['category_id']);
   779           $cid = sanitize_page_id($row['category_id']);
   708           $title = get_page_title_ns($cid, 'Category');
   780           $title = get_page_title_ns($cid, 'Category');
   709           $link = makeUrlNS('Category', $cid);
   781           $link = makeUrlNS('Category', $cid);
   710           $list[] = '<a href="' . $link . '">' . htmlspecialchars($title) . '</a>';
   782           $list[] = '<a href="' . $link . '">' . htmlspecialchars($title) . '</a>';
   711         }
   783         }
   712         while ( $row = $db->fetchrow() );
   784         while ( $row = $db->fetchrow($q) );
   713         $html .= implode(', ', $list);
   785         $html .= implode(', ', $list);
   714       }
   786       }
   715       else
   787       else
   716       {
   788       {
   717         $html .= $lang->get('catedit_catbox_lbl_uncategorized');
   789         $html .= $lang->get('catedit_catbox_lbl_uncategorized');
   726       
   798       
   727       $html .= '</div></div>';
   799       $html .= '</div></div>';
   728     }
   800     }
   729     return $html;
   801     return $html;
   730   }
   802   }
       
   803   
       
   804   /**
       
   805    * Pull in switches as to whether a specific toolbar button should be used or not. This sets things up according to the current page being displayed.
       
   806    * @return array Associative
       
   807    */
       
   808   
       
   809   function set_conds()
       
   810   {
       
   811     global $db, $session, $paths, $template, $plugins; // Common objects
       
   812     
       
   813     if ( !$this->perms )
       
   814       $this->perms = $session->fetch_page_acl($this->page_id, $this->namespace);
       
   815     
       
   816     $enforce_protection = ( $this->page_protected && ( ( $session->check_acl_scope('even_when_protected', $this->namespace) && !$this->perms->get_permissions('even_when_protected') ) || !$session->check_acl_scope('even_when_protected', $this->namespace) ) );
       
   817     
       
   818     $conds = array();
       
   819     
       
   820     // Article: always show
       
   821     $conds['article'] = true;
       
   822     
       
   823     // Discussion: Show if comments are enabled on the site, and if comments are on for this page.
       
   824     $conds['comments'] = $this->perms->get_permissions('read') && getConfig('enable_comments', '1')=='1' && $this->cdata['comments_on'] == 1;
       
   825     
       
   826     // Edit: Show if we have permission to edit the page, and if we don't have protection in effect
       
   827     $conds['edit'] = $this->perms->get_permissions('read') && $session->check_acl_scope('edit_page', $this->namespace) && $this->perms->get_permissions('edit_page') && !$enforce_protection;
       
   828     
       
   829     // View source: Show if we have permission to view source and either ACLs prohibit editing or protection is in effect
       
   830     $conds['viewsource'] = $session->check_acl_scope('view_source', $this->namespace) && $this->perms->get_permissions('view_source') && ( !$this->perms->get_permissions('edit_page') || $enforce_protection ) && $this->namespace != 'API';
       
   831     
       
   832     // History: Show if we have permission to see history and if the page exists
       
   833     $conds['history'] = $session->check_acl_scope('history_view', $this->namespace) && $this->exists && $this->perms->get_permissions('history_view');
       
   834     
       
   835     // Rename: Show if the page exists, if we have permission to rename, and if protection isn't in effect
       
   836     $conds['rename'] = $session->check_acl_scope('rename', $this->namespace) && $this->exists && $this->perms->get_permissions('rename') && !$enforce_protection;
       
   837     
       
   838     // Vote-to-delete: Show if we have Wiki Mode on, if we have permission to vote for deletion, and if the page exists (can't vote to delete a nonexistent page)
       
   839     $conds['delvote'] = $this->wiki_mode && $session->check_acl_scope('vote_delete', $this->namespace) && $this->perms->get_permissions('vote_delete') && $this->exists;
       
   840     
       
   841     // Reset votes: Show if we have Wiki Mode on, if we have permission to reset votes, if the page exists, and if there's at least one vote
       
   842     $conds['resetvotes'] = $session->check_acl_scope('vote_reset', $this->namespace) && $this->wiki_mode && $this->exists && $this->perms->get_permissions('vote_reset') && $this->cdata['delvotes'] > 0;
       
   843     
       
   844     // Delete page: Show if the page exists and if we have permission to delete it
       
   845     $conds['delete'] = $session->check_acl_scope('delete_page', $this->namespace) && $this->exists && $this->perms->get_permissions('delete_page');
       
   846     
       
   847     // Printable view: Show if the page exists
       
   848     $conds['printable'] = $this->exists;
       
   849     
       
   850     // Protect: Show if we have Wiki Mode on, if the page exists, and if we have permission to protect the page.
       
   851     $conds['protect'] = $session->check_acl_scope('protect', $this->namespace) && $this->wiki_mode && $this->exists && $this->perms->get_permissions('protect');
       
   852     
       
   853     // Set Wiki Mode: Show if the page exists and if we have permission to set wiki mode
       
   854     $conds['setwikimode'] = $session->check_acl_scope('set_wiki_mode', $this->namespace) && $this->exists && $this->perms->get_permissions('set_wiki_mode');
       
   855     
       
   856     // Clear logs: Show if we have permission to clear logs
       
   857     $conds['clearlogs'] = $session->check_acl_scope('clear_logs', $this->namespace) && $this->perms->get_permissions('clear_logs');
       
   858     
       
   859     // Set password: a little bit complicated. If there's a password, check for password_reset; else, check for password_set.
       
   860     $conds['password'] = empty($this->cdata['password']) ?
       
   861                            $session->check_acl_scope('password_set', $this->namespace) && $this->perms->get_permissions('password_set') :
       
   862                            $session->check_acl_scope('password_reset', $this->namespace) && $this->perms->get_permissions('password_reset');
       
   863     
       
   864     // Edit ACLs: Show if this is a non-Enano page that's calling the Enano API and (a) if we have permissions to edit ACLs or (b) we're an admin AND ACL_ALWAYS_ALLOW_ADMIN_EDIT_ACL is on
       
   865     $conds['acledit'] = $this->namespace != 'API' && $session->check_acl_scope('edit_acl', $this->namespace) && ( $this->perms->get_permissions('edit_acl') || ( defined('ACL_ALWAYS_ALLOW_ADMIN_EDIT_ACL') &&  $session->user_level >= USER_LEVEL_ADMIN ) );
       
   866     
       
   867     // Admin page: Show if the page exists and if we're an admin
       
   868     $conds['adminpage'] = $session->user_level >= USER_LEVEL_ADMIN && $this->exists;
       
   869     
       
   870     // Allow plugins to change stuff
       
   871     $code = $plugins->setHook('page_conds_set');
       
   872     foreach ( $code as $cmd )
       
   873     {
       
   874       eval($cmd);
       
   875     }
       
   876     
       
   877     $this->conds = $conds;
       
   878   }
       
   879   
       
   880   /**
       
   881    * Return page conditions
       
   882    * @return array
       
   883    */
       
   884   
       
   885   public function get_conds()
       
   886   {
       
   887     if ( empty($this->conds) )
       
   888       $this->set_conds();
       
   889     
       
   890     return $this->conds;
       
   891   }
       
   892   
   731   /**
   893   /**
   732    * Just tell us if the current page exists or not.
   894    * Just tell us if the current page exists or not.
   733    * @return bool
   895    * @return bool
   734    */
   896    */
   735    
   897    
   736   function exists()
   898   public function exists()
   737   {
   899   {
   738     return $this->exists;
   900     return $this->exists;
       
   901   }
       
   902   
       
   903   /**
       
   904    * Return cdata
       
   905    * @return array
       
   906    */
       
   907   
       
   908   public function get_cdata()
       
   909   {
       
   910     return $this->cdata;
       
   911   }
       
   912   
       
   913   /**
       
   914    * Bake, or finalize the processing of, a cdata array.
       
   915    * @static
       
   916    * @access public
       
   917    */
       
   918   
       
   919   public static function bake_cdata($cdata)
       
   920   {
       
   921     global $db, $session, $paths, $template, $plugins; // Common objects
       
   922     
       
   923     // urlname_nons is the actual page_id.
       
   924     $cdata['urlname_nons'] = $cdata['urlname'];
       
   925     if ( isset($paths->nslist[ $cdata['namespace'] ]) )
       
   926     {
       
   927       $cdata['urlname'] = $paths->nslist[ $cdata['namespace'] ] . $cdata['urlname'];
       
   928     }
       
   929     else
       
   930     {
       
   931       $ns_char = substr($paths->nslist['Special'], -1);
       
   932       $cdata['urlname'] = $cdata['namespace'] . $ns_char . $cdata['urlname'];
       
   933     }
       
   934     
       
   935     // fix up deletion votes
       
   936     if ( empty($cdata['delvotes']) )
       
   937       $cdata['delvotes'] = 0;
       
   938     
       
   939     // calculate wiki mode
       
   940     $cdata['really_wiki_mode'] = ( $cdata['wiki_mode'] == 1 || ( $cdata['wiki_mode'] == 2 && getConfig('wiki_mode', 0) == 1 ) );
       
   941     
       
   942     // calculate protection
       
   943     $cdata['really_protected'] = ( $cdata['protected'] > 0 );
       
   944     if ( $cdata['protected'] == 2 )
       
   945     {
       
   946       $cdata['really_protected'] = !$session->user_logged_in || ( $session->user_logged_in && $session->reg_time + 86400*4 > time() );
       
   947     }
       
   948     
       
   949     return $cdata;
       
   950   }
       
   951   
       
   952   /**
       
   953    * Grabs raw (unbaked) cdata from the database, caching if possible.
       
   954    * @param string Page ID
       
   955    * @param string Namespace.
       
   956    * @static
       
   957    */
       
   958   
       
   959   public static function get_cdata_from_db($page_id, $namespace)
       
   960   {
       
   961     global $db, $session, $paths, $template, $plugins; // Common objects
       
   962     static $cache = array();
       
   963     
       
   964     $pathskey = $paths->get_pathskey($page_id, $namespace);
       
   965     if ( isset($cache[$pathskey]) )
       
   966       return $cache[$pathskey];
       
   967     
       
   968     $page_id_db = $db->escape($page_id);
       
   969     $namespace_db = $db->escape($namespace);
       
   970     
       
   971     $q = $db->sql_query('SELECT * FROM ' . table_prefix . "pages WHERE urlname = '$page_id_db' AND namespace = '$namespace_db';");
       
   972     if ( !$q )
       
   973       $db->_die();
       
   974     
       
   975     if ( $db->numrows() < 1 )
       
   976     {
       
   977       $db->free_result();
       
   978       $cache[$pathskey] = false;
       
   979       return false;
       
   980     }
       
   981     
       
   982     $row = $db->fetchrow();
       
   983     $cache[$pathskey] = $row;
       
   984     return $row;
   739   }
   985   }
   740 }
   986 }
   741 
   987 
   742 /**
   988 /**
   743  * The namespaces that use the default handler.
   989  * The namespaces that use the default handler.
   753 
   999 
   754 class Namespace_Help extends Namespace_Default
  1000 class Namespace_Help extends Namespace_Default
   755 {
  1001 {
   756 }
  1002 }
   757 
  1003 
       
  1004 class Namespace_Category extends Namespace_Default
       
  1005 {
       
  1006 }
       
  1007