| [ Index ] |
|
Code source de Plume CMS 1.2.2 |
1 <?php 2 /* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 3 /* 4 # ***** BEGIN LICENSE BLOCK ***** 5 # This file is part of Plume CMS, a website management application. 6 # Copyright (C) 2001-2005 Loic d'Anterroches and contributors. 7 # 8 # Plume CMS is free software; you can redistribute it and/or modify 9 # it under the terms of the GNU General Public License as published by 10 # the Free Software Foundation; either version 2 of the License, or 11 # (at your option) any later version. 12 # 13 # Plume CMS is distributed in the hope that it will be useful, 14 # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 # GNU General Public License for more details. 17 # 18 # You should have received a copy of the GNU General Public License 19 # along with this program; if not, write to the Free Software 20 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 # 22 # ***** END LICENSE BLOCK ***** */ 23 24 require_once 'path.php'; 25 require_once dirname(__FILE__).'/prepend.php'; 26 auth::checkAuth(PX_AUTH_NORMAL); 27 28 $m = new Manager(); 29 $_px_theme = $m->user->getTheme(); 30 31 require_once config::f('manager_path').'/extinc/class.lum.php'; 32 require_once config::f('manager_path').'/extinc/lib.image.php'; 33 34 if (false === config::loadWebsite($_SESSION['website_id'])) { 35 $m->setError(sprintf(__('Error: Configuration file of the website (<strong>%s</strong>) not available. Please check your installation.'), $_SESSION['website_id']), 500); 36 } 37 38 39 /** 40 * for the moment the logic is here, completely based on the work done in 41 * dotclear with extension to almost all the kind of files, but will need 42 * to move it into classes at some point. 43 */ 44 $px_gd_version = gd_version(); 45 $mode = (!empty($_REQUEST['mode'])) ? $_REQUEST['mode'] : ''; 46 $env = (!empty($_GET['env'])) ? $_GET['env'] : 1; 47 $is_writable = false; 48 $is_dir = true; 49 50 if (false === $m->error()): 51 $up_dir = config::f('xmedia_root'); 52 53 //set the current dir and mode from the session if info available 54 if (empty($_REQUEST['dir'])) { 55 $current_dir = $m->user->getPref('xmedia_current_dir'); 56 if (!empty($current_dir)) { 57 // the current dir is coming from the session, 58 // set the $env from it or set it to 1 59 $env = ($m->user->getPref('xmedia_current_page')) ? $m->user->getPref('xmedia_current_page') : 1; 60 //we need to ensure a "correct" request URI to work with the lum class 61 if ('.php' == substr($_SERVER['REQUEST_URI'], strlen($_SERVER['REQUEST_URI'])-4, 4)) 62 $_SERVER['REQUEST_URI'] .= '?'; 63 $_SERVER['REQUEST_URI'] = str_replace('?','?dir='.$current_dir.'&env='.$env.'&',$_SERVER['REQUEST_URI']); 64 } 65 } else { 66 $current_dir = $_REQUEST['dir']; 67 } 68 69 if (!empty($current_dir)) { 70 $current_dir = str_replace('\\','',$current_dir); 71 $current_dir = str_replace('..','',$current_dir); 72 $current_dir = preg_replace( '#(/)+#', '/', $current_dir); 73 $current_dir = preg_replace( '#^(/)+#', '', $current_dir); 74 $current_dir = preg_replace( '#(/)+$#', '', $current_dir); 75 if (!empty($current_dir)) 76 $current_dir .= '/'; 77 } else { 78 $current_dir = ''; 79 } 80 81 /* check rights */ 82 if (is_dir($up_dir.'/'.$current_dir)) { 83 if (is_writable($up_dir.'/'.$current_dir)) { 84 $is_writable = true; 85 } else { 86 $m->setError(sprintf(__('Error: The system has no write access to the folder <strong>%s</strong>. Check the permissions.'), config::f('rel_url_files').'/'.$current_dir), 500); 87 } 88 } else { 89 $m->setError(sprintf(__('Error: The folder <strong>%s</strong> does not exist.'), config::f('rel_url_files').'/'.$current_dir), 500); 90 $is_dir = false; 91 } 92 endif; //end of if (false === $m->error()): 93 if ($is_dir) { 94 $m->user->savePref('xmedia_current_dir', $current_dir, $_SESSION['website_id'], true); 95 } else { 96 $m->user->savePref('xmedia_current_dir', '/', $_SESSION['website_id'], true); 97 $current_dir = '/'; 98 } 99 /* modification of the file */ 100 if (!empty($_GET['file']) && (false === $m->error())) { 101 $px_file = str_replace('..','',$_GET['file']); 102 $px_file = preg_replace( '#(/)+#', '/', $px_file); 103 $px_file = preg_replace( '#^(/)+#', '', $px_file); 104 105 if (!file_exists($up_dir.'/'.$px_file)) { 106 $m->setError(__('Error: The requested file does not exist.'), 400); 107 } else { 108 if (!empty($_GET['del']) && $_GET['del'] == 1) { 109 if (@unlink($up_dir.'/'.$px_file) === false) { 110 $m->setError(__('Error: Impossible to delete the file.'), 500); 111 } else { 112 @unlink($up_dir.'/thumb/'.md5($px_file).'.jpg'); 113 $m->setMessage(__('File deleted with success.')); 114 header('Location: xmedia.php?dir='.rawurlencode($current_dir).'&mode='.$mode); 115 exit(); 116 } 117 } elseif(!empty($_GET['thumb']) && $_GET['thumb'] == 1) { 118 $thumb = $up_dir.'/thumb/'.md5($px_file).'.jpg'; 119 @$thumb = cropImg($up_dir.'/'.$px_file, $thumb, 150, 100); 120 } 121 } 122 } 123 124 /* Upload of the file */ 125 if ($is_writable && !empty($_FILES['up_file']) && (false === $m->error())) { 126 $tmp_file = $_FILES['up_file']['tmp_name']; 127 $file_name = $_FILES['up_file']['name']; 128 129 if (version_compare(phpversion(),'4.2.0','>=')) { 130 $upd_error = $_FILES['up_file']['error']; 131 } else { 132 $upd_error = 0; 133 } 134 135 if ($upd_error != 0) { 136 switch ($upd_error) { 137 case 1: 138 case 2: 139 $m->setError(__('Error: The size of the file excess the maximum size.'), 400); 140 break; 141 case 3: 142 $m->setError(__('Error: File not fully transfered.'), 400); 143 break; 144 case 4: 145 $m->setError(__('Error: No file.'), 400); 146 break; 147 } 148 } elseif(!file_exists($tmp_file)) { 149 $m->setError(__('Error: No file.'), 400); 150 } elseif(filesize($tmp_file) > config::f('max_upload_size')) { 151 $m->setError(__('Error: The size of the file excess the maximum size.'), 400); 152 } else { 153 $file_name = preg_replace( '#(\s+)#', '_', $file_name); 154 if(!isFileSafe($file_name)) { 155 $m->setError(__('Error: Not an authorized type of file. The file name must contain only simple letters, digits, "-", "_" and a recognized extension. No spaces allowed.'), 400); 156 } else { 157 if (@copy($tmp_file,$up_dir.'/'.$current_dir.$file_name)) { 158 @chmod($up_dir.'/'.$current_dir.$file_name, 0666); 159 /* create thumb */ 160 $thumb = $up_dir.'/thumb/'.md5($current_dir.$file_name).'.jpg'; 161 @unlink($thumb); //ensure that the old thumbnail is removed if available 162 @$msg=cropImg($up_dir.'/'.$current_dir.$file_name, $thumb, 150, 100); 163 @chmod($thumb, 0666); 164 165 $m->setMessage(__('File successfully uploaded.')); 166 header('Location: xmedia.php?dir='.rawurlencode($current_dir) 167 .'&mode='.$mode.'&env='.$env); 168 exit(); 169 } else { 170 $m->setError(__('An error occured during the transfer of the file.'), 500); 171 } 172 } 173 } 174 } 175 176 /* Create a subfolder */ 177 if ($is_writable && !empty($_POST['create']) && (false === $m->error()) 178 && (auth::asLevel(PX_AUTH_ADVANCED)) 179 ) { 180 if (!empty($_POST['new_folder'])) { 181 $new_dir = trim($_POST['new_folder']); 182 if (preg_match('/[^A-Za-z0-9\-\_]/', $new_dir) or ($new_dir == 'thumb')) { 183 $m->setError( __('Error: Invalid folder name, it must contain only letters, digits, "_" and "-".'), 400); 184 } else { 185 if (@mkdir($up_dir.'/'.$current_dir.$new_dir, 0777)) { 186 $m->setMessage(__('The folder was successfully created, you can already add files and images in.')); 187 header('Location: xmedia.php?dir='.rawurlencode($current_dir.$new_dir).'&mode='.$mode); 188 exit(); 189 190 } else { 191 $m->setError( __('Error: Impossible to create the new folder.'), 500); 192 } 193 194 } 195 } 196 } 197 198 199 /* Delete a subfolder */ 200 if ($is_writable && !empty($_REQUEST['delfolder']) && (false === $m->error()) 201 && (auth::asLevel(PX_AUTH_ADVANCED))) { 202 203 $can_delete = true; 204 $can_delete = (strlen($current_dir) != 0) ? true : false; 205 206 if ($is_dir && $can_delete) { 207 $D = dir($up_dir.'/'.$current_dir); 208 while(false !== ($entry = $D->read())) { 209 if ($entry != '.' && $entry != '..' && $entry != '.htaccess' && $entry != '.htpasswd') { 210 $can_delete = false; 211 break; 212 } 213 } 214 $D->close(); 215 } 216 217 if ($can_delete) { 218 // brut force delete of possible files 219 220 if (file_exists($up_dir.'/'.$current_dir.'.htaccess')) 221 @unlink($up_dir.'/'.$current_dir.'.htaccess'); 222 if (file_exists($up_dir.'/'.$current_dir.'.htpasswd')) 223 @unlink($up_dir.'/'.$current_dir.'.htpasswd'); 224 225 if (!rmdir($up_dir.'/'.$current_dir)) { 226 $m->setError( __('Error: Impossible to delete the folder.'), 500); 227 } else { 228 $m->setMessage(__('Folder successfully deleted.')); 229 $dir = getParentDir($current_dir); 230 if (empty($dir)) $dir = '/'; 231 header('Location: xmedia.php?dir='.rawurlencode($dir).'&mode='.$mode); 232 exit(); 233 } 234 } 235 } 236 237 /*============================================================================= 238 Display block 239 =============================================================================*/ 240 241 /*================================================= 242 Set title of the page, and load common top page 243 =================================================*/ 244 $px_title = __('Files and images'); 245 246 if ($mode == 'popup') { 247 include dirname(__FILE__).'/mtemplates/_pop_top.php'; 248 } else { 249 // sub menu 250 $px_submenu->addItem( __('Back to the list of resources'),'index.php','themes/'.$_px_theme.'/images/ico_back.png',false); 251 252 include dirname(__FILE__).'/mtemplates/_top.php'; 253 } 254 255 echo '<h1>'. __('Files and images')."</h1>\n\n"; 256 257 ?> 258 259 <?php if($is_writable) : ?> 260 261 <form enctype="multipart/form-data" action="xmedia.php" method="post" onsubmit="return isReady('up_file','<?php echo __('Error: No file.') ?>')"> 262 <fieldset><legend><?php echo __('Add a file to the current folder'); ?></legend> 263 <p><label for="up_file"><?php echo sprintf( __('Choose a file (maximum size %s)'), prettySize($_PX_config['max_upload_size'])); ?> <?php echo $m->HelpLink('xmedia', 'h-add-file'); ?></label> 264 <input name="up_file" id="up_file" type="file" /> 265 <input type="hidden" name="MAX_FILE_SIZE" value="<?php echo $_PX_config['max_upload_size']; ?>" /> 266 <input type="hidden" name="mode" value="<?php echo $mode; ?>" /> 267 <input type="hidden" name="env" value="<?php echo $env; ?>" /> 268 <input type="hidden" name="dir" value="<?php echo $current_dir; ?>" /></p><p> 269 <input class="submit" type="submit" value="<?php echo __('Add the file'); ?>" /></p> 270 </fieldset> 271 </form> 272 <?php endif; ?> 273 274 <h2><?php echo __('Your files'); ?></h2> 275 <?php 276 /* Start populating the list of files and folders */ 277 $img_list = array(); 278 $rep_list = array(); 279 280 if ($is_dir) { 281 $D = dir($up_dir.'/'.$current_dir); 282 $i = 0; 283 $j = 0; 284 //Get the parent folder to go "up" one level. 285 if (strlen($current_dir) > 0) { 286 $parent_dir = getParentDir($current_dir); 287 if (empty($parent_dir)) $parent_dir = '/'; 288 $rep_list[$j]['url'] = config::f('rel_url_files').'/'.$parent_dir; 289 $rep_list[$j]['name'] = __('Parent folder'); 290 $rep_list[$j]['current_dir'] = $parent_dir; 291 $rep_list[$j]['type'] = 'updir'; 292 $j++; 293 } 294 while(false !== ($entry = $D->read())) 295 { 296 if($entry != '.' && $entry != '..' && $entry != '.htaccess' && $entry != '.htpasswd') { 297 if (!is_dir($up_dir.'/'.$current_dir.$entry)) { 298 $img_list[$i]['url'] = config::f('rel_url_files').'/' 299 .$current_dir.$entry; 300 $img_list[$i]['name'] = $entry; 301 $img_list[$i]['current_dir'] = $current_dir; 302 $img_list[$i]['type'] = 'file'; 303 $i++; 304 } elseif ($entry != 'thumb') { 305 $rep_list[$j]['url'] = config::f('rel_url_files').'/' 306 .$current_dir.$entry; 307 $rep_list[$j]['name'] = $entry; 308 $rep_list[$j]['current_dir'] = $current_dir.$entry; 309 $rep_list[$j]['type'] = 'dir'; 310 $j++; 311 } 312 } 313 } 314 $D->close(); 315 } 316 /* End populating the list of files and folders */ 317 318 /* Line to display a file */ 319 function line_file($data,$i) 320 { 321 global $mode, $up_dir, $_PX_website_config, $m, 322 $px_gd_version, $env, $_px_theme; 323 324 // 4 kinds of entry: "up" folder, folder, image and normal file 325 // 2 modes: popup and normal 326 $is_dir = false; 327 $is_file = false; 328 $is_image = false; 329 $is_updir = false; 330 $url = $data['url']; 331 $name = $data['name']; 332 $current_dir = $data['current_dir']; 333 334 switch ($data['type']) { 335 case 'file': 336 $is_image = isImage($name); 337 $is_file = !$is_image; 338 $ext = getFileExtension($name); 339 break; 340 case 'dir': 341 $is_dir = true; 342 break; 343 case 'updir': 344 $is_updir = true; 345 break; 346 } 347 348 $res = ''; //final string to be displayed. 349 350 //contains the height/width of the image or the size of 351 // the file, nothing if an image and impossible to get the size 352 $file_size = ''; 353 354 $create_thumb = ''; //link to create the thumbnail 355 $icons_dir = config::f('manager_path').'/themes/' 356 .$_px_theme.'/images/icons/'; 357 358 $delete_link = '<a href="xmedia.php?dir='.rawurlencode($current_dir) 359 .'&file='.rawurlencode($current_dir.$name).'&del=1&mode=' 360 .$mode.'&env='.$env.'" title="'. __('Delete') 361 .'" onclick="return window.confirm(\'' 362 . __('Are you sure you want to delete this file?') 363 .'\')"><img src="themes/'.$_px_theme.'/images/delete.png" alt="' 364 .__('Delete').'" /></a>'; 365 366 // Get size of the file in $file_size format ready to be displayed 367 if ($is_image) { 368 $siz = @getimagesize(config::f('xmedia_root').'/'.$current_dir.$name); 369 if ($siz !== false && 'html' == $m->user->getPref('content_format')) { 370 //HTML format 371 $file_size = __('<strong>size</strong>:').' '.$siz[3]; 372 } elseif ($siz !== false) { 373 //wiki format 374 $file_size = __('<strong>size</strong>:').' '.$siz[0].'x'.$siz[1]; 375 } 376 } elseif ($is_file) { 377 //size in kb 378 $file_size = __('<strong>size</strong>:').' ' 379 .prettySize(filesize(config::f('xmedia_root').'/' 380 .$current_dir.$name)); 381 } 382 383 if ($mode == 'popup' && ($is_image || $is_file)) { 384 //call from the popup 385 $act = ($is_image) ? 'img' : 'file'; 386 $action_link = '<a href="#" ' 387 .'onclick="insertImage(window.opener.document,\''.$url 388 .'\',\''.$act.'\',\'' 389 .addslashes(__('Title of the file or image:')).'\'); ' 390 .'window.close(); return false;">%s</a>'; 391 } elseif ($is_dir || $is_updir) { 392 $slash = ($is_dir) ? '/' : ''; 393 $action_link = '<a href="xmedia.php?dir='.$current_dir.$slash 394 .'&mode='.$mode.'">%s</a>'; 395 } else { 396 //call from the "normal" list of files page 397 $action_link = '<a href="http://'.config::f('domain').$url.'">%s</a>'; 398 } 399 400 // create the thumbnail link 401 if ($is_file || $is_image) { 402 if (file_exists($up_dir.'/thumb/'.md5($current_dir.$name).'.jpg')) { 403 //thumbnail exists 404 $th = sprintf($action_link, 405 '<img class="thumbnail" src="' 406 .www::getManagedWebsiteUrl() 407 .config::f('rel_url_files') 408 .'/thumb/'.md5($current_dir.$name).'.jpg" alt="" />' 409 ); 410 } elseif ($is_image && $px_gd_version) { 411 //image without thumbnail 412 if (file_exists($icons_dir.$ext.'-dist.png')) { 413 $img = 'themes/'.$_px_theme.'/images/icons/'.$ext.'-dist.png'; 414 } else { 415 $img = 'themes/'.$_px_theme.'/images/icons/default-dist.png'; 416 } 417 $th = sprintf($action_link, 418 '<img class="thumbnailicon" src="'.$img 419 .'" alt="" />'); 420 $create_thumb = '<a href="xmedia.php?dir=' 421 .rawurlencode($current_dir).'&file=' 422 .rawurlencode($current_dir.$name).'&thumb=1&mode=' 423 .$mode.'&env='.$env.'" title="' 424 .__('Try to create the thumbnail').'"><img src="themes/' 425 .$_px_theme.'/images/ico_createthumb.png" alt="' 426 .__('Try to create the thumbnail').'" /></a>'; 427 } else { 428 //normal file 429 $ext = getFileExtension($name); 430 if (file_exists($icons_dir.$ext.'-dist.png')) { 431 $img = 'themes/'.$_px_theme.'/images/icons/'.$ext.'-dist.png'; 432 } else { 433 $img = 'themes/'.$_px_theme.'/images/icons/default-dist.png'; 434 } 435 $th = sprintf($action_link, 436 '<img class="thumbnailicon" src="'.$img 437 .'" alt="" />'); 438 } 439 $res = '<div class="icon">'."\n" 440 .'<p class="legend action">'.$create_thumb.' '.$delete_link.'</p>' 441 ."\n".'<p class="icon">'.$th.'</p>'."\n".'<p class="legend">' 442 .sprintf($action_link,$name).'<br />'."\n".$file_size.'</p>'."\n" 443 .'</div>'."\n"; 444 } elseif ($is_dir || $is_updir) { 445 $ico = ($is_dir) ? 'ico_folder.png' : 'ico_folder_up.png'; 446 $img = 'themes/'.$_px_theme.'/images/'.$ico; 447 $th = sprintf($action_link, 448 '<img class="thumbnailicon" src="'.$img.'" alt="" />'); 449 $res = '<div class="icon">'."\n" 450 .'<p class="icon">'.$th.'</p>'."\n" 451 .'<p class="legend">'.sprintf($action_link,$name).'</p>'."\n" 452 .'</div>'."\n"; 453 } 454 return $res; 455 } 456 457 // Display the files and folders 458 $img_list = array_merge($rep_list, $img_list); 459 460 $objLum = new lum($env, 'line_file', $img_list, 0, 12); 461 $m->user->savePref('xmedia_current_page', $objLum->env, $_SESSION['website_id'], true); 462 $objLum->htmlHeader = '<div class="spacer"> </div>'; 463 $objLum->htmlLineStart = ''; 464 $objLum->htmlColStart = ''; 465 $objLum->htmlColEnd = ''; 466 $objLum->htmlLineEnd = ''; 467 $objLum->htmlFooter = '<div class="spacer"> </div>'; 468 469 $objLum->htmlLinksStart = '<p class="small">'; 470 $objLum->htmlLinksEnd = '</p>'; 471 472 $objLum->htmlCurPgStart = '<strong>'; 473 $objLum->htmlCurPgEnd = '</strong>'; 474 475 $objLum->htmlPrev = __('« previous page'); 476 $objLum->htmlNext = __('» next page'); 477 $objLum->htmlPrevGrp = '...'; 478 $objLum->htmlNextGrp = '...'; 479 480 $objLum->htmlEmpty = '<div class="spacer"> </div><div class="icon"><p class="icon"><strong>'.__('No file for the moment.').'</strong></p></div><div class="spacer"> </div>'; 481 $objLum->htmlLinksLib = __('page(s):'); 482 483 if ($is_dir) { 484 $parent_dir = getParentDir($current_dir); 485 if (empty($parent_dir)) $parent_dir = '/'; 486 487 echo '<p class="small">'; 488 if (strlen($current_dir) > 0) { 489 echo '<a href="xmedia.php?dir='.$parent_dir.'&mode='.$mode 490 .'" title="'.__('Go one folder up.').'"><img src="themes/' 491 .$_px_theme.'/images/ico_folder_up_small.png" alt=" " /></a> '; 492 } 493 echo sprintf(__('You are in the folder <strong>%s</strong>'), 494 config::f('rel_url_files').'/'.$current_dir); 495 echo '</p>'; 496 497 echo $objLum->drawLinks()."\n\n"; 498 echo $objLum->drawPage()."\n\n"; 499 echo $objLum->drawLinks()."\n\n"; 500 501 echo '<p class="small">'; 502 if (strlen($current_dir) > 0) { 503 echo '<a href="xmedia.php?dir='.$parent_dir.'&mode='.$mode 504 .'" title="'.__('Go one folder up.').'"><img src="themes/' 505 .$_px_theme.'/images/ico_folder_up_small.png" alt=" " /></a> '; 506 } 507 echo sprintf(__('You are in the folder <strong>%s</strong>'), 508 config::f('rel_url_files').'/'.$current_dir); 509 510 if (count($rep_list) == 1 511 && count($img_list) == 1 512 && $rep_list[0]['type'] == 'updir' 513 && $is_writable 514 && false === $m->error() 515 && auth::asLevel(PX_AUTH_ADVANCED) 516 ) { 517 518 echo ' <strong><a href="xmedia.php?dir=' 519 .rawurlencode($current_dir).'&delfolder=1&mode=' 520 .$mode.'" ' 521 .'onclick="return window.confirm(\'' 522 .__('Are you sure you want to delete this folder?').'\')" title="' 523 .__('Delete this folder').'"><img src="themes/'.$_px_theme 524 .'/images/delete.png" alt=" " /></a></strong>'; 525 } 526 echo '</p>'; 527 528 if ($is_writable && (false === $m->error()) 529 && (auth::asLevel(PX_AUTH_ADVANCED)) ) { 530 ?><form action='xmedia.php' method='POST'> 531 <input type='hidden' name='dir' value='<?php echo $current_dir; ?>' /> 532 <input type='hidden' name='mode' value='<?php echo $mode; ?>' /> 533 <p> 534 <span class="nowrap"><label for="new_folder" 535 style="display:inline"><?php echo __('Create a sub-folder'); ?> <?php echo $m->HelpLink('xmedia', 'h-sub-folder'); ?></label> 536 <?php echo form::textField('new_folder', 15, 30, '', '', ''); ?> 537 <input name="create" type="submit" class="submit" value="<?php echo __('Create'); ?>" /> 538 </span></p> 539 </form> 540 <?php 541 542 } 543 } 544 545 ?> 546 547 548 <?php 549 if ($mode == 'popup') { 550 include dirname(__FILE__).'/mtemplates/_pop_bottom.php'; 551 } else { 552 include dirname(__FILE__).'/mtemplates/_bottom.php'; 553 } 554 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Mon Nov 26 11:57:01 2007 | par Balluche grâce à PHPXref 0.7 |
|