From d9abe553cfb0723aba098c5901326dce4082952e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 21 Mar 2017 10:54:47 +0100 Subject: [PATCH 01/16] Useless bottom-border --- htdocs/admin/modules.php | 6 +++--- htdocs/supplier_proposal/card.php | 2 +- htdocs/supplier_proposal/document.php | 2 +- htdocs/supplier_proposal/info.php | 2 +- htdocs/supplier_proposal/note.php | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/htdocs/admin/modules.php b/htdocs/admin/modules.php index 107cffd8500..52b250e8cf0 100644 --- a/htdocs/admin/modules.php +++ b/htdocs/admin/modules.php @@ -440,7 +440,7 @@ if ($mode == 'common') print ''; print ''; - dol_fiche_head($head, $mode, ''); + dol_fiche_head($head, $mode, '', -1); $moreforfilter = ''; $moreforfilter.='
'; @@ -773,7 +773,7 @@ if ($mode == 'common') if ($mode == 'marketplace') { - dol_fiche_head($head, $mode, ''); + dol_fiche_head($head, $mode, '', -1); // Marketplace print "\n"; @@ -809,7 +809,7 @@ if ($mode == 'marketplace') if ($mode == 'deploy') { - dol_fiche_head($head, $mode, ''); + dol_fiche_head($head, $mode, '', -1); $allowonlineinstall=true; diff --git a/htdocs/supplier_proposal/card.php b/htdocs/supplier_proposal/card.php index 8ec24860e14..d05d3490776 100644 --- a/htdocs/supplier_proposal/card.php +++ b/htdocs/supplier_proposal/card.php @@ -1283,7 +1283,7 @@ if ($action == 'create') $soc->fetch($object->socid); $head = supplier_proposal_prepare_head($object); - dol_fiche_head($head, 'comm', $langs->trans('CommRequest'), 0, 'supplier_proposal'); + dol_fiche_head($head, 'comm', $langs->trans('CommRequest'), -1, 'supplier_proposal'); $formconfirm = ''; diff --git a/htdocs/supplier_proposal/document.php b/htdocs/supplier_proposal/document.php index 2f49951c844..1f21693246b 100644 --- a/htdocs/supplier_proposal/document.php +++ b/htdocs/supplier_proposal/document.php @@ -83,7 +83,7 @@ if ($object->id > 0) $upload_dir = $conf->supplier_proposal->dir_output.'/'.dol_sanitizeFileName($object->ref); $head = supplier_proposal_prepare_head($object); - dol_fiche_head($head, 'document', $langs->trans('CommRequest'), 0, 'supplier_proposal'); + dol_fiche_head($head, 'document', $langs->trans('CommRequest'), -1, 'supplier_proposal'); // Construit liste des fichiers $filearray=dol_dir_list($upload_dir,"files",0,'','(\.meta|_preview\.png)$',$sortfield,(strtolower($sortorder)=='desc'?SORT_DESC:SORT_ASC),1); diff --git a/htdocs/supplier_proposal/info.php b/htdocs/supplier_proposal/info.php index de98ed5be65..718b79ce4ae 100644 --- a/htdocs/supplier_proposal/info.php +++ b/htdocs/supplier_proposal/info.php @@ -53,7 +53,7 @@ $object->info($object->id); $head = supplier_proposal_prepare_head($object); -dol_fiche_head($head, 'info', $langs->trans('CommRequest'), 0, 'supplier_proposal'); +dol_fiche_head($head, 'info', $langs->trans('CommRequest'), -1, 'supplier_proposal'); // Supplier proposal card $linkback = '' . $langs->trans("BackToList") . ''; diff --git a/htdocs/supplier_proposal/note.php b/htdocs/supplier_proposal/note.php index b764372848d..10a9668382c 100644 --- a/htdocs/supplier_proposal/note.php +++ b/htdocs/supplier_proposal/note.php @@ -76,7 +76,7 @@ if ($id > 0 || ! empty($ref)) if ( $societe->fetch($object->socid) ) { $head = supplier_proposal_prepare_head($object); - dol_fiche_head($head, 'note', $langs->trans('CommRequest'), 0, 'supplier_proposal'); + dol_fiche_head($head, 'note', $langs->trans('CommRequest'), -1, 'supplier_proposal'); // Supplier proposal card From 5231fbf1e3519c3cb1d7caf704b25b20a67a6a1f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 21 Mar 2017 11:37:03 +0100 Subject: [PATCH 02/16] Option to hide version --- htdocs/main.inc.php | 60 +++++++++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 5cb73be28e7..6b9d4f08531 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -1390,7 +1390,7 @@ function top_menu($head, $title='', $target='', $disablejs=0, $disablehead=0, $a $logouttext=''; if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { - $logouthtmltext=$appli.'
'; + //$logouthtmltext=$appli.'
'; if ($_SESSION["dol_authmode"] != 'forceuser' && $_SESSION["dol_authmode"] != 'http') { $logouthtmltext.=$langs->trans("Logout").'
'; @@ -1467,8 +1467,7 @@ function top_menu($head, $title='', $target='', $disablejs=0, $disablehead=0, $a if ($helpbaseurl && $helppage) { $text=''; - $title=''; - //$text.='
'; + $title=$appli.'
'; $title.=$langs->trans($mode == 'wiki' ? 'GoToWikiHelpPage': 'GoToHelpPage'); if ($mode == 'wiki') $title.=' - '.$langs->trans("PageWiki").' "'.dol_escape_htmltag(strtr($helppage,'_',' ')).'"'; $text.=''."\n"; // Version - $doliurl='http://www.dolibarr.org'; - //local communities - if (preg_match('/fr/i',$langs->defaultlang)) $doliurl='http://www.dolibarr.fr'; - if (preg_match('/es/i',$langs->defaultlang)) $doliurl='http://www.dolibarr.es'; - if (preg_match('/de/i',$langs->defaultlang)) $doliurl='http://www.dolibarr.de'; - if (preg_match('/it/i',$langs->defaultlang)) $doliurl='http://www.dolibarr.it'; - if (preg_match('/gr/i',$langs->defaultlang)) $doliurl='http://www.dolibarr.gr'; - - $appli=constant('DOL_APPLICATION_TITLE'); - if (! empty($conf->global->MAIN_APPLICATION_TITLE)) - { - $appli=$conf->global->MAIN_APPLICATION_TITLE; $doliurl=''; - if (preg_match('/\d\.\d/', $appli)) - { - if (! preg_match('/'.preg_quote(DOL_VERSION).'/', $appli)) $appli.=" (".DOL_VERSION.")"; // If new title contains a version that is different than core - } - else $appli.=" ".DOL_VERSION; - } - else $appli.=" ".DOL_VERSION; - print ''."\n"; + if (empty($conf->global->MAIN_HIDE_VERSION)) // Version is already on help picto and on login page. + { + $doliurl='https://www.dolibarr.org'; + //local communities + if (preg_match('/fr/i',$langs->defaultlang)) $doliurl='http://www.dolibarr.fr'; + if (preg_match('/es/i',$langs->defaultlang)) $doliurl='http://www.dolibarr.es'; + if (preg_match('/de/i',$langs->defaultlang)) $doliurl='http://www.dolibarr.de'; + if (preg_match('/it/i',$langs->defaultlang)) $doliurl='http://www.dolibarr.it'; + if (preg_match('/gr/i',$langs->defaultlang)) $doliurl='http://www.dolibarr.gr'; + + $appli=constant('DOL_APPLICATION_TITLE'); + if (! empty($conf->global->MAIN_APPLICATION_TITLE)) + { + $appli=$conf->global->MAIN_APPLICATION_TITLE; $doliurl=''; + if (preg_match('/\d\.\d/', $appli)) + { + if (! preg_match('/'.preg_quote(DOL_VERSION).'/', $appli)) $appli.=" (".DOL_VERSION.")"; // If new title contains a version that is different than core + } + else $appli.=" ".DOL_VERSION; + } + else $appli.=" ".DOL_VERSION; + print '
'; + if ($doliurl) print ''; + else print ''; + print $appli; + if ($doliurl) print ''; + else print ''; + print '
'."\n"; + } // Link to bugtrack if (! empty($conf->global->MAIN_BUGTRACK_ENABLELINK)) From 9abe0940e7ec3234302388956a63fae7e5e6bc35 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 21 Mar 2017 11:42:02 +0100 Subject: [PATCH 03/16] Fix bad use of showLinkedObjectBlock --- htdocs/user/card.php | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/htdocs/user/card.php b/htdocs/user/card.php index 4627d7c472a..839d09ee9c7 100644 --- a/htdocs/user/card.php +++ b/htdocs/user/card.php @@ -2360,13 +2360,9 @@ else $somethingshown = $formfile->show_documents('user', $filename, $filedir, $urlsource, $genallowed, $delallowed, $object->modelpdf, 1, 0, 0, 28, 0, '', 0, '', $soc->default_lang); - // Linked object block - $somethingshown = $form->showLinkedObjectBlock($object); - // Show links to link elements - $linktoelem = $form->showLinkToObjectBlock($object); - if ($linktoelem) print '
'.$linktoelem; - + $linktoelem = $form->showLinkToObjectBlock($object, null, null); + $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem); print '
'; From 5b4bb560122450add46324a9233d9016a95455fb Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 21 Mar 2017 12:13:02 +0100 Subject: [PATCH 04/16] No more need of $bc[$var] --- htdocs/admin/ihm.php | 195 +++++++++++++++++++------------------------ 1 file changed, 88 insertions(+), 107 deletions(-) diff --git a/htdocs/admin/ihm.php b/htdocs/admin/ihm.php index eefa6a1fc24..95917a79ab5 100644 --- a/htdocs/admin/ihm.php +++ b/htdocs/admin/ihm.php @@ -157,8 +157,7 @@ if ($action == 'edit') // Edit print ''; clearstatcache(); - $var=true; - + print '
'; print '
'; print ''; @@ -166,16 +165,14 @@ if ($action == 'edit') // Edit print ''; // Default language - $var=!$var; - print ''; print ''; print ''; // Multilingual GUI - $var=!$var; - print ''; print ''; @@ -192,11 +189,9 @@ if ($action == 'edit') // Edit { print '
'.$langs->trans("Parameters").''.$langs->trans("Value").'
'.$langs->trans("DefaultLanguage").''; + print '
'.$langs->trans("DefaultLanguage").''; print $formadmin->select_language($conf->global->MAIN_LANG_DEFAULT, 'main_lang_default', 1, 0, 0, 0, 0, 'minwidth300'); print ' 
'.$langs->trans("EnableMultilangInterface").''; + print '
'.$langs->trans("EnableMultilangInterface").''; print $form->selectyesno('main_multilangs',$conf->global->MAIN_MULTILANGS,1); print ' 
'; print ''; - $var=True; foreach ($searchform as $key => $value) { - $var=!$var; - print ''; } @@ -210,29 +205,18 @@ if ($action == 'edit') // Edit print ''; print ''; - // Show logo - $var=!$var; - print ''; - print ''; - print ''; - // Max size of lists - $var=!$var; - print ''; + print ''; print ''; print ''; // Max size of short lists on customer card - $var=!$var; - print ''; + print ''; print ''; print ''; // Disable javascript and ajax - $var=!$var; - print ''; print ''; @@ -241,8 +225,7 @@ if ($action == 'edit') // Edit // Activate preview tab on element card if (class_exists("Imagick")) { - $var=!$var; - print ''; print ''; @@ -250,32 +233,28 @@ if ($action == 'edit') // Edit } // First day for weeks - $var=!$var; - print ''; print ''; print ''; // DefaultWorkingDays - $var=!$var; - print ''; print ''; print ''; // DefaultWorkingHours - $var=!$var; - print ''; print ''; print ''; // Firstname/Name - $var=!$var; - print ''; @@ -283,40 +262,52 @@ if ($action == 'edit') // Edit print ''; // Hide unauthorized button - $var=!$var; - print ''; print ''; print ''; - // Hide helpcenter link on login page - $var=!$var; - print ''; + // Show logo + print ''; print ''; print ''; - - // Hide wiki link on login page - $var=!$var; - print ''; + + // Hide version link + /* + + print ''; print ''; print ''; - + */ + // Show bugtrack link - $var=!$var; - print ''; print ''; print ''; - // Message on login page - $var=!$var; - print ''; + print ''; + print ''; + + // Hide helpcenter link on login page + print ''; + print ''; + print ''; + + // Message on login page + print ''."\n"; // Message of the day on home page - $var=!$var; - print ''; - print ''; - print ''; + print ''; - print ''; - print ''; + print ''; @@ -1485,7 +1485,7 @@ else } else { - dol_fiche_head($head, 'card', $langs->trans("ExpenseReport"), 0, 'trip'); + dol_fiche_head($head, 'card', $langs->trans("ExpenseReport"), -1, 'trip'); // Clone confirmation if ($action == 'clone') { diff --git a/htdocs/expensereport/document.php b/htdocs/expensereport/document.php index 470e2ec3346..eb622867f54 100644 --- a/htdocs/expensereport/document.php +++ b/htdocs/expensereport/document.php @@ -91,7 +91,7 @@ if ($object->id) $head=expensereport_prepare_head($object); - dol_fiche_head($head, 'documents', $langs->trans("ExpenseReport"), 0, 'trip'); + dol_fiche_head($head, 'documents', $langs->trans("ExpenseReport"), -1, 'trip'); $linkback = ''.$langs->trans("BackToList").''; diff --git a/htdocs/expensereport/info.php b/htdocs/expensereport/info.php index 21ee44df97a..0c3f687519c 100644 --- a/htdocs/expensereport/info.php +++ b/htdocs/expensereport/info.php @@ -39,6 +39,9 @@ $result = restrictedArea($user, 'expensereport', $id, 'expensereport'); /* * View */ + +$form = new Form($db); + $title=$langs->trans("ExpenseReport") . " - " . $langs->trans("Info"); $helpurl="EN:Module_Expense_Reports"; llxHeader("",$title,$helpurl); @@ -51,7 +54,7 @@ if ($id > 0 || ! empty($ref)) $head = expensereport_prepare_head($object); - dol_fiche_head($head, 'info', $langs->trans("ExpenseReport"), 0, 'trip'); + dol_fiche_head($head, 'info', $langs->trans("ExpenseReport"), -1, 'trip'); $linkback = ''.$langs->trans("BackToList").''; From 9a13dc92ab4ed01916a3410d4bf96f6caae50f2a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 21 Mar 2017 17:56:11 +0100 Subject: [PATCH 15/16] bottom-border useless --- htdocs/expensereport/card.php | 6 +++--- htdocs/expensereport/document.php | 2 +- htdocs/expensereport/info.php | 5 ++++- htdocs/expensereport/note.php | 17 +---------------- 4 files changed, 9 insertions(+), 21 deletions(-) diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php index 4c28fe0281c..8ec9d9140cb 100644 --- a/htdocs/expensereport/card.php +++ b/htdocs/expensereport/card.php @@ -1272,8 +1272,8 @@ if ($action == 'create') print ''; @@ -1485,7 +1485,7 @@ else } else { - dol_fiche_head($head, 'card', $langs->trans("ExpenseReport"), 0, 'trip'); + dol_fiche_head($head, 'card', $langs->trans("ExpenseReport"), -1, 'trip'); // Clone confirmation if ($action == 'clone') { diff --git a/htdocs/expensereport/document.php b/htdocs/expensereport/document.php index 470e2ec3346..eb622867f54 100644 --- a/htdocs/expensereport/document.php +++ b/htdocs/expensereport/document.php @@ -91,7 +91,7 @@ if ($object->id) $head=expensereport_prepare_head($object); - dol_fiche_head($head, 'documents', $langs->trans("ExpenseReport"), 0, 'trip'); + dol_fiche_head($head, 'documents', $langs->trans("ExpenseReport"), -1, 'trip'); $linkback = ''.$langs->trans("BackToList").''; diff --git a/htdocs/expensereport/info.php b/htdocs/expensereport/info.php index 21ee44df97a..0c3f687519c 100644 --- a/htdocs/expensereport/info.php +++ b/htdocs/expensereport/info.php @@ -39,6 +39,9 @@ $result = restrictedArea($user, 'expensereport', $id, 'expensereport'); /* * View */ + +$form = new Form($db); + $title=$langs->trans("ExpenseReport") . " - " . $langs->trans("Info"); $helpurl="EN:Module_Expense_Reports"; llxHeader("",$title,$helpurl); @@ -51,7 +54,7 @@ if ($id > 0 || ! empty($ref)) $head = expensereport_prepare_head($object); - dol_fiche_head($head, 'info', $langs->trans("ExpenseReport"), 0, 'trip'); + dol_fiche_head($head, 'info', $langs->trans("ExpenseReport"), -1, 'trip'); $linkback = ''.$langs->trans("BackToList").''; diff --git a/htdocs/expensereport/note.php b/htdocs/expensereport/note.php index 636e54c654e..8c059b8b284 100644 --- a/htdocs/expensereport/note.php +++ b/htdocs/expensereport/note.php @@ -78,7 +78,7 @@ if ($id > 0 || ! empty($ref)) $head = expensereport_prepare_head($object); - dol_fiche_head($head, 'note', $langs->trans("ExpenseReport"), 0, 'trip'); + dol_fiche_head($head, 'note', $langs->trans("ExpenseReport"), -1, 'trip'); $linkback = ''.$langs->trans("BackToList").''; @@ -87,20 +87,6 @@ if ($id > 0 || ! empty($ref)) dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); - - - /* - print '
'.$langs->trans("PermanentLeftSearchForm").''.$langs->trans("Activated").'
'.$searchformtitle[$key].''; + print '
'.$searchformtitle[$key].''; print $form->selectyesno($searchform[$key],$searchformconst[$key],1); print '
 
