PageRenderTime 703ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/Ypd.php

https://github.com/Martiusweb/YaPhpDoc
PHP | 674 lines | 332 code | 66 blank | 276 comment | 23 complexity | d8ae6f76e370b3ad12d0a3063ccf584a MD5 | raw file
  1. <?php
  2. /**
  3. * YaPhpDoc
  4. * @author Martin Richard
  5. * @license New BSD License
  6. */
  7. /**
  8. * Ypd is the base system class. It provides translation helpers and
  9. * store the configuration of the instance.
  10. *
  11. * @author Martin Richard
  12. */
  13. class Ypd implements YaPhpDoc_Core_OutputManager_Interface, YaPhpDoc_Core_TranslationManager_Interface
  14. {
  15. /**
  16. * Returns the array of cli options.
  17. * @return array
  18. */
  19. protected static function _getCliOptions()
  20. {
  21. return array(
  22. 'file|f=s' => 'Name of file(s) to parse, coma-separated',
  23. 'directory|d=s' => 'Name of directory(ies) to parse, coma-separated',
  24. 'help|h' => 'Display help summary',
  25. 'verbose|v' => 'Enable verbose output',
  26. 'disable-output|no' => 'Disable output',
  27. 'disable-notice|nn' => 'Disable notices output',
  28. 'disable-warning|nw' => 'Disable warning messages output',
  29. 'disable-error|ne' => 'Disable fatal errors output',
  30. 'list|l' => 'Don\'t parse, just display files to parse list',
  31. 'exclude|e=s' => 'Exclude files matching the given Regex pattern',
  32. 'include|i=s' => 'Include files matching the given Regex pattern',
  33. 'output-format|out=s' => 'Select output format (default is the standard value)',
  34. 'destination|o=s' => 'Destination of the generated files (default is working directory)',
  35. 'config|c=s' => 'Configuration file'
  36. );
  37. }
  38. /**
  39. * Returns an array of available locales
  40. * @return array
  41. */
  42. protected static function _getTranslations()
  43. {
  44. return array('en');
  45. }
  46. /**
  47. * Singleton instance
  48. * @var YaPhpDoc_Core_Ypd
  49. */
  50. protected static $_instance;
  51. /**
  52. * Getopt cli option parser object.
  53. * @var YaPhpDoc_Console_Getopt
  54. */
  55. protected $_getopt;
  56. /**
  57. * PHP Documents parser object.
  58. * @var YaPhpDoc_Core_Parser
  59. */
  60. protected $_parser;
  61. /**
  62. * PHP Documentation generator object.
  63. * @var YaPhpDoc_Generator_Abstract
  64. */
  65. protected $_generator;
  66. /**
  67. * Zend_Config object.
  68. * @var Zend_Config
  69. */
  70. protected $_config;
  71. /**
  72. * Locale code
  73. * @var string
  74. */
  75. protected $_locale = 'en';
  76. /**
  77. * Translations object map
  78. * @var Zend_Translate
  79. */
  80. protected $_translation;
  81. /**
  82. * Loaded translation dictionaries
  83. * @var array
  84. */
  85. protected $_loadedTranslations = array();
  86. /**
  87. * True if output is enabled
  88. * @var bool
  89. */
  90. protected $_enableOutput = true;
  91. /**
  92. * True if errors are displayed
  93. * @var bool
  94. */
  95. protected $_outputErrors = true;
  96. /**
  97. * True if warning messages are displayed
  98. * @var bool
  99. */
  100. protected $_outputWarnings = true;
  101. /**
  102. * True if notices are displayed
  103. * @var bool
  104. */
  105. protected $_outputNotices = true;
  106. /**
  107. * True if verbose mode is enabled (default to false).
  108. * @var bool
  109. */
  110. protected $_verbose = false;
  111. /**
  112. * Destination of the generated files.
  113. * @var string
  114. */
  115. protected $_destination = '';
  116. /**
  117. * Path to data directory.
  118. * @var string
  119. */
  120. protected $_dataDir = '';
  121. /**
  122. * Warning alerts counter
  123. * @var int
  124. */
  125. protected $_warnings = 0;
  126. /**
  127. * Notices counter
  128. * @var int
  129. */
  130. protected $_notices = 0;
  131. /**
  132. * Constructor is private, use getInstance() instead.
  133. *
  134. * Try to find the current locale according to YPD_LOCALE constant and
  135. * available translations.
  136. */
  137. protected function __construct()
  138. {
  139. if(!defined('YPD_LOCALE') || !in_array(YPD_LOCALE, self::_getTranslations()))
  140. $this->_locale = 'en';
  141. else
  142. $this->_locale = YPD_LOCALE;
  143. $this->_parser = new YaPhpDoc_Core_Parser($this, $this);
  144. YaPhpDoc_Core_TranslationManager_Resolver::setTranslationManager($this);
  145. }
  146. /**
  147. * Return the Getopt object allowing to parse cli options.
  148. * @return YaPhpDoc_Console_Getopt
  149. */
  150. public function getGetopt()
  151. {
  152. if(null === $this->_getopt)
  153. {
  154. $options = self::_getCliOptions();
  155. # Translate options
  156. $translator = $this->getTranslation('cli');
  157. foreach($options as $option => $desc)
  158. $options[$option] = $translator->_($desc);
  159. # Create getopt object
  160. $this->_getopt = new YaPhpDoc_Console_Getopt($options);
  161. }
  162. return $this->_getopt;
  163. }
  164. /**
  165. * Returns the document parser object.
  166. * @return YaPhpDoc_Core_Parser
  167. */
  168. public function getParser()
  169. {
  170. return $this->_parser;
  171. }
  172. /**
  173. * Returns the documentation generator. If the generator does not exists
  174. * yet, getGenerator() will try to create a generator for "default" format.
  175. *
  176. * @return YaPhpDoc_Generator_Abstract
  177. */
  178. public function getGenerator()
  179. {
  180. if($this->_generator === null)
  181. {
  182. $this->setOutputFormat('default');
  183. }
  184. return $this->_generator;
  185. }
  186. /**
  187. * Returns translate object for current $key dictionnary
  188. * @param string $key (default core)
  189. * @return Zend_Translate
  190. */
  191. public function getTranslation($key = 'core')
  192. {
  193. $options = array(
  194. 'delimiter' => ',',
  195. 'disableNotices' => true
  196. );
  197. if(null === $this->_translation)
  198. {
  199. $this->_translation = new Zend_Translate(
  200. 'csv',
  201. YPD_ROOT.DIRECTORY_SEPARATOR.'l10n'.DIRECTORY_SEPARATOR
  202. .self::$this->_locale.DIRECTORY_SEPARATOR.$key.'.csv',
  203. $this->_locale,
  204. $options
  205. );
  206. $this->_translation->setLocale($this->_locale);
  207. array_push($this->_loadedTranslations, $key);
  208. }
  209. elseif(!in_array($key, $this->_loadedTranslations))
  210. {
  211. $this->_translation->addTranslation(
  212. YPD_ROOT.DIRECTORY_SEPARATOR.'l10n'.DIRECTORY_SEPARATOR
  213. .self::$this->_locale.DIRECTORY_SEPARATOR.$key.'.csv',
  214. $this->_locale, $options);
  215. array_push($this->_loadedTranslations, $key);
  216. }
  217. return $this->_translation;
  218. }
  219. /**
  220. * Returns the Ypd instance
  221. * @return Ypd
  222. */
  223. public static function getInstance()
  224. {
  225. if(null === self::$_instance)
  226. {
  227. self::$_instance = new self();
  228. }
  229. return self::$_instance;
  230. }
  231. /**
  232. * Enable or disable output.
  233. *
  234. * @param bool $flag default true
  235. * @return Ypd
  236. */
  237. public function setEnableOutput($flag = true)
  238. {
  239. $this->_enableOutput = $flag;
  240. return $this;
  241. }
  242. /**
  243. * Enable or disable fatal errors.
  244. *
  245. * @param bool $flag default true
  246. * @return Ypd
  247. */
  248. public function setOutputErrors($flag = true)
  249. {
  250. $this->_outputErrors = $flag;
  251. return $this;
  252. }
  253. /**
  254. * Enable or disable fatal warning messages.
  255. *
  256. * @param bool $flag default true
  257. * @return Ypd
  258. */
  259. public function setOutputWarnings($flag = true)
  260. {
  261. $this->_outputWarnings = $flag;
  262. return $this;
  263. }
  264. /**
  265. * Enable or disable notices.
  266. *
  267. * @param bool $flag default true
  268. * @return Ypd
  269. */
  270. public function setOutputNotices($flag = true)
  271. {
  272. $this->_outputNotices = $flag;
  273. return $this;
  274. }
  275. /**
  276. * Enable or disable verbose mode.
  277. *
  278. * @param bool $flag default true
  279. * @return Ypd
  280. */
  281. public function setVerbose($flag = true)
  282. {
  283. $this->_verbose = $flag;
  284. return $this;
  285. }
  286. /**
  287. * Display a message to user.
  288. *
  289. * @todo Support web interface
  290. * @param string $message
  291. * @param bool $linebreak optional, default to true, adds a trailing line-break
  292. * @return Ypd
  293. */
  294. public function out($message, $linebreak = true)
  295. {
  296. if($this->_enableOutput)
  297. {
  298. echo $message."\n";
  299. }
  300. return $this;
  301. }
  302. /**
  303. * Send a fatal error and stops the program.
  304. *
  305. * @todo Support web interface
  306. * @param Exception|string $error
  307. * @return void
  308. */
  309. public function error($error)
  310. {
  311. $txt = $this->getTranslation()->_('Fatal error');
  312. if($this->_outputErrors)
  313. {
  314. if($error instanceof Exception)
  315. $this->out($txt.' : '.$error->getMessage());
  316. else
  317. $this->out($txt.' : '.$error);
  318. }
  319. exit();
  320. }
  321. /**
  322. * Send a warning.
  323. *
  324. * @param Exception|string $warning
  325. * @return Ypd
  326. */
  327. public function warning($warning)
  328. {
  329. $txt = $this->getTranslation()->_('Warning');
  330. if($this->_outputWarnings)
  331. {
  332. if($warning instanceof Exception)
  333. $this->out($txt.' : '.$warning->getMessage());
  334. else
  335. $this->out($txt.' : '.$warning);
  336. }
  337. ++$this->_warning;
  338. return $this;
  339. }
  340. /**
  341. * Send a notice.
  342. *
  343. * @param Exception|string $notice
  344. * @return Ypd
  345. */
  346. public function notice($notice)
  347. {
  348. if($this->_outputNotices)
  349. {
  350. $txt = $this->getTranslation()->_('Notice');
  351. if($notice instanceof Exception)
  352. $this->out($txt.' : '.$notice->getMessage());
  353. else
  354. $this->out($txt.' : '.$notice);
  355. }
  356. ++$this->_notices;
  357. return $this;
  358. }
  359. /**
  360. * Display (if verbose mode is enabled) the message.
  361. *
  362. * @param String $message
  363. * @param bool $translate (optional, default true) Translate the message
  364. * @param string $translation_key (optional, default core) Set the dictionnary to use for translation
  365. * @return Ypd
  366. */
  367. public function verbose($message, $translate = true, $translation_key = 'core')
  368. {
  369. if($this->_verbose)
  370. {
  371. if($translate)
  372. $message = $this->getTranslation($translation_key)->_($message);
  373. $this->out($message);
  374. }
  375. return $this;
  376. }
  377. /**
  378. * Returns the number of warning alerts caught during execution.
  379. * @return int
  380. */
  381. public function getWarningCount()
  382. {
  383. return $this->_warnings;
  384. }
  385. /**
  386. * Returns the number of notices caught during execution.
  387. * @return int
  388. */
  389. public function getNoticeCount()
  390. {
  391. return $this->_notices;
  392. }
  393. /**
  394. * Display an information when non-handled exception is caught, and exit
  395. * the program.
  396. *
  397. * @param Exception $e
  398. * @return void
  399. */
  400. public function phpException(Exception $e)
  401. {
  402. $this->out(
  403. 'A fatal error had been received, if you think that it must '
  404. ."not append, please contact developer with following :\n"
  405. .$e->getMessage()."\n"
  406. .$e->getTraceAsString()
  407. );
  408. exit();
  409. }
  410. /**
  411. * Add file(s) to parse, coma separated.
  412. *
  413. * @param string $file
  414. * @return Ypd
  415. */
  416. public function addFileFromOption($file)
  417. {
  418. if(!empty($file))
  419. {
  420. $file = explode(',', $file);
  421. if(count($file))
  422. $this->_parser->addFile($file);
  423. }
  424. return $this;
  425. }
  426. /**
  427. * Add directory(ies) to parse, coma separated.
  428. *
  429. * @param string $directory
  430. * @return Ypd
  431. */
  432. public function addDirectoryFromOption($directory)
  433. {
  434. if(!empty($directory))
  435. {
  436. $directory = explode(',', $directory);
  437. if(count($directory))
  438. $this->_parser->addDirectory($directory);
  439. }
  440. return $this;
  441. }
  442. /**
  443. * Add paths to parse, in an array. Each path will be analyzed and tested
  444. * in order to determine if the path matches an existing file or a
  445. * directory.
  446. *
  447. * @param array $paths
  448. * @return Ypd
  449. */
  450. public function addPathsFromOption(array $paths)
  451. {
  452. foreach($paths as $path)
  453. {
  454. if(is_file($path))
  455. $this->_parser->addFile($path);
  456. elseif(is_dir($path))
  457. $this->_parser->addDirectory($path);
  458. else
  459. $this->warning(sprintf($this->getTranslation()->_(
  460. '%s does not seem to be a file or a directory, ignoring'
  461. ), $path));
  462. }
  463. return $this;
  464. }
  465. /**
  466. * Set filenames include pattern from option.
  467. *
  468. * @param string $pattern
  469. * @return Ypd
  470. */
  471. public function setIncludePatternFromOption($pattern)
  472. {
  473. $this->_parser->setIncludePattern($pattern);
  474. return $this;
  475. }
  476. /**
  477. * Set filenames exclude pattern from option.
  478. *
  479. * @param string $pattern
  480. * @return Ypd
  481. */
  482. public function setExcludePatternFromOption($pattern)
  483. {
  484. $this->_parser->setExcludePattern($pattern);
  485. return $this;
  486. }
  487. /**
  488. * Set the documentation output format.
  489. * @param string $format
  490. * @return Ypd
  491. */
  492. public function setOutputFormat($format)
  493. {
  494. $this->_generator = YaPhpDoc_Generator_Factory::getGenerator($format,
  495. $this, $this, $this->_dataDir);
  496. return $this;
  497. }
  498. /**
  499. * Set the destination directory.
  500. * @param string $dest
  501. * @return Ypd
  502. */
  503. public function setDestination($dest)
  504. {
  505. $this->_destination = $dest;
  506. return $this;
  507. }
  508. /**
  509. * Set the data directory.
  510. *
  511. * @param string $data_dir path to data directory
  512. * @return Ypd
  513. */
  514. public function setDataDirectory($data_dir)
  515. {
  516. $this->_dataDir = $data_dir;
  517. return $this;
  518. }
  519. /**
  520. * Returns the data directory.
  521. * @return string
  522. */
  523. public function getDataDirectory()
  524. {
  525. return $this->_dataDir;
  526. }
  527. /**
  528. * Loads configuration according to config_file.
  529. * Formats supported are listed in the YaPhpDoc_Tool_Config::load() method
  530. * documentation.
  531. *
  532. * If $merge is given, the file will be used as default configuration file.
  533. *
  534. * @param string $config_file
  535. * @param string $merge base file to merge with
  536. * @throws YaPhpDoc_Core_Exception
  537. * @return Ypd
  538. */
  539. public function setConfig($config_file, $merge = null)
  540. {
  541. try {
  542. if($merge == null)
  543. $this->_config = YaPhpDoc_Tool_Config::load($config_file);
  544. else
  545. $this->_config = YaPhpDoc_Tool_Config::merge($merge, $config_file);
  546. }
  547. catch(Zend_Config_Exception $e)
  548. {
  549. throw new YaPhpDoc_Core_Exception(sprintf($this->getTranslation()
  550. ->_('Unable to load configuration file %s'), $config_file));
  551. }
  552. return $this;
  553. }
  554. /**
  555. * Display the list of file to be parsed.
  556. * @return Ypd
  557. */
  558. public function outputFilesToParse()
  559. {
  560. $this->out($this->getTranslation()->_('Files to parse :'));
  561. foreach($this->getParser()->getFilesToParse() as $file)
  562. $this->out($file);
  563. return $this;
  564. }
  565. /**
  566. * Start parsing.
  567. *
  568. * @return Ypd
  569. */
  570. public function parse()
  571. {
  572. $this->verbose('Start parsing');
  573. $timer = new YaPhpDoc_Tool_Timer();
  574. $timer->start();
  575. $e = null;
  576. try {
  577. $this->_parser->setConfig($this->_config->parser)->parseAll();
  578. }
  579. catch(Exception $e)
  580. {}
  581. $timer->stop();
  582. $msg = sprintf($this->getTranslation()
  583. ->_('Stop parsing (time : %.4f sec, memory: %s, max: %s)'), $timer->getTimeUsage(),
  584. $timer->getMemoryUsage(), $timer->getMemoryPeak()
  585. );
  586. $this->verbose($msg, false);
  587. if(null !== $e)
  588. throw $e;
  589. return $this;
  590. }
  591. /**
  592. * Start documentation generation.
  593. *
  594. * @return Ypd
  595. */
  596. public function generate()
  597. {
  598. $msg = sprintf($this->getTranslation()
  599. ->_('Start generation of documentation in format %s'), $this->_generator);
  600. $this->verbose($msg, false);
  601. $this->getGenerator()
  602. ->setDestination($this->_destination)
  603. ->setConfig($this->_config->generator)
  604. ->setRoot($this->getParser()->getRoot())
  605. ->render();
  606. return $this;
  607. }
  608. }