includes/namespaces/file.php
changeset 1227 bdac73ed481e
parent 1114 4f4d63a281cd
child 1277 4264ace0855f
equal deleted inserted replaced
1226:de56132c008d 1227:bdac73ed481e
    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 class Namespace_File extends Namespace_Default
    14 class Namespace_File extends Namespace_Default
    15 {
    15 {
    16   function send()
    16 	function send()
    17   {
    17 	{
    18     global $output;
    18 		global $output;
    19     
    19 		
    20     $output->add_before_footer($this->show_info());
    20 		$output->add_before_footer($this->show_info());
    21     $output->add_before_footer($this->display_categories());
    21 		$output->add_before_footer($this->display_categories());
    22     
    22 		
    23     if ( $this->exists )
    23 		if ( $this->exists )
    24     {
    24 		{
    25       $this->send_from_db();
    25 			$this->send_from_db();
    26     }
    26 		}
    27     else
    27 		else
    28     {
    28 		{
    29       $output->header();
    29 			$output->header();
    30       $this->error_404();
    30 			$this->error_404();
    31       $output->footer();
    31 			$output->footer();
    32     }
    32 		}
    33   }
    33 	}
    34   
    34 	
    35   function show_info()
    35 	function show_info()
    36   {
    36 	{
    37     global $db, $session, $paths, $template, $plugins; // Common objects
    37 		global $db, $session, $paths, $template, $plugins; // Common objects
    38     global $lang;
    38 		global $lang;
    39     
    39 		
    40     require_once(ENANO_ROOT . '/includes/log.php');
    40 		require_once(ENANO_ROOT . '/includes/log.php');
    41     
    41 		
    42     $local_page_id = $this->page_id;
    42 		$local_page_id = $this->page_id;
    43     $local_namespace = $this->namespace;
    43 		$local_namespace = $this->namespace;
    44     $html = '';
    44 		$html = '';
    45     
    45 		
    46     // Prevent unnecessary work
    46 		// Prevent unnecessary work
    47     if ( $local_namespace != 'File' )
    47 		if ( $local_namespace != 'File' )
    48       return null;
    48 			return null;
    49     
    49 		
    50     $selfn = $db->escape($this->page_id);
    50 		$selfn = $db->escape($this->page_id);
    51     $q = $db->sql_query('SELECT f.mimetype,f.time_id,f.size,l.log_id FROM ' . table_prefix . "files AS f\n"
    51 		$q = $db->sql_query('SELECT f.mimetype,f.time_id,f.size,l.log_id FROM ' . table_prefix . "files AS f\n"
    52                       . "  LEFT JOIN " . table_prefix . "logs AS l\n"
    52 											. "  LEFT JOIN " . table_prefix . "logs AS l\n"
    53                       . "    ON ( l.time_id = f.time_id AND ( l.action = 'reupload' OR l.action IS NULL ) )\n"
    53 											. "    ON ( l.time_id = f.time_id AND ( l.action = 'reupload' OR l.action IS NULL ) )\n"
    54                       . "  WHERE f.page_id = '$selfn'\n"
    54 											. "  WHERE f.page_id = '$selfn'\n"
    55                       . "    ORDER BY f.time_id DESC;");
    55 											. "    ORDER BY f.time_id DESC;");
    56     if ( !$q )
    56 		if ( !$q )
    57     {
    57 		{
    58       $db->_die('The file type could not be fetched.');
    58 			$db->_die('The file type could not be fetched.');
    59     }
    59 		}
    60     
    60 		
    61     if ( $db->numrows() < 1 )
    61 		if ( $db->numrows() < 1 )
    62     {
    62 		{
    63       $html .= '<div class="mdg-comment" style="margin-left: 0;">
    63 			$html .= '<div class="mdg-comment" style="margin-left: 0;">
    64               <h3>' . $lang->get('onpage_filebox_heading') . '</h3>
    64 							<h3>' . $lang->get('onpage_filebox_heading') . '</h3>
    65               <p>' . $lang->get('onpage_filebox_msg_not_found', array('upload_link' => makeUrlNS('Special', 'UploadFile/'.$local_page_id))) . '</p>
    65 							<p>' . $lang->get('onpage_filebox_msg_not_found', array('upload_link' => makeUrlNS('Special', 'UploadFile/'.$local_page_id))) . '</p>
    66             </div>
    66 						</div>
    67             <br />';
    67 						<br />';
    68       return $html;
    68 			return $html;
    69     }
    69 		}
    70     $r = $db->fetchrow();
    70 		$r = $db->fetchrow();
    71     $mimetype = $r['mimetype'];
    71 		$mimetype = $r['mimetype'];
    72     $datestring = enano_date(ED_DATE | ED_TIME, (int)$r['time_id']);
    72 		$datestring = enano_date(ED_DATE | ED_TIME, (int)$r['time_id']);
    73     $html .= '<div class="mdg-comment" style="margin-left: 0;">
    73 		$html .= '<div class="mdg-comment" style="margin-left: 0;">
    74             <h3>' . $lang->get('onpage_filebox_heading') . '</h3>
    74 						<h3>' . $lang->get('onpage_filebox_heading') . '</h3>
    75             <p>' . $lang->get('onpage_filebox_lbl_type') . ' '.$r['mimetype'].'<br />';
    75 						<p>' . $lang->get('onpage_filebox_lbl_type') . ' '.$r['mimetype'].'<br />';
    76     
    76 		
    77     $size = $r['size'] . ' ' . $lang->get('etc_unit_bytes');
    77 		$size = $r['size'] . ' ' . $lang->get('etc_unit_bytes');
    78     if ( $r['size'] >= 1048576 )
    78 		if ( $r['size'] >= 1048576 )
    79     {
    79 		{
    80       $size .= ' (' . ( round($r['size'] / 1048576, 1) ) . ' ' . $lang->get('etc_unit_megabytes_short') . ')';
    80 			$size .= ' (' . ( round($r['size'] / 1048576, 1) ) . ' ' . $lang->get('etc_unit_megabytes_short') . ')';
    81     }
    81 		}
    82     else if ( $r['size'] >= 1024 )
    82 		else if ( $r['size'] >= 1024 )
    83     {
    83 		{
    84       $size .= ' (' . ( round($r['size'] / 1024, 1) ) . ' ' . $lang->get('etc_unit_kilobytes_short') . ')';
    84 			$size .= ' (' . ( round($r['size'] / 1024, 1) ) . ' ' . $lang->get('etc_unit_kilobytes_short') . ')';
    85     }
    85 		}
    86     
    86 		
    87     $html .= $lang->get('onpage_filebox_lbl_size', array('size' => $size));
    87 		$html .= $lang->get('onpage_filebox_lbl_size', array('size' => $size));
    88     
    88 		
    89     $html .= '<br />' . $lang->get('onpage_filebox_lbl_uploaded') . ' ' . $datestring . '</p>';
    89 		$html .= '<br />' . $lang->get('onpage_filebox_lbl_uploaded') . ' ' . $datestring . '</p>';
    90     // are we dealing with an image?
    90 		// are we dealing with an image?
    91     $is_image = substr($mimetype, 0, 6) == 'image/';
    91 		$is_image = substr($mimetype, 0, 6) == 'image/';
    92     
    92 		
    93     // for anything other than plain text and 
    93 		// for anything other than plain text and 
    94     if ( !$is_image && ( substr($mimetype, 0, 5) != 'text/' || $mimetype == 'text/html' || $mimetype == 'text/javascript' ) )
    94 		if ( !$is_image && ( substr($mimetype, 0, 5) != 'text/' || $mimetype == 'text/html' || $mimetype == 'text/javascript' ) )
    95     {
    95 		{
    96       $html .= '<div class="warning-box">
    96 			$html .= '<div class="warning-box">
    97               ' . $lang->get('onpage_filebox_msg_virus_warning') . '
    97 							' . $lang->get('onpage_filebox_msg_virus_warning') . '
    98             </div>';
    98 						</div>';
    99     }
    99 		}
   100     if ( $is_image )
   100 		if ( $is_image )
   101     {
   101 		{
   102       // show a thumbnail of the image
   102 			// show a thumbnail of the image
   103       $html .= '<p>
   103 			$html .= '<p>
   104               <a href="'.makeUrlNS('Special', 'DownloadFile'.'/'.$selfn).'">
   104 							<a href="'.makeUrlNS('Special', 'DownloadFile'.'/'.$selfn).'">
   105                 <img style="border: 0;" alt="' . htmlspecialchars($paths->page) . '" src="' . makeUrlNS('Special', "DownloadFile/$selfn/{$r['time_id']}", 'preview', true) . '" />
   105 								<img style="border: 0;" alt="' . htmlspecialchars($paths->page) . '" src="' . makeUrlNS('Special', "DownloadFile/$selfn/{$r['time_id']}", 'preview', true) . '" />
   106               </a>
   106 							</a>
   107             </p>';
   107 						</p>';
   108     }
   108 		}
   109     $html .= '<p>
   109 		$html .= '<p>
   110             <a href="'.makeUrlNS('Special', 'DownloadFile'.'/'.$selfn.'/'.$r['time_id'].htmlspecialchars(urlSeparator).'download').'">
   110 						<a href="'.makeUrlNS('Special', 'DownloadFile'.'/'.$selfn.'/'.$r['time_id'].htmlspecialchars(urlSeparator).'download').'">
   111               ' . $lang->get('onpage_filebox_btn_download') . '
   111 							' . $lang->get('onpage_filebox_btn_download') . '
   112             </a>';
   112 						</a>';
   113     // allow reupload if:
   113 		// allow reupload if:
   114     //   * we are allowed to upload new versions, and
   114 		//   * we are allowed to upload new versions, and
   115     //      - the file is unprotected, or
   115 		//      - the file is unprotected, or
   116     //      - we have permission to override protection
   116 		//      - we have permission to override protection
   117     
   117 		
   118     if ( !$this->perms )
   118 		if ( !$this->perms )
   119       $this->perms = $session->fetch_page_acl($this->page_id, $this->namespace);
   119 			$this->perms = $session->fetch_page_acl($this->page_id, $this->namespace);
   120     
   120 		
   121     if ( $this->perms->get_permissions('upload_new_version') && ( !$this->page_protected || $this->perms->get_permissions('even_when_protected') ) )
   121 		if ( $this->perms->get_permissions('upload_new_version') && ( !$this->page_protected || $this->perms->get_permissions('even_when_protected') ) )
   122     {
   122 		{
   123       // upload new version link
   123 			// upload new version link
   124       $html .= '  |  <a href="'.makeUrlNS('Special', "UploadFile/$selfn", false, true).'">
   124 			$html .= '  |  <a href="'.makeUrlNS('Special', "UploadFile/$selfn", false, true).'">
   125               ' . $lang->get('onpage_filebox_btn_upload_new') . '
   125 							' . $lang->get('onpage_filebox_btn_upload_new') . '
   126             </a>';
   126 						</a>';
   127     }
   127 		}
   128     // close off paragraph
   128 		// close off paragraph
   129     $html .= '</p>';
   129 		$html .= '</p>';
   130     // only show this if there's more than one revision
   130 		// only show this if there's more than one revision
   131     if ( $db->numrows() > 1 )
   131 		if ( $db->numrows() > 1 )
   132     {
   132 		{
   133       // requery, sql_result_seek() doesn't work on postgres
   133 			// requery, sql_result_seek() doesn't work on postgres
   134       $db->free_result();
   134 			$db->free_result();
   135       $q = $db->sql_query('SELECT f.mimetype,f.time_id,f.size,l.log_id FROM ' . table_prefix . "files AS f\n"
   135 			$q = $db->sql_query('SELECT f.mimetype,f.time_id,f.size,l.log_id FROM ' . table_prefix . "files AS f\n"
   136                       . "  LEFT JOIN " . table_prefix . "logs AS l\n"
   136 											. "  LEFT JOIN " . table_prefix . "logs AS l\n"
   137                       . "    ON ( l.time_id = f.time_id AND ( l.action = 'reupload' OR l.action IS NULL ) )\n"
   137 											. "    ON ( l.time_id = f.time_id AND ( l.action = 'reupload' OR l.action IS NULL ) )\n"
   138                       . "  WHERE f.page_id = '$selfn'\n"
   138 											. "  WHERE f.page_id = '$selfn'\n"
   139                       . "    ORDER BY f.time_id DESC;");
   139 											. "    ORDER BY f.time_id DESC;");
   140       if ( !$q )
   140 			if ( !$q )
   141         $db->_die();
   141 				$db->_die();
   142       
   142 			
   143       $log = new LogDisplay();
   143 			$log = new LogDisplay();
   144       $log->add_criterion('page', $paths->nslist['File'] . $this->page_id);
   144 			$log->add_criterion('page', $paths->nslist['File'] . $this->page_id);
   145       $log->add_criterion('action', 'reupload');
   145 			$log->add_criterion('action', 'reupload');
   146       $data = $log->get_data();
   146 			$data = $log->get_data();
   147       $i = -1;
   147 			$i = -1;
   148       
   148 			
   149       $html .= '<h3>' . $lang->get('onpage_filebox_heading_history') . '</h3><p>';
   149 			$html .= '<h3>' . $lang->get('onpage_filebox_heading_history') . '</h3><p>';
   150       $last_rollback_id = false;
   150 			$last_rollback_id = false;
   151       $download_flag = $is_image ? false : 'download';
   151 			$download_flag = $is_image ? false : 'download';
   152       while ( $r = $db->fetchrow($q) )
   152 			while ( $r = $db->fetchrow($q) )
   153       {
   153 			{
   154         $html .= '(<a href="'.makeUrlNS('Special', "DownloadFile/$selfn/{$r['time_id']}", $download_flag, true).'">' . $lang->get('onpage_filebox_btn_this_version') . '</a>) ';
   154 				$html .= '(<a href="'.makeUrlNS('Special', "DownloadFile/$selfn/{$r['time_id']}", $download_flag, true).'">' . $lang->get('onpage_filebox_btn_this_version') . '</a>) ';
   155         if ( $session->get_permissions('history_rollback') && $last_rollback_id )
   155 				if ( $session->get_permissions('history_rollback') && $last_rollback_id )
   156           $html .= ' (<a href="#rollback:' . $last_rollback_id . '" onclick="ajaxRollback(\''.$last_rollback_id.'\'); return false;">' . $lang->get('onpage_filebox_btn_revert') . '</a>) ';
   156 					$html .= ' (<a href="#rollback:' . $last_rollback_id . '" onclick="ajaxRollback(\''.$last_rollback_id.'\'); return false;">' . $lang->get('onpage_filebox_btn_revert') . '</a>) ';
   157         else if ( $session->get_permissions('history_rollback') && !$last_rollback_id )
   157 				else if ( $session->get_permissions('history_rollback') && !$last_rollback_id )
   158           $html .= ' (' . $lang->get('onpage_filebox_btn_current') . ') ';
   158 					$html .= ' (' . $lang->get('onpage_filebox_btn_current') . ') ';
   159         $last_rollback_id = $r['log_id'];
   159 				$last_rollback_id = $r['log_id'];
   160         
   160 				
   161         $html .= $r['mimetype'].', ';
   161 				$html .= $r['mimetype'].', ';
   162         
   162 				
   163         $fs = $r['size'];
   163 				$fs = $r['size'];
   164         $fs = (int)$fs;
   164 				$fs = (int)$fs;
   165         
   165 				
   166         if($fs >= 1048576)
   166 				if($fs >= 1048576)
   167         {
   167 				{
   168           $fs = round($fs / 1048576, 1);
   168 					$fs = round($fs / 1048576, 1);
   169           $size = $fs . ' ' . $lang->get('etc_unit_megabytes_short');
   169 					$size = $fs . ' ' . $lang->get('etc_unit_megabytes_short');
   170         }
   170 				}
   171         else
   171 				else
   172         if ( $fs >= 1024 )
   172 				if ( $fs >= 1024 )
   173         {
   173 				{
   174           $fs = round($fs / 1024, 1);
   174 					$fs = round($fs / 1024, 1);
   175           $size = $fs . ' ' . $lang->get('etc_unit_kilobytes_short');
   175 					$size = $fs . ' ' . $lang->get('etc_unit_kilobytes_short');
   176         }
   176 				}
   177         else
   177 				else
   178         {
   178 				{
   179           $size = $fs . ' ' . $lang->get('etc_unit_bytes');
   179 					$size = $fs . ' ' . $lang->get('etc_unit_bytes');
   180         }
   180 				}
   181         
   181 				
   182         $html .= $size;
   182 				$html .= $size;
   183         if ( isset($data[++$i]) )
   183 				if ( isset($data[++$i]) )
   184           $html .= ': ' . LogDisplay::render_row($data[$i], false, false);
   184 					$html .= ': ' . LogDisplay::render_row($data[$i], false, false);
   185         
   185 				
   186         $html .= '<br />';
   186 				$html .= '<br />';
   187       }
   187 			}
   188       $html .= '</p>';
   188 			$html .= '</p>';
   189     }
   189 		}
   190     $db->free_result();
   190 		$db->free_result();
   191     $html .= '</div><br />';
   191 		$html .= '</div><br />';
   192     return $html;
   192 		return $html;
   193   }
   193 	}
   194   
   194 	
   195   /**
   195 	/**
   196    * Delete a file from the database and filesystem based on file ID.
   196  	* Delete a file from the database and filesystem based on file ID.
   197    * @param int File ID
   197  	* @param int File ID
   198    * @return null
   198  	* @return null
   199    */
   199  	*/
   200   
   200 	
   201   public static function delete_file($file_id)
   201 	public static function delete_file($file_id)
   202   {
   202 	{
   203     global $db, $session, $paths, $template, $plugins; // Common objects
   203 		global $db, $session, $paths, $template, $plugins; // Common objects
   204     
   204 		
   205     if ( !is_int($file_id) )
   205 		if ( !is_int($file_id) )
   206       // seriously?
   206 			// seriously?
   207       return null;
   207 			return null;
   208     
   208 		
   209     // pull file info
   209 		// pull file info
   210     $q = $db->sql_query('SELECT filename, page_id, time_id, file_extension, file_key FROM ' . table_prefix . "files WHERE file_id = $file_id;");
   210 		$q = $db->sql_query('SELECT filename, page_id, time_id, file_extension, file_key FROM ' . table_prefix . "files WHERE file_id = $file_id;");
   211     if ( !$q )
   211 		if ( !$q )
   212       $db->_die();
   212 			$db->_die();
   213     
   213 		
   214     if ( $db->numrows() < 1 )
   214 		if ( $db->numrows() < 1 )
   215     {
   215 		{
   216       $db->free_result();
   216 			$db->free_result();
   217       return null;
   217 			return null;
   218     }
   218 		}
   219     
   219 		
   220     $row = $db->fetchrow();
   220 		$row = $db->fetchrow();
   221     $db->free_result();
   221 		$db->free_result();
   222     
   222 		
   223     // make sure the image isn't used by multiple revisions
   223 		// make sure the image isn't used by multiple revisions
   224     $q = $db->sql_query('SELECT 1 FROM ' . table_prefix . "files WHERE file_key = '{$row['file_key']}';");
   224 		$q = $db->sql_query('SELECT 1 FROM ' . table_prefix . "files WHERE file_key = '{$row['file_key']}';");
   225     if ( !$q )
   225 		if ( !$q )
   226       $db->_die();
   226 			$db->_die();
   227     if ( $db->numrows() < 1 )
   227 		if ( $db->numrows() < 1 )
   228     {
   228 		{
   229       // remove from filesystem
   229 			// remove from filesystem
   230       $file_path = ENANO_ROOT . "/files/{$row['file_key']}{$row['file_extension']}";
   230 			$file_path = ENANO_ROOT . "/files/{$row['file_key']}{$row['file_extension']}";
   231       @unlink($file_path);
   231 			@unlink($file_path);
   232       // old filename standard
   232 			// old filename standard
   233       $file_path = ENANO_ROOT . "/files/{$row['file_key']}-{$row['time_id']}{$row['file_extension']}";
   233 			$file_path = ENANO_ROOT . "/files/{$row['file_key']}-{$row['time_id']}{$row['file_extension']}";
   234       @unlink($file_path);
   234 			@unlink($file_path);
   235     }
   235 		}
   236     $db->free_result();
   236 		$db->free_result();
   237     
   237 		
   238     // remove from cache
   238 		// remove from cache
   239     if ( $dp = @opendir(ENANO_ROOT . '/cache/') )
   239 		if ( $dp = @opendir(ENANO_ROOT . '/cache/') )
   240     {
   240 		{
   241       $regexp = '#' . preg_quote($row['filename']) . '-' . $row['time_id'] . '-[0-9]+x[0-9]+' . preg_quote($row['file_extension']) . '#';
   241 			$regexp = '#' . preg_quote($row['filename']) . '-' . $row['time_id'] . '-[0-9]+x[0-9]+' . preg_quote($row['file_extension']) . '#';
   242       while ( $dh = @readdir($dp) )
   242 			while ( $dh = @readdir($dp) )
   243       {
   243 			{
   244         if ( preg_match($regexp, $dh) )
   244 				if ( preg_match($regexp, $dh) )
   245         {
   245 				{
   246           // it's a match, delete the cached thumbnail
   246 					// it's a match, delete the cached thumbnail
   247           @unlink(ENANO_ROOT . "/cache/$dh");
   247 					@unlink(ENANO_ROOT . "/cache/$dh");
   248         }
   248 				}
   249       }
   249 			}
   250       closedir($dp);
   250 			closedir($dp);
   251     }
   251 		}
   252     
   252 		
   253     // remove from database
   253 		// remove from database
   254     $q = $db->sql_query('DELETE FROM ' . table_prefix . "files WHERE file_id = $file_id;");
   254 		$q = $db->sql_query('DELETE FROM ' . table_prefix . "files WHERE file_id = $file_id;");
   255     if ( !$q )
   255 		if ( !$q )
   256       $db->_die();
   256 			$db->_die();
   257     
   257 		
   258     // remove from logs
   258 		// remove from logs
   259     $page_id_db = $db->escape($row['page_id']);
   259 		$page_id_db = $db->escape($row['page_id']);
   260     $q = $db->sql_query('DELETE FROM ' . table_prefix . "logs WHERE page_id = '{$page_id_db}' AND namespace = 'File' AND action = 'reupload' AND time_id = {$row['time_id']};");
   260 		$q = $db->sql_query('DELETE FROM ' . table_prefix . "logs WHERE page_id = '{$page_id_db}' AND namespace = 'File' AND action = 'reupload' AND time_id = {$row['time_id']};");
   261     if ( !$q )
   261 		if ( !$q )
   262       $db->_die();
   262 			$db->_die();
   263     
   263 		
   264     return true;
   264 		return true;
   265   }
   265 	}
   266 }
   266 }
   267 
   267