1<?php 2 3namespace dokuwiki\plugin\bez\mdl; 4 5use Assetic\Exception\Exception; 6 7class ThreadFactory extends Factory { 8 9 public function get_table_view() { 10 return 'thread_view'; 11 } 12 13 public function get_years_scope() { 14 $r = $this->model->sqlite->query('SELECT create_date FROM thread ORDER BY id LIMIT 1'); 15 $date = $this->model->sqlite->res2single($r); 16 17 //get only year 18 $first = (int) substr($date, 0, strpos($date, '-')); 19 $last = (int) date('Y'); 20 21 $years = array(); 22 for ($year = $first; $year <= $last; $year++) { 23 $years[] = (string) $year; 24 } 25 return $years; 26 } 27 28 public function users_involvement($range=array()) { 29 if (count($range) > 0) { 30 $from = date('c ', strtotime($range[0])); 31 if (count($range) == 1) { 32 $to = date('c'); 33 } else { 34 $to = date('c', strtotime($range[1])); 35 } 36 $sql = "SELECT thread_participant.user_id, 37 SUM(thread_participant.original_poster) AS original_poster_sum, 38 SUM(thread_participant.coordinator) AS coordinator_sum, 39 SUM(thread_participant.commentator) AS commentator_sum, 40 SUM(thread_participant.task_assignee) AS task_assignee_sum 41 FROM thread_participant JOIN thread ON thread_participant.thread_id = thread.id 42 WHERE thread.create_date BETWEEN ? AND ? 43 GROUP BY user_id 44 ORDER BY user_id"; 45 $r = $this->model->sqlite->query($sql, $from, $to); 46 } else { 47 $sql = "SELECT user_id, 48 SUM(original_poster) AS original_poster_sum, 49 SUM(coordinator) AS coordinator_sum, 50 SUM(commentator) AS commentator_sum, 51 SUM(task_assignee) AS task_assignee_sum 52 FROM thread_participant 53 GROUP BY user_id 54 ORDER BY user_id"; 55 56 $r = $this->model->sqlite->query($sql); 57 } 58 return $r; 59 } 60 61 public function kpi($range=array()) { 62 if (count($range) > 0) { 63 $from = date('c ', strtotime($range[0])); 64 if (count($range) == 1) { 65 $to = date('c'); 66 } else { 67 $to = date('c', strtotime($range[1])); 68 } 69 $sql = "SELECT COUNT(*)*1.0/COUNT(DISTINCT thread_id) AS kpi 70 FROM thread_participant JOIN thread ON thread_participant.thread_id = thread.id 71 WHERE thread.create_date BETWEEN ? AND ?"; 72 $r = $this->model->sqlite->query($sql, $from, $to); 73 } else { 74 $sql = "SELECT COUNT(*)*1.0/COUNT(DISTINCT thread_id) AS kpi 75 FROM thread_participant"; 76 77 $r = $this->model->sqlite->query($sql); 78 } 79 80 return $r->fetchColumn(); 81 } 82 83 public function bez_activity($range=array()) { 84 if (count($range) > 0) { 85 $from = date('c ', strtotime($range[0])); 86 if (count($range) == 1) { 87 $to = date('c'); 88 } else { 89 $to = date('c', strtotime($range[1])); 90 } 91 $sql = "SELECT COUNT(DISTINCT user_id) 92 FROM (SELECT user_id 93 FROM thread_participant JOIN thread ON thread_participant.thread_id = thread.id 94 WHERE create_date BETWEEN ? AND ? 95 UNION 96 SELECT user_id 97 FROM task_participant JOIN task ON task_participant.task_id = task.id 98 WHERE create_date BETWEEN ? AND ?)"; 99 $r = $this->model->sqlite->query($sql, $from, $to, $from, $to); 100 } else { 101 $sql = "SELECT COUNT(DISTINCT user_id) 102 FROM (SELECT user_id FROM thread_participant 103 UNION 104 SELECT user_id FROM task_participant)"; 105 106 $r = $this->model->sqlite->query($sql); 107 } 108 $active_users = $r->fetchColumn(); 109 $wiki_users = count($this->model->userFactory->get_all()); 110 111 return $active_users/$wiki_users * 100; 112 } 113 114 public function initial_save(Entity $thread, $data) { 115 $label_ids = array(); 116 if (isset($data['label_id']) && $data['label_id'] != '') { 117 $label_ids[] = $data['label_id']; 118 } 119 try { 120 $this->beginTransaction(); 121 122 parent::initial_save($thread, $data); 123 124 foreach($label_ids as $label_id) { 125 $thread->add_label($label_id); 126 } 127 128 $thread->set_participant_flags($thread->original_poster, array('original_poster', 'subscribent')); 129 if($thread->coordinator != null) { 130 $thread->set_participant_flags($thread->coordinator, array('coordinator', 'subscribent')); 131 } 132 133 if ($this->model->get_level() >= BEZ_AUTH_LEADER) { 134 $private = false; 135 if (isset($data['private'])) { 136 $private = true; 137 } 138 $thread->set_private_flag($private); 139 } 140 141 $this->commitTransaction(); 142 143 if ($thread->state != 'proposal' && $this->model->user_nick != $thread->coordinator) { 144 $thread->mail_inform_coordinator(); 145 } elseif ($thread->state == 'proposal') { 146 $thread->mail_inform_admins(); 147 } 148 149 } catch(Exception $exception) { 150 $this->rollbackTransaction(); 151 } 152 } 153 154 protected function update(Entity $obj) { 155 if ($obj->state == 'done') { 156 $prev_state = $obj->state; 157 $reflectionClass = new \ReflectionClass('dokuwiki\plugin\bez\mdl\Thread'); 158 $reflectionProperty = $reflectionClass->getProperty('state'); 159 $reflectionProperty->setAccessible(true); 160 $reflectionProperty->setValue($obj, 'opened'); 161 } 162 try { 163 parent::update($obj); 164 } finally { 165 if (isset($prev_state)) { 166 $reflectionProperty->setValue($obj, $prev_state); 167 } 168 } 169 } 170 171 public function update_save(Entity $thread, $data) { 172 $prev_coordinator = $thread->coordinator; 173 174 $label_ids = array(); 175 if (isset($data['label_id']) && $data['label_id'] != '') { 176 $label_ids[] = $data['label_id']; 177 } 178 try { 179 $this->beginTransaction(); 180 parent::update_save($thread, $data); 181 182 $cur_label_ids = array_keys($thread->get_labels()); 183 $labels_to_add = array_diff($label_ids, $cur_label_ids); 184 $labels_to_rem = array_diff($cur_label_ids, $label_ids); 185 186 foreach($labels_to_add as $label_id) { 187 $thread->add_label($label_id); 188 } 189 190 foreach($labels_to_rem as $label_id) { 191 $thread->remove_label($label_id); 192 } 193 194 if ($thread->coordinator != null && $thread->coordinator != $prev_coordinator) { 195 if ($prev_coordinator != null) { 196 $thread->remove_participant_flags($prev_coordinator, array('coordinator')); 197 } 198 $thread->set_participant_flags($thread->coordinator, array('subscribent', 'coordinator')); 199 } 200 201 if ($thread->acl_of('private') >= BEZ_PERMISSION_CHANGE) { 202 $private = false; 203 if (isset($data['private'])) { 204 $private = true; 205 } 206 $thread->set_private_flag($private); 207 } 208 209 $this->commitTransaction(); 210 } catch(Exception $exception) { 211 $this->rollbackTransaction(); 212 } 213 214 if ($thread->state != 'proposal' && $this->model->user_nick != $thread->coordinator) { 215 $thread->mail_inform_coordinator(); 216 } 217 } 218} 219