Chris@0
|
1 <?php
|
Chris@0
|
2
|
Chris@0
|
3 namespace Drupal\Component\Discovery;
|
Chris@0
|
4
|
Chris@0
|
5 use Drupal\Component\Serialization\Yaml;
|
Chris@0
|
6 use Drupal\Component\FileCache\FileCacheFactory;
|
Chris@0
|
7
|
Chris@0
|
8 /**
|
Chris@0
|
9 * Provides discovery for YAML files within a given set of directories.
|
Chris@0
|
10 */
|
Chris@0
|
11 class YamlDiscovery implements DiscoverableInterface {
|
Chris@0
|
12
|
Chris@0
|
13 /**
|
Chris@0
|
14 * The base filename to look for in each directory.
|
Chris@0
|
15 *
|
Chris@0
|
16 * @var string
|
Chris@0
|
17 */
|
Chris@0
|
18 protected $name;
|
Chris@0
|
19
|
Chris@0
|
20 /**
|
Chris@0
|
21 * An array of directories to scan, keyed by the provider.
|
Chris@0
|
22 *
|
Chris@0
|
23 * @var array
|
Chris@0
|
24 */
|
Chris@0
|
25 protected $directories = [];
|
Chris@0
|
26
|
Chris@0
|
27 /**
|
Chris@0
|
28 * Constructs a YamlDiscovery object.
|
Chris@0
|
29 *
|
Chris@0
|
30 * @param string $name
|
Chris@0
|
31 * The base filename to look for in each directory. The format will be
|
Chris@0
|
32 * $provider.$name.yml.
|
Chris@0
|
33 * @param array $directories
|
Chris@0
|
34 * An array of directories to scan, keyed by the provider.
|
Chris@0
|
35 */
|
Chris@0
|
36 public function __construct($name, array $directories) {
|
Chris@0
|
37 $this->name = $name;
|
Chris@0
|
38 $this->directories = $directories;
|
Chris@0
|
39 }
|
Chris@0
|
40
|
Chris@0
|
41 /**
|
Chris@0
|
42 * {@inheritdoc}
|
Chris@0
|
43 */
|
Chris@0
|
44 public function findAll() {
|
Chris@0
|
45 $all = [];
|
Chris@0
|
46
|
Chris@0
|
47 $files = $this->findFiles();
|
Chris@0
|
48 $provider_by_files = array_flip($files);
|
Chris@0
|
49
|
Chris@0
|
50 $file_cache = FileCacheFactory::get('yaml_discovery:' . $this->name);
|
Chris@0
|
51
|
Chris@0
|
52 // Try to load from the file cache first.
|
Chris@0
|
53 foreach ($file_cache->getMultiple($files) as $file => $data) {
|
Chris@0
|
54 $all[$provider_by_files[$file]] = $data;
|
Chris@0
|
55 unset($provider_by_files[$file]);
|
Chris@0
|
56 }
|
Chris@0
|
57
|
Chris@0
|
58 // If there are files left that were not returned from the cache, load and
|
Chris@0
|
59 // parse them now. This list was flipped above and is keyed by filename.
|
Chris@0
|
60 if ($provider_by_files) {
|
Chris@0
|
61 foreach ($provider_by_files as $file => $provider) {
|
Chris@0
|
62 // If a file is empty or its contents are commented out, return an empty
|
Chris@0
|
63 // array instead of NULL for type consistency.
|
Chris@0
|
64 $all[$provider] = $this->decode($file);
|
Chris@0
|
65 $file_cache->set($file, $all[$provider]);
|
Chris@0
|
66 }
|
Chris@0
|
67 }
|
Chris@0
|
68
|
Chris@0
|
69 return $all;
|
Chris@0
|
70 }
|
Chris@0
|
71
|
Chris@0
|
72 /**
|
Chris@0
|
73 * Decode a YAML file.
|
Chris@0
|
74 *
|
Chris@0
|
75 * @param string $file
|
Chris@0
|
76 * Yaml file path.
|
Chris@0
|
77 * @return array
|
Chris@0
|
78 */
|
Chris@0
|
79 protected function decode($file) {
|
Chris@0
|
80 return Yaml::decode(file_get_contents($file)) ?: [];
|
Chris@0
|
81 }
|
Chris@0
|
82
|
Chris@0
|
83 /**
|
Chris@0
|
84 * Returns an array of file paths, keyed by provider.
|
Chris@0
|
85 *
|
Chris@0
|
86 * @return array
|
Chris@0
|
87 */
|
Chris@0
|
88 protected function findFiles() {
|
Chris@0
|
89 $files = [];
|
Chris@0
|
90 foreach ($this->directories as $provider => $directory) {
|
Chris@0
|
91 $file = $directory . '/' . $provider . '.' . $this->name . '.yml';
|
Chris@0
|
92 if (file_exists($file)) {
|
Chris@0
|
93 $files[$provider] = $file;
|
Chris@0
|
94 }
|
Chris@0
|
95 }
|
Chris@0
|
96 return $files;
|
Chris@0
|
97 }
|
Chris@0
|
98
|
Chris@0
|
99 }
|