NEW Add REST API to push a file.
This commit is contained in:
parent
864dc0d989
commit
80cbc28385
@ -929,7 +929,7 @@ if ($id)
|
||||
{
|
||||
print '<td align="center">';
|
||||
if ($user->admin) print '<a href="'.$url.'action=delete">'.img_delete().'</a>';
|
||||
//else print '<a href="#">'.img_delete().'</a>'; // Some dictionnary can be edited by other profile than admin
|
||||
//else print '<a href="#">'.img_delete().'</a>'; // Some dictionary can be edited by other profile than admin
|
||||
print '</td>';
|
||||
}
|
||||
else print '<td> </td>';
|
||||
|
||||
@ -676,7 +676,7 @@ if ($id)
|
||||
{
|
||||
print '<td align="center">';
|
||||
if ($user->admin) print '<a href="'.$url.'action=delete">'.img_delete().'</a>';
|
||||
//else print '<a href="#">'.img_delete().'</a>'; // Some dictionnary can be edited by other profile than admin
|
||||
//else print '<a href="#">'.img_delete().'</a>'; // Some dictionary can be edited by other profile than admin
|
||||
print '</td>';
|
||||
}
|
||||
else print '<td> </td>';
|
||||
|
||||
@ -1100,7 +1100,7 @@ if ($id)
|
||||
$reshook=$hookmanager->executeHooks('createDictionaryFieldlist',$parameters, $obj, $tmpaction); // Note that $action and $object may have been modified by some hooks
|
||||
$error=$hookmanager->error; $errors=$hookmanager->errors;
|
||||
|
||||
if ($id == 3) unset($fieldlist[2]); // Remove field ??? if dictionnary Regions
|
||||
if ($id == 3) unset($fieldlist[2]); // Remove field ??? if dictionary Regions
|
||||
|
||||
if (empty($reshook))
|
||||
{
|
||||
@ -1555,7 +1555,7 @@ if ($id)
|
||||
{
|
||||
print '<td align="center">';
|
||||
if ($user->admin) print '<a href="'.$url.'action=delete">'.img_delete().'</a>';
|
||||
//else print '<a href="#">'.img_delete().'</a>'; // Some dictionnary can be edited by other profile than admin
|
||||
//else print '<a href="#">'.img_delete().'</a>'; // Some dictionary can be edited by other profile than admin
|
||||
print '</td>';
|
||||
}
|
||||
else print '<td> </td>';
|
||||
|
||||
@ -767,7 +767,7 @@ if ($resql)
|
||||
{
|
||||
print '<td align="center">';
|
||||
if ($user->admin) print '<a href="'.$url.'action=delete">'.img_delete().'</a>';
|
||||
//else print '<a href="#">'.img_delete().'</a>'; // Some dictionnary can be edited by other profile than admin
|
||||
//else print '<a href="#">'.img_delete().'</a>'; // Some dictionary can be edited by other profile than admin
|
||||
print '</td>';
|
||||
}
|
||||
else print '<td> </td>';
|
||||
|
||||
@ -14,6 +14,8 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @deprecated Old explorer. Not using Swagger. See instead explorer in htdocs/api/index.php.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
||||
@ -27,7 +27,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/ccountry.class.php';
|
||||
* @access protected
|
||||
* @class DolibarrApiAccess {@requires user,external}
|
||||
*/
|
||||
class DictionnaryCountries extends DolibarrApi
|
||||
class DictionaryCountries extends DolibarrApi
|
||||
{
|
||||
private $translations = null;
|
||||
|
||||
@ -93,7 +93,8 @@ class DictionnaryCountries extends DolibarrApi
|
||||
|
||||
if ($result) {
|
||||
$num = $this->db->num_rows($result);
|
||||
for ($i = 0; $i < min($num, ($limit <= 0 ? $num : $limit)); $i++) {
|
||||
$min = min($num, ($limit <= 0 ? $num : $limit));
|
||||
for ($i = 0; $i < $min; $i++) {
|
||||
$obj = $this->db->fetch_object($result);
|
||||
$country = new Ccountry($this->db);
|
||||
if ($country->fetch($obj->rowid) > 0) {
|
||||
@ -27,7 +27,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/ccountry.class.php';
|
||||
* @access protected
|
||||
* @class DolibarrApiAccess {@requires user,external}
|
||||
*/
|
||||
class DictionnaryTowns extends DolibarrApi
|
||||
class DictionaryTowns extends DolibarrApi
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
@ -88,7 +88,8 @@ class DictionnaryTowns extends DolibarrApi
|
||||
|
||||
if ($result) {
|
||||
$num = $this->db->num_rows($result);
|
||||
for ($i = 0; $i < min($num, ($limit <= 0 ? $num : $limit)); $i++) {
|
||||
$min = min($num, ($limit <= 0 ? $num : $limit));
|
||||
for ($i = 0; $i < $min; $i++) {
|
||||
$list[] = $this->db->fetch_object($result);
|
||||
}
|
||||
} else {
|
||||
@ -58,23 +58,33 @@ class Documents extends DolibarrApi
|
||||
*
|
||||
* @return array
|
||||
* @throws RestException
|
||||
*
|
||||
*/
|
||||
/*
|
||||
public function get($module_part, $filename) {
|
||||
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
/**
|
||||
* Receive file
|
||||
* Push a file.
|
||||
* Test sample: { "filename": "mynewfile.txt", "modulepart": "facture", "ref": "FA1701-001", "subdir": "", "filecontent": "content text", "fileencoding": "" }
|
||||
*
|
||||
* @param array $request_data Request datas
|
||||
*
|
||||
* @return bool State of copy
|
||||
* @param string $filename Name of file to create ('FA1705-0123')
|
||||
* @param string $modulepart Module part ('facture', ...)
|
||||
* @param string $ref Reference of object (This will define subdir automatically and store submited file into it)
|
||||
* @param string $subdir Subdirectory (Only if refname not provided)
|
||||
* @param string $filecontent File content (string with file content. An empty file will be created if this parameter is not provided)
|
||||
* @param string $fileencoding File encoding (''=no encoding, 'base64'=Base 64)
|
||||
* @return bool State of copy
|
||||
* @throws RestException
|
||||
*/
|
||||
public function post($request_data) {
|
||||
global $conf;
|
||||
public function post($filename, $modulepart, $ref='', $subdir='', $filecontent='', $fileencoding='') {
|
||||
global $db, $conf;
|
||||
|
||||
/*var_dump($modulepart);
|
||||
var_dump($filename);
|
||||
var_dump($filecontent);
|
||||
exit;*/
|
||||
|
||||
require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
|
||||
|
||||
@ -82,46 +92,89 @@ class Documents extends DolibarrApi
|
||||
throw new RestException(401);
|
||||
}
|
||||
|
||||
// Suppression de la chaine de caractere ../ dans $original_file
|
||||
$original_file = str_replace("../","/", $request_data['name']);
|
||||
$refname = str_replace("../","/", $request_data['refname']);
|
||||
$newfilecontent = '';
|
||||
if (empty($fileencoding)) $newfilecontent = $filecontent;
|
||||
if ($fileencoding == 'base64') $newfilecontent = base64_decode($filecontent);
|
||||
|
||||
// find the subdirectory name as the reference
|
||||
if (empty($request_data['refname'])) $refname=basename(dirname($original_file)."/");
|
||||
$original_file = dol_sanitizeFileName($filename);
|
||||
|
||||
// Define $uploadir
|
||||
$object = null;
|
||||
$entity = $user->entity;
|
||||
if ($ref)
|
||||
{
|
||||
if ($modulepart == 'facture' || $modulepart == 'invoice')
|
||||
{
|
||||
$modulepart='facture';
|
||||
$object=new Facture($db);
|
||||
$result = $object->fetch('', $ref);
|
||||
if (! ($result > 0))
|
||||
{
|
||||
throw new RestException(500, 'The object '.$modulepart." with ref '".$ref."' was not found.");
|
||||
}
|
||||
if (! empty($entity))
|
||||
{
|
||||
$tmpreldir = get_exdir(0, 0, 0, 0, $object, $modulepart);
|
||||
$upload_dir = $conf->{$modulepart}->multidir_output[$entity].'/'.$tmpreldir.$object->ref;
|
||||
}
|
||||
else
|
||||
{
|
||||
$tmpreldir = get_exdir(0, 0, 0, 0, $object, $modulepart);
|
||||
$upload_dir = $conf->{$modulepart}->dir_output.'/'.$tmpreldir.$object->ref;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($upload_dir) || $upload_dir == '/')
|
||||
{
|
||||
throw new RestException(500, 'This value of modulepart does not support yet usage of refname. Check modulepart parameter or try to use subdir parameter instead of ref.');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($modulepart == 'invoice') $modulepart ='facture';
|
||||
if (empty($conf->{$modulepart}->dir_output))
|
||||
{
|
||||
throw new RestException(500, 'This value of modulepart is not supported with refname not defined.');
|
||||
}
|
||||
$upload_dir = $conf->{$modulepart}->multidir_output[$entity];
|
||||
|
||||
if (empty($upload_dir) || $upload_dir == '/')
|
||||
{
|
||||
throw new RestException(500, 'This value of modulepart is not yet supported.');
|
||||
}
|
||||
}
|
||||
$upload_dir = dol_sanitizePathName($upload_dir);
|
||||
|
||||
// Security:
|
||||
// On interdit les remontees de repertoire ainsi que les pipe dans
|
||||
// les noms de fichiers.
|
||||
if (preg_match('/\.\./',$original_file) || preg_match('/[<>|]/',$original_file))
|
||||
{
|
||||
throw new RestException(401,'Refused to deliver file '.$original_file);
|
||||
}
|
||||
if (preg_match('/\.\./',$refname) || preg_match('/[<>|]/',$refname))
|
||||
{
|
||||
throw new RestException(401,'Refused to deliver file '.$refname);
|
||||
}
|
||||
|
||||
$modulepart = $request_data['modulepart'];
|
||||
// TODO Use dol_check_secure_access_document
|
||||
|
||||
// Check mandatory fields
|
||||
$result = $this->_validate_file($request_data);
|
||||
//$result = $this->_validate_file($request_data);
|
||||
|
||||
$upload_dir = DOL_DATA_ROOT . '/' .$modulepart.'/'.dol_sanitizeFileName($refname);
|
||||
$destfile = $upload_dir . $original_file;
|
||||
$destfile = $upload_dir . '/' . $original_file;
|
||||
|
||||
if (!is_dir($upload_dir)) {
|
||||
if (!dol_is_dir($upload_dir)) {
|
||||
throw new RestException(401,'Directory not exists : '.$upload_dir);
|
||||
}
|
||||
|
||||
$file = $_FILES['file'];
|
||||
$srcfile = $file['tmp_name'];
|
||||
$res = dol_move($srcfile, $destfile, 0, 1);
|
||||
|
||||
if (!$res) {
|
||||
throw new RestException(500);
|
||||
if (dol_is_file($destfile))
|
||||
{
|
||||
throw new RestException(500, "File with name '".$original_file."' already exists.");
|
||||
}
|
||||
|
||||
return $res;
|
||||
|
||||
$fhandle = fopen($destfile, 'w');
|
||||
if ($fhandle)
|
||||
{
|
||||
$nbofbyteswrote = fwrite($fhandle, $newfilecontent);
|
||||
fclose($fhandle);
|
||||
@chmod($destfile, octdec($conf->global->MAIN_UMASK));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new RestException(500, 'Failed to open file for write');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -36,7 +36,7 @@ class Login
|
||||
*
|
||||
* Request the API token for a couple username / password.
|
||||
* Using method POST is recommanded for security reasons (method GET is often logged by default by web servers with parameters so with login and pass into server log file).
|
||||
* Both method are provided for developer conveniance. Best is to not use at all the login API method and enter directly the "api_key" into field at the top right of page (Note: "api_key" can be found/set on the user page).
|
||||
* Both methods are provided for developer conveniance. Best is to not use at all the login API method and enter directly the "api_key" into field at the top right of page (Note: "api_key" can be found/set on the user page).
|
||||
*
|
||||
* @param string $login User login
|
||||
* @param string $password User password
|
||||
|
||||
@ -2502,7 +2502,7 @@ class Form
|
||||
}
|
||||
if ($objp->supplier_reputation)
|
||||
{
|
||||
//TODO dictionnary
|
||||
//TODO dictionary
|
||||
$reputations=array(''=>$langs->trans('Standard'),'FAVORITE'=>$langs->trans('Favorite'),'NOTTHGOOD'=>$langs->trans('NotTheGoodQualitySupplier'), 'DONOTORDER'=>$langs->trans('DoNotOrderThisProductToThisSupplier'));
|
||||
|
||||
$opt .= " - ".$reputations[$objp->supplier_reputation];
|
||||
|
||||
@ -4555,8 +4555,8 @@ function yn($yesno, $case=1, $color=0)
|
||||
|
||||
/**
|
||||
* Return a path to have a directory according to object.
|
||||
* New usage: $conf->module->multidir_output[$object->entity].'/'.get_exdir(0, 0, 0, 1, $object, 'modulepart')
|
||||
* or: $conf->module->dir_output.'/'.get_exdir(0, 0, 0, 1, $object, 'modulepart') if multidir_output not defined.
|
||||
* New usage: $conf->module->multidir_output[$object->entity].'/'.get_exdir(0, 0, 0, 1, $object, $modulepart)
|
||||
* or: $conf->module->dir_output.'/'.get_exdir(0, 0, 0, 1, $object, $modulepart) if multidir_output not defined.
|
||||
* Old usage: '015' with level 3->"0/1/5/", '015' with level 1->"5/", 'ABC-1' with level 3 ->"0/0/1/"
|
||||
*
|
||||
* @param string $num Id of object (deprecated, $object will be used in future)
|
||||
|
||||
@ -305,7 +305,7 @@ class modResource extends DolibarrModules
|
||||
);
|
||||
//$this->import_convertvalue_array[$r]=array('s.fk_soc'=>array('rule'=>'lastrowid',table='t');
|
||||
$this->import_regex_array[$r]=array('s.datec'=>'^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]( [0-9][0-9]:[0-9][0-9]:[0-9][0-9])?$');
|
||||
$this->import_examplevalues_array[$r]=array('r.ref'=>"REF1",'r.fk_code_type_resource'=>"Code from dictionnary resource type",'r.datec'=>"2017-01-01 or 2017-01-01 12:30:00");
|
||||
$this->import_examplevalues_array[$r]=array('r.ref'=>"REF1",'r.fk_code_type_resource'=>"Code from dictionary resource type",'r.datec'=>"2017-01-01 or 2017-01-01 12:30:00");
|
||||
$this->import_updatekeys_array[$r]=array('r.rf'=>'ResourceFormLabel_ref');
|
||||
|
||||
}
|
||||
|
||||
@ -218,7 +218,7 @@ create table llx_user_employment
|
||||
tms timestamp,
|
||||
fk_user_creat integer,
|
||||
fk_user_modif integer,
|
||||
job varchar(128), -- job position. may be a dictionnary
|
||||
job varchar(128), -- job position. may be a dictionary
|
||||
status integer NOT NULL, -- draft, active, closed
|
||||
salary double(24,8), -- last and current value stored into llx_user
|
||||
salaryextra double(24,8), -- last and current value stored into llx_user
|
||||
|
||||
@ -28,7 +28,7 @@ create table llx_user_employment
|
||||
tms timestamp,
|
||||
fk_user_creat integer,
|
||||
fk_user_modif integer,
|
||||
job varchar(128), -- job position. may be a dictionnary
|
||||
job varchar(128), -- job position. may be a dictionary
|
||||
status integer NOT NULL, -- draft, active, closed
|
||||
salary double(24,8), -- last and current value stored into llx_user
|
||||
salaryextra double(24,8), -- last and current value stored into llx_user
|
||||
|
||||
@ -162,19 +162,19 @@ if (! empty($id) || ! empty($ref)) {
|
||||
|
||||
print_fiche_titre($langs->trans('ProductCombinationGenerator'));
|
||||
|
||||
$dictionnary_attr = array();
|
||||
$dictionary_attr = array();
|
||||
|
||||
foreach ($prodattr->fetchAll() as $attr) {
|
||||
$dictionnary_attr[$attr->id] = $attr;
|
||||
$dictionary_attr[$attr->id] = $attr;
|
||||
foreach ($prodattrval->fetchAllByProductAttribute($attr->id) as $attrval) {
|
||||
$dictionnary_attr[$attr->id]->values[$attrval->id] = $attrval;
|
||||
$dictionary_attr[$attr->id]->values[$attrval->id] = $attrval;
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<script>
|
||||
|
||||
dictionnary_attr = <?php echo json_encode($dictionnary_attr) ?>;
|
||||
dictionary_attr = <?php echo json_encode($dictionary_attr) ?>;
|
||||
weight_units = '<?php echo measuring_units_string($object->weight_units, 'weight') ?>';
|
||||
attr_selected = {};
|
||||
percentage_variation = jQuery('input#price_var_percent').prop('checked');
|
||||
@ -191,7 +191,7 @@ if (! empty($id) || ! empty($ref)) {
|
||||
|
||||
if (!attr_selected.hasOwnProperty(attr)) {
|
||||
|
||||
var label = dictionnary_attr[attr].label;
|
||||
var label = dictionary_attr[attr].label;
|
||||
|
||||
var table = jQuery(document.createElement('table'))
|
||||
.attr('id', 'combinations_'+attr)
|
||||
@ -239,7 +239,7 @@ if (! empty($id) || ! empty($ref)) {
|
||||
}
|
||||
|
||||
html.append(
|
||||
jQuery(document.createElement('td')).text(dictionnary_attr[attr].values[val].value),
|
||||
jQuery(document.createElement('td')).text(dictionary_attr[attr].values[val].value),
|
||||
jQuery(document.createElement('td')).css('text-align', 'center').append(
|
||||
jQuery(document.createElement('input')).attr('type', 'text').css('width', '50px').attr('name', 'combinations[' + attr + '][' + val + '][price]').val(price),
|
||||
percent_symbol_html
|
||||
@ -350,7 +350,7 @@ if (! empty($id) || ! empty($ref)) {
|
||||
<div style="float:left; width: 20%">
|
||||
|
||||
<select id="features" multiple style="width: 100%; height: 300px; overflow: auto">
|
||||
<?php foreach ($dictionnary_attr as $attr): ?>
|
||||
<?php foreach ($dictionary_attr as $attr): ?>
|
||||
<optgroup label="<?php echo $attr->label ?>">
|
||||
<?php foreach ($attr->values as $attrval): ?>
|
||||
<option value="<?php echo $attr->id.':'.$attrval->id ?>"<?php
|
||||
|
||||
@ -131,11 +131,11 @@ class RestAPIDocumentTest extends PHPUnit_Framework_TestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* testRestReceiveDocument.
|
||||
* testPushDocument.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function testRestReceiveDocument()
|
||||
public function testPushDocument()
|
||||
{
|
||||
global $conf,$user,$langs,$db;
|
||||
|
||||
@ -143,20 +143,17 @@ class RestAPIDocumentTest extends PHPUnit_Framework_TestCase
|
||||
|
||||
$fileName = 'img250x20.png';
|
||||
$filePath = dirname(__FILE__).'/'.$fileName;
|
||||
$mimetype = mime_content_type($filePath);
|
||||
// Init Curl file object
|
||||
// See https://wiki.php.net/rfc/curl-file-upload
|
||||
$cfile = curl_file_create($filePath, $mimetype);
|
||||
$mimetype = dol_mimetype($filePath);
|
||||
|
||||
echo __METHOD__.' Request POST url='.$url."\n";
|
||||
|
||||
// Send to existant directory
|
||||
$data = array(
|
||||
// Send to existant directory
|
||||
$data = array(
|
||||
'modulepart' => 'facture',
|
||||
'file' => $cfile,
|
||||
'file' => 'eeeeeee',
|
||||
'refname' => 'AV1303-0003',
|
||||
'name' => $fileName, // Name for destination
|
||||
'type' => $mimetype, );
|
||||
'mime' => $mimetype );
|
||||
|
||||
$result = getURLContent($url, 'POST', $data, 1);
|
||||
|
||||
@ -165,8 +162,8 @@ class RestAPIDocumentTest extends PHPUnit_Framework_TestCase
|
||||
$this->assertEquals($result['curl_error_no'], '');
|
||||
$this->assertEquals($result['content'], 'true');
|
||||
|
||||
// Send to unexistant directory
|
||||
$data = array(
|
||||
// Send to unexistant directory
|
||||
$data = array(
|
||||
'modulepart' => 'facture',
|
||||
'file' => $cfile,
|
||||
'name' => 'AV1303-0003STSEIUDEISRESIJLEU/'.$fileName, // Name for destination
|
||||
|
||||
Loading…
Reference in New Issue
Block a user