Bootstrap.php 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985
  1. <?php declare(strict_types=1);
  2. use Google\Cloud\Core\Exception\BadRequestException;
  3. use Google\Cloud\Core\Exception\NotFoundException;
  4. use Google\Cloud\Storage\Bucket;
  5. use Google\Cloud\Storage\Connection\ConnectionInterface;
  6. use Google\Cloud\Storage\StorageClient;
  7. use Google\Cloud\Storage\StorageObject;
  8. use PrivateBin\Persistence\ServerSalt;
  9. error_reporting(E_ALL | E_STRICT);
  10. // change this, if your php files and data is outside of your webservers document root
  11. if (!defined('PUBLIC_PATH')) {
  12. define('PUBLIC_PATH', '..');
  13. }
  14. if (!defined('PATH')) {
  15. define('PATH', '..' . DIRECTORY_SEPARATOR);
  16. }
  17. if (!defined('CONF')) {
  18. define('CONF', PATH . 'cfg' . DIRECTORY_SEPARATOR . 'conf.php');
  19. }
  20. if (!defined('CONF_SAMPLE')) {
  21. define('CONF_SAMPLE', PATH . 'cfg' . DIRECTORY_SEPARATOR . 'conf.sample.php');
  22. }
  23. require PATH . 'vendor/autoload.php';
  24. Helper::updateSubresourceIntegrity();
  25. /**
  26. * Class Helper provides unit tests pastes and comments of various formats
  27. */
  28. class Helper
  29. {
  30. /**
  31. * example ID of a paste
  32. *
  33. * @var string
  34. */
  35. private static $pasteid = '5b65a01b43987bc2';
  36. /**
  37. * example paste version 1
  38. *
  39. * @var array
  40. */
  41. private static $pasteV1 = array(
  42. 'data' => '{"iv":"EN39/wd5Nk8HAiSG2K5AsQ","v":1,"iter":1000,"ks":128,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"QKN1DBXe5PI","ct":"8hA83xDdXjD7K2qfmw5NdA"}',
  43. 'attachment' => '{"iv":"Pd4pOKWkmDTT9uPwVwd5Ag","v":1,"iter":1000,"ks":128,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"ZIUhFTliVz4","ct":"6nOCU3peNDclDDpFtJEBKA"}',
  44. 'attachmentname' => '{"iv":"76MkAtOGC4oFogX/aSMxRA","v":1,"iter":1000,"ks":128,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"ZIUhFTliVz4","ct":"b6Ae/U1xJdsX/+lATud4sQ"}',
  45. 'meta' => array(
  46. 'formatter' => 'plaintext',
  47. 'postdate' => 1344803344,
  48. 'opendiscussion' => true,
  49. ),
  50. );
  51. /**
  52. * example paste version 2
  53. *
  54. * @var array
  55. */
  56. private static $pasteV2 = array(
  57. 'adata' => array(
  58. array(
  59. 'gMSNoLOk4z0RnmsYwXZ8mw==',
  60. 'TZO+JWuIuxs=',
  61. 100000,
  62. 256,
  63. 128,
  64. 'aes',
  65. 'gcm',
  66. 'zlib',
  67. ),
  68. 'plaintext',
  69. 1,
  70. 0,
  71. ),
  72. 'meta' => array(
  73. 'expire' => '5min',
  74. ),
  75. 'v' => 2,
  76. 'ct' => 'ME5JF/YBEijp2uYMzLZozbKtWc5wfy6R59NBb7SmRig=',
  77. );
  78. /**
  79. * example ID of a comment
  80. *
  81. * @var string
  82. */
  83. private static $commentid = '5a52eebf11c4c94b';
  84. /**
  85. * example comment
  86. *
  87. * @var array
  88. */
  89. private static $commentV1 = array(
  90. 'data' => '{"iv":"Pd4pOKWkmDTT9uPwVwd5Ag","v":1,"iter":1000,"ks":128,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"ZIUhFTliVz4","ct":"6nOCU3peNDclDDpFtJEBKA"}',
  91. 'meta' => array(
  92. 'nickname' => '{"iv":"76MkAtOGC4oFogX/aSMxRA","v":1,"iter":1000,"ks":128,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"ZIUhFTliVz4","ct":"b6Ae/U1xJdsX/+lATud4sQ"}',
  93. 'vizhash' => 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAABGUlEQVQokWOsl5/94983CNKQMjnxaOePf98MeKwPfNjkLZ3AgARab6b9+PeNEVnDj3/ff/z7ZiHnzsDA8Pv7H2TVPJw8EAYLAwb48OaVgIgYKycLsrYv378wMDB8//qdCVMDRA9EKSsnCwRBxNsepaLboMFlyMDAICAi9uHNK24GITQ/MDAwoNhgIGMLtwGrzegaLjw5jMz9+vUdnN17uwDCQDhJgk0O07yvX9+teDX1x79v6DYIsIjgcgMaYGFgYOBg4kJx2JejkAiBxAw+PzAwMNz4dp6wDXDw4MdNNOl0rWYsNkD89OLXI/xmo9sgzatJjAYmBgYGDiauD3/ePP18nVgb4MF89+M5ZX6js293wUMpnr8KTQMAxsCJnJ30apMAAAAASUVORK5CYII=',
  94. 'postdate' => 1344803528,
  95. ),
  96. );
  97. /**
  98. * JS files and their SRI hashes
  99. *
  100. * @var array
  101. */
  102. private static $hashes = array();
  103. /**
  104. * get example paste ID
  105. *
  106. * @return string
  107. */
  108. public static function getPasteId()
  109. {
  110. return self::$pasteid;
  111. }
  112. /**
  113. * get example paste, as stored on server
  114. *
  115. * @param int $version
  116. * @param array $meta
  117. * @return array
  118. */
  119. public static function getPaste($version = 2, array $meta = array())
  120. {
  121. $example = self::getPasteWithAttachment($version, $meta);
  122. // v1 has the attachment stored in a separate property
  123. if ($version === 1) {
  124. unset($example['attachment'], $example['attachmentname']);
  125. }
  126. return $example;
  127. }
  128. /**
  129. * get example paste with attachment, as stored on server
  130. *
  131. * @param int $version
  132. * @param array $meta
  133. * @return array
  134. */
  135. public static function getPasteWithAttachment($version = 2, array $meta = array())
  136. {
  137. $example = $version === 1 ? self::$pasteV1 : self::$pasteV2;
  138. $example['meta']['salt'] = ServerSalt::generate();
  139. $example['meta'] = array_merge($example['meta'], $meta);
  140. return $example;
  141. }
  142. /**
  143. * get example paste, as decoded from POST by the request object
  144. *
  145. * @param int $version
  146. * @param array $meta
  147. * @return array
  148. */
  149. public static function getPastePost($version = 2, array $meta = array())
  150. {
  151. $example = self::getPaste($version, $meta);
  152. if ($version == 2) {
  153. $example['meta'] = array('expire' => $example['meta']['expire']);
  154. } else {
  155. unset($example['meta']['postdate']);
  156. }
  157. return $example;
  158. }
  159. /**
  160. * get example paste, as received via POST by the user
  161. *
  162. * @param int $version
  163. * @param array $meta
  164. * @return array
  165. */
  166. public static function getPasteJson($version = 2, array $meta = array())
  167. {
  168. return json_encode(self::getPastePost($version, $meta));
  169. }
  170. /**
  171. * get example paste ID
  172. *
  173. * @return string
  174. */
  175. public static function getCommentId()
  176. {
  177. return self::$commentid;
  178. }
  179. /**
  180. * get example comment, as stored on server
  181. *
  182. * @param int $version
  183. * @param array $meta
  184. * @return array
  185. */
  186. public static function getComment($version = 2, array $meta = array())
  187. {
  188. $example = $version === 1 ? self::$commentV1 : self::$pasteV2;
  189. if ($version === 2) {
  190. $example['adata'] = $example['adata'][0];
  191. $example['pasteid'] = $example['parentid'] = self::getPasteId();
  192. $example['meta']['created'] = self::$commentV1['meta']['postdate'];
  193. $example['meta']['icon'] = self::$commentV1['meta']['vizhash'];
  194. unset($example['meta']['expire']);
  195. }
  196. $example['meta'] = array_merge($example['meta'], $meta);
  197. return $example;
  198. }
  199. /**
  200. * get example comment, as decoded from POST by the request object
  201. *
  202. * @param int $version
  203. * @return array
  204. */
  205. public static function getCommentPost()
  206. {
  207. $example = self::getComment();
  208. unset($example['meta']);
  209. return $example;
  210. }
  211. /**
  212. * get example comment, as received via POST by user
  213. *
  214. * @param int $version
  215. * @return array
  216. */
  217. public static function getCommentJson()
  218. {
  219. return json_encode(self::getCommentPost());
  220. }
  221. /**
  222. * delete directory and all its contents recursively
  223. *
  224. * @param string $path
  225. * @throws Exception
  226. */
  227. public static function rmDir($path)
  228. {
  229. if (is_dir($path)) {
  230. $path .= DIRECTORY_SEPARATOR;
  231. $dir = dir($path);
  232. while (false !== ($file = $dir->read())) {
  233. if ($file != '.' && $file != '..') {
  234. if (is_dir($path . $file)) {
  235. self::rmDir($path . $file);
  236. } elseif (is_file($path . $file)) {
  237. if (!unlink($path . $file)) {
  238. throw new Exception('Error deleting file "' . $path . $file . '".');
  239. }
  240. }
  241. }
  242. }
  243. $dir->close();
  244. if (!rmdir($path)) {
  245. throw new Exception('Error deleting directory "' . $path . '".');
  246. }
  247. }
  248. }
  249. /**
  250. * create a backup of the config file
  251. *
  252. * @return void
  253. */
  254. public static function confBackup()
  255. {
  256. if (!is_file(CONF . '.bak') && is_file(CONF)) {
  257. rename(CONF, CONF . '.bak');
  258. }
  259. if (!is_file(CONF_SAMPLE . '.bak') && is_file(CONF_SAMPLE)) {
  260. copy(CONF_SAMPLE, CONF_SAMPLE . '.bak');
  261. }
  262. }
  263. /**
  264. * restor backup of the config file
  265. *
  266. * @return void
  267. */
  268. public static function confRestore()
  269. {
  270. if (is_file(CONF . '.bak')) {
  271. rename(CONF . '.bak', CONF);
  272. }
  273. if (is_file(CONF_SAMPLE . '.bak')) {
  274. rename(CONF_SAMPLE . '.bak', CONF_SAMPLE);
  275. }
  276. }
  277. /**
  278. * create ini file
  279. *
  280. * @param string $pathToFile
  281. * @param array $values
  282. */
  283. public static function createIniFile($pathToFile, array $values)
  284. {
  285. if (count($values)) {
  286. @unlink($pathToFile);
  287. $ini = fopen($pathToFile, 'a');
  288. foreach ($values as $section => $options) {
  289. fwrite($ini, "[$section]" . PHP_EOL);
  290. foreach ($options as $option => $setting) {
  291. if (is_null($setting)) {
  292. continue;
  293. } elseif (is_string($setting)) {
  294. $setting = '"' . $setting . '"';
  295. } elseif (is_array($setting)) {
  296. foreach ($setting as $key => $value) {
  297. if (is_null($value)) {
  298. $value = 'null';
  299. } elseif (is_string($value)) {
  300. $value = '"' . $value . '"';
  301. } else {
  302. $value = var_export($value, true);
  303. }
  304. fwrite($ini, $option . "[$key] = $value" . PHP_EOL);
  305. }
  306. continue;
  307. } else {
  308. $setting = var_export($setting, true);
  309. }
  310. fwrite($ini, "$option = $setting" . PHP_EOL);
  311. }
  312. fwrite($ini, PHP_EOL);
  313. }
  314. fclose($ini);
  315. }
  316. }
  317. /**
  318. * a var_export that returns arrays without line breaks
  319. * by linus@flowingcreativity.net via php.net
  320. *
  321. * @param mixed $var
  322. * @param bool $return
  323. * @return void|string
  324. */
  325. public static function varExportMin($var, $return = false)
  326. {
  327. if (is_array($var)) {
  328. $toImplode = array();
  329. foreach ($var as $key => $value) {
  330. $toImplode[] = var_export($key, true) . ' => ' . self::varExportMin($value, true);
  331. }
  332. $code = 'array(' . implode(', ', $toImplode) . ')';
  333. if ($return) {
  334. return $code;
  335. } else {
  336. echo $code;
  337. }
  338. } else {
  339. return var_export($var, $return);
  340. }
  341. }
  342. /**
  343. * update all templates with the latest SRI hashes for all JS files
  344. *
  345. * @return void
  346. */
  347. public static function updateSubresourceIntegrity()
  348. {
  349. foreach (new GlobIterator(PATH . 'js' . DIRECTORY_SEPARATOR . '*.js') as $file) {
  350. if ($file->getBasename() == 'common.js') {
  351. continue; // ignore JS unit test bootstrap
  352. }
  353. self::$hashes[$file->getBasename()] = base64_encode(
  354. hash('sha512', file_get_contents($file->getPathname()), true)
  355. );
  356. }
  357. $counter = 0;
  358. $file = PATH . 'lib' . DIRECTORY_SEPARATOR . 'Configuration.php';
  359. $content = preg_replace_callback(
  360. '#\'js/([a-z0-9.-]+.js)(\' +)=\> \'[^\']*\',#',
  361. function ($matches) use (&$counter) {
  362. if (array_key_exists($matches[1], Helper::$hashes)) {
  363. ++$counter;
  364. return '\'js/' . $matches[1] . $matches[2] .
  365. '=> \'sha512-' . Helper::$hashes[$matches[1]] . '\',';
  366. } else {
  367. throw new Exception('SRI hash for file js/' . $matches[1] . ' not found, please add the missing file or remove it from lib/Configuration.php.');
  368. }
  369. },
  370. file_get_contents($file)
  371. );
  372. file_put_contents($file, $content);
  373. if ($counter != count(self::$hashes)) {
  374. throw new Exception('Mismatch between ' . count(self::$hashes) . ' found js files and ' . $counter . ' SRI hashes in lib/Configuration.php, please update lib/Configuration.php to match the list of js files.');
  375. }
  376. }
  377. }
  378. /**
  379. * Class BucketStub stubs a GCS bucket.
  380. */
  381. class BucketStub extends Bucket
  382. {
  383. public $_objects;
  384. private $_name;
  385. private $_info;
  386. private $_connection;
  387. private $_client;
  388. public function __construct(ConnectionInterface $connection, $name, array $info = array(), $client = null)
  389. {
  390. $this->_name = $name;
  391. $this->_info = $info;
  392. $this->_connection = $connection;
  393. $this->_objects = array();
  394. $this->_client = $client;
  395. }
  396. public function acl()
  397. {
  398. throw new BadMethodCallException('not supported by this stub');
  399. }
  400. public function defaultAcl()
  401. {
  402. throw new BadMethodCallException('not supported by this stub');
  403. }
  404. public function exists(array $options = array())
  405. {
  406. return true;
  407. }
  408. public function upload($data, array $options = array())
  409. {
  410. if (!is_string($data) || !key_exists('name', $options)) {
  411. throw new BadMethodCallException('not supported by this stub');
  412. }
  413. $name = $options['name'];
  414. $generation = '1';
  415. $o = new StorageObjectStub($this->_connection, $name, $this, $generation, $options);
  416. $this->_objects[$options['name']] = $o;
  417. $o->setData($data);
  418. }
  419. public function uploadAsync($data, array $options = array())
  420. {
  421. throw new BadMethodCallException('not supported by this stub');
  422. }
  423. public function getResumableUploader($data, array $options = array())
  424. {
  425. throw new BadMethodCallException('not supported by this stub');
  426. }
  427. public function getStreamableUploader($data, array $options = array())
  428. {
  429. throw new BadMethodCallException('not supported by this stub');
  430. }
  431. public function object($name, array $options = array())
  432. {
  433. if (key_exists($name, $this->_objects)) {
  434. return $this->_objects[$name];
  435. } else {
  436. return new StorageObjectStub($this->_connection, $name, $this, null, $options);
  437. }
  438. }
  439. public function objects(array $options = array())
  440. {
  441. $prefix = key_exists('prefix', $options) ? $options['prefix'] : '';
  442. return new CallbackFilterIterator(
  443. new ArrayIterator($this->_objects),
  444. function ($current, $key, $iterator) use ($prefix) {
  445. return substr($key, 0, strlen($prefix)) == $prefix;
  446. }
  447. );
  448. }
  449. public function createNotification($topic, array $options = array())
  450. {
  451. throw new BadMethodCallException('not supported by this stub');
  452. }
  453. public function notification($id)
  454. {
  455. throw new BadMethodCallException('not supported by this stub');
  456. }
  457. public function notifications(array $options = array())
  458. {
  459. throw new BadMethodCallException('not supported by this stub');
  460. }
  461. public function delete(array $options = array())
  462. {
  463. $this->_client->deleteBucket($this->_name);
  464. }
  465. public function update(array $options = array())
  466. {
  467. throw new BadMethodCallException('not supported by this stub');
  468. }
  469. public function compose(array $sourceObjects, $name, array $options = array())
  470. {
  471. throw new BadMethodCallException('not supported by this stub');
  472. }
  473. public function info(array $options = array())
  474. {
  475. throw new BadMethodCallException('not supported by this stub');
  476. }
  477. public function reload(array $options = array())
  478. {
  479. throw new BadMethodCallException('not supported by this stub');
  480. }
  481. public function name()
  482. {
  483. return $this->_name;
  484. }
  485. public static function lifecycle(array $lifecycle = array())
  486. {
  487. throw new BadMethodCallException('not supported by this stub');
  488. }
  489. public function currentLifecycle(array $options = array())
  490. {
  491. throw new BadMethodCallException('not supported by this stub');
  492. }
  493. public function isWritable($file = null)
  494. {
  495. throw new BadMethodCallException('not supported by this stub');
  496. }
  497. public function iam()
  498. {
  499. throw new BadMethodCallException('not supported by this stub');
  500. }
  501. public function lockRetentionPolicy(array $options = array())
  502. {
  503. throw new BadMethodCallException('not supported by this stub');
  504. }
  505. public function signedUrl($expires, array $options = array())
  506. {
  507. throw new BadMethodCallException('not supported by this stub');
  508. }
  509. public function generateSignedPostPolicyV4($objectName, $expires, array $options = array())
  510. {
  511. throw new BadMethodCallException('not supported by this stub');
  512. }
  513. }
  514. /**
  515. * Class StorageObjectStub stubs a GCS storage object.
  516. */
  517. class StorageObjectStub extends StorageObject
  518. {
  519. private $_name;
  520. private $_data;
  521. private $_info;
  522. private $_bucket;
  523. private $_generation;
  524. private $_exists = false;
  525. private $_connection;
  526. public function __construct(ConnectionInterface $connection, $name, $bucket, $generation = null, array $info = array(), $encryptionKey = null, $encryptionKeySHA256 = null)
  527. {
  528. $this->_name = $name;
  529. $this->_bucket = $bucket;
  530. $this->_generation = $generation;
  531. $this->_info = $info;
  532. $this->_connection = $connection;
  533. $timeCreated = new DateTime();
  534. $this->_info['metadata']['timeCreated'] = $timeCreated->format('Y-m-d\TH:i:s.u\Z');
  535. }
  536. public function acl()
  537. {
  538. throw new BadMethodCallException('not supported by this stub');
  539. }
  540. public function exists(array $options = array())
  541. {
  542. return key_exists($this->_name, $this->_bucket->_objects);
  543. }
  544. /**
  545. * @throws NotFoundException
  546. */
  547. public function delete(array $options = array())
  548. {
  549. if (key_exists($this->_name, $this->_bucket->_objects)) {
  550. unset($this->_bucket->_objects[$this->_name]);
  551. } else {
  552. throw new NotFoundException('key ' . $this->_name . ' not found.');
  553. }
  554. }
  555. /**
  556. * @throws NotFoundException
  557. */
  558. public function update(array $metadata, array $options = array())
  559. {
  560. if (!$this->_exists) {
  561. throw new NotFoundException('key ' . $this->_name . ' not found.');
  562. }
  563. $this->_info = $metadata;
  564. }
  565. public function copy($destination, array $options = array())
  566. {
  567. throw new BadMethodCallException('not supported by this stub');
  568. }
  569. public function rewrite($destination, array $options = array())
  570. {
  571. throw new BadMethodCallException('not supported by this stub');
  572. }
  573. public function rename($name, array $options = array())
  574. {
  575. throw new BadMethodCallException('not supported by this stub');
  576. }
  577. /**
  578. * @throws NotFoundException
  579. */
  580. public function downloadAsString(array $options = array())
  581. {
  582. if (!$this->_exists) {
  583. throw new NotFoundException('key ' . $this->_name . ' not found.');
  584. }
  585. return $this->_data;
  586. }
  587. public function downloadToFile($path, array $options = array())
  588. {
  589. throw new BadMethodCallException('not supported by this stub');
  590. }
  591. public function downloadAsStream(array $options = array())
  592. {
  593. throw new BadMethodCallException('not supported by this stub');
  594. }
  595. public function downloadAsStreamAsync(array $options = array())
  596. {
  597. throw new BadMethodCallException('not supported by this stub');
  598. }
  599. public function signedUrl($expires, array $options = array())
  600. {
  601. throw new BadMethodCallException('not supported by this stub');
  602. }
  603. public function signedUploadUrl($expires, array $options = array())
  604. {
  605. throw new BadMethodCallException('not supported by this stub');
  606. }
  607. public function beginSignedUploadSession(array $options = array())
  608. {
  609. throw new BadMethodCallException('not supported by this stub');
  610. }
  611. public function info(array $options = array())
  612. {
  613. return key_exists('metadata',$this->_info) ? $this->_info['metadata'] : array();
  614. }
  615. public function reload(array $options = array())
  616. {
  617. throw new BadMethodCallException('not supported by this stub');
  618. }
  619. public function name()
  620. {
  621. return $this->_name;
  622. }
  623. public function identity()
  624. {
  625. throw new BadMethodCallException('not supported by this stub');
  626. }
  627. public function gcsUri()
  628. {
  629. return sprintf(
  630. 'gs://%s/%s',
  631. $this->_bucket->name(),
  632. $this->_name
  633. );
  634. }
  635. public function setData($data)
  636. {
  637. $this->_data = $data;
  638. $this->_exists = true;
  639. }
  640. }
  641. /**
  642. * Class ConnectionInterfaceStub required for the stubs.
  643. */
  644. class ConnectionInterfaceStub implements ConnectionInterface
  645. {
  646. public function deleteAcl(array $args = array())
  647. {
  648. throw new BadMethodCallException('not supported by this stub');
  649. }
  650. public function getAcl(array $args = array())
  651. {
  652. throw new BadMethodCallException('not supported by this stub');
  653. }
  654. public function listAcl(array $args = array())
  655. {
  656. throw new BadMethodCallException('not supported by this stub');
  657. }
  658. public function insertAcl(array $args = array())
  659. {
  660. throw new BadMethodCallException('not supported by this stub');
  661. }
  662. public function patchAcl(array $args = array())
  663. {
  664. throw new BadMethodCallException('not supported by this stub');
  665. }
  666. public function deleteBucket(array $args = array())
  667. {
  668. throw new BadMethodCallException('not supported by this stub');
  669. }
  670. public function getBucket(array $args = array())
  671. {
  672. throw new BadMethodCallException('not supported by this stub');
  673. }
  674. public function listBuckets(array $args = array())
  675. {
  676. throw new BadMethodCallException('not supported by this stub');
  677. }
  678. public function insertBucket(array $args = array())
  679. {
  680. throw new BadMethodCallException('not supported by this stub');
  681. }
  682. public function getBucketIamPolicy(array $args)
  683. {
  684. throw new BadMethodCallException('not supported by this stub');
  685. }
  686. public function setBucketIamPolicy(array $args)
  687. {
  688. throw new BadMethodCallException('not supported by this stub');
  689. }
  690. public function testBucketIamPermissions(array $args)
  691. {
  692. throw new BadMethodCallException('not supported by this stub');
  693. }
  694. public function patchBucket(array $args = array())
  695. {
  696. throw new BadMethodCallException('not supported by this stub');
  697. }
  698. public function deleteObject(array $args = array())
  699. {
  700. throw new BadMethodCallException('not supported by this stub');
  701. }
  702. public function restoreObject(array $args = array())
  703. {
  704. throw new BadMethodCallException('not supported by this stub');
  705. }
  706. public function copyObject(array $args = array())
  707. {
  708. throw new BadMethodCallException('not supported by this stub');
  709. }
  710. public function rewriteObject(array $args = array())
  711. {
  712. throw new BadMethodCallException('not supported by this stub');
  713. }
  714. public function composeObject(array $args = array())
  715. {
  716. throw new BadMethodCallException('not supported by this stub');
  717. }
  718. public function getObject(array $args = array())
  719. {
  720. throw new BadMethodCallException('not supported by this stub');
  721. }
  722. public function listObjects(array $args = array())
  723. {
  724. throw new BadMethodCallException('not supported by this stub');
  725. }
  726. public function patchObject(array $args = array())
  727. {
  728. throw new BadMethodCallException('not supported by this stub');
  729. }
  730. public function downloadObject(array $args = array())
  731. {
  732. throw new BadMethodCallException('not supported by this stub');
  733. }
  734. public function insertObject(array $args = array())
  735. {
  736. throw new BadMethodCallException('not supported by this stub');
  737. }
  738. public function getNotification(array $args = array())
  739. {
  740. throw new BadMethodCallException('not supported by this stub');
  741. }
  742. public function deleteNotification(array $args = array())
  743. {
  744. throw new BadMethodCallException('not supported by this stub');
  745. }
  746. public function insertNotification(array $args = array())
  747. {
  748. throw new BadMethodCallException('not supported by this stub');
  749. }
  750. public function listNotifications(array $args = array())
  751. {
  752. throw new BadMethodCallException('not supported by this stub');
  753. }
  754. public function getServiceAccount(array $args = array())
  755. {
  756. throw new BadMethodCallException('not supported by this stub');
  757. }
  758. public function lockRetentionPolicy(array $args = array())
  759. {
  760. throw new BadMethodCallException('not supported by this stub');
  761. }
  762. public function createHmacKey(array $args = array())
  763. {
  764. throw new BadMethodCallException('not supported by this stub');
  765. }
  766. public function deleteHmacKey(array $args = array())
  767. {
  768. throw new BadMethodCallException('not supported by this stub');
  769. }
  770. public function getHmacKey(array $args = array())
  771. {
  772. throw new BadMethodCallException('not supported by this stub');
  773. }
  774. public function updateHmacKey(array $args = array())
  775. {
  776. throw new BadMethodCallException('not supported by this stub');
  777. }
  778. public function listHmacKeys(array $args = array())
  779. {
  780. throw new BadMethodCallException('not supported by this stub');
  781. }
  782. }
  783. /**
  784. * Class StorageClientStub provides a limited stub for performing the unit test
  785. */
  786. class StorageClientStub extends StorageClient
  787. {
  788. private $_config = null;
  789. private $_connection = null;
  790. private static $_buckets = array();
  791. public function __construct(array $config = array())
  792. {
  793. $this->_config = $config;
  794. $this->_connection = new ConnectionInterfaceStub();
  795. }
  796. public function bucket($name, $userProject = false)
  797. {
  798. if (!key_exists($name, self::$_buckets)) {
  799. $b = new BucketStub($this->_connection, $name, array(), $this);
  800. self::$_buckets[$name] = $b;
  801. }
  802. return self::$_buckets[$name];
  803. }
  804. /**
  805. * @throws \Google\Cloud\Core\Exception\NotFoundException
  806. */
  807. public function deleteBucket($name)
  808. {
  809. if (key_exists($name, self::$_buckets)) {
  810. unset(self::$_buckets[$name]);
  811. } else {
  812. throw new NotFoundException();
  813. }
  814. }
  815. public function buckets(array $options = array())
  816. {
  817. throw new BadMethodCallException('not supported by this stub');
  818. }
  819. public function registerStreamWrapper($protocol = null)
  820. {
  821. throw new BadMethodCallException('not supported by this stub');
  822. }
  823. public function unregisterStreamWrapper($protocol = null)
  824. {
  825. throw new BadMethodCallException('not supported by this stub');
  826. }
  827. public function signedUrlUploader($uri, $data, array $options = array())
  828. {
  829. throw new BadMethodCallException('not supported by this stub');
  830. }
  831. public function timestamp(\DateTimeInterface $timestamp, $nanoSeconds = null)
  832. {
  833. throw new BadMethodCallException('not supported by this stub');
  834. }
  835. public function getServiceAccount(array $options = array())
  836. {
  837. throw new BadMethodCallException('not supported by this stub');
  838. }
  839. public function hmacKeys(array $options = array())
  840. {
  841. throw new BadMethodCallException('not supported by this stub');
  842. }
  843. public function hmacKey($accessId, $projectId = null, array $metadata = array())
  844. {
  845. throw new BadMethodCallException('not supported by this stub');
  846. }
  847. public function createHmacKey($serviceAccountEmail, array $options = array())
  848. {
  849. throw new BadMethodCallException('not supported by this stub');
  850. }
  851. public function createBucket($name, array $options = array())
  852. {
  853. if (key_exists($name, self::$_buckets)) {
  854. throw new BadRequestException('already exists');
  855. }
  856. $b = new BucketStub($this->_connection, $name, array(), $this);
  857. self::$_buckets[$name] = $b;
  858. return $b;
  859. }
  860. }