From 7f44faf0bef218587e35a7be28df3d75810d0e5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Mon, 6 Nov 2017 20:29:57 +0100 Subject: [PATCH 001/131] correct merge --- htdocs/accountancy/admin/export.php | 7 ------- 1 file changed, 7 deletions(-) diff --git a/htdocs/accountancy/admin/export.php b/htdocs/accountancy/admin/export.php index af11824e91a..4a9625972b8 100644 --- a/htdocs/accountancy/admin/export.php +++ b/htdocs/accountancy/admin/export.php @@ -77,11 +77,6 @@ $model_option = array ( 'label' => 'ACCOUNTING_EXPORT_DATE', 'param' => '', ), - //'ACCOUNTING_EXPORT_PIECE', - //'ACCOUNTING_EXPORT_GLOBAL_ACCOUNT', - //'ACCOUNTING_EXPORT_LABEL', - //'ACCOUNTING_EXPORT_AMOUNT', - //'ACCOUNTING_EXPORT_DEVISE', ); /* @@ -143,7 +138,6 @@ $form = new Form($db); // $linkback = '' . $langs->trans("BackToModuleList") . ''; print load_fiche_titre($langs->trans('ConfigAccountingExpert'), $linkback, 'title_setup'); -$head = admin_accounting_prepare_head(); print "\n".''."\n"; - } - - // Google Analytics (need Google module) - if (! empty($conf->google->enabled) && ! empty($conf->global->MAIN_GOOGLE_AN_ID)) - { - if (($conf->dol_use_jmobile != 4)) - { - print "\n"; - print ''."\n"; + if (empty($conf->dol_use_jmobile)) + { + print "\n"; + print '/* Set handler to switch left menu page (menuhider) */'."\n"; + print 'jQuery(".menuhider").click(function() {'; + print ' console.log("We click on .menuhider");'."\n"; + //print " $('.side-nav').animate({width:'toggle'},200);\n"; // OK with eldy theme but not with md + print " $('.side-nav').toggle()\n"; + print " $('.login_block').toggle()\n"; + print '});'."\n"; + } + + // Google Analytics (need Google module) + if (! empty($conf->google->enabled) && ! empty($conf->global->MAIN_GOOGLE_AN_ID)) + { + if (($conf->dol_use_jmobile != 4)) + { + print "\n"; + print "/* Set google analtics tag */\n"; + print ' var _gaq = _gaq || [];'."\n"; + print ' _gaq.push([\'_setAccount\', \''.$conf->global->MAIN_GOOGLE_AN_ID.'\']);'."\n"; + print ' _gaq.push([\'_trackPageview\']);'."\n"; + print ''."\n"; + print ' (function() {'."\n"; + print ' var ga = document.createElement(\'script\'); ga.type = \'text/javascript\'; ga.async = true;'."\n"; + print ' ga.src = (\'https:\' == document.location.protocol ? \'https://ssl\' : \'http://www\') + \'.google-analytics.com/ga.js\';'."\n"; + print ' var s = document.getElementsByTagName(\'script\')[0]; s.parentNode.insertBefore(ga, s);'."\n"; + print ' })();'."\n"; + } + } + + // End of tuning + if (! empty($_SERVER['MAIN_SHOW_TUNING_INFO']) || ! empty($conf->global->MAIN_SHOW_TUNING_INFO)) + { + print "\n"; + print "/* Add memory info */\n"; + print 'window.console && console.log("'; + if (! empty($conf->global->MEMCACHED_SERVER)) print 'MEMCACHED_SERVER='.$conf->global->MEMCACHED_SERVER.' - '; + print 'MAIN_OPTIMIZE_SPEED='.(isset($conf->global->MAIN_OPTIMIZE_SPEED)?$conf->global->MAIN_OPTIMIZE_SPEED:'off'); + if (! empty($micro_start_time)) // Works only if MAIN_SHOW_TUNING_INFO is defined at $_SERVER level. Not in global variable. + { + $micro_end_time = microtime(true); + print ' - Build time: '.ceil(1000*($micro_end_time-$micro_start_time)).' ms'; + } + if (function_exists("memory_get_usage")) + { + print ' - Mem: '.memory_get_usage(); + } + if (function_exists("xdebug_memory_usage")) + { + print ' - XDebug time: '.ceil(1000*xdebug_time_index()).' ms'; + print ' - XDebug mem: '.xdebug_memory_usage(); + print ' - XDebug mem peak: '.xdebug_peak_memory_usage(); + } + if (function_exists("zend_loader_file_encoded")) + { + print ' - Zend encoded file: '.(zend_loader_file_encoded()?'yes':'no'); + } + print '");'."\n"; + } + + print "\n".''."\n"; } - } - - // End of tuning - if (! empty($_SERVER['MAIN_SHOW_TUNING_INFO']) || ! empty($conf->global->MAIN_SHOW_TUNING_INFO)) - { - print "\n".''."\n"; // Add Xdebug coverage of code if (defined('XDEBUGCOVERAGE')) { print_r(xdebug_get_code_coverage()); } - } - - // If there is some logs in buffer to show - if (count($conf->logbuffer)) - { - print "\n"; - print "\n"; } - //print ''."\n"; - print "End of log output -->\n"; } - - $parameters=array(); - $reshook=$hookmanager->executeHooks('printCommonFooter',$parameters); // Note that $action and $object may have been modified by some hooks } /** diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 29546764f9b..93b4327620b 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -1928,101 +1928,23 @@ if (! function_exists("llxFooter")) print ' '."\n"; // End div fiche - if (empty($conf->dol_hide_leftmenu)) print ' '; // End div id-right + if (empty($conf->dol_hide_leftmenu)) print ' '."\n"; // End div id-right + + if (empty($conf->dol_hide_leftmenu) && empty($conf->dol_use_jmobile)) print ' '."\n"; // End div container print "\n"; if ($comment) print ''."\n"; printCommonFooter($zone); - if (empty($conf->dol_hide_leftmenu) && empty($conf->dol_use_jmobile)) print ' '."\n"; // End div container - if (! empty($delayedhtmlcontent)) print $delayedhtmlcontent; - // TODO Move this in lib_head.js.php - - // Wrapper to show tooltips (html or onclick popup) - if (! empty($conf->use_javascript_ajax) && empty($conf->dol_no_mouse_hover)) + if (! empty($conf->use_javascript_ajax)) { - print "\n\n"; - print '' . "\n"; + print "\n".''."\n"; + print ''."\n"; } - - // Wrapper to manage document_preview - if (! empty($conf->use_javascript_ajax) && ($conf->browser->layout != 'phone')) - { - print "\n\n"; - print '' . "\n"; - } - - // Wrapper to manage dropdown - if (! empty($conf->use_javascript_ajax) && ! defined('JS_JQUERY_DISABLE_DROPDOWN')) - { - print "\n\n"; - print ''; - } - + // Wrapper to add log when clicking on download or preview if (! empty($conf->blockedlog->enabled) && is_object($object) && $object->id > 0 && $object->statut > 0) { @@ -2056,7 +1978,6 @@ if (! function_exists("llxFooter")) } } - // A div for the address popup print "\n\n"; print ''."\n"; From ad71a22994faadff8baadd0dd780f64bb71e1491 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 9 Nov 2017 01:21:02 +0100 Subject: [PATCH 013/131] Code comment --- htdocs/core/lib/functions.lib.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index e13d8a2febf..a791f2e68cf 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -6289,9 +6289,10 @@ function complete_head_from_modules($conf,$langs,$object,&$head,&$h,$type,$mode= /** * Print common footer : * conf->global->MAIN_HTML_FOOTER - * conf->global->MAIN_GOOGLE_AN_ID - * conf->global->MAIN_SHOW_TUNING_INFO or $_SERVER["MAIN_SHOW_TUNING_INFO"] - * conf->logbuffer + * js for switch of menu hider + * js for conf->global->MAIN_GOOGLE_AN_ID + * js for conf->global->MAIN_SHOW_TUNING_INFO or $_SERVER["MAIN_SHOW_TUNING_INFO"] + * js for conf->logbuffer * * @param string $zone 'private' (for private pages) or 'public' (for public pages) * @return void @@ -6315,7 +6316,7 @@ function printCommonFooter($zone='private') { print ''."\n"; + print ''."\n"; } - + // Wrapper to add log when clicking on download or preview if (! empty($conf->blockedlog->enabled) && is_object($object) && $object->id > 0 && $object->statut > 0) { From a2daef3450dacc768e2f5fced499d5eb97ceaab4 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 9 Nov 2017 16:13:39 +0100 Subject: [PATCH 015/131] Update doc --- dev/examples/ldap/ldapsearch_sample1.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dev/examples/ldap/ldapsearch_sample1.txt b/dev/examples/ldap/ldapsearch_sample1.txt index 7000723d92a..5f667ffd7a4 100644 --- a/dev/examples/ldap/ldapsearch_sample1.txt +++ b/dev/examples/ldap/ldapsearch_sample1.txt @@ -7,3 +7,7 @@ # ldapsearch -h hostname -x -b "ou=people,dc=teclib,dc=infra" # ldapsearch -h hostname -x -z 0 -b "o=somecompany.com" -D "cn=manager,o=somecompany.com" -w password "(objectclass=*)" # ldapsearch -h hostname -x -b "o=somecompany.com" -D "cn=manager,o=somecompany.com" -w password "(objectclass=*)" +# +# Example to test a ldap search: +# ldapsearch -h hostname -x -z 5 -b 'OU=Collaborateurs,OU=Utilisateurs,OU=MyCompany,DC=bocal,DC=lan' -D 'CN=UserAdmin,OU=Informatique,OU=Utilisateurs,OU=MyCompany,DC=bocal,DC=lan' -w password + From e528a820514bd92ffed954dcd9731ee114d821a0 Mon Sep 17 00:00:00 2001 From: Ion Date: Thu, 9 Nov 2017 16:54:31 +0100 Subject: [PATCH 016/131] Remove price dynamic internal var --- htdocs/product/dynamic_price/class/price_parser.class.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/htdocs/product/dynamic_price/class/price_parser.class.php b/htdocs/product/dynamic_price/class/price_parser.class.php index aba86bfd97e..f2243ba1c09 100644 --- a/htdocs/product/dynamic_price/class/price_parser.class.php +++ b/htdocs/product/dynamic_price/class/price_parser.class.php @@ -178,6 +178,9 @@ class PriceParser $values["global_".$entry->code] = $entry->value; } + //Remove internal variables + unset($values["supplier_id"]); + //Prepare the lib, parameters and values $em = new EvalMath(); $em->suppress_errors = true; //Don't print errors on page From aa0b811f7330ba53d8d7cd826933445dc7bf8b08 Mon Sep 17 00:00:00 2001 From: Ion Agorria Date: Wed, 24 Feb 2016 18:56:59 +0100 Subject: [PATCH 017/131] Undefined variable detection in price parser --- htdocs/langs/en_US/errors.lang | 1 + .../dynamic_price/class/price_parser.class.php | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index 77a4ba76383..c36a3fad5ff 100644 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -155,6 +155,7 @@ ErrorPriceExpression19=Expression not found ErrorPriceExpression20=Empty expression ErrorPriceExpression21=Empty result '%s' ErrorPriceExpression22=Negative result '%s' +ErrorPriceExpression23=Unknown or non set variable '%s' in %s ErrorPriceExpressionInternal=Internal error '%s' ErrorPriceExpressionUnknown=Unknown error '%s' ErrorSrcAndTargetWarehouseMustDiffers=Source and target warehouses must differs diff --git a/htdocs/product/dynamic_price/class/price_parser.class.php b/htdocs/product/dynamic_price/class/price_parser.class.php index f2243ba1c09..e11edfee76c 100644 --- a/htdocs/product/dynamic_price/class/price_parser.class.php +++ b/htdocs/product/dynamic_price/class/price_parser.class.php @@ -85,6 +85,7 @@ class PriceParser -2 Args 6, wrong number of arguments (%s given, %s expected) + 23, unknown or non set variable '%s' after %s -internal errors 7, internal error @@ -187,13 +188,25 @@ class PriceParser $this->error_expr = null; $last_result = null; - //Iterate over each expression splitted by $separator_chr + //Fill each variable in expression from values $expression = str_replace("\n", $this->separator_chr, $expression); foreach ($values as $key => $value) { if ($value === null) $value = "NULL"; $expression = str_replace($this->special_chr.$key.$this->special_chr, strval($value), $expression); } + + //Check if there is unfilled variable + if (strpos($expression, $this->special_chr) !== false) + { + $data = explode($this->special_chr, $expression); + $variable = $this->special_chr.$data[1]; + if (isset($data[2])) $variable.= $this->special_chr; + $this->error_parser = array(23, array($variable, $expression)); + return -6; + } + + //Iterate over each expression splitted by $separator_chr $expressions = explode($this->separator_chr, $expression); $expressions = array_slice($expressions, 0, $this->limit); foreach ($expressions as $expr) { From f6a0603fb09b3904ccc4fb2b1e6d169c365e5852 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 9 Nov 2017 18:16:15 +0100 Subject: [PATCH 018/131] Clean code/constant --- htdocs/bookmarks/bookmarks.lib.php | 13 +++++++---- htdocs/core/js/lib_foot.js.php | 1 - htdocs/install/mysql/data/llx_const.sql | 23 ++++++++++--------- .../install/mysql/migration/6.0.0-7.0.0.sql | 4 +++- htdocs/main.inc.php | 14 +---------- 5 files changed, 24 insertions(+), 31 deletions(-) diff --git a/htdocs/bookmarks/bookmarks.lib.php b/htdocs/bookmarks/bookmarks.lib.php index cb234de583f..dc91b259018 100644 --- a/htdocs/bookmarks/bookmarks.lib.php +++ b/htdocs/bookmarks/bookmarks.lib.php @@ -76,13 +76,16 @@ function printBookmarksList($aDb, $aLangs) $ret.= '
'; $ret.= ''; } -dol_fiche_head($head, 'card', $langs->trans("File"), 0, 'generic'); +dol_fiche_head($head, 'card', $langs->trans("File"), -1, 'generic'); + -print ''; -print ''; -/*print ''; -print ''; -*/ -print '
'.$langs->trans("Ref").''; $s=''; $tmpecmdir=new EcmDirectory($db); // Need to create a new one $tmpecmdir->fetch($ecmdir->id); @@ -259,7 +258,7 @@ $i=0; while ($tmpecmdir && $result > 0) { $tmpecmdir->ref=$tmpecmdir->label; - $s=$tmpecmdir->getNomUrl(1).$s; + $s=$tmpecmdir->getNomUrl(1).$s; if ($tmpecmdir->fk_parent) { $s=' -> '.$s; @@ -272,28 +271,18 @@ while ($tmpecmdir && $result > 0) $i++; } -print img_picto('','object_dir').' '.$langs->trans("ECMRoot").' -> '; -print $s; -print ' -> '; -if ($action == 'edit') print ''; -else print $urlfile; -print '
'.$langs->trans("Description").''; -if ($action == 'edit') -{ - print ''; -} -else print dol_nl2br($ecmdir->description); -print '
'.$langs->trans("ECMCreationUser").''; -$userecm=new User($db); -$userecm->fetch($ecmdir->fk_user_c); -print $userecm->getNomUrl(1); -print '
'.$langs->trans("ECMCreationDate").''; +$s = img_picto('','object_dir').' '.$langs->trans("ECMRoot").' -> '.$s.' -> '; +if ($action == 'edit') $s .= ''; +else $s .= $urlfile; + +$object->ref=''; // Force to hide ref +dol_banner_tab($object, '', $morehtml, 0, '', '', $s); + +print '
'; + +print '
'; +print ''; +print ''; /*print ''; print '
'.$langs->trans("ECMCreationDate").''; print dol_print_date(dol_filemtime($fullpath),'dayhour'); print '
'.$langs->trans("ECMDirectoryForFiles").''; @@ -385,6 +374,7 @@ else print '
'; +print '
'; print ajax_autoselect('downloadinternallink'); print ajax_autoselect('downloadlink'); diff --git a/htdocs/ecm/index.php b/htdocs/ecm/index.php index 56f9b692e94..8841778ce26 100644 --- a/htdocs/ecm/index.php +++ b/htdocs/ecm/index.php @@ -337,165 +337,6 @@ dol_fiche_head($head, 'index', $langs->trans("ECMArea").' - '.$langs->trans("ECM $module='ecm'; include DOL_DOCUMENT_ROOT.'/ecm/tpl/filemanager.tpl.php'; - -/* -// Start container of all panels -?> - -
-
-'; - -// Toolbar -if ($user->rights->ecm->setup) -{ - print ''; - print ''; - print ''; -} -else -{ - print ''; - print ''; - print ''; -} -$url=((! empty($conf->use_javascript_ajax) && empty($conf->global->MAIN_ECM_DISABLE_JS))?'#':($_SERVER["PHP_SELF"].'?action=refreshmanual'.($module?'&module='.$module:'').($section?'&section='.$section:''))); -print ''; -print ''; -print ''; - - -// Start Add new file area -$nameforformuserfile = 'formuserfileecm'; - -print '
'; - -// To attach new file -if ((! empty($conf->use_javascript_ajax) && empty($conf->global->MAIN_ECM_DISABLE_JS)) || ! empty($section)) -{ - if ((empty($section) || $section == -1) && ($module != 'medias')) - { - ?> - - form_attach_new_file($_SERVER["PHP_SELF"], 'none', 0, ($section?$section:-1), $user->rights->ecm->upload, 48, null, '', 0, '', 0, $nameforformuserfile); -} -else print ' '; - -print '
'; -// End Add new file area - - -print '
'; -// End top panel, toolbar - -?> -
-
-formconfirm($_SERVER["PHP_SELF"].'?section='.$section, $langs->trans('DeleteSection'), $langs->trans('ConfirmDeleteSection',$ecmdir->label), 'confirm_deletesection','','',1); -} -// End confirm - - -if (empty($action) || $action == 'file_manager' || preg_match('/refresh/i',$action) || $action == 'delete') -{ - print ''."\n"; - - print ''."\n"; - print ''."\n"; - print ''; - - $showonrightsize=''; - - // Manual section - $htmltooltip=$langs->trans("ECMAreaDesc2"); - - if (! empty($conf->use_javascript_ajax) && empty($conf->global->MAIN_ECM_DISABLE_JS)) - { - print ''; - } - else - { - print ''; - } - - - print "
'; - print ' '.$langs->trans("ECMSections"); - print '
'; - - // Show filemanager tree (will be filled by call of ajax enablefiletreeajax.tpl.php that execute ajaxdirtree.php) - print '
'; - - if ($action == 'deletefile') print $form->formconfirm('eeeee', $langs->trans('DeleteFile'), $langs->trans('ConfirmDeleteFile'), 'confirm_deletefile', '', '', 'deletefile'); - - print '
'; - - if (empty($module)) $module='ecm'; - - $_POST['modulepart'] = $module; - $_POST['openeddir'] = GETPOST('openeddir'); - $_POST['dir'] = empty($_POST['dir'])?'/':$_POST['dir']; - - // Show filemanager tree (will be filled by direct include of ajaxdirtree.php in mode noajax, this will return all dir - all levels - to show) - print '
'; - - $mode='noajax'; - $url=DOL_URL_ROOT.'/ecm/index.php'; - include DOL_DOCUMENT_ROOT.'/core/ajax/ajaxdirtree.php'; - - print '
'; - print '
"; -} - - -// End left panel -?> -
-
-
-
- -
-
- -
- -use_javascript_ajax) && empty($conf->global->MAIN_ECM_DISABLE_JS)) { - include DOL_DOCUMENT_ROOT.'/ecm/tpl/enablefiletreeajax.tpl.php'; -} -*/ - // End of page dol_fiche_end(); diff --git a/htdocs/ecm/tpl/enablefiletreeajax.tpl.php b/htdocs/ecm/tpl/enablefiletreeajax.tpl.php index 4be1bf1979a..3e77c0acd92 100644 --- a/htdocs/ecm/tpl/enablefiletreeajax.tpl.php +++ b/htdocs/ecm/tpl/enablefiletreeajax.tpl.php @@ -33,8 +33,8 @@ $(document).ready(function() { $('#filetree').fileTree({ root: '', - // Ajax called if we click to expand a dir (not a file). Parameter 'dir' is provided as a POST parameter by fileTree code. - script: '', + // Ajax called if we click to expand a dir (not a file). Parameter 'dir' is provided as a POST parameter by fileTree code to this following URL. + script: '', folderEvent: 'click', // 'dblclick' multiFolder: false }, // Called if we click on a file (not a dir) @@ -46,7 +46,7 @@ $(document).ready(function() { function(elem) { id=elem.attr('id').substr(12); // We get id that is 'fmdirlia_id_xxx' (id we want is xxx) jQuery("#_section_dir").val(elem.attr('rel')); - jQuery("#_section_id").val(id); + jQuery("#_section_id").val(id); jQuery('#').show(); } ); @@ -73,7 +73,7 @@ function loadandshowpreview(filedirname,section) $('#ecmfileview').empty(); - var url = '?action=preview&module=§ion='+section+'&file='+urlencode(filedirname); + var url = '?action=preview&module=§ion='+section+'&file='+urlencode(filedirname); $.get(url, function(data) { //alert('Load of url '+url+' was performed : '+data); pos=data.indexOf("TYPE=directory",0); diff --git a/htdocs/ecm/tpl/filemanager.tpl.php b/htdocs/ecm/tpl/filemanager.tpl.php index e80e9fd3e83..c5216deb170 100644 --- a/htdocs/ecm/tpl/filemanager.tpl.php +++ b/htdocs/ecm/tpl/filemanager.tpl.php @@ -57,8 +57,8 @@ else } if ($module == 'ecm') { - $url=((! empty($conf->use_javascript_ajax) && empty($conf->global->MAIN_ECM_DISABLE_JS))?'#':($_SERVER["PHP_SELF"].'?action=refreshmanual'.($module?'&module='.$module:'').($section?'&section='.$section:''))); - print ''; + $tmpurl=((! empty($conf->use_javascript_ajax) && empty($conf->global->MAIN_ECM_DISABLE_JS))?'#':($_SERVER["PHP_SELF"].'?action=refreshmanual'.($module?'&module='.$module:'').($section?'&section='.$section:''))); + print ''; print ''; print ''; } @@ -150,7 +150,7 @@ if (empty($action) || $action == 'file_manager' || preg_match('/refresh/i',$acti print '
'; $mode='noajax'; - $url=DOL_URL_ROOT.'/ecm/index.php'; + if (empty($url)) $url=DOL_URL_ROOT.'/ecm/index.php'; include DOL_DOCUMENT_ROOT.'/core/ajax/ajaxdirtree.php'; print '
'; @@ -173,7 +173,7 @@ if (empty($action) || $action == 'file_manager' || preg_match('/refresh/i',$acti $mode='noajax'; -$url=DOL_URL_ROOT.'/ecm/index.php'; +if (empty($url)) $url=DOL_URL_ROOT.'/ecm/index.php'; include_once DOL_DOCUMENT_ROOT.'/core/ajax/ajaxdirpreview.php'; diff --git a/htdocs/website/index.php b/htdocs/website/index.php index 79eca309e59..b3f1116d50c 100644 --- a/htdocs/website/index.php +++ b/htdocs/website/index.php @@ -52,7 +52,6 @@ $pageid=GETPOST('pageid', 'int'); $pageref=GETPOST('pageref', 'aZ09'); $action=GETPOST('action','alpha'); - if (GETPOST('delete')) { $action='delete'; } if (GETPOST('preview')) $action='preview'; if (GETPOST('createsite')) { $action='createsite'; } @@ -67,6 +66,18 @@ if (GETPOST('editcontent')) { $action='editcontent'; } if (GETPOST('createfromclone')) { $action='createfromclone'; } if (GETPOST('createpagefromclone')) { $action='createpagefromclone'; } +// Load variable for pagination +$limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit; +$sortfield = GETPOST("sortfield",'alpha'); +$sortorder = GETPOST("sortorder",'alpha'); +$page = GETPOST("page",'int'); +if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1 +$offset = $limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; +//if (! $sortfield) $sortfield='name'; +//if (! $sortorder) $sortorder='ASC'; + if (empty($action)) $action='preview'; $object=new Website($db); @@ -111,7 +122,6 @@ $urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current - /* * Actions */ @@ -1792,6 +1802,7 @@ if ($action == 'file_manager') //print '
'.$langs->trans("FeatureNotYetAvailable").''; $module = 'medias'; + if (empty($url)) $url=DOL_URL_ROOT.'/website/index.php'; include DOL_DOCUMENT_ROOT.'/ecm/tpl/filemanager.tpl.php'; } From beacf4225ff0c414a8848fd658eb9933d11a9d12 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 10 Nov 2017 15:29:12 +0100 Subject: [PATCH 030/131] Work on filemanager --- htdocs/core/ajax/ajaxdirpreview.php | 2 +- htdocs/core/class/html.formfile.class.php | 7 ++-- htdocs/core/js/lib_foot.js.php | 6 ++- htdocs/ecm/docdir.php | 26 +++++++++---- htdocs/ecm/tpl/filemanager.tpl.php | 45 +++++++++++++---------- htdocs/main.inc.php | 4 +- htdocs/theme/eldy/style.css.php | 2 +- htdocs/website/index.php | 23 +++++++++++- 8 files changed, 80 insertions(+), 35 deletions(-) diff --git a/htdocs/core/ajax/ajaxdirpreview.php b/htdocs/core/ajax/ajaxdirpreview.php index 9107b604e80..90e5bc1521f 100644 --- a/htdocs/core/ajax/ajaxdirpreview.php +++ b/htdocs/core/ajax/ajaxdirpreview.php @@ -268,7 +268,7 @@ if ($type == 'directory') if ($module == 'medias') { - $useinecm = 0; + $useinecm = 2; $modulepart='medias'; $perm=($user->rights->website->write || $user->rights->emailing->creer); $title='none'; diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index 2a514f65f1f..bc162abd170 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -917,6 +917,7 @@ class FormFile * @param int $useinecm Change output for use in ecm module: * 0: Add a previw link. Show also rename and crop file * 1: Add link to edit ECM entry + * 2: Add rename and crop file * @param string $textifempty Text to show if filearray is empty ('NoFileFound' if not defined) * @param int $maxlength Maximum length of file name shown. * @param string $title Title before list. Use 'none' to disable title. @@ -1128,11 +1129,11 @@ class FormFile // Delete or view link // ($param must start with &) print '
'; - if ($useinecm) + if ($useinecm == 1) { print ''.img_view('default', 0, 'class="paddingrightonly"').''; } - else + if (! $useinecm || $useinecm == 2) { $newmodulepart=$modulepart; if (in_array($modulepart, array('product','produit','service'))) $newmodulepart='produit|service'; @@ -1151,7 +1152,7 @@ class FormFile if ($permtoeditline) { - print ''.img_edit('default',0,'class="paddingrightonly"').''; + print ''.img_edit('default',0,'class="paddingrightonly"').''; } } if ($permonobject) diff --git a/htdocs/core/js/lib_foot.js.php b/htdocs/core/js/lib_foot.js.php index c133e0014f1..d3b3db60ef8 100644 --- a/htdocs/core/js/lib_foot.js.php +++ b/htdocs/core/js/lib_foot.js.php @@ -58,7 +58,11 @@ if (empty($conf->dol_no_mouse_hover)) return $(this).prop(\'title\'); /* To force to get title as is */ } }); - jQuery(".classfortooltiponclicktext").dialog({ closeOnEscape: true, classes: { "ui-dialog": "highlight" }, maxHeight: window.innerHeight-60, width: '.($conf->browser->layout == 'phone' ? 400 : 700).', autoOpen: false }).css("z-index: 5000"); + jQuery(".classfortooltiponclicktext").dialog( + { closeOnEscape: true, classes: { "ui-dialog": "highlight" }, + maxHeight: window.innerHeight-60, width: '.($conf->browser->layout == 'phone' ? 400 : 700).', + modal: true, + autoOpen: false }).css("z-index: 5000"); jQuery(".classfortooltiponclick").click(function () { console.log("We click on tooltip for element with dolid="+$(this).attr(\'dolid\')); if ($(this).attr(\'dolid\')) diff --git a/htdocs/ecm/docdir.php b/htdocs/ecm/docdir.php index b3b9fa528e0..2fa84f8b96d 100644 --- a/htdocs/ecm/docdir.php +++ b/htdocs/ecm/docdir.php @@ -42,8 +42,10 @@ $langs->load("categories"); if (! $user->rights->ecm->setup) accessforbidden(); // Get parameters -$socid = GETPOST('socid','int'); -$action=GETPOST('action','alpha'); +$socid = GETPOST('socid','int'); +$action = GETPOST('action','alpha'); +$cancel = GETPOST('cancel', 'aZ09'); +$backtopage = GETPOST('backtopage', 'alpha'); $confirm=GETPOST('confirm','alpha'); // Security check @@ -86,11 +88,20 @@ if (! empty($section)) // Action ajout d'un produit ou service if ($action == 'add' && $user->rights->ecm->setup) { - if (! empty($_POST["cancel"])) + if ($cancel) { - header("Location: ".DOL_URL_ROOT.'/ecm/index.php?action=file_manager'); - exit; + if (! empty($backtopage)) + { + header("Location: ".$backtopage); + exit; + } + else + { + header("Location: ".DOL_URL_ROOT.'/ecm/index.php?action=file_manager'); + exit; + } } + $ecmdir->ref = trim($_POST["ref"]); $ecmdir->label = trim($_POST["label"]); $ecmdir->description = trim($_POST["desc"]); @@ -150,10 +161,11 @@ if ($action == 'create') print ''; print ''; print ''; + print ''; $title=$langs->trans("ECMNewSection"); print load_fiche_titre($title); - + dol_fiche_head(); print ''; @@ -206,7 +218,7 @@ if (empty($action) || $action == 'delete_section') if ($action == 'delete_section') { print $form->formconfirm($_SERVER["PHP_SELF"].'?section='.$section, $langs->trans('DeleteSection'), $langs->trans('ConfirmDeleteSection',$ecmdir->label), 'confirm_deletesection'); - + } // Construit fiche rubrique diff --git a/htdocs/ecm/tpl/filemanager.tpl.php b/htdocs/ecm/tpl/filemanager.tpl.php index c5216deb170..d201e73798e 100644 --- a/htdocs/ecm/tpl/filemanager.tpl.php +++ b/htdocs/ecm/tpl/filemanager.tpl.php @@ -43,25 +43,32 @@ if (($action == 'delete' || $action == 'file_manager_delete') && empty($conf->us print '
'; // Toolbar -if ($user->rights->ecm->setup) -{ - print ''; - print ''; - print ''; -} -else -{ - print ''; - print ''; - print ''; -} -if ($module == 'ecm') -{ - $tmpurl=((! empty($conf->use_javascript_ajax) && empty($conf->global->MAIN_ECM_DISABLE_JS))?'#':($_SERVER["PHP_SELF"].'?action=refreshmanual'.($module?'&module='.$module:'').($section?'&section='.$section:''))); - print ''; - print ''; - print ''; -} +//if (preg_match('/\/ecm/', $_SERVER['PHP_SELF'])) { +//if ($module == 'ecm') { + $permtoadd = 0; + if ($module == 'ecm') $permtoadd = $user->rights->ecm->setup; + if ($module == 'medias') $permtoadd = ($user->rights->ecm->setup || $user->rights->website->setup); + + if ($permtoadd) + { + print ''; + print ''; + print ''; + } + else + { + print ''; + print ''; + print ''; + } + if ($module == 'ecm') + { + $tmpurl=((! empty($conf->use_javascript_ajax) && empty($conf->global->MAIN_ECM_DISABLE_JS))?'#':($_SERVER["PHP_SELF"].'?action=refreshmanual'.($module?'&module='.$module:'').($section?'&section='.$section:''))); + print ''; + print ''; + print ''; + } +//} // Start "Add new file" area $nameforformuserfile = 'formuserfileecm'; diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 9389d960171..1d049e670c9 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -1858,7 +1858,7 @@ if (! function_exists("llxFooter")) global $delayedhtmlcontent; $ext='version='.urlencode(DOL_VERSION); - + // Global html output events ($mesgs, $errors, $warnings) dol_htmloutput_events($disabledoutputofmessages); @@ -1918,7 +1918,7 @@ if (! function_exists("llxFooter")) if (! empty($conf->use_javascript_ajax)) { print "\n".''."\n"; - print ''."\n"; + print ''."\n"; } // Wrapper to add log when clicking on download or preview diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 03825de4406..fb9b9724114 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -4844,7 +4844,7 @@ div.tabsElem a.tab { @media only screen and (max-width: 1024px) { div#ecm-layout-west { - width: 100%; + width: calc(100% - 4px); clear: both; } div#ecm-layout-center { diff --git a/htdocs/website/index.php b/htdocs/website/index.php index b3f1116d50c..d030bdb4647 100644 --- a/htdocs/website/index.php +++ b/htdocs/website/index.php @@ -1161,6 +1161,8 @@ if ($action == 'edit') $style=''; if ($action != 'preview' && $action != 'editcontent' && $action != 'editsource') $style=' margin-bottom: 5px;'; +if (! GETPOST('hide_websitemenu')) +{ //var_dump($objectpage);exit; print '
'; @@ -1221,6 +1223,23 @@ if (count($object->records) > 0) print '   '; print ''; + /*print ''.dol_escape_htmltag($langs->trans("MediaFiles")).''; + print ''; + */ } print '
'; @@ -1465,8 +1484,10 @@ else $action=''; } - print '
'; // end current websitebar +} + + $head = array(); From 73fe991aedd84b49953efe48b2b92983417dac1e Mon Sep 17 00:00:00 2001 From: Neil Orley Date: Fri, 10 Nov 2017 15:46:53 +0100 Subject: [PATCH 031/131] NEW Return the order object when validate Return the order object when the order is validated using the REST API --- htdocs/commande/class/api_orders.class.php | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/htdocs/commande/class/api_orders.class.php b/htdocs/commande/class/api_orders.class.php index a6788f95698..298333e1fb8 100644 --- a/htdocs/commande/class/api_orders.class.php +++ b/htdocs/commande/class/api_orders.class.php @@ -492,13 +492,17 @@ class Orders extends DolibarrApi if ($result < 0) { throw new RestException(500, 'Error when validating Order: '.$this->commande->error); } + $result = $this->commande->fetch($id); + if( ! $result ) { + throw new RestException(404, 'Order not found'); + } - return array( - 'success' => array( - 'code' => 200, - 'message' => 'Order validated (Ref='.$this->commande->ref.')' - ) - ); + if( ! DolibarrApi::_checkAccessToResource('commande',$this->commande->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + $this->commande->fetchObjectLinked(); + return $this->_cleanObjectDatas($this->commande); } /** From 182fe4a90f99fbcc664f2243b5d7f3636e8cd94b Mon Sep 17 00:00:00 2001 From: Neil Orley Date: Fri, 10 Nov 2017 15:48:43 +0100 Subject: [PATCH 032/131] Change HTTP response code when nothing modified --- htdocs/commande/class/api_orders.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/commande/class/api_orders.class.php b/htdocs/commande/class/api_orders.class.php index 298333e1fb8..60f1be1e00c 100644 --- a/htdocs/commande/class/api_orders.class.php +++ b/htdocs/commande/class/api_orders.class.php @@ -490,7 +490,7 @@ class Orders extends DolibarrApi throw new RestException(500, 'Error nothing done. May be object is already validated'); } if ($result < 0) { - throw new RestException(500, 'Error when validating Order: '.$this->commande->error); + throw new RestException(304, 'Error when validating Order: '.$this->commande->error); } $result = $this->commande->fetch($id); if( ! $result ) { From dd93a1793ad5c684c61f7005fa2f546cbcbf0da8 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Fri, 10 Nov 2017 16:12:17 +0100 Subject: [PATCH 033/131] Fix: remove var_dump --- htdocs/core/lib/security2.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/security2.lib.php b/htdocs/core/lib/security2.lib.php index e953a8018cb..7d305ded7d4 100644 --- a/htdocs/core/lib/security2.lib.php +++ b/htdocs/core/lib/security2.lib.php @@ -456,7 +456,7 @@ function getRandomPassword($generic=false) $randomCode = ""; $nbofchar = round($length/3); $nbofcharlast = ($length - 2*$nbofchar); - var_dump($nbofchar.'-'.$nbofcharlast); + //var_dump($nbofchar.'-'.$nbofcharlast); if (function_exists('random_int')) // Cryptographic random { $max = strlen($lowercase) - 1; From c68f717071cba21726653ac9cee4a6ff7df33a1a Mon Sep 17 00:00:00 2001 From: Neil Orley Date: Fri, 10 Nov 2017 16:22:20 +0100 Subject: [PATCH 034/131] NEW Update availability Add the ability to update availability while updating an invoice using the REST API --- htdocs/commande/class/api_orders.class.php | 50 ++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/htdocs/commande/class/api_orders.class.php b/htdocs/commande/class/api_orders.class.php index 60f1be1e00c..086379a3989 100644 --- a/htdocs/commande/class/api_orders.class.php +++ b/htdocs/commande/class/api_orders.class.php @@ -413,6 +413,12 @@ class Orders extends DolibarrApi $this->commande->$field = $value; } + // Update availability + if( isset($this->commande->availability_id) && !empty($this->commande->availability_id) ) { + if($this->commande->availability($this->commande->availability_id) < 0) + throw new RestException(400, 'Error while updating availability'); + } + if($this->commande->update($id, DolibarrApiAccess::$user, 1, '', '', 'update')) return $this->get($id); @@ -545,6 +551,50 @@ class Orders extends DolibarrApi ); } + /** + * Set an order to draft + * + * @param int $id Order ID + * + * @url POST {id}/settodraft + * + * @return array + */ + function settodraft($id) + { + if(! DolibarrApiAccess::$user->rights->commande->creer) { + throw new RestException(401); + } + $result = $this->commande->fetch($id); + if( ! $result ) { + throw new RestException(404, 'Order not found'); + } + + if( ! DolibarrApi::_checkAccessToResource('commande',$this->commande->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + $result = $this->commande->set_draft(DolibarrApiAccess::$user); + if ($result == 0) { + throw new RestException(304, 'Nothing done. May be object is already closed'); + } + if ($result < 0) { + throw new RestException(500, 'Error when closing Order: '.$this->commande->error); + } + + $result = $this->commande->fetch($id); + if( ! $result ) { + throw new RestException(404, 'Order not found'); + } + + if( ! DolibarrApi::_checkAccessToResource('commande',$this->commande->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + $this->commande->fetchObjectLinked(); + return $this->_cleanObjectDatas($this->commande); + } + /** * Clean sensible object datas From 4dfb0a8f1bf04248536acf77b2a92f8cee98535a Mon Sep 17 00:00:00 2001 From: Neil Orley Date: Fri, 10 Nov 2017 16:42:06 +0100 Subject: [PATCH 035/131] NEW add the ability to regenerate an pdf for the order module add the ability to regenerate an pdf for the order module --- htdocs/api/class/api_documents.class.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/htdocs/api/class/api_documents.class.php b/htdocs/api/class/api_documents.class.php index da97215dc0c..669fc09911e 100644 --- a/htdocs/api/class/api_documents.class.php +++ b/htdocs/api/class/api_documents.class.php @@ -119,6 +119,20 @@ class Documents extends DolibarrApi throw new RestException(500, 'Error generating document'); } } + if ($module_part == 'commande' || $module_part == 'order') + { + require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php'; + $this->order = new Commande($this->db); + $result = $this->order->fetch(0, preg_replace('/\.[^\.]+$/', '', basename($original_file))); + if( ! $result ) { + throw new RestException(404, 'Order not found'); + } + $result = $this->order->generateDocument($this->order->modelpdf, $langs, $hidedetails, $hidedesc, $hideref); + if( $result <= 0 ) { + throw new RestException(500, 'Error generating document'); + } + } + } $filename = basename($original_file); From 3ffe1b6725687aede5f4cb26c88b3e34069165a2 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Fri, 10 Nov 2017 16:51:37 +0100 Subject: [PATCH 036/131] Fix: missing status 3 (only on form) --- htdocs/core/class/commonobject.class.php | 2 +- htdocs/core/tpl/extrafields_view.tpl.php | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 7f73630f7f6..4138607de28 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -5620,7 +5620,7 @@ abstract class CommonObject foreach($extrafields->attribute_label as $key=>$label) { if (empty($extrafields->attribute_list[$key])) continue; // 0 = Never visible field - if (($mode == 'create' || $mode == 'edit') && abs($extrafields->attribute_list[$key]) != 1) continue; // <> -1 and <> 1 = not visible on forms, only on list + if (($mode == 'create' || $mode == 'edit') && abs($extrafields->attribute_list[$key]) != 1 && abs($extrafields->attribute_list[$key]) != 3) continue; // <> -1 and <> 1 and <> 3 = not visible on forms, only on list // Load language if required if (! empty($extrafields->attributes[$this->table_element]['langfile'][$key])) $langs->load($extrafields->attributes[$this->table_element]['langfile'][$key]); diff --git a/htdocs/core/tpl/extrafields_view.tpl.php b/htdocs/core/tpl/extrafields_view.tpl.php index b57025e3dd6..589a7b56e0e 100644 --- a/htdocs/core/tpl/extrafields_view.tpl.php +++ b/htdocs/core/tpl/extrafields_view.tpl.php @@ -43,7 +43,8 @@ if (empty($reshook) && ! empty($extrafields->attributes[$object->table_element][ foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $label) { // Discard if extrafield is a hidden field on form - if (abs($extrafields->attributes[$object->table_element]['list'][$key]) != 1) continue; + if (empty($extrafields->attributes[$object->table_element]['list'][$key])) continue; // 0 = Never visible field + if (abs($extrafields->attributes[$object->table_element]['list'][$key]) != 1 && abs($extrafields->attributes[$object->table_element]['list'][$key]) != 3) continue; // <> -1 and <> 1 and <> 3 = not visible on forms, only on list // Load language if required if (! empty($extrafields->attributes[$object->table_element]['langfile'][$key])) $langs->load($extrafields->attributes[$object->table_element]['langfile'][$key]); From 56829656baf4bbf460021ae5e92087dd6021e312 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Fri, 10 Nov 2017 17:57:11 +0100 Subject: [PATCH 037/131] Fix: Avoid ldap error --- htdocs/adherents/class/adherent.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index 81167eebc5e..d42f67f075a 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -1969,7 +1969,7 @@ class Adherent extends CommonObject $this->fullname=$this->getFullName($langs); // For avoid ldap error when firstname and lastname are empty - if ($this->morphy == 'mor' && empty($this->fullname)) { + if ($this->morphy == 'mor' && (empty($this->fullname) || $this->fullname == $this->societe)) { $this->fullname = $this->societe; $this->lastname = $this->societe; } From cb03b2f3074965ac6cd5f9e8f9e5b593400cbfdb Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 10 Nov 2017 18:14:29 +0100 Subject: [PATCH 038/131] NEW Can sort joined files on thirdparty and user card. --- htdocs/core/ajax/row.php | 4 ++-- htdocs/core/class/html.formfile.class.php | 8 +++---- htdocs/core/photos_resize.php | 24 ++++++++++++++++--- .../tpl/document_actions_post_headers.tpl.php | 2 +- htdocs/societe/document.php | 2 +- htdocs/user/class/user.class.php | 13 +++++----- htdocs/user/document.php | 2 +- 7 files changed, 37 insertions(+), 18 deletions(-) diff --git a/htdocs/core/ajax/row.php b/htdocs/core/ajax/row.php index 6e358bdbd88..71a5a0aac88 100644 --- a/htdocs/core/ajax/row.php +++ b/htdocs/core/ajax/row.php @@ -63,9 +63,9 @@ if ((isset($_POST['roworder']) && ! empty($_POST['roworder'])) && (isset($_POST[ $row->table_element_line = $table_element_line; $row->fk_element = $fk_element; $row->id = $element_id; - $row->line_ajaxorder($newrowordertab); + $row->line_ajaxorder($newrowordertab); // This update field rank or position in table table_element_line - // Reorder line to have position of chilren lines sharing same counter than parent lines + // Reorder line to have position of children lines sharing same counter than parent lines // This should be useless because there is no need to have children sharing same counter than parent, but well, it's cleaner into database. if (in_array($fk_element,array('fk_facture','fk_propal','fk_commande'))) { diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index bc162abd170..4c354b66107 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -1042,10 +1042,10 @@ class FormFile { completeFileArrayWithDatabaseInfo($filearray, $relativedir); - /*var_dump($sortfield); - var_dump($sortorder);*/ - if ($sortfield && $sortorder) + //var_dump($sortfield.' - '.$sortorder); + if ($sortfield && $sortorder) // If $sortfield is for example 'position_name', we will sort on the property 'position_name' (that is concat of position+name) { + //var_dump($sortfield); $filearray=dol_sort_array($filearray, $sortfield, $sortorder); } //var_dump($filearray); @@ -1139,7 +1139,7 @@ class FormFile if (in_array($modulepart, array('product','produit','service'))) $newmodulepart='produit|service'; $disablecrop=1; - if (in_array($modulepart, array('product','produit','service','expensereport','holiday','project','user'))) $disablecrop=0; + if (in_array($modulepart, array('societe','product','produit','service','expensereport','holiday','project','user'))) $disablecrop=0; if (! $disablecrop && image_format_supported($file['name']) > 0) { diff --git a/htdocs/core/photos_resize.php b/htdocs/core/photos_resize.php index fcedc2a4e11..9a11523f39b 100644 --- a/htdocs/core/photos_resize.php +++ b/htdocs/core/photos_resize.php @@ -67,9 +67,15 @@ elseif ($modulepart == 'expensereport') } elseif ($modulepart == 'user') { - $result=restrictedArea($user,'user',$id,'user'); - if (! $user->rights->user->user->lire) accessforbidden(); - $accessallowed=1; + $result=restrictedArea($user,'user',$id,'user'); + if (! $user->rights->user->user->lire) accessforbidden(); + $accessallowed=1; +} +elseif ($modulepart == 'societe') +{ + $result=restrictedArea($user,'societe',$id,'societe'); + if (! $user->rights->societe->lire) accessforbidden(); + $accessallowed=1; } // Security: @@ -115,6 +121,17 @@ elseif ($modulepart == 'holiday') $dir=$conf->holiday->dir_output; // By default } } +elseif ($modulepart == 'societe') +{ + require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php'; + $object = new Societe($db); + if ($id > 0) + { + $result = $object->fetch($id); + if ($result <= 0) dol_print_error($db,'Failed to load object'); + $dir=$conf->societe->dir_output; + } +} elseif ($modulepart == 'user') { require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php'; @@ -145,6 +162,7 @@ if (empty($backtourl)) else if (in_array($modulepart, array('holiday'))) $backtourl=DOL_URL_ROOT."/holiday/document.php?id=".$id.'&file='.urldecode($_POST["file"]); else if (in_array($modulepart, array('project'))) $backtourl=DOL_URL_ROOT."/projet/document.php?id=".$id.'&file='.urldecode($_POST["file"]); else if (in_array($modulepart, array('user'))) $backtourl=DOL_URL_ROOT."/user/document.php?id=".$id.'&file='.urldecode($_POST["file"]); + else if (in_array($modulepart, array('societe'))) $backtourl=DOL_URL_ROOT."/societe/document.php?id=".$id.'&file='.urldecode($_POST["file"]); } diff --git a/htdocs/core/tpl/document_actions_post_headers.tpl.php b/htdocs/core/tpl/document_actions_post_headers.tpl.php index da1cb9658a0..10650364543 100644 --- a/htdocs/core/tpl/document_actions_post_headers.tpl.php +++ b/htdocs/core/tpl/document_actions_post_headers.tpl.php @@ -79,7 +79,7 @@ $formfile->form_attach_new_file( ); $disablemove=1; -if ($modulepart == 'product' || $modulepart == 'produit') $disablemove=0; // Drag and drop for up and down allowed on product +if (in_array($modulepart, array('product', 'produit', 'societe', 'user'))) $disablemove=0; // Drag and drop for up and down allowed on product // List of document $formfile->list_of_documents( diff --git a/htdocs/societe/document.php b/htdocs/societe/document.php index fbfd931b69b..be549d6cac5 100644 --- a/htdocs/societe/document.php +++ b/htdocs/societe/document.php @@ -58,7 +58,7 @@ $offset = $conf->liste_limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; if (! $sortorder) $sortorder="ASC"; -if (! $sortfield) $sortfield="name"; +if (! $sortfield) $sortfield="position_name"; $object = new Societe($db); if ($id > 0 || ! empty($ref)) diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index b9e7378bd31..565e1f014b7 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -40,6 +40,7 @@ class User extends CommonObject { public $element='user'; public $table_element='user'; + public $fk_element='fk_user'; public $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe public $id=0; @@ -53,17 +54,17 @@ class User extends CommonObject public $job; public $signature; public $address; - public $zip; - public $town; - public $state_id; - public $state_code; - public $state; + public $zip; + public $town; + public $state_id; + public $state_code; + public $state; public $office_phone; public $office_fax; public $user_mobile; public $admin; public $login; - public $api_key; + public $api_key; public $entity; //! Clear password in memory diff --git a/htdocs/user/document.php b/htdocs/user/document.php index 27cf4eb757a..ff7fe9b5ab9 100644 --- a/htdocs/user/document.php +++ b/htdocs/user/document.php @@ -81,7 +81,7 @@ $offset = $conf->liste_limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; if (! $sortorder) $sortorder="ASC"; -if (! $sortfield) $sortfield="name"; +if (! $sortfield) $sortfield="position_name"; $object = new User($db); if ($id > 0 || ! empty($ref)) From a029b16795c042f6799d118cb38c37b6f6b231b4 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 10 Nov 2017 18:27:03 +0100 Subject: [PATCH 039/131] css --- htdocs/core/class/html.formfile.class.php | 2 +- htdocs/theme/eldy/style.css.php | 3 +++ htdocs/theme/md/style.css.php | 4 +++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index 4c354b66107..7156524a89c 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -1128,7 +1128,7 @@ class FormFile { // Delete or view link // ($param must start with &) - print ''; // Show file size @@ -741,12 +741,11 @@ class FormFile //$out.= '&modulepart='.$modulepart; // TODO obsolete ? //$out.= '&urlsource='.urlencode($urlsource); // TODO obsolete ? $out.= '">'.img_picto($langs->trans("Delete"), 'delete.png').''; - //$out.=''; } if ($printer) { //$out.= ''; print '\n"; @@ -1448,10 +1456,10 @@ class FormFile // File print '
'; + print ''; if ($useinecm == 1) { print ''.img_view('default', 0, 'class="paddingrightonly"').''; diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index fb9b9724114..dce3318d1da 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -398,6 +398,9 @@ td.onholidaymorning, td.onholidayafternoon { td.onholidayallday { background-color: #f4eede; } +td.actionbuttons a { + padding-left: 6px; +} select.flat, form.flat select { font-weight: normal; } diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 92f5f44b64f..266444516f6 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -405,7 +405,9 @@ td.onholidaymorning, td.onholidayafternoon { td.onholidayallday { background-color: #f4eede; } - +td.actionbuttons a { + padding-left: 6px; +} select.flat, form.flat select { font-weight: normal; } From debc0480dd96a2fccbad4e8114560efa7a01de71 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 10 Nov 2017 20:20:59 +0100 Subject: [PATCH 040/131] CSS --- htdocs/core/class/html.formfile.class.php | 52 +++++--- htdocs/core/lib/functions.lib.php | 141 ++++++++++++---------- htdocs/theme/eldy/style.css.php | 4 +- htdocs/theme/md/style.css.php | 4 +- 4 files changed, 112 insertions(+), 89 deletions(-) diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index 7156524a89c..049f768b549 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -713,14 +713,14 @@ class FormFile // Show file name with link to download $out.= ''; - $tmp = $this->showPreview($file,$modulepart,$relativepath,0,$param); - $out.= ($tmp?$tmp.' ':''); - $out.= 'trans("File").': '.$file["name"]).' '.$file["name"]; + $out.= img_mime($file["name"],$langs->trans("File").': '.$file["name"]); + $out.= $file["name"]; $out.= ''."\n"; + $out.= $this->showPreview($file,$modulepart,$relativepath,0,$param); $out.= ''; - $out.= ' '.img_picto($langs->trans("PrintFile", $relativepath),'printer.png').''; } @@ -841,21 +840,24 @@ class FormFile $file_list=dol_dir_list($filedir, 'files', 0, $filterforfilesearch, '\.meta$|\.png$'); // Get list of files starting with name of ref (but not followed by "-" to discard uploaded files) + //var_dump($file_list); // For ajax treatment $out.= ''."\n"; if (! empty($file_list)) { $out=''; + + if (! $found) $out=''; } else { @@ -1062,6 +1072,7 @@ class FormFile && ! preg_match('/\.meta$/i',$file['name'])) { if ($filearray[$key]['rowid'] > 0) $lastrowid = $filearray[$key]['rowid']; + $filepath=$relativepath.$file['name']; $editline=0; $nboflines++; @@ -1071,18 +1082,14 @@ class FormFile print '
'; - $filepath=$relativepath.$file['name']; - - if (! $editline) print $this->showPreview($file,$modulepart,$filepath); - + // Show file name with link to download //print "XX".$file['name']; //$file['name'] must be utf8 - print ''; - - print img_mime($file['name'],$file['name'].' ('.dol_print_size($file['size'],0,0).')').' '; + print img_mime($file['name'], $file['name'].' ('.dol_print_size($file['size'],0,0).')', 'inline-block valignbottom paddingright'); if ($showrelpart == 1) print $relativepath; //print dol_trunc($file['name'],$maxlength,'middle'); if (GETPOST('action','aZ09') == 'editfile' && $file['name'] == basename(GETPOST('urlfile'))) @@ -1097,6 +1104,7 @@ class FormFile print $file['name']; print ''; } + if (! $editline) print $this->showPreview($file, $modulepart, $filepath); print "'; //print "XX".$file['name']; //$file['name'] must be utf8 - print ''; - print img_mime($file['name'],$file['name'].' ('.dol_print_size($file['size'],0,0).')').' '; + print img_mime($file['name'],$file['name'].' ('.dol_print_size($file['size'],0,0).')'); print dol_trunc($file['name'],$maxlength,'middle'); print ''; @@ -1678,7 +1686,11 @@ class FormFile { $out.= ''; //$out.= ''; - if (empty($ruleforpicto)) $out.= img_picto($langs->trans('Preview').' '.$file['name'], 'detail'); + if (empty($ruleforpicto)) + { + //$out.= img_picto($langs->trans('Preview').' '.$file['name'], 'detail'); + $out.=''; + } else $out.= img_mime($relativepath, $langs->trans('Preview').' '.$file['name']); $out.= ''; } diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 1628a09d202..1a6f2d821e0 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -3216,18 +3216,21 @@ function img_allow($allow, $titlealt = 'default') * * @param string $file Filename * @param string $titlealt Text on alt and title of image. Alt only if param notitle is set to 1. If text is "TextA:TextB", use Text A on alt and Text B on title. + * @param string $morecss More css * @return string Return img tag */ -function img_mime($file, $titlealt = '') +function img_mime($file, $titlealt = '', $morecss='') { require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; $mimetype = dol_mimetype($file, '', 1); $mimeimg = dol_mimetype($file, '', 2); + $mimefa = dol_mimetype($file, '', 4); if (empty($titlealt)) $titlealt = 'Mime type: '.$mimetype; - return img_picto_common($titlealt, 'mime/'.$mimeimg); + //return img_picto_common($titlealt, 'mime/'.$mimeimg, 'class="'.$morecss.'"'); + return ''; } @@ -6368,7 +6371,7 @@ function printCommonFooter($zone='private') if (empty($reshook)) { if (! empty($conf->global->MAIN_HTML_FOOTER)) print $conf->global->MAIN_HTML_FOOTER."\n"; - + print "\n"; if (! empty($conf->use_javascript_ajax)) { @@ -6385,7 +6388,7 @@ function printCommonFooter($zone='private') print " $('.login_block').toggle()\n"; print '});'."\n"; } - + // Google Analytics (need Google module) if (! empty($conf->google->enabled) && ! empty($conf->global->MAIN_GOOGLE_AN_ID)) { @@ -6404,7 +6407,7 @@ function printCommonFooter($zone='private') print ' })();'."\n"; } } - + // End of tuning if (! empty($_SERVER['MAIN_SHOW_TUNING_INFO']) || ! empty($conf->global->MAIN_SHOW_TUNING_INFO)) { @@ -6434,7 +6437,7 @@ function printCommonFooter($zone='private') } print '");'."\n"; } - + print "\n".''."\n"; } @@ -6443,7 +6446,7 @@ function printCommonFooter($zone='private') { print_r(xdebug_get_code_coverage()); } - + // If there is some logs in buffer to show if (count($conf->logbuffer)) { @@ -6736,92 +6739,93 @@ function getAdvancedPreviewUrl($modulepart, $relativepath, $alldata=0, $param='' * * @param string $file Filename we looking for MIME type * @param string $default Default mime type if extension not found in known list - * @param int $mode 0=Return full mime, 1=otherwise short mime string, 2=image for mime type, 3=source language + * @param int $mode 0=Return full mime, 1=otherwise short mime string, 2=image for mime type, 3=source language, 4=css of font fa * @return string Return a mime type family (text/xxx, application/xxx, image/xxx, audio, video, archive) * @see image_format_supported (images.lib.php) */ -function dol_mimetype($file,$default='application/octet-stream',$mode=0) +function dol_mimetype($file, $default='application/octet-stream', $mode=0) { $mime=$default; $imgmime='other.png'; + $famime='file-o'; $srclang=''; $tmpfile=preg_replace('/\.noexe$/','',$file); // Text files - if (preg_match('/\.txt$/i',$tmpfile)) { $mime='text/plain'; $imgmime='text.png'; } - if (preg_match('/\.rtx$/i',$tmpfile)) { $mime='text/richtext'; $imgmime='text.png'; } - if (preg_match('/\.csv$/i',$tmpfile)) { $mime='text/csv'; $imgmime='text.png'; } - if (preg_match('/\.tsv$/i',$tmpfile)) { $mime='text/tab-separated-values'; $imgmime='text.png'; } - if (preg_match('/\.(cf|conf|log)$/i',$tmpfile)) { $mime='text/plain'; $imgmime='text.png'; } - if (preg_match('/\.ini$/i',$tmpfile)) { $mime='text/plain'; $imgmime='text.png'; $srclang='ini'; } - if (preg_match('/\.css$/i',$tmpfile)) { $mime='text/css'; $imgmime='css.png'; $srclang='css'; } + if (preg_match('/\.txt$/i',$tmpfile)) { $mime='text/plain'; $imgmime='text.png'; $famime='file-text-o'; } + if (preg_match('/\.rtx$/i',$tmpfile)) { $mime='text/richtext'; $imgmime='text.png'; $famime='file-text-o'; } + if (preg_match('/\.csv$/i',$tmpfile)) { $mime='text/csv'; $imgmime='text.png'; $famime='file-text-o'; } + if (preg_match('/\.tsv$/i',$tmpfile)) { $mime='text/tab-separated-values'; $imgmime='text.png'; $famime='file-text-o'; } + if (preg_match('/\.(cf|conf|log)$/i',$tmpfile)) { $mime='text/plain'; $imgmime='text.png'; $famime='file-text-o'; } + if (preg_match('/\.ini$/i',$tmpfile)) { $mime='text/plain'; $imgmime='text.png'; $srclang='ini'; $famime='file-text-o'; } + if (preg_match('/\.css$/i',$tmpfile)) { $mime='text/css'; $imgmime='css.png'; $srclang='css'; $famime='file-text-o'; } // Certificate files - if (preg_match('/\.(crt|cer|key|pub)$/i',$tmpfile)) { $mime='text/plain'; $imgmime='text.png'; } + if (preg_match('/\.(crt|cer|key|pub)$/i',$tmpfile)) { $mime='text/plain'; $imgmime='text.png'; $famime='file-text-o'; } // HTML/XML - if (preg_match('/\.(html|htm|shtml)$/i',$tmpfile)) { $mime='text/html'; $imgmime='html.png'; $srclang='html'; } - if (preg_match('/\.(xml|xhtml)$/i',$tmpfile)) { $mime='text/xml'; $imgmime='other.png'; $srclang='xml'; } + if (preg_match('/\.(html|htm|shtml)$/i',$tmpfile)) { $mime='text/html'; $imgmime='html.png'; $srclang='html'; $famime='file-text-o'; } + if (preg_match('/\.(xml|xhtml)$/i',$tmpfile)) { $mime='text/xml'; $imgmime='other.png'; $srclang='xml'; $famime='file-text-o'; } // Languages - if (preg_match('/\.bas$/i',$tmpfile)) { $mime='text/plain'; $imgmime='text.png'; $srclang='bas'; } - if (preg_match('/\.(c)$/i',$tmpfile)) { $mime='text/plain'; $imgmime='text.png'; $srclang='c'; } - if (preg_match('/\.(cpp)$/i',$tmpfile)) { $mime='text/plain'; $imgmime='text.png'; $srclang='cpp'; } - if (preg_match('/\.(h)$/i',$tmpfile)) { $mime='text/plain'; $imgmime='text.png'; $srclang='h'; } - if (preg_match('/\.(java|jsp)$/i',$tmpfile)) { $mime='text/plain'; $imgmime='text.png'; $srclang='java'; } - if (preg_match('/\.php([0-9]{1})?$/i',$tmpfile)) { $mime='text/plain'; $imgmime='php.png'; $srclang='php'; } - if (preg_match('/\.phtml$/i',$tmpfile)) { $mime='text/plain'; $imgmime='php.png'; $srclang='php'; } - if (preg_match('/\.(pl|pm)$/i',$tmpfile)) { $mime='text/plain'; $imgmime='pl.png'; $srclang='perl'; } - if (preg_match('/\.sql$/i',$tmpfile)) { $mime='text/plain'; $imgmime='text.png'; $srclang='sql'; } - if (preg_match('/\.js$/i',$tmpfile)) { $mime='text/x-javascript'; $imgmime='jscript.png'; $srclang='js'; } + if (preg_match('/\.bas$/i',$tmpfile)) { $mime='text/plain'; $imgmime='text.png'; $srclang='bas'; $famime='file-code-o'; } + if (preg_match('/\.(c)$/i',$tmpfile)) { $mime='text/plain'; $imgmime='text.png'; $srclang='c'; $famime='file-code-o'; } + if (preg_match('/\.(cpp)$/i',$tmpfile)) { $mime='text/plain'; $imgmime='text.png'; $srclang='cpp'; $famime='file-code-o'; } + if (preg_match('/\.(h)$/i',$tmpfile)) { $mime='text/plain'; $imgmime='text.png'; $srclang='h'; $famime='file-code-o'; } + if (preg_match('/\.(java|jsp)$/i',$tmpfile)) { $mime='text/plain'; $imgmime='text.png'; $srclang='java'; $famime='file-code-o'; } + if (preg_match('/\.php([0-9]{1})?$/i',$tmpfile)) { $mime='text/plain'; $imgmime='php.png'; $srclang='php'; $famime='file-code-o'; } + if (preg_match('/\.phtml$/i',$tmpfile)) { $mime='text/plain'; $imgmime='php.png'; $srclang='php'; $famime='file-code-o'; } + if (preg_match('/\.(pl|pm)$/i',$tmpfile)) { $mime='text/plain'; $imgmime='pl.png'; $srclang='perl'; $famime='file-code-o'; } + if (preg_match('/\.sql$/i',$tmpfile)) { $mime='text/plain'; $imgmime='text.png'; $srclang='sql'; $famime='file-code-o'; } + if (preg_match('/\.js$/i',$tmpfile)) { $mime='text/x-javascript'; $imgmime='jscript.png'; $srclang='js'; $famime='file-code-o'; } // Open office - if (preg_match('/\.odp$/i',$tmpfile)) { $mime='application/vnd.oasis.opendocument.presentation'; $imgmime='ooffice.png'; } - if (preg_match('/\.ods$/i',$tmpfile)) { $mime='application/vnd.oasis.opendocument.spreadsheet'; $imgmime='ooffice.png'; } - if (preg_match('/\.odt$/i',$tmpfile)) { $mime='application/vnd.oasis.opendocument.text'; $imgmime='ooffice.png'; } + if (preg_match('/\.odp$/i',$tmpfile)) { $mime='application/vnd.oasis.opendocument.presentation'; $imgmime='ooffice.png'; $famime='file-powerpoint-o'; } + if (preg_match('/\.ods$/i',$tmpfile)) { $mime='application/vnd.oasis.opendocument.spreadsheet'; $imgmime='ooffice.png'; $famime='file-excel-o'; } + if (preg_match('/\.odt$/i',$tmpfile)) { $mime='application/vnd.oasis.opendocument.text'; $imgmime='ooffice.png'; $famime='file-word-o'; } // MS Office - if (preg_match('/\.mdb$/i',$tmpfile)) { $mime='application/msaccess'; $imgmime='mdb.png'; } - if (preg_match('/\.doc(x|m)?$/i',$tmpfile)) { $mime='application/msword'; $imgmime='doc.png'; } - if (preg_match('/\.dot(x|m)?$/i',$tmpfile)) { $mime='application/msword'; $imgmime='doc.png'; } - if (preg_match('/\.xlt(x)?$/i',$tmpfile)) { $mime='application/vnd.ms-excel'; $imgmime='xls.png'; } - if (preg_match('/\.xla(m)?$/i',$tmpfile)) { $mime='application/vnd.ms-excel'; $imgmime='xls.png'; } - if (preg_match('/\.xls$/i',$tmpfile)) { $mime='application/vnd.ms-excel'; $imgmime='xls.png'; } - if (preg_match('/\.xls(b|m|x)$/i',$tmpfile)) { $mime='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'; $imgmime='xls.png'; } - if (preg_match('/\.pps(m|x)?$/i',$tmpfile)) { $mime='application/vnd.ms-powerpoint'; $imgmime='ppt.png'; } - if (preg_match('/\.ppt(m|x)?$/i',$tmpfile)) { $mime='application/x-mspowerpoint'; $imgmime='ppt.png'; } + if (preg_match('/\.mdb$/i',$tmpfile)) { $mime='application/msaccess'; $imgmime='mdb.png'; $famime='file-o'; } + if (preg_match('/\.doc(x|m)?$/i',$tmpfile)) { $mime='application/msword'; $imgmime='doc.png'; $famime='file-word-o'; } + if (preg_match('/\.dot(x|m)?$/i',$tmpfile)) { $mime='application/msword'; $imgmime='doc.png'; $famime='file-word-o'; } + if (preg_match('/\.xlt(x)?$/i',$tmpfile)) { $mime='application/vnd.ms-excel'; $imgmime='xls.png'; $famime='file-excel-o'; } + if (preg_match('/\.xla(m)?$/i',$tmpfile)) { $mime='application/vnd.ms-excel'; $imgmime='xls.png'; $famime='file-excel-o'; } + if (preg_match('/\.xls$/i',$tmpfile)) { $mime='application/vnd.ms-excel'; $imgmime='xls.png'; $famime='file-excel-o'; } + if (preg_match('/\.xls(b|m|x)$/i',$tmpfile)) { $mime='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'; $imgmime='xls.png'; $famime='file-excel-o'; } + if (preg_match('/\.pps(m|x)?$/i',$tmpfile)) { $mime='application/vnd.ms-powerpoint'; $imgmime='ppt.png'; $famime='file-powerpoint-o'; } + if (preg_match('/\.ppt(m|x)?$/i',$tmpfile)) { $mime='application/x-mspowerpoint'; $imgmime='ppt.png'; $famime='file-powerpoint-o'; } // Other - if (preg_match('/\.pdf$/i',$tmpfile)) { $mime='application/pdf'; $imgmime='pdf.png'; } + if (preg_match('/\.pdf$/i',$tmpfile)) { $mime='application/pdf'; $imgmime='pdf.png'; $famime='file-pdf-o'; } // Scripts - if (preg_match('/\.bat$/i',$tmpfile)) { $mime='text/x-bat'; $imgmime='script.png'; $srclang='dos'; } - if (preg_match('/\.sh$/i',$tmpfile)) { $mime='text/x-sh'; $imgmime='script.png'; $srclang='bash'; } - if (preg_match('/\.ksh$/i',$tmpfile)) { $mime='text/x-ksh'; $imgmime='script.png'; $srclang='bash'; } - if (preg_match('/\.bash$/i',$tmpfile)) { $mime='text/x-bash'; $imgmime='script.png'; $srclang='bash'; } + if (preg_match('/\.bat$/i',$tmpfile)) { $mime='text/x-bat'; $imgmime='script.png'; $srclang='dos'; $famime='file-code-o'; } + if (preg_match('/\.sh$/i',$tmpfile)) { $mime='text/x-sh'; $imgmime='script.png'; $srclang='bash'; $famime='file-code-o'; } + if (preg_match('/\.ksh$/i',$tmpfile)) { $mime='text/x-ksh'; $imgmime='script.png'; $srclang='bash'; $famime='file-code-o'; } + if (preg_match('/\.bash$/i',$tmpfile)) { $mime='text/x-bash'; $imgmime='script.png'; $srclang='bash'; $famime='file-code-o'; } // Images - if (preg_match('/\.ico$/i',$tmpfile)) { $mime='image/x-icon'; $imgmime='image.png'; } - if (preg_match('/\.(jpg|jpeg)$/i',$tmpfile)) { $mime='image/jpeg'; $imgmime='image.png'; } - if (preg_match('/\.png$/i',$tmpfile)) { $mime='image/png'; $imgmime='image.png'; } - if (preg_match('/\.gif$/i',$tmpfile)) { $mime='image/gif'; $imgmime='image.png'; } - if (preg_match('/\.bmp$/i',$tmpfile)) { $mime='image/bmp'; $imgmime='image.png'; } - if (preg_match('/\.(tif|tiff)$/i',$tmpfile)) { $mime='image/tiff'; $imgmime='image.png'; } + if (preg_match('/\.ico$/i',$tmpfile)) { $mime='image/x-icon'; $imgmime='image.png'; $famime='file-image-o'; } + if (preg_match('/\.(jpg|jpeg)$/i',$tmpfile)) { $mime='image/jpeg'; $imgmime='image.png'; $famime='file-image-o'; } + if (preg_match('/\.png$/i',$tmpfile)) { $mime='image/png'; $imgmime='image.png'; $famime='file-image-o'; } + if (preg_match('/\.gif$/i',$tmpfile)) { $mime='image/gif'; $imgmime='image.png'; $famime='file-image-o'; } + if (preg_match('/\.bmp$/i',$tmpfile)) { $mime='image/bmp'; $imgmime='image.png'; $famime='file-image-o'; } + if (preg_match('/\.(tif|tiff)$/i',$tmpfile)) { $mime='image/tiff'; $imgmime='image.png'; $famime='file-image-o'; } // Calendar - if (preg_match('/\.vcs$/i',$tmpfile)) { $mime='text/calendar'; $imgmime='other.png'; } - if (preg_match('/\.ics$/i',$tmpfile)) { $mime='text/calendar'; $imgmime='other.png'; } + if (preg_match('/\.vcs$/i',$tmpfile)) { $mime='text/calendar'; $imgmime='other.png'; $famime='file-text-o'; } + if (preg_match('/\.ics$/i',$tmpfile)) { $mime='text/calendar'; $imgmime='other.png'; $famime='file-text-o'; } // Other - if (preg_match('/\.torrent$/i',$tmpfile)) { $mime='application/x-bittorrent'; $imgmime='other.png'; } + if (preg_match('/\.torrent$/i',$tmpfile)) { $mime='application/x-bittorrent'; $imgmime='other.png'; $famime='file-o'; } // Audio - if (preg_match('/\.(mp3|ogg|au|wav|wma|mid)$/i',$tmpfile)) { $mime='audio'; $imgmime='audio.png'; } + if (preg_match('/\.(mp3|ogg|au|wav|wma|mid)$/i',$tmpfile)) { $mime='audio'; $imgmime='audio.png'; $famime='file-audio-o'; } // Video - if (preg_match('/\.ogv$/i',$tmpfile)) { $mime='video/ogg'; $imgmime='video.png'; } - if (preg_match('/\.webm$/i',$tmpfile)) { $mime='video/webm'; $imgmime='video.png'; } - if (preg_match('/\.avi$/i',$tmpfile)) { $mime='video/x-msvideo'; $imgmime='video.png'; } - if (preg_match('/\.divx$/i',$tmpfile)) { $mime='video/divx'; $imgmime='video.png'; } - if (preg_match('/\.xvid$/i',$tmpfile)) { $mime='video/xvid'; $imgmime='video.png'; } - if (preg_match('/\.(wmv|mpg|mpeg)$/i',$tmpfile)) { $mime='video'; $imgmime='video.png'; } + if (preg_match('/\.ogv$/i',$tmpfile)) { $mime='video/ogg'; $imgmime='video.png'; $famime='file-video-o'; } + if (preg_match('/\.webm$/i',$tmpfile)) { $mime='video/webm'; $imgmime='video.png'; $famime='file-video-o'; } + if (preg_match('/\.avi$/i',$tmpfile)) { $mime='video/x-msvideo'; $imgmime='video.png'; $famime='file-video-o'; } + if (preg_match('/\.divx$/i',$tmpfile)) { $mime='video/divx'; $imgmime='video.png'; $famime='file-video-o'; } + if (preg_match('/\.xvid$/i',$tmpfile)) { $mime='video/xvid'; $imgmime='video.png'; $famime='file-video-o'; } + if (preg_match('/\.(wmv|mpg|mpeg)$/i',$tmpfile)) { $mime='video'; $imgmime='video.png'; $famime='file-video-o'; } // Archive - if (preg_match('/\.(zip|rar|gz|tgz|z|cab|bz2|7z|tar|lzh)$/i',$tmpfile)) { $mime='archive'; $imgmime='archive.png'; } // application/xxx where zzz is zip, ... + if (preg_match('/\.(zip|rar|gz|tgz|z|cab|bz2|7z|tar|lzh)$/i',$tmpfile)) { $mime='archive'; $imgmime='archive.png'; $famime='file-archive-o'; } // application/xxx where zzz is zip, ... // Exe - if (preg_match('/\.(exe|com)$/i',$tmpfile)) { $mime='application/octet-stream'; $imgmime='other.png'; } + if (preg_match('/\.(exe|com)$/i',$tmpfile)) { $mime='application/octet-stream'; $imgmime='other.png'; $famime='file-o'; } // Lib - if (preg_match('/\.(dll|lib|o|so|a)$/i',$tmpfile)) { $mime='library'; $imgmime='library.png'; } + if (preg_match('/\.(dll|lib|o|so|a)$/i',$tmpfile)) { $mime='library'; $imgmime='library.png'; $famime='file-o'; } // Err - if (preg_match('/\.err$/i',$tmpfile)) { $mime='error'; $imgmime='error.png'; } + if (preg_match('/\.err$/i',$tmpfile)) { $mime='error'; $imgmime='error.png'; $famime='file-text-o'; } // Return string if ($mode == 1) @@ -6837,7 +6841,10 @@ function dol_mimetype($file,$default='application/octet-stream',$mode=0) { return $srclang; } - + if ($mode == 4) + { + return $famime; + } return $mime; } diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index dce3318d1da..e20ca0c0acc 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -762,7 +762,9 @@ div.myavailability { box-shadow: 1px 1px 25px #aaa; max-width: calc(100% - 56px); } - +.fa-file-text-o, .fa-file-code-o, .fa-file-powerpoint-o, .fa-file-excel-o, .fa-file-word-o, .fa-file-o, .fa-file-image-o, .fa-file-video-o, .fa-file-audio-o, .fa-file-archive-o, .fa-file-pdf-o { + color: #055; +} /* DOL_XXX for future usage (when left menu has been removed). If we do not use datatable */ /*.table-responsive { diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 266444516f6..32add92b970 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -768,7 +768,9 @@ div.myavailability { box-shadow: 1px 1px 25px #aaa; max-width: calc(100% - 56px); } - +.fa-file-text-o, .fa-file-code-o, .fa-file-powerpoint-o, .fa-file-excel-o, .fa-file-word-o, .fa-file-o, .fa-file-image-o, .fa-file-video-o, .fa-file-audio-o, .fa-file-archive-o, .fa-file-pdf-o { + color: #505; +} /* DOL_XXX for future usage (when left menu has been removed). If we do not use datatable */ /*.table-responsive { From b8cbb84e7cb10117a110a61f2745caaa14d12467 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 11 Nov 2017 00:28:00 +0100 Subject: [PATCH 041/131] Clean code --- htdocs/core/boxes/box_activity.php | 2 ++ htdocs/core/boxes/box_external_rss.php | 4 +-- htdocs/core/boxes/box_factures_fourn.php | 3 ++ htdocs/core/boxes/box_ficheinter.php | 26 +++++++------- htdocs/core/boxes/box_members.php | 5 +-- htdocs/core/boxes/box_project.php | 42 ++++++++++------------ htdocs/core/boxes/box_services_expired.php | 42 ++++++++++++---------- htdocs/core/boxes/box_supplier_orders.php | 28 ++++++--------- htdocs/index.php | 4 +-- htdocs/langs/en_US/contracts.lang | 1 - htdocs/langs/en_US/interventions.lang | 1 - htdocs/langs/en_US/main.lang | 2 ++ htdocs/theme/eldy/style.css.php | 2 +- 13 files changed, 80 insertions(+), 82 deletions(-) diff --git a/htdocs/core/boxes/box_activity.php b/htdocs/core/boxes/box_activity.php index d3059daba53..cbb866d6f20 100644 --- a/htdocs/core/boxes/box_activity.php +++ b/htdocs/core/boxes/box_activity.php @@ -188,6 +188,8 @@ class box_activity extends ModeleBoxes include_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php'; $commandestatic=new Commande($db); + $langs->load("orders"); + $cachedir = DOL_DATA_ROOT.'/commande/temp'; $filename = '/boxactivity-order'.$fileid; $refresh = dol_cache_refresh($cachedir, $filename, $cachetime); diff --git a/htdocs/core/boxes/box_external_rss.php b/htdocs/core/boxes/box_external_rss.php index 264f05b1f03..01eb4ac8893 100644 --- a/htdocs/core/boxes/box_external_rss.php +++ b/htdocs/core/boxes/box_external_rss.php @@ -82,7 +82,7 @@ class box_external_rss extends ModeleBoxes $keyforparamurl="EXTERNAL_RSS_URLRSS_".$site; $keyforparamtitle="EXTERNAL_RSS_TITLE_".$site; - + // Get RSS feed $url=$conf->global->$keyforparamurl; @@ -106,7 +106,7 @@ class box_external_rss extends ModeleBoxes 'text' => $title, 'sublink' => $link, 'subtext'=>$langs->trans("LastRefreshDate").': '.($rssparser->getLastFetchDate()?dol_print_date($rssparser->getLastFetchDate(),"dayhourtext"):$langs->trans("Unknown")), - 'subpicto'=>'object_bookmark', + 'subpicto'=>'help', ); } diff --git a/htdocs/core/boxes/box_factures_fourn.php b/htdocs/core/boxes/box_factures_fourn.php index 0dd0ceb22ba..bae9aef5953 100644 --- a/htdocs/core/boxes/box_factures_fourn.php +++ b/htdocs/core/boxes/box_factures_fourn.php @@ -117,6 +117,7 @@ class box_factures_fourn extends ModeleBoxes $datelimite=$db->jdate($objp->datelimite); $date=$db->jdate($objp->df); $datem=$db->jdate($objp->tms); + $facturestatic->id = $objp->facid; $facturestatic->ref = $objp->ref; $facturestatic->total_ht = $objp->total_ht; @@ -124,6 +125,8 @@ class box_factures_fourn extends ModeleBoxes $facturestatic->total_ttc = $objp->total_ttc; $facturestatic->date_echeance = $datelimite; $facturestatic->statut = $objp->fk_statut; + $facturestatic->ref_supplier = $objp->ref_supplier; + $thirdpartytmp->id = $objp->socid; $thirdpartytmp->name = $objp->name; $thirdpartytmp->fournisseur = 1; diff --git a/htdocs/core/boxes/box_ficheinter.php b/htdocs/core/boxes/box_ficheinter.php index c96fb37afe7..ef7ba62c15c 100644 --- a/htdocs/core/boxes/box_ficheinter.php +++ b/htdocs/core/boxes/box_ficheinter.php @@ -108,27 +108,25 @@ class box_ficheinter extends ModeleBoxes $ficheinterstatic->statut=$objp->fk_statut; $ficheinterstatic->id=$objp->rowid; + $ficheinterstatic->ref=$objp->ref; - $this->info_box_contents[$i][0] = array('td' => 'align="left" width="16"', - 'logo' => $this->boximg, - 'url' => DOL_URL_ROOT."/fichinter/card.php?id=".$objp->rowid); + $this->info_box_contents[$i][] = array('td' => '', + 'text' => $ficheinterstatic->getNomUrl(1), + 'asis' => 1 + ); - $this->info_box_contents[$i][1] = array('td' => '', - 'text' => ($objp->ref?$objp->ref:$objp->rowid), // Some interventions have no ref - 'url' => DOL_URL_ROOT."/fichinter/card.php?id=".$objp->rowid); - - $this->info_box_contents[$i][2] = array('td' => 'align="left" width="16"', + $this->info_box_contents[$i][] = array('td' => 'align="left" width="16"', 'logo' => 'company', 'url' => DOL_URL_ROOT."/comm/card.php?socid=".$objp->socid); - $this->info_box_contents[$i][3] = array('td' => '', + $this->info_box_contents[$i][] = array('td' => '', 'text' => dol_trunc($objp->name,40), 'url' => DOL_URL_ROOT."/comm/card.php?socid=".$objp->socid); - $this->info_box_contents[$i][4] = array('td' => 'class="right"', + $this->info_box_contents[$i][] = array('td' => 'class="right"', 'text' => dol_print_date($datec,'day')); - $this->info_box_contents[$i][5] = array('td' => 'align="right" class="nowrap"', + $this->info_box_contents[$i][] = array('td' => 'align="right" class="nowrap"', 'text' => $ficheinterstatic->getLibStatut(6), 'asis'=>1 ); @@ -136,20 +134,20 @@ class box_ficheinter extends ModeleBoxes $i++; } - if ($num==0) $this->info_box_contents[$i][0] = array('td' => 'align="center"','text'=>$langs->trans("NoRecordedInterventions")); + if ($num==0) $this->info_box_contents[$i][] = array('td' => 'align="center"','text'=>$langs->trans("NoRecordedInterventions")); $db->free($resql); } else { - $this->info_box_contents[0][0] = array( 'td' => '', + $this->info_box_contents[0][] = array( 'td' => '', 'maxlength'=>500, 'text' => ($db->error().' sql='.$sql)); } } else { - $this->info_box_contents[0][0] = array( + $this->info_box_contents[0][] = array( 'td' => 'align="left" class="nohover opacitymedium"', 'text' => $langs->trans("ReadPermissionNotAllowed") ); diff --git a/htdocs/core/boxes/box_members.php b/htdocs/core/boxes/box_members.php index bbf7cd8ad48..25fa257d098 100644 --- a/htdocs/core/boxes/box_members.php +++ b/htdocs/core/boxes/box_members.php @@ -1,6 +1,6 @@ - * Copyright (C) 2004-2013 Laurent Destailleur + * Copyright (C) 2004-2017 Laurent Destailleur * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2015 Frederic France * @@ -109,6 +109,7 @@ class box_members extends ModeleBoxes $memberstatic->firstname=$objp->firstname; $memberstatic->id = $objp->rowid; $memberstatic->ref = $objp->rowid; + $memberstatic->company = $objp->company; if (! empty($objp->fk_soc)) { $memberstatic->socid = $objp->fk_soc; @@ -126,7 +127,7 @@ class box_members extends ModeleBoxes $this->info_box_contents[$line][] = array( 'td' => '', - 'text' => $memberstatic->getFullName($langs), + 'text' => $memberstatic->company, 'url' => DOL_URL_ROOT."/adherents/card.php?rowid=".$objp->rowid, ); diff --git a/htdocs/core/boxes/box_project.php b/htdocs/core/boxes/box_project.php index 9422f228530..ad5af03ac00 100644 --- a/htdocs/core/boxes/box_project.php +++ b/htdocs/core/boxes/box_project.php @@ -110,22 +110,18 @@ class box_project extends ModeleBoxes while ($i < min($num, $max)) { $objp = $db->fetch_object($result); - $tooltip = $langs->trans('Project') . ': ' . $objp->ref; - $this->info_box_contents[$i][0] = array( - 'td' => 'align="left" width="16"', - 'logo' => 'object_project'.($objp->public?'pub':''), - 'tooltip' => $tooltip, - 'url' => DOL_URL_ROOT."/projet/card.php?id=".$objp->rowid, - ); + $projectstatic->id = $objp->rowid; + $projectstatic->ref = $objp->ref; + $projectstatic->title = $objp->title; + $projectstatic->public = $objp->public; - $this->info_box_contents[$i][1] = array( + $this->info_box_contents[$i][] = array( 'td' => '', - 'text' => $objp->ref, - 'tooltip' => $tooltip, - 'url' => DOL_URL_ROOT."/projet/card.php?id=".$objp->rowid, + 'text' => $projectstatic->getNomUrl(1), + 'asis' => 1 ); - $this->info_box_contents[$i][2] = array( + $this->info_box_contents[$i][] = array( 'td' => '', 'text' => $objp->title, ); @@ -137,28 +133,28 @@ class box_project extends ModeleBoxes $resultTask = $db->query($sql); if ($resultTask) { $objTask = $db->fetch_object($resultTask); - $this->info_box_contents[$i][3] = array( + $this->info_box_contents[$i][] = array( 'td' => 'class="right"', 'text' => $objTask->nb." ".$langs->trans("Tasks"), ); if ($objTask->nb > 0) - $this->info_box_contents[$i][4] = array( + $this->info_box_contents[$i][] = array( 'td' => 'class="right"', 'text' => round($objTask->totprogress/$objTask->nb, 0)."%", ); else - $this->info_box_contents[$i][4] = array('td' => 'class="right"', 'text' => "N/A "); + $this->info_box_contents[$i][] = array('td' => 'class="right"', 'text' => "N/A "); $totalnbTask += $objTask->nb; } else { - $this->info_box_contents[$i][3] = array('td' => 'class="right"', 'text' => round(0)); - $this->info_box_contents[$i][4] = array('td' => 'class="right"', 'text' => "N/A "); + $this->info_box_contents[$i][] = array('td' => 'class="right"', 'text' => round(0)); + $this->info_box_contents[$i][] = array('td' => 'class="right"', 'text' => "N/A "); } $i++; } if ($max < $num) { - $this->info_box_contents[$i][0] = array('td' => 'colspan="5"', 'text' => '...'); + $this->info_box_contents[$i][] = array('td' => 'colspan="5"', 'text' => '...'); $i++; } } @@ -166,25 +162,25 @@ class box_project extends ModeleBoxes // Add the sum à the bottom of the boxes - $this->info_box_contents[$i][0] = array( + $this->info_box_contents[$i][] = array( 'tr' => 'class="liste_total"', 'td' => 'align="left" ', 'text' => " ", ); - $this->info_box_contents[$i][1] = array( + $this->info_box_contents[$i][] = array( 'td' => '', 'text' => $langs->trans("Total")." ".$textHead, 'text' => " ", ); - $this->info_box_contents[$i][2] = array( + $this->info_box_contents[$i][] = array( 'td' => 'align="right" ', 'text' => round($num, 0)." ".$langs->trans("Projects"), ); - $this->info_box_contents[$i][3] = array( + $this->info_box_contents[$i][] = array( 'td' => 'align="right" ', 'text' => (($max < $num) ? '' : (round($totalnbTask, 0)." ".$langs->trans("Tasks"))), ); - $this->info_box_contents[$i][4] = array( + $this->info_box_contents[$i][] = array( 'td' => '', 'text' => " ", ); diff --git a/htdocs/core/boxes/box_services_expired.php b/htdocs/core/boxes/box_services_expired.php index 4f3a2817549..f1d14c0df70 100644 --- a/htdocs/core/boxes/box_services_expired.php +++ b/htdocs/core/boxes/box_services_expired.php @@ -69,6 +69,8 @@ class box_services_expired extends ModeleBoxes $this->max=$max; + include_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php'; + $now=dol_now(); $this->info_box_head = array('text' => $langs->trans("BoxLastExpiredServices",$max)); @@ -77,7 +79,7 @@ class box_services_expired extends ModeleBoxes { // Select contracts with at least one expired service $sql = "SELECT "; - $sql.= " c.rowid, c.ref, c.statut as fk_statut, c.date_contrat,"; + $sql.= " c.rowid, c.ref, c.statut as fk_statut, c.date_contrat, c.ref_customer, c.ref_supplier,"; $sql.= " s.nom as name, s.rowid as socid,"; $sql.= " MIN(cd.date_fin_validite) as date_line, COUNT(cd.rowid) as nb_services"; $sql.= " FROM ".MAIN_DB_PREFIX."contrat as c, ".MAIN_DB_PREFIX."societe s, ".MAIN_DB_PREFIX."contratdet as cd"; @@ -87,7 +89,7 @@ class box_services_expired extends ModeleBoxes $sql.= " AND c.fk_soc=s.rowid AND cd.fk_contrat=c.rowid AND c.statut > 0"; if ($user->societe_id) $sql.=' AND c.fk_soc = '.$user->societe_id; if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; - $sql.= " GROUP BY c.rowid, c.ref, c.statut, c.date_contrat, s.nom, s.rowid"; + $sql.= " GROUP BY c.rowid, c.ref, c.statut, c.date_contrat, c.ref_customer, c.ref_supplier, s.nom, s.rowid"; $sql.= " ORDER BY date_line ASC"; $sql.= $db->plimit($max, 0); @@ -99,6 +101,7 @@ class box_services_expired extends ModeleBoxes $i = 0; $thirdpartytmp = new Societe($this->db); + $contract = new Contrat($this->db); while ($i < $num) { @@ -106,30 +109,33 @@ class box_services_expired extends ModeleBoxes $objp = $db->fetch_object($resql); - $dateline=$db->jdate($objp->date_line); - if (($dateline + $conf->contrat->services->expires->warning_delay) < $now) $late=img_warning($langs->trans("Late")); - - $this->info_box_contents[$i][0] = array('td' => 'align="left" width="16"', - 'logo' => $this->boximg, - 'url' => DOL_URL_ROOT."/contrat/card.php?id=".$objp->rowid); - - $this->info_box_contents[$i][1] = array('td' => '', - 'text' => ($objp->ref?$objp->ref:$objp->rowid), // Some contracts have no ref - 'url' => DOL_URL_ROOT."/contrat/card.php?id=".$objp->rowid); - $thirdpartytmp->id = $objp->socid; $thirdpartytmp->name = $objp->name; - $this->info_box_contents[$i][2] = array('td' => 'class="tdoverflowmax100 maxwidth100onsmartphone" align="left"', + $contract->id = $objp->rowid; + $contract->ref = $objp->ref; + $contract->statut = $objp->fk_statut; + $contract->ref_customer = $objp->ref_customer; + $contract->ref_supplier = $objp->ref_supplier; + + $dateline=$db->jdate($objp->date_line); + if (($dateline + $conf->contrat->services->expires->warning_delay) < $now) $late=img_warning($langs->trans("Late")); + + $this->info_box_contents[$i][] = array('td' => '', + 'text' => $contract->getNomUrl(1), + 'asis' => 1 + ); + + $this->info_box_contents[$i][] = array('td' => 'class="tdoverflowmax100 maxwidth100onsmartphone" align="left"', 'text' => $thirdpartytmp->getNomUrl(1, 'customer'), 'asis' => 1 ); - $this->info_box_contents[$i][4] = array('td' => 'align="center"', + $this->info_box_contents[$i][] = array('td' => 'align="center"', 'text' => dol_print_date($dateline,'day'), 'text2'=> $late); - $this->info_box_contents[$i][5] = array('td' => 'class="right"', + $this->info_box_contents[$i][] = array('td' => 'class="right"', 'text' => $objp->nb_services); @@ -139,14 +145,14 @@ class box_services_expired extends ModeleBoxes if ($num==0) { $langs->load("contracts"); - $this->info_box_contents[$i][0] = array('td' => 'align="center"','text'=>$langs->trans("NoExpiredServices")); + $this->info_box_contents[$i][] = array('td' => 'align="center"','text'=>$langs->trans("NoExpiredServices")); } $db->free($resql); } else { - $this->info_box_contents[0][0] = array( 'td' => '', + $this->info_box_contents[0][] = array( 'td' => '', 'maxlength'=>500, 'text' => ($db->error().' sql='.$sql)); } diff --git a/htdocs/core/boxes/box_supplier_orders.php b/htdocs/core/boxes/box_supplier_orders.php index 34734d9dd5a..dc20e9b9665 100644 --- a/htdocs/core/boxes/box_supplier_orders.php +++ b/htdocs/core/boxes/box_supplier_orders.php @@ -109,28 +109,20 @@ class box_supplier_orders extends ModeleBoxes $objp = $db->fetch_object($result); $date=$db->jdate($objp->date_commande); $datem=$db->jdate($objp->tms); - $thirdpartytmp->id = $objp->socid; + + $supplierorderstatic->id = $objp->id; + $supplierorderstatic->ref = $objp->ref; + + $thirdpartytmp->id = $objp->socid; $thirdpartytmp->name = $objp->name; $thirdpartytmp->fournisseur = 1; $thirdpartytmp->code_fournisseur = $objp->code_fournisseur; $thirdpartytmp->logo = $objp->logo; - $urlo = DOL_URL_ROOT."/fourn/commande/card.php?id=".$objp->rowid; - $urls = DOL_URL_ROOT."/fourn/card.php?socid=".$objp->socid; - - $tooltip = $langs->trans('SupplierOrder') . ': ' . $objp->ref; - $this->info_box_contents[$line][] = array( - 'td' => 'align="left" width="16"', - 'logo' => $this->boximg, - 'tooltip' => $tooltip, - 'url' => $urlo, - ); - $this->info_box_contents[$line][] = array( 'td' => '', - 'text' => $objp->ref, - 'tooltip' => $tooltip, - 'url' => $urlo, + 'text' => $supplierorderstatic->getNomUrl(1), + 'asis' => 1 ); $this->info_box_contents[$line][] = array( @@ -158,14 +150,14 @@ class box_supplier_orders extends ModeleBoxes } if ($num == 0) - $this->info_box_contents[$line][0] = array( + $this->info_box_contents[$line][] = array( 'td' => 'align="center"', 'text' => $langs->trans("NoSupplierOrder"), ); $db->free($result); } else { - $this->info_box_contents[0][0] = array( + $this->info_box_contents[0][] = array( 'td' => '', 'maxlength'=>500, 'text' => ($db->error().' sql='.$sql), @@ -174,7 +166,7 @@ class box_supplier_orders extends ModeleBoxes } else { - $this->info_box_contents[0][0] = array( + $this->info_box_contents[0][] = array( 'td' => 'align="left" class="nohover opacitymedium"', 'text' => $langs->trans("ReadPermissionNotAllowed") ); diff --git a/htdocs/index.php b/htdocs/index.php index 0cba7291e9b..8c2a45d0edd 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -118,7 +118,7 @@ $langs->load("contracts"); if (empty($user->societe_id)) { $boxstat.='
'; - $boxstat.=''; + $boxstat.='
'; $boxstat.=''; $boxstat.=''; $boxstat.=''; @@ -525,7 +525,7 @@ if(!empty($conf->global->MAIN_USE_METEO_WITH_PERCENTAGE)) $totallate = round($to //var_dump($totallate); $boxwork=''; $boxwork.='
'; -$boxwork.='
'.$langs->trans("DolibarrStateBoard").'
'."\n"; +$boxwork.='
'."\n"; $boxwork.=''; $boxwork.=''; $boxwork.=''."\n"; diff --git a/htdocs/langs/en_US/contracts.lang b/htdocs/langs/en_US/contracts.lang index e0642b27c02..3768cfb9ff1 100644 --- a/htdocs/langs/en_US/contracts.lang +++ b/htdocs/langs/en_US/contracts.lang @@ -44,7 +44,6 @@ ConfirmActivateService=Are you sure you want to activate this service with date RefContract=Contract reference DateContract=Contract date DateServiceActivate=Service activation date -ShowContract=Show contract ListOfServices=List of services ListOfInactiveServices=List of not active services ListOfExpiredServices=List of expired active services diff --git a/htdocs/langs/en_US/interventions.lang b/htdocs/langs/en_US/interventions.lang index 15415a7fcd5..4c93eff9d0d 100644 --- a/htdocs/langs/en_US/interventions.lang +++ b/htdocs/langs/en_US/interventions.lang @@ -28,7 +28,6 @@ InterventionClassifyBilled=Classify "Billed" InterventionClassifyUnBilled=Classify "Unbilled" InterventionClassifyDone=Classify "Done" StatusInterInvoiced=Billed -ShowIntervention=Show intervention SendInterventionRef=Submission of intervention %s SendInterventionByMail=Send intervention by Email InterventionCreatedInDolibarr=Intervention %s created diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index 7f89918e90a..518b3ea6e04 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -766,6 +766,8 @@ AddBox=Add box SelectElementAndClick=Select an element and click %s PrintFile=Print File %s ShowTransaction=Show entry on bank account +ShowIntervention=Show intervention +ShowContract=Show contract GoIntoSetupToChangeLogo=Go into Home - Setup - Company to change logo or go into Home - Setup - Display to hide. Deny=Deny Denied=Denied diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index e20ca0c0acc..f835ecaddf9 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -4469,7 +4469,7 @@ dl.dropdown { margin-left: 2px; margin-right: 2px; padding:0px; - vertical-align: text-bottom; + vertical-align: middle; display: inline-block; } .dropdown dd, .dropdown dt { From bf0017ffaf602074fa5b659ffb0021cdaf8cb377 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 11 Nov 2017 00:30:16 +0100 Subject: [PATCH 042/131] Fix column --- htdocs/core/boxes/box_project.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/htdocs/core/boxes/box_project.php b/htdocs/core/boxes/box_project.php index ad5af03ac00..976cbf1766c 100644 --- a/htdocs/core/boxes/box_project.php +++ b/htdocs/core/boxes/box_project.php @@ -162,11 +162,6 @@ class box_project extends ModeleBoxes // Add the sum à the bottom of the boxes - $this->info_box_contents[$i][] = array( - 'tr' => 'class="liste_total"', - 'td' => 'align="left" ', - 'text' => " ", - ); $this->info_box_contents[$i][] = array( 'td' => '', 'text' => $langs->trans("Total")." ".$textHead, From d938a56282e0dfa426e620803c42986e72019352 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 11 Nov 2017 01:10:17 +0100 Subject: [PATCH 043/131] Clean code --- .../class/accountingjournal.class.php | 12 +++++------ htdocs/comm/action/rapport/index.php | 8 ++++---- htdocs/hrm/index.php | 20 +++++++++++++++---- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/htdocs/accountancy/class/accountingjournal.class.php b/htdocs/accountancy/class/accountingjournal.class.php index 41cce96995f..41152130f19 100644 --- a/htdocs/accountancy/class/accountingjournal.class.php +++ b/htdocs/accountancy/class/accountingjournal.class.php @@ -30,6 +30,7 @@ class AccountingJournal extends CommonObject public $table_element='accounting_journal'; public $fk_element = ''; public $ismultientitymanaged = 0; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + public $picto = 'generic'; var $rowid; @@ -187,9 +188,6 @@ class AccountingJournal extends CommonObject $url = DOL_URL_ROOT . '/accountancy/admin/journals_list.php?id=35'; - $picto = 'billr'; - $label=''; - $label = '' . $langs->trans("ShowAccountingJournal") . ''; if (! empty($this->code)) $label .= '
'.$langs->trans('Code') . ': ' . $this->code; @@ -223,9 +221,11 @@ class AccountingJournal extends CommonObject $label_link = $this->code; if ($withlabel) $label_link .= ' - ' . $this->label; - if ($withpicto) $result.=($linkstart.img_object(($notooltip?'':$label), $picto, ($notooltip?'':'class="classfortooltip"'), 0, 0, $notooltip?0:1).$linkend); - if ($withpicto && $withpicto != 2) $result .= ' '; - if ($withpicto != 2) $result.=$linkstart . $label_link . $linkend; + $result .= $linkstart; + if ($withpicto) $result.=img_object(($notooltip?'':$label), ($this->picto?$this->picto:'generic'), ($notooltip?(($withpicto != 2) ? 'class="paddingright"' : ''):'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip?0:1); + if ($withpicto != 2) $result.= $label_link; + $result .= $linkend; + return $result; } diff --git a/htdocs/comm/action/rapport/index.php b/htdocs/comm/action/rapport/index.php index 5994f692cc8..2d72fa4c3f8 100644 --- a/htdocs/comm/action/rapport/index.php +++ b/htdocs/comm/action/rapport/index.php @@ -170,15 +170,15 @@ if ($resql) $out=''; // Show file name with link to download - $tmp = $formfile->showPreview($filearray,$modulepart,$relativepath,0,$param); - $out.= ($tmp?$tmp.' ':''); $out.= 'trans("File").': '.$filearray["name"]).' '.$filearray["name"]; + $out.= img_mime($filearray["name"],$langs->trans("File").': '.$filearray["name"]); + $out.= $filearray["name"]; $out.= ''."\n"; - print $out; + $out.= $formfile->showPreview($filearray,$modulepart,$relativepath,0,$param); + print $out; print ''; print '
'; diff --git a/htdocs/hrm/index.php b/htdocs/hrm/index.php index bcf2c7d99ec..e21db6a1dd1 100644 --- a/htdocs/hrm/index.php +++ b/htdocs/hrm/index.php @@ -77,7 +77,7 @@ print load_fiche_titre($langs->trans("HRMArea"),'', 'title_hrm.png'); if (empty($conf->global->MAIN_INFO_SOCIETE_NOM) || empty($conf->global->MAIN_INFO_SOCIETE_COUNTRY)) $setupcompanynotcomplete=1; -if ( empty($setupcompanynotcomplete)) +if (! empty($setupcompanynotcomplete)) { $langs->load("errors"); $warnpicto=img_warning($langs->trans("WarningMandatorySetupNotComplete")); @@ -165,7 +165,7 @@ $langs->load("boxes"); // Latest leave requests if (! empty($conf->holiday->enabled) && $user->rights->holiday->read) { - $sql = "SELECT u.rowid as uid, u.lastname, u.firstname, u.login, u.photo, u.statut, x.rowid, x.rowid as ref, x.fk_type, x.date_debut as date_start, x.date_fin as date_end, x.halfday, x.tms as dm, x.statut as status"; + $sql = "SELECT u.rowid as uid, u.lastname, u.firstname, u.login, u.email, u.photo, u.statut, x.rowid, x.rowid as ref, x.fk_type, x.date_debut as date_start, x.date_fin as date_end, x.halfday, x.tms as dm, x.statut as status"; $sql.= " FROM ".MAIN_DB_PREFIX."holiday as x, ".MAIN_DB_PREFIX."user as u"; $sql.= " WHERE u.rowid = x.fk_user"; $sql.= " AND x.entity = ".$conf->entity; @@ -203,14 +203,18 @@ if (! empty($conf->holiday->enabled) && $user->rights->holiday->read) while ($i < $num && $i < $max) { $obj = $db->fetch_object($result); + $holidaystatic->id=$obj->rowid; $holidaystatic->ref=$obj->ref; + $userstatic->id=$obj->uid; $userstatic->lastname=$obj->lastname; $userstatic->firstname=$obj->firstname; $userstatic->login=$obj->login; $userstatic->photo=$obj->photo; + $userstatic->email=$obj->email; $userstatic->statut=$obj->statut; + print ''; print ''; print ''; @@ -242,7 +246,7 @@ if (! empty($conf->holiday->enabled) && $user->rights->holiday->read) // Last expense report (old module) if (! empty($conf->deplacement->enabled) && $user->rights->deplacement->lire) { - $sql = "SELECT u.rowid as uid, u.lastname, u.firstname, u.login, u.statut, u.photo, d.rowid, d.dated as date, d.tms as dm, d.km, d.fk_statut"; + $sql = "SELECT u.rowid as uid, u.lastname, u.firstname, u.login, u.email, u.statut, u.photo, d.rowid, d.dated as date, d.tms as dm, d.km, d.fk_statut"; $sql.= " FROM ".MAIN_DB_PREFIX."deplacement as d, ".MAIN_DB_PREFIX."user as u"; if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= ", ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."societe_commerciaux as sc"; $sql.= " WHERE u.rowid = d.fk_user"; @@ -277,14 +281,18 @@ if (! empty($conf->deplacement->enabled) && $user->rights->deplacement->lire) while ($i < $num && $i < $max) { $obj = $db->fetch_object($result); + $deplacementstatic->ref=$obj->rowid; $deplacementstatic->id=$obj->rowid; + $userstatic->id=$obj->uid; $userstatic->lastname=$obj->lastname; $userstatic->firstname=$obj->firstname; $userstatic->login=$obj->login; + $userstatic->email=$obj->email; $userstatic->statut=$obj->statut; $userstatic->photo=$obj->photo; + print ''; print ''; print ''; @@ -309,7 +317,7 @@ if (! empty($conf->deplacement->enabled) && $user->rights->deplacement->lire) // Last expense report (new module) if (! empty($conf->expensereport->enabled) && $user->rights->expensereport->lire) { - $sql = "SELECT u.rowid as uid, u.lastname, u.firstname, u.login, u.statut, u.photo, x.rowid, x.ref, x.date_debut as date, x.tms as dm, x.total_ttc, x.fk_statut as status"; + $sql = "SELECT u.rowid as uid, u.lastname, u.firstname, u.login, u.email, u.statut, u.photo, x.rowid, x.ref, x.date_debut as date, x.tms as dm, x.total_ttc, x.fk_statut as status"; $sql.= " FROM ".MAIN_DB_PREFIX."expensereport as x, ".MAIN_DB_PREFIX."user as u"; if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= ", ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."societe_commerciaux as sc"; $sql.= " WHERE u.rowid = x.fk_user_author"; @@ -344,14 +352,18 @@ if (! empty($conf->expensereport->enabled) && $user->rights->expensereport->lire while ($i < $num && $i < $max) { $obj = $db->fetch_object($result); + $expensereportstatic->id=$obj->rowid; $expensereportstatic->ref=$obj->ref; + $userstatic->id=$obj->uid; $userstatic->lastname=$obj->lastname; $userstatic->firstname=$obj->firstname; + $userstatic->email=$obj->email; $userstatic->login=$obj->login; $userstatic->statut=$obj->statut; $userstatic->photo=$obj->photo; + print ''; print ''; print ''; From 60fcddb9e45e7baaace240acd0faa522dbc0a7c6 Mon Sep 17 00:00:00 2001 From: Maxime Kohlhaas Date: Sat, 11 Nov 2017 12:07:55 +0100 Subject: [PATCH 044/131] NEW deposits can be converted even if unpaid --- htdocs/compta/facture/card.php | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 8365a52f277..7b4118d73c4 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -677,7 +677,7 @@ if (empty($reshook)) $result=$discountcheck->fetch(0,$object->id); $canconvert=0; - if ($object->type == Facture::TYPE_DEPOSIT && $object->paye == 1 && empty($discountcheck->id)) $canconvert=1; // we can convert deposit into discount if deposit is payed completely and not already converted (see real condition into condition used to show button converttoreduc) + if ($object->type == Facture::TYPE_DEPOSIT && empty($discountcheck->id)) $canconvert=1; // we can convert deposit into discount if deposit is payed completely and not already converted (see real condition into condition used to show button converttoreduc) if (($object->type == Facture::TYPE_CREDIT_NOTE || $object->type == Facture::TYPE_STANDARD) && $object->paye == 0 && empty($discountcheck->id)) $canconvert=1; // we can convert credit note into discount if credit note is not payed back and not already converted and amount of payment is 0 (see real condition into condition used to show button converttoreduc) if ($canconvert) { @@ -763,17 +763,21 @@ if (empty($reshook)) if (empty($error)) { - // Classe facture - $result = $object->set_paid($user); - if ($result >= 0) - { + if($object->type != Facture::TYPE_DEPOSIT) { + // Classe facture + $result = $object->set_paid($user); + if ($result >= 0) + { + $db->commit(); + } + else + { + setEventMessages($object->error, $object->errors, 'errors'); + $db->rollback(); + } + } else { $db->commit(); } - else - { - setEventMessages($object->error, $object->errors, 'errors'); - $db->rollback(); - } } else { @@ -4258,7 +4262,7 @@ else if ($id > 0 || ! empty($ref)) print ''; } // For deposit invoice - if ($object->type == Facture::TYPE_DEPOSIT && $object->paye == 1 && $resteapayer == 0 && $user->rights->facture->creer && empty($discount->id)) + if ($object->type == Facture::TYPE_DEPOSIT && $user->rights->facture->creer && empty($discount->id)) { print ''; } From 01a41237bf45cef05ac07960d586a5dadb6bb5a7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 11 Nov 2017 14:20:08 +0100 Subject: [PATCH 045/131] CSS --- htdocs/core/boxes/modules_boxes.php | 2 ++ htdocs/core/class/html.form.class.php | 11 ++++---- htdocs/core/lib/ajax.lib.php | 14 +++++----- htdocs/core/lib/files.lib.php | 2 +- htdocs/ecm/class/htmlecm.form.class.php | 33 +++++++++++++++-------- htdocs/ecm/docdir.php | 35 ++++++++++++++++++------- htdocs/ecm/tpl/filemanager.tpl.php | 26 +++++++++++++----- htdocs/langs/en_US/ecm.lang | 3 ++- htdocs/public/payment/newpayment.php | 6 ++--- htdocs/societe/list.php | 3 +-- htdocs/theme/eldy/style.css.php | 7 +++-- htdocs/theme/md/style.css.php | 6 ++--- 12 files changed, 94 insertions(+), 54 deletions(-) diff --git a/htdocs/core/boxes/modules_boxes.php b/htdocs/core/boxes/modules_boxes.php index fe919b1fcba..790fe29fbcf 100644 --- a/htdocs/core/boxes/modules_boxes.php +++ b/htdocs/core/boxes/modules_boxes.php @@ -231,6 +231,7 @@ class ModeleBoxes // Can't be abtract as it is instantiated to build "empty" $nblines=count($contents); $out.= "\n\n"; + //$out.= '
'; // Does not work on home page. TODO Try to fix this. $out.= '
'."\n"; if (! empty($head['text']) || ! empty($head['sublink']) || ! empty($head['subpicto']) || $nblines) @@ -360,6 +361,7 @@ class ModeleBoxes // Can't be abtract as it is instantiated to build "empty" if (empty($head['text']) && empty($head['sublink']) && empty($head['subpicto']) && ! $nblines) $out.= "
\n"; $out.= "
\n"; + //$out.= "
\n"; $out.= "\n\n"; if (! empty($conf->global->MAIN_ACTIVATE_FILECACHE)) { dol_filecache($cachedir, $filename, $out); diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 2274701644f..2a8aa87686f 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -689,18 +689,19 @@ class Form if (empty($row['favorite']) && $atleastonefavorite) { $atleastonefavorite=0; - $out.= ''; + $out.= ''; } if ($selected && $selected != '-1' && ($selected == $row['rowid'] || $selected == $row['code_iso'] || $selected == $row['code_iso3'] || $selected == $row['label']) ) { $foundselected=true; - $out.= ''; } @@ -5508,7 +5509,7 @@ class Form cache: true }, language: select2arrayoflanguage, - containerCssClass: \':all:\', /* Line to add class or origin SELECT propagated to the new tag */ placeholder: "'.dol_escape_js($placeholder).'", escapeMarkup: function (markup) { return markup; }, // let our custom formatter work minimumInputLength: '.$minimumInputLength.', diff --git a/htdocs/core/lib/ajax.lib.php b/htdocs/core/lib/ajax.lib.php index 825f99d6e98..2f1caf6e999 100644 --- a/htdocs/core/lib/ajax.lib.php +++ b/htdocs/core/lib/ajax.lib.php @@ -393,8 +393,10 @@ function ajax_combobox($htmlname, $events=array(), $minLengthToAutocomplete=0, $ { global $conf; - if (! empty($conf->browser->phone)) return ''; // select2 disabled for smartphones with standard browser (does not works, popup appears outside screen) - //if (! empty($conf->dol_use_jmobile)) return ''; // select2 works with jmobile but it breaks the autosize feature of jmobile. + // select2 disabled for smartphones with standard browser. + // TODO With select2 v4, it seems ok, except that responsive style on table become crazy when scrolling at end of array) + if (! empty($conf->browser->phone)) return ''; + if (! empty($conf->global->MAIN_DISABLE_AJAX_COMBOX)) return ''; if (empty($conf->use_javascript_ajax)) return ''; if (empty($conf->global->MAIN_USE_JQUERY_MULTISELECT) && ! defined('REQUIRE_JQUERY_MULTISELECT')) return ''; @@ -405,19 +407,15 @@ function ajax_combobox($htmlname, $events=array(), $minLengthToAutocomplete=0, $ $msg="\n".' '; diff --git a/htdocs/core/js/lib_foot.js.php b/htdocs/core/js/lib_foot.js.php index d3b3db60ef8..f9ee9ea3ad4 100644 --- a/htdocs/core/js/lib_foot.js.php +++ b/htdocs/core/js/lib_foot.js.php @@ -52,7 +52,7 @@ if (empty($conf->dol_no_mouse_hover)) jQuery(document).ready(function () { jQuery(".classfortooltip").tooltip({ show: { collision: "flipfit", effect:\'toggle\', delay:50 }, - hide: { effect:\'toggle\', delay: 50 }, + hide: { delay: 50 }, tooltipClass: "mytooltip", content: function () { return $(this).prop(\'title\'); /* To force to get title as is */ From 97c954908708586c98298cafa8d9e24c7f15f8f2 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 13 Nov 2017 11:30:41 +0100 Subject: [PATCH 065/131] Fix ref supplier must be output if it exists, even for free products --- htdocs/core/lib/pdf.lib.php | 70 ++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 36 deletions(-) diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php index 932373665e5..377f2215b6d 100644 --- a/htdocs/core/lib/pdf.lib.php +++ b/htdocs/core/lib/pdf.lib.php @@ -1265,47 +1265,45 @@ function pdf_getlinedesc($object,$i,$outputlangs,$hideref=0,$hidedesc=0,$issuppl } } - // If line linked to a product - if ($idprod) + // We add ref of product (and supplier ref if defined) + $prefix_prodserv = ""; + $ref_prodserv = ""; + if (! empty($conf->global->PRODUCT_ADD_TYPE_IN_DOCUMENTS)) // In standard mode, we do not show this { - // We add ref - if ($prodser->ref) + if ($prodser->isService()) { - $prefix_prodserv = ""; - $ref_prodserv = ""; - if (! empty($conf->global->PRODUCT_ADD_TYPE_IN_DOCUMENTS)) // In standard mode, we do not show this - { - if ($prodser->isService()) - { - $prefix_prodserv = $outputlangs->transnoentitiesnoconv("Service")." "; - } - else - { - $prefix_prodserv = $outputlangs->transnoentitiesnoconv("Product")." "; - } - } - - if (empty($hideref)) - { - if ($issupplierline) - { - if ($conf->global->PDF_HIDE_PRODUCT_REF_IN_SUPPLIER_LINES == 1) - $ref_prodserv = $ref_supplier; - elseif ($conf->global->PDF_HIDE_PRODUCT_REF_IN_SUPPLIER_LINES == 2) - $ref_prodserv = $ref_supplier. ' ('.$outputlangs->transnoentitiesnoconv("InternalRef").' '.$prodser->ref.')'; - else - $ref_prodserv = $prodser->ref.($ref_supplier ? ' ('.$outputlangs->transnoentitiesnoconv("SupplierRef").' '.$ref_supplier.')' : ''); - } - else - $ref_prodserv = $prodser->ref; // Show local ref only - - if (! empty($libelleproduitservice)) $ref_prodserv .= " - "; - } - - $libelleproduitservice=$prefix_prodserv.$ref_prodserv.$libelleproduitservice; + $prefix_prodserv = $outputlangs->transnoentitiesnoconv("Service")." "; + } + else + { + $prefix_prodserv = $outputlangs->transnoentitiesnoconv("Product")." "; } } + if (empty($hideref)) + { + if ($issupplierline) + { + if ($conf->global->PDF_HIDE_PRODUCT_REF_IN_SUPPLIER_LINES == 1) + $ref_prodserv = $ref_supplier; + elseif ($conf->global->PDF_HIDE_PRODUCT_REF_IN_SUPPLIER_LINES == 2) + $ref_prodserv = $ref_supplier. ' ('.$outputlangs->transnoentitiesnoconv("InternalRef").' '.$prodser->ref.')'; + else // Common case + { + $ref_prodserv = $prodser->ref; // Show local ref + if ($ref_supplier) $ref_prodserv.= ($prodser->ref?' (':'').$outputlangs->transnoentitiesnoconv("SupplierRef").' '.$ref_supplier.($prodser->ref?')':''); + } + } + else + { + $ref_prodserv = $prodser->ref; // Show local ref only + } + + if (! empty($libelleproduitservice) && ! empty($ref_prodserv)) $ref_prodserv .= " - "; + } + + $libelleproduitservice=$prefix_prodserv.$ref_prodserv.$libelleproduitservice; + // Add an additional description for the category products if (! empty($conf->global->CATEGORY_ADD_DESC_INTO_DOC) && $idprod && ! empty($conf->categorie->enabled)) { From 05683bbf6172f91fa350161706e6bb6d6916aafe Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 13 Nov 2017 11:41:37 +0100 Subject: [PATCH 066/131] Code comment --- dev/dolibarr_changes.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/dolibarr_changes.txt b/dev/dolibarr_changes.txt index 3b9ef4cc447..3c2b7b3c932 100644 --- a/dev/dolibarr_changes.txt +++ b/dev/dolibarr_changes.txt @@ -99,7 +99,7 @@ JQUERYFILETREE: RESTLER: -------- -* Add 2 lines into function +* Add 2 lines into file AutoLoader.php to complete function private function alias($className, $currentClass) { ... From 1a5bbef2664e2307460aeae9a3bbdeff1020d182 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 13 Nov 2017 13:07:31 +0100 Subject: [PATCH 067/131] FIX Locatax were not propagated when cloning order or proposal --- htdocs/comm/propal/class/propal.class.php | 19 +++++++++++-------- htdocs/commande/class/commande.class.php | 12 ++++++++---- htdocs/compta/facture/class/facture.class.php | 10 +++++++--- 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index 64997b4c9ea..ffeda27da42 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -371,12 +371,12 @@ class Propal extends CommonObject * by whose calling the method get_default_tva (societe_vendeuse, societe_acheteuse, '' product) * and desc must already have the right value (it's up to the caller to manage multilanguage) * - * @param string $desc Description de la ligne - * @param float $pu_ht Prix unitaire - * @param float $qty Quantite - * @param float $txtva Taux de tva - * @param float $txlocaltax1 Local tax 1 rate - * @param float $txlocaltax2 Local tax 2 rate + * @param string $desc Description of line + * @param float $pu_ht Unit price + * @param float $qty Quantity + * @param float $txtva Force Vat rate, -1 for auto (Can contain the vat_src_code too with syntax '9.9 (CODE)') + * @param float $txlocaltax1 Local tax 1 rate (deprecated, use instead txtva with code inside) + * @param float $txlocaltax2 Local tax 2 rate (deprecated, use instead txtva with code inside) * @param int $fk_product Id du produit/service predefini * @param float $remise_percent Pourcentage de remise de la ligne * @param string $price_base_type HT or TTC @@ -1018,11 +1018,15 @@ class Propal extends CommonObject $fk_parent_line = 0; } + // Complete vat rate with code + $vatrate = $this->lines[$i]->tva_tx; + if ($this->lines[$i]->vat_src_code && ! preg_match('/\(.*\)/', $vatrate)) $vatrate.=' ('.$this->lines[$i]->vat_src_code.')'; + $result = $this->addline( $this->lines[$i]->desc, $this->lines[$i]->subprice, $this->lines[$i]->qty, - $this->lines[$i]->tva_tx, + $vatrate, $this->lines[$i]->localtax1_tx, $this->lines[$i]->localtax2_tx, $this->lines[$i]->fk_product, @@ -1227,7 +1231,6 @@ class Propal extends CommonObject if (empty($conf->global->MAIN_KEEP_REF_CUSTOMER_ON_CLONING)) $clonedObj->ref_client = ''; // Create clone - $result=$clonedObj->create($user); if ($result < 0) $error++; else diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 56a7fe16b43..5023410cf53 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -821,11 +821,15 @@ class Commande extends CommonOrder $fk_parent_line = 0; } + // Complete vat rate with code + $vatrate = $line->tva_tx; + if ($line->vat_src_code && ! preg_match('/\(.*\)/', $vatrate)) $vatrate.=' ('.$line->vat_src_code.')'; + $result = $this->addline( $line->desc, $line->subprice, $line->qty, - $line->tva_tx, + $vatrate, $line->localtax1_tx, $line->localtax2_tx, $line->fk_product, @@ -1211,9 +1215,9 @@ class Commande extends CommonOrder * @param string $desc Description of line * @param float $pu_ht Unit price (without tax) * @param float $qty Quantite - * @param float $txtva Taux de tva force, sinon -1 - * @param float $txlocaltax1 Local tax 1 rate - * @param float $txlocaltax2 Local tax 2 rate + * @param float $txtva Force Vat rate, -1 for auto (Can contain the vat_src_code too with syntax '9.9 (CODE)') + * @param float $txlocaltax1 Local tax 1 rate (deprecated, use instead txtva with code inside) + * @param float $txlocaltax2 Local tax 2 rate (deprecated, use instead txtva with code inside) * @param int $fk_product Id of product * @param float $remise_percent Pourcentage de remise de la ligne * @param int $info_bits Bits de type de lignes diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 99665476a8e..e704a5a229a 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -575,11 +575,15 @@ class Facture extends CommonInvoice $fk_parent_line = 0; } + // Complete vat rate with code + $vatrate = $line->tva_tx; + if ($line->vat_src_code && ! preg_match('/\(.*\)/', $vatrate)) $vatrate.=' ('.$line->vat_src_code.')'; + $result = $this->addline( $line->desc, $line->subprice, $line->qty, - $line->tva_tx, + $vatrate, $line->localtax1_tx, $line->localtax2_tx, $line->fk_product, @@ -2427,8 +2431,8 @@ class Facture extends CommonInvoice * @param double $pu_ht Unit price without tax (> 0 even for credit note) * @param double $qty Quantity * @param double $txtva Force Vat rate, -1 for auto (Can contain the vat_src_code too with syntax '9.9 (CODE)') - * @param double $txlocaltax1 Local tax 1 rate (deprecated) - * @param double $txlocaltax2 Local tax 2 rate (deprecated) + * @param double $txlocaltax1 Local tax 1 rate (deprecated, use instead txtva with code inside) + * @param double $txlocaltax2 Local tax 2 rate (deprecated, use instead txtva with code inside) * @param int $fk_product Id of predefined product/service * @param double $remise_percent Percent of discount on line * @param int $date_start Date start of service From b5196b71641699b8e83ba6166a74a52081c0405e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 13 Nov 2017 14:02:17 +0100 Subject: [PATCH 068/131] FIX A lot of several fix on local taxes and NPR tax --- htdocs/cashdesk/facturation_verif.php | 11 ++- htdocs/comm/propal/card.php | 3 + htdocs/commande/card.php | 11 ++- htdocs/compta/facture/card.php | 3 + htdocs/compta/facture/fiche-rec.php | 3 + htdocs/contrat/card.php | 3 + htdocs/core/class/commonobject.class.php | 1 + htdocs/expedition/class/expedition.class.php | 3 +- .../install/mysql/migration/5.0.0-6.0.0.sql | 2 + htdocs/langs/en_US/main.lang | 1 + htdocs/langs/en_US/stocks.lang | 2 +- htdocs/product/price.php | 73 ++++++++++++++----- 12 files changed, 88 insertions(+), 28 deletions(-) diff --git a/htdocs/cashdesk/facturation_verif.php b/htdocs/cashdesk/facturation_verif.php index 24876a0a8fb..25ddfd8c1f8 100644 --- a/htdocs/cashdesk/facturation_verif.php +++ b/htdocs/cashdesk/facturation_verif.php @@ -114,10 +114,13 @@ switch($action) { if (count($prodcustprice->lines) > 0) { - $pu_ht = price($prodcustprice->lines [0]->price); - $pu_ttc = price($prodcustprice->lines [0]->price_ttc); - $price_base_type = $prodcustprice->lines [0]->price_base_type; - $tva_tx = $prodcustprice->lines [0]->tva_tx; + $pu_ht = price($prodcustprice->lines[0]->price); + $pu_ttc = price($prodcustprice->lines[0]->price_ttc); + $price_base_type = $prodcustprice->lines[0]->price_base_type; + $tva_tx = $prodcustprice->lines[0]->tva_tx; + if ($prodcustprice->lines[0]->default_vat_code && ! preg_match('/\(.*\)/', $tva_tx)) $tva_tx.= ' ('.$prodcustprice->lines[0]->default_vat_code.')'; + $tva_npr = $prodcustprice->lines[0]->recuperableonly; + if (empty($tva_tx)) $tva_npr=0; } } else diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index 839538f777e..c3be71c35a1 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -805,6 +805,9 @@ if (empty($reshook)) $pu_ttc = price($prodcustprice->lines[0]->price_ttc); $price_base_type = $prodcustprice->lines[0]->price_base_type; $tva_tx = ($prodcustprice->lines[0]->default_vat_code ? $prodcustprice->lines[0]->tva_tx . ' ('.$prodcustprice->lines[0]->default_vat_code.' )' : $prodcustprice->lines[0]->tva_tx); + if ($prodcustprice->lines[0]->default_vat_code && ! preg_match('/\(.*\)/', $tva_tx)) $tva_tx.= ' ('.$prodcustprice->lines[0]->default_vat_code.')'; + $tva_npr = $prodcustprice->lines[0]->recuperableonly; + if (empty($tva_tx)) $tva_npr=0; } } } diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index 374ec0477fe..33048f8d470 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -766,10 +766,13 @@ if (empty($reshook)) { if (count($prodcustprice->lines) > 0) { - $pu_ht = price($prodcustprice->lines [0]->price); - $pu_ttc = price($prodcustprice->lines [0]->price_ttc); - $price_base_type = $prodcustprice->lines [0]->price_base_type; - $tva_tx = $prodcustprice->lines [0]->tva_tx; + $pu_ht = price($prodcustprice->lines[0]->price); + $pu_ttc = price($prodcustprice->lines[0]->price_ttc); + $price_base_type = $prodcustprice->lines[0]->price_base_type; + $tva_tx = $prodcustprice->lines[0]->tva_tx; + if ($prodcustprice->lines[0]->default_vat_code && ! preg_match('/\(.*\)/', $tva_tx)) $tva_tx.= ' ('.$prodcustprice->lines[0]->default_vat_code.')'; + $tva_npr = $prodcustprice->lines[0]->recuperableonly; + if (empty($tva_tx)) $tva_npr=0; } } else diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index f438a5ab6b9..3bc4759e589 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -1589,6 +1589,9 @@ if (empty($reshook)) $pu_ttc = price($prodcustprice->lines[0]->price_ttc); $price_base_type = $prodcustprice->lines[0]->price_base_type; $tva_tx = $prodcustprice->lines[0]->tva_tx; + if ($prodcustprice->lines[0]->default_vat_code && ! preg_match('/\(.*\)/', $tva_tx)) $tva_tx.= ' ('.$prodcustprice->lines[0]->default_vat_code.')'; + $tva_npr = $prodcustprice->lines[0]->recuperableonly; + if (empty($tva_tx)) $tva_npr=0; } } } diff --git a/htdocs/compta/facture/fiche-rec.php b/htdocs/compta/facture/fiche-rec.php index 0bfdc134258..c748cb0a0e3 100644 --- a/htdocs/compta/facture/fiche-rec.php +++ b/htdocs/compta/facture/fiche-rec.php @@ -530,6 +530,9 @@ if (empty($reshook)) $pu_ttc = price($prodcustprice->lines[0]->price_ttc); $price_base_type = $prodcustprice->lines[0]->price_base_type; $tva_tx = $prodcustprice->lines[0]->tva_tx; + if ($prodcustprice->lines[0]->default_vat_code && ! preg_match('/\(.*\)/', $tva_tx)) $tva_tx.= ' ('.$prodcustprice->lines[0]->default_vat_code.')'; + $tva_npr = $prodcustprice->lines[0]->recuperableonly; + if (empty($tva_tx)) $tva_npr=0; } } } diff --git a/htdocs/contrat/card.php b/htdocs/contrat/card.php index 39a708bcdad..43f086fbab4 100644 --- a/htdocs/contrat/card.php +++ b/htdocs/contrat/card.php @@ -509,6 +509,9 @@ if (empty($reshook)) $pu_ttc = price($prodcustprice->lines [0]->price_ttc); $price_base_type = $prodcustprice->lines [0]->price_base_type; $tva_tx = $prodcustprice->lines [0]->tva_tx; + if ($prodcustprice->lines[0]->default_vat_code && ! preg_match('/\(.*\)/', $tva_tx)) $tva_tx.= ' ('.$prodcustprice->lines[0]->default_vat_code.')'; + $tva_npr = $prodcustprice->lines[0]->recuperableonly; + if (empty($tva_tx)) $tva_npr=0; } } } diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index a97b553aed4..83c38477f28 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -3748,6 +3748,7 @@ abstract class CommonObject // VAT Rate $this->tpl['vat_rate'] = vatrate($line->tva_tx, true); + $this->tpl['vat_rate'] .= (($line->info_bits & 1) == 1) ? '*' : ''; if (! empty($line->vat_src_code) && ! preg_match('/\(/', $this->tpl['vat_rate'])) $this->tpl['vat_rate'].=' ('.$line->vat_src_code.')'; $this->tpl['price'] = price($line->subprice); diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index 879b5745db4..bccfba4446d 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -1321,7 +1321,7 @@ class Expedition extends CommonObject $sql = "SELECT cd.rowid, cd.fk_product, cd.label as custom_label, cd.description, cd.qty as qty_asked, cd.product_type"; $sql.= ", cd.total_ht, cd.total_localtax1, cd.total_localtax2, cd.total_ttc, cd.total_tva"; - $sql.= ", cd.vat_src_code, cd.tva_tx, cd.localtax1_tx, cd.localtax2_tx, cd.localtax1_type, cd.localtax2_type, cd.price, cd.subprice, cd.remise_percent,cd.buy_price_ht as pa_ht"; + $sql.= ", cd.vat_src_code, cd.tva_tx, cd.localtax1_tx, cd.localtax2_tx, cd.localtax1_type, cd.localtax2_type, cd.info_bits, cd.price, cd.subprice, cd.remise_percent,cd.buy_price_ht as pa_ht"; $sql.= ", cd.fk_multicurrency, cd.multicurrency_code, cd.multicurrency_subprice, cd.multicurrency_total_ht, cd.multicurrency_total_tva, cd.multicurrency_total_ttc"; $sql.= ", ed.rowid as line_id, ed.qty as qty_shipped, ed.fk_origin_line, ed.fk_entrepot"; $sql.= ", p.ref as product_ref, p.label as product_label, p.fk_product_type"; @@ -1418,6 +1418,7 @@ class Expedition extends CommonObject $line->tva_tx = $obj->tva_tx; $line->localtax1_tx = $obj->localtax1_tx; $line->localtax2_tx = $obj->localtax2_tx; + $line->info_bits = $obj->info_bits; $line->price = $obj->price; $line->subprice = $obj->subprice; $line->remise_percent = $obj->remise_percent; diff --git a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql index 5da8799d7b3..8b68929864f 100644 --- a/htdocs/install/mysql/migration/5.0.0-6.0.0.sql +++ b/htdocs/install/mysql/migration/5.0.0-6.0.0.sql @@ -382,6 +382,8 @@ ALTER TABLE llx_product_fournisseur_price_log ADD COLUMN multicurrency_tx d ALTER TABLE llx_product_fournisseur_price_log ADD COLUMN multicurrency_price double(24,8) DEFAULT NULL; ALTER TABLE llx_product_fournisseur_price_log ADD COLUMN multicurrency_price_ttc double(24,8) DEFAULT NULL; +ALTER TABLE llx_product_customer_price_log ADD COLUMN default_vat_code varchar(10); + UPDATE llx_contrat SET ref = rowid WHERE ref IS NULL OR ref = ''; ALTER TABLE llx_contratdet ADD COLUMN vat_src_code varchar(10) DEFAULT ''; diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index 02f3f80982e..9c53b726544 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -366,6 +366,7 @@ TotalLT1IN=Total CGST TotalLT2IN=Total SGST HT=Net of tax TTC=Inc. tax +INCVATONLY=Inc. VAT INCT=Inc. all taxes VAT=Sales tax VATIN=IGST diff --git a/htdocs/langs/en_US/stocks.lang b/htdocs/langs/en_US/stocks.lang index f2115666a36..a4fb098f5ac 100644 --- a/htdocs/langs/en_US/stocks.lang +++ b/htdocs/langs/en_US/stocks.lang @@ -133,7 +133,7 @@ MovementLabel=Label of movement InventoryCode=Movement or inventory code IsInPackage=Contained into package WarehouseAllowNegativeTransfer=Stock can be negative -qtyToTranferIsNotEnough=You don't have enough stock from your source warehouse +qtyToTranferIsNotEnough=You don't have enough stock from your source warehouse and your setup does not allow negative stocks. ShowWarehouse=Show warehouse MovementCorrectStock=Stock correction for product %s MovementTransferStock=Stock transfer of product %s into another warehouse diff --git a/htdocs/product/price.php b/htdocs/product/price.php index f16b716c9cc..b38aa15a694 100644 --- a/htdocs/product/price.php +++ b/htdocs/product/price.php @@ -1800,8 +1800,15 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) print '
'; print ''; print ''; - print ''; - if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") print ''; + if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") + { + //print ''; + print ''; + } + else + { + print ''; + } print ''; print ''; print ''; @@ -1843,20 +1850,28 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) print ""; print '"; print '"; print '"; - print '"; - if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") print ''; + if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") + { + //print '"; + print ''; + } + else + { + print '"; + } print ''; print ''; @@ -1902,7 +1917,7 @@ var_dump($prodcustprice);exit; if (count($prodcustprice->lines) > 0 || $search_soc) { $colspan=8; - if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") $colspan++; + //if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") $colspan++; print ''; print ''; @@ -1921,8 +1936,16 @@ var_dump($prodcustprice);exit; print ''; print ''; print ''; - print ''; - if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") print ''; + if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") + { + //print ''; + print ''; + } + else + { + print ''; + } + print ''; print ''; print ''; @@ -1969,9 +1992,17 @@ var_dump($prodcustprice);exit; print ""; print '"; - print '"; - if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") print ''; + if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") + { + //print '"; + print ''; + } + else + { + print '"; + } + print ''; print ''; @@ -1992,7 +2023,6 @@ var_dump($prodcustprice);exit; } print "\n"; - if (count($prodcustprice->lines) > 0) { foreach ($prodcustprice->lines as $line) @@ -2037,13 +2067,20 @@ var_dump($prodcustprice);exit; if (price2num($line->localtax1_type)) $positiverates.=($positiverates?'/':'').price2num($line->localtax1_tx); if (price2num($line->localtax2_type)) $positiverates.=($positiverates?'/':'').price2num($line->localtax2_tx); if (empty($positiverates)) $positiverates='0'; - echo vatrate($positiverates.($line->default_vat_code?' ('.$line->default_vat_code.')':''), '%', $line->tva_npr); + echo vatrate($positiverates.($line->default_vat_code?' ('.$line->default_vat_code.')':''), '%', ($line->tva_npr?$line->tva_npr:$line->recuperableonly)); print ""; print '"; - print '"; - if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") print ''; + if ($mysoc->localtax1_assuj == "1" || $mysoc->localtax2_assuj == "1") + { + //print '"; + print ''; + } + else + { + print '"; + } print ''; print ''; From 53bfbcf5db3744b0b945a00c92dd2b2f4b5da631 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 13 Nov 2017 17:05:07 +0100 Subject: [PATCH 069/131] NEW Ad performances indexes on calendar events --- htdocs/install/mysql/migration/6.0.0-7.0.0.sql | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/htdocs/install/mysql/migration/6.0.0-7.0.0.sql b/htdocs/install/mysql/migration/6.0.0-7.0.0.sql index c185d3c9afd..09c1f973a7f 100644 --- a/htdocs/install/mysql/migration/6.0.0-7.0.0.sql +++ b/htdocs/install/mysql/migration/6.0.0-7.0.0.sql @@ -394,6 +394,12 @@ ALTER TABLE llx_holiday_config ADD UNIQUE INDEX idx_holiday_config (name); ALTER TABLE llx_actioncomm MODIFY COLUMN label varchar(255) NOT NULL; +ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_fk_user_action (fk_user_action); +ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_fk_project (fk_project); +ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_datep (datep); +ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_datep2 (datep2); +ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_recurid (recurid); + ALTER TABLE llx_payment_various ADD COLUMN fk_projet integer DEFAULT NULL after accountancy_code; UPDATE llx_const set name = 'ONLINE_PAYMENT_MESSAGE_OK' where name = 'PAYPAL_MESSAGE_OK'; From 2d78136781228beac141b01f88dc65274840c168 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 13 Nov 2017 18:04:14 +0100 Subject: [PATCH 070/131] Standardize field length --- htdocs/install/mysql/migration/6.0.0-7.0.0.sql | 9 +++++++++ htdocs/install/mysql/tables/llx_actioncomm.key.sql | 9 ++++++++- htdocs/install/mysql/tables/llx_actioncomm.sql | 8 ++++---- htdocs/install/mysql/tables/llx_commande_fournisseur.sql | 2 +- htdocs/install/mysql/tables/llx_contrat.sql | 8 ++++---- htdocs/install/mysql/tables/llx_expedition.sql | 6 +++--- htdocs/install/mysql/tables/llx_livraison.sql | 6 +++--- htdocs/install/mysql/tables/llx_societe.sql | 8 ++++---- htdocs/install/mysql/tables/llx_socpeople.sql | 2 +- 9 files changed, 37 insertions(+), 21 deletions(-) diff --git a/htdocs/install/mysql/migration/6.0.0-7.0.0.sql b/htdocs/install/mysql/migration/6.0.0-7.0.0.sql index 09c1f973a7f..396ab94938f 100644 --- a/htdocs/install/mysql/migration/6.0.0-7.0.0.sql +++ b/htdocs/install/mysql/migration/6.0.0-7.0.0.sql @@ -392,6 +392,13 @@ ALTER TABLE llx_extrafields MODIFY COLUMN langs varchar(64); ALTER TABLE llx_holiday_config MODIFY COLUMN name varchar(128); ALTER TABLE llx_holiday_config ADD UNIQUE INDEX idx_holiday_config (name); +ALTER TABLE llx_societe MODIFY COLUMN ref_ext varchar(255); +ALTER TABLE llx_socpeople MODIFY COLUMN ref_ext varchar(255); +ALTER TABLE llx_actioncomm MODIFY COLUMN ref_ext varchar(255); +ALTER TABLE llx_expedition MODIFY COLUMN ref_ext varchar(255); +ALTER TABLE llx_livraison MODIFY COLUMN ref_ext varchar(255); +ALTER TABLE llx_contrat MODIFY COLUMN ref_ext varchar(255); + ALTER TABLE llx_actioncomm MODIFY COLUMN label varchar(255) NOT NULL; ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_fk_user_action (fk_user_action); @@ -400,6 +407,8 @@ ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_datep (datep); ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_datep2 (datep2); ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_recurid (recurid); +ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_ref_ext (ref_ext); + ALTER TABLE llx_payment_various ADD COLUMN fk_projet integer DEFAULT NULL after accountancy_code; UPDATE llx_const set name = 'ONLINE_PAYMENT_MESSAGE_OK' where name = 'PAYPAL_MESSAGE_OK'; diff --git a/htdocs/install/mysql/tables/llx_actioncomm.key.sql b/htdocs/install/mysql/tables/llx_actioncomm.key.sql index 64162dbbc73..257eb22a240 100644 --- a/htdocs/install/mysql/tables/llx_actioncomm.key.sql +++ b/htdocs/install/mysql/tables/llx_actioncomm.key.sql @@ -1,5 +1,5 @@ -- ============================================================================ --- Copyright (C) 2005-2013 Laurent Destailleur +-- Copyright (C) 2005-2017 Laurent Destailleur -- Copyright (C) 2011 Regis Houssin -- -- This program is free software; you can redistribute it and/or modify @@ -22,3 +22,10 @@ ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_fk_soc (fk_soc); ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_fk_contact (fk_contact); ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_code (code); ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_fk_element (fk_element); +ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_fk_user_action (fk_user_action); +ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_fk_project (fk_project); +ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_datep (datep); +ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_datep2 (datep2); +ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_recurid (recurid); + +ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_ref_ext (ref_ext); diff --git a/htdocs/install/mysql/tables/llx_actioncomm.sql b/htdocs/install/mysql/tables/llx_actioncomm.sql index fdde835ad51..8203b027567 100644 --- a/htdocs/install/mysql/tables/llx_actioncomm.sql +++ b/htdocs/install/mysql/tables/llx_actioncomm.sql @@ -1,6 +1,6 @@ -- ======================================================================== -- Copyright (C) 2001-2003 Rodolphe Quiedeville --- Copyright (C) 2005-2010 Laurent Destailleur +-- Copyright (C) 2005-2017 Laurent Destailleur -- Copyright (C) 2011 Regis Houssin -- -- This program is free software; you can redistribute it and/or modify @@ -23,8 +23,8 @@ create table llx_actioncomm ( id integer AUTO_INCREMENT PRIMARY KEY, - ref_ext varchar(128), - entity integer DEFAULT 1 NOT NULL, -- multi company id + ref_ext varchar(255), -- reference into an external system (not used by dolibarr). Example: An id coming from google calendar has length between 5 and 1024 chars. An event id must follow rule: chars used in base32hex encoding (i.e. lowercase letters a-v and digits 0-9, see section 3.1.2 in RFC2938) + entity integer DEFAULT 1 NOT NULL, -- multi company id datep datetime, -- date start datep2 datetime, -- date end @@ -64,7 +64,7 @@ create table llx_actioncomm email_tobcc varchar(255), -- when event was an email, we store here the email_tobcc errors_to varchar(255), -- when event was an email, we store here the erros_to - recurid varchar(128), -- used to store event id to link each other all the repeating event record + recurid varchar(128), -- used to store event id to link each other all the repeating event record. It can be the "iCalUID" as in RFC5545 (an id similar for all the same serie) recurrule varchar(128), -- contains string with ical format recurring rule like 'FREQ=MONTHLY;INTERVAL=2;BYMONTHDAY=19' or 'FREQ=WEEKLY;BYDAY=MO' recurdateend datetime, -- no more recurring event after this date diff --git a/htdocs/install/mysql/tables/llx_commande_fournisseur.sql b/htdocs/install/mysql/tables/llx_commande_fournisseur.sql index bb060afca67..930a675c5e1 100644 --- a/htdocs/install/mysql/tables/llx_commande_fournisseur.sql +++ b/htdocs/install/mysql/tables/llx_commande_fournisseur.sql @@ -26,7 +26,7 @@ create table llx_commande_fournisseur ref varchar(255) NOT NULL, -- order number entity integer DEFAULT 1 NOT NULL, -- multi company id - ref_ext varchar(64), -- reference into an external system (not used by dolibarr) + ref_ext varchar(255), -- reference into an external system (not used by dolibarr) ref_supplier varchar(255), fk_soc integer NOT NULL, diff --git a/htdocs/install/mysql/tables/llx_contrat.sql b/htdocs/install/mysql/tables/llx_contrat.sql index 606c0e78f8f..ac6f56631ec 100644 --- a/htdocs/install/mysql/tables/llx_contrat.sql +++ b/htdocs/install/mysql/tables/llx_contrat.sql @@ -21,10 +21,10 @@ create table llx_contrat ( rowid integer AUTO_INCREMENT PRIMARY KEY, - ref varchar(50), -- contrat reference - ref_customer varchar(50), -- customer contract ref - ref_supplier varchar(50), -- supplier contract ref - ref_ext varchar(50), -- external contract ref + ref varchar(255), -- contrat reference + ref_customer varchar(255), -- customer contract ref + ref_supplier varchar(255), -- supplier contract ref + ref_ext varchar(255), -- external contract ref entity integer DEFAULT 1 NOT NULL, -- multi company id tms timestamp, datec datetime, -- creation date diff --git a/htdocs/install/mysql/tables/llx_expedition.sql b/htdocs/install/mysql/tables/llx_expedition.sql index cdf3f253892..e252783ac94 100644 --- a/htdocs/install/mysql/tables/llx_expedition.sql +++ b/htdocs/install/mysql/tables/llx_expedition.sql @@ -28,9 +28,9 @@ create table llx_expedition fk_soc integer NOT NULL, fk_projet integer DEFAULT NULL, - ref_ext varchar(30), -- reference into an external system (not used by dolibarr) - ref_int varchar(30), -- reference into an internal system (used by dolibarr to store extern id like paypal info) - ref_customer varchar(30), -- customer number + ref_ext varchar(255), -- reference into an external system (not used by dolibarr) + ref_int varchar(255), -- reference into an internal system (used by dolibarr to store extern id like paypal info) + ref_customer varchar(255), -- customer number date_creation datetime, -- date de creation fk_user_author integer, -- author of creation diff --git a/htdocs/install/mysql/tables/llx_livraison.sql b/htdocs/install/mysql/tables/llx_livraison.sql index d5848eb708e..32e9de8b2a7 100644 --- a/htdocs/install/mysql/tables/llx_livraison.sql +++ b/htdocs/install/mysql/tables/llx_livraison.sql @@ -25,9 +25,9 @@ create table llx_livraison entity integer DEFAULT 1 NOT NULL, -- multi company id fk_soc integer NOT NULL, - ref_ext varchar(30), -- reference into an external system (not used by dolibarr) - ref_int varchar(30), -- reference into an internal system (used by dolibarr to store extern id like paypal info) - ref_customer varchar(30), -- customer number + ref_ext varchar(255), -- reference into an external system (not used by dolibarr) + ref_int varchar(255), -- reference into an internal system (used by dolibarr to store extern id like paypal info) + ref_customer varchar(255), -- customer number date_creation datetime, -- date de creation fk_user_author integer, -- createur du bon de livraison diff --git a/htdocs/install/mysql/tables/llx_societe.sql b/htdocs/install/mysql/tables/llx_societe.sql index a6a1e51a22b..4d74e411260 100644 --- a/htdocs/install/mysql/tables/llx_societe.sql +++ b/htdocs/install/mysql/tables/llx_societe.sql @@ -25,11 +25,11 @@ create table llx_societe ( rowid integer AUTO_INCREMENT PRIMARY KEY, nom varchar(128), -- company reference name (should be same length than adherent.societe) - name_alias varchar(128) NULL, - entity integer DEFAULT 1 NOT NULL, -- multi company id + name_alias varchar(128) NULL, + entity integer DEFAULT 1 NOT NULL, -- multi company id - ref_ext varchar(128), -- reference into an external system (not used by dolibarr) - ref_int varchar(60), -- reference into an internal system (deprecated) + ref_ext varchar(255), -- reference into an external system (not used by dolibarr) + ref_int varchar(255), -- reference into an internal system (deprecated) statut tinyint DEFAULT 0, -- statut parent integer, diff --git a/htdocs/install/mysql/tables/llx_socpeople.sql b/htdocs/install/mysql/tables/llx_socpeople.sql index b9aad05b956..51848b33b48 100644 --- a/htdocs/install/mysql/tables/llx_socpeople.sql +++ b/htdocs/install/mysql/tables/llx_socpeople.sql @@ -25,7 +25,7 @@ create table llx_socpeople tms timestamp, fk_soc integer, -- lien vers la societe entity integer DEFAULT 1 NOT NULL, -- multi company id - ref_ext varchar(128), -- reference into an external system (not used by dolibarr) + ref_ext varchar(255), -- reference into an external system (not used by dolibarr) civility varchar(6), lastname varchar(50), firstname varchar(50), From a2c80a704f69316e65414b3ffac9388326d2d77d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 13 Nov 2017 19:06:58 +0100 Subject: [PATCH 071/131] Code comment --- .../modules/import/import_xlsx.modules.php | 50 +++++++++---------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/htdocs/core/modules/import/import_xlsx.modules.php b/htdocs/core/modules/import/import_xlsx.modules.php index eff3b8f8b21..22b81fcdcbf 100644 --- a/htdocs/core/modules/import/import_xlsx.modules.php +++ b/htdocs/core/modules/import/import_xlsx.modules.php @@ -20,9 +20,9 @@ */ /** - * \file htdocs/core/modules/import/import_csv.modules.php + * \file htdocs/core/modules/import/import_xlsx.modules.php * \ingroup import - * \brief File to load import files with CSV format + * \brief File to load import files with Excel format */ require_once DOL_DOCUMENT_ROOT .'/core/modules/import/modules_import.php'; @@ -54,10 +54,10 @@ class ImportXlsx extends ModeleImports var $cacheconvert=array(); // Array to cache list of value found after a convertion var $cachefieldtable=array(); // Array to cache list of value found into fields@tables - + var $workbook; // temporary import file var $record; // current record - var $headers; + var $headers; /** @@ -95,7 +95,7 @@ class ImportXlsx extends ModeleImports if (preg_match('/^societe_/',$datatoimport)) $this->thirpartyobject=new Societe($this->db); } - + /** * Output header of an example file for this format * @@ -144,7 +144,7 @@ class ImportXlsx extends ModeleImports foreach($headerlinefields as $field) { $this->workbook->getActiveSheet()->SetCellValueByColumnAndRow($col, 1, $outputlangs->transnoentities($field)); // set autowidth - //$this->workbook->getActiveSheet()->getColumnDimension($this->column2Letter($col + 1))->setAutoSize(true); + //$this->workbook->getActiveSheet()->getColumnDimension($this->column2Letter($col + 1))->setAutoSize(true); $col++; } return ''; // final output will be generated in footer @@ -211,10 +211,10 @@ class ImportXlsx extends ModeleImports return $ret; } - + /** * Return nb of records. File must be closed. - * + * * @param string $file Path of filename * @return int <0 if KO, >=0 if OK */ @@ -222,15 +222,15 @@ class ImportXlsx extends ModeleImports { $reader = new PHPExcel_Reader_Excel2007(); $this->workbook = $reader->load($file); - + $rowcount = $this->workbook->getActiveSheet()->getHighestDataRow(); - + $this->workbook->disconnectWorksheets(); unset($this->workbook); - + return $rowcount; } - + /** * Input header line from file @@ -399,7 +399,7 @@ class ImportXlsx extends ModeleImports if (! is_numeric($newval) && $newval != '' && ! preg_match('/^id:/i',$newval)) $isidorref='ref'; $newval=preg_replace('/^(id|ref):/i','',$newval); // Remove id: or ref: that was used to force if field is id or ref //print 'Val is now '.$newval.' and is type '.$isidorref."
\n"; - + if ($isidorref == 'ref') // If value into input import file is a ref, we apply the function defined into descriptor { $file=(empty($objimport->array_import_convertvalue[0][$val]['classfile'])?$objimport->array_import_convertvalue[0][$val]['file']:$objimport->array_import_convertvalue[0][$val]['classfile']); @@ -502,9 +502,9 @@ class ImportXlsx extends ModeleImports } if (is_numeric($defaultref) && $defaultref <= 0) $defaultref=''; $newval=$defaultref; - } - - + } + + elseif ($objimport->array_import_convertvalue[0][$val]['rule']=='numeric') { $newval = price2num($newval); @@ -616,7 +616,7 @@ class ImportXlsx extends ModeleImports // We do SELECT to get the rowid, if we already have the rowid, it's to be used below for related tables (extrafields) if (empty($lastinsertid)) { $sqlSelect = 'SELECT rowid FROM '.$tablename; - + $data = array_combine($listfields, $listvalues); $where = array(); $filters = array(); @@ -627,7 +627,7 @@ class ImportXlsx extends ModeleImports $filters[] = $col.' = '.$data[$key]; } $sqlSelect.= ' WHERE '.implode(' AND ', $where); - + $resql=$this->db->query($sqlSelect); if($resql) { $res = $this->db->fetch_object($resql); @@ -650,23 +650,23 @@ class ImportXlsx extends ModeleImports $error++; } } - + if (!empty($lastinsertid)) { // Build SQL UPDATE request $sqlstart = 'UPDATE '.$tablename; - + $data = array_combine($listfields, $listvalues); $set = array(); foreach ($data as $key => $val) { $set[] = $key.' = '.$val; } $sqlstart.= ' SET '.implode(', ', $set); - + if(empty($keyfield)) $keyfield = 'rowid'; $sqlend = ' WHERE '.$keyfield.' = '.$lastinsertid; - + $sql = $sqlstart.$sqlend; - + // Run update request $resql=$this->db->query($sql); if($resql) { @@ -691,14 +691,14 @@ class ImportXlsx extends ModeleImports if (! empty($tablewithentity_cache[$tablename])) { $sqlstart.= ', entity'; $sqlend.= ', '.$conf->entity; - } + } if (! empty($objimport->array_import_tables_creator[0][$alias])) { $sqlstart.= ', '.$objimport->array_import_tables_creator[0][$alias]; $sqlend.=', '.$user->id; } $sql = $sqlstart.$sqlend.')'; dol_syslog("import_xlsx.modules", LOG_DEBUG); - + // Run insert request if ($sql) { From 31e152274c679b84831e8f1e518443aa313559c0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 14 Nov 2017 01:00:57 +0100 Subject: [PATCH 072/131] NEW Add 2 new automatic classification in workflow module --- htdocs/admin/workflow.php | 60 ++++++++++++++----- ...e_20_modWorkflow_WorkflowManager.class.php | 51 ++++++++++++++++ htdocs/langs/en_US/workflow.lang | 7 ++- 3 files changed, 101 insertions(+), 17 deletions(-) diff --git a/htdocs/admin/workflow.php b/htdocs/admin/workflow.php index c730760898d..511188e55df 100644 --- a/htdocs/admin/workflow.php +++ b/htdocs/admin/workflow.php @@ -27,8 +27,7 @@ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; -$langs->load("admin"); -$langs->load("workflow"); +$langs->loadLangs(array("admin","workflow","propal","workflow","orders","supplier_proposals")); if (! $user->admin) accessforbidden(); @@ -68,21 +67,26 @@ print "
"; // List of workflow we can enable -print '
'.$langs->trans("DolibarrWorkBoard").'
'.dol_print_date(dol_filemtime($file),'dayhour').'
'.$holidaystatic->getNomUrl(1).''.$userstatic->getNomUrl(-1, 'leave').'
'.$deplacementstatic->getNomUrl(1).''.$userstatic->getNomUrl(-1).'
'.$expensereportstatic->getNomUrl(1).''.$userstatic->getNomUrl(-1).'' . $langs->trans("PriceBase") . '' . $langs->trans("VATRate") . '' . $langs->trans("HT") . '' . $langs->trans("TTC") . '' . $langs->trans("INCT") . '' . $langs->trans("INCVATONLY") . '' . $langs->trans("INCT") . '' . $langs->trans("TTC") . '' . $langs->trans("MinPrice") . ' ' . $langs->trans("HT") . '' . $langs->trans("MinPrice") . ' ' . $langs->trans("TTC") . '' . $langs->trans("ChangedBy") . '" . dol_print_date($line->datec, "dayhour") . "' . $langs->trans($line->price_base_type) . "'; -var_dump($prodcustprice);exit; + $positiverates=''; - if (price2num($objp->tva_tx)) $positiverates.=($positiverates?'/':'').price2num($objp->tva_tx); - if (price2num($objp->localtax1_type)) $positiverates.=($positiverates?'/':'').price2num($objp->localtax1_tx); - if (price2num($objp->localtax2_type)) $positiverates.=($positiverates?'/':'').price2num($objp->localtax2_tx); + if (price2num($line->tva_tx)) $positiverates.=($positiverates?'/':'').price2num($line->tva_tx); + if (price2num($line->localtax1_type)) $positiverates.=($positiverates?'/':'').price2num($line->localtax1_tx); + if (price2num($line->localtax2_type)) $positiverates.=($positiverates?'/':'').price2num($line->localtax2_tx); if (empty($positiverates)) $positiverates='0'; - echo vatrate($positiverates.($objp->default_vat_code?' ('.$objp->default_vat_code.')':''), '%', $objp->tva_npr); + + echo vatrate($positiverates.($line->default_vat_code?' ('.$line->default_vat_code.')':''), '%', ($line->tva_npr?$line->tva_npr:$line->recuperableonly)); //. vatrate($tva_tx, true, $line->recuperableonly) . print "' . price($line->price) . "' . price($line->price_ttc) . "' . price($resultarray[2]) . '' . price($line->price_ttc) . "' . price($resultarray[2]) . '' . price($line->price_ttc) . "' . price($line->price_min) . '' . price($line->price_min_ttc) . '
' . $langs->trans("PriceBase") . '' . $langs->trans("VATRate") . '' . $langs->trans("HT") . '' . $langs->trans("TTC") . '' . $langs->trans("INCT") . '' . $langs->trans("INCVATONLY") . '' . $langs->trans("INCT") . '' . $langs->trans("TTC") . '' . $langs->trans("MinPrice") . ' ' . $langs->trans("HT") . '' . $langs->trans("MinPrice") . ' ' . $langs->trans("TTC") . '' . $langs->trans("ChangedBy") . '' . price($object->price) . "' . price($object->price_ttc) . "' . price($resultarray[2]) . '' . price($object->price_ttc) . "' . price($resultarray[2]) . '' . price($object->price_ttc) . "' . price($object->price_min) . '' . price($object->price_min_ttc) . '
' . price($line->price) . "' . price($line->price_ttc) . "' . price($resultarray[2]) . '' . price($line->price_ttc) . "' . price($resultarray[2]) . '' . price($line->price_ttc) . "' . price($line->price_min) . '' . price($line->price_min_ttc) . '
'."\n"; - clearstatcache(); $workflowcodes=array( // Automatic creation 'WORKFLOW_PROPAL_AUTOCREATE_ORDER'=>array('family'=>'create', 'position'=>10, 'enabled'=>'! empty($conf->propal->enabled) && ! empty($conf->commande->enabled)', 'picto'=>'order'), 'WORKFLOW_ORDER_AUTOCREATE_INVOICE'=>array('family'=>'create', 'position'=>20, 'enabled'=>'! empty($conf->commande->enabled) && ! empty($conf->facture->enabled)', 'picto'=>'bill'), - // Automatic classification - 'WORKFLOW_ORDER_CLASSIFY_BILLED_PROPAL'=>array('family'=>'classify', 'position'=>30, 'enabled'=>'! empty($conf->propal->enabled) && ! empty($conf->commande->enabled)', 'picto'=>'order','warning'=>''), - 'WORKFLOW_INVOICE_CLASSIFY_BILLED_PROPAL'=>array('family'=>'classify', 'position'=>30, 'enabled'=>'! empty($conf->propal->enabled) && ! empty($conf->facture->enabled)', 'picto'=>'order','warning'=>''), + 'separator1'=>array('family'=>'separator', 'position'=>25), + // Automatic classification proposal + 'WORKFLOW_ORDER_CLASSIFY_BILLED_PROPAL'=>array('family'=>'classify_proposal', 'position'=>30, 'enabled'=>'! empty($conf->propal->enabled) && ! empty($conf->commande->enabled)', 'picto'=>'propal','warning'=>''), + 'WORKFLOW_INVOICE_CLASSIFY_BILLED_PROPAL'=>array('family'=>'classify_proposal', 'position'=>31, 'enabled'=>'! empty($conf->propal->enabled) && ! empty($conf->facture->enabled)', 'picto'=>'propal','warning'=>''), + // Automatic classification invoice + 'WORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING'=>array('family'=>'classify_order', 'position'=>40, 'enabled'=>'! empty($conf->expedition->enabled) && ! empty($conf->commande->enabled)', 'picto'=>'order'), // For the following 2 options, if module invoice is disabled, they does not exists, so "Classify billed" for order must be done manually from order card. - 'WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER'=>array('family'=>'classify', 'position'=>50, 'enabled'=>'! empty($conf->facture->enabled) && ! empty($conf->commande->enabled)', 'picto'=>'bill','warning'=>''), - 'WORKFLOW_INVOICE_CLASSIFY_BILLED_ORDER'=>array('family'=>'classify', 'position'=>40, 'enabled'=>'! empty($conf->facture->enabled) && ! empty($conf->commande->enabled)', 'picto'=>'bill','warning'=>''), - 'WORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING'=>array('family'=>'classify', 'position'=>30, 'enabled'=>'! empty($conf->expedition->enabled) && ! empty($conf->commande->enabled)', 'picto'=>'order'), + 'WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER'=>array('family'=>'classify_order', 'position'=>41, 'enabled'=>'! empty($conf->facture->enabled) && ! empty($conf->commande->enabled)', 'picto'=>'order','warning'=>''), + //Moved as hidden feature: 'WORKFLOW_INVOICE_CLASSIFY_BILLED_ORDER'=>array('family'=>'classify_order', 'position'=>42, 'enabled'=>'! empty($conf->facture->enabled) && ! empty($conf->commande->enabled)', 'picto'=>'order','warning'=>''), + 'separator2'=>array('family'=>'separator', 'position'=>50), + // Automatic classification supplier proposal + 'WORKFLOW_ORDER_CLASSIFY_BILLED_SUPPLIER_PROPOSAL'=>array('family'=>'classify_supplier_proposal', 'position'=>60, 'enabled'=>'! empty($conf->supplier_proposal->enabled) && ! empty($conf->fournisseur->enabled)', 'picto'=>'propal','warning'=>''), + // Automatic classification supplier order + 'WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_SUPPLIER_ORDER'=>array('family'=>'classify_supplier_order', 'position'=>62, 'enabled'=>'! empty($conf->fournisseur->enabled)', 'picto'=>'order','warning'=>''), ); if (! empty($conf->modules_parts['workflow']) && is_array($conf->modules_parts['workflow'])) @@ -93,27 +97,53 @@ if (! empty($conf->modules_parts['workflow']) && is_array($conf->modules_parts[' } } -// TODO We must sort on position here +// Sort on position +$workflowcodes = dol_sort_array($workflowcodes, 'position'); $nbqualified=0; $oldfamily=''; +print '
'."\n"; + foreach($workflowcodes as $key => $params) { $picto=$params['picto']; $enabled=$params['enabled']; $family=$params['family']; - if (! verifCond($enabled)) continue; + + if ($family == 'separator') + { + print '

'; + print ''."\n"; + + continue; + } + + if (! verifCond($enabled)) continue; $nbqualified++; + if ($oldfamily != $family) { print ''."\n"; print ' '; print ' '; print "\n"; diff --git a/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php b/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php index c25e1ae9ad7..3c9880ef4ec 100644 --- a/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php +++ b/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php @@ -167,7 +167,58 @@ class InterfaceWorkflowManager extends DolibarrTriggers } return $ret; } + } + // classify billed order & billed propososal + if ($action == 'BILL_SUPPLIER_VALIDATE') + { + dol_syslog( "Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id ); + + // First classify billed the order to allow the proposal classify process + if (! empty($conf->fournisseur->commande->enabled) && ! empty($conf->global->WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_SUPPLIER_ORDER)) + { + $object->fetchObjectLinked('','order_supplier',$object->id,$object->element); + if (! empty($object->linkedObjects)) + { + $totalonlinkedelements=0; + foreach($object->linkedObjects['order_supplier'] as $element) + { + if ($element->statut == CommandeFournisseur::STATUS_ACCEPTED || $element->statut == CommandeFournisseur::STATUS_ORDERSENT || $element->statut == CommandeFournisseur::STATUS_RECEIVED_PARTIALLY || $element->statut == CommandeFournisseur::STATUS_RECEIVED_COMPLETELY) $totalonlinkedelements += $element->total_ht; + } + dol_syslog( "Amount of linked orders = ".$totalonlinkedelements.", of invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht) ); + if ( ($totalonlinkedelements == $object->total_ht) || (! empty($conf->global->WORKFLOW_CLASSIFY_IF_AMOUNTS_ARE_DIFFERENTS)) ) + { + foreach($object->linkedObjects['order_supplier'] as $element) + { + $ret=$element->classifyBilled($user); + } + } + } + return $ret; + } + + // Second classify billed the proposal. + if (! empty($conf->supplier_proposal->enabled) && ! empty($conf->global->WORKFLOW_INVOICE_CLASSIFY_BILLED_SUPPLIER_PROPOSAL)) + { + $object->fetchObjectLinked('','supplier_proposal',$object->id,$object->element); + if (! empty($object->linkedObjects)) + { + $totalonlinkedelements=0; + foreach($object->linkedObjects['supplier_proposal'] as $element) + { + if ($element->statut == SupplierProposal::STATUS_SIGNED || $element->statut == SupplierProposal::STATUS_BILLED) $totalonlinkedelements += $element->total_ht; + } + dol_syslog( "Amount of linked supplier proposals = ".$totalonlinkedelements.", of supplier invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht) ); + if ( ($totalonlinkedelements == $object->total_ht) || (! empty($conf->global->WORKFLOW_CLASSIFY_IF_AMOUNTS_ARE_DIFFERENTS)) ) + { + foreach($object->linkedObjects['supplier_proposal'] as $element) + { + $ret=$element->classifyBilled($user); + } + } + } + return $ret; + } } // Invoice classify billed order diff --git a/htdocs/langs/en_US/workflow.lang b/htdocs/langs/en_US/workflow.lang index a477790b01b..eba04cc44d1 100644 --- a/htdocs/langs/en_US/workflow.lang +++ b/htdocs/langs/en_US/workflow.lang @@ -7,11 +7,14 @@ descWORKFLOW_PROPAL_AUTOCREATE_ORDER=Automatically create a customer order after descWORKFLOW_PROPAL_AUTOCREATE_INVOICE=Automatically create a customer invoice after a commercial proposal is signed (new invoice will have same amount than proposal) descWORKFLOW_CONTRACT_AUTOCREATE_INVOICE=Automatically create a customer invoice after a contract is validated descWORKFLOW_ORDER_AUTOCREATE_INVOICE=Automatically create a customer invoice after a customer order is closed (new invoice will have same amount than order) -# Autoclassify +# Autoclassify customer proposal or order descWORKFLOW_ORDER_CLASSIFY_BILLED_PROPAL=Classify linked source proposal(s) to billed when customer order is set to billed (and if amount of the order is same than total amount of signed linked proposals) descWORKFLOW_INVOICE_CLASSIFY_BILLED_PROPAL=Classify linked source proposal(s) to billed when customer invoice is validated (and if amount of the invoice is same than total amount of signed linked proposals) descWORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER=Classify linked source customer order(s) to billed when customer invoice is validated (and if amount of the invoice is same than total amount of linked orders) descWORKFLOW_INVOICE_CLASSIFY_BILLED_ORDER=Classify linked source customer order(s) to billed when customer invoice is set to paid (and if amount of the invoice is same than total amount of linked orders) -descWORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING=Classify linked source order to shipped when a shipment is validated (and if quantity shipped by all shipments is the same as in the order to update) +descWORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING=Classify linked source customer order to shipped when a shipment is validated (and if quantity shipped by all shipments is the same as in the order to update) +# Autoclassify supplier order +descWORKFLOW_ORDER_CLASSIFY_BILLED_SUPPLIER_PROPOSAL=Classify linked source supplier proposal(s) to billed when supplier invoice is validated (and if amount of the invoice is same than total amount of linked proposals) +descWORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_SUPPLIER_ORDER=Classify linked source supplier order(s) to billed when supplier invoice is validated (and if amount of the invoice is same than total amount of linked orders) AutomaticCreation=Automatic creation AutomaticClassification=Automatic classification \ No newline at end of file From 010e542fe444f783442a05ce2b4bcae78940640f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 14 Nov 2017 01:15:02 +0100 Subject: [PATCH 073/131] CSS --- htdocs/theme/eldy/style.css.php | 3 +++ htdocs/theme/md/style.css.php | 3 +++ 2 files changed, 6 insertions(+) diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index c57f19d676b..c24caf2f22b 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -3009,6 +3009,9 @@ span.dashboardlineko { .boxtablenobottom { border-bottom-width: 0 !important; } +.boxtable .fichehalfright, .boxtable .fichehalfleft { + min-width: 300px; +} .tdboxstats { text-align: center; } diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 066cf1e7d72..dd568d9ba60 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -3103,6 +3103,9 @@ span.dashboardlineko { .boxtablenobottom { border-bottom-width: 0 !important; } +.boxtable .fichehalfright, .boxtable .fichehalfleft { + min-width: 300px; +} .tdboxstats { text-align: center; } From bf05a0b8e005353774318c33f86b59c9754a4144 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 14 Nov 2017 01:19:04 +0100 Subject: [PATCH 074/131] Update api_orders.class.php --- htdocs/commande/class/api_orders.class.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/htdocs/commande/class/api_orders.class.php b/htdocs/commande/class/api_orders.class.php index 086379a3989..7f2a5b03ae4 100644 --- a/htdocs/commande/class/api_orders.class.php +++ b/htdocs/commande/class/api_orders.class.php @@ -396,16 +396,16 @@ class Orders extends DolibarrApi * @return int */ function put($id, $request_data = NULL) { - if(! DolibarrApiAccess::$user->rights->commande->creer) { + if (! DolibarrApiAccess::$user->rights->commande->creer) { throw new RestException(401); } $result = $this->commande->fetch($id); - if( ! $result ) { + if (! $result) { throw new RestException(404, 'Order not found'); } - if( ! DolibarrApi::_checkAccessToResource('commande',$this->commande->id)) { + if (! DolibarrApi::_checkAccessToResource('commande',$this->commande->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } foreach($request_data as $field => $value) { @@ -414,12 +414,12 @@ class Orders extends DolibarrApi } // Update availability - if( isset($this->commande->availability_id) && !empty($this->commande->availability_id) ) { - if($this->commande->availability($this->commande->availability_id) < 0) + if (!empty($this->commande->availability_id)) { + if ($this->commande->availability($this->commande->availability_id) < 0) throw new RestException(400, 'Error while updating availability'); } - if($this->commande->update($id, DolibarrApiAccess::$user, 1, '', '', 'update')) + if ($this->commande->update($id, DolibarrApiAccess::$user, 1, '', '', 'update')) return $this->get($id); return false; From 4212000cafde2965b61a39f1061c5088d23b7618 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 14 Nov 2017 01:21:06 +0100 Subject: [PATCH 075/131] Update api_orders.class.php --- htdocs/commande/class/api_orders.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/commande/class/api_orders.class.php b/htdocs/commande/class/api_orders.class.php index 7f2a5b03ae4..64958b01ef6 100644 --- a/htdocs/commande/class/api_orders.class.php +++ b/htdocs/commande/class/api_orders.class.php @@ -493,10 +493,10 @@ class Orders extends DolibarrApi $result = $this->commande->valid(DolibarrApiAccess::$user, $idwarehouse, $notrigger); if ($result == 0) { - throw new RestException(500, 'Error nothing done. May be object is already validated'); + throw new RestException(304, 'Error nothing done. May be object is already validated'); } if ($result < 0) { - throw new RestException(304, 'Error when validating Order: '.$this->commande->error); + throw new RestException(500, 'Error when validating Order: '.$this->commande->error); } $result = $this->commande->fetch($id); if( ! $result ) { From a12186a0b800f190d04d23f3f2cbc61cba8c8a58 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 14 Nov 2017 01:26:02 +0100 Subject: [PATCH 076/131] Use HTTP response code 304 instead of 500 when nothing is done --- htdocs/comm/propal/class/api_proposals.class.php | 4 ++-- htdocs/commande/class/api_orders.class.php | 2 +- htdocs/contrat/class/api_contracts.class.php | 4 ++-- htdocs/fourn/class/api_supplier_invoices.class.php | 2 +- htdocs/fourn/class/api_supplier_orders.class.php | 2 +- htdocs/projet/class/api_projects.class.php | 2 +- htdocs/projet/class/api_tasks.class.php | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/htdocs/comm/propal/class/api_proposals.class.php b/htdocs/comm/propal/class/api_proposals.class.php index 97ea07bf7e6..36a5c9a780d 100644 --- a/htdocs/comm/propal/class/api_proposals.class.php +++ b/htdocs/comm/propal/class/api_proposals.class.php @@ -493,7 +493,7 @@ class Proposals extends DolibarrApi $result = $this->propal->valid(DolibarrApiAccess::$user, $notrigger); if ($result == 0) { - throw new RestException(500, 'Error nothing done. May be object is already validated'); + throw new RestException(304, 'Error nothing done. May be object is already validated'); } if ($result < 0) { throw new RestException(500, 'Error when validating Commercial Proposal: '.$this->propal->error); @@ -535,7 +535,7 @@ class Proposals extends DolibarrApi $result = $this->propal->cloture(DolibarrApiAccess::$user, $status, $note_private, $notrigger); if ($result == 0) { - throw new RestException(500, 'Error nothing done. May be object is already closed'); + throw new RestException(304, 'Error nothing done. May be object is already closed'); } if ($result < 0) { throw new RestException(500, 'Error when closing Commercial Proposal: '.$this->propal->error); diff --git a/htdocs/commande/class/api_orders.class.php b/htdocs/commande/class/api_orders.class.php index 64958b01ef6..8bfed9d4eb4 100644 --- a/htdocs/commande/class/api_orders.class.php +++ b/htdocs/commande/class/api_orders.class.php @@ -537,7 +537,7 @@ class Orders extends DolibarrApi $result = $this->commande->cloture(DolibarrApiAccess::$user, $notrigger); if ($result == 0) { - throw new RestException(500, 'Error nothing done. May be object is already closed'); + throw new RestException(304, 'Error nothing done. May be object is already closed'); } if ($result < 0) { throw new RestException(500, 'Error when closing Order: '.$this->commande->error); diff --git a/htdocs/contrat/class/api_contracts.class.php b/htdocs/contrat/class/api_contracts.class.php index 0bc02458869..45595712b68 100644 --- a/htdocs/contrat/class/api_contracts.class.php +++ b/htdocs/contrat/class/api_contracts.class.php @@ -479,7 +479,7 @@ class Contracts extends DolibarrApi $result = $this->contract->validate(DolibarrApiAccess::$user, '', $notrigger); if ($result == 0) { - throw new RestException(500, 'Error nothing done. May be object is already validated'); + throw new RestException(304, 'Error nothing done. May be object is already validated'); } if ($result < 0) { throw new RestException(500, 'Error when validating Contract: '.$this->contract->error); @@ -525,7 +525,7 @@ class Contracts extends DolibarrApi $result = $this->contract->closeAll(DolibarrApiAccess::$user, $notrigger); if ($result == 0) { - throw new RestException(500, 'Error nothing done. May be object is already close'); + throw new RestException(304, 'Error nothing done. May be object is already close'); } if ($result < 0) { throw new RestException(500, 'Error when closing Contract: '.$this->contract->error); diff --git a/htdocs/fourn/class/api_supplier_invoices.class.php b/htdocs/fourn/class/api_supplier_invoices.class.php index 1d7efb236a2..e60fdccd4ad 100644 --- a/htdocs/fourn/class/api_supplier_invoices.class.php +++ b/htdocs/fourn/class/api_supplier_invoices.class.php @@ -312,7 +312,7 @@ class SupplierInvoices extends DolibarrApi $result = $this->invoice->validate(DolibarrApiAccess::$user, '', $idwarehouse, $notrigger); if ($result == 0) { - throw new RestException(500, 'Error nothing done. May be object is already validated'); + throw new RestException(304, 'Error nothing done. May be object is already validated'); } if ($result < 0) { throw new RestException(500, 'Error when validating Invoice: '.$this->invoice->error); diff --git a/htdocs/fourn/class/api_supplier_orders.class.php b/htdocs/fourn/class/api_supplier_orders.class.php index 22cd4eb191c..74b5bbe43b3 100644 --- a/htdocs/fourn/class/api_supplier_orders.class.php +++ b/htdocs/fourn/class/api_supplier_orders.class.php @@ -316,7 +316,7 @@ class SupplierOrders extends DolibarrApi $result = $this->order->valid(DolibarrApiAccess::$user, $idwarehouse, $notrigger); if ($result == 0) { - throw new RestException(500, 'Error nothing done. May be object is already validated'); + throw new RestException(304, 'Error nothing done. May be object is already validated'); } if ($result < 0) { throw new RestException(500, 'Error when validating Order: '.$this->order->error); diff --git a/htdocs/projet/class/api_projects.class.php b/htdocs/projet/class/api_projects.class.php index 6fcdfde7ca2..f6364eb0544 100644 --- a/htdocs/projet/class/api_projects.class.php +++ b/htdocs/projet/class/api_projects.class.php @@ -513,7 +513,7 @@ class Projects extends DolibarrApi $result = $this->project->setValid(DolibarrApiAccess::$user, $notrigger); if ($result == 0) { - throw new RestException(500, 'Error nothing done. May be object is already validated'); + throw new RestException(304, 'Error nothing done. May be object is already validated'); } if ($result < 0) { throw new RestException(500, 'Error when validating Project: '.$this->project->error); diff --git a/htdocs/projet/class/api_tasks.class.php b/htdocs/projet/class/api_tasks.class.php index f00a536df87..fc006706d81 100644 --- a/htdocs/projet/class/api_tasks.class.php +++ b/htdocs/projet/class/api_tasks.class.php @@ -529,7 +529,7 @@ class Tasks extends DolibarrApi $result = $this->task->addTimeSpent(DolibarrApiAccess::$user, 0); if ($result == 0) { - throw new RestException(500, 'Error nothing done. May be object is already validated'); + throw new RestException(304, 'Error nothing done. May be object is already validated'); } if ($result < 0) { throw new RestException(500, 'Error when adding time: '.$this->task->error); From 59d9ab731ecae2cebae7f3f0dddb1b95e2db8767 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 14 Nov 2017 01:29:28 +0100 Subject: [PATCH 077/131] Add param $idwarehouse to settodraft --- htdocs/commande/class/api_orders.class.php | 7 ++++--- htdocs/commande/class/commande.class.php | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/htdocs/commande/class/api_orders.class.php b/htdocs/commande/class/api_orders.class.php index 8bfed9d4eb4..e5228185657 100644 --- a/htdocs/commande/class/api_orders.class.php +++ b/htdocs/commande/class/api_orders.class.php @@ -555,12 +555,13 @@ class Orders extends DolibarrApi * Set an order to draft * * @param int $id Order ID + * @param int $idwarehouse Warehouse ID to use for stock change (Used only if option STOCK_CALCULATE_ON_VALIDATE_ORDER is on) * * @url POST {id}/settodraft * * @return array */ - function settodraft($id) + function settodraft($id, $idwarehouse=-1) { if(! DolibarrApiAccess::$user->rights->commande->creer) { throw new RestException(401); @@ -574,7 +575,7 @@ class Orders extends DolibarrApi throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - $result = $this->commande->set_draft(DolibarrApiAccess::$user); + $result = $this->commande->set_draft(DolibarrApiAccess::$user, $idwarehouse); if ($result == 0) { throw new RestException(304, 'Nothing done. May be object is already closed'); } @@ -582,7 +583,7 @@ class Orders extends DolibarrApi throw new RestException(500, 'Error when closing Order: '.$this->commande->error); } - $result = $this->commande->fetch($id); + $result = $this->commande->fetch($id); if( ! $result ) { throw new RestException(404, 'Order not found'); } diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 04ba162cb9e..26674818027 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -416,7 +416,7 @@ class Commande extends CommonOrder * Set draft status * * @param User $user Object user that modify - * @param int $idwarehouse Id warehouse to use for stock change. + * @param int $idwarehouse Warehouse ID to use for stock change (Used only if option STOCK_CALCULATE_ON_VALIDATE_ORDER is on) * @return int <0 if KO, >0 if OK */ function set_draft($user, $idwarehouse=-1) From 3dc06977af6b5a45ae4b69b93ed3736c2ad92378 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 14 Nov 2017 01:33:44 +0100 Subject: [PATCH 078/131] Update listactions.php --- htdocs/comm/action/listactions.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/comm/action/listactions.php b/htdocs/comm/action/listactions.php index 90f2f9298fa..55a824c93ca 100644 --- a/htdocs/comm/action/listactions.php +++ b/htdocs/comm/action/listactions.php @@ -240,17 +240,17 @@ $sql.= " sp.lastname, sp.firstname"; // Add fields from extrafields foreach ($extrafields->attribute_label as $key => $val) $sql.=($extrafields->attribute_type[$key] != 'separate' ? ",ef.".$key.' as options_'.$key : ''); $sql.= " FROM ".MAIN_DB_PREFIX."actioncomm as a"; -$sql.=" LEFT JOIN ".MAIN_DB_PREFIX."c_actioncomm as c ON (c.id = a.fk_action)"; $sql.=" LEFT JOIN ".MAIN_DB_PREFIX."actioncomm_extrafields as ef ON (a.id = ef.fk_object) "; if (! $user->rights->societe->client->voir && ! $socid) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON a.fk_soc = sc.fk_soc"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON a.fk_soc = s.rowid"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."socpeople as sp ON a.fk_contact = sp.rowid"; +$sql.=" ,".MAIN_DB_PREFIX."c_actioncomm as c"; // We must filter on resource table if ($resourceid > 0) $sql.=", ".MAIN_DB_PREFIX."element_resources as r"; // We must filter on assignement table if ($filtert > 0 || $usergroup > 0) $sql.=", ".MAIN_DB_PREFIX."actioncomm_resources as ar"; if ($usergroup > 0) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."usergroup_user as ugu ON ugu.fk_user = ar.fk_element"; -$sql.= " WHERE 1"; +$sql.= " WHERE c.id = a.fk_action"; $sql.= ' AND a.entity IN ('.getEntity('agenda').')'; // Condition on actioncode if (! empty($actioncode)) From 11cb9c0d81fadad25d1654f553146a406429e121 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 14 Nov 2017 01:57:50 +0100 Subject: [PATCH 079/131] Code simpler --- htdocs/comm/action/listactions.php | 68 +++++++++++--------- htdocs/core/class/html.formactions.class.php | 12 ++-- 2 files changed, 42 insertions(+), 38 deletions(-) diff --git a/htdocs/comm/action/listactions.php b/htdocs/comm/action/listactions.php index 55a824c93ca..8faeb365cb6 100644 --- a/htdocs/comm/action/listactions.php +++ b/htdocs/comm/action/listactions.php @@ -120,6 +120,7 @@ $hookmanager->initHooks(array('agendalist')); $arrayfields=array( 'a.id'=>array('label'=>"Ref", 'checked'=>1), + 'owner'=>array('label'=>"Owner", 'checked'=>1), 'a.label'=>array('label'=>"Title", 'checked'=>1), 'c.libelle'=>array('label'=>"Type", 'checked'=>1), 'a.datep'=>array('label'=>"DateStart", 'checked'=>1), @@ -128,7 +129,7 @@ $arrayfields=array( 'a.fk_contact'=>array('label'=>"Contact", 'checked'=>1), 'a.fk_element'=>array('label'=>"LinkedObject", 'checked'=>$checkedsuppliercode, 'enabled'=>(! empty($conf->global->AGENDA_SHOW_LINKED_OBJECT))), 'a.percent'=>array('label'=>"Status", 'checked'=>1, 'position'=>1000), - + ); // Extra fields if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) @@ -278,7 +279,7 @@ if (! empty($actioncode)) else { $sql.=" AND c.code IN ('".implode("','", explode(',', $actioncode))."')"; - } + } } } } @@ -315,12 +316,12 @@ foreach ($search_array_options as $key => $val) $crit=$val; $tmpkey=preg_replace('/search_options_/','',$key); $typ=$extrafields->attribute_type[$tmpkey]; - $mode=0; - if (in_array($typ, array('int','double','real'))) $mode=1; // Search on a numeric - if (in_array($typ, array('sellist')) && $crit != '0' && $crit != '-1') $mode=2; // Search on a foreign key int - if ($crit != '' && (! in_array($typ, array('select','sellist')) || $crit != '0')) + $mode_search=0; + if (in_array($typ, array('int','double','real'))) $mode_search=1; // Search on a numeric + if (in_array($typ, array('sellist','link')) && $crit != '0' && $crit != '-1') $mode_search=2; // Search on a foreign key int + if ($crit != '' && (! in_array($typ, array('select','sellist')) || $crit != '0') && (! in_array($typ, array('link')) || $crit != '-1')) { - $sql .= natural_search('ef.'.$tmpkey, $crit, $mode); + $sql .= natural_search('ef.'.$tmpkey, $crit, $mode_search); } } $sql.= $db->order($sortfield,$sortorder); @@ -438,23 +439,23 @@ if ($resql) print '
'; - if ($family == 'create') print $langs->trans("AutomaticCreation"); - elseif ($family == 'classify') print $langs->trans("AutomaticClassification"); - else print $langs->trans("Description"); + if ($family == 'create') + { + print $langs->trans("AutomaticCreation"); + } + elseif (preg_match('/classify_(.*)/', $family, $reg)) + { + print $langs->trans("AutomaticClassification"); + if ($reg[1] == 'proposal') print ' - '.$langs->trans('Proposal'); + if ($reg[1] == 'order') print ' - '.$langs->trans('Order'); + if ($reg[1] == 'supplier_proposal') print ' - '.$langs->trans('SupplierProposal'); + if ($reg[1] == 'supplier_order') print ' - '.$langs->trans('SupplierOrder'); + } + else + { + print $langs->trans("Description"); + } print ''.$langs->trans("Status").'
'."\n"; print ''; - if (! empty($arrayfields['a.id']['checked'])) print ''; - print ''; - if (! empty($arrayfields['c.libelle']['checked'])) print ''; + if (! empty($arrayfields['a.id']['checked'])) print ''; + if (! empty($arrayfields['owner']['checked'])) print ''; + if (! empty($arrayfields['c.libelle']['checked'])) print ''; if (! empty($arrayfields['a.label']['checked'])) print ''; if (! empty($arrayfields['a.datep']['checked'])) { print ''; } - if (! empty($arrayfields['a.datep2']['checked'])) { + if (! empty($arrayfields['a.datep2']['checked'])) { print ''; } - if (! empty($arrayfields['s.nom']['checked'])) print ''; + if (! empty($arrayfields['s.nom']['checked'])) print ''; if (! empty($arrayfields['a.fk_contact']['checked'])) print ''; - if (! empty($arrayfields['a.fk_element']['checked']) && ! empty($conf->global->AGENDA_SHOW_LINKED_OBJECT)) print ''; + if (! empty($arrayfields['a.fk_element']['checked'])) print ''; // Extra fields if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) { @@ -502,17 +503,17 @@ if ($resql) print "\n"; print ''; - if (! empty($arrayfields['a.id']['checked'])) print_liste_field_titre("Ref",$_SERVER["PHP_SELF"],"a.id",$param,"","",$sortfield,$sortorder); - print_liste_field_titre("ActionsOwnedByShort",$_SERVER["PHP_SELF"],"",$param,"","",$sortfield,$sortorder); - if (! empty($arrayfields['c.libelle']['checked'])) print_liste_field_titre("Type",$_SERVER["PHP_SELF"],"c.libelle",$param,"","",$sortfield,$sortorder); - if (! empty($arrayfields['a.label']['checked'])) print_liste_field_titre("Label",$_SERVER["PHP_SELF"],"a.label",$param,"","",$sortfield,$sortorder); + if (! empty($arrayfields['a.id']['checked'])) print_liste_field_titre($arrayfields['a.id']['label'] , $_SERVER["PHP_SELF"],"a.id",$param,"","",$sortfield,$sortorder); + if (! empty($arrayfields['owner']['checked'])) print_liste_field_titre($arrayfields['owner']['label'] , $_SERVER["PHP_SELF"],"",$param,"","",$sortfield,$sortorder); + if (! empty($arrayfields['c.libelle']['checked'])) print_liste_field_titre($arrayfields['c.libelle']['label'] , $_SERVER["PHP_SELF"],"c.libelle",$param,"","",$sortfield,$sortorder); + if (! empty($arrayfields['a.label']['checked'])) print_liste_field_titre($arrayfields['a.label']['label'] , $_SERVER["PHP_SELF"],"a.label",$param,"","",$sortfield,$sortorder); //if (! empty($conf->global->AGENDA_USE_EVENT_TYPE)) - if (! empty($arrayfields['a.datep']['checked'])) print_liste_field_titre("DateStart",$_SERVER["PHP_SELF"],"a.datep",$param,'','align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['a.datep2']['checked'])) print_liste_field_titre("DateEnd",$_SERVER["PHP_SELF"],"a.datep2",$param,'','align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['s.nom']['checked'])) print_liste_field_titre("ThirdParty",$_SERVER["PHP_SELF"],"s.nom",$param,"","",$sortfield,$sortorder); - if (! empty($arrayfields['a.fk_contact']['checked'])) print_liste_field_titre("Contact",$_SERVER["PHP_SELF"],"a.fk_contact",$param,"","",$sortfield,$sortorder); - if (! empty($arrayfields['a.fk_element']['checked']) && ! empty($conf->global->AGENDA_SHOW_LINKED_OBJECT)) print_liste_field_titre("LinkedObject",$_SERVER["PHP_SELF"],"a.fk_element",$param,"","",$sortfield,$sortorder); - + if (! empty($arrayfields['a.datep']['checked'])) print_liste_field_titre($arrayfields['a.datep']['label'] , $_SERVER["PHP_SELF"],"a.datep",$param,'','align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['a.datep2']['checked'])) print_liste_field_titre($arrayfields['a.datep2']['label'] , $_SERVER["PHP_SELF"],"a.datep2",$param,'','align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['s.nom']['checked'])) print_liste_field_titre($arrayfields['s.nom']['label'] , $_SERVER["PHP_SELF"],"s.nom",$param,"","",$sortfield,$sortorder); + if (! empty($arrayfields['a.fk_contact']['checked'])) print_liste_field_titre($arrayfields['a.fk_contact']['label'], $_SERVER["PHP_SELF"],"a.fk_contact",$param,"","",$sortfield,$sortorder); + if (! empty($arrayfields['a.fk_element']['checked'])) print_liste_field_titre($arrayfields['a.fk_element']['label'], $_SERVER["PHP_SELF"],"a.fk_element",$param,"","",$sortfield,$sortorder); + // Extra fields if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) { @@ -572,14 +573,17 @@ if ($resql) } // User owner - print ''; } - else print ' '; - print ''; if (! empty($arrayfields['c.libelle']['checked'])) { // Type print ''; } - + if (! empty($arrayfields['a.datep']['checked'])) { // Start date print ''; } - if (! empty($arrayfields['a.fk_element']['checked']) && ! empty($conf->global->AGENDA_SHOW_LINKED_OBJECT)) { + if (! empty($arrayfields['a.fk_element']['checked'])) { // Linked object print ''; - + } // Extra fields if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) diff --git a/htdocs/core/class/html.formactions.class.php b/htdocs/core/class/html.formactions.class.php index 7db6ec3331a..3fcf4a15bdd 100644 --- a/htdocs/core/class/html.formactions.class.php +++ b/htdocs/core/class/html.formactions.class.php @@ -205,12 +205,12 @@ class FormActions print '
'; print '
'; print $form->select_date($datestart, 'datestart', 0, 0, 1, '', 1, 0, 1); print ''; print $form->select_date($dateend, 'dateend', 0, 0, 1, '', 1, 0, 1); print '
'; - if ($obj->fk_user_action > 0) + if (! empty($arrayfields['owner']['checked'])) { - $userstatic->fetch($obj->fk_user_action); - print $userstatic->getNomUrl(-1); + print ''; + if ($obj->fk_user_action > 0) + { + $userstatic->fetch($obj->fk_user_action); + print $userstatic->getNomUrl(-1); + } + else print ' '; + print ''; @@ -605,7 +609,7 @@ if ($resql) print $actionstatic->label; print ''; @@ -653,7 +657,7 @@ if ($resql) } print ''; if ($obj->fk_element > 0 && ! empty($obj->elementtype)) { @@ -663,7 +667,7 @@ if ($resql) print " "; } print '
'; print ''; - print getTitleFieldOfList('Ref', 0, $_SERVER["PHP_SELF"], '', $page, $param, '', $sortfield, $sortorder, '', 1); - print getTitleFieldOfList('By', 0, $_SERVER["PHP_SELF"], '', $page, $param, '', $sortfield, $sortorder, '', 1); - print getTitleFieldOfList('Type', 0, $_SERVER["PHP_SELF"], '', $page, $param, '', $sortfield, $sortorder, '', 1); - print getTitleFieldOfList('Action', 0, $_SERVER["PHP_SELF"], '', $page, $param, '', $sortfield, $sortorder, '', 1); - print getTitleFieldOfList('Date', 0, $_SERVER["PHP_SELF"], 'a.datep', $page, $param, 'align="center"', $sortfield, $sortorder, '', 1); - print getTitleFieldOfList('', 0, $_SERVER["PHP_SELF"], '', $page, $param, 'align="right"', $sortfield, $sortorder, '', 1); + print getTitleFieldOfList('Ref', 0, $_SERVER["PHP_SELF"], '', $page, $param, '', $sortfield, $sortorder, '', 1); + print getTitleFieldOfList('By', 0, $_SERVER["PHP_SELF"], '', $page, $param, '', $sortfield, $sortorder, '', 1); + print getTitleFieldOfList('Type', 0, $_SERVER["PHP_SELF"], '', $page, $param, '', $sortfield, $sortorder, '', 1); + print getTitleFieldOfList('Title', 0, $_SERVER["PHP_SELF"], '', $page, $param, '', $sortfield, $sortorder, '', 1); + print getTitleFieldOfList('Date', 0, $_SERVER["PHP_SELF"], 'a.datep', $page, $param, 'align="center"', $sortfield, $sortorder, '', 1); + print getTitleFieldOfList('', 0, $_SERVER["PHP_SELF"], '', $page, $param, 'align="right"', $sortfield, $sortorder, '', 1); print ''; print "\n"; From 0553e331fe80813d0673a738a857b450b8e1b5c9 Mon Sep 17 00:00:00 2001 From: BENKE Charlene Date: Tue, 14 Nov 2017 08:48:41 +0100 Subject: [PATCH 080/131] Update card.php Normalize link and generate document --- htdocs/expensereport/card.php | 42 ++++++++++++++--------------------- 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php index dc2c0a22f66..3db8e30f9f4 100644 --- a/htdocs/expensereport/card.php +++ b/htdocs/expensereport/card.php @@ -2391,47 +2391,39 @@ if (GETPOST('modelselected')) { if ($action != 'presend') { - print '
'; /* * Generate documents */ - if($user->rights->expensereport->export && $action != 'create' && $action != 'edit') + print '
'; + print ''; // ancre + + if($user->rights->expensereport->creer && $action != 'create' && $action != 'edit') { $filename = dol_sanitizeFileName($object->ref); $filedir = $conf->expensereport->dir_output . "/" . dol_sanitizeFileName($object->ref); $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id; - $genallowed = $user->rights->expensereport->export; - $delallowed = $user->rights->expensereport->export; + $genallowed = $user->rights->expensereport->creer; + $delallowed = $user->rights->expensereport->creer; $var = true; - print $formfile->showdocuments('expensereport',$filename,$filedir,$urlsource,$genallowed,$delallowed); + print $formfile->showdocuments('expensereport', $filename, $filedir, $urlsource, $genallowed, $delallowed); $somethingshown = $formfile->numoffiles; } - print '
'; - if ($action != 'create' && $action != 'edit' && ($id || $ref)) { - $permissiondellink=$user->rights->facture->creer; // Used by the include of actions_dellink.inc.php - include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; // Must be include, not include_once - - // Link invoice to intervention - if (GETPOST('LinkedFichinter')) { - $object->fetch($id); - $object->fetch_thirdparty(); - $result = $object->add_object_linked('fichinter', GETPOST('LinkedFichinter')); - } - - // Show links to link elements - $linktoelements=array(); - if (! empty($conf->global->EXPENSES_LINK_TO_INTERVENTION)) - { - $linktoelements[]='fichinter'; - $linktoelem = $form->showLinkToObjectBlock($object, $linktoelements, array('expensereport')); - $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem); - } + $linktoelem = $form->showLinkToObjectBlock($object, null, array('expensereport')); + $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem); } + print '
'; + // List of actions on element + include_once DOL_DOCUMENT_ROOT . '/core/class/html.formactions.class.php'; + $formactions = new FormActions($db); + $somethingshown = $formactions->showactions($object, 'expensereport', null); + + print '
'; + } // Presend form From e195cf0b9566dc4fa2050cfad2f8651c230b6274 Mon Sep 17 00:00:00 2001 From: florian HENRY Date: Tue, 14 Nov 2017 09:53:06 +0100 Subject: [PATCH 081/131] fix : return vat code for supplier price --- htdocs/core/lib/functions.lib.php | 1 + htdocs/product/class/product.class.php | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 51eb070da91..b58d24ba028 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -4306,6 +4306,7 @@ function get_product_vat_for_country($idprod, $thirdparty_seller, $idprodfournpr { $product->get_buyprice($idprodfournprice,0,0,0); $ret=$product->vatrate_supplier; + if ($product->default_vat_code) $ret.=' ('.$product->default_vat_code.')'; } else { diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 05adfc1b5c5..b0985f6f2e8 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -1505,6 +1505,7 @@ class Product extends CommonObject // We do a first seach with a select by searching with couple prodfournprice and qty only (later we will search on triplet qty/product_id/fourn_ref) $sql = "SELECT pfp.rowid, pfp.price as price, pfp.quantity as quantity, pfp.remise_percent,"; $sql.= " pfp.fk_product, pfp.ref_fourn, pfp.fk_soc, pfp.tva_tx, pfp.fk_supplier_price_expression"; + $sql.= " ,pfp.default_vat_code"; $sql.= " FROM ".MAIN_DB_PREFIX."product_fournisseur_price as pfp"; $sql.= " WHERE pfp.rowid = ".$prodfournprice; if ($qty > 0) $sql.= " AND pfp.quantity <= ".$qty; @@ -1540,6 +1541,7 @@ class Product extends CommonObject $this->ref_supplier = $obj->ref_fourn; // Ref supplier $this->remise_percent = $obj->remise_percent; // remise percent if present and not typed $this->vatrate_supplier = $obj->tva_tx; // Vat ref supplier + $this->default_vat_code = $obj->default_vat_code; // Vat code supplier $result=$obj->fk_product; return $result; } @@ -1548,6 +1550,7 @@ class Product extends CommonObject // We do a second search by doing a select again but searching with less reliable criteria: couple qty/id product, and if set fourn_ref or fk_soc. $sql = "SELECT pfp.rowid, pfp.price as price, pfp.quantity as quantity, pfp.fk_soc,"; $sql.= " pfp.fk_product, pfp.ref_fourn as ref_supplier, pfp.tva_tx, pfp.fk_supplier_price_expression"; + $sql.= " ,pfp.default_vat_code"; $sql.= " FROM ".MAIN_DB_PREFIX."product_fournisseur_price as pfp"; $sql.= " WHERE pfp.fk_product = ".$product_id; if ($fourn_ref != 'none') $sql.= " AND pfp.ref_fourn = '".$fourn_ref."'"; @@ -1587,6 +1590,7 @@ class Product extends CommonObject $this->ref_supplier = $obj->ref_supplier; // Ref supplier $this->remise_percent = $obj->remise_percent; // remise percent if present and not typed $this->vatrate_supplier = $obj->tva_tx; // Vat ref supplier + $this->default_vat_code = $obj->default_vat_code; // Vat code supplier $result=$obj->fk_product; return $result; } From 7a76a3f497ad59d022207b39eaff6b81aa3f0716 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Tue, 14 Nov 2017 10:20:43 +0100 Subject: [PATCH 082/131] fix trigger when module not enabled --- .../interface_99_modMyModule_MyModuleTriggers.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/modulebuilder/template/core/triggers/interface_99_modMyModule_MyModuleTriggers.class.php b/htdocs/modulebuilder/template/core/triggers/interface_99_modMyModule_MyModuleTriggers.class.php index 3ea9ed8a090..62b35bfdf39 100644 --- a/htdocs/modulebuilder/template/core/triggers/interface_99_modMyModule_MyModuleTriggers.class.php +++ b/htdocs/modulebuilder/template/core/triggers/interface_99_modMyModule_MyModuleTriggers.class.php @@ -97,7 +97,7 @@ class InterfaceMyModuleTriggers extends DolibarrTriggers */ public function runTrigger($action, $object, User $user, Translate $langs, Conf $conf) { - if (!empty($conf->mymodule->enabled)) return 0; // Module not active, we do nothing + if (empty($conf->mymodule->enabled)) return 0; // Module not active, we do nothing // Put here code you want to execute when a Dolibarr business events occurs. // Data and type of action are stored into $object and $action From 96031b0787c915f726f0e85fe74a0f351b7fff00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Tue, 14 Nov 2017 11:05:58 +0100 Subject: [PATCH 083/131] Update listactions.php --- htdocs/comm/action/listactions.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/htdocs/comm/action/listactions.php b/htdocs/comm/action/listactions.php index 8faeb365cb6..9bfd3600df3 100644 --- a/htdocs/comm/action/listactions.php +++ b/htdocs/comm/action/listactions.php @@ -503,14 +503,14 @@ if ($resql) print "\n"; print '
'; - if (! empty($arrayfields['a.id']['checked'])) print_liste_field_titre($arrayfields['a.id']['label'] , $_SERVER["PHP_SELF"],"a.id",$param,"","",$sortfield,$sortorder); - if (! empty($arrayfields['owner']['checked'])) print_liste_field_titre($arrayfields['owner']['label'] , $_SERVER["PHP_SELF"],"",$param,"","",$sortfield,$sortorder); - if (! empty($arrayfields['c.libelle']['checked'])) print_liste_field_titre($arrayfields['c.libelle']['label'] , $_SERVER["PHP_SELF"],"c.libelle",$param,"","",$sortfield,$sortorder); - if (! empty($arrayfields['a.label']['checked'])) print_liste_field_titre($arrayfields['a.label']['label'] , $_SERVER["PHP_SELF"],"a.label",$param,"","",$sortfield,$sortorder); + if (! empty($arrayfields['a.id']['checked'])) print_liste_field_titre($arrayfields['a.id']['label'], $_SERVER["PHP_SELF"],"a.id",$param,"","",$sortfield,$sortorder); + if (! empty($arrayfields['owner']['checked'])) print_liste_field_titre($arrayfields['owner']['label'], $_SERVER["PHP_SELF"],"",$param,"","",$sortfield,$sortorder); + if (! empty($arrayfields['c.libelle']['checked'])) print_liste_field_titre($arrayfields['c.libelle']['label'], $_SERVER["PHP_SELF"],"c.libelle",$param,"","",$sortfield,$sortorder); + if (! empty($arrayfields['a.label']['checked'])) print_liste_field_titre($arrayfields['a.label']['label'], $_SERVER["PHP_SELF"],"a.label",$param,"","",$sortfield,$sortorder); //if (! empty($conf->global->AGENDA_USE_EVENT_TYPE)) - if (! empty($arrayfields['a.datep']['checked'])) print_liste_field_titre($arrayfields['a.datep']['label'] , $_SERVER["PHP_SELF"],"a.datep",$param,'','align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['a.datep2']['checked'])) print_liste_field_titre($arrayfields['a.datep2']['label'] , $_SERVER["PHP_SELF"],"a.datep2",$param,'','align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['s.nom']['checked'])) print_liste_field_titre($arrayfields['s.nom']['label'] , $_SERVER["PHP_SELF"],"s.nom",$param,"","",$sortfield,$sortorder); + if (! empty($arrayfields['a.datep']['checked'])) print_liste_field_titre($arrayfields['a.datep']['label'], $_SERVER["PHP_SELF"],"a.datep",$param,'','align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['a.datep2']['checked'])) print_liste_field_titre($arrayfields['a.datep2']['label'], $_SERVER["PHP_SELF"],"a.datep2",$param,'','align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['s.nom']['checked'])) print_liste_field_titre($arrayfields['s.nom']['label'], $_SERVER["PHP_SELF"],"s.nom",$param,"","",$sortfield,$sortorder); if (! empty($arrayfields['a.fk_contact']['checked'])) print_liste_field_titre($arrayfields['a.fk_contact']['label'], $_SERVER["PHP_SELF"],"a.fk_contact",$param,"","",$sortfield,$sortorder); if (! empty($arrayfields['a.fk_element']['checked'])) print_liste_field_titre($arrayfields['a.fk_element']['label'], $_SERVER["PHP_SELF"],"a.fk_element",$param,"","",$sortfield,$sortorder); From fa92c53ff6546f491390b4b6e0a72a94104dbc42 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 14 Nov 2017 11:13:24 +0100 Subject: [PATCH 084/131] Fix pb when showing dictionaries --- htdocs/admin/dict.php | 17 ++++++++++++++--- htdocs/comm/action/index.php | 2 +- htdocs/langs/en_US/admin.lang | 6 +++--- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index f8ac87fcb3e..eb1efd3211b 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -80,7 +80,10 @@ $pageprev = $page - 1; $pagenext = $page + 1; $search_country_id = GETPOST('search_country_id','int'); -if($search_country_id == '') $search_country_id = $mysoc->country_id; +if ($search_country_id == '' && ($id == 2 || $id == 3 || $id == 10)) // Not a so good idea to force on current country for all dictionaries. Some tables have entries that are for all countries, we must be able to see them, so this is done for dedicated dictionaries only. +{ + $search_country_id = $mysoc->country_id; +} $search_code = GETPOST('search_code','alpha'); // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context @@ -90,7 +93,7 @@ $hookmanager->initHooks(array('admin')); // Put here declaration of dictionaries properties // Sort order to show dictionary (0 is space). All other dictionaries (added by modules) will be at end of this. -$taborder=array(9,0,4,3,2,0,1,8,19,16,27,0,5,11,0,33,34,0,6,0,29,0,7,17,35,36,24,28,0,10,23,12,13,0,14,0,22,20,18,21,0,15,30,0,26,0,); +$taborder=array(9,0,4,3,2,0,1,8,19,16,27,0,5,11,0,33,34,0,6,0,29,0,7,24,28,17,35,36,0,10,23,12,13,0,14,0,22,20,18,21,0,15,30,0,26,0,); // Name of SQL tables of dictionaries $tabname=array(); @@ -282,6 +285,8 @@ $tabfield[29]= "code,label,percent,position"; $tabfield[30]= "code,name,paper_size,orientation,metric,leftmargin,topmargin,nx,ny,spacex,spacey,width,height,font_size,custom_x,custom_y"; //$tabfield[31]= "pcg_version,label"; //$tabfield[32]= "code,label,range_account,sens,category_type,formula,position,country_id,country"; +$tabfield[33]= "code,label"; +$tabfield[34]= "code,label"; $tabfield[35]= "label"; $tabfield[36]= "range_ik,fk_c_exp_tax_cat"; @@ -1010,6 +1015,11 @@ if ($id) $sql.=$db->plimit($listlimit+1,$offset); //print $sql; + if (empty($tabfield[$id])) + { + dol_print_error($db, 'The table with id '.$id.' has no array tabfield defined'); + exit; + } $fieldlist=explode(',',$tabfield[$id]); print ''; @@ -1393,6 +1403,7 @@ if ($id) foreach ($fieldlist as $field => $value) { + //var_dump($fieldlist); $showfield=1; $align="left"; $valuetoshow=$obj->{$fieldlist[$field]}; @@ -1750,7 +1761,7 @@ $db->close(); * @param Object $obj If we show a particular record, obj is filled with record fields * @param string $tabname Name of SQL table * @param string $context 'add'=Output field for the "add form", 'edit'=Output field for the "edit form", 'hide'=Output field for the "add form" but we dont want it to be rendered - * @return string '' or value of entity into table + * @return string '' or value of entity into table */ function fieldList($fieldlist, $obj='', $tabname='', $context='') { diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php index 431ac1b5569..6d7f9ae5b33 100644 --- a/htdocs/comm/action/index.php +++ b/htdocs/comm/action/index.php @@ -1375,7 +1375,7 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa print '>'; print '
Date: Tue, 14 Nov 2017 12:18:02 +0100 Subject: [PATCH 085/131] CSS --- htdocs/comm/action/index.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php index 6d7f9ae5b33..4cbb0d929fc 100644 --- a/htdocs/comm/action/index.php +++ b/htdocs/comm/action/index.php @@ -392,7 +392,7 @@ if (! empty($conf->use_javascript_ajax)) // If javascript on $s.='' . "\n"; // Local calendar - $s.='
' . $langs->trans("LocalAgenda").'  
'; + $s.='
' . $langs->trans("LocalAgenda").'  
'; // External calendars if (is_array($showextcals) && count($showextcals) > 0) @@ -409,12 +409,12 @@ if (! empty($conf->use_javascript_ajax)) // If javascript on foreach ($showextcals as $val) { $htmlname = md5($val['name']); - $s.='
' . $val['name'] . '  
'; + $s.='
' . $val['name'] . '  
'; } } // Birthdays - $s.='
'.$langs->trans("AgendaShowBirthdayEvents").'  
'; + $s.='
'.$langs->trans("AgendaShowBirthdayEvents").'  
'; // Calendars from hooks $parameters=array(); $object=null; From 4dca97401d862ffb0e73e909eec6fa301c4c81e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Tue, 14 Nov 2017 13:18:31 +0100 Subject: [PATCH 086/131] Update llx_actioncomm.sql --- htdocs/install/mysql/tables/llx_actioncomm.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/install/mysql/tables/llx_actioncomm.sql b/htdocs/install/mysql/tables/llx_actioncomm.sql index 8203b027567..72321e19db5 100644 --- a/htdocs/install/mysql/tables/llx_actioncomm.sql +++ b/htdocs/install/mysql/tables/llx_actioncomm.sql @@ -64,7 +64,7 @@ create table llx_actioncomm email_tobcc varchar(255), -- when event was an email, we store here the email_tobcc errors_to varchar(255), -- when event was an email, we store here the erros_to - recurid varchar(128), -- used to store event id to link each other all the repeating event record. It can be the "iCalUID" as in RFC5545 (an id similar for all the same serie) + recurid varchar(128), -- used to store event id to link each other all the repeating event record. It can be the 'iCalUID' as in RFC5545 (an id similar for all the same serie) recurrule varchar(128), -- contains string with ical format recurring rule like 'FREQ=MONTHLY;INTERVAL=2;BYMONTHDAY=19' or 'FREQ=WEEKLY;BYDAY=MO' recurdateend datetime, -- no more recurring event after this date From a50589c3c9e72e6423366108f07f41698ab7552f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 14 Nov 2017 15:10:46 +0100 Subject: [PATCH 087/131] NEW Better behaviour when using a text browser --- htdocs/core/class/html.formother.class.php | 6 +++++- htdocs/core/menus/standard/auguria.lib.php | 2 +- htdocs/core/menus/standard/eldy.lib.php | 2 +- htdocs/core/search_page.php | 11 +++++------ htdocs/main.inc.php | 16 ++++++++++++---- 5 files changed, 24 insertions(+), 13 deletions(-) diff --git a/htdocs/core/class/html.formother.class.php b/htdocs/core/class/html.formother.class.php index 432a7bb37de..565cd4310b4 100644 --- a/htdocs/core/class/html.formother.class.php +++ b/htdocs/core/class/html.formother.class.php @@ -1023,7 +1023,11 @@ class FormOther $selectboxlist.=Form::selectarray('boxcombo', $arrayboxtoactivatelabel, -1, $langs->trans("ChooseBoxToAdd").'...', 0, 0, '', 0, 0, 0, 'ASC', 'maxwidth150onsmartphone', 0, 'hidden selected', 0, 1); if (empty($conf->use_javascript_ajax)) $selectboxlist.=' '; $selectboxlist.=''; - $selectboxlist.=ajax_combobox("boxcombo"); + if (! empty($conf->use_javascript_ajax)) + { + include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; + $selectboxlist.=ajax_combobox("boxcombo"); + } } // Javascript code for dynamic actions diff --git a/htdocs/core/menus/standard/auguria.lib.php b/htdocs/core/menus/standard/auguria.lib.php index ebd64b36a3c..90089488389 100644 --- a/htdocs/core/menus/standard/auguria.lib.php +++ b/htdocs/core/menus/standard/auguria.lib.php @@ -298,7 +298,7 @@ function print_left_auguria_menu($db,$menu_array_before,$menu_array_after,&$tabM print ''."\n"; } - if (is_array($moredata) && ! empty($moredata['searchform'])) + if (is_array($moredata) && ! empty($moredata['searchform'])) // searchform can contains select2 code or link to show old search form or link to switch on search page { print "\n"; print "\n"; diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 9e88767f473..1f8529257d2 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -484,7 +484,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu print ''."\n"; } - if (is_array($moredata) && ! empty($moredata['searchform']) && empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) + if (is_array($moredata) && ! empty($moredata['searchform'])) // searchform can contains select2 code or link to show old search form or link to switch on search page { print "\n"; print "\n"; diff --git a/htdocs/core/search_page.php b/htdocs/core/search_page.php index eb873d0e8f9..83ef016d3a9 100644 --- a/htdocs/core/search_page.php +++ b/htdocs/core/search_page.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2005-2017 Laurent Destailleur * * This file is a modified version of datepicker.php from phpBSM to fix some * bugs, to add new features and to dramatically increase speed. @@ -20,7 +20,7 @@ /** * \file htdocs/core/search_page.php - * \brief File to return search box + * \brief File to return a page with search boxes */ //if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER','1'); // Not disabled cause need to load personalized language @@ -78,7 +78,8 @@ if ($conf->use_javascript_ajax && 1 == 2) // select2 is ko with jmobile else { $usedbyinclude = 1; // Used into next include - include DOL_DOCUMENT_ROOT.'/core/ajax/selectsearchbox.php'; + $showtitlebefore = GETPOST('showtitlebefore','int'); + include DOL_DOCUMENT_ROOT.'/core/ajax/selectsearchbox.php'; $accesskeyalreadyassigned=array(); foreach($arrayresult as $key => $val) @@ -94,7 +95,7 @@ else $accesskey=$val['label'][0]; $accesskeyalreadyassigned[$accesskey]=$accesskey; } - $searchform.=printSearchForm($urlaction, $urlaction, $val['label'], 'minwidth200', $keysearch, $accesskey, $key, img_picto('',$val['img'],'', 0, 1)); + $searchform.=printSearchForm($urlaction, $urlaction, $val['label'], 'minwidth200', $keysearch, $accesskey, $key, img_picto('',$val['img'],'', 0, 1), $showtitlebefore); } } @@ -112,11 +113,9 @@ print "\n"; print "\n"; print '
'; print ''; -//print '
'; print '
'."\n"; print $searchform; print '
'."\n"; -//print '
'; print '
'; print "\n\n"; diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 1d049e670c9..a4654713208 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -1589,9 +1589,9 @@ function left_menu($menu_array_before, $helppagename='', $notused='', $menu_arra print "\n".''."\n".'
'."\n"; - print "\n"; + if ($conf->browser->layout == 'phone') $conf->global->MAIN_USE_OLD_SEARCH_FORM=1; // Select into select2 is awfull on smartphone. TODO Is this still true with select2 v4 ? - if ($conf->browser->layout == 'phone') $conf->global->MAIN_USE_OLD_SEARCH_FORM=1; // Select into select2 is awfull on smartphone + print "\n"; if ($conf->use_javascript_ajax && empty($conf->global->MAIN_USE_OLD_SEARCH_FORM)) { if (! is_object($form)) $form=new Form($db); @@ -1621,7 +1621,13 @@ function left_menu($menu_array_before, $helppagename='', $notused='', $menu_arra } else $searchform=$hookmanager->resPrint; - if ($conf->use_javascript_ajax && ! empty($conf->global->MAIN_USE_OLD_SEARCH_FORM)) + // Force special value for $searchform + if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) + { + $urltosearch=DOL_URL_ROOT.'/core/search_page.php?showtitlebefore=1'; + $searchform='
'; + } + elseif ($conf->use_javascript_ajax && ! empty($conf->global->MAIN_USE_OLD_SEARCH_FORM)) { $searchform='
'; $searchform.=''."\n"; llxHeader($moreheadcss.$moreheadjs, $langs->trans("websiteetup"), $help_url, '', 0, 0, $arrayofjs, $arrayofcss, '', '', ''."\n".'
'); -print "\n".'
'; +print "\n".''; + print ''; if ($action == 'createsite') { @@ -1156,6 +1157,7 @@ if ($action == 'edit') print ''; } +print '
'; // Add a margin under toolbar ? $style=''; @@ -1170,12 +1172,12 @@ if (count($object->records) > 0) { // ***** Part for web sites - print '
'; - print ''; + print '
'; + print $langs->trans("Website").' : '; print '
'; print '
'; - print $langs->trans("WebSite").': '; + print ' '; print '
'; // List of website @@ -1199,7 +1201,9 @@ if (count($object->records) > 0) $out.=''; $out.=ajax_combobox('website'); print $out; - print ''; + //print ''; + print ''; + if ($website) { @@ -1215,14 +1219,14 @@ if (count($object->records) > 0) print '   '; - print ''; + print ''; //print ''; - print ''; - print ''; + print ''; + print ''; print '   '; - print ''; + print ''; /*print ''.dol_escape_htmltag($langs->trans("MediaFiles")).''; print ''; +if ($conf->use_javascript_ajax) +{ + print "\n\n"; + print ''; +} llxFooter(); diff --git a/htdocs/projet/activity/perweek.php b/htdocs/projet/activity/perweek.php index b7fc2b32376..08b59ffafbc 100644 --- a/htdocs/projet/activity/perweek.php +++ b/htdocs/projet/activity/perweek.php @@ -286,7 +286,9 @@ if ($action == 'addtime' && $user->rights->projet->lire) $param=''; $param.=($mode?'&mode='.$mode:''); - $param.=($projectid?'id='.$projectid:'').($search_usertoprocessid?'&search_usertoprocessid='.$search_usertoprocessid:'').($day?'&day='.$day:'').($month?'&month='.$month:'').($year?'&year='.$year:''); + $param.=($projectid?'id='.$projectid:''); + $param.=($search_usertoprocessid?'&search_usertoprocessid='.$search_usertoprocessid:''); + $param.=($day?'&day='.$day:'').($month?'&month='.$month:'').($year?'&year='.$year:''); $param.=($search_project_ref?'&search_project_ref='.$search_project_ref:''); $param.=($search_usertoprocessid > 0?'&search_usertoprocessid='.$search_usertoprocessid:''); $param.=($search_thirdparty?'&search_thirdparty='.$search_thirdparty:''); @@ -333,6 +335,10 @@ if ($search_task_label) $morewherefilter.=natural_search(array("t.ref", "t.label if ($search_thirdparty) $morewherefilter.=natural_search("s.nom", $search_thirdparty); $tasksarray=$taskstatic->getTasksArray(0, 0, ($project->id?$project->id:0), $socid, 0, $search_project_ref, $onlyopenedproject, $morewherefilter, ($search_usertoprocessid?$search_usertoprocessid:0)); // We want to see all task of opened project i am allowed to see and that match filter, not only my tasks. Later only mine will be editable later. +if ($morewherefilter) // Get all task with no filter so we can show total of time spent for not visible tasks +{ + $tasksarraywithoutfilter=$taskstatic->getTasksArray(0, 0, ($project->id?$project->id:0), $socid, 0, '', $onlyopenedproject, '', ($search_usertoprocessid?$search_usertoprocessid:0)); // We want to see all task of opened project i am allowed to see and that match filter, not only my tasks. Later only mine will be editable later. +} $projectsrole=$taskstatic->getUserRolesForProjectsOrTasks($usertoprocess, 0, ($project->id?$project->id:0), 0, $onlyopenedproject); $tasksrole=$taskstatic->getUserRolesForProjectsOrTasks(0, $usertoprocess, ($project->id?$project->id:0), 0, $onlyopenedproject); //var_dump($tasksarray); @@ -478,7 +484,7 @@ print '
'; else print '';*/ print ''; -print ''; +print ''; $startday=dol_mktime(12, 0, 0, $startdayarray['first_month'], $startdayarray['first_day'], $startdayarray['first_year']); @@ -515,11 +521,65 @@ if (count($tasksarray) > 0) $j=0; $level=0; - projectLinesPerWeek($j, $firstdaytoshow, $usertoprocess, 0, $tasksarray, $level, $projectsrole, $tasksrole, $mine, $restrictviewformytask, $isavailable); + $totalforvisibletasks = projectLinesPerWeek($j, $firstdaytoshow, $usertoprocess, 0, $tasksarray, $level, $projectsrole, $tasksrole, $mine, $restrictviewformytask, $isavailable, 0); + //var_dump($totalforvisibletasks); + + // Show total for all other tasks + + // Calculate total for all tasks + $listofdistinctprojectid=array(); // List of all distinct projects + if (is_array($tasksarraywithoutfilter) && count($tasksarraywithoutfilter)) + { + foreach($tasksarraywithoutfilter as $tmptask) + { + $listofdistinctprojectid[$tmptask->fk_project]=$tmptask->fk_project; + } + } + //var_dump($listofdistinctprojectid); + $totalforeachday=array(); + foreach($listofdistinctprojectid as $tmpprojectid) + { + $lineother=''; + $projectstatic->id=$tmpprojectid; + $projectstatic->loadTimeSpent($firstdaytoshow, 0, $usertoprocess->id); // Load time spent from table projet_task_time for the project into this->weekWorkLoad and this->weekWorkLoadPerTask for all days of a week + for ($idw = 0; $idw < 7; $idw++) + { + $tmpday=dol_time_plus_duree($firstdaytoshow, $idw, 'd'); + $totalforeachday[$tmpday]+=$projectstatic->weekWorkLoad[$tmpday]; + } + } + $lineother=''; + //var_dump($totalforeachday); $colspan=7; - print ' + // There is a diff between total shown on screen and total spent by user, so we add a line with all other cumulated time of user + if (count($totalforeachday)) + { + print ''; + print ''; + for ($idw = 0; $idw < 7; $idw++) + { + print ''; + } + print ' '; + print ''; + } + + if ($conf->use_javascript_ajax) + { + print ' - '; + '; + } } else { @@ -551,25 +612,29 @@ print ''."\n\n"; $modeinput='hours'; -print "\n\n"; -print ''; } -print "\n});\n"; -print ''; llxFooter(); diff --git a/htdocs/projet/class/project.class.php b/htdocs/projet/class/project.class.php index 74b274d5f3a..da754176386 100644 --- a/htdocs/projet/class/project.class.php +++ b/htdocs/projet/class/project.class.php @@ -1652,7 +1652,8 @@ class Project extends CommonObject /** - * Load time spent into this->weekWorkLoad and this->weekWorkLoadPerTask for all day of a week of project + * Load time spent into this->weekWorkLoad and this->weekWorkLoadPerTask for all day of a week of project. + * Note: array weekWorkLoad and weekWorkLoadPerTask are reset and filled at each call. * * @param int $datestart First day of week (use dol_get_first_day to find this date) * @param int $taskid Filter on a task id @@ -1663,9 +1664,12 @@ class Project extends CommonObject { $error=0; + $this->weekWorkLoad=array(); + $this->weekWorkLoadPerTask=array(); + if (empty($datestart)) dol_print_error('','Error datestart parameter is empty'); - $sql = "SELECT ptt.rowid as taskid, ptt.task_duration, ptt.task_date, ptt.fk_task"; + $sql = "SELECT ptt.rowid as taskid, ptt.task_duration, ptt.task_date, ptt.task_datehour, ptt.fk_task"; $sql.= " FROM ".MAIN_DB_PREFIX."projet_task_time AS ptt, ".MAIN_DB_PREFIX."projet_task as pt"; $sql.= " WHERE ptt.fk_task = pt.rowid"; $sql.= " AND pt.fk_projet = ".$this->id; @@ -1678,8 +1682,6 @@ class Project extends CommonObject $resql=$this->db->query($sql); if ($resql) { - //unset($this->weekWorkLoad[$day]); - //unset($this->weekWorkLoadPerTask[$day]); $daylareadyfound=array(); $num = $this->db->num_rows($resql); @@ -1688,7 +1690,7 @@ class Project extends CommonObject while ($i < $num) { $obj=$this->db->fetch_object($resql); - $day=$this->db->jdate($obj->task_date); + $day=$this->db->jdate($obj->task_date); // task_date is date without hours if (empty($daylareadyfound[$day])) { $this->weekWorkLoad[$day] = $obj->task_duration; From f708450276f048a0a2a56b93d2e3a114a7a35ae7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 16 Nov 2017 22:57:25 +0100 Subject: [PATCH 118/131] Fix sql error --- htdocs/install/mysql/tables/llx_actioncomm.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/install/mysql/tables/llx_actioncomm.sql b/htdocs/install/mysql/tables/llx_actioncomm.sql index 8203b027567..72321e19db5 100644 --- a/htdocs/install/mysql/tables/llx_actioncomm.sql +++ b/htdocs/install/mysql/tables/llx_actioncomm.sql @@ -64,7 +64,7 @@ create table llx_actioncomm email_tobcc varchar(255), -- when event was an email, we store here the email_tobcc errors_to varchar(255), -- when event was an email, we store here the erros_to - recurid varchar(128), -- used to store event id to link each other all the repeating event record. It can be the "iCalUID" as in RFC5545 (an id similar for all the same serie) + recurid varchar(128), -- used to store event id to link each other all the repeating event record. It can be the 'iCalUID' as in RFC5545 (an id similar for all the same serie) recurrule varchar(128), -- contains string with ical format recurring rule like 'FREQ=MONTHLY;INTERVAL=2;BYMONTHDAY=19' or 'FREQ=WEEKLY;BYDAY=MO' recurdateend datetime, -- no more recurring event after this date From ba372bfc5c6ae9d3eb10748b1785f30c41b68f3b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 16 Nov 2017 23:11:49 +0100 Subject: [PATCH 119/131] Fix typo --- htdocs/langs/en_US/projects.lang | 3 ++- htdocs/projet/tasks.php | 4 ++-- htdocs/projet/tasks/task.php | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/htdocs/langs/en_US/projects.lang b/htdocs/langs/en_US/projects.lang index dd7f15aa61b..f57174ed956 100644 --- a/htdocs/langs/en_US/projects.lang +++ b/htdocs/langs/en_US/projects.lang @@ -96,7 +96,8 @@ ActivityOnProjectYesterday=Activity on project yesterday ActivityOnProjectThisWeek=Activity on project this week ActivityOnProjectThisMonth=Activity on project this month ActivityOnProjectThisYear=Activity on project this year -ChildOfTask=Child of project/task +ChildOfProjectTask=Child of project/task +ChildOfTask=Child of task NotOwnerOfProject=Not owner of this private project AffectedTo=Allocated to CantRemoveProject=This project can't be removed as it is referenced by some other objects (invoice, orders or other). See referers tab. diff --git a/htdocs/projet/tasks.php b/htdocs/projet/tasks.php index 385b63142d4..567acbfee03 100644 --- a/htdocs/projet/tasks.php +++ b/htdocs/projet/tasks.php @@ -116,7 +116,7 @@ if ($action == 'createtask' && $user->rights->projet->creer) } else if (empty($_POST['task_parent'])) { - setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("ChildOfTask")), null, 'errors'); + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("ChildOfProjectTask")), null, 'errors'); $action='create'; $error++; } @@ -370,7 +370,7 @@ if ($action == 'create' && $user->rights->projet->creer && (empty($object->third print ''; // List of projects - print ''; diff --git a/htdocs/projet/tasks/task.php b/htdocs/projet/tasks/task.php index e539adf4f41..f416a71b432 100644 --- a/htdocs/projet/tasks/task.php +++ b/htdocs/projet/tasks/task.php @@ -194,7 +194,7 @@ if ($action == 'remove_file' && $user->rights->projet->creer) /* * View -*/ + */ llxHeader('', $langs->trans("Task")); @@ -376,7 +376,7 @@ if ($id > 0 || ! empty($ref)) } // Task parent - print ''; From 92753273b927d8ab19e72d4a1f0adabde6b914fb Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 17 Nov 2017 11:44:52 +0100 Subject: [PATCH 120/131] Fix upload api for invoices and bad id for bank account --- htdocs/api/class/api_documents.class.php | 11 ++++++++--- htdocs/compta/bank/class/api_bankaccounts.class.php | 8 ++++---- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/htdocs/api/class/api_documents.class.php b/htdocs/api/class/api_documents.class.php index 669fc09911e..7cbdd1d21f7 100644 --- a/htdocs/api/class/api_documents.class.php +++ b/htdocs/api/class/api_documents.class.php @@ -23,8 +23,6 @@ use Luracast\Restler\Format\UploadFormat; require_once DOL_DOCUMENT_ROOT.'/main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; -require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php'; /** * API class for receive files @@ -177,6 +175,8 @@ class Documents extends DolibarrApi if ($modulepart == 'societe' || $modulepart == 'thirdparty') { + require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; + if (!DolibarrApiAccess::$user->rights->societe->lire) { throw new RestException(401); } @@ -239,7 +239,7 @@ class Documents extends DolibarrApi * Test sample 1: { "filename": "mynewfile.txt", "modulepart": "facture", "ref": "FA1701-001", "subdir": "", "filecontent": "content text", "fileencoding": "", "overwriteifexists": "0" }. * Test sample 2: { "filename": "mynewfile.txt", "modulepart": "medias", "ref": "", "subdir": "mysubdir1/mysubdir2", "filecontent": "content text", "fileencoding": "", "overwriteifexists": "0" }. * - * @param string $filename Name of file to create ('FA1705-0123') + * @param string $filename Name of file to create ('FA1705-0123.txt') * @param string $modulepart Name of module or area concerned by file upload ('facture', 'project', 'project_task', ...) * @param string $ref Reference of object (This will define subdir automatically and store submited file into it) * @param string $subdir Subdirectory (Only if ref not provided) @@ -285,15 +285,20 @@ class Documents extends DolibarrApi if ($modulepart == 'facture' || $modulepart == 'invoice') { $modulepart='facture'; + + require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; $object = new Facture($this->db); } elseif ($modulepart == 'project') { + require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; $object = new Project($this->db); } elseif ($modulepart == 'task' || $modulepart == 'project_task') { $modulepart = 'project_task'; + + require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php'; $object = new Task($this->db); $task_result = $object->fetch('', $ref); diff --git a/htdocs/compta/bank/class/api_bankaccounts.class.php b/htdocs/compta/bank/class/api_bankaccounts.class.php index fa540f43401..f1fdb31cf69 100644 --- a/htdocs/compta/bank/class/api_bankaccounts.class.php +++ b/htdocs/compta/bank/class/api_bankaccounts.class.php @@ -344,7 +344,7 @@ class BankAccounts extends DolibarrApi /** * Add a link to an account line * - * @param int $account_id ID of account + * @param int $id ID of account * @param int $line_id ID of account line * @param int $url_id ID to set in the URL {@from body} * @param string $url URL of the link {@from body} @@ -352,16 +352,16 @@ class BankAccounts extends DolibarrApi * @param string $type Type of link ('payment', 'company', 'member', ...) {@from body} * @return int ID of link * - * @url POST {account_id}/lines/{line_id}/links + * @url POST {id}/lines/{line_id}/links */ - function addLink($account_id, $line_id, $url_id, $url, $label, $type) + function addLink($id, $line_id, $url_id, $url, $label, $type) { if (! DolibarrApiAccess::$user->rights->banque->modifier) { throw new RestException(401); } $account = new Account($this->db); - $result = $account->fetch($account_id); + $result = $account->fetch($id); if (! $result) { throw new RestException(404, 'account not found'); } From a5a9b9b23fb6cf6d46bfa880844362cb4f71ee54 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 17 Nov 2017 12:46:30 +0100 Subject: [PATCH 121/131] Removed deprecated REST API Prepare code to be compatible with swagger v2 --- ChangeLog | 8 +++++--- htdocs/api/index.php | 16 +++++++++------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index f33c02b8d18..aa89dd48f9f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,22 +15,24 @@ WARNING: Following changes may create regressions for some external modules, but were necessary to make Dolibarr better: * The methode "cloture" on contract were renamed into "closeAll". -* The substitution key for reference of object is now __REF__ whatever is the object (it replaces __ORDERREF__, +* The substitution key for reference of objects is now __REF__ whatever is the object (it replaces __ORDERREF__, __PROPALREF__, ...) * The substition key __SIGNATURE__ was renamed into __USER_SIGNATURE__ to follow naming conventions. * Substitution keys with syntax %XXX% were renamed into __XXX__ to match others. +* Removed old deprecated REST API (APIs found into '/root' section of the REST API explorer in Dolibarr v6). * Some REST API to access setup features, like dictionaries (country, town, extrafields, ...) were moved into a common API "/setup". * The REST API /documents were renamed into /documents/download and /documents/upload. * Page bank/index.php, bank/bankentries.php and comm/actions/listactions.php were renamed into bank/list.php, bank/bankentries_list.php and comm/actions/list.php to follow page naming - conventions (so default filter/sort order features can also work). + conventions (so default filter/sort order features can also work for this pages). * The trigger ORDER_SUPPLIER_STATUS_ONPROCESS was renamed into ORDER_SUPPLIER_STATUS_ORDERED. * The trigger ORDER_SUPPLIER_STATUS_RECEIVED_ALL was renamed into ORDER_SUPPLIER_STATUS_RECEIVED_COMPLETELY. * The parameter note into method cloture() is added at end of private note (previously in v6, it replaced). * The parameter $user is now mandatory for method createFromOrder and createFromPropal. * Removed js library 'fileupload' that was not used by core code. -* IE8 and earlier and Firefox 12 and earlier (2012) are no more supported. +* IE8 and earlier and Firefox 12 and earlier (< 2012) are no more supported. + ***** ChangeLog for 6.0.3 compared to 6.0.2 ***** FIX: #7211 Update qty dispatched on qty change diff --git a/htdocs/api/index.php b/htdocs/api/index.php index 50e0421010a..9582ddb8efb 100644 --- a/htdocs/api/index.php +++ b/htdocs/api/index.php @@ -96,7 +96,7 @@ preg_match('/index\.php\/([^\/]+)(.*)$/', $_SERVER["PHP_SELF"], $reg); // Set the flag to say to refresh (when we reload the explorer, production must be for API call only) $refreshcache=false; -if (! empty($reg[1]) && $reg[1] == 'explorer' && ($reg[2] == '/resources.json' || $reg[2] == '/resources.json/root')) +if (! empty($reg[1]) && $reg[1] == 'explorer' && ($reg[2] == '/swagger.json' || $reg[2] == '/swagger.json/root' || $reg[2] == '/resources.json' || $reg[2] == '/resources.json/root')) { $refreshcache=true; } @@ -109,7 +109,7 @@ $api = new DolibarrApi($db, '', $refreshcache); // See https://github.com/Luracast/Restler-API-Explorer for more info. $api->r->addAPIClass('Luracast\\Restler\\Explorer'); -$api->r->setSupportedFormats('JsonFormat', 'XmlFormat', 'UploadFormat'); +$api->r->setSupportedFormats('JsonFormat', 'XmlFormat', 'UploadFormat'); // 'YamlFormat' $api->r->addAuthenticationClass('DolibarrApiAccess',''); // Define accepted mime types @@ -118,7 +118,7 @@ UploadFormat::$allowedMimeTypes = array('image/jpeg', 'image/png', 'text/plain', // Call Explorer file for all APIs definitions -if (! empty($reg[1]) && $reg[1] == 'explorer' && ($reg[2] == '/resources.json' || $reg[2] == '/resources.json/root')) +if (! empty($reg[1]) && $reg[1] == 'explorer' && ($reg[2] == '/swagger.json' || $reg[2] == '/swagger.json/root' || $reg[2] == '/resources.json' || $reg[2] == '/resources.json/root')) { // Scan all API files to load them @@ -164,7 +164,7 @@ if (! empty($reg[1]) && $reg[1] == 'explorer' && ($reg[2] == '/resources.json' | if ($file_searched == 'api_access.class.php') continue; // Support of the deprecated API. - if (is_readable($dir_part.$file_searched) && preg_match("/^api_deprecated_(.*)\.class\.php$/i",$file_searched,$regapi)) + /*if (is_readable($dir_part.$file_searched) && preg_match("/^api_deprecated_(.*)\.class\.php$/i",$file_searched,$regapi)) { $classname = ucwords($regapi[1]).'Api'; require_once $dir_part.$file_searched; @@ -178,7 +178,8 @@ if (! empty($reg[1]) && $reg[1] == 'explorer' && ($reg[2] == '/resources.json' | dol_syslog("We found an api_xxx file (".$file_searched.") but class ".$classname." does not exists after loading file", LOG_WARNING); } } - elseif (is_readable($dir_part.$file_searched) && preg_match("/^api_(.*)\.class\.php$/i",$file_searched,$regapi)) + else*/ + if (is_readable($dir_part.$file_searched) && preg_match("/^api_(.*)\.class\.php$/i",$file_searched,$regapi)) { $classname = ucwords($regapi[1]); $classname = str_replace('_', '', $classname); @@ -213,15 +214,16 @@ if (! empty($reg[1]) && $reg[1] == 'explorer' && ($reg[2] == '/resources.json' | { $api->r->addAPIClass($classname, $apiname); } + //var_dump($api->r); } // Call one APIs or one definition of an API -if (! empty($reg[1]) && ($reg[1] != 'explorer' || ($reg[2] != '/resources.json' && preg_match('/^\/resources.json\/(.+)$/', $reg[2], $regbis) && $regbis[1] != 'root'))) +if (! empty($reg[1]) && ($reg[1] != 'explorer' || ($reg[2] != '/swagger.json' && $reg[2] != '/resources.json' && preg_match('/^\/(swagger|resources)\.json\/(.+)$/', $reg[2], $regbis) && $regbis[2] != 'root'))) { $module = $reg[1]; if ($module == 'explorer') // If we call page to explore details of a service { - $module = $regbis[1]; + $module = $regbis[2]; } $module=strtolower($module); From f33b5067ad57a798d2fc62a90c78c0bac24a427d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 17 Nov 2017 12:54:49 +0100 Subject: [PATCH 122/131] Upgrade branch 3.0 of RESTLER (still 3.0.0 RC6) This upgrade Swagger from 1.2 to 2.0 --- dev/dolibarr_changes.txt | 13 +- .../framework/Luracast/Restler/AutoLoader.php | 4 +- .../Luracast/Restler/CommentParser.php | 2 +- .../Restler/Data/{Object.php => Obj.php} | 2 +- .../Luracast/Restler/Data/Validator.php | 12 +- .../Luracast/Restler/EventDispatcher.php | 2 +- .../framework/Luracast/Restler/Explorer.php | 422 +- .../Luracast/Restler/ExplorerInfo.php | 18 +- .../Luracast/Restler/Format/CsvFormat.php | 26 +- .../Luracast/Restler/Format/HtmlFormat.php | 4 +- .../Luracast/Restler/Format/JsonFormat.php | 25 +- .../Luracast/Restler/Format/PlistFormat.php | 4 +- .../Luracast/Restler/Format/UploadFormat.php | 4 +- .../Luracast/Restler/Format/XmlFormat.php | 4 +- .../Luracast/Restler/Format/YamlFormat.php | 4 +- .../Luracast/Restler/PassThrough.php | 1 - .../framework/Luracast/Restler/Restler.php | 149 +- .../framework/Luracast/Restler/Routes.php | 3 +- .../framework/Luracast/Restler/Scope.php | 17 +- .../framework/Luracast/Restler/Util.php | 4 + .../Luracast/Restler/explorer/css/print.css | 1187 + .../Luracast/Restler/explorer/css/screen.css | 166 +- .../Luracast/Restler/explorer/css/style.css | 250 + .../Restler/explorer/css/typography.css | 14 + .../Restler/explorer/fonts/DroidSans-Bold.ttf | Bin 0 -> 42480 bytes .../Restler/explorer/fonts/DroidSans.ttf | Bin 0 -> 41028 bytes .../Restler/explorer/images/collapse.gif | Bin 0 -> 69 bytes .../Restler/explorer/images/expand.gif | Bin 0 -> 73 bytes .../Restler/explorer/images/logo_small.png | Bin 770 -> 1620 bytes .../Restler/explorer/images/pet_store_api.png | Bin 824 -> 0 bytes .../Restler/explorer/images/wordnik_api.png | Bin 980 -> 0 bytes .../Luracast/Restler/explorer/index.html | 167 +- .../Luracast/Restler/explorer/lang/en.js | 55 + .../Luracast/Restler/explorer/lang/es.js | 52 + .../Luracast/Restler/explorer/lang/fr.js | 53 + .../Luracast/Restler/explorer/lang/it.js | 52 + .../Luracast/Restler/explorer/lang/ja.js | 53 + .../Luracast/Restler/explorer/lang/pl.js | 53 + .../Luracast/Restler/explorer/lang/pt.js | 53 + .../Luracast/Restler/explorer/lang/ru.js | 55 + .../Luracast/Restler/explorer/lang/tr.js | 53 + .../Restler/explorer/lang/translator.js | 39 + .../Luracast/Restler/explorer/lang/zh-cn.js | 53 + .../Restler/explorer/lib/backbone-min.js | 51 +- .../Restler/explorer/lib/handlebars-2.0.0.js | 28 + .../Restler/explorer/lib/jsoneditor.min.js | 11 + .../Luracast/Restler/explorer/lib/marked.js | 1272 + .../Restler/explorer/lib/swagger-oauth.js | 255 +- .../Restler/explorer/lib/underscore-min.js | 38 +- .../Restler/explorer/lib/underscore-min.map | 1 + .../Luracast/Restler/explorer/o2c.html | 7 +- .../Luracast/Restler/explorer/swagger-ui.js | 28091 ++++++++++++++-- .../Restler/explorer/swagger-ui.min.js | 1 - 53 files changed, 30276 insertions(+), 2554 deletions(-) rename htdocs/includes/restler/framework/Luracast/Restler/Data/{Object.php => Obj.php} (99%) create mode 100644 htdocs/includes/restler/framework/Luracast/Restler/explorer/css/print.css create mode 100644 htdocs/includes/restler/framework/Luracast/Restler/explorer/css/style.css create mode 100644 htdocs/includes/restler/framework/Luracast/Restler/explorer/css/typography.css create mode 100644 htdocs/includes/restler/framework/Luracast/Restler/explorer/fonts/DroidSans-Bold.ttf create mode 100644 htdocs/includes/restler/framework/Luracast/Restler/explorer/fonts/DroidSans.ttf create mode 100644 htdocs/includes/restler/framework/Luracast/Restler/explorer/images/collapse.gif create mode 100644 htdocs/includes/restler/framework/Luracast/Restler/explorer/images/expand.gif delete mode 100644 htdocs/includes/restler/framework/Luracast/Restler/explorer/images/pet_store_api.png delete mode 100644 htdocs/includes/restler/framework/Luracast/Restler/explorer/images/wordnik_api.png create mode 100644 htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/en.js create mode 100644 htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/es.js create mode 100644 htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/fr.js create mode 100644 htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/it.js create mode 100644 htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/ja.js create mode 100644 htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/pl.js create mode 100644 htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/pt.js create mode 100644 htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/ru.js create mode 100644 htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/tr.js create mode 100644 htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/translator.js create mode 100644 htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/zh-cn.js create mode 100644 htdocs/includes/restler/framework/Luracast/Restler/explorer/lib/handlebars-2.0.0.js create mode 100644 htdocs/includes/restler/framework/Luracast/Restler/explorer/lib/jsoneditor.min.js create mode 100644 htdocs/includes/restler/framework/Luracast/Restler/explorer/lib/marked.js create mode 100644 htdocs/includes/restler/framework/Luracast/Restler/explorer/lib/underscore-min.map delete mode 100644 htdocs/includes/restler/framework/Luracast/Restler/explorer/swagger-ui.min.js diff --git a/dev/dolibarr_changes.txt b/dev/dolibarr_changes.txt index fa84aedc26a..f8d50ca6402 100644 --- a/dev/dolibarr_changes.txt +++ b/dev/dolibarr_changes.txt @@ -116,4 +116,15 @@ to get if ($className == 'Luracast\Restler\string') return; if ($className == 'Luracast\Restler\mixed') return; ... - \ No newline at end of file + +Change also file Luracast/Restler/explorer/index.html + ++With swagger 2: + +* Add line into Util.php to complete function + + public static function getShortName($className) + { + // @CHANGE LDR + if (! is_string($className)) return; + //var_dump($className); diff --git a/htdocs/includes/restler/framework/Luracast/Restler/AutoLoader.php b/htdocs/includes/restler/framework/Luracast/Restler/AutoLoader.php index 20a33ee3b70..300eadb0f70 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/AutoLoader.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/AutoLoader.php @@ -307,10 +307,10 @@ class AutoLoader */ private function alias($className, $currentClass) { - // @CHANGE LDR + // @CHANGE LDR if ($className == 'Luracast\Restler\string') return; if ($className == 'Luracast\Restler\mixed') return; - + if ($className != $currentClass && false !== strpos($className, $currentClass)) if (!class_exists($currentClass, false) diff --git a/htdocs/includes/restler/framework/Luracast/Restler/CommentParser.php b/htdocs/includes/restler/framework/Luracast/Restler/CommentParser.php index 8a3023cab20..e8248a385fa 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/CommentParser.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/CommentParser.php @@ -505,7 +505,7 @@ class CommentParser $data = explode('|', $data); $r['type'] = count($data) == 1 ? $data[0] : $data; } - if (isset($r['type']) && is_string($r['type']) && Text::endsWith($r['type'], '[]')) { + if (isset($r['type']) && Text::endsWith($r['type'], '[]')) { $r[static::$embeddedDataName]['type'] = substr($r['type'], 0, -2); $r['type'] = 'array'; } diff --git a/htdocs/includes/restler/framework/Luracast/Restler/Data/Object.php b/htdocs/includes/restler/framework/Luracast/Restler/Data/Obj.php similarity index 99% rename from htdocs/includes/restler/framework/Luracast/Restler/Data/Object.php rename to htdocs/includes/restler/framework/Luracast/Restler/Data/Obj.php index 5ef5850b86e..003f1df8794 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/Data/Object.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/Data/Obj.php @@ -13,7 +13,7 @@ namespace Luracast\Restler\Data; * @link http://luracast.com/products/restler/ * @version 3.0.0rc6 */ -class Object +class Obj { /** * @var bool|string|callable diff --git a/htdocs/includes/restler/framework/Luracast/Restler/Data/Validator.php b/htdocs/includes/restler/framework/Luracast/Restler/Data/Validator.php index be2ef28f40a..28202efb7ad 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/Data/Validator.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/Data/Validator.php @@ -454,7 +454,10 @@ class Validator implements iValidate } if (isset ($info->choice)) { - if (is_array($input)) { + if (!$info->required && empty($input)) { + //since its optional, and empty let it pass. + $input = null; + } elseif (is_array($input)) { foreach ($input as $i) { if (!in_array($i, $info->choice)) { $error .= ". Expected one of (" . implode(',', $info->choice) . ")."; @@ -468,6 +471,11 @@ class Validator implements iValidate } if (method_exists($class = get_called_class(), $info->type) && $info->type != 'validate') { + if(!$info->required && empty($input)) + { + //optional parameter with a empty value assume null + return null; + } try { return call_user_func("$class::$info->type", $input, $info); } catch (Invalid $e) { @@ -669,4 +677,4 @@ class Validator implements iValidate throw $e; } } -} \ No newline at end of file +} diff --git a/htdocs/includes/restler/framework/Luracast/Restler/EventDispatcher.php b/htdocs/includes/restler/framework/Luracast/Restler/EventDispatcher.php index 1c173d38baa..f8cd883af46 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/EventDispatcher.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/EventDispatcher.php @@ -44,7 +44,7 @@ class EventDispatcher public function __call($eventName, $params) { if (0 === strpos($eventName, 'on')) { - if (!@is_array($this->listeners[$eventName])) + if (!isset($this->listeners[$eventName]) || !is_array($this->listeners[$eventName])) $this->listeners[$eventName] = array(); $this->listeners[$eventName][] = $params[0]; } diff --git a/htdocs/includes/restler/framework/Luracast/Restler/Explorer.php b/htdocs/includes/restler/framework/Luracast/Restler/Explorer.php index 9522441c5b0..686c4c2fc23 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/Explorer.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/Explorer.php @@ -16,7 +16,12 @@ use Luracast\Restler\Scope; */ class Explorer implements iProvideMultiVersionApi { - const SWAGGER_VERSION = '1.2'; + const SWAGGER = '2.0'; + + /** + * @var array http schemes supported. http or https or both http and https + */ + public static $schemes = array(); /** * @var bool should protected resources be shown to unauthenticated users? */ @@ -70,17 +75,17 @@ class Explorer implements iProvideMultiVersionApi */ public static $dataTypeAlias = array( //'string' => 'string', - 'int' => 'integer', - 'number' => 'number', - 'float' => array('number', 'float'), - 'bool' => 'boolean', + 'int' => 'integer', + 'number' => 'number', + 'float' => array('number', 'float'), + 'bool' => 'boolean', //'boolean' => 'boolean', //'NULL' => 'null', - 'array' => 'array', + 'array' => 'array', //'object' => 'object', 'stdClass' => 'object', - 'mixed' => 'string', - 'date' => array('string', 'date'), + 'mixed' => 'string', + 'date' => array('string', 'date'), 'datetime' => array('string', 'date-time'), ); @@ -89,9 +94,9 @@ class Explorer implements iProvideMultiVersionApi * protected api */ public static $apiDescriptionSuffixSymbols = array( - 0 => '  ', //public api - 1 => '  ', //hybrid api - 2 => '  ', //protected api + 0 => ' 🔓', //'  ', //public api + 1 => ' ◑', //'  ', //hybrid api + 2 => ' 🔐', //'  ', //protected api ); protected $models = array(); @@ -100,27 +105,23 @@ class Explorer implements iProvideMultiVersionApi */ protected $_fullDataRequested = false; protected $crud = array( - 'POST' => 'create', - 'GET' => 'retrieve', - 'PUT' => 'update', + 'POST' => 'create', + 'GET' => 'retrieve', + 'PUT' => 'update', 'DELETE' => 'delete', - 'PATCH' => 'partial update' + 'PATCH' => 'partial update' ); protected static $prefixes = array( - 'get' => 'retrieve', - 'index' => 'list', - 'post' => 'create', - 'put' => 'update', - 'patch' => 'modify', + 'get' => 'retrieve', + 'index' => 'list', + 'post' => 'create', + 'put' => 'update', + 'patch' => 'modify', 'delete' => 'remove', ); protected $_authenticated = false; protected $cacheName = ''; - public function __construct() - { - - } /** * Serve static files for exploring @@ -131,7 +132,7 @@ class Explorer implements iProvideMultiVersionApi */ public function get() { - if (func_num_args() > 1 && func_get_arg(0) == 'resources') { + if (func_num_args() > 1 && func_get_arg(0) == 'swagger') { /** * BUGFIX: * If we use common resourcePath (e.g. $r->addAPIClass([api-class], 'api/shop')), than we must determine resource-ID of e.g. 'api/shop'! @@ -141,6 +142,7 @@ class Explorer implements iProvideMultiVersionApi array_shift($arguments); // create ID $id = implode('/', $arguments); + return $this->getResources($id); } $filename = implode('/', func_get_args()); @@ -161,125 +163,75 @@ class Explorer implements iProvideMultiVersionApi ) { $filename .= '.js'; } - PassThrough::file(__DIR__ . '/explorer/' . (empty($filename) ? 'index.html' : $filename), false, 0); //60 * 60 * 24); + PassThrough::file(__DIR__ . '/explorer/' . (empty($filename) ? 'index.html' : $filename), false, + 0); //60 * 60 * 24); } - public function resources() + /** + * @return stdClass + */ + public function swagger() { $r = new stdClass(); - $r->apiVersion = (string)$this->restler->getRequestedApiVersion(); - $r->swaggerVersion = static::SWAGGER_VERSION; - $r->apis = $this->apis($r->apiVersion); - $r->authorizations = $this->authorizations(); - $r->info = array_filter(get_class_vars(static::$infoClass)); - return $r; - } + $version = (string)$this->restler->getRequestedApiVersion(); + $r->swagger = static::SWAGGER; - public function getResources($id) - { - $r = new stdClass(); - $r->apiVersion = (string)$this->restler->getRequestedApiVersion(); - $r->swaggerVersion = static::SWAGGER_VERSION; - $r->basePath = $this->restler->getBaseUrl(); - $r->resourcePath = "/$id"; - - $r->apis = $this->apis($r->apiVersion, $id); - $r->models = (object)$this->models; + $info = parse_url($this->restler->getBaseUrl()); + $r->host = $info['host']; + if (isset($info['port'])) { + $r->host .= ':' . $info['port']; + } + $r->basePath = isset($info['path']) ? $info['path'] : ''; + if (!empty(static::$schemes)) { + $r->schemes = static::$schemes; + } $r->produces = $this->restler->getWritableMimeTypes(); $r->consumes = $this->restler->getReadableMimeTypes(); - $r->authorizations = $this->authorizations(); + + $r->paths = $this->paths($version); + $r->definitions = (object)$this->models; + $r->securityDefinitions = $this->securityDefinitions(); + $r->info = compact('version') + array_filter(get_class_vars(static::$infoClass)); + return $r; } - private function apis($version = 1, $resource = false) + private function paths($version = 1) { $map = Routes::findAll(static::$excludedPaths + array($this->base()), static::$excludedHttpMethods, $version); - $r = array(); - $a = array(); + $paths = array(); foreach ($map as $path => $data) { - $route = $data[0]['route']; $access = $data[0]['access']; - if ($access && !Text::contains($path, '{')) { - $r[] = array( - 'path' => empty($path) ? '/root' : "/$path", - //'description' => '' - //TODO: Util::nestedValue($route, 'metadata', 'classDescription') ? : '' - ); - } - if (static::$hideProtected && !$access) + if (static::$hideProtected && !$access) { continue; - $grouper = array(); + } foreach ($data as $item) { $route = $item['route']; $access = $item['access']; - if (static::$hideProtected && !$access) + if (static::$hideProtected && !$access) { continue; + } $url = $route['url']; - if (isset($grouper[$url])) { - $grouper[$url]['operations'][] = $this->operation($route); - } else { - $api = array( - 'path' => "/$url", - 'description' => - Util::nestedValue($route, 'metadata', 'classDescription') ? : '', - 'operations' => array($this->operation($route)) - ); - static::$groupOperations - ? $grouper[$url] = $api - : $a[$path][] = $api; - } + $paths["/$url"][strtolower($route['httpMethod'])] = $this->operation($route); } - if (!empty($grouper)) { - $a[$path] = array_values($grouper); - // sort REST-endpoints by path - foreach ($a as & $b) { - usort( - $b, - function ($x, $y) { - return $x['path'] > $y['path']; - } - ); - } - } else { - $order = array( - 'GET' => 1, - 'POST' => 2, - 'PUT' => 3, - 'PATCH' => 4, - 'DELETE' => 5 - ); - foreach ($a as & $b) { - usort( - $b, - function ($x, $y) use ($order) { - return - $x['operations'][0]->method == - $y['operations'][0]->method - ? $x['path'] > $y['path'] - : $order[$x['operations'][0]->method] > - $order[$y['operations'][0]->method]; + } - } - ); - } - } - } - if (false !== $resource) { - if ($resource == 'root') $resource = ''; - if (isset($a[$resource])) return $a[$resource]; - } - return $r; + return $paths; } private function operation($route) { $r = new stdClass(); - $r->method = $route['httpMethod']; - $r->nickname = $this->nickname($route); + $m = $route['metadata']; + $r->operationId = $this->operationId($route); + $base = strtok($route['url'], '/'); + if (empty($base)) { + $base = 'root'; + } + $r->tags = array($base); $r->parameters = $this->parameters($route); - $m = $route['metadata']; $r->summary = isset($m['description']) ? $m['description'] @@ -287,13 +239,18 @@ class Explorer implements iProvideMultiVersionApi $r->summary .= $route['accessLevel'] > 2 ? static::$apiDescriptionSuffixSymbols[2] : static::$apiDescriptionSuffixSymbols[$route['accessLevel']]; - $r->notes = isset($m['longDescription']) + $r->description = isset($m['longDescription']) ? $m['longDescription'] : ''; - $r->responseMessages = $this->responseMessages($route); + $r->responses = $this->responses($route); + //TODO: avoid hard coding. Properly detect security + if ($route['accessLevel']) { + $r->security = array(array('api_key' => array())); + } + /* $this->setType( $r, - new ValidationInfo(Util::nestedValue($m, 'return') ? : array()) + new ValidationInfo(Util::nestedValue($m, 'return') ?: array()) ); if (is_null($r->type) || 'mixed' == $r->type) { $r->type = 'array'; @@ -302,7 +259,7 @@ class Explorer implements iProvideMultiVersionApi } elseif (Text::contains($r->type, '|')) { $r->type = 'array'; } - + */ //TODO: add $r->authorizations //A list of authorizations required to execute this operation. While not mandatory, if used, it overrides //the value given at the API Declaration's authorizations. In order to completely remove API Declaration's @@ -324,8 +281,9 @@ class Explorer implements iProvideMultiVersionApi $info = new ValidationInfo($param); $description = isset($param['description']) ? $param['description'] : ''; if ('body' == $info->from) { - if ($info->required) + if ($info->required) { $required = true; + } $param['description'] = $description; $children[] = $param; } else { @@ -341,31 +299,31 @@ class Explorer implements iProvideMultiVersionApi if (empty($firstChild['children'])) { $description = $firstChild['description']; } else { - $description = '
'; + $description = ''; //'
'; foreach ($firstChild['children'] as $child) { $description .= isset($child['required']) && $child['required'] - ? '' . $child['name'] . ' (required)
' - : $child['name'] . '
'; + ? '**' . $child['name'] . '** (required) '.PHP_EOL + : $child['name'] . ' '.PHP_EOL; } - $description .= '
'; + //$description .= '
'; } $r[] = $this->parameter(new ValidationInfo($firstChild), $description); } else { - $description = '
'; + $description = ''; //'
'; foreach ($children as $child) { - $description .= isset($child['required']) && $child['required'] - ? '' . $child['name'] . ' (required)
' - : $child['name'] . '
'; + $description .= isset($child['required']) && $child['required'] + ? '**' . $child['name'] . '** (required) '.PHP_EOL + : $child['name'] . ' '.PHP_EOL; } - $description .= '
'; + //$description .= '
'; //lets group all body parameters under a generated model name - $name = $this->nameModel($route); + $name = $this->modelName($route); $r[] = $this->parameter( new ValidationInfo(array( - 'name' => $name, - 'type' => $name, - 'from' => 'body', + 'name' => $name, + 'type' => $name, + 'from' => 'body', 'required' => $required, 'children' => $children )), @@ -373,196 +331,224 @@ class Explorer implements iProvideMultiVersionApi ); } } + return $r; } private function parameter(ValidationInfo $info, $description = '') { $p = new stdClass(); - if(isset($info->rules['model'])){ - $info->type = $info->rules['model']; + if (isset($info->rules['model'])) { + //$info->type = $info->rules['model']; } $p->name = $info->name; $this->setType($p, $info); if (empty($info->children) || $info->type != 'array') { //primitives - if ($info->default) + if ($info->default) { $p->defaultValue = $info->default; - if ($info->choice) + } + if ($info->choice) { $p->enum = $info->choice; - if ($info->min) + } + if ($info->min) { $p->minimum = $info->min; - if ($info->max) + } + if ($info->max) { $p->maximum = $info->max; + } //TODO: $p->items and $p->uniqueItems boolean } $p->description = $description; - $p->paramType = $info->from; //$info->from == 'body' ? 'form' : $info->from; + $p->in = $info->from; //$info->from == 'body' ? 'form' : $info->from; $p->required = $info->required; - $p->allowMultiple = false; + + //$p->allowMultiple = false; + + if (isset($p->{'$ref'})) { + $p->schema = (object)array('$ref' => ($p->{'$ref'})); + unset($p->{'$ref'}); + } + return $p; } - private function responseMessages(array $route) + private function responses(array $route) { - $r = array(); + $code = '200'; + $r = array( + $code => (object)array( + 'description' => 'Success', + 'schema' => new stdClass() + ) + ); + $return = Util::nestedValue($route, 'metadata', 'return'); + if (!empty($return)) { + $this->setType($r[$code]->schema, new ValidationInfo($return)); + } + if (is_array($throws = Util::nestedValue($route, 'metadata', 'throws'))) { foreach ($throws as $message) { - $m = (object)$message; - //TODO: add $m->responseModel from composer class - $r[] = $m; + $r[$message['code']] = array('description' => $message['message']); } } + return $r; } private function model($type, array $children) { - /** - * Bugfix: - * If we use namespaces, than the model will not be correct, if we use a short name for the type! - * - * Example (phpDoc/annotations in API-class, which uses custom domain-model with namespace): - * @param Car $car {@from body} {@type Aoe\RestServices\Domain\Model\Car} - * @return Car {@type Aoe\RestServices\Domain\Model\Car} - * Than, the model (in swagger-spec) must also be 'Aoe\RestServices\Domain\Model\Car' and not 'Car' - * - * When we use namespaces, than we must use the @type-annotation, otherwise the automatic reconstitution - * from request-data (e.g. when it is a POST-request) to custom domain-model-object will not work! - * - * Summary: - * - When we use no namespaces, than the type would not be changed, if we would call 'Util::getShortName' - * - When we use namespaces, than the model will not be correct, if we would call 'Util::getShortName' - * ...so this method-call is either needless or will create a bug/error - */ - //$type = Util::getShortName($type); - if (isset($this->models[$type])) + if (isset($this->models[$type])) { return $this->models[$type]; + } $r = new stdClass(); - $r->id = $type; - $r->description = "$type Model"; //TODO: enhance this on Router - $r->required = array(); $r->properties = array(); + $required = array(); foreach ($children as $child) { $info = new ValidationInfo($child); $p = new stdClass(); $this->setType($p, $info); $p->description = isset($child['description']) ? $child['description'] : ''; - if ($info->default) + if ($info->default) { $p->defaultValue = $info->default; - if ($info->choice) + } + if ($info->choice) { $p->enum = $info->choice; - if ($info->min) + } + if ($info->min) { $p->minimum = $info->min; - if ($info->max) + } + if ($info->max) { $p->maximum = $info->max; - if ($info->required) - $r->required[] = $info->name; + } + if ($info->required) { + $required[] = $info->name; + } $r->properties[$info->name] = $p; } + if (!empty($required)) { + $r->required = $required; + } //TODO: add $r->subTypes https://github.com/wordnik/swagger-spec/blob/master/versions/1.2.md#527-model-object //TODO: add $r->discriminator https://github.com/wordnik/swagger-spec/blob/master/versions/1.2.md#527-model-object $this->models[$type] = $r; + return $r; } private function setType(&$object, ValidationInfo $info) { //TODO: proper type management + $type = Util::getShortName($info->type); if ($info->type == 'array') { + $object->type = 'array'; if ($info->children) { - $this->model($info->contentType, $info->children); + $contentType = Util::getShortName($info->contentType); + $model = $this->model($contentType, $info->children); $object->items = (object)array( - '$ref' => $info->contentType + '$ref' => "#/definitions/$contentType" ); } elseif ($info->contentType && $info->contentType == 'associative') { unset($info->contentType); $this->model($info->type = 'Object', array( array( - 'name' => 'property', - 'type' => 'string', - 'default' => '', - 'required' => false, + 'name' => 'property', + 'type' => 'string', + 'default' => '', + 'required' => false, 'description' => '' ) )); } elseif ($info->contentType && $info->contentType != 'indexed') { - $object->items = (object)array( - 'type' => $info->contentType - ); + if (is_string($info->contentType) && $t = Util::nestedValue(static::$dataTypeAlias, + strtolower($info->contentType))) { + if (is_array($t)) { + $object->items = (object)array( + 'type' => $t[0], + 'format' => $t[1], + ); + } else { + $object->items = (object)array( + 'type' => $t, + ); + } + } else { + $contentType = Util::getShortName($info->contentType); + $object->items = (object)array( + '$ref' => "#/definitions/$contentType" + ); + } } else { $object->items = (object)array( 'type' => 'string' ); } } elseif ($info->children) { - $this->model($info->type, $info->children); + $this->model($type, $info->children); + $object->{'$ref'} = "#/definitions/$type"; } elseif (is_string($info->type) && $t = Util::nestedValue(static::$dataTypeAlias, strtolower($info->type))) { if (is_array($t)) { - list($info->type, $object->format) = $t; + $object->type = $t[0]; + $object->format = $t[1]; } else { - $info->type = $t; + $object->type = $t; } } else { - $info->type = 'string'; + $object->type = 'string'; } - $object->type = $info->type; $has64bit = PHP_INT_MAX > 2147483647; - if ($object->type == 'integer') { - $object->format = $has64bit - ? 'int64' - : 'int32'; - } elseif ($object->type == 'number') { - $object->format = $has64bit - ? 'double' - : 'float'; + if (isset($object->type)) { + if ($object->type == 'integer') { + $object->format = $has64bit + ? 'int64' + : 'int32'; + } elseif ($object->type == 'number') { + $object->format = $has64bit + ? 'double' + : 'float'; + } } } - private function nickname(array $route) + private function operationId(array $route) { static $hash = array(); + $id = $route['httpMethod'] . ' ' . $route['url']; + if (isset($hash[$id])) { + return $hash[$id]; + } + $class = Util::getShortName($route['className']); $method = $route['methodName']; + if (isset(static::$prefixes[$method])) { - $method = static::$prefixes[$method]; + $method = static::$prefixes[$method] . $class; } else { $method = str_replace( array_keys(static::$prefixes), array_values(static::$prefixes), $method ); + $method = lcfirst($class) . ucfirst($method); } - while (isset($hash[$method]) && $route['url'] != $hash[$method]) { - //create another one - $method .= '_'; - } - $hash[$method] = $route['url']; + $hash[$id] = $method; + return $method; } - private function nameModel(array $route) + private function modelName(array $route) { - static $hash = array(); - $count = 1; - //$name = str_replace('/', '-', $route['url']) . 'Model'; - $name = $route['className'] . 'Model'; - while (isset($hash[$name . $count])) { - //create another one - $count++; - } - $name .= $count; - $hash[$name] = $route['url']; - return $name; + return $this->operationId($route) . 'Model'; } - private function authorizations() + private function securityDefinitions() { $r = new stdClass(); - $r->apiKey = (object)array( + $r->api_key = (object)array( 'type' => 'apiKey', - 'passAs' => 'query', - 'keyname' => 'api_key', + 'name' => 'api_key', + 'in' => 'query', ); + return $r; } diff --git a/htdocs/includes/restler/framework/Luracast/Restler/ExplorerInfo.php b/htdocs/includes/restler/framework/Luracast/Restler/ExplorerInfo.php index 41d969f65d9..b55c5943fed 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/ExplorerInfo.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/ExplorerInfo.php @@ -2,16 +2,22 @@ /** * Class ExplorerInfo - * @package Luracast\Restler - * + * @package Luracast\Restler + * * @version 3.0.0rc6 */ class ExplorerInfo { public static $title = 'Restler API Explorer'; public static $description = 'Live API Documentation'; - public static $termsOfServiceUrl = null; - public static $contact = 'arul@luracast.com'; - public static $license = 'LGPL-2.1'; - public static $licenseUrl = 'https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html'; + public static $termsOfService = null; + public static $contact = array( + 'name' => 'Restler Support', + 'url' => 'luracast.com/products/restler', + 'email' => 'arul@luracast.com', + ); + public static $license = array( + 'name' => 'LGPL-2.1', + 'url' => 'https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html', + ); } \ No newline at end of file diff --git a/htdocs/includes/restler/framework/Luracast/Restler/Format/CsvFormat.php b/htdocs/includes/restler/framework/Luracast/Restler/Format/CsvFormat.php index d6cdb63a943..4bed88251c8 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/Format/CsvFormat.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/Format/CsvFormat.php @@ -2,7 +2,7 @@ namespace Luracast\Restler\Format; -use Luracast\Restler\Data\Object; +use Luracast\Restler\Data\Obj; use Luracast\Restler\RestException; /** @@ -44,10 +44,10 @@ class CsvFormat extends Format implements iDecodeStream */ public function encode($data, $humanReadable = false) { - $char = Object::$separatorChar; - Object::$separatorChar = false; - $data = Object::toArray($data); - Object::$separatorChar = $char; + $char = Obj::$separatorChar; + Obj::$separatorChar = false; + $data = Obj::toArray($data); + Obj::$separatorChar = $char; if (is_array($data) && array_values($data) == $data) { //if indexed array $lines = array(); @@ -109,10 +109,10 @@ class CsvFormat extends Format implements iDecodeStream while (($row = static::getRow(array_shift($lines), $keys)) !== FALSE) $decoded [] = $row; - $char = Object::$separatorChar; - Object::$separatorChar = false; - $decoded = Object::toArray($decoded); - Object::$separatorChar = $char; + $char = Obj::$separatorChar; + Obj::$separatorChar = false; + $decoded = Obj::toArray($decoded); + Obj::$separatorChar = $char; return $decoded; } @@ -172,10 +172,10 @@ class CsvFormat extends Format implements iDecodeStream while (($row = static::getRow(stream_get_line($stream, 0, PHP_EOL), $keys)) !== FALSE) $decoded [] = $row; - $char = Object::$separatorChar; - Object::$separatorChar = false; - $decoded = Object::toArray($decoded); - Object::$separatorChar = $char; + $char = Obj::$separatorChar; + Obj::$separatorChar = false; + $decoded = Obj::toArray($decoded); + Obj::$separatorChar = $char; return $decoded; } } \ No newline at end of file diff --git a/htdocs/includes/restler/framework/Luracast/Restler/Format/HtmlFormat.php b/htdocs/includes/restler/framework/Luracast/Restler/Format/HtmlFormat.php index 6e7d4b7303e..e871186c446 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/Format/HtmlFormat.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/Format/HtmlFormat.php @@ -11,7 +11,7 @@ use Illuminate\View\Engines\EngineResolver; use Illuminate\View\Factory; use Illuminate\View\FileViewFinder; use Illuminate\View\View; -use Luracast\Restler\Data\Object; +use Luracast\Restler\Data\Obj; use Luracast\Restler\Defaults; use Luracast\Restler\RestException; use Luracast\Restler\Restler; @@ -315,7 +315,7 @@ class HtmlFormat extends DependentFormat $error = $success ? null : $exception->getMessage(); $data = array( 'response' => static::$convertResponseToArray - ? Object::toArray($data) + ? Obj::toArray($data) : $data, 'stages' => $this->restler->getEvents(), 'success' => $success, diff --git a/htdocs/includes/restler/framework/Luracast/Restler/Format/JsonFormat.php b/htdocs/includes/restler/framework/Luracast/Restler/Format/JsonFormat.php index 6986ce65c90..28dfd560969 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/Format/JsonFormat.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/Format/JsonFormat.php @@ -1,7 +1,7 @@ handleJsonError(); return $result; } - $result = json_encode(Object::toArray($data, true)); + $result = json_encode(Obj::toArray($data, true)); $this->handleJsonError(); if ($humanReadable) { @@ -116,6 +127,10 @@ class JsonFormat extends Format public function decode($data) { + if(empty($data)){ + return null; + } + $options = 0; if (self::$bigIntAsString) { if ((PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 4) // PHP >= 5.4 @@ -142,7 +157,7 @@ class JsonFormat extends Format throw new RestException(400, 'Error parsing JSON'); } - return Object::toArray($decoded); + return Obj::toArray($decoded); } /** @@ -259,4 +274,4 @@ class JsonFormat extends Format throw new \RuntimeException('Error encoding/decoding JSON: '. $message); } } -} \ No newline at end of file +} diff --git a/htdocs/includes/restler/framework/Luracast/Restler/Format/PlistFormat.php b/htdocs/includes/restler/framework/Luracast/Restler/Format/PlistFormat.php index 2f4faa0769f..cc07066a33c 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/Format/PlistFormat.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/Format/PlistFormat.php @@ -1,7 +1,7 @@ toCFType( - Object::toArray($data) + Obj::toArray($data) ); $plist->add($guessedStructure); diff --git a/htdocs/includes/restler/framework/Luracast/Restler/Format/UploadFormat.php b/htdocs/includes/restler/framework/Luracast/Restler/Format/UploadFormat.php index f785beeaa02..de41bf98c71 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/Format/UploadFormat.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/Format/UploadFormat.php @@ -25,7 +25,9 @@ class UploadFormat extends Format 2 => "The uploaded file exceeds the maximum allowed size", 3 => "The uploaded file was only partially uploaded", 4 => "No file was uploaded", - 6 => "Missing a temporary folder" + 6 => "Missing a temporary folder", + 7 => "Failed to write file to disk", + 8 => "A PHP extension stopped the file upload" ); /** * use it if you need to restrict uploads based on file type diff --git a/htdocs/includes/restler/framework/Luracast/Restler/Format/XmlFormat.php b/htdocs/includes/restler/framework/Luracast/Restler/Format/XmlFormat.php index b006409e800..b51fa707a53 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/Format/XmlFormat.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/Format/XmlFormat.php @@ -1,7 +1,7 @@ openMemory(); $xml->startDocument('1.0', $this->charset); diff --git a/htdocs/includes/restler/framework/Luracast/Restler/Format/YamlFormat.php b/htdocs/includes/restler/framework/Luracast/Restler/Format/YamlFormat.php index 0cb1564f4ed..07baae88b6f 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/Format/YamlFormat.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/Format/YamlFormat.php @@ -2,7 +2,7 @@ namespace Luracast\Restler\Format; use Symfony\Component\Yaml\Yaml; -use Luracast\Restler\Data\Object; +use Luracast\Restler\Data\Obj; /** * YAML Format for Restler Framework @@ -26,7 +26,7 @@ class YamlFormat extends DependentFormat public function encode($data, $humanReadable = false) { - return @Yaml::dump(Object::toArray($data), $humanReadable ? 10 : 4); + return @Yaml::dump(Obj::toArray($data), $humanReadable ? 10 : 4); } public function decode($data) diff --git a/htdocs/includes/restler/framework/Luracast/Restler/PassThrough.php b/htdocs/includes/restler/framework/Luracast/Restler/PassThrough.php index e1fc21eae6b..a77e533b722 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/PassThrough.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/PassThrough.php @@ -34,7 +34,6 @@ class PassThrough * @param bool $isPublic cache control, is it public or private * * @throws RestException - * @internal param string $pragma * */ public static function file($filename, $forceDownload = false, $expires = 0, $isPublic = true) diff --git a/htdocs/includes/restler/framework/Luracast/Restler/Restler.php b/htdocs/includes/restler/framework/Luracast/Restler/Restler.php index 0cef46a7e41..c2e9b1acb73 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/Restler.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/Restler.php @@ -538,7 +538,7 @@ class Restler extends EventDispatcher if ($version && $version <= $this->apiVersion) { $this->requestedApiVersion = $version; $path = explode('/', $path, 2); - $path = $path[1]; + $path = count($path) == 2 ? $path[1] : ''; } } else { $this->requestedApiVersion = $this->apiMinimumVersion; @@ -718,7 +718,8 @@ class Restler extends EventDispatcher . $_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']); header('Access-Control-Allow-Origin: ' . - (Defaults::$accessControlAllowOrigin == '*' ? $_SERVER['HTTP_ORIGIN'] : Defaults::$accessControlAllowOrigin)); + ((Defaults::$accessControlAllowOrigin == '*' && isset($_SERVER['HTTP_ORIGIN'])) + ? $_SERVER['HTTP_ORIGIN'] : Defaults::$accessControlAllowOrigin)); header('Access-Control-Allow-Credentials: true'); exit(0); @@ -1195,7 +1196,7 @@ class Restler extends EventDispatcher foreach ($this->errorClasses as $className) { if (method_exists($className, $method)) { $obj = Scope::get($className); - if ($obj->$method()) + if ($obj->$method($exception)) $handled = true; } } @@ -1397,6 +1398,135 @@ class Restler extends EventDispatcher $this->errorClasses[] = $className; } + /** + * protected methods will need at least one authentication class to be set + * in order to allow that method to be executed. When multiple authentication + * classes are in use, this function provides better performance by setting + * all auth classes through a single function call. + * + * @param array $classNames array of associative arrays containing + * the authentication class name & optional + * url prefix for mapping. + */ + public function setAuthClasses(array $classNames) + { + $this->authClasses = array_merge($this->authClasses, array_values($classNames)); + } + + /** + * Add multiple api classes through this method. + * + * This method provides better performance when large number + * of API classes are in use as it processes them all at once, + * as opposed to hundreds (or more) addAPIClass calls. + * + * + * All the public methods that do not start with _ (underscore) + * will be will be exposed as the public api by default. + * + * All the protected methods that do not start with _ (underscore) + * will exposed as protected api which will require authentication + * + * @param array $map array of associative arrays containing + * the class name & optional url prefix + * for mapping. + * + * @return null + * + * @throws Exception when supplied with invalid class name + */ + public function mapAPIClasses(array $map) + { + try { + if ($this->productionMode && is_null($this->cached)) { + $routes = $this->cache->get('routes'); + if (isset($routes) && is_array($routes)) { + $this->apiVersionMap = $routes['apiVersionMap']; + unset($routes['apiVersionMap']); + Routes::fromArray($routes); + $this->cached = true; + } else { + $this->cached = false; + } + } + $maxVersionMethod = '__getMaximumSupportedVersion'; + if (!$this->productionMode || !$this->cached) { + foreach ($map as $className => $resourcePath) { + if (is_numeric($className)) { + $className = $resourcePath; + $resourcePath = null; + } + if (isset(Scope::$classAliases[$className])) { + $className = Scope::$classAliases[$className]; + } + if (class_exists($className)) { + if (method_exists($className, $maxVersionMethod)) { + $max = $className::$maxVersionMethod(); + for ($i = 1; $i <= $max; $i++) { + $this->apiVersionMap[$className][$i] = $className; + } + } else { + $this->apiVersionMap[$className][1] = $className; + } + } + //versioned api + if (false !== ($index = strrpos($className, '\\'))) { + $name = substr($className, 0, $index) + . '\\v{$version}' . substr($className, $index); + } else { + if (false !== ($index = strrpos($className, '_'))) { + $name = substr($className, 0, $index) + . '_v{$version}' . substr($className, $index); + } else { + $name = 'v{$version}\\' . $className; + } + } + + for ($version = $this->apiMinimumVersion; + $version <= $this->apiVersion; + $version++) { + + $versionedClassName = str_replace('{$version}', $version, + $name); + if (class_exists($versionedClassName)) { + Routes::addAPIClass($versionedClassName, + Util::getResourcePath( + $className, + $resourcePath + ), + $version + ); + if (method_exists($versionedClassName, $maxVersionMethod)) { + $max = $versionedClassName::$maxVersionMethod(); + for ($i = $version; $i <= $max; $i++) { + $this->apiVersionMap[$className][$i] = $versionedClassName; + } + } else { + $this->apiVersionMap[$className][$version] = $versionedClassName; + } + } elseif (isset($this->apiVersionMap[$className][$version])) { + Routes::addAPIClass($this->apiVersionMap[$className][$version], + Util::getResourcePath( + $className, + $resourcePath + ), + $version + ); + } + } + } + } + } catch (Exception $e) { + $e = new Exception( + "mapAPIClasses failed. " . $e->getMessage(), + $e->getCode(), + $e + ); + $this->setSupportedFormats('JsonFormat'); + $this->message($e); + } + } + /** * Associated array that maps formats to their respective format class name * @@ -1484,6 +1614,19 @@ class Restler extends EventDispatcher public function __destruct() { if ($this->productionMode && !$this->cached) { + if (empty($this->url) && empty($this->requestMethod)) { + // url and requestMethod is NOT set: + // This can only happen, when an exception was thrown outside of restler, so that the method Restler::handle was NOT called. + // In this case, the routes can now be corrupt/incomplete, because we don't know, if all API-classes could be registered + // before the exception was thrown. So, don't cache the routes, because the routes can now be corrupt/incomplete! + return; + } + if ($this->exception instanceof RestException && $this->exception->getStage() === 'setup') { + // An exception has occured during configuration of restler. Maybe we could not add all API-classes correctly! + // So, don't cache the routes, because the routes can now be corrupt/incomplete! + return; + } + $this->cache->set( 'routes', Routes::toArray() + diff --git a/htdocs/includes/restler/framework/Luracast/Restler/Routes.php b/htdocs/includes/restler/framework/Luracast/Restler/Routes.php index 067603a0f58..73e78dc0039 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/Routes.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/Routes.php @@ -293,8 +293,6 @@ class Routes } $url = empty($methodUrl) ? rtrim($resourcePath, '/') : $resourcePath . $methodUrl; - $lastPathParam = array_keys($pathParams); - $lastPathParam = end($lastPathParam); for ($position = 0; $position < count($params); $position++) { $from = $metadata['param'][$position][$dataName]['from']; if ($from == 'body' && ($httpMethod == 'GET' || @@ -307,6 +305,7 @@ class Routes if (empty($pathParams) || $allowAmbiguity) { static::addPath($url, $call, $httpMethod, $version); } + $lastPathParam = end($pathParams); foreach ($pathParams as $position) { if (!empty($url)) $url .= '/'; diff --git a/htdocs/includes/restler/framework/Luracast/Restler/Scope.php b/htdocs/includes/restler/framework/Luracast/Restler/Scope.php index 91eea3ef6a1..fd4b41ff98d 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/Scope.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/Scope.php @@ -52,7 +52,7 @@ class Scope 'MemcacheCache' => 'Luracast\Restler\MemcacheCache', //Utility classes - 'Object' => 'Luracast\Restler\Data\Object', + 'Obj' => 'Luracast\Restler\Data\Obj', 'Text' => 'Luracast\Restler\Data\Text', 'Arr' => 'Luracast\Restler\Data\Arr', @@ -194,6 +194,11 @@ class Scope { if (empty($className) || !is_string($className)) return false; + + if (self::isPrimitiveDataType($className)) { + return false; + } + $divider = '\\'; $qualified = false; if ($className{0} == $divider) { @@ -212,4 +217,14 @@ class Scope } return false; } + + /** + * @param string $stringName + * @return boolean + */ + private static function isPrimitiveDataType($stringName) + { + $primitiveDataTypes = array('Array', 'array', 'bool', 'boolean', 'float', 'int', 'integer', 'string'); + return in_array($stringName, $primitiveDataTypes); + } } diff --git a/htdocs/includes/restler/framework/Luracast/Restler/Util.php b/htdocs/includes/restler/framework/Luracast/Restler/Util.php index e1c6f60c317..e7324a3a620 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/Util.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/Util.php @@ -226,6 +226,10 @@ class Util public static function getShortName($className) { + // @CHANGE LDR + if (! is_string($className)) return ''; + //var_dump($className); + $className = explode('\\', $className); return end($className); } diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/css/print.css b/htdocs/includes/restler/framework/Luracast/Restler/explorer/css/print.css new file mode 100644 index 00000000000..2e6b310300b --- /dev/null +++ b/htdocs/includes/restler/framework/Luracast/Restler/explorer/css/print.css @@ -0,0 +1,1187 @@ +/* Original style from softwaremaniacs.org (c) Ivan Sagalaev */ +.swagger-section pre code { + display: block; + padding: 0.5em; + background: #F0F0F0; +} +.swagger-section pre code, +.swagger-section pre .subst, +.swagger-section pre .tag .title, +.swagger-section pre .lisp .title, +.swagger-section pre .clojure .built_in, +.swagger-section pre .nginx .title { + color: black; +} +.swagger-section pre .string, +.swagger-section pre .title, +.swagger-section pre .constant, +.swagger-section pre .parent, +.swagger-section pre .tag .value, +.swagger-section pre .rules .value, +.swagger-section pre .rules .value .number, +.swagger-section pre .preprocessor, +.swagger-section pre .ruby .symbol, +.swagger-section pre .ruby .symbol .string, +.swagger-section pre .aggregate, +.swagger-section pre .template_tag, +.swagger-section pre .django .variable, +.swagger-section pre .smalltalk .class, +.swagger-section pre .addition, +.swagger-section pre .flow, +.swagger-section pre .stream, +.swagger-section pre .bash .variable, +.swagger-section pre .apache .tag, +.swagger-section pre .apache .cbracket, +.swagger-section pre .tex .command, +.swagger-section pre .tex .special, +.swagger-section pre .erlang_repl .function_or_atom, +.swagger-section pre .markdown .header { + color: #800; +} +.swagger-section pre .comment, +.swagger-section pre .annotation, +.swagger-section pre .template_comment, +.swagger-section pre .diff .header, +.swagger-section pre .chunk, +.swagger-section pre .markdown .blockquote { + color: #888; +} +.swagger-section pre .number, +.swagger-section pre .date, +.swagger-section pre .regexp, +.swagger-section pre .literal, +.swagger-section pre .smalltalk .symbol, +.swagger-section pre .smalltalk .char, +.swagger-section pre .go .constant, +.swagger-section pre .change, +.swagger-section pre .markdown .bullet, +.swagger-section pre .markdown .link_url { + color: #080; +} +.swagger-section pre .label, +.swagger-section pre .javadoc, +.swagger-section pre .ruby .string, +.swagger-section pre .decorator, +.swagger-section pre .filter .argument, +.swagger-section pre .localvars, +.swagger-section pre .array, +.swagger-section pre .attr_selector, +.swagger-section pre .important, +.swagger-section pre .pseudo, +.swagger-section pre .pi, +.swagger-section pre .doctype, +.swagger-section pre .deletion, +.swagger-section pre .envvar, +.swagger-section pre .shebang, +.swagger-section pre .apache .sqbracket, +.swagger-section pre .nginx .built_in, +.swagger-section pre .tex .formula, +.swagger-section pre .erlang_repl .reserved, +.swagger-section pre .prompt, +.swagger-section pre .markdown .link_label, +.swagger-section pre .vhdl .attribute, +.swagger-section pre .clojure .attribute, +.swagger-section pre .coffeescript .property { + color: #8888ff; +} +.swagger-section pre .keyword, +.swagger-section pre .id, +.swagger-section pre .phpdoc, +.swagger-section pre .title, +.swagger-section pre .built_in, +.swagger-section pre .aggregate, +.swagger-section pre .css .tag, +.swagger-section pre .javadoctag, +.swagger-section pre .phpdoc, +.swagger-section pre .yardoctag, +.swagger-section pre .smalltalk .class, +.swagger-section pre .winutils, +.swagger-section pre .bash .variable, +.swagger-section pre .apache .tag, +.swagger-section pre .go .typename, +.swagger-section pre .tex .command, +.swagger-section pre .markdown .strong, +.swagger-section pre .request, +.swagger-section pre .status { + font-weight: bold; +} +.swagger-section pre .markdown .emphasis { + font-style: italic; +} +.swagger-section pre .nginx .built_in { + font-weight: normal; +} +.swagger-section pre .coffeescript .javascript, +.swagger-section pre .javascript .xml, +.swagger-section pre .tex .formula, +.swagger-section pre .xml .javascript, +.swagger-section pre .xml .vbscript, +.swagger-section pre .xml .css, +.swagger-section pre .xml .cdata { + opacity: 0.5; +} +.swagger-section .swagger-ui-wrap { + line-height: 1; + font-family: "Droid Sans", sans-serif; + max-width: 960px; + margin-left: auto; + margin-right: auto; + /* JSONEditor specific styling */ +} +.swagger-section .swagger-ui-wrap b, +.swagger-section .swagger-ui-wrap strong { + font-family: "Droid Sans", sans-serif; + font-weight: bold; +} +.swagger-section .swagger-ui-wrap q, +.swagger-section .swagger-ui-wrap blockquote { + quotes: none; +} +.swagger-section .swagger-ui-wrap p { + line-height: 1.4em; + padding: 0 0 10px; + color: #333333; +} +.swagger-section .swagger-ui-wrap q:before, +.swagger-section .swagger-ui-wrap q:after, +.swagger-section .swagger-ui-wrap blockquote:before, +.swagger-section .swagger-ui-wrap blockquote:after { + content: none; +} +.swagger-section .swagger-ui-wrap .heading_with_menu h1, +.swagger-section .swagger-ui-wrap .heading_with_menu h2, +.swagger-section .swagger-ui-wrap .heading_with_menu h3, +.swagger-section .swagger-ui-wrap .heading_with_menu h4, +.swagger-section .swagger-ui-wrap .heading_with_menu h5, +.swagger-section .swagger-ui-wrap .heading_with_menu h6 { + display: block; + clear: none; + float: left; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + -ms-box-sizing: border-box; + box-sizing: border-box; + width: 60%; +} +.swagger-section .swagger-ui-wrap table { + border-collapse: collapse; + border-spacing: 0; +} +.swagger-section .swagger-ui-wrap table thead tr th { + padding: 5px; + font-size: 0.9em; + color: #666666; + border-bottom: 1px solid #999999; +} +.swagger-section .swagger-ui-wrap table tbody tr:last-child td { + border-bottom: none; +} +.swagger-section .swagger-ui-wrap table tbody tr.offset { + background-color: #f0f0f0; +} +.swagger-section .swagger-ui-wrap table tbody tr td { + padding: 6px; + font-size: 0.9em; + border-bottom: 1px solid #cccccc; + vertical-align: top; + line-height: 1.3em; +} +.swagger-section .swagger-ui-wrap ol { + margin: 0px 0 10px; + padding: 0 0 0 18px; + list-style-type: decimal; +} +.swagger-section .swagger-ui-wrap ol li { + padding: 5px 0px; + font-size: 0.9em; + color: #333333; +} +.swagger-section .swagger-ui-wrap ol, +.swagger-section .swagger-ui-wrap ul { + list-style: none; +} +.swagger-section .swagger-ui-wrap h1 a, +.swagger-section .swagger-ui-wrap h2 a, +.swagger-section .swagger-ui-wrap h3 a, +.swagger-section .swagger-ui-wrap h4 a, +.swagger-section .swagger-ui-wrap h5 a, +.swagger-section .swagger-ui-wrap h6 a { + text-decoration: none; +} +.swagger-section .swagger-ui-wrap h1 a:hover, +.swagger-section .swagger-ui-wrap h2 a:hover, +.swagger-section .swagger-ui-wrap h3 a:hover, +.swagger-section .swagger-ui-wrap h4 a:hover, +.swagger-section .swagger-ui-wrap h5 a:hover, +.swagger-section .swagger-ui-wrap h6 a:hover { + text-decoration: underline; +} +.swagger-section .swagger-ui-wrap h1 span.divider, +.swagger-section .swagger-ui-wrap h2 span.divider, +.swagger-section .swagger-ui-wrap h3 span.divider, +.swagger-section .swagger-ui-wrap h4 span.divider, +.swagger-section .swagger-ui-wrap h5 span.divider, +.swagger-section .swagger-ui-wrap h6 span.divider { + color: #aaaaaa; +} +.swagger-section .swagger-ui-wrap a { + color: #547f00; +} +.swagger-section .swagger-ui-wrap a img { + border: none; +} +.swagger-section .swagger-ui-wrap article, +.swagger-section .swagger-ui-wrap aside, +.swagger-section .swagger-ui-wrap details, +.swagger-section .swagger-ui-wrap figcaption, +.swagger-section .swagger-ui-wrap figure, +.swagger-section .swagger-ui-wrap footer, +.swagger-section .swagger-ui-wrap header, +.swagger-section .swagger-ui-wrap hgroup, +.swagger-section .swagger-ui-wrap menu, +.swagger-section .swagger-ui-wrap nav, +.swagger-section .swagger-ui-wrap section, +.swagger-section .swagger-ui-wrap summary { + display: block; +} +.swagger-section .swagger-ui-wrap pre { + font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; + background-color: #fcf6db; + border: 1px solid #e5e0c6; + padding: 10px; +} +.swagger-section .swagger-ui-wrap pre code { + line-height: 1.6em; + background: none; +} +.swagger-section .swagger-ui-wrap .content > .content-type > div > label { + clear: both; + display: block; + color: #0F6AB4; + font-size: 1.1em; + margin: 0; + padding: 15px 0 5px; +} +.swagger-section .swagger-ui-wrap .content pre { + font-size: 12px; + margin-top: 5px; + padding: 5px; +} +.swagger-section .swagger-ui-wrap .icon-btn { + cursor: pointer; +} +.swagger-section .swagger-ui-wrap .info_title { + padding-bottom: 10px; + font-weight: bold; + font-size: 25px; +} +.swagger-section .swagger-ui-wrap .footer { + margin-top: 20px; +} +.swagger-section .swagger-ui-wrap p.big, +.swagger-section .swagger-ui-wrap div.big p { + font-size: 1em; + margin-bottom: 10px; +} +.swagger-section .swagger-ui-wrap form.fullwidth ol li.string input, +.swagger-section .swagger-ui-wrap form.fullwidth ol li.url input, +.swagger-section .swagger-ui-wrap form.fullwidth ol li.text textarea, +.swagger-section .swagger-ui-wrap form.fullwidth ol li.numeric input { + width: 500px !important; +} +.swagger-section .swagger-ui-wrap .info_license { + padding-bottom: 5px; +} +.swagger-section .swagger-ui-wrap .info_tos { + padding-bottom: 5px; +} +.swagger-section .swagger-ui-wrap .message-fail { + color: #cc0000; +} +.swagger-section .swagger-ui-wrap .info_url { + padding-bottom: 5px; +} +.swagger-section .swagger-ui-wrap .info_email { + padding-bottom: 5px; +} +.swagger-section .swagger-ui-wrap .info_name { + padding-bottom: 5px; +} +.swagger-section .swagger-ui-wrap .info_description { + padding-bottom: 10px; + font-size: 15px; +} +.swagger-section .swagger-ui-wrap .markdown ol li, +.swagger-section .swagger-ui-wrap .markdown ul li { + padding: 3px 0px; + line-height: 1.4em; + color: #333333; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.string input, +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.url input, +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.numeric input { + display: block; + padding: 4px; + width: auto; + clear: both; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.string input.title, +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.url input.title, +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.numeric input.title { + font-size: 1.3em; +} +.swagger-section .swagger-ui-wrap table.fullwidth { + width: 100%; +} +.swagger-section .swagger-ui-wrap .model-signature { + font-family: "Droid Sans", sans-serif; + font-size: 1em; + line-height: 1.5em; +} +.swagger-section .swagger-ui-wrap .model-signature .signature-nav a { + text-decoration: none; + color: #AAA; +} +.swagger-section .swagger-ui-wrap .model-signature .signature-nav a:hover { + text-decoration: underline; + color: black; +} +.swagger-section .swagger-ui-wrap .model-signature .signature-nav .selected { + color: black; + text-decoration: none; +} +.swagger-section .swagger-ui-wrap .model-signature .propType { + color: #5555aa; +} +.swagger-section .swagger-ui-wrap .model-signature pre:hover { + background-color: #ffffdd; +} +.swagger-section .swagger-ui-wrap .model-signature pre { + font-size: .85em; + line-height: 1.2em; + overflow: auto; + max-height: 200px; + cursor: pointer; +} +.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav { + display: block; + margin: 0; + padding: 0; +} +.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav li:last-child { + padding-right: 0; + border-right: none; +} +.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav li { + float: left; + margin: 0 5px 5px 0; + padding: 2px 5px 2px 0; + border-right: 1px solid #ddd; +} +.swagger-section .swagger-ui-wrap .model-signature .propOpt { + color: #555; +} +.swagger-section .swagger-ui-wrap .model-signature .snippet small { + font-size: 0.75em; +} +.swagger-section .swagger-ui-wrap .model-signature .propOptKey { + font-style: italic; +} +.swagger-section .swagger-ui-wrap .model-signature .description .strong { + font-weight: bold; + color: #000; + font-size: .9em; +} +.swagger-section .swagger-ui-wrap .model-signature .description div { + font-size: 0.9em; + line-height: 1.5em; + margin-left: 1em; +} +.swagger-section .swagger-ui-wrap .model-signature .description .stronger { + font-weight: bold; + color: #000; +} +.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper { + border-spacing: 0; + position: absolute; + background-color: #ffffff; + border: 1px solid #bbbbbb; + display: none; + font-size: 11px; + max-width: 400px; + line-height: 30px; + color: black; + padding: 5px; + margin-left: 10px; +} +.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper th { + text-align: center; + background-color: #eeeeee; + border: 1px solid #bbbbbb; + font-size: 11px; + color: #666666; + font-weight: bold; + padding: 5px; + line-height: 15px; +} +.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper .optionName { + font-weight: bold; +} +.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown > p:first-child, +.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown > p:last-child { + display: inline; +} +.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown > p:not(:first-child):before { + display: block; + content: ''; +} +.swagger-section .swagger-ui-wrap .model-signature .description span:last-of-type.propDesc.markdown > p:only-child { + margin-right: -3px; +} +.swagger-section .swagger-ui-wrap .model-signature .propName { + font-weight: bold; +} +.swagger-section .swagger-ui-wrap .model-signature .signature-container { + clear: both; +} +.swagger-section .swagger-ui-wrap .body-textarea { + width: 300px; + height: 100px; + border: 1px solid #aaa; +} +.swagger-section .swagger-ui-wrap .markdown p code, +.swagger-section .swagger-ui-wrap .markdown li code { + font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; + background-color: #f0f0f0; + color: black; + padding: 1px 3px; +} +.swagger-section .swagger-ui-wrap .required { + font-weight: bold; +} +.swagger-section .swagger-ui-wrap .editor_holder { + font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; + font-size: 0.9em; +} +.swagger-section .swagger-ui-wrap .editor_holder label { + font-weight: normal!important; + /* JSONEditor uses bold by default for all labels, we revert that back to normal to not give the impression that by default fields are required */ +} +.swagger-section .swagger-ui-wrap .editor_holder label.required { + font-weight: bold!important; +} +.swagger-section .swagger-ui-wrap input.parameter { + width: 300px; + border: 1px solid #aaa; +} +.swagger-section .swagger-ui-wrap h1 { + color: black; + font-size: 1.5em; + line-height: 1.3em; + padding: 10px 0 10px 0; + font-family: "Droid Sans", sans-serif; + font-weight: bold; +} +.swagger-section .swagger-ui-wrap .heading_with_menu { + float: none; + clear: both; + overflow: hidden; + display: block; +} +.swagger-section .swagger-ui-wrap .heading_with_menu ul { + display: block; + clear: none; + float: right; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + -ms-box-sizing: border-box; + box-sizing: border-box; + margin-top: 10px; +} +.swagger-section .swagger-ui-wrap h2 { + color: black; + font-size: 1.3em; + padding: 10px 0 10px 0; +} +.swagger-section .swagger-ui-wrap h2 a { + color: black; +} +.swagger-section .swagger-ui-wrap h2 span.sub { + font-size: 0.7em; + color: #999999; + font-style: italic; +} +.swagger-section .swagger-ui-wrap h2 span.sub a { + color: #777777; +} +.swagger-section .swagger-ui-wrap span.weak { + color: #666666; +} +.swagger-section .swagger-ui-wrap .message-success { + color: #89BF04; +} +.swagger-section .swagger-ui-wrap caption, +.swagger-section .swagger-ui-wrap th, +.swagger-section .swagger-ui-wrap td { + text-align: left; + font-weight: normal; + vertical-align: middle; +} +.swagger-section .swagger-ui-wrap .code { + font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.text textarea { + font-family: "Droid Sans", sans-serif; + height: 250px; + padding: 4px; + display: block; + clear: both; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.select select { + display: block; + clear: both; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean { + float: none; + clear: both; + overflow: hidden; + display: block; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean label { + display: block; + float: left; + clear: none; + margin: 0; + padding: 0; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean input { + display: block; + float: left; + clear: none; + margin: 0 5px 0 0; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.required label { + color: black; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li label { + display: block; + clear: both; + width: auto; + padding: 0 0 3px; + color: #666666; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li label abbr { + padding-left: 3px; + color: #888888; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li p.inline-hints { + margin-left: 0; + font-style: italic; + font-size: 0.9em; + margin: 0; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.buttons { + margin: 0; + padding: 0; +} +.swagger-section .swagger-ui-wrap span.blank, +.swagger-section .swagger-ui-wrap span.empty { + color: #888888; + font-style: italic; +} +.swagger-section .swagger-ui-wrap .markdown h3 { + color: #547f00; +} +.swagger-section .swagger-ui-wrap .markdown h4 { + color: #666666; +} +.swagger-section .swagger-ui-wrap .markdown pre { + font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; + background-color: #fcf6db; + border: 1px solid #e5e0c6; + padding: 10px; + margin: 0 0 10px 0; +} +.swagger-section .swagger-ui-wrap .markdown pre code { + line-height: 1.6em; +} +.swagger-section .swagger-ui-wrap div.gist { + margin: 20px 0 25px 0 !important; +} +.swagger-section .swagger-ui-wrap ul#resources { + font-family: "Droid Sans", sans-serif; + font-size: 0.9em; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource { + border-bottom: 1px solid #dddddd; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource:hover div.heading h2 a, +.swagger-section .swagger-ui-wrap ul#resources li.resource.active div.heading h2 a { + color: black; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource:hover div.heading ul.options li a, +.swagger-section .swagger-ui-wrap ul#resources li.resource.active div.heading ul.options li a { + color: #555555; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource:last-child { + border-bottom: none; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading { + border: 1px solid transparent; + float: none; + clear: both; + overflow: hidden; + display: block; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options { + overflow: hidden; + padding: 0; + display: block; + clear: none; + float: right; + margin: 14px 10px 0 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li { + float: left; + clear: none; + margin: 0; + padding: 2px 10px; + border-right: 1px solid #dddddd; + color: #666666; + font-size: 0.9em; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a { + color: #aaaaaa; + text-decoration: none; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:hover { + text-decoration: underline; + color: black; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:hover, +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:active, +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a.active { + text-decoration: underline; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li:first-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li.first { + padding-left: 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li:last-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li.last { + padding-right: 0; + border-right: none; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options:first-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options.first { + padding-left: 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 { + color: #999999; + padding-left: 0; + display: block; + clear: none; + float: left; + font-family: "Droid Sans", sans-serif; + font-weight: bold; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a { + color: #999999; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a:hover { + color: black; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation { + float: none; + clear: both; + overflow: hidden; + display: block; + margin: 0 0 10px; + padding: 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading { + float: none; + clear: both; + overflow: hidden; + display: block; + margin: 0; + padding: 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 { + display: block; + clear: none; + float: left; + width: auto; + margin: 0; + padding: 0; + line-height: 1.1em; + color: black; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path { + padding-left: 10px; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a { + color: black; + text-decoration: none; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a:hover { + text-decoration: underline; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.http_method a { + text-transform: uppercase; + text-decoration: none; + color: white; + display: inline-block; + width: 50px; + font-size: 0.7em; + text-align: center; + padding: 7px 0 4px; + -moz-border-radius: 2px; + -webkit-border-radius: 2px; + -o-border-radius: 2px; + -ms-border-radius: 2px; + -khtml-border-radius: 2px; + border-radius: 2px; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span { + margin: 0; + padding: 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options { + overflow: hidden; + padding: 0; + display: block; + clear: none; + float: right; + margin: 6px 10px 0 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li { + float: left; + clear: none; + margin: 0; + padding: 2px 10px; + font-size: 0.9em; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li a { + text-decoration: none; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li.access { + color: black; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content { + border-top: none; + padding: 10px; + -moz-border-radius-bottomleft: 6px; + -webkit-border-bottom-left-radius: 6px; + -o-border-bottom-left-radius: 6px; + -ms-border-bottom-left-radius: 6px; + -khtml-border-bottom-left-radius: 6px; + border-bottom-left-radius: 6px; + -moz-border-radius-bottomright: 6px; + -webkit-border-bottom-right-radius: 6px; + -o-border-bottom-right-radius: 6px; + -ms-border-bottom-right-radius: 6px; + -khtml-border-bottom-right-radius: 6px; + border-bottom-right-radius: 6px; + margin: 0 0 20px; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content h4 { + font-size: 1.1em; + margin: 0; + padding: 15px 0 5px; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header { + float: none; + clear: both; + overflow: hidden; + display: block; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header a { + padding: 4px 0 0 10px; + display: inline-block; + font-size: 0.9em; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header input.submit { + display: block; + clear: none; + float: left; + padding: 6px 8px; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header span.response_throbber { + background-image: url('../images/throbber.gif'); + width: 128px; + height: 16px; + display: block; + clear: none; + float: right; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content form input[type='text'].error { + outline: 2px solid black; + outline-color: #cc0000; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content form select[name='parameterContentType'] { + max-width: 300px; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.response div.block pre { + font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; + padding: 10px; + font-size: 0.9em; + max-height: 400px; + overflow-y: auto; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading { + background-color: #f9f2e9; + border: 1px solid #f0e0ca; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading h3 span.http_method a { + background-color: #c5862b; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li { + border-right: 1px solid #dddddd; + border-right-color: #f0e0ca; + color: #c5862b; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li a { + color: #c5862b; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content { + background-color: #faf5ee; + border: 1px solid #f0e0ca; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content h4 { + color: #c5862b; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content div.sandbox_header a { + color: #dcb67f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading { + background-color: #fcffcd; + border: 1px solid black; + border-color: #ffd20f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading h3 span.http_method a { + text-transform: uppercase; + background-color: #ffd20f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li { + border-right: 1px solid #dddddd; + border-right-color: #ffd20f; + color: #ffd20f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li a { + color: #ffd20f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content { + background-color: #fcffcd; + border: 1px solid black; + border-color: #ffd20f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content h4 { + color: #ffd20f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content div.sandbox_header a { + color: #6fc992; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading { + background-color: #f5e8e8; + border: 1px solid #e8c6c7; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading h3 span.http_method a { + text-transform: uppercase; + background-color: #a41e22; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li { + border-right: 1px solid #dddddd; + border-right-color: #e8c6c7; + color: #a41e22; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li a { + color: #a41e22; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content { + background-color: #f7eded; + border: 1px solid #e8c6c7; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content h4 { + color: #a41e22; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content div.sandbox_header a { + color: #c8787a; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading { + background-color: #e7f6ec; + border: 1px solid #c3e8d1; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading h3 span.http_method a { + background-color: #10a54a; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li { + border-right: 1px solid #dddddd; + border-right-color: #c3e8d1; + color: #10a54a; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li a { + color: #10a54a; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content { + background-color: #ebf7f0; + border: 1px solid #c3e8d1; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content h4 { + color: #10a54a; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content div.sandbox_header a { + color: #6fc992; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading { + background-color: #FCE9E3; + border: 1px solid #F5D5C3; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading h3 span.http_method a { + background-color: #D38042; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li { + border-right: 1px solid #dddddd; + border-right-color: #f0cecb; + color: #D38042; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li a { + color: #D38042; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content { + background-color: #faf0ef; + border: 1px solid #f0cecb; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content h4 { + color: #D38042; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content div.sandbox_header a { + color: #dcb67f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading { + background-color: #e7f0f7; + border: 1px solid #c3d9ec; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading h3 span.http_method a { + background-color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li { + border-right: 1px solid #dddddd; + border-right-color: #c3d9ec; + color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li a { + color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content { + background-color: #ebf3f9; + border: 1px solid #c3d9ec; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content h4 { + color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content div.sandbox_header a { + color: #6fa5d2; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading { + background-color: #e7f0f7; + border: 1px solid #c3d9ec; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading h3 span.http_method a { + background-color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading ul.options li { + border-right: 1px solid #dddddd; + border-right-color: #c3d9ec; + color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading ul.options li a { + color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content { + background-color: #ebf3f9; + border: 1px solid #c3d9ec; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content h4 { + color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content div.sandbox_header a { + color: #6fa5d2; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content { + border-top: none; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li:last-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li:last-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li:last-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li:last-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li:last-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li:last-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li.last, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li.last, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li.last, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li.last, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li.last, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li.last { + padding-right: 0; + border-right: none; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a:hover, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a:active, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a.active { + text-decoration: underline; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li:first-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li.first { + padding-left: 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations:first-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations.first { + padding-left: 0; +} +.swagger-section .swagger-ui-wrap p#colophon { + margin: 0 15px 40px 15px; + padding: 10px 0; + font-size: 0.8em; + border-top: 1px solid #dddddd; + font-family: "Droid Sans", sans-serif; + color: #999999; + font-style: italic; +} +.swagger-section .swagger-ui-wrap p#colophon a { + text-decoration: none; + color: #547f00; +} +.swagger-section .swagger-ui-wrap h3 { + color: black; + font-size: 1.1em; + padding: 10px 0 10px 0; +} +.swagger-section .swagger-ui-wrap .markdown ol, +.swagger-section .swagger-ui-wrap .markdown ul { + font-family: "Droid Sans", sans-serif; + margin: 5px 0 10px; + padding: 0 0 0 18px; + list-style-type: disc; +} +.swagger-section .swagger-ui-wrap form.form_box { + background-color: #ebf3f9; + border: 1px solid #c3d9ec; + padding: 10px; +} +.swagger-section .swagger-ui-wrap form.form_box label { + color: #0f6ab4 !important; +} +.swagger-section .swagger-ui-wrap form.form_box input[type=submit] { + display: block; + padding: 10px; +} +.swagger-section .swagger-ui-wrap form.form_box p.weak { + font-size: 0.8em; +} +.swagger-section .swagger-ui-wrap form.form_box p { + font-size: 0.9em; + padding: 0 0 15px; + color: #7e7b6d; +} +.swagger-section .swagger-ui-wrap form.form_box p a { + color: #646257; +} +.swagger-section .swagger-ui-wrap form.form_box p strong { + color: black; +} +.swagger-section .swagger-ui-wrap .operation-status td.markdown > p:last-child { + padding-bottom: 0; +} +.swagger-section .title { + font-style: bold; +} +.swagger-section .secondary_form { + display: none; +} +.swagger-section .main_image { + display: block; + margin-left: auto; + margin-right: auto; +} +.swagger-section .oauth_body { + margin-left: 100px; + margin-right: 100px; +} +.swagger-section .oauth_submit { + text-align: center; +} +.swagger-section .api-popup-dialog { + z-index: 10000; + position: absolute; + width: 500px; + background: #FFF; + padding: 20px; + border: 1px solid #ccc; + border-radius: 5px; + display: none; + font-size: 13px; + color: #777; +} +.swagger-section .api-popup-dialog .api-popup-title { + font-size: 24px; + padding: 10px 0; +} +.swagger-section .api-popup-dialog .api-popup-title { + font-size: 24px; + padding: 10px 0; +} +.swagger-section .api-popup-dialog .error-msg { + padding-left: 5px; + padding-bottom: 5px; +} +.swagger-section .api-popup-dialog .api-popup-authbtn { + height: 30px; +} +.swagger-section .api-popup-dialog .api-popup-cancel { + height: 30px; +} +.swagger-section .api-popup-scopes { + padding: 10px 20px; +} +.swagger-section .api-popup-scopes li { + padding: 5px 0; + line-height: 20px; +} +.swagger-section .api-popup-scopes li input { + position: relative; + top: 2px; +} +.swagger-section .api-popup-scopes .api-scope-desc { + padding-left: 20px; + font-style: italic; +} +.swagger-section .api-popup-actions { + padding-top: 10px; +} +#header { + display: none; +} +.swagger-section .swagger-ui-wrap .model-signature pre { + max-height: none; +} +.swagger-section .swagger-ui-wrap .body-textarea { + width: 100px; +} +.swagger-section .swagger-ui-wrap input.parameter { + width: 100px; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options { + display: none; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints { + display: block !important; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content { + display: block !important; +} diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/css/screen.css b/htdocs/includes/restler/framework/Luracast/Restler/explorer/css/screen.css index 478b99837d7..dc02468fdc0 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/explorer/css/screen.css +++ b/htdocs/includes/restler/framework/Luracast/Restler/explorer/css/screen.css @@ -126,6 +126,7 @@ max-width: 960px; margin-left: auto; margin-right: auto; + /* JSONEditor specific styling */ } .swagger-section .swagger-ui-wrap b, .swagger-section .swagger-ui-wrap strong { @@ -274,6 +275,9 @@ font-weight: bold; font-size: 25px; } +.swagger-section .swagger-ui-wrap .footer { + margin-top: 20px; +} .swagger-section .swagger-ui-wrap p.big, .swagger-section .swagger-ui-wrap div.big p { font-size: 1em; @@ -294,7 +298,13 @@ .swagger-section .swagger-ui-wrap .message-fail { color: #cc0000; } -.swagger-section .swagger-ui-wrap .info_contact { +.swagger-section .swagger-ui-wrap .info_url { + padding-bottom: 5px; +} +.swagger-section .swagger-ui-wrap .info_email { + padding-bottom: 5px; +} +.swagger-section .swagger-ui-wrap .info_name { padding-bottom: 5px; } .swagger-section .swagger-ui-wrap .info_description { @@ -350,7 +360,7 @@ font-size: .85em; line-height: 1.2em; overflow: auto; - max-height: 200px; + max-height: 400px; cursor: pointer; } .swagger-section .swagger-ui-wrap .model-signature ul.signature-nav { @@ -391,6 +401,43 @@ font-weight: bold; color: #000; } +.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper { + border-spacing: 0; + position: absolute; + background-color: #ffffff; + border: 1px solid #bbbbbb; + display: none; + font-size: 11px; + max-width: 400px; + line-height: 30px; + color: black; + padding: 5px; + margin-left: 10px; +} +.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper th { + text-align: center; + background-color: #eeeeee; + border: 1px solid #bbbbbb; + font-size: 11px; + color: #666666; + font-weight: bold; + padding: 5px; + line-height: 15px; +} +.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper .optionName { + font-weight: bold; +} +.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown > p:first-child, +.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown > p:last-child { + display: inline; +} +.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown > p:not(:first-child):before { + display: block; + content: ''; +} +.swagger-section .swagger-ui-wrap .model-signature .description span:last-of-type.propDesc.markdown > p:only-child { + margin-right: -3px; +} .swagger-section .swagger-ui-wrap .model-signature .propName { font-weight: bold; } @@ -412,6 +459,17 @@ .swagger-section .swagger-ui-wrap .required { font-weight: bold; } +.swagger-section .swagger-ui-wrap .editor_holder { + font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; + font-size: 0.9em; +} +.swagger-section .swagger-ui-wrap .editor_holder label { + font-weight: normal!important; + /* JSONEditor uses bold by default for all labels, we revert that back to normal to not give the impression that by default fields are required */ +} +.swagger-section .swagger-ui-wrap .editor_holder label.required { + font-weight: bold!important; +} .swagger-section .swagger-ui-wrap input.parameter { width: 300px; border: 1px solid #aaa; @@ -761,6 +819,9 @@ outline: 2px solid black; outline-color: #cc0000; } +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content form select[name='parameterContentType'] { + max-width: 300px; +} .swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.response div.block pre { font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; padding: 10px; @@ -1034,6 +1095,9 @@ .swagger-section .swagger-ui-wrap form.form_box p strong { color: black; } +.swagger-section .swagger-ui-wrap .operation-status td.markdown > p:last-child { + padding-bottom: 0; +} .swagger-section .title { font-style: bold; } @@ -1072,14 +1136,14 @@ font-size: 24px; padding: 10px 0; } -.swagger-section .api-popup-dialog p.error-msg { +.swagger-section .api-popup-dialog .error-msg { padding-left: 5px; padding-bottom: 5px; } -.swagger-section .api-popup-dialog button.api-popup-authbtn { +.swagger-section .api-popup-dialog .api-popup-authbtn { height: 30px; } -.swagger-section .api-popup-dialog button.api-popup-cancel { +.swagger-section .api-popup-dialog .api-popup-cancel { height: 30px; } .swagger-section .api-popup-scopes { @@ -1089,14 +1153,14 @@ padding: 5px 0; line-height: 20px; } -.swagger-section .api-popup-scopes .api-scope-desc { - padding-left: 20px; - font-style: italic; -} .swagger-section .api-popup-scopes li input { position: relative; top: 2px; } +.swagger-section .api-popup-scopes .api-scope-desc { + padding-left: 20px; + font-style: italic; +} .swagger-section .api-popup-actions { padding-top: 10px; } @@ -1106,8 +1170,16 @@ .swagger-section .auth { float: right; } -.swagger-section #api_information_panel { - position: absolute; +.swagger-section .api-ic { + height: 18px; + vertical-align: middle; + display: inline-block; + background: url(../images/explorer_icons.png) no-repeat; +} +.swagger-section .api-ic .api_information_panel { + position: relative; + margin-top: 20px; + margin-left: -5px; background: #FFF; border: 1px solid #ccc; border-radius: 5px; @@ -1118,34 +1190,32 @@ color: black; padding: 5px; } -.swagger-section #api_information_panel p .api-msg-enabled { +.swagger-section .api-ic .api_information_panel p .api-msg-enabled { color: green; } -.swagger-section #api_information_panel p .api-msg-disabled { +.swagger-section .api-ic .api_information_panel p .api-msg-disabled { color: red; } -.swagger-section .api-ic { - height: 18px; - vertical-align: middle; - display: inline-block; - background: url(../images/explorer_icons.png) no-repeat; +.swagger-section .api-ic:hover .api_information_panel { + position: absolute; + display: block; } .swagger-section .ic-info { background-position: 0 0; width: 18px; - margin-top: -7px; + margin-top: -6px; margin-left: 4px; } .swagger-section .ic-warning { background-position: -60px 0; width: 18px; - margin-top: -7px; + margin-top: -6px; margin-left: 4px; } .swagger-section .ic-error { background-position: -30px 0; width: 18px; - margin-top: -7px; + margin-top: -6px; margin-left: 4px; } .swagger-section .ic-off { @@ -1161,42 +1231,39 @@ cursor: pointer; } .swagger-section #header { - background-color: #89bf04; + background-color: #646257; padding: 14px; } -.swagger-section #header a#logo { - font-size: 1.5em; - font-weight: bold; - text-decoration: none; - background: transparent url(../images/logo_small.png) no-repeat left center; - padding: 20px 0 20px 40px; - color: white; +.swagger-section #input_baseUrl { + width: 400px; } -.swagger-section #header form#api_selector { +.swagger-section #api_selector { display: block; clear: none; float: right; } -.swagger-section #header form#api_selector .input { +.swagger-section #api_selector .input { display: block; clear: none; float: left; margin: 0 10px 0 0; } -.swagger-section #header form#api_selector .input input#input_apiKey { +.swagger-section #api_selector input { + font-size: 0.9em; + padding: 3px; + margin: 0; +} +.swagger-section #input_apiKey { width: 200px; } -.swagger-section #header form#api_selector .input input#input_baseUrl { - width: 400px; -} -.swagger-section #header form#api_selector .input a#explore { +.swagger-section #explore { display: block; text-decoration: none; font-weight: bold; padding: 6px 8px; font-size: 0.9em; color: white; - background-color: #547f00; + background-color: #000000; -moz-border-radius: 4px; -webkit-border-radius: 4px; -o-border-radius: 4px; @@ -1204,13 +1271,16 @@ -khtml-border-radius: 4px; border-radius: 4px; } -.swagger-section #header form#api_selector .input a#explore:hover { - background-color: #547f00; +.swagger-section #explore:hover { + background-color: #a41e22; } -.swagger-section #header form#api_selector .input input { - font-size: 0.9em; - padding: 3px; - margin: 0; +.swagger-section #header #logo { + font-size: 1.5em; + font-weight: bold; + text-decoration: none; + background: transparent url(../images/logo_small.png) no-repeat left center; + padding: 20px 0 20px 40px; + color: white; } .swagger-section #content_message { margin: 10px 15px; @@ -1222,3 +1292,13 @@ text-align: center; padding-top: 10px; } +.swagger-section .swagger-collapse:before { + content: "-"; +} +.swagger-section .swagger-expand:before { + content: "+"; +} + +#input_baseUrl { + display: none; +} diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/css/style.css b/htdocs/includes/restler/framework/Luracast/Restler/explorer/css/style.css new file mode 100644 index 00000000000..fc21a31db54 --- /dev/null +++ b/htdocs/includes/restler/framework/Luracast/Restler/explorer/css/style.css @@ -0,0 +1,250 @@ +.swagger-section #header a#logo { + font-size: 1.5em; + font-weight: bold; + text-decoration: none; + background: transparent url(../images/logo.png) no-repeat left center; + padding: 20px 0 20px 40px; +} +#text-head { + font-size: 80px; + font-family: 'Roboto', sans-serif; + color: #ffffff; + float: right; + margin-right: 20%; +} +.navbar-fixed-top .navbar-nav { + height: auto; +} +.navbar-fixed-top .navbar-brand { + height: auto; +} +.navbar-header { + height: auto; +} +.navbar-inverse { + background-color: #000; + border-color: #000; +} +#navbar-brand { + margin-left: 20%; +} +.navtext { + font-size: 10px; +} +.h1, +h1 { + font-size: 60px; +} +.navbar-default .navbar-header .navbar-brand { + color: #a2dfee; +} +/* tag titles */ +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a { + color: #393939; + font-family: 'Arvo', serif; + font-size: 1.5em; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a:hover { + color: black; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 { + color: #525252; + padding-left: 0px; + display: block; + clear: none; + float: left; + font-family: 'Arvo', serif; + font-weight: bold; +} +.navbar-default .navbar-collapse, +.navbar-default .navbar-form { + border-color: #0A0A0A; +} +.container1 { + width: 1500px; + margin: auto; + margin-top: 0; + background-image: url('../images/shield.png'); + background-repeat: no-repeat; + background-position: -40px -20px; + margin-bottom: 210px; +} +.container-inner { + width: 1200px; + margin: auto; + background-color: rgba(223, 227, 228, 0.75); + padding-bottom: 40px; + padding-top: 40px; + border-radius: 15px; +} +.header-content { + padding: 0; + width: 1000px; +} +.title1 { + font-size: 80px; + font-family: 'Vollkorn', serif; + color: #404040; + text-align: center; + padding-top: 40px; + padding-bottom: 100px; +} +#icon { + margin-top: -18px; +} +.subtext { + font-size: 25px; + font-style: italic; + color: #08b; + text-align: right; + padding-right: 250px; +} +.bg-primary { + background-color: #00468b; +} +.navbar-default .nav > li > a, +.navbar-default .nav > li > a:focus { + color: #08b; +} +.navbar-default .nav > li > a, +.navbar-default .nav > li > a:hover { + color: #08b; +} +.navbar-default .nav > li > a, +.navbar-default .nav > li > a:focus:hover { + color: #08b; +} +.text-faded { + font-size: 25px; + font-family: 'Vollkorn', serif; +} +.section-heading { + font-family: 'Vollkorn', serif; + font-size: 45px; + padding-bottom: 10px; +} +hr { + border-color: #00468b; + padding-bottom: 10px; +} +.description { + margin-top: 20px; + padding-bottom: 200px; +} +.description li { + font-family: 'Vollkorn', serif; + font-size: 25px; + color: #525252; + margin-left: 28%; + padding-top: 5px; +} +.gap { + margin-top: 200px; +} +.troubleshootingtext { + color: rgba(255, 255, 255, 0.7); + padding-left: 30%; +} +.troubleshootingtext li { + list-style-type: circle; + font-size: 25px; + padding-bottom: 5px; +} +.overlay { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 1000; +} +.block.response_body.json:hover { + cursor: pointer; +} +.backdrop { + color: blue; +} +#myModal { + height: 100%; +} +.modal-backdrop { + bottom: 0; + position: fixed; +} +.curl { + padding: 10px; + font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; + font-size: 0.9em; + max-height: 400px; + margin-top: 5px; + overflow-y: auto; + background-color: #fcf6db; + border: 1px solid #e5e0c6; + border-radius: 4px; +} +.curl_title { + font-size: 1.1em; + margin: 0; + padding: 15px 0 5px; + font-family: 'Open Sans', 'Helvetica Neue', Arial, sans-serif; + font-weight: 500; + line-height: 1.1; +} +.footer { + display: none; +} +.swagger-section .swagger-ui-wrap h2 { + padding: 0; +} +h2 { + margin: 0; + margin-bottom: 5px; +} +.markdown p { + font-size: 15px; + font-family: 'Arvo', serif; +} +.swagger-section .swagger-ui-wrap .code { + font-size: 15px; + font-family: 'Arvo', serif; +} +.swagger-section .swagger-ui-wrap b { + font-family: 'Arvo', serif; +} +#signin:hover { + cursor: pointer; +} +.dropdown-menu { + padding: 15px; +} +.navbar-right .dropdown-menu { + left: 0; + right: auto; +} +#signinbutton { + width: 100%; + height: 32px; + font-size: 13px; + font-weight: bold; + color: #08b; +} +.navbar-default .nav > li .details { + color: #000000; + text-transform: none; + font-size: 15px; + font-weight: normal; + font-family: 'Open Sans', sans-serif; + font-style: italic; + line-height: 20px; + top: -2px; +} +.navbar-default .nav > li .details:hover { + color: black; +} +#signout { + width: 100%; + height: 32px; + font-size: 13px; + font-weight: bold; + color: #08b; +} diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/css/typography.css b/htdocs/includes/restler/framework/Luracast/Restler/explorer/css/typography.css new file mode 100644 index 00000000000..3235edd9503 --- /dev/null +++ b/htdocs/includes/restler/framework/Luracast/Restler/explorer/css/typography.css @@ -0,0 +1,14 @@ +/* Google Font's Droid Sans */ +@font-face { + font-family: 'Droid Sans'; + font-style: normal; + font-weight: 400; + src: local('Droid Sans'), local('DroidSans'), url('../fonts/DroidSans.ttf') format('truetype'); +} +/* Google Font's Droid Sans Bold */ +@font-face { + font-family: 'Droid Sans'; + font-style: normal; + font-weight: 700; + src: local('Droid Sans Bold'), local('DroidSans-Bold'), url('../fonts/DroidSans-Bold.ttf') format('truetype'); +} diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/fonts/DroidSans-Bold.ttf b/htdocs/includes/restler/framework/Luracast/Restler/explorer/fonts/DroidSans-Bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..942bbf5ba3aa04288175d094bc9c11d109c5726c GIT binary patch literal 42480 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 literal 0 HcmV?d00001 diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/fonts/DroidSans.ttf b/htdocs/includes/restler/framework/Luracast/Restler/explorer/fonts/DroidSans.ttf new file mode 100644 index 0000000000000000000000000000000000000000..efd1f8bbd882a6a434159fa1da7238babbaa2fb3 GIT binary patch literal 41028 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 literal 0 HcmV?d00001 diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/images/collapse.gif b/htdocs/includes/restler/framework/Luracast/Restler/explorer/images/collapse.gif new file mode 100644 index 0000000000000000000000000000000000000000..8843e8ce5a46781defd33d5304a0cb4191e72546 GIT binary patch literal 69 zcmZ?wbhEHbwd`J-OQ1PRqNMh0sDWgikt literal 0 HcmV?d00001 diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/images/expand.gif b/htdocs/includes/restler/framework/Luracast/Restler/explorer/images/expand.gif new file mode 100644 index 0000000000000000000000000000000000000000..477bf13718dc56928f313ef6eeb1c2b1a47db69a GIT binary patch literal 73 zcmZ?wbhEHb}?}J(t ztryNcu>M1Y8rg+jhiC`b|TlKDJ7A5P}ONxTFekIUo1iHR@_b6}X8z-4neaq(;x zi?xi&WX3QVOeUSdpfMQH0DAP2=x7>kN#s&mB#jmY{Hatjl}cGej_~+~FC>MBg@u4M z0d3%>RmwaX5>H-%K)?s75kAbHVKzGqCvdr3jwf$CNX=%mLH4*fR$MF-IIvhTK*Qs} zc&`B*fC&(oHSuTw6Ut%=DBEo1B7g~r6y_lW6xmbe1>gsOQm@i#bTX-0z>}vWNxAVL zBUl<3X_89~QW2V*l+K3{4m(dFH7le!GO-B}7)AW76n>_Fmn{)xBZ4BCxG)vTmk0|a zh#3*&A%a{{a=J+L!dz{q}EO5*5<5lFX ztT~aF-W=wwXlAasy!KA#{!_vCc8`r){wOYAfK|}Zg9PJbxS`Drk;)p~zY|Tt-88>* zwriWWb1zVDZtTG?paYc|7T*|z0vmc|>Drcq6j5NpMz|2?cHb`i@?uwOi^ zq83NCbnz;42Pc0dj34#(XLPH(clD@>^Tx(273Y3H^+xZ#{TS}&gSD83m-~j}1AOfv zMVs~g)RU1HH|1RUcD`si?r4G*GZO0OveK+}{)fDYSTMi+hjRZR>cge1S zR@On$u^Zq1me^ji^p@q(E2tfBTvg3>Jq*E-5aaR-qd1lcM;WU z`vf>j9jA6B>rS5l-}&OHq0;I0;+3!cMzi&fqek1LqNjZyefrl8q?U<>9#!evrstg< z9UZRNU`5UKvUD!GPtvYGoKo%T9HASStIj)gc|l1glldggnPy|@c4zEtP{iK5USC1K ziz=MEGQLy=x@c#Hg$F8HUC&hyzUtY|{)^#UHYzzVSzcQ3^7e(a`*rm1RIaV^#o0IS z_w{vkWbY|374IK1=xA3vqFX{vwfG#EEU9>G9xCaaa>Z+G%+t}diAF+FEzVq};smoa zbi)HvbN`b!s}nDrr&Ia{2953Bcl~x&Cvp!-BYU1?)gSHc36Gp-R=&RcbjO;eQEGE& ta!w9m(NDOMo}d5m!&kLnqYQAv9LOHZ7#!&yyal!|q>!SLGf3{ne*t=UPFDZ` delta 757 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 + Api Explorer - + - - + + - + - - - + + + + + + + + @@ -87,22 +128,14 @@ -
 
+
 
diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/en.js b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/en.js new file mode 100644 index 00000000000..9ccd65ad1d7 --- /dev/null +++ b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/en.js @@ -0,0 +1,55 @@ +'use strict'; + +/* jshint quotmark: double */ +window.SwaggerTranslator.learn({ + "Warning: Deprecated":"Warning: Deprecated", + "Implementation Notes":"Implementation Notes", + "Response Class":"Response Class", + "Status":"Status", + "Parameters":"Parameters", + "Parameter":"Parameter", + "Value":"Value", + "Description":"Description", + "Parameter Type":"Parameter Type", + "Data Type":"Data Type", + "Response Messages":"Response Messages", + "HTTP Status Code":"HTTP Status Code", + "Reason":"Reason", + "Response Model":"Response Model", + "Request URL":"Request URL", + "Response Body":"Response Body", + "Response Code":"Response Code", + "Response Headers":"Response Headers", + "Hide Response":"Hide Response", + "Headers":"Headers", + "Try it out!":"Try it out!", + "Show/Hide":"Show/Hide", + "List Operations":"List Operations", + "Expand Operations":"Expand Operations", + "Raw":"Raw", + "can't parse JSON. Raw result":"can't parse JSON. Raw result", + "Model Schema":"Model Schema", + "Model":"Model", + "Click to set as parameter value":"Click to set as parameter value", + "apply":"apply", + "Username":"Username", + "Password":"Password", + "Terms of service":"Terms of service", + "Created by":"Created by", + "See more at":"See more at", + "Contact the developer":"Contact the developer", + "api version":"api version", + "Response Content Type":"Response Content Type", + "Parameter content type:":"Parameter content type:", + "fetching resource":"fetching resource", + "fetching resource list":"fetching resource list", + "Explore":"Explore", + "Show Swagger Petstore Example Apis":"Show Swagger Petstore Example Apis", + "Can't read from server. It may not have the appropriate access-control-origin settings.":"Can't read from server. It may not have the appropriate access-control-origin settings.", + "Please specify the protocol for":"Please specify the protocol for", + "Can't read swagger JSON from":"Can't read swagger JSON from", + "Finished Loading Resource Information. Rendering Swagger UI":"Finished Loading Resource Information. Rendering Swagger UI", + "Unable to read api":"Unable to read api", + "from path":"from path", + "server returned":"server returned" +}); diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/es.js b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/es.js new file mode 100644 index 00000000000..a8dff60b6a9 --- /dev/null +++ b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/es.js @@ -0,0 +1,52 @@ +'use strict'; + +/* jshint quotmark: double */ +window.SwaggerTranslator.learn({ + "Warning: Deprecated":"Advertencia: Obsoleto", + "Implementation Notes":"Notas de implementación", + "Response Class":"Clase de la Respuesta", + "Status":"Status", + "Parameters":"Parámetros", + "Parameter":"Parámetro", + "Value":"Valor", + "Description":"Descripción", + "Parameter Type":"Tipo del Parámetro", + "Data Type":"Tipo del Dato", + "Response Messages":"Mensajes de la Respuesta", + "HTTP Status Code":"Código de Status HTTP", + "Reason":"Razón", + "Response Model":"Modelo de la Respuesta", + "Request URL":"URL de la Solicitud", + "Response Body":"Cuerpo de la Respuesta", + "Response Code":"Código de la Respuesta", + "Response Headers":"Encabezados de la Respuesta", + "Hide Response":"Ocultar Respuesta", + "Try it out!":"Pruébalo!", + "Show/Hide":"Mostrar/Ocultar", + "List Operations":"Listar Operaciones", + "Expand Operations":"Expandir Operaciones", + "Raw":"Crudo", + "can't parse JSON. Raw result":"no puede parsear el JSON. Resultado crudo", + "Model Schema":"Esquema del Modelo", + "Model":"Modelo", + "apply":"aplicar", + "Username":"Nombre de usuario", + "Password":"Contraseña", + "Terms of service":"Términos de Servicio", + "Created by":"Creado por", + "See more at":"Ver más en", + "Contact the developer":"Contactar al desarrollador", + "api version":"versión de la api", + "Response Content Type":"Tipo de Contenido (Content Type) de la Respuesta", + "fetching resource":"buscando recurso", + "fetching resource list":"buscando lista del recurso", + "Explore":"Explorar", + "Show Swagger Petstore Example Apis":"Mostrar Api Ejemplo de Swagger Petstore", + "Can't read from server. It may not have the appropriate access-control-origin settings.":"No se puede leer del servidor. Tal vez no tiene la configuración de control de acceso de origen (access-control-origin) apropiado.", + "Please specify the protocol for":"Por favor, especificar el protocola para", + "Can't read swagger JSON from":"No se puede leer el JSON de swagger desde", + "Finished Loading Resource Information. Rendering Swagger UI":"Finalizada la carga del recurso de Información. Mostrando Swagger UI", + "Unable to read api":"No se puede leer la api", + "from path":"desde ruta", + "server returned":"el servidor retornó" +}); diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/fr.js b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/fr.js new file mode 100644 index 00000000000..2e095ad0948 --- /dev/null +++ b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/fr.js @@ -0,0 +1,53 @@ +'use strict'; + +/* jshint quotmark: double */ +window.SwaggerTranslator.learn({ + "Warning: Deprecated":"Avertissement : Obsolète", + "Implementation Notes":"Notes d'implementation", + "Response Class":"Classe de la réponse", + "Status":"Statut", + "Parameters":"Paramètres", + "Parameter":"Paramètre", + "Value":"Valeur", + "Description":"Description", + "Parameter Type":"Type du paramètre", + "Data Type":"Type de données", + "Response Messages":"Messages de la réponse", + "HTTP Status Code":"Code de statut HTTP", + "Reason":"Raison", + "Response Model":"Modèle de réponse", + "Request URL":"URL appelée", + "Response Body":"Corps de la réponse", + "Response Code":"Code de la réponse", + "Response Headers":"En-têtes de la réponse", + "Hide Response":"Cacher la réponse", + "Headers":"En-têtes", + "Try it out!":"Testez !", + "Show/Hide":"Afficher/Masquer", + "List Operations":"Liste des opérations", + "Expand Operations":"Développer les opérations", + "Raw":"Brut", + "can't parse JSON. Raw result":"impossible de décoder le JSON. Résultat brut", + "Model Schema":"Définition du modèle", + "Model":"Modèle", + "apply":"appliquer", + "Username":"Nom d'utilisateur", + "Password":"Mot de passe", + "Terms of service":"Conditions de service", + "Created by":"Créé par", + "See more at":"Voir plus sur", + "Contact the developer":"Contacter le développeur", + "api version":"version de l'api", + "Response Content Type":"Content Type de la réponse", + "fetching resource":"récupération de la ressource", + "fetching resource list":"récupération de la liste de ressources", + "Explore":"Explorer", + "Show Swagger Petstore Example Apis":"Montrer les Apis de l'exemple Petstore de Swagger", + "Can't read from server. It may not have the appropriate access-control-origin settings.":"Impossible de lire à partir du serveur. Il se peut que les réglages access-control-origin ne soient pas appropriés.", + "Please specify the protocol for":"Veuillez spécifier un protocole pour", + "Can't read swagger JSON from":"Impossible de lire le JSON swagger à partir de", + "Finished Loading Resource Information. Rendering Swagger UI":"Chargement des informations terminé. Affichage de Swagger UI", + "Unable to read api":"Impossible de lire l'api", + "from path":"à partir du chemin", + "server returned":"réponse du serveur" +}); diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/it.js b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/it.js new file mode 100644 index 00000000000..8529c2a90bc --- /dev/null +++ b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/it.js @@ -0,0 +1,52 @@ +'use strict'; + +/* jshint quotmark: double */ +window.SwaggerTranslator.learn({ + "Warning: Deprecated":"Attenzione: Deprecato", + "Implementation Notes":"Note di implementazione", + "Response Class":"Classe della risposta", + "Status":"Stato", + "Parameters":"Parametri", + "Parameter":"Parametro", + "Value":"Valore", + "Description":"Descrizione", + "Parameter Type":"Tipo di parametro", + "Data Type":"Tipo di dato", + "Response Messages":"Messaggi della risposta", + "HTTP Status Code":"Codice stato HTTP", + "Reason":"Motivo", + "Response Model":"Modello di risposta", + "Request URL":"URL della richiesta", + "Response Body":"Corpo della risposta", + "Response Code":"Oggetto della risposta", + "Response Headers":"Intestazioni della risposta", + "Hide Response":"Nascondi risposta", + "Try it out!":"Provalo!", + "Show/Hide":"Mostra/Nascondi", + "List Operations":"Mostra operazioni", + "Expand Operations":"Espandi operazioni", + "Raw":"Grezzo (raw)", + "can't parse JSON. Raw result":"non è possibile parsare il JSON. Risultato grezzo (raw).", + "Model Schema":"Schema del modello", + "Model":"Modello", + "apply":"applica", + "Username":"Nome utente", + "Password":"Password", + "Terms of service":"Condizioni del servizio", + "Created by":"Creato da", + "See more at":"Informazioni aggiuntive:", + "Contact the developer":"Contatta lo sviluppatore", + "api version":"versione api", + "Response Content Type":"Tipo di contenuto (content type) della risposta", + "fetching resource":"recuperando la risorsa", + "fetching resource list":"recuperando lista risorse", + "Explore":"Esplora", + "Show Swagger Petstore Example Apis":"Mostra le api di esempio di Swagger Petstore", + "Can't read from server. It may not have the appropriate access-control-origin settings.":"Non è possibile leggere dal server. Potrebbe non avere le impostazioni di controllo accesso origine (access-control-origin) appropriate.", + "Please specify the protocol for":"Si prega di specificare il protocollo per", + "Can't read swagger JSON from":"Impossibile leggere JSON swagger da:", + "Finished Loading Resource Information. Rendering Swagger UI":"Lettura informazioni risorse termianta. Swagger UI viene mostrata", + "Unable to read api":"Impossibile leggere la api", + "from path":"da cartella", + "server returned":"il server ha restituito" +}); diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/ja.js b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/ja.js new file mode 100644 index 00000000000..3207bfc0baf --- /dev/null +++ b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/ja.js @@ -0,0 +1,53 @@ +'use strict'; + +/* jshint quotmark: double */ +window.SwaggerTranslator.learn({ + "Warning: Deprecated":"警告: 廃止予定", + "Implementation Notes":"実装メモ", + "Response Class":"レスポンスクラス", + "Status":"ステータス", + "Parameters":"パラメータ群", + "Parameter":"パラメータ", + "Value":"値", + "Description":"説明", + "Parameter Type":"パラメータタイプ", + "Data Type":"データタイプ", + "Response Messages":"レスポンスメッセージ", + "HTTP Status Code":"HTTPステータスコード", + "Reason":"理由", + "Response Model":"レスポンスモデル", + "Request URL":"リクエストURL", + "Response Body":"レスポンスボディ", + "Response Code":"レスポンスコード", + "Response Headers":"レスポンスヘッダ", + "Hide Response":"レスポンスを隠す", + "Headers":"ヘッダ", + "Try it out!":"実際に実行!", + "Show/Hide":"表示/非表示", + "List Operations":"操作一覧", + "Expand Operations":"操作の展開", + "Raw":"Raw", + "can't parse JSON. Raw result":"JSONへ解釈できません. 未加工の結果", + "Model Schema":"モデルスキーマ", + "Model":"モデル", + "apply":"実行", + "Username":"ユーザ名", + "Password":"パスワード", + "Terms of service":"サービス利用規約", + "Created by":"Created by", + "See more at":"See more at", + "Contact the developer":"開発者に連絡", + "api version":"APIバージョン", + "Response Content Type":"レスポンス コンテンツタイプ", + "fetching resource":"リソースの取得", + "fetching resource list":"リソース一覧の取得", + "Explore":"Explore", + "Show Swagger Petstore Example Apis":"SwaggerペットストアAPIの表示", + "Can't read from server. It may not have the appropriate access-control-origin settings.":"サーバから読み込めません. 適切なaccess-control-origin設定を持っていない可能性があります.", + "Please specify the protocol for":"プロトコルを指定してください", + "Can't read swagger JSON from":"次からswagger JSONを読み込めません", + "Finished Loading Resource Information. Rendering Swagger UI":"リソース情報の読み込みが完了しました. Swagger UIを描画しています", + "Unable to read api":"APIを読み込めません", + "from path":"次のパスから", + "server returned":"サーバからの返答" +}); diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/pl.js b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/pl.js new file mode 100644 index 00000000000..ce41e91799d --- /dev/null +++ b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/pl.js @@ -0,0 +1,53 @@ +'use strict'; + +/* jshint quotmark: double */ +window.SwaggerTranslator.learn({ + "Warning: Deprecated":"Uwaga: Wycofane", + "Implementation Notes":"Uwagi Implementacji", + "Response Class":"Klasa Odpowiedzi", + "Status":"Status", + "Parameters":"Parametry", + "Parameter":"Parametr", + "Value":"Wartość", + "Description":"Opis", + "Parameter Type":"Typ Parametru", + "Data Type":"Typ Danych", + "Response Messages":"Wiadomości Odpowiedzi", + "HTTP Status Code":"Kod Statusu HTTP", + "Reason":"Przyczyna", + "Response Model":"Model Odpowiedzi", + "Request URL":"URL Wywołania", + "Response Body":"Treść Odpowiedzi", + "Response Code":"Kod Odpowiedzi", + "Response Headers":"Nagłówki Odpowiedzi", + "Hide Response":"Ukryj Odpowiedź", + "Headers":"Nagłówki", + "Try it out!":"Wypróbuj!", + "Show/Hide":"Pokaż/Ukryj", + "List Operations":"Lista Operacji", + "Expand Operations":"Rozwiń Operacje", + "Raw":"Nieprzetworzone", + "can't parse JSON. Raw result":"nie można przetworzyć pliku JSON. Nieprzetworzone dane", + "Model Schema":"Schemat Modelu", + "Model":"Model", + "apply":"użyj", + "Username":"Nazwa użytkownika", + "Password":"Hasło", + "Terms of service":"Warunki używania", + "Created by":"Utworzone przez", + "See more at":"Zobacz więcej na", + "Contact the developer":"Kontakt z deweloperem", + "api version":"wersja api", + "Response Content Type":"Typ Zasobu Odpowiedzi", + "fetching resource":"ładowanie zasobu", + "fetching resource list":"ładowanie listy zasobów", + "Explore":"Eksploruj", + "Show Swagger Petstore Example Apis":"Pokaż Przykładowe Api Swagger Petstore", + "Can't read from server. It may not have the appropriate access-control-origin settings.":"Brak połączenia z serwerem. Może on nie mieć odpowiednich ustawień access-control-origin.", + "Please specify the protocol for":"Proszę podać protokół dla", + "Can't read swagger JSON from":"Nie można odczytać swagger JSON z", + "Finished Loading Resource Information. Rendering Swagger UI":"Ukończono Ładowanie Informacji o Zasobie. Renderowanie Swagger UI", + "Unable to read api":"Nie można odczytać api", + "from path":"ze ścieżki", + "server returned":"serwer zwrócił" +}); diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/pt.js b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/pt.js new file mode 100644 index 00000000000..f2e7c13d413 --- /dev/null +++ b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/pt.js @@ -0,0 +1,53 @@ +'use strict'; + +/* jshint quotmark: double */ +window.SwaggerTranslator.learn({ + "Warning: Deprecated":"Aviso: Depreciado", + "Implementation Notes":"Notas de Implementação", + "Response Class":"Classe de resposta", + "Status":"Status", + "Parameters":"Parâmetros", + "Parameter":"Parâmetro", + "Value":"Valor", + "Description":"Descrição", + "Parameter Type":"Tipo de parâmetro", + "Data Type":"Tipo de dados", + "Response Messages":"Mensagens de resposta", + "HTTP Status Code":"Código de status HTTP", + "Reason":"Razão", + "Response Model":"Modelo resposta", + "Request URL":"URL requisição", + "Response Body":"Corpo da resposta", + "Response Code":"Código da resposta", + "Response Headers":"Cabeçalho da resposta", + "Headers":"Cabeçalhos", + "Hide Response":"Esconder resposta", + "Try it out!":"Tente agora!", + "Show/Hide":"Mostrar/Esconder", + "List Operations":"Listar operações", + "Expand Operations":"Expandir operações", + "Raw":"Cru", + "can't parse JSON. Raw result":"Falha ao analisar JSON. Resulto cru", + "Model Schema":"Modelo esquema", + "Model":"Modelo", + "apply":"Aplicar", + "Username":"Usuário", + "Password":"Senha", + "Terms of service":"Termos do serviço", + "Created by":"Criado por", + "See more at":"Veja mais em", + "Contact the developer":"Contate o desenvolvedor", + "api version":"Versão api", + "Response Content Type":"Tipo de conteúdo da resposta", + "fetching resource":"busca recurso", + "fetching resource list":"buscando lista de recursos", + "Explore":"Explorar", + "Show Swagger Petstore Example Apis":"Show Swagger Petstore Example Apis", + "Can't read from server. It may not have the appropriate access-control-origin settings.":"Não é possível ler do servidor. Pode não ter as apropriadas configurações access-control-origin", + "Please specify the protocol for":"Por favor especifique o protocolo", + "Can't read swagger JSON from":"Não é possível ler o JSON Swagger de", + "Finished Loading Resource Information. Rendering Swagger UI":"Carregar informação de recurso finalizada. Renderizando Swagger UI", + "Unable to read api":"Não foi possível ler api", + "from path":"do caminho", + "server returned":"servidor retornou" +}); diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/ru.js b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/ru.js new file mode 100644 index 00000000000..381f1b3fd0d --- /dev/null +++ b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/ru.js @@ -0,0 +1,55 @@ +'use strict'; + +/* jshint quotmark: double */ +window.SwaggerTranslator.learn({ + "Warning: Deprecated":"Предупреждение: Устарело", + "Implementation Notes":"Заметки", + "Response Class":"Пример ответа", + "Status":"Статус", + "Parameters":"Параметры", + "Parameter":"Параметр", + "Value":"Значение", + "Description":"Описание", + "Parameter Type":"Тип параметра", + "Data Type":"Тип данных", + "HTTP Status Code":"HTTP код", + "Reason":"Причина", + "Response Model":"Структура ответа", + "Request URL":"URL запроса", + "Response Body":"Тело ответа", + "Response Code":"HTTP код ответа", + "Response Headers":"Заголовки ответа", + "Hide Response":"Спрятать ответ", + "Headers":"Заголовки", + "Response Messages":"Что может прийти в ответ", + "Try it out!":"Попробовать!", + "Show/Hide":"Показать/Скрыть", + "List Operations":"Операции кратко", + "Expand Operations":"Операции подробно", + "Raw":"В сыром виде", + "can't parse JSON. Raw result":"Не удается распарсить ответ:", + "Model Schema":"Структура", + "Model":"Описание", + "Click to set as parameter value":"Нажмите, чтобы испльзовать в качестве значения параметра", + "apply":"применить", + "Username":"Имя пользователя", + "Password":"Пароль", + "Terms of service":"Условия использования", + "Created by":"Разработано", + "See more at":"Еще тут", + "Contact the developer":"Связаться с разработчиком", + "api version":"Версия API", + "Response Content Type":"Content Type ответа", + "Parameter content type:":"Content Type параметра:", + "fetching resource":"Получение ресурса", + "fetching resource list":"Получение ресурсов", + "Explore":"Показать", + "Show Swagger Petstore Example Apis":"Показать примеры АПИ", + "Can't read from server. It may not have the appropriate access-control-origin settings.":"Не удается получить ответ от сервера. Возможно, проблема с настройками доступа", + "Please specify the protocol for":"Пожалуйста, укажите протокол для", + "Can't read swagger JSON from":"Не получается прочитать swagger json из", + "Finished Loading Resource Information. Rendering Swagger UI":"Загрузка информации о ресурсах завершена. Рендерим", + "Unable to read api":"Не удалось прочитать api", + "from path":"по адресу", + "server returned":"сервер сказал" +}); diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/tr.js b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/tr.js new file mode 100644 index 00000000000..16426a9c34b --- /dev/null +++ b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/tr.js @@ -0,0 +1,53 @@ +'use strict'; + +/* jshint quotmark: double */ +window.SwaggerTranslator.learn({ + "Warning: Deprecated":"Uyarı: Deprecated", + "Implementation Notes":"Gerçekleştirim Notları", + "Response Class":"Dönen Sınıf", + "Status":"Statü", + "Parameters":"Parametreler", + "Parameter":"Parametre", + "Value":"Değer", + "Description":"Açıklama", + "Parameter Type":"Parametre Tipi", + "Data Type":"Veri Tipi", + "Response Messages":"Dönüş Mesajı", + "HTTP Status Code":"HTTP Statü Kodu", + "Reason":"Gerekçe", + "Response Model":"Dönüş Modeli", + "Request URL":"İstek URL", + "Response Body":"Dönüş İçeriği", + "Response Code":"Dönüş Kodu", + "Response Headers":"Dönüş Üst Bilgileri", + "Hide Response":"Dönüşü Gizle", + "Headers":"Üst Bilgiler", + "Try it out!":"Dene!", + "Show/Hide":"Göster/Gizle", + "List Operations":"Operasyonları Listele", + "Expand Operations":"Operasyonları Aç", + "Raw":"Ham", + "can't parse JSON. Raw result":"JSON çözümlenemiyor. Ham sonuç", + "Model Schema":"Model Şema", + "Model":"Model", + "apply":"uygula", + "Username":"Kullanıcı Adı", + "Password":"Parola", + "Terms of service":"Servis şartları", + "Created by":"Oluşturan", + "See more at":"Daha fazlası için", + "Contact the developer":"Geliştirici ile İletişime Geçin", + "api version":"api versiyon", + "Response Content Type":"Dönüş İçerik Tipi", + "fetching resource":"kaynak getiriliyor", + "fetching resource list":"kaynak listesi getiriliyor", + "Explore":"Keşfet", + "Show Swagger Petstore Example Apis":"Swagger Petstore Örnek Api'yi Gör", + "Can't read from server. It may not have the appropriate access-control-origin settings.":"Sunucudan okuma yapılamıyor. Sunucu access-control-origin ayarlarınızı kontrol edin.", + "Please specify the protocol for":"Lütfen istenen adres için protokol belirtiniz", + "Can't read swagger JSON from":"Swagger JSON bu kaynaktan okunamıyor", + "Finished Loading Resource Information. Rendering Swagger UI":"Kaynak baglantısı tamamlandı. Swagger UI gösterime hazırlanıyor", + "Unable to read api":"api okunamadı", + "from path":"yoldan", + "server returned":"sunucuya dönüldü" +}); diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/translator.js b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/translator.js new file mode 100644 index 00000000000..591f6d40943 --- /dev/null +++ b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/translator.js @@ -0,0 +1,39 @@ +'use strict'; + +/** + * Translator for documentation pages. + * + * To enable translation you should include one of language-files in your index.html + * after . + * For example - + * + * If you wish to translate some new texsts you should do two things: + * 1. Add a new phrase pair ("New Phrase": "New Translation") into your language file (for example lang/ru.js). It will be great if you add it in other language files too. + * 2. Mark that text it templates this way New Phrase or . + * The main thing here is attribute data-sw-translate. Only inner html, title-attribute and value-attribute are going to translate. + * + */ +window.SwaggerTranslator = { + + _words:[], + + translate: function(sel) { + var $this = this; + sel = sel || '[data-sw-translate]'; + + $(sel).each(function() { + $(this).html($this._tryTranslate($(this).html())); + + $(this).val($this._tryTranslate($(this).val())); + $(this).attr('title', $this._tryTranslate($(this).attr('title'))); + }); + }, + + _tryTranslate: function(word) { + return this._words[$.trim(word)] !== undefined ? this._words[$.trim(word)] : word; + }, + + learn: function(wordsMap) { + this._words = wordsMap; + } +}; diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/zh-cn.js b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/zh-cn.js new file mode 100644 index 00000000000..570319ba156 --- /dev/null +++ b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/zh-cn.js @@ -0,0 +1,53 @@ +'use strict'; + +/* jshint quotmark: double */ +window.SwaggerTranslator.learn({ + "Warning: Deprecated":"警告:已过时", + "Implementation Notes":"实现备注", + "Response Class":"响应类", + "Status":"状态", + "Parameters":"参数", + "Parameter":"参数", + "Value":"值", + "Description":"描述", + "Parameter Type":"参数类型", + "Data Type":"数据类型", + "Response Messages":"响应消息", + "HTTP Status Code":"HTTP状态码", + "Reason":"原因", + "Response Model":"响应模型", + "Request URL":"请求URL", + "Response Body":"响应体", + "Response Code":"响应码", + "Response Headers":"响应头", + "Hide Response":"隐藏响应", + "Headers":"头", + "Try it out!":"试一下!", + "Show/Hide":"显示/隐藏", + "List Operations":"显示操作", + "Expand Operations":"展开操作", + "Raw":"原始", + "can't parse JSON. Raw result":"无法解析JSON. 原始结果", + "Model Schema":"模型架构", + "Model":"模型", + "apply":"应用", + "Username":"用户名", + "Password":"密码", + "Terms of service":"服务条款", + "Created by":"创建者", + "See more at":"查看更多:", + "Contact the developer":"联系开发者", + "api version":"api版本", + "Response Content Type":"响应Content Type", + "fetching resource":"正在获取资源", + "fetching resource list":"正在获取资源列表", + "Explore":"浏览", + "Show Swagger Petstore Example Apis":"显示 Swagger Petstore 示例 Apis", + "Can't read from server. It may not have the appropriate access-control-origin settings.":"无法从服务器读取。可能没有正确设置access-control-origin。", + "Please specify the protocol for":"请指定协议:", + "Can't read swagger JSON from":"无法读取swagger JSON于", + "Finished Loading Resource Information. Rendering Swagger UI":"已加载资源信息。正在渲染Swagger UI", + "Unable to read api":"无法读取api", + "from path":"从路径", + "server returned":"服务器返回" +}); diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/lib/backbone-min.js b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lib/backbone-min.js index c1c0d4fff28..a3f544be6d9 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/explorer/lib/backbone-min.js +++ b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lib/backbone-min.js @@ -1,38 +1,15 @@ -// Backbone.js 0.9.2 +// Backbone.js 1.1.2 -// (c) 2010-2012 Jeremy Ashkenas, DocumentCloud Inc. -// Backbone may be freely distributed under the MIT license. -// For all details and documentation: -// http://backbonejs.org -(function(){var l=this,y=l.Backbone,z=Array.prototype.slice,A=Array.prototype.splice,g;g="undefined"!==typeof exports?exports:l.Backbone={};g.VERSION="0.9.2";var f=l._;!f&&"undefined"!==typeof require&&(f=require("underscore"));var i=l.jQuery||l.Zepto||l.ender;g.setDomLibrary=function(a){i=a};g.noConflict=function(){l.Backbone=y;return this};g.emulateHTTP=!1;g.emulateJSON=!1;var p=/\s+/,k=g.Events={on:function(a,b,c){var d,e,f,g,j;if(!b)return this;a=a.split(p);for(d=this._callbacks||(this._callbacks= -{});e=a.shift();)f=(j=d[e])?j.tail:{},f.next=g={},f.context=c,f.callback=b,d[e]={tail:g,next:j?j.next:f};return this},off:function(a,b,c){var d,e,h,g,j,q;if(e=this._callbacks){if(!a&&!b&&!c)return delete this._callbacks,this;for(a=a?a.split(p):f.keys(e);d=a.shift();)if(h=e[d],delete e[d],h&&(b||c))for(g=h.tail;(h=h.next)!==g;)if(j=h.callback,q=h.context,b&&j!==b||c&&q!==c)this.on(d,j,q);return this}},trigger:function(a){var b,c,d,e,f,g;if(!(d=this._callbacks))return this;f=d.all;a=a.split(p);for(g= -z.call(arguments,1);b=a.shift();){if(c=d[b])for(e=c.tail;(c=c.next)!==e;)c.callback.apply(c.context||this,g);if(c=f){e=c.tail;for(b=[b].concat(g);(c=c.next)!==e;)c.callback.apply(c.context||this,b)}}return this}};k.bind=k.on;k.unbind=k.off;var o=g.Model=function(a,b){var c;a||(a={});b&&b.parse&&(a=this.parse(a));if(c=n(this,"defaults"))a=f.extend({},c,a);b&&b.collection&&(this.collection=b.collection);this.attributes={};this._escapedAttributes={};this.cid=f.uniqueId("c");this.changed={};this._silent= -{};this._pending={};this.set(a,{silent:!0});this.changed={};this._silent={};this._pending={};this._previousAttributes=f.clone(this.attributes);this.initialize.apply(this,arguments)};f.extend(o.prototype,k,{changed:null,_silent:null,_pending:null,idAttribute:"id",initialize:function(){},toJSON:function(){return f.clone(this.attributes)},get:function(a){return this.attributes[a]},escape:function(a){var b;if(b=this._escapedAttributes[a])return b;b=this.get(a);return this._escapedAttributes[a]=f.escape(null== -b?"":""+b)},has:function(a){return null!=this.get(a)},set:function(a,b,c){var d,e;f.isObject(a)||null==a?(d=a,c=b):(d={},d[a]=b);c||(c={});if(!d)return this;d instanceof o&&(d=d.attributes);if(c.unset)for(e in d)d[e]=void 0;if(!this._validate(d,c))return!1;this.idAttribute in d&&(this.id=d[this.idAttribute]);var b=c.changes={},h=this.attributes,g=this._escapedAttributes,j=this._previousAttributes||{};for(e in d){a=d[e];if(!f.isEqual(h[e],a)||c.unset&&f.has(h,e))delete g[e],(c.silent?this._silent: -b)[e]=!0;c.unset?delete h[e]:h[e]=a;!f.isEqual(j[e],a)||f.has(h,e)!=f.has(j,e)?(this.changed[e]=a,c.silent||(this._pending[e]=!0)):(delete this.changed[e],delete this._pending[e])}c.silent||this.change(c);return this},unset:function(a,b){(b||(b={})).unset=!0;return this.set(a,null,b)},clear:function(a){(a||(a={})).unset=!0;return this.set(f.clone(this.attributes),a)},fetch:function(a){var a=a?f.clone(a):{},b=this,c=a.success;a.success=function(d,e,f){if(!b.set(b.parse(d,f),a))return!1;c&&c(b,d)}; -a.error=g.wrapError(a.error,b,a);return(this.sync||g.sync).call(this,"read",this,a)},save:function(a,b,c){var d,e;f.isObject(a)||null==a?(d=a,c=b):(d={},d[a]=b);c=c?f.clone(c):{};if(c.wait){if(!this._validate(d,c))return!1;e=f.clone(this.attributes)}a=f.extend({},c,{silent:!0});if(d&&!this.set(d,c.wait?a:c))return!1;var h=this,i=c.success;c.success=function(a,b,e){b=h.parse(a,e);if(c.wait){delete c.wait;b=f.extend(d||{},b)}if(!h.set(b,c))return false;i?i(h,a):h.trigger("sync",h,a,c)};c.error=g.wrapError(c.error, -h,c);b=this.isNew()?"create":"update";b=(this.sync||g.sync).call(this,b,this,c);c.wait&&this.set(e,a);return b},destroy:function(a){var a=a?f.clone(a):{},b=this,c=a.success,d=function(){b.trigger("destroy",b,b.collection,a)};if(this.isNew())return d(),!1;a.success=function(e){a.wait&&d();c?c(b,e):b.trigger("sync",b,e,a)};a.error=g.wrapError(a.error,b,a);var e=(this.sync||g.sync).call(this,"delete",this,a);a.wait||d();return e},url:function(){var a=n(this,"urlRoot")||n(this.collection,"url")||t(); -return this.isNew()?a:a+("/"==a.charAt(a.length-1)?"":"/")+encodeURIComponent(this.id)},parse:function(a){return a},clone:function(){return new this.constructor(this.attributes)},isNew:function(){return null==this.id},change:function(a){a||(a={});var b=this._changing;this._changing=!0;for(var c in this._silent)this._pending[c]=!0;var d=f.extend({},a.changes,this._silent);this._silent={};for(c in d)this.trigger("change:"+c,this,this.get(c),a);if(b)return this;for(;!f.isEmpty(this._pending);){this._pending= -{};this.trigger("change",this,a);for(c in this.changed)!this._pending[c]&&!this._silent[c]&&delete this.changed[c];this._previousAttributes=f.clone(this.attributes)}this._changing=!1;return this},hasChanged:function(a){return!arguments.length?!f.isEmpty(this.changed):f.has(this.changed,a)},changedAttributes:function(a){if(!a)return this.hasChanged()?f.clone(this.changed):!1;var b,c=!1,d=this._previousAttributes,e;for(e in a)if(!f.isEqual(d[e],b=a[e]))(c||(c={}))[e]=b;return c},previous:function(a){return!arguments.length|| -!this._previousAttributes?null:this._previousAttributes[a]},previousAttributes:function(){return f.clone(this._previousAttributes)},isValid:function(){return!this.validate(this.attributes)},_validate:function(a,b){if(b.silent||!this.validate)return!0;var a=f.extend({},this.attributes,a),c=this.validate(a,b);if(!c)return!0;b&&b.error?b.error(this,c,b):this.trigger("error",this,c,b);return!1}});var r=g.Collection=function(a,b){b||(b={});b.model&&(this.model=b.model);b.comparator&&(this.comparator=b.comparator); -this._reset();this.initialize.apply(this,arguments);a&&this.reset(a,{silent:!0,parse:b.parse})};f.extend(r.prototype,k,{model:o,initialize:function(){},toJSON:function(a){return this.map(function(b){return b.toJSON(a)})},add:function(a,b){var c,d,e,g,i,j={},k={},l=[];b||(b={});a=f.isArray(a)?a.slice():[a];c=0;for(d=a.length;c=b))this.iframe=i('
'.$langs->trans("ProgressDeclared"). if ($usertoprocess->id == $user->id) print ''.$langs->trans("TimeSpentByYou").''.$langs->trans("TimeSpentByUser").''.$langs->trans("TimeSpent").'
('.$langs->trans("Everybody").')
'.$langs->trans("TimeSpent").''.$langs->trans("TimeSpent").($usertoprocess->firstname?'
('.$usertoprocess->firstname.')':'').'
'; + print $langs->trans("OtherFilteredTasks"); + print ''; + $tmpday=dol_time_plus_duree($firstdaytoshow, $idw, 'd'); + $timeonothertasks=($totalforeachday[$tmpday] - $totalforvisibletasks[$tmpday]); + if ($timeonothertasks) + { + print ''; + } + print '
'; print $langs->trans("Total"); print ' - '.$langs->trans("ExpectedWorkedHours").': '.price($usertoprocess->weeklyhours, 1, $langs, 0, 0).''; @@ -532,7 +592,8 @@ if (count($tasksarray) > 0)
 
 
'.$langs->trans("ChildOfTask").''; + print '
'.$langs->trans("ChildOfProjectTask").''; print $formother->selectProjectTasks(GETPOST('task_parent'),$projectid?$projectid:$object->id, 'task_parent', 0, 0, 1, 1); print '
'.$langs->trans("ChildOfTask").''; + print '
'.$langs->trans("ChildOfProjectTask").''; print $formother->selectProjectTasks($object->fk_task_parent, $projectstatic->id, 'task_parent', ($user->admin?0:1), 0, 0, 0, $object->id); print '