ajax.php
changeset 1227 bdac73ed481e
parent 1175 1e2c9819ede3
child 1252 e34c23a35dc9
equal deleted inserted replaced
1226:de56132c008d 1227:bdac73ed481e
     9  *
     9  *
    10  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
    10  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
    11  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
    11  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
    12  */
    12  */
    13  
    13  
    14   define('ENANO_INTERFACE_AJAX', '');
    14 define('ENANO_INTERFACE_AJAX', '');
    15  
    15 
    16   require('includes/common.php');
    16 require('includes/common.php');
    17   
    17 
    18   global $db, $session, $paths, $template, $plugins; // Common objects
    18 global $db, $session, $paths, $template, $plugins; // Common objects
    19   if(!isset($_GET['_mode'])) die('This script cannot be accessed directly.');
    19 if(!isset($_GET['_mode'])) die('This script cannot be accessed directly.');
    20   
    20 
    21   $_ob = '';
    21 $_ob = '';
    22   
    22 
    23   switch($_GET['_mode']) {
    23 switch($_GET['_mode']) {
    24     case "checkusername":
    24 	case "checkusername":
    25       require_once(ENANO_ROOT.'/includes/pageutils.php');
    25 		require_once(ENANO_ROOT.'/includes/pageutils.php');
    26       echo PageUtils::checkusername($_GET['name']);
    26 		echo PageUtils::checkusername($_GET['name']);
    27       break;
    27 		break;
    28     case "getsource":
    28 	case "getsource":
    29       header('Content-type: text/plain');
    29 		header('Content-type: text/plain');
    30       $password = ( isset($_GET['pagepass']) ) ? $_GET['pagepass'] : false;
    30 		$password = ( isset($_GET['pagepass']) ) ? $_GET['pagepass'] : false;
    31       $revid = ( isset($_GET['revid']) ) ? intval($_GET['revid']) : 0;
    31 		$revid = ( isset($_GET['revid']) ) ? intval($_GET['revid']) : 0;
    32       $page = new PageProcessor($paths->page_id, $paths->namespace, $revid);
    32 		$page = new PageProcessor($paths->page_id, $paths->namespace, $revid);
    33       $page->password = $password;
    33 		$page->password = $password;
    34       
    34 		
    35       $have_draft = false;
    35 		$have_draft = false;
    36       // Kinda hacky fix for issue 7: draft restore not offered for nonexistent pages
    36 		// Kinda hacky fix for issue 7: draft restore not offered for nonexistent pages
    37       if ( ($src = $page->fetch_source()) || !$page->exists() )
    37 		if ( ($src = $page->fetch_source()) || !$page->exists() )
    38       {
    38 		{
    39         $allowed = true;
    39 			$allowed = true;
    40         $q = $db->sql_query('SELECT author, time_id, page_text, edit_summary, page_format FROM ' . table_prefix . 'logs WHERE log_type = \'page\' AND action = \'edit\'
    40 			$q = $db->sql_query('SELECT author, time_id, page_text, edit_summary, page_format FROM ' . table_prefix . 'logs WHERE log_type = \'page\' AND action = \'edit\'
    41                                AND page_id = \'' . $db->escape($paths->page_id) . '\'
    41 														AND page_id = \'' . $db->escape($paths->page_id) . '\'
    42                                AND namespace = \'' . $db->escape($paths->namespace) . '\'
    42 														AND namespace = \'' . $db->escape($paths->namespace) . '\'
    43                                AND is_draft = 1;');
    43 														AND is_draft = 1;');
    44         if ( !$q )
    44 			if ( !$q )
    45           $db->die_json();
    45 				$db->die_json();
    46         
    46 			
    47         if ( $db->numrows() > 0 )
    47 			if ( $db->numrows() > 0 )
    48         {
    48 			{
    49           $have_draft = true;
    49 				$have_draft = true;
    50           $draft_row = $db->fetchrow($q);
    50 				$draft_row = $db->fetchrow($q);
    51         }
    51 			}
    52       }
    52 		}
    53       else if ( $src !== false )
    53 		else if ( $src !== false )
    54       {
    54 		{
    55         $allowed = true;
    55 			$allowed = true;
    56         $src = '';
    56 			$src = '';
    57       }
    57 		}
    58       else
    58 		else
    59       {
    59 		{
    60         $allowed = false;
    60 			$allowed = false;
    61         $src = '';
    61 			$src = '';
    62       }
    62 		}
    63       
    63 		
    64       $auth_edit = ( $session->get_permissions('edit_page') && ( $session->get_permissions('even_when_protected') || !$page->ns->page_protected ) );
    64 		$auth_edit = ( $session->get_permissions('edit_page') && ( $session->get_permissions('even_when_protected') || !$page->ns->page_protected ) );
    65       $auth_wysiwyg = ( $session->get_permissions('edit_wysiwyg') );
    65 		$auth_wysiwyg = ( $session->get_permissions('edit_wysiwyg') );
    66       
    66 		
    67       $return = array(
    67 		$return = array(
    68           'mode' => 'editor',
    68 				'mode' => 'editor',
    69           'src' => $src,
    69 				'src' => $src,
    70           'auth_view_source' => $allowed,
    70 				'auth_view_source' => $allowed,
    71           'auth_edit' => $auth_edit,
    71 				'auth_edit' => $auth_edit,
    72           'time' => time(),
    72 				'time' => time(),
    73           'require_captcha' => false,
    73 				'require_captcha' => false,
    74           'allow_wysiwyg' => $auth_wysiwyg,
    74 				'allow_wysiwyg' => $auth_wysiwyg,
    75           'revid' => $revid,
    75 				'revid' => $revid,
    76           'have_draft' => false
    76 				'have_draft' => false
    77         );
    77 			);
    78       
    78 		
    79       $return['page_format'] = $page->ns->cdata['page_format'];
    79 		$return['page_format'] = $page->ns->cdata['page_format'];
    80       if ( $return['page_format'] == 'xhtml' )
    80 		if ( $return['page_format'] == 'xhtml' )
    81       {
    81 		{
    82         // gently process headings to make tinymce format them correctly
    82 			// gently process headings to make tinymce format them correctly
    83         if ( preg_match_all('/^ *?(={1,6}) *(.+?) *\\1 *$/m', $return['src'], $matches) )
    83 			if ( preg_match_all('/^ *?(={1,6}) *(.+?) *\\1 *$/m', $return['src'], $matches) )
    84         {
    84 			{
    85           foreach ( $matches[0] as $i => $match )
    85 				foreach ( $matches[0] as $i => $match )
    86           {
    86 				{
    87             $hi = strlen($matches[1][$i]);
    87 					$hi = strlen($matches[1][$i]);
    88             $heading = "<h{$hi}>{$matches[2][$i]}</h{$hi}>";
    88 					$heading = "<h{$hi}>{$matches[2][$i]}</h{$hi}>";
    89             $return['src'] = str_replace_once($match, $heading, $return['src']);
    89 					$return['src'] = str_replace_once($match, $heading, $return['src']);
    90           }
    90 				}
    91         }
    91 			}
    92       }
    92 		}
    93       
    93 		
    94       if ( $have_draft )
    94 		if ( $have_draft )
    95       {
    95 		{
    96         $row =& $draft_row;
    96 			$row =& $draft_row;
    97         $return['have_draft'] = true;
    97 			$return['have_draft'] = true;
    98         $return['draft_author'] = $row['author'];
    98 			$return['draft_author'] = $row['author'];
    99         $return['draft_time'] = enano_date(ED_DATE | ED_TIME, intval($row['time_id']));
    99 			$return['draft_time'] = enano_date(ED_DATE | ED_TIME, intval($row['time_id']));
   100         if ( isset($_GET['get_draft']) && @$_GET['get_draft'] === '1' )
   100 			if ( isset($_GET['get_draft']) && @$_GET['get_draft'] === '1' )
   101         {
   101 			{
   102           $return['src'] = $row['page_text'];
   102 				$return['src'] = $row['page_text'];
   103           $return['edit_summary'] = $row['edit_summary'];
   103 				$return['edit_summary'] = $row['edit_summary'];
   104           $return['page_format'] = $row['page_format'];
   104 				$return['page_format'] = $row['page_format'];
   105         }
   105 			}
   106       }
   106 		}
   107       
   107 		
   108       $return['undo_info'] = array();
   108 		$return['undo_info'] = array();
   109       
   109 		
   110       if ( $revid > 0 )
   110 		if ( $revid > 0 )
   111       {
   111 		{
   112         // Retrieve information about this revision and the current one
   112 			// Retrieve information about this revision and the current one
   113         $q = $db->sql_query('SELECT l1.author AS currentrev_author, l2.author AS oldrev_author FROM ' . table_prefix . 'logs AS l1
   113 			$q = $db->sql_query('SELECT l1.author AS currentrev_author, l2.author AS oldrev_author FROM ' . table_prefix . 'logs AS l1
   114   LEFT JOIN ' . table_prefix . 'logs AS l2
   114 LEFT JOIN ' . table_prefix . 'logs AS l2
   115     ON ( l2.log_id = ' . $revid . '
   115 	ON ( l2.log_id = ' . $revid . '
   116          AND l2.log_type  = \'page\'
   116 			AND l2.log_type  = \'page\'
   117          AND l2.action    = \'edit\'
   117 			AND l2.action    = \'edit\'
   118          AND l2.page_id   = \'' . $db->escape($paths->page_id)   . '\'
   118 			AND l2.page_id   = \'' . $db->escape($paths->page_id)   . '\'
   119          AND l2.namespace = \'' . $db->escape($paths->namespace) . '\'
   119 			AND l2.namespace = \'' . $db->escape($paths->namespace) . '\'
   120          AND l2.is_draft != 1
   120 			AND l2.is_draft != 1
   121         )
   121 			)
   122   WHERE l1.log_type  = \'page\'
   122 WHERE l1.log_type  = \'page\'
   123     AND l1.action    = \'edit\'
   123 	AND l1.action    = \'edit\'
   124     AND l1.page_id   = \'' . $db->escape($paths->page_id)   . '\'
   124 	AND l1.page_id   = \'' . $db->escape($paths->page_id)   . '\'
   125     AND l1.namespace = \'' . $db->escape($paths->namespace) . '\'
   125 	AND l1.namespace = \'' . $db->escape($paths->namespace) . '\'
   126     AND l1.time_id   > ' . $page->revision_time . '
   126 	AND l1.time_id   > ' . $page->revision_time . '
   127     AND l1.is_draft != 1
   127 	AND l1.is_draft != 1
   128   ORDER BY l1.time_id DESC;');
   128 ORDER BY l1.time_id DESC;');
   129         if ( !$q )
   129 			if ( !$q )
   130           $db->die_json();
   130 				$db->die_json();
   131         
   131 			
   132         if ( $db->numrows() > 0 )
   132 			if ( $db->numrows() > 0 )
   133         {
   133 			{
   134           $rev_count = $db->numrows() - 1;
   134 				$rev_count = $db->numrows() - 1;
   135           if ( $rev_count == -1 )
   135 				if ( $rev_count == -1 )
   136           {
   136 				{
   137             $return = array(
   137 					$return = array(
   138                 'mode' => 'error',
   138 							'mode' => 'error',
   139                 'error' => '[Internal] No rows returned by revision info query. SQL:<pre>' . $db->latest_query . '</pre>'
   139 							'error' => '[Internal] No rows returned by revision info query. SQL:<pre>' . $db->latest_query . '</pre>'
   140               );
   140 						);
   141           }
   141 				}
   142           else
   142 				else
   143           {
   143 				{
   144             $row = $db->fetchrow();
   144 					$row = $db->fetchrow();
   145             $return['undo_info'] = array(
   145 					$return['undo_info'] = array(
   146               'old_author'     => $row['oldrev_author'],
   146 						'old_author'     => $row['oldrev_author'],
   147               'current_author' => $row['currentrev_author'],
   147 						'current_author' => $row['currentrev_author'],
   148               'undo_count'     => $rev_count
   148 						'undo_count'     => $rev_count
   149             );
   149 					);
   150           }
   150 				}
   151         }
   151 			}
   152         else
   152 			else
   153         {
   153 			{
   154           $return['revid'] = $revid = 0;
   154 				$return['revid'] = $revid = 0;
   155         }
   155 			}
   156       }
   156 		}
   157       
   157 		
   158       if ( $auth_edit && !$session->user_logged_in && getConfig('guest_edit_require_captcha') == '1' )
   158 		if ( $auth_edit && !$session->user_logged_in && getConfig('guest_edit_require_captcha') == '1' )
   159       {
   159 		{
   160         $return['require_captcha'] = true;
   160 			$return['require_captcha'] = true;
   161         $return['captcha_id'] = $session->make_captcha();
   161 			$return['captcha_id'] = $session->make_captcha();
   162       }
   162 		}
   163       
   163 		
   164       $template->load_theme();
   164 		$template->load_theme();
   165       $return['toolbar_templates'] = $template->extract_vars('toolbar.tpl');
   165 		$return['toolbar_templates'] = $template->extract_vars('toolbar.tpl');
   166       $return['edit_notice'] = $template->get_wiki_edit_notice();
   166 		$return['edit_notice'] = $template->get_wiki_edit_notice();
   167       
   167 		
   168       echo enano_json_encode($return);
   168 		echo enano_json_encode($return);
   169       break;
   169 		break;
   170     case "getpage":
   170 	case "getpage":
   171       // echo PageUtils::getpage($paths->page, false, ( (isset($_GET['oldid'])) ? $_GET['oldid'] : false ));
   171 		// echo PageUtils::getpage($paths->page, false, ( (isset($_GET['oldid'])) ? $_GET['oldid'] : false ));
   172       $output = new Output_Striptease();
   172 		$output = new Output_Striptease();
   173       
   173 		
   174       $revision_id = ( (isset($_GET['oldid'])) ? intval($_GET['oldid']) : 0 );
   174 		$revision_id = ( (isset($_GET['oldid'])) ? intval($_GET['oldid']) : 0 );
   175       $page = new PageProcessor( $paths->page_id, $paths->namespace, $revision_id );
   175 		$page = new PageProcessor( $paths->page_id, $paths->namespace, $revision_id );
   176       
   176 		
   177       $pagepass = ( isset($_REQUEST['pagepass']) ) ? $_REQUEST['pagepass'] : '';
   177 		$pagepass = ( isset($_REQUEST['pagepass']) ) ? $_REQUEST['pagepass'] : '';
   178       $page->password = $pagepass;
   178 		$page->password = $pagepass;
   179       $page->allow_redir = ( !isset($_GET['redirect']) || (isset($_GET['redirect']) && $_GET['redirect'] !== 'no') );
   179 		$page->allow_redir = ( !isset($_GET['redirect']) || (isset($_GET['redirect']) && $_GET['redirect'] !== 'no') );
   180             
   180 					
   181       $page->send();
   181 		$page->send();
   182       break;
   182 		break;
   183     case "savepage":
   183 	case "savepage":
   184       /* **** OBSOLETE **** */
   184 		/* **** OBSOLETE **** */
   185       
   185 		
   186       break;
   186 		break;
   187     case "savepage_json":
   187 	case "savepage_json":
   188       header('Content-type: application/json');
   188 		header('Content-type: application/json');
   189       if ( !isset($_POST['r']) )
   189 		if ( !isset($_POST['r']) )
   190         die('Invalid request');
   190 			die('Invalid request');
   191       
   191 		
   192       try
   192 		try
   193       {
   193 		{
   194         $request = enano_json_decode($_POST['r']);
   194 			$request = enano_json_decode($_POST['r']);
   195         if ( !isset($request['src']) || !isset($request['summary']) || !isset($request['minor_edit']) || !isset($request['time']) || !isset($request['draft']) )
   195 			if ( !isset($request['src']) || !isset($request['summary']) || !isset($request['minor_edit']) || !isset($request['time']) || !isset($request['draft']) )
   196           die('Invalid request');
   196 				die('Invalid request');
   197       }
   197 		}
   198       catch(Zend_Json_Exception $e)
   198 		catch(Zend_Json_Exception $e)
   199       {
   199 		{
   200         die("JSON parsing failed. View as HTML to see full report.\n<br /><br />\n<pre>" . htmlspecialchars(strval($e)) . "</pre><br />Request: <pre>" . htmlspecialchars($_POST['r']) . "</pre>");
   200 			die("JSON parsing failed. View as HTML to see full report.\n<br /><br />\n<pre>" . htmlspecialchars(strval($e)) . "</pre><br />Request: <pre>" . htmlspecialchars($_POST['r']) . "</pre>");
   201       }
   201 		}
   202       
   202 		
   203       $time = intval($request['time']);
   203 		$time = intval($request['time']);
   204       
   204 		
   205       if ( $request['draft'] )
   205 		if ( $request['draft'] )
   206       {
   206 		{
   207         //
   207 			//
   208         // The user wants to save a draft version of the page.
   208 			// The user wants to save a draft version of the page.
   209         //
   209 			//
   210         
   210 			
   211         // Validate permissions
   211 			// Validate permissions
   212         if ( !$session->get_permissions('edit_page') )
   212 			if ( !$session->get_permissions('edit_page') )
   213         {
   213 			{
   214           $return = array(
   214 				$return = array(
   215             'mode' => 'error',
   215 					'mode' => 'error',
   216             'error' => 'access_denied'
   216 					'error' => 'access_denied'
   217           );
   217 				);
   218         }
   218 			}
   219         else
   219 			else
   220         {
   220 			{
   221           // Delete any draft copies if they exist
   221 				// Delete any draft copies if they exist
   222           $q = $db->sql_query('DELETE FROM ' . table_prefix . 'logs WHERE log_type = \'page\' AND action = \'edit\'
   222 				$q = $db->sql_query('DELETE FROM ' . table_prefix . 'logs WHERE log_type = \'page\' AND action = \'edit\'
   223                                  AND page_id = \'' . $db->escape($paths->page_id) . '\'
   223 															AND page_id = \'' . $db->escape($paths->page_id) . '\'
   224                                  AND namespace = \'' . $db->escape($paths->namespace) . '\'
   224 															AND namespace = \'' . $db->escape($paths->namespace) . '\'
   225                                  AND is_draft = 1;');
   225 															AND is_draft = 1;');
   226           if ( !$q )
   226 				if ( !$q )
   227             $db->die_json();
   227 					$db->die_json();
   228           
   228 				
   229           // are we just supposed to delete the draft?
   229 				// are we just supposed to delete the draft?
   230           if ( $request['src'] === -1 )
   230 				if ( $request['src'] === -1 )
   231           {
   231 				{
   232             $return = array(
   232 					$return = array(
   233               'mode' => 'success',
   233 						'mode' => 'success',
   234               'is_draft' => 'delete'
   234 						'is_draft' => 'delete'
   235             );
   235 					);
   236           }
   236 				}
   237           else
   237 				else
   238           {
   238 				{
   239             $src = RenderMan::preprocess_text($request['src'], false, false);
   239 					$src = RenderMan::preprocess_text($request['src'], false, false);
   240             $draft_format = $request['format'];
   240 					$draft_format = $request['format'];
   241             if ( !in_array($draft_format, array('xhtml', 'wikitext')) )
   241 					if ( !in_array($draft_format, array('xhtml', 'wikitext')) )
   242             {
   242 					{
   243               $return = array(
   243 						$return = array(
   244                 'mode' => 'error',
   244 							'mode' => 'error',
   245                 'error' => 'invalid_format'
   245 							'error' => 'invalid_format'
   246               );
   246 						);
   247             }
   247 					}
   248             else
   248 					else
   249             {
   249 					{
   250               // Save the draft
   250 						// Save the draft
   251               $q = $db->sql_query('INSERT INTO ' . table_prefix . 'logs ( log_type, action, page_id, namespace, author, author_uid, edit_summary, page_text, is_draft, time_id, page_format )
   251 						$q = $db->sql_query('INSERT INTO ' . table_prefix . 'logs ( log_type, action, page_id, namespace, author, author_uid, edit_summary, page_text, is_draft, time_id, page_format )
   252                                      VALUES (
   252 												VALUES (
   253                                        \'page\',
   253 													\'page\',
   254                                        \'edit\',
   254 													\'edit\',
   255                                        \'' . $db->escape($paths->page_id) . '\',
   255 													\'' . $db->escape($paths->page_id) . '\',
   256                                        \'' . $db->escape($paths->namespace) . '\',
   256 													\'' . $db->escape($paths->namespace) . '\',
   257                                        \'' . $db->escape($session->username) . '\',
   257 													\'' . $db->escape($session->username) . '\',
   258                                        ' . $session->user_id . ',
   258 													' . $session->user_id . ',
   259                                        \'' . $db->escape($request['summary']) . '\',
   259 													\'' . $db->escape($request['summary']) . '\',
   260                                        \'' . $db->escape($src) . '\',
   260 													\'' . $db->escape($src) . '\',
   261                                        1,
   261 													1,
   262                                        ' . time() . ',
   262 													' . time() . ',
   263                                        \'' . $draft_format . '\'
   263 													\'' . $draft_format . '\'
   264                                      );');
   264 												);');
   265               
   265 						
   266               // Done!
   266 						// Done!
   267               $return = array(
   267 						$return = array(
   268                   'mode' => 'success',
   268 								'mode' => 'success',
   269                   'is_draft' => true
   269 								'is_draft' => true
   270                 );
   270 							);
   271             }
   271 					}
   272           }
   272 				}
   273         }
   273 			}
   274       }
   274 		}
   275       else
   275 		else
   276       {
   276 		{
   277         // Verify that no edits have been made since the editor was requested
   277 			// Verify that no edits have been made since the editor was requested
   278         $q = $db->sql_query('SELECT time_id, author FROM ' . table_prefix . "logs WHERE log_type = 'page' AND action = 'edit' AND page_id = '{$paths->page_id}' AND namespace = '{$paths->namespace}' AND is_draft != 1 ORDER BY time_id DESC LIMIT 1;");
   278 			$q = $db->sql_query('SELECT time_id, author FROM ' . table_prefix . "logs WHERE log_type = 'page' AND action = 'edit' AND page_id = '{$paths->page_id}' AND namespace = '{$paths->namespace}' AND is_draft != 1 ORDER BY time_id DESC LIMIT 1;");
   279         if ( !$q )
   279 			if ( !$q )
   280           $db->die_json();
   280 				$db->die_json();
   281         
   281 			
   282         $row = $db->fetchrow();
   282 			$row = $db->fetchrow();
   283         $db->free_result();
   283 			$db->free_result();
   284         
   284 			
   285         if ( $row['time_id'] > $time )
   285 			if ( $row['time_id'] > $time )
   286         {
   286 			{
   287           $return = array(
   287 				$return = array(
   288             'mode' => 'obsolete',
   288 					'mode' => 'obsolete',
   289             'author' => $row['author'],
   289 					'author' => $row['author'],
   290             'date_string' => enano_date(ED_DATE | ED_TIME, $row['time_id']),
   290 					'date_string' => enano_date(ED_DATE | ED_TIME, $row['time_id']),
   291             'time' => $row['time_id'] // time() ???
   291 					'time' => $row['time_id'] // time() ???
   292             );
   292 					);
   293           echo enano_json_encode($return);
   293 				echo enano_json_encode($return);
   294           break;
   294 				break;
   295         }
   295 			}
   296         
   296 			
   297         // Verify captcha, if needed
   297 			// Verify captcha, if needed
   298         if ( false && !$session->user_logged_in && getConfig('guest_edit_require_captcha') == '1' )
   298 			if ( false && !$session->user_logged_in && getConfig('guest_edit_require_captcha') == '1' )
   299         {
   299 			{
   300           if ( !isset($request['captcha_id']) || !isset($request['captcha_code']) )
   300 				if ( !isset($request['captcha_id']) || !isset($request['captcha_code']) )
   301           {
   301 				{
   302             die('Invalid request, need captcha metadata');
   302 					die('Invalid request, need captcha metadata');
   303           }
   303 				}
   304           $code_correct = strtolower($session->get_captcha($request['captcha_id']));
   304 				$code_correct = strtolower($session->get_captcha($request['captcha_id']));
   305           $code_input = strtolower($request['captcha_code']);
   305 				$code_input = strtolower($request['captcha_code']);
   306           if ( $code_correct !== $code_input )
   306 				if ( $code_correct !== $code_input )
   307           {
   307 				{
   308             $return = array(
   308 					$return = array(
   309               'mode' => 'errors',
   309 						'mode' => 'errors',
   310               'errors' => array($lang->get('editor_err_captcha_wrong')),
   310 						'errors' => array($lang->get('editor_err_captcha_wrong')),
   311               'new_captcha' => $session->make_captcha()
   311 						'new_captcha' => $session->make_captcha()
   312             );
   312 					);
   313             echo enano_json_encode($return);
   313 					echo enano_json_encode($return);
   314             break;
   314 					break;
   315           }
   315 				}
   316         }
   316 			}
   317         
   317 			
   318         // Verification complete. Start the PageProcessor and let it do the dirty work for us.
   318 			// Verification complete. Start the PageProcessor and let it do the dirty work for us.
   319         $page = new PageProcessor($paths->page_id, $paths->namespace);
   319 			$page = new PageProcessor($paths->page_id, $paths->namespace);
   320         if ( $page->update_page($request['src'], $request['summary'], ( $request['minor_edit'] == 1 ), $request['format']) )
   320 			if ( $page->update_page($request['src'], $request['summary'], ( $request['minor_edit'] == 1 ), $request['format']) )
   321         {
   321 			{
   322           $return = array(
   322 				$return = array(
   323               'mode' => 'success',
   323 						'mode' => 'success',
   324               'is_draft' => false
   324 						'is_draft' => false
   325             );
   325 					);
   326         }
   326 			}
   327         else
   327 			else
   328         {
   328 			{
   329           $errors = array();
   329 				$errors = array();
   330           while ( $err = $page->pop_error() )
   330 				while ( $err = $page->pop_error() )
   331           {
   331 				{
   332             $errors[] = $err;
   332 					$errors[] = $err;
   333           }
   333 				}
   334           $return = array(
   334 				$return = array(
   335             'mode' => 'errors',
   335 					'mode' => 'errors',
   336             'errors' => array_values($errors)
   336 					'errors' => array_values($errors)
   337             );
   337 					);
   338           if ( !$session->user_logged_in && getConfig('guest_edit_require_captcha') == '1' )
   338 				if ( !$session->user_logged_in && getConfig('guest_edit_require_captcha') == '1' )
   339           {
   339 				{
   340             $return['new_captcha'] = $session->make_captcha();
   340 					$return['new_captcha'] = $session->make_captcha();
   341           }
   341 				}
   342         }
   342 			}
   343       }
   343 		}
   344       
   344 		
   345       // If this is based on a draft version, delete the draft - we no longer need it.
   345 		// If this is based on a draft version, delete the draft - we no longer need it.
   346       if ( @$request['used_draft'] && !$request['draft'] )
   346 		if ( @$request['used_draft'] && !$request['draft'] )
   347       {
   347 		{
   348         $q = $db->sql_query('DELETE FROM ' . table_prefix . 'logs WHERE log_type = \'page\' AND action = \'edit\'
   348 			$q = $db->sql_query('DELETE FROM ' . table_prefix . 'logs WHERE log_type = \'page\' AND action = \'edit\'
   349                                AND page_id = \'' . $db->escape($paths->page_id) . '\'
   349 														AND page_id = \'' . $db->escape($paths->page_id) . '\'
   350                                AND namespace = \'' . $db->escape($paths->namespace) . '\'
   350 														AND namespace = \'' . $db->escape($paths->namespace) . '\'
   351                                AND is_draft = 1;');
   351 														AND is_draft = 1;');
   352       }
   352 		}
   353       
   353 		
   354       echo enano_json_encode($return);
   354 		echo enano_json_encode($return);
   355       
   355 		
   356       break;
   356 		break;
   357     case "diff_cur":
   357 	case "diff_cur":
   358       
   358 		
   359       // Lie about our content type to fool ad scripts
   359 		// Lie about our content type to fool ad scripts
   360       header('Content-type: application/xhtml+xml');
   360 		header('Content-type: application/xhtml+xml');
   361       
   361 		
   362       if ( !isset($_POST['text']) )
   362 		if ( !isset($_POST['text']) )
   363         die('Invalid request');
   363 			die('Invalid request');
   364       
   364 		
   365       $page = new PageProcessor($paths->page_id, $paths->namespace);
   365 		$page = new PageProcessor($paths->page_id, $paths->namespace);
   366       if ( !($src = $page->fetch_source()) )
   366 		if ( !($src = $page->fetch_source()) )
   367       {
   367 		{
   368         die('Access denied');
   368 			die('Access denied');
   369       }
   369 		}
   370       
   370 		
   371       $diff = RenderMan::diff($src, $_POST['text']);
   371 		$diff = RenderMan::diff($src, $_POST['text']);
   372       if ( $diff == '<table class="diff"></table>' )
   372 		if ( $diff == '<table class="diff"></table>' )
   373       {
   373 		{
   374         $diff = '<p>' . $lang->get('editor_msg_diff_empty') . '</p>';
   374 			$diff = '<p>' . $lang->get('editor_msg_diff_empty') . '</p>';
   375       }
   375 		}
   376       
   376 		
   377       echo '<div class="info-box">' . $lang->get('editor_msg_diff') . '</div>';
   377 		echo '<div class="info-box">' . $lang->get('editor_msg_diff') . '</div>';
   378       echo $diff;
   378 		echo $diff;
   379       
   379 		
   380       break;
   380 		break;
   381     case "protect":
   381 	case "protect":
   382       // echo PageUtils::protect($paths->page_id, $paths->namespace, (int)$_POST['level'], $_POST['reason']);
   382 		// echo PageUtils::protect($paths->page_id, $paths->namespace, (int)$_POST['level'], $_POST['reason']);
   383       
   383 		
   384       if ( @$_POST['reason'] === '__ROLLBACK__' )
   384 		if ( @$_POST['reason'] === '__ROLLBACK__' )
   385       {
   385 		{
   386         // __ROLLBACK__ is a keyword for log entries.
   386 			// __ROLLBACK__ is a keyword for log entries.
   387         die('"__ROLLBACK__" ain\'t gonna do it, buddy. Try to _not_ use reserved keywords next time, ok?');
   387 			die('"__ROLLBACK__" ain\'t gonna do it, buddy. Try to _not_ use reserved keywords next time, ok?');
   388       }
   388 		}
   389       
   389 		
   390       $page = new PageProcessor($paths->page_id, $paths->namespace);
   390 		$page = new PageProcessor($paths->page_id, $paths->namespace);
   391       header('Content-type: application/json');
   391 		header('Content-type: application/json');
   392       
   392 		
   393       $result = $page->protect_page(intval($_POST['level']), $_POST['reason']);
   393 		$result = $page->protect_page(intval($_POST['level']), $_POST['reason']);
   394       echo enano_json_encode($result);
   394 		echo enano_json_encode($result);
   395       break;
   395 		break;
   396     case "histlist":
   396 	case "histlist":
   397       require_once(ENANO_ROOT.'/includes/pageutils.php');
   397 		require_once(ENANO_ROOT.'/includes/pageutils.php');
   398       echo PageUtils::histlist($paths->page_id, $paths->namespace);
   398 		echo PageUtils::histlist($paths->page_id, $paths->namespace);
   399       break;
   399 		break;
   400     case "rollback":
   400 	case "rollback":
   401       $id = intval(@$_GET['id']);
   401 		$id = intval(@$_GET['id']);
   402       $page = new PageProcessor($paths->page_id, $paths->namespace);
   402 		$page = new PageProcessor($paths->page_id, $paths->namespace);
   403       header('Content-type: application/json');
   403 		header('Content-type: application/json');
   404       
   404 		
   405       $result = $page->rollback_log_entry($id);
   405 		$result = $page->rollback_log_entry($id);
   406       echo enano_json_encode($result);
   406 		echo enano_json_encode($result);
   407       break;
   407 		break;
   408     case "comments":
   408 	case "comments":
   409       require_once(ENANO_ROOT.'/includes/comment.php');
   409 		require_once(ENANO_ROOT.'/includes/comment.php');
   410       $comments = new Comments($paths->page_id, $paths->namespace);
   410 		$comments = new Comments($paths->page_id, $paths->namespace);
   411       if ( isset($_POST['data']) )
   411 		if ( isset($_POST['data']) )
   412       {
   412 		{
   413         $comments->process_json($_POST['data']);
   413 			$comments->process_json($_POST['data']);
   414       }
   414 		}
   415       else
   415 		else
   416       {
   416 		{
   417         die('{ "mode" : "error", "error" : "No input" }');
   417 			die('{ "mode" : "error", "error" : "No input" }');
   418       }
   418 		}
   419       break;
   419 		break;
   420     case "rename":
   420 	case "rename":
   421       $page = new PageProcessor($paths->page_id, $paths->namespace);
   421 		$page = new PageProcessor($paths->page_id, $paths->namespace);
   422       header('Content-type: application/json');
   422 		header('Content-type: application/json');
   423       
   423 		
   424       $result = $page->rename_page($_POST['newtitle']);
   424 		$result = $page->rename_page($_POST['newtitle']);
   425       echo enano_json_encode($result);
   425 		echo enano_json_encode($result);
   426       break;
   426 		break;
   427     case "flushlogs":
   427 	case "flushlogs":
   428       require_once(ENANO_ROOT.'/includes/pageutils.php');
   428 		require_once(ENANO_ROOT.'/includes/pageutils.php');
   429       echo PageUtils::flushlogs($paths->page_id, $paths->namespace);
   429 		echo PageUtils::flushlogs($paths->page_id, $paths->namespace);
   430       break;
   430 		break;
   431     case "deletepage":
   431 	case "deletepage":
   432       require_once(ENANO_ROOT.'/includes/pageutils.php');
   432 		require_once(ENANO_ROOT.'/includes/pageutils.php');
   433       $reason = ( isset($_POST['reason']) ) ? $_POST['reason'] : false;
   433 		$reason = ( isset($_POST['reason']) ) ? $_POST['reason'] : false;
   434       if ( empty($reason) )
   434 		if ( empty($reason) )
   435         die($lang->get('page_err_need_reason'));
   435 			die($lang->get('page_err_need_reason'));
   436       echo PageUtils::deletepage($paths->page_id, $paths->namespace, $reason);
   436 		echo PageUtils::deletepage($paths->page_id, $paths->namespace, $reason);
   437       break;
   437 		break;
   438     case "delvote":
   438 	case "delvote":
   439       require_once(ENANO_ROOT.'/includes/pageutils.php');
   439 		require_once(ENANO_ROOT.'/includes/pageutils.php');
   440       echo PageUtils::delvote($paths->page_id, $paths->namespace);
   440 		echo PageUtils::delvote($paths->page_id, $paths->namespace);
   441       break;
   441 		break;
   442     case "resetdelvotes":
   442 	case "resetdelvotes":
   443       require_once(ENANO_ROOT.'/includes/pageutils.php');
   443 		require_once(ENANO_ROOT.'/includes/pageutils.php');
   444       echo PageUtils::resetdelvotes($paths->page_id, $paths->namespace);
   444 		echo PageUtils::resetdelvotes($paths->page_id, $paths->namespace);
   445       break;
   445 		break;
   446     case "getstyles":
   446 	case "getstyles":
   447       require_once(ENANO_ROOT.'/includes/pageutils.php');
   447 		require_once(ENANO_ROOT.'/includes/pageutils.php');
   448       echo PageUtils::getstyles($_GET['id']);
   448 		echo PageUtils::getstyles($_GET['id']);
   449       break;
   449 		break;
   450     case "catedit":
   450 	case "catedit":
   451       require_once(ENANO_ROOT.'/includes/pageutils.php');
   451 		require_once(ENANO_ROOT.'/includes/pageutils.php');
   452       echo PageUtils::catedit($paths->page_id, $paths->namespace);
   452 		echo PageUtils::catedit($paths->page_id, $paths->namespace);
   453       break;
   453 		break;
   454     case "catsave":
   454 	case "catsave":
   455       require_once(ENANO_ROOT.'/includes/pageutils.php');
   455 		require_once(ENANO_ROOT.'/includes/pageutils.php');
   456       echo PageUtils::catsave($paths->page_id, $paths->namespace, $_POST);
   456 		echo PageUtils::catsave($paths->page_id, $paths->namespace, $_POST);
   457       break;
   457 		break;
   458     case "setwikimode":
   458 	case "setwikimode":
   459       require_once(ENANO_ROOT.'/includes/pageutils.php');
   459 		require_once(ENANO_ROOT.'/includes/pageutils.php');
   460       echo PageUtils::setwikimode($paths->page_id, $paths->namespace, (int)$_GET['mode']);
   460 		echo PageUtils::setwikimode($paths->page_id, $paths->namespace, (int)$_GET['mode']);
   461       break;
   461 		break;
   462     case "setpass":
   462 	case "setpass":
   463       require_once(ENANO_ROOT.'/includes/pageutils.php');
   463 		require_once(ENANO_ROOT.'/includes/pageutils.php');
   464       echo PageUtils::setpass($paths->page_id, $paths->namespace, $_POST['password']);
   464 		echo PageUtils::setpass($paths->page_id, $paths->namespace, $_POST['password']);
   465       break;
   465 		break;
   466     case "fillusername":
   466 	case "fillusername":
   467       break;
   467 		break;
   468     case "fillpagename":
   468 	case "fillpagename":
   469       break;
   469 		break;
   470     case "preview":
   470 	case "preview":
   471       require_once(ENANO_ROOT.'/includes/pageutils.php');
   471 		require_once(ENANO_ROOT.'/includes/pageutils.php');
   472       $template->init_vars();
   472 		$template->init_vars();
   473       echo PageUtils::genPreview($_POST['text']);
   473 		echo PageUtils::genPreview($_POST['text']);
   474       break;
   474 		break;
   475     case "transform":
   475 	case "transform":
   476       header('Content-type: text/javascript');
   476 		header('Content-type: text/javascript');
   477       if ( !isset($_GET['to']) )
   477 		if ( !isset($_GET['to']) )
   478       {
   478 		{
   479         echo enano_json_encode(array(
   479 			echo enano_json_encode(array(
   480             'mode' => 'error',
   480 					'mode' => 'error',
   481             'error' => '"to" not specified'
   481 					'error' => '"to" not specified'
   482           ));
   482 				));
   483         break;
   483 			break;
   484       }
   484 		}
   485       if ( !isset($_POST['text']) )
   485 		if ( !isset($_POST['text']) )
   486       {
   486 		{
   487         echo enano_json_encode(array(
   487 			echo enano_json_encode(array(
   488             'mode' => 'error',
   488 					'mode' => 'error',
   489             'error' => '"text" not specified (must be on POST)'
   489 					'error' => '"text" not specified (must be on POST)'
   490           ));
   490 				));
   491         break;
   491 			break;
   492       }
   492 		}
   493       switch($_GET['to'])
   493 		switch($_GET['to'])
   494       {
   494 		{
   495         case 'xhtml':
   495 			case 'xhtml':
   496           $result = RenderMan::render($_POST['text'], RENDER_BLOCK | RENDER_NOSMILIES, false);
   496 				$result = RenderMan::render($_POST['text'], RENDER_BLOCK | RENDER_NOSMILIES, false);
   497           break;
   497 				break;
   498         case 'wikitext':
   498 			case 'wikitext':
   499           $result = RenderMan::reverse_render($_POST['text']);
   499 				$result = RenderMan::reverse_render($_POST['text']);
   500           break;
   500 				break;
   501         default:
   501 			default:
   502           $text =& $_POST['text'];
   502 				$text =& $_POST['text'];
   503           $result = false;
   503 				$result = false;
   504           $code = $plugins->setHook('ajax_transform');
   504 				$code = $plugins->setHook('ajax_transform');
   505           foreach ( $code as $cmd )
   505 				foreach ( $code as $cmd )
   506           {
   506 				{
   507             eval($cmd);
   507 					eval($cmd);
   508           }
   508 				}
   509           if ( !$result )
   509 				if ( !$result )
   510           {
   510 				{
   511             echo enano_json_encode(array(
   511 					echo enano_json_encode(array(
   512                 'mode' => 'error',
   512 							'mode' => 'error',
   513                 'error' => 'Invalid target format'
   513 							'error' => 'Invalid target format'
   514               ));
   514 						));
   515             break;
   515 					break;
   516           }
   516 				}
   517           break;
   517 				break;
   518       }
   518 		}
   519       
   519 		
   520       // mostly for debugging, but I suppose this could be useful elsewhere.
   520 		// mostly for debugging, but I suppose this could be useful elsewhere.
   521       if ( isset($_POST['plaintext']) )
   521 		if ( isset($_POST['plaintext']) )
   522         die($result);
   522 			die($result);
   523       
   523 		
   524       echo enano_json_encode(array(
   524 		echo enano_json_encode(array(
   525           'mode' => 'transformed_text',
   525 				'mode' => 'transformed_text',
   526           'text' => $result
   526 				'text' => $result
   527         ));
   527 			));
   528       break;
   528 		break;
   529     case "pagediff":
   529 	case "pagediff":
   530       require_once(ENANO_ROOT.'/includes/pageutils.php');
   530 		require_once(ENANO_ROOT.'/includes/pageutils.php');
   531       $id1 = ( isset($_GET['diff1']) ) ? (int)$_GET['diff1'] : false;
   531 		$id1 = ( isset($_GET['diff1']) ) ? (int)$_GET['diff1'] : false;
   532       $id2 = ( isset($_GET['diff2']) ) ? (int)$_GET['diff2'] : false;
   532 		$id2 = ( isset($_GET['diff2']) ) ? (int)$_GET['diff2'] : false;
   533       if(!$id1 || !$id2) { echo '<p>Invalid request.</p>'; $template->footer(); break; }
   533 		if(!$id1 || !$id2) { echo '<p>Invalid request.</p>'; $template->footer(); break; }
   534       if(!preg_match('#^([0-9]+)$#', (string)$_GET['diff1']) ||
   534 		if(!preg_match('#^([0-9]+)$#', (string)$_GET['diff1']) ||
   535          !preg_match('#^([0-9]+)$#', (string)$_GET['diff2']  )) { echo '<p>SQL injection attempt</p>'; $template->footer(); break; }
   535 			!preg_match('#^([0-9]+)$#', (string)$_GET['diff2']  )) { echo '<p>SQL injection attempt</p>'; $template->footer(); break; }
   536       echo PageUtils::pagediff($paths->page_id, $paths->namespace, $id1, $id2);
   536 		echo PageUtils::pagediff($paths->page_id, $paths->namespace, $id1, $id2);
   537       break;
   537 		break;
   538     case "jsres":
   538 	case "jsres":
   539       die('// ERROR: this section is deprecated and has moved to includes/clientside/static/enano-lib-basic.js.');
   539 		die('// ERROR: this section is deprecated and has moved to includes/clientside/static/enano-lib-basic.js.');
   540       break;
   540 		break;
   541     case "rdns":
   541 	case "rdns":
   542       if(!$session->get_permissions('mod_misc')) die('Go somewhere else for your reverse DNS info!');
   542 		if(!$session->get_permissions('mod_misc')) die('Go somewhere else for your reverse DNS info!');
   543       $ip = $_GET['ip'];
   543 		$ip = $_GET['ip'];
   544       if ( !is_valid_ip($ip) )
   544 		if ( !is_valid_ip($ip) )
   545       {
   545 		{
   546         echo $lang->get('acpsl_err_invalid_ip');
   546 			echo $lang->get('acpsl_err_invalid_ip');
   547       }
   547 		}
   548       $rdns = gethostbyaddr($ip);
   548 		$rdns = gethostbyaddr($ip);
   549       if ( $rdns == $ip )
   549 		if ( $rdns == $ip )
   550         echo $lang->get('acpsl_err_ptr_no_resolve');
   550 			echo $lang->get('acpsl_err_ptr_no_resolve');
   551       else echo $rdns;
   551 		else echo $rdns;
   552       break;
   552 		break;
   553     case 'acljson':
   553 	case 'acljson':
   554       require_once(ENANO_ROOT.'/includes/pageutils.php');
   554 		require_once(ENANO_ROOT.'/includes/pageutils.php');
   555       $parms = ( isset($_POST['acl_params']) ) ? rawurldecode($_POST['acl_params']) : false;
   555 		$parms = ( isset($_POST['acl_params']) ) ? rawurldecode($_POST['acl_params']) : false;
   556       echo PageUtils::acl_json($parms);
   556 		echo PageUtils::acl_json($parms);
   557       break;
   557 		break;
   558     case 'theme_list':
   558 	case 'theme_list':
   559       header('Content-type: application/json');
   559 		header('Content-type: application/json');
   560       
   560 		
   561       $return = array();
   561 		$return = array();
   562       foreach ( $template->theme_list as $theme )
   562 		foreach ( $template->theme_list as $theme )
   563       {
   563 		{
   564         if ( $theme['enabled'] != 1 )
   564 			if ( $theme['enabled'] != 1 )
   565           continue;
   565 				continue;
   566         
   566 			
   567         $return[] = array(
   567 			$return[] = array(
   568             'theme_name' => $theme['theme_name'],
   568 					'theme_name' => $theme['theme_name'],
   569             'theme_id' => $theme['theme_id'],
   569 					'theme_id' => $theme['theme_id'],
   570             'have_thumb' => file_exists(ENANO_ROOT . "/themes/{$theme['theme_id']}/preview.png")
   570 					'have_thumb' => file_exists(ENANO_ROOT . "/themes/{$theme['theme_id']}/preview.png")
   571           );
   571 				);
   572       }
   572 		}
   573       
   573 		
   574       echo enano_json_encode($return);
   574 		echo enano_json_encode($return);
   575       
   575 		
   576       break;
   576 		break;
   577     case "get_styles":
   577 	case "get_styles":
   578       if ( !preg_match('/^[a-z0-9_-]+$/', $_GET['theme_id']) )
   578 		if ( !preg_match('/^[a-z0-9_-]+$/', $_GET['theme_id']) )
   579         die(enano_json_encode(array()));
   579 			die(enano_json_encode(array()));
   580       
   580 		
   581       $theme_id = $_GET['theme_id'];
   581 		$theme_id = $_GET['theme_id'];
   582       $return = array();
   582 		$return = array();
   583       
   583 		
   584       if ( $dr = @opendir(ENANO_ROOT . "/themes/$theme_id/css/") )
   584 		if ( $dr = @opendir(ENANO_ROOT . "/themes/$theme_id/css/") )
   585       {
   585 		{
   586         while ( $dh = @readdir($dr) )
   586 			while ( $dh = @readdir($dr) )
   587         {
   587 			{
   588           if ( preg_match('/\.css$/', $dh) && $dh != '_printable.css' )
   588 				if ( preg_match('/\.css$/', $dh) && $dh != '_printable.css' )
   589           {
   589 				{
   590             $return[] = preg_replace('/\.css$/', '', $dh);
   590 					$return[] = preg_replace('/\.css$/', '', $dh);
   591           }
   591 				}
   592         }
   592 			}
   593       }
   593 		}
   594       else
   594 		else
   595       {
   595 		{
   596         $return = array(
   596 			$return = array(
   597             'mode' => 'error',
   597 					'mode' => 'error',
   598             'error' => 'Could not open directory.'
   598 					'error' => 'Could not open directory.'
   599           );
   599 				);
   600       }
   600 		}
   601       echo enano_json_encode($return);
   601 		echo enano_json_encode($return);
   602       break;
   602 		break;
   603     case "change_theme":
   603 	case "change_theme":
   604       if ( !isset($_POST['theme_id']) || !isset($_POST['style_id']) )
   604 		if ( !isset($_POST['theme_id']) || !isset($_POST['style_id']) )
   605       {
   605 		{
   606         die(enano_json_encode(array('mode' => 'error', 'error' => 'Invalid parameter')));
   606 			die(enano_json_encode(array('mode' => 'error', 'error' => 'Invalid parameter')));
   607       }
   607 		}
   608       if ( !preg_match('/^([a-z0-9_-]+)$/i', $_POST['theme_id']) || !preg_match('/^([a-z0-9_-]+)$/i', $_POST['style_id']) )
   608 		if ( !preg_match('/^([a-z0-9_-]+)$/i', $_POST['theme_id']) || !preg_match('/^([a-z0-9_-]+)$/i', $_POST['style_id']) )
   609       {
   609 		{
   610         die(enano_json_encode(array('mode' => 'error', 'error' => 'Invalid parameter')));
   610 			die(enano_json_encode(array('mode' => 'error', 'error' => 'Invalid parameter')));
   611       }
   611 		}
   612       if ( !file_exists(ENANO_ROOT . '/themes/' . $_POST['theme_id'] . '/css/' . $_POST['style_id'] . '.css') )
   612 		if ( !file_exists(ENANO_ROOT . '/themes/' . $_POST['theme_id'] . '/css/' . $_POST['style_id'] . '.css') )
   613       {
   613 		{
   614         die(enano_json_encode(array('mode' => 'error', 'error' => 'Can\'t find theme file: ' . ENANO_ROOT . '/themes/' . $_POST['theme_id'] . '/css/' . $_POST['style_id'] . '.css')));;
   614 			die(enano_json_encode(array('mode' => 'error', 'error' => 'Can\'t find theme file: ' . ENANO_ROOT . '/themes/' . $_POST['theme_id'] . '/css/' . $_POST['style_id'] . '.css')));;
   615       }
   615 		}
   616       if ( !$session->user_logged_in )
   616 		if ( !$session->user_logged_in )
   617       {
   617 		{
   618         die(enano_json_encode(array('mode' => 'error', 'error' => 'You must be logged in to change your theme')));
   618 			die(enano_json_encode(array('mode' => 'error', 'error' => 'You must be logged in to change your theme')));
   619       }
   619 		}
   620       // Just in case something slipped through...
   620 		// Just in case something slipped through...
   621       $theme_id = $db->escape($_POST['theme_id']);
   621 		$theme_id = $db->escape($_POST['theme_id']);
   622       $style_id = $db->escape($_POST['style_id']);
   622 		$style_id = $db->escape($_POST['style_id']);
   623       $e = $db->sql_query('UPDATE ' . table_prefix . "users SET theme = '$theme_id', style = '$style_id' WHERE user_id = $session->user_id;");
   623 		$e = $db->sql_query('UPDATE ' . table_prefix . "users SET theme = '$theme_id', style = '$style_id' WHERE user_id = $session->user_id;");
   624       if ( !$e )
   624 		if ( !$e )
   625         die( $db->get_error() );
   625 			die( $db->get_error() );
   626       
   626 		
   627       echo enano_json_encode(array(
   627 		echo enano_json_encode(array(
   628           'success' => true
   628 				'success' => true
   629         ));
   629 			));
   630       break;
   630 		break;
   631     case 'get_tags':
   631 	case 'get_tags':
   632       
   632 		
   633       $ret = array('tags' => array(), 'user_level' => $session->user_level, 'can_add' => $session->get_permissions('tag_create'));
   633 		$ret = array('tags' => array(), 'user_level' => $session->user_level, 'can_add' => $session->get_permissions('tag_create'));
   634       $q = $db->sql_query('SELECT t.tag_id, t.tag_name, pg.pg_target IS NOT NULL AS used_in_acl, t.user_id FROM '.table_prefix.'tags AS t
   634 		$q = $db->sql_query('SELECT t.tag_id, t.tag_name, pg.pg_target IS NOT NULL AS used_in_acl, t.user_id FROM '.table_prefix.'tags AS t
   635         LEFT JOIN '.table_prefix.'page_groups AS pg
   635 			LEFT JOIN '.table_prefix.'page_groups AS pg
   636           ON ( ( pg.pg_type = ' . PAGE_GRP_TAGGED . ' AND pg.pg_target=t.tag_name ) OR ( pg.pg_type IS NULL AND pg.pg_target IS NULL ) )
   636 				ON ( ( pg.pg_type = ' . PAGE_GRP_TAGGED . ' AND pg.pg_target=t.tag_name ) OR ( pg.pg_type IS NULL AND pg.pg_target IS NULL ) )
   637         WHERE t.page_id=\'' . $db->escape($paths->page_id) . '\' AND t.namespace=\'' . $db->escape($paths->namespace) . '\';');
   637 			WHERE t.page_id=\'' . $db->escape($paths->page_id) . '\' AND t.namespace=\'' . $db->escape($paths->namespace) . '\';');
   638       if ( !$q )
   638 		if ( !$q )
   639         $db->_die();
   639 			$db->_die();
   640       
   640 		
   641       while ( $row = $db->fetchrow() )
   641 		while ( $row = $db->fetchrow() )
   642       {
   642 		{
   643         $can_del = true;
   643 			$can_del = true;
   644         
   644 			
   645         $perm = ( $row['user_id'] != $session->user_id ) ?
   645 			$perm = ( $row['user_id'] != $session->user_id ) ?
   646                 'tag_delete_other' :
   646 							'tag_delete_other' :
   647                 'tag_delete_own';
   647 							'tag_delete_own';
   648         
   648 			
   649         if ( $row['user_id'] == 1 && !$session->user_logged_in )
   649 			if ( $row['user_id'] == 1 && !$session->user_logged_in )
   650           // anonymous user trying to delete tag (hardcode blacklisted)
   650 				// anonymous user trying to delete tag (hardcode blacklisted)
   651           $can_del = false;
   651 				$can_del = false;
   652           
   652 				
   653         if ( !$session->get_permissions($perm) )
   653 			if ( !$session->get_permissions($perm) )
   654           $can_del = false;
   654 				$can_del = false;
   655         
   655 			
   656         if ( $row['used_in_acl'] == 1 && !$session->get_permissions('edit_acl') && $session->user_level < USER_LEVEL_ADMIN )
   656 			if ( $row['used_in_acl'] == 1 && !$session->get_permissions('edit_acl') && $session->user_level < USER_LEVEL_ADMIN )
   657           $can_del = false;
   657 				$can_del = false;
   658         
   658 			
   659         $ret['tags'][] = array(
   659 			$ret['tags'][] = array(
   660           'id' => $row['tag_id'],
   660 				'id' => $row['tag_id'],
   661           'name' => $row['tag_name'],
   661 				'name' => $row['tag_name'],
   662           'can_del' => $can_del,
   662 				'can_del' => $can_del,
   663           'acl' => ( $row['used_in_acl'] == 1 )
   663 				'acl' => ( $row['used_in_acl'] == 1 )
   664         );
   664 			);
   665       }
   665 		}
   666       
   666 		
   667       echo enano_json_encode($ret);
   667 		echo enano_json_encode($ret);
   668       
   668 		
   669       break;
   669 		break;
   670     case 'addtag':
   670 	case 'addtag':
   671       $resp = array(
   671 		$resp = array(
   672           'success' => false,
   672 				'success' => false,
   673           'error' => 'No error',
   673 				'error' => 'No error',
   674           'can_del' => ( $session->get_permissions('tag_delete_own') && $session->user_logged_in ),
   674 				'can_del' => ( $session->get_permissions('tag_delete_own') && $session->user_logged_in ),
   675           'in_acl' => false
   675 				'in_acl' => false
   676         );
   676 			);
   677       
   677 		
   678       // first of course, are we allowed to tag pages?
   678 		// first of course, are we allowed to tag pages?
   679       if ( !$session->get_permissions('tag_create') )
   679 		if ( !$session->get_permissions('tag_create') )
   680       {
   680 		{
   681         $resp['error'] = 'You are not permitted to tag pages.';
   681 			$resp['error'] = 'You are not permitted to tag pages.';
   682         die(enano_json_encode($resp));
   682 			die(enano_json_encode($resp));
   683       }
   683 		}
   684       
   684 		
   685       // sanitize the tag name
   685 		// sanitize the tag name
   686       $tag = sanitize_tag($_POST['tag']);
   686 		$tag = sanitize_tag($_POST['tag']);
   687       $tag = $db->escape($tag);
   687 		$tag = $db->escape($tag);
   688       
   688 		
   689       if ( strlen($tag) < 2 )
   689 		if ( strlen($tag) < 2 )
   690       {
   690 		{
   691         $resp['error'] = 'Tags must consist of at least 2 alphanumeric characters.';
   691 			$resp['error'] = 'Tags must consist of at least 2 alphanumeric characters.';
   692         die(enano_json_encode($resp));
   692 			die(enano_json_encode($resp));
   693       }
   693 		}
   694       
   694 		
   695       // check if tag is already on page
   695 		// check if tag is already on page
   696       $q = $db->sql_query('SELECT 1 FROM '.table_prefix.'tags WHERE page_id=\'' . $db->escape($paths->page_id) . '\' AND namespace=\'' . $db->escape($paths->namespace) . '\' AND tag_name=\'' . $tag . '\';');
   696 		$q = $db->sql_query('SELECT 1 FROM '.table_prefix.'tags WHERE page_id=\'' . $db->escape($paths->page_id) . '\' AND namespace=\'' . $db->escape($paths->namespace) . '\' AND tag_name=\'' . $tag . '\';');
   697       if ( !$q )
   697 		if ( !$q )
   698         $db->_die();
   698 			$db->_die();
   699       if ( $db->numrows() > 0 )
   699 		if ( $db->numrows() > 0 )
   700       {
   700 		{
   701         $resp['error'] = 'This page already has this tag.';
   701 			$resp['error'] = 'This page already has this tag.';
   702         die(enano_json_encode($resp));
   702 			die(enano_json_encode($resp));
   703       }
   703 		}
   704       $db->free_result();
   704 		$db->free_result();
   705       
   705 		
   706       // tricky: make sure this tag isn't being used in some page group, and thus adding it could affect page access
   706 		// tricky: make sure this tag isn't being used in some page group, and thus adding it could affect page access
   707       $can_edit_acl = ( $session->get_permissions('edit_acl') || $session->user_level >= USER_LEVEL_ADMIN );
   707 		$can_edit_acl = ( $session->get_permissions('edit_acl') || $session->user_level >= USER_LEVEL_ADMIN );
   708       $q = $db->sql_query('SELECT 1 FROM '.table_prefix.'page_groups WHERE pg_type=' . PAGE_GRP_TAGGED . ' AND pg_target=\'' . $tag . '\';');
   708 		$q = $db->sql_query('SELECT 1 FROM '.table_prefix.'page_groups WHERE pg_type=' . PAGE_GRP_TAGGED . ' AND pg_target=\'' . $tag . '\';');
   709       if ( !$q )
   709 		if ( !$q )
   710         $db->_die();
   710 			$db->_die();
   711       if ( $db->numrows() > 0 && !$can_edit_acl )
   711 		if ( $db->numrows() > 0 && !$can_edit_acl )
   712       {
   712 		{
   713         $resp['error'] = 'This tag is used in an ACL page group, and thus can\'t be added to a page by people without administrator privileges.';
   713 			$resp['error'] = 'This tag is used in an ACL page group, and thus can\'t be added to a page by people without administrator privileges.';
   714         die(enano_json_encode($resp));
   714 			die(enano_json_encode($resp));
   715       }
   715 		}
   716       $resp['in_acl'] = ( $db->numrows() > 0 );
   716 		$resp['in_acl'] = ( $db->numrows() > 0 );
   717       $db->free_result();
   717 		$db->free_result();
   718       
   718 		
   719       // we're good
   719 		// we're good
   720       $q = $db->sql_query('INSERT INTO '.table_prefix.'tags(tag_name,page_id,namespace,user_id) VALUES(\'' . $tag . '\', \'' . $db->escape($paths->page_id) . '\', \'' . $db->escape($paths->namespace) . '\', ' . $session->user_id . ');');
   720 		$q = $db->sql_query('INSERT INTO '.table_prefix.'tags(tag_name,page_id,namespace,user_id) VALUES(\'' . $tag . '\', \'' . $db->escape($paths->page_id) . '\', \'' . $db->escape($paths->namespace) . '\', ' . $session->user_id . ');');
   721       if ( !$q )
   721 		if ( !$q )
   722         $db->_die();
   722 			$db->_die();
   723       
   723 		
   724       $resp['success'] = true;
   724 		$resp['success'] = true;
   725       $resp['tag'] = $tag;
   725 		$resp['tag'] = $tag;
   726       $resp['tag_id'] = $db->insert_id();
   726 		$resp['tag_id'] = $db->insert_id();
   727       
   727 		
   728       echo enano_json_encode($resp);
   728 		echo enano_json_encode($resp);
   729       break;
   729 		break;
   730     case 'deltag':
   730 	case 'deltag':
   731       
   731 		
   732       $tag_id = intval($_POST['tag_id']);
   732 		$tag_id = intval($_POST['tag_id']);
   733       if ( empty($tag_id) )
   733 		if ( empty($tag_id) )
   734         die('Invalid tag ID');
   734 			die('Invalid tag ID');
   735       
   735 		
   736       $q = $db->sql_query('SELECT t.tag_id, t.user_id, t.page_id, t.namespace, pg.pg_target IS NOT NULL AS used_in_acl FROM '.table_prefix.'tags AS t
   736 		$q = $db->sql_query('SELECT t.tag_id, t.user_id, t.page_id, t.namespace, pg.pg_target IS NOT NULL AS used_in_acl FROM '.table_prefix.'tags AS t
   737   LEFT JOIN '.table_prefix.'page_groups AS pg
   737 LEFT JOIN '.table_prefix.'page_groups AS pg
   738     ON ( pg.pg_id IS NULL OR ( pg.pg_target = t.tag_name AND pg.pg_type = ' . PAGE_GRP_TAGGED . ' ) )
   738 	ON ( pg.pg_id IS NULL OR ( pg.pg_target = t.tag_name AND pg.pg_type = ' . PAGE_GRP_TAGGED . ' ) )
   739   WHERE t.tag_id=' . $tag_id . ';');
   739 WHERE t.tag_id=' . $tag_id . ';');
   740       
   740 		
   741       if ( !$q )
   741 		if ( !$q )
   742         $db->_die();
   742 			$db->_die();
   743       
   743 		
   744       if ( $db->numrows() < 1 )
   744 		if ( $db->numrows() < 1 )
   745         die('Could not find a tag with that ID');
   745 			die('Could not find a tag with that ID');
   746       
   746 		
   747       $row = $db->fetchrow();
   747 		$row = $db->fetchrow();
   748       $db->free_result();
   748 		$db->free_result();
   749       
   749 		
   750       if ( $row['page_id'] == $paths->page_id && $row['namespace'] == $paths->namespace )
   750 		if ( $row['page_id'] == $paths->page_id && $row['namespace'] == $paths->namespace )
   751         $perms =& $session;
   751 			$perms =& $session;
   752       else
   752 		else
   753         $perms = $session->fetch_page_acl($row['page_id'], $row['namespace']);
   753 			$perms = $session->fetch_page_acl($row['page_id'], $row['namespace']);
   754         
   754 			
   755       $perm = ( $row['user_id'] != $session->user_id ) ?
   755 		$perm = ( $row['user_id'] != $session->user_id ) ?
   756                 'tag_delete_other' :
   756 							'tag_delete_other' :
   757                 'tag_delete_own';
   757 							'tag_delete_own';
   758       
   758 		
   759       if ( $row['user_id'] == 1 && !$session->user_logged_in )
   759 		if ( $row['user_id'] == 1 && !$session->user_logged_in )
   760         // anonymous user trying to delete tag (hardcode blacklisted)
   760 			// anonymous user trying to delete tag (hardcode blacklisted)
   761         die('You are not authorized to delete this tag.');
   761 			die('You are not authorized to delete this tag.');
   762         
   762 			
   763       if ( !$perms->get_permissions($perm) )
   763 		if ( !$perms->get_permissions($perm) )
   764         die('You are not authorized to delete this tag.');
   764 			die('You are not authorized to delete this tag.');
   765       
   765 		
   766       if ( $row['used_in_acl'] == 1 && !$perms->get_permissions('edit_acl') && $session->user_level < USER_LEVEL_ADMIN )
   766 		if ( $row['used_in_acl'] == 1 && !$perms->get_permissions('edit_acl') && $session->user_level < USER_LEVEL_ADMIN )
   767         die('You are not authorized to delete this tag.');
   767 			die('You are not authorized to delete this tag.');
   768       
   768 		
   769       // We're good
   769 		// We're good
   770       $q = $db->sql_query('DELETE FROM '.table_prefix.'tags WHERE tag_id = ' . $tag_id . ';');
   770 		$q = $db->sql_query('DELETE FROM '.table_prefix.'tags WHERE tag_id = ' . $tag_id . ';');
   771       if ( !$q )
   771 		if ( !$q )
   772         $db->_die();
   772 			$db->_die();
   773       
   773 		
   774       echo 'success';
   774 		echo 'success';
   775       
   775 		
   776       break;
   776 		break;
   777     case 'ping':
   777 	case 'ping':
   778       echo 'pong';
   778 		echo 'pong';
   779       break;
   779 		break;
   780     default:
   780 	default:
   781       die('Hacking attempt');
   781 		die('Hacking attempt');
   782       break;
   782 		break;
   783   }
   783 }
   784   
   784 
   785 ?>
   785 ?>