Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
| Total | |
0.00% |
0 / 1 |
|
64.29% |
9 / 14 |
CRAP | |
56.60% |
30 / 53 |
| FileStorage | |
0.00% |
0 / 1 |
|
64.29% |
9 / 14 |
141.92 | |
56.60% |
30 / 53 |
| __construct | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
| exists | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
| load | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
| save | |
0.00% |
0 / 1 |
5.26 | |
57.14% |
4 / 7 |
|||
| htaccessLines | |
100.00% |
1 / 1 |
2 | |
100.00% |
4 / 4 |
|||
| ensureDirectory | |
100.00% |
1 / 1 |
4 | |
100.00% |
5 / 5 |
|||
| createDirectory | |
0.00% |
0 / 1 |
7.14 | |
85.71% |
6 / 7 |
|||
| delete | |
100.00% |
1 / 1 |
2 | |
100.00% |
4 / 4 |
|||
| getFullPath | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
| writeable | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
| deleteAll | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
| unlink | |
0.00% |
0 / 1 |
30 | |
0.00% |
0 / 10 |
|||
| listAll | |
0.00% |
0 / 1 |
30 | |
0.00% |
0 / 8 |
|||
| garbageCollection | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
|||
| <?php | |
| /** | |
| * @file | |
| * Contains \Drupal\Component\PhpStorage\FileStorage. | |
| */ | |
| namespace Drupal\Component\PhpStorage; | |
| /** | |
| * Stores the code as regular PHP files. | |
| */ | |
| class FileStorage implements PhpStorageInterface { | |
| /** | |
| * The directory where the files should be stored. | |
| * | |
| * @var string | |
| */ | |
| protected $directory; | |
| /** | |
| * Constructs this FileStorage object. | |
| * | |
| * @param array $configuration | |
| * An associative array, containing at least these two keys: | |
| * - directory: The directory where the files should be stored. | |
| * - bin: The storage bin. Multiple storage objects can be instantiated with | |
| * the same configuration, but for different bins.. | |
| */ | |
| public function __construct(array $configuration) { | |
| $this->directory = $configuration['directory'] . '/' . $configuration['bin']; | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function exists($name) { | |
| return file_exists($this->getFullPath($name)); | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function load($name) { | |
| // The FALSE returned on failure is enough for the caller to handle this, | |
| // we do not want a warning too. | |
| return (@include_once $this->getFullPath($name)) !== FALSE; | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function save($name, $code) { | |
| $path = $this->getFullPath($name); | |
| $directory = dirname($path); | |
| if ($this->ensureDirectory($directory)) { | |
| $htaccess_path = $directory . '/.htaccess'; | |
| if (!file_exists($htaccess_path) && file_put_contents($htaccess_path, static::htaccessLines())) { | |
| @chmod($htaccess_path, 0444); | |
| } | |
| } | |
| return (bool) file_put_contents($path, $code); | |
| } | |
| /** | |
| * Returns the standard .htaccess lines that Drupal writes to file directories. | |
| * | |
| * @param bool $private | |
| * (optional) Set to FALSE to return the .htaccess lines for an open and | |
| * public directory. The default is TRUE, which returns the .htaccess lines | |
| * for a private and protected directory. | |
| * | |
| * @return string | |
| * The desired contents of the .htaccess file. | |
| * | |
| * @see file_create_htaccess() | |
| */ | |
| public static function htaccessLines($private = TRUE) { | |
| $lines = <<<EOF | |
| # Turn off all options we don't need. | |
| Options -Indexes -ExecCGI -Includes -MultiViews | |
| # Set the catch-all handler to prevent scripts from being executed. | |
| SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006 | |
| <Files *> | |
| # Override the handler again if we're run later in the evaluation list. | |
| SetHandler Drupal_Security_Do_Not_Remove_See_SA_2013_003 | |
| </Files> | |
| # If we know how to do it safely, disable the PHP engine entirely. | |
| <IfModule mod_php5.c> | |
| php_flag engine off | |
| </IfModule> | |
| EOF; | |
| if ($private) { | |
| $lines = <<<EOF | |
| # Deny all requests from Apache 2.4+. | |
| <IfModule mod_authz_core.c> | |
| Require all denied | |
| </IfModule> | |
| # Deny all requests from Apache 2.0-2.2. | |
| <IfModule !mod_authz_core.c> | |
| Deny from all | |
| </IfModule> | |
| $lines | |
| EOF; | |
| } | |
| return $lines; | |
| } | |
| /** | |
| * Ensures the directory exists, has the right permissions, and a .htaccess. | |
| * | |
| * For compatibility with open_basedir, the requested directory is created | |
| * using a recursion logic that is based on the relative directory path/tree: | |
| * It works from the end of the path recursively back towards the root | |
| * directory, until an existing parent directory is found. From there, the | |
| * subdirectories are created. | |
| * | |
| * @param string $directory | |
| * The directory path. | |
| * @param int $mode | |
| * The mode, permissions, the directory should have. | |
| * | |
| * @return bool | |
| * TRUE if the directory exists or has been created, FALSE otherwise. | |
| */ | |
| protected function ensureDirectory($directory, $mode = 0777) { | |
| if ($this->createDirectory($directory, $mode)) { | |
| $htaccess_path = $directory . '/.htaccess'; | |
| if (!file_exists($htaccess_path) && file_put_contents($htaccess_path, static::htaccessLines())) { | |
| @chmod($htaccess_path, 0444); | |
| } | |
| } | |
| } | |
| /** | |
| * Ensures the requested directory exists and has the right permissions. | |
| * | |
| * For compatibility with open_basedir, the requested directory is created | |
| * using a recursion logic that is based on the relative directory path/tree: | |
| * It works from the end of the path recursively back towards the root | |
| * directory, until an existing parent directory is found. From there, the | |
| * subdirectories are created. | |
| * | |
| * @param string $directory | |
| * The directory path. | |
| * @param int $mode | |
| * The mode, permissions, the directory should have. | |
| * @param bool $is_backwards_recursive | |
| * Internal use only. | |
| * | |
| * @return bool | |
| * TRUE if the directory exists or has been created, FALSE otherwise. | |
| */ | |
| protected function createDirectory($directory, $mode = 0777, $is_backwards_recursive = FALSE) { | |
| // If the directory exists already, there's nothing to do. | |
| if (is_dir($directory)) { | |
| return TRUE; | |
| } | |
| // Otherwise, try to create the directory and ensure to set its permissions, | |
| // because mkdir() obeys the umask of the current process. | |
| if (is_dir($parent = dirname($directory))) { | |
| // If the parent directory exists, then the backwards recursion must end, | |
| // regardless of whether the subdirectory could be created. | |
| if ($status = mkdir($directory)) { | |
| // Only try to chmod() if the subdirectory could be created. | |
| $status = chmod($directory, $mode); | |
| } | |
| return $is_backwards_recursive ? TRUE : $status; | |
| } | |
| // If the parent directory and the requested directory does not exist and | |
| // could not be created above, walk the requested directory path back up | |
| // until an existing directory is hit, and from there, recursively create | |
| // the sub-directories. Only if that recursion succeeds, create the final, | |
| // originally requested subdirectory. | |
| return $this->createDirectory($parent, $mode, TRUE) && mkdir($directory) && chmod($directory, $mode); | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function delete($name) { | |
| $path = $this->getFullPath($name); | |
| if (file_exists($path)) { | |
| return $this->unlink($path); | |
| } | |
| return FALSE; | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function getFullPath($name) { | |
| return $this->directory . '/' . $name; | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function writeable() { | |
| return TRUE; | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function deleteAll() { | |
| return $this->unlink($this->directory); | |
| } | |
| /** | |
| * Deletes files and/or directories in the specified path. | |
| * | |
| * If the specified path is a directory the method will | |
| * call itself recursively to process the contents. Once the contents have | |
| * been removed the directory will also be removed. | |
| * | |
| * @param string $path | |
| * A string containing either a file or directory path. | |
| * | |
| * @return bool | |
| * TRUE for success or if path does not exist, FALSE in the event of an | |
| * error. | |
| */ | |
| protected function unlink($path) { | |
| if (file_exists($path)) { | |
| if (is_dir($path)) { | |
| // Ensure the folder is writable. | |
| @chmod($path, 0777); | |
| foreach (new \DirectoryIterator($path) as $fileinfo) { | |
| if (!$fileinfo->isDot()) { | |
| $this->unlink($fileinfo->getPathName()); | |
| } | |
| } | |
| return @rmdir($path); | |
| } | |
| // Windows needs the file to be writable. | |
| @chmod($path, 0700); | |
| return @unlink($path); | |
| } | |
| // If there's nothing to delete return TRUE anyway. | |
| return TRUE; | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function listAll() { | |
| $names = array(); | |
| if (file_exists($this->directory)) { | |
| foreach (new \DirectoryIterator($this->directory) as $fileinfo) { | |
| if (!$fileinfo->isDot()) { | |
| $name = $fileinfo->getFilename(); | |
| if ($name != '.htaccess') { | |
| $names[] = $name; | |
| } | |
| } | |
| } | |
| } | |
| return $names; | |
| } | |
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function garbageCollection() { | |
| } | |
| } |