PageRenderTime 625ms CodeModel.GetById 35ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/phing/phing/classes/phing/tasks/ext/WikiPublishTask.php

https://gitlab.com/Isaki/le331.fr
PHP | 435 lines | 211 code | 42 blank | 182 comment | 31 complexity | dc0ce1e815473aa54213a9a31d530707 MD5 | raw file
  1. <?php
  2. /*
  3. * $Id: f156eaee85b94f50511ae48d36758ea1bc57ed63 $
  4. *
  5. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  6. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  7. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  8. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  9. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  10. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  11. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  12. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  13. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  14. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  15. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  16. *
  17. * This software consists of voluntary contributions made by many individuals
  18. * and is licensed under the LGPL. For more information please see
  19. * <http://phing.info>.
  20. */
  21. require_once 'phing/Task.php';
  22. /**
  23. * Publish Wiki document using Wiki API.
  24. *
  25. * @author Piotr Lewandowski <piotr@cassis.pl>
  26. * @package phing.tasks.ext
  27. */
  28. class WikiPublishTask extends Task
  29. {
  30. /**
  31. * Wiki API url
  32. *
  33. * @var string
  34. */
  35. private $apiUrl;
  36. /**
  37. * Wiki API user name
  38. *
  39. * @var string
  40. */
  41. private $apiUser;
  42. /**
  43. * Wiki API password
  44. *
  45. * @var string
  46. */
  47. private $apiPassword;
  48. /**
  49. * Wiki document Id. Document can be identified by title instead.
  50. *
  51. * @var int
  52. */
  53. private $id;
  54. /**
  55. * Wiki document title
  56. *
  57. * @var string
  58. */
  59. private $title;
  60. /**
  61. * Wiki document content
  62. *
  63. * @var string
  64. */
  65. private $content;
  66. /**
  67. * Publishing mode (append, prepend, overwrite).
  68. *
  69. * @var string
  70. */
  71. private $mode = 'append';
  72. /**
  73. * Publish modes map
  74. * @var array
  75. */
  76. private $modeMap = array(
  77. 'overwrite' => 'text',
  78. 'append' => 'appendtext',
  79. 'prepend' => 'prependtext',
  80. );
  81. /**
  82. * Curl handler
  83. *
  84. * @var resource
  85. */
  86. private $curl;
  87. /**
  88. * Wiki api edit token
  89. *
  90. * @var string
  91. */
  92. private $apiEditToken;
  93. /**
  94. * Temporary cookies file
  95. *
  96. * @var string
  97. */
  98. private $cookiesFile;
  99. /**
  100. * @param string $apiPassword
  101. */
  102. public function setApiPassword($apiPassword)
  103. {
  104. $this->apiPassword = $apiPassword;
  105. }
  106. /**
  107. * @return string
  108. */
  109. public function getApiPassword()
  110. {
  111. return $this->apiPassword;
  112. }
  113. /**
  114. * @param string $apiUrl
  115. */
  116. public function setApiUrl($apiUrl)
  117. {
  118. $this->apiUrl = $apiUrl;
  119. }
  120. /**
  121. * @return string
  122. */
  123. public function getApiUrl()
  124. {
  125. return $this->apiUrl;
  126. }
  127. /**
  128. * @param string $apiUser
  129. */
  130. public function setApiUser($apiUser)
  131. {
  132. $this->apiUser = $apiUser;
  133. }
  134. /**
  135. * @return string
  136. */
  137. public function getApiUser()
  138. {
  139. return $this->apiUser;
  140. }
  141. /**
  142. * @param int $id
  143. */
  144. public function setId($id)
  145. {
  146. $this->id = $id;
  147. }
  148. /**
  149. * @return int
  150. */
  151. public function getId()
  152. {
  153. return $this->id;
  154. }
  155. /**
  156. * @param string $mode
  157. * @throws BuildException
  158. */
  159. public function setMode($mode)
  160. {
  161. if (false === isset($this->modeMap[$mode])) {
  162. throw new BuildException('Mode is invalid (' . $mode . ', should be one of ' . implode(
  163. ',',
  164. array_keys($this->modeMap)
  165. ) . ')');
  166. }
  167. $this->mode = $mode;
  168. }
  169. /**
  170. * @return string
  171. */
  172. public function getMode()
  173. {
  174. return $this->mode;
  175. }
  176. /**
  177. * @param string $title
  178. */
  179. public function setTitle($title)
  180. {
  181. $this->title = $title;
  182. }
  183. /**
  184. * @return string
  185. */
  186. public function getTitle()
  187. {
  188. return $this->title;
  189. }
  190. /**
  191. * @param string $content
  192. */
  193. public function setContent($content)
  194. {
  195. $this->content = $content;
  196. }
  197. /**
  198. * @return string
  199. */
  200. public function getContent()
  201. {
  202. return $this->content;
  203. }
  204. /**
  205. * Prepare CURL object
  206. *
  207. * @throws BuildException
  208. */
  209. public function init()
  210. {
  211. $this->cookiesFile = tempnam(sys_get_temp_dir(), 'WikiPublish.' . uniqid() . '.cookies');
  212. $this->curl = curl_init();
  213. if (false === is_resource($this->curl)) {
  214. throw new BuildException('Curl init failed (' . $this->apiUrl . ')');
  215. }
  216. curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true);
  217. curl_setopt($this->curl, CURLOPT_COOKIEJAR, $this->cookiesFile);
  218. curl_setopt($this->curl, CURLOPT_COOKIEFILE, $this->cookiesFile);
  219. }
  220. /**
  221. * The main entry point method
  222. */
  223. public function main()
  224. {
  225. $this->validateAttributes();
  226. $this->callApiLogin();
  227. $this->callApiEdit();
  228. }
  229. /**
  230. * Close curl connection and clean up
  231. */
  232. public function __destruct()
  233. {
  234. if (null !== $this->curl && is_resource($this->curl)) {
  235. curl_close($this->curl);
  236. }
  237. if (null !== $this->cookiesFile && file_exists($this->cookiesFile)) {
  238. unlink($this->cookiesFile);
  239. }
  240. }
  241. /**
  242. * Validates attributes coming in from XML
  243. *
  244. * @throws BuildException
  245. */
  246. private function validateAttributes()
  247. {
  248. if (null === $this->apiUrl) {
  249. throw new BuildException('Wiki apiUrl is required');
  250. }
  251. if (null === $this->id && null === $this->title) {
  252. throw new BuildException('Wiki page id or title is required');
  253. }
  254. }
  255. /**
  256. * Call Wiki webapi login action
  257. *
  258. * @param string|null $token
  259. *
  260. * @throws BuildException
  261. */
  262. private function callApiLogin($token = null)
  263. {
  264. $postData = array('lgname' => $this->apiUser, 'lgpassword' => $this->apiPassword);
  265. if (null !== $token) {
  266. $postData['lgtoken'] = $token;
  267. }
  268. $result = $this->callApi('action=login', $postData);
  269. try {
  270. $this->checkApiResponseResult('login', $result);
  271. } catch (BuildException $e) {
  272. if (null !== $token) {
  273. throw $e;
  274. }
  275. // if token is required then call login again with token
  276. $this->checkApiResponseResult('login', $result, 'NeedToken');
  277. if (isset($result['login']) && isset($result['login']['token'])) {
  278. $this->callApiLogin($result['login']['token']);
  279. } else {
  280. throw $e;
  281. }
  282. }
  283. }
  284. /**
  285. * Call Wiki webapi edit action
  286. */
  287. private function callApiEdit()
  288. {
  289. $this->callApiTokens();
  290. $result = $this->callApi('action=edit&token=' . urlencode($this->apiEditToken), $this->getApiEditData());
  291. $this->checkApiResponseResult('edit', $result);
  292. }
  293. /**
  294. * Return prepared data for Wiki webapi edit action
  295. *
  296. * @return array
  297. */
  298. private function getApiEditData()
  299. {
  300. $result = array(
  301. 'minor' => '',
  302. );
  303. if (null !== $this->title) {
  304. $result['title'] = $this->title;
  305. }
  306. if (null !== $this->id) {
  307. $result['pageid'] = $this->id;
  308. }
  309. $result[$this->modeMap[$this->mode]] = $this->content;
  310. return $result;
  311. }
  312. /**
  313. * Call Wiki webapi tokens action
  314. *
  315. * @throws BuildException
  316. */
  317. private function callApiTokens()
  318. {
  319. $result = $this->callApi('action=tokens&type=edit');
  320. if (false == isset($result['tokens']) || false == isset($result['tokens']['edittoken'])) {
  321. throw new BuildException('Wiki token not found');
  322. }
  323. $this->apiEditToken = $result['tokens']['edittoken'];
  324. }
  325. /**
  326. * Call Wiki webapi
  327. *
  328. * @param string $queryString
  329. * @param array|null $postData
  330. *
  331. * @return array
  332. * @throws BuildException
  333. */
  334. protected function callApi($queryString, $postData = null)
  335. {
  336. $this->setPostData($postData);
  337. $url = $this->apiUrl . '?' . $queryString . '&format=php';
  338. curl_setopt($this->curl, CURLOPT_URL, $url);
  339. $response = curl_exec($this->curl);
  340. $responseCode = curl_getinfo($this->curl, CURLINFO_HTTP_CODE);
  341. if (200 !== $responseCode) {
  342. throw new BuildException('Wiki webapi call failed (http response ' . $responseCode . ')');
  343. }
  344. $result = @unserialize($response);
  345. if (false === $result) {
  346. throw new BuildException('Couldn\'t unserialize Wiki webapi response');
  347. }
  348. return $result;
  349. }
  350. /**
  351. * Set POST data for curl call
  352. *
  353. * @param array|null $data
  354. */
  355. private function setPostData($data = null)
  356. {
  357. if (null === $data) {
  358. curl_setopt($this->curl, CURLOPT_POST, false);
  359. return;
  360. }
  361. $postData = '';
  362. foreach ($data as $key => $value) {
  363. $postData .= urlencode($key) . '=' . urlencode($value) . '&';
  364. }
  365. if ($postData != '') {
  366. curl_setopt($this->curl, CURLOPT_POST, true);
  367. curl_setopt($this->curl, CURLOPT_POSTFIELDS, substr($postData, 0, -1));
  368. }
  369. }
  370. /**
  371. * Validate Wiki webapi response
  372. *
  373. * @param string $action
  374. * @param array $response
  375. * @param string $expect
  376. *
  377. * @throws BuildException
  378. */
  379. private function checkApiResponseResult($action, $response, $expect = 'Success')
  380. {
  381. if (isset($response['error'])) {
  382. throw new BuildException(
  383. 'Wiki response error (action: ' . $action . ', error code: ' . $response['error']['code'] . ')');
  384. }
  385. if (false == isset($response[$action]) || false == isset($response[$action]['result'])) {
  386. throw new BuildException('Wiki response result not found (action: ' . $action . ')');
  387. }
  388. if ($response[$action]['result'] !== $expect) {
  389. throw new BuildException(
  390. 'Unexpected Wiki response result ' . $response[$action]['result'] . ' (expected: ' . $expect . ')');
  391. }
  392. }
  393. }