diff --git a/wire/core/Process.php b/wire/core/Process.php index baa717c2..72b5336b 100644 --- a/wire/core/Process.php +++ b/wire/core/Process.php @@ -20,6 +20,7 @@ * https://processwire.com/about/license/mit/ * * @method string|array execute() + * @method string|array executeUnknown() Called when urlSegment matches no execute[Method], only if implemented. * @method Process headline(string $headline) * @method Process browserTitle(string $title) * @method Process breadcrumb(string $href, string $label) diff --git a/wire/core/WireFileTools.php b/wire/core/WireFileTools.php index 9fbcc68c..87c1a8e4 100644 --- a/wire/core/WireFileTools.php +++ b/wire/core/WireFileTools.php @@ -794,22 +794,49 @@ class WireFileTools extends Wire { /** * Send the contents of the given filename to the current http connection * - * This function utilizes the `$config->fileContentTypes` to match file extension - * to content type headers and force-download state. + * This function utilizes the `$config->fileContentTypes` to match file extension to content type headers + * and force-download state. * - * This function throws a WireException if the file can't be sent for some reason. + * This function throws a `WireException` if the file can’t be sent for some reason. Set the `throw` option to + * false if you want it to instead return integer 0 when errors occur. * - * @param string $filename Full path and filename to send - * @param array $options Optional options that you may pass in (see `WireHttp::sendFile()` for details) - * @param array $headers Optional headers that are sent (see `WireHttp::sendFile()` for details) + * @param string|bool $filename Full path and filename to send or boolean false if provided in `$options[data]`. + * @param array $options Optional options to modify default behavior: + * - `exit` (bool): Halt program execution after file send (default=true). + * - `partial` (bool): Allow use of partial downloads via HTTP_RANGE requests? Since 3.0.131 (default=true) + * - `forceDownload` (bool|null): Whether file should force download, or null to let content-type header decide (default=null). + * - `downloadFilename` (string): Filename you want the download to show on user’s computer, or omit to use existing (default=''). + * - `headers` (array): The $headers argument to this method can also be provided as an option right here (default=[]). Since 3.0.131. + * - `data` (string): String of data to send rather than file, $filename argument must be false (default=''). Since 3.0.132. + * - `limitPath` (string|bool): Prefix disk path $filename must be within, false to disable, true for site/assets (default=false). Since 3.0.169. + * - `throw` (bool): Throw exceptions on error? When false, it will instead return integer 0 on errors (default=true). Since 3.0.169. + * @param array $headers Optional headers that are sent, below are the defaults: + * - `pragma`: public + * - `expires`: 0 + * - `cache-control`: must-revalidate, post-check=0, pre-check=0 + * - `content-type`: {content-type} (replaced with actual content type) + * - `content-transfer-encoding`: binary + * - `content-length`: {filesize} (replaced with actual filesize) + * - To remove a header completely, make its value NULL. + * - If preferred, the above headers can be specified in `$options[headers]` instead. + * @return int Returns bytes sent, only if `exit` option is false (since 3.0.169) * @throws WireException * @see WireHttp::sendFile() * */ public function send($filename, array $options = array(), array $headers = array()) { - $this->allowPath($filename, false, true); + $defaults = array('limitPath' => false, 'throw' => true); + $options = array_merge($defaults, $options); + if($filename && !$this->allowPath($filename, $options['limitPath'], $options['throw'])) return 0; $http = new WireHttp(); - $http->sendFile($filename, $options, $headers); + $this->wire($http); + try { + $result = $http->sendFile($filename, $options, $headers); + } catch(\Exception $e) { + if($options['throw']) throw $e; + $result = 0; + } + return $result; } /**