PostfixAdmin - web based virtual user administration interface for Postfix mail servers https://postfixadmin.github.io/postfixadmin/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

369 lines
12 KiB

  1. <?php
  2. /**
  3. * Base class for Shells
  4. *
  5. * Long description for file
  6. *
  7. * PHP versions 4 and 5
  8. *
  9. * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
  10. * Copyright 2005-2008, Cake Software Foundation, Inc.
  11. * 1785 E. Sahara Avenue, Suite 490-204
  12. * Las Vegas, Nevada 89104
  13. * Modified for Postfixadmin by Valkum
  14. *
  15. * Copyright 2010
  16. *
  17. * Licensed under The MIT License
  18. * Redistributions of files must retain the above copyright notice.
  19. *
  20. * @filesource
  21. * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
  22. * @link http://postfixadmin.sourceforge.net/ Postfixadmin on Sourceforge
  23. * @package postfixadmin
  24. * @subpackage -
  25. * @since -
  26. * @version $Revision$
  27. * @modifiedby $LastChangedBy$
  28. * @lastmodified $Date$
  29. * @license http://www.opensource.org/licenses/mit-license.php The MIT License
  30. */
  31. class Shell {
  32. /**
  33. * An instance of the ShellDispatcher object that loaded this script
  34. *
  35. * @var object
  36. * @access public
  37. */
  38. var $Dispatch = null;
  39. /**
  40. * If true, the script will ask for permission to perform actions.
  41. *
  42. * @var boolean
  43. * @access public
  44. */
  45. var $interactive = true;
  46. /**
  47. * Holds the DATABASE_CONFIG object for the app. Null if database.php could not be found,
  48. * or the app does not exist.
  49. *
  50. * @var object
  51. * @access public
  52. */
  53. var $DbConfig = null;
  54. /**
  55. * Contains command switches parsed from the command line.
  56. *
  57. * @var array
  58. * @access public
  59. */
  60. var $params = array();
  61. /**
  62. * Contains arguments parsed from the command line.
  63. *
  64. * @var array
  65. * @access public
  66. */
  67. var $args = array();
  68. /**
  69. * The file name of the shell that was invoked.
  70. *
  71. * @var string
  72. * @access public
  73. */
  74. var $shell = null;
  75. /**
  76. * The class name of the shell that was invoked.
  77. *
  78. * @var string
  79. * @access public
  80. */
  81. var $className = null;
  82. /**
  83. * The command called if public methods are available.
  84. *
  85. * @var string
  86. * @access public
  87. */
  88. var $command = null;
  89. /**
  90. * The name of the shell in camelized.
  91. *
  92. * @var string
  93. * @access public
  94. */
  95. var $name = null;
  96. /**
  97. * Contains tasks to load and instantiate
  98. *
  99. * @var array
  100. * @access public
  101. */
  102. var $tasks = array();
  103. /**
  104. * Contains the loaded tasks
  105. *
  106. * @var array
  107. * @access public
  108. */
  109. var $taskNames = array();
  110. /**
  111. * Contains models to load and instantiate
  112. *
  113. * @var array
  114. * @access public
  115. */
  116. var $uses = array();
  117. /**
  118. * Constructs this Shell instance.
  119. *
  120. */
  121. function __construct(&$dispatch) {
  122. $vars = array('params', 'args', 'shell', 'shellCommand'=> 'command');
  123. foreach ($vars as $key => $var) {
  124. if (is_string($key)) {
  125. $this->{$var} =& $dispatch->{$key};
  126. } else {
  127. $this->{$var} =& $dispatch->{$var};
  128. }
  129. }
  130. $this->className = get_class($this);
  131. if ($this->name == null) {
  132. $this->name = str_replace(array('shell', 'Shell', 'task', 'Task'), '', $this->className);
  133. }
  134. $shellKey = Inflector::underscore($this->className);
  135. # if (!PHP5 && isset($this->args[0])) {
  136. # if(strpos($this->className, strtolower(Inflector::camelize($this->args[0]))) !== false) {
  137. # $dispatch->shiftArgs();
  138. # }
  139. # if (strtolower($this->command) == strtolower(Inflector::variable($this->args[0])) && method_exists($this, $this->command)) {
  140. # $dispatch->shiftArgs();
  141. # }
  142. # }
  143. $this->Dispatch =& $dispatch;
  144. }
  145. /**
  146. * Initializes the Shell
  147. * acts as constructor for subclasses
  148. * allows configuration of tasks prior to shell execution
  149. *
  150. * @access public
  151. */
  152. function initialize() {
  153. }
  154. /**
  155. * Starts up the the Shell
  156. * allows for checking and configuring prior to command or main execution
  157. * can be overriden in subclasses
  158. *
  159. * @access public
  160. */
  161. function startup() {
  162. #CHECK!
  163. if ( empty($this->params['q'] ) ) {
  164. $this->_welcome();
  165. }
  166. $CONF = Config::read('all');
  167. }
  168. /**
  169. * Displays a header for the shell
  170. *
  171. * @access protected
  172. */
  173. function _welcome() {
  174. $this->out("\nWelcome to Postfixadmin-CLI v" . $this->Dispatch->version);
  175. $this->out("---------------------------------------------------------------");
  176. $this->out('Path: '. PATH);
  177. $this->hr();
  178. }
  179. /**
  180. * Loads tasks defined in var $tasks
  181. *
  182. * @return bool
  183. * @access public
  184. */
  185. function loadTasks() {
  186. if ($this->tasks === null || $this->tasks === false) {
  187. return;
  188. }
  189. if ($this->tasks !== true && !empty($this->tasks)) {
  190. $tasks = $this->tasks;
  191. if (!is_array($tasks)) {
  192. $tasks = array($tasks);
  193. }
  194. foreach ($tasks as $taskName) {
  195. $task = Inflector::underscore($taskName);
  196. $taskClass = Inflector::camelize($taskName.'Task');
  197. $taskKey = Inflector::underscore($taskClass);
  198. if ($taskName == 'Add' || $taskName == 'Update') {
  199. $taskClass = 'CliEdit';
  200. }
  201. # elseif (!class_exists($taskClass)) {
  202. # foreach ($this->Dispatch->shellPaths as $path) {
  203. # $taskPath = $path . 'tasks' . DS . $task.'.php';
  204. # if (file_exists($taskPath)) {
  205. # require_once $taskPath;
  206. # break;
  207. # }
  208. # }
  209. # }
  210. $this->taskNames[] = $taskName;
  211. # if (!PHP5) {
  212. # $this->{$taskName} = new $taskClass($this->Dispatch);
  213. # } else {
  214. $this->{$taskName} = new $taskClass($this->Dispatch);
  215. # }
  216. if ($taskName == 'Add') {
  217. $this->{$taskName}->handler_to_use = ucfirst($this->shell) . 'Handler';
  218. $this->{$taskName}->new = 1;
  219. } elseif ($taskName == 'Update') {
  220. $this->{$taskName}->handler_to_use = ucfirst($this->shell) . 'Handler';
  221. $this->{$taskName}->new = 0;
  222. }
  223. if (!isset($this->{$taskName})) {
  224. $this->err("Task '".$taskName."' could not be loaded");
  225. $this->_stop();
  226. }
  227. }
  228. }
  229. return false;
  230. }
  231. /**
  232. * Prompts the user for input, and returns it.
  233. *
  234. * @param string $prompt Prompt text.
  235. * @param mixed $options Array or string of options.
  236. * @param string $default Default input value.
  237. * @return Either the default value, or the user-provided input.
  238. * @access public
  239. */
  240. function in($prompt, $options = null, $default = null) {
  241. if (!$this->interactive) {
  242. return $default;
  243. }
  244. if ($prompt != '') $this->out("");
  245. $in = $this->Dispatch->getInput($prompt, $options, $default);
  246. if ($options && is_string($options)) {
  247. if (strpos($options, ',')) {
  248. $options = explode(',', $options);
  249. } elseif (strpos($options, '/')) {
  250. $options = explode('/', $options);
  251. } else {
  252. $options = array($options);
  253. }
  254. }
  255. if (is_array($options)) {
  256. while ($in == '' || ($in && (!in_array(strtolower($in), $options) && !in_array(strtoupper($in), $options)) && !in_array($in, $options))) {
  257. $this->err("Invalid input"); # TODO: make translateable
  258. $in = $this->Dispatch->getInput($prompt, $options, $default);
  259. }
  260. }
  261. return $in;
  262. }
  263. /**
  264. * Outputs to the stdout filehandle.
  265. *
  266. * @param string $string String to output.
  267. * @param boolean $newline If true, the outputs gets an added newline.
  268. * @access public
  269. */
  270. function out($string, $newline = true) {
  271. if (is_array($string)) {
  272. $str = '';
  273. foreach($string as $message) {
  274. $str .= $message ."\n";
  275. }
  276. $string = $str;
  277. }
  278. return $this->Dispatch->stdout($string, $newline);
  279. }
  280. /**
  281. * Outputs to the stderr filehandle.
  282. *
  283. * @param string $string Error text to output.
  284. * @access public
  285. */
  286. function err($string) {
  287. if (is_array($string)) {
  288. $str = '';
  289. foreach($string as $message) {
  290. $str .= $message ."\n";
  291. }
  292. $string = $str;
  293. }
  294. return $this->Dispatch->stderr($string."\n");
  295. }
  296. /**
  297. * Outputs a series of minus characters to the standard output, acts as a visual separator.
  298. *
  299. * @param boolean $newline If true, the outputs gets an added newline.
  300. * @access public
  301. */
  302. function hr($newline = false) {
  303. if ($newline) {
  304. $this->out("\n");
  305. }
  306. $this->out('---------------------------------------------------------------');
  307. if ($newline) {
  308. $this->out("\n");
  309. }
  310. }
  311. /**
  312. * Displays a formatted error message and exits the application
  313. *
  314. * @param string $title Title of the error message
  315. * @param string $msg Error message
  316. * @access public
  317. */
  318. function error($title, $msg) {
  319. $out = "$title\n";
  320. $out .= "$msg\n";
  321. $out .= "\n";
  322. $this->err($out);
  323. $this->_stop(1);
  324. }
  325. /**
  326. * Outputs usage text on the standard output. Implement it in subclasses.
  327. *
  328. * @access public
  329. */
  330. function help() {
  331. if ($this->command != null) {
  332. $this->err("Unknown {$this->name} command '$this->command'.\nFor usage, try 'postfixadmin-cli {$this->shell} help'.\n\n");
  333. } else {
  334. $this->Dispatch->help();
  335. }
  336. }
  337. /**
  338. * Stop execution of the current script
  339. *
  340. * @param $status see http://php.net/exit for values
  341. * @return void
  342. * @access public
  343. */
  344. function _stop($status = 0) {
  345. exit($status);
  346. }
  347. }