'.$langs->trans("EnableShowLogo").''; - print $form->selectyesno('MAIN_SHOW_LOGO',$conf->global->MAIN_SHOW_LOGO,1); - print ' 
'.$langs->trans("DefaultMaxSizeList").'
'.$langs->trans("DefaultMaxSizeList").' 
'.$langs->trans("DefaultMaxSizeShortList").'
'.$langs->trans("DefaultMaxSizeShortList").' 
'.$langs->trans("DisableJavascript").''; + print '
'.$langs->trans("DisableJavascript").''; print $form->selectyesno('main_disable_javascript',isset($conf->global->MAIN_DISABLE_JAVASCRIPT)?$conf->global->MAIN_DISABLE_JAVASCRIPT:0,1); print ' 
'.$langs->trans("UsePreviewTabs").''; + print '
'.$langs->trans("UsePreviewTabs").''; print $form->selectyesno('MAIN_USE_PREVIEW_TABS',isset($conf->global->MAIN_USE_PREVIEW_TABS)?$conf->global->MAIN_USE_PREVIEW_TABS:0,1); print ' 
'.$langs->trans("WeekStartOnDay").''; + print '
'.$langs->trans("WeekStartOnDay").''; print $formother->select_dayofweek((isset($conf->global->MAIN_START_WEEK)?$conf->global->MAIN_START_WEEK:'1'),'MAIN_START_WEEK',0); print ' 
'.$langs->trans("DefaultWorkingDays").''; + print '
'.$langs->trans("DefaultWorkingDays").''; print ''; print ' 
'.$langs->trans("DefaultWorkingHours").''; + print '
'.$langs->trans("DefaultWorkingHours").''; print ''; print ' 
'.$langs->trans("FirstnameNamePosition").''; + print '
'.$langs->trans("FirstnameNamePosition").''; $array=array(0=>$langs->trans("Firstname").' '.$langs->trans("Lastname"),1=>$langs->trans("Lastname").' '.$langs->trans("Firstname")); print $form->selectarray('MAIN_FIRSTNAME_NAME_POSITION',$array,(isset($conf->global->MAIN_FIRSTNAME_NAME_POSITION)?$conf->global->MAIN_FIRSTNAME_NAME_POSITION:0)); print '
'.$langs->trans("ButtonHideUnauthorized").''; + print '
'.$langs->trans("ButtonHideUnauthorized").''; print $form->selectyesno('MAIN_BUTTON_HIDE_UNAUTHORIZED',isset($conf->global->MAIN_BUTTON_HIDE_UNAUTHORIZED)?$conf->global->MAIN_BUTTON_HIDE_UNAUTHORIZED:0,1); print ' 
'.$langs->trans("DisableLinkToHelpCenter").''; - print $form->selectyesno('MAIN_HELPCENTER_DISABLELINK',isset($conf->global->MAIN_HELPCENTER_DISABLELINK)?$conf->global->MAIN_HELPCENTER_DISABLELINK:0,1); - print '
'.$langs->trans("EnableShowLogo").''; + print $form->selectyesno('MAIN_SHOW_LOGO',$conf->global->MAIN_SHOW_LOGO,1); + print ' 
'.$langs->trans("DisableLinkToHelp",img_picto('',DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/helpdoc.png','',1)).''; - print $form->selectyesno('MAIN_HELP_DISABLELINK', isset($conf->global->MAIN_HELP_DISABLELINK)?$conf->global->MAIN_HELP_DISABLELINK:0,1); - print '
'.$langs->trans("HideVersionLink").''; + print $form->selectyesno('MAIN_HIDE_VERSION',$conf->global->MAIN_HIDE_VERSION,1); + print ' 
'.$langs->trans("ShowBugTrackLink", $langs->transnoentitiesnoconv("FindBug")).''; + print '
'.$langs->trans("ShowBugTrackLink", $langs->transnoentitiesnoconv("FindBug")).''; print $form->selectyesno('MAIN_BUGTRACK_ENABLELINK',$conf->global->MAIN_BUGTRACK_ENABLELINK,1); print ' 
'.$langs->trans("MessageLogin").''; + // Hide wiki link on login page + print '
'.$langs->trans("DisableLinkToHelp",img_picto('',DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/helpdoc.png','',1)).''; + print $form->selectyesno('MAIN_HELP_DISABLELINK', isset($conf->global->MAIN_HELP_DISABLELINK)?$conf->global->MAIN_HELP_DISABLELINK:0,1); + print ' 
'.$langs->trans("DisableLinkToHelpCenter").''; + print $form->selectyesno('MAIN_HELPCENTER_DISABLELINK',isset($conf->global->MAIN_HELPCENTER_DISABLELINK)?$conf->global->MAIN_HELPCENTER_DISABLELINK:0,1); + print ' 
'.$langs->trans("MessageLogin").''; $doleditor = new DolEditor('main_home', (isset($conf->global->MAIN_HOME)?$conf->global->MAIN_HOME:''), '', 142, 'dolibarr_notes', 'In', false, true, true, ROWS_4, '90%'); $doleditor->Create(); @@ -324,8 +315,7 @@ if ($action == 'edit') // Edit print '
'.$langs->trans("MessageOfDay").''; + print '
'.$langs->trans("MessageOfDay").''; $doleditor = new DolEditor('main_motd', (isset($conf->global->MAIN_MOTD)?$conf->global->MAIN_MOTD:''), '', 142, 'dolibarr_notes', 'In', false, true, true, ROWS_4, '90%'); $doleditor->Create(); @@ -345,14 +335,11 @@ if ($action == 'edit') // Edit } else // Show { - $var=true; - // Language print ''; print ''; - $var=!$var; - print ''; print ""; - - $var=!$var; - print ''; + + print ''; print ''; print ""; @@ -380,11 +366,10 @@ else // Show { print '
'.$langs->trans("Parameters").''.$langs->trans("Value").' 
'.$langs->trans("DefaultLanguage").''; + print '
'.$langs->trans("DefaultLanguage").''; $s=picto_from_langcode($conf->global->MAIN_LANG_DEFAULT); print ($s?$s.' ':''); print ($conf->global->MAIN_LANG_DEFAULT=='auto'?$langs->trans("AutoDetectLang"):$langs->trans("Language_".$conf->global->MAIN_LANG_DEFAULT)); @@ -361,9 +348,8 @@ else // Show if ($user->admin && $conf->global->MAIN_LANG_DEFAULT!='auto') print info_admin($langs->trans("SubmitTranslation".($conf->global->MAIN_LANG_DEFAULT=='en_US'?'ENUS':''),$conf->global->MAIN_LANG_DEFAULT),1); print '
'.$langs->trans("EnableMultilangInterface").'' . yn($conf->global->MAIN_MULTILANGS) . '
'.$langs->trans("EnableMultilangInterface").'' . yn($conf->global->MAIN_MULTILANGS) . ' 
'; print ''; - $var=true; foreach ($searchform as $key => $value) { - $var=!$var; - print ''; + + print ''; print ''; @@ -394,28 +379,20 @@ else // Show } // Other - $var=true; print '
'.$langs->trans("PermanentLeftSearchForm").''.$langs->trans("Activated").' 
'.$searchformtitle[$key].''.yn($searchformconst[$key]).'
'.$searchformtitle[$key].''.yn($searchformconst[$key]).''; if (! empty($searchformmodule[$key])) print $langs->trans("IfModuleEnabled",$langs->transnoentitiesnoconv($searchformmodule[$key])); print '
'; print ''; - $var=!$var; - print ''; - print ''; - print ""; - - $var=!$var; - print ''; + print ''; print ''; print ""; - $var=!$var; - print ''; + print ''; print ''; print ""; // Disable javascript/ajax - $var=!$var; - print '"; print ''; print ""; @@ -423,40 +400,36 @@ else // Show // Activate preview tab on element card if (class_exists("Imagick")) { - $var=!$var; - print '"; print ''; print ""; } // First day for weeks - $var=!$var; - print ''; print ''; print ''; // DefaultWorkingDays - $var=!$var; - print ''; print ''; print ''; // DefaultWorkingHours - $var=!$var; - print ''; print ''; print ''; // Firstname / Name position - $var=!$var; - print ''; @@ -464,40 +437,48 @@ else // Show print ''; // Hide unauthorized button - $var=!$var; - print ''; - // Link to help center - $var=!$var; - print ''; + // Show logo + print ''; + print ''; + print ""; - // Link to wiki help - $var=!$var; - print ''; - - // Show bugtrack link - $var=!$var; - print ''; + print ''; + print ''; + */ + + // Show bugtrack link + print '"; print ''; print ""; - // Message login - $var=!$var; - print ''; + + // Link to help center + print ''; + + // Message login + print ''."\n"; // Message of the day - $var=!$var; - print ''."\n"; From 0e997c973f05cff4d8bafcf363081d8274a34df0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 21 Mar 2017 13:01:32 +0100 Subject: [PATCH 05/16] FIX Picto of project on dol_banner and box --- htdocs/core/boxes/box_project.php | 8 ++++---- htdocs/core/lib/functions.lib.php | 6 ++++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/htdocs/core/boxes/box_project.php b/htdocs/core/boxes/box_project.php index c2cc1cb041b..b4a020cf500 100644 --- a/htdocs/core/boxes/box_project.php +++ b/htdocs/core/boxes/box_project.php @@ -78,7 +78,7 @@ class box_project extends ModeleBoxes // list the summary of the orders if ($user->rights->projet->lire) { - $sql = "SELECT p.rowid, p.ref, p.title, p.fk_statut "; + $sql = "SELECT p.rowid, p.ref, p.title, p.fk_statut, p.public"; $sql.= " FROM ".MAIN_DB_PREFIX."projet as p"; if($user->socid) $sql.= " INNER JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid=p.fk_soc"; $sql.= " WHERE p.entity = ".$conf->entity; @@ -98,7 +98,7 @@ class box_project extends ModeleBoxes $tooltip = $langs->trans('Project') . ': ' . $objp->ref; $this->info_box_contents[$i][0] = array( 'td' => 'align="left" width="16"', - 'logo' => 'object_project', + 'logo' => 'object_project'.($objp->public?'pub':''), 'tooltip' => $tooltip, 'url' => DOL_URL_ROOT."/projet/card.php?id=".$objp->rowid, ); @@ -124,12 +124,12 @@ class box_project extends ModeleBoxes $objTask = $db->fetch_object($resultTask); $this->info_box_contents[$i][3] = array( 'td' => 'class="right"', - 'text' => number_format($objTask->nb, 0, ',', ' ')." ".$langs->trans("Tasks"), + 'text' => $objTask->nb." ".$langs->trans("Tasks"), ); if ($objTask->nb > 0 ) $this->info_box_contents[$i][4] = array( 'td' => 'class="right"', - 'text' => number_format(($objTask->totprogress/$objTask->nb), 0, ',', ' ')."%", + 'text' => round($objTask->totprogress/$objTask->nb, 0)."%", ); else $this->info_box_contents[$i][4] = array('td' => 'class="right"', 'text' => "N/A "); diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 3851a173c24..c987b9dd954 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -1045,7 +1045,7 @@ function dol_banner_tab($object, $paramid, $morehtml='', $shownav=1, $fieldid='r $morehtmlleft.=''; } } - elseif ($conf->browser->layout != 'phone') // Show no photo link + elseif ($conf->browser->layout != 'phone') // Show No photo link (picto of pbject) { $morehtmlleft.='
'; if ($object->element == 'action') @@ -1057,7 +1057,9 @@ function dol_banner_tab($object, $paramid, $morehtml='', $shownav=1, $fieldid='r else { $width=14; $cssclass='photorefcenter'; - $nophoto=img_picto('', 'object_'.$object->picto, '', false, 1); + $picto = $object->picto; + if ($object->element == 'project' && ! $object->public) $picto = 'project'; // instead of projectpub + $nophoto=img_picto('', 'object_'.$picto, '', false, 1); $morehtmlleft.='
No photo
'; } $morehtmlleft.='
'; From aa71710a746794f42e71c0708b83461e51e03fc4 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 21 Mar 2017 13:38:00 +0100 Subject: [PATCH 06/16] FIX list of projects --- htdocs/core/boxes/box_project.php | 44 ++++++++++++++++++++++--------- htdocs/projet/list.php | 3 ++- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/htdocs/core/boxes/box_project.php b/htdocs/core/boxes/box_project.php index b4a020cf500..4277481499f 100644 --- a/htdocs/core/boxes/box_project.php +++ b/htdocs/core/boxes/box_project.php @@ -72,27 +72,40 @@ class box_project extends ModeleBoxes $totalnb = 0; $totalnbTask=0; - $textHead = $langs->trans("Projects"); + $textHead = $langs->trans("OpenedProjects"); $this->info_box_head = array('text' => $textHead, 'limit'=> dol_strlen($textHead)); // list the summary of the orders if ($user->rights->projet->lire) { - - $sql = "SELECT p.rowid, p.ref, p.title, p.fk_statut, p.public"; + + include_once(DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'); + $projectstatic = new Project($this->db); + + $socid=$user->societe_id; + + // Get list of project id allowed to user (in a string list separated by coma) + $projectsListId=''; + if (! $user->rights->projet->all->lire) $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user,0,1,$socid); + + $sql = "SELECT p.rowid, p.ref, p.title, p.fk_statut, p.public"; $sql.= " FROM ".MAIN_DB_PREFIX."projet as p"; if($user->socid) $sql.= " INNER JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid=p.fk_soc"; - $sql.= " WHERE p.entity = ".$conf->entity; - if($user->socid) $sql.= " AND s.rowid = ".$user->socid; + $sql.= " WHERE p.entity IN (".getEntity('project',1).')'; + if (! $user->rights->projet->all->lire) $sql.= " AND p.rowid IN (".$projectsListId.")"; // public and assigned to, or restricted to company for external users + if ($user->socid) $sql.= " AND s.rowid = ".$user->socid; $sql.= " AND p.fk_statut = 1"; // Seulement les projets ouverts - $sql.= " ORDER BY p.datec DESC"; - $sql.= $db->plimit($max, 0); + if ($socid) $sql.= " AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".$socid.")"; + if (! $user->rights->societe->client->voir && ! $socid) $sql.= " AND ((s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id.") OR (s.rowid IS NULL))"; + + $sql.= " ORDER BY p.datec DESC"; + //$sql.= $db->plimit($max, 0); $result = $db->query($sql); if ($result) { $num = $db->num_rows($result); $i = 0; - while ($i < $num) { + while ($i < min($num, $max)) { $objp = $db->fetch_object($result); $tooltip = $langs->trans('Project') . ': ' . $objp->ref; @@ -117,8 +130,8 @@ class box_project extends ModeleBoxes $sql ="SELECT count(*) as nb, sum(progress) as totprogress"; $sql.=" FROM ".MAIN_DB_PREFIX."projet as p LEFT JOIN ".MAIN_DB_PREFIX."projet_task as pt on pt.fk_projet = p.rowid"; - $sql.=" WHERE p.entity = ".$conf->entity; - $sql.=" AND p.rowid = ".$objp->rowid; + $sql.= " WHERE p.entity IN (".getEntity('project',1).')'; + $sql.=" AND p.rowid = ".$objp->rowid; $resultTask = $db->query($sql); if ($resultTask) { $objTask = $db->fetch_object($resultTask); @@ -135,12 +148,17 @@ class box_project extends ModeleBoxes $this->info_box_contents[$i][4] = array('td' => 'class="right"', 'text' => "N/A "); $totalnbTask += $objTask->nb; } else { - $this->info_box_contents[$i][3] = array('td' => 'class="right"', 'text' => number_format(0, 0, ',', ' ')); + $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 "); } $i++; } + if ($max < $num) + { + $this->info_box_contents[$i][0] = array('td' => 'colspan="5"', 'text' => '...'); + $i++; + } } } @@ -158,11 +176,11 @@ class box_project extends ModeleBoxes ); $this->info_box_contents[$i][2] = array( 'td' => 'align="right" ', - 'text' => number_format($num, 0, ',', ' ')." ".$langs->trans("Projects"), + 'text' => round($num, 0)." ".$langs->trans("Projects"), ); $this->info_box_contents[$i][3] = array( 'td' => 'align="right" ', - 'text' => number_format($totalnbTask, 0, ',', ' ')." ".$langs->trans("Tasks"), + 'text' => (($max < $num) ? '' : (round($totalnbTask, 0)." ".$langs->trans("Tasks"))), ); $this->info_box_contents[$i][4] = array( 'td' => '', diff --git a/htdocs/projet/list.php b/htdocs/projet/list.php index f45148c84c7..c7d213b19ce 100644 --- a/htdocs/projet/list.php +++ b/htdocs/projet/list.php @@ -197,6 +197,7 @@ $title=$langs->trans("Projects"); // Get list of project id allowed to user (in a string list separated by coma) +$projectsListId=''; if (! $user->rights->projet->all->lire) $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user,0,1,$socid); // Get id of types of contacts for projects (This list never contains a lot of elements) @@ -246,7 +247,7 @@ if ($search_project_user > 0) $sql.= " WHERE p.entity IN (".getEntity('project',1).')'; if (! $user->rights->projet->all->lire) $sql.= " AND p.rowid IN (".$projectsListId.")"; // public and assigned to, or restricted to company for external users // No need to check company, as filtering of projects must be done by getProjectsAuthorizedForUser -if ($socid) $sql.= " AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".$socid.")"; +if ($socid) $sql.= " AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".$socid.")"; if ($search_categ > 0) $sql.= " AND cs.fk_categorie = ".$db->escape($search_categ); if ($search_categ == -2) $sql.= " AND cs.fk_categorie IS NULL"; if ($search_ref) $sql .= natural_search('p.ref', $search_ref); From 95da2f5d545aa9083ea47ba3ebe5776eac142373 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 21 Mar 2017 13:38:21 +0100 Subject: [PATCH 07/16] NEW Add font-awesome css. --- htdocs/main.inc.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 6b9d4f08531..45787d5054b 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -1080,7 +1080,13 @@ function top_htmlhead($head, $title='', $disablejs=0, $disablehead=0, $arrayofjs print ''."\n"; } } - + + if (! defined('DISABLE_FONT_AWSOME')) + { + print ''."\n"; + print ''."\n"; + } + print ''."\n"; // Output style sheets (optioncss='print' or ''). Note: $conf->css looks like '/theme/eldy/style.css.php' //$themepath=dol_buildpath((empty($conf->global->MAIN_FORCETHEMEDIR)?'':$conf->global->MAIN_FORCETHEMEDIR).$conf->css,1); @@ -1100,7 +1106,7 @@ function top_htmlhead($head, $title='', $disablejs=0, $disablehead=0, $arrayofjs } //print 'themepath='.$themepath.' themeparam='.$themeparam;exit; print ''."\n"; - if (! empty($conf->global->MAIN_FIX_FLASH_ON_CHROME)) print ''."\n".''."\n"; + if (! empty($conf->global->MAIN_FIX_FLASH_ON_CHROME)) print ''."\n".''."\n"; // CSS forced by modules (relative url starting with /) if (! empty($conf->modules_parts['css'])) From 68257283e444cab0e16d4559d8f083a5bb557102 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 21 Mar 2017 13:39:42 +0100 Subject: [PATCH 08/16] Enhance select list --- htdocs/core/class/html.form.class.php | 41 ++++++++++------------ htdocs/core/class/html.formother.class.php | 3 +- htdocs/core/lib/ajax.lib.php | 2 +- htdocs/index.php | 5 ++- htdocs/projet/class/project.class.php | 4 +-- 5 files changed, 25 insertions(+), 30 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 1366435f144..0ec07e1c3fa 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -1070,11 +1070,10 @@ class Form include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; $comboenhancement =ajax_combobox($htmlname, $events, $conf->global->COMPANY_USE_SEARCH_TO_SELECT); $out.= $comboenhancement; - $nodatarole=($comboenhancement?' data-role="none"':''); } // Construct $out and $outarray - $out.= ''."\n"; $textifempty=''; // Do not use textifempty = ' ' or ' ' here, or search on key will search on ' key'. @@ -1286,10 +1285,9 @@ class Form include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; $comboenhancement = ajax_combobox($htmlname, $events, $conf->global->CONTACT_USE_SEARCH_TO_SELECT); $out.= $comboenhancement; - $nodatarole=($comboenhancement?' data-role="none"':''); } - if ($htmlname != 'none' || $options_only) $out.= ''; if ($showempty == 1) $out.= ''; if ($showempty == 2) $out.= ''; $num = $this->db->num_rows($resql); @@ -1481,17 +1479,15 @@ class Form if ($num) { // Enhance with select2 - $nodatarole=''; if ($conf->use_javascript_ajax) { include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; $comboenhancement = ajax_combobox($htmlname); $out.=$comboenhancement; - $nodatarole=($comboenhancement?' data-role="none"':''); } // do not use maxwidthonsmartphone by default. Set it by caller so auto size to 100% will work when not defined - $out.= ''; if ($show_empty) $out.= ''."\n"; if ($show_every) $out.= ''."\n"; @@ -1964,10 +1960,9 @@ class Form include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; $comboenhancement =ajax_combobox($htmlname, $events, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT); $out.= $comboenhancement; - $nodatarole=($comboenhancement?' data-role="none"':''); } - $out.=''; $textifempty=''; // Do not use textifempty = ' ' or ' ' here, or search on key will search on ' key'. @@ -4966,24 +4961,25 @@ class Form * Note: Do not apply langs->trans function on returned content, content may be entity encoded twice. * * @param string $htmlname Name of html select area. Must start with "multi" if this is a multiselect - * @param array $array Array with key+value + * @param array $array Array (key => value) * @param string|string[] $id Preselected key or preselected keys for multiselect * @param int $show_empty 0 no empty value allowed, 1 or string to add an empty value into list (value is '' or ' ' if 1), <0 to add an empty value with key that is this value. - * @param int $key_in_label 1 pour afficher la key dans la valeur "[key] value" + * @param int $key_in_label 1 to show key into label with format "[key] value" * @param int $value_as_key 1 to use value as key * @param string $moreparam Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container - * @param int $translate Translate and encode value + * @param int $translate 1=Translate and encode value * @param int $maxlen Length maximum for labels * @param int $disabled Html select box is disabled * @param string $sort 'ASC' or 'DESC' = Sort on label, '' or 'NONE' or 'POS' = Do not sort, we keep original order * @param string $morecss Add more class to css styles * @param int $addjscombo Add js combo - * @param string $moreparamonempty Add more param on the empty option line. Not used if show_empty not set. - * @param int $disablebademail Check if an email is found into value and if not disable and colorize entry. - * @return string HTML select string. + * @param string $moreparamonempty Add more param on the empty option line. Not used if show_empty not set + * @param int $disablebademail Check if an email is found into value and if not disable and colorize entry + * @param int $nohtmlescape No html escaping. + * @return string HTML select string * @see multiselectarray */ - static function selectarray($htmlname, $array, $id='', $show_empty=0, $key_in_label=0, $value_as_key=0, $moreparam='', $translate=0, $maxlen=0, $disabled=0, $sort='', $morecss='', $addjscombo=0, $moreparamonempty='',$disablebademail=0) + static function selectarray($htmlname, $array, $id='', $show_empty=0, $key_in_label=0, $value_as_key=0, $moreparam='', $translate=0, $maxlen=0, $disabled=0, $sort='', $morecss='', $addjscombo=0, $moreparamonempty='',$disablebademail=0, $nohtmlescape=0) { global $conf, $langs; @@ -5003,13 +4999,11 @@ class Form $tmpplugin=empty($conf->global->MAIN_USE_JQUERY_MULTISELECT)?(constant('REQUIRE_JQUERY_MULTISELECT')?constant('REQUIRE_JQUERY_MULTISELECT'):'select2'):$conf->global->MAIN_USE_JQUERY_MULTISELECT; // Enhance with select2 - $nodatarole=''; if ($conf->use_javascript_ajax) { include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; $comboenhancement = ajax_combobox($htmlname); $out.=$comboenhancement; - $nodatarole=($comboenhancement?' data-role="none"':''); } } @@ -5057,11 +5051,13 @@ class Form if ($key_in_label) { - $selectOptionValue = dol_escape_htmltag($key.' - '.($maxlen?dol_trunc($value,$maxlen):$value)); + if (empty($nohtmlescape)) $selectOptionValue = dol_escape_htmltag($key.' - '.($maxlen?dol_trunc($value,$maxlen):$value)); + else $selectOptionValue = $key.' - '.($maxlen?dol_trunc($value,$maxlen):$value); } else { - $selectOptionValue = dol_escape_htmltag($maxlen?dol_trunc($value,$maxlen):$value); + if (empty($nohtmlescape)) $selectOptionValue = dol_escape_htmltag($maxlen?dol_trunc($value,$maxlen):$value); + else $selectOptionValue = $maxlen?dol_trunc($value,$maxlen):$value; if ($value == '' || $value == '-') $selectOptionValue=' '; } //var_dump($selectOptionValue); @@ -5976,6 +5972,7 @@ class Form } else { + // Generic case to show photos $dir=$conf->$modulepart->dir_output; if (! empty($object->photo)) { @@ -6045,7 +6042,6 @@ class Form if ($object->photo) $ret.="
\n"; $ret.='
'.$langs->trans("Parameters").''.$langs->trans("Value").'
'.$langs->trans("EnableShowLogo").'' . yn($conf->global->MAIN_SHOW_LOGO) . ' 
'.$langs->trans("DefaultMaxSizeList").'' . $conf->global->MAIN_SIZE_LISTE_LIMIT . '
'.$langs->trans("DefaultMaxSizeList").'' . $conf->global->MAIN_SIZE_LISTE_LIMIT . ' 
'.$langs->trans("DefaultMaxSizeShortList").'' . $conf->global->MAIN_SIZE_SHORTLIST_LIMIT . '
'.$langs->trans("DefaultMaxSizeShortList").'' . $conf->global->MAIN_SIZE_SHORTLIST_LIMIT . ' 
'.$langs->trans("DisableJavascript").''; + + print '
'.$langs->trans("DisableJavascript").''; print yn($conf->global->MAIN_DISABLE_JAVASCRIPT)." 
'.$langs->trans("UsePreviewTabs").''; + + print '
'.$langs->trans("UsePreviewTabs").''; print yn(isset($conf->global->MAIN_USE_PREVIEW_TABS)?$conf->global->MAIN_USE_PREVIEW_TABS:0)." 
'.$langs->trans("WeekStartOnDay").''; + print '
'.$langs->trans("WeekStartOnDay").''; print $langs->trans("Day".(isset($conf->global->MAIN_START_WEEK)?$conf->global->MAIN_START_WEEK:'1')); print ' 
'.$langs->trans("DefaultWorkingDays").''; + print '
'.$langs->trans("DefaultWorkingDays").''; print isset($conf->global->MAIN_DEFAULT_WORKING_DAYS)?$conf->global->MAIN_DEFAULT_WORKING_DAYS:'1-5'; print ' 
'.$langs->trans("DefaultWorkingHours").''; + print '
'.$langs->trans("DefaultWorkingHours").''; print isset($conf->global->MAIN_DEFAULT_WORKING_HOURS)?$conf->global->MAIN_DEFAULT_WORKING_HOURS:'9-18'; print ' 
'.$langs->trans("FirstnameNamePosition").''; + print '
'.$langs->trans("FirstnameNamePosition").''; if (empty($conf->global->MAIN_FIRSTNAME_NAME_POSITION)) { print $langs->trans("Firstname").' '.$langs->trans("Lastname"); } else { print $langs->trans("Lastname").' '.$langs->trans("Firstname"); } print '
'.$langs->trans("ButtonHideUnauthorized").''; + print '
'.$langs->trans("ButtonHideUnauthorized").''; print yn((isset($conf->global->MAIN_BUTTON_HIDE_UNAUTHORIZED)?$conf->global->MAIN_BUTTON_HIDE_UNAUTHORIZED:0),1); print '
'.$langs->trans("DisableLinkToHelpCenter").''; - print yn((isset($conf->global->MAIN_HELPCENTER_DISABLELINK)?$conf->global->MAIN_HELPCENTER_DISABLELINK:0),1); - print '
'.$langs->trans("EnableShowLogo").'' . yn($conf->global->MAIN_SHOW_LOGO) . ' 
'.$langs->trans("DisableLinkToHelp",img_picto('',DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/helpdoc.png','',1)).''; - print yn((isset($conf->global->MAIN_HELP_DISABLELINK)?$conf->global->MAIN_HELP_DISABLELINK:0),1); - print '
'.$langs->trans("ShowBugTrackLink", $langs->transnoentitiesnoconv("FindBug")).''; + // Hide version link + /* + print '
'.$langs->trans("HideVersionLink").''; + print yn($conf->global->MAIN_HIDE_VERSION); + print ' 
'.$langs->trans("ShowBugTrackLink", $langs->transnoentitiesnoconv("FindBug")).''; print yn($conf->global->MAIN_BUGTRACK_ENABLELINK)." 
'.$langs->trans("MessageLogin").''; + // Link to wiki help + print '
'.$langs->trans("DisableLinkToHelp",img_picto('',DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/helpdoc.png','',1)).''; + print yn((isset($conf->global->MAIN_HELP_DISABLELINK)?$conf->global->MAIN_HELP_DISABLELINK:0),1); + print '
'.$langs->trans("DisableLinkToHelpCenter").''; + print yn((isset($conf->global->MAIN_HELPCENTER_DISABLELINK)?$conf->global->MAIN_HELPCENTER_DISABLELINK:0),1); + print '
'.$langs->trans("MessageLogin").''; if (isset($conf->global->MAIN_HOME)) print dol_htmlcleanlastbr($conf->global->MAIN_HOME); else print ' '; print '
'.$langs->trans("MessageOfDay").''; + print '
'.$langs->trans("MessageOfDay").''; if (isset($conf->global->MAIN_MOTD)) print dol_htmlcleanlastbr($conf->global->MAIN_MOTD); else print ' '; print '
'; if ($object->photo) $ret.=''; - //$ret.=''; $ret.=''; $ret.='
'.$langs->trans("Delete").'

