diff --git a/.gitignore b/.gitignore index 077e29e35..c62f3dd79 100644 --- a/.gitignore +++ b/.gitignore @@ -19,7 +19,7 @@ # composer reserver directory, from sources, populate/update using "composer install" vendor/* -test/vendor/* +tests/*/vendor/* # all conf but listing prevention /conf/** @@ -46,7 +46,7 @@ test/vendor/* !/log/web.config # PHPUnit cache file -/test/.phpunit.result.cache +/tests/php-unit-tests/.phpunit.result.cache # Jetbrains diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2d60aad3d..257b1e171 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -131,7 +131,7 @@ Our tests are located in the `test/` directory, containing a PHPUnit config file When your code is working, please: -* stash as much as possible your commits, +* squash as much as possible your commits, * rebase your branch on our repo last commit, * create a pull request. diff --git a/Jenkinsfile b/Jenkinsfile index 56f298717..ca7548d2a 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,6 +1,14 @@ def infra node(){ + properties([ + buildDiscarder( + logRotator( + daysToKeepStr: "28", + numToKeepStr: "500") + ) + ]) + checkout scm infra = load '/var/lib/jenkins/workspace/itop-test-infra_master/src/Infra.groovy' diff --git a/README.md b/README.md index ac2d8bbcf..ceb645328 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ iTop also offers mass import tools to help you being even more efficient. - [iTop Forums][1]: community support - [iTop Tickets][2]: for feature requests and bug reports - [Releases download][3] - - [Software requirements][4] + - [iTop requirements][4] - [Documentation][5] covering both iTop and its official extensions - [iTop Hub][6] : discover and install extensions ! @@ -45,7 +45,7 @@ iTop also offers mass import tools to help you being even more efficient. [1]: https://sourceforge.net/p/itop/discussion/ [2]: https://sourceforge.net/p/itop/tickets/ [3]: https://sourceforge.net/projects/itop/files/itop/ -[4]: https://www.itophub.io/wiki/page?id=latest:install:upgrading_itop +[4]: https://www.itophub.io/wiki/page?id=latest:install:requirements [5]: https://www.itophub.io/wiki [6]: https://store.itophub.io/en_US/ diff --git a/application/applicationcontext.class.inc.php b/application/applicationcontext.class.inc.php index 1361f92d3..da68ff8d6 100644 --- a/application/applicationcontext.class.inc.php +++ b/application/applicationcontext.class.inc.php @@ -376,26 +376,19 @@ class ApplicationContext { $oAppContext = new ApplicationContext(); - if (is_null($sUrlMakerClass)) - { - $sUrlMakerClass = self::GetUrlMakerClass(); - } + if (is_null($sUrlMakerClass)) { + $sUrlMakerClass = self::GetUrlMakerClass(); + } $sUrl = call_user_func(array($sUrlMakerClass, 'MakeObjectUrl'), $sObjClass, $sObjKey); - if (strlen($sUrl) > 0) - { - if ($bWithNavigationContext) - { - return $sUrl."&".$oAppContext->GetForLink(); - } - else - { - return $sUrl; - } - } - else - { - return ''; - } + if (utils::StrLen($sUrl) > 0) { + if ($bWithNavigationContext) { + return $sUrl."&".$oAppContext->GetForLink(); + } else { + return $sUrl; + } + } else { + return ''; + } } /** diff --git a/application/applicationextension.inc.php b/application/applicationextension.inc.php index 5b658d3ee..f877239ce 100644 --- a/application/applicationextension.inc.php +++ b/application/applicationextension.inc.php @@ -30,9 +30,9 @@ require_once(APPROOT.'application/newsroomprovider.class.inc.php'); * You may implement such interfaces in a module file (e.g. main.mymodule.php) * * @api + * @package LoginExtensibilityAPI * @copyright Copyright (C) 2010-2021 Combodo SARL * @license http://opensource.org/licenses/AGPL-3.0 - * @package Extensibility * @since 2.7.0 */ interface iLoginExtension @@ -40,12 +40,16 @@ interface iLoginExtension /** * Return the list of supported login modes for this plugin * + * @api + * * @return array of supported login modes */ public function ListSupportedLoginModes(); } /** + * @api + * @package LoginExtensibilityAPI * @since 2.7.0 */ interface iLoginFSMExtension extends iLoginExtension @@ -57,6 +61,7 @@ interface iLoginFSMExtension extends iLoginExtension * if LoginWebPage::LOGIN_FSM_RETURN_OK is returned then the login is OK and terminated * if LoginWebPage::LOGIN_FSM_RETURN_IGNORE is returned then the FSM will proceed to next plugin or state * + * @api * @param string $sLoginState (see LoginWebPage::LOGIN_STATE_...) * @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...) * @@ -66,6 +71,8 @@ interface iLoginFSMExtension extends iLoginExtension } /** + * @api + * @package LoginExtensibilityAPI * @since 2.7.0 */ abstract class AbstractLoginFSMExtension implements iLoginFSMExtension @@ -112,6 +119,7 @@ abstract class AbstractLoginFSMExtension implements iLoginFSMExtension /** * Initialization * + * @api * @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...) * * @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_RETURN_IGNORE @@ -125,6 +133,7 @@ abstract class AbstractLoginFSMExtension implements iLoginFSMExtension * Detect login mode explicitly without respecting configured order (legacy mode) * In most case do nothing here * + * @api * @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...) * * @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_RETURN_IGNORE @@ -141,6 +150,7 @@ abstract class AbstractLoginFSMExtension implements iLoginFSMExtension * 1 - display login form * 2 - read the values posted by the user * + * @api * @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...) * * @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_RETURN_IGNORE @@ -154,6 +164,7 @@ abstract class AbstractLoginFSMExtension implements iLoginFSMExtension * Control the validity of the data provided by the user * Automatic user provisioning can be done here * + * @api * @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...) * * @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_RETURN_IGNORE @@ -164,6 +175,7 @@ abstract class AbstractLoginFSMExtension implements iLoginFSMExtension } /** + * @api * @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...) * * @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_RETURN_IGNORE @@ -174,6 +186,7 @@ abstract class AbstractLoginFSMExtension implements iLoginFSMExtension } /** + * @api * @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...) * * @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_RETURN_IGNORE @@ -184,6 +197,7 @@ abstract class AbstractLoginFSMExtension implements iLoginFSMExtension } /** + * @api * @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...) * * @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_RETURN_IGNORE @@ -194,6 +208,7 @@ abstract class AbstractLoginFSMExtension implements iLoginFSMExtension } /** + * @api * @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...) * * @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_RETURN_IGNORE @@ -205,22 +220,28 @@ abstract class AbstractLoginFSMExtension implements iLoginFSMExtension } /** + * @api + * @package LoginExtensibilityAPI * @since 2.7.0 */ interface iLogoutExtension extends iLoginExtension { /** * Execute all actions to log out properly + * @api */ public function LogoutAction(); } /** + * @api + * @package UIExtensibilityAPI * @since 2.7.0 */ interface iLoginUIExtension extends iLoginExtension { /** + * @api * @return LoginTwigContext */ public function GetTwigContext(); @@ -228,18 +249,20 @@ interface iLoginUIExtension extends iLoginExtension /** * @api - * @package Extensibility + * @package PreferencesExtensibilityAPI * @since 2.7.0 */ interface iPreferencesExtension { /** + * @api * @param \WebPage $oPage * */ public function DisplayPreferences(WebPage $oPage); /** + * @api * @param \WebPage $oPage * @param string $sOperation * @@ -252,7 +275,7 @@ interface iPreferencesExtension * Extend this class instead of implementing iPreferencesExtension if you don't need to overload all methods * * @api - * @package Extensibility + * @package PreferencesExtensibilityAPI * @since 2.7.0 */ abstract class AbstractPreferencesExtension implements iPreferencesExtension @@ -298,7 +321,7 @@ abstract class AbstractPreferencesExtension implements iPreferencesExtension * A recommended pattern is to cache data by the mean of static members. * * @api - * @package Extensibility + * @package UIExtensibilityAPI */ interface iApplicationUIExtension { @@ -320,6 +343,7 @@ interface iApplicationUIExtension * } * * + * @api * @param DBObject $oObject The object being displayed * @param WebPage $oPage The output context * @param boolean $bEditMode True if the edition form is being displayed @@ -333,6 +357,7 @@ interface iApplicationUIExtension * * The method is called rigth after all the tabs have been displayed * + * @api * @param DBObject $oObject The object being displayed * @param WebPage $oPage The output context * @param boolean $bEditMode True if the edition form is being displayed @@ -347,6 +372,7 @@ interface iApplicationUIExtension * The method is called after the changes from the standard form have been * taken into account, and before saving the changes into the database. * + * @api * @param DBObject $oObject The object being edited * @param string $sFormPrefix Prefix given to the HTML form inputs * @@ -361,6 +387,7 @@ interface iApplicationUIExtension * javascript into the edition form, and if that code requires to store temporary data * (this is the case when a file must be uploaded). * + * @api * @param string $sTempId Unique temporary identifier made of session_id and transaction_id. It identifies the object in a unique way. * * @return void @@ -372,6 +399,7 @@ interface iApplicationUIExtension * * Sorry, the verb has been reserved. You must implement it, but it is not called as of now. * + * @api * @param DBObject $oObject The object being displayed * * @return string[] desc @@ -383,6 +411,7 @@ interface iApplicationUIExtension * * Sorry, the verb has been reserved. You must implement it, but it is not called as of now. * + * @api * @param DBObject $oObject The object being displayed * * @return string Path of the icon, relative to the modules directory. @@ -402,6 +431,7 @@ interface iApplicationUIExtension * * HILIGHT_CLASS_OK * * HILIGHT_CLASS_NONE * + * @api * @param DBObject $oObject The object being displayed * * @return integer The value representing the mood of the object @@ -428,6 +458,7 @@ interface iApplicationUIExtension * * See also iPopupMenuExtension for greater flexibility * + * @api * @param DBObjectSet $oSet A set of persistent objects (DBObject) * * @return array @@ -439,7 +470,7 @@ interface iApplicationUIExtension * Extend this class instead of implementing iApplicationUIExtension if you don't need to overload * * @api - * @package Extensibility + * @package UIExtensibilityAPI * @since 2.7.0 */ abstract class AbstractApplicationUIExtension implements iApplicationUIExtension @@ -513,7 +544,7 @@ abstract class AbstractApplicationUIExtension implements iApplicationUIExtension * or through the GUI. * * @api - * @package Extensibility + * @package ORMExtensibilityAPI */ interface iApplicationObjectExtension { @@ -526,6 +557,7 @@ interface iApplicationObjectExtension * If the extension returns false, then the framework will perform the usual evaluation. * Otherwise, the answer is definitively "yes, the object has changed". * + * @api * @param \cmdbAbstractObject $oObject The target object * * @return boolean True if something has changed for the target object @@ -538,6 +570,7 @@ interface iApplicationObjectExtension * The GUI calls this verb and reports any issue. * Anyhow, this API can be called in other contexts such as the CSV import tool. * + * @api * @param \cmdbAbstractObject $oObject The target object * * @return string[] A list of errors message. An error message is made of one line and it can be displayed to the end-user. @@ -551,6 +584,7 @@ interface iApplicationObjectExtension * * Please not that it is not possible to cascade deletion by this mean: only stopper issues can be handled. * + * @api * @param \cmdbAbstractObject $oObject The target object * * @return string[] A list of errors message. An error message is made of one line and it can be displayed to the end-user. @@ -566,6 +600,7 @@ interface iApplicationObjectExtension * * {@see DBObject::ListPreviousValuesForUpdatedAttributes()} : list of changed attributes and their values before the change * * {@see DBObject::Get()} : for a given attribute the new value that was persisted * + * @api * @param \cmdbAbstractObject $oObject The target object * @param CMDBChange|null $oChange A change context. Since 2.0 it is fine to ignore it, as the framework does maintain this information * once for all the changes made within the current page @@ -581,6 +616,7 @@ interface iApplicationObjectExtension * * The method is called right after the object has been written to the database. * + * @api * @param \cmdbAbstractObject $oObject The target object * @param CMDBChange|null $oChange A change context. Since 2.0 it is fine to ignore it, as the framework does maintain this information * once for all the changes made within the current page @@ -594,6 +630,7 @@ interface iApplicationObjectExtension * * The method is called right before the object will be deleted from the database. * + * @api * @param \cmdbAbstractObject $oObject The target object * @param CMDBChange|null $oChange A change context. Since 2.0 it is fine to ignore it, as the framework does maintain this information * once for all the changes made within the current page @@ -607,7 +644,7 @@ interface iApplicationObjectExtension * Extend this class instead of iApplicationObjectExtension if you don't need to overload all methods * * @api - * @package Extensibility + * @package ORMExtensibilityAPI * @since 2.7.0 */ abstract class AbstractApplicationObjectExtension implements iApplicationObjectExtension @@ -667,7 +704,7 @@ abstract class AbstractApplicationObjectExtension implements iApplicationObjectE * by the application, as long as the class definition is included somewhere in the code * * @api - * @package Extensibility + * @package UIExtensibilityAPI * @since 2.0 */ interface iPopupMenuExtension @@ -676,18 +713,21 @@ interface iPopupMenuExtension * Insert an item into the Actions menu of a list * * $param is a DBObjectSet containing the list of objects + * @api */ const MENU_OBJLIST_ACTIONS = 1; /** * Insert an item into the Toolkit menu of a list * * $param is a DBObjectSet containing the list of objects + * @api */ const MENU_OBJLIST_TOOLKIT = 2; /** * Insert an item into the Actions menu on an object details page * * $param is a DBObject instance: the object currently displayed + * @api */ const MENU_OBJDETAILS_ACTIONS = 3; /** @@ -697,12 +737,14 @@ interface iPopupMenuExtension * is being displayed. * * $param is a Dashboard instance: the dashboard currently displayed + * @api */ const MENU_DASHBOARD_ACTIONS = 4; /** * Insert an item into the User menu (upper right corner) * * $param is null + * @api */ const MENU_USER_ACTIONS = 5; /** @@ -710,6 +752,7 @@ interface iPopupMenuExtension * * $param is an array('portal_id' => $sPortalId, 'object' => $oObject) containing the portal id and a DBObject instance (the object on * the current line) + * @api */ const PORTAL_OBJLISTITEM_ACTIONS = 7; /** @@ -717,6 +760,7 @@ interface iPopupMenuExtension * * $param is an array('portal_id' => $sPortalId, 'object' => $oObject) containing the portal id and a DBObject instance (the object * currently displayed) + * @api */ const PORTAL_OBJDETAILS_ACTIONS = 8; @@ -754,6 +798,7 @@ interface iPopupMenuExtension * This method is called by the framework for each menu. * The items will be inserted in the menu in the order of the returned array. * + * @api * @param int $iMenuId The identifier of the type of menu, as listed by the constants MENU_xxx * @param mixed $param Depends on $iMenuId, see the constants defined above * @@ -766,7 +811,7 @@ interface iPopupMenuExtension * Base class for the various types of custom menus * * @api - * @package Extensibility + * @package UIExtensibilityAPI * @since 2.0 */ abstract class ApplicationPopupMenuItem @@ -776,7 +821,7 @@ abstract class ApplicationPopupMenuItem /** @ignore */ protected $sLabel; /** @ignore */ - protected $sTooltip; + protected $sTooltip; /** @ignore */ protected $sIconClass; /** @ignore */ @@ -833,6 +878,7 @@ abstract class ApplicationPopupMenuItem } /** + * @api * @param $aCssClasses */ public function SetCssClasses($aCssClasses) @@ -843,6 +889,7 @@ abstract class ApplicationPopupMenuItem /** * Adds a CSS class to the CSS classes that will be put on the menu item * + * @api * @param $sCssClass */ public function AddCssClass($sCssClass) @@ -853,7 +900,7 @@ abstract class ApplicationPopupMenuItem /** * @param $sTooltip - * + * * @since 3.0.0 */ public function SetTooltip($sTooltip) @@ -863,24 +910,24 @@ abstract class ApplicationPopupMenuItem /** * @return string - * + * * @since 3.0.0 */ public function GetTooltip() { return $this->sTooltip; } - + /** * @param $sIconClass - * + * * @since 3.0.0 */ public function SetIconClass($sIconClass) { $this->sIconClass = $sIconClass; - } - + } + /** * @return string * @@ -890,7 +937,7 @@ abstract class ApplicationPopupMenuItem { return $this->sIconClass; } - + /** * Returns the components to create a popup menu item in HTML * @@ -912,7 +959,7 @@ abstract class ApplicationPopupMenuItem * Note: This works only in the backoffice, {@see \URLButtonItem} for the end-user portal * * @api - * @package Extensibility + * @package UIExtensibilityAPI * @since 2.0 */ class URLPopupMenuItem extends ApplicationPopupMenuItem @@ -925,6 +972,7 @@ class URLPopupMenuItem extends ApplicationPopupMenuItem /** * Constructor * + * @api * @param string $sUID The unique identifier of this menu in iTop... make sure you pass something unique enough * @param string $sLabel The display label of the menu (must be localized) * @param string $sUrl If the menu is an hyperlink, provide the absolute hyperlink here @@ -948,7 +996,7 @@ class URLPopupMenuItem extends ApplicationPopupMenuItem 'tooltip' => $this->sTooltip ); } - + /** @ignore */ public function GetUrl() { @@ -968,7 +1016,7 @@ class URLPopupMenuItem extends ApplicationPopupMenuItem * Note: This works only in the backoffice, {@see \JSButtonItem} for the end-user portal * * @api - * @package Extensibility + * @package UIExtensibilityAPI * @since 2.0 */ class JSPopupMenuItem extends ApplicationPopupMenuItem @@ -1018,13 +1066,13 @@ class JSPopupMenuItem extends ApplicationPopupMenuItem { return $this->aIncludeJSFiles; } - + /** @ignore */ public function GetJsCode() { return $this->sJsCode; } - + /** @ignore */ public function GetUrl() { @@ -1037,7 +1085,7 @@ class JSPopupMenuItem extends ApplicationPopupMenuItem * will automatically reduce several consecutive separators to just one * * @api - * @package Extensibility + * @package UIExtensibilityAPI * @since 2.0 */ class SeparatorPopupMenuItem extends ApplicationPopupMenuItem @@ -1046,6 +1094,7 @@ class SeparatorPopupMenuItem extends ApplicationPopupMenuItem /** * Constructor + * @api */ public function __construct() { @@ -1063,7 +1112,7 @@ class SeparatorPopupMenuItem extends ApplicationPopupMenuItem * Class for adding an item as a button that browses to the given URL * * @api - * @package Extensibility + * @package UIExtensibilityAPI * @since 2.0 */ class URLButtonItem extends URLPopupMenuItem @@ -1075,7 +1124,7 @@ class URLButtonItem extends URLPopupMenuItem * Class for adding an item as a button that runs some JS code * * @api - * @package Extensibility + * @package UIExtensibilityAPI * @since 2.0 */ class JSButtonItem extends JSPopupMenuItem @@ -1099,7 +1148,7 @@ class JSButtonItem extends JSPopupMenuItem * the specified place and can use the passed iTopWebPage object to add javascript or CSS definitions * * @api - * @package Extensibility + * @package UIExtensibilityAPI * @since 2.0 * @deprecated 3.0.0 If you need to include: * * JS/CSS files/snippets, use {@see \iBackofficeLinkedScriptsExtension}, {@see \iBackofficeLinkedStylesheetsExtension}, etc instead @@ -1110,6 +1159,7 @@ interface iPageUIExtension /** * Add content to the header of the page * + * @api * @param iTopWebPage $oPage The page to insert stuff into. * * @return string The HTML content to add into the page @@ -1119,6 +1169,7 @@ interface iPageUIExtension /** * Add content to the footer of the page * + * @api * @param iTopWebPage $oPage The page to insert stuff into. * * @return string The HTML content to add into the page @@ -1128,6 +1179,7 @@ interface iPageUIExtension /** * Add content to the "admin banner" * + * @api * @param iTopWebPage $oPage The page to insert stuff into. * * @return string The HTML content to add into the page @@ -1151,7 +1203,7 @@ interface iPageUIExtension * the specified place and can use the passed iTopWebPage object to add javascript or CSS definitions * * @api - * @package Extensibility + * @package UIBlockExtensibilityAPI * @since 3.0.0 */ interface iPageUIBlockExtension @@ -1182,7 +1234,7 @@ interface iPageUIBlockExtension * Extend this class instead of iPageUIExtension if you don't need to overload all methods * * @api - * @package Extensibility + * @package UIExtensibilityAPI * @since 2.7.0 * @deprecated since 3.0.0 use AbstractPageUIBlockExtension instead */ @@ -1224,7 +1276,7 @@ abstract class AbstractPageUIExtension implements iPageUIExtension * Extend this class instead of iPageUIExtension if you don't need to overload all methods * * @api - * @package Extensibility + * @package UIBlockExtensibilityAPI * @since 3.0.0 */ abstract class AbstractPageUIBlockExtension implements iPageUIBlockExtension @@ -1259,6 +1311,7 @@ abstract class AbstractPageUIBlockExtension implements iPageUIBlockExtension * * @see \iTopWebPage::$a_linked_scripts * @api + * @package BackofficeUIExtensibilityAPI * @since 3.0.0 */ interface iBackofficeLinkedScriptsExtension @@ -1276,6 +1329,7 @@ interface iBackofficeLinkedScriptsExtension * * @see \iTopWebPage::$a_early_scripts * @api + * @package BackofficeUIExtensibilityAPI * @since 3.0.0 */ interface iBackofficeEarlyScriptExtension @@ -1292,6 +1346,7 @@ interface iBackofficeEarlyScriptExtension * * @see \iTopWebPage::$a_scripts * @api + * @package BackofficeUIExtensibilityAPI * @since 3.0.0 */ interface iBackofficeScriptExtension @@ -1308,6 +1363,7 @@ interface iBackofficeScriptExtension * * @see \iTopWebPage::$a_init_scripts * @api + * @package BackofficeUIExtensibilityAPI * @since 3.0.0 */ interface iBackofficeInitScriptExtension @@ -1324,6 +1380,7 @@ interface iBackofficeInitScriptExtension * * @see \iTopWebPage::$a_ready_scripts * @api + * @package BackofficeUIExtensibilityAPI * @since 3.0.0 */ interface iBackofficeReadyScriptExtension @@ -1340,6 +1397,7 @@ interface iBackofficeReadyScriptExtension * * @see \iTopWebPage::$a_linked_stylesheets * @api + * @package BackofficeUIExtensibilityAPI * @since 3.0.0 */ interface iBackofficeLinkedStylesheetsExtension @@ -1356,6 +1414,7 @@ interface iBackofficeLinkedStylesheetsExtension * * @see \iTopWebPage::$a_styles * @api + * @package BackofficeUIExtensibilityAPI * @since 3.0.0 */ interface iBackofficeStyleExtension @@ -1372,6 +1431,7 @@ interface iBackofficeStyleExtension * * @see \iTopWebPage::$a_dict_entries * @api + * @package BackofficeUIExtensibilityAPI * @since 3.0.0 */ interface iBackofficeDictEntriesExtension @@ -1388,6 +1448,7 @@ interface iBackofficeDictEntriesExtension * * @see \iTopWebPage::$a_dict_entries_prefixes * @api + * @package BackofficeUIExtensibilityAPI * @since 3.0.0 */ interface iBackofficeDictEntriesPrefixesExtension @@ -1403,7 +1464,7 @@ interface iBackofficeDictEntriesPrefixesExtension * Implement this interface to add content to any enhanced portal page * * @api - * @package Extensibility + * @package PortalExtensibilityAPI * * @since 2.4.0 interface creation * @since 2.7.0 change method signatures due to Silex to Symfony migration @@ -1417,6 +1478,7 @@ interface iPortalUIExtension /** * Returns an array of CSS file urls * + * @api * @param \Symfony\Component\DependencyInjection\Container $oContainer * * @return array @@ -1426,6 +1488,7 @@ interface iPortalUIExtension /** * Returns inline (raw) CSS * + * @api * @param \Symfony\Component\DependencyInjection\Container $oContainer * * @return string @@ -1435,6 +1498,7 @@ interface iPortalUIExtension /** * Returns an array of JS file urls * + * @api * @param \Symfony\Component\DependencyInjection\Container $oContainer * * @return array @@ -1444,6 +1508,7 @@ interface iPortalUIExtension /** * Returns raw JS code * + * @api * @param \Symfony\Component\DependencyInjection\Container $oContainer * * @return string @@ -1453,6 +1518,7 @@ interface iPortalUIExtension /** * Returns raw HTML code to put at the end of the tag * + * @api * @param \Symfony\Component\DependencyInjection\Container $oContainer * * @return string @@ -1462,6 +1528,7 @@ interface iPortalUIExtension /** * Returns raw HTML code to put at the end of the #main-wrapper element * + * @api * @param \Symfony\Component\DependencyInjection\Container $oContainer * * @return string @@ -1471,6 +1538,7 @@ interface iPortalUIExtension /** * Returns raw HTML code to put at the end of the #topbar and #sidebar elements * + * @api * @param \Symfony\Component\DependencyInjection\Container $oContainer * * @return string @@ -1482,7 +1550,7 @@ interface iPortalUIExtension * Extend this class instead of iPortalUIExtension if you don't need to overload all methods * * @api - * @package Extensibility + * @package PortalExtensibilityAPI * @since 2.4.0 */ abstract class AbstractPortalUIExtension implements iPortalUIExtension @@ -1548,7 +1616,7 @@ abstract class AbstractPortalUIExtension implements iPortalUIExtension * Implement this interface to add new operations to the REST/JSON web service * * @api - * @package Extensibility + * @package RESTExtensibilityAPI * @since 2.0.1 */ interface iRestServiceProvider @@ -1556,6 +1624,7 @@ interface iRestServiceProvider /** * Enumerate services delivered by this class * + * @api * @param string $sVersion The version (e.g. 1.0) supported by the services * * @return array An array of hash 'verb' => verb, 'description' => description @@ -1565,6 +1634,7 @@ interface iRestServiceProvider /** * Enumerate services delivered by this class * + * @api * @param string $sVersion The version (e.g. 1.0) supported by the services * @param string $sVerb * @param array $aParams @@ -1578,69 +1648,90 @@ interface iRestServiceProvider * Minimal REST response structure. Derive this structure to add response data and error codes. * * @api - * @package Extensibility + * @package RESTExtensibilityAPI * @since 2.0.1 */ class RestResult { /** * Result: no issue has been encountered + * @api */ const OK = 0; /** * Result: missing/wrong credentials or the user does not have enough rights to perform the requested operation + * @api */ const UNAUTHORIZED = 1; /** * Result: the parameter 'version' is missing + * @api */ const MISSING_VERSION = 2; /** * Result: the parameter 'json_data' is missing + * @api */ const MISSING_JSON = 3; /** * Result: the input structure is not a valid JSON string + * @api */ const INVALID_JSON = 4; /** * Result: the parameter 'auth_user' is missing, authentication aborted + * @api */ const MISSING_AUTH_USER = 5; /** * Result: the parameter 'auth_pwd' is missing, authentication aborted + * @api */ const MISSING_AUTH_PWD = 6; /** * Result: no operation is available for the specified version + * @api */ const UNSUPPORTED_VERSION = 10; /** * Result: the requested operation is not valid for the specified version + * @api */ const UNKNOWN_OPERATION = 11; /** * Result: the requested operation cannot be performed because it can cause data (integrity) loss + * @api */ const UNSAFE = 12; /** * Result: the request page number is not valid. It must be an integer greater than 0 + * @api */ const INVALID_PAGE = 13; /** * Result: the operation could not be performed, see the message for troubleshooting + * @api */ const INTERNAL_ERROR = 100; /** * Default constructor - ok! + * @api */ public function __construct() { $this->code = RestResult::OK; } + /** + * @var int + * @api + */ public $code; + /** + * @var string + * @api + */ public $message; } @@ -1648,7 +1739,7 @@ class RestResult * Helpers for implementing REST services * * @api - * @package Extensibility + * @package RESTExtensibilityAPI */ class RestUtils { @@ -1797,6 +1888,7 @@ class RestUtils /** * Read and interpret object search criteria from a Rest/Json structure * + * @api * @param string $sClass Name of the class * @param StdClass $oCriteria Hash of attribute code => value (can be a substructure or a scalar, depending on the nature of the * attriute) @@ -1906,6 +1998,7 @@ class RestUtils /** * Search objects from a polymorph search specification (Rest/Json) * + * @api * @param string $sClass Name of the class * @param mixed $key Either search criteria (substructure), or an object or an OQL string. * @param int $iLimit The limit of results to return diff --git a/application/cmdbabstract.class.inc.php b/application/cmdbabstract.class.inc.php index 7adaaa934..f1d0154c5 100644 --- a/application/cmdbabstract.class.inc.php +++ b/application/cmdbabstract.class.inc.php @@ -3054,7 +3054,16 @@ EOF // Hook the cancel button via jQuery so that it can be unhooked easily as well if needed $sDefaultUrl = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=search_form&class='.$sClass.'&'.$oAppContext->GetForLink(); - $oPage->add_ready_script("$('#form_{$this->m_iFormId} button.cancel').on('click', function() { BackToDetails('$sClass', $iKey, '$sDefaultUrl', $sJSToken)} );"); + + $sCancelButtonOnClickScript = "let fOnClick{$this->m_iFormId}CancelButton = "; + if(isset($aExtraParams['js_handlers']['cancel_button_on_click'])){ + $sCancelButtonOnClickScript .= $aExtraParams['js_handlers']['cancel_button_on_click']; + } else { + $sCancelButtonOnClickScript .= "function() { BackToDetails('$sClass', $iKey, '$sDefaultUrl', $sJSToken)};"; + } + $sCancelButtonOnClickScript .= "$('#form_{$this->m_iFormId} button.cancel').on('click', fOnClick{$this->m_iFormId}CancelButton);"; + $oPage->add_ready_script($sCancelButtonOnClickScript); + $iFieldsCount = count($aFieldsMap); $sJsonFieldsMap = json_encode($aFieldsMap); @@ -3374,13 +3383,14 @@ EOF // Consider only the "expected" fields for the target state if (array_key_exists($sAttCode, $aExpectedAttributes)) { $iExpectCode = $aExpectedAttributes[$sAttCode]; + // Prompt for an attribute if // - the attribute must be changed or must be displayed to the user for confirmation // - or the field is mandatory and currently empty if (($iExpectCode & (OPT_ATT_MUSTCHANGE | OPT_ATT_MUSTPROMPT)) || - (($iExpectCode & OPT_ATT_MANDATORY) && ($this->Get($sAttCode) == ''))) { - $oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode); + (($iExpectCode & OPT_ATT_MANDATORY) && (false === $this->HasAValue($sAttCode)))) { $aArgs = array('this' => $this); + $oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode); // If the field is mandatory, set it to the only possible value if ((!$oAttDef->IsNullAllowed()) || ($iExpectCode & OPT_ATT_MANDATORY)) { if ($oAttDef->IsExternalKey()) { @@ -3409,32 +3419,35 @@ EOF } } } + $sInputType = ''; + $sInputId = 'att_'.$iFieldIndex; $sHTMLValue = cmdbAbstractObject::GetFormElementForField($oPage, $sClass, $sAttCode, $oAttDef, - $this->Get($sAttCode), $this->GetEditValue($sAttCode), 'att_'.$iFieldIndex, '', $iExpectCode, - $aArgs); - $aAttrib = array( + $this->Get($sAttCode), $this->GetEditValue($sAttCode), $sInputId, '', $iExpectCode, + $aArgs, true, $sInputType); + $aAttrib = array( 'label' => ''.$oAttDef->GetLabel().'', 'value' => "$sHTMLValue", ); //add attrib for data-attribute // Prepare metadata attributes - $sAttCode = $oAttDef->GetCode(); - $oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode); + $sAttCode = $oAttDef->GetCode(); + $oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode); $sAttDefClass = get_class($oAttDef); - $sAttLabel = MetaModel::GetLabel($sClass, $sAttCode); + $sAttLabel = MetaModel::GetLabel($sClass, $sAttCode); - $aAttrib['attcode'] = $sAttCode; - $aAttrib['atttype'] = $sAttDefClass; + $aAttrib['attcode'] = $sAttCode; + $aAttrib['atttype'] = $sAttDefClass; $aAttrib['attlabel'] = $sAttLabel; // - Attribute flags - $aAttrib['attflags'] = $this->GetFormAttributeFlags($sAttCode) ; + $aAttrib['attflags'] = $this->GetFormAttributeFlags($sAttCode); // - How the field should be rendered - $aAttrib['layout'] = (in_array($oAttDef->GetEditClass(), static::GetAttEditClassesToRenderAsLargeField())) ? 'large' : 'small'; + $aAttrib['layout'] = (in_array($oAttDef->GetEditClass(), static::GetAttEditClassesToRenderAsLargeField())) ? 'large' : 'small'; + $aAttrib['inputid'] = $sInputId; + $aAttrib['inputtype'] = $sInputType; // - For simple fields, we get the raw (stored) value as well $bExcludeRawValue = false; - foreach (static::GetAttDefClassesToExcludeFromMarkupMetadataRawValue() as $sAttDefClassToExclude) - { + foreach (static::GetAttDefClassesToExcludeFromMarkupMetadataRawValue() as $sAttDefClassToExclude) { if (is_a($sAttDefClass, $sAttDefClassToExclude, true)) { $bExcludeRawValue = true; break; @@ -3442,8 +3455,8 @@ EOF } $aAttrib['value_raw'] = ($bExcludeRawValue === false) ? $this->Get($sAttCode) : ''; - $aDetails[] = $aAttrib; - $aFieldsMap[$sAttCode] = 'att_'.$iFieldIndex; + $aDetails[] = $aAttrib; + $aFieldsMap[$sAttCode] = $sInputId; $iFieldIndex++; $bExistFieldToDisplay = true; } @@ -3667,7 +3680,7 @@ HTML; $sDisplayLabel = Dict::S('UI:OpenDocumentInNewWindow_'); $sDisplayUrl = $oDocument->GetDisplayURL(get_class($this), $this->GetKey(), $sAttCode); - $sDownloadLabel = Dict::Format('UI:DownloadDocument_'); + $sDownloadLabel = Dict::S('UI:DownloadDocument_'); $sDownloadUrl = $oDocument->GetDownloadURL(get_class($this), $this->GetKey(), $sAttCode); $sDisplayValue = <<sDefinitionFile; } + /** + * @param string $sDashboardFileRelative can also be an absolute path (compatibility with old URL) + * + * @return string full path to the Dashboard file + * @throws \SecurityException if path isn't under approot + * @uses utils::RealPath() + * @since 2.7.8 3.0.3 3.1.0 N°4449 remove FPD + */ + public static function GetDashboardFileFromRelativePath($sDashboardFileRelative) + { + if (utils::RealPath($sDashboardFileRelative, APPROOT)) { + // compatibility with old URL containing absolute path ! + return $sDashboardFileRelative; + } + + $sDashboardFile = APPROOT.$sDashboardFileRelative; + if (false === utils::RealPath($sDashboardFile, APPROOT)) { + throw new SecurityException('Invalid dashboard file !'); + } + + return $sDashboardFile; + } + /** * @param string $sDefinitionFile */ diff --git a/application/datatable.class.inc.php b/application/datatable.class.inc.php index 4e4ce06b4..31c84b857 100644 --- a/application/datatable.class.inc.php +++ b/application/datatable.class.inc.php @@ -386,7 +386,7 @@ EOF; if (!$oPage->IsPrintableVersion()) { $sMenuTitle = Dict::S('UI:ConfigureThisList'); - $sHtml = '