diff options
Diffstat (limited to 'src/Wallabag/CoreBundle/Helper')
-rw-r--r-- | src/Wallabag/CoreBundle/Helper/FileCookieJar.php | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/src/Wallabag/CoreBundle/Helper/FileCookieJar.php b/src/Wallabag/CoreBundle/Helper/FileCookieJar.php new file mode 100644 index 00000000..9a63e949 --- /dev/null +++ b/src/Wallabag/CoreBundle/Helper/FileCookieJar.php | |||
@@ -0,0 +1,91 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\CoreBundle\Helper; | ||
4 | |||
5 | use GuzzleHttp\Cookie\FileCookieJar as BaseFileCookieJar; | ||
6 | use GuzzleHttp\Cookie\SetCookie; | ||
7 | use GuzzleHttp\Utils; | ||
8 | use Psr\Log\LoggerInterface; | ||
9 | |||
10 | /** | ||
11 | * Overidden Cookie behavior to: | ||
12 | * - fix multiple concurrent writes (see https://github.com/guzzle/guzzle/pull/1884) | ||
13 | * - ignore error when the cookie file is malformatted (resulting in clearing it). | ||
14 | */ | ||
15 | class FileCookieJar extends BaseFileCookieJar | ||
16 | { | ||
17 | private $logger; | ||
18 | |||
19 | /** | ||
20 | * @param LoggerInterface $logger Only used to log info when something goes wrong | ||
21 | * @param string $cookieFile File to store the cookie data | ||
22 | */ | ||
23 | public function __construct(LoggerInterface $logger, $cookieFile) | ||
24 | { | ||
25 | parent::__construct($cookieFile); | ||
26 | |||
27 | $this->logger = $logger; | ||
28 | } | ||
29 | |||
30 | /** | ||
31 | * Saves the cookies to a file. | ||
32 | * | ||
33 | * @param string $filename File to save | ||
34 | * | ||
35 | * @throws \RuntimeException if the file cannot be found or created | ||
36 | */ | ||
37 | public function save($filename) | ||
38 | { | ||
39 | $json = []; | ||
40 | foreach ($this as $cookie) { | ||
41 | if ($cookie->getExpires() && !$cookie->getDiscard()) { | ||
42 | $json[] = $cookie->toArray(); | ||
43 | } | ||
44 | } | ||
45 | |||
46 | if (false === file_put_contents($filename, json_encode($json), LOCK_EX)) { | ||
47 | // @codeCoverageIgnoreStart | ||
48 | throw new \RuntimeException("Unable to save file {$filename}"); | ||
49 | // @codeCoverageIgnoreEnd | ||
50 | } | ||
51 | } | ||
52 | |||
53 | /** | ||
54 | * Load cookies from a JSON formatted file. | ||
55 | * | ||
56 | * Old cookies are kept unless overwritten by newly loaded ones. | ||
57 | * | ||
58 | * @param string $filename cookie file to load | ||
59 | * | ||
60 | * @throws \RuntimeException if the file cannot be loaded | ||
61 | */ | ||
62 | public function load($filename) | ||
63 | { | ||
64 | $json = file_get_contents($filename); | ||
65 | if (false === $json) { | ||
66 | // @codeCoverageIgnoreStart | ||
67 | throw new \RuntimeException("Unable to load file {$filename}"); | ||
68 | // @codeCoverageIgnoreEnd | ||
69 | } | ||
70 | |||
71 | try { | ||
72 | $data = Utils::jsonDecode($json, true); | ||
73 | } catch (\InvalidArgumentException $e) { | ||
74 | $this->logger->error('JSON inside the cookie is broken', [ | ||
75 | 'json' => $json, | ||
76 | 'error_msg' => $e->getMessage(), | ||
77 | ]); | ||
78 | |||
79 | // cookie file is invalid, just ignore the exception and it'll reset the whole cookie file | ||
80 | $data = ''; | ||
81 | } | ||
82 | |||
83 | if (\is_array($data)) { | ||
84 | foreach (Utils::jsonDecode($json, true) as $cookie) { | ||
85 | $this->setCookie(new SetCookie($cookie)); | ||
86 | } | ||
87 | } elseif (\strlen($data)) { | ||
88 | throw new \RuntimeException("Invalid cookie file: {$filename}"); | ||
89 | } | ||
90 | } | ||
91 | } | ||