Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
56.00% covered (warning)
56.00%
14 / 25
57.14% covered (warning)
57.14%
4 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
OutputFile
56.00% covered (warning)
56.00%
14 / 25
57.14% covered (warning)
57.14%
4 / 7
30.70
0.00% covered (danger)
0.00%
0 / 1
 onReceived
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 requireExitCode
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 wasReceived
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setReceived
66.67% covered (warning)
66.67%
2 / 3
0.00% covered (danger)
0.00%
0 / 1
2.15
 getClientData
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 getRequiredExitCode
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 newFromClientData
33.33% covered (danger)
33.33%
4 / 12
0.00% covered (danger)
0.00%
0 / 1
16.67
1<?php
2
3namespace Shellbox\Command;
4
5use Shellbox\ShellboxError;
6
7/**
8 * The base class for encapsulated output files.
9 *
10 * An OutputFile object is a declaration of a file expected to be created by a
11 * command. These objects are created on the client side before command
12 * execution, then they are serialized, sent to the server, unserialized,
13 * populated with contents, then sent back to the client where the contents
14 * will be put into its declared destination.
15 */
16abstract class OutputFile {
17    use UserDataTrait;
18
19    /** @var bool */
20    protected $received = false;
21    /** @var callable[] */
22    private $receivedListeners = [];
23    /** @var int|null */
24    private $requiredExitCode;
25
26    /**
27     * Add a callback to call after the file is received
28     *
29     * @since 4.1.0
30     * @param callable $callback
31     * @return $this
32     */
33    public function onReceived( callable $callback ) {
34        $this->receivedListeners[] = $callback;
35        return $this;
36    }
37
38    /**
39     * Upload/return the file only if the command returns the specified exit
40     * code.
41     *
42     * @since 4.1.0
43     * @param ?int $status
44     * @return $this
45     */
46    public function requireExitCode( ?int $status = 0 ) {
47        $this->requiredExitCode = $status;
48        return $this;
49    }
50
51    /**
52     * Return true if the file was received from the command or server.
53     *
54     * @return bool
55     */
56    public function wasReceived() {
57        return $this->received;
58    }
59
60    /**
61     * Set the received flag to true and notify the listeners
62     *
63     * @internal
64     */
65    protected function setReceived() {
66        $this->received = true;
67        foreach ( $this->receivedListeners as $listener ) {
68            $listener();
69        }
70    }
71
72    /**
73     * Get data for JSON serialization by the client.
74     *
75     * @internal
76     * @return array
77     */
78    public function getClientData() {
79        $data = [];
80        if ( $this->requiredExitCode !== null ) {
81            $data['requiredExitCode'] = $this->requiredExitCode;
82        }
83        return $data;
84    }
85
86    /**
87     * @internal
88     * @return int|null
89     */
90    public function getRequiredExitCode() {
91        return $this->requiredExitCode;
92    }
93
94    /**
95     * This is used to create a placeholder object for use on the server side.
96     * It doesn't need to actually be functional since the server is responsible
97     * for reading output files.
98     *
99     * @internal
100     * @param array $data
101     * @return OutputFile
102     */
103    public static function newFromClientData( $data ) {
104        if ( ( $data['type'] ?? '' ) === 'url' ) {
105            if ( !isset( $data['url'] ) ) {
106                throw new ShellboxError( 'Missing required parameter for URL file: "url"' );
107            }
108            $file = new OutputFileToUrl( $data['url'] );
109            if ( isset( $data['headers'] ) ) {
110                $file->headers( $data['headers'] );
111            }
112            if ( isset( $data['mwContentHash'] ) ) {
113                $file->enableMwContentHash( $data['mwContentHash'] );
114            }
115        } else {
116            $file = new OutputFilePlaceholder;
117        }
118        if ( isset( $data['requiredExitCode'] ) ) {
119            $file->requireExitCode( $data['requiredExitCode'] );
120        }
121        return $file;
122    }
123}