API page: https://api.drupal.org/api/drupal/includes%21file.inc/function/file_prep...

If you have a valid file_uri_scheme (e.g. public) and the directory exists then an attempt is made to use is_writable('public://mydirectory/myfile') which will return FALSE as we are passing a URI instead of full filename to is_writable

Using drupal_realpath($directory) will not always work either as passing a full filename to drupal_realpath instead of a URI will return FALSE from drupal_realpath.

I would suggest this:

$writable = is_writable(drupal_realpath($directory) == FALSE ? $directory : drupal_realpath($directory));

Patch attached

CommentFileSizeAuthor
file-21914.patch570 bytesCarlHinton
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

CarlHinton’s picture

Status: Active » Needs review
gmclelland’s picture

cleverhoods’s picture

Another solution (for Drupal 7)

You can solve this issue by defining your own Stream Wrapper.

/**
 * Implements hook_stream_wrappers().
 */
function MYMODULE_stream_wrappers() {
  return array(
    'syspublic' => array(
      'name' => t("Default distribution files"),
      'class' => 'SysPublicStreamWrapper',
      'description' => t("Visible, readable and writeable local path"),
      'type' => STREAM_WRAPPERS_LOCAL_NORMAL,
    ),
  );
}

/**
 * Default sys (syspublic://) stream wrapper class.
 */
class SysPublicStreamWrapper extends DrupalPublicStreamWrapper {
  public function getDirectoryPath() {
    return 'sites/default/files/sys';
  }
}

Via: Writing Stream Wrappers