Commit 01b40c02 authored by Dries's avatar Dries

Merge branch '8.x' of git.drupal.org:project/drupal into 8.x

parents 31461129 56741a09
...@@ -58,7 +58,7 @@ Database system ...@@ -58,7 +58,7 @@ Database system
- Károly Négyesi 'chx' <http://drupal.org/user/9446> - Károly Négyesi 'chx' <http://drupal.org/user/9446>
Database update system Database update system
- ? - Ashok Modi 'btmash' <http://drupal.org/user/60422>
Entity system Entity system
- Wolfgang Ziegler 'fago' <http://drupal.org/user/16747> - Wolfgang Ziegler 'fago' <http://drupal.org/user/16747>
......
...@@ -265,7 +265,7 @@ ...@@ -265,7 +265,7 @@
/** /**
* Regular expression to match PHP function names. * Regular expression to match PHP function names.
* *
* @see http://php.net/manual/en/language.functions.php * @see http://php.net/manual/language.functions.php
*/ */
const DRUPAL_PHP_FUNCTION_PATTERN = '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*'; const DRUPAL_PHP_FUNCTION_PATTERN = '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*';
...@@ -3029,8 +3029,8 @@ function registry_update() { ...@@ -3029,8 +3029,8 @@ function registry_update() {
* However, the above line of code does not work, because PHP only allows static * However, the above line of code does not work, because PHP only allows static
* variables to be initializied by literal values, and does not allow static * variables to be initializied by literal values, and does not allow static
* variables to be assigned to references. * variables to be assigned to references.
* - http://php.net/manual/en/language.variables.scope.php#language.variables.scope.static * - http://php.net/manual/language.variables.scope.php#language.variables.scope.static
* - http://php.net/manual/en/language.variables.scope.php#language.variables.scope.references * - http://php.net/manual/language.variables.scope.php#language.variables.scope.references
* The example below shows the syntax needed to work around both limitations. * The example below shows the syntax needed to work around both limitations.
* For benchmarks and more information, see http://drupal.org/node/619666. * For benchmarks and more information, see http://drupal.org/node/619666.
* *
......
...@@ -1059,7 +1059,7 @@ function _fix_gpc_magic(&$item) { ...@@ -1059,7 +1059,7 @@ function _fix_gpc_magic(&$item) {
* @param $key * @param $key
* The key for the item within $_FILES. * The key for the item within $_FILES.
* *
* @see http://php.net/manual/en/features.file-upload.php#42280 * @see http://php.net/manual/features.file-upload.php#42280
*/ */
function _fix_gpc_magic_files(&$item, $key) { function _fix_gpc_magic_files(&$item, $key) {
if ($key != 'tmp_name') { if ($key != 'tmp_name') {
...@@ -1883,7 +1883,7 @@ function format_interval($interval, $granularity = 2, $langcode = NULL) { ...@@ -1883,7 +1883,7 @@ function format_interval($interval, $granularity = 2, $langcode = NULL) {
* get interpreted as date format characters. * get interpreted as date format characters.
* @param $timezone * @param $timezone
* (optional) Time zone identifier, as described at * (optional) Time zone identifier, as described at
* http://php.net/manual/en/timezones.php Defaults to the time zone used to * http://php.net/manual/timezones.php Defaults to the time zone used to
* display the page. * display the page.
* @param $langcode * @param $langcode
* (optional) Language code to translate to. Defaults to the language used to * (optional) Language code to translate to. Defaults to the language used to
...@@ -3644,7 +3644,7 @@ function drupal_load_stylesheet_content($contents, $optimize = FALSE) { ...@@ -3644,7 +3644,7 @@ function drupal_load_stylesheet_content($contents, $optimize = FALSE) {
// Remove certain whitespace. // Remove certain whitespace.
// There are different conditions for removing leading and trailing // There are different conditions for removing leading and trailing
// whitespace. // whitespace.
// @see http://php.net/manual/en/regexp.reference.subpatterns.php // @see http://php.net/manual/regexp.reference.subpatterns.php
$contents = preg_replace('< $contents = preg_replace('<
# Strip leading and trailing whitespace. # Strip leading and trailing whitespace.
\s*([@{};,])\s* \s*([@{};,])\s*
...@@ -5193,7 +5193,7 @@ function _drupal_bootstrap_full() { ...@@ -5193,7 +5193,7 @@ function _drupal_bootstrap_full() {
* client without gzip support. * client without gzip support.
* *
* Page compression requires the PHP zlib extension * Page compression requires the PHP zlib extension
* (http://php.net/manual/en/ref.zlib.php). * (http://php.net/manual/ref.zlib.php).
* *
* @see drupal_page_header() * @see drupal_page_header()
*/ */
...@@ -6984,6 +6984,9 @@ function drupal_common_theme() { ...@@ -6984,6 +6984,9 @@ function drupal_common_theme() {
'textarea' => array( 'textarea' => array(
'render element' => 'element', 'render element' => 'element',
), ),
'search' => array(
'render element' => 'element',
),
'password' => array( 'password' => array(
'render element' => 'element', 'render element' => 'element',
), ),
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
* Maps PHP error constants to watchdog severity levels. * Maps PHP error constants to watchdog severity levels.
* *
* The error constants are documented at * The error constants are documented at
* http://php.net/manual/en/errorfunc.constants.php * http://php.net/manual/errorfunc.constants.php
* *
* @ingroup logging_severity_levels * @ingroup logging_severity_levels
*/ */
......
...@@ -1494,7 +1494,7 @@ function file_save_upload($source, $validators = array(), $destination = FALSE, ...@@ -1494,7 +1494,7 @@ function file_save_upload($source, $validators = array(), $destination = FALSE,
// Check for file upload errors and return FALSE if a lower level system // Check for file upload errors and return FALSE if a lower level system
// error occurred. For a complete list of errors: // error occurred. For a complete list of errors:
// See http://php.net/manual/en/features.file-upload.errors.php. // See http://php.net/manual/features.file-upload.errors.php.
switch ($_FILES['files']['error'][$source]) { switch ($_FILES['files']['error'][$source]) {
case UPLOAD_ERR_INI_SIZE: case UPLOAD_ERR_INI_SIZE:
case UPLOAD_ERR_FORM_SIZE: case UPLOAD_ERR_FORM_SIZE:
...@@ -2253,7 +2253,7 @@ function drupal_chmod($uri, $mode = NULL) { ...@@ -2253,7 +2253,7 @@ function drupal_chmod($uri, $mode = NULL) {
* @param $uri * @param $uri
* A URI or pathname. * A URI or pathname.
* @param $context * @param $context
* Refer to http://php.net/manual/en/ref.stream.php * Refer to http://php.net/manual/ref.stream.php
* *
* @return * @return
* Boolean TRUE on success, or FALSE on failure. * Boolean TRUE on success, or FALSE on failure.
...@@ -2388,7 +2388,7 @@ function drupal_basename($uri, $suffix = NULL) { ...@@ -2388,7 +2388,7 @@ function drupal_basename($uri, $suffix = NULL) {
* @param $recursive * @param $recursive
* Default to FALSE. * Default to FALSE.
* @param $context * @param $context
* Refer to http://php.net/manual/en/ref.stream.php * Refer to http://php.net/manual/ref.stream.php
* *
* @return * @return
* Boolean TRUE on success, or FALSE on failure. * Boolean TRUE on success, or FALSE on failure.
...@@ -2419,7 +2419,7 @@ function drupal_mkdir($uri, $mode = NULL, $recursive = FALSE, $context = NULL) { ...@@ -2419,7 +2419,7 @@ function drupal_mkdir($uri, $mode = NULL, $recursive = FALSE, $context = NULL) {
* @param $uri * @param $uri
* A URI or pathname. * A URI or pathname.
* @param $context * @param $context
* Refer to http://php.net/manual/en/ref.stream.php * Refer to http://php.net/manual/ref.stream.php
* *
* @return * @return
* Boolean TRUE on success, or FALSE on failure. * Boolean TRUE on success, or FALSE on failure.
......
...@@ -3094,7 +3094,7 @@ function form_pre_render_conditional_form_element($element) { ...@@ -3094,7 +3094,7 @@ function form_pre_render_conditional_form_element($element) {
$element['#attributes']['title'] = $element['#title']; $element['#attributes']['title'] = $element['#title'];
if (!empty($element['#required'])) { if (!empty($element['#required'])) {
// Append an indication that this field is required. // Append an indication that this field is required.
$element['#attributes']['title'] .= ' (' . t('Required') . ')'; $element['#attributes']['title'] .= ' (' . $t('Required') . ')';
} }
} }
...@@ -3104,6 +3104,19 @@ function form_pre_render_conditional_form_element($element) { ...@@ -3104,6 +3104,19 @@ function form_pre_render_conditional_form_element($element) {
return $element; return $element;
} }
/**
* Processes a form button element.
*/
function form_process_button($element, $form_state) {
// If this is a button intentionally allowing incomplete form submission
// (e.g., a "Previous" or "Add another item" button), then also skip
// client-side validation.
if (isset($element['#limit_validation_errors']) && $element['#limit_validation_errors'] !== FALSE) {
$element['#attributes']['formnovalidate'] = 'formnovalidate';
}
return $element;
}
/** /**
* Sets the #checked property of a checkbox element. * Sets the #checked property of a checkbox element.
*/ */
...@@ -3930,6 +3943,42 @@ function theme_url($variables) { ...@@ -3930,6 +3943,42 @@ function theme_url($variables) {
return $output . $extra; return $output . $extra;
} }
/**
* Returns HTML for a search form element.
*
* @param $variables
* An associative array containing:
* - element: An associative array containing the properties of the element.
* Properties used: #title, #value, #description, #size, #maxlength,
* #placeholder, #required, #attributes, #autocomplete_path.
*
* @ingroup themeable
*/
function theme_search($variables) {
$element = $variables['element'];
$element['#attributes']['type'] = 'search';
element_set_attributes($element, array('id', 'name', 'value', 'size', 'maxlength', 'placeholder'));
_form_set_class($element, array('form-search'));
$extra = '';
if ($element['#autocomplete_path'] && drupal_valid_path($element['#autocomplete_path'])) {
drupal_add_library('system', 'drupal.autocomplete');
$element['#attributes']['class'][] = 'form-autocomplete';
$attributes = array();
$attributes['type'] = 'hidden';
$attributes['id'] = $element['#attributes']['id'] . '-autocomplete';
$attributes['value'] = url($element['#autocomplete_path'], array('absolute' => TRUE));
$attributes['disabled'] = 'disabled';
$attributes['class'][] = 'autocomplete';
$extra = '<input' . drupal_attributes($attributes) . ' />';
}
$output = '<input' . drupal_attributes($element['#attributes']) . ' />';
return $output . $extra;
}
/** /**
* Form element validation handler for #type 'url'. * Form element validation handler for #type 'url'.
* *
...@@ -4276,6 +4325,10 @@ function _form_set_class(&$element, $class = array()) { ...@@ -4276,6 +4325,10 @@ function _form_set_class(&$element, $class = array()) {
// form_builder(). // form_builder().
if (!empty($element['#required'])) { if (!empty($element['#required'])) {
$element['#attributes']['class'][] = 'required'; $element['#attributes']['class'][] = 'required';
// @todo Rename the _form_set_class() function to reflect that we're setting
// non-class attributes too.
$element['#attributes']['required'] = 'required';
$element['#attributes']['aria-required'] = 'true';
} }
if (isset($element['#parents']) && form_get_error($element)) { if (isset($element['#parents']) && form_get_error($element)) {
$element['#attributes']['class'][] = 'error'; $element['#attributes']['class'][] = 'error';
......
...@@ -2292,6 +2292,9 @@ function menu_get_active_menu_names() { ...@@ -2292,6 +2292,9 @@ function menu_get_active_menu_names() {
*/ */
function menu_set_active_item($path) { function menu_set_active_item($path) {
$_GET['q'] = $path; $_GET['q'] = $path;
// Since the active item has changed, the active menu trail may also be out
// of date.
drupal_static_reset('menu_set_active_trail');
} }
/** /**
...@@ -2377,7 +2380,7 @@ function menu_set_active_trail($new_trail = NULL) { ...@@ -2377,7 +2380,7 @@ function menu_set_active_trail($new_trail = NULL) {
// appending either the preferred link or the menu router item for the // appending either the preferred link or the menu router item for the
// current page. Exclude it if we are on the front page. // current page. Exclude it if we are on the front page.
$last = end($trail); $last = end($trail);
if ($last['href'] != $preferred_link['href'] && !drupal_is_front_page()) { if ($preferred_link && $last['href'] != $preferred_link['href'] && !drupal_is_front_page()) {
$trail[] = $preferred_link; $trail[] = $preferred_link;
} }
} }
...@@ -3102,10 +3105,10 @@ function menu_link_save(&$item, $existing_item = array(), $parent_candidates = a ...@@ -3102,10 +3105,10 @@ function menu_link_save(&$item, $existing_item = array(), $parent_candidates = a
} }
// If every value in $existing_item is the same in the $item, there is no // If every value in $existing_item is the same in the $item, there is no
// reason to run the update queries or clear the caches. We use // reason to run the update queries or clear the caches. We use
// array_intersect_assoc() with the $item as the first parameter because // array_intersect_key() with the $item as the first parameter because
// $item may have additional keys left over from building a router entry. // $item may have additional keys left over from building a router entry.
// The intersect removes the extra keys, allowing a meaningful comparison. // The intersect removes the extra keys, allowing a meaningful comparison.
if (!$existing_item || (array_intersect_assoc($item, $existing_item)) != $existing_item) { if (!$existing_item || (array_intersect_key($item, $existing_item)) != $existing_item) {
db_update('menu_links') db_update('menu_links')
->fields(array( ->fields(array(
'menu_name' => $item['menu_name'], 'menu_name' => $item['menu_name'],
......
...@@ -81,7 +81,7 @@ public function isOverridden($key) { ...@@ -81,7 +81,7 @@ public function isOverridden($key) {
* cause issues with Booleans, which are casted to "1" (TRUE) or "0" (FALSE). * cause issues with Booleans, which are casted to "1" (TRUE) or "0" (FALSE).
* In particular, code relying on === or !== will no longer function properly. * In particular, code relying on === or !== will no longer function properly.
* *
* @see http://php.net/manual/en/language.operators.comparison.php. * @see http://php.net/manual/language.operators.comparison.php.
* *
* @return * @return
* The data that was requested. * The data that was requested.
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
* concrete implementation of it to support special handling required by that * concrete implementation of it to support special handling required by that
* database. * database.
* *
* @see http://php.net/manual/en/book.pdo.php * @see http://php.net/manual/book.pdo.php
*/ */
abstract class Connection extends PDO { abstract class Connection extends PDO {
......
...@@ -55,8 +55,6 @@ public function __construct(array $connection_options = array()) { ...@@ -55,8 +55,6 @@ public function __construct(array $connection_options = array()) {
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => TRUE, PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => TRUE,
// Because MySQL's prepared statements skip the query cache, because it's dumb. // Because MySQL's prepared statements skip the query cache, because it's dumb.
PDO::ATTR_EMULATE_PREPARES => TRUE, PDO::ATTR_EMULATE_PREPARES => TRUE,
// Force column names to lower case.
PDO::ATTR_CASE => PDO::CASE_LOWER,
); );
parent::__construct($dsn, $connection_options['username'], $connection_options['password'], $connection_options['pdo']); parent::__construct($dsn, $connection_options['username'], $connection_options['password'], $connection_options['pdo']);
......
...@@ -390,7 +390,7 @@ public function indexExists($table, $name) { ...@@ -390,7 +390,7 @@ public function indexExists($table, $name) {
// Returns one row for each column in the index. Result is string or FALSE. // Returns one row for each column in the index. Result is string or FALSE.
// Details at http://dev.mysql.com/doc/refman/5.0/en/show-index.html // Details at http://dev.mysql.com/doc/refman/5.0/en/show-index.html
$row = $this->connection->query('SHOW INDEX FROM {' . $table . "} WHERE key_name = '$name'")->fetchAssoc(); $row = $this->connection->query('SHOW INDEX FROM {' . $table . "} WHERE key_name = '$name'")->fetchAssoc();
return isset($row['key_name']); return isset($row['Key_name']);
} }
public function addPrimaryKey($table, $fields) { public function addPrimaryKey($table, $fields) {
......
...@@ -71,8 +71,6 @@ public function __construct(array $connection_options = array()) { ...@@ -71,8 +71,6 @@ public function __construct(array $connection_options = array()) {
PDO::ATTR_EMULATE_PREPARES => TRUE, PDO::ATTR_EMULATE_PREPARES => TRUE,
// Convert numeric values to strings when fetching. // Convert numeric values to strings when fetching.
PDO::ATTR_STRINGIFY_FETCHES => TRUE, PDO::ATTR_STRINGIFY_FETCHES => TRUE,
// Force column names to lower case.
PDO::ATTR_CASE => PDO::CASE_LOWER,
); );
parent::__construct($dsn, $connection_options['username'], $connection_options['password'], $connection_options['pdo']); parent::__construct($dsn, $connection_options['username'], $connection_options['password'], $connection_options['pdo']);
......
...@@ -73,8 +73,6 @@ public function __construct(array $connection_options = array()) { ...@@ -73,8 +73,6 @@ public function __construct(array $connection_options = array()) {
'pdo' => array(), 'pdo' => array(),
); );
$connection_options['pdo'] += array( $connection_options['pdo'] += array(
// Force column names to lower case.
PDO::ATTR_CASE => PDO::CASE_LOWER,
// Convert numeric values to strings when fetching. // Convert numeric values to strings when fetching.
PDO::ATTR_STRINGIFY_FETCHES => TRUE, PDO::ATTR_STRINGIFY_FETCHES => TRUE,
); );
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
* driver needs to set a custom statement class, it may do so in its * driver needs to set a custom statement class, it may do so in its
* constructor. * constructor.
* *
* @see http://us.php.net/pdostatement * @see http://php.net/pdostatement
*/ */
class Statement extends PDOStatement implements StatementInterface { class Statement extends PDOStatement implements StatementInterface {
......
...@@ -64,7 +64,7 @@ public function rowCount(); ...@@ -64,7 +64,7 @@ public function rowCount();
/** /**
* Sets the default fetch mode for this statement. * Sets the default fetch mode for this statement.
* *
* See http://php.net/manual/en/pdo.constants.php for the definition of the * See http://php.net/manual/pdo.constants.php for the definition of the
* constants used. * constants used.
* *
* @param $mode * @param $mode
...@@ -83,7 +83,7 @@ public function rowCount(); ...@@ -83,7 +83,7 @@ public function rowCount();
/** /**
* Fetches the next row from a result set. * Fetches the next row from a result set.
* *
* See http://php.net/manual/en/pdo.constants.php for the definition of the * See http://php.net/manual/pdo.constants.php for the definition of the
* constants used. * constants used.
* *
* @param $mode * @param $mode
......
...@@ -291,7 +291,7 @@ public function current() { ...@@ -291,7 +291,7 @@ public function current() {
$class_name = $this->fetchOptions['class']; $class_name = $this->fetchOptions['class'];
} }
if (count($this->fetchOptions['constructor_args'])) { if (count($this->fetchOptions['constructor_args'])) {
$reflector = new ReflectionClass($class_name); $reflector = new \ReflectionClass($class_name);
$result = $reflector->newInstanceArgs($this->fetchOptions['constructor_args']); $result = $reflector->newInstanceArgs($this->fetchOptions['constructor_args']);
} }
else { else {
......
...@@ -189,7 +189,7 @@ protected function getLocalPath($uri = NULL) { ...@@ -189,7 +189,7 @@ protected function getLocalPath($uri = NULL) {
* @return bool * @return bool
* Returns TRUE if file was opened successfully. * Returns TRUE if file was opened successfully.
* *
* @see http://php.net/manual/en/streamwrapper.stream-open.php * @see http://php.net/manual/streamwrapper.stream-open.php
*/ */
public function stream_open($uri, $mode, $options, &$opened_path) { public function stream_open($uri, $mode, $options, &$opened_path) {
$this->uri = $uri; $this->uri = $uri;
...@@ -217,7 +217,7 @@ public function stream_open($uri, $mode, $options, &$opened_path) { ...@@ -217,7 +217,7 @@ public function stream_open($uri, $mode, $options, &$opened_path) {
* @return bool * @return bool
* Always returns TRUE at the present time. * Always returns TRUE at the present time.
* *
* @see http://php.net/manual/en/streamwrapper.stream-lock.php * @see http://php.net/manual/streamwrapper.stream-lock.php
*/ */
public function stream_lock($operation) { public function stream_lock($operation) {
if (in_array($operation, array(LOCK_SH, LOCK_EX, LOCK_UN, LOCK_NB))) { if (in_array($operation, array(LOCK_SH, LOCK_EX, LOCK_UN, LOCK_NB))) {
...@@ -236,7 +236,7 @@ public function stream_lock($operation) { ...@@ -236,7 +236,7 @@ public function stream_lock($operation) {
* @return string|bool * @return string|bool
* The string that was read, or FALSE in case of an error. * The string that was read, or FALSE in case of an error.
* *
* @see http://php.net/manual/en/streamwrapper.stream-read.php * @see http://php.net/manual/streamwrapper.stream-read.php
*/ */
public function stream_read($count) { public function stream_read($count) {
return fread($this->handle, $count); return fread($this->handle, $count);
...@@ -251,7 +251,7 @@ public function stream_read($count) { ...@@ -251,7 +251,7 @@ public function stream_read($count) {
* @return int * @return int
* The number of bytes written. * The number of bytes written.
* *
* @see http://php.net/manual/en/streamwrapper.stream-write.php * @see http://php.net/manual/streamwrapper.stream-write.php
*/ */
public function stream_write($data) { public function stream_write($data) {
return fwrite($this->handle, $data); return fwrite($this->handle, $data);
...@@ -263,7 +263,7 @@ public function stream_write($data) { ...@@ -263,7 +263,7 @@ public function stream_write($data) {
* @return bool * @return bool
* TRUE if end-of-file has been reached. * TRUE if end-of-file has been reached.
* *
* @see http://php.net/manual/en/streamwrapper.stream-eof.php * @see http://php.net/manual/streamwrapper.stream-eof.php
*/ */
public function stream_eof() { public function stream_eof() {
return feof($this->handle); return feof($this->handle);
...@@ -280,7 +280,7 @@ public function stream_eof() { ...@@ -280,7 +280,7 @@ public function stream_eof() {
* @return bool * @return bool
* TRUE on success. * TRUE on success.
* *
* @see http://php.net/manual/en/streamwrapper.stream-seek.php * @see http://php.net/manual/streamwrapper.stream-seek.php
*/ */
public function stream_seek($offset, $whence) { public function stream_seek($offset, $whence) {
// fseek returns 0 on success and -1 on a failure. // fseek returns 0 on success and -1 on a failure.
...@@ -294,7 +294,7 @@ public function stream_seek($offset, $whence) { ...@@ -294,7 +294,7 @@ public function stream_seek($offset, $whence) {
* @return bool * @return bool
* TRUE if data was successfully stored (or there was no data to store). * TRUE if data was successfully stored (or there was no data to store).
* *
* @see http://php.net/manual/en/streamwrapper.stream-flush.php * @see http://php.net/manual/streamwrapper.stream-flush.php
*/ */
public function stream_flush() { public function stream_flush() {
return fflush($this->handle); return fflush($this->handle);
...@@ -306,7 +306,7 @@ public function stream_flush() { ...@@ -306,7 +306,7 @@ public function stream_flush() {
* @return bool * @return bool
* The current offset in bytes from the beginning of file. * The current offset in bytes from the beginning of file.
* *
* @see http://php.net/manual/en/streamwrapper.stream-tell.php * @see http://php.net/manual/streamwrapper.stream-tell.php
*/ */
public function stream_tell() { public function stream_tell() {
return ftell($this->handle); return ftell($this->handle);
...@@ -319,7 +319,7 @@ public function stream_tell() { ...@@ -319,7 +319,7 @@ public function stream_tell() {
* An array with file status, or FALSE in case of an error - see fstat() * An array with file status, or FALSE in case of an error - see fstat()
* for a description of this array. * for a description of this array.
* *
* @see http://php.net/manual/en/streamwrapper.stream-stat.php * @see http://php.net/manual/streamwrapper.stream-stat.php
*/ */
public function stream_stat() { public function stream_stat() {
return fstat($this->handle); return fstat($this->handle);