/libraries/Zend/Session/Configuration/StandardConfiguration.php

https://github.com/kiranatama/sagalaya · PHP · 707 lines · 338 code · 63 blank · 306 comment · 45 complexity · 818723544329f5cc9ac079779312a769 MD5 · raw file

  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-webat this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Session
  17. * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
  18. * @license http://framework.zend.com/license/new-bsd New BSD License
  19. */
  20. namespace Zend\Session\Configuration;
  21. use Zend\Session\Configuration\ConfigurationInterface as Configurable,
  22. Zend\Session\Exception,
  23. Zend\Validator\Hostname as HostnameValidator,
  24. Zend\Filter\Word\CamelCaseToUnderscore as CamelCaseToUnderscoreFilter;
  25. /**
  26. * Standard session configuration
  27. *
  28. * @category Zend
  29. * @package Zend_Session
  30. * @subpackage Configuration
  31. * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
  32. * @license http://framework.zend.com/license/new-bsd New BSD License
  33. */
  34. class StandardConfiguration implements Configurable
  35. {
  36. /**
  37. * @var Zend\Filter Filter to convert CamelCase to underscore_separated
  38. */
  39. protected $camelCaseToUnderscoreFilter;
  40. /**
  41. * @var string session.cookie_domain
  42. */
  43. protected $cookieDomain;
  44. /**
  45. * @var bool session.cookie_httponly
  46. */
  47. protected $cookieHttpOnly;
  48. /**
  49. * @var int session.cookie_lifetime
  50. */
  51. protected $cookieLifetime;
  52. /**
  53. * @var string session.cookie_path
  54. */
  55. protected $cookiePath;
  56. /**
  57. * @var bool session.cookie_secure
  58. */
  59. protected $cookieSecure;
  60. /**
  61. * @var string session.name
  62. */
  63. protected $name;
  64. /**
  65. * @var array All options
  66. */
  67. protected $options = array();
  68. /**
  69. * @var int remember_me_seconds
  70. */
  71. protected $rememberMeSeconds;
  72. /**
  73. * @var string session.save_path
  74. */
  75. protected $savePath;
  76. /**
  77. * @var bool session.use_cookies
  78. */
  79. protected $useCookies;
  80. /**
  81. * Set storage option in backend configuration store
  82. *
  83. * Does nothing in this implementation; others might use it to set things
  84. * such as INI settings.
  85. *
  86. * @param string $storageName
  87. * @param mixed $storageValue
  88. * @return StandardConfiguration
  89. */
  90. public function setStorageOption($storageName, $storageValue)
  91. {
  92. }
  93. /**
  94. * Retrieve a storage option from a backend configuration store
  95. *
  96. * Used to retrieve default values from a backend configuration store.
  97. *
  98. * @param string $storageOption
  99. * @return mixed
  100. */
  101. public function getStorageOption($storageOption)
  102. {
  103. return null;
  104. }
  105. /**
  106. * Set session.save_path
  107. *
  108. * @param string $savePath
  109. * @return StandardConfiguration
  110. * @throws Exception\InvalidArgumentException on invalid path
  111. */
  112. public function setSavePath($savePath)
  113. {
  114. if (!is_dir($savePath)) {
  115. throw new Exception\InvalidArgumentException('Invalid save_path provided');
  116. }
  117. $this->savePath = $savePath;
  118. $this->setStorageOption('save_path', $savePath);
  119. return $this;
  120. }
  121. /**
  122. * Set session.save_path
  123. *
  124. * @return string|null
  125. */
  126. public function getSavePath()
  127. {
  128. if (null === $this->savePath) {
  129. $this->savePath = $this->getStorageOption('save_path');
  130. }
  131. return $this->savePath;
  132. }
  133. /**
  134. * Set session.name
  135. *
  136. * @param string $name
  137. * @return StandardConfiguration
  138. * @throws Exception\InvalidArgumentException
  139. */
  140. public function setName($name)
  141. {
  142. $this->name = (string) $name;
  143. if (empty($this->name)) {
  144. throw new Exception\InvalidArgumentException('Invalid session name; cannot be empty');
  145. }
  146. $this->setStorageOption('name', $this->name);
  147. return $this;
  148. }
  149. /**
  150. * Get session.name
  151. *
  152. * @return null|string
  153. */
  154. public function getName()
  155. {
  156. if (null === $this->name) {
  157. $this->name = $this->getStorageOption('name');
  158. }
  159. return $this->name;
  160. }
  161. /**
  162. * Set session.gc_probability
  163. *
  164. * @param int $gcProbability
  165. * @return StandardConfiguration
  166. * @throws Exception\InvalidArgumentException
  167. */
  168. public function setGcProbability($gcProbability)
  169. {
  170. if (!is_numeric($gcProbability)) {
  171. throw new Exception\InvalidArgumentException('Invalid gc_probability; must be numeric');
  172. }
  173. $gcProbability = (int) $gcProbability;
  174. if (1 > $gcProbability || 100 < $gcProbability) {
  175. throw new Exception\InvalidArgumentException('Invalid gc_probability; must be a percentage');
  176. }
  177. $this->setOption('gc_probability', $gcProbability);
  178. $this->setStorageOption('gc_probability', $gcProbability);
  179. return $this;
  180. }
  181. /**
  182. * Set session.gc_divisor
  183. *
  184. * @param int $gcDivisor
  185. * @return StandardConfiguration
  186. * @throws Exception\InvalidArgumentException
  187. */
  188. public function setGcDivisor($gcDivisor)
  189. {
  190. if (!is_numeric($gcDivisor)) {
  191. throw new Exception\InvalidArgumentException('Invalid gc_divisor; must be numeric');
  192. }
  193. $gcDivisor = (int) $gcDivisor;
  194. if (1 > $gcDivisor) {
  195. throw new Exception\InvalidArgumentException('Invalid gc_divisor; must be a positive integer');
  196. }
  197. $this->setOption('gc_divisor', $gcDivisor);
  198. $this->setStorageOption('gc_divisor', $gcDivisor);
  199. return $this;
  200. }
  201. /**
  202. * Set gc.maxlifetime
  203. *
  204. * @param int $gcMaxlifetime
  205. * @return StandardConfiguration
  206. * @throws Exception\InvalidArgumentException
  207. */
  208. public function setGcMaxlifetime($gcMaxlifetime)
  209. {
  210. if (!is_numeric($gcMaxlifetime)) {
  211. throw new Exception\InvalidArgumentException('Invalid gc_maxlifetime; must be numeric');
  212. }
  213. $gcMaxlifetime = (int) $gcMaxlifetime;
  214. if (1 > $gcMaxlifetime) {
  215. throw new Exception\InvalidArgumentException('Invalid gc_maxlifetime; must be a positive integer');
  216. }
  217. $this->setOption('gc_maxlifetime', $gcMaxlifetime);
  218. $this->setStorageOption('gc_maxlifetime', $gcMaxlifetime);
  219. return $this;
  220. }
  221. /**
  222. * Set session.cookie_lifetime
  223. *
  224. * @param int $cookieLifetime
  225. * @return StandardConfiguration
  226. * @throws Exception\InvalidArgumentException
  227. */
  228. public function setCookieLifetime($cookieLifetime)
  229. {
  230. if (!is_numeric($cookieLifetime)) {
  231. throw new Exception\InvalidArgumentException('Invalid cookie_lifetime; must be numeric');
  232. }
  233. if (0 > $cookieLifetime) {
  234. throw new Exception\InvalidArgumentException('Invalid cookie_lifetime; must be a positive integer or zero');
  235. }
  236. $this->cookieLifetime = (int) $cookieLifetime;
  237. $this->setStorageOption('cookie_lifetime', $this->cookieLifetime);
  238. return $this;
  239. }
  240. /**
  241. * Get session.cookie_lifetime
  242. *
  243. * @return int
  244. */
  245. public function getCookieLifetime()
  246. {
  247. if (null === $this->cookieLifetime) {
  248. $this->cookieLifetime = $this->getStorageOption('cookie_lifetime');
  249. }
  250. return $this->cookieLifetime;
  251. }
  252. /**
  253. * Set session.cookie_path
  254. *
  255. * @param string $cookiePath
  256. * @return StandardConfiguration
  257. * @throws Exception\InvalidArgumentException
  258. */
  259. public function setCookiePath($cookiePath)
  260. {
  261. $cookiePath = (string) $cookiePath;
  262. $test = parse_url($cookiePath, PHP_URL_PATH);
  263. if ($test != $cookiePath || '/' != $test[0]) {
  264. throw new Exception\InvalidArgumentException('Invalid cookie path');
  265. }
  266. $this->cookiePath = $cookiePath;
  267. $this->setStorageOption('cookie_path', $cookiePath);
  268. return $this;
  269. }
  270. /**
  271. * Get session.cookie_path
  272. *
  273. * @return string
  274. */
  275. public function getCookiePath()
  276. {
  277. if (null === $this->cookiePath) {
  278. $this->cookiePath = $this->getStorageOption('cookie_path');
  279. }
  280. return $this->cookiePath;
  281. }
  282. /**
  283. * Set session.cookie_domain
  284. *
  285. * @param string $cookieDomain
  286. * @return StandardConfiguration
  287. * @throws Exception\InvalidArgumentException
  288. */
  289. public function setCookieDomain($cookieDomain)
  290. {
  291. if (!is_string($cookieDomain)) {
  292. throw new Exception\InvalidArgumentException('Invalid cookie domain: must be a string');
  293. }
  294. $validator = new HostnameValidator(HostnameValidator::ALLOW_ALL);
  295. if (!empty($cookieDomain) && !$validator->isValid($cookieDomain)) {
  296. throw new Exception\InvalidArgumentException('Invalid cookie domain: ' . implode('; ', $validator->getMessages()));
  297. }
  298. $this->cookieDomain = $cookieDomain;
  299. $this->setStorageOption('cookie_domain', $cookieDomain);
  300. return $this;
  301. }
  302. /**
  303. * Get session.cookie_domain
  304. *
  305. * @return string
  306. */
  307. public function getCookieDomain()
  308. {
  309. if (null === $this->cookieDomain) {
  310. $this->cookieDomain = $this->getStorageOption('cookie_domain');
  311. }
  312. return $this->cookieDomain;
  313. }
  314. /**
  315. * Set session.cookie_secure
  316. *
  317. * @param bool $cookieSecure
  318. * @return StandardConfiguration
  319. */
  320. public function setCookieSecure($cookieSecure)
  321. {
  322. $this->cookieSecure = (bool) $cookieSecure;
  323. $this->setStorageOption('cookie_secure', $this->cookieSecure);
  324. return $this;
  325. }
  326. /**
  327. * Get session.cookie_secure
  328. *
  329. * @return bool
  330. */
  331. public function getCookieSecure()
  332. {
  333. if (null === $this->cookieSecure) {
  334. $this->cookieSecure = $this->getStorageOption('cookie_secure');
  335. }
  336. return $this->cookieSecure;
  337. }
  338. /**
  339. * Set session.cookie_httponly
  340. *
  341. * case sensitive method lookups in setOptions means this method has an
  342. * unusual casing
  343. *
  344. * @param bool $cookieHttpOnly
  345. * @return StandardConfiguration
  346. */
  347. public function setCookieHttpOnly($cookieHttpOnly)
  348. {
  349. $this->cookieHttpOnly = (bool) $cookieHttpOnly;
  350. $this->setStorageOption('cookie_httponly', $this->cookieHttpOnly);
  351. return $this;
  352. }
  353. /**
  354. * Get session.cookie_httponly
  355. *
  356. * @return bool
  357. */
  358. public function getCookieHttpOnly()
  359. {
  360. if (null === $this->cookieHttpOnly) {
  361. $this->cookieHttpOnly = $this->getStorageOption('cookie_httponly');
  362. }
  363. return $this->cookieHttpOnly;
  364. }
  365. /**
  366. * Set session.use_cookies
  367. *
  368. * @param bool $useCookies
  369. * @return StandardConfiguration
  370. */
  371. public function setUseCookies($useCookies)
  372. {
  373. $this->useCookies = (bool) $useCookies;
  374. $this->setStorageOption('use_cookies', $this->useCookies);
  375. return $this;
  376. }
  377. /**
  378. * Get session.use_cookies
  379. *
  380. * @return bool
  381. */
  382. public function getUseCookies()
  383. {
  384. if (null === $this->useCookies) {
  385. $this->useCookies = $this->getStorageOption('use_cookies');
  386. }
  387. return $this->useCookies;
  388. }
  389. /**
  390. * Set session.entropy_file
  391. *
  392. * @param string $entropyFile
  393. * @return StandardConfiguration
  394. * @throws Exception\InvalidArgumentException
  395. */
  396. public function setEntropyFile($entropyFile)
  397. {
  398. if (is_dir($entropyFile) || !is_readable($entropyFile)) {
  399. throw new Exception\InvalidArgumentException('Invalid entropy_file provided');
  400. }
  401. $this->setOption('entropy_file', $entropyFile);
  402. $this->setStorageOption('entropy_file', $entropyFile);
  403. return $this;
  404. }
  405. /**
  406. * set session.entropy_length
  407. *
  408. * @param int $entropyLength
  409. * @return StandardConfiguration
  410. * @throws Exception\InvalidArgumentException
  411. */
  412. public function setEntropyLength($entropyLength)
  413. {
  414. if (!is_numeric($entropyLength)) {
  415. throw new Exception\InvalidArgumentException('Invalid entropy_length; must be numeric');
  416. }
  417. if (0 > $entropyLength) {
  418. throw new Exception\InvalidArgumentException('Invalid entropy_length; must be a positive integer or zero');
  419. }
  420. $this->setOption('entropy_length', $entropyLength);
  421. $this->setStorageOption('entropy_length', $entropyLength);
  422. return $this;
  423. }
  424. /**
  425. * Set session.cache_expire
  426. *
  427. * @param int $cacheExpire
  428. * @return StandardConfiguration
  429. * @throws Exception\InvalidArgumentException
  430. */
  431. public function setCacheExpire($cacheExpire)
  432. {
  433. if (!is_numeric($cacheExpire)) {
  434. throw new Exception\InvalidArgumentException('Invalid cache_expire; must be numeric');
  435. }
  436. $cacheExpire = (int) $cacheExpire;
  437. if (1 > $cacheExpire) {
  438. throw new Exception\InvalidArgumentException('Invalid cache_expire; must be a positive integer');
  439. }
  440. $this->setOption('cache_expire', $cacheExpire);
  441. $this->setStorageOption('cache_expire', $cacheExpire);
  442. return $this;
  443. }
  444. /**
  445. * Set session.hash_bits_per_character
  446. *
  447. * @param int $hashBitsPerCharacter
  448. * @return StandardConfiguration
  449. * @throws Exception\InvalidArgumentException
  450. */
  451. public function setHashBitsPerCharacter($hashBitsPerCharacter)
  452. {
  453. if (!is_numeric($hashBitsPerCharacter)) {
  454. throw new Exception\InvalidArgumentException('Invalid hash bits per character provided');
  455. }
  456. $hashBitsPerCharacter = (int) $hashBitsPerCharacter;
  457. $this->setOption('hash_bits_per_character', $hashBitsPerCharacter);
  458. $this->setStorageOption('hash_bits_per_character', $hashBitsPerCharacter);
  459. return $this;
  460. }
  461. /**
  462. * Set remember_me_seconds
  463. *
  464. * @param int $rememberMeSeconds
  465. * @return StandardConfiguration
  466. * @throws Exception\InvalidArgumentException
  467. */
  468. public function setRememberMeSeconds($rememberMeSeconds)
  469. {
  470. if (!is_numeric($rememberMeSeconds)) {
  471. throw new Exception\InvalidArgumentException('Invalid remember_me_seconds; must be numeric');
  472. }
  473. $rememberMeSeconds = (int) $rememberMeSeconds;
  474. if (1 > $rememberMeSeconds) {
  475. throw new Exception\InvalidArgumentException('Invalid remember_me_seconds; must be a positive integer');
  476. }
  477. $this->rememberMeSeconds = $rememberMeSeconds;
  478. $this->setStorageOption('remember_me_seconds', $rememberMeSeconds);
  479. return $this;
  480. }
  481. /**
  482. * Get remember_me_seconds
  483. *
  484. * @return int
  485. */
  486. public function getRememberMeSeconds()
  487. {
  488. if (null === $this->rememberMeSeconds) {
  489. $this->rememberMeSeconds = $this->getStorageOption('remember_me_seconds');
  490. }
  491. return $this->rememberMeSeconds;
  492. }
  493. /**
  494. * Set many options at once
  495. *
  496. * If a setter method exists for the key, that method will be called;
  497. * otherwise, a standard option will be set with the value provided via
  498. * {@link setOption()}.
  499. *
  500. * @param array $options
  501. * @return StandardConfiguration
  502. */
  503. public function setOptions(array $options)
  504. {
  505. foreach ($options as $key => $value) {
  506. // translate key from underscore_separated to TitleCased
  507. $methodKey = str_replace(' ', '', ucwords(str_replace('_', ' ', $key)));
  508. $method = 'set' . $methodKey;
  509. if (method_exists($this, $method)) {
  510. $this->$method($value);
  511. } else {
  512. $this->setOption($key, $value);
  513. }
  514. }
  515. return $this;
  516. }
  517. /**
  518. * Set an individual option
  519. *
  520. * Keys are normalized to lowercase. After setting internally, calls
  521. * {@link setStorageOption()} to allow further processing.
  522. *
  523. *
  524. * @param string $option
  525. * @param mixed $value
  526. * @return StandardConfiguration
  527. */
  528. public function setOption($option, $value)
  529. {
  530. $option = $this->normalizeOption($option);
  531. $this->options[$option] = $value;
  532. $this->setStorageOption($option, $value);
  533. return $this;
  534. }
  535. /**
  536. * Get an individual option
  537. *
  538. * Keys are normalized to lowercase. If the option is not found, attempts
  539. * to retrieve it via {@link getStorageOption()}; if a value is returned
  540. * from that method, it will be set as the internal value and returned.
  541. *
  542. * Returns null for unfound options
  543. *
  544. * @param string $option
  545. * @return mixed
  546. */
  547. public function getOption($option)
  548. {
  549. $option = $this->normalizeOption($option);
  550. if (array_key_exists($option, $this->options)) {
  551. return $this->options[$option];
  552. }
  553. $value = $this->getStorageOption($option);
  554. if (null !== $value) {
  555. $this->setOption($option, $value);
  556. return $value;
  557. }
  558. return null;
  559. }
  560. /**
  561. * Check to see if an internal option has been set for the key provided.
  562. *
  563. * @param string $option
  564. * @return bool
  565. */
  566. public function hasOption($option)
  567. {
  568. $option = $this->normalizeOption($option);
  569. return array_key_exists($option, $this->options);
  570. }
  571. /**
  572. * Cast configuration to an array
  573. *
  574. * @return array
  575. */
  576. public function toArray()
  577. {
  578. $options = $this->options;
  579. $extraOpts = array(
  580. 'cookie_domain' => $this->getCookieDomain(),
  581. 'cookie_httponly' => $this->getCookieHttpOnly(),
  582. 'cookie_lifetime' => $this->getCookieLifetime(),
  583. 'cookie_path' => $this->getCookiePath(),
  584. 'cookie_secure' => $this->getCookieSecure(),
  585. 'name' => $this->getName(),
  586. 'remember_me_seconds' => $this->getRememberMeSeconds(),
  587. 'save_path' => $this->getSavePath(),
  588. 'use_cookies' => $this->getUseCookies(),
  589. );
  590. return array_merge($options, $extraOpts);
  591. }
  592. /**
  593. * Intercept get*() and set*() methods
  594. *
  595. * Intercepts getters and setters and passes them to getOption() and setOption(),
  596. * respectively.
  597. *
  598. * @param string $method
  599. * @param array $args
  600. * @return mixed
  601. * @throws Exception\BadMethodCallException on non-getter/setter method
  602. */
  603. public function __call($method, $args)
  604. {
  605. if ('get' == substr($method, 0, 3)) {
  606. // Call to a getter; return matching option.
  607. // Transform method from MixedCase to underscore_separated.
  608. $option = substr($method, 3);
  609. $key = $this->getCamelCaseToUnderscoreFilter()->filter($option);
  610. return $this->getOption($key);
  611. }
  612. if ('set' == substr($method, 0, 3)) {
  613. // Call to a setter; return matching option.
  614. // Transform method from MixedCase to underscore_separated.
  615. $option = substr($method, 3);
  616. $key = $this->getCamelCaseToUnderscoreFilter()->filter($option);
  617. $value = array_shift($args);
  618. return $this->setOption($key, $value);
  619. }
  620. throw new Exception\BadMethodCallException(sprintf('Method "%s" does not exist', $method));
  621. }
  622. /**
  623. * Normalize an option name to lowercase
  624. *
  625. * @param string $option
  626. * @return string
  627. */
  628. protected function normalizeOption($option)
  629. {
  630. return strtolower((string) $option);
  631. }
  632. /**
  633. * Retrieve the CamelCaseToUnderscoreFilter
  634. *
  635. * @return CamelCaseToUnderscoreFilter
  636. */
  637. protected function getCamelCaseToUnderscoreFilter()
  638. {
  639. if (null === $this->camelCaseToUnderscoreFilter) {
  640. $this->camelCaseToUnderscoreFilter = new CamelCaseToUnderscoreFilter();
  641. }
  642. return $this->camelCaseToUnderscoreFilter;
  643. }
  644. }