View Issue Details

IDProjectCategoryView StatusLast Update
0000938Composrunvalidatedpublic2016-10-27 22:31
ReporterChris GrahamAssigned To 
Status non-assignedResolutionopen 
Product Version 
Target VersionFixed in Version 
Summary0000938: Option to disable validation control for members
DescriptionAdd a new privilege that determines whether someone can UNVALIDATE stuff. Usually in Composr anyone who can bypass-validation (i.e. post straight to live) can also unvalidate, and see's this in the UI. This may not be desirable due to clutter.
TagsNo tags attached.
Attach Tags
Time estimation (hours)24
Sponsorship open


related to 0002886 closedChris Graham Option for users to mark new content for moderator approval 


Chris Graham

2013-07-17 14:30

administrator   ~0001565

Another use case is if validation is being used as a 'has purchased' indicator. You want editing to not unvalidate, and you don't want to see the validation option.

This is slightly different to the original issue here. The original issue is about DENYing unvalidating, this is about PREVENTing unvalidating. In actualality it is the same thing.

We ideally need a new set of privileges.

I have attached a diff for calendars, which is hard-coded rather than privileges. Privileges could be built on top of this same model, which involves adding a new flag to the crud module's and also handling it in the form building logic.

Chris Graham

2013-07-17 14:31


validation_preservation.diff (5,038 bytes)
diff --git a/cms/pages/modules/cms_calendar.php b/cms/pages/modules/cms_calendar.php
index 4d534f8..72fe8fc 100644
--- a/cms/pages/modules/cms_calendar.php
+++ b/cms/pages/modules/cms_calendar.php
@@ -42,6 +42,7 @@ class Module_cms_calendar extends standard_crud_module
 	var $permissions_cat_require='calendar';
 	var $permissions_cat_name='type';
 	var $posting_field_required=false;
+	var $edit_keep_validation=true;
 	// These are state-set, for usage by the specialised donext manager
 	var $donext_type=NULL;
@@ -447,8 +450,16 @@ class Module_cms_calendar extends standard_crud_module
 		// Validation
 		if ($validated==0) $validated=get_param_integer('validated',0);
 		if (has_some_cat_privilege(get_member(),'bypass_validation_'.$this->permissions_require.'range_content',NULL,$this->permissions_cat_require))
+		{
 			if (addon_installed('unvalidated'))
+		} else
+		{
+			if ($this->edit_keep_validation)
+			{
+				$hidden->attach(form_input_hidden('validated','1')); // Will actually be changed to -1 by crud_module, and we later change -1 to NULL, which means no-change
+			}
+		}
 		$fields2=new ocp_tempcode();
@@ -971,6 +982,7 @@ class Module_cms_calendar extends standard_crud_module
+		if ($validation==-1) $validation=NULL;
 		if (($delete_status=='3') && (!fractional_edit()))
diff --git a/sources/calendar2.php b/sources/calendar2.php
index 938bc12..ed2d130 100644
--- a/sources/calendar2.php
+++ b/sources/calendar2.php
@@ -201,7 +201,7 @@ function add_calendar_event($type,$recurrence,$recurrences,$seg_recurrences,$tit
  * @param  ?MEMBER			The member's calendar it will be on (NULL: not on a specific member's calendar)
  * @param  SHORT_TEXT		Meta keywords
  * @param  LONG_TEXT			Meta description
