clilib.php 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. <?php
  2. exit;
  3. /**
  4. * Opens and parses/checks a VChamilo instance definition file
  5. * @param string $nodelistlocation
  6. * @param string $plugin
  7. * @return mixed
  8. */
  9. function vchamilo_parse_csv_nodelist($nodelistlocation = '', $plugin = null) {
  10. global $_configuration;
  11. $vnodes = array();
  12. if (empty($nodelistlocation)) {
  13. $nodelistlocation = $_configuration['root_sys'].'/plugin/vchamilo/nodelist.csv';
  14. }
  15. // decode file
  16. $csv_delimiter = "\;";
  17. $csv_delimiter2 = ";";
  18. // make arrays of valid fields for error checking
  19. $required = array(
  20. 'root_web' => 1,
  21. 'sitename' => 1,
  22. 'institution' => 1,
  23. 'main_database' => 1,
  24. 'statistics_database' => 1,
  25. 'user_personal_database' => 1,
  26. 'db_user' => 1,
  27. 'db_password' => 1,
  28. 'course_folder' => 1,
  29. );
  30. $optional = array(
  31. 'db_host' => 1,
  32. 'template' => 1,
  33. 'table_prefix' => 1,
  34. 'single_database' => 1,
  35. 'tracking_enabled' => 1,
  36. 'visible' => 1,
  37. );
  38. $optionalDefaults = array(
  39. 'db_host' => $_configuration['db_host'],
  40. 'db_prefix' => 'chm_',
  41. 'table_prefix' => '',
  42. 'tracking_enabled' => 0,
  43. 'single_database' => 1,
  44. 'template' => '',
  45. 'visible' => 1
  46. );
  47. $patterns = array();
  48. // Metas are accepted patterns (optional)
  49. $metas = array(
  50. 'plugin_.*',
  51. 'config_.*'
  52. );
  53. // Get header (field names)
  54. $textlib = new textlib();
  55. if (!$fp = fopen($nodelistlocation, 'rb')) {
  56. cli_error($plugin->get_lang('badnodefile', 'vchamilo', $nodelistlocation));
  57. }
  58. // Jump any empty or comment line
  59. $text = fgets($fp, 1024);
  60. $i = 0;
  61. while (vchamilo_is_empty_line_or_format($text, $i == 0)) {
  62. $text = fgets($fp, 1024);
  63. $i++;
  64. }
  65. $headers = explode($csv_delimiter2, $text);
  66. // Check for valid field names
  67. foreach ($headers as $h) {
  68. $header[] = trim($h);
  69. $patternized = implode('|', $patterns)."\\d+";
  70. $metapattern = implode('|', $metas);
  71. if (!(isset($required[$h]) ||
  72. isset($optionalDefaults[$h]) ||
  73. isset($optional[$h]) ||
  74. preg_match("/$patternized/", $h) ||
  75. preg_match("/$metapattern/", $h))) {
  76. cli_error("Node parse : invalidfieldname $h ");
  77. return;
  78. }
  79. if (isset($required[trim($h)])) {
  80. $required[trim($h)] = 0;
  81. }
  82. }
  83. $expectedcols = count($headers);
  84. $i++;
  85. // Check for required fields.
  86. foreach ($required as $key => $value) {
  87. if ($value) { // Required field missing.
  88. cli_error("fieldrequired $key");
  89. return;
  90. }
  91. }
  92. $linenum = 2; // Since header is line 1.
  93. // Take some from admin profile, other fixed by hardcoded defaults.
  94. while (!feof($fp)) {
  95. // Make a new base record.
  96. $vnode = new StdClass();
  97. foreach ($optionalDefaults as $key => $value) {
  98. $vnode->$key = $value;
  99. }
  100. //Note: commas within a field should be encoded as &#44 (for comma separated csv files)
  101. //Note: semicolon within a field should be encoded as &#59 (for semicolon separated csv files)
  102. $text = fgets($fp, 1024);
  103. if (vchamilo_is_empty_line_or_format($text, false)) {
  104. $i++;
  105. continue;
  106. }
  107. $valueset = explode($csv_delimiter2, $text);
  108. if (count($valueset) != $expectedcols) {
  109. cli_error('wrong line count at line '.$i);
  110. }
  111. $f = 0;
  112. foreach ($valueset as $value) {
  113. // Decode encoded commas.
  114. $key = $headers[$f];
  115. if (preg_match('/\|/', $key)) {
  116. list($plugin, $variable) = explode('|', str_replace('plugin_', '', $key));
  117. if (empty($variable)) die("Key error in CSV : $key ");
  118. if (!isset($vnode->$plugin)) {
  119. $vnode->$plugin = new StdClass();
  120. }
  121. $vnode->$plugin->$variable = trim($value);
  122. } else {
  123. if (preg_match('/^config_/', $key)) {
  124. $smartkey = str_replace('config_', '', $key);
  125. $keyparts = implode('|', $smartkey);
  126. $keyvar = $keyparts[0];
  127. $subkey = @$keyparts[1];
  128. $vnode->config->$smartkey = new StdClass;
  129. $vnode->config->$smartkey->subkey = $subkey;
  130. $vnode->config->$smartkey->value = trim($value);
  131. } else {
  132. $vnode->$key = trim($value);
  133. }
  134. }
  135. $f++;
  136. }
  137. $vnodes[] = $vnode;
  138. }
  139. return $vnodes;
  140. }
  141. /**
  142. * Check a CSV input line format for empty or commented lines
  143. * Ensures compatbility to UTF-8 BOM or unBOM formats
  144. * @param resource $text
  145. * @param bool $resetfirst
  146. * @return bool
  147. */
  148. function vchamilo_is_empty_line_or_format(&$text, $resetfirst = false) {
  149. global $CFG;
  150. static $textlib;
  151. static $first = true;
  152. // We may have a risk the BOM is present on first line
  153. if ($resetfirst) $first = true;
  154. if (!isset($textlib)) $textlib = new textlib(); // Singleton
  155. $text = $textlib->trim_utf8_bom($text);
  156. $first = false;
  157. $text = preg_replace("/\n?\r?/", '', $text);
  158. // last chance
  159. if ('ASCII' == mb_detect_encoding($text)) {
  160. $text = utf8_encode($text);
  161. }
  162. // Check the text is empty or comment line and answer true if it is.
  163. return preg_match('/^$/', $text) || preg_match('/^(\(|\[|-|#|\/| )/', $text);
  164. }
  165. /**
  166. * Get input from user
  167. * @param string $prompt text prompt, should include possible options
  168. * @param string $default default value when enter pressed
  169. * @param array $options list of allowed options, empty means any text
  170. * @param bool $casesensitiveoptions true if options are case sensitive
  171. * @return string entered text
  172. */
  173. function cli_input($prompt, $default = '', array $options = null, $casesensitiveoptions = false) {
  174. echo $prompt;
  175. echo "\n: ";
  176. $input = fread(STDIN, 2048);
  177. $input = trim($input);
  178. if ($input === '') {
  179. $input = $default;
  180. }
  181. if ($options) {
  182. if (!$casesensitiveoptions) {
  183. $input = strtolower($input);
  184. }
  185. if (!in_array($input, $options)) {
  186. echo "Incorrect value, please retry.\n"; // TODO: localize, mark as needed in install
  187. return cli_input($prompt, $default, $options, $casesensitiveoptions);
  188. }
  189. }
  190. return $input;
  191. }
  192. /**
  193. * Returns cli script parameters.
  194. * @param array $longoptions array of --style options ex:('verbose'=>false)
  195. * @param array $shortmapping array describing mapping of short to long style options ex:('h'=>'help', 'v'=>'verbose')
  196. * @return array array of arrays, options, unrecognised as optionlongname=>value
  197. */
  198. function cli_get_params(array $longoptions, array $shortmapping = null) {
  199. $shortmapping = (array) $shortmapping;
  200. $options = array();
  201. $unrecognized = array();
  202. if (empty($_SERVER['argv'])) {
  203. // Bad luck, we can continue in interactive mode ;-)
  204. return array($options, $unrecognized);
  205. }
  206. $rawoptions = $_SERVER['argv'];
  207. // Remove anything after '--', options can not be there.
  208. if (($key = array_search('--', $rawoptions)) !== false) {
  209. $rawoptions = array_slice($rawoptions, 0, $key);
  210. }
  211. // Remove script.
  212. unset($rawoptions[0]);
  213. foreach ($rawoptions as $raw) {
  214. if (substr($raw, 0, 2) === '--') {
  215. $value = substr($raw, 2);
  216. $parts = explode('=', $value);
  217. if (count($parts) == 1) {
  218. $key = reset($parts);
  219. $value = true;
  220. } else {
  221. $key = array_shift($parts);
  222. $value = implode('=', $parts);
  223. }
  224. if (array_key_exists($key, $longoptions)) {
  225. $options[$key] = $value;
  226. } else {
  227. $unrecognized[] = $raw;
  228. }
  229. } else if (substr($raw, 0, 1) === '-') {
  230. $value = substr($raw, 1);
  231. $parts = explode('=', $value);
  232. if (count($parts) == 1) {
  233. $key = reset($parts);
  234. $value = true;
  235. } else {
  236. $key = array_shift($parts);
  237. $value = implode('=', $parts);
  238. }
  239. if (array_key_exists($key, $shortmapping)) {
  240. $options[$shortmapping[$key]] = $value;
  241. } else {
  242. $unrecognized[] = $raw;
  243. }
  244. } else {
  245. $unrecognized[] = $raw;
  246. continue;
  247. }
  248. }
  249. // Apply defaults.
  250. foreach ($longoptions as $key=>$default) {
  251. if (!array_key_exists($key, $options)) {
  252. $options[$key] = $default;
  253. }
  254. }
  255. // Finished.
  256. return array($options, $unrecognized);
  257. }
  258. /**
  259. * Print or return section separator string
  260. * @param bool $return false means print, true return as string
  261. * @return mixed void or string
  262. */
  263. function cli_separator($return = false) {
  264. $separator = str_repeat('-', 79)."\n";
  265. if ($return) {
  266. return $separator;
  267. } else {
  268. echo $separator;
  269. }
  270. }
  271. /**
  272. * Print or return section heading string
  273. * @param string $string text
  274. * @param bool $return false means print, true return as string
  275. * @return mixed void or string
  276. */
  277. function cli_heading($string, $return = false) {
  278. $string = "== $string ==\n";
  279. if ($return) {
  280. return $string;
  281. } else {
  282. echo $string;
  283. }
  284. }
  285. /**
  286. * Write error notification
  287. * @param $text
  288. * @return void
  289. */
  290. function cli_problem($text) {
  291. fwrite(STDERR, $text."\n");
  292. }
  293. /**
  294. * Write to standard out and error with exit in error.
  295. *
  296. * @param string $text
  297. * @param int $errorCode
  298. * @return void (does not return)
  299. */
  300. function cli_error($text, $errorCode = 1) {
  301. fwrite(STDERR, $text);
  302. fwrite(STDERR, "\n");
  303. die($errorCode);
  304. }