Sfoglia il codice sorgente

- Added support for pattern-based field validation (anticipating HTML5 ?).

git-svn-id: http://svn.code.sf.net/p/itop/code/trunk@411 a333f486-631f-4898-b8df-5754b55c2be0
dflaven 15 anni fa
parent
commit
a5b70a7ad5

+ 7 - 7
business/ChangeMgmt.business.php

@@ -39,12 +39,12 @@ class bizChangeTicket extends cmdbAbstractObject
 		MetaModel::Init_AddAttribute(new AttributeEnum("ticket_status", array("allowed_values"=>new ValueSetEnum("New, Validated,Rejected,Assigned,PlannedScheduled,Approved,NotApproved,Implemented,Monitored, Closed"), "sql"=>"change_status", "default_value"=>"New", "is_null_allowed"=>false, "depends_on"=>array())));
 		// SetPossibleValues("status",array("Open","Monitored","Closed"));
 
-		MetaModel::Init_AddAttribute(new AttributeDate("creation_date", array("allowed_values"=>null, "sql"=>"creation_date", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
-    	// définir une date de défaut à maintenant, alias creation ou modification du ticket
-		MetaModel::Init_AddAttribute(new AttributeDate("last_update", array("allowed_values"=>null, "sql"=>"last_update", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
-	  MetaModel::Init_AddAttribute(new AttributeDate("start_date", array("allowed_values"=>null, "sql"=>"start_date", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
-		MetaModel::Init_AddAttribute(new AttributeDate("end_date", array("allowed_values"=>null, "sql"=>"end_date", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
-		MetaModel::Init_AddAttribute(new AttributeDate("close_date", array("allowed_values"=>null, "sql"=>"closed_date", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
+		MetaModel::Init_AddAttribute(new AttributeDateTIme("creation_date", array("allowed_values"=>null, "sql"=>"creation_date", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
+    	// d�finir une date de d�faut � maintenant, alias creation ou modification du ticket
+		MetaModel::Init_AddAttribute(new AttributeDateTime("last_update", array("allowed_values"=>null, "sql"=>"last_update", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
+	  MetaModel::Init_AddAttribute(new AttributeDateTime("start_date", array("allowed_values"=>null, "sql"=>"start_date", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
+		MetaModel::Init_AddAttribute(new AttributeDateTime("end_date", array("allowed_values"=>null, "sql"=>"end_date", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
+		MetaModel::Init_AddAttribute(new AttributeDateTime("close_date", array("allowed_values"=>null, "sql"=>"closed_date", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
 	  MetaModel::Init_AddAttribute(new AttributeString("impact", array("allowed_values"=>null, "sql"=>"impact", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
     MetaModel::Init_AddAttribute(new AttributeExternalKey("workgroup_id", array("targetclass"=>"bizWorkgroup", "jointype"=> "", "allowed_values"=>null, "sql"=>"workgroup_id", "is_null_allowed"=>true, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array())));
 		MetaModel::Init_AddAttribute(new AttributeExternalField("workgroup_name", array("allowed_values"=>null, "extkey_attcode"=> 'workgroup_id', "target_attcode"=>"name")));  
@@ -70,7 +70,7 @@ class bizChangeTicket extends cmdbAbstractObject
 		
 		MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("impacted_infra_manual", array("linked_class"=>"lnkInfraChangeTicket", "ext_key_to_me"=>"ticket_id", "ext_key_to_remote"=>"infra_id", "allowed_values"=>null, "count_min"=>1, "count_max"=>0, "depends_on"=>array())));
 
-		// doit-on aussi ajouter un filtre sur les extfields lié à une extkey ? ici le name de l'agent?
+		// doit-on aussi ajouter un filtre sur les extfields li� � une extkey ? ici le name de l'agent?
 		
 		// Display lists
 		MetaModel::Init_SetZListItems('details', array('name','title', 'org_id','type','domain','requestor_id','change_request','ticket_status', 'outage','impact', 'last_update', 'start_date','end_date', 'assignment_count', 'workgroup_id','agent_id','supervisorgroup_id','supervisor_id','managergroup_id','manager_id','change_log','fallback')); // Attributes to be displayed for a list

+ 3 - 2
business/KEDB.business.php

@@ -95,7 +95,8 @@ class lnkInfraError extends cmdbAbstractObject
 
 	
 }
-
+if (false)
+{
 ////////////////////////////////////////////////////////////////////////////////////
 /**
 * n-n link between any Contract and a Document
@@ -130,6 +131,6 @@ class lnkDocumentError extends cmdbAbstractObject
 		MetaModel::Init_SetZListItems('list', array('doc_id', 'error_name', 'link_type')); // Attributes to be displayed for a list
 	}
 }
-
+}
 
 ?>

+ 5 - 5
business/ServiceDesk.business.php

@@ -46,12 +46,12 @@ class bizServiceCall extends cmdbAbstractObject
 		MetaModel::Init_AddAttribute(new AttributeEnum("call_status", array("allowed_values"=>new ValueSetEnum("New, Assigned, WorkInProgress,Resolved,Closed"), "sql"=>"call_status", "default_value"=>"New", "is_null_allowed"=>false, "depends_on"=>array())));
 		// SetPossibleValues("status",array("Open","Monitored","Closed"));
 		MetaModel::Init_AddAttribute(new AttributeText("call_description", array("allowed_values"=>null, "sql"=>"call_description", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
-		MetaModel::Init_AddAttribute(new AttributeDate("creation_date", array("allowed_values"=>null, "sql"=>"creation_date", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
-		// définir une date de défaut à maintenant, alias creation ou modification du ticket
-		MetaModel::Init_AddAttribute(new AttributeDate("last_update", array("allowed_values"=>null, "sql"=>"last_update", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
-		MetaModel::Init_AddAttribute(new AttributeDate("next_update", array("allowed_values"=>null, "sql"=>"next_update", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
+		MetaModel::Init_AddAttribute(new AttributeDateTime("creation_date", array("allowed_values"=>null, "sql"=>"creation_date", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
+		// d�finir une date de d�faut � maintenant, alias creation ou modification du ticket
+		MetaModel::Init_AddAttribute(new AttributeDateTime("last_update", array("allowed_values"=>null, "sql"=>"last_update", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
+		MetaModel::Init_AddAttribute(new AttributeDateTime("next_update", array("allowed_values"=>null, "sql"=>"next_update", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
 		
-		MetaModel::Init_AddAttribute(new AttributeDate("end_date", array("allowed_values"=>null, "sql"=>"closed_date", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
+		MetaModel::Init_AddAttribute(new AttributeDateTime("end_date", array("allowed_values"=>null, "sql"=>"closed_date", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
 		MetaModel::Init_AddAttribute(new AttributeExternalKey("caller_id", array("targetclass"=>"bizPerson", "jointype"=> "", "allowed_values"=>new ValueSetObjects('SELECT bizPerson AS p WHERE p.org_id = :this->org_id'), "sql"=>"caller_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array('org_id'))));
 		MetaModel::Init_AddAttribute(new AttributeExternalField("caller_mail", array("allowed_values"=>null, "extkey_attcode"=> 'caller_id', "target_attcode"=>"email")));
 		

+ 2 - 2
business/ServiceMgmt.business.php

@@ -110,8 +110,8 @@ class bizContract extends cmdbAbstractObject
 		MetaModel::Init_AddAttribute(new AttributeString("cost", array("allowed_values"=>null, "sql"=>"cost", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
 		MetaModel::Init_AddAttribute(new AttributeEnum("currency", array("allowed_values"=>new ValueSetEnum("Euros,Dollars"), "sql"=>"currency", "default_value"=>"Euros", "is_null_allowed"=>true, "depends_on"=>array())));
 		MetaModel::Init_AddAttribute(new AttributeText("description", array("allowed_values"=>null, "sql"=>"description", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
-		MetaModel::Init_AddAttribute(new AttributeDate("move2prod_date", array("allowed_values"=>null, "sql"=>"move2prod_date", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
-		MetaModel::Init_AddAttribute(new AttributeDate("end_prod", array("allowed_values"=>null, "sql"=>"end_date", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
+		MetaModel::Init_AddAttribute(new AttributeDateTime("move2prod_date", array("allowed_values"=>null, "sql"=>"move2prod_date", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
+		MetaModel::Init_AddAttribute(new AttributeDateTime("end_prod", array("allowed_values"=>null, "sql"=>"end_date", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
 		MetaModel::Init_AddAttribute(new AttributeEnum("status", array("allowed_values"=>new ValueSetEnum("New, Negotiating, Signed, Production,Finished"), "sql"=>"status", "default_value"=>"New", "is_null_allowed"=>false, "depends_on"=>array())));
 		MetaModel::Init_AddAttribute(new AttributeEnum("type", array("allowed_values"=>new ValueSetEnum("Hardware,Software,Support,Licence"), "sql"=>"type", "default_value"=>"Support", "is_null_allowed"=>false, "depends_on"=>array())));
 		MetaModel::Init_AddAttribute(new AttributeInteger("version_number", array("allowed_values"=>null, "sql"=>"version_number", "default_value"=>1, "is_null_allowed"=>false, "depends_on"=>array())));

+ 9 - 11
business/incidentMgmt.business.php

@@ -47,12 +47,12 @@ class bizIncidentTicket extends cmdbAbstractObject
 		// SetPossibleValues("status",array("Open","Monitored","Closed"));
 		MetaModel::Init_AddAttribute(new AttributeText("initial_situation", array("allowed_values"=>null, "sql"=>"initial_situation", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
 		MetaModel::Init_AddAttribute(new AttributeText("current_situation", array("allowed_values"=>null, "sql"=>"current_situation", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
-		MetaModel::Init_AddAttribute(new AttributeDate("start_date", array("allowed_values"=>null, "sql"=>"start_date", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
-		// définir une date de défaut à maintenant, alias creation ou modification du ticket
-		MetaModel::Init_AddAttribute(new AttributeDate("last_update", array("allowed_values"=>null, "sql"=>"last_update", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
-	    MetaModel::Init_AddAttribute(new AttributeDate("next_update", array("allowed_values"=>null, "sql"=>"next_update", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
+		MetaModel::Init_AddAttribute(new AttributeDateTime("start_date", array("allowed_values"=>null, "sql"=>"start_date", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
+		// d�finir une date de d�faut � maintenant, alias creation ou modification du ticket
+		MetaModel::Init_AddAttribute(new AttributeDateTime("last_update", array("allowed_values"=>null, "sql"=>"last_update", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
+	    MetaModel::Init_AddAttribute(new AttributeDateTime("next_update", array("allowed_values"=>null, "sql"=>"next_update", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
 
-		MetaModel::Init_AddAttribute(new AttributeDate("end_date", array("allowed_values"=>null, "sql"=>"closed_date", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
+		MetaModel::Init_AddAttribute(new AttributeDateTime("end_date", array("allowed_values"=>null, "sql"=>"closed_date", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
 		MetaModel::Init_AddAttribute(new AttributeExternalKey("caller_id", array("targetclass"=>"bizPerson", "jointype"=> "", "allowed_values"=>new ValueSetObjects('SELECT bizPerson AS p WHERE p.org_id = :this->org_id'), "sql"=>"caller_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array("org_id"))));
 		MetaModel::Init_AddAttribute(new AttributeExternalField("caller_mail", array("allowed_values"=>null, "extkey_attcode"=> 'caller_id', "target_attcode"=>"email")));
 	
@@ -71,7 +71,7 @@ class bizIncidentTicket extends cmdbAbstractObject
 		MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("related_tickets", array("linked_class"=>"lnkRelatedTicket", "ext_key_to_me"=>"ticket_id", "ext_key_to_remote"=>"rel_ticket_id", "allowed_values"=>null, "count_min"=>0, "count_max"=>0, "depends_on"=>array(/*'impacted_infra_computed',*/ 'impacted_infra_manual'))));
 		MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("contacts_a_notifier", array("linked_class"=>"lnkContactTicket", "ext_key_to_me"=>"ticket_id", "ext_key_to_remote"=>"contact_id", "allowed_values"=>null, "default_value"=>new ValueSetRelatedObjectsFromLinkSet('impacted_infra_manual'/*sLinkSetAttCode*/, 'infra_id'/*sExtKeyToRemote*/, 'impacts'/*sRelationCode*/, 3/*iMaxDepth*/, 'bizContact'/*sTargetClass*/, 'lnkContactTicket'/*sTargetLinkClass*/, 'contact_id'/*sTargetExtKey*/) /* ici plus tard... */, "count_min"=>0, "count_max"=>0, "depends_on"=>array('impacted_infra_manual'))));
 
-		// doit-on aussi ajouter un filtre sur les extfields lié à une extkey ? ici le name de l'agent?
+		// doit-on aussi ajouter un filtre sur les extfields li� � une extkey ? ici le name de l'agent?
 		
 		// Display lists
 		MetaModel::Init_SetZListItems('details', array('name','title', 'org_id', 'type','ticket_status', 'severity','start_date', 'initial_situation', 'current_situation','caller_id', 'impact', 'last_update', 'next_update','end_date', 'assignment_count', 'workgroup_id','agent_id','action_log','resolution')); // Attributes to be displayed for a list
@@ -86,7 +86,7 @@ class bizIncidentTicket extends cmdbAbstractObject
 												 "title"=>OPT_ATT_MANDATORY, "org_id"=>OPT_ATT_MANDATORY, "caller_id"=>OPT_ATT_MANDATORY, "initial_situation"=>OPT_ATT_MANDATORY, "start_date"=>OPT_ATT_MANDATORY, "workgroup_id"=>OPT_ATT_MANDATORY,
 												 "severity"=>OPT_ATT_MANDATORY, "agent_id"=>OPT_ATT_HIDDEN,"impacted_infra_manual"=>OPT_ATT_MANDATORY, "related_tickets"=>OPT_ATT_MUSTPROMPT,"resolution"=>OPT_ATT_HIDDEN)));
 		MetaModel::Init_DefineState("Assigned", array("attribute_inherit"=>null,
-												"attribute_list"=>array('name' => OPT_ATT_READONLY, "title"=>OPT_ATT_READONLY, "org_id"=>OPT_ATT_READONLY, "caller_id"=>OPT_ATT_READONLY, "initial_situation"=>OPT_ATT_READONLY, "start_date"=>OPT_ATT_READONLY,'assignment_count' => OPT_ATT_READONLY,'end_date' => OPT_ATT_HIDDEN, "workgroup_id"=>OPT_ATT_READONLY, "agent_id"=>OPT_ATT_MUSTCHANGE,"resolution"=>OPT_ATT_HIDDEN)));
+												"attribute_list"=>array('name' => OPT_ATT_READONLY, "title"=>OPT_ATT_READONLY, "org_id"=>OPT_ATT_READONLY, "caller_id"=>OPT_ATT_READONLY, "initial_situation"=>OPT_ATT_READONLY, "start_date"=>OPT_ATT_READONLY,'assignment_count' => OPT_ATT_READONLY,'end_date' => OPT_ATT_HIDDEN, "workgroup_id"=>OPT_ATT_MUSTPROMPT, "agent_id"=>OPT_ATT_MUSTCHANGE,"resolution"=>OPT_ATT_HIDDEN)));
 		MetaModel::Init_DefineState("WorkInProgress", array("attribute_inherit"=>null, "attribute_list"=>array("title"=>OPT_ATT_READONLY, "org_id"=>OPT_ATT_READONLY, "caller_id"=>OPT_ATT_READONLY, "initial_situation"=>OPT_ATT_READONLY,'end_date' => OPT_ATT_HIDDEN, "start_date"=>OPT_ATT_READONLY,"workgroup_id"=>OPT_ATT_MANDATORY, "agent_id"=>OPT_ATT_MANDATORY,"action_log"=>OPT_ATT_MANDATORY,"impact"=>OPT_ATT_READONLY,"severity"=>OPT_ATT_READONLY)));
 		MetaModel::Init_DefineState("Resolved", array("attribute_inherit"=>null, "attribute_list"=>array('name' => OPT_ATT_READONLY,'type' => OPT_ATT_READONLY, "title"=>OPT_ATT_READONLY, "org_id"=>OPT_ATT_READONLY, "caller_id"=>OPT_ATT_READONLY, "initial_situation"=>OPT_ATT_READONLY,"current_situation"=>OPT_ATT_READONLY,'end_date' => OPT_ATT_READONLY,'last_update' => OPT_ATT_READONLY,'next_update' => OPT_ATT_READONLY, "start_date"=>OPT_ATT_READONLY,"workgroup_id"=>OPT_ATT_READONLY, "agent_id"=>OPT_ATT_READONLY,"action_log"=>OPT_ATT_READONLY,"impact"=>OPT_ATT_READONLY,"severity"=>OPT_ATT_READONLY,"resolution"=>OPT_ATT_MUSTCHANGE)));
 		MetaModel::Init_DefineState("Closed", array("attribute_inherit"=>null, "attribute_list"=>array('name' => OPT_ATT_READONLY,'type' => OPT_ATT_READONLY, "title"=>OPT_ATT_READONLY, "org_id"=>OPT_ATT_READONLY, "caller_id"=>OPT_ATT_READONLY, "initial_situation"=>OPT_ATT_READONLY,"current_situation"=>OPT_ATT_READONLY,'end_date' => OPT_ATT_READONLY,'last_update' => OPT_ATT_READONLY,'next_update' => OPT_ATT_READONLY, "start_date"=>OPT_ATT_READONLY,"workgroup_id"=>OPT_ATT_READONLY, "agent_id"=>OPT_ATT_READONLY,"action_log"=>OPT_ATT_READONLY,"impact"=>OPT_ATT_READONLY,"severity"=>OPT_ATT_READONLY,"resolution"=>OPT_ATT_READONLY)));
@@ -153,12 +153,10 @@ class bizIncidentTicket extends cmdbAbstractObject
 
 		$oImpactedInfras = DBObjectSet::FromLinkSet($this, 'impacted_infra_manual', 'infra_id');
 
-		$aComputed = $oImpactedInfras->GetRelatedObjects('impacts', 2);
+		$aComputed = $oImpactedInfras->GetRelatedObjects('impacts', 10);
 
 		if (array_key_exists('logRealObject', $aComputed))
 		{
-			// Romain: supprimer cette ligne
-			// $aLinksToCreate = array();
 			foreach($aComputed['logRealObject'] as $iKey => $oObject)
 			{
 				if (MetaModel::IsParentClass('bizContact', get_class($oObject)))
@@ -166,7 +164,7 @@ class bizIncidentTicket extends cmdbAbstractObject
 					$oNewLink = new lnkContactTicket();
 					$oNewLink->Set('contact_id', $iKey);
 					//$oNewLink->Set('ticket_id', $this->GetKey()); // unkown at that time!
-					$oNewLink->Set('role', 'concerned by an impacted CI');
+					$oNewLink->Set('role', 'contact automatically computed');
 
 					// Romain: transformer cette ligne
 					$oToNotify->AddObject($oNewLink);

+ 2 - 2
business/itop.business.class.inc.php

@@ -1330,7 +1330,7 @@ class bizApplication extends logInfra
 		MetaModel::Init_InheritAttributes();
 		MetaModel::Init_AddAttribute(new AttributeExternalKey("device_id", array("targetclass"=>"bizDevice", "jointype"=> '', "allowed_values"=>new ValueSetObjects('SELECT bizDevice AS p WHERE p.org_id = :this->org_id'), "sql"=>"device_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array("org_id"))));
 		MetaModel::Init_AddAttribute(new AttributeExternalField("device_name", array("allowed_values"=>null, "extkey_attcode"=> 'device_id', "target_attcode"=>"name")));
-		MetaModel::Init_AddAttribute(new AttributeDate("install_date", array("allowed_values"=>null, "sql"=>"install_date", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
+		MetaModel::Init_AddAttribute(new AttributeDateTime("install_date", array("allowed_values"=>null, "sql"=>"install_date", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
 
 		MetaModel::Init_AddAttribute(new AttributeString("version", array("allowed_values"=>null, "sql"=>"version", "default_value"=>"undefined", "is_null_allowed"=>false, "depends_on"=>array())));
 		MetaModel::Init_AddAttribute(new AttributeString("function", array("allowed_values"=>null, "sql"=>"function", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
@@ -1495,7 +1495,7 @@ class bizPatch extends logRealObject
 		MetaModel::Init_AddAttribute(new AttributeEnum("status", array("allowed_values"=>new ValueSetEnum('production,obsolete'), "sql"=>"status", "default_value"=>"production", "is_null_allowed"=>false, "depends_on"=>array())));
 		MetaModel::Init_AddAttribute(new AttributeExternalKey("device_id", array("targetclass"=>"bizDevice", "jointype"=> '', "allowed_values"=>new ValueSetObjects('SELECT bizDevice AS p WHERE p.org_id = :this->org_id'), "sql"=>"device_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_MANUAL, "depends_on"=>array("org_id"))));
 		MetaModel::Init_AddAttribute(new AttributeExternalField("device_name", array("allowed_values"=>null, "extkey_attcode"=> 'device_id', "target_attcode"=>"name")));
-   	MetaModel::Init_AddAttribute(new AttributeDate("install_date", array("allowed_values"=>null, "sql"=>"install_date", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
+   		MetaModel::Init_AddAttribute(new AttributeDateTime("install_date", array("allowed_values"=>null, "sql"=>"install_date", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
 		
 		MetaModel::Init_AddAttribute(new AttributeText("description", array("allowed_values"=>null, "sql"=>"description", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
 		MetaModel::Init_AddAttribute(new AttributeString("patch_type", array("allowed_values"=>new ValueSetEnum("OS,Application"), "sql"=>"patch_type", "default_value"=>"OS", "is_null_allowed"=>false, "depends_on"=>array())));

+ 183 - 8
core/attributedef.class.inc.php

@@ -177,16 +177,14 @@ abstract class AttributeDefinition
 	public function GetSQLValues($value) {return array();} // returns column/value pairs (1 in most of the cases), for WRITING (Insert, Update)
 	public function RequiresIndex() {return false;}
 
-	public function GetJSCheckFunc()
+	public function GetValidationPattern()
 	{
-		$sRegExp = $this->Get("regexp");
-		if (empty($sRegExp)) return 'return true;';
-
-		return "return regexp('$sRegExp', myvalue);";
-	} 
+		return '';
+	}
+	
 	public function CheckValue($value)
 	{
-		$sRegExp = $this->Get("regexp");
+		$sRegExp = $this->Get("regexp"); // ??? Does it exist ??
 		if (empty($sRegExp)) return true;
 		
 		return preg_match(preg_escape($this->Get("regexp")), $value);
@@ -464,6 +462,11 @@ class AttributeInteger extends AttributeDBField
 	public function GetEditClass() {return "String";}
 	protected function GetSQLCol() {return "INT(11)";}
 	
+	public function GetValidationPattern()
+	{
+		return "^[0-9]+$";
+	}
+
 	public function GetBasicFilterOperators()
 	{
 		return array(
@@ -799,6 +802,11 @@ class AttributeText extends AttributeString
 class AttributeEmailAddress extends AttributeString
 {
 	public function GetTypeDesc() {return "Email address(es)";}
+
+	public function GetValidationPattern()
+	{
+		return "^([0-9a-zA-Z]([-.\\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\\w]*[0-9a-zA-Z]\\.)+[a-zA-Z]{2,9})$";
+	}
 }
 
 /**
@@ -948,6 +956,163 @@ class AttributeEnum extends AttributeString
  */
 class AttributeDate extends AttributeDBField
 {
+	const MYDATEFORMAT = "Y-m-d";
+
+	static public function InitStatics()
+	{
+		// Nothing to do...
+	}
+
+	static protected function ListExpectedParams()
+	{
+		return parent::ListExpectedParams();
+		//return array_merge(parent::ListExpectedParams(), array());
+	}
+
+	public function GetType() {return "Date";}
+	public function GetTypeDesc() {return "Date";}
+	public function GetEditClass() {return "Date";}
+	protected function GetSQLCol() {return "DATE";}
+
+	// #@# THIS HAS TO REVISED
+	// Having null not allowed was interpreted by mySQL
+	// which was creating the field with the flag 'ON UPDATE CURRENT_TIMESTAMP'
+	// Then, on each update of the record, the field was modified.
+	// We will have to specify the default value if we want to restore this option
+	// In fact, we could also have more verbs dedicated to the DB:
+	// GetDBDefaultValue()... or GetDBFieldCreationStatement()....
+	public function IsNullAllowed() {return true;}
+	public function GetDefaultValue()
+	{
+		$default = parent::GetDefaultValue();
+
+		if (!parent::IsNullAllowed())
+		{
+			if (empty($default))
+			{
+				$default = date("Y-m-d");
+			}
+		}
+
+		return $default;
+	}
+	// END OF THE WORKAROUND
+	///////////////////////////////////////////////////////////////
+
+	public function GetValidationPattern()
+	{
+		return "^[0-9]{4}-(((0[13578]|(10|12))-(0[1-9]|[1-2][0-9]|3[0-1]))|(02-(0[1-9]|[1-2][0-9]))|((0[469]|11)-(0[1-9]|[1-2][0-9]|30)))$";
+	}
+
+	public function GetBasicFilterOperators()
+	{
+		return array(
+			"="=>"equals",
+			"!="=>"differs from",
+			"<"=>"before",
+			"<="=>"before",
+			">"=>"after (strictly)",
+			">="=>"after",
+			"SameMonth"=>"same year/month",
+			"SameYear"=>"same year",
+			"Today"=>"today",
+			">|"=>"after today + N days",
+			"<|"=>"before today + N days",
+			"=|"=>"equals today + N days",
+		);
+	}
+	public function GetBasicFilterLooseOperator()
+	{
+		// Unless we implement a "same xxx, depending on given precision" !
+		return "=";
+	}
+
+	public function GetBasicFilterSQLExpr($sOpCode, $value)
+	{
+		$sQValue = CMDBSource::Quote($value);
+
+		switch ($sOpCode)
+		{
+		case '=':
+		case '!=':
+		case '<':
+		case '<=':
+		case '>':
+		case '>=':
+			return $this->GetSQLExpr()." $sOpCode $sQValue";
+		case 'SameMonth':
+			return "DATE_FORMAT(".$this->GetSQLExpr().", '%Y-%m') = DATE_FORMAT($sQValue, '%Y-%m')";
+		case 'SameYear':
+			return "MONTH(".$this->GetSQLExpr().") = MONTH($sQValue)";
+		case 'Today':
+			return "DATE(".$this->GetSQLExpr().") = CURRENT_DATE()";
+		case '>|':
+			return "DATE(".$this->GetSQLExpr().") > DATE_ADD(CURRENT_DATE(), INTERVAL $sQValue DAY)";
+		case '<|':
+			return "DATE(".$this->GetSQLExpr().") < DATE_ADD(CURRENT_DATE(), INTERVAL $sQValue DAY)";
+		case '=|':
+			return "DATE(".$this->GetSQLExpr().") = DATE_ADD(CURRENT_DATE(), INTERVAL $sQValue DAY)";
+		default:
+			return $this->GetSQLExpr()." = $sQValue";
+		}
+	}
+	
+	public function MakeRealValue($proposedValue)
+	{
+		if (!is_numeric($proposedValue))
+		{
+			return $proposedValue;
+		}
+		else
+		{
+			return date("Y-m-d", $proposedValue);
+		}
+		throw new CoreException("Invalid type for a date (found ".gettype($proposedValue)." and accepting string/int/DateTime)");
+		return null;
+	}
+	public function ScalarToSQL($value)
+	{
+		if (empty($value))
+		{
+			// Make a valid date for MySQL. TO DO: support NULL as a literal value for fields that can be null.
+			return '0000-00-00';
+		}
+		return $value;
+	}
+
+	public function GetAsHTML($value)
+	{
+		return Str::pure2html($value);
+	}
+
+	public function GetAsXML($value)
+	{
+		return Str::pure2xml($value);
+	}
+
+	public function GetAsCSV($sValue, $sSeparator = ',', $sTextQualifier = '"')
+	{
+		$sFrom = array("\r\n", $sTextQualifier);
+		$sTo = array("\n", $sTextQualifier.$sTextQualifier);
+		$sEscaped = str_replace($sFrom, $sTo, (string)$sValue);
+		return '"'.$sEscaped.'"';
+	}
+}
+
+// Init static constant once for all (remove when PHP allows real static const)
+AttributeDate::InitStatics();
+/**
+ * Map a date+time column to an attribute 
+ *
+ * @package     iTopORM
+ * @author      Romain Quetiez <romainquetiez@yahoo.fr>
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.itop.com
+ * @since       1.0
+ * @version     $itopversion$
+ */
+class AttributeDateTime extends AttributeDBField
+{
 	const MYDATEFORMAT = "Y-m-d H:i:s";
 	//const MYDATETIMEZONE = "UTC";
 	const MYDATETIMEZONE = "Europe/Paris";
@@ -971,7 +1136,7 @@ class AttributeDate extends AttributeDBField
 
 	public function GetType() {return "Date";}
 	public function GetTypeDesc() {return "Date and time";}
-	public function GetEditClass() {return "Date";}
+	public function GetEditClass() {return "DateTime";}
 	protected function GetSQLCol() {return "TIMESTAMP";}
 
 	// #@# THIS HAS TO REVISED
@@ -999,6 +1164,11 @@ class AttributeDate extends AttributeDBField
 	// END OF THE WORKAROUND
 	///////////////////////////////////////////////////////////////
 
+	public function GetValidationPattern()
+	{
+		return "^([0-9]{4}-(((0[13578]|(10|12))-(0[1-9]|[1-2][0-9]|3[0-1]))|(02-(0[1-9]|[1-2][0-9]))|((0[469]|11)-(0[1-9]|[1-2][0-9]|30))))( (0[0-9]|1[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])){0,1}|0000-00-00 00:00:00|0000-00-00$";
+	}
+
 	public function GetBasicFilterOperators()
 	{
 		return array(
@@ -1398,6 +1568,11 @@ class AttributeURL extends AttributeString
 		}
 		return "<a target=\"$sTarget\" href=\"$sValue\">$sLabel</a>";
 	}
+
+	public function GetValidationPattern()
+	{
+		return "^(http|https|ftp)\://[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(:[a-zA-Z0-9]*)?/?([a-zA-Z0-9\-\._\?\,\'/\\\+&amp;%\$#\=~])*$";
+	}
 }
 
 /**

+ 1 - 1
core/cmdbchange.class.inc.php

@@ -29,7 +29,7 @@ class CMDBChange extends DBObject
 		);
 		MetaModel::Init_Params($aParams);
 		//MetaModel::Init_InheritAttributes();
-		MetaModel::Init_AddAttribute(new AttributeDate("date", array("allowed_values"=>null, "sql"=>"date", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
+		MetaModel::Init_AddAttribute(new AttributeDateTime("date", array("allowed_values"=>null, "sql"=>"date", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
 		MetaModel::Init_AddAttribute(new AttributeString("userinfo", array("allowed_values"=>null, "sql"=>"userinfo", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
 	}
 

+ 1 - 1
core/event.class.inc.php

@@ -31,7 +31,7 @@ class Event extends cmdbAbstractObject
 		MetaModel::Init_Params($aParams);
 		//MetaModel::Init_InheritAttributes();
 		MetaModel::Init_AddAttribute(new AttributeText("message", array("allowed_values"=>null, "sql"=>"message", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
-		MetaModel::Init_AddAttribute(new AttributeDate("date", array("allowed_values"=>null, "sql"=>"date", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
+		MetaModel::Init_AddAttribute(new AttributeDateTime("date", array("allowed_values"=>null, "sql"=>"date", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
 		MetaModel::Init_AddAttribute(new AttributeString("userinfo", array("allowed_values"=>null, "sql"=>"userinfo", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
 
 		// Display lists

+ 20 - 0
core/metamodel.class.php

@@ -318,6 +318,26 @@ abstract class MetaModel
 			return array();
 		}
 	}
+	/**
+	 * Find all attributes that depend on the specified one (reverse of GetPrequisiteAttributes)
+	 * @param string $sClass Name of the class
+	 * @param string $sAttCode Code of the attributes
+	 * @return Array List of attribute codes that depend on the given attribute, empty array if none.
+	 */
+	final static public function GetDependentAttributes($sClass, $sAttCode)
+	{
+		$aResults = array();
+		self::_check_subclass($sClass);
+		foreach (self::ListAttributeDefs($sClass) as $sDependentAttCode=>$void)
+		{
+			$aPrerequisites = self::GetPrequisiteAttributes($sClass, $sDependentAttCode);
+			if (in_array($sAttCode, $aPrerequisites))
+			{
+				$aResults[] = $sDependentAttCode;
+			}
+		}
+		return $aResults;
+	}
 	// #@# restore to private ?
 	final static public function DBGetTable($sClass, $sAttCode = null)
 	{