1<?php 2 3namespace dokuwiki\plugin\bez\mdl; 4/* 5 * All fields are stored in object as strings. 6 * NULLs are converted to empty string. 7 * If any attribute in object === NULL -> it means that it was not initialized 8 * But we always inserts NULLs instead of empty strings. 9 * https://stackoverflow.com/questions/1267999/mysql-better-to-insert-null-or-empty-string 10 **/ 11 12use dokuwiki\plugin\bez\meta\PermissionDeniedException; 13use dokuwiki\plugin\bez\meta\ValidationException; 14use Mailer; 15 16abstract class Entity { 17 18 /** @var Model */ 19 protected $model; 20 21 /** @var Validator */ 22 protected $validator; 23 24 /** @var Acl */ 25 protected $acl; 26 27 abstract public static function get_columns(); 28 29 public static function get_select_columns() { 30 $class = get_called_class(); 31 return $class::get_columns(); 32 } 33 34 public static function get_acl_columns() { 35 $class = get_called_class(); 36 return $class::get_select_columns(); 37 } 38 39 public function get_assoc($filter=NULL) { 40 $assoc = array(); 41 42 $columns = $this->get_select_columns(); 43 if ($filter !== NULL) { 44 $columns = array_intersect($columns, $filter); 45 } 46 47 foreach ($columns as $col) { 48 $assoc[$col] = $this->$col; 49 } 50 return $assoc; 51 } 52 53 public function get_table_name() { 54 $class = (new \ReflectionClass($this))->getShortName(); 55 return lcfirst($class); 56 } 57 58 public function __get($property) { 59 if (!property_exists($this, $property) || !in_array($property, $this->get_select_columns())) { 60 throw new \Exception('there is no column: "'.$property. '"" in table: "' . $this->get_table_name() . '"'); 61 } 62 63 if ($this->acl_of($property) < BEZ_PERMISSION_VIEW) { 64 throw new PermissionDeniedException(); 65 } 66 67 return $this->$property; 68 69 } 70 71 protected function set_property($property, $value) { 72 if ($this->acl_of($property) < BEZ_PERMISSION_CHANGE) { 73 throw new PermissionDeniedException("cannot change field $property"); 74 } 75 $this->$property = $value; 76 } 77 78 protected function set_property_array($array) { 79 foreach ($array as $k => $v) { 80 $this->set_property($k, $v); 81 } 82 } 83 84 public function set_data($post) { 85 $val_data = $this->validator->validate($post); 86 if ($val_data === false) { 87 throw new ValidationException($this->get_table_name(), $this->validator->get_errors()); 88 } 89 90 $this->set_property_array($val_data); 91 } 92 93 94 public function purge() { 95 if (property_exists($this, 'content') && property_exists($this, 'content_html')) { 96 $rule = $this->validator->get_rule('content'); 97 98 $html = p_render('xhtml',p_get_instructions($this->content), $ignore); 99 100 //probably content contains only white spaces 101 if (empty($html) && $rule[1] == 'NOT NULL') { 102 $html = '<p></p>'; 103 } 104 $this->content_html = $html; 105 } 106 107 } 108 109 public function changable_fields($filter=NULL) { 110 $fields = $this->acl->get_list(); 111 112 if ($filter !== NULL) { 113 $fields = array_filter($fields, function ($k) use ($filter) { 114 return in_array($k, $filter); 115 }, ARRAY_FILTER_USE_KEY); 116 } 117 118 return array_keys(array_filter($fields, function ($var) { 119 return $var >= BEZ_PERMISSION_CHANGE; 120 })); 121 } 122 123 public function can_be_null($field) { 124 $rule = $this->validator->get_rule($field); 125 $null = $rule[1]; 126 if (strtolower($null) == 'null') { 127 return true; 128 } 129 130 return false; 131 } 132 133 public function __construct($model) { 134 $this->model = $model; 135 $this->validator = new Validator($this->model); 136 137 $this->acl = new Acl($this->model->get_level(), $this->get_acl_columns()); 138 } 139 140 public function acl_of($field) { 141 return $this->acl->acl_of($field); 142 } 143 144 protected function html_link_url() { 145 return '#'; 146 } 147 148 protected function html_link_content() { 149 echo $this->id; 150 } 151 152 public function html_link($pre='', $post='', $print=true) { 153 $ret = '<a href="'.$this->html_link_url().'">'; 154 $ret .= $pre . $this->html_link_content() . $post; 155 $ret .= '</a>'; 156 157 if ($print) { 158 echo $ret; 159 } 160 return $ret; 161 } 162 163 protected function getMailSubject() { 164 global $conf; 165 return $conf['title']; 166 } 167 168 //http://data.agaric.com/capture-all-sent-mail-locally-postfix 169 //https://askubuntu.com/questions/192572/how-do-i-read-local-email-in-thunderbird 170 public function mail_notify($content, $users=false, $attachedImages=array()) { 171 global $conf; 172 173 $mailer = new Mailer(); 174 $mailer->subject($this->getMailSubject()); 175 176 if ($users == FALSE) { 177 $users = $this->get_participants('subscribent'); 178 //don't notify myself 179 unset($users[$this->model->user_nick]); 180 } 181 182 $muted_users = $this->model->factory('subscription')->getMutedUsers(); 183 foreach ($users as $user) { 184 if (is_array($user)) { 185 $user = $user['user_id']; 186 } 187 //omit muted users 188 if (in_array($user, $muted_users)) continue; 189 190 $email = $this->model->userFactory->get_user_email($user); 191 //do we have user email address 192 if (!$email) continue; 193 194 $name = $this->model->userFactory->get_user_full_name($user); 195 196 $mailer->to("$name <$email>"); 197 198// $token = $this->model->factory('subscription')->getUserToken($user); 199// $resign_link = $this->model->action->url('unsubscribe', array('GET' => array( 't' => $token))); 200// $html = str_replace('%%resign_link%%', $resign_link, $content); 201 $mailer->setBody('', null, null, $content); 202 203 try { 204 $mailer->send(); 205 } catch (\Exception $e) { 206 $msg = $this->get_table_name() . '#' . $this->id . ': ' . $e->getMessage(); 207 throw new \Exception($msg); 208 } 209 } 210 } 211 212} 213