- * @param  BINARY				Whether the event has been validated
+ * @param  ?BINARY			Whether the event has been validated (NULL: don't change)
  * @param  BINARY				Whether the event may be rated
  * @param  SHORT_INTEGER	Whether comments are allowed (0=no, 1=yes, 2=review style)
  * @param  BINARY				Whether the event may be trackbacked
@@ -267,7 +267,6 @@ function edit_calendar_event($id,$type,$recurrence,$recurrences,$seg_recurrences
-		'validated'=>$validated,
@@ -275,6 +274,8 @@ function edit_calendar_event($id,$type,$recurrence,$recurrences,$seg_recurrences
+	if (!is_null($validated))
+		$update_map['validated']=$validated;
 	if (!is_null($add_time))
diff --git a/sources/crud_module.php b/sources/crud_module.php
index f40ff95..518f365 100644
--- a/sources/crud_module.php
+++ b/sources/crud_module.php
@@ -95,6 +95,7 @@ class standard_crud_module
 	var $cached_max_rows=NULL;
 	var $lang_type=NULL;
 	var $permission_page_name=NULL;
+	var $edit_keep_validation=false;
 	// These only needed if we are generate nice_get_entries automatically
 	var $table_prefix='';
@@ -1368,10 +1369,18 @@ class standard_crud_module
 			if (!is_null($test)) return $test;
-			if (($this->user_facing) && (!is_null($this->permissions_require)) && (addon_installed('unvalidated')) && (array_key_exists('validated',$_POST)))
+			if (($this->user_facing) && (!is_null($this->permissions_require)) && (addon_installed('unvalidated')))
-				if (!has_privilege(get_member(),'bypass_validation_'.$this->permissions_require.'range_content',$this->permission_page_name,array($this->permissions_cat_require,is_null($this->permissions_cat_name)?'':post_param($this->permissions_cat_name),$this->permissions_cat_require_b,is_null($this->permissions_cat_name_b)?'':post_param($this->permissions_cat_name_b))))
-					$_POST['validated']='0';
+				if (array_key_exists('validated',$_POST))
+				{
+					if (!has_privilege(get_member(),'bypass_validation_'.$this->permissions_require.'range_content',$this->permission_page_name,array($this->permissions_cat_require,is_null($this->permissions_cat_name)?'':post_param($this->permissions_cat_name),$this->permissions_cat_require_b,is_null($this->permissions_cat_name_b)?'':post_param($this->permissions_cat_name_b))))
+					{
+						if (!$this->edit_keep_validation)
+							$_POST['validated']='0';
+						else
+							$_POST['validated']='-1';
+					}
+				}
 			if (!is_null($this->upload)) require_code('uploads');

Chris Graham

2013-07-17 14:33

administrator   ~0001566

It's actually a bit odd. We kind of have two converse privileges here.

On one hand, we want a privilege where we grant access to not have something auto-unvalidate when editing.

On the other hand, we want a privilege that lets people choose to unvalidate.

So maybe it is actually two separate things that need to tie together. Needs more careful though.

Chris Graham

2013-07-17 17:10

administrator   ~0001567

Also it would be good to be able to have it so you are allowed to only delete non-validated content.

This is all getting very complex. I don't want to bloat up the privilege system, so maybe this should work via pluggable code. Pass in state information consistently in the Composr API calls, and provide hooks that can perturb the configured permissions landscape based on that other state information.

Chris Graham

2013-07-17 18:03

administrator   ~0001568

Last edited: 2013-07-17 18:08

View 2 revisions

Ok, so I've thought about this.

I think the best solution (although much more time consuming than 2.5 hours), is to change the current privilege model in a few ways.

Instead of these privileges:

...create a conceptual system of privilege levels:
add as unvalidated < add as validated
edit own to unvalidated < edit own keeping validated < edit all to unvalidated < edit all keeping validated
manually edit validation to off < manually edit validation to on (*1)
delete own if unvalidated < delete own < delete all if unvalidated < delete all

(*1 validation may automatically trigger to off, based on the other privileges, but behind the scenes, without a UI)

These could be encoded still using binary privileges, so long as it makes the assumption that if you have a higher level one, you also have the lower level ones. We can add an abstraction layer in the code to tackle the checking sequence.
The UI would show using lists rather than checkboxes though (when setting global privileges, and in permission tree editor).

The validation checkbox would only show on forms based on some careful logic. E.g. if your entry was validated and you were editing and had "manually edit validation to off", it would show. If your entry was not validated and you were editing and had "manually edit validation to off" it would not show, as there is no change you can make that would be able to take effect.

In all this there probably is a few days work.

There may be other privileges that could benefit from putting into levels. I seem to remember there being some that define acces to a 'low' limit and a 'high' limit, but in difference privileges.

Issue History

Date Modified Username Field Change
2016-10-17 16:02 Chris Graham Category core => unvalidated
2016-10-17 16:02 Chris Graham Relationship added related to 0002886