MDL-69549 core: Add context export API
[moodle.git] / lib / classes / content / export / exported_item.php
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
17 /**
18  * Exported Item.
19  *
20  * @package     core
21  * @copyright   2020 Andrew Nicols <andrew@nicols.co.uk>
22  * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23  */
25 declare(strict_types=1);
27 namespace core\content\export;
29 use stdClass;
31 /**
32  * This class describes the files which were exported, and any text content that those files were contained in.
33  *
34  * @copyright   2020 Andrew Nicols <andrew@nicols.co.uk>
35  * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
36  */
37 class exported_item {
39     /** @var string A short, descriptive, name for this exported item */
40     protected $title = null;
42     /** @var string Any string content for export  */
43     protected $content = '';
45     /** @var string[] A list of files which were exported and are not present in the content */
46     protected $files = [];
48     /** @var string[] A list of files which were exported and are present in the content */
49     protected $contentfiles = [];
51     /**
52      * Constructor for the exported_item.
53      *
54      * @param   array $files A list of all files which were exported
55      */
56     public function __construct(array $files = []) {
57         $this->add_files($files);
58     }
60     /**
61      * Set a title for this exported item.
62      *
63      * @param   string $title
64      */
65     public function set_title(string $title): void {
66         $this->title = $title;
67     }
69     /**
70      * Add a file to the list of exported files.
71      *
72      * @param   string $relativefilepath The path to the content relative to the exported context
73      * @param   bool $incontent Whether this file is included within the content
74      * @param   null|string $url The URL to use of the live file where the file could not be stored in the archive
75      */
76     public function add_file(string $relativefilepath, bool $incontent = false, ?string $url = null): void {
77         if ($url === null) {
78             $url = $relativefilepath;
79         }
81         $file = (object) [
82             'filepath' => $url,
83             'filename' => basename($relativefilepath),
84         ];
86         $this->files[$relativefilepath] = $file;
87         if ($incontent) {
88             $this->contentfiles[$relativefilepath] = $file;
89         }
90     }
92     /**
93      * Add a list of files to the list of exported files.
94      *
95      * @param   string[] $files The path to the content relative to the exported context
96      * @param   bool $incontent Whether this file is included within the content
97      */
98     public function add_files(array $files, bool $incontent = false): void {
99         foreach ($files as $relativefilepath) {
100             $this->add_file($relativefilepath, $incontent);
101         }
102     }
104     /**
105      * Set the rewritten content.
106      *
107      * @param   string $content
108      */
109     public function set_content(string $content): void {
110         $this->content = $content;
111     }
113     /**
114      * Fetch the rewritten content.
115      *
116      * @return  string
117      */
118     public function get_content(): string {
119         return $this->content;
120     }
122     /**
123      * Get a short, descriptive name associated with the exported content, if one is avaiable.
124      *
125      * @return  null|string
126      */
127     public function get_title(): ?string {
128         return $this->title;
129     }
131     /**
132      * Get all template data for this exported item.
133      *
134      * @return  stdClass
135      */
136     public function get_template_data(): stdClass {
137         return (object) [
138             'title' => $this->get_title(),
139             'files' => $this->get_noncontent_files(),
140             'content' => $this->content,
141         ];
142     }
144     /**
145      * Get a list of all files in the exported item.
146      *
147      * @return  array
148      */
149     public function get_all_files(): array {
150         return $this->files;
151     }
153     /**
154      * Get a list of all files present in the content.
155      *
156      * That is those files which were exported, and which are referenced in some fashion.
157      * These files typically do not need to be listed separately.
158      *
159      * @return  array
160      */
161     public function get_content_files(): array {
162         return $this->contentfiles;
163     }
165     /**
166      * Get all files which are not already referenced in the content.
167      *
168      * These files will typically be displayed in a separate list.
169      *
170      * @return  array
171      */
172     public function get_noncontent_files(): array {
173         return array_values(array_diff_key(
174             $this->get_all_files(),
175             $this->get_content_files()
176         ));
177     }
179     /**
180      * Check whether the exported_item includes any data.
181      *
182      * @return  bool
183      */
184     public function has_any_data(): bool {
185         if ($this->get_all_files()) {
186             // Some files are present.
187             return true;
188         }
190         if (trim(html_to_text($this->get_content())) !== '') {
191             // The content is not empty.
192             return true;
193         }
195         // No truthy conditions match.
196         return false;
197     }