Completed
Branch develop (30080e)
by
unknown
16:47
created
htdocs/contact/list.php 2 patches
Spacing   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -500,7 +500,7 @@  discard block
 block discarded – undo
500 500
 
501 501
 // Add fields from hooks - ListFrom
502 502
 $parameters = array();
503
-$reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object, $action);    // Note that $action and $object may have been modified by hook
503
+$reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
504 504
 $sql .= $hookmanager->resPrint;
505 505
 $sql .= ' WHERE p.entity IN ('.getEntity('contact').')';
506 506
 if (empty($user->rights->societe->client->voir) && !$socid) { //restriction
@@ -543,7 +543,7 @@  discard block
 block discarded – undo
543 543
 			if ($searchCategoryContactOperator == 0) {
544 544
 				$searchCategoryContactSqlList[] = " EXISTS (SELECT ck.fk_socpeople FROM ".MAIN_DB_PREFIX."categorie_contact as ck WHERE p.rowid = ck.fk_socpeople AND ck.fk_categorie = ".((int) $searchCategoryContact).")";
545 545
 			} else {
546
-				$listofcategoryid .= ($listofcategoryid ? ', ' : '') .((int) $searchCategoryContact);
546
+				$listofcategoryid .= ($listofcategoryid ? ', ' : '').((int) $searchCategoryContact);
547 547
 			}
548 548
 		}
549 549
 	}
@@ -575,7 +575,7 @@  discard block
 block discarded – undo
575 575
 			if ($searchCategoryCustomerOperator == 0) {
576 576
 				$searchCategoryCustomerSqlList[] = " EXISTS (SELECT ck.fk_soc FROM ".MAIN_DB_PREFIX."categorie_societe as ck WHERE s.rowid = ck.fk_soc AND ck.fk_categorie = ".((int) $searchCategoryCustomer).")";
577 577
 			} else {
578
-				$listofcategoryid .= ($listofcategoryid ? ', ' : '') .((int) $searchCategoryCustomer);
578
+				$listofcategoryid .= ($listofcategoryid ? ', ' : '').((int) $searchCategoryCustomer);
579 579
 			}
580 580
 		}
581 581
 	}
@@ -607,7 +607,7 @@  discard block
 block discarded – undo
607 607
 			if ($searchCategorySupplierOperator == 0) {
608 608
 				$searchCategorySupplierSqlList[] = " EXISTS (SELECT ck.fk_soc FROM ".MAIN_DB_PREFIX."categorie_fournisseur as ck WHERE s.rowid = ck.fk_soc AND ck.fk_categorie = ".((int) $searchCategorySupplier).")";
609 609
 			} else {
610
-				$listofcategoryid .= ($listofcategoryid ? ', ' : '') .((int) $searchCategorySupplier);
610
+				$listofcategoryid .= ($listofcategoryid ? ', ' : '').((int) $searchCategorySupplier);
611 611
 			}
612 612
 		}
613 613
 	}
@@ -897,7 +897,7 @@  discard block
 block discarded – undo
897 897
 if (count($search_roles) > 0) {
898 898
 	$param .= implode('&search_roles[]=', $search_roles);
899 899
 }
