get_id()."\">";
echo "";
}
/** @js:translate */
static function create ($gte, $group)
{
$res = new group_editor;
$res->group = $group;
$res->gq_initialise ($gte);
return $res;
}
}
/** @codegroup:admin */
class query_editor extends gq_editor
{
var $query;
var $need_reload;
/** @js:translatesync */
function target_object ()
{
return $this->query;
}
/** @js:translatesync */
function i_can_read ()
{
return $this->query->i_can_read;
}
/** @js:translatesync */
function group_id ()
{
return "Q".$this->query->rowid;
}
/** @js:translatesync */
function i_am_owner ()
{
if ($this->query->is_super_group == "1") return person::is_webmaster();
return $this->query->i_am_owner;
}
/** @js:translatesync */
function i_can_annotate ()
{
return $this->query->i_am_owner;
}
/** @js:translatesync */
function i_can_modify ()
{
return false;
}
function do_save_column_headings ($headings)
{
$this->query->set_default_headings ($headings);
}
/** @js:translate */
function get_default_headings ()
{
return $this->query->get_default_headings ();
}
/** @js:translate */
function edit ($el, $arg, $ev)
{
$this->query->edit();
$this->gte->rerender_doc();
$this->rerender_count ();
}
/** @js:translate */
function base_expr ()
{
return "Q".$this->query->rowid.".";
}
/** @js:translate */
function quick_report ()
{
$this->run_quick_report ("Q".$this->query->rowid.".");
}
/** @js:translate */
function on_drag_group_stop_handler ($payload)
{
$this->need_reload = false;
$this->gte->drag_stop ($payload, $this->is_copy);
$this->dtm->drag_group_complete ();
if ($this->need_reload)
$this->gte->rerender_doc ();
}
/** @js:translate */
function on_drag_group_start ($el, $gmr, $ev)
{
if ($this->is_dragging) return; // this is to get around an IE bug - if you click quickly then up handler doesn't get called
$this->is_dragging = true;
$gmr->is_selected = 1;
$this->dtm->rerender_row ($gmr);
$rowids = $this->dtm->get_rows();
$selected_rows = array();
foreach ($rowids as $rowid)
{
$xgmr = rpcclass::get_object_by_id ("gq_member_row", $rowid);
if ($xgmr->is_selected != 0)
$selected_rows[] = $xgmr;
}
$this->is_copy = true;
$this->dtm->drag_group_start ($selected_rows, $ev);
}
/** @js:translate */
function get_row_fields ($gmr)
{
$res = array();
$res[] = "
render_start("on_drag_group_start", $gmr)."\""
." onmousedown=\"".$this->render_start ("on_drag_group_start", $gmr)."\""
." />";
$xres = $gmr->get_row_fields ();
array_splice ($res, count($res), 0, $xres);
return $res;
}
/** @js:translate */
function move_complete ()
{
$this->need_reload = true;
}
/** @js:translate */
function render_editor ()
{
echo "
get_id()."\">";
echo "";
}
/** @js:translate */
static function create ($gte, $query)
{
$res = new query_editor;
$res->query = $query;
$res->gq_initialise ($gte);
return $res;
}
}
//-----------------------------------------------------------------------------------------------------------
/** @dbtable:groups @readonly:1 */
class group extends tracked_dbclass implements mailunsub_source
{
/** @dbfield:menuname @dbsql:varchar(128)+not+null */
var $menuname;
/** @dbfield:description @dbsql:varchar(255)+not+null */
var $description;
/** @dbfield:owners @dbsql:varchar(255)+not+null */
var $owners;
/** @dbfield:readers @dbsql:varchar(255)+not+null */
var $readers;
/** @dbfield:is_role @dbsql:int+not+null */
var $is_role;
/** @dbfield:is_historical @dbsql:int+not+null */
var $is_historical;
/** @dbfield:is_newcomer @dbsql:int+not+null */
var $is_newcomer;
/** @dbfield:can_process @dbsql:int+not+null */
var $can_process;
/** @dbfield:is_opt_in_only @dbsql:int+not+null */
var $is_opt_in_only;
/** @dbfield:is_self_subscribe @dbsql:int+not+null */
var $is_self_subscribe;
/** @dbfield:is_self_unsubscribe @dbsql:int+not+null */
var $is_self_unsubscribe;
/** @dbfield:attributes @dbsql:varchar(255)+not+null */
var $attributes;
/** @dbfield:consent_text @dbsql:varchar(256)+not+null @js:no */
var $consent_text;
/** @dbfield:default_headings @dbarray:1 @dbsql:varchar(1024)+not+null */
var $default_headings;
var $dtm;
var $i_am_owner;
var $i_can_remove_member;
var $i_can_read;
static function get_all_can_process ()
{
return self::search ("group", "can_process=1 or is_opt_in_only=1");
}
static function get_all_self_subscribe ()
{
return self::search ("group", "is_self_subscribe=1");
}
static function get_all_self_unsubscribe ()
{
return self::search ("group", "is_self_unsubscribe=1");
}
function consent_text ()
{
return $this->consent_text;
}
function audit_name () { return $this->menuname; }
function audit_url () { return group_tree_editor2::url ($this->menuname); }
function save_attributes ($gptn)
{
$consent = $gptn->get_attribute_recursive ("consent");
if ($consent != $this->consent_text)
{
error_log ("set consent to [$consent]");
$this->consent_text = $consent;
$this->save_property ("consent_text");
}
}
function label ()
{
return $this->menuname;
}
function set_default_headings ($headings)
{
$this->default_headings = $headings;
$this->save_property ("default_headings");
}
/** @js:translate */
function get_default_headings ()
{
return $this->default_headings;
}
/** @js:translate */
function get_attributes ()
{
$string = $this->attributes;
if ($string === null || $string === "")
$aarr = aarray();
else if (substr($string, 0, 2) == "a:")
{
$aarr = unserialize($string);
}
else
{
$aarr = aarray();
$strings = explode (";", $string);
foreach ($strings as $s)
{
$matches = array();
$match = preg_match("/([^=]+)=(.*)/", $s, $matches);
if ($match == 1)
{
$key = $matches[1];
$value = $matches[2];
$aarr[$key] = $value;
}
}
}
return ($aarr);
}
function raw_set_special ($fname, $val)
{
if ($this->$fname == $val) return;
$this->$fname = $val;
$this->save_property ($fname);
if ($fname == "can_process" && $val == 1)
{
$this->is_opt_in_only = 0;
$this->save_property ("is_opt_in_only");
}
else if ($fname == "is_opt_in_only" && $val == 1)
{
$this->can_process = 0;
$this->save_property ("can_process");
}
if ($fname == "is_self_subscribe" && $val == 1)
{
$this->is_self_unsubscribe = 0;
$this->save_property ("is_self_unsubscribe");
}
else if ($fname == "is_self_unsubscribe" && $val == 1)
{
$this->is_self_subscribe = 0;
$this->save_property ("is_self_subscribe");
}
if ($fname == "can_process" || $fname == "is_opt_in_only") gdpr::update_groups ();
}
/** @js:rpc */
function set_special ($fname, $val)
{
if (!$this->i_am_owner) ajax::error ("Access denied");
if (!in_array ($fname, array ("is_role", "is_historical", "is_newcomer", "can_process", "is_opt_in_only", "is_self_subscribe", "is_self_unsubscribe"))) ajax::error ("Bad fname");
$this->raw_set_special ($fname, $val);
$this->push_to_client ();
}
function postload ()
{
$this->i_am_owner = person::is_webmaster() || person::i_match_expr ($this->owners);
$this->i_can_read = $this->i_am_owner || person::i_match_expr ($this->readers);
$this->i_can_remove_member = $this->i_am_owner || person::i_match_query ("Web\\Group Removers");
}
static function get_all ()
{
return self::search ("group", "true order by menuname asc");
}
/** @js:rpc */
static function get_all_readable ()
{
$candidates = self::get_all ();
$res = array();
foreach ($candidates as $candidate)
{
if ($candidate->i_can_read)
$res[] = $candidate;
}
return $res;
}
/** @js:rpc */
function do_save ($str)
{
if (!$this->i_am_owner) ajax::error ("Access denied");
popupobjeditor::from_struct ($this, $str);
$this->save ();
}
function save_name ($name)
{
if ($name != $this->menuname)
{
$this->menuname = $name;
$this->save_property ("menuname");
stored_query::update_pattern_queries ();
cache::clear ("query_to_sql");
person::flush_category_cache ();
}
}
function save_access ($readers, $writers)
{
$this->readers = $readers;
$this->owners = $writers;
$this->save_property ("readers");
$this->save_property ("owners");
$this->postload ();
}
/** @js:rpc */
function copy_group_or_query ($oldgroup)
{
if (!(person::is_webmaster())) ajax::error ("Access denied");
$expr_str = $oldgroup->as_expr_str();
$pl = person::get_all_matching ($expr_str);
foreach ($pl as $p)
$p->do_add_to_group ($this);
$this->owners = $oldgroup->owners;
$this->readers = $oldgroup->readers;
$this->i_am_owner = $oldgroup->i_am_owner;
$this->i_can_read = $oldgroup->i_can_read;
}
/** @js:translate */
static function popupobjeditor_fields ()
{
return array (
array ("name"=>"menuname", "label"=>"Menuname", "type"=>"text", "width"=>300),
array ("name"=>"description", "label"=>"Description", "type"=>"text", "width"=>300),
array ("name"=>"owners", "label"=>"Owners", "type"=>"query_expr"),
array ("name"=>"readers", "label"=>"Readers", "type"=>"query_expr"),
array ("name"=>"is_role", "label"=>"Is Job", "type"=>"yesno"),
array ("name"=>"is_historical", "label"=>"Is Historical Record", "type"=>"yesno"),
array ("name"=>"attributes", "label"=>"Attributes", "type"=>"text")
);
}
/** @js:translate */
function edit_properties ()
{
if (popupobjeditor::edit ($this, "Group properties"))
{
$this->do_save (popupobjeditor::to_struct ($this));
return true;
}
return false;
}
function raw_get_members ()
{
return person::search ("person", "group_membership like '%{".$this->rowid."}%' order by sname asc, nname asc");
}
/** @js:rpc */
function get_members ()
{
if (!$this->i_can_read) ajax::error ("Access denied");
return $this->raw_get_members();
}
/** @js:rpc */
function get_members_filtered ($filter)
{
if (!$this->i_can_read) ajax::error ("Access denied");
$qs = $filter->as_safe_sql ();
error_log ("[$qs]");
return person::search ("person", "group_membership like '%{".$this->rowid."}%' and ($qs) order by sname asc, nname asc");
}
/*
static function expr_is_used ($exp)
{
$nicearray = array();
$safeexp = db::escape($exp);
$sql = "owners like '%$safeexp%'";
$objs = self::search("group", $sql);
foreach($objs as $obj)
{
$nicearray[] = array("object"=>$obj,"class"=>"Group", "name" =>$obj->menuname, "section"=>"Writers");
}
$sql = "readers like '%$safeexp%'";
$objs = self::search("group", $sql);
foreach($objs as $obj)
{
$nicearray[] = array("object"=>$obj,"class"=>"Group", "name" =>$obj->menuname, "section"=>"Readers");
}
return $nicearray;
}
*/
function raw_remove ()
{
error_log ("Removing group ".$this->menuname);
$members = $this->raw_get_members ();
foreach ($members as $p)
$p->do_remove_from_group ($this);
$this->delete_row();
stored_query::update_pattern_queries ();
cache::clear ("query_to_sql");
person::flush_category_cache ();
}
/** @js:rpc */
function remove ()
{
if (!$this->i_am_owner) ajax::error ("Access denied");
$this->raw_remove();
}
function garbage_collect ($p)
{
$res = array("ignore"=>"me");
error_log ("Garbage collect on group $this->menuname");
$specs = gq_annotation_spec::raw_get_all ($this);
foreach ($specs as $key => $spec)
{
if ($key == "ignore") continue;
if ($spec->cleanup_dead)
{
error_log ("Found a cleanup-dead column: ".$spec->label());
gq_annotation::set ($spec, $p, null);
}
$a = gq_annotation::get_for_spec_person ($spec, $p);
if ($a !== null) $res[$spec->rowid] = $a;
}
return $res;
}
/** @js:translate */
function as_expr_str ()
{
return "G".$this->rowid.".";
}
/** @js:translate */
function as_unevaluated_expr_str ()
{
return "G".$this->rowid.".";
}
static function create_new ($menuname,$historical = 0)
{
$g = group::insert_new ("group");
$g->menuname = $menuname;
$g->description = "";
$g->owners = "";
$g->readers = "";
$g->is_role = 0;
$g->is_historical = $historical;
$g->is_newcomer = 0;
$g->attributes = "";
$g->default_headings = array();
$g->save();
$g->postload ();
stored_query::update_pattern_queries ();
cache::clear ("query_to_sql");
person::flush_category_cache ();
return $g;
}
static function navmenu_spec ()
{
return array (
array ("classname"=>"group", "methodname"=>"open_group_manager", "label"=>"Group Manager", "options"=>array(), "default"=>"Admin:60"),
);
}
static function navmenu_open_group_manager ($node)
{
if (person::is_webmaster() || person::i_match_query ("Web\\Group Managers"))
return "
".$node->getAttribute("label")."";
return "";
}
/** @js:translate */
function editor_class ()
{
return "group_editor";
}
function ptn_remove ()
{
$this->raw_remove ();
}
function mailunsub_unsubscribe ()
{
if (($this->is_self_subscribe || $this->is_self_unsubscribe) && person::i_match_expr ($this->as_unevaluated_expr_str ()))
{
error_log ("Self unsubscribe...");
person::$me->raw_do_remove_from_group ($this);
}
}
function mailunsub_info ()
{
$text = "
This email was sent using a group called '".htmlentities($this->menuname)."'.
";
if ($this->consent_text != "") $text .= "
The purpose of this group is described here: ".htmlentities($this->consent_text)."
";
return array (
"text" => $text,
"is_subscribed"=>person::i_match_expr ($this->as_unevaluated_expr_str ()),
"can_unsubscribe"=>($this->is_self_subscribe || $this->is_self_unsubscribe));
}
}
class audit_action_add_to_group extends audit_action
{
static function msg_template () { return "User %0 added to group %1"; }
}
class audit_action_remove_from_group extends audit_action
{
static function msg_template () { return "User %0 removed from group %1"; }
}