1--TEST--
2Phar with object in metadata
3--SKIPIF--
4<?php
5if (!extension_loaded("phar")) die("skip");
6?>
7--INI--
8phar.require_hash=0
9phar.readonly=0
10--FILE--
11<?php
12class EchoesOnWakeup {
13    public function __wakeup() {
14        echo "In __wakeup " . spl_object_id($this) . "\n";
15    }
16    public function __destruct() {
17        echo "In __destruct " . spl_object_id($this) . "\n";
18    }
19}
20class ThrowsOnSerialize {
21    public function __sleep() {
22        throw new RuntimeException("In sleep");
23    }
24}
25$fname = __DIR__ . '/' . basename(__FILE__, '.php') . '.phar.php';
26$pname = 'phar://' . $fname;
27$file = "<?php __HALT_COMPILER(); ?>";
28
29$files = array();
30$files['a'] = array('cont' => 'a', 'meta' => new EchoesOnWakeup());
31include 'files/phar_test.inc';
32
33foreach($files as $name => $cont) {
34    var_dump(file_get_contents($pname.'/'.$name));
35}
36unset($files);
37
38$phar = new Phar($fname);
39echo "Loading metadata for 'a' without allowed_classes\n";
40var_dump($phar['a']->getMetadata(['allowed_classes' => []]));
41echo "Loading metadata for 'a' with allowed_classes\n";
42var_dump($phar['a']->getMetadata(['allowed_classes' => true]));
43unset($phar);
44// NOTE: Phar will use the cached value of metadata if setMetaData was called on that Phar path before.
45// Save the writes to the phar and use a different file path.
46$fname_new = "$fname.copy.php";
47copy($fname, $fname_new);
48$phar = new Phar($fname_new);
49echo "Loading metadata from 'a' from the new phar\n";
50var_dump($phar['a']->getMetadata());
51echo "Loading metadata from 'a' from the new phar with unserialize options\n";
52var_dump($phar['a']->getMetadata(['allowed_classes' => true]));
53// PharEntry->setMetaData will do the following:
54// 1. serialize, checking for exceptions
55// 2. free the original data, checking for exceptions or the data getting set from destructors or error handlers.
56// 3. set the new data.
57try {
58    var_dump($phar['a']->setMetadata(new ThrowsOnSerialize()));
59} catch (RuntimeException $e) {
60    echo "Caught {$e->getMessage()} at {$e->getFile()}:{$e->getLine()}\n";
61    unset($e);
62}
63var_dump($phar['a']->getMetadata([]));
64var_dump($phar['a']->getMetadata(['allowed_classes' => false]));
65
66?>
67--CLEAN--
68<?php
69unlink(__DIR__ . '/' . basename(__FILE__, '.clean.php') . '.phar.php');
70unlink(__DIR__ . '/' . basename(__FILE__, '.clean.php') . '.phar.php.copy.php');
71?>
72--EXPECTF--
73In __destruct 1
74string(1) "a"
75Loading metadata for 'a' without allowed_classes
76object(__PHP_Incomplete_Class)#3 (1) {
77  ["__PHP_Incomplete_Class_Name"]=>
78  string(14) "EchoesOnWakeup"
79}
80Loading metadata for 'a' with allowed_classes
81In __wakeup 2
82object(EchoesOnWakeup)#2 (0) {
83}
84In __destruct 2
85Loading metadata from 'a' from the new phar
86In __wakeup 3
87object(EchoesOnWakeup)#3 (0) {
88}
89In __destruct 3
90Loading metadata from 'a' from the new phar with unserialize options
91In __wakeup 2
92object(EchoesOnWakeup)#2 (0) {
93}
94In __destruct 2
95Caught In sleep at %sphar_metadata_write4.php:12
96In __wakeup 3
97object(EchoesOnWakeup)#3 (0) {
98}
99In __destruct 3
100object(__PHP_Incomplete_Class)#4 (1) {
101  ["__PHP_Incomplete_Class_Name"]=>
102  string(14) "EchoesOnWakeup"
103}