PageRenderTime 54ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 0ms

/www/libs/Zend/Http/Header/SetCookie.php

https://bitbucket.org/Ppito/kawaiviewmodel2
PHP | 530 lines | 281 code | 74 blank | 175 comment | 48 complexity | 81fc5d79e48100ac1df558446305a328 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php
  2. /**
  3. * Zend Framework (http://framework.zend.com/)
  4. *
  5. * @link http://github.com/zendframework/zf2 for the canonical source repository
  6. * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
  7. * @license http://framework.zend.com/license/new-bsd New BSD License
  8. * @package Zend_Http
  9. */
  10. namespace Zend\Http\Header;
  11. use Closure;
  12. /**
  13. * @throws Exception\InvalidArgumentException
  14. * @see http://www.ietf.org/rfc/rfc2109.txt
  15. * @see http://www.w3.org/Protocols/rfc2109/rfc2109
  16. */
  17. class SetCookie implements MultipleHeaderInterface
  18. {
  19. /**
  20. * Cookie name
  21. *
  22. * @var string
  23. */
  24. protected $name = null;
  25. /**
  26. * Cookie value
  27. *
  28. * @var string
  29. */
  30. protected $value = null;
  31. /**
  32. * Version
  33. *
  34. * @var integer
  35. */
  36. protected $version = null;
  37. /**
  38. * Max Age
  39. *
  40. * @var integer
  41. */
  42. protected $maxAge = null;
  43. /**
  44. * Cookie expiry date
  45. *
  46. * @var int
  47. */
  48. protected $expires = null;
  49. /**
  50. * Cookie domain
  51. *
  52. * @var string
  53. */
  54. protected $domain = null;
  55. /**
  56. * Cookie path
  57. *
  58. * @var string
  59. */
  60. protected $path = null;
  61. /**
  62. * Whether the cookie is secure or not
  63. *
  64. * @var boolean
  65. */
  66. protected $secure = null;
  67. /**
  68. * @var boolean|null
  69. */
  70. protected $httponly = null;
  71. /**
  72. * @static
  73. * @throws Exception\InvalidArgumentException
  74. * @param $headerLine
  75. * @param bool $bypassHeaderFieldName
  76. * @return array|SetCookie
  77. */
  78. public static function fromString($headerLine, $bypassHeaderFieldName = false)
  79. {
  80. /* @var $setCookieProcessor Closure */
  81. static $setCookieProcessor = null;
  82. if ($setCookieProcessor === null) {
  83. $setCookieClass = get_called_class();
  84. $setCookieProcessor = function ($headerLine) use ($setCookieClass) {
  85. $header = new $setCookieClass;
  86. $keyValuePairs = preg_split('#;\s*#', $headerLine);
  87. foreach ($keyValuePairs as $keyValue) {
  88. if (strpos($keyValue, '=')) {
  89. list($headerKey, $headerValue) = preg_split('#=\s*#', $keyValue, 2);
  90. } else {
  91. $headerKey = $keyValue;
  92. $headerValue = null;
  93. }
  94. // First K=V pair is always the cookie name and value
  95. if ($header->getName() === NULL) {
  96. $header->setName($headerKey);
  97. $header->setValue(urldecode($headerValue));
  98. continue;
  99. }
  100. // Process the remaining elements
  101. switch (str_replace(array('-', '_'), '', strtolower($headerKey))) {
  102. case 'expires' : $header->setExpires($headerValue); break;
  103. case 'domain' : $header->setDomain($headerValue); break;
  104. case 'path' : $header->setPath($headerValue); break;
  105. case 'secure' : $header->setSecure(true); break;
  106. case 'httponly': $header->setHttponly(true); break;
  107. case 'version' : $header->setVersion((int) $headerValue); break;
  108. case 'maxage' : $header->setMaxAge((int) $headerValue); break;
  109. default:
  110. // Intentionally omitted
  111. }
  112. }
  113. return $header;
  114. };
  115. }
  116. list($name, $value) = explode(': ', $headerLine, 2);
  117. // some sites return set-cookie::value, this is to get rid of the second :
  118. $name = (strtolower($name) =='set-cookie:') ? 'set-cookie' : $name;
  119. // check to ensure proper header type for this factory
  120. if (strtolower($name) !== 'set-cookie') {
  121. throw new Exception\InvalidArgumentException('Invalid header line for Set-Cookie string: "' . $name . '"');
  122. }
  123. $multipleHeaders = preg_split('#(?<!Sun|Mon|Tue|Wed|Thu|Fri|Sat),\s*#', $value);
  124. if (count($multipleHeaders) <= 1) {
  125. return $setCookieProcessor(array_pop($multipleHeaders));
  126. } else {
  127. $headers = array();
  128. foreach ($multipleHeaders as $headerLine) {
  129. $headers[] = $setCookieProcessor($headerLine);
  130. }
  131. return $headers;
  132. }
  133. }
  134. /**
  135. * Cookie object constructor
  136. *
  137. * @todo Add validation of each one of the parameters (legal domain, etc.)
  138. *
  139. * @param string $name
  140. * @param string $value
  141. * @param int $expires
  142. * @param string $path
  143. * @param string $domain
  144. * @param bool $secure
  145. * @param bool $httponly
  146. * @param string $maxAge
  147. * @param int $version
  148. * @return SetCookie
  149. */
  150. public function __construct($name = null, $value = null, $expires = null, $path = null, $domain = null, $secure = false, $httponly = false, $maxAge = null, $version = null)
  151. {
  152. $this->type = 'Cookie';
  153. if ($name) {
  154. $this->setName($name);
  155. }
  156. if ($value) {
  157. $this->setValue($value); // in parent
  158. }
  159. if ($version!==null) {
  160. $this->setVersion($version);
  161. }
  162. if ($maxAge!==null) {
  163. $this->setMaxAge($maxAge);
  164. }
  165. if ($domain) {
  166. $this->setDomain($domain);
  167. }
  168. if ($expires) {
  169. $this->setExpires($expires);
  170. }
  171. if ($path) {
  172. $this->setPath($path);
  173. }
  174. if ($secure) {
  175. $this->setSecure($secure);
  176. }
  177. if ($httponly) {
  178. $this->setHttpOnly($httponly);
  179. }
  180. }
  181. /**
  182. * @return string 'Set-Cookie'
  183. */
  184. public function getFieldName()
  185. {
  186. return 'Set-Cookie';
  187. }
  188. /**
  189. * @throws Exception\RuntimeException
  190. * @return string
  191. */
  192. public function getFieldValue()
  193. {
  194. if ($this->getName() == '') {
  195. throw new Exception\RuntimeException('A cookie name is required to generate a field value for this cookie');
  196. }
  197. $value = $this->getValue();
  198. if (strpos($value, '"')!==false) {
  199. $value = '"'.urlencode(str_replace('"', '', $value)).'"';
  200. } else {
  201. $value = urlencode($value);
  202. }
  203. $fieldValue = $this->getName() . '=' . $value;
  204. $version = $this->getVersion();
  205. if ($version!==null) {
  206. $fieldValue .= '; Version=' . $version;
  207. }
  208. $maxAge = $this->getMaxAge();
  209. if ($maxAge!==null) {
  210. $fieldValue .= '; Max-Age=' . $maxAge;
  211. }
  212. $expires = $this->getExpires();
  213. if ($expires) {
  214. $fieldValue .= '; Expires=' . $expires;
  215. }
  216. $domain = $this->getDomain();
  217. if ($domain) {
  218. $fieldValue .= '; Domain=' . $domain;
  219. }
  220. $path = $this->getPath();
  221. if ($path) {
  222. $fieldValue .= '; Path=' . $path;
  223. }
  224. if ($this->isSecure()) {
  225. $fieldValue .= '; Secure';
  226. }
  227. if ($this->isHttponly()) {
  228. $fieldValue .= '; HttpOnly';
  229. }
  230. return $fieldValue;
  231. }
  232. /**
  233. * @param string $name
  234. * @throws Exception\InvalidArgumentException
  235. * @return SetCookie
  236. */
  237. public function setName($name)
  238. {
  239. if (preg_match("/[=,; \t\r\n\013\014]/", $name)) {
  240. throw new Exception\InvalidArgumentException("Cookie name cannot contain these characters: =,; \\t\\r\\n\\013\\014 ({$name})");
  241. }
  242. $this->name = $name;
  243. return $this;
  244. }
  245. /**
  246. * @return string
  247. */
  248. public function getName()
  249. {
  250. return $this->name;
  251. }
  252. /**
  253. * @param string $value
  254. */
  255. public function setValue($value)
  256. {
  257. $this->value = $value;
  258. }
  259. /**
  260. * @return string
  261. */
  262. public function getValue()
  263. {
  264. return $this->value;
  265. }
  266. /**
  267. * Set version
  268. *
  269. * @param integer $version
  270. * @throws Exception\InvalidArgumentException
  271. */
  272. public function setVersion($version)
  273. {
  274. if (!is_int($version)) {
  275. throw new Exception\InvalidArgumentException('Invalid Version number specified');
  276. }
  277. $this->version = $version;
  278. }
  279. /**
  280. * Get version
  281. *
  282. * @return integer
  283. */
  284. public function getVersion()
  285. {
  286. return $this->version;
  287. }
  288. /**
  289. * Set Max-Age
  290. *
  291. * @param integer $maxAge
  292. * @throws Exception\InvalidArgumentException
  293. */
  294. public function setMaxAge($maxAge)
  295. {
  296. if (!is_int($maxAge) || ($maxAge<0)) {
  297. throw new Exception\InvalidArgumentException('Invalid Max-Age number specified');
  298. }
  299. $this->maxAge = $maxAge;
  300. }
  301. /**
  302. * Get Max-Age
  303. *
  304. * @return integer
  305. */
  306. public function getMaxAge()
  307. {
  308. return $this->maxAge;
  309. }
  310. /**
  311. * @param int $expires
  312. * @throws Exception\InvalidArgumentException
  313. * @return SetCookie
  314. */
  315. public function setExpires($expires)
  316. {
  317. if (!empty($expires)) {
  318. if (is_string($expires)) {
  319. $expires = strtotime($expires);
  320. } elseif (!is_int($expires)) {
  321. throw new Exception\InvalidArgumentException('Invalid expires time specified');
  322. }
  323. $this->expires = (int) $expires;
  324. }
  325. return $this;
  326. }
  327. /**
  328. * @param bool $inSeconds
  329. * @return int
  330. */
  331. public function getExpires($inSeconds = false)
  332. {
  333. if ($this->expires == null) {
  334. return;
  335. }
  336. if ($inSeconds) {
  337. return $this->expires;
  338. }
  339. return gmdate('D, d-M-Y H:i:s', $this->expires) . ' GMT';
  340. }
  341. /**
  342. * @param string $domain
  343. */
  344. public function setDomain($domain)
  345. {
  346. $this->domain = $domain;
  347. }
  348. /**
  349. * @return string
  350. */
  351. public function getDomain()
  352. {
  353. return $this->domain;
  354. }
  355. /**
  356. * @param string $path
  357. */
  358. public function setPath($path)
  359. {
  360. $this->path = $path;
  361. }
  362. /**
  363. * @return string
  364. */
  365. public function getPath()
  366. {
  367. return $this->path;
  368. }
  369. /**
  370. * @param boolean $secure
  371. */
  372. public function setSecure($secure)
  373. {
  374. $this->secure = $secure;
  375. }
  376. /**
  377. * @return boolean
  378. */
  379. public function isSecure()
  380. {
  381. return $this->secure;
  382. }
  383. /**
  384. * @param boolean $httponly
  385. */
  386. public function setHttponly($httponly)
  387. {
  388. $this->httponly = $httponly;
  389. }
  390. /**
  391. * @return boolean
  392. */
  393. public function isHttponly()
  394. {
  395. return $this->httponly;
  396. }
  397. /**
  398. * Check whether the cookie has expired
  399. *
  400. * Always returns false if the cookie is a session cookie (has no expiry time)
  401. *
  402. * @param int $now Timestamp to consider as "now"
  403. * @return boolean
  404. */
  405. public function isExpired($now = null)
  406. {
  407. if ($now === null) {
  408. $now = time();
  409. }
  410. if (is_int($this->expires) && $this->expires < $now) {
  411. return true;
  412. } else {
  413. return false;
  414. }
  415. }
  416. /**
  417. * Check whether the cookie is a session cookie (has no expiry time set)
  418. *
  419. * @return boolean
  420. */
  421. public function isSessionCookie()
  422. {
  423. return ($this->expires === null);
  424. }
  425. public function isValidForRequest($requestDomain, $path, $isSecure = false)
  426. {
  427. if ($this->getDomain() && (strrpos($requestDomain, $this->getDomain()) === false)) {
  428. return false;
  429. }
  430. if ($this->getPath() && (strpos($path, $this->getPath()) !== 0)) {
  431. return false;
  432. }
  433. if ($this->secure && $this->isSecure()!==$isSecure) {
  434. return false;
  435. }
  436. return true;
  437. }
  438. public function toString()
  439. {
  440. return 'Set-Cookie: ' . $this->getFieldValue();
  441. }
  442. public function toStringMultipleHeaders(array $headers)
  443. {
  444. $headerLine = $this->toString();
  445. /* @var $header SetCookie */
  446. foreach ($headers as $header) {
  447. if (!$header instanceof SetCookie) {
  448. throw new Exception\RuntimeException(
  449. 'The SetCookie multiple header implementation can only accept an array of SetCookie headers'
  450. );
  451. }
  452. $headerLine .= ', ' . $header->getFieldValue();
  453. }
  454. return $headerLine;
  455. }
  456. }