ExportYaml.php 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. <?php
  2. /**
  3. * Set of functions used to build YAML dumps of tables
  4. */
  5. declare(strict_types=1);
  6. namespace PhpMyAdmin\Plugins\Export;
  7. use PhpMyAdmin\DatabaseInterface;
  8. use PhpMyAdmin\FieldMetadata;
  9. use PhpMyAdmin\Plugins\ExportPlugin;
  10. use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyMainGroup;
  11. use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyRootGroup;
  12. use PhpMyAdmin\Properties\Options\Items\HiddenPropertyItem;
  13. use PhpMyAdmin\Properties\Plugins\ExportPluginProperties;
  14. use function __;
  15. use function array_key_exists;
  16. use function is_numeric;
  17. use function str_replace;
  18. use function stripslashes;
  19. /**
  20. * Handles the export for the YAML format
  21. */
  22. class ExportYaml extends ExportPlugin
  23. {
  24. /**
  25. * @psalm-return non-empty-lowercase-string
  26. */
  27. public function getName(): string
  28. {
  29. return 'yaml';
  30. }
  31. protected function setProperties(): ExportPluginProperties
  32. {
  33. $exportPluginProperties = new ExportPluginProperties();
  34. $exportPluginProperties->setText('YAML');
  35. $exportPluginProperties->setExtension('yml');
  36. $exportPluginProperties->setMimeType('text/yaml');
  37. $exportPluginProperties->setForceFile(true);
  38. $exportPluginProperties->setOptionsText(__('Options'));
  39. // create the root group that will be the options field for
  40. // $exportPluginProperties
  41. // this will be shown as "Format specific options"
  42. $exportSpecificOptions = new OptionsPropertyRootGroup('Format Specific Options');
  43. // general options main group
  44. $generalOptions = new OptionsPropertyMainGroup('general_opts');
  45. // create primary items and add them to the group
  46. $leaf = new HiddenPropertyItem('structure_or_data');
  47. $generalOptions->addProperty($leaf);
  48. // add the main group to the root group
  49. $exportSpecificOptions->addProperty($generalOptions);
  50. // set the options for the export plugin property item
  51. $exportPluginProperties->setOptions($exportSpecificOptions);
  52. return $exportPluginProperties;
  53. }
  54. /**
  55. * Outputs export header
  56. */
  57. public function exportHeader(): bool
  58. {
  59. $this->export->outputHandler('%YAML 1.1' . $GLOBALS['crlf'] . '---' . $GLOBALS['crlf']);
  60. return true;
  61. }
  62. /**
  63. * Outputs export footer
  64. */
  65. public function exportFooter(): bool
  66. {
  67. $this->export->outputHandler('...' . $GLOBALS['crlf']);
  68. return true;
  69. }
  70. /**
  71. * Outputs database header
  72. *
  73. * @param string $db Database name
  74. * @param string $dbAlias Aliases of db
  75. */
  76. public function exportDBHeader($db, $dbAlias = ''): bool
  77. {
  78. return true;
  79. }
  80. /**
  81. * Outputs database footer
  82. *
  83. * @param string $db Database name
  84. */
  85. public function exportDBFooter($db): bool
  86. {
  87. return true;
  88. }
  89. /**
  90. * Outputs CREATE DATABASE statement
  91. *
  92. * @param string $db Database name
  93. * @param string $exportType 'server', 'database', 'table'
  94. * @param string $dbAlias Aliases of db
  95. */
  96. public function exportDBCreate($db, $exportType, $dbAlias = ''): bool
  97. {
  98. return true;
  99. }
  100. /**
  101. * Outputs the content of a table in JSON format
  102. *
  103. * @param string $db database name
  104. * @param string $table table name
  105. * @param string $crlf the end of line sequence
  106. * @param string $errorUrl the url to go back in case of error
  107. * @param string $sqlQuery SQL query for obtaining data
  108. * @param array $aliases Aliases of db/table/columns
  109. */
  110. public function exportData(
  111. $db,
  112. $table,
  113. $crlf,
  114. $errorUrl,
  115. $sqlQuery,
  116. array $aliases = []
  117. ): bool {
  118. global $dbi;
  119. $db_alias = $db;
  120. $table_alias = $table;
  121. $this->initAlias($aliases, $db_alias, $table_alias);
  122. $result = $dbi->query($sqlQuery, DatabaseInterface::CONNECT_USER, DatabaseInterface::QUERY_UNBUFFERED);
  123. $columns_cnt = $result->numFields();
  124. $fieldsMeta = $dbi->getFieldsMeta($result);
  125. $columns = [];
  126. foreach ($fieldsMeta as $i => $field) {
  127. $col_as = $field->name;
  128. if (! empty($aliases[$db]['tables'][$table]['columns'][$col_as])) {
  129. $col_as = $aliases[$db]['tables'][$table]['columns'][$col_as];
  130. }
  131. $columns[$i] = stripslashes($col_as);
  132. }
  133. $record_cnt = 0;
  134. while ($record = $result->fetchRow()) {
  135. $record_cnt++;
  136. // Output table name as comment if this is the first record of the table
  137. if ($record_cnt == 1) {
  138. $buffer = '# ' . $db_alias . '.' . $table_alias . $crlf;
  139. $buffer .= '-' . $crlf;
  140. } else {
  141. $buffer = '-' . $crlf;
  142. }
  143. for ($i = 0; $i < $columns_cnt; $i++) {
  144. if (! array_key_exists($i, $record)) {
  145. continue;
  146. }
  147. if ($record[$i] === null) {
  148. $buffer .= ' ' . $columns[$i] . ': null' . $crlf;
  149. continue;
  150. }
  151. $isNotString = isset($fieldsMeta[$i]) && $fieldsMeta[$i]->isNotType(FieldMetadata::TYPE_STRING);
  152. if (is_numeric($record[$i]) && $isNotString) {
  153. $buffer .= ' ' . $columns[$i] . ': ' . $record[$i] . $crlf;
  154. continue;
  155. }
  156. $record[$i] = str_replace(
  157. [
  158. '\\',
  159. '"',
  160. "\n",
  161. "\r",
  162. ],
  163. [
  164. '\\\\',
  165. '\"',
  166. '\n',
  167. '\r',
  168. ],
  169. $record[$i]
  170. );
  171. $buffer .= ' ' . $columns[$i] . ': "' . $record[$i] . '"' . $crlf;
  172. }
  173. if (! $this->export->outputHandler($buffer)) {
  174. return false;
  175. }
  176. }
  177. return true;
  178. }
  179. /**
  180. * Outputs result raw query in YAML format
  181. *
  182. * @param string $errorUrl the url to go back in case of error
  183. * @param string|null $db the database where the query is executed
  184. * @param string $sqlQuery the rawquery to output
  185. * @param string $crlf the end of line sequence
  186. */
  187. public function exportRawQuery(string $errorUrl, ?string $db, string $sqlQuery, string $crlf): bool
  188. {
  189. global $dbi;
  190. if ($db !== null) {
  191. $dbi->selectDb($db);
  192. }
  193. return $this->exportData($db ?? '', '', $crlf, $errorUrl, $sqlQuery);
  194. }
  195. }