File indexing completed on 2025-02-02 05:48:37
0001 <?php 0002 /** 0003 * @author Krzysztof Suszyński <k.suszynski@mediovski.pl> 0004 * @version 0.2 0005 * @package php.manager.crontab 0006 * 0007 * Copyright (c) 2012 Krzysztof Suszyński <k.suszynski@mediovski.pl> 0008 * 0009 * Permission is hereby granted, free of charge, to any person obtaining a copy 0010 * of this software and associated documentation files (the "Software"), to deal 0011 * in the Software without restriction, including without limitation the rights 0012 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 0013 * copies of the Software, and to permit persons to whom the Software is 0014 * furnished to do so, subject to the following conditions: 0015 * 0016 * The above copyright notice and this permission notice shall be included in 0017 * all copies or substantial portions of the Software. 0018 * 0019 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 0020 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 0021 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 0022 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 0023 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 0024 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 0025 * THE SOFTWARE. 0026 * 0027 */ 0028 0029 //namespace Crontab\Manager; 0030 0031 /** 0032 * 0033 */ 0034 class Crontab_Manager_CliTool 0035 { 0036 /** 0037 * @var bool 0038 */ 0039 protected $_verbose = false; 0040 /** 0041 * @var string|null 0042 */ 0043 protected $_sudo = null; 0044 /** 0045 * @var string 0046 */ 0047 protected $_targetFile; 0048 /** 0049 * @var array 0050 */ 0051 private $_opts; 0052 /** 0053 * @var string|null 0054 */ 0055 private $_methodName = null; 0056 0057 /** 0058 * Constructor 0059 */ 0060 public function __construct() 0061 { 0062 $this->_progName = $_SERVER['argv'][0]; 0063 } 0064 0065 /** 0066 * Runs tool from CLI 0067 * 0068 * @return integer 0069 * @static 0070 */ 0071 public static function run() 0072 { 0073 $cli = self::_instantinate(); 0074 try { 0075 $cli->_parseOpts(); 0076 $method = $cli->_dispach(); 0077 $out = $method->invoke($cli); 0078 if ($out) { 0079 $cli->_out($out); 0080 } 0081 } catch (\UnexpectedValueException $optExc) { 0082 $cli->_err("Invalid option: " . $optExc->getMessage() . "\n"); 0083 $cli->_err($cli->usage()); 0084 return 1; 0085 } catch (\Exception $exc) { 0086 if ($cli->_verbose) { 0087 $cli->_err($exc . "\n"); 0088 } else { 0089 $cli->_err("Error: " . $exc->getMessage() . "\n"); 0090 } 0091 return 2; 0092 } 0093 return 0; 0094 } 0095 0096 /** 0097 * CliTool factory method 0098 * 0099 * @return CliTool 0100 */ 0101 protected static function _instantinate() 0102 { 0103 return new self(); 0104 } 0105 0106 /** 0107 * Enable CRON file action 0108 */ 0109 public function enable() 0110 { 0111 $this->_loadClasses(); 0112 $manager = $this->_createManager(); 0113 if ($this->_sudo) { 0114 $manager->user = $this->_sudo; 0115 $this->_out(sprintf('Using "%s" user\'s crontab with `sudo\' command', $this->_sudo)); 0116 } 0117 $manager->enableOrUpdate($this->_targetFile); 0118 $manager->save(); 0119 0120 $this->_out(sprintf('File "%s" merged into crontab', $this->_targetFile)); 0121 } 0122 0123 /** 0124 * Loads classes if they are not present 0125 * 0126 */ 0127 private function _loadClasses() 0128 { 0129 if (!class_exists('php\manager\crontab\CrontabManager')) { 0130 require_once __DIR__ . '/CrontabManager.php'; 0131 } 0132 if (!class_exists('php\manager\crontab\CronEntry')) { 0133 require_once __DIR__ . '/CronEntry.php'; 0134 } 0135 } 0136 0137 /** 0138 * Crontab_Manager_CrontabManager factory method 0139 * 0140 * @return Crontab_Manager_CrontabManager 0141 */ 0142 protected function _createManager() 0143 { 0144 return new Crontab_Manager_CrontabManager(); 0145 } 0146 0147 /** 0148 * Echoes to PHP STDOUT 0149 * 0150 * @param string $message 0151 */ 0152 protected function _out($message) 0153 { 0154 fprintf(STDOUT, $message . "\n"); 0155 } 0156 0157 /** 0158 * Enable CRON file action 0159 */ 0160 public function disable() 0161 { 0162 $this->_loadClasses(); 0163 $manager = $this->_createManager(); 0164 if ($this->_sudo) { 0165 $manager->user = $this->_sudo; 0166 $this->_out(sprintf('Using "%s" crontab with `sudo\' command', $this->_sudo)); 0167 } 0168 $manager->disable($this->_targetFile); 0169 $manager->save(); 0170 0171 $this->_out(sprintf('File "%s" removed from crontab', $this->_targetFile)); 0172 } 0173 0174 /** 0175 * Usage for cli 0176 * 0177 * @return string 0178 */ 0179 public function usage() 0180 { 0181 $usage = "Usage: cronman <--enable|-e FILE,--disable|-d FILE> [--user|-u USER] [--verbose|-v] [--help|-h] [--usage]"; 0182 $usage .= "\n\n"; 0183 $usage .= "Required params:\n"; 0184 $usage .= " --enable|-e FILE Enable target FILE to crontab, replace it if already set\n"; 0185 $usage .= " --disable|-d FILE Disable target FILE from crontab\n"; 0186 $usage .= "\n"; 0187 $usage .= "Optional params:\n"; 0188 $usage .= " --user|-u USER For which user to run this program\n"; 0189 $usage .= " --verbose|-v Display more massages\n"; 0190 $usage .= " --help|-h,--usage Displays this help\n"; 0191 0192 return $usage; 0193 } 0194 0195 /** 0196 * Echoes to PHP STDERR 0197 * 0198 * @param string $message 0199 */ 0200 protected function _err($message) 0201 { 0202 fprintf(STDERR, $message . "\n"); 0203 } 0204 0205 /** 0206 * Dispaches to an CLI action 0207 * 0208 * @return \ReflectionMethod 0209 */ 0210 private function _dispach() 0211 { 0212 $cls = new \ReflectionClass($this); 0213 $method = $cls->getMethod($this->_methodName); 0214 return $method; 0215 } 0216 0217 /** 0218 * Parse cli opt params 0219 * 0220 * @return CliTool 0221 * @throws \UnexpectedValueException 0222 */ 0223 private function _parseOpts() 0224 { 0225 $longOpts = array( 0226 'enable:', 0227 'disable:', 0228 'user:', 0229 'help', 0230 'usage', 0231 'verbose' 0232 ); 0233 $opts = getopt('e:d:hvu:', $longOpts); 0234 $this->_opts = $opts; 0235 $this->_verbose = $this->_isSet('verbose', 'v'); 0236 if ($this->_isSet('usage') || $this->_isSet('help', 'h')) { 0237 $this->_methodName = 'usage'; 0238 return $this; 0239 } 0240 if ($this->_isSet('user', 'u')) { 0241 $this->_sudo = $this->_getOpt('user', 'u'); 0242 } 0243 if ( 0244 ($this->_isSet('enable', 'e') && $this->_isSet('disable', 'd')) || 0245 ($this->_isNotSet('enable', 'e') && $this->_isNotSet('disable', 'd')) 0246 ) { 0247 throw new \UnexpectedValueException( 0248 '--enable|-e or --disable|-d opt is required, but only one of them' 0249 ); 0250 } 0251 if ($this->_isSet('enable', 'e')) { 0252 $this->_methodName = 'enable'; 0253 $this->_targetFile = $this->_getOpt('enable', 'e'); 0254 return $this; 0255 } 0256 if ($this->_isSet('disable', 'd')) { 0257 $this->_methodName = 'disable'; 0258 $this->_targetFile = $this->_getOpt('disable', 'd'); 0259 return $this; 0260 } 0261 0262 return $this; 0263 } 0264 0265 /** 0266 * Checks if opt is set 0267 * 0268 * @param string $name 0269 * @param string|null $alias 0270 * @return bool 0271 */ 0272 protected function _isSet($name, $alias = null) 0273 { 0274 return isset($this->_opts[$name]) || 0275 ($alias && isset($this->_opts[$alias])); 0276 } 0277 0278 /** 0279 * Gets opt if is set 0280 * 0281 * @param string $name 0282 * @param string|null $alias 0283 * @param mixed|null $default 0284 * @return bool 0285 */ 0286 protected function _getOpt($name, $alias = null, $default = null) 0287 { 0288 if ($this->_isSet($name, $alias)) { 0289 if ($this->_isSet($name)) { 0290 return $this->_opts[$name]; 0291 } else { 0292 return $this->_opts[$alias]; 0293 } 0294 } 0295 return $default; 0296 } 0297 0298 /** 0299 * Checks if opt is not set 0300 * 0301 * @param string $name 0302 * @param string|null $alias 0303 * @return bool 0304 */ 0305 protected function _isNotSet($name, $alias = null) 0306 { 0307 return !isset($this->_opts[$name]) && 0308 !($alias && isset($this->_opts[$alias])); 0309 } 0310 0311 } 0312 0313 if (PHP_SAPI == 'cli' && isset($_SERVER['argv']) 0314 && realpath($_SERVER['argv'][0]) == __FILE__ 0315 ) { 0316 exit(CliTool::run()); 0317 }