'.$langs->trans("PhotoFile").'
'; } @@ -6112,10 +6108,9 @@ class Form include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; $comboenhancement = ajax_combobox($htmlname); $out.= $comboenhancement; - $nodatarole=($comboenhancement?' data-role="none"':''); } - $out.= ''; $num = $this->db->num_rows($resql); $i = 0; diff --git a/htdocs/core/class/html.formother.class.php b/htdocs/core/class/html.formother.class.php index 95dee1424ef..4ae2d81539d 100644 --- a/htdocs/core/class/html.formother.class.php +++ b/htdocs/core/class/html.formother.class.php @@ -1011,6 +1011,7 @@ class FormOther if (! empty($boxidactivatedforuser[$box->id])) continue; // Already visible for user $label=$langs->transnoentitiesnoconv($box->boxlabel); if (preg_match('/graph/',$box->class)) $label.=' ('.$langs->trans("Graph").')'; + //$label = ''.$label; KO with select2. No html rendering. $arrayboxtoactivatelabel[$box->id]=$label; // We keep only boxes not shown for user, to show into combo list } foreach($boxidactivatedforuser as $boxid) @@ -1027,7 +1028,7 @@ class FormOther $selectboxlist.=''; $selectboxlist.=''; $selectboxlist.=''; - $selectboxlist.=Form::selectarray('boxcombo', $arrayboxtoactivatelabel, -1, $langs->trans("ChooseBoxToAdd").'...', 0, 0, '', 0, 0, 0, 'ASC', 'maxwidth150onsmartphone', 0, 'hidden selected'); + $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"); diff --git a/htdocs/core/lib/ajax.lib.php b/htdocs/core/lib/ajax.lib.php index 68e3f079361..214704f06a2 100644 --- a/htdocs/core/lib/ajax.lib.php +++ b/htdocs/core/lib/ajax.lib.php @@ -377,7 +377,7 @@ function ajax_combobox($htmlname, $events=array(), $minLengthToAutocomplete=0, $ $(\''.(preg_match('/^\./',$htmlname)?$htmlname:'#'.$htmlname).'\').'.$tmpplugin.'({ dir: \'ltr\', width: \''.$widthTypeOfAutocomplete.'\', /* off or resolve */ - minimumInputLength: '.$minLengthToAutocomplete.' + minimumInputLength: '.$minLengthToAutocomplete.' })'; if ($forcefocus) $msg.= '.select2(\'focus\')'; $msg.= ';'."\n"; diff --git a/htdocs/index.php b/htdocs/index.php index b6189537546..75ee74144f2 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -77,7 +77,7 @@ if (! empty($conf->global->MAIN_APPLICATION_TITLE)) $title=$langs->trans("HomeAr llxHeader('',$title); - + $resultboxes=FormOther::getBoxesArea($user,"0"); // Load $resultboxes (selectboxlist + boxactivated + boxlista + boxlistb) @@ -242,7 +242,7 @@ if (empty($user->societe_id)) 'order', 'bill', 'propal', - 'project', + 'projectpub', 'trip', 'generic' ); @@ -388,7 +388,6 @@ if (! empty($conf->projet->enabled) && $user->rights->projet->lire) { include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; $board=new Project($db); - $dashboardlines[] = $board->load_board($user); } diff --git a/htdocs/projet/class/project.class.php b/htdocs/projet/class/project.class.php index 755998f7238..94c49d6d0ef 100644 --- a/htdocs/projet/class/project.class.php +++ b/htdocs/projet/class/project.class.php @@ -1692,8 +1692,8 @@ class Project extends CommonObject $response->warning_delay = $conf->projet->warning_delay/60/60/24; $response->label = $langs->trans("OpenedProjects"); if ($user->rights->projet->all->lire) $response->url = DOL_URL_ROOT.'/projet/list.php?search_status=1&mainmenu=project'; - else $response->url = DOL_URL_ROOT.'/projet/list.php?mode=mine&search_status=1&mainmenu=project'; - $response->img = img_object($langs->trans("Projects"),"project"); + else $response->url = DOL_URL_ROOT.'/projet/list.php?search_project_user=-1&search_status=1&mainmenu=project'; + $response->img = img_object($langs->trans("Projects"),"projectpub"); // This assignment in condition is not a bug. It allows walking the results. while ($obj=$this->db->fetch_object($resql)) From a5c11dc8408884ce022e648ac7f3d4409eabdf12 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 21 Mar 2017 16:02:54 +0100 Subject: [PATCH 09/16] NEW Add function dolMd2Html --- COPYRIGHT | 1 + htdocs/admin/modulehelp.php | 68 +- htdocs/core/lib/parsemd.lib.php | 46 + htdocs/core/modules/modFacture.class.php | 2 +- htdocs/includes/parsedown/.travis.yml | 16 + htdocs/includes/parsedown/LICENSE.txt | 20 + htdocs/includes/parsedown/Parsedown.php | 1548 ++++++++++++++++++++ htdocs/includes/parsedown/README.md | 56 + htdocs/includes/parsedown/composer.json | 21 + htdocs/includes/parsedown/phpunit.xml.dist | 8 + htdocs/langs/en_US/admin.lang | 1 + 11 files changed, 1762 insertions(+), 25 deletions(-) create mode 100644 htdocs/core/lib/parsemd.lib.php create mode 100644 htdocs/includes/parsedown/.travis.yml create mode 100644 htdocs/includes/parsedown/LICENSE.txt create mode 100644 htdocs/includes/parsedown/Parsedown.php create mode 100644 htdocs/includes/parsedown/README.md create mode 100644 htdocs/includes/parsedown/composer.json create mode 100644 htdocs/includes/parsedown/phpunit.xml.dist diff --git a/COPYRIGHT b/COPYRIGHT index f55772c0d9f..6f8a595897d 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -22,6 +22,7 @@ Mobiledetect 2.8.17 MIT License Yes NuSoap 0.9.5 LGPL 2.1+ Yes Library to develop SOAP Web services (not into rpm and deb package) PEAR Mail_MIME 1.8.9 BSD Yes NuSoap dependency odtPHP 1.0.1 GPL-2+ b Yes Library to build/edit ODT files +ParseDown 1.6 MIT License Yes Markdown parser PHPExcel 1.8.1 LGPL-2.1+ Yes Read/Write XLS files, read ODS files php-iban 1.4.7 LGPL-3+ Yes Parse and validate IBAN (and IIBAN) bank account information in PHP PHPoAuthLib 0.8.2 MIT License Yes Library to provide oauth1 and oauth2 to different service diff --git a/htdocs/admin/modulehelp.php b/htdocs/admin/modulehelp.php index 9ff7a4478ff..e76627c2965 100644 --- a/htdocs/admin/modulehelp.php +++ b/htdocs/admin/modulehelp.php @@ -239,7 +239,7 @@ $head[$h][2] = 'desc'; $h++; $head[$h][0] = DOL_URL_ROOT."/admin/modulehelp.php?id=".$id.'&mode=feature'; -$head[$h][1] = $langs->trans("Features"); +$head[$h][1] = $langs->trans("TechnicalServicesProvided"); $head[$h][2] = 'feature'; $h++; @@ -251,45 +251,38 @@ foreach($orders as $tmpkey => $tmpvalue) if ($objMod->numero == $id) { $key = $i; + $modName = $filename[$tmpkey]; + $dirofmodule = $dirmod[$tmpkey]; break; } $i++; } $value = $orders[$key]; +$special = $objMod->special; +$tab=explode('_',$value); +$familyposition=$tab[0]; $familykey=$tab[1]; $module_position=$tab[2]; $numero=$tab[3]; + +// Check filters +$modulename=$objMod->getName(); +$moduledesc=$objMod->getDesc(); +$moduleauthor=$objMod->getPublisher(); + print '
'; - -print load_fiche_titre($objMod->getDesc(),$moreinfo,'object_'.$objMod->picto); +print load_fiche_titre(($modulename?$modulename:$moduledesc), $moreinfo, 'object_'.$objMod->picto); print '
'; -dol_fiche_head($head, $mode, $title); +dol_fiche_head($head, $mode, $title, -1); - - -$tab=explode('_',$value); -$familyposition=$tab[0]; $familykey=$tab[1]; $module_position=$tab[2]; $numero=$tab[3]; - -$modName = $filename[$key]; -$objMod = $modules[$key]; -$dirofmodule = $dirmod[$key]; - -$special = $objMod->special; - -if (! $objMod->getName()) +if (! $modulename) { dol_syslog("Error for module ".$key." - Property name of module looks empty", LOG_WARNING); } $const_name = 'MAIN_MODULE_'.strtoupper(preg_replace('/^mod/i','',get_class($objMod))); -// Check filters -$modulename=$objMod->getName(); -$moduledesc=$objMod->getDesc(); -$moduledesclong=$objMod->getDescLong(); -$moduleauthor=$objMod->getPublisher(); - // Load all lang files of module if (isset($objMod->langfiles) && is_array($objMod->langfiles)) { @@ -322,6 +315,8 @@ $text=''; if ($mode == 'desc') { + if ($moduledesc) $text.=$moduledesc.'

'; + $text.=''.$langs->trans("Version").': '.$version; $textexternal=''; @@ -329,7 +324,7 @@ if ($mode == 'desc') { $textexternal.='
'.$langs->trans("Origin").': '.$langs->trans("ExternalModule",$dirofmodule); if ($objMod->editor_name != 'dolibarr') $textexternal.='
'.$langs->trans("Publisher").': '.(empty($objMod->editor_name)?$langs->trans("Unknown"):$objMod->editor_name); - if (! empty($objMod->editor_url) && ! preg_match('/dolibarr\.org/i',$objMod->editor_url)) $textexternal.='
'.$langs->trans("Url").': '.$objMod->editor_url; + if (! empty($objMod->editor_url) && ! preg_match('/dolibarr\.org/i',$objMod->editor_url)) $textexternal.='
'.$langs->trans("Url").': '.$objMod->editor_url.''; $text.=$textexternal; $text.='
'; } @@ -342,7 +337,8 @@ if ($mode == 'desc') else $text.=$langs->trans("Disabled"); $text.='
'; - if ($objMod->getDescLong()) $text.=$objMod->getDesc().'
'; + $moduledesclong=$objMod->getDescLong(); + if ($moduledesclong) $text.='


'.$moduledesclong.'
'; } if ($mode == 'feature') @@ -360,6 +356,8 @@ if ($mode == 'feature') } else $text.=$langs->trans("No"); + $text.='
'; + $text.='
'.$langs->trans("AddDictionaries").': '; if (isset($objMod->dictionaries) && isset($objMod->dictionaries['tablib']) && is_array($objMod->dictionaries['tablib']) && count($objMod->dictionaries['tablib'])) { @@ -372,6 +370,8 @@ if ($mode == 'feature') } else $text.=$langs->trans("No"); + $text.='
'; + $text.='
'.$langs->trans("AddBoxes").': '; if (isset($objMod->boxes) && is_array($objMod->boxes) && count($objMod->boxes)) { @@ -384,6 +384,8 @@ if ($mode == 'feature') } else $text.=$langs->trans("No"); + $text.='
'; + $text.='
'.$langs->trans("AddModels").': '; if (isset($objMod->module_parts) && isset($objMod->module_parts['models']) && $objMod->module_parts['models']) { @@ -391,6 +393,8 @@ if ($mode == 'feature') } else $text.=$langs->trans("No"); + $text.='
'; + $text.='
'.$langs->trans("AddSubstitutions").': '; if (isset($objMod->module_parts) && isset($objMod->module_parts['substitutions']) && $objMod->module_parts['substitutions']) { @@ -398,6 +402,8 @@ if ($mode == 'feature') } else $text.=$langs->trans("No"); + $text.='
'; + $text.='
'.$langs->trans("AddSheduledJobs").': '; if (isset($objMod->cronjobs) && is_array($objMod->cronjobs) && count($objMod->cronjobs)) { @@ -410,6 +416,8 @@ if ($mode == 'feature') } else $text.=$langs->trans("No"); + $text.='
'; + $text.='
'.$langs->trans("AddTriggers").': '; if (isset($objMod->module_parts) && isset($objMod->module_parts['triggers']) && $objMod->module_parts['triggers']) { @@ -417,6 +425,8 @@ if ($mode == 'feature') } else $text.=$langs->trans("No"); + $text.='
'; + $text.='
'.$langs->trans("AddHooks").': '; if (isset($objMod->module_parts) && is_array($objMod->module_parts['hooks']) && count($objMod->module_parts['hooks'])) { @@ -429,6 +439,8 @@ if ($mode == 'feature') } else $text.=$langs->trans("No"); + $text.='
'; + $text.='
'.$langs->trans("AddPermissions").': '; if (isset($objMod->rights) && is_array($objMod->rights) && count($objMod->rights)) { @@ -441,6 +453,8 @@ if ($mode == 'feature') } else $text.=$langs->trans("No"); + $text.='
'; + $text.='
'.$langs->trans("AddMenus").': '; if (isset($objMod->menu) && ! empty($objMod->menu)) // objMod can be an array or just an int 1 { @@ -448,6 +462,8 @@ if ($mode == 'feature') } else $text.=$langs->trans("No"); + $text.='
'; + $text.='
'.$langs->trans("AddExportProfiles").': '; if (isset($objMod->export_label) && is_array($objMod->export_label) && count($objMod->export_label)) { @@ -460,6 +476,8 @@ if ($mode == 'feature') } else $text.=$langs->trans("No"); + $text.='
'; + $text.='
'.$langs->trans("AddImportProfiles").': '; if (isset($objMod->import_label) && is_array($objMod->import_label) && count($objMod->import_label)) { @@ -472,6 +490,8 @@ if ($mode == 'feature') } else $text.=$langs->trans("No"); + $text.='
'; + $text.='
'.$langs->trans("AddOtherPagesOrServices").': '; $text.=$langs->trans("DetectionNotPossible"); } diff --git a/htdocs/core/lib/parsemd.lib.php b/htdocs/core/lib/parsemd.lib.php new file mode 100644 index 00000000000..17e64f6543e --- /dev/null +++ b/htdocs/core/lib/parsemd.lib.php @@ -0,0 +1,46 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * or see http://www.gnu.org/ + */ + +/** + * \file htdocs/core/lib/parsemd.lib.php + * \brief This file contains functions dedicated to MD parsind. + */ + +/** + * Function to parse MD content into HTML + * + * @param string $content MD content + * @param string $parser 'parsedown' or 'nl2br' + * @return string Parsed content + */ +function dolMd2Html($content, $parser='parsedown') +{ + if ($parser == 'parsedown') + { + include DOL_DOCUMENT_ROOT.'/includes/parsedown/Parsedown.php'; + $Parsedown = new Parsedown(); + $content = $Parsedown->text($content); + } + else + { + $content = nl2br($content); + } + + return $content; +} + diff --git a/htdocs/core/modules/modFacture.class.php b/htdocs/core/modules/modFacture.class.php index a88082ba6fc..d6e6bfd2575 100644 --- a/htdocs/core/modules/modFacture.class.php +++ b/htdocs/core/modules/modFacture.class.php @@ -69,7 +69,7 @@ class modFacture extends DolibarrModules $this->conflictwith = array(); $this->langfiles = array("bills","companies","compta","products"); $this->warnings_activation = array(); // Warning to show when we activate module. array('always'='text') or array('FR'='text') - $this->warnings_activation_ext = array('CA'=>'WarningInstallationMayBecomeNotCompliantWithLaw'); // Warning to show when we activate an external module. array('always'='text') or array('FR'='text') + $this->warnings_activation_ext = array('FR'=>'WarningInstallationMayBecomeNotCompliantWithLaw'); // Warning to show when we activate an external module. array('always'='text') or array('FR'='text') // Config pages $this->config_page_url = array("facture.php"); diff --git a/htdocs/includes/parsedown/.travis.yml b/htdocs/includes/parsedown/.travis.yml new file mode 100644 index 00000000000..fa5ca981cc9 --- /dev/null +++ b/htdocs/includes/parsedown/.travis.yml @@ -0,0 +1,16 @@ +language: php + +php: + - 7.1 + - 7.0 + - 5.6 + - 5.5 + - 5.4 + - 5.3 + - hhvm + - hhvm-nightly + +matrix: + fast_finish: true + allow_failures: + - php: hhvm-nightly diff --git a/htdocs/includes/parsedown/LICENSE.txt b/htdocs/includes/parsedown/LICENSE.txt new file mode 100644 index 00000000000..baca86f5b8e --- /dev/null +++ b/htdocs/includes/parsedown/LICENSE.txt @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2013 Emanuil Rusev, erusev.com + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/htdocs/includes/parsedown/Parsedown.php b/htdocs/includes/parsedown/Parsedown.php new file mode 100644 index 00000000000..20863a7537a --- /dev/null +++ b/htdocs/includes/parsedown/Parsedown.php @@ -0,0 +1,1548 @@ +DefinitionData = array(); + + # standardize line breaks + $text = str_replace(array("\r\n", "\r"), "\n", $text); + + # remove surrounding line breaks + $text = trim($text, "\n"); + + # split text into lines + $lines = explode("\n", $text); + + # iterate through lines to identify blocks + $markup = $this->lines($lines); + + # trim line breaks + $markup = trim($markup, "\n"); + + return $markup; + } + + # + # Setters + # + + function setBreaksEnabled($breaksEnabled) + { + $this->breaksEnabled = $breaksEnabled; + + return $this; + } + + protected $breaksEnabled; + + function setMarkupEscaped($markupEscaped) + { + $this->markupEscaped = $markupEscaped; + + return $this; + } + + protected $markupEscaped; + + function setUrlsLinked($urlsLinked) + { + $this->urlsLinked = $urlsLinked; + + return $this; + } + + protected $urlsLinked = true; + + # + # Lines + # + + protected $BlockTypes = array( + '#' => array('Header'), + '*' => array('Rule', 'List'), + '+' => array('List'), + '-' => array('SetextHeader', 'Table', 'Rule', 'List'), + '0' => array('List'), + '1' => array('List'), + '2' => array('List'), + '3' => array('List'), + '4' => array('List'), + '5' => array('List'), + '6' => array('List'), + '7' => array('List'), + '8' => array('List'), + '9' => array('List'), + ':' => array('Table'), + '<' => array('Comment', 'Markup'), + '=' => array('SetextHeader'), + '>' => array('Quote'), + '[' => array('Reference'), + '_' => array('Rule'), + '`' => array('FencedCode'), + '|' => array('Table'), + '~' => array('FencedCode'), + ); + + # ~ + + protected $unmarkedBlockTypes = array( + 'Code', + ); + + # + # Blocks + # + + protected function lines(array $lines) + { + $CurrentBlock = null; + + foreach ($lines as $line) + { + if (chop($line) === '') + { + if (isset($CurrentBlock)) + { + $CurrentBlock['interrupted'] = true; + } + + continue; + } + + if (strpos($line, "\t") !== false) + { + $parts = explode("\t", $line); + + $line = $parts[0]; + + unset($parts[0]); + + foreach ($parts as $part) + { + $shortage = 4 - mb_strlen($line, 'utf-8') % 4; + + $line .= str_repeat(' ', $shortage); + $line .= $part; + } + } + + $indent = 0; + + while (isset($line[$indent]) and $line[$indent] === ' ') + { + $indent ++; + } + + $text = $indent > 0 ? substr($line, $indent) : $line; + + # ~ + + $Line = array('body' => $line, 'indent' => $indent, 'text' => $text); + + # ~ + + if (isset($CurrentBlock['continuable'])) + { + $Block = $this->{'block'.$CurrentBlock['type'].'Continue'}($Line, $CurrentBlock); + + if (isset($Block)) + { + $CurrentBlock = $Block; + + continue; + } + else + { + if ($this->isBlockCompletable($CurrentBlock['type'])) + { + $CurrentBlock = $this->{'block'.$CurrentBlock['type'].'Complete'}($CurrentBlock); + } + } + } + + # ~ + + $marker = $text[0]; + + # ~ + + $blockTypes = $this->unmarkedBlockTypes; + + if (isset($this->BlockTypes[$marker])) + { + foreach ($this->BlockTypes[$marker] as $blockType) + { + $blockTypes []= $blockType; + } + } + + # + # ~ + + foreach ($blockTypes as $blockType) + { + $Block = $this->{'block'.$blockType}($Line, $CurrentBlock); + + if (isset($Block)) + { + $Block['type'] = $blockType; + + if ( ! isset($Block['identified'])) + { + $Blocks []= $CurrentBlock; + + $Block['identified'] = true; + } + + if ($this->isBlockContinuable($blockType)) + { + $Block['continuable'] = true; + } + + $CurrentBlock = $Block; + + continue 2; + } + } + + # ~ + + if (isset($CurrentBlock) and ! isset($CurrentBlock['type']) and ! isset($CurrentBlock['interrupted'])) + { + $CurrentBlock['element']['text'] .= "\n".$text; + } + else + { + $Blocks []= $CurrentBlock; + + $CurrentBlock = $this->paragraph($Line); + + $CurrentBlock['identified'] = true; + } + } + + # ~ + + if (isset($CurrentBlock['continuable']) and $this->isBlockCompletable($CurrentBlock['type'])) + { + $CurrentBlock = $this->{'block'.$CurrentBlock['type'].'Complete'}($CurrentBlock); + } + + # ~ + + $Blocks []= $CurrentBlock; + + unset($Blocks[0]); + + # ~ + + $markup = ''; + + foreach ($Blocks as $Block) + { + if (isset($Block['hidden'])) + { + continue; + } + + $markup .= "\n"; + $markup .= isset($Block['markup']) ? $Block['markup'] : $this->element($Block['element']); + } + + $markup .= "\n"; + + # ~ + + return $markup; + } + + protected function isBlockContinuable($Type) + { + return method_exists($this, 'block'.$Type.'Continue'); + } + + protected function isBlockCompletable($Type) + { + return method_exists($this, 'block'.$Type.'Complete'); + } + + # + # Code + + protected function blockCode($Line, $Block = null) + { + if (isset($Block) and ! isset($Block['type']) and ! isset($Block['interrupted'])) + { + return; + } + + if ($Line['indent'] >= 4) + { + $text = substr($Line['body'], 4); + + $Block = array( + 'element' => array( + 'name' => 'pre', + 'handler' => 'element', + 'text' => array( + 'name' => 'code', + 'text' => $text, + ), + ), + ); + + return $Block; + } + } + + protected function blockCodeContinue($Line, $Block) + { + if ($Line['indent'] >= 4) + { + if (isset($Block['interrupted'])) + { + $Block['element']['text']['text'] .= "\n"; + + unset($Block['interrupted']); + } + + $Block['element']['text']['text'] .= "\n"; + + $text = substr($Line['body'], 4); + + $Block['element']['text']['text'] .= $text; + + return $Block; + } + } + + protected function blockCodeComplete($Block) + { + $text = $Block['element']['text']['text']; + + $text = htmlspecialchars($text, ENT_NOQUOTES, 'UTF-8'); + + $Block['element']['text']['text'] = $text; + + return $Block; + } + + # + # Comment + + protected function blockComment($Line) + { + if ($this->markupEscaped) + { + return; + } + + if (isset($Line['text'][3]) and $Line['text'][3] === '-' and $Line['text'][2] === '-' and $Line['text'][1] === '!') + { + $Block = array( + 'markup' => $Line['body'], + ); + + if (preg_match('/-->$/', $Line['text'])) + { + $Block['closed'] = true; + } + + return $Block; + } + } + + protected function blockCommentContinue($Line, array $Block) + { + if (isset($Block['closed'])) + { + return; + } + + $Block['markup'] .= "\n" . $Line['body']; + + if (preg_match('/-->$/', $Line['text'])) + { + $Block['closed'] = true; + } + + return $Block; + } + + # + # Fenced Code + + protected function blockFencedCode($Line) + { + if (preg_match('/^['.$Line['text'][0].']{3,}[ ]*([\w-]+)?[ ]*$/', $Line['text'], $matches)) + { + $Element = array( + 'name' => 'code', + 'text' => '', + ); + + if (isset($matches[1])) + { + $class = 'language-'.$matches[1]; + + $Element['attributes'] = array( + 'class' => $class, + ); + } + + $Block = array( + 'char' => $Line['text'][0], + 'element' => array( + 'name' => 'pre', + 'handler' => 'element', + 'text' => $Element, + ), + ); + + return $Block; + } + } + + protected function blockFencedCodeContinue($Line, $Block) + { + if (isset($Block['complete'])) + { + return; + } + + if (isset($Block['interrupted'])) + { + $Block['element']['text']['text'] .= "\n"; + + unset($Block['interrupted']); + } + + if (preg_match('/^'.$Block['char'].'{3,}[ ]*$/', $Line['text'])) + { + $Block['element']['text']['text'] = substr($Block['element']['text']['text'], 1); + + $Block['complete'] = true; + + return $Block; + } + + $Block['element']['text']['text'] .= "\n".$Line['body']; + + return $Block; + } + + protected function blockFencedCodeComplete($Block) + { + $text = $Block['element']['text']['text']; + + $text = htmlspecialchars($text, ENT_NOQUOTES, 'UTF-8'); + + $Block['element']['text']['text'] = $text; + + return $Block; + } + + # + # Header + + protected function blockHeader($Line) + { + if (isset($Line['text'][1])) + { + $level = 1; + + while (isset($Line['text'][$level]) and $Line['text'][$level] === '#') + { + $level ++; + } + + if ($level > 6) + { + return; + } + + $text = trim($Line['text'], '# '); + + $Block = array( + 'element' => array( + 'name' => 'h' . min(6, $level), + 'text' => $text, + 'handler' => 'line', + ), + ); + + return $Block; + } + } + + # + # List + + protected function blockList($Line) + { + list($name, $pattern) = $Line['text'][0] <= '-' ? array('ul', '[*+-]') : array('ol', '[0-9]+[.]'); + + if (preg_match('/^('.$pattern.'[ ]+)(.*)/', $Line['text'], $matches)) + { + $Block = array( + 'indent' => $Line['indent'], + 'pattern' => $pattern, + 'element' => array( + 'name' => $name, + 'handler' => 'elements', + ), + ); + + if($name === 'ol') + { + $listStart = stristr($matches[0], '.', true); + + if($listStart !== '1') + { + $Block['element']['attributes'] = array('start' => $listStart); + } + } + + $Block['li'] = array( + 'name' => 'li', + 'handler' => 'li', + 'text' => array( + $matches[2], + ), + ); + + $Block['element']['text'] []= & $Block['li']; + + return $Block; + } + } + + protected function blockListContinue($Line, array $Block) + { + if ($Block['indent'] === $Line['indent'] and preg_match('/^'.$Block['pattern'].'(?:[ ]+(.*)|$)/', $Line['text'], $matches)) + { + if (isset($Block['interrupted'])) + { + $Block['li']['text'] []= ''; + + unset($Block['interrupted']); + } + + unset($Block['li']); + + $text = isset($matches[1]) ? $matches[1] : ''; + + $Block['li'] = array( + 'name' => 'li', + 'handler' => 'li', + 'text' => array( + $text, + ), + ); + + $Block['element']['text'] []= & $Block['li']; + + return $Block; + } + + if ($Line['text'][0] === '[' and $this->blockReference($Line)) + { + return $Block; + } + + if ( ! isset($Block['interrupted'])) + { + $text = preg_replace('/^[ ]{0,4}/', '', $Line['body']); + + $Block['li']['text'] []= $text; + + return $Block; + } + + if ($Line['indent'] > 0) + { + $Block['li']['text'] []= ''; + + $text = preg_replace('/^[ ]{0,4}/', '', $Line['body']); + + $Block['li']['text'] []= $text; + + unset($Block['interrupted']); + + return $Block; + } + } + + # + # Quote + + protected function blockQuote($Line) + { + if (preg_match('/^>[ ]?(.*)/', $Line['text'], $matches)) + { + $Block = array( + 'element' => array( + 'name' => 'blockquote', + 'handler' => 'lines', + 'text' => (array) $matches[1], + ), + ); + + return $Block; + } + } + + protected function blockQuoteContinue($Line, array $Block) + { + if ($Line['text'][0] === '>' and preg_match('/^>[ ]?(.*)/', $Line['text'], $matches)) + { + if (isset($Block['interrupted'])) + { + $Block['element']['text'] []= ''; + + unset($Block['interrupted']); + } + + $Block['element']['text'] []= $matches[1]; + + return $Block; + } + + if ( ! isset($Block['interrupted'])) + { + $Block['element']['text'] []= $Line['text']; + + return $Block; + } + } + + # + # Rule + + protected function blockRule($Line) + { + if (preg_match('/^(['.$Line['text'][0].'])([ ]*\1){2,}[ ]*$/', $Line['text'])) + { + $Block = array( + 'element' => array( + 'name' => 'hr' + ), + ); + + return $Block; + } + } + + # + # Setext + + protected function blockSetextHeader($Line, array $Block = null) + { + if ( ! isset($Block) or isset($Block['type']) or isset($Block['interrupted'])) + { + return; + } + + if (chop($Line['text'], $Line['text'][0]) === '') + { + $Block['element']['name'] = $Line['text'][0] === '=' ? 'h1' : 'h2'; + + return $Block; + } + } + + # + # Markup + + protected function blockMarkup($Line) + { + if ($this->markupEscaped) + { + return; + } + + if (preg_match('/^<(\w*)(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*(\/)?>/', $Line['text'], $matches)) + { + $element = strtolower($matches[1]); + + if (in_array($element, $this->textLevelElements)) + { + return; + } + + $Block = array( + 'name' => $matches[1], + 'depth' => 0, + 'markup' => $Line['text'], + ); + + $length = strlen($matches[0]); + + $remainder = substr($Line['text'], $length); + + if (trim($remainder) === '') + { + if (isset($matches[2]) or in_array($matches[1], $this->voidElements)) + { + $Block['closed'] = true; + + $Block['void'] = true; + } + } + else + { + if (isset($matches[2]) or in_array($matches[1], $this->voidElements)) + { + return; + } + + if (preg_match('/<\/'.$matches[1].'>[ ]*$/i', $remainder)) + { + $Block['closed'] = true; + } + } + + return $Block; + } + } + + protected function blockMarkupContinue($Line, array $Block) + { + if (isset($Block['closed'])) + { + return; + } + + if (preg_match('/^<'.$Block['name'].'(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*>/i', $Line['text'])) # open + { + $Block['depth'] ++; + } + + if (preg_match('/(.*?)<\/'.$Block['name'].'>[ ]*$/i', $Line['text'], $matches)) # close + { + if ($Block['depth'] > 0) + { + $Block['depth'] --; + } + else + { + $Block['closed'] = true; + } + } + + if (isset($Block['interrupted'])) + { + $Block['markup'] .= "\n"; + + unset($Block['interrupted']); + } + + $Block['markup'] .= "\n".$Line['body']; + + return $Block; + } + + # + # Reference + + protected function blockReference($Line) + { + if (preg_match('/^\[(.+?)\]:[ ]*?(?:[ ]+["\'(](.+)["\')])?[ ]*$/', $Line['text'], $matches)) + { + $id = strtolower($matches[1]); + + $Data = array( + 'url' => $matches[2], + 'title' => null, + ); + + if (isset($matches[3])) + { + $Data['title'] = $matches[3]; + } + + $this->DefinitionData['Reference'][$id] = $Data; + + $Block = array( + 'hidden' => true, + ); + + return $Block; + } + } + + # + # Table + + protected function blockTable($Line, array $Block = null) + { + if ( ! isset($Block) or isset($Block['type']) or isset($Block['interrupted'])) + { + return; + } + + if (strpos($Block['element']['text'], '|') !== false and chop($Line['text'], ' -:|') === '') + { + $alignments = array(); + + $divider = $Line['text']; + + $divider = trim($divider); + $divider = trim($divider, '|'); + + $dividerCells = explode('|', $divider); + + foreach ($dividerCells as $dividerCell) + { + $dividerCell = trim($dividerCell); + + if ($dividerCell === '') + { + continue; + } + + $alignment = null; + + if ($dividerCell[0] === ':') + { + $alignment = 'left'; + } + + if (substr($dividerCell, - 1) === ':') + { + $alignment = $alignment === 'left' ? 'center' : 'right'; + } + + $alignments []= $alignment; + } + + # ~ + + $HeaderElements = array(); + + $header = $Block['element']['text']; + + $header = trim($header); + $header = trim($header, '|'); + + $headerCells = explode('|', $header); + + foreach ($headerCells as $index => $headerCell) + { + $headerCell = trim($headerCell); + + $HeaderElement = array( + 'name' => 'th', + 'text' => $headerCell, + 'handler' => 'line', + ); + + if (isset($alignments[$index])) + { + $alignment = $alignments[$index]; + + $HeaderElement['attributes'] = array( + 'style' => 'text-align: '.$alignment.';', + ); + } + + $HeaderElements []= $HeaderElement; + } + + # ~ + + $Block = array( + 'alignments' => $alignments, + 'identified' => true, + 'element' => array( + 'name' => 'table', + 'handler' => 'elements', + ), + ); + + $Block['element']['text'] []= array( + 'name' => 'thead', + 'handler' => 'elements', + ); + + $Block['element']['text'] []= array( + 'name' => 'tbody', + 'handler' => 'elements', + 'text' => array(), + ); + + $Block['element']['text'][0]['text'] []= array( + 'name' => 'tr', + 'handler' => 'elements', + 'text' => $HeaderElements, + ); + + return $Block; + } + } + + protected function blockTableContinue($Line, array $Block) + { + if (isset($Block['interrupted'])) + { + return; + } + + if ($Line['text'][0] === '|' or strpos($Line['text'], '|')) + { + $Elements = array(); + + $row = $Line['text']; + + $row = trim($row); + $row = trim($row, '|'); + + preg_match_all('/(?:(\\\\[|])|[^|`]|`[^`]+`|`)+/', $row, $matches); + + foreach ($matches[0] as $index => $cell) + { + $cell = trim($cell); + + $Element = array( + 'name' => 'td', + 'handler' => 'line', + 'text' => $cell, + ); + + if (isset($Block['alignments'][$index])) + { + $Element['attributes'] = array( + 'style' => 'text-align: '.$Block['alignments'][$index].';', + ); + } + + $Elements []= $Element; + } + + $Element = array( + 'name' => 'tr', + 'handler' => 'elements', + 'text' => $Elements, + ); + + $Block['element']['text'][1]['text'] []= $Element; + + return $Block; + } + } + + # + # ~ + # + + protected function paragraph($Line) + { + $Block = array( + 'element' => array( + 'name' => 'p', + 'text' => $Line['text'], + 'handler' => 'line', + ), + ); + + return $Block; + } + + # + # Inline Elements + # + + protected $InlineTypes = array( + '"' => array('SpecialCharacter'), + '!' => array('Image'), + '&' => array('SpecialCharacter'), + '*' => array('Emphasis'), + ':' => array('Url'), + '<' => array('UrlTag', 'EmailTag', 'Markup', 'SpecialCharacter'), + '>' => array('SpecialCharacter'), + '[' => array('Link'), + '_' => array('Emphasis'), + '`' => array('Code'), + '~' => array('Strikethrough'), + '\\' => array('EscapeSequence'), + ); + + # ~ + + protected $inlineMarkerList = '!"*_&[:<>`~\\'; + + # + # ~ + # + + public function line($text) + { + $markup = ''; + + # $excerpt is based on the first occurrence of a marker + + while ($excerpt = strpbrk($text, $this->inlineMarkerList)) + { + $marker = $excerpt[0]; + + $markerPosition = strpos($text, $marker); + + $Excerpt = array('text' => $excerpt, 'context' => $text); + + foreach ($this->InlineTypes[$marker] as $inlineType) + { + $Inline = $this->{'inline'.$inlineType}($Excerpt); + + if ( ! isset($Inline)) + { + continue; + } + + # makes sure that the inline belongs to "our" marker + + if (isset($Inline['position']) and $Inline['position'] > $markerPosition) + { + continue; + } + + # sets a default inline position + + if ( ! isset($Inline['position'])) + { + $Inline['position'] = $markerPosition; + } + + # the text that comes before the inline + $unmarkedText = substr($text, 0, $Inline['position']); + + # compile the unmarked text + $markup .= $this->unmarkedText($unmarkedText); + + # compile the inline + $markup .= isset($Inline['markup']) ? $Inline['markup'] : $this->element($Inline['element']); + + # remove the examined text + $text = substr($text, $Inline['position'] + $Inline['extent']); + + continue 2; + } + + # the marker does not belong to an inline + + $unmarkedText = substr($text, 0, $markerPosition + 1); + + $markup .= $this->unmarkedText($unmarkedText); + + $text = substr($text, $markerPosition + 1); + } + + $markup .= $this->unmarkedText($text); + + return $markup; + } + + # + # ~ + # + + protected function inlineCode($Excerpt) + { + $marker = $Excerpt['text'][0]; + + if (preg_match('/^('.$marker.'+)[ ]*(.+?)[ ]*(? strlen($matches[0]), + 'element' => array( + 'name' => 'code', + 'text' => $text, + ), + ); + } + } + + protected function inlineEmailTag($Excerpt) + { + if (strpos($Excerpt['text'], '>') !== false and preg_match('/^<((mailto:)?\S+?@\S+?)>/i', $Excerpt['text'], $matches)) + { + $url = $matches[1]; + + if ( ! isset($matches[2])) + { + $url = 'mailto:' . $url; + } + + return array( + 'extent' => strlen($matches[0]), + 'element' => array( + 'name' => 'a', + 'text' => $matches[1], + 'attributes' => array( + 'href' => $url, + ), + ), + ); + } + } + + protected function inlineEmphasis($Excerpt) + { + if ( ! isset($Excerpt['text'][1])) + { + return; + } + + $marker = $Excerpt['text'][0]; + + if ($Excerpt['text'][1] === $marker and preg_match($this->StrongRegex[$marker], $Excerpt['text'], $matches)) + { + $emphasis = 'strong'; + } + elseif (preg_match($this->EmRegex[$marker], $Excerpt['text'], $matches)) + { + $emphasis = 'em'; + } + else + { + return; + } + + return array( + 'extent' => strlen($matches[0]), + 'element' => array( + 'name' => $emphasis, + 'handler' => 'line', + 'text' => $matches[1], + ), + ); + } + + protected function inlineEscapeSequence($Excerpt) + { + if (isset($Excerpt['text'][1]) and in_array($Excerpt['text'][1], $this->specialCharacters)) + { + return array( + 'markup' => $Excerpt['text'][1], + 'extent' => 2, + ); + } + } + + protected function inlineImage($Excerpt) + { + if ( ! isset($Excerpt['text'][1]) or $Excerpt['text'][1] !== '[') + { + return; + } + + $Excerpt['text']= substr($Excerpt['text'], 1); + + $Link = $this->inlineLink($Excerpt); + + if ($Link === null) + { + return; + } + + $Inline = array( + 'extent' => $Link['extent'] + 1, + 'element' => array( + 'name' => 'img', + 'attributes' => array( + 'src' => $Link['element']['attributes']['href'], + 'alt' => $Link['element']['text'], + ), + ), + ); + + $Inline['element']['attributes'] += $Link['element']['attributes']; + + unset($Inline['element']['attributes']['href']); + + return $Inline; + } + + protected function inlineLink($Excerpt) + { + $Element = array( + 'name' => 'a', + 'handler' => 'line', + 'text' => null, + 'attributes' => array( + 'href' => null, + 'title' => null, + ), + ); + + $extent = 0; + + $remainder = $Excerpt['text']; + + if (preg_match('/\[((?:[^][]++|(?R))*+)\]/', $remainder, $matches)) + { + $Element['text'] = $matches[1]; + + $extent += strlen($matches[0]); + + $remainder = substr($remainder, $extent); + } + else + { + return; + } + + if (preg_match('/^[(]\s*+((?:[^ ()]++|[(][^ )]+[)])++)(?:[ ]+("[^"]*"|\'[^\']*\'))?\s*[)]/', $remainder, $matches)) + { + $Element['attributes']['href'] = $matches[1]; + + if (isset($matches[2])) + { + $Element['attributes']['title'] = substr($matches[2], 1, - 1); + } + + $extent += strlen($matches[0]); + } + else + { + if (preg_match('/^\s*\[(.*?)\]/', $remainder, $matches)) + { + $definition = strlen($matches[1]) ? $matches[1] : $Element['text']; + $definition = strtolower($definition); + + $extent += strlen($matches[0]); + } + else + { + $definition = strtolower($Element['text']); + } + + if ( ! isset($this->DefinitionData['Reference'][$definition])) + { + return; + } + + $Definition = $this->DefinitionData['Reference'][$definition]; + + $Element['attributes']['href'] = $Definition['url']; + $Element['attributes']['title'] = $Definition['title']; + } + + $Element['attributes']['href'] = str_replace(array('&', '<'), array('&', '<'), $Element['attributes']['href']); + + return array( + 'extent' => $extent, + 'element' => $Element, + ); + } + + protected function inlineMarkup($Excerpt) + { + if ($this->markupEscaped or strpos($Excerpt['text'], '>') === false) + { + return; + } + + if ($Excerpt['text'][1] === '/' and preg_match('/^<\/\w*[ ]*>/s', $Excerpt['text'], $matches)) + { + return array( + 'markup' => $matches[0], + 'extent' => strlen($matches[0]), + ); + } + + if ($Excerpt['text'][1] === '!' and preg_match('/^/s', $Excerpt['text'], $matches)) + { + return array( + 'markup' => $matches[0], + 'extent' => strlen($matches[0]), + ); + } + + if ($Excerpt['text'][1] !== ' ' and preg_match('/^<\w*(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*\/?>/s', $Excerpt['text'], $matches)) + { + return array( + 'markup' => $matches[0], + 'extent' => strlen($matches[0]), + ); + } + } + + protected function inlineSpecialCharacter($Excerpt) + { + if ($Excerpt['text'][0] === '&' and ! preg_match('/^&#?\w+;/', $Excerpt['text'])) + { + return array( + 'markup' => '&', + 'extent' => 1, + ); + } + + $SpecialCharacter = array('>' => 'gt', '<' => 'lt', '"' => 'quot'); + + if (isset($SpecialCharacter[$Excerpt['text'][0]])) + { + return array( + 'markup' => '&'.$SpecialCharacter[$Excerpt['text'][0]].';', + 'extent' => 1, + ); + } + } + + protected function inlineStrikethrough($Excerpt) + { + if ( ! isset($Excerpt['text'][1])) + { + return; + } + + if ($Excerpt['text'][1] === '~' and preg_match('/^~~(?=\S)(.+?)(?<=\S)~~/', $Excerpt['text'], $matches)) + { + return array( + 'extent' => strlen($matches[0]), + 'element' => array( + 'name' => 'del', + 'text' => $matches[1], + 'handler' => 'line', + ), + ); + } + } + + protected function inlineUrl($Excerpt) + { + if ($this->urlsLinked !== true or ! isset($Excerpt['text'][2]) or $Excerpt['text'][2] !== '/') + { + return; + } + + if (preg_match('/\bhttps?:[\/]{2}[^\s<]+\b\/*/ui', $Excerpt['context'], $matches, PREG_OFFSET_CAPTURE)) + { + $Inline = array( + 'extent' => strlen($matches[0][0]), + 'position' => $matches[0][1], + 'element' => array( + 'name' => 'a', + 'text' => $matches[0][0], + 'attributes' => array( + 'href' => $matches[0][0], + ), + ), + ); + + return $Inline; + } + } + + protected function inlineUrlTag($Excerpt) + { + if (strpos($Excerpt['text'], '>') !== false and preg_match('/^<(\w+:\/{2}[^ >]+)>/i', $Excerpt['text'], $matches)) + { + $url = str_replace(array('&', '<'), array('&', '<'), $matches[1]); + + return array( + 'extent' => strlen($matches[0]), + 'element' => array( + 'name' => 'a', + 'text' => $url, + 'attributes' => array( + 'href' => $url, + ), + ), + ); + } + } + + # ~ + + protected function unmarkedText($text) + { + if ($this->breaksEnabled) + { + $text = preg_replace('/[ ]*\n/', "
\n", $text); + } + else + { + $text = preg_replace('/(?:[ ][ ]+|[ ]*\\\\)\n/', "
\n", $text); + $text = str_replace(" \n", "\n", $text); + } + + return $text; + } + + # + # Handlers + # + + protected function element(array $Element) + { + $markup = '<'.$Element['name']; + + if (isset($Element['attributes'])) + { + foreach ($Element['attributes'] as $name => $value) + { + if ($value === null) + { + continue; + } + + $markup .= ' '.$name.'="'.$value.'"'; + } + } + + if (isset($Element['text'])) + { + $markup .= '>'; + + if (isset($Element['handler'])) + { + $markup .= $this->{$Element['handler']}($Element['text']); + } + else + { + $markup .= $Element['text']; + } + + $markup .= ''; + } + else + { + $markup .= ' />'; + } + + return $markup; + } + + protected function elements(array $Elements) + { + $markup = ''; + + foreach ($Elements as $Element) + { + $markup .= "\n" . $this->element($Element); + } + + $markup .= "\n"; + + return $markup; + } + + # ~ + + protected function li($lines) + { + $markup = $this->lines($lines); + + $trimmedMarkup = trim($markup); + + if ( ! in_array('', $lines) and substr($trimmedMarkup, 0, 3) === '

') + { + $markup = $trimmedMarkup; + $markup = substr($markup, 3); + + $position = strpos($markup, "

"); + + $markup = substr_replace($markup, '', $position, 4); + } + + return $markup; + } + + # + # Deprecated Methods + # + + function parse($text) + { + $markup = $this->text($text); + + return $markup; + } + + # + # Static Methods + # + + static function instance($name = 'default') + { + if (isset(self::$instances[$name])) + { + return self::$instances[$name]; + } + + $instance = new static(); + + self::$instances[$name] = $instance; + + return $instance; + } + + private static $instances = array(); + + # + # Fields + # + + protected $DefinitionData; + + # + # Read-Only + + protected $specialCharacters = array( + '\\', '`', '*', '_', '{', '}', '[', ']', '(', ')', '>', '#', '+', '-', '.', '!', '|', + ); + + protected $StrongRegex = array( + '*' => '/^[*]{2}((?:\\\\\*|[^*]|[*][^*]*[*])+?)[*]{2}(?![*])/s', + '_' => '/^__((?:\\\\_|[^_]|_[^_]*_)+?)__(?!_)/us', + ); + + protected $EmRegex = array( + '*' => '/^[*]((?:\\\\\*|[^*]|[*][*][^*]+?[*][*])+?)[*](?![*])/s', + '_' => '/^_((?:\\\\_|[^_]|__[^_]*__)+?)_(?!_)\b/us', + ); + + protected $regexHtmlAttribute = '[a-zA-Z_:][\w:.-]*(?:\s*=\s*(?:[^"\'=<>`\s]+|"[^"]*"|\'[^\']*\'))?'; + + protected $voidElements = array( + 'area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', + ); + + protected $textLevelElements = array( + 'a', 'br', 'bdo', 'abbr', 'blink', 'nextid', 'acronym', 'basefont', + 'b', 'em', 'big', 'cite', 'small', 'spacer', 'listing', + 'i', 'rp', 'del', 'code', 'strike', 'marquee', + 'q', 'rt', 'ins', 'font', 'strong', + 's', 'tt', 'sub', 'mark', + 'u', 'xm', 'sup', 'nobr', + 'var', 'ruby', + 'wbr', 'span', + 'time', + ); +} diff --git a/htdocs/includes/parsedown/README.md b/htdocs/includes/parsedown/README.md new file mode 100644 index 00000000000..4e5659a4804 --- /dev/null +++ b/htdocs/includes/parsedown/README.md @@ -0,0 +1,56 @@ +> You might also like [Caret](http://caret.io?ref=parsedown) - our Markdown editor for Mac / Windows / Linux. + +## Parsedown + +[![Build Status](https://img.shields.io/travis/erusev/parsedown/master.svg?style=flat-square)](https://travis-ci.org/erusev/parsedown) + + +Better Markdown Parser in PHP + +[Demo](http://parsedown.org/demo) | +[Benchmarks](http://parsedown.org/speed) | +[Tests](http://parsedown.org/tests/) | +[Documentation](https://github.com/erusev/parsedown/wiki/) + +### Features + +* One File +* Super Fast +* Extensible +* [GitHub flavored](https://help.github.com/articles/github-flavored-markdown) +* Tested in 5.3 to 7.1 and in HHVM +* [Markdown Extra extension](https://github.com/erusev/parsedown-extra) + +### Installation + +Include `Parsedown.php` or install [the composer package](https://packagist.org/packages/erusev/parsedown). + +### Example + +``` php +$Parsedown = new Parsedown(); + +echo $Parsedown->text('Hello _Parsedown_!'); # prints:

Hello Parsedown!

+``` + +More examples in [the wiki](https://github.com/erusev/parsedown/wiki/) and in [this video tutorial](http://youtu.be/wYZBY8DEikI). + +### Questions + +**How does Parsedown work?** + +It tries to read Markdown like a human. First, it looks at the lines. It’s interested in how the lines start. This helps it recognise blocks. It knows, for example, that if a line starts with a `-` then perhaps it belongs to a list. Once it recognises the blocks, it continues to the content. As it reads, it watches out for special characters. This helps it recognise inline elements (or inlines). + +We call this approach "line based". We believe that Parsedown is the first Markdown parser to use it. Since the release of Parsedown, other developers have used the same approach to develop other Markdown parsers in PHP and in other languages. + +**Is it compliant with CommonMark?** + +It passes most of the CommonMark tests. Most of the tests that don't pass deal with cases that are quite uncommon. Still, as CommonMark matures, compliance should improve. + +**Who uses it?** + +[phpDocumentor](http://www.phpdoc.org/), [October CMS](http://octobercms.com/), [Bolt CMS](http://bolt.cm/), [Kirby CMS](http://getkirby.com/), [Grav CMS](http://getgrav.org/), [Statamic CMS](http://www.statamic.com/), [Herbie CMS](http://www.getherbie.org/), [RaspberryPi.org](http://www.raspberrypi.org/), [Symfony demo](https://github.com/symfony/symfony-demo) and [more](https://packagist.org/packages/erusev/parsedown/dependents). + +**How can I help?** + +Use it, star it, share it and if you feel generous, [donate](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=528P3NZQMP8N2). diff --git a/htdocs/includes/parsedown/composer.json b/htdocs/includes/parsedown/composer.json new file mode 100644 index 00000000000..28145af68ca --- /dev/null +++ b/htdocs/includes/parsedown/composer.json @@ -0,0 +1,21 @@ +{ + "name": "erusev/parsedown", + "description": "Parser for Markdown.", + "keywords": ["markdown", "parser"], + "homepage": "http://parsedown.org", + "type": "library", + "license": "MIT", + "authors": [ + { + "name": "Emanuil Rusev", + "email": "hello@erusev.com", + "homepage": "http://erusev.com" + } + ], + "require": { + "php": ">=5.3.0" + }, + "autoload": { + "psr-0": {"Parsedown": ""} + } +} diff --git a/htdocs/includes/parsedown/phpunit.xml.dist b/htdocs/includes/parsedown/phpunit.xml.dist new file mode 100644 index 00000000000..b2d5e9d4fe1 --- /dev/null +++ b/htdocs/includes/parsedown/phpunit.xml.dist @@ -0,0 +1,8 @@ + + + + + test/ParsedownTest.php + + + \ No newline at end of file diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index f5aa35f0c35..69881d693c6 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1131,6 +1131,7 @@ CompanyIdProfChecker=Rules on Professional Ids MustBeUnique=Must be unique? MustBeMandatory=Mandatory to create third parties? MustBeInvoiceMandatory=Mandatory to validate invoices? +TechnicalServicesProvided=Technical services provided ##### Webcal setup ##### WebCalUrlForVCalExport=An export link to %s format is available at following link: %s ##### Invoices ##### From b5e646daa0620ec92f0953730acdd2f4369dbd54 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 21 Mar 2017 16:29:31 +0100 Subject: [PATCH 10/16] NEW Show by default README.md file found into root dir of ext module. --- htdocs/admin/modulehelp.php | 2 +- htdocs/core/lib/parsemd.lib.php | 18 ++++-- htdocs/core/modules/DolibarrModules.class.php | 58 ++++++++++++++++--- htdocs/theme/eldy/style.css.php | 7 +++ htdocs/theme/md/style.css.php | 7 +++ 5 files changed, 79 insertions(+), 13 deletions(-) diff --git a/htdocs/admin/modulehelp.php b/htdocs/admin/modulehelp.php index e76627c2965..5b428443248 100644 --- a/htdocs/admin/modulehelp.php +++ b/htdocs/admin/modulehelp.php @@ -338,7 +338,7 @@ if ($mode == 'desc') $text.='
'; $moduledesclong=$objMod->getDescLong(); - if ($moduledesclong) $text.='


'.$moduledesclong.'
'; + if ($moduledesclong) $text.='

'.$moduledesclong.'
'; } if ($mode == 'feature') diff --git a/htdocs/core/lib/parsemd.lib.php b/htdocs/core/lib/parsemd.lib.php index 17e64f6543e..1eb962463c0 100644 --- a/htdocs/core/lib/parsemd.lib.php +++ b/htdocs/core/lib/parsemd.lib.php @@ -24,12 +24,22 @@ /** * Function to parse MD content into HTML * - * @param string $content MD content - * @param string $parser 'parsedown' or 'nl2br' - * @return string Parsed content + * @param string $content MD content + * @param string $parser 'parsedown' or 'nl2br' + * @param string $replaceimagepath Replace path to image with another path. Exemple: ('doc/'=>'xxx/aaa/') + * @return string Parsed content */ -function dolMd2Html($content, $parser='parsedown') +function dolMd2Html($content, $parser='parsedown',$replaceimagepath=null) { + if (is_array($replaceimagepath)) + { + foreach($replaceimagepath as $key => $val) + { + $keytoreplace = ']('.$key; + $valafter = ']('.$val; + $content = preg_replace('/'.preg_quote($keytoreplace,'/').'/m', $valafter, $content); + } + } if ($parser == 'parsedown') { include DOL_DOCUMENT_ROOT.'/includes/parsedown/Parsedown.php'; diff --git a/htdocs/core/modules/DolibarrModules.class.php b/htdocs/core/modules/DolibarrModules.class.php index 84538801add..48ce35f1532 100644 --- a/htdocs/core/modules/DolibarrModules.class.php +++ b/htdocs/core/modules/DolibarrModules.class.php @@ -582,26 +582,68 @@ class DolibarrModules // Can not be abstract, because we need to insta } /** - * Gives the translated module description if translation exists in admin.lang or the default module description + * Gives the long description of a module. First check README-la_LA.md then README.md + * If not markdown files found, it return translated value of the key ->descriptionlong. * - * @return string Translated module description + * @return string Long description of a module */ function getDescLong() { global $langs; $langs->load("admin"); - if (empty($this->descriptionlong)) return ''; + include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + include_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php'; + + $filefound= false; - // If module description translation does not exist using its unique id, we can use its name to find translation - if (is_array($this->langfiles)) + // Define path to file README.md. + // First check README-la_LA.md then README.md + $pathoffile = dol_buildpath(strtolower($this->name).'/README-'.$langs->defaultlang.'.md', 0); + if (dol_is_file($pathoffile)) { - foreach($this->langfiles as $val) + $filefound = true; + } + if (! $filefound) + { + $pathoffile = dol_buildpath(strtolower($this->name).'/README.md', 0); + if (dol_is_file($pathoffile)) { - if ($val) $langs->load($val); + $filefound = true; } } - return $langs->trans($this->descriptionlong); + + if ($filefound) // Mostly for external modules + { + $content = file_get_contents($pathoffile); + + if ((float) DOL_VERSION >= 6.0) + { + @include_once DOL_DOCUMENT_ROOT.'/core/lib/parsemd.lib.php'; + $content = dolMd2Html($content, 'parsedown', array('doc/'=>dol_buildpath('cabinetmed/doc/', 1))); + } + else + { + $content = nl2br($content); + } + } + else // Mostly for internal modules + { + if (! empty($this->descriptionlong)) + { + if (is_array($this->langfiles)) + { + foreach($this->langfiles as $val) + { + if ($val) $langs->load($val); + } + } + + $content = $langs->trans($this->descriptionlong); + } + } + + return $content; } /** diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 3d6e8868bec..26a0c8d21ed 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -632,6 +632,13 @@ div.myavailability { margin-bottom: 12px; } +/* For the long description of module */ +.moduledesclong p img, .moduledesclong p a img { + max-width: 90% !important; + height: auto !important; +} + + /* DOL_XXX for future usage (when left menu has been removed). If we do not use datatable */ /*.table-responsive { width: calc(100% - 330px); diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index aae0fd7f677..c930b82dd8c 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -640,6 +640,13 @@ div.myavailability { margin-bottom: 12px; } +/* For the long description of module */ +.moduledesclong p img,.moduledesclong p a img { + max-width: 90% !important; + height: auto !important; +} + + /* DOL_XXX for future usage (when left menu has been removed). If we do not use datatable */ /*.table-responsive { width: calc(100% - 330px); From a0fe79a1132b329b744c7bd1b487d358beb9db4a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 21 Mar 2017 16:46:12 +0100 Subject: [PATCH 11/16] Fix duplicate include. --- htdocs/core/lib/parsemd.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/parsemd.lib.php b/htdocs/core/lib/parsemd.lib.php index 1eb962463c0..13334fd400c 100644 --- a/htdocs/core/lib/parsemd.lib.php +++ b/htdocs/core/lib/parsemd.lib.php @@ -42,7 +42,7 @@ function dolMd2Html($content, $parser='parsedown',$replaceimagepath=null) } if ($parser == 'parsedown') { - include DOL_DOCUMENT_ROOT.'/includes/parsedown/Parsedown.php'; + include_once DOL_DOCUMENT_ROOT.'/includes/parsedown/Parsedown.php'; $Parsedown = new Parsedown(); $content = $Parsedown->text($content); } From e7a45a7f6ad69e42b325d4cf514a2610edc23fc1 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 21 Mar 2017 17:50:43 +0100 Subject: [PATCH 12/16] NEW Use html5 type "number" on select field for year and duration. --- htdocs/core/class/html.form.class.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 0ec07e1c3fa..90c2a98720f 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -4735,7 +4735,7 @@ class Form // Year if ($emptydate || $set_time == -1) { - $retstring.=''; + $retstring.=''; } else { @@ -4918,7 +4918,7 @@ class Form } elseif ($typehour=='text') { - $retstring.=''; + $retstring.=''; } else return 'BadValueForParameterTypeHour'; @@ -4942,7 +4942,7 @@ class Form } elseif ($typehour=='text') { - $retstring.=''; + $retstring.=''; } if ($typehour!='text') $retstring.=' '.$langs->trans('MinuteShort'); From b0a75da2ac62ca0fd34fd665d8c46ba4a0426bb8 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 21 Mar 2017 17:50:52 +0100 Subject: [PATCH 13/16] Fix css --- htdocs/expensereport/card.php | 59 +++++------------------------------ 1 file changed, 8 insertions(+), 51 deletions(-) diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php index 6061250bfbd..4c28fe0281c 100644 --- a/htdocs/expensereport/card.php +++ b/htdocs/expensereport/card.php @@ -1217,53 +1217,10 @@ if (empty($reshook)) } } - - /* - * Generate or regenerate the PDF document - */ - if ($action == 'builddoc') // GET or POST - { - $depl = new ExpenseReport($db, 0, $_GET['id']); - $depl->fetch($id); - - if ($_REQUEST['model']) - { - $depl->setDocModel($user, $_REQUEST['model']); - } - - $outputlangs = $langs; - if (! empty($_REQUEST['lang_id'])) - { - $outputlangs = new Translate("",$conf); - $outputlangs->setDefaultLang($_REQUEST['lang_id']); - } - $result=expensereport_pdf_create($db, $depl, '', $depl->modelpdf, $outputlangs); - if ($result <= 0) - { - setEventMessages($object->error, $object->errors, 'errors'); - $action=''; - } - } - - // Remove file in doc form - else if ($action == 'remove_file') - { - $object = new ExpenseReport($db, 0, $_GET['id']); - if ($object->fetch($id)) - { - require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - - $object->fetch_thirdparty(); - - $langs->load("other"); - $upload_dir = $conf->expensereport->dir_output; - $file = $upload_dir . '/' . GETPOST('file'); - $ret=dol_delete_file($file,0,0,0,$object); - if ($ret) setEventMessages($langs->trans("FileWasRemoved", GETPOST('urlfile')), null, 'mesgs'); - else setEventMessages($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), null, 'errors'); - $action=''; - } - } + // Actions to build doc + $upload_dir = $conf->expensereport->dir_output; + $permissioncreate = $user->rights->expensereport->creer; + include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php'; } @@ -1352,8 +1309,8 @@ if ($action == 'create') // Public note print '
' . $langs->trans('NotePublic') . ''; + print '' . $langs->trans('NotePublic') . ''; $doleditor = new DolEditor('note_public', $note_public, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, '90%'); print $doleditor->Create(1); @@ -1362,8 +1319,8 @@ if ($action == 'create') // Private note if (empty($user->societe_id)) { print '
' . $langs->trans('NotePrivate') . ''; + print '' . $langs->trans('NotePrivate') . ''; $doleditor = new DolEditor('note_private', $note_private, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, '90%'); print $doleditor->Create(1); From 559232a4d726cb70fe296a7bae6df966c563d9d2 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 21 Mar 2017 17:56:11 +0100 Subject: [PATCH 14/16] bottom-border useless --- htdocs/expensereport/card.php | 6 +++--- htdocs/expensereport/document.php | 2 +- htdocs/expensereport/info.php | 5 ++++- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php index 4c28fe0281c..8ec9d9140cb 100644 --- a/htdocs/expensereport/card.php +++ b/htdocs/expensereport/card.php @@ -1272,8 +1272,8 @@ if ($action == 'create') print ''; $defaultselectuser=$user->id; if (GETPOST('fk_user_author') > 0) $defaultselectuser=GETPOST('fk_user_author'); - $include_users = 'hierarchyme'; - if (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->expensereport->writeall_advance)) $include_users=array(); + $include_users = 'hierarchyme'; + if (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->expensereport->writeall_advance)) $include_users=array(); $s=$form->select_dolusers($defaultselectuser, "fk_user_author", 0, "", 0, $include_users); print $s; print ''; $defaultselectuser=$user->id; if (GETPOST('fk_user_author') > 0) $defaultselectuser=GETPOST('fk_user_author'); - $include_users = 'hierarchyme'; - if (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->expensereport->writeall_advance)) $include_users=array(); + $include_users = 'hierarchyme'; + if (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->expensereport->writeall_advance)) $include_users=array(); $s=$form->select_dolusers($defaultselectuser, "fk_user_author", 0, "", 0, $include_users); print $s; print '
'; - - // Ref - print '"; - - print "
'.$langs->trans("Ref").''; - print $form->showrefnav($object, 'ref', $linkback, 1, 'ref', 'ref'); - print "
"; - - print '
'; - */ print '
'; print '
'; @@ -111,7 +97,6 @@ if ($id > 0 || ! empty($ref)) print '
'; dol_fiche_end(); - } From acdfd6ab9edc33cb8299b9bb853786afe110b54a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 21 Mar 2017 18:23:58 +0100 Subject: [PATCH 16/16] css enhancement --- htdocs/core/class/html.form.class.php | 6 +++--- htdocs/expensereport/card.php | 14 +++++++------- htdocs/theme/eldy/style.css.php | 17 +++++++++++------ htdocs/theme/md/style.css.php | 17 +++++++++++------ 4 files changed, 32 insertions(+), 22 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 90c2a98720f..c5118ec56ef 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -4528,7 +4528,7 @@ class Form $disabled=true; } - if (! $options_only) $return.= ''; $selectedfound=false; foreach ($this->cache_vatrates as $rate) @@ -4717,7 +4717,7 @@ class Form $retstring.=""; - $retstring.=''; + $retstring.=''; if ($emptydate || $set_time == -1) { $retstring.=''; @@ -4739,7 +4739,7 @@ class Form } else { - $retstring.=''; + $retstring.=''; for ($year = $syear - 5; $year < $syear + 10 ; $year++) { diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php index 8ec9d9140cb..fa6018fcd07 100644 --- a/htdocs/expensereport/card.php +++ b/htdocs/expensereport/card.php @@ -1959,7 +1959,7 @@ else print ''; // Select date - print ''; + print ''; $form->select_date($objp->date,'date'); print ''; @@ -1972,13 +1972,13 @@ else } // Select type - print ''; + print ''; select_type_fees_id($objp->type_fees_code,'fk_c_type_fees'); print ''; // Add comments print ''; - print ''; + print ''; print ''; // VAT @@ -1988,12 +1988,12 @@ else // Unit price print ''; - print ''; + print ''; print ''; // Quantity print ''; - print ''; + print ''; print ''; if ($action != 'editline') @@ -2074,12 +2074,12 @@ else // Unit price print ''; - print ''; + print ''; print ''; // Quantity print ''; - print ''; + print ''; print ''; if ($action != 'editline') diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 26a0c8d21ed..086e78f3552 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -693,6 +693,7 @@ div.fiche>form>div.div-table-responsive { .minwidth400 { min-width: 400px; } .minwidth500 { min-width: 500px; } .minwidth50imp { min-width: 50px !important; } + .minwidth75imp { min-width: 75px !important; } .minwidth100imp { min-width: 100px !important; } .minwidth200imp { min-width: 200px !important; } .minwidth300imp { min-width: 300px !important; } @@ -709,6 +710,7 @@ div.fiche>form>div.div-table-responsive { .maxwidth400 { max-width: 400px; } .maxwidth500 { max-width: 500px; } .maxwidth50imp { max-width: 50px !important; } +.maxwidth75imp { max-width: 75px !important; } .minheight20 { min-height: 20px; } .minheight40 { min-height: 40px; } .titlefieldcreate { width: 20%; } @@ -722,6 +724,7 @@ div.fiche>form>div.div-table-responsive { .titlefield { width: 30% !important; } .titlefieldcreate { width: 30% !important; } .minwidth50imp { min-width: 50px !important; } + .minwidth75imp { min-width: 75px !important; } .minwidth100imp { min-width: 100px !important; } .minwidth200imp { min-width: 200px !important; } .minwidth300imp { min-width: 300px !important; } @@ -734,7 +737,8 @@ div.fiche>form>div.div-table-responsive { { .maxwidthonsmartphone { max-width: 100px; } .minwidth50imp { min-width: 50px !important; } - .minwidth100imp { min-width: 50px !important; } + .minwidth75imp { min-width: 70px !important; } + .minwidth100imp { min-width: 80px !important; } .minwidth200imp { min-width: 100px !important; } .minwidth300imp { min-width: 100px !important; } .minwidth400imp { min-width: 100px !important; } @@ -785,11 +789,12 @@ div.fiche>form>div.div-table-responsive { .maxwidth300onsmartphone { max-width: 300px; } .maxwidth400onsmartphone { max-width: 400px; } .minwidth50imp { min-width: 50px !important; } - .minwidth100imp { min-width: 50px !important; } - .minwidth200imp { min-width: 50px !important; } - .minwidth300imp { min-width: 50px !important; } - .minwidth400imp { min-width: 50px !important; } - .minwidth500imp { min-width: 50px !important; } + .minwidth75imp { min-width: 60px !important; } + .minwidth100imp { min-width: 60px !important; } + .minwidth200imp { min-width: 60px !important; } + .minwidth300imp { min-width: 60px !important; } + .minwidth400imp { min-width: 60px !important; } + .minwidth500imp { min-width: 60px !important; } .titlefield { width: auto; } .titlefieldcreate { width: auto; } diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index c930b82dd8c..e90311ca0d2 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -702,6 +702,7 @@ div.fiche>form>div.div-table-responsive { .minwidth400 { min-width: 400px; } .minwidth500 { min-width: 500px; } .minwidth50imp { min-width: 50px !important; } + .minwidth75imp { min-width: 75px !important; } .minwidth100imp { min-width: 100px !important; } .minwidth200imp { min-width: 200px !important; } .minwidth300imp { min-width: 300px !important; } @@ -718,6 +719,7 @@ div.fiche>form>div.div-table-responsive { .maxwidth400 { max-width: 400px; } .maxwidth500 { max-width: 500px; } .maxwidth50imp { max-width: 50px !important; } +.maxwidth75imp { max-width: 75px !important; } .minheight20 { min-height: 20px; } .minheight40 { min-height: 40px; } .titlefieldcreate { width: 20%; } @@ -732,6 +734,7 @@ div.fiche>form>div.div-table-responsive { .titlefield { width: 30% !important; } .titlefieldcreate { width: 30% !important; } .minwidth50imp { min-width: 50px !important; } + .minwidth75imp { min-width: 75px !important; } .minwidth100imp { min-width: 100px !important; } .minwidth200imp { min-width: 200px !important; } .minwidth300imp { min-width: 300px !important; } @@ -744,7 +747,8 @@ div.fiche>form>div.div-table-responsive { { .maxwidthonsmartphone { max-width: 100px; } .minwidth50imp { min-width: 50px !important; } - .minwidth100imp { min-width: 50px !important; } + .minwidth75imp { min-width: 70px !important; } + .minwidth100imp { min-width: 80px !important; } .minwidth200imp { min-width: 100px !important; } .minwidth300imp { min-width: 100px !important; } .minwidth400imp { min-width: 100px !important; } @@ -794,11 +798,12 @@ div.fiche>form>div.div-table-responsive { .maxwidth300onsmartphone { max-width: 300px; } .maxwidth400onsmartphone { max-width: 400px; } .minwidth50imp { min-width: 50px !important; } - .minwidth100imp { min-width: 50px !important; } - .minwidth200imp { min-width: 50px !important; } - .minwidth300imp { min-width: 50px !important; } - .minwidth400imp { min-width: 50px !important; } - .minwidth500imp { min-width: 50px !important; } + .minwidth75imp { min-width: 60px !important; } + .minwidth100imp { min-width: 60px !important; } + .minwidth200imp { min-width: 60px !important; } + .minwidth300imp { min-width: 60px !important; } + .minwidth400imp { min-width: 60px !important; } + .minwidth500imp { min-width: 60px !important; } .titlefield { width: auto; } .titlefieldcreate { width: auto; }