[ Index ]

PHP Cross Reference of Wordpress 2.9.1

title

Body

[close]

/wp-admin/includes/ -> file.php (source)

   1  <?php
   2  /**
   3   * File contains all the administration image manipulation functions.
   4   *
   5   * @package WordPress
   6   * @subpackage Administration
   7   */
   8  
   9  /** The descriptions for theme files. */
  10  $wp_file_descriptions = array (
  11      'index.php' => __( 'Main Index Template' ),
  12      'style.css' => __( 'Stylesheet' ),
  13      'rtl.css' => __( 'RTL Stylesheet' ),
  14      'comments.php' => __( 'Comments' ),
  15      'comments-popup.php' => __( 'Popup Comments' ),
  16      'footer.php' => __( 'Footer' ),
  17      'header.php' => __( 'Header' ),
  18      'sidebar.php' => __( 'Sidebar' ),
  19      'archive.php' => __( 'Archives' ),
  20      'category.php' => __( 'Category Template' ),
  21      'page.php' => __( 'Page Template' ),
  22      'search.php' => __( 'Search Results' ),
  23      'searchform.php' => __( 'Search Form' ),
  24      'single.php' => __( 'Single Post' ),
  25      '404.php' => __( '404 Template' ),
  26      'link.php' => __( 'Links Template' ),
  27      'functions.php' => __( 'Theme Functions' ),
  28      'attachment.php' => __( 'Attachment Template' ),
  29      'image.php' => __('Image Attachment Template'),
  30      'video.php' => __('Video Attachment Template'),
  31      'audio.php' => __('Audio Attachment Template'),
  32      'application.php' => __('Application Attachment Template'),
  33      'my-hacks.php' => __( 'my-hacks.php (legacy hacks support)' ),
  34      '.htaccess' => __( '.htaccess (for rewrite rules )' ),
  35      // Deprecated files
  36      'wp-layout.css' => __( 'Stylesheet' ), 'wp-comments.php' => __( 'Comments Template' ), 'wp-comments-popup.php' => __( 'Popup Comments Template' ));
  37  
  38  /**
  39   * {@internal Missing Short Description}}
  40   *
  41   * @since unknown
  42   *
  43   * @param unknown_type $file
  44   * @return unknown
  45   */
  46  function get_file_description( $file ) {
  47      global $wp_file_descriptions;
  48  
  49      if ( isset( $wp_file_descriptions[basename( $file )] ) ) {
  50          return $wp_file_descriptions[basename( $file )];
  51      }
  52      elseif ( file_exists( WP_CONTENT_DIR . $file ) && is_file( WP_CONTENT_DIR . $file ) ) {
  53          $template_data = implode( '', file( WP_CONTENT_DIR . $file ) );
  54          if ( preg_match( '|Template Name:(.*)$|mi', $template_data, $name ))
  55              return _cleanup_header_comment($name[1]) . ' Page Template';
  56      }
  57  
  58      return basename( $file );
  59  }
  60  
  61  /**
  62   * {@internal Missing Short Description}}
  63   *
  64   * @since unknown
  65   *
  66   * @return unknown
  67   */
  68  function get_home_path() {
  69      $home = get_option( 'home' );
  70      $siteurl = get_option( 'siteurl' );
  71      if ( $home != '' && $home != $siteurl ) {
  72              $wp_path_rel_to_home = str_replace($home, '', $siteurl); /* $siteurl - $home */
  73              $pos = strpos($_SERVER["SCRIPT_FILENAME"], $wp_path_rel_to_home);
  74              $home_path = substr($_SERVER["SCRIPT_FILENAME"], 0, $pos);
  75          $home_path = trailingslashit( $home_path );
  76      } else {
  77          $home_path = ABSPATH;
  78      }
  79  
  80      return $home_path;
  81  }
  82  
  83  /**
  84   * {@internal Missing Short Description}}
  85   *
  86   * @since unknown
  87   *
  88   * @param unknown_type $file
  89   * @return unknown
  90   */
  91  function get_real_file_to_edit( $file ) {
  92      if ('index.php' == $file || '.htaccess' == $file ) {
  93          $real_file = get_home_path() . $file;
  94      } else {
  95          $real_file = WP_CONTENT_DIR . $file;
  96      }
  97  
  98      return $real_file;
  99  }
 100  
 101  /**
 102   * Returns a listing of all files in the specified folder and all subdirectories up to 100 levels deep.
 103   * The depth of the recursiveness can be controlled by the $levels param.
 104   *
 105   * @since 2.6.0
 106   *
 107   * @param string $folder Full path to folder
 108   * @param int $levels (optional) Levels of folders to follow, Default: 100 (PHP Loop limit).
 109   * @return bool|array False on failure, Else array of files
 110   */
 111  function list_files( $folder = '', $levels = 100 ) {
 112      if( empty($folder) )
 113          return false;
 114  
 115      if( ! $levels )
 116          return false;
 117  
 118      $files = array();
 119      if ( $dir = @opendir( $folder ) ) {
 120          while (($file = readdir( $dir ) ) !== false ) {
 121              if ( in_array($file, array('.', '..') ) )
 122                  continue;
 123              if ( is_dir( $folder . '/' . $file ) ) {
 124                  $files2 = list_files( $folder . '/' . $file, $levels - 1);
 125                  if( $files2 )
 126                      $files = array_merge($files, $files2 );
 127                  else
 128                      $files[] = $folder . '/' . $file . '/';
 129              } else {
 130                  $files[] = $folder . '/' . $file;
 131              }
 132          }
 133      }
 134      @closedir( $dir );
 135      return $files;
 136  }
 137  
 138  /**
 139   * Determines a writable directory for temporary files.
 140   * Function's preference is to WP_CONTENT_DIR followed by the return value of <code>sys_get_temp_dir()</code>, before finally defaulting to /tmp/
 141   *
 142   * In the event that this function does not find a writable location, It may be overridden by the <code>WP_TEMP_DIR</code> constant in your <code>wp-config.php</code> file.
 143   *
 144   * @since 2.5.0
 145   *
 146   * @return string Writable temporary directory
 147   */
 148  function get_temp_dir() {
 149      if ( defined('WP_TEMP_DIR') )
 150          return trailingslashit(WP_TEMP_DIR);
 151  
 152      $temp = WP_CONTENT_DIR . '/';
 153      if ( is_dir($temp) && is_writable($temp) )
 154          return $temp;
 155  
 156      if  ( function_exists('sys_get_temp_dir') )
 157          return trailingslashit(sys_get_temp_dir());
 158  
 159      return '/tmp/';
 160  }
 161  
 162  /**
 163   * Returns a filename of a Temporary unique file.
 164   * Please note that the calling function must unlink() this itself.
 165   *
 166   * The filename is based off the passed parameter or defaults to the current unix timestamp,
 167   * while the directory can either be passed as well, or by leaving  it blank, default to a writable temporary directory.
 168   *
 169   * @since 2.6.0
 170   *
 171   * @param string $filename (optional) Filename to base the Unique file off
 172   * @param string $dir (optional) Directory to store the file in
 173   * @return string a writable filename
 174   */
 175  function wp_tempnam($filename = '', $dir = ''){
 176      if ( empty($dir) )
 177          $dir = get_temp_dir();
 178      $filename = basename($filename);
 179      if ( empty($filename) )
 180          $filename = time();
 181  
 182      $filename = preg_replace('|\..*$|', '.tmp', $filename);
 183      $filename = $dir . wp_unique_filename($dir, $filename);
 184      touch($filename);
 185      return $filename;
 186  }
 187  
 188  /**
 189   * {@internal Missing Short Description}}
 190   *
 191   * @since unknown
 192   *
 193   * @param unknown_type $file
 194   * @param unknown_type $allowed_files
 195   * @return unknown
 196   */
 197  function validate_file_to_edit( $file, $allowed_files = '' ) {
 198      $code = validate_file( $file, $allowed_files );
 199  
 200      if (!$code )
 201          return $file;
 202  
 203      switch ( $code ) {
 204          case 1 :
 205              wp_die( __('Sorry, can&#8217;t edit files with &#8220;..&#8221; in the name. If you are trying to edit a file in your WordPress home directory, you can just type the name of the file in.' ));
 206  
 207          //case 2 :
 208          //    wp_die( __('Sorry, can&#8217;t call files with their real path.' ));
 209  
 210          case 3 :
 211              wp_die( __('Sorry, that file cannot be edited.' ));
 212      }
 213  }
 214  
 215  /**
 216   * {@internal Missing Short Description}}
 217   *
 218   * @since unknown
 219   *
 220   * @param array $file Reference to a single element of $_FILES. Call the function once for each uploaded file.
 221   * @param array $overrides Optional. An associative array of names=>values to override default variables with extract( $overrides, EXTR_OVERWRITE ).
 222   * @return array On success, returns an associative array of file attributes. On failure, returns $overrides['upload_error_handler'](&$file, $message ) or array( 'error'=>$message ).
 223   */
 224  function wp_handle_upload( &$file, $overrides = false, $time = null ) {
 225      // The default error handler.
 226      if (! function_exists( 'wp_handle_upload_error' ) ) {
 227  		function wp_handle_upload_error( &$file, $message ) {
 228              return array( 'error'=>$message );
 229          }
 230      }
 231  
 232      $file = apply_filters( 'wp_handle_upload_prefilter', $file );
 233  
 234      // You may define your own function and pass the name in $overrides['upload_error_handler']
 235      $upload_error_handler = 'wp_handle_upload_error';
 236  
 237      // You may have had one or more 'wp_handle_upload_prefilter' functions error out the file.  Handle that gracefully.
 238      if ( isset( $file['error'] ) && !is_numeric( $file['error'] ) && $file['error'] )
 239          return $upload_error_handler( $file, $file['error'] );
 240  
 241      // You may define your own function and pass the name in $overrides['unique_filename_callback']
 242      $unique_filename_callback = null;
 243  
 244      // $_POST['action'] must be set and its value must equal $overrides['action'] or this:
 245      $action = 'wp_handle_upload';
 246  
 247      // Courtesy of php.net, the strings that describe the error indicated in $_FILES[{form field}]['error'].
 248      $upload_error_strings = array( false,
 249          __( "The uploaded file exceeds the <code>upload_max_filesize</code> directive in <code>php.ini</code>." ),
 250          __( "The uploaded file exceeds the <em>MAX_FILE_SIZE</em> directive that was specified in the HTML form." ),
 251          __( "The uploaded file was only partially uploaded." ),
 252          __( "No file was uploaded." ),
 253          '',
 254          __( "Missing a temporary folder." ),
 255          __( "Failed to write file to disk." ),
 256          __( "File upload stopped by extension." ));
 257  
 258      // All tests are on by default. Most can be turned off by $override[{test_name}] = false;
 259      $test_form = true;
 260      $test_size = true;
 261  
 262      // If you override this, you must provide $ext and $type!!!!
 263      $test_type = true;
 264      $mimes = false;
 265  
 266      // Install user overrides. Did we mention that this voids your warranty?
 267      if ( is_array( $overrides ) )
 268          extract( $overrides, EXTR_OVERWRITE );
 269  
 270      // A correct form post will pass this test.
 271      if ( $test_form && (!isset( $_POST['action'] ) || ($_POST['action'] != $action ) ) )
 272          return $upload_error_handler( $file, __( 'Invalid form submission.' ));
 273  
 274      // A successful upload will pass this test. It makes no sense to override this one.
 275      if ( $file['error'] > 0 )
 276          return $upload_error_handler( $file, $upload_error_strings[$file['error']] );
 277  
 278      // A non-empty file will pass this test.
 279      if ( $test_size && !($file['size'] > 0 ) )
 280          return $upload_error_handler( $file, __( 'File is empty. Please upload something more substantial. This error could also be caused by uploads being disabled in your php.ini or by post_max_size being defined as smaller than upload_max_filesize in php.ini.' ));
 281  
 282      // A properly uploaded file will pass this test. There should be no reason to override this one.
 283      if (! @ is_uploaded_file( $file['tmp_name'] ) )
 284          return $upload_error_handler( $file, __( 'Specified file failed upload test.' ));
 285  
 286      // A correct MIME type will pass this test. Override $mimes or use the upload_mimes filter.
 287      if ( $test_type ) {
 288          $wp_filetype = wp_check_filetype( $file['name'], $mimes );
 289  
 290          extract( $wp_filetype );
 291  
 292          if ( ( !$type || !$ext ) && !current_user_can( 'unfiltered_upload' ) )
 293              return $upload_error_handler( $file, __( 'File type does not meet security guidelines. Try another.' ));
 294  
 295          if ( !$ext )
 296              $ext = ltrim(strrchr($file['name'], '.'), '.');
 297  
 298          if ( !$type )
 299              $type = $file['type'];
 300      } else {
 301          $type = '';
 302      }
 303  
 304      // A writable uploads dir will pass this test. Again, there's no point overriding this one.
 305      if ( ! ( ( $uploads = wp_upload_dir($time) ) && false === $uploads['error'] ) )
 306          return $upload_error_handler( $file, $uploads['error'] );
 307  
 308      $filename = wp_unique_filename( $uploads['path'], $file['name'], $unique_filename_callback );
 309  
 310      // Move the file to the uploads dir
 311      $new_file = $uploads['path'] . "/$filename";
 312      if ( false === @ move_uploaded_file( $file['tmp_name'], $new_file ) ) {
 313          return $upload_error_handler( $file, sprintf( __('The uploaded file could not be moved to %s.' ), $uploads['path'] ) );
 314      }
 315  
 316      // Set correct file permissions
 317      $stat = stat( dirname( $new_file ));
 318      $perms = $stat['mode'] & 0000666;
 319      @ chmod( $new_file, $perms );
 320  
 321      // Compute the URL
 322      $url = $uploads['url'] . "/$filename";
 323  
 324      return apply_filters( 'wp_handle_upload', array( 'file' => $new_file, 'url' => $url, 'type' => $type ) );
 325  }
 326  
 327  /**
 328   * {@internal Missing Short Description}}
 329   *
 330   * Pass this function an array similar to that of a $_FILES POST array.
 331   *
 332   * @since unknown
 333   *
 334   * @param unknown_type $file
 335   * @param unknown_type $overrides
 336   * @return unknown
 337   */
 338  function wp_handle_sideload( &$file, $overrides = false ) {
 339      // The default error handler.
 340      if (! function_exists( 'wp_handle_upload_error' ) ) {
 341  		function wp_handle_upload_error( &$file, $message ) {
 342              return array( 'error'=>$message );
 343          }
 344      }
 345  
 346      // You may define your own function and pass the name in $overrides['upload_error_handler']
 347      $upload_error_handler = 'wp_handle_upload_error';
 348  
 349      // You may define your own function and pass the name in $overrides['unique_filename_callback']
 350      $unique_filename_callback = null;
 351  
 352      // $_POST['action'] must be set and its value must equal $overrides['action'] or this:
 353      $action = 'wp_handle_sideload';
 354  
 355      // Courtesy of php.net, the strings that describe the error indicated in $_FILES[{form field}]['error'].
 356      $upload_error_strings = array( false,
 357          __( "The uploaded file exceeds the <code>upload_max_filesize</code> directive in <code>php.ini</code>." ),
 358          __( "The uploaded file exceeds the <em>MAX_FILE_SIZE</em> directive that was specified in the HTML form." ),
 359          __( "The uploaded file was only partially uploaded." ),
 360          __( "No file was uploaded." ),
 361          '',
 362          __( "Missing a temporary folder." ),
 363          __( "Failed to write file to disk." ),
 364          __( "File upload stopped by extension." ));
 365  
 366      // All tests are on by default. Most can be turned off by $override[{test_name}] = false;
 367      $test_form = true;
 368      $test_size = true;
 369  
 370      // If you override this, you must provide $ext and $type!!!!
 371      $test_type = true;
 372      $mimes = false;
 373  
 374      // Install user overrides. Did we mention that this voids your warranty?
 375      if ( is_array( $overrides ) )
 376          extract( $overrides, EXTR_OVERWRITE );
 377  
 378      // A correct form post will pass this test.
 379      if ( $test_form && (!isset( $_POST['action'] ) || ($_POST['action'] != $action ) ) )
 380          return $upload_error_handler( $file, __( 'Invalid form submission.' ));
 381  
 382      // A successful upload will pass this test. It makes no sense to override this one.
 383      if ( $file['error'] > 0 )
 384          return $upload_error_handler( $file, $upload_error_strings[$file['error']] );
 385  
 386      // A non-empty file will pass this test.
 387      if ( $test_size && !(filesize($file['tmp_name']) > 0 ) )
 388          return $upload_error_handler( $file, __( 'File is empty. Please upload something more substantial. This error could also be caused by uploads being disabled in your php.ini.' ));
 389  
 390      // A properly uploaded file will pass this test. There should be no reason to override this one.
 391      if (! @ is_file( $file['tmp_name'] ) )
 392          return $upload_error_handler( $file, __( 'Specified file does not exist.' ));
 393  
 394      // A correct MIME type will pass this test. Override $mimes or use the upload_mimes filter.
 395      if ( $test_type ) {
 396          $wp_filetype = wp_check_filetype( $file['name'], $mimes );
 397  
 398          extract( $wp_filetype );
 399  
 400          if ( ( !$type || !$ext ) && !current_user_can( 'unfiltered_upload' ) )
 401              return $upload_error_handler( $file, __( 'File type does not meet security guidelines. Try another.' ));
 402  
 403          if ( !$ext )
 404              $ext = ltrim(strrchr($file['name'], '.'), '.');
 405  
 406          if ( !$type )
 407              $type = $file['type'];
 408      }
 409  
 410      // A writable uploads dir will pass this test. Again, there's no point overriding this one.
 411      if ( ! ( ( $uploads = wp_upload_dir() ) && false === $uploads['error'] ) )
 412          return $upload_error_handler( $file, $uploads['error'] );
 413  
 414      $filename = wp_unique_filename( $uploads['path'], $file['name'], $unique_filename_callback );
 415  
 416      // Strip the query strings.
 417      $filename = str_replace('?','-', $filename);
 418      $filename = str_replace('&','-', $filename);
 419  
 420      // Move the file to the uploads dir
 421      $new_file = $uploads['path'] . "/$filename";
 422      if ( false === @ rename( $file['tmp_name'], $new_file ) ) {
 423          return $upload_error_handler( $file, sprintf( __('The uploaded file could not be moved to %s.' ), $uploads['path'] ) );
 424      }
 425  
 426      // Set correct file permissions
 427      $stat = stat( dirname( $new_file ));
 428      $perms = $stat['mode'] & 0000666;
 429      @ chmod( $new_file, $perms );
 430  
 431      // Compute the URL
 432      $url = $uploads['url'] . "/$filename";
 433  
 434      $return = apply_filters( 'wp_handle_upload', array( 'file' => $new_file, 'url' => $url, 'type' => $type ) );
 435  
 436      return $return;
 437  }
 438  
 439  /**
 440   * Downloads a url to a local temporary file using the WordPress HTTP Class.
 441   * Please note, That the calling function must unlink() the  file.
 442   *
 443   * @since 2.5.0
 444   *
 445   * @param string $url the URL of the file to download
 446   * @return mixed WP_Error on failure, string Filename on success.
 447   */
 448  function download_url( $url ) {
 449      //WARNING: The file is not automatically deleted, The script must unlink() the file.
 450      if ( ! $url )
 451          return new WP_Error('http_no_url', __('Invalid URL Provided'));
 452  
 453      $tmpfname = wp_tempnam($url);
 454      if ( ! $tmpfname )
 455          return new WP_Error('http_no_file', __('Could not create Temporary file'));
 456  
 457      $handle = @fopen($tmpfname, 'wb');
 458      if ( ! $handle )
 459          return new WP_Error('http_no_file', __('Could not create Temporary file'));
 460  
 461      $response = wp_remote_get($url, array('timeout' => 300));
 462  
 463      if ( is_wp_error($response) ) {
 464          fclose($handle);
 465          unlink($tmpfname);
 466          return $response;
 467      }
 468  
 469      if ( $response['response']['code'] != '200' ){
 470          fclose($handle);
 471          unlink($tmpfname);
 472          return new WP_Error('http_404', trim($response['response']['message']));
 473      }
 474  
 475      fwrite($handle, $response['body']);
 476      fclose($handle);
 477  
 478      return $tmpfname;
 479  }
 480  
 481  /**
 482   * Unzip's a specified ZIP file to a location on the Filesystem via the WordPress Filesystem Abstraction.
 483   * Assumes that WP_Filesystem() has already been called and set up.
 484   *
 485   * Attempts to increase the PHP Memory limit to 256M before uncompressing,
 486   * However, The most memory required shouldn't be much larger than the Archive itself.
 487   *
 488   * @since 2.5.0
 489   *
 490   * @param string $file Full path and filename of zip archive
 491   * @param string $to Full path on the filesystem to extract archive to
 492   * @return mixed WP_Error on failure, True on success
 493   */
 494  function unzip_file($file, $to) {
 495      global $wp_filesystem;
 496  
 497      if ( ! $wp_filesystem || !is_object($wp_filesystem) )
 498          return new WP_Error('fs_unavailable', __('Could not access filesystem.'));
 499  
 500      // Unzip uses a lot of memory, but not this much hopefully
 501      @ini_set('memory_limit', '256M');
 502  
 503      $fs =& $wp_filesystem;
 504  
 505      require_once (ABSPATH . 'wp-admin/includes/class-pclzip.php');
 506  
 507      $archive = new PclZip($file);
 508  
 509      // Is the archive valid?
 510      if ( false == ($archive_files = $archive->extract(PCLZIP_OPT_EXTRACT_AS_STRING)) )
 511          return new WP_Error('incompatible_archive', __('Incompatible archive'), $archive->errorInfo(true));
 512  
 513      if ( 0 == count($archive_files) )
 514          return new WP_Error('empty_archive', __('Empty archive'));
 515  
 516      $path = explode('/', untrailingslashit($to));
 517      for ( $i = count($path); $i > 0; $i-- ) { //>0 = first element is empty allways for paths starting with '/'
 518          $tmppath = implode('/', array_slice($path, 0, $i) );
 519          if ( $fs->is_dir($tmppath) ) { //Found the highest folder that exists, Create from here(ie +1)
 520              for ( $i = $i + 1; $i <= count($path); $i++ ) {
 521                  $tmppath = implode('/', array_slice($path, 0, $i) );
 522                  if ( ! $fs->mkdir($tmppath, FS_CHMOD_DIR) )
 523                      return new WP_Error('mkdir_failed', __('Could not create directory'), $tmppath);
 524              }
 525              break; //Exit main for loop
 526          }
 527      }
 528  
 529      $to = trailingslashit($to);
 530      foreach ($archive_files as $file) {
 531          $path = $file['folder'] ? $file['filename'] : dirname($file['filename']);
 532          $path = explode('/', $path);
 533          for ( $i = count($path); $i >= 0; $i-- ) { //>=0 as the first element contains data
 534              if ( empty($path[$i]) )
 535                  continue;
 536              $tmppath = $to . implode('/', array_slice($path, 0, $i) );
 537              if ( $fs->is_dir($tmppath) ) {//Found the highest folder that exists, Create from here
 538                  for ( $i = $i + 1; $i <= count($path); $i++ ) { //< count() no file component please.
 539                      $tmppath = $to . implode('/', array_slice($path, 0, $i) );
 540                      if ( ! $fs->is_dir($tmppath) && ! $fs->mkdir($tmppath, FS_CHMOD_DIR) )
 541                          return new WP_Error('mkdir_failed', __('Could not create directory'), $tmppath);
 542                  }
 543                  break; //Exit main for loop
 544              }
 545          }
 546  
 547          // We've made sure the folders are there, so let's extract the file now:
 548          if ( ! $file['folder'] ) {
 549              if ( !$fs->put_contents( $to . $file['filename'], $file['content']) )
 550                  return new WP_Error('copy_failed', __('Could not copy file'), $to . $file['filename']);
 551              $fs->chmod($to . $file['filename'], FS_CHMOD_FILE);
 552          }
 553      }
 554      return true;
 555  }
 556  
 557  /**
 558   * Copies a directory from one location to another via the WordPress Filesystem Abstraction.
 559   * Assumes that WP_Filesystem() has already been called and setup.
 560   *
 561   * @since 2.5.0
 562   *
 563   * @param string $from source directory
 564   * @param string $to destination directory
 565   * @return mixed WP_Error on failure, True on success.
 566   */
 567  function copy_dir($from, $to) {
 568      global $wp_filesystem;
 569  
 570      $dirlist = $wp_filesystem->dirlist($from);
 571  
 572      $from = trailingslashit($from);
 573      $to = trailingslashit($to);
 574  
 575      foreach ( (array) $dirlist as $filename => $fileinfo ) {
 576          if ( 'f' == $fileinfo['type'] ) {
 577              if ( ! $wp_filesystem->copy($from . $filename, $to . $filename, true) ) {
 578                  // If copy failed, chmod file to 0644 and try again.
 579                  $wp_filesystem->chmod($to . $filename, 0644);
 580                  if ( ! $wp_filesystem->copy($from . $filename, $to . $filename, true) )
 581                      return new WP_Error('copy_failed', __('Could not copy file'), $to . $filename);
 582              }
 583              $wp_filesystem->chmod($to . $filename, FS_CHMOD_FILE);
 584          } elseif ( 'd' == $fileinfo['type'] ) {
 585              if ( !$wp_filesystem->is_dir($to . $filename) ) {
 586                  if ( !$wp_filesystem->mkdir($to . $filename, FS_CHMOD_DIR) )
 587                      return new WP_Error('mkdir_failed', __('Could not create directory'), $to . $filename);
 588              }
 589              $result = copy_dir($from . $filename, $to . $filename);
 590              if ( is_wp_error($result) )
 591                  return $result;
 592          }
 593      }
 594      return true;
 595  }
 596  
 597  /**
 598   * Initialises and connects the WordPress Filesystem Abstraction classes.
 599   * This function will include the chosen transport and attempt connecting.
 600   *
 601   * Plugins may add extra transports, And force WordPress to use them by returning the filename via the 'filesystem_method_file' filter.
 602   *
 603   * @since 2.5.0
 604   *
 605   * @param array $args (optional) Connection args, These are passed directly to the WP_Filesystem_*() classes.
 606   * @param string $context (optional) Context for get_filesystem_method(), See function declaration for more information.
 607   * @return boolean false on failure, true on success
 608   */
 609  function WP_Filesystem( $args = false, $context = false ) {
 610      global $wp_filesystem;
 611  
 612      require_once (ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php');
 613  
 614      $method = get_filesystem_method($args, $context);
 615  
 616      if ( ! $method )
 617          return false;
 618  
 619      if ( ! class_exists("WP_Filesystem_$method") ) {
 620          $abstraction_file = apply_filters('filesystem_method_file', ABSPATH . 'wp-admin/includes/class-wp-filesystem-' . $method . '.php', $method);
 621          if( ! file_exists($abstraction_file) )
 622              return;
 623  
 624          require_once($abstraction_file);
 625      }
 626      $method = "WP_Filesystem_$method";
 627  
 628      $wp_filesystem = new $method($args);
 629  
 630      //Define the timeouts for the connections. Only available after the construct is called to allow for per-transport overriding of the default.
 631      if ( ! defined('FS_CONNECT_TIMEOUT') )
 632          define('FS_CONNECT_TIMEOUT', 30);
 633      if ( ! defined('FS_TIMEOUT') )
 634          define('FS_TIMEOUT', 30);
 635  
 636      if ( is_wp_error($wp_filesystem->errors) && $wp_filesystem->errors->get_error_code() )
 637          return false;
 638  
 639      if ( !$wp_filesystem->connect() )
 640          return false; //There was an erorr connecting to the server.
 641  
 642      // Set the permission constants if not already set.
 643      if ( ! defined('FS_CHMOD_DIR') )
 644          define('FS_CHMOD_DIR', 0755 );
 645      if ( ! defined('FS_CHMOD_FILE') )
 646          define('FS_CHMOD_FILE', 0644 );
 647  
 648      return true;
 649  }
 650  
 651  /**
 652   * Determines which Filesystem Method to use.
 653   * The priority of the Transports are: Direct, SSH2, FTP PHP Extension, FTP Sockets (Via Sockets class, or fsoxkopen())
 654   *
 655   * Note that the return value of this function can be overridden in 2 ways
 656   *  - By defining FS_METHOD in your <code>wp-config.php</code> file
 657   *  - By using the filesystem_method filter
 658   * Valid values for these are: 'direct', 'ssh', 'ftpext' or 'ftpsockets'
 659   * Plugins may also define a custom transport handler, See the WP_Filesystem function for more information.
 660   *
 661   * @since 2.5.0
 662   *
 663   * @param array $args Connection details.
 664   * @param string $context Full path to the directory that is tested for being writable.
 665   * @return string The transport to use, see description for valid return values.
 666   */
 667  function get_filesystem_method($args = array(), $context = false) {
 668      $method = defined('FS_METHOD') ? FS_METHOD : false; //Please ensure that this is either 'direct', 'ssh', 'ftpext' or 'ftpsockets'
 669  
 670      if( ! $method && function_exists('getmyuid') && function_exists('fileowner') ){
 671          if ( !$context )
 672              $context = WP_CONTENT_DIR;
 673          $context = trailingslashit($context);
 674          $temp_file_name = $context . 'temp-write-test-' . time();
 675          $temp_handle = @fopen($temp_file_name, 'w');
 676          if ( $temp_handle ) {
 677              if ( getmyuid() == @fileowner($temp_file_name) )
 678                  $method = 'direct';
 679              @fclose($temp_handle);
 680              @unlink($temp_file_name);
 681          }
 682       }
 683  
 684      if ( ! $method && isset($args['connection_type']) && 'ssh' == $args['connection_type'] && extension_loaded('ssh2') && function_exists('stream_get_contents') ) $method = 'ssh2';
 685      if ( ! $method && extension_loaded('ftp') ) $method = 'ftpext';
 686      if ( ! $method && ( extension_loaded('sockets') || function_exists('fsockopen') ) ) $method = 'ftpsockets'; //Sockets: Socket extension; PHP Mode: FSockopen / fwrite / fread
 687      return apply_filters('filesystem_method', $method, $args);
 688  }
 689  
 690  /**
 691   * Displays a form to the user to request for their FTP/SSH details in order to  connect to the filesystem.
 692   * All chosen/entered details are saved, Excluding the Password.
 693   *
 694   * Hostnames may be in the form of hostname:portnumber (eg: wordpress.org:2467) to specify an alternate FTP/SSH port.
 695   *
 696   * Plugins may override this form by returning true|false via the <code>request_filesystem_credentials</code> filter.
 697   *
 698   * @since 2.5.0
 699   *
 700   * @param string $form_post the URL to post the form to
 701   * @param string $type the chosen Filesystem method in use
 702   * @param boolean $error if the current request has failed to connect
 703   * @param string $context The directory which is needed access to, The write-test will be performed on  this directory by get_filesystem_method()
 704   * @return boolean False on failure. True on success.
 705   */
 706  function request_filesystem_credentials($form_post, $type = '', $error = false, $context = false) {
 707      $req_cred = apply_filters('request_filesystem_credentials', '', $form_post, $type, $error, $context);
 708      if ( '' !== $req_cred )
 709          return $req_cred;
 710  
 711      if ( empty($type) )
 712          $type = get_filesystem_method(array(), $context);
 713  
 714      if ( 'direct' == $type )
 715          return true;
 716  
 717      $credentials = get_option('ftp_credentials', array( 'hostname' => '', 'username' => ''));
 718  
 719      // If defined, set it to that, Else, If POST'd, set it to that, If not, Set it to whatever it previously was(saved details in option)
 720      $credentials['hostname'] = defined('FTP_HOST') ? FTP_HOST : (!empty($_POST['hostname']) ? stripslashes($_POST['hostname']) : $credentials['hostname']);
 721      $credentials['username'] = defined('FTP_USER') ? FTP_USER : (!empty($_POST['username']) ? stripslashes($_POST['username']) : $credentials['username']);
 722      $credentials['password'] = defined('FTP_PASS') ? FTP_PASS : (!empty($_POST['password']) ? stripslashes($_POST['password']) : '');
 723  
 724      // Check to see if we are setting the public/private keys for ssh
 725      $credentials['public_key'] = defined('FTP_PUBKEY') ? FTP_PUBKEY : (!empty($_POST['public_key']) ? stripslashes($_POST['public_key']) : '');
 726      $credentials['private_key'] = defined('FTP_PRIKEY') ? FTP_PRIKEY : (!empty($_POST['private_key']) ? stripslashes($_POST['private_key']) : '');
 727  
 728      //sanitize the hostname, Some people might pass in odd-data:
 729      $credentials['hostname'] = preg_replace('|\w+://|', '', $credentials['hostname']); //Strip any schemes off
 730  
 731      if ( strpos($credentials['hostname'], ':') ) {
 732          list( $credentials['hostname'], $credentials['port'] ) = explode(':', $credentials['hostname'], 2);
 733          if ( ! is_numeric($credentials['port']) )
 734              unset($credentials['port']);
 735      } else {
 736          unset($credentials['port']);
 737      }
 738  
 739      if ( (defined('FTP_SSH') && FTP_SSH) || (defined('FS_METHOD') && 'ssh' == FS_METHOD) )
 740          $credentials['connection_type'] = 'ssh';
 741      else if ( (defined('FTP_SSL') && FTP_SSL) && 'ftpext' == $type ) //Only the FTP Extension understands SSL
 742          $credentials['connection_type'] = 'ftps';
 743      else if ( !empty($_POST['connection_type']) )
 744          $credentials['connection_type'] = stripslashes($_POST['connection_type']);
 745      else if ( !isset($credentials['connection_type']) ) //All else fails (And its not defaulted to something else saved), Default to FTP
 746          $credentials['connection_type'] = 'ftp';
 747  
 748      if ( ! $error &&
 749              (
 750                  ( !empty($credentials['password']) && !empty($credentials['username']) && !empty($credentials['hostname']) ) ||
 751                  ( 'ssh' == $credentials['connection_type'] && !empty($credentials['public_key']) && !empty($credentials['private_key']) )
 752              ) ) {
 753          $stored_credentials = $credentials;
 754          if ( !empty($stored_credentials['port']) ) //save port as part of hostname to simplify above code.
 755              $stored_credentials['hostname'] .= ':' . $stored_credentials['port'];
 756  
 757          unset($stored_credentials['password'], $stored_credentials['port'], $stored_credentials['private_key'], $stored_credentials['public_key']);
 758          update_option('ftp_credentials', $stored_credentials);
 759          return $credentials;
 760      }
 761      $hostname = '';
 762      $username = '';
 763      $password = '';
 764      $connection_type = '';
 765      if ( !empty($credentials) )
 766          extract($credentials, EXTR_OVERWRITE);
 767      if ( $error ) {
 768          $error_string = __('<strong>Error:</strong> There was an error connecting to the server, Please verify the settings are correct.');
 769          if ( is_wp_error($error) )
 770              $error_string = $error->get_error_message();
 771          echo '<div id="message" class="error"><p>' . $error_string . '</p></div>';
 772      }
 773  
 774      $types = array();
 775      if ( extension_loaded('ftp') || extension_loaded('sockets') || function_exists('fsockopen') )
 776          $types[ 'ftp' ] = __('FTP');
 777      if ( extension_loaded('ftp') ) //Only this supports FTPS
 778          $types[ 'ftps' ] = __('FTPS (SSL)');
 779      if ( extension_loaded('ssh2') && function_exists('stream_get_contents') )
 780          $types[ 'ssh' ] = __('SSH2');
 781  
 782      $types = apply_filters('fs_ftp_connection_types', $types, $credentials, $type, $error, $context);
 783  
 784  ?>
 785  <script type="text/javascript">
 786  <!--
 787  jQuery(function($){
 788      jQuery("#ssh").click(function () {
 789          jQuery("#ssh_keys").show();
 790      });
 791      jQuery("#ftp, #ftps").click(function () {
 792          jQuery("#ssh_keys").hide();
 793      });
 794      jQuery('form input[value=""]:first').focus();
 795  });
 796  -->
 797  </script>
 798  <form action="<?php echo $form_post ?>" method="post">
 799  <div class="wrap">
 800  <?php screen_icon(); ?>
 801  <h2><?php _e('Connection Information') ?></h2>
 802  <p><?php _e('To perform the requested action, connection information is required.') ?></p>
 803  
 804  <table class="form-table">
 805  <tr valign="top">
 806  <th scope="row"><label for="hostname"><?php _e('Hostname') ?></label></th>
 807  <td><input name="hostname" type="text" id="hostname" value="<?php echo esc_attr($hostname); if ( !empty($port) ) echo ":$port"; ?>"<?php if( defined('FTP_HOST') ) echo ' disabled="disabled"' ?> size="40" /></td>
 808  </tr>
 809  
 810  <tr valign="top">
 811  <th scope="row"><label for="username"><?php _e('Username') ?></label></th>
 812  <td><input name="username" type="text" id="username" value="<?php echo esc_attr($username) ?>"<?php if( defined('FTP_USER') ) echo ' disabled="disabled"' ?> size="40" /></td>
 813  </tr>
 814  
 815  <tr valign="top">
 816  <th scope="row"><label for="password"><?php _e('Password') ?></label></th>
 817  <td><input name="password" type="password" id="password" value="<?php if ( defined('FTP_PASS') ) echo '*****'; ?>"<?php if ( defined('FTP_PASS') ) echo ' disabled="disabled"' ?> size="40" /></td>
 818  </tr>
 819  
 820  <?php if ( isset($types['ssh']) ) : ?>
 821  <tr id="ssh_keys" valign="top" style="<?php if ( 'ssh' != $connection_type ) echo 'display:none' ?>">
 822  <th scope="row"><?php _e('Authentication Keys') ?>
 823  <div class="key-labels textright">
 824  <label for="public_key"><?php _e('Public Key:') ?></label ><br />
 825  <label for="private_key"><?php _e('Private Key:') ?></label>
 826  </div></th>
 827  <td><br /><input name="public_key" type="text" id="public_key" value="<?php echo esc_attr($public_key) ?>"<?php if( defined('FTP_PUBKEY') ) echo ' disabled="disabled"' ?> size="40" /><br /><input name="private_key" type="text" id="private_key" value="<?php echo esc_attr($private_key) ?>"<?php if( defined('FTP_PRIKEY') ) echo ' disabled="disabled"' ?> size="40" />
 828  <div><?php _e('Enter the location on the server where the keys are located. If a passphrase is needed, enter that in the password field above.') ?></div></td>
 829  </tr>
 830  <?php endif; ?>
 831  
 832  <tr valign="top">
 833  <th scope="row"><?php _e('Connection Type') ?></th>
 834  <td>
 835  <fieldset><legend class="screen-reader-text"><span><?php _e('Connection Type') ?></span></legend>
 836  <?php
 837  
 838      $disabled = (defined('FTP_SSL') && FTP_SSL) || (defined('FTP_SSH') && FTP_SSH) ? ' disabled="disabled"' : '';
 839  
 840      foreach ( $types as $name => $text ) : ?>
 841      <label for="<?php echo esc_attr($name) ?>">
 842          <input type="radio" name="connection_type" id="<?php echo esc_attr($name) ?>" value="<?php echo esc_attr($name) ?>" <?php checked($name, $connection_type); echo $disabled; ?>/>
 843          <?php echo $text ?>
 844      </label>
 845      <?php endforeach; ?>
 846  </fieldset>
 847  </td>
 848  </tr>
 849  </table>
 850  
 851  <?php if ( isset( $_POST['version'] ) ) : ?>
 852  <input type="hidden" name="version" value="<?php echo esc_attr(stripslashes($_POST['version'])) ?>" />
 853  <?php endif; ?>
 854  <?php if ( isset( $_POST['locale'] ) ) : ?>
 855  <input type="hidden" name="locale" value="<?php echo esc_attr(stripslashes($_POST['locale'])) ?>" />
 856  <?php endif; ?>
 857  <p class="submit">
 858  <input id="upgrade" name="upgrade" type="submit" class="button" value="<?php esc_attr_e('Proceed'); ?>" />
 859  </p>
 860  </div>
 861  </form>
 862  <?php
 863      return false;
 864  }
 865  
 866  ?>


Generated: Fri Jan 8 00:19:48 2010 Cross-referenced by PHPXref 0.7