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