Test Failed
Branch develop (86e751)
by Laurent
34:11
created

Documents::_validate_file()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 7
nc 3
nop 1
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
1
<?php
2
/* Copyright (C) 2016   Xebax Christy           <[email protected]>
3
 * Copyright (C) 2016	Laurent Destailleur		<[email protected]>
4
 * Copyright (C) 2016   Jean-François Ferry     <[email protected]>
5
 *
6
 * This program is free software you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation; either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18
 */
19
20
use Luracast\Restler\RestException;
21
use Luracast\Restler\Format\UploadFormat;
22
23
24
require_once DOL_DOCUMENT_ROOT.'/main.inc.php';
25
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
26
27
/**
28
 * API class for receive files
29
 *
30
 * @access protected
31
 * @class Documents {@requires user,external}
32
 */
33
class Documents extends DolibarrApi
34
{
35
36
    /**
37
     * @var array   $DOCUMENT_FIELDS     Mandatory fields, checked when create and update object
38
     */
39
    static $DOCUMENT_FIELDS = array(
40
        'modulepart'
41
    );
42
43
    /**
44
     * Constructor
45
     */
46
    function __construct()
47
    {
48
        global $db;
49
        $this->db = $db;
50
    }
51
52
53
    /**
54
     * Returns a document. Note that, this API is similar to using the wrapper link "documents.php" to download
55
     * a file (used for internal HTML links of documents into application), but with no need to be into a logged session (no need to post the session cookie).
56
     *
57
     * @param   string  $module_part    Name of module or area concerned by file download ('facture', ...)
58
     * @param   string  $original_file  Relative path with filename, relative to modulepart (for example: IN201701-999/IN201701-999.pdf)
59
     * @param	int		$regeneratedoc	If requested document is the main document of an object, setting this to 1 ask API to regenerate document before returning it (supported for some module_part only). It is no effect in other cases.
60
     * 									Also, note that setting this to 1 nead write access on object.
61
     * @return  array                   List of documents
62
     *
63
     * @throws 500
64
     * @throws 501
65
     * @throws 400
66
     * @throws 401
67
     * @throws 200
68
     */
69
    public function index($module_part, $original_file='', $regeneratedoc=0)
70
    {
71
		global $conf;
72
73
		if (empty($module_part)) {
74
	            throw new RestException(400, 'bad value for parameter modulepart');
75
		}
76
        if (empty($original_file)) {
77
            throw new RestException(400, 'bad value for parameter ref or subdir');
78
        }
79
80
		//--- Finds and returns the document
81
		$entity=$conf->entity;
82
83
		$check_access = dol_check_secure_access_document($module_part, $original_file, $entity, DolibarrApiAccess::$user, '', ($regeneratedoc ? 'write' : 'read'));
84
		$accessallowed              = $check_access['accessallowed'];
85
		$sqlprotectagainstexternals = $check_access['sqlprotectagainstexternals'];
86
		$original_file              = $check_access['original_file'];
87
88
		if (preg_match('/\.\./',$original_file) || preg_match('/[<>|]/',$original_file))
89
		{
90
		    throw new RestException(401);
91
		}
92
	    if (!$accessallowed) {
93
	        throw new RestException(401);
94
	    }
95
96
        // --- Generates the document
97
        if ($regeneratedoc)
98
        {
99
        	$hidedetails = empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 0 : 1;
100
        	$hidedesc = empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DESC) ? 0 : 1;
101
        	$hideref = empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_REF) ? 0 : 1;
102
103
        	if ($module_part == 'facture' || $module_part == 'invoice')
104
        	{
105
        		require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
106
        		$this->invoice = new Facture($this->db);
107
        		$result = $this->invoice->fetch(0, $ref);
0 ignored issues
show
Bug introduced by
The variable $ref does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
108
        		if( ! $result ) {
109
        			throw new RestException(404, 'Invoice not found');
110
        		}
111
        		$result = $this->invoice->generateDocument($this->invoice->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
0 ignored issues
show
Bug introduced by
The variable $outputlangs does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
112
        		if( $result <= 0 ) {
113
        			throw new RestException(500, 'Error generating document');
114
        		}
115
        	}
116
        }
117
118
		$filename = basename($original_file);
119
		$original_file_osencoded=dol_osencode($original_file);	// New file name encoded in OS encoding charset
120
121
		if (! file_exists($original_file_osencoded))
122
		{
123
		    throw new RestException(404, 'File not found');
124
		}
125
126
		$file_content=file_get_contents($original_file_osencoded);
127
        return array('filename'=>$filename, 'content'=>base64_encode($file_content), 'encoding'=>'MIME base64 (base64_encode php function, http://php.net/manual/en/function.base64-encode.php)' );
128
    }
129
130
131
    /**
132
     * Return a document.
133
     *
134
     * @param   int         $id          ID of document
135
     * @return  array                    Array with data of file
136
     *
137
     * @throws RestException
138
     */
139
    /*
140
    public function get($id) {
141
        return array('note'=>'xxx');
142
    }*/
