/** * Loads a Yaml file. * * @param mixed $file The resource */ public function load($file) { // Load from the file cache, fall back to loading the file. // @todo Refactor this to cache parsed definition objects in // https://www.drupal.org/node/2464053 $content = $this->fileCache->get($file); if (!$content) { $content = $this->loadFile($file); $this->fileCache->set($file, $content); } // Not supported. //$this->container->addResource(new FileResource($path)); // empty file if (null === $content) { return; } // imports // Not supported. //$this->parseImports($content, $file); // parameters if (isset($content['parameters'])) { if (!is_array($content['parameters'])) { throw new InvalidArgumentException(sprintf('The "parameters" key should contain an array in %s. Check your YAML syntax.', $file)); } foreach ($content['parameters'] as $key => $value) { $this->container->setParameter($key, $this->resolveServices($value)); } } // extensions // Not supported. //$this->loadFromExtensions($content); // services $this->parseDefinitions($content, $file); }
/** * Loads a Yaml file. * * @param mixed $file The resource */ public function load($file) { // Load from the file cache, fall back to loading the file. // @todo Refactor this to cache parsed definition objects in // https://www.drupal.org/node/2464053 $content = $this->fileCache->get($file); if (!$content) { $content = $this->loadFile($file); $this->fileCache->set($file, $content); } // Not supported. //$this->container->addResource(new FileResource($path)); // empty file if (null === $content) { return; } // imports // Not supported. //$this->parseImports($content, $file); // parameters if (isset($content['parameters'])) { foreach ($content['parameters'] as $key => $value) { $this->container->setParameter($key, $this->resolveServices($value)); } } // extensions // Not supported. //$this->loadFromExtensions($content); // services $this->parseDefinitions($content, $file); }
/** * {@inheritdoc} */ public function rename($name, $new_name) { $status = @rename($this->getFilePath($name), $this->getFilePath($new_name)); if ($status === FALSE) { throw new StorageException('Failed to rename configuration file from: ' . $this->getFilePath($name) . ' to: ' . $this->getFilePath($new_name)); } $this->fileCache->delete($this->getFilePath($name)); $this->fileCache->delete($this->getFilePath($new_name)); return TRUE; }
/** * @covers ::delete */ public function testDelete() { $filename = __DIR__ . '/Fixtures/llama-23.txt'; $realpath = realpath($filename); $cid = 'prefix:test:' . $realpath; $this->fileCache->set($filename, 23); // Ensure data is removed after deletion. $this->fileCache->delete($filename); $result = $this->staticFileCache->fetch([$cid]); $this->assertEquals([], $result); $result = $this->fileCache->get($filename); $this->assertNull($result); }
/** * {@inheritdoc} */ public function getDefinitions() { $definitions = array(); $reader = $this->getAnnotationReader(); // Clear the annotation loaders of any previous annotation classes. AnnotationRegistry::reset(); // Register the namespaces of classes that can be used for annotations. AnnotationRegistry::registerLoader('class_exists'); // Search for classes within all PSR-0 namespace locations. foreach ($this->getPluginNamespaces() as $namespace => $dirs) { foreach ($dirs as $dir) { if (file_exists($dir)) { $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($dir, \RecursiveDirectoryIterator::SKIP_DOTS)); foreach ($iterator as $fileinfo) { if ($fileinfo->getExtension() == 'php') { if ($cached = $this->fileCache->get($fileinfo->getPathName())) { if (isset($cached['id'])) { // Explicitly unserialize this to create a new object instance. $definitions[$cached['id']] = unserialize($cached['content']); } continue; } $sub_path = $iterator->getSubIterator()->getSubPath(); $sub_path = $sub_path ? str_replace(DIRECTORY_SEPARATOR, '\\', $sub_path) . '\\' : ''; $class = $namespace . '\\' . $sub_path . $fileinfo->getBasename('.php'); // The filename is already known, so there is no need to find the // file. However, StaticReflectionParser needs a finder, so use a // mock version. $finder = MockFileFinder::create($fileinfo->getPathName()); $parser = new StaticReflectionParser($class, $finder, TRUE); /** @var $annotation \Drupal\Component\Annotation\AnnotationInterface */ if ($annotation = $reader->getClassAnnotation($parser->getReflectionClass(), $this->pluginDefinitionAnnotationName)) { $this->prepareAnnotationDefinition($annotation, $class); $id = $annotation->getId(); $content = $annotation->get(); $definitions[$id] = $content; // Explicitly serialize this to create a new object instance. $this->fileCache->set($fileinfo->getPathName(), ['id' => $id, 'content' => serialize($content)]); } else { // Store a NULL object, so the file is not reparsed again. $this->fileCache->set($fileinfo->getPathName(), [NULL]); } } } } } } // Don't let annotation loaders pile up. AnnotationRegistry::reset(); return $definitions; }
/** * Recursively scans a base directory for the requested extension type. * * @param string $dir * A relative base directory path to scan, without trailing slash. * @param bool $include_tests * Whether to include test extensions. If FALSE, all 'tests' directories are * excluded in the search. * * @return array * An associative array whose keys are extension type names and whose values * are associative arrays of \Drupal\Core\Extension\Extension objects, keyed * by absolute path name. * * @see \Drupal\Core\Extension\Discovery\RecursiveExtensionFilterIterator */ protected function scanDirectory($dir, $include_tests) { $files = array(); // In order to scan top-level directories, absolute directory paths have to // be used (which also improves performance, since any configured PHP // include_paths will not be consulted). Retain the relative originating // directory being scanned, so relative paths can be reconstructed below // (all paths are expected to be relative to $this->root). $dir_prefix = $dir == '' ? '' : "{$dir}/"; $absolute_dir = $dir == '' ? $this->root : $this->root . "/{$dir}"; if (!is_dir($absolute_dir)) { return $files; } // Use Unix paths regardless of platform, skip dot directories, follow // symlinks (to allow extensions to be linked from elsewhere), and return // the RecursiveDirectoryIterator instance to have access to getSubPath(), // since SplFileInfo does not support relative paths. $flags = \FilesystemIterator::UNIX_PATHS; $flags |= \FilesystemIterator::SKIP_DOTS; $flags |= \FilesystemIterator::FOLLOW_SYMLINKS; $flags |= \FilesystemIterator::CURRENT_AS_SELF; $directory_iterator = new \RecursiveDirectoryIterator($absolute_dir, $flags); // Filter the recursive scan to discover extensions only. // Important: Without a RecursiveFilterIterator, RecursiveDirectoryIterator // would recurse into the entire filesystem directory tree without any kind // of limitations. $filter = new RecursiveExtensionFilterIterator($directory_iterator); $filter->acceptTests($include_tests); // The actual recursive filesystem scan is only invoked by instantiating the // RecursiveIteratorIterator. $iterator = new \RecursiveIteratorIterator($filter, \RecursiveIteratorIterator::LEAVES_ONLY, \RecursiveIteratorIterator::CATCH_GET_CHILD); foreach ($iterator as $key => $fileinfo) { // All extension names in Drupal have to be valid PHP function names due // to the module hook architecture. if (!preg_match(static::PHP_FUNCTION_PATTERN, $fileinfo->getBasename('.info.yml'))) { continue; } if ($this->fileCache && ($cached_extension = $this->fileCache->get($fileinfo->getPathName()))) { $files[$cached_extension->getType()][$key] = $cached_extension; continue; } // Determine extension type from info file. $type = FALSE; $file = $fileinfo->openFile('r'); while (!$type && !$file->eof()) { preg_match('@^type:\\s*(\'|")?(\\w+)\\1?\\s*$@', $file->fgets(), $matches); if (isset($matches[2])) { $type = $matches[2]; } } if (empty($type)) { continue; } $name = $fileinfo->getBasename('.info.yml'); $pathname = $dir_prefix . $fileinfo->getSubPathname(); // Determine whether the extension has a main extension file. // For theme engines, the file extension is .engine. if ($type == 'theme_engine') { $filename = $name . '.engine'; } else { $filename = $name . '.' . $type; } if (!file_exists(dirname($pathname) . '/' . $filename)) { $filename = NULL; } $extension = new Extension($this->root, $type, $pathname, $filename); // Track the originating directory for sorting purposes. $extension->subpath = $fileinfo->getSubPath(); $extension->origin = $dir; $files[$type][$key] = $extension; if ($this->fileCache) { $this->fileCache->set($fileinfo->getPathName(), $extension); } } return $files; }