├── .gitignore ├── .editorconfig ├── src └── JenkinsApi │ ├── Exceptions │ ├── JenkinsApiException.php │ ├── JobNotFoundException.php │ ├── NodeNotFoundException.php │ └── BuildNotFoundException.php │ ├── Item │ ├── JobList.php │ ├── LastBuild.php │ ├── Queue.php │ ├── JobQueue.php │ ├── View.php │ ├── Executor.php │ ├── Node.php │ ├── Job.php │ └── Build.php │ ├── AbstractItem.php │ └── Jenkins.php ├── composer.json └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | vendor/ 2 | composer.phar 3 | composer.lock 4 | composer.local.json 5 | composer.local.lock 6 | .idea 7 | tests/ 8 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | charset = utf-8 6 | trim_trailing_whitespace = true 7 | insert_final_newline = true 8 | 9 | [*.php] 10 | indent_style = space 11 | indent_size = 4 12 | -------------------------------------------------------------------------------- /src/JenkinsApi/Exceptions/JenkinsApiException.php: -------------------------------------------------------------------------------- 1 | 7 | * @copyright 2013 Jungheinrich AG 8 | * @license Proprietary license 9 | * @version $Id$ 10 | */ 11 | 12 | namespace JenkinsApi\Item; 13 | 14 | 15 | class JobList { 16 | 17 | } -------------------------------------------------------------------------------- /src/JenkinsApi/Exceptions/JobNotFoundException.php: -------------------------------------------------------------------------------- 1 | =5.5.0" 19 | }, 20 | "autoload": { 21 | "psr-0": { 22 | "JenkinsApi": "src/" 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/JenkinsApi/Item/LastBuild.php: -------------------------------------------------------------------------------- 1 | 12 | * @version $Id$ 13 | * 14 | * @method int getNumber() 15 | * @method string getBuiltOn() 16 | */ 17 | class LastBuild extends Build 18 | { 19 | /** 20 | * @param string $jobName 21 | * @param Jenkins $jenkins 22 | */ 23 | public function __construct($jobName, Jenkins $jenkins) 24 | { 25 | $this->_jobName = (string) $jobName; 26 | $this->_jenkins = $jenkins; 27 | 28 | $this->refresh(); 29 | 30 | $this->_buildNumber = $this->get('number'); 31 | } 32 | 33 | /** 34 | * @return string 35 | */ 36 | protected function getUrl() 37 | { 38 | return sprintf('job/%s/lastBuild/api/json', rawurlencode($this->_jobName)); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/JenkinsApi/Item/Queue.php: -------------------------------------------------------------------------------- 1 | 13 | * @version $Id$ 14 | */ 15 | class Queue extends AbstractItem 16 | { 17 | /** 18 | * @var Jenkins 19 | */ 20 | protected $_jenkins; 21 | 22 | /** 23 | * @param Jenkins $jenkins 24 | */ 25 | public function __construct(Jenkins $jenkins) 26 | { 27 | $this->_jenkins = $jenkins; 28 | 29 | $this->refresh(); 30 | } 31 | 32 | /** 33 | * @return string 34 | */ 35 | protected function getUrl() 36 | { 37 | return 'queue/api/json'; 38 | } 39 | 40 | /** 41 | * @return JobQueue[] 42 | */ 43 | public function getJobQueues() 44 | { 45 | $jobs = array(); 46 | foreach ($this->get('items') as $item) { 47 | $jobs[] = new JobQueue($item, $this->getJenkins()); 48 | } 49 | 50 | return $jobs; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/JenkinsApi/Item/JobQueue.php: -------------------------------------------------------------------------------- 1 | 13 | * @version $Id$ 14 | */ 15 | class JobQueue 16 | { 17 | /** 18 | * @var stdClass 19 | */ 20 | private $_jobQueue; 21 | 22 | 23 | /** 24 | * @var Jenkins 25 | */ 26 | protected $_jenkins; 27 | 28 | /** 29 | * @param stdClass $jobQueue 30 | * @param Jenkins $jenkins 31 | */ 32 | public function __construct($jobQueue, Jenkins $jenkins) 33 | { 34 | $this->_jobQueue = $jobQueue; 35 | $this->_jenkins = $jenkins; 36 | } 37 | 38 | /** 39 | * @return array 40 | */ 41 | public function getInputParameters() 42 | { 43 | $parameters = array(); 44 | 45 | if (!property_exists($this->_jobQueue->actions[0], 'parameters')) { 46 | return $parameters; 47 | } 48 | 49 | foreach ($this->_jobQueue->actions[0]->parameters as $parameter) { 50 | $parameters[$parameter->name] = $parameter->value; 51 | } 52 | 53 | return $parameters; 54 | } 55 | 56 | /** 57 | * @return string 58 | */ 59 | public function getJobName() 60 | { 61 | return $this->_jobQueue->task->name; 62 | } 63 | 64 | /** 65 | * @return int 66 | */ 67 | public function getId() 68 | { 69 | return $this->_jobQueue->id; 70 | } 71 | 72 | /** 73 | * @return void 74 | */ 75 | public function cancel() 76 | { 77 | $response = $this->getJenkins()->post(sprintf('queue/item/%s/cancelQueue', $this->getId())); 78 | if ($response) { 79 | throw new RuntimeException(sprintf('Error durring stopping job queue #%s', $this->getId())); 80 | } 81 | } 82 | 83 | /** 84 | * @return Jenkins 85 | */ 86 | public function getJenkins() 87 | { 88 | return $this->_jenkins; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/JenkinsApi/AbstractItem.php: -------------------------------------------------------------------------------- 1 | 7 | * @copyright 2013 Jungheinrich AG 8 | * @license Proprietary license 9 | * @version $Id$ 10 | */ 11 | 12 | namespace JenkinsApi; 13 | 14 | use stdClass; 15 | 16 | /** 17 | * Abstract class for all items that can be access via jenkins api 18 | * 19 | * @package JenkinsApi 20 | * @author Christopher Biel 21 | * @version $Id$ 22 | */ 23 | abstract class AbstractItem 24 | { 25 | /** 26 | * @var Jenkins 27 | */ 28 | protected $_jenkins; 29 | 30 | /** 31 | * @var stdClass 32 | */ 33 | protected $_data; 34 | 35 | /** 36 | * @return $this 37 | */ 38 | public function refresh() 39 | { 40 | $this->_data = $this->getJenkins()->get($this->getUrl()); 41 | return $this; 42 | } 43 | 44 | /** 45 | * @return string 46 | */ 47 | abstract protected function getUrl(); 48 | 49 | /** 50 | * @param string $propertyName 51 | * 52 | * @return string|int|null|stdClass 53 | */ 54 | public function get($propertyName) 55 | { 56 | if ($this->_data instanceof stdClass && property_exists($this->_data, $propertyName)) { 57 | return $this->_data->$propertyName; 58 | } 59 | return null; 60 | } 61 | 62 | /** 63 | * @return Jenkins 64 | */ 65 | public function getJenkins() 66 | { 67 | return $this->_jenkins; 68 | } 69 | 70 | /** 71 | * @param Jenkins $jenkins 72 | */ 73 | public function setJenkins($jenkins) 74 | { 75 | $this->_jenkins = $jenkins; 76 | } 77 | 78 | public function __get($property) 79 | { 80 | return $this->get($property); 81 | } 82 | 83 | public function __isset($property) 84 | { 85 | return array_key_exists($property, $this->_data); 86 | } 87 | 88 | public function __call($name, $args = array()) 89 | { 90 | if(strlen($name) > 3 && substr($name, 0, 3) === 'get') { 91 | return $this->get(lcfirst(substr($name, 3))); 92 | } 93 | } 94 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Jenkins PHP API 2 | =============== 3 | 4 | This version of the Jenkins PHP API is based on https://github.com/jenkins-khan/jenkins-php-api. 5 | It's more OOP (means a clearer API) than the original and has some more features. 6 | 7 | It wraps the API calls of the Jenkins API. 8 | 9 | 10 | Getting started 11 | --------------- 12 | First you need to instantiate the connection: 13 | 14 | ```php 15 | $jenkins = new Jenkins('http://host.org:8080'); 16 | ``` 17 | 18 | If your Jenkins needs authentication, you need to pass a URL like this : `'http://user:token@host.org:8080'`. 19 | 20 | 21 | There are always two ways to instanciate an item and get the data you want: 22 | 23 | 1. Use the classes directly (`new Job('myjob', $jenkins)`). In this case you have to instanciate Jenkins first and pass it as second constructor argument. 24 | 2. Use methods of Jenkins: `(new Jenkins('myurl'))->getJob('myjob')` 25 | 26 | Get the color of the job 27 | ------------------------ 28 | 29 | ```php 30 | $job = $jenkins->getJob("dev2-pull"); 31 | var_dump($job->getColor()); 32 | //string(4) "blue" 33 | ``` 34 | 35 | 36 | Launch a Job 37 | ------------ 38 | 39 | Will launch the job and return imidiatly 40 | ```php 41 | $job = $jenkins->getJob("clone-deploy")->launch(); 42 | ``` 43 | 44 | Will launch the job and wait until the job is finished 45 | ```php 46 | $job = $jenkins->getJob("clone-deploy")->launchAndWait(); 47 | ``` 48 | 49 | 50 | List the jobs of a given view 51 | ----------------------------- 52 | 53 | ```php 54 | $view = $jenkins->getView('madb_deploy'); 55 | foreach ($view->getJobs() as $job) { 56 | var_dump($job->getName()); 57 | } 58 | //string(13) "altlinux-pull" 59 | //string(8) "dev-pull" 60 | //string(9) "dev2-pull" 61 | //string(11) "fedora-pull" 62 | ``` 63 | 64 | List builds and their status 65 | ---------------------------- 66 | 67 | ```php 68 | $job = $jenkins->getJob('dev2-pull'); 69 | foreach ($job->getBuilds() as $build) { 70 | var_dump($build->getNumber()); 71 | var_dump($build->getResult()); 72 | } 73 | //int(122) 74 | //string(7) "SUCCESS" 75 | //int(121) 76 | //string(7) "FAILURE" 77 | ``` 78 | 79 | 80 | Check if Jenkins is available 81 | ----------------------------- 82 | 83 | ```php 84 | var_dump($jenkins->isAvailable()); 85 | //bool(true); 86 | ``` 87 | 88 | For more information, see the [Jenkins API](https://wiki.jenkins-ci.org/display/JENKINS/Remote+access+API). 89 | -------------------------------------------------------------------------------- /src/JenkinsApi/Item/View.php: -------------------------------------------------------------------------------- 1 | 13 | * @version $Id$ 14 | */ 15 | class View extends AbstractItem 16 | { 17 | /** 18 | * @var string 19 | */ 20 | private $_name; 21 | 22 | /** 23 | * @param string $name 24 | * @param Jenkins $jenkins 25 | */ 26 | public function __construct($name, Jenkins $jenkins) 27 | { 28 | $this->_name = $name; 29 | $this->_jenkins = $jenkins; 30 | 31 | $this->refresh(); 32 | } 33 | 34 | /** 35 | * @return string 36 | */ 37 | protected function getUrl() 38 | { 39 | return sprintf('view/%s/api/json', rawurlencode($this->_name)); 40 | } 41 | 42 | /** 43 | * @return string 44 | */ 45 | public function getName() 46 | { 47 | return $this->_name; 48 | } 49 | 50 | /** 51 | * @return Job[] 52 | */ 53 | public function getJobs() 54 | { 55 | $jobs = array(); 56 | foreach ($this->get('jobs') as $job) { 57 | $jobs[] = new Job($job->name, $this); 58 | } 59 | return $jobs; 60 | } 61 | 62 | /** 63 | * getColor 64 | * 65 | * @return string 66 | */ 67 | public function getColor() 68 | { 69 | $color = 'blue'; 70 | foreach ($this->get('jobs') as $job) { 71 | if ($this->getColorPriority($job->color) > $this->getColorPriority($color)) { 72 | $color = $job->color; 73 | } 74 | } 75 | return $color; 76 | } 77 | 78 | /** 79 | * getColorPriority 80 | * 81 | * @param string $color 82 | * 83 | * @return int 84 | */ 85 | protected function getColorPriority($color) 86 | { 87 | switch ($color) { 88 | default: 89 | return 999; 90 | case 'red_anime': 91 | return 11; 92 | case 'red': 93 | return 10; 94 | case 'yellow_anime': 95 | return 6; 96 | case 'yellow': 97 | return 5; 98 | case 'blue_anime': 99 | return 2; 100 | case 'blue': 101 | return 1; 102 | case 'disabled': 103 | return 0; 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/JenkinsApi/Item/Executor.php: -------------------------------------------------------------------------------- 1 | 13 | * @version $Id$ 14 | * 15 | * @method int getProgress() 16 | * @method int getNumber() 17 | */ 18 | class Executor extends AbstractItem 19 | { 20 | /** 21 | * @var int 22 | */ 23 | private $_executorId; 24 | /** 25 | * @var string 26 | */ 27 | private $_nodeName; 28 | 29 | /** 30 | * @var Node 31 | */ 32 | private $_node; 33 | 34 | /** 35 | * @param int $executorId 36 | * @param string $nodeName 37 | * @param Jenkins $jenkins 38 | */ 39 | public function __construct($executorId, $nodeName, Jenkins $jenkins) 40 | { 41 | $this->_executorId = $executorId; 42 | $this->_nodeName = $nodeName; 43 | $this->_jenkins = $jenkins; 44 | 45 | $this->refresh(); 46 | } 47 | 48 | /** 49 | * @return string 50 | */ 51 | protected function getUrl() 52 | { 53 | return sprintf('computer/%s/executors/%s/api/json', rawurlencode($this->_nodeName), rawurlencode($this->_executorId)); 54 | } 55 | 56 | /** 57 | * @return Node 58 | */ 59 | public function getNode() 60 | { 61 | if(!$this->_node) { 62 | $this->_node = new Node($this->_nodeName, $this->getJenkins()); 63 | } 64 | return $this->_node; 65 | } 66 | 67 | /** 68 | * @return int|null 69 | */ 70 | public function getBuildNumber() 71 | { 72 | if (($currentExecutable = $this->get('currentExecutable')) !== null) { 73 | return $currentExecutable->number; 74 | } 75 | return null; 76 | } 77 | 78 | /** 79 | * @return null|string 80 | */ 81 | public function getBuildUrl() 82 | { 83 | if (($currentExecutable = $this->get('currentExecutable')) !== null) { 84 | return $currentExecutable->url; 85 | } 86 | return null; 87 | } 88 | 89 | /** 90 | * @return void 91 | */ 92 | public function stop() 93 | { 94 | $response = $this->getJenkins()->post( 95 | sprintf('computer/%s/executors/%s/stop', $this->getNode()->getName(), $this->getNumber()) 96 | ); 97 | if($response) { 98 | throw new RuntimeException(sprintf('Error durring stopping executor #%s', $this->getNumber())); 99 | } 100 | } 101 | 102 | /** 103 | * @return Jenkins 104 | */ 105 | public function getJenkins() 106 | { 107 | return $this->_jenkins; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/JenkinsApi/Item/Node.php: -------------------------------------------------------------------------------- 1 | 16 | * @version $Id$ 17 | * 18 | * @method null|stdClass getOfflineCause() null when computer is launching, tdClass when computer has been put offline 19 | */ 20 | class Node extends AbstractItem 21 | { 22 | /** 23 | * @var string 24 | */ 25 | private $_nodeName; 26 | 27 | /** 28 | * @param string $nodeName 29 | * @param Jenkins $jenkins 30 | */ 31 | public function __construct($nodeName, Jenkins $jenkins) 32 | { 33 | if ($nodeName === 'master') { 34 | $nodeName = '(master)'; 35 | } 36 | 37 | $this->_nodeName = $nodeName; 38 | $this->_jenkins = $jenkins; 39 | 40 | $this->refresh(); 41 | } 42 | 43 | public function refresh() 44 | { 45 | try { 46 | return parent::refresh(); 47 | } catch (JenkinsApiException $e) { 48 | throw new NodeNotFoundException($this->_nodeName, 0, $e); 49 | } 50 | } 51 | 52 | /** 53 | * @return string 54 | */ 55 | protected function getUrl() 56 | { 57 | return sprintf('computer/%s/api/json', rawurlencode($this->_nodeName)); 58 | } 59 | 60 | /** 61 | * @return Executor[] 62 | */ 63 | public function getExecutors() 64 | { 65 | for ($i = 0; $i < $this->get('numExecutors'); $i++) { 66 | yield new Executor($i, $this->_nodeName, $this->getJenkins()); 67 | } 68 | } 69 | 70 | /** 71 | * @return Node 72 | */ 73 | public function toggleOffline() 74 | { 75 | $response = $this->getJenkins()->post(sprintf('computer/%s/toggleOffline', $this->_nodeName)); 76 | if ($response) { 77 | throw new RuntimeException(sprintf('Error marking %s offline', $this->_nodeName)); 78 | } 79 | return $this; 80 | } 81 | 82 | /** 83 | * @return void 84 | */ 85 | public function delete() 86 | { 87 | $this->getJenkins()->post(sprintf('computer/%s/doDelete', $this->_nodeName)); 88 | } 89 | 90 | /** 91 | * @return string 92 | */ 93 | public function getConfiguration() 94 | { 95 | return $this->getJenkins()->get( 96 | sprintf('/computer/%s/config.xml', $this->_nodeName), [], [CURLOPT_RETURNTRANSFER => 1] 97 | ); 98 | } 99 | 100 | /** 101 | * @return string 102 | */ 103 | public function getName() 104 | { 105 | return $this->get('displayName'); 106 | } 107 | 108 | /** 109 | * 110 | * @return bool 111 | */ 112 | public function isOffline() 113 | { 114 | return (bool) $this->get('offline'); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/JenkinsApi/Item/Job.php: -------------------------------------------------------------------------------- 1 | 14 | * @version $Id$ 15 | * 16 | * @method string getName() 17 | * @method string getColor() 18 | */ 19 | class Job extends AbstractItem 20 | { 21 | /** 22 | * @var 23 | */ 24 | private $_jobName; 25 | 26 | /** 27 | * @param $jobName 28 | * @param Jenkins $jenkins 29 | */ 30 | public function __construct($jobName, Jenkins $jenkins) 31 | { 32 | $this->_jobName = $jobName; 33 | $this->_jenkins = $jenkins; 34 | 35 | $this->refresh(); 36 | } 37 | 38 | public function refresh() 39 | { 40 | try { 41 | return parent::refresh(); 42 | } catch (JenkinsApiException $e) { 43 | throw new JobNotFoundException($this->_jobName, 0, $e); 44 | } 45 | } 46 | 47 | /** 48 | * @return string 49 | */ 50 | protected function getUrl() 51 | { 52 | return sprintf('job/%s/api/json', rawurlencode($this->_jobName)); 53 | } 54 | 55 | /** 56 | * @return Build[] 57 | */ 58 | public function getBuilds() 59 | { 60 | $builds = array(); 61 | foreach ($this->_data->builds as $build) { 62 | $builds[] = $this->getBuild($build->number); 63 | } 64 | 65 | return $builds; 66 | } 67 | 68 | /** 69 | * @param int $buildId 70 | * 71 | * @return Build 72 | * @throws RuntimeException 73 | */ 74 | public function getBuild($buildId) 75 | { 76 | return $this->_jenkins->getBuild($this->getName(), $buildId); 77 | } 78 | 79 | /** 80 | * @return array 81 | */ 82 | public function getParametersDefinition() 83 | { 84 | $parameters = array(); 85 | 86 | foreach ($this->_data->actions as $action) { 87 | if (!property_exists($action, 'parameterDefinitions')) { 88 | continue; 89 | } 90 | 91 | foreach ($action->parameterDefinitions as $parameterDefinition) { 92 | $default = property_exists($parameterDefinition, 'defaultParameterValue') ? $parameterDefinition->defaultParameterValue->value : null; 93 | $description = property_exists($parameterDefinition, 'description') ? $parameterDefinition->description : null; 94 | $choices = property_exists($parameterDefinition, 'choices') ? $parameterDefinition->choices : null; 95 | 96 | $parameters[$parameterDefinition->name] = array('default' => $default, 'choices' => $choices, 'description' => $description); 97 | } 98 | } 99 | 100 | return $parameters; 101 | } 102 | 103 | /** 104 | * @return Build|null 105 | */ 106 | public function getLastSuccessfulBuild() 107 | { 108 | if (null === $this->_data->lastSuccessfulBuild) { 109 | return null; 110 | } 111 | 112 | return $this->_jenkins->getBuild($this->getName(), $this->_data->lastSuccessfulBuild->number); 113 | } 114 | 115 | /** 116 | * @return Build|null 117 | */ 118 | public function getLastBuild() 119 | { 120 | if (null === $this->_data->lastBuild) { 121 | return null; 122 | } 123 | return $this->_jenkins->getBuild($this->getName(), $this->_data->lastBuild->number); 124 | } 125 | 126 | /** 127 | * @return bool 128 | */ 129 | public function isCurrentlyBuilding() 130 | { 131 | $lastBuild = $this->getLastBuild(); 132 | if ($lastBuild === null) { 133 | return false; 134 | } 135 | return $lastBuild->isBuilding(); 136 | } 137 | 138 | /** 139 | * @param array $parameters 140 | * 141 | * @return bool|resource 142 | */ 143 | public function launch($parameters = array()) 144 | { 145 | if (empty($parameters)) { 146 | return $this->_jenkins->post(sprintf('job/%s/build', rawurlencode($this->_jobName))); 147 | } else { 148 | return $this->_jenkins->post(sprintf('job/%s/buildWithParameters', rawurlencode($this->_jobName)), $parameters); 149 | } 150 | } 151 | 152 | /** 153 | * @param array $parameters 154 | * 155 | * @param int $timeoutSeconds 156 | * @param int $checkIntervalSeconds 157 | * @return bool|Build 158 | */ 159 | public function launchAndWait($parameters = array(), $timeoutSeconds = 86400, $checkIntervalSeconds = 5) 160 | { 161 | if (!$this->isCurrentlyBuilding()) { 162 | $lastNumber = $this->getLastBuild()->getNumber(); 163 | $startTime = time(); 164 | $response = $this->launch($parameters); 165 | // TODO evaluate the response correctly, to get the queued item and later the build 166 | if ($response) { 167 | // list($header, $body) = explode("\r\n\r\n", $response, 2); 168 | } 169 | 170 | while ((time() < $startTime + $timeoutSeconds) 171 | && (($this->getLastBuild()->getNumber() == $lastNumber) 172 | || ($this->getLastBuild()->getNumber() == $lastNumber + 1 173 | && $this->getLastBuild()->isBuilding()))) { 174 | sleep($checkIntervalSeconds); 175 | $this->refresh(); 176 | } 177 | } else { 178 | while ($this->getLastBuild()->isBuilding()) { 179 | sleep($checkIntervalSeconds); 180 | $this->refresh(); 181 | } 182 | } 183 | return $this->getLastBuild(); 184 | } 185 | 186 | public function delete() 187 | { 188 | if (!$this->getJenkins()->post(sprintf('job/%s/doDelete', $this->_jobName))) { 189 | throw new RuntimeException(sprintf('Error deleting job %s on %s', $this->_jobName, $this->getJenkins()->getBaseUrl())); 190 | } 191 | } 192 | 193 | public function getConfig() 194 | { 195 | $config = $this->getJenkins()->get(sprintf('job/%s/config.xml', $this->_jobName)); 196 | if ($config) { 197 | throw new RuntimeException(sprintf('Error during getting configuation for job %s', $this->_jobName)); 198 | } 199 | return $config; 200 | } 201 | 202 | /** 203 | * @param string $jobname 204 | * @param DomDocument $document 205 | * 206 | * @deprecated use setJobConfig instead 207 | */ 208 | public function setConfigFromDomDocument($jobname, DomDocument $document) 209 | { 210 | $this->setJobConfig($jobname, $document->saveXML()); 211 | } 212 | 213 | /** 214 | * @param string $configuration config XML 215 | * 216 | */ 217 | public function setJobConfig($configuration) 218 | { 219 | $return = $this->getJenkins()->post(sprintf('job/%s/config.xml', $this->_jobName), $configuration, array(CURLOPT_HTTPHEADER => array('Content-Type: text/xml'))); 220 | if ($return != 1) { 221 | throw new RuntimeException(sprintf('Error during setting configuration for job %s', $this->_jobName)); 222 | } 223 | } 224 | 225 | public function disable() 226 | { 227 | if (!$this->getJenkins()->post(sprintf('job/%s/disable', $this->_jobName))) { 228 | throw new RuntimeException(sprintf('Error disabling job %s on %s', $this->_jobName, $this->getJenkins()->getBaseUrl())); 229 | } 230 | } 231 | 232 | public function enable() 233 | { 234 | if (!$this->getJenkins()->post(sprintf('job/%s/enable', $this->_jobName))) { 235 | throw new RuntimeException(sprintf('Error enabling job %s on %s', $this->_jobName, $this->getJenkins()->getBaseUrl())); 236 | } 237 | } 238 | 239 | /** 240 | * @return boolean 241 | */ 242 | public function isBuildable() 243 | { 244 | return $this->_data->buildable; 245 | } 246 | 247 | public function __toString() 248 | { 249 | return $this->_jobName; 250 | } 251 | } 252 | -------------------------------------------------------------------------------- /src/JenkinsApi/Item/Build.php: -------------------------------------------------------------------------------- 1 | 14 | * @version $Id$ 15 | * 16 | * @method int getNumber() 17 | * @method string getBuiltOn() 18 | */ 19 | class Build extends AbstractItem 20 | { 21 | /** 22 | * @var string 23 | */ 24 | const FAILURE = 'FAILURE'; 25 | 26 | /** 27 | * @var string 28 | */ 29 | const SUCCESS = 'SUCCESS'; 30 | 31 | /** 32 | * @var string 33 | */ 34 | const RUNNING = 'RUNNING'; 35 | 36 | /** 37 | * @var string 38 | */ 39 | const WAITING = 'WAITING'; 40 | 41 | /** 42 | * @var string 43 | */ 44 | const UNSTABLE = 'UNSTABLE'; 45 | 46 | /** 47 | * @var string 48 | */ 49 | const ABORTED = 'ABORTED'; 50 | 51 | /** 52 | * @var string 53 | */ 54 | protected $_buildNumber; 55 | 56 | /** 57 | * @var string 58 | */ 59 | protected $_jobName; 60 | 61 | /** 62 | * @param string $buildNumber 63 | * @param string $jobName 64 | * @param Jenkins $jenkins 65 | */ 66 | public function __construct($buildNumber, $jobName, Jenkins $jenkins) 67 | { 68 | $this->_buildNumber = $buildNumber; 69 | $this->_jobName = (string) $jobName; 70 | $this->_jenkins = $jenkins; 71 | 72 | $this->refresh(); 73 | } 74 | 75 | public function refresh() 76 | { 77 | try { 78 | return parent::refresh(); 79 | } catch (JenkinsApiException $e) { 80 | throw new BuildNotFoundException($this->_buildNumber, $this->_jobName, 0, $e); 81 | } 82 | } 83 | 84 | /** 85 | * @return string 86 | */ 87 | protected function getUrl() 88 | { 89 | return sprintf('job/%s/%d/api/json', rawurlencode($this->_jobName), rawurlencode($this->_buildNumber)); 90 | } 91 | 92 | /** 93 | * @return array 94 | */ 95 | public function getInputParameters() 96 | { 97 | $parameters = array(); 98 | if (($this->get('actions')) === null || $this->get('actions') === array()) { 99 | return $parameters; 100 | } 101 | 102 | foreach ($this->get('actions') as $action) { 103 | if (property_exists($action, 'parameters')) { 104 | foreach ($action->parameters as $parameter) { 105 | if (property_exists($parameter, 'value')) { 106 | $parameters[$parameter->name] = $parameter->value; 107 | } elseif (property_exists($parameter, 'number') && property_exists($parameter, 'jobName')) { 108 | $parameters[$parameter->name]['number'] = $parameter->number; 109 | $parameters[$parameter->name]['jobName'] = $parameter->jobName; 110 | } 111 | } 112 | break; 113 | } 114 | } 115 | 116 | return $parameters; 117 | } 118 | 119 | /** 120 | * @return null|int 121 | */ 122 | public function getProgress() 123 | { 124 | $progress = null; 125 | if (null !== ($executor = $this->getExecutor())) { 126 | $progress = $executor->getProgress(); 127 | } 128 | 129 | return $progress; 130 | } 131 | 132 | /** 133 | * @return float|null 134 | */ 135 | public function getEstimatedDuration() 136 | { 137 | //since version 1.461 estimatedDuration is displayed in jenkins's api 138 | //we can use it witch is more accurate than calcule ourselves 139 | //but older versions need to continue to work, so in case of estimated 140 | //duration is not found we fallback to calcule it. 141 | if ($this->get('estimatedDuration')) { 142 | return $this->get('estimatedDuration') / 1000; 143 | } 144 | 145 | $duration = null; 146 | $progress = $this->getProgress(); 147 | if (null !== $progress && $progress >= 0) { 148 | $duration = ceil((time() - $this->getTimestamp()) / ($progress / 100)); 149 | } 150 | return $duration; 151 | } 152 | 153 | /** 154 | * Returns remaining execution time (seconds) 155 | * 156 | * @return int|null 157 | */ 158 | public function getRemainingExecutionTime() 159 | { 160 | $remaining = null; 161 | if (null !== ($estimatedDuration = $this->getEstimatedDuration())) { 162 | //be carefull because time from JK server could be different 163 | //of time from Jenkins server 164 | //but i didn't find a timestamp given by Jenkins api 165 | 166 | $remaining = $estimatedDuration - (time() - $this->getTimestamp()); 167 | } 168 | 169 | return max(0, $remaining); 170 | } 171 | 172 | /** 173 | * @return null|string 174 | */ 175 | public function getResult() 176 | { 177 | $result = null; 178 | switch ($this->get('result')) { 179 | case 'FAILURE': 180 | $result = Build::FAILURE; 181 | break; 182 | case 'SUCCESS': 183 | $result = Build::SUCCESS; 184 | break; 185 | case 'UNSTABLE': 186 | $result = Build::UNSTABLE; 187 | break; 188 | case 'ABORTED': 189 | $result = Build::ABORTED; 190 | break; 191 | case 'WAITING': 192 | $result = Build::WAITING; 193 | break; 194 | default: 195 | $result = Build::RUNNING; 196 | break; 197 | } 198 | 199 | return $result; 200 | } 201 | 202 | /** 203 | * @return Executor|null 204 | */ 205 | public function getExecutor() 206 | { 207 | if (!$this->isBuilding()) { 208 | return null; 209 | } 210 | 211 | $runExecutor = null; 212 | foreach ($this->getJenkins()->getExecutors() as $executor) { 213 | /** @var Executor $executor */ 214 | if ($this->getBuildUrl() === $executor->getBuildUrl()) { 215 | $runExecutor = $executor; 216 | } 217 | } 218 | return $runExecutor; 219 | } 220 | 221 | /** 222 | * @param $text 223 | * 224 | * @return bool 225 | */ 226 | public function setDescription($text) 227 | { 228 | $url = sprintf('job/%s/%s/submitDescription', $this->_jobName, $this->_buildNumber); 229 | return $this->getJenkins()->post($url, array('description' => $text)); 230 | } 231 | 232 | /** 233 | * @return string 234 | */ 235 | public function getConsoleTextBuild() 236 | { 237 | return $this->getJenkins()->get(sprintf('job/%s/%s/consoleText', $this->_jobName, $this->_buildNumber), 1, array(), array(), true); 238 | } 239 | 240 | /** 241 | * @return bool 242 | */ 243 | public function isBuilding() 244 | { 245 | return (bool) $this->get('building'); 246 | } 247 | 248 | /** 249 | * @return int 250 | */ 251 | public function getTimestamp() 252 | { 253 | return (int) ($this->get('timestamp') / 1000); 254 | } 255 | 256 | /** 257 | * @return int 258 | */ 259 | public function getDuration() 260 | { 261 | if ($this->get('duration') == 0) { 262 | // duration is not set by Jenkins, let's calculate ourselves 263 | return (int) (time() - $this->getTimestamp()); 264 | } 265 | return (int) ($this->get('duration') / 1000); 266 | } 267 | 268 | /** 269 | * @return string 270 | */ 271 | public function getBuildUrl() 272 | { 273 | return $this->get('url'); 274 | } 275 | 276 | /** 277 | * @return string 278 | */ 279 | public function getJobName() 280 | { 281 | return $this->_jobName; 282 | } 283 | 284 | /** 285 | * @return bool 286 | */ 287 | public function stop() 288 | { 289 | if (!$this->isBuilding()) { 290 | return null; 291 | } 292 | 293 | return $this->getJenkins()->post( 294 | sprintf('job/%s/%d/stop', $this->_jobName, $this->_buildNumber) 295 | ); 296 | } 297 | } 298 | -------------------------------------------------------------------------------- /src/JenkinsApi/Jenkins.php: -------------------------------------------------------------------------------- 1 | 7 | * @copyright 2013 Jungheinrich AG 8 | * @license Proprietary license 9 | * @version $Id$ 10 | */ 11 | 12 | namespace JenkinsApi; 13 | 14 | use InvalidArgumentException; 15 | use JenkinsApi\Exceptions\JenkinsApiException; 16 | use JenkinsApi\Item\Build; 17 | use JenkinsApi\Item\Executor; 18 | use JenkinsApi\Item\Job; 19 | use JenkinsApi\Item\LastBuild; 20 | use JenkinsApi\Item\Node; 21 | use JenkinsApi\Item\Queue; 22 | use JenkinsApi\Item\View; 23 | use RuntimeException; 24 | use stdClass; 25 | 26 | /** 27 | * Wrapper for general 28 | * 29 | * @package JenkinsApi 30 | * @author Christopher Biel 31 | * @version $Id$ 32 | */ 33 | class Jenkins 34 | { 35 | const FORMAT_OBJECT = 'asObject'; 36 | const FORMAT_XML = 'asXml'; 37 | 38 | /** 39 | * @var bool 40 | */ 41 | private $_verbose = false; 42 | 43 | /** 44 | * @var string 45 | */ 46 | private $_baseUrl; 47 | 48 | /** 49 | * @var string 50 | */ 51 | private $_username; 52 | 53 | /** 54 | * @var string 55 | */ 56 | private $_password; 57 | 58 | /** 59 | * @var string 60 | */ 61 | private $_urlExtension = '/api/json'; 62 | 63 | /** 64 | * Whether or not to retrieve and send anti-CSRF crumb tokens 65 | * with each request 66 | * 67 | * Defaults to false for backwards compatibility 68 | * 69 | * @var boolean 70 | */ 71 | private $_crumbsEnabled = false; 72 | 73 | /** 74 | * The anti-CSRF crumb to use for each request 75 | * 76 | * Set when crumbs are enabled, by requesting a new crumb from Jenkins 77 | * 78 | * @var string 79 | */ 80 | private $_crumb; 81 | 82 | /** 83 | * The header to use for sending anti-CSRF crumbs 84 | * 85 | * Set when crumbs are enabled, by requesting a new crumb from Jenkins 86 | * 87 | * @var string 88 | */ 89 | private $_crumbRequestField; 90 | 91 | /** 92 | * @param string $baseUrl 93 | */ 94 | public function __construct($baseUrl, $username = '', $password = '') 95 | { 96 | $this->_baseUrl = $baseUrl . ((substr($baseUrl, -1) === '/') ? '' : '/'); 97 | $this->_username = $username; 98 | $this->_password = $password; 99 | } 100 | 101 | /** 102 | * @param string|Job $jobName 103 | * @param int|string $buildNumber 104 | * 105 | * @return Build 106 | */ 107 | public function getBuild($jobName, $buildNumber) 108 | { 109 | return new Build($buildNumber, $jobName, $this); 110 | } 111 | 112 | /** 113 | * @param string $jobName 114 | * 115 | * @return Job 116 | */ 117 | public function getJob($jobName) 118 | { 119 | return new Job($jobName, $this); 120 | } 121 | 122 | /** 123 | * @return Job[] 124 | */ 125 | public function getJobs() 126 | { 127 | $data = $this->get('api/json'); 128 | 129 | $jobs = array(); 130 | foreach ($data->jobs as $job) { 131 | $jobs[$job->name] = $this->getJob($job->name); 132 | } 133 | 134 | return $jobs; 135 | } 136 | 137 | /** 138 | * @return Queue 139 | * @throws RuntimeException 140 | */ 141 | public function getQueue() 142 | { 143 | return new Queue($this); 144 | } 145 | 146 | /** 147 | * @param string $url 148 | * @param int $depth 149 | * @param array $params 150 | * @param array $curlOpts 151 | * @param bool $raw 152 | * 153 | * @throws RuntimeException 154 | * @return stdClass 155 | */ 156 | public function get($url, $depth = 1, $params = array(), array $curlOpts = [], $raw = false) 157 | { 158 | // $url = str_replace(' ', '%20', sprintf('%s' . $url . '?depth=' . $depth, $this->_baseUrl)); 159 | $url = sprintf('%s', $this->_baseUrl) . $url . '?depth=' . $depth; 160 | if ($params) { 161 | foreach ($params as $key => $val) { 162 | $url .= '&' . $key . '=' . $val; 163 | } 164 | } 165 | $curl = curl_init($url); 166 | if ($curlOpts) { 167 | curl_setopt_array($curl, $curlOpts); 168 | } 169 | curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); 170 | curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 171 | 172 | if ($this->_username) { 173 | curl_setopt($curl, CURLOPT_USERPWD, $this->_username . ":" . $this->_password); 174 | } 175 | 176 | $ret = curl_exec($curl); 177 | 178 | $response_info = curl_getinfo($curl); 179 | 180 | if (200 != $response_info['http_code']) { 181 | throw new JenkinsApiException( 182 | sprintf( 183 | 'Error during getting information from url %s (Response: %s)', $url, $response_info['http_code'] 184 | ) 185 | ); 186 | } 187 | 188 | if (curl_errno($curl)) { 189 | throw new JenkinsApiException( 190 | sprintf('Error during getting information from url %s (%s)', $url, curl_error($curl)) 191 | ); 192 | } 193 | if ($raw) { 194 | return $ret; 195 | } 196 | $data = json_decode($ret); 197 | if (!$data instanceof stdClass) { 198 | throw new JenkinsApiException('Error during json_decode'); 199 | } 200 | 201 | return $data; 202 | } 203 | 204 | /** 205 | * @param string $url 206 | * @param array|string $parameters 207 | * @param array $curlOpts 208 | * 209 | * @throws RuntimeException 210 | * @return bool 211 | */ 212 | public function post($url, $parameters = [], array $curlOpts = []) 213 | { 214 | $url = sprintf('%s', $this->_baseUrl) . $url; 215 | 216 | $curl = curl_init($url); 217 | if ($curlOpts) { 218 | curl_setopt_array($curl, $curlOpts); 219 | } 220 | curl_setopt($curl, CURLOPT_POST, 1); 221 | if (is_array($parameters)) { 222 | $parameters = http_build_query($parameters); 223 | } 224 | curl_setopt($curl, CURLOPT_POSTFIELDS, $parameters); 225 | 226 | if ($this->_username) { 227 | curl_setopt($curl, CURLOPT_USERPWD, $this->_username . ":" . $this->_password); 228 | } 229 | 230 | $headers = (isset($curlOpts[CURLOPT_HTTPHEADER])) ? $curlOpts[CURLOPT_HTTPHEADER] : array(); 231 | 232 | if ($this->areCrumbsEnabled()) { 233 | $headers[] = $this->getCrumbHeader(); 234 | } 235 | 236 | curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); 237 | curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); 238 | curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 239 | 240 | $return = curl_exec($curl); 241 | return (curl_errno($curl)) ?: $return; 242 | } 243 | 244 | /** 245 | * @return boolean 246 | */ 247 | public function isAvailable() 248 | { 249 | $curl = curl_init($this->_baseUrl . '/api/json'); 250 | curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 251 | 252 | if ($this->_username) { 253 | curl_setopt($curl, CURLOPT_USERPWD, $this->_username . ":" . $this->_password); 254 | } 255 | 256 | curl_exec($curl); 257 | 258 | if (curl_errno($curl)) { 259 | return false; 260 | } else { 261 | try { 262 | $this->getQueue(); 263 | } catch (JenkinsApiException $e) { 264 | return false; 265 | } 266 | } 267 | 268 | return true; 269 | } 270 | 271 | public function getCrumbHeader() 272 | { 273 | return "$this->_crumbRequestField: $this->_crumb"; 274 | } 275 | 276 | /** 277 | * Get the status of anti-CSRF crumbs 278 | * 279 | * @return boolean Whether or not crumbs have been enabled 280 | */ 281 | public function areCrumbsEnabled() 282 | { 283 | return $this->_crumbsEnabled; 284 | } 285 | 286 | public function requestCrumb() 287 | { 288 | $url = sprintf('%s/crumbIssuer/api/json', $this->_baseUrl); 289 | 290 | $curl = curl_init($url); 291 | 292 | curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 293 | 294 | if ($this->_username) { 295 | curl_setopt($curl, CURLOPT_USERPWD, $this->_username . ":" . $this->_password); 296 | } 297 | 298 | $ret = curl_exec($curl); 299 | 300 | if (curl_errno($curl)) { 301 | throw new JenkinsApiException('Error getting csrf crumb'); 302 | } 303 | 304 | $crumbResult = json_decode($ret); 305 | 306 | if (!$crumbResult instanceof stdClass) { 307 | throw new JenkinsApiException('Error during json_decode of csrf crumb'); 308 | } 309 | 310 | return $crumbResult; 311 | } 312 | 313 | /** 314 | * Enable the use of anti-CSRF crumbs on requests 315 | * 316 | * @return void 317 | */ 318 | public function enableCrumbs() 319 | { 320 | $this->_crumbsEnabled = true; 321 | 322 | $crumbResult = $this->requestCrumb(); 323 | 324 | if (!$crumbResult || !is_object($crumbResult)) { 325 | $this->_crumbsEnabled = false; 326 | 327 | return; 328 | } 329 | 330 | $this->_crumb = $crumbResult->crumb; 331 | $this->_crumbRequestField = $crumbResult->crumbRequestField; 332 | } 333 | 334 | /** 335 | * Get the currently building jobs 336 | * 337 | * @param string $outputFormat One of the FORMAT_* constants 338 | * 339 | * @return Item\Job[] 340 | */ 341 | public function getCurrentlyBuildingJobs($outputFormat = self::FORMAT_OBJECT) 342 | { 343 | $url = sprintf( 344 | '%s/api/xml?%s', 345 | $this->_baseUrl, 346 | 'tree=jobs[name,url,color]&xpath=/hudson/job[ends-with(color/text(),%22_anime%22)]&wrapper=jobs' 347 | ); 348 | 349 | $curl = curl_init($url); 350 | 351 | curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 352 | 353 | if ($this->_username) { 354 | curl_setopt($curl, CURLOPT_USERPWD, $this->_username . ":" . $this->_password); 355 | } 356 | 357 | $ret = curl_exec($curl); 358 | 359 | if (curl_errno($curl)) { 360 | throw new JenkinsApiException( 361 | sprintf( 362 | 'Error during getting all currently building jobs on %s (%s)', $this->_baseUrl, curl_error($curl) 363 | ) 364 | ); 365 | } 366 | 367 | $xml = simplexml_load_string($ret); 368 | $jobs = $xml->xpath('/jobs/job'); 369 | 370 | switch ($outputFormat) { 371 | case self::FORMAT_OBJECT: 372 | $buildingJobs = []; 373 | foreach ($jobs as $job) { 374 | $buildingJobs[] = new Job($job->name, $this); 375 | } 376 | return $buildingJobs; 377 | case self::FORMAT_XML: 378 | return $jobs; 379 | default: 380 | throw new InvalidArgumentException('Output format "' . $outputFormat . '" is unknown!'); 381 | } 382 | } 383 | 384 | /** 385 | * Get the last builds from the currently building jobs 386 | * 387 | * @return LastBuild[] 388 | */ 389 | public function getLastBuildsFromCurrentlyBuildingJobs() 390 | { 391 | $jobs = $this->getCurrentlyBuildingJobs(); 392 | $lastBuilds = []; 393 | foreach ($jobs as $job) { 394 | $lastBuilds[] = $job->getLastBuild(); 395 | } 396 | 397 | return $lastBuilds; 398 | } 399 | 400 | /** 401 | * @return View[] 402 | */ 403 | public function getViews() 404 | { 405 | $data = $this->get('api/json'); 406 | $views = array(); 407 | foreach ($data->views as $view) { 408 | $views[] = $this->getView($view->name); 409 | } 410 | return $views; 411 | } 412 | 413 | /** 414 | * @return View|null 415 | */ 416 | public function getPrimaryView() 417 | { 418 | $data = $this->get('api/json'); 419 | 420 | $primaryView = null; 421 | if (property_exists($data, 'primaryView')) { 422 | $primaryView = $this->getView($data->primaryView->name); 423 | } 424 | 425 | return $primaryView; 426 | } 427 | 428 | /** 429 | * @param string $jobname 430 | * @param string $xmlConfiguration 431 | * 432 | * @throws InvalidArgumentException 433 | * @return void 434 | */ 435 | public function createJob($jobname, $xmlConfiguration) 436 | { 437 | $url = sprintf('%s/createItem?name=%s', $this->getBaseUrl(), $jobname); 438 | $curl = curl_init($url); 439 | curl_setopt($curl, CURLOPT_POST, 1); 440 | 441 | curl_setopt($curl, CURLOPT_POSTFIELDS, $xmlConfiguration); 442 | curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 443 | 444 | if ($this->_username) { 445 | curl_setopt($curl, CURLOPT_USERPWD, $this->_username . ":" . $this->_password); 446 | } 447 | 448 | $headers = array('Content-Type: text/xml'); 449 | 450 | if ($this->areCrumbsEnabled()) { 451 | $headers[] = $this->getCrumbHeader(); 452 | } 453 | 454 | curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); 455 | 456 | $response = curl_exec($curl); 457 | 458 | if (curl_getinfo($curl, CURLINFO_HTTP_CODE) != 200) { 459 | throw new InvalidArgumentException(sprintf('Job %s already exists', $jobname)); 460 | } 461 | if (curl_errno($curl)) { 462 | throw new JenkinsApiException(sprintf('Error creating job %s (%s)', $jobname, curl_error($curl))); 463 | } 464 | } 465 | 466 | /** 467 | * @return Node[] 468 | */ 469 | public function getNodes() 470 | { 471 | $data = $this->get('computer/api/json'); 472 | 473 | foreach ($data->computer as $node) { 474 | yield new Node($node->displayName, $this); 475 | } 476 | } 477 | 478 | /** 479 | * @return Executor[] 480 | */ 481 | public function getExecutors() 482 | { 483 | foreach ($this->getNodes() as $node) { 484 | yield $node->getExecutors(); 485 | } 486 | } 487 | 488 | /** 489 | * Go into prepare shutdown mode. 490 | * This prevents new jobs beeing started 491 | */ 492 | public function prepareShutdown() 493 | { 494 | $this->post('quietDown'); 495 | } 496 | 497 | /** 498 | * Exit prepare shutdown mode 499 | * This allows jobs beeing started after shutdown prepare (but before actual restart) 500 | */ 501 | public function cancelPrepareShutdown() 502 | { 503 | $this->post('cancelQuietDown'); 504 | } 505 | 506 | /** 507 | * @param string $viewName 508 | * 509 | * @return View 510 | * @throws RuntimeException 511 | */ 512 | public function getView($viewName) 513 | { 514 | return new View($viewName, $this); 515 | } 516 | 517 | /** 518 | * Disable the use of anti-CSRF crumbs on requests 519 | * 520 | * @return void 521 | */ 522 | public function disableCrumbs() 523 | { 524 | $this->_crumbsEnabled = false; 525 | } 526 | 527 | /** 528 | * @return string 529 | */ 530 | public function getUrlExtension() 531 | { 532 | return $this->_urlExtension; 533 | } 534 | 535 | /** 536 | * @param string $urlExtension 537 | */ 538 | public function setUrlExtension($urlExtension) 539 | { 540 | $this->_urlExtension = $urlExtension; 541 | } 542 | 543 | /** 544 | * @return string 545 | */ 546 | public function getBaseUrl() 547 | { 548 | return $this->_baseUrl; 549 | } 550 | 551 | /** 552 | * @param string $baseUrl 553 | */ 554 | public function setBaseUrl($baseUrl) 555 | { 556 | $this->_baseUrl = $baseUrl; 557 | } 558 | 559 | /** 560 | * @return boolean 561 | */ 562 | public function isVerbose() 563 | { 564 | return $this->_verbose; 565 | } 566 | 567 | /** 568 | * @param boolean $verbose 569 | */ 570 | public function setVerbose($verbose) 571 | { 572 | $this->_verbose = $verbose; 573 | } 574 | } 575 | --------------------------------------------------------------------------------