1: <?php
  2:   3:   4:   5:   6:   7:   8:   9:  10:  11:  12:  13:  14:  15:  16: 
 17: 
 18: App::uses('AppShell', 'Console/Command');
 19: 
 20:  21:  22:  23:  24: 
 25: class ServerShell extends AppShell {
 26: 
 27:  28:  29:  30:  31: 
 32:     const DEFAULT_HOST = 'localhost';
 33: 
 34:  35:  36:  37:  38: 
 39:     const DEFAULT_PORT = 80;
 40: 
 41:  42:  43:  44:  45: 
 46:     protected $_host = null;
 47: 
 48:  49:  50:  51:  52: 
 53:     protected $_port = null;
 54: 
 55:  56:  57:  58:  59: 
 60:     protected $_documentRoot = null;
 61: 
 62:  63:  64:  65:  66: 
 67:     public function initialize() {
 68:         $this->_host = static::DEFAULT_HOST;
 69:         $this->_port = static::DEFAULT_PORT;
 70:         $this->_documentRoot = WWW_ROOT;
 71:     }
 72: 
 73:  74:  75:  76:  77:  78:  79:  80:  81:  82: 
 83:     public function startup() {
 84:         if (!empty($this->params['host'])) {
 85:             $this->_host = $this->params['host'];
 86:         }
 87:         if (!empty($this->params['port'])) {
 88:             $this->_port = $this->params['port'];
 89:         }
 90:         if (!empty($this->params['document_root'])) {
 91:             $this->_documentRoot = $this->params['document_root'];
 92:         }
 93: 
 94:         
 95:         if (substr($this->_documentRoot, -1, 1) === DIRECTORY_SEPARATOR) {
 96:             $this->_documentRoot = substr($this->_documentRoot, 0, strlen($this->_documentRoot) - 1);
 97:         }
 98:         if (preg_match("/^([a-z]:)[\\\]+(.+)$/i", $this->_documentRoot, $m)) {
 99:             $this->_documentRoot = $m[1] . '\\' . $m[2];
100:         }
101: 
102:         parent::startup();
103:     }
104: 
105: 106: 107: 108: 109: 
110:     protected function _welcome() {
111:         $this->out();
112:         $this->out(__d('cake_console', '<info>Welcome to CakePHP %s Console</info>', 'v' . Configure::version()));
113:         $this->hr();
114:         $this->out(__d('cake_console', 'App : %s', APP_DIR));
115:         $this->out(__d('cake_console', 'Path: %s', APP));
116:         $this->out(__d('cake_console', 'DocumentRoot: %s', $this->_documentRoot));
117:         $this->hr();
118:     }
119: 
120: 121: 122: 123: 124: 
125:     public function main() {
126:         if (version_compare(PHP_VERSION, '5.4.0') < 0) {
127:             $this->out(__d('cake_console', '<warning>This command is available on %s or above</warning>', 'PHP5.4'));
128:             return;
129:         }
130: 
131:         $command = sprintf("php -S %s:%d -t %s %s",
132:             $this->_host,
133:             $this->_port,
134:             escapeshellarg($this->_documentRoot),
135:             escapeshellarg($this->_documentRoot . '/index.php')
136:         );
137: 
138:         $port = ($this->_port == static::DEFAULT_PORT) ? '' : ':' . $this->_port;
139:         $this->out(__d('cake_console', 'built-in server is running in http://%s%s/', $this->_host, $port));
140:         system($command);
141:     }
142: 
143: 144: 145: 146: 147: 
148:     public function getOptionParser() {
149:         $parser = parent::getOptionParser();
150: 
151:         $parser->description(array(
152:             __d('cake_console', 'PHP Built-in Server for CakePHP'),
153:             __d('cake_console', '<warning>[WARN] Don\'t use this at the production environment</warning>')
154:         ))->addOption('host', array(
155:             'short' => 'H',
156:             'help' => __d('cake_console', 'ServerHost')
157:         ))->addOption('port', array(
158:             'short' => 'p',
159:             'help' => __d('cake_console', 'ListenPort')
160:         ))->addOption('document_root', array(
161:             'short' => 'd',
162:             'help' => __d('cake_console', 'DocumentRoot')
163:         ));
164: 
165:         return $parser;
166:     }
167: }
168: