PageRenderTime 53ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/phpdocumentor/phpdocumentor/src/phpDocumentor/Transformer/Transformer.php

https://gitlab.com/faisaliqbal/mytripsorter
PHP | 317 lines | 229 code | 21 blank | 67 comment | 7 complexity | b128ccba6eb6d61001d2666457d140fb MD5 | raw file
  1. <?php
  2. /**
  3. * phpDocumentor
  4. *
  5. * PHP Version 5.3
  6. *
  7. * @copyright 2010-2014 Mike van Riel / Naenius (http://www.naenius.com)
  8. * @license http://www.opensource.org/licenses/mit-license.php MIT
  9. * @link http://phpdoc.org
  10. */
  11. namespace phpDocumentor\Transformer;
  12. use phpDocumentor\Transformer\Event\WriterInitializationEvent;
  13. use phpDocumentor\Transformer\Writer\Initializable;
  14. use phpDocumentor\Transformer\Writer\WriterAbstract;
  15. use Psr\Log\LogLevel;
  16. use phpDocumentor\Compiler\CompilerPassInterface;
  17. use phpDocumentor\Descriptor\ProjectDescriptor;
  18. use phpDocumentor\Event\DebugEvent;
  19. use phpDocumentor\Event\Dispatcher;
  20. use phpDocumentor\Event\LogEvent;
  21. use phpDocumentor\Transformer\Event\PostTransformEvent;
  22. use phpDocumentor\Transformer\Event\PostTransformationEvent;
  23. use phpDocumentor\Transformer\Event\PreTransformEvent;
  24. use phpDocumentor\Transformer\Event\PreTransformationEvent;
  25. /**
  26. * Core class responsible for transforming the cache file to a set of artifacts.
  27. */
  28. class Transformer implements CompilerPassInterface
  29. {
  30. const EVENT_PRE_TRANSFORMATION = 'transformer.transformation.pre';
  31. const EVENT_POST_TRANSFORMATION = 'transformer.transformation.post';
  32. const EVENT_PRE_INITIALIZATION = 'transformer.writer.initialization.pre';
  33. const EVENT_POST_INITIALIZATION = 'transformer.writer.initialization.post';
  34. const EVENT_PRE_TRANSFORM = 'transformer.transform.pre';
  35. const EVENT_POST_TRANSFORM = 'transformer.transform.post';
  36. /** @var integer represents the priority in the Compiler queue. */
  37. const COMPILER_PRIORITY = 5000;
  38. /** @var string|null $target Target location where to output the artifacts */
  39. protected $target = null;
  40. /** @var Template\Collection $templates */
  41. protected $templates;
  42. /** @var Writer\Collection|WriterAbstract[] $writers */
  43. protected $writers;
  44. /** @var Transformation[] $transformations */
  45. protected $transformations = array();
  46. /**
  47. * Wires the template collection and writer collection to this transformer.
  48. *
  49. * @param Template\Collection $templateCollection
  50. * @param Writer\Collection $writerCollection
  51. */
  52. public function __construct(Template\Collection $templateCollection, Writer\Collection $writerCollection)
  53. {
  54. $this->templates = $templateCollection;
  55. $this->writers = $writerCollection;
  56. }
  57. /**
  58. * {@inheritDoc}
  59. */
  60. public function getDescription()
  61. {
  62. return 'Transform analyzed project into artifacts';
  63. }
  64. /**
  65. * Sets the target location where to output the artifacts.
  66. *
  67. * @param string $target The target location where to output the artifacts.
  68. *
  69. * @throws \InvalidArgumentException if the target is not a valid writable
  70. * directory.
  71. *
  72. * @return void
  73. */
  74. public function setTarget($target)
  75. {
  76. $path = realpath($target);
  77. if (false === $path) {
  78. if (@mkdir($target, 0755, true)) {
  79. $path = realpath($target);
  80. } else {
  81. throw new \InvalidArgumentException(
  82. 'Target directory (' . $target . ') does not exist and could not be created'
  83. );
  84. }
  85. }
  86. if (!is_dir($path) || !is_writable($path)) {
  87. throw new \InvalidArgumentException('Given target (' . $target . ') is not a writable directory');
  88. }
  89. $this->target = $path;
  90. }
  91. /**
  92. * Returns the location where to store the artifacts.
  93. *
  94. * @return string
  95. */
  96. public function getTarget()
  97. {
  98. return $this->target;
  99. }
  100. /**
  101. * Returns the list of templates which are going to be adopted.
  102. *
  103. * @return Template\Collection
  104. */
  105. public function getTemplates()
  106. {
  107. return $this->templates;
  108. }
  109. /**
  110. * Transforms the given project into a series of artifacts as provided by the templates.
  111. *
  112. * @param ProjectDescriptor $project
  113. *
  114. * @return void
  115. */
  116. public function execute(ProjectDescriptor $project)
  117. {
  118. Dispatcher::getInstance()->dispatch(
  119. self::EVENT_PRE_TRANSFORM,
  120. PreTransformEvent::createInstance($this)->setProject($project)
  121. );
  122. $transformations = $this->getTemplates()->getTransformations();
  123. $this->initializeWriters($project, $transformations);
  124. $this->transformProject($project, $transformations);
  125. Dispatcher::getInstance()->dispatch(self::EVENT_POST_TRANSFORM, PostTransformEvent::createInstance($this));
  126. $this->log('Finished transformation process');
  127. }
  128. /**
  129. * Converts a source file name to the name used for generating the end result.
  130. *
  131. * This method strips down the given $name using the following rules:
  132. *
  133. * * if the $name is suffixed with .php then that is removed
  134. * * any occurrence of \ or DIRECTORY_SEPARATOR is replaced with .
  135. * * any dots that the name starts or ends with is removed
  136. * * the result is suffixed with .html
  137. *
  138. * @param string $name Name to convert.
  139. *
  140. * @return string
  141. */
  142. public function generateFilename($name)
  143. {
  144. if (substr($name, -4) == '.php') {
  145. $name = substr($name, 0, -4);
  146. }
  147. return trim(str_replace(array(DIRECTORY_SEPARATOR, '\\'), '.', trim($name, DIRECTORY_SEPARATOR . '.')), '.')
  148. . '.html';
  149. }
  150. /**
  151. * Dispatches a logging request.
  152. *
  153. * @param string $message The message to log.
  154. * @param string $priority The logging priority
  155. *
  156. * @return void
  157. */
  158. public function log($message, $priority = LogLevel::INFO)
  159. {
  160. Dispatcher::getInstance()->dispatch(
  161. 'system.log',
  162. LogEvent::createInstance($this)
  163. ->setMessage($message)
  164. ->setPriority($priority)
  165. );
  166. }
  167. /**
  168. * Dispatches a logging request to log a debug message.
  169. *
  170. * @param string $message The message to log.
  171. *
  172. * @return void
  173. */
  174. public function debug($message)
  175. {
  176. Dispatcher::getInstance()->dispatch(
  177. 'system.debug',
  178. DebugEvent::createInstance($this)
  179. ->setMessage($message)
  180. );
  181. }
  182. /**
  183. * Initializes all writers that are used during this transformation.
  184. *
  185. * @param ProjectDescriptor $project
  186. * @param Transformation[] $transformations
  187. *
  188. * @return void
  189. */
  190. private function initializeWriters(ProjectDescriptor $project, $transformations)
  191. {
  192. $isInitialized = array();
  193. foreach ($transformations as $transformation) {
  194. $writerName = $transformation->getWriter();
  195. if (in_array($writerName, $isInitialized)) {
  196. continue;
  197. }
  198. $isInitialized[] = $writerName;
  199. $writer = $this->writers[$writerName];
  200. $this->initializeWriter($writer, $project);
  201. }
  202. }
  203. /**
  204. * Initializes the given writer using the provided project meta-data.
  205. *
  206. * This method wil call for the initialization of each writer that supports an initialization routine (as defined by
  207. * the `Initializable` interface).
  208. *
  209. * In addition to this, the following events emitted for each writer that is present in the collected list of
  210. * transformations, even those that do not implement the `Initializable` interface.
  211. *
  212. * Emitted events:
  213. *
  214. * - transformer.writer.initialization.pre, before the initialization of a single writer.
  215. * - transformer.writer.initialization.post, after the initialization of a single writer.
  216. *
  217. * @param WriterAbstract $writer
  218. * @param ProjectDescriptor $project
  219. *
  220. * @uses Dispatcher to emit the events surrounding an initialization.
  221. *
  222. * @return void
  223. */
  224. private function initializeWriter(WriterAbstract $writer, ProjectDescriptor $project)
  225. {
  226. $event = WriterInitializationEvent::createInstance($this)->setWriter($writer);
  227. Dispatcher::getInstance()->dispatch(self::EVENT_PRE_INITIALIZATION, $event);
  228. if ($writer instanceof Initializable) {
  229. $writer->initialize($project);
  230. }
  231. Dispatcher::getInstance()->dispatch(self::EVENT_POST_INITIALIZATION, $event);
  232. }
  233. /**
  234. * Applies all given transformations to the provided project.
  235. *
  236. * @param ProjectDescriptor $project
  237. * @param Transformation[] $transformations
  238. *
  239. * @return void
  240. */
  241. private function transformProject(ProjectDescriptor $project, $transformations)
  242. {
  243. foreach ($transformations as $transformation) {
  244. $transformation->setTransformer($this);
  245. $this->applyTransformationToProject($transformation, $project);
  246. }
  247. }
  248. /**
  249. * Applies the given transformation to the provided project.
  250. *
  251. * This method will attempt to find an appropriate writer for the given transformation and invoke that with the
  252. * transformation and project so that an artifact can be generated that matches the intended transformation.
  253. *
  254. * In addition this method will emit the following events:
  255. *
  256. * - transformer.transformation.pre, before the project has been transformed with this transformation.
  257. * - transformer.transformation.post, after the project has been transformed with this transformation
  258. *
  259. * @param Transformation $transformation
  260. * @param ProjectDescriptor $project
  261. *
  262. * @uses Dispatcher to emit the events surrounding a transformation.
  263. *
  264. * @return void
  265. */
  266. private function applyTransformationToProject(Transformation $transformation, ProjectDescriptor $project)
  267. {
  268. $this->log(
  269. sprintf(
  270. ' Writer %s %s on %s',
  271. $transformation->getWriter(),
  272. ($transformation->getQuery() ? ' using query "' . $transformation->getQuery() . '"' : ''),
  273. $transformation->getArtifact()
  274. )
  275. );
  276. $preTransformationEvent = PreTransformationEvent::createInstance($this)->setTransformation($transformation);
  277. Dispatcher::getInstance()->dispatch(self::EVENT_PRE_TRANSFORMATION, $preTransformationEvent);
  278. $writer = $this->writers[$transformation->getWriter()];
  279. $writer->transform($project, $transformation);
  280. $postTransformationEvent = PostTransformationEvent::createInstance($this);
  281. Dispatcher::getInstance()->dispatch(self::EVENT_POST_TRANSFORMATION, $postTransformationEvent);
  282. }
  283. }