900
-if ($search_birthday_start)	{
900
+if ($search_birthday_start) {
901 901
 	$param .= '&search_birthday_start='.urlencode(dol_print_date($search_birthday_start, '%d')).'&search_birthday_startmonth='.urlencode(dol_print_date($search_birthday_start, '%m')).'&search_birthday_startyear='.urlencode(dol_print_date($search_birthday_start, '%Y'));
902 902
 }
903 903
 if ($search_birthday_end) {
@@ -918,7 +918,7 @@  discard block
 block discarded – undo
918 918
 if (isModEnabled('category') && $user->hasRight('societe', 'creer')) {
919 919
 	$arrayofmassactions['preaffecttag'] = img_picto('', 'category', 'class="pictofixedwidth"').$langs->trans("AffectTag");
920 920
 }
921
-if (GETPOST('nomassaction', 'int') || in_array($massaction, array('presend', 'predelete','preaffecttag'))) {
921
+if (GETPOST('nomassaction', 'int') || in_array($massaction, array('presend', 'predelete', 'preaffecttag'))) {
922 922
 	$arrayofmassactions = array();
923 923
 }
924 924
 if ($contextpage != 'poslist') $massactionbutton = $form->selectMassAction('', $arrayofmassactions);
@@ -946,7 +946,7 @@  discard block
 block discarded – undo
946 946
 if ($contextpage != 'poslist') {
947 947
 	$newcardbutton .= dolGetButtonTitle($langs->trans('NewContactAddress'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/contact/card.php?action=create', '', $permissiontoadd);
948 948
 } elseif ($user->hasRight('societe', 'contact', 'creer')) {
949
-	$url = DOL_URL_ROOT . '/contact/card.php?action=create&type=t&contextpage=poslist&optioncss=print&backtopage=' . urlencode($_SERVER["PHP_SELF"] . '?token=' . newToken() . 'type=t&contextpage=poslist&nomassaction=1&optioncss=print&place='.$place);
949
+	$url = DOL_URL_ROOT.'/contact/card.php?action=create&type=t&contextpage=poslist&optioncss=print&backtopage='.urlencode($_SERVER["PHP_SELF"].'?token='.newToken().'type=t&contextpage=poslist&nomassaction=1&optioncss=print&place='.$place);
950 950
 	$label = 'MenuNewCustomer';
951 951
 	$newcardbutton .= dolGetButtonTitle($langs->trans($label), '', 'fa fa-plus-circle', $url);
952 952
 }
Please login to merge, or discard this patch.
Braces   +6 added lines, -2 removed lines patch added patch discarded remove patch
@@ -277,7 +277,9 @@  discard block
 block discarded – undo
277 277
 $permissiontodelete = $user->hasRight('societe', 'supprimer');
278 278
 $permissiontoadd = $user->hasRight('societe', 'creer');
279 279
 
280
-if (!$permissiontoread) accessforbidden();
280
+if (!$permissiontoread) {
281
+	accessforbidden();
282
+}
281 283
 
282 284
 
283 285
 /*
@@ -921,7 +923,9 @@  discard block
 block discarded – undo
921 923
 if (GETPOST('nomassaction', 'int') || in_array($massaction, array('presend', 'predelete','preaffecttag'))) {
922 924
 	$arrayofmassactions = array();
923 925
 }
924
-if ($contextpage != 'poslist') $massactionbutton = $form->selectMassAction('', $arrayofmassactions);
926
+if ($contextpage != 'poslist') {
927
+	$massactionbutton = $form->selectMassAction('', $arrayofmassactions);
928
+}
925 929
 
926 930
 print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'" name="formfilter">';
927 931
 if ($optioncss != '') {
Please login to merge, or discard this patch.
htdocs/core/lib/modulebuilder.lib.php 1 patch
Spacing   +51 added lines, -51 removed lines patch added patch discarded remove patch
@@ -270,22 +270,22 @@  discard block
 block discarded – undo
270 270
 	// Edit .sql file
271 271
 	if ($moduletype == 'internal') {
272 272
 		$pathoffiletoeditsrc = '/../install/mysql/tables/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql';
273
-		if (! dol_is_file($readdir.$pathoffiletoeditsrc)) {
273
+		if (!dol_is_file($readdir.$pathoffiletoeditsrc)) {
274 274
 			$pathoffiletoeditsrc = '/../install/mysql/tables/llx_'.strtolower($module).'_'.strtolower($objectname).'-'.strtolower($module).'.sql';
275
-			if (! dol_is_file($readdir.$pathoffiletoeditsrc)) {
275
+			if (!dol_is_file($readdir.$pathoffiletoeditsrc)) {
276 276
 				$pathoffiletoeditsrc = '/../install/mysql/tables/llx_'.strtolower($module).'-'.strtolower($module).'.sql';
277
-				if (! dol_is_file($readdir.$pathoffiletoeditsrc)) {
277
+				if (!dol_is_file($readdir.$pathoffiletoeditsrc)) {
278 278
 					$pathoffiletoeditsrc = '/../install/mysql/tables/llx_'.strtolower($module).'.sql';
279 279
 				}
280 280
 			}
281 281
 		}
282 282
 	} else {
283 283
 		$pathoffiletoeditsrc = '/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql';
284
-		if (! dol_is_file($readdir.$pathoffiletoeditsrc)) {
284
+		if (!dol_is_file($readdir.$pathoffiletoeditsrc)) {
285 285
 			$pathoffiletoeditsrc = '/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'-'.strtolower($module).'.sql';
286
-			if (! dol_is_file($readdir.$pathoffiletoeditsrc)) {
286
+			if (!dol_is_file($readdir.$pathoffiletoeditsrc)) {
287 287
 				$pathoffiletoeditsrc = '/sql/llx_'.strtolower($module).'-'.strtolower($module).'.sql';
288
-				if (! dol_is_file($readdir.$pathoffiletoeditsrc)) {
288
+				if (!dol_is_file($readdir.$pathoffiletoeditsrc)) {
289 289
 					$pathoffiletoeditsrc = '/sql/llx_'.strtolower($module).'.sql';
290 290
 				}
291 291
 			}
@@ -442,7 +442,7 @@  discard block
 block discarded – undo
442 442
 			$objects[$fileobj['fullname']] = $objectnameloop;
443 443
 		}
444 444
 	}
445
-	if (count($objects)>0) {
445
+	if (count($objects) > 0) {
446 446
 		return $objects;
447 447
 	}
448 448
 
@@ -552,12 +552,12 @@  discard block
 block discarded – undo
552 552
 			}
553 553
 		}
554 554
 	} elseif ($action == -2 && !empty($objectname) && !empty($module)) {
555
-		$key= null;
555
+		$key = null;
556 556
 		$right = null;
557 557
 		$objectOfRights = array();
558 558
 		//check if object already declared in rights file
559 559
 		foreach ($permissions as $right) {
560
-			$objectOfRights[]= $right[4];
560
+			$objectOfRights[] = $right[4];
561 561
 		}
562 562
 		if (in_array(strtolower($objectname), $objectOfRights)) {
563 563
 			$error++;
@@ -584,7 +584,7 @@  discard block
 block discarded – undo
584 584
 	if (!$error) {
585 585
 		// prepare permissions array
586 586
 		$count_perms = count($permissions);
587
-		for ($i = 0;$i<$count_perms;$i++) {
587
+		for ($i = 0; $i < $count_perms; $i++) {
588 588
 			$permissions[$i][0] = "\$this->rights[\$r][0] = \$this->numero . sprintf('%02d', \$r + 1)";
589 589
 			$permissions[$i][1] = "\$this->rights[\$r][1] = '".$permissions[$i][1]."'";
590 590
 			$permissions[$i][4] = "\$this->rights[\$r][4] = '".$permissions[$i][4]."'";
@@ -604,7 +604,7 @@  discard block
 block discarded – undo
604 604
 
605 605
 
606 606
 		// parcourir les objets
607
-		$o=0;
607
+		$o = 0;
608 608
 		foreach ($permissions as &$object) {
609 609
 			// récupérer la permission de l'objet
610 610
 			$p = 1;
@@ -699,7 +699,7 @@  discard block
 block discarded – undo
699 699
 {
700 700
 
701 701
 	// stock all properties in array
702
-	$attributesUnique = array ('type','label', 'enabled', 'position', 'notnull', 'visible', 'noteditable', 'index', 'default' , 'foreignkey', 'arrayofkeyval', 'alwayseditable','validate', 'searchall','comment', 'isameasure', 'css', 'cssview','csslist', 'help', 'showoncombobox','picto' );
702
+	$attributesUnique = array('type', 'label', 'enabled', 'position', 'notnull', 'visible', 'noteditable', 'index', 'default', 'foreignkey', 'arrayofkeyval', 'alwayseditable', 'validate', 'searchall', 'comment', 'isameasure', 'css', 'cssview', 'csslist', 'help', 'showoncombobox', 'picto');
703 703
 
704 704
 	$start = "public \$fields=array(";
705 705
 	$end = ");";
@@ -729,7 +729,7 @@  discard block
 block discarded – undo
729 729
 	foreach ($attributesUnique as $attUnique) {
730 730
 		$table .= "|".$attUnique;
731 731
 	}
732
-	$table .="\n";
732
+	$table .= "\n";
733 733
 	$valuesModif = array();
734 734
 	foreach ($keys as $string) {
735 735
 		$string = trim($string, "'");
@@ -769,8 +769,8 @@  discard block
 block discarded – undo
769 769
 				$valuesModif[$attUnique] = $values[$attUnique];
770 770
 			}
771 771
 		}
772
-		$table .= "|*" . $field[0] . "*|";
773
-		$table .= implode("|", $valuesModif) . "\n";
772
+		$table .= "|*".$field[0]."*|";
773
+		$table .= implode("|", $valuesModif)."\n";
774 774
 	}
775 775
 
776 776
 	// end table
@@ -779,7 +779,7 @@  discard block
 block discarded – undo
779 779
 
780 780
 	//write in file
781 781
 	$writeInFile = dolReplaceInFile($destfile, array('== DATA SPECIFICATIONS' => $table));
782
-	if ($writeInFile<0) {
782
+	if ($writeInFile < 0) {
783 783
 		return -1;
784 784
 	}
785 785
 	return 1;
@@ -801,13 +801,13 @@  discard block
 block discarded – undo
801 801
 
802 802
 		$str = file_get_contents($file);
803 803
 
804
-		$search = '/' . preg_quote($start, '/') . '(.*?)' . preg_quote($end, '/') . '/s';
804
+		$search = '/'.preg_quote($start, '/').'(.*?)'.preg_quote($end, '/').'/s';
805 805
 		$new_contents = preg_replace($search, '', $str);
806 806
 		file_put_contents($file, $new_contents);
807 807
 
808 808
 		//perms If Exist
809 809
 		$perms = "|*".strtolower($objectname)."*|";
810
-		$search_pattern_perms = '/' . preg_quote($perms, '/') . '.*?\n/';
810
+		$search_pattern_perms = '/'.preg_quote($perms, '/').'.*?\n/';
811 811
 		$new_contents = preg_replace($search_pattern_perms, '', $new_contents);
812 812
 		file_put_contents($file, $new_contents);
813 813
 	}
@@ -864,7 +864,7 @@  discard block
 block discarded – undo
864 864
 	$string = "[options='header',grid=rows,width=60%,caption=Organisation]\n";
865 865
 	$string .= "|===\n";
866 866
 	// header for table
867
-	$header = array($langs->trans('Objects'),$langs->trans('Permission'));
867
+	$header = array($langs->trans('Objects'), $langs->trans('Permission'));
868 868
 	foreach ($header as $h) {
869 869
 		$string .= "|".$h;
870 870
 	}
@@ -891,7 +891,7 @@  discard block
 block discarded – undo
891 891
 	foreach ($permissions as $key => $element) {
892 892
 		$element = str_replace(" '", '', $element);
893 893
 		$element = trim($element, "'");
894
-		$permsN[] = substr($element, strpos($element, "=")+1);
894
+		$permsN[] = substr($element, strpos($element, "=") + 1);
895 895
 	}
896 896
 	array_pop($permsN);
897 897
 
@@ -921,7 +921,7 @@  discard block
 block discarded – undo
921 921
 	// end table
922 922
 	$string .= "\n|===\n";
923 923
 	$write = dolReplaceInFile($destfile, array('__DATA_PERMISSIONS__'=> $string));
924
-	if ($write<0) {
924
+	if ($write < 0) {
925 925
 		return -1;
926 926
 	}
927 927
 	return 1;
@@ -950,26 +950,26 @@  discard block
 block discarded – undo
950 950
 		if (strpos($lineContent, $varcomented) !== false) {
951 951
 			$lineContent = '';
952 952
 			foreach ($objects as $object) {
953
-				$lineContent .= "\t * @var ".$object." \$".strtolower($object)." {@type ".$object."}". PHP_EOL;
953
+				$lineContent .= "\t * @var ".$object." \$".strtolower($object)." {@type ".$object."}".PHP_EOL;
954 954
 			}
955 955
 			//var_dump($lineContent);exit;
956 956
 		}
957 957
 		if (strpos($lineContent, $props) !== false) {
958 958
 			$lineContent = '';
959 959
 			foreach ($objects as $object) {
960
-				$lineContent .= "\tpublic \$".strtolower($object).";". PHP_EOL;
960
+				$lineContent .= "\tpublic \$".strtolower($object).";".PHP_EOL;
961 961
 			}
962 962
 		}
963 963
 		if (strpos($lineContent, $constructObj) !== false) {
964 964
 			$lineContent = '';
965 965
 			foreach ($objects as $object) {
966
-				$lineContent .= "\t\t\$this->".strtolower($object)." = new ".$object."(\$this->db);". PHP_EOL;
966
+				$lineContent .= "\t\t\$this->".strtolower($object)." = new ".$object."(\$this->db);".PHP_EOL;
967 967
 			}
968 968
 		}
969 969
 		if (strpos($lineContent, $includeClass) !== false) {
970 970
 			$lineContent = '';
971 971
 			foreach ($objects as $object) {
972
-				$lineContent .= "dol_include_once('/".strtolower($modulename)."/class/".strtolower($object).".class.php');". PHP_EOL;
972
+				$lineContent .= "dol_include_once('/".strtolower($modulename)."/class/".strtolower($object).".class.php');".PHP_EOL;
973 973
 			}
974 974
 		}
975 975
 	}
@@ -979,10 +979,10 @@  discard block
 block discarded – undo
979 979
 	//add methods for each object
980 980
 	$allContent = getFromFile($file, '/*begin methods CRUD*/', '/*end methods CRUD*/');
981 981
 	foreach ($objects as $object) {
982
-		$contentReplaced =str_replace(["myobject","MyObject"], [strtolower($object),$object], $allContent);
982
+		$contentReplaced = str_replace(["myobject", "MyObject"], [strtolower($object), $object], $allContent);
983 983
 		dolReplaceInFile($file, array('/*end methods CRUD*/' => '/*CRUD FOR '.strtoupper($object).'*/'."\n".$contentReplaced."\n\t".'/*END CRUD FOR '.strtoupper($object).'*/'."\n\t".'/*end methods CRUD*/'));
984 984
 	}
985
-	dolReplaceInFile($file, array($allContent => '','MyModule' => ucfirst($modulename)));
985
+	dolReplaceInFile($file, array($allContent => '', 'MyModule' => ucfirst($modulename)));
986 986
 	return 1;
987 987
 }
988 988
 
@@ -1043,7 +1043,7 @@  discard block
 block discarded – undo
1043 1043
  */
1044 1044
 function reWriteAllMenus($file, $menus, $menuWantTo, $key, $action)
1045 1045
 {
1046
-	$errors =0;
1046
+	$errors = 0;
1047 1047
 	$counter = 0;
1048 1048
 	if (!file_exists($file)) {
1049 1049
 		return -1;
@@ -1056,7 +1056,7 @@  discard block
 block discarded – undo
1056 1056
 		array_push($menus, $menuWantTo);
1057 1057
 	} elseif ($action == 2 && !empty($key) && !empty($menuWantTo)) {
1058 1058
 		// update right from permissions array
1059
-		$urlCounter=0;
1059
+		$urlCounter = 0;
1060 1060
 		// check if the values already exists
1061 1061
 		foreach ($menus as $index => $menu) {
1062 1062
 			if ($index !== $key) {
@@ -1104,20 +1104,20 @@  discard block
 block discarded – undo
1104 1104
 				$next_val = empty($menus[$index + 1]) ? null : $menus[$index + 1];
1105 1105
 
1106 1106
 				$str_menu .= $start."\n";
1107
-				$str_menu.= "\t\t\$this->menu[\$r++]=array(\n";
1108
-				$str_menu.= "\t\t\t 'fk_menu' =>'".$menu['fk_menu']."',\n";
1109
-				$str_menu.= "\t\t\t 'type' =>'".$menu['type']."',\n";
1110
-				$str_menu.= "\t\t\t 'titre' =>'".$menu['titre']."',\n";
1111
-				$str_menu.= "\t\t\t 'mainmenu' =>'".$menu['mainmenu']."',\n";
1112
-				$str_menu.= "\t\t\t 'leftmenu' =>'".$menu['leftmenu']."',\n";
1113
-				$str_menu.= "\t\t\t 'url' =>'".$menu['url']."',\n";
1114
-				$str_menu.= "\t\t\t 'langs' =>'".$menu['langs']."',\n";
1115
-				$str_menu.= "\t\t\t 'position' =>".$menu['position'].",\n";
1116
-				$str_menu.= "\t\t\t 'enabled' =>'".$menu['enabled']."',\n";
1117
-				$str_menu.= "\t\t\t 'perms' =>'".$menu['perms']."',\n";
1118
-				$str_menu.= "\t\t\t 'target' =>'".$menu['target']."',\n";
1119
-				$str_menu.= "\t\t\t 'user' =>".$menu['user'].",\n";
1120
-				$str_menu.= "\t\t);\n";
1107
+				$str_menu .= "\t\t\$this->menu[\$r++]=array(\n";
1108
+				$str_menu .= "\t\t\t 'fk_menu' =>'".$menu['fk_menu']."',\n";
1109
+				$str_menu .= "\t\t\t 'type' =>'".$menu['type']."',\n";
1110
+				$str_menu .= "\t\t\t 'titre' =>'".$menu['titre']."',\n";
1111
+				$str_menu .= "\t\t\t 'mainmenu' =>'".$menu['mainmenu']."',\n";
1112
+				$str_menu .= "\t\t\t 'leftmenu' =>'".$menu['leftmenu']."',\n";
1113
+				$str_menu .= "\t\t\t 'url' =>'".$menu['url']."',\n";
1114
+				$str_menu .= "\t\t\t 'langs' =>'".$menu['langs']."',\n";
1115
+				$str_menu .= "\t\t\t 'position' =>".$menu['position'].",\n";
1116
+				$str_menu .= "\t\t\t 'enabled' =>'".$menu['enabled']."',\n";
1117
+				$str_menu .= "\t\t\t 'perms' =>'".$menu['perms']."',\n";
1118
+				$str_menu .= "\t\t\t 'target' =>'".$menu['target']."',\n";
1119
+				$str_menu .= "\t\t\t 'user' =>".$menu['user'].",\n";
1120
+				$str_menu .= "\t\t);\n";
1121 1121
 
1122 1122
 				if (is_null($next_val) || $val_actuel['leftmenu'] !== $next_val['leftmenu']) {
1123 1123
 					$str_menu .= $end."\n";
@@ -1154,21 +1154,21 @@  discard block
 block discarded – undo
1154 1154
 		$dicData .= "\t\t\t'$key'=>";
1155 1155
 
1156 1156
 		if ($key === 'tabcond') {
1157
-			$conditions = array_map(function ($val) use ($module) {
1157
+			$conditions = array_map(function($val) use ($module) {
1158 1158
 				return ($val === true || $val === false) ? "isModEnabled('$module')" : $val;
1159 1159
 			}, $value);
1160
-			$dicData .= "array(" . implode(",", $conditions) . ")";
1160
+			$dicData .= "array(".implode(",", $conditions).")";
1161 1161
 		} elseif ($key === 'tabhelp') {
1162 1162
 			$helpItems = array();
1163 1163
 			foreach ($value as $key => $helpValue) {
1164 1164
 				$helpItems[] = "array('code'=>\$langs->trans('".$helpValue['code']."'), 'field2' => 'field2tooltip')";
1165 1165
 			}
1166
-			$dicData .= "array(" . implode(",", $helpItems) . ")";
1166
+			$dicData .= "array(".implode(",", $helpItems).")";
1167 1167
 		} else {
1168 1168
 			if (is_array($value)) {
1169
-				$dicData .= "array(" . implode(",", array_map(function ($val) {
1169
+				$dicData .= "array(".implode(",", array_map(function($val) {
1170 1170
 					return "'$val'";
1171
-				}, $value)) . ")";
1171
+				}, $value)).")";
1172 1172
 			} else {
1173 1173
 				$dicData .= "'$value'";
1174 1174
 			}
@@ -1234,7 +1234,7 @@  discard block
 block discarded – undo
1234 1234
 		}
1235 1235
 	}
1236 1236
 	// check if tablename exist in Database and create it if not
1237
-	$query = "SHOW TABLES LIKE '" . MAIN_DB_PREFIX.strtolower($namedic) . "'";
1237
+	$query = "SHOW TABLES LIKE '".MAIN_DB_PREFIX.strtolower($namedic)."'";
1238 1238
 	$checkTable = $db->query($query);
1239 1239
 	if ($checkTable && $db->num_rows($checkTable) > 0) {
1240 1240
 		setEventMessages($langs->trans("ErrorTableExist", $namedic), null, 'errors');
@@ -1343,9 +1343,9 @@  discard block
 block discarded – undo
1343 1343
 
1344 1344
 	foreach ($allFilesAndDirs as $item) {
1345 1345
 		if ($item != '.' && $item != '..') {
1346
-			if ($type == 1 && is_file($path . DIRECTORY_SEPARATOR . $item) && strpos($item, '.back') === false) {
1346
+			if ($type == 1 && is_file($path.DIRECTORY_SEPARATOR.$item) && strpos($item, '.back') === false) {
1347 1347
 				$count++;
1348
-			} elseif ($type == 2 && is_dir($path . DIRECTORY_SEPARATOR . $item)) {
1348
+			} elseif ($type == 2 && is_dir($path.DIRECTORY_SEPARATOR.$item)) {
1349 1349
 				$count++;
1350 1350
 			}
1351 1351
 		}
Please login to merge, or discard this patch.
htdocs/admin/mails_ticket.php 1 patch
Spacing   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -307,7 +307,7 @@  discard block
 block discarded – undo
307 307
 	print '<tr class="oddeven"><td>'.$langs->trans("MAIN_MAIL_SENDMODE").'</td><td>';
308 308
 
309 309
 	// SuperAdministrator access only
310
-	if (!isModEnabled('multicompany')  || ($user->admin && !$user->entity)) {
310
+	if (!isModEnabled('multicompany') || ($user->admin && !$user->entity)) {
311 311
 		print $form->selectarray('MAIN_MAIL_SENDMODE_TICKET', $listofmethods, $conf->global->MAIN_MAIL_SENDMODE_TICKET);
312 312
 	} else {
313 313
 		$text = $listofmethods[getDolGlobalString('MAIN_MAIL_SENDMODE_TICKET')];
@@ -316,7 +316,7 @@  discard block
 block discarded – undo
316 316
 		}
317 317
 		$htmltext = $langs->trans("ContactSuperAdminForChange");
318 318
 		print $form->textwithpicto($text, $htmltext, 1, 'superadmin');
319
-		print '<input type="hidden" name="MAIN_MAIL_SENDMODE_TICKET" value="' . getDolGlobalString('MAIN_MAIL_SENDMODE_TICKET').'">';
319
+		print '<input type="hidden" name="MAIN_MAIL_SENDMODE_TICKET" value="'.getDolGlobalString('MAIN_MAIL_SENDMODE_TICKET').'">';
320 320
 	}
321 321
 	print '</td></tr>';
322 322
 
@@ -437,7 +437,7 @@  discard block
 block discarded – undo
437 437
 	if (!empty($conf->use_javascript_ajax) || (isset($conf->global->MAIN_MAIL_SENDMODE_TICKET) && in_array($conf->global->MAIN_MAIL_SENDMODE_TICKET, array('smtps', 'swiftmailer')))) {
438 438
 		print '<tr class="oddeven smtp_oauth_service hideifdefault"><td>'.$langs->trans("MAIN_MAIL_SMTPS_OAUTH_SERVICE").'</td><td>';
439 439
 		// SuperAdministrator access only
440
-		if (!isModEnabled('multicompany')  || ($user->admin && !$user->entity)) {
440
+		if (!isModEnabled('multicompany') || ($user->admin && !$user->entity)) {
441 441
 			print $form->selectarray('MAIN_MAIL_SMTPS_OAUTH_SERVICE_TICKET', $oauthservices, $conf->global->MAIN_MAIL_SMTPS_OAUTH_SERVICE_TICKET);
442 442
 		} else {
443 443
 			$text = $oauthservices[getDolGlobalString('MAIN_MAIL_SMTPS_OAUTH_SERVICE_TICKET')];
@@ -446,7 +446,7 @@  discard block
 block discarded – undo
446 446
 			}
447 447
 			$htmltext = $langs->trans("ContactSuperAdminForChange");
448 448
 			print $form->textwithpicto($text, $htmltext, 1, 'superadmin');
449
-			print '<input type="hidden" name="MAIN_MAIL_SMTPS_OAUTH_SERVICE_TICKET" value="' . getDolGlobalString('MAIN_MAIL_SMTPS_OAUTH_SERVICE_TICKET').'">';
449
+			print '<input type="hidden" name="MAIN_MAIL_SMTPS_OAUTH_SERVICE_TICKET" value="'.getDolGlobalString('MAIN_MAIL_SMTPS_OAUTH_SERVICE_TICKET').'">';
450 450
 		}
451 451
 		print '</td></tr>';
452 452
 	}
@@ -526,13 +526,13 @@  discard block
 block discarded – undo
526 526
 		// AUTH method
527 527
 		if (in_array(getDolGlobalString('MAIN_MAIL_SENDMODE_TICKET'), array('smtps', 'swiftmailer'))) {
528 528
 			$authtype = getDolGlobalString('MAIN_MAIL_SMTPS_AUTH_TYPE_TICKET', 'LOGIN');
529
-			$text = ($authtype === "LOGIN") ? $langs->trans("UsePassword") : ($authtype === "XOAUTH2" ?  $langs->trans("UseOauth") : '') ;
529
+			$text = ($authtype === "LOGIN") ? $langs->trans("UsePassword") : ($authtype === "XOAUTH2" ? $langs->trans("UseOauth") : '');
530 530
 			print '<tr class="oddeven hideifdefault"><td>'.$langs->trans("MAIN_MAIL_SMTPS_AUTH_TYPE").'</td><td>'.$text.'</td></tr>';
531 531
 		}
532 532
 
533 533
 		// SMTPS ID
534 534
 		if (isset($conf->global->MAIN_MAIL_SENDMODE_TICKET) && in_array($conf->global->MAIN_MAIL_SENDMODE_TICKET, array('smtps', 'swiftmailer'))) {
535
-			print '<tr class="oddeven hideifdefault"><td>'.$langs->trans("MAIN_MAIL_SMTPS_ID").'</td><td>' . getDolGlobalString('MAIN_MAIL_SMTPS_ID_TICKET').'</td></tr>';
535
+			print '<tr class="oddeven hideifdefault"><td>'.$langs->trans("MAIN_MAIL_SMTPS_ID").'</td><td>'.getDolGlobalString('MAIN_MAIL_SMTPS_ID_TICKET').'</td></tr>';
536 536
 		}
537 537
 
538 538
 		// SMTPS PW
Please login to merge, or discard this patch.
htdocs/admin/mails_emailing.php 1 patch
Spacing   +23 added lines, -23 removed lines patch added patch discarded remove patch
@@ -327,7 +327,7 @@  discard block
 block discarded – undo
327 327
 		}
328 328
 		$htmltext = $langs->trans("ContactSuperAdminForChange");
329 329
 		print $form->textwithpicto($text, $htmltext, 1, 'superadmin');
330
-		print '<input type="hidden" name="MAIN_MAIL_SENDMODE_EMAILING" value="' . getDolGlobalString('MAIN_MAIL_SENDMODE_EMAILING').'">';
330
+		print '<input type="hidden" name="MAIN_MAIL_SENDMODE_EMAILING" value="'.getDolGlobalString('MAIN_MAIL_SENDMODE_EMAILING').'">';
331 331
 	}
332 332
 	print '</td></tr>';
333 333
 
@@ -352,15 +352,15 @@  discard block
 block discarded – undo
352 352
 		print '</td><td>';
353 353
 		// SuperAdministrator access only
354 354
 		if (!isModEnabled('multicompany') || ($user->admin && !$user->entity)) {
355
-			print '<input class="flat minwidth300" id="MAIN_MAIL_SMTP_SERVER_EMAILING" name="MAIN_MAIL_SMTP_SERVER_EMAILING" size="18" value="' . $mainserver . '">';
356
-			print '<input type="hidden" id="MAIN_MAIL_SMTP_SERVER_EMAILING_sav" name="MAIN_MAIL_SMTP_SERVER_EMAILING_sav" value="' . $mainserver . '">';
357
-			print '<span id="smtp_server_mess" class="opacitymedium">' . $langs->trans("SeeLocalSendMailSetup") . '</span>';
358
-			print ' <span class="opacitymedium smtp_method">' . $langs->trans("SeeLinkToOnlineDocumentation") . '</span>';
355
+			print '<input class="flat minwidth300" id="MAIN_MAIL_SMTP_SERVER_EMAILING" name="MAIN_MAIL_SMTP_SERVER_EMAILING" size="18" value="'.$mainserver.'">';
356
+			print '<input type="hidden" id="MAIN_MAIL_SMTP_SERVER_EMAILING_sav" name="MAIN_MAIL_SMTP_SERVER_EMAILING_sav" value="'.$mainserver.'">';
357
+			print '<span id="smtp_server_mess" class="opacitymedium">'.$langs->trans("SeeLocalSendMailSetup").'</span>';
358
+			print ' <span class="opacitymedium smtp_method">'.$langs->trans("SeeLinkToOnlineDocumentation").'</span>';
359 359
 		} else {
360 360
 			$text = !empty($mainserver) ? $mainserver : $smtpserver;
361 361
 			$htmltext = $langs->trans("ContactSuperAdminForChange");
362 362
 			print $form->textwithpicto($text, $htmltext, 1, 'superadmin');
363
-			print '<input type="hidden" id="MAIN_MAIL_SMTP_SERVER_EMAILING" name="MAIN_MAIL_SMTP_SERVER_EMAILING" value="' . $mainserver . '">';
363
+			print '<input type="hidden" id="MAIN_MAIL_SMTP_SERVER_EMAILING" name="MAIN_MAIL_SMTP_SERVER_EMAILING" value="'.$mainserver.'">';
364 364
 		}
365 365
 		print '</td>';
366 366
 	}
@@ -384,14 +384,14 @@  discard block
 block discarded – undo
384 384
 		print '</td><td>';
385 385
 		// SuperAdministrator access only
386 386
 		if (!isModEnabled('multicompany') || ($user->admin && !$user->entity)) {
387
-			print '<input class="flat" id="MAIN_MAIL_SMTP_PORT_EMAILING" name="MAIN_MAIL_SMTP_PORT_EMAILING" size="3" value="' . $mainport . '">';
388
-			print '<input type="hidden" id="MAIN_MAIL_SMTP_PORT_EMAILING_sav" name="MAIN_MAIL_SMTP_PORT_EMAILING_sav" value="' . $mainport . '">';
389
-			print '<span id="smtp_port_mess" class="opacitymedium">' . $langs->trans("SeeLocalSendMailSetup") . '</span>';
387
+			print '<input class="flat" id="MAIN_MAIL_SMTP_PORT_EMAILING" name="MAIN_MAIL_SMTP_PORT_EMAILING" size="3" value="'.$mainport.'">';
388
+			print '<input type="hidden" id="MAIN_MAIL_SMTP_PORT_EMAILING_sav" name="MAIN_MAIL_SMTP_PORT_EMAILING_sav" value="'.$mainport.'">';
389
+			print '<span id="smtp_port_mess" class="opacitymedium">'.$langs->trans("SeeLocalSendMailSetup").'</span>';
390 390
 		} else {
391 391
 			$text = (!empty($mainport) ? $mainport : $smtpport);
392 392
 			$htmltext = $langs->trans("ContactSuperAdminForChange");
393 393
 			print $form->textwithpicto($text, $htmltext, 1, 'superadmin');
394
-			print '<input type="hidden" id="MAIN_MAIL_SMTP_PORT_EMAILING" name="MAIN_MAIL_SMTP_PORT_EMAILING" value="' . $mainport . '">';
394
+			print '<input type="hidden" id="MAIN_MAIL_SMTP_PORT_EMAILING" name="MAIN_MAIL_SMTP_PORT_EMAILING" value="'.$mainport.'">';
395 395
 		}
396 396
 	}
397 397
 	print '</td></tr>';
@@ -418,14 +418,14 @@  discard block
 block discarded – undo
418 418
 	// ID
419 419
 	if (!empty($conf->use_javascript_ajax) || (isset($conf->global->MAIN_MAIL_SENDMODE_EMAILING) && in_array($conf->global->MAIN_MAIL_SENDMODE_EMAILING, array('smtps', 'swiftmailer')))) {
420 420
 		$mainstmpid = (!empty($conf->global->MAIN_MAIL_SMTPS_ID_EMAILING) ? $conf->global->MAIN_MAIL_SMTPS_ID_EMAILING : '');
421
-		print '<tr class="drag drop oddeven hideifdefault"><td>' . $langs->trans("MAIN_MAIL_SMTPS_ID") . '</td><td>';
421
+		print '<tr class="drag drop oddeven hideifdefault"><td>'.$langs->trans("MAIN_MAIL_SMTPS_ID").'</td><td>';
422 422
 		// SuperAdministrator access only
423 423
 		if (!isModEnabled('multicompany') || ($user->admin && !$user->entity)) {
424
-			print '<input class="flat" name="MAIN_MAIL_SMTPS_ID_EMAILING" size="32" value="' . $mainstmpid . '">';
424
+			print '<input class="flat" name="MAIN_MAIL_SMTPS_ID_EMAILING" size="32" value="'.$mainstmpid.'">';
425 425
 		} else {
426 426
 			$htmltext = $langs->trans("ContactSuperAdminForChange");
427 427
 			print $form->textwithpicto($conf->global->MAIN_MAIL_SMTPS_ID_EMAILING, $htmltext, 1, 'superadmin');
428
-			print '<input type="hidden" name="MAIN_MAIL_SMTPS_ID_EMAILING" value="' . $mainstmpid . '">';
428
+			print '<input type="hidden" name="MAIN_MAIL_SMTPS_ID_EMAILING" value="'.$mainstmpid.'">';
429 429
 		}
430 430
 		print '</td></tr>';
431 431
 	}
@@ -433,14 +433,14 @@  discard block
 block discarded – undo
433 433
 	// PW
434 434
 	if (!empty($conf->use_javascript_ajax) || (isset($conf->global->MAIN_MAIL_SENDMODE_EMAILING) && in_array($conf->global->MAIN_MAIL_SENDMODE_EMAILING, array('smtps', 'swiftmailer')))) {
435 435
 		$mainsmtppw = (!empty($conf->global->MAIN_MAIL_SMTPS_PW_EMAILING) ? $conf->global->MAIN_MAIL_SMTPS_PW_EMAILING : '');
436
-		print '<tr class="drag drop oddeven smtp_pw hideifdefault"><td>' . $langs->trans("MAIN_MAIL_SMTPS_PW") . '</td><td>';
436
+		print '<tr class="drag drop oddeven smtp_pw hideifdefault"><td>'.$langs->trans("MAIN_MAIL_SMTPS_PW").'</td><td>';
437 437
 		// SuperAdministrator access only
438 438
 		if (!isModEnabled('multicompany') || ($user->admin && !$user->entity)) {
439
-			print '<input class="flat" type="password" name="MAIN_MAIL_SMTPS_PW_EMAILING" size="32" value="' . $mainsmtppw . '">';
439
+			print '<input class="flat" type="password" name="MAIN_MAIL_SMTPS_PW_EMAILING" size="32" value="'.$mainsmtppw.'">';
440 440
 		} else {
441 441
 			$htmltext = $langs->trans("ContactSuperAdminForChange");
442 442
 			print $form->textwithpicto($conf->global->MAIN_MAIL_SMTPS_PW_EMAILING, $htmltext, 1, 'superadmin');
443
-			print '<input type="hidden" name="MAIN_MAIL_SMTPS_PW_EMAILING" value="' . $mainsmtppw . '">';
443
+			print '<input type="hidden" name="MAIN_MAIL_SMTPS_PW_EMAILING" value="'.$mainsmtppw.'">';
444 444
 		}
445 445
 		print '</td></tr>';
446 446
 	}
@@ -450,7 +450,7 @@  discard block
 block discarded – undo
450 450
 		print '<tr class="oddeven smtp_oauth_service hideifdefault"><td>'.$langs->trans("MAIN_MAIL_SMTPS_OAUTH_SERVICE").'</td><td>';
451 451
 
452 452
 		// SuperAdministrator access only
453
-		if (!isModEnabled('multicompany')  || ($user->admin && !$user->entity)) {
453
+		if (!isModEnabled('multicompany') || ($user->admin && !$user->entity)) {
454 454
 			print $form->selectarray('MAIN_MAIL_SMTPS_OAUTH_SERVICE_EMAILING', $oauthservices, $conf->global->MAIN_MAIL_SMTPS_OAUTH_SERVICE_EMAILING);
455 455
 		} else {
456 456
 			$text = $oauthservices[getDolGlobalString('MAIN_MAIL_SMTPS_OAUTH_SERVICE_EMAILING')];
@@ -459,7 +459,7 @@  discard block
 block discarded – undo
459 459
 			}
460 460
 			$htmltext = $langs->trans("ContactSuperAdminForChange");
461 461
 			print $form->textwithpicto($text, $htmltext, 1, 'superadmin');
462
-			print '<input type="hidden" name="MAIN_MAIL_SMTPS_OAUTH_SERVICE_EMAILING" value="' . getDolGlobalString('MAIN_MAIL_SMTPS_OAUTH_SERVICE_EMAILING').'">';
462
+			print '<input type="hidden" name="MAIN_MAIL_SMTPS_OAUTH_SERVICE_EMAILING" value="'.getDolGlobalString('MAIN_MAIL_SMTPS_OAUTH_SERVICE_EMAILING').'">';
463 463
 		}
464 464
 		print '</td></tr>';
465 465
 	}
@@ -552,7 +552,7 @@  discard block
 block discarded – undo
552 552
 		// AUTH method
553 553
 		if (in_array(getDolGlobalString('MAIN_MAIL_SENDMODE_EMAILING'), array('smtps', 'swiftmailer'))) {
554 554
 			$authtype = getDolGlobalString('MAIN_MAIL_SMTPS_AUTH_TYPE_EMAILING', 'LOGIN');
555
-			$text = ($authtype === "LOGIN") ? $langs->trans("UsePassword") : ($authtype === "XOAUTH2" ?  $langs->trans("UseOauth") : '') ;
555
+			$text = ($authtype === "LOGIN") ? $langs->trans("UsePassword") : ($authtype === "XOAUTH2" ? $langs->trans("UseOauth") : '');
556 556
 			print '<tr class="oddeven hideifdefault"><td>'.$langs->trans("MAIN_MAIL_SMTPS_AUTH_TYPE").'</td><td>'.$text.'</td></tr>';
557 557
 		}
558 558
 
@@ -646,16 +646,16 @@  discard block
 block discarded – undo
646 646
 	if (!empty($conf->global->MAIN_MAIL_SENDMODE_EMAILING) && $conf->global->MAIN_MAIL_SENDMODE_EMAILING != 'default') {
647 647
 		if ($conf->global->MAIN_MAIL_SENDMODE_EMAILING != 'mail' || !$linuxlike) {
648 648
 			if (function_exists('fsockopen') && $port && $server) {
649
-				print '<a class="butAction" href="' . $_SERVER["PHP_SELF"] . '?action=testconnect">' . $langs->trans("DoTestServerAvailability") . '</a>';
649
+				print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=testconnect">'.$langs->trans("DoTestServerAvailability").'</a>';
650 650
 			}
651 651
 		} else {
652
-			print '<a class="butActionRefused classfortooltip" href="#" title="' . $langs->trans("FeatureNotAvailableOnLinux") . '">' . $langs->trans("DoTestServerAvailability") . '</a>';
652
+			print '<a class="butActionRefused classfortooltip" href="#" title="'.$langs->trans("FeatureNotAvailableOnLinux").'">'.$langs->trans("DoTestServerAvailability").'</a>';
653 653
 		}
654 654
 
655
-		print '<a class="butAction" href="' . $_SERVER["PHP_SELF"] . '?action=test&amp;mode=init">' . $langs->trans("DoTestSend") . '</a>';
655
+		print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=test&amp;mode=init">'.$langs->trans("DoTestSend").'</a>';
656 656
 
657 657
 		if (isModEnabled('fckeditor')) {
658
-			print '<a class="butAction" href="' . $_SERVER["PHP_SELF"] . '?action=testhtml&amp;mode=init">' . $langs->trans("DoTestSendHTML") . '</a>';
658
+			print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=testhtml&amp;mode=init">'.$langs->trans("DoTestSendHTML").'</a>';
659 659
 		}
660 660
 	}
661 661
 
Please login to merge, or discard this patch.
htdocs/admin/mails.php 1 patch
Spacing   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -383,7 +383,7 @@  discard block
 block discarded – undo
383 383
 	print '<tr class="oddeven"><td>'.$langs->trans("MAIN_MAIL_SENDMODE").'</td><td>';
384 384
 
385 385
 	// SuperAdministrator access only
386
-	if (!isModEnabled('multicompany')  || ($user->admin && !$user->entity)) {
386
+	if (!isModEnabled('multicompany') || ($user->admin && !$user->entity)) {
387 387
 		print $form->selectarray('MAIN_MAIL_SENDMODE', $listofmethods, getDolGlobalString('MAIN_MAIL_SENDMODE', 'mail'));
388 388
 	} else {
389 389
 		$text = $listofmethods[getDolGlobalString('MAIN_MAIL_SENDMODE')];
@@ -502,11 +502,11 @@  discard block
 block discarded – undo
502 502
 		print '</td><td>';
503 503
 		// SuperAdministrator access only
504 504
 		if (!isModEnabled('multicompany') || ($user->admin && !$user->entity)) {
505
-			print '<input class="flat" type="password" name="MAIN_MAIL_SMTPS_PW" size="32" value="' . htmlspecialchars($mainsmtppw, ENT_COMPAT, 'UTF-8') . '" autocomplete="off">';
505
+			print '<input class="flat" type="password" name="MAIN_MAIL_SMTPS_PW" size="32" value="'.htmlspecialchars($mainsmtppw, ENT_COMPAT, 'UTF-8').'" autocomplete="off">';
506 506
 		} else {
507 507
 			$htmltext = $langs->trans("ContactSuperAdminForChange");
508 508
 			print $form->textwithpicto($conf->global->MAIN_MAIL_SMTPS_PW, $htmltext, 1, 'superadmin');
509
-			print '<input type="hidden" name="MAIN_MAIL_SMTPS_PW" value="' . htmlspecialchars($mainsmtppw, ENT_COMPAT, 'UTF-8') . '">';
509
+			print '<input type="hidden" name="MAIN_MAIL_SMTPS_PW" value="'.htmlspecialchars($mainsmtppw, ENT_COMPAT, 'UTF-8').'">';
510 510
 		}
511 511
 		print '</td></tr>';
512 512
 	}
@@ -516,7 +516,7 @@  discard block
 block discarded – undo
516 516
 		print '<tr class="oddeven smtp_oauth_service"><td>'.$langs->trans("MAIN_MAIL_SMTPS_OAUTH_SERVICE").'</td><td>';
517 517
 
518 518
 		// SuperAdministrator access only
519
-		if (!isModEnabled('multicompany')  || ($user->admin && !$user->entity)) {
519
+		if (!isModEnabled('multicompany') || ($user->admin && !$user->entity)) {
520 520
 			print $form->selectarray('MAIN_MAIL_SMTPS_OAUTH_SERVICE', $oauthservices, $conf->global->MAIN_MAIL_SMTPS_OAUTH_SERVICE);
521 521
 		} else {
522 522
 			$text = $oauthservices[getDolGlobalString('MAIN_MAIL_SMTPS_OAUTH_SERVICE')];
@@ -525,7 +525,7 @@  discard block
 block discarded – undo
525 525
 			}
526 526
 			$htmltext = $langs->trans("ContactSuperAdminForChange");
527 527
 			print $form->textwithpicto($text, $htmltext, 1, 'superadmin');
528
-			print '<input type="hidden" name="MAIN_MAIL_SMTPS_OAUTH_SERVICE" value="' . getDolGlobalString('MAIN_MAIL_SMTPS_OAUTH_SERVICE').'">';
528
+			print '<input type="hidden" name="MAIN_MAIL_SMTPS_OAUTH_SERVICE" value="'.getDolGlobalString('MAIN_MAIL_SMTPS_OAUTH_SERVICE').'">';
529 529
 		}
530 530
 		print '</td></tr>';
531 531
 	}
@@ -717,13 +717,13 @@  discard block
 block discarded – undo
717 717
 		// AUTH method
718 718
 		if (in_array(getDolGlobalString('MAIN_MAIL_SENDMODE', 'mail'), array('smtps', 'swiftmailer'))) {
719 719
 			$authtype = getDolGlobalString('MAIN_MAIL_SMTPS_AUTH_TYPE', 'LOGIN');
720
-			$text = ($authtype === "LOGIN") ? $langs->trans("UsePassword") : ($authtype === "XOAUTH2" ?  $langs->trans("UseOauth") : '') ;
720
+			$text = ($authtype === "LOGIN") ? $langs->trans("UsePassword") : ($authtype === "XOAUTH2" ? $langs->trans("UseOauth") : '');
721 721
 			print '<tr class="oddeven"><td>'.$langs->trans("MAIN_MAIL_SMTPS_AUTH_TYPE").'</td><td>'.$text.'</td></tr>';
722 722
 		}
723 723
 
724 724
 		// SMTPS ID
725 725
 		if (in_array(getDolGlobalString('MAIN_MAIL_SENDMODE', 'mail'), array('smtps', 'swiftmailer'))) {
726
-			print '<tr class="oddeven"><td>'.$langs->trans("MAIN_MAIL_SMTPS_ID").'</td><td>' . getDolGlobalString('MAIN_MAIL_SMTPS_ID').'</td></tr>';
726
+			print '<tr class="oddeven"><td>'.$langs->trans("MAIN_MAIL_SMTPS_ID").'</td><td>'.getDolGlobalString('MAIN_MAIL_SMTPS_ID').'</td></tr>';
727 727
 		}
728 728
 
729 729
 		// SMTPS PW
@@ -832,7 +832,7 @@  discard block
 block discarded – undo
832 832
 		// From
833 833
 		$help = img_help(1, $langs->trans("EMailHelpMsgSPFDKIM"));
834 834
 		print '<tr class="oddeven"><td>'.$langs->trans("MAIN_MAIL_EMAIL_FROM", ini_get('sendmail_from') ?ini_get('sendmail_from') : $langs->transnoentities("Undefined")).' '.$help.'</td>';
835
-		print '<td>' . getDolGlobalString('MAIN_MAIL_EMAIL_FROM');
835
+		print '<td>'.getDolGlobalString('MAIN_MAIL_EMAIL_FROM');
836 836
 		if (empty($conf->global->MAIN_MAIL_EMAIL_FROM)) {
837 837
 			print img_warning($langs->trans("Mandatory"));
838 838
 		} elseif (!isValidEmail($conf->global->MAIN_MAIL_EMAIL_FROM)) {
Please login to merge, or discard this patch.
htdocs/includes/markrogoyski/math-php/src/Finance.php 2 patches
Indentation   +770 added lines, -770 removed lines patch added patch discarded remove patch
@@ -5,776 +5,776 @@
 block discarded – undo
5 5
 use MathPHP\Exception\OutOfBoundsException;
6 6
 
7 7
 /**
8
-  * General references on financial functions and formulas:
9
-  * - Open Document Format for Office Applications (OpenDocument) Version 1.2 Part 2:
10
-  *   Recalculated Formula (OpenFormula) Format. 29 September 2011. OASIS Standard.
11
-  *   http://docs.oasis-open.org/office/v1.2/os/OpenDocument-v1.2-os-part2.html#__RefHeading__1018228_715980110
12
-  * - https://wiki.openoffice.org/wiki/Documentation/How_Tos/Calc:_Derivation_of_Financial_Formulas#Loans_and_Annuities
13
-  */
8
+ * General references on financial functions and formulas:
9
+ * - Open Document Format for Office Applications (OpenDocument) Version 1.2 Part 2:
10
+ *   Recalculated Formula (OpenFormula) Format. 29 September 2011. OASIS Standard.
11
+ *   http://docs.oasis-open.org/office/v1.2/os/OpenDocument-v1.2-os-part2.html#__RefHeading__1018228_715980110
12
+ * - https://wiki.openoffice.org/wiki/Documentation/How_Tos/Calc:_Derivation_of_Financial_Formulas#Loans_and_Annuities
13
+ */
14 14
 class Finance
15 15
 {
16
-    /**
17
-     * Floating-point range near zero to consider insignificant.
18
-     */
19
-    public const EPSILON = 1e-6;
20
-
21
-    /**
22
-     * Consider any floating-point value less than epsilon from zero as zero,
23
-     * ie any value in the range [-epsilon < 0 < epsilon] is considered zero.
24
-     * Also used to convert -0.0 to 0.0.
25
-     *
26
-     * @param float $value
27
-     * @param float $epsilon
28
-     *
29
-     * @return float
30
-     */
31
-    private static function checkZero(float $value, float $epsilon = self::EPSILON): float
32
-    {
33
-        return \abs($value) < $epsilon ? 0.0 : $value;
34
-    }
35
-
36
-    /**
37
-     * Financial payment for a loan or annuity with compound interest.
38
-     * Determines the periodic payment amount for a given interest rate,
39
-     * principal, targeted payment goal, life of the annuity as number
40
-     * of payments, and whether the payments are made at the start or end
41
-     * of each payment period.
42
-     *
43
-     * Same as the =PMT() function in most spreadsheet software.
44
-     *
45
-     * The basic monthly payment formula derivation:
46
-     * https://en.wikipedia.org/wiki/Mortgage_calculator#Monthly_payment_formula
47
-     *
48
-     *       rP(1+r)ᴺ
49
-     * PMT = --------
50
-     *       (1+r)ᴺ-1
51
-     *
52
-     * The formula is adjusted to allow targeting any future value rather than 0.
53
-     * The 1/(1+r*when) factor adjusts the payment to the beginning or end
54
-     * of the period. In the common case of a payment at the end of a period,
55
-     * the factor is 1 and reduces to the formula above. Setting when=1 computes
56
-     * an "annuity due" with an immediate payment.
57
-     *
58
-     * Examples:
59
-     * The payment on a 30-year fixed mortgage note of $265000 at 3.5% interest
60
-     * paid at the end of every month.
61
-     *   pmt(0.035/12, 30*12, 265000, 0, false)
62
-     *
63
-     * The payment on a 30-year fixed mortgage note of $265000 at 3.5% interest
64
-     * needed to half the principal in half in 5 years:
65
-     *   pmt(0.035/12, 5*12, 265000, 265000/2, false)
66
-     *
67
-     * The weekly payment into a savings account with 1% interest rate and current
68
-     * balance of $1500 needed to reach $10000 after 3 years:
69
-     *   pmt(0.01/52, 3*52, -1500, 10000, false)
70
-     * The present_value is negative indicating money put into the savings account,
71
-     * whereas future_value is positive, indicating money that will be withdrawn from
72
-     * the account. Similarly, the payment value is negative
73
-     *
74
-     * How much money can be withdrawn at the end of every quarter from an account
75
-     * with $1000000 earning 4% so the money lasts 20 years:
76
-     *  pmt(0.04/4, 20*4, 1000000, 0, false)
77
-     *
78
-     * @param  float $rate
79
-     * @param  int   $periods
80
-     * @param  float $present_value
81
-     * @param  float $future_value
82
-     * @param  bool  $beginning adjust the payment to the beginning or end of the period
83
-     *
84
-     * @return float
85
-     */
86
-    public static function pmt(float $rate, int $periods, float $present_value, float $future_value = 0.0, bool $beginning = false): float
87
-    {
88
-        $when = $beginning ? 1 : 0;
89
-
90
-        if ($rate == 0) {
91
-            return - ($future_value + $present_value) / $periods;
92
-        }
93
-
94
-        return - ($future_value + ($present_value * \pow(1 + $rate, $periods)))
95
-            /
96
-            ((1 + $rate * $when) / $rate * (\pow(1 + $rate, $periods) - 1));
97
-    }
98
-
99
-    /**
100
-     * Interest on a financial payment for a loan or annuity with compound interest.
101
-     * Determines the interest payment at a particular period of the annuity. For
102
-     * a typical loan paid down to zero, the amount of interest and principle paid
103
-     * throughout the lifetime of the loan will change, with the interest portion
104
-     * of the payment decreasing over time as the loan principle decreases.
105
-     *
106
-     * Same as the =IPMT() function in most spreadsheet software.
107
-     *
108
-     * See the PMT function for derivation of the formula. For IPMT, we have
109
-     * the payment equal to the interest portion and principle portion of the payment:
110
-     *
111
-     * PMT = IPMT + PPMT
112
-     *
113
-     * The interest portion IPMT on a regular annuity can be calculated by computing
114
-     * the future value of the annuity for the prior period and computing the compound
115
-     * interest for one period:
116
-     *
117
-     * IPMT = FV(p=n-1) * rate
118
-     *
119
-     * For an "annuity due" where payment is at the start of the period, period=1 has
120
-     * no interest portion of the payment because no time has elapsed for compounding.
121
-     * To compute the interest portion of the payment, the future value of 2 periods
122
-     * back needs to be computed, as the definition of a period is different, giving:
123
-     *
124
-     * IPMT = (FV(p=n-2) - PMT) * rate
125
-     *
126
-     * By thinking of the future value at period 0 instead of the present value, the
127
-     * given formulas are computed.
128
-     *
129
-     * Example of regular annuity and annuity due for a loan of $10.00 paid back in 3 periods.
130
-     * Although the principle payments are equal, the total payment and interest portion are
131
-     * lower with the annuity due because a principle payment is made immediately.
132
-     *
133
-     *                       Regular Annuity |  Annuity Due
134
-     * Period   FV       PMT    IPMT   PPMT  |   PMT    IPMT    PPMT
135
-     *   0     -10.00                        |
136
-     *   1      -6.83   -3.67  -0.50  -3.17  |  -3.50   0.00   -3.50
137
-     *   2      -3.50   -3.67  -0.34  -3.33  |  -3.50  -0.33   -3.17
138
-     *   3       0.00   -3.67  -0.17  -3.50  |  -3.50  -0.17   -3.33
139
-     *                -----------------------|----------------------
140
-     *             SUM -11.01  -1.01 -10.00  | -10.50  -0.50  -10.00
141
-     *
142
-     * Examples:
143
-     * The interest on a payment on a 30-year fixed mortgage note of $265000 at 3.5% interest
144
-     * paid at the end of every month, looking at the first payment:
145
-     *   ipmt(0.035/12, 1, 30*12, 265000, 0, false)
146
-     *
147
-     * @param  float $rate
148
-     * @param  int   $period
149
-     * @param  int   $periods
150
-     * @param  float $present_value
151
-     * @param  float $future_value
152
-     * @param  bool  $beginning adjust the payment to the beginning or end of the period
153
-     *
154
-     * @return float
155
-     */
156
-    public static function ipmt(float $rate, int $period, int $periods, float $present_value, float $future_value = 0.0, bool $beginning = false): float
157
-    {
158
-        if ($period < 1 || $period > $periods) {
159
-            return \NAN;
160
-        }
161
-
162
-        if ($rate == 0) {
163
-            return 0;
164
-        }
165
-
166
-        if ($beginning && $period == 1) {
167
-            return 0.0;
168
-        }
169
-
170
-        $payment = self::pmt($rate, $periods, $present_value, $future_value, $beginning);
171
-        if ($beginning) {
172
-            $interest = (self::fv($rate, $period - 2, $payment, $present_value, $beginning) - $payment) * $rate;
173
-        } else {
174
-            $interest = self::fv($rate, $period - 1, $payment, $present_value, $beginning) * $rate;
175
-        }
176
-
177
-        return self::checkZero($interest);
178
-    }
179
-
180
-    /**
181
-     * Principle on a financial payment for a loan or annuity with compound interest.
182
-     * Determines the principle payment at a particular period of the annuity. For
183
-     * a typical loan paid down to zero, the amount of interest and principle paid
184
-     * throughout the lifetime of the loan will change, with the principle portion
185
-     * of the payment increasing over time as the loan principle decreases.
186
-     *
187
-     * Same as the =PPMT() function in most spreadsheet software.
188
-     *
189
-     * See the PMT function for derivation of the formula.
190
-     * See the IPMT function for derivation and use of PMT, IPMT, and PPMT.
191
-     *
192
-     * With derivations for PMT and IPMT, we simply compute:
193
-     *
194
-     * PPMT = PMT - IPMT
195
-     *
196
-     * Examples:
197
-     * The principle on a payment on a 30-year fixed mortgage note of $265000 at 3.5% interest
198
-     * paid at the end of every month, looking at the first payment:
199
-     *   ppmt(0.035/12, 1, 30*12, 265000, 0, false)
200
-     *
201
-     * @param  float $rate
202
-     * @param  int   $period
203
-     * @param  int   $periods
204
-     * @param  float $present_value
205
-     * @param  float $future_value
206
-     * @param  bool  $beginning adjust the payment to the beginning or end of the period
207
-     *
208
-     * @return float
209
-     */
210
-    public static function ppmt(float $rate, int $period, int $periods, float $present_value, float $future_value = 0.0, bool $beginning = false): float
211
-    {
212
-        $payment = self::pmt($rate, $periods, $present_value, $future_value, $beginning);
213
-        $ipmt    = self::ipmt($rate, $period, $periods, $present_value, $future_value, $beginning);
214
-
215
-        return $payment - $ipmt;
216
-    }
217
-
218
-    /**
219
-     * Number of payment periods of an annuity.
220
-     * Solves for the number of periods in the annuity formula.
221
-     *
222
-     * Same as the =NPER() function in most spreadsheet software.
223
-     *
224
-     * Solving the basic annuity formula for number of periods:
225
-     *        log(PMT - FV*r)
226
-     *        ---------------
227
-     *        log(PMT + PV*r)
228
-     * n = --------------------
229
-     *          log(1 + r)
230
-     *
231
-     * The (1+r*when) factor adjusts the payment to the beginning or end
232
-     * of the period. In the common case of a payment at the end of a period,
233
-     * the factor is 1 and reduces to the formula above. Setting when=1 computes
234
-     * an "annuity due" with an immediate payment.
235
-     *
236
-     * Examples:
237
-     * The number of periods of a $475000 mortgage with interest rate 3.5% and monthly
238
-     * payment of $2132.96  paid in full:
239
-     *   nper(0.035/12, -2132.96, 475000, 0)
240
-     *
241
-     * @param  float $rate
242
-     * @param  float $payment
243
-     * @param  float $present_value
244
-     * @param  float $future_value
245
-     * @param  bool  $beginning adjust the payment to the beginning or end of the period
246
-     *
247
-     * @return float
248
-     */
249
-    public static function periods(float $rate, float $payment, float $present_value, float $future_value, bool $beginning = false): float
250
-    {
251
-        $when = $beginning ? 1 : 0;
252
-
253
-        if ($rate == 0) {
254
-            return - ($present_value + $future_value) / $payment;
255
-        }
256
-
257
-        $initial = $payment * (1.0 + $rate * $when);
258
-        return \log(($initial - $future_value * $rate) / ($initial + $present_value * $rate)) / \log(1.0 + $rate);
259
-    }
260
-
261
-    /**
262
-     * Annual Equivalent Rate (AER) of an annual percentage rate (APR).
263
-     * The effective yearly rate of an annual percentage rate when the
264
-     * annual percentage rate is compounded periodically within the year.
265
-     *
266
-     * Same as the =EFFECT() function in most spreadsheet software.
267
-     *
268
-     * The formula:
269
-     * https://en.wikipedia.org/wiki/Effective_interest_rate
270
-     *
271
-     *        /     i \ ᴺ
272
-     * AER = | 1 +  -  |  - 1
273
-     *        \     n /
274
-     *
275
-     * Examples:
276
-     * The AER of APR 3.5% interest compounded monthly.
277
-     *   aer(0.035, 12)
278
-     *
279
-     * @param  float $nominal
280
-     * @param  int $periods
281
-     *
282
-     * @return float
283
-     */
284
-    public static function aer(float $nominal, int $periods): float
285
-    {
286
-        if ($periods == 1) {
287
-            return $nominal;
288
-        }
289
-
290
-        return \pow(1 + ($nominal / $periods), $periods) - 1;
291
-    }
292
-
293
-    /**
294
-     * Annual Nominal Rate of an annual effective rate (AER).
295
-     * The nominal yearly rate of an annual effective rate when the
296
-     * annual effective rate is compounded periodically within the year.
297
-     *
298
-     * Same as the =NOMINAL() function in most spreadsheet software.
299
-     *
300
-     * See:
301
-     * https://en.wikipedia.org/wiki/Nominal_interest_rate
302
-     *
303
-     *           /          1/N    \
304
-     * NOMINAL = | (AER + 1)    -1 | * N
305
-     *           \                 /
306
-     *
307
-     * Examples:
308
-     * The nominal rate of AER 3.557% interest compounded monthly.
309
-     *   nominal(0.03557, 12)
310
-     *
311
-     * @param  float $aer
312
-     * @param  int $periods
313
-     *
314
-     * @return float
315
-     */
316
-    public static function nominal(float $aer, int $periods): float
317
-    {
318
-        if ($periods == 1) {
319
-            return $aer;
320
-        }
321
-
322
-        return (\pow($aer + 1, 1 / $periods) - 1) * $periods;
323
-    }
324
-
325
-    /**
326
-     * Future value for a loan or annuity with compound interest.
327
-     *
328
-     * Same as the =FV() function in most spreadsheet software.
329
-     *
330
-     * The basic future-value formula derivation:
331
-     * https://en.wikipedia.org/wiki/Future_value
332
-     *
333
-     *                   PMT*((1+r)ᴺ - 1)
334
-     * FV = -PV*(1+r)ᴺ - ----------------
335
-     *                          r
336
-     *
337
-     * The (1+r*when) factor adjusts the payment to the beginning or end
338
-     * of the period. In the common case of a payment at the end of a period,
339
-     * the factor is 1 and reduces to the formula above. Setting when=1 computes
340
-     * an "annuity due" with an immediate payment.
341
-     *
342
-     * Examples:
343
-     * The future value in 5 years on a 30-year fixed mortgage note of $265000
344
-     * at 3.5% interest paid at the end of every month. This is how much loan
345
-     * principle would be outstanding:
346
-     *   fv(0.035/12, 5*12, 1189.97, -265000, false)
347
-     *
348
-     * The present_value is negative indicating money borrowed for the mortgage,
349
-     * whereas payment is positive, indicating money that will be paid to the
350
-     * mortgage.
351
-     *
352
-     * @param  float $rate
353
-     * @param  int   $periods
354
-     * @param  float $payment
355
-     * @param  float $present_value
356
-     * @param  bool  $beginning adjust the payment to the beginning or end of the period
357
-     *
358
-     * @return float
359
-     */
360
-    public static function fv(float $rate, int $periods, float $payment, float $present_value, bool $beginning = false): float
361
-    {
362
-        $when = $beginning ? 1 : 0;
363
-
364
-        if ($rate == 0) {
365
-            $fv = -($present_value + ($payment * $periods));
366
-            return self::checkZero($fv);
367
-        }
368
-
369
-        $initial  = 1 + ($rate * $when);
370
-        $compound = \pow(1 + $rate, $periods);
371
-        $fv       = - (($present_value * $compound) + (($payment * $initial * ($compound - 1)) / $rate));
372
-
373
-        return self::checkZero($fv);
374
-    }
375
-
376
-    /**
377
-     * Present value for a loan or annuity with compound interest.
378
-     *
379
-     * Same as the =PV() function in most spreadsheet software.
380
-     *
381
-     * The basic present-value formula derivation:
382
-     * https://en.wikipedia.org/wiki/Present_value
383
-     *
384
-     *            PMT*((1+r)ᴺ - 1)
385
-     * PV = -FV - ----------------
386
-     *                   r
387
-     *      ---------------------
388
-     *             (1 + r)ᴺ
389
-     *
390
-     * The (1+r*when) factor adjusts the payment to the beginning or end
391
-     * of the period. In the common case of a payment at the end of a period,
392
-     * the factor is 1 and reduces to the formula above. Setting when=1 computes
393
-     * an "annuity due" with an immediate payment.
394
-     *
395
-     * Examples:
396
-     * The present value of a bond's $1000 face value paid in 5 year's time
397
-     * with a constant discount rate of 3.5% compounded monthly:
398
-     *   pv(0.035/12, 5*12, 0, -1000, false)
399
-     *
400
-     * The present value of a $1000 5-year bond that pays a fixed 7% ($70)
401
-     * coupon at the end of each year with a discount rate of 5%:
402
-     *   pv(0.5, 5, -70, -1000, false)
403
-     *
404
-     * The payment and future_value is negative indicating money paid out.
405
-     *
406
-     * @param  float $rate
407
-     * @param  int   $periods
408
-     * @param  float $payment
409
-     * @param  float $future_value
410
-     * @param  bool  $beginning adjust the payment to the beginning or end of the period
411
-     *
412
-     * @return float
413
-     */
414
-    public static function pv(float $rate, int $periods, float $payment, float $future_value, bool $beginning = false): float
415
-    {
416
-        $when = $beginning ? 1 : 0;
417
-
418
-        if ($rate == 0) {
419
-            $pv = -$future_value - ($payment * $periods);
420
-            return self::checkZero($pv);
421
-        }
422
-
423
-        $initial  = 1 + ($rate * $when);
424
-        $compound = \pow(1 + $rate, $periods);
425
-        $pv       = (-$future_value - (($payment * $initial * ($compound - 1)) / $rate)) / $compound;
426
-
427
-        return self::checkZero($pv);
428
-    }
429
-
430
-    /**
431
-     * Net present value of cash flows. Cash flows are periodic starting
432
-     * from an initial time and with a uniform discount rate.
433
-     *
434
-     * Similar to the =NPV() function in most spreadsheet software, except
435
-     * the initial (usually negative) cash flow at time 0 is given as the
436
-     * first element of the array rather than subtracted. For example,
437
-     *   spreadsheet: =NPV(0.01, 100, 200, 300, 400) - 1000
438
-     * is done as
439
-     *   MathPHP::npv(0.01, [-1000, 100, 200, 300, 400])
440
-     *
441
-     * The basic net-present-value formula derivation:
442
-     * https://en.wikipedia.org/wiki/Net_present_value
443
-     *
444
-     *  n      Rt
445
-     *  Σ   --------
446
-     * t=0  (1 / r)ᵗ
447
-     *
448
-     * Examples:
449
-     * The net present value of 5 yearly cash flows after an initial $1000
450
-     * investment with a 3% discount rate:
451
-     *  npv(0.03, [-1000, 100, 500, 300, 700, 700])
452
-     *
453
-     * @param  float $rate
454
-     * @param  array<float> $values
455
-     *
456
-     * @return float
457
-     */
458
-    public static function npv(float $rate, array $values): float
459
-    {
460
-        $result = 0.0;
461
-
462
-        for ($i = 0; $i < \count($values); ++$i) {
463
-            $result += $values[$i] / (1 + $rate) ** $i;
464
-        }
465
-
466
-        return $result;
467
-    }
468
-
469
-    /**
470
-     * Interest rate per period of an Annuity.
471
-     *
472
-     * Same as the =RATE() formula in most spreadsheet software.
473
-     *
474
-     * The basic rate formula derivation is to solve for the future value
475
-     * taking into account the present value:
476
-     * https://en.wikipedia.org/wiki/Future_value
477
-     *
478
-     *                        ((1+r)ᴺ - 1)
479
-     * FV + PV*(1+r)ᴺ + PMT * ------------ = 0
480
-     *                             r
481
-     * The (1+r*when) factor adjusts the payment to the beginning or end
482
-     * of the period. In the common case of a payment at the end of a period,
483
-     * the factor is 1 and reduces to the formula above. Setting when=1 computes
484
-     * an "annuity due" with an immediate payment.
485
-     *
486
-     * Not all solutions for the rate have real-value solutions or converge.
487
-     * In these cases, NAN is returned.
488
-     *
489
-     * @param  float $periods
490
-     * @param  float $payment
491
-     * @param  float $present_value
492
-     * @param  float $future_value
493
-     * @param  bool  $beginning
494
-     * @param  float $initial_guess
495
-     *
496
-     * @return float
497
-     */
498
-    public static function rate(float $periods, float $payment, float $present_value, float $future_value, bool $beginning = false, float $initial_guess = 0.1): float
499
-    {
500
-        $when = $beginning ? 1 : 0;
501
-
502
-        $func = function ($x, $periods, $payment, $present_value, $future_value, $when) {
503
-            return $future_value + $present_value * (1 + $x) ** $periods + $payment * (1 + $x * $when) / $x * ((1 + $x) ** $periods - 1);
504
-        };
505
-
506
-        return self::checkZero(NumericalAnalysis\RootFinding\NewtonsMethod::solve($func, [$initial_guess, $periods, $payment, $present_value, $future_value, $when], 0, self::EPSILON, 0));
507
-    }
508
-
509
-    /**
510
-     * Internal rate of return.
511
-     * Periodic rate of return that would provide a net-present value (NPV) of 0.
512
-     *
513
-     * Same as =IRR formula in most spreadsheet software.
514
-     *
515
-     * Reference:
516
-     * https://en.wikipedia.org/wiki/Internal_rate_of_return
517
-     *
518
-     * Examples:
519
-     * The rate of return of an initial investment of $100 with returns
520
-     * of $50, $40, and $30:
521
-     *  irr([-100, 50, 40, 30])
522
-     *
523
-     * Solves for NPV=0 using Newton's Method.
524
-     * @param array<float> $values
525
-     * @param float $initial_guess
526
-     *
527
-     * @return float
528
-     *
529
-     * @throws OutOfBoundsException
530
-     *
531
-     * @todo: Use eigenvalues to find the roots of a characteristic polynomial.
532
-     * This will allow finding all solutions and eliminate the need of the initial_guess.
533
-     */
534
-    public static function irr(array $values, float $initial_guess = 0.1): float
535
-    {
536
-        $func = function ($x, $values) {
537
-            return Finance::npv($x, $values);
538
-        };
539
-
540
-        if (\count($values) <= 1) {
541
-            return \NAN;
542
-        }
543
-
544
-        $root = NumericalAnalysis\RootFinding\NewtonsMethod::solve($func, [$initial_guess, $values], 0, self::EPSILON, 0);
545
-        if (!\is_nan($root)) {
546
-            return self::CheckZero($root);
547
-        }
548
-        return self::checkZero(self::alternateIrr($values));
549
-    }
550
-
551
-    /**
552
-     * Alternate IRR implementation.
553
-     *
554
-     * A more numerically stable implementation that converges to only one value.
555
-     *
556
-     * Based off of Better: https://github.com/better/irr
557
-     *
558
-     * @param  array<float> $values
559
-     *
560
-     * @return float
561
-     */
562
-    private static function alternateIrr(array $values): float
563
-    {
564
-        $rate = 0.0;
565
-        for ($iter = 0; $iter < 100; $iter++) {
566
-            $m = -1000;
567
-            for ($i = 0; $i < \count($values); $i++) {
568
-                $m = \max($m, -$rate * $i);
569
-            }
570
-            $f = [];
571
-            for ($i = 0; $i < \count($values); $i++) {
572
-                $f[$i] = \exp(-$rate * $i - $m);
573
-            }
574
-            $t = 0;
575
-            for ($i = 0; $i < \count($values); $i++) {
576
-                $t += $f[$i] * $values[$i];
577
-            }
578
-            if (\abs($t) < (self::EPSILON * \exp($m))) {
579
-                break;
580
-            }
581
-            $u = 0;
582
-            for ($i = 0; $i < \count($values); $i++) {
583
-                $u += $f[$i] * $i * $values[$i];
584
-            }
585
-            if ($u == 0) {
586
-                return \NAN;
587
-            }
588
-            $rate += $t / $u;
589
-        }
590
-        return \exp($rate) - 1;
591
-    }
592
-
593
-    /**
594
-     * Modified internal rate of return.
595
-     * Rate of return that discounts outflows (investments) at the financing rate,
596
-     * and reinvests inflows with an expected rate of return.
597
-     *
598
-     * Same as =MIRR formula in most spreadsheet software.
599
-     *
600
-     * The formula derivation:
601
-     * https://en.wikipedia.org/wiki/Modified_internal_rate_of_return
602
-     *
603
-     *       _____________________________
604
-     *     n/ FV(re-invested cash inflows)
605
-     *  -  /  ----------------------------  - 1.0
606
-     *   \/   PV(discounted cash outflows)
607
-     *
608
-     * Examples:
609
-     * The rate of return of an initial investment of $100 at 5% financing
610
-     * with returns of $50, $40, and $30 reinvested at 10%:
611
-     *  mirr([-100, 50, 40, 30], 0.05, 0.10)
612
-     *
613
-     * @param  array<float> $values
614
-     * @param  float $finance_rate
615
-     * @param  float $reinvestment_rate
616
-     *
617
-     * @return float
618
-     */
619
-    public static function mirr(array $values, float $finance_rate, float $reinvestment_rate): float
620
-    {
621
-        $inflows  = array();
622
-        $outflows = array();
623
-
624
-        for ($i = 0; $i < \count($values); $i++) {
625
-            if ($values[$i] >= 0) {
626
-                $inflows[]  = $values[$i];
627
-                $outflows[] = 0;
628
-            } else {
629
-                $inflows[]  = 0;
630
-                $outflows[] = $values[$i];
631
-            }
632
-        }
633
-
634
-        $nonzero = function ($x) {
635
-            return $x != 0;
636
-        };
637
-
638
-        if (\count(\array_filter($inflows, $nonzero)) == 0 || \count(\array_filter($outflows, $nonzero)) == 0) {
639
-            return \NAN;
640
-        }
641
-
642
-        $root        = \count($values) - 1;
643
-        $pv_inflows  = self::npv($reinvestment_rate, $inflows);
644
-        $fv_inflows  = self::fv($reinvestment_rate, $root, 0, -$pv_inflows);
645
-        $pv_outflows = self::npv($finance_rate, $outflows);
646
-
647
-        return self::checkZero(\pow($fv_inflows / -$pv_outflows, 1 / $root) - 1);
648
-    }
649
-
650
-    /**
651
-     * Discounted Payback of an investment.
652
-     * The number of periods to recoup cash outlays of an investment.
653
-     *
654
-     * This is commonly used with discount rate=0 as simple payback period,
655
-     * but it is not a real financial measurement when it doesn't consider the
656
-     * discount rate. Even with a discount rate, it doesn't consider the cost
657
-     * of capital or re-investment of returns.
658
-     *
659
-     * Avoid this when possible. Consider NPV, MIRR, IRR, and other financial
660
-     * functions.
661
-     *
662
-     * Reference:
663
-     * https://en.wikipedia.org/wiki/Payback_period
664
-     *
665
-     * The result is given assuming cash flows are continous throughout a period.
666
-     * To compute payback in terms of whole periods, use ceil() on the result.
667
-     *
668
-     * An investment could reach its payback period before future cash outlays occur.
669
-     * The payback period returned is defined to be the final point at which the
670
-     * sum of returns becomes positive.
671
-     *
672
-     * Examples:
673
-     * The payback period of an investment with a $1,000 investment and future returns
674
-     * of $100, $200, $300, $400, $500:
675
-     *  payback([-1000, 100, 200, 300, 400, 500])
676
-     *
677
-     * The discounted payback period of an investment with a $1,000 investment, future returns
678
-     * of $100, $200, $300, $400, $500, and a discount rate of 0.10:
679
-     *  payback([-1000, 100, 200, 300, 400, 500], 0.1)
680
-     *
681
-     * @param  array<float> $values
682
-     * @param  float $rate
683
-     *
684
-     * @return float
685
-     */
686
-    public static function payback(array $values, float $rate = 0.0): float
687
-    {
688
-        $last_outflow = -1;
689
-        for ($i = 0; $i < \count($values); $i++) {
690
-            if ($values[$i] < 0) {
691
-                $last_outflow = $i;
692
-            }
693
-        }
694
-
695
-        if ($last_outflow < 0) {
696
-            return 0.0;
697
-        }
698
-
699
-        $sum            = $values[0];
700
-        $payback_period = -1;
701
-
702
-        for ($i = 1; $i < \count($values); $i++) {
703
-            $prevsum         = $sum;
704
-            $discounted_flow = $values[$i] / (1 + $rate) ** $i;
705
-            $sum            += $discounted_flow;
706
-            if ($sum >= 0) {
707
-                if ($i > $last_outflow) {
708
-                    return ($i - 1) + (-$prevsum / $discounted_flow);
709
-                }
710
-                if ($payback_period == -1) {
711
-                    $payback_period = ($i - 1) + (-$prevsum / $discounted_flow);
712
-                }
713
-            } else {
714
-                $payback_period = -1;
715
-            }
716
-        }
717
-        if ($sum >= 0) {
718
-            return $payback_period;
719
-        }
720
-
721
-        return \NAN;
722
-    }
723
-
724
-    /**
725
-     * Profitability Index.
726
-     * The Profitability Index, also referred to as Profit Investment
727
-     * Ratio (PIR) and Value Investment Ratio (VIR), is a comparison of
728
-     * discounted cash inflows to discounted cash outflows. It can be
729
-     * used as a decision criteria of an investment, using larger than 1
730
-     * to choose an investment, and less than 1 to pass.
731
-     *
732
-     * The formula derivation:
733
-     * https://en.wikipedia.org/wiki/Profitability_index
734
-     *
735
-     * PV(cash inflows)
736
-     * ----------------
737
-     * PV(cash outflows)
738
-     *
739
-     * The formula is usually stated in terms of the initial investmest,
740
-     * but it is generalized here to discount all future outflows.
741
-     *
742
-     * Examples:
743
-     * The profitability index of an initial $100 investment with future
744
-     * returns of $50, $50, $50 with a 10% discount rate:
745
-     *  profitabilityIndex([-100, 50, 50, 50], 0.10)
746
-     *
747
-     * @param  array<float> $values
748
-     * @param  float $rate
749
-     *
750
-     * @return float
751
-     */
752
-    public static function profitabilityIndex(array $values, float $rate): float
753
-    {
754
-        $inflows  = array();
755
-        $outflows = array();
756
-
757
-        for ($i = 0; $i < \count($values); $i++) {
758
-            if ($values[$i] >= 0) {
759
-                $inflows[]  = $values[$i];
760
-                $outflows[] = 0;
761
-            } else {
762
-                $inflows[]  = 0;
763
-                $outflows[] = -$values[$i];
764
-            }
765
-        }
766
-
767
-        $nonzero = function ($x) {
768
-            return $x != 0;
769
-        };
770
-
771
-        if (\count(\array_filter($outflows, $nonzero)) == 0) {
772
-            return \NAN;
773
-        }
774
-
775
-        $pv_inflows  = self::npv($rate, $inflows);
776
-        $pv_outflows = self::npv($rate, $outflows);
777
-
778
-        return $pv_inflows / $pv_outflows;
779
-    }
16
+	/**
17
+	 * Floating-point range near zero to consider insignificant.
18
+	 */
19
+	public const EPSILON = 1e-6;
20
+
21
+	/**
22
+	 * Consider any floating-point value less than epsilon from zero as zero,
23
+	 * ie any value in the range [-epsilon < 0 < epsilon] is considered zero.
24
+	 * Also used to convert -0.0 to 0.0.
25
+	 *
26
+	 * @param float $value
27
+	 * @param float $epsilon
28
+	 *
29
+	 * @return float
30
+	 */
31
+	private static function checkZero(float $value, float $epsilon = self::EPSILON): float
32
+	{
33
+		return \abs($value) < $epsilon ? 0.0 : $value;
34
+	}
35
+
36
+	/**
37
+	 * Financial payment for a loan or annuity with compound interest.
38
+	 * Determines the periodic payment amount for a given interest rate,
39
+	 * principal, targeted payment goal, life of the annuity as number
40
+	 * of payments, and whether the payments are made at the start or end
41
+	 * of each payment period.
42
+	 *
43
+	 * Same as the =PMT() function in most spreadsheet software.
44
+	 *
45
+	 * The basic monthly payment formula derivation:
46
+	 * https://en.wikipedia.org/wiki/Mortgage_calculator#Monthly_payment_formula
47
+	 *
48
+	 *       rP(1+r)ᴺ
49
+	 * PMT = --------
50
+	 *       (1+r)ᴺ-1
51
+	 *
52
+	 * The formula is adjusted to allow targeting any future value rather than 0.
53
+	 * The 1/(1+r*when) factor adjusts the payment to the beginning or end
54
+	 * of the period. In the common case of a payment at the end of a period,
55
+	 * the factor is 1 and reduces to the formula above. Setting when=1 computes
56
+	 * an "annuity due" with an immediate payment.
57
+	 *
58
+	 * Examples:
59
+	 * The payment on a 30-year fixed mortgage note of $265000 at 3.5% interest
60
+	 * paid at the end of every month.
61
+	 *   pmt(0.035/12, 30*12, 265000, 0, false)
62
+	 *
63
+	 * The payment on a 30-year fixed mortgage note of $265000 at 3.5% interest
64
+	 * needed to half the principal in half in 5 years:
65
+	 *   pmt(0.035/12, 5*12, 265000, 265000/2, false)
66
+	 *
67
+	 * The weekly payment into a savings account with 1% interest rate and current
68
+	 * balance of $1500 needed to reach $10000 after 3 years:
69
+	 *   pmt(0.01/52, 3*52, -1500, 10000, false)
70
+	 * The present_value is negative indicating money put into the savings account,
71
+	 * whereas future_value is positive, indicating money that will be withdrawn from
72
+	 * the account. Similarly, the payment value is negative
73
+	 *
74
+	 * How much money can be withdrawn at the end of every quarter from an account
75
+	 * with $1000000 earning 4% so the money lasts 20 years:
76
+	 *  pmt(0.04/4, 20*4, 1000000, 0, false)
77
+	 *
78
+	 * @param  float $rate
79
+	 * @param  int   $periods
80
+	 * @param  float $present_value
81
+	 * @param  float $future_value
82
+	 * @param  bool  $beginning adjust the payment to the beginning or end of the period
83
+	 *
84
+	 * @return float
85
+	 */
86
+	public static function pmt(float $rate, int $periods, float $present_value, float $future_value = 0.0, bool $beginning = false): float
87
+	{
88
+		$when = $beginning ? 1 : 0;
89
+
90
+		if ($rate == 0) {
91
+			return - ($future_value + $present_value) / $periods;
92
+		}
93
+
94
+		return - ($future_value + ($present_value * \pow(1 + $rate, $periods)))
95
+			/
96
+			((1 + $rate * $when) / $rate * (\pow(1 + $rate, $periods) - 1));
97
+	}
98
+
99
+	/**
100
+	 * Interest on a financial payment for a loan or annuity with compound interest.
101
+	 * Determines the interest payment at a particular period of the annuity. For
102
+	 * a typical loan paid down to zero, the amount of interest and principle paid
103
+	 * throughout the lifetime of the loan will change, with the interest portion
104
+	 * of the payment decreasing over time as the loan principle decreases.
105
+	 *
106
+	 * Same as the =IPMT() function in most spreadsheet software.
107
+	 *
108
+	 * See the PMT function for derivation of the formula. For IPMT, we have
109
+	 * the payment equal to the interest portion and principle portion of the payment:
110
+	 *
111
+	 * PMT = IPMT + PPMT
112
+	 *
113
+	 * The interest portion IPMT on a regular annuity can be calculated by computing
114
+	 * the future value of the annuity for the prior period and computing the compound
115
+	 * interest for one period:
116
+	 *
117
+	 * IPMT = FV(p=n-1) * rate
118
+	 *
119
+	 * For an "annuity due" where payment is at the start of the period, period=1 has
120
+	 * no interest portion of the payment because no time has elapsed for compounding.
121
+	 * To compute the interest portion of the payment, the future value of 2 periods
122
+	 * back needs to be computed, as the definition of a period is different, giving:
123
+	 *
124
+	 * IPMT = (FV(p=n-2) - PMT) * rate
125
+	 *
126
+	 * By thinking of the future value at period 0 instead of the present value, the
127
+	 * given formulas are computed.
128
+	 *
129
+	 * Example of regular annuity and annuity due for a loan of $10.00 paid back in 3 periods.
130
+	 * Although the principle payments are equal, the total payment and interest portion are
131
+	 * lower with the annuity due because a principle payment is made immediately.
132
+	 *
133
+	 *                       Regular Annuity |  Annuity Due
134
+	 * Period   FV       PMT    IPMT   PPMT  |   PMT    IPMT    PPMT
135
+	 *   0     -10.00                        |
136
+	 *   1      -6.83   -3.67  -0.50  -3.17  |  -3.50   0.00   -3.50
137
+	 *   2      -3.50   -3.67  -0.34  -3.33  |  -3.50  -0.33   -3.17
138
+	 *   3       0.00   -3.67  -0.17  -3.50  |  -3.50  -0.17   -3.33
139
+	 *                -----------------------|----------------------
140
+	 *             SUM -11.01  -1.01 -10.00  | -10.50  -0.50  -10.00
141
+	 *
142
+	 * Examples:
143
+	 * The interest on a payment on a 30-year fixed mortgage note of $265000 at 3.5% interest
144
+	 * paid at the end of every month, looking at the first payment:
145
+	 *   ipmt(0.035/12, 1, 30*12, 265000, 0, false)
146
+	 *
147
+	 * @param  float $rate
148
+	 * @param  int   $period
149
+	 * @param  int   $periods
150
+	 * @param  float $present_value
151
+	 * @param  float $future_value
152
+	 * @param  bool  $beginning adjust the payment to the beginning or end of the period
153
+	 *
154
+	 * @return float
155
+	 */
156
+	public static function ipmt(float $rate, int $period, int $periods, float $present_value, float $future_value = 0.0, bool $beginning = false): float
157
+	{
158
+		if ($period < 1 || $period > $periods) {
159
+			return \NAN;
160
+		}
161
+
162
+		if ($rate == 0) {
163
+			return 0;
164
+		}
165
+
166
+		if ($beginning && $period == 1) {
167
+			return 0.0;
168
+		}
169
+
170
+		$payment = self::pmt($rate, $periods, $present_value, $future_value, $beginning);
171
+		if ($beginning) {
172
+			$interest = (self::fv($rate, $period - 2, $payment, $present_value, $beginning) - $payment) * $rate;
173
+		} else {
174
+			$interest = self::fv($rate, $period - 1, $payment, $present_value, $beginning) * $rate;
175
+		}
176
+
177
+		return self::checkZero($interest);
178
+	}
179
+
180
+	/**
181
+	 * Principle on a financial payment for a loan or annuity with compound interest.
182
+	 * Determines the principle payment at a particular period of the annuity. For
183
+	 * a typical loan paid down to zero, the amount of interest and principle paid
184
+	 * throughout the lifetime of the loan will change, with the principle portion
185
+	 * of the payment increasing over time as the loan principle decreases.
186
+	 *
187
+	 * Same as the =PPMT() function in most spreadsheet software.
188
+	 *
189
+	 * See the PMT function for derivation of the formula.
190
+	 * See the IPMT function for derivation and use of PMT, IPMT, and PPMT.
191
+	 *
192
+	 * With derivations for PMT and IPMT, we simply compute:
193
+	 *
194
+	 * PPMT = PMT - IPMT
195
+	 *
196
+	 * Examples:
197
+	 * The principle on a payment on a 30-year fixed mortgage note of $265000 at 3.5% interest
198
+	 * paid at the end of every month, looking at the first payment:
199
+	 *   ppmt(0.035/12, 1, 30*12, 265000, 0, false)
200
+	 *
201
+	 * @param  float $rate
202
+	 * @param  int   $period
203
+	 * @param  int   $periods
204
+	 * @param  float $present_value
205
+	 * @param  float $future_value
206
+	 * @param  bool  $beginning adjust the payment to the beginning or end of the period
207
+	 *
208
+	 * @return float
209
+	 */
210
+	public static function ppmt(float $rate, int $period, int $periods, float $present_value, float $future_value = 0.0, bool $beginning = false): float
211
+	{
212
+		$payment = self::pmt($rate, $periods, $present_value, $future_value, $beginning);
213
+		$ipmt    = self::ipmt($rate, $period, $periods, $present_value, $future_value, $beginning);
214
+
215
+		return $payment - $ipmt;
216
+	}
217
+
218
+	/**
219
+	 * Number of payment periods of an annuity.
220
+	 * Solves for the number of periods in the annuity formula.
221
+	 *
222
+	 * Same as the =NPER() function in most spreadsheet software.
223
+	 *
224
+	 * Solving the basic annuity formula for number of periods:
225
+	 *        log(PMT - FV*r)
226
+	 *        ---------------
227
+	 *        log(PMT + PV*r)
228
+	 * n = --------------------
229
+	 *          log(1 + r)
230
+	 *
231
+	 * The (1+r*when) factor adjusts the payment to the beginning or end
232
+	 * of the period. In the common case of a payment at the end of a period,
233
+	 * the factor is 1 and reduces to the formula above. Setting when=1 computes
234
+	 * an "annuity due" with an immediate payment.
235
+	 *
236
+	 * Examples:
237
+	 * The number of periods of a $475000 mortgage with interest rate 3.5% and monthly
238
+	 * payment of $2132.96  paid in full:
239
+	 *   nper(0.035/12, -2132.96, 475000, 0)
240
+	 *
241
+	 * @param  float $rate
242
+	 * @param  float $payment
243
+	 * @param  float $present_value
244
+	 * @param  float $future_value
245
+	 * @param  bool  $beginning adjust the payment to the beginning or end of the period
246
+	 *
247
+	 * @return float
248
+	 */
249
+	public static function periods(float $rate, float $payment, float $present_value, float $future_value, bool $beginning = false): float
250
+	{
251
+		$when = $beginning ? 1 : 0;
252
+
253
+		if ($rate == 0) {
254
+			return - ($present_value + $future_value) / $payment;
255
+		}
256
+
257
+		$initial = $payment * (1.0 + $rate * $when);
258
+		return \log(($initial - $future_value * $rate) / ($initial + $present_value * $rate)) / \log(1.0 + $rate);
259
+	}
260
+
261
+	/**
262
+	 * Annual Equivalent Rate (AER) of an annual percentage rate (APR).
263
+	 * The effective yearly rate of an annual percentage rate when the
264
+	 * annual percentage rate is compounded periodically within the year.
265
+	 *
266
+	 * Same as the =EFFECT() function in most spreadsheet software.
267
+	 *
268
+	 * The formula:
269
+	 * https://en.wikipedia.org/wiki/Effective_interest_rate
270
+	 *
271
+	 *        /     i \ ᴺ
272
+	 * AER = | 1 +  -  |  - 1
273
+	 *        \     n /
274
+	 *
275
+	 * Examples:
276
+	 * The AER of APR 3.5% interest compounded monthly.
277
+	 *   aer(0.035, 12)
278
+	 *
279
+	 * @param  float $nominal
280
+	 * @param  int $periods
281
+	 *
282
+	 * @return float
283
+	 */
284
+	public static function aer(float $nominal, int $periods): float
285
+	{
286
+		if ($periods == 1) {
287
+			return $nominal;
288
+		}
289
+
290
+		return \pow(1 + ($nominal / $periods), $periods) - 1;
291
+	}
292
+
293
+	/**
294
+	 * Annual Nominal Rate of an annual effective rate (AER).
295
+	 * The nominal yearly rate of an annual effective rate when the
296
+	 * annual effective rate is compounded periodically within the year.
297
+	 *
298
+	 * Same as the =NOMINAL() function in most spreadsheet software.
299
+	 *
300
+	 * See:
301
+	 * https://en.wikipedia.org/wiki/Nominal_interest_rate
302
+	 *
303
+	 *           /          1/N    \
304
+	 * NOMINAL = | (AER + 1)    -1 | * N
305
+	 *           \                 /
306
+	 *
307
+	 * Examples:
308
+	 * The nominal rate of AER 3.557% interest compounded monthly.
309
+	 *   nominal(0.03557, 12)
310
+	 *
311
+	 * @param  float $aer
312
+	 * @param  int $periods
313
+	 *
314
+	 * @return float
315
+	 */
316
+	public static function nominal(float $aer, int $periods): float
317
+	{
318
+		if ($periods == 1) {
319
+			return $aer;
320
+		}
321
+
322
+		return (\pow($aer + 1, 1 / $periods) - 1) * $periods;
323
+	}
324
+
325
+	/**
326
+	 * Future value for a loan or annuity with compound interest.
327
+	 *
328
+	 * Same as the =FV() function in most spreadsheet software.
329
+	 *
330
+	 * The basic future-value formula derivation:
331
+	 * https://en.wikipedia.org/wiki/Future_value
332
+	 *
333
+	 *                   PMT*((1+r)ᴺ - 1)
334
+	 * FV = -PV*(1+r)ᴺ - ----------------
335
+	 *                          r
336
+	 *
337
+	 * The (1+r*when) factor adjusts the payment to the beginning or end
338
+	 * of the period. In the common case of a payment at the end of a period,
339
+	 * the factor is 1 and reduces to the formula above. Setting when=1 computes
340
+	 * an "annuity due" with an immediate payment.
341
+	 *
342
+	 * Examples:
343
+	 * The future value in 5 years on a 30-year fixed mortgage note of $265000
344
+	 * at 3.5% interest paid at the end of every month. This is how much loan
345
+	 * principle would be outstanding:
346
+	 *   fv(0.035/12, 5*12, 1189.97, -265000, false)
347
+	 *
348
+	 * The present_value is negative indicating money borrowed for the mortgage,
349
+	 * whereas payment is positive, indicating money that will be paid to the
350
+	 * mortgage.
351
+	 *
352
+	 * @param  float $rate
353
+	 * @param  int   $periods
354
+	 * @param  float $payment
355
+	 * @param  float $present_value
356
+	 * @param  bool  $beginning adjust the payment to the beginning or end of the period
357
+	 *
358
+	 * @return float
359
+	 */
360
+	public static function fv(float $rate, int $periods, float $payment, float $present_value, bool $beginning = false): float
361
+	{
362
+		$when = $beginning ? 1 : 0;
363
+
364
+		if ($rate == 0) {
365
+			$fv = -($present_value + ($payment * $periods));
366
+			return self::checkZero($fv);
367
+		}
368
+
369
+		$initial  = 1 + ($rate * $when);
370
+		$compound = \pow(1 + $rate, $periods);
371
+		$fv       = - (($present_value * $compound) + (($payment * $initial * ($compound - 1)) / $rate));
372
+
373
+		return self::checkZero($fv);
374
+	}
375
+
376
+	/**
377
+	 * Present value for a loan or annuity with compound interest.
378
+	 *
379
+	 * Same as the =PV() function in most spreadsheet software.
380
+	 *
381
+	 * The basic present-value formula derivation:
382
+	 * https://en.wikipedia.org/wiki/Present_value
383
+	 *
384
+	 *            PMT*((1+r)ᴺ - 1)
385
+	 * PV = -FV - ----------------
386
+	 *                   r
387
+	 *      ---------------------
388
+	 *             (1 + r)ᴺ
389
+	 *
390
+	 * The (1+r*when) factor adjusts the payment to the beginning or end
391
+	 * of the period. In the common case of a payment at the end of a period,
392
+	 * the factor is 1 and reduces to the formula above. Setting when=1 computes
393
+	 * an "annuity due" with an immediate payment.
394
+	 *
395
+	 * Examples:
396
+	 * The present value of a bond's $1000 face value paid in 5 year's time
397
+	 * with a constant discount rate of 3.5% compounded monthly:
398
+	 *   pv(0.035/12, 5*12, 0, -1000, false)
399
+	 *
400
+	 * The present value of a $1000 5-year bond that pays a fixed 7% ($70)
401
+	 * coupon at the end of each year with a discount rate of 5%:
402
+	 *   pv(0.5, 5, -70, -1000, false)
403
+	 *
404
+	 * The payment and future_value is negative indicating money paid out.
405
+	 *
406
+	 * @param  float $rate
407
+	 * @param  int   $periods
408
+	 * @param  float $payment
409
+	 * @param  float $future_value
410
+	 * @param  bool  $beginning adjust the payment to the beginning or end of the period
411
+	 *
412
+	 * @return float
413
+	 */
414
+	public static function pv(float $rate, int $periods, float $payment, float $future_value, bool $beginning = false): float
415
+	{
416
+		$when = $beginning ? 1 : 0;
417
+
418
+		if ($rate == 0) {
419
+			$pv = -$future_value - ($payment * $periods);
420
+			return self::checkZero($pv);
421
+		}
422
+
423
+		$initial  = 1 + ($rate * $when);
424
+		$compound = \pow(1 + $rate, $periods);
425
+		$pv       = (-$future_value - (($payment * $initial * ($compound - 1)) / $rate)) / $compound;
426
+
427
+		return self::checkZero($pv);
428
+	}
429
+
430
+	/**
431
+	 * Net present value of cash flows. Cash flows are periodic starting
432
+	 * from an initial time and with a uniform discount rate.
433
+	 *
434
+	 * Similar to the =NPV() function in most spreadsheet software, except
435
+	 * the initial (usually negative) cash flow at time 0 is given as the
436
+	 * first element of the array rather than subtracted. For example,
437
+	 *   spreadsheet: =NPV(0.01, 100, 200, 300, 400) - 1000
438
+	 * is done as
439
+	 *   MathPHP::npv(0.01, [-1000, 100, 200, 300, 400])
440
+	 *
441
+	 * The basic net-present-value formula derivation:
442
+	 * https://en.wikipedia.org/wiki/Net_present_value
443
+	 *
444
+	 *  n      Rt
445
+	 *  Σ   --------
446
+	 * t=0  (1 / r)ᵗ
447
+	 *
448
+	 * Examples:
449
+	 * The net present value of 5 yearly cash flows after an initial $1000
450
+	 * investment with a 3% discount rate:
451
+	 *  npv(0.03, [-1000, 100, 500, 300, 700, 700])
452
+	 *
453
+	 * @param  float $rate
454
+	 * @param  array<float> $values
455
+	 *
456
+	 * @return float
457
+	 */
458
+	public static function npv(float $rate, array $values): float
459
+	{
460
+		$result = 0.0;
461
+
462
+		for ($i = 0; $i < \count($values); ++$i) {
463
+			$result += $values[$i] / (1 + $rate) ** $i;
464
+		}
465
+
466
+		return $result;
467
+	}
468
+
469
+	/**
470
+	 * Interest rate per period of an Annuity.
471
+	 *
472
+	 * Same as the =RATE() formula in most spreadsheet software.
473
+	 *
474
+	 * The basic rate formula derivation is to solve for the future value
475
+	 * taking into account the present value:
476
+	 * https://en.wikipedia.org/wiki/Future_value
477
+	 *
478
+	 *                        ((1+r)ᴺ - 1)
479
+	 * FV + PV*(1+r)ᴺ + PMT * ------------ = 0
480
+	 *                             r
481
+	 * The (1+r*when) factor adjusts the payment to the beginning or end
482
+	 * of the period. In the common case of a payment at the end of a period,
483
+	 * the factor is 1 and reduces to the formula above. Setting when=1 computes
484
+	 * an "annuity due" with an immediate payment.
485
+	 *
486
+	 * Not all solutions for the rate have real-value solutions or converge.
487
+	 * In these cases, NAN is returned.
488
+	 *
489
+	 * @param  float $periods
490
+	 * @param  float $payment
491
+	 * @param  float $present_value
492
+	 * @param  float $future_value
493
+	 * @param  bool  $beginning
494
+	 * @param  float $initial_guess
495
+	 *
496
+	 * @return float
497
+	 */
498
+	public static function rate(float $periods, float $payment, float $present_value, float $future_value, bool $beginning = false, float $initial_guess = 0.1): float
499
+	{
500
+		$when = $beginning ? 1 : 0;
501
+
502
+		$func = function ($x, $periods, $payment, $present_value, $future_value, $when) {
503
+			return $future_value + $present_value * (1 + $x) ** $periods + $payment * (1 + $x * $when) / $x * ((1 + $x) ** $periods - 1);
504
+		};
505
+
506
+		return self::checkZero(NumericalAnalysis\RootFinding\NewtonsMethod::solve($func, [$initial_guess, $periods, $payment, $present_value, $future_value, $when], 0, self::EPSILON, 0));
507
+	}
508
+
509
+	/**
510
+	 * Internal rate of return.
511
+	 * Periodic rate of return that would provide a net-present value (NPV) of 0.
512
+	 *
513
+	 * Same as =IRR formula in most spreadsheet software.
514
+	 *
515
+	 * Reference:
516
+	 * https://en.wikipedia.org/wiki/Internal_rate_of_return
517
+	 *
518
+	 * Examples:
519
+	 * The rate of return of an initial investment of $100 with returns
520
+	 * of $50, $40, and $30:
521
+	 *  irr([-100, 50, 40, 30])
522
+	 *
523
+	 * Solves for NPV=0 using Newton's Method.
524
+	 * @param array<float> $values
525
+	 * @param float $initial_guess
526
+	 *
527
+	 * @return float
528
+	 *
529
+	 * @throws OutOfBoundsException
530
+	 *
531
+	 * @todo: Use eigenvalues to find the roots of a characteristic polynomial.
532
+	 * This will allow finding all solutions and eliminate the need of the initial_guess.
533
+	 */
534
+	public static function irr(array $values, float $initial_guess = 0.1): float
535
+	{
536
+		$func = function ($x, $values) {
537
+			return Finance::npv($x, $values);
538
+		};
539
+
540
+		if (\count($values) <= 1) {
541
+			return \NAN;
542
+		}
543
+
544
+		$root = NumericalAnalysis\RootFinding\NewtonsMethod::solve($func, [$initial_guess, $values], 0, self::EPSILON, 0);
545
+		if (!\is_nan($root)) {
546
+			return self::CheckZero($root);
547
+		}
548
+		return self::checkZero(self::alternateIrr($values));
549
+	}
550
+
551
+	/**
552
+	 * Alternate IRR implementation.
553
+	 *
554
+	 * A more numerically stable implementation that converges to only one value.
555
+	 *
556
+	 * Based off of Better: https://github.com/better/irr
557
+	 *
558
+	 * @param  array<float> $values
559
+	 *
560
+	 * @return float
561
+	 */
562
+	private static function alternateIrr(array $values): float
563
+	{
564
+		$rate = 0.0;
565
+		for ($iter = 0; $iter < 100; $iter++) {
566
+			$m = -1000;
567
+			for ($i = 0; $i < \count($values); $i++) {
568
+				$m = \max($m, -$rate * $i);
569
+			}
570
+			$f = [];
571
+			for ($i = 0; $i < \count($values); $i++) {
572
+				$f[$i] = \exp(-$rate * $i - $m);
573
+			}
574
+			$t = 0;
575
+			for ($i = 0; $i < \count($values); $i++) {
576
+				$t += $f[$i] * $values[$i];
577
+			}
578
+			if (\abs($t) < (self::EPSILON * \exp($m))) {
579
+				break;
580
+			}
581
+			$u = 0;
582
+			for ($i = 0; $i < \count($values); $i++) {
583
+				$u += $f[$i] * $i * $values[$i];
584
+			}
585
+			if ($u == 0) {
586
+				return \NAN;
587
+			}
588
+			$rate += $t / $u;
589
+		}
590
+		return \exp($rate) - 1;
591
+	}
592
+
593
+	/**
594
+	 * Modified internal rate of return.
595
+	 * Rate of return that discounts outflows (investments) at the financing rate,
596
+	 * and reinvests inflows with an expected rate of return.
597
+	 *
598
+	 * Same as =MIRR formula in most spreadsheet software.
599
+	 *
600
+	 * The formula derivation:
601
+	 * https://en.wikipedia.org/wiki/Modified_internal_rate_of_return
602
+	 *
603
+	 *       _____________________________
604
+	 *     n/ FV(re-invested cash inflows)
605
+	 *  -  /  ----------------------------  - 1.0
606
+	 *   \/   PV(discounted cash outflows)
607
+	 *
608
+	 * Examples:
609
+	 * The rate of return of an initial investment of $100 at 5% financing
610
+	 * with returns of $50, $40, and $30 reinvested at 10%:
611
+	 *  mirr([-100, 50, 40, 30], 0.05, 0.10)
612
+	 *
613
+	 * @param  array<float> $values
614
+	 * @param  float $finance_rate
615
+	 * @param  float $reinvestment_rate
616
+	 *
617
+	 * @return float
618
+	 */
619
+	public static function mirr(array $values, float $finance_rate, float $reinvestment_rate): float
620
+	{
621
+		$inflows  = array();
622
+		$outflows = array();
623
+
624
+		for ($i = 0; $i < \count($values); $i++) {
625
+			if ($values[$i] >= 0) {
626
+				$inflows[]  = $values[$i];
627
+				$outflows[] = 0;
628
+			} else {
629
+				$inflows[]  = 0;
630
+				$outflows[] = $values[$i];
631
+			}
632
+		}
633
+
634
+		$nonzero = function ($x) {
635
+			return $x != 0;
636
+		};
637
+
638
+		if (\count(\array_filter($inflows, $nonzero)) == 0 || \count(\array_filter($outflows, $nonzero)) == 0) {
639
+			return \NAN;
640
+		}
641
+
642
+		$root        = \count($values) - 1;
643
+		$pv_inflows  = self::npv($reinvestment_rate, $inflows);
644
+		$fv_inflows  = self::fv($reinvestment_rate, $root, 0, -$pv_inflows);
645
+		$pv_outflows = self::npv($finance_rate, $outflows);
646
+
647
+		return self::checkZero(\pow($fv_inflows / -$pv_outflows, 1 / $root) - 1);
648
+	}
649
+
650
+	/**
651
+	 * Discounted Payback of an investment.
652
+	 * The number of periods to recoup cash outlays of an investment.
653
+	 *
654
+	 * This is commonly used with discount rate=0 as simple payback period,
655
+	 * but it is not a real financial measurement when it doesn't consider the
656
+	 * discount rate. Even with a discount rate, it doesn't consider the cost
657
+	 * of capital or re-investment of returns.
658
+	 *
659
+	 * Avoid this when possible. Consider NPV, MIRR, IRR, and other financial
660
+	 * functions.
661
+	 *
662
+	 * Reference:
663
+	 * https://en.wikipedia.org/wiki/Payback_period
664
+	 *
665
+	 * The result is given assuming cash flows are continous throughout a period.
666
+	 * To compute payback in terms of whole periods, use ceil() on the result.
667
+	 *
668
+	 * An investment could reach its payback period before future cash outlays occur.
669
+	 * The payback period returned is defined to be the final point at which the
670
+	 * sum of returns becomes positive.
671
+	 *
672
+	 * Examples:
673
+	 * The payback period of an investment with a $1,000 investment and future returns
674
+	 * of $100, $200, $300, $400, $500:
675
+	 *  payback([-1000, 100, 200, 300, 400, 500])
676
+	 *
677
+	 * The discounted payback period of an investment with a $1,000 investment, future returns
678
+	 * of $100, $200, $300, $400, $500, and a discount rate of 0.10:
679
+	 *  payback([-1000, 100, 200, 300, 400, 500], 0.1)
680
+	 *
681
+	 * @param  array<float> $values
682
+	 * @param  float $rate
683
+	 *
684
+	 * @return float
685
+	 */
686
+	public static function payback(array $values, float $rate = 0.0): float
687
+	{
688
+		$last_outflow = -1;
689
+		for ($i = 0; $i < \count($values); $i++) {
690
+			if ($values[$i] < 0) {
691
+				$last_outflow = $i;
692
+			}
693
+		}
694
+
695
+		if ($last_outflow < 0) {
696
+			return 0.0;
697
+		}
698
+
699
+		$sum            = $values[0];
700
+		$payback_period = -1;
701
+
702
+		for ($i = 1; $i < \count($values); $i++) {
703
+			$prevsum         = $sum;
704
+			$discounted_flow = $values[$i] / (1 + $rate) ** $i;
705
+			$sum            += $discounted_flow;
706
+			if ($sum >= 0) {
707
+				if ($i > $last_outflow) {
708
+					return ($i - 1) + (-$prevsum / $discounted_flow);
709
+				}
710
+				if ($payback_period == -1) {
711
+					$payback_period = ($i - 1) + (-$prevsum / $discounted_flow);
712
+				}
713
+			} else {
714
+				$payback_period = -1;
715
+			}
716
+		}
717
+		if ($sum >= 0) {
718
+			return $payback_period;
719
+		}
720
+
721
+		return \NAN;
722
+	}
723
+
724
+	/**
725
+	 * Profitability Index.
726
+	 * The Profitability Index, also referred to as Profit Investment
727
+	 * Ratio (PIR) and Value Investment Ratio (VIR), is a comparison of
728
+	 * discounted cash inflows to discounted cash outflows. It can be
729
+	 * used as a decision criteria of an investment, using larger than 1
730
+	 * to choose an investment, and less than 1 to pass.
731
+	 *
732
+	 * The formula derivation:
733
+	 * https://en.wikipedia.org/wiki/Profitability_index
734
+	 *
735
+	 * PV(cash inflows)
736
+	 * ----------------
737
+	 * PV(cash outflows)
738
+	 *
739
+	 * The formula is usually stated in terms of the initial investmest,
740
+	 * but it is generalized here to discount all future outflows.
741
+	 *
742
+	 * Examples:
743
+	 * The profitability index of an initial $100 investment with future
744
+	 * returns of $50, $50, $50 with a 10% discount rate:
745
+	 *  profitabilityIndex([-100, 50, 50, 50], 0.10)
746
+	 *
747
+	 * @param  array<float> $values
748
+	 * @param  float $rate
749
+	 *
750
+	 * @return float
751
+	 */
752
+	public static function profitabilityIndex(array $values, float $rate): float
753
+	{
754
+		$inflows  = array();
755
+		$outflows = array();
756
+
757
+		for ($i = 0; $i < \count($values); $i++) {
758
+			if ($values[$i] >= 0) {
759
+				$inflows[]  = $values[$i];
760
+				$outflows[] = 0;
761
+			} else {
762
+				$inflows[]  = 0;
763
+				$outflows[] = -$values[$i];
764
+			}
765
+		}
766
+
767
+		$nonzero = function ($x) {
768
+			return $x != 0;
769
+		};
770
+
771
+		if (\count(\array_filter($outflows, $nonzero)) == 0) {
772
+			return \NAN;
773
+		}
774
+
775
+		$pv_inflows  = self::npv($rate, $inflows);
776
+		$pv_outflows = self::npv($rate, $outflows);
777
+
778
+		return $pv_inflows / $pv_outflows;
779
+	}
780 780
 }
Please login to merge, or discard this patch.
Spacing   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -88,10 +88,10 @@  discard block
 block discarded – undo
88 88
         $when = $beginning ? 1 : 0;
89 89
 
90 90
         if ($rate == 0) {
91
-            return - ($future_value + $present_value) / $periods;
91
+            return -($future_value + $present_value) / $periods;
92 92
         }
93 93
 
94
-        return - ($future_value + ($present_value * \pow(1 + $rate, $periods)))
94
+        return -($future_value + ($present_value * \pow(1 + $rate, $periods)))
95 95
             /
96 96
             ((1 + $rate * $when) / $rate * (\pow(1 + $rate, $periods) - 1));
97 97
     }
@@ -251,7 +251,7 @@  discard block
 block discarded – undo
251 251
         $when = $beginning ? 1 : 0;
252 252
 
253 253
         if ($rate == 0) {
254
-            return - ($present_value + $future_value) / $payment;
254
+            return -($present_value + $future_value) / $payment;
255 255
         }
256 256
 
257 257
         $initial = $payment * (1.0 + $rate * $when);
@@ -499,7 +499,7 @@  discard block
 block discarded – undo
499 499
     {
500 500
         $when = $beginning ? 1 : 0;
501 501
 
502
-        $func = function ($x, $periods, $payment, $present_value, $future_value, $when) {
502
+        $func = function($x, $periods, $payment, $present_value, $future_value, $when) {
503 503
             return $future_value + $present_value * (1 + $x) ** $periods + $payment * (1 + $x * $when) / $x * ((1 + $x) ** $periods - 1);
504 504
         };
505 505
 
@@ -533,7 +533,7 @@  discard block
 block discarded – undo
533 533
      */
534 534
     public static function irr(array $values, float $initial_guess = 0.1): float
535 535
     {
536
-        $func = function ($x, $values) {
536
+        $func = function($x, $values) {
537 537
             return Finance::npv($x, $values);
538 538
         };
539 539
 
@@ -631,7 +631,7 @@  discard block
 block discarded – undo
631 631
             }
632 632
         }
633 633
 
634
-        $nonzero = function ($x) {
634
+        $nonzero = function($x) {
635 635
             return $x != 0;
636 636
         };
637 637
 
@@ -764,7 +764,7 @@  discard block
 block discarded – undo
764 764
             }
765 765
         }
766 766
 
767
-        $nonzero = function ($x) {
767
+        $nonzero = function($x) {
768 768
             return $x != 0;
769 769
         };
770 770
 
Please login to merge, or discard this patch.
markrogoyski/math-php/src/NumericalAnalysis/RootFinding/NewtonsMethod.php 2 patches
Indentation   +43 added lines, -43 removed lines patch added patch discarded remove patch
@@ -12,50 +12,50 @@
 block discarded – undo
12 12
  */
13 13
 class NewtonsMethod
14 14
 {
15
-    /**
16
-     * Use Newton's Method to find the x which produces $target = $function(x) value
17
-     * $args is an array of parameters to pass to $function, but having the element that
18
-     * will be changed and serve as the initial guess in position $position.
19
-     *
20
-     * @param callable     $function     f(x) callback function
21
-     * @param array<mixed> $args         Parameters to pass to callback function. The initial value for the
22
-     *                                   parameter of interest must be in this array.
23
-     * @param int|float    $target       Value of f(x) we a trying to solve for
24
-     * @param float        $tol          Tolerance; How close to the actual solution we would like.
25
-     * @param int          $position     Which element in the $args array will be changed; also serves as initial guess
26
-     * @param int          $iterations
27
-     *
28
-     * @return int|float
29
-     *
30
-     * @throws Exception\OutOfBoundsException if the tolerance is not valid
31
-     */
32
-    public static function solve(callable $function, array $args, $target, float $tol, int $position = 0, int $iterations = 100)
33
-    {
34
-        Validation::tolerance($tol);
15
+	/**
16
+	 * Use Newton's Method to find the x which produces $target = $function(x) value
17
+	 * $args is an array of parameters to pass to $function, but having the element that
18
+	 * will be changed and serve as the initial guess in position $position.
19
+	 *
20
+	 * @param callable     $function     f(x) callback function
21
+	 * @param array<mixed> $args         Parameters to pass to callback function. The initial value for the
22
+	 *                                   parameter of interest must be in this array.
23
+	 * @param int|float    $target       Value of f(x) we a trying to solve for
24
+	 * @param float        $tol          Tolerance; How close to the actual solution we would like.
25
+	 * @param int          $position     Which element in the $args array will be changed; also serves as initial guess
26
+	 * @param int          $iterations
27
+	 *
28
+	 * @return int|float
29
+	 *
30
+	 * @throws Exception\OutOfBoundsException if the tolerance is not valid
31
+	 */
32
+	public static function solve(callable $function, array $args, $target, float $tol, int $position = 0, int $iterations = 100)
33
+	{
34
+		Validation::tolerance($tol);
35 35
 
36
-        // Initialize
37
-        $args1 = $args;
38
-        $guess = $args[$position];
39
-        $i     = 0;
36
+		// Initialize
37
+		$args1 = $args;
38
+		$guess = $args[$position];
39
+		$i     = 0;
40 40
 
41
-        do {
42
-            $args1[$position] = $guess + $tol; // load the initial guess into the arguments
43
-            $args[$position]  = $guess;        // load the initial guess into the arguments
44
-            $y                = $function(...$args);
45
-            $y_at_xplusdelx   = $function(...$args1);
46
-            $slope            = ($y_at_xplusdelx - $y) / $tol;
47
-            $del_y            = $target - $y;
48
-            if (\abs($slope) < $tol) {
49
-                return \NAN;
50
-            }
51
-            $guess            = $del_y / $slope + $guess;
52
-            $dif              = \abs($del_y);
53
-            $i++;
54
-        } while ($dif > $tol && $i < $iterations);
41
+		do {
42
+			$args1[$position] = $guess + $tol; // load the initial guess into the arguments
43
+			$args[$position]  = $guess;        // load the initial guess into the arguments
44
+			$y                = $function(...$args);
45
+			$y_at_xplusdelx   = $function(...$args1);
46
+			$slope            = ($y_at_xplusdelx - $y) / $tol;
47
+			$del_y            = $target - $y;
48
+			if (\abs($slope) < $tol) {
49
+				return \NAN;
50
+			}
51
+			$guess            = $del_y / $slope + $guess;
52
+			$dif              = \abs($del_y);
53
+			$i++;
54
+		} while ($dif > $tol && $i < $iterations);
55 55
 
56
-        if ($dif > $tol) {
57
-            return \NAN;
58
-        }
59
-        return $guess;
60
-    }
56
+		if ($dif > $tol) {
57
+			return \NAN;
58
+		}
59
+		return $guess;
60
+	}
61 61
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -40,7 +40,7 @@
 block discarded – undo
40 40
 
41 41
         do {
42 42
             $args1[$position] = $guess + $tol; // load the initial guess into the arguments
43
-            $args[$position]  = $guess;        // load the initial guess into the arguments
43
+            $args[$position]  = $guess; // load the initial guess into the arguments
44 44
             $y                = $function(...$args);
45 45
             $y_at_xplusdelx   = $function(...$args1);
46 46
             $slope            = ($y_at_xplusdelx - $y) / $tol;
Please login to merge, or discard this patch.
markrogoyski/math-php/src/NumericalAnalysis/RootFinding/Validation.php 1 patch
Indentation   +27 added lines, -27 removed lines patch added patch discarded remove patch
@@ -9,32 +9,32 @@
 block discarded – undo
9 9
  */
10 10
 class Validation
11 11
 {
12
-    /**
13
-     * Throw an exception if the tolerance is negative.
14
-     *
15
-     * @param int|float $tol Tolerance; How close to the actual solution we would like.
16
-     *
17
-     * @throws Exception\OutOfBoundsException if $tol (the tolerance) is negative
18
-     */
19
-    public static function tolerance($tol): void
20
-    {
21
-        if ($tol < 0) {
22
-            throw new Exception\OutOfBoundsException('Tolerance must be greater than zero.');
23
-        }
24
-    }
12
+	/**
13
+	 * Throw an exception if the tolerance is negative.
14
+	 *
15
+	 * @param int|float $tol Tolerance; How close to the actual solution we would like.
16
+	 *
17
+	 * @throws Exception\OutOfBoundsException if $tol (the tolerance) is negative
18
+	 */
19
+	public static function tolerance($tol): void
20
+	{
21
+		if ($tol < 0) {
22
+			throw new Exception\OutOfBoundsException('Tolerance must be greater than zero.');
23
+		}
24
+	}
25 25
 
26
-    /**
27
-     * Verify that the start and end of of an interval are distinct numbers.
28
-     *
29
-     * @param int|float $a The start of the interval
30
-     * @param int|float $b The end of the interval
31
-     *
32
-     * @throws Exception\BadDataException if $a = $b
33
-     */
34
-    public static function interval($a, $b): void
35
-    {
36
-        if ($a === $b) {
37
-            throw new Exception\BadDataException('Start point and end point of interval cannot be the same.');
38
-        }
39
-    }
26
+	/**
27
+	 * Verify that the start and end of of an interval are distinct numbers.
28
+	 *
29
+	 * @param int|float $a The start of the interval
30
+	 * @param int|float $b The end of the interval
31
+	 *
32
+	 * @throws Exception\BadDataException if $a = $b
33
+	 */
34
+	public static function interval($a, $b): void
35
+	{
36
+		if ($a === $b) {
37
+			throw new Exception\BadDataException('Start point and end point of interval cannot be the same.');
38
+		}
39
+	}
40 40
 }
Please login to merge, or discard this patch.
htdocs/api/index.php 1 patch
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -91,7 +91,7 @@  discard block
 block discarded – undo
91 91
 
92 92
 require_once DOL_DOCUMENT_ROOT.'/includes/restler/framework/Luracast/Restler/AutoLoader.php';
93 93
 
94
-call_user_func(function () {
94
+call_user_func(function() {
95 95
 	$loader = Luracast\Restler\AutoLoader::instance();
96 96
 	spl_autoload_register($loader);
97 97
 	return $loader;
@@ -112,7 +112,7 @@  discard block
 block discarded – undo
112 112
 }
113 113
 
114 114
 // Enable and test if module Api is enabled
115
-if (!isModEnabled('api') ) {
115
+if (!isModEnabled('api')) {
116 116
 	$langs->load("admin");
117 117
 	dol_syslog("Call of Dolibarr API interfaces with module API REST are disabled");
118 118
 	print $langs->trans("WarningModuleNotActive", 'Api').'.<br><br>';
@@ -169,7 +169,7 @@  discard block
 block discarded – undo
169 169
 // If MAIN_API_DEBUG is set to 1, we save logs into file "dolibarr_api.log"
170 170
 if (!empty($conf->global->MAIN_API_DEBUG)) {
171 171
 	$r = $api->r;
172
-	$r->onCall(function () use ($r) {
172
+	$r->onCall(function() use ($r) {
173 173
 		// Don't log Luracast Restler Explorer recources calls
174 174
 		//if (!preg_match('/^explorer/', $r->url)) {
175 175
 		//	'method'  => $api->r->requestMethod,
@@ -354,7 +354,7 @@  discard block
 block discarded – undo
354 354
 			}
355 355
 		}
356 356
 
357
-		if (! $endpointisallowed) {
357
+		if (!$endpointisallowed) {
358 358
 			dol_syslog('The API with endpoint /'.$classfile.' is forbidden by config API_ENDPOINT_RULES', LOG_WARNING);
359 359
 			print 'The API with endpoint /'.$classfile.' is forbidden by config API_ENDPOINT_RULES';
360 360
 			header('HTTP/1.1 501 API is forbidden by API_ENDPOINT_RULES');
Please login to merge, or discard this patch.