plugins/admin/PageManager.php
changeset 343 eefe9ab7fe7c
child 345 4ccdfeee9a11
equal deleted inserted replaced
342:ac34de920762 343:eefe9ab7fe7c
       
     1 <?php
       
     2 
       
     3 /*
       
     4  * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
       
     5  * Version 1.0.3 (Dyrad)
       
     6  * Copyright (C) 2006-2007 Dan Fuhry
       
     7  *
       
     8  * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
       
     9  * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
       
    10  *
       
    11  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
       
    12  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
       
    13  */
       
    14 
       
    15 // Page management smart form
       
    16 
       
    17 function page_Admin_PageManager()
       
    18 {
       
    19   global $db, $session, $paths, $template, $plugins; // Common objects
       
    20   global $lang;
       
    21   if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN )
       
    22   {
       
    23     $login_link = makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true);
       
    24     echo '<h3>' . $lang->get('adm_err_not_auth_title') . '</h3>';
       
    25     echo '<p>' . $lang->get('adm_err_not_auth_body', array( 'login_link' => $login_link )) . '</p>';
       
    26     return;
       
    27   }
       
    28   
       
    29   echo '<h3>' . $lang->get('acppm_heading_main') . '</h3>';
       
    30   $show_select = true;
       
    31   
       
    32   if ( isset($_REQUEST['action']) || isset($_REQUEST['source']) )
       
    33   {
       
    34     if ( isset($_REQUEST['action']) )
       
    35     {
       
    36       $act =& $_REQUEST['action'];
       
    37       $act = strtolower($act);
       
    38     }
       
    39     else if ( isset($_REQUEST['source']) && $_REQUEST['source'] == 'ajax' )
       
    40     {
       
    41       $act = 'select';
       
    42     }
       
    43     switch ( $act )
       
    44     {
       
    45       case 'save':
       
    46       case 'select':
       
    47         // First step is to determine the page ID and namespace
       
    48         
       
    49         if ( isset($_REQUEST['pid_search']) )
       
    50         {
       
    51           list($page_id, $namespace) = RenderMan::strToPageID($_REQUEST['page_id']);
       
    52           $name = $db->escape(dirtify_page_id($page_id));
       
    53           $page_id = $db->escape(sanitize_page_id($page_id));
       
    54           $namespace = $db->escape($namespace);
       
    55           $name = strtolower($name);
       
    56           $page_id = strtolower($page_id);
       
    57           $sql = "SELECT * FROM " . table_prefix . "pages WHERE ( " . ENANO_SQLFUNC_LOWERCASE . "(urlname) LIKE '%$page_id%' OR " . ENANO_SQLFUNC_LOWERCASE . "(name) LIKE '%$name%' ) ORDER BY name ASC;";
       
    58         }
       
    59         else
       
    60         {
       
    61           // pid_search was not set, assume absolute page ID
       
    62           list($page_id, $namespace) = RenderMan::strToPageID($_REQUEST['page_id']);
       
    63           $page_id = $db->escape(sanitize_page_id($page_id));
       
    64           $namespace = $db->escape($namespace);
       
    65           
       
    66           $sql = "SELECT * FROM " . table_prefix . "pages WHERE urlname = '$page_id' AND namespace = '$namespace';";
       
    67         }
       
    68         
       
    69         if ( !($q = $db->sql_query($sql)) )
       
    70         {
       
    71           $db->_die('PageManager selecting dataset for page');
       
    72         }
       
    73         
       
    74         if ( $db->numrows() < 1 )
       
    75         {
       
    76           echo '<div class="error-box">
       
    77                   ' . $lang->get('acppm_err_page_not_found') . '
       
    78                 </div>';
       
    79           break;
       
    80         }
       
    81         
       
    82         if ( $db->numrows() > 1 )
       
    83         {
       
    84           // Ambiguous results
       
    85           if ( isset($_REQUEST['pid_search']) )
       
    86           {
       
    87             echo '<h3>' . $lang->get('acppm_msg_results_ambiguous_title') . '</h3>';
       
    88             echo '<p>' . $lang->get('acppm_msg_results_ambiguous_body') . '</p>';
       
    89             echo '<ul>';
       
    90             while ( $row = $db->fetchrow($q) )
       
    91             {
       
    92               echo '<li>';
       
    93               $pathskey = $paths->nslist[$row['namespace']] . $row['urlname'];
       
    94               $edit_url = makeUrlNS('Special', 'Administration', "module={$paths->nslist['Admin']}PageManager&action=select&page_id=$pathskey", true);
       
    95               $view_url = makeUrlNS($row['namespace'], $row['urlname']);
       
    96               $page_name = htmlspecialchars(get_page_title_ns( $row['urlname'], $row['namespace'] ));
       
    97               $view_link = $lang->get('acppm_ambig_btn_viewpage');
       
    98               echo "<a href=\"$edit_url\">$page_name</a> (<a onclick=\"window.open(this.href); return false;\" href=\"$view_url\">$view_link</a>)";
       
    99               echo '</li>';
       
   100             }
       
   101             echo '</ul>';
       
   102             $show_select = false;
       
   103             break;
       
   104           }
       
   105           else
       
   106           {
       
   107             echo '<p>' . $lang->get('acppm_err_ambig_absolute') . '</p>';
       
   108             break;
       
   109           }
       
   110         }
       
   111         
       
   112         // From this point on we can assume that exactly one matching page was found.
       
   113         $dataset = $db->fetchrow();
       
   114         $page_id = $dataset['urlname'];
       
   115         $namespace = $dataset['namespace'];
       
   116         
       
   117         // This is used to re-determine the page ID after submit.
       
   118         $pathskey = $paths->nslist[$namespace] . sanitize_page_id($page_id);
       
   119         
       
   120         // The extra switch allows us to break out of the save routine if needed
       
   121         switch ( $act )
       
   122         {
       
   123           case 'save':
       
   124             
       
   125             $errors = array();
       
   126             $page_id_changed = false;
       
   127             $namespace_changed = false;
       
   128             
       
   129             // Backup the dataset to avoid redundantly updating values
       
   130             $dataset_backup = $dataset;
       
   131             
       
   132             // We've elected to save the page. The angle of attack here is to validate each form field,
       
   133             // and if the field validates successfully, change the value in $dataset accordingly.
       
   134             
       
   135             // Field: page name
       
   136             $page_name = $_POST['page_name'];
       
   137             $page_name = trim($page_name);
       
   138             if ( empty($page_name) )
       
   139             {
       
   140               $errors[] = $lang->get('acppm_err_invalid_page_name');
       
   141             }
       
   142             else
       
   143             {
       
   144               $dataset['name'] = $page_name;
       
   145             }
       
   146             
       
   147             // Field: page URL string
       
   148             $page_urlname = $_POST['page_urlname'];
       
   149             $page_urlname = trim($_POST['page_urlname']);
       
   150             if ( empty($page_urlname) && getConfig('main_page') !== '' )
       
   151             {
       
   152               $errors[] = $lang->get('acppm_err_invalid_url_string');
       
   153             }
       
   154             else
       
   155             {
       
   156               $page_id_changed = ( $_POST['page_urlname'] !== $dataset['urlname'] );
       
   157               $dataset['urlname'] = sanitize_page_id($page_urlname);
       
   158             }
       
   159             
       
   160             // Field: namespace
       
   161             $namespace = $_POST['page_namespace'];
       
   162             if ( !isset($paths->nslist[ $namespace ]) )
       
   163             {
       
   164               $errors[] = $lang->get('acppm_err_invalid_namespace');
       
   165             }
       
   166             else
       
   167             {
       
   168               $namespace_changed = ( $_POST['page_namespace'] !== $dataset['namespace'] );
       
   169               $dataset['namespace'] = $namespace;
       
   170             }
       
   171             
       
   172             // Field: comments enabled
       
   173             $dataset['comments_on'] = ( isset($_POST['comments_on']) ) ? 1 : 0;
       
   174             
       
   175             // Field: page visible
       
   176             $dataset['visible'] = ( isset($_POST['visible']) ) ? 1 : 0;
       
   177             
       
   178             // Field: standalone page
       
   179             $dataset['special'] = ( isset($_POST['special']) ) ? 1 : 0;
       
   180             
       
   181             // Field: page protection
       
   182             $protect_level = $_POST['protected'];
       
   183             if ( !in_array($protect_level, array('0', '1', '2')) )
       
   184             {
       
   185               $errors[] = $lang->get('acppm_err_invalid_protection');
       
   186             }
       
   187             else
       
   188             {
       
   189               $dataset['protected'] = intval($protect_level);
       
   190             }
       
   191             
       
   192             // Field: wiki mode
       
   193             $wiki_mode = $_POST['wikimode'];
       
   194             if ( !in_array($wiki_mode, array('0', '1', '2')) )
       
   195             {
       
   196               $errors[] = $lang->get('acppm_err_invalid_wiki_mode');
       
   197             }
       
   198             else
       
   199             {
       
   200               $dataset['wiki_mode'] = intval($wiki_mode);
       
   201             }
       
   202             
       
   203             if ( count($errors) < 1 )
       
   204             {
       
   205               // We're free of errors. Build a SQL query to update the page table.
       
   206               $particles = array();
       
   207               
       
   208               foreach ( $dataset as $key => $value )
       
   209               {
       
   210                 if ( $value === $dataset_backup[$key] || ( is_int($value) && $value === intval($dataset_backup[$key]) ) )
       
   211                   continue;
       
   212                 if ( is_int($value) )
       
   213                 {
       
   214                   $particle = "$key = $value";
       
   215                 }
       
   216                 else
       
   217                 {
       
   218                   $value = $db->escape($value);
       
   219                   $particle = "$key = '$value'";
       
   220                 }
       
   221                 $particles[] = $particle;
       
   222                 unset($particle);
       
   223               }
       
   224               
       
   225               $page_id_new = $db->escape($dataset['urlname']);
       
   226               $namespace_new = $db->escape($dataset['namespace']);
       
   227               
       
   228               // Only run the update query if at least one field was changed.
       
   229               if ( count($particles) > 0 )
       
   230               {
       
   231                 $particles = implode(', ', $particles);
       
   232                 $page_id_db = $db->escape($page_id);
       
   233                 $namespace_db = $db->escape($namespace);
       
   234                 $sql = 'UPDATE ' . table_prefix . "pages SET $particles WHERE urlname = '$page_id_db' AND namespace = '$namespace_db';";
       
   235                 
       
   236                 if ( !$db->sql_query($sql) )
       
   237                   $db->_die('PageManager running primary update query');
       
   238                 
       
   239                 // Did we change the page ID or namespace? If so we need to also change logs, comments, tags, etc.
       
   240                 if ( $page_id_changed || $namespace_changed )
       
   241                 {
       
   242                   $sql = array(
       
   243                       'UPDATE ' . table_prefix . "logs SET page_id = '$page_id_new', namespace = '$namespace_new' WHERE page_id = '$page_id_db' AND namespace = '$namespace_db';",
       
   244                       'UPDATE ' . table_prefix . "tags SET page_id = '$page_id_new', namespace = '$namespace_new' WHERE page_id = '$page_id_db' AND namespace = '$namespace_db';",
       
   245                       'UPDATE ' . table_prefix . "comments SET page_id = '$page_id_new', namespace = '$namespace_new' WHERE page_id = '$page_id_db' AND namespace = '$namespace_db';",
       
   246                       'UPDATE ' . table_prefix . "page_text SET page_id = '$page_id_new', namespace = '$namespace_new' WHERE page_id = '$page_id_db' AND namespace = '$namespace_db';",
       
   247                       'UPDATE ' . table_prefix . "categories SET page_id = '$page_id_new', namespace = '$namespace_new' WHERE page_id = '$page_id_db' AND namespace = '$namespace_db';"
       
   248                     );
       
   249                   foreach ( $sql as $q )
       
   250                   {
       
   251                     if ( !$db->sql_query($q) )
       
   252                       $db->_die('PageManager running slave update query after page ID/namespace change');
       
   253                   }
       
   254                 }
       
   255                 
       
   256                 // Did we change the name of the page? If so, make PageUtils log it
       
   257                 if ( $dataset_backup['name'] != $dataset['name'] )
       
   258                 {
       
   259                   PageUtils::rename($page_id_new, $namespace_new, $dataset['name']);
       
   260                 }
       
   261               }
       
   262               
       
   263               // Did the user ask to delete the page?
       
   264               if ( isset($_POST['delete']) )
       
   265               {
       
   266                 PageUtils::deletepage($page_id_new, $namespace_new, $lang->get('acppm_delete_reason'));
       
   267               }
       
   268               
       
   269               echo '<div class="info-box">' . $lang->get('acppm_msg_save_success', array( 'viewpage_url' => makeUrlNS($dataset['namespace'], $dataset['urlname']) )) . '</div>';
       
   270               break 2;
       
   271             }
       
   272             
       
   273             break;
       
   274         }
       
   275         $tpl_code = <<<TPLCODE
       
   276         <div class="tblholder">
       
   277           <table border="0" cellspacing="1" cellpadding="4">
       
   278             <tr>
       
   279               <th colspan="2">
       
   280                 {lang:acppm_heading_editing} "{PAGE_NAME}"
       
   281               </th>
       
   282             </tr>
       
   283             
       
   284             <tr>
       
   285               <td class="row2">
       
   286                 {lang:acppm_lbl_page_name}
       
   287               </td>
       
   288               <td class="row1">
       
   289                 <input type="text" name="page_name" value="{PAGE_NAME}" size="40" />
       
   290               </td>
       
   291             </tr>
       
   292             
       
   293             <tr>
       
   294               <td class="row2">
       
   295                 {lang:acppm_lbl_page_urlname}<br />
       
   296                 <small>{lang:acppm_lbl_page_urlname_hint}</small>
       
   297               </td>
       
   298               <td class="row1">
       
   299                 <input type="text" name="page_urlname" value="{PAGE_URLNAME}" size="40" />
       
   300               </td>
       
   301             </tr>
       
   302             
       
   303             <tr>
       
   304               <td class="row2">
       
   305                 {lang:acppm_lbl_namespace}
       
   306               </td>
       
   307               <td class="row1">
       
   308                 <select name="page_namespace">
       
   309                 {NAMESPACE_LIST}</select>
       
   310               </td>
       
   311             </tr>
       
   312             
       
   313             <tr>
       
   314               <th colspan="2" class="subhead">
       
   315                 {lang:acppm_heading_advanced}
       
   316               </th>
       
   317             </tr>
       
   318             
       
   319             <tr>
       
   320               <td class="row2">
       
   321                 {lang:acppm_lbl_enable_comments_title}
       
   322               </td>
       
   323               <td class="row1">
       
   324                 <label>
       
   325                   <input type="checkbox" name="comments_on" <!-- BEGIN comments_enabled -->checked="checked" <!-- END comments_enabled -->/>
       
   326                   {lang:acppm_lbl_enable_comments}
       
   327                 </label>
       
   328                 <br />
       
   329                 <small>{lang:acppm_lbl_enable_comments_hint}</small>
       
   330               </td>
       
   331             </tr>
       
   332             
       
   333             <tr>
       
   334               <td class="row2">
       
   335                 {lang:acppm_lbl_special_title}
       
   336               </td>
       
   337               <td class="row1">
       
   338                 <label>
       
   339                   <input type="checkbox" name="special" <!-- BEGIN special -->checked="checked" <!-- END special -->/>
       
   340                   {lang:acppm_lbl_special}
       
   341                 </label>
       
   342                 <br />
       
   343                 <small>{lang:acppm_lbl_special_hint}</small>
       
   344               </td>
       
   345             </tr>
       
   346             
       
   347             <tr>
       
   348               <td class="row2">
       
   349                 {lang:acppm_lbl_visible_title}
       
   350               </td>
       
   351               <td class="row1">
       
   352                 <label>
       
   353                   <input type="checkbox" name="visible" <!-- BEGIN visible -->checked="checked" <!-- END visible -->/>
       
   354                   {lang:acppm_lbl_visible}
       
   355                 </label>
       
   356                 <br />
       
   357                 <small>{lang:acppm_lbl_visible_hint}</small>
       
   358               </td>
       
   359             </tr>
       
   360             
       
   361             <tr>
       
   362               <td class="row2">
       
   363                 {lang:acppm_lbl_protected_title}
       
   364               </td>
       
   365               <td class="row1">
       
   366                 <label>
       
   367                   <input type="radio" name="protected" value="0" <!-- BEGIN protected_off -->checked="checked" <!-- END protected_off -->/>
       
   368                   {lang:acppm_lbl_protected_off}
       
   369                 </label>
       
   370                 <br />
       
   371                 <label>
       
   372                   <input type="radio" name="protected" value="1" <!-- BEGIN protected_on -->checked="checked" <!-- END protected_on -->/>
       
   373                   {lang:acppm_lbl_protected_on}
       
   374                 </label>
       
   375                 <br />
       
   376                 <label>
       
   377                   <input type="radio" name="protected" value="2" <!-- BEGIN protected_semi -->checked="checked" <!-- END protected_semi -->/>
       
   378                   {lang:acppm_lbl_protected_semi}
       
   379                 </label>
       
   380                 <br />
       
   381                 <small>{lang:acppm_lbl_protected_hint}</small>
       
   382               </td>
       
   383             </tr>
       
   384             
       
   385             <tr>
       
   386               <td class="row2">
       
   387                 {lang:acppm_lbl_wikimode_title}
       
   388               </td>
       
   389               <td class="row1">
       
   390                 <label>
       
   391                   <input type="radio" name="wikimode" value="0" <!-- BEGIN wikimode_off -->checked="checked" <!-- END wikimode_off -->/>
       
   392                   {lang:acppm_lbl_wikimode_off}
       
   393                 </label>
       
   394                 <br />
       
   395                 <label>
       
   396                   <input type="radio" name="wikimode" value="1" <!-- BEGIN wikimode_on -->checked="checked" <!-- END wikimode_on -->/>
       
   397                   {lang:acppm_lbl_wikimode_on}
       
   398                 </label>
       
   399                 <br />
       
   400                 <label>
       
   401                   <input type="radio" name="wikimode" value="2" <!-- BEGIN wikimode_global -->checked="checked" <!-- END wikimode_global -->/>
       
   402                   {lang:acppm_lbl_wikimode_global}
       
   403                 </label>
       
   404                 <br />
       
   405                 <small>{lang:acppm_lbl_wikimode_hint}</small>
       
   406               </td>
       
   407             </tr>
       
   408             
       
   409             <tr>
       
   410               <td class="row2">
       
   411                 {lang:acppm_lbl_delete_title}
       
   412               </td>
       
   413               <td class="row1">
       
   414                 <label>
       
   415                   <input type="checkbox" name="delete" />
       
   416                   {lang:acppm_lbl_delete}
       
   417                 </label>
       
   418                 <br />
       
   419                 <small>{lang:acppm_lbl_delete_hint}</small>
       
   420               </td>
       
   421             </tr>
       
   422             
       
   423             <tr>
       
   424               <th colspan="2" class="subhead">
       
   425                 <button name="action" value="save">
       
   426                   <b>{lang:etc_save_changes}</b>
       
   427                 </button>
       
   428                 <button name="action" value="nil">
       
   429                   <b>{lang:etc_cancel}</b>
       
   430                 </button>
       
   431               </th>
       
   432             </tr>
       
   433             
       
   434           </table>
       
   435         </div>
       
   436         
       
   437         <input type="hidden" name="page_id" value="{PATHS_KEY}" />
       
   438 TPLCODE;
       
   439         $parser = $template->makeParserText($tpl_code);
       
   440         
       
   441         $ns_list = '';
       
   442         foreach ( $paths->nslist as $ns => $prefix ) 
       
   443         {
       
   444           // FIXME: Plugins need to specify whether they want Enano's regular PageProcessor
       
   445           // to handle these pages, and whether such pages from namespaces created by plugins
       
   446           // can be stored in the database or not.
       
   447           if ( $ns == 'Special' || $ns == 'Admin' || $ns == 'Anonymous' )
       
   448             continue;
       
   449           $ns = htmlspecialchars($ns);
       
   450           $prefix = htmlspecialchars($prefix);
       
   451           if ( empty($prefix) )
       
   452             $prefix = $lang->get('acppm_ns_article');
       
   453           $sel = ( $dataset['namespace'] == $ns ) ? ' selected="selected"' : '';
       
   454           $ns_list .= "  <option value=\"$ns\"$sel>$prefix</option>\n                ";
       
   455         }
       
   456         
       
   457         $parser->assign_vars(array(
       
   458             'PAGE_NAME' => htmlspecialchars($dataset['name']),
       
   459             'PAGE_URLNAME' => htmlspecialchars($dataset['urlname']),
       
   460             'NAMESPACE_LIST' => $ns_list,
       
   461             'PATHS_KEY' => $pathskey
       
   462           ));
       
   463         
       
   464         $parser->assign_bool(array(
       
   465             'comments_enabled' => ( $dataset['comments_on'] == 1 ),
       
   466             'special' => ( $dataset['special'] == 1 ),
       
   467             'visible' => ( $dataset['visible'] == 1 ),
       
   468             'protected_off'   => ( $dataset['protected'] == 0 ),
       
   469             'protected_on'    => ( $dataset['protected'] == 1 ),
       
   470             'protected_semi'  => ( $dataset['protected'] == 2 ),
       
   471             'wikimode_off'    => ( $dataset['wiki_mode'] == 0 ),
       
   472             'wikimode_on'     => ( $dataset['wiki_mode'] == 1 ),
       
   473             'wikimode_global' => ( $dataset['wiki_mode'] == 2 )
       
   474           ));
       
   475         
       
   476         if ( isset($errors) )
       
   477         {
       
   478           echo '<div class="error-box">';
       
   479           echo $lang->get('acppm_err_header');
       
   480           echo '<ul>';
       
   481           echo '<li>' . implode('</li><li>', $errors) . '</li>';
       
   482           echo '</ul>';
       
   483           echo '</div>';
       
   484         }
       
   485         
       
   486         $form_action = makeUrlNS('Special', 'Administration', "module={$paths->nslist['Admin']}PageManager", true);
       
   487         
       
   488         echo "<form action=\"$form_action\" method=\"post\">";
       
   489         echo $parser->run();
       
   490         echo "</form>";
       
   491         
       
   492         $show_select = false;
       
   493         break;
       
   494     }
       
   495   }
       
   496   
       
   497   if ( $show_select )
       
   498   {
       
   499     echo '<p>' . $lang->get('acppm_hint') . '</p>';
       
   500     
       
   501     // Show the search form
       
   502     
       
   503     $form_action = makeUrlNS('Special', 'Administration', "module={$paths->nslist['Admin']}PageManager", true);
       
   504     echo "<form action=\"$form_action\" method=\"post\">";
       
   505     echo $lang->get('acppm_lbl_field_search') . ' ';
       
   506     echo $template->pagename_field('page_id') . ' ';
       
   507     echo '<input type="hidden" name="action" value="select" />';
       
   508     echo '<input type="submit" name="pid_search" value="' . $lang->get('search_btn_search') . '" />';
       
   509     echo "</form>";
       
   510     
       
   511     // Grab all pages from the database and show a list of pages on the site
       
   512     
       
   513     echo '<h3>' . $lang->get('acppm_heading_select_page_from_list') . '</h3>';
       
   514     echo '<p>' . $lang->get('acppm_hint_select_page_from_list') . '</p>';
       
   515     
       
   516     $q = $db->sql_query('SELECT COUNT(name) AS num_pages FROM ' . table_prefix . 'pages;');
       
   517     if ( !$q )
       
   518       $db->_die('PageManager doing initial page count');
       
   519     list($num_pages) = $db->fetchrow_num();
       
   520     $db->free_result();
       
   521     
       
   522     $pg_start = ( isset($_GET['offset']) ) ? intval($_GET['offset']) : 0;
       
   523     
       
   524     $q = $db->sql_unbuffered_query('SELECT urlname, name, namespace, ' . $num_pages . ' AS num_pages, ' . $pg_start . ' AS offset FROM ' . table_prefix . 'pages ORDER BY name ASC;');
       
   525     if ( !$q )
       
   526       $db->_die('PageManager doing main select query for page list');
       
   527     
       
   528     // Paginate results
       
   529     $html = paginate(
       
   530         $q,
       
   531         '{urlname}',
       
   532         $num_pages,
       
   533         makeUrlNS('Special', 'Administration', "module={$paths->nslist['Admin']}PageManager&offset=%s", false),
       
   534         $pg_start,
       
   535         99,
       
   536         array('urlname' => 'admin_pagemanager_format_listing'),
       
   537         '<div class="tblholder" style="height: 300px; clip: rect(0px, auto, auto, 0px); overflow: auto;">
       
   538         <table border="0" cellspacing="1" cellpadding="4">',
       
   539         '  </table>
       
   540          </div>'
       
   541       );
       
   542     echo $html;
       
   543   }
       
   544   
       
   545 }
       
   546 
       
   547 function admin_pagemanager_format_listing($_, $row)
       
   548 {
       
   549   global $db, $session, $paths, $template, $plugins; // Common objects
       
   550   
       
   551   static $cell_count = 0;
       
   552   static $td_class = 'row1';
       
   553   static $run_count = 0;
       
   554   static $num_pages_floor = false;
       
   555   if ( !$num_pages_floor )
       
   556   {
       
   557     $num_pages_floor = $row['num_pages'];
       
   558     while ( $num_pages_floor % 99 > 0 )
       
   559       $num_pages_floor--;
       
   560   }
       
   561   $return = '';
       
   562   $run_count++;
       
   563   
       
   564   $last_page = ( $row['offset'] == $num_pages_floor );
       
   565   $last_run = ( ( $last_page && $run_count == $row['num_pages'] % 99 ) || $run_count == 99 );
       
   566   if ( $cell_count == 0 )
       
   567   {
       
   568     $return .= "<tr>\n";
       
   569   }
       
   570   $title = get_page_title_ns($row['urlname'], $row['namespace']);
       
   571   $pathskey = $paths->nslist[$row['namespace']] . $row['urlname'];
       
   572   $url = makeUrlNS('Special', 'Administration', "module={$paths->nslist['Admin']}PageManager&action=select&page_id=$pathskey", true);
       
   573   $url = '<a href="' . $url . '">' . htmlspecialchars($title) . '</a>';
       
   574   $return .= '  <td class="' . $td_class . '" style="width: 33%;">' . $url . '</td>' . "\n";
       
   575   $cell_count++;
       
   576   if ( $cell_count == 3 && !$last_run )
       
   577   {
       
   578     $cell_count = 0;
       
   579     $td_class = ( $td_class == 'row2' ) ? 'row1' : 'row2';
       
   580     $return .= "</tr>\n";
       
   581   }
       
   582   else if ( $last_run )
       
   583   {
       
   584     while ( $cell_count < 3 )
       
   585     {
       
   586       $return .= "  <td class=\"{$td_class}\"></td>\n";
       
   587       $cell_count++;
       
   588     }
       
   589     $return .= "</tr>\n";
       
   590   }
       
   591   return $return;
       
   592 }
       
   593 
       
   594 ?>