143
144
145
    /**
146
     * Push a file.
147
     * Test sample 1: { "filename": "mynewfile.txt", "modulepart": "facture", "ref": "FA1701-001", "subdir": "", "filecontent": "content text", "fileencoding": "", "overwriteifexists": "0" }.
148
     * Test sample 2: { "filename": "mynewfile.txt", "modulepart": "medias", "ref": "", "subdir": "mysubdir1/mysubdir2", "filecontent": "content text", "fileencoding": "", "overwriteifexists": "0" }.
149
     *
150
     * @param   string  $filename           Name of file to create ('FA1705-0123')
151
     * @param   string  $modulepart         Name of module or area concerned by file upload ('facture', ...)
152
     * @param   string  $ref                Reference of object (This will define subdir automatically and store submited file into it)
153
     * @param   string  $subdir             Subdirectory (Only if ref not provided)
154
     * @param   string  $filecontent        File content (string with file content. An empty file will be created if this parameter is not provided)
155
     * @param   string  $fileencoding       File encoding (''=no encoding, 'base64'=Base 64)
156
     * @param   int 	$overwriteifexists  Overwrite file if exists (1 by default)
157
     * @return  bool     				    State of copy
158
     * @throws RestException
159
     */
160
    public function post($filename, $modulepart, $ref='', $subdir='', $filecontent='', $fileencoding='', $overwriteifexists=0)
161
    {
162
        global $db, $conf;
163
164
        /*var_dump($modulepart);
165
        var_dump($filename);
166
        var_dump($filecontent);
167
        exit;*/
168
169
        require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
170
171
        if (!DolibarrApiAccess::$user->rights->ecm->upload) {
172
            throw new RestException(401);
173
        }
174
175
        $newfilecontent = '';
176
        if (empty($fileencoding)) $newfilecontent = $filecontent;
177
        if ($fileencoding == 'base64') $newfilecontent = base64_decode($filecontent);
178
179
		$original_file = dol_sanitizeFileName($filename);
180
181
		// Define $uploadir
182
		$object = null;
183
		$entity = $user->entity;
0 ignored issues
show
Bug introduced by
The variable $user does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
184
		if ($ref)
185
		{
186
    		if ($modulepart == 'facture' || $modulepart == 'invoice')
187
    		{
188
    		    $modulepart='facture';
189
    		    $object=new Facture($db);
190
    		    $result = $object->fetch('', $ref);
191
    		}
192
193
    		if (! ($object->id > 0))
194
    		{
195
   		        throw new RestException(500, 'The object '.$modulepart." with ref '".$ref."' was not found.");
196
    		}
197
198
    		$tmp = dol_check_secure_access_document($modulepart, $tmpreldir.$object->ref, $entity, DolibarrApiAccess::$user, $ref, 'write');
0 ignored issues
show
Bug introduced by
The variable $tmpreldir does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
199
    		$upload_dir = $tmp['original_file'];
200
201
    		if (empty($upload_dir) || $upload_dir == '/')
202
    		{
203
    		    throw new RestException(500, 'This value of modulepart does not support yet usage of ref. Check modulepart parameter or try to use subdir parameter instead of ref.');
204
    		}
205
		}
206
		else
207
		{
208
		    if ($modulepart == 'invoice') $modulepart ='facture';
209
210
		    $tmp = dol_check_secure_access_document($modulepart, $subdir, $entity, DolibarrApiAccess::$user, '', 'write');
211
    		$upload_dir = $tmp['original_file'];
212
213
		    if (empty($upload_dir) || $upload_dir == '/')
214
    		{
215
    		    throw new RestException(500, 'This value of modulepart does not support yet usage of ref. Check modulepart parameter or try to use subdir parameter instead of ref.');
216
    		}
217
		}
218
219
220
		$upload_dir = dol_sanitizePathName($upload_dir);
221
222
		$destfile = $upload_dir . '/' . $original_file;
223
		$destfiletmp = DOL_DATA_ROOT.'/admin/temp/' . $original_file;
224
		dol_delete_file($destfiletmp);
225
226
        if (!dol_is_dir($upload_dir)) {
227
            throw new RestException(401,'Directory not exists : '.$upload_dir);
228
        }
229
230
        if (! $overwriteifexists && dol_is_file($destfile))
231
        {
232
            throw new RestException(500, "File with name '".$original_file."' already exists.");
233
        }
234
235
        $fhandle = @fopen($destfiletmp, 'w');
236
        if ($fhandle)
237
        {
238
            $nbofbyteswrote = fwrite($fhandle, $newfilecontent);
239
            fclose($fhandle);
240
            @chmod($destfiletmp, octdec($conf->global->MAIN_UMASK));
241
        }
242
        else
243
        {
244
            throw new RestException(500, "Failed to open file '".$destfiletmp."' for write");
245
        }
246
247
        $result = dol_move($destfiletmp, $destfile, 0, $overwriteifexists, 1);
248
249
        return $result;
250
    }
251
252
    /**
253
     * Validate fields before create or update object
254
     *
255
     * @param   array           $data   Array with data to verify
256
     * @return  array
257
     * @throws  RestException
258
     */
259
    function _validate_file($data) {
260
        $result = array();
261
        foreach (Documents::$DOCUMENT_FIELDS as $field) {
262
            if (!isset($data[$field]))
263
                throw new RestException(400, "$field field missing");
264
            $result[$field] = $data[$field];
265
        }
266
        return $result;
267
    }
268
}
269