Extension.php 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. <?php
  2. namespace Drupal\Core\Extension;
  3. /**
  4. * Defines an extension (file) object.
  5. *
  6. * This class does not implement the Serializable interface since problems
  7. * occurred when using the serialize method.
  8. *
  9. * @see https://bugs.php.net/bug.php?id=66052
  10. */
  11. class Extension {
  12. /**
  13. * The type of the extension (e.g., 'module').
  14. *
  15. * @var string
  16. */
  17. protected $type;
  18. /**
  19. * The relative pathname of the extension (e.g., 'core/modules/node/node.info.yml').
  20. *
  21. * @var string
  22. */
  23. protected $pathname;
  24. /**
  25. * The filename of the main extension file (e.g., 'node.module').
  26. *
  27. * @var string|null
  28. */
  29. protected $filename;
  30. /**
  31. * An SplFileInfo instance for the extension's info file.
  32. *
  33. * Note that SplFileInfo is a PHP resource and resources cannot be serialized.
  34. *
  35. * @var \SplFileInfo
  36. */
  37. protected $splFileInfo;
  38. /**
  39. * The app root.
  40. *
  41. * @var string
  42. */
  43. protected $root;
  44. /**
  45. * Constructs a new Extension object.
  46. *
  47. * @param string $root
  48. * The app root.
  49. * @param string $type
  50. * The type of the extension; e.g., 'module'.
  51. * @param string $pathname
  52. * The relative path and filename of the extension's info file; e.g.,
  53. * 'core/modules/node/node.info.yml'.
  54. * @param string $filename
  55. * (optional) The filename of the main extension file; e.g., 'node.module'.
  56. */
  57. public function __construct($root, $type, $pathname, $filename = NULL) {
  58. // @see \Drupal\Core\Theme\ThemeInitialization::getActiveThemeByName()
  59. assert($pathname === 'core/core.info.yml' || ($pathname[0] !== '/' && file_exists($root . '/' . $pathname)), sprintf('The file specified by the given app root, relative path and file name (%s) do not exist.', $root . '/' . $pathname));
  60. $this->root = $root;
  61. $this->type = $type;
  62. $this->pathname = $pathname;
  63. $this->filename = $filename;
  64. }
  65. /**
  66. * Returns the type of the extension.
  67. *
  68. * @return string
  69. */
  70. public function getType() {
  71. return $this->type;
  72. }
  73. /**
  74. * Returns the internal name of the extension.
  75. *
  76. * @return string
  77. */
  78. public function getName() {
  79. return basename($this->pathname, '.info.yml');
  80. }
  81. /**
  82. * Returns the relative path of the extension.
  83. *
  84. * @return string
  85. */
  86. public function getPath() {
  87. return dirname($this->pathname);
  88. }
  89. /**
  90. * Returns the relative path and filename of the extension's info file.
  91. *
  92. * @return string
  93. */
  94. public function getPathname() {
  95. return $this->pathname;
  96. }
  97. /**
  98. * Returns the filename of the extension's info file.
  99. *
  100. * @return string
  101. */
  102. public function getFilename() {
  103. return basename($this->pathname);
  104. }
  105. /**
  106. * Returns the relative path of the main extension file, if any.
  107. *
  108. * @return string|null
  109. */
  110. public function getExtensionPathname() {
  111. if ($this->filename) {
  112. return $this->getPath() . '/' . $this->filename;
  113. }
  114. }
  115. /**
  116. * Returns the name of the main extension file, if any.
  117. *
  118. * @return string|null
  119. */
  120. public function getExtensionFilename() {
  121. return $this->filename;
  122. }
  123. /**
  124. * Loads the main extension file, if any.
  125. *
  126. * @return bool
  127. * TRUE if this extension has a main extension file, FALSE otherwise.
  128. */
  129. public function load() {
  130. if ($this->filename) {
  131. include_once $this->root . '/' . $this->getPath() . '/' . $this->filename;
  132. return TRUE;
  133. }
  134. return FALSE;
  135. }
  136. /**
  137. * Re-routes method calls to SplFileInfo.
  138. *
  139. * Offers all SplFileInfo methods to consumers; e.g., $extension->getMTime().
  140. */
  141. public function __call($method, array $args) {
  142. if (!isset($this->splFileInfo)) {
  143. $this->splFileInfo = new \SplFileInfo($this->root . '/' . $this->pathname);
  144. }
  145. return call_user_func_array([$this->splFileInfo, $method], $args);
  146. }
  147. /**
  148. * Magic method implementation to serialize the extension object.
  149. *
  150. * @return array
  151. * The names of all variables that should be serialized.
  152. */
  153. public function __sleep() {
  154. // @todo \Drupal\Core\Extension\ThemeExtensionList is adding custom
  155. // properties to the Extension object.
  156. $properties = get_object_vars($this);
  157. // Don't serialize the app root, since this could change if the install is
  158. // moved. Don't serialize splFileInfo because it can not be.
  159. unset($properties['splFileInfo'], $properties['root']);
  160. return array_keys($properties);
  161. }
  162. /**
  163. * Magic method implementation to unserialize the extension object.
  164. */
  165. public function __wakeup() {
  166. // Get the app root from the container.
  167. $this->root = \Drupal::hasService('app.root') ? \Drupal::root() : DRUPAL_ROOT;
  168. }
  169. }