clilib.php 9.7 KB

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