1<?php
2// (c) Copyright by authors of the Tiki Wiki CMS Groupware Project
3//
4// All Rights Reserved. See copyright.txt for details and a complete list of authors.
5// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
6// $Id$
7
8/**
9 * TikiImporter
10 *
11 * This file has the main class for the TikiImporter.
12 * The TikiImporter was started as a Google Summer of Code project and
13 * aim to provide a generic structure for importing content from other
14 * softwares to TikiWiki
15 * See http://dev.tiki.org/gsoc2009rodrigo for more information
16 *
17 * @author Rodrigo Sampaio Primo <rodrigo@utopia.org.br>
18 * @package tikiimporter
19 */
20
21/**
22 * TikiImporter is a generic class that should be extended
23 * by any importer class. Each importer class must implement
24 * the methods validateInput(), parseData() and import()
25 *
26 */
27class TikiImporter
28{
29	/**
30	 * The name of the software to import from.
31	 * Should be defined in child class
32	 * @var string
33	 */
34	public $softwareName = '';
35
36	/**
37	 * During the importing process all the log
38	 * strings will be appended to this object property
39	 * using the method saveAndDisplayLog()
40	 *
41	 * @var string
42	 */
43	public $log = '';
44
45	/**
46	 * During the importing process all the error
47	 * messagens will be appended to this property
48	 * using the method saveAndDisplayLog()
49	 *
50	 * @var string
51	 */
52	public $errors = '';
53
54	/**
55	 * Options to the importer (i.e. the number of page
56	 * revisions to import in the case of a wiki software)
57	 *
58	 * The function when implemented by child classes should return
59	 * an array of options that is used in tiki-importer.tpl to display to the user
60	 * the options related with the data import. Currently we support the following
61	 * types: checkbox, select, text
62	 *
63	 * Example of array:
64	 *
65	 * $options = array(
66	 * 		array('name' => 'importAttachments', 'type' => 'checkbox', 'label' => tra('Import images and other attachments')),
67	 * );
68	 *
69	 * @return array
70	 */
71	public static function importOptions()
72	{
73		return [];
74	}
75
76	/**
77	 * Abstract method to start the import process and
78	 * call all other functions for each step of the importation
79	 * (validateInput(), parseData(), insertData())
80	 *
81	 * @return array $importFeedback array with the number of pages imported etc
82	 */
83	function import($filePath = null)
84	{
85	}
86
87	/**
88	 * Abstract method to validate the input import data
89	 *
90	 * Must be implemented by classes
91	 * that extends this one.
92	 */
93	function validateInput()
94	{
95	}
96
97	/**
98	 * Abstract method to parse the input import data
99	 *
100	 * Must be implemented by classes
101	 * that extends this one and should return
102	 * the data to be used by insertData.
103	 */
104	function parseData()
105	{
106	}
107
108	/**
109	 * Abstract method to insert the imported content
110	 * into Tiki
111	 *
112	 * Must be implemented by classes
113	 * that extends this one.
114	 *
115	 * @param array $parsedData data ready to be inserted into Tiki
116	 */
117	function insertData($parsedData = null)
118	{
119	}
120
121	/**
122	 * Abstract method to check the requirements for a
123	 * specific importer.
124	 *
125	 * This method is optional and can be implemented by classes
126	 * that extends this one.
127	 *
128	 * If an error is found the methods should raise an exception.
129	 */
130	function checkRequirements()
131	{
132	}
133
134	/**
135	 * Return a $importOptions array with the result of the concatenation of the $importOptions
136	 * property of all classes in the hierarchy. Should be called by the classes that
137	 * extend from this one, it doesn't make sense to call this method directly from this
138	 * class.
139	 *
140	 * This method should be static but apparently only with PHP >= 5.3.0 is possible to get
141	 * the name of the class the static method was called. For more information see
142	 * http://us2.php.net/manual/en/function.get-called-class.php
143	 *
144	 * @return array $importOptions
145	 */
146	function getOptions()
147	{
148		$class = get_class($this);
149		$importOptions = [];
150
151		do {
152			$importOptions = array_merge($importOptions, call_user_func([$class, 'importOptions']));
153		} while ($class = get_parent_class($class));
154
155		return $importOptions;
156	}
157
158	/**
159	 * Try to change some PHP settings to avoid problens while running the script:
160	 *   - error_reporting
161	 *   - display_errors
162	 *   - max_execution_time
163	 *
164	 * @return void
165	 */
166	static function changePhpSettings()
167	{
168		if (ini_get('error_reporting') != (E_ALL & ~E_DEPRECATED)) {
169			error_reporting(E_ALL & ~E_DEPRECATED);
170		}
171
172		if (ini_get('display_errors') != true) {
173			ini_set('display_errors', true);
174		}
175
176		// change max_execution_time
177		if (ini_get('max_execution_time') != 0) {
178			set_time_limit(0);
179		}
180	}
181
182	/**
183	 * Handle the PHP $_FILES errors
184	 *
185	 * @param int $code error code
186	 * @return string $message error message
187	 */
188	static function displayPhpUploadError($code)
189	{
190		require_once(__DIR__ . '/../init/tra.php');
191		$errors = [1 => tra('The uploaded file exceeds the upload_max_filesize directive in php.ini.') . ' ' . ini_get('upload_max_filesize') . 'B',
192				2 => tra('The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.'),
193				3 => tra('The uploaded file was only partially uploaded. Please try again.'),
194				4 => tra('No file was uploaded.'),
195				6 => tra('Missing a temporary folder.'),
196				7 => tra('Failed to write file to disk.'),
197				8 => tra('File upload stopped by extension.'),
198				];
199
200		if (isset($errors[$code])) {
201			return $errors[$code];
202		}
203	}
204
205	/**
206	 * Append $msg to $this->log and output the $msg to the browser
207	 * during the execution of the script using the flush() method
208	 *
209	 * @param string $msg the log message
210	 * @param bool $error if the message is a error or not (default false)
211	 * @return void
212	 */
213	function saveAndDisplayLog($msg, $error = false)
214	{
215		$this->log .= $msg;
216
217		if ($error) {
218			$this->errors .= $msg;
219		}
220
221		// convert \n to <br> if running script in web browser
222		if (php_sapi_name() != 'cli') {
223			$msg = nl2br($msg);
224			if (ob_get_level() > 0) {
225				ob_flush();
226			}
227		}
228
229		echo $msg;
230
231		flush();
232	}
233}
234
235/**
236 *
237 */
238class ImporterParserException extends Exception
239{